cleaned up nearly all of the externs in .c files (moved to appropriate .h files)
[divverent/darkplaces.git] / transform.c
1 // LordHavoc: transform code for purposes of transpoly, wallpoly, etc
2
3 #include "quakedef.h"
4
5 vec3_t softwaretransform_x;
6 vec3_t softwaretransform_y;
7 vec3_t softwaretransform_z;
8 vec_t softwaretransform_scale;
9 vec3_t softwaretransform_offset;
10
11 // set to different transform code depending on complexity of transform
12 void (*softwaretransform) (vec3_t in, vec3_t out);
13
14 // the real deal
15 void softwaretransform_dorotatescaletranslate (vec3_t in, vec3_t out)
16 {
17         out[0] = (in[0] * softwaretransform_x[0] + in[1] * softwaretransform_y[0] + in[2] * softwaretransform_z[0]) * softwaretransform_scale + softwaretransform_offset[0];
18         out[1] = (in[0] * softwaretransform_x[1] + in[1] * softwaretransform_y[1] + in[2] * softwaretransform_z[1]) * softwaretransform_scale + softwaretransform_offset[1];
19         out[2] = (in[0] * softwaretransform_x[2] + in[1] * softwaretransform_y[2] + in[2] * softwaretransform_z[2]) * softwaretransform_scale + softwaretransform_offset[2];
20 }
21
22 void softwaretransform_doscaletranslate (vec3_t in, vec3_t out)
23 {
24         out[0] = in[0] * softwaretransform_scale + softwaretransform_offset[0];
25         out[1] = in[1] * softwaretransform_scale + softwaretransform_offset[1];
26         out[2] = in[2] * softwaretransform_scale + softwaretransform_offset[2];
27 }
28
29 void softwaretransform_dorotatetranslate (vec3_t in, vec3_t out)
30 {
31         out[0] = (in[0] * softwaretransform_x[0] + in[1] * softwaretransform_y[0] + in[2] * softwaretransform_z[0]) + softwaretransform_offset[0];
32         out[1] = (in[0] * softwaretransform_x[1] + in[1] * softwaretransform_y[1] + in[2] * softwaretransform_z[1]) + softwaretransform_offset[1];
33         out[2] = (in[0] * softwaretransform_x[2] + in[1] * softwaretransform_y[2] + in[2] * softwaretransform_z[2]) + softwaretransform_offset[2];
34 }
35
36 void softwaretransform_dotranslate (vec3_t in, vec3_t out)
37 {
38         out[0] = in[0] + softwaretransform_offset[0];
39         out[1] = in[1] + softwaretransform_offset[1];
40         out[2] = in[2] + softwaretransform_offset[2];
41 }
42
43 void softwaretransform_dorotatescale (vec3_t in, vec3_t out)
44 {
45         out[0] = (in[0] * softwaretransform_x[0] + in[1] * softwaretransform_y[0] + in[2] * softwaretransform_z[0]) * softwaretransform_scale;
46         out[1] = (in[0] * softwaretransform_x[1] + in[1] * softwaretransform_y[1] + in[2] * softwaretransform_z[1]) * softwaretransform_scale;
47         out[2] = (in[0] * softwaretransform_x[2] + in[1] * softwaretransform_y[2] + in[2] * softwaretransform_z[2]) * softwaretransform_scale;
48 }
49
50 void softwaretransform_doscale (vec3_t in, vec3_t out)
51 {
52         out[0] = in[0] * softwaretransform_scale + softwaretransform_offset[0];
53         out[1] = in[1] * softwaretransform_scale + softwaretransform_offset[1];
54         out[2] = in[2] * softwaretransform_scale + softwaretransform_offset[2];
55 }
56
57 void softwaretransform_dorotate (vec3_t in, vec3_t out)
58 {
59         out[0] = (in[0] * softwaretransform_x[0] + in[1] * softwaretransform_y[0] + in[2] * softwaretransform_z[0]);
60         out[1] = (in[0] * softwaretransform_x[1] + in[1] * softwaretransform_y[1] + in[2] * softwaretransform_z[1]);
61         out[2] = (in[0] * softwaretransform_x[2] + in[1] * softwaretransform_y[2] + in[2] * softwaretransform_z[2]);
62 }
63
64 void softwaretransform_docopy (vec3_t in, vec3_t out)
65 {
66         out[0] = in[0];
67         out[1] = in[1];
68         out[2] = in[2];
69 }
70
71 void softwareuntransform (vec3_t in, vec3_t out)
72 {
73         vec3_t v;
74         float s = 1.0f / softwaretransform_scale;
75         v[0] = in[0] - softwaretransform_offset[0];
76         v[1] = in[1] - softwaretransform_offset[1];
77         v[2] = in[2] - softwaretransform_offset[2];
78         out[0] = (v[0] * softwaretransform_x[0] + v[1] * softwaretransform_x[1] + v[2] * softwaretransform_x[2]) * s;
79         out[1] = (v[0] * softwaretransform_y[0] + v[1] * softwaretransform_y[1] + v[2] * softwaretransform_y[2]) * s;
80         out[2] = (v[0] * softwaretransform_z[0] + v[1] * softwaretransform_z[1] + v[2] * softwaretransform_z[2]) * s;
81 }
82
83 // to save time on transforms, choose the appropriate function
84 void softwaretransform_classify(void)
85 {
86         if (softwaretransform_offset[0] != 0 || softwaretransform_offset[1] != 0 || softwaretransform_offset[2] != 0)
87         {
88                 if (softwaretransform_scale != 1)
89                 {
90                         if (softwaretransform_x[0] != 1 || softwaretransform_x[1] != 0 || softwaretransform_x[2] != 0 ||
91                                 softwaretransform_y[0] != 0 || softwaretransform_y[1] != 1 || softwaretransform_y[2] != 0 ||
92                                 softwaretransform_z[0] != 0 || softwaretransform_z[1] != 0 || softwaretransform_z[2] != 1)
93                                 softwaretransform = &softwaretransform_dorotatescaletranslate;
94                         else
95                                 softwaretransform = &softwaretransform_doscaletranslate;
96                 }
97                 else
98                 {
99                         if (softwaretransform_x[0] != 1 || softwaretransform_x[1] != 0 || softwaretransform_x[2] != 0 ||
100                                 softwaretransform_y[0] != 0 || softwaretransform_y[1] != 1 || softwaretransform_y[2] != 0 ||
101                                 softwaretransform_z[0] != 0 || softwaretransform_z[1] != 0 || softwaretransform_z[2] != 1)
102                                 softwaretransform = &softwaretransform_dorotatetranslate;
103                         else
104                                 softwaretransform = &softwaretransform_dotranslate;
105                 }
106         }
107         else
108         {
109                 if (softwaretransform_scale != 1)
110                 {
111                         if (softwaretransform_x[0] != 1 || softwaretransform_x[1] != 0 || softwaretransform_x[2] != 0 ||
112                                 softwaretransform_y[0] != 0 || softwaretransform_y[1] != 1 || softwaretransform_y[2] != 0 ||
113                                 softwaretransform_z[0] != 0 || softwaretransform_z[1] != 0 || softwaretransform_z[2] != 1)
114                                 softwaretransform = &softwaretransform_dorotatescale;
115                         else
116                                 softwaretransform = &softwaretransform_doscale;
117                 }
118                 else
119                 {
120                         if (softwaretransform_x[0] != 1 || softwaretransform_x[1] != 0 || softwaretransform_x[2] != 0 ||
121                                 softwaretransform_y[0] != 0 || softwaretransform_y[1] != 1 || softwaretransform_y[2] != 0 ||
122                                 softwaretransform_z[0] != 0 || softwaretransform_z[1] != 0 || softwaretransform_z[2] != 1)
123                                 softwaretransform = &softwaretransform_dorotate;
124                         else
125                                 softwaretransform = &softwaretransform_docopy;
126                 }
127         }
128 }
129
130 void softwaretransformidentity(void)
131 {
132         softwaretransform_offset[0] = softwaretransform_offset[1] = softwaretransform_offset[2] = softwaretransform_x[1] = softwaretransform_x[2] = softwaretransform_y[0] = softwaretransform_y[2] = softwaretransform_z[0] = softwaretransform_z[1] = 0;
133         softwaretransform_x[0] = softwaretransform_y[1] = softwaretransform_z[2] = 1;
134         softwaretransform_scale = 1;
135         // we know what it is
136         softwaretransform = &softwaretransform_docopy;
137 }
138
139 void softwaretransformset (vec3_t origin, vec3_t angles, vec_t scale)
140 {
141         VectorCopy(origin, softwaretransform_offset);
142         AngleVectors(angles, softwaretransform_x, softwaretransform_y, softwaretransform_z);
143         softwaretransform_y[0] = -softwaretransform_y[0];
144         softwaretransform_y[1] = -softwaretransform_y[1];
145         softwaretransform_y[2] = -softwaretransform_y[2];
146         softwaretransform_scale = scale;
147         // choose best transform code
148         softwaretransform_classify();
149 }
150
151 void softwaretransformforentity (entity_t *e)
152 {
153         vec3_t angles;
154         angles[0] = -e->render.angles[0];
155         angles[1] = e->render.angles[1];
156         angles[2] = e->render.angles[2];
157         softwaretransformset(e->render.origin, angles, e->render.scale);
158 }