Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound 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://ogre.sourceforge.net/
00006 
00007 Copyright © 2000-2002 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         Real x, y, z;        
00046 
00047     public:
00048         inline Vector3()
00049         {
00050         }
00051 
00052         inline Vector3( Real fX, Real fY, Real fZ ) 
00053             : x( fX ), y( fY ), z( fZ )
00054         {
00055         }
00056 
00057         inline Vector3( Real afCoordinate[3] )
00058             : x( afCoordinate[0] ),
00059               y( afCoordinate[1] ),
00060               z( afCoordinate[2] )
00061         {
00062         }
00063 
00064         inline Vector3( int afCoordinate[3] )
00065         {
00066             x = (Real)afCoordinate[0];
00067             y = (Real)afCoordinate[1];
00068             z = (Real)afCoordinate[2];
00069         }
00070 
00071         inline Vector3( const Real* const r )
00072             : x( r[0] ), y( r[1] ), z( r[2] )
00073         {
00074         }
00075 
00076         inline Vector3( const Vector3& rkVector )
00077             : x( rkVector.x ), y( rkVector.y ), z( rkVector.z )
00078         {
00079         }
00080 
00081         inline Real operator [] ( unsigned i ) const
00082         {
00083             assert( i < 3 );
00084 
00085             return *(&x+i);
00086         }
00087 
00088         inline Real& operator [] ( unsigned i )
00089         {
00090             assert( i < 3 );
00091 
00092             return *(&x+i);
00093         }
00094 
00099         inline Vector3& operator = ( const Vector3& rkVector )
00100         {
00101             x = rkVector.x;
00102             y = rkVector.y;
00103             z = rkVector.z;            
00104 
00105             return *this;
00106         }
00107 
00108         inline bool operator == ( const Vector3& rkVector ) const
00109         {
00110             return ( x == rkVector.x && y == rkVector.y && z == rkVector.z );
00111         }
00112 
00113         inline bool operator != ( const Vector3& rkVector ) const
00114         {
00115             return ( x != rkVector.x || y != rkVector.y || z != rkVector.z );
00116         }
00117 
00118         // arithmetic operations
00119         inline Vector3 operator + ( const Vector3& rkVector ) const
00120         {
00121             Vector3 kSum;
00122 
00123             kSum.x = x + rkVector.x;
00124             kSum.y = y + rkVector.y;
00125             kSum.z = z + rkVector.z;
00126 
00127             return kSum;
00128         }
00129 
00130         inline Vector3 operator - ( const Vector3& rkVector ) const
00131         {
00132             Vector3 kDiff;
00133 
00134             kDiff.x = x - rkVector.x;
00135             kDiff.y = y - rkVector.y;
00136             kDiff.z = z - rkVector.z;
00137 
00138             return kDiff;
00139         }
00140 
00141         inline Vector3 operator * ( Real fScalar ) const
00142         {
00143             Vector3 kProd;
00144 
00145             kProd.x = fScalar*x;
00146             kProd.y = fScalar*y;
00147             kProd.z = fScalar*z;
00148 
00149             return kProd;
00150         }
00151 
00152         inline Vector3 operator * ( const Vector3& rhs) const
00153         {
00154             Vector3 kProd;
00155 
00156             kProd.x = rhs.x * x;
00157             kProd.y = rhs.y * y;
00158             kProd.z = rhs.z * z;
00159 
00160             return kProd;
00161         }
00162 
00163         inline Vector3 operator / ( Real fScalar ) const
00164         {
00165             assert( fScalar != 0.0 );
00166 
00167             Vector3 kDiv;
00168 
00169             Real fInv = 1.0 / fScalar;
00170             kDiv.x = x * fInv;
00171             kDiv.y = y * fInv;
00172             kDiv.z = z * fInv;
00173 
00174             return kDiv;
00175         }
00176 
00177         inline Vector3 operator - () const
00178         {
00179             Vector3 kNeg;
00180 
00181             kNeg.x = -x;
00182             kNeg.y = -y;
00183             kNeg.z = -z;
00184 
00185             return kNeg;
00186         }
00187 
00188         inline friend Vector3 operator * ( Real fScalar, const Vector3& rkVector )
00189         {
00190             Vector3 kProd;
00191 
00192             kProd.x = fScalar * rkVector.x;
00193             kProd.y = fScalar * rkVector.y;
00194             kProd.z = fScalar * rkVector.z;
00195 
00196             return kProd;
00197         }
00198 
00199         // arithmetic updates
00200         inline Vector3& operator += ( const Vector3& rkVector )
00201         {
00202             x += rkVector.x;
00203             y += rkVector.y;
00204             z += rkVector.z;
00205 
00206             return *this;
00207         }
00208 
00209         inline Vector3& operator -= ( const Vector3& rkVector )
00210         {
00211             x -= rkVector.x;
00212             y -= rkVector.y;
00213             z -= rkVector.z;
00214 
00215             return *this;
00216         }
00217 
00218         inline Vector3& operator *= ( Real fScalar )
00219         {
00220             x *= fScalar;
00221             y *= fScalar;
00222             z *= fScalar;
00223             return *this;
00224         }
00225 
00226         inline Vector3& operator /= ( Real fScalar )
00227         {
00228             assert( fScalar != 0.0 );
00229 
00230             Real fInv = 1.0 / fScalar;
00231 
00232             x *= fInv;
00233             y *= fInv;
00234             z *= fInv;
00235 
00236             return *this;
00237         }
00238 
00246         inline Real length () const
00247         {
00248             return Math::Sqrt( x * x + y * y + z * z );
00249         }
00250 
00261         inline Real squaredLength () const
00262         {
00263             return x * x + y * y + z * z;
00264         }
00265 
00280         inline Real dotProduct(const Vector3& vec) const
00281         {
00282             return x * vec.x + y * vec.y + z * vec.z;
00283         }
00284 
00293         inline Vector3 & normalise()
00294         {
00295             Real fLength = Math::Sqrt( x * x + y * y + z * z );
00296 
00297             // Will also work for zero-sized vectors, but will change nothing
00298             if ( fLength > 1e-06 )
00299             {
00300                 Real fInvLength = 1.0 / fLength;
00301                 x *= fInvLength;
00302                 y *= fInvLength;
00303                 z *= fInvLength;
00304             }
00305 
00306             return *this;
00307         }
00308 
00336         inline Vector3 crossProduct( const Vector3& rkVector ) const
00337         {
00338             Vector3 kCross;
00339 
00340             kCross.x = y * rkVector.z - z * rkVector.y;
00341             kCross.y = z * rkVector.x - x * rkVector.z;
00342             kCross.z = x * rkVector.y - y * rkVector.x;
00343 
00344             return kCross;
00345         }
00346 
00350         inline Vector3 midPoint( const Vector3& vec ) const
00351         {
00352             return Vector3( 
00353                 ( x + vec.x ) * 0.5, 
00354                 ( y + vec.y ) * 0.5, 
00355                 ( z + vec.z ) * 0.5 );
00356         }
00357 
00361         inline bool operator < ( const Vector3& rhs ) const
00362         {
00363             if( x < rhs.x && y < rhs.y && z < rhs.z )
00364                 return true;
00365             return false;
00366         }
00367 
00371         inline bool operator > ( const Vector3& rhs ) const
00372         {
00373             if( x > rhs.x && y > rhs.y && z > rhs.z )
00374                 return true;
00375             return false;
00376         }
00377 
00385         inline void makeFloor( const Vector3& cmp )
00386         {
00387             if( cmp.x < x ) x = cmp.x;
00388             if( cmp.y < y ) y = cmp.y;
00389             if( cmp.z < z ) z = cmp.z;
00390         }
00391 
00399         inline void makeCeil( const Vector3& cmp )
00400         {
00401             if( cmp.x > x ) x = cmp.x;
00402             if( cmp.y > y ) y = cmp.y;
00403             if( cmp.z > z ) z = cmp.z;
00404         }
00405 
00413         inline Vector3 perpendicular(void)
00414         {
00415             static Real fSquareZero = 1e-06 * 1e-06;
00416 
00417             Vector3 perp = this->crossProduct( Vector3::UNIT_X );
00418 
00419             // Check length
00420             if( perp.squaredLength() < fSquareZero )
00421             {
00422                 /* This vector is the Y axis multiplied by a scalar, so we have 
00423                    to use another axis.
00424                 */
00425                 perp = this->crossProduct( Vector3::UNIT_Y );
00426             }
00427 
00428             return perp;
00429         }
00449         inline Vector3 randomDeviant(
00450             Real angle, 
00451             const Vector3& up = Vector3::ZERO )
00452         {
00453             Vector3 newUp;
00454 
00455             if (up == Vector3::ZERO)
00456             {
00457                 // Generate an up vector
00458                 newUp = this->perpendicular();
00459             }
00460             else
00461             {
00462                 newUp = up;
00463             }
00464 
00465             // Rotate up vector by random amount around this
00466             Quaternion q;
00467             q.FromAngleAxis( Math::UnitRandom() * Math::TWO_PI, *this );
00468             newUp = q * newUp;
00469 
00470             // Finally rotate this by given angle around randomised up
00471             q.FromAngleAxis( angle, newUp );
00472             return q * (*this);
00473         }
00474 
00481         Quaternion getRotationTo(const Vector3& dest) const
00482         {
00483             // Based on Stan Melax's article in Game Programming Gems
00484             Quaternion q;
00485             // Copy, since cannot modify local
00486             Vector3 v0 = *this;
00487             Vector3 v1 = dest;
00488             v0.normalise();
00489             v1.normalise();
00490 
00491             Vector3 c = v0.crossProduct(v1);
00492 
00493             // NB if the crossProduct approaches zero, we get unstable because ANY axis will do
00494             // when v0 == -v1
00495             Real d = v0.dotProduct(v1);
00496             // If dot == 1, vectors are the same
00497             if (d >= 1.0f)
00498             {
00499                 return Quaternion::IDENTITY;
00500             }
00501             Real s = Math::Sqrt( (1+d)*2 );
00502             Real invs = 1 / s;
00503 
00504 
00505             q.x = c.x * invs;
00506             q.y = c.y * invs;
00507             q.z = c.z * invs;
00508             q.w = s * 0.5;
00509             return q;
00510         }
00511 
00512         // special points
00513         static const Vector3 ZERO;
00514         static const Vector3 UNIT_X;
00515         static const Vector3 UNIT_Y;
00516         static const Vector3 UNIT_Z;
00517         static const Vector3 UNIT_SCALE;
00518 
00521         inline _OgreExport friend std::ostream& operator <<
00522             ( std::ostream& o, const Vector3& v )
00523         {
00524             o << "Vector3(" << v.x << ", " << v.y << ", " << v.z << ")";
00525             return o;
00526         }
00527     };
00528 
00529 }
00530 #endif

Copyright © 2002 by The OGRE Team