mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-04-08 18:31:59 +00:00
[qfcc] Implement quaternion multiplication
I'm surprised it took almost two years to discover that I had no quaternion multiplications in any test code, but getting an ICE for a quaternion-vector product, and the Hadamard product for quaternion-quaternion was a bit of a nasty surprise.
This commit is contained in:
parent
2e19e2d913
commit
5fef8e6edb
3 changed files with 17 additions and 3 deletions
|
@ -48,6 +48,7 @@ typedef struct {
|
|||
bool (*commutative) (void);
|
||||
bool (*anticommute) (void);
|
||||
bool (*associative) (void);
|
||||
int true_op;
|
||||
} expr_type_t;
|
||||
|
||||
static const expr_t *pointer_arithmetic (int op, const expr_t *e1,
|
||||
|
@ -272,7 +273,12 @@ static expr_type_t quat_float[] = {
|
|||
};
|
||||
|
||||
static expr_type_t quat_vector[] = {
|
||||
{'*', &type_vector},
|
||||
{'*', &type_vector, .true_op = QVMUL},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
static expr_type_t vector_quat[] = {
|
||||
{'*', &type_vector, .true_op = VQMUL},
|
||||
{0, 0}
|
||||
};
|
||||
|
||||
|
@ -281,7 +287,7 @@ static expr_type_t quat_quat[] = {
|
|||
.commutative = fp_com_add, .associative = fp_ass_add},
|
||||
{'-', &type_quaternion,
|
||||
.anticommute = fp_com_add},
|
||||
{'*', &type_quaternion, .associative = always},
|
||||
{'*', &type_quaternion, .associative = always, .true_op = QMUL},
|
||||
{EQ, &type_int},
|
||||
{NE, &type_int},
|
||||
{0, 0}
|
||||
|
@ -727,6 +733,7 @@ static expr_type_t *float_x[ev_type_count] = {
|
|||
static expr_type_t *vector_x[ev_type_count] = {
|
||||
[ev_float] = vector_float,
|
||||
[ev_vector] = vector_vector,
|
||||
[ev_quaternion] = vector_quat,
|
||||
[ev_int] = vector_int,
|
||||
[ev_uint] = vector_uint,
|
||||
[ev_short] = vector_short,
|
||||
|
@ -1463,6 +1470,10 @@ binary_expr (int op, const expr_t *e1, const expr_t *e2)
|
|||
if ((e = reimplement_binary_expr (op, e1, e2)))
|
||||
return edag_add_expr (fold_constants (e));
|
||||
|
||||
if (expr_type->true_op) {
|
||||
op = expr_type->true_op;
|
||||
}
|
||||
|
||||
auto ne = new_binary_expr (op, e1, e2);
|
||||
ne->expr.type = expr_type->result_type;
|
||||
if (expr_type->commutative) {
|
||||
|
|
|
@ -143,7 +143,7 @@ int yylex (void);
|
|||
|
||||
%left SHL SHR
|
||||
%left '+' '-'
|
||||
%left '*' '/' '%' MOD SCALE GEOMETRIC
|
||||
%left '*' '/' '%' MOD SCALE GEOMETRIC QMUL QVMUL VQMUL
|
||||
%left HADAMARD CROSS DOT WEDGE REGRESSIVE
|
||||
%right <op> SIZEOF UNARY INCOP REVERSE STAR DUAL
|
||||
%left HYPERUNARY
|
||||
|
|
|
@ -602,6 +602,9 @@ convert_op (int op)
|
|||
case DOT: return "dot";
|
||||
case HADAMARD: return "mul";
|
||||
case SCALE: return "scale";
|
||||
case QMUL: return "qmul";
|
||||
case QVMUL: return "qvmul";
|
||||
case VQMUL: return "vqmul";
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue