00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <lib3ds/matrix.h>
00023 #include <lib3ds/quat.h>
00024 #include <lib3ds/vector.h>
00025 #include <string.h>
00026 #include <math.h>
00027
00028
00047 void
00048 lib3ds_matrix_zero(Lib3dsMatrix m)
00049 {
00050 int i,j;
00051
00052 for (i=0; i<4; i++) {
00053 for (j=0; j<4; j++) m[i][j]=0.0f;
00054 }
00055 }
00056
00057
00065 void
00066 lib3ds_matrix_identity(Lib3dsMatrix m)
00067 {
00068 int i,j;
00069
00070 for (i=0; i<4; i++) {
00071 for (j=0; j<4; j++) m[i][j]=0.0;
00072 }
00073 for (i=0; i<4; i++) m[i][i]=1.0;
00074 }
00075
00076
00082 void
00083 lib3ds_matrix_copy(Lib3dsMatrix dest, Lib3dsMatrix src)
00084 {
00085 memcpy(dest, src, sizeof(Lib3dsMatrix));
00086 }
00087
00088
00094 void
00095 lib3ds_matrix_neg(Lib3dsMatrix m)
00096 {
00097 int i,j;
00098
00099 for (j=0; j<4; j++) {
00100 for (i=0; i<4; i++) {
00101 m[j][i]=-m[j][i];
00102 }
00103 }
00104 }
00105
00106
00112 void
00113 lib3ds_matrix_abs(Lib3dsMatrix m)
00114 {
00115 int i,j;
00116
00117 for (j=0; j<4; j++) {
00118 for (i=0; i<4; i++) {
00119 m[j][i]=(Lib3dsFloat)fabs(m[j][i]);
00120 }
00121 }
00122 }
00123
00124
00130 void
00131 lib3ds_matrix_transpose(Lib3dsMatrix m)
00132 {
00133 int i,j;
00134 Lib3dsFloat swp;
00135
00136 for (j=0; j<4; j++) {
00137 for (i=j+1; i<4; i++) {
00138 swp=m[j][i];
00139 m[j][i]=m[i][j];
00140 m[i][j]=swp;
00141 }
00142 }
00143 }
00144
00145
00151 void
00152 _lib3ds_matrix_add(Lib3dsMatrix m, Lib3dsMatrix a, Lib3dsMatrix b)
00153 {
00154 int i,j;
00155
00156 for (j=0; j<4; j++) {
00157 for (i=0; i<4; i++) {
00158 m[j][i]=a[j][i]+b[j][i];
00159 }
00160 }
00161 }
00162
00163
00173 void
00174 _lib3ds_matrix_sub(Lib3dsMatrix m, Lib3dsMatrix a, Lib3dsMatrix b)
00175 {
00176 int i,j;
00177
00178 for (j=0; j<4; j++) {
00179 for (i=0; i<4; i++) {
00180 m[j][i]=a[j][i]-b[j][i];
00181 }
00182 }
00183 }
00184
00185
00191 void
00192 lib3ds_matrix_mult(Lib3dsMatrix m, Lib3dsMatrix n)
00193 {
00194 Lib3dsMatrix tmp;
00195 int i,j,k;
00196 Lib3dsFloat ab;
00197
00198 memcpy(tmp, m, sizeof(Lib3dsMatrix));
00199 for (j=0; j<4; j++) {
00200 for (i=0; i<4; i++) {
00201 ab=0.0f;
00202 for (k=0; k<4; k++) ab+=tmp[k][i]*n[j][k];
00203 m[j][i]=ab;
00204 }
00205 }
00206 }
00207
00208
00217 void
00218 lib3ds_matrix_scalar(Lib3dsMatrix m, Lib3dsFloat k)
00219 {
00220 int i,j;
00221
00222 for (j=0; j<4; j++) {
00223 for (i=0; i<4; i++) {
00224 m[j][i]*=k;
00225 }
00226 }
00227 }
00228
00229
00230 static Lib3dsFloat
00231 det2x2(
00232 Lib3dsFloat a, Lib3dsFloat b,
00233 Lib3dsFloat c, Lib3dsFloat d)
00234 {
00235 return((a)*(d)-(b)*(c));
00236 }
00237
00238
00239 static Lib3dsFloat
00240 det3x3(
00241 Lib3dsFloat a1, Lib3dsFloat a2, Lib3dsFloat a3,
00242 Lib3dsFloat b1, Lib3dsFloat b2, Lib3dsFloat b3,
00243 Lib3dsFloat c1, Lib3dsFloat c2, Lib3dsFloat c3)
00244 {
00245 return(
00246 a1*det2x2(b2,b3,c2,c3)-
00247 b1*det2x2(a2,a3,c2,c3)+
00248 c1*det2x2(a2,a3,b2,b3)
00249 );
00250 }
00251
00252
00258 Lib3dsFloat
00259 lib3ds_matrix_det(Lib3dsMatrix m)
00260 {
00261 Lib3dsFloat a1,a2,a3,a4,b1,b2,b3,b4,c1,c2,c3,c4,d1,d2,d3,d4;
00262
00263 a1 = m[0][0];
00264 b1 = m[1][0];
00265 c1 = m[2][0];
00266 d1 = m[3][0];
00267 a2 = m[0][1];
00268 b2 = m[1][1];
00269 c2 = m[2][1];
00270 d2 = m[3][1];
00271 a3 = m[0][2];
00272 b3 = m[1][2];
00273 c3 = m[2][2];
00274 d3 = m[3][2];
00275 a4 = m[0][3];
00276 b4 = m[1][3];
00277 c4 = m[2][3];
00278 d4 = m[3][3];
00279 return(
00280 a1 * det3x3(b2, b3, b4, c2, c3, c4, d2, d3, d4)-
00281 b1 * det3x3(a2, a3, a4, c2, c3, c4, d2, d3, d4)+
00282 c1 * det3x3(a2, a3, a4, b2, b3, b4, d2, d3, d4)-
00283 d1 * det3x3(a2, a3, a4, b2, b3, b4, c2, c3, c4)
00284 );
00285 }
00286
00287
00293 void
00294 lib3ds_matrix_adjoint(Lib3dsMatrix m)
00295 {
00296 Lib3dsFloat a1,a2,a3,a4,b1,b2,b3,b4,c1,c2,c3,c4,d1,d2,d3,d4;
00297
00298 a1 = m[0][0];
00299 b1 = m[1][0];
00300 c1 = m[2][0];
00301 d1 = m[3][0];
00302 a2 = m[0][1];
00303 b2 = m[1][1];
00304 c2 = m[2][1];
00305 d2 = m[3][1];
00306 a3 = m[0][2];
00307 b3 = m[1][2];
00308 c3 = m[2][2];
00309 d3 = m[3][2];
00310 a4 = m[0][3];
00311 b4 = m[1][3];
00312 c4 = m[2][3];
00313 d4 = m[3][3];
00314 m[0][0]= det3x3 (b2, b3, b4, c2, c3, c4, d2, d3, d4);
00315 m[0][1]= -det3x3 (a2, a3, a4, c2, c3, c4, d2, d3, d4);
00316 m[0][2]= det3x3 (a2, a3, a4, b2, b3, b4, d2, d3, d4);
00317 m[0][3]= -det3x3 (a2, a3, a4, b2, b3, b4, c2, c3, c4);
00318 m[1][0]= -det3x3 (b1, b3, b4, c1, c3, c4, d1, d3, d4);
00319 m[1][1]= det3x3 (a1, a3, a4, c1, c3, c4, d1, d3, d4);
00320 m[1][2]= -det3x3 (a1, a3, a4, b1, b3, b4, d1, d3, d4);
00321 m[1][3]= det3x3 (a1, a3, a4, b1, b3, b4, c1, c3, c4);
00322 m[2][0]= det3x3 (b1, b2, b4, c1, c2, c4, d1, d2, d4);
00323 m[2][1]= -det3x3 (a1, a2, a4, c1, c2, c4, d1, d2, d4);
00324 m[2][2]= det3x3 (a1, a2, a4, b1, b2, b4, d1, d2, d4);
00325 m[2][3]= -det3x3 (a1, a2, a4, b1, b2, b4, c1, c2, c4);
00326 m[3][0]= -det3x3 (b1, b2, b3, c1, c2, c3, d1, d2, d3);
00327 m[3][1]= det3x3 (a1, a2, a3, c1, c2, c3, d1, d2, d3);
00328 m[3][2]= -det3x3 (a1, a2, a3, b1, b2, b3, d1, d2, d3);
00329 m[3][3]= det3x3 (a1, a2, a3, b1, b2, b3, c1, c2, c3);
00330 }
00331
00332
00343 Lib3dsBool
00344 lib3ds_matrix_inv(Lib3dsMatrix m)
00345 {
00346 int i,j,k;
00347 int pvt_i[4], pvt_j[4];
00348 Lib3dsFloat pvt_val;
00349 Lib3dsFloat hold;
00350 Lib3dsFloat determinat;
00351
00352 determinat = 1.0f;
00353 for (k=0; k<4; k++) {
00354
00355 pvt_val=m[k][k];
00356 pvt_i[k]=k;
00357 pvt_j[k]=k;
00358 for (i=k; i<4; i++) {
00359 for (j=k; j<4; j++) {
00360 if (fabs(m[i][j]) > fabs(pvt_val)) {
00361 pvt_i[k]=i;
00362 pvt_j[k]=j;
00363 pvt_val=m[i][j];
00364 }
00365 }
00366 }
00367
00368
00369 determinat*=pvt_val;
00370 if (fabs(determinat)<LIB3DS_EPSILON) {
00371 return(LIB3DS_FALSE);
00372 }
00373
00374
00375 i=pvt_i[k];
00376 if (i!=k) {
00377 for (j=0; j<4; j++) {
00378 hold=-m[k][j];
00379 m[k][j]=m[i][j];
00380 m[i][j]=hold;
00381 }
00382 }
00383
00384
00385 j=pvt_j[k];
00386 if (j!=k) {
00387 for (i=0; i<4; i++) {
00388 hold=-m[i][k];
00389 m[i][k]=m[i][j];
00390 m[i][j]=hold;
00391 }
00392 }
00393
00394
00395 for (i=0; i<4; i++) {
00396 if (i!=k) m[i][k]/=( -pvt_val) ;
00397 }
00398
00399
00400 for (i=0; i<4; i++) {
00401 hold = m[i][k];
00402 for (j=0; j<4; j++) {
00403 if (i!=k && j!=k) m[i][j]+=hold*m[k][j];
00404 }
00405 }
00406
00407
00408 for (j=0; j<4; j++) {
00409 if (j!=k) m[k][j]/=pvt_val;
00410 }
00411
00412
00413 m[k][k] = 1.0f/pvt_val;
00414 }
00415
00416
00417
00418 for (k=4-2; k>=0; k--) {
00419 i=pvt_j[k];
00420 if (i!=k) {
00421 for(j=0; j<4; j++) {
00422 hold = m[k][j];
00423 m[k][j]=-m[i][j];
00424 m[i][j]=hold;
00425 }
00426 }
00427
00428 j=pvt_i[k];
00429 if (j!=k)
00430 for (i=0; i<4; i++) {
00431 hold=m[i][k];
00432 m[i][k]=-m[i][j];
00433 m[i][j]=hold;
00434 }
00435 }
00436 return(LIB3DS_TRUE);
00437 }
00438
00439
00445 void
00446 lib3ds_matrix_translate_xyz(Lib3dsMatrix m, Lib3dsFloat x, Lib3dsFloat y, Lib3dsFloat z)
00447 {
00448 int i;
00449
00450 for (i=0; i<3; i++) {
00451 m[3][i]+= m[0][i]*x + m[1][i]*y + m[2][i]*z;
00452 }
00453 }
00454
00455
00461 void
00462 lib3ds_matrix_translate(Lib3dsMatrix m, Lib3dsVector t)
00463 {
00464 int i;
00465
00466 for (i=0; i<3; i++) {
00467 m[3][i]+= m[0][i]*t[0] + m[1][i]*t[1] + m[2][i]*t[2];
00468 }
00469 }
00470
00471
00477 void
00478 lib3ds_matrix_scale_xyz(Lib3dsMatrix m, Lib3dsFloat x, Lib3dsFloat y, Lib3dsFloat z)
00479 {
00480 int i;
00481
00482 for (i=0; i<4; i++) {
00483 m[0][i]*=x;
00484 m[1][i]*=y;
00485 m[2][i]*=z;
00486 }
00487 }
00488
00489
00495 void
00496 lib3ds_matrix_scale(Lib3dsMatrix m, Lib3dsVector s)
00497 {
00498 int i;
00499
00500 for (i=0; i<4; i++) {
00501 m[0][i]*=s[0];
00502 m[1][i]*=s[1];
00503 m[2][i]*=s[2];
00504 }
00505 }
00506
00507
00513 void
00514 lib3ds_matrix_rotate_x(Lib3dsMatrix m, Lib3dsFloat phi)
00515 {
00516 Lib3dsFloat SinPhi,CosPhi;
00517 Lib3dsFloat a1[4],a2[4];
00518
00519 SinPhi=(Lib3dsFloat)sin(phi);
00520 CosPhi=(Lib3dsFloat)cos(phi);
00521 memcpy(a1,m[1],4*sizeof(Lib3dsFloat));
00522 memcpy(a2,m[2],4*sizeof(Lib3dsFloat));
00523 m[1][0]=CosPhi*a1[0]+SinPhi*a2[0];
00524 m[1][1]=CosPhi*a1[1]+SinPhi*a2[1];
00525 m[1][2]=CosPhi*a1[2]+SinPhi*a2[2];
00526 m[1][3]=CosPhi*a1[3]+SinPhi*a2[3];
00527 m[2][0]=-SinPhi*a1[0]+CosPhi*a2[0];
00528 m[2][1]=-SinPhi*a1[1]+CosPhi*a2[1];
00529 m[2][2]=-SinPhi*a1[2]+CosPhi*a2[2];
00530 m[2][3]=-SinPhi*a1[3]+CosPhi*a2[3];
00531 }
00532
00533
00539 void
00540 lib3ds_matrix_rotate_y(Lib3dsMatrix m, Lib3dsFloat phi)
00541 {
00542 Lib3dsFloat SinPhi,CosPhi;
00543 Lib3dsFloat a0[4],a2[4];
00544
00545 SinPhi=(Lib3dsFloat)sin(phi);
00546 CosPhi=(Lib3dsFloat)cos(phi);
00547 memcpy(a0,m[0],4*sizeof(Lib3dsFloat));
00548 memcpy(a2,m[2],4*sizeof(Lib3dsFloat));
00549 m[0][0]=CosPhi*a0[0]-SinPhi*a2[0];
00550 m[0][1]=CosPhi*a0[1]-SinPhi*a2[1];
00551 m[0][2]=CosPhi*a0[2]-SinPhi*a2[2];
00552 m[0][3]=CosPhi*a0[3]-SinPhi*a2[3];
00553 m[2][0]=SinPhi*a0[0]+CosPhi*a2[0];
00554 m[2][1]=SinPhi*a0[1]+CosPhi*a2[1];
00555 m[2][2]=SinPhi*a0[2]+CosPhi*a2[2];
00556 m[2][3]=SinPhi*a0[3]+CosPhi*a2[3];
00557 }
00558
00559
00565 void
00566 lib3ds_matrix_rotate_z(Lib3dsMatrix m, Lib3dsFloat phi)
00567 {
00568 Lib3dsFloat SinPhi,CosPhi;
00569 Lib3dsFloat a0[4],a1[4];
00570
00571 SinPhi=(Lib3dsFloat)sin(phi);
00572 CosPhi=(Lib3dsFloat)cos(phi);
00573 memcpy(a0,m[0],4*sizeof(Lib3dsFloat));
00574 memcpy(a1,m[1],4*sizeof(Lib3dsFloat));
00575 m[0][0]=CosPhi*a0[0]+SinPhi*a1[0];
00576 m[0][1]=CosPhi*a0[1]+SinPhi*a1[1];
00577 m[0][2]=CosPhi*a0[2]+SinPhi*a1[2];
00578 m[0][3]=CosPhi*a0[3]+SinPhi*a1[3];
00579 m[1][0]=-SinPhi*a0[0]+CosPhi*a1[0];
00580 m[1][1]=-SinPhi*a0[1]+CosPhi*a1[1];
00581 m[1][2]=-SinPhi*a0[2]+CosPhi*a1[2];
00582 m[1][3]=-SinPhi*a0[3]+CosPhi*a1[3];
00583 }
00584
00585
00591 void
00592 lib3ds_matrix_rotate(Lib3dsMatrix m, Lib3dsQuat q)
00593 {
00594 Lib3dsFloat s,xs,ys,zs,wx,wy,wz,xx,xy,xz,yy,yz,zz,l;
00595 Lib3dsMatrix R;
00596
00597 l=q[0]*q[0] + q[1]*q[1] + q[2]*q[2] + q[3]*q[3];
00598 if (fabs(l)<LIB3DS_EPSILON) {
00599 s=1.0f;
00600 }
00601 else {
00602 s=2.0f/l;
00603 }
00604
00605 xs = q[0] * s; ys = q[1] * s; zs = q[2] * s;
00606 wx = q[3] * xs; wy = q[3] * ys; wz = q[3] * zs;
00607 xx = q[0] * xs; xy = q[0] * ys; xz = q[0] * zs;
00608 yy = q[1] * ys; yz = q[1] * zs; zz = q[2] * zs;
00609
00610 R[0][0]=1.0f - (yy +zz);
00611 R[1][0]=xy - wz;
00612 R[2][0]=xz + wy;
00613 R[0][1]=xy + wz;
00614 R[1][1]=1.0f - (xx +zz);
00615 R[2][1]=yz - wx;
00616 R[0][2]=xz - wy;
00617 R[1][2]=yz + wx;
00618 R[2][2]=1.0f - (xx + yy);
00619 R[3][0]=R[3][1]=R[3][2]=R[0][3]=R[1][3]=R[2][3]=0.0f;
00620 R[3][3]=1.0f;
00621
00622 lib3ds_matrix_mult(m,R);
00623 }
00624
00625
00631 void
00632 lib3ds_matrix_rotate_axis(Lib3dsMatrix m, Lib3dsVector axis, Lib3dsFloat angle)
00633 {
00634 Lib3dsQuat q;
00635
00636 lib3ds_quat_axis_angle(q,axis,angle);
00637 lib3ds_matrix_rotate(m,q);
00638 }
00639
00640
00655 void
00656 lib3ds_matrix_camera(Lib3dsMatrix matrix, Lib3dsVector pos,
00657 Lib3dsVector tgt, Lib3dsFloat roll)
00658 {
00659 Lib3dsMatrix M;
00660 Lib3dsVector x, y, z;
00661
00662 lib3ds_vector_sub(y, tgt, pos);
00663 lib3ds_vector_normalize(y);
00664
00665 if (y[0] != 0. || y[1] != 0) {
00666 z[0] = 0;
00667 z[1] = 0;
00668 z[2] = 1.0;
00669 }
00670 else {
00671 z[0] = -1.0;
00672 z[1] = 0;
00673 z[2] = 0;
00674 }
00675
00676 lib3ds_vector_cross(x, y, z);
00677 lib3ds_vector_cross(z, x, y);
00678 lib3ds_vector_normalize(x);
00679 lib3ds_vector_normalize(z);
00680
00681 lib3ds_matrix_identity(M);
00682 M[0][0] = x[0];
00683 M[1][0] = x[1];
00684 M[2][0] = x[2];
00685 M[0][1] = y[0];
00686 M[1][1] = y[1];
00687 M[2][1] = y[2];
00688 M[0][2] = z[0];
00689 M[1][2] = z[1];
00690 M[2][2] = z[2];
00691
00692 lib3ds_matrix_identity(matrix);
00693 lib3ds_matrix_rotate_y(matrix, roll);
00694 lib3ds_matrix_mult(matrix, M);
00695 lib3ds_matrix_translate_xyz(matrix, -pos[0],-pos[1],-pos[2]);
00696 }
00697
00698
00702 void
00703 lib3ds_matrix_dump(Lib3dsMatrix matrix)
00704 {
00705 int i,j;
00706
00707 for (i=0; i<4; ++i) {
00708 for (j=0; j<4; ++j) {
00709 printf("%f ", matrix[j][i]);
00710 }
00711 printf("\n");
00712 }
00713 }
00714
00715
00716
00717
00718