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:
Bill Currie 2018-10-12 14:33:55 +09:00
parent b7aa5bb8fe
commit f58c2fef5a
17 changed files with 272 additions and 159 deletions

View file

@ -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 { \

View file

@ -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;

View file

@ -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)

View file

@ -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;

View file

@ -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));

View file

@ -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;
}

View file

@ -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);

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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 {

View file

@ -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)

View 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;
}

View file

@ -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);