OGRE  1.7
Object-Oriented Graphics Rendering Engine
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator 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-2011 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 "OgreMath.h"
33 #include "OgreQuaternion.h"
34 
35 namespace Ogre
36 {
37 
52  {
53  public:
54  Real x, y, z;
55 
56  public:
57  inline Vector3()
58  {
59  }
60 
61  inline Vector3( const Real fX, const Real fY, const Real fZ )
62  : x( fX ), y( fY ), z( fZ )
63  {
64  }
65 
66  inline explicit Vector3( const Real afCoordinate[3] )
67  : x( afCoordinate[0] ),
68  y( afCoordinate[1] ),
69  z( afCoordinate[2] )
70  {
71  }
72 
73  inline explicit Vector3( const int afCoordinate[3] )
74  {
75  x = (Real)afCoordinate[0];
76  y = (Real)afCoordinate[1];
77  z = (Real)afCoordinate[2];
78  }
79 
80  inline explicit Vector3( Real* const r )
81  : x( r[0] ), y( r[1] ), z( r[2] )
82  {
83  }
84 
85  inline explicit Vector3( const Real scaler )
86  : x( scaler )
87  , y( scaler )
88  , z( scaler )
89  {
90  }
91 
92 
95  inline void swap(Vector3& other)
96  {
97  std::swap(x, other.x);
98  std::swap(y, other.y);
99  std::swap(z, other.z);
100  }
101 
102  inline Real operator [] ( const size_t i ) const
103  {
104  assert( i < 3 );
105 
106  return *(&x+i);
107  }
108 
109  inline Real& operator [] ( const size_t i )
110  {
111  assert( i < 3 );
112 
113  return *(&x+i);
114  }
116  inline Real* ptr()
117  {
118  return &x;
119  }
121  inline const Real* ptr() const
122  {
123  return &x;
124  }
125 
130  inline Vector3& operator = ( const Vector3& rkVector )
131  {
132  x = rkVector.x;
133  y = rkVector.y;
134  z = rkVector.z;
135 
136  return *this;
137  }
138 
139  inline Vector3& operator = ( const Real fScaler )
140  {
141  x = fScaler;
142  y = fScaler;
143  z = fScaler;
144 
145  return *this;
146  }
147 
148  inline bool operator == ( const Vector3& rkVector ) const
149  {
150  return ( x == rkVector.x && y == rkVector.y && z == rkVector.z );
151  }
152 
153  inline bool operator != ( const Vector3& rkVector ) const
154  {
155  return ( x != rkVector.x || y != rkVector.y || z != rkVector.z );
156  }
157 
158  // arithmetic operations
159  inline Vector3 operator + ( const Vector3& rkVector ) const
160  {
161  return Vector3(
162  x + rkVector.x,
163  y + rkVector.y,
164  z + rkVector.z);
165  }
166 
167  inline Vector3 operator - ( const Vector3& rkVector ) const
168  {
169  return Vector3(
170  x - rkVector.x,
171  y - rkVector.y,
172  z - rkVector.z);
173  }
174 
175  inline Vector3 operator * ( const Real fScalar ) const
176  {
177  return Vector3(
178  x * fScalar,
179  y * fScalar,
180  z * fScalar);
181  }
182 
183  inline Vector3 operator * ( const Vector3& rhs) const
184  {
185  return Vector3(
186  x * rhs.x,
187  y * rhs.y,
188  z * rhs.z);
189  }
190 
191  inline Vector3 operator / ( const Real fScalar ) const
192  {
193  assert( fScalar != 0.0 );
194 
195  Real fInv = 1.0f / fScalar;
196 
197  return Vector3(
198  x * fInv,
199  y * fInv,
200  z * fInv);
201  }
202 
203  inline Vector3 operator / ( const Vector3& rhs) const
204  {
205  return Vector3(
206  x / rhs.x,
207  y / rhs.y,
208  z / rhs.z);
209  }
210 
211  inline const Vector3& operator + () const
212  {
213  return *this;
214  }
215 
216  inline Vector3 operator - () const
217  {
218  return Vector3(-x, -y, -z);
219  }
220 
221  // overloaded operators to help Vector3
222  inline friend Vector3 operator * ( const Real fScalar, const Vector3& rkVector )
223  {
224  return Vector3(
225  fScalar * rkVector.x,
226  fScalar * rkVector.y,
227  fScalar * rkVector.z);
228  }
229 
230  inline friend Vector3 operator / ( const Real fScalar, const Vector3& rkVector )
231  {
232  return Vector3(
233  fScalar / rkVector.x,
234  fScalar / rkVector.y,
235  fScalar / rkVector.z);
236  }
237 
238  inline friend Vector3 operator + (const Vector3& lhs, const Real rhs)
239  {
240  return Vector3(
241  lhs.x + rhs,
242  lhs.y + rhs,
243  lhs.z + rhs);
244  }
245 
246  inline friend Vector3 operator + (const Real lhs, const Vector3& rhs)
247  {
248  return Vector3(
249  lhs + rhs.x,
250  lhs + rhs.y,
251  lhs + rhs.z);
252  }
253 
254  inline friend Vector3 operator - (const Vector3& lhs, const Real rhs)
255  {
256  return Vector3(
257  lhs.x - rhs,
258  lhs.y - rhs,
259  lhs.z - rhs);
260  }
261 
262  inline friend Vector3 operator - (const Real lhs, const Vector3& rhs)
263  {
264  return Vector3(
265  lhs - rhs.x,
266  lhs - rhs.y,
267  lhs - rhs.z);
268  }
269 
270  // arithmetic updates
271  inline Vector3& operator += ( const Vector3& rkVector )
272  {
273  x += rkVector.x;
274  y += rkVector.y;
275  z += rkVector.z;
276 
277  return *this;
278  }
279 
280  inline Vector3& operator += ( const Real fScalar )
281  {
282  x += fScalar;
283  y += fScalar;
284  z += fScalar;
285  return *this;
286  }
287 
288  inline Vector3& operator -= ( const Vector3& rkVector )
289  {
290  x -= rkVector.x;
291  y -= rkVector.y;
292  z -= rkVector.z;
293 
294  return *this;
295  }
296 
297  inline Vector3& operator -= ( const Real fScalar )
298  {
299  x -= fScalar;
300  y -= fScalar;
301  z -= fScalar;
302  return *this;
303  }
304 
305  inline Vector3& operator *= ( const Real fScalar )
306  {
307  x *= fScalar;
308  y *= fScalar;
309  z *= fScalar;
310  return *this;
311  }
312 
313  inline Vector3& operator *= ( const Vector3& rkVector )
314  {
315  x *= rkVector.x;
316  y *= rkVector.y;
317  z *= rkVector.z;
318 
319  return *this;
320  }
321 
322  inline Vector3& operator /= ( const Real fScalar )
323  {
324  assert( fScalar != 0.0 );
325 
326  Real fInv = 1.0f / fScalar;
327 
328  x *= fInv;
329  y *= fInv;
330  z *= fInv;
331 
332  return *this;
333  }
334 
335  inline Vector3& operator /= ( const Vector3& rkVector )
336  {
337  x /= rkVector.x;
338  y /= rkVector.y;
339  z /= rkVector.z;
340 
341  return *this;
342  }
343 
344 
352  inline Real length () const
353  {
354  return Math::Sqrt( x * x + y * y + z * z );
355  }
356 
367  inline Real squaredLength () const
368  {
369  return x * x + y * y + z * z;
370  }
371 
379  inline Real distance(const Vector3& rhs) const
380  {
381  return (*this - rhs).length();
382  }
383 
394  inline Real squaredDistance(const Vector3& rhs) const
395  {
396  return (*this - rhs).squaredLength();
397  }
398 
413  inline Real dotProduct(const Vector3& vec) const
414  {
415  return x * vec.x + y * vec.y + z * vec.z;
416  }
417 
428  inline Real absDotProduct(const Vector3& vec) const
429  {
430  return Math::Abs(x * vec.x) + Math::Abs(y * vec.y) + Math::Abs(z * vec.z);
431  }
432 
442  inline Real normalise()
443  {
444  Real fLength = Math::Sqrt( x * x + y * y + z * z );
445 
446  // Will also work for zero-sized vectors, but will change nothing
447  if ( fLength > 1e-08 )
448  {
449  Real fInvLength = 1.0f / fLength;
450  x *= fInvLength;
451  y *= fInvLength;
452  z *= fInvLength;
453  }
454 
455  return fLength;
456  }
457 
486  inline Vector3 crossProduct( const Vector3& rkVector ) const
487  {
488  return Vector3(
489  y * rkVector.z - z * rkVector.y,
490  z * rkVector.x - x * rkVector.z,
491  x * rkVector.y - y * rkVector.x);
492  }
493 
497  inline Vector3 midPoint( const Vector3& vec ) const
498  {
499  return Vector3(
500  ( x + vec.x ) * 0.5f,
501  ( y + vec.y ) * 0.5f,
502  ( z + vec.z ) * 0.5f );
503  }
504 
508  inline bool operator < ( const Vector3& rhs ) const
509  {
510  if( x < rhs.x && y < rhs.y && z < rhs.z )
511  return true;
512  return false;
513  }
514 
518  inline bool operator > ( const Vector3& rhs ) const
519  {
520  if( x > rhs.x && y > rhs.y && z > rhs.z )
521  return true;
522  return false;
523  }
524 
532  inline void makeFloor( const Vector3& cmp )
533  {
534  if( cmp.x < x ) x = cmp.x;
535  if( cmp.y < y ) y = cmp.y;
536  if( cmp.z < z ) z = cmp.z;
537  }
538 
546  inline void makeCeil( const Vector3& cmp )
547  {
548  if( cmp.x > x ) x = cmp.x;
549  if( cmp.y > y ) y = cmp.y;
550  if( cmp.z > z ) z = cmp.z;
551  }
552 
560  inline Vector3 perpendicular(void) const
561  {
562  static const Real fSquareZero = (Real)(1e-06 * 1e-06);
563 
564  Vector3 perp = this->crossProduct( Vector3::UNIT_X );
565 
566  // Check length
567  if( perp.squaredLength() < fSquareZero )
568  {
569  /* This vector is the Y axis multiplied by a scalar, so we have
570  to use another axis.
571  */
572  perp = this->crossProduct( Vector3::UNIT_Y );
573  }
574  perp.normalise();
575 
576  return perp;
577  }
598  const Radian& angle,
599  const Vector3& up = Vector3::ZERO ) const
600  {
601  Vector3 newUp;
602 
603  if (up == Vector3::ZERO)
604  {
605  // Generate an up vector
606  newUp = this->perpendicular();
607  }
608  else
609  {
610  newUp = up;
611  }
612 
613  // Rotate up vector by random amount around this
614  Quaternion q;
616  newUp = q * newUp;
617 
618  // Finally rotate this by given angle around randomised up
619  q.FromAngleAxis( angle, newUp );
620  return q * (*this);
621  }
622 
627  inline Radian angleBetween(const Vector3& dest)
628  {
629  Real lenProduct = length() * dest.length();
630 
631  // Divide by zero check
632  if(lenProduct < 1e-6f)
633  lenProduct = 1e-6f;
634 
635  Real f = dotProduct(dest) / lenProduct;
636 
637  f = Math::Clamp(f, (Real)-1.0, (Real)1.0);
638  return Math::ACos(f);
639 
640  }
650  const Vector3& fallbackAxis = Vector3::ZERO) const
651  {
652  // Based on Stan Melax's article in Game Programming Gems
653  Quaternion q;
654  // Copy, since cannot modify local
655  Vector3 v0 = *this;
656  Vector3 v1 = dest;
657  v0.normalise();
658  v1.normalise();
659 
660  Real d = v0.dotProduct(v1);
661  // If dot == 1, vectors are the same
662  if (d >= 1.0f)
663  {
664  return Quaternion::IDENTITY;
665  }
666  if (d < (1e-6f - 1.0f))
667  {
668  if (fallbackAxis != Vector3::ZERO)
669  {
670  // rotate 180 degrees about the fallback axis
671  q.FromAngleAxis(Radian(Math::PI), fallbackAxis);
672  }
673  else
674  {
675  // Generate an axis
676  Vector3 axis = Vector3::UNIT_X.crossProduct(*this);
677  if (axis.isZeroLength()) // pick another if colinear
678  axis = Vector3::UNIT_Y.crossProduct(*this);
679  axis.normalise();
680  q.FromAngleAxis(Radian(Math::PI), axis);
681  }
682  }
683  else
684  {
685  Real s = Math::Sqrt( (1+d)*2 );
686  Real invs = 1 / s;
687 
688  Vector3 c = v0.crossProduct(v1);
689 
690  q.x = c.x * invs;
691  q.y = c.y * invs;
692  q.z = c.z * invs;
693  q.w = s * 0.5f;
694  q.normalise();
695  }
696  return q;
697  }
698 
700  inline bool isZeroLength(void) const
701  {
702  Real sqlen = (x * x) + (y * y) + (z * z);
703  return (sqlen < (1e-06 * 1e-06));
704 
705  }
706 
709  inline Vector3 normalisedCopy(void) const
710  {
711  Vector3 ret = *this;
712  ret.normalise();
713  return ret;
714  }
715 
719  inline Vector3 reflect(const Vector3& normal) const
720  {
721  return Vector3( *this - ( 2 * this->dotProduct(normal) * normal ) );
722  }
723 
730  inline bool positionEquals(const Vector3& rhs, Real tolerance = 1e-03) const
731  {
732  return Math::RealEqual(x, rhs.x, tolerance) &&
733  Math::RealEqual(y, rhs.y, tolerance) &&
734  Math::RealEqual(z, rhs.z, tolerance);
735 
736  }
737 
744  inline bool positionCloses(const Vector3& rhs, Real tolerance = 1e-03f) const
745  {
746  return squaredDistance(rhs) <=
747  (squaredLength() + rhs.squaredLength()) * tolerance;
748  }
749 
757  inline bool directionEquals(const Vector3& rhs,
758  const Radian& tolerance) const
759  {
760  Real dot = dotProduct(rhs);
761  Radian angle = Math::ACos(dot);
762 
763  return Math::Abs(angle.valueRadians()) <= tolerance.valueRadians();
764 
765  }
766 
768  inline bool isNaN() const
769  {
770  return Math::isNaN(x) || Math::isNaN(y) || Math::isNaN(z);
771  }
772 
773  // special points
774  static const Vector3 ZERO;
775  static const Vector3 UNIT_X;
776  static const Vector3 UNIT_Y;
777  static const Vector3 UNIT_Z;
778  static const Vector3 NEGATIVE_UNIT_X;
779  static const Vector3 NEGATIVE_UNIT_Y;
780  static const Vector3 NEGATIVE_UNIT_Z;
781  static const Vector3 UNIT_SCALE;
782 
785  inline _OgreExport friend std::ostream& operator <<
786  ( std::ostream& o, const Vector3& v )
787  {
788  o << "Vector3(" << v.x << ", " << v.y << ", " << v.z << ")";
789  return o;
790  }
791  };
795 }
796 #endif
bool isNaN() const
Check whether this vector contains valid values.
Definition: OgreVector3.h:768
static const Vector3 NEGATIVE_UNIT_Y
Definition: OgreVector3.h:779
static const Vector3 NEGATIVE_UNIT_X
Definition: OgreVector3.h:778
static const Vector3 UNIT_Z
Definition: OgreVector3.h:777
Vector3(Real *const r)
Definition: OgreVector3.h:80
static Real UnitRandom()
const Real * ptr() const
Pointer accessor for direct copying.
Definition: OgreVector3.h:121
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:597
float Real
Software floating point type.
Vector3 perpendicular(void) const
Generates a vector perpendicular to this vector (eg an 'up' vector).
Definition: OgreVector3.h:560
#define _OgreExport
Definition: OgrePlatform.h:203
static T Clamp(T val, T minval, T maxval)
Clamp a value within an inclusive range.
Definition: OgreMath.h:576
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:394
Radian angleBetween(const Vector3 &dest)
Gets the angle between 2 vectors.
Definition: OgreVector3.h:627
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:730
static const Vector3 ZERO
Definition: OgreVector3.h:774
static const Real TWO_PI
Definition: OgreMath.h:593
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:649
Real length() const
Returns the length (magnitude) of the vector.
Definition: OgreVector3.h:352
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:532
Vector3(const Real scaler)
Definition: OgreVector3.h:85
Real dotProduct(const Vector3 &vec) const
Calculates the dot (scalar) product of this vector with another.
Definition: OgreVector3.h:413
static Radian ACos(Real fValue)
Real * ptr()
Pointer accessor for direct copying.
Definition: OgreVector3.h:116
Radian operator*(Real a, const Radian &b)
Definition: OgreMath.h:633
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:638
Implementation of a Quaternion, i.e.
bool isZeroLength(void) const
Returns true if this vector is zero length.
Definition: OgreVector3.h:700
Vector3(const Real afCoordinate[3])
Definition: OgreVector3.h:66
static const Real PI
Definition: OgreMath.h:592
static const Quaternion IDENTITY
static const Vector3 NEGATIVE_UNIT_Z
Definition: OgreVector3.h:780
static Real Abs(Real fValue)
Definition: OgreMath.h:239
bool directionEquals(const Vector3 &rhs, const Radian &tolerance) const
Returns whether this vector is within a directional tolerance of another vector.
Definition: OgreVector3.h:757
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:744
static Real Sqrt(Real fValue)
Definition: OgreMath.h:323
void FromAngleAxis(const Radian &rfAngle, const Vector3 &rkAxis)
Real absDotProduct(const Vector3 &vec) const
Calculates the absolute dot (scalar) product of this vector with another.
Definition: OgreVector3.h:428
Real valueRadians() const
Definition: OgreMath.h:58
Real squaredLength() const
Returns the square of the length(magnitude) of the vector.
Definition: OgreVector3.h:367
Standard 3-dimensional vector.
Definition: OgreVector3.h:51
Wrapper class which indicates a given angle value is in Radians.
Definition: OgreMath.h:46
static const Vector3 UNIT_X
Definition: OgreVector3.h:775
Real distance(const Vector3 &rhs) const
Returns the distance to another vector.
Definition: OgreVector3.h:379
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:546
Real normalise()
Normalises the vector.
Definition: OgreVector3.h:442
static const Vector3 UNIT_Y
Definition: OgreVector3.h:776
Vector3 reflect(const Vector3 &normal) const
Calculates a reflection vector to the plane with the given normal .
Definition: OgreVector3.h:719
static bool isNaN(Real f)
Definition: OgreMath.h:247
Vector3(const Real fX, const Real fY, const Real fZ)
Definition: OgreVector3.h:61
Vector3 crossProduct(const Vector3 &rkVector) const
Calculates the cross-product of 2 vectors, i.e.
Definition: OgreVector3.h:486
void swap(Vector3 &other)
Exchange the contents of this vector with another.
Definition: OgreVector3.h:95
Vector3(const int afCoordinate[3])
Definition: OgreVector3.h:73
Real normalise(void)
Normalises this quaternion, and returns the previous length.
static const Vector3 UNIT_SCALE
Definition: OgreVector3.h:781
Vector3 normalisedCopy(void) const
As normalise, except that this vector is unaffected and the normalised vector is returned as a copy...
Definition: OgreVector3.h:709
Vector3 midPoint(const Vector3 &vec) const
Returns a vector at a point half way between this and the passed in vector.
Definition: OgreVector3.h:497
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++)