godotengine / godot

Godot Engine – Multi-platform 2D and 3D game engine
https://godotengine.org
MIT License
89.06k stars 20.19k forks source link

ShapeCast3D has massive accuracy issues #85314

Open NatePlays95 opened 9 months ago

NatePlays95 commented 9 months ago

Godot version

v4.1.1.stable.official [bd6af8e0e]

System information

Godot v4.1.1.stable - Windows 10.0.22621 - Vulkan (Forward+) - dedicated NVIDIA GeForce RTX 3050 Laptop GPU (NVIDIA; 31.0.15.4617) - 12th Gen Intel(R) Core(TM) i5-12500H (16 Threads)

Issue description

A ShapeCast3D with a sphere shape set is varying its collision distance from another collider wildly when moving a few units parallel to its extend direction. This problem does not show itself with RayCast3D.

Godot_v4 1 1-stable_win64_Mgu49AgIm7

How I expect it to work

Cast a shape downwards, onto a collider like a CSGBox, and the shapecast cast will stay at one Y level. Move the shapecast origin in the X and Z axis, and the Y level of the cast should stay the same.

How it actually performs

Move the shapecast origin in the X and Z axis, and the Y level of the cast changes. Using debug shapes, the sphere shape visibly bounces, even though the origin's height stays the same. Variations of >0.0001 aren't great for physics sims, but I can see variations of >0.1, which are unacceptable!

My observations:

StaticBodies from meshes do not show this problem if the shapecast hits the front-side of a tri, but do show if the shapecast hits the back-side of a tri. CSGBoxes with large sizes show this problem very often, as an user tends to make one single large csgbox instead of one for each cubic meter of space.

This behavior would usually not occur in Godot-JoltPhysics, but if I use a CSGBox with flipped faces there, it does. My guess is that sphere ShapeCasts don't go well with reversed normals, yet CSGBoxes have double-sided faces with the back-side interfering with the front-side from lack of accuracy?

I think the distance from the sides of a tri increases the effect, so casting to the center of a tri has more visible effects than casting closer to that tri's edge, but I'm not sure.

Why is it a problem

For physics simulations like vehicles, any minor deviations can cause major instability in suspension and wheel systems. For clipped cameras, camera positions jerking when in contact with walls and ceilings may lead to motion sickness. This makes CSG objects unusable for prototyping with those systems in mind, requiring a blender-first workflow to ensure no back-face or double-face colliders, which is not ideal.

Steps to reproduce

  1. Make a new ShapeCast3D, set shape to Sphere.
  2. Make a new CSGBox, and set the X and Z size to a large value, like 1000.
  3. Check the CSGBox's use collision bool.
  4. Set some way to move either the shapecast or the box, like a Path or a KinematicBody or simple keyboard controls.
  5. Move the two so that the shapecast collides with the box. Check the height of the cast (with DebugShapes or printing to the console)
  6. Keep moving the objects, while keeping the Y positions of both the same. Check the height of the cast again.

Minimal reproduction project

ShapecastAccuracyBug.zip There's a test_shapecast scene with a csgbox and a shapecast tied to a path, as seen in the example gif. There's also a test_shapecast_on_mesh scene with two square planes from Blender set up as static bodies, and one's upside down, as well as the raycast and the path.

AThousandShips commented 9 months ago

Can you please try this with a supported version, like 4.1.3 (only the latest patch version is supported, and it might already be fixed)

NatePlays95 commented 9 months ago

Godot_v4 1 3-stable_win64_PM4ERh3fZz can confirm bug on v4.1.3.stable.official [f06b6836a]

EDIT: can also confirm bug on v4.2.rc1.official [ad72de508]

Griiimon commented 9 months ago

That's not the only issue with CSGPrimitives and physics. They are also known to miss body_entered signals for Rigidbodies. It's unfortunate but they are just not suited to be used in this context. I still consider it a bug, but since it has been a long standing issue and doesn't seem to be fixed soon, these physics- side limitations should be mentioned explicitly in the docs.

And for Jolt: It will hit backfaces by default when casting. Could explain your problem when using flipped faces.

venilark commented 7 months ago

I'm dealing with ConvexPolygonShape3D, those created from Qodot, and the results have been really bad when trying to check if an object was above the player but after changing the margin to 0.15 in my case (I'm using a BoxCollider for the shapecast, which is not very big, less than 1m3), I finally managed to get it working decently. Also I'm calling force_shapecast_update() after move_and_slide(), if that could help.

For my needs it is fine but it is definetely a problem is someone needs more precision/smaller colliders and I wouldn't be surprised if it fails with other geometry.

Godot 4.2.1, Godot Physics.