Skip to content

Commit 6a60d72

Browse files
committed
Merge pull request godotengine#108544 from mihe/jolt/sleeping-contacts
Fix contacts not being reported properly when using Jolt Physics
2 parents c6d130a + 5a16e2f commit 6a60d72

File tree

6 files changed

+111
-1
lines changed

6 files changed

+111
-1
lines changed

modules/jolt_physics/objects/jolt_body_3d.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,8 @@ void JoltBody3D::_add_to_space() {
161161
}
162162

163163
void JoltBody3D::_enqueue_call_queries() {
164+
// This method will be called from the body activation listener on multiple threads during the simulation step.
165+
164166
if (space != nullptr) {
165167
space->enqueue_call_queries(&call_queries_element);
166168
}
@@ -299,6 +301,14 @@ JPH::MassProperties JoltBody3D::_calculate_mass_properties() const {
299301
return _calculate_mass_properties(*jolt_shape);
300302
}
301303

304+
void JoltBody3D::_on_wake_up() {
305+
// This method will be called from the body activation listener on multiple threads during the simulation step.
306+
307+
if (_should_call_queries()) {
308+
_enqueue_call_queries();
309+
}
310+
}
311+
302312
void JoltBody3D::_update_mass_properties() {
303313
if (in_space()) {
304314
jolt_body->GetMotionPropertiesUnchecked()->SetMassProperties(_calculate_allowed_dofs(), _calculate_mass_properties());

modules/jolt_physics/objects/jolt_body_3d.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ class JoltBody3D final : public JoltShapedObject3D {
5656
};
5757

5858
private:
59+
friend class JoltBodyActivationListener3D;
60+
5961
SelfList<JoltBody3D> call_queries_element;
6062

6163
LocalVector<RID> exceptions;
@@ -114,14 +116,15 @@ class JoltBody3D final : public JoltShapedObject3D {
114116
void _dequeue_call_queries();
115117

116118
void _integrate_forces(float p_step, JPH::Body &p_jolt_body);
117-
118119
void _move_kinematic(float p_step, JPH::Body &p_jolt_body);
119120

120121
JPH::EAllowedDOFs _calculate_allowed_dofs() const;
121122

122123
JPH::MassProperties _calculate_mass_properties(const JPH::Shape &p_shape) const;
123124
JPH::MassProperties _calculate_mass_properties() const;
124125

126+
void _on_wake_up();
127+
125128
void _update_mass_properties();
126129
void _update_gravity(JPH::Body &p_jolt_body);
127130
void _update_damp();
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
/**************************************************************************/
2+
/* jolt_body_activation_listener_3d.cpp */
3+
/**************************************************************************/
4+
/* This file is part of: */
5+
/* GODOT ENGINE */
6+
/* https://godotengine.org */
7+
/**************************************************************************/
8+
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9+
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10+
/* */
11+
/* Permission is hereby granted, free of charge, to any person obtaining */
12+
/* a copy of this software and associated documentation files (the */
13+
/* "Software"), to deal in the Software without restriction, including */
14+
/* without limitation the rights to use, copy, modify, merge, publish, */
15+
/* distribute, sublicense, and/or sell copies of the Software, and to */
16+
/* permit persons to whom the Software is furnished to do so, subject to */
17+
/* the following conditions: */
18+
/* */
19+
/* The above copyright notice and this permission notice shall be */
20+
/* included in all copies or substantial portions of the Software. */
21+
/* */
22+
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23+
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24+
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25+
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26+
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27+
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28+
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29+
/**************************************************************************/
30+
31+
#include "jolt_body_activation_listener_3d.h"
32+
33+
#include "../objects/jolt_body_3d.h"
34+
35+
void JoltBodyActivationListener3D::OnBodyActivated(const JPH::BodyID &p_body_id, JPH::uint64 p_body_user_data) {
36+
// This method will be called on multiple threads during the simulation step.
37+
38+
if (JoltBody3D *body = reinterpret_cast<JoltObject3D *>(p_body_user_data)->as_body()) {
39+
body->_on_wake_up();
40+
}
41+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**************************************************************************/
2+
/* jolt_body_activation_listener_3d.h */
3+
/**************************************************************************/
4+
/* This file is part of: */
5+
/* GODOT ENGINE */
6+
/* https://godotengine.org */
7+
/**************************************************************************/
8+
/* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
9+
/* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
10+
/* */
11+
/* Permission is hereby granted, free of charge, to any person obtaining */
12+
/* a copy of this software and associated documentation files (the */
13+
/* "Software"), to deal in the Software without restriction, including */
14+
/* without limitation the rights to use, copy, modify, merge, publish, */
15+
/* distribute, sublicense, and/or sell copies of the Software, and to */
16+
/* permit persons to whom the Software is furnished to do so, subject to */
17+
/* the following conditions: */
18+
/* */
19+
/* The above copyright notice and this permission notice shall be */
20+
/* included in all copies or substantial portions of the Software. */
21+
/* */
22+
/* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */
23+
/* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */
24+
/* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */
25+
/* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */
26+
/* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */
27+
/* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */
28+
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
29+
/**************************************************************************/
30+
31+
#pragma once
32+
33+
#include "Jolt/Jolt.h"
34+
35+
#include "Jolt/Physics/Body/BodyActivationListener.h"
36+
37+
class JoltBodyActivationListener3D final
38+
: public JPH::BodyActivationListener {
39+
public:
40+
virtual void OnBodyActivated(const JPH::BodyID &p_body_id, JPH::uint64 p_body_user_data) override;
41+
virtual void OnBodyDeactivated(const JPH::BodyID &p_body_id, JPH::uint64 p_body_user_data) override {}
42+
};

modules/jolt_physics/spaces/jolt_space_3d.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "../objects/jolt_body_3d.h"
3939
#include "../shapes/jolt_custom_shape_type.h"
4040
#include "../shapes/jolt_shape_3d.h"
41+
#include "jolt_body_activation_listener_3d.h"
4142
#include "jolt_contact_listener_3d.h"
4243
#include "jolt_layers.h"
4344
#include "jolt_physics_direct_space_state_3d.h"
@@ -101,6 +102,7 @@ JoltSpace3D::JoltSpace3D(JPH::JobSystem *p_job_system) :
101102
temp_allocator(new JoltTempAllocator()),
102103
layers(new JoltLayers()),
103104
contact_listener(new JoltContactListener3D(this)),
105+
body_activation_listener(new JoltBodyActivationListener3D()),
104106
physics_system(new JPH::PhysicsSystem()) {
105107
physics_system->Init((JPH::uint)JoltProjectSettings::max_bodies, 0, (JPH::uint)JoltProjectSettings::max_body_pairs, (JPH::uint)JoltProjectSettings::max_contact_constraints, *layers, *layers, *layers);
106108

@@ -124,6 +126,7 @@ JoltSpace3D::JoltSpace3D(JPH::JobSystem *p_job_system) :
124126
physics_system->SetGravity(JPH::Vec3::sZero());
125127
physics_system->SetContactListener(contact_listener);
126128
physics_system->SetSoftBodyContactListener(contact_listener);
129+
physics_system->SetBodyActivationListener(body_activation_listener);
127130

128131
physics_system->SetSimCollideBodyVsBody([](const JPH::Body &p_body1, const JPH::Body &p_body2, JPH::Mat44Arg p_transform_com1, JPH::Mat44Arg p_transform_com2, JPH::CollideShapeSettings &p_collide_shape_settings, JPH::CollideShapeCollector &p_collector, const JPH::ShapeFilter &p_shape_filter) {
129132
if (p_body1.IsSensor() || p_body2.IsSensor()) {
@@ -157,6 +160,11 @@ JoltSpace3D::~JoltSpace3D() {
157160
physics_system = nullptr;
158161
}
159162

163+
if (body_activation_listener != nullptr) {
164+
delete body_activation_listener;
165+
body_activation_listener = nullptr;
166+
}
167+
160168
if (contact_listener != nullptr) {
161169
delete contact_listener;
162170
contact_listener = nullptr;
@@ -488,6 +496,9 @@ void JoltSpace3D::set_is_object_sleeping(const JPH::BodyID &p_jolt_id, bool p_en
488496
}
489497

490498
void JoltSpace3D::enqueue_call_queries(SelfList<JoltBody3D> *p_body) {
499+
// This method will be called from the body activation listener on multiple threads during the simulation step.
500+
MutexLock body_call_queries_lock(body_call_queries_mutex);
501+
491502
if (!p_body->in_list()) {
492503
body_call_queries_list.add(p_body);
493504
}

modules/jolt_physics/spaces/jolt_space_3d.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444

4545
class JoltArea3D;
4646
class JoltBody3D;
47+
class JoltBodyActivationListener3D;
4748
class JoltContactListener3D;
4849
class JoltJoint3D;
4950
class JoltLayers;
@@ -54,6 +55,7 @@ class JoltSoftBody3D;
5455

5556
class JoltSpace3D {
5657
Mutex pending_objects_mutex;
58+
Mutex body_call_queries_mutex;
5759

5860
SelfList<JoltBody3D>::List body_call_queries_list;
5961
SelfList<JoltArea3D>::List area_call_queries_list;
@@ -69,6 +71,7 @@ class JoltSpace3D {
6971
JPH::TempAllocator *temp_allocator = nullptr;
7072
JoltLayers *layers = nullptr;
7173
JoltContactListener3D *contact_listener = nullptr;
74+
JoltBodyActivationListener3D *body_activation_listener = nullptr;
7275
JPH::PhysicsSystem *physics_system = nullptr;
7376
JoltPhysicsDirectSpaceState3D *direct_state = nullptr;
7477
JoltArea3D *default_area = nullptr;

0 commit comments

Comments
 (0)