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
00030 void
00031 lib3ds_matrix_zero(float m[4][4]) {
00032 int i, j;
00033
00034 for (i = 0; i < 4; i++) {
00035 for (j = 0; j < 4; j++) m[i][j] = 0.0f;
00036 }
00037 }
00038
00039
00045 void
00046 lib3ds_matrix_identity(float m[4][4]) {
00047 int i, j;
00048
00049 for (i = 0; i < 4; i++) {
00050 for (j = 0; j < 4; j++) m[i][j] = 0.0;
00051 }
00052 for (i = 0; i < 4; i++) m[i][i] = 1.0;
00053 }
00054
00055
00059 void
00060 lib3ds_matrix_copy(float dest[4][4], float src[4][4]) {
00061 memcpy(dest, src, 16 * sizeof(float));
00062 }
00063
00064
00068 void
00069 lib3ds_matrix_neg(float m[4][4]) {
00070 int i, j;
00071
00072 for (j = 0; j < 4; j++) {
00073 for (i = 0; i < 4; i++) {
00074 m[j][i] = -m[j][i];
00075 }
00076 }
00077 }
00078
00079
00083 void
00084 lib3ds_matrix_transpose(float m[4][4]) {
00085 int i, j;
00086 float swp;
00087
00088 for (j = 0; j < 4; j++) {
00089 for (i = j + 1; i < 4; i++) {
00090 swp = m[j][i];
00091 m[j][i] = m[i][j];
00092 m[i][j] = swp;
00093 }
00094 }
00095 }
00096
00097
00101 void
00102 lib3ds_matrix_add(float m[4][4], float a[4][4], float b[4][4]) {
00103 int i, j;
00104
00105 for (j = 0; j < 4; j++) {
00106 for (i = 0; i < 4; i++) {
00107 m[j][i] = a[j][i] + b[j][i];
00108 }
00109 }
00110 }
00111
00112
00120 void
00121 lib3ds_matrix_sub(float m[4][4], float a[4][4], float b[4][4]) {
00122 int i, j;
00123
00124 for (j = 0; j < 4; j++) {
00125 for (i = 0; i < 4; i++) {
00126 m[j][i] = a[j][i] - b[j][i];
00127 }
00128 }
00129 }
00130
00131
00135 void
00136 lib3ds_matrix_mult(float m[4][4], float a[4][4], float b[4][4]) {
00137 float tmp[4][4];
00138 int i, j, k;
00139 float ab;
00140
00141 memcpy(tmp, a, 16 * sizeof(float));
00142 for (j = 0; j < 4; j++) {
00143 for (i = 0; i < 4; i++) {
00144 ab = 0.0f;
00145 for (k = 0; k < 4; k++) ab += tmp[k][i] * b[j][k];
00146 m[j][i] = ab;
00147 }
00148 }
00149 }
00150
00151
00158 void
00159 lib3ds_matrix_scalar(float m[4][4], float k) {
00160 int i, j;
00161
00162 for (j = 0; j < 4; j++) {
00163 for (i = 0; i < 4; i++) {
00164 m[j][i] *= k;
00165 }
00166 }
00167 }
00168
00169
00170 static float
00171 det2x2(
00172 float a, float b,
00173 float c, float d) {
00174 return((a)*(d) - (b)*(c));
00175 }
00176
00177
00178 static float
00179 det3x3(
00180 float a1, float a2, float a3,
00181 float b1, float b2, float b3,
00182 float c1, float c2, float c3) {
00183 return(
00184 a1*det2x2(b2, b3, c2, c3) -
00185 b1*det2x2(a2, a3, c2, c3) +
00186 c1*det2x2(a2, a3, b2, b3)
00187 );
00188 }
00189
00190
00194 float
00195 lib3ds_matrix_det(float m[4][4]) {
00196 float a1, a2, a3, a4, b1, b2, b3, b4, c1, c2, c3, c4, d1, d2, d3, d4;
00197
00198 a1 = m[0][0];
00199 b1 = m[1][0];
00200 c1 = m[2][0];
00201 d1 = m[3][0];
00202 a2 = m[0][1];
00203 b2 = m[1][1];
00204 c2 = m[2][1];
00205 d2 = m[3][1];
00206 a3 = m[0][2];
00207 b3 = m[1][2];
00208 c3 = m[2][2];
00209 d3 = m[3][2];
00210 a4 = m[0][3];
00211 b4 = m[1][3];
00212 c4 = m[2][3];
00213 d4 = m[3][3];
00214 return(
00215 a1 * det3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4) -
00216 b1 * det3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4) +
00217 c1 * det3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4) -
00218 d1 * det3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4)
00219 );
00220 }
00221
00222
00232 int
00233 lib3ds_matrix_inv(float m[4][4]) {
00234 int i, j, k;
00235 int pvt_i[4], pvt_j[4];
00236 float pvt_val;
00237 float hold;
00238 float determinat;
00239
00240 determinat = 1.0f;
00241 for (k = 0; k < 4; k++) {
00242
00243 pvt_val = m[k][k];
00244 pvt_i[k] = k;
00245 pvt_j[k] = k;
00246 for (i = k; i < 4; i++) {
00247 for (j = k; j < 4; j++) {
00248 if (fabs(m[i][j]) > fabs(pvt_val)) {
00249 pvt_i[k] = i;
00250 pvt_j[k] = j;
00251 pvt_val = m[i][j];
00252 }
00253 }
00254 }
00255
00256
00257 determinat *= pvt_val;
00258 if (fabs(determinat) < LIB3DS_EPSILON) {
00259 return(FALSE);
00260 }
00261
00262
00263 i = pvt_i[k];
00264 if (i != k) {
00265 for (j = 0; j < 4; j++) {
00266 hold = -m[k][j];
00267 m[k][j] = m[i][j];
00268 m[i][j] = hold;
00269 }
00270 }
00271
00272
00273 j = pvt_j[k];
00274 if (j != k) {
00275 for (i = 0; i < 4; i++) {
00276 hold = -m[i][k];
00277 m[i][k] = m[i][j];
00278 m[i][j] = hold;
00279 }
00280 }
00281
00282
00283 for (i = 0; i < 4; i++) {
00284 if (i != k) m[i][k] /= (-pvt_val) ;
00285 }
00286
00287
00288 for (i = 0; i < 4; i++) {
00289 hold = m[i][k];
00290 for (j = 0; j < 4; j++) {
00291 if (i != k && j != k) m[i][j] += hold * m[k][j];
00292 }
00293 }
00294
00295
00296 for (j = 0; j < 4; j++) {
00297 if (j != k) m[k][j] /= pvt_val;
00298 }
00299
00300
00301 m[k][k] = 1.0f / pvt_val;
00302 }
00303
00304
00305
00306 for (k = 4 - 2; k >= 0; k--) {
00307 i = pvt_j[k];
00308 if (i != k) {
00309 for (j = 0; j < 4; j++) {
00310 hold = m[k][j];
00311 m[k][j] = -m[i][j];
00312 m[i][j] = hold;
00313 }
00314 }
00315
00316 j = pvt_i[k];
00317 if (j != k)
00318 for (i = 0; i < 4; i++) {
00319 hold = m[i][k];
00320 m[i][k] = -m[i][j];
00321 m[i][j] = hold;
00322 }
00323 }
00324 return(TRUE);
00325 }
00326
00327
00331 void
00332 lib3ds_matrix_translate(float m[4][4], float x, float y, float z) {
00333 int i;
00334
00335 for (i = 0; i < 3; i++) {
00336 m[3][i] += m[0][i] * x + m[1][i] * y + m[2][i] * z;
00337 }
00338 }
00339
00340
00344 void
00345 lib3ds_matrix_scale(float m[4][4], float x, float y, float z) {
00346 int i;
00347
00348 for (i = 0; i < 4; i++) {
00349 m[0][i] *= x;
00350 m[1][i] *= y;
00351 m[2][i] *= z;
00352 }
00353 }
00354
00355
00359 void
00360 lib3ds_matrix_rotate_quat(float m[4][4], float q[4]) {
00361 float s, xs, ys, zs, wx, wy, wz, xx, xy, xz, yy, yz, zz, l;
00362 float R[4][4];
00363
00364 l = q[0] * q[0] + q[1] * q[1] + q[2] * q[2] + q[3] * q[3];
00365 if (fabs(l) < LIB3DS_EPSILON) {
00366 s = 1.0f;
00367 } else {
00368 s = 2.0f / l;
00369 }
00370
00371 xs = q[0] * s;
00372 ys = q[1] * s;
00373 zs = q[2] * s;
00374 wx = q[3] * xs;
00375 wy = q[3] * ys;
00376 wz = q[3] * zs;
00377 xx = q[0] * xs;
00378 xy = q[0] * ys;
00379 xz = q[0] * zs;
00380 yy = q[1] * ys;
00381 yz = q[1] * zs;
00382 zz = q[2] * zs;
00383
00384 R[0][0] = 1.0f - (yy + zz);
00385 R[1][0] = xy - wz;
00386 R[2][0] = xz + wy;
00387 R[0][1] = xy + wz;
00388 R[1][1] = 1.0f - (xx + zz);
00389 R[2][1] = yz - wx;
00390 R[0][2] = xz - wy;
00391 R[1][2] = yz + wx;
00392 R[2][2] = 1.0f - (xx + yy);
00393 R[3][0] = R[3][1] = R[3][2] = R[0][3] = R[1][3] = R[2][3] = 0.0f;
00394 R[3][3] = 1.0f;
00395
00396 lib3ds_matrix_mult(m, m, R);
00397 }
00398
00399
00403 void
00404 lib3ds_matrix_rotate(float m[4][4], float angle, float ax, float ay, float az) {
00405 float q[4];
00406 float axis[3];
00407
00408 lib3ds_vector_make(axis, ax, ay, az);
00409 lib3ds_quat_axis_angle(q, axis, angle);
00410 lib3ds_matrix_rotate_quat(m, q);
00411 }
00412
00413
00426 void
00427 lib3ds_matrix_camera(float matrix[4][4], float pos[3], float tgt[3], float roll) {
00428 float M[4][4];
00429 float x[3], y[3], z[3];
00430
00431 lib3ds_vector_sub(y, tgt, pos);
00432 lib3ds_vector_normalize(y);
00433
00434 if (y[0] != 0. || y[1] != 0) {
00435 z[0] = 0;
00436 z[1] = 0;
00437 z[2] = 1.0;
00438 } else {
00439 z[0] = -1.0;
00440 z[1] = 0;
00441 z[2] = 0;
00442 }
00443
00444 lib3ds_vector_cross(x, y, z);
00445 lib3ds_vector_cross(z, x, y);
00446 lib3ds_vector_normalize(x);
00447 lib3ds_vector_normalize(z);
00448
00449 lib3ds_matrix_identity(M);
00450 M[0][0] = x[0];
00451 M[1][0] = x[1];
00452 M[2][0] = x[2];
00453 M[0][1] = y[0];
00454 M[1][1] = y[1];
00455 M[2][1] = y[2];
00456 M[0][2] = z[0];
00457 M[1][2] = z[1];
00458 M[2][2] = z[2];
00459
00460 lib3ds_matrix_identity(matrix);
00461 lib3ds_matrix_rotate(matrix, roll, 0, 1, 0);
00462 lib3ds_matrix_mult(matrix, matrix, M);
00463 lib3ds_matrix_translate(matrix, -pos[0], -pos[1], -pos[2]);
00464 }
00465
00466
00467
00468
00469
00470