RigidBody get_contact_local_normal "jumps" when passing over collision shape edges

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By Noah-Huppert

I believe I am seeing behavior where when a RigidBody passes over an edge of a CollisionShape the RigidBody’s get_contact_local_normal() Z axis jumps to a different value. I am wondering why this might be happening, and how I can prevent this or detect this (short of filtering out large changes in values).

I am seeing this behavior on a ramp with a constant slope, so my understanding is the collision normal should be the same the whole way down. However:

  1. The collision normal seems to change and stay at a completely different value sometimes
  2. Sometimes there is a slight “jitter” where the collision normal changes briefly to a new value and then back to the old value.

I am trying to make the player camera rotate to always be parallel to the ground the player is on. The player is a RigidBody and the ground is a StaticBody. So to figure out the angle of the ground the player is sitting on I call get_contact_local_normal() when the RigidBody is colliding. I then use this normal’s Z axis to rotate the camera.

GIF showing the jumping behavior of the camera, which is driven by the normal

By printing to the console I have confirmed that this camera jumping movement is caused by the collision normal changing rapidly.

Graph of normal value

As you can see, the areas on the ramp where the camera jumps seem to line up with the edges of the collision shape:

Ramp with mesh and collision shape
Ramp with just collision shape

Source code (pinned to the moment in time where I asked this question) can be found here
The behavior is occurring in the Player scene, the collision normal is extracted in the PlayerCollision.cs script, and the camera is rotated in the Player.cs script.

I enabled “Smooth Trimesh Collision” and switched to “GodotPhysics” for my project. The collision normals seem to be more stable now. I did this because of this GitHub issue which mentioned similar behavior.

Here is a video of the player’s camera being rotated based on the player’s collision Z axis:

https://user-images.githubusercontent.com/3323504/186556564-3a5a2466-b6ce-408b-8b38-8cd23afb549b.mp4

Graph of the normal’s Z axis from that video:

I also updated to 3.5 from 3.4.4 but I’m not sure if that helped.

I won’t mark this as an answer because I feel like it’s possible I misconfigured my scene or there was some workaround I could do and keep the other physics engine. But with GodotPhysics becoming the default in 4.x I think this is a good fix too.

Noah-Huppert | 2022-08-25 02:17

:bust_in_silhouette: Reply From: jpate

It’s a known issue: [Bullet] KinemeticBody still jitters against gridmap seams with 3.5 RC2 using Bullet · Issue #61616 · godotengine/godot · GitHub