11 template <
class VEC3,
class VEC4>
15 typedef typename VEC4::elem_t
T;
20 qrot(
const VEC3& a_axis,
T a_radians,
T(*a_sin)(
T),
T(*a_cos)(
T)){
21 if(!
set_value(a_axis,a_radians,a_sin,a_cos)) {}
23 qrot(
const VEC3& a_from,
const VEC3& a_to,
T(*a_sqrt)(
T),
T(*a_fabs)(
T)){
set_value(a_from,a_to,a_sqrt,a_fabs);}
35 :
m_quat(a_q0,a_q1,a_q2,a_q3)
57 m_quat.set_value(qw*tx + qx*tw + qy*tz - qz*ty,
58 qw*ty - qx*tz + qy*tw + qz*tx,
59 qw*tz + qx*ty - qy*tx + qz*tw,
60 qw*tw - qx*tx - qy*ty - qz*tz);
79 if(length==
T())
return false;
82 T inv =
one() / length;
95 if(length==
T())
return false;
98 T inv =
one() / length;
113 if(a_axis.length()==
T())
return false;
114 m_quat.v3(a_cos(a_radians/2));
115 T sineval = a_sin(a_radians/2);
118 m_quat.v0(a.v0() * sineval);
119 m_quat.v1(a.v1() * sineval);
120 m_quat.v2(a.v2() * sineval);
124 bool set_value(
const VEC3& a_from,
const VEC3& a_to,
T(*a_sqrt)(
T),
T(*a_fabs)(
T)) {
129 if(from.normalize()==
T())
return false;
131 if(
to.normalize()==
T())
return false;
133 T dot = from.dot(
to);
134 VEC3 crossvec;from.cross(
to,crossvec);
135 T crosslen = crossvec.normalize();
137 if(crosslen ==
T()) {
140 m_quat.set_value(0,0,0,1);
145 VEC3 t;from.cross(VEC3(1,0,0),t);
147 if(t.normalize() ==
T()) {
148 from.cross(VEC3(0,1,0),t);
151 m_quat.set_value(t[0],t[1],t[2],0);
156 crossvec *= (
T)a_sqrt(
half() * a_fabs(
one() - dot));
159 m_quat.set_value(crossvec[0], crossvec[1], crossvec[2],(
T)a_sqrt(
half()*a_fabs(
one()+dot)));
166 bool value(VEC3& a_axis,
T& a_radians,
T(*a_sin)(
T),
T(*a_acos)(
T))
const {
169 a_axis.set_value(0,0,1);
174 a_radians = a_acos(
m_quat.v3()) * 2;
175 T sineval = a_sin(a_radians/2);
178 a_axis.set_value(0,0,1);
182 a_axis.set_value(
m_quat.v0()/sineval,
188 template <
class MAT4>
195 T scalerow = a_m.v00() + a_m.v11() + a_m.v22();
196 if (scalerow >
T()) {
197 T _s = a_sqrt(scalerow + a_m.v33());
201 m_quat.v0((a_m.v21() - a_m.v12()) * _s);
202 m_quat.v1((a_m.v02() - a_m.v20()) * _s);
203 m_quat.v2((a_m.v10() - a_m.v01()) * _s);
206 if (a_m.v11() > a_m.v00()) i = 1;
207 if (a_m.v22() > a_m.value(i,i)) i = 2;
209 unsigned int j = (i+1)%3;
210 unsigned int k = (j+1)%3;
212 T _s = a_sqrt((a_m.value(i,i) - (a_m.value(j,j) + a_m.value(k,k))) + a_m.v33());
217 m_quat.v3((a_m.value(k,j) - a_m.value(j,k)) * _s);
218 m_quat.set_value(j,(a_m.value(j,i) + a_m.value(i,j)) * _s);
219 m_quat.set_value(k,(a_m.value(k,i) + a_m.value(i,k)) * _s);
222 if (a_m.v33()!=
one()) {
223 m_quat.multiply(
one()/a_sqrt(a_m.v33()));
227 template <
class MAT4>
239 a_m.v00(w*w + x*x - y*y - z*z);
240 a_m.v01(2*x*y - 2*w*z);
241 a_m.v02(2*x*z + 2*w*y);
245 a_m.v10(2*x*y + 2*w*z);
246 a_m.v11(w*w - x*x + y*y - z*z);
247 a_m.v12(2*y*z - 2*w*x);
251 a_m.v20(2*x*z - 2*w*y);
252 a_m.v21(2*y*z + 2*w*x);
253 a_m.v22(w*w - x*x - y*y + z*z);
260 a_m.v33(w*w + x*x + y*y + z*z);
263 template <
class MAT3>
275 a_m.v00(w*w + x*x - y*y - z*z);
276 a_m.v01(2*x*y - 2*w*z);
277 a_m.v02(2*x*z + 2*w*y);
280 a_m.v10(2*x*y + 2*w*z);
281 a_m.v11(w*w - x*x + y*y - z*z);
282 a_m.v12(2*y*z - 2*w*x);
285 a_m.v20(2*x*z - 2*w*y);
286 a_m.v21(2*y*z + 2*w*x);
287 a_m.v22(w*w - x*x - y*y + z*z);
294 return w*w + x*x + y*y + z*z;
297 void mul_vec(
const VEC3& a_in,VEC3& a_out)
const {
304 T v0 = (w*w + x*x - y*y - z*z) * a_in.v0()
305 + (2*x*y - 2*w*z) * a_in.v1()
306 + (2*x*z + 2*w*y) * a_in.v2();
308 T v1 = (2*x*y + 2*w*z) * a_in.v0()
309 +(w*w - x*x + y*y - z*z) * a_in.v1()
310 + (2*y*z - 2*w*x) * a_in.v2();
312 T v2 = (2*x*z - 2*w*y) * a_in.v0()
313 + (2*y*z + 2*w*x) * a_in.v1()
314 +(w*w - x*x - y*y + z*z) * a_in.v2();
316 a_out.set_value(v0,v1,v2);
326 T v0 = (w*w + x*x - y*y - z*z) * a_v.v0()
327 + (2*x*y - 2*w*z) * a_v.v1()
328 + (2*x*z + 2*w*y) * a_v.v2();
330 T v1 = (2*x*y + 2*w*z) * a_v.v0()
331 +(w*w - x*x + y*y - z*z) * a_v.v1()
332 + (2*y*z - 2*w*x) * a_v.v2();
334 T v2 = (2*x*z - 2*w*y) * a_v.v0()
335 + (2*y*z + 2*w*x) * a_v.v1()
336 +(w*w - x*x - y*y + z*z) * a_v.v2();
338 a_v.set_value(v0,v1,v2);
348 T v0 = (w*w + x*x - y*y - z*z) * a_x
349 + (2*x*y - 2*w*z) * a_y
350 + (2*x*z + 2*w*y) * a_z;
352 T v1 = (2*x*y + 2*w*z) * a_x
353 +(w*w - x*x + y*y - z*z) * a_y
354 + (2*y*z - 2*w*x) * a_z;
356 T v2 = (2*x*z - 2*w*y) * a_x
357 + (2*y*z + 2*w*x) * a_y
358 +(w*w - x*x - y*y + z*z) * a_z;