MeshLib
 
Loading...
Searching...
No Matches
MRTriangleIntersection.h
Go to the documentation of this file.
1#pragma once
2
3#include "MRVector3.h"
5#include "MRTriPoint.h"
6#include <optional>
7
8namespace MR
9{
10
14
16{
17 // barycentric representation
18 TriPointf bary;
19 // distance from ray origin to p in dir length units
20 float t = 0;
21 TriIntersectResult(float U, float V, float dist)
22 {
23 bary.a = U; bary.b = V; t = dist;
24 }
25};
26
29template <typename T>
33)
34{
35 const auto abcd = mixed( a - d, b - d, c - d );
36 const auto abce = mixed( a - e, b - e, c - e );
37 const auto abcf = mixed( a - f, b - f, c - f );
38 const auto abc_de = abcd * abce >= 0; // segment DE is located at one side of the plane ABC
39 const auto abc_fd = abcf * abcd >= 0; // segment FD is located at one side of the plane ABC
40
41 if ( abc_de && abc_fd && abce * abcf >= 0 )
42 return false; // triangle DEF is located at one side of the plane ABC
43
44 const auto defa = mixed( d - a, e - a, f - a );
45 const auto defb = mixed( d - b, e - b, f - b );
46 const auto defc = mixed( d - c, e - c, f - c );
47 const auto def_ab = defa * defb >= 0; // segment AB is located at one side of the plane DEF
48 const auto def_ca = defc * defa >= 0; // segment CA is located at one side of the plane DEF
49
50 if ( def_ab && def_ca && defb * defc >= 0 )
51 return false; // triangle ABC is located at one side of the plane DEF
52
53 if ( abc_de )
54 std::swap( d, f );
55 else if( abc_fd )
56 std::swap( d, e );
57 // now segments DE and FD are crossed by the plane ABC: D at one side and EF at the other
58
59 if ( def_ab )
60 std::swap( a, c );
61 else if ( def_ca )
62 std::swap( a, b );
63 // now segments AB and CA are crossed by the plane DEF: A at one side and BC at the other
64
65 const auto abde = mixed( a - e, b - e, d - e );
66 const auto abdf = mixed( a - f, b - f, d - f );
67
68 if ( abde * abdf < 0 )
69 return true; // AB segment penetrates triangle DEF since points E and F are at distinct sides of ABD
70
71 const auto acde = mixed( a - e, c - e, d - e );
72
73 if ( abde * acde < 0 )
74 return true; // DE segment penetrates triangle ABC since points B and C are at distinct sides of ADE
75
76 if ( abdf == 0 && acde == 0 )
77 return true; // AB and DF segments are in the same plane, and AC and DE segments are in other same plane => triangles intersect, but no edge intersect the interior of other triangle
78
79 const auto acdf = mixed( a - f, c - f, d - f );
80
81 if ( acde * acdf < 0 )
82 return true; // AC segment penetrates triangle DEF since points E and F are at distinct sides of ACD
83
84 if ( abdf * acdf < 0 )
85 return true; // DF segment penetrates triangle ABC since points B and C are at distinct sides of ADF
86
87 if ( abde == 0 && acdf == 0 )
88 return true; // AB and DE segments are in the same plane, and AC and DF segments are in other same plane => triangles intersect, but no edge intersect the interior of other triangle
89
90 return false;
91}
92
94template <typename T>
96 const Vector3<T> & x, const Vector3<T> & y, const Vector3<T> & z,
97 const Vector3<T> & u, const Vector3<T> & v, const Vector3<T> & w,
98 Vector3<T> d // approximate normal of the plane
99)
100{
101 const auto xy = ( y - x ).normalized();
102 d = ( d - xy * dot( xy, d ) ).normalized();
103 // now d is orthogonal to xy
104 const auto dz = dot( d, z - x );
105 return
106 dz * dot( d, u - x ) < 0 &&
107 dz * dot( d, v - x ) < 0 &&
108 dz * dot( d, w - x ) < 0;
109}
110
113template <typename T>
115 const Vector3<T> & a, const Vector3<T> & b, const Vector3<T> & c,
116 const Vector3<T> & d, const Vector3<T> & e, const Vector3<T> & f
117)
118{
119 if ( !doTrianglesIntersect( a, b, c, d, e, f ) )
120 return false;
121
122 // direction from center to center
123 const auto dir = a + b + c - d - e - f;
124
125 return
126 !doesEdgeXySeparate( a, b, c, d, e, f, dir ) &&
127 !doesEdgeXySeparate( b, c, a, d, e, f, dir ) &&
128 !doesEdgeXySeparate( c, a, b, d, e, f, dir ) &&
129 !doesEdgeXySeparate( d, e, f, a, b, c, dir ) &&
130 !doesEdgeXySeparate( e, f, d, a, b, c, dir ) &&
131 !doesEdgeXySeparate( f, d, e, a, b, c, dir );
132}
133
135template <typename T>
137 const Vector3<T> & a, const Vector3<T> & b, const Vector3<T> & c,
138 const Vector3<T> & d, const Vector3<T> & e
139)
140{
141 const auto dabe = mixed( d - e, a - e, b - e );
142 const auto dbce = mixed( d - e, b - e, c - e );
143 if ( dabe * dbce <= 0 )
144 return false; // segment AC is located at one side of the plane DEB
145
146 const auto dcae = mixed( d - e, c - e, a - e );
147 if ( dbce * dcae <= 0 )
148 return false; // segment AB is located at one side of the plane DEC
149
150 if ( dcae * dabe <= 0 )
151 return false; // segment BC is located at one side of the plane DEA
152
153 return true;
154}
155
157template <typename T>
159 const Vector3<T> & a, const Vector3<T> & b, const Vector3<T> & c,
160 const Vector3<T> & d, const Vector3<T> & e
161)
162{
163 const auto abcd = mixed( a - d, b - d, c - d );
164 const auto abce = mixed( a - e, b - e, c - e );
165 if ( abcd * abce >= 0 )
166 return false; // segment DE is located at one side of the plane ABC
167 return doTriangleLineIntersect( a, b, c, d, e );
168}
169
171template <typename T>
173 const Vector3<T>& a, const Vector3<T>& b, const Vector3<T>& c,
174 const Vector3<T>& d, const Vector3<T>& e
175)
176{
177 const auto abcd = std::abs( mixed( a - d, b - d, c - d ) );
178 const auto abce = std::abs( mixed( a - e, b - e, c - e ) );
179 auto r = std::clamp( abcd / ( abcd + abce ), T( 0 ), T( 1 ) );
180 return r * e + ( 1 - r ) * d;
181}
182
183template <typename T>
184std::optional<TriIntersectResult> rayTriangleIntersect_( const Vector3<T>& oriA, const Vector3<T>& oriB, const Vector3<T>& oriC,
185 const IntersectionPrecomputes<T>& prec )
186{
187 const T& Sx = prec.Sx;
188 const T& Sy = prec.Sy;
189 const T& Sz = prec.Sz;
190
191 const T Ax = oriA[prec.idxX] - Sx * oriA[prec.maxDimIdxZ];
192 const T Ay = oriA[prec.idxY] - Sy * oriA[prec.maxDimIdxZ];
193 const T Bx = oriB[prec.idxX] - Sx * oriB[prec.maxDimIdxZ];
194 const T By = oriB[prec.idxY] - Sy * oriB[prec.maxDimIdxZ];
195 const T Cx = oriC[prec.idxX] - Sx * oriC[prec.maxDimIdxZ];
196 const T Cy = oriC[prec.idxY] - Sy * oriC[prec.maxDimIdxZ];
197
198 // due to fused multiply-add (FMA): (A*B-A*B) can be different from zero, so we need epsilon
199 const T eps = std::numeric_limits<T>::epsilon() * std::max( { Ax, Bx, Cx, Ay, By, Cy } );
200 T U = Cx * By - Cy * Bx;
201 T V = Ax * Cy - Ay * Cx;
202 T W = Bx * Ay - By * Ax;
203
204 if( U < -eps || V < -eps || W < -eps )
205 {
206 if( U > eps || V > eps || W > eps )
207 {
208 // U,V,W have clearly different signs, so the ray misses the triangle
209 return std::nullopt;
210 }
211 }
212
213 T det = U + V + W;
214 if( det == T( 0 ) )
215 return std::nullopt;
216 const T Az = Sz * oriA[prec.maxDimIdxZ];
217 const T Bz = Sz * oriB[prec.maxDimIdxZ];
218 const T Cz = Sz * oriC[prec.maxDimIdxZ];
219 const T t = U * Az + V * Bz + W * Cz;
220
221 auto invDet = T( 1 ) / det;
222 return TriIntersectResult( float( V * invDet ), float( W * invDet ), float( t * invDet ) );
223}
224
225inline std::optional<TriIntersectResult> rayTriangleIntersect( const Vector3f& oriA, const Vector3f& oriB, const Vector3f& oriC,
227{
228 return rayTriangleIntersect_( oriA, oriB, oriC, prec );
229}
230inline std::optional<TriIntersectResult> rayTriangleIntersect( const Vector3f& oriA, const Vector3f& oriB, const Vector3f& oriC,
231 const Vector3f& dir )
232{
233 const IntersectionPrecomputes<float> prec( dir );
234 return rayTriangleIntersect_( oriA, oriB, oriC, prec );
235}
236
237inline std::optional<TriIntersectResult> rayTriangleIntersect( const Vector3d& oriA, const Vector3d& oriB, const Vector3d& oriC,
239{
240 return rayTriangleIntersect_( oriA, oriB, oriC, prec );
241}
242
243inline std::optional<TriIntersectResult> rayTriangleIntersect( const Vector3d& oriA, const Vector3d& oriB, const Vector3d& oriC,
244 const Vector3d& dir )
245{
246 const IntersectionPrecomputes<double> prec( dir );
247 return rayTriangleIntersect_( oriA, oriB, oriC, prec );
248}
249
251
252} // namespace MR
represents a 3-dimentional float-typed vector
Definition MRDotNet/MRVector3.h:8
int idxY
Definition MRIntersectionPrecomputes.h:123
T Sx
precomputed factors
Definition MRIntersectionPrecomputes.h:129
int idxX
Definition MRIntersectionPrecomputes.h:122
T Sz
Definition MRIntersectionPrecomputes.h:129
T Sy
Definition MRIntersectionPrecomputes.h:129
int maxDimIdxZ
Definition MRIntersectionPrecomputes.h:121
MRMESH_API TriangleSegmentIntersectResult doTriangleSegmentIntersect(const std::array< PreciseVertCoords, 5 > &vs)
bool doTrianglesIntersect(Vector3< T > a, Vector3< T > b, Vector3< T > c, Vector3< T > d, Vector3< T > e, Vector3< T > f)
Definition MRTriangleIntersection.h:30
bool doesEdgeXySeparate(const Vector3< T > &x, const Vector3< T > &y, const Vector3< T > &z, const Vector3< T > &u, const Vector3< T > &v, const Vector3< T > &w, Vector3< T > d)
returns true if a plane containing edge XY separates point Z from triangle UVW
Definition MRTriangleIntersection.h:95
std::optional< TriIntersectResult > rayTriangleIntersect(const Vector3f &oriA, const Vector3f &oriB, const Vector3f &oriC, const IntersectionPrecomputes< float > &prec)
Definition MRTriangleIntersection.h:225
std::optional< TriIntersectResult > rayTriangleIntersect_(const Vector3< T > &oriA, const Vector3< T > &oriB, const Vector3< T > &oriC, const IntersectionPrecomputes< T > &prec)
Definition MRTriangleIntersection.h:184
bool doTriangleLineIntersect(const Vector3< T > &a, const Vector3< T > &b, const Vector3< T > &c, const Vector3< T > &d, const Vector3< T > &e)
checks whether triangle ABC and infinite line DE intersect
Definition MRTriangleIntersection.h:136
Vector3< T > findTriangleSegmentIntersection(const Vector3< T > &a, const Vector3< T > &b, const Vector3< T > &c, const Vector3< T > &d, const Vector3< T > &e)
this function input should have intersection
Definition MRTriangleIntersection.h:172
bool doTrianglesIntersectExt(const Vector3< T > &a, const Vector3< T > &b, const Vector3< T > &c, const Vector3< T > &d, const Vector3< T > &e, const Vector3< T > &f)
Definition MRTriangleIntersection.h:114
Definition MRCameraOrientationPlugin.h:7
Definition MRMesh/MRMeshFwd.h:364
Definition MRTriangleIntersection.h:16
TriIntersectResult(float U, float V, float dist)
Definition MRTriangleIntersection.h:21
float t
Definition MRTriangleIntersection.h:20
TriPointf bary
Definition MRTriangleIntersection.h:18
Definition MRMesh/MRVector3.h:19