OpenVDB 13.1.0
Loading...
Searching...
No Matches
Proximity.h
Go to the documentation of this file.
1// Copyright Contributors to the OpenVDB Project
2// SPDX-License-Identifier: Apache-2.0
3
4/*!
5 \file Proximity.h
6
7 \author Efty Sifakis
8
9 \brief Closest-point queries on geometric primitives,
10 suitable for use in both host and device code.
11*/
12
13#ifndef NANOVDB_MATH_PROXIMITY_H_HAS_BEEN_INCLUDED
14#define NANOVDB_MATH_PROXIMITY_H_HAS_BEEN_INCLUDED
15
16#include <nanovdb/util/Util.h> // for __hostdev__
17#include <nanovdb/math/Math.h> // for nanovdb::math::Sqrt
18
19namespace nanovdb {
20
21namespace math {
22
23/// @brief Returns the closest point on the line segment [v0,v1] to @a p.
24///
25/// The result lies on the closed segment (t clamped to [0,1]).
26///
27/// @tparam Vec3T Any Vec3 type supporting arithmetic and dot().
28template<typename Vec3T>
29__hostdev__ inline Vec3T
30closestPointOnSegmentToPoint(const Vec3T &v0, const Vec3T &v1, const Vec3T &p)
31{
32 const Vec3T seg = v1 - v0;
33 const Vec3T w = p - v0;
34
35 const auto c1 = seg.dot(w);
36 if (c1 <= 0) return v0;
37
38 const auto c2 = seg.dot(seg);
39 if (c2 <= c1) return v1;
40
41 return v0 + (c1 / c2) * seg;
42}
43
44/// @brief Returns the closest point on triangle [v0,v1,v2] to @a p,
45/// and (via @a t0, @a t1) the barycentric coordinates of that
46/// point: closest = v0 + t0*(v1-v0) + t1*(v2-v0).
47///
48/// Uses Voronoi-region decomposition (Ericson, "Real-Time Collision
49/// Detection", Sec. 5.1.5). Degenerate triangles (zero area, collinear or
50/// coincident vertices) are handled implicitly: the face-interior test
51/// naturally fails and the code falls through to the nearest edge or
52/// vertex result.
53///
54/// @tparam Vec3T Any Vec3 type supporting arithmetic and dot().
55template<typename Vec3T>
56__hostdev__ inline Vec3T
58 const Vec3T &v0,
59 const Vec3T &v1,
60 const Vec3T &v2,
61 const Vec3T &p,
62 typename Vec3T::ValueType &t0,
63 typename Vec3T::ValueType &t1)
64{
65 using RealT = typename Vec3T::ValueType;
66
67 const Vec3T ab = v1 - v0;
68 const Vec3T ac = v2 - v0;
69 const Vec3T ap = p - v0;
70
71 // --- Region A (vertex v0) ---
72 const RealT d1 = ab.dot(ap);
73 const RealT d2 = ac.dot(ap);
74 if (d1 <= RealT(0) && d2 <= RealT(0)) {
75 t0 = RealT(0);
76 t1 = RealT(0);
77 return v0;
78 }
79
80 // --- Region B (vertex v1) ---
81 const Vec3T bp = p - v1;
82 const RealT d3 = ab.dot(bp);
83 const RealT d4 = ac.dot(bp);
84 if (d3 >= RealT(0) && d4 <= d3) {
85 t0 = RealT(1);
86 t1 = RealT(0);
87 return v1;
88 }
89
90 // --- Region AB (edge v0-v1) ---
91 const RealT vc = d1 * d4 - d3 * d2;
92 if (vc <= RealT(0) && d1 >= RealT(0) && d3 <= RealT(0)) {
93 t0 = d1 / (d1 - d3);
94 t1 = RealT(0);
95 return v0 + t0 * ab;
96 }
97
98 // --- Region C (vertex v2) ---
99 const Vec3T cp = p - v2;
100 const RealT d5 = ab.dot(cp);
101 const RealT d6 = ac.dot(cp);
102 if (d6 >= RealT(0) && d5 <= d6) {
103 t0 = RealT(0);
104 t1 = RealT(1);
105 return v2;
106 }
107
108 // --- Region AC (edge v0-v2) ---
109 const RealT vb = d5 * d2 - d1 * d6;
110 if (vb <= RealT(0) && d2 >= RealT(0) && d6 <= RealT(0)) {
111 t1 = d2 / (d2 - d6);
112 t0 = RealT(0);
113 return v0 + t1 * ac;
114 }
115
116 // --- Region BC (edge v1-v2) ---
117 const RealT va = d3 * d6 - d5 * d4;
118 if (va <= RealT(0) && (d4 - d3) >= RealT(0) && (d5 - d6) >= RealT(0)) {
119 t1 = (d4 - d3) / ((d4 - d3) + (d5 - d6));
120 t0 = RealT(1) - t1;
121 return v1 + t1 * (v2 - v1);
122 }
123
124 // --- Interior of triangle ---
125 const RealT denom = RealT(1) / (va + vb + vc);
126 t0 = vb * denom;
127 t1 = vc * denom;
128 return v0 + t0 * ab + t1 * ac;
129}
130
131/// @brief Returns the squared distance from @a p to the closest point
132/// on triangle [v0,v1,v2].
133template<typename Vec3T>
134__hostdev__ inline typename Vec3T::ValueType
136 const Vec3T &v0,
137 const Vec3T &v1,
138 const Vec3T &v2,
139 const Vec3T &p)
140{
141 typename Vec3T::ValueType t0, t1;
142 const Vec3T closest = closestPointOnTriangleToPoint(v0, v1, v2, p, t0, t1);
143 return (p - closest).lengthSqr();
144}
145
146} // namespace math
147
148} // namespace nanovdb
149
150#endif // NANOVDB_MATH_PROXIMITY_H_HAS_BEEN_INCLUDED
#define __hostdev__
Definition SampleFromVoxels.h:29
Definition DitherLUT.h:19
__hostdev__ Vec3T closestPointOnTriangleToPoint(const Vec3T &v0, const Vec3T &v1, const Vec3T &v2, const Vec3T &p, typename Vec3T::ValueType &t0, typename Vec3T::ValueType &t1)
Returns the closest point on triangle [v0,v1,v2] to p, and (via t0, t1) the barycentric coordinates o...
Definition Proximity.h:57
__hostdev__ Vec3T closestPointOnSegmentToPoint(const Vec3T &v0, const Vec3T &v1, const Vec3T &p)
Returns the closest point on the line segment [v0,v1] to p.
Definition Proximity.h:30
__hostdev__ Vec3T::ValueType pointToTriangleDistSqr(const Vec3T &v0, const Vec3T &v1, const Vec3T &v2, const Vec3T &p)
Returns the squared distance from p to the closest point on triangle [v0,v1,v2].
Definition Proximity.h:135
Defines a simple memory pool used to call cub functions that use dynamic temporary storage.
Definition GridHandle.h:31
Math functions and classes.
Utility functions.