OgreVector3.h
Go to the documentation of this file.
1/*
2-----------------------------------------------------------------------------
3This source file is part of OGRE
4 (Object-oriented Graphics Rendering Engine)
5For the latest info, see http://www.ogre3d.org/
6
7Copyright (c) 2000-2013 Torus Knot Software Ltd
8
9Permission is hereby granted, free of charge, to any person obtaining a copy
10of this software and associated documentation files (the "Software"), to deal
11in the Software without restriction, including without limitation the rights
12to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
13copies of the Software, and to permit persons to whom the Software is
14furnished to do so, subject to the following conditions:
15
16The above copyright notice and this permission notice shall be included in
17all copies or substantial portions of the Software.
18
19THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
23LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
24OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
25THE 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
35namespace 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
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 {
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
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)
788 else
790 else // absx <= absy
791 if (absy > absz)
793 else
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;
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
#define _OgreExport
Definition: OgrePlatform.h:257
static T Clamp(T val, T minval, T maxval)
Clamp a value within an inclusive range.
Definition: OgreMath.h:690
static Real UnitRandom()
Generate a random number of unit length.
static Radian ACos(Real fValue)
Arc cosine function.
static const Real TWO_PI
Definition: OgreMath.h:707
static bool RealEqual(Real a, Real b, Real tolerance=std::numeric_limits< Real >::epsilon())
Compare 2 reals, using tolerance for inaccuracies.
static bool isNaN(Real f)
Definition: OgreMath.h:305
static Real Sqrt(Real fValue)
Square root function.
Definition: OgreMath.h:405
static Real Abs(Real fValue)
Absolute value function.
Definition: OgreMath.h:258
static const Real PI
Definition: OgreMath.h:706
Implementation of a Quaternion, i.e.
static const Quaternion IDENTITY
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 normalise(void)
Normalises this quaternion, and returns the previous length.
Wrapper class which indicates a given angle value is in Radians.
Definition: OgreMath.h:48
Real valueRadians() const
Definition: OgreMath.h:59
Standard 3-dimensional vector.
Definition: OgreVector3.h:52
bool isNaN() const
Check whether this vector contains valid values.
Definition: OgreVector3.h:774
static const Vector3 UNIT_X
Definition: OgreVector3.h:801
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 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
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 midPoint(const Vector3 &vec) const
Returns a vector at a point half way between this and the passed in vector.
Definition: OgreVector3.h:503
Real squaredLength() const
Returns the square of the length(magnitude) of the vector.
Definition: OgreVector3.h:371
Vector3 primaryAxis() const
Extract the primary (dominant) axis from this direction vector.
Definition: OgreVector3.h:780
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
static const Vector3 NEGATIVE_UNIT_X
Definition: OgreVector3.h:804
Real distance(const Vector3 &rhs) const
Returns the distance to another vector.
Definition: OgreVector3.h:383
Real absDotProduct(const Vector3 &vec) const
Calculates the absolute dot (scalar) product of this vector with another.
Definition: OgreVector3.h:432
static const Vector3 ZERO
Definition: OgreVector3.h:800
Vector3 perpendicular(void) const
Generates a vector perpendicular to this vector (eg an 'up' vector).
Definition: OgreVector3.h:566
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
Vector3(const Real fX, const Real fY, const Real fZ)
Definition: OgreVector3.h:65
static const Vector3 UNIT_SCALE
Definition: OgreVector3.h:807
static const Vector3 NEGATIVE_UNIT_Y
Definition: OgreVector3.h:805
Vector3(Real *const r)
Definition: OgreVector3.h:84
bool isZeroLength(void) const
Returns true if this vector is zero length.
Definition: OgreVector3.h:706
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
Real length() const
Returns the length (magnitude) of the vector.
Definition: OgreVector3.h:356
Vector3(const Real scaler)
Definition: OgreVector3.h:89
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
static const Vector3 UNIT_Y
Definition: OgreVector3.h:802
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 normalise()
Normalises the vector.
Definition: OgreVector3.h:446
Radian angleBetween(const Vector3 &dest) const
Gets the angle between 2 vectors.
Definition: OgreVector3.h:633
const Real * ptr() const
Pointer accessor for direct copying.
Definition: OgreVector3.h:125
Vector3 reflect(const Vector3 &normal) const
Calculates a reflection vector to the plane with the given normal .
Definition: OgreVector3.h:725
Vector3()
Default constructor.
Definition: OgreVector3.h:61
static const Vector3 NEGATIVE_UNIT_Z
Definition: OgreVector3.h:806
Vector3(const int afCoordinate[3])
Definition: OgreVector3.h:77
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
Real * ptr()
Pointer accessor for direct copying.
Definition: OgreVector3.h:120
static const Vector3 UNIT_Z
Definition: OgreVector3.h:803
Real dotProduct(const Vector3 &vec) const
Calculates the dot (scalar) product of this vector with another.
Definition: OgreVector3.h:417
Real squaredDistance(const Vector3 &rhs) const
Returns the square of the distance to another vector.
Definition: OgreVector3.h:398
Vector3(const Real afCoordinate[3])
Definition: OgreVector3.h:70
bool operator<(SharedPtr< T > const &a, SharedPtr< U > const &b)
Radian operator*(Real a, const Radian &b)
Definition: OgreMath.h:747
Radian operator/(Real a, const Radian &b)
Definition: OgreMath.h:752
bool operator!=(STLAllocator< T, P > const &, STLAllocator< T2, P > const &)
determine equality, can memory from another allocator be released by this allocator,...
bool operator==(STLAllocator< T, P > const &, STLAllocator< T2, P > const &)
determine equality, can memory from another allocator be released by this allocator,...
float Real
Software floating point type.
void swap(Ogre::SmallVectorImpl< T > &LHS, Ogre::SmallVectorImpl< T > &RHS)
Implement std::swap in terms of SmallVector swap.

Copyright © 2012 Torus Knot Software Ltd
Creative Commons License
This work is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.