MLR_I_TMesh.cpp 30 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322
  1. //===========================================================================//
  2. // Copyright (C) Microsoft Corporation. All rights reserved. //
  3. //===========================================================================//
  4. #include "MLRHeaders.hpp"
  5. #if defined(TRACE_ENABLED) && defined(MLR_TRACE)
  6. BitTrace *MLR_I_TMesh_Clip;
  7. #endif
  8. extern DWORD gEnableLightMaps;
  9. #define UV_TEST 0
  10. #define SPEW_AWAY 0
  11. //#define TOP_DOWN_ONLY
  12. //#############################################################################
  13. //###### MLRIndexedTriMesh with no color no lighting one texture layer ######
  14. //#############################################################################
  15. MLR_I_TMesh::ClassData*
  16. MLR_I_TMesh::DefaultData = NULL;
  17. extern DynamicArrayOf<Vector2DScalar> *lightMapUVs;
  18. extern DynamicArrayOf<Scalar> *lightMapSqFalloffs;
  19. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  20. //
  21. void
  22. MLR_I_TMesh::InitializeClass()
  23. {
  24. Verify(!DefaultData);
  25. Verify(gos_GetCurrentHeap() == StaticHeap);
  26. DefaultData =
  27. new ClassData(
  28. MLR_I_TMeshClassID,
  29. "MidLevelRenderer::MLR_I_TMesh",
  30. MLRIndexedPrimitiveBase::DefaultData,
  31. (MLRPrimitiveBase::Factory)&Make
  32. );
  33. Register_Object(DefaultData);
  34. #if defined(TRACE_ENABLED) && defined(MLR_TRACE)
  35. MLR_I_TMesh_Clip = new BitTrace("MLR_I_TMesh_Clip");
  36. Register_Object(MLR_I_TMesh_Clip);
  37. #endif
  38. }
  39. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  40. //
  41. void
  42. MLR_I_TMesh::TerminateClass()
  43. {
  44. Unregister_Object(DefaultData);
  45. delete DefaultData;
  46. DefaultData = NULL;
  47. #if defined(TRACE_ENABLED) && defined(MLR_TRACE)
  48. Unregister_Object(MLR_I_TMesh_Clip);
  49. delete MLR_I_TMesh_Clip;
  50. #endif
  51. }
  52. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  53. //
  54. MLR_I_TMesh::MLR_I_TMesh(
  55. ClassData *class_data,
  56. MemoryStream *stream,
  57. int version
  58. ):
  59. MLRIndexedPrimitiveBase(class_data, stream, version)
  60. {
  61. Check_Pointer(this);
  62. Check_Pointer(stream);
  63. Verify(gos_GetCurrentHeap() == Heap);
  64. numOfTriangles = index.GetLength()/3;
  65. facePlanes.SetLength(numOfTriangles);
  66. testList.SetLength(numOfTriangles);
  67. FindFacePlanes();
  68. }
  69. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  70. //
  71. MLR_I_TMesh::MLR_I_TMesh(ClassData *class_data):
  72. MLRIndexedPrimitiveBase(class_data)
  73. {
  74. Check_Pointer(this);
  75. Verify(gos_GetCurrentHeap() == Heap);
  76. drawMode = SortData::TriIndexedList;
  77. }
  78. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  79. //
  80. MLR_I_TMesh::~MLR_I_TMesh()
  81. {
  82. Check_Object(this);
  83. }
  84. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  85. //
  86. MLR_I_TMesh*
  87. MLR_I_TMesh::Make(
  88. MemoryStream *stream,
  89. int version
  90. )
  91. {
  92. Check_Object(stream);
  93. gos_PushCurrentHeap(Heap);
  94. MLR_I_TMesh *mesh = new MLR_I_TMesh(DefaultData, stream, version);
  95. gos_PopCurrentHeap();
  96. return mesh;
  97. }
  98. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  99. //
  100. void
  101. MLR_I_TMesh::Save(MemoryStream *stream)
  102. {
  103. Check_Object(this);
  104. Check_Object(stream);
  105. MLRIndexedPrimitiveBase::Save(stream);
  106. }
  107. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  108. //
  109. void
  110. MLR_I_TMesh::TestInstance() const
  111. {
  112. Verify(IsDerivedFrom(DefaultData));
  113. }
  114. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  115. //
  116. bool
  117. MLR_I_TMesh::Copy(MLR_I_PMesh *pMesh)
  118. {
  119. Check_Object(this);
  120. Check_Object(pMesh);
  121. Verify(gos_GetCurrentHeap() == Heap);
  122. int len;
  123. unsigned short *_index;
  124. Point3D *_coords;
  125. Vector2DScalar *_texCoords;
  126. pMesh->GetCoordData(&_coords, &len);
  127. SetCoordData(_coords, len);
  128. pMesh->GetIndexData(&_index, &len);
  129. SetIndexData(_index, len);
  130. SetSubprimitiveLengths(NULL, pMesh->GetNumPrimitives());
  131. facePlanes.SetLength(GetNumPrimitives());
  132. testList.SetLength(GetNumPrimitives());
  133. FindFacePlanes();
  134. pMesh->GetTexCoordData(&_texCoords, &len);
  135. SetTexCoordData(_texCoords, len);
  136. referenceState = pMesh->GetReferenceState();
  137. visibleIndexedVerticesKey = false;
  138. visibleIndexedVertices.SetLength(coords.GetLength());
  139. return true;
  140. }
  141. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  142. //
  143. void
  144. MLR_I_TMesh::InitializeDrawPrimitive(unsigned char vis, int parameter)
  145. {
  146. MLRIndexedPrimitiveBase::InitializeDrawPrimitive(vis, parameter);
  147. if(parameter & 1)
  148. {
  149. ResetTestList();
  150. }
  151. }
  152. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  153. //
  154. void
  155. MLR_I_TMesh::FindFacePlanes()
  156. {
  157. Check_Object(this);
  158. int i, j, numPrimitives = GetNumPrimitives();
  159. Vector3D v;
  160. Verify(index.GetLength() > 0);
  161. for(i=0,j=0;i<numPrimitives;++i,j+=3)
  162. {
  163. facePlanes[i].BuildPlane(
  164. coords[index[j]],
  165. coords[index[j+1]],
  166. coords[index[j+2]]
  167. );
  168. ;
  169. }
  170. }
  171. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  172. //
  173. int
  174. MLR_I_TMesh::FindBackFace(const Point3D& u)
  175. {
  176. Check_Object(this);
  177. int ret = 0;
  178. unsigned char *iPtr;
  179. Plane *p;
  180. if(numOfTriangles <= 0)
  181. {
  182. visible = 0;
  183. return 0;
  184. }
  185. p = &facePlanes[numOfTriangles-1];
  186. iPtr = &testList[0];
  187. if(state.GetBackFaceMode() == MLRState::BackFaceOffMode)
  188. {
  189. ResetTestList();
  190. ret = 1;
  191. }
  192. else
  193. {
  194. memset(iPtr, 0, numOfTriangles);
  195. for(int i=numOfTriangles-1;i>=0;p--,i--)
  196. {
  197. if(p->GetDistanceTo(u)>= 0.0f)
  198. {
  199. iPtr[i] = (unsigned char)(ret = 1);
  200. }
  201. }
  202. }
  203. visible = (unsigned char)ret;
  204. FindVisibleVertices();
  205. return ret;
  206. }
  207. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  208. //
  209. void
  210. MLR_I_TMesh::ResetTestList()
  211. {
  212. int i, numPrimitives = GetNumPrimitives();
  213. unsigned char *iPtr = &testList[0];
  214. for(i=0;i<numPrimitives;i++,iPtr++)
  215. {
  216. *iPtr = 1;
  217. }
  218. }
  219. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  220. //
  221. int
  222. MLR_I_TMesh::FindVisibleVertices()
  223. {
  224. Check_Object(this);
  225. Verify(index.GetLength() > 0);
  226. int ret, i, j;
  227. DWORD *indices = (DWORD *)index.GetData();
  228. for(i=0,j=0,ret=0;i<(numOfTriangles>>1);++i)
  229. {
  230. if(testList[i<<1] != 0)
  231. {
  232. visibleIndexedVertices[(*(indices+j))&0xffff] = 1;
  233. visibleIndexedVertices[(*(indices+j))>>16] = 1;
  234. visibleIndexedVertices[(*(indices+j+1))&0xffff] = 1;
  235. ret = 1;
  236. }
  237. if(testList[(i<<1)+1] != 0)
  238. {
  239. visibleIndexedVertices[(*(indices+j+1))>>16] = 1;
  240. visibleIndexedVertices[(*(indices+j+2))&0xffff] = 1;
  241. visibleIndexedVertices[(*(indices+j+2))>>16] = 1;
  242. ret = 1;
  243. }
  244. j+=3;
  245. }
  246. if(numOfTriangles&1)
  247. {
  248. if(testList[numOfTriangles-1] != 0)
  249. {
  250. j <<= 1;
  251. visibleIndexedVertices[index[j++]] = 1;
  252. visibleIndexedVertices[index[j++]] = 1;
  253. visibleIndexedVertices[index[j++]] = 1;
  254. ret = 1;
  255. }
  256. }
  257. visibleIndexedVerticesKey = true;
  258. return ret;
  259. }
  260. extern DWORD gEnableTextureSort, gEnableAlphaSort;
  261. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  262. /*
  263. void
  264. MLR_I_TMesh::Transform(Matrix4D *mat)
  265. {
  266. Check_Object(this);
  267. Verify(index.GetLength() > 0);
  268. int i, len = coords.GetLength();
  269. if(visibleIndexedVerticesKey == false)
  270. {
  271. FindVisibleVertices();
  272. }
  273. Stuff::Vector4D *v4d = transformedCoords.GetData();
  274. Stuff::Point3D *p3d = coords.GetData();
  275. MLRClippingState *cs = clipPerVertex.GetData();
  276. unsigned char *viv = visibleIndexedVertices.GetData();
  277. for(i=0;i<len;i++,p3d++,v4d++,cs++,viv++)
  278. {
  279. if(*viv == 0)
  280. {
  281. continue;
  282. }
  283. v4d->Multiply(*p3d, *mat);
  284. #ifdef LAB_ONLY
  285. Statistics::MLR_TransformedVertices++;
  286. #endif
  287. cs->Clip4dVertex(v4d);
  288. //
  289. //--------------------------------------------------------
  290. // I claims all vertices are in. lets check it. who knows
  291. //--------------------------------------------------------
  292. //
  293. #ifdef LAB_ONLY
  294. if( (*cs)==0)
  295. {
  296. #if defined(_ARMOR)
  297. if(ArmorLevel > 3)
  298. {
  299. //
  300. //--------------------------------------------------------
  301. // I claims all vertices are in. lets check it. who knows
  302. //--------------------------------------------------------
  303. //
  304. Verify(v4d->x >= 0.0f && v4d->x <= v4d->w );
  305. Verify(v4d->y >= 0.0f && v4d->y <= v4d->w );
  306. Verify(v4d->z >= 0.0f && v4d->z <= v4d->w );
  307. }
  308. #endif
  309. Statistics::MLR_NonClippedVertices++;
  310. }
  311. else
  312. {
  313. Statistics::MLR_ClippedVertices++;
  314. }
  315. #endif
  316. }
  317. }
  318. */
  319. #undef I_SAY_YES_TO_DUAL_TEXTURES
  320. #undef I_SAY_YES_TO_COLOR
  321. #undef I_SAY_YES_TO_LIGHTING
  322. #define CLASSNAME MLR_I_TMesh
  323. #if defined(TRACE_ENABLED) && defined(MLR_TRACE)
  324. #define SET_MLR_TMESH_CLIP() MLR_I_TMesh_Clip->Set()
  325. #define CLEAR_MLR_TMESH_CLIP() MLR_I_TMesh_Clip->Clear()
  326. #else
  327. #define SET_MLR_TMESH_CLIP()
  328. #define CLEAR_MLR_TMESH_CLIP()
  329. #endif
  330. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  331. // This include contains follwing functions:
  332. // void MLR_I_TMesh::TransformNoClip(Matrix4D*, GOSVertexPool*);
  333. // int MLR_I_TMesh::Clip(MLRClippingState, GOSVertexPool*);
  334. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  335. #include <MLR\MLRTriangleClipping.hpp>
  336. #undef CLASSNAME
  337. //---------------------------------------------------------------------------
  338. //
  339. void
  340. MLR_I_TMesh::Lighting(MLRLight* const* lights, int nrLights)
  341. {
  342. int i;
  343. MLRLightMap *lightMap;
  344. for(i=0;i<nrLights;i++)
  345. {
  346. lightMap = lights[i]->GetLightMap();
  347. if(lightMap!=NULL)
  348. {
  349. Start_Timer(LightMap_Light_Time);
  350. LightMapLighting(lights[i]);
  351. Stop_Timer(LightMap_Light_Time);
  352. }
  353. }
  354. }
  355. extern RGBAColor errorColor;
  356. extern bool
  357. CheckForBigTriangles(DynamicArrayOf<Vector2DScalar> *lightMapUVs, int stride);
  358. //---------------------------------------------------------------------------
  359. //
  360. void
  361. MLR_I_TMesh::LightMapLighting(MLRLight *light)
  362. {
  363. int i, j, k, len = numOfTriangles;
  364. LinearMatrix4D matrix = LinearMatrix4D::Identity;
  365. Point3D lightPosInShape, hitPoint;
  366. UnitVector3D up, left, forward;
  367. bool lm;
  368. Scalar f, rhf, falloff = 1.0f, distance;
  369. MLRLightMap *lightMap = light->GetLightMap();
  370. if( (!lightMap) || (!gEnableLightMaps) )
  371. {
  372. return;
  373. }
  374. Scalar bigUV = MLRState::GetMaxUV();
  375. int tooBig = 0;
  376. switch(light->GetLightType())
  377. {
  378. case MLRLight::PointLight:
  379. {
  380. Check_Object(lightMap);
  381. lightMap->AddState(referenceState.GetPriority()+1);
  382. light->GetInShapePosition(lightPosInShape);
  383. for(i=0,j=0,k=0;i<len;i++,j += 3)
  384. {
  385. if(testList[i] == 0)
  386. {
  387. continue;
  388. }
  389. f = facePlanes[i].GetDistanceTo(lightPosInShape);
  390. lm = false;
  391. if(f>0.0f && Cast_Object(MLRInfiniteLightWithFalloff*, light)->GetFalloff(f, falloff) == true)
  392. {
  393. rhf = 1.0f/f;
  394. matrix = LinearMatrix4D::Identity;
  395. matrix.AlignLocalAxisToWorldVector(facePlanes[i].normal, Z_Axis, X_Axis, Y_Axis);
  396. matrix.GetLocalLeftInWorld(&left);
  397. matrix.GetLocalUpInWorld(&up);
  398. matrix.GetLocalForwardInWorld(&forward);
  399. Verify(Small_Enough(up*left));
  400. #if defined(_ARMOR)
  401. Scalar diff = forward*left;
  402. Verify(Small_Enough(diff));
  403. diff = up*forward;
  404. Verify(Small_Enough(diff));
  405. #endif
  406. Check_Object(&forward);
  407. hitPoint.Multiply(forward, -f);
  408. hitPoint+=lightPosInShape;
  409. tooBig = 0;
  410. for(k=0;k<3;k++)
  411. {
  412. Vector3D vec(coords[index[k+j]]);
  413. vec-=hitPoint;
  414. (*lightMapUVs)[k][0] = -(left*vec)*rhf;
  415. (*lightMapUVs)[k][1] = -(up*vec)*rhf;
  416. if(
  417. (*lightMapUVs)[k][0] >= -0.5f && (*lightMapUVs)[k][0] <= 0.5f &&
  418. (*lightMapUVs)[k][1] >= -0.5f && (*lightMapUVs)[k][1] <= 0.5f
  419. )
  420. {
  421. lm = true;
  422. }
  423. if(
  424. (*lightMapUVs)[k][0] < -bigUV || (*lightMapUVs)[k][0] > bigUV ||
  425. (*lightMapUVs)[k][1] < -bigUV || (*lightMapUVs)[k][1] > bigUV
  426. )
  427. {
  428. tooBig++;
  429. }
  430. }
  431. }
  432. else
  433. {
  434. continue;
  435. }
  436. if(tooBig==0 && (lm == true || CheckForBigTriangles(lightMapUVs, 3) == true))
  437. {
  438. lightMap->SetPolygonMarker(0);
  439. lightMap->AddUShort(3);
  440. #if 0
  441. Vector3D vec(coords[index[j]]);
  442. SPEW(("micgaert", "\nvertex1 = %f,%f,%f", vec.x, vec.y, vec.z));
  443. vec = coords[index[j+1]];
  444. SPEW(("micgaert", "vertex2 = %f,%f,%f", vec.x, vec.y, vec.z));
  445. vec = coords[index[j+2]];
  446. SPEW(("micgaert", "vertex3 = %f,%f,%f", vec.x, vec.y, vec.z));
  447. vec = facePlanes[i].normal;
  448. SPEW(("micgaert", "normal = %f,%f,%f", vec.x, vec.y, vec.z));
  449. SPEW(("micgaert", "forward = %f,%f,%f", forward.x, forward.y, forward.z));
  450. SPEW(("micgaert", "distance = %f", f));
  451. SPEW(("micgaert", "light = %f,%f,%f", lightPosInShape.x, lightPosInShape.y, lightPosInShape.z));
  452. SPEW(("micgaert", "projection = %f,%f,%f", hitPoint.x, hitPoint.y, hitPoint.z));
  453. #endif
  454. Scalar sq_falloff
  455. = falloff*falloff*light->GetIntensity();
  456. RGBAColor color(sq_falloff, sq_falloff, sq_falloff, 1.0f);
  457. lightMap->AddColor(color);
  458. for(k=0;k<3;k++)
  459. {
  460. lightMap->AddCoord(coords[index[k+j]]);
  461. }
  462. for(k=0;k<3;k++)
  463. {
  464. lightMap->AddUVs((*lightMapUVs)[k][0]+0.5f, (*lightMapUVs)[k][1]+0.5f);
  465. // DEBUG_STREAM << k << " " << lightMapUVs[k][0] << " " << lightMapUVs[k][0] << "\n";
  466. }
  467. }
  468. }
  469. }
  470. break;
  471. case MLRLight::SpotLight:
  472. {
  473. int behindCount = 0, falloffCount = 0;
  474. Check_Object(lightMap);
  475. lightMap->AddState(referenceState.GetPriority()+1);
  476. light->GetInShapePosition(matrix);
  477. lightPosInShape = matrix;
  478. Scalar tanSpeadAngle = Cast_Object(MLRSpotLight*, light)->GetTanSpreadAngle();
  479. #ifndef TOP_DOWN_ONLY
  480. matrix.GetLocalLeftInWorld(&left);
  481. matrix.GetLocalUpInWorld(&up);
  482. matrix.GetLocalForwardInWorld(&forward);
  483. #else
  484. forward = UnitVector3D(0.0f, -1.0f, 0.0);
  485. up = UnitVector3D(1.0f, 0.0f, 0.0);
  486. left = UnitVector3D(0.0f, 0.0f, 1.0);
  487. #endif
  488. Verify(Small_Enough(up*left));
  489. for(i=0,j=0,k=0;i<len;i++,j += 3)
  490. {
  491. behindCount = 0;
  492. falloffCount = 0;
  493. if(testList[i] == 0)
  494. {
  495. continue;
  496. }
  497. lm = false;
  498. if(!facePlanes[i].IsSeenBy(lightPosInShape))
  499. {
  500. continue;
  501. }
  502. #if SPEW_AWAY
  503. Scalar maxX, maxZ;
  504. Scalar minX, minZ;
  505. minX = maxX = coords[index[j]].x;
  506. minZ = maxZ = coords[index[j]].z;
  507. if(minX>coords[index[j+1]].x)
  508. {
  509. minX = coords[index[j+1]].x;
  510. }
  511. if(minX>coords[index[j+2]].x)
  512. {
  513. minX = coords[index[j+2]].x;
  514. }
  515. if(minZ>coords[index[j+1]].z)
  516. {
  517. minZ = coords[index[j+1]].z;
  518. }
  519. if(minX>coords[index[j+2]].z)
  520. {
  521. minZ = coords[index[j+2]].z;
  522. }
  523. if(maxX<coords[index[j+1]].x)
  524. {
  525. maxX = coords[index[j+1]].x;
  526. }
  527. if(maxX<coords[index[j+2]].x)
  528. {
  529. maxX = coords[index[j+2]].x;
  530. }
  531. if(maxZ<coords[index[j+1]].z)
  532. {
  533. maxZ = coords[index[j+1]].z;
  534. }
  535. if(maxX<coords[index[j+2]].z)
  536. {
  537. maxZ = coords[index[j+2]].z;
  538. }
  539. if(lightPosInShape.x > minX && lightPosInShape.x < maxX && lightPosInShape.z > minZ && lightPosInShape.z < maxZ)
  540. {
  541. SPEW(("micgaert", "On Target !!"));
  542. }
  543. #endif
  544. tooBig = 0;
  545. for(k=0;k<3;k++)
  546. {
  547. Vector3D vec;
  548. Scalar oneOver;
  549. vec.Subtract(coords[index[k+j]], lightPosInShape);
  550. #ifndef TOP_DOWN_ONLY
  551. distance = (vec*forward);
  552. #else
  553. distance = -vec.y;
  554. #endif
  555. #if SPEW_AWAY
  556. SPEW(("micgaert", "vertex%d = %f,%f,%f", k, coords[index[k+j]].x, coords[index[k+j]].y, coords[index[k+j]].z));
  557. SPEW(("micgaert", "distance = %f", distance));
  558. #endif
  559. if(distance > SMALL)
  560. {
  561. if(Cast_Object(MLRInfiniteLightWithFalloff*, light)->GetFalloff(distance, falloff) == false)
  562. {
  563. falloffCount++;
  564. }
  565. (*lightMapSqFalloffs)[k] = falloff*falloff*light->GetIntensity();
  566. oneOver
  567. #if 0
  568. = 1.0f/(2.0f*distance*tanSpeadAngle);
  569. #else
  570. = OneOverApproximate(2.0f*distance*tanSpeadAngle);
  571. #endif
  572. }
  573. else
  574. {
  575. behindCount++;
  576. oneOver = 1.0f/50.0f;
  577. (*lightMapSqFalloffs)[k] = 0.0f;
  578. #if SPEW_AWAY
  579. SPEW(("micgaert", "Behind"));
  580. #endif
  581. }
  582. #ifndef TOP_DOWN_ONLY
  583. (*lightMapUVs)[k][0] = (left*vec) * oneOver;
  584. (*lightMapUVs)[k][1] = -(up*vec) * oneOver;
  585. #else
  586. (*lightMapUVs)[k][0] = vec.x * oneOver;
  587. (*lightMapUVs)[k][1] = -vec.z * oneOver;
  588. #endif
  589. #if SPEW_AWAY
  590. SPEW(("micgaert", "uv%d = %f,%f", k, (*lightMapUVs)[k][0], (*lightMapUVs)[k][1]));
  591. #endif
  592. if(
  593. (*lightMapUVs)[k][0] >= -0.5f && (*lightMapUVs)[k][0] <= 0.5f &&
  594. (*lightMapUVs)[k][1] >= -0.5f && (*lightMapUVs)[k][1] <= 0.5f
  595. )
  596. {
  597. lm = true;
  598. }
  599. if(
  600. (*lightMapUVs)[k][0] < -bigUV || (*lightMapUVs)[k][0] > bigUV ||
  601. (*lightMapUVs)[k][1] < -bigUV || (*lightMapUVs)[k][1] > bigUV
  602. )
  603. {
  604. tooBig++;
  605. }
  606. }
  607. #if 1
  608. if(
  609. tooBig == 0
  610. && behindCount < 3
  611. && falloffCount < 3
  612. && ((lm == true) || CheckForBigTriangles(lightMapUVs, 3) == true)
  613. )
  614. {
  615. lightMap->SetPolygonMarker(1);
  616. lightMap->AddUShort(3);
  617. for(k=0;k<3;k++)
  618. {
  619. lightMap->AddCoord(coords[index[k+j]]);
  620. }
  621. for(k=0;k<3;k++)
  622. {
  623. lightMap->AddColor((*lightMapSqFalloffs)[k], (*lightMapSqFalloffs)[k], (*lightMapSqFalloffs)[k], 1.0f);
  624. }
  625. for(k=0;k<3;k++)
  626. {
  627. lightMap->AddUVs((*lightMapUVs)[k][0]+0.5f, (*lightMapUVs)[k][1]+0.5f);
  628. // DEBUG_STREAM << k << " " << lightMapUVs[k][0] << " " << lightMapUVs[k][0] << "\n";
  629. }
  630. #if SPEW_AWAY
  631. SPEW(("micgaert", "See the Light !"));
  632. #endif
  633. }
  634. #if SPEW_AWAY
  635. Vector3D vec = facePlanes[i].normal;
  636. SPEW(("micgaert", "normal = %f,%f,%f", vec.x, vec.y, vec.z));
  637. SPEW(("micgaert", "forward = %f,%f,%f", forward.x, forward.y, forward.z));
  638. SPEW(("micgaert", "left = %f,%f,%f", left.x, left.y, left.z));
  639. SPEW(("micgaert", "up = %f,%f,%f", up.x, up.y, up.z));
  640. SPEW(("micgaert", "light = %f,%f,%f\n", lightPosInShape.x, lightPosInShape.y, lightPosInShape.z));
  641. #endif
  642. #else
  643. if(tooBig != 0)
  644. {
  645. lightMap->SetPolygonMarker(1);
  646. lightMap->AddUShort(3);
  647. for(k=0;k<3;k++)
  648. {
  649. lightMap->AddCoord(coords[index[k+j]]);
  650. }
  651. for(k=0;k<3;k++)
  652. {
  653. lightMap->AddColor(RGBAColor(0.0f, 0.0f, 0.5f, 1.0f));
  654. }
  655. for(k=0;k<3;k++)
  656. {
  657. lightMap->AddUVs(0.5f, 0.5f);
  658. // DEBUG_STREAM << k << " " << lightMapUVs[k][0] << " " << lightMapUVs[k][0] << "\n";
  659. }
  660. }
  661. else if(behindCount != 0)
  662. {
  663. lightMap->SetPolygonMarker(1);
  664. lightMap->AddUShort(3);
  665. for(k=0;k<3;k++)
  666. {
  667. lightMap->AddCoord(coords[index[k+j]]);
  668. }
  669. for(k=0;k<3;k++)
  670. {
  671. lightMap->AddColor(RGBAColor(0.5f, 0.0f, 0.0f, 1.0f));
  672. }
  673. for(k=0;k<3;k++)
  674. {
  675. lightMap->AddUVs(0.5f, 0.5f);
  676. // DEBUG_STREAM << k << " " << lightMapUVs[k][0] << " " << lightMapUVs[k][0] << "\n";
  677. }
  678. }
  679. else if(behindCount == 0 && (lm == true || CheckForBigTriangles(&lightMapUVs, 3) == true) )
  680. {
  681. lightMap->SetPolygonMarker(1);
  682. lightMap->AddUShort(3);
  683. for(k=0;k<3;k++)
  684. {
  685. lightMap->AddCoord(coords[index[k+j]]);
  686. }
  687. for(k=0;k<3;k++)
  688. {
  689. lightMap->AddColor(lightMapSqFalloffs[k], lightMapSqFalloffs[k], lightMapSqFalloffs[k], 1.0f);
  690. }
  691. for(k=0;k<3;k++)
  692. {
  693. lightMap->AddUVs(lightMapUVs[k][0]+0.5f, lightMapUVs[k][1]+0.5f);
  694. // DEBUG_STREAM << k << " " << lightMapUVs[k][0] << " " << lightMapUVs[k][0] << "\n";
  695. }
  696. }
  697. else if(CheckForBigTriangles(&lightMapUVs, 3) == false)
  698. {
  699. lightMap->SetPolygonMarker(1);
  700. lightMap->AddUShort(3);
  701. for(k=0;k<3;k++)
  702. {
  703. lightMap->AddCoord(coords[index[k+j]]);
  704. }
  705. for(k=0;k<3;k++)
  706. {
  707. lightMap->AddColor(errorColor);
  708. }
  709. for(k=0;k<3;k++)
  710. {
  711. lightMap->AddUVs(0.5f, 0.5f);
  712. // DEBUG_STREAM << k << " " << lightMapUVs[k][0] << " " << lightMapUVs[k][0] << "\n";
  713. }
  714. }
  715. #endif
  716. }
  717. }
  718. break;
  719. default:
  720. STOP(("MLR_I_PMesh::LightMapLighting: What you want me to do ?"));
  721. break;
  722. }
  723. }
  724. //---------------------------------------------------------------------------
  725. //
  726. bool
  727. MLR_I_TMesh::CastRay(
  728. Line3D *line,
  729. Normal3D *normal
  730. )
  731. {
  732. Check_Object(this);
  733. Check_Object(line);
  734. Check_Pointer(normal);
  735. //
  736. //---------------------------------------------------------------------
  737. // We have to spin through each of the polygons stored in the shape and
  738. // collide the ray against each
  739. //---------------------------------------------------------------------
  740. //
  741. int poly_start = 0;
  742. bool hit = false;
  743. for (int polygon=0; polygon<numOfTriangles; poly_start += 3,++polygon)
  744. {
  745. //
  746. //---------------------------------
  747. // See if the line misses the plane
  748. //---------------------------------
  749. //
  750. Scalar product;
  751. const Plane *plane = &facePlanes[polygon];
  752. Check_Object(plane);
  753. Scalar distance = line->GetDistanceTo(*plane, &product);
  754. if (distance < 0.0f || distance > line->length)
  755. {
  756. continue;
  757. }
  758. bool negate = false;
  759. if (product > -SMALL)
  760. {
  761. if (GetCurrentState().GetBackFaceMode() == MLRState::BackFaceOnMode)
  762. {
  763. continue;
  764. }
  765. negate = true;
  766. }
  767. //
  768. //-------------------------------------------
  769. // Figure out where on the plane the line hit
  770. //-------------------------------------------
  771. //
  772. Point3D impact;
  773. line->Project(distance, &impact);
  774. //
  775. //-------------------------------------------------------------------
  776. // We now need to find out which cardinal plane we should project the
  777. // triangle onto
  778. //-------------------------------------------------------------------
  779. //
  780. int s,t;
  781. Scalar nx = Abs(plane->normal.x);
  782. Scalar ny = Abs(plane->normal.y);
  783. Scalar nz = Abs(plane->normal.z);
  784. if (nx > ny)
  785. {
  786. if (nx > nz)
  787. {
  788. s = Y_Axis;
  789. t = Z_Axis;
  790. }
  791. else
  792. {
  793. s = X_Axis;
  794. t = Y_Axis;
  795. }
  796. }
  797. else if (ny > nz)
  798. {
  799. s = Z_Axis;
  800. t = X_Axis;
  801. }
  802. else
  803. {
  804. s = X_Axis;
  805. t = Y_Axis;
  806. }
  807. //
  808. //----------------------------------------
  809. // Initialize the vertex and leg variables
  810. //----------------------------------------
  811. //
  812. Point3D *v1, *v2, *v3;
  813. v1 = &coords[index[poly_start]];
  814. v2 = &coords[index[poly_start+1]];
  815. v3 = &coords[index[poly_start+2]];
  816. //
  817. //---------------------------------------
  818. // Get the projection of the impact point
  819. //---------------------------------------
  820. //
  821. Scalar s0 = impact[s] - (*v1)[s];
  822. Scalar t0 = impact[t] - (*v1)[t];
  823. Scalar s1 = (*v2)[s] - (*v1)[s];
  824. Scalar t1 = (*v2)[t] - (*v1)[t];
  825. //
  826. //------------------------------------------------------------
  827. // For each triangle, figure out what the second leg should be
  828. //------------------------------------------------------------
  829. //
  830. bool local_hit = false;
  831. Check_Pointer(v3);
  832. Scalar s2 = (*v3)[s] - (*v1)[s];
  833. Scalar t2 = (*v3)[t] - (*v1)[t];
  834. //
  835. //--------------------------------
  836. // Now, see if we hit the triangle
  837. //--------------------------------
  838. //
  839. if (Small_Enough(s1))
  840. {
  841. Verify(!Small_Enough(s2));
  842. Scalar beta = s0 / s2;
  843. if (beta >= 0.0f && beta < 1.0f)
  844. {
  845. Verify(!Small_Enough(t1));
  846. Scalar alpha = (t0 - beta*t2) / t1;
  847. local_hit = (alpha >= 0.0f && alpha+beta <= 1.0f);
  848. }
  849. }
  850. else
  851. {
  852. Scalar beta = (t0*s1 - s0*t1);
  853. Scalar alpha = (t2*s1 - s2*t1);
  854. beta /= alpha;
  855. if (beta >= 0.0f && beta <= 1.0f)
  856. {
  857. alpha = (s0 - beta*s2) / s1;
  858. local_hit = (alpha >= 0.0f && alpha+beta <= 1.0f);
  859. }
  860. }
  861. //
  862. //
  863. //----------------------------------------------------
  864. // Handle the hit status, and move to the next polygon
  865. //----------------------------------------------------
  866. //
  867. if (local_hit)
  868. {
  869. hit = true;
  870. line->length = distance;
  871. if (negate)
  872. normal->Negate(plane->normal);
  873. else
  874. *normal = plane->normal;
  875. Verify(*normal * line->direction <= -SMALL);
  876. }
  877. }
  878. //
  879. //----------------------
  880. // Return the hit status
  881. //----------------------
  882. //
  883. return hit;
  884. }
  885. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  886. //
  887. MLR_I_TMesh*
  888. MidLevelRenderer::CreateIndexedTriCube_NoColor_NoLit(
  889. Scalar half,
  890. MLRState *state
  891. )
  892. {
  893. #if 0
  894. gos_PushCurrentHeap(Heap);
  895. MLR_I_TMesh *ret = new MLR_I_TMesh();
  896. Register_Object(ret);
  897. Point3D *coords = new Point3D [8];
  898. Register_Object(coords);
  899. coords[0] = Point3D( half, -half, half);
  900. coords[1] = Point3D(-half, -half, half);
  901. coords[2] = Point3D( half, -half, -half);
  902. coords[3] = Point3D(-half, -half, -half);
  903. coords[4] = Point3D(-half, half, half);
  904. coords[5] = Point3D( half, half, half);
  905. coords[6] = Point3D( half, half, -half);
  906. coords[7] = Point3D(-half, half, -half);
  907. unsigned char *lengths = new unsigned char [6];
  908. Register_Pointer(lengths);
  909. int i;
  910. for(i=0;i<6;i++)
  911. {
  912. lengths[i] = 4;
  913. }
  914. ret->SetSubprimitiveLengths(lengths, 6);
  915. ret->SetCoordData(coords, 8);
  916. unsigned short *index = new unsigned short [6*4];
  917. Register_Pointer(index);
  918. index[0] = 0;
  919. index[1] = 2;
  920. index[2] = 6;
  921. index[3] = 5;
  922. index[4] = 0;
  923. index[5] = 5;
  924. index[6] = 4;
  925. index[7] = 1;
  926. index[8] = 5;
  927. index[9] = 6;
  928. index[10] = 7;
  929. index[11] = 4;
  930. index[12] = 2;
  931. index[13] = 3;
  932. index[14] = 7;
  933. index[15] = 6;
  934. index[16] = 1;
  935. index[17] = 4;
  936. index[18] = 7;
  937. index[19] = 3;
  938. index[20] = 0;
  939. index[21] = 1;
  940. index[22] = 3;
  941. index[23] = 2;
  942. ret->SetIndexData(index, 6*4);
  943. ret->FindFacePlanes();
  944. Vector2DScalar *texCoords = new Vector2DScalar[8];
  945. Register_Object(texCoords);
  946. texCoords[0] = Vector2DScalar(0.0f, 0.0f);
  947. texCoords[1] = Vector2DScalar(0.0f, 0.0f);
  948. texCoords[2] = Vector2DScalar(0.0f, 0.0f);
  949. texCoords[3] = Vector2DScalar(0.0f, 0.0f);
  950. texCoords[4] = Vector2DScalar(0.0f, 0.0f);
  951. texCoords[5] = Vector2DScalar(0.0f, 0.0f);
  952. texCoords[6] = Vector2DScalar(0.0f, 0.0f);
  953. texCoords[7] = Vector2DScalar(0.0f, 0.0f);
  954. if(state != NULL)
  955. {
  956. ret->SetReferenceState(*state);
  957. if(state->GetTextureHandle() > 0)
  958. {
  959. texCoords[0] = Vector2DScalar(0.0f, 0.0f);
  960. texCoords[1] = Vector2DScalar(1.0f, 0.0f);
  961. texCoords[2] = Vector2DScalar(0.25f, 0.25f);
  962. texCoords[3] = Vector2DScalar(0.75f, 0.25f);
  963. texCoords[4] = Vector2DScalar(1.0f, 1.0f);
  964. texCoords[5] = Vector2DScalar(0.0f, 1.0f);
  965. texCoords[6] = Vector2DScalar(0.25f, 0.75f);
  966. texCoords[7] = Vector2DScalar(0.75f, 0.75f);
  967. }
  968. }
  969. ret->SetTexCoordData(texCoords, 8);
  970. Unregister_Object(texCoords);
  971. delete [] texCoords;
  972. Unregister_Pointer(index);
  973. delete [] index;
  974. Unregister_Pointer(lengths);
  975. delete [] lengths;
  976. Unregister_Object(coords);
  977. delete [] coords;
  978. gos_PopCurrentHeap();
  979. return ret;
  980. #endif
  981. return NULL;
  982. }
  983. //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  984. //
  985. MLRShape*
  986. MidLevelRenderer::CreateIndexedTriIcosahedron_NoColor_NoLit(
  987. IcoInfo& icoInfo,
  988. MLRState *state
  989. )
  990. {
  991. gos_PushCurrentHeap(Heap);
  992. MLRShape *ret = new MLRShape(20);
  993. Register_Object(ret);
  994. int i, j, k;
  995. long nrTri = (long) ceil (icoInfo.all * pow (4.0f, icoInfo.depth));
  996. Point3D v[3];
  997. if(3*nrTri >= Limits::Max_Number_Vertices_Per_Mesh)
  998. {
  999. nrTri = Limits::Max_Number_Vertices_Per_Mesh/3;
  1000. }
  1001. Point3D *coords = new Point3D [nrTri*3];
  1002. Register_Pointer(coords);
  1003. Point3D *collapsedCoords = NULL;
  1004. if(icoInfo.indexed==true)
  1005. {
  1006. collapsedCoords = new Point3D [nrTri*3];
  1007. Register_Pointer(collapsedCoords);
  1008. }
  1009. unsigned short *index = new unsigned short [nrTri*3];
  1010. Register_Pointer(index);
  1011. Vector2DScalar *texCoords = new Vector2DScalar[nrTri*3];
  1012. Register_Pointer(texCoords);
  1013. int uniquePoints = 0;
  1014. for (k=0;k<20;k++)
  1015. {
  1016. triDrawn = 0;
  1017. MLR_I_TMesh *mesh = new MLR_I_TMesh();
  1018. Register_Object(mesh);
  1019. // setup vertex position information
  1020. for (j=0;j<3;j++)
  1021. {
  1022. v[j].x = vdata[tindices[k][j]][0];
  1023. v[j].y = vdata[tindices[k][j]][1];
  1024. v[j].z = vdata[tindices[k][j]][2];
  1025. }
  1026. subdivide (coords, v[0], v[1], v[2], icoInfo.depth, nrTri, icoInfo.radius);
  1027. mesh->SetSubprimitiveLengths(NULL, nrTri);
  1028. if(icoInfo.indexed==true)
  1029. {
  1030. uniquePoints = 1;
  1031. collapsedCoords[0] = coords[0];
  1032. index[0] = 0;
  1033. for(i=1;i<nrTri*3;i++)
  1034. {
  1035. for(j=0;j<uniquePoints;j++)
  1036. {
  1037. if(coords[i] == collapsedCoords[j])
  1038. {
  1039. break;
  1040. }
  1041. }
  1042. if(j==uniquePoints)
  1043. {
  1044. collapsedCoords[uniquePoints++] = coords[i];
  1045. }
  1046. index[i] = static_cast<unsigned short>(j);
  1047. }
  1048. mesh->SetCoordData(collapsedCoords, uniquePoints);
  1049. }
  1050. else
  1051. {
  1052. uniquePoints = nrTri*3;
  1053. for(i=0;i<nrTri*3;i++)
  1054. {
  1055. index[i] = static_cast<unsigned short>(i);
  1056. }
  1057. mesh->SetCoordData(coords, nrTri*3);
  1058. }
  1059. mesh->SetIndexData(index, nrTri*3);
  1060. mesh->FindFacePlanes();
  1061. if(state == NULL)
  1062. {
  1063. for(i=0;i<uniquePoints;i++)
  1064. {
  1065. texCoords[i] = Vector2DScalar(0.0f, 0.0f);
  1066. }
  1067. }
  1068. else
  1069. {
  1070. mesh->SetReferenceState(*state);
  1071. if(state->GetTextureHandle() > 0)
  1072. {
  1073. if(icoInfo.indexed==true)
  1074. {
  1075. for(i=0;i<uniquePoints;i++)
  1076. {
  1077. texCoords[i] =
  1078. Vector2DScalar(
  1079. (1.0f + collapsedCoords[i].x)/2.0f,
  1080. (1.0f + collapsedCoords[i].y)/2.0f
  1081. );
  1082. }
  1083. }
  1084. else
  1085. {
  1086. for(i=0;i<nrTri;i++)
  1087. {
  1088. texCoords[3*i] =
  1089. Vector2DScalar(
  1090. (1.0f + coords[3*i].x)/2.0f,
  1091. (1.0f + coords[3*i].y)/2.0f
  1092. );
  1093. texCoords[3*i+1] =
  1094. Vector2DScalar(
  1095. (1.0f + coords[3*i+1].x)/2.0f,
  1096. (1.0f + coords[3*i+1].y)/2.0f
  1097. );
  1098. texCoords[3*i+2] =
  1099. Vector2DScalar(
  1100. (1.0f + coords[3*i+2].x)/2.0f,
  1101. (1.0f + coords[3*i+2].y)/2.0f
  1102. );
  1103. }
  1104. }
  1105. }
  1106. else
  1107. {
  1108. for(i=0;i<uniquePoints;i++)
  1109. {
  1110. texCoords[i] = Vector2DScalar(0.0f, 0.0f);
  1111. }
  1112. }
  1113. }
  1114. mesh->SetTexCoordData(texCoords, uniquePoints);
  1115. ret->Add(mesh);
  1116. mesh->DetachReference();
  1117. }
  1118. Unregister_Pointer(texCoords);
  1119. delete [] texCoords;
  1120. Unregister_Pointer(index);
  1121. delete [] index;
  1122. if(icoInfo.indexed==true)
  1123. {
  1124. Unregister_Pointer(collapsedCoords);
  1125. delete [] collapsedCoords;
  1126. }
  1127. Unregister_Pointer(coords);
  1128. delete [] coords;
  1129. gos_PopCurrentHeap();
  1130. return ret;
  1131. }