TrinityCore
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
DetourCommon.cpp File Reference
#include "DetourCommon.h"
#include "DetourMath.h"
+ Include dependency graph for DetourCommon.cpp:

Functions

void dtClosestPtPointTriangle (float *closest, const float *p, const float *a, const float *b, const float *c)
 
bool dtIntersectSegmentPoly2D (const float *p0, const float *p1, const float *verts, int nverts, float &tmin, float &tmax, int &segMin, int &segMax)
 
float dtDistancePtSegSqr2D (const float *pt, const float *p, const float *q, float &t)
 
void dtCalcPolyCenter (float *tc, const unsigned short *idx, int nidx, const float *verts)
 
bool dtClosestHeightPointTriangle (const float *p, const float *a, const float *b, const float *c, float &h)
 
bool dtPointInPolygon (const float *pt, const float *verts, const int nverts)
 
bool dtDistancePtPolyEdgesSqr (const float *pt, const float *verts, const int nverts, float *ed, float *et)
 
static void projectPoly (const float *axis, const float *poly, const int npoly, float &rmin, float &rmax)
 
bool overlapRange (const float amin, const float amax, const float bmin, const float bmax, const float eps)
 
bool dtOverlapPolyPoly2D (const float *polya, const int npolya, const float *polyb, const int npolyb)
 
void dtRandomPointInConvexPoly (const float *pts, const int npts, float *areas, const float s, const float t, float *out)
 
float vperpXZ (const float *a, const float *b)
 
bool dtIntersectSegSeg2D (const float *ap, const float *aq, const float *bp, const float *bq, float &s, float &t)
 

Function Documentation

void dtCalcPolyCenter ( float *  tc,
const unsigned short *  idx,
int  nidx,
const float *  verts 
)

Derives the centroid of a convex polygon.

Parameters
[out]tcThe centroid of the polgyon. [(x, y, z)]
[in]idxThe polygon indices. [(vertIndex) * nidx]
[in]nidxThe number of indices in the polygon. [Limit: >= 3]
[in]vertsThe polygon vertices. [(x, y, z) * vertCount]
187 {
188  tc[0] = 0.0f;
189  tc[1] = 0.0f;
190  tc[2] = 0.0f;
191  for (int j = 0; j < nidx; ++j)
192  {
193  const float* v = &verts[idx[j]*3];
194  tc[0] += v[0];
195  tc[1] += v[1];
196  tc[2] += v[2];
197  }
198  const float s = 1.0f / nidx;
199  tc[0] *= s;
200  tc[1] *= s;
201  tc[2] *= s;
202 }
bool dtClosestHeightPointTriangle ( const float *  p,
const float *  a,
const float *  b,
const float *  c,
float &  h 
)

Derives the y-axis height of the closest point on the triangle from the specified reference point.

Parameters
[in]pThe reference point from which to test. [(x, y, z)]
[in]aVertex A of triangle ABC. [(x, y, z)]
[in]bVertex B of triangle ABC. [(x, y, z)]
[in]cVertex C of triangle ABC. [(x, y, z)]
[out]hThe resulting height.
205 {
206  float v0[3], v1[3], v2[3];
207  dtVsub(v0, c,a);
208  dtVsub(v1, b,a);
209  dtVsub(v2, p,a);
210 
211  const float dot00 = dtVdot2D(v0, v0);
212  const float dot01 = dtVdot2D(v0, v1);
213  const float dot02 = dtVdot2D(v0, v2);
214  const float dot11 = dtVdot2D(v1, v1);
215  const float dot12 = dtVdot2D(v1, v2);
216 
217  // Compute barycentric coordinates
218  const float invDenom = 1.0f / (dot00 * dot11 - dot01 * dot01);
219  const float u = (dot11 * dot02 - dot01 * dot12) * invDenom;
220  const float v = (dot00 * dot12 - dot01 * dot02) * invDenom;
221 
222  // The (sloppy) epsilon is needed to allow to get height of points which
223  // are interpolated along the edges of the triangles.
224  static const float EPS = 1e-4f;
225 
226  // If point lies inside the triangle, return interpolated ycoord.
227  if (u >= -EPS && v >= -EPS && (u+v) <= 1+EPS)
228  {
229  h = a[1] + v0[1]*u + v1[1]*v;
230  return true;
231  }
232 
233  return false;
234 }
void dtVsub(float *dest, const float *v1, const float *v2)
Definition: DetourCommon.h:139
float dtVdot2D(const float *u, const float *v)
Definition: DetourCommon.h:291

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

void dtClosestPtPointTriangle ( float *  closest,
const float *  p,
const float *  a,
const float *  b,
const float *  c 
)

