mirror of
https://github.com/Relintai/godot_voxel.git
synced 2024-11-19 02:47:18 +01:00
Added collision shape generation
This commit is contained in:
parent
6235985d80
commit
353b32c49a
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -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?
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user