MLRIndexedPolyMesh.cpp 44 KB

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