mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-26 06:10:56 +00:00
[qfcc] Implement 3d PGA dot products
Also, correct the handling of scalars in dot and wedge products: it turns out s.v and s^v both scale. However, it seems the CSE code loses things sometimes.
This commit is contained in:
parent
6d75d91de2
commit
5f22fd07d9
4 changed files with 239 additions and 16 deletions
|
@ -85,6 +85,7 @@ struct expr_s;
|
|||
bool is_algebra (const struct type_s *type) __attribute__((pure));
|
||||
struct type_s *algebra_type (struct type_s *type, struct expr_s *params);
|
||||
struct type_s *algebra_mvec_type (algebra_t *algebra, pr_uint_t group_mask);
|
||||
struct ex_value_s *algebra_blade_value (algebra_t *alg, const char *name);
|
||||
struct symtab_s *algebra_scope (struct type_s *type, struct symtab_s *curscope);
|
||||
void algebra_print_type_str (struct dstring_s *str, const struct type_s *type);
|
||||
void algebra_encode_type (struct dstring_s *encoding,
|
||||
|
|
|
@ -456,11 +456,9 @@ static int pga_swaps_3d[16] = {
|
|||
[0xd] = 1, // e032
|
||||
};
|
||||
|
||||
static symbol_t *
|
||||
algebra_symbol (const char *name, symtab_t *symtab)
|
||||
ex_value_t *
|
||||
algebra_blade_value (algebra_t *alg, const char *name)
|
||||
{
|
||||
algebra_t *alg = symtab->procsymbol_data;
|
||||
symbol_t *sym = 0;
|
||||
uint32_t dimension = alg->plus + alg->minus + alg->zero;
|
||||
bool pga_2d = (alg->plus == 2 && alg->minus == 0 && alg->zero == 1);
|
||||
bool pga_3d = (alg->plus == 3 && alg->minus == 0 && alg->zero == 1);
|
||||
|
@ -513,12 +511,24 @@ algebra_symbol (const char *name, symtab_t *symtab)
|
|||
components[g[1]] = sign;
|
||||
blade_val = new_type_value (group_type, (pr_type_t *)components);
|
||||
}
|
||||
sym = new_symbol_type (name, group_type);
|
||||
return blade_val;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static symbol_t *
|
||||
algebra_symbol (const char *name, symtab_t *symtab)
|
||||
{
|
||||
algebra_t *alg = symtab->procsymbol_data;
|
||||
symbol_t *sym = 0;
|
||||
|
||||
auto blade_val = algebra_blade_value (alg, name);
|
||||
if (blade_val) {
|
||||
sym = new_symbol_type (name, blade_val->type);
|
||||
sym->sy_type = sy_const;
|
||||
sym->s.value = blade_val;
|
||||
symtab_addsymbol (symtab, sym);
|
||||
}
|
||||
|
||||
return sym;
|
||||
}
|
||||
|
||||
|
|
|
@ -285,6 +285,14 @@ dot_expr (type_t *type, expr_t *a, expr_t *b)
|
|||
return dot;
|
||||
}
|
||||
|
||||
static expr_t *
|
||||
cross_expr (type_t *type, expr_t *a, expr_t *b)
|
||||
{
|
||||
auto cross = new_binary_expr (CROSS, a, b);
|
||||
cross->e.expr.type = type;
|
||||
return cross;
|
||||
}
|
||||
|
||||
typedef void (*pga_func) (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg);
|
||||
static void
|
||||
scale_component (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
||||
|
@ -294,9 +302,210 @@ scale_component (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
|||
c[group] = scale;
|
||||
}
|
||||
|
||||
static void
|
||||
pga3_x_y_z_w_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, 0x04);
|
||||
auto va = new_offset_alias_expr (vtype, a, 0);
|
||||
auto vb = new_offset_alias_expr (vtype, b, 0);
|
||||
c[2] = dot_expr (dot_type, va, vb);
|
||||
}
|
||||
|
||||
static void
|
||||
pga3_x_y_z_w_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 = new_offset_alias_expr (vtype, a, 0);
|
||||
c[2] = cross_expr (dot_type, b, va);
|
||||
}
|
||||
|
||||
static void
|
||||
pga3_x_y_z_w_dot_wx_wy_wz (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
||||
{
|
||||
auto stype = alg->type;
|
||||
auto vtype = vector_type (stype, 3);
|
||||
auto va = new_offset_alias_expr (vtype, a, 0);
|
||||
auto cs = dot_expr (stype, b, va);
|
||||
auto blade = new_value_expr (algebra_blade_value (alg, "e0"));
|
||||
c[0] = scale_expr (blade, unary_expr ('-', cs), alg);
|
||||
}
|
||||
|
||||
static void
|
||||
pga3_x_y_z_w_dot_wxyz (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
||||
{
|
||||
auto stype = alg->type;
|
||||
auto dot_type = algebra_mvec_type (alg, 0x20);
|
||||
auto va = new_offset_alias_expr (dot_type, new_swizzle_expr (a, "xyz0"), 0);
|
||||
auto sb = new_offset_alias_expr (stype, b, 0);
|
||||
c[5] = scale_expr (va, sb, alg);
|
||||
}
|
||||
|
||||
#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)
|
||||
{
|
||||
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 va = new_offset_alias_expr (bvtype, a, 0);
|
||||
auto vb = new_offset_alias_expr (vtype, b, 0);
|
||||
auto sb = new_offset_alias_expr (stype, b, 3);
|
||||
c[1] = scale_expr (va, sb, alg);
|
||||
c[3] = cross_expr (bmtype, vb, va);
|
||||
}
|
||||
|
||||
static void
|
||||
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 = new_offset_alias_expr (vtype, a, 0);
|
||||
c[2] = cross_expr (dot_type, a, vb);
|
||||
}
|
||||
|
||||
static void
|
||||
pga3_yz_zx_xy_dot_yz_zx_xy (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
||||
{
|
||||
auto dot_type = algebra_mvec_type (alg, 0x04);
|
||||
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)
|
||||
{
|
||||
auto stype = alg->type;
|
||||
auto bmtype = algebra_mvec_type (alg, 0x08);
|
||||
auto va = new_offset_alias_expr (bmtype, a, 0);
|
||||
auto sb = new_offset_alias_expr (stype, b, 0);
|
||||
c[3] = scale_expr (va, unary_expr ('-', sb), alg);
|
||||
}
|
||||
|
||||
#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)
|
||||
{
|
||||
auto stype = alg->type;
|
||||
auto vtype = vector_type (stype, 3);
|
||||
auto dot_type = algebra_mvec_type (alg, 0x01);
|
||||
|
||||
auto vb = new_offset_alias_expr (vtype, b, 0);
|
||||
auto sb = new_offset_alias_expr (stype, b, 3);
|
||||
|
||||
auto cv = scale_expr (a, sb, alg);
|
||||
auto cs = dot_expr (stype, a, vb);
|
||||
|
||||
auto tmp = new_temp_def_expr (dot_type);
|
||||
auto vtmp = new_offset_alias_expr (vtype, tmp, 0);
|
||||
auto stmp = new_offset_alias_expr (stype, tmp, 3);
|
||||
auto block = new_block_expr ();
|
||||
block->e.block.result = tmp;
|
||||
append_expr (block, assign_expr (vtmp, cv));
|
||||
append_expr (block, assign_expr (stmp, cs));
|
||||
c[0] = block;
|
||||
}
|
||||
|
||||
static void
|
||||
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 = new_offset_alias_expr (vtype, a, 0);
|
||||
auto cs = dot_expr (stype, b, va);
|
||||
auto blade = new_value_expr (algebra_blade_value (alg, "e0"));
|
||||
c[0] = scale_expr (blade, cs, alg);
|
||||
}
|
||||
|
||||
static void
|
||||
pga3_wxyz_dot_x_y_z_w (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
||||
{
|
||||
auto stype = alg->type;
|
||||
auto dot_type = algebra_mvec_type (alg, 0x20);
|
||||
auto vb = new_offset_alias_expr (dot_type,
|
||||
new_swizzle_expr (b, "-x-y-z0"), 0);
|
||||
auto sa = new_offset_alias_expr (stype, a, 0);
|
||||
c[5] = scale_expr (vb, sa, alg);
|
||||
}
|
||||
|
||||
static void
|
||||
pga3_wxyz_dot_wzy_wxz_wyx_xyz (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
||||
{
|
||||
auto stype = alg->type;
|
||||
auto sa = new_offset_alias_expr (stype, a, 0);
|
||||
auto sb = new_offset_alias_expr (stype, b, 3);
|
||||
auto blade = new_value_expr (algebra_blade_value (alg, "e0"));
|
||||
sb = unary_expr ('-', sb);
|
||||
c[0] = scale_expr (blade, scale_expr (sa, sb, alg), alg);
|
||||
}
|
||||
|
||||
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 = new_offset_alias_expr (stype, a, 0);
|
||||
auto sb = new_offset_alias_expr (stype, b, 3);
|
||||
auto blade = new_value_expr (algebra_blade_value (alg, "e0"));
|
||||
c[0] = scale_expr (blade, scale_expr (sa, sb, alg), alg);
|
||||
}
|
||||
|
||||
static void
|
||||
pga3_wzy_wxz_wyx_xyz_dot_wzy_wxz_wyx_xyz (expr_t **c, expr_t *a, expr_t *b,
|
||||
algebra_t *alg)
|
||||
{
|
||||
auto stype = alg->type;
|
||||
auto sa = new_offset_alias_expr (stype, a, 3);
|
||||
auto sb = new_offset_alias_expr (stype, b, 3);
|
||||
c[0] = unary_expr ('-', scale_expr (sa, sb, alg));
|
||||
}
|
||||
|
||||
static pga_func pga3_dot_funcs[6][6] = {
|
||||
[2] = {
|
||||
[0] = {
|
||||
[0] = pga3_x_y_z_w_dot_x_y_z_w,
|
||||
[1] = pga3_x_y_z_w_dot_yz_zx_xy,
|
||||
[2] = scale_component,
|
||||
[3] = pga3_x_y_z_w_dot_wx_wy_wz,
|
||||
[4] = pga3_x_y_z_w_dot_wxyz,
|
||||
[5] = pga3_x_y_z_w_dot_wzy_wxz_wyx_xyz,
|
||||
},
|
||||
[1] = {
|
||||
[0] = pga3_yz_zx_xy_dot_x_y_z_w,
|
||||
[1] = pga3_yz_zx_xy_dot_yz_zx_xy,
|
||||
[2] = scale_component,
|
||||
[4] = pga3_yz_zx_xy_dot_wxyz,
|
||||
[5] = pga3_yz_zx_xy_dot_wzy_wxz_wyx_xyz,
|
||||
},
|
||||
[2] = {
|
||||
[0] = scale_component,
|
||||
[1] = scale_component,
|
||||
[2] = scale_component,
|
||||
[3] = scale_component,
|
||||
[4] = scale_component,
|
||||
[5] = scale_component,
|
||||
},
|
||||
[3] = {
|
||||
[0] = pga3_wx_wy_wz_dot_x_y_z_w,
|
||||
[2] = scale_component,
|
||||
},
|
||||
[4] = {
|
||||
[0] = pga3_wxyz_dot_x_y_z_w,
|
||||
[1] = pga3_wxyz_dot_yz_zx_xy,
|
||||
[2] = scale_component,
|
||||
[5] = pga3_wxyz_dot_wzy_wxz_wyx_xyz,
|
||||
},
|
||||
[5] = {
|
||||
[0] = pga3_wzy_wxz_wyx_xyz_dot_x_y_z_w,
|
||||
[1] = pga3_wzy_wxz_wyx_xyz_dot_yz_zx_xy,
|
||||
[2] = scale_component,
|
||||
[4] = pga3_wzy_wxz_wyx_xyz_dot_wxyz,
|
||||
[5] = pga3_wzy_wxz_wyx_xyz_dot_wzy_wxz_wyx_xyz,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -317,8 +526,7 @@ pga2_yw_wx_xy_dot_x_y_w (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
|||
auto dot_type = algebra_mvec_type (alg, 0x04);
|
||||
auto va = new_offset_alias_expr (dot_type, new_swizzle_expr (a, "y-x0"), 0);
|
||||
auto sb = new_offset_alias_expr (stype, b, 2);
|
||||
auto tmp = new_binary_expr (CROSS, a, b);
|
||||
tmp->e.expr.type = dot_type;
|
||||
auto tmp = cross_expr (dot_type, a, b);
|
||||
tmp = new_offset_alias_expr (dot_type, new_swizzle_expr (tmp, "00z"), 0);
|
||||
c[2] = new_binary_expr ('+', scale_expr (va, sb, alg), tmp);
|
||||
c[2]->e.expr.type = dot_type;
|
||||
|
@ -331,8 +539,7 @@ pga2_x_y_w_dot_yw_wx_xy (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
|||
auto dot_type = algebra_mvec_type (alg, 0x04);
|
||||
auto va = new_offset_alias_expr (dot_type, new_swizzle_expr (a, "-yx0"), 0);
|
||||
auto sb = new_offset_alias_expr (stype, b, 2);
|
||||
auto tmp = new_binary_expr (CROSS, a, b);
|
||||
tmp->e.expr.type = dot_type;
|
||||
auto tmp = cross_expr (dot_type, a, b);
|
||||
tmp = new_offset_alias_expr (dot_type, new_swizzle_expr (tmp, "00-z"), 0);
|
||||
c[2] = new_binary_expr ('+', scale_expr (va, sb, alg), tmp);
|
||||
c[2]->e.expr.type = dot_type;
|
||||
|
@ -387,7 +594,10 @@ static pga_func pga2_dot_funcs[4][4] = {
|
|||
[2] = pga2_yw_wx_xy_dot_x_y_w,
|
||||
},
|
||||
[1] = {
|
||||
[0] = scale_component,
|
||||
[1] = scale_component,
|
||||
[2] = scale_component,
|
||||
[3] = scale_component,
|
||||
},
|
||||
[2] = {
|
||||
[0] = pga2_x_y_w_dot_yw_wx_xy,
|
||||
|
@ -466,8 +676,7 @@ pga3_x_y_z_w_wedge_x_y_z_w (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
|||
auto vb = new_offset_alias_expr (vtype, b, 0);
|
||||
auto sa = new_offset_alias_expr (stype, a, 3);
|
||||
auto sb = new_offset_alias_expr (stype, b, 3);
|
||||
c[1] = new_binary_expr (CROSS, va, vb);
|
||||
c[1]->e.expr.type = algebra_mvec_type (alg, 0x02);
|
||||
c[1] = cross_expr (algebra_mvec_type (alg, 0x02), va, vb);
|
||||
c[3] = new_binary_expr ('-', scale_expr (vb, sa, alg),
|
||||
scale_expr (va, sb, alg));
|
||||
c[3]->e.expr.type = wedge_type;
|
||||
|
@ -503,7 +712,7 @@ pga3_x_y_z_w_wedge_wx_wy_wz (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
|||
auto vtype = vector_type (stype, 3);
|
||||
auto wedge_type = algebra_mvec_type (alg, 0x20);
|
||||
auto va = new_offset_alias_expr (vtype, a, 0);
|
||||
auto cv = new_binary_expr (CROSS, va, b);
|
||||
auto cv = cross_expr (vtype, va, b);
|
||||
auto cs = new_zero_expr (stype);
|
||||
auto tmp = new_temp_def_expr (wedge_type);
|
||||
auto vtmp = new_offset_alias_expr (vtype, tmp, 0);
|
||||
|
@ -584,8 +793,7 @@ static void
|
|||
pga2_x_y_w_wedge_x_y_w (expr_t **c, expr_t *a, expr_t *b, algebra_t *alg)
|
||||
{
|
||||
auto wedge_type = algebra_mvec_type (alg, 0x01);
|
||||
c[0] = new_binary_expr (CROSS, a, b);
|
||||
c[0]->e.expr.type = wedge_type;
|
||||
c[0] = cross_expr (wedge_type, a, b);
|
||||
}
|
||||
|
||||
static pga_func pga2_wedge_funcs[4][4] = {
|
||||
|
@ -604,6 +812,9 @@ static pga_func pga2_wedge_funcs[4][4] = {
|
|||
[1] = scale_component,
|
||||
[2] = pga2_x_y_w_wedge_x_y_w,
|
||||
},
|
||||
[3] = {
|
||||
[1] = scale_component,
|
||||
},
|
||||
};
|
||||
|
||||
static void
|
||||
|
|
|
@ -24,6 +24,7 @@ main (void)
|
|||
auto v = 4*(e1 + e032 + e123);
|
||||
pgaf1 = p1 + v;// * p2;
|
||||
pgaf1 = (p1 + v)∧p2;
|
||||
pgaf1 = v • p2;
|
||||
#if 0
|
||||
auto rx = e23;
|
||||
auto ry = e31;
|
||||
|
|
Loading…
Reference in a new issue