00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <lib3ds/quat.h>
00023 #include <math.h>
00024
00025
00041 void
00042 lib3ds_quat_zero(Lib3dsQuat c)
00043 {
00044 c[0]=c[1]=c[2]=c[3]=0.0f;
00045 }
00046
00047
00052 void
00053 lib3ds_quat_identity(Lib3dsQuat c)
00054 {
00055 c[0]=c[1]=c[2]=0.0f;
00056 c[3]=1.0f;
00057 }
00058
00059
00064 void
00065 lib3ds_quat_copy(Lib3dsQuat dest, Lib3dsQuat src)
00066 {
00067 int i;
00068 for (i=0; i<4; ++i) {
00069 dest[i]=src[i];
00070 }
00071 }
00072
00073
00083 void
00084 lib3ds_quat_axis_angle(Lib3dsQuat c, Lib3dsVector axis, Lib3dsFloat angle)
00085 {
00086 Lib3dsDouble omega,s;
00087 Lib3dsDouble l;
00088
00089 l=sqrt(axis[0]*axis[0] + axis[1]*axis[1] + axis[2]*axis[2]);
00090 if (l<LIB3DS_EPSILON) {
00091 c[0]=c[1]=c[2]=0.0f;
00092 c[3]=1.0f;
00093 }
00094 else {
00095 omega=-0.5*angle;
00096 s=sin(omega)/l;
00097 c[0]=(Lib3dsFloat)s*axis[0];
00098 c[1]=(Lib3dsFloat)s*axis[1];
00099 c[2]=(Lib3dsFloat)s*axis[2];
00100 c[3]=(Lib3dsFloat)cos(omega);
00101 }
00102 }
00103
00104
00110 void
00111 lib3ds_quat_neg(Lib3dsQuat c)
00112 {
00113 int i;
00114 for (i=0; i<4; ++i) {
00115 c[i]=-c[i];
00116 }
00117 }
00118
00119
00125 void
00126 lib3ds_quat_abs(Lib3dsQuat c)
00127 {
00128 int i;
00129 for (i=0; i<4; ++i) {
00130 c[i]=(Lib3dsFloat)fabs(c[i]);
00131 }
00132 }
00133
00134
00140 void
00141 lib3ds_quat_cnj(Lib3dsQuat c)
00142 {
00143 int i;
00144 for (i=0; i<3; ++i) {
00145 c[i]=-c[i];
00146 }
00147 }
00148
00149
00157 void
00158 lib3ds_quat_mul(Lib3dsQuat c, Lib3dsQuat a, Lib3dsQuat b)
00159 {
00160 c[0]=a[3]*b[0] + a[0]*b[3] + a[1]*b[2] - a[2]*b[1];
00161 c[1]=a[3]*b[1] + a[1]*b[3] + a[2]*b[0] - a[0]*b[2];
00162 c[2]=a[3]*b[2] + a[2]*b[3] + a[0]*b[1] - a[1]*b[0];
00163 c[3]=a[3]*b[3] - a[0]*b[0] - a[1]*b[1] - a[2]*b[2];
00164 }
00165
00166
00172 void
00173 lib3ds_quat_scalar(Lib3dsQuat c, Lib3dsFloat k)
00174 {
00175 int i;
00176 for (i=0; i<4; ++i) {
00177 c[i]*=k;
00178 }
00179 }
00180
00181
00187 void
00188 lib3ds_quat_normalize(Lib3dsQuat c)
00189 {
00190 Lib3dsDouble l,m;
00191
00192 l=sqrt(c[0]*c[0] + c[1]*c[1] + c[2]*c[2] + c[3]*c[3]);
00193 if (fabs(l)<LIB3DS_EPSILON) {
00194 c[0]=c[1]=c[2]=0.0f;
00195 c[3]=1.0f;
00196 }
00197 else {
00198 int i;
00199 m=1.0f/l;
00200 for (i=0; i<4; ++i) {
00201 c[i]=(Lib3dsFloat)(c[i]*m);
00202 }
00203 }
00204 }
00205
00206
00212 void
00213 lib3ds_quat_inv(Lib3dsQuat c)
00214 {
00215 Lib3dsDouble l,m;
00216
00217 l=sqrt(c[0]*c[0] + c[1]*c[1] + c[2]*c[2] + c[3]*c[3]);
00218 if (fabs(l)<LIB3DS_EPSILON) {
00219 c[0]=c[1]=c[2]=0.0f;
00220 c[3]=1.0f;
00221 }
00222 else {
00223 m=1.0f/l;
00224 c[0]=(Lib3dsFloat)(-c[0]*m);
00225 c[1]=(Lib3dsFloat)(-c[1]*m);
00226 c[2]=(Lib3dsFloat)(-c[2]*m);
00227 c[3]=(Lib3dsFloat)(c[3]*m);
00228 }
00229 }
00230
00231
00237 Lib3dsFloat
00238 lib3ds_quat_dot(Lib3dsQuat a, Lib3dsQuat b)
00239 {
00240 return(a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + a[3]*b[3]);
00241 }
00242
00243
00247 Lib3dsFloat
00248 lib3ds_quat_squared(Lib3dsQuat c)
00249 {
00250 return(c[0]*c[0] + c[1]*c[1] + c[2]*c[2] + c[3]*c[3]);
00251 }
00252
00253
00257 Lib3dsFloat
00258 lib3ds_quat_length(Lib3dsQuat c)
00259 {
00260 return((Lib3dsFloat)sqrt(c[0]*c[0] + c[1]*c[1] + c[2]*c[2] + c[3]*c[3]));
00261 }
00262
00263
00267 void
00268 lib3ds_quat_ln(Lib3dsQuat c)
00269 {
00270 Lib3dsDouble om,s,t;
00271
00272 s=sqrt(c[0]*c[0] + c[1]*c[1] + c[2]*c[2]);
00273 om=atan2(s,c[3]);
00274 if (fabs(s)<LIB3DS_EPSILON) {
00275 t=0.0f;
00276 }
00277 else {
00278 t=om/s;
00279 }
00280 {
00281 int i;
00282 for (i=0; i<3; ++i) {
00283 c[i]=(Lib3dsFloat)(c[i]*t);
00284 }
00285 c[3]=0.0f;
00286 }
00287 }
00288
00289
00293 void
00294 lib3ds_quat_ln_dif(Lib3dsQuat c, Lib3dsQuat a, Lib3dsQuat b)
00295 {
00296 Lib3dsQuat invp;
00297
00298 lib3ds_quat_copy(invp, a);
00299 lib3ds_quat_inv(invp);
00300 lib3ds_quat_mul(c, invp, b);
00301 lib3ds_quat_ln(c);
00302 }
00303
00304
00308 void
00309 lib3ds_quat_exp(Lib3dsQuat c)
00310 {
00311 Lib3dsDouble om,sinom;
00312
00313 om=sqrt(c[0]*c[0] + c[1]*c[1] + c[2]*c[2]);
00314 if (fabs(om)<LIB3DS_EPSILON) {
00315 sinom=1.0f;
00316 }
00317 else {
00318 sinom=sin(om)/om;
00319 }
00320 {
00321 int i;
00322 for (i=0; i<3; ++i) {
00323 c[i]=(Lib3dsFloat)(c[i]*sinom);
00324 }
00325 c[3]=(Lib3dsFloat)cos(om);
00326 }
00327 }
00328
00329
00333 void
00334 lib3ds_quat_slerp(Lib3dsQuat c, Lib3dsQuat a, Lib3dsQuat b, Lib3dsFloat t)
00335 {
00336 Lib3dsDouble l;
00337 Lib3dsDouble om,sinom;
00338 Lib3dsDouble sp,sq;
00339 Lib3dsQuat q;
00340
00341 l=a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + a[3]*b[3];
00342 if ((1.0+l)>LIB3DS_EPSILON) {
00343 if (fabs(l)>1.0f) l/=fabs(l);
00344 om=acos(l);
00345 sinom=sin(om);
00346 if (fabs(sinom)>LIB3DS_EPSILON) {
00347 sp=sin((1.0f-t)*om)/sinom;
00348 sq=sin(t*om)/sinom;
00349 }
00350 else {
00351 sp=1.0f-t;
00352 sq=t;
00353 }
00354 c[0]=(Lib3dsFloat)(sp*a[0] + sq*b[0]);
00355 c[1]=(Lib3dsFloat)(sp*a[1] + sq*b[1]);
00356 c[2]=(Lib3dsFloat)(sp*a[2] + sq*b[2]);
00357 c[3]=(Lib3dsFloat)(sp*a[3] + sq*b[3]);
00358 }
00359 else {
00360 q[0]=-a[1];
00361 q[1]=a[0];
00362 q[2]=-a[3];
00363 q[3]=a[2];
00364 sp=sin((1.0-t)*LIB3DS_HALFPI);
00365 sq=sin(t*LIB3DS_HALFPI);
00366 c[0]=(Lib3dsFloat)(sp*a[0] + sq*q[0]);
00367 c[1]=(Lib3dsFloat)(sp*a[1] + sq*q[1]);
00368 c[2]=(Lib3dsFloat)(sp*a[2] + sq*q[2]);
00369 c[3]=(Lib3dsFloat)(sp*a[3] + sq*q[3]);
00370 }
00371 }
00372
00373
00377 void
00378 lib3ds_quat_squad(Lib3dsQuat c, Lib3dsQuat a, Lib3dsQuat p, Lib3dsQuat q,
00379 Lib3dsQuat b, Lib3dsFloat t)
00380 {
00381 Lib3dsQuat ab;
00382 Lib3dsQuat pq;
00383
00384 lib3ds_quat_slerp(ab,a,b,t);
00385 lib3ds_quat_slerp(pq,p,q,t);
00386 lib3ds_quat_slerp(c,ab,pq,2*t*(1-t));
00387 }
00388
00389
00393 void
00394 lib3ds_quat_tangent(Lib3dsQuat c, Lib3dsQuat p, Lib3dsQuat q, Lib3dsQuat n)
00395 {
00396 Lib3dsQuat dn,dp,x;
00397 int i;
00398
00399 lib3ds_quat_ln_dif(dn, q, n);
00400 lib3ds_quat_ln_dif(dp, q, p);
00401
00402 for (i=0; i<4; i++) {
00403 x[i]=-1.0f/4.0f*(dn[i]+dp[i]);
00404 }
00405 lib3ds_quat_exp(x);
00406 lib3ds_quat_mul(c,q,x);
00407 }
00408
00409
00413 void
00414 lib3ds_quat_dump(Lib3dsQuat q)
00415 {
00416 printf("%f %f %f %f\n", q[0], q[1], q[2], q[3]);
00417 }
00418