49 #if defined(DEBUG) || defined(_DEBUG) 52 #include <spu_printf.h> 53 #define printf spu_printf 60 #define GJK_MAX_ITERATIONS 128 61 #define GJK_ACCURARY ((btScalar)0.0001) 62 #define GJK_MIN_DISTANCE ((btScalar)0.0001) 63 #define GJK_DUPLICATED_EPS ((btScalar)0.0001) 64 #define GJK_SIMPLEX2_EPS ((btScalar)0.0) 65 #define GJK_SIMPLEX3_EPS ((btScalar)0.0) 66 #define GJK_SIMPLEX4_EPS ((btScalar)0.0) 69 #define EPA_MAX_VERTICES 64 70 #define EPA_MAX_FACES (EPA_MAX_VERTICES * 2) 71 #define EPA_MAX_ITERATIONS 255 72 #define EPA_ACCURACY ((btScalar)0.0001) 73 #define EPA_FALLBACK (10 * EPA_ACCURACY) 74 #define EPA_PLANE_EPS ((btScalar)0.00001) 75 #define EPA_INSIDE_EPS ((btScalar)0.01) 78 typedef unsigned int U;
79 typedef unsigned char U1;
82 template <
typename btConvexTemplate>
101 m_enableMargin = enable;
105 return m_convexAPtr->getLocalSupportWithMargin(d);
109 return m_toshape0 * m_convexBPtr->getLocalSupportWithMargin(m_toshape1 * d);
114 return (Support0(d) - Support1(-d));
119 return (Support1(d));
121 return (Support0(d));
133 template <
typename btConvexTemplate>
162 GJK(
const btConvexTemplate& a,
const btConvexTemplate& b)
183 m_free[0] = &m_store[0];
184 m_free[1] = &m_store[1];
185 m_free[2] = &m_store[2];
186 m_free[3] = &m_store[3];
193 m_simplices[0].
rank = 0;
196 appendvertice(m_simplices[0], sqrl > 0 ? -m_ray :
btVector3(1, 0, 0));
197 m_simplices[0].
p[0] = 1;
198 m_ray = m_simplices[0].
c[0]->
w;
207 const U next = 1 - m_current;
208 sSimplex& cs = m_simplices[m_current];
218 appendvertice(cs, -m_ray);
221 for (
U i = 0; i < 4; ++i)
231 removevertice(m_simplices[m_current]);
236 lastw[clastw = (clastw + 1) & 3] = w;
240 alpha =
btMax(omega, alpha);
243 removevertice(m_simplices[m_current]);
252 sqdist = projectorigin(cs.
c[0]->
w,
257 sqdist = projectorigin(cs.
c[0]->
w,
263 sqdist = projectorigin(cs.
c[0]->
w,
275 for (
U i = 0, ni = cs.
rank; i < ni; ++i)
280 ns.
p[ns.
rank++] = weights[i];
281 m_ray += cs.
c[i]->
w * weights[i];
285 m_free[m_nfree++] = cs.
c[i];
292 removevertice(m_simplices[m_current]);
297 m_simplex = &m_simplices[m_current];
301 m_distance = m_ray.
length();
314 switch (m_simplex->
rank)
318 for (
U i = 0; i < 3; ++i)
322 appendvertice(*m_simplex, axis);
323 if (EncloseOrigin())
return (
true);
324 removevertice(*m_simplex);
325 appendvertice(*m_simplex, -axis);
326 if (EncloseOrigin())
return (
true);
327 removevertice(*m_simplex);
334 for (
U i = 0; i < 3; ++i)
341 appendvertice(*m_simplex, p);
342 if (EncloseOrigin())
return (
true);
343 removevertice(*m_simplex);
344 appendvertice(*m_simplex, -p);
345 if (EncloseOrigin())
return (
true);
346 removevertice(*m_simplex);
354 m_simplex->
c[2]->
w - m_simplex->
c[0]->
w);
357 appendvertice(*m_simplex, n);
358 if (EncloseOrigin())
return (
true);
359 removevertice(*m_simplex);
360 appendvertice(*m_simplex, -n);
361 if (EncloseOrigin())
return (
true);
362 removevertice(*m_simplex);
368 if (
btFabs(det(m_simplex->
c[0]->
w - m_simplex->
c[3]->
w,
369 m_simplex->
c[1]->
w - m_simplex->
c[3]->
w,
370 m_simplex->
c[2]->
w - m_simplex->
c[3]->
w)) > 0)
385 m_free[m_nfree++] = simplex.
c[--simplex.
rank];
389 simplex.
p[simplex.
rank] = 0;
390 simplex.
c[simplex.
rank] = m_free[--m_nfree];
391 getsupport(v, *simplex.
c[simplex.
rank++]);
395 return (a.
y() * b.
z() * c.
x() + a.
z() * b.
x() * c.
y() -
396 a.
x() * b.
z() * c.
y() - a.
y() * b.
x() * c.
z() +
397 a.
x() * b.
y() * c.
z() - a.
z() * b.
y() * c.
x());
420 return (a.length2());
424 w[0] = 1 - (w[1] = t);
426 return ((a + d * t).length2());
436 static const U imd3[] = {1, 2, 0};
438 const btVector3 dl[] = {a - b, b - c, c - a};
446 for (
U i = 0; i < 3; ++i)
451 const btScalar subd(projectorigin(*vt[i], *vt[j], subw, subm));
452 if ((mindist < 0) || (subd < mindist))
455 m =
static_cast<U>(((subm & 1) ? 1 << i : 0) + ((subm & 2) ? 1 << j : 0));
471 w[2] = 1 - (w[0] + w[1]);
483 static const U imd3[] = {1, 2, 0};
484 const btVector3* vt[] = {&a, &b, &c, &d};
485 const btVector3 dl[] = {a - d, b - d, c - d};
486 const btScalar vl = det(dl[0], dl[1], dl[2]);
487 const bool ng = (vl *
btDot(a,
btCross(b - c, a - b))) <= 0;
493 for (
U i = 0; i < 3; ++i)
499 const btScalar subd = projectorigin(*vt[i], *vt[j], d, subw, subm);
500 if ((mindist < 0) || (subd < mindist))
503 m =
static_cast<U>((subm & 1 ? 1 << i : 0) +
504 (subm & 2 ? 1 << j : 0) +
517 w[0] = det(c, b, d) / vl;
518 w[1] = det(a, c, d) / vl;
519 w[2] = det(b, a, d) / vl;
520 w[3] = 1 - (w[0] + w[1] + w[2]);
543 template <
typename btConvexTemplate>
598 face->
l[1] = list.
root;
605 if (face->l[1]) face->l[1]->l[0] = face->l[0];
606 if (face->l[0]) face->l[0]->l[1] = face->l[1];
607 if (face == list.root) list.root = face->l[1];
619 append(m_stock, &m_fc_store[EPA_MAX_FACES - i - 1]);
637 if (gjk.
det(simplex.
c[0]->
w - simplex.
c[3]->
w,
638 simplex.
c[1]->
w - simplex.
c[3]->
w,
639 simplex.
c[2]->
w - simplex.
c[3]->
w) < 0)
645 sFace* tetra[] = {newface(simplex.
c[0], simplex.
c[1], simplex.
c[2],
true),
646 newface(simplex.
c[1], simplex.
c[0], simplex.
c[3],
true),
647 newface(simplex.
c[2], simplex.
c[1], simplex.
c[3],
true),
648 newface(simplex.
c[0], simplex.
c[2], simplex.
c[3],
true)};
649 if (m_hull.
count == 4)
651 sFace* best = findbest();
655 bind(tetra[0], 0, tetra[1], 0);
656 bind(tetra[0], 1, tetra[2], 0);
657 bind(tetra[0], 2, tetra[3], 0);
658 bind(tetra[1], 1, tetra[3], 2);
659 bind(tetra[1], 2, tetra[2], 1);
660 bind(tetra[2], 2, tetra[3], 1);
669 best->
pass = (
U1)(++pass);
674 for (
U j = 0; (j < 3) && valid; ++j)
676 valid &= expand(pass, w,
677 best->
f[j], best->
e[j],
680 if (valid && (horizon.
nf >= 3))
682 bind(horizon.
cf, 1, horizon.
ff, 2);
683 remove(m_hull, best);
684 append(m_stock, best);
710 m_result.
c[0] = outer.
c[0];
711 m_result.
c[1] = outer.
c[1];
712 m_result.
c[2] = outer.
c[2];
713 m_result.
p[0] =
btCross(outer.
c[1]->w - projection,
714 outer.
c[2]->w - projection)
716 m_result.
p[1] =
btCross(outer.
c[2]->w - projection,
717 outer.
c[0]->w - projection)
719 m_result.
p[2] =
btCross(outer.
c[0]->w - projection,
720 outer.
c[1]->w - projection)
722 const btScalar sum = m_result.
p[0] + m_result.
p[1] + m_result.
p[2];
723 m_result.
p[0] /=
sum;
724 m_result.
p[1] /=
sum;
725 m_result.
p[2] /=
sum;
734 m_normal = m_normal / nl;
739 m_result.
c[0] = simplex.
c[0];
762 else if (b_dot_ba < 0)
784 remove(m_stock, face);
785 append(m_hull, face);
796 if (!(getedgedist(face, a, b, face->
d) ||
797 getedgedist(face, b, c, face->
d) ||
798 getedgedist(face, c, a, face->
d)))
816 remove(m_hull, face);
817 append(m_stock, face);
827 for (
sFace* f = minf->
l[1]; f; f = f->
l[1])
840 static const U i1m3[] = {1, 2, 0};
841 static const U i2m3[] = {2, 0, 1};
844 const U e1 = i1m3[e];
847 sFace* nf = newface(f->
c[e1], f->
c[e], w,
false);
852 bind(horizon.
cf, 1, nf, 2);
862 const U e2 = i2m3[e];
864 if (expand(pass, w, f->
f[e1], f->
e[e1], horizon) &&
865 expand(pass, w, f->
f[e2], f->
e[e2], horizon))
877 template <
typename btConvexTemplate>
878 static void Initialize(
const btConvexTemplate& a,
const btConvexTemplate& b,
897 template <
typename btConvexTemplate>
916 results.
witnesses[0] = a.getWorldTransform() * w0;
917 results.
witnesses[1] = a.getWorldTransform() * w1;
930 template <
typename btConvexTemplate>
932 const btConvexTemplate& b,
949 for (
U i = 0; i < epa.
m_result.rank; ++i)
954 results.
witnesses[0] = a.getWorldTransform() * w0;
975 int btComputeGjkEpaPenetration2(
const btCollisionDescription& colDesc, btDistanceInfo* distInfo)
980 bool res = btGjkEpaSolver3::Penetration(colDesc.m_objA,colDesc.m_objB,
981 colDesc.m_transformA,colDesc.m_transformB,
982 colDesc.m_localSupportFuncA,colDesc.m_localSupportFuncB,
991 distInfo->m_distance = results.
distance;
992 distInfo->m_normalBtoA = results.
normal;
997 tmpNormalInB = results.
normal;
1001 if (lenSqr > (SIMD_EPSILON*SIMD_EPSILON))
1003 tmpNormalInB /=
btSqrt(lenSqr);
1008 distInfo->m_distance = distance2;
1009 distInfo->m_pointOnA= results.
witnesses[0];
1010 distInfo->m_pointOnB= results.
witnesses[1];
1011 distInfo->m_normalBtoA= tmpNormalInB;
1023 template <
typename btConvexTemplate,
typename btDistanceInfoTemplate>
1035 distInfo->m_distance = results.
distance;
1036 distInfo->m_pointOnA = results.
witnesses[0];
1037 distInfo->m_pointOnB = results.
witnesses[1];
1038 distInfo->m_normalBtoA = results.
normal;
1047 #undef GJK_MAX_ITERATIONS 1049 #undef GJK_MIN_DISTANCE 1050 #undef GJK_DUPLICATED_EPS 1051 #undef GJK_SIMPLEX2_EPS 1052 #undef GJK_SIMPLEX3_EPS 1053 #undef GJK_SIMPLEX4_EPS 1055 #undef EPA_MAX_VERTICES 1056 #undef EPA_MAX_FACES 1057 #undef EPA_MAX_ITERATIONS 1060 #undef EPA_PLANE_EPS 1061 #undef EPA_INSIDE_EPS 1063 #endif //BT_GJK_EPA3_H static T sum(const btAlignedObjectArray< T > &items)
bool btGjkEpaSolver3_Penetration(const btConvexTemplate &a, const btConvexTemplate &b, const btVector3 &guess, btGjkEpaSolver3::sResults &results)
btScalar length(const btQuaternion &q)
Return the length of a quaternion.
btVector3 Support(const btVector3 &d) const
eEpaStatus Evaluate(GJK< btConvexTemplate > &gjk, const btVector3 &guess)
int btComputeGjkDistance(const btConvexTemplate &a, const btConvexTemplate &b, const btGjkCollisionDescription &colDesc, btDistanceInfoTemplate *distInfo)
#define GJK_MAX_ITERATIONS
btScalar length2() const
Return the length of the vector squared.
const btConvexTemplate * m_convexBPtr
btScalar btSqrt(btScalar y)
const btConvexTemplate * m_convexAPtr
static void append(sList &list, sFace *face)
static btScalar projectorigin(const btVector3 &a, const btVector3 &b, btScalar *w, U &m)
btVector3 btCross(const btVector3 &v1, const btVector3 &v2)
Return the cross product of two vectors.
static void Initialize(const btConvexTemplate &a, const btConvexTemplate &b, btGjkEpaSolver3::sResults &results, MinkowskiDiff< btConvexTemplate > &shape)
#define GJK_DUPLICATED_EPS
btMatrix3x3 transposeTimes(const btMatrix3x3 &m) const
void EnableMargin(bool enable)
static btScalar projectorigin(const btVector3 &a, const btVector3 &b, const btVector3 &c, btScalar *w, U &m)
eGjkStatus Evaluate(const MinkowskiDiff< btConvexTemplate > &shapearg, const btVector3 &guess)
const btScalar & x() const
Return the x value.
MinkowskiDiff(const btConvexTemplate &a, const btConvexTemplate &b)
static btScalar projectorigin(const btVector3 &a, const btVector3 &b, const btVector3 &c, const btVector3 &d, btScalar *w, U &m)
const btScalar & y() const
Return the y value.
const btScalar & z() const
Return the z value.
btVector3 Support1(const btVector3 &d) const
bool expand(U pass, typename GJK< btConvexTemplate >::sSV *w, sFace *f, U e, sHorizon &horizon)
GJK< btConvexTemplate >::sSV * c[3]
btVector3 can be used to represent 3D points and vectors.
MinkowskiDiff< btConvexTemplate > m_shape
btVector3 Support(const btVector3 &d, U index) const
static btScalar det(const btVector3 &a, const btVector3 &b, const btVector3 &c)
sFace * newface(typename GJK< btConvexTemplate >::sSV *a, typename GJK< btConvexTemplate >::sSV *b, typename GJK< btConvexTemplate >::sSV *c, bool forced)
bool btGjkEpaSolver3_Distance(const btConvexTemplate &a, const btConvexTemplate &b, const btVector3 &guess, btGjkEpaSolver3::sResults &results)
static void bind(sFace *fa, U ea, sFace *fb, U eb)
btVector3 Support0(const btVector3 &d) const
void getsupport(const btVector3 &d, sSV &sv) const
void appendvertice(sSimplex &simplex, const btVector3 &v)
void removevertice(sSimplex &simplex)
const T & btMax(const T &a, const T &b)
GJK< btConvexTemplate >::sSimplex m_result
#define EPA_MAX_ITERATIONS
bool getedgedist(sFace *face, typename GJK< btConvexTemplate >::sSV *a, typename GJK< btConvexTemplate >::sSV *b, btScalar &dist)
The btMatrix3x3 class implements a 3x3 rotation matrix, to perform linear algebra in combination with...
enum btGjkEpaSolver3::sResults::eStatus status
btScalar btDot(const btVector3 &v1, const btVector3 &v2)
Return the dot product between two vectors.
GJK(const btConvexTemplate &a, const btConvexTemplate &b)
float btScalar
The btScalar type abstracts floating point numbers, to easily switch between double and single floati...
btScalar length() const
Return the length of the vector.
btScalar btFabs(btScalar x)