voxelTerrain
 All Classes Functions Variables Typedefs Enumerations Pages
vector3.hpp
1 #ifndef BLUB_MATH_VECTOR3_HPP
2 #define BLUB_MATH_VECTOR3_HPP
3 
4 #include "blub/core/classVersion.hpp"
5 #include "blub/core/globals.hpp"
6 #include "blub/math/math.hpp"
7 #include "blub/math/predecl.hpp"
8 #include "blub/serialization/access.hpp"
9 #include "blub/serialization/nameValuePair.hpp"
10 #ifdef BLUB_USE_PHYSX
11 # include <foundation/PxVec3.h>
12 #endif
13 
14 #ifdef BLUB_USE_BULLET
15 class btVector3;
16 #endif
17 namespace Ogre
18 {
19  class Vector3;
20 }
21 
22 
23 namespace blub
24 {
25 
26 class vector3
27 {
28 public:
29  vector3()
30  : x(0.)
31  , y(0.)
32  , z(0.)
33  {
34  }
35 
36 #ifndef BLUB_NO_OGRE3D
37  vector3(const Ogre::Vector3 &vec);
38  operator Ogre::Vector3() const;
39 #endif
40 #ifdef BLUB_USE_PHYSX
41  vector3(const physx::PxVec3& other)
42  : x(other.x), y(other.y), z(other.z)
43  {}
44  operator physx::PxVec3() const
45  {return physx::PxVec3(x,y,z);}
46 #endif
47 #ifdef BLUB_USE_BULLET
48  vector3(const btVector3 &vec);
49  operator btVector3() const;
50 #endif
51 
52  vector3(const real fX, const real fY, const real fZ)
53  : x(fX)
54  , y(fY)
55  , z(fZ)
56  {
57  }
58 
59  vector3(const real& scaler)
60  : x(scaler)
61  , y(scaler)
62  , z(scaler)
63  {
64  }
65 
66  vector3(const vector3int32& cast);
67 
68  bool operator <= ( const vector3& rhs ) const
69  {
70  return x <= rhs.x && y <= rhs.y && z <= rhs.z;
71  }
72 
73  bool operator >= ( const vector3& rhs ) const
74  {
75  return x >= rhs.x && y >= rhs.y && z >= rhs.z;
76  }
77 
78  vector3 getFloor(void) const;
79  vector3 getAbs(void) const;
80 
81 
84  inline void swap(vector3& other)
85  {
86  std::swap(x, other.x);
87  std::swap(y, other.y);
88  std::swap(z, other.z);
89  }
90 
91  inline real operator [] ( const size_t i ) const
92  {
93  BASSERT( i < 3 );
94 
95  return *(&x+i);
96  }
97 
98  inline real& operator [] ( const size_t i )
99  {
100  BASSERT( i < 3 );
101 
102  return *(&x+i);
103  }
105  inline real* ptr()
106  {
107  return &x;
108  }
110  inline const real* ptr() const
111  {
112  return &x;
113  }
114 
129  inline vector3& operator = ( const real fScaler )
130  {
131  x = fScaler;
132  y = fScaler;
133  z = fScaler;
134 
135  return *this;
136  }
137 
138  inline bool operator == ( const vector3& rkVector ) const
139  {
140  return ( x == rkVector.x && y == rkVector.y && z == rkVector.z );
141  }
142 
143  inline bool operator != ( const vector3& rkVector ) const
144  {
145  return ( x != rkVector.x || y != rkVector.y || z != rkVector.z );
146  }
147 
148  // arithmetic operations
149  inline vector3 operator + ( const vector3& rkVector ) const
150  {
151  return vector3(
152  x + rkVector.x,
153  y + rkVector.y,
154  z + rkVector.z);
155  }
156 
157  inline vector3 operator - ( const vector3& rkVector ) const
158  {
159  return vector3(
160  x - rkVector.x,
161  y - rkVector.y,
162  z - rkVector.z);
163  }
164 
165  inline vector3 operator * ( const real fScalar ) const
166  {
167  return vector3(
168  x * fScalar,
169  y * fScalar,
170  z * fScalar);
171  }
172 
173  inline vector3 operator * ( const vector3& rhs) const
174  {
175  return vector3(
176  x * rhs.x,
177  y * rhs.y,
178  z * rhs.z);
179  }
180 
181  inline vector3 operator / ( const real fScalar ) const
182  {
183  BASSERT( fScalar != 0.0 );
184 
185  real fInv = 1.0f / fScalar;
186 
187  return vector3(
188  x * fInv,
189  y * fInv,
190  z * fInv);
191  }
192 
193  inline vector3 operator / ( const vector3& rhs) const
194  {
195  return vector3(
196  x / rhs.x,
197  y / rhs.y,
198  z / rhs.z);
199  }
200 
201  inline const vector3& operator + () const
202  {
203  return *this;
204  }
205 
206  inline vector3 operator - () const
207  {
208  return vector3(-x, -y, -z);
209  }
210 
211  // overloaded operators to help vector3
212  inline friend vector3 operator * ( const real fScalar, const vector3& rkVector )
213  {
214  return vector3(
215  fScalar * rkVector.x,
216  fScalar * rkVector.y,
217  fScalar * rkVector.z);
218  }
219 
220  inline friend vector3 operator / ( const real fScalar, const vector3& rkVector )
221  {
222  return vector3(
223  fScalar / rkVector.x,
224  fScalar / rkVector.y,
225  fScalar / rkVector.z);
226  }
227 
228  inline friend vector3 operator + (const vector3& lhs, const real rhs)
229  {
230  return vector3(
231  lhs.x + rhs,
232  lhs.y + rhs,
233  lhs.z + rhs);
234  }
235 
236  inline friend vector3 operator + (const real lhs, const vector3& rhs)
237  {
238  return vector3(
239  lhs + rhs.x,
240  lhs + rhs.y,
241  lhs + rhs.z);
242  }
243 
244  inline friend vector3 operator - (const vector3& lhs, const real rhs)
245  {
246  return vector3(
247  lhs.x - rhs,
248  lhs.y - rhs,
249  lhs.z - rhs);
250  }
251 
252  inline friend vector3 operator - (const real lhs, const vector3& rhs)
253  {
254  return vector3(
255  lhs - rhs.x,
256  lhs - rhs.y,
257  lhs - rhs.z);
258  }
259 
260  // arithmetic updates
261  inline vector3& operator += ( const vector3& rkVector )
262  {
263  x += rkVector.x;
264  y += rkVector.y;
265  z += rkVector.z;
266 
267  return *this;
268  }
269 
270  inline vector3& operator += ( const real fScalar )
271  {
272  x += fScalar;
273  y += fScalar;
274  z += fScalar;
275  return *this;
276  }
277 
278  inline vector3& operator -= ( const vector3& rkVector )
279  {
280  x -= rkVector.x;
281  y -= rkVector.y;
282  z -= rkVector.z;
283 
284  return *this;
285  }
286 
287  inline vector3& operator -= ( const real fScalar )
288  {
289  x -= fScalar;
290  y -= fScalar;
291  z -= fScalar;
292  return *this;
293  }
294 
295  inline vector3& operator *= ( const real fScalar )
296  {
297  x *= fScalar;
298  y *= fScalar;
299  z *= fScalar;
300  return *this;
301  }
302 
303  inline vector3& operator *= ( const vector3& rkVector )
304  {
305  x *= rkVector.x;
306  y *= rkVector.y;
307  z *= rkVector.z;
308 
309  return *this;
310  }
311 
312  inline vector3& operator /= ( const real fScalar )
313  {
314  BASSERT( fScalar != 0.0 );
315 
316  real fInv = 1.0f / fScalar;
317 
318  x *= fInv;
319  y *= fInv;
320  z *= fInv;
321 
322  return *this;
323  }
324 
325  inline vector3& operator /= ( const vector3& rkVector )
326  {
327  x /= rkVector.x;
328  y /= rkVector.y;
329  z /= rkVector.z;
330 
331  return *this;
332  }
333 
334 
342  inline real length () const
343  {
344  return math::sqrt( x * x + y * y + z * z );
345  }
346 
357  inline real squaredLength () const
358  {
359  return x * x + y * y + z * z;
360  }
361 
369  inline real distance(const vector3& rhs) const
370  {
371  return (*this - rhs).length();
372  }
373 
384  inline real squaredDistance(const vector3& rhs) const
385  {
386  return (*this - rhs).squaredLength();
387  }
388 
403  inline real dotProduct(const vector3& vec) const
404  {
405  return x * vec.x + y * vec.y + z * vec.z;
406  }
407 
418  inline real absDotProduct(const vector3& vec) const
419  {
420  return math::abs(x * vec.x) + math::abs(y * vec.y) + math::abs(z * vec.z);
421  }
422 
432  inline real normalise()
433  {
434  real fLength = math::sqrt( x * x + y * y + z * z );
435 
436  // Will also work for zero-sized vectors, but will change nothing
437  // We're not using epsilons because we don't need to.
438  // Read http://www.ogre3d.org/forums/viewtopic.php?f=4&t=61259
439  if ( fLength > real(0.0f) )
440  {
441  real fInvLength = 1.0f / fLength;
442  x *= fInvLength;
443  y *= fInvLength;
444  z *= fInvLength;
445  }
446 
447  return fLength;
448  }
449 
478  inline vector3 crossProduct( const vector3& rkVector ) const
479  {
480  return vector3(
481  y * rkVector.z - z * rkVector.y,
482  z * rkVector.x - x * rkVector.z,
483  x * rkVector.y - y * rkVector.x);
484  }
485 
489  inline vector3 midPoint( const vector3& vec ) const
490  {
491  return vector3(
492  ( x + vec.x ) * 0.5f,
493  ( y + vec.y ) * 0.5f,
494  ( z + vec.z ) * 0.5f );
495  }
496 
500  inline bool operator < ( const vector3& rhs ) const
501  {
502  if( x < rhs.x && y < rhs.y && z < rhs.z )
503  return true;
504  return false;
505  }
506 
510  inline bool operator > ( const vector3& rhs ) const
511  {
512  if( x > rhs.x && y > rhs.y && z > rhs.z )
513  return true;
514  return false;
515  }
516 
524  inline void makeFloor( const vector3& cmp )
525  {
526  if( cmp.x < x ) x = cmp.x;
527  if( cmp.y < y ) y = cmp.y;
528  if( cmp.z < z ) z = cmp.z;
529  }
530 
538  inline void makeCeil( 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 vector3 perpendicular(void) const
553  {
554  static const real fSquareZero = (real)(1e-06 * 1e-06);
555 
556  vector3 perp = this->crossProduct( vector3::UNIT_X );
557 
558  // Check length
559  if( perp.squaredLength() < fSquareZero )
560  {
561  /* This vector is the Y axis multiplied by a scalar, so we have
562  to use another axis.
563  */
564  perp = this->crossProduct( vector3::UNIT_Y );
565  }
566  perp.normalise();
567 
568  return perp;
569  }
570 
571 
576  inline real angleBetween(const vector3& dest) const
577  {
578  real lenProduct = length() * dest.length();
579 
580  // Divide by zero check
581  if(lenProduct < 1e-6f)
582  lenProduct = 1e-6f;
583 
584  real f = dotProduct(dest) / lenProduct;
585 
586  f = math::clamp(f, (real)-1.0, (real)1.0);
587  return math::acos(f);
588 
589  }
598  quaternion getRotationTo(const vector3& dest,
599  const vector3& fallbackAxis = vector3::ZERO) const;
600 
602  inline bool isZeroLength(void) const
603  {
604  real sqlen = (x * x) + (y * y) + (z * z);
605  return (sqlen < (1e-06 * 1e-06));
606 
607  }
608 
611  inline vector3 getNormalise() const
612  {
613  return normalisedCopy();
614  }
615 
618  inline vector3 normalisedCopy(void) const
619  {
620  vector3 ret = *this;
621  ret.normalise();
622  return ret;
623  }
624 
628  inline vector3 reflect(const vector3& normal) const
629  {
630  return vector3( *this - ( 2 * this->dotProduct(normal) * normal ) );
631  }
632 
639  inline bool positionCloses(const vector3& rhs, real tolerance = 1e-03f) const
640  {
641  return squaredDistance(rhs) <=
642  (squaredLength() + rhs.squaredLength()) * tolerance;
643  }
644 
646  inline vector3 primaryAxis() const
647  {
648  real absx = math::abs(x);
649  real absy = math::abs(y);
650  real absz = math::abs(z);
651  if (absx > absy)
652  if (absx > absz)
653  return x > 0 ? vector3::UNIT_X : vector3::NEGATIVE_UNIT_X;
654  else
655  return z > 0 ? vector3::UNIT_Z : vector3::NEGATIVE_UNIT_Z;
656  else // absx <= absy
657  if (absy > absz)
658  return y > 0 ? vector3::UNIT_Y : vector3::NEGATIVE_UNIT_Y;
659  else
660  return z > 0 ? vector3::UNIT_Z : vector3::NEGATIVE_UNIT_Z;
661 
662 
663  }
664 
665 public:
666  real x, y, z;
667 
668  static const vector3 ZERO;
669  static const vector3 UNIT_X;
670  static const vector3 UNIT_Y;
671  static const vector3 UNIT_Z;
672  static const vector3 NEGATIVE_UNIT_X;
673  static const vector3 NEGATIVE_UNIT_Y;
674  static const vector3 NEGATIVE_UNIT_Z;
675  static const vector3 UNIT_SCALE;
676 
677 private:
678  BLUB_SERIALIZATION_ACCESS
679 
680  template <class formatType>
681  void serialize(formatType & readWrite, const uint32& version)
682  {
683  (void)version;
684 
685  readWrite & BLUB_SERIALIZATION_NAMEVALUEPAIR(x);
686  readWrite & BLUB_SERIALIZATION_NAMEVALUEPAIR(y);
687  readWrite & BLUB_SERIALIZATION_NAMEVALUEPAIR(z);
688  }
689 };
690 
691 
692 std::ostream& operator<< (std::ostream& ostr, const vector3& toCast);
693 std::size_t hash_value(const vector3& value);
694 
695 
696 }
697 BLUB_CLASSVERSION(blub::vector3, 1)
698 
699 
700 #endif // BLUB_MATH_VECTOR3_HPP
real angleBetween(const vector3 &dest) const
Definition: vector3.hpp:576
vector3 normalisedCopy(void) const
Definition: vector3.hpp:618
real length() const
Definition: vector3.hpp:342
real squaredLength() const
Definition: vector3.hpp:357
vector3 primaryAxis() const
Extract the primary (dominant) axis from this direction vector.
Definition: vector3.hpp:646
Definition: quaternion.hpp:25
real squaredDistance(const vector3 &rhs) const
Definition: vector3.hpp:384
void makeCeil(const vector3 &cmp)
Definition: vector3.hpp:538
real absDotProduct(const vector3 &vec) const
Definition: vector3.hpp:418
real dotProduct(const vector3 &vec) const
Definition: vector3.hpp:403
bool operator>(const vector3 &rhs) const
Definition: vector3.hpp:510
real distance(const vector3 &rhs) const
Definition: vector3.hpp:369
bool positionCloses(const vector3 &rhs, real tolerance=1e-03f) const
Definition: vector3.hpp:639
quaternion getRotationTo(const vector3 &dest, const vector3 &fallbackAxis=vector3::ZERO) const
Definition: vector3.cpp:70
const real * ptr() const
Pointer accessor for direct copying.
Definition: vector3.hpp:110
void swap(vector3 &other)
Definition: vector3.hpp:84
real normalise()
Definition: vector3.hpp:432
void makeFloor(const vector3 &cmp)
Definition: vector3.hpp:524
vector3 reflect(const vector3 &normal) const
Definition: vector3.hpp:628
Definition: vector3.hpp:26
vector3 crossProduct(const vector3 &rkVector) const
Definition: vector3.hpp:478
vector3 perpendicular(void) const
Definition: vector3.hpp:552
real * ptr()
Pointer accessor for direct copying.
Definition: vector3.hpp:105
bool isZeroLength(void) const
Definition: vector3.hpp:602
vector3 midPoint(const vector3 &vec) const
Definition: vector3.hpp:489
vector3 getNormalise() const
Definition: vector3.hpp:611
Definition: deadlineTimer.hpp:10
Definition: axisAlignedBox.hpp:10
vector3 & operator=(const real fScaler)
Definition: vector3.hpp:129
bool operator<(const vector3 &rhs) const
Definition: vector3.hpp:500