Initial revision
[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 // to save time on transforms, choose the appropriate function
72 void softwaretransform_classify()
73 {
74         if (softwaretransform_offset[0] != 0 || softwaretransform_offset[1] != 0 || softwaretransform_offset[2] != 0)
75         {
76                 if (softwaretransform_scale != 1)
77                 {
78                         if (softwaretransform_x[0] != 1 || softwaretransform_x[1] != 0 || softwaretransform_x[2] != 0 ||
79                                 softwaretransform_y[0] != 0 || softwaretransform_y[1] != 1 || softwaretransform_y[2] != 0 ||
80                                 softwaretransform_z[0] != 0 || softwaretransform_z[1] != 0 || softwaretransform_z[2] != 1)
81                                 softwaretransform = &softwaretransform_dorotatescaletranslate;
82                         else
83                                 softwaretransform = &softwaretransform_doscaletranslate;
84                 }
85                 else
86                 {
87                         if (softwaretransform_x[0] != 1 || softwaretransform_x[1] != 0 || softwaretransform_x[2] != 0 ||
88                                 softwaretransform_y[0] != 0 || softwaretransform_y[1] != 1 || softwaretransform_y[2] != 0 ||
89                                 softwaretransform_z[0] != 0 || softwaretransform_z[1] != 0 || softwaretransform_z[2] != 1)
90                                 softwaretransform = &softwaretransform_dorotatetranslate;
91                         else
92                                 softwaretransform = &softwaretransform_dotranslate;
93                 }
94         }
95         else
96         {
97                 if (softwaretransform_scale != 1)
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_dorotatescale;
103                         else
104                                 softwaretransform = &softwaretransform_doscale;
105                 }
106                 else
107                 {
108                         if (softwaretransform_x[0] != 1 || softwaretransform_x[1] != 0 || softwaretransform_x[2] != 0 ||
109                                 softwaretransform_y[0] != 0 || softwaretransform_y[1] != 1 || softwaretransform_y[2] != 0 ||
110                                 softwaretransform_z[0] != 0 || softwaretransform_z[1] != 0 || softwaretransform_z[2] != 1)
111                                 softwaretransform = &softwaretransform_dorotate;
112                         else
113                                 softwaretransform = &softwaretransform_docopy;
114                 }
115         }
116 }
117
118 void softwaretransformidentity ()
119 {
120         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;
121         softwaretransform_x[0] = softwaretransform_y[1] = softwaretransform_z[2] = 1;
122         softwaretransform_scale = 1;
123         // we know what it is
124         softwaretransform = &softwaretransform_docopy;
125 }
126
127 void softwaretransformset (vec3_t origin, vec3_t angles, vec_t scale)
128 {
129         VectorCopy(origin, softwaretransform_offset);
130         AngleVectors(angles, softwaretransform_x, softwaretransform_y, softwaretransform_z);
131         softwaretransform_y[0] = -softwaretransform_y[0];
132         softwaretransform_y[1] = -softwaretransform_y[1];
133         softwaretransform_y[2] = -softwaretransform_y[2];
134         softwaretransform_scale = scale;
135         // choose best transform code
136         softwaretransform_classify();
137 }
138
139 void softwaretransformforentity (entity_t *e)
140 {
141         vec3_t angles;
142         angles[0] = -e->angles[0];
143         angles[1] = e->angles[1];
144         angles[2] = e->angles[2];
145         softwaretransformset(e->origin, angles, e->scale);
146 }