[GodotPhysics] Fix raycasts don't reliably collide with HeightMapShape3D #97471
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Tested this fix on both of the MRPs shared and it seems to work
heightmap_raycast_repro.zip
raycastHeightmapBug.zip
If there's cleaner way to fix this, or if I missed something, let me know thanks
Details:
Raycast with issue fall under this case where ray is long so it does query on higher level grid first
godot/modules/godot_physics_3d/godot_shape_3d.cpp
Line 1998 in f7c567e
And issue looks to be in the loop here, it exit before it got to the chunk where the ray actually intersect
godot/modules/godot_physics_3d/godot_shape_3d.cpp
Lines 1940 to 1941 in f7c567e
p_width and p_depth is the chunk's width and depth for this flow
using heightmap_raycast_repro.zip as example
p_width = ceil( width/chunk size) = ceil( (21/16) = 2
p_depth = ceil(depth/chunk size) = ceil( (21/16) = 2
x = 1 or z = 1 should still be valid chunk, but it will exit here.
But can't directly change that line to
if ((x < 0) || (z < 0) || (x >= p_width) || (z >= p_depth))
because
_intersect_grid_segment()
is used by cell level too, where in_heightmap_cell_cull_segment
:godot/modules/godot_physics_3d/godot_shape_3d.cpp
Lines 1754 to 1755 in f7c567e
it performs get point on the triangle with
p_state.x + 1
,p_state.z + 1
etc so it will hit out of range on the edge cell if we change that lineThis PR passes
bounds_grid_width + 1
,bounds_grid_depth + 1
to_intersect_grid_segment()
with a comment to explain this,if there's cleaner way let me know 😅