Counter Strike : Global Offensive Source Code
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.

1828 lines
40 KiB

  1. //========= Copyright � 1996-2005, Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose:
  4. //
  5. // $NoKeywords: $
  6. //
  7. //=============================================================================//
  8. // faces.c
  9. #include "vbsp.h"
  10. #include "utlvector.h"
  11. #include "utilmatlib.h"
  12. #include <float.h>
  13. #include "mstristrip.h"
  14. #include "tier1/strtools.h"
  15. #include "materialpatch.h"
  16. /*
  17. some faces will be removed before saving, but still form nodes:
  18. the insides of sky volumes
  19. meeting planes of different water current volumes
  20. */
  21. // undefine for dumb linear searches
  22. #define USE_HASHING
  23. #define INTEGRAL_EPSILON 0.01
  24. #define POINT_EPSILON 0.1
  25. #define OFF_EPSILON 0.25
  26. int c_merge;
  27. int c_subdivide;
  28. int c_totalverts;
  29. int c_uniqueverts;
  30. int c_degenerate;
  31. int c_tjunctions;
  32. int c_faceoverflows;
  33. int c_facecollapse;
  34. int c_badstartverts;
  35. #define MAX_SUPERVERTS 512
  36. int superverts[MAX_SUPERVERTS];
  37. int numsuperverts;
  38. face_t *edgefaces[MAX_MAP_EDGES][2];
  39. int firstmodeledge = 1;
  40. int firstmodelface;
  41. int c_tryedges;
  42. Vector edge_dir;
  43. Vector edge_start;
  44. vec_t edge_len;
  45. int num_edge_verts;
  46. int edge_verts[MAX_MAP_VERTS];
  47. float g_maxLightmapDimension = MAX_BRUSH_LIGHTMAP_DIM_WITHOUT_BORDER;
  48. face_t *NewFaceFromFace (face_t *f);
  49. // Used to speed up GetEdge2(). Holds a list of edges connected to each vert.
  50. CUtlVector<int> g_VertEdgeList[MAX_MAP_VERTS];
  51. //===========================================================================
  52. typedef struct hashvert_s
  53. {
  54. struct hashvert_s *next;
  55. int num;
  56. } hashvert_t;
  57. #define HASH_BITS 7
  58. #define HASH_SIZE (COORD_EXTENT>>HASH_BITS)
  59. int vertexchain[MAX_MAP_VERTS]; // the next vertex in a hash chain
  60. int hashverts[HASH_SIZE*HASH_SIZE]; // a vertex number, or 0 for no verts
  61. //face_t *edgefaces[MAX_MAP_EDGES][2];
  62. //============================================================================
  63. unsigned HashVec (Vector& vec)
  64. {
  65. int x, y;
  66. x = (MAX_COORD_INTEGER + (int)(vec[0]+0.5)) >> HASH_BITS;
  67. y = (MAX_COORD_INTEGER + (int)(vec[1]+0.5)) >> HASH_BITS;
  68. if ( x < 0 || x >= HASH_SIZE || y < 0 || y >= HASH_SIZE )
  69. Error ("HashVec: point outside valid range");
  70. return y*HASH_SIZE + x;
  71. }
  72. #ifdef USE_HASHING
  73. /*
  74. =============
  75. GetVertex
  76. Uses hashing
  77. =============
  78. */
  79. int GetVertexnum (Vector& in)
  80. {
  81. int h;
  82. int i;
  83. Vector vert;
  84. int vnum;
  85. c_totalverts++;
  86. for (i=0 ; i<3 ; i++)
  87. {
  88. if ( fabs(in[i] - (int)(in[i]+0.5)) < INTEGRAL_EPSILON)
  89. vert[i] = (int)(in[i]+0.5);
  90. else
  91. vert[i] = in[i];
  92. }
  93. h = HashVec (vert);
  94. for (vnum=hashverts[h] ; vnum ; vnum=vertexchain[vnum])
  95. {
  96. Vector& p = dvertexes[vnum].point;
  97. if ( fabs(p[0]-vert[0])<POINT_EPSILON
  98. && fabs(p[1]-vert[1])<POINT_EPSILON
  99. && fabs(p[2]-vert[2])<POINT_EPSILON )
  100. return vnum;
  101. }
  102. // emit a vertex
  103. if (numvertexes == MAX_MAP_VERTS)
  104. Error ("Too many unique verts, max = %d (map has too much brush geometry)\n", MAX_MAP_VERTS);
  105. dvertexes[numvertexes].point[0] = vert[0];
  106. dvertexes[numvertexes].point[1] = vert[1];
  107. dvertexes[numvertexes].point[2] = vert[2];
  108. vertexchain[numvertexes] = hashverts[h];
  109. hashverts[h] = numvertexes;
  110. c_uniqueverts++;
  111. numvertexes++;
  112. return numvertexes-1;
  113. }
  114. #else
  115. /*
  116. ==================
  117. GetVertexnum
  118. Dumb linear search
  119. ==================
  120. */
  121. int GetVertexnum (Vector& v)
  122. {
  123. int i, j;
  124. dvertex_t *dv;
  125. vec_t d;
  126. c_totalverts++;
  127. // make really close values exactly integral
  128. for (i=0 ; i<3 ; i++)
  129. {
  130. if ( fabs(v[i] - (int)(v[i]+0.5)) < INTEGRAL_EPSILON )
  131. v[i] = (int)(v[i]+0.5);
  132. if (v[i] < MIN_COORD_INTEGER || v[i] > MAX_COORD_INTEGER)
  133. Error ("GetVertexnum: outside world, vertex %.1f %.1f %.1f", v.x, v.y, v.z);
  134. }
  135. // search for an existing vertex match
  136. for (i=0, dv=dvertexes ; i<numvertexes ; i++, dv++)
  137. {
  138. for (j=0 ; j<3 ; j++)
  139. {
  140. d = v[j] - dv->point[j];
  141. if ( d > POINT_EPSILON || d < -POINT_EPSILON)
  142. break;
  143. }
  144. if (j == 3)
  145. return i; // a match
  146. }
  147. // new point
  148. if (numvertexes == MAX_MAP_VERTS)
  149. Error ("Too many unique verts, max = %d (map has too much brush geometry)\n", MAX_MAP_VERTS);
  150. VectorCopy (v, dv->point);
  151. numvertexes++;
  152. c_uniqueverts++;
  153. return numvertexes-1;
  154. }
  155. #endif
  156. /*
  157. ==================
  158. FaceFromSuperverts
  159. The faces vertexes have beeb added to the superverts[] array,
  160. and there may be more there than can be held in a face (MAXEDGES).
  161. If less, the faces vertexnums[] will be filled in, otherwise
  162. face will reference a tree of split[] faces until all of the
  163. vertexnums can be added.
  164. superverts[base] will become face->vertexnums[0], and the others
  165. will be circularly filled in.
  166. ==================
  167. */
  168. void FaceFromSuperverts (face_t **pListHead, face_t *f, int base)
  169. {
  170. face_t *newf;
  171. int remaining;
  172. int i;
  173. remaining = numsuperverts;
  174. while (remaining > MAXEDGES)
  175. { // must split into two faces, because of vertex overload
  176. c_faceoverflows++;
  177. newf = NewFaceFromFace (f);
  178. f->split[0] = newf;
  179. newf->next = *pListHead;
  180. *pListHead = newf;
  181. newf->numpoints = MAXEDGES;
  182. for (i=0 ; i<MAXEDGES ; i++)
  183. newf->vertexnums[i] = superverts[(i+base)%numsuperverts];
  184. f->split[1] = NewFaceFromFace (f);
  185. f = f->split[1];
  186. f->next = *pListHead;
  187. *pListHead = f;
  188. remaining -= (MAXEDGES-2);
  189. base = (base+MAXEDGES-1)%numsuperverts;
  190. }
  191. // copy the vertexes back to the face
  192. f->numpoints = remaining;
  193. for (i=0 ; i<remaining ; i++)
  194. f->vertexnums[i] = superverts[(i+base)%numsuperverts];
  195. }
  196. /*
  197. ==================
  198. EmitFaceVertexes
  199. ==================
  200. */
  201. void EmitFaceVertexes (face_t **pListHead, face_t *f)
  202. {
  203. winding_t *w;
  204. int i;
  205. if (f->merged || f->split[0] || f->split[1])
  206. return;
  207. w = f->w;
  208. for (i=0 ; i<w->numpoints ; i++)
  209. {
  210. if (noweld)
  211. { // make every point unique
  212. if (numvertexes == MAX_MAP_VERTS)
  213. Error ("Too many unique verts, max = %d (map has too much brush geometry)\n", MAX_MAP_VERTS);
  214. superverts[i] = numvertexes;
  215. VectorCopy (w->p[i], dvertexes[numvertexes].point);
  216. numvertexes++;
  217. c_uniqueverts++;
  218. c_totalverts++;
  219. }
  220. else
  221. superverts[i] = GetVertexnum (w->p[i]);
  222. }
  223. numsuperverts = w->numpoints;
  224. // this may fragment the face if > MAXEDGES
  225. FaceFromSuperverts (pListHead, f, 0);
  226. }
  227. /*
  228. ==================
  229. EmitNodeFaceVertexes_r
  230. ==================
  231. */
  232. void EmitNodeFaceVertexes_r (node_t *node)
  233. {
  234. int i;
  235. face_t *f;
  236. if (node->planenum == PLANENUM_LEAF)
  237. {
  238. // leaf faces are emitted in second pass
  239. return;
  240. }
  241. for (f=node->faces ; f ; f=f->next)
  242. {
  243. EmitFaceVertexes (&node->faces, f);
  244. }
  245. for (i=0 ; i<2 ; i++)
  246. {
  247. EmitNodeFaceVertexes_r (node->children[i]);
  248. }
  249. }
  250. void EmitLeafFaceVertexes( face_t **ppLeafFaceList )
  251. {
  252. face_t *f = *ppLeafFaceList;
  253. while ( f )
  254. {
  255. EmitFaceVertexes( ppLeafFaceList, f );
  256. f = f->next;
  257. }
  258. }
  259. #ifdef USE_HASHING
  260. /*
  261. ==========
  262. FindEdgeVerts
  263. Uses the hash tables to cut down to a small number
  264. ==========
  265. */
  266. void FindEdgeVerts (Vector& v1, Vector& v2)
  267. {
  268. int x1, x2, y1, y2, t;
  269. int x, y;
  270. int vnum;
  271. #if 0
  272. {
  273. int i;
  274. num_edge_verts = numvertexes-1;
  275. for (i=0 ; i<numvertexes-1 ; i++)
  276. edge_verts[i] = i+1;
  277. }
  278. #endif
  279. x1 = (MAX_COORD_INTEGER + (int)(v1[0]+0.5)) >> HASH_BITS;
  280. y1 = (MAX_COORD_INTEGER + (int)(v1[1]+0.5)) >> HASH_BITS;
  281. x2 = (MAX_COORD_INTEGER + (int)(v2[0]+0.5)) >> HASH_BITS;
  282. y2 = (MAX_COORD_INTEGER + (int)(v2[1]+0.5)) >> HASH_BITS;
  283. if (x1 > x2)
  284. {
  285. t = x1;
  286. x1 = x2;
  287. x2 = t;
  288. }
  289. if (y1 > y2)
  290. {
  291. t = y1;
  292. y1 = y2;
  293. y2 = t;
  294. }
  295. #if 0
  296. x1--;
  297. x2++;
  298. y1--;
  299. y2++;
  300. if (x1 < 0)
  301. x1 = 0;
  302. if (x2 >= HASH_SIZE)
  303. x2 = HASH_SIZE;
  304. if (y1 < 0)
  305. y1 = 0;
  306. if (y2 >= HASH_SIZE)
  307. y2 = HASH_SIZE;
  308. #endif
  309. num_edge_verts = 0;
  310. for (x=x1 ; x <= x2 ; x++)
  311. {
  312. for (y=y1 ; y <= y2 ; y++)
  313. {
  314. for (vnum=hashverts[y*HASH_SIZE+x] ; vnum ; vnum=vertexchain[vnum])
  315. {
  316. edge_verts[num_edge_verts++] = vnum;
  317. }
  318. }
  319. }
  320. }
  321. #else
  322. /*
  323. ==========
  324. FindEdgeVerts
  325. Forced a dumb check of everything
  326. ==========
  327. */
  328. void FindEdgeVerts (Vector& v1, Vector& v2)
  329. {
  330. int i;
  331. num_edge_verts = numvertexes-1;
  332. for (i=0 ; i<num_edge_verts ; i++)
  333. edge_verts[i] = i+1;
  334. }
  335. #endif
  336. /*
  337. ==========
  338. TestEdge
  339. Can be recursively reentered
  340. ==========
  341. */
  342. void TestEdge (vec_t start, vec_t end, int p1, int p2, int startvert)
  343. {
  344. int j, k;
  345. vec_t dist;
  346. Vector delta;
  347. Vector exact;
  348. Vector off;
  349. vec_t error;
  350. Vector p;
  351. if (p1 == p2)
  352. {
  353. c_degenerate++;
  354. return; // degenerate edge
  355. }
  356. for (k=startvert ; k<num_edge_verts ; k++)
  357. {
  358. j = edge_verts[k];
  359. if (j==p1 || j == p2)
  360. continue;
  361. VectorCopy (dvertexes[j].point, p);
  362. VectorSubtract (p, edge_start, delta);
  363. dist = DotProduct (delta, edge_dir);
  364. if (dist <=start || dist >= end)
  365. continue; // off an end
  366. VectorMA (edge_start, dist, edge_dir, exact);
  367. VectorSubtract (p, exact, off);
  368. error = off.Length();
  369. if (error > OFF_EPSILON)
  370. continue; // not on the edge
  371. // break the edge
  372. c_tjunctions++;
  373. TestEdge (start, dist, p1, j, k+1);
  374. TestEdge (dist, end, j, p2, k+1);
  375. return;
  376. }
  377. // the edge p1 to p2 is now free of tjunctions
  378. if (numsuperverts >= MAX_SUPERVERTS)
  379. Error ("Edge with too many vertices due to t-junctions. Max %d verts along an edge!\n", MAX_SUPERVERTS);
  380. superverts[numsuperverts] = p1;
  381. numsuperverts++;
  382. }
  383. // stores the edges that each vert is part of
  384. struct face_vert_table_t
  385. {
  386. face_vert_table_t()
  387. {
  388. edge0 = -1;
  389. edge1 = -1;
  390. }
  391. void AddEdge( int edge )
  392. {
  393. if ( edge0 == -1 )
  394. {
  395. edge0 = edge;
  396. }
  397. else
  398. {
  399. // can only have two edges
  400. Assert(edge1==-1);
  401. edge1 = edge;
  402. }
  403. }
  404. bool HasEdge( int edge ) const
  405. {
  406. if ( edge >= 0 )
  407. {
  408. if ( edge0 == edge || edge1 == edge )
  409. return true;
  410. }
  411. return false;
  412. }
  413. int edge0;
  414. int edge1;
  415. };
  416. // if these two verts share an edge, they must be collinear
  417. bool IsDiagonal( const face_vert_table_t &v0, const face_vert_table_t &v1 )
  418. {
  419. if ( v1.HasEdge(v0.edge0) || v1.HasEdge(v0.edge1) )
  420. return false;
  421. return true;
  422. }
  423. void Triangulate_r( CUtlVector<int> &out, const CUtlVector<int> &inIndices, const CUtlVector<face_vert_table_t> &poly )
  424. {
  425. Assert( inIndices.Count() > 2 );
  426. // one triangle left, return
  427. if ( inIndices.Count() == 3 )
  428. {
  429. for ( int i = 0; i < inIndices.Count(); i++ )
  430. {
  431. out.AddToTail( inIndices[i] );
  432. }
  433. return;
  434. }
  435. // check each pair of verts and see if they are diagonal (not on a shared edge)
  436. // if so, split & recurse
  437. for ( int i = 0; i < inIndices.Count(); i++ )
  438. {
  439. int count = inIndices.Count();
  440. // i + count is myself, i + count-1 is previous, so we need to stop at i+count-2
  441. for ( int j = 2; j < count-1; j++ )
  442. {
  443. // if these two form a diagonal, split the poly along
  444. // the diagonal and triangulate the two sub-polys
  445. int index = inIndices[i];
  446. int nextArray = (i+j)%count;
  447. int nextIndex = inIndices[nextArray];
  448. if ( IsDiagonal(poly[index], poly[nextIndex]) )
  449. {
  450. // add the poly up to the diagonal
  451. CUtlVector<int> in1;
  452. for ( int k = i; k != nextArray; k = (k+1)%count )
  453. {
  454. in1.AddToTail(inIndices[k]);
  455. }
  456. in1.AddToTail(nextIndex);
  457. // add the rest of the poly starting with the diagonal
  458. CUtlVector<int> in2;
  459. in2.AddToTail(index);
  460. for ( int l = nextArray; l != i; l = (l+1)%count )
  461. {
  462. in2.AddToTail(inIndices[l]);
  463. }
  464. // triangulate the sub-polys
  465. Triangulate_r( out, in1, poly );
  466. Triangulate_r( out, in2, poly );
  467. return;
  468. }
  469. }
  470. }
  471. // didn't find a diagonal
  472. Assert(0);
  473. }
  474. /*
  475. ==================
  476. FixFaceEdges
  477. ==================
  478. */
  479. void FixFaceEdges (face_t **pList, face_t *f)
  480. {
  481. int p1, p2;
  482. int i;
  483. Vector e2;
  484. vec_t len;
  485. int count[MAX_SUPERVERTS], start[MAX_SUPERVERTS];
  486. int base;
  487. if (f->merged || f->split[0] || f->split[1])
  488. return;
  489. numsuperverts = 0;
  490. int originalPoints = f->numpoints;
  491. for (i=0 ; i<f->numpoints ; i++)
  492. {
  493. p1 = f->vertexnums[i];
  494. p2 = f->vertexnums[(i+1)%f->numpoints];
  495. VectorCopy (dvertexes[p1].point, edge_start);
  496. VectorCopy (dvertexes[p2].point, e2);
  497. FindEdgeVerts (edge_start, e2);
  498. VectorSubtract (e2, edge_start, edge_dir);
  499. len = VectorNormalize (edge_dir);
  500. start[i] = numsuperverts;
  501. TestEdge (0, len, p1, p2, 0);
  502. count[i] = numsuperverts - start[i];
  503. }
  504. if (numsuperverts < 3)
  505. { // entire face collapsed
  506. f->numpoints = 0;
  507. c_facecollapse++;
  508. return;
  509. }
  510. // we want to pick a vertex that doesn't have tjunctions
  511. // on either side, which can cause artifacts on trifans,
  512. // especially underwater
  513. for (i=0 ; i<f->numpoints ; i++)
  514. {
  515. if (count[i] == 1 && count[(i+f->numpoints-1)%f->numpoints] == 1)
  516. break;
  517. }
  518. if (i == f->numpoints)
  519. {
  520. f->badstartvert = true;
  521. c_badstartverts++;
  522. base = 0;
  523. }
  524. else
  525. { // rotate the vertex order
  526. base = start[i];
  527. }
  528. // this may fragment the face if > MAXEDGES
  529. FaceFromSuperverts (pList, f, base);
  530. // if this is the world, then re-triangulate to sew cracks
  531. if ( f->badstartvert && entity_num == 0 )
  532. {
  533. CUtlVector<face_vert_table_t> poly;
  534. CUtlVector<int> inIndices;
  535. CUtlVector<int> outIndices;
  536. poly.AddMultipleToTail( numsuperverts );
  537. for ( i = 0; i < originalPoints; i++ )
  538. {
  539. // edge may not have output any points. Don't mark
  540. if ( !count[i] )
  541. continue;
  542. // mark each edge the point is a member of
  543. // we'll use this as a fast "is collinear" test
  544. for ( int j = 0; j <= count[i]; j++ )
  545. {
  546. int polyIndex = (start[i] + j) % numsuperverts;
  547. poly[polyIndex].AddEdge( i );
  548. }
  549. }
  550. for ( i = 0; i < numsuperverts; i++ )
  551. {
  552. inIndices.AddToTail( i );
  553. }
  554. Triangulate_r( outIndices, inIndices, poly );
  555. dprimitive_t &newPrim = g_primitives[g_numprimitives];
  556. f->firstPrimID = g_numprimitives;
  557. g_numprimitives++;
  558. f->numPrims = 1;
  559. newPrim.firstIndex = g_numprimindices;
  560. newPrim.firstVert = g_numprimverts;
  561. newPrim.indexCount = outIndices.Count();
  562. newPrim.vertCount = 0;
  563. newPrim.type = PRIM_TRILIST;
  564. g_numprimindices += newPrim.indexCount;
  565. if ( g_numprimitives > MAX_MAP_PRIMITIVES || g_numprimindices > MAX_MAP_PRIMINDICES )
  566. {
  567. Error("Too many t-junctions to fix up! (%d prims, max %d :: %d indices, max %d)\n", g_numprimitives, MAX_MAP_PRIMITIVES, g_numprimindices, MAX_MAP_PRIMINDICES );
  568. }
  569. for ( i = 0; i < outIndices.Count(); i++ )
  570. {
  571. g_primindices[newPrim.firstIndex + i] = outIndices[i];
  572. }
  573. }
  574. }
  575. /*
  576. ==================
  577. FixEdges_r
  578. ==================
  579. */
  580. void FixEdges_r (node_t *node)
  581. {
  582. int i;
  583. face_t *f;
  584. if (node->planenum == PLANENUM_LEAF)
  585. {
  586. return;
  587. }
  588. for (f=node->faces ; f ; f=f->next)
  589. FixFaceEdges (&node->faces, f);
  590. for (i=0 ; i<2 ; i++)
  591. FixEdges_r (node->children[i]);
  592. }
  593. //-----------------------------------------------------------------------------
  594. // Purpose: Fix the t-junctions on detail faces
  595. //-----------------------------------------------------------------------------
  596. void FixLeafFaceEdges( face_t **ppLeafFaceList )
  597. {
  598. face_t *f;
  599. for ( f = *ppLeafFaceList; f; f = f->next )
  600. {
  601. FixFaceEdges( ppLeafFaceList, f );
  602. }
  603. }
  604. /*
  605. ===========
  606. FixTjuncs
  607. ===========
  608. */
  609. face_t *FixTjuncs (node_t *headnode, face_t *pLeafFaceList)
  610. {
  611. // snap and merge all vertexes
  612. qprintf ("---- snap verts ----\n");
  613. memset (hashverts, 0, sizeof(hashverts));
  614. memset (vertexchain, 0, sizeof(vertexchain));
  615. c_totalverts = 0;
  616. c_uniqueverts = 0;
  617. c_faceoverflows = 0;
  618. EmitNodeFaceVertexes_r (headnode);
  619. // UNDONE: This count is wrong with tjuncs off on details - since
  620. // break edges on tjunctions
  621. qprintf ("---- tjunc ----\n");
  622. c_tryedges = 0;
  623. c_degenerate = 0;
  624. c_facecollapse = 0;
  625. c_tjunctions = 0;
  626. if ( g_bAllowDetailCracks )
  627. {
  628. FixEdges_r (headnode);
  629. EmitLeafFaceVertexes( &pLeafFaceList );
  630. FixLeafFaceEdges( &pLeafFaceList );
  631. }
  632. else
  633. {
  634. EmitLeafFaceVertexes( &pLeafFaceList );
  635. if (!notjunc)
  636. {
  637. FixEdges_r (headnode);
  638. FixLeafFaceEdges( &pLeafFaceList );
  639. }
  640. }
  641. qprintf ("%i unique from %i\n", c_uniqueverts, c_totalverts);
  642. qprintf ("%5i edges degenerated\n", c_degenerate);
  643. qprintf ("%5i faces degenerated\n", c_facecollapse);
  644. qprintf ("%5i edges added by tjunctions\n", c_tjunctions);
  645. qprintf ("%5i faces added by tjunctions\n", c_faceoverflows);
  646. qprintf ("%5i bad start verts\n", c_badstartverts);
  647. return pLeafFaceList;
  648. }
  649. //========================================================
  650. int c_faces;
  651. face_t *AllocFace (void)
  652. {
  653. static int s_FaceId = 0;
  654. face_t *f;
  655. f = (face_t*)malloc(sizeof(*f));
  656. memset (f, 0, sizeof(*f));
  657. f->id = s_FaceId;
  658. ++s_FaceId;
  659. c_faces++;
  660. return f;
  661. }
  662. face_t *NewFaceFromFace (face_t *f)
  663. {
  664. face_t *newf;
  665. newf = AllocFace ();
  666. *newf = *f;
  667. newf->merged = NULL;
  668. newf->split[0] = newf->split[1] = NULL;
  669. newf->w = NULL;
  670. return newf;
  671. }
  672. void FreeFace (face_t *f)
  673. {
  674. if (f->w)
  675. FreeWinding (f->w);
  676. free (f);
  677. c_faces--;
  678. }
  679. void FreeFaceList( face_t *pFaces )
  680. {
  681. while ( pFaces )
  682. {
  683. face_t *next = pFaces->next;
  684. FreeFace( pFaces );
  685. pFaces = next;
  686. }
  687. }
  688. //========================================================
  689. void GetEdge2_InitOptimizedList()
  690. {
  691. for( int i=0; i < MAX_MAP_VERTS; i++ )
  692. g_VertEdgeList[i].RemoveAll();
  693. }
  694. void IntSort( CUtlVector<int> &theList )
  695. {
  696. for( int i=0; i < theList.Count()-1; i++ )
  697. {
  698. if( theList[i] > theList[i+1] )
  699. {
  700. int temp = theList[i];
  701. theList[i] = theList[i+1];
  702. theList[i+1] = temp;
  703. if( i > 0 )
  704. i -= 2;
  705. else
  706. i = -1;
  707. }
  708. }
  709. }
  710. int AddEdge( int v1, int v2, face_t *f )
  711. {
  712. if (numedges >= MAX_MAP_EDGES)
  713. Error ("Too many edges in map, max == %d", MAX_MAP_EDGES);
  714. g_VertEdgeList[v1].AddToTail( numedges );
  715. g_VertEdgeList[v2].AddToTail( numedges );
  716. IntSort( g_VertEdgeList[v1] );
  717. IntSort( g_VertEdgeList[v2] );
  718. dedge_t *edge = &dedges[numedges];
  719. numedges++;
  720. edge->v[0] = v1;
  721. edge->v[1] = v2;
  722. edgefaces[numedges-1][0] = f;
  723. return numedges - 1;
  724. }
  725. /*
  726. ==================
  727. GetEdge
  728. Called by writebsp.
  729. Don't allow four way edges
  730. ==================
  731. */
  732. int GetEdge2 (int v1, int v2, face_t *f)
  733. {
  734. dedge_t *edge;
  735. c_tryedges++;
  736. if (!noshare)
  737. {
  738. // Check all edges connected to v1.
  739. CUtlVector<int> &theList = g_VertEdgeList[v1];
  740. for( int i=0; i < theList.Count(); i++ )
  741. {
  742. int iEdge = theList[i];
  743. edge = &dedges[iEdge];
  744. if (v1 == edge->v[1] && v2 == edge->v[0] && edgefaces[iEdge][0]->contents == f->contents)
  745. {
  746. if (edgefaces[iEdge][1])
  747. continue;
  748. edgefaces[iEdge][1] = f;
  749. return -iEdge;
  750. }
  751. }
  752. }
  753. return AddEdge( v1, v2, f );
  754. }
  755. /*
  756. ===========================================================================
  757. FACE MERGING
  758. ===========================================================================
  759. */
  760. #define CONTINUOUS_EPSILON 0.001
  761. /*
  762. =============
  763. TryMergeWinding
  764. If two polygons share a common edge and the edges that meet at the
  765. common points are both inside the other polygons, merge them
  766. Returns NULL if the faces couldn't be merged, or the new face.
  767. The originals will NOT be freed.
  768. =============
  769. */
  770. winding_t *TryMergeWinding (winding_t *f1, winding_t *f2, Vector& planenormal)
  771. {
  772. Vector *p1, *p2, *p3, *p4, *back;
  773. winding_t *newf;
  774. int i, j, k, l;
  775. Vector normal, delta;
  776. vec_t dot;
  777. qboolean keep1, keep2;
  778. //
  779. // find a common edge
  780. //
  781. p1 = p2 = NULL; // stop compiler warning
  782. j = 0; //
  783. for (i=0 ; i<f1->numpoints ; i++)
  784. {
  785. p1 = &f1->p[i];
  786. p2 = &f1->p[(i+1)%f1->numpoints];
  787. for (j=0 ; j<f2->numpoints ; j++)
  788. {
  789. p3 = &f2->p[j];
  790. p4 = &f2->p[(j+1)%f2->numpoints];
  791. for (k=0 ; k<3 ; k++)
  792. {
  793. if (fabs((*p1)[k] - (*p4)[k]) > EQUAL_EPSILON)
  794. break;
  795. if (fabs((*p2)[k] - (*p3)[k]) > EQUAL_EPSILON)
  796. break;
  797. }
  798. if (k==3)
  799. break;
  800. }
  801. if (j < f2->numpoints)
  802. break;
  803. }
  804. if (i == f1->numpoints)
  805. return NULL; // no matching edges
  806. //
  807. // check slope of connected lines
  808. // if the slopes are colinear, the point can be removed
  809. //
  810. back = &f1->p[(i+f1->numpoints-1)%f1->numpoints];
  811. VectorSubtract (*p1, *back, delta);
  812. CrossProduct (planenormal, delta, normal);
  813. VectorNormalize (normal);
  814. back = &f2->p[(j+2)%f2->numpoints];
  815. VectorSubtract (*back, *p1, delta);
  816. dot = DotProduct (delta, normal);
  817. if (dot > CONTINUOUS_EPSILON)
  818. return NULL; // not a convex polygon
  819. keep1 = (qboolean)(dot < -CONTINUOUS_EPSILON);
  820. back = &f1->p[(i+2)%f1->numpoints];
  821. VectorSubtract (*back, *p2, delta);
  822. CrossProduct (planenormal, delta, normal);
  823. VectorNormalize (normal);
  824. back = &f2->p[(j+f2->numpoints-1)%f2->numpoints];
  825. VectorSubtract (*back, *p2, delta);
  826. dot = DotProduct (delta, normal);
  827. if (dot > CONTINUOUS_EPSILON)
  828. return NULL; // not a convex polygon
  829. keep2 = (qboolean)(dot < -CONTINUOUS_EPSILON);
  830. //
  831. // build the new polygon
  832. //
  833. newf = AllocWinding (f1->numpoints + f2->numpoints);
  834. // copy first polygon
  835. for (k=(i+1)%f1->numpoints ; k != i ; k=(k+1)%f1->numpoints)
  836. {
  837. if (k==(i+1)%f1->numpoints && !keep2)
  838. continue;
  839. VectorCopy (f1->p[k], newf->p[newf->numpoints]);
  840. newf->numpoints++;
  841. }
  842. // copy second polygon
  843. for (l= (j+1)%f2->numpoints ; l != j ; l=(l+1)%f2->numpoints)
  844. {
  845. if (l==(j+1)%f2->numpoints && !keep1)
  846. continue;
  847. VectorCopy (f2->p[l], newf->p[newf->numpoints]);
  848. newf->numpoints++;
  849. }
  850. return newf;
  851. }
  852. //-----------------------------------------------------------------------------
  853. // Purpose:
  854. //-----------------------------------------------------------------------------
  855. bool OverlaysAreEqual( face_t *f1, face_t *f2 )
  856. {
  857. // Check the overlay ids - see if they are the same.
  858. if ( f1->originalface->aOverlayIds.Count() != f2->originalface->aOverlayIds.Count() )
  859. return false;
  860. int nOverlayCount = f1->originalface->aOverlayIds.Count();
  861. for ( int iOverlay = 0; iOverlay < nOverlayCount; ++iOverlay )
  862. {
  863. int nOverlayId = f1->originalface->aOverlayIds[iOverlay];
  864. if ( f2->originalface->aOverlayIds.Find( nOverlayId ) == -1 )
  865. return false;
  866. }
  867. return true;
  868. }
  869. //-----------------------------------------------------------------------------
  870. // Purpose:
  871. //-----------------------------------------------------------------------------
  872. bool FaceOnWaterBrush( face_t *face )
  873. {
  874. side_t *pSide = face->originalface;
  875. if ( !pSide )
  876. return false;
  877. if ( pSide->contents & ( CONTENTS_WATER | CONTENTS_SLIME ) )
  878. return true;
  879. return false;
  880. }
  881. /*
  882. =============
  883. TryMerge
  884. If two polygons share a common edge and the edges that meet at the
  885. common points are both inside the other polygons, merge them
  886. Returns NULL if the faces couldn't be merged, or the new face.
  887. The originals will NOT be freed.
  888. =============
  889. */
  890. face_t *TryMerge (face_t *f1, face_t *f2, Vector& planenormal)
  891. {
  892. face_t *newf;
  893. winding_t *nw;
  894. if (!f1->w || !f2->w)
  895. return NULL;
  896. if (f1->texinfo != f2->texinfo)
  897. return NULL;
  898. if (f1->planenum != f2->planenum) // on front and back sides
  899. return NULL;
  900. if (f1->contents != f2->contents)
  901. return NULL;
  902. if ( f1->originalface->smoothingGroups != f2->originalface->smoothingGroups )
  903. return NULL;
  904. if ( !OverlaysAreEqual( f1, f2 ) )
  905. return NULL;
  906. if ( nomergewater && ( FaceOnWaterBrush( f1 ) || FaceOnWaterBrush( f2 ) ) )
  907. return NULL;
  908. nw = TryMergeWinding (f1->w, f2->w, planenormal);
  909. if (!nw)
  910. return NULL;
  911. c_merge++;
  912. newf = NewFaceFromFace (f1);
  913. newf->w = nw;
  914. // ----------------------------------------------------------------------------
  915. // NOTE: Keep this list so we can build the face->brush map for portal2
  916. // this lets us know every brush that contributed a chunk of this merged face
  917. newf->pMergedList = new CUtlVector<side_t *>;
  918. newf->pMergedList->AddToTail( f1->originalface );
  919. newf->pMergedList->AddToTail( f2->originalface );
  920. if ( f1->pMergedList )
  921. {
  922. newf->pMergedList->AddVectorToTail( *f1->pMergedList );
  923. delete f1->pMergedList;
  924. f1->pMergedList = NULL;
  925. }
  926. if ( f2->pMergedList )
  927. {
  928. newf->pMergedList->AddVectorToTail( *f2->pMergedList );
  929. delete f2->pMergedList;
  930. f2->pMergedList = NULL;
  931. }
  932. // ----------------------------------------------------------------------------
  933. f1->merged = newf;
  934. f2->merged = newf;
  935. return newf;
  936. }
  937. /*
  938. ===============
  939. MergeFaceList
  940. ===============
  941. */
  942. void MergeFaceList(face_t **pList)
  943. {
  944. face_t *f1, *f2, *end;
  945. face_t *merged;
  946. plane_t *plane;
  947. merged = NULL;
  948. for (f1 = *pList; f1 ; f1 = f1->next)
  949. {
  950. if (f1->merged || f1->split[0] || f1->split[1])
  951. continue;
  952. for (f2 = *pList; f2 != f1 ; f2=f2->next)
  953. {
  954. if (f2->merged || f2->split[0] || f2->split[1])
  955. continue;
  956. plane = &g_MainMap->mapplanes[f1->planenum];
  957. merged = TryMerge (f1, f2, plane->normal);
  958. if (!merged)
  959. continue;
  960. // add merged to the end of the face list
  961. // so it will be checked against all the faces again
  962. for (end = *pList; end->next ; end = end->next)
  963. ;
  964. merged->next = NULL;
  965. end->next = merged;
  966. break;
  967. }
  968. }
  969. }
  970. //=====================================================================
  971. /*
  972. ===============
  973. SubdivideFace
  974. Chop up faces that are larger than we want in the surface cache
  975. ===============
  976. */
  977. void SubdivideFace (face_t **pFaceList, face_t *f)
  978. {
  979. float mins, maxs;
  980. vec_t v;
  981. vec_t luxelsPerWorldUnit;
  982. int axis, i;
  983. texinfo_t *tex;
  984. Vector temp;
  985. vec_t dist;
  986. winding_t *w, *frontw, *backw;
  987. if ( f->merged || f->split[0] || f->split[1] )
  988. return;
  989. // special (non-surface cached) faces don't need subdivision
  990. tex = &texinfo[f->texinfo];
  991. if( tex->flags & SURF_NOLIGHT )
  992. {
  993. return;
  994. }
  995. for (axis = 0 ; axis < 2 ; axis++)
  996. {
  997. while (1)
  998. {
  999. mins = 999999;
  1000. maxs = -999999;
  1001. VECTOR_COPY (tex->lightmapVecsLuxelsPerWorldUnits[axis], temp);
  1002. w = f->w;
  1003. for (i=0 ; i<w->numpoints ; i++)
  1004. {
  1005. v = DotProduct (w->p[i], temp);
  1006. if (v < mins)
  1007. mins = v;
  1008. if (v > maxs)
  1009. maxs = v;
  1010. }
  1011. #if 0
  1012. if (maxs - mins <= 0)
  1013. Error ("zero extents");
  1014. #endif
  1015. if (maxs - mins <= g_maxLightmapDimension)
  1016. break;
  1017. // split it
  1018. c_subdivide++;
  1019. luxelsPerWorldUnit = VectorNormalize (temp);
  1020. dist = ( mins + g_maxLightmapDimension - 1 ) / luxelsPerWorldUnit;
  1021. ClipWindingEpsilon (w, temp, dist, ON_EPSILON, &frontw, &backw);
  1022. if (!frontw || !backw)
  1023. Error ("SubdivideFace: didn't split the polygon");
  1024. f->split[0] = NewFaceFromFace (f);
  1025. f->split[0]->w = frontw;
  1026. f->split[0]->next = *pFaceList;
  1027. *pFaceList = f->split[0];
  1028. f->split[1] = NewFaceFromFace (f);
  1029. f->split[1]->w = backw;
  1030. f->split[1]->next = *pFaceList;
  1031. *pFaceList = f->split[1];
  1032. SubdivideFace (pFaceList, f->split[0]);
  1033. SubdivideFace (pFaceList, f->split[1]);
  1034. return;
  1035. }
  1036. }
  1037. }
  1038. void SubdivideFaceList(face_t **pFaceList)
  1039. {
  1040. face_t *f;
  1041. for (f = *pFaceList ; f ; f=f->next)
  1042. {
  1043. SubdivideFace (pFaceList, f);
  1044. }
  1045. }
  1046. //-----------------------------------------------------------------------------
  1047. // Assigns the bottom material to the bottom face
  1048. //-----------------------------------------------------------------------------
  1049. static bool AssignBottomWaterMaterialToFace( face_t *f )
  1050. {
  1051. // NOTE: This happens *after* cubemap fixup occurs, so we need to get the
  1052. // fixed-up bottom material for this
  1053. texinfo_t *pTexInfo = &texinfo[f->texinfo];
  1054. dtexdata_t *pTexData = GetTexData( pTexInfo->texdata );
  1055. const char *pMaterialName = TexDataStringTable_GetString( pTexData->nameStringTableID );
  1056. char pBottomMatName[512];
  1057. if ( !GetValueFromPatchedMaterial( pMaterialName, "$bottommaterial", pBottomMatName, 512 ) )
  1058. {
  1059. if( !Q_stristr( pMaterialName, "nodraw" ) && !Q_stristr( pMaterialName, "toolsskip" ) )
  1060. {
  1061. Warning("error: material %s doesn't have a $bottommaterial\n", pMaterialName );
  1062. }
  1063. return false;
  1064. }
  1065. //Assert( mapplanes[f->planenum].normal.z < 0 );
  1066. texinfo_t newTexInfo;
  1067. newTexInfo.flags = pTexInfo->flags;
  1068. int j, k;
  1069. for (j=0 ; j<2 ; j++)
  1070. {
  1071. for (k=0 ; k<4 ; k++)
  1072. {
  1073. newTexInfo.textureVecsTexelsPerWorldUnits[j][k] = pTexInfo->textureVecsTexelsPerWorldUnits[j][k];
  1074. newTexInfo.lightmapVecsLuxelsPerWorldUnits[j][k] = pTexInfo->lightmapVecsLuxelsPerWorldUnits[j][k];
  1075. }
  1076. }
  1077. newTexInfo.texdata = FindOrCreateTexData( pBottomMatName );
  1078. f->texinfo = FindOrCreateTexInfo( newTexInfo );
  1079. return true;
  1080. }
  1081. //===========================================================================
  1082. int c_nodefaces;
  1083. static void SubdivideFaceBySubdivSize( face_t *f, float subdivsize );
  1084. void SubdivideFaceBySubdivSize( face_t *f );
  1085. /*
  1086. ============
  1087. FaceFromPortal
  1088. ============
  1089. */
  1090. extern int FindOrCreateTexInfo( const texinfo_t &searchTexInfo );
  1091. face_t *FaceFromPortal (portal_t *p, int pside)
  1092. {
  1093. face_t *f;
  1094. side_t *side;
  1095. int deltaContents;
  1096. // portal does not bridge different visible contents
  1097. side = p->side;
  1098. if (!side)
  1099. return NULL;
  1100. // allocate a new face
  1101. f = AllocFace();
  1102. // save the original "side" from the map brush -- portal->side
  1103. // see FindPortalSide(...)
  1104. f->originalface = side;
  1105. //
  1106. // save material info
  1107. //
  1108. f->texinfo = side->texinfo;
  1109. f->dispinfo = -1; // all faces with displacement info are created elsewhere
  1110. f->smoothingGroups = side->smoothingGroups;
  1111. // save plane info
  1112. f->planenum = (side->planenum & ~1) | pside;
  1113. if ( entity_num != 0 )
  1114. {
  1115. // the brush model renderer doesn't use PLANEBACK, so write the real plane
  1116. // inside water faces can be flipped because they are generated on the inside of the brush
  1117. if ( p->nodes[pside]->contents & (CONTENTS_WATER|CONTENTS_SLIME) )
  1118. {
  1119. f->planenum = (side->planenum & ~1) | pside;
  1120. }
  1121. else
  1122. {
  1123. f->planenum = side->planenum;
  1124. }
  1125. }
  1126. // save portal info
  1127. f->portal = p;
  1128. f->fogVolumeLeaf = NULL;
  1129. deltaContents = VisibleContents(p->nodes[!pside]->contents^p->nodes[pside]->contents);
  1130. // don't show insides of windows or grates
  1131. if ( ((p->nodes[pside]->contents & CONTENTS_WINDOW) && deltaContents == CONTENTS_WINDOW) ||
  1132. ((p->nodes[pside]->contents & CONTENTS_GRATE) && deltaContents == CONTENTS_GRATE) )
  1133. {
  1134. FreeFace( f );
  1135. return NULL;
  1136. }
  1137. if ( p->nodes[pside]->contents & MASK_WATER )
  1138. {
  1139. f->fogVolumeLeaf = p->nodes[pside];
  1140. }
  1141. else if ( p->nodes[!pside]->contents & MASK_WATER )
  1142. {
  1143. f->fogVolumeLeaf = p->nodes[!pside];
  1144. }
  1145. // If it's the underside of water, we need to figure out what material to use, etc.
  1146. if( ( p->nodes[pside]->contents & CONTENTS_WATER ) && deltaContents == CONTENTS_WATER )
  1147. {
  1148. if ( !AssignBottomWaterMaterialToFace( f ) )
  1149. {
  1150. FreeFace( f );
  1151. return NULL;
  1152. }
  1153. }
  1154. //
  1155. // generate the winding for the face and save face contents
  1156. //
  1157. if( pside )
  1158. {
  1159. f->w = ReverseWinding(p->winding);
  1160. f->contents = p->nodes[1]->contents;
  1161. }
  1162. else
  1163. {
  1164. f->w = CopyWinding(p->winding);
  1165. f->contents = p->nodes[0]->contents;
  1166. }
  1167. f->numPrims = 0;
  1168. f->firstPrimID = 0;
  1169. // return the created face
  1170. return f;
  1171. }
  1172. /*
  1173. ===============
  1174. MakeFaces_r
  1175. If a portal will make a visible face,
  1176. mark the side that originally created it
  1177. solid / empty : solid
  1178. solid / water : solid
  1179. water / empty : water
  1180. water / water : none
  1181. ===============
  1182. */
  1183. void MakeFaces_r (node_t *node)
  1184. {
  1185. portal_t *p;
  1186. int s;
  1187. // recurse down to leafs
  1188. if (node->planenum != PLANENUM_LEAF)
  1189. {
  1190. MakeFaces_r (node->children[0]);
  1191. MakeFaces_r (node->children[1]);
  1192. // merge together all visible faces on the node
  1193. if (!nomerge)
  1194. MergeFaceList(&node->faces);
  1195. if (!nosubdiv)
  1196. SubdivideFaceList(&node->faces);
  1197. return;
  1198. }
  1199. // solid leafs never have visible faces
  1200. if (node->contents & CONTENTS_SOLID)
  1201. return;
  1202. // see which portals are valid
  1203. for (p=node->portals ; p ; p = p->next[s])
  1204. {
  1205. s = (p->nodes[1] == node);
  1206. p->face[s] = FaceFromPortal (p, s);
  1207. if (p->face[s])
  1208. {
  1209. c_nodefaces++;
  1210. p->face[s]->next = p->onnode->faces;
  1211. p->onnode->faces = p->face[s];
  1212. }
  1213. }
  1214. }
  1215. typedef winding_t *pwinding_t;
  1216. static void PrintWinding( winding_t *w )
  1217. {
  1218. int i;
  1219. Msg( "\t---\n" );
  1220. for( i = 0; i < w->numpoints; i++ )
  1221. {
  1222. Msg( "\t%f %f %f\n", w->p[i].x, w->p[i].y, w->p[i].z );
  1223. }
  1224. }
  1225. //-----------------------------------------------------------------------------
  1226. // Purpose: Adds a winding to the current list of primverts
  1227. // Input : *w - the winding
  1228. // *pIndices - The output indices
  1229. // vertStart - the starting vert index
  1230. // vertCount - current count
  1231. // Output : int - output count including new verts from this winding
  1232. //-----------------------------------------------------------------------------
  1233. int AddWindingToPrimverts( const winding_t *w, unsigned short *pIndices, int vertStart, int vertCount )
  1234. {
  1235. for( int i = 0; i < w->numpoints; i++ )
  1236. {
  1237. int j;
  1238. for( j = vertStart; j < vertStart + vertCount; j++ )
  1239. {
  1240. Vector tmp = g_primverts[j].pos - w->p[i];
  1241. if( tmp.LengthSqr() < POINT_EPSILON*POINT_EPSILON )
  1242. {
  1243. pIndices[i] = j;
  1244. break;
  1245. }
  1246. }
  1247. if ( j >= vertStart + vertCount )
  1248. {
  1249. pIndices[i] = j;
  1250. g_primverts[j].pos = w->p[i];
  1251. vertCount++;
  1252. g_numprimverts++;
  1253. if ( g_numprimverts > MAX_MAP_PRIMVERTS )
  1254. {
  1255. Error( "Exceeded max water verts.\nIncrease surface subdivision size or lower your subdivision size in vmt files! (%d>%d)\n",
  1256. ( int )g_numprimverts, ( int )MAX_MAP_PRIMVERTS );
  1257. }
  1258. }
  1259. }
  1260. return vertCount;
  1261. }
  1262. #pragma optimize( "g", off )
  1263. #define USE_TRISTRIPS
  1264. // UNDONE: Should split this function into subdivide and primitive building parts
  1265. // UNDONE: We should try building strips of shared verts for all water faces in a leaf
  1266. // since those will be drawn concurrently anyway. It should be more efficient.
  1267. static void SubdivideFaceBySubdivSize( face_t *f, float subdivsize )
  1268. {
  1269. // garymcthack - REFACTOR ME!!!
  1270. vec_t dummy;
  1271. Vector hackNormal;
  1272. WindingPlane( f->w, hackNormal, &dummy );
  1273. // HACK - only subdivide stuff that is facing up or down (for water)
  1274. if( fabs(hackNormal[2]) < .9f )
  1275. {
  1276. return;
  1277. }
  1278. // Get the extents of the surface.
  1279. // garymcthack - this assumes a surface of constant z for now (for water). . can generalize later.
  1280. subdivsize = ( int )subdivsize;
  1281. winding_t *w;
  1282. w = CopyWinding( f->w );
  1283. Vector min, max;
  1284. WindingBounds( w, min, max );
  1285. #if 0
  1286. Msg( "START WINDING: \n" );
  1287. PrintWinding( w );
  1288. #endif
  1289. int xStart, yStart, xEnd, yEnd, xSteps, ySteps;
  1290. xStart = ( int )subdivsize * ( int )( ( min[0] - subdivsize ) / subdivsize );
  1291. xEnd = ( int )subdivsize * ( int )( ( max[0] + subdivsize ) / subdivsize );
  1292. yStart = ( int )subdivsize * ( int )( ( min[1] - subdivsize ) / subdivsize );
  1293. yEnd = ( int )subdivsize * ( int )( ( max[1] + subdivsize ) / subdivsize );
  1294. xSteps = ( xEnd - xStart ) / subdivsize;
  1295. ySteps = ( yEnd - yStart ) / subdivsize;
  1296. int x, y;
  1297. int xi, yi;
  1298. winding_t **windings = ( winding_t ** )new pwinding_t[xSteps * ySteps];
  1299. memset( windings, 0, sizeof( winding_t * ) * xSteps * ySteps );
  1300. for( yi = 0, y = yStart; y < yEnd; y += ( int )subdivsize, yi++ )
  1301. {
  1302. for( xi = 0, x = xStart; x < xEnd; x += ( int )subdivsize, xi++ )
  1303. {
  1304. winding_t *tempWinding, *frontWinding, *backWinding;
  1305. float planeDist;
  1306. Vector normal;
  1307. normal.Init( 1.0f, 0.0f, 0.0f );
  1308. planeDist = ( float )x;
  1309. tempWinding = CopyWinding( w );
  1310. ClipWindingEpsilon( tempWinding, normal, planeDist, ON_EPSILON,
  1311. &frontWinding, &backWinding );
  1312. if( tempWinding )
  1313. {
  1314. FreeWinding( tempWinding );
  1315. }
  1316. if( backWinding )
  1317. {
  1318. FreeWinding( backWinding );
  1319. }
  1320. if( !frontWinding )
  1321. {
  1322. continue;
  1323. }
  1324. tempWinding = frontWinding;
  1325. normal.Init( -1.0f, 0.0f, 0.0f );
  1326. planeDist = -( float )( x + subdivsize );
  1327. ClipWindingEpsilon( tempWinding, normal, planeDist, ON_EPSILON,
  1328. &frontWinding, &backWinding );
  1329. if( tempWinding )
  1330. {
  1331. FreeWinding( tempWinding );
  1332. }
  1333. if( backWinding )
  1334. {
  1335. FreeWinding( backWinding );
  1336. }
  1337. if( !frontWinding )
  1338. {
  1339. continue;
  1340. }
  1341. tempWinding = frontWinding;
  1342. normal.Init( 0.0f, 1.0f, 0.0f );
  1343. planeDist = ( float )y;
  1344. ClipWindingEpsilon( tempWinding, normal, planeDist, ON_EPSILON,
  1345. &frontWinding, &backWinding );
  1346. if( tempWinding )
  1347. {
  1348. FreeWinding( tempWinding );
  1349. }
  1350. if( backWinding )
  1351. {
  1352. FreeWinding( backWinding );
  1353. }
  1354. if( !frontWinding )
  1355. {
  1356. continue;
  1357. }
  1358. tempWinding = frontWinding;
  1359. normal.Init( 0.0f, -1.0f, 0.0f );
  1360. planeDist = -( float )( y + subdivsize );
  1361. ClipWindingEpsilon( tempWinding, normal, planeDist, ON_EPSILON,
  1362. &frontWinding, &backWinding );
  1363. if( tempWinding )
  1364. {
  1365. FreeWinding( tempWinding );
  1366. }
  1367. if( backWinding )
  1368. {
  1369. FreeWinding( backWinding );
  1370. }
  1371. if( !frontWinding )
  1372. {
  1373. continue;
  1374. }
  1375. #if 0
  1376. Msg( "output winding:\n" );
  1377. PrintWinding( frontWinding );
  1378. #endif
  1379. if( frontWinding )
  1380. {
  1381. windings[xi + yi * xSteps] = frontWinding;
  1382. }
  1383. }
  1384. }
  1385. FreeWinding( w );
  1386. dprimitive_t &newPrim = g_primitives[g_numprimitives];
  1387. f->firstPrimID = g_numprimitives;
  1388. f->numPrims = 1;
  1389. newPrim.firstIndex = g_numprimindices;
  1390. newPrim.firstVert = g_numprimverts;
  1391. newPrim.indexCount = 0;
  1392. newPrim.vertCount = 0;
  1393. #ifdef USE_TRISTRIPS
  1394. newPrim.type = PRIM_TRISTRIP;
  1395. #else
  1396. newPrim.type = PRIM_TRILIST;
  1397. #endif
  1398. CUtlVector<WORD> triListIndices;
  1399. int i;
  1400. for( i = 0; i < xSteps * ySteps; i++ )
  1401. {
  1402. if( !windings[i] )
  1403. {
  1404. continue;
  1405. }
  1406. unsigned short *pIndices =
  1407. ( unsigned short * )_alloca( windings[i]->numpoints * sizeof( unsigned short ) );
  1408. // find indices for the verts.
  1409. newPrim.vertCount = AddWindingToPrimverts( windings[i], pIndices, newPrim.firstVert, newPrim.vertCount );
  1410. // Now that we have indices for the verts, fan-tesselate the polygon and spit out tris.
  1411. for( int j = 0; j < windings[i]->numpoints - 2; j++ )
  1412. {
  1413. triListIndices.AddToTail( pIndices[0] );
  1414. triListIndices.AddToTail( pIndices[j+1] );
  1415. triListIndices.AddToTail( pIndices[j+2] );
  1416. }
  1417. }
  1418. delete [] windings;
  1419. // We've already updated the verts and have a trilist. . let's strip it!
  1420. if( !triListIndices.Count() )
  1421. {
  1422. return;
  1423. }
  1424. #ifdef USE_TRISTRIPS
  1425. int numTristripIndices;
  1426. WORD *pStripIndices = NULL;
  1427. Stripify( triListIndices.Count() / 3, triListIndices.Base(), &numTristripIndices,
  1428. &pStripIndices );
  1429. Assert( pStripIndices );
  1430. // FIXME: Should also call ComputeVertexPermutation and reorder the verts.
  1431. for( i = 0; i < numTristripIndices; i++ )
  1432. {
  1433. Assert( pStripIndices[i] >= newPrim.firstVert &&
  1434. pStripIndices[i] < newPrim.firstVert + newPrim.vertCount );
  1435. g_primindices[newPrim.firstIndex + newPrim.indexCount] = pStripIndices[i];
  1436. newPrim.indexCount++;
  1437. g_numprimindices++;
  1438. if( g_numprimindices > MAX_MAP_PRIMINDICES )
  1439. {
  1440. Error( "Exceeded max water indicies.\nIncrease surface subdivision size! (%d>%d)\n", g_numprimindices, MAX_MAP_PRIMINDICES );
  1441. }
  1442. }
  1443. delete [] pStripIndices;
  1444. #else
  1445. for( i = 0; i < triListIndices.Size(); i++ )
  1446. {
  1447. g_primindices[newPrim.firstIndex + newPrim.indexCount] = triListIndices[i];
  1448. newPrim.indexCount++;
  1449. g_numprimindices++;
  1450. if( g_numprimindices > MAX_MAP_PRIMINDICES )
  1451. {
  1452. Error( "Exceeded max water indicies.\nIncrease surface subdivision size! (%d>%d)\n", g_numprimindices, MAX_MAP_PRIMINDICES );
  1453. }
  1454. }
  1455. #endif
  1456. g_numprimitives++; // don't increment until we get here and are sure that we have a primitive.
  1457. if( g_numprimitives > MAX_MAP_PRIMITIVES )
  1458. {
  1459. Error( "Exceeded max water primitives.\nIncrease surface subdivision size! (%d>%d)\n", ( int )g_numprimitives, ( int )MAX_MAP_PRIMITIVES );
  1460. }
  1461. }
  1462. void SubdivideFaceBySubdivSize( face_t *f )
  1463. {
  1464. if( f->numpoints == 0 || f->split[0] || f->split[1] || f->merged || !f->w )
  1465. {
  1466. return;
  1467. }
  1468. // see if the face needs to be subdivided.
  1469. texinfo_t *pTexInfo = &texinfo[f->texinfo];
  1470. dtexdata_t *pTexData = GetTexData( pTexInfo->texdata );
  1471. bool bFound;
  1472. const char *pMaterialName = TexDataStringTable_GetString( pTexData->nameStringTableID );
  1473. MaterialSystemMaterial_t matID =
  1474. FindOriginalMaterial( pMaterialName, &bFound, false );
  1475. if( !bFound )
  1476. {
  1477. return;
  1478. }
  1479. const char *subdivsizeString = GetMaterialVar( matID, "$subdivsize" );
  1480. if( subdivsizeString )
  1481. {
  1482. float subdivSize = atof( subdivsizeString );
  1483. if( subdivSize > 0.0f )
  1484. {
  1485. // NOTE: Subdivision is unsupported and should be phased out
  1486. Warning("Using subdivision on %s\n", pMaterialName );
  1487. SubdivideFaceBySubdivSize( f, subdivSize );
  1488. }
  1489. }
  1490. }
  1491. void SplitSubdividedFaces_Node_r( node_t *node )
  1492. {
  1493. if (node->planenum == PLANENUM_LEAF)
  1494. {
  1495. return;
  1496. }
  1497. face_t *f;
  1498. for( f = node->faces; f ;f = f->next )
  1499. {
  1500. SubdivideFaceBySubdivSize( f );
  1501. }
  1502. //
  1503. // recursively output the other nodes
  1504. //
  1505. SplitSubdividedFaces_Node_r( node->children[0] );
  1506. SplitSubdividedFaces_Node_r( node->children[1] );
  1507. }
  1508. void SplitSubdividedFaces( face_t *pLeafFaceList, node_t *headnode )
  1509. {
  1510. // deal with leaf faces.
  1511. face_t *f = pLeafFaceList;
  1512. while ( f )
  1513. {
  1514. SubdivideFaceBySubdivSize( f );
  1515. f = f->next;
  1516. }
  1517. // deal with node faces.
  1518. SplitSubdividedFaces_Node_r( headnode );
  1519. }
  1520. #pragma optimize( "", on )
  1521. /*
  1522. ============
  1523. MakeFaces
  1524. ============
  1525. */
  1526. void MakeFaces (node_t *node)
  1527. {
  1528. qprintf ("--- MakeFaces ---\n");
  1529. c_merge = 0;
  1530. c_subdivide = 0;
  1531. c_nodefaces = 0;
  1532. MakeFaces_r (node);
  1533. qprintf ("%5i makefaces\n", c_nodefaces);
  1534. qprintf ("%5i merged\n", c_merge);
  1535. qprintf ("%5i subdivided\n", c_subdivide);
  1536. }