00001
00002 #include "revolt.h"
00003 #include "main.h"
00004 #include "geom.h"
00005 #include "Gaussian.h"
00006
00007
00008
00009 REAL BaseGeomPers = 640;
00010 REAL ScreenLeftClip, ScreenRightClip, ScreenTopClip, ScreenBottomClip;
00011 REAL ScreenLeftClipGuard, ScreenRightClipGuard, ScreenTopClipGuard, ScreenBottomClipGuard;
00012 MAT IdentityMatrix = {ONE, ZERO, ZERO, ZERO, ONE, ZERO, ZERO, ZERO, ONE};
00013
00014 MAT Identity = {ONE, ZERO, ZERO, ZERO, ONE, ZERO, ZERO, ZERO, ONE};
00015 VEC ZeroVector = {ZERO, ZERO, ZERO};
00016 VEC DownVec = {ZERO, ONE, ZERO};
00017 VEC UpVec = {ZERO, -ONE, ZERO};
00018 VEC RightVec = {ONE, ZERO, ZERO};
00019 VEC LeftVec = {-ONE, ZERO, ZERO};
00020 VEC LookVec = {ZERO, ZERO, ONE};
00021 VEC NegLookVec = {ZERO, ZERO, -ONE};
00022 QUATERNION IdentityQuat = {ZERO, ZERO, ZERO, ONE};
00023
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00038
00039 #pragma optimize("", off)
00040
00041 REAL NearPointOnLine(VEC *r0, VEC *r1, VEC *p, VEC *rN)
00042 {
00043 REAL dRdR, rPdR, t;
00044 VEC dR, rP;
00045
00046 VecMinusVec(r0, p, &rP);
00047 VecMinusVec(r1, r0, &dR);
00048
00049 dRdR = VecDotVec(&dR, &dR);
00050 rPdR = VecDotVec(&rP, &dR);
00051
00052 t = - rPdR / dRdR;
00053
00054 VecPlusScalarVec(r0, t, &dR, rN);
00055
00056 return t;
00057 }
00058 #pragma optimize("", on)
00059
00061
00063
00064 void RotMatrixX(MAT *mat, REAL rot)
00065 {
00066 REAL c, s;
00067
00068 rot *= RAD;
00069 c = (REAL)cos(rot);
00070 s = (REAL)sin(rot);
00071
00072 mat->m[RX] = 1;
00073 mat->m[RY] = 0;
00074 mat->m[RZ] = 0;
00075
00076 mat->m[UX] = 0;
00077 mat->m[UY] = c;
00078 mat->m[UZ] = -s;
00079
00080 mat->m[LX] = 0;
00081 mat->m[LY] = s;
00082 mat->m[LZ] = c;
00083 }
00084
00086
00088
00089 void RotMatrixY(MAT *mat, REAL rot)
00090 {
00091 REAL c, s;
00092
00093 rot *= RAD;
00094 c = (REAL)cos(rot);
00095 s = (REAL)sin(rot);
00096
00097 mat->m[RX] = c;
00098 mat->m[RY] = 0;
00099 mat->m[RZ] = s;
00100
00101 mat->m[UX] = 0;
00102 mat->m[UY] = 1;
00103 mat->m[UZ] = 0;
00104
00105 mat->m[LX] = -s;
00106 mat->m[LY] = 0;
00107 mat->m[LZ] = c;
00108 }
00109
00111
00113
00114 void RotMatrixZ(MAT *mat, REAL rot)
00115 {
00116 REAL c, s;
00117
00118 rot *= RAD;
00119 c = (REAL)cos(rot);
00120 s = (REAL)sin(rot);
00121
00122 mat->m[RX] = c;
00123 mat->m[RY] = -s;
00124 mat->m[RZ] = 0;
00125
00126 mat->m[UX] = s;
00127 mat->m[UY] = c;
00128 mat->m[UZ] = 0;
00129
00130 mat->m[LX] = 0;
00131 mat->m[LY] = 0;
00132 mat->m[LZ] = 1;
00133 }
00134
00136
00138
00139 void RotMatrixZYX(MAT *mat, REAL x, REAL y, REAL z)
00140 {
00141 REAL cx, cy, cz, sx, sy, sz;
00142
00143 cx = (REAL)cos(x * RAD);
00144 cy = (REAL)cos(-y * RAD);
00145 cz = (REAL)cos(z * RAD);
00146 sx = (REAL)sin(x * RAD);
00147 sy = (REAL)sin(-y * RAD);
00148 sz = (REAL)sin(z * RAD);
00149
00150 mat->m[RX] = cy * cz;
00151 mat->m[RY] = -cy * sz;
00152 mat->m[RZ] = -sy;
00153
00154 mat->m[UX] = cx * sz - sx * sy * cz;
00155 mat->m[UY] = sx * sy * sz + cx * cz;
00156 mat->m[UZ] = -sx * cy;
00157
00158 mat->m[LX] = cx * sy * cz + sx * sz;
00159 mat->m[LY] = sx * cz - cx * sy * sz;
00160 mat->m[LZ] = cx * cy;
00161 }
00162
00164
00166
00167 void RotVector(MAT *mat, VEC *in, VEC *out)
00168 {
00169 out->v[X] = in->v[X] * mat->m[RX] + in->v[Y] * mat->m[UX] + in->v[Z] * mat->m[LX];
00170 out->v[Y] = in->v[X] * mat->m[RY] + in->v[Y] * mat->m[UY] + in->v[Z] * mat->m[LY];
00171 out->v[Z] = in->v[X] * mat->m[RZ] + in->v[Y] * mat->m[UZ] + in->v[Z] * mat->m[LZ];
00172 }
00173
00175
00177
00178 void TransposeRotVector(MAT *mat, VEC *in, VEC *out)
00179 {
00180 out->v[X] = in->v[X] * mat->m[RX] + in->v[Y] * mat->m[RY] + in->v[Z] * mat->m[RZ];
00181 out->v[Y] = in->v[X] * mat->m[UX] + in->v[Y] * mat->m[UY] + in->v[Z] * mat->m[UZ];
00182 out->v[Z] = in->v[X] * mat->m[LX] + in->v[Y] * mat->m[LY] + in->v[Z] * mat->m[LZ];
00183 }
00184
00186
00188
00189 void RotTransVector(MAT *mat, VEC *trans, VEC *in, VEC *out)
00190 {
00191 out->v[X] = in->v[X] * mat->m[RX] + in->v[Y] * mat->m[UX] + in->v[Z] * mat->m[LX] + trans->v[X];
00192 out->v[Y] = in->v[X] * mat->m[RY] + in->v[Y] * mat->m[UY] + in->v[Z] * mat->m[LY] + trans->v[Y];
00193 out->v[Z] = in->v[X] * mat->m[RZ] + in->v[Y] * mat->m[UZ] + in->v[Z] * mat->m[LZ] + trans->v[Z];
00194 }
00195
00197
00199
00200 void RotTransPersVector(MAT *mat, VEC *trans, VEC *in, REAL *out)
00201 {
00202 REAL z;
00203
00204 z = in->v[X] * mat->m[RZ] + in->v[Y] * mat->m[UZ] + in->v[Z] * mat->m[LZ] + trans->v[Z];
00205 if (z < 1) z = 1;
00206
00207 out[0] = (in->v[X] * mat->m[RX] + in->v[Y] * mat->m[UX] + in->v[Z] * mat->m[LX] + trans->v[X]) / z + RenderSettings.GeomCentreX;
00208 out[1] = (in->v[X] * mat->m[RY] + in->v[Y] * mat->m[UY] + in->v[Z] * mat->m[LY] + trans->v[Y]) / z + RenderSettings.GeomCentreY;
00209
00210 out[3] = 1 / z;
00211 out[2] = GET_ZBUFFER(z);
00212 }
00213
00215
00217
00218 void RotTransPersVectorZleave(MAT *mat, VEC *trans, VEC *in, REAL *out)
00219 {
00220 REAL z;
00221
00222 z = in->v[X] * mat->m[RZ] + in->v[Y] * mat->m[UZ] + in->v[Z] * mat->m[LZ] + trans->v[Z];
00223 out[0] = (in->v[X] * mat->m[RX] + in->v[Y] * mat->m[UX] + in->v[Z] * mat->m[LX] + trans->v[X]) / z + RenderSettings.GeomCentreX;
00224 out[1] = (in->v[X] * mat->m[RY] + in->v[Y] * mat->m[UY] + in->v[Z] * mat->m[LY] + trans->v[Y]) / z + RenderSettings.GeomCentreY;
00225
00226 out[3] = 1 / z;
00227 out[2] = GET_ZBUFFER(z);
00228 }
00229
00231
00233
00234 void RotTransPersVectorZbias(MAT *mat, VEC *trans, VEC *in, REAL *out, REAL zbias)
00235 {
00236 REAL z;
00237
00238 z = in->v[X] * mat->m[RZ] + in->v[Y] * mat->m[UZ] + in->v[Z] * mat->m[LZ] + trans->v[Z];
00239 if (z < 1) z = 1;
00240
00241 out[0] = (in->v[X] * mat->m[RX] + in->v[Y] * mat->m[UX] + in->v[Z] * mat->m[LX] + trans->v[X]) / z + RenderSettings.GeomCentreX;
00242 out[1] = (in->v[X] * mat->m[RY] + in->v[Y] * mat->m[UY] + in->v[Z] * mat->m[LY] + trans->v[Y]) / z + RenderSettings.GeomCentreY;
00243
00244 out[3] = 1 / z;
00245 out[2] = GET_ZBUFFER(z + zbias);
00246 }
00247
00249
00251
00252 void MulMatrix(MAT *one, MAT *two, MAT *out)
00253 {
00254 char i, j, k;
00255
00256 for (i = 0 ; i < 9 ; i++)
00257 out->m[i] = 0;
00258
00259 for (i = 0 ; i < 3 ; i++)
00260 for (j = 0 ; j < 3 ; j++)
00261 for (k = 0 ; k < 3 ; k++)
00262 out->m[i * 3 + j] += one->m[k * 3 + j] * two->m[i * 3 + k];
00263 }
00264
00266
00268
00269 void TransposeMatrix(MAT *in, MAT *out)
00270 {
00271 out->m[RX] = in->m[RX];
00272 out->m[RY] = in->m[UX];
00273 out->m[RZ] = in->m[LX];
00274 out->m[UX] = in->m[RY];
00275 out->m[UY] = in->m[UY];
00276 out->m[UZ] = in->m[LY];
00277 out->m[LX] = in->m[RZ];
00278 out->m[LY] = in->m[UZ];
00279 out->m[LZ] = in->m[LZ];
00280 }
00281
00283
00285
00286 void BuildLookMatrixForward(VEC *pos, VEC *look, MAT *mat)
00287 {
00288
00289
00290
00291 SubVector(look, pos, &mat->mv[Z]);
00292 NormalizeVector(&mat->mv[Z]);
00293
00294
00295
00296 mat->m[RX] = mat->m[LZ];
00297 mat->m[RY] = 0;
00298 mat->m[RZ] = -mat->m[LX];
00299 NormalizeVector(&mat->mv[X]);
00300
00301
00302
00303 CrossProduct(&mat->mv[Z], &mat->mv[X], &mat->mv[Y]);
00304 }
00305
00307
00309
00310 void BuildLookMatrixDown(VEC *pos, VEC *look, MAT *mat)
00311 {
00312
00313
00314
00315 SubVector(look, pos, &mat->mv[Y]);
00316 NormalizeVector(&mat->mv[Y]);
00317
00318
00319
00320 mat->m[RX] = -mat->m[UZ];
00321 mat->m[RY] = 0;
00322 mat->m[RZ] = mat->m[UX];
00323 NormalizeVector(&mat->mv[X]);
00324
00325
00326
00327 CrossProduct(&mat->mv[X], &mat->mv[Y], &mat->mv[Z]);
00328 }
00329
00331
00333
00334 void CopyMatrix(MAT *src, MAT *dest)
00335 {
00336 dest->m[XX] = src->m[XX];
00337 dest->m[XY] = src->m[XY];
00338 dest->m[XZ] = src->m[XZ];
00339
00340 dest->m[YX] = src->m[YX];
00341 dest->m[YY] = src->m[YY];
00342 dest->m[YZ] = src->m[YZ];
00343
00344 dest->m[ZX] = src->m[ZX];
00345 dest->m[ZY] = src->m[ZY];
00346 dest->m[ZZ] = src->m[ZZ];
00347 }
00348
00350
00351
00352
00354
00355 void BuildMatrixFromLook(MAT *matrix)
00356 {
00357
00358
00359 if (fabs(matrix->m[LX]) < fabs(matrix->m[LY])) {
00360 if (fabs(matrix->m[LX]) < fabs(matrix->m[LZ])) {
00361 matrix->m[UX] = 0.0f;
00362 matrix->m[UY] = matrix->m[LZ];
00363 matrix->m[UZ] = -matrix->m[LY];
00364 } else {
00365 matrix->m[UX] = -matrix->m[LY];
00366 matrix->m[UY] = matrix->m[LX];
00367 matrix->m[UZ] = 0.0f;
00368 }
00369 } else {
00370 if (fabs(matrix->m[LY]) < fabs(matrix->m[LZ])) {
00371 matrix->m[UX] = matrix->m[LZ];
00372 matrix->m[UY] = 0.0f;
00373 matrix->m[UZ] = -matrix->m[LX];
00374 } else {
00375 matrix->m[UX] = matrix->m[LY];
00376 matrix->m[UY] = -matrix->m[LX];
00377 matrix->m[UZ] = 0.0f;
00378 }
00379 }
00380 NormalizeVector(&matrix->mv[U])
00381
00382
00383 CrossProduct(&matrix->mv[L], &matrix->mv[U], &matrix->mv[R]);
00384 }
00385
00386
00387 void BuildMatrixFromUp(MAT *matrix)
00388 {
00389
00390
00391 if (fabs(matrix->m[UX]) < fabs(matrix->m[UY])) {
00392 if (fabs(matrix->m[UX]) < fabs(matrix->m[UZ])) {
00393 matrix->m[RX] = 0.0f;
00394 matrix->m[RY] = matrix->m[UZ];
00395 matrix->m[RZ] = -matrix->m[UY];
00396 } else {
00397 matrix->m[RX] = -matrix->m[UY];
00398 matrix->m[RY] = matrix->m[UX];
00399 matrix->m[RZ] = 0.0f;
00400 }
00401 } else {
00402 if (fabs(matrix->m[UY]) < fabs(matrix->m[UZ])) {
00403 matrix->m[RX] = matrix->m[UZ];
00404 matrix->m[RY] = 0.0f;
00405 matrix->m[RZ] = -matrix->m[UX];
00406 } else {
00407 matrix->m[RX] = matrix->m[UY];
00408 matrix->m[RY] = -matrix->m[UX];
00409 matrix->m[RZ] = 0.0f;
00410 }
00411 }
00412 NormalizeVector(&matrix->mv[R])
00413
00414
00415 CrossProduct(&matrix->mv[R], &matrix->mv[U], &matrix->mv[L]);
00416 }
00417
00418
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00431
00432 void Interpolate3D(VEC *r0, VEC *r1, VEC *r2, REAL t, VEC *rt)
00433 {
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443 REAL tSq = t * t;
00444
00445 rt->v[X] = r0->v[X] * (2.0f * tSq - 3.0f * t + 1.0f) +
00446 r1->v[X] * (-4.0f * tSq + 4.0f * t) +
00447 r2->v[X] * (2.0f * tSq - t);
00448 rt->v[Y] = r0->v[Y] * (2.0f * tSq - 3.0f * t + 1.0f) +
00449 r1->v[Y] * (-4.0f * tSq + 4.0f * t) +
00450 r2->v[Y] * (2.0f * tSq - t);
00451 rt->v[Z] = r0->v[Z] * (2.0f * tSq - 3.0f * t + 1.0f) +
00452 r1->v[Z] * (-4.0f * tSq + 4.0f * t) +
00453 r2->v[Z] * (2.0f * tSq - t);
00454
00455 }
00456
00457
00458
00460
00461
00462
00463
00465
00466 void QuadInterpVec(VEC *r0, REAL t0, VEC *r1, REAL t1, VEC *r2, REAL t2, REAL t, VEC *rt)
00467 {
00468 REAL a, b, c;
00469
00470 a = ((t - t1) * (t - t2)) / ((t0 - t1) * (t0 - t2));
00471 b = ((t - t0) * (t - t2)) / ((t1 - t0) * (t1 - t2));
00472 c = ((t - t0) * (t - t1)) / ((t2 - t0) * (t2 - t1));
00473
00474 rt->v[X] = a * r0->v[X] + b * r1->v[X] + c * r2->v[X];
00475 rt->v[Y] = a * r0->v[Y] + b * r1->v[Y] + c * r2->v[Y];
00476 rt->v[Z] = a * r0->v[Z] + b * r1->v[Z] + c * r2->v[Z];
00477 }
00478
00479
00481
00482
00483
00485
00486 void LInterpVec(VEC *r0, REAL t0, VEC *r1, REAL t1, REAL t, VEC *rt)
00487 {
00488 REAL a, b;
00489
00490 a = (t - t1) / (t0 - t1);
00491 b = (t - t0) / (t1 - t0);
00492
00493 rt->v[X] = a * r0->v[X] + b * r1->v[X];
00494 rt->v[Y] = a * r0->v[Y] + b * r1->v[Y];
00495 rt->v[Z] = a * r0->v[Z] + b * r1->v[Z];
00496 }
00497
00499
00500
00502
00503 void MatMulVec(MAT *mIn, VEC *vIn, VEC *vOut)
00504 {
00505 vOut->v[X] =
00506 mIn->m[XX] * vIn->v[X] +
00507 mIn->m[XY] * vIn->v[Y] +
00508 mIn->m[XZ] * vIn->v[Z];
00509 vOut->v[Y] =
00510 mIn->m[YX] * vIn->v[X] +
00511 mIn->m[YY] * vIn->v[Y] +
00512 mIn->m[YZ] * vIn->v[Z];
00513 vOut->v[Z] =
00514 mIn->m[ZX] * vIn->v[X] +
00515 mIn->m[ZY] * vIn->v[Y] +
00516 mIn->m[ZZ] * vIn->v[Z];
00517 }
00518
00519 void VecMulMat(VEC *vIn, MAT *mIn, VEC *vOut)
00520 {
00521 vOut->v[X] =
00522 mIn->m[XX] * vIn->v[X] +
00523 mIn->m[YX] * vIn->v[Y] +
00524 mIn->m[ZX] * vIn->v[Z];
00525 vOut->v[Y] =
00526 mIn->m[XY] * vIn->v[X] +
00527 mIn->m[YY] * vIn->v[Y] +
00528 mIn->m[ZY] * vIn->v[Z];
00529 vOut->v[Z] =
00530 mIn->m[XZ] * vIn->v[X] +
00531 mIn->m[YZ] * vIn->v[Y] +
00532 mIn->m[ZZ] * vIn->v[Z];
00533 }
00534
00535
00537
00538
00540 void MatMulThisVec(MAT *mIn, VEC *vInOut)
00541 {
00542 VEC vecTemp;
00543 vecTemp.v[X] =
00544 mIn->m[XX] * vInOut->v[X] +
00545 mIn->m[XY] * vInOut->v[Y] +
00546 mIn->m[XZ] * vInOut->v[Z];
00547 vecTemp.v[Y] =
00548 mIn->m[YX] * vInOut->v[X] +
00549 mIn->m[YY] * vInOut->v[Y] +
00550 mIn->m[YZ] * vInOut->v[Z];
00551 vecTemp.v[Z] =
00552 mIn->m[ZX] * vInOut->v[X] +
00553 mIn->m[ZY] * vInOut->v[Y] +
00554 mIn->m[ZZ] * vInOut->v[Z];
00555 vInOut->v[X] = vecTemp.v[X];
00556 vInOut->v[Y] = vecTemp.v[Y];
00557 vInOut->v[Z] = vecTemp.v[Z];
00558 }
00559
00561
00562
00564
00565 extern void MatMulTransMat(MAT *mLeft, MAT *mRight, MAT *mOut)
00566 {
00567 mOut->m[XX] =
00568 mLeft->m[XX] * mRight->m[XX] +
00569 mLeft->m[XY] * mRight->m[XY] +
00570 mLeft->m[XZ] * mRight->m[XZ];
00571 mOut->m[XY] =
00572 mLeft->m[XX] * mRight->m[YX] +
00573 mLeft->m[XY] * mRight->m[YY] +
00574 mLeft->m[XZ] * mRight->m[YZ];
00575 mOut->m[XZ] =
00576 mLeft->m[XX] * mRight->m[ZX] +
00577 mLeft->m[XY] * mRight->m[ZY] +
00578 mLeft->m[XZ] * mRight->m[ZZ];
00579
00580 mOut->m[YX] =
00581 mLeft->m[YX] * mRight->m[XX] +
00582 mLeft->m[YY] * mRight->m[XY] +
00583 mLeft->m[YZ] * mRight->m[XZ];
00584 mOut->m[YY] =
00585 mLeft->m[YX] * mRight->m[YX] +
00586 mLeft->m[YY] * mRight->m[YY] +
00587 mLeft->m[YZ] * mRight->m[YZ];
00588 mOut->m[YZ] =
00589 mLeft->m[YX] * mRight->m[ZX] +
00590 mLeft->m[YY] * mRight->m[ZY] +
00591 mLeft->m[YZ] * mRight->m[ZZ];
00592
00593 mOut->m[ZX] =
00594 mLeft->m[ZX] * mRight->m[XX] +
00595 mLeft->m[ZY] * mRight->m[XY] +
00596 mLeft->m[ZZ] * mRight->m[XZ];
00597 mOut->m[ZY] =
00598 mLeft->m[ZX] * mRight->m[YX] +
00599 mLeft->m[ZY] * mRight->m[YY] +
00600 mLeft->m[ZZ] * mRight->m[YZ];
00601 mOut->m[ZZ] =
00602 mLeft->m[ZX] * mRight->m[ZX] +
00603 mLeft->m[ZY] * mRight->m[ZY] +
00604 mLeft->m[ZZ] * mRight->m[ZZ];
00605 }
00606
00607 extern void TransMatMulMat(MAT *mLeft, MAT *mRight, MAT *mOut)
00608 {
00609 mOut->m[XX] =
00610 mLeft->m[XX] * mRight->m[XX] +
00611 mLeft->m[YX] * mRight->m[YX] +
00612 mLeft->m[ZX] * mRight->m[ZX];
00613 mOut->m[XY] =
00614 mLeft->m[XX] * mRight->m[XY] +
00615 mLeft->m[YX] * mRight->m[YY] +
00616 mLeft->m[ZX] * mRight->m[ZY];
00617 mOut->m[XZ] =
00618 mLeft->m[XX] * mRight->m[XZ] +
00619 mLeft->m[YX] * mRight->m[YZ] +
00620 mLeft->m[ZX] * mRight->m[ZZ];
00621
00622 mOut->m[YX] =
00623 mLeft->m[XY] * mRight->m[XX] +
00624 mLeft->m[YY] * mRight->m[YX] +
00625 mLeft->m[ZY] * mRight->m[ZX];
00626 mOut->m[YY] =
00627 mLeft->m[XY] * mRight->m[XY] +
00628 mLeft->m[YY] * mRight->m[YY] +
00629 mLeft->m[ZY] * mRight->m[ZY];
00630 mOut->m[YZ] =
00631 mLeft->m[XY] * mRight->m[XZ] +
00632 mLeft->m[YY] * mRight->m[YZ] +
00633 mLeft->m[ZY] * mRight->m[ZZ];
00634
00635 mOut->m[ZX] =
00636 mLeft->m[XZ] * mRight->m[XX] +
00637 mLeft->m[YZ] * mRight->m[YX] +
00638 mLeft->m[ZZ] * mRight->m[ZX];
00639 mOut->m[ZY] =
00640 mLeft->m[XZ] * mRight->m[XY] +
00641 mLeft->m[YZ] * mRight->m[YY] +
00642 mLeft->m[ZZ] * mRight->m[ZY];
00643 mOut->m[ZZ] =
00644 mLeft->m[XZ] * mRight->m[XZ] +
00645 mLeft->m[YZ] * mRight->m[YZ] +
00646 mLeft->m[ZZ] * mRight->m[ZZ];
00647 }
00648
00649 extern void MatMulMat(MAT *mLeft, MAT *mRight, MAT *mOut)
00650 {
00651 mOut->m[XX] =
00652 mLeft->m[XX] * mRight->m[XX] +
00653 mLeft->m[XY] * mRight->m[YX] +
00654 mLeft->m[XZ] * mRight->m[ZX];
00655 mOut->m[XY] =
00656 mLeft->m[XX] * mRight->m[XY] +
00657 mLeft->m[XY] * mRight->m[YY] +
00658 mLeft->m[XZ] * mRight->m[ZY];
00659 mOut->m[XZ] =
00660 mLeft->m[XX] * mRight->m[XZ] +
00661 mLeft->m[XY] * mRight->m[YZ] +
00662 mLeft->m[XZ] * mRight->m[ZZ];
00663
00664 mOut->m[YX] =
00665 mLeft->m[YX] * mRight->m[XX] +
00666 mLeft->m[YY] * mRight->m[YX] +
00667 mLeft->m[YZ] * mRight->m[ZX];
00668 mOut->m[YY] =
00669 mLeft->m[YX] * mRight->m[XY] +
00670 mLeft->m[YY] * mRight->m[YY] +
00671 mLeft->m[YZ] * mRight->m[ZY];
00672 mOut->m[YZ] =
00673 mLeft->m[YX] * mRight->m[XZ] +
00674 mLeft->m[YY] * mRight->m[YZ] +
00675 mLeft->m[YZ] * mRight->m[ZZ];
00676
00677 mOut->m[ZX] =
00678 mLeft->m[ZX] * mRight->m[XX] +
00679 mLeft->m[ZY] * mRight->m[YX] +
00680 mLeft->m[ZZ] * mRight->m[ZX];
00681 mOut->m[ZY] =
00682 mLeft->m[ZX] * mRight->m[XY] +
00683 mLeft->m[ZY] * mRight->m[YY] +
00684 mLeft->m[ZZ] * mRight->m[ZY];
00685 mOut->m[ZZ] =
00686 mLeft->m[ZX] * mRight->m[XZ] +
00687 mLeft->m[ZY] * mRight->m[YZ] +
00688 mLeft->m[ZZ] * mRight->m[ZZ];
00689 }
00690
00692
00693
00694
00695
00697
00698 void BuildRotation3D(REAL axisX, REAL axisY, REAL axisZ, REAL angle, MAT *matOut)
00699 {
00700 REAL c, s;
00701
00702 c = (REAL) cos(angle);
00703 s = (REAL) sin(angle);
00704
00705 matOut->m[XX] = axisX * axisX - c * axisX * axisX + c;
00706 matOut->m[XY] = axisX * axisY - c * axisX * axisY - s * axisZ;
00707 matOut->m[XZ] = axisX * axisZ - c * axisX * axisZ + s * axisY;
00708 matOut->m[YX] = axisY * axisX - c * axisY * axisX + s * axisZ;
00709 matOut->m[YY] = axisY * axisY - c * axisY * axisY + c;
00710 matOut->m[YZ] = axisY * axisZ - c * axisY * axisZ - s * axisX;
00711 matOut->m[ZX] = axisZ * axisX - c * axisZ * axisX - s * axisY;
00712 matOut->m[ZY] = axisZ * axisY - c * axisZ * axisY + s * axisX;
00713 matOut->m[ZZ] = axisZ * axisZ - c * axisZ * axisZ + c;
00714 }
00715
00716
00718
00719
00720
00722
00723 void RotationX(MAT *mat, REAL rot)
00724 {
00725 REAL c, s;
00726
00727 c = (REAL)cos(rot);
00728 s = (REAL)sin(rot);
00729
00730 mat->m[RX] = 1;
00731 mat->m[RY] = 0;
00732 mat->m[RZ] = 0;
00733
00734 mat->m[UX] = 0;
00735 mat->m[UY] = c;
00736 mat->m[UZ] = -s;
00737
00738 mat->m[LX] = 0;
00739 mat->m[LY] = s;
00740 mat->m[LZ] = c;
00741 }
00742
00744
00745
00746
00748
00749 void RotationY(MAT *mat, REAL rot)
00750 {
00751 REAL c, s;
00752
00753 c = (REAL)cos(rot);
00754 s = (REAL)sin(rot);
00755
00756 mat->m[RX] = c;
00757 mat->m[RY] = 0;
00758 mat->m[RZ] = s;
00759
00760 mat->m[UX] = 0;
00761 mat->m[UY] = 1;
00762 mat->m[UZ] = 0;
00763
00764 mat->m[LX] = -s;
00765 mat->m[LY] = 0;
00766 mat->m[LZ] = c;
00767 }
00768
00770
00771
00772
00774
00775 void RotationZ(MAT *mat, REAL rot)
00776 {
00777 REAL c, s;
00778
00779 c = (REAL)cos(rot);
00780 s = (REAL)sin(rot);
00781
00782 mat->m[RX] = c;
00783 mat->m[RY] = -s;
00784 mat->m[RZ] = 0;
00785
00786 mat->m[UX] = s;
00787 mat->m[UY] = c;
00788 mat->m[UZ] = 0;
00789
00790 mat->m[LX] = 0;
00791 mat->m[LY] = 0;
00792 mat->m[LZ] = 1;
00793 }
00794
00796
00798 void CopyMat(MAT *src, MAT *dest)
00799 {
00800 dest->m[XX] = src->m[XX];
00801 dest->m[XY] = src->m[XY];
00802 dest->m[XZ] = src->m[XZ];
00803
00804 dest->m[YX] = src->m[YX];
00805 dest->m[YY] = src->m[YY];
00806 dest->m[YZ] = src->m[YZ];
00807
00808 dest->m[ZX] = src->m[ZX];
00809 dest->m[ZY] = src->m[ZY];
00810 dest->m[ZZ] = src->m[ZZ];
00811 }
00812
00814
00816
00817 void SetMat(MAT *mat, REAL xx, REAL xy, REAL xz, REAL yx, REAL yy, REAL yz, REAL zx, REAL zy, REAL zz)
00818 {
00819 mat->m[XX] = xx;
00820 mat->m[XY] = xy;
00821 mat->m[XZ] = xz;
00822
00823 mat->m[YX] = yx;
00824 mat->m[YY] = yy;
00825 mat->m[YZ] = yz;
00826
00827 mat->m[ZX] = zx;
00828 mat->m[ZY] = zy;
00829 mat->m[ZZ] = zz;
00830 }
00831
00832
00834
00836 void SetMatUnit(MAT *mat)
00837 {
00838 mat->m[XX] = mat->m[YY] = mat->m[ZZ] = (REAL)1.0f;
00839 mat->m[XY] = mat->m[XZ] = (REAL)0.0f;
00840 mat->m[YX] = mat->m[YZ] = (REAL)0.0f;
00841 mat->m[ZX] = mat->m[ZY] = (REAL)0.0f;
00842 }
00843
00844 void SetMatZero(MAT *mat)
00845 {
00846 mat->m[XX] = mat->m[YY] = mat->m[ZZ] = (REAL)0.0f;
00847 mat->m[XY] = mat->m[XZ] = (REAL)0.0f;
00848 mat->m[YX] = mat->m[YZ] = (REAL)0.0f;
00849 mat->m[ZX] = mat->m[ZY] = (REAL)0.0f;
00850 }
00851
00852
00854
00856 void MatMulScalar(MAT *mat, REAL scalar)
00857 {
00858 int iEl;
00859
00860 for (iEl = 0; iEl < 9; iEl++) {
00861 mat->m[iEl] *= scalar;
00862 }
00863 }
00864
00865
00867
00868
00870 void BuildCrossMat(VEC *vec, MAT *mat)
00871 {
00872 mat->m[XX] = (REAL)0.0f;
00873 mat->m[XY] = -vec->v[Z];
00874 mat->m[XZ] = vec->v[Y];
00875
00876 mat->m[YX] = vec->v[Z];
00877 mat->m[YY] = (REAL)0.0f;
00878 mat->m[YZ] = -vec->v[X];
00879
00880 mat->m[ZX] = -vec->v[Y];
00881 mat->m[ZY] = vec->v[X];
00882 mat->m[ZZ] = (REAL)0.0f;
00883 }
00884
00886
00887
00889 void VecCrossMat(VEC *vecLeft, MAT *matRight, MAT *matOut)
00890 {
00891
00892 matOut->m[XX] = vecLeft->v[Y] * matRight->m[ZX] - vecLeft->v[Z] * matRight->m[YX];
00893 matOut->m[XY] = vecLeft->v[Y] * matRight->m[ZY] - vecLeft->v[Z] * matRight->m[YY];
00894 matOut->m[XZ] = vecLeft->v[Y] * matRight->m[ZZ] - vecLeft->v[Z] * matRight->m[YZ];
00895
00896 matOut->m[YX] = vecLeft->v[Z] * matRight->m[XX] - vecLeft->v[X] * matRight->m[ZX];
00897 matOut->m[YY] = vecLeft->v[Z] * matRight->m[XY] - vecLeft->v[X] * matRight->m[ZY];
00898 matOut->m[YZ] = vecLeft->v[Z] * matRight->m[XZ] - vecLeft->v[X] * matRight->m[ZZ];
00899
00900 matOut->m[ZX] = vecLeft->v[X] * matRight->m[YX] - vecLeft->v[Y] * matRight->m[XX];
00901 matOut->m[ZY] = vecLeft->v[X] * matRight->m[YY] - vecLeft->v[Y] * matRight->m[XY];
00902 matOut->m[ZZ] = vecLeft->v[X] * matRight->m[YZ] - vecLeft->v[Y] * matRight->m[XZ];
00903
00904 }
00905
00906 void MatCrossVec(MAT *matLeft, VEC *vecRight, MAT *matOut)
00907 {
00908
00909 matOut->m[XX] = - vecRight->v[Y] * matLeft->m[XZ] + vecRight->v[Z] * matLeft->m[XY];
00910 matOut->m[XY] = - vecRight->v[Z] * matLeft->m[XX] + vecRight->v[X] * matLeft->m[XZ];
00911 matOut->m[XZ] = - vecRight->v[X] * matLeft->m[XY] + vecRight->v[Y] * matLeft->m[XX];
00912
00913 matOut->m[YX] = - vecRight->v[Y] * matLeft->m[YZ] + vecRight->v[Z] * matLeft->m[YY];
00914 matOut->m[YY] = - vecRight->v[Z] * matLeft->m[YX] + vecRight->v[X] * matLeft->m[YZ];
00915 matOut->m[YZ] = - vecRight->v[X] * matLeft->m[YY] + vecRight->v[Y] * matLeft->m[YX];
00916
00917 matOut->m[ZX] = - vecRight->v[Y] * matLeft->m[ZZ] + vecRight->v[Z] * matLeft->m[ZY];
00918 matOut->m[ZY] = - vecRight->v[Z] * matLeft->m[ZX] + vecRight->v[X] * matLeft->m[ZZ];
00919 matOut->m[ZZ] = - vecRight->v[X] * matLeft->m[ZY] + vecRight->v[Y] * matLeft->m[ZX];
00920
00921 }
00922
00924
00926
00927 void SwapVecs(VEC *a, VEC *b)
00928 {
00929 VEC store;
00930 store.v[X] = a->v[X];
00931 store.v[Y] = a->v[Y];
00932 store.v[Z] = a->v[Z];
00933
00934 a->v[X] = b->v[X];
00935 a->v[Y] = b->v[Y];
00936 a->v[Z] = b->v[Z];
00937
00938 b->v[X] = store.v[X];
00939 b->v[Y] = store.v[Y];
00940 b->v[Z] = store.v[Z];
00941 }
00942
00943
00945
00946
00947
00949
00950 void TransMat(MAT *src, MAT *dest)
00951 {
00952 dest->m[XX] = src->m[XX];
00953 dest->m[XY] = src->m[YX];
00954 dest->m[XZ] = src->m[ZX];
00955
00956 dest->m[YX] = src->m[XY];
00957 dest->m[YY] = src->m[YY];
00958 dest->m[YZ] = src->m[ZY];
00959
00960 dest->m[ZX] = src->m[XZ];
00961 dest->m[ZY] = src->m[YZ];
00962 dest->m[ZZ] = src->m[ZZ];
00963 }
00964
00965
00967
00968
00969
00970
00972
00973 void InvertMat(MAT *mat)
00974 {
00975
00976
00977
00978 MAT a;
00979 MAT b;
00980 REAL tmpReal;
00981
00982 int i, j;
00983 int pivotCandidate;
00984
00985 CopyMat(mat, &a);
00986 SetMatUnit(&b);
00987
00988
00989
00990 for (j = 0; j < 3; ++j) {
00991 pivotCandidate = j;
00992
00993 for (i = j + 1; i < 3; ++i) {
00994 if (abs(a.mv[i].v[j]) > abs(a.mv[pivotCandidate].v[j])) {
00995 pivotCandidate = i;
00996 }
00997 }
00998
00999
01000 SwapVecs(&a.mv[pivotCandidate], &a.mv[j]);
01001 SwapVecs(&b.mv[pivotCandidate], &b.mv[j]);
01002
01003
01004 if (a.mv[j].v[j] == (REAL)0.0) {
01005
01006 SetMatZero(mat);
01007 return;
01008 }
01009 tmpReal = a.mv[j].v[j];
01010 VecDivScalar(&b.mv[j], tmpReal);
01011 VecDivScalar(&a.mv[j], tmpReal);
01012
01013
01014 for (i = 0; i < 3; ++i) {
01015 if (i != j) {
01016 tmpReal = a.mv[i].v[j];
01017 b.mv[i].v[X] -= tmpReal * b.mv[j].v[X];
01018 b.mv[i].v[Y] -= tmpReal * b.mv[j].v[Y];
01019 b.mv[i].v[Z] -= tmpReal * b.mv[j].v[Z];
01020
01021 a.mv[i].v[X] -= tmpReal * a.mv[j].v[X];
01022 a.mv[i].v[Y] -= tmpReal * a.mv[j].v[Y];
01023 a.mv[i].v[Z] -= tmpReal * a.mv[j].v[Z];
01024 }
01025 }
01026 }
01027
01028 CopyMat(&b, mat);
01029 }
01030
01032
01033
01034
01036
01037 void MatPlusMat(MAT *matLeft, MAT *matRight, MAT *matOut)
01038 {
01039 matOut->m[XX] = matLeft->m[XX] + matRight->m[XX];
01040 matOut->m[XY] = matLeft->m[XY] + matRight->m[XY];
01041 matOut->m[XZ] = matLeft->m[XZ] + matRight->m[XZ];
01042
01043 matOut->m[YX] = matLeft->m[YX] + matRight->m[YX];
01044 matOut->m[YY] = matLeft->m[YY] + matRight->m[YY];
01045 matOut->m[YZ] = matLeft->m[YZ] + matRight->m[YZ];
01046
01047 matOut->m[ZX] = matLeft->m[ZX] + matRight->m[ZX];
01048 matOut->m[ZY] = matLeft->m[ZY] + matRight->m[ZY];
01049 matOut->m[ZZ] = matLeft->m[ZZ] + matRight->m[ZZ];
01050 }
01051
01052 void MatPlusEqScalarMat(MAT *matLeft, REAL scalar, MAT *matRight)
01053 {
01054 matLeft->m[XX] += scalar * matRight->m[XX];
01055 matLeft->m[XY] += scalar * matRight->m[XY];
01056 matLeft->m[XZ] += scalar * matRight->m[XZ];
01057
01058 matLeft->m[YX] += scalar * matRight->m[YX];
01059 matLeft->m[YY] += scalar * matRight->m[YY];
01060 matLeft->m[YZ] += scalar * matRight->m[YZ];
01061
01062 matLeft->m[ZX] += scalar * matRight->m[ZX];
01063 matLeft->m[ZY] += scalar * matRight->m[ZY];
01064 matLeft->m[ZZ] += scalar * matRight->m[ZZ];
01065 }
01066
01068
01069
01070
01072
01073 void BuildMatFromVec(VEC *vec, MAT *mat)
01074 {
01075 mat->m[UX] = vec->v[X];
01076 mat->m[UY] = vec->v[Y];
01077 mat->m[UZ] = vec->v[Z];
01078
01079
01080 if (fabs(mat->m[UX]) < fabs(mat->m[UY])) {
01081 if (fabs(mat->m[UX]) < fabs(mat->m[UZ])) {
01082 mat->m[RX] = 0.0f;
01083 mat->m[RY] = mat->m[UZ];
01084 mat->m[RZ] = -mat->m[UY];
01085 } else {
01086 mat->m[RX] = -mat->m[UY];
01087 mat->m[RY] = mat->m[UX];
01088 mat->m[RZ] = 0.0f;
01089 }
01090 } else {
01091 if (fabs(mat->m[UY]) < fabs(mat->m[UZ])) {
01092 mat->m[RX] = mat->m[UZ];
01093 mat->m[RY] = 0.0f;
01094 mat->m[RZ] = -mat->m[UX];
01095 } else {
01096 mat->m[RX] = mat->m[UY];
01097 mat->m[RY] = -mat->m[UX];
01098 mat->m[RZ] = 0.0f;
01099 }
01100 }
01101 NormalizeVec(&mat->mv[R])
01102
01103
01104 CrossProduct(&mat->mv[R], &mat->mv[U], &mat->mv[L]);
01105 NormalizeVec(&mat->mv[L]);
01106
01107 }
01108
01109
01111
01112
01113
01114
01116
01117 void MovePlane(PLANE *plane, VEC *dR)
01118 {
01119 plane->v[D] -= VecDotVec(dR, PlaneNormal(plane));
01120 }
01121
01122
01124
01125
01126
01127
01129
01130 static BIGMAT GEO_Coef;
01131 static BIGVEC GEO_Res;
01132 static BIGVEC GEO_Soln;
01133 static BIGVEC GEO_Work;
01134 static int GEO_OrigCol[BIG_NMAX];
01135 static int GEO_OrigRow[BIG_NMAX];
01136
01137 bool PlaneIntersect3(PLANE *p1, PLANE *p2, PLANE *p3, VEC *r)
01138 {
01139 int nSolved;
01140
01141
01142 SetBigMatSize(&GEO_Coef, 3, 3);
01143 SetBigVecSize(&GEO_Res, 3);
01144 SetBigVecSize(&GEO_Soln, 3);
01145
01146 GEO_Coef.m[0][A] = p1->v[A];
01147 GEO_Coef.m[0][B] = p1->v[B];
01148 GEO_Coef.m[0][C] = p1->v[C];
01149 GEO_Res.v[0] = -p1->v[D];
01150
01151 GEO_Coef.m[1][A] = p2->v[A];
01152 GEO_Coef.m[1][B] = p2->v[B];
01153 GEO_Coef.m[1][C] = p2->v[C];
01154 GEO_Res.v[1] = -p2->v[D];
01155
01156 GEO_Coef.m[2][A] = p3->v[A];
01157 GEO_Coef.m[2][B] = p3->v[B];
01158 GEO_Coef.m[2][C] = p3->v[C];
01159 GEO_Res.v[2] = -p3->v[D];
01160
01161 nSolved = SolveLinearEquations(&GEO_Coef, &GEO_Res, ZERO, Real(0.0001), GEO_OrigRow, GEO_OrigCol, &GEO_Work, &GEO_Soln);
01162 if (nSolved < 3) {
01163 return FALSE;
01164 } else {
01165 SetVec(r, GEO_Soln.v[0], GEO_Soln.v[1], GEO_Soln.v[2]);
01166 return TRUE;
01167 }
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180
01181
01182
01183
01184
01185
01186
01187
01188
01189
01190
01191
01192
01193
01194
01195 }
01196
01197
01199
01200
01201
01203
01204 void RotTransPlane(PLANE *plane, MAT *rotMat, VEC *dR, PLANE *pOut)
01205 {
01206 VecMulMat(PlaneNormal(plane), rotMat, PlaneNormal(pOut));
01207
01208 pOut->v[D] = plane->v[D] - VecDotVec(dR, PlaneNormal(pOut));
01209 }
01210
01212
01214
01215 void BuildPlane(VEC *a, VEC *b, VEC *c, PLANE *p)
01216 {
01217 VEC vec1, vec2;
01218
01219
01220
01221 SubVector(b, a, &vec1)
01222 SubVector(c, a, &vec2)
01223 CrossProduct(&vec1, &vec2, (VEC*)p);
01224 NormalizeVector((VEC*)p);
01225
01226
01227
01228 AddVector(a, b, &vec1);
01229 AddVector(&vec1, c, &vec1);
01230 p->v[D] = -DotProduct((VEC*)p, &vec1) / 3.0f;
01231 }
01232
01234
01235
01236
01238
01239 void BuildPlane2(VEC *normal, VEC *pt, PLANE *plane)
01240 {
01241 CopyVec(normal, PlaneNormal(plane));
01242 plane->v[D] = -VecDotVec(pt, normal);
01243 }
01244
01245
01247
01248
01249
01251
01252 void QuatToMat(QUATERNION *quat, MAT *mat)
01253 {
01254 REAL tReal1, tReal2;
01255
01256 mat->m[XX] = ONE - 2 * (quat->v[VY] * quat->v[VY] + quat->v[VZ] * quat->v[VZ]);
01257 mat->m[YY] = ONE - 2 * (quat->v[VX] * quat->v[VX] + quat->v[VZ] * quat->v[VZ]);
01258 mat->m[ZZ] = ONE - 2 * (quat->v[VX] * quat->v[VX] + quat->v[VY] * quat->v[VY]);
01259
01260 tReal1 = quat->v[VX] * quat->v[VY];
01261 tReal2 = quat->v[S] * quat->v[VZ];
01262 mat->m[YX] = 2 * (tReal1 - tReal2);
01263 mat->m[XY] = 2 * (tReal1 + tReal2);
01264
01265 tReal1 = quat->v[VX] * quat->v[VZ];
01266 tReal2 = quat->v[S] * quat->v[VY];
01267 mat->m[ZX] = 2 * (tReal1 + tReal2);
01268 mat->m[XZ] = 2 * (tReal1 - tReal2);
01269
01270 tReal1 = quat->v[VY] * quat->v[VZ];
01271 tReal2 = quat->v[S] * quat->v[VX];
01272 mat->m[ZY] = 2 * (tReal1 - tReal2);
01273 mat->m[YZ] = 2 * (tReal1 + tReal2);
01274
01275 }
01276
01277
01279
01280
01281
01283
01284 void MatToQuat(MAT *mat, QUATERNION *quat)
01285 {
01286 REAL tr, s;
01287 int i = XX;
01288
01289 tr = mat->m[XX] + mat->m[YY] + mat->m[ZZ];
01290
01291 if (tr >= 0) {
01292
01293 s = (REAL)sqrt(tr + ONE);
01294 quat->v[S] = HALF * s;
01295 s = HALF / s;
01296 quat->v[VX] = (mat->m[YZ] - mat->m[ZY]) * s;
01297 quat->v[VY] = (mat->m[ZX] - mat->m[XZ]) * s;
01298 quat->v[VZ] = (mat->m[XY] - mat->m[YX]) * s;
01299
01300 } else {
01301 if (mat->m[YY] > mat->m[XX]) {
01302 i = YY;
01303 }
01304 if (mat->m[ZZ] > mat->m[i]) {
01305 i = ZZ;
01306 }
01307
01308 switch(i) {
01309
01310 case XX:
01311
01312 s = (REAL)sqrt((mat->m[XX] - (mat->m[YY] + mat->m[ZZ])) + 1);
01313 quat->v[VX] = HALF * s;
01314 s = HALF / s;
01315 quat->v[VY] = (mat->m[YX] + mat->m[XY]) * s;
01316 quat->v[VZ] = (mat->m[XZ] + mat->m[ZX]) * s;
01317 quat->v[S] = (mat->m[YZ] - mat->m[ZY]) * s;
01318 break;
01319
01320 case YY:
01321
01322 s = (REAL)sqrt((mat->m[YY] - (mat->m[ZZ] + mat->m[XX])) + 1);
01323 quat->v[VY] = HALF * s;
01324 s = HALF / s;
01325 quat->v[VZ] = (mat->m[ZY] + mat->m[YZ]) * s;
01326 quat->v[VX] = (mat->m[YX] + mat->m[XY]) * s;
01327 quat->v[S] = (mat->m[ZX] - mat->m[XZ]) * s;
01328 break;
01329
01330 case ZZ:
01331
01332 s = (REAL)sqrt((mat->m[ZZ] - (mat->m[XX] + mat->m[YY])) + 1);
01333 quat->v[VZ] = HALF * s;
01334 s = HALF / s;
01335 quat->v[VX] = (mat->m[XZ] + mat->m[ZX]) * s;
01336 quat->v[VY] = (mat->m[ZY] + mat->m[YZ]) * s;
01337 quat->v[S] = (mat->m[XY] - mat->m[YX]) * s;
01338 break;
01339
01340 }
01341 }
01342 }
01343
01344
01346
01347
01348
01350
01351 void QuatRotVec(QUATERNION *quat, VEC *vIn, VEC *vOut)
01352 {
01353 REAL sQ2;
01354 REAL dot;
01355 VEC cross;
01356
01357 sQ2 = quat->v[S] * quat->v[S];
01358 dot = VecDotVec(vIn, VecOfQuat(quat));
01359 VecCrossVec(vIn, VecOfQuat(quat), &cross);
01360
01361 VecCrossVec(&cross, VecOfQuat(quat), vOut)
01362 VecPlusEqScalarVec(vOut, sQ2, vIn);
01363 VecPlusEqScalarVec(vOut, -2 * quat->v[S], &cross);
01364 VecPlusEqScalarVec(vOut, dot, VecOfQuat(quat));
01365
01366 }
01367
01368
01370
01371
01372
01374
01375 void LerpQuat(QUATERNION *q0, QUATERNION *q1, REAL t, QUATERNION *qt)
01376 {
01377 qt->v[VX] = (ONE - t) * q0->v[VX] + t * q1->v[VX];
01378 qt->v[VY] = (ONE - t) * q0->v[VY] + t * q1->v[VY];
01379 qt->v[VZ] = (ONE - t) * q0->v[VZ] + t * q1->v[VZ];
01380 qt->v[S] = (ONE - t) * q0->v[S] + t * q1->v[S];
01381 }
01382
01383
01385
01386
01387
01389
01390 #ifndef _N64
01391 void SLerpQuat(QUATERNION *q0, QUATERNION *q1, REAL t, QUATERNION *qt)
01392 {
01393 REAL theta, sinT, sin1mtT, sintT;
01394
01395 theta = (REAL)acosf(QuatDotQuat(q0, q1));
01396
01397
01398 if (theta < SLERP_SMALL_ANGLE) {
01399 sinT = ZERO;
01400 sintT = t;
01401 sin1mtT = (ONE - t);
01402 } else {
01403 sinT = (REAL)sin(theta);
01404 sintT = (REAL)sin(t * theta);
01405 sin1mtT = (REAL)sin((ONE - t) * theta);
01406 sin1mtT /= sinT;
01407 sintT /= sinT;
01408 }
01409
01410 qt->v[VX] = sin1mtT * q0->v[VX] + sintT * q1->v[VX];
01411 qt->v[VY] = sin1mtT * q0->v[VY] + sintT * q1->v[VY];
01412 qt->v[VZ] = sin1mtT * q0->v[VZ] + sintT * q1->v[VZ];
01413 qt->v[S] = sin1mtT * q0->v[S] + sintT * q1->v[S];
01414 }
01415 #endif
01416
01417
01419
01420
01421
01422
01424
01425 bool LinePoint(VEC *p, REAL d, VEC *r0, VEC *r1, REAL *t1, REAL *t2)
01426 {
01427 VEC rP, dR;
01428 REAL rPrP, dRdR, rPdR, dd, t;
01429
01430 VecMinusVec(r1, r0, &dR);
01431 VecMinusVec(r0, p, &rP);
01432
01433 dd = d * d;
01434 rPrP = VecDotVec(&rP, &rP);
01435 dRdR = VecDotVec(&dR, &dR);
01436 rPdR = VecDotVec(&rP, &dR);
01437
01438 t = Real(4) * (rPdR * rPdR - dRdR * (rPrP - dd));
01439
01440 if (t < ZERO) return FALSE;
01441 t = (REAL)sqrt(t);
01442
01443 *t1 = (-rPdR + HALF * t) / dRdR;
01444 *t2 = (-rPdR - HALF * t) / dRdR;
01445
01446 return TRUE;
01447 }
01448
01449 void TestLinePoint()
01450 {
01451 VEC r0, r1, p;
01452 REAL t1, t2;
01453
01454
01455 SetVec(&r0, ZERO, ZERO, ZERO);
01456 SetVec(&r1, ONE, ZERO, ZERO);
01457
01458 SetVec(&p, HALF, ONE, ZERO);
01459
01460 LinePoint(&p, ONE, &r0, &r1, &t1, &t2);
01461
01462 LinePoint(&p, 1.1f, &r0, &r1, &t1, &t2);
01463
01464 LinePoint(&p, 2.0f, &r0, &r1, &t1, &t2);
01465
01466 SetVec(&p, ONE, ONE, ZERO);
01467
01468 LinePoint(&p, ONE, &r0, &r1, &t1, &t2);
01469
01470 LinePoint(&p, 1.1f, &r0, &r1, &t1, &t2);
01471
01472 LinePoint(&p, 2.0f, &r0, &r1, &t1, &t2);
01473
01474 }
01475
01476
01478
01480
01481 void FindIntersection(VEC *point1, REAL dist1, VEC *point2, REAL dist2, VEC *out)
01482 {
01483 REAL mul;
01484 VEC diff;
01485
01486
01487
01488 SubVector(point2, point1, &diff);
01489 mul = -dist1 / (dist2 - dist1);
01490
01491
01492
01493 out->v[X] = point1->v[X] + diff.v[X] * mul;
01494 out->v[Y] = point1->v[Y] + diff.v[Y] * mul;
01495 out->v[Z] = point1->v[Z] + diff.v[Z] * mul;
01496 }
01497