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; } }
/** * @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; } }