frustrum.c 39 KB

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