Team Fortress 2 Source Code as on 22/4/2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

517 lines
19 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: low-level code to write IVP_Compact_Ledge/IVP_Compact_Triangle.
  4. // also includes code to pack/unpack outer hull ledges to 8-bit rep
  5. //
  6. //=============================================================================
  7. #include "cbase.h"
  8. #include "convert.h"
  9. #include <ivp_surface_manager.hxx>
  10. #include <ivp_surman_polygon.hxx>
  11. #include <ivp_template_surbuild.hxx>
  12. #include <ivp_compact_surface.hxx>
  13. #include <ivp_compact_ledge.hxx>
  14. #include "utlbuffer.h"
  15. #include "ledgewriter.h"
  16. // gets the max vertex index referenced by a compact ledge
  17. static int MaxLedgeVertIndex( const IVP_Compact_Ledge *pLedge )
  18. {
  19. int maxIndex = -1;
  20. for ( int i = 0; i < pLedge->get_n_triangles(); i++ )
  21. {
  22. const IVP_Compact_Triangle *pTri = pLedge->get_first_triangle() + i;
  23. for ( int j = 0; j < 3; j++ )
  24. {
  25. int ivpIndex = pTri->get_edge(j)->get_start_point_index();
  26. maxIndex = max(maxIndex, ivpIndex);
  27. }
  28. }
  29. return maxIndex;
  30. }
  31. struct vertmap_t
  32. {
  33. CUtlVector<int> map;
  34. int minRef;
  35. int maxRef;
  36. };
  37. // searches pVerts for each vert used by pLedge and builds a one way map from ledge indices to pVerts indices
  38. // NOTE: pVerts is in HL coords, pLedge is in IVP coords
  39. static void BuildVertMap( vertmap_t &out, const Vector *pVerts, int vertexCount, const IVP_Compact_Ledge *pLedge )
  40. {
  41. out.map.EnsureCount(MaxLedgeVertIndex(pLedge)+1);
  42. for ( int i = 0; i < out.map.Count(); i++ )
  43. {
  44. out.map[i] = -1;
  45. }
  46. out.minRef = vertexCount;
  47. out.maxRef = 0;
  48. const IVP_Compact_Poly_Point *pVertList = pLedge->get_point_array();
  49. for ( int i = 0; i < pLedge->get_n_triangles(); i++ )
  50. {
  51. // iterate each triangle, for each referenced vert that hasn't yet been mapped, search for the nearest match
  52. const IVP_Compact_Triangle *pTri = pLedge->get_first_triangle() + i;
  53. for ( int j = 0; j < 3; j++ )
  54. {
  55. int ivpIndex = pTri->get_edge(j)->get_start_point_index();
  56. if ( out.map[ivpIndex] < 0 )
  57. {
  58. int index = -1;
  59. Vector tmp;
  60. ConvertPositionToHL( &pVertList[ivpIndex], tmp);
  61. float minDist = 1e24;
  62. for ( int k = 0; k < vertexCount; k++ )
  63. {
  64. float dist = (tmp-pVerts[k]).Length();
  65. if ( dist < minDist )
  66. {
  67. index = k;
  68. minDist = dist;
  69. }
  70. }
  71. Assert(minDist<0.1f);
  72. out.map[ivpIndex] = index;
  73. out.minRef = min(out.minRef, index);
  74. out.maxRef = max(out.maxRef, index);
  75. }
  76. }
  77. }
  78. }
  79. // Each IVP_Compact_Triangle and IVP_Compact_Edge occupies an index
  80. // 0,1,2,3 is tri, edge, edge, edge (tris and edges are both 16 bytes)
  81. // So you can just add the index to get_first_triangle to get a pointer
  82. inline int EdgeIndex( const IVP_Compact_Ledge *pLedge, const IVP_Compact_Edge *pEdge )
  83. {
  84. return pEdge - (const IVP_Compact_Edge *)pLedge->get_first_triangle();
  85. }
  86. // Builds a packedhull_t from a IVP_Compact_Ledge. Assumes that the utlbuffer points at the memory following pHull (pHull is the header, utlbuffer is the body)
  87. void PackLedgeIntoBuffer( packedhull_t *pHull, CUtlBuffer &buf, const IVP_Compact_Ledge *pLedge, const virtualmeshlist_t &list )
  88. {
  89. if ( !pLedge )
  90. return;
  91. // The lists store the ivp index of each element to be written out
  92. // The maps store the output packed index for each ivp index
  93. CUtlVector<int> triangleList, triangleMap;
  94. CUtlVector<int> edgeList, edgeMap;
  95. vertmap_t vertMap;
  96. BuildVertMap( vertMap, list.pVerts, list.vertexCount, pLedge );
  97. pHull->baseVert = vertMap.minRef;
  98. // clear the maps
  99. triangleMap.EnsureCount(pLedge->get_n_triangles());
  100. for ( int i = 0; i < triangleMap.Count(); i++ )
  101. {
  102. triangleMap[i] = -1;
  103. }
  104. edgeMap.EnsureCount(pLedge->get_n_triangles()*4); // each triangle also occupies an edge index
  105. for ( int i = 0; i < edgeMap.Count(); i++ )
  106. {
  107. edgeMap[i] = -1;
  108. }
  109. // we're going to reorder the triangles and edges so that the ones marked virtual
  110. // appear first in the list. This way we only need a virtual count, not a per-item
  111. // flag.
  112. // also, the edges are stored relative to the first triangle that references them
  113. // so an edge from 0->1 means that the first triangle that references the edge is 0->1 and the
  114. // second triangle is 1->0. This way we store half the edges and the winged edge pointers are implicit
  115. // sort triangles in two passes
  116. for ( int i = 0; i < pLedge->get_n_triangles(); i++ )
  117. {
  118. const IVP_Compact_Triangle *pTri = pLedge->get_first_triangle() + i;
  119. if ( pTri->get_is_virtual() )
  120. {
  121. triangleMap[i] = triangleList.AddToTail(i);
  122. }
  123. }
  124. pHull->vtriCount = triangleList.Count();
  125. for ( int i = 0; i < pLedge->get_n_triangles(); i++ )
  126. {
  127. const IVP_Compact_Triangle *pTri = pLedge->get_first_triangle() + i;
  128. if ( !pTri->get_is_virtual() )
  129. {
  130. triangleMap[i] = triangleList.AddToTail(i);
  131. }
  132. }
  133. // sort edges in two passes
  134. for ( int i = 0; i < pLedge->get_n_triangles(); i++ )
  135. {
  136. const IVP_Compact_Triangle *pTri = pLedge->get_first_triangle() + triangleList[i];
  137. for ( int j = 0; j < 3; j++ )
  138. {
  139. const IVP_Compact_Edge *pEdge = pTri->get_edge(j);
  140. if ( pEdge->get_is_virtual() && edgeMap[EdgeIndex(pLedge, pEdge->get_opposite())] < 0 )
  141. {
  142. edgeMap[EdgeIndex(pLedge, pEdge)] = edgeList.AddToTail(EdgeIndex(pLedge, pEdge));
  143. }
  144. }
  145. }
  146. pHull->vedgeCount = edgeList.Count();
  147. for ( int i = 0; i < pLedge->get_n_triangles(); i++ )
  148. {
  149. const IVP_Compact_Triangle *pTri = pLedge->get_first_triangle() + triangleList[i];
  150. for ( int j = 0; j < 3; j++ )
  151. {
  152. const IVP_Compact_Edge *pEdge = pTri->get_edge(j);
  153. int index = EdgeIndex(pLedge, pEdge);
  154. int oppositeIndex = EdgeIndex(pLedge, pEdge->get_opposite());
  155. if ( !pEdge->get_is_virtual() && edgeMap[oppositeIndex] < 0 )
  156. {
  157. edgeMap[index] = edgeList.AddToTail(index);
  158. }
  159. if ( edgeMap[index] < 0 )
  160. {
  161. Assert(edgeMap[oppositeIndex] >= 0);
  162. edgeMap[index] = edgeMap[oppositeIndex];
  163. }
  164. }
  165. }
  166. Assert( edgeList.Count() == pHull->edgeCount );
  167. // now write the packed triangles
  168. for ( int i = 0; i < pHull->triangleCount; i++ )
  169. {
  170. packedtriangle_t tri;
  171. const IVP_Compact_Triangle *pTri = pLedge->get_first_triangle() + triangleList[i];
  172. const IVP_Compact_Edge *pEdge;
  173. pEdge = pTri->get_edge(0);
  174. tri.opposite = triangleMap[pTri->get_pierce_index()];
  175. Assert(tri.opposite<pHull->triangleCount);
  176. tri.e0 = edgeMap[EdgeIndex(pLedge, pEdge)];
  177. pEdge = pTri->get_edge(1);
  178. tri.e1 = edgeMap[EdgeIndex(pLedge, pEdge)];
  179. pEdge = pTri->get_edge(2);
  180. tri.e2 = edgeMap[EdgeIndex(pLedge, pEdge)];
  181. Assert(tri.e0<pHull->edgeCount);
  182. Assert(tri.e1<pHull->edgeCount);
  183. Assert(tri.e2<pHull->edgeCount);
  184. buf.Put(&tri, sizeof(tri));
  185. }
  186. // now write the packed edges
  187. for ( int i = 0; i < pHull->edgeCount; i++ )
  188. {
  189. packededge_t edge;
  190. const IVP_Compact_Edge *pEdge = (const IVP_Compact_Edge *)pLedge->get_first_triangle() + edgeList[i];
  191. Assert((edgeList[i]&3) != 0); // must not be a triangle
  192. int v0 = vertMap.map[pEdge->get_start_point_index()] - pHull->baseVert;
  193. int v1 = vertMap.map[pEdge->get_next()->get_start_point_index()] - pHull->baseVert;
  194. Assert(v0>=0 && v0<256);
  195. Assert(v1>=0 && v1<256);
  196. edge.v0 = v0;
  197. edge.v1 = v1;
  198. buf.Put(&edge, sizeof(edge));
  199. }
  200. }
  201. // decompress packed hull into a compact ledge
  202. void CVPhysicsVirtualMeshWriter::UnpackCompactLedgeFromHull( IVP_Compact_Ledge *pLedge, int materialIndex, const IVP_Compact_Poly_Point *pPointList, const virtualmeshhull_t *pHullHeader, int hullIndex, bool isVirtualLedge )
  203. {
  204. const packedhull_t *pHull = pHullHeader->GetPackedHull(hullIndex);
  205. const packedtriangle_t *pPackedTris = pHullHeader->GetPackedTriangles(hullIndex);
  206. // write the ledge
  207. pLedge->set_offset_ledge_points( (int)((char *)pPointList - (char *)pLedge) ); // byte offset from 'this' to (ledge) point array
  208. pLedge->set_is_compact( IVP_TRUE );
  209. pLedge->set_size(sizeof(IVP_Compact_Ledge) + sizeof(IVP_Compact_Triangle)*pHull->triangleCount); // <0 indicates a non compact compact ledge
  210. pLedge->n_triangles = pHull->triangleCount;
  211. pLedge->has_chilren_flag = isVirtualLedge ? IVP_TRUE : IVP_FALSE;
  212. // Make the offset -pLedge so the result is a NULL ledgetree node - we haven't needed to create one of these as of yet
  213. pLedge->ledgetree_node_offset = -((int)pLedge);
  214. // keep track of which triangle edge referenced this edge (so the next one can swap the order and point to the first one)
  215. int forwardEdgeIndex[255];
  216. for ( int i = 0; i < pHull->edgeCount; i++ )
  217. {
  218. forwardEdgeIndex[i] = -1;
  219. }
  220. packededge_t *pPackedEdges = (packededge_t *)(pPackedTris + pHull->triangleCount);
  221. IVP_Compact_Triangle *pOut = pLedge->get_first_triangle();
  222. // now write the compact triangles and their edges
  223. int baseVert = pHull->baseVert;
  224. for ( int i = 0; i < pHull->triangleCount; i++ )
  225. {
  226. pOut[i].set_tri_index(i);
  227. pOut[i].set_material_index(materialIndex);
  228. pOut[i].set_is_virtual( i < pHull->vtriCount ? IVP_TRUE : IVP_FALSE );
  229. pOut[i].set_pierce_index(pPackedTris[i].opposite);
  230. Assert(pPackedTris[i].opposite<pHull->triangleCount);
  231. int edges[3] = {pPackedTris[i].e0, pPackedTris[i].e1, pPackedTris[i].e2};
  232. for ( int j = 0; j < 3; j++ )
  233. {
  234. Assert(edges[j]<pHull->edgeCount);
  235. if ( forwardEdgeIndex[edges[j]] < 0 )
  236. {
  237. // this is the first triangle to use this edge, so it's forward (and the other triangle sharing (opposite edge pointer) is unknown)
  238. int startVert = pPackedEdges[edges[j]].v0 + baseVert;
  239. pOut[i].c_three_edges[j].set_start_point_index(startVert);
  240. pOut[i].c_three_edges[j].set_is_virtual( edges[j] < pHull->vedgeCount ? IVP_TRUE : IVP_FALSE );
  241. forwardEdgeIndex[edges[j]] = EdgeIndex(pLedge, &pOut[i].c_three_edges[j]);
  242. }
  243. else
  244. {
  245. // this is the second triangle to use this edge, so it's reversed (and the other triangle sharing is in the forward edge table)
  246. int oppositeIndex = forwardEdgeIndex[edges[j]];
  247. int startVert = pPackedEdges[edges[j]].v1 + baseVert;
  248. pOut[i].c_three_edges[j].set_start_point_index(startVert);
  249. pOut[i].c_three_edges[j].set_is_virtual( edges[j] < pHull->vedgeCount ? IVP_TRUE : IVP_FALSE );
  250. // now build the links between the triangles sharing this edge
  251. int thisEdgeIndex = EdgeIndex( pLedge, &pOut[i].c_three_edges[j] );
  252. pOut[i].c_three_edges[j].set_opposite_index( oppositeIndex - thisEdgeIndex );
  253. pOut[i].c_three_edges[j].get_opposite()->set_opposite_index( thisEdgeIndex - oppositeIndex );
  254. }
  255. }
  256. }
  257. }
  258. // low-level code to initialize a 2-sided triangle
  259. static void InitTriangle( IVP_Compact_Triangle *pTri, int index, int materialIndex, int v0, int v1, int v2, int opp0, int opp1, int opp2 )
  260. {
  261. pTri->set_tri_index(index);
  262. pTri->set_material_index(materialIndex);
  263. pTri->c_three_edges[0].set_start_point_index(v0);
  264. pTri->c_three_edges[1].set_start_point_index(v1);
  265. pTri->c_three_edges[2].set_start_point_index(v2);
  266. pTri->c_three_edges[0].set_opposite_index(opp0);
  267. pTri->c_three_edges[1].set_opposite_index(opp1);
  268. pTri->c_three_edges[2].set_opposite_index(opp2);
  269. }
  270. void CVPhysicsVirtualMeshWriter::InitTwoSidedTriangleLege( triangleledge_t *pOut, const IVP_Compact_Poly_Point *pPoints, int v0, int v1, int v2, int materialIndex )
  271. {
  272. IVP_Compact_Ledge *pLedge = &pOut->ledge;
  273. pLedge->set_offset_ledge_points( (int)((char *)pPoints - (char *)pLedge) ); // byte offset from 'this' to (ledge) point array
  274. pLedge->set_is_compact( IVP_TRUE );
  275. pLedge->set_size(sizeof(triangleledge_t)); // <0 indicates a non compact compact ledge
  276. pLedge->n_triangles = 2;
  277. pLedge->has_chilren_flag = IVP_FALSE;
  278. // triangles
  279. InitTriangle( &pOut->faces[0], 0, materialIndex, v0, v1, v2, 6, 4, 2 );
  280. InitTriangle( &pOut->faces[1], 1, materialIndex, v0, v2, v1, -2, -4, -6);
  281. pOut->faces[0].set_pierce_index(1);
  282. pOut->faces[1].set_pierce_index(0);
  283. }
  284. bool CVPhysicsVirtualMeshWriter::LedgeCanBePacked(const IVP_Compact_Ledge *pLedge, const virtualmeshlist_t &list)
  285. {
  286. int edgeCount = pLedge->get_n_triangles() * 3;
  287. if ( edgeCount > 512 )
  288. return false;
  289. vertmap_t vertMap;
  290. BuildVertMap( vertMap, list.pVerts, list.vertexCount, pLedge );
  291. if ( (vertMap.maxRef - vertMap.minRef) > 255 )
  292. return false;
  293. return true;
  294. }
  295. // this builds a packed hull array from a compact ledge array (needs the virtualmeshlist for reference)
  296. virtualmeshhull_t *CVPhysicsVirtualMeshWriter::CreatePackedHullFromLedges( const virtualmeshlist_t &list, const IVP_Compact_Ledge **pLedges, int ledgeCount )
  297. {
  298. int triCount = 0;
  299. int edgeCount = 0;
  300. for ( int i = 0; i < ledgeCount; i++ )
  301. {
  302. triCount += pLedges[i]->get_n_triangles();
  303. edgeCount += (pLedges[i]->get_n_triangles() * 3)/2;
  304. Assert(LedgeCanBePacked(pLedges[i], list));
  305. }
  306. unsigned int totalSize = sizeof(packedtriangle_t)*triCount + sizeof(packededge_t)*edgeCount + sizeof(packedhull_t)*ledgeCount + sizeof(virtualmeshhull_t);
  307. byte *pBuf = new byte[totalSize];
  308. CUtlBuffer buf;
  309. buf.SetExternalBuffer( pBuf, totalSize, 0, 0 );
  310. if ( 1 )
  311. {
  312. virtualmeshhull_t tmp;
  313. Q_memset( &tmp, 0, sizeof(tmp) );
  314. tmp.hullCount = ledgeCount;
  315. buf.Put(&tmp, sizeof(tmp));
  316. }
  317. // write the headers
  318. Assert(ledgeCount < 16);
  319. packedhull_t *pHulls[16];
  320. for ( int i = 0; i < ledgeCount; i++ )
  321. {
  322. pHulls[i] = (packedhull_t *)buf.PeekPut();
  323. packedhull_t hull;
  324. hull.triangleCount = pLedges[i]->get_n_triangles();
  325. hull.edgeCount = (hull.triangleCount * 3) / 2;
  326. buf.Put(&hull, sizeof(hull));
  327. }
  328. // write the data itself
  329. for ( int i = 0; i < ledgeCount; i++ )
  330. {
  331. PackLedgeIntoBuffer( pHulls[i], buf, pLedges[i], list );
  332. }
  333. return (virtualmeshhull_t *)pBuf;
  334. }
  335. // frees the memory associated with this packed hull
  336. void CVPhysicsVirtualMeshWriter::DestroyPackedHull( virtualmeshhull_t *pHull )
  337. {
  338. byte *pData = (byte *)pHull;
  339. delete[] pData;
  340. }
  341. unsigned int CVPhysicsVirtualMeshWriter::UnpackLedgeListFromHull( byte *pOut, virtualmeshhull_t *pHull, IVP_Compact_Poly_Point *pPoints )
  342. {
  343. unsigned int memOffset = 0;
  344. for ( int i = 0; i < pHull->hullCount; i++ )
  345. {
  346. IVP_Compact_Ledge *pHullLedge = (IVP_Compact_Ledge *)(pOut + memOffset);
  347. CVPhysicsVirtualMeshWriter::UnpackCompactLedgeFromHull( pHullLedge, 0, pPoints, pHull, i, true );
  348. memOffset += pHullLedge->get_size();
  349. }
  350. return memOffset;
  351. }
  352. /*
  353. #define DUMP_FILES 1
  354. static bool DumpListToGLView( const char *pFilename, const virtualmeshlist_t &list )
  355. {
  356. #if DUMP_FILES
  357. FILE *fp = fopen( pFilename, "a+" );
  358. for ( int i = 0; i < list.triangleCount; i++ )
  359. {
  360. fprintf( fp, "3\n" );
  361. fprintf( fp, "%6.3f %6.3f %6.3f 1 0 0\n", list.pVerts[list.indices[i*3+0]].x, list.pVerts[list.indices[i*3+0]].y, list.pVerts[list.indices[i*3+0]].z );
  362. fprintf( fp, "%6.3f %6.3f %6.3f 0 1 0\n", list.pVerts[list.indices[i*3+1]].x, list.pVerts[list.indices[i*3+1]].y, list.pVerts[list.indices[i*3+1]].z );
  363. fprintf( fp, "%6.3f %6.3f %6.3f 0 0 1\n", list.pVerts[list.indices[i*3+2]].x, list.pVerts[list.indices[i*3+2]].y, list.pVerts[list.indices[i*3+2]].z );
  364. }
  365. fclose(fp);
  366. #endif
  367. return true;
  368. }
  369. static bool DumpLedgeToGLView( const char *pFilename, const IVP_Compact_Ledge *pLedge, float r=1.0f, float g=1.0f, float b=1.0f, float offset=0.0f )
  370. {
  371. #if DUMP_FILES
  372. FILE *fp = fopen( pFilename, "a+" );
  373. int ivpIndex;
  374. Vector tmp[3];
  375. const IVP_Compact_Poly_Point *pPoints = pLedge->get_point_array();
  376. for ( int i = 0; i < pLedge->get_n_triangles(); i++ )
  377. {
  378. // iterate each triangle, for each referenced vert that hasn't yet been mapped, search for the nearest match
  379. const IVP_Compact_Triangle *pTri = pLedge->get_first_triangle() + i;
  380. ivpIndex = pTri->get_edge(2)->get_start_point_index();
  381. ConvertPositionToHL( &pPoints[ivpIndex], tmp[0] );
  382. ivpIndex = pTri->get_edge(1)->get_start_point_index();
  383. ConvertPositionToHL( &pPoints[ivpIndex], tmp[1] );
  384. ivpIndex = pTri->get_edge(0)->get_start_point_index();
  385. ConvertPositionToHL( &pPoints[ivpIndex], tmp[2] );
  386. tmp[0].x += offset;
  387. tmp[1].x += offset;
  388. tmp[2].x += offset;
  389. fprintf( fp, "2\n" );
  390. fprintf( fp, "%6.3f %6.3f %6.3f %.1f %.1f %.1f\n", tmp[0].x, tmp[0].y, tmp[0].z, r, g, b );
  391. fprintf( fp, "%6.3f %6.3f %6.3f %.1f %.1f %.1f\n", tmp[1].x, tmp[1].y, tmp[1].z, r, g, b );
  392. fprintf( fp, "2\n" );
  393. fprintf( fp, "%6.3f %6.3f %6.3f %.1f %.1f %.1f\n", tmp[1].x, tmp[1].y, tmp[1].z, r, g, b );
  394. fprintf( fp, "%6.3f %6.3f %6.3f %.1f %.1f %.1f\n", tmp[2].x, tmp[2].y, tmp[2].z, r, g, b );
  395. fprintf( fp, "2\n" );
  396. fprintf( fp, "%6.3f %6.3f %6.3f %.1f %.1f %.1f\n", tmp[2].x, tmp[2].y, tmp[2].z, r, g, b );
  397. fprintf( fp, "%6.3f %6.3f %6.3f %.1f %.1f %.1f\n", tmp[0].x, tmp[0].y, tmp[0].z, r, g, b );
  398. }
  399. fclose( fp );
  400. #endif
  401. return true;
  402. }
  403. static int ComputeSize( virtualmeshhull_t *pHeader )
  404. {
  405. packedhull_t *pHull = (packedhull_t *)(pHeader+1);
  406. unsigned int size = pHeader->hullCount * sizeof(IVP_Compact_Ledge);
  407. for ( int i = 0; i < pHeader->hullCount; i++ )
  408. {
  409. size += sizeof(IVP_Compact_Triangle) * pHull[i].triangleCount;
  410. }
  411. return size;
  412. }
  413. bool CVPhysicsVirtualMeshWriter::CheckHulls( virtualmeshhull_t *pHull0, virtualmeshhull_t *pHull1, const virtualmeshlist_t &list )
  414. {
  415. for ( int i = 0; i < pHull0->hullCount; i++ )
  416. {
  417. const packedhull_t *pP0 = pHull0->GetPackedHull(i);
  418. const packedhull_t *pP1 = pHull1->GetPackedHull(i);
  419. Assert(pP0->triangleCount == pP1->triangleCount);
  420. Assert(pP0->vtriCount == pP1->vtriCount);
  421. Assert(pP0->edgeCount == pP1->edgeCount);
  422. Assert(pP0->vedgeCount == pP1->vedgeCount);
  423. Assert(pP0->baseVert == pP1->baseVert);
  424. const packedtriangle_t *pTri0 = pHull0->GetPackedTriangles( i );
  425. const packedtriangle_t *pTri1 = pHull1->GetPackedTriangles( i );
  426. for ( int j = 0; j < pP0->triangleCount; j++ )
  427. {
  428. Assert(pTri0[j].e0 == pTri1[j].e0);
  429. Assert(pTri0[j].e1 == pTri1[j].e1);
  430. Assert(pTri0[j].e2 == pTri1[j].e2);
  431. Assert(pTri0[j].opposite == pTri1[j].opposite);
  432. }
  433. }
  434. {
  435. int size0 = ComputeSize(pHull0);
  436. int pointSize0 = sizeof(IVP_Compact_Poly_Point) * list.vertexCount;
  437. byte *pMem0 = (byte *)ivp_malloc_aligned( size0+pointSize0, 16 );
  438. IVP_Compact_Poly_Point *pPoints = (IVP_Compact_Poly_Point *)pMem0;
  439. IVP_Compact_Ledge *pLedge0 = (IVP_Compact_Ledge *)(pPoints + list.vertexCount);
  440. for ( int i = 0; i < list.vertexCount; i++ )
  441. {
  442. ConvertPositionToIVP( list.pVerts[i], pPoints[i] );
  443. }
  444. UnpackLedgeListFromHull( (byte *)pLedge0, pHull0, pPoints );
  445. for ( int i = 0; i < pHull0->hullCount; i++ )
  446. {
  447. if ( i == i ) DumpLedgeToGLView( "c:\\jay.txt", pLedge0, 1, 0, 0, 0 );
  448. pLedge0 = (IVP_Compact_Ledge *)( ((byte *)pLedge0 ) + pLedge0->get_size() );
  449. }
  450. ivp_free_aligned(pMem0);
  451. }
  452. {
  453. int size1 = ComputeSize(pHull1);
  454. int pointSize1 = sizeof(IVP_Compact_Poly_Point) * list.vertexCount;
  455. byte *pMem1 = (byte *)ivp_malloc_aligned( size1+pointSize1, 16 );
  456. IVP_Compact_Poly_Point *pPoints = (IVP_Compact_Poly_Point *)pMem1;
  457. IVP_Compact_Ledge *pLedge1 = (IVP_Compact_Ledge *)(pPoints + list.vertexCount);
  458. for ( int i = 0; i < list.vertexCount; i++ )
  459. {
  460. ConvertPositionToIVP( list.pVerts[i], pPoints[i] );
  461. }
  462. UnpackLedgeListFromHull( (byte *)pLedge1, pHull1, pPoints );
  463. for ( int i = 0; i < pHull1->hullCount; i++ )
  464. {
  465. if ( i == i ) DumpLedgeToGLView( "c:\\jay.txt", pLedge1, 0, 1, 0, 1024 );
  466. pLedge1 = (IVP_Compact_Ledge *)( ((byte *)pLedge1 ) + pLedge1->get_size() );
  467. }
  468. ivp_free_aligned(pMem1);
  469. }
  470. return true;
  471. }
  472. */