godotengine / godot

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

PhysicsDirectSpaceState.intersect_ray returns a different result with Bullet and GodotPhysics #49055

Open QazPolma opened 3 years ago

QazPolma commented 3 years ago

Godot version: 3.3.2.stable

OS/device including version: Linux Mint 20.1(Ubuntu 20.04 LTS)

Issue description: When raycasting from the center of a KinematicBody to another KinematicBody with "get_world().direct_space_state.intersect_ray", I get different results depending on PhysicsEngine. With "Bullet" I get the second body and with "GodotPhysics" I get the first body.

Steps to reproduce: 1.Make 2 KinematicBody objects. 2.Raycast between the 2 bodies. 3.Change "Project settings->Physics->3D->Physics Engine"

Minimal reproduction project:

RaycastBug_v2.zip

Edit: Removed the exclusion lists issue, since it was because of incorrect setup.

pouleyKetchoupp commented 3 years ago

I can confirm the inconsistency between Bullet and Godot Physics.

Exclusion lists should work though. In your project, you're setting self in the exclusion list for the raycast, and because the script is on the root node, it doesn't affect the raycast. You would need to set the kinematic body itself in the exclude list to make it work properly.

QazPolma commented 3 years ago

Thank you for the explanation. I have updated the case accordingly.

rburing commented 2 years ago

The behavior of raycasts with Bullet in this case is due to the following code:

https://github.com/godotengine/godot/blob/c08e753ef6dba156a87bb4148faf7d190b6676f0/thirdparty/bullet/BulletCollision/NarrowPhaseCollision/btSubSimplexConvexCast.cpp#L135-L137

Even if that weren't there, there would still be this check:

https://github.com/godotengine/godot/blob/c08e753ef6dba156a87bb4148faf7d190b6676f0/thirdparty/bullet/BulletCollision/CollisionDispatch/btCollisionWorld.cpp#L638-L639

There are no settings in Bullet to change this behavior, so besides documenting this there is not much we can do (unless someone changes Bullet upstream).

In GodotPhysics in master there is a hit_from_inside parameter that can be passed in to intersect_ray.

prominentdetail commented 2 years ago

This may be related, but I found that having a collisionShape that has its Z extents set below 0.5 will cause GodotPhysics to fail to hit it (in this case the intersect_ray is traveling along the X axis straight through the object). It works fine in Bullet physics, but not in GodotPhysics.