21bbox::bbox(
float xMin,
float yMin,
float zMin,
float xMax,
float yMax,
float zMax)
24 min = vec3(xMin, yMin, zMin);
25 max = vec3(xMax, yMax, zMax);
30 min = vec3(std::numeric_limits<float>::max(), std::numeric_limits<float>::max(), std::numeric_limits<float>::max());
31 max = vec3(-std::numeric_limits<float>::max(),
32 -std::numeric_limits<float>::max(),
33 -std::numeric_limits<float>::max());
38 if(min != vec3(std::numeric_limits<float>::max(),
39 std::numeric_limits<float>::max(),
40 std::numeric_limits<float>::max()) ||
41 max != vec3(-std::numeric_limits<float>::max(),
42 -std::numeric_limits<float>::max(),
43 -std::numeric_limits<float>::max()))
54 return (glm::abs<float>(max.x - min.x) < glm::epsilon<float>() &&
55 glm::abs<float>(max.y - min.y) < glm::epsilon<float>() &&
56 glm::abs<float>(max.z - min.z) < glm::epsilon<float>());
62 memset(&bounds_plane, 0,
sizeof(
plane));
68 bounds_plane.
data.y = 1;
69 bounds_plane.
data.w = -max.y;
72 bounds_plane.
data.x = 1;
73 bounds_plane.
data.w = -max.x;
76 bounds_plane.
data.z = 1;
77 bounds_plane.
data.w = -max.z;
80 bounds_plane.
data.y = -1;
81 bounds_plane.
data.w = min.y;
84 bounds_plane.
data.x = -1;
85 bounds_plane.
data.w = min.x;
88 bounds_plane.
data.z = -1;
89 bounds_plane.
data.w = min.z;
103 points_out[0].x = min.x;
104 points_out[0].y = max.y;
105 points_out[0].z = min.z;
106 points_out[1].x = min.x;
107 points_out[1].y = max.y;
108 points_out[1].z = max.z;
109 points_out[2].x = max.x;
110 points_out[2].y = max.y;
111 points_out[2].z = max.z;
112 points_out[3].x = max.x;
113 points_out[3].y = max.y;
114 points_out[3].z = min.z;
117 points_out[0].x = max.x;
118 points_out[0].y = min.y;
119 points_out[0].z = min.z;
120 points_out[1].x = max.x;
121 points_out[1].y = max.y;
122 points_out[1].z = min.z;
123 points_out[2].x = max.x;
124 points_out[2].y = max.y;
125 points_out[2].z = max.z;
126 points_out[3].x = max.x;
127 points_out[3].y = min.y;
128 points_out[3].z = max.z;
131 points_out[0].x = max.x;
132 points_out[0].y = min.y;
133 points_out[0].z = max.z;
134 points_out[1].x = max.x;
135 points_out[1].y = max.y;
136 points_out[1].z = max.z;
137 points_out[2].x = min.x;
138 points_out[2].y = max.y;
139 points_out[2].z = max.z;
140 points_out[3].x = min.x;
141 points_out[3].y = min.y;
142 points_out[3].z = max.z;
145 points_out[0].x = min.x;
146 points_out[0].y = min.y;
147 points_out[0].z = max.z;
148 points_out[1].x = min.x;
149 points_out[1].y = min.y;
150 points_out[1].z = min.z;
151 points_out[2].x = max.x;
152 points_out[2].y = min.y;
153 points_out[2].z = min.z;
154 points_out[3].x = max.x;
155 points_out[3].y = min.y;
156 points_out[3].z = max.z;
159 points_out[0].x = min.x;
160 points_out[0].y = min.y;
161 points_out[0].z = max.z;
162 points_out[1].x = min.x;
163 points_out[1].y = max.y;
164 points_out[1].z = max.z;
165 points_out[2].x = min.x;
166 points_out[2].y = max.y;
167 points_out[2].z = min.z;
168 points_out[3].x = min.x;
169 points_out[3].y = min.y;
170 points_out[3].z = min.z;
173 points_out[0].x = min.x;
174 points_out[0].y = min.y;
175 points_out[0].z = min.z;
176 points_out[1].x = min.x;
177 points_out[1].y = max.y;
178 points_out[1].z = min.z;
179 points_out[2].x = max.x;
180 points_out[2].y = max.y;
181 points_out[2].z = min.z;
182 points_out[3].x = max.x;
183 points_out[3].y = min.y;
184 points_out[3].z = min.z;
191 unsigned int point_count,
192 unsigned int point_stride,
202 if((point_buffer !=
nullptr) && (point_count != 0u))
204 for(
unsigned int v = 0; v < point_count; ++v, point_buffer += point_stride)
206 add_point(*
reinterpret_cast<const vec3*
>(point_buffer));
215 min = center - vec3(radius, radius, radius);
216 max = center + vec3(radius, radius, radius);
246 return (min.x <= bounds.
max.x) && (min.y <= bounds.
max.y) && (min.z <= bounds.
max.z) && (max.x >= bounds.
min.x) &&
247 (max.y >= bounds.
min.y) && (max.z >= bounds.
min.z);
256 if(bounds.
min.x < min.x || bounds.
min.x > max.x)
260 else if(bounds.
min.y < min.y || bounds.
min.y > max.y)
264 else if(bounds.
min.z < min.z || bounds.
min.z > max.z)
268 else if(bounds.
max.x < min.x || bounds.
max.x > max.x)
272 else if(bounds.
max.y < min.y || bounds.
max.y > max.y)
276 else if(bounds.
max.z < min.z || bounds.
max.z > max.z)
288 return (min.x <= bounds.
max.x) && (min.y <= bounds.
max.y) && (min.z <= bounds.
max.z) && (max.x >= bounds.
min.x) &&
289 (max.y >= bounds.
min.y) && (max.z >= bounds.
min.z);
294 intersection.
min.x = glm::max(min.x, bounds.
min.x);
295 intersection.
min.y = glm::max(min.y, bounds.
min.y);
296 intersection.
min.z = glm::max(min.z, bounds.
min.z);
297 intersection.
max.x = glm::min(max.x, bounds.
max.x);
298 intersection.
max.y = glm::min(max.y, bounds.
max.y);
299 intersection.
max.z = glm::min(max.z, bounds.
max.z);
302 if(intersection.
min.x > intersection.
max.x || intersection.
min.y > intersection.
max.y ||
303 intersection.
min.z > intersection.
max.z)
314 return ((min.x - tolerance.x) <= (bounds.
max.x + tolerance.x)) &&
315 ((min.y - tolerance.y) <= (bounds.
max.y + tolerance.y)) &&
316 ((min.z - tolerance.z) <= (bounds.
max.z + tolerance.z)) &&
317 ((max.x + tolerance.x) >= (bounds.
min.x - tolerance.x)) &&
318 ((max.y + tolerance.y) >= (bounds.
min.y - tolerance.y)) &&
319 ((max.z + tolerance.z) >= (bounds.
min.z - tolerance.z));
322bool bbox::intersect(
const vec3& origin,
const vec3& velocity,
float& t,
bool restrict_range )
const
324 float tMin = std::numeric_limits<float>::min();
325 float tMax = std::numeric_limits<float>::max();
339 if(glm::abs<float>(velocity.x) > glm::epsilon<float>())
341 fTemp = 1.0f / velocity.x;
342 t1 = (max.x - origin.x) * fTemp;
343 t2 = (min.x - origin.x) * fTemp;
377 if(origin.x < min.x || origin.x > max.x)
384 if(glm::abs<float>(velocity.y) > glm::epsilon<float>())
386 fTemp = 1.0f / velocity.y;
387 t1 = (max.y - origin.y) * fTemp;
388 t2 = (min.y - origin.y) * fTemp;
422 if(origin.y < min.y || origin.y > max.y)
431 if(glm::abs<float>(velocity.z) > glm::epsilon<float>())
433 fTemp = 1.0f / velocity.z;
434 t1 = (max.z - origin.z) * fTemp;
435 t2 = (min.z - origin.z) * fTemp;
469 if(origin.z < min.z || origin.z > max.z)
487 if(t < 0.0f || (restrict_range && t > 1.0f))
496bool bbox::intersect(
const vec3& v_tri0,
const vec3& v_tri1,
const vec3& v_tri2,
const bbox& tri_bounds)
const
500 if(tri_bounds.
min.x > max.x || tri_bounds.
max.x < min.x || tri_bounds.
min.y > max.y || tri_bounds.
max.y < min.y ||
501 tri_bounds.
min.z > max.z || tri_bounds.
max.z < min.z)
510 const vec3 v0 = v_tri0 - vCenter;
511 const vec3 v1 = v_tri1 - vCenter;
512 const vec3 v2 = v_tri2 - vCenter;
518 vec3 vEdge0 = v1 - v0;
519 vec3 vEdge1 = v2 - v1;
520 vec3 vNormal = glm::cross(vEdge0, vEdge1);
521 float fPlaneDistance = -glm::dot(vNormal, v0);
524 vec3 vNearPoint, vFarPoint;
528 vNearPoint.x = min.x;
533 vNearPoint.x = max.x;
538 vNearPoint.y = min.y;
543 vNearPoint.y = max.y;
548 vNearPoint.z = min.z;
553 vNearPoint.z = max.z;
558 if(glm::dot(vNormal, vNearPoint - vCenter) + fPlaneDistance > 0.0f)
564 if(glm::dot(vNormal, vFarPoint - vCenter) + fPlaneDistance < 0.0f)
571 float fTemp0, fTemp1, fMin, fMax;
572#define AXISTEST(vEdge, vP0, vP1, nComponent0, nComponent1) \
573 fTemp0 = vEdge[nComponent1] * vP0[nComponent0] - vEdge[nComponent0] * vP0[nComponent1]; \
574 fTemp1 = vEdge[nComponent1] * vP1[nComponent0] - vEdge[nComponent0] * vP1[nComponent1]; \
575 if(fTemp0 < fTemp1) \
585 fTemp0 = vAbsEdge[nComponent1] * vExtents[nComponent0] + vAbsEdge[nComponent0] * vExtents[nComponent1]; \
586 if(fMin > fTemp0 || fMax < -fTemp0) \
589#define AXISTEST2(vEdge, vP0, vP1, nComponent0, nComponent1) \
590 fTemp0 = -vEdge[nComponent1] * vP0[nComponent0] + vEdge[nComponent0] * vP0[nComponent1]; \
591 fTemp1 = -vEdge[nComponent1] * vP1[nComponent0] + vEdge[nComponent0] * vP1[nComponent1]; \
592 if(fTemp0 < fTemp1) \
602 fTemp0 = vAbsEdge[nComponent1] * vExtents[nComponent0] + vAbsEdge[nComponent0] * vExtents[nComponent1]; \
603 if(fMin > fTemp0 || fMax < -fTemp0) \
607 vAbsEdge.x = glm::abs<float>(vEdge0.x);
608 vAbsEdge.y = glm::abs<float>(vEdge0.y);
609 vAbsEdge.z = glm::abs<float>(vEdge0.z);
614 vAbsEdge.x = glm::abs<float>(vEdge1.x);
615 vAbsEdge.y = glm::abs<float>(vEdge1.y);
616 vAbsEdge.z = glm::abs<float>(vEdge1.z);
621 const vec3 vEdge2 = v0 - v2;
622 vAbsEdge.x = glm::abs<float>(vEdge2.x);
623 vAbsEdge.y = glm::abs<float>(vEdge2.y);
624 vAbsEdge.z = glm::abs<float>(vEdge2.z);
642 if(tri_bounds.
min.x > max.x || tri_bounds.
max.x < min.x || tri_bounds.
min.y > max.y || tri_bounds.
max.y < min.y ||
643 tri_bounds.
min.z > max.z || tri_bounds.
max.z < min.z)
652 const vec3 v0 = v_tri0 - vCenter;
653 const vec3 v1 = v_tri1 - vCenter;
654 const vec3 v2 = v_tri2 - vCenter;
660 vec3 vEdge0 = v1 - v0;
661 vec3 vEdge1 = v2 - v1;
662 vec3 vNormal = glm::cross(vEdge0, vEdge1);
663 float fPlaneDistance = -glm::dot(vNormal, v0);
666 vec3 vNearPoint, vFarPoint;
670 vNearPoint.x = min.x;
675 vNearPoint.x = max.x;
680 vNearPoint.y = min.y;
685 vNearPoint.y = max.y;
690 vNearPoint.z = min.z;
695 vNearPoint.z = max.z;
700 if(glm::dot(vNormal, vNearPoint - vCenter) + fPlaneDistance > 0.0f)
706 if(glm::dot(vNormal, vFarPoint - vCenter) + fPlaneDistance < 0.0f)
713 float fTemp0, fTemp1, fMin, fMax;
714#define AXISTEST(vEdge, vP0, vP1, nComponent0, nComponent1) \
715 fTemp0 = vEdge[nComponent1] * vP0[nComponent0] - vEdge[nComponent0] * vP0[nComponent1]; \
716 fTemp1 = vEdge[nComponent1] * vP1[nComponent0] - vEdge[nComponent0] * vP1[nComponent1]; \
717 if(fTemp0 < fTemp1) \
727 fTemp0 = vAbsEdge[nComponent1] * vExtents[nComponent0] + vAbsEdge[nComponent0] * vExtents[nComponent1]; \
728 if(fMin > fTemp0 || fMax < -fTemp0) \
731#define AXISTEST2(vEdge, vP0, vP1, nComponent0, nComponent1) \
732 fTemp0 = -vEdge[nComponent1] * vP0[nComponent0] + vEdge[nComponent0] * vP0[nComponent1]; \
733 fTemp1 = -vEdge[nComponent1] * vP1[nComponent0] + vEdge[nComponent0] * vP1[nComponent1]; \
734 if(fTemp0 < fTemp1) \
744 fTemp0 = vAbsEdge[nComponent1] * vExtents[nComponent0] + vAbsEdge[nComponent0] * vExtents[nComponent1]; \
745 if(fMin > fTemp0 || fMax < -fTemp0) \
749 vAbsEdge.x = glm::abs<float>(vEdge0.x);
750 vAbsEdge.y = glm::abs<float>(vEdge0.y);
751 vAbsEdge.z = glm::abs<float>(vEdge0.z);
756 vAbsEdge.x = glm::abs<float>(vEdge1.x);
757 vAbsEdge.y = glm::abs<float>(vEdge1.y);
758 vAbsEdge.z = glm::abs<float>(vEdge1.z);
763 const vec3 vEdge2 = v0 - v2;
764 vAbsEdge.x = glm::abs<float>(vEdge2.x);
765 vAbsEdge.y = glm::abs<float>(vEdge2.y);
766 vAbsEdge.z = glm::abs<float>(vEdge2.z);
777 if(
point.
x < min.x - tolerance ||
point.
x > max.x + tolerance)
781 if(
point.
y < min.y - tolerance ||
point.
y > max.y + tolerance)
785 if(
point.z < min.z - tolerance ||
point.z > max.z + tolerance)
811 if(
point.
x < min.x - tolerance.x ||
point.
x > max.x + tolerance.x)
815 if(
point.
y < min.y - tolerance.y ||
point.
y > max.y + tolerance.y)
819 if(
point.z < min.z - tolerance.z ||
point.z > max.z + tolerance.z)
831 if(test_point.x < min.x)
835 else if(test_point.x > max.x)
841 Closest.x = test_point.x;
845 if(test_point.y < min.y)
849 else if(test_point.y > max.y)
855 Closest.y = test_point.y;
859 if(test_point.z < min.z)
863 else if(test_point.z > max.z)
869 Closest.z = test_point.z;
878 *
this =
mul(*
this, t);
886 const auto x_axis = t.x_axis();
887 const auto y_axis = t.y_axis();
888 const auto z_axis = t.z_axis();
889 auto xa = x_axis * bounds.
min.x;
890 auto xb = x_axis * bounds.
max.x;
891 auto ya = y_axis * bounds.
min.y;
892 auto yb = y_axis * bounds.
max.y;
893 auto za = z_axis * bounds.
min.z;
894 auto zb = z_axis * bounds.
max.z;
896 return bbox(math::min(xa, xb) + math::min(ya, yb) + math::min(za, zb) + t.get_position(),
897 math::max(xa, xb) + math::max(ya, yb) + math::max(za, zb) + t.get_position());
910 const auto x_axis = t.x_unit_axis();
911 const auto y_axis = t.y_unit_axis();
912 const auto z_axis = t.z_unit_axis();
913 auto xa = x_axis * bounds.
min.x;
914 auto xb = x_axis * bounds.
max.x;
915 auto ya = y_axis * bounds.
min.y;
916 auto yb = y_axis * bounds.
max.y;
917 auto za = z_axis * bounds.
min.z;
918 auto zb = z_axis * bounds.
max.z;
920 return bbox(math::min(xa, xb) + math::min(ya, yb) + math::min(za, zb) + t.get_position(),
921 math::max(xa, xb) + math::max(ya, yb) + math::max(za, zb) + t.get_position());
948 return vec3((max.x + min.x) * 0.5f, (max.y + min.y) * 0.5f, (max.z + min.z) * 0.5f);
953 return vec3((max.x - min.x) * 0.5f, (max.y - min.y) * 0.5f, (max.z - min.z) * 0.5f);
968 min.x -= grow_size.x;
969 min.y -= grow_size.y;
970 min.z -= grow_size.z;
971 max.x += grow_size.x;
972 max.y += grow_size.y;
973 max.z += grow_size.z;
979 { min.x, min.y, min.z },
980 { max.x, min.y, min.z },
981 { min.x, max.y, min.z },
982 { max.x, max.y, min.z },
983 { min.x, min.y, max.z },
984 { max.x, min.y, max.z },
985 { min.x, max.y, max.z },
986 { max.x, max.y, max.z }
1024 return (min == bounds.
min) && (max == bounds.
max);
1029 return (min != bounds.
min) || (max != bounds.
max);
#define AXISTEST2(vEdge, vP0, vP1, nComponent0, nComponent1)
#define AXISTEST(vEdge, vP0, vP1, nComponent0, nComponent1)
Storage for box vector values and wraps up common functionality.
bbox & add_point(const vec3 &point)
Grows the bounding box based on the point passed.
vec3 max
The maximum vector value of the bounding box.
bbox operator*(float scale) const
Scales the bounding box values by the scalar passed.
void reset()
Resets the bounding box values.
bool intersect(const bbox &bounds) const
Tests to see if this AABB is intersected by another AABB.
bbox & operator+=(const vec3 &shift)
Moves the bounding box by the vector passed.
bbox & from_points(const char *point_buffer, unsigned int point_count, unsigned int point_stride, bool reset=true)
Calculates the bounding box based on the points specified.
bbox & operator-=(const vec3 &shift)
Moves the bounding box by the vector passed.
bbox & mul(const transform &t)
Transforms an axis aligned bounding box by the specified matrix.
void get_plane_points(volume_plane::e side, vec3 points_out[]) const
Retrieves the four points that form the boundary of the specified side of the bounding box.
void inflate(float amount)
Grows the bounding box by the specified number of world space units on all three axes.
bool operator==(const bbox &bounds) const
Checks for equality between this bounding box and another.
bbox & from_sphere(const vec3 ¢er, float radius)
Calculates the bounding box based on the sphere specified.
bbox & operator*=(const transform &t)
Transforms the bounding box by the matrix passed.
vec3 min
The minimum vector value of the bounding box.
std::array< vec3, 8 > get_corners() const
bool is_degenerate() const
Checks if the bounding box is degenerate (empty)
bbox & mul_no_scale(const transform &t)
bool contains_point(const vec3 &point) const
Tests to see if a point falls within this bounding box or not.
static bbox empty
An empty bounding box.
plane get_plane(volume_plane::e side) const
Retrieves the plane for the specified side of the bounding box.
void validate()
Ensures that the values placed in the min/max values never make the bounding box itself inverted.
bool is_populated() const
Checks if the bounding box is populated.
bool operator!=(const bbox &bounds) const
Checks for inequality between this bounding box and another.
vec3 get_dimensions() const
Returns a vector containing the dimensions of the bounding box.
vec3 get_extents() const
Returns a vector containing the extents of the bounding box (the half-dimensions)
vec3 closest_point(const vec3 &source_point) const
Computes the closest point on the surface of the AABB to the input point.
vec3 get_center() const
Returns a vector containing the exact center point of the box.
bbox()
Default Constructor.
Storage for infinite plane.
vec4 data
The components of the plane.