Added collision shape generation

This commit is contained in:
Marc Gilleron 2017-03-26 18:09:37 +02:00
parent 6235985d80
commit 353b32c49a
4 changed files with 53 additions and 3 deletions

View File

@ -14,6 +14,15 @@ MeshInstance * VoxelBlock::get_mesh_instance(const Node & root) {
return n->cast_to<MeshInstance>();
}
StaticBody * VoxelBlock::get_physics_body(const Node & root) {
if (mesh_instance_path.is_empty())
return NULL;
Node * n = root.get_node(body_path);
if (n == NULL)
return NULL;
return n->cast_to<StaticBody>();
}
// Helper
VoxelBlock * VoxelBlock::create(Vector3i bpos, Ref<VoxelBuffer> buffer) {
const int bs = VoxelBlock::SIZE;

View File

@ -4,6 +4,7 @@
#include <scene/main/node.h>
#include <core/hash_map.h>
#include <scene/3d/mesh_instance.h>
#include <scene/3d/physics_body.h>
#include "voxel_buffer.h"
@ -16,11 +17,12 @@ public:
Ref<VoxelBuffer> voxels; // SIZE*SIZE*SIZE voxels
Vector3i pos;
NodePath mesh_instance_path;
//NodePath body_path; // TODO
NodePath body_path; // TODO
static VoxelBlock * create(Vector3i bpos, Ref<VoxelBuffer> buffer);
MeshInstance * get_mesh_instance(const Node & root);
StaticBody * get_physics_body(const Node & root);
private:
VoxelBlock();

View File

@ -2,7 +2,7 @@
#include <scene/3d/mesh_instance.h>
#include <os/os.h>
VoxelTerrain::VoxelTerrain(): Node(), _min_y(-4), _max_y(4) {
VoxelTerrain::VoxelTerrain(): Node(), _min_y(-4), _max_y(4), _generate_collisions(true) {
_map = Ref<VoxelMap>(memnew(VoxelMap));
_mesher = Ref<VoxelMesher>(memnew(VoxelMesher));
@ -24,6 +24,10 @@ Ref<VoxelProvider> VoxelTerrain::get_provider() {
return _provider;
}
void VoxelTerrain::set_generate_collisions(bool enabled) {
_generate_collisions = enabled;
}
void VoxelTerrain::force_load_blocks(Vector3i center, Vector3i extents) {
//Vector3i min = center - extents;
//Vector3i max = center + extents + Vector3i(1,1,1);
@ -159,6 +163,8 @@ void VoxelTerrain::update_block_mesh(Vector3i block_pos) {
// wprintf(os.c_str());
//}
Vector3 block_node_pos = VoxelMap::block_to_voxel(block_pos).to_vec3();
// Build mesh (that part is the most CPU-intensive)
Ref<Mesh> mesh = _mesher->build(nbuffer);
@ -167,13 +173,35 @@ void VoxelTerrain::update_block_mesh(Vector3i block_pos) {
// Create and spawn mesh
mesh_instance = memnew(MeshInstance);
mesh_instance->set_mesh(mesh);
mesh_instance->set_translation(VoxelMap::block_to_voxel(block_pos).to_vec3());
mesh_instance->set_translation(block_node_pos);
add_child(mesh_instance);
block->mesh_instance_path = mesh_instance->get_path();
}
else {
// Update mesh
mesh_instance->set_mesh(mesh);
}
if(get_tree()->is_editor_hint() == false && _generate_collisions) {
// Generate collisions
// TODO Need to select only specific surfaces because some may not have collisions
Ref<Shape> shape = mesh->create_trimesh_shape();
StaticBody * body = block->get_physics_body(*this);
if(body == NULL) {
// Create body
body = memnew(StaticBody);
body->set_translation(block_node_pos);
body->add_shape(shape);
add_child(body);
block->body_path = body->get_path();
}
else {
// Update body
body->set_shape(0, shape);
}
}
}
@ -192,6 +220,9 @@ void VoxelTerrain::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_block_update_count"), &VoxelTerrain::get_block_update_count);
ClassDB::bind_method(D_METHOD("get_mesher:VoxelMesher"), &VoxelTerrain::get_mesher);
ClassDB::bind_method(D_METHOD("get_generate_collisions"), &VoxelTerrain::get_generate_collisions);
ClassDB::bind_method(D_METHOD("set_generate_collisions", "enabled"), &VoxelTerrain::set_generate_collisions);
ClassDB::bind_method(D_METHOD("get_map:VoxelMap"), &VoxelTerrain::get_map);
// TODO Make those two static in VoxelMap?

View File

@ -6,6 +6,9 @@
#include "voxel_mesher.h"
#include "voxel_provider.h"
// TODO
//#define VOXEL_TERRAIN_PROFILING
// Infinite static terrain made of voxels.
// It is loaded around VoxelTerrainStreamers.
class VoxelTerrain : public Node /*, public IVoxelMapObserver*/ {
@ -19,6 +22,9 @@ public:
void force_load_blocks(Vector3i center, Vector3i extents);
int get_block_update_count();
void set_generate_collisions(bool enabled);
bool get_generate_collisions() { return _generate_collisions; }
Ref<VoxelMesher> get_mesher() { return _mesher; }
Ref<VoxelMap> get_map() { return _map; }
@ -51,6 +57,8 @@ private:
Ref<VoxelMesher> _mesher;
Ref<VoxelProvider> _provider;
bool _generate_collisions;
};
#endif // VOXEL_TERRAIN_H