box.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. AABB3 boxUnion(AABB3 a, AABB3 b) {
  2. return (AABB3) {
  3. {fmin(a.min.x, b.min.x), fmin(a.min.y, b.min.y), fmin(a.min.z, b.min.z)},
  4. {fmax(a.max.x, b.max.x), fmax(a.max.y, b.max.y), fmax(a.max.z, b.max.z)}
  5. };
  6. }
  7. // this version has no branching, but only answers yes or no.
  8. // algorithm explanation here. hopefully my extrapolation into 3 dimensions is correct.
  9. // http://tavianator.com/fast-branchless-raybounding-box-intersections/
  10. int boxRayIntersectFast3p(const AABB3* b, const Ray3* r) {
  11. Vector3 t1, t2;
  12. float tmin, tmax;
  13. Vector3 id;
  14. vInv3p(&r->d, &id);
  15. t1.x = (b->min.x - r->o.x) * id.x;
  16. t2.x = (b->max.x - r->o.x) * id.x;
  17. tmin = fminf(t1.x, t2.x);
  18. tmax = fmaxf(t1.x, t2.x);
  19. t1.y = (b->min.y - r->o.y) * id.y;
  20. t2.y = (b->max.y - r->o.y) * id.y;
  21. tmin = fmaxf(tmin, fminf(t1.y, t2.y));
  22. tmax = fminf(tmax, fmaxf(t1.y, t2.y));
  23. t1.z = (b->min.z - r->o.z) * id.z;
  24. t2.z = (b->max.z - r->o.z) * id.z;
  25. tmin = fmaxf(tmin, fminf(t1.z, t2.z));
  26. tmax = fminf(tmax, fmaxf(t1.z, t2.z));
  27. return tmax >= tmin && tmax > 0.0f;
  28. }
  29. // this version has no branching, but only answers yes or no.
  30. // http://tavianator.com/fast-branchless-raybounding-box-intersections/
  31. int boxRayIntersectFast2(const AABB2* b, const Ray2* r) {
  32. Vector2 t1, t2;
  33. float tmin, tmax;
  34. Vector2 id;
  35. vInv2p(&r->d, &id);
  36. t1.x = (b->min.x - r->o.x) * id.x;
  37. t2.x = (b->max.x - r->o.x) * id.x;
  38. tmin = fminf(t1.x, t2.x);
  39. tmax = fmaxf(t1.x, t2.x);
  40. t1.y = (b->min.y - r->o.y) * id.y;
  41. t2.y = (b->max.y - r->o.y) * id.y;
  42. // tmin = fmaxf(tmin, fminf(t1.y, t2.y));
  43. tmax = fminf(tmax, fmaxf(t1.y, t2.y));
  44. return tmax >= tmin && tmax > 0.0f;
  45. }
  46. // this version gives the point of intersection as well as distance
  47. // algorithm explanation here. hopefully my extrapolation into 3 dimensions is correct.
  48. // http://tavianator.com/fast-branchless-raybounding-box-intersections/
  49. int boxRayIntersect3p(const AABB3* b, const Ray3* r, Vector3* ipoint, float* idist) {
  50. Vector3 t1, t2, id;
  51. float tmin, tmax;
  52. vInv3p(&r->d, &id);
  53. t1.x = (b->min.x - r->o.x) * id.x;
  54. t2.x = (b->max.x - r->o.x) * id.x;
  55. tmin = fminf(t1.x, t2.x);
  56. tmax = fmaxf(t1.x, t2.x);
  57. t1.y = (b->min.y - r->o.y) * id.y;
  58. t2.y = (b->max.y - r->o.y) * id.y;
  59. tmin = fmaxf(tmin, fminf(t1.y, t2.y));
  60. tmax = fminf(tmax, fmaxf(t1.y, t2.y));
  61. t1.z = (b->min.z - r->o.z) * id.z;
  62. t2.z = (b->max.z - r->o.z) * id.z;
  63. tmin = fmaxf(tmin, fminf(t1.z, t2.z));
  64. tmax = fminf(tmax, fmaxf(t1.z, t2.z));
  65. if(tmax < tmin) return C3DLAS_DISJOINT;
  66. if(idist) *idist = tmin;
  67. if(ipoint) {
  68. ipoint->x = r->o.x + (r->d.x * tmin);
  69. ipoint->y = r->o.y + (r->d.y * tmin);
  70. ipoint->z = r->o.z + (r->d.z * tmin);
  71. }
  72. return C3DLAS_INTERSECT;
  73. }
  74. // this version gives the point of intersection as well as distance
  75. // algorithm explanation here. hopefully my extrapolation into 3 dimensions is correct.
  76. // http://tavianator.com/fast-branchless-raybounding-box-intersections/
  77. int intersectBoxLine3p(const AABB3* b, const Line3* l, Vector3* ipoint, float* idist) {
  78. Vector3 t1, t2, id;
  79. float tmin, tmax;
  80. Vector3 o = l->start;
  81. Vector3 d = vNorm3(vSub3(l->end, l->start));
  82. id = vInv3(d);
  83. t1.x = (b->min.x - o.x) * id.x;
  84. t2.x = (b->max.x - o.x) * id.x;
  85. tmin = fminf(t1.x, t2.x);
  86. tmax = fmaxf(t1.x, t2.x);
  87. t1.y = (b->min.y - o.y) * id.y;
  88. t2.y = (b->max.y - o.y) * id.y;
  89. tmin = fmaxf(tmin, fminf(t1.y, t2.y));
  90. tmax = fminf(tmax, fmaxf(t1.y, t2.y));
  91. t1.z = (b->min.z - o.z) * id.z;
  92. t2.z = (b->max.z - o.z) * id.z;
  93. tmin = fmaxf(tmin, fminf(t1.z, t2.z));
  94. tmax = fminf(tmax, fmaxf(t1.z, t2.z));
  95. if(tmax < tmin) return C3DLAS_DISJOINT;
  96. if(idist) *idist = tmin;
  97. if(ipoint) {
  98. ipoint->x = o.x + (d.x * tmin);
  99. ipoint->y = o.y + (d.y * tmin);
  100. ipoint->z = o.z + (d.z * tmin);
  101. }
  102. return C3DLAS_INTERSECT;
  103. }
  104. int intersectBoxLine3(AABB3 b, Line3 l, Vector3* ipoint, float* idist) {
  105. return intersectBoxLine3p(&b, &l, ipoint, idist);
  106. }
  107. bool boxContainsPoint3(AABB3 b, Vector3 p) {
  108. return b.min.x <= p.x && b.max.x >= p.x
  109. && b.min.y <= p.y && b.max.y >= p.y
  110. && b.min.z <= p.z && b.max.z >= p.z;
  111. }