Bullet Collision Detection & Physics Library: btConvexHull.cpp Source File

Bullet Collision Detection & Physics Library

btConvexHull.cpp
Go to the documentation of this file.
1/*
2Stan Melax Convex Hull Computation
3Copyright (c) 2003-2006 Stan Melax http://www.melax.com/
4
5This software is provided 'as-is', without any express or implied warranty.
6In no event will the authors be held liable for any damages arising from the use of this software.
7Permission is granted to anyone to use this software for any purpose,
8including commercial applications, and to alter it and redistribute it freely,
9subject to the following restrictions:
10
111. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
122. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
133. This notice may not be removed or altered from any source distribution.
14*/
15
16#include <string.h>
17
18#include "btConvexHull.h"
19#include "btAlignedObjectArray.h"
20#include "btMinMax.h"
21#include "btVector3.h"
22
23//----------------------------------
24
25 class int3
26{
27public:
28 int x, y, z;
29 int3(){};
30 int3(int _x, int _y, int _z)
31 {
32 x = _x;
33 y = _y;
34 z = _z;
35 }
36 const int &operator[](int i) const { return (&x)[i]; }
37 int &operator[](int i) { return (&x)[i]; }
38};
39
40//------- btPlane ----------
41
42 inline btPlane PlaneFlip(const btPlane &plane) { return btPlane(-plane.normal, -plane.dist); }
43 inline int operator==(const btPlane &a, const btPlane &b) { return (a.normal == b.normal && a.dist == b.dist); }
44 inline int coplanar(const btPlane &a, const btPlane &b) { return (a == b || a == PlaneFlip(b)); }
45
46//--------- Utility Functions ------
47
48 btVector3 PlaneLineIntersection(const btPlane &plane, const btVector3 &p0, const btVector3 &p1);
49 btVector3 PlaneProject(const btPlane &plane, const btVector3 &point);
50
51 btVector3 ThreePlaneIntersection(const btPlane &p0, const btPlane &p1, const btPlane &p2);
52 btVector3 ThreePlaneIntersection(const btPlane &p0, const btPlane &p1, const btPlane &p2)
53{
54 btVector3 N1 = p0.normal;
55 btVector3 N2 = p1.normal;
56 btVector3 N3 = p2.normal;
57
58 btVector3 n2n3;
59 n2n3 = N2.cross(N3);
60 btVector3 n3n1;
61 n3n1 = N3.cross(N1);
62 btVector3 n1n2;
63 n1n2 = N1.cross(N2);
64
65 btScalar quotient = (N1.dot(n2n3));
66
67 btAssert(btFabs(quotient) > btScalar(0.000001));
68
69 quotient = btScalar(-1.) / quotient;
70 n2n3 *= p0.dist;
71 n3n1 *= p1.dist;
72 n1n2 *= p2.dist;
73 btVector3 potentialVertex = n2n3;
74 potentialVertex += n3n1;
75 potentialVertex += n1n2;
76 potentialVertex *= quotient;
77
78 btVector3 result(potentialVertex.getX(), potentialVertex.getY(), potentialVertex.getZ());
79 return result;
80}
81
82 btScalar DistanceBetweenLines(const btVector3 &ustart, const btVector3 &udir, const btVector3 &vstart, const btVector3 &vdir, btVector3 *upoint = NULL, btVector3 *vpoint = NULL);
83 btVector3 TriNormal(const btVector3 &v0, const btVector3 &v1, const btVector3 &v2);
84 btVector3 NormalOf(const btVector3 *vert, const int n);
85
86 btVector3 PlaneLineIntersection(const btPlane &plane, const btVector3 &p0, const btVector3 &p1)
87{
88 // returns the point where the line p0-p1 intersects the plane n&d
89 btVector3 dif;
90 dif = p1 - p0;
91 btScalar dn = btDot(plane.normal, dif);
92 btScalar t = -(plane.dist + btDot(plane.normal, p0)) / dn;
93 return p0 + (dif * t);
94}
95
96 btVector3 PlaneProject(const btPlane &plane, const btVector3 &point)
97{
98 return point - plane.normal * (btDot(point, plane.normal) + plane.dist);
99}
100
101 btVector3 TriNormal(const btVector3 &v0, const btVector3 &v1, const btVector3 &v2)
102{
103 // return the normal of the triangle
104 // inscribed by v0, v1, and v2
105 btVector3 cp = btCross(v1 - v0, v2 - v1);
106 btScalar m = cp.length();
107 if (m == 0) return btVector3(1, 0, 0);
108 return cp * (btScalar(1.0) / m);
109}
110
111 btScalar DistanceBetweenLines(const btVector3 &ustart, const btVector3 &udir, const btVector3 &vstart, const btVector3 &vdir, btVector3 *upoint, btVector3 *vpoint)
112{
113 btVector3 cp;
114 cp = btCross(udir, vdir).normalized();
115
116 btScalar distu = -btDot(cp, ustart);
117 btScalar distv = -btDot(cp, vstart);
118 btScalar dist = (btScalar)fabs(distu - distv);
119 if (upoint)
120 {
121 btPlane plane;
122 plane.normal = btCross(vdir, cp).normalized();
123 plane.dist = -btDot(plane.normal, vstart);
124 *upoint = PlaneLineIntersection(plane, ustart, ustart + udir);
125 }
126 if (vpoint)
127 {
128 btPlane plane;
129 plane.normal = btCross(udir, cp).normalized();
130 plane.dist = -btDot(plane.normal, ustart);
131 *vpoint = PlaneLineIntersection(plane, vstart, vstart + vdir);
132 }
133 return dist;
134}
135
136#define COPLANAR (0)
137#define UNDER (1)
138#define OVER (2)
139#define SPLIT (OVER | UNDER)
140#define PAPERWIDTH (btScalar(0.001))
141
142 btScalar planetestepsilon = PAPERWIDTH;
143
144 typedef ConvexH::HalfEdge HalfEdge;
145
146 ConvexH::ConvexH(int vertices_size, int edges_size, int facets_size)
147{
148 vertices.resize(vertices_size);
149 edges.resize(edges_size);
150 facets.resize(facets_size);
151}
152
153int PlaneTest(const btPlane &p, const btVector3 &v);
154 int PlaneTest(const btPlane &p, const btVector3 &v)
155{
156 btScalar a = btDot(v, p.normal) + p.dist;
157 int flag = (a > planetestepsilon) ? OVER : ((a < -planetestepsilon) ? UNDER : COPLANAR);
158 return flag;
159}
160
161int SplitTest(ConvexH &convex, const btPlane &plane);
162 int SplitTest(ConvexH &convex, const btPlane &plane)
163{
164 int flag = 0;
165 for (int i = 0; i < convex.vertices.size(); i++)
166 {
167 flag |= PlaneTest(plane, convex.vertices[i]);
168 }
169 return flag;
170}
171
172 class VertFlag
173{
174public:
175 unsigned char planetest;
176 unsigned char junk;
177 unsigned char undermap;
178 unsigned char overmap;
179};
180 class EdgeFlag
181{
182public:
183 unsigned char planetest;
184 unsigned char fixes;
185 short undermap;
186 short overmap;
187};
188 class PlaneFlag
189{
190public:
191 unsigned char undermap;
192 unsigned char overmap;
193};
194 class Coplanar
195{
196public:
197 unsigned short ea;
198 unsigned char v0;
199 unsigned char v1;
200};
201
202template <class T>
203 int maxdirfiltered(const T *p, int count, const T &dir, btAlignedObjectArray<int> &allow)
204{
205 btAssert(count);
206 int m = -1;
207 for (int i = 0; i < count; i++)
208 if (allow[i])
209 {
210 if (m == -1 || btDot(p[i], dir) > btDot(p[m], dir))
211 m = i;
212 }
213 btAssert(m != -1);
214 return m;
215}
216
217 btVector3 orth(const btVector3 &v);
218 btVector3 orth(const btVector3 &v)
219{
220 btVector3 a = btCross(v, btVector3(0, 0, 1));
221 btVector3 b = btCross(v, btVector3(0, 1, 0));
222 if (a.length() > b.length())
223 {
224 return a.normalized();
225 }
226 else
227 {
228 return b.normalized();
229 }
230}
231
232template <class T>
233 int maxdirsterid(const T *p, int count, const T &dir, btAlignedObjectArray<int> &allow)
234{
235 int m = -1;
236 while (m == -1)
237 {
238 m = maxdirfiltered(p, count, dir, allow);
239 if (allow[m] == 3) return m;
240 T u = orth(dir);
241 T v = btCross(u, dir);
242 int ma = -1;
243 for (btScalar x = btScalar(0.0); x <= btScalar(360.0); x += btScalar(45.0))
244 {
245 btScalar s = btSin(SIMD_RADS_PER_DEG * (x));
246 btScalar c = btCos(SIMD_RADS_PER_DEG * (x));
247 int mb = maxdirfiltered(p, count, dir + (u * s + v * c) * btScalar(0.025), allow);
248 if (ma == m && mb == m)
249 {
250 allow[m] = 3;
251 return m;
252 }
253 if (ma != -1 && ma != mb) // Yuck - this is really ugly
254 {
255 int mc = ma;
256 for (btScalar xx = x - btScalar(40.0); xx <= x; xx += btScalar(5.0))
257 {
258 btScalar s = btSin(SIMD_RADS_PER_DEG * (xx));
259 btScalar c = btCos(SIMD_RADS_PER_DEG * (xx));
260 int md = maxdirfiltered(p, count, dir + (u * s + v * c) * btScalar(0.025), allow);
261 if (mc == m && md == m)
262 {
263 allow[m] = 3;
264 return m;
265 }
266 mc = md;
267 }
268 }
269 ma = mb;
270 }
271 allow[m] = 0;
272 m = -1;
273 }
274 btAssert(0);
275 return m;
276}
277
278int operator==(const int3 &a, const int3 &b);
279 int operator==(const int3 &a, const int3 &b)
280{
281 for (int i = 0; i < 3; i++)
282 {
283 if (a[i] != b[i]) return 0;
284 }
285 return 1;
286}
287
288int above(btVector3 *vertices, const int3 &t, const btVector3 &p, btScalar epsilon);
289 int above(btVector3 *vertices, const int3 &t, const btVector3 &p, btScalar epsilon)
290{
291 btVector3 n = TriNormal(vertices[t[0]], vertices[t[1]], vertices[t[2]]);
292 return (btDot(n, p - vertices[t[0]]) > epsilon); // EPSILON???
293}
294int hasedge(const int3 &t, int a, int b);
295 int hasedge(const int3 &t, int a, int b)
296{
297 for (int i = 0; i < 3; i++)
298 {
299 int i1 = (i + 1) % 3;
300 if (t[i] == a && t[i1] == b) return 1;
301 }
302 return 0;
303}
304int hasvert(const int3 &t, int v);
305 int hasvert(const int3 &t, int v)
306{
307 return (t[0] == v || t[1] == v || t[2] == v);
308}
309int shareedge(const int3 &a, const int3 &b);
310 int shareedge(const int3 &a, const int3 &b)
311{
312 int i;
313 for (i = 0; i < 3; i++)
314 {
315 int i1 = (i + 1) % 3;
316 if (hasedge(a, b[i1], b[i])) return 1;
317 }
318 return 0;
319}
320
321class btHullTriangle;
322
323 class btHullTriangle : public int3
324{
325public:
326 int3 n;
327 int id;
328 int vmax;
329 btScalar rise;
330 btHullTriangle(int a, int b, int c) : int3(a, b, c), n(-1, -1, -1)
331 {
332 vmax = -1;
333 rise = btScalar(0.0);
334 }
335 ~btHullTriangle()
336 {
337 }
338 int &neib(int a, int b);
339};
340
341 int &btHullTriangle::neib(int a, int b)
342{
343 static int er = -1;
344 int i;
345 for (i = 0; i < 3; i++)
346 {
347 int i1 = (i + 1) % 3;
348 int i2 = (i + 2) % 3;
349 if ((*this)[i] == a && (*this)[i1] == b) return n[i2];
350 if ((*this)[i] == b && (*this)[i1] == a) return n[i2];
351 }
352 btAssert(0);
353 return er;
354}
355 void HullLibrary::b2bfix(btHullTriangle *s, btHullTriangle *t)
356{
357 int i;
358 for (i = 0; i < 3; i++)
359 {
360 int i1 = (i + 1) % 3;
361 int i2 = (i + 2) % 3;
362 int a = (*s)[i1];
363 int b = (*s)[i2];
364 btAssert(m_tris[s->neib(a, b)]->neib(b, a) == s->id);
365 btAssert(m_tris[t->neib(a, b)]->neib(b, a) == t->id);
366 m_tris[s->neib(a, b)]->neib(b, a) = t->neib(b, a);
367 m_tris[t->neib(b, a)]->neib(a, b) = s->neib(a, b);
368 }
369}
370
371 void HullLibrary::removeb2b(btHullTriangle *s, btHullTriangle *t)
372{
373 b2bfix(s, t);
374 deAllocateTriangle(s);
375
376 deAllocateTriangle(t);
377}
378
379 void HullLibrary::checkit(btHullTriangle *t)
380{
381 (void)t;
382
383 int i;
384 btAssert(m_tris[t->id] == t);
385 for (i = 0; i < 3; i++)
386 {
387 int i1 = (i + 1) % 3;
388 int i2 = (i + 2) % 3;
389 int a = (*t)[i1];
390 int b = (*t)[i2];
391
392 // release compile fix
393 (void)i1;
394 (void)i2;
395 (void)a;
396 (void)b;
397
398 btAssert(a != b);
399 btAssert(m_tris[t->n[i]]->neib(b, a) == t->id);
400 }
401}
402
403 btHullTriangle *HullLibrary::allocateTriangle(int a, int b, int c)
404{
405 void *mem = btAlignedAlloc(sizeof(btHullTriangle), 16);
406 btHullTriangle *tr = new (mem) btHullTriangle(a, b, c);
407 tr->id = m_tris.size();
408 m_tris.push_back(tr);
409
410 return tr;
411}
412
413 void HullLibrary::deAllocateTriangle(btHullTriangle *tri)
414{
415 btAssert(m_tris[tri->id] == tri);
416 m_tris[tri->id] = NULL;
417 tri->~btHullTriangle();
418 btAlignedFree(tri);
419}
420
421 void HullLibrary::extrude(btHullTriangle *t0, int v)
422{
423 int3 t = *t0;
424 int n = m_tris.size();
425 btHullTriangle *ta = allocateTriangle(v, t[1], t[2]);
426 ta->n = int3(t0->n[0], n + 1, n + 2);
427 m_tris[t0->n[0]]->neib(t[1], t[2]) = n + 0;
428 btHullTriangle *tb = allocateTriangle(v, t[2], t[0]);
429 tb->n = int3(t0->n[1], n + 2, n + 0);
430 m_tris[t0->n[1]]->neib(t[2], t[0]) = n + 1;
431 btHullTriangle *tc = allocateTriangle(v, t[0], t[1]);
432 tc->n = int3(t0->n[2], n + 0, n + 1);
433 m_tris[t0->n[2]]->neib(t[0], t[1]) = n + 2;
434 checkit(ta);
435 checkit(tb);
436 checkit(tc);
437 if (hasvert(*m_tris[ta->n[0]], v)) removeb2b(ta, m_tris[ta->n[0]]);
438 if (hasvert(*m_tris[tb->n[0]], v)) removeb2b(tb, m_tris[tb->n[0]]);
439 if (hasvert(*m_tris[tc->n[0]], v)) removeb2b(tc, m_tris[tc->n[0]]);
440 deAllocateTriangle(t0);
441}
442
443 btHullTriangle *HullLibrary::extrudable(btScalar epsilon)
444{
445 int i;
446 btHullTriangle *t = NULL;
447 for (i = 0; i < m_tris.size(); i++)
448 {
449 if (!t || (m_tris[i] && t->rise < m_tris[i]->rise))
450 {
451 t = m_tris[i];
452 }
453 }
454 return (t->rise > epsilon) ? t : NULL;
455}
456
457 int4 HullLibrary::FindSimplex(btVector3 *verts, int verts_count, btAlignedObjectArray<int> &allow)
458{
459 btVector3 basis[3];
460 basis[0] = btVector3(btScalar(0.01), btScalar(0.02), btScalar(1.0));
461 int p0 = maxdirsterid(verts, verts_count, basis[0], allow);
462 int p1 = maxdirsterid(verts, verts_count, -basis[0], allow);
463 basis[0] = verts[p0] - verts[p1];
464 if (p0 == p1 || basis[0] == btVector3(0, 0, 0))
465 return int4(-1, -1, -1, -1);
466 basis[1] = btCross(btVector3(btScalar(1), btScalar(0.02), btScalar(0)), basis[0]);
467 basis[2] = btCross(btVector3(btScalar(-0.02), btScalar(1), btScalar(0)), basis[0]);
468 if (basis[1].length() > basis[2].length())
469 {
470 basis[1].normalize();
471 }
472 else
473 {
474 basis[1] = basis[2];
475 basis[1].normalize();
476 }
477 int p2 = maxdirsterid(verts, verts_count, basis[1], allow);
478 if (p2 == p0 || p2 == p1)
479 {
480 p2 = maxdirsterid(verts, verts_count, -basis[1], allow);
481 }
482 if (p2 == p0 || p2 == p1)
483 return int4(-1, -1, -1, -1);
484 basis[1] = verts[p2] - verts[p0];
485 basis[2] = btCross(basis[1], basis[0]).normalized();
486 int p3 = maxdirsterid(verts, verts_count, basis[2], allow);
487 if (p3 == p0 || p3 == p1 || p3 == p2) p3 = maxdirsterid(verts, verts_count, -basis[2], allow);
488 if (p3 == p0 || p3 == p1 || p3 == p2)
489 return int4(-1, -1, -1, -1);
490 btAssert(!(p0 == p1 || p0 == p2 || p0 == p3 || p1 == p2 || p1 == p3 || p2 == p3));
491 if (btDot(verts[p3] - verts[p0], btCross(verts[p1] - verts[p0], verts[p2] - verts[p0])) < 0)
492 {
493 btSwap(p2, p3);
494 }
495 return int4(p0, p1, p2, p3);
496}
497
498 int HullLibrary::calchullgen(btVector3 *verts, int verts_count, int vlimit)
499{
500 if (verts_count < 4) return 0;
501 if (vlimit == 0) vlimit = 1000000000;
502 int j;
503 btVector3 bmin(*verts), bmax(*verts);
504 btAlignedObjectArray<int> isextreme;
505 isextreme.reserve(verts_count);
506 btAlignedObjectArray<int> allow;
507 allow.reserve(verts_count);
508
509 for (j = 0; j < verts_count; j++)
510 {
511 allow.push_back(1);
512 isextreme.push_back(0);
513 bmin.setMin(verts[j]);
514 bmax.setMax(verts[j]);
515 }
516 btScalar epsilon = (bmax - bmin).length() * btScalar(0.001);
517 btAssert(epsilon != 0.0);
518
519 int4 p = FindSimplex(verts, verts_count, allow);
520 if (p.x == -1) return 0; // simplex failed
521
522 btVector3 center = (verts[p[0]] + verts[p[1]] + verts[p[2]] + verts[p[3]]) / btScalar(4.0); // a valid interior point
523 btHullTriangle *t0 = allocateTriangle(p[2], p[3], p[1]);
524 t0->n = int3(2, 3, 1);
525 btHullTriangle *t1 = allocateTriangle(p[3], p[2], p[0]);
526 t1->n = int3(3, 2, 0);
527 btHullTriangle *t2 = allocateTriangle(p[0], p[1], p[3]);
528 t2->n = int3(0, 1, 3);
529 btHullTriangle *t3 = allocateTriangle(p[1], p[0], p[2]);
530 t3->n = int3(1, 0, 2);
531 isextreme[p[0]] = isextreme[p[1]] = isextreme[p[2]] = isextreme[p[3]] = 1;
532 checkit(t0);
533 checkit(t1);
534 checkit(t2);
535 checkit(t3);
536
537 for (j = 0; j < m_tris.size(); j++)
538 {
539 btHullTriangle *t = m_tris[j];
540 btAssert(t);
541 btAssert(t->vmax < 0);
542 btVector3 n = TriNormal(verts[(*t)[0]], verts[(*t)[1]], verts[(*t)[2]]);
543 t->vmax = maxdirsterid(verts, verts_count, n, allow);
544 t->rise = btDot(n, verts[t->vmax] - verts[(*t)[0]]);
545 }
546 btHullTriangle *te;
547 vlimit -= 4;
548 while (vlimit > 0 && ((te = extrudable(epsilon)) != 0))
549 {
550 //int3 ti=*te;
551 int v = te->vmax;
552 btAssert(v != -1);
553 btAssert(!isextreme[v]); // wtf we've already done this vertex
554 isextreme[v] = 1;
555 //if(v==p0 || v==p1 || v==p2 || v==p3) continue; // done these already
556 j = m_tris.size();
557 while (j--)
558 {
559 if (!m_tris[j]) continue;
560 int3 t = *m_tris[j];
561 if (above(verts, t, verts[v], btScalar(0.01) * epsilon))
562 {
563 extrude(m_tris[j], v);
564 }
565 }
566 // now check for those degenerate cases where we have a flipped triangle or a really skinny triangle
567 j = m_tris.size();
568 while (j--)
569 {
570 if (!m_tris[j]) continue;
571 if (!hasvert(*m_tris[j], v)) break;
572 int3 nt = *m_tris[j];
573 if (above(verts, nt, center, btScalar(0.01) * epsilon) || btCross(verts[nt[1]] - verts[nt[0]], verts[nt[2]] - verts[nt[1]]).length() < epsilon * epsilon * btScalar(0.1))
574 {
575 btHullTriangle *nb = m_tris[m_tris[j]->n[0]];
576 btAssert(nb);
577 btAssert(!hasvert(*nb, v));
578 btAssert(nb->id < j);
579 extrude(nb, v);
580 j = m_tris.size();
581 }
582 }
583 j = m_tris.size();
584 while (j--)
585 {
586 btHullTriangle *t = m_tris[j];
587 if (!t) continue;
588 if (t->vmax >= 0) break;
589 btVector3 n = TriNormal(verts[(*t)[0]], verts[(*t)[1]], verts[(*t)[2]]);
590 t->vmax = maxdirsterid(verts, verts_count, n, allow);
591 if (isextreme[t->vmax])
592 {
593 t->vmax = -1; // already done that vertex - algorithm needs to be able to terminate.
594 }
595 else
596 {
597 t->rise = btDot(n, verts[t->vmax] - verts[(*t)[0]]);
598 }
599 }
600 vlimit--;
601 }
602 return 1;
603}
604
605 int HullLibrary::calchull(btVector3 *verts, int verts_count, TUIntArray &tris_out, int &tris_count, int vlimit)
606{
607 int rc = calchullgen(verts, verts_count, vlimit);
608 if (!rc) return 0;
609 btAlignedObjectArray<int> ts;
610 int i;
611
612 for (i = 0; i < m_tris.size(); i++)
613 {
614 if (m_tris[i])
615 {
616 for (int j = 0; j < 3; j++)
617 ts.push_back((*m_tris[i])[j]);
618 deAllocateTriangle(m_tris[i]);
619 }
620 }
621 tris_count = ts.size() / 3;
622 tris_out.resize(ts.size());
623
624 for (i = 0; i < ts.size(); i++)
625 {
626 tris_out[i] = static_cast<unsigned int>(ts[i]);
627 }
628 m_tris.resize(0);
629
630 return 1;
631}
632
633 bool HullLibrary::ComputeHull(unsigned int vcount, const btVector3 *vertices, PHullResult &result, unsigned int vlimit)
634{
635 int tris_count;
636 int ret = calchull((btVector3 *)vertices, (int)vcount, result.m_Indices, tris_count, static_cast<int>(vlimit));
637 if (!ret) return false;
638 result.mIndexCount = (unsigned int)(tris_count * 3);
639 result.mFaceCount = (unsigned int)tris_count;
640 result.mVertices = (btVector3 *)vertices;
641 result.mVcount = (unsigned int)vcount;
642 return true;
643}
644
645void ReleaseHull(PHullResult &result);
646 void ReleaseHull(PHullResult &result)
647{
648 if (result.m_Indices.size())
649 {
650 result.m_Indices.clear();
651 }
652
653 result.mVcount = 0;
654 result.mIndexCount = 0;
655 result.mVertices = 0;
656}
657
658//*********************************************************************
659//*********************************************************************
660//******** HullLib header
661//*********************************************************************
662//*********************************************************************
663
664//*********************************************************************
665//*********************************************************************
666//******** HullLib implementation
667//*********************************************************************
668//*********************************************************************
669
670 HullError HullLibrary::CreateConvexHull(const HullDesc &desc, // describes the input request
671 HullResult &result) // contains the resulst
672{
673 HullError ret = QE_FAIL;
674
675 PHullResult hr;
676
677 unsigned int vcount = desc.mVcount;
678 if (vcount < 8) vcount = 8;
679
680 btAlignedObjectArray<btVector3> vertexSource;
681 vertexSource.resize(static_cast<int>(vcount));
682
683 btVector3 scale;
684
685 unsigned int ovcount;
686
687 bool ok = CleanupVertices(desc.mVcount, desc.mVertices, desc.mVertexStride, ovcount, &vertexSource[0], desc.mNormalEpsilon, scale); // normalize point cloud, remove duplicates!
688
689 if (ok)
690 {
691 // if ( 1 ) // scale vertices back to their original size.
692 {
693 for (unsigned int i = 0; i < ovcount; i++)
694 {
695 btVector3 &v = vertexSource[static_cast<int>(i)];
696 v[0] *= scale[0];
697 v[1] *= scale[1];
698 v[2] *= scale[2];
699 }
700 }
701
702 ok = ComputeHull(ovcount, &vertexSource[0], hr, desc.mMaxVertices);
703
704 if (ok)
705 {
706 // re-index triangle mesh so it refers to only used vertices, rebuild a new vertex table.
707 btAlignedObjectArray<btVector3> vertexScratch;
708 vertexScratch.resize(static_cast<int>(hr.mVcount));
709
710 BringOutYourDead(hr.mVertices, hr.mVcount, &vertexScratch[0], ovcount, &hr.m_Indices[0], hr.mIndexCount);
711
712 ret = QE_OK;
713
714 if (desc.HasHullFlag(QF_TRIANGLES)) // if he wants the results as triangle!
715 {
716 result.mPolygons = false;
717 result.mNumOutputVertices = ovcount;
718 result.m_OutputVertices.resize(static_cast<int>(ovcount));
719 result.mNumFaces = hr.mFaceCount;
720 result.mNumIndices = hr.mIndexCount;
721
722 result.m_Indices.resize(static_cast<int>(hr.mIndexCount));
723
724 memcpy(&result.m_OutputVertices[0], &vertexScratch[0], sizeof(btVector3) * ovcount);
725
726 if (desc.HasHullFlag(QF_REVERSE_ORDER))
727 {
728 const unsigned int *source = &hr.m_Indices[0];
729 unsigned int *dest = &result.m_Indices[0];
730
731 for (unsigned int i = 0; i < hr.mFaceCount; i++)
732 {
733 dest[0] = source[2];
734 dest[1] = source[1];
735 dest[2] = source[0];
736 dest += 3;
737 source += 3;
738 }
739 }
740 else
741 {
742 memcpy(&result.m_Indices[0], &hr.m_Indices[0], sizeof(unsigned int) * hr.mIndexCount);
743 }
744 }
745 else
746 {
747 result.mPolygons = true;
748 result.mNumOutputVertices = ovcount;
749 result.m_OutputVertices.resize(static_cast<int>(ovcount));
750 result.mNumFaces = hr.mFaceCount;
751 result.mNumIndices = hr.mIndexCount + hr.mFaceCount;
752 result.m_Indices.resize(static_cast<int>(result.mNumIndices));
753 memcpy(&result.m_OutputVertices[0], &vertexScratch[0], sizeof(btVector3) * ovcount);
754
755 // if ( 1 )
756 {
757 const unsigned int *source = &hr.m_Indices[0];
758 unsigned int *dest = &result.m_Indices[0];
759 for (unsigned int i = 0; i < hr.mFaceCount; i++)
760 {
761 dest[0] = 3;
762 if (desc.HasHullFlag(QF_REVERSE_ORDER))
763 {
764 dest[1] = source[2];
765 dest[2] = source[1];
766 dest[3] = source[0];
767 }
768 else
769 {
770 dest[1] = source[0];
771 dest[2] = source[1];
772 dest[3] = source[2];
773 }
774
775 dest += 4;
776 source += 3;
777 }
778 }
779 }
780 ReleaseHull(hr);
781 }
782 }
783
784 return ret;
785}
786
787 HullError HullLibrary::ReleaseResult(HullResult &result) // release memory allocated for this result, we are done with it.
788{
789 if (result.m_OutputVertices.size())
790 {
791 result.mNumOutputVertices = 0;
792 result.m_OutputVertices.clear();
793 }
794 if (result.m_Indices.size())
795 {
796 result.mNumIndices = 0;
797 result.m_Indices.clear();
798 }
799 return QE_OK;
800}
801
802 static void addPoint(unsigned int &vcount, btVector3 *p, btScalar x, btScalar y, btScalar z)
803{
804 // XXX, might be broken
805 btVector3 &dest = p[vcount];
806 dest[0] = x;
807 dest[1] = y;
808 dest[2] = z;
809 vcount++;
810}
811
812 btScalar GetDist(btScalar px, btScalar py, btScalar pz, const btScalar *p2);
813 btScalar GetDist(btScalar px, btScalar py, btScalar pz, const btScalar *p2)
814{
815 btScalar dx = px - p2[0];
816 btScalar dy = py - p2[1];
817 btScalar dz = pz - p2[2];
818
819 return dx * dx + dy * dy + dz * dz;
820}
821
822 bool HullLibrary::CleanupVertices(unsigned int svcount,
823 const btVector3 *svertices,
824 unsigned int stride,
825 unsigned int &vcount, // output number of vertices
826 btVector3 *vertices, // location to store the results.
827 btScalar normalepsilon,
828 btVector3 &scale)
829{
830 if (svcount == 0) return false;
831
832 m_vertexIndexMapping.resize(0);
833
834#define EPSILON btScalar(0.000001) /* close enough to consider two btScalaring point numbers to be 'the same'. */
835
836 vcount = 0;
837
838 btScalar recip[3] = {0.f, 0.f, 0.f};
839
840 if (scale)
841 {
842 scale[0] = 1;
843 scale[1] = 1;
844 scale[2] = 1;
845 }
846
847 btScalar bmin[3] = {FLT_MAX, FLT_MAX, FLT_MAX};
848 btScalar bmax[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX};
849
850 const char *vtx = (const char *)svertices;
851
852 // if ( 1 )
853 {
854 for (unsigned int i = 0; i < svcount; i++)
855 {
856 const btScalar *p = (const btScalar *)vtx;
857
858 vtx += stride;
859
860 for (int j = 0; j < 3; j++)
861 {
862 if (p[j] < bmin[j]) bmin[j] = p[j];
863 if (p[j] > bmax[j]) bmax[j] = p[j];
864 }
865 }
866 }
867
868 btScalar dx = bmax[0] - bmin[0];
869 btScalar dy = bmax[1] - bmin[1];
870 btScalar dz = bmax[2] - bmin[2];
871
872 btVector3 center;
873
874 center[0] = dx * btScalar(0.5) + bmin[0];
875 center[1] = dy * btScalar(0.5) + bmin[1];
876 center[2] = dz * btScalar(0.5) + bmin[2];
877
878 if (dx < EPSILON || dy < EPSILON || dz < EPSILON || svcount < 3)
879 {
880 btScalar len = FLT_MAX;
881
882 if (dx > EPSILON && dx < len) len = dx;
883 if (dy > EPSILON && dy < len) len = dy;
884 if (dz > EPSILON && dz < len) len = dz;
885
886 if (len == FLT_MAX)
887 {
888 dx = dy = dz = btScalar(0.01); // one centimeter
889 }
890 else
891 {
892 if (dx < EPSILON) dx = len * btScalar(0.05); // 1/5th the shortest non-zero edge.
893 if (dy < EPSILON) dy = len * btScalar(0.05);
894 if (dz < EPSILON) dz = len * btScalar(0.05);
895 }
896
897 btScalar x1 = center[0] - dx;
898 btScalar x2 = center[0] + dx;
899
900 btScalar y1 = center[1] - dy;
901 btScalar y2 = center[1] + dy;
902
903 btScalar z1 = center[2] - dz;
904 btScalar z2 = center[2] + dz;
905
906 addPoint(vcount, vertices, x1, y1, z1);
907 addPoint(vcount, vertices, x2, y1, z1);
908 addPoint(vcount, vertices, x2, y2, z1);
909 addPoint(vcount, vertices, x1, y2, z1);
910 addPoint(vcount, vertices, x1, y1, z2);
911 addPoint(vcount, vertices, x2, y1, z2);
912 addPoint(vcount, vertices, x2, y2, z2);
913 addPoint(vcount, vertices, x1, y2, z2);
914
915 return true; // return cube
916 }
917 else
918 {
919 if (scale)
920 {
921 scale[0] = dx;
922 scale[1] = dy;
923 scale[2] = dz;
924
925 recip[0] = 1 / dx;
926 recip[1] = 1 / dy;
927 recip[2] = 1 / dz;
928
929 center[0] *= recip[0];
930 center[1] *= recip[1];
931 center[2] *= recip[2];
932 }
933 }
934
935 vtx = (const char *)svertices;
936
937 for (unsigned int i = 0; i < svcount; i++)
938 {
939 const btVector3 *p = (const btVector3 *)vtx;
940 vtx += stride;
941
942 btScalar px = p->getX();
943 btScalar py = p->getY();
944 btScalar pz = p->getZ();
945
946 if (scale)
947 {
948 px = px * recip[0]; // normalize
949 py = py * recip[1]; // normalize
950 pz = pz * recip[2]; // normalize
951 }
952
953 // if ( 1 )
954 {
955 unsigned int j;
956
957 for (j = 0; j < vcount; j++)
958 {
960 btVector3 &v = vertices[j];
961
962 btScalar x = v[0];
963 btScalar y = v[1];
964 btScalar z = v[2];
965
966 btScalar dx = btFabs(x - px);
967 btScalar dy = btFabs(y - py);
968 btScalar dz = btFabs(z - pz);
969
970 if (dx < normalepsilon && dy < normalepsilon && dz < normalepsilon)
971 {
972 // ok, it is close enough to the old one
973 // now let us see if it is further from the center of the point cloud than the one we already recorded.
974 // in which case we keep this one instead.
975
976 btScalar dist1 = GetDist(px, py, pz, center);
977 btScalar dist2 = GetDist(v[0], v[1], v[2], center);
978
979 if (dist1 > dist2)
980 {
981 v[0] = px;
982 v[1] = py;
983 v[2] = pz;
984 }
985
986 break;
987 }
988 }
989
990 if (j == vcount)
991 {
992 btVector3 &dest = vertices[vcount];
993 dest[0] = px;
994 dest[1] = py;
995 dest[2] = pz;
996 vcount++;
997 }
998 m_vertexIndexMapping.push_back(j);
999 }
1000 }
1001
1002 // ok..now make sure we didn't prune so many vertices it is now invalid.
1003 // if ( 1 )
1004 {
1005 btScalar bmin[3] = {FLT_MAX, FLT_MAX, FLT_MAX};
1006 btScalar bmax[3] = {-FLT_MAX, -FLT_MAX, -FLT_MAX};
1007
1008 for (unsigned int i = 0; i < vcount; i++)
1009 {
1010 const btVector3 &p = vertices[i];
1011 for (int j = 0; j < 3; j++)
1012 {
1013 if (p[j] < bmin[j]) bmin[j] = p[j];
1014 if (p[j] > bmax[j]) bmax[j] = p[j];
1015 }
1016 }
1017
1018 btScalar dx = bmax[0] - bmin[0];
1019 btScalar dy = bmax[1] - bmin[1];
1020 btScalar dz = bmax[2] - bmin[2];
1021
1022 if (dx < EPSILON || dy < EPSILON || dz < EPSILON || vcount < 3)
1023 {
1024 btScalar cx = dx * btScalar(0.5) + bmin[0];
1025 btScalar cy = dy * btScalar(0.5) + bmin[1];
1026 btScalar cz = dz * btScalar(0.5) + bmin[2];
1027
1028 btScalar len = FLT_MAX;
1029
1030 if (dx >= EPSILON && dx < len) len = dx;
1031 if (dy >= EPSILON && dy < len) len = dy;
1032 if (dz >= EPSILON && dz < len) len = dz;
1033
1034 if (len == FLT_MAX)
1035 {
1036 dx = dy = dz = btScalar(0.01); // one centimeter
1037 }
1038 else
1039 {
1040 if (dx < EPSILON) dx = len * btScalar(0.05); // 1/5th the shortest non-zero edge.
1041 if (dy < EPSILON) dy = len * btScalar(0.05);
1042 if (dz < EPSILON) dz = len * btScalar(0.05);
1043 }
1044
1045 btScalar x1 = cx - dx;
1046 btScalar x2 = cx + dx;
1047
1048 btScalar y1 = cy - dy;
1049 btScalar y2 = cy + dy;
1050
1051 btScalar z1 = cz - dz;
1052 btScalar z2 = cz + dz;
1053
1054 vcount = 0; // add box
1055
1056 addPoint(vcount, vertices, x1, y1, z1);
1057 addPoint(vcount, vertices, x2, y1, z1);
1058 addPoint(vcount, vertices, x2, y2, z1);
1059 addPoint(vcount, vertices, x1, y2, z1);
1060 addPoint(vcount, vertices, x1, y1, z2);
1061 addPoint(vcount, vertices, x2, y1, z2);
1062 addPoint(vcount, vertices, x2, y2, z2);
1063 addPoint(vcount, vertices, x1, y2, z2);
1064
1065 return true;
1066 }
1067 }
1068
1069 return true;
1070}
1071
1072 void HullLibrary::BringOutYourDead(const btVector3 *verts, unsigned int vcount, btVector3 *overts, unsigned int &ocount, unsigned int *indices, unsigned indexcount)
1073{
1074 btAlignedObjectArray<int> tmpIndices;
1075 tmpIndices.resize(m_vertexIndexMapping.size());
1076 int i;
1077
1078 for (i = 0; i < m_vertexIndexMapping.size(); i++)
1079 {
1080 tmpIndices[i] = m_vertexIndexMapping[i];
1081 }
1082
1083 TUIntArray usedIndices;
1084 usedIndices.resize(static_cast<int>(vcount));
1085 memset(&usedIndices[0], 0, sizeof(unsigned int) * vcount);
1086
1087 ocount = 0;
1088
1089 for (i = 0; i < int(indexcount); i++)
1090 {
1091 unsigned int v = indices[i]; // original array index
1092
1093 btAssert(v >= 0 && v < vcount);
1094
1095 if (usedIndices[static_cast<int>(v)]) // if already remapped
1096 {
1097 indices[i] = usedIndices[static_cast<int>(v)] - 1; // index to new array
1098 }
1099 else
1100 {
1101 indices[i] = ocount; // new index mapping
1102
1103 overts[ocount][0] = verts[v][0]; // copy old vert to new vert array
1104 overts[ocount][1] = verts[v][1];
1105 overts[ocount][2] = verts[v][2];
1106
1107 for (int k = 0; k < m_vertexIndexMapping.size(); k++)
1108 {
1109 if (tmpIndices[k] == int(v))
1110 m_vertexIndexMapping[k] = ocount;
1111 }
1112
1113 ocount++; // increment output vert count
1114
1115 btAssert(ocount >= 0 && ocount <= vcount);
1116
1117 usedIndices[static_cast<int>(v)] = ocount; // assign new index remapping
1118 }
1119 }
1120}
btAlignedFree
#define btAlignedFree(ptr)
Definition: btAlignedAllocator.h:47
btAlignedAlloc
#define btAlignedAlloc(size, alignment)
Definition: btAlignedAllocator.h:46
btAlignedObjectArray.h
EPSILON
#define EPSILON
HalfEdge
ConvexH::HalfEdge HalfEdge
Definition: btConvexHull.cpp:144
ThreePlaneIntersection
btVector3 ThreePlaneIntersection(const btPlane &p0, const btPlane &p1, const btPlane &p2)
Definition: btConvexHull.cpp:52
DistanceBetweenLines
btScalar DistanceBetweenLines(const btVector3 &ustart, const btVector3 &udir, const btVector3 &vstart, const btVector3 &vdir, btVector3 *upoint=NULL, btVector3 *vpoint=NULL)
Definition: btConvexHull.cpp:111
maxdirsterid
int maxdirsterid(const T *p, int count, const T &dir, btAlignedObjectArray< int > &allow)
Definition: btConvexHull.cpp:233
PlaneLineIntersection
btVector3 PlaneLineIntersection(const btPlane &plane, const btVector3 &p0, const btVector3 &p1)
Definition: btConvexHull.cpp:86
OVER
#define OVER
Definition: btConvexHull.cpp:138
addPoint
static void addPoint(unsigned int &vcount, btVector3 *p, btScalar x, btScalar y, btScalar z)
Definition: btConvexHull.cpp:802
operator==
int operator==(const btPlane &a, const btPlane &b)
Definition: btConvexHull.cpp:43
ReleaseHull
void ReleaseHull(PHullResult &result)
Definition: btConvexHull.cpp:646
COPLANAR
#define COPLANAR
Definition: btConvexHull.cpp:136
hasvert
int hasvert(const int3 &t, int v)
Definition: btConvexHull.cpp:305
PlaneFlip
btPlane PlaneFlip(const btPlane &plane)
Definition: btConvexHull.cpp:42
NormalOf
btVector3 NormalOf(const btVector3 *vert, const int n)
coplanar
int coplanar(const btPlane &a, const btPlane &b)
Definition: btConvexHull.cpp:44
PlaneProject
btVector3 PlaneProject(const btPlane &plane, const btVector3 &point)
Definition: btConvexHull.cpp:96
maxdirfiltered
int maxdirfiltered(const T *p, int count, const T &dir, btAlignedObjectArray< int > &allow)
Definition: btConvexHull.cpp:203
TriNormal
btVector3 TriNormal(const btVector3 &v0, const btVector3 &v1, const btVector3 &v2)
Definition: btConvexHull.cpp:101
UNDER
#define UNDER
Definition: btConvexHull.cpp:137
SplitTest
int SplitTest(ConvexH &convex, const btPlane &plane)
Definition: btConvexHull.cpp:162
hasedge
int hasedge(const int3 &t, int a, int b)
Definition: btConvexHull.cpp:295
above
int above(btVector3 *vertices, const int3 &t, const btVector3 &p, btScalar epsilon)
Definition: btConvexHull.cpp:289
planetestepsilon
btScalar planetestepsilon
Definition: btConvexHull.cpp:142
PlaneTest
int PlaneTest(const btPlane &p, const btVector3 &v)
Definition: btConvexHull.cpp:154
PAPERWIDTH
#define PAPERWIDTH
Definition: btConvexHull.cpp:140
GetDist
btScalar GetDist(btScalar px, btScalar py, btScalar pz, const btScalar *p2)
Definition: btConvexHull.cpp:813
shareedge
int shareedge(const int3 &a, const int3 &b)
Definition: btConvexHull.cpp:310
orth
btVector3 orth(const btVector3 &v)
Definition: btConvexHull.cpp:218
btConvexHull.h
HullError
HullError
Definition: btConvexHull.h:108
QE_OK
@ QE_OK
Definition: btConvexHull.h:109
QE_FAIL
@ QE_FAIL
Definition: btConvexHull.h:110
QF_TRIANGLES
@ QF_TRIANGLES
Definition: btConvexHull.h:50
QF_REVERSE_ORDER
@ QF_REVERSE_ORDER
Definition: btConvexHull.h:51
btMinMax.h
length
btScalar length(const btQuaternion &q)
Return the length of a quaternion.
Definition: btQuaternion.h:895
SIMD_RADS_PER_DEG
#define SIMD_RADS_PER_DEG
Definition: btScalar.h:529
btScalar
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
Definition: btScalar.h:314
btSin
btScalar btSin(btScalar x)
Definition: btScalar.h:499
btFabs
btScalar btFabs(btScalar x)
Definition: btScalar.h:497
btCos
btScalar btCos(btScalar x)
Definition: btScalar.h:498
btSwap
void btSwap(T &a, T &b)
Definition: btScalar.h:643
btAssert
#define btAssert(x)
Definition: btScalar.h:153
btVector3.h
btDot
btScalar btDot(const btVector3 &v1, const btVector3 &v2)
Return the dot product between two vectors.
Definition: btVector3.h:890
btCross
btVector3 btCross(const btVector3 &v1, const btVector3 &v2)
Return the cross product of two vectors.
Definition: btVector3.h:918
ConvexH::HalfEdge
Definition: btConvexHull.h:126
ConvexH
Definition: btConvexHull.h:123
ConvexH::edges
btAlignedObjectArray< HalfEdge > edges
Definition: btConvexHull.h:141
ConvexH::facets
btAlignedObjectArray< btPlane > facets
Definition: btConvexHull.h:142
ConvexH::vertices
btAlignedObjectArray< btVector3 > vertices
Definition: btConvexHull.h:140
ConvexH::ConvexH
ConvexH()
Definition: btConvexHull.h:134
Coplanar
Definition: btConvexHull.cpp:195
Coplanar::ea
unsigned short ea
Definition: btConvexHull.cpp:197
Coplanar::v0
unsigned char v0
Definition: btConvexHull.cpp:198
Coplanar::v1
unsigned char v1
Definition: btConvexHull.cpp:199
EdgeFlag
Definition: btConvexHull.cpp:181
EdgeFlag::overmap
short overmap
Definition: btConvexHull.cpp:186
EdgeFlag::undermap
short undermap
Definition: btConvexHull.cpp:185
EdgeFlag::planetest
unsigned char planetest
Definition: btConvexHull.cpp:183
EdgeFlag::fixes
unsigned char fixes
Definition: btConvexHull.cpp:184
HullDesc
Definition: btConvexHull.h:56
HullDesc::HasHullFlag
bool HasHullFlag(HullFlag flag) const
Definition: btConvexHull.h:82
HullDesc::mVcount
unsigned int mVcount
Definition: btConvexHull.h:99
HullDesc::mNormalEpsilon
btScalar mNormalEpsilon
Definition: btConvexHull.h:102
HullDesc::mMaxVertices
unsigned int mMaxVertices
Definition: btConvexHull.h:103
HullDesc::mVertices
const btVector3 * mVertices
Definition: btConvexHull.h:100
HullDesc::mVertexStride
unsigned int mVertexStride
Definition: btConvexHull.h:101
HullLibrary::extrudable
btHullTriangle * extrudable(btScalar epsilon)
Definition: btConvexHull.cpp:443
HullLibrary::allocateTriangle
class btHullTriangle * allocateTriangle(int a, int b, int c)
Definition: btConvexHull.cpp:403
HullLibrary::ComputeHull
bool ComputeHull(unsigned int vcount, const btVector3 *vertices, PHullResult &result, unsigned int vlimit)
Definition: btConvexHull.cpp:633
HullLibrary::ReleaseResult
HullError ReleaseResult(HullResult &result)
Definition: btConvexHull.cpp:787
HullLibrary::BringOutYourDead
void BringOutYourDead(const btVector3 *verts, unsigned int vcount, btVector3 *overts, unsigned int &ocount, unsigned int *indices, unsigned indexcount)
Definition: btConvexHull.cpp:1072
HullLibrary::CreateConvexHull
HullError CreateConvexHull(const HullDesc &desc, HullResult &result)
Definition: btConvexHull.cpp:670
HullLibrary::deAllocateTriangle
void deAllocateTriangle(btHullTriangle *)
Definition: btConvexHull.cpp:413
HullLibrary::calchull
int calchull(btVector3 *verts, int verts_count, TUIntArray &tris_out, int &tris_count, int vlimit)
Definition: btConvexHull.cpp:605
HullLibrary::m_vertexIndexMapping
btAlignedObjectArray< int > m_vertexIndexMapping
Definition: btConvexHull.h:187
HullLibrary::b2bfix
void b2bfix(btHullTriangle *s, btHullTriangle *t)
Definition: btConvexHull.cpp:355
HullLibrary::removeb2b
void removeb2b(btHullTriangle *s, btHullTriangle *t)
Definition: btConvexHull.cpp:371
HullLibrary::m_tris
btAlignedObjectArray< class btHullTriangle * > m_tris
Definition: btConvexHull.h:184
HullLibrary::checkit
void checkit(btHullTriangle *t)
Definition: btConvexHull.cpp:379
HullLibrary::extrude
void extrude(class btHullTriangle *t0, int v)
Definition: btConvexHull.cpp:421
HullLibrary::calchullgen
int calchullgen(btVector3 *verts, int verts_count, int vlimit)
Definition: btConvexHull.cpp:498
HullLibrary::FindSimplex
int4 FindSimplex(btVector3 *verts, int verts_count, btAlignedObjectArray< int > &allow)
Definition: btConvexHull.cpp:457
HullLibrary::CleanupVertices
bool CleanupVertices(unsigned int svcount, const btVector3 *svertices, unsigned int stride, unsigned int &vcount, btVector3 *vertices, btScalar normalepsilon, btVector3 &scale)
Definition: btConvexHull.cpp:822
HullResult
Definition: btConvexHull.h:28
HullResult::m_OutputVertices
btAlignedObjectArray< btVector3 > m_OutputVertices
Definition: btConvexHull.h:39
HullResult::m_Indices
btAlignedObjectArray< unsigned int > m_Indices
Definition: btConvexHull.h:42
HullResult::mNumOutputVertices
unsigned int mNumOutputVertices
Definition: btConvexHull.h:38
HullResult::mNumFaces
unsigned int mNumFaces
Definition: btConvexHull.h:40
HullResult::mPolygons
bool mPolygons
Definition: btConvexHull.h:37
HullResult::mNumIndices
unsigned int mNumIndices
Definition: btConvexHull.h:41
PHullResult
Definition: btConvexHull.h:163
PHullResult::mFaceCount
unsigned int mFaceCount
Definition: btConvexHull.h:175
PHullResult::mVcount
unsigned int mVcount
Definition: btConvexHull.h:173
PHullResult::mIndexCount
unsigned int mIndexCount
Definition: btConvexHull.h:174
PHullResult::mVertices
btVector3 * mVertices
Definition: btConvexHull.h:176
PHullResult::m_Indices
TUIntArray m_Indices
Definition: btConvexHull.h:177
PlaneFlag
Definition: btConvexHull.cpp:189
PlaneFlag::overmap
unsigned char overmap
Definition: btConvexHull.cpp:192
PlaneFlag::undermap
unsigned char undermap
Definition: btConvexHull.cpp:191
VertFlag
Definition: btConvexHull.cpp:173
VertFlag::junk
unsigned char junk
Definition: btConvexHull.cpp:176
VertFlag::undermap
unsigned char undermap
Definition: btConvexHull.cpp:177
VertFlag::overmap
unsigned char overmap
Definition: btConvexHull.cpp:178
VertFlag::planetest
unsigned char planetest
Definition: btConvexHull.cpp:175
btAlignedObjectArray< int >
btAlignedObjectArray::size
int size() const
return the number of elements in the array
Definition: btAlignedObjectArray.h:142
btAlignedObjectArray::resize
void resize(int newsize, const T &fillData=T())
Definition: btAlignedObjectArray.h:203
btAlignedObjectArray::clear
void clear()
clear the array, deallocated memory. Generally it is better to use array.resize(0),...
Definition: btAlignedObjectArray.h:176
btAlignedObjectArray::push_back
void push_back(const T &_Val)
Definition: btAlignedObjectArray.h:257
btAlignedObjectArray::reserve
void reserve(int _Count)
Definition: btAlignedObjectArray.h:280
btHullTriangle
Definition: btConvexHull.cpp:324
btHullTriangle::vmax
int vmax
Definition: btConvexHull.cpp:328
btHullTriangle::id
int id
Definition: btConvexHull.cpp:327
btHullTriangle::rise
btScalar rise
Definition: btConvexHull.cpp:329
btHullTriangle::~btHullTriangle
~btHullTriangle()
Definition: btConvexHull.cpp:335
btHullTriangle::n
int3 n
Definition: btConvexHull.cpp:326
btHullTriangle::neib
int & neib(int a, int b)
Definition: btConvexHull.cpp:341
btHullTriangle::btHullTriangle
btHullTriangle(int a, int b, int c)
Definition: btConvexHull.cpp:330
btPlane
Definition: btConvexHull.h:114
btPlane::normal
btVector3 normal
Definition: btConvexHull.h:116
btPlane::dist
btScalar dist
Definition: btConvexHull.h:117
btVector3
btVector3 can be used to represent 3D points and vectors.
Definition: btVector3.h:82
btVector3::getZ
const btScalar & getZ() const
Return the z value.
Definition: btVector3.h:565
btVector3::setMax
void setMax(const btVector3 &other)
Set each element to the max of the current values and the values of another btVector3.
Definition: btVector3.h:609
btVector3::length
btScalar length() const
Return the length of the vector.
Definition: btVector3.h:257
btVector3::cross
btVector3 cross(const btVector3 &v) const
Return the cross product between this and another vector.
Definition: btVector3.h:380
btVector3::dot
btScalar dot(const btVector3 &v) const
Return the dot product.
Definition: btVector3.h:229
btVector3::normalized
btVector3 normalized() const
Return a normalized version of this vector.
Definition: btVector3.h:949
btVector3::getY
const btScalar & getY() const
Return the y value.
Definition: btVector3.h:563
btVector3::normalize
btVector3 & normalize()
Normalize this vector x^2 + y^2 + z^2 = 1.
Definition: btVector3.h:303
btVector3::getX
const btScalar & getX() const
Return the x value.
Definition: btVector3.h:561
int3
Definition: btConvexHull.cpp:26
int3::x
int x
Definition: btConvexHull.cpp:28
int3::operator[]
int & operator[](int i)
Definition: btConvexHull.cpp:37
int3::z
int z
Definition: btConvexHull.cpp:28
int3::y
int y
Definition: btConvexHull.cpp:28
int3::int3
int3(int _x, int _y, int _z)
Definition: btConvexHull.cpp:30
int3::operator[]
const int & operator[](int i) const
Definition: btConvexHull.cpp:36
int3::int3
int3()
Definition: btConvexHull.cpp:29
int4
Definition: btConvexHull.h:147
int4::x
int x
Definition: btConvexHull.h:149