Subversion Repositories Games.Carmageddon

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. #include "quat.h"
  2. #include "matrix34.h"
  3. #include "matrix4.h"
  4. #include "harness/trace.h"
  5. #include <math.h>
  6.  
  7. #define M(x, y) mat->m[x][y]
  8. #define M_DIAG(x) (((br_scalar*)mat->m)[4*(x)])
  9. #define Q_EL(e) (((br_scalar*)&(q->x))[(e)])
  10.  
  11. // IDA: br_quat* __cdecl BrQuatMul(br_quat *q, br_quat *l, br_quat *r)
  12. br_quat* BrQuatMul(br_quat* q, br_quat* l, br_quat* r) {
  13.     br_scalar x1;
  14.     br_scalar x2;
  15.     br_scalar x3;
  16.     br_scalar x4;
  17.     //br_scalar x5; // Pierre-Marie Baty -- unused variable
  18.     //br_scalar x6; // Pierre-Marie Baty -- unused variable
  19.     //br_scalar x7; // Pierre-Marie Baty -- unused variable
  20.     //br_scalar x8; // Pierre-Marie Baty -- unused variable
  21.     br_scalar s;
  22.     //br_scalar t; // Pierre-Marie Baty -- unused variable
  23.     LOG_TRACE("(%p, %p, %p)", q, l, r);
  24.  
  25.     x1 = (l->x + l->z) * (r->y + r->x);
  26.     x2 = (l->w + l->y) * (r->w - r->z);
  27.     x3 = (l->w - l->y) * (r->w + r->z);
  28.     s = x1 + x2 + x3;
  29.     x4 = ((l->z - l->x) * (r->x - r->y) + s) * 0.5f;
  30.     q->x = x4 + (l->w + l->x) * (r->w + r->x) - s;
  31.     q->y = x4 + (l->w - l->x) * (r->z + r->y) - x3;
  32.     q->z = x4 + (l->y + l->z) * (r->w - r->x) - x2;
  33.     q->w = x4 + (l->z - l->y) * (r->y - r->z) - x1;
  34.     return q;
  35. }
  36.  
  37. // IDA: br_quat* __cdecl BrQuatNormalise(br_quat *q, br_quat *qq)
  38. br_quat* BrQuatNormalise(br_quat* q, br_quat* qq) {
  39.     br_scalar s;
  40.     LOG_TRACE("(%p, %p)", q, qq);
  41.  
  42.     s = 1.f / sqrtf(qq->x * qq->x + qq->y * qq->y + qq->z * qq->z + qq->w * qq->w);
  43.     q->x = qq->x * s;
  44.     q->y = qq->y * s;
  45.     q->z = qq->z * s;
  46.     q->w = qq->w * s;
  47.     return q;
  48. }
  49.  
  50. // IDA: br_quat* __cdecl BrQuatInvert(br_quat *q, br_quat *qq)
  51. br_quat* BrQuatInvert(br_quat* q, br_quat* qq) {
  52.     LOG_TRACE("(%p, %p)", q, qq);
  53.  
  54.     q->x = -qq->x;
  55.     q->y = -qq->y;
  56.     q->z = -qq->z;
  57.     q->w = qq->w;
  58.     return q;
  59. }
  60.  
  61. // IDA: br_quat* __cdecl BrQuatSlerp(br_quat *q, br_quat *l, br_quat *r, br_scalar a, br_int_16 spins)
  62. br_quat* BrQuatSlerp(br_quat* q, br_quat* l, br_quat* r, br_scalar a, br_int_16 spins) {
  63.     int omega;
  64.     int omega_spin;
  65.     br_scalar s_omega;
  66.     br_scalar c_omega;
  67.     br_scalar scale_l;
  68.     br_scalar scale_r;
  69.     br_quat t;
  70.     LOG_TRACE("(%p, %p, %p, %f, %d)", q, l, r, a, spins);
  71.  
  72.     // Animating rotation with quaternion curves, Ken Shoemake,SIGGRAPH Computer Graphics, 19(3):245–254, 1985. doi:10.1145/325165.325242.
  73.     c_omega = l->x * r->x + l->y * r->y + l->z * r->z + l->w * r->w;
  74.     if (c_omega >= 0.f) {
  75.         t.x = r->x;
  76.         t.y = r->y;
  77.         t.z = r->z;
  78.         t.w = r->w;
  79.     } else {
  80.         t.x = -r->x;
  81.         t.y = -r->y;
  82.         t.z = -r->z;
  83.         t.w = -r->w;
  84.         c_omega = -c_omega;
  85.     }
  86.  
  87.     if ((1.f - c_omega) <= BR_SCALAR_EPSILON) {
  88.         scale_l = 1.f - a;
  89.         scale_r = a;
  90.     } else {
  91.         omega = BrRadianToAngle(acosf(c_omega));
  92.         s_omega = sinf(BrAngleToRadian(omega));
  93.         omega_spin = omega + spins * BR_ANGLE_RAD(PI);
  94.         scale_l = sinf(BrAngleToRadian(omega - a * omega_spin)) / s_omega;
  95.         scale_r = sinf(BrAngleToRadian(a * omega_spin)) / s_omega;
  96.     }
  97.     q->x = scale_l * l->x + scale_r * t.x;
  98.     q->y = scale_l * l->y + scale_r * t.y;
  99.     q->z = scale_l * l->z + scale_r * t.z;
  100.     q->w = scale_l * l->w + scale_r * t.w;
  101.     return q;
  102. }
  103.  
  104. // IDA: br_matrix34* __cdecl BrQuatToMatrix34(br_matrix34 *mat, br_quat *q)
  105. br_matrix34* BrQuatToMatrix34(br_matrix34* mat, br_quat* q) {
  106.     br_scalar xs;
  107.     br_scalar ys;
  108.     br_scalar zs;
  109.     br_scalar wx;
  110.     br_scalar wy;
  111.     br_scalar wz;
  112.     br_scalar xx;
  113.     br_scalar xy;
  114.     br_scalar xz;
  115.     br_scalar yy;
  116.     br_scalar yz;
  117.     br_scalar zz;
  118.     LOG_TRACE("(%p, %p)", mat, q);
  119.  
  120.     zz = q->z + q->z;
  121.     yy = q->y + q->y;
  122.     zs = q->z * zz;
  123.     xx = q->x + q->x;
  124.     wx = q->w * xx;
  125.     wy = q->w * yy;
  126.     wz = q->w * zz;
  127.     xy = q->x * yy;
  128.     xz = q->x * zz;
  129.     ys = q->y * yy;
  130.     xs = q->x * xx;
  131.     yz = q->y * zz;
  132.  
  133.     M(0, 0) = 1.f - (ys + zs);
  134.     M(1, 0) = xy - wz;
  135.     M(2, 0) = xz + wy;
  136.     M(0, 1) = xy + wz;
  137.     M(1, 1) = 1.f - (zs + xs);
  138.     M(2, 1) = yz - wx;
  139.     M(0, 2) = xz - wy;
  140.     M(1, 2) = yz + wx;
  141.     M(2, 2) = 1.f - (xs + ys);
  142.     M(3, 0) = 0.f;
  143.     M(3, 1) = 0.f;
  144.     M(3, 2) = 0.f;
  145.  
  146.     return mat;
  147. }
  148.  
  149. // IDA: br_quat* __cdecl BrMatrix34ToQuat(br_quat *q, br_matrix34 *mat)
  150. br_quat* BrMatrix34ToQuat(br_quat* q, br_matrix34* mat) {
  151.     br_scalar tr;
  152.     br_scalar s;
  153.     int i;
  154.     int j;
  155.     int k;
  156.     LOG_TRACE("(%p, %p)", q, mat);
  157.  
  158.     tr = M(0, 0) + M(1, 1) + M(2, 2);
  159.     if (tr >= 0.f) {
  160.         tr = sqrtf(tr + 1.f);
  161.         s = 0.5f / tr;
  162.         q->w = tr * 0.5f;
  163.         q->x = (M(1, 2) - M(2, 1)) * s;
  164.         q->y = (M(2, 0) - M(0, 2)) * s;
  165.         q->z = (M(0, 1) - M(1, 0)) * s;
  166.         return q;
  167.     }
  168.     i = M_DIAG(1) >= M_DIAG(0) ? 1 : 0;
  169.     i = M_DIAG(2) >= M_DIAG(i) ? 2 : i;
  170.     j = (i + 1) % 3;
  171.     k = (j + 1) % 3;
  172.     tr = sqrtf(M_DIAG(i) - (M_DIAG(j) + M_DIAG(k)) + 1.f);
  173.     s = 0.5f / tr;
  174.     Q_EL(i) = 0.5f * tr;
  175.     Q_EL(j) = (M(i, j) + M(j, i)) * s;
  176.     Q_EL(k) = (M(i, k) + M(k, i)) * s;
  177.     q->w = (M(k, j) - M(j, k)) * s;
  178.     return q;
  179. }
  180.  
  181. // IDA: br_matrix4* __cdecl BrQuatToMatrix4(br_matrix4 *mat, br_quat *q)
  182. br_matrix4* BrQuatToMatrix4(br_matrix4* mat, br_quat* q) {
  183.     br_matrix34 tmp;
  184.     LOG_TRACE("(%p, %p)", mat, q);
  185.  
  186.     BrQuatToMatrix34(&tmp, q);
  187.     BrMatrix4Copy34(mat, &tmp);
  188.     return mat;
  189. }
  190.  
  191. // IDA: br_quat* __cdecl BrMatrix4ToQuat(br_quat *q, br_matrix4 *mat)
  192. br_quat* BrMatrix4ToQuat(br_quat* q, br_matrix4* mat) {
  193.     br_matrix34 tmp;
  194.     LOG_TRACE("(%p, %p)", q, mat);
  195.  
  196.     BrMatrix34Copy4(&tmp, mat);
  197.     return BrMatrix34ToQuat(q, &tmp);
  198. }
  199.