Skip to content

Commit 7c62a9a

Browse files
committed
Document Jolt built-in module in 4.4
1 parent cb80512 commit 7c62a9a

File tree

2 files changed

+289
-0
lines changed

2 files changed

+289
-0
lines changed

tutorials/physics/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Physics
1010
:name: toc-learn-features-physics
1111

1212
physics_introduction
13+
using_jolt_physics
1314
rigid_body
1415
using_area_2d
1516
using_character_body_2d
Lines changed: 288 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,288 @@
1+
.. _doc_using_jolt_physics:
2+
3+
Using Jolt Physics
4+
==================
5+
6+
Overview
7+
--------
8+
9+
The Jolt physics engine was added as an alternative to the existing GodotPhysics3D
10+
physics engine in 4.4. Jolt is developed by Jorrit Rouwe with a focus on games and
11+
VR applications. Previously it was available as a extension but is now built into
12+
Godot.
13+
14+
It is important to note that the built in Jolt Physics module is considered
15+
**not finished**, **experimental**, and **lacks feature partiy** with both
16+
GodotPhysics3D, and the Jolt Extension. Behavior may change as it is developed
17+
further, please keep that in mind when choosing what to use for your project. A
18+
roadmap of this module can be found at the bottom of this page.
19+
20+
The existing extension is now considered in maintenance mode. That means bug fixes
21+
will be merged, and it will be kept compatible with new versions of Godot until
22+
the built-in module has feature parity with the extension. The extension can be
23+
found `here on GitHub <https://github.com/godot-jolt/godot-jolt>`_ and in Godot's asset
24+
library.
25+
26+
To change the 3D physics engine to the Jolt module go to
27+
:ref:`**Project Settings > Physics > 3D > Physics Engine**<class_ProjectSettings_property_physics/3D/Physics_Engine>`
28+
and select ``Jolt Physics`` from the dropdown menu. Once you've done that click the
29+
``Save & Restart`` button, when the editor opens again 3D scenes should now be using
30+
Jolt for physics.
31+
32+
Notable differences to Godot Physics
33+
------------------------------------
34+
35+
There are many differences between the existing GodotPhysics3D engine and Jolt.
36+
37+
Area3D and static bodies
38+
~~~~~~~~~~~~~~~~~~~~~~~~
39+
When using Jolt, :ref:`class_Area3D` will not detect overlaps with :ref:`class_StaticBody3D`
40+
(nor a :ref:`class_RigidBody3D` frozen with ``FREEZE_MODE_STATIC``) by default, for
41+
performance reasons. If you have many/large :ref:`class_Area3D` overlapping with
42+
complex static geometry, such as :ref:`class_ConcavePolygonShape3D` or
43+
:ref:`class_HeightMapShape3D`, you can end up wasting a significant amount of CPU
44+
performance without realizing it.
45+
46+
For this reason this behavior is opt-in through the project setting
47+
:ref:`physics/jolt_physics_3d/simulation/areas_detect_static_bodies<class_ProjectSettings_property_physics/jolt_physics_3d/simulation/areas_detect_static_bodies>`,
48+
with the recommendation that you set up your collision layers/masks in such a way that only
49+
the relevant :ref:`class_Area3D` are able to detect collisions with static bodies.
50+
51+
Joint properties
52+
~~~~~~~~~~~~~~~~
53+
54+
The current interfaces for the 3D joint nodes don't quite line up with the interface
55+
of Jolt's own joints. As such, there are a number of joint properties that are not
56+
supported, mainly ones related to configuring the joint's soft limits.
57+
58+
The unsupported properties are:
59+
60+
- PinJoint3D: ``bias``, ``damping``, ``impulse_clamp``
61+
- HingeJoint3D: ``bias``, ``softness``, ``relaxation``
62+
- SliderJoint3D: ``angular_\*``, ``\*_limit/softness``, ``\*_limit/restitution``, ``\*_limit/damping``
63+
- ConeTwistJoint3D: ``bias``, ``relaxation``, ``softness``
64+
- Generic6DOFJoint3D: ``*_limit_*/softness``, ``*_limit_*/restitution``, ``*_limit_*/damping``, ``*_limit_*/erp``
65+
66+
Currently an error is emitted if you set these properties to anything but their
67+
default values.
68+
69+
Single-body joints
70+
~~~~~~~~~~~~~~~~~~
71+
72+
You can, in Godot, omit one of the joint bodies for a two-body joint and effectively
73+
have "the world" be the other body. However, the node path that you assign your body
74+
to (node_a vs node_b) is ignored. Godot Physics will always behave as if you
75+
assigned it to node_a, and since node_a is also what defines the frame of reference
76+
for the joint limits, you end up with inverted limits and a potentially strange
77+
limit shape, especially if your limits allow both linear and angular degrees of
78+
freedom.
79+
80+
Jolt will behave as if you assigned the body to node_b instead, with node_a
81+
representing "the world". There is a project setting called :ref:`physics/jolt_physics_3d/joints/world_node<class_ProjectSettings_property_physics/jolt_physics_3d/joints/world_node>`
82+
that lets you toggle this behavior, if you need compatibility for an existing project.
83+
84+
Collision margins
85+
~~~~~~~~~~~~~~~~~
86+
87+
Jolt (and other similar physics engines) uses something that Jolt refers to as
88+
"convex radius" to help improve the performance and behavior of the types of
89+
collision detection that Jolt relies on for convex shapes. Other physics engines
90+
(Godot included) might refer to these as "collision margins" instead. Godot exposes
91+
these as the margin property on every Shape3D-derived class, as a leftover from the
92+
Bullet integration in Godot 3, but Godot Physics itself does not use them for
93+
anything.
94+
95+
What these collision margins sometimes do in other engines (as described in Godot's
96+
documentation) is effectively add a "shell" around the shape, slightly increasing
97+
its size while also rounding off any edges/corners. In Jolt however, these margins
98+
are first used to shrink the shape, and then the "shell" is applied, resulting in
99+
edges/corners being similarly rounded off, but without increasing the size of the
100+
shape.
101+
102+
To prevent having to tweak this margin property manually, since its default value
103+
can be problematic for smaller shapes, this module exposes a project setting called
104+
:ref:`physics/jolt_physics_3d/collisions/collision_margin_fraction<class_ProjectSettings_property_physics/jolt_physics_3d/collisions/collision_margin_fraction>`
105+
which is multiplied with the smallest axis of the shape's AABB to calculate the
106+
actual margin. The margin property of the shape is then instead used as an upper
107+
bound.
108+
109+
These margins should, for most use-cases, be more or less transparent, but can
110+
sometimes result in odd collision normals when performing shape queries. You can
111+
lower the above mentioned project setting to mitigate some of this, including
112+
setting it to ``0``, but too small of a margin can also cause odd collision results,
113+
so is generally not recommended.
114+
115+
Baumgarte stabilization
116+
~~~~~~~~~~~~~~~~~~~~~~~
117+
118+
Jolt employs a technique in its solver called Baumgarte stabilization, which is
119+
meant to mitigate constraint drift within the simulation, resulting in a more stable
120+
simulation. This technique can however result in some artifacts, like piles of
121+
bodies not separating as quickly as one might expect.
122+
123+
The strength of this stabilization can be tweaked using the project setting
124+
:ref:`physics/jolt_physics_3d/simulation/baumgarte_stabilization_factor<class_ProjectSettings_property_physics/jolt_physics_3d/simulation/baumgarte_stabilization_factor>`.
125+
Setting this project setting to ``1.0`` will resolve penetration in 1 simulation
126+
step, resulting in a simulation that more closely resembles Godot Physics, but which
127+
is also more unstable.
128+
129+
Ghost collisions
130+
~~~~~~~~~~~~~~~~
131+
132+
Jolt employs two techniques to mitigate ghost collisions, meaning collisions with
133+
internal edges of shapes/bodies.
134+
135+
The first technique, called "active edge detection", marks edges of triangles in
136+
:ref:`class_ConcavePolygonShape3D` or :ref:`class_HeightMapShape3D` as either "active" or "inactive", based on
137+
the angle to the neighboring triangle. When a collision happens with an inactive
138+
edge the collision normal will be replaced with the triangle's normal instead, to
139+
lessen the effect of ghost collisions.
140+
141+
The angle threshold for this active edge detection is configurable through the
142+
project setting :ref:`physics/jolt_physics_3d/collisions/active_edge_threshold<class_ProjectSettings_property_physics/jolt_physics_3d/collisions/active_edge_threshold>`.
143+
144+
The second technique, called "enhanced internal edge removal", instead adds runtime
145+
checks to detect whether an edge is active or inactive, based on the contact points
146+
of the two bodies. This has the benefit of applying not only to collisions with
147+
:ref:`class_ConcavePolygonShape3D` and :ref:`class_HeightMapShape3D`, but also edges between any shapes within
148+
the same body.
149+
150+
Enhanced internal edge removal can be toggled on and off for the various contexts to
151+
which it's applied, using the ``physics/jolt_physics_3d/*/use_enhanced_internal_edge_removal``
152+
project settings.
153+
154+
Memory usage
155+
~~~~~~~~~~~~
156+
157+
Jolt uses a stack allocator for temporary allocations within its simulation step.
158+
This stack allocator requires allocating a set amount of memory up front, which can
159+
be configured using the :ref:`physics/jolt_physics_3d/limits/temporary_memory_buffer_size<class_ProjectSettings_property_physics/jolt_physics_3d/limits/temporary_memory_buffer_size>`
160+
project setting.
161+
162+
Jolt also makes use of aligned allocations for some of its memory usage, which it
163+
acquires through function pointers that the implementer assigns. Aligned allocations
164+
were recently added to Godot in the form of ``Memory::alloc_aligned_static``,
165+
``Memory::realloc_aligned_static``, and ``Memory::free_aligned_static``, which have all been
166+
hooked up to Jolt. However, these aligned allocation functions don't currently touch
167+
``Memory::mem_usage``, which means that some of Jolt's memory won't be tracked, and thus
168+
the performance monitors in Godot won't be accurate.
169+
170+
Ray-Cast face index
171+
~~~~~~~~~~~~~~~~~~~
172+
173+
The face_index property returned in the results of intersect_ray and RayCast3D will
174+
by default always be ``-1`` with Jolt, the project setting :ref:`physics/jolt_physics_3d/queries/enable_ray_cast_face_index<class_ProjectSettings_property_physics/jolt_physics_3d/queries/enable_ray_cast_face_index>`
175+
will enable them. The reason for this being that Jolt does not store these indices,
176+
and for them to be stored per-triangle userdata must be enabled, which adds about
177+
25% extra memory usage to the underlying Jolt implementation of :ref:`class_ConcavePolygonShape3D`.
178+
179+
Kinematic RigidBody3D contacts
180+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
181+
182+
When using Jolt, a :ref:`class_RigidBody3D` frozen with ``FREEZE_MODE_KINEMATIC`` will by default not
183+
report contacts from collisions with other static/kinematic bodies, for performance
184+
reasons, even when setting a non-zero max_contacts_reported. If you have many/large
185+
kinematic bodies overlapping with complex static geometry, such as :ref:`class_ConcavePolygonShape3D`
186+
or :ref:`class_HeightMapShape3D`, you can end up wasting a significant amount of CPU
187+
performance without realizing it.
188+
189+
For this reason this behavior is opt-in through the project setting
190+
:ref:`physics/jolt_physics_3d/simulation/generate_all_kinematic_contacts<class_ProjectSettings_property_physics/jolt_physics_3d/simulation/generate_all_kinematic_contacts>`.
191+
192+
Contact impulses
193+
~~~~~~~~~~~~~~~~
194+
195+
Jolt is not able to provide any impulse as part of its contact data, due to how it
196+
orders its simulation step, and instead provides a helper function for estimating
197+
what the impulse would be based on various parameters. While this is fine for most
198+
use cases, like emitting a sound based on how hard something collided, it won't be
199+
accurate if a body is colliding with multiple bodies during a simulation step.
200+
201+
Area3D and SoftBody3D
202+
~~~~~~~~~~~~~~~~~~~~~
203+
204+
This module does not currently support any interactions between :ref:`class_SoftBody3D`
205+
and :ref:`class_Area3D`, such as overlap events, or the wind properties found on
206+
:ref:`class_Area3D`. Support for this has been added to Jolt recently, but it is not
207+
currently part of the built-in Jolt module.
208+
209+
WorldBoundaryShape3D
210+
~~~~~~~~~~~~~~~~~~~~
211+
212+
:ref:`class_WorldBoundaryShape3D`, which is meant to represent an infinite plane, is
213+
implemented a bit differently in Jolt compared to Godot Physics. Both engines have
214+
an upper limit for how big the effective size of this plane can be, but this size is
215+
much smaller when using Jolt, in order to avoid precision issues.
216+
217+
You can configure this size using the :ref:`physics/jolt_physics_3d/limits/world_boundary_shape_size<Class_ProjectSettings_Property_physics/jolt_physics_3d/limits/world_boundary_shape_size>`
218+
project setting.
219+
220+
Notable differences to Godot Jolt
221+
---------------------------------
222+
223+
While this module is largely a straight port of the Godot Jolt extension, with a lot
224+
of cosmetic changes, there are a few things that are different.
225+
226+
Project Settings
227+
~~~~~~~~~~~~~~~~
228+
229+
All project settings have been moved from the ``physics/jolt_3d`` category to
230+
``physics/jolt_physics_3d``.
231+
232+
On top of that, there's been some renaming and refactoring of the individual project
233+
settings as well. These include:
234+
235+
- ``sleep/enabled`` is now ``simulation/allow_sleep.``
236+
- ``sleep/velocity_threshold`` is now ``simulation/sleep_velocity_threshold.``
237+
- ``sleep/time_threshold`` is now ``simulation/sleep_time_threshold.``
238+
- ``collisions/use_shape_margins`` is now ``collisions/collision_margin_fraction``,
239+
where a value of 0 is equivalent to disabling it.
240+
- ``collisions/use_enhanced_internal_edge_removal`` is now ``simulation/use_enhanced_internal_edge_removal.``
241+
- ``collisions/areas_detect_static_bodies`` is now ``simulation/areas_detect_static_bodies.``
242+
- ``collisions/report_all_kinematic_contacts`` is now ``simulation/generate_all_kinematic_contacts.``
243+
- ``collisions/soft_body_point_margin`` is now ``simulation/soft_body_point_radius.``
244+
- ``collisions/body_pair_cache_enabled is now simulation/body_pair_contact_cache_enabled.``
245+
- ``collisions/body_pair_cache_distance_threshold`` is ``now simulation/body_pair_contact_cache_distance_threshold.``
246+
- ``collisions/body_pair_cache_angle_threshold is now simulation/body_pair_contact_cache_angle_threshold.``
247+
- ``continuous_cd/movement_threshold`` is now ``simulation/continuous_cd_movement_threshold``,
248+
but expressed as a fraction instead of a percentage.
249+
- ``continuous_cd/max_penetration`` is now ``simulation/continuous_cd_max_penetration``,
250+
but expressed as a fraction instead of a percentage.
251+
- ``kinematics/use_enhanced_internal_edge_removal`` is now ``motion_queries/use_enhanced_internal_edge_removal.``
252+
- ``kinematics/recovery_iterations`` is now ``motion_queries/recovery_iterations``,
253+
but expressed as a fraction instead of a percentage.
254+
- ``kinematics/recovery_amount`` is now ``motion_queries/recovery_amount.``
255+
- ``queries/use_legacy_ray_casting`` has been removed.
256+
- ``solver/position_iterations`` is now ``simulation/position_steps.``
257+
- ``solver/velocity_iterations`` is now ``simulation/velocity_steps.``
258+
- ``solver/position_correction`` is now ``simulation/baumgarte_stabilization_factor``,
259+
but expressed as a fraction instead of a percentage.
260+
- ``solver/active_edge_threshold`` is now ``collisions/active_edge_threshold.``
261+
- ``solver/bounce_velocity_threshold`` is now ``simulation/bounce_velocity_threshold.``
262+
- ``solver/contact_speculative_distance`` is now ``simulation/speculative_contact_distance.``
263+
- ``solver/contact_allowed_penetration`` is now ``simulation/penetration_slop.``
264+
- ``limits/max_angular_velocity`` is now stored as radians instead.
265+
- ``limits/max_temporary_memory`` is now ``limits/temporary_memory_buffer_size.``
266+
267+
There might be some discussion to be had with regards to migrating the settings
268+
values for projects who have previously been relying on the extension.
269+
270+
Joint Nodes
271+
~~~~~~~~~~~
272+
273+
The joint nodes that are exposed in the Godot Jolt extension (JoltPinJoint3D,
274+
JoltHingeJoint3D, JoltSliderJoint3D, JoltConeTwistJoint3D, and JoltGeneric6DOFJoint)
275+
have not been included with this module.
276+
277+
Thread Safety
278+
~~~~~~~~~~~~~
279+
280+
Unlike the Godot Jolt extension, this module does have experimental thread-safety,
281+
including support for the :ref:`physics/3d/run_on_separate_thread<class_ProjectSettings_Property_physics/3d/run_on_separate_thread>`
282+
project setting. This is achieved by utilizing the same wrapper server that's used
283+
by Godot Physics, called ``PhysicsServer3DWrapMT``, as well as introducing a mutex
284+
around the rebuilding of shapes, since concurrent shape-casts could otherwise
285+
trigger a race condition.
286+
287+
This has however not been tested very thoroughly, so should be considered
288+
experimental.

0 commit comments

Comments
 (0)