diff --git a/tools/qfcc/source/expr_algebra.c b/tools/qfcc/source/expr_algebra.c index d450b46f3..2ee35774a 100644 --- a/tools/qfcc/source/expr_algebra.c +++ b/tools/qfcc/source/expr_algebra.c @@ -351,7 +351,7 @@ pga3_x_y_z_w_dot_yz_zx_xy (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg) auto vtype = vector_type (stype, 3); auto dot_type = algebra_mvec_type (alg, 0x01); auto va = offset_cast (vtype, a, 0); - c[2] = cross_expr (dot_type, b, va); + c[0] = new_extend_expr (cross_expr (vtype, b, va), dot_type, 0, false); } static void @@ -375,7 +375,6 @@ pga3_x_y_z_w_dot_wxyz (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg) c[5] = new_extend_expr (cv, algebra_mvec_type (alg, 0x20), 0, false); } -#define pga3_wzy_wxz_wyx_xyz_dot_x_y_z_w pga3_x_y_z_w_dot_wzy_wxz_wyx_xyz static void pga3_x_y_z_w_dot_wzy_wxz_wyx_xyz (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg) @@ -397,8 +396,8 @@ pga3_yz_zx_xy_dot_x_y_z_w (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg) auto stype = alg->type; auto vtype = vector_type (stype, 3); auto dot_type = algebra_mvec_type (alg, 0x01); - auto vb = offset_cast (vtype, a, 0); - c[2] = cross_expr (dot_type, a, vb); + auto vb = offset_cast (vtype, b, 0); + c[0] = new_extend_expr (cross_expr (vtype, vb, a), dot_type, 0, false); } static void @@ -408,7 +407,6 @@ pga3_yz_zx_xy_dot_yz_zx_xy (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg) c[2] = unary_expr ('-', dot_expr (dot_type, a, b)); } -#define pga3_wxyz_dot_yz_zx_xy pga3_yz_zx_xy_dot_wxyz static void pga3_yz_zx_xy_dot_wxyz (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg) { @@ -419,7 +417,6 @@ pga3_yz_zx_xy_dot_wxyz (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg) c[3] = scale_expr (bmtype, va, unary_expr ('-', sb)); } -#define pga3_wzy_wxz_wyx_xyz_dot_yz_zx_xy pga3_yz_zx_xy_dot_wzy_wxz_wyx_xyz static void pga3_yz_zx_xy_dot_wzy_wxz_wyx_xyz (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg) @@ -443,8 +440,8 @@ pga3_wx_wy_wz_dot_x_y_z_w (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg) { auto stype = alg->type; auto vtype = vector_type (stype, 3); - auto va = offset_cast (vtype, a, 0); - auto cs = dot_expr (stype, b, va); + auto vb = offset_cast (vtype, b, 0); + auto cs = dot_expr (stype, a, vb); c[0] = new_extend_expr (cs, algebra_mvec_type (alg, 0x01), 0, true); } @@ -459,6 +456,16 @@ pga3_wxyz_dot_x_y_z_w (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg) c[5] = scale_expr (dot_type, vb, sa); } +static void +pga3_wxyz_dot_yz_zx_xy (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg) +{ + auto stype = alg->type; + auto bmtype = algebra_mvec_type (alg, 0x08); + auto sa = offset_cast (stype, a, 0); + auto vb = offset_cast (bmtype, b, 0); + c[3] = scale_expr (bmtype, vb, unary_expr ('-', sa)); +} + static void pga3_wxyz_dot_wzy_wxz_wyx_xyz (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg) { @@ -470,12 +477,45 @@ pga3_wxyz_dot_wzy_wxz_wyx_xyz (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg) c[0] = new_extend_expr (cs, algebra_mvec_type (alg, 0x01), 0, true); } +static void +pga3_wzy_wxz_wyx_xyz_dot_x_y_z_w (expr_t **c, expr_t *a, expr_t *b, + algebra_t *alg) +{ + auto stype = alg->type; + auto vtype = vector_type (stype, 3); + auto bvtype = algebra_mvec_type (alg, 0x02); + auto bmtype = algebra_mvec_type (alg, 0x08); + auto sa = offset_cast (stype, a, 3); + auto va = offset_cast (vtype, a, 0); + auto vb = offset_cast (vtype, b, 0); + c[1] = scale_expr (bvtype, vb, sa); + c[3] = cross_expr (bmtype, va, vb); +} + +static void +pga3_wzy_wxz_wyx_xyz_dot_yz_zx_xy (expr_t **c, expr_t *a, expr_t *b, + algebra_t *alg) +{ + auto stype = alg->type; + auto vtype = vector_type (stype, 3); + auto dot_type = algebra_mvec_type (alg, 0x01); + + auto va = offset_cast (vtype, a, 0); + auto sa = offset_cast (stype, a, 3); + + auto cv = scale_expr (vtype, b, sa); + auto cs = dot_expr (stype, b, va); + + c[0] = sum_expr (dot_type, '-', new_extend_expr (cs, dot_type, 0, true), + new_extend_expr (cv, dot_type, 0, false)); +} + static void pga3_wzy_wxz_wyx_xyz_dot_wxyz (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg) { auto stype = alg->type; - auto sa = offset_cast (stype, a, 0); - auto sb = offset_cast (stype, b, 3); + auto sa = offset_cast (stype, a, 3); + auto sb = offset_cast (stype, b, 0); auto cs = scale_expr (stype, sa, sb); c[0] = new_extend_expr (cs, algebra_mvec_type (alg, 0x01), 0, true); } diff --git a/tools/qfcc/test/pga3d.r b/tools/qfcc/test/pga3d.r index 09e10631b..52a7d2d5b 100644 --- a/tools/qfcc/test/pga3d.r +++ b/tools/qfcc/test/pga3d.r @@ -27,36 +27,9 @@ typedef union { }; } oddgrades_t; -int -main (void) +static int +test_wedge (void) { - if (sizeof (scalar_t) != sizeof (float)) { - printf ("scalar has wrong size: %d\n", sizeof (scalar_t)); - return 1; - } - if (sizeof (vector_t) != 4 * sizeof (scalar_t)) { - printf ("bivector has wrong size: %d\n", sizeof (vector_t)); - return 1; - } - // the pair of vec3s in a bivector have an alignment of 4 - if (sizeof (bivector_t) != 8 * sizeof (scalar_t)) { - printf ("bivector has wrong size: %d\n", sizeof (bivector_t)); - return 1; - } - if (sizeof (bivector_t) != sizeof (PGA.group_mask(0x0a))) { - printf ("bivector group has wrong size: %d\n", - sizeof (PGA.group_mask(0x0a))); - return 1; - } - if (sizeof (trivector_t) != 4 * sizeof (scalar_t)) { - printf ("trivector has wrong size: %d\n", sizeof (trivector_t)); - return 1; - } - if (sizeof (quadvector_t) != sizeof (scalar_t)) { - printf ("quadvector has wrong size: %d\n", sizeof (quadvector_t)); - return 1; - } - scalar_t scalar; vector_t vec, vecb, vecc, vecd; bivector_t bvec, bvecb; @@ -147,6 +120,163 @@ main (void) printf ("(vecd ∧ vecc) ∧ a != 742': %g\n", (scalar_t) c); return 1; } + return 0; +} + +static int +test_dot (void) +{ + scalar_t scalar; + vector_t vec, vecb, vecc, vecd; + bivector_t bvec, bvecb; + trivector_t tvec, tvecb; + quadvector_t qvec, qvecb; + @algebra (PGA) { + scalar = 42; + vec = 3*e1 - 2*e2 + 4*e3 + e0; + bvec.bvec = -3*e01 + 5*e02 + 7*e03 + 11*e23 - 4*e31 + 2*e12; + tvec = 1*e032 + 4*e013 + 7*e021 - 2*e123; + qvec = 8*e0123; + + vecb = 5*e1 + 12*e2 - 13*e0; + bvecb.bvec = 6*e20 + 4*e01 + 1*e12; + tvecb = 3*e032; + qvecb = 1*e0123; + + vecc = 5*e1 + 4*e2 - 3*e3 + 4*e0; + vecd = e1 + e2 + e3 + e0; + } + + if (qvec • qvecb != 0) { + printf ("(qvec • qvecb) != 0': %g\n", qvec • qvecb); + return 1; + } + + auto a = tvec • qvec; + if ((vec4)a != '0 0 0 -16') { + printf ("vec • vecb != '0 0 0 -16': %v\n", a); + return 1; + } + + bivector_t b = { .mom = bvec.bvec • qvec }; + if ((vec3)b.dir != '0 0 0' || (vec3)b.mom != '-88 32 -16') { + printf ("bvec • qvec != '0 0 0' '-88 32 -16': %v %v\n", b.dir, b.mom); + return 1; + } + + auto c = vec • qvec; + if ((vec4)c != '24 -16 32 0') { + printf ("vec • qvec != '24 -16 32 0': %v\n", c); + return 1; + } + + a = bvec.bvec • tvec; + if ((vec4)a != '22 -8 4 9') { + printf ("bvec • tvec != '22 -8 4 9': %v\n", a); + return 1; + } + + b.bvec = vec • tvec; + if ((vec3)b.dir != '-6 4 -8' || (vec3)b.mom != '30 17 -14') { + printf ("vec • tvec != '-6 4 -8' '30 17 -14': %v %v\n", b.dir, b.mom); + return 1; + } + + if (bvec.bvec • bvec.bvec != -141) { + printf ("(bvec • bvec) != -141': %g\n", bvec.bvec • bvec.bvec); + return 1; + } + + a = vec • bvec.bvec; + if ((vec4)a != '-12 -38 -10 -9') { + printf ("vec • bvec != '-12 -38 -10 -9': %v\n", a); + return 1; + } + + if (vec • vecb != -9) { + printf ("(vec • vecb) != -9': %g\n", vec • vecb); + return 1; + } + + a = qvec • tvec; + if ((vec4)a != '0 0 0 16') { + printf ("vec • vecb != '0 0 0 16': %v\n", a); + return 1; + } + + b.dir = nil;//FIXME allow bvec = mom + b.mom = qvec • bvec.bvec; + if ((vec3)b.dir != '0 0 0' || (vec3)b.mom != '-88 32 -16') { + printf ("qvec • bvec != '0 0 0' '-88 32 -16': %v %v\n", b.dir, b.mom); + return 1; + } + + c = qvec • vec; + if ((vec4)c != '-24 16 -32 0') { + printf ("vec • qvec != '-24 16 -32 0': %v\n", c); + return 1; + } + + a = tvec • bvec.bvec; + if ((vec4)a != '22 -8 4 9') { + printf ("tvec • vec != '22 -8 4 9': %v\n", a); + return 1; + } + + b.bvec = tvec • vec; + if ((vec3)b.dir != '-6 4 -8' || (vec3)b.mom != '30 17 -14') { + printf ("tvec • vec != '-6 4 -8' '30 17 -14': %v %v\n", b.dir, b.mom); + return 1; + } + + a = bvec.bvec • vec; + if ((vec4)a != '12 38 10 9') { + printf ("bvec • vec != '12 38 10 9': %q\n", a); + return 1; + } + + return 0; +} + +int +main (void) +{ + if (sizeof (scalar_t) != sizeof (float)) { + printf ("scalar has wrong size: %d\n", sizeof (scalar_t)); + return 1; + } + if (sizeof (vector_t) != 4 * sizeof (scalar_t)) { + printf ("bivector has wrong size: %d\n", sizeof (vector_t)); + return 1; + } + // the pair of vec3s in a bivector have an alignment of 4 + if (sizeof (bivector_t) != 8 * sizeof (scalar_t)) { + printf ("bivector has wrong size: %d\n", sizeof (bivector_t)); + return 1; + } + if (sizeof (bivector_t) != sizeof (PGA.group_mask(0x0a))) { + printf ("bivector group has wrong size: %d\n", + sizeof (PGA.group_mask(0x0a))); + return 1; + } + if (sizeof (trivector_t) != 4 * sizeof (scalar_t)) { + printf ("trivector has wrong size: %d\n", sizeof (trivector_t)); + return 1; + } + if (sizeof (quadvector_t) != sizeof (scalar_t)) { + printf ("quadvector has wrong size: %d\n", sizeof (quadvector_t)); + return 1; + } + + if (test_wedge ()) { + printf ("wedge products failed\n"); + return 1; + } + + if (test_dot ()) { + printf ("dot products failed\n"); + return 1; + } return 0; // to survive and prevail :) }