1 /*
2 * KJL 15:13:43 7/17/97 - frustrum.c
3 *
4 * Contains all the functions connected
5 * to the view frustrum and clipping
6 *
7 */
8 #include "3dc.h"
9 #include "module.h"
10 #include "inline.h"
11
12 #include "stratdef.h"
13 #include "gamedef.h"
14
15 #include "kshape.h"
16 #include "kzsort.h"
17 #include "frustum.h"
18
19 #include "particle.h"
20
21 #define UseLocalAssert Yes
22 #include "ourasert.h"
23
24 /*KJL****************************************************************************************
25 * G L O B A L S *
26 ****************************************************************************************KJL*/
27 extern VECTORCH RotatedPts[];
28
29 extern DISPLAYBLOCK *Global_ODB_Ptr;
30 extern SHAPEHEADER *Global_ShapeHeaderPtr;
31 extern int *Global_ShapePoints;
32 extern int *Global_ShapeNormals;
33
34 extern VECTORCH LocalView;
35
36 #define FAR_Z_CLIP 0
37 #define FAR_Z_CLIP_RANGE 49000
38 /*KJL****************************************************************************************
39 * P R O T O T Y P E S *
40 ****************************************************************************************KJL*/
41 /* GOURAUD POLYGON CLIPPING */
42 void (*GouraudPolygon_ClipWithNegativeX)(void);
43 void (*GouraudPolygon_ClipWithPositiveY)(void);
44 void (*GouraudPolygon_ClipWithNegativeY)(void);
45 void (*GouraudPolygon_ClipWithPositiveX)(void);
46
47 /* TEXTURED POLYGON CLIPPING */
48 void (*TexturedPolygon_ClipWithNegativeX)(void);
49 void (*TexturedPolygon_ClipWithPositiveY)(void);
50 void (*TexturedPolygon_ClipWithNegativeY)(void);
51 void (*TexturedPolygon_ClipWithPositiveX)(void);
52
53 /* GOURAUD TEXTURED POLYGON CLIPPING */
54 void (*GouraudTexturedPolygon_ClipWithNegativeX)(void);
55 void (*GouraudTexturedPolygon_ClipWithPositiveY)(void);
56 void (*GouraudTexturedPolygon_ClipWithNegativeY)(void);
57 void (*GouraudTexturedPolygon_ClipWithPositiveX)(void);
58
59 /* FRUSTRUM TESTS */
60 int (*ObjectWithinFrustrum)(DISPLAYBLOCK *dbPtr);
61 int (*ObjectCompletelyWithinFrustrum)(DISPLAYBLOCK *dbPtr);
62 int (*VertexWithinFrustrum)(RENDERVERTEX *vertexPtr);
63 void (*TestVerticesWithFrustrum)(void);
64
65
66 static void GouraudPolygon_Norm_ClipWithNegativeX(void);
67 static void GouraudPolygon_Wide_ClipWithNegativeX(void);
68 static void GouraudPolygon_Norm_ClipWithPositiveY(void);
69 static void GouraudPolygon_Wide_ClipWithPositiveY(void);
70 static void GouraudPolygon_Norm_ClipWithNegativeY(void);
71 static void GouraudPolygon_Wide_ClipWithNegativeY(void);
72 static void GouraudPolygon_Norm_ClipWithPositiveX(void);
73 static void GouraudPolygon_Wide_ClipWithPositiveX(void);
74
75 static void TexturedPolygon_Norm_ClipWithNegativeX(void);
76 static void TexturedPolygon_Wide_ClipWithNegativeX(void);
77 static void TexturedPolygon_Norm_ClipWithPositiveY(void);
78 static void TexturedPolygon_Wide_ClipWithPositiveY(void);
79 static void TexturedPolygon_Norm_ClipWithNegativeY(void);
80 static void TexturedPolygon_Wide_ClipWithNegativeY(void);
81 static void TexturedPolygon_Norm_ClipWithPositiveX(void);
82 static void TexturedPolygon_Wide_ClipWithPositiveX(void);
83
84 static void GouraudTexturedPolygon_Norm_ClipWithNegativeX(void);
85 static void GouraudTexturedPolygon_Wide_ClipWithNegativeX(void);
86 static void GouraudTexturedPolygon_Norm_ClipWithPositiveY(void);
87 static void GouraudTexturedPolygon_Wide_ClipWithPositiveY(void);
88 static void GouraudTexturedPolygon_Norm_ClipWithNegativeY(void);
89 static void GouraudTexturedPolygon_Wide_ClipWithNegativeY(void);
90 static void GouraudTexturedPolygon_Norm_ClipWithPositiveX(void);
91 static void GouraudTexturedPolygon_Wide_ClipWithPositiveX(void);
92
93 static int VertexWithin_Norm_Frustrum(RENDERVERTEX *vertexPtr);
94 static int VertexWithin_Wide_Frustrum(RENDERVERTEX *vertexPtr);
95 static int ObjectWithin_Norm_Frustrum(DISPLAYBLOCK *dbPtr);
96 static int ObjectWithin_Wide_Frustrum(DISPLAYBLOCK *dbPtr);
97 static int ObjectCompletelyWithin_Norm_Frustrum(DISPLAYBLOCK *dbPtr);
98 static int ObjectCompletelyWithin_Wide_Frustrum(DISPLAYBLOCK *dbPtr);
99 static void TestVerticesWith_Norm_Frustrum(void);
100 static void TestVerticesWith_Wide_Frustrum(void);
101
102 /*KJL****************************************************************************************
103 * F U N C T I O N S *
104 ****************************************************************************************KJL*/
SetFrustrumType(enum FrustrumType frustrumType)105 void SetFrustrumType(enum FrustrumType frustrumType)
106 {
107 switch (frustrumType)
108 {
109 default:
110 case FRUSTRUM_TYPE_NORMAL:
111 {
112 /* GOURAUD POLYGON CLIPPING */
113 GouraudPolygon_ClipWithNegativeX = GouraudPolygon_Norm_ClipWithNegativeX;
114 GouraudPolygon_ClipWithPositiveY = GouraudPolygon_Norm_ClipWithPositiveY;
115 GouraudPolygon_ClipWithNegativeY = GouraudPolygon_Norm_ClipWithNegativeY;
116 GouraudPolygon_ClipWithPositiveX = GouraudPolygon_Norm_ClipWithPositiveX;
117
118 /* TEXTURED POLYGON CLIPPING */
119 TexturedPolygon_ClipWithNegativeX = TexturedPolygon_Norm_ClipWithNegativeX;
120 TexturedPolygon_ClipWithPositiveY = TexturedPolygon_Norm_ClipWithPositiveY;
121 TexturedPolygon_ClipWithNegativeY = TexturedPolygon_Norm_ClipWithNegativeY;
122 TexturedPolygon_ClipWithPositiveX = TexturedPolygon_Norm_ClipWithPositiveX;
123
124 /* GOURAUD TEXTURED POLYGON CLIPPING */
125 GouraudTexturedPolygon_ClipWithNegativeX = GouraudTexturedPolygon_Norm_ClipWithNegativeX;
126 GouraudTexturedPolygon_ClipWithPositiveY = GouraudTexturedPolygon_Norm_ClipWithPositiveY;
127 GouraudTexturedPolygon_ClipWithNegativeY = GouraudTexturedPolygon_Norm_ClipWithNegativeY;
128 GouraudTexturedPolygon_ClipWithPositiveX = GouraudTexturedPolygon_Norm_ClipWithPositiveX;
129
130 /* FRUSTRUM TESTS */
131 TestVerticesWithFrustrum = TestVerticesWith_Norm_Frustrum;
132 ObjectWithinFrustrum = ObjectWithin_Norm_Frustrum;
133 ObjectCompletelyWithinFrustrum = ObjectCompletelyWithin_Norm_Frustrum;
134 VertexWithinFrustrum = VertexWithin_Norm_Frustrum;
135
136 break;
137 }
138
139 case FRUSTRUM_TYPE_WIDE:
140 {
141 /* GOURAUD POLYGON CLIPPING */
142 GouraudPolygon_ClipWithNegativeX = GouraudPolygon_Wide_ClipWithNegativeX;
143 GouraudPolygon_ClipWithPositiveY = GouraudPolygon_Wide_ClipWithPositiveY;
144 GouraudPolygon_ClipWithNegativeY = GouraudPolygon_Wide_ClipWithNegativeY;
145 GouraudPolygon_ClipWithPositiveX = GouraudPolygon_Wide_ClipWithPositiveX;
146
147 /* TEXTURED POLYGON CLIPPING */
148 TexturedPolygon_ClipWithNegativeX = TexturedPolygon_Wide_ClipWithNegativeX;
149 TexturedPolygon_ClipWithPositiveY = TexturedPolygon_Wide_ClipWithPositiveY;
150 TexturedPolygon_ClipWithNegativeY = TexturedPolygon_Wide_ClipWithNegativeY;
151 TexturedPolygon_ClipWithPositiveX = TexturedPolygon_Wide_ClipWithPositiveX;
152
153 /* GOURAUD TEXTURED POLYGON CLIPPING */
154 GouraudTexturedPolygon_ClipWithNegativeX = GouraudTexturedPolygon_Wide_ClipWithNegativeX;
155 GouraudTexturedPolygon_ClipWithPositiveY = GouraudTexturedPolygon_Wide_ClipWithPositiveY;
156 GouraudTexturedPolygon_ClipWithNegativeY = GouraudTexturedPolygon_Wide_ClipWithNegativeY;
157 GouraudTexturedPolygon_ClipWithPositiveX = GouraudTexturedPolygon_Wide_ClipWithPositiveX;
158
159 /* FRUSTRUM TESTS */
160 TestVerticesWithFrustrum = TestVerticesWith_Wide_Frustrum;
161 ObjectWithinFrustrum = ObjectWithin_Wide_Frustrum;
162 ObjectCompletelyWithinFrustrum = ObjectCompletelyWithin_Wide_Frustrum;
163 VertexWithinFrustrum = VertexWithin_Wide_Frustrum;
164
165 break;
166 }
167 }
168 }
169
170 /* clipping code macros - these are used as building blocks to assemble
171 clipping fns for different polygon types with the minimum of fuss */
172 #define ZCLIPPINGVALUE 4
173 //64
174 #define Clip_Z_Test(v) (ZCLIPPINGVALUE <= (v)->Z)
175 #define Clip_NX_Test(v) (-(v)->X <= (v)->Z)
176 #define Clip_PX_Test(v) ((v)->X <= (v)->Z)
177 #define Clip_NY_Test(v) (-(v)->Y <= (v)->Z)
178 #define Clip_PY_Test(v) ((v)->Y <= (v)->Z)
179
180
181 #define Clip_LoopStart(b) \
182 do \
183 { \
184 RENDERVERTEX *nextVertexPtr; \
185 int nextVertexInside; \
186 \
187 /* setup pointer to next vertex, wrapping round if necessary */ \
188 if (!--verticesLeft) \
189 { \
190 nextVertexPtr = (b); \
191 } \
192 else \
193 { \
194 nextVertexPtr = curVertexPtr+1; \
195 } \
196 \
197 /* if current vertex is inside the plane, output it */ \
198 if (curVertexInside) \
199 { \
200 numberOfPointsOutputted++; \
201 *outputVerticesPtr++ = *curVertexPtr; \
202 } \
203 \
204 /* test if next vertex is inside the plane */ \
205 nextVertexInside =
206
207 #define Clip_Z_OutputXYZ \
208 /* if one is in, and the other is out, output a clipped vertex */ \
209 if (nextVertexInside != curVertexInside) \
210 { \
211 int lambda; \
212 \
213 lambda = DIV_FIXED \
214 ( \
215 (ZCLIPPINGVALUE - curVertexPtr->Z), \
216 (nextVertexPtr->Z - curVertexPtr->Z) \
217 ); \
218 \
219 outputVerticesPtr->X = curVertexPtr->X + MUL_FIXED(lambda,nextVertexPtr->X-curVertexPtr->X); \
220 outputVerticesPtr->Y = curVertexPtr->Y + MUL_FIXED(lambda,nextVertexPtr->Y-curVertexPtr->Y); \
221 outputVerticesPtr->Z = ZCLIPPINGVALUE;
222
223 #define Clip_NX_OutputXYZ \
224 /* if one is in, and the other is out, output a clipped vertex */ \
225 if (nextVertexInside != curVertexInside) \
226 { \
227 int lambda; \
228 \
229 lambda = DIV_FIXED \
230 ( \
231 (curVertexPtr->Z + curVertexPtr->X), \
232 -(nextVertexPtr->X-curVertexPtr->X) - (nextVertexPtr->Z-curVertexPtr->Z) \
233 ); \
234 \
235 outputVerticesPtr->X = curVertexPtr->X + MUL_FIXED(lambda,nextVertexPtr->X-curVertexPtr->X); \
236 outputVerticesPtr->Z = -outputVerticesPtr->X; \
237 outputVerticesPtr->Y = curVertexPtr->Y + MUL_FIXED(lambda,nextVertexPtr->Y-curVertexPtr->Y);
238
239 #define Clip_PX_OutputXYZ \
240 /* if one is in, and the other is out, output a clipped vertex */ \
241 if (nextVertexInside != curVertexInside) \
242 { \
243 int lambda; \
244 \
245 lambda = DIV_FIXED \
246 ( \
247 (curVertexPtr->Z - curVertexPtr->X), \
248 (nextVertexPtr->X-curVertexPtr->X) - (nextVertexPtr->Z-curVertexPtr->Z) \
249 ); \
250 \
251 outputVerticesPtr->X = curVertexPtr->X + MUL_FIXED(lambda,nextVertexPtr->X-curVertexPtr->X); \
252 outputVerticesPtr->Z = outputVerticesPtr->X; \
253 outputVerticesPtr->Y = curVertexPtr->Y + MUL_FIXED(lambda,nextVertexPtr->Y-curVertexPtr->Y);
254
255 #define Clip_NY_OutputXYZ \
256 /* if one is in, and the other is out, output a clipped vertex */ \
257 if (nextVertexInside != curVertexInside) \
258 { \
259 int lambda; \
260 \
261 lambda = DIV_FIXED \
262 ( \
263 (curVertexPtr->Z + curVertexPtr->Y), \
264 -(nextVertexPtr->Y-curVertexPtr->Y) - (nextVertexPtr->Z-curVertexPtr->Z) \
265 ); \
266 \
267 outputVerticesPtr->Z = curVertexPtr->Z + MUL_FIXED(lambda,nextVertexPtr->Z-curVertexPtr->Z); \
268 outputVerticesPtr->Y = -(outputVerticesPtr->Z); \
269 outputVerticesPtr->X = curVertexPtr->X + MUL_FIXED(lambda,nextVertexPtr->X-curVertexPtr->X);
270
271 #define Clip_PY_OutputXYZ \
272 /* if one is in, and the other is out, output a clipped vertex */ \
273 if (nextVertexInside != curVertexInside) \
274 { \
275 int lambda; \
276 \
277 lambda = DIV_FIXED \
278 ( \
279 (curVertexPtr->Z - curVertexPtr->Y), \
280 (nextVertexPtr->Y-curVertexPtr->Y) - (nextVertexPtr->Z-curVertexPtr->Z) \
281 ); \
282 \
283 outputVerticesPtr->Z = curVertexPtr->Z + MUL_FIXED(lambda,nextVertexPtr->Z-curVertexPtr->Z); \
284 outputVerticesPtr->Y = (outputVerticesPtr->Z); \
285 outputVerticesPtr->X = curVertexPtr->X + MUL_FIXED(lambda,nextVertexPtr->X-curVertexPtr->X);
286
287 #define Clip_OutputUV \
288 outputVerticesPtr->U = curVertexPtr->U + MUL_FIXED(lambda,nextVertexPtr->U-curVertexPtr->U); \
289 outputVerticesPtr->V = curVertexPtr->V + MUL_FIXED(lambda,nextVertexPtr->V-curVertexPtr->V);
290
291 #define Clip_OutputI \
292 outputVerticesPtr->A = curVertexPtr->A + MUL_FIXED(lambda,nextVertexPtr->A-curVertexPtr->A); \
293 outputVerticesPtr->R = curVertexPtr->R + MUL_FIXED(lambda,nextVertexPtr->R-curVertexPtr->R); \
294 outputVerticesPtr->G = curVertexPtr->G + MUL_FIXED(lambda,nextVertexPtr->G-curVertexPtr->G); \
295 outputVerticesPtr->B = curVertexPtr->B + MUL_FIXED(lambda,nextVertexPtr->B-curVertexPtr->B); \
296 outputVerticesPtr->SpecularR = curVertexPtr->SpecularR + MUL_FIXED(lambda,nextVertexPtr->SpecularR-curVertexPtr->SpecularR); \
297 outputVerticesPtr->SpecularG = curVertexPtr->SpecularG + MUL_FIXED(lambda,nextVertexPtr->SpecularG-curVertexPtr->SpecularG); \
298 outputVerticesPtr->SpecularB = curVertexPtr->SpecularB + MUL_FIXED(lambda,nextVertexPtr->SpecularB-curVertexPtr->SpecularB);
299
300 #define Clip_LoopEnd(b) \
301 numberOfPointsOutputted++; \
302 outputVerticesPtr++; \
303 } \
304 \
305 /* okay, now the current vertex becomes what was the next vertex */ \
306 curVertexPtr = nextVertexPtr; \
307 curVertexInside = nextVertexInside; \
308 } \
309 while(verticesLeft); \
310 \
311 RenderPolygon.NumberOfVertices = numberOfPointsOutputted;
312
313 /* Wide screen versions of clip macros */
314
315 #define Clip_Wide_NX_Test(v) (-(v)->X <= (v)->Z*2)
316 #define Clip_Wide_PX_Test(v) ((v)->X <= (v)->Z*2)
317 #define Clip_Wide_NY_Test(v) (-(v)->Y <= (v)->Z*2)
318 #define Clip_Wide_PY_Test(v) ((v)->Y <= (v)->Z*2)
319 #define Clip_Wide_NX_OutputXYZ \
320 /* if one is in, and the other is out, output a clipped vertex */ \
321 if (nextVertexInside != curVertexInside) \
322 { \
323 int lambda; \
324 \
325 lambda = DIV_FIXED \
326 ( \
327 (-2*curVertexPtr->Z - curVertexPtr->X), \
328 (nextVertexPtr->X-curVertexPtr->X) - (-2)*(nextVertexPtr->Z-curVertexPtr->Z) \
329 ); \
330 \
331 outputVerticesPtr->X = curVertexPtr->X + MUL_FIXED(lambda,nextVertexPtr->X-curVertexPtr->X); \
332 outputVerticesPtr->Z = -outputVerticesPtr->X/2; \
333 outputVerticesPtr->Y = curVertexPtr->Y + MUL_FIXED(lambda,nextVertexPtr->Y-curVertexPtr->Y);
334
335 #define Clip_Wide_PX_OutputXYZ \
336 /* if one is in, and the other is out, output a clipped vertex */ \
337 if (nextVertexInside != curVertexInside) \
338 { \
339 int lambda; \
340 \
341 lambda = DIV_FIXED \
342 ( \
343 (2*curVertexPtr->Z - curVertexPtr->X), \
344 (nextVertexPtr->X-curVertexPtr->X) - 2*(nextVertexPtr->Z-curVertexPtr->Z) \
345 ); \
346 \
347 outputVerticesPtr->X = curVertexPtr->X + MUL_FIXED(lambda,nextVertexPtr->X-curVertexPtr->X); \
348 outputVerticesPtr->Z = outputVerticesPtr->X/2; \
349 outputVerticesPtr->Y = curVertexPtr->Y + MUL_FIXED(lambda,nextVertexPtr->Y-curVertexPtr->Y);
350
351 #define Clip_Wide_NY_OutputXYZ \
352 /* if one is in, and the other is out, output a clipped vertex */ \
353 if (nextVertexInside != curVertexInside) \
354 { \
355 int lambda; \
356 \
357 lambda = DIV_FIXED \
358 ( \
359 (2*curVertexPtr->Z + curVertexPtr->Y), \
360 -(nextVertexPtr->Y-curVertexPtr->Y) - 2*(nextVertexPtr->Z-curVertexPtr->Z) \
361 ); \
362 \
363 outputVerticesPtr->Z = curVertexPtr->Z + MUL_FIXED(lambda,nextVertexPtr->Z-curVertexPtr->Z); \
364 outputVerticesPtr->Y = -(outputVerticesPtr->Z*2); \
365 outputVerticesPtr->X = curVertexPtr->X + MUL_FIXED(lambda,nextVertexPtr->X-curVertexPtr->X);
366
367 #define Clip_Wide_PY_OutputXYZ \
368 /* if one is in, and the other is out, output a clipped vertex */ \
369 if (nextVertexInside != curVertexInside) \
370 { \
371 int lambda; \
372 \
373 lambda = DIV_FIXED \
374 ( \
375 (2*curVertexPtr->Z - curVertexPtr->Y), \
376 (nextVertexPtr->Y-curVertexPtr->Y) - 2*(nextVertexPtr->Z-curVertexPtr->Z) \
377 ); \
378 \
379 outputVerticesPtr->Z = curVertexPtr->Z + MUL_FIXED(lambda,nextVertexPtr->Z-curVertexPtr->Z); \
380 outputVerticesPtr->Y = (outputVerticesPtr->Z*2); \
381 outputVerticesPtr->X = curVertexPtr->X + MUL_FIXED(lambda,nextVertexPtr->X-curVertexPtr->X);
382
383
384 /*KJL**************
385 * GOURAUD POLYGON *
386 **************KJL*/
387
388 /* Clip against Z plane */
GouraudPolygon_ClipWithZ(void)389 void GouraudPolygon_ClipWithZ(void)
390 {
391 RENDERVERTEX *curVertexPtr = VerticesBuffer;
392 RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
393 int verticesLeft = RenderPolygon.NumberOfVertices;
394 int numberOfPointsOutputted=0;
395
396 int curVertexInside = Clip_Z_Test(curVertexPtr);
397
398 Clip_LoopStart(VerticesBuffer)
399 Clip_Z_Test(nextVertexPtr);
400 Clip_Z_OutputXYZ
401 Clip_OutputI
402 Clip_LoopEnd((RenderPolygon.Vertices))
403 }
404
405
406 /* Clip against negative X plane */
GouraudPolygon_Norm_ClipWithNegativeX(void)407 static void GouraudPolygon_Norm_ClipWithNegativeX(void)
408 {
409 RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
410 RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
411 int verticesLeft = RenderPolygon.NumberOfVertices;
412 int numberOfPointsOutputted=0;
413
414 int curVertexInside = Clip_NX_Test(curVertexPtr);
415
416 Clip_LoopStart((RenderPolygon.Vertices))
417 Clip_NX_Test(nextVertexPtr);
418 Clip_NX_OutputXYZ
419 Clip_OutputI
420 Clip_LoopEnd(VerticesBuffer)
421 }
GouraudPolygon_Wide_ClipWithNegativeX(void)422 static void GouraudPolygon_Wide_ClipWithNegativeX(void)
423 {
424 RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
425 RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
426 int verticesLeft = RenderPolygon.NumberOfVertices;
427 int numberOfPointsOutputted=0;
428
429 int curVertexInside = Clip_Wide_NX_Test(curVertexPtr);
430
431 Clip_LoopStart((RenderPolygon.Vertices))
432 Clip_Wide_NX_Test(nextVertexPtr);
433 Clip_Wide_NX_OutputXYZ
434 Clip_OutputI
435 Clip_LoopEnd(VerticesBuffer)
436 }
437
438 /* Clip against positive Y plane*/
GouraudPolygon_Norm_ClipWithPositiveY(void)439 static void GouraudPolygon_Norm_ClipWithPositiveY(void)
440 {
441 RENDERVERTEX *curVertexPtr = VerticesBuffer;
442 RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
443 int verticesLeft = RenderPolygon.NumberOfVertices;
444 int numberOfPointsOutputted=0;
445
446 int curVertexInside = Clip_PY_Test(curVertexPtr);
447
448 Clip_LoopStart(VerticesBuffer)
449 Clip_PY_Test(nextVertexPtr);
450 Clip_PY_OutputXYZ
451 Clip_OutputI
452 Clip_LoopEnd((RenderPolygon.Vertices))
453 }
GouraudPolygon_Wide_ClipWithPositiveY(void)454 static void GouraudPolygon_Wide_ClipWithPositiveY(void)
455 {
456 RENDERVERTEX *curVertexPtr = VerticesBuffer;
457 RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
458 int verticesLeft = RenderPolygon.NumberOfVertices;
459 int numberOfPointsOutputted=0;
460
461 int curVertexInside = Clip_Wide_PY_Test(curVertexPtr);
462
463 Clip_LoopStart(VerticesBuffer)
464 Clip_Wide_PY_Test(nextVertexPtr);
465 Clip_Wide_PY_OutputXYZ
466 Clip_OutputI
467 Clip_LoopEnd((RenderPolygon.Vertices))
468 }
469
470 /* Clip against negative Y plane*/
GouraudPolygon_Norm_ClipWithNegativeY(void)471 static void GouraudPolygon_Norm_ClipWithNegativeY(void)
472 {
473 RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
474 RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
475 int verticesLeft = RenderPolygon.NumberOfVertices;
476 int numberOfPointsOutputted=0;
477
478 int curVertexInside = Clip_NY_Test(curVertexPtr);
479
480 Clip_LoopStart((RenderPolygon.Vertices))
481 Clip_NY_Test(nextVertexPtr);
482 Clip_NY_OutputXYZ
483 Clip_OutputI
484 Clip_LoopEnd(VerticesBuffer)
485 }
GouraudPolygon_Wide_ClipWithNegativeY(void)486 static void GouraudPolygon_Wide_ClipWithNegativeY(void)
487 {
488 RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
489 RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
490 int verticesLeft = RenderPolygon.NumberOfVertices;
491 int numberOfPointsOutputted=0;
492
493 int curVertexInside = Clip_Wide_NY_Test(curVertexPtr);
494
495 Clip_LoopStart((RenderPolygon.Vertices))
496 Clip_Wide_NY_Test(nextVertexPtr);
497 Clip_Wide_NY_OutputXYZ
498 Clip_OutputI
499 Clip_LoopEnd(VerticesBuffer)
500 }
501
502 /* Clip against positive X plane */
GouraudPolygon_Norm_ClipWithPositiveX(void)503 static void GouraudPolygon_Norm_ClipWithPositiveX(void)
504 {
505 RENDERVERTEX *curVertexPtr = VerticesBuffer;
506 RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
507 int verticesLeft = RenderPolygon.NumberOfVertices;
508 int numberOfPointsOutputted=0;
509
510 int curVertexInside = Clip_PX_Test(curVertexPtr);
511
512 Clip_LoopStart(VerticesBuffer)
513 Clip_PX_Test(nextVertexPtr);
514 Clip_PX_OutputXYZ
515 Clip_OutputI
516 Clip_LoopEnd((RenderPolygon.Vertices))
517 }
GouraudPolygon_Wide_ClipWithPositiveX(void)518 static void GouraudPolygon_Wide_ClipWithPositiveX(void)
519 {
520 RENDERVERTEX *curVertexPtr = VerticesBuffer;
521 RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
522 int verticesLeft = RenderPolygon.NumberOfVertices;
523 int numberOfPointsOutputted=0;
524
525 int curVertexInside = Clip_Wide_PX_Test(curVertexPtr);
526
527 Clip_LoopStart(VerticesBuffer)
528 Clip_Wide_PX_Test(nextVertexPtr);
529 Clip_Wide_PX_OutputXYZ
530 Clip_OutputI
531 Clip_LoopEnd((RenderPolygon.Vertices))
532 }
533
534 /*KJL***************
535 * TEXTURED POLYGON *
536 ***************KJL*/
537
538 /* Clip against Z plane */
TexturedPolygon_ClipWithZ(void)539 void TexturedPolygon_ClipWithZ(void)
540 {
541 RENDERVERTEX *curVertexPtr = VerticesBuffer;
542 RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
543 int verticesLeft = RenderPolygon.NumberOfVertices;
544 int numberOfPointsOutputted=0;
545
546 int curVertexInside = Clip_Z_Test(curVertexPtr);
547
548 Clip_LoopStart(VerticesBuffer)
549 Clip_Z_Test(nextVertexPtr);
550 Clip_Z_OutputXYZ
551 Clip_OutputUV
552 Clip_OutputI
553 Clip_LoopEnd((RenderPolygon.Vertices))
554 }
555
556 /* Clip against negative X plane */
TexturedPolygon_Norm_ClipWithNegativeX(void)557 static void TexturedPolygon_Norm_ClipWithNegativeX(void)
558 {
559 RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
560 RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
561 int verticesLeft = RenderPolygon.NumberOfVertices;
562 int numberOfPointsOutputted=0;
563
564 int curVertexInside = Clip_NX_Test(curVertexPtr);
565
566 Clip_LoopStart((RenderPolygon.Vertices))
567 Clip_NX_Test(nextVertexPtr);
568 Clip_NX_OutputXYZ
569 Clip_OutputUV
570 Clip_OutputI
571 Clip_LoopEnd(VerticesBuffer)
572 }
TexturedPolygon_Wide_ClipWithNegativeX(void)573 static void TexturedPolygon_Wide_ClipWithNegativeX(void)
574 {
575 RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
576 RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
577 int verticesLeft = RenderPolygon.NumberOfVertices;
578 int numberOfPointsOutputted=0;
579
580 int curVertexInside = Clip_Wide_NX_Test(curVertexPtr);
581
582 Clip_LoopStart((RenderPolygon.Vertices))
583 Clip_Wide_NX_Test(nextVertexPtr);
584 Clip_Wide_NX_OutputXYZ
585 Clip_OutputUV
586 Clip_OutputI
587 Clip_LoopEnd(VerticesBuffer)
588 }
589
590 /* Clip against positive Y plane*/
TexturedPolygon_Norm_ClipWithPositiveY(void)591 static void TexturedPolygon_Norm_ClipWithPositiveY(void)
592 {
593 RENDERVERTEX *curVertexPtr = VerticesBuffer;
594 RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
595 int verticesLeft = RenderPolygon.NumberOfVertices;
596 int numberOfPointsOutputted=0;
597
598 int curVertexInside = Clip_PY_Test(curVertexPtr);
599
600 Clip_LoopStart(VerticesBuffer)
601 Clip_PY_Test(nextVertexPtr);
602 Clip_PY_OutputXYZ
603 Clip_OutputUV
604 Clip_OutputI
605 Clip_LoopEnd((RenderPolygon.Vertices))
606 }
TexturedPolygon_Wide_ClipWithPositiveY(void)607 static void TexturedPolygon_Wide_ClipWithPositiveY(void)
608 {
609 RENDERVERTEX *curVertexPtr = VerticesBuffer;
610 RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
611 int verticesLeft = RenderPolygon.NumberOfVertices;
612 int numberOfPointsOutputted=0;
613
614 int curVertexInside = Clip_Wide_PY_Test(curVertexPtr);
615
616 Clip_LoopStart(VerticesBuffer)
617 Clip_Wide_PY_Test(nextVertexPtr);
618 Clip_Wide_PY_OutputXYZ
619 Clip_OutputUV
620 Clip_OutputI
621 Clip_LoopEnd((RenderPolygon.Vertices))
622 }
623
624 /* Clip against negative Y plane*/
TexturedPolygon_Norm_ClipWithNegativeY(void)625 static void TexturedPolygon_Norm_ClipWithNegativeY(void)
626 {
627 RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
628 RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
629 int verticesLeft = RenderPolygon.NumberOfVertices;
630 int numberOfPointsOutputted=0;
631
632 int curVertexInside = Clip_NY_Test(curVertexPtr);
633
634 Clip_LoopStart((RenderPolygon.Vertices))
635 Clip_NY_Test(nextVertexPtr);
636 Clip_NY_OutputXYZ
637 Clip_OutputUV
638 Clip_OutputI
639 Clip_LoopEnd(VerticesBuffer)
640 }
TexturedPolygon_Wide_ClipWithNegativeY(void)641 static void TexturedPolygon_Wide_ClipWithNegativeY(void)
642 {
643 RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
644 RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
645 int verticesLeft = RenderPolygon.NumberOfVertices;
646 int numberOfPointsOutputted=0;
647
648 int curVertexInside = Clip_Wide_NY_Test(curVertexPtr);
649
650 Clip_LoopStart((RenderPolygon.Vertices))
651 Clip_Wide_NY_Test(nextVertexPtr);
652 Clip_Wide_NY_OutputXYZ
653 Clip_OutputUV
654 Clip_OutputI
655 Clip_LoopEnd(VerticesBuffer)
656 }
657
658 /* Clip against positive X plane */
TexturedPolygon_Norm_ClipWithPositiveX(void)659 static void TexturedPolygon_Norm_ClipWithPositiveX(void)
660 {
661 RENDERVERTEX *curVertexPtr = VerticesBuffer;
662 RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
663 int verticesLeft = RenderPolygon.NumberOfVertices;
664 int numberOfPointsOutputted=0;
665
666 int curVertexInside = Clip_PX_Test(curVertexPtr);
667
668 Clip_LoopStart(VerticesBuffer)
669 Clip_PX_Test(nextVertexPtr);
670 Clip_PX_OutputXYZ
671 Clip_OutputUV
672 Clip_OutputI
673 Clip_LoopEnd((RenderPolygon.Vertices))
674 }
TexturedPolygon_Wide_ClipWithPositiveX(void)675 static void TexturedPolygon_Wide_ClipWithPositiveX(void)
676 {
677 RENDERVERTEX *curVertexPtr = VerticesBuffer;
678 RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
679 int verticesLeft = RenderPolygon.NumberOfVertices;
680 int numberOfPointsOutputted=0;
681
682 int curVertexInside = Clip_Wide_PX_Test(curVertexPtr);
683
684 Clip_LoopStart(VerticesBuffer)
685 Clip_Wide_PX_Test(nextVertexPtr);
686 Clip_Wide_PX_OutputXYZ
687 Clip_OutputUV
688 Clip_OutputI
689 Clip_LoopEnd((RenderPolygon.Vertices))
690 }
691
692
693
694
695 /*KJL************************
696 * GOURAUD TEXTURED POLYGONS *
697 ************************KJL*/
698
699 /* Clip against Z plane */
GouraudTexturedPolygon_ClipWithZ(void)700 void GouraudTexturedPolygon_ClipWithZ(void)
701 {
702 RENDERVERTEX *curVertexPtr = VerticesBuffer;
703 RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
704 int verticesLeft = RenderPolygon.NumberOfVertices;
705 int numberOfPointsOutputted=0;
706
707 int curVertexInside = Clip_Z_Test(curVertexPtr);
708
709 Clip_LoopStart(VerticesBuffer)
710 Clip_Z_Test(nextVertexPtr);
711 Clip_Z_OutputXYZ
712 Clip_OutputUV
713 Clip_OutputI
714 Clip_LoopEnd((RenderPolygon.Vertices))
715 }
716
717 /* Clip against negative X plane */
GouraudTexturedPolygon_Norm_ClipWithNegativeX(void)718 static void GouraudTexturedPolygon_Norm_ClipWithNegativeX(void)
719 {
720 RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
721 RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
722 int verticesLeft = RenderPolygon.NumberOfVertices;
723 int numberOfPointsOutputted=0;
724
725 int curVertexInside = Clip_NX_Test(curVertexPtr);
726
727 Clip_LoopStart((RenderPolygon.Vertices))
728 Clip_NX_Test(nextVertexPtr);
729 Clip_NX_OutputXYZ
730 Clip_OutputUV
731 Clip_OutputI
732 Clip_LoopEnd(VerticesBuffer)
733 }
GouraudTexturedPolygon_Wide_ClipWithNegativeX(void)734 static void GouraudTexturedPolygon_Wide_ClipWithNegativeX(void)
735 {
736 RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
737 RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
738 int verticesLeft = RenderPolygon.NumberOfVertices;
739 int numberOfPointsOutputted=0;
740
741 int curVertexInside = Clip_Wide_NX_Test(curVertexPtr);
742
743 Clip_LoopStart((RenderPolygon.Vertices))
744 Clip_Wide_NX_Test(nextVertexPtr);
745 Clip_Wide_NX_OutputXYZ
746 Clip_OutputUV
747 Clip_OutputI
748 Clip_LoopEnd(VerticesBuffer)
749 }
750
751 /* Clip against positive Y plane*/
GouraudTexturedPolygon_Norm_ClipWithPositiveY(void)752 static void GouraudTexturedPolygon_Norm_ClipWithPositiveY(void)
753 {
754 RENDERVERTEX *curVertexPtr = VerticesBuffer;
755 RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
756 int verticesLeft = RenderPolygon.NumberOfVertices;
757 int numberOfPointsOutputted=0;
758
759 int curVertexInside = Clip_PY_Test(curVertexPtr);
760
761 Clip_LoopStart(VerticesBuffer)
762 Clip_PY_Test(nextVertexPtr);
763 Clip_PY_OutputXYZ
764 Clip_OutputUV
765 Clip_OutputI
766 Clip_LoopEnd((RenderPolygon.Vertices))
767 }
GouraudTexturedPolygon_Wide_ClipWithPositiveY(void)768 static void GouraudTexturedPolygon_Wide_ClipWithPositiveY(void)
769 {
770 RENDERVERTEX *curVertexPtr = VerticesBuffer;
771 RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
772 int verticesLeft = RenderPolygon.NumberOfVertices;
773 int numberOfPointsOutputted=0;
774
775 int curVertexInside = Clip_Wide_PY_Test(curVertexPtr);
776
777 Clip_LoopStart(VerticesBuffer)
778 Clip_Wide_PY_Test(nextVertexPtr);
779 Clip_Wide_PY_OutputXYZ
780 Clip_OutputUV
781 Clip_OutputI
782 Clip_LoopEnd((RenderPolygon.Vertices))
783 }
784
785 /* Clip against negative Y plane*/
GouraudTexturedPolygon_Norm_ClipWithNegativeY(void)786 static void GouraudTexturedPolygon_Norm_ClipWithNegativeY(void)
787 {
788 RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
789 RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
790 int verticesLeft = RenderPolygon.NumberOfVertices;
791 int numberOfPointsOutputted=0;
792
793 int curVertexInside = Clip_NY_Test(curVertexPtr);
794
795 Clip_LoopStart((RenderPolygon.Vertices))
796 Clip_NY_Test(nextVertexPtr);
797 Clip_NY_OutputXYZ
798 Clip_OutputUV
799 Clip_OutputI
800 Clip_LoopEnd(VerticesBuffer)
801 }
GouraudTexturedPolygon_Wide_ClipWithNegativeY(void)802 static void GouraudTexturedPolygon_Wide_ClipWithNegativeY(void)
803 {
804 RENDERVERTEX *curVertexPtr = (RenderPolygon.Vertices);
805 RENDERVERTEX *outputVerticesPtr = VerticesBuffer;
806 int verticesLeft = RenderPolygon.NumberOfVertices;
807 int numberOfPointsOutputted=0;
808
809 int curVertexInside = Clip_Wide_NY_Test(curVertexPtr);
810
811 Clip_LoopStart((RenderPolygon.Vertices))
812 Clip_Wide_NY_Test(nextVertexPtr);
813 Clip_Wide_NY_OutputXYZ
814 Clip_OutputUV
815 Clip_OutputI
816 Clip_LoopEnd(VerticesBuffer)
817 }
818
819 /* Clip against positive X plane */
GouraudTexturedPolygon_Norm_ClipWithPositiveX(void)820 static void GouraudTexturedPolygon_Norm_ClipWithPositiveX(void)
821 {
822 RENDERVERTEX *curVertexPtr = VerticesBuffer;
823 RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
824 int verticesLeft = RenderPolygon.NumberOfVertices;
825 int numberOfPointsOutputted=0;
826
827 int curVertexInside = Clip_PX_Test(curVertexPtr);
828
829 Clip_LoopStart(VerticesBuffer)
830 Clip_PX_Test(nextVertexPtr);
831 Clip_PX_OutputXYZ
832 Clip_OutputUV
833 Clip_OutputI
834 Clip_LoopEnd((RenderPolygon.Vertices))
835 }
GouraudTexturedPolygon_Wide_ClipWithPositiveX(void)836 static void GouraudTexturedPolygon_Wide_ClipWithPositiveX(void)
837 {
838 RENDERVERTEX *curVertexPtr = VerticesBuffer;
839 RENDERVERTEX *outputVerticesPtr = (RenderPolygon.Vertices);
840 int verticesLeft = RenderPolygon.NumberOfVertices;
841 int numberOfPointsOutputted=0;
842
843 int curVertexInside = Clip_Wide_PX_Test(curVertexPtr);
844
845 Clip_LoopStart(VerticesBuffer)
846 Clip_Wide_PX_Test(nextVertexPtr);
847 Clip_Wide_PX_OutputXYZ
848 Clip_OutputUV
849 Clip_OutputI
850 Clip_LoopEnd((RenderPolygon.Vertices))
851 }
852
853
854
855
856
857
858
PolygonWithinFrustrum(POLYHEADER * polyPtr)859 int PolygonWithinFrustrum(POLYHEADER *polyPtr)
860 {
861 char inFrustrumFlag=0;
862 char noClippingFlag=INSIDE_FRUSTRUM;
863 int *vertexNumberPtr = &polyPtr->Poly1stPt;
864
865 if (polyPtr->PolyFlags & iflag_notvis) return 0;
866
867 RenderPolygon.NumberOfVertices=0;
868 while(*vertexNumberPtr != Term)
869 {
870 int vertexNumber = *vertexNumberPtr++;
871
872 inFrustrumFlag |= FrustrumFlagForVertex[vertexNumber];
873 noClippingFlag &= FrustrumFlagForVertex[vertexNumber];
874
875 /* count the number of points in the polygon; this is used for all the loops that follow */
876 RenderPolygon.NumberOfVertices++;
877 }
878
879 if (inFrustrumFlag != INSIDE_FRUSTRUM) return 0;
880
881 /* at this point we know that the poly is inside the view frustrum */
882
883 /* if not a sprite, test direction of poly */
884 if (!( (Global_ShapeHeaderPtr->shapeflags&ShapeFlag_Sprite) || (polyPtr->PolyFlags & iflag_no_bfc) ))
885 {
886 VECTORCH pop;
887 VECTORCH *normalPtr = (VECTORCH*)(Global_ShapeNormals + polyPtr->PolyNormalIndex);
888
889 #if 1
890 if(Global_ODB_Ptr->ObMorphCtrl)
891 {
892 extern MORPHDISPLAY MorphDisplay;
893 SHAPEHEADER *shape1Ptr;
894 VECTORCH *shape1PointsPtr;
895 VECTORCH *shape2PointsPtr;
896
897 /* Set up the morph data */
898 GetMorphDisplay(&MorphDisplay, Global_ODB_Ptr);
899
900 shape1Ptr = MorphDisplay.md_sptr1;
901
902 if(MorphDisplay.md_lerp == 0x0000)
903 {
904 shape1PointsPtr = (VECTORCH *)*shape1Ptr->points;
905 pop = shape1PointsPtr[polyPtr->Poly1stPt];
906
907 }
908 else if(MorphDisplay.md_lerp == 0xffff)
909 {
910 SHAPEHEADER *shape2Ptr = MorphDisplay.md_sptr2;
911
912 shape2PointsPtr = (VECTORCH *)*shape2Ptr->points;
913 pop = shape2PointsPtr[polyPtr->Poly1stPt];
914 }
915 else
916 {
917 SHAPEHEADER *shape2Ptr = MorphDisplay.md_sptr2;
918
919 shape1PointsPtr = (VECTORCH *)(*shape1Ptr->points);
920 shape2PointsPtr = (VECTORCH *)(*shape2Ptr->points);
921
922 {
923 VECTORCH vertex1 = shape1PointsPtr[polyPtr->Poly1stPt];
924 VECTORCH vertex2 = shape2PointsPtr[polyPtr->Poly1stPt];
925
926 if( (vertex1.vx == vertex2.vx && vertex1.vy == vertex2.vy && vertex1.vz == vertex2.vz) )
927 {
928 pop = vertex1;
929 }
930 else
931 {
932 /* KJL 15:27:20 05/22/97 - I've changed this to speed things up, If a vertex
933 component has a magnitude greater than 32768 things will go wrong. */
934 pop.vx = vertex1.vx + (((vertex2.vx-vertex1.vx)*MorphDisplay.md_lerp)>>16);
935 pop.vy = vertex1.vy + (((vertex2.vy-vertex1.vy)*MorphDisplay.md_lerp)>>16);
936 pop.vz = vertex1.vz + (((vertex2.vz-vertex1.vz)*MorphDisplay.md_lerp)>>16);
937 }
938 }
939 }
940 }
941 else
942 #endif
943 {
944 /* Get the 1st polygon point as the POP */
945 VECTORCH *pointsArray = (VECTORCH*)(Global_ShapePoints);
946 pop = pointsArray[polyPtr->Poly1stPt];
947 }
948 pop.vx -= LocalView.vx;
949 pop.vy -= LocalView.vy;
950 pop.vz -= LocalView.vz;
951
952 if (Dot(&pop, normalPtr)>0) return 0;
953 }
954
955 if (noClippingFlag == INSIDE_FRUSTRUM) return 2;
956
957 /* yes, we need to draw poly */
958 return 1;
959 }
960
PolygonShouldBeDrawn(POLYHEADER * polyPtr)961 int PolygonShouldBeDrawn(POLYHEADER *polyPtr)
962 {
963
964 /* at this point we know that the poly is inside the view frustrum */
965 if (polyPtr->PolyFlags & iflag_notvis) return 0;
966
967 #if 1
968 /* if not a sprite, test direction of poly */
969 if (!( (Global_ShapeHeaderPtr->shapeflags&ShapeFlag_Sprite) || (polyPtr->PolyFlags & iflag_no_bfc) ))
970 {
971 /* KJL 16:49:14 7/10/97 -
972
973 ***** MORPHED NORMALS SUPPORT NOT YET ADDED *****
974
975 */
976 VECTORCH pop;
977 VECTORCH *normalPtr = (VECTORCH*)(Global_ShapeNormals + polyPtr->PolyNormalIndex);
978 VECTORCH *pointsArray = (VECTORCH*)(Global_ShapePoints);
979 /* Get the 1st polygon point as the POP */
980
981 pop.vx = pointsArray[polyPtr->Poly1stPt].vx - LocalView.vx;
982 pop.vy = pointsArray[polyPtr->Poly1stPt].vy - LocalView.vy;
983 pop.vz = pointsArray[polyPtr->Poly1stPt].vz - LocalView.vz;
984
985 if (Dot(&pop, normalPtr)>0) return 0;
986 }
987 #endif
988 #if 0
989 {
990 int *vertexNumberPtr = &polyPtr->Poly1stPt;
991 RenderPolygon.NumberOfVertices=0;
992 while(*vertexNumberPtr++ != Term)
993 {
994 /* count the number of points in the polygon; this is used for all the loops that follow */
995 RenderPolygon.NumberOfVertices++;
996 }
997 }
998 #elif 0
999 RenderPolygon.NumberOfVertices = 3;
1000 #else
1001 {
1002 int *vertexNumberPtr = &polyPtr->Poly1stPt;
1003 if (vertexNumberPtr[3] == Term)
1004 {
1005 RenderPolygon.NumberOfVertices = 3;
1006 }
1007 else
1008 {
1009 RenderPolygon.NumberOfVertices = 4;
1010 }
1011 }
1012 #endif
1013
1014 return 2;
1015 }
1016
1017 /* KJL 16:18:59 7/7/97 - simple vertex test to be used in first
1018 pass of subdividing code */
VertexWithin_Norm_Frustrum(RENDERVERTEX * vertexPtr)1019 static int VertexWithin_Norm_Frustrum(RENDERVERTEX *vertexPtr)
1020 {
1021 int vertexFlag = 0;
1022
1023 if(Clip_Z_Test(vertexPtr)) vertexFlag |= INSIDE_FRUSTRUM_Z_PLANE;
1024 if(Clip_PX_Test(vertexPtr)) vertexFlag |= INSIDE_FRUSTRUM_PX_PLANE;
1025 if(Clip_NX_Test(vertexPtr)) vertexFlag |= INSIDE_FRUSTRUM_NX_PLANE;
1026 if(Clip_PY_Test(vertexPtr)) vertexFlag |= INSIDE_FRUSTRUM_PY_PLANE;
1027 if(Clip_NY_Test(vertexPtr)) vertexFlag |= INSIDE_FRUSTRUM_NY_PLANE;
1028
1029 return vertexFlag;
1030 }
1031
VertexWithin_Wide_Frustrum(RENDERVERTEX * vertexPtr)1032 static int VertexWithin_Wide_Frustrum(RENDERVERTEX *vertexPtr)
1033 {
1034 int vertexFlag = 0;
1035
1036 if(Clip_Z_Test(vertexPtr)) vertexFlag |= INSIDE_FRUSTRUM_Z_PLANE;
1037 if(Clip_Wide_PX_Test(vertexPtr)) vertexFlag |= INSIDE_FRUSTRUM_PX_PLANE;
1038 if(Clip_Wide_NX_Test(vertexPtr)) vertexFlag |= INSIDE_FRUSTRUM_NX_PLANE;
1039 if(Clip_Wide_PY_Test(vertexPtr)) vertexFlag |= INSIDE_FRUSTRUM_PY_PLANE;
1040 if(Clip_Wide_NY_Test(vertexPtr)) vertexFlag |= INSIDE_FRUSTRUM_NY_PLANE;
1041
1042 return vertexFlag;
1043 }
1044
1045
1046 /* KJL 15:32:52 7/17/97 - Test to see if an object is in the view frustrum */
ObjectWithin_Norm_Frustrum(DISPLAYBLOCK * dbPtr)1047 static int ObjectWithin_Norm_Frustrum(DISPLAYBLOCK *dbPtr)
1048 {
1049 // LOCALASSERT(dbPtr->ObShapeData->shaperadius);
1050
1051 #if FAR_Z_CLIP
1052 if(dbPtr->ObView.vz-dbPtr->ObShapeData->shaperadius<=FAR_Z_CLIP_RANGE)
1053 #endif
1054 if (dbPtr->ObView.vz+dbPtr->ObShapeData->shaperadius>=ZCLIPPINGVALUE)
1055 {
1056 /* scale radius by square root of 2 */
1057 int radius = MUL_FIXED(92682,dbPtr->ObShapeData->shaperadius);
1058
1059 if ((dbPtr->ObView.vx-dbPtr->ObView.vz)<=radius)
1060 if ((-dbPtr->ObView.vx-dbPtr->ObView.vz)<=radius)
1061 if ((dbPtr->ObView.vy-dbPtr->ObView.vz)<=radius)
1062 if ((-dbPtr->ObView.vy-dbPtr->ObView.vz)<=radius)
1063 return 1;
1064 }
1065 return 0;
1066 }
ObjectCompletelyWithin_Norm_Frustrum(DISPLAYBLOCK * dbPtr)1067 static int ObjectCompletelyWithin_Norm_Frustrum(DISPLAYBLOCK *dbPtr)
1068 {
1069 // LOCALASSERT(dbPtr->ObShapeData->shaperadius);
1070 if (dbPtr->ObView.vz-dbPtr->ObShapeData->shaperadius>=ZCLIPPINGVALUE)
1071 {
1072 /* scale radius by square root of 2 */
1073 int radius = MUL_FIXED(92682,dbPtr->ObShapeData->shaperadius);
1074
1075 if ((dbPtr->ObView.vz-dbPtr->ObView.vx)>=radius)
1076 if ((dbPtr->ObView.vz+dbPtr->ObView.vx)>=radius)
1077 if ((dbPtr->ObView.vz-dbPtr->ObView.vy)>=radius)
1078 if ((dbPtr->ObView.vz+dbPtr->ObView.vy)>=radius)
1079 return 1;
1080 }
1081 return 0;
1082 }
ObjectCompletelyWithin_Wide_Frustrum(DISPLAYBLOCK * dbPtr)1083 static int ObjectCompletelyWithin_Wide_Frustrum(DISPLAYBLOCK *dbPtr)
1084 {
1085 return 0;
1086 }
1087
ObjectWithin_Wide_Frustrum(DISPLAYBLOCK * dbPtr)1088 static int ObjectWithin_Wide_Frustrum(DISPLAYBLOCK *dbPtr)
1089 {
1090 if (dbPtr->ObView.vz+dbPtr->ObShapeData->shaperadius>=ZCLIPPINGVALUE)
1091 {
1092 /* scale radius by square root of 5 */
1093 int radius = MUL_FIXED(146543,dbPtr->ObShapeData->shaperadius);
1094
1095 if ((dbPtr->ObView.vx-2*dbPtr->ObView.vz)<=radius)
1096 if ((-dbPtr->ObView.vx-2*dbPtr->ObView.vz)<=radius)
1097 if ((dbPtr->ObView.vy-2*dbPtr->ObView.vz)<=radius)
1098 if ((-dbPtr->ObView.vy-2*dbPtr->ObView.vz)<=radius)
1099 return 1;
1100 }
1101 return 0;
1102 }
1103
1104
1105 char FrustrumFlagForVertex[maxrotpts];
1106
TestVerticesWith_Norm_Frustrum(void)1107 void TestVerticesWith_Norm_Frustrum(void)
1108 {
1109 int v = Global_ShapeHeaderPtr->numpoints;
1110
1111 GLOBALASSERT(v>0);
1112
1113 while(v--)
1114 {
1115 char vertexFlag = 0;
1116
1117 #if FAR_Z_CLIP
1118 if(ZCLIPPINGVALUE <= RotatedPts[v].vz && RotatedPts[v].vz<=FAR_Z_CLIP_RANGE)
1119 #else
1120 if(ZCLIPPINGVALUE <= RotatedPts[v].vz)
1121 #endif
1122 vertexFlag |= INSIDE_FRUSTRUM_Z_PLANE;
1123
1124 if(-RotatedPts[v].vx <= RotatedPts[v].vz)
1125 vertexFlag |= INSIDE_FRUSTRUM_PX_PLANE;
1126
1127 if(RotatedPts[v].vx <= RotatedPts[v].vz)
1128 vertexFlag |= INSIDE_FRUSTRUM_NX_PLANE;
1129
1130 if(-RotatedPts[v].vy <= RotatedPts[v].vz)
1131 vertexFlag |= INSIDE_FRUSTRUM_PY_PLANE;
1132
1133 if(RotatedPts[v].vy <= RotatedPts[v].vz)
1134 vertexFlag |= INSIDE_FRUSTRUM_NY_PLANE;
1135
1136 FrustrumFlagForVertex[v] = vertexFlag;
1137 }
1138 }
TestVerticesWith_Wide_Frustrum(void)1139 void TestVerticesWith_Wide_Frustrum(void)
1140 {
1141 int v = Global_ShapeHeaderPtr->numpoints;
1142
1143 GLOBALASSERT(v>0);
1144
1145 while(v--)
1146 {
1147 char vertexFlag = 0;
1148
1149 if(ZCLIPPINGVALUE <= RotatedPts[v].vz)
1150 vertexFlag |= INSIDE_FRUSTRUM_Z_PLANE;
1151
1152 if(-RotatedPts[v].vx <= RotatedPts[v].vz*2)
1153 vertexFlag |= INSIDE_FRUSTRUM_PX_PLANE;
1154
1155 if(RotatedPts[v].vx <= RotatedPts[v].vz*2)
1156 vertexFlag |= INSIDE_FRUSTRUM_NX_PLANE;
1157
1158 if(-RotatedPts[v].vy <= RotatedPts[v].vz*2)
1159 vertexFlag |= INSIDE_FRUSTRUM_PY_PLANE;
1160
1161 if(RotatedPts[v].vy <= RotatedPts[v].vz*2)
1162 vertexFlag |= INSIDE_FRUSTRUM_NY_PLANE;
1163
1164 FrustrumFlagForVertex[v] = vertexFlag;
1165 }
1166 }
1167
1168
1169
DecalWithinFrustrum(DECAL * decalPtr)1170 int DecalWithinFrustrum(DECAL *decalPtr)
1171 {
1172 char inFrustrumFlag;
1173 char noClippingFlag;
1174
1175 if(ModuleCurrVisArray[decalPtr->ModuleIndex] != 2) return 0;
1176
1177 inFrustrumFlag=0;
1178 noClippingFlag=INSIDE_FRUSTRUM;
1179
1180 {
1181 int vertexFlag = VertexWithinFrustrum(&VerticesBuffer[0]);
1182 inFrustrumFlag |= vertexFlag;
1183 noClippingFlag &= vertexFlag;
1184 }
1185 {
1186 int vertexFlag = VertexWithinFrustrum(&VerticesBuffer[1]);
1187 inFrustrumFlag |= vertexFlag;
1188 noClippingFlag &= vertexFlag;
1189 }
1190 {
1191 int vertexFlag = VertexWithinFrustrum(&VerticesBuffer[2]);
1192 inFrustrumFlag |= vertexFlag;
1193 noClippingFlag &= vertexFlag;
1194 }
1195 {
1196 int vertexFlag = VertexWithinFrustrum(&VerticesBuffer[3]);
1197 inFrustrumFlag |= vertexFlag;
1198 noClippingFlag &= vertexFlag;
1199 }
1200
1201 if (inFrustrumFlag != INSIDE_FRUSTRUM) return 0;
1202 if (noClippingFlag == INSIDE_FRUSTRUM) return 2;
1203
1204 /* yes, we need to draw poly */
1205 return 1;
1206 }
1207
QuadWithinFrustrum(void)1208 int QuadWithinFrustrum(void)
1209 {
1210 char inFrustrumFlag;
1211 char noClippingFlag;
1212
1213 inFrustrumFlag=0;
1214 noClippingFlag=INSIDE_FRUSTRUM;
1215
1216 {
1217 int vertexFlag = VertexWithinFrustrum(&VerticesBuffer[0]);
1218 inFrustrumFlag |= vertexFlag;
1219 noClippingFlag &= vertexFlag;
1220 }
1221 {
1222 int vertexFlag = VertexWithinFrustrum(&VerticesBuffer[1]);
1223 inFrustrumFlag |= vertexFlag;
1224 noClippingFlag &= vertexFlag;
1225 }
1226 {
1227 int vertexFlag = VertexWithinFrustrum(&VerticesBuffer[2]);
1228 inFrustrumFlag |= vertexFlag;
1229 noClippingFlag &= vertexFlag;
1230 }
1231 {
1232 int vertexFlag = VertexWithinFrustrum(&VerticesBuffer[3]);
1233 inFrustrumFlag |= vertexFlag;
1234 noClippingFlag &= vertexFlag;
1235 }
1236
1237 if (inFrustrumFlag != INSIDE_FRUSTRUM) return 0;
1238 if (noClippingFlag == INSIDE_FRUSTRUM) return 2;
1239
1240 /* yes, we need to draw poly */
1241 return 1;
1242 }
1243
TriangleWithinFrustrum(void)1244 int TriangleWithinFrustrum(void)
1245 {
1246 char inFrustrumFlag;
1247 char noClippingFlag;
1248
1249 inFrustrumFlag=0;
1250 noClippingFlag=INSIDE_FRUSTRUM;
1251
1252 {
1253 int vertexFlag = VertexWithinFrustrum(&VerticesBuffer[0]);
1254 inFrustrumFlag |= vertexFlag;
1255 noClippingFlag &= vertexFlag;
1256 }
1257 {
1258 int vertexFlag = VertexWithinFrustrum(&VerticesBuffer[1]);
1259 inFrustrumFlag |= vertexFlag;
1260 noClippingFlag &= vertexFlag;
1261 }
1262 {
1263 int vertexFlag = VertexWithinFrustrum(&VerticesBuffer[2]);
1264 inFrustrumFlag |= vertexFlag;
1265 noClippingFlag &= vertexFlag;
1266 }
1267
1268 if (inFrustrumFlag != INSIDE_FRUSTRUM) return 0;
1269 if (noClippingFlag == INSIDE_FRUSTRUM) return 2;
1270
1271 /* yes, we need to draw poly */
1272 return 1;
1273 }
1274