MezzanineEngine 
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
vector3.cpp
1 // © Copyright 2010 - 2014 BlackTopp Studios Inc.
2 /* This file is part of The Mezzanine Engine.
3 
4  The Mezzanine Engine is free software: you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation, either version 3 of the License, or
7  (at your option) any later version.
8 
9  The Mezzanine Engine is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with The Mezzanine Engine. If not, see <http://www.gnu.org/licenses/>.
16 */
17 /* The original authors have included a copy of the license specified above in the
18  'Docs' folder. See 'gpl.txt'
19 */
20 /* We welcome the use of the Mezzanine engine to anyone, including companies who wish to
21  Build professional software and charge for their product.
22 
23  However there are some practical restrictions, so if your project involves
24  any of the following you should contact us and we will try to work something
25  out:
26  - DRM or Copy Protection of any kind(except Copyrights)
27  - Software Patents You Do Not Wish to Freely License
28  - Any Kind of Linking to Non-GPL licensed Works
29  - Are Currently In Violation of Another Copyright Holder's GPL License
30  - If You want to change our code and not add a few hundred MB of stuff to
31  your distribution
32 
33  These and other limitations could cause serious legal problems if you ignore
34  them, so it is best to simply contact us or the Free Software Foundation, if
35  you have any questions.
36 
37  Joseph Toppi - toppij@gmail.com
38  John Blackwood - makoenergy02@gmail.com
39 */
40 #ifndef _vector3_cpp
41 #define _vector3_cpp
42 
43 #include "vector3.h"
44 #include "quaternion.h"
45 #include "exception.h"
46 #include "serialization.h"
47 #include "stringtool.h"
48 #include "mathtool.h"
49 #ifndef SWIG
50  #include "XML/xml.h"
51 #endif
52 #include "XML/xml.h" // Needed for streaming to xml
53 
54 #include <Ogre.h>
55 #include "btBulletDynamicsCommon.h"
56 
57 #include <memory>
58 
59 //remove this
60 #include <iostream>
61 
62 namespace Mezzanine
63 {
64 
65  //remove this too
66  void PrintHello() // Function to call from Lua
67  {
68  std::cout << "Hello world! From PrintHello()" << std::endl;
69  }
70 
71  ///////////////////////////////////////////////////////////////////////////////
72  // The Essentials
73 
75  {
76  switch(Axis)
77  {
78  case 0: return this->X;
79  case 1: return this->Y;
80  case 2: return this->Z;
81  default: { MEZZ_EXCEPTION(Exception::PARAMETERS_EXCEPTION,"Cannot retrieve invalid StandardAxis."); }
82  }
83  }
84 
85  Real Vector3::GetAxisValue(const Whole& Axis) const
86  { return this->GetAxisValue((StandardAxis)Axis); }
87 
89  {
90  switch(Axis)
91  {
92  case 0: return this->X;
93  case 1: return this->Y;
94  case 2: return this->Z;
95  default: { MEZZ_EXCEPTION(Exception::PARAMETERS_EXCEPTION,"Cannot retrieve invalid StandardAxis."); }
96  }
97  }
98 
100  { return this->GetAxisValue((StandardAxis)Axis); }
101 
103  { return this->GetAxisValue(Axis); }
104 
105  Real Vector3::operator[] (const Whole& Axis) const
106  { return this->GetAxisValue((StandardAxis)Axis); }
107 
109  { return this->GetAxisValue(Axis); }
110 
112  { return this->GetAxisValue((StandardAxis)Axis); }
113 
114  ///////////////////////////////////////////////////////////////////////////////
115  // Constructors
116 
118  { this->Zero(); }
119 
120  Vector3::Vector3(const Real& x, const Real& y, const Real& z)
121  { this->SetValues(x,y,z); }
122 
123  Vector3::Vector3(const Ogre::Vector3& Vec)
124  { this->ExtractOgreVector3(Vec); }
125 
126  Vector3::Vector3(const btVector3& Vec)
127  { this->ExtractBulletVector3(Vec); }
128 
130  { *this = Vec; }
131 
133  { this->ProtoDeSerialize(OneNode); }
134 
135  ///////////////////////////////////////////////////////////////////////////////
136  // Prebuilt Vectors
137 
139  { return Vector3(1,0,0); }
140 
142  { return Vector3(0,1,0);}
143 
145  { return Vector3(0,0,1); }
146 
148  { return Vector3(-1,0,0); }
149 
151  { return Vector3(0,-1,0); }
152 
154  { return Vector3(0,0,-1); }
155 
157  {
158  switch(Axis)
159  {
160  case 0: return Vector3::Unit_X();
161  case 1: return Vector3::Unit_Y();
162  case 2: return Vector3::Unit_Z();
163  default: { MEZZ_EXCEPTION(Exception::PARAMETERS_EXCEPTION,"Cannot convert invalid StandardAxis."); }
164  }
165  }
166 
168  {
169  if (1.0==this->X && 0.0==this->Y && 0.0==this->Z)
170  {
171  return Axis_X;
172  } else if (0.0==this->X) { // Not Unit_X
173  if (1.0==this->Y && 0.0==this->Z)
174  {
175  return Axis_Y;
176  } else if (0.0==this->Y && 1.0==this->Z) { // Not Unit_Y so hopefully it is Z
177  return Axis_Z;
178  }
179  }
180  return Axis_Invalid;
181  //MEZZ_EXCEPTION(Exception::INVALID_STATE_EXCEPTION,"Cannot convert Vector3 to StandardAxis, Vector3 may not be Axis Aligned or may not be Unit Length.");
182  }
183 
184 
185  ///////////////////////////////////////////////////////////////////////////////
186  // Assignment Operators
187 
188  Vector3& Vector3::operator= (const btVector3 &Vec)
189  {
190  this->X=Vec.getX();
191  this->Y=Vec.getY();
192  this->Z=Vec.getZ();
193  return *this;
194  }
195 
196  Vector3& Vector3::operator= (const Ogre::Vector3 &Vec)
197  {
198  this->X=Vec.x;
199  this->Y=Vec.y;
200  this->Z=Vec.z;
201  return *this;
202  }
203 
204  ///////////////////////////////////////////////////////////////////////////////
205  // Unary Operators
206 
208  { return Vector3(-X,-Y,-Z); }
209 
210  ///////////////////////////////////////////////////////////////////////////////
211  // Vector3 Arithmetic with Real
212 
213  Vector3 Vector3::operator* (const Real &scalar) const
214  { return Vector3(this->X * scalar, this->Y * scalar, this->Z * scalar); }
215 
216  Vector3 Vector3::operator/ (const Real &scalar) const
217  { return Vector3(this->X / scalar, this->Y / scalar, this->Z / scalar); }
218 
219  ///////////////////////////////////////////////////////////////////////////////
220  // Vector3 Arithmetic and assignment with Real
221 
223  {
224  this->X *= scalar;
225  this->Y *= scalar;
226  this->Z *= scalar;
227  return *this;
228  }
229 
231  {
232  this->X /= scalar;
233  this->Y /= scalar;
234  this->Z /= scalar;
235  return *this;
236  }
237 
238  ///////////////////////////////////////////////////////////////////////////////
239  // Equality Comparison operators
240 
241  bool Vector3::operator== (const Vector3 &Vec) const
242  { return( Vec.X == this->X && Vec.Y == this->Y && Vec.Z == this->Z ); }
243 
244  bool Vector3::operator== (const btVector3 &Vec) const
245  { return( Vec.getX() == this->X && Vec.getY() == this->Y && Vec.getZ() == this->Z ); }
246 
247  bool Vector3::operator== (const Ogre::Vector3 &Vec) const
248  { return ( Vec.x == this->X && Vec.y == this->Y && Vec.z == this->Z ); }
249 
250 
251  bool Vector3::operator!= (const Vector3 &Vec) const
252  { return ( Vec.X != this->X || Vec.Y != this->Y || Vec.Z != this->Z ); }
253 
254  bool Vector3::operator!= (const btVector3 &Vec) const
255  { return ( Vec.getX() != this->X || Vec.getY() != this->Y || Vec.getZ() != this->Z ); }
256 
257  bool Vector3::operator!= (const Ogre::Vector3 &Vec) const
258  { return ( Vec.x != this->X || Vec.y != this->Y || Vec.z != this->Z ); }
259 
261  { return ( this->X <= Vec.X && this->Y <= Vec.Y && this->Z <= Vec.Z); }
263  { return ( this->X >= Vec.X && this->Y >= Vec.Y && this->Z >= Vec.Z); }
264 
265  ///////////////////////////////////////////////////////////////////////////////
266  // Arithmetic Operators
267 
269  { return Vector3(X+Vec.X, Y+Vec.Y, Z+Vec.Z ); }
270 
272  { return Vector3(X-Vec.X, Y-Vec.Y, Z-Vec.Z ); }
273 
275  { return Vector3(X*Vec.X, Y*Vec.Y, Z*Vec.Z ); }
276 
278  { return Vector3(X/Vec.X, Y/Vec.Y, Z/Vec.Z ); }
279 
280  ///////////////////////////////////////////////////////////////////////////////
281  // Arithmetic Operators with btVector3
282 
283  Vector3 Vector3::operator+ (const btVector3 &Vec) const
284  { return Vector3(X+Vec.getX(), Y+Vec.getY(), Z+Vec.getZ()); }
285 
286  Vector3 Vector3::operator- (const btVector3 &Vec) const
287  { return Vector3(X-Vec.getX(), Y-Vec.getY(), Z-Vec.getZ()); }
288 
289  Vector3 Vector3::operator* (const btVector3 &Vec) const
290  { return Vector3(X*Vec.getX(), Y*Vec.getY(), Z*Vec.getZ()); }
291 
292  Vector3 Vector3::operator/ (const btVector3 &Vec) const
293  { return Vector3(X/Vec.getX(), Y/Vec.getY(), Z/Vec.getZ()); }
294 
295  ///////////////////////////////////////////////////////////////////////////////
296  // Arithmetic Operators with Ogre::Vector3
297 
298  Vector3 Vector3::operator+ (const Ogre::Vector3 &Vec) const
299  { return Vector3(X+Vec.x, Y+Vec.y, Z+Vec.z); }
300 
301  Vector3 Vector3::operator- (const Ogre::Vector3 &Vec) const
302  { return Vector3(X-Vec.x, Y-Vec.y, Z-Vec.z); }
303 
304  Vector3 Vector3::operator* (const Ogre::Vector3 &Vec) const
305  { return Vector3(X*Vec.x, Y*Vec.y, Z*Vec.z); }
306 
307  Vector3 Vector3::operator/ (const Ogre::Vector3 &Vec) const
308  { return Vector3(X/Vec.x, Y/Vec.y, Z/Vec.z); }
309 
310  ///////////////////////////////////////////////////////////////////////////////
311  // Fancy Math
312 
314  {
315  return Vector3( // 1,2,3 . 4,5,6
316  this->Y * Vec.Z - this->Z * Vec.Y, // 2*6-3*5 = -3
317  this->Z * Vec.X - this->X * Vec.Z, // 3*4-1*6 = 6
318  this->X * Vec.Y - this->Y * Vec.X // 1*5-2*4 = -3
319  );
320  }
321 
322  Real Vector3::DotProduct(const Vector3& Vec) const
323  {
324  return this->X * Vec.X + this->Y * Vec.Y + this->Z * Vec.Z;
325  }
326 
328  {
329  Real TempLength = this->Distance(Vector3(0.0f,0.0f,0.0f));
330  if (0!=TempLength)
331  {
332  (*this) /= TempLength;
333  }else{
334  MEZZ_EXCEPTION(Exception::ARITHMETIC_EXCEPTION,"Cannot Normalize Vector3(0,0,0).");
335  }
336  return *this;
337  }
338 
340  {
341  Real TempLength = this->Distance(Vector3(0.0f,0.0f,0.0f));
342  if (0!=TempLength)
343  {
344  return (*this) / TempLength;
345  }else{
346  MEZZ_EXCEPTION(Exception::ARITHMETIC_EXCEPTION,"Cannot Get the Normal of Vector3(0,0,0).");
347  }
348  }
349 
350  Vector3 Vector3::GetDirection(const Vector3& Destination) const
351  {
352  return (Destination - *this).Normalize();
353  }
354 
356  {
357  if (X!=0)
358  X=1/X;
359  if (Y!=0)
360  Y=1/Y;
361  if (Z!=0)
362  Z=1/Z;
363  return *this;
364  }
365 
367  {
368  return Vector3( *this - ( Normal * (2 * this->DotProduct(Normal) ) ) );
369  }
370 
371  Real Vector3::Distance(const Vector3& OtherVec) const
372  {
373  return (*this - OtherVec).Length();
374  }
375 
376  Real Vector3::SquaredDistance(const Vector3& OtherVec) const
377  {
378  return (*this - OtherVec).SquaredLength();
379  }
380 
382  {
383  return MathTools::Sqrt(X * X + Y * Y + Z * Z);
384  }
385 
387  {
388  return (X * X + Y * Y + Z * Z);
389  }
390 
392  {
393  return SquaredLength() < (1e-06 * 1e-06);
394  }
395 
396  Quaternion Vector3::GetRotationToAxis(const Vector3& Axis, const Vector3& FallBackAxis) const
397  {
398  Quaternion Ret;
399  Vector3 Vec1 = *this;
400  Vector3 Vec2 = Axis;
401  Vec1.Normalize();
402  Vec2.Normalize();
403 
404  Real Dot = Vec1.DotProduct(Vec2);
405  if( Dot >= 1.0 )
406  {
407  return Ret;
408  }
409  if( Dot < (1e-6 - 1.0) )
410  {
411  if( FallBackAxis != Vector3() )
412  {
413  Ret.SetFromAxisAngle(MathTools::GetPi(),FallBackAxis);
414  }else{
415  Vector3 CrossAxis = Vector3::Unit_X().CrossProduct(*this);
416  if(CrossAxis.IsZeroLength())
417  CrossAxis = Vector3::Unit_Y().CrossProduct(*this);
418  CrossAxis.Normalize();
419  Ret.SetFromAxisAngle(MathTools::GetPi(),CrossAxis);
420  }
421  }else{
422  Real Sqr = MathTools::Sqrt( (1+Dot)*2 );
423  Real InvSqr = 1 / Sqr;
424 
425  Vector3 Cross = Vec1.CrossProduct(Vec2);
426 
427  Ret.X = Cross.X * InvSqr;
428  Ret.Y = Cross.Y * InvSqr;
429  Ret.Z = Cross.Z * InvSqr;
430  Ret.W = Sqr * 0.5f;
431  Ret.Normalize();
432  }
433  return Ret;
434  }
435 
436  ///////////////////////////////////////////////////////////////////////////////
437  // Utility Functions
438 
440  {
441  this->X = 0;
442  this->Y = 0;
443  this->Z = 0;
444  }
445 
446  void Vector3::SetValues(const Real& X, const Real& Y, const Real& Z)
447  {
448  this->X = X;
449  this->Y = Y;
450  this->Z = Z;
451  }
452 
454  {
455  if( Other.X > this->X ) this->X = Other.X;
456  if( Other.Y > this->Y ) this->Y = Other.Y;
457  if( Other.Z > this->Z ) this->Z = Other.Z;
458  return *this;
459  }
460 
462  {
463  if( Other.X < this->X ) this->X = Other.X;
464  if( Other.Y < this->Y ) this->Y = Other.Y;
465  if( Other.Z < this->Z ) this->Z = Other.Z;
466  return *this;
467  }
468 
469  ///////////////////////////////////////////////////////////////////////////////
470  // Manual Conversions
471 
472  btVector3 Vector3::GetBulletVector3() const
473  {
474  btVector3 Theirs;
475  Theirs.setX(this->X);
476  Theirs.setY(this->Y);
477  Theirs.setZ(this->Z);
478  Theirs.setW(0);
479  return Theirs;
480  }
481 
482  void Vector3::ExtractBulletVector3(const btVector3& Ours)
483  {
484  this->X=Ours.getX();
485  this->Y=Ours.getY();
486  this->Z=Ours.getZ();
487  }
488 
489  Ogre::Vector3 Vector3::GetOgreVector3() const
490  {
491  Ogre::Vector3 Theirs;
492  Theirs.x=this->X;
493  Theirs.y=this->Y;
494  Theirs.z=this->Z;
495  return Theirs;
496  }
497 
498  void Vector3::ExtractOgreVector3(const Ogre::Vector3& Ours)
499  {
500  this->X=Ours.x;
501  this->Y=Ours.y;
502  this->Z=Ours.z;
503  }
504 
505  void Vector3::ProtoSerialize(XML::Node& CurrentRoot) const
506  {
507  Mezzanine::XML::Node VecNode = CurrentRoot.AppendChild(SerializableName());
508  VecNode.SetName(SerializableName());
509 
510  Mezzanine::XML::Attribute VersionAttr = VecNode.AppendAttribute("Version");
511  Mezzanine::XML::Attribute XAttr = VecNode.AppendAttribute("X");
512  Mezzanine::XML::Attribute YAttr = VecNode.AppendAttribute("Y");
513  Mezzanine::XML::Attribute ZAttr = VecNode.AppendAttribute("Z");
514  if( VersionAttr && XAttr && YAttr && ZAttr )
515  {
516  if( VersionAttr.SetValue("1") && XAttr.SetValue(this->X) && YAttr.SetValue(this->Y) && ZAttr.SetValue(this->Z))
517  {
518  return;
519  }else{
520  SerializeError("Create XML Attribute Values", SerializableName(),true);
521  }
522  }else{
523  SerializeError("Create XML Attributes", SerializableName(),true);
524  }
525  }
526 
528  {
530  {
531  if(OneNode.GetAttribute("Version").AsInt() == 1)
532  {
533  this->X=OneNode.GetAttribute("X").AsReal();
534  this->Y=OneNode.GetAttribute("Y").AsReal();
535  this->Z=OneNode.GetAttribute("Z").AsReal();
536  }else{
537  MEZZ_EXCEPTION(Exception::INVALID_VERSION_EXCEPTION,"Incompatible XML Version for " + SerializableName() + ": Not Version 1.");
538  }
539  }else{
540  MEZZ_EXCEPTION(Exception::II_IDENTITY_INVALID_EXCEPTION,"Attempting to deserialize a " + SerializableName() + ", found a " + String(OneNode.Name()) + ".");
541  }
542  }
543 
545  { return String("Vector3"); }
546 }
547 
548 Mezzanine::Vector3 operator+ (const btVector3 &Vec, const Mezzanine::Vector3& lhs)
549  { return lhs + Vec; }
550 Mezzanine::Vector3 operator- (const btVector3 &Vec, const Mezzanine::Vector3& lhs)
551  { return Mezzanine::Vector3(Vec.getX()-lhs.X, Vec.getY()-lhs.Y, Vec.getZ()-lhs.Z); }
552 Mezzanine::Vector3 operator* (const btVector3 &Vec, const Mezzanine::Vector3& lhs)
553  { return lhs * Vec; }
554 Mezzanine::Vector3 operator/ (const btVector3 &Vec, const Mezzanine::Vector3& lhs)
555  { return Mezzanine::Vector3(Vec.getX()/lhs.X, Vec.getY()/lhs.Y, Vec.getZ()/lhs.Z); }
556 
557 Mezzanine::Vector3 operator+ (const Ogre::Vector3 &Vec, const Mezzanine::Vector3& lhs)
558  { return lhs + Vec; }
559 Mezzanine::Vector3 operator- (const Ogre::Vector3 &Vec, const Mezzanine::Vector3& lhs)
560  { return Mezzanine::Vector3(Vec.x-lhs.X, Vec.y-lhs.Y, Vec.z-lhs.Z); }
561 Mezzanine::Vector3 operator* (const Ogre::Vector3 &Vec, const Mezzanine::Vector3& lhs)
562  { return lhs * Vec; }
563 Mezzanine::Vector3 operator/ (const Ogre::Vector3 &Vec, const Mezzanine::Vector3& lhs)
564  { return Mezzanine::Vector3(Vec.x/lhs.X, Vec.y/lhs.Y, Vec.z/lhs.Z); }
565 
566 ///////////////////////////////////////////////////////////////////////////////
567 // Class External << Operators for streaming or assignment
568 std::ostream& operator << (std::ostream& stream, const Mezzanine::Vector3& x)
569 {
570  //stream << "<Vector3 Version=\"1\" X=\"" << x.X << "\" Y=\"" << x.Y << "\" Z=\"" << x.Z << "\"/>";
571  Serialize(stream,x);
572  return stream;
573 }
574 
575 std::istream& operator >> (std::istream& stream, Mezzanine::Vector3& Vec)
576  { return DeSerialize(stream, Vec); }
577 
578 void operator >> (const Mezzanine::XML::Node& OneNode, Mezzanine::Vector3& Vec)
579  { Vec.ProtoDeSerialize(OneNode); }
580 
581 Ogre::Vector3& operator << (Ogre::Vector3& VecTo, const Mezzanine::Vector3& VecFrom)
582 {
583  VecTo = VecFrom.GetOgreVector3();
584  return VecTo;
585 }
586 
587 Ogre::Vector3& operator << (Ogre::Vector3& VecTo, const btVector3& VecFrom)
588 {
589  VecTo.x=VecFrom.getX();
590  VecTo.y=VecFrom.getY();
591  VecTo.z=VecFrom.getZ();
592  return VecTo;
593 }
594 
595 btVector3& operator << (btVector3& VecTo, const Ogre::Vector3& VecFrom)
596 {
597  VecTo.setX(VecFrom.x);
598  VecTo.setY(VecFrom.y);
599  VecTo.setZ(VecFrom.z);
600  VecTo.setW(0);
601  return VecTo;
602 }
603 
604 btVector3& operator << (btVector3& VecTo, const Mezzanine::Vector3& VecFrom)
605 {
606  VecTo=VecFrom.GetBulletVector3();
607  return VecTo;
608 }
609 
610 Mezzanine::Vector3& operator << (Mezzanine::Vector3& VecTo, const Ogre::Vector3& VecFrom)
611 {
612  VecTo=VecFrom;
613  return VecTo;
614 }
615 
616 Mezzanine::Vector3& operator << (Mezzanine::Vector3& VecTo, const btVector3& VecFrom)
617 {
618  VecTo=VecFrom;
619  return VecTo;
620 }
621 
622 #endif