teamradar: fix clip fail
[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_Divide(vector to_transform, vector from_transform)
88 {
89         return AnglesTransform_Multiply(to_transform, AnglesTransform_Invert(from_transform));
90 }
91
92 vector AnglesTransform_Normalize(vector t, float minimize_roll)
93 {
94         float need_flip;
95         // first, bring all angles in their range...
96         t_x = t_x - 360 * rint(t_x / 360);
97         t_y = t_y - 360 * rint(t_y / 360);
98         t_z = t_z - 360 * rint(t_z / 360);
99         if(minimize_roll)
100                 need_flip = (t_z > 90 || t_z <= -90);
101         else
102                 need_flip = (t_x > 90 || t_x < -90); // for pitch we prefer to allow exactly -90 degrees for looking straight down
103         if(need_flip)
104         {
105                 if(t_x >= 0) t_x = 180 - t_x; else t_x = -180 - t_x;
106                 if(t_y > 0) t_y -= 180; else t_y += 180;
107                 if(t_z > 0) t_z -= 180; else t_z += 180;
108         }
109         return t;
110 }
111
112 vector AnglesTransform_CancelRoll(vector t)
113 {
114         const float epsilon = 30;
115         float f;
116
117         // constraints:
118         // forward vector (NOT SO important)
119         // right vector, up vector: screen rotation (MORE important)
120         // choose best match among all pitch-yaw only rotations
121
122         // FIXME find a better method
123
124         f = fabs(t_x - (-90)) / epsilon;
125         if(f < 1)
126         {
127                 //t_x = -90;
128                 t_y += t_z;
129                 t_z = 0;
130         }
131         else
132         {
133                 f = fabs(t_x - 90) / epsilon;
134                 if(f < 1)
135                 {
136                         //t_x = 90;
137                         t_y -= t_z;
138                         t_z = 0;
139                 }
140         }
141         return t;
142 }
143
144 #ifdef POSITIVE_PITCH_IS_DOWN
145 vector AnglesTransform_ApplyToAngles(vector transform, vector v)
146 {
147         v_x = -v_x;
148         v = AnglesTransform_Multiply(transform, v);
149         v_x = -v_x;
150         return v;
151 }
152 vector AnglesTransform_ApplyToVAngles(vector transform, vector v)
153 {
154         v = AnglesTransform_Multiply(transform, v);
155         return v;
156 }
157 vector AnglesTransform_FromAngles(vector v)
158 {
159         v_x = -v_x;
160         return v;
161 }
162 vector AnglesTransform_ToAngles(vector v)
163 {
164         v_x = -v_x;
165         return v;
166 }
167 vector AnglesTransform_FromVAngles(vector v)
168 {
169         return v;
170 }
171 vector AnglesTransform_ToVAngles(vector v)
172 {
173         return v;
174 }
175 #else
176 vector AnglesTransform_ApplyToAngles(vector transform, vector v)
177 {
178         v = AnglesTransform_Multiply(transform, v);
179         return v;
180 }
181 vector AnglesTransform_ApplyToVAngles(vector transform, vector v)
182 {
183         v_x = -v_x;
184         v = AnglesTransform_Multiply(transform, v);
185         v_x = -v_x;
186         return v;
187 }
188 vector AnglesTransform_FromAngles(vector v)
189 {
190         return v;
191 }
192 vector AnglesTransform_ToAngles(vector v)
193 {
194         return v;
195 }
196 vector AnglesTransform_FromVAngles(vector v)
197 {
198         v_x = -v_x;
199         return v;
200 }
201 vector AnglesTransform_ToVAngles(vector v)
202 {
203         v_x = -v_x;
204         return v;
205 }
206 #endif
207
208 vector AnglesTransform_Multiply_GetPostShift(vector t0, vector st0, vector t1, vector st1)
209 {
210         // we want the result of:
211         //   t0 * (t1 * p + st1) + st0
212         //   t0 * t1 * p + t0 * st1 + st0
213         return st0 + AnglesTransform_Apply(t0, st1);
214 }
215 vector AnglesTransform_PrePostShift_GetPostShift(vector sf, vector t, vector st)
216 {
217         return st - AnglesTransform_Apply(t, sf);
218 }