Skip to content

feat: add Bvh::cast_ray_best for SIMD-accelerated generic ray queries#412

Open
zmerlynn wants to merge 1 commit intodimforge:masterfrom
zmerlynn:fix/simd-cast-ray-best
Open

feat: add Bvh::cast_ray_best for SIMD-accelerated generic ray queries#412
zmerlynn wants to merge 1 commit intodimforge:masterfrom
zmerlynn:fix/simd-cast-ray-best

Conversation

@zmerlynn
Copy link
Copy Markdown

Problem

CompositeShapeRef::cast_local_ray_and_get_normal calls bvh().find_best() directly with BvhNode::cast_ray as the AABB cost function. This always uses the non-SIMD ray-AABB test, even on f32/dim3/simd-is-enabled builds where cast_inv_ray_simd is available.

Meanwhile, the sibling method cast_local_ray calls bvh().cast_ray() which does dispatch to the SIMD path. So TriMesh::cast_local_ray gets SIMD but TriMesh::cast_local_ray_and_get_normal does not — a surprising inconsistency.

The root cause: Bvh::cast_ray returns Option<(u32, Real)>, so it can't be used when the caller needs RayIntersection (which includes the surface normal). The caller was forced to use find_best directly and provide its own (non-SIMD) AABB cost closure.

Solution

Add Bvh::cast_ray_best<L: BvhLeafCost> — identical to cast_ray but generic over the return type. Two #[cfg]-gated variants provide the same SIMD/non-SIMD dispatch as cast_ray:

// Non-SIMD
pub fn cast_ray_best<L: BvhLeafCost>(
    &self, ray: &Ray, max_time_of_impact: Real,
    primitive_check: impl Fn(u32, Real) -> Option<L>,
) -> Option<(u32, L)>

// SIMD (f32 + dim3 + simd-is-enabled)
pub fn cast_ray_best<L: BvhLeafCost>(
    &self, ray: &Ray, max_time_of_impact: Real,
    primitive_check: impl Fn(u32, Real) -> Option<L>,
) -> Option<(u32, L)>

RayIntersection already implements BvhLeafCost (returns time_of_impact as cost), so cast_local_ray_and_get_normal can now simply call bvh().cast_ray_best(...).

Test plan

  • cargo test — all 520 tests pass across parry2d, parry2d-f64, parry3d, parry3d-f64
  • cargo fmt -- --check
  • RUSTFLAGS="-D warnings" cargo clippy
  • RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps
  • Doc-test example on cast_ray_best with proper feature gate
  • Benchmark comparison (SIMD vs non-SIMD) — would appreciate guidance on parry's benchmarking setup if one exists

🤖 Generated with Claude Code

cast_local_ray_and_get_normal on CompositeShapeRef was calling
find_best() directly with the non-SIMD BvhNode::cast_ray for AABB
tests, missing the SIMD-accelerated path available on f32/dim3 builds.

Add Bvh::cast_ray_best — a generic version of cast_ray that returns
any BvhLeafCost type (not just Real) with proper SIMD/non-SIMD
dispatch. Change cast_local_ray_and_get_normal to use it.

This means TriMesh::cast_local_ray_and_get_normal (and all composite
shapes using this code path) now benefits from SIMD AABB tests on
supported platforms, matching the existing cast_local_ray behavior.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant