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