/** * @brief Projects a decal onto a world surface * @param[in] dp * @param[in] surf * @param[in] bmodel */ void R_ProjectDecalOntoSurface(decalProjector_t *dp, msurface_t *surf, bmodel_t *bmodel) { srfGeneric_t *gen; int i; // early outs if (dp->shader == NULL) { return; } //if( surf->viewCount == tr.viewCount ) // return; if ((surf->shader->surfaceFlags & (SURF_NOIMPACT | SURF_NOMARKS)) || (surf->shader->contentFlags & CONTENTS_FOG)) { return; } // get generic surface gen = (srfGeneric_t *) surf->data; // ignore certain surfacetypes if (gen->surfaceType != SF_FACE && gen->surfaceType != SF_TRIANGLES && gen->surfaceType != SF_GRID) { return; } // test bounding sphere if (!R_TestDecalBoundingSphere(dp, gen->origin, (gen->radius * gen->radius))) { return; } // planar surface if (gen->plane.normal[0] != 0.f || gen->plane.normal[1] != 0.f || gen->plane.normal[2] != 0.f) { float d; // backface check d = DotProduct(dp->planes[0], gen->plane.normal); if (d < -0.0001f) { return; } // plane-sphere check d = DotProduct(dp->center, gen->plane.normal) - gen->plane.dist; if (Q_fabs(d) >= dp->radius) { return; } } // add to counts tr.pc.c_decalClipSurfaces++; // check if this projector already has a decal on this surface { int count = (bmodel == tr.world->bmodels ? MAX_WORLD_DECALS : MAX_ENTITY_DECALS); decal_t *decal = bmodel->decals; for (i = 0; i < count; i++, decal++) { if (decal->parent == surf && decal->projectorNum == dp->projectorNum) { return; } } // add to counts tr.pc.c_decalTestSurfaces++; } // switch on type switch (gen->surfaceType) { case SF_FACE: case SF_TRIANGLES: ProjectDecalOntoTriangles(dp, surf, bmodel); break; case SF_GRID: ProjectDecalOntoGrid(dp, surf, bmodel); break; default: break; } }
void R_ProjectDecalOntoSurface( decalProjector_t *dp, bspSurface_t *surf, bspModel_t *bmodel ) { float d; srfGeneric_t *gen; /* early outs */ if ( dp->shader == NULL ) { return; } //% if( surf->viewCount == tr.viewCount ) //% return; if ( ( surf->shader->surfaceFlags & ( SURF_NOIMPACT | SURF_NOMARKS ) ) || ( surf->shader->contentFlags & CONTENTS_FOG ) ) { return; } /* add to counts */ tr.pc.c_decalTestSurfaces++; /* get generic surface */ gen = ( srfGeneric_t * ) surf->data; /* ignore certain surfacetypes */ if ( gen->surfaceType != SF_FACE && gen->surfaceType != SF_TRIANGLES && gen->surfaceType != SF_GRID ) { return; } /* test bounding sphere */ if ( !R_TestDecalBoundingSphere( dp, gen->origin, ( gen->radius * gen->radius ) ) ) // if(!R_TestDecalBoundingBox(dp, gen->bounds[0], gen->bounds[1])) { return; } /* planar surface */ if ( gen->surfaceType == SF_FACE ) { srfSurfaceFace_t *srf = ( srfSurfaceFace_t * )surf->data; if ( srf->plane.normal[ 0 ] || srf->plane.normal[ 1 ] || srf->plane.normal[ 2 ] ) { /* backface check */ d = DotProduct( dp->planes[ 0 ], srf->plane.normal ); if ( d < -0.0001 ) { return; } /* plane-sphere check */ d = DotProduct( dp->center, srf->plane.normal ) - srf->plane.dist; if ( fabs( d ) >= dp->radius ) { return; } } } /* add to counts */ tr.pc.c_decalClipSurfaces++; /* switch on type */ switch ( gen->surfaceType ) { case SF_FACE: case SF_TRIANGLES: ProjectDecalOntoTriangles( dp, surf, bmodel ); break; case SF_GRID: ProjectDecalOntoGrid( dp, surf, bmodel ); break; default: break; } }
void MakeEntityDecals( entity_t *e ) { int i, j, k, f, fOld; double start; decalProjector_t dp; mapDrawSurface_t *ds; vec3_t identityAxis[ 3 ] = { { 1, 0, 0 }, { 0, 1, 0 }, { 0, 0, 1 } }; /* note it */ MsgDev( D_NOTE, "--- MakeEntityDecals ---\n" ); /* set entity origin */ VectorCopy( e->origin, entityOrigin ); /* transform projector instead of geometry */ VectorClear( entityOrigin ); /* init pacifier */ fOld = -1; start = Sys_DoubleTime(); /* walk the list of decal projectors */ for( i = 0; i < numProjectors; i++ ) { /* print pacifier */ f = 10 * i / numProjectors; if( f != fOld ) { fOld = f; MsgDev( D_NOTE, "%d...", f ); } /* get projector */ TransformDecalProjector( &projectors[ i ], identityAxis, e->origin, &dp ); /* walk the list of surfaces in the entity */ for( j = e->firstDrawSurf; j < numMapDrawSurfs; j++ ) { /* get surface */ ds = &mapDrawSurfs[ j ]; if( ds->numVerts <= 0 ) continue; /* ignore autosprite or nomarks */ if( ds->shaderInfo->autosprite || (ds->shaderInfo->compileFlags & C_NOMARKS) ) continue; /* bounds check */ for( k = 0; k < 3; k++ ) if( ds->mins[ k ] >= (dp.center[ k ] + dp.radius) || ds->maxs[ k ] <= (dp.center[ k ] - dp.radius) ) break; if( k < 3 ) continue; /* switch on type */ switch( ds->type ) { case SURFACE_FACE: ProjectDecalOntoFace( &dp, ds ); break; case SURFACE_PATCH: ProjectDecalOntoPatch( &dp, ds ); break; case SURFACE_TRIANGLES: case SURFACE_FORCED_META: case SURFACE_META: ProjectDecalOntoTriangles( &dp, ds ); break; default: break; } } } MsgDev( D_NOTE, " (%g) second elapsed\n", (Sys_DoubleTime() - start )); MsgDev( D_NOTE, "%9d decal surfaces\n", numDecalSurfaces ); }