~ubuntu-branches/debian/sid/ember/sid

« back to all changes in this revision

Viewing changes to src/components/ogre/ogreopcode/include/Opcode/OPC_LSSTriOverlap.h

  • Committer: Bazaar Package Importer
  • Author(s): Michael Koch
  • Date: 2009-07-23 07:46:40 UTC
  • Revision ID: james.westby@ubuntu.com-20090723074640-wh0ukzis0kda36qv
Tags: upstream-0.5.6
ImportĀ upstreamĀ versionĀ 0.5.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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 IceMaths::Point& point, const IceMaths::Point& p0, const IceMaths::Point& p1, const IceMaths::Point& p2)
 
7
{
 
8
        // Hook
 
9
        IceMaths::Point TriEdge0 = p1 - p0;
 
10
        IceMaths::Point TriEdge1 = p2 - p0;
 
11
 
 
12
        IceMaths::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 IceMaths::Segment& rkSeg0, const IceMaths::Segment& rkSeg1)
 
154
{
 
155
        // Hook
 
156
        IceMaths::Point rkSeg0Direction = rkSeg0.ComputeDirection();
 
157
        IceMaths::Point rkSeg1Direction = rkSeg1.ComputeDirection();
 
158
 
 
159
        IceMaths::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 IceMaths::Segment& rkSeg0, const IceMaths::Ray& rkSeg1)
 
351
{
 
352
        return OPC_SegmentSegmentSqrDist(rkSeg0, IceMaths::Segment(rkSeg1.mOrig, rkSeg1.mOrig + rkSeg1.mDir));
 
353
}
 
354
 
 
355
static float OPC_SegmentTriangleSqrDist(const IceMaths::Segment& segment, const IceMaths::Point& p0, const IceMaths::Point& p1, const IceMaths::Point& p2)
 
356
{
 
357
        // Hook
 
358
        const IceMaths::Point TriEdge0 = p1 - p0;
 
359
        const IceMaths::Point TriEdge1 = p2 - p0;
 
360
 
 
361
        const IceMaths::Point& rkSegOrigin      = segment.GetOrigin();
 
362
        IceMaths::Point rkSegDirection          = segment.ComputeDirection();
 
363
 
 
364
        IceMaths::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
        IceMaths::Ray kTriSeg;
 
380
        IceMaths::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 IceMaths::Point& vert0_, const IceMaths::Point& vert1_, const IceMaths::Point& vert2_)
 
672
{
 
673
        // Applies the model's local scale
 
674
        const IceMaths::Point vert0 = vert0_*mLocalScale;
 
675
        const IceMaths::Point vert1 = vert1_*mLocalScale;
 
676
        const IceMaths::Point vert2 = vert2_*mLocalScale;
 
677
        // Stats
 
678
        mNbVolumePrimTests++;
 
679
 
 
680
        float s2 = OPC_SegmentTriangleSqrDist(mSeg, vert0, vert1, vert2);
 
681
        if(s2<mRadius2) return TRUE;
 
682
        return FALSE;
 
683
}