10#ifndef MATH_OCTREETOOLS_HEADER
11#define MATH_OCTREETOOLS_HEADER
72template <
typename T,
int N>
90template <
typename T,
int N>
97#define AXISTEST_X01(a, b, fa, fb) { \
98 T p0 = a * v[0][1] - b * v[0][2]; \
99 T p2 = a * v[2][1] - b * v[2][2]; \
100 T min = std::min(p0, p2); T max = std::max(p0, p2); \
101 T rad = fa * boxhalfsize[1] + fb * boxhalfsize[2]; \
102 if (min > rad || max < -rad) return false; }
104#define AXISTEST_X2(a, b, fa, fb) { \
105 T p0 = a * v[0][1] - b * v[0][2]; \
106 T p1 = a * v[1][1] - b * v[1][2]; \
107 T min = std::min(p0, p1); T max = std::max(p0, p1); \
108 T rad = fa * boxhalfsize[1] + fb * boxhalfsize[2]; \
109 if (min > rad || max < -rad) return false; }
111#define AXISTEST_Y02(a, b, fa, fb) { \
112 T p0 = -a * v[0][0] + b * v[0][2]; \
113 T p2 = -a * v[2][0] + b * v[2][2]; \
114 T min = std::min(p0, p2); T max = std::max(p0, p2); \
115 T rad = fa * boxhalfsize[0] + fb * boxhalfsize[2]; \
116 if (min > rad || max < -rad) return false; }
118#define AXISTEST_Y1(a, b, fa, fb) { \
119 T p0 = -a * v[0][0] + b * v[0][2]; \
120 T p1 = -a * v[1][0] + b * v[1][2]; \
121 T min = std::min(p0, p1); T max = std::max(p0, p1); \
122 T rad = fa * boxhalfsize[0] + fb * boxhalfsize[2]; \
123 if (min > rad || max < -rad) return false; }
125#define AXISTEST_Z12(a, b, fa, fb) { \
126 T p1 = a * v[1][0] - b * v[1][1]; \
127 T p2 = a * v[2][0] - b * v[2][1]; \
128 T min = std::min(p1, p2); T max = std::max(p1, p2); \
129 T rad = fa * boxhalfsize[0] + fb * boxhalfsize[1]; \
130 if (min > rad || max < -rad) return false; }
132#define AXISTEST_Z0(a, b, fa, fb) { \
133 T p0 = a * v[0][0] - b * v[0][1]; \
134 T p1 = a * v[1][0] - b * v[1][1]; \
135 T min = std::min(p0, p1); T max = std::max(p0, p1); \
136 T rad = fa * boxhalfsize[0] + fb * boxhalfsize[1]; \
137 if (min > rad || max < -rad) return false; }
149 T abs[3] = { std::abs(e[0][0]), std::abs(e[0][1]), std::abs(e[0][2]) };
156 T abs[3] = { std::abs(e[1][0]), std::abs(e[1][1]), std::abs(e[1][2]) };
163 T abs[3] = { std::abs(e[2][0]), std::abs(e[2][1]), std::abs(e[2][2]) };
169 for (
int i = 0; i < 3; ++i)
173 if (
min > boxhalfsize[i] ||
max < -boxhalfsize[i])
193 for (
int q = 0; q < 3; ++q)
195 if (normal[q] > (T)0)
197 vmin[q] = -boxhalfsize[q] - pos[q];
198 vmax[q] = boxhalfsize[q] - pos[q];
202 vmin[q] = boxhalfsize[q] - pos[q];
203 vmax[q] = -boxhalfsize[q] - pos[q];
207 if (normal.
dot(vmin) > (T)0)
209 if (normal.
dot(vmax) >= (T)0)
233 T idir[3] = { (T)1 / dir[0], (T)1 / dir[1], (T)1 / dir[2] };
234 bool sign[3] = { idir[0] < (T)0, idir[1] < (T)0, idir[2] < (T)0 };
236 float tmin = (box[sign[0]][0] - origin[0]) * idir[0];
237 float tmax = (box[1 - sign[0]][0] - origin[0]) * idir[0];
238 float tymin = (box[sign[1]][1] - origin[1]) * idir[1];
239 float tymax = (box[1 - sign[1]][1] - origin[1]) * idir[1];
241 if (tmin > tymax || tymin > tmax)
248 float tzmin = (box[sign[2]][2] - origin[2]) * idir[2];
249 float tzmax = (box[1 - sign[2]][2] - origin[2]) * idir[2];
251 if (tmin > tzmax || tzmin > tmax)
259 T
const t1 = (T)1/(T)0;
260 return tmin < t1 && tmax > t0;
280 T det = edge1.
dot(pvec);
283 T inv_det = T(1) / det;
289 T u = tvec.
dot(pvec) * inv_det;
290 if (u < T(0) || u > T(1))
297 T v = dir.
dot(qvec) * inv_det;
298 if (v < T(0) || u + v > T(1))
302 T t = edge2.
dot(qvec) * inv_det;
306 return std::numeric_limits<T>::min();
319template <
typename T,
int N>
324 for (
int i = 0; i < N; ++i)
325 if (b1min[i] > b2max[i] || b1max[i] < b2min[i])
339 m1[0] = p2[0] - p1[0]; m1[1] = d2[0]; m1[2] = dx[0];
340 m1[3] = p2[1] - p1[1]; m1[4] = d2[1]; m1[5] = dx[1];
341 m1[6] = p2[2] - p1[2]; m1[7] = d2[2]; m1[8] = dx[2];
344 m2[0] = p2[0] - p1[0]; m2[1] = d1[0]; m2[2] = dx[0];
345 m2[3] = p2[1] - p1[1]; m2[4] = d1[1]; m2[5] = dx[1];
346 m2[6] = p2[2] - p1[2]; m2[7] = d1[2]; m2[8] = dx[2];
355template <
typename T,
int N>
360 for (
int i = 0; i < N; ++i)
361 if (point[i] < aabb_min[i] || point[i] > aabb_max[i])
Matrix class for arbitrary dimensions and types.
Vector class for arbitrary dimensions and types.
T square_norm(void) const
Computes the squared norm of the vector (much cheaper).
Vector< T, N > cross(Vector< T, N > const &other) const
Cross product between this and another vector.
T dot(Vector< T, N > const &other) const
Dot (or scalar) product between self and another vector.
#define MATH_GEOM_NAMESPACE_BEGIN
#define MATH_NAMESPACE_BEGIN
#define MATH_NAMESPACE_END
#define MATH_GEOM_NAMESPACE_END
#define MATH_FLOAT_EQ(x, v)
bool plane_box_overlap(math::Vector< T, 3 > const &normal, math::Vector< T, 3 > const &pos, math::Vector< T, 3 > const &boxhalfsize)
Returns true if the given plane (in Hesse normal form) and a box in the origin given by 'boxhalfsizes...
bool box_box_overlap(math::Vector< T, N > const &b1min, math::Vector< T, N > const &b1max, math::Vector< T, N > const &b2min, math::Vector< T, N > const &b2max)
Returns true if the given boxes overlap, false otherwise.
bool triangle_box_overlap(math::Vector< T, 3 > const &boxcenter, math::Vector< T, 3 > const &boxhalfsize, math::Vector< T, 3 > const &a, math::Vector< T, 3 > const &b, math::Vector< T, 3 > const &c)
Returns true if the given triangle and box overlap, false otherwise.
bool ray_box_overlap(math::Vector< T, 3 > const &origin, math::Vector< T, 3 > const &dir, math::Vector< T, 3 > const &box_min, math::Vector< T, 3 > const &box_max)
Returns true if the given ray intersects with the given axis-aligned bounding box,...
math::Vector< T, 2 > ray_ray_intersect(math::Vector< T, 3 > const &p1, math::Vector< T, 3 > const &d1, math::Vector< T, 3 > const &p2, math::Vector< T, 3 > const &d2)
Intersects the given rays with each other.
T ray_triangle_intersect(math::Vector< T, 3 > const &origin, math::Vector< T, 3 > const &dir, math::Vector< T, 3 > const &a, math::Vector< T, 3 > const &b, math::Vector< T, 3 > const &c, float *bary=0)
Intersects the given ray with the given triangle and returns the 't' parameter of the intersection po...
bool point_box_overlap(math::Vector< T, N > const &point, math::Vector< T, N > const &aabb_min, math::Vector< T, N > const &aabb_max)
Returns true if the given point overlaps with the axis-aligned box.
T const & max(T const &a, T const &b, T const &c)
Returns the maximum value of three arguments.
T const & min(T const &a, T const &b, T const &c)
Returns the minimum value of three arguments.
T matrix_determinant(Matrix< T, N, N > const &mat)
Calculates the determinant of the given matrix.