From 5fccd67bada2be7a3fbb2df3abf08bfde58b600b Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sun, 1 Sep 2013 19:08:51 +0200 Subject: Added line collision calculation to cBoundingBox. --- source/BoundingBox.cpp | 114 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 104 insertions(+), 10 deletions(-) (limited to 'source/BoundingBox.cpp') diff --git a/source/BoundingBox.cpp b/source/BoundingBox.cpp index 9af726223..c845fe372 100644 --- a/source/BoundingBox.cpp +++ b/source/BoundingBox.cpp @@ -5,6 +5,7 @@ #include "Globals.h" #include "BoundingBox.h" +#include "Defines.h" @@ -123,11 +124,7 @@ cBoundingBox cBoundingBox::Union(const cBoundingBox & a_Other) bool cBoundingBox::IsInside(const Vector3d & a_Point) { - return ( - ((a_Point.x >= m_Min.x) && (a_Point.x < m_Max.x)) && - ((a_Point.y >= m_Min.y) && (a_Point.y < m_Max.y)) && - ((a_Point.z >= m_Min.z) && (a_Point.z < m_Max.z)) - ); + return IsInside(m_Min, m_Max, a_Point); } @@ -136,11 +133,7 @@ bool cBoundingBox::IsInside(const Vector3d & a_Point) bool cBoundingBox::IsInside(double a_X, double a_Y,double a_Z) { - return ( - ((a_X >= m_Min.x) && (a_X < m_Max.x)) && - ((a_Y >= m_Min.y) && (a_Y < m_Max.y)) && - ((a_Z >= m_Min.z) && (a_Z < m_Max.z)) - ); + return IsInside(m_Min, m_Max, a_X, a_Y, a_Z); } @@ -167,6 +160,107 @@ bool cBoundingBox::IsInside(const Vector3d & a_Min, const Vector3d & a_Max) +bool cBoundingBox::IsInside(const Vector3d & a_Min, const Vector3d & a_Max, const Vector3d & a_Point) +{ + return ( + ((a_Point.x >= a_Min.x) && (a_Point.x < a_Max.x)) && + ((a_Point.y >= a_Min.y) && (a_Point.y < a_Max.y)) && + ((a_Point.z >= a_Min.z) && (a_Point.z < a_Max.z)) + ); +} + + + + + +bool cBoundingBox::IsInside(const Vector3d & a_Min, const Vector3d & a_Max, double a_X, double a_Y, double a_Z) +{ + return ( + ((a_X >= a_Min.x) && (a_X < a_Max.x)) && + ((a_Y >= a_Min.y) && (a_Y < a_Max.y)) && + ((a_Z >= a_Min.z) && (a_Z < a_Max.z)) + ); +} + + + + + +bool cBoundingBox::CalcLineIntersection(const Vector3d & a_Line1, const Vector3d & a_Line2, double & a_LineCoeff, char & a_Face) +{ + return CalcLineIntersection(m_Min, m_Max, a_Line1, a_Line2, a_LineCoeff, a_Face); +} + + + + + +bool cBoundingBox::CalcLineIntersection(const Vector3d & a_Min, const Vector3d & a_Max, const Vector3d & a_Line1, const Vector3d & a_Line2, double & a_LineCoeff, char & a_Face) +{ + char Face = 0; + double Coeff = Vector3d::NO_INTERSECTION; + + // Check each individual bbox face for intersection with the line, remember the one with the lowest coeff + double c = a_Line1.LineCoeffToXYPlane(a_Line2, a_Min.z); + if (c < Coeff) + { + Face = (a_Line1.z > a_Line2.z) ? BLOCK_FACE_ZP : BLOCK_FACE_ZM; + Coeff = c; + } + c = a_Line1.LineCoeffToXYPlane(a_Line2, a_Max.z); + if (c < Coeff) + { + Face = (a_Line1.z > a_Line2.z) ? BLOCK_FACE_ZP : BLOCK_FACE_ZM; + Coeff = c; + } + c = a_Line1.LineCoeffToXZPlane(a_Line2, a_Min.y); + if (c < Coeff) + { + Face = (a_Line1.y > a_Line2.y) ? BLOCK_FACE_YP : BLOCK_FACE_YM; + Coeff = c; + } + c = a_Line1.LineCoeffToXZPlane(a_Line2, a_Max.y); + if (c < Coeff) + { + Face = (a_Line1.y > a_Line2.y) ? BLOCK_FACE_YP : BLOCK_FACE_YM; + Coeff = c; + } + c = a_Line1.LineCoeffToYZPlane(a_Line2, a_Min.x); + if (c < Coeff) + { + Face = (a_Line1.x > a_Line2.x) ? BLOCK_FACE_XP : BLOCK_FACE_XM; + Coeff = c; + } + c = a_Line1.LineCoeffToYZPlane(a_Line2, a_Max.x); + if (c < Coeff) + { + Face = (a_Line1.x > a_Line2.x) ? BLOCK_FACE_XP : BLOCK_FACE_XM; + Coeff = c; + } + + if (Coeff >= Vector3d::NO_INTERSECTION) + { + // There has been no intersection + return false; + } + + Vector3d Intersection = a_Line1 + (a_Line2 - a_Line1) * Coeff; + if (!IsInside(a_Min, a_Max, Intersection)) + { + // The line intersects with the individual wall planes, but not within this bounding box + return false; + } + + // True intersection, return all the values: + a_LineCoeff = Coeff; + a_Face = Face; + return true; +} + + + + + bool cBoundingBox::Intersect(const cBoundingBox & a_Other, cBoundingBox & a_Intersection) { a_Intersection.m_Min.x = std::max(m_Min.x, a_Other.m_Min.x); -- cgit v1.2.3