OGRE  1.9
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 "OgreMath.h"
33 #include "OgreQuaternion.h"
34 
35 namespace Ogre
36 {
37 
52  {
53  public:
54  Real x, y, z;
55 
56  public:
61  inline Vector3()
62  {
63  }
64 
65  inline Vector3( const Real fX, const Real fY, const Real fZ )
66  : x( fX ), y( fY ), z( fZ )
67  {
68  }
69 
70  inline explicit Vector3( const Real afCoordinate[3] )
71  : x( afCoordinate[0] ),
72  y( afCoordinate[1] ),
73  z( afCoordinate[2] )
74  {
75  }
76 
77  inline explicit Vector3( const int afCoordinate[3] )
78  {
79  x = (Real)afCoordinate[0];
80  y = (Real)afCoordinate[1];
81  z = (Real)afCoordinate[2];
82  }
83 
84  inline explicit Vector3( Real* const r )
85  : x( r[0] ), y( r[1] ), z( r[2] )
86  {
87  }
88 
89  inline explicit Vector3( const Real scaler )
90  : x( scaler )
91  , y( scaler )
92  , z( scaler )
93  {
94  }
95 
96 
99  inline void swap(Vector3& other)
100  {
101  std::swap(x, other.x);
102  std::swap(y, other.y);
103  std::swap(z, other.z);
104  }
105 
106  inline Real operator [] ( const size_t i ) const
107  {
108  assert( i < 3 );
109 
110  return *(&x+i);
111  }
112 
113  inline Real& operator [] ( const size_t i )
114  {
115  assert( i < 3 );
116 
117  return *(&x+i);
118  }
120  inline Real* ptr()
121  {
122  return &x;
123  }
125  inline const Real* ptr() const
126  {
127  return &x;
128  }
129 
134  inline Vector3& operator = ( const Vector3& rkVector )
135  {
136  x = rkVector.x;
137  y = rkVector.y;
138  z = rkVector.z;
139 
140  return *this;
141  }
142 
143  inline Vector3& operator = ( const Real fScaler )
144  {
145  x = fScaler;
146  y = fScaler;
147  z = fScaler;
148 
149  return *this;
150  }
151 
152  inline bool operator == ( const Vector3& rkVector ) const
153  {
154  return ( x == rkVector.x && y == rkVector.y && z == rkVector.z );
155  }
156 
157  inline bool operator != ( const Vector3& rkVector ) const
158  {
159  return ( x != rkVector.x || y != rkVector.y || z != rkVector.z );
160  }
161 
162  // arithmetic operations
163  inline Vector3 operator + ( const Vector3& rkVector ) const
164  {
165  return Vector3(
166  x + rkVector.x,
167  y + rkVector.y,
168  z + rkVector.z);
169  }
170 
171  inline Vector3 operator - ( const Vector3& rkVector ) const
172  {
173  return Vector3(
174  x - rkVector.x,
175  y - rkVector.y,
176  z - rkVector.z);
177  }
178 
179  inline Vector3 operator * ( const Real fScalar ) const
180  {
181  return Vector3(
182  x * fScalar,
183  y * fScalar,
184  z * fScalar);
185  }
186 
187  inline Vector3 operator * ( const Vector3& rhs) const
188  {
189  return Vector3(
190  x * rhs.x,
191  y * rhs.y,
192  z * rhs.z);
193  }
194 
195  inline Vector3 operator / ( const Real fScalar ) const
196  {
197  assert( fScalar != 0.0 );
198 
199  Real fInv = 1.0f / fScalar;
200 
201  return Vector3(
202  x * fInv,
203  y * fInv,
204  z * fInv);
205  }
206 
207  inline Vector3 operator / ( const Vector3& rhs) const
208  {
209  return Vector3(
210  x / rhs.x,
211  y / rhs.y,
212  z / rhs.z);
213  }
214 
215  inline const Vector3& operator + () const
216  {
217  return *this;
218  }
219 
220  inline Vector3 operator - () const
221  {
222  return Vector3(-x, -y, -z);
223  }
224 
225  // overloaded operators to help Vector3
226  inline friend Vector3 operator * ( const Real fScalar, const Vector3& rkVector )
227  {
228  return Vector3(
229  fScalar * rkVector.x,
230  fScalar * rkVector.y,
231  fScalar * rkVector.z);
232  }
233 
234  inline friend Vector3 operator / ( const Real fScalar, const Vector3& rkVector )
235  {
236  return Vector3(
237  fScalar / rkVector.x,
238  fScalar / rkVector.y,
239  fScalar / rkVector.z);
240  }
241 
242  inline friend Vector3 operator + (const Vector3& lhs, const Real rhs)
243  {
244  return Vector3(
245  lhs.x + rhs,
246  lhs.y + rhs,
247  lhs.z + rhs);
248  }
249 
250  inline friend Vector3 operator + (const Real lhs, const Vector3& rhs)
251  {
252  return Vector3(
253  lhs + rhs.x,
254  lhs + rhs.y,
255  lhs + rhs.z);
256  }
257 
258  inline friend Vector3 operator - (const Vector3& lhs, const Real rhs)
259  {
260  return Vector3(
261  lhs.x - rhs,
262  lhs.y - rhs,
263  lhs.z - rhs);
264  }
265 
266  inline friend Vector3 operator - (const Real lhs, const Vector3& rhs)
267  {
268  return Vector3(
269  lhs - rhs.x,
270  lhs - rhs.y,
271  lhs - rhs.z);
272  }
273 
274  // arithmetic updates
275  inline Vector3& operator += ( const Vector3& rkVector )
276  {
277  x += rkVector.x;
278  y += rkVector.y;
279  z += rkVector.z;
280 
281  return *this;
282  }
283 
284  inline Vector3& operator += ( const Real fScalar )
285  {
286  x += fScalar;
287  y += fScalar;
288  z += fScalar;
289  return *this;
290  }
291 
292  inline Vector3& operator -= ( const Vector3& rkVector )
293  {
294  x -= rkVector.x;
295  y -= rkVector.y;
296  z -= rkVector.z;
297 
298  return *this;
299  }
300 
301  inline Vector3& operator -= ( const Real fScalar )
302  {
303  x -= fScalar;
304  y -= fScalar;
305  z -= fScalar;
306  return *this;
307  }
308 
309  inline Vector3& operator *= ( const Real fScalar )
310  {
311  x *= fScalar;
312  y *= fScalar;
313  z *= fScalar;
314  return *this;
315  }
316 
317  inline Vector3& operator *= ( const Vector3& rkVector )
318  {
319  x *= rkVector.x;
320  y *= rkVector.y;
321  z *= rkVector.z;
322 
323  return *this;
324  }
325 
326  inline Vector3& operator /= ( const Real fScalar )
327  {
328  assert( fScalar != 0.0 );
329 
330  Real fInv = 1.0f / fScalar;
331 
332  x *= fInv;
333  y *= fInv;
334  z *= fInv;
335 
336  return *this;
337  }
338 
339  inline Vector3& operator /= ( const Vector3& rkVector )
340  {
341  x /= rkVector.x;
342  y /= rkVector.y;
343  z /= rkVector.z;
344 
345  return *this;
346  }
347 
348 
356  inline Real length () const
357  {
358  return Math::Sqrt( x * x + y * y + z * z );
359  }
360 
371  inline Real squaredLength () const
372  {
373  return x * x + y * y + z * z;
374  }
375 
383  inline Real distance(const Vector3& rhs) const
384  {
385  return (*this - rhs).length();
386  }
387 
398  inline Real squaredDistance(const Vector3& rhs) const
399  {
400  return (*this - rhs).squaredLength();
401  }
402 
417  inline Real dotProduct(const Vector3& vec) const
418  {
419  return x * vec.x + y * vec.y + z * vec.z;
420  }
421 
432  inline Real absDotProduct(const Vector3& vec) const
433  {
434  return Math::Abs(x * vec.x) + Math::Abs(y * vec.y) + Math::Abs(z * vec.z);
435  }
436 
446  inline Real normalise()
447  {
448  Real fLength = Math::Sqrt( x * x + y * y + z * z );
449 
450  // Will also work for zero-sized vectors, but will change nothing
451  // We're not using epsilons because we don't need to.
452  // Read http://www.ogre3d.org/forums/viewtopic.php?f=4&t=61259
453  if ( fLength > Real(0.0f) )
454  {
455  Real fInvLength = 1.0f / fLength;
456  x *= fInvLength;
457  y *= fInvLength;
458  z *= fInvLength;
459  }
460 
461  return fLength;
462  }
463 
492  inline Vector3 crossProduct( const Vector3& rkVector ) const
493  {
494  return Vector3(
495  y * rkVector.z - z * rkVector.y,
496  z * rkVector.x - x * rkVector.z,
497  x * rkVector.y - y * rkVector.x);
498  }
499 
503  inline Vector3 midPoint( const Vector3& vec ) const
504  {
505  return Vector3(
506  ( x + vec.x ) * 0.5f,
507  ( y + vec.y ) * 0.5f,
508  ( z + vec.z ) * 0.5f );
509  }
510 
514  inline bool operator < ( const Vector3& rhs ) const
515  {
516  if( x < rhs.x && y < rhs.y && z < rhs.z )
517  return true;
518  return false;
519  }
520 
524  inline bool operator > ( const Vector3& rhs ) const
525  {
526  if( x > rhs.x && y > rhs.y && z > rhs.z )
527  return true;
528  return false;
529  }
530 
538  inline void makeFloor( const Vector3& cmp )
539  {
540  if( cmp.x < x ) x = cmp.x;
541  if( cmp.y < y ) y = cmp.y;
542  if( cmp.z < z ) z = cmp.z;
543  }
544 
552  inline void makeCeil( const Vector3& cmp )
553  {
554  if( cmp.x > x ) x = cmp.x;
555  if( cmp.y > y ) y = cmp.y;
556  if( cmp.z > z ) z = cmp.z;
557  }
558 
566  inline Vector3 perpendicular(void) const
567  {
568  static const Real fSquareZero = (Real)(1e-06 * 1e-06);
569 
570  Vector3 perp = this->crossProduct( Vector3::UNIT_X );
571 
572  // Check length
573  if( perp.squaredLength() < fSquareZero )
574  {
575  /* This vector is the Y axis multiplied by a scalar, so we have
576  to use another axis.
577  */
578  perp = this->crossProduct( Vector3::UNIT_Y );
579  }
580  perp.normalise();
581 
582  return perp;
583  }
604  const Radian& angle,
605  const Vector3& up = Vector3::ZERO ) const
606  {
607  Vector3 newUp;
608 
609  if (up == Vector3::ZERO)
610  {
611  // Generate an up vector
612  newUp = this->perpendicular();
613  }
614  else
615  {
616  newUp = up;
617  }
618 
619  // Rotate up vector by random amount around this
620  Quaternion q;
622  newUp = q * newUp;
623 
624  // Finally rotate this by given angle around randomised up
625  q.FromAngleAxis( angle, newUp );
626  return q * (*this);
627  }
628 
633  inline Radian angleBetween(const Vector3& dest) const
634  {
635  Real lenProduct = length() * dest.length();
636 
637  // Divide by zero check
638  if(lenProduct < 1e-6f)
639  lenProduct = 1e-6f;
640 
641  Real f = dotProduct(dest) / lenProduct;
642 
643  f = Math::Clamp(f, (Real)-1.0, (Real)1.0);
644  return Math::ACos(f);
645 
646  }
656  const Vector3& fallbackAxis = Vector3::ZERO) const
657  {
658  // Based on Stan Melax's article in Game Programming Gems
659  Quaternion q;
660  // Copy, since cannot modify local
661  Vector3 v0 = *this;
662  Vector3 v1 = dest;
663  v0.normalise();
664  v1.normalise();
665 
666  Real d = v0.dotProduct(v1);
667  // If dot == 1, vectors are the same
668  if (d >= 1.0f)
669  {
670  return Quaternion::IDENTITY;
671  }
672  if (d < (1e-6f - 1.0f))
673  {
674  if (fallbackAxis != Vector3::ZERO)
675  {
676  // rotate 180 degrees about the fallback axis
677  q.FromAngleAxis(Radian(Math::PI), fallbackAxis);
678  }
679  else
680  {
681  // Generate an axis
682  Vector3 axis = Vector3::UNIT_X.crossProduct(*this);
683  if (axis.isZeroLength()) // pick another if colinear
684  axis = Vector3::UNIT_Y.crossProduct(*this);
685  axis.normalise();
686  q.FromAngleAxis(Radian(Math::PI), axis);
687  }
688  }
689  else
690  {
691  Real s = Math::Sqrt( (1+d)*2 );
692  Real invs = 1 / s;
693 
694  Vector3 c = v0.crossProduct(v1);
695 
696  q.x = c.x * invs;
697  q.y = c.y * invs;
698  q.z = c.z * invs;
699  q.w = s * 0.5f;
700  q.normalise();
701  }
702  return q;
703  }
704 
706  inline bool isZeroLength(void) const
707  {
708  Real sqlen = (x * x) + (y * y) + (z * z);
709  return (sqlen < (1e-06 * 1e-06));
710 
711  }
712 
715  inline Vector3 normalisedCopy(void) const
716  {
717  Vector3 ret = *this;
718  ret.normalise();
719  return ret;
720  }
721 
725  inline Vector3 reflect(const Vector3& normal) const
726  {
727  return Vector3( *this - ( 2 * this->dotProduct(normal) * normal ) );
728  }
729 
736  inline bool positionEquals(const Vector3& rhs, Real tolerance = 1e-03) const
737  {
738  return Math::RealEqual(x, rhs.x, tolerance) &&
739  Math::RealEqual(y, rhs.y, tolerance) &&
740  Math::RealEqual(z, rhs.z, tolerance);
741 
742  }
743 
750  inline bool positionCloses(const Vector3& rhs, Real tolerance = 1e-03f) const
751  {
752  return squaredDistance(rhs) <=
753  (squaredLength() + rhs.squaredLength()) * tolerance;
754  }
755 
763  inline bool directionEquals(const Vector3& rhs,
764  const Radian& tolerance) const
765  {
766  Real dot = dotProduct(rhs);
767  Radian angle = Math::ACos(dot);
768 
769  return Math::Abs(angle.valueRadians()) <= tolerance.valueRadians();
770 
771  }
772 
774  inline bool isNaN() const
775  {
776  return Math::isNaN(x) || Math::isNaN(y) || Math::isNaN(z);
777  }
778 
780  inline Vector3 primaryAxis() const
781  {
782  Real absx = Math::Abs(x);
783  Real absy = Math::Abs(y);
784  Real absz = Math::Abs(z);
785  if (absx > absy)
786  if (absx > absz)
787  return x > 0 ? Vector3::UNIT_X : Vector3::NEGATIVE_UNIT_X;
788  else
789  return z > 0 ? Vector3::UNIT_Z : Vector3::NEGATIVE_UNIT_Z;
790  else // absx <= absy
791  if (absy > absz)
792  return y > 0 ? Vector3::UNIT_Y : Vector3::NEGATIVE_UNIT_Y;
793  else
794  return z > 0 ? Vector3::UNIT_Z : Vector3::NEGATIVE_UNIT_Z;
795 
796 
797  }
798 
799  // special points
800  static const Vector3 ZERO;
801  static const Vector3 UNIT_X;
802  static const Vector3 UNIT_Y;
803  static const Vector3 UNIT_Z;
804  static const Vector3 NEGATIVE_UNIT_X;
805  static const Vector3 NEGATIVE_UNIT_Y;
806  static const Vector3 NEGATIVE_UNIT_Z;
807  static const Vector3 UNIT_SCALE;
808 
811  inline _OgreExport friend std::ostream& operator <<
812  ( std::ostream& o, const Vector3& v )
813  {
814  o << "Vector3(" << v.x << ", " << v.y << ", " << v.z << ")";
815  return o;
816  }
817  };
821 }
822 #endif
bool isNaN() const
Check whether this vector contains valid values.
Definition: OgreVector3.h:774
static const Vector3 NEGATIVE_UNIT_Y
Definition: OgreVector3.h:805
static const Vector3 NEGATIVE_UNIT_X
Definition: OgreVector3.h:804
static const Vector3 UNIT_Z
Definition: OgreVector3.h:803
Vector3(Real *const r)
Definition: OgreVector3.h:84
static Real UnitRandom()
Generate a random number of unit length.
const Real * ptr() const
Pointer accessor for direct copying.
Definition: OgreVector3.h:125
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:603
float Real
Software floating point type.
Vector3 perpendicular(void) const
Generates a vector perpendicular to this vector (eg an 'up' vector).
Definition: OgreVector3.h:566
#define _OgreExport
Definition: OgrePlatform.h:260
static T Clamp(T val, T minval, T maxval)
Clamp a value within an inclusive range.
Definition: OgreMath.h:690
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:398
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:736
static const Vector3 ZERO
Definition: OgreVector3.h:800
static const Real TWO_PI
Definition: OgreMath.h:707
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:655
Real length() const
Returns the length (magnitude) of the vector.
Definition: OgreVector3.h:356
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:538
Vector3(const Real scaler)
Definition: OgreVector3.h:89
Real dotProduct(const Vector3 &vec) const
Calculates the dot (scalar) product of this vector with another.
Definition: OgreVector3.h:417
Vector3()
Default constructor.
Definition: OgreVector3.h:61
static Radian ACos(Real fValue)
Arc cosine function.
Real * ptr()
Pointer accessor for direct copying.
Definition: OgreVector3.h:120
Radian operator*(Real a, const Radian &b)
Definition: OgreMath.h:747
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:752
Implementation of a Quaternion, i.e.
bool isZeroLength(void) const
Returns true if this vector is zero length.
Definition: OgreVector3.h:706
Vector3(const Real afCoordinate[3])
Definition: OgreVector3.h:70
static const Real PI
Definition: OgreMath.h:706
static const Quaternion IDENTITY
static const Vector3 NEGATIVE_UNIT_Z
Definition: OgreVector3.h:806
static Real Abs(Real fValue)
Absolute value function.
Definition: OgreMath.h:258
bool directionEquals(const Vector3 &rhs, const Radian &tolerance) const
Returns whether this vector is within a directional tolerance of another vector.
Definition: OgreVector3.h:763
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:750
Radian angleBetween(const Vector3 &dest) const
Gets the angle between 2 vectors.
Definition: OgreVector3.h:633
static Real Sqrt(Real fValue)
Square root function.
Definition: OgreMath.h:405
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:432
Real valueRadians() const
Definition: OgreMath.h:59
Real squaredLength() const
Returns the square of the length(magnitude) of the vector.
Definition: OgreVector3.h:371
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:51
Vector3 primaryAxis() const
Extract the primary (dominant) axis from this direction vector.
Definition: OgreVector3.h:780
Wrapper class which indicates a given angle value is in Radians.
Definition: OgreMath.h:47
static const Vector3 UNIT_X
Definition: OgreVector3.h:801
Real distance(const Vector3 &rhs) const
Returns the distance to another vector.
Definition: OgreVector3.h:383
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:552
Real normalise()
Normalises the vector.
Definition: OgreVector3.h:446
static const Vector3 UNIT_Y
Definition: OgreVector3.h:802
Vector3 reflect(const Vector3 &normal) const
Calculates a reflection vector to the plane with the given normal .
Definition: OgreVector3.h:725
static bool isNaN(Real f)
Definition: OgreMath.h:305
Vector3(const Real fX, const Real fY, const Real fZ)
Definition: OgreVector3.h:65
Vector3 crossProduct(const Vector3 &rkVector) const
Calculates the cross-product of 2 vectors, i.e.
Definition: OgreVector3.h:492
void swap(Vector3 &other)
Exchange the contents of this vector with another.
Definition: OgreVector3.h:99
Vector3(const int afCoordinate[3])
Definition: OgreVector3.h:77
Real normalise(void)
Normalises this quaternion, and returns the previous length.
static const Vector3 UNIT_SCALE
Definition: OgreVector3.h:807
Vector3 normalisedCopy(void) const
As normalise, except that this vector is unaffected and the normalised vector is returned as a copy...
Definition: OgreVector3.h:715
Vector3 midPoint(const Vector3 &vec) const
Returns a vector at a point half way between this and the passed in vector.
Definition: OgreVector3.h:503
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++)