From 0ea5fc66924303d1bf73ba283a383e2aadee02f2 Mon Sep 17 00:00:00 2001 From: neodarz Date: Sat, 11 Aug 2018 20:21:34 +0200 Subject: Initial commit --- docs/doxygen/nel/quat_8h-source.html | 555 +++++++++++++++++++++++++++++++++++ 1 file changed, 555 insertions(+) create mode 100644 docs/doxygen/nel/quat_8h-source.html (limited to 'docs/doxygen/nel/quat_8h-source.html') diff --git a/docs/doxygen/nel/quat_8h-source.html b/docs/doxygen/nel/quat_8h-source.html new file mode 100644 index 00000000..e2b530e8 --- /dev/null +++ b/docs/doxygen/nel/quat_8h-source.html @@ -0,0 +1,555 @@ + + + + nevrax.org : docs + + + + + + + + + + + + + + +
# Home   # nevrax.com   
+ + + + +
Nevrax
+ + + + + + + + + + +
+ + +
+ Nevrax.org
+ + + + + + + +
#News
#Mailing-list
#Documentation
#CVS
#Bugs
#License
+
+ + +
+ + +
+Docs + +
+  + + + + + +
Documentation 
+ +
+Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages   Search  
+

quat.h

Go to the documentation of this file.
00001 
+00007 /* Copyright, 2000 Nevrax Ltd.
+00008  *
+00009  * This file is part of NEVRAX NEL.
+00010  * NEVRAX NEL is free software; you can redistribute it and/or modify
+00011  * it under the terms of the GNU General Public License as published by
+00012  * the Free Software Foundation; either version 2, or (at your option)
+00013  * any later version.
+00014 
+00015  * NEVRAX NEL is distributed in the hope that it will be useful, but
+00016  * WITHOUT ANY WARRANTY; without even the implied warranty of
+00017  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+00018  * General Public License for more details.
+00019 
+00020  * You should have received a copy of the GNU General Public License
+00021  * along with NEVRAX NEL; see the file COPYING. If not, write to the
+00022  * Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+00023  * MA 02111-1307, USA.
+00024  */
+00025 
+00026 #ifndef NL_QUAT_H 
+00027 #define NL_QUAT_H 
+00028 
+00029 #include "nel/misc/types_nl.h"
+00030 #include "nel/misc/vector.h"
+00031 #include "nel/misc/stream.h"
+00032 #include <math.h>
+00033 
+00034 namespace       NLMISC
+00035 {
+00036 
+00037 
+00038 // ***************************************************************************
+00039 const   double  QuatEpsilon= 0.000001;
+00040 
+00041 
+00042 
+00043 // ***************************************************************************
+00050 struct  CAngleAxis
+00051 {
+00052         CVector         Axis;           
+00053         float           Angle;          
+00054 
+00055         CAngleAxis() {}
+00056         CAngleAxis(CVector axis, float ang) : Axis(axis), Angle(ang) {}
+00057 
+00059         void    serial(IStream &f)
+00060         {
+00061                 f.serial(Axis);
+00062                 f.serial(Angle);
+00063         }
+00064 };
+00065 
+00066 
+00067 // ***************************************************************************
+00074 template <class T> class CQuatT
+00075 {
+00076 public:
+00077         T x,y,z,w;
+00078 
+00079 
+00080 public:
+00081 
+00083         // @{
+00084         CQuatT() : x((T)0.0),y((T)0.0),z((T)0.0),w((T)1.0) {}
+00085         CQuatT(T X, T Y, T Z, T W) : x(X), y(Y), z(Z), w(W) {}
+00087         CQuatT(const CVector &axis, float angle) {setAngleAxis(axis, angle);}
+00089         CQuatT(const CAngleAxis &aa) {setAngleAxis(aa);}
+00090         // @}
+00091 
+00092     
+00094         // @{
+00095         void    set(T X, T Y, T Z, T W)         {x= X; y= Y; z= Z; w= W;}
+00096         // @}
+00097 
+00099         // @{
+00100         bool    operator==(const CQuatT& a) const               {return (x==0 && y==0 && z==0 && w==1.0f);}
+00101         bool    equal(const CQuatT& a, float epsilon = 1E-6f) const;
+00102         void    identity()                                              {x = y = z = 0.0f ;     w = 1.0f; }
+00103         bool    isIdentity() const                              {return (x==0.0f && y==0.0f && z==0.0f && w==1.0f);}
+00104         // @}
+00105 
+00107         // @{
+00108         CQuatT& operator+=(const CQuatT&o)              {x+=o.x; y+=o.y; z+=o.z; w+=o.w; return *this;}
+00109         CQuatT& operator-=(const CQuatT&o)              {x-=o.x; y-=o.y; z-=o.z; w-=o.w; return *this;}
+00110         CQuatT& operator*=(T f)                                 {x*=f;y*=f;z*=f;w*=f; return *this;}
+00111         CQuatT& operator/=(T f)                                 {double oof= 1.0/f; x=(T)(x*oof); y=(T)(y*oof); z= (T)(z*oof); w=(T)(w*oof); return *this;}
+00112         CQuatT  operator+(const CQuatT&o) const {return CQuatT(x+o.x,y+o.y,z+o.z,w+o.w);}
+00113         CQuatT  operator-(const CQuatT&o) const {return CQuatT(x-o.x,y-o.y,z-o.z,w-o.w);}
+00114         CQuatT  operator*(T f) const                    {return CQuatT(x*f,y*f,z*f,w*f);}
+00115         CQuatT  operator/(T f) const                    {double oof= 1.0/f; return CQuatT(x*oof,y*oof,z*oof,w*oof);}
+00116         CQuatT  operator-() const                               {return(CQuatT(-x,-y,-z,-w)); }
+00117         CQuatT  operator+() const                               {return *this; }
+00119         T               sqrnorm() const                                 {return (x*x + y*y + z*z + w*w);}
+00121         T               norm() const                                    {return (T)sqrt(sqrnorm());}
+00123         void    normalize();
+00125         CQuatT  normed() const                                  {CQuatT ret= *this; ret.normalize(); return ret;}
+00126         // @}
+00127 
+00128 
+00130         // @{
+00132         CQuatT  operator*(const CQuatT&) const; 
+00133         CQuatT& operator*=(const CQuatT&);
+00135         void    invert();
+00137         CQuatT  inverted() const                                {CQuatT ret= *this; ret.invert(); return ret;}
+00139         CQuatT  conjugate() const                               {return CQuatT(-x, -y, -z, w);}
+00140         // @}
+00141 
+00142 
+00144         // @{
+00146         CVector getAxis() const {CVector ret((float)x,(float)y,(float)z); return ret.normed();}
+00148         float   getAngle() const {return (float)(2*acos(w/norm()));}
+00150         CAngleAxis      getAngleAxis() const {return CAngleAxis(getAxis(), getAngle());}
+00151 
+00153         void    setAngleAxis(const CVector &axis, float angle);
+00155         void    setAngleAxis(const CAngleAxis &angAxis) {setAngleAxis(angAxis.Axis, angAxis.Angle);}
+00156         // @}
+00157 
+00158 
+00160         // @{
+00162         CQuatT  log();
+00164         CQuatT  exp();
+00166         void    makeClosest(const CQuatT &o);
+00168         void    serial(IStream &f)
+00169         {
+00170                 f.serial(x,y,z,w);
+00171         }
+00172         // @}
+00173 
+00174 
+00175 public:
+00176 
+00178         // @{
+00180         static  T               dotProduct(const CQuatT<T> &q0, const CQuatT<T> &q1);
+00184         static  CQuatT  slerp(const CQuatT<T>& q0, const CQuatT<T>& q1, float t);
+00188         static  CQuatT  squad(const CQuatT<T>& q0, const CQuatT<T>& tgtQ0, const CQuatT<T>& tgtQ1, const CQuatT<T>& q1, float t);
+00191         static  CQuatT  squadrev(const CAngleAxis &rot, const CQuatT<T>& q0, const CQuatT<T>& tgtQ0, const CQuatT<T>& tgtQ1, const CQuatT<T>& q1, float t);
+00192 
+00194         static  CQuatT  lnDif(const CQuatT &q0, const CQuatT &q1);
+00195 
+00196         // @}
+00197 
+00198 
+00199 };
+00200 
+00201 
+00202 
+00203 // ***************************************************************************
+00204 
+00205 
+00207 // @{
+00208 
+00210 template <class T> 
+00211 inline  CQuatT<T>       operator*(T f, const CQuatT<T> &o) {return o*f;}
+00212 
+00213 // @}
+00214 
+00215 
+00216 
+00217 // ***************************************************************************
+00218 // ***************************************************************************
+00219 // Template implementation.
+00220 // ***************************************************************************
+00221 // ***************************************************************************
+00222 
+00223 
+00224 
+00225 // ***************************************************************************
+00226 template <class T> 
+00227 inline bool     CQuatT<T>::equal(const CQuatT<T>& a, float epsilon) const
+00228 {
+00229         if (fabs(x-a.x)<epsilon &&
+00230                 fabs(y-a.y)<epsilon &&
+00231                 fabs(z-a.z)<epsilon &&
+00232                 fabs(w-a.w)<epsilon )
+00233         {
+00234                 return true;
+00235         }
+00236         return false;
+00237 }
+00238 
+00239 
+00240 // ***************************************************************************
+00241 template <class T> 
+00242 inline CQuatT<T>        CQuatT<T>::operator*(const CQuatT<T>& o) const
+00243 {
+00244         // wres= ww´ - v·v´
+00245         // vres= wv´ + w´v + v^v´ ] 
+00246         return  CQuatT<T>(
+00247                                         (w*o.x) +(x*o.w) + (y*o.z)-(z*o.y),
+00248                                         (w*o.y) +(y*o.w) + (z*o.x)-(x*o.z),
+00249                                         (w*o.z) +(z*o.w) + (x*o.y)-(y*o.x),
+00250                                         (w*o.w)-(x*o.x)-(y*o.y)-(z*o.z) );
+00251 
+00252 }
+00253 
+00254 // ***************************************************************************
+00255 template <class T> 
+00256 inline CQuatT<T>&       CQuatT<T>::operator*=(const CQuatT<T>& o)
+00257 {
+00258         *this= *this * o;
+00259         return *this;
+00260 }
+00261 
+00262 
+00263 // ***************************************************************************
+00264 template <class T> 
+00265 inline void     CQuatT<T>::invert()
+00266 {
+00267         // Must invert the norm.
+00268         T       f= sqrnorm();
+00269         if(f!=0)
+00270         {
+00271                 *this/=f;
+00272         }
+00273 
+00274         *this= conjugate();
+00275 }
+00276 
+00277 
+00278 // ***************************************************************************
+00279 template <class T> 
+00280 inline void     CQuatT<T>::normalize()
+00281 {
+00282         T       f= norm();
+00283         if(f==0)
+00284                 identity();
+00285         else
+00286         {
+00287                 *this/=f;
+00288         }
+00289 }
+00290 
+00291 
+00292 // ***************************************************************************
+00293 template <class T> 
+00294 inline void     CQuatT<T>::setAngleAxis(const CVector &axis, float angle)
+00295 {
+00296         CVector         v= axis;
+00297         v.normalize();
+00298         double  ca= cos(angle/2);
+00299         double  sa= sin(angle/2);
+00300         x= (T)(v.x*sa);
+00301         y= (T)(v.y*sa);
+00302         z= (T)(v.z*sa);
+00303         w= (T)(ca);
+00304 }
+00305 
+00306 
+00307 // ***************************************************************************
+00308 template <class T> 
+00309 T       CQuatT<T>::dotProduct(const CQuatT<T> &q0, const CQuatT<T> &q1)
+00310 {
+00311         return q0.x*q1.x + q0.y*q1.y + q0.z*q1.z + q0.w*q1.w;
+00312 }
+00313 
+00314 
+00315 // ***************************************************************************
+00316 template <class T> 
+00317 CQuatT<T>       CQuatT<T>::slerp(const CQuatT<T>& q0, const CQuatT<T>& q1, float t)
+00318 {
+00319         // omega is the 4D angle between q0 and q1.
+00320         double  omega, cosom,sinom;
+00321         T       factq0= 1;
+00322         T       s0,s1;
+00323 
+00324         cosom = CQuatT<T>::dotProduct(q0, q1);
+00325 
+00326         // Make q0 and q1 on the same hemisphere.
+00327         /*if(cosom<0)
+00328         {
+00329                 cosom= -cosom;
+00330                 factq0= -1;
+00331         }*/
+00332         // ????
+00333 
+00334         if ( cosom < 1.0 - NLMISC::QuatEpsilon)
+00335         { 
+00336                 omega = acos(cosom);
+00337                 sinom = sin(omega);
+00338                 s0 = (T) (sin((1.0f - t)*omega) / sinom);
+00339                 s1 = (T) (sin(t*omega) / sinom);
+00340         }
+00341         else
+00342         {       // q0 and q1 are nearly the same => sinom nearly 0. We can't slerp.
+00343                 // just linear interpolate.
+00344                 s0 = (T)(1.0 - t);
+00345                 s1 = t;
+00346         }
+00347 
+00348         return  q0*(factq0*s0) + q1*s1;
+00349 
+00350 }
+00351 
+00352 
+00353 // ***************************************************************************
+00354 template <class T> 
+00355 CQuatT<T>       CQuatT<T>::squad(const CQuatT<T>& q0, const CQuatT<T>& tgtQ0, const CQuatT<T>& tgtQ1, const CQuatT<T>& q1, float t)
+00356 {
+00357         return CQuatT<T>::slerp(
+00358                 CQuatT<T>::slerp(q0, q1, t),
+00359                 CQuatT<T>::slerp(tgtQ0, tgtQ1, t),
+00360                 2.f*(1.f-t)*t);
+00361 }
+00362 
+00363 
+00364 // ***************************************************************************
+00365 template <class T> 
+00366 CQuatT<T>       CQuatT<T>::squadrev(const CAngleAxis &rot, const CQuatT<T>& q0, const CQuatT<T>& tgtQ0, const CQuatT<T>& tgtQ1, const CQuatT<T>& q1, float t)
+00367 {
+00368         float s,v;
+00369         float omega = rot.Angle* 0.5f;
+00370         float nrevs = 0.0f;
+00371         CQuatT<T>       ret,qaxis,pp,qq;
+00372 
+00373         // just one rev?
+00374         //==============
+00375         if (omega<Pi-QuatEpsilon)
+00376         {
+00377                 ret = CQuatT<T>::squad(q0,tgtQ0,tgtQ1,q1,t);
+00378                 return ret; 
+00379         }
+00380 
+00381 
+00382         // multirev.
+00383         //==============
+00384 
+00385         // rotation of 180° around rot.Axis.  (=> sin(a/2)==sin(Pi/2)==1, and c(a/2)=0).
+00386         qaxis.set(rot.Axis.x, rot.Axis.y, rot.Axis.z, 0);
+00387 
+00388         // the number of revisions (float!)
+00389         nrevs= (float)(omega/Pi);
+00390         // Angle>2Pi. squad from 0 to Pi, slerp from Pi to Angle-Pi, squad from Angle-Pi to Angle.
+00391         s = t*2*nrevs;
+00392         
+00393 
+00394         // So for s, squad from 0 to 1, slerp from 1 to 2*nrevs-1, squad from 2*nrevs-1 to 2*nrevs.
+00395         if (s < 1.0f)
+00396         {
+00397                 // first part.
+00398                 pp = q0*qaxis;
+00399                 ret = CQuatT<T>::squad(q0,tgtQ0,pp,pp,s);
+00400         }
+00401         else
+00402         {
+00403                 v = s - (2.0f*nrevs - 1.0f);
+00404                 if( v <= 0.0f)
+00405                 {
+00406                         // middle part
+00407                         while (s >= 2.0f) s -= 2.0f;
+00408                         pp = q0*qaxis;
+00409                         // s vary from 1 to 2. This is still correct for slerp().
+00410                         ret = CQuatT<T>::slerp(q0,pp,s);
+00411                 }
+00412                 else
+00413                 {
+00414                         // Last part.
+00415                         qq = - q1*qaxis;
+00416                         ret= CQuatT<T>::squad(qq,qq,tgtQ1,q1,v);
+00417                 }
+00418         }
+00419 
+00420         return ret;
+00421 }
+00422 
+00423 
+00424 
+00425 // ***************************************************************************
+00426 template <class T> 
+00427 CQuatT<T>       CQuatT<T>::log()
+00428 {
+00429         double  len;
+00430         len = sqrt (x*x + y*y + z*z);
+00431 
+00432         if (len < QuatEpsilon)
+00433                 return CQuatT<T>(0.f, 0.f, 0.f, 0.f);
+00434         else
+00435         {
+00436                 double div = (float) acos (w) / len;
+00437                 return CQuatT<T>( (T)(x*div), (T)(y*div), (T)(z*div), 0.f);
+00438         }
+00439 
+00440 }
+00441 
+00442 
+00443 // ***************************************************************************
+00444 template <class T> 
+00445 CQuatT<T>       CQuatT<T>::exp()
+00446 {
+00447         double  len;
+00448         len = sqrt (x*x + y*y + z*z);
+00449 
+00450         if (len < QuatEpsilon)
+00451                 return CQuatT<T>(0.f, 0.f, 0.f, 1.f);
+00452         else
+00453         {
+00454                 double len1 = sin(len) / len; 
+00455                 return CQuatT<T>( (T)(x*len1), (T)(y*len1), (T)(z*len1), (T)cos(len));
+00456         }
+00457 }
+00458 
+00459 
+00460 // ***************************************************************************
+00461 template <class T> 
+00462 CQuatT<T>       CQuatT<T>::lnDif(const CQuatT<T> &q0, const CQuatT<T> &q1)
+00463 {
+00464         CQuatT<T>       dif = q0.inverted()*q1;
+00465         dif.normalize();
+00466 
+00467         return dif.log();
+00468 }
+00469 
+00470 
+00471 // ***************************************************************************
+00472 template <class T> 
+00473 void    CQuatT<T>::makeClosest(const CQuatT<T> &o)
+00474 {
+00475         if( dotProduct(*this, o) < 0 )
+00476                 *this= -(*this);
+00477 }
+00478 
+00479 
+00480 
+00481 // ***************************************************************************
+00482 // ***************************************************************************
+00483 // CQuat/CQuatD
+00484 // ***************************************************************************
+00485 // ***************************************************************************
+00486 
+00487 
+00488 
+00489 // ***************************************************************************
+00496 class   CQuat : public CQuatT<float>
+00497 {
+00498 public:
+00499         static const CQuat              Identity;
+00500 
+00502         // @{
+00503         CQuat   &operator=(const CQuatT<float> &o) {x=o.x; y=o.y; z=o.z; w=o.w; return *this;}
+00504         CQuat(const CQuatT<float> &o) : CQuatT<float>(o) {}
+00505         CQuat() {}
+00506         CQuat(float X, float Y, float Z, float W) : CQuatT<float>(X,Y,Z,W) {}
+00508         CQuat(const CVector &axis, float angle) : CQuatT<float>(axis, angle) {}
+00510         CQuat(const CAngleAxis &aa) : CQuatT<float>(aa) {}
+00511         // @}
+00512 
+00513 };
+00514 
+00515 
+00516 // ***************************************************************************
+00523 class   CQuatD : public CQuatT<double>
+00524 {
+00525 public:
+00526         static const CQuatD             Identity;
+00527 
+00529         // @{
+00530         CQuatD  &operator=(const CQuatT<double> &o) {x=o.x; y=o.y; z=o.z; w=o.w; return *this;}
+00531         CQuatD(const CQuatT<double> &o) : CQuatT<double>(o) {}
+00532         CQuatD() {}
+00533         CQuatD(double X, double Y, double Z, double W) : CQuatT<double>(X,Y,Z,W) {}
+00535         CQuatD(const CVector &axis, float angle) : CQuatT<double>(axis, angle) {}
+00537         CQuatD(const CAngleAxis &aa) : CQuatT<double>(aa) {}
+00538         // @}
+00539 
+00540         
+00542         // @{
+00543         CQuatD(const CQuat &o) {x=o.x; y=o.y; z=o.z; w=o.w;}
+00544         CQuatD  &operator=(const CQuatT<float> &o) {x=o.x; y=o.y; z=o.z; w=o.w; return *this;}
+00545         operator        CQuat() const {return CQuat((float)x, (float)y, (float)z, (float)w);} 
+00546         // @}
+00547 
+00548 };
+00549 
+00550 
+00551 
+00552 
+00553 
+00554 } // NLMISC
+00555 
+00556 #endif // NL_QUAT_H 
+00557 
+
+ + +
                                                                                                                                                                    +
+ + -- cgit v1.2.1