]> icculus.org git repositories - divverent/nexuiz.git/blob - data/qcsrc/warpzonelib/anglestransform.qc
more warpzone fixes - now angled warpzones work too
[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 = -transform_x;
51         transform_y = 180 + transform_y;
52         transform_z = -transform_z;
53         // pitch: -s +c
54         // yaw:   -s -c
55         // roll:  -s +c
56         return transform;
57 }
58
59 vector AnglesTransform_TurnDirectionFU(vector transform)
60 {
61         // turn 180 degrees around v_up
62         // changes in-direction to out-direction
63         //fixedmakevectors(transform);
64         //return fixedvectoangles2(-1 * v_forward, 1 * v_up);
65         transform_x = -transform_x;
66         transform_y = 180 + transform_y;
67         transform_z = 180 - transform_z;
68         return transform;
69 }
70
71 vector AnglesTransform_Divide(vector to_transform, vector from_transform)
72 {
73         return AnglesTransform_Multiply(to_transform, AnglesTransform_Invert(from_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_ApplyToAngles(vector transform, vector v)
97 {
98         //v_x = -v_x;
99         v = AnglesTransform_Multiply(transform, v);
100         //v_x = -v_x;
101         return v;
102 }
103
104 vector AnglesTransform_ApplyToVAngles(vector transform, vector v)
105 {
106         v_x = -v_x;
107         v = AnglesTransform_Multiply(transform, v);
108         v_x = -v_x;
109         return v;
110 }