# OgreVector3.h

Go to the documentation of this file.

    00001 /*
    00002 -----------------------------------------------------------------------------
    00003 This source file is part of OGRE
    00004     (Object-oriented Graphics Rendering Engine)
    00005 For the latest info, see http://www.ogre3d.org/
    00006
    00007 Copyright (c) 2000-2005 The OGRE Team
    00008 Also see acknowledgements in Readme.html
    00009
    00010 This program is free software; you can redistribute it and/or modify it under
    00011 the terms of the GNU Lesser General Public License as published by the Free Software
    00012 Foundation; either version 2 of the License, or (at your option) any later
    00013 version.
    00014
    00015 This program is distributed in the hope that it will be useful, but WITHOUT
    00016 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    00017 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
    00018
    00019 You should have received a copy of the GNU Lesser General Public License along with
    00020 this program; if not, write to the Free Software Foundation, Inc., 59 Temple
    00021 Place - Suite 330, Boston, MA 02111-1307, USA, or go to
    00022 http://www.gnu.org/copyleft/lesser.txt.
    00023 -----------------------------------------------------------------------------
    00024 */
    00025 #ifndef __Vector3_H__
    00026 #define __Vector3_H__
    00027
    00028 #include "OgrePrerequisites.h"
    00029 #include "OgreMath.h"
    00030 #include "OgreQuaternion.h"
    00031
    00032 namespace Ogre
    00033 {
    00034
    00042     class _OgreExport Vector3
    00043     {
    00044     public:
    00045         union {
    00046             struct {
    00047                 Real x, y, z;
    00048             };
    00049             Real val[3];
    00050         };
    00051
    00052     public:
    00053         inline Vector3()
    00054         {
    00055         }
    00056
    00057         inline Vector3( const Real fX, const Real fY, const Real fZ )
    00058             : x( fX ), y( fY ), z( fZ )
    00059         {
    00060         }
    00061
    00062         inline explicit Vector3( const Real afCoordinate[3] )
    00063             : x( afCoordinate[0] ),
    00064               y( afCoordinate[1] ),
    00065               z( afCoordinate[2] )
    00066         {
    00067         }
    00068
    00069         inline explicit Vector3( const int afCoordinate[3] )
    00070         {
    00071             x = (Real)afCoordinate[0];
    00072             y = (Real)afCoordinate[1];
    00073             z = (Real)afCoordinate[2];
    00074         }
    00075
    00076         inline explicit Vector3( Real* const r )
    00077             : x( r[0] ), y( r[1] ), z( r[2] )
    00078         {
    00079         }
    00080
    00081         inline explicit Vector3( const Real scaler )
    00082             : x( scaler )
    00083             , y( scaler )
    00084             , z( scaler )
    00085         {
    00086         }
    00087
    00088
    00089         inline Vector3( const Vector3& rkVector )
    00090             : x( rkVector.x ), y( rkVector.y ), z( rkVector.z )
    00091         {
    00092         }
    00093
    00094         inline Real operator [] ( const size_t i ) const
    00095         {
    00096             assert( i < 3 );
    00097
    00098             return *(&x+i);
    00099         }
    00100
    00101         inline Real& operator [] ( const size_t i )
    00102         {
    00103             assert( i < 3 );
    00104
    00105             return *(&x+i);
    00106         }
    00107
    00112         inline Vector3& operator = ( const Vector3& rkVector )
    00113         {
    00114             x = rkVector.x;
    00115             y = rkVector.y;
    00116             z = rkVector.z;
    00117
    00118             return *this;
    00119         }
    00120
    00121         inline Vector3& operator = ( const Real fScaler )
    00122         {
    00123             x = fScaler;
    00124             y = fScaler;
    00125             z = fScaler;
    00126
    00127             return *this;
    00128         }
    00129
    00130         inline bool operator == ( const Vector3& rkVector ) const
    00131         {
    00132             return ( x == rkVector.x && y == rkVector.y && z == rkVector.z );
    00133         }
    00134
    00135         inline bool operator != ( const Vector3& rkVector ) const
    00136         {
    00137             return ( x != rkVector.x || y != rkVector.y || z != rkVector.z );
    00138         }
    00139
    00140         // arithmetic operations
    00141         inline Vector3 operator + ( const Vector3& rkVector ) const
    00142         {
    00143             return Vector3(
    00144                 x + rkVector.x,
    00145                 y + rkVector.y,
    00146                 z + rkVector.z);
    00147         }
    00148
    00149         inline Vector3 operator - ( const Vector3& rkVector ) const
    00150         {
    00151             return Vector3(
    00152                 x - rkVector.x,
    00153                 y - rkVector.y,
    00154                 z - rkVector.z);
    00155         }
    00156
    00157         inline Vector3 operator * ( const Real fScalar ) const
    00158         {
    00159             return Vector3(
    00160                 x * fScalar,
    00161                 y * fScalar,
    00162                 z * fScalar);
    00163         }
    00164
    00165         inline Vector3 operator * ( const Vector3& rhs) const
    00166         {
    00167             return Vector3(
    00168                 x * rhs.x,
    00169                 y * rhs.y,
    00170                 z * rhs.z);
    00171         }
    00172
    00173         inline Vector3 operator / ( const Real fScalar ) const
    00174         {
    00175             assert( fScalar != 0.0 );
    00176
    00177             Real fInv = 1.0 / fScalar;
    00178
    00179             return Vector3(
    00180                 x * fInv,
    00181                 y * fInv,
    00182                 z * fInv);
    00183         }
    00184
    00185         inline Vector3 operator / ( const Vector3& rhs) const
    00186         {
    00187             return Vector3(
    00188                 x / rhs.x,
    00189                 y / rhs.y,
    00190                 z / rhs.z);
    00191         }
    00192
    00193         inline const Vector3& operator + () const
    00194         {
    00195             return *this;
    00196         }
    00197
    00198         inline Vector3 operator - () const
    00199         {
    00200             return Vector3(-x, -y, -z);
    00201         }
    00202
    00203         // overloaded operators to help Vector3
    00204         inline friend Vector3 operator * ( const Real fScalar, const Vector3& rkVector )
    00205         {
    00206             return Vector3(
    00207                 fScalar * rkVector.x,
    00208                 fScalar * rkVector.y,
    00209                 fScalar * rkVector.z);
    00210         }
    00211
    00212         inline friend Vector3 operator / ( const Real fScalar, const Vector3& rkVector )
    00213         {
    00214             return Vector3(
    00215                 fScalar / rkVector.x,
    00216                 fScalar / rkVector.y,
    00217                 fScalar / rkVector.z);
    00218         }
    00219
    00220         inline friend Vector3 operator + (const Vector3& lhs, const Real rhs)
    00221         {
    00222             return Vector3(
    00223                 lhs.x + rhs,
    00224                 lhs.y + rhs,
    00225                 lhs.z + rhs);
    00226         }
    00227
    00228         inline friend Vector3 operator + (const Real lhs, const Vector3& rhs)
    00229         {
    00230             return Vector3(
    00231                 lhs + rhs.x,
    00232                 lhs + rhs.y,
    00233                 lhs + rhs.z);
    00234         }
    00235
    00236         inline friend Vector3 operator - (const Vector3& lhs, const Real rhs)
    00237         {
    00238             return Vector3(
    00239                 lhs.x - rhs,
    00240                 lhs.y - rhs,
    00241                 lhs.z - rhs);
    00242         }
    00243
    00244         inline friend Vector3 operator - (const Real lhs, const Vector3& rhs)
    00245         {
    00246             return Vector3(
    00247                 lhs - rhs.x,
    00248                 lhs - rhs.y,
    00249                 lhs - rhs.z);
    00250         }
    00251
    00252         // arithmetic updates
    00253         inline Vector3& operator += ( const Vector3& rkVector )
    00254         {
    00255             x += rkVector.x;
    00256             y += rkVector.y;
    00257             z += rkVector.z;
    00258
    00259             return *this;
    00260         }
    00261
    00262         inline Vector3& operator += ( const Real fScalar )
    00263         {
    00264             x += fScalar;
    00265             y += fScalar;
    00266             z += fScalar;
    00267             return *this;
    00268         }
    00269
    00270         inline Vector3& operator -= ( const Vector3& rkVector )
    00271         {
    00272             x -= rkVector.x;
    00273             y -= rkVector.y;
    00274             z -= rkVector.z;
    00275
    00276             return *this;
    00277         }
    00278
    00279         inline Vector3& operator -= ( const Real fScalar )
    00280         {
    00281             x -= fScalar;
    00282             y -= fScalar;
    00283             z -= fScalar;
    00284             return *this;
    00285         }
    00286
    00287         inline Vector3& operator *= ( const Real fScalar )
    00288         {
    00289             x *= fScalar;
    00290             y *= fScalar;
    00291             z *= fScalar;
    00292             return *this;
    00293         }
    00294
    00295         inline Vector3& operator *= ( const Vector3& rkVector )
    00296         {
    00297             x *= rkVector.x;
    00298             y *= rkVector.y;
    00299             z *= rkVector.z;
    00300
    00301             return *this;
    00302         }
    00303
    00304         inline Vector3& operator /= ( const Real fScalar )
    00305         {
    00306             assert( fScalar != 0.0 );
    00307
    00308             Real fInv = 1.0 / fScalar;
    00309
    00310             x *= fInv;
    00311             y *= fInv;
    00312             z *= fInv;
    00313
    00314             return *this;
    00315         }
    00316
    00317         inline Vector3& operator /= ( const Vector3& rkVector )
    00318         {
    00319             x /= rkVector.x;
    00320             y /= rkVector.y;
    00321             z /= rkVector.z;
    00322
    00323             return *this;
    00324         }
    00325
    00326
    00334         inline Real length () const
    00335         {
    00336             return Math::Sqrt( x * x + y * y + z * z );
    00337         }
    00338
    00349         inline Real squaredLength () const
    00350         {
    00351             return x * x + y * y + z * z;
    00352         }
    00353
    00368         inline Real dotProduct(const Vector3& vec) const
    00369         {
    00370             return x * vec.x + y * vec.y + z * vec.z;
    00371         }
    00372
    00382         inline Real normalise()
    00383         {
    00384             Real fLength = Math::Sqrt( x * x + y * y + z * z );
    00385
    00386             // Will also work for zero-sized vectors, but will change nothing
    00387             if ( fLength > 1e-08 )
    00388             {
    00389                 Real fInvLength = 1.0 / fLength;
    00390                 x *= fInvLength;
    00391                 y *= fInvLength;
    00392                 z *= fInvLength;
    00393             }
    00394
    00395             return fLength;
    00396         }
    00397
    00426         inline Vector3 crossProduct( const Vector3& rkVector ) const
    00427         {
    00428             return Vector3(
    00429                 y * rkVector.z - z * rkVector.y,
    00430                 z * rkVector.x - x * rkVector.z,
    00431                 x * rkVector.y - y * rkVector.x);
    00432         }
    00433
    00437         inline Vector3 midPoint( const Vector3& vec ) const
    00438         {
    00439             return Vector3(
    00440                 ( x + vec.x ) * 0.5,
    00441                 ( y + vec.y ) * 0.5,
    00442                 ( z + vec.z ) * 0.5 );
    00443         }
    00444
    00448         inline bool operator < ( const Vector3& rhs ) const
    00449         {
    00450             if( x < rhs.x && y < rhs.y && z < rhs.z )
    00451                 return true;
    00452             return false;
    00453         }
    00454
    00458         inline bool operator > ( const Vector3& rhs ) const
    00459         {
    00460             if( x > rhs.x && y > rhs.y && z > rhs.z )
    00461                 return true;
    00462             return false;
    00463         }
    00464
    00472         inline void makeFloor( const Vector3& cmp )
    00473         {
    00474             if( cmp.x < x ) x = cmp.x;
    00475             if( cmp.y < y ) y = cmp.y;
    00476             if( cmp.z < z ) z = cmp.z;
    00477         }
    00478
    00486         inline void makeCeil( const Vector3& cmp )
    00487         {
    00488             if( cmp.x > x ) x = cmp.x;
    00489             if( cmp.y > y ) y = cmp.y;
    00490             if( cmp.z > z ) z = cmp.z;
    00491         }
    00492
    00500         inline Vector3 perpendicular(void) const
    00501         {
    00502             static const Real fSquareZero = 1e-06 * 1e-06;
    00503
    00504             Vector3 perp = this->crossProduct( Vector3::UNIT_X );
    00505
    00506             // Check length
    00507             if( perp.squaredLength() < fSquareZero )
    00508             {
    00509                 /* This vector is the Y axis multiplied by a scalar, so we have
    00510                    to use another axis.
    00511                 */
    00512                 perp = this->crossProduct( Vector3::UNIT_Y );
    00513             }
    00514
    00515             return perp;
    00516         }
    00536         inline Vector3 randomDeviant(
    00537             const Radian& angle,
    00538             const Vector3& up = Vector3::ZERO ) const
    00539         {
    00540             Vector3 newUp;
    00541
    00542             if (up == Vector3::ZERO)
    00543             {
    00544                 // Generate an up vector
    00545                 newUp = this->perpendicular();
    00546             }
    00547             else
    00548             {
    00549                 newUp = up;
    00550             }
    00551
    00552             // Rotate up vector by random amount around this
    00553             Quaternion q;
    00554             q.FromAngleAxis( Radian(Math::UnitRandom() * Math::TWO_PI), *this );
    00555             newUp = q * newUp;
    00556
    00557             // Finally rotate this by given angle around randomised up
    00558             q.FromAngleAxis( angle, newUp );
    00559             return q * (*this);
    00560         }
    00561 #ifndef OGRE_FORCE_ANGLE_TYPES
    00562         inline Vector3 randomDeviant(
    00563             Real angle,
    00564             const Vector3& up = Vector3::ZERO ) const
    00565         {
    00566             return randomDeviant ( Radian(angle), up );
    00567         }
    00568 #endif//OGRE_FORCE_ANGLE_TYPES
    00569
    00578         Quaternion getRotationTo(const Vector3& dest,
    00579             const Vector3& fallbackAxis = Vector3::ZERO) const
    00580         {
    00581             // Based on Stan Melax's article in Game Programming Gems
    00582             Quaternion q;
    00583             // Copy, since cannot modify local
    00584             Vector3 v0 = *this;
    00585             Vector3 v1 = dest;
    00586             v0.normalise();
    00587             v1.normalise();
    00588
    00589             Vector3 c = v0.crossProduct(v1);
    00590
    00591             Real d = v0.dotProduct(v1);
    00592             // If dot == 1, vectors are the same
    00593             if (d >= 1.0f)
    00594             {
    00595                 return Quaternion::IDENTITY;
    00596             }
    00597             Real s = Math::Sqrt( (1+d)*2 );
    00598             if (s < 1e-6f)
    00599             {
    00600                 if (fallbackAxis != Vector3::ZERO)
    00601                 {
    00602                     // rotate 180 degrees about the fallback axis
    00603                     q.FromAngleAxis(Radian(Math::PI), fallbackAxis);
    00604                 }
    00605                 else
    00606                 {
    00607                     // Generate an axis
    00608                     Vector3 axis = Vector3::UNIT_X.crossProduct(*this);
    00609                     if (axis.isZeroLength()) // pick another if colinear
    00610                         axis = Vector3::UNIT_Y.crossProduct(*this);
    00611                     axis.normalise();
    00612                     q.FromAngleAxis(Radian(Math::PI), axis);
    00613                 }
    00614             }
    00615             else
    00616             {
    00617                 Real invs = 1 / s;
    00618
    00619                 q.x = c.x * invs;
    00620                 q.y = c.y * invs;
    00621                 q.z = c.z * invs;
    00622                 q.w = s * 0.5;
    00623             }
    00624             return q;
    00625         }
    00626
    00628         inline bool isZeroLength(void) const
    00629         {
    00630             Real sqlen = (x * x) + (y * y) + (z * z);
    00631             return (sqlen < (1e-06 * 1e-06));
    00632
    00633         }
    00634
    00637         inline Vector3 normalisedCopy(void) const
    00638         {
    00639             Vector3 ret = *this;
    00640             ret.normalise();
    00641             return ret;
    00642         }
    00643
    00647         inline Vector3 reflect(const Vector3& normal) const
    00648         {
    00649             return Vector3( *this - ( 2 * this->dotProduct(normal) * normal ) );
    00650         }
    00651
    00658         inline bool positionEquals(const Vector3& rhs, Real tolerance = 1e-03) const
    00659         {
    00660             return Math::RealEqual(x, rhs.x, tolerance) &&
    00661                 Math::RealEqual(y, rhs.y, tolerance) &&
    00662                 Math::RealEqual(z, rhs.z, tolerance);
    00663
    00664         }
    00671         inline bool directionEquals(const Vector3& rhs,
    00672             const Radian& tolerance) const
    00673         {
    00674             Real dot = dotProduct(rhs);
    00675             Radian angle = Math::ACos(dot);
    00676
    00677             return Math::Abs(angle.valueRadians()) <= tolerance.valueRadians();
    00678
    00679         }
    00680
    00681         // special points
    00682         static const Vector3 ZERO;
    00683         static const Vector3 UNIT_X;
    00684         static const Vector3 UNIT_Y;
    00685         static const Vector3 UNIT_Z;
    00686         static const Vector3 NEGATIVE_UNIT_X;
    00687         static const Vector3 NEGATIVE_UNIT_Y;
    00688         static const Vector3 NEGATIVE_UNIT_Z;
    00689         static const Vector3 UNIT_SCALE;
    00690
    00693         inline _OgreExport friend std::ostream& operator <<
    00694             ( std::ostream& o, const Vector3& v )
    00695         {
    00696             o << "Vector3(" << v.x << ", " << v.y << ", " << v.z << ")";
    00697             return o;
    00698         }
    00699     };
    00700
    00701 }
    00702 #endif

Copyright © 2000-2005 by The OGRE Team
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Sun Sep 17 15:39:12 2006