Derives the closest point on a triangle from the specified reference point.

Parameters
[out]closestThe closest point on the triangle.
[in]pThe reference point from which to test. [(x, y, z)]
[in]aVertex A of triangle ABC. [(x, y, z)]
[in]bVertex B of triangle ABC. [(x, y, z)]
[in]cVertex C of triangle ABC. [(x, y, z)]
26 {
27  // Check if P in vertex region outside A
28  float ab[3], ac[3], ap[3];
29  dtVsub(ab, b, a);
30  dtVsub(ac, c, a);
31  dtVsub(ap, p, a);
32  float d1 = dtVdot(ab, ap);
33  float d2 = dtVdot(ac, ap);
34  if (d1 <= 0.0f && d2 <= 0.0f)
35  {
36  // barycentric coordinates (1,0,0)
37  dtVcopy(closest, a);
38  return;
39  }
40 
41  // Check if P in vertex region outside B
42  float bp[3];
43  dtVsub(bp, p, b);
44  float d3 = dtVdot(ab, bp);
45  float d4 = dtVdot(ac, bp);
46  if (d3 >= 0.0f && d4 <= d3)
47  {
48  // barycentric coordinates (0,1,0)
49  dtVcopy(closest, b);
50  return;
51  }
52 
53  // Check if P in edge region of AB, if so return projection of P onto AB
54  float vc = d1*d4 - d3*d2;
55  if (vc <= 0.0f && d1 >= 0.0f && d3 <= 0.0f)
56  {
57  // barycentric coordinates (1-v,v,0)
58  float v = d1 / (d1 - d3);
59  closest[0] = a[0] + v * ab[0];
60  closest[1] = a[1] + v * ab[1];
61  closest[2] = a[2] + v * ab[2];
62  return;
63  }
64 
65  // Check if P in vertex region outside C
66  float cp[3];
67  dtVsub(cp, p, c);
68  float d5 = dtVdot(ab, cp);
69  float d6 = dtVdot(ac, cp);
70  if (d6 >= 0.0f && d5 <= d6)
71  {
72  // barycentric coordinates (0,0,1)
73  dtVcopy(closest, c);
74  return;
75  }
76 
77  // Check if P in edge region of AC, if so return projection of P onto AC
78  float vb = d5*d2 - d1*d6;
79  if (vb <= 0.0f && d2 >= 0.0f && d6 <= 0.0f)
80  {
81  // barycentric coordinates (1-w,0,w)
82  float w = d2 / (d2 - d6);
83  closest[0] = a[0] + w * ac[0];
84  closest[1] = a[1] + w * ac[1];
85  closest[2] = a[2] + w * ac[2];
86  return;
87  }
88 
89  // Check if P in edge region of BC, if so return projection of P onto BC
90  float va = d3*d6 - d5*d4;
91  if (va <= 0.0f && (d4 - d3) >= 0.0f && (d5 - d6) >= 0.0f)
92  {
93  // barycentric coordinates (0,1-w,w)
94  float w = (d4 - d3) / ((d4 - d3) + (d5 - d6));
95  closest[0] = b[0] + w * (c[0] - b[0]);
96  closest[1] = b[1] + w * (c[1] - b[1]);
97  closest[2] = b[2] + w * (c[2] - b[2]);
98  return;
99  }
100 
101  // P inside face region. Compute Q through its barycentric coordinates (u,v,w)
102  float denom = 1.0f / (va + vb + vc);
103  float v = vb * denom;
104  float w = vc * denom;
105  closest[0] = a[0] + ab[0] * v + ac[0] * w;
106  closest[1] = a[1] + ab[1] * v + ac[1] * w;
107  closest[2] = a[2] + ab[2] * v + ac[2] * w;
108 }
float dtVdot(const float *v1, const float *v2)
Definition: DetourCommon.h:95
void dtVcopy(float *dest, const float *a)
Definition: DetourCommon.h:190
void dtVsub(float *dest, const float *v1, const float *v2)
Definition: DetourCommon.h:139

+ Here is the call graph for this function:

bool dtDistancePtPolyEdgesSqr ( const float *  pt,
const float *  verts,
const int  nverts,
float *  ed,
float *  et 
)
257 {
258  // TODO: Replace pnpoly with triArea2D tests?
259  int i, j;
260  bool c = false;
261  for (i = 0, j = nverts-1; i < nverts; j = i++)
262  {
263  const float* vi = &verts[i*3];
264  const float* vj = &verts[j*3];
265  if (((vi[2] > pt[2]) != (vj[2] > pt[2])) &&
266  (pt[0] < (vj[0]-vi[0]) * (pt[2]-vi[2]) / (vj[2]-vi[2]) + vi[0]) )
267  c = !c;
268  ed[j] = dtDistancePtSegSqr2D(pt, vj, vi, et[j]);
269  }
270  return c;
271 }
float dtDistancePtSegSqr2D(const float *pt, const float *p, const float *q, float &t)
Definition: DetourCommon.cpp:170

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

