/* ProjectDecalOntoGrid() projects a decal onto a grid (patch) surface */ static void ProjectDecalOntoGrid(decalProjector_t *dp, msurface_t *surf, bmodel_t *bmodel) { vec3_t points[2][MAX_DECAL_VERTS]; int x, y; drawVert_t *dv; srfGridMesh_t *srf = (srfGridMesh_t *) surf->data; // get surface // walk mesh rows for (y = 0; y < (srf->height - 1); y++) { // walk mesh cols for (x = 0; x < (srf->width - 1); x++) { // get vertex dv = srf->verts + y * srf->width + x; // first triangle VectorCopy(dv[0].xyz, points[0][0]); VectorCopy(dv[srf->width].xyz, points[0][1]); VectorCopy(dv[1].xyz, points[0][2]); ProjectDecalOntoWinding(dp, 3, points, surf, bmodel); // second triangle VectorCopy(dv[1].xyz, points[0][0]); VectorCopy(dv[srf->width].xyz, points[0][1]); VectorCopy(dv[srf->width + 1].xyz, points[0][2]); ProjectDecalOntoWinding(dp, 3, points, surf, bmodel); } } }
static void ProjectDecalOntoGrid( decalProjector_t *dp, bspSurface_t *surf, bspModel_t *bmodel ) { int x, y; srfGridMesh_t *srf; srfVert_t *dv; vec3_t points[ 2 ][ MAX_DECAL_VERTS ]; /* get surface */ srf = ( srfGridMesh_t * ) surf->data; /* walk mesh rows */ for ( y = 0; y < ( srf->height - 1 ); y++ ) { /* walk mesh cols */ for ( x = 0; x < ( srf->width - 1 ); x++ ) { /* get vertex */ dv = srf->verts + y * srf->width + x; /* first triangle */ VectorCopy( dv[ 0 ].xyz, points[ 0 ][ 0 ] ); VectorCopy( dv[ srf->width ].xyz, points[ 0 ][ 1 ] ); VectorCopy( dv[ 1 ].xyz, points[ 0 ][ 2 ] ); ProjectDecalOntoWinding( dp, 3, points, surf, bmodel ); /* second triangle */ VectorCopy( dv[ 1 ].xyz, points[ 0 ][ 0 ] ); VectorCopy( dv[ srf->width ].xyz, points[ 0 ][ 1 ] ); VectorCopy( dv[ srf->width + 1 ].xyz, points[ 0 ][ 2 ] ); ProjectDecalOntoWinding( dp, 3, points, surf, bmodel ); } } }
static void ProjectDecalOntoTriangles( decalProjector_t *dp, mapDrawSurface_t *ds ) { int i; vec4_t plane; float d; winding_t *w; /* triangle surfaces without shaders don't get marks by default */ if( ds->type == SURFACE_TRIANGLES && ds->shaderInfo->shaderText == NULL ) return; /* backface check */ if( ds->planar ) { VectorCopy( mapplanes[ ds->planeNum ].normal, plane ); plane[ 3 ] = mapplanes[ ds->planeNum ].dist + DotProduct( plane, entityOrigin ); d = DotProduct( dp->planes[ 0 ], plane ); if( d < -0.0001f ) return; } /* iterate through triangles */ for( i = 0; i < ds->numIndexes; i += 3 ) { /* generate decal */ w = AllocWinding( 3 ); w->numpoints = 3; VectorCopy( ds->verts[ ds->indexes[ i ] ].xyz, w->p[ 0 ] ); VectorCopy( ds->verts[ ds->indexes[ i + 1 ] ].xyz, w->p[ 1 ] ); VectorCopy( ds->verts[ ds->indexes[ i + 2 ] ].xyz, w->p[ 2 ] ); ProjectDecalOntoWinding( dp, ds, w ); } }
static void ProjectDecalOntoFace( decalProjector_t *dp, mapDrawSurface_t *ds ) { vec4_t plane; float d; winding_t *w; /* dummy check */ if( ds->sideRef == NULL || ds->sideRef->side == NULL ) return; /* backface check */ if( ds->planar ) { VectorCopy( mapplanes[ ds->planeNum ].normal, plane ); plane[ 3 ] = mapplanes[ ds->planeNum ].dist + DotProduct( plane, entityOrigin ); d = DotProduct( dp->planes[ 0 ], plane ); if( d < -0.0001f ) return; } /* generate decal */ w = WindingFromDrawSurf( ds ); ProjectDecalOntoWinding( dp, ds, w ); }
static void ProjectDecalOntoTriangles( decalProjector_t *dp, bspSurface_t *surf, bspModel_t *bmodel ) { int i; srfTriangle_t *tri; vec3_t points[ 2 ][ MAX_DECAL_VERTS ]; if ( *surf->data == SF_FACE ) { /* get surface */ srfSurfaceFace_t *srf = ( srfSurfaceFace_t * ) surf->data; /* walk triangle list */ for ( i = 0, tri = srf->triangles; i < srf->numTriangles; i++, tri++ ) { /* make triangle */ VectorCopy( srf->verts[ tri->indexes[ 0 ] ].xyz, points[ 0 ][ 0 ] ); VectorCopy( srf->verts[ tri->indexes[ 1 ] ].xyz, points[ 0 ][ 1 ] ); VectorCopy( srf->verts[ tri->indexes[ 2 ] ].xyz, points[ 0 ][ 2 ] ); /* chop it */ ProjectDecalOntoWinding( dp, 3, points, surf, bmodel ); } } else if ( *surf->data == SF_TRIANGLES ) { /* get surface */ srfTriangles_t *srf = ( srfTriangles_t * ) surf->data; /* walk triangle list */ for ( i = 0, tri = srf->triangles; i < srf->numTriangles; i++, tri++ ) { /* make triangle */ VectorCopy( srf->verts[ tri->indexes[ 0 ] ].xyz, points[ 0 ][ 0 ] ); VectorCopy( srf->verts[ tri->indexes[ 1 ] ].xyz, points[ 0 ][ 1 ] ); VectorCopy( srf->verts[ tri->indexes[ 2 ] ].xyz, points[ 0 ][ 2 ] ); /* chop it */ ProjectDecalOntoWinding( dp, 3, points, surf, bmodel ); } } }
/** * @brief Projects a decal onto a triangle surface (brush faces, misc_models, metasurfaces) * @param[in] dp * @param[in] surf * @param[in] bmodel */ static void ProjectDecalOntoTriangles(decalProjector_t *dp, msurface_t *surf, bmodel_t *bmodel) { vec3_t points[2][MAX_DECAL_VERTS]; int i; srfTriangles_t *srf = (srfTriangles_t *) surf->data; // get surface // walk triangle list for (i = 0; i < srf->numIndexes; i += 3) { // make triangle VectorCopy(srf->verts[srf->indexes[i]].xyz, points[0][0]); VectorCopy(srf->verts[srf->indexes[i + 1]].xyz, points[0][1]); VectorCopy(srf->verts[srf->indexes[i + 2]].xyz, points[0][2]); // chop it ProjectDecalOntoWinding(dp, 3, points, surf, bmodel); } }
static void ProjectDecalOntoPatch( decalProjector_t *dp, mapDrawSurface_t *ds ) { int x, y, pw[ 5 ], r, iterations; vec4_t plane; float d; mesh_t src, *mesh, *subdivided; winding_t *w; /* backface check */ if( ds->planar ) { VectorCopy( mapplanes[ ds->planeNum ].normal, plane ); plane[ 3 ] = mapplanes[ ds->planeNum ].dist + DotProduct( plane, entityOrigin ); d = DotProduct( dp->planes[ 0 ], plane ); if( d < -0.0001f ) return; } /* tesselate the patch */ src.width = ds->patchWidth; src.height = ds->patchHeight; src.verts = ds->verts; iterations = IterationsForCurve( ds->longestCurve, patch_subdivide->integer ); subdivided = SubdivideMesh2( src, iterations ); /* fit it to the curve and remove colinear verts on rows/columns */ PutMeshOnCurve( *subdivided ); mesh = RemoveLinearMeshColumnsRows( subdivided ); FreeMesh( subdivided ); /* iterate through the mesh quads */ for( y = 0; y < (mesh->height - 1); y++ ) { for( x = 0; x < (mesh->width - 1); x++ ) { /* set indexes */ pw[ 0 ] = x + (y * mesh->width); pw[ 1 ] = x + ((y + 1) * mesh->width); pw[ 2 ] = x + 1 + ((y + 1) * mesh->width); pw[ 3 ] = x + 1 + (y * mesh->width); pw[ 4 ] = x + (y * mesh->width); /* same as pw[ 0 ] */ /* set radix */ r = (x + y) & 1; /* generate decal for first triangle */ w = AllocWinding( 3 ); w->numpoints = 3; VectorCopy( mesh->verts[ pw[ r + 0 ] ].xyz, w->p[ 0 ] ); VectorCopy( mesh->verts[ pw[ r + 1 ] ].xyz, w->p[ 1 ] ); VectorCopy( mesh->verts[ pw[ r + 2 ] ].xyz, w->p[ 2 ] ); ProjectDecalOntoWinding( dp, ds, w ); /* generate decal for second triangle */ w = AllocWinding( 3 ); w->numpoints = 3; VectorCopy( mesh->verts[ pw[ r + 0 ] ].xyz, w->p[ 0 ] ); VectorCopy( mesh->verts[ pw[ r + 2 ] ].xyz, w->p[ 1 ] ); VectorCopy( mesh->verts[ pw[ r + 3 ] ].xyz, w->p[ 2 ] ); ProjectDecalOntoWinding( dp, ds, w ); } } /* clean up */ Mem_Free( mesh ); }