21 #include "../PlatformDefinitions.h"
24 static inline float sqr(
float a )
45 #define AaxisTest( dim, letter, first ) \
49 maxGap = gap = gapsA.get##letter(); \
50 if ( gap > distanceThreshold ) return gap; \
53 axisA = identity.getCol##dim(); \
57 gap = gapsA.get##letter(); \
58 if ( gap > distanceThreshold ) return gap; \
59 else if ( gap > maxGap ) \
64 axisA = identity.getCol##dim(); \
70 #define BaxisTest( dim, letter ) \
72 gap = gapsB.get##letter(); \
73 if ( gap > distanceThreshold ) return gap; \
74 else if ( gap > maxGap ) \
79 axisB = identity.getCol##dim(); \
83 #define CrossAxisTest( dima, dimb, letterb ) \
85 const float lsqr_tolerance = 1.0e-30f; \
88 lsqr = lsqrs.getCol##dima().get##letterb(); \
90 if ( lsqr > lsqr_tolerance ) \
92 float l_recip = 1.0f / sqrtf( lsqr ); \
93 gap = float(gapsAxB.getCol##dima().get##letterb()) * l_recip; \
95 if ( gap > distanceThreshold ) \
100 if ( gap > maxGap ) \
103 axisType = CROSS_AXIS; \
106 axisA = cross(identity.getCol##dima(),matrixAB.getCol##dimb()) * l_recip; \
141 else if ( t0 < -hA[0] )
145 else if ( t1 < -hA[1] )
154 inVoronoi = ( ( facePointB[0] >=
voronoiTol * facePointB[2] ) &&
155 ( facePointB[1] >=
voronoiTol * facePointB[0] ) &&
156 ( facePointB[2] >=
voronoiTol * facePointB[1] ) );
158 return (
sqr( corner[0] - t0 ) +
sqr( corner[1] - t1 ) +
sqr( corner[2] ));
161 #define VertexBFaceA_SetNewMin() \
163 minDistSqr = distSqr; \
164 localPointA.setX(t0); \
165 localPointA.setY(t1); \
166 localPointB.setX( scalesB.getX() ); \
167 localPointB.setY( scalesB.getY() ); \
194 matrixAB, matrixBA, signsB, scalesB );
199 if ( distSqr < minDistSqr ) {
211 matrixAB, matrixBA, signsB, scalesB );
213 if ( distSqr < minDistSqr ) {
224 matrixAB, matrixBA, signsB, scalesB );
226 if ( distSqr < minDistSqr ) {
237 matrixAB, matrixBA, signsB, scalesB );
239 if ( distSqr < minDistSqr ) {
270 else if ( t0 < -hB[0] )
274 else if ( t1 < -hB[1] )
280 inVoronoi = ( ( facePointA[0] >=
voronoiTol * facePointA[2] ) &&
281 ( facePointA[1] >=
voronoiTol * facePointA[0] ) &&
282 ( facePointA[2] >=
voronoiTol * facePointA[1] ) );
284 return (
sqr( corner[0] - t0 ) +
sqr( corner[1] - t1 ) +
sqr( corner[2] ));
287 #define VertexAFaceB_SetNewMin() \
289 minDistSqr = distSqr; \
290 localPointB.setX(t0); \
291 localPointB.setY(t1); \
292 localPointA.setX( scalesA.getX() ); \
293 localPointA.setY( scalesA.getY() ); \
319 matrixAB, matrixBA, signsA, scalesA );
324 if ( distSqr < minDistSqr ) {
336 matrixAB, matrixBA, signsA, scalesA );
338 if ( distSqr < minDistSqr ) {
349 matrixAB, matrixBA, signsA, scalesA );
351 if ( distSqr < minDistSqr ) {
362 matrixAB, matrixBA, signsA, scalesA );
364 if ( distSqr < minDistSqr ) {
381 #define CustomEdgeEdgeTest( ac, ac_letter, ad, ad_letter, bc, bc_letter, bd, bd_letter ) \
383 vmVector3 edgeOffsetAB; \
384 vmVector3 edgeOffsetBA; \
386 edgeOffsetAB = faceOffsetAB + matrixAB.getCol##bc() * scalesB.get##bc_letter(); \
387 edgeOffsetAB.set##ac_letter( edgeOffsetAB.get##ac_letter() - scalesA.get##ac_letter() ); \
389 edgeOffsetBA = faceOffsetBA + matrixBA.getCol##ac() * scalesA.get##ac_letter(); \
390 edgeOffsetBA.set##bc_letter( edgeOffsetBA.get##bc_letter() - scalesB.get##bc_letter() ); \
392 float dirDot = matrixAB.getCol##bd().get##ad_letter(); \
393 float denom = 1.0f - dirDot*dirDot; \
394 float edgeOffsetAB_ad = edgeOffsetAB.get##ad_letter(); \
395 float edgeOffsetBA_bd = edgeOffsetBA.get##bd_letter(); \
397 if ( denom == 0.0f ) \
403 tA = ( edgeOffsetAB_ad + edgeOffsetBA_bd * dirDot ) / denom; \
406 if ( tA < -hA[ad] ) tA = -hA[ad]; \
407 else if ( tA > hA[ad] ) tA = hA[ad]; \
409 tB = tA * dirDot + edgeOffsetBA_bd; \
411 if ( tB < -hB[bd] ) \
414 tA = tB * dirDot + edgeOffsetAB_ad; \
416 if ( tA < -hA[ad] ) tA = -hA[ad]; \
417 else if ( tA > hA[ad] ) tA = hA[ad]; \
419 else if ( tB > hB[bd] ) \
422 tA = tB * dirDot + edgeOffsetAB_ad; \
424 if ( tA < -hA[ad] ) tA = -hA[ad]; \
425 else if ( tA > hA[ad] ) tA = hA[ad]; \
428 vmVector3 edgeOffAB = vmVector3( mulPerElem( edgeOffsetAB + matrixAB.getCol##bd() * tB, signsA ) );\
429 vmVector3 edgeOffBA = vmVector3( mulPerElem( edgeOffsetBA + matrixBA.getCol##ad() * tA, signsB ) );\
431 inVoronoi = ( edgeOffAB[ac] >= voronoiTol * edgeOffAB[2] ) && \
432 ( edgeOffAB[2] >= voronoiTol * edgeOffAB[ac] ) && \
433 ( edgeOffBA[bc] >= voronoiTol * edgeOffBA[2] ) && \
434 ( edgeOffBA[2] >= voronoiTol * edgeOffBA[bc] ); \
436 edgeOffAB[ad] -= tA; \
437 edgeOffBA[bd] -= tB; \
439 return dot(edgeOffAB,edgeOffAB); \
518 #define EdgeEdge_SetNewMin( ac_letter, ad_letter, bc_letter, bd_letter ) \
520 minDistSqr = distSqr; \
521 localPointA.set##ac_letter(scalesA.get##ac_letter()); \
522 localPointA.set##ad_letter(tA); \
523 localPointB.set##bc_letter(scalesB.get##bc_letter()); \
524 localPointB.set##bd_letter(tB); \
525 otherFaceDimA = testOtherFaceDimA; \
526 otherFaceDimB = testOtherFaceDimB; \
557 int testOtherFaceDimA, testOtherFaceDimB;
559 testOtherFaceDimA = 0;
560 testOtherFaceDimB = 0;
563 matrixAB, matrixBA, signsA, signsB, scalesA, scalesB );
568 if ( distSqr < minDistSqr ) {
580 matrixAB, matrixBA, signsA, signsB, scalesA, scalesB );
582 if ( distSqr < minDistSqr ) {
593 matrixAB, matrixBA, signsA, signsB, scalesA, scalesB );
595 if ( distSqr < minDistSqr ) {
606 matrixAB, matrixBA, signsA, signsB, scalesA, scalesB );
608 if ( distSqr < minDistSqr ) {
615 testOtherFaceDimA = 1;
616 testOtherFaceDimB = 0;
621 matrixAB, matrixBA, signsA, signsB, scalesA, scalesB );
623 if ( distSqr < minDistSqr ) {
634 matrixAB, matrixBA, signsA, signsB, scalesA, scalesB );
636 if ( distSqr < minDistSqr ) {
647 matrixAB, matrixBA, signsA, signsB, scalesA, scalesB );
649 if ( distSqr < minDistSqr ) {
660 matrixAB, matrixBA, signsA, signsB, scalesA, scalesB );
662 if ( distSqr < minDistSqr ) {
669 testOtherFaceDimA = 0;
670 testOtherFaceDimB = 1;
675 matrixAB, matrixBA, signsA, signsB, scalesA, scalesB );
677 if ( distSqr < minDistSqr ) {
688 matrixAB, matrixBA, signsA, signsB, scalesA, scalesB );
690 if ( distSqr < minDistSqr ) {
701 matrixAB, matrixBA, signsA, signsB, scalesA, scalesB );
703 if ( distSqr < minDistSqr ) {
714 matrixAB, matrixBA, signsA, signsB, scalesA, scalesB );
716 if ( distSqr < minDistSqr ) {
723 testOtherFaceDimA = 1;
724 testOtherFaceDimB = 1;
729 matrixAB, matrixBA, signsA, signsB, scalesA, scalesB );
731 if ( distSqr < minDistSqr ) {
742 matrixAB, matrixBA, signsA, signsB, scalesA, scalesB );
744 if ( distSqr < minDistSqr ) {
755 matrixAB, matrixBA, signsA, signsB, scalesA, scalesB );
757 if ( distSqr < minDistSqr ) {
768 matrixAB, matrixBA, signsA, signsB, scalesA, scalesB );
770 if ( distSqr < minDistSqr ) {
780 float distanceThreshold)
811 int faceDimA = 0, faceDimB = 0, edgeDimA = 0, edgeDimB = 0;
833 vmMatrix3 lsqrs, projOffset, projAhalf, projBhalf;
870 int dimA[3], dimB[3];
872 if ( axisType ==
A_AXIS ) {
873 if (
dot(axisA,offsetAB) < 0.0f )
875 axisB = matrixBA * -axisA;
879 if ( ( absAxisB[0] > absAxisB[1] ) && ( absAxisB[0] > absAxisB[2] ) )
881 else if ( absAxisB[1] > absAxisB[2] )
885 }
else if ( axisType ==
B_AXIS ) {
886 if (
dot(axisB,offsetBA) < 0.0f )
888 axisA = matrixAB * -axisB;
892 if ( ( absAxisA[0] > absAxisA[1] ) && ( absAxisA[0] > absAxisA[2] ) )
894 else if ( absAxisA[1] > absAxisA[2] )
901 if (
dot(axisA,offsetAB) < 0.0f )
903 axisB = matrixBA * -axisA;
911 if ( edgeDimA == 0 ) {
912 if ( absAxisA[1] > absAxisA[2] ) {
919 }
else if ( edgeDimA == 1 ) {
920 if ( absAxisA[2] > absAxisA[0] ) {
928 if ( absAxisA[0] > absAxisA[1] ) {
937 if ( edgeDimB == 0 ) {
938 if ( absAxisB[1] > absAxisB[2] ) {
945 }
else if ( edgeDimB == 1 ) {
946 if ( absAxisB[2] > absAxisB[0] ) {
954 if ( absAxisB[0] > absAxisB[1] ) {
964 dimA[0] = (faceDimA+1)%3;
965 dimA[1] = (faceDimA+2)%3;
967 dimB[0] = (faceDimB+1)%3;
968 dimB[1] = (faceDimB+2)%3;
973 aperm_col.
setCol0(ident[dimA[0]]);
974 aperm_col.
setCol1(ident[dimA[1]]);
975 aperm_col.
setCol2(ident[dimA[2]]);
977 bperm_col.
setCol0(ident[dimB[0]]);
978 bperm_col.
setCol1(ident[dimB[1]]);
979 bperm_col.
setCol2(ident[dimB[2]]);
988 vmMatrix3 matrixAB_perm = aperm_row * matrixAB * bperm_col;
993 offsetAB_perm = aperm_row * offsetAB;
994 offsetBA_perm = bperm_row * offsetBA;
998 halfA_perm = aperm_row * boxA.
mHalf;
999 halfB_perm = bperm_row * boxB.
mHalf;
1003 vmVector3 signsA_perm, signsB_perm, scalesA_perm, scalesB_perm, faceOffsetAB_perm, faceOffsetBA_perm;
1007 scalesA_perm =
mulPerElem( signsA_perm, halfA_perm );
1008 scalesB_perm =
mulPerElem( signsB_perm, halfB_perm );
1010 faceOffsetAB_perm = offsetAB_perm + matrixAB_perm.
getCol2() * scalesB_perm.
getZ();
1011 faceOffsetAB_perm.
setZ( faceOffsetAB_perm.
getZ() - scalesA_perm.
getZ() );
1013 faceOffsetBA_perm = offsetBA_perm + matrixBA_perm.
getCol2() * scalesA_perm.
getZ();
1014 faceOffsetBA_perm.
setZ( faceOffsetBA_perm.
getZ() - scalesB_perm.
getZ() );
1016 if ( maxGap < 0.0f ) {
1019 faceOffsetAB_perm -= aperm_row * axisA * maxGap * 1.01f;
1020 faceOffsetBA_perm -= bperm_row * axisB * maxGap * 1.01f;
1036 vmPoint3 localPointA_perm, localPointB_perm;
1040 vmVector3 hA_perm( halfA_perm ), hB_perm( halfB_perm );
1042 localPointA_perm.
setZ( scalesA_perm.
getZ() );
1043 localPointB_perm.
setZ( scalesB_perm.
getZ() );
1044 scalesA_perm.
setZ(0.0f);
1045 scalesB_perm.
setZ(0.0f);
1047 int otherFaceDimA, otherFaceDimB;
1051 EdgeEdgeTests( done, minDistSqr, localPointA_perm, localPointB_perm,
1052 otherFaceDimA, otherFaceDimB, featureA, featureB,
1053 hA_perm, hB_perm, faceOffsetAB_perm, faceOffsetBA_perm,
1054 matrixAB_perm, matrixBA_perm, signsA_perm, signsB_perm,
1055 scalesA_perm, scalesB_perm,
true );
1060 hA_perm, faceOffsetAB_perm, faceOffsetBA_perm,
1061 matrixAB_perm, matrixBA_perm, signsB_perm, scalesB_perm,
false );
1066 hB_perm, faceOffsetAB_perm, faceOffsetBA_perm,
1067 matrixAB_perm, matrixBA_perm, signsA_perm, scalesA_perm,
false );
1070 }
else if ( axisType ==
B_AXIS ) {
1073 hB_perm, faceOffsetAB_perm, faceOffsetBA_perm,
1074 matrixAB_perm, matrixBA_perm, signsA_perm, scalesA_perm,
true );
1079 hA_perm, faceOffsetAB_perm, faceOffsetBA_perm,
1080 matrixAB_perm, matrixBA_perm, signsB_perm, scalesB_perm,
false );
1083 EdgeEdgeTests( done, minDistSqr, localPointA_perm, localPointB_perm,
1084 otherFaceDimA, otherFaceDimB, featureA, featureB,
1085 hA_perm, hB_perm, faceOffsetAB_perm, faceOffsetBA_perm,
1086 matrixAB_perm, matrixBA_perm, signsA_perm, signsB_perm,
1087 scalesA_perm, scalesB_perm,
false );
1093 hA_perm, faceOffsetAB_perm, faceOffsetBA_perm,
1094 matrixAB_perm, matrixBA_perm, signsB_perm, scalesB_perm,
true );
1099 hB_perm, faceOffsetAB_perm, faceOffsetBA_perm,
1100 matrixAB_perm, matrixBA_perm, signsA_perm, scalesA_perm,
false );
1103 EdgeEdgeTests( done, minDistSqr, localPointA_perm, localPointB_perm,
1104 otherFaceDimA, otherFaceDimB, featureA, featureB,
1105 hA_perm, hB_perm, faceOffsetAB_perm, faceOffsetBA_perm,
1106 matrixAB_perm, matrixBA_perm, signsA_perm, signsB_perm,
1107 scalesA_perm, scalesB_perm,
false );
1136 if ( featureA ==
F ) {
1138 }
else if ( featureA ==
E ) {
1139 boxPointA.
setEdgeFeature( dimA[2], sA[dimA[2]], dimA[otherFaceDimA], sA[dimA[otherFaceDimA]] );
1144 if ( featureB ==
F ) {
1146 }
else if ( featureB ==
E ) {
1147 boxPointB.
setEdgeFeature( dimB[2], sB[dimB[2]], dimB[otherFaceDimB], sB[dimB[otherFaceDimB]] );
1153 normal = transformA * axisA;
1155 if ( maxGap < 0.0f ) {
1158 return (sqrtf( minDistSqr ));
void EdgeEdgeTests(bool &done, float &minDistSqr, vmPoint3 &localPointA, vmPoint3 &localPointB, int &otherFaceDimA, int &otherFaceDimB, FeatureType &featureA, FeatureType &featureB, const vmVector3 &hA, const vmVector3 &hB, PE_REF(vmVector3) faceOffsetAB, PE_REF(vmVector3) faceOffsetBA, const vmMatrix3 &matrixAB, const vmMatrix3 &matrixBA, PE_REF(vmVector3) signsA, PE_REF(vmVector3) signsB, PE_REF(vmVector3) scalesA, PE_REF(vmVector3) scalesB, bool first)
float CustomEdgeEdgeTest_1010(bool &inVoronoi, float &tA, float &tB, const vmVector3 &hA, const vmVector3 &hB, PE_REF(vmVector3) faceOffsetAB, PE_REF(vmVector3) faceOffsetBA, const vmMatrix3 &matrixAB, const vmMatrix3 &matrixBA, PE_REF(vmVector3) signsA, PE_REF(vmVector3) signsB, PE_REF(vmVector3) scalesA, PE_REF(vmVector3) scalesB)
Vectormath::Aos::Point3 vmPoint3
void setFaceFeature(int dim, int plus)
float VertexBFaceATest(bool &inVoronoi, float &t0, float &t1, const vmVector3 &hA, PE_REF(vmVector3) faceOffsetAB, PE_REF(vmVector3) faceOffsetBA, const vmMatrix3 &matrixAB, const vmMatrix3 &matrixBA, PE_REF(vmVector3) signsB, PE_REF(vmVector3) scalesB)
float CustomEdgeEdgeTest_0101(bool &inVoronoi, float &tA, float &tB, const vmVector3 &hA, const vmVector3 &hB, PE_REF(vmVector3) faceOffsetAB, PE_REF(vmVector3) faceOffsetBA, const vmMatrix3 &matrixAB, const vmMatrix3 &matrixBA, PE_REF(vmVector3) signsA, PE_REF(vmVector3) signsB, PE_REF(vmVector3) scalesA, PE_REF(vmVector3) scalesB)
Matrix3 & setCol0(const Vector3 &col0)
#define AaxisTest(dim, letter, first)
Matrix3 & setCol2(const Vector3 &col2)
#define EdgeEdge_SetNewMin(ac_letter, ad_letter, bc_letter, bd_letter)
float CustomEdgeEdgeTest_0110(bool &inVoronoi, float &tA, float &tB, const vmVector3 &hA, const vmVector3 &hB, PE_REF(vmVector3) faceOffsetAB, PE_REF(vmVector3) faceOffsetBA, const vmMatrix3 &matrixAB, const vmMatrix3 &matrixBA, PE_REF(vmVector3) signsA, PE_REF(vmVector3) signsB, PE_REF(vmVector3) scalesA, PE_REF(vmVector3) scalesB)
Vectormath::Aos::Matrix3 vmMatrix3
void setVertexFeature(int plusX, int plusY, int plusZ)
static const Matrix3 identity()
static const float voronoiTol
void setEdgeFeature(int dim0, int plus0, int dim1, int plus1)
const Vector3 copySignPerElem(const Vector3 &vec0, const Vector3 &vec1)
const Vector3 getCol0() const
float VertexAFaceBTest(bool &inVoronoi, float &t0, float &t1, const vmVector3 &hB, PE_REF(vmVector3) faceOffsetAB, PE_REF(vmVector3) faceOffsetBA, const vmMatrix3 &matrixAB, const vmMatrix3 &matrixBA, PE_REF(vmVector3) signsA, PE_REF(vmVector3) scalesA)
Matrix3 & setCol1(const Vector3 &col1)
const Matrix4 orthoInverse(const Matrix4 &mat)
The Box is an internal class used by the boxBoxDistance calculation.
float distSqr(const Point3 &pnt0, const Point3 &pnt1)
float boxBoxDistance(vmVector3 &normal, BoxPoint &boxPointA, BoxPoint &boxPointB, PE_REF(Box) boxA, const vmTransform3 &transformA, PE_REF(Box) boxB, const vmTransform3 &transformB, float distanceThreshold)
const Matrix3 transpose(const Matrix3 &mat)
Vectormath::Aos::Vector3 vmVector3
static float sqr(float a)
btScalar dot(const btQuaternion &q1, const btQuaternion &q2)
Calculate the dot product between two quaternions.
#define CrossAxisTest(dima, dimb, letterb)
void VertexAFaceBTests(bool &done, float &minDistSqr, vmPoint3 &localPointA, vmPoint3 &localPointB, FeatureType &featureA, FeatureType &featureB, const vmVector3 &hB, PE_REF(vmVector3) faceOffsetAB, PE_REF(vmVector3) faceOffsetBA, const vmMatrix3 &matrixAB, const vmMatrix3 &matrixBA, PE_REF(vmVector3) signsA, PE_REF(vmVector3) scalesA, bool first)
#define CustomEdgeEdgeTest(ac, ac_letter, ad, ad_letter, bc, bc_letter, bd, bd_letter)
#define VertexAFaceB_SetNewMin()
float CustomEdgeEdgeTest_1001(bool &inVoronoi, float &tA, float &tB, const vmVector3 &hA, const vmVector3 &hB, PE_REF(vmVector3) faceOffsetAB, PE_REF(vmVector3) faceOffsetBA, const vmMatrix3 &matrixAB, const vmMatrix3 &matrixBA, PE_REF(vmVector3) signsA, PE_REF(vmVector3) signsB, PE_REF(vmVector3) scalesA, PE_REF(vmVector3) scalesB)
The BoxPoint class is an internally used class to contain feature information for boxBoxDistance calc...
const Matrix3 mulPerElem(const Matrix3 &mat0, const Matrix3 &mat1)
#define VertexBFaceA_SetNewMin()
const Vector3 getCol2() const
const Matrix3 absPerElem(const Matrix3 &mat)
void VertexBFaceATests(bool &done, float &minDistSqr, vmPoint3 &localPointA, vmPoint3 &localPointB, FeatureType &featureA, FeatureType &featureB, const vmVector3 &hA, PE_REF(vmVector3) faceOffsetAB, PE_REF(vmVector3) faceOffsetBA, const vmMatrix3 &matrixAB, const vmMatrix3 &matrixBA, PE_REF(vmVector3) signsB, PE_REF(vmVector3) scalesB, bool first)
#define BaxisTest(dim, letter)
const Vector3 getCol1() const