00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00022 #include "lib3ds_impl.h"
00023
00024
00028 void
00029 lib3ds_quat_identity(float c[4]) {
00030 c[0] = c[1] = c[2] = 0.0f;
00031 c[3] = 1.0f;
00032 }
00033
00034
00038 void
00039 lib3ds_quat_copy(float dest[4], float src[4]) {
00040 int i;
00041 for (i = 0; i < 4; ++i) {
00042 dest[i] = src[i];
00043 }
00044 }
00045
00046
00054 void
00055 lib3ds_quat_axis_angle(float c[4], float axis[3], float angle) {
00056 double omega, s;
00057 double l;
00058
00059 l = sqrt(axis[0] * axis[0] + axis[1] * axis[1] + axis[2] * axis[2]);
00060 if (l < LIB3DS_EPSILON) {
00061 c[0] = c[1] = c[2] = 0.0f;
00062 c[3] = 1.0f;
00063 } else {
00064 omega = -0.5 * angle;
00065 s = sin(omega) / l;
00066 c[0] = (float)s * axis[0];
00067 c[1] = (float)s * axis[1];
00068 c[2] = (float)s * axis[2];
00069 c[3] = (float)cos(omega);
00070 }
00071 }
00072
00073
00077 void
00078 lib3ds_quat_neg(float c[4]) {
00079 int i;
00080 for (i = 0; i < 4; ++i) {
00081 c[i] = -c[i];
00082 }
00083 }
00084
00085
00089 void
00090 lib3ds_quat_cnj(float c[4]) {
00091 int i;
00092 for (i = 0; i < 3; ++i) {
00093 c[i] = -c[i];
00094 }
00095 }
00096
00097
00104 void
00105 lib3ds_quat_mul(float c[4], float a[4], float b[4]) {
00106 float qa[4], qb[4];
00107 lib3ds_quat_copy(qa, a);
00108 lib3ds_quat_copy(qb, b);
00109 c[0] = qa[3] * qb[0] + qa[0] * qb[3] + qa[1] * qb[2] - qa[2] * qb[1];
00110 c[1] = qa[3] * qb[1] + qa[1] * qb[3] + qa[2] * qb[0] - qa[0] * qb[2];
00111 c[2] = qa[3] * qb[2] + qa[2] * qb[3] + qa[0] * qb[1] - qa[1] * qb[0];
00112 c[3] = qa[3] * qb[3] - qa[0] * qb[0] - qa[1] * qb[1] - qa[2] * qb[2];
00113 }
00114
00115
00119 void
00120 lib3ds_quat_scalar(float c[4], float k) {
00121 int i;
00122 for (i = 0; i < 4; ++i) {
00123 c[i] *= k;
00124 }
00125 }
00126
00127
00131 void
00132 lib3ds_quat_normalize(float c[4]) {
00133 double l, m;
00134
00135 l = sqrt(c[0] * c[0] + c[1] * c[1] + c[2] * c[2] + c[3] * c[3]);
00136 if (fabs(l) < LIB3DS_EPSILON) {
00137 c[0] = c[1] = c[2] = 0.0f;
00138 c[3] = 1.0f;
00139 } else {
00140 int i;
00141 m = 1.0f / l;
00142 for (i = 0; i < 4; ++i) {
00143 c[i] = (float)(c[i] * m);
00144 }
00145 }
00146 }
00147
00148
00152 void
00153 lib3ds_quat_inv(float c[4]) {
00154 double l, m;
00155
00156 l = sqrt(c[0] * c[0] + c[1] * c[1] + c[2] * c[2] + c[3] * c[3]);
00157 if (fabs(l) < LIB3DS_EPSILON) {
00158 c[0] = c[1] = c[2] = 0.0f;
00159 c[3] = 1.0f;
00160 } else {
00161 m = 1.0f / l;
00162 c[0] = (float)(-c[0] * m);
00163 c[1] = (float)(-c[1] * m);
00164 c[2] = (float)(-c[2] * m);
00165 c[3] = (float)(c[3] * m);
00166 }
00167 }
00168
00169
00173 float
00174 lib3ds_quat_dot(float a[4], float b[4]) {
00175 return(a[0]*b[0] + a[1]*b[1] + a[2]*b[2] + a[3]*b[3]);
00176 }
00177
00178
00179 float
00180 lib3ds_quat_norm(float c[4]) {
00181 return(c[0]*c[0] + c[1]*c[1] + c[2]*c[2] + c[3]*c[3]);
00182 }
00183
00184
00185 void
00186 lib3ds_quat_ln(float c[4]) {
00187 double om, s, t;
00188
00189 s = sqrt(c[0] * c[0] + c[1] * c[1] + c[2] * c[2]);
00190 om = atan2(s, c[3]);
00191 if (fabs(s) < LIB3DS_EPSILON) {
00192 t = 0.0f;
00193 } else {
00194 t = om / s;
00195 }
00196 {
00197 int i;
00198 for (i = 0; i < 3; ++i) {
00199 c[i] = (float)(c[i] * t);
00200 }
00201 c[3] = 0.0f;
00202 }
00203 }
00204
00205
00206 void
00207 lib3ds_quat_ln_dif(float c[4], float a[4], float b[4]) {
00208 float invp[4];
00209
00210 lib3ds_quat_copy(invp, a);
00211 lib3ds_quat_inv(invp);
00212 lib3ds_quat_mul(c, invp, b);
00213 lib3ds_quat_ln(c);
00214 }
00215
00216
00217 void
00218 lib3ds_quat_exp(float c[4]) {
00219 double om, sinom;
00220
00221 om = sqrt(c[0] * c[0] + c[1] * c[1] + c[2] * c[2]);
00222 if (fabs(om) < LIB3DS_EPSILON) {
00223 sinom = 1.0f;
00224 } else {
00225 sinom = sin(om) / om;
00226 }
00227 {
00228 int i;
00229 for (i = 0; i < 3; ++i) {
00230 c[i] = (float)(c[i] * sinom);
00231 }
00232 c[3] = (float)cos(om);
00233 }
00234 }
00235
00236
00237 void
00238 lib3ds_quat_slerp(float c[4], float a[4], float b[4], float t) {
00239 double l;
00240 double om, sinom;
00241 double sp, sq;
00242 float flip = 1.0f;
00243 int i;
00244
00245 l = a[0] * b[0] + a[1] * b[1] + a[2] * b[2] + a[3] * b[3];
00246 if (l < 0) {
00247 flip = -1.0f;
00248 l = -l;
00249 }
00250
00251 om = acos(l);
00252 sinom = sin(om);
00253 if (fabs(sinom) > LIB3DS_EPSILON) {
00254 sp = sin((1.0f - t) * om) / sinom;
00255 sq = sin(t * om) / sinom;
00256 } else {
00257 sp = 1.0f - t;
00258 sq = t;
00259 }
00260 sq *= flip;
00261 for (i = 0; i < 4; ++i) {
00262 c[i] = (float)(sp * a[i] + sq * b[i]);
00263 }
00264 }
00265
00266
00267 void
00268 lib3ds_quat_squad(float c[4], float a[4], float p[4], float q[4], float b[4], float t) {
00269 float ab[4];
00270 float pq[4];
00271
00272 lib3ds_quat_slerp(ab, a, b, t);
00273 lib3ds_quat_slerp(pq, p, q, t);
00274 lib3ds_quat_slerp(c, ab, pq, 2*t*(1 - t));
00275 }
00276
00277
00278 void
00279 lib3ds_quat_tangent(float c[4], float p[4], float q[4], float n[4]) {
00280 float dn[4], dp[4], x[4];
00281 int i;
00282
00283 lib3ds_quat_ln_dif(dn, q, n);
00284 lib3ds_quat_ln_dif(dp, q, p);
00285
00286 for (i = 0; i < 4; i++) {
00287 x[i] = -1.0f / 4.0f * (dn[i] + dp[i]);
00288 }
00289 lib3ds_quat_exp(x);
00290 lib3ds_quat_mul(c, q, x);
00291 }
00292
00293
00294 void
00295 lib3ds_quat_dump(float q[4]) {
00296 printf("%f %f %f %f\n", q[0], q[1], q[2], q[3]);
00297 }
00298