42 #define SET_CONTACT(prim_index, flag) \
45 mTouchedPrimitives->Add(prim_index);
48 #define SPHERE_PRIM(prim_index, flag) \
50 VertexPointers VP; mIMesh->GetTriangle(VP, prim_index); \
53 if(SphereTriOverlap(*VP.Vertex[0], *VP.Vertex[1], *VP.Vertex[2])) \
55 SET_CONTACT(prim_index, flag) \
97 if(!Setup(&model))
return false;
100 if(InitQuery(cache, sphere, worlds, worldm))
return true;
113 if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes());
114 else _Collide(Tree->GetNodes());
121 if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes());
122 else _Collide(Tree->GetNodes());
136 if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes());
137 else _Collide(Tree->GetNodes());
144 if(SkipPrimitiveTests()) _CollideNoPrimitiveTest(Tree->GetNodes());
145 else _Collide(Tree->GetNodes());
173 mRadius2 = sphere.mRadius * sphere.mRadius;
175 mCenter = sphere.mCenter;
177 if(worlds) mCenter *= *worlds;
185 mCenter *= InvWorldM;
192 if(mCurrentModel && mCurrentModel->HasSingleNode())
194 if(!SkipPrimitiveTests())
197 mTouchedPrimitives->Reset();
208 if(TemporalCoherenceEnabled())
212 if(FirstContactEnabled())
215 if(mTouchedPrimitives->GetNbEntries())
218 udword PreviouslyTouchedFace = mTouchedPrimitives->GetEntry(0);
223 mTouchedPrimitives->Reset();
229 if(GetContactStatus())
return TRUE;
237 float r = sqrtf(cache.
FatRadius2) - sphere.mRadius;
238 if(IsCacheValid(cache) && cache.
Center.SquareDistance(mCenter) < r*r)
254 mTouchedPrimitives->Reset();
269 mTouchedPrimitives->Reset();
289 ASSERT( !(FirstContactEnabled() && TemporalCoherenceEnabled()) );
292 if(!tree)
return false;
295 if(InitQuery(cache, sphere))
return true;
316 p.x=bc.x+be.x; p.y=bc.y+be.y; p.z=bc.z+be.z;
if(mCenter.SquareDistance(p)>=mRadius2)
return FALSE;
317 p.x=bc.x-be.x;
if(mCenter.SquareDistance(p)>=mRadius2)
return FALSE;
318 p.x=bc.x+be.x; p.y=bc.y-be.y;
if(mCenter.SquareDistance(p)>=mRadius2)
return FALSE;
319 p.x=bc.x-be.x;
if(mCenter.SquareDistance(p)>=mRadius2)
return FALSE;
320 p.x=bc.x+be.x; p.y=bc.y+be.y; p.z=bc.z-be.z;
if(mCenter.SquareDistance(p)>=mRadius2)
return FALSE;
321 p.x=bc.x-be.x;
if(mCenter.SquareDistance(p)>=mRadius2)
return FALSE;
322 p.x=bc.x+be.x; p.y=bc.y-be.y;
if(mCenter.SquareDistance(p)>=mRadius2)
return FALSE;
323 p.x=bc.x-be.x;
if(mCenter.SquareDistance(p)>=mRadius2)
return FALSE;
328 #define TEST_BOX_IN_SPHERE(center, extents) \
329 if(SphereContainsBox(center, extents)) \
332 mFlags |= OPC_CONTACT; \
346 if(!SphereAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents))
return;
356 _Collide(node->GetPos());
358 if(ContactFound())
return;
360 _Collide(node->GetNeg());
373 if(!SphereAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents))
return;
383 _CollideNoPrimitiveTest(node->GetPos());
385 if(ContactFound())
return;
387 _CollideNoPrimitiveTest(node->GetNeg());
401 const Point Center(
float(Box.
mCenter[0]) * mCenterCoeff.x,
float(Box.
mCenter[1]) * mCenterCoeff.y,
float(Box.
mCenter[2]) * mCenterCoeff.z);
402 const Point Extents(
float(Box.
mExtents[0]) * mExtentsCoeff.x,
float(Box.
mExtents[1]) * mExtentsCoeff.y,
float(Box.
mExtents[2]) * mExtentsCoeff.z);
405 if(!SphereAABBOverlap(Center, Extents))
return;
415 _Collide(node->GetPos());
417 if(ContactFound())
return;
419 _Collide(node->GetNeg());
433 const Point Center(
float(Box.
mCenter[0]) * mCenterCoeff.x,
float(Box.
mCenter[1]) * mCenterCoeff.y,
float(Box.
mCenter[2]) * mCenterCoeff.z);
434 const Point Extents(
float(Box.
mExtents[0]) * mExtentsCoeff.x,
float(Box.
mExtents[1]) * mExtentsCoeff.y,
float(Box.
mExtents[2]) * mExtentsCoeff.z);
437 if(!SphereAABBOverlap(Center, Extents))
return;
447 _CollideNoPrimitiveTest(node->GetPos());
449 if(ContactFound())
return;
451 _CollideNoPrimitiveTest(node->GetNeg());
464 if(!SphereAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents))
return;
469 else _Collide(node->GetPos());
471 if(ContactFound())
return;
474 else _Collide(node->GetNeg());
486 if(!SphereAABBOverlap(node->mAABB.mCenter, node->mAABB.mExtents))
return;
491 else _CollideNoPrimitiveTest(node->GetPos());
493 if(ContactFound())
return;
496 else _CollideNoPrimitiveTest(node->GetNeg());
509 const Point Center(
float(Box.
mCenter[0]) * mCenterCoeff.x,
float(Box.
mCenter[1]) * mCenterCoeff.y,
float(Box.
mCenter[2]) * mCenterCoeff.z);
510 const Point Extents(
float(Box.
mExtents[0]) * mExtentsCoeff.x,
float(Box.
mExtents[1]) * mExtentsCoeff.y,
float(Box.
mExtents[2]) * mExtentsCoeff.z);
513 if(!SphereAABBOverlap(Center, Extents))
return;
518 else _Collide(node->GetPos());
520 if(ContactFound())
return;
523 else _Collide(node->GetNeg());
536 const Point Center(
float(Box.
mCenter[0]) * mCenterCoeff.x,
float(Box.
mCenter[1]) * mCenterCoeff.y,
float(Box.
mCenter[2]) * mCenterCoeff.z);
537 const Point Extents(
float(Box.
mExtents[0]) * mExtentsCoeff.x,
float(Box.
mExtents[1]) * mExtentsCoeff.y,
float(Box.
mExtents[2]) * mExtentsCoeff.z);
540 if(!SphereAABBOverlap(Center, Extents))
return;
545 else _CollideNoPrimitiveTest(node->GetPos());
547 if(ContactFound())
return;
550 else _CollideNoPrimitiveTest(node->GetNeg());
562 Point Center, Extents;
563 node->GetAABB()->GetCenter(Center);
564 node->GetAABB()->GetExtents(Extents);
565 if(!SphereAABBOverlap(Center, Extents))
return;
567 if(node->IsLeaf() || SphereContainsBox(Center, Extents))
574 _Collide(node->GetPos());
575 _Collide(node->GetNeg());
609 if(!Setup(&model))
return false;
612 if(InitQuery(cache, sphere, worlds, worldm))
return true;
615 if(mCurrentModel && mCurrentModel->HasSingleNode())
618 udword Nb = mIMesh->GetNbTriangles();
629 mTouchedBoxes.Reset();
630 mTouchedPrimitives = &mTouchedBoxes;
644 _CollideNoPrimitiveTest(Tree->GetNodes());
651 _CollideNoPrimitiveTest(Tree->GetNodes());
665 _CollideNoPrimitiveTest(Tree->GetNodes());
672 _CollideNoPrimitiveTest(Tree->GetNodes());
677 if(GetContactStatus())
687 udword Nb = mTouchedBoxes.GetNbEntries();
688 const udword* Touched = mTouchedBoxes.GetEntries();
707 udword TriangleIndex = *T++;
718 udword TriangleIndex = BaseIndex++;