float dtDistancePtSegSqr2D ( const float *  pt,
const float *  p,
const float *  q,
float &  t 
)
171 {
172  float pqx = q[0] - p[0];
173  float pqz = q[2] - p[2];
174  float dx = pt[0] - p[0];
175  float dz = pt[2] - p[2];
176  float d = pqx*pqx + pqz*pqz;
177  t = pqx*dx + pqz*dz;
178  if (d > 0) t /= d;
179  if (t < 0) t = 0;
180  else if (t > 1) t = 1;
181  dx = p[0] + t*pqx - pt[0];
182  dz = p[2] + t*pqz - pt[2];
183  return dx*dx + dz*dz;
184 }

+ Here is the caller graph for this function:

bool dtIntersectSegmentPoly2D ( const float *  p0,
const float *  p1,
const float *  verts,
int  nverts,
float &  tmin,
float &  tmax,
int &  segMin,
int &  segMax 
)
114 {
115  static const float EPS = 0.00000001f;
116 
117  tmin = 0;
118  tmax = 1;
119  segMin = -1;
120  segMax = -1;
121 
122  float dir[3];
123  dtVsub(dir, p1, p0);
124 
125  for (int i = 0, j = nverts-1; i < nverts; j=i++)
126  {
127  float edge[3], diff[3];
128  dtVsub(edge, &verts[i*3], &verts[j*3]);
129  dtVsub(diff, p0, &verts[j*3]);
130  const float n = dtVperp2D(edge, diff);
131  const float d = dtVperp2D(dir, edge);
132  if (fabsf(d) < EPS)
133  {
134  // S is nearly parallel to this edge
135  if (n < 0)
136  return false;
137  else
138  continue;
139  }
140  const float t = n / d;
141  if (d < 0)
142  {
143  // segment S is entering across this edge
144  if (t > tmin)
145  {
146  tmin = t;
147  segMin = j;
148  // S enters after leaving polygon
149  if (tmin > tmax)
150  return false;
151  }
152  }
153  else
154  {
155  // segment S is leaving across this edge
156  if (t < tmax)
157  {
158  tmax = t;
159  segMax = j;
160  // S leaves before entering polygon
161  if (tmax < tmin)
162  return false;
163  }
164  }
165  }
166 
167  return true;
168 }
float dtVperp2D(const float *u, const float *v)
Definition: DetourCommon.h:302
void dtVsub(float *dest, const float *v1, const float *v2)
Definition: DetourCommon.h:139

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool dtIntersectSegSeg2D ( const float *  ap,
const float *  aq,
const float *  bp,
const float *  bq,
float &  s,
float &  t 
)
377 {
378  float u[3], v[3], w[3];
379  dtVsub(u,aq,ap);
380  dtVsub(v,bq,bp);
381  dtVsub(w,ap,bp);
382  float d = vperpXZ(u,v);
383  if (fabsf(d) < 1e-6f) return false;
384  s = vperpXZ(v,w) / d;
385  t = vperpXZ(u,w) / d;
386  return true;
387 }
float vperpXZ(const float *a, const float *b)
Definition: DetourCommon.cpp:372
void dtVsub(float *dest, const float *v1, const float *v2)
Definition: DetourCommon.h:139

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool dtOverlapPolyPoly2D ( const float *  polya,
const int  npolya,
const float *  polyb,
const int  npolyb 
)

All vertices are projected onto the xz-plane, so the y-values are ignored.

297 {
298  const float eps = 1e-4f;
299 
300  for (int i = 0, j = npolya-1; i < npolya; j=i++)
301  {
302  const float* va = &polya[j*3];
303  const float* vb = &polya[i*3];
304  const float n[3] = { vb[2]-va[2], 0, -(vb[0]-va[0]) };
305  float amin,amax,bmin,bmax;
306  projectPoly(n, polya, npolya, amin,amax);
307  projectPoly(n, polyb, npolyb, bmin,bmax);
308  if (!overlapRange(amin,amax, bmin,bmax, eps))
309  {
310  // Found separating axis
311  return false;
312  }
313  }
314  for (int i = 0, j = npolyb-1; i < npolyb; j=i++)
315  {
316  const float* va = &polyb[j*3];
317  const float* vb = &polyb[i*3];
318  const float n[3] = { vb[2]-va[2], 0, -(vb[0]-va[0]) };
319  float amin,amax,bmin,bmax;
320  projectPoly(n, polya, npolya, amin,amax);
321  projectPoly(n, polyb, npolyb, bmin,bmax);
322  if (!overlapRange(amin,amax, bmin,bmax, eps))
323  {
324  // Found separating axis
325  return false;
326  }
327  }
328  return true;
329 }
bool overlapRange(const float amin, const float amax, const float bmin, const float bmax, const float eps)
Definition: DetourCommon.cpp:285
double eps(double a, double b)
Definition: g3dmath.h:824
static void projectPoly(const float *axis, const float *poly, const int npoly, float &rmin, float &rmax)
Definition: DetourCommon.cpp:273

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool dtPointInPolygon ( const float *  pt,
const float *  verts,
const int  nverts 
)

All points are projected onto the xz-plane, so the y-values are ignored.

240 {
241  // TODO: Replace pnpoly with triArea2D tests?
242  int i, j;
243  bool c = false;
244  for (i = 0, j = nverts-1; i < nverts; j = i++)
245  {
246  const float* vi = &verts[i*3];
247  const float* vj = &verts[j*3];
248  if (((vi[2] > pt[2]) != (vj[2] > pt[2])) &&
249  (pt[0] < (vj[0]-vi[0]) * (pt[2]-vi[2]) / (vj[2]-vi[2]) + vi[0]) )
250  c = !c;
251  }
252  return c;
253 }

+ Here is the caller graph for this function:

void dtRandomPointInConvexPoly ( const float *  pts,
const int  npts,
float *  areas,
const float  s,
const float  t,
float *  out 
)
335 {
336  // Calc triangle araes
337  float areasum = 0.0f;
338  for (int i = 2; i < npts; i++) {
339  areas[i] = dtTriArea2D(&pts[0], &pts[(i-1)*3], &pts[i*3]);
340  areasum += dtMax(0.001f, areas[i]);
341  }
342  // Find sub triangle weighted by area.
343  const float thr = s*areasum;
344  float acc = 0.0f;
345  float u = 0.0f;
346  int tri = 0;
347  for (int i = 2; i < npts; i++) {
348  const float dacc = areas[i];
349  if (thr >= acc && thr < (acc+dacc))
350  {
351  u = (thr - acc) / dacc;
352  tri = i;
353  break;
354  }
355  acc += dacc;
356  }
357 
358  float v = dtMathSqrtf(t);
359 
360  const float a = 1 - v;
361  const float b = (1 - u) * v;
362  const float c = u * v;
363  const float* pa = &pts[0];
364  const float* pb = &pts[(tri-1)*3];
365  const float* pc = &pts[tri*3];
366 
367  out[0] = a*pa[0] + b*pb[0] + c*pc[0];
368  out[1] = a*pa[1] + b*pb[1] + c*pc[1];
369  out[2] = a*pa[2] + b*pb[2] + c*pc[2];
370 }
float dtTriArea2D(const float *a, const float *b, const float *c)
Definition: DetourCommon.h:316
Definition: BnetFileGenerator.h:49
float dtMathSqrtf(float x)
Definition: DetourMath.h:13
T dtMax(T a, T b)
Definition: DetourCommon.h:57

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

bool overlapRange ( const float  amin,
const float  amax,
const float  bmin,
const float  bmax,
const float  eps 
)
inline
288 {
289  return ((amin+eps) > bmax || (amax-eps) < bmin) ? false : true;
290 }
double eps(double a, double b)
Definition: g3dmath.h:824

+ Here is the caller graph for this function:

static void projectPoly ( const float *  axis,
const float *  poly,
const int  npoly,
float &  rmin,
float &  rmax 
)
static
275 {
276  rmin = rmax = dtVdot2D(axis, &poly[0]);
277  for (int i = 1; i < npoly; ++i)
278  {
279  const float d = dtVdot2D(axis, &poly[i*3]);
280  rmin = dtMin(rmin, d);
281  rmax = dtMax(rmax, d);
282  }
283 }
T dtMax(T a, T b)
Definition: DetourCommon.h:57
T dtMin(T a, T b)
Definition: DetourCommon.h:51
float dtVdot2D(const float *u, const float *v)
Definition: DetourCommon.h:291

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

float vperpXZ ( const float *  a,
const float *  b 
)
inline
372 { return a[0]*b[2] - a[2]*b[0]; }

+ Here is the caller graph for this function: