]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/warpzonelib/anglestransform.qc
warpzonelib - the beginning
[divverent/nexuiz.git] / data / qcsrc / warpzonelib / anglestransform.qc
1 // helper function
2 void fixedmakevectors(vector a)
3 {
4         // a makevectors that actually inverts vectoangles
5         a_x = -a_x;
6         makevectors(a);
7 }
8
9 // angles transforms
10 // angles in fixedmakevectors/fixedvectoangles space
11 vector AnglesTransform_Apply(vector transform, vector v)
12 {
13         fixedmakevectors(transform);
14         return v_forward * v_x
15              + v_right   * (-v_y)
16                  + v_up      * v_z;
17 }
18
19 vector AnglesTransform_Multiply(vector t1, vector t2)
20 {
21         vector m_forward, m_up;
22         fixedmakevectors(t2); m_forward = v_forward; m_up = v_up;
23         m_forward = AnglesTransform_Apply(t1, m_forward); m_up = AnglesTransform_Apply(t1, m_up);
24         return fixedvectoangles2(m_forward, m_up);
25 }
26
27 vector AnglesTransform_Invert(vector transform)
28 {
29         vector i_forward, i_up;
30         fixedmakevectors(transform);
31         // we want angles that turn v_forward into '1 0 0', v_right into '0 1 0' and v_up into '0 0 1'
32         // but these are orthogonal unit vectors!
33         // so to invert, we can simply fixedvectoangles the TRANSPOSED matrix
34         // TODO is this always -transform?
35         i_forward_x = v_forward_x;
36         i_forward_y = -v_right_x;
37         i_forward_z = v_up_x;
38         i_up_x = v_forward_z;
39         i_up_y = -v_right_z;
40         i_up_z = v_up_z;
41         return fixedvectoangles2(i_forward, i_up);
42 }
43
44 vector AnglesTransform_TurnDirectionFR(vector transform)
45 {
46         // turn 180 degrees around v_up
47         // changes in-direction to out-direction
48         //fixedmakevectors(transform);
49         //return fixedvectoangles2(-1 * v_forward, 1 * v_up);
50         transform_x = 180 - transform_x;
51         transform_y = 180 + transform_y;
52         transform_z = -transform_z;
53         return transform;
54 }
55
56 vector AnglesTransform_TurnDirectionFU(vector transform)
57 {
58         // turn 180 degrees around v_up
59         // changes in-direction to out-direction
60         //fixedmakevectors(transform);
61         //return fixedvectoangles2(-1 * v_forward, 1 * v_up);
62         transform_x = 180 - transform_x;
63         transform_y = 180 + transform_y;
64         transform_z = 180 - transform_z;
65         return transform;
66 }
67
68 vector AnglesTransform_Divide(vector to_transform, vector from_transform)
69 {
70         return AnglesTransform_Multiply(to_transform, AnglesTransform_Invert(from_transform));
71 }
72
73 vector AnglesTransform_Normalize(vector t, float minimize_roll)
74 {
75         float need_flip;
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);
80         if(minimize_roll)
81                 need_flip = (t_z > 90 || t_z <= -90);
82         else
83                 need_flip = (t_x > 90 || t_x < -90); // for pitch we prefer to allow exactly -90 degrees for looking straight down
84         if(need_flip)
85         {
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;
89         }
90         return t;
91 }
92
93 vector AnglesTransform_ApplyToVAngles(vector transform, vector v)
94 {
95         v_x = -v_x;
96         v = AnglesTransform_ApplyToAngles(transform, v);
97         v_x = -v_x;
98         return v;
99 }