surface.c 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159
  1. /*
  2. ===========================================================================
  3. Copyright (C) 1999-2005 Id Software, Inc.
  4. This file is part of Quake III Arena source code.
  5. Quake III Arena source code is free software; you can redistribute it
  6. and/or modify it under the terms of the GNU General Public License as
  7. published by the Free Software Foundation; either version 2 of the License,
  8. or (at your option) any later version.
  9. Quake III Arena source code is distributed in the hope that it will be
  10. useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. GNU General Public License for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with Foobar; if not, write to the Free Software
  15. Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
  16. ===========================================================================
  17. */
  18. #include "qbsp.h"
  19. mapDrawSurface_t mapDrawSurfs[MAX_MAP_DRAW_SURFS];
  20. int numMapDrawSurfs;
  21. /*
  22. =============================================================================
  23. DRAWSURF CONSTRUCTION
  24. =============================================================================
  25. */
  26. /*
  27. =================
  28. AllocDrawSurf
  29. =================
  30. */
  31. mapDrawSurface_t *AllocDrawSurf( void ) {
  32. mapDrawSurface_t *ds;
  33. if ( numMapDrawSurfs >= MAX_MAP_DRAW_SURFS ) {
  34. Error( "MAX_MAP_DRAW_SURFS");
  35. }
  36. ds = &mapDrawSurfs[ numMapDrawSurfs ];
  37. numMapDrawSurfs++;
  38. return ds;
  39. }
  40. /*
  41. =================
  42. DrawSurfaceForSide
  43. =================
  44. */
  45. #define SNAP_FLOAT_TO_INT 8
  46. #define SNAP_INT_TO_FLOAT (1.0/SNAP_FLOAT_TO_INT)
  47. mapDrawSurface_t *DrawSurfaceForSide( bspbrush_t *b, side_t *s, winding_t *w ) {
  48. mapDrawSurface_t *ds;
  49. int i, j;
  50. shaderInfo_t *si;
  51. drawVert_t *dv;
  52. float mins[2], maxs[2];
  53. // brush primitive :
  54. // axis base
  55. vec3_t texX,texY;
  56. vec_t x,y;
  57. if ( w->numpoints > 64 ) {
  58. Error( "DrawSurfaceForSide: w->numpoints = %i", w->numpoints );
  59. }
  60. si = s->shaderInfo;
  61. ds = AllocDrawSurf();
  62. ds->shaderInfo = si;
  63. ds->mapBrush = b;
  64. ds->side = s;
  65. ds->fogNum = -1;
  66. ds->numVerts = w->numpoints;
  67. ds->verts = malloc( ds->numVerts * sizeof( *ds->verts ) );
  68. memset( ds->verts, 0, ds->numVerts * sizeof( *ds->verts ) );
  69. mins[0] = mins[1] = 99999;
  70. maxs[0] = maxs[1] = -99999;
  71. // compute s/t coordinates from brush primitive texture matrix
  72. // compute axis base
  73. ComputeAxisBase( mapplanes[s->planenum].normal, texX, texY );
  74. for ( j = 0 ; j < w->numpoints ; j++ ) {
  75. dv = ds->verts + j;
  76. // round the xyz to a given precision
  77. for ( i = 0 ; i < 3 ; i++ ) {
  78. dv->xyz[i] = SNAP_INT_TO_FLOAT * floor( w->p[j][i] * SNAP_FLOAT_TO_INT + 0.5 );
  79. }
  80. if (g_bBrushPrimit==BPRIMIT_OLDBRUSHES)
  81. {
  82. // calculate texture s/t
  83. dv->st[0] = s->vecs[0][3] + DotProduct( s->vecs[0], dv->xyz );
  84. dv->st[1] = s->vecs[1][3] + DotProduct( s->vecs[1], dv->xyz );
  85. dv->st[0] /= si->width;
  86. dv->st[1] /= si->height;
  87. }
  88. else
  89. {
  90. // calculate texture s/t from brush primitive texture matrix
  91. x = DotProduct( dv->xyz, texX );
  92. y = DotProduct( dv->xyz, texY );
  93. dv->st[0]=s->texMat[0][0]*x+s->texMat[0][1]*y+s->texMat[0][2];
  94. dv->st[1]=s->texMat[1][0]*x+s->texMat[1][1]*y+s->texMat[1][2];
  95. }
  96. for ( i = 0 ; i < 2 ; i++ ) {
  97. if ( dv->st[i] < mins[i] ) {
  98. mins[i] = dv->st[i];
  99. }
  100. if ( dv->st[i] > maxs[i] ) {
  101. maxs[i] = dv->st[i];
  102. }
  103. }
  104. // copy normal
  105. VectorCopy ( mapplanes[s->planenum].normal, dv->normal );
  106. }
  107. // adjust the texture coordinates to be as close to 0 as possible
  108. if ( !si->globalTexture ) {
  109. mins[0] = floor( mins[0] );
  110. mins[1] = floor( mins[1] );
  111. for ( i = 0 ; i < w->numpoints ; i++ ) {
  112. dv = ds->verts + i;
  113. dv->st[0] -= mins[0];
  114. dv->st[1] -= mins[1];
  115. }
  116. }
  117. return ds;
  118. }
  119. //=========================================================================
  120. typedef struct {
  121. int planenum;
  122. shaderInfo_t *shaderInfo;
  123. int count;
  124. } sideRef_t;
  125. #define MAX_SIDE_REFS MAX_MAP_PLANES
  126. sideRef_t sideRefs[MAX_SIDE_REFS];
  127. int numSideRefs;
  128. void AddSideRef( side_t *side ) {
  129. int i;
  130. for ( i = 0 ; i < numSideRefs ; i++ ) {
  131. if ( side->planenum == sideRefs[i].planenum
  132. && side->shaderInfo == sideRefs[i].shaderInfo ) {
  133. sideRefs[i].count++;
  134. return;
  135. }
  136. }
  137. if ( numSideRefs == MAX_SIDE_REFS ) {
  138. Error( "MAX_SIDE_REFS" );
  139. }
  140. sideRefs[i].planenum = side->planenum;
  141. sideRefs[i].shaderInfo = side->shaderInfo;
  142. sideRefs[i].count++;
  143. numSideRefs++;
  144. }
  145. /*
  146. =====================
  147. MergeSides
  148. =====================
  149. */
  150. void MergeSides( entity_t *e, tree_t *tree ) {
  151. int i;
  152. qprintf( "----- MergeSides -----\n");
  153. for ( i = e->firstDrawSurf ; i < numMapDrawSurfs ; i++ ) {
  154. // AddSideRef( side );
  155. }
  156. qprintf( "%5i siderefs\n", numSideRefs );
  157. }
  158. //=====================================================================
  159. /*
  160. ===================
  161. SubdivideDrawSurf
  162. ===================
  163. */
  164. void SubdivideDrawSurf( mapDrawSurface_t *ds, winding_t *w, float subdivisions ) {
  165. int i;
  166. int axis;
  167. vec3_t bounds[2];
  168. const float epsilon = 0.1;
  169. int subFloor, subCeil;
  170. winding_t *frontWinding, *backWinding;
  171. mapDrawSurface_t *newds;
  172. if ( !w ) {
  173. return;
  174. }
  175. if ( w->numpoints < 3 ) {
  176. Error( "SubdivideDrawSurf: Bad w->numpoints" );
  177. }
  178. ClearBounds( bounds[0], bounds[1] );
  179. for ( i = 0 ; i < w->numpoints ; i++ ) {
  180. AddPointToBounds( w->p[i], bounds[0], bounds[1] );
  181. }
  182. for ( axis = 0 ; axis < 3 ; axis++ ) {
  183. vec3_t planePoint = { 0, 0, 0 };
  184. vec3_t planeNormal = { 0, 0, 0 };
  185. float d;
  186. subFloor = floor( bounds[0][axis] / subdivisions ) * subdivisions;
  187. subCeil = ceil( bounds[1][axis] / subdivisions ) * subdivisions;
  188. planePoint[axis] = subFloor + subdivisions;
  189. planeNormal[axis] = -1;
  190. d = DotProduct( planePoint, planeNormal );
  191. // subdivide if necessary
  192. if ( subCeil - subFloor > subdivisions ) {
  193. // gotta clip polygon into two polygons
  194. ClipWindingEpsilon( w, planeNormal, d, epsilon, &frontWinding, &backWinding );
  195. // the clip may not produce two polygons if it was epsilon close
  196. if ( !frontWinding ) {
  197. w = backWinding;
  198. } else if ( !backWinding ) {
  199. w = frontWinding;
  200. } else {
  201. SubdivideDrawSurf( ds, frontWinding, subdivisions );
  202. SubdivideDrawSurf( ds, backWinding, subdivisions );
  203. return;
  204. }
  205. }
  206. }
  207. // emit this polygon
  208. newds = DrawSurfaceForSide( ds->mapBrush, ds->side, w );
  209. newds->fogNum = ds->fogNum;
  210. }
  211. /*
  212. =====================
  213. SubdivideDrawSurfs
  214. Chop up surfaces that have subdivision attributes
  215. =====================
  216. */
  217. void SubdivideDrawSurfs( entity_t *e, tree_t *tree ) {
  218. int i;
  219. mapDrawSurface_t *ds;
  220. int numBaseDrawSurfs;
  221. winding_t *w;
  222. float subdivision;
  223. shaderInfo_t *si;
  224. qprintf( "----- SubdivideDrawSurfs -----\n");
  225. numBaseDrawSurfs = numMapDrawSurfs;
  226. for ( i = e->firstDrawSurf ; i < numBaseDrawSurfs ; i++ ) {
  227. ds = &mapDrawSurfs[i];
  228. // only subdivide brush sides, not patches or misc_models
  229. if ( !ds->side ) {
  230. continue;
  231. }
  232. // check subdivision for shader
  233. si = ds->side->shaderInfo;
  234. if ( !si ) {
  235. continue;
  236. }
  237. if (ds->shaderInfo->autosprite || si->autosprite) {
  238. continue;
  239. }
  240. subdivision = si->subdivisions;
  241. if ( !subdivision ) {
  242. continue;
  243. }
  244. w = WindingFromDrawSurf( ds );
  245. ds->numVerts = 0; // remove this reference
  246. SubdivideDrawSurf( ds, w, subdivision );
  247. }
  248. }
  249. //===================================================================================
  250. /*
  251. ====================
  252. ClipSideIntoTree_r
  253. Adds non-opaque leaf fragments to the convex hull
  254. ====================
  255. */
  256. void ClipSideIntoTree_r( winding_t *w, side_t *side, node_t *node ) {
  257. plane_t *plane;
  258. winding_t *front, *back;
  259. if ( !w ) {
  260. return;
  261. }
  262. if ( node->planenum != PLANENUM_LEAF ) {
  263. if ( side->planenum == node->planenum ) {
  264. ClipSideIntoTree_r( w, side, node->children[0] );
  265. return;
  266. }
  267. if ( side->planenum == ( node->planenum ^ 1) ) {
  268. ClipSideIntoTree_r( w, side, node->children[1] );
  269. return;
  270. }
  271. plane = &mapplanes[ node->planenum ];
  272. ClipWindingEpsilon ( w, plane->normal, plane->dist,
  273. ON_EPSILON, &front, &back );
  274. FreeWinding( w );
  275. ClipSideIntoTree_r( front, side, node->children[0] );
  276. ClipSideIntoTree_r( back, side, node->children[1] );
  277. return;
  278. }
  279. // if opaque leaf, don't add
  280. if ( !node->opaque ) {
  281. AddWindingToConvexHull( w, &side->visibleHull, mapplanes[ side->planenum ].normal );
  282. }
  283. FreeWinding( w );
  284. return;
  285. }
  286. /*
  287. =====================
  288. ClipSidesIntoTree
  289. Creates side->visibleHull for all visible sides
  290. The drawsurf for a side will consist of the convex hull of
  291. all points in non-opaque clusters, which allows overlaps
  292. to be trimmed off automatically.
  293. =====================
  294. */
  295. void ClipSidesIntoTree( entity_t *e, tree_t *tree ) {
  296. bspbrush_t *b;
  297. int i;
  298. winding_t *w;
  299. side_t *side, *newSide;
  300. shaderInfo_t *si;
  301. qprintf( "----- ClipSidesIntoTree -----\n");
  302. for ( b = e->brushes ; b ; b = b->next ) {
  303. for ( i = 0 ; i < b->numsides ; i++ ) {
  304. side = &b->sides[i];
  305. if ( !side->winding) {
  306. continue;
  307. }
  308. w = CopyWinding( side->winding );
  309. side->visibleHull = NULL;
  310. ClipSideIntoTree_r( w, side, tree->headnode );
  311. w = side->visibleHull;
  312. if ( !w ) {
  313. continue;
  314. }
  315. si = side->shaderInfo;
  316. if ( !si ) {
  317. continue;
  318. }
  319. // don't create faces for non-visible sides
  320. if ( si->surfaceFlags & SURF_NODRAW ) {
  321. continue;
  322. }
  323. // always use the original quad winding for auto sprites
  324. if ( side->shaderInfo->autosprite ) {
  325. w = side->winding;
  326. }
  327. //
  328. if ( side->bevel ) {
  329. Error( "monkey tried to create draw surface for brush bevel" );
  330. }
  331. // save this winding as a visible surface
  332. DrawSurfaceForSide( b, side, w );
  333. // make a back side for it if needed
  334. if ( !(si->contents & CONTENTS_FOG) ) {
  335. continue;
  336. }
  337. // duplicate the up-facing side
  338. w = ReverseWinding( w );
  339. newSide = malloc( sizeof( *side ) );
  340. *newSide = *side;
  341. newSide->visibleHull = w;
  342. newSide->planenum ^= 1;
  343. // save this winding as a visible surface
  344. DrawSurfaceForSide( b, newSide, w );
  345. }
  346. }
  347. }
  348. /*
  349. ===================================================================================
  350. FILTER REFERENCES DOWN THE TREE
  351. ===================================================================================
  352. */
  353. /*
  354. ====================
  355. FilterDrawSurfIntoTree
  356. Place a reference to the given drawsurf in every leaf it contacts
  357. We assume that the point mesh aproximation to the curve will get a
  358. reference into all the leafs we need.
  359. ====================
  360. */
  361. int FilterMapDrawSurfIntoTree( vec3_t point, mapDrawSurface_t *ds, node_t *node ) {
  362. drawSurfRef_t *dsr;
  363. float d;
  364. plane_t *plane;
  365. int c;
  366. if ( node->planenum != PLANENUM_LEAF ) {
  367. plane = &mapplanes[ node->planenum ];
  368. d = DotProduct( point, plane->normal ) - plane->dist;
  369. c = 0;
  370. if ( d >= -ON_EPSILON ) {
  371. c += FilterMapDrawSurfIntoTree( point, ds, node->children[0] );
  372. }
  373. if ( d <= ON_EPSILON ) {
  374. c += FilterMapDrawSurfIntoTree( point, ds, node->children[1] );
  375. }
  376. return c;
  377. }
  378. // if opaque leaf, don't add
  379. if ( node->opaque ) {
  380. return 0;
  381. }
  382. // add the drawsurf if it hasn't been already
  383. for ( dsr = node->drawSurfReferences ; dsr ; dsr = dsr->nextRef ) {
  384. if ( dsr->outputNumber == numDrawSurfaces ) {
  385. return 0; // already referenced
  386. }
  387. }
  388. dsr = malloc( sizeof( *dsr ) );
  389. dsr->outputNumber = numDrawSurfaces;
  390. dsr->nextRef = node->drawSurfReferences;
  391. node->drawSurfReferences = dsr;
  392. return 1;
  393. }
  394. /*
  395. ====================
  396. FilterDrawSurfIntoTree_r
  397. Place a reference to the given drawsurf in every leaf it is in
  398. ====================
  399. */
  400. int FilterMapDrawSurfIntoTree_r( winding_t *w, mapDrawSurface_t *ds, node_t *node ) {
  401. drawSurfRef_t *dsr;
  402. plane_t *plane;
  403. int total;
  404. winding_t *front, *back;
  405. if ( node->planenum != PLANENUM_LEAF ) {
  406. plane = &mapplanes[ node->planenum ];
  407. ClipWindingEpsilon ( w, plane->normal, plane->dist,
  408. ON_EPSILON, &front, &back );
  409. total = 0;
  410. if ( front ) {
  411. total += FilterMapDrawSurfIntoTree_r( front, ds, node->children[0] );
  412. }
  413. if ( back ) {
  414. total += FilterMapDrawSurfIntoTree_r( back, ds, node->children[1] );
  415. }
  416. FreeWinding( w );
  417. return total;
  418. }
  419. // if opaque leaf, don't add
  420. if ( node->opaque ) {
  421. return 0;
  422. }
  423. // add the drawsurf if it hasn't been already
  424. for ( dsr = node->drawSurfReferences ; dsr ; dsr = dsr->nextRef ) {
  425. if ( dsr->outputNumber == numDrawSurfaces ) {
  426. return 0; // already referenced
  427. }
  428. }
  429. dsr = malloc( sizeof( *dsr ) );
  430. dsr->outputNumber = numDrawSurfaces;
  431. dsr->nextRef = node->drawSurfReferences;
  432. node->drawSurfReferences = dsr;
  433. return 1;
  434. }
  435. /*
  436. ====================
  437. FilterSideIntoTree_r
  438. Place a reference to the given drawsurf in every leaf it contacts
  439. ====================
  440. */
  441. int FilterSideIntoTree_r( winding_t *w, side_t *side, mapDrawSurface_t *ds, node_t *node ) {
  442. drawSurfRef_t *dsr;
  443. plane_t *plane;
  444. winding_t *front, *back;
  445. int total;
  446. if ( !w ) {
  447. return 0;
  448. }
  449. if ( node->planenum != PLANENUM_LEAF ) {
  450. if ( side->planenum == node->planenum ) {
  451. return FilterSideIntoTree_r( w, side, ds, node->children[0] );
  452. }
  453. if ( side->planenum == ( node->planenum ^ 1) ) {
  454. return FilterSideIntoTree_r( w, side, ds, node->children[1] );
  455. }
  456. plane = &mapplanes[ node->planenum ];
  457. ClipWindingEpsilon ( w, plane->normal, plane->dist,
  458. ON_EPSILON, &front, &back );
  459. total = FilterSideIntoTree_r( front, side, ds, node->children[0] );
  460. total += FilterSideIntoTree_r( back, side, ds, node->children[1] );
  461. FreeWinding( w );
  462. return total;
  463. }
  464. // if opaque leaf, don't add
  465. if ( node->opaque ) {
  466. return 0;
  467. }
  468. dsr = malloc( sizeof( *dsr ) );
  469. dsr->outputNumber = numDrawSurfaces;
  470. dsr->nextRef = node->drawSurfReferences;
  471. node->drawSurfReferences = dsr;
  472. FreeWinding( w );
  473. return 1;
  474. }
  475. /*
  476. =====================
  477. FilterFaceIntoTree
  478. =====================
  479. */
  480. int FilterFaceIntoTree( mapDrawSurface_t *ds, tree_t *tree ) {
  481. int l;
  482. winding_t *w;
  483. w = WindingFromDrawSurf( ds );
  484. l = FilterSideIntoTree_r( w, ds->side, ds, tree->headnode );
  485. return l;
  486. }
  487. /*
  488. =====================
  489. FilterPatchSurfIntoTree
  490. =====================
  491. */
  492. #define SUBDIVISION_LIMIT 8.0
  493. int FilterPatchSurfIntoTree( mapDrawSurface_t *ds, tree_t *tree ) {
  494. int i, j;
  495. int l;
  496. mesh_t baseMesh, *subdividedMesh;
  497. winding_t *w;
  498. baseMesh.width = ds->patchWidth;
  499. baseMesh.height = ds->patchHeight;
  500. baseMesh.verts = ds->verts;
  501. subdividedMesh = SubdivideMesh( baseMesh, SUBDIVISION_LIMIT, 32 );
  502. l = 0;
  503. for (i = 0; i < subdividedMesh->width-1; i++) {
  504. for (j = 0; j < subdividedMesh->height-1; j++) {
  505. w = AllocWinding(3);
  506. VectorCopy(subdividedMesh->verts[j * subdividedMesh->width + i].xyz, w->p[0]);
  507. VectorCopy(subdividedMesh->verts[j * subdividedMesh->width + i + 1].xyz, w->p[1]);
  508. VectorCopy(subdividedMesh->verts[(j+1) * subdividedMesh->width + i].xyz, w->p[2]);
  509. w->numpoints = 3;
  510. l += FilterMapDrawSurfIntoTree_r( w, ds, tree->headnode );
  511. w = AllocWinding(3);
  512. VectorCopy(subdividedMesh->verts[j * subdividedMesh->width + i + 1].xyz, w->p[0]);
  513. VectorCopy(subdividedMesh->verts[(j+1) * subdividedMesh->width + i + 1].xyz, w->p[1]);
  514. VectorCopy(subdividedMesh->verts[(j+1) * subdividedMesh->width + i].xyz, w->p[2]);
  515. w->numpoints = 3;
  516. l += FilterMapDrawSurfIntoTree_r( w, ds, tree->headnode );
  517. }
  518. }
  519. // also use the old point filtering into the tree
  520. for ( i = 0 ; i < subdividedMesh->width * subdividedMesh->height ; i++ ) {
  521. l += FilterMapDrawSurfIntoTree( subdividedMesh->verts[i].xyz, ds, tree->headnode );
  522. }
  523. free(subdividedMesh);
  524. return l;
  525. }
  526. /*
  527. =====================
  528. FilterMiscModelSurfIntoTree
  529. =====================
  530. */
  531. int FilterMiscModelSurfIntoTree( mapDrawSurface_t *ds, tree_t *tree ) {
  532. int i;
  533. int l;
  534. winding_t *w;
  535. l = 0;
  536. for (i = 0; i < ds->numIndexes-2; i++) {
  537. w = AllocWinding(3);
  538. VectorCopy(ds->verts[ds->indexes[i]].xyz, w->p[0]);
  539. VectorCopy(ds->verts[ds->indexes[i+1]].xyz, w->p[1]);
  540. VectorCopy(ds->verts[ds->indexes[i+2]].xyz, w->p[2]);
  541. w->numpoints = 3;
  542. l += FilterMapDrawSurfIntoTree_r( w, ds, tree->headnode );
  543. }
  544. // also use the old point filtering into the tree
  545. for ( i = 0 ; i < ds->numVerts ; i++ ) {
  546. l += FilterMapDrawSurfIntoTree( ds->verts[i].xyz, ds, tree->headnode );
  547. }
  548. return l;
  549. }
  550. /*
  551. =====================
  552. FilterFlareSurfIntoTree
  553. =====================
  554. */
  555. int FilterFlareSurfIntoTree( mapDrawSurface_t *ds, tree_t *tree ) {
  556. return FilterMapDrawSurfIntoTree( ds->lightmapOrigin, ds, tree->headnode );
  557. }
  558. //======================================================================
  559. int c_stripSurfaces, c_fanSurfaces;
  560. /*
  561. ==================
  562. IsTriangleDegenerate
  563. Returns qtrue if all three points are collinear or backwards
  564. ===================
  565. */
  566. #define COLINEAR_AREA 10
  567. static qboolean IsTriangleDegenerate( drawVert_t *points, int a, int b, int c ) {
  568. vec3_t v1, v2, v3;
  569. float d;
  570. VectorSubtract( points[b].xyz, points[a].xyz, v1 );
  571. VectorSubtract( points[c].xyz, points[a].xyz, v2 );
  572. CrossProduct( v1, v2, v3 );
  573. d = VectorLength( v3 );
  574. // assume all very small or backwards triangles will cause problems
  575. if ( d < COLINEAR_AREA ) {
  576. return qtrue;
  577. }
  578. return qfalse;
  579. }
  580. /*
  581. ===============
  582. SurfaceAsTriFan
  583. The surface can't be represented as a single tristrip without
  584. leaving a degenerate triangle (and therefore a crack), so add
  585. a point in the middle and create (points-1) triangles in fan order
  586. ===============
  587. */
  588. static void SurfaceAsTriFan( dsurface_t *ds ) {
  589. int i;
  590. int colorSum[4];
  591. drawVert_t *mid, *v;
  592. // create a new point in the center of the face
  593. if ( numDrawVerts == MAX_MAP_DRAW_VERTS ) {
  594. Error( "MAX_MAP_DRAW_VERTS" );
  595. }
  596. mid = &drawVerts[ numDrawVerts ];
  597. numDrawVerts++;
  598. colorSum[0] = colorSum[1] = colorSum[2] = colorSum[3] = 0;
  599. v = drawVerts + ds->firstVert;
  600. for (i = 0 ; i < ds->numVerts ; i++, v++ ) {
  601. VectorAdd( mid->xyz, v->xyz, mid->xyz );
  602. mid->st[0] += v->st[0];
  603. mid->st[1] += v->st[1];
  604. mid->lightmap[0] += v->lightmap[0];
  605. mid->lightmap[1] += v->lightmap[1];
  606. colorSum[0] += v->color[0];
  607. colorSum[1] += v->color[1];
  608. colorSum[2] += v->color[2];
  609. colorSum[3] += v->color[3];
  610. }
  611. mid->xyz[0] /= ds->numVerts;
  612. mid->xyz[1] /= ds->numVerts;
  613. mid->xyz[2] /= ds->numVerts;
  614. mid->st[0] /= ds->numVerts;
  615. mid->st[1] /= ds->numVerts;
  616. mid->lightmap[0] /= ds->numVerts;
  617. mid->lightmap[1] /= ds->numVerts;
  618. mid->color[0] = colorSum[0] / ds->numVerts;
  619. mid->color[1] = colorSum[1] / ds->numVerts;
  620. mid->color[2] = colorSum[2] / ds->numVerts;
  621. mid->color[3] = colorSum[3] / ds->numVerts;
  622. VectorCopy((drawVerts+ds->firstVert)->normal, mid->normal );
  623. // fill in indices in trifan order
  624. if ( numDrawIndexes + ds->numVerts*3 > MAX_MAP_DRAW_INDEXES ) {
  625. Error( "MAX_MAP_DRAWINDEXES" );
  626. }
  627. ds->firstIndex = numDrawIndexes;
  628. ds->numIndexes = ds->numVerts*3;
  629. //FIXME
  630. // should be: for ( i = 0 ; i < ds->numVerts ; i++ ) {
  631. // set a break point and test this in a map
  632. //for ( i = 0 ; i < ds->numVerts*3 ; i++ ) {
  633. for ( i = 0 ; i < ds->numVerts ; i++ ) {
  634. drawIndexes[numDrawIndexes++] = ds->numVerts;
  635. drawIndexes[numDrawIndexes++] = i;
  636. drawIndexes[numDrawIndexes++] = (i+1) % ds->numVerts;
  637. }
  638. ds->numVerts++;
  639. }
  640. /*
  641. ================
  642. SurfaceAsTristrip
  643. Try to create indices that make (points-2) triangles in tristrip order
  644. ================
  645. */
  646. #define MAX_INDICES 1024
  647. static void SurfaceAsTristrip( dsurface_t *ds ) {
  648. int i;
  649. int rotate;
  650. int numIndices;
  651. int ni;
  652. int a, b, c;
  653. int indices[MAX_INDICES];
  654. // determine the triangle strip order
  655. numIndices = ( ds->numVerts - 2 ) * 3;
  656. if ( numIndices > MAX_INDICES ) {
  657. Error( "MAX_INDICES exceeded for surface" );
  658. }
  659. // try all possible orderings of the points looking
  660. // for a strip order that isn't degenerate
  661. for ( rotate = 0 ; rotate < ds->numVerts ; rotate++ ) {
  662. for ( ni = 0, i = 0 ; i < ds->numVerts - 2 - i ; i++ ) {
  663. a = ( ds->numVerts - 1 - i + rotate ) % ds->numVerts;
  664. b = ( i + rotate ) % ds->numVerts;
  665. c = ( ds->numVerts - 2 - i + rotate ) % ds->numVerts;
  666. if ( IsTriangleDegenerate( drawVerts + ds->firstVert, a, b, c ) ) {
  667. break;
  668. }
  669. indices[ni++] = a;
  670. indices[ni++] = b;
  671. indices[ni++] = c;
  672. if ( i + 1 != ds->numVerts - 1 - i ) {
  673. a = ( ds->numVerts - 2 - i + rotate ) % ds->numVerts;
  674. b = ( i + rotate ) % ds->numVerts;
  675. c = ( i + 1 + rotate ) % ds->numVerts;
  676. if ( IsTriangleDegenerate( drawVerts + ds->firstVert, a, b, c ) ) {
  677. break;
  678. }
  679. indices[ni++] = a;
  680. indices[ni++] = b;
  681. indices[ni++] = c;
  682. }
  683. }
  684. if ( ni == numIndices ) {
  685. break; // got it done without degenerate triangles
  686. }
  687. }
  688. // if any triangle in the strip is degenerate,
  689. // render from a centered fan point instead
  690. if ( ni < numIndices ) {
  691. c_fanSurfaces++;
  692. SurfaceAsTriFan( ds );
  693. return;
  694. }
  695. // a normal tristrip
  696. c_stripSurfaces++;
  697. if ( numDrawIndexes + ni > MAX_MAP_DRAW_INDEXES ) {
  698. Error( "MAX_MAP_DRAW_INDEXES" );
  699. }
  700. ds->firstIndex = numDrawIndexes;
  701. ds->numIndexes = ni;
  702. memcpy( drawIndexes + numDrawIndexes, indices, ni * sizeof(int) );
  703. numDrawIndexes += ni;
  704. }
  705. /*
  706. ===============
  707. EmitPlanarSurf
  708. ===============
  709. */
  710. void EmitPlanarSurf( mapDrawSurface_t *ds ) {
  711. int j;
  712. dsurface_t *out;
  713. drawVert_t *outv;
  714. if ( numDrawSurfaces == MAX_MAP_DRAW_SURFS ) {
  715. Error( "MAX_MAP_DRAW_SURFS" );
  716. }
  717. out = &drawSurfaces[ numDrawSurfaces ];
  718. numDrawSurfaces++;
  719. out->surfaceType = MST_PLANAR;
  720. out->shaderNum = EmitShader( ds->shaderInfo->shader );
  721. out->firstVert = numDrawVerts;
  722. out->numVerts = ds->numVerts;
  723. out->fogNum = ds->fogNum;
  724. out->lightmapNum = ds->lightmapNum;
  725. out->lightmapX = ds->lightmapX;
  726. out->lightmapY = ds->lightmapY;
  727. out->lightmapWidth = ds->lightmapWidth;
  728. out->lightmapHeight = ds->lightmapHeight;
  729. VectorCopy( ds->lightmapOrigin, out->lightmapOrigin );
  730. VectorCopy( ds->lightmapVecs[0], out->lightmapVecs[0] );
  731. VectorCopy( ds->lightmapVecs[1], out->lightmapVecs[1] );
  732. VectorCopy( ds->lightmapVecs[2], out->lightmapVecs[2] );
  733. for ( j = 0 ; j < ds->numVerts ; j++ ) {
  734. if ( numDrawVerts == MAX_MAP_DRAW_VERTS ) {
  735. Error( "MAX_MAP_DRAW_VERTS" );
  736. }
  737. outv = &drawVerts[ numDrawVerts ];
  738. numDrawVerts++;
  739. memcpy( outv, &ds->verts[ j ], sizeof( *outv ) );
  740. outv->color[0] = 255;
  741. outv->color[1] = 255;
  742. outv->color[2] = 255;
  743. outv->color[3] = 255;
  744. }
  745. // create the indexes
  746. SurfaceAsTristrip( out );
  747. }
  748. /*
  749. ===============
  750. EmitPatchSurf
  751. ===============
  752. */
  753. void EmitPatchSurf( mapDrawSurface_t *ds ) {
  754. int j;
  755. dsurface_t *out;
  756. drawVert_t *outv;
  757. if ( numDrawSurfaces == MAX_MAP_DRAW_SURFS ) {
  758. Error( "MAX_MAP_DRAW_SURFS" );
  759. }
  760. out = &drawSurfaces[ numDrawSurfaces ];
  761. numDrawSurfaces++;
  762. out->surfaceType = MST_PATCH;
  763. out->shaderNum = EmitShader( ds->shaderInfo->shader );
  764. out->firstVert = numDrawVerts;
  765. out->numVerts = ds->numVerts;
  766. out->firstIndex = numDrawIndexes;
  767. out->numIndexes = ds->numIndexes;
  768. out->patchWidth = ds->patchWidth;
  769. out->patchHeight = ds->patchHeight;
  770. out->fogNum = ds->fogNum;
  771. out->lightmapNum = ds->lightmapNum;
  772. out->lightmapX = ds->lightmapX;
  773. out->lightmapY = ds->lightmapY;
  774. out->lightmapWidth = ds->lightmapWidth;
  775. out->lightmapHeight = ds->lightmapHeight;
  776. VectorCopy( ds->lightmapOrigin, out->lightmapOrigin );
  777. VectorCopy( ds->lightmapVecs[0], out->lightmapVecs[0] );
  778. VectorCopy( ds->lightmapVecs[1], out->lightmapVecs[1] );
  779. VectorCopy( ds->lightmapVecs[2], out->lightmapVecs[2] );
  780. for ( j = 0 ; j < ds->numVerts ; j++ ) {
  781. if ( numDrawVerts == MAX_MAP_DRAW_VERTS ) {
  782. Error( "MAX_MAP_DRAW_VERTS" );
  783. }
  784. outv = &drawVerts[ numDrawVerts ];
  785. numDrawVerts++;
  786. memcpy( outv, &ds->verts[ j ], sizeof( *outv ) );
  787. outv->color[0] = 255;
  788. outv->color[1] = 255;
  789. outv->color[2] = 255;
  790. outv->color[3] = 255;
  791. }
  792. for ( j = 0 ; j < ds->numIndexes ; j++ ) {
  793. if ( numDrawIndexes == MAX_MAP_DRAW_INDEXES ) {
  794. Error( "MAX_MAP_DRAW_INDEXES" );
  795. }
  796. drawIndexes[ numDrawIndexes ] = ds->indexes[ j ];
  797. numDrawIndexes++;
  798. }
  799. }
  800. /*
  801. ===============
  802. EmitFlareSurf
  803. ===============
  804. */
  805. void EmitFlareSurf( mapDrawSurface_t *ds ) {
  806. dsurface_t *out;
  807. if ( numDrawSurfaces == MAX_MAP_DRAW_SURFS ) {
  808. Error( "MAX_MAP_DRAW_SURFS" );
  809. }
  810. out = &drawSurfaces[ numDrawSurfaces ];
  811. numDrawSurfaces++;
  812. out->surfaceType = MST_FLARE;
  813. out->shaderNum = EmitShader( ds->shaderInfo->shader );
  814. out->fogNum = ds->fogNum;
  815. VectorCopy( ds->lightmapOrigin, out->lightmapOrigin );
  816. VectorCopy( ds->lightmapVecs[0], out->lightmapVecs[0] ); // color
  817. VectorCopy( ds->lightmapVecs[2], out->lightmapVecs[2] );
  818. }
  819. /*
  820. ===============
  821. EmitModelSurf
  822. ===============
  823. */
  824. void EmitModelSurf( mapDrawSurface_t *ds ) {
  825. int j;
  826. dsurface_t *out;
  827. drawVert_t *outv;
  828. if ( numDrawSurfaces == MAX_MAP_DRAW_SURFS ) {
  829. Error( "MAX_MAP_DRAW_SURFS" );
  830. }
  831. out = &drawSurfaces[ numDrawSurfaces ];
  832. numDrawSurfaces++;
  833. out->surfaceType = MST_TRIANGLE_SOUP;
  834. out->shaderNum = EmitShader( ds->shaderInfo->shader );
  835. out->firstVert = numDrawVerts;
  836. out->numVerts = ds->numVerts;
  837. out->firstIndex = numDrawIndexes;
  838. out->numIndexes = ds->numIndexes;
  839. out->patchWidth = ds->patchWidth;
  840. out->patchHeight = ds->patchHeight;
  841. out->fogNum = ds->fogNum;
  842. out->lightmapNum = ds->lightmapNum;
  843. out->lightmapX = ds->lightmapX;
  844. out->lightmapY = ds->lightmapY;
  845. out->lightmapWidth = ds->lightmapWidth;
  846. out->lightmapHeight = ds->lightmapHeight;
  847. VectorCopy( ds->lightmapOrigin, out->lightmapOrigin );
  848. VectorCopy( ds->lightmapVecs[0], out->lightmapVecs[0] );
  849. VectorCopy( ds->lightmapVecs[1], out->lightmapVecs[1] );
  850. VectorCopy( ds->lightmapVecs[2], out->lightmapVecs[2] );
  851. for ( j = 0 ; j < ds->numVerts ; j++ ) {
  852. if ( numDrawVerts == MAX_MAP_DRAW_VERTS ) {
  853. Error( "MAX_MAP_DRAW_VERTS" );
  854. }
  855. outv = &drawVerts[ numDrawVerts ];
  856. numDrawVerts++;
  857. memcpy( outv, &ds->verts[ j ], sizeof( *outv ) );
  858. outv->color[0] = 255;
  859. outv->color[1] = 255;
  860. outv->color[2] = 255;
  861. }
  862. for ( j = 0 ; j < ds->numIndexes ; j++ ) {
  863. if ( numDrawIndexes == MAX_MAP_DRAW_INDEXES ) {
  864. Error( "MAX_MAP_DRAW_INDEXES" );
  865. }
  866. drawIndexes[ numDrawIndexes ] = ds->indexes[ j ];
  867. numDrawIndexes++;
  868. }
  869. }
  870. //======================================================================
  871. /*
  872. ==================
  873. CreateFlareSurface
  874. Light flares from surface lights become
  875. ==================
  876. */
  877. void CreateFlareSurface( mapDrawSurface_t *faceDs ) {
  878. mapDrawSurface_t *ds;
  879. int i;
  880. ds = AllocDrawSurf();
  881. if ( faceDs->shaderInfo->flareShader[0] ) {
  882. ds->shaderInfo = ShaderInfoForShader( faceDs->shaderInfo->flareShader );
  883. } else {
  884. ds->shaderInfo = ShaderInfoForShader( "flareshader" );
  885. }
  886. ds->flareSurface = qtrue;
  887. VectorCopy( faceDs->lightmapVecs[2], ds->lightmapVecs[2] );
  888. // find midpoint
  889. VectorClear( ds->lightmapOrigin );
  890. for ( i = 0 ; i < faceDs->numVerts ; i++ ) {
  891. VectorAdd( ds->lightmapOrigin, faceDs->verts[i].xyz, ds->lightmapOrigin );
  892. }
  893. VectorScale( ds->lightmapOrigin, 1.0/faceDs->numVerts, ds->lightmapOrigin );
  894. VectorMA( ds->lightmapOrigin, 2, ds->lightmapVecs[2], ds->lightmapOrigin );
  895. VectorCopy( faceDs->shaderInfo->color, ds->lightmapVecs[0] );
  896. // FIXME: fog
  897. }
  898. /*
  899. =====================
  900. FilterDrawsurfsIntoTree
  901. Upon completion, all drawsurfs that actually generate a reference
  902. will have been emited to the bspfile arrays, and the references
  903. will have valid final indexes
  904. =====================
  905. */
  906. void FilterDrawsurfsIntoTree( entity_t *e, tree_t *tree ) {
  907. int i;
  908. mapDrawSurface_t *ds;
  909. int refs;
  910. int c_surfs, c_refs;
  911. qprintf( "----- FilterDrawsurfsIntoTree -----\n");
  912. c_surfs = 0;
  913. c_refs = 0;
  914. for ( i = e->firstDrawSurf ; i < numMapDrawSurfs ; i++ ) {
  915. ds = &mapDrawSurfs[i];
  916. if ( !ds->numVerts && !ds->flareSurface ) {
  917. continue;
  918. }
  919. if ( ds->miscModel ) {
  920. refs = FilterMiscModelSurfIntoTree( ds, tree );
  921. EmitModelSurf( ds );
  922. } else if ( ds->patch ) {
  923. refs = FilterPatchSurfIntoTree( ds, tree );
  924. EmitPatchSurf( ds );
  925. } else if ( ds->flareSurface ) {
  926. refs = FilterFlareSurfIntoTree( ds, tree );
  927. EmitFlareSurf( ds );
  928. } else {
  929. refs = FilterFaceIntoTree( ds, tree );
  930. // if ( ds->shaderInfo->value >= 1000 ) { // ds->shaderInfo->flareShader[0] ) {
  931. if ( ds->shaderInfo->flareShader[0] ) {
  932. CreateFlareSurface( ds );
  933. }
  934. EmitPlanarSurf( ds );
  935. }
  936. if ( refs > 0 ) {
  937. c_surfs++;
  938. c_refs += refs;
  939. }
  940. }
  941. qprintf( "%5i emited drawsurfs\n", c_surfs );
  942. qprintf( "%5i references\n", c_refs );
  943. qprintf( "%5i stripfaces\n", c_stripSurfaces );
  944. qprintf( "%5i fanfaces\n", c_fanSurfaces );
  945. }