stereokit-rust 0.4.0-alpha.22

High-Level Rust bindings around the StereoKitC library for XR
Documentation
#include "bbox.h"

namespace sk {

// Update the bounding box to include the point p
void
bbox_update(boundingbox& bbox, vec3 p)
{
    vec3 *bounds = bbox.bounds;

    if (p.x < bounds[0].x) bounds[0].x = p.x;
    if (p.y < bounds[0].y) bounds[0].y = p.y;
    if (p.z < bounds[0].z) bounds[0].z = p.z;

    if (p.x > bounds[1].x) bounds[1].x = p.x;
    if (p.y > bounds[1].y) bounds[1].y = p.y;
    if (p.z > bounds[1].z) bounds[1].z = p.z;
}

// Return the bounding box resulting from the combination of the
// two given bounding boxes
boundingbox
bbox_combine(const boundingbox& bbox1, const boundingbox& bbox2)
{
    vec3 min, max;

    min = bbox_min(bbox1);
    max = bbox_max(bbox1);

    const vec3 *bounds2 = bbox2.bounds;

    if (bounds2[0].x < min.x) min.x = bounds2[0].x;
    if (bounds2[0].y < min.y) min.y = bounds2[0].y;
    if (bounds2[0].z < min.z) min.z = bounds2[0].z;

    if (bounds2[1].x > max.x) max.x = bounds2[1].x;
    if (bounds2[1].y > max.y) max.y = bounds2[1].y;
    if (bounds2[1].z > max.z) max.z = bounds2[1].z;

    return boundingbox{min, max};
}


// Intersect a ray (delimited by t0 and t1) with the given bounding box.
// Returns true (and sets t_min and t_max) when the ray intersects the bbox,
// returns false otherwise

bool
bbox_intersect_full(const boundingbox& bbox, float& t_min, float& t_max, bbox_ray_t r, float t0, float t1)
{
    // This code makes handy use of IEEE floating-point behaviour, such
    // as division by zero. See
    // 1) Shirley et.al. Section 10.9.1
    // 2) Williams et.al., "An Efficient and Robust Ray-Box Intersection Algorithm"

    float tmin, tmax;
    float tymin, tymax, tzmin, tzmax;
    const vec3* bounds = bbox.bounds;

    tmin = (bounds[r.sign[0]].x - r.origin.x) * r.inv_direction.x;
    tmax = (bounds[1-r.sign[0]].x - r.origin.x) * r.inv_direction.x;

    tymin = (bounds[r.sign[1]].y - r.origin.y) * r.inv_direction.y;
    tymax = (bounds[1-r.sign[1]].y - r.origin.y) * r.inv_direction.y;

    if (tmin > tymax || tymin > tmax)
        return false;

    if (tymin > tmin)
        tmin = tymin;
    if (tymax < tmax)
        tmax = tymax;

    tzmin = (bounds[r.sign[2]].z - r.origin.z) * r.inv_direction.z;
    tzmax = (bounds[1-r.sign[2]].z - r.origin.z) * r.inv_direction.z;

    if (tmin > tzmax || tzmin > tmax)
        return false;

    if (tzmin > tmin)
        tmin = tzmin;
    if (tzmax < tmax)
        tmax = tzmax;

    t_min = tmin;
    t_max = tmax;

    return (tmin < t1 && tmax > t0);
}

// Intersect a ray with the given bounding box.
// Returns true when the ray intersects the bbox, returns false otherwise

bool
bbox_intersect(const boundingbox& bbox, bbox_ray_t r, float t0, float t1)
{
    // This code makes handy use of IEEE floating-point behaviour, such
    // as division by zero. See
    // 1) Shirley et.al. Section 10.9.1
    // 2) Williams et.al., "An Efficient and Robust Ray-Box Intersection Algorithm"

    float tmin, tmax;
    float tymin, tymax, tzmin, tzmax;
    const vec3* bounds = bbox.bounds;

    tmin = (bounds[r.sign[0]].x - r.origin.x) * r.inv_direction.x;
    tmax = (bounds[1-r.sign[0]].x - r.origin.x) * r.inv_direction.x;

    tymin = (bounds[r.sign[1]].y - r.origin.y) * r.inv_direction.y;
    tymax = (bounds[1-r.sign[1]].y - r.origin.y) * r.inv_direction.y;

    if (tmin > tymax || tymin > tmax)
        return false;

    if (tymin > tmin)
        tmin = tymin;
    if (tymax < tmax)
        tmax = tymax;

    tzmin = (bounds[r.sign[2]].z - r.origin.z) * r.inv_direction.z;
    tzmax = (bounds[1-r.sign[2]].z - r.origin.z) * r.inv_direction.z;

    if (tmin > tzmax || tzmin > tmax)
        return false;

    if (tzmin > tmin)
        tmin = tzmin;
    if (tzmax < tmax)
        tmax = tzmax;

    return (tmin < t1 && tmax > t0);
}
    
} // namespace sk