imathquat.h
来自「image converter source code」· C头文件 代码 · 共 737 行 · 第 1/2 页
H
737 行
/////////////////////////////////////////////////////////////////////////////// Copyright (c) 2002, Industrial Light & Magic, a division of Lucas// Digital Ltd. LLC// // All rights reserved.// // Redistribution and use in source and binary forms, with or without// modification, are permitted provided that the following conditions are// met:// * Redistributions of source code must retain the above copyright// notice, this list of conditions and the following disclaimer.// * Redistributions in binary form must reproduce the above// copyright notice, this list of conditions and the following disclaimer// in the documentation and/or other materials provided with the// distribution.// * Neither the name of Industrial Light & Magic nor the names of// its contributors may be used to endorse or promote products derived// from this software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE./////////////////////////////////////////////////////////////////////////////#ifndef INCLUDED_IMATHQUAT_H#define INCLUDED_IMATHQUAT_H//----------------------------------------------------------------------//// template class Quat<T>//// "Quaternions came from Hamilton ... and have been an unmixed// evil to those who have touched them in any way. Vector is a// useless survival ... and has never been of the slightest use// to any creature."//// - Lord Kelvin//// This class implements the quaternion numerical type -- you// will probably want to use this class to represent orientations// in R3 and to convert between various euler angle reps. You// should probably use Imath::Euler<> for that.////----------------------------------------------------------------------#include "ImathExc.h"#include "ImathMatrix.h"#include <iostream>namespace Imath {#if (defined _WIN32 || defined _WIN64) && defined _MSC_VER// Disable MS VC++ warnings about conversion from double to float#pragma warning(disable:4244)#endiftemplate <class T>class Quat;template<class T>Quat<T> slerp (const Quat<T> &q1,const Quat<T> &q2, T t);template<class T>Quat<T> squad (const Quat<T> &q1,const Quat<T> &q2, const Quat<T> &qa,const Quat<T> &qb, T t);template<class T>void intermediate (const Quat<T> &q0, const Quat<T> &q1, const Quat<T> &q2, const Quat<T> &q3, Quat<T> &qa, Quat<T> &qb);template <class T>class Quat{ public: T r; // real part Vec3<T> v; // imaginary vector //----------------------------------------------------- // Constructors - default constructor is identity quat //----------------------------------------------------- Quat() : r(1), v(0,0,0) {} template <class S> Quat( const Quat<S>& q) : r(q.r), v(q.v) {} Quat( T s, T i, T j, T k ) : r(s), v(i,j,k) {} Quat( T s, Vec3<T> d ) : r(s), v(d) {} static Quat<T> identity() { return Quat<T>(); } //------------------------------------------------ // Basic Algebra - Operators and Methods // The operator return values are *NOT* normalized // // operator^ is 4D dot product // operator/ uses the inverse() quaternion // operator~ is conjugate -- if (S+V) is quat then // the conjugate (S+V)* == (S-V) // // some operators (*,/,*=,/=) treat the quat as // a 4D vector when one of the operands is scalar //------------------------------------------------ const Quat<T>& operator= (const Quat<T>&); const Quat<T>& operator*= (const Quat<T>&); const Quat<T>& operator*= (T); const Quat<T>& operator/= (const Quat<T>&); const Quat<T>& operator/= (T); const Quat<T>& operator+= (const Quat<T>&); const Quat<T>& operator-= (const Quat<T>&); T& operator[] (int index); // as 4D vector T operator[] (int index) const; template <class S> bool operator == (const Quat<S> &q) const; template <class S> bool operator != (const Quat<S> &q) const; Quat<T>& invert(); // this -> 1 / this Quat<T> inverse() const; Quat<T>& normalize(); // returns this Quat<T> normalized() const; T length() const; // in R4 //----------------------- // Rotation conversion //----------------------- Quat<T>& setAxisAngle(const Vec3<T>& axis, T radians); Quat<T>& setRotation(const Vec3<T>& fromDirection, const Vec3<T>& toDirection); T angle() const; Vec3<T> axis() const; Matrix33<T> toMatrix33() const; Matrix44<T> toMatrix44() const; Quat<T> log() const; Quat<T> exp() const; private: void setRotationInternal (const Vec3<T>& f0, const Vec3<T>& t0, Quat<T> &q);};//--------------------// Convenient typedefs//--------------------typedef Quat<float> Quatf;typedef Quat<double> Quatd;//---------------// Implementation//---------------template<class T>inline const Quat<T>& Quat<T>::operator= (const Quat<T>& q){ r = q.r; v = q.v; return *this;}template<class T>inline const Quat<T>& Quat<T>::operator*= (const Quat<T>& q){ T rtmp = r * q.r - (v ^ q.v); v = r * q.v + v * q.r + v % q.v; r = rtmp; return *this;}template<class T>inline const Quat<T>& Quat<T>::operator*= (T t){ r *= t; v *= t; return *this;}template<class T>inline const Quat<T>& Quat<T>::operator/= (const Quat<T>& q){ *this = *this * q.inverse(); return *this;}template<class T>inline const Quat<T>& Quat<T>::operator/= (T t){ r /= t; v /= t; return *this;}template<class T>inline const Quat<T>& Quat<T>::operator+= (const Quat<T>& q){ r += q.r; v += q.v; return *this;}template<class T>inline const Quat<T>& Quat<T>::operator-= (const Quat<T>& q){ r -= q.r; v -= q.v; return *this;}template<class T>inline T& Quat<T>::operator[] (int index){ return index ? v[index-1] : r;}template<class T>inline T Quat<T>::operator[] (int index) const{ return index ? v[index-1] : r;}template <class T>template <class S>inline boolQuat<T>::operator == (const Quat<S> &q) const{ return r == q.r && v == q.v;}template <class T>template <class S>inline boolQuat<T>::operator != (const Quat<S> &q) const{ return r != q.r || v != q.v;}template<class T>inline T operator^ (const Quat<T>& q1,const Quat<T>& q2){ return q1.r * q2.r + (q1.v ^ q2.v);}template <class T>inline T Quat<T>::length() const{ return Math<T>::sqrt( r * r + (v ^ v) );}template <class T>inline Quat<T>& Quat<T>::normalize(){ if ( T l = length() ) { r /= l; v /= l; } else { r = 1; v = Vec3<T>(0); } return *this;}template <class T>inline Quat<T> Quat<T>::normalized() const{ if ( T l = length() ) return Quat( r / l, v / l ); return Quat();}template<class T>inline Quat<T> Quat<T>::inverse() const{ // 1 Q* // - = ---- where Q* is conjugate (operator~) // Q Q* Q and (Q* Q) == Q ^ Q (4D dot) T qdot = *this ^ *this; return Quat( r / qdot, -v / qdot );}template<class T>inline Quat<T>& Quat<T>::invert(){ T qdot = (*this) ^ (*this); r /= qdot; v = -v / qdot; return *this;}template<class T>Tangle4D (const Quat<T> &q1, const Quat<T> &q2){ // // Compute the angle between two quaternions, // interpreting the quaternions as 4D vectors. // Quat<T> d = q1 - q2; T lengthD = Math<T>::sqrt (d ^ d); Quat<T> s = q1 + q2; T lengthS = Math<T>::sqrt (s ^ s); return 2 * Math<T>::atan2 (lengthD, lengthS);}template<class T>Quat<T>slerp(const Quat<T> &q1,const Quat<T> &q2, T t){ // // Spherical linear interpolation. // Assumes q1 and q2 are normalized and that q1 != -q2. // // This method does *not* interpolate along the shortest // arc between q1 and q2. If you desire interpolation // along the shortest arc, and q1^q2 is negative, then // consider flipping the second quaternion explicitly. // // The implementation of squad() depends on a slerp() // that interpolates as is, without the automatic // flipping. // // Don Hatch explains the method we use here on his // web page, The Right Way to Calculate Stuff, at // http://www.plunk.org/~hatch/rightway.php // T a = angle4D (q1, q2); T s = 1 - t; Quat<T> q = sinx_over_x (s * a) / sinx_over_x (a) * s * q1 + sinx_over_x (t * a) / sinx_over_x (a) * t * q2; return q.normalized();}template<class T>Quat<T> spline(const Quat<T> &q0, const Quat<T> &q1, const Quat<T> &q2, const Quat<T> &q3, T t){ // Spherical Cubic Spline Interpolation - // from Advanced Animation and Rendering // Techniques by Watt and Watt, Page 366: // A spherical curve is constructed using three // spherical linear interpolations of a quadrangle // of unit quaternions: q1, qa, qb, q2.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?