mirror of
https://github.com/Relintai/godot_voxel.git
synced 2025-05-01 17:57:55 +02: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>();
|
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
|
// Helper
|
||||||
VoxelBlock * VoxelBlock::create(Vector3i bpos, Ref<VoxelBuffer> buffer) {
|
VoxelBlock * VoxelBlock::create(Vector3i bpos, Ref<VoxelBuffer> buffer) {
|
||||||
const int bs = VoxelBlock::SIZE;
|
const int bs = VoxelBlock::SIZE;
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <scene/main/node.h>
|
#include <scene/main/node.h>
|
||||||
#include <core/hash_map.h>
|
#include <core/hash_map.h>
|
||||||
#include <scene/3d/mesh_instance.h>
|
#include <scene/3d/mesh_instance.h>
|
||||||
|
#include <scene/3d/physics_body.h>
|
||||||
#include "voxel_buffer.h"
|
#include "voxel_buffer.h"
|
||||||
|
|
||||||
|
|
||||||
@ -16,11 +17,12 @@ public:
|
|||||||
Ref<VoxelBuffer> voxels; // SIZE*SIZE*SIZE voxels
|
Ref<VoxelBuffer> voxels; // SIZE*SIZE*SIZE voxels
|
||||||
Vector3i pos;
|
Vector3i pos;
|
||||||
NodePath mesh_instance_path;
|
NodePath mesh_instance_path;
|
||||||
//NodePath body_path; // TODO
|
NodePath body_path; // TODO
|
||||||
|
|
||||||
static VoxelBlock * create(Vector3i bpos, Ref<VoxelBuffer> buffer);
|
static VoxelBlock * create(Vector3i bpos, Ref<VoxelBuffer> buffer);
|
||||||
|
|
||||||
MeshInstance * get_mesh_instance(const Node & root);
|
MeshInstance * get_mesh_instance(const Node & root);
|
||||||
|
StaticBody * get_physics_body(const Node & root);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
VoxelBlock();
|
VoxelBlock();
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
#include <scene/3d/mesh_instance.h>
|
#include <scene/3d/mesh_instance.h>
|
||||||
#include <os/os.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));
|
_map = Ref<VoxelMap>(memnew(VoxelMap));
|
||||||
_mesher = Ref<VoxelMesher>(memnew(VoxelMesher));
|
_mesher = Ref<VoxelMesher>(memnew(VoxelMesher));
|
||||||
@ -24,6 +24,10 @@ Ref<VoxelProvider> VoxelTerrain::get_provider() {
|
|||||||
return _provider;
|
return _provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VoxelTerrain::set_generate_collisions(bool enabled) {
|
||||||
|
_generate_collisions = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
void VoxelTerrain::force_load_blocks(Vector3i center, Vector3i extents) {
|
void VoxelTerrain::force_load_blocks(Vector3i center, Vector3i extents) {
|
||||||
//Vector3i min = center - extents;
|
//Vector3i min = center - extents;
|
||||||
//Vector3i max = center + extents + Vector3i(1,1,1);
|
//Vector3i max = center + extents + Vector3i(1,1,1);
|
||||||
@ -159,6 +163,8 @@ void VoxelTerrain::update_block_mesh(Vector3i block_pos) {
|
|||||||
// wprintf(os.c_str());
|
// 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)
|
// Build mesh (that part is the most CPU-intensive)
|
||||||
Ref<Mesh> mesh = _mesher->build(nbuffer);
|
Ref<Mesh> mesh = _mesher->build(nbuffer);
|
||||||
|
|
||||||
@ -167,13 +173,35 @@ void VoxelTerrain::update_block_mesh(Vector3i block_pos) {
|
|||||||
// Create and spawn mesh
|
// Create and spawn mesh
|
||||||
mesh_instance = memnew(MeshInstance);
|
mesh_instance = memnew(MeshInstance);
|
||||||
mesh_instance->set_mesh(mesh);
|
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);
|
add_child(mesh_instance);
|
||||||
block->mesh_instance_path = mesh_instance->get_path();
|
block->mesh_instance_path = mesh_instance->get_path();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// Update mesh
|
// Update mesh
|
||||||
mesh_instance->set_mesh(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_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_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);
|
ClassDB::bind_method(D_METHOD("get_map:VoxelMap"), &VoxelTerrain::get_map);
|
||||||
|
|
||||||
// TODO Make those two static in VoxelMap?
|
// TODO Make those two static in VoxelMap?
|
||||||
|
@ -6,6 +6,9 @@
|
|||||||
#include "voxel_mesher.h"
|
#include "voxel_mesher.h"
|
||||||
#include "voxel_provider.h"
|
#include "voxel_provider.h"
|
||||||
|
|
||||||
|
// TODO
|
||||||
|
//#define VOXEL_TERRAIN_PROFILING
|
||||||
|
|
||||||
// Infinite static terrain made of voxels.
|
// Infinite static terrain made of voxels.
|
||||||
// It is loaded around VoxelTerrainStreamers.
|
// It is loaded around VoxelTerrainStreamers.
|
||||||
class VoxelTerrain : public Node /*, public IVoxelMapObserver*/ {
|
class VoxelTerrain : public Node /*, public IVoxelMapObserver*/ {
|
||||||
@ -19,6 +22,9 @@ public:
|
|||||||
void force_load_blocks(Vector3i center, Vector3i extents);
|
void force_load_blocks(Vector3i center, Vector3i extents);
|
||||||
int get_block_update_count();
|
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<VoxelMesher> get_mesher() { return _mesher; }
|
||||||
Ref<VoxelMap> get_map() { return _map; }
|
Ref<VoxelMap> get_map() { return _map; }
|
||||||
|
|
||||||
@ -51,6 +57,8 @@ private:
|
|||||||
Ref<VoxelMesher> _mesher;
|
Ref<VoxelMesher> _mesher;
|
||||||
Ref<VoxelProvider> _provider;
|
Ref<VoxelProvider> _provider;
|
||||||
|
|
||||||
|
bool _generate_collisions;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // VOXEL_TERRAIN_H
|
#endif // VOXEL_TERRAIN_H
|
||||||
|
Loading…
Reference in New Issue
Block a user