Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

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
Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 2.5 License.
Last modified Sun Jul 23 10:05:41 2006