2
* Copyright (C) 1999-2005 Terence M. Welsh
4
* This file is part of rsMath.
6
* rsMath is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU Lesser General Public
8
* License version 2.1 as published by the Free Software Foundation.
10
* rsMath is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU Lesser General Public
16
* License along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22
#include <rsMath/rsMath.h>
35
rsQuat::rsQuat(float x, float y, float z, float w){
48
void rsQuat::set(float x, float y, float z, float w){
56
void rsQuat::copy(rsQuat copyquat){
64
void rsQuat::make(float a, float x, float y, float z){
65
if(a < RSEPSILON && a > -RSEPSILON){
73
float sintheta = sinf(a);
82
void rsQuat::make(float a, const rsVec &v){
83
if(a < RSEPSILON && a > -RSEPSILON){
91
float sintheta = sinf(a);
92
q[0] = sintheta * v[0];
93
q[1] = sintheta * v[1];
94
q[2] = sintheta * v[2];
100
void rsQuat::normalize(){
101
float length = float(sqrt(q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]));
110
void rsQuat::preMult(rsQuat &postQuat){
111
// q1q2 = s1v2 + s2v1 + v1xv2, s1s2 - v1.v2
117
q[0] = tempw * postQuat[0] + postQuat[3] * tempx
118
+ tempy * postQuat[2] - postQuat[1] * tempz;
119
q[1] = tempw * postQuat[1] + postQuat[3] * tempy
120
+ tempz * postQuat[0] - postQuat[2] * tempx;
121
q[2] = tempw * postQuat[2] + postQuat[3] * tempz
122
+ tempx * postQuat[1] - postQuat[0] * tempy;
123
q[3] = tempw * postQuat[3]
124
- tempx * postQuat[0]
125
- tempy * postQuat[1]
126
- tempz * postQuat[2];
130
void rsQuat::postMult(rsQuat &preQuat){
136
q[0] = preQuat[3] * tempx + tempw * preQuat[0]
137
+ preQuat[1] * tempz - tempy * preQuat[2];
138
q[1] = preQuat[3] * tempy + tempw * preQuat[1]
139
+ preQuat[2] * tempx - tempz * preQuat[0];
140
q[2] = preQuat[3] * tempz + tempw * preQuat[2]
141
+ preQuat[0] * tempy - tempx * preQuat[1];
142
q[3] = preQuat[3] * tempw
145
- preQuat[2] * tempz;
149
void rsQuat::toMat(float *mat){
150
float s, xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz;
153
if(q[0] == 0.0f && q[1] == 0.0f && q[2] == 0.0f){
173
s = 2.0f / (q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3]);
187
mat[0] = 1.0f - yy - zz;
192
mat[5] = 1.0f - xx - zz;
197
mat[10] = 1.0f - xx - yy;
206
void rsQuat::fromMat(float* mat){
210
a = mat[0] + mat[5] + mat[10];
212
b = float(sqrt(a + 1.0f));
216
q[0] = (mat[6] - mat[9]) * b;
217
q[1] = (mat[8] - mat[2]) * b;
218
q[2] = (mat[1] - mat[4]) * b;
228
b = float(sqrt(mat[0] - mat[5] - mat[10] + 1.0f));
231
q[3] = (mat[6] - mat[9]) * b;
232
q[1] = (mat[1] - mat[4]) * b;
233
q[2] = (mat[2] - mat[8]) * b;
236
b = float(sqrt(mat[5] - mat[10] - mat[0] + 1.0f));
239
q[3] = (mat[8] - mat[2]) * b;
240
q[2] = (mat[6] - mat[9]) * b;
241
q[0] = (mat[4] - mat[1]) * b;
244
b = float(sqrt(mat[10] - mat[0] - mat[5] + 1.0f));
247
q[3] = (mat[1] - mat[4]) * b;
248
q[0] = (mat[8] - mat[2]) * b;
249
q[1] = (mat[9] - mat[6]) * b;
255
void rsQuat::fromEuler(float yaw, float pitch, float roll){
256
float cy, cp, cr, sy, sp, sr, cpcy, spsy;
258
cy = cosf(yaw * 0.5f);
259
cp = cosf(pitch * 0.5f);
260
cr = cosf(roll * 0.5f);
262
sy = sinf(yaw * 0.5f);
263
sp = sinf(pitch * 0.5f);
264
sr = sinf(roll * 0.5f);
269
q[3] = cr * cpcy + sr * spsy;
270
q[0] = sr * cpcy - cr * spsy;
271
q[1] = cr * sp * cy + sr * cp * sy;
272
q[2] = cr * cp * sy - sr * sp * cy;
276
void rsQuat::slerp(rsQuat a, rsQuat b, float t){
277
float n, cn, sn, scalea, scaleb;
279
cn = a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
280
if((1.0f + cn) > RSEPSILON){
281
if((1.0f - cn) > RSEPSILON){
284
scalea = sinf((1.0f - t) * n) / sn;
285
scaleb = sinf(t * n) / sn;
291
q[0] = scalea * a[0] + scaleb * b[0];
292
q[1] = scalea * a[1] + scaleb * b[1];
293
q[2] = scalea * a[2] + scaleb * b[2];
294
q[3] = scalea * a[3] + scaleb * b[3];
297
scalea = sinf((1.0f - t) * RS_PIo2);
298
scaleb = sinf(t * RS_PIo2);
299
q[0] = scalea * a[0] - scaleb * q[1];
300
q[1] = scalea * a[1] + scaleb * q[0];
301
q[2] = scalea * a[2] - scaleb * q[3];
302
q[3] = scalea * a[3] + scaleb * q[2];