34 template <
class _Precision>
38 static bool isOnRayW(_Precision, _Precision, _Precision);
39 static bool isOnRayS(_Precision, _Precision, _Precision);
56 inline explicit BoundBox3 (_Precision fMinX = std::numeric_limits<_Precision>::max(),
57 _Precision fMinY = std::numeric_limits<_Precision>::max(),
58 _Precision fMinZ = std::numeric_limits<_Precision>::max(),
59 _Precision fMaxX = -std::numeric_limits<_Precision>::max(),
60 _Precision fMaxY = -std::numeric_limits<_Precision>::max(),
61 _Precision fMaxZ = -std::numeric_limits<_Precision>::max());
62 BoundBox3 (
const BoundBox3<_Precision> &rcBB) { *
this = rcBB; }
64 inline BoundBox3 (
const Vector3<_Precision> *pclVect,
unsigned long ulCt);
69 BoundBox3 (
const Vector3<_Precision> &rcCnt, _Precision fDistance);
73 inline BoundBox3<_Precision>&
operator = (
const BoundBox3<_Precision> &rcBound);
78 inline bool Intersect (
const BoundBox3<_Precision> &rcBB)
const;
80 inline bool operator && (
const BoundBox3<_Precision> &rcBB)
const;
129 inline Vector3<_Precision>
CalcPoint (
unsigned short usPoint)
const;
131 void CalcPlane (
unsigned short usPlane, Vector3<_Precision>& rBase, Vector3<_Precision>& rNormal )
const;
138 bool CalcEdge (
unsigned short usEdge, Vector3<_Precision>& rcP0, Vector3<_Precision>& rcP1)
const;
143 bool IntersectionPoint (
const Vector3<_Precision> &rcVct,
const Vector3<_Precision> &rcVctDir, Vector3<_Precision>& cVctRes, _Precision epsilon)
const;
145 bool IsCutLine (
const Vector3<_Precision>& rcBase,
const Vector3<_Precision>& rcDir, _Precision fTolerance = 0.0f)
const;
149 inline bool IsCutPlane (
const Vector3<_Precision> &rclBase,
const Vector3<_Precision> &rclNormal)
const;
151 bool IntersectWithLine (
const Vector3<_Precision>& rcBase,
const Vector3<_Precision>& rcDir, Vector3<_Precision>& rcP0, Vector3<_Precision>& rcP1)
const;
153 bool IntersectPlaneWithLine (
unsigned short usSide,
const Vector3<_Precision>& rcBase,
const Vector3<_Precision>& rcDir,
154 Vector3<_Precision>& rcP0)
const;
180 inline void Enlarge (_Precision fLen);
182 inline void Shrink (_Precision fLen);
185 inline _Precision
LengthX (
void)
const;
187 inline _Precision
LengthY (
void)
const;
189 inline _Precision
LengthZ (
void)
const;
191 inline void MoveX (_Precision f);
193 inline void MoveY (_Precision f);
195 inline void MoveZ (_Precision f);
197 inline void ScaleX (_Precision f);
199 inline void ScaleY (_Precision f);
201 inline void ScaleZ (_Precision f);
204 void Print (std::ostream&)
const;
208 template <
class _Precision>
212 return ((A <= K) && (K <= B));
215 template <
class _Precision>
216 bool BoundBox3<_Precision>::isOnRayS(_Precision A, _Precision B, _Precision K)
219 return ((A <= K) && (K < B));
222 template <
class _Precision>
224 _Precision fMaxX, _Precision fMaxY, _Precision fMaxZ)
225 : MinX(fMinX), MinY(fMinY), MinZ(fMinZ),
226 MaxX(fMaxX), MaxY(fMaxY), MaxZ(fMaxZ)
230 template <
class _Precision>
232 : MinX(
std::numeric_limits<_Precision>::max())
233 , MinY(
std::numeric_limits<_Precision>::max())
234 , MinZ(
std::numeric_limits<_Precision>::max())
235 , MaxX(-
std::numeric_limits<_Precision>::max())
236 , MaxY(-
std::numeric_limits<_Precision>::max())
237 , MaxZ(-
std::numeric_limits<_Precision>::max())
239 const Vector3<_Precision> *pI, *pEnd = pclVect + ulCt;
240 for (pI = pclVect; pI < pEnd; ++pI) {
241 MinX = std::min<_Precision>(
MinX, pI->x);
242 MinY = std::min<_Precision>(
MinY, pI->y);
245 MaxY = std::max<_Precision>(
MaxY, pI->y);
246 MaxZ = std::max<_Precision>(
MaxZ, pI->z);
250 template <
class _Precision>
253 MinX = rcVector.
x - fDistance;
254 MaxX = rcVector.
x + fDistance;
255 MinY = rcVector.
y - fDistance;
256 MaxY = rcVector.
y + fDistance;
257 MinZ = rcVector.
z - fDistance;
258 MaxZ = rcVector.
z + fDistance;
261 template <
class _Precision>
266 template <
class _Precision>
278 template <
class _Precision>
281 if (rcBB.MaxX < this->MinX || rcBB.MinX > this->MaxX)
283 if (rcBB.MaxY < this->MinY || rcBB.MinY > this->MaxY)
285 if (rcBB.MaxZ < this->MinZ || rcBB.MinZ > this->MaxZ)
290 template <
class _Precision>
293 return Intersect(rcBB);
296 template <
class _Precision>
299 if (rcBB.MaxX < this->MinX || rcBB.MinX > this->MaxX)
301 if (rcBB.MaxY < this->MinY || rcBB.MinY > this->MaxY)
306 template <
class _Precision>
309 return Intersect(rcBB);
312 template <
class _Precision>
317 cBBRes.MinX = std::max<_Precision> (MinX, rcBB.MinX);
318 cBBRes.MaxX = std::min<_Precision> (MaxX, rcBB.MaxX);
319 cBBRes.MinY = std::max<_Precision> (MinY, rcBB.MinY);
320 cBBRes.MaxY = std::min<_Precision> (MaxY, rcBB.MaxY);
321 cBBRes.MinZ = std::max<_Precision> (MinZ, rcBB.MinZ);
322 cBBRes.MaxZ = std::min<_Precision> (MaxZ, rcBB.MaxZ);
327 template <
class _Precision>
332 cBBRes.MinX = std::min<_Precision> (MinX, rcBB.MinX);
333 cBBRes.MaxX = std::max<_Precision> (MaxX, rcBB.MaxX);
334 cBBRes.MinY = std::min<_Precision> (MinY, rcBB.MinY);
335 cBBRes.MaxY = std::max<_Precision> (MaxY, rcBB.MaxY);
336 cBBRes.MinZ = std::min<_Precision> (MinZ, rcBB.MinZ);
337 cBBRes.MaxZ = std::max<_Precision> (MaxZ, rcBB.MaxZ);
342 template <
class _Precision>
345 this->MinX = std::min<_Precision>(this->MinX, rclVect.
x);
346 this->MinY = std::min<_Precision>(this->MinY, rclVect.
y);
347 this->MinZ = std::min<_Precision>(this->MinZ, rclVect.
z);
348 this->MaxX = std::max<_Precision>(this->MaxX, rclVect.
x);
349 this->MaxY = std::max<_Precision>(this->MaxY, rclVect.
y);
350 this->MaxZ = std::max<_Precision>(this->MaxZ, rclVect.
z);
353 template <
class _Precision>
356 this->MinX = std::min<_Precision> (this->MinX, rcBB.MinX);
357 this->MaxX = std::max<_Precision> (this->MaxX, rcBB.MaxX);
358 this->MinY = std::min<_Precision> (this->MinY, rcBB.MinY);
359 this->MaxY = std::max<_Precision> (this->MaxY, rcBB.MaxY);
360 this->MinZ = std::min<_Precision> (this->MinZ, rcBB.MinZ);
361 this->MaxZ = std::max<_Precision> (this->MaxZ, rcBB.MaxZ);
364 template <
class _Precision>
367 if (rcVct.
x < this->MinX || rcVct.
x > this->MaxX)
369 if (rcVct.
y < this->MinY || rcVct.
y > this->MaxY)
371 if (rcVct.
z < this->MinZ || rcVct.
z > this->MaxZ)
376 template <
class _Precision>
379 if (rcBB.MinX < this->MinX || rcBB.MaxX > this->MaxX)
381 if (rcBB.MinY < this->MinY || rcBB.MaxY > this->MaxY)
383 if (rcBB.MinZ < this->MinZ || rcBB.MaxZ > this->MaxZ)
388 template <
class _Precision>
391 if (rcBB.
MinX < this->MinX || rcBB.
MaxX > this->MaxX)
393 if (rcBB.
MinY < this->MinY || rcBB.
MaxY > this->MaxY)
398 template <
class _Precision>
401 return ((MinX <= MaxX) && (MinY <= MaxY) && (MinZ <= MaxZ));
404 template <
class _Precision>
407 if (!IsInBox (rclVct))
410 unsigned short usNdx = 0;
411 if (isOnRayS ((MinX + MaxX)/2, MaxX, rclVct.
x))
413 if (isOnRayS ((MinY + MaxY)/2, MaxY, rclVct.
y))
415 if (isOnRayS ((MinZ + MaxZ)/2, MaxZ, rclVct.
z))
417 rclOctant =
static_cast<OCTANT>(usNdx);
421 template <
class _Precision>
428 cOct.MaxX = (cOct.MinX + cOct.MaxX)/2;
429 cOct.MaxY = (cOct.MinY + cOct.MaxY)/2;
430 cOct.MaxZ = (cOct.MinZ + cOct.MaxZ)/2;
434 cOct.MinX = (cOct.MinX + cOct.MaxX)/2;
435 cOct.MaxY = (cOct.MinY + cOct.MaxY)/2;
436 cOct.MaxZ = (cOct.MinZ + cOct.MaxZ)/2;
440 cOct.MaxX = (cOct.MinX + cOct.MaxX)/2;
441 cOct.MinY = (cOct.MinY + cOct.MaxY)/2;
442 cOct.MaxZ = (cOct.MinZ + cOct.MaxZ)/2;
446 cOct.MinX = (cOct.MinX + cOct.MaxX)/2;
447 cOct.MinY = (cOct.MinY + cOct.MaxY)/2;
448 cOct.MaxZ = (cOct.MinZ + cOct.MaxZ)/2;
452 cOct.MaxX = (cOct.MinX + cOct.MaxX)/2;
453 cOct.MaxY = (cOct.MinY + cOct.MaxY)/2;
454 cOct.MinZ = (cOct.MinZ + cOct.MaxZ)/2;
458 cOct.MinX = (cOct.MinX + cOct.MaxX)/2;
459 cOct.MaxY = (cOct.MinY + cOct.MaxY)/2;
460 cOct.MinZ = (cOct.MinZ + cOct.MaxZ)/2;
464 cOct.MaxX = (cOct.MinX + cOct.MaxX)/2;
465 cOct.MinY = (cOct.MinY + cOct.MaxY)/2;
466 cOct.MinZ = (cOct.MinZ + cOct.MaxZ)/2;
470 cOct.MinX = (cOct.MinX + cOct.MaxX)/2;
471 cOct.MinY = (cOct.MinY + cOct.MaxY)/2;
472 cOct.MinZ = (cOct.MinZ + cOct.MaxZ)/2;
478 template <
class _Precision>
482 case 0:
return Vector3<_Precision>(MinX, MinY, MaxZ);
483 case 1:
return Vector3<_Precision>(MaxX, MinY, MaxZ);
484 case 2:
return Vector3<_Precision>(MaxX, MaxY, MaxZ);
485 case 3:
return Vector3<_Precision>(MinX, MaxY, MaxZ);
486 case 4:
return Vector3<_Precision>(MinX, MinY, MinZ);
487 case 5:
return Vector3<_Precision>(MaxX, MinY, MinZ);
488 case 6:
return Vector3<_Precision>(MaxX, MaxY, MinZ);
489 case 7:
return Vector3<_Precision>(MinX, MaxY, MinZ);
492 return Vector3<_Precision>();
495 template <
class _Precision>
500 rBase.Set(MinX, MinY, MaxZ);
501 rNormal.Set(1.0f, 0.0f, 0.0f);
505 rBase.Set(MaxX, MinY, MaxZ);
506 rNormal.Set(1.0f, 0.0f, 0.0f);
510 rBase.Set(MinX, MaxY, MaxZ);
511 rNormal.Set(0.0f, 1.0f, 0.0f);
515 rBase.Set(MinX, MinY, MaxZ);
516 rNormal.Set(0.0f, 1.0f, 0.0f);
520 rBase.Set(MinX, MinY, MaxZ);
521 rNormal.Set(0.0f, 0.0f, 1.0f);
525 rBase.Set(MinX, MinY, MinZ);
526 rNormal.Set(0.0f, 0.0f, 1.0f);
533 template <
class _Precision>
592 template <
class _Precision>
596 BoundBox3<_Precision> cCmpBound(*
this);
600 cCmpBound.Enlarge(epsilon);
603 if (cCmpBound.IsInBox (rcVct)) {
605 for (i = 0; (i < 6) && (!rc); i++) {
606 rc = IntersectPlaneWithLine(i, rcVct, rcVctDir, cVctRes);
607 if (!cCmpBound.IsInBox(cVctRes))
613 rc = ((cVctRes - rcVct) * rcVctDir) >= 0.0;
621 template <
class _Precision>
632 fDist = (rcDir % (GetCenter() - rcBase)).Length() / rcDir.Length();
634 if (fDist > (CalcDiagonalLength() + fTolerance)) {
639 Vector3<_Precision> clVectRes;
642 for (i = 0; i < 6; i++) {
643 if (IntersectPlaneWithLine(i, rcBase, rcDir, clVectRes)) {
648 if ((isOnRayW (MinY - fTolerance, MaxY + fTolerance, clVectRes.y) &&
649 isOnRayW (MinZ - fTolerance, MaxZ + fTolerance, clVectRes.z)))
654 if ((isOnRayW (MinX - fTolerance, MaxX + fTolerance, clVectRes.x) &&
655 isOnRayW (MinZ - fTolerance, MaxZ + fTolerance, clVectRes.z)))
660 if ((isOnRayW (MinX - fTolerance, MaxX + fTolerance, clVectRes.x) &&
661 isOnRayW (MinY - fTolerance, MaxY + fTolerance, clVectRes.y)))
672 template <
class _Precision>
675 if (fabs(GetCenter().DistanceToPlane(rclBase, rclNormal)) < CalcDiagonalLength()) {
676 _Precision fD = CalcPoint(0).DistanceToPlane(rclBase, rclNormal);
677 for (
unsigned short i = 1; i < 8; i++) {
678 if ((CalcPoint(i).DistanceToPlane(rclBase, rclNormal) * fD) <= 0.0f)
685 template <
class _Precision>
687 Vector3<_Precision>& rcP0, Vector3<_Precision>& rcP1)
const
689 Vector3<_Precision> clVectRes, clVect[6];
691 unsigned short numIntersect = 0;
693 for (
unsigned short i = 0; i < 6; i++) {
694 if (IntersectPlaneWithLine(i, rcBase, rcDir, clVectRes)) {
699 if ((isOnRayS(MinY, MaxY, clVectRes.y) &&
700 isOnRayS(MinZ, MaxZ, clVectRes.z))) {
701 clVect[numIntersect] = clVectRes;
706 if ((isOnRayS(MinX, MaxX, clVectRes.x) &&
707 isOnRayS(MinZ, MaxZ, clVectRes.z))) {
708 clVect[numIntersect] = clVectRes;
713 if ((isOnRayS(MinX, MaxX, clVectRes.x) &&
714 isOnRayS(MinY, MaxY, clVectRes.y))) {
715 clVect[numIntersect] = clVectRes;
722 if (numIntersect == 2) {
727 else if (numIntersect > 2) {
728 for (
unsigned short i = 1; i < numIntersect; i++) {
729 if (clVect[i] != clVect[0]) {
740 template <
class _Precision>
742 const Vector3<_Precision>& rcDir, Vector3<_Precision>& rcP0)
const
745 Vector3<_Precision> cBase, cNormal;
746 Vector3<_Precision> cDir(rcDir);
747 CalcPlane(usSide, cBase, cNormal);
749 if ((cNormal * cDir) == 0.0f) {
753 k = (cNormal * (cBase - rcBase)) / (cNormal * cDir);
755 rcP0 = rcBase + cDir;
760 template <
class _Precision>
764 return GetSideFromRay( rclPt, rclDir, cIntersection);
767 template <
class _Precision>
772 if (IntersectWithLine(rclPt, rclDir, cP0, cP1) ==
false)
777 if ((cP1-cP0)*rclDir > 0)
784 _Precision fMax = 1.0e-3f;
785 SIDE tSide = INVALID;
787 if (fabs(cOut.
x - MinX) < fMax) {
788 fMax = _Precision(fabs(cOut.
x - MinX));
792 if (fabs(cOut.
x - MaxX) < fMax) {
793 fMax = _Precision(fabs(cOut.
x - MaxX));
797 if (fabs(cOut.
y - MinY) < fMax) {
798 fMax = _Precision(fabs(cOut.
y - MinY));
802 if (fabs(cOut.
y - MaxY) < fMax) {
803 fMax = _Precision(fabs(cOut.
y - MaxY));
807 if (fabs(cOut.
z - MinZ) < fMax) {
808 fMax = _Precision(fabs(cOut.
z - MinZ));
812 if (fabs(cOut.
z - MaxZ) < fMax) {
813 fMax = _Precision(fabs(cOut.
z - MaxZ));
820 template <
class _Precision>
825 _Precision fMinDist = std::numeric_limits<_Precision>::max();
826 Vector3<_Precision> cBase, cNormal, clRet;
828 for (
int i = 0; i < 6; i++) {
829 Vector3<_Precision> clTemp = rclPt;
830 CalcPlane(i, cBase, cNormal);
831 clTemp.ProjectToPlane(cBase, cNormal);
832 _Precision fDist = (clTemp - rclPt).Length();
833 if (fDist < fMinDist) {
844 _Precision devx = closest.
x - center.
x;
845 _Precision devy = closest.
y - center.
y;
846 _Precision devz = closest.
z - center.
z;
848 _Precision halfwidth = (MaxX - MinX) / 2;
849 _Precision halfheight = (MaxY - MinY) / 2;
850 _Precision halfdepth = (MaxZ - MinZ) / 2;
853 if ((fabs(devx) > fabs(devy)) && (fabs(devx) > fabs(devz)))
854 closest.
x = center.
x + halfwidth * ((devx < 0.0) ? -1.0 : 1.0);
855 else if (fabs(devy) > fabs(devz))
856 closest.
y = center.
y + halfheight * ((devy < 0.0) ? -1.0 : 1.0);
858 closest.
z = center.
z + halfdepth * ((devz < 0.0) ? -1.0 : 1.0);
861 closest.
x = std::min<_Precision>(std::max<_Precision>(closest.
x, MinX), MaxX);
862 closest.
y = std::min<_Precision>(std::max<_Precision>(closest.
y, MinY), MaxY);
863 closest.
z = std::min<_Precision>(std::max<_Precision>(closest.
z, MinZ), MaxZ);
869 template <
class _Precision>
875 for (
int i = 0; i < 8; i++) {
883 template <
class _Precision>
886 BoundBox3<_Precision> bbox;
887 for (
int i=0; i<8; i++)
888 bbox.Add(mat * CalcPoint(i));
892 template <
class _Precision>
900 template <
class _Precision>
903 return static_cast<_Precision
>(sqrt (((MaxX - MinX) * (MaxX - MinX)) +
904 ((MaxY - MinY) * (MaxY - MinY)) +
905 ((MaxZ - MinZ) * (MaxZ - MinZ))));
908 template <
class _Precision>
911 MinX = MinY = MinZ = std::numeric_limits<_Precision>::max();
912 MaxX = MaxY = MaxZ = -std::numeric_limits<_Precision>::max();
915 template <
class _Precision>
918 MinX -= fLen; MinY -= fLen; MinZ -= fLen;
919 MaxX += fLen; MaxY += fLen; MaxZ += fLen;
922 template <
class _Precision>
925 MinX += fLen; MinY += fLen; MinZ += fLen;
926 MaxX -= fLen; MaxY -= fLen; MaxZ -= fLen;
929 template <
class _Precision>
935 template <
class _Precision>
941 template <
class _Precision>
947 template <
class _Precision>
950 MinX += f; MaxX += f;
953 template <
class _Precision>
956 MinY += f; MaxY += f;
959 template <
class _Precision>
962 MinZ += f; MaxZ += f;
965 template <
class _Precision>
968 MinX *= f; MaxX *= f;
971 template <
class _Precision>
974 MinY *= f; MaxY *= f;
977 template <
class _Precision>
980 MinZ *= f; MaxZ *= f;