|
| 1 | +.. _doc_using_jolt_physics: |
| 2 | + |
| 3 | +Using Jolt Physics |
| 4 | +================== |
| 5 | + |
| 6 | +Introduction |
| 7 | +------------ |
| 8 | + |
| 9 | +The Jolt physics engine was added as an alternative to the existing Godot Physics |
| 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 parity** with both |
| 16 | +Godot Physics and the Godot Jolt extension. Behavior may change as it is developed |
| 17 | +further. Please keep that in mind when choosing what to use for your project. |
| 18 | + |
| 19 | +The existing extension is now considered in maintenance mode. That means bug fixes |
| 20 | +will be merged, and it will be kept compatible with new versions of Godot until |
| 21 | +the built-in module has feature parity with the extension. The extension can be |
| 22 | +found `here on GitHub <https://github.com/godot-jolt/godot-jolt>`_ and in Godot's asset |
| 23 | +library. |
| 24 | + |
| 25 | +To change the 3D physics engine to be Jolt Physics, set |
| 26 | +:ref:`Project Settings > Physics > 3D > Physics Engine<class_ProjectSettings_property_physics/3D/Physics_Engine>` |
| 27 | +to ``Jolt Physics``. Once you've done that, click the **Save & Restart** button. |
| 28 | +When the editor opens again, 3D scenes should now be using Jolt for physics. |
| 29 | + |
| 30 | +Notable differences to Godot Physics |
| 31 | +------------------------------------ |
| 32 | + |
| 33 | +There are many differences between the existing Godot Physics engine and Jolt. |
| 34 | + |
| 35 | +Area3D and static bodies |
| 36 | +~~~~~~~~~~~~~~~~~~~~~~~~ |
| 37 | +When using Jolt, :ref:`class_Area3D` will not detect overlaps with :ref:`class_StaticBody3D` |
| 38 | +(nor a :ref:`class_RigidBody3D` frozen with ``FREEZE_MODE_STATIC``) by default, for |
| 39 | +performance reasons. If you have many/large :ref:`class_Area3D` overlapping with |
| 40 | +complex static geometry, such as :ref:`class_ConcavePolygonShape3D` or |
| 41 | +:ref:`class_HeightMapShape3D`, you can end up wasting a significant amount of CPU |
| 42 | +performance and memory without realizing it. |
| 43 | + |
| 44 | +For this reason this behavior is opt-in through the project setting |
| 45 | +:ref:`Physics > Jolt Physics 3D > Simulation > Areas Detect Static Bodies<class_ProjectSettings_property_physics/jolt_physics_3d/simulation/areas_detect_static_bodies>`, |
| 46 | +with the recommendation that you set up your collision layers and masks in such a |
| 47 | +way that only a few small :ref:`class_Area3D` are able to detect collisions with |
| 48 | +static bodies. |
| 49 | + |
| 50 | +Joint properties |
| 51 | +~~~~~~~~~~~~~~~~ |
| 52 | + |
| 53 | +The current interfaces for the 3D joint nodes don't quite line up with the interface |
| 54 | +of Jolt's own joints. As such, there are a number of joint properties that are not |
| 55 | +supported, mainly ones related to configuring the joint's soft limits. |
| 56 | + |
| 57 | +The unsupported properties are: |
| 58 | + |
| 59 | +- PinJoint3D: ``bias``, ``damping``, ``impulse_clamp`` |
| 60 | +- HingeJoint3D: ``bias``, ``softness``, ``relaxation`` |
| 61 | +- SliderJoint3D: ``angular_\*``, ``\*_limit/softness``, ``\*_limit/restitution``, ``\*_limit/damping`` |
| 62 | +- ConeTwistJoint3D: ``bias``, ``relaxation``, ``softness`` |
| 63 | +- Generic6DOFJoint3D: ``*_limit_*/softness``, ``*_limit_*/restitution``, ``*_limit_*/damping``, ``*_limit_*/erp`` |
| 64 | + |
| 65 | +Currently a warning is emitted if you set these properties to anything but their |
| 66 | +default values. |
| 67 | + |
| 68 | +Single-body joints |
| 69 | +~~~~~~~~~~~~~~~~~~ |
| 70 | + |
| 71 | +You can, in Godot, omit one of the joint bodies for a two-body joint and effectively |
| 72 | +have "the world" be the other body. However, the node path that you assign your body |
| 73 | +to (:ref:`node_a<class_Joint3D_property_node_a>` vs :ref:`node_b<class_Joint3D_property_node_b>`) |
| 74 | +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, but Godot Physics |
| 92 | +itself does not use them for anything. |
| 93 | + |
| 94 | +What these collision margins sometimes do in other engines (as described in Godot's |
| 95 | +documentation) is effectively add a "shell" around the shape, slightly increasing |
| 96 | +its size while also rounding off any edges/corners. In Jolt however, these margins |
| 97 | +are first used to shrink the shape, and then the "shell" is applied, resulting in |
| 98 | +edges/corners being similarly rounded off, but without increasing the size of the |
| 99 | +shape. |
| 100 | + |
| 101 | +To prevent having to tweak this margin property manually, since its default value |
| 102 | +can be problematic for smaller shapes, the Jolt module exposes a project setting |
| 103 | +called :ref:`Physics > Jolt Physics 3D > Collisions > Collision Margin Fraction<class_ProjectSettings_property_physics/jolt_physics_3d/collisions/collision_margin_fraction>` |
| 104 | +which is multiplied with the smallest axis of the shape's AABB to calculate the |
| 105 | +actual margin. The margin property of the shape is then instead used as an upper |
| 106 | +bound. |
| 107 | + |
| 108 | +These margins should, for most use-cases, be more or less transparent, but can |
| 109 | +sometimes result in odd collision normals when performing shape queries. You can |
| 110 | +lower the above mentioned project setting to mitigate some of this, including |
| 111 | +setting it to ``0.0``, but too small of a margin can also cause odd collision results, |
| 112 | +so is generally not recommended. |
| 113 | + |
| 114 | +Baumgarte stabilization |
| 115 | +~~~~~~~~~~~~~~~~~~~~~~~ |
| 116 | + |
| 117 | +Baumgarte stabilization is a method to resolve penetrating bodies and push them to a |
| 118 | +state where they are just touching. In Godot Physics this works like a spring. This |
| 119 | +means that bodies can accelerate and may cause the bodies to overshoot and separate |
| 120 | +completely. With Jolt, the stabilization is only applied to the position and not to |
| 121 | +the velocity of the body. This means it cannot overshoot but it may take longer to |
| 122 | +resolve the penetration. |
| 123 | + |
| 124 | +The strength of this stabilization can be tweaked using the project setting |
| 125 | +:ref:`Physics > Jolt Physics 3D > Simulation > Baumgarte Stabilization Factor<class_ProjectSettings_property_physics/jolt_physics_3d/simulation/baumgarte_stabilization_factor>`. |
| 126 | +Setting this project setting to ``0.0`` will turn Baumgarte stabilization off. |
| 127 | +Setting it to ``1.0`` will resolve penetration in 1 simulation step. This is fast |
| 128 | +but often also unstable. |
| 129 | + |
| 130 | +Ghost collisions |
| 131 | +~~~~~~~~~~~~~~~~ |
| 132 | + |
| 133 | +Jolt employs two techniques to mitigate ghost collisions, meaning collisions with |
| 134 | +internal edges of shapes/bodies that result in collision normals that oppose the |
| 135 | +direction of movement. |
| 136 | + |
| 137 | +The first technique, called "active edge detection", marks edges of triangles in |
| 138 | +:ref:`class_ConcavePolygonShape3D` or :ref:`class_HeightMapShape3D` as either "active" or "inactive", based on |
| 139 | +the angle to the neighboring triangle. When a collision happens with an inactive |
| 140 | +edge the collision normal will be replaced with the triangle's normal instead, to |
| 141 | +lessen the effect of ghost collisions. |
| 142 | + |
| 143 | +The angle threshold for this active edge detection is configurable through the |
| 144 | +project setting :ref:`Physics >Jolt Physics 3D > Collisions > Active Edge Threshold<class_ProjectSettings_property_physics/jolt_physics_3d/collisions/active_edge_threshold>`. |
| 145 | + |
| 146 | +The second technique, called "enhanced internal edge removal", instead adds runtime |
| 147 | +checks to detect whether an edge is active or inactive, based on the contact points |
| 148 | +of the two bodies. This has the benefit of applying not only to collisions with |
| 149 | +:ref:`class_ConcavePolygonShape3D` and :ref:`class_HeightMapShape3D`, but also edges between any shapes within |
| 150 | +the same body. |
| 151 | + |
| 152 | +Enhanced internal edge removal can be toggled on and off for the various contexts to |
| 153 | +which it's applied, using the :ref:`Physics >Jolt Physics 3D > Simulation > Use Enhanced Internal Edge Removal<class_ProjectSettings_property_physics/jolt_physics_3d/simulation/use_enhanced_internal_edge_removal>`, |
| 154 | +project setting, and the similar settings for :ref:`queries<class_ProjectSettings_property_physics/jolt_physics_3d/queries/use_enhanced_internal_edge_removal>` |
| 155 | +and :ref:`motion queries<class_ProjectSettings_property_physics/jolt_physics_3d/motion_queries/use_enhanced_internal_edge_removal>`. |
| 156 | + |
| 157 | +Note that neither the active edge detection nor enhanced internal edge removal apply |
| 158 | +when dealing with ghost collisions between two different bodies. |
| 159 | + |
| 160 | +Memory usage |
| 161 | +~~~~~~~~~~~~ |
| 162 | + |
| 163 | +Jolt uses a stack allocator for temporary allocations within its simulation step. |
| 164 | +This stack allocator requires allocating a set amount of memory up front, which can |
| 165 | +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>` |
| 166 | +project setting. |
| 167 | + |
| 168 | +Ray-cast face index |
| 169 | +~~~~~~~~~~~~~~~~~~~ |
| 170 | + |
| 171 | +The ``face_index`` property returned in the results of :ref:`intersect_ray()<class_PhysicsDirectSpaceState3D_method_intersect_ray>` |
| 172 | +and RayCast3D will 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>` |
| 173 | +will enable them. |
| 174 | + |
| 175 | +Note that enabling this setting will increase the memory requirement of :ref:`class_ConcavePolygonShape3D` |
| 176 | +with about 25%. |
| 177 | + |
| 178 | +Kinematic RigidBody3D contacts |
| 179 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 180 | + |
| 181 | +When using Jolt, a :ref:`class_RigidBody3D` frozen with :ref:`FREEZE_MODE_KINEMATIC<class_RigidBody3D_constant_FREEZE_MODE_KINEMATIC>` |
| 182 | +will by default not report contacts from collisions with other static/kinematic |
| 183 | +bodies, for performance reasons, even when setting a non-zero :ref:`max_contacts_reported<class_RigidBody3D_property_max_contacts_reported>`. |
| 184 | +If you have many/large kinematic bodies overlapping with complex static geometry, |
| 185 | +such as :ref:`class_ConcavePolygonShape3D` or :ref:`class_HeightMapShape3D`, you can |
| 186 | +end up wasting a significant amount of CPU performance and memory without realizing |
| 187 | +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 | +Due to limitations internal to Jolt, the contact impulses provided by :ref:`PhysicsDirectBodyState3D.get_contact_impulse()<class_physicsdirectbodystate3d_method_get_contact_impulse>` |
| 196 | +are estimated ahead of time based on things like the contact manifold and velocities |
| 197 | +of the colliding bodies. This means that the reported impulses will only be accurate |
| 198 | +in cases where the two bodies in question are not colliding with any other bodies. |
| 199 | + |
| 200 | +Area3D and SoftBody3D |
| 201 | +~~~~~~~~~~~~~~~~~~~~~ |
| 202 | + |
| 203 | +Jolt does not currently support any interactions between :ref:`class_SoftBody3D` |
| 204 | +and :ref:`class_Area3D`, such as overlap events, or the wind properties found on |
| 205 | +:ref:`class_Area3D`. |
| 206 | + |
| 207 | +WorldBoundaryShape3D |
| 208 | +~~~~~~~~~~~~~~~~~~~~ |
| 209 | + |
| 210 | +:ref:`class_WorldBoundaryShape3D`, which is meant to represent an infinite plane, is |
| 211 | +implemented a bit differently in Jolt compared to Godot Physics. Both engines have |
| 212 | +an upper limit for how big the effective size of this plane can be, but this size is |
| 213 | +much smaller when using Jolt, in order to avoid precision issues. |
| 214 | + |
| 215 | +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>` |
| 216 | +project setting. |
| 217 | + |
| 218 | +Notable differences to the Godot Jolt extension |
| 219 | +----------------------------------------------- |
| 220 | + |
| 221 | +While the built-in Jolt module is largely a straight port of the Godot Jolt |
| 222 | +extension, there are a few things that are different. |
| 223 | + |
| 224 | +Project settings |
| 225 | +~~~~~~~~~~~~~~~~ |
| 226 | + |
| 227 | +All project settings have been moved from the ``physics/jolt_3d`` category to |
| 228 | +``physics/jolt_physics_3d``. |
| 229 | + |
| 230 | +On top of that, there's been some renaming and refactoring of the individual project |
| 231 | +settings as well. These include: |
| 232 | + |
| 233 | +- ``sleep/enabled`` is now ``simulation/allow_sleep.`` |
| 234 | +- ``sleep/velocity_threshold`` is now ``simulation/sleep_velocity_threshold.`` |
| 235 | +- ``sleep/time_threshold`` is now ``simulation/sleep_time_threshold.`` |
| 236 | +- ``collisions/use_shape_margins`` is now ``collisions/collision_margin_fraction``, |
| 237 | + where a value of 0 is equivalent to disabling it. |
| 238 | +- ``collisions/use_enhanced_internal_edge_removal`` is now ``simulation/use_enhanced_internal_edge_removal.`` |
| 239 | +- ``collisions/areas_detect_static_bodies`` is now ``simulation/areas_detect_static_bodies.`` |
| 240 | +- ``collisions/report_all_kinematic_contacts`` is now ``simulation/generate_all_kinematic_contacts.`` |
| 241 | +- ``collisions/soft_body_point_margin`` is now ``simulation/soft_body_point_radius.`` |
| 242 | +- ``collisions/body_pair_cache_enabled is now simulation/body_pair_contact_cache_enabled.`` |
| 243 | +- ``collisions/body_pair_cache_distance_threshold`` is ``now simulation/body_pair_contact_cache_distance_threshold.`` |
| 244 | +- ``collisions/body_pair_cache_angle_threshold is now simulation/body_pair_contact_cache_angle_threshold.`` |
| 245 | +- ``continuous_cd/movement_threshold`` is now ``simulation/continuous_cd_movement_threshold``, |
| 246 | + but expressed as a fraction instead of a percentage. |
| 247 | +- ``continuous_cd/max_penetration`` is now ``simulation/continuous_cd_max_penetration``, |
| 248 | + but expressed as a fraction instead of a percentage. |
| 249 | +- ``kinematics/use_enhanced_internal_edge_removal`` is now ``motion_queries/use_enhanced_internal_edge_removal.`` |
| 250 | +- ``kinematics/recovery_iterations`` is now ``motion_queries/recovery_iterations``, |
| 251 | + but expressed as a fraction instead of a percentage. |
| 252 | +- ``kinematics/recovery_amount`` is now ``motion_queries/recovery_amount.`` |
| 253 | +- ``queries/use_legacy_ray_casting`` has been removed. |
| 254 | +- ``solver/position_iterations`` is now ``simulation/position_steps.`` |
| 255 | +- ``solver/velocity_iterations`` is now ``simulation/velocity_steps.`` |
| 256 | +- ``solver/position_correction`` is now ``simulation/baumgarte_stabilization_factor``, |
| 257 | + but expressed as a fraction instead of a percentage. |
| 258 | +- ``solver/active_edge_threshold`` is now ``collisions/active_edge_threshold.`` |
| 259 | +- ``solver/bounce_velocity_threshold`` is now ``simulation/bounce_velocity_threshold.`` |
| 260 | +- ``solver/contact_speculative_distance`` is now ``simulation/speculative_contact_distance.`` |
| 261 | +- ``solver/contact_allowed_penetration`` is now ``simulation/penetration_slop.`` |
| 262 | +- ``limits/max_angular_velocity`` is now stored as radians instead. |
| 263 | +- ``limits/max_temporary_memory`` is now ``limits/temporary_memory_buffer_size.`` |
| 264 | + |
| 265 | +Joint nodes |
| 266 | +~~~~~~~~~~~ |
| 267 | + |
| 268 | +The joint nodes that are exposed in the Godot Jolt extension (JoltPinJoint3D, |
| 269 | +JoltHingeJoint3D, JoltSliderJoint3D, JoltConeTwistJoint3D, and JoltGeneric6DOFJoint) |
| 270 | +have not been included in the Jolt module. |
| 271 | + |
| 272 | +Thread safety |
| 273 | +~~~~~~~~~~~~~ |
| 274 | + |
| 275 | +Unlike the Godot Jolt extension, the Jolt module does have thread-safety, |
| 276 | +including support for the :ref:`Physics > 3D > Run On Separate Thread<class_ProjectSettings_Property_physics/3d/run_on_separate_thread>` |
| 277 | +project setting. However this has not been tested very thoroughly, so it should be |
| 278 | +considered experimental. |
0 commit comments