30 #include"../CollisionPairInserter.h" 55 mFullBoxBoxTest (true),
56 mFullPrimBoxTest (true),
57 collisionPairInserter(0)
79 if(TemporalCoherenceEnabled() && !FirstContactEnabled())
return "Temporal coherence only works with ""First contact"" mode!";
114 #ifdef __MESHMERIZER_H__ 124 CollisionHull* Hull = (CollisionHull*)user_data;
125 previndex = Hull->ComputeSupportingVertex(sv, previndex);
126 return (
Point*)&Hull->GetVerts()[previndex];
134 static GJKEngine GJK;
135 static bool GJKInitDone=
false;
138 GJK.Enable(GJK_BACKUP_PROCEDURE);
139 GJK.Enable(GJK_DEGENERATE);
140 GJK.Enable(GJK_HILLCLIMBING);
143 GJK.SetCallbackObj0(Local::SVCallback);
144 GJK.SetCallbackObj1(Local::SVCallback);
147 Collide = GJK.Collide(*world0, *world1, &cache.SepVector);
152 SVE.SetCallbackObj0(Local::SVCallback);
153 SVE.SetCallbackObj1(Local::SVCallback);
156 Collide = SVE.Collide(*world0, *world1, &cache.SepVector);
164 mNbPrimPrimTests = 0;
173 cache.HullTest =
false;
174 #endif // __MESHMERIZER_H__ 187 Status = Collide(T0, T1, world0, world1, &cache);
193 Status = Collide(T0, T1, world0, world1, &cache);
202 Status = Collide(T0, T1, world0, world1, &cache);
208 Status = Collide(T0, T1, world0, world1, &cache);
212 #ifdef __MESHMERIZER_H__ 223 cache.HullTest =
true;
246 mNbPrimPrimTests = 0;
258 Matrix4x4 World0to1 = world0 ? (*world0 * InvWorld1) : InvWorld1;
259 Matrix4x4 World1to0 = world1 ? (*world1 * InvWorld0) : InvWorld0;
261 mR0to1 = World0to1; World0to1.
GetTrans(mT0to1);
262 mR1to0 = World1to0; World1to0.GetTrans(mT1to0);
270 mAR.m[
i][j] = 1e-6
f + fabsf(mR1to0.m[
i][j]);
278 if(collisionPairInserter){
281 for(
udword j=0; j<3; j++){
282 collisionPairInserter->CD_Rot1(
i,j) = (double) world0->
m[j][
i];
283 collisionPairInserter->CD_Rot2(
i,j) = (double) world1->
m[j][
i];
293 collisionPairInserter->CD_Trans1[0] = (double) t0.
x;
294 collisionPairInserter->CD_Trans1[1] = (
double) t0.
y;
295 collisionPairInserter->CD_Trans1[2] = (double) t0.
z;
297 collisionPairInserter->CD_Trans2[0] = (
double) t1.
x;
298 collisionPairInserter->CD_Trans2[1] = (double) t1.
y;
299 collisionPairInserter->CD_Trans2[2] = (
double) t1.
z;
302 collisionPairInserter->CD_s1 = 1.0;
303 collisionPairInserter->CD_s2 = 1.0;
319 if(!cache)
return false;
322 if(TemporalCoherenceEnabled() && FirstContactEnabled())
324 PrimTest(cache->
id0, cache->
id1);
325 if(GetContactStatus())
return true;
330 #define UPDATE_CACHE \ 331 if(cache && GetContactStatus()) \ 333 cache->id0 = mPairs.GetEntry(0); \ 334 cache->id1 = mPairs.GetEntry(1); \ 352 InitQuery(world0, world1);
355 if(CheckTemporalCoherence(cache))
return true;
358 _Collide(tree0->GetNodes(), tree1->GetNodes());
380 InitQuery(world0, world1);
383 if(CheckTemporalCoherence(cache))
return true;
386 _Collide(tree0->GetNodes(), tree1->GetNodes());
408 InitQuery(world0, world1);
411 if(CheckTemporalCoherence(cache))
return true;
421 const Point a(
float(N0->mAABB.mExtents[0]) * mExtentsCoeff0.x,
float(N0->mAABB.mExtents[1]) * mExtentsCoeff0.y,
float(N0->mAABB.mExtents[2]) * mExtentsCoeff0.z);
422 const Point Pa(
float(N0->mAABB.mCenter[0]) * mCenterCoeff0.x,
float(N0->mAABB.mCenter[1]) * mCenterCoeff0.y,
float(N0->mAABB.mCenter[2]) * mCenterCoeff0.z);
425 const Point b(
float(N1->mAABB.mExtents[0]) * mExtentsCoeff1.x,
float(N1->mAABB.mExtents[1]) * mExtentsCoeff1.y,
float(N1->mAABB.mExtents[2]) * mExtentsCoeff1.z);
426 const Point Pb(
float(N1->mAABB.mCenter[0]) * mCenterCoeff1.x,
float(N1->mAABB.mCenter[1]) * mCenterCoeff1.y,
float(N1->mAABB.mCenter[2]) * mCenterCoeff1.z);
429 _Collide(N0, N1, a, Pa, b, Pb);
451 InitQuery(world0, world1);
454 if(CheckTemporalCoherence(cache))
return true;
463 _Collide(tree0->GetNodes(), tree1->GetNodes());
476 #define ALTERNATIVE_CODE 491 if(!BoxBoxOverlap(b0->mAABB.mExtents, b0->mAABB.mCenter, b1->mAABB.mExtents, b1->mAABB.mCenter))
return;
493 if(b0->IsLeaf() && b1->IsLeaf()) { PrimTest(b0->GetPrimitive(), b1->GetPrimitive());
return; }
495 if(b1->IsLeaf() || (!b0->IsLeaf() && (b0->
GetSize() > b1->
GetSize())))
497 _Collide(b0->GetNeg(), b1);
498 if(ContactFound())
return;
499 _Collide(b0->GetPos(), b1);
503 _Collide(b0, b1->GetNeg());
504 if(ContactFound())
return;
505 _Collide(b0, b1->GetPos());
510 #ifdef ALTERNATIVE_CODE 521 if(!BoxBoxOverlap(b0->mAABB.mExtents, b0->mAABB.mCenter, b1->mAABB.mExtents, b1->mAABB.mCenter))
532 PrimTest(b0->GetPrimitive(), b1->GetPrimitive());
536 _Collide(b0, b1->GetNeg());
537 if(ContactFound())
return;
538 _Collide(b0, b1->GetPos());
541 else if(b1->IsLeaf())
543 _Collide(b0->GetNeg(), b1);
544 if(ContactFound())
return;
545 _Collide(b0->GetPos(), b1);
549 _Collide(b0->GetNeg(), b1->GetNeg());
550 if(ContactFound())
return;
551 _Collide(b0->GetNeg(), b1->GetPos());
552 if(ContactFound())
return;
553 _Collide(b0->GetPos(), b1->GetNeg());
554 if(ContactFound())
return;
555 _Collide(b0->GetPos(), b1->GetPos());
578 mIMesh0->GetTriangle(VP0, id0);
579 mIMesh1->GetTriangle(VP1, id1);
590 if(TriTriOverlap(u0, u1, u2,
594 mPairs.Add(id0).Add(id1);
610 mIMesh1->GetTriangle(VP, id1);
613 if(TriTriOverlap(mLeafVerts[0], mLeafVerts[1], mLeafVerts[2], *VP.
Vertex[0], *VP.
Vertex[1], *VP.
Vertex[2]))
616 mPairs.Add(mLeafIndex).Add(id1);
632 mIMesh0->GetTriangle(VP, id0);
635 if(TriTriOverlap(mLeafVerts[0], mLeafVerts[1], mLeafVerts[2], *VP.
Vertex[0], *VP.
Vertex[1], *VP.
Vertex[2]))
638 mPairs.Add(id0).Add(mLeafIndex);
658 if(b->HasPosLeaf()) PrimTestTriIndex(b->GetPosPrimitive());
659 else _CollideTriBox(b->GetPos());
661 if(ContactFound())
return;
664 if(b->HasNegLeaf()) PrimTestTriIndex(b->GetNegPrimitive());
665 else _CollideTriBox(b->GetNeg());
682 if(b->HasPosLeaf()) PrimTestIndexTri(b->GetPosPrimitive());
683 else _CollideBoxTri(b->GetPos());
685 if(ContactFound())
return;
688 if(b->HasNegLeaf()) PrimTestIndexTri(b->GetNegPrimitive());
689 else _CollideBoxTri(b->GetNeg());
693 #define FETCH_LEAF(prim_index, imesh, rot, trans) \ 694 mLeafIndex = prim_index; \ 696 VertexPointers VP; imesh->GetTriangle(VP, prim_index); \ 698 TransformPoint(mLeafVerts[0], *VP.Vertex[0], rot, trans); \ 699 TransformPoint(mLeafVerts[1], *VP.Vertex[1], rot, trans); \ 700 TransformPoint(mLeafVerts[2], *VP.Vertex[2], rot, trans); 712 if(!BoxBoxOverlap(a->mAABB.mExtents, a->mAABB.mCenter, b->mAABB.mExtents, b->mAABB.mCenter))
return;
715 BOOL BHasPosLeaf = b->HasPosLeaf();
716 BOOL BHasNegLeaf = b->HasNegLeaf();
720 FETCH_LEAF(a->GetPosPrimitive(), mIMesh0, mR0to1, mT0to1)
722 if(BHasPosLeaf) PrimTestTriIndex(b->GetPosPrimitive());
723 else _CollideTriBox(b->GetPos());
725 if(ContactFound())
return;
727 if(BHasNegLeaf) PrimTestTriIndex(b->GetNegPrimitive());
728 else _CollideTriBox(b->GetNeg());
734 FETCH_LEAF(b->GetPosPrimitive(), mIMesh1, mR1to0, mT1to0)
736 _CollideBoxTri(a->GetPos());
738 else _Collide(a->GetPos(), b->GetPos());
740 if(ContactFound())
return;
744 FETCH_LEAF(b->GetNegPrimitive(), mIMesh1, mR1to0, mT1to0)
746 _CollideBoxTri(a->GetPos());
748 else _Collide(a->GetPos(), b->GetNeg());
751 if(ContactFound())
return;
755 FETCH_LEAF(a->GetNegPrimitive(), mIMesh0, mR0to1, mT0to1)
757 if(BHasPosLeaf) PrimTestTriIndex(b->GetPosPrimitive());
758 else _CollideTriBox(b->GetPos());
760 if(ContactFound())
return;
762 if(BHasNegLeaf) PrimTestTriIndex(b->GetNegPrimitive());
763 else _CollideTriBox(b->GetNeg());
770 FETCH_LEAF(b->GetPosPrimitive(), mIMesh1, mR1to0, mT1to0)
772 _CollideBoxTri(a->GetNeg());
774 else _Collide(a->GetNeg(), b->GetPos());
776 if(ContactFound())
return;
781 FETCH_LEAF(b->GetNegPrimitive(), mIMesh1, mR1to0, mT1to0)
783 _CollideBoxTri(a->GetNeg());
785 else _Collide(a->GetNeg(), b->GetNeg());
807 if(!BoxBoxOverlap(a, Pa, b, Pb))
return;
809 if(b0->IsLeaf() && b1->IsLeaf()) { PrimTest(b0->GetPrimitive(), b1->GetPrimitive());
return; }
811 if(b1->IsLeaf() || (!b0->IsLeaf() && (b0->
GetSize() > b1->
GetSize())))
815 const Point negPa(
float(Box->
mCenter[0]) * mCenterCoeff0.x,
float(Box->
mCenter[1]) * mCenterCoeff0.y,
float(Box->
mCenter[2]) * mCenterCoeff0.z);
816 const Point nega(
float(Box->
mExtents[0]) * mExtentsCoeff0.x,
float(Box->
mExtents[1]) * mExtentsCoeff0.y,
float(Box->
mExtents[2]) * mExtentsCoeff0.z);
817 _Collide(b0->GetNeg(), b1, nega, negPa,
b, Pb);
819 if(ContactFound())
return;
822 Box = &b0->GetPos()->mAABB;
823 const Point posPa(
float(Box->
mCenter[0]) * mCenterCoeff0.x,
float(Box->
mCenter[1]) * mCenterCoeff0.y,
float(Box->
mCenter[2]) * mCenterCoeff0.z);
824 const Point posa(
float(Box->
mExtents[0]) * mExtentsCoeff0.x,
float(Box->
mExtents[1]) * mExtentsCoeff0.y,
float(Box->
mExtents[2]) * mExtentsCoeff0.z);
825 _Collide(b0->GetPos(), b1, posa, posPa,
b, Pb);
831 const Point negPb(
float(Box->
mCenter[0]) * mCenterCoeff1.x,
float(Box->
mCenter[1]) * mCenterCoeff1.y,
float(Box->
mCenter[2]) * mCenterCoeff1.z);
832 const Point negb(
float(Box->
mExtents[0]) * mExtentsCoeff1.x,
float(Box->
mExtents[1]) * mExtentsCoeff1.y,
float(Box->
mExtents[2]) * mExtentsCoeff1.z);
833 _Collide(b0, b1->GetNeg(), a, Pa, negb, negPb);
835 if(ContactFound())
return;
838 Box = &b1->GetPos()->mAABB;
839 const Point posPb(
float(Box->
mCenter[0]) * mCenterCoeff1.x,
float(Box->
mCenter[1]) * mCenterCoeff1.y,
float(Box->
mCenter[2]) * mCenterCoeff1.z);
840 const Point posb(
float(Box->
mExtents[0]) * mExtentsCoeff1.x,
float(Box->
mExtents[1]) * mExtentsCoeff1.y,
float(Box->
mExtents[2]) * mExtentsCoeff1.z);
841 _Collide(b0, b1->GetPos(), a, Pa, posb, posPb);
861 const Point Pb(
float(bb->
mCenter[0]) * mCenterCoeff1.x,
float(bb->
mCenter[1]) * mCenterCoeff1.y,
float(bb->
mCenter[2]) * mCenterCoeff1.z);
862 const Point eb(
float(bb->
mExtents[0]) * mExtentsCoeff1.x,
float(bb->
mExtents[1]) * mExtentsCoeff1.y,
float(bb->
mExtents[2]) * mExtentsCoeff1.z);
869 if(b->HasPosLeaf()) PrimTestTriIndex(b->GetPosPrimitive());
870 else _CollideTriBox(b->GetPos());
872 if(ContactFound())
return;
874 if(b->HasNegLeaf()) PrimTestTriIndex(b->GetNegPrimitive());
875 else _CollideTriBox(b->GetNeg());
889 const Point Pa(
float(bb->
mCenter[0]) * mCenterCoeff0.x,
float(bb->
mCenter[1]) * mCenterCoeff0.y,
float(bb->
mCenter[2]) * mCenterCoeff0.z);
890 const Point ea(
float(bb->
mExtents[0]) * mExtentsCoeff0.x,
float(bb->
mExtents[1]) * mExtentsCoeff0.y,
float(bb->
mExtents[2]) * mExtentsCoeff0.z);
898 if(b->HasPosLeaf()) PrimTestIndexTri(b->GetPosPrimitive());
899 else _CollideBoxTri(b->GetPos());
901 if(ContactFound())
return;
903 if(b->HasNegLeaf()) PrimTestIndexTri(b->GetNegPrimitive());
904 else _CollideBoxTri(b->GetNeg());
918 const Point Pa(
float(ab->
mCenter[0]) * mCenterCoeff0.x,
float(ab->
mCenter[1]) * mCenterCoeff0.y,
float(ab->
mCenter[2]) * mCenterCoeff0.z);
919 const Point ea(
float(ab->
mExtents[0]) * mExtentsCoeff0.x,
float(ab->
mExtents[1]) * mExtentsCoeff0.y,
float(ab->
mExtents[2]) * mExtentsCoeff0.z);
922 const Point Pb(
float(bb->
mCenter[0]) * mCenterCoeff1.x,
float(bb->
mCenter[1]) * mCenterCoeff1.y,
float(bb->
mCenter[2]) * mCenterCoeff1.z);
923 const Point eb(
float(bb->
mExtents[0]) * mExtentsCoeff1.x,
float(bb->
mExtents[1]) * mExtentsCoeff1.y,
float(bb->
mExtents[2]) * mExtentsCoeff1.z);
926 if(!BoxBoxOverlap(ea, Pa, eb, Pb))
return;
929 BOOL BHasPosLeaf = b->HasPosLeaf();
930 BOOL BHasNegLeaf = b->HasNegLeaf();
934 FETCH_LEAF(a->GetPosPrimitive(), mIMesh0, mR0to1, mT0to1)
936 if(BHasPosLeaf) PrimTestTriIndex(b->GetPosPrimitive());
937 else _CollideTriBox(b->GetPos());
939 if(ContactFound())
return;
941 if(BHasNegLeaf) PrimTestTriIndex(b->GetNegPrimitive());
942 else _CollideTriBox(b->GetNeg());
948 FETCH_LEAF(b->GetPosPrimitive(), mIMesh1, mR1to0, mT1to0)
950 _CollideBoxTri(a->GetPos());
952 else _Collide(a->GetPos(), b->GetPos());
954 if(ContactFound())
return;
958 FETCH_LEAF(b->GetNegPrimitive(), mIMesh1, mR1to0, mT1to0)
960 _CollideBoxTri(a->GetPos());
962 else _Collide(a->GetPos(), b->GetNeg());
965 if(ContactFound())
return;
969 FETCH_LEAF(a->GetNegPrimitive(), mIMesh0, mR0to1, mT0to1)
971 if(BHasPosLeaf) PrimTestTriIndex(b->GetPosPrimitive());
972 else _CollideTriBox(b->GetPos());
974 if(ContactFound())
return;
976 if(BHasNegLeaf) PrimTestTriIndex(b->GetNegPrimitive());
977 else _CollideTriBox(b->GetNeg());
984 FETCH_LEAF(b->GetPosPrimitive(), mIMesh1, mR1to0, mT1to0)
986 _CollideBoxTri(a->GetNeg());
988 else _Collide(a->GetNeg(), b->GetPos());
990 if(ContactFound())
return;
995 FETCH_LEAF(b->GetNegPrimitive(), mIMesh1, mR1to0, mT1to0)
997 _CollideBoxTri(a->GetNeg());
999 else _Collide(a->GetNeg(), b->GetNeg());
inline_ void PrimTestTriIndex(udword id1)
#define null
our own NULL pointer
bool CheckTemporalCoherence(Pair *cache)
Final contact status after a collision query.
A generic couple structure.
inline_ const HPoint & GetTrans() const
Returns the translation part of the matrix.
inline_ uword GetSize() const
uword mExtents[3]
Quantized extents.
const Model * Model1
Model for second object.
void _CollideTriBox(const AABBNoLeafNode *b)
virtual inline_ void InitQuery()
udword id1
Second index of the pair.
sword mCenter[3]
Quantized center.
#define FETCH_LEAF(prim_index, imesh, rot, trans)
Request triangle vertices from the app and transform them.
int BOOL
Another boolean type.
inline_ void Identity()
Sets the identity matrix.
unsigned int udword
sizeof(udword) must be 4
virtual const char * ValidateSettings()=0
virtual ~AABBTreeCollider()
void _Collide(const AABBCollisionNode *b0, const AABBCollisionNode *b1)
udword id0
First index of the pair.
inline_ float GetSize() const
bool Collide(BVTCache &cache, const Matrix4x4 *world0=null, const Matrix4x4 *world1=null)
ICEMATHS_API void InvertPRMatrix(Matrix4x4 &dest, const Matrix4x4 &src)
const Model * Model0
Model for first object.
inline_ void ResetCountDown()
inline_ void TransformPoint(Point &dest, const Point &source, const Matrix3x3 &rot, const Point &trans)
Quickly rotates & translates a vector.
inline_ BOOL IsQuantized() const
inline_ void PrimTestIndexTri(udword id0)
void _CollideBoxTri(const AABBNoLeafNode *b)
inline_ BOOL HasLeafNodes() const
inline_ const MeshInterface * GetMeshInterface() const
inline_ const AABBOptimizedTree * GetTree() const
void PrimTest(udword id0, udword id1)