Skip to content

fix: report rays starting inside a box when a hit point is requested - #9915

Open
mmporong wants to merge 1 commit into
playcanvas:mainfrom
mmporong:fix-aabb-ray-inside
Open

mmporong wants to merge 1 commit into
playcanvas:mainfrom
mmporong:fix-aabb-ray-inside

Conversation

@mmporong

@mmporong mmporong commented Nov 3, 2026

Copy link
Copy Markdown

BoundingBox.intersectsRay() gives different answers for the same ray depending on whether a hit point is requested. Without a point it uses _fastIntersectsRay() and reports a ray that starts inside the box as a hit. With a point it uses _intersectsRay(), which requires the entry distance maxMin >= 0, so the same ray returns false. OrientedBox.intersectsRay(ray, point) goes through _intersectsRay() and behaves the same way.

  • _intersectsRay() now treats the box as hit unless it is entirely behind the ray (minMax >= 0), so the result no longer depends on passing point.
  • For a ray that starts inside the box, point is set to where the ray leaves the box. A box entirely behind the ray still returns false (the case maxMin >= 0 was added for in Fixed infinite raycast bug in aabb intersectsRay #828).
  • The JSDoc of BoundingBox.intersectsRay() and OrientedBox.intersectsRay() now describes the inside case.

Public API change (behaviour only, no signature change):

const box = new BoundingBox(new Vec3(0, 0, 0), new Vec3(1, 1, 1));
const ray = new Ray(new Vec3(0.5, 0, 0), new Vec3(1, 0, 0));
const point = new Vec3();

box.intersectsRay(ray);        // true (before and after)
box.intersectsRay(ray, point); // before: false, after: true with point = (1, 0, 0)

Tests: added #intersectsRay cases to test/core/shape/bounding-box.test.mjs (entry point from outside, exit point from inside, box behind the ray). The inside case fails before the change and passes after it, and the test/core/shape tests pass (65). I also checked OrientedBox with an identity transform: before false, after true with point (1, 0, 0). eslint is clean on the changed files. I did not run the full npm test.

BoundingBox.intersectsRay(ray, point) required the entry distance to be
non-negative, so a ray starting inside the box returned false, while the
same call without a point returned true. OrientedBox.intersectsRay goes
through the same code. Treat the box as hit unless it is entirely behind
the ray, and report the exit point for a ray that starts inside.

This branch has not been deployed

No deployments
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