Clean up and do fixes to hash functions and newly introduced murmur3 hashes in #61934
* Clean up usage of murmur3
* Fixed usages of binary murmur3 on floats (this is invalid)
* Changed DJB2 to use xor (which seems to be better)
* Map is unnecessary and inefficient in almost every case.
* Replaced by the new HashMap.
* Renamed Map to RBMap and Set to RBSet for cases that still make sense
(order matters) but use is discouraged.
There were very few cases where replacing by HashMap was undesired because
keeping the key order was intended.
I tried to keep those (as RBMap) as much as possible, but might have missed
some. Review appreciated!
Didn't commit all the changes where it wants to initialize a struct
with `{}`. Should be reviewed in a separate PR.
Option `IgnoreArrays` enabled for now to be conservative, can be
disabled to see if it proposes more useful changes.
Also fixed manually a handful of other missing initializations / moved
some from constructors.
Adds DEV_ASSERTS that will halt at runtime if the BVH is misused with invalid IDs, and adds ERR_FAIL macros to prevent calling with invalid IDs.
Any such misuse is a bug in the physics, but this should flag any errors quickly.
For 2D:
Raycast CCD now works the same as in 3D, it changes the body's velocity
to place it at the impact position instead of generating a contact point
that causes a wrong push back.
For both 2D and 3D:
The raycast CCD process reads and modifies body velocities, so it needs
to be moved to pre_solve() instead of setup() to be processed linearly
on the main thread, otherwise multithreading can cause some CCD results
to be randomly lost when multiple collisions occur.
Makes the API for forces and impulses more flexible, easier to
understand and harmonized between 2D and 3D.
Rigid bodies now have 3 sets of methods for forces and impulses:
-apply_impulse() for impulses (one-shot and time independent)
-apply_force() for forces (time dependent) applied for the current step
-add_constant_force() for forces that keeps being applied each step
Also updated the documentation to clarify the different methods and
parameters in rigid body nodes, body direct state and physics servers.
Margin needs to have a high enough value for test body motion to work
properly (separate using the margin, move without then gather rest info
with the margin again).
Fixes issues with test motion returning no collision in some cases with
margin equal to 0.
Helps with discovery and setup of physics solver settings, in a specific
project settings section for both 2D and 3D.
Other changes for cleanup:
-Removed unused space parameters in 3D
SPACE_PARAM_BODY_ANGULAR_VELOCITY_DAMP_RATIO
SPACE_PARAM_CONSTRAINT_DEFAULT_BIAS
-Added custom solver bias for Shape3D (same as Shape2D)
-Improved documentation for solver settings
Clarified space parameters for contacts and added missing ones.
List of changes:
-Add contact bias to space parameters
-Add solver iterations to space parameters, instead of a specific
physics server function
-Renamed BODY_MAX_ALLOWED_PENETRATION to CONTACT_MAX_ALLOWED_PENETRATION
to make it consistent with other contact parameters
Changed the algorithm for solving contacts to keep previous contacts as
long as they are under the max separation threshold to keep contact
impulses more consistent and contacts more stable.
Also made 2D consistent with 3D and changed some default parameters:
-Contact bias is now 0.8 instead of 0.3 to avoid springy contacts
-Solver iterations are 16 instead of 8 by default for better stability
Performance considerations:
Tested with stress tests that include lots of contacts from overlapping
bodies.
3D: There's no measurable difference in performance.
2D: Performance is a bit lower (close to 10% slower in extreme cases)
The benefit for 2D physics to be much more stable outweighs the slight
decrease in performance, and this could be alleviated by changing the
algorithm to use jacobians for contact solving to help with cache
efficiency and memory allocations.
Bounce calculation now uses the previous frame's velocity, so it's
consistent with the actual motion of the bodies involved and not the
yet-to-be-applied forces.
When bounce is 1, using the current velocity was causing the new forces
(including gravity) to be taken into account, which lead to the bounce
velocity to be higher than the falling velocity at the moment of impact,
adding more and more energy over time.
Updating the broadphase to find new collision pairs was done after
checking for collision islands, so it was working in most cases due to
the pairing margin used in the BVH, but in case of teleported objects
the narrowphase collision could be skipped.
Now it's done before checking for collision islands, so we can ensure
that broadphase pairing has been done at the same time as objects are
marked as moved so their collision can be checked properly.
This issue didn't happen in the Octree/HashGrid because they do nothing
on update and trigger pairs directly when objects move instead.
In all physics servers, body_get_direct_state() now silently returns
nullptr when the body has been already freed or is removed from space,
so the client code can detect this state and invalidate the body rid.
In 2D, there is no change in behavior (just no more errors).
In 3D, the Bullet server returned a valid direct body state when the
body was removed from the physics space, but in this case it didn't
make sense to use the information from the body state.
Center of mass in body's local space is more useful than the transformed
one in some cases, like drawing its position for debug.
It's especially useful to get the generated local center of mass when
in auto mode (by default).
Physics Server BODY_PARAM_CENTER_OF_MASS:
Now always returns the local center of mass, instead of setting a local
center of mass and getting a transformed one.
This causes compatibility breaking, but it makes more sense for the
parameter to be consistent between getter and setter.
Direct Body State:
There are now two properties, because both of them can be useful in
different situations.
center_of_mass: relative position in global coordinates (same as before)
center_of_mass_local: position in local coordinates