Moved simple collider storage from VoxelChunkDefault to VoxelChunk and separated it from the mesh data resource api.

This commit is contained in:
Relintai 2020-06-30 18:55:50 +02:00
parent 138614f743
commit 3190217284
4 changed files with 136 additions and 44 deletions

View File

@ -716,10 +716,8 @@ void VoxelChunkDefault::update_transforms() {
}
}
for (int i = 0; i < _collider_bodies.size(); ++i) {
const MDRColliders &c = _collider_bodies[i];
PhysicsServer::get_singleton()->body_set_state(c.body, PhysicsServer::BODY_STATE_TRANSFORM, get_transform() * c.transform);
for (int i = 0; i < get_collider_count(); ++i) {
PhysicsServer::get_singleton()->body_set_state(get_collider_body(i), PhysicsServer::BODY_STATE_TRANSFORM, get_transform() * get_collider_transform(i));
}
if (_debug_mesh_instance != RID()) {
@ -894,7 +892,6 @@ void VoxelChunkDefault::draw_debug_voxel_lights() {
debug_mesh_send();
}
#ifdef MESH_DATA_RESOURCE_PRESENT
void VoxelChunkDefault::draw_debug_mdr_colliders() {
if (!debug_mesh_has()) {
debug_mesh_allocate();
@ -919,7 +916,6 @@ void VoxelChunkDefault::draw_debug_mdr_colliders() {
}
}
}
#endif
void VoxelChunkDefault::_visibility_changed(bool visible) {
if (visible) {
@ -1182,14 +1178,6 @@ VoxelChunkDefault::~VoxelChunkDefault() {
_lights.clear();
debug_mesh_free();
#if MESH_DATA_RESOURCE_PRESENT
for (int i = 0; i < _collider_bodies.size(); ++i) {
PhysicsServer::get_singleton()->free(_collider_bodies[i].body);
}
_collider_bodies.clear();
#endif
}
void VoxelChunkDefault::_setup_channels() {
@ -1736,13 +1724,12 @@ void VoxelChunkDefault::_build_phase_physics_process(int phase) {
temp_arr_collider_liquid.resize(0);
}
#if MESH_DATA_RESOURCE_PRESENT
//TODO this should only update the differences
for (int i = 0; i < _collider_bodies.size(); ++i) {
PhysicsServer::get_singleton()->free(_collider_bodies[i].body);
for (int i = 0; i < get_collider_count(); ++i) {
PhysicsServer::get_singleton()->free(get_collider_body(i));
}
_collider_bodies.clear();
clear_colliders();
for (int i = 0; i < get_mesh_data_resource_count(); ++i) {
Ref<MeshDataResource> mdr = get_mesh_data_resource(i);
@ -1755,13 +1742,10 @@ void VoxelChunkDefault::_build_phase_physics_process(int phase) {
continue;
}
MDRColliders c;
RID body = PhysicsServer::get_singleton()->body_create(PhysicsServer::BODY_MODE_STATIC);
c.body = body;
c.transform = get_mesh_data_resource_transform(i);
c.transform *= offset;
Transform transform = get_mesh_data_resource_transform(i);
transform *= offset;
PhysicsServer::get_singleton()->body_add_shape(body, shape->get_rid());
@ -1777,18 +1761,16 @@ void VoxelChunkDefault::_build_phase_physics_process(int phase) {
}
}
PhysicsServer::get_singleton()->body_set_state(body, PhysicsServer::BODY_STATE_TRANSFORM, get_transform() * c.transform);
PhysicsServer::get_singleton()->body_set_state(body, PhysicsServer::BODY_STATE_TRANSFORM, get_transform() * transform);
_collider_bodies.push_back(c);
add_collider(transform, shape, shape->get_rid(), body);
}
}
#if TOOLS_ENABLED
if (SceneTree::get_singleton()->is_debugging_collisions_hint() && _collider_bodies.size() > 0) {
if (SceneTree::get_singleton()->is_debugging_collisions_hint() && get_collider_count() > 0) {
draw_debug_mdr_colliders();
}
#endif
#endif
set_active_build_phase_type(BUILD_PHASE_TYPE_NORMAL);
@ -1938,9 +1920,7 @@ void VoxelChunkDefault::_bind_methods() {
ClassDB::bind_method(D_METHOD("draw_debug_voxels", "max", "color"), &VoxelChunkDefault::draw_debug_voxels, DEFVAL(Color(1, 1, 1)));
ClassDB::bind_method(D_METHOD("draw_debug_voxel_lights"), &VoxelChunkDefault::draw_debug_voxel_lights);
#ifdef MESH_DATA_RESOURCE_PRESENT
ClassDB::bind_method(D_METHOD("draw_debug_mdr_colliders"), &VoxelChunkDefault::draw_debug_mdr_colliders);
#endif
//Free
ClassDB::bind_method(D_METHOD("free_chunk"), &VoxelChunkDefault::free_chunk);

View File

@ -215,9 +215,7 @@ public:
void draw_cross_voxels_fill(Vector3 pos, float fill);
void draw_debug_voxels(int max, Color color = Color(1, 1, 1));
void draw_debug_voxel_lights();
#ifdef MESH_DATA_RESOURCE_PRESENT
void draw_debug_mdr_colliders();
#endif
//Visibility
void visibility_changed(bool visible);
@ -233,14 +231,6 @@ public:
VoxelChunkDefault();
~VoxelChunkDefault();
#if MESH_DATA_RESOURCE_PRESENT
protected:
struct MDRColliders {
Transform transform;
RID body;
};
#endif
protected:
virtual void _setup_channels();
virtual void _build_phase(int phase);
@ -306,9 +296,6 @@ protected:
ActiveBuildPhaseType _active_build_phase_type;
Vector<Ref<VoxelLight> > _lights;
#if MESH_DATA_RESOURCE_PRESENT
Vector<MDRColliders> _collider_bodies;
#endif
};
VARIANT_ENUM_CAST(VoxelChunkDefault::DefaultChannels);

View File

@ -803,6 +803,79 @@ void VoxelChunk::clear_mesh_data_resources() {
#endif
int VoxelChunk::add_collider(const Transform &local_transform, const Ref<Shape> &shape, const RID &shape_rid, const RID &body) {
ERR_FAIL_COND_V(!shape.is_valid() && shape_rid == RID(), 0);
int index = _colliders.size();
ColliderBody e;
e.transform = local_transform;
e.body = body;
e.shape = shape;
e.shape_rid = shape_rid;
_colliders.push_back(e);
return index;
}
Transform VoxelChunk::get_collider_transform(const int index) {
ERR_FAIL_INDEX_V(index, _colliders.size(), Transform());
return _colliders[index].transform;
}
void VoxelChunk::set_collider_transform(const int index, const Transform &transform) {
ERR_FAIL_INDEX(index, _colliders.size());
_colliders.write[index].transform = transform;
}
Ref<Shape> VoxelChunk::get_collider_shape(const int index) {
ERR_FAIL_INDEX_V(index, _colliders.size(), Ref<MeshDataResource>());
return _colliders[index].shape;
}
void VoxelChunk::set_collider_shape(const int index, const Ref<Shape> &shape) {
ERR_FAIL_INDEX(index, _colliders.size());
_colliders.write[index].shape = shape;
}
RID VoxelChunk::get_collider_shape_rid(const int index) {
ERR_FAIL_INDEX_V(index, _colliders.size(), RID());
return _colliders[index].shape_rid;
}
void VoxelChunk::set_collider_shape_rid(const int index, const RID &rid) {
ERR_FAIL_INDEX(index, _colliders.size());
_colliders.write[index].shape_rid = rid;
}
RID VoxelChunk::get_collider_body(const int index) {
ERR_FAIL_INDEX_V(index, _colliders.size(), RID());
return _colliders[index].body;
}
void VoxelChunk::set_collider_body(const int index, const RID &rid) {
ERR_FAIL_INDEX(index, _colliders.size());
_colliders.write[index].body = rid;
}
int VoxelChunk::get_collider_count() const {
return _colliders.size();
}
void VoxelChunk::remove_collider(const int index) {
ERR_FAIL_INDEX(index, _colliders.size());
_colliders.remove(index);
}
void VoxelChunk::clear_colliders() {
_colliders.clear();
}
void VoxelChunk::enter_tree() {
_is_in_tree = true;
@ -897,6 +970,12 @@ VoxelChunk::~VoxelChunk() {
memdelete_arr(ch);
}
}
for (int i = 0; i < _colliders.size(); ++i) {
PhysicsServer::get_singleton()->free(_colliders[i].body);
}
_colliders.clear();
}
void VoxelChunk::_world_transform_changed() {
@ -1159,6 +1238,24 @@ void VoxelChunk::_bind_methods() {
ClassDB::bind_method(D_METHOD("clear_mesh_data_resources"), &VoxelChunk::clear_mesh_data_resources);
#endif
ClassDB::bind_method(D_METHOD("add_collider", "local_transform", "shape", "shape_rid", "body"), &VoxelChunk::add_collider, DEFVAL(RID()), DEFVAL(RID()));
ClassDB::bind_method(D_METHOD("get_collider_transform", "index"), &VoxelChunk::get_collider_transform);
ClassDB::bind_method(D_METHOD("set_collider_transform", "index", "transform"), &VoxelChunk::set_collider_transform);
ClassDB::bind_method(D_METHOD("get_collider_shape", "index"), &VoxelChunk::get_collider_shape);
ClassDB::bind_method(D_METHOD("set_collider_shape", "index", "shape"), &VoxelChunk::set_collider_shape);
ClassDB::bind_method(D_METHOD("get_collider_shape_rid", "index"), &VoxelChunk::get_collider_shape_rid);
ClassDB::bind_method(D_METHOD("set_collider_shape_rid", "index", "rid"), &VoxelChunk::set_collider_shape_rid);
ClassDB::bind_method(D_METHOD("get_collider_body", "index"), &VoxelChunk::get_collider_body);
ClassDB::bind_method(D_METHOD("set_collider_body", "index", "rid"), &VoxelChunk::set_collider_body);
ClassDB::bind_method(D_METHOD("get_collider_count"), &VoxelChunk::get_collider_count);
ClassDB::bind_method(D_METHOD("remove_collider", "index"), &VoxelChunk::remove_collider);
ClassDB::bind_method(D_METHOD("clear_colliders"), &VoxelChunk::clear_colliders);
ClassDB::bind_method(D_METHOD("create_meshers"), &VoxelChunk::create_meshers);
ClassDB::bind_method(D_METHOD("_world_transform_changed"), &VoxelChunk::_world_transform_changed);

View File

@ -222,6 +222,25 @@ public:
void clear_mesh_data_resources();
#endif
//Colliders
int add_collider(const Transform &local_transform, const Ref<Shape> &shape, const RID &shape_rid = RID(), const RID &body = RID());
Transform get_collider_transform(const int index);
void set_collider_transform(const int index, const Transform &transform);
Ref<Shape> get_collider_shape(const int index);
void set_collider_shape(const int index, const Ref<Shape> &shape);
RID get_collider_shape_rid(const int index);
void set_collider_shape_rid(const int index, const RID &rid);
RID get_collider_body(const int index);
void set_collider_body(const int index, const RID &rid);
int get_collider_count() const;
void remove_collider(const int index);
void clear_colliders();
//handlers
void enter_tree();
void exit_tree();
@ -238,8 +257,8 @@ public:
VoxelChunk();
~VoxelChunk();
#if MESH_DATA_RESOURCE_PRESENT
protected:
#if MESH_DATA_RESOURCE_PRESENT
struct MeshDataResourceEntry {
Ref<MeshDataResource> mesh;
Ref<Texture> texture;
@ -249,6 +268,13 @@ protected:
};
#endif
struct ColliderBody {
Transform transform;
RID body;
Ref<Shape> shape;
RID shape_rid;
};
protected:
virtual void _world_transform_changed();
@ -304,6 +330,8 @@ protected:
Vector<MeshDataResourceEntry> _mesh_data_resources;
#endif
Vector<ColliderBody> _colliders;
Transform _transform;
};