123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149 |
- AABB3 boxUnion(AABB3 a, AABB3 b) {
- return (AABB3) {
- {fmin(a.min.x, b.min.x), fmin(a.min.y, b.min.y), fmin(a.min.z, b.min.z)},
- {fmax(a.max.x, b.max.x), fmax(a.max.y, b.max.y), fmax(a.max.z, b.max.z)}
- };
- }
- // this version has no branching, but only answers yes or no.
- // algorithm explanation here. hopefully my extrapolation into 3 dimensions is correct.
- // http://tavianator.com/fast-branchless-raybounding-box-intersections/
- int boxRayIntersectFast3p(const AABB3* b, const Ray3* r) {
- Vector3 t1, t2;
- float tmin, tmax;
- Vector3 id;
-
- vInv3p(&r->d, &id);
-
- t1.x = (b->min.x - r->o.x) * id.x;
- t2.x = (b->max.x - r->o.x) * id.x;
- tmin = fminf(t1.x, t2.x);
- tmax = fmaxf(t1.x, t2.x);
-
- t1.y = (b->min.y - r->o.y) * id.y;
- t2.y = (b->max.y - r->o.y) * id.y;
- tmin = fmaxf(tmin, fminf(t1.y, t2.y));
- tmax = fminf(tmax, fmaxf(t1.y, t2.y));
-
- t1.z = (b->min.z - r->o.z) * id.z;
- t2.z = (b->max.z - r->o.z) * id.z;
- tmin = fmaxf(tmin, fminf(t1.z, t2.z));
- tmax = fminf(tmax, fmaxf(t1.z, t2.z));
- return tmax >= tmin && tmax > 0.0f;
- }
- // this version has no branching, but only answers yes or no.
- // http://tavianator.com/fast-branchless-raybounding-box-intersections/
- int boxRayIntersectFast2(const AABB2* b, const Ray2* r) {
- Vector2 t1, t2;
- float tmin, tmax;
- Vector2 id;
-
- vInv2p(&r->d, &id);
-
- t1.x = (b->min.x - r->o.x) * id.x;
- t2.x = (b->max.x - r->o.x) * id.x;
- tmin = fminf(t1.x, t2.x);
- tmax = fmaxf(t1.x, t2.x);
-
- t1.y = (b->min.y - r->o.y) * id.y;
- t2.y = (b->max.y - r->o.y) * id.y;
- // tmin = fmaxf(tmin, fminf(t1.y, t2.y));
- tmax = fminf(tmax, fmaxf(t1.y, t2.y));
-
- return tmax >= tmin && tmax > 0.0f;
- }
- // this version gives the point of intersection as well as distance
- // algorithm explanation here. hopefully my extrapolation into 3 dimensions is correct.
- // http://tavianator.com/fast-branchless-raybounding-box-intersections/
- int boxRayIntersect3p(const AABB3* b, const Ray3* r, Vector3* ipoint, float* idist) {
- Vector3 t1, t2, id;
- float tmin, tmax;
-
- vInv3p(&r->d, &id);
-
- t1.x = (b->min.x - r->o.x) * id.x;
- t2.x = (b->max.x - r->o.x) * id.x;
- tmin = fminf(t1.x, t2.x);
- tmax = fmaxf(t1.x, t2.x);
-
- t1.y = (b->min.y - r->o.y) * id.y;
- t2.y = (b->max.y - r->o.y) * id.y;
- tmin = fmaxf(tmin, fminf(t1.y, t2.y));
- tmax = fminf(tmax, fmaxf(t1.y, t2.y));
-
- t1.z = (b->min.z - r->o.z) * id.z;
- t2.z = (b->max.z - r->o.z) * id.z;
- tmin = fmaxf(tmin, fminf(t1.z, t2.z));
- tmax = fminf(tmax, fmaxf(t1.z, t2.z));
-
- if(tmax < tmin) return C3DLAS_DISJOINT;
-
- if(idist) *idist = tmin;
-
- if(ipoint) {
- ipoint->x = r->o.x + (r->d.x * tmin);
- ipoint->y = r->o.y + (r->d.y * tmin);
- ipoint->z = r->o.z + (r->d.z * tmin);
- }
-
- return C3DLAS_INTERSECT;
- }
- // this version gives the point of intersection as well as distance
- // algorithm explanation here. hopefully my extrapolation into 3 dimensions is correct.
- // http://tavianator.com/fast-branchless-raybounding-box-intersections/
- int intersectBoxLine3p(const AABB3* b, const Line3* l, Vector3* ipoint, float* idist) {
- Vector3 t1, t2, id;
- float tmin, tmax;
-
- Vector3 o = l->start;
- Vector3 d = vNorm3(vSub3(l->end, l->start));
- id = vInv3(d);
-
- t1.x = (b->min.x - o.x) * id.x;
- t2.x = (b->max.x - o.x) * id.x;
- tmin = fminf(t1.x, t2.x);
- tmax = fmaxf(t1.x, t2.x);
-
- t1.y = (b->min.y - o.y) * id.y;
- t2.y = (b->max.y - o.y) * id.y;
- tmin = fmaxf(tmin, fminf(t1.y, t2.y));
- tmax = fminf(tmax, fmaxf(t1.y, t2.y));
-
- t1.z = (b->min.z - o.z) * id.z;
- t2.z = (b->max.z - o.z) * id.z;
- tmin = fmaxf(tmin, fminf(t1.z, t2.z));
- tmax = fminf(tmax, fmaxf(t1.z, t2.z));
-
- if(tmax < tmin) return C3DLAS_DISJOINT;
-
- if(idist) *idist = tmin;
-
- if(ipoint) {
- ipoint->x = o.x + (d.x * tmin);
- ipoint->y = o.y + (d.y * tmin);
- ipoint->z = o.z + (d.z * tmin);
- }
-
- return C3DLAS_INTERSECT;
- }
- int intersectBoxLine3(AABB3 b, Line3 l, Vector3* ipoint, float* idist) {
- return intersectBoxLine3p(&b, &l, ipoint, idist);
- }
- bool boxContainsPoint3(AABB3 b, Vector3 p) {
- return b.min.x <= p.x && b.max.x >= p.x
- && b.min.y <= p.y && b.max.y >= p.y
- && b.min.z <= p.z && b.max.z >= p.z;
- }
|