| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813 |
- /*
- -----------------------------------------------------------------------------
- This source file is part of OGRE
- (Object-oriented Graphics Rendering Engine)
- For the latest info, see http://www.ogre3d.org/
- Copyright (c) 2000-2011 Torus Knot Software Ltd
- Permission is hereby granted, free of charge, to any person obtaining a copy
- of this software and associated documentation files (the "Software"), to deal
- in the Software without restriction, including without limitation the rights
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- copies of the Software, and to permit persons to whom the Software is
- furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice shall be included in
- all copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- THE SOFTWARE.
- -----------------------------------------------------------------------------
- */
- #ifndef __AxisAlignedBox_H_
- #define __AxisAlignedBox_H_
- // Precompiler options
- #include "CmPrerequisitesUtil.h"
- #include "CmVector3.h"
- #include "CmMatrix4.h"
- namespace CamelotFramework {
- /** \addtogroup Core
- * @{
- */
- /** \addtogroup Math
- * @{
- */
- /** A 3D box aligned with the x/y/z axes.
- @remarks
- This class represents a simple box which is aligned with the
- axes. Internally it only stores 2 points as the extremeties of
- the box, one which is the minima of all 3 axes, and the other
- which is the maxima of all 3 axes. This class is typically used
- for an axis-aligned bounding box (AABB) for collision and
- visibility determination.
- */
- class CM_UTILITY_EXPORT AxisAlignedBox
- {
- public:
- enum Extent
- {
- EXTENT_NULL,
- EXTENT_FINITE,
- EXTENT_INFINITE
- };
- protected:
- Vector3 mMinimum;
- Vector3 mMaximum;
- Extent mExtent;
- mutable Vector3* mpCorners;
- public:
- /*
- 1-----2
- /| /|
- / | / |
- 5-----4 |
- | 0--|--3
- | / | /
- |/ |/
- 6-----7
- */
- typedef enum {
- FAR_LEFT_BOTTOM = 0,
- FAR_LEFT_TOP = 1,
- FAR_RIGHT_TOP = 2,
- FAR_RIGHT_BOTTOM = 3,
- NEAR_RIGHT_BOTTOM = 7,
- NEAR_LEFT_BOTTOM = 6,
- NEAR_LEFT_TOP = 5,
- NEAR_RIGHT_TOP = 4
- } CornerEnum;
- inline AxisAlignedBox() : mMinimum(Vector3::ZERO), mMaximum(Vector3::UNIT_SCALE), mpCorners(0)
- {
- // Default to a null box
- setMinimum( -0.5, -0.5, -0.5 );
- setMaximum( 0.5, 0.5, 0.5 );
- mExtent = EXTENT_NULL;
- }
- inline AxisAlignedBox(Extent e) : mMinimum(Vector3::ZERO), mMaximum(Vector3::UNIT_SCALE), mpCorners(0)
- {
- setMinimum( -0.5, -0.5, -0.5 );
- setMaximum( 0.5, 0.5, 0.5 );
- mExtent = e;
- }
- inline AxisAlignedBox(const AxisAlignedBox & rkBox) : mMinimum(Vector3::ZERO), mMaximum(Vector3::UNIT_SCALE), mpCorners(0)
- {
- if (rkBox.isNull())
- setNull();
- else if (rkBox.isInfinite())
- setInfinite();
- else
- setExtents( rkBox.mMinimum, rkBox.mMaximum );
- }
- inline AxisAlignedBox( const Vector3& min, const Vector3& max ) : mMinimum(Vector3::ZERO), mMaximum(Vector3::UNIT_SCALE), mpCorners(0)
- {
- setExtents( min, max );
- }
- inline AxisAlignedBox(
- float mx, float my, float mz,
- float Mx, float My, float Mz ) : mMinimum(Vector3::ZERO), mMaximum(Vector3::UNIT_SCALE), mpCorners(0)
- {
- setExtents( mx, my, mz, Mx, My, Mz );
- }
- AxisAlignedBox& operator=(const AxisAlignedBox& rhs)
- {
- // Specifically override to avoid copying mpCorners
- if (rhs.isNull())
- setNull();
- else if (rhs.isInfinite())
- setInfinite();
- else
- setExtents(rhs.mMinimum, rhs.mMaximum);
- return *this;
- }
- ~AxisAlignedBox()
- {
- if (mpCorners)
- free(mpCorners);
- }
- /** Gets the minimum corner of the box.
- */
- inline const Vector3& getMinimum(void) const
- {
- return mMinimum;
- }
- /** Gets a modifiable version of the minimum
- corner of the box.
- */
- inline Vector3& getMinimum(void)
- {
- return mMinimum;
- }
- /** Gets the maximum corner of the box.
- */
- inline const Vector3& getMaximum(void) const
- {
- return mMaximum;
- }
- /** Gets a modifiable version of the maximum
- corner of the box.
- */
- inline Vector3& getMaximum(void)
- {
- return mMaximum;
- }
- /** Sets the minimum corner of the box.
- */
- inline void setMinimum( const Vector3& vec )
- {
- mExtent = EXTENT_FINITE;
- mMinimum = vec;
- }
- inline void setMinimum( float x, float y, float z )
- {
- mExtent = EXTENT_FINITE;
- mMinimum.x = x;
- mMinimum.y = y;
- mMinimum.z = z;
- }
- /** Changes one of the components of the minimum corner of the box
- used to resize only one dimension of the box
- */
- inline void setMinimumX(float x)
- {
- mMinimum.x = x;
- }
- inline void setMinimumY(float y)
- {
- mMinimum.y = y;
- }
- inline void setMinimumZ(float z)
- {
- mMinimum.z = z;
- }
- /** Sets the maximum corner of the box.
- */
- inline void setMaximum( const Vector3& vec )
- {
- mExtent = EXTENT_FINITE;
- mMaximum = vec;
- }
- inline void setMaximum( float x, float y, float z )
- {
- mExtent = EXTENT_FINITE;
- mMaximum.x = x;
- mMaximum.y = y;
- mMaximum.z = z;
- }
- /** Changes one of the components of the maximum corner of the box
- used to resize only one dimension of the box
- */
- inline void setMaximumX( float x )
- {
- mMaximum.x = x;
- }
- inline void setMaximumY( float y )
- {
- mMaximum.y = y;
- }
- inline void setMaximumZ( float z )
- {
- mMaximum.z = z;
- }
- /** Sets both minimum and maximum extents at once.
- */
- inline void setExtents( const Vector3& min, const Vector3& max )
- {
- assert( (min.x <= max.x && min.y <= max.y && min.z <= max.z) &&
- "The minimum corner of the box must be less than or equal to maximum corner" );
- mExtent = EXTENT_FINITE;
- mMinimum = min;
- mMaximum = max;
- }
- inline void setExtents(
- float mx, float my, float mz,
- float Mx, float My, float Mz )
- {
- assert( (mx <= Mx && my <= My && mz <= Mz) &&
- "The minimum corner of the box must be less than or equal to maximum corner" );
- mExtent = EXTENT_FINITE;
- mMinimum.x = mx;
- mMinimum.y = my;
- mMinimum.z = mz;
- mMaximum.x = Mx;
- mMaximum.y = My;
- mMaximum.z = Mz;
- }
- /** Returns a pointer to an array of 8 corner points, useful for
- collision vs. non-aligned objects.
- @remarks
- If the order of these corners is important, they are as
- follows: The 4 points of the minimum Z face (note that
- because Engine uses right-handed coordinates, the minimum Z is
- at the 'back' of the box) starting with the minimum point of
- all, then anticlockwise around this face (if you are looking
- onto the face from outside the box). Then the 4 points of the
- maximum Z face, starting with maximum point of all, then
- anticlockwise around this face (looking onto the face from
- outside the box). Like this:
- <pre>
- 1-----2
- /| /|
- / | / |
- 5-----4 |
- | 0--|--3
- | / | /
- |/ |/
- 6-----7
- </pre>
- @remarks as this implementation uses a static member, make sure to use your own copy !
- */
- inline const Vector3* getAllCorners(void) const
- {
- assert( (mExtent == EXTENT_FINITE) && "Can't get corners of a null or infinite AAB" );
- // The order of these items is, using right-handed co-ordinates:
- // Minimum Z face, starting with Min(all), then anticlockwise
- // around face (looking onto the face)
- // Maximum Z face, starting with Max(all), then anticlockwise
- // around face (looking onto the face)
- // Only for optimization/compatibility.
- if (!mpCorners)
- mpCorners = (Vector3*)malloc(sizeof(Vector3) * 8);
- mpCorners[0] = mMinimum;
- mpCorners[1].x = mMinimum.x; mpCorners[1].y = mMaximum.y; mpCorners[1].z = mMinimum.z;
- mpCorners[2].x = mMaximum.x; mpCorners[2].y = mMaximum.y; mpCorners[2].z = mMinimum.z;
- mpCorners[3].x = mMaximum.x; mpCorners[3].y = mMinimum.y; mpCorners[3].z = mMinimum.z;
- mpCorners[4] = mMaximum;
- mpCorners[5].x = mMinimum.x; mpCorners[5].y = mMaximum.y; mpCorners[5].z = mMaximum.z;
- mpCorners[6].x = mMinimum.x; mpCorners[6].y = mMinimum.y; mpCorners[6].z = mMaximum.z;
- mpCorners[7].x = mMaximum.x; mpCorners[7].y = mMinimum.y; mpCorners[7].z = mMaximum.z;
- return mpCorners;
- }
- /** gets the position of one of the corners
- */
- Vector3 getCorner(CornerEnum cornerToGet) const
- {
- switch(cornerToGet)
- {
- case FAR_LEFT_BOTTOM:
- return mMinimum;
- case FAR_LEFT_TOP:
- return Vector3(mMinimum.x, mMaximum.y, mMinimum.z);
- case FAR_RIGHT_TOP:
- return Vector3(mMaximum.x, mMaximum.y, mMinimum.z);
- case FAR_RIGHT_BOTTOM:
- return Vector3(mMaximum.x, mMinimum.y, mMinimum.z);
- case NEAR_RIGHT_BOTTOM:
- return Vector3(mMaximum.x, mMinimum.y, mMaximum.z);
- case NEAR_LEFT_BOTTOM:
- return Vector3(mMinimum.x, mMinimum.y, mMaximum.z);
- case NEAR_LEFT_TOP:
- return Vector3(mMinimum.x, mMaximum.y, mMaximum.z);
- case NEAR_RIGHT_TOP:
- return mMaximum;
- default:
- return Vector3();
- }
- }
- CM_UTILITY_EXPORT friend std::ostream& operator<<( std::ostream& o, const AxisAlignedBox aab )
- {
- switch (aab.mExtent)
- {
- case EXTENT_NULL:
- o << "AxisAlignedBox(null)";
- return o;
- case EXTENT_FINITE:
- o << "AxisAlignedBox(min=" << aab.mMinimum << ", max=" << aab.mMaximum << ")";
- return o;
- case EXTENT_INFINITE:
- o << "AxisAlignedBox(infinite)";
- return o;
- default: // shut up compiler
- assert( false && "Never reached" );
- return o;
- }
- }
- /** Merges the passed in box into the current box. The result is the
- box which encompasses both.
- */
- void merge( const AxisAlignedBox& rhs )
- {
- // Do nothing if rhs null, or this is infinite
- if ((rhs.mExtent == EXTENT_NULL) || (mExtent == EXTENT_INFINITE))
- {
- return;
- }
- // Otherwise if rhs is infinite, make this infinite, too
- else if (rhs.mExtent == EXTENT_INFINITE)
- {
- mExtent = EXTENT_INFINITE;
- }
- // Otherwise if current null, just take rhs
- else if (mExtent == EXTENT_NULL)
- {
- setExtents(rhs.mMinimum, rhs.mMaximum);
- }
- // Otherwise merge
- else
- {
- Vector3 min = mMinimum;
- Vector3 max = mMaximum;
- max.makeCeil(rhs.mMaximum);
- min.makeFloor(rhs.mMinimum);
- setExtents(min, max);
- }
- }
- /** Extends the box to encompass the specified point (if needed).
- */
- inline void merge( const Vector3& point )
- {
- switch (mExtent)
- {
- case EXTENT_NULL: // if null, use this point
- setExtents(point, point);
- return;
- case EXTENT_FINITE:
- mMaximum.makeCeil(point);
- mMinimum.makeFloor(point);
- return;
- case EXTENT_INFINITE: // if infinite, makes no difference
- return;
- }
- assert( false && "Never reached" );
- }
- /** Transforms the box according to the matrix supplied.
- @remarks
- By calling this method you get the axis-aligned box which
- surrounds the transformed version of this box. Therefore each
- corner of the box is transformed by the matrix, then the
- extents are mapped back onto the axes to produce another
- AABB. Useful when you have a local AABB for an object which
- is then transformed.
- */
- inline void transform( const Matrix4& matrix )
- {
- // Do nothing if current null or infinite
- if( mExtent != EXTENT_FINITE )
- return;
- Vector3 oldMin, oldMax, currentCorner;
- // Getting the old values so that we can use the existing merge method.
- oldMin = mMinimum;
- oldMax = mMaximum;
- // reset
- setNull();
- // We sequentially compute the corners in the following order :
- // 0, 6, 5, 1, 2, 4 ,7 , 3
- // This sequence allows us to only change one member at a time to get at all corners.
- // For each one, we transform it using the matrix
- // Which gives the resulting point and merge the resulting point.
- // First corner
- // min min min
- currentCorner = oldMin;
- merge( matrix * currentCorner );
- // min,min,max
- currentCorner.z = oldMax.z;
- merge( matrix * currentCorner );
- // min max max
- currentCorner.y = oldMax.y;
- merge( matrix * currentCorner );
- // min max min
- currentCorner.z = oldMin.z;
- merge( matrix * currentCorner );
- // max max min
- currentCorner.x = oldMax.x;
- merge( matrix * currentCorner );
- // max max max
- currentCorner.z = oldMax.z;
- merge( matrix * currentCorner );
- // max min max
- currentCorner.y = oldMin.y;
- merge( matrix * currentCorner );
- // max min min
- currentCorner.z = oldMin.z;
- merge( matrix * currentCorner );
- }
- /** Transforms the box according to the affine matrix supplied.
- @remarks
- By calling this method you get the axis-aligned box which
- surrounds the transformed version of this box. Therefore each
- corner of the box is transformed by the matrix, then the
- extents are mapped back onto the axes to produce another
- AABB. Useful when you have a local AABB for an object which
- is then transformed.
- @note
- The matrix must be an affine matrix. @see Matrix4::isAffine.
- */
- void transformAffine(const Matrix4& m)
- {
- assert(m.isAffine());
- // Do nothing if current null or infinite
- if ( mExtent != EXTENT_FINITE )
- return;
- Vector3 centre = getCenter();
- Vector3 halfSize = getHalfSize();
- Vector3 newCentre = m.transformAffine(centre);
- Vector3 newHalfSize(
- Math::Abs(m[0][0]) * halfSize.x + Math::Abs(m[0][1]) * halfSize.y + Math::Abs(m[0][2]) * halfSize.z,
- Math::Abs(m[1][0]) * halfSize.x + Math::Abs(m[1][1]) * halfSize.y + Math::Abs(m[1][2]) * halfSize.z,
- Math::Abs(m[2][0]) * halfSize.x + Math::Abs(m[2][1]) * halfSize.y + Math::Abs(m[2][2]) * halfSize.z);
- setExtents(newCentre - newHalfSize, newCentre + newHalfSize);
- }
- /** Sets the box to a 'null' value i.e. not a box.
- */
- inline void setNull()
- {
- mExtent = EXTENT_NULL;
- }
- /** Returns true if the box is null i.e. empty.
- */
- inline bool isNull(void) const
- {
- return (mExtent == EXTENT_NULL);
- }
- /** Returns true if the box is finite.
- */
- bool isFinite(void) const
- {
- return (mExtent == EXTENT_FINITE);
- }
- /** Sets the box to 'infinite'
- */
- inline void setInfinite()
- {
- mExtent = EXTENT_INFINITE;
- }
- /** Returns true if the box is infinite.
- */
- bool isInfinite(void) const
- {
- return (mExtent == EXTENT_INFINITE);
- }
- /** Returns whether or not this box intersects another. */
- inline bool intersects(const AxisAlignedBox& b2) const
- {
- // Early-fail for nulls
- if (this->isNull() || b2.isNull())
- return false;
- // Early-success for infinites
- if (this->isInfinite() || b2.isInfinite())
- return true;
- // Use up to 6 separating planes
- if (mMaximum.x < b2.mMinimum.x)
- return false;
- if (mMaximum.y < b2.mMinimum.y)
- return false;
- if (mMaximum.z < b2.mMinimum.z)
- return false;
- if (mMinimum.x > b2.mMaximum.x)
- return false;
- if (mMinimum.y > b2.mMaximum.y)
- return false;
- if (mMinimum.z > b2.mMaximum.z)
- return false;
- // otherwise, must be intersecting
- return true;
- }
- /// Calculate the area of intersection of this box and another
- inline AxisAlignedBox intersection(const AxisAlignedBox& b2) const
- {
- if (this->isNull() || b2.isNull())
- {
- return AxisAlignedBox();
- }
- else if (this->isInfinite())
- {
- return b2;
- }
- else if (b2.isInfinite())
- {
- return *this;
- }
- Vector3 intMin = mMinimum;
- Vector3 intMax = mMaximum;
- intMin.makeCeil(b2.getMinimum());
- intMax.makeFloor(b2.getMaximum());
- // Check intersection isn't null
- if (intMin.x < intMax.x &&
- intMin.y < intMax.y &&
- intMin.z < intMax.z)
- {
- return AxisAlignedBox(intMin, intMax);
- }
- return AxisAlignedBox();
- }
- /// Calculate the volume of this box
- float volume(void) const
- {
- switch (mExtent)
- {
- case EXTENT_NULL:
- return 0.0f;
- case EXTENT_FINITE:
- {
- Vector3 diff = mMaximum - mMinimum;
- return diff.x * diff.y * diff.z;
- }
- case EXTENT_INFINITE:
- return Math::POS_INFINITY;
- default: // shut up compiler
- assert( false && "Never reached" );
- return 0.0f;
- }
- }
- /** Scales the AABB by the vector given. */
- inline void scale(const Vector3& s)
- {
- // Do nothing if current null or infinite
- if (mExtent != EXTENT_FINITE)
- return;
- // NB assumes centered on origin
- Vector3 min = mMinimum * s;
- Vector3 max = mMaximum * s;
- setExtents(min, max);
- }
- /** Tests whether this box intersects a sphere. */
- bool intersects(const Sphere& s) const
- {
- return Math::intersects(s, *this);
- }
- /** Tests whether this box intersects a plane. */
- bool intersects(const Plane& p) const
- {
- return Math::intersects(p, *this);
- }
- /** Tests whether the vector point is within this box. */
- bool intersects(const Vector3& v) const
- {
- switch (mExtent)
- {
- case EXTENT_NULL:
- return false;
- case EXTENT_FINITE:
- return(v.x >= mMinimum.x && v.x <= mMaximum.x &&
- v.y >= mMinimum.y && v.y <= mMaximum.y &&
- v.z >= mMinimum.z && v.z <= mMaximum.z);
- case EXTENT_INFINITE:
- return true;
- default: // shut up compiler
- assert( false && "Never reached" );
- return false;
- }
- }
- /// Gets the centre of the box
- Vector3 getCenter(void) const
- {
- assert( (mExtent == EXTENT_FINITE) && "Can't get center of a null or infinite AAB" );
- return Vector3(
- (mMaximum.x + mMinimum.x) * 0.5f,
- (mMaximum.y + mMinimum.y) * 0.5f,
- (mMaximum.z + mMinimum.z) * 0.5f);
- }
- /// Gets the size of the box
- Vector3 getSize(void) const
- {
- switch (mExtent)
- {
- case EXTENT_NULL:
- return Vector3::ZERO;
- case EXTENT_FINITE:
- return mMaximum - mMinimum;
- case EXTENT_INFINITE:
- return Vector3(
- Math::POS_INFINITY,
- Math::POS_INFINITY,
- Math::POS_INFINITY);
- default: // shut up compiler
- assert( false && "Never reached" );
- return Vector3::ZERO;
- }
- }
- /// Gets the half-size of the box
- Vector3 getHalfSize(void) const
- {
- switch (mExtent)
- {
- case EXTENT_NULL:
- return Vector3::ZERO;
- case EXTENT_FINITE:
- return (mMaximum - mMinimum) * 0.5;
- case EXTENT_INFINITE:
- return Vector3(
- Math::POS_INFINITY,
- Math::POS_INFINITY,
- Math::POS_INFINITY);
- default: // shut up compiler
- assert( false && "Never reached" );
- return Vector3::ZERO;
- }
- }
- /** Tests whether the given point contained by this box.
- */
- bool contains(const Vector3& v) const
- {
- if (isNull())
- return false;
- if (isInfinite())
- return true;
- return mMinimum.x <= v.x && v.x <= mMaximum.x &&
- mMinimum.y <= v.y && v.y <= mMaximum.y &&
- mMinimum.z <= v.z && v.z <= mMaximum.z;
- }
- /** Tests whether another box contained by this box.
- */
- bool contains(const AxisAlignedBox& other) const
- {
- if (other.isNull() || this->isInfinite())
- return true;
- if (this->isNull() || other.isInfinite())
- return false;
- return this->mMinimum.x <= other.mMinimum.x &&
- this->mMinimum.y <= other.mMinimum.y &&
- this->mMinimum.z <= other.mMinimum.z &&
- other.mMaximum.x <= this->mMaximum.x &&
- other.mMaximum.y <= this->mMaximum.y &&
- other.mMaximum.z <= this->mMaximum.z;
- }
- /** Tests 2 boxes for equality.
- */
- bool operator== (const AxisAlignedBox& rhs) const
- {
- if (this->mExtent != rhs.mExtent)
- return false;
- if (!this->isFinite())
- return true;
- return this->mMinimum == rhs.mMinimum &&
- this->mMaximum == rhs.mMaximum;
- }
- /** Tests 2 boxes for inequality.
- */
- bool operator!= (const AxisAlignedBox& rhs) const
- {
- return !(*this == rhs);
- }
- // special values
- static const AxisAlignedBox BOX_NULL;
- static const AxisAlignedBox BOX_INFINITE;
- };
- /** @} */
- /** @} */
- } // namespace CamelotFramework
- #endif
|