Fixed collision shape positions in PropInstanceMerger. Also improved it's collision shape / physics body handling.

This commit is contained in:
Relintai 2021-08-25 20:37:37 +02:00
parent 2568178b42
commit 7ccdbd474c
4 changed files with 45 additions and 19 deletions

View File

@ -271,7 +271,7 @@ RID PropInstanceMerger::collider_shape_rid_get(const int index) {
return _colliders[index].shape_rid; return _colliders[index].shape_rid;
} }
int PropInstanceMerger::collider_add(const Transform &local_transform, const Ref<Shape> &shape, const RID &shape_rid, const RID &body) { int PropInstanceMerger::collider_add(const Transform &local_transform, const Ref<Shape> &shape, const RID &shape_rid, const RID &body, const bool owns_shape) {
ERR_FAIL_COND_V(!shape.is_valid() && shape_rid == RID(), 0); ERR_FAIL_COND_V(!shape.is_valid() && shape_rid == RID(), 0);
int index = _colliders.size(); int index = _colliders.size();
@ -281,6 +281,7 @@ int PropInstanceMerger::collider_add(const Transform &local_transform, const Ref
e.body = body; e.body = body;
e.shape = shape; e.shape = shape;
e.shape_rid = shape_rid; e.shape_rid = shape_rid;
e.owns_shape = owns_shape;
_colliders.push_back(e); _colliders.push_back(e);
@ -449,8 +450,9 @@ void PropInstanceMerger::draw_debug_mdr_colliders() {
for (int i = 0; i < collider_get_num(); ++i) { for (int i = 0; i < collider_get_num(); ++i) {
Ref<Shape> shape = collider_shape_get(i); Ref<Shape> shape = collider_shape_get(i);
if (!shape.is_valid()) if (!shape.is_valid()) {
continue; continue;
}
Transform t = collider_local_transform_get(i); Transform t = collider_local_transform_get(i);
@ -481,9 +483,16 @@ void PropInstanceMerger::free_meshes() {
void PropInstanceMerger::free_colliders() { void PropInstanceMerger::free_colliders() {
for (int i = 0; i < _colliders.size(); ++i) { for (int i = 0; i < _colliders.size(); ++i) {
PhysicsServer::get_singleton()->free(_colliders[i].body); ColliderBody &e = _colliders.write[i];
_colliders.write[i].body = RID(); PhysicsServer::get_singleton()->free(e.body);
e.body = RID();
if (e.owns_shape) {
e.shape.unref();
e.shape_rid = RID();
}
} }
} }
@ -570,6 +579,8 @@ void PropInstanceMerger::_build_finished() {
apply_lod_level(); apply_lod_level();
check_auto_lod(); check_auto_lod();
notification(NOTIFICATION_TRANSFORM_CHANGED);
if (_build_queued) { if (_build_queued) {
call_deferred("build"); call_deferred("build");
} }
@ -618,7 +629,7 @@ void PropInstanceMerger::_prop_preprocess(Transform transform, const Ref<PropDat
//tt.origin += Vector3(hew, heh, 0); //tt.origin += Vector3(hew, heh, 0);
tt.translate(hew, heh, 0); tt.translate(hew, heh, 0);
_job->add_collision_shape(tws, tt); _job->add_collision_shape(tws, tt, true);
} }
continue; continue;
@ -840,9 +851,10 @@ void PropInstanceMerger::_notification(int p_what) {
case NOTIFICATION_TRANSFORM_CHANGED: { case NOTIFICATION_TRANSFORM_CHANGED: {
Transform new_transform = get_global_transform(); Transform new_transform = get_global_transform();
if (new_transform == _last_transform) { //Don't do this check, so this can be used to setmesh positions after a build
break; //if (new_transform == _last_transform) {
} // break;
//}
_last_transform = new_transform; _last_transform = new_transform;
@ -863,8 +875,10 @@ void PropInstanceMerger::_notification(int p_what) {
for (int i = 0; i < _colliders.size(); ++i) { for (int i = 0; i < _colliders.size(); ++i) {
const ColliderBody &c = _colliders[i]; const ColliderBody &c = _colliders[i];
if (c.body != RID()) {
PhysicsServer::get_singleton()->body_set_shape_transform(c.body, 0, new_transform * c.transform); PhysicsServer::get_singleton()->body_set_shape_transform(c.body, 0, new_transform * c.transform);
} }
}
break; break;
} }

View File

@ -92,7 +92,7 @@ public:
RID collider_body_get(const int index); RID collider_body_get(const int index);
Ref<Shape> collider_shape_get(const int index); Ref<Shape> collider_shape_get(const int index);
RID collider_shape_rid_get(const int index); RID collider_shape_rid_get(const int index);
int collider_add(const Transform &local_transform, const Ref<Shape> &shape, const RID &shape_rid, const RID &body); int collider_add(const Transform &local_transform, const Ref<Shape> &shape, const RID &shape_rid, const RID &body, const bool owns_shape = false);
int collider_get_num() const; int collider_get_num() const;
void colliders_clear(); void colliders_clear();
@ -135,6 +135,11 @@ protected:
RID body; RID body;
Ref<Shape> shape; Ref<Shape> shape;
RID shape_rid; RID shape_rid;
bool owns_shape;
ColliderBody() {
owns_shape = false;
}
}; };
struct MeshEntry { struct MeshEntry {

View File

@ -91,11 +91,12 @@ int PropInstancePropJob::get_jobs_step_count() const {
return _job_steps.size(); return _job_steps.size();
} }
void PropInstancePropJob::add_collision_shape(const Ref<Shape> &shape, const Transform &transform) { void PropInstancePropJob::add_collision_shape(const Ref<Shape> &shape, const Transform &transform, const bool owns_shape) {
CollisionShapeEntry e; CollisionShapeEntry e;
e.shape = shape; e.shape = shape;
e.transform = transform; e.transform = transform;
e.owns_shape = owns_shape;
_collision_shapes.push_back(e); _collision_shapes.push_back(e);
} }
@ -214,10 +215,11 @@ void PropInstancePropJob::_reset() {
void PropInstancePropJob::phase_physics_process() { void PropInstancePropJob::phase_physics_process() {
//TODO this should only update the differences //TODO this should only update the differences
for (int i = 0; i < _prop_instace->collider_get_num(); ++i) { //for (int i = 0; i < _prop_instace->collider_get_num(); ++i) {
PhysicsServer::get_singleton()->free(_prop_instace->collider_body_get(i)); // PhysicsServer::get_singleton()->free(_prop_instace->collider_body_get(i));
} //}
_prop_instace->free_colliders();
_prop_instace->colliders_clear(); _prop_instace->colliders_clear();
for (int i = 0; i < _collision_shapes.size(); ++i) { for (int i = 0; i < _collision_shapes.size(); ++i) {
@ -233,7 +235,6 @@ void PropInstancePropJob::phase_physics_process() {
//TODO store the layer mask somewhere //TODO store the layer mask somewhere
PhysicsServer::get_singleton()->body_set_collision_layer(body, 1); PhysicsServer::get_singleton()->body_set_collision_layer(body, 1);
PhysicsServer::get_singleton()->body_set_collision_mask(body, 1); PhysicsServer::get_singleton()->body_set_collision_mask(body, 1);
if (_prop_instace->is_inside_tree() && _prop_instace->is_inside_world()) { if (_prop_instace->is_inside_tree() && _prop_instace->is_inside_world()) {
@ -244,9 +245,9 @@ void PropInstancePropJob::phase_physics_process() {
} }
} }
PhysicsServer::get_singleton()->body_set_state(body, PhysicsServer::BODY_STATE_TRANSFORM, e.transform); //PhysicsServer::get_singleton()->body_set_state(body, PhysicsServer::BODY_STATE_TRANSFORM, e.transform);
_prop_instace->collider_add(e.transform, e.shape, e.shape->get_rid(), body); _prop_instace->collider_add(e.transform, e.shape, e.shape->get_rid(), body, e.owns_shape);
} }
#if TOOLS_ENABLED #if TOOLS_ENABLED
@ -322,7 +323,8 @@ void PropInstancePropJob::phase_prop() {
PTWEntry &e = _prop_tiled_wall_datas.write[i]; PTWEntry &e = _prop_tiled_wall_datas.write[i];
Ref<PropDataTiledWall> pdtw = e.data; Ref<PropDataTiledWall> pdtw = e.data;
Transform t = pdtw->get_transform(); //Transform t = pdtw->get_transform();
Transform t = e.base_transform;
_prop_mesher->add_tiled_wall_simple(pdtw->get_width(), pdtw->get_heigth(), t, pdtw->get_data(), _material_cache); _prop_mesher->add_tiled_wall_simple(pdtw->get_width(), pdtw->get_heigth(), t, pdtw->get_data(), _material_cache);
} }

View File

@ -51,7 +51,7 @@ public:
void add_jobs_step(const Ref<PropMesherJobStep> &step); void add_jobs_step(const Ref<PropMesherJobStep> &step);
int get_jobs_step_count() const; int get_jobs_step_count() const;
void add_collision_shape(const Ref<Shape> &shape, const Transform &transform); void add_collision_shape(const Ref<Shape> &shape, const Transform &transform, const bool owns_shape = false);
void clear_collision_shapes(); void clear_collision_shapes();
PropInstanceMerger *get_prop_instace(); PropInstanceMerger *get_prop_instace();
@ -115,6 +115,11 @@ protected:
struct CollisionShapeEntry { struct CollisionShapeEntry {
Ref<Shape> shape; Ref<Shape> shape;
Transform transform; Transform transform;
bool owns_shape;
CollisionShapeEntry() {
owns_shape = false;
}
}; };
Ref<PropMaterialCache> _material_cache; Ref<PropMaterialCache> _material_cache;