00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00027
#include "ShQuaternion.hpp"
00028
00029
namespace SH {
00030
template<ShBindingType B,
typename T>
00031 ShQuaternion<B, T>::ShQuaternion()
00032 {
00033
if (B == SH_TEMP)
00034 {
00035 m_data =
ShVector4f(1.0, 0.0, 0.0, 0.0);
00036
00037 }
00038 }
00039
00040
template<ShBindingType B,
typename T>
00041
template<ShBindingType B2>
00042 ShQuaternion<B, T>::ShQuaternion(
const ShQuaternion<B2, T>& other)
00043 : m_data(other.getVector())
00044 {
00045 }
00046
00047
template<ShBindingType B,
typename T>
00048
template<ShBindingType B2>
00049 ShQuaternion<B, T>::ShQuaternion(
const ShVector<4, B2, T>& values)
00050 : m_data(values)
00051 {
00052 }
00053
00054
template<ShBindingType B,
typename T>
00055
template<ShBindingType B2, ShBindingType B3>
00056 ShQuaternion<B, T>::ShQuaternion(
const ShAttrib<1, B2, T>& angle,
00057
const ShVector<3, B3, T>& axis)
00058 {
00059 m_data(0) =
cos(angle/2.0);
00060 m_data(1,2,3) =
SH::normalize(axis);
00061 m_data(1,2,3) *=
sin(angle/2.0);
00062
00063 }
00064
00065
template<ShBindingType B,
typename T>
00066
template<ShBindingType B2>
00067 ShQuaternion<B, T>::ShQuaternion(
const ShMatrix<4, 4, B2, T>& mat)
00068 {
00069
ShAttrib1f trace = 1.0 + mat[0](0) + mat[1](1) + mat[2](2);
00070 trace = (trace >= 0.0)*trace + (trace < 0.0)*0.0;
00071
ShAttrib1f c0 = (trace > 0.001);
00072
ShAttrib1f c1 = ((mat[0](0) > mat[1](1))*(mat[0](0) > mat[2](2)));
00073
ShAttrib1f c2 = ( mat[1](1) > mat[2](2) );
00074
ShVector4f res0, res1, res2, res3;
00075
ShAttrib1f S0 = sqrt(trace) * 2.0;
00076 S0 += (S0 == 0.0)*1.0;
00077
00078 res0(0) = 0.25 * S0;
00079 res0(1) = (mat[1](2) - mat[2](1)) / S0;
00080 res0(2) = (mat[2](0) - mat[0](2)) / S0;
00081 res0(3) = (mat[0](1) - mat[1](0)) / S0;
00082
00083 trace = 1.0 + mat[0](0) - mat[1](1) - mat[2](2);
00084 trace = (trace >= 0.0)*trace + (trace < 0.0)*0.0;
00085
ShAttrib1f S1 = sqrt(trace) * 2.0;
00086 S1 += (S1 == 0.0)*1.0;
00087
00088 res1(0) = (mat[2](1) - mat[1](2)) / S1;
00089 res1(1) = 0.25 * S1;
00090 res1(2) = (mat[0](1) + mat[1](0)) / S1;
00091 res1(3) = (mat[2](0) + mat[0](2)) / S1;
00092
00093 trace = 1.0 - mat[0](0) + mat[1](1) - mat[2](2);
00094 trace = (trace >= 0.0)*trace + (trace < 0.0)*0.0;
00095
ShAttrib1f S2 = sqrt(trace) * 2.0;
00096 S2 += (S2 == 0.0)*1.0;
00097
00098 res2(0) = (mat[2](0) - mat[0](2)) / S2;
00099 res2(1) = (mat[0](1) + mat[1](0)) / S2;
00100 res2(2) = 0.25 * S2;
00101 res2(3) = (mat[1](2) + mat[2](1)) / S2;
00102
00103 trace = 1.0 - mat[0](0) - mat[1](1) + mat[2](2);
00104 trace = (trace >= 0.0)*trace + (trace < 0.0)*0.0;
00105
ShAttrib1f S3 = sqrt(trace) * 2.0;
00106 S3 += (S3 == 0.0)*1.0;
00107
00108 res3(0) = (mat[1](0) - mat[0](1)) / S3;
00109 res3(1) = (mat[2](0) + mat[0](2)) / S3;
00110 res3(2) = (mat[1](2) + mat[2](1)) / S3;
00111 res3(3) = 0.25 * S3;
00112
00113 m_data = c0*res0 +
00114 (c0 == 0.0)*(c1*res1 + (c1 == 0.0)*(c2*res2 + (c2 == 0.0)*res3));
00115
00116 }
00117
00118
template<ShBindingType B,
typename T>
00119 std::ostream& operator<<(std::ostream& out, const ShQuaternion<B, T>& q)
00120 {
00121
float vals[4];
00122 q.m_data.
getValues(vals);
00123 out <<
"ShQuaternion: " << vals[0] <<
" " << vals[1] <<
" " << vals[2]
00124 <<
" " << vals[3];
00125
return out;
00126 }
00127
00128
template<ShBindingType B,
typename T>
00129
template<ShBindingType B2>
00130 ShQuaternion<B, T>&
00131 ShQuaternion<B, T>::operator=(
const ShQuaternion<B2, T>& other)
00132 {
00133 m_data = other.
getVector();
00134
return *
this;
00135 }
00136
00137
template<ShBindingType B,
typename T>
00138
template<ShBindingType B2>
00139
ShQuaternion<B, T>&
00140 ShQuaternion<B, T>::operator+=(
const ShQuaternion<B2, T>& right)
00141 {
00142 m_data += right.
getVector();
00143
return *
this;
00144 }
00145
00146
template<ShBindingType B,
typename T>
00147
template<ShBindingType B2>
00148
ShQuaternion<B, T>&
00149 ShQuaternion<B, T>::operator-=(
const ShQuaternion<B2, T>& right)
00150 {
00151 m_data -= right.
getVector();
00152
return *
this;
00153 }
00154
00155
template<ShBindingType B,
typename T>
00156
template<ShBindingType B2>
00157
ShQuaternion<B, T>&
00158 ShQuaternion<B, T>::operator*=(
const ShQuaternion<B2, T>& right)
00159 {
00160
ShVector4f result;
00161
ShVector4f rightData = right.
getVector();
00162 result(0) =
00163 m_data(0)*rightData(0) -
SH::dot(m_data(1,2,3), rightData(1,2,3));
00164 result(1,2,3) =
00165 m_data(0)*rightData(1,2,3) + rightData(0)*m_data(1,2,3) +
00166
cross(m_data(1,2,3), rightData(1,2,3));
00167
00168
00169 m_data = result;
00170
return *
this;
00171 }
00172
00173
template<ShBindingType B,
typename T>
00174
template<ShBindingType B2>
00175
ShQuaternion<B, T>&
00176 ShQuaternion<B, T>::operator*=(
const ShAttrib<1, B2, T>& right)
00177 {
00178 m_data = m_data*right;
00179
return *
this;
00180 }
00181
00182
template<ShBindingType B,
typename T>
00183
template<ShBindingType B2>
00184
ShQuaternion<B, T>&
00185 ShQuaternion<B, T>::operator*=(
const ShVector<3, B2, T>& right)
00186 {
00187
ShVector4f v;
00188 v(0) = 0.0;
00189 v(1,2,3) = right;
00190
00191 *
this *=
ShQuaternionf(v);
00192
return *
this;
00193 }
00194
00195
template<ShBindingType B,
typename T>
00196
template<ShBindingType B2>
00197
ShQuaternion<B, T>&
00198 ShQuaternion<B, T>::operator*=(
const ShNormal<3, B2, T>& right)
00199 {
00200
ShVector4f v;
00201 v(0) = 0.0;
00202 v(1,2,3) = right;
00203
00204 *
this *=
ShQuaternionf(v);
00205
return *
this;
00206 }
00207
00208
template<ShBindingType B,
typename T>
00209
template<ShBindingType B2>
00210
ShAttrib<1, SH_TEMP, T>
00211 ShQuaternion<B, T>::dot(
const ShQuaternion<B2, T>& q)
const
00212
{
00213
return SH::dot(m_data, q.
getVector());
00214 }
00215
00216
template<ShBindingType B,
typename T>
00217 ShQuaternion<SH_TEMP, T> ShQuaternion<B, T>::conjugate()
const
00218
{
00219
ShVector4f conjData;
00220 conjData(0) = m_data(0);
00221 conjData(1, 2, 3) = -m_data(1, 2, 3);
00222
00223
00224
return ShQuaternion<SH_TEMP>(conjData);
00225 }
00226
00227
template<ShBindingType B,
typename T>
00228 ShQuaternion<SH_TEMP, T> ShQuaternion<B, T>::inverse()
const
00229
{
00230
00231
00232
00233
ShAttrib1f norm =
SH::dot(m_data, m_data);
00234
return conjugate() * (1.0 / norm);
00235
00236 }
00237
00238
template<ShBindingType B,
typename T>
00239 ShMatrix<4, 4, SH_TEMP, T> ShQuaternion<B, T>::getMatrix()
const
00240
{
00241
SH::ShMatrix4x4f m;
00242
ShAttrib4f x = m_data(1,1,1,1) * m_data(1,2,3,0);
00243
ShAttrib4f y = m_data(2,2,2,2) * m_data(0,2,3,0);
00244
ShAttrib4f z = m_data(3,3,3,3) * m_data(0,0,3,0);
00245
00246 m[0](0) = 1 - 2 * (y(1) + z(2));
00247 m[1](0) = 2 * (x(1) - z(3));
00248 m[2](0) = 2 * (x(2) + y(3));
00249
00250 m[0](1) = 2 * (x(2) + z(3));
00251 m[1](1) = 1 - 2 * (x(0) + z(2));
00252 m[2](1) = 2 * (y(2) - x(3));
00253
00254 m[0](2) = 2 * (x(2) - y(3));
00255 m[1](2) = 2 * (y(2) + x(3));
00256 m[2](2) = 1 - 2 * (x(0) + y(1));
00257
00258
return m;
00259 }
00260
00261
template<ShBindingType B,
typename T>
00262 ShVector<4, SH_TEMP, T> ShQuaternion<B, T>::getVector()
const
00263
{
00264
return m_data;
00265 }
00266
00267
template<ShBindingType B,
typename T>
00268
template<ShBindingType B2>
00269
ShQuaternion<SH_TEMP, T>
00270 ShQuaternion<B, T>::operator+(
const ShQuaternion<B2, T>& q)
00271 {
00272
ShQuaternion<B, T> r = *
this;
00273
return (r += q);
00274 }
00275
00276
template<ShBindingType B,
typename T>
00277
template<ShBindingType B2>
00278
ShQuaternion<SH_TEMP, T>
00279 ShQuaternion<B, T>::operator-(
const ShQuaternion<B2, T>& q)
00280 {
00281
ShQuaternion<B, T> r = *
this;
00282
return (r -= q);
00283 }
00284
00285
template<ShBindingType B,
typename T>
00286
template<ShBindingType B2>
00287
ShQuaternion<SH_TEMP, T>
00288 ShQuaternion<B, T>::operator*(
const ShQuaternion<B2, T>& q)
00289 {
00290
ShQuaternion<B, T> r = *
this;
00291
return (r *= q);
00292 }
00293
00294
template<ShBindingType B,
typename T>
00295
template<ShBindingType B2>
00296
ShQuaternion<SH_TEMP, T>
00297 ShQuaternion<B, T>::operator*(
const ShAttrib<1, B2, T>& c)
00298 {
00299
ShQuaternion<B, T> r = *
this;
00300
return (r *= c);
00301 }
00302
00303
template<ShBindingType B,
typename T>
00304
template<ShBindingType B2>
00305
ShQuaternion<SH_TEMP, T>
00306 ShQuaternion<B, T>::operator*(
const ShVector<3, B2, T>& v)
00307 {
00308
ShQuaternion<B, T> r = *
this;
00309
return (r *= v);
00310 }
00311
00312
template<ShBindingType B,
typename T>
00313
template<ShBindingType B2>
00314
ShQuaternion<SH_TEMP, T>
00315 ShQuaternion<B, T>::operator*(
const ShNormal<3, B2, T>& v)
00316 {
00317
ShQuaternion<B, T> r = *
this;
00318
return (r *= v);
00319 }
00320
00321
template<ShBindingType B,
typename T>
00322 void ShQuaternion<B, T>::normalize()
00323 {
00324 m_data =
SH::normalize(m_data);
00325 }
00326
00327
template<ShBindingType B,
typename T>
00328 void ShQuaternion<B, T>::setUnit(
bool flag)
00329 {
00330
00331 }
00332
00333
template<ShBindingType B,
typename T>
00334 void ShQuaternion<B, T>::getValues(T values[])
const
00335
{
00336 m_data.
getValues(values);
00337 }
00338
00339
template<ShBindingType B,
typename T, ShBindingType B2>
00340
ShQuaternion<SH_TEMP, T>
00341
operator*(
const ShAttrib<1, B2, T>& c,
const ShQuaternion<B, T>& q)
00342 {
00343
ShQuaternion<B, T> r = q;
00344
return (r *= c);
00345 }
00346
00347
template<ShBindingType B1, ShBindingType B2,
typename T>
00348
extern ShQuaternion<SH_TEMP, T>
00349 slerp(
const ShQuaternion<B1, T>& q1,
const ShQuaternion<B2, T>& q2,
00350
const ShAttrib1f& t)
00351 {
00352
00353
00354
00355
00356 ShAttrib<1, SH_TEMP, T> cosTheta = q1.dot(q2);
00357 ShAttrib<1, SH_TEMP, T> sinTheta = sqrt(1.0 - cosTheta*cosTheta);
00358
00359 ShQuaternion<B2, T> q2prime = (cosTheta >= 0.0)*q2 - (cosTheta < 0.0)*q2;
00360 ShAttrib<1, SH_TEMP, T> theta =
asin(sinTheta);
00361
00362
return (
sin((1.0 - t)*theta)/sinTheta)*q1 + (
sin(t*theta)/sinTheta)*q2prime;
00363 }
00364
00365
template<ShBindingType B,
typename T>
00366 std::string
ShQuaternion<B, T>::name()
const
00367
{
00368
return m_data.name();
00369 }
00370
00371
template<ShBindingType B,
typename T>
00372 void ShQuaternion<B, T>::name(
const std::string& name)
00373 {
00374 m_data.name(name);
00375 }
00376
00377
00378 }