00001
00002 #include <vecmath/_Quat4.h>
00003
00004 template<> const double _Quat4<double>::EPS = 1.0e-06;
00005 template<> const double _Quat4<double>::EPS1 = 1.0e-30;
00006 template<> const float _Quat4<float>::EPS = 1.0e-06;
00007 template<> const float _Quat4<float>::EPS1 = 1.0e-30;
00008
00009 template <class Type>
00010 void _Quat4<Type>::setByMatrix(double m00, double m01, double m02,
00011 double m10, double m11, double m12,
00012 double m20, double m21, double m22)
00013 {
00014 double d = (1.0 + m00 + m11 + m22) / 4;
00015 if (fabs(d) >= EPS1) {
00016 _Tuple4<Type>::w = sqrt(d);
00017 d = 0.25 / _Tuple4<Type>::w;
00018 _Tuple4<Type>::x = (m21 - m12) * d;
00019 _Tuple4<Type>::y = (m02 - m20) * d;
00020 _Tuple4<Type>::z = (m10 - m01) * d;
00021 return;
00022 }
00023 _Tuple4<Type>::w = 0.0;
00024 d = -0.5 * (m11 + m22);
00025 if (fabs(d) >= EPS1) {
00026 _Tuple4<Type>::x = sqrt(d);
00027 d = 1.0 / (2 * _Tuple4<Type>::x);
00028 _Tuple4<Type>::y = m10 * d;
00029 _Tuple4<Type>::z = m20 * d;
00030 return;
00031 }
00032 _Tuple4<Type>::x = 0.0;
00033 d = (1.0 - m22) / 2;
00034 if (fabs(d) >= EPS1) {
00035 _Tuple4<Type>::y = sqrt(d);
00036 _Tuple4<Type>::z = m21 / (2.0 * _Tuple4<Type>::y);
00037 } else {
00038 _Tuple4<Type>::y = 0.0;
00039 _Tuple4<Type>::z = 1.0;
00040 }
00041 }
00042
00043 template <class Type>
00044 void _Quat4<Type>::setByAxis(double ax, double ay, double az, double aa)
00045 {
00046 double d1 = sqrt(ax * ax + ay * ay + az * az);
00047 if(d1 > EPS) {
00048 Type d = sin(aa / 2);
00049 _Tuple4<Type>::set(ax / d1 * d, ay / d1 * d, az / d1 * d, cos(aa / 2));
00050 } else
00051 _Tuple4<Type>::set(0.0, 0.0, 0.0, 0.0);
00052 }
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 template <class Type>
00063 void _Quat4<Type>::interpolate(const _Quat4<Type>& q, const _Quat4<Type>& q1, Type d)
00064 {
00065 Type x, y, z, w;
00066
00067 Type d1 = q.x * q1.x + q.y * q1.y + q.z * q1.z + q.w * q1.w;
00068
00069
00070 if (d1 < 0.0) {
00071
00072 x = -q.x;
00073 y = -q.y;
00074 z = -q.z;
00075 w = -q.w;
00076 } else {
00077 x = q.x;
00078 y = q.y;
00079 z = q.z;
00080 w = q.w;
00081 }
00082
00083 if(1.0 + d1 > EPS) {
00084 Type d2;
00085 Type d4;
00086 if(1.0 - d1 > EPS) {
00087 Type d6 = acos(d1);
00088 Type d7 = sin(d6);
00089 d2 = sin((1.0 - d) * d6) / d7;
00090 d4 = sin(d * d6) / d7;
00091 } else {
00092 d2 = 1.0 - d;
00093 d4 = d;
00094 }
00095 _Tuple4<Type>::set(d2 * x + d4 * q1.x,
00096 d2 * y + d4 * q1.y,
00097 d2 * z + d4 * q1.z,
00098 d2 * w + d4 * q1.w);
00099 } else {
00100 Type d9 = x;
00101 Type d8 = -y;
00102 Type d11 = z;
00103 Type d10 = -w;
00104 Type d3 = sin((1.0 - d) * Math::PI/2.0);
00105 Type d5 = sin(d * Math::PI/2.0);
00106 _Tuple4<Type>::set(d3 * x + d5 * d8,
00107 d3 * y + d5 * d9,
00108 d3 * z + d5 * d10,
00109 d3 * w + d5 * d11);
00110 }
00111 }
00112
00113 template <class Type>
00114 void _Quat4<Type>::mul(const _Quat4<Type>& q, const _Quat4<Type>& q1)
00115 {
00116 Type d = (q.w * q1.x + q1.w * q.x + q.y * q1.z) - q.z * q1.y;
00117 Type d1 = ((q.w * q1.y + q1.w * q.y) - q.x * q1.z) + q.z * q1.x;
00118 Type d2 = q.w * q1.w - q.x * q1.x - q.y * q1.y - q.z * q1.z;
00119
00120 _Tuple4<Type>::z = (q.w * q1.z + q1.w * q.z + q.x * q1.y) - q.y * q1.x;
00121 _Tuple4<Type>::x = d;
00122 _Tuple4<Type>::y = d1;
00123 _Tuple4<Type>::w = d2;
00124 }
00125
00126 template class _Quat4<double>;
00127 template class _Quat4<float>;
00128