]> de.git.xonotic.org Git - xonotic/xonotic-data.pk3dir.git/blob - qcsrc/lib/warpzone/anglestransform.qc
Merge branch 'master' into Mario/weaponorder
[xonotic/xonotic-data.pk3dir.git] / qcsrc / lib / warpzone / anglestransform.qc
1 #include "anglestransform.qh"
2
3 // angles transforms
4 // angles in fixedmakevectors/fixedvectoangles space
5 vector AnglesTransform_Apply(vector transform, vector v)
6 {
7         vector forward, right, up;
8         FIXED_MAKE_VECTORS(transform, forward, right, up);
9         return forward * v.x + right * (-v.y) + up * v.z;
10 }
11
12 vector AnglesTransform_Multiply(vector t1, vector t2)
13 {
14         vector forward, right, up;
15         FIXED_MAKE_VECTORS(t2, forward, right, up);
16         forward = AnglesTransform_Apply(t1, forward);
17         up = AnglesTransform_Apply(t1, up);
18         return fixedvectoangles2(forward, up);
19 }
20
21 vector AnglesTransform_Invert(vector transform)
22 {
23         vector i_forward, i_up;
24         vector forward, right, up;
25         FIXED_MAKE_VECTORS(transform, forward, right, up);
26         // we want angles that turn forward into '1 0 0', right into '0 1 0' and up into '0 0 1'
27         // but these are orthogonal unit vectors!
28         // so to invert, we can simply fixedvectoangles the TRANSPOSED matrix
29         // TODO is this always -transform?
30         i_forward.x = forward.x;
31         i_forward.y = -right.x;
32         i_forward.z = up.x;
33         i_up.x = forward.z;
34         i_up.y = -right.z;
35         i_up.z = up.z;
36         return fixedvectoangles2(i_forward, i_up);
37 }
38
39 vector AnglesTransform_TurnDirectionFR(vector transform)
40 {
41         // turn 180 degrees around v_up
42         // changes in-direction to out-direction
43         //fixedmakevectors(transform);
44         //return fixedvectoangles2(-1 * v_forward, 1 * v_up);
45         transform.x = -transform.x;
46         transform.y = 180 + transform.y;
47         transform.z = -transform.z;
48         // pitch: -s +c
49         // yaw:   -s -c
50         // roll:  -s +c
51         return transform;
52 }
53
54 vector AnglesTransform_TurnDirectionFU(vector transform)
55 {
56         // turn 180 degrees around v_up
57         // changes in-direction to out-direction
58         //fixedmakevectors(transform);
59         //return fixedvectoangles2(-1 * v_forward, 1 * v_up);
60         transform.x = -transform.x;
61         transform.y = 180 + transform.y;
62         transform.z = 180 - transform.z;
63         return transform;
64 }
65
66 vector AnglesTransform_RightDivide(vector to_transform, vector from_transform)
67 {
68         return AnglesTransform_Multiply(to_transform, AnglesTransform_Invert(from_transform));
69 }
70
71 vector AnglesTransform_LeftDivide(vector from_transform, vector to_transform)
72 {
73         return AnglesTransform_Multiply(AnglesTransform_Invert(from_transform), to_transform);
74 }
75
76 vector AnglesTransform_Normalize(vector t, float minimize_roll)
77 {
78         float need_flip;
79         // first, bring all angles in their range...
80         t.x = t.x - 360 * rint(t.x / 360);
81         t.y = t.y - 360 * rint(t.y / 360);
82         t.z = t.z - 360 * rint(t.z / 360);
83         if(minimize_roll)
84                 need_flip = (t.z > 90 || t.z <= -90);
85         else
86                 need_flip = (t.x > 90 || t.x < -90); // for pitch we prefer to allow exactly -90 degrees for looking straight down
87         if(need_flip)
88         {
89                 if(t.x >= 0) t.x = 180 - t.x; else t.x = -180 - t.x;
90                 if(t.y > 0) t.y -= 180; else t.y += 180;
91                 if(t.z > 0) t.z -= 180; else t.z += 180;
92         }
93         return t;
94 }
95
96 vector AnglesTransform_CancelRoll(vector t)
97 {
98         const float epsilon = 30;
99         float f;
100
101         // constraints:
102         // forward vector (NOT SO important)
103         // right vector, up vector: screen rotation (MORE important)
104         // choose best match among all pitch-yaw only rotations
105
106         // FIXME find a better method
107
108         f = fabs(t.x - (-90)) / epsilon;
109         if(f < 1)
110         {
111                 //t_x = -90;
112                 t.y += t.z;
113                 t.z = 0;
114         }
115         else
116         {
117                 f = fabs(t.x - 90) / epsilon;
118                 if(f < 1)
119                 {
120                         //t_x = 90;
121                         t.y -= t.z;
122                         t.z = 0;
123                 }
124         }
125         return t;
126 }
127
128 #if POSITIVE_PITCH_IS_DOWN
129 vector AnglesTransform_ApplyToAngles(vector transform, vector v)
130 {
131         v.x = -v.x;
132         v = AnglesTransform_Multiply(transform, v);
133         v.x = -v.x;
134         return v;
135 }
136 vector AnglesTransform_ApplyToVAngles(vector transform, vector v)
137 {
138         v = AnglesTransform_Multiply(transform, v);
139         return v;
140 }
141 vector AnglesTransform_FromAngles(vector v)
142 {
143         v.x = -v.x;
144         return v;
145 }
146 vector AnglesTransform_ToAngles(vector v)
147 {
148         v.x = -v.x;
149         return v;
150 }
151 vector AnglesTransform_FromVAngles(vector v)
152 {
153         return v;
154 }
155 vector AnglesTransform_ToVAngles(vector v)
156 {
157         return v;
158 }
159 #else
160 vector AnglesTransform_ApplyToAngles(vector transform, vector v)
161 {
162         v = AnglesTransform_Multiply(transform, v);
163         return v;
164 }
165 vector AnglesTransform_ApplyToVAngles(vector transform, vector v)
166 {
167         v.x = -v.x;
168         v = AnglesTransform_Multiply(transform, v);
169         v.x = -v.x;
170         return v;
171 }
172 vector AnglesTransform_FromAngles(vector v)
173 {
174         return v;
175 }
176 vector AnglesTransform_ToAngles(vector v)
177 {
178         return v;
179 }
180 vector AnglesTransform_FromVAngles(vector v)
181 {
182         v.x = -v.x;
183         return v;
184 }
185 vector AnglesTransform_ToVAngles(vector v)
186 {
187         v.x = -v.x;
188         return v;
189 }
190 #endif
191
192 vector AnglesTransform_Multiply_GetPostShift(vector t0, vector st0, vector t1, vector st1)
193 {
194         // we want the result of:
195         //   t0 * (t1 * p + st1) + st0
196         //   t0 * t1 * p + t0 * st1 + st0
197         return st0 + AnglesTransform_Apply(t0, st1);
198 }
199 vector AnglesTransform_PrePostShift_GetPostShift(vector sf, vector t, vector st)
200 {
201         return st - AnglesTransform_Apply(t, sf);
202 }