X-Git-Url: https://de.git.xonotic.org/?p=xonotic%2Fnetradiant.git;a=blobdiff_plain;f=tools%2Fquake3%2Fq3map2%2Fsurface.c;h=b5dd724e15d9ee564b548f465129ec8d80108ff3;hp=a99c58008560c1b0102f034bfd581e096f4f2a33;hb=2af64392f80ea19c416da54e346f0f70400710c8;hpb=c005536caf84ce760f2030ae121ba52151fd7960 diff --git a/tools/quake3/q3map2/surface.c b/tools/quake3/q3map2/surface.c index a99c5800..b5dd724e 100644 --- a/tools/quake3/q3map2/surface.c +++ b/tools/quake3/q3map2/surface.c @@ -291,7 +291,7 @@ deletes all empty or bad surfaces from the surface list void TidyEntitySurfaces( entity_t *e ) { int i, j, deleted; - mapDrawSurface_t *out, *in; + mapDrawSurface_t *out, *in = NULL; /* note it */ @@ -1207,7 +1207,7 @@ DrawSurfaceForFlare() - ydnar creates a flare draw surface */ -mapDrawSurface_t *DrawSurfaceForFlare( int entNum, vec3_t origin, vec3_t normal, vec3_t color, char *flareShader, int lightStyle ) +mapDrawSurface_t *DrawSurfaceForFlare( int entNum, vec3_t origin, vec3_t normal, vec3_t color, const char *flareShader, int lightStyle ) { mapDrawSurface_t *ds; @@ -1965,6 +1965,51 @@ int FilterPointIntoTree_r( vec3_t point, mapDrawSurface_t *ds, node_t *node ) return AddReferenceToLeaf( ds, node ); } +/* +FilterPointConvexHullIntoTree_r() - ydnar +filters the convex hull of multiple points from a surface into the tree +*/ + +int FilterPointConvexHullIntoTree_r( vec3_t **points, int npoints, mapDrawSurface_t *ds, node_t *node ) +{ + float d, dmin, dmax; + plane_t *plane; + int refs = 0; + int i; + + if(!points) + return 0; + + /* is this a decision node? */ + if( node->planenum != PLANENUM_LEAF ) + { + /* classify the point in relation to the plane */ + plane = &mapplanes[ node->planenum ]; + + dmin = dmax = DotProduct( *(points[0]), plane->normal ) - plane->dist; + for(i = 1; i < npoints; ++i) + { + d = DotProduct( *(points[i]), plane->normal ) - plane->dist; + if(d > dmax) + dmax = d; + if(d < dmin) + dmin = d; + } + + /* filter by this plane */ + refs = 0; + if( dmax >= -ON_EPSILON ) + refs += FilterPointConvexHullIntoTree_r( points, npoints, ds, node->children[ 0 ] ); + if( dmin <= ON_EPSILON ) + refs += FilterPointConvexHullIntoTree_r( points, npoints, ds, node->children[ 1 ] ); + + /* return */ + return refs; + } + + /* add a reference */ + return AddReferenceToLeaf( ds, node ); +} /* @@ -1992,14 +2037,25 @@ int FilterWindingIntoTree_r( winding_t *w, mapDrawSurface_t *ds, node_t *node ) { /* 'fatten' the winding by the shader mins/maxs (parsed from vertexDeform move) */ /* note this winding is completely invalid (concave, nonplanar, etc) */ - fat = AllocWinding( w->numpoints * 3 ); - fat->numpoints = w->numpoints * 3; + fat = AllocWinding( w->numpoints * 3 + 3 ); + fat->numpoints = w->numpoints * 3 + 3; for( i = 0; i < w->numpoints; i++ ) { VectorCopy( w->p[ i ], fat->p[ i ] ); - VectorAdd( w->p[ i ], si->mins, fat->p[ i * 2 ] ); - VectorAdd( w->p[ i ], si->maxs, fat->p[ i * 3 ] ); + VectorAdd( w->p[ i ], si->mins, fat->p[ i + (w->numpoints+1) ] ); + VectorAdd( w->p[ i ], si->maxs, fat->p[ i + (w->numpoints+1) * 2 ] ); } + VectorCopy( w->p[ 0 ], fat->p[ i ] ); + VectorAdd( w->p[ 0 ], si->mins, fat->p[ i + w->numpoints ] ); + VectorAdd( w->p[ 0 ], si->maxs, fat->p[ i + w->numpoints * 2 ] ); + + /* + * note: this winding is STILL not suitable for ClipWindingEpsilon, and + * also does not really fulfill the intention as it only contains + * origin, +mins, +maxs, but thanks to the "closing" points I just + * added to the three sub-windings, the fattening at least doesn't make + * it worse + */ FreeWinding( w ); w = fat; @@ -2091,48 +2147,24 @@ subdivides a patch into an approximate curve and filters it into the tree static int FilterPatchIntoTree( mapDrawSurface_t *ds, tree_t *tree ) { - int i, x, y, refs; - mesh_t src, *mesh; - winding_t *w; - + int x, y, refs = 0; - /* subdivide the surface */ - src.width = ds->patchWidth; - src.height = ds->patchHeight; - src.verts = ds->verts; - mesh = SubdivideMesh( src, FILTER_SUBDIVISION, 32 ); - - - /* filter each quad into the tree (fixme: use new patch x-triangulation code?) */ - refs = 0; - for( y = 0; y < (mesh->height - 1); y++ ) - { - for( x = 0; x < (mesh->width - 1); x++ ) + for(y = 0; y + 2 < ds->patchHeight; y += 2) + for(x = 0; x + 2 < ds->patchWidth; x += 2) { - /* triangle 1 */ - w = AllocWinding( 3 ); - w->numpoints = 3; - VectorCopy( mesh->verts[ y * mesh->width + x ].xyz, w->p[ 0 ] ); - VectorCopy( mesh->verts[ y * mesh->width + x + 1 ].xyz, w->p[ 1 ] ); - VectorCopy( mesh->verts[ (y + 1) * mesh->width + x ].xyz, w->p[ 2 ] ); - refs += FilterWindingIntoTree_r( w, ds, tree->headnode ); - - /* triangle 2 */ - w = AllocWinding( 3 ); - w->numpoints = 3; - VectorCopy( mesh->verts[ y * mesh->width + x + 1 ].xyz, w->p[ 0 ] ); - VectorCopy( mesh->verts[ (y + 1 ) * mesh->width + x + 1 ].xyz, w->p[ 1 ] ); - VectorCopy( mesh->verts[ (y + 1 ) * mesh->width + x ].xyz, w->p[ 2 ] ); - refs += FilterWindingIntoTree_r( w, ds, tree->headnode ); + vec3_t *points[9]; + points[0] = &ds->verts[(y+0) * ds->patchWidth + (x+0)].xyz; + points[1] = &ds->verts[(y+0) * ds->patchWidth + (x+1)].xyz; + points[2] = &ds->verts[(y+0) * ds->patchWidth + (x+2)].xyz; + points[3] = &ds->verts[(y+1) * ds->patchWidth + (x+0)].xyz; + points[4] = &ds->verts[(y+1) * ds->patchWidth + (x+1)].xyz; + points[5] = &ds->verts[(y+1) * ds->patchWidth + (x+2)].xyz; + points[6] = &ds->verts[(y+2) * ds->patchWidth + (x+0)].xyz; + points[7] = &ds->verts[(y+2) * ds->patchWidth + (x+1)].xyz; + points[8] = &ds->verts[(y+2) * ds->patchWidth + (x+2)].xyz; + refs += FilterPointConvexHullIntoTree_r(points, 9, ds, tree->headnode); } - } - - /* use point filtering as well */ - for( i = 0; i < (mesh->width * mesh->height); i++ ) - refs += FilterPointIntoTree_r( mesh->verts[ i ].xyz, ds, tree->headnode ); - - /* free the subdivided mesh and return */ - FreeMesh( mesh ); + return refs; } @@ -2818,7 +2850,10 @@ emits a bsp planar winding (brush face) drawsurface static void EmitFaceSurface(mapDrawSurface_t *ds ) { /* strip/fan finding was moved elsewhere */ - StripFaceSurface( ds ); + if(maxAreaFaceSurface) + MaxAreaFaceSurface( ds ); + else + StripFaceSurface( ds ); EmitTriangleSurface(ds); } @@ -3073,7 +3108,7 @@ int AddSurfaceModelsToTriangle_r( mapDrawSurface_t *ds, surfaceModel_t *model, b /* roll the dice (model's odds scaled by vertex alpha) */ odds = model->odds * (tri[ 0 ]->color[ 0 ][ 3 ] + tri[ 0 ]->color[ 0 ][ 3 ] + tri[ 0 ]->color[ 0 ][ 3 ]) / 765.0f; r = Random(); - if( r > model->odds ) + if( r > odds ) return 0; /* calculate scale */ @@ -3138,7 +3173,7 @@ int AddSurfaceModelsToTriangle_r( mapDrawSurface_t *ds, surfaceModel_t *model, b } /* insert the model */ - InsertModel( (char *) model->model, 0, transform, NULL, ds->celShader, ds->entityNum, ds->castShadows, ds->recvShadows, 0, ds->lightmapScale, 0, 0 ); + InsertModel( (char *) model->model, 0, 0, transform, NULL, ds->celShader, ds->entityNum, ds->castShadows, ds->recvShadows, 0, ds->lightmapScale, 0, 0 ); /* return to sender */ return 1; @@ -3416,6 +3451,7 @@ void FilterDrawsurfsIntoTree( entity_t *e, tree_t *tree ) vec3_t origin, mins, maxs; int refs; int numSurfs, numRefs, numSkyboxSurfaces; + qboolean sb; /* note it */ @@ -3434,15 +3470,18 @@ void FilterDrawsurfsIntoTree( entity_t *e, tree_t *tree ) /* get shader */ si = ds->shaderInfo; - + /* ydnar: skybox surfaces are special */ if( ds->skybox ) { refs = AddReferenceToTree_r( ds, tree->headnode, qtrue ); ds->skybox = qfalse; + sb = qtrue; } else { + sb = qfalse; + /* refs initially zero */ refs = 0; @@ -3562,6 +3601,11 @@ void FilterDrawsurfsIntoTree( entity_t *e, tree_t *tree ) refs = 0; break; } + + /* maybe surface got marked as skybox again */ + /* if we keep that flag, it will get scaled up AGAIN */ + if(sb) + ds->skybox = qfalse; /* tot up the references */ if( refs > 0 ) @@ -3600,6 +3644,7 @@ void FilterDrawsurfsIntoTree( entity_t *e, tree_t *tree ) Sys_FPrintf( SYS_VRB, "%9d (%d) emitted drawsurfs\n", numSurfs, numBSPDrawSurfaces ); Sys_FPrintf( SYS_VRB, "%9d stripped face surfaces\n", numStripSurfaces ); Sys_FPrintf( SYS_VRB, "%9d fanned face surfaces\n", numFanSurfaces ); + Sys_FPrintf( SYS_VRB, "%9d maxarea'd face surfaces\n", numMaxAreaSurfaces ); Sys_FPrintf( SYS_VRB, "%9d surface models generated\n", numSurfaceModels ); Sys_FPrintf( SYS_VRB, "%9d skybox surfaces generated\n", numSkyboxSurfaces ); for( i = 0; i < NUM_SURFACE_TYPES; i++ )