rev |
line source |
nuclear@0
|
1 #include <math.h>
|
nuclear@0
|
2 #include <stdio.h>
|
nuclear@0
|
3
|
nuclear@0
|
4 #include "engine3d.h"
|
nuclear@0
|
5 #include "generate3d.h"
|
nuclear@0
|
6 #include "render3d.h"
|
nuclear@0
|
7 #include "main.h"
|
nuclear@0
|
8
|
nuclear@0
|
9 point3d fpts[MAXDATA];
|
nuclear@0
|
10 point3d norms[MAXDATA];
|
nuclear@0
|
11 point3d pt_norms[MAXDATA];
|
nuclear@0
|
12 point2d spts[MAXDATA];
|
nuclear@0
|
13 point3d spls[MAXDATA];
|
nuclear@0
|
14
|
nuclear@0
|
15 unsigned short swp[MAXDATA];
|
nuclear@0
|
16
|
nuclear@0
|
17 int lightcalc = LIGHTVIEW;
|
nuclear@0
|
18
|
nuclear@0
|
19 #define fp_mul 256
|
nuclear@0
|
20 #define fp_shr 8
|
nuclear@0
|
21 #define proj_shr 8
|
nuclear@0
|
22
|
nuclear@0
|
23
|
nuclear@0
|
24 vector3d CrossProduct(vector3d v1, vector3d v2)
|
nuclear@0
|
25 {
|
nuclear@0
|
26 vector3d v;
|
nuclear@0
|
27 v.x=v1.y*v2.z-v1.z*v2.y;
|
nuclear@0
|
28 v.y=v1.z*v2.x-v1.x*v2.z;
|
nuclear@0
|
29 v.z=v1.x*v2.y-v1.y*v2.x;
|
nuclear@0
|
30 return v;
|
nuclear@0
|
31 }
|
nuclear@0
|
32
|
nuclear@0
|
33
|
nuclear@0
|
34 int DotProduct(vector3d v1, vector3d v2)
|
nuclear@0
|
35 {
|
nuclear@0
|
36 return v1.x*v2.x + v1.y*v2.y + v1.z*v2.z;
|
nuclear@0
|
37 }
|
nuclear@0
|
38
|
nuclear@0
|
39
|
nuclear@0
|
40 vector3d Normalize(vector3d v)
|
nuclear@0
|
41 {
|
nuclear@0
|
42 int d=(int)(sqrt(v.x*v.x+v.y*v.y+v.z*v.z));
|
nuclear@0
|
43 if (d!=0)
|
nuclear@0
|
44 {
|
nuclear@0
|
45 v.x=(v.x<<fp_shr)/d;
|
nuclear@0
|
46 v.y=(v.y<<fp_shr)/d;
|
nuclear@0
|
47 v.z=(v.z<<fp_shr)/d;
|
nuclear@0
|
48 }
|
nuclear@0
|
49 else
|
nuclear@0
|
50 {
|
nuclear@0
|
51 v.x = 0;
|
nuclear@0
|
52 v.y = 0;
|
nuclear@0
|
53 v.z = 0;
|
nuclear@0
|
54 }
|
nuclear@0
|
55 return v;
|
nuclear@0
|
56 }
|
nuclear@0
|
57
|
nuclear@0
|
58
|
nuclear@0
|
59 vector3d NegVec(vector3d v)
|
nuclear@0
|
60 {
|
nuclear@0
|
61 v.x=-v.x;
|
nuclear@0
|
62 v.y=-v.y;
|
nuclear@0
|
63 v.z=-v.z;
|
nuclear@0
|
64 return v;
|
nuclear@0
|
65 }
|
nuclear@0
|
66
|
nuclear@0
|
67
|
nuclear@0
|
68 void translate3d (object3d *obj)
|
nuclear@0
|
69 {
|
nuclear@0
|
70 int i;
|
nuclear@0
|
71 int objposx = (int)(obj->pos.x * fp_mul);
|
nuclear@0
|
72 int objposy = (int)(obj->pos.y * fp_mul);
|
nuclear@0
|
73 int objposz = (int)(obj->pos.z * fp_mul);
|
nuclear@0
|
74
|
nuclear@0
|
75 for (i=0; i<obj->npts; i++)
|
nuclear@0
|
76 {
|
nuclear@0
|
77 fpts[i].x += objposx;
|
nuclear@0
|
78 fpts[i].y += objposy;
|
nuclear@0
|
79 fpts[i].z += objposz;
|
nuclear@0
|
80 }
|
nuclear@0
|
81 }
|
nuclear@0
|
82
|
nuclear@0
|
83 void rotate3d (object3d *obj)
|
nuclear@0
|
84 {
|
nuclear@0
|
85 float cosxr = cos(obj->rot.x); float cosyr = cos(obj->rot.y); float coszr = cos(obj->rot.z);
|
nuclear@0
|
86 float sinxr = sin(obj->rot.x); float sinyr = sin(obj->rot.y); float sinzr = sin(obj->rot.z);
|
nuclear@0
|
87
|
nuclear@0
|
88 int xvx = (int)((cosyr * coszr) * fp_mul); int xvy = (int)((sinxr * sinyr * coszr - cosxr * sinzr) * fp_mul); int xvz = (int)((cosxr * sinyr * coszr + sinxr * sinzr) * fp_mul);
|
nuclear@0
|
89 int yvx = (int)((cosyr * sinzr) * fp_mul); int yvy = (int)((cosxr * coszr + sinxr * sinyr * sinzr) * fp_mul); int yvz = (int)((-sinxr * coszr + cosxr * sinyr * sinzr) * fp_mul);
|
nuclear@0
|
90 int zvx = (int)((-sinyr) * fp_mul); int zvy = (int)((sinxr * cosyr) * fp_mul); int zvz = (int)((cosxr * cosyr) * fp_mul);
|
nuclear@0
|
91
|
nuclear@0
|
92 int x, y, z;
|
nuclear@0
|
93 int i;
|
nuclear@0
|
94 for (i=0; i<obj->npts; i++)
|
nuclear@0
|
95 {
|
nuclear@0
|
96 x = obj->point[i].x;
|
nuclear@0
|
97 y = obj->point[i].y;
|
nuclear@0
|
98 z = obj->point[i].z;
|
nuclear@0
|
99 fpts[i].x = x * xvx + y * xvy + z * xvz;
|
nuclear@0
|
100 fpts[i].y = x * yvx + y * yvy + z * yvz;
|
nuclear@0
|
101 fpts[i].z = x * zvx + y * zvy + z * zvz;
|
nuclear@0
|
102 }
|
nuclear@0
|
103 }
|
nuclear@0
|
104
|
nuclear@0
|
105
|
nuclear@0
|
106 void rotate3d_normals (object3d *obj)
|
nuclear@0
|
107 {
|
nuclear@0
|
108 float cosxr = cos(obj->rot.x); float cosyr = cos(obj->rot.y); float coszr = cos(obj->rot.z);
|
nuclear@0
|
109 float sinxr = sin(obj->rot.x); float sinyr = sin(obj->rot.y); float sinzr = sin(obj->rot.z);
|
nuclear@0
|
110
|
nuclear@0
|
111 int xvx = (int)((cosyr * coszr) * fp_mul); int xvy = (int)((sinxr * sinyr * coszr - cosxr * sinzr) * fp_mul); int xvz = (int)((cosxr * sinyr * coszr + sinxr * sinzr) * fp_mul);
|
nuclear@0
|
112 int yvx = (int)((cosyr * sinzr) * fp_mul); int yvy = (int)((cosxr * coszr + sinxr * sinyr * sinzr) * fp_mul); int yvz = (int)((-sinxr * coszr + cosxr * sinyr * sinzr) * fp_mul);
|
nuclear@0
|
113 int zvx = (int)((-sinyr) * fp_mul); int zvy = (int)((sinxr * cosyr) * fp_mul); int zvz = (int)((cosxr * cosyr) * fp_mul);
|
nuclear@0
|
114
|
nuclear@0
|
115 int x, y, z;
|
nuclear@0
|
116 int i;
|
nuclear@0
|
117 for (i=0; i<obj->npls; i++)
|
nuclear@0
|
118 {
|
nuclear@0
|
119 x = obj->normal[i].x;
|
nuclear@0
|
120 y = obj->normal[i].y;
|
nuclear@0
|
121 z = obj->normal[i].z;
|
nuclear@0
|
122 norms[i].x = x * xvx + y * xvy + z * xvz;
|
nuclear@0
|
123 norms[i].y = x * yvx + y * yvy + z * yvz;
|
nuclear@0
|
124 norms[i].z = x * zvx + y * zvy + z * zvz;
|
nuclear@0
|
125 }
|
nuclear@0
|
126 }
|
nuclear@0
|
127
|
nuclear@0
|
128
|
nuclear@0
|
129 void rotate3d_pt_normals (object3d *obj)
|
nuclear@0
|
130 {
|
nuclear@0
|
131 float cosxr = cos(obj->rot.x); float cosyr = cos(obj->rot.y); float coszr = cos(obj->rot.z);
|
nuclear@0
|
132 float sinxr = sin(obj->rot.x); float sinyr = sin(obj->rot.y); float sinzr = sin(obj->rot.z);
|
nuclear@0
|
133
|
nuclear@0
|
134 int xvx = (int)((cosyr * coszr) * fp_mul); int xvy = (int)((sinxr * sinyr * coszr - cosxr * sinzr) * fp_mul); int xvz = (int)((cosxr * sinyr * coszr + sinxr * sinzr) * fp_mul);
|
nuclear@0
|
135 int yvx = (int)((cosyr * sinzr) * fp_mul); int yvy = (int)((cosxr * coszr + sinxr * sinyr * sinzr) * fp_mul); int yvz = (int)((-sinxr * coszr + cosxr * sinyr * sinzr) * fp_mul);
|
nuclear@0
|
136 int zvx = (int)((-sinyr) * fp_mul); int zvy = (int)((sinxr * cosyr) * fp_mul); int zvz = (int)((cosxr * cosyr) * fp_mul);
|
nuclear@0
|
137
|
nuclear@0
|
138 int x, y, z;
|
nuclear@0
|
139 int i;
|
nuclear@0
|
140 for (i=0; i<obj->npts; i++)
|
nuclear@0
|
141 {
|
nuclear@0
|
142 x = obj->pt_normal[i].x;
|
nuclear@0
|
143 y = obj->pt_normal[i].y;
|
nuclear@0
|
144 z = obj->pt_normal[i].z;
|
nuclear@0
|
145 pt_norms[i].x = x * xvx + y * xvy + z * xvz;
|
nuclear@0
|
146 pt_norms[i].y = x * yvx + y * yvy + z * yvz;
|
nuclear@0
|
147 pt_norms[i].z = x * zvx + y * zvy + z * zvz;
|
nuclear@0
|
148 }
|
nuclear@0
|
149 }
|
nuclear@0
|
150
|
nuclear@0
|
151 void project3d (object3d *obj)
|
nuclear@0
|
152 {
|
nuclear@0
|
153 int i;
|
nuclear@0
|
154 int smul = 1;
|
nuclear@0
|
155
|
nuclear@0
|
156 for (i=0; i<obj->npts; i++)
|
nuclear@0
|
157 if (fpts[i].z > 0)
|
nuclear@0
|
158 {
|
nuclear@0
|
159 spts[i].x = ((fpts[i].x << proj_shr) / (fpts[i].z/smul)) + (ScreenWidth>>1);
|
nuclear@0
|
160 spts[i].y = ((fpts[i].y << proj_shr) / (fpts[i].z/smul)) + (ScreenHeight>>1);
|
nuclear@0
|
161 }
|
nuclear@0
|
162 }
|
nuclear@0
|
163
|
nuclear@0
|
164 void CalcPolyColorStatic(object3d *obj)
|
nuclear@0
|
165 {
|
nuclear@0
|
166 int i, c;
|
nuclear@0
|
167 for (i=0; i<obj->npls; i++)
|
nuclear@0
|
168 {
|
nuclear@0
|
169 c = norms[i].z>>8;
|
nuclear@0
|
170 if (c<0) c=0;
|
nuclear@0
|
171 if (c>255) c=255;
|
nuclear@0
|
172 spls[i].c = c;
|
nuclear@0
|
173 }
|
nuclear@0
|
174 }
|
nuclear@0
|
175
|
nuclear@0
|
176 void CalcPointColorStatic(object3d *obj)
|
nuclear@0
|
177 {
|
nuclear@0
|
178 int i, c;
|
nuclear@0
|
179 for (i=0; i<obj->npts; i++)
|
nuclear@0
|
180 {
|
nuclear@0
|
181 c = pt_norms[i].z>>8;
|
nuclear@0
|
182 if (c<0) c=0;
|
nuclear@0
|
183 if (c>255) c=255;
|
nuclear@0
|
184 spts[i].c = c;
|
nuclear@0
|
185 }
|
nuclear@0
|
186 }
|
nuclear@0
|
187
|
nuclear@0
|
188 void CalcPolyColorDynamic(object3d *obj)
|
nuclear@0
|
189 {
|
nuclear@0
|
190 vector3d light, v;
|
nuclear@0
|
191 light.x = 0;
|
nuclear@0
|
192 light.y = 0;
|
nuclear@0
|
193 light.z = 256;
|
nuclear@0
|
194 float c;
|
nuclear@0
|
195
|
nuclear@0
|
196 int i;
|
nuclear@0
|
197 for (i=0; i<obj->npls; i++)
|
nuclear@0
|
198 {
|
nuclear@0
|
199 v.x = norms[i].x;
|
nuclear@0
|
200 v.y = norms[i].y;
|
nuclear@0
|
201 v.z = norms[i].z;
|
nuclear@0
|
202 c = DotProduct(v,light);
|
nuclear@0
|
203 spls[i].c = (int)c;
|
nuclear@0
|
204 if (c<0) spls[i].c = 0;
|
nuclear@0
|
205 if (spls[i].c>255) spls[i].c = 255;
|
nuclear@0
|
206 }
|
nuclear@0
|
207 }
|
nuclear@0
|
208
|
nuclear@0
|
209 void CalcPointColorDynamic(object3d *obj)
|
nuclear@0
|
210 {
|
nuclear@0
|
211 vector3d light, v;
|
nuclear@0
|
212 light.x = 0;
|
nuclear@0
|
213 light.y = 0;
|
nuclear@0
|
214 light.z = 256;
|
nuclear@0
|
215 float c;
|
nuclear@0
|
216
|
nuclear@0
|
217 int i;
|
nuclear@0
|
218 for (i=0; i<obj->npts; i++)
|
nuclear@0
|
219 {
|
nuclear@0
|
220 v.x = pt_norms[i].x;
|
nuclear@0
|
221 v.y = pt_norms[i].y;
|
nuclear@0
|
222 v.z = pt_norms[i].z;
|
nuclear@0
|
223 c = DotProduct(v,light);
|
nuclear@0
|
224 if (c<0) c = 0;
|
nuclear@0
|
225 if (c>255) c = 255;
|
nuclear@0
|
226 spts[i].c = (int)c;
|
nuclear@0
|
227 }
|
nuclear@0
|
228 }
|
nuclear@0
|
229
|
nuclear@0
|
230 void CalcPointColor(object3d *obj)
|
nuclear@0
|
231 {
|
nuclear@0
|
232 if (lightcalc==LIGHTVIEW) CalcPointColorStatic(obj);
|
nuclear@0
|
233 if (lightcalc==LIGHTMOVE) CalcPointColorDynamic(obj);
|
nuclear@0
|
234 }
|
nuclear@0
|
235
|
nuclear@0
|
236 void CalcPolyColor(object3d *obj)
|
nuclear@0
|
237 {
|
nuclear@0
|
238 if (lightcalc==LIGHTVIEW) CalcPolyColorStatic(obj);
|
nuclear@0
|
239 if (lightcalc==LIGHTMOVE) CalcPolyColorDynamic(obj);
|
nuclear@0
|
240 }
|
nuclear@0
|
241
|
nuclear@0
|
242 void Calc3d(object3d *obj)
|
nuclear@0
|
243 {
|
nuclear@0
|
244 rotate3d(obj);
|
nuclear@0
|
245 translate3d(obj);
|
nuclear@0
|
246 project3d(obj);
|
nuclear@0
|
247 }
|
nuclear@0
|
248
|
nuclear@0
|
249 void quicksort (int lo, int hi, int data[])
|
nuclear@0
|
250 {
|
nuclear@0
|
251 int m1 = lo;
|
nuclear@0
|
252 int m2 = hi;
|
nuclear@0
|
253 int temp0;
|
nuclear@0
|
254 unsigned short temp1;
|
nuclear@0
|
255
|
nuclear@0
|
256 int mp = data[(lo + hi)>>1];
|
nuclear@0
|
257
|
nuclear@0
|
258 while (m1<=m2)
|
nuclear@0
|
259 {
|
nuclear@0
|
260 while (data[m1] < mp) m1++;
|
nuclear@0
|
261 while (mp < data[m2]) m2--;
|
nuclear@0
|
262
|
nuclear@0
|
263 if (m1<=m2)
|
nuclear@0
|
264 {
|
nuclear@0
|
265 temp0 = data[m1]; data[m1] = data[m2]; data[m2] = temp0;
|
nuclear@0
|
266 temp1 = swp[m1]; swp[m1] = swp[m2]; swp[m2] = temp1;
|
nuclear@0
|
267 m1++;
|
nuclear@0
|
268 m2--;
|
nuclear@0
|
269 }
|
nuclear@0
|
270 }
|
nuclear@0
|
271
|
nuclear@0
|
272 if (m2>lo) quicksort(lo, m2, data);
|
nuclear@0
|
273 if (m1<hi) quicksort(m1, hi, data);
|
nuclear@0
|
274 }
|