gkjohnson / three-mesh-bvh

A BVH implementation to speed up raycasting and enable spatial queries against three.js meshes.
https://gkjohnson.github.io/three-mesh-bvh/example/bundle/raycast.html
MIT License
2.39k stars 247 forks source link

Consider new shader bounds intersection function #604

Closed gkjohnson closed 5 months ago

gkjohnson commented 7 months ago

this paper

See https://github.com/mrdoob/three.js/issues/26937

gkjohnson commented 5 months ago
float max(vec3 v) { return max (max(v.x, v.y), v.z); }

// box.rotation = object-to-world, invRayDir unused if oriented
bool ourIntersectBox(
    Box box, Ray ray, out float distance, out vec3 normal,
    const bool canStartInBox, const in bool oriented, in vec3 _invRayDir
) {

    ray.origin = ray.origin - box.center;

    if (oriented) {
        ray.dir *= box.rot;
        ray.origin *= box.rot;
    }
    float winding = canStartInBox && (max(abs(ray.origin) * box.invRadius)< 1.0) ? -1 : 1;
    vec3 sgn = -sign(ray.dir);

    // Distance to plane
    vec3 d = box.radius * winding * sgn - ray.origin;
    if (oriented) {
        d /= ray.dir; else d *= _invRayDir;
    }

    # define TEST(U, VW) (d.U >= 0.0) && \
        all(lessThan(abs(ray.origin.VW + ray.dir.VW * d.U), box.radius.VW))

        bvec3 test = bvec3(TEST(x, yz), TEST(y, zx), TEST(z, xy));
        sgn = test.x ? vec3(sgn.x,0,0) : (test.y ? vec3(0,sgn.y,0) : vec3(0,0,test.z ? sgn.z:0));

    # undef TEST

    distance = (sgn.x != 0) ? d.x : ((sgn.y != 0) ? d.y : d.z);

    normal = oriented ? (box.rot * sgn) : sgn;

    return (sgn.x != 0) || (sgn.y != 0) || (sgn.z != 0);

}
gkjohnson commented 5 months ago

It doesn't seem to beat the function currently being used.