Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: downloads/ogre_src_v1-9-0/OgreMain/include/OgreAxisAlignedBox.h @ 148

Last change on this file since 148 was 148, checked in by patricwi, 6 years ago

Added new dependencies for ogre1.9 and cegui0.8

File size: 21.0 KB
Line 
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4(Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2013 Torus Knot Software Ltd
8
9Permission is hereby granted, free of charge, to any person obtaining a copy
10of this software and associated documentation files (the "Software"), to deal
11in the Software without restriction, including without limitation the rights
12to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13copies of the Software, and to permit persons to whom the Software is
14furnished to do so, subject to the following conditions:
15
16The above copyright notice and this permission notice shall be included in
17all copies or substantial portions of the Software.
18
19THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25THE SOFTWARE.
26-----------------------------------------------------------------------------
27*/
28#ifndef __AxisAlignedBox_H_
29#define __AxisAlignedBox_H_
30
31// Precompiler options
32#include "OgrePrerequisites.h"
33
34#include "OgreVector3.h"
35#include "OgreMatrix4.h"
36
37namespace Ogre {
38        /** \addtogroup Core
39        *  @{
40        */
41        /** \addtogroup Math
42        *  @{
43        */
44
45        /** A 3D box aligned with the x/y/z axes.
46        @remarks
47        This class represents a simple box which is aligned with the
48        axes. Internally it only stores 2 points as the extremeties of
49        the box, one which is the minima of all 3 axes, and the other
50        which is the maxima of all 3 axes. This class is typically used
51        for an axis-aligned bounding box (AABB) for collision and
52        visibility determination.
53        */
54        class _OgreExport AxisAlignedBox
55        {
56        public:
57                enum Extent
58                {
59                        EXTENT_NULL,
60                        EXTENT_FINITE,
61                        EXTENT_INFINITE
62                };
63        protected:
64
65                Vector3 mMinimum;
66                Vector3 mMaximum;
67                Extent mExtent;
68                mutable Vector3* mCorners;
69
70        public:
71                /*
72           1-------2
73          /|      /|
74         / |     / |
75        5-------4  |
76        |  0----|--3
77        | /     | /
78        |/      |/
79        6-------7
80                */
81                typedef enum {
82                        FAR_LEFT_BOTTOM = 0,
83                        FAR_LEFT_TOP = 1,
84                        FAR_RIGHT_TOP = 2,
85                        FAR_RIGHT_BOTTOM = 3,
86                        NEAR_RIGHT_BOTTOM = 7,
87                        NEAR_LEFT_BOTTOM = 6,
88                        NEAR_LEFT_TOP = 5,
89                        NEAR_RIGHT_TOP = 4
90                } CornerEnum;
91                inline AxisAlignedBox() : mMinimum(Vector3::ZERO), mMaximum(Vector3::UNIT_SCALE), mCorners(0)
92                {
93                        // Default to a null box
94                        setMinimum( -0.5, -0.5, -0.5 );
95                        setMaximum( 0.5, 0.5, 0.5 );
96                        mExtent = EXTENT_NULL;
97                }
98                inline AxisAlignedBox(Extent e) : mMinimum(Vector3::ZERO), mMaximum(Vector3::UNIT_SCALE), mCorners(0)
99                {
100                        setMinimum( -0.5, -0.5, -0.5 );
101                        setMaximum( 0.5, 0.5, 0.5 );
102                        mExtent = e;
103                }
104
105                inline AxisAlignedBox(const AxisAlignedBox & rkBox) : mMinimum(Vector3::ZERO), mMaximum(Vector3::UNIT_SCALE), mCorners(0)
106
107                {
108                        if (rkBox.isNull())
109                                setNull();
110                        else if (rkBox.isInfinite())
111                                setInfinite();
112                        else
113                                setExtents( rkBox.mMinimum, rkBox.mMaximum );
114                }
115
116                inline AxisAlignedBox( const Vector3& min, const Vector3& max ) : mMinimum(Vector3::ZERO), mMaximum(Vector3::UNIT_SCALE), mCorners(0)
117                {
118                        setExtents( min, max );
119                }
120
121                inline AxisAlignedBox(
122                        Real mx, Real my, Real mz,
123                        Real Mx, Real My, Real Mz ) : mMinimum(Vector3::ZERO), mMaximum(Vector3::UNIT_SCALE), mCorners(0)
124                {
125                        setExtents( mx, my, mz, Mx, My, Mz );
126                }
127
128                AxisAlignedBox& operator=(const AxisAlignedBox& rhs)
129                {
130                        // Specifically override to avoid copying mCorners
131                        if (rhs.isNull())
132                                setNull();
133                        else if (rhs.isInfinite())
134                                setInfinite();
135                        else
136                                setExtents(rhs.mMinimum, rhs.mMaximum);
137
138                        return *this;
139                }
140
141                ~AxisAlignedBox()
142                {
143                        if (mCorners)
144                                OGRE_FREE(mCorners, MEMCATEGORY_SCENE_CONTROL);
145                }
146
147
148                /** Gets the minimum corner of the box.
149                */
150                inline const Vector3& getMinimum(void) const
151                { 
152                        return mMinimum; 
153                }
154
155                /** Gets a modifiable version of the minimum
156                corner of the box.
157                */
158                inline Vector3& getMinimum(void)
159                { 
160                        return mMinimum; 
161                }
162
163                /** Gets the maximum corner of the box.
164                */
165                inline const Vector3& getMaximum(void) const
166                { 
167                        return mMaximum;
168                }
169
170                /** Gets a modifiable version of the maximum
171                corner of the box.
172                */
173                inline Vector3& getMaximum(void)
174                { 
175                        return mMaximum;
176                }
177
178
179                /** Sets the minimum corner of the box.
180                */
181                inline void setMinimum( const Vector3& vec )
182                {
183                        mExtent = EXTENT_FINITE;
184                        mMinimum = vec;
185                }
186
187                inline void setMinimum( Real x, Real y, Real z )
188                {
189                        mExtent = EXTENT_FINITE;
190                        mMinimum.x = x;
191                        mMinimum.y = y;
192                        mMinimum.z = z;
193                }
194
195                /** Changes one of the components of the minimum corner of the box
196                used to resize only one dimension of the box
197                */
198                inline void setMinimumX(Real x)
199                {
200                        mMinimum.x = x;
201                }
202
203                inline void setMinimumY(Real y)
204                {
205                        mMinimum.y = y;
206                }
207
208                inline void setMinimumZ(Real z)
209                {
210                        mMinimum.z = z;
211                }
212
213                /** Sets the maximum corner of the box.
214                */
215                inline void setMaximum( const Vector3& vec )
216                {
217                        mExtent = EXTENT_FINITE;
218                        mMaximum = vec;
219                }
220
221                inline void setMaximum( Real x, Real y, Real z )
222                {
223                        mExtent = EXTENT_FINITE;
224                        mMaximum.x = x;
225                        mMaximum.y = y;
226                        mMaximum.z = z;
227                }
228
229                /** Changes one of the components of the maximum corner of the box
230                used to resize only one dimension of the box
231                */
232                inline void setMaximumX( Real x )
233                {
234                        mMaximum.x = x;
235                }
236
237                inline void setMaximumY( Real y )
238                {
239                        mMaximum.y = y;
240                }
241
242                inline void setMaximumZ( Real z )
243                {
244                        mMaximum.z = z;
245                }
246
247                /** Sets both minimum and maximum extents at once.
248                */
249                inline void setExtents( const Vector3& min, const Vector3& max )
250                {
251            assert( (min.x <= max.x && min.y <= max.y && min.z <= max.z) &&
252                "The minimum corner of the box must be less than or equal to maximum corner" );
253
254                        mExtent = EXTENT_FINITE;
255                        mMinimum = min;
256                        mMaximum = max;
257                }
258
259                inline void setExtents(
260                        Real mx, Real my, Real mz,
261                        Real Mx, Real My, Real Mz )
262                {
263            assert( (mx <= Mx && my <= My && mz <= Mz) &&
264                "The minimum corner of the box must be less than or equal to maximum corner" );
265
266                        mExtent = EXTENT_FINITE;
267
268                        mMinimum.x = mx;
269                        mMinimum.y = my;
270                        mMinimum.z = mz;
271
272                        mMaximum.x = Mx;
273                        mMaximum.y = My;
274                        mMaximum.z = Mz;
275
276                }
277
278                /** Returns a pointer to an array of 8 corner points, useful for
279                collision vs. non-aligned objects.
280                @remarks
281                If the order of these corners is important, they are as
282                follows: The 4 points of the minimum Z face (note that
283                because Ogre uses right-handed coordinates, the minimum Z is
284                at the 'back' of the box) starting with the minimum point of
285                all, then anticlockwise around this face (if you are looking
286                onto the face from outside the box). Then the 4 points of the
287                maximum Z face, starting with maximum point of all, then
288                anticlockwise around this face (looking onto the face from
289                outside the box). Like this:
290                <pre>
291           1-------2
292          /|      /|
293         / |     / |
294        5-------4  |
295        |  0----|--3
296        | /     | /
297        |/      |/
298        6-------7
299                </pre>
300                */
301                inline const Vector3* getAllCorners(void) const
302                {
303                        assert( (mExtent == EXTENT_FINITE) && "Can't get corners of a null or infinite AAB" );
304
305                        // The order of these items is, using right-handed co-ordinates:
306                        // Minimum Z face, starting with Min(all), then anticlockwise
307                        //   around face (looking onto the face)
308                        // Maximum Z face, starting with Max(all), then anticlockwise
309                        //   around face (looking onto the face)
310                        // Only for optimization/compatibility.
311                        if (!mCorners)
312                                mCorners = OGRE_ALLOC_T(Vector3, 8, MEMCATEGORY_SCENE_CONTROL);
313
314                        mCorners[0] = mMinimum;
315                        mCorners[1].x = mMinimum.x; mCorners[1].y = mMaximum.y; mCorners[1].z = mMinimum.z;
316                        mCorners[2].x = mMaximum.x; mCorners[2].y = mMaximum.y; mCorners[2].z = mMinimum.z;
317                        mCorners[3].x = mMaximum.x; mCorners[3].y = mMinimum.y; mCorners[3].z = mMinimum.z;           
318
319                        mCorners[4] = mMaximum;
320                        mCorners[5].x = mMinimum.x; mCorners[5].y = mMaximum.y; mCorners[5].z = mMaximum.z;
321                        mCorners[6].x = mMinimum.x; mCorners[6].y = mMinimum.y; mCorners[6].z = mMaximum.z;
322                        mCorners[7].x = mMaximum.x; mCorners[7].y = mMinimum.y; mCorners[7].z = mMaximum.z;
323
324                        return mCorners;
325                }
326
327                /** Gets the position of one of the corners
328                */
329                Vector3 getCorner(CornerEnum cornerToGet) const
330                {
331                        switch(cornerToGet)
332                        {
333                        case FAR_LEFT_BOTTOM:
334                                return mMinimum;
335                        case FAR_LEFT_TOP:
336                                return Vector3(mMinimum.x, mMaximum.y, mMinimum.z);
337                        case FAR_RIGHT_TOP:
338                                return Vector3(mMaximum.x, mMaximum.y, mMinimum.z);
339                        case FAR_RIGHT_BOTTOM:
340                                return Vector3(mMaximum.x, mMinimum.y, mMinimum.z);
341                        case NEAR_RIGHT_BOTTOM:
342                                return Vector3(mMaximum.x, mMinimum.y, mMaximum.z);
343                        case NEAR_LEFT_BOTTOM:
344                                return Vector3(mMinimum.x, mMinimum.y, mMaximum.z);
345                        case NEAR_LEFT_TOP:
346                                return Vector3(mMinimum.x, mMaximum.y, mMaximum.z);
347                        case NEAR_RIGHT_TOP:
348                                return mMaximum;
349                        default:
350                                return Vector3();
351                        }
352                }
353
354                _OgreExport friend std::ostream& operator<<( std::ostream& o, const AxisAlignedBox &aab )
355                {
356                        switch (aab.mExtent)
357                        {
358                        case EXTENT_NULL:
359                                o << "AxisAlignedBox(null)";
360                                return o;
361
362                        case EXTENT_FINITE:
363                                o << "AxisAlignedBox(min=" << aab.mMinimum << ", max=" << aab.mMaximum << ")";
364                                return o;
365
366                        case EXTENT_INFINITE:
367                                o << "AxisAlignedBox(infinite)";
368                                return o;
369
370                        default: // shut up compiler
371                                assert( false && "Never reached" );
372                                return o;
373                        }
374                }
375
376                /** Merges the passed in box into the current box. The result is the
377                box which encompasses both.
378                */
379                void merge( const AxisAlignedBox& rhs )
380                {
381                        // Do nothing if rhs null, or this is infinite
382                        if ((rhs.mExtent == EXTENT_NULL) || (mExtent == EXTENT_INFINITE))
383                        {
384                                return;
385                        }
386                        // Otherwise if rhs is infinite, make this infinite, too
387                        else if (rhs.mExtent == EXTENT_INFINITE)
388                        {
389                                mExtent = EXTENT_INFINITE;
390                        }
391                        // Otherwise if current null, just take rhs
392                        else if (mExtent == EXTENT_NULL)
393                        {
394                                setExtents(rhs.mMinimum, rhs.mMaximum);
395                        }
396                        // Otherwise merge
397                        else
398                        {
399                                Vector3 min = mMinimum;
400                                Vector3 max = mMaximum;
401                                max.makeCeil(rhs.mMaximum);
402                                min.makeFloor(rhs.mMinimum);
403
404                                setExtents(min, max);
405                        }
406
407                }
408
409                /** Extends the box to encompass the specified point (if needed).
410                */
411                inline void merge( const Vector3& point )
412                {
413                        switch (mExtent)
414                        {
415                        case EXTENT_NULL: // if null, use this point
416                                setExtents(point, point);
417                                return;
418
419                        case EXTENT_FINITE:
420                                mMaximum.makeCeil(point);
421                                mMinimum.makeFloor(point);
422                                return;
423
424                        case EXTENT_INFINITE: // if infinite, makes no difference
425                                return;
426                        }
427
428                        assert( false && "Never reached" );
429                }
430
431                /** Transforms the box according to the matrix supplied.
432                @remarks
433                By calling this method you get the axis-aligned box which
434                surrounds the transformed version of this box. Therefore each
435                corner of the box is transformed by the matrix, then the
436                extents are mapped back onto the axes to produce another
437                AABB. Useful when you have a local AABB for an object which
438                is then transformed.
439                */
440                inline void transform( const Matrix4& matrix )
441                {
442                        // Do nothing if current null or infinite
443                        if( mExtent != EXTENT_FINITE )
444                                return;
445
446                        Vector3 oldMin, oldMax, currentCorner;
447
448                        // Getting the old values so that we can use the existing merge method.
449                        oldMin = mMinimum;
450                        oldMax = mMaximum;
451
452                        // reset
453                        setNull();
454
455                        // We sequentially compute the corners in the following order :
456                        // 0, 6, 5, 1, 2, 4 ,7 , 3
457                        // This sequence allows us to only change one member at a time to get at all corners.
458
459                        // For each one, we transform it using the matrix
460                        // Which gives the resulting point and merge the resulting point.
461
462                        // First corner
463                        // min min min
464                        currentCorner = oldMin;
465                        merge( matrix * currentCorner );
466
467                        // min,min,max
468                        currentCorner.z = oldMax.z;
469                        merge( matrix * currentCorner );
470
471                        // min max max
472                        currentCorner.y = oldMax.y;
473                        merge( matrix * currentCorner );
474
475                        // min max min
476                        currentCorner.z = oldMin.z;
477                        merge( matrix * currentCorner );
478
479                        // max max min
480                        currentCorner.x = oldMax.x;
481                        merge( matrix * currentCorner );
482
483                        // max max max
484                        currentCorner.z = oldMax.z;
485                        merge( matrix * currentCorner );
486
487                        // max min max
488                        currentCorner.y = oldMin.y;
489                        merge( matrix * currentCorner );
490
491                        // max min min
492                        currentCorner.z = oldMin.z;
493                        merge( matrix * currentCorner ); 
494                }
495
496                /** Transforms the box according to the affine matrix supplied.
497                @remarks
498                By calling this method you get the axis-aligned box which
499                surrounds the transformed version of this box. Therefore each
500                corner of the box is transformed by the matrix, then the
501                extents are mapped back onto the axes to produce another
502                AABB. Useful when you have a local AABB for an object which
503                is then transformed.
504                @note
505                The matrix must be an affine matrix. @see Matrix4::isAffine.
506                */
507                void transformAffine(const Matrix4& m)
508                {
509                        assert(m.isAffine());
510
511                        // Do nothing if current null or infinite
512                        if ( mExtent != EXTENT_FINITE )
513                                return;
514
515                        Vector3 centre = getCenter();
516                        Vector3 halfSize = getHalfSize();
517
518                        Vector3 newCentre = m.transformAffine(centre);
519                        Vector3 newHalfSize(
520                                Math::Abs(m[0][0]) * halfSize.x + Math::Abs(m[0][1]) * halfSize.y + Math::Abs(m[0][2]) * halfSize.z, 
521                                Math::Abs(m[1][0]) * halfSize.x + Math::Abs(m[1][1]) * halfSize.y + Math::Abs(m[1][2]) * halfSize.z,
522                                Math::Abs(m[2][0]) * halfSize.x + Math::Abs(m[2][1]) * halfSize.y + Math::Abs(m[2][2]) * halfSize.z);
523
524                        setExtents(newCentre - newHalfSize, newCentre + newHalfSize);
525                }
526
527                /** Sets the box to a 'null' value i.e. not a box.
528                */
529                inline void setNull()
530                {
531                        mExtent = EXTENT_NULL;
532                }
533
534                /** Returns true if the box is null i.e. empty.
535                */
536                inline bool isNull(void) const
537                {
538                        return (mExtent == EXTENT_NULL);
539                }
540
541                /** Returns true if the box is finite.
542                */
543                bool isFinite(void) const
544                {
545                        return (mExtent == EXTENT_FINITE);
546                }
547
548                /** Sets the box to 'infinite'
549                */
550                inline void setInfinite()
551                {
552                        mExtent = EXTENT_INFINITE;
553                }
554
555                /** Returns true if the box is infinite.
556                */
557                bool isInfinite(void) const
558                {
559                        return (mExtent == EXTENT_INFINITE);
560                }
561
562                /** Returns whether or not this box intersects another. */
563                inline bool intersects(const AxisAlignedBox& b2) const
564                {
565                        // Early-fail for nulls
566                        if (this->isNull() || b2.isNull())
567                                return false;
568
569                        // Early-success for infinites
570                        if (this->isInfinite() || b2.isInfinite())
571                                return true;
572
573                        // Use up to 6 separating planes
574                        if (mMaximum.x < b2.mMinimum.x)
575                                return false;
576                        if (mMaximum.y < b2.mMinimum.y)
577                                return false;
578                        if (mMaximum.z < b2.mMinimum.z)
579                                return false;
580
581                        if (mMinimum.x > b2.mMaximum.x)
582                                return false;
583                        if (mMinimum.y > b2.mMaximum.y)
584                                return false;
585                        if (mMinimum.z > b2.mMaximum.z)
586                                return false;
587
588                        // otherwise, must be intersecting
589                        return true;
590
591                }
592
593                /// Calculate the area of intersection of this box and another
594                inline AxisAlignedBox intersection(const AxisAlignedBox& b2) const
595                {
596            if (this->isNull() || b2.isNull())
597                        {
598                                return AxisAlignedBox();
599                        }
600                        else if (this->isInfinite())
601                        {
602                                return b2;
603                        }
604                        else if (b2.isInfinite())
605                        {
606                                return *this;
607                        }
608
609                        Vector3 intMin = mMinimum;
610            Vector3 intMax = mMaximum;
611
612            intMin.makeCeil(b2.getMinimum());
613            intMax.makeFloor(b2.getMaximum());
614
615            // Check intersection isn't null
616            if (intMin.x < intMax.x &&
617                intMin.y < intMax.y &&
618                intMin.z < intMax.z)
619            {
620                return AxisAlignedBox(intMin, intMax);
621            }
622
623            return AxisAlignedBox();
624                }
625
626                /// Calculate the volume of this box
627                Real volume(void) const
628                {
629                        switch (mExtent)
630                        {
631                        case EXTENT_NULL:
632                                return 0.0f;
633
634                        case EXTENT_FINITE:
635                                {
636                                        Vector3 diff = mMaximum - mMinimum;
637                                        return diff.x * diff.y * diff.z;
638                                }
639
640                        case EXTENT_INFINITE:
641                                return Math::POS_INFINITY;
642
643                        default: // shut up compiler
644                                assert( false && "Never reached" );
645                                return 0.0f;
646                        }
647                }
648
649                /** Scales the AABB by the vector given. */
650                inline void scale(const Vector3& s)
651                {
652                        // Do nothing if current null or infinite
653                        if (mExtent != EXTENT_FINITE)
654                                return;
655
656                        // NB assumes centered on origin
657                        Vector3 min = mMinimum * s;
658                        Vector3 max = mMaximum * s;
659                        setExtents(min, max);
660                }
661
662                /** Tests whether this box intersects a sphere. */
663                bool intersects(const Sphere& s) const
664                {
665                        return Math::intersects(s, *this); 
666                }
667                /** Tests whether this box intersects a plane. */
668                bool intersects(const Plane& p) const
669                {
670                        return Math::intersects(p, *this);
671                }
672                /** Tests whether the vector point is within this box. */
673                bool intersects(const Vector3& v) const
674                {
675                        switch (mExtent)
676                        {
677                        case EXTENT_NULL:
678                                return false;
679
680                        case EXTENT_FINITE:
681                                return(v.x >= mMinimum.&&  v.x <= mMaximum.&& 
682                                        v.y >= mMinimum.&&  v.y <= mMaximum.&& 
683                                        v.z >= mMinimum.&&  v.z <= mMaximum.z);
684
685                        case EXTENT_INFINITE:
686                                return true;
687
688                        default: // shut up compiler
689                                assert( false && "Never reached" );
690                                return false;
691                        }
692                }
693                /// Gets the centre of the box
694                Vector3 getCenter(void) const
695                {
696                        assert( (mExtent == EXTENT_FINITE) && "Can't get center of a null or infinite AAB" );
697
698                        return Vector3(
699                                (mMaximum.x + mMinimum.x) * 0.5f,
700                                (mMaximum.y + mMinimum.y) * 0.5f,
701                                (mMaximum.z + mMinimum.z) * 0.5f);
702                }
703                /// Gets the size of the box
704                Vector3 getSize(void) const
705                {
706                        switch (mExtent)
707                        {
708                        case EXTENT_NULL:
709                                return Vector3::ZERO;
710
711                        case EXTENT_FINITE:
712                                return mMaximum - mMinimum;
713
714                        case EXTENT_INFINITE:
715                                return Vector3(
716                                        Math::POS_INFINITY,
717                                        Math::POS_INFINITY,
718                                        Math::POS_INFINITY);
719
720                        default: // shut up compiler
721                                assert( false && "Never reached" );
722                                return Vector3::ZERO;
723                        }
724                }
725                /// Gets the half-size of the box
726                Vector3 getHalfSize(void) const
727                {
728                        switch (mExtent)
729                        {
730                        case EXTENT_NULL:
731                                return Vector3::ZERO;
732
733                        case EXTENT_FINITE:
734                                return (mMaximum - mMinimum) * 0.5;
735
736                        case EXTENT_INFINITE:
737                                return Vector3(
738                                        Math::POS_INFINITY,
739                                        Math::POS_INFINITY,
740                                        Math::POS_INFINITY);
741
742                        default: // shut up compiler
743                                assert( false && "Never reached" );
744                                return Vector3::ZERO;
745                        }
746                }
747
748        /** Tests whether the given point contained by this box.
749        */
750        bool contains(const Vector3& v) const
751        {
752            if (isNull())
753                return false;
754            if (isInfinite())
755                return true;
756
757            return mMinimum.x <= v.x && v.x <= mMaximum.x &&
758                   mMinimum.y <= v.y && v.y <= mMaximum.y &&
759                   mMinimum.z <= v.z && v.z <= mMaximum.z;
760        }
761               
762                /** Returns the squared minimum distance between a given point and any part of the box.
763                 *  This is faster than distance since avoiding a squareroot, so use if you can. */
764        Real squaredDistance(const Vector3& v) const
765        {
766
767                        if (this->contains(v))
768                                return 0;
769                        else
770                        {
771                                Vector3 maxDist(0,0,0);
772
773                                if (v.x < mMinimum.x)
774                                        maxDist.x = mMinimum.x - v.x;
775                                else if (v.x > mMaximum.x)
776                                        maxDist.x = v.x - mMaximum.x;
777
778                                if (v.y < mMinimum.y)
779                                        maxDist.y = mMinimum.y - v.y;
780                                else if (v.y > mMaximum.y)
781                                        maxDist.y = v.y - mMaximum.y;
782
783                                if (v.z < mMinimum.z)
784                                        maxDist.z = mMinimum.z - v.z;
785                                else if (v.z > mMaximum.z)
786                                        maxDist.z = v.z - mMaximum.z;
787
788                                return maxDist.squaredLength();
789                        }
790        }
791       
792        /** Returns the minimum distance between a given point and any part of the box. */
793        Real distance (const Vector3& v) const
794        {
795                        return Ogre::Math::Sqrt(squaredDistance(v));
796                }
797
798        /** Tests whether another box contained by this box.
799        */
800        bool contains(const AxisAlignedBox& other) const
801        {
802            if (other.isNull() || this->isInfinite())
803                return true;
804
805            if (this->isNull() || other.isInfinite())
806                return false;
807
808            return this->mMinimum.x <= other.mMinimum.x &&
809                   this->mMinimum.y <= other.mMinimum.y &&
810                   this->mMinimum.z <= other.mMinimum.z &&
811                   other.mMaximum.x <= this->mMaximum.x &&
812                   other.mMaximum.y <= this->mMaximum.y &&
813                   other.mMaximum.z <= this->mMaximum.z;
814        }
815
816        /** Tests 2 boxes for equality.
817        */
818        bool operator== (const AxisAlignedBox& rhs) const
819        {
820            if (this->mExtent != rhs.mExtent)
821                return false;
822
823            if (!this->isFinite())
824                return true;
825
826            return this->mMinimum == rhs.mMinimum &&
827                   this->mMaximum == rhs.mMaximum;
828        }
829
830        /** Tests 2 boxes for inequality.
831        */
832        bool operator!= (const AxisAlignedBox& rhs) const
833        {
834            return !(*this == rhs);
835        }
836
837                // special values
838                static const AxisAlignedBox BOX_NULL;
839                static const AxisAlignedBox BOX_INFINITE;
840
841
842        };
843
844        /** @} */
845        /** @} */
846} // namespace Ogre
847
848#endif
Note: See TracBrowser for help on using the repository browser.