Vegastrike 0.5.1 rc1  1.0
Original sources for Vegastrike Evolved
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
OPC_LSSTriOverlap.h
Go to the documentation of this file.
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
675 
676  float s2 = OPC_SegmentTriangleSqrDist(mSeg, vert0, vert1, vert2);
677  if(s2<mRadius2) return TRUE;
678  return FALSE;
679 }