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

View File

@ -92,7 +92,7 @@ public:
RID collider_body_get(const int index);
Ref<Shape> collider_shape_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;
void colliders_clear();
@ -135,6 +135,11 @@ protected:
RID body;
Ref<Shape> shape;
RID shape_rid;
bool owns_shape;
ColliderBody() {
owns_shape = false;
}
};
struct MeshEntry {

View File

@ -91,11 +91,12 @@ int PropInstancePropJob::get_jobs_step_count() const {
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;
e.shape = shape;
e.transform = transform;
e.owns_shape = owns_shape;
_collision_shapes.push_back(e);
}
@ -214,10 +215,11 @@ void PropInstancePropJob::_reset() {
void PropInstancePropJob::phase_physics_process() {
//TODO this should only update the differences
for (int i = 0; i < _prop_instace->collider_get_num(); ++i) {
PhysicsServer::get_singleton()->free(_prop_instace->collider_body_get(i));
}
//for (int i = 0; i < _prop_instace->collider_get_num(); ++i) {
// PhysicsServer::get_singleton()->free(_prop_instace->collider_body_get(i));
//}
_prop_instace->free_colliders();
_prop_instace->colliders_clear();
for (int i = 0; i < _collision_shapes.size(); ++i) {
@ -233,7 +235,6 @@ void PropInstancePropJob::phase_physics_process() {
//TODO store the layer mask somewhere
PhysicsServer::get_singleton()->body_set_collision_layer(body, 1);
PhysicsServer::get_singleton()->body_set_collision_mask(body, 1);
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
@ -322,7 +323,8 @@ void PropInstancePropJob::phase_prop() {
PTWEntry &e = _prop_tiled_wall_datas.write[i];
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);
}

View File

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