1 #include "anglestransform.qh"
4 // angles in fixedmakevectors/fixedvectoangles space
5 vector AnglesTransform_Apply(vector transform, vector v)
7 FIXED_MAKE_VECTORS_NEW(transform, forward, right, up);
8 return forward * v.x + right * (-v.y) + up * v.z;
11 vector AnglesTransform_Multiply(vector t1, vector t2)
13 FIXED_MAKE_VECTORS_NEW(t2, forward, right, up);
14 forward = AnglesTransform_Apply(t1, forward);
15 up = AnglesTransform_Apply(t1, up);
16 return fixedvectoangles2(forward, up);
19 vector AnglesTransform_Invert(vector transform)
21 vector i_forward, i_up;
22 FIXED_MAKE_VECTORS_NEW(transform, forward, right, up);
23 // we want angles that turn forward into '1 0 0', right into '0 1 0' and up into '0 0 1'
24 // but these are orthogonal unit vectors!
25 // so to invert, we can simply fixedvectoangles the TRANSPOSED matrix
26 // TODO is this always -transform?
27 i_forward.x = forward.x;
28 i_forward.y = -right.x;
33 return fixedvectoangles2(i_forward, i_up);
36 vector AnglesTransform_TurnDirectionFR(vector transform)
38 // turn 180 degrees around v_up
39 // changes in-direction to out-direction
40 //fixedmakevectors(transform);
41 //return fixedvectoangles2(-1 * v_forward, 1 * v_up);
42 transform.x = -transform.x;
43 transform.y = 180 + transform.y;
44 transform.z = -transform.z;
51 vector AnglesTransform_TurnDirectionFU(vector transform)
53 // turn 180 degrees around v_up
54 // changes in-direction to out-direction
55 //fixedmakevectors(transform);
56 //return fixedvectoangles2(-1 * v_forward, 1 * v_up);
57 transform.x = -transform.x;
58 transform.y = 180 + transform.y;
59 transform.z = 180 - transform.z;
63 vector AnglesTransform_RightDivide(vector to_transform, vector from_transform)
65 return AnglesTransform_Multiply(to_transform, AnglesTransform_Invert(from_transform));
68 vector AnglesTransform_LeftDivide(vector from_transform, vector to_transform)
70 return AnglesTransform_Multiply(AnglesTransform_Invert(from_transform), to_transform);
73 vector AnglesTransform_Normalize(vector t, float minimize_roll)
76 // first, bring all angles in their range...
77 t.x = t.x - 360 * rint(t.x / 360);
78 t.y = t.y - 360 * rint(t.y / 360);
79 t.z = t.z - 360 * rint(t.z / 360);
81 need_flip = (t.z > 90 || t.z <= -90);
83 need_flip = (t.x > 90 || t.x < -90); // for pitch we prefer to allow exactly -90 degrees for looking straight down
86 if(t.x >= 0) t.x = 180 - t.x; else t.x = -180 - t.x;
87 if(t.y > 0) t.y -= 180; else t.y += 180;
88 if(t.z > 0) t.z -= 180; else t.z += 180;
93 vector AnglesTransform_CancelRoll(vector t)
95 const float epsilon = 30;
99 // forward vector (NOT SO important)
100 // right vector, up vector: screen rotation (MORE important)
101 // choose best match among all pitch-yaw only rotations
103 // FIXME find a better method
105 f = fabs(t.x - (-90)) / epsilon;
114 f = fabs(t.x - 90) / epsilon;
125 #if POSITIVE_PITCH_IS_DOWN
126 vector AnglesTransform_ApplyToAngles(vector transform, vector v)
129 v = AnglesTransform_Multiply(transform, v);
133 vector AnglesTransform_ApplyToVAngles(vector transform, vector v)
135 v = AnglesTransform_Multiply(transform, v);
138 vector AnglesTransform_FromAngles(vector v)
143 vector AnglesTransform_ToAngles(vector v)
148 vector AnglesTransform_FromVAngles(vector v)
152 vector AnglesTransform_ToVAngles(vector v)
157 vector AnglesTransform_ApplyToAngles(vector transform, vector v)
159 v = AnglesTransform_Multiply(transform, v);
162 vector AnglesTransform_ApplyToVAngles(vector transform, vector v)
165 v = AnglesTransform_Multiply(transform, v);
169 vector AnglesTransform_FromAngles(vector v)
173 vector AnglesTransform_ToAngles(vector v)
177 vector AnglesTransform_FromVAngles(vector v)
182 vector AnglesTransform_ToVAngles(vector v)
189 vector AnglesTransform_Multiply_GetPostShift(vector t0, vector st0, vector t1, vector st1)
191 // we want the result of:
192 // t0 * (t1 * p + st1) + st0
193 // t0 * t1 * p + t0 * st1 + st0
194 return st0 + AnglesTransform_Apply(t0, st1);
196 vector AnglesTransform_PrePostShift_GetPostShift(vector sf, vector t, vector st)
198 return st - AnglesTransform_Apply(t, sf);