mirror of
https://github.com/godotengine/godot.git
synced 2026-01-06 10:11:57 +03:00
Fix Area3D signal emissions when using Jolt Physics
This commit is contained in:
@@ -113,12 +113,14 @@ void JoltArea3D::_add_shape_pair(Overlap &p_overlap, const JPH::BodyID &p_body_i
|
||||
p_overlap.rid = other_object->get_rid();
|
||||
p_overlap.instance_id = other_object->get_instance_id();
|
||||
|
||||
ShapeIndexPair &shape_indices = p_overlap.shape_pairs[{ p_other_shape_id, p_self_shape_id }];
|
||||
HashMap<ShapeIDPair, ShapeIndexPair, ShapeIDPair>::Iterator shape_pair = p_overlap.shape_pairs.find(ShapeIDPair(p_other_shape_id, p_self_shape_id));
|
||||
if (shape_pair == p_overlap.shape_pairs.end()) {
|
||||
const int other_shape_index = other_object->find_shape_index(p_other_shape_id);
|
||||
const int self_shape_index = find_shape_index(p_self_shape_id);
|
||||
shape_pair = p_overlap.shape_pairs.insert(ShapeIDPair(p_other_shape_id, p_self_shape_id), ShapeIndexPair(other_shape_index, self_shape_index));
|
||||
}
|
||||
|
||||
shape_indices.other = other_object->find_shape_index(p_other_shape_id);
|
||||
shape_indices.self = find_shape_index(p_self_shape_id);
|
||||
|
||||
p_overlap.pending_added.push_back(shape_indices);
|
||||
p_overlap.pending_added.push_back(shape_pair->value);
|
||||
|
||||
_events_changed();
|
||||
}
|
||||
@@ -143,12 +145,20 @@ void JoltArea3D::_flush_events(OverlapsById &p_objects, const Callable &p_callba
|
||||
Overlap &overlap = E->value;
|
||||
|
||||
if (p_callback.is_valid()) {
|
||||
for (ShapeIndexPair &shape_indices : overlap.pending_removed) {
|
||||
_report_event(p_callback, PhysicsServer3D::AREA_BODY_REMOVED, overlap.rid, overlap.instance_id, shape_indices.other, shape_indices.self);
|
||||
for (const ShapeIndexPair &shape_indices : overlap.pending_added) {
|
||||
int &ref_count = overlap.ref_counts[shape_indices];
|
||||
if (ref_count++ == 0) {
|
||||
_report_event(p_callback, PhysicsServer3D::AREA_BODY_ADDED, overlap.rid, overlap.instance_id, shape_indices.other, shape_indices.self);
|
||||
}
|
||||
}
|
||||
|
||||
for (ShapeIndexPair &shape_indices : overlap.pending_added) {
|
||||
_report_event(p_callback, PhysicsServer3D::AREA_BODY_ADDED, overlap.rid, overlap.instance_id, shape_indices.other, shape_indices.self);
|
||||
for (const ShapeIndexPair &shape_indices : overlap.pending_removed) {
|
||||
int &ref_count = overlap.ref_counts[shape_indices];
|
||||
ERR_CONTINUE(ref_count <= 0);
|
||||
if (--ref_count == 0) {
|
||||
_report_event(p_callback, PhysicsServer3D::AREA_BODY_REMOVED, overlap.rid, overlap.instance_id, shape_indices.other, shape_indices.self);
|
||||
overlap.ref_counts.erase(shape_indices);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -73,6 +73,12 @@ private:
|
||||
ShapeIndexPair(int p_other, int p_self) :
|
||||
other(p_other), self(p_self) {}
|
||||
|
||||
static uint32_t hash(const ShapeIndexPair &p_pair) {
|
||||
uint32_t hash = hash_murmur3_one_32(p_pair.other);
|
||||
hash = hash_murmur3_one_32(p_pair.self, hash);
|
||||
return hash_fmix32(hash);
|
||||
}
|
||||
|
||||
friend bool operator==(const ShapeIndexPair &p_lhs, const ShapeIndexPair &p_rhs) {
|
||||
return (p_lhs.other == p_rhs.other) && (p_lhs.self == p_rhs.self);
|
||||
}
|
||||
@@ -80,6 +86,7 @@ private:
|
||||
|
||||
struct Overlap {
|
||||
HashMap<ShapeIDPair, ShapeIndexPair, ShapeIDPair> shape_pairs;
|
||||
HashMap<ShapeIndexPair, int, ShapeIndexPair> ref_counts;
|
||||
LocalVector<ShapeIndexPair> pending_added;
|
||||
LocalVector<ShapeIndexPair> pending_removed;
|
||||
RID rid;
|
||||
|
||||
@@ -304,7 +304,10 @@ void JoltShapedObject3D::commit_shapes(bool p_optimize_compound) {
|
||||
return;
|
||||
}
|
||||
|
||||
previous_jolt_shape = jolt_shape;
|
||||
if (previous_jolt_shape == nullptr) {
|
||||
previous_jolt_shape = jolt_shape;
|
||||
}
|
||||
|
||||
jolt_shape = new_shape;
|
||||
|
||||
space->get_body_iface().SetShape(jolt_body->GetID(), jolt_shape, false, JPH::EActivation::DontActivate);
|
||||
|
||||
Reference in New Issue
Block a user