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-2006 Torus Knot Software Ltd
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 You may alternatively use this source under the terms of a specific version of
00025 the OGRE Unrestricted License provided you have obtained such a license from
00026 Torus Knot Software Ltd.
00027 -----------------------------------------------------------------------------
00028 */
00029 #ifndef __Vector3_H__
00030 #define __Vector3_H__
00031 
00032 #include "OgrePrerequisites.h"
00033 #include "OgreMath.h"
00034 #include "OgreQuaternion.h"
00035 
00036 namespace Ogre
00037 {
00038 
00046     class _OgreExport Vector3
00047     {
00048     public:
00049         Real x, y, z;
00050 
00051     public:
00052         inline Vector3()
00053         {
00054         }
00055 
00056         inline Vector3( const Real fX, const Real fY, const Real fZ )
00057             : x( fX ), y( fY ), z( fZ )
00058         {
00059         }
00060 
00061         inline explicit Vector3( const Real afCoordinate[3] )
00062             : x( afCoordinate[0] ),
00063               y( afCoordinate[1] ),
00064               z( afCoordinate[2] )
00065         {
00066         }
00067 
00068         inline explicit Vector3( const int afCoordinate[3] )
00069         {
00070             x = (Real)afCoordinate[0];
00071             y = (Real)afCoordinate[1];
00072             z = (Real)afCoordinate[2];
00073         }
00074 
00075         inline explicit Vector3( Real* const r )
00076             : x( r[0] ), y( r[1] ), z( r[2] )
00077         {
00078         }
00079 
00080         inline explicit Vector3( const Real scaler )
00081             : x( scaler )
00082             , y( scaler )
00083             , z( scaler )
00084         {
00085         }
00086 
00087 
00088         inline Vector3( const Vector3& rkVector )
00089             : x( rkVector.x ), y( rkVector.y ), z( rkVector.z )
00090         {
00091         }
00092 
00093         inline Real operator [] ( const size_t i ) const
00094         {
00095             assert( i < 3 );
00096 
00097             return *(&x+i);
00098         }
00099 
00100         inline Real& operator [] ( const size_t i )
00101         {
00102             assert( i < 3 );
00103 
00104             return *(&x+i);
00105         }
00107         inline Real* ptr()
00108         {
00109             return &x;
00110         }
00112         inline const Real* ptr() const
00113         {
00114             return &x;
00115         }
00116 
00121         inline Vector3& operator = ( const Vector3& rkVector )
00122         {
00123             x = rkVector.x;
00124             y = rkVector.y;
00125             z = rkVector.z;
00126 
00127             return *this;
00128         }
00129 
00130         inline Vector3& operator = ( const Real fScaler )
00131         {
00132             x = fScaler;
00133             y = fScaler;
00134             z = fScaler;
00135 
00136             return *this;
00137         }
00138 
00139         inline bool operator == ( const Vector3& rkVector ) const
00140         {
00141             return ( x == rkVector.x && y == rkVector.y && z == rkVector.z );
00142         }
00143 
00144         inline bool operator != ( const Vector3& rkVector ) const
00145         {
00146             return ( x != rkVector.x || y != rkVector.y || z != rkVector.z );
00147         }
00148 
00149         // arithmetic operations
00150         inline Vector3 operator + ( const Vector3& rkVector ) const
00151         {
00152             return Vector3(
00153                 x + rkVector.x,
00154                 y + rkVector.y,
00155                 z + rkVector.z);
00156         }
00157 
00158         inline Vector3 operator - ( const Vector3& rkVector ) const
00159         {
00160             return Vector3(
00161                 x - rkVector.x,
00162                 y - rkVector.y,
00163                 z - rkVector.z);
00164         }
00165 
00166         inline Vector3 operator * ( const Real fScalar ) const
00167         {
00168             return Vector3(
00169                 x * fScalar,
00170                 y * fScalar,
00171                 z * fScalar);
00172         }
00173 
00174         inline Vector3 operator * ( const Vector3& rhs) const
00175         {
00176             return Vector3(
00177                 x * rhs.x,
00178                 y * rhs.y,
00179                 z * rhs.z);
00180         }
00181 
00182         inline Vector3 operator / ( const Real fScalar ) const
00183         {
00184             assert( fScalar != 0.0 );
00185 
00186             Real fInv = 1.0 / fScalar;
00187 
00188             return Vector3(
00189                 x * fInv,
00190                 y * fInv,
00191                 z * fInv);
00192         }
00193 
00194         inline Vector3 operator / ( const Vector3& rhs) const
00195         {
00196             return Vector3(
00197                 x / rhs.x,
00198                 y / rhs.y,
00199                 z / rhs.z);
00200         }
00201 
00202         inline const Vector3& operator + () const
00203         {
00204             return *this;
00205         }
00206 
00207         inline Vector3 operator - () const
00208         {
00209             return Vector3(-x, -y, -z);
00210         }
00211 
00212         // overloaded operators to help Vector3
00213         inline friend Vector3 operator * ( const Real fScalar, const Vector3& rkVector )
00214         {
00215             return Vector3(
00216                 fScalar * rkVector.x,
00217                 fScalar * rkVector.y,
00218                 fScalar * rkVector.z);
00219         }
00220 
00221         inline friend Vector3 operator / ( const Real fScalar, const Vector3& rkVector )
00222         {
00223             return Vector3(
00224                 fScalar / rkVector.x,
00225                 fScalar / rkVector.y,
00226                 fScalar / rkVector.z);
00227         }
00228 
00229         inline friend Vector3 operator + (const Vector3& lhs, const Real rhs)
00230         {
00231             return Vector3(
00232                 lhs.x + rhs,
00233                 lhs.y + rhs,
00234                 lhs.z + rhs);
00235         }
00236 
00237         inline friend Vector3 operator + (const Real lhs, const Vector3& rhs)
00238         {
00239             return Vector3(
00240                 lhs + rhs.x,
00241                 lhs + rhs.y,
00242                 lhs + rhs.z);
00243         }
00244 
00245         inline friend Vector3 operator - (const Vector3& lhs, const Real rhs)
00246         {
00247             return Vector3(
00248                 lhs.x - rhs,
00249                 lhs.y - rhs,
00250                 lhs.z - rhs);
00251         }
00252 
00253         inline friend Vector3 operator - (const Real lhs, const Vector3& rhs)
00254         {
00255             return Vector3(
00256                 lhs - rhs.x,
00257                 lhs - rhs.y,
00258                 lhs - rhs.z);
00259         }
00260 
00261         // arithmetic updates
00262         inline Vector3& operator += ( const Vector3& rkVector )
00263         {
00264             x += rkVector.x;
00265             y += rkVector.y;
00266             z += rkVector.z;
00267 
00268             return *this;
00269         }
00270 
00271         inline Vector3& operator += ( const Real fScalar )
00272         {
00273             x += fScalar;
00274             y += fScalar;
00275             z += fScalar;
00276             return *this;
00277         }
00278 
00279         inline Vector3& operator -= ( const Vector3& rkVector )
00280         {
00281             x -= rkVector.x;
00282             y -= rkVector.y;
00283             z -= rkVector.z;
00284 
00285             return *this;
00286         }
00287 
00288         inline Vector3& operator -= ( const Real fScalar )
00289         {
00290             x -= fScalar;
00291             y -= fScalar;
00292             z -= fScalar;
00293             return *this;
00294         }
00295 
00296         inline Vector3& operator *= ( const Real fScalar )
00297         {
00298             x *= fScalar;
00299             y *= fScalar;
00300             z *= fScalar;
00301             return *this;
00302         }
00303 
00304         inline Vector3& operator *= ( const Vector3& rkVector )
00305         {
00306             x *= rkVector.x;
00307             y *= rkVector.y;
00308             z *= rkVector.z;
00309 
00310             return *this;
00311         }
00312 
00313         inline Vector3& operator /= ( const Real fScalar )
00314         {
00315             assert( fScalar != 0.0 );
00316 
00317             Real fInv = 1.0 / fScalar;
00318 
00319             x *= fInv;
00320             y *= fInv;
00321             z *= fInv;
00322 
00323             return *this;
00324         }
00325 
00326         inline Vector3& operator /= ( const Vector3& rkVector )
00327         {
00328             x /= rkVector.x;
00329             y /= rkVector.y;
00330             z /= rkVector.z;
00331 
00332             return *this;
00333         }
00334 
00335 
00343         inline Real length () const
00344         {
00345             return Math::Sqrt( x * x + y * y + z * z );
00346         }
00347 
00358         inline Real squaredLength () const
00359         {
00360             return x * x + y * y + z * z;
00361         }
00362 
00370         inline Real distance(const Vector3& rhs) const
00371         {
00372             return (*this - rhs).length();
00373         }
00374 
00385         inline Real squaredDistance(const Vector3& rhs) const
00386         {
00387             return (*this - rhs).squaredLength();
00388         }
00389 
00404         inline Real dotProduct(const Vector3& vec) const
00405         {
00406             return x * vec.x + y * vec.y + z * vec.z;
00407         }
00408 
00419         inline Real absDotProduct(const Vector3& vec) const
00420         {
00421             return Math::Abs(x * vec.x) + Math::Abs(y * vec.y) + Math::Abs(z * vec.z);
00422         }
00423 
00433         inline Real normalise()
00434         {
00435             Real fLength = Math::Sqrt( x * x + y * y + z * z );
00436 
00437             // Will also work for zero-sized vectors, but will change nothing
00438             if ( fLength > 1e-08 )
00439             {
00440                 Real fInvLength = 1.0 / fLength;
00441                 x *= fInvLength;
00442                 y *= fInvLength;
00443                 z *= fInvLength;
00444             }
00445 
00446             return fLength;
00447         }
00448 
00477         inline Vector3 crossProduct( const Vector3& rkVector ) const
00478         {
00479             return Vector3(
00480                 y * rkVector.z - z * rkVector.y,
00481                 z * rkVector.x - x * rkVector.z,
00482                 x * rkVector.y - y * rkVector.x);
00483         }
00484 
00488         inline Vector3 midPoint( const Vector3& vec ) const
00489         {
00490             return Vector3(
00491                 ( x + vec.x ) * 0.5,
00492                 ( y + vec.y ) * 0.5,
00493                 ( z + vec.z ) * 0.5 );
00494         }
00495 
00499         inline bool operator < ( const Vector3& rhs ) const
00500         {
00501             if( x < rhs.x && y < rhs.y && z < rhs.z )
00502                 return true;
00503             return false;
00504         }
00505 
00509         inline bool operator > ( const Vector3& rhs ) const
00510         {
00511             if( x > rhs.x && y > rhs.y && z > rhs.z )
00512                 return true;
00513             return false;
00514         }
00515 
00523         inline void makeFloor( const Vector3& cmp )
00524         {
00525             if( cmp.x < x ) x = cmp.x;
00526             if( cmp.y < y ) y = cmp.y;
00527             if( cmp.z < z ) z = cmp.z;
00528         }
00529 
00537         inline void makeCeil( const Vector3& cmp )
00538         {
00539             if( cmp.x > x ) x = cmp.x;
00540             if( cmp.y > y ) y = cmp.y;
00541             if( cmp.z > z ) z = cmp.z;
00542         }
00543 
00551         inline Vector3 perpendicular(void) const
00552         {
00553             static const Real fSquareZero = 1e-06 * 1e-06;
00554 
00555             Vector3 perp = this->crossProduct( Vector3::UNIT_X );
00556 
00557             // Check length
00558             if( perp.squaredLength() < fSquareZero )
00559             {
00560                 /* This vector is the Y axis multiplied by a scalar, so we have
00561                    to use another axis.
00562                 */
00563                 perp = this->crossProduct( Vector3::UNIT_Y );
00564             }
00565 
00566             return perp;
00567         }
00587         inline Vector3 randomDeviant(
00588             const Radian& angle,
00589             const Vector3& up = Vector3::ZERO ) const
00590         {
00591             Vector3 newUp;
00592 
00593             if (up == Vector3::ZERO)
00594             {
00595                 // Generate an up vector
00596                 newUp = this->perpendicular();
00597             }
00598             else
00599             {
00600                 newUp = up;
00601             }
00602 
00603             // Rotate up vector by random amount around this
00604             Quaternion q;
00605             q.FromAngleAxis( Radian(Math::UnitRandom() * Math::TWO_PI), *this );
00606             newUp = q * newUp;
00607 
00608             // Finally rotate this by given angle around randomised up
00609             q.FromAngleAxis( angle, newUp );
00610             return q * (*this);
00611         }
00612 #ifndef OGRE_FORCE_ANGLE_TYPES
00613         inline Vector3 randomDeviant(
00614             Real angle,
00615             const Vector3& up = Vector3::ZERO ) const
00616         {
00617             return randomDeviant ( Radian(angle), up );
00618         }
00619 #endif//OGRE_FORCE_ANGLE_TYPES
00620 
00629         Quaternion getRotationTo(const Vector3& dest,
00630             const Vector3& fallbackAxis = Vector3::ZERO) const
00631         {
00632             // Based on Stan Melax's article in Game Programming Gems
00633             Quaternion q;
00634             // Copy, since cannot modify local
00635             Vector3 v0 = *this;
00636             Vector3 v1 = dest;
00637             v0.normalise();
00638             v1.normalise();
00639 
00640             Real d = v0.dotProduct(v1);
00641             // If dot == 1, vectors are the same
00642             if (d >= 1.0f)
00643             {
00644                 return Quaternion::IDENTITY;
00645             }
00646             if (d < (1e-6f - 1.0f))
00647             {
00648                 if (fallbackAxis != Vector3::ZERO)
00649                 {
00650                     // rotate 180 degrees about the fallback axis
00651                     q.FromAngleAxis(Radian(Math::PI), fallbackAxis);
00652                 }
00653                 else
00654                 {
00655                     // Generate an axis
00656                     Vector3 axis = Vector3::UNIT_X.crossProduct(*this);
00657                     if (axis.isZeroLength()) // pick another if colinear
00658                         axis = Vector3::UNIT_Y.crossProduct(*this);
00659                     axis.normalise();
00660                     q.FromAngleAxis(Radian(Math::PI), axis);
00661                 }
00662             }
00663             else
00664             {
00665                 Real s = Math::Sqrt( (1+d)*2 );
00666                 Real invs = 1 / s;
00667 
00668                 Vector3 c = v0.crossProduct(v1);
00669 
00670                 q.x = c.x * invs;
00671                 q.y = c.y * invs;
00672                 q.z = c.z * invs;
00673                 q.w = s * 0.5;
00674                 q.normalise();
00675             }
00676             return q;
00677         }
00678 
00680         inline bool isZeroLength(void) const
00681         {
00682             Real sqlen = (x * x) + (y * y) + (z * z);
00683             return (sqlen < (1e-06 * 1e-06));
00684 
00685         }
00686 
00689         inline Vector3 normalisedCopy(void) const
00690         {
00691             Vector3 ret = *this;
00692             ret.normalise();
00693             return ret;
00694         }
00695 
00699         inline Vector3 reflect(const Vector3& normal) const
00700         {
00701             return Vector3( *this - ( 2 * this->dotProduct(normal) * normal ) );
00702         }
00703 
00710         inline bool positionEquals(const Vector3& rhs, Real tolerance = 1e-03) const
00711         {
00712             return Math::RealEqual(x, rhs.x, tolerance) &&
00713                 Math::RealEqual(y, rhs.y, tolerance) &&
00714                 Math::RealEqual(z, rhs.z, tolerance);
00715 
00716         }
00717 
00724         inline bool positionCloses(const Vector3& rhs, Real tolerance = 1e-03f) const
00725         {
00726             return squaredDistance(rhs) <=
00727                 (squaredLength() + rhs.squaredLength()) * tolerance;
00728         }
00729 
00737         inline bool directionEquals(const Vector3& rhs,
00738             const Radian& tolerance) const
00739         {
00740             Real dot = dotProduct(rhs);
00741             Radian angle = Math::ACos(dot);
00742 
00743             return Math::Abs(angle.valueRadians()) <= tolerance.valueRadians();
00744 
00745         }
00746 
00747         // special points
00748         static const Vector3 ZERO;
00749         static const Vector3 UNIT_X;
00750         static const Vector3 UNIT_Y;
00751         static const Vector3 UNIT_Z;
00752         static const Vector3 NEGATIVE_UNIT_X;
00753         static const Vector3 NEGATIVE_UNIT_Y;
00754         static const Vector3 NEGATIVE_UNIT_Z;
00755         static const Vector3 UNIT_SCALE;
00756 
00759         inline _OgreExport friend std::ostream& operator <<
00760             ( std::ostream& o, const Vector3& v )
00761         {
00762             o << "Vector3(" << v.x << ", " << v.y << ", " << v.z << ")";
00763             return o;
00764         }
00765     };
00766 
00767 }
00768 #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 Mar 25 13:03:17 2007