OGRE  2.0
Object-Oriented Graphics Rendering Engine
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
OgreVector3.h
Go to the documentation of this file.
1 /*
2 -----------------------------------------------------------------------------
3 This source file is part of OGRE
4  (Object-oriented Graphics Rendering Engine)
5 For the latest info, see http://www.ogre3d.org/
6 
7 Copyright (c) 2000-2014 Torus Knot Software Ltd
8 
9 Permission is hereby granted, free of charge, to any person obtaining a copy
10 of this software and associated documentation files (the "Software"), to deal
11 in the Software without restriction, including without limitation the rights
12 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13 copies of the Software, and to permit persons to whom the Software is
14 furnished to do so, subject to the following conditions:
15 
16 The above copyright notice and this permission notice shall be included in
17 all copies or substantial portions of the Software.
18 
19 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25 THE SOFTWARE.
26 -----------------------------------------------------------------------------
27 */
28 #ifndef __Vector3_H__
29 #define __Vector3_H__
30 
31 #include "OgrePrerequisites.h"
32 #include "OgreQuaternion.h"
33 
34 namespace Ogre
35 {
36 
51  {
52  public:
53  Real x, y, z;
54 
55  public:
60  inline Vector3()
61  {
62  }
63 
64  inline Vector3( const Real fX, const Real fY, const Real fZ )
65  : x( fX ), y( fY ), z( fZ )
66  {
67  }
68 
69  inline explicit Vector3( const Real afCoordinate[3] )
70  : x( afCoordinate[0] ),
71  y( afCoordinate[1] ),
72  z( afCoordinate[2] )
73  {
74  }
75 
76  inline explicit Vector3( const int afCoordinate[3] )
77  {
78  x = (Real)afCoordinate[0];
79  y = (Real)afCoordinate[1];
80  z = (Real)afCoordinate[2];
81  }
82 
83  inline explicit Vector3( Real* const r )
84  : x( r[0] ), y( r[1] ), z( r[2] )
85  {
86  }
87 
88  inline explicit Vector3( const Real scaler )
89  : x( scaler )
90  , y( scaler )
91  , z( scaler )
92  {
93  }
94 
95 
98  inline void swap(Vector3& other)
99  {
100  std::swap(x, other.x);
101  std::swap(y, other.y);
102  std::swap(z, other.z);
103  }
104 
105  inline Real operator [] ( const size_t i ) const
106  {
107  assert( i < 3 );
108 
109  return *(&x+i);
110  }
111 
112  inline Real& operator [] ( const size_t i )
113  {
114  assert( i < 3 );
115 
116  return *(&x+i);
117  }
119  inline Real* ptr()
120  {
121  return &x;
122  }
124  inline const Real* ptr() const
125  {
126  return &x;
127  }
128 
133  inline Vector3& operator = ( const Vector3& rkVector )
134  {
135  x = rkVector.x;
136  y = rkVector.y;
137  z = rkVector.z;
138 
139  return *this;
140  }
141 
142  inline Vector3& operator = ( const Real fScaler )
143  {
144  x = fScaler;
145  y = fScaler;
146  z = fScaler;
147 
148  return *this;
149  }
150 
151  inline bool operator == ( const Vector3& rkVector ) const
152  {
153  return ( x == rkVector.x && y == rkVector.y && z == rkVector.z );
154  }
155 
156  inline bool operator != ( const Vector3& rkVector ) const
157  {
158  return ( x != rkVector.x || y != rkVector.y || z != rkVector.z );
159  }
160 
161  // arithmetic operations
162  inline Vector3 operator + ( const Vector3& rkVector ) const
163  {
164  return Vector3(
165  x + rkVector.x,
166  y + rkVector.y,
167  z + rkVector.z);
168  }
169 
170  inline Vector3 operator - ( const Vector3& rkVector ) const
171  {
172  return Vector3(
173  x - rkVector.x,
174  y - rkVector.y,
175  z - rkVector.z);
176  }
177 
178  inline Vector3 operator * ( const Real fScalar ) const
179  {
180  return Vector3(
181  x * fScalar,
182  y * fScalar,
183  z * fScalar);
184  }
185 
186  inline Vector3 operator * ( const Vector3& rhs) const
187  {
188  return Vector3(
189  x * rhs.x,
190  y * rhs.y,
191  z * rhs.z);
192  }
193 
194  inline Vector3 operator / ( const Real fScalar ) const
195  {
196  assert( fScalar != 0.0 );
197 
198  Real fInv = 1.0f / fScalar;
199 
200  return Vector3(
201  x * fInv,
202  y * fInv,
203  z * fInv);
204  }
205 
206  inline Vector3 operator / ( const Vector3& rhs) const
207  {
208  return Vector3(
209  x / rhs.x,
210  y / rhs.y,
211  z / rhs.z);
212  }
213 
214  inline const Vector3& operator + () const
215  {
216  return *this;
217  }
218 
219  inline Vector3 operator - () const
220  {
221  return Vector3(-x, -y, -z);
222  }
223 
224  // overloaded operators to help Vector3
225  inline friend Vector3 operator * ( const Real fScalar, const Vector3& rkVector )
226  {
227  return Vector3(
228  fScalar * rkVector.x,
229  fScalar * rkVector.y,
230  fScalar * rkVector.z);
231  }
232 
233  inline friend Vector3 operator / ( const Real fScalar, const Vector3& rkVector )
234  {
235  return Vector3(
236  fScalar / rkVector.x,
237  fScalar / rkVector.y,
238  fScalar / rkVector.z);
239  }
240 
241  inline friend Vector3 operator + (const Vector3& lhs, const Real rhs)
242  {
243  return Vector3(
244  lhs.x + rhs,
245  lhs.y + rhs,
246  lhs.z + rhs);
247  }
248 
249  inline friend Vector3 operator + (const Real lhs, const Vector3& rhs)
250  {
251  return Vector3(
252  lhs + rhs.x,
253  lhs + rhs.y,
254  lhs + rhs.z);
255  }
256 
257  inline friend Vector3 operator - (const Vector3& lhs, const Real rhs)
258  {
259  return Vector3(
260  lhs.x - rhs,
261  lhs.y - rhs,
262  lhs.z - rhs);
263  }
264 
265  inline friend Vector3 operator - (const Real lhs, const Vector3& rhs)
266  {
267  return Vector3(
268  lhs - rhs.x,
269  lhs - rhs.y,
270  lhs - rhs.z);
271  }
272 
273  // arithmetic updates
274  inline Vector3& operator += ( const Vector3& rkVector )
275  {
276  x += rkVector.x;
277  y += rkVector.y;
278  z += rkVector.z;
279 
280  return *this;
281  }
282 
283  inline Vector3& operator += ( const Real fScalar )
284  {
285  x += fScalar;
286  y += fScalar;
287  z += fScalar;
288  return *this;
289  }
290 
291  inline Vector3& operator -= ( const Vector3& rkVector )
292  {
293  x -= rkVector.x;
294  y -= rkVector.y;
295  z -= rkVector.z;
296 
297  return *this;
298  }
299 
300  inline Vector3& operator -= ( const Real fScalar )
301  {
302  x -= fScalar;
303  y -= fScalar;
304  z -= fScalar;
305  return *this;
306  }
307 
308  inline Vector3& operator *= ( const Real fScalar )
309  {
310  x *= fScalar;
311  y *= fScalar;
312  z *= fScalar;
313  return *this;
314  }
315 
316  inline Vector3& operator *= ( const Vector3& rkVector )
317  {
318  x *= rkVector.x;
319  y *= rkVector.y;
320  z *= rkVector.z;
321 
322  return *this;
323  }
324 
325  inline Vector3& operator /= ( const Real fScalar )
326  {
327  assert( fScalar != 0.0 );
328 
329  Real fInv = 1.0f / fScalar;
330 
331  x *= fInv;
332  y *= fInv;
333  z *= fInv;
334 
335  return *this;
336  }
337 
338  inline Vector3& operator /= ( const Vector3& rkVector )
339  {
340  x /= rkVector.x;
341  y /= rkVector.y;
342  z /= rkVector.z;
343 
344  return *this;
345  }
346 
347 
355  inline Real length () const
356  {
357  return Math::Sqrt( x * x + y * y + z * z );
358  }
359 
370  inline Real squaredLength () const
371  {
372  return x * x + y * y + z * z;
373  }
374 
382  inline Real distance(const Vector3& rhs) const
383  {
384  return (*this - rhs).length();
385  }
386 
397  inline Real squaredDistance(const Vector3& rhs) const
398  {
399  return (*this - rhs).squaredLength();
400  }
401 
416  inline Real dotProduct(const Vector3& vec) const
417  {
418  return x * vec.x + y * vec.y + z * vec.z;
419  }
420 
431  inline Real absDotProduct(const Vector3& vec) const
432  {
433  return Math::Abs(x * vec.x) + Math::Abs(y * vec.y) + Math::Abs(z * vec.z);
434  }
435 
445  inline Real normalise()
446  {
447  Real fLength = Math::Sqrt( x * x + y * y + z * z );
448 
449  // Will also work for zero-sized vectors, but will change nothing
450  // We're not using epsilons because we don't need to.
451  // Read http://www.ogre3d.org/forums/viewtopic.php?f=4&t=61259
452  if ( fLength > Real(0.0f) )
453  {
454  Real fInvLength = 1.0f / fLength;
455  x *= fInvLength;
456  y *= fInvLength;
457  z *= fInvLength;
458  }
459 
460  return fLength;
461  }
462 
491  inline Vector3 crossProduct( const Vector3& rkVector ) const
492  {
493  return Vector3(
494  y * rkVector.z - z * rkVector.y,
495  z * rkVector.x - x * rkVector.z,
496  x * rkVector.y - y * rkVector.x);
497  }
498 
502  inline Vector3 midPoint( const Vector3& vec ) const
503  {
504  return Vector3(
505  ( x + vec.x ) * 0.5f,
506  ( y + vec.y ) * 0.5f,
507  ( z + vec.z ) * 0.5f );
508  }
509 
513  inline bool operator < ( const Vector3& rhs ) const
514  {
515  if( x < rhs.x && y < rhs.y && z < rhs.z )
516  return true;
517  return false;
518  }
519 
523  inline bool operator > ( const Vector3& rhs ) const
524  {
525  if( x > rhs.x && y > rhs.y && z > rhs.z )
526  return true;
527  return false;
528  }
529 
537  inline void makeFloor( const Vector3& cmp )
538  {
539  x = Ogre::min( x, cmp.x );
540  y = Ogre::min( y, cmp.y );
541  z = Ogre::min( z, cmp.z );
542  }
543 
551  inline void makeCeil( const Vector3& cmp )
552  {
553  x = Ogre::max( x, cmp.x );
554  y = Ogre::max( y, cmp.y );
555  z = Ogre::max( z, cmp.z );
556  }
557 
559  inline void makeAbs()
560  {
561  x = Math::Abs( x );
562  y = Math::Abs( y );
563  z = Math::Abs( z );
564  }
565 
573  inline Vector3 perpendicular(void) const
574  {
575  static const Real fSquareZero = (Real)(1e-06 * 1e-06);
576 
577  Vector3 perp = this->crossProduct( Vector3::UNIT_X );
578 
579  // Check length
580  if( perp.squaredLength() < fSquareZero )
581  {
582  /* This vector is the Y axis multiplied by a scalar, so we have
583  to use another axis.
584  */
585  perp = this->crossProduct( Vector3::UNIT_Y );
586  }
587  perp.normalise();
588 
589  return perp;
590  }
611  const Radian& angle,
612  const Vector3& up = Vector3::ZERO ) const
613  {
614  Vector3 newUp;
615 
616  if (up == Vector3::ZERO)
617  {
618  // Generate an up vector
619  newUp = this->perpendicular();
620  }
621  else
622  {
623  newUp = up;
624  }
625 
626  // Rotate up vector by random amount around this
627  Quaternion q;
629  newUp = q * newUp;
630 
631  // Finally rotate this by given angle around randomised up
632  q.FromAngleAxis( angle, newUp );
633  return q * (*this);
634  }
635 
640  inline Radian angleBetween(const Vector3& dest) const
641  {
642  Real lenProduct = length() * dest.length();
643 
644  // Divide by zero check
645  if(lenProduct < 1e-6f)
646  lenProduct = 1e-6f;
647 
648  Real f = dotProduct(dest) / lenProduct;
649 
650  f = Math::Clamp(f, (Real)-1.0, (Real)1.0);
651  return Math::ACos(f);
652 
653  }
663  const Vector3& fallbackAxis = Vector3::ZERO) const
664  {
665  // Based on Stan Melax's article in Game Programming Gems
666  Quaternion q;
667  // Copy, since cannot modify local
668  Vector3 v0 = *this;
669  Vector3 v1 = dest;
670  v0.normalise();
671  v1.normalise();
672 
673  Real d = v0.dotProduct(v1);
674  // If dot == 1, vectors are the same
675  if (d >= 1.0f)
676  {
677  return Quaternion::IDENTITY;
678  }
679  if (d < (1e-6f - 1.0f))
680  {
681  if (fallbackAxis != Vector3::ZERO)
682  {
683  // rotate 180 degrees about the fallback axis
684  q.FromAngleAxis(Radian(Math::PI), fallbackAxis);
685  }
686  else
687  {
688  // Generate an axis
689  Vector3 axis = Vector3::UNIT_X.crossProduct(*this);
690  if (axis.isZeroLength()) // pick another if colinear
691  axis = Vector3::UNIT_Y.crossProduct(*this);
692  axis.normalise();
693  q.FromAngleAxis(Radian(Math::PI), axis);
694  }
695  }
696  else
697  {
698  Real s = Math::Sqrt( (1+d)*2 );
699  Real invs = 1 / s;
700 
701  Vector3 c = v0.crossProduct(v1);
702 
703  q.x = c.x * invs;
704  q.y = c.y * invs;
705  q.z = c.z * invs;
706  q.w = s * 0.5f;
707  q.normalise();
708  }
709  return q;
710  }
711 
713  inline bool isZeroLength(void) const
714  {
715  Real sqlen = (x * x) + (y * y) + (z * z);
716  return (sqlen < (1e-06 * 1e-06));
717 
718  }
719 
722  inline Vector3 normalisedCopy(void) const
723  {
724  Vector3 ret = *this;
725  ret.normalise();
726  return ret;
727  }
728 
732  inline Vector3 reflect(const Vector3& normal) const
733  {
734  return Vector3( *this - ( 2 * this->dotProduct(normal) * normal ) );
735  }
736 
743  inline bool positionEquals(const Vector3& rhs, Real tolerance = 1e-03) const
744  {
745  return Math::RealEqual(x, rhs.x, tolerance) &&
746  Math::RealEqual(y, rhs.y, tolerance) &&
747  Math::RealEqual(z, rhs.z, tolerance);
748 
749  }
750 
757  inline bool positionCloses(const Vector3& rhs, Real tolerance = 1e-03f) const
758  {
759  return squaredDistance(rhs) <=
760  (squaredLength() + rhs.squaredLength()) * tolerance;
761  }
762 
770  inline bool directionEquals(const Vector3& rhs,
771  const Radian& tolerance) const
772  {
773  Real dot = dotProduct(rhs);
774  Radian angle = Math::ACos(dot);
775 
776  return Math::Abs(angle.valueRadians()) <= tolerance.valueRadians();
777 
778  }
779 
781  inline bool isNaN() const
782  {
783  return Math::isNaN(x) || Math::isNaN(y) || Math::isNaN(z);
784  }
785 
787  inline Vector3 primaryAxis() const
788  {
789  Real absx = Math::Abs(x);
790  Real absy = Math::Abs(y);
791  Real absz = Math::Abs(z);
792  if (absx > absy)
793  if (absx > absz)
794  return x > 0 ? Vector3::UNIT_X : Vector3::NEGATIVE_UNIT_X;
795  else
796  return z > 0 ? Vector3::UNIT_Z : Vector3::NEGATIVE_UNIT_Z;
797  else // absx <= absy
798  if (absy > absz)
799  return y > 0 ? Vector3::UNIT_Y : Vector3::NEGATIVE_UNIT_Y;
800  else
801  return z > 0 ? Vector3::UNIT_Z : Vector3::NEGATIVE_UNIT_Z;
802 
803 
804  }
805 
806  // special points
807  static const Vector3 ZERO;
808  static const Vector3 UNIT_X;
809  static const Vector3 UNIT_Y;
810  static const Vector3 UNIT_Z;
811  static const Vector3 NEGATIVE_UNIT_X;
812  static const Vector3 NEGATIVE_UNIT_Y;
813  static const Vector3 NEGATIVE_UNIT_Z;
814  static const Vector3 UNIT_SCALE;
815 
818  inline _OgreExport friend std::ostream& operator <<
819  ( std::ostream& o, const Vector3& v )
820  {
821  o << "Vector3(" << v.x << ", " << v.y << ", " << v.z << ")";
822  return o;
823  }
824  };
828 }
829 #endif
bool isNaN() const
Check whether this vector contains valid values.
Definition: OgreVector3.h:781
static const Vector3 NEGATIVE_UNIT_Y
Definition: OgreVector3.h:812
static const Vector3 NEGATIVE_UNIT_X
Definition: OgreVector3.h:811
static const Vector3 UNIT_Z
Definition: OgreVector3.h:810
Vector3(Real *const r)
Definition: OgreVector3.h:83
static Real UnitRandom()
Generate a random number of unit length.
const Real * ptr() const
Pointer accessor for direct copying.
Definition: OgreVector3.h:124
Vector3 randomDeviant(const Radian &angle, const Vector3 &up=Vector3::ZERO) const
Generates a new random vector which deviates from this vector by a given angle in a random direction...
Definition: OgreVector3.h:610
float Real
Software floating point type.
Vector3 perpendicular(void) const
Generates a vector perpendicular to this vector (eg an 'up' vector).
Definition: OgreVector3.h:573
#define _OgreExport
Definition: OgrePlatform.h:255
static T Clamp(T val, T minval, T maxval)
Clamp a value within an inclusive range.
Definition: OgreMath.h:712
const float & max(const float &a, const float &b)
Definition: OgreCommon.h:851
bool operator<(SharedPtr< T > const &a, SharedPtr< U > const &b)
Real squaredDistance(const Vector3 &rhs) const
Returns the square of the distance to another vector.
Definition: OgreVector3.h:397
bool positionEquals(const Vector3 &rhs, Real tolerance=1e-03) const
Returns whether this vector is within a positional tolerance of another vector.
Definition: OgreVector3.h:743
static const Vector3 ZERO
Definition: OgreVector3.h:807
static const Real TWO_PI
Definition: OgreMath.h:729
Quaternion getRotationTo(const Vector3 &dest, const Vector3 &fallbackAxis=Vector3::ZERO) const
Gets the shortest arc quaternion to rotate this vector to the destination vector. ...
Definition: OgreVector3.h:662
Real length() const
Returns the length (magnitude) of the vector.
Definition: OgreVector3.h:355
void makeFloor(const Vector3 &cmp)
Sets this vector's components to the minimum of its own and the ones of the passed in vector...
Definition: OgreVector3.h:537
Vector3(const Real scaler)
Definition: OgreVector3.h:88
Real dotProduct(const Vector3 &vec) const
Calculates the dot (scalar) product of this vector with another.
Definition: OgreVector3.h:416
Vector3()
Default constructor.
Definition: OgreVector3.h:60
static Radian ACos(Real fValue)
Arc cosine function.
Real * ptr()
Pointer accessor for direct copying.
Definition: OgreVector3.h:119
Radian operator*(Real a, const Radian &b)
Definition: OgreMath.h:782
static bool RealEqual(Real a, Real b, Real tolerance=std::numeric_limits< Real >::epsilon())
Compare 2 reals, using tolerance for inaccuracies.
Radian operator/(Real a, const Radian &b)
Definition: OgreMath.h:787
Implementation of a Quaternion, i.e.
bool isZeroLength(void) const
Returns true if this vector is zero length.
Definition: OgreVector3.h:713
Vector3(const Real afCoordinate[3])
Definition: OgreVector3.h:69
static const Real PI
Definition: OgreMath.h:728
static const Quaternion IDENTITY
static const Vector3 NEGATIVE_UNIT_Z
Definition: OgreVector3.h:813
static Real Abs(Real fValue)
Absolute value function.
Definition: OgreMath.h:260
bool directionEquals(const Vector3 &rhs, const Radian &tolerance) const
Returns whether this vector is within a directional tolerance of another vector.
Definition: OgreVector3.h:770
bool positionCloses(const Vector3 &rhs, Real tolerance=1e-03f) const
Returns whether this vector is within a positional tolerance of another vector, also take scale of th...
Definition: OgreVector3.h:757
Radian angleBetween(const Vector3 &dest) const
Gets the angle between 2 vectors.
Definition: OgreVector3.h:640
static Real Sqrt(Real fValue)
Square root function.
Definition: OgreMath.h:423
void makeAbs()
Causes negative members to become positive.
Definition: OgreVector3.h:559
const float & min(const float &a, const float &b)
Definition: OgreCommon.h:846
void FromAngleAxis(const Radian &rfAngle, const Vector3 &rkAxis)
Setups the quaternion using the supplied vector, and "roll" around that vector by the specified radia...
Real absDotProduct(const Vector3 &vec) const
Calculates the absolute dot (scalar) product of this vector with another.
Definition: OgreVector3.h:431
Real valueRadians() const
Definition: OgreMath.h:61
Real squaredLength() const
Returns the square of the length(magnitude) of the vector.
Definition: OgreVector3.h:370
void swap(Ogre::SmallVectorImpl< T > &LHS, Ogre::SmallVectorImpl< T > &RHS)
Implement std::swap in terms of SmallVector swap.
Standard 3-dimensional vector.
Definition: OgreVector3.h:50
Vector3 primaryAxis() const
Extract the primary (dominant) axis from this direction vector.
Definition: OgreVector3.h:787
Wrapper class which indicates a given angle value is in Radians.
Definition: OgreMath.h:49
static const Vector3 UNIT_X
Definition: OgreVector3.h:808
Real distance(const Vector3 &rhs) const
Returns the distance to another vector.
Definition: OgreVector3.h:382
void makeCeil(const Vector3 &cmp)
Sets this vector's components to the maximum of its own and the ones of the passed in vector...
Definition: OgreVector3.h:551
Real normalise()
Normalises the vector.
Definition: OgreVector3.h:445
static const Vector3 UNIT_Y
Definition: OgreVector3.h:809
Vector3 reflect(const Vector3 &normal) const
Calculates a reflection vector to the plane with the given normal .
Definition: OgreVector3.h:732
static bool isNaN(Real f)
Definition: OgreMath.h:307
Vector3(const Real fX, const Real fY, const Real fZ)
Definition: OgreVector3.h:64
Vector3 crossProduct(const Vector3 &rkVector) const
Calculates the cross-product of 2 vectors, i.e.
Definition: OgreVector3.h:491
void swap(Vector3 &other)
Exchange the contents of this vector with another.
Definition: OgreVector3.h:98
Vector3(const int afCoordinate[3])
Definition: OgreVector3.h:76
Real normalise(void)
Normalises this quaternion, and returns the previous length.
static const Vector3 UNIT_SCALE
Definition: OgreVector3.h:814
Vector3 normalisedCopy(void) const
As normalise, except that this vector is unaffected and the normalised vector is returned as a copy...
Definition: OgreVector3.h:722
Vector3 midPoint(const Vector3 &vec) const
Returns a vector at a point half way between this and the passed in vector.
Definition: OgreVector3.h:502
bool operator==(STLAllocator< T, P > const &, STLAllocator< T2, P > const &)
determine equality, can memory from another allocator be released by this allocator, (ISO C++)
bool operator!=(STLAllocator< T, P > const &, STLAllocator< T2, P > const &)
determine equality, can memory from another allocator be released by this allocator, (ISO C++)