00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "qbsp.h"
00024
00025
00026 mapDrawSurface_t mapDrawSurfs[MAX_MAP_DRAW_SURFS];
00027 int numMapDrawSurfs;
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 mapDrawSurface_t *AllocDrawSurf( void ) {
00043 mapDrawSurface_t *ds;
00044
00045 if ( numMapDrawSurfs >= MAX_MAP_DRAW_SURFS ) {
00046 Error( "MAX_MAP_DRAW_SURFS");
00047 }
00048 ds = &mapDrawSurfs[ numMapDrawSurfs ];
00049 numMapDrawSurfs++;
00050
00051 return ds;
00052 }
00053
00054
00055
00056
00057
00058
00059 #define SNAP_FLOAT_TO_INT 8
00060 #define SNAP_INT_TO_FLOAT (1.0/SNAP_FLOAT_TO_INT)
00061
00062 mapDrawSurface_t *DrawSurfaceForSide( bspbrush_t *b, side_t *s, winding_t *w ) {
00063 mapDrawSurface_t *ds;
00064 int i, j;
00065 shaderInfo_t *si;
00066 drawVert_t *dv;
00067 float mins[2], maxs[2];
00068
00069
00070
00071 vec3_t texX,texY;
00072 vec_t x,y;
00073
00074 if ( w->numpoints > 64 ) {
00075 Error( "DrawSurfaceForSide: w->numpoints = %i", w->numpoints );
00076 }
00077
00078 si = s->shaderInfo;
00079
00080 ds = AllocDrawSurf();
00081
00082 ds->shaderInfo = si;
00083 ds->mapBrush = b;
00084 ds->side = s;
00085 ds->fogNum = -1;
00086 ds->numVerts = w->numpoints;
00087 ds->verts = malloc( ds->numVerts * sizeof( *ds->verts ) );
00088 memset( ds->verts, 0, ds->numVerts * sizeof( *ds->verts ) );
00089
00090 mins[0] = mins[1] = 99999;
00091 maxs[0] = maxs[1] = -99999;
00092
00093
00094
00095 ComputeAxisBase( mapplanes[s->planenum].normal, texX, texY );
00096
00097 for ( j = 0 ; j < w->numpoints ; j++ ) {
00098 dv = ds->verts + j;
00099
00100
00101 for ( i = 0 ; i < 3 ; i++ ) {
00102 dv->xyz[i] = SNAP_INT_TO_FLOAT * floor( w->p[j][i] * SNAP_FLOAT_TO_INT + 0.5 );
00103 }
00104
00105 if (g_bBrushPrimit==BPRIMIT_OLDBRUSHES)
00106 {
00107
00108 dv->st[0] = s->vecs[0][3] + DotProduct( s->vecs[0], dv->xyz );
00109 dv->st[1] = s->vecs[1][3] + DotProduct( s->vecs[1], dv->xyz );
00110 dv->st[0] /= si->width;
00111 dv->st[1] /= si->height;
00112 }
00113 else
00114 {
00115
00116 x = DotProduct( dv->xyz, texX );
00117 y = DotProduct( dv->xyz, texY );
00118 dv->st[0]=s->texMat[0][0]*x+s->texMat[0][1]*y+s->texMat[0][2];
00119 dv->st[1]=s->texMat[1][0]*x+s->texMat[1][1]*y+s->texMat[1][2];
00120 }
00121
00122 for ( i = 0 ; i < 2 ; i++ ) {
00123 if ( dv->st[i] < mins[i] ) {
00124 mins[i] = dv->st[i];
00125 }
00126 if ( dv->st[i] > maxs[i] ) {
00127 maxs[i] = dv->st[i];
00128 }
00129 }
00130
00131
00132 VectorCopy ( mapplanes[s->planenum].normal, dv->normal );
00133 }
00134
00135
00136 if ( !si->globalTexture ) {
00137 mins[0] = floor( mins[0] );
00138 mins[1] = floor( mins[1] );
00139 for ( i = 0 ; i < w->numpoints ; i++ ) {
00140 dv = ds->verts + i;
00141 dv->st[0] -= mins[0];
00142 dv->st[1] -= mins[1];
00143 }
00144 }
00145
00146 return ds;
00147 }
00148
00149
00150
00151
00152
00153
00154
00155 typedef struct {
00156 int planenum;
00157 shaderInfo_t *shaderInfo;
00158 int count;
00159 } sideRef_t;
00160
00161 #define MAX_SIDE_REFS MAX_MAP_PLANES
00162
00163 sideRef_t sideRefs[MAX_SIDE_REFS];
00164 int numSideRefs;
00165
00166 void AddSideRef( side_t *side ) {
00167 int i;
00168
00169 for ( i = 0 ; i < numSideRefs ; i++ ) {
00170 if ( side->planenum == sideRefs[i].planenum
00171 && side->shaderInfo == sideRefs[i].shaderInfo ) {
00172 sideRefs[i].count++;
00173 return;
00174 }
00175 }
00176
00177 if ( numSideRefs == MAX_SIDE_REFS ) {
00178 Error( "MAX_SIDE_REFS" );
00179 }
00180
00181 sideRefs[i].planenum = side->planenum;
00182 sideRefs[i].shaderInfo = side->shaderInfo;
00183 sideRefs[i].count++;
00184 numSideRefs++;
00185 }
00186
00187
00188
00189
00190
00191
00192
00193
00194 void MergeSides( entity_t *e, tree_t *tree ) {
00195 int i;
00196
00197 qprintf( "----- MergeSides -----\n");
00198
00199 for ( i = e->firstDrawSurf ; i < numMapDrawSurfs ; i++ ) {
00200
00201 }
00202
00203 qprintf( "%5i siderefs\n", numSideRefs );
00204 }
00205
00206
00207
00208
00209
00210
00211
00212
00213 void SubdivideDrawSurf( mapDrawSurface_t *ds, winding_t *w, float subdivisions ) {
00214 int i;
00215 int axis;
00216 vec3_t bounds[2];
00217 const float epsilon = 0.1;
00218 int subFloor, subCeil;
00219 winding_t *frontWinding, *backWinding;
00220 mapDrawSurface_t *newds;
00221
00222 if ( !w ) {
00223 return;
00224 }
00225 if ( w->numpoints < 3 ) {
00226 Error( "SubdivideDrawSurf: Bad w->numpoints" );
00227 }
00228
00229 ClearBounds( bounds[0], bounds[1] );
00230 for ( i = 0 ; i < w->numpoints ; i++ ) {
00231 AddPointToBounds( w->p[i], bounds[0], bounds[1] );
00232 }
00233
00234 for ( axis = 0 ; axis < 3 ; axis++ ) {
00235 vec3_t planePoint = { 0, 0, 0 };
00236 vec3_t planeNormal = { 0, 0, 0 };
00237 float d;
00238
00239 subFloor = floor( bounds[0][axis] / subdivisions ) * subdivisions;
00240 subCeil = ceil( bounds[1][axis] / subdivisions ) * subdivisions;
00241
00242 planePoint[axis] = subFloor + subdivisions;
00243 planeNormal[axis] = -1;
00244
00245 d = DotProduct( planePoint, planeNormal );
00246
00247
00248 if ( subCeil - subFloor > subdivisions ) {
00249
00250 ClipWindingEpsilon( w, planeNormal, d, epsilon, &frontWinding, &backWinding );
00251
00252
00253 if ( !frontWinding ) {
00254 w = backWinding;
00255 } else if ( !backWinding ) {
00256 w = frontWinding;
00257 } else {
00258 SubdivideDrawSurf( ds, frontWinding, subdivisions );
00259 SubdivideDrawSurf( ds, backWinding, subdivisions );
00260
00261 return;
00262 }
00263 }
00264 }
00265
00266
00267 newds = DrawSurfaceForSide( ds->mapBrush, ds->side, w );
00268 newds->fogNum = ds->fogNum;
00269 }
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 void SubdivideDrawSurfs( entity_t *e, tree_t *tree ) {
00280 int i;
00281 mapDrawSurface_t *ds;
00282 int numBaseDrawSurfs;
00283 winding_t *w;
00284 float subdivision;
00285 shaderInfo_t *si;
00286
00287 qprintf( "----- SubdivideDrawSurfs -----\n");
00288 numBaseDrawSurfs = numMapDrawSurfs;
00289 for ( i = e->firstDrawSurf ; i < numBaseDrawSurfs ; i++ ) {
00290 ds = &mapDrawSurfs[i];
00291
00292
00293 if ( !ds->side ) {
00294 continue;
00295 }
00296
00297
00298 si = ds->side->shaderInfo;
00299 if ( !si ) {
00300 continue;
00301 }
00302
00303 if (ds->shaderInfo->autosprite || si->autosprite) {
00304 continue;
00305 }
00306
00307 subdivision = si->subdivisions;
00308 if ( !subdivision ) {
00309 continue;
00310 }
00311
00312 w = WindingFromDrawSurf( ds );
00313 ds->numVerts = 0;
00314 SubdivideDrawSurf( ds, w, subdivision );
00315 }
00316
00317 }
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329 void ClipSideIntoTree_r( winding_t *w, side_t *side, node_t *node ) {
00330 plane_t *plane;
00331 winding_t *front, *back;
00332
00333 if ( !w ) {
00334 return;
00335 }
00336
00337 if ( node->planenum != PLANENUM_LEAF ) {
00338 if ( side->planenum == node->planenum ) {
00339 ClipSideIntoTree_r( w, side, node->children[0] );
00340 return;
00341 }
00342 if ( side->planenum == ( node->planenum ^ 1) ) {
00343 ClipSideIntoTree_r( w, side, node->children[1] );
00344 return;
00345 }
00346
00347 plane = &mapplanes[ node->planenum ];
00348 ClipWindingEpsilon ( w, plane->normal, plane->dist,
00349 ON_EPSILON, &front, &back );
00350 FreeWinding( w );
00351
00352 ClipSideIntoTree_r( front, side, node->children[0] );
00353 ClipSideIntoTree_r( back, side, node->children[1] );
00354
00355 return;
00356 }
00357
00358
00359 if ( !node->opaque ) {
00360 AddWindingToConvexHull( w, &side->visibleHull, mapplanes[ side->planenum ].normal );
00361 }
00362
00363 FreeWinding( w );
00364 return;
00365 }
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379 void ClipSidesIntoTree( entity_t *e, tree_t *tree ) {
00380 bspbrush_t *b;
00381 int i;
00382 winding_t *w;
00383 side_t *side, *newSide;
00384 shaderInfo_t *si;
00385
00386 qprintf( "----- ClipSidesIntoTree -----\n");
00387
00388 for ( b = e->brushes ; b ; b = b->next ) {
00389 for ( i = 0 ; i < b->numsides ; i++ ) {
00390 side = &b->sides[i];
00391 if ( !side->winding) {
00392 continue;
00393 }
00394 w = CopyWinding( side->winding );
00395 side->visibleHull = NULL;
00396 ClipSideIntoTree_r( w, side, tree->headnode );
00397
00398 w = side->visibleHull;
00399 if ( !w ) {
00400 continue;
00401 }
00402 si = side->shaderInfo;
00403 if ( !si ) {
00404 continue;
00405 }
00406
00407 if ( si->surfaceFlags & SURF_NODRAW ) {
00408 continue;
00409 }
00410
00411
00412 if ( side->shaderInfo->autosprite ) {
00413 w = side->winding;
00414 }
00415
00416 if ( side->bevel ) {
00417 Error( "monkey tried to create draw surface for brush bevel" );
00418 }
00419
00420 DrawSurfaceForSide( b, side, w );
00421
00422
00423 if ( !(si->contents & CONTENTS_FOG) ) {
00424 continue;
00425 }
00426
00427
00428 w = ReverseWinding( w );
00429
00430 newSide = malloc( sizeof( *side ) );
00431 *newSide = *side;
00432 newSide->visibleHull = w;
00433 newSide->planenum ^= 1;
00434
00435
00436 DrawSurfaceForSide( b, newSide, w );
00437
00438 }
00439 }
00440 }
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459 int FilterMapDrawSurfIntoTree( vec3_t point, mapDrawSurface_t *ds, node_t *node ) {
00460 drawSurfRef_t *dsr;
00461 float d;
00462 plane_t *plane;
00463 int c;
00464
00465 if ( node->planenum != PLANENUM_LEAF ) {
00466 plane = &mapplanes[ node->planenum ];
00467 d = DotProduct( point, plane->normal ) - plane->dist;
00468 c = 0;
00469 if ( d >= -ON_EPSILON ) {
00470 c += FilterMapDrawSurfIntoTree( point, ds, node->children[0] );
00471 }
00472 if ( d <= ON_EPSILON ) {
00473 c += FilterMapDrawSurfIntoTree( point, ds, node->children[1] );
00474 }
00475 return c;
00476 }
00477
00478
00479 if ( node->opaque ) {
00480 return 0;
00481 }
00482
00483
00484 for ( dsr = node->drawSurfReferences ; dsr ; dsr = dsr->nextRef ) {
00485 if ( dsr->outputNumber == numDrawSurfaces ) {
00486 return 0;
00487 }
00488 }
00489
00490 dsr = malloc( sizeof( *dsr ) );
00491 dsr->outputNumber = numDrawSurfaces;
00492 dsr->nextRef = node->drawSurfReferences;
00493 node->drawSurfReferences = dsr;
00494 return 1;
00495 }
00496
00497
00498
00499
00500
00501
00502
00503
00504 int FilterMapDrawSurfIntoTree_r( winding_t *w, mapDrawSurface_t *ds, node_t *node ) {
00505 drawSurfRef_t *dsr;
00506 plane_t *plane;
00507 int total;
00508 winding_t *front, *back;
00509
00510 if ( node->planenum != PLANENUM_LEAF ) {
00511 plane = &mapplanes[ node->planenum ];
00512 ClipWindingEpsilon ( w, plane->normal, plane->dist,
00513 ON_EPSILON, &front, &back );
00514
00515 total = 0;
00516 if ( front ) {
00517 total += FilterMapDrawSurfIntoTree_r( front, ds, node->children[0] );
00518 }
00519 if ( back ) {
00520 total += FilterMapDrawSurfIntoTree_r( back, ds, node->children[1] );
00521 }
00522
00523 FreeWinding( w );
00524 return total;
00525 }
00526
00527
00528 if ( node->opaque ) {
00529 return 0;
00530 }
00531
00532
00533 for ( dsr = node->drawSurfReferences ; dsr ; dsr = dsr->nextRef ) {
00534 if ( dsr->outputNumber == numDrawSurfaces ) {
00535 return 0;
00536 }
00537 }
00538
00539 dsr = malloc( sizeof( *dsr ) );
00540 dsr->outputNumber = numDrawSurfaces;
00541 dsr->nextRef = node->drawSurfReferences;
00542 node->drawSurfReferences = dsr;
00543 return 1;
00544 }
00545
00546
00547
00548
00549
00550
00551
00552
00553 int FilterSideIntoTree_r( winding_t *w, side_t *side, mapDrawSurface_t *ds, node_t *node ) {
00554 drawSurfRef_t *dsr;
00555 plane_t *plane;
00556 winding_t *front, *back;
00557 int total;
00558
00559 if ( !w ) {
00560 return 0;
00561 }
00562
00563 if ( node->planenum != PLANENUM_LEAF ) {
00564 if ( side->planenum == node->planenum ) {
00565 return FilterSideIntoTree_r( w, side, ds, node->children[0] );
00566 }
00567 if ( side->planenum == ( node->planenum ^ 1) ) {
00568 return FilterSideIntoTree_r( w, side, ds, node->children[1] );
00569 }
00570
00571 plane = &mapplanes[ node->planenum ];
00572 ClipWindingEpsilon ( w, plane->normal, plane->dist,
00573 ON_EPSILON, &front, &back );
00574
00575 total = FilterSideIntoTree_r( front, side, ds, node->children[0] );
00576 total += FilterSideIntoTree_r( back, side, ds, node->children[1] );
00577
00578 FreeWinding( w );
00579 return total;
00580 }
00581
00582
00583 if ( node->opaque ) {
00584 return 0;
00585 }
00586
00587 dsr = malloc( sizeof( *dsr ) );
00588 dsr->outputNumber = numDrawSurfaces;
00589 dsr->nextRef = node->drawSurfReferences;
00590 node->drawSurfReferences = dsr;
00591
00592 FreeWinding( w );
00593 return 1;
00594 }
00595
00596
00597
00598
00599
00600
00601
00602 int FilterFaceIntoTree( mapDrawSurface_t *ds, tree_t *tree ) {
00603 int l;
00604 winding_t *w;
00605
00606 w = WindingFromDrawSurf( ds );
00607 l = FilterSideIntoTree_r( w, ds->side, ds, tree->headnode );
00608
00609 return l;
00610 }
00611
00612
00613
00614
00615
00616
00617
00618
00619 #define SUBDIVISION_LIMIT 8.0
00620 int FilterPatchSurfIntoTree( mapDrawSurface_t *ds, tree_t *tree ) {
00621 int i, j;
00622 int l;
00623 mesh_t baseMesh, *subdividedMesh;
00624 winding_t *w;
00625
00626 baseMesh.width = ds->patchWidth;
00627 baseMesh.height = ds->patchHeight;
00628 baseMesh.verts = ds->verts;
00629 subdividedMesh = SubdivideMesh( baseMesh, SUBDIVISION_LIMIT, 32 );
00630
00631 l = 0;
00632 for (i = 0; i < subdividedMesh->width-1; i++) {
00633 for (j = 0; j < subdividedMesh->height-1; j++) {
00634 w = AllocWinding(3);
00635 VectorCopy(subdividedMesh->verts[j * subdividedMesh->width + i].xyz, w->p[0]);
00636 VectorCopy(subdividedMesh->verts[j * subdividedMesh->width + i + 1].xyz, w->p[1]);
00637 VectorCopy(subdividedMesh->verts[(j+1) * subdividedMesh->width + i].xyz, w->p[2]);
00638 w->numpoints = 3;
00639 l += FilterMapDrawSurfIntoTree_r( w, ds, tree->headnode );
00640 w = AllocWinding(3);
00641 VectorCopy(subdividedMesh->verts[j * subdividedMesh->width + i + 1].xyz, w->p[0]);
00642 VectorCopy(subdividedMesh->verts[(j+1) * subdividedMesh->width + i + 1].xyz, w->p[1]);
00643 VectorCopy(subdividedMesh->verts[(j+1) * subdividedMesh->width + i].xyz, w->p[2]);
00644 w->numpoints = 3;
00645 l += FilterMapDrawSurfIntoTree_r( w, ds, tree->headnode );
00646 }
00647 }
00648
00649
00650 for ( i = 0 ; i < subdividedMesh->width * subdividedMesh->height ; i++ ) {
00651 l += FilterMapDrawSurfIntoTree( subdividedMesh->verts[i].xyz, ds, tree->headnode );
00652 }
00653
00654 free(subdividedMesh);
00655
00656 return l;
00657 }
00658
00659
00660
00661
00662
00663
00664
00665 int FilterMiscModelSurfIntoTree( mapDrawSurface_t *ds, tree_t *tree ) {
00666 int i;
00667 int l;
00668 winding_t *w;
00669
00670 l = 0;
00671 for (i = 0; i < ds->numIndexes-2; i++) {
00672 w = AllocWinding(3);
00673 VectorCopy(ds->verts[ds->indexes[i]].xyz, w->p[0]);
00674 VectorCopy(ds->verts[ds->indexes[i+1]].xyz, w->p[1]);
00675 VectorCopy(ds->verts[ds->indexes[i+2]].xyz, w->p[2]);
00676 w->numpoints = 3;
00677 l += FilterMapDrawSurfIntoTree_r( w, ds, tree->headnode );
00678 }
00679
00680
00681 for ( i = 0 ; i < ds->numVerts ; i++ ) {
00682 l += FilterMapDrawSurfIntoTree( ds->verts[i].xyz, ds, tree->headnode );
00683 }
00684
00685 return l;
00686 }
00687
00688
00689
00690
00691
00692
00693 int FilterFlareSurfIntoTree( mapDrawSurface_t *ds, tree_t *tree ) {
00694 return FilterMapDrawSurfIntoTree( ds->lightmapOrigin, ds, tree->headnode );
00695 }
00696
00697
00698
00699
00700 int c_stripSurfaces, c_fanSurfaces;
00701
00702
00703
00704
00705
00706
00707
00708
00709 #define COLINEAR_AREA 10
00710 static qboolean IsTriangleDegenerate( drawVert_t *points, int a, int b, int c ) {
00711 vec3_t v1, v2, v3;
00712 float d;
00713
00714 VectorSubtract( points[b].xyz, points[a].xyz, v1 );
00715 VectorSubtract( points[c].xyz, points[a].xyz, v2 );
00716 CrossProduct( v1, v2, v3 );
00717 d = VectorLength( v3 );
00718
00719
00720 if ( d < COLINEAR_AREA ) {
00721 return qtrue;
00722 }
00723
00724 return qfalse;
00725 }
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736 static void SurfaceAsTriFan( dsurface_t *ds ) {
00737 int i;
00738 int colorSum[4];
00739 drawVert_t *mid, *v;
00740
00741
00742 if ( numDrawVerts == MAX_MAP_DRAW_VERTS ) {
00743 Error( "MAX_MAP_DRAW_VERTS" );
00744 }
00745 mid = &drawVerts[ numDrawVerts ];
00746 numDrawVerts++;
00747
00748 colorSum[0] = colorSum[1] = colorSum[2] = colorSum[3] = 0;
00749
00750 v = drawVerts + ds->firstVert;
00751 for (i = 0 ; i < ds->numVerts ; i++, v++ ) {
00752 VectorAdd( mid->xyz, v->xyz, mid->xyz );
00753 mid->st[0] += v->st[0];
00754 mid->st[1] += v->st[1];
00755 mid->lightmap[0] += v->lightmap[0];
00756 mid->lightmap[1] += v->lightmap[1];
00757
00758 colorSum[0] += v->color[0];
00759 colorSum[1] += v->color[1];
00760 colorSum[2] += v->color[2];
00761 colorSum[3] += v->color[3];
00762 }
00763
00764 mid->xyz[0] /= ds->numVerts;
00765 mid->xyz[1] /= ds->numVerts;
00766 mid->xyz[2] /= ds->numVerts;
00767
00768 mid->st[0] /= ds->numVerts;
00769 mid->st[1] /= ds->numVerts;
00770
00771 mid->lightmap[0] /= ds->numVerts;
00772 mid->lightmap[1] /= ds->numVerts;
00773
00774 mid->color[0] = colorSum[0] / ds->numVerts;
00775 mid->color[1] = colorSum[1] / ds->numVerts;
00776 mid->color[2] = colorSum[2] / ds->numVerts;
00777 mid->color[3] = colorSum[3] / ds->numVerts;
00778
00779 VectorCopy((drawVerts+ds->firstVert)->normal, mid->normal );
00780
00781
00782 if ( numDrawIndexes + ds->numVerts*3 > MAX_MAP_DRAW_INDEXES ) {
00783 Error( "MAX_MAP_DRAWINDEXES" );
00784 }
00785 ds->firstIndex = numDrawIndexes;
00786 ds->numIndexes = ds->numVerts*3;
00787
00788
00789
00790
00791
00792 for ( i = 0 ; i < ds->numVerts ; i++ ) {
00793 drawIndexes[numDrawIndexes++] = ds->numVerts;
00794 drawIndexes[numDrawIndexes++] = i;
00795 drawIndexes[numDrawIndexes++] = (i+1) % ds->numVerts;
00796 }
00797
00798 ds->numVerts++;
00799 }
00800
00801
00802
00803
00804
00805
00806
00807
00808
00809 #define MAX_INDICES 1024
00810 static void SurfaceAsTristrip( dsurface_t *ds ) {
00811 int i;
00812 int rotate;
00813 int numIndices;
00814 int ni;
00815 int a, b, c;
00816 int indices[MAX_INDICES];
00817
00818
00819 numIndices = ( ds->numVerts - 2 ) * 3;
00820 if ( numIndices > MAX_INDICES ) {
00821 Error( "MAX_INDICES exceeded for surface" );
00822 }
00823
00824
00825
00826 for ( rotate = 0 ; rotate < ds->numVerts ; rotate++ ) {
00827 for ( ni = 0, i = 0 ; i < ds->numVerts - 2 - i ; i++ ) {
00828 a = ( ds->numVerts - 1 - i + rotate ) % ds->numVerts;
00829 b = ( i + rotate ) % ds->numVerts;
00830 c = ( ds->numVerts - 2 - i + rotate ) % ds->numVerts;
00831
00832 if ( IsTriangleDegenerate( drawVerts + ds->firstVert, a, b, c ) ) {
00833 break;
00834 }
00835 indices[ni++] = a;
00836 indices[ni++] = b;
00837 indices[ni++] = c;
00838
00839 if ( i + 1 != ds->numVerts - 1 - i ) {
00840 a = ( ds->numVerts - 2 - i + rotate ) % ds->numVerts;
00841 b = ( i + rotate ) % ds->numVerts;
00842 c = ( i + 1 + rotate ) % ds->numVerts;
00843
00844 if ( IsTriangleDegenerate( drawVerts + ds->firstVert, a, b, c ) ) {
00845 break;
00846 }
00847 indices[ni++] = a;
00848 indices[ni++] = b;
00849 indices[ni++] = c;
00850 }
00851 }
00852 if ( ni == numIndices ) {
00853 break;
00854 }
00855 }
00856
00857
00858
00859 if ( ni < numIndices ) {
00860 c_fanSurfaces++;
00861 SurfaceAsTriFan( ds );
00862 return;
00863 }
00864
00865
00866 c_stripSurfaces++;
00867
00868 if ( numDrawIndexes + ni > MAX_MAP_DRAW_INDEXES ) {
00869 Error( "MAX_MAP_DRAW_INDEXES" );
00870 }
00871 ds->firstIndex = numDrawIndexes;
00872 ds->numIndexes = ni;
00873
00874 memcpy( drawIndexes + numDrawIndexes, indices, ni * sizeof(int) );
00875 numDrawIndexes += ni;
00876 }
00877
00878
00879
00880
00881
00882
00883 void EmitPlanarSurf( mapDrawSurface_t *ds ) {
00884 int j;
00885 dsurface_t *out;
00886 drawVert_t *outv;
00887
00888 if ( numDrawSurfaces == MAX_MAP_DRAW_SURFS ) {
00889 Error( "MAX_MAP_DRAW_SURFS" );
00890 }
00891 out = &drawSurfaces[ numDrawSurfaces ];
00892 numDrawSurfaces++;
00893
00894 out->surfaceType = MST_PLANAR;
00895 out->shaderNum = EmitShader( ds->shaderInfo->shader );
00896 out->firstVert = numDrawVerts;
00897 out->numVerts = ds->numVerts;
00898 out->fogNum = ds->fogNum;
00899 out->lightmapNum = ds->lightmapNum;
00900 out->lightmapX = ds->lightmapX;
00901 out->lightmapY = ds->lightmapY;
00902 out->lightmapWidth = ds->lightmapWidth;
00903 out->lightmapHeight = ds->lightmapHeight;
00904
00905 VectorCopy( ds->lightmapOrigin, out->lightmapOrigin );
00906 VectorCopy( ds->lightmapVecs[0], out->lightmapVecs[0] );
00907 VectorCopy( ds->lightmapVecs[1], out->lightmapVecs[1] );
00908 VectorCopy( ds->lightmapVecs[2], out->lightmapVecs[2] );
00909
00910 for ( j = 0 ; j < ds->numVerts ; j++ ) {
00911 if ( numDrawVerts == MAX_MAP_DRAW_VERTS ) {
00912 Error( "MAX_MAP_DRAW_VERTS" );
00913 }
00914 outv = &drawVerts[ numDrawVerts ];
00915 numDrawVerts++;
00916 memcpy( outv, &ds->verts[ j ], sizeof( *outv ) );
00917 outv->color[0] = 255;
00918 outv->color[1] = 255;
00919 outv->color[2] = 255;
00920 outv->color[3] = 255;
00921 }
00922
00923
00924 SurfaceAsTristrip( out );
00925 }
00926
00927
00928
00929
00930
00931
00932
00933 void EmitPatchSurf( mapDrawSurface_t *ds ) {
00934 int j;
00935 dsurface_t *out;
00936 drawVert_t *outv;
00937
00938 if ( numDrawSurfaces == MAX_MAP_DRAW_SURFS ) {
00939 Error( "MAX_MAP_DRAW_SURFS" );
00940 }
00941 out = &drawSurfaces[ numDrawSurfaces ];
00942 numDrawSurfaces++;
00943
00944 out->surfaceType = MST_PATCH;
00945 out->shaderNum = EmitShader( ds->shaderInfo->shader );
00946 out->firstVert = numDrawVerts;
00947 out->numVerts = ds->numVerts;
00948 out->firstIndex = numDrawIndexes;
00949 out->numIndexes = ds->numIndexes;
00950 out->patchWidth = ds->patchWidth;
00951 out->patchHeight = ds->patchHeight;
00952 out->fogNum = ds->fogNum;
00953 out->lightmapNum = ds->lightmapNum;
00954 out->lightmapX = ds->lightmapX;
00955 out->lightmapY = ds->lightmapY;
00956 out->lightmapWidth = ds->lightmapWidth;
00957 out->lightmapHeight = ds->lightmapHeight;
00958
00959 VectorCopy( ds->lightmapOrigin, out->lightmapOrigin );
00960 VectorCopy( ds->lightmapVecs[0], out->lightmapVecs[0] );
00961 VectorCopy( ds->lightmapVecs[1], out->lightmapVecs[1] );
00962 VectorCopy( ds->lightmapVecs[2], out->lightmapVecs[2] );
00963
00964 for ( j = 0 ; j < ds->numVerts ; j++ ) {
00965 if ( numDrawVerts == MAX_MAP_DRAW_VERTS ) {
00966 Error( "MAX_MAP_DRAW_VERTS" );
00967 }
00968 outv = &drawVerts[ numDrawVerts ];
00969 numDrawVerts++;
00970 memcpy( outv, &ds->verts[ j ], sizeof( *outv ) );
00971 outv->color[0] = 255;
00972 outv->color[1] = 255;
00973 outv->color[2] = 255;
00974 outv->color[3] = 255;
00975 }
00976
00977 for ( j = 0 ; j < ds->numIndexes ; j++ ) {
00978 if ( numDrawIndexes == MAX_MAP_DRAW_INDEXES ) {
00979 Error( "MAX_MAP_DRAW_INDEXES" );
00980 }
00981 drawIndexes[ numDrawIndexes ] = ds->indexes[ j ];
00982 numDrawIndexes++;
00983 }
00984 }
00985
00986
00987
00988
00989
00990
00991 void EmitFlareSurf( mapDrawSurface_t *ds ) {
00992 dsurface_t *out;
00993
00994 if ( numDrawSurfaces == MAX_MAP_DRAW_SURFS ) {
00995 Error( "MAX_MAP_DRAW_SURFS" );
00996 }
00997 out = &drawSurfaces[ numDrawSurfaces ];
00998 numDrawSurfaces++;
00999
01000 out->surfaceType = MST_FLARE;
01001 out->shaderNum = EmitShader( ds->shaderInfo->shader );
01002 out->fogNum = ds->fogNum;
01003
01004 VectorCopy( ds->lightmapOrigin, out->lightmapOrigin );
01005 VectorCopy( ds->lightmapVecs[0], out->lightmapVecs[0] );
01006 VectorCopy( ds->lightmapVecs[2], out->lightmapVecs[2] );
01007 }
01008
01009
01010
01011
01012
01013
01014
01015 void EmitModelSurf( mapDrawSurface_t *ds ) {
01016 int j;
01017 dsurface_t *out;
01018 drawVert_t *outv;
01019
01020 if ( numDrawSurfaces == MAX_MAP_DRAW_SURFS ) {
01021 Error( "MAX_MAP_DRAW_SURFS" );
01022 }
01023 out = &drawSurfaces[ numDrawSurfaces ];
01024 numDrawSurfaces++;
01025
01026 out->surfaceType = MST_TRIANGLE_SOUP;
01027 out->shaderNum = EmitShader( ds->shaderInfo->shader );
01028 out->firstVert = numDrawVerts;
01029 out->numVerts = ds->numVerts;
01030 out->firstIndex = numDrawIndexes;
01031 out->numIndexes = ds->numIndexes;
01032 out->patchWidth = ds->patchWidth;
01033 out->patchHeight = ds->patchHeight;
01034 out->fogNum = ds->fogNum;
01035 out->lightmapNum = ds->lightmapNum;
01036 out->lightmapX = ds->lightmapX;
01037 out->lightmapY = ds->lightmapY;
01038 out->lightmapWidth = ds->lightmapWidth;
01039 out->lightmapHeight = ds->lightmapHeight;
01040
01041 VectorCopy( ds->lightmapOrigin, out->lightmapOrigin );
01042 VectorCopy( ds->lightmapVecs[0], out->lightmapVecs[0] );
01043 VectorCopy( ds->lightmapVecs[1], out->lightmapVecs[1] );
01044 VectorCopy( ds->lightmapVecs[2], out->lightmapVecs[2] );
01045
01046 for ( j = 0 ; j < ds->numVerts ; j++ ) {
01047 if ( numDrawVerts == MAX_MAP_DRAW_VERTS ) {
01048 Error( "MAX_MAP_DRAW_VERTS" );
01049 }
01050 outv = &drawVerts[ numDrawVerts ];
01051 numDrawVerts++;
01052 memcpy( outv, &ds->verts[ j ], sizeof( *outv ) );
01053 outv->color[0] = 255;
01054 outv->color[1] = 255;
01055 outv->color[2] = 255;
01056 }
01057
01058 for ( j = 0 ; j < ds->numIndexes ; j++ ) {
01059 if ( numDrawIndexes == MAX_MAP_DRAW_INDEXES ) {
01060 Error( "MAX_MAP_DRAW_INDEXES" );
01061 }
01062 drawIndexes[ numDrawIndexes ] = ds->indexes[ j ];
01063 numDrawIndexes++;
01064 }
01065 }
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076 void CreateFlareSurface( mapDrawSurface_t *faceDs ) {
01077 mapDrawSurface_t *ds;
01078 int i;
01079
01080 ds = AllocDrawSurf();
01081
01082 if ( faceDs->shaderInfo->flareShader[0] ) {
01083 ds->shaderInfo = ShaderInfoForShader( faceDs->shaderInfo->flareShader );
01084 } else {
01085 ds->shaderInfo = ShaderInfoForShader( "flareshader" );
01086 }
01087 ds->flareSurface = qtrue;
01088 VectorCopy( faceDs->lightmapVecs[2], ds->lightmapVecs[2] );
01089
01090
01091 VectorClear( ds->lightmapOrigin );
01092 for ( i = 0 ; i < faceDs->numVerts ; i++ ) {
01093 VectorAdd( ds->lightmapOrigin, faceDs->verts[i].xyz, ds->lightmapOrigin );
01094 }
01095 VectorScale( ds->lightmapOrigin, 1.0/faceDs->numVerts, ds->lightmapOrigin );
01096
01097 VectorMA( ds->lightmapOrigin, 2, ds->lightmapVecs[2], ds->lightmapOrigin );
01098
01099 VectorCopy( faceDs->shaderInfo->color, ds->lightmapVecs[0] );
01100
01101
01102 }
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113 void FilterDrawsurfsIntoTree( entity_t *e, tree_t *tree ) {
01114 int i;
01115 mapDrawSurface_t *ds;
01116 int refs;
01117 int c_surfs, c_refs;
01118
01119 qprintf( "----- FilterDrawsurfsIntoTree -----\n");
01120
01121 c_surfs = 0;
01122 c_refs = 0;
01123 for ( i = e->firstDrawSurf ; i < numMapDrawSurfs ; i++ ) {
01124 ds = &mapDrawSurfs[i];
01125
01126 if ( !ds->numVerts && !ds->flareSurface ) {
01127 continue;
01128 }
01129 if ( ds->miscModel ) {
01130 refs = FilterMiscModelSurfIntoTree( ds, tree );
01131 EmitModelSurf( ds );
01132 } else if ( ds->patch ) {
01133 refs = FilterPatchSurfIntoTree( ds, tree );
01134 EmitPatchSurf( ds );
01135 } else if ( ds->flareSurface ) {
01136 refs = FilterFlareSurfIntoTree( ds, tree );
01137 EmitFlareSurf( ds );
01138 } else {
01139 refs = FilterFaceIntoTree( ds, tree );
01140
01141 if ( ds->shaderInfo->flareShader[0] ) {
01142 CreateFlareSurface( ds );
01143 }
01144 EmitPlanarSurf( ds );
01145 }
01146 if ( refs > 0 ) {
01147 c_surfs++;
01148 c_refs += refs;
01149 }
01150 }
01151 qprintf( "%5i emited drawsurfs\n", c_surfs );
01152 qprintf( "%5i references\n", c_refs );
01153 qprintf( "%5i stripfaces\n", c_stripSurfaces );
01154 qprintf( "%5i fanfaces\n", c_fanSurfaces );
01155 }
01156
01157
01158