/* =========================================================================== Copyright (C) 2000 - 2013, Raven Software, Inc. Copyright (C) 2001 - 2013, Activision, Inc. Copyright (C) 2013 - 2015, OpenJK contributors This file is part of the OpenJK source code. OpenJK is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License version 2 as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, see . =========================================================================== */ //////////////////////////////////////////////////////////////////////////////////////// // RAVEN STANDARD TEMPLATE LIBRARY // (c) 2002 Activision // // // Vector Library // -------------- // // // // // NOTES: // 05/31/02 - CREATED // // //////////////////////////////////////////////////////////////////////////////////////// #if !defined(ASSERT_H_INC) #include #define ASSERT_H_INC #endif #include #include #include #include "CBounds.h" //////////////////////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////////////////////// /*void CBBox::ThroughMatrix(const CBBox &from, const CMatrix4 &mat) { Clear(); CVec3 bb,t; int i; const CVec3 &xmn=from.GetMin(); const CVec3 &xmx=from.GetMax(); for ( i = 0; i < 8; i++ ) { if ( i & 1 ) bb[0] = xmn[0]; else bb[0] = xmx[0]; if ( i & 2 ) bb[1] = xmn[1]; else bb[1] = xmx[1]; if ( i & 4 ) bb[2] = xmn[2]; else bb[2] = xmx[2]; mat.XFormPoint(t,bb); AddPoint(t); } }*/ //////////////////////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////////////////////// float CBBox::LargestAxisSize() const { CVec3 Work(mMax); Work-=mMin; return Work.MaxElement(); } //////////////////////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////////////////////// float CBBox::DistanceEstimate(const CVec3 &p) const { float ret=0.0f; // X Axis //-------- if (p[0]>mMax[0]) { ret=p[0]-mMax[0]; } else if (p[0]mMax[1]) { ret+=p[1]-mMax[1]; } else if (p[1]mMax[2]) { ret+=p[2]-mMax[2]; } else if (p[2]mMin && vmMax[0]+tolout|| v[1]mMax[1]+tolout|| v[2]mMax[2]+tolout) { return Side_Out; } if (v[0]>mMin[0]+tolin&&v[0]mMin[1]+tolin&&v[1]mMin[2]+tolin&&v[2]b2.mMax[0] || mMin[1]-tolout>b2.mMax[1] || mMin[2]-tolout>b2.mMax[2] || b2.mMin[0]-tolout>mMax[0] || b2.mMin[1]-tolout>mMax[1] || b2.mMin[2]-tolout>mMax[2]) { return false; } return true; } //////////////////////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////////////////////// bool CBBox::SphereTouchTest(const CVec3 &v,float rad) const { if (v[0]mMax[0]+rad|| v[1]mMax[1]+rad|| v[2]mMax[2]+rad) return false; return true; } //////////////////////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////////////////////// TPlanes CBBox::PlaneFlags(const CVec3 &p) { TPlanes ret=0; if (p[0]mMax[0]) { ret|=2; } if (p[1]mMax[1]) { ret|=8; } if (p[2]mMax[2]) { ret|=32; } return ret; } //////////////////////////////////////////////////////////////////////////////////////// // // return true if the segment intersect the box, in that case, return the first contact. //////////////////////////////////////////////////////////////////////////////////////// bool CBBox::HitTest(CBTrace& Tr) const { // Quick Box Cull //---------------- CBBox tmp; tmp.AddPoint(Tr.mStart); tmp.AddPoint(Tr.mStop); if (!BoxTouchTest(tmp)) { return false; } // Initialize Our Ranges //----------------------- Tr.mRange =-1E30f; Tr.mRangeMax = 1E30f; // For Each Non Zero Axis Of The Aim Vector //------------------------------------------ float tmax,tmin,temp; for (int axis=0; axis<3; axis++) { if (fabs(Tr.mAim[axis])>1E-6f) { // Find Mins And Maxs From The Start Along The Axis Of Aim //--------------------------------------------------------- tmax = ((mMax[axis]-Tr.mStart[axis])/Tr.mAim[axis]); tmin = ((mMin[axis]-Tr.mStart[axis])/Tr.mAim[axis]); if (tmaxTr.mRange) { Tr.mRange=tmin; Tr.mNormal.Clear(); Tr.mNormal[axis]=-1.0f; } } } // Missed? //--------- if (Tr.mRangeMaxTr.mLength) { return false; } // Start Solid Conditions //------------------------ if (Tr.mRange<0.0f) { Tr.mRange = 0.0f; Tr.mPoint = Tr.mStart; return true; } // Calculate The End Point //------------------------- Tr.mPoint = Tr.mAim; Tr.mPoint *= Tr.mRange; Tr.mPoint += Tr.mStart; return true; } //////////////////////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////////////////////// void CBBox::FromStr(const char *s) { assert(s && s[0]); char MinS[256]; char MaxS[266]; sscanf(s, "(%s|%s)", MinS, MaxS); mMin.FromStr(MinS); mMax.FromStr(MaxS); } //////////////////////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////////////////////// void CBBox::ToStr(char* s) { assert(s && s[0]); char MinS[256]; char MaxS[266]; mMin.ToStr(MinS); mMax.ToStr(MaxS); sprintf(s, "(%s|%s)", MinS, MaxS); } //////////////////////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////////////////////// void CBBox::Validate() { assert(mMax>=mMin); }