builtin/voxelworld: WIP
This commit is contained in:
parent
1c7ee8ddcb
commit
6402c5c246
@ -529,10 +529,10 @@ struct Module: public interface::Module, public voxelworld::Interface
|
||||
n->SetVar(StringHash("buildat_voxel_data"), Variant(
|
||||
PODVector<uint8_t>((const uint8_t*)data.c_str(), data.size())));
|
||||
|
||||
// There is no collision shape initially, but add the components now
|
||||
// There are no collision shapes initially, but add the rigid body now
|
||||
RigidBody *body = n->CreateComponent<RigidBody>(LOCAL);
|
||||
body->SetFriction(0.75f);
|
||||
CollisionShape *shape = n->CreateComponent<CollisionShape>(LOCAL);
|
||||
//CollisionShape *shape = n->CreateComponent<CollisionShape>(LOCAL);
|
||||
}
|
||||
|
||||
void create_section(Section §ion)
|
||||
@ -752,11 +752,14 @@ struct Module: public interface::Module, public voxelworld::Interface
|
||||
// TODO: Create multiple box collision shapes insteade of one mesh;
|
||||
// vertical voxel sectors should work well enough maybe
|
||||
|
||||
SharedPtr<Model> model(interface::
|
||||
create_voxel_physics_model(context, *volume,
|
||||
m_voxel_reg.get()));
|
||||
CollisionShape *shape = n->CreateComponent<CollisionShape>();
|
||||
shape->SetBox(Vector3(10, 0, 10));
|
||||
|
||||
CollisionShape *shape = n->GetComponent<CollisionShape>();
|
||||
/*SharedPtr<Model> model(interface::
|
||||
create_voxel_physics_model(context, *volume,
|
||||
m_voxel_reg.get()));*/
|
||||
|
||||
/*CollisionShape *shape = n->GetComponent<CollisionShape>();
|
||||
if(model){
|
||||
log_v(MODULE, "Chunk " PV3I_FORMAT " has collision shape",
|
||||
PV3I_PARAMS(chunk_p));
|
||||
@ -767,7 +770,7 @@ struct Module: public interface::Module, public voxelworld::Interface
|
||||
log_v(MODULE, "Chunk " PV3I_FORMAT " does not have collision shape",
|
||||
PV3I_PARAMS(chunk_p));
|
||||
shape->ReleaseShape();
|
||||
}
|
||||
}*/
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,7 @@ zone.fogEnd = 300
|
||||
|
||||
-- Add a node that the player can use to walk around with
|
||||
local player_node = scene:CreateChild("Player")
|
||||
--player_node.position = magic.Vector3(0, 30, 0)
|
||||
player_node.position = magic.Vector3(55, 30, 40)
|
||||
---[[
|
||||
local body = player_node:CreateComponent("RigidBody")
|
||||
@ -129,10 +130,10 @@ magic.SubscribeToEvent("Update", function(event_type, event_data)
|
||||
|
||||
--if magic.input:GetKeyPress(magic.KEY_SPACE) then
|
||||
if magic.input:GetKeyDown(magic.KEY_SPACE) then
|
||||
if player_touches_ground and
|
||||
math.abs(body.linearVelocity.y) < JUMP_SPEED then
|
||||
--if player_touches_ground and
|
||||
-- math.abs(body.linearVelocity.y) < JUMP_SPEED then
|
||||
wanted_v.y = wanted_v.y + JUMP_SPEED
|
||||
end
|
||||
--end
|
||||
end
|
||||
if magic.input:GetKeyDown(magic.KEY_SHIFT) then
|
||||
wanted_v.y = wanted_v.y - MOVE_SPEED
|
||||
|
@ -204,6 +204,11 @@ struct Module: public interface::Module
|
||||
ivoxelworld->set_voxel(p, VoxelInstance(1));
|
||||
continue;
|
||||
}
|
||||
if(x > 18 && x < 25 && z >= 32 && z <= 37 &&
|
||||
y > 20 && y < 25){
|
||||
ivoxelworld->set_voxel(p, VoxelInstance(1));
|
||||
continue;
|
||||
}
|
||||
double a = interface::NoisePerlin2D(&np, x, z, 0);
|
||||
if(y < a+5){
|
||||
ivoxelworld->set_voxel(p, VoxelInstance(2));
|
||||
|
@ -21,7 +21,9 @@
|
||||
#include <Context.h>
|
||||
#include <ResourceCache.h>
|
||||
#include <Texture2D.h> // Allows cast to Texture
|
||||
#include <CollisionShape.h>
|
||||
#pragma GCC diagnostic pop
|
||||
#include <climits>
|
||||
#define MODULE "mesh"
|
||||
|
||||
namespace magic = Urho3D;
|
||||
@ -524,5 +526,131 @@ void set_voxel_geometry(CustomGeometry *cg, Context *context,
|
||||
cg->Commit();
|
||||
}
|
||||
|
||||
void set_voxel_physics_boxes(Node *node, Context *context,
|
||||
pv::RawVolume<VoxelInstance> &volume_orig,
|
||||
VoxelRegistry *voxel_reg)
|
||||
{
|
||||
PODVector<CollisionShape*> previous_shapes;
|
||||
node->GetComponents<CollisionShape>(previous_shapes);
|
||||
for(size_t i = 0; i < previous_shapes.Size(); i++){
|
||||
node->RemoveComponent(previous_shapes[i]);
|
||||
}
|
||||
|
||||
int w = volume_orig.getWidth() - 2;
|
||||
int h = volume_orig.getHeight() - 2;
|
||||
int d = volume_orig.getDepth() - 2;
|
||||
|
||||
auto region = volume_orig.getEnclosingRegion();
|
||||
auto &lc = region.getLowerCorner();
|
||||
auto &uc = region.getUpperCorner();
|
||||
|
||||
// Create a new volume which only holds the solidity of the voxels
|
||||
pv::RawVolume<uint8_t> volume(region);
|
||||
for(int x = lc.getX(); x <= uc.getX(); x++){
|
||||
for(int y = lc.getY(); y <= uc.getY(); y++){
|
||||
for(int z = lc.getZ(); z <= uc.getZ(); z++){
|
||||
VoxelInstance v_orig = volume_orig.getVoxelAt(x, y, z);
|
||||
const interface::CachedVoxelDefinition *def =
|
||||
voxel_reg->get_cached(v_orig);
|
||||
uint8_t v = (def && def->physically_solid);
|
||||
volume.setVoxelAt(x, y, z, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create minimal number of boxes to fill the solid voxels. Boxes can
|
||||
// overlap. When a box is added, its voxels are set to value 2 in the
|
||||
// temporary volume.
|
||||
|
||||
for(int z0 = lc.getZ(); z0 <= uc.getZ(); z0++){
|
||||
// Loop until this z0 plane is done, then handle the next one
|
||||
for(;;){
|
||||
// Find a solid non-covered voxel (v=1) on the z0 plane
|
||||
int x0 = INT_MAX;
|
||||
int y0 = INT_MAX;
|
||||
for(int x = lc.getX(); x <= uc.getX(); x++){
|
||||
for(int y = lc.getY(); y <= uc.getY(); y++){
|
||||
uint8_t v = volume.getVoxelAt(x, y, z0);
|
||||
if(v == 1){
|
||||
x0 = x;
|
||||
y0 = y;
|
||||
goto found_non_covered_voxel;
|
||||
}
|
||||
}
|
||||
}
|
||||
break; // Done
|
||||
found_non_covered_voxel:
|
||||
// Stretch this box first in x, then y and then z to be as large as
|
||||
// possible without covering any non-solid voxels
|
||||
int x1 = x0;
|
||||
int y1 = y0;
|
||||
int z1 = z0;
|
||||
for(;;){
|
||||
x1++;
|
||||
for(int y = y0; y <= y1; y++){
|
||||
for(int z = z0; z <= z1; z++){
|
||||
uint8_t v = volume.getVoxelAt(x1, y, z);
|
||||
if(v == 0)
|
||||
goto x_plane_does_not_fit;
|
||||
}
|
||||
}
|
||||
continue; // Fits
|
||||
x_plane_does_not_fit:
|
||||
x1--;
|
||||
break;
|
||||
}
|
||||
for(;;){
|
||||
y1++;
|
||||
for(int x = x0; x <= x1; x++){
|
||||
for(int z = z0; z <= z1; z++){
|
||||
uint8_t v = volume.getVoxelAt(x, y1, z);
|
||||
if(v == 0)
|
||||
goto y_plane_does_not_fit;
|
||||
}
|
||||
}
|
||||
continue; // Fits
|
||||
y_plane_does_not_fit:
|
||||
y1--;
|
||||
break;
|
||||
}
|
||||
for(;;){
|
||||
z1++;
|
||||
for(int x = x0; x <= x1; x++){
|
||||
for(int y = y0; y <= y1; y++){
|
||||
uint8_t v = volume.getVoxelAt(x, y, z1);
|
||||
if(v == 0)
|
||||
goto z_plane_does_not_fit;
|
||||
}
|
||||
}
|
||||
continue; // Fits
|
||||
z_plane_does_not_fit:
|
||||
z1--;
|
||||
break;
|
||||
}
|
||||
// Now we have a box; set the voxels to 2
|
||||
for(int x = x0; x <= x1; x++){
|
||||
for(int y = y0; y <= y1; y++){
|
||||
for(int z = z0; z <= z1; z++){
|
||||
volume.setVoxelAt(x, y, z, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Create the box
|
||||
CollisionShape *shape =
|
||||
node->CreateComponent<CollisionShape>();
|
||||
shape->SetBox(Vector3(
|
||||
x1 - x0 + 1,
|
||||
y1 - y0 + 1,
|
||||
z1 - z0 + 1
|
||||
));
|
||||
shape->SetPosition(Vector3(
|
||||
(x0 + x1)/2.0f - w/2 - 0.5f,
|
||||
(y0 + y1)/2.0f - h/2 - 0.5f,
|
||||
(z0 + z1)/2.0f - d/2 - 0.5f
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace interface
|
||||
// vim: set noet ts=4 sw=4:
|
||||
|
@ -10,6 +10,7 @@ namespace Urho3D
|
||||
class Context;
|
||||
class Model;
|
||||
class CustomGeometry;
|
||||
class Node;
|
||||
}
|
||||
|
||||
namespace interface
|
||||
@ -20,12 +21,14 @@ namespace interface
|
||||
// Create a model from a string; eg. (2, 2, 2, "11101111")
|
||||
Model* create_simple_voxel_model(Context *context, int w, int h, int d,
|
||||
const ss_ &source_data);
|
||||
|
||||
// Create a model from 8-bit voxel data, using a voxel registry, without
|
||||
// textures or normals, based on the physically_solid flag.
|
||||
// Returns nullptr if there is no geometry
|
||||
Model* create_8bit_voxel_physics_model(Context *context,
|
||||
int w, int h, int d, const ss_ &source_data,
|
||||
VoxelRegistry *voxel_reg);
|
||||
|
||||
// Set custom geometry from 8-bit voxel data, using a voxel registry
|
||||
void set_8bit_voxel_geometry(CustomGeometry *cg, Context *context,
|
||||
int w, int h, int d, const ss_ &source_data,
|
||||
@ -39,11 +42,16 @@ namespace interface
|
||||
Model* create_voxel_physics_model(Context *context,
|
||||
pv::RawVolume<VoxelInstance> &volume,
|
||||
VoxelRegistry *voxel_reg);
|
||||
|
||||
// Set custom geometry from voxel volume, using a voxel registry
|
||||
// Volume should be padded by one voxel on each edge
|
||||
// NOTE: volume is non-const due to PolyVox deficiency
|
||||
void set_voxel_geometry(CustomGeometry *cg, Context *context,
|
||||
pv::RawVolume<VoxelInstance> &volume,
|
||||
VoxelRegistry *voxel_reg);
|
||||
|
||||
void set_voxel_physics_boxes(Node *node, Context *context,
|
||||
pv::RawVolume<VoxelInstance> &volume,
|
||||
VoxelRegistry *voxel_reg);
|
||||
}
|
||||
// vim: set noet ts=4 sw=4:
|
||||
|
@ -162,7 +162,7 @@ static int l_set_voxel_geometry(lua_State *L)
|
||||
cg->SetCastShadows(true);
|
||||
|
||||
// TODO: Don't do this here; allow caller to do this explicitly
|
||||
SharedPtr<Model> model(interface::
|
||||
/*SharedPtr<Model> model(interface::
|
||||
create_voxel_physics_model(context, *volume, voxel_reg));
|
||||
RigidBody *body = node->GetOrCreateComponent<RigidBody>(LOCAL);
|
||||
body->SetFriction(0.7);
|
||||
@ -173,7 +173,16 @@ static int l_set_voxel_geometry(lua_State *L)
|
||||
//log_w(MODULE, "CollisionShape disabled");
|
||||
} else {
|
||||
shape->ReleaseShape();
|
||||
}
|
||||
}*/
|
||||
/*RigidBody *body = node->GetOrCreateComponent<RigidBody>(LOCAL);
|
||||
body->SetFriction(0.7);
|
||||
CollisionShape *shape = node->CreateComponent<CollisionShape>();
|
||||
shape->SetBox(Vector3(10, 0, 10));*/
|
||||
|
||||
// TODO: Don't do this here; allow caller to do this explicitly
|
||||
RigidBody *body = node->GetOrCreateComponent<RigidBody>(LOCAL);
|
||||
body->SetFriction(0.7);
|
||||
interface::set_voxel_physics_boxes(node, context, *volume, voxel_reg);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user