@@ -128,6 +128,7 @@ void JoltBody3D::_add_to_space() {
128
128
jolt_settings->mAllowDynamicOrKinematic = true ;
129
129
jolt_settings->mCollideKinematicVsNonDynamic = reports_all_kinematic_contacts ();
130
130
jolt_settings->mUseManifoldReduction = !reports_contacts ();
131
+ jolt_settings->mAllowSleeping = is_sleep_actually_allowed ();
131
132
jolt_settings->mLinearDamping = 0 .0f ;
132
133
jolt_settings->mAngularDamping = 0 .0f ;
133
134
jolt_settings->mMaxLinearVelocity = JoltProjectSettings::get_max_linear_velocity ();
@@ -153,11 +154,19 @@ void JoltBody3D::_add_to_space() {
153
154
jolt_settings = nullptr ;
154
155
}
155
156
156
- void JoltBody3D::_integrate_forces (float p_step, JPH::Body &p_jolt_body) {
157
- if (!p_jolt_body.IsActive ()) {
158
- return ;
157
+ void JoltBody3D::_enqueue_call_queries () {
158
+ if (space != nullptr ) {
159
+ space->enqueue_call_queries (&call_queries_element);
160
+ }
161
+ }
162
+
163
+ void JoltBody3D::_dequeue_call_queries () {
164
+ if (space != nullptr ) {
165
+ space->dequeue_call_queries (&call_queries_element);
159
166
}
167
+ }
160
168
169
+ void JoltBody3D::_integrate_forces (float p_step, JPH::Body &p_jolt_body) {
161
170
_update_gravity (p_jolt_body);
162
171
163
172
if (!custom_integrator) {
@@ -182,8 +191,6 @@ void JoltBody3D::_integrate_forces(float p_step, JPH::Body &p_jolt_body) {
182
191
p_jolt_body.AddForce (to_jolt (constant_force));
183
192
p_jolt_body.AddTorque (to_jolt (constant_torque));
184
193
}
185
-
186
- sync_state = true ;
187
194
}
188
195
189
196
void JoltBody3D::_move_kinematic (float p_step, JPH::Body &p_jolt_body) {
@@ -201,27 +208,19 @@ void JoltBody3D::_move_kinematic(float p_step, JPH::Body &p_jolt_body) {
201
208
}
202
209
203
210
p_jolt_body.MoveKinematic (new_position, new_rotation, p_step);
204
-
205
- sync_state = true ;
206
- }
207
-
208
- void JoltBody3D::_pre_step_static (float p_step, JPH::Body &p_jolt_body) {
209
- // Nothing to do.
210
211
}
211
212
212
213
void JoltBody3D::_pre_step_rigid (float p_step, JPH::Body &p_jolt_body) {
213
214
_integrate_forces (p_step, p_jolt_body);
215
+ _enqueue_call_queries ();
214
216
}
215
217
216
218
void JoltBody3D::_pre_step_kinematic (float p_step, JPH::Body &p_jolt_body) {
217
219
_update_gravity (p_jolt_body);
218
-
219
220
_move_kinematic (p_step, p_jolt_body);
220
221
221
222
if (reports_contacts ()) {
222
- // This seems to emulate the behavior of Godot Physics, where kinematic bodies are set as active (and thereby
223
- // have their state synchronized on every step) only if its max reported contacts is non-zero.
224
- sync_state = true ;
223
+ _enqueue_call_queries ();
225
224
}
226
225
}
227
226
@@ -428,6 +427,20 @@ void JoltBody3D::_update_possible_kinematic_contacts() {
428
427
}
429
428
}
430
429
430
+ void JoltBody3D::_update_sleep_allowed () {
431
+ const bool value = is_sleep_actually_allowed ();
432
+
433
+ if (!in_space ()) {
434
+ jolt_settings->mAllowSleeping = value;
435
+ return ;
436
+ }
437
+
438
+ const JoltWritableBody3D body = space->write_body (jolt_id);
439
+ ERR_FAIL_COND (body.is_invalid ());
440
+
441
+ body->SetAllowSleeping (value);
442
+ }
443
+
431
444
void JoltBody3D::_destroy_joint_constraints () {
432
445
for (JoltJoint3D *joint : joints) {
433
446
joint->destroy ();
@@ -460,6 +473,7 @@ void JoltBody3D::_mode_changed() {
460
473
_update_object_layer ();
461
474
_update_kinematic_transform ();
462
475
_update_mass_properties ();
476
+ _update_sleep_allowed ();
463
477
wake_up ();
464
478
}
465
479
@@ -478,6 +492,7 @@ void JoltBody3D::_space_changing() {
478
492
479
493
_destroy_joint_constraints ();
480
494
_exit_all_areas ();
495
+ _dequeue_call_queries ();
481
496
}
482
497
483
498
void JoltBody3D::_space_changed () {
@@ -486,9 +501,8 @@ void JoltBody3D::_space_changed() {
486
501
_update_kinematic_transform ();
487
502
_update_group_filter ();
488
503
_update_joint_constraints ();
504
+ _update_sleep_allowed ();
489
505
_areas_changed ();
490
-
491
- sync_state = false ;
492
506
}
493
507
494
508
void JoltBody3D::_areas_changed () {
@@ -519,11 +533,18 @@ void JoltBody3D::_axis_lock_changed() {
519
533
520
534
void JoltBody3D::_contact_reporting_changed () {
521
535
_update_possible_kinematic_contacts ();
536
+ _update_sleep_allowed ();
537
+ wake_up ();
538
+ }
539
+
540
+ void JoltBody3D::_sleep_allowed_changed () {
541
+ _update_sleep_allowed ();
522
542
wake_up ();
523
543
}
524
544
525
545
JoltBody3D::JoltBody3D () :
526
- JoltShapedObject3D(OBJECT_TYPE_BODY) {
546
+ JoltShapedObject3D(OBJECT_TYPE_BODY),
547
+ call_queries_element(this ) {
527
548
}
528
549
529
550
JoltBody3D::~JoltBody3D () {
@@ -573,7 +594,7 @@ Variant JoltBody3D::get_state(PhysicsServer3D::BodyState p_state) const {
573
594
return is_sleeping ();
574
595
}
575
596
case PhysicsServer3D::BODY_STATE_CAN_SLEEP: {
576
- return can_sleep ();
597
+ return is_sleep_allowed ();
577
598
}
578
599
default : {
579
600
ERR_FAIL_V_MSG (Variant (), vformat (" Unhandled body state: '%d'. This should not happen. Please report this." , p_state));
@@ -596,7 +617,7 @@ void JoltBody3D::set_state(PhysicsServer3D::BodyState p_state, const Variant &p_
596
617
set_is_sleeping (p_value);
597
618
} break ;
598
619
case PhysicsServer3D::BODY_STATE_CAN_SLEEP: {
599
- set_can_sleep (p_value);
620
+ set_is_sleep_allowed (p_value);
600
621
} break ;
601
622
default : {
602
623
ERR_FAIL_MSG (vformat (" Unhandled body state: '%d'. This should not happen. Please report this." , p_state));
@@ -712,6 +733,10 @@ bool JoltBody3D::is_sleeping() const {
712
733
return !body->IsActive ();
713
734
}
714
735
736
+ bool JoltBody3D::is_sleep_actually_allowed () const {
737
+ return sleep_allowed && !(is_kinematic () && reports_contacts ());
738
+ }
739
+
715
740
void JoltBody3D::set_is_sleeping (bool p_enabled) {
716
741
if (!in_space ()) {
717
742
sleep_initially = p_enabled;
@@ -727,27 +752,14 @@ void JoltBody3D::set_is_sleeping(bool p_enabled) {
727
752
}
728
753
}
729
754
730
- bool JoltBody3D::can_sleep () const {
731
- if (!in_space ()) {
732
- return jolt_settings->mAllowSleeping ;
733
- }
734
-
735
- const JoltReadableBody3D body = space->read_body (jolt_id);
736
- ERR_FAIL_COND_V (body.is_invalid (), false );
737
-
738
- return body->GetAllowSleeping ();
739
- }
740
-
741
- void JoltBody3D::set_can_sleep (bool p_enabled) {
742
- if (!in_space ()) {
743
- jolt_settings->mAllowSleeping = p_enabled;
755
+ void JoltBody3D::set_is_sleep_allowed (bool p_enabled) {
756
+ if (sleep_allowed == p_enabled) {
744
757
return ;
745
758
}
746
759
747
- const JoltWritableBody3D body = space->write_body (jolt_id);
748
- ERR_FAIL_COND (body.is_invalid ());
760
+ sleep_allowed = p_enabled;
749
761
750
- body-> SetAllowSleeping (p_enabled );
762
+ _sleep_allowed_changed ( );
751
763
}
752
764
753
765
Basis JoltBody3D::get_principal_inertia_axes () const {
@@ -1187,11 +1199,7 @@ void JoltBody3D::remove_joint(JoltJoint3D *p_joint) {
1187
1199
_joints_changed ();
1188
1200
}
1189
1201
1190
- void JoltBody3D::call_queries (JPH::Body &p_jolt_body) {
1191
- if (!sync_state) {
1192
- return ;
1193
- }
1194
-
1202
+ void JoltBody3D::call_queries () {
1195
1203
if (custom_integration_callback.is_valid ()) {
1196
1204
const Variant direct_state_variant = get_direct_state ();
1197
1205
const Variant *args[2 ] = { &direct_state_variant, &custom_integration_userdata };
@@ -1218,16 +1226,14 @@ void JoltBody3D::call_queries(JPH::Body &p_jolt_body) {
1218
1226
ERR_PRINT_ONCE (vformat (" Failed to call state synchronization callback for '%s'. It returned the following error: '%s'." , to_string (), Variant::get_callable_error_text (state_sync_callback, args, 1 , ce)));
1219
1227
}
1220
1228
}
1221
-
1222
- sync_state = false ;
1223
1229
}
1224
1230
1225
1231
void JoltBody3D::pre_step (float p_step, JPH::Body &p_jolt_body) {
1226
1232
JoltObject3D::pre_step (p_step, p_jolt_body);
1227
1233
1228
1234
switch (mode) {
1229
1235
case PhysicsServer3D::BODY_MODE_STATIC: {
1230
- _pre_step_static (p_step, p_jolt_body);
1236
+ // Will never happen.
1231
1237
} break ;
1232
1238
case PhysicsServer3D::BODY_MODE_RIGID:
1233
1239
case PhysicsServer3D::BODY_MODE_RIGID_LINEAR: {
0 commit comments