MLRLightMap.cpp 48 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590
  1. //===========================================================================//
  2. // Copyright (C) Microsoft Corporation. All rights reserved. //
  3. //===========================================================================//
  4. #include "MLRHeaders.hpp"
  5. #if !defined(MLR_MLRCLIPTRICK_HPP)
  6. #include <MLR\MLRClipTrick.hpp>
  7. #endif
  8. //#############################################################################
  9. //########################### MLRLightMap ###############################
  10. //#############################################################################
  11. MLRLightMap::ClassData*
  12. MLRLightMap::DefaultData = NULL;
  13. Stuff::MemoryStream
  14. *MLRLightMap::stream;
  15. GOSVertexPool*
  16. MLRLightMap::vertexPool;
  17. DynamicArrayOf<Stuff::Vector4D>
  18. *transformedCoords, *clipExtraCoords;
  19. DynamicArrayOf<RGBAColor>
  20. *clipExtraColors;
  21. DynamicArrayOf<Vector2DScalar>
  22. *clipExtraTexCoords;
  23. DynamicArrayOf<MLRClippingState>
  24. *clippingStates;
  25. ClipPolygon2
  26. *MLRLightMap::clipBuffer;
  27. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  28. //
  29. void
  30. MLRLightMap::InitializeClass()
  31. {
  32. Verify(!DefaultData);
  33. Verify(gos_GetCurrentHeap() == StaticHeap);
  34. DefaultData =
  35. new ClassData(
  36. MLRLightMapClassID,
  37. "MidLevelRenderer::MLRLightMap",
  38. RegisteredClass::DefaultData
  39. );
  40. Register_Object(DefaultData);
  41. unsigned char *ptr = new unsigned char [Limits::Max_Size_Of_LightMap_MemoryStream];
  42. Register_Pointer(ptr);
  43. stream = new MemoryStream(ptr, Limits::Max_Size_Of_LightMap_MemoryStream);
  44. Register_Object(stream);
  45. transformedCoords = new DynamicArrayOf<Stuff::Vector4D> (Limits::Max_Number_Vertices_Per_Polygon);
  46. Register_Object(transformedCoords);
  47. clipExtraCoords = new DynamicArrayOf<Stuff::Vector4D> (2*Limits::Max_Number_Vertices_Per_Polygon);
  48. Register_Object(clipExtraCoords);
  49. clipExtraColors = new DynamicArrayOf<RGBAColor> (2*Limits::Max_Number_Vertices_Per_Polygon);
  50. Register_Object(clipExtraColors);
  51. clipExtraTexCoords = new DynamicArrayOf<Vector2DScalar> (2*Limits::Max_Number_Vertices_Per_Polygon);
  52. Register_Object(clipExtraTexCoords);
  53. clippingStates = new DynamicArrayOf<MLRClippingState> (Limits::Max_Number_Vertices_Per_Polygon);
  54. Register_Object(clippingStates);
  55. clipBuffer = new ClipPolygon2 [2];
  56. Register_Pointer(clipBuffer);
  57. clipBuffer[0].Init(Limits::Max_Number_Of_Multitextures);
  58. clipBuffer[1].Init(Limits::Max_Number_Of_Multitextures);
  59. }
  60. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  61. //
  62. void
  63. MLRLightMap::TerminateClass()
  64. {
  65. clipBuffer[1].Destroy();
  66. clipBuffer[0].Destroy();
  67. Unregister_Pointer(clipBuffer);
  68. delete [] clipBuffer;
  69. Unregister_Object(transformedCoords);
  70. delete transformedCoords;
  71. Unregister_Object(clipExtraCoords);
  72. delete clipExtraCoords;
  73. Unregister_Object(clipExtraColors);
  74. delete clipExtraColors;
  75. Unregister_Object(clipExtraTexCoords);
  76. delete clipExtraTexCoords;
  77. Unregister_Object(clippingStates);
  78. delete clippingStates;
  79. stream->Rewind();
  80. unsigned char *ptr = (unsigned char *)stream->GetPointer();
  81. Unregister_Object(stream);
  82. delete stream;
  83. stream = NULL;
  84. Unregister_Pointer(ptr);
  85. delete [] ptr;
  86. Unregister_Object(DefaultData);
  87. delete DefaultData;
  88. DefaultData = NULL;
  89. }
  90. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  91. //
  92. MLRLightMap::MLRLightMap(MLRTexture *tex) :
  93. RegisteredClass(DefaultData)
  94. {
  95. Verify(gos_GetCurrentHeap() == Heap);
  96. state.SetTextureHandle(tex->GetTextureHandle());
  97. state.SetRenderDeltaMask(MLRState::TextureMask);
  98. // state.SetFogData(0xffffffff, 0.0f, 1.0f, 100.0f);
  99. #ifdef OLDFOG
  100. state.SetFogMode(MLRState::DisableFogMode);
  101. #else
  102. state.SetFogMode(0);
  103. #endif
  104. state.SetZBufferCompareOn();
  105. state.SetZBufferWriteOff();
  106. state.SetBackFaceOn();
  107. state.SetAlphaMode(MLRState::OneOneMode);
  108. state.SetFilterMode(MLRState::BiLinearFilterMode);
  109. state.SetTextureWrapMode(MLRState::TextureClamp);
  110. }
  111. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  112. //
  113. MLRLightMap::~MLRLightMap()
  114. {
  115. Check_Object(this);
  116. Check_Object(stream);
  117. }
  118. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  119. //
  120. void
  121. MLRLightMap::SetDrawData
  122. (
  123. GOSVertexPool *vp,
  124. Stuff::Matrix4D *mat,
  125. MLRClippingState& clippingState,
  126. MLRState& _state
  127. )
  128. {
  129. vertexPool = vp;
  130. stream->Rewind();
  131. *stream << (int)Matrix4D;
  132. *stream << reinterpret_cast<int>(mat);
  133. *stream << (int)ClippingState;
  134. clippingState.Save(stream);
  135. *stream << (int)MasterRenderState;
  136. _state.Save(stream);
  137. }
  138. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  139. //
  140. void
  141. MLRLightMap::TestInstance()
  142. {
  143. Verify(IsDerivedFrom(DefaultData));
  144. Check_Object(stream);
  145. }
  146. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  147. //
  148. void
  149. MLRLightMap::DrawLightMaps(MLRSorter *sorter)
  150. {
  151. Check_Object(stream);
  152. void *ptr, *end = stream->GetPointer();
  153. Stuff::Matrix4D *currentMatrix=NULL;
  154. MLRClippingState currentClippingState;
  155. MLRState currentState, masterState;
  156. unsigned short stride;
  157. int i, pointerValue;
  158. Stuff::Point3D *coords = NULL;
  159. Stuff::RGBAColor color;
  160. Stuff::RGBAColor *colors = NULL;
  161. Vector2DScalar *texCoords = NULL;
  162. DWORD argb = 0xffffffff;
  163. Check_Object(vertexPool);
  164. GOSVertex* gos_vertices = vertexPool->GetActualVertexPool();
  165. int numGOSVertices = 0;
  166. int msd;
  167. MemoryStreamData type;
  168. stream->Rewind();
  169. ptr = stream->GetPointer();
  170. while(ptr < end)
  171. {
  172. *stream >> msd;
  173. type = static_cast<MemoryStreamData>(msd);
  174. switch(msd)
  175. {
  176. case Matrix4D:
  177. *stream >> pointerValue;
  178. currentMatrix = reinterpret_cast<Stuff::Matrix4D*>(pointerValue);
  179. break;
  180. case ClippingState:
  181. currentClippingState.Load(stream);
  182. break;
  183. case MasterRenderState:
  184. masterState.Load(stream, Current_MLR_Version);
  185. break;
  186. case LightMapRenderState:
  187. {
  188. MLRState lightmapState;
  189. lightmapState.Load(stream, Current_MLR_Version);
  190. lightmapState.Combine(masterState, lightmapState);
  191. if(numGOSVertices && (lightmapState != currentState))
  192. {
  193. vertexPool->Increase(numGOSVertices);
  194. SortData *sd = sorter->SetRawData
  195. (
  196. gos_vertices,
  197. numGOSVertices,
  198. currentState,
  199. SortData::TriList
  200. );
  201. if(currentState.GetDrawNowMode()==MLRState::DrawNowOnMode)
  202. {
  203. SortData::DrawFunc drawFunc = sd->Draw[sd->type];
  204. (sd->*drawFunc)();
  205. }
  206. else
  207. {
  208. sorter->AddSortRawData(sd);
  209. }
  210. gos_vertices = vertexPool->GetActualVertexPool();
  211. numGOSVertices = 0;
  212. }
  213. currentState = lightmapState;
  214. }
  215. break;
  216. case Polygon:
  217. {
  218. *stream >> stride;
  219. Verify(stride<=Limits::Max_Number_Vertices_Per_Polygon);
  220. *stream >> color;
  221. argb = GOSCopyColor(&color);
  222. coords = (Stuff::Point3D *)stream->GetPointer();
  223. stream->AdvancePointer(stride*sizeof(Stuff::Point3D));
  224. texCoords = (Vector2DScalar *)stream->GetPointer();
  225. stream->AdvancePointer(stride*sizeof(Vector2DScalar));
  226. MLRClippingState theAnd(0x3f), theOr(0);
  227. MLRClippingState *cs = clippingStates->GetData();
  228. Vector4D *v4d = transformedCoords->GetData();
  229. for(i=0;i<stride;i++,v4d++,cs++)
  230. {
  231. v4d->Multiply(coords[i], *currentMatrix);
  232. if(currentClippingState!=0)
  233. {
  234. cs->Clip4dVertex(v4d);
  235. theAnd &= *cs;
  236. theOr |= *cs;
  237. }
  238. #if defined(_ARMOR)
  239. else
  240. {
  241. Verify((*transformedCoords)[i].x >= 0.0f && (*transformedCoords)[i].x <= (*transformedCoords)[i].w );
  242. Verify((*transformedCoords)[i].y >= 0.0f && (*transformedCoords)[i].y <= (*transformedCoords)[i].w );
  243. Verify((*transformedCoords)[i].z >= 0.0f && (*transformedCoords)[i].z <= (*transformedCoords)[i].w );
  244. }
  245. #endif
  246. }
  247. if(theOr == 0)
  248. {
  249. for(i=1;i<stride-1;i++)
  250. {
  251. Verify((vertexPool->GetLast() + 3 + numGOSVertices) < vertexPool->GetLength());
  252. GOSCopyTriangleData(
  253. &gos_vertices[numGOSVertices],
  254. transformedCoords->GetData(),
  255. texCoords,
  256. 0, i + 1, i
  257. );
  258. gos_vertices[numGOSVertices].argb = argb;
  259. gos_vertices[numGOSVertices+1].argb = argb;
  260. gos_vertices[numGOSVertices+2].argb = argb;
  261. numGOSVertices+=3;
  262. }
  263. }
  264. else
  265. {
  266. if(theAnd != 0)
  267. {
  268. break;
  269. }
  270. else
  271. {
  272. int k, k0, k1, l, mask, ct = 0;
  273. Scalar a = 0.0f;
  274. int numberVerticesPerPolygon = 0;
  275. //
  276. //---------------------------------------------------------------
  277. // Handle the case of a single clipping plane by stepping through
  278. // the vertices and finding the edge it originates
  279. //---------------------------------------------------------------
  280. //
  281. bool firstIsIn;
  282. MLRClippingState theTest;
  283. if (theOr.GetNumberOfSetBits() == 1)
  284. {
  285. #ifdef LAB_ONLY
  286. Set_Statistic(PolysClippedButOnePlane, PolysClippedButOnePlane+1);
  287. #endif
  288. for(k=0;k<stride;k++)
  289. {
  290. int clipped_index = numberVerticesPerPolygon;
  291. k0 = k;
  292. k1 = (k+1) < stride ? k+1 : 0;
  293. //
  294. //----------------------------------------------------
  295. // If this vertex is inside the viewing space, copy it
  296. // directly to the clipping buffer
  297. //----------------------------------------------------
  298. //
  299. theTest = (*clippingStates)[k0];
  300. if(theTest == 0)
  301. {
  302. firstIsIn = true;
  303. (*clipExtraCoords)[clipped_index] = (*transformedCoords)[k0];
  304. Verify((*clipExtraCoords)[clipped_index].x >= 0.0f && (*clipExtraCoords)[clipped_index].x <= (*clipExtraCoords)[clipped_index].w );
  305. Verify((*clipExtraCoords)[clipped_index].y >= 0.0f && (*clipExtraCoords)[clipped_index].y <= (*clipExtraCoords)[clipped_index].w );
  306. Verify((*clipExtraCoords)[clipped_index].z >= 0.0f && (*clipExtraCoords)[clipped_index].z <= (*clipExtraCoords)[clipped_index].w );
  307. (*clipExtraTexCoords)[clipped_index] = texCoords[k0];
  308. numberVerticesPerPolygon++;
  309. clipped_index++;
  310. //
  311. //-------------------------------------------------------
  312. // We don't need to clip this edge if the next vertex is
  313. // also in the viewing space, so just move on to the next
  314. // vertex
  315. //-------------------------------------------------------
  316. //
  317. if((*clippingStates)[k1] == 0)
  318. {
  319. continue;
  320. }
  321. }
  322. //
  323. //---------------------------------------------------------
  324. // This vertex is outside the viewing space, so if the next
  325. // vertex is also outside the viewing space, no clipping is
  326. // needed and we throw this vertex away. Since only one
  327. // clipping plane is involved, it must be in the same space
  328. // as the first vertex
  329. //---------------------------------------------------------
  330. //
  331. else
  332. {
  333. firstIsIn = false;
  334. if((*clippingStates)[k1] != 0)
  335. {
  336. Verify((*clippingStates)[k1] == (*clippingStates)[k0]);
  337. continue;
  338. }
  339. }
  340. //
  341. //--------------------------------------------------
  342. // We now find the distance along the edge where the
  343. // clipping plane will intersect
  344. //--------------------------------------------------
  345. //
  346. mask = 1;
  347. theTest |= (*clippingStates)[k1];
  348. //
  349. //-----------------------------------------------------
  350. // Find the boundary conditions that match our clipping
  351. // plane
  352. //-----------------------------------------------------
  353. //
  354. for (l=0; l<MLRClippingState::NextBit; l++)
  355. {
  356. if(theTest.IsClipped(mask))
  357. {
  358. // GetDoubleBC(l, bc0, bc1, transformedCoords[k0], transformedCoords[k1]);
  359. //
  360. //-------------------------------------------
  361. // Find the clipping interval from bc0 to bc1
  362. //-------------------------------------------
  363. //
  364. if(firstIsIn==true)
  365. {
  366. a = GetLerpFactor(l, (*transformedCoords)[k0], (*transformedCoords)[k1]);
  367. }
  368. else
  369. {
  370. a = GetLerpFactor(l, (*transformedCoords)[k1], (*transformedCoords)[k0]);
  371. }
  372. Verify(a >= 0.0f && a <= 1.0f);
  373. ct = l;
  374. break;
  375. }
  376. mask <<= 1;
  377. }
  378. //
  379. //------------------------------
  380. // Lerp the homogeneous position
  381. //------------------------------
  382. //
  383. if(firstIsIn==true)
  384. {
  385. (*clipExtraCoords)[clipped_index].Lerp(
  386. (*transformedCoords)[k0],
  387. (*transformedCoords)[k1],
  388. a
  389. );
  390. DoClipTrick((*clipExtraCoords)[clipped_index], ct);
  391. Verify((*clipExtraCoords)[clipped_index].x >= 0.0f && (*clipExtraCoords)[clipped_index].x <= (*clipExtraCoords)[clipped_index].w );
  392. Verify((*clipExtraCoords)[clipped_index].y >= 0.0f && (*clipExtraCoords)[clipped_index].y <= (*clipExtraCoords)[clipped_index].w );
  393. Verify((*clipExtraCoords)[clipped_index].z >= 0.0f && (*clipExtraCoords)[clipped_index].z <= (*clipExtraCoords)[clipped_index].w );
  394. //
  395. //-----------------------------------------------------
  396. // If there are texture uv's, we need to lerp them in a
  397. // perspective correct manner
  398. //-----------------------------------------------------
  399. //
  400. (*clipExtraTexCoords)[clipped_index].Lerp
  401. (
  402. texCoords[k0],
  403. texCoords[k1],
  404. a
  405. );
  406. }
  407. else
  408. {
  409. (*clipExtraCoords)[clipped_index].Lerp(
  410. (*transformedCoords)[k1],
  411. (*transformedCoords)[k0],
  412. a
  413. );
  414. DoClipTrick((*clipExtraCoords)[clipped_index], ct);
  415. Verify((*clipExtraCoords)[clipped_index].x >= 0.0f && (*clipExtraCoords)[clipped_index].x <= (*clipExtraCoords)[clipped_index].w );
  416. Verify((*clipExtraCoords)[clipped_index].y >= 0.0f && (*clipExtraCoords)[clipped_index].y <= (*clipExtraCoords)[clipped_index].w );
  417. Verify((*clipExtraCoords)[clipped_index].z >= 0.0f && (*clipExtraCoords)[clipped_index].z <= (*clipExtraCoords)[clipped_index].w );
  418. //
  419. //-----------------------------------------------------
  420. // If there are texture uv's, we need to lerp them in a
  421. // perspective correct manner
  422. //-----------------------------------------------------
  423. //
  424. (*clipExtraTexCoords)[clipped_index].Lerp
  425. (
  426. texCoords[k1],
  427. texCoords[k0],
  428. a
  429. );
  430. }
  431. //
  432. //--------------------------------
  433. // Bump the polygon's vertex count
  434. //--------------------------------
  435. //
  436. numberVerticesPerPolygon++;
  437. }
  438. }
  439. //
  440. //---------------------------------------------------------------
  441. // We have to handle multiple planes. We do this by creating two
  442. // buffers and we switch between them as we clip plane by plane
  443. //---------------------------------------------------------------
  444. //
  445. else
  446. {
  447. #ifdef LAB_ONLY
  448. Set_Statistic(PolysClippedButGOnePlane, PolysClippedButGOnePlane+1);
  449. #endif
  450. ClipData2 srcPolygon, dstPolygon;
  451. int dstBuffer = 1;
  452. srcPolygon.coords = clipBuffer[dstBuffer].coords.GetData();
  453. srcPolygon.texCoords = clipBuffer[dstBuffer].texCoords.GetData();
  454. srcPolygon.clipPerVertex = clipBuffer[dstBuffer].clipPerVertex.GetData();
  455. //
  456. //----------------------------------------------------------
  457. // unravel and copy the original data into the source buffer
  458. //----------------------------------------------------------
  459. //
  460. for(k=0;k<stride;k++)
  461. {
  462. srcPolygon.coords[k] = (*transformedCoords)[k];
  463. srcPolygon.texCoords[k] = texCoords[k];
  464. srcPolygon.clipPerVertex[k] = (*clippingStates)[k];
  465. }
  466. srcPolygon.length = stride;
  467. //
  468. //--------------------------------
  469. // Point to the destination buffer
  470. //--------------------------------
  471. //
  472. dstBuffer = 0;
  473. dstPolygon.coords = clipBuffer[dstBuffer].coords.GetData();
  474. dstPolygon.texCoords = clipBuffer[dstBuffer].texCoords.GetData();
  475. dstPolygon.clipPerVertex = clipBuffer[dstBuffer].clipPerVertex.GetData();
  476. dstPolygon.length = 0;
  477. //
  478. //-----------------------------------------------------------
  479. // Spin through each plane that clipped the primitive and use
  480. // it to actually clip the primitive
  481. //-----------------------------------------------------------
  482. //
  483. mask = 1;
  484. MLRClippingState theNewOr(0);
  485. int loop = 4;
  486. do
  487. {
  488. for(l=0; l<MLRClippingState::NextBit; l++)
  489. {
  490. if(theOr.IsClipped(mask))
  491. {
  492. //
  493. //-----------------------------------
  494. // Clip each vertex against the plane
  495. //-----------------------------------
  496. //
  497. for(k=0;k<srcPolygon.length;k++)
  498. {
  499. k1 = (k+1) < srcPolygon.length ? k+1 : 0;
  500. theTest = srcPolygon.clipPerVertex[k];
  501. //
  502. //----------------------------------------------------
  503. // If this vertex is inside the viewing space, copy it
  504. // directly to the clipping buffer
  505. //----------------------------------------------------
  506. //
  507. if(theTest.IsClipped(mask) == 0)
  508. {
  509. firstIsIn = true;
  510. dstPolygon.coords[dstPolygon.length] =
  511. srcPolygon.coords[k];
  512. dstPolygon.clipPerVertex[dstPolygon.length] =
  513. srcPolygon.clipPerVertex[k];
  514. dstPolygon.texCoords[dstPolygon.length] =
  515. srcPolygon.texCoords[k];
  516. dstPolygon.length++;
  517. //
  518. //-------------------------------------------------------
  519. // We don't need to clip this edge if the next vertex is
  520. // also in the viewing space, so just move on to the next
  521. // vertex
  522. //-------------------------------------------------------
  523. //
  524. if(srcPolygon.clipPerVertex[k1].IsClipped(mask) == 0)
  525. {
  526. continue;
  527. }
  528. }
  529. //
  530. //---------------------------------------------------------
  531. // This vertex is outside the viewing space, so if the next
  532. // vertex is also outside the viewing space, no clipping is
  533. // needed and we throw this vertex away. Since only one
  534. // clipping plane is involved, it must be in the same space
  535. // as the first vertex
  536. //---------------------------------------------------------
  537. //
  538. else
  539. {
  540. firstIsIn = false;
  541. if(srcPolygon.clipPerVertex[k1].IsClipped(mask) != 0)
  542. {
  543. Verify(
  544. srcPolygon.clipPerVertex[k1].IsClipped(mask)
  545. == srcPolygon.clipPerVertex[k].IsClipped(mask)
  546. );
  547. continue;
  548. }
  549. }
  550. //
  551. //-------------------------------------------
  552. // Find the clipping interval from bc0 to bc1
  553. //-------------------------------------------
  554. //
  555. if(firstIsIn == true)
  556. {
  557. a = GetLerpFactor (l, srcPolygon.coords[k], srcPolygon.coords[k1]);
  558. Verify(a >= 0.0f && a <= 1.0f);
  559. //
  560. //------------------------------
  561. // Lerp the homogeneous position
  562. //------------------------------
  563. //
  564. dstPolygon.coords[dstPolygon.length].Lerp(
  565. srcPolygon.coords[k],
  566. srcPolygon.coords[k1],
  567. a
  568. );
  569. DoClipTrick(dstPolygon.coords[dstPolygon.length], l);
  570. //
  571. //-----------------------------------------------------
  572. // If there are texture uv's, we need to lerp them in a
  573. // perspective correct manner
  574. //-----------------------------------------------------
  575. //
  576. dstPolygon.texCoords[dstPolygon.length].Lerp
  577. (
  578. srcPolygon.texCoords[k],
  579. srcPolygon.texCoords[k1],
  580. a
  581. );
  582. }
  583. else
  584. {
  585. a = GetLerpFactor (l, srcPolygon.coords[k1], srcPolygon.coords[k]);
  586. Verify(a >= 0.0f && a <= 1.0f);
  587. //
  588. //------------------------------
  589. // Lerp the homogeneous position
  590. //------------------------------
  591. //
  592. dstPolygon.coords[dstPolygon.length].Lerp(
  593. srcPolygon.coords[k1],
  594. srcPolygon.coords[k],
  595. a
  596. );
  597. DoClipTrick(dstPolygon.coords[dstPolygon.length], l);
  598. //
  599. //-----------------------------------------------------
  600. // If there are texture uv's, we need to lerp them in a
  601. // perspective correct manner
  602. //-----------------------------------------------------
  603. //
  604. dstPolygon.texCoords[dstPolygon.length].Lerp
  605. (
  606. srcPolygon.texCoords[k1],
  607. srcPolygon.texCoords[k],
  608. a
  609. );
  610. }
  611. //
  612. //-------------------------------------
  613. // We have to generate a new clip state
  614. //-------------------------------------
  615. //
  616. dstPolygon.clipPerVertex[dstPolygon.length].Clip4dVertex(&dstPolygon.coords[dstPolygon.length]);
  617. //
  618. //----------------------------------
  619. // Bump the new polygon vertex count
  620. //----------------------------------
  621. //
  622. dstPolygon.length++;
  623. }
  624. //
  625. //-----------------------------------------------
  626. // Swap source and destination buffer pointers in
  627. // preparation for the next plane test
  628. //-----------------------------------------------
  629. //
  630. srcPolygon.coords = clipBuffer[dstBuffer].coords.GetData();
  631. srcPolygon.texCoords = clipBuffer[dstBuffer].texCoords.GetData();
  632. srcPolygon.clipPerVertex = clipBuffer[dstBuffer].clipPerVertex.GetData();
  633. srcPolygon.length = dstPolygon.length;
  634. dstBuffer = !dstBuffer;
  635. dstPolygon.coords = clipBuffer[dstBuffer].coords.GetData();
  636. dstPolygon.texCoords = clipBuffer[dstBuffer].texCoords.GetData();
  637. dstPolygon.clipPerVertex = clipBuffer[dstBuffer].clipPerVertex.GetData();
  638. dstPolygon.length = 0;
  639. }
  640. mask = mask << 1;
  641. }
  642. theNewOr = 0;
  643. for(k=0;k<srcPolygon.length;k++)
  644. {
  645. theNewOr |= srcPolygon.clipPerVertex[k];
  646. }
  647. theOr == theNewOr;
  648. loop++;
  649. } while (theNewOr != 0 && loop--);
  650. Verify(theNewOr == 0);
  651. //
  652. //--------------------------------------------------
  653. // Move the most recent polygon into the clip buffer
  654. //--------------------------------------------------
  655. //
  656. for(k=0;k<srcPolygon.length;k++)
  657. {
  658. (*clipExtraCoords)[k] = srcPolygon.coords[k];
  659. Verify((*clipExtraCoords)[k].x >= 0.0f && (*clipExtraCoords)[k].x <= (*clipExtraCoords)[k].w );
  660. Verify((*clipExtraCoords)[k].y >= 0.0f && (*clipExtraCoords)[k].y <= (*clipExtraCoords)[k].w );
  661. Verify((*clipExtraCoords)[k].z >= 0.0f && (*clipExtraCoords)[k].z <= (*clipExtraCoords)[k].w );
  662. (*clipExtraTexCoords)[k] = srcPolygon.texCoords[k];
  663. }
  664. numberVerticesPerPolygon = srcPolygon.length;
  665. }
  666. // clip
  667. for(i=1;i<numberVerticesPerPolygon-1;i++)
  668. {
  669. Verify((vertexPool->GetLast() + 3 + numGOSVertices) < vertexPool->GetLength());
  670. GOSCopyTriangleData(
  671. &gos_vertices[numGOSVertices],
  672. clipExtraCoords->GetData(),
  673. clipExtraTexCoords->GetData(),
  674. 0, i + 1, i
  675. );
  676. gos_vertices[numGOSVertices].argb = argb;
  677. gos_vertices[numGOSVertices+1].argb = argb;
  678. gos_vertices[numGOSVertices+2].argb = argb;
  679. numGOSVertices+=3;
  680. }
  681. }
  682. }
  683. }
  684. break;
  685. case PolygonWithColor:
  686. {
  687. *stream >> stride;
  688. Verify(stride<=Limits::Max_Number_Vertices_Per_Polygon);
  689. coords = (Stuff::Point3D *)stream->GetPointer();
  690. stream->AdvancePointer(stride*sizeof(Stuff::Point3D));
  691. colors = (Stuff::RGBAColor *)stream->GetPointer();
  692. stream->AdvancePointer(stride*sizeof(Stuff::RGBAColor));
  693. texCoords = (Vector2DScalar *)stream->GetPointer();
  694. stream->AdvancePointer(stride*sizeof(Vector2DScalar));
  695. MLRClippingState theAnd(0x3f), theOr(0);
  696. MLRClippingState *cs = clippingStates->GetData();
  697. Vector4D *v4d = transformedCoords->GetData();
  698. for(i=0;i<stride;i++,v4d++,cs++)
  699. {
  700. v4d->Multiply(coords[i], *currentMatrix);
  701. if(currentClippingState!=0)
  702. {
  703. cs->Clip4dVertex(v4d);
  704. theAnd &= *cs;
  705. theOr |= *cs;
  706. }
  707. #if defined(_ARMOR)
  708. else
  709. {
  710. Verify((*transformedCoords)[i].x >= 0.0f && (*transformedCoords)[i].x <= (*transformedCoords)[i].w );
  711. Verify((*transformedCoords)[i].y >= 0.0f && (*transformedCoords)[i].y <= (*transformedCoords)[i].w );
  712. Verify((*transformedCoords)[i].z >= 0.0f && (*transformedCoords)[i].z <= (*transformedCoords)[i].w );
  713. }
  714. #endif
  715. }
  716. if(theOr == 0)
  717. {
  718. for(i=1;i<stride-1;i++)
  719. {
  720. Verify((vertexPool->GetLast() + 3 + numGOSVertices) < vertexPool->GetLength());
  721. GOSCopyTriangleData(
  722. &gos_vertices[numGOSVertices],
  723. transformedCoords->GetData(),
  724. colors,
  725. texCoords,
  726. 0, i + 1, i
  727. );
  728. numGOSVertices+=3;
  729. }
  730. }
  731. else
  732. {
  733. if(theAnd != 0)
  734. {
  735. break;
  736. }
  737. else
  738. {
  739. int k, k0, k1, l, mask, ct = 0;
  740. Scalar a = 0.0f;
  741. int numberVerticesPerPolygon = 0;
  742. //
  743. //---------------------------------------------------------------
  744. // Handle the case of a single clipping plane by stepping through
  745. // the vertices and finding the edge it originates
  746. //---------------------------------------------------------------
  747. //
  748. bool firstIsIn;
  749. MLRClippingState theTest;
  750. if (theOr.GetNumberOfSetBits() == 1)
  751. {
  752. #ifdef LAB_ONLY
  753. Set_Statistic(PolysClippedButOnePlane, PolysClippedButOnePlane+1);
  754. #endif
  755. for(k=0;k<stride;k++)
  756. {
  757. int clipped_index = numberVerticesPerPolygon;
  758. k0 = k;
  759. k1 = (k+1) < stride ? k+1 : 0;
  760. //
  761. //----------------------------------------------------
  762. // If this vertex is inside the viewing space, copy it
  763. // directly to the clipping buffer
  764. //----------------------------------------------------
  765. //
  766. theTest = (*clippingStates)[k0];
  767. if(theTest == 0)
  768. {
  769. firstIsIn = true;
  770. (*clipExtraCoords)[clipped_index] = (*transformedCoords)[k0];
  771. Verify((*clipExtraCoords)[clipped_index].x >= 0.0f && (*clipExtraCoords)[clipped_index].x <= (*clipExtraCoords)[clipped_index].w );
  772. Verify((*clipExtraCoords)[clipped_index].y >= 0.0f && (*clipExtraCoords)[clipped_index].y <= (*clipExtraCoords)[clipped_index].w );
  773. Verify((*clipExtraCoords)[clipped_index].z >= 0.0f && (*clipExtraCoords)[clipped_index].z <= (*clipExtraCoords)[clipped_index].w );
  774. (*clipExtraColors)[clipped_index] = colors[k0];
  775. (*clipExtraTexCoords)[clipped_index] = texCoords[k0];
  776. numberVerticesPerPolygon++;
  777. clipped_index++;
  778. //
  779. //-------------------------------------------------------
  780. // We don't need to clip this edge if the next vertex is
  781. // also in the viewing space, so just move on to the next
  782. // vertex
  783. //-------------------------------------------------------
  784. //
  785. if((*clippingStates)[k1] == 0)
  786. {
  787. continue;
  788. }
  789. }
  790. //
  791. //---------------------------------------------------------
  792. // This vertex is outside the viewing space, so if the next
  793. // vertex is also outside the viewing space, no clipping is
  794. // needed and we throw this vertex away. Since only one
  795. // clipping plane is involved, it must be in the same space
  796. // as the first vertex
  797. //---------------------------------------------------------
  798. //
  799. else
  800. {
  801. firstIsIn = false;
  802. if((*clippingStates)[k1] != 0)
  803. {
  804. Verify((*clippingStates)[k1] == (*clippingStates)[k0]);
  805. continue;
  806. }
  807. }
  808. //
  809. //--------------------------------------------------
  810. // We now find the distance along the edge where the
  811. // clipping plane will intersect
  812. //--------------------------------------------------
  813. //)
  814. mask = 1;
  815. theTest |= (*clippingStates)[k1];
  816. //
  817. //-----------------------------------------------------
  818. // Find the boundary conditions that match our clipping
  819. // plane
  820. //-----------------------------------------------------
  821. //
  822. for (l=0; l<MLRClippingState::NextBit; l++)
  823. {
  824. if(theTest.IsClipped(mask))
  825. {
  826. // GetDoubleBC(l, bc0, bc1, transformedCoords[k0], transformedCoords[k1]);
  827. //
  828. //-------------------------------------------
  829. // Find the clipping interval from bc0 to bc1
  830. //-------------------------------------------
  831. //
  832. if(firstIsIn==true)
  833. {
  834. a = GetLerpFactor(l, (*transformedCoords)[k0], (*transformedCoords)[k1]);
  835. }
  836. else
  837. {
  838. a = GetLerpFactor(l, (*transformedCoords)[k1], (*transformedCoords)[k0]);
  839. }
  840. Verify(a >= 0.0f && a <= 1.0f);
  841. ct = l;
  842. break;
  843. }
  844. mask <<= 1;
  845. }
  846. //
  847. //------------------------------
  848. // Lerp the homogeneous position
  849. //------------------------------
  850. //
  851. if(firstIsIn==true)
  852. {
  853. (*clipExtraCoords)[clipped_index].Lerp(
  854. (*transformedCoords)[k0],
  855. (*transformedCoords)[k1],
  856. a
  857. );
  858. DoClipTrick((*clipExtraCoords)[clipped_index], ct);
  859. Verify((*clipExtraCoords)[clipped_index].x >= 0.0f && (*clipExtraCoords)[clipped_index].x <= (*clipExtraCoords)[clipped_index].w );
  860. Verify((*clipExtraCoords)[clipped_index].y >= 0.0f && (*clipExtraCoords)[clipped_index].y <= (*clipExtraCoords)[clipped_index].w );
  861. Verify((*clipExtraCoords)[clipped_index].z >= 0.0f && (*clipExtraCoords)[clipped_index].z <= (*clipExtraCoords)[clipped_index].w );
  862. //
  863. //-----------------------------------------------------
  864. // If there are texture uv's, we need to lerp them in a
  865. // perspective correct manner
  866. //-----------------------------------------------------
  867. //
  868. (*clipExtraTexCoords)[clipped_index].Lerp
  869. (
  870. texCoords[k0],
  871. texCoords[k1],
  872. a
  873. );
  874. (*clipExtraColors)[clipped_index].Lerp
  875. (
  876. colors[k0],
  877. colors[k1],
  878. a
  879. );
  880. }
  881. else
  882. {
  883. (*clipExtraCoords)[clipped_index].Lerp(
  884. (*transformedCoords)[k1],
  885. (*transformedCoords)[k0],
  886. a
  887. );
  888. DoClipTrick((*clipExtraCoords)[clipped_index], ct);
  889. Verify((*clipExtraCoords)[clipped_index].x >= 0.0f && (*clipExtraCoords)[clipped_index].x <= (*clipExtraCoords)[clipped_index].w );
  890. Verify((*clipExtraCoords)[clipped_index].y >= 0.0f && (*clipExtraCoords)[clipped_index].y <= (*clipExtraCoords)[clipped_index].w );
  891. Verify((*clipExtraCoords)[clipped_index].z >= 0.0f && (*clipExtraCoords)[clipped_index].z <= (*clipExtraCoords)[clipped_index].w );
  892. //
  893. //-----------------------------------------------------
  894. // If there are texture uv's, we need to lerp them in a
  895. // perspective correct manner
  896. //-----------------------------------------------------
  897. //
  898. (*clipExtraTexCoords)[clipped_index].Lerp
  899. (
  900. texCoords[k1],
  901. texCoords[k0],
  902. a
  903. );
  904. (*clipExtraColors)[clipped_index].Lerp
  905. (
  906. colors[k1],
  907. colors[k0],
  908. a
  909. );
  910. }
  911. //
  912. //--------------------------------
  913. // Bump the polygon's vertex count
  914. //--------------------------------
  915. //
  916. numberVerticesPerPolygon++;
  917. }
  918. }
  919. //
  920. //---------------------------------------------------------------
  921. // We have to handle multiple planes. We do this by creating two
  922. // buffers and we switch between them as we clip plane by plane
  923. //---------------------------------------------------------------
  924. //
  925. else
  926. {
  927. #ifdef LAB_ONLY
  928. Set_Statistic(PolysClippedButGOnePlane, PolysClippedButGOnePlane+1);
  929. #endif
  930. ClipData2 srcPolygon, dstPolygon;
  931. int dstBuffer = 1;
  932. srcPolygon.coords = clipBuffer[dstBuffer].coords.GetData();
  933. srcPolygon.texCoords = clipBuffer[dstBuffer].texCoords.GetData();
  934. srcPolygon.colors = clipBuffer[dstBuffer].colors.GetData();
  935. srcPolygon.clipPerVertex = clipBuffer[dstBuffer].clipPerVertex.GetData();
  936. //
  937. //----------------------------------------------------------
  938. // unravel and copy the original data into the source buffer
  939. //----------------------------------------------------------
  940. //
  941. for(k=0;k<stride;k++)
  942. {
  943. srcPolygon.coords[k] = (*transformedCoords)[k];
  944. srcPolygon.texCoords[k] = texCoords[k];
  945. srcPolygon.colors[k] = colors[k];
  946. srcPolygon.clipPerVertex[k] = (*clippingStates)[k];
  947. }
  948. srcPolygon.length = stride;
  949. //
  950. //--------------------------------
  951. // Point to the destination buffer
  952. //--------------------------------
  953. //
  954. dstBuffer = 0;
  955. dstPolygon.coords = clipBuffer[dstBuffer].coords.GetData();
  956. dstPolygon.texCoords = clipBuffer[dstBuffer].texCoords.GetData();
  957. dstPolygon.colors = clipBuffer[dstBuffer].colors.GetData();
  958. dstPolygon.clipPerVertex = clipBuffer[dstBuffer].clipPerVertex.GetData();
  959. dstPolygon.length = 0;
  960. //
  961. //-----------------------------------------------------------
  962. // Spin through each plane that clipped the primitive and use
  963. // it to actually clip the primitive
  964. //-----------------------------------------------------------
  965. //
  966. mask = 1;
  967. MLRClippingState theNewOr(0);
  968. int loop = 4;
  969. do
  970. {
  971. for(l=0; l<MLRClippingState::NextBit; l++)
  972. {
  973. if(theOr.IsClipped(mask))
  974. {
  975. //
  976. //-----------------------------------
  977. // Clip each vertex against the plane
  978. //-----------------------------------
  979. //
  980. for(k=0;k<srcPolygon.length;k++)
  981. {
  982. k1 = (k+1) < srcPolygon.length ? k+1 : 0;
  983. theTest = srcPolygon.clipPerVertex[k];
  984. //
  985. //----------------------------------------------------
  986. // If this vertex is inside the viewing space, copy it
  987. // directly to the clipping buffer
  988. //----------------------------------------------------
  989. //
  990. if(theTest.IsClipped(mask) == 0)
  991. {
  992. firstIsIn = true;
  993. dstPolygon.coords[dstPolygon.length] =
  994. srcPolygon.coords[k];
  995. dstPolygon.clipPerVertex[dstPolygon.length] =
  996. srcPolygon.clipPerVertex[k];
  997. dstPolygon.texCoords[dstPolygon.length] =
  998. srcPolygon.texCoords[k];
  999. dstPolygon.colors[dstPolygon.length] =
  1000. srcPolygon.colors[k];
  1001. dstPolygon.length++;
  1002. //
  1003. //-------------------------------------------------------
  1004. // We don't need to clip this edge if the next vertex is
  1005. // also in the viewing space, so just move on to the next
  1006. // vertex
  1007. //-------------------------------------------------------
  1008. //
  1009. if(srcPolygon.clipPerVertex[k1].IsClipped(mask) == 0)
  1010. {
  1011. continue;
  1012. }
  1013. }
  1014. //
  1015. //---------------------------------------------------------
  1016. // This vertex is outside the viewing space, so if the next
  1017. // vertex is also outside the viewing space, no clipping is
  1018. // needed and we throw this vertex away. Since only one
  1019. // clipping plane is involved, it must be in the same space
  1020. // as the first vertex
  1021. //---------------------------------------------------------
  1022. //
  1023. else
  1024. {
  1025. firstIsIn = false;
  1026. if(srcPolygon.clipPerVertex[k1].IsClipped(mask) != 0)
  1027. {
  1028. Verify(
  1029. srcPolygon.clipPerVertex[k1].IsClipped(mask)
  1030. == srcPolygon.clipPerVertex[k].IsClipped(mask)
  1031. );
  1032. continue;
  1033. }
  1034. }
  1035. //
  1036. //-------------------------------------------
  1037. // Find the clipping interval from bc0 to bc1
  1038. //-------------------------------------------
  1039. //
  1040. if(firstIsIn == true)
  1041. {
  1042. a = GetLerpFactor (l, srcPolygon.coords[k], srcPolygon.coords[k1]);
  1043. Verify(a >= 0.0f && a <= 1.0f);
  1044. //
  1045. //------------------------------
  1046. // Lerp the homogeneous position
  1047. //------------------------------
  1048. //
  1049. dstPolygon.coords[dstPolygon.length].Lerp(
  1050. srcPolygon.coords[k],
  1051. srcPolygon.coords[k1],
  1052. a
  1053. );
  1054. DoClipTrick(dstPolygon.coords[dstPolygon.length], l);
  1055. //
  1056. //-----------------------------------------------------
  1057. // If there are texture uv's, we need to lerp them in a
  1058. // perspective correct manner
  1059. //-----------------------------------------------------
  1060. //
  1061. dstPolygon.texCoords[dstPolygon.length].Lerp
  1062. (
  1063. srcPolygon.texCoords[k],
  1064. srcPolygon.texCoords[k1],
  1065. a
  1066. );
  1067. dstPolygon.colors[dstPolygon.length].Lerp
  1068. (
  1069. srcPolygon.colors[k],
  1070. srcPolygon.colors[k1],
  1071. a
  1072. );
  1073. }
  1074. else
  1075. {
  1076. a = GetLerpFactor (l, srcPolygon.coords[k1], srcPolygon.coords[k]);
  1077. Verify(a >= 0.0f && a <= 1.0f);
  1078. //
  1079. //------------------------------
  1080. // Lerp the homogeneous position
  1081. //------------------------------
  1082. //
  1083. dstPolygon.coords[dstPolygon.length].Lerp(
  1084. srcPolygon.coords[k1],
  1085. srcPolygon.coords[k],
  1086. a
  1087. );
  1088. DoClipTrick(dstPolygon.coords[dstPolygon.length], l);
  1089. //
  1090. //-----------------------------------------------------
  1091. // If there are texture uv's, we need to lerp them in a
  1092. // perspective correct manner
  1093. //-----------------------------------------------------
  1094. //
  1095. dstPolygon.texCoords[dstPolygon.length].Lerp
  1096. (
  1097. srcPolygon.texCoords[k1],
  1098. srcPolygon.texCoords[k],
  1099. a
  1100. );
  1101. dstPolygon.colors[dstPolygon.length].Lerp
  1102. (
  1103. srcPolygon.colors[k1],
  1104. srcPolygon.colors[k],
  1105. a
  1106. );
  1107. }
  1108. //
  1109. //-------------------------------------
  1110. // We have to generate a new clip state
  1111. //-------------------------------------
  1112. //
  1113. dstPolygon.clipPerVertex[dstPolygon.length].Clip4dVertex(&dstPolygon.coords[dstPolygon.length]);
  1114. //
  1115. //----------------------------------
  1116. // Bump the new polygon vertex count
  1117. //----------------------------------
  1118. //
  1119. dstPolygon.length++;
  1120. }
  1121. //
  1122. //-----------------------------------------------
  1123. // Swap source and destination buffer pointers in
  1124. // preparation for the next plane test
  1125. //-----------------------------------------------
  1126. //
  1127. srcPolygon.coords = clipBuffer[dstBuffer].coords.GetData();
  1128. srcPolygon.texCoords = clipBuffer[dstBuffer].texCoords.GetData();
  1129. srcPolygon.colors = clipBuffer[dstBuffer].colors.GetData();
  1130. srcPolygon.clipPerVertex = clipBuffer[dstBuffer].clipPerVertex.GetData();
  1131. srcPolygon.length = dstPolygon.length;
  1132. dstBuffer = !dstBuffer;
  1133. dstPolygon.coords = clipBuffer[dstBuffer].coords.GetData();
  1134. dstPolygon.texCoords = clipBuffer[dstBuffer].texCoords.GetData();
  1135. dstPolygon.colors = clipBuffer[dstBuffer].colors.GetData();
  1136. dstPolygon.clipPerVertex = clipBuffer[dstBuffer].clipPerVertex.GetData();
  1137. dstPolygon.length = 0;
  1138. }
  1139. mask = mask << 1;
  1140. }
  1141. theNewOr = 0;
  1142. for(k=0;k<srcPolygon.length;k++)
  1143. {
  1144. theNewOr |= srcPolygon.clipPerVertex[k];
  1145. }
  1146. theOr == theNewOr;
  1147. loop++;
  1148. } while (theNewOr != 0 && loop--);
  1149. Verify(theNewOr == 0);
  1150. //
  1151. //--------------------------------------------------
  1152. // Move the most recent polygon into the clip buffer
  1153. //--------------------------------------------------
  1154. //
  1155. for(k=0;k<srcPolygon.length;k++)
  1156. {
  1157. (*clipExtraCoords)[k] = srcPolygon.coords[k];
  1158. Verify((*clipExtraCoords)[k].x >= 0.0f && (*clipExtraCoords)[k].x <= (*clipExtraCoords)[k].w );
  1159. Verify((*clipExtraCoords)[k].y >= 0.0f && (*clipExtraCoords)[k].y <= (*clipExtraCoords)[k].w );
  1160. Verify((*clipExtraCoords)[k].z >= 0.0f && (*clipExtraCoords)[k].z <= (*clipExtraCoords)[k].w );
  1161. (*clipExtraTexCoords)[k] = srcPolygon.texCoords[k];
  1162. (*clipExtraColors)[k] = srcPolygon.colors[k];
  1163. }
  1164. numberVerticesPerPolygon = srcPolygon.length;
  1165. }
  1166. // clip
  1167. for(i=1;i<numberVerticesPerPolygon-1;i++)
  1168. {
  1169. Verify((vertexPool->GetLast() + 3 + numGOSVertices) < vertexPool->GetLength());
  1170. GOSCopyTriangleData(
  1171. &gos_vertices[numGOSVertices],
  1172. clipExtraCoords->GetData(),
  1173. clipExtraColors->GetData(),
  1174. clipExtraTexCoords->GetData(),
  1175. 0, i + 1, i
  1176. );
  1177. numGOSVertices+=3;
  1178. }
  1179. }
  1180. }
  1181. }
  1182. break;
  1183. }
  1184. ptr = stream->GetPointer();
  1185. }
  1186. if(numGOSVertices)
  1187. {
  1188. vertexPool->Increase(numGOSVertices);
  1189. SortData *sd = sorter->SetRawData
  1190. (
  1191. gos_vertices,
  1192. numGOSVertices,
  1193. currentState,
  1194. SortData::TriList
  1195. );
  1196. if(currentState.GetDrawNowMode()==MLRState::DrawNowOnMode)
  1197. {
  1198. SortData::DrawFunc drawFunc = sd->Draw[sd->type];
  1199. (sd->*drawFunc)();
  1200. }
  1201. else
  1202. {
  1203. sorter->AddSortRawData(sd);
  1204. }
  1205. }
  1206. }
  1207. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1208. //
  1209. MLRShape*
  1210. MLRLightMap::CreateLightMapShape()
  1211. {
  1212. Check_Object(stream);
  1213. gos_PushCurrentHeap(Heap);
  1214. MLRShape *ret = new MLRShape(20);
  1215. Register_Object(ret);
  1216. MLR_I_C_TMesh *ctmesh = NULL;
  1217. void *ptr, *end = stream->GetPointer();
  1218. MLRClippingState currentClippingState;
  1219. MLRState currentState, masterState;
  1220. unsigned short stride;
  1221. int i;
  1222. Stuff::Point3D *coords = NULL;
  1223. Stuff::RGBAColor color;
  1224. Stuff::RGBAColor *colors = NULL;
  1225. Vector2DScalar *texCoords = NULL;
  1226. int numGOSVertices = 0;
  1227. int msd;
  1228. MemoryStreamData type;
  1229. stream->Rewind();
  1230. ptr = stream->GetPointer();
  1231. while(ptr < end)
  1232. {
  1233. *stream >> msd;
  1234. type = static_cast<MemoryStreamData>(msd);
  1235. switch(msd)
  1236. {
  1237. case Matrix4D:
  1238. // not this time
  1239. *stream >> i;
  1240. break;
  1241. case ClippingState:
  1242. // not this time
  1243. *stream >> i;
  1244. break;
  1245. case MasterRenderState:
  1246. // not this time
  1247. masterState.Load(stream, Current_MLR_Version);
  1248. break;
  1249. case LightMapRenderState:
  1250. {
  1251. MLRState state;
  1252. state.Load(stream, Current_MLR_Version);
  1253. if(numGOSVertices && (state != currentState))
  1254. {
  1255. if(ctmesh!=NULL)
  1256. {
  1257. ctmesh->SetSubprimitiveLengths(NULL, numGOSVertices/3);
  1258. ctmesh->FlashClipCoords(numGOSVertices);
  1259. ctmesh->FlashClipTexCoords(numGOSVertices);
  1260. ctmesh->FlashClipColors(numGOSVertices);
  1261. ctmesh->SetReferenceState(currentState);
  1262. ctmesh->TheIndexer(numGOSVertices);
  1263. ctmesh->FindFacePlanes();
  1264. ret->Add(ctmesh);
  1265. ctmesh->DetachReference();
  1266. ctmesh = NULL;
  1267. }
  1268. }
  1269. currentState = state;
  1270. }
  1271. break;
  1272. case Polygon:
  1273. {
  1274. if(ctmesh == NULL)
  1275. {
  1276. ctmesh = new MLR_I_C_TMesh;
  1277. numGOSVertices = 0;
  1278. }
  1279. *stream >> stride;
  1280. Verify(stride==3);
  1281. *stream >> color;
  1282. #if COLOR_AS_DWORD
  1283. DWORD argb = 0xffffffff;
  1284. argb = GOSCopyColor(&color);
  1285. #endif
  1286. coords = (Stuff::Point3D *)stream->GetPointer();
  1287. stream->AdvancePointer(stride*sizeof(Stuff::Point3D));
  1288. texCoords = (Vector2DScalar *)stream->GetPointer();
  1289. stream->AdvancePointer(stride*sizeof(Vector2DScalar));
  1290. for(i=0;i<stride;i++,numGOSVertices++)
  1291. {
  1292. ctmesh->SetClipCoord(coords[i], numGOSVertices);
  1293. ctmesh->SetClipTexCoord(texCoords[i], numGOSVertices);
  1294. #if COLOR_AS_DWORD
  1295. ctmesh->SetClipColor(argb, numGOSVertices);
  1296. #else
  1297. ctmesh->SetClipColor(color, numGOSVertices);
  1298. #endif
  1299. }
  1300. }
  1301. break;
  1302. case PolygonWithColor:
  1303. {
  1304. if(ctmesh == NULL)
  1305. {
  1306. ctmesh = new MLR_I_C_TMesh;
  1307. numGOSVertices = 0;
  1308. }
  1309. *stream >> stride;
  1310. Verify(stride<=Limits::Max_Number_Vertices_Per_Polygon);
  1311. coords = (Stuff::Point3D *)stream->GetPointer();
  1312. stream->AdvancePointer(stride*sizeof(Stuff::Point3D));
  1313. colors = (Stuff::RGBAColor *)stream->GetPointer();
  1314. stream->AdvancePointer(stride*sizeof(Stuff::RGBAColor));
  1315. texCoords = (Vector2DScalar *)stream->GetPointer();
  1316. stream->AdvancePointer(stride*sizeof(Vector2DScalar));
  1317. for(i=0;i<stride;i++,numGOSVertices++)
  1318. {
  1319. ctmesh->SetClipCoord(coords[i], numGOSVertices);
  1320. ctmesh->SetClipTexCoord(texCoords[i], numGOSVertices);
  1321. #if COLOR_AS_DWORD
  1322. #error not implemented yet
  1323. #else
  1324. ctmesh->SetClipColor(colors[i], numGOSVertices);
  1325. #endif
  1326. }
  1327. }
  1328. break;
  1329. }
  1330. ptr = stream->GetPointer();
  1331. }
  1332. if(ctmesh!=NULL)
  1333. {
  1334. ctmesh->SetSubprimitiveLengths(NULL, numGOSVertices/3);
  1335. ctmesh->FlashClipCoords(numGOSVertices);
  1336. ctmesh->FlashClipTexCoords(numGOSVertices);
  1337. ctmesh->FlashClipColors(numGOSVertices);
  1338. ctmesh->SetReferenceState(currentState);
  1339. ctmesh->TheIndexer(numGOSVertices);
  1340. ctmesh->FindFacePlanes();
  1341. ret->Add(ctmesh);
  1342. ctmesh->DetachReference();
  1343. }
  1344. gos_PopCurrentHeap();
  1345. return ret;
  1346. }