diff options
Diffstat (limited to 'libraries/ode-0.9/OPCODE/OPC_LSSTriOverlap.h')
-rw-r--r-- | libraries/ode-0.9/OPCODE/OPC_LSSTriOverlap.h | 679 |
1 files changed, 0 insertions, 679 deletions
diff --git a/libraries/ode-0.9/OPCODE/OPC_LSSTriOverlap.h b/libraries/ode-0.9/OPCODE/OPC_LSSTriOverlap.h deleted file mode 100644 index f1d17e4..0000000 --- a/libraries/ode-0.9/OPCODE/OPC_LSSTriOverlap.h +++ /dev/null | |||
@@ -1,679 +0,0 @@ | |||
1 | // Following code from Magic-Software (http://www.magic-software.com/) | ||
2 | // A bit modified for Opcode | ||
3 | |||
4 | static const float gs_fTolerance = 1e-05f; | ||
5 | |||
6 | static float OPC_PointTriangleSqrDist(const Point& point, const Point& p0, const Point& p1, const Point& p2) | ||
7 | { | ||
8 | // Hook | ||
9 | Point TriEdge0 = p1 - p0; | ||
10 | Point TriEdge1 = p2 - p0; | ||
11 | |||
12 | Point kDiff = p0 - point; | ||
13 | float fA00 = TriEdge0.SquareMagnitude(); | ||
14 | float fA01 = TriEdge0 | TriEdge1; | ||
15 | float fA11 = TriEdge1.SquareMagnitude(); | ||
16 | float fB0 = kDiff | TriEdge0; | ||
17 | float fB1 = kDiff | TriEdge1; | ||
18 | float fC = kDiff.SquareMagnitude(); | ||
19 | float fDet = fabsf(fA00*fA11 - fA01*fA01); | ||
20 | float fS = fA01*fB1-fA11*fB0; | ||
21 | float fT = fA01*fB0-fA00*fB1; | ||
22 | float fSqrDist; | ||
23 | |||
24 | if(fS + fT <= fDet) | ||
25 | { | ||
26 | if(fS < 0.0f) | ||
27 | { | ||
28 | if(fT < 0.0f) // region 4 | ||
29 | { | ||
30 | if(fB0 < 0.0f) | ||
31 | { | ||
32 | if(-fB0 >= fA00) fSqrDist = fA00+2.0f*fB0+fC; | ||
33 | else fSqrDist = fB0*(-fB0/fA00)+fC; | ||
34 | } | ||
35 | else | ||
36 | { | ||
37 | if(fB1 >= 0.0f) fSqrDist = fC; | ||
38 | else if(-fB1 >= fA11) fSqrDist = fA11+2.0f*fB1+fC; | ||
39 | else fSqrDist = fB1*(-fB1/fA11)+fC; | ||
40 | } | ||
41 | } | ||
42 | else // region 3 | ||
43 | { | ||
44 | if(fB1 >= 0.0f) fSqrDist = fC; | ||
45 | else if(-fB1 >= fA11) fSqrDist = fA11+2.0f*fB1+fC; | ||
46 | else fSqrDist = fB1*(-fB1/fA11)+fC; | ||
47 | } | ||
48 | } | ||
49 | else if(fT < 0.0f) // region 5 | ||
50 | { | ||
51 | if(fB0 >= 0.0f) fSqrDist = fC; | ||
52 | else if(-fB0 >= fA00) fSqrDist = fA00+2.0f*fB0+fC; | ||
53 | else fSqrDist = fB0*(-fB0/fA00)+fC; | ||
54 | } | ||
55 | else // region 0 | ||
56 | { | ||
57 | // minimum at interior point | ||
58 | if(fDet==0.0f) | ||
59 | { | ||
60 | fSqrDist = MAX_FLOAT; | ||
61 | } | ||
62 | else | ||
63 | { | ||
64 | float fInvDet = 1.0f/fDet; | ||
65 | fS *= fInvDet; | ||
66 | fT *= fInvDet; | ||
67 | fSqrDist = fS*(fA00*fS+fA01*fT+2.0f*fB0) + fT*(fA01*fS+fA11*fT+2.0f*fB1)+fC; | ||
68 | } | ||
69 | } | ||
70 | } | ||
71 | else | ||
72 | { | ||
73 | float fTmp0, fTmp1, fNumer, fDenom; | ||
74 | |||
75 | if(fS < 0.0f) // region 2 | ||
76 | { | ||
77 | fTmp0 = fA01 + fB0; | ||
78 | fTmp1 = fA11 + fB1; | ||
79 | if(fTmp1 > fTmp0) | ||
80 | { | ||
81 | fNumer = fTmp1 - fTmp0; | ||
82 | fDenom = fA00-2.0f*fA01+fA11; | ||
83 | if(fNumer >= fDenom) | ||
84 | { | ||
85 | fSqrDist = fA00+2.0f*fB0+fC; | ||
86 | } | ||
87 | else | ||
88 | { | ||
89 | fS = fNumer/fDenom; | ||
90 | fT = 1.0f - fS; | ||
91 | fSqrDist = fS*(fA00*fS+fA01*fT+2.0f*fB0) + fT*(fA01*fS+fA11*fT+2.0f*fB1)+fC; | ||
92 | } | ||
93 | } | ||
94 | else | ||
95 | { | ||
96 | if(fTmp1 <= 0.0f) fSqrDist = fA11+2.0f*fB1+fC; | ||
97 | else if(fB1 >= 0.0f) fSqrDist = fC; | ||
98 | else fSqrDist = fB1*(-fB1/fA11)+fC; | ||
99 | } | ||
100 | } | ||
101 | else if(fT < 0.0f) // region 6 | ||
102 | { | ||
103 | fTmp0 = fA01 + fB1; | ||
104 | fTmp1 = fA00 + fB0; | ||
105 | if(fTmp1 > fTmp0) | ||
106 | { | ||
107 | fNumer = fTmp1 - fTmp0; | ||
108 | fDenom = fA00-2.0f*fA01+fA11; | ||
109 | if(fNumer >= fDenom) | ||
110 | { | ||
111 | fSqrDist = fA11+2.0f*fB1+fC; | ||
112 | } | ||
113 | else | ||
114 | { | ||
115 | fT = fNumer/fDenom; | ||
116 | fS = 1.0f - fT; | ||
117 | fSqrDist = fS*(fA00*fS+fA01*fT+2.0f*fB0) + fT*(fA01*fS+fA11*fT+2.0f*fB1)+fC; | ||
118 | } | ||
119 | } | ||
120 | else | ||
121 | { | ||
122 | if(fTmp1 <= 0.0f) fSqrDist = fA00+2.0f*fB0+fC; | ||
123 | else if(fB0 >= 0.0f) fSqrDist = fC; | ||
124 | else fSqrDist = fB0*(-fB0/fA00)+fC; | ||
125 | } | ||
126 | } | ||
127 | else // region 1 | ||
128 | { | ||
129 | fNumer = fA11 + fB1 - fA01 - fB0; | ||
130 | if(fNumer <= 0.0f) | ||
131 | { | ||
132 | fSqrDist = fA11+2.0f*fB1+fC; | ||
133 | } | ||
134 | else | ||
135 | { | ||
136 | fDenom = fA00-2.0f*fA01+fA11; | ||
137 | if(fNumer >= fDenom) | ||
138 | { | ||
139 | fSqrDist = fA00+2.0f*fB0+fC; | ||
140 | } | ||
141 | else | ||
142 | { | ||
143 | fS = fNumer/fDenom; | ||
144 | fT = 1.0f - fS; | ||
145 | fSqrDist = fS*(fA00*fS+fA01*fT+2.0f*fB0) + fT*(fA01*fS+fA11*fT+2.0f*fB1)+fC; | ||
146 | } | ||
147 | } | ||
148 | } | ||
149 | } | ||
150 | return fabsf(fSqrDist); | ||
151 | } | ||
152 | |||
153 | static float OPC_SegmentSegmentSqrDist(const Segment& rkSeg0, const Segment& rkSeg1) | ||
154 | { | ||
155 | // Hook | ||
156 | Point rkSeg0Direction = rkSeg0.ComputeDirection(); | ||
157 | Point rkSeg1Direction = rkSeg1.ComputeDirection(); | ||
158 | |||
159 | Point kDiff = rkSeg0.mP0 - rkSeg1.mP0; | ||
160 | float fA00 = rkSeg0Direction.SquareMagnitude(); | ||
161 | float fA01 = -rkSeg0Direction.Dot(rkSeg1Direction); | ||
162 | float fA11 = rkSeg1Direction.SquareMagnitude(); | ||
163 | float fB0 = kDiff.Dot(rkSeg0Direction); | ||
164 | float fC = kDiff.SquareMagnitude(); | ||
165 | float fDet = fabsf(fA00*fA11-fA01*fA01); | ||
166 | |||
167 | float fB1, fS, fT, fSqrDist, fTmp; | ||
168 | |||
169 | if(fDet>=gs_fTolerance) | ||
170 | { | ||
171 | // line segments are not parallel | ||
172 | fB1 = -kDiff.Dot(rkSeg1Direction); | ||
173 | fS = fA01*fB1-fA11*fB0; | ||
174 | fT = fA01*fB0-fA00*fB1; | ||
175 | |||
176 | if(fS >= 0.0f) | ||
177 | { | ||
178 | if(fS <= fDet) | ||
179 | { | ||
180 | if(fT >= 0.0f) | ||
181 | { | ||
182 | if(fT <= fDet) // region 0 (interior) | ||
183 | { | ||
184 | // minimum at two interior points of 3D lines | ||
185 | float fInvDet = 1.0f/fDet; | ||
186 | fS *= fInvDet; | ||
187 | fT *= fInvDet; | ||
188 | fSqrDist = fS*(fA00*fS+fA01*fT+2.0f*fB0) + fT*(fA01*fS+fA11*fT+2.0f*fB1)+fC; | ||
189 | } | ||
190 | else // region 3 (side) | ||
191 | { | ||
192 | fTmp = fA01+fB0; | ||
193 | if(fTmp>=0.0f) fSqrDist = fA11+2.0f*fB1+fC; | ||
194 | else if(-fTmp>=fA00) fSqrDist = fA00+fA11+fC+2.0f*(fB1+fTmp); | ||
195 | else fSqrDist = fTmp*(-fTmp/fA00)+fA11+2.0f*fB1+fC; | ||
196 | } | ||
197 | } | ||
198 | else // region 7 (side) | ||
199 | { | ||
200 | if(fB0>=0.0f) fSqrDist = fC; | ||
201 | else if(-fB0>=fA00) fSqrDist = fA00+2.0f*fB0+fC; | ||
202 | else fSqrDist = fB0*(-fB0/fA00)+fC; | ||
203 | } | ||
204 | } | ||
205 | else | ||
206 | { | ||
207 | if ( fT >= 0.0 ) | ||
208 | { | ||
209 | if ( fT <= fDet ) // region 1 (side) | ||
210 | { | ||
211 | fTmp = fA01+fB1; | ||
212 | if(fTmp>=0.0f) fSqrDist = fA00+2.0f*fB0+fC; | ||
213 | else if(-fTmp>=fA11) fSqrDist = fA00+fA11+fC+2.0f*(fB0+fTmp); | ||
214 | else fSqrDist = fTmp*(-fTmp/fA11)+fA00+2.0f*fB0+fC; | ||
215 | } | ||
216 | else // region 2 (corner) | ||
217 | { | ||
218 | fTmp = fA01+fB0; | ||
219 | if ( -fTmp <= fA00 ) | ||
220 | { | ||
221 | if(fTmp>=0.0f) fSqrDist = fA11+2.0f*fB1+fC; | ||
222 | else fSqrDist = fTmp*(-fTmp/fA00)+fA11+2.0f*fB1+fC; | ||
223 | } | ||
224 | else | ||
225 | { | ||
226 | fTmp = fA01+fB1; | ||
227 | if(fTmp>=0.0f) fSqrDist = fA00+2.0f*fB0+fC; | ||
228 | else if(-fTmp>=fA11) fSqrDist = fA00+fA11+fC+2.0f*(fB0+fTmp); | ||
229 | else fSqrDist = fTmp*(-fTmp/fA11)+fA00+2.0f*fB0+fC; | ||
230 | } | ||
231 | } | ||
232 | } | ||
233 | else // region 8 (corner) | ||
234 | { | ||
235 | if ( -fB0 < fA00 ) | ||
236 | { | ||
237 | if(fB0>=0.0f) fSqrDist = fC; | ||
238 | else fSqrDist = fB0*(-fB0/fA00)+fC; | ||
239 | } | ||
240 | else | ||
241 | { | ||
242 | fTmp = fA01+fB1; | ||
243 | if(fTmp>=0.0f) fSqrDist = fA00+2.0f*fB0+fC; | ||
244 | else if(-fTmp>=fA11) fSqrDist = fA00+fA11+fC+2.0f*(fB0+fTmp); | ||
245 | else fSqrDist = fTmp*(-fTmp/fA11)+fA00+2.0f*fB0+fC; | ||
246 | } | ||
247 | } | ||
248 | } | ||
249 | } | ||
250 | else | ||
251 | { | ||
252 | if ( fT >= 0.0f ) | ||
253 | { | ||
254 | if ( fT <= fDet ) // region 5 (side) | ||
255 | { | ||
256 | if(fB1>=0.0f) fSqrDist = fC; | ||
257 | else if(-fB1>=fA11) fSqrDist = fA11+2.0f*fB1+fC; | ||
258 | else fSqrDist = fB1*(-fB1/fA11)+fC; | ||
259 | } | ||
260 | else // region 4 (corner) | ||
261 | { | ||
262 | fTmp = fA01+fB0; | ||
263 | if ( fTmp < 0.0f ) | ||
264 | { | ||
265 | if(-fTmp>=fA00) fSqrDist = fA00+fA11+fC+2.0f*(fB1+fTmp); | ||
266 | else fSqrDist = fTmp*(-fTmp/fA00)+fA11+2.0f*fB1+fC; | ||
267 | } | ||
268 | else | ||
269 | { | ||
270 | if(fB1>=0.0f) fSqrDist = fC; | ||
271 | else if(-fB1>=fA11) fSqrDist = fA11+2.0f*fB1+fC; | ||
272 | else fSqrDist = fB1*(-fB1/fA11)+fC; | ||
273 | } | ||
274 | } | ||
275 | } | ||
276 | else // region 6 (corner) | ||
277 | { | ||
278 | if ( fB0 < 0.0f ) | ||
279 | { | ||
280 | if(-fB0>=fA00) fSqrDist = fA00+2.0f*fB0+fC; | ||
281 | else fSqrDist = fB0*(-fB0/fA00)+fC; | ||
282 | } | ||
283 | else | ||
284 | { | ||
285 | if(fB1>=0.0f) fSqrDist = fC; | ||
286 | else if(-fB1>=fA11) fSqrDist = fA11+2.0f*fB1+fC; | ||
287 | else fSqrDist = fB1*(-fB1/fA11)+fC; | ||
288 | } | ||
289 | } | ||
290 | } | ||
291 | } | ||
292 | else | ||
293 | { | ||
294 | // line segments are parallel | ||
295 | if ( fA01 > 0.0f ) | ||
296 | { | ||
297 | // direction vectors form an obtuse angle | ||
298 | if ( fB0 >= 0.0f ) | ||
299 | { | ||
300 | fSqrDist = fC; | ||
301 | } | ||
302 | else if ( -fB0 <= fA00 ) | ||
303 | { | ||
304 | fSqrDist = fB0*(-fB0/fA00)+fC; | ||
305 | } | ||
306 | else | ||
307 | { | ||
308 | fB1 = -kDiff.Dot(rkSeg1Direction); | ||
309 | fTmp = fA00+fB0; | ||
310 | if ( -fTmp >= fA01 ) | ||
311 | { | ||
312 | fSqrDist = fA00+fA11+fC+2.0f*(fA01+fB0+fB1); | ||
313 | } | ||
314 | else | ||
315 | { | ||
316 | fT = -fTmp/fA01; | ||
317 | fSqrDist = fA00+2.0f*fB0+fC+fT*(fA11*fT+2.0f*(fA01+fB1)); | ||
318 | } | ||
319 | } | ||
320 | } | ||
321 | else | ||
322 | { | ||
323 | // direction vectors form an acute angle | ||
324 | if ( -fB0 >= fA00 ) | ||
325 | { | ||
326 | fSqrDist = fA00+2.0f*fB0+fC; | ||
327 | } | ||
328 | else if ( fB0 <= 0.0f ) | ||
329 | { | ||
330 | fSqrDist = fB0*(-fB0/fA00)+fC; | ||
331 | } | ||
332 | else | ||
333 | { | ||
334 | fB1 = -kDiff.Dot(rkSeg1Direction); | ||
335 | if ( fB0 >= -fA01 ) | ||
336 | { | ||
337 | fSqrDist = fA11+2.0f*fB1+fC; | ||
338 | } | ||
339 | else | ||
340 | { | ||
341 | fT = -fB0/fA01; | ||
342 | fSqrDist = fC+fT*(2.0f*fB1+fA11*fT); | ||
343 | } | ||
344 | } | ||
345 | } | ||
346 | } | ||
347 | return fabsf(fSqrDist); | ||
348 | } | ||
349 | |||
350 | inline_ float OPC_SegmentRaySqrDist(const Segment& rkSeg0, const Ray& rkSeg1) | ||
351 | { | ||
352 | return OPC_SegmentSegmentSqrDist(rkSeg0, Segment(rkSeg1.mOrig, rkSeg1.mOrig + rkSeg1.mDir)); | ||
353 | } | ||
354 | |||
355 | static float OPC_SegmentTriangleSqrDist(const Segment& segment, const Point& p0, const Point& p1, const Point& p2) | ||
356 | { | ||
357 | // Hook | ||
358 | const Point TriEdge0 = p1 - p0; | ||
359 | const Point TriEdge1 = p2 - p0; | ||
360 | |||
361 | const Point& rkSegOrigin = segment.GetOrigin(); | ||
362 | Point rkSegDirection = segment.ComputeDirection(); | ||
363 | |||
364 | Point kDiff = p0 - rkSegOrigin; | ||
365 | float fA00 = rkSegDirection.SquareMagnitude(); | ||
366 | float fA01 = -rkSegDirection.Dot(TriEdge0); | ||
367 | float fA02 = -rkSegDirection.Dot(TriEdge1); | ||
368 | float fA11 = TriEdge0.SquareMagnitude(); | ||
369 | float fA12 = TriEdge0.Dot(TriEdge1); | ||
370 | float fA22 = TriEdge1.Dot(TriEdge1); | ||
371 | float fB0 = -kDiff.Dot(rkSegDirection); | ||
372 | float fB1 = kDiff.Dot(TriEdge0); | ||
373 | float fB2 = kDiff.Dot(TriEdge1); | ||
374 | float fCof00 = fA11*fA22-fA12*fA12; | ||
375 | float fCof01 = fA02*fA12-fA01*fA22; | ||
376 | float fCof02 = fA01*fA12-fA02*fA11; | ||
377 | float fDet = fA00*fCof00+fA01*fCof01+fA02*fCof02; | ||
378 | |||
379 | Ray kTriSeg; | ||
380 | Point kPt; | ||
381 | float fSqrDist, fSqrDist0; | ||
382 | |||
383 | if(fabsf(fDet)>=gs_fTolerance) | ||
384 | { | ||
385 | float fCof11 = fA00*fA22-fA02*fA02; | ||
386 | float fCof12 = fA02*fA01-fA00*fA12; | ||
387 | float fCof22 = fA00*fA11-fA01*fA01; | ||
388 | float fInvDet = 1.0f/fDet; | ||
389 | float fRhs0 = -fB0*fInvDet; | ||
390 | float fRhs1 = -fB1*fInvDet; | ||
391 | float fRhs2 = -fB2*fInvDet; | ||
392 | |||
393 | float fR = fCof00*fRhs0+fCof01*fRhs1+fCof02*fRhs2; | ||
394 | float fS = fCof01*fRhs0+fCof11*fRhs1+fCof12*fRhs2; | ||
395 | float fT = fCof02*fRhs0+fCof12*fRhs1+fCof22*fRhs2; | ||
396 | |||
397 | if ( fR < 0.0f ) | ||
398 | { | ||
399 | if ( fS+fT <= 1.0f ) | ||
400 | { | ||
401 | if ( fS < 0.0f ) | ||
402 | { | ||
403 | if ( fT < 0.0f ) // region 4m | ||
404 | { | ||
405 | // min on face s=0 or t=0 or r=0 | ||
406 | kTriSeg.mOrig = p0; | ||
407 | kTriSeg.mDir = TriEdge1; | ||
408 | fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); | ||
409 | kTriSeg.mOrig = p0; | ||
410 | kTriSeg.mDir = TriEdge0; | ||
411 | fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg); | ||
412 | if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; | ||
413 | fSqrDist0 = OPC_PointTriangleSqrDist(rkSegOrigin, p0, p1, p2); | ||
414 | if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; | ||
415 | } | ||
416 | else // region 3m | ||
417 | { | ||
418 | // min on face s=0 or r=0 | ||
419 | kTriSeg.mOrig = p0; | ||
420 | kTriSeg.mDir = TriEdge1; | ||
421 | fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); | ||
422 | fSqrDist0 = OPC_PointTriangleSqrDist(rkSegOrigin, p0, p1, p2); | ||
423 | if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; | ||
424 | } | ||
425 | } | ||
426 | else if ( fT < 0.0f ) // region 5m | ||
427 | { | ||
428 | // min on face t=0 or r=0 | ||
429 | kTriSeg.mOrig = p0; | ||
430 | kTriSeg.mDir = TriEdge0; | ||
431 | fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); | ||
432 | fSqrDist0 = OPC_PointTriangleSqrDist(rkSegOrigin, p0, p1, p2); | ||
433 | if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; | ||
434 | } | ||
435 | else // region 0m | ||
436 | { | ||
437 | // min on face r=0 | ||
438 | fSqrDist = OPC_PointTriangleSqrDist(rkSegOrigin, p0, p1, p2); | ||
439 | } | ||
440 | } | ||
441 | else | ||
442 | { | ||
443 | if ( fS < 0.0f ) // region 2m | ||
444 | { | ||
445 | // min on face s=0 or s+t=1 or r=0 | ||
446 | kTriSeg.mOrig = p0; | ||
447 | kTriSeg.mDir = TriEdge1; | ||
448 | fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); | ||
449 | kTriSeg.mOrig = p1; | ||
450 | kTriSeg.mDir = TriEdge1-TriEdge0; | ||
451 | fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg); | ||
452 | if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; | ||
453 | fSqrDist0 = OPC_PointTriangleSqrDist(rkSegOrigin, p0, p1, p2); | ||
454 | if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; | ||
455 | } | ||
456 | else if ( fT < 0.0f ) // region 6m | ||
457 | { | ||
458 | // min on face t=0 or s+t=1 or r=0 | ||
459 | kTriSeg.mOrig = p0; | ||
460 | kTriSeg.mDir = TriEdge0; | ||
461 | fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); | ||
462 | kTriSeg.mOrig = p1; | ||
463 | kTriSeg.mDir = TriEdge1-TriEdge0; | ||
464 | fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg); | ||
465 | if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; | ||
466 | fSqrDist0 = OPC_PointTriangleSqrDist(rkSegOrigin, p0, p1, p2); | ||
467 | if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; | ||
468 | } | ||
469 | else // region 1m | ||
470 | { | ||
471 | // min on face s+t=1 or r=0 | ||
472 | kTriSeg.mOrig = p1; | ||
473 | kTriSeg.mDir = TriEdge1-TriEdge0; | ||
474 | fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); | ||
475 | fSqrDist0 = OPC_PointTriangleSqrDist(rkSegOrigin, p0, p1, p2); | ||
476 | if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; | ||
477 | } | ||
478 | } | ||
479 | } | ||
480 | else if ( fR <= 1.0f ) | ||
481 | { | ||
482 | if ( fS+fT <= 1.0f ) | ||
483 | { | ||
484 | if ( fS < 0.0f ) | ||
485 | { | ||
486 | if ( fT < 0.0f ) // region 4 | ||
487 | { | ||
488 | // min on face s=0 or t=0 | ||
489 | kTriSeg.mOrig = p0; | ||
490 | kTriSeg.mDir = TriEdge1; | ||
491 | fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); | ||
492 | kTriSeg.mOrig = p0; | ||
493 | kTriSeg.mDir = TriEdge0; | ||
494 | fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg); | ||
495 | if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; | ||
496 | } | ||
497 | else // region 3 | ||
498 | { | ||
499 | // min on face s=0 | ||
500 | kTriSeg.mOrig = p0; | ||
501 | kTriSeg.mDir = TriEdge1; | ||
502 | fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); | ||
503 | } | ||
504 | } | ||
505 | else if ( fT < 0.0f ) // region 5 | ||
506 | { | ||
507 | // min on face t=0 | ||
508 | kTriSeg.mOrig = p0; | ||
509 | kTriSeg.mDir = TriEdge0; | ||
510 | fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); | ||
511 | } | ||
512 | else // region 0 | ||
513 | { | ||
514 | // global minimum is interior, done | ||
515 | fSqrDist = fR*(fA00*fR+fA01*fS+fA02*fT+2.0f*fB0) | ||
516 | +fS*(fA01*fR+fA11*fS+fA12*fT+2.0f*fB1) | ||
517 | +fT*(fA02*fR+fA12*fS+fA22*fT+2.0f*fB2) | ||
518 | +kDiff.SquareMagnitude(); | ||
519 | } | ||
520 | } | ||
521 | else | ||
522 | { | ||
523 | if ( fS < 0.0f ) // region 2 | ||
524 | { | ||
525 | // min on face s=0 or s+t=1 | ||
526 | kTriSeg.mOrig = p0; | ||
527 | kTriSeg.mDir = TriEdge1; | ||
528 | fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); | ||
529 | kTriSeg.mOrig = p1; | ||
530 | kTriSeg.mDir = TriEdge1-TriEdge0; | ||
531 | fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg); | ||
532 | if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; | ||
533 | } | ||
534 | else if ( fT < 0.0f ) // region 6 | ||
535 | { | ||
536 | // min on face t=0 or s+t=1 | ||
537 | kTriSeg.mOrig = p0; | ||
538 | kTriSeg.mDir = TriEdge0; | ||
539 | fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); | ||
540 | kTriSeg.mOrig = p1; | ||
541 | kTriSeg.mDir = TriEdge1-TriEdge0; | ||
542 | fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg); | ||
543 | if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; | ||
544 | } | ||
545 | else // region 1 | ||
546 | { | ||
547 | // min on face s+t=1 | ||
548 | kTriSeg.mOrig = p1; | ||
549 | kTriSeg.mDir = TriEdge1-TriEdge0; | ||
550 | fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); | ||
551 | } | ||
552 | } | ||
553 | } | ||
554 | else // fR > 1 | ||
555 | { | ||
556 | if ( fS+fT <= 1.0f ) | ||
557 | { | ||
558 | if ( fS < 0.0f ) | ||
559 | { | ||
560 | if ( fT < 0.0f ) // region 4p | ||
561 | { | ||
562 | // min on face s=0 or t=0 or r=1 | ||
563 | kTriSeg.mOrig = p0; | ||
564 | kTriSeg.mDir = TriEdge1; | ||
565 | fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); | ||
566 | kTriSeg.mOrig = p0; | ||
567 | kTriSeg.mDir = TriEdge0; | ||
568 | fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg); | ||
569 | if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; | ||
570 | kPt = rkSegOrigin+rkSegDirection; | ||
571 | fSqrDist0 = OPC_PointTriangleSqrDist(kPt, p0, p1, p2); | ||
572 | if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; | ||
573 | } | ||
574 | else // region 3p | ||
575 | { | ||
576 | // min on face s=0 or r=1 | ||
577 | kTriSeg.mOrig = p0; | ||
578 | kTriSeg.mDir = TriEdge1; | ||
579 | fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); | ||
580 | kPt = rkSegOrigin+rkSegDirection; | ||
581 | fSqrDist0 = OPC_PointTriangleSqrDist(kPt, p0, p1, p2); | ||
582 | if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; | ||
583 | } | ||
584 | } | ||
585 | else if ( fT < 0.0f ) // region 5p | ||
586 | { | ||
587 | // min on face t=0 or r=1 | ||
588 | kTriSeg.mOrig = p0; | ||
589 | kTriSeg.mDir = TriEdge0; | ||
590 | fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); | ||
591 | kPt = rkSegOrigin+rkSegDirection; | ||
592 | fSqrDist0 = OPC_PointTriangleSqrDist(kPt, p0, p1, p2); | ||
593 | if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; | ||
594 | } | ||
595 | else // region 0p | ||
596 | { | ||
597 | // min face on r=1 | ||
598 | kPt = rkSegOrigin+rkSegDirection; | ||
599 | fSqrDist = OPC_PointTriangleSqrDist(kPt, p0, p1, p2); | ||
600 | } | ||
601 | } | ||
602 | else | ||
603 | { | ||
604 | if ( fS < 0.0f ) // region 2p | ||
605 | { | ||
606 | // min on face s=0 or s+t=1 or r=1 | ||
607 | kTriSeg.mOrig = p0; | ||
608 | kTriSeg.mDir = TriEdge1; | ||
609 | fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); | ||
610 | kTriSeg.mOrig = p1; | ||
611 | kTriSeg.mDir = TriEdge1-TriEdge0; | ||
612 | fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg); | ||
613 | if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; | ||
614 | kPt = rkSegOrigin+rkSegDirection; | ||
615 | fSqrDist0 = OPC_PointTriangleSqrDist(kPt, p0, p1, p2); | ||
616 | if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; | ||
617 | } | ||
618 | else if ( fT < 0.0f ) // region 6p | ||
619 | { | ||
620 | // min on face t=0 or s+t=1 or r=1 | ||
621 | kTriSeg.mOrig = p0; | ||
622 | kTriSeg.mDir = TriEdge0; | ||
623 | fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); | ||
624 | kTriSeg.mOrig = p1; | ||
625 | kTriSeg.mDir = TriEdge1-TriEdge0; | ||
626 | fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg); | ||
627 | if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; | ||
628 | kPt = rkSegOrigin+rkSegDirection; | ||
629 | fSqrDist0 = OPC_PointTriangleSqrDist(kPt, p0, p1, p2); | ||
630 | if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; | ||
631 | } | ||
632 | else // region 1p | ||
633 | { | ||
634 | // min on face s+t=1 or r=1 | ||
635 | kTriSeg.mOrig = p1; | ||
636 | kTriSeg.mDir = TriEdge1-TriEdge0; | ||
637 | fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); | ||
638 | kPt = rkSegOrigin+rkSegDirection; | ||
639 | fSqrDist0 = OPC_PointTriangleSqrDist(kPt, p0, p1, p2); | ||
640 | if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; | ||
641 | } | ||
642 | } | ||
643 | } | ||
644 | } | ||
645 | else | ||
646 | { | ||
647 | // segment and triangle are parallel | ||
648 | kTriSeg.mOrig = p0; | ||
649 | kTriSeg.mDir = TriEdge0; | ||
650 | fSqrDist = OPC_SegmentRaySqrDist(segment, kTriSeg); | ||
651 | |||
652 | kTriSeg.mDir = TriEdge1; | ||
653 | fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg); | ||
654 | if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; | ||
655 | |||
656 | kTriSeg.mOrig = p1; | ||
657 | kTriSeg.mDir = TriEdge1 - TriEdge0; | ||
658 | fSqrDist0 = OPC_SegmentRaySqrDist(segment, kTriSeg); | ||
659 | if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; | ||
660 | |||
661 | fSqrDist0 = OPC_PointTriangleSqrDist(rkSegOrigin, p0, p1, p2); | ||
662 | if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; | ||
663 | |||
664 | kPt = rkSegOrigin+rkSegDirection; | ||
665 | fSqrDist0 = OPC_PointTriangleSqrDist(kPt, p0, p1, p2); | ||
666 | if(fSqrDist0<fSqrDist) fSqrDist = fSqrDist0; | ||
667 | } | ||
668 | return fabsf(fSqrDist); | ||
669 | } | ||
670 | |||
671 | inline_ BOOL LSSCollider::LSSTriOverlap(const Point& vert0, const Point& vert1, const Point& vert2) | ||
672 | { | ||
673 | // Stats | ||
674 | mNbVolumePrimTests++; | ||
675 | |||
676 | float s2 = OPC_SegmentTriangleSqrDist(mSeg, vert0, vert1, vert2); | ||
677 | if(s2<mRadius2) return TRUE; | ||
678 | return FALSE; | ||
679 | } | ||