MLRPolyMesh.cpp 39 KB

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