mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-26 14:20:59 +00:00
Switch QF's quaterions from wxyz to xyzw.
After messing with SIMD stuff for a little, I think I now understand why the industry went with xyzw instead of the mathematical wxyz. Anyway, this will make for less pain in the future (assuming I got everything).
This commit is contained in:
parent
b7aa5bb8fe
commit
f58c2fef5a
17 changed files with 272 additions and 159 deletions
|
@ -58,10 +58,10 @@ extern const vec_t *const quat_origin;
|
|||
} while (0)
|
||||
#define QuatConj(a,b) \
|
||||
do { \
|
||||
(b)[0] = (a)[0]; \
|
||||
(b)[0] = -(a)[0]; \
|
||||
(b)[1] = -(a)[1]; \
|
||||
(b)[2] = -(a)[2]; \
|
||||
(b)[3] = -(a)[3]; \
|
||||
(b)[3] = (a)[3]; \
|
||||
} while (0)
|
||||
#define QuatAdd(a,b,c) \
|
||||
do { \
|
||||
|
|
|
@ -76,8 +76,8 @@ typedef vec_t quat_t[4]; ///< A quaternion.
|
|||
typedef vec_t vec5_t[5];
|
||||
typedef union {
|
||||
struct {
|
||||
vec_t s;
|
||||
vec3_t v;
|
||||
vec_t s;
|
||||
} sv;
|
||||
quat_t q;
|
||||
} Quat_t;
|
||||
|
|
|
@ -118,7 +118,6 @@ get_joints (const iqmheader *hdr, byte *buffer)
|
|||
{
|
||||
iqmjoint *joint;
|
||||
uint32_t i, j;
|
||||
float t;
|
||||
|
||||
if (hdr->ofs_joints + hdr->num_joints * sizeof (iqmjoint) > hdr->filesize)
|
||||
return 0;
|
||||
|
@ -135,10 +134,6 @@ get_joints (const iqmheader *hdr, byte *buffer)
|
|||
joint[i].translate[j] = LittleFloat (joint[i].translate[j]);
|
||||
for (j = 0; j < 4; j++)
|
||||
joint[i].rotate[j] = LittleFloat (joint[i].rotate[j]);
|
||||
// iqm quaternions use xyzw but QF quaternions use wxyz
|
||||
t = joint[i].rotate[3];
|
||||
memmove (&joint[i].rotate[1], &joint[i].rotate[0], 3 * sizeof (float));
|
||||
joint[i].rotate[0] = t;
|
||||
for (j = 0; j < 3; j++)
|
||||
joint[i].scale[j] = LittleFloat (joint[i].scale[j]);
|
||||
}
|
||||
|
@ -442,19 +437,18 @@ load_iqm_anims (model_t *mod, const iqmheader *hdr, byte *buffer)
|
|||
if (p->mask & 0x004)
|
||||
translation[2] += *framedata++ * p->channelscale[2];
|
||||
|
||||
// QF's quaternions are wxyz while IQM's quaternions are xyzw
|
||||
rotation[1] = p->channeloffset[3];
|
||||
rotation[0] = p->channeloffset[3];
|
||||
if (p->mask & 0x008)
|
||||
rotation[1] += *framedata++ * p->channelscale[3];
|
||||
rotation[2] = p->channeloffset[4];
|
||||
rotation[0] += *framedata++ * p->channelscale[3];
|
||||
rotation[1] = p->channeloffset[4];
|
||||
if (p->mask & 0x010)
|
||||
rotation[2] += *framedata++ * p->channelscale[4];
|
||||
rotation[3] = p->channeloffset[5];
|
||||
rotation[1] += *framedata++ * p->channelscale[4];
|
||||
rotation[2] = p->channeloffset[5];
|
||||
if (p->mask & 0x020)
|
||||
rotation[3] += *framedata++ * p->channelscale[5];
|
||||
rotation[0] = p->channeloffset[6];
|
||||
rotation[2] += *framedata++ * p->channelscale[5];
|
||||
rotation[3] = p->channeloffset[6];
|
||||
if (p->mask & 0x040)
|
||||
rotation[0] += *framedata++ * p->channelscale[6];
|
||||
rotation[3] += *framedata++ * p->channelscale[6];
|
||||
|
||||
scale[0] = p->channeloffset[7];
|
||||
if (p->mask & 0x080)
|
||||
|
|
|
@ -248,11 +248,11 @@ QuatMult (const quat_t q1, const quat_t q2, quat_t out)
|
|||
vec_t s;
|
||||
vec3_t v;
|
||||
|
||||
s = q1[0] * q2[0] - DotProduct (q1 + 1, q2 + 1);
|
||||
CrossProduct (q1 + 1, q2 + 1, v);
|
||||
VectorMultAdd (v, q1[0], q2 + 1, v);
|
||||
VectorMultAdd (v, q2[0], q1 + 1, out + 1);
|
||||
out[0] = s;
|
||||
s = q1[3] * q2[3] - DotProduct (q1, q2);
|
||||
CrossProduct (q1, q2, v);
|
||||
VectorMultAdd (v, q1[3], q2, v);
|
||||
VectorMultAdd (v, q2[3], q1, out);
|
||||
out[3] = s;
|
||||
}
|
||||
|
||||
VISIBLE void
|
||||
|
@ -261,12 +261,12 @@ QuatMultVec (const quat_t q, const vec3_t v, vec3_t out)
|
|||
vec_t s;
|
||||
vec3_t tv;
|
||||
|
||||
s = -DotProduct (q + 1, v);
|
||||
CrossProduct (q + 1, v, tv);
|
||||
VectorMultAdd (tv, q[0], v, tv);
|
||||
CrossProduct (q + 1, tv, out);
|
||||
VectorMultSub (out, s, q + 1, out);
|
||||
VectorMultAdd (out, q[0], tv, out);
|
||||
s = -DotProduct (q, v);
|
||||
CrossProduct (q, v, tv);
|
||||
VectorMultAdd (tv, q[3], v, tv);
|
||||
CrossProduct (q, tv, out);
|
||||
VectorMultSub (out, s, q, out);
|
||||
VectorMultAdd (out, q[3], tv, out);
|
||||
}
|
||||
|
||||
VISIBLE void
|
||||
|
@ -288,19 +288,19 @@ QuatExp (const quat_t a, quat_t b)
|
|||
vec_t r;
|
||||
vec_t c, s;
|
||||
|
||||
VectorCopy (a + 1, n);
|
||||
VectorCopy (a, n);
|
||||
th = VectorNormalize (n);
|
||||
r = expf (a[0]);
|
||||
r = expf (a[3]);
|
||||
c = cosf (th);
|
||||
s = sinf (th);
|
||||
VectorScale (n, r * s, b + 1);
|
||||
b[0] = r * c;
|
||||
VectorScale (n, r * s, b);
|
||||
b[3] = r * c;
|
||||
}
|
||||
|
||||
VISIBLE void
|
||||
QuatToMatrix (const quat_t q, vec_t *m, int homogenous, int vertical)
|
||||
{
|
||||
vec_t aa, ab, ac, ad, bb, bc, bd, cc, cd, dd;
|
||||
vec_t xx, xy, xz, xw, yy, yz, yw, zz, zw, ww;
|
||||
vec_t *_m[4] = {
|
||||
m + (homogenous ? 0 : 0),
|
||||
m + (homogenous ? 4 : 3),
|
||||
|
@ -308,28 +308,28 @@ QuatToMatrix (const quat_t q, vec_t *m, int homogenous, int vertical)
|
|||
m + (homogenous ? 12 : 9),
|
||||
};
|
||||
|
||||
aa = q[0] * q[0];
|
||||
ab = q[0] * q[1];
|
||||
ac = q[0] * q[2];
|
||||
ad = q[0] * q[3];
|
||||
xx = q[0] * q[0];
|
||||
xy = q[0] * q[1];
|
||||
xz = q[0] * q[2];
|
||||
xw = q[0] * q[3];
|
||||
|
||||
bb = q[1] * q[1];
|
||||
bc = q[1] * q[2];
|
||||
bd = q[1] * q[3];
|
||||
yy = q[1] * q[1];
|
||||
yz = q[1] * q[2];
|
||||
yw = q[1] * q[3];
|
||||
|
||||
cc = q[2] * q[2];
|
||||
cd = q[2] * q[3];
|
||||
zz = q[2] * q[2];
|
||||
zw = q[2] * q[3];
|
||||
|
||||
dd = q[3] * q[3];
|
||||
ww = q[3] * q[3];
|
||||
|
||||
if (vertical) {
|
||||
VectorSet (aa + bb - cc - dd, 2 * (bc + ad), 2 * (bd - ac), _m[0]);
|
||||
VectorSet (2 * (bc - ad), aa - bb + cc - dd, 2 * (cd + ab), _m[1]);
|
||||
VectorSet (2 * (bd + ac), 2 * (cd - ab), aa - bb - cc + dd, _m[2]);
|
||||
VectorSet (ww + xx - yy - zz, 2 * (xy + zw), 2 * (xz - yw), _m[0]);
|
||||
VectorSet (2 * (xy - zw), ww - xx + yy - zz, 2 * (yz + xw), _m[1]);
|
||||
VectorSet (2 * (xz + yw), 2 * (yz - xw), ww - xx - yy + zz, _m[2]);
|
||||
} else {
|
||||
VectorSet (aa + bb - cc - dd, 2 * (bc - ad), 2 * (bd + ac), _m[0]);
|
||||
VectorSet (2 * (bc + ad), aa - bb + cc - dd, 2 * (cd - ab), _m[1]);
|
||||
VectorSet (2 * (bd - ac), 2 * (cd + ab), aa - bb - cc + dd, _m[2]);
|
||||
VectorSet (ww + xx - yy - zz, 2 * (xy - zw), 2 * (xz + yw), _m[0]);
|
||||
VectorSet (2 * (xy + zw), ww - xx + yy - zz, 2 * (yz - xw), _m[1]);
|
||||
VectorSet (2 * (xz - yw), 2 * (yz + xw), ww - xx - yy + zz, _m[2]);
|
||||
}
|
||||
if (homogenous) {
|
||||
_m[0][3] = 0;
|
||||
|
@ -555,10 +555,10 @@ AngleQuat (const vec3_t angles, quat_t q)
|
|||
sr = sin (alpha);
|
||||
cr = cos (alpha);
|
||||
|
||||
QuatSet (cy * cp * cr + sy * sp * sr,
|
||||
cy * cp * sr - sy * sp * cr,
|
||||
cy * sp * cr + sy * cp * sr,
|
||||
sy * cp * cr - cy * sp * sr,
|
||||
QuatSet (cy * cp * sr - sy * sp * cr, // x
|
||||
cy * sp * cr + sy * cp * sr, // y
|
||||
sy * cp * cr - cy * sp * sr, // z
|
||||
cy * cp * cr + sy * sp * sr, // w
|
||||
q);
|
||||
}
|
||||
|
||||
|
@ -1112,29 +1112,29 @@ Mat3Decompose (const mat3_t mat, quat_t rot, vec3_t shear, vec3_t scale)
|
|||
t = 1 + row[0][0] + row[1][1] + row[2][2];
|
||||
if (t >= 1e-5) {
|
||||
vec_t s = sqrt (t) * 2;
|
||||
rot[0] = s / 4;
|
||||
rot[1] = (row[2][1] - row[1][2]) / s;
|
||||
rot[2] = (row[0][2] - row[2][0]) / s;
|
||||
rot[3] = (row[1][0] - row[0][1]) / s;
|
||||
rot[0] = (row[2][1] - row[1][2]) / s;
|
||||
rot[1] = (row[0][2] - row[2][0]) / s;
|
||||
rot[2] = (row[1][0] - row[0][1]) / s;
|
||||
rot[3] = s / 4;
|
||||
} else {
|
||||
if (row[0][0] > row[1][1] && row[0][0] > row[2][2]) {
|
||||
vec_t s = sqrt (1 + row[0][0] - row[1][1] - row[2][2]) * 2;
|
||||
rot[0] = (row[2][1] - row[1][2]) / s;
|
||||
rot[1] = s / 4;
|
||||
rot[2] = (row[1][0] + row[0][1]) / s;
|
||||
rot[3] = (row[0][2] + row[2][0]) / s;
|
||||
rot[0] = s / 4;
|
||||
rot[1] = (row[1][0] + row[0][1]) / s;
|
||||
rot[2] = (row[0][2] + row[2][0]) / s;
|
||||
rot[3] = (row[2][1] - row[1][2]) / s;
|
||||
} else if (row[1][1] > row[2][2]) {
|
||||
vec_t s = sqrt (1 + row[1][1] - row[0][0] - row[2][2]) * 2;
|
||||
rot[0] = (row[0][2] - row[2][0]) / s;
|
||||
rot[1] = (row[1][0] + row[0][1]) / s;
|
||||
rot[2] = s / 4;
|
||||
rot[3] = (row[2][1] + row[1][2]) / s;
|
||||
rot[0] = (row[1][0] + row[0][1]) / s;
|
||||
rot[1] = s / 4;
|
||||
rot[2] = (row[2][1] + row[1][2]) / s;
|
||||
rot[3] = (row[0][2] - row[2][0]) / s;
|
||||
} else {
|
||||
vec_t s = sqrt (1 + row[2][2] - row[0][0] - row[1][1]) * 2;
|
||||
rot[0] = (row[1][0] - row[0][1]) / s;
|
||||
rot[1] = (row[0][2] + row[2][0]) / s;
|
||||
rot[2] = (row[2][1] + row[1][2]) / s;
|
||||
rot[3] = s / 4;
|
||||
rot[0] = (row[0][2] + row[2][0]) / s;
|
||||
rot[1] = (row[2][1] + row[1][2]) / s;
|
||||
rot[2] = s / 4;
|
||||
rot[3] = (row[1][0] - row[0][1]) / s;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
|
|
|
@ -80,7 +80,8 @@ negate:
|
|||
|
||||
return 1;
|
||||
fail:
|
||||
printf ("\n\n(%g %g %g)\n", VectorExpand (angles));
|
||||
printf ("\ntest_angle\n");
|
||||
printf ("(%g %g %g)\n", VectorExpand (angles));
|
||||
printf (" [%g %g %g %g]\n", QuatExpand (rotation));
|
||||
printf (" [%g %g %g %g] [%g %g %g] [%g %g %g]\n",
|
||||
QuatExpand (r), VectorExpand (scale), VectorExpand (shear));
|
||||
|
@ -110,7 +111,8 @@ test_transform (const vec3_t angles, const vec3_t scale)
|
|||
|
||||
return 1;
|
||||
fail:
|
||||
printf ("\n\n(%g %g %g) (%g %g %g)\n", VectorExpand (angles),
|
||||
printf ("\ntest_transform\n");
|
||||
printf ("(%g %g %g) (%g %g %g)\n", VectorExpand (angles),
|
||||
VectorExpand (scale));
|
||||
printf (" (%g %g %g)\n", VectorExpand (x));
|
||||
printf (" (%g %g %g)\n", VectorExpand (y));
|
||||
|
@ -146,7 +148,8 @@ test_transform2 (const vec3_t angles, const vec3_t scale)
|
|||
|
||||
return 1;
|
||||
fail:
|
||||
printf ("\n\n(%g %g %g) (%g %g %g) (%g %g %g)\n",
|
||||
printf ("\ntest_transform2\n");
|
||||
printf ("(%g %g %g) (%g %g %g) (%g %g %g)\n",
|
||||
VectorExpand (angles), VectorExpand (scale), VectorExpand (v));
|
||||
printf (" (%g %g %g)\n", VectorExpand (x));
|
||||
printf (" (%g %g %g)\n", VectorExpand (y));
|
||||
|
@ -173,7 +176,8 @@ test_inverse (const vec3_t angles, const vec3_t scale)
|
|||
|
||||
return 1;
|
||||
fail:
|
||||
printf ("\n\n(%g %g %g) (%g %g %g)\n",
|
||||
printf ("\ntest_inverse\n");
|
||||
printf ("(%g %g %g) (%g %g %g)\n",
|
||||
VectorExpand (angles), VectorExpand (scale));
|
||||
printf (" [%g %g %g]\n [%g %g %g]\n [%g %g %g]\n\n", Mat3Expand (mat));
|
||||
printf (" [%g %g %g]\n [%g %g %g]\n [%g %g %g]\n\n", Mat3Expand (inv));
|
||||
|
|
|
@ -9,7 +9,7 @@ static struct {
|
|||
quat_t q2;
|
||||
quat_t expect;
|
||||
} quat_mult_tests[] = {
|
||||
{{4, 1, 2, 3}, {8, 5, 6, 7}, {-6, 24, 48, 48}},
|
||||
{{1, 2, 3, 4}, {5, 6, 7, 8}, {24, 48, 48, -6}},
|
||||
};
|
||||
#define num_quat_mult_tests (sizeof (quat_mult_tests) / sizeof (quat_mult_tests[0]))
|
||||
|
||||
|
@ -50,10 +50,10 @@ test_quat_mult(const quat_t q1, const quat_t q2, const quat_t expect)
|
|||
goto fail;
|
||||
return 1;
|
||||
fail:
|
||||
printf ("%g %g %g %g\n", QuatExpand (q1));
|
||||
printf ("%g %g %g %g\n", QuatExpand (q2));
|
||||
printf ("%g %g %g %g\n", QuatExpand (r));
|
||||
printf ("%g %g %g %g\n", QuatExpand (expect));
|
||||
printf ("%11.9g %11.9g %11.9g %11.9g\n", QuatExpand (q1));
|
||||
printf ("%11.9g %11.9g %11.9g %11.9g\n", QuatExpand (q2));
|
||||
printf ("%11.9g %11.9g %11.9g %11.9g\n", QuatExpand (r));
|
||||
printf ("%11.9g %11.9g %11.9g %11.9g\n", QuatExpand (expect));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -64,12 +64,12 @@ rotate_vec (const quat_t r, const vec3_t v, vec3_t out)
|
|||
quat_t qv = {0, 0, 0, 0};
|
||||
quat_t t;
|
||||
|
||||
VectorCopy (v, qv + 1);
|
||||
VectorCopy (v, qv);
|
||||
|
||||
QuatConj (r, t);
|
||||
QuatMult (qv, t, t);
|
||||
QuatMult (r, t, t);
|
||||
VectorCopy (t + 1, out);
|
||||
VectorCopy (t, out);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -78,54 +78,55 @@ test_rotation (const vec3_t angles)
|
|||
int i;
|
||||
vec3_t forward, right, up;
|
||||
|
||||
quat_t quat, f, r, u, t;
|
||||
quat_t qf = {0, 1, 0, 0};
|
||||
quat_t qr = {0, 0, -1, 0};
|
||||
quat_t qu = {0, 0, 0, 1};
|
||||
quat_t quat, conj, f, r, u, t;
|
||||
quat_t qf = {1, 0, 0, 0};
|
||||
quat_t qr = {0, -1, 0, 0};
|
||||
quat_t qu = {0, 0, 1, 0};
|
||||
|
||||
AngleVectors (angles, forward, right, up);
|
||||
|
||||
AngleQuat (angles, quat);
|
||||
QuatConj (quat, conj);
|
||||
// rotate forward vector
|
||||
QuatConj (quat, t);
|
||||
QuatMult (qf, t, t);
|
||||
QuatMult (qf, conj, t);
|
||||
QuatMult (quat, t, f);
|
||||
// rotate right vector
|
||||
QuatConj (quat, t);
|
||||
QuatMult (qr, t, t);
|
||||
QuatMult (qr, conj, t);
|
||||
QuatMult (quat, t, r);
|
||||
// rotate up vector
|
||||
QuatConj (quat, t);
|
||||
QuatMult (qu, t, t);
|
||||
QuatMult (qu, conj, t);
|
||||
QuatMult (quat, t, u);
|
||||
|
||||
if (!compare (f[0], 0))
|
||||
if (!compare (f[3], 0))
|
||||
goto fail;
|
||||
for (i = 0; i < 3; i++)
|
||||
if (!compare (forward[i], f[i + 1]))
|
||||
if (!compare (forward[i], f[i]))
|
||||
goto fail;
|
||||
|
||||
if (!compare (r[0], 0))
|
||||
if (!compare (r[3], 0))
|
||||
goto fail;
|
||||
for (i = 0; i < 3; i++)
|
||||
if (!compare (right[i], r[i + 1]))
|
||||
if (!compare (right[i], r[i]))
|
||||
goto fail;
|
||||
|
||||
if (!compare (u[0], 0))
|
||||
if (!compare (u[3], 0))
|
||||
goto fail;
|
||||
for (i = 0; i < 3; i++)
|
||||
if (!compare (up[i], u[i + 1]))
|
||||
if (!compare (up[i], u[i]))
|
||||
goto fail;
|
||||
return 1;
|
||||
fail:
|
||||
printf ("\n\n%g %g %g\n\n", angles[0], angles[1], angles[2]);
|
||||
printf ("%g %g %g\n", forward[0], forward[1], forward[2]);
|
||||
printf ("%g %g %g\n", right[0], right[1], right[2]);
|
||||
printf ("%g %g %g\n\n", up[0], up[1], up[2]);
|
||||
printf ("\ntest_rotation\n");
|
||||
printf ("%11.9g %11.9g %11.9g\n", VectorExpand (angles));
|
||||
printf ("%11.9g %11.9g %11.9g %11.9g\n", QuatExpand (quat));
|
||||
printf ("%11.9g %11.9g %11.9g %11.9g\n\n", QuatExpand (conj));
|
||||
printf ("%11.9g %11.9g %11.9g\n", VectorExpand (forward));
|
||||
printf ("%11.9g %11.9g %11.9g\n", VectorExpand (right));
|
||||
printf ("%11.9g %11.9g %11.9g\n\n", VectorExpand (up));
|
||||
|
||||
printf ("%g %g %g %g\n", f[0], f[1], f[2], f[3]);
|
||||
printf ("%g %g %g %g\n", r[0], r[1], r[2], r[3]);
|
||||
printf ("%g %g %g %g\n", u[0], u[1], u[2], u[3]);
|
||||
printf ("%11.9g %11.9g %11.9g %11.9g\n", QuatExpand (f));
|
||||
printf ("%11.9g %11.9g %11.9g %11.9g\n", QuatExpand (r));
|
||||
printf ("%11.9g %11.9g %11.9g %11.9g\n", QuatExpand (u));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -164,14 +165,15 @@ test_rotation2 (const vec3_t angles)
|
|||
goto fail;
|
||||
return 1;
|
||||
fail:
|
||||
printf ("\n\n%g %g %g\n\n", angles[0], angles[1], angles[2]);
|
||||
printf ("%g %g %g\n", forward[0], forward[1], forward[2]);
|
||||
printf ("%g %g %g\n", right[0], right[1], right[2]);
|
||||
printf ("%g %g %g\n\n", up[0], up[1], up[2]);
|
||||
printf ("\ntest_rotation2\n");
|
||||
printf ("\n\n%11.9g %11.9g %11.9g\n\n", angles[0], angles[1], angles[2]);
|
||||
printf ("%11.9g %11.9g %11.9g\n", forward[0], forward[1], forward[2]);
|
||||
printf ("%11.9g %11.9g %11.9g\n", right[0], right[1], right[2]);
|
||||
printf ("%11.9g %11.9g %11.9g\n\n", up[0], up[1], up[2]);
|
||||
|
||||
printf ("%g %g %g\n", f[0], f[1], f[2]);
|
||||
printf ("%g %g %g\n", r[0], r[1], r[2]);
|
||||
printf ("%g %g %g\n", u[0], u[1], u[2]);
|
||||
printf ("%11.9g %11.9g %11.9g\n", f[0], f[1], f[2]);
|
||||
printf ("%11.9g %11.9g %11.9g\n", r[0], r[1], r[2]);
|
||||
printf ("%11.9g %11.9g %11.9g\n", u[0], u[1], u[2]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -192,8 +194,9 @@ test_rotation3 (const vec3_t angles)
|
|||
goto fail;
|
||||
return 1;
|
||||
fail:
|
||||
printf ("%g %g %g\n", VectorExpand(a));
|
||||
printf ("%g %g %g\n", VectorExpand(b));
|
||||
printf ("\ntest_rotation3\n");
|
||||
printf ("%11.9g %11.9g %11.9g\n", VectorExpand(a));
|
||||
printf ("%11.9g %11.9g %11.9g\n", VectorExpand(b));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -543,8 +543,8 @@ glsl_R_BuildDisplayLists (model_t **models, int num_models)
|
|||
msurface_t *surf;
|
||||
dstring_t *vertices;
|
||||
|
||||
QuatSet (sqrt(0.5), 0, 0, sqrt(0.5), sky_fix); // proper skies
|
||||
QuatSet (1, 0, 0, 0, sky_rotation[0]);
|
||||
QuatSet (0, 0, sqrt(0.5), sqrt(0.5), sky_fix); // proper skies
|
||||
QuatSet (0, 0, 0, 1, sky_rotation[0]);
|
||||
QuatCopy (sky_rotation[0], sky_rotation[1]);
|
||||
QuatSet (0, 0, 0, 0, sky_velocity);
|
||||
QuatExp (sky_velocity, sky_velocity);
|
||||
|
|
|
@ -464,8 +464,8 @@ main (void)
|
|||
m += bonemats[int (vbones.z)] * vweights.z;
|
||||
m += bonemats[int (vbones.w)] * vweights.w;
|
||||
#if 0
|
||||
q0 = m[0].yzwx; //swizzle for conversion betwen QF and GL
|
||||
qe = m[1].yzwx; //swizzle for conversion betwen QF and GL
|
||||
q0 = m[0];
|
||||
qe = m[1];
|
||||
sh = m[2].xyz;
|
||||
sc = m[3].xyz;
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ R_IQMBlendFrames (const iqm_t *iqm, int frame1, int frame2, float blend,
|
|||
} else {
|
||||
#if 0
|
||||
for (i = 0; i < iqm->num_joints; i++) {
|
||||
QuatSet (1, 0, 0, 0, frame[i].rt.q0.q);
|
||||
QuatSet (0, 0, 0, 1, frame[i].rt.q0.q);
|
||||
QuatSet (0, 0, 0, 0, frame[i].rt.qe.q);
|
||||
QuatSet (0, 0, 0, 0, frame[i].shear);
|
||||
QuatSet (1, 1, 1, 0, frame[i].scale);
|
||||
|
|
|
@ -593,11 +593,11 @@ do_op_quaternion (int op, expr_t *e, expr_t *e1, expr_t *e2)
|
|||
return e;
|
||||
|
||||
if (is_float_val (e1)) {
|
||||
float_quat[0] = expr_float (e1);
|
||||
QuatSet (0, 0, 0, expr_float (e1), float_quat);
|
||||
q2 = float_quat;
|
||||
q1 = expr_quaternion (e2);
|
||||
} else if (is_float_val (e2)) {
|
||||
float_quat[0] = expr_float (e2);
|
||||
QuatSet (0, 0, 0, expr_float (e2), float_quat);
|
||||
q2 = float_quat;
|
||||
q1 = expr_quaternion (e1);
|
||||
} else {
|
||||
|
@ -627,7 +627,7 @@ do_op_quaternion (int op, expr_t *e, expr_t *e1, expr_t *e2)
|
|||
if (get_type (e2) == &type_quaternion) {
|
||||
QuatMult (q1, q2, q);
|
||||
} else {
|
||||
QuatScale (q1, q2[0], q);
|
||||
QuatScale (q1, q2[3], q);
|
||||
}
|
||||
e = new_quaternion_expr (q);
|
||||
break;
|
||||
|
|
|
@ -163,35 +163,42 @@ convert_vector (expr_t *e)
|
|||
if (e->e.vector.type == &type_quaternion) {
|
||||
// guaranteed to have two or four elements
|
||||
if (e->e.vector.list->next->next) {
|
||||
// four vals: w, x, y, z
|
||||
expr_t *w = e->e.vector.list;
|
||||
expr_t *x = w->next;
|
||||
// four vals: x, y, z, w
|
||||
expr_t *x = e->e.vector.list;
|
||||
expr_t *y = x->next;
|
||||
expr_t *z = y->next;
|
||||
w = fold_constants (cast_expr (&type_float, w));
|
||||
expr_t *w = z->next;
|
||||
x = fold_constants (cast_expr (&type_float, x));
|
||||
y = fold_constants (cast_expr (&type_float, y));
|
||||
z = fold_constants (cast_expr (&type_float, z));
|
||||
if (is_constant (w) && is_constant (x) && is_constant (y)
|
||||
&& is_constant (z)) {
|
||||
val[0] = expr_float(w);
|
||||
val[1] = expr_float(x);
|
||||
val[2] = expr_float(y);
|
||||
val[3] = expr_float(z);
|
||||
w = fold_constants (cast_expr (&type_float, w));
|
||||
if (is_constant (x) && is_constant (y) && is_constant (z)
|
||||
&& is_constant (w)) {
|
||||
val[0] = expr_float(x);
|
||||
val[1] = expr_float(y);
|
||||
val[2] = expr_float(z);
|
||||
val[3] = expr_float(w);
|
||||
return new_quaternion_expr (val);
|
||||
}
|
||||
} else {
|
||||
// s, v
|
||||
expr_t *s = e->e.vector.list;
|
||||
expr_t *v = s->next;
|
||||
// v, s
|
||||
expr_t *v = e->e.vector.list;
|
||||
expr_t *s = v->next;
|
||||
|
||||
s = fold_constants (cast_expr (&type_float, s));
|
||||
v = convert_vector (v);
|
||||
if (is_constant (s) && is_constant (v)) {
|
||||
val[0] = expr_float (s);
|
||||
memcpy (val + 1, expr_vector (v), 3 * sizeof (float));
|
||||
s = fold_constants (cast_expr (&type_float, s));
|
||||
if (is_constant (v) && is_constant (s)) {
|
||||
memcpy (val, expr_vector (v), 3 * sizeof (float));
|
||||
val[3] = expr_float (s);
|
||||
return new_quaternion_expr (val);
|
||||
}
|
||||
// Either v or is is not constant, so can't convert to a quaternion
|
||||
// constant.
|
||||
// Rebuild the list in case v or s is a new expression
|
||||
s->next = 0;
|
||||
v->next = s;
|
||||
e->e.vector.list = v;
|
||||
return e;
|
||||
}
|
||||
}
|
||||
internal_error (e, "bogus vector expression");
|
||||
|
@ -645,13 +652,23 @@ new_vector_list (expr_t *e)
|
|||
vec->e.vector.list = e;
|
||||
break;
|
||||
case 2:
|
||||
// quaternion. first expression must be compatible with a float,
|
||||
// the other must be a vector
|
||||
if (!type_assignable (&type_float, get_type (e))
|
||||
|| !type_assignable (&type_vector, get_type(e->next))) {
|
||||
// quaternion. either float-ish, vector or vector, float-ish
|
||||
if (type_assignable (&type_float, get_type (e))
|
||||
&& type_assignable (&type_vector, get_type(e->next))) {
|
||||
// float-ish, vector
|
||||
// swap expressions
|
||||
t = e;
|
||||
e = e->next;
|
||||
e->next = t;
|
||||
t->next = 0;
|
||||
} else if (type_assignable (&type_vector, get_type (e))
|
||||
&& type_assignable (&type_float, get_type(e->next))) {
|
||||
// vector, float-ish
|
||||
// do nothing
|
||||
} else {
|
||||
return error (t, "invalid types for vector elements");
|
||||
}
|
||||
// s, v
|
||||
// v, s
|
||||
vec = new_expr ();
|
||||
vec->type = ex_vector;
|
||||
vec->e.vector.type = &type_quaternion;
|
||||
|
|
|
@ -193,8 +193,11 @@ qfo_init_string_space (qfo_t *qfo, qfo_mspace_t *space, strpool_t *strings)
|
|||
space->type = qfos_string;
|
||||
space->num_defs = 0;
|
||||
space->defs = 0;
|
||||
space->d.strings = 0;
|
||||
if (strings->strings) {
|
||||
space->d.strings = malloc (size);
|
||||
memcpy (space->d.strings, strings->strings, size);
|
||||
}
|
||||
space->data_size = strings->size;
|
||||
space->id = qfo_strings_space;
|
||||
}
|
||||
|
@ -207,8 +210,11 @@ qfo_init_code_space (qfo_t *qfo, qfo_mspace_t *space, codespace_t *code)
|
|||
space->type = qfos_code;
|
||||
space->num_defs = 0;
|
||||
space->defs = 0;
|
||||
space->d.code = 0;
|
||||
if (code->code) {
|
||||
space->d.code = malloc (size);
|
||||
memcpy (space->d.code, code->code, size);
|
||||
}
|
||||
space->data_size = code->size;
|
||||
space->id = qfo_code_space;
|
||||
}
|
||||
|
@ -222,8 +228,11 @@ qfo_init_data_space (qfo_t *qfo, qfo_def_t **defs, qfo_reloc_t **relocs,
|
|||
space->type = qfos_data;
|
||||
space->defs = *defs;
|
||||
space->num_defs = qfo_encode_defs (qfo, data->defs, defs, relocs);
|
||||
space->d.data = 0;
|
||||
if (data->data) {
|
||||
space->d.data = malloc (size);
|
||||
memcpy (space->d.data, data->data, size);
|
||||
}
|
||||
space->data_size = data->size;
|
||||
}
|
||||
|
||||
|
@ -249,8 +258,11 @@ qfo_init_type_space (qfo_t *qfo, qfo_def_t **defs, qfo_reloc_t **relocs,
|
|||
space->type = qfos_type;
|
||||
space->defs = *defs;
|
||||
space->num_defs = qfo_encode_defs (qfo, data->defs, defs, relocs);
|
||||
space->d.data = 0;
|
||||
if (data->data) {
|
||||
space->d.data = malloc (size);
|
||||
memcpy (space->d.data, data->data, size);
|
||||
}
|
||||
space->data_size = data->size;
|
||||
space->id = qfo_type_space;
|
||||
}
|
||||
|
|
|
@ -843,8 +843,8 @@ init_types (void)
|
|||
{0, 0}
|
||||
};
|
||||
static struct_def_t quaternion_struct[] = {
|
||||
{"s", &type_float},
|
||||
{"v", &type_vector},
|
||||
{"s", &type_float},
|
||||
{0, 0}
|
||||
};
|
||||
static struct_def_t type_encoding_struct[] = {
|
||||
|
@ -882,16 +882,16 @@ init_types (void)
|
|||
type_quaternion.meta = ty_none;
|
||||
{
|
||||
symbol_t *sym;
|
||||
sym = new_symbol_type ("w", &type_float);
|
||||
sym = new_symbol_type ("x", &type_float);
|
||||
sym->s.offset = 0;
|
||||
symtab_addsymbol (type_quaternion.t.symtab, sym);
|
||||
sym = new_symbol_type ("x", &type_float);
|
||||
sym = new_symbol_type ("y", &type_float);
|
||||
sym->s.offset = 1;
|
||||
symtab_addsymbol (type_quaternion.t.symtab, sym);
|
||||
sym = new_symbol_type ("y", &type_float);
|
||||
sym = new_symbol_type ("z", &type_float);
|
||||
sym->s.offset = 2;
|
||||
symtab_addsymbol (type_quaternion.t.symtab, sym);
|
||||
sym = new_symbol_type ("z", &type_float);
|
||||
sym = new_symbol_type ("w", &type_float);
|
||||
sym->s.offset = 3;
|
||||
symtab_addsymbol (type_quaternion.t.symtab, sym);
|
||||
}
|
||||
|
|
|
@ -316,9 +316,7 @@ imm_compare (const void *_imm1, const void *_imm2, void *_tab)
|
|||
return !memcmp (&imm1->i.pointer, &imm2->i.pointer,
|
||||
sizeof (imm1->i.pointer));
|
||||
} else if (tab == &quaternion_imm_defs) {
|
||||
return (VectorCompare (imm1->i.quaternion_val,
|
||||
imm2->i.quaternion_val)
|
||||
&& imm1->i.quaternion_val[3] == imm2->i.quaternion_val[3]);
|
||||
return QuatCompare (imm1->i.quaternion_val, imm2->i.quaternion_val);
|
||||
} else if (tab == &integer_imm_defs) {
|
||||
return imm1->i.integer_val == imm2->i.integer_val;
|
||||
} else {
|
||||
|
|
|
@ -37,6 +37,7 @@ test_progs_dat=\
|
|||
infloop.dat \
|
||||
modulo.dat \
|
||||
paramret.dat \
|
||||
quaternion.dat \
|
||||
return-ivar.dat \
|
||||
sendv.dat \
|
||||
state.dat \
|
||||
|
@ -130,6 +131,14 @@ paramret.run: Makefile build-run
|
|||
TEST_HARNESS_OPTS=--float $(srcdir)/build-run $@
|
||||
include ./$(DEPDIR)/paramret.Qo
|
||||
|
||||
quaternion_dat_SOURCES=quaternion.r
|
||||
quaternion_obj=$(quaternion_dat_SOURCES:.r=.qfo)
|
||||
quaternion.dat$(EXEEXT): $(quaternion_obj) $(QFCC_DEP)
|
||||
$(QFCC) $(QCFLAGS) -o $@ $(quaternion_obj)
|
||||
quaternion.run: Makefile build-run
|
||||
$(srcdir)/build-run $@
|
||||
include ./$(DEPDIR)/quaternion.Qo
|
||||
|
||||
return_ivar_dat_SOURCES=return-ivar.r
|
||||
return_ivar_obj=$(return_ivar_dat_SOURCES:.r=.qfo)
|
||||
return-ivar.dat$(EXEEXT): $(return_ivar_obj) $(QFCC_DEP)
|
||||
|
|
73
tools/qfcc/test/quaternion.r
Normal file
73
tools/qfcc/test/quaternion.r
Normal file
|
@ -0,0 +1,73 @@
|
|||
void printf (string fmt, ...) = #0;
|
||||
|
||||
int
|
||||
test_format ()
|
||||
{
|
||||
int fail = 0;
|
||||
quaternion q = '1 2 3 4';
|
||||
vector v = '-1 -2 -3';
|
||||
float s = -4;
|
||||
|
||||
if (q.x != 1 || q.y != 2 || q.z != 3 || q.w != 4) {
|
||||
printf ("q = '1 2 3 4' -> %q\n", q);
|
||||
fail = 1;
|
||||
}
|
||||
if (q.v != '1 2 3' || q.s != 4) {
|
||||
printf ("q = '1 2 3 4' -> %v, %g\n", q.v, q.s);
|
||||
fail = 1;
|
||||
}
|
||||
q = nil;
|
||||
if (q.x != 0 || q.y != 0 || q.z != 0 || q.w != 0) {
|
||||
printf ("q = nil -> %q\n", q);
|
||||
fail = 1;
|
||||
}
|
||||
if (q.v != '0 0 0' || q.s != 0) {
|
||||
printf ("q = nil -> %v, %g\n", q.v, q.s);
|
||||
fail = 1;
|
||||
}
|
||||
q = [1, [2, 3, 4]];
|
||||
if (q.x != 2 || q.y != 3 || q.z != 4 || q.w != 1) {
|
||||
printf ("q = [1, [2, 3, 4]] -> %q\n", q);
|
||||
fail = 1;
|
||||
}
|
||||
if (q.v != '2 3 4' || q.s != 1) {
|
||||
printf ("q = [1, [2, 3, 4]] -> %v, %g\n", q.v, q.s);
|
||||
fail = 1;
|
||||
}
|
||||
q = [[5, 6, 7], 8];
|
||||
if (q.x != 5 || q.y != 6 || q.z != 7 || q.w != 8) {
|
||||
printf ("q = [[5, 6, 7], 8] -> %q\n", q);
|
||||
fail = 1;
|
||||
}
|
||||
if (q.v != '5 6 7' || q.s != 8) {
|
||||
printf ("q = [[5, 6, 7], 8] -> %v, %g\n", q.v, q.s);
|
||||
fail = 1;
|
||||
}
|
||||
/* q = [s, v];
|
||||
if (q.x != v.x || q.y != v.y || q.z != v.z || q.w != s) {
|
||||
printf ("q = [s, v] -> %q (%v)\n", q, v);
|
||||
fail = 1;
|
||||
}
|
||||
if (q.v != v || q.s != s) {
|
||||
printf ("q = [s, v] -> %v, %g (%v)\n", q.v, q.s, v);
|
||||
fail = 1;
|
||||
}
|
||||
q = [v, s];
|
||||
if (q.x != v.x || q.y != v.y || q.z != v.z || q.w != s) {
|
||||
printf ("q = [v, s] -> %q (%v %s)\n", q, v, s);
|
||||
fail = 1;
|
||||
}
|
||||
if (q.v != v || q.s != s) {
|
||||
printf ("q = [v, s] -> %v, %g (%v %s)\n", q.v, q.s, v, s);
|
||||
fail = 1;
|
||||
}*/
|
||||
return fail;
|
||||
}
|
||||
|
||||
int
|
||||
main ()
|
||||
{
|
||||
int fail = 0;
|
||||
fail |= test_format ();
|
||||
return fail;
|
||||
}
|
|
@ -165,7 +165,10 @@ load_progs (const char *name)
|
|||
return 0;
|
||||
}
|
||||
pr.progs_name = name;
|
||||
PR_LoadProgsFile (&pr, file, size, 16, 1024 * 1024);
|
||||
pr.max_edicts = 16;
|
||||
pr.zone_size = 1024 * 1024;
|
||||
pr.stack_size = 64 * 1024;
|
||||
PR_LoadProgsFile (&pr, file, size);
|
||||
Qclose (file);
|
||||
if (!PR_RunLoadFuncs (&pr))
|
||||
PR_Error (&pr, "unable to load %s", pr.progs_name);
|
||||
|
|
Loading…
Reference in a new issue