Added collision layer and mask properties

master
Marc Gilleron 2021-05-09 20:49:45 +01:00
parent b5f1634906
commit fa48523073
9 changed files with 117 additions and 1 deletions

View File

@ -22,6 +22,7 @@ Ongoing development
- Added `VoxelStreamSQLite`, allowing to save volumes as a single SQLite database
- Implemented `copy` and `paste` for `VoxelToolTerrain`
- Added ability to double block size used for meshes and instancing, improving rendering speed at the cost of slower modification
- Added collision layer and mask properties
- Editor
- Streaming/LOD can be set to follow the editor camera instead of being centered on world origin. Use with caution, fast big movements and zooms can cause lag

View File

@ -588,6 +588,32 @@ int VoxelLodTerrain::get_collision_lod_count() const {
return _collision_lod_count;
}
void VoxelLodTerrain::set_collision_layer(int layer) {
_collision_layer = layer;
for (unsigned int lod_index = 0; lod_index < _lod_count; ++lod_index) {
_lods[lod_index].mesh_map.for_all_blocks([layer](VoxelMeshBlock *block) {
block->set_collision_layer(layer);
});
}
}
int VoxelLodTerrain::get_collision_layer() const {
return _collision_layer;
}
void VoxelLodTerrain::set_collision_mask(int mask) {
_collision_mask = mask;
for (unsigned int lod_index = 0; lod_index < _lod_count; ++lod_index) {
_lods[lod_index].mesh_map.for_all_blocks([mask](VoxelMeshBlock *block) {
block->set_collision_mask(mask);
});
}
}
int VoxelLodTerrain::get_collision_mask() const {
return _collision_mask;
}
int VoxelLodTerrain::get_data_block_region_extent() const {
return VoxelServer::get_octree_lod_block_region_extent(_lod_distance, get_data_block_size());
}
@ -1607,6 +1633,8 @@ void VoxelLodTerrain::_process(float delta) {
if (_collision_update_delay == 0 ||
static_cast<int>(now - block->last_collider_update_time) > _collision_update_delay) {
block->set_collision_mesh(mesh_data.surfaces, get_tree()->is_debugging_collisions_hint(), this);
block->set_collision_layer(_collision_layer);
block->set_collision_mask(_collision_mask);
block->last_collider_update_time = now;
block->has_deferred_collider_update = false;
block->deferred_collider_data.clear();
@ -1663,6 +1691,8 @@ void VoxelLodTerrain::process_deferred_collision_updates(uint32_t timeout_msec)
if (static_cast<int>(now - block->last_collider_update_time) > _collision_update_delay) {
block->set_collision_mesh(
block->deferred_collider_data, get_tree()->is_debugging_collisions_hint(), this);
block->set_collision_layer(_collision_layer);
block->set_collision_mask(_collision_mask);
block->last_collider_update_time = now;
block->has_deferred_collider_update = false;
block->deferred_collider_data.clear();
@ -2418,6 +2448,12 @@ void VoxelLodTerrain::_bind_methods() {
ClassDB::bind_method(D_METHOD("get_collision_lod_count"), &VoxelLodTerrain::get_collision_lod_count);
ClassDB::bind_method(D_METHOD("set_collision_lod_count", "count"), &VoxelLodTerrain::set_collision_lod_count);
ClassDB::bind_method(D_METHOD("get_collision_layer"), &VoxelLodTerrain::get_collision_layer);
ClassDB::bind_method(D_METHOD("set_collision_layer", "layer"), &VoxelLodTerrain::set_collision_layer);
ClassDB::bind_method(D_METHOD("get_collision_mask"), &VoxelLodTerrain::get_collision_mask);
ClassDB::bind_method(D_METHOD("set_collision_mask", "mask"), &VoxelLodTerrain::set_collision_mask);
ClassDB::bind_method(D_METHOD("get_collision_update_delay"), &VoxelLodTerrain::get_collision_update_delay);
ClassDB::bind_method(D_METHOD("set_collision_update_delay", "delay_msec"),
&VoxelLodTerrain::set_collision_update_delay);
@ -2494,9 +2530,12 @@ void VoxelLodTerrain::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "generate_collisions"),
"set_generate_collisions", "get_generate_collisions");
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_3D_PHYSICS),
"set_collision_layer", "get_collision_layer");
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS),
"set_collision_mask", "get_collision_mask");
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_lod_count"),
"set_collision_lod_count", "get_collision_lod_count");
// TODO Collision mask and layer
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_update_delay"),
"set_collision_update_delay", "get_collision_update_delay");

View File

@ -56,6 +56,12 @@ public:
void set_collision_lod_count(int lod_count);
int get_collision_lod_count() const;
void set_collision_layer(int layer);
int get_collision_layer() const;
void set_collision_mask(int mask);
int get_collision_mask() const;
int get_data_block_region_extent() const;
int get_mesh_block_region_extent() const;
@ -242,6 +248,8 @@ private:
bool _generate_collisions = true;
unsigned int _collision_lod_count = 0;
unsigned int _collision_layer = 1;
unsigned int _collision_mask = 1;
int _collision_update_delay = 0;
VoxelInstancer *_instancer = nullptr;

View File

@ -281,6 +281,18 @@ void VoxelMeshBlock::set_collision_mesh(Vector<Array> surface_arrays, bool debug
_static_body.set_shape_enabled(0, _visible);
}
void VoxelMeshBlock::set_collision_layer(int layer) {
if (_static_body.is_valid()) {
_static_body.set_collision_layer(layer);
}
}
void VoxelMeshBlock::set_collision_mask(int mask) {
if (_static_body.is_valid()) {
_static_body.set_collision_mask(mask);
}
}
void VoxelMeshBlock::drop_collision() {
if (_static_body.is_valid()) {
_static_body.destroy();

View File

@ -67,6 +67,8 @@ public:
// Collisions
void set_collision_mesh(Vector<Array> surface_arrays, bool debug_collision, Spatial *node);
void set_collision_layer(int layer);
void set_collision_mask(int mask);
void drop_collision();
// TODO Collision layer and mask

View File

@ -253,6 +253,28 @@ void VoxelTerrain::set_generate_collisions(bool enabled) {
_generate_collisions = enabled;
}
void VoxelTerrain::set_collision_layer(int layer) {
_collision_layer = layer;
_mesh_map.for_all_blocks([layer](VoxelMeshBlock *block) {
block->set_collision_layer(layer);
});
}
int VoxelTerrain::get_collision_layer() const {
return _collision_layer;
}
void VoxelTerrain::set_collision_mask(int mask) {
_collision_mask = mask;
_mesh_map.for_all_blocks([mask](VoxelMeshBlock *block) {
block->set_collision_mask(mask);
});
}
int VoxelTerrain::get_collision_mask() const {
return _collision_mask;
}
unsigned int VoxelTerrain::get_max_view_distance() const {
return _max_view_distance_voxels;
}
@ -1169,6 +1191,8 @@ void VoxelTerrain::_process() {
block->set_mesh(mesh);
if (gen_collisions) {
block->set_collision_mesh(collidable_surfaces, get_tree()->is_debugging_collisions_hint(), this);
block->set_collision_layer(_collision_layer);
block->set_collision_mask(_collision_mask);
}
block->set_visible(true);
block->set_parent_visible(is_visible());
@ -1287,6 +1311,12 @@ void VoxelTerrain::_bind_methods() {
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_collision_layer"), &VoxelTerrain::get_collision_layer);
ClassDB::bind_method(D_METHOD("set_collision_layer", "layer"), &VoxelTerrain::set_collision_layer);
ClassDB::bind_method(D_METHOD("get_collision_mask"), &VoxelTerrain::get_collision_mask);
ClassDB::bind_method(D_METHOD("set_collision_mask", "mask"), &VoxelTerrain::set_collision_mask);
ClassDB::bind_method(D_METHOD("voxel_to_data_block", "voxel_pos"), &VoxelTerrain::_b_voxel_to_data_block);
ClassDB::bind_method(D_METHOD("data_block_to_voxel", "block_pos"), &VoxelTerrain::_b_data_block_to_voxel);
@ -1317,6 +1347,10 @@ void VoxelTerrain::_bind_methods() {
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "generate_collisions"),
"set_generate_collisions", "get_generate_collisions");
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_layer", PROPERTY_HINT_LAYERS_3D_PHYSICS),
"set_collision_layer", "get_collision_layer");
ADD_PROPERTY(PropertyInfo(Variant::INT, "collision_mask", PROPERTY_HINT_LAYERS_3D_PHYSICS),
"set_collision_mask", "get_collision_mask");
ADD_GROUP("Advanced", "");

View File

@ -44,6 +44,12 @@ public:
void set_generate_collisions(bool enabled);
bool get_generate_collisions() const { return _generate_collisions; }
void set_collision_layer(int layer);
int get_collision_layer() const;
void set_collision_mask(int mask);
int get_collision_mask() const;
unsigned int get_max_view_distance() const;
void set_max_view_distance(unsigned int distance_in_voxels);
@ -189,6 +195,8 @@ private:
Ref<VoxelGenerator> _generator;
bool _generate_collisions = true;
unsigned int _collision_layer = 1;
unsigned int _collision_mask = 1;
bool _run_stream_in_editor = true;
//bool _stream_enabled = false;

View File

@ -93,6 +93,16 @@ void DirectStaticBody::set_attached_object(Object *obj) {
PhysicsServer::get_singleton()->body_attach_object_instance_id(_body, obj != nullptr ? obj->get_instance_id() : 0);
}
void DirectStaticBody::set_collision_layer(int layer) {
ERR_FAIL_COND(!_body.is_valid());
PhysicsServer::get_singleton()->body_set_collision_layer(_body, layer);
}
void DirectStaticBody::set_collision_mask(int mask) {
ERR_FAIL_COND(!_body.is_valid());
PhysicsServer::get_singleton()->body_set_collision_mask(_body, mask);
}
void DirectStaticBody::set_debug(bool enabled, World *world) {
ERR_FAIL_COND(world == nullptr);

View File

@ -23,6 +23,8 @@ public:
void set_world(World *world);
void set_shape_enabled(int shape_index, bool disabled);
void set_attached_object(Object *obj);
void set_collision_layer(int layer);
void set_collision_mask(int mask);
void set_debug(bool enabled, World *world);