Skip to content
Snippets Groups Projects
Commit d94974c1 authored by Thomas Müller's avatar Thomas Müller
Browse files

Simplification of Triangle/BoundingBox code

parent e7d1e404
No related branches found
No related tags found
No related merge requests found
...@@ -29,8 +29,14 @@ NGP_HOST_DEVICE inline void project(Eigen::Vector3f points[N_POINTS], const Eige ...@@ -29,8 +29,14 @@ NGP_HOST_DEVICE inline void project(Eigen::Vector3f points[N_POINTS], const Eige
NGP_PRAGMA_UNROLL NGP_PRAGMA_UNROLL
for (uint32_t i = 0; i < N_POINTS; ++i) { for (uint32_t i = 0; i < N_POINTS; ++i) {
float val = axis.dot(points[i]); float val = axis.dot(points[i]);
if (val < min) min = val;
if (val > max) max = val; if (val < min) {
min = val;
}
if (val > max) {
max = val;
}
} }
} }
...@@ -39,14 +45,12 @@ struct BoundingBox { ...@@ -39,14 +45,12 @@ struct BoundingBox {
NGP_HOST_DEVICE BoundingBox(const Eigen::Vector3f& a, const Eigen::Vector3f& b) : min{a}, max{b} {} NGP_HOST_DEVICE BoundingBox(const Eigen::Vector3f& a, const Eigen::Vector3f& b) : min{a}, max{b} {}
// From triangle
NGP_HOST_DEVICE explicit BoundingBox(const Triangle& tri) { NGP_HOST_DEVICE explicit BoundingBox(const Triangle& tri) {
min = max = tri.a; min = max = tri.a;
enlarge(tri.b); enlarge(tri.b);
enlarge(tri.c); enlarge(tri.c);
} }
// From iterators
BoundingBox(std::vector<Triangle>::iterator begin, std::vector<Triangle>::iterator end) { BoundingBox(std::vector<Triangle>::iterator begin, std::vector<Triangle>::iterator end) {
min = max = begin->a; min = max = begin->a;
for (auto it = begin; it != end; ++it) { for (auto it = begin; it != end; ++it) {
...@@ -98,10 +102,6 @@ struct BoundingBox { ...@@ -98,10 +102,6 @@ struct BoundingBox {
return !intersection(other).is_empty(); return !intersection(other).is_empty();
} }
// NGP_HOST_DEVICE bool intersects(const Triangle& triangle) const {
// return !intersection(BoundingBox{triangle}).is_empty();
// }
// Based on the separating axis theorem // Based on the separating axis theorem
// (https://fileadmin.cs.lth.se/cs/Personal/Tomas_Akenine-Moller/code/tribox_tam.pdf) // (https://fileadmin.cs.lth.se/cs/Personal/Tomas_Akenine-Moller/code/tribox_tam.pdf)
// Code adapted from a C# implementation at stack overflow // Code adapted from a C# implementation at stack overflow
...@@ -123,8 +123,9 @@ struct BoundingBox { ...@@ -123,8 +123,9 @@ struct BoundingBox {
for (int i = 0; i < 3; i++) { for (int i = 0; i < 3; i++) {
project<3>(triangle_verts, box_normals[i], triangle_min, triangle_max); project<3>(triangle_verts, box_normals[i], triangle_min, triangle_max);
if (triangle_max < min[i] || triangle_min > max[i]) if (triangle_max < min[i] || triangle_min > max[i]) {
return false; // No intersection possible. return false; // No intersection possible.
}
} }
Eigen::Vector3f verts[8]; Eigen::Vector3f verts[8];
...@@ -163,15 +164,20 @@ struct BoundingBox { ...@@ -163,15 +164,20 @@ struct BoundingBox {
float tmin = (min.x() - pos.x()) / dir.x(); float tmin = (min.x() - pos.x()) / dir.x();
float tmax = (max.x() - pos.x()) / dir.x(); float tmax = (max.x() - pos.x()) / dir.x();
if (tmin > tmax) tcnn::host_device_swap(tmin, tmax); if (tmin > tmax) {
tcnn::host_device_swap(tmin, tmax);
}
float tymin = (min.y() - pos.y()) / dir.y(); float tymin = (min.y() - pos.y()) / dir.y();
float tymax = (max.y() - pos.y()) / dir.y(); float tymax = (max.y() - pos.y()) / dir.y();
if (tymin > tymax) tcnn::host_device_swap(tymin, tymax); if (tymin > tymax) {
tcnn::host_device_swap(tymin, tymax);
}
if ((tmin > tymax) || (tymin > tmax)) if (tmin > tymax || tymin > tmax) {
return { 100000.0f, 100000.0f }; return { std::numeric_limits<float>::max(), std::numeric_limits<float>::max() };
}
if (tymin > tmin) if (tymin > tmin)
tmin = tymin; tmin = tymin;
...@@ -182,16 +188,21 @@ struct BoundingBox { ...@@ -182,16 +188,21 @@ struct BoundingBox {
float tzmin = (min.z() - pos.z()) / dir.z(); float tzmin = (min.z() - pos.z()) / dir.z();
float tzmax = (max.z() - pos.z()) / dir.z(); float tzmax = (max.z() - pos.z()) / dir.z();
if (tzmin > tzmax) tcnn::host_device_swap(tzmin, tzmax); if (tzmin > tzmax) {
tcnn::host_device_swap(tzmin, tzmax);
}
if ((tmin > tzmax) || (tzmin > tmax)) if (tmin > tzmax || tzmin > tmax) {
return { 100000.0f, 100000.0f }; return { std::numeric_limits<float>::max(), std::numeric_limits<float>::max() };
}
if (tzmin > tmin) if (tzmin > tmin) {
tmin = tzmin; tmin = tzmin;
}
if (tzmax < tmax) if (tzmax < tmax) {
tmax = tzmax; tmax = tzmax;
}
return { tmin, tmax }; return { tmin, tmax };
} }
......
...@@ -40,18 +40,21 @@ struct Triangle { ...@@ -40,18 +40,21 @@ struct Triangle {
return (b - a).cross(c - a).normalized(); return (b - a).cross(c - a).normalized();
} }
NGP_HOST_DEVICE float ray_intersect(const Eigen::Vector3f &ro, const Eigen::Vector3f &rd, Eigen::Vector3f& n) const { // based on https://www.iquilezles.org/www/articles/intersectors/intersectors.htm // based on https://www.iquilezles.org/www/articles/intersectors/intersectors.htm
NGP_HOST_DEVICE float ray_intersect(const Eigen::Vector3f &ro, const Eigen::Vector3f &rd, Eigen::Vector3f& n) const {
Eigen::Vector3f v1v0 = b - a; Eigen::Vector3f v1v0 = b - a;
Eigen::Vector3f v2v0 = c - a; Eigen::Vector3f v2v0 = c - a;
Eigen::Vector3f rov0 = ro - a; Eigen::Vector3f rov0 = ro - a;
n = v1v0.cross( v2v0 ); n = v1v0.cross(v2v0);
Eigen::Vector3f q = rov0.cross( rd ); Eigen::Vector3f q = rov0.cross(rd);
float d = 1.0f/rd.dot( n ); float d = 1.0f / rd.dot(n);
float u = d*-q.dot( v2v0 ); float u = d * -q.dot(v2v0);
float v = d* q.dot( v1v0 ); float v = d * q.dot(v1v0);
float t = d*-n.dot( rov0 ); float t = d * -n.dot(rov0);
if( u<0.0f || u>1.0f || v<0.0f || (u+v)>1.0f || t<0.0f) t = 1e6f; if (u < 0.0f || u > 1.0f || v < 0.0f || (u+v) > 1.0f || t < 0.0f) {
return t; // Eigen::Vector3f( t, u, v ); t = std::numeric_limits<float>::max(); // No intersection
}
return t;
} }
NGP_HOST_DEVICE float ray_intersect(const Eigen::Vector3f &ro, const Eigen::Vector3f &rd) const { NGP_HOST_DEVICE float ray_intersect(const Eigen::Vector3f &ro, const Eigen::Vector3f &rd) const {
...@@ -59,8 +62,8 @@ struct Triangle { ...@@ -59,8 +62,8 @@ struct Triangle {
return ray_intersect(ro, rd, n); return ray_intersect(ro, rd, n);
} }
// based on https://www.iquilezles.org/www/articles/distfunctions/distfunctions.htm
NGP_HOST_DEVICE float distance_sq(const Eigen::Vector3f& pos) const { NGP_HOST_DEVICE float distance_sq(const Eigen::Vector3f& pos) const {
// prepare data
Eigen::Vector3f v21 = b - a; Eigen::Vector3f p1 = pos - a; Eigen::Vector3f v21 = b - a; Eigen::Vector3f p1 = pos - a;
Eigen::Vector3f v32 = c - b; Eigen::Vector3f p2 = pos - b; Eigen::Vector3f v32 = c - b; Eigen::Vector3f p2 = pos - b;
Eigen::Vector3f v13 = a - c; Eigen::Vector3f p3 = pos - c; Eigen::Vector3f v13 = a - c; Eigen::Vector3f p3 = pos - c;
...@@ -71,13 +74,11 @@ struct Triangle { ...@@ -71,13 +74,11 @@ struct Triangle {
(sign(v21.cross(nor).dot(p1)) + sign(v32.cross(nor).dot(p2)) + sign(v13.cross(nor).dot(p3)) < 2.0f) (sign(v21.cross(nor).dot(p1)) + sign(v32.cross(nor).dot(p2)) + sign(v13.cross(nor).dot(p3)) < 2.0f)
? ?
// 3 edges // 3 edges
std::min( std::min({
std::min( (v21 * tcnn::clamp(v21.dot(p1) / v21.squaredNorm(), 0.0f, 1.0f)-p1).squaredNorm(),
(v21 * tcnn::clamp(v21.dot(p1) / v21.squaredNorm(), 0.0f, 1.0f)-p1).squaredNorm(), (v32 * tcnn::clamp(v32.dot(p2) / v32.squaredNorm(), 0.0f, 1.0f)-p2).squaredNorm(),
(v32 * tcnn::clamp(v32.dot(p2) / v32.squaredNorm(), 0.0f, 1.0f)-p2).squaredNorm() (v13 * tcnn::clamp(v13.dot(p3) / v13.squaredNorm(), 0.0f, 1.0f)-p3).squaredNorm(),
), })
(v13 * tcnn::clamp(v13.dot(p3) / v13.squaredNorm(), 0.0f, 1.0f)-p3).squaredNorm()
)
: :
// 1 face // 1 face
nor.dot(p1)*nor.dot(p1)/nor.squaredNorm(); nor.dot(p1)*nor.dot(p1)/nor.squaredNorm();
...@@ -108,17 +109,9 @@ struct Triangle { ...@@ -108,17 +109,9 @@ struct Triangle {
Eigen::Vector3f v = local_c.cross(local_a); Eigen::Vector3f v = local_c.cross(local_a);
Eigen::Vector3f w = local_a.cross(local_b); Eigen::Vector3f w = local_a.cross(local_b);
// Test to see if the normals are facing // Test to see if the normals are facing the same direction.
// the same direction, return false if not // If yes, the point is inside, otherwise it isn't.
if (u.dot(v) < 0.0f) { return u.dot(v) >= 0.0f && u.dot(w) >= 0.0f;
return false;
}
if (u.dot(w) < 0.0f) {
return false;
}
// All normals facing the same way, return true
return true;
} }
NGP_HOST_DEVICE Eigen::Vector3f closest_point_to_line(const Eigen::Vector3f& a, const Eigen::Vector3f& b, const Eigen::Vector3f& c) const { NGP_HOST_DEVICE Eigen::Vector3f closest_point_to_line(const Eigen::Vector3f& a, const Eigen::Vector3f& b, const Eigen::Vector3f& c) const {
...@@ -142,16 +135,15 @@ struct Triangle { ...@@ -142,16 +135,15 @@ struct Triangle {
float mag2 = (point - c2).squaredNorm(); float mag2 = (point - c2).squaredNorm();
float mag3 = (point - c3).squaredNorm(); float mag3 = (point - c3).squaredNorm();
float min = std::min(mag1, mag2); float min = std::min({mag1, mag2, mag3});
min = std::min(min, mag3);
if (min == mag1) { if (min == mag1) {
return c1; return c1;
} } else if (min == mag2) {
else if (min == mag2) {
return c2; return c2;
} else {
return c3;
} }
return c3;
} }
NGP_HOST_DEVICE Eigen::Vector3f centroid() const { NGP_HOST_DEVICE Eigen::Vector3f centroid() const {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment