MLRIndexedTriangleCloud.cpp 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014
  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. #if !defined(MLR_MLRINDEXEDTRIANGLECLOUD_HPP)
  9. #include <MLR\MLRIndexedTriangleCloud.hpp>
  10. #endif
  11. extern DWORD gShowClippedPolys;
  12. extern unsigned short *indexOffset; // [MidLevelRenderer::Max_Number_Vertices_Per_Mesh]
  13. //#############################################################################
  14. //#################### MLRIndexedTriangleCloud ##########################
  15. //#############################################################################
  16. DynamicArrayOf<unsigned short>
  17. *MLRIndexedTriangleCloud::clipExtraIndex;
  18. DynamicArrayOf<Vector2DScalar>
  19. *MLRIndexedTriangleCloud::clipExtraTexCoords;
  20. DynamicArrayOf<unsigned char>
  21. *MLRIndexedTriangleCloud::visibleIndexedVertices;
  22. MLRIndexedTriangleCloud::ClassData*
  23. MLRIndexedTriangleCloud::DefaultData = NULL;
  24. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  25. //
  26. void
  27. MLRIndexedTriangleCloud::InitializeClass()
  28. {
  29. Verify(!DefaultData);
  30. Verify(gos_GetCurrentHeap() == StaticHeap);
  31. DefaultData =
  32. new ClassData(
  33. MLRIndexedTriangleCloudClassID,
  34. "MidLevelRenderer::MLRIndexedTriangleCloud",
  35. MLRTriangleCloud::DefaultData
  36. );
  37. Register_Object(DefaultData);
  38. clipExtraIndex = new DynamicArrayOf<unsigned short> (Limits::Max_Number_Vertices_Per_Mesh);
  39. Register_Pointer(clipExtraIndex);
  40. clipExtraTexCoords = new DynamicArrayOf<Vector2DScalar> (Limits::Max_Number_Vertices_Per_Mesh);
  41. Register_Pointer(clipExtraTexCoords);
  42. visibleIndexedVertices = new DynamicArrayOf<unsigned char> (Limits::Max_Number_Vertices_Per_Mesh);
  43. Register_Pointer(visibleIndexedVertices);
  44. }
  45. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  46. //
  47. void
  48. MLRIndexedTriangleCloud::TerminateClass()
  49. {
  50. Unregister_Pointer(clipExtraIndex);
  51. delete clipExtraIndex;
  52. Unregister_Pointer(clipExtraTexCoords);
  53. delete clipExtraTexCoords;
  54. Unregister_Pointer(visibleIndexedVertices);
  55. delete visibleIndexedVertices;
  56. Unregister_Object(DefaultData);
  57. delete DefaultData;
  58. DefaultData = NULL;
  59. }
  60. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  61. //
  62. MLRIndexedTriangleCloud::MLRIndexedTriangleCloud(int nr) :
  63. MLRTriangleCloud(nr)
  64. {
  65. Verify(gos_GetCurrentHeap() == Heap);
  66. usedNrOfPoints = NULL;
  67. Check_Pointer(this);
  68. drawMode = SortData::TriIndexedList;
  69. }
  70. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  71. //
  72. MLRIndexedTriangleCloud::~MLRIndexedTriangleCloud()
  73. {
  74. Check_Object(this);
  75. }
  76. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  77. //
  78. void
  79. MLRIndexedTriangleCloud::SetData
  80. (
  81. const int *tri_count,
  82. const int *point_count,
  83. const unsigned short *index_data,
  84. const Stuff::Point3D *point_data,
  85. const Stuff::RGBAColor *color_data,
  86. const Vector2DScalar *uv_data
  87. )
  88. {
  89. Check_Pointer(this);
  90. usedNrOfTriangles = tri_count;
  91. usedNrOfPoints = point_count;
  92. Verify(*usedNrOfTriangles <= maxNrOf);
  93. index = index_data;
  94. points = point_data;
  95. colors = color_data;
  96. texCoords = uv_data;
  97. }
  98. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  99. //
  100. void
  101. MLRIndexedTriangleCloud::Draw (DrawEffectInformation *dInfo, GOSVertexPool *allVerticesToDraw, MLRSorter *sorter)
  102. {
  103. Check_Object(this);
  104. worldToEffect.Invert(*dInfo->effectToWorld);
  105. Vector4D *v4 = transformedCoords->GetData();
  106. for(int k=0;k<*usedNrOfPoints;k++, v4++)
  107. {
  108. v4->Multiply(points[k], effectToClipMatrix);
  109. (*clipPerVertex)[k].Clip4dVertex(v4);
  110. }
  111. #if 0
  112. Lighting(*shape->worldToShape, dInfo->activeLights, dInfo->nrOfActiveLights);
  113. #endif
  114. if( Clip(dInfo->clippingFlags, allVerticesToDraw) )
  115. {
  116. sorter->AddEffect(this, dInfo->state);
  117. }
  118. }
  119. static MLRClippingState theAnd, theOr, theTest;
  120. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  121. //
  122. int
  123. MLRIndexedTriangleCloud::Clip(MLRClippingState clippingFlags, GOSVertexPool *vt)
  124. {
  125. int myNumberUsedClipVertex, myNumberUsedClipIndex, myNumberUsedClipLength;
  126. myNumberUsedClipVertex = 0;
  127. myNumberUsedClipIndex = 0;
  128. myNumberUsedClipLength = 0;
  129. Verify(*usedNrOfTriangles > 0);
  130. //
  131. //------------------------
  132. // Handle the indexed case
  133. //------------------------
  134. //
  135. memset(visibleIndexedVertices->GetData(), 0, *usedNrOfPoints);
  136. //
  137. //-----------------------------------------------------------------
  138. // Step through each polygon, making sure that we don't try to clip
  139. // backfaced polygons
  140. //-----------------------------------------------------------------
  141. //
  142. int i, j, k, k0, k1, *cs = (int *)clipPerVertex->GetData();
  143. unsigned short l;
  144. int index0, index1, index2, ret = 0;
  145. int mask;
  146. Scalar a = 0.0f;
  147. for(i=0,j=0;i<*usedNrOfTriangles;j+=3,++i)
  148. {
  149. index0 = index[j];
  150. index1 = index[j+1];
  151. index2 = index[j+2];
  152. //
  153. //---------------------------------------------------------------
  154. // Test each vertex of the polygon against the allowed clipping
  155. // planes, and accumulate status for which planes always clip and
  156. // which planes clipped at least once
  157. //---------------------------------------------------------------
  158. //
  159. theAnd = cs[index0];
  160. theAnd &= (cs[index1] & cs[index2]);
  161. theOr |= (cs[index1] | cs[index2]);
  162. theAnd = theOr = 0; //ASSUME NO CLIPPING NEEDED FOR MC2. Its just not done here!
  163. //
  164. //-------------------------------------------------------------------
  165. // If any bit is set for all vertices, then the polygon is completely
  166. // outside the viewing space and we don't have to draw it. On the
  167. // other hand, if no bits at all were ever set, we can do a trivial
  168. // accept of the polygon
  169. //-------------------------------------------------------------------
  170. //
  171. if (theAnd != 0)
  172. {
  173. testList[i] = 0;
  174. #ifdef LAB_ONLY
  175. Set_Statistic(PolysClippedButOutside, PolysClippedButOutside+1);
  176. #endif
  177. }
  178. else if (theOr == 0)
  179. {
  180. testList[i] = 1;
  181. ret++;
  182. (*visibleIndexedVertices)[index0] = 1;
  183. (*visibleIndexedVertices)[index1] = 1;
  184. (*visibleIndexedVertices)[index2] = 1;
  185. #ifdef LAB_ONLY
  186. Set_Statistic(PolysClippedButInside, PolysClippedButInside+1);
  187. #endif
  188. }
  189. //
  190. //-----------------------------------------------------------------
  191. // It is not a trivial case, so we must now do real clipping on the
  192. // polygon
  193. //-----------------------------------------------------------------
  194. //
  195. else
  196. {
  197. unsigned short numberVerticesPerPolygon = 0;
  198. //
  199. //---------------------------------------------------------------
  200. // Handle the case of a single clipping plane by stepping through
  201. // the vertices and finding the edge it originates
  202. //---------------------------------------------------------------
  203. //
  204. bool firstIsIn;
  205. if (theOr.GetNumberOfSetBits() == 1)
  206. {
  207. #ifdef LAB_ONLY
  208. Set_Statistic(PolysClippedButOnePlane, PolysClippedButOnePlane+1);
  209. #endif
  210. for(k=j;k<j+3;k++)
  211. {
  212. k0 = index[k];
  213. k1 = index[(k+1) < j+3 ? k+1 : j];
  214. //
  215. //----------------------------------------------------
  216. // If this vertex is inside the viewing space, copy it
  217. // directly to the clipping buffer
  218. //----------------------------------------------------
  219. //
  220. int clipped_index =
  221. myNumberUsedClipVertex + numberVerticesPerPolygon;
  222. theTest = cs[k0];
  223. if(theTest == 0)
  224. {
  225. firstIsIn = true;
  226. (*clipExtraCoords)[clipped_index] = (*transformedCoords)[k0];
  227. (*clipExtraColors)[clipped_index] = colors[k0];
  228. (*clipExtraTexCoords)[clipped_index] = texCoords[k0];
  229. numberVerticesPerPolygon++;
  230. clipped_index++;
  231. //
  232. //-------------------------------------------------------
  233. // We don't need to clip this edge if the next vertex is
  234. // also in the viewing space, so just move on to the next
  235. // vertex
  236. //-------------------------------------------------------
  237. //
  238. if(cs[k1] == 0)
  239. {
  240. continue;
  241. }
  242. }
  243. //
  244. //---------------------------------------------------------
  245. // This vertex is outside the viewing space, so if the next
  246. // vertex is also outside the viewing space, no clipping is
  247. // needed and we throw this vertex away. Since only one
  248. // clipping plane is involved, it must be in the same space
  249. // as the first vertex
  250. //---------------------------------------------------------
  251. //
  252. else
  253. {
  254. firstIsIn = false;
  255. if(cs[k1] != 0)
  256. {
  257. Verify(cs[k1] == cs[k0]);
  258. continue;
  259. }
  260. }
  261. //
  262. //--------------------------------------------------
  263. // We now find the distance along the edge where the
  264. // clipping plane will intersect
  265. //--------------------------------------------------
  266. //
  267. int ct = 0;
  268. mask = 1;
  269. theTest |= cs[k1];
  270. //
  271. //-----------------------------------------------------
  272. // Find the boundary conditions that match our clipping
  273. // plane
  274. //-----------------------------------------------------
  275. //
  276. for (l=0; l<MLRClippingState::NextBit; l++)
  277. {
  278. if(theTest.IsClipped(mask))
  279. {
  280. // GetDoubleBC(l, bc0, bc1, transformedCoords[k0], transformedCoords[k1]);
  281. //
  282. //-------------------------------------------
  283. // Find the clipping interval from bc0 to bc1
  284. //-------------------------------------------
  285. //
  286. if(firstIsIn==true)
  287. {
  288. a = GetLerpFactor(l, (*transformedCoords)[k0], (*transformedCoords)[k1]);
  289. }
  290. else
  291. {
  292. a = GetLerpFactor(l, (*transformedCoords)[k1], (*transformedCoords)[k0]);
  293. }
  294. Verify(a >= 0.0f && a <= 1.0f);
  295. ct = l;
  296. break;
  297. }
  298. mask <<= 1;
  299. }
  300. //
  301. //------------------------------
  302. // Lerp the homogeneous position
  303. //------------------------------
  304. //
  305. if(firstIsIn==true)
  306. {
  307. (*clipExtraCoords)[clipped_index].Lerp(
  308. (*transformedCoords)[k0],
  309. (*transformedCoords)[k1],
  310. a
  311. );
  312. DoClipTrick((*clipExtraCoords)[clipped_index], ct);
  313. //
  314. //----------------------------------------------------------
  315. // If there are colors, lerp them in screen space for now as
  316. // most cards do that anyway
  317. //----------------------------------------------------------
  318. //
  319. #if COLOR_AS_DWORD
  320. (*clipExtraColors)[clipped_index] = Color_DWORD_Lerp (
  321. colors[k0],
  322. colors[k1],
  323. a
  324. );
  325. #else
  326. (*clipExtraColors)[clipped_index].Lerp(
  327. colors[k0],
  328. colors[k1],
  329. a
  330. );
  331. #endif
  332. //
  333. //-----------------------------------------------------
  334. // If there are texture uv's, we need to lerp them in a
  335. // perspective correct manner
  336. //-----------------------------------------------------
  337. //
  338. (*clipExtraTexCoords)[clipped_index].Lerp
  339. (
  340. texCoords[k0],
  341. texCoords[k1],
  342. a
  343. );
  344. }
  345. else
  346. {
  347. (*clipExtraCoords)[clipped_index].Lerp(
  348. (*transformedCoords)[k1],
  349. (*transformedCoords)[k0],
  350. a
  351. );
  352. DoClipTrick((*clipExtraCoords)[clipped_index], ct);
  353. //
  354. //----------------------------------------------------------
  355. // If there are colors, lerp them in screen space for now as
  356. // most cards do that anyway
  357. //----------------------------------------------------------
  358. //
  359. #if COLOR_AS_DWORD
  360. (*clipExtraColors)[clipped_index] = Color_DWORD_Lerp (
  361. colors[k1],
  362. colors[k0],
  363. a
  364. );
  365. #else
  366. (*clipExtraColors)[clipped_index].Lerp(
  367. colors[k1],
  368. colors[k0],
  369. a
  370. );
  371. #endif
  372. //
  373. //-----------------------------------------------------
  374. // If there are texture uv's, we need to lerp them in a
  375. // perspective correct manner
  376. //-----------------------------------------------------
  377. //
  378. (*clipExtraTexCoords)[clipped_index].Lerp
  379. (
  380. texCoords[k1],
  381. texCoords[k0],
  382. a
  383. );
  384. }
  385. //
  386. //--------------------------------
  387. // Bump the polygon's vertex count
  388. //--------------------------------
  389. //
  390. numberVerticesPerPolygon++;
  391. }
  392. (*clipExtraLength)[myNumberUsedClipLength] = numberVerticesPerPolygon;
  393. #ifdef _ARMOR
  394. (*clipExtraLength)[myNumberUsedClipLength] &= ~0x8000;
  395. #endif
  396. }
  397. //
  398. //---------------------------------------------------------------
  399. // We have to handle multiple planes. We do this by creating two
  400. // buffers and we switch between them as we clip plane by plane
  401. //---------------------------------------------------------------
  402. //
  403. else
  404. {
  405. #ifdef LAB_ONLY
  406. Set_Statistic(PolysClippedButGOnePlane, PolysClippedButGOnePlane+1);
  407. #endif
  408. ClipData2 srcPolygon, dstPolygon;
  409. int dstBuffer = 1;
  410. srcPolygon.coords = clipBuffer[dstBuffer].coords.GetData();
  411. srcPolygon.colors = clipBuffer[dstBuffer].colors.GetData();
  412. srcPolygon.texCoords = clipBuffer[dstBuffer].texCoords.GetData();
  413. srcPolygon.clipPerVertex = clipBuffer[dstBuffer].clipPerVertex.GetData();
  414. //
  415. //----------------------------------------------------------
  416. // unravel and copy the original data into the source buffer
  417. //----------------------------------------------------------
  418. //
  419. for(k=j,l=0;k<j+3;k++,l++)
  420. {
  421. int indexK = index[k];
  422. srcPolygon.coords[l] = (*transformedCoords)[indexK];
  423. srcPolygon.colors[l] = colors[indexK];
  424. srcPolygon.texCoords[l] = texCoords[indexK];
  425. srcPolygon.clipPerVertex[l] = (*clipPerVertex)[indexK];
  426. }
  427. srcPolygon.length = l;
  428. //
  429. //--------------------------------
  430. // Point to the destination buffer
  431. //--------------------------------
  432. //
  433. dstBuffer = 0;
  434. dstPolygon.coords = clipBuffer[dstBuffer].coords.GetData();
  435. dstPolygon.colors = clipBuffer[dstBuffer].colors.GetData();
  436. dstPolygon.texCoords = clipBuffer[dstBuffer].texCoords.GetData();
  437. dstPolygon.clipPerVertex = clipBuffer[dstBuffer].clipPerVertex.GetData();
  438. dstPolygon.length = 0;
  439. //
  440. //-----------------------------------------------------------
  441. // Spin through each plane that clipped the primitive and use
  442. // it to actually clip the primitive
  443. //-----------------------------------------------------------
  444. //
  445. mask = 1;
  446. MLRClippingState theNewOr(0);
  447. int loop = 4;
  448. #if HUNT_CLIP_ERROR
  449. for(k=0;k<srcPolygon.length;k++)
  450. {
  451. DEBUG_STREAM << setiosflags( ios::scientific) << setprecision(20)
  452. << srcPolygon.coords[k].x << " "
  453. << srcPolygon.coords[k].y << " "
  454. << srcPolygon.coords[k].z << " "
  455. << srcPolygon.coords[k].w << '\n';
  456. }
  457. #endif
  458. #if HUNT_CLIP_ERROR
  459. DEBUG_STREAM << "TheOriginalOR: " << hex << theOr.GetClippingState() << dec << '\n';
  460. #endif
  461. do
  462. {
  463. for(l=0; l<MLRClippingState::NextBit; l++)
  464. {
  465. if(theOr.IsClipped(mask))
  466. {
  467. //
  468. //-----------------------------------
  469. // Clip each vertex against the plane
  470. //-----------------------------------
  471. //
  472. #if HUNT_CLIP_ERROR
  473. DEBUG_STREAM << l << ": " << '\n';
  474. #endif
  475. for(k=0;k<srcPolygon.length;k++)
  476. {
  477. k1 = (k+1) < srcPolygon.length ? k+1 : 0;
  478. theTest = srcPolygon.clipPerVertex[k];
  479. //
  480. //----------------------------------------------------
  481. // If this vertex is inside the viewing space, copy it
  482. // directly to the clipping buffer
  483. //----------------------------------------------------
  484. //
  485. if(theTest.IsClipped(mask) == 0)
  486. {
  487. firstIsIn = true;
  488. dstPolygon.coords[dstPolygon.length] =
  489. srcPolygon.coords[k];
  490. #if HUNT_CLIP_ERROR
  491. DEBUG_STREAM << k << " goes " << setiosflags( ios::scientific) << setprecision(20)
  492. << srcPolygon.coords[k].x << " "
  493. << srcPolygon.coords[k].y << " "
  494. << srcPolygon.coords[k].z << " "
  495. << srcPolygon.coords[k].w << '\n';
  496. #endif
  497. dstPolygon.clipPerVertex[dstPolygon.length] =
  498. srcPolygon.clipPerVertex[k];
  499. dstPolygon.colors[dstPolygon.length] =
  500. srcPolygon.colors[k];
  501. dstPolygon.texCoords[dstPolygon.length] =
  502. srcPolygon.texCoords[k];
  503. dstPolygon.length++;
  504. //
  505. //-------------------------------------------------------
  506. // We don't need to clip this edge if the next vertex is
  507. // also in the viewing space, so just move on to the next
  508. // vertex
  509. //-------------------------------------------------------
  510. //
  511. if(srcPolygon.clipPerVertex[k1].IsClipped(mask) == 0)
  512. {
  513. continue;
  514. }
  515. }
  516. //
  517. //---------------------------------------------------------
  518. // This vertex is outside the viewing space, so if the next
  519. // vertex is also outside the viewing space, no clipping is
  520. // needed and we throw this vertex away. Since only one
  521. // clipping plane is involved, it must be in the same space
  522. // as the first vertex
  523. //---------------------------------------------------------
  524. //
  525. else
  526. {
  527. firstIsIn = false;
  528. if(srcPolygon.clipPerVertex[k1].IsClipped(mask) != 0)
  529. {
  530. Verify(
  531. srcPolygon.clipPerVertex[k1].IsClipped(mask)
  532. == srcPolygon.clipPerVertex[k].IsClipped(mask)
  533. );
  534. continue;
  535. }
  536. }
  537. //
  538. //-------------------------------------------
  539. // Find the clipping interval from bc0 to bc1
  540. //-------------------------------------------
  541. //
  542. if(firstIsIn == true)
  543. {
  544. a = GetLerpFactor (l, srcPolygon.coords[k], srcPolygon.coords[k1]);
  545. Verify(a >= 0.0f && a <= 1.0f);
  546. //
  547. //------------------------------
  548. // Lerp the homogeneous position
  549. //------------------------------
  550. //
  551. dstPolygon.coords[dstPolygon.length].Lerp(
  552. srcPolygon.coords[k],
  553. srcPolygon.coords[k1],
  554. a
  555. );
  556. #if HUNT_CLIP_ERROR
  557. DEBUG_STREAM << "True " << a << " " << k << " " << k1 << " we get " << dstPolygon.length << '\n';
  558. DEBUG_STREAM << setiosflags( ios::scientific) << setprecision(20)
  559. << dstPolygon.coords[dstPolygon.length].x << " "
  560. << dstPolygon.coords[dstPolygon.length].y << " "
  561. << dstPolygon.coords[dstPolygon.length].z << " "
  562. << dstPolygon.coords[dstPolygon.length].w << '\n';
  563. #endif
  564. DoClipTrick(dstPolygon.coords[dstPolygon.length], l);
  565. //
  566. //----------------------------------------------------------
  567. // If there are colors, lerp them in screen space for now as
  568. // most cards do that anyway
  569. //----------------------------------------------------------
  570. //
  571. #if COLOR_AS_DWORD
  572. dstPolygon.colors[dstPolygon.length] = Color_DWORD_Lerp(
  573. srcPolygon.colors[k],
  574. srcPolygon.colors[k1],
  575. a
  576. );
  577. #else
  578. dstPolygon.colors[dstPolygon.length].Lerp(
  579. srcPolygon.colors[k],
  580. srcPolygon.colors[k1],
  581. a
  582. );
  583. #endif
  584. //
  585. //-----------------------------------------------------
  586. // If there are texture uv's, we need to lerp them in a
  587. // perspective correct manner
  588. //-----------------------------------------------------
  589. //
  590. dstPolygon.texCoords[dstPolygon.length].Lerp
  591. (
  592. srcPolygon.texCoords[k],
  593. srcPolygon.texCoords[k1],
  594. a
  595. );
  596. }
  597. else
  598. {
  599. a = GetLerpFactor (l, srcPolygon.coords[k1], srcPolygon.coords[k]);
  600. Verify(a >= 0.0f && a <= 1.0f);
  601. //
  602. //------------------------------
  603. // Lerp the homogeneous position
  604. //------------------------------
  605. //
  606. dstPolygon.coords[dstPolygon.length].Lerp(
  607. srcPolygon.coords[k1],
  608. srcPolygon.coords[k],
  609. a
  610. );
  611. #if HUNT_CLIP_ERROR
  612. DEBUG_STREAM << "False " << a << " " << k << " " << k1 << " we get " << dstPolygon.length << '\n';
  613. DEBUG_STREAM << setiosflags( ios::scientific) << setprecision(20)
  614. << dstPolygon.coords[dstPolygon.length].x << " "
  615. << dstPolygon.coords[dstPolygon.length].y << " "
  616. << dstPolygon.coords[dstPolygon.length].z << " "
  617. << dstPolygon.coords[dstPolygon.length].w << '\n';
  618. #endif
  619. DoClipTrick(dstPolygon.coords[dstPolygon.length], l);
  620. //
  621. //----------------------------------------------------------
  622. // If there are colors, lerp them in screen space for now as
  623. // most cards do that anyway
  624. //----------------------------------------------------------
  625. //
  626. #if COLOR_AS_DWORD
  627. dstPolygon.colors[dstPolygon.length] = Color_DWORD_Lerp(
  628. srcPolygon.colors[k1],
  629. srcPolygon.colors[k],
  630. a
  631. );
  632. #else
  633. dstPolygon.colors[dstPolygon.length].Lerp(
  634. srcPolygon.colors[k1],
  635. srcPolygon.colors[k],
  636. a
  637. );
  638. #endif
  639. //
  640. //-----------------------------------------------------
  641. // If there are texture uv's, we need to lerp them in a
  642. // perspective correct manner
  643. //-----------------------------------------------------
  644. //
  645. dstPolygon.texCoords[dstPolygon.length].Lerp
  646. (
  647. srcPolygon.texCoords[k1],
  648. srcPolygon.texCoords[k],
  649. a
  650. );
  651. }
  652. //
  653. //-------------------------------------
  654. // We have to generate a new clip state
  655. //-------------------------------------
  656. //
  657. dstPolygon.clipPerVertex[dstPolygon.length].Clip4dVertex(&dstPolygon.coords[dstPolygon.length]);
  658. //
  659. //----------------------------------
  660. // Bump the new polygon vertex count
  661. //----------------------------------
  662. //
  663. dstPolygon.length++;
  664. }
  665. //
  666. //-----------------------------------------------
  667. // Swap source and destination buffer pointers in
  668. // preparation for the next plane test
  669. //-----------------------------------------------
  670. //
  671. srcPolygon.coords = clipBuffer[dstBuffer].coords.GetData();
  672. srcPolygon.colors = clipBuffer[dstBuffer].colors.GetData();
  673. srcPolygon.texCoords = clipBuffer[dstBuffer].texCoords.GetData();
  674. srcPolygon.clipPerVertex = clipBuffer[dstBuffer].clipPerVertex.GetData();
  675. srcPolygon.length = dstPolygon.length;
  676. dstBuffer = !dstBuffer;
  677. dstPolygon.coords = clipBuffer[dstBuffer].coords.GetData();
  678. dstPolygon.colors = clipBuffer[dstBuffer].colors.GetData();
  679. dstPolygon.texCoords = clipBuffer[dstBuffer].texCoords.GetData();
  680. dstPolygon.clipPerVertex = clipBuffer[dstBuffer].clipPerVertex.GetData();
  681. dstPolygon.length = 0;
  682. }
  683. mask = mask << 1;
  684. }
  685. theNewOr = 0;
  686. for(k=0;k<srcPolygon.length;k++)
  687. {
  688. theNewOr |= srcPolygon.clipPerVertex[k];
  689. }
  690. #if HUNT_CLIP_ERROR
  691. DEBUG_STREAM << "TheOR: " << hex << theNewOr.GetClippingState() << dec << '\n';
  692. #endif
  693. theOr = theNewOr;
  694. } while (theNewOr != 0 && loop--);
  695. //
  696. //--------------------------------------------------
  697. // could not clip this rare case, just ignore it
  698. //--------------------------------------------------
  699. //
  700. if(theNewOr != 0)
  701. {
  702. testList[i] = 0;
  703. continue;
  704. }
  705. //
  706. //--------------------------------------------------
  707. // Move the most recent polygon into the clip buffer
  708. //--------------------------------------------------
  709. //
  710. #if HUNT_CLIP_ERROR
  711. DEBUG_STREAM << "Final: " << srcPolygon.length << '\n';
  712. #endif
  713. for(k=0;k<srcPolygon.length;k++)
  714. {
  715. int clipped_index = myNumberUsedClipVertex + k;
  716. #if HUNT_CLIP_ERROR
  717. DEBUG_STREAM << setiosflags( ios::scientific) << setprecision(20)
  718. << srcPolygon.coords[k].x << " "
  719. << srcPolygon.coords[k].y << " "
  720. << srcPolygon.coords[k].z << " "
  721. << srcPolygon.coords[k].w << '\n';
  722. #endif
  723. (*clipExtraCoords)[clipped_index] = srcPolygon.coords[k];
  724. (*clipExtraColors)[clipped_index] = srcPolygon.colors[k];
  725. (*clipExtraTexCoords)[clipped_index] = srcPolygon.texCoords[k];
  726. }
  727. numberVerticesPerPolygon = srcPolygon.length;
  728. #if HUNT_CLIP_ERROR
  729. DEBUG_STREAM << "---" << '\n';
  730. #endif
  731. (*clipExtraLength)[myNumberUsedClipLength] = numberVerticesPerPolygon;
  732. #ifdef _ARMOR
  733. (*clipExtraLength)[myNumberUsedClipLength] |= 0x8000;
  734. #endif
  735. }
  736. myNumberUsedClipVertex += numberVerticesPerPolygon;
  737. myNumberUsedClipLength++;
  738. ret++;
  739. // clip
  740. // dont draw the original
  741. testList[i] = 0;
  742. }
  743. }
  744. Check_Object(vt);
  745. gos_vertices = vt->GetActualVertexPool();
  746. numGOSVertices = 0;
  747. gos_indices = vt->GetActualIndexPool();
  748. numGOSIndices = 0;
  749. unsigned short strideIndex;
  750. for(j=0,strideIndex=0;j<*usedNrOfPoints;j++)
  751. {
  752. if((*visibleIndexedVertices)[j] == 0)
  753. {
  754. strideIndex++;
  755. }
  756. else
  757. {
  758. indexOffset[j] = static_cast<unsigned short>(j-strideIndex);
  759. GOSCopyData(
  760. &gos_vertices[numGOSVertices],
  761. transformedCoords->GetData(),
  762. colors,
  763. texCoords,
  764. j
  765. );
  766. #ifdef LAB_ONLY
  767. if(gShowClippedPolys)
  768. {
  769. gos_vertices[numGOSVertices].argb = 0xff0000ff;
  770. gos_vertices[numGOSVertices].u = 0.0f;
  771. gos_vertices[numGOSVertices].v = 0.0f;
  772. }
  773. #endif
  774. numGOSVertices++;
  775. }
  776. }
  777. for(i=0,j=0;i<*usedNrOfTriangles;j+=3,++i)
  778. {
  779. if(testList[i] == 0)
  780. {
  781. continue;
  782. }
  783. Verify((vt->GetLastIndex() + 3 + numGOSIndices) < vt->GetLength());
  784. Verify(indexOffset[index[j]] < numGOSVertices);
  785. gos_indices[numGOSIndices] = indexOffset[index[j]];
  786. Verify(indexOffset[index[j+2]] < numGOSVertices);
  787. gos_indices[numGOSIndices+1] = indexOffset[index[j+2]];
  788. Verify(indexOffset[index[j+1]] < numGOSVertices);
  789. gos_indices[numGOSIndices+2] = indexOffset[index[j+1]];
  790. numGOSIndices += 3;
  791. }
  792. unsigned short stride;
  793. if(myNumberUsedClipLength > 0)
  794. {
  795. for(i=0,j=0;i<myNumberUsedClipLength;i++)
  796. {
  797. #ifdef _ARMOR
  798. stride = static_cast<unsigned short>((*clipExtraLength)[i] & 0x7fff);
  799. #else
  800. stride = static_cast<unsigned short>((*clipExtraLength)[i]);
  801. #endif
  802. for(k=1;k<stride-1;k++)
  803. {
  804. Verify((vt->GetLast() + 3 + numGOSVertices) < vt->GetLength());
  805. Verify((vt->GetLastIndex() + 3 + numGOSIndices) < vt->GetLength());
  806. GOSCopyTriangleData(
  807. &gos_vertices[numGOSVertices],
  808. clipExtraCoords->GetData(),
  809. clipExtraColors->GetData(),
  810. clipExtraTexCoords->GetData(),
  811. j, j+k+1, j+k
  812. );
  813. #ifdef LAB_ONLY
  814. if(gShowClippedPolys)
  815. {
  816. if((*clipExtraLength)[i] & 0x8000)
  817. {
  818. gos_vertices[numGOSVertices].argb = 0xffff0000;
  819. gos_vertices[numGOSVertices].u = 0.0f;
  820. gos_vertices[numGOSVertices].v = 0.0f;
  821. gos_vertices[numGOSVertices+1].argb = 0xffff0000;
  822. gos_vertices[numGOSVertices+1].u = 0.0f;
  823. gos_vertices[numGOSVertices+1].v = 0.0f;
  824. gos_vertices[numGOSVertices+2].argb = 0xffff0000;
  825. gos_vertices[numGOSVertices+2].u = 0.0f;
  826. gos_vertices[numGOSVertices+2].v = 0.0f;
  827. }
  828. else
  829. {
  830. gos_vertices[numGOSVertices].argb = 0xffff9999;
  831. gos_vertices[numGOSVertices].u = 0.0f;
  832. gos_vertices[numGOSVertices].v = 0.0f;
  833. gos_vertices[numGOSVertices+1].argb = 0xffff9999;
  834. gos_vertices[numGOSVertices+1].u = 0.0f;
  835. gos_vertices[numGOSVertices+1].v = 0.0f;
  836. gos_vertices[numGOSVertices+2].argb = 0xffff9999;
  837. gos_vertices[numGOSVertices+2].u = 0.0f;
  838. gos_vertices[numGOSVertices+2].v = 0.0f;
  839. }
  840. }
  841. #endif
  842. Verify((vt->GetLastIndex() + 3 + numGOSIndices) < vt->GetLength());
  843. Verify(numGOSIndices%3 == 0);
  844. gos_indices[numGOSIndices] = (unsigned short)numGOSVertices;
  845. gos_indices[numGOSIndices+1] = (unsigned short)(numGOSVertices + 1);
  846. gos_indices[numGOSIndices+2] = (unsigned short)(numGOSVertices + 2);
  847. numGOSVertices += 3;
  848. numGOSIndices += 3;
  849. }
  850. j += stride;
  851. }
  852. #if HUNT_CLIP_ERROR
  853. DEBUG_STREAM << "***" << endl << endl;
  854. #endif
  855. }
  856. vt->Increase(numGOSVertices);
  857. vt->IncreaseIndex(numGOSIndices);
  858. return numGOSIndices;
  859. }
  860. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  861. //
  862. void
  863. MLRIndexedTriangleCloud::TestInstance() const
  864. {
  865. if (usedNrOfTriangles)
  866. {
  867. Check_Pointer(usedNrOfTriangles);
  868. Verify(*usedNrOfTriangles >= 0);
  869. Verify(*usedNrOfTriangles <= maxNrOf);
  870. }
  871. }