* support separated _ambient, _color per group, misc_model entities

This commit is contained in:
Garux
2025-10-25 22:10:56 +05:00
parent ae3b75b31f
commit abadf52398
14 changed files with 198 additions and 148 deletions
+2
View File
@@ -112,8 +112,10 @@ td.formatted_questions ol { margin-top: 0px; margin-bottom: 0px; }
</li>
<li>On brush entities, classname <strong><code>func_group</code></strong> and classname <strong><code>misc_model</code></strong>:
<ul>
<li><strong><code>_ambient</code>, <code>ambient</code>:</strong> amount of ambient light</li>
<li><strong><code>_castShadows</code>, <code>_cs</code>:</strong> sets whether the entity casts shadows</li>
<li><strong><code>_celshader</code>:</strong> CelShader to use</li>
<li><strong><code>_color</code>:</strong> color to use for <strong><code>_ambient</code></strong></li>
<li><strong><code>_lightmapsamplesize</code>, <code>_samplesize</code>, <code>_ss</code>:</strong> sample size to use for surfaces of this entity</li>
<li><strong><code>_receiveShadows</code>, <code>_rs</code>:</strong> sets whether the entity receives shadows</li>
<li><strong><code>_shadeangle</code>, <code>_smoothnormals</code>, <code>_sn</code>, <code>_sa</code>, <code>_smooth</code>:</strong> largest angle between faces to allow to treat them part of the same nonplanar surface</li>
+1
View File
@@ -190,6 +190,7 @@ Q3map2:
* -wtf: During bsp to map conversion use common/WTF on faces with failed texture alignment deduction
* fix AP texture alignment deduction during bsp to map decompilation
* -format map_220: bsp to map of Valve220 format conversion
* support separated _ambient, _color per group, misc_model entities
+1
View File
@@ -552,6 +552,7 @@ static void ProjectDecalOntoWinding( decalProjector_t *dp, mapDrawSurface_t *ds,
ds2->fogNum = ds->fogNum; /* why was this -1? */
ds2->lightmapScale = ds->lightmapScale;
ds2->shadeAngleDegrees = ds->shadeAngleDegrees;
ds2->ambientColor = ds->ambientColor;
ds2->numVerts = w.size();
ds2->verts = safe_calloc( ds2->numVerts * sizeof( *ds2->verts ) );
+10 -9
View File
@@ -1186,7 +1186,7 @@ int LightContributionToSample( trace_t *trace ){
determines the amount of light reaching a sample (luxel or vertex)
*/
void LightingAtSample( trace_t *trace, byte styles[ MAX_LIGHTMAPS ], Vector3 (&colors)[ MAX_LIGHTMAPS ] ){
void LightingAtSample( trace_t *trace, byte styles[ MAX_LIGHTMAPS ], Vector3 (&colors)[ MAX_LIGHTMAPS ], const Vector3& ambientColor ){
int i, lightmapNum;
@@ -1200,10 +1200,7 @@ void LightingAtSample( trace_t *trace, byte styles[ MAX_LIGHTMAPS ], Vector3 (&c
return;
}
/* ydnar: don't bounce ambient all the time */
if ( !bouncing ) {
colors[ 0 ] = ambientColor;
}
colors[ 0 ] = ambientColor;
/* ydnar: trace to all the list of lights pre-stored in tw */
for ( i = 0; i < trace->numLights && trace->lights[ i ] != nullptr; ++i )
@@ -1728,7 +1725,7 @@ static void TraceGrid( int num ){
calculates the size of the lightgrid and allocates memory
*/
static void SetupGrid(){
static void SetupGrid( const Vector3& ambientColor ){
/* don't do this if not grid lighting */
if ( noGridLighting ) {
return;
@@ -1958,7 +1955,7 @@ static void LightWorld( bool fastAllocate, bool bounceStore ){
ColorFromSRGB( color );
/* ambient */
ambientColor = color * entities[ 0 ].floatForKey( "_ambient", "ambient" );
const Vector3 ambientColor = color * entities[ 0 ].floatForKey( "_ambient", "ambient" );
/* minvertexlight */
if ( ( minVertex = entities[ 0 ].read_keyvalue( f, "_minvertexlight" ) ) ) {
@@ -1986,7 +1983,7 @@ static void LightWorld( bool fastAllocate, bool bounceStore ){
/* determine the number of grid points */
Sys_Printf( "--- SetupGrid ---\n" );
SetupGrid(); // uses ambientColor read above
SetupGrid( ambientColor );
/* create world lights */
Sys_FPrintf( SYS_VRB, "--- CreateLights ---\n" );
@@ -2075,7 +2072,11 @@ static void LightWorld( bool fastAllocate, bool bounceStore ){
/* flag bouncing */
bouncing = true;
ambientColor.set( 0 );
/* ydnar: don't bounce ambient all the time */
for( rawLightmap_t& lm : Span( rawLightmaps, numRawLightmaps ) )
lm.ambientColor.set( 0 );
for( surfaceInfo_t& info : Span( surfaceInfos, bspDrawSurfaces.size() ) )
info.ambientColor.set( 0 );
floodlighty = false;
/* delete any existing lights, freeing up memory for the next bounce */
+15 -15
View File
@@ -2353,10 +2353,10 @@ void IlluminateRawLightmap( int rawLightmapNum ){
/* set ambient */
else
{
luxel.value = ambientColor;
luxel.value = lm->ambientColor;
if ( deluxemap ) {
// use AT LEAST this amount of contribution from ambient for the deluxemap, fixes points that receive ZERO light
const float brightness = std::max( 0.00390625f, RGBTOGRAY( ambientColor ) * ( 1.0f / 255.0f ) );
const float brightness = std::max( 0.00390625f, RGBTOGRAY( lm->ambientColor ) * ( 1.0f / 255.0f ) );
lm->getSuperDeluxel( x, y ) = lm->getSuperNormal( x, y ) * brightness;
}
@@ -2809,9 +2809,9 @@ void IlluminateRawLightmap( int rawLightmapNum ){
filterColor = false;
filterDir = false;
if ( cluster < CLUSTER_NORMAL ||
( lm->splotchFix && ( luxel.value[ 0 ] <= ambientColor[ 0 ]
|| luxel.value[ 1 ] <= ambientColor[ 1 ]
|| luxel.value[ 2 ] <= ambientColor[ 2 ] ) ) ) {
( lm->splotchFix && ( luxel.value[ 0 ] <= lm->ambientColor[ 0 ]
|| luxel.value[ 1 ] <= lm->ambientColor[ 1 ]
|| luxel.value[ 2 ] <= lm->ambientColor[ 2 ] ) ) ) {
filterColor = true;
}
@@ -2846,7 +2846,7 @@ void IlluminateRawLightmap( int rawLightmapNum ){
/* ignore unmapped/unlit luxels */
if ( lm->getSuperCluster( sx, sy ) < CLUSTER_NORMAL || luxel2.count == 0.0f ||
( lm->splotchFix && VectorCompare( luxel2.value, ambientColor ) ) ) {
( lm->splotchFix && VectorCompare( luxel2.value, lm->ambientColor ) ) ) {
continue;
}
@@ -2867,7 +2867,7 @@ void IlluminateRawLightmap( int rawLightmapNum ){
/* dark lightmap seams */
if ( dark ) {
if ( lightmapNum == 0 ) {
averageColor += ambientColor * 2;
averageColor += lm->ambientColor * 2;
}
samples += 2.0f;
}
@@ -3043,7 +3043,7 @@ void IlluminateVertexes( int num ){
}
/* trace */
LightingAtSample( &trace, ds->vertexStyles, colors );
LightingAtSample( &trace, ds->vertexStyles, colors, info->ambientColor );
/* store */
for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; ++lightmapNum )
@@ -3064,7 +3064,7 @@ void IlluminateVertexes( int num ){
const auto vector3_component_greater = []( const Vector3& greater, const Vector3& lesser ){
return greater[0] > lesser[0] || greater[1] > lesser[1] || greater[2] > lesser[2];
};
if ( !vector3_component_greater( getRadVertexLuxel( 0, ds->firstVert + i ), ambientColor ) ) {
if ( !vector3_component_greater( getRadVertexLuxel( 0, ds->firstVert + i ), info->ambientColor ) ) {
/* nudge the sample point around a bit */
for ( x = 0; x < 5; ++x )
{
@@ -3105,7 +3105,7 @@ void IlluminateVertexes( int num ){
}
/* trace */
LightingAtSample( &trace, ds->vertexStyles, colors );
LightingAtSample( &trace, ds->vertexStyles, colors, info->ambientColor );
/* store */
for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; ++lightmapNum )
@@ -3121,7 +3121,7 @@ void IlluminateVertexes( int num ){
}
/* bright enough? */
if ( vector3_component_greater( getRadVertexLuxel( 0, ds->firstVert + i ), ambientColor ) ) {
if ( vector3_component_greater( getRadVertexLuxel( 0, ds->firstVert + i ), info->ambientColor ) ) {
x = y = z = 1000;
}
}
@@ -3130,7 +3130,7 @@ void IlluminateVertexes( int num ){
}
/* add to average? */
if ( vector3_component_greater( getRadVertexLuxel( 0, ds->firstVert + i ), ambientColor ) ) {
if ( vector3_component_greater( getRadVertexLuxel( 0, ds->firstVert + i ), info->ambientColor ) ) {
numAvg++;
for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; ++lightmapNum )
{
@@ -3150,7 +3150,7 @@ void IlluminateVertexes( int num ){
}
else
{
avgColors[ 0 ] = ambientColor;
avgColors[ 0 ] = info->ambientColor;
}
/* clean up and store vertex color */
@@ -3268,7 +3268,7 @@ void IlluminateVertexes( int num ){
}
/* testing: must be brigher than ambient color */
//% if( luxel[ 0 ] <= ambientColor[ 0 ] || luxel[ 1 ] <= ambientColor[ 1 ] || luxel[ 2 ] <= ambientColor[ 2 ] )
//% if( luxel[ 0 ] <= info->ambientColor[ 0 ] || luxel[ 1 ] <= info->ambientColor[ 1 ] || luxel[ 2 ] <= info->ambientColor[ 2 ] )
//% continue;
/* add its distinctiveness to our own */
@@ -3283,7 +3283,7 @@ void IlluminateVertexes( int num ){
radVertLuxel *= ( 1.f / samples );
}
else{
radVertLuxel = ambientColor;
radVertLuxel = info->ambientColor;
}
}
+4 -1
View File
@@ -592,6 +592,7 @@ static bool AddSurfaceToRawLightmap( int num, rawLightmap_t *lm ){
/* match identical attributes */
if ( info->sampleSize != lm->sampleSize ||
info->ambientColor != lm->ambientColor || // may be different inside one entityNum for attached misc_models
info->entityNum != lm->entityNum ||
info->recvShadows != lm->recvShadows ||
info->si->lmCustomWidth != lm->customWidth ||
@@ -999,6 +1000,7 @@ void SetupSurfaceLightmaps(){
info->castShadows = se.castShadows;
info->recvShadows = se.recvShadows;
info->sampleSize = se.sampleSize;
info->ambientColor = se.ambientColor;
info->longestCurve = se.longestCurve;
info->patchIterations = IterationsForCurve( info->longestCurve, patchSubdivisions );
info->axis = se.lightmapAxis;
@@ -1103,6 +1105,7 @@ void SetupSurfaceLightmaps(){
lm->recvShadows = info->recvShadows;
lm->brightness = info->si->lmBrightness;
lm->filterRadius = info->si->lmFilterRadius;
lm->ambientColor = info->ambientColor;
lm->floodlightRGB = info->si->floodlightRGB;
lm->floodlightDistance = info->si->floodlightDistance;
lm->floodlightIntensity = info->si->floodlightIntensity;
@@ -2490,7 +2493,7 @@ void StoreSurfaceLightmaps( bool fastAllocate, bool storeForReal ){
/* if any samples were mapped in any way, store ambient color */
else if ( mappedSamples > 0 ) {
if ( lightmapNum == 0 ) {
luxel.value = ambientColor;
luxel.value = lm->ambientColor;
}
else{
luxel.value.set( 0 );
+75 -53
View File
@@ -1468,6 +1468,65 @@ static void LoadEntityIndexMap( entity_t& e ){
p->im = im;
}
EntityCompileParams ParseEntityCompileParams( const entity_t& e, const entity_t *eparent, bool worldShadowGroup ){
EntityCompileParams params;
const char *classname = e.classname();
/* worldspawn (and func_groups) default to cast/recv shadows in worldspawn group */
if ( worldShadowGroup ) { // or misc_model without non world "_target", "target"
//% Sys_Printf( "World: %d\n", e.mapEntityNum );
params.castShadows = WORLDSPAWN_CAST_SHADOWS;
params.recvShadows = WORLDSPAWN_RECV_SHADOWS;
}
else{ /* other entities don't cast any shadows, but recv worldspawn shadows */
//% Sys_Printf( "Entity: %d\n", e.mapEntityNum );
params.castShadows = ENTITY_CAST_SHADOWS;
params.recvShadows = ENTITY_RECV_SHADOWS;
}
/* get explicit shadow flags */
GetEntityShadowFlags( &e, eparent, &params.castShadows, &params.recvShadows );
/* ydnar: get lightmap scaling value for this entity */
params.lightmapScale = std::max( 0.f, e.floatForKey( "lightmapscale", "_lightmapscale", "_ls" ) );
if ( params.lightmapScale != 0 )
Sys_Printf( "Entity %d (%s) has lightmap scale of %.4f\n", e.mapEntityNum, classname, params.lightmapScale );
/* ydnar: get cel shader :) for this entity */
if( const char *value; e.read_keyvalue( value, "_celshader" ) ||
entities[ 0 ].read_keyvalue( value, "_celshader" ) ){
params.celShader = &ShaderInfoForShader( String64( "textures/", value ) );
Sys_Printf( "Entity %d (%s) has cel shader %s\n", e.mapEntityNum, classname, params.celShader->shader.c_str() );
}
else{
params.celShader = globalCelShader.empty() ? nullptr : &ShaderInfoForShader( globalCelShader );
}
/* jal : entity based _shadeangle */
params.shadeAngle = std::max( 0.f, e.floatForKey( "_shadeangle",
"_smoothnormals", "_sn", "_sa", "_smooth" ) ); /* vortex' aliases */
if ( params.shadeAngle != 0 )
Sys_Printf( "Entity %d (%s) has shading angle of %.4f\n", e.mapEntityNum, classname, params.shadeAngle );
/* jal : entity based _samplesize */
params.lightmapSampleSize = std::max( 0, e.intForKey( "_lightmapsamplesize", "_samplesize", "_ss" ) );
if ( params.lightmapSampleSize != 0 )
Sys_Printf( "Entity %d (%s) has lightmap sample size of %d\n", e.mapEntityNum, classname, params.lightmapSampleSize );
/* ambient */
params.ambientColor = e.vectorForKey( "_color" );
if ( params.ambientColor == g_vector3_identity )
params.ambientColor.set( 1 );
else
ColorFromSRGB( params.ambientColor );
params.ambientColor *= e.floatForKey( "_ambient", "ambient" );
if ( params.ambientColor != g_vector3_identity )
Sys_Printf( "Entity %d (%s) has ambient of %f %f %f\n", e.mapEntityNum, classname,
params.ambientColor[0], params.ambientColor[1], params.ambientColor[2] );
return params;
}
@@ -1563,70 +1622,33 @@ static bool ParseMapEntity( bool onlyLights, bool noCollapseGroups, int mapEntit
/* ydnar: determine if this is a func_group */
const bool funcGroup = striEqual( "func_group", classname );
/* worldspawn (and func_groups) default to cast/recv shadows in worldspawn group */
int castShadows, recvShadows;
if ( funcGroup || mapEnt.mapEntityNum == 0 ) {
//% Sys_Printf( "World: %d\n", mapEnt.mapEntityNum );
castShadows = WORLDSPAWN_CAST_SHADOWS;
recvShadows = WORLDSPAWN_RECV_SHADOWS;
}
else{ /* other entities don't cast any shadows, but recv worldspawn shadows */
//% Sys_Printf( "Entity: %d\n", mapEnt.mapEntityNum );
castShadows = ENTITY_CAST_SHADOWS;
recvShadows = ENTITY_RECV_SHADOWS;
}
const EntityCompileParams params = ParseEntityCompileParams( mapEnt, nullptr, funcGroup || mapEnt.mapEntityNum == 0 );
/* get explicit shadow flags */
GetEntityShadowFlags( &mapEnt, nullptr, &castShadows, &recvShadows );
/* ydnar: get lightmap scaling value for this entity */
const float lightmapScale = std::max( 0.f, mapEnt.floatForKey( "lightmapscale", "_lightmapscale", "_ls" ) );
if ( lightmapScale != 0 )
Sys_Printf( "Entity %d (%s) has lightmap scale of %.4f\n", mapEnt.mapEntityNum, classname, lightmapScale );
/* ydnar: get cel shader :) for this entity */
shaderInfo_t *celShader;
const char *value;
if( mapEnt.read_keyvalue( value, "_celshader" ) ||
entities[ 0 ].read_keyvalue( value, "_celshader" ) ){
celShader = &ShaderInfoForShader( String64( "textures/", value ) );
Sys_Printf( "Entity %d (%s) has cel shader %s\n", mapEnt.mapEntityNum, classname, celShader->shader.c_str() );
}
else{
celShader = globalCelShader.empty() ? nullptr : &ShaderInfoForShader( globalCelShader );
}
/* jal : entity based _shadeangle */
const float shadeAngle = std::max( 0.f, mapEnt.floatForKey( "_shadeangle",
"_smoothnormals", "_sn", "_sa", "_smooth" ) ); /* vortex' aliases */
if ( shadeAngle != 0 )
Sys_Printf( "Entity %d (%s) has shading angle of %.4f\n", mapEnt.mapEntityNum, classname, shadeAngle );
/* jal : entity based _samplesize */
const int lightmapSampleSize = std::max( 0, mapEnt.intForKey( "_lightmapsamplesize", "_samplesize", "_ss" ) );
if ( lightmapSampleSize != 0 )
Sys_Printf( "Entity %d (%s) has lightmap sample size of %d\n", mapEnt.mapEntityNum, classname, lightmapSampleSize );
if( mapEnt.mapEntityNum == 0 )
SetDefaultAmbientColor( params.ambientColor );
/* attach stuff to everything in the entity */
for ( brush_t& brush : mapEnt.brushes )
{
brush.entityNum = mapEnt.mapEntityNum;
brush.castShadows = castShadows;
brush.recvShadows = recvShadows;
brush.lightmapSampleSize = lightmapSampleSize;
brush.lightmapScale = lightmapScale;
brush.celShader = celShader;
brush.shadeAngleDegrees = shadeAngle;
brush.castShadows = params.castShadows;
brush.recvShadows = params.recvShadows;
brush.lightmapSampleSize = params.lightmapSampleSize;
brush.lightmapScale = params.lightmapScale;
brush.celShader = params.celShader;
brush.shadeAngleDegrees = params.shadeAngle;
brush.ambientColor = params.ambientColor;
}
for ( parseMesh_t *patch = mapEnt.patches; patch != nullptr; patch = patch->next )
{
patch->entityNum = mapEnt.mapEntityNum;
patch->castShadows = castShadows;
patch->recvShadows = recvShadows;
patch->lightmapSampleSize = lightmapSampleSize;
patch->lightmapScale = lightmapScale;
patch->celShader = celShader;
patch->castShadows = params.castShadows;
patch->recvShadows = params.recvShadows;
patch->lightmapSampleSize = params.lightmapSampleSize;
patch->lightmapScale = params.lightmapScale;
patch->celShader = params.celShader;
patch->ambientColor = params.ambientColor;
}
/* ydnar: gs mods: set entity bounds */
+15 -63
View File
@@ -982,7 +982,8 @@ default_CLIPMODEL:
adds a picomodel into the bsp
*/
void InsertModel( const char *name, const char *skin, int frame, const Matrix4& transform, const std::list<remap_t> *remaps, shaderInfo_t *celShader, entity_t& entity, int castShadows, int recvShadows, int spawnFlags, float lightmapScale, int lightmapSampleSize, float shadeAngle, float clipDepth ){
void InsertModel( const char *name, const char *skin, int frame, const Matrix4& transform, const std::list<remap_t> *remaps,
entity_t& entity, int spawnFlags, float clipDepth, const EntityCompileParams& params ){
int i, j;
const Matrix4 nTransform( matrix4_for_normal_transform( transform ) );
const bool transform_lefthanded = MATRIX4_LEFTHANDED == matrix4_handedness( transform );
@@ -1057,16 +1058,6 @@ void InsertModel( const char *name, const char *skin, int frame, const Matrix4&
uncomment the following line with old m4x4_t (non 1.3/spog_branch) code */
//% m4x4_transpose( transform );
/* fix bogus lightmap scale */
if ( lightmapScale <= 0.0f ) {
lightmapScale = 1.0f;
}
/* fix bogus shade angle */
if ( shadeAngle <= 0.0f ) {
shadeAngle = 0.0f;
}
/* each surface on the model will become a new map drawsurface */
//% Sys_FPrintf( SYS_VRB, "Model %s has %d surfaces\n", name, numSurfaces );
for ( const auto& surface : model->m_meshes )
@@ -1122,8 +1113,10 @@ void InsertModel( const char *name, const char *skin, int frame, const Matrix4&
/* allocate a surface (ydnar: gs mods) */
ds = AllocDrawSurface( ESurfaceType::Triangles );
ds->entityNum = entity.mapEntityNum;
ds->castShadows = castShadows;
ds->recvShadows = recvShadows;
ds->castShadows = params.castShadows;
ds->recvShadows = params.recvShadows;
ds->celShader = params.celShader;
ds->ambientColor = params.ambientColor;
/* set shader */
ds->shaderInfo = &si;
@@ -1134,23 +1127,23 @@ void InsertModel( const char *name, const char *skin, int frame, const Matrix4&
}
/* fix the surface's normals (jal: conditioned by shader info) */
if ( !( spawnFlags & eNoSmooth ) && ( shadeAngle == 0.0f || ds->type != ESurfaceType::ForcedMeta ) ) {
if ( !( spawnFlags & eNoSmooth ) && ( params.shadeAngle == 0.0f || ds->type != ESurfaceType::ForcedMeta ) ) {
// PicoFixSurfaceNormals( surface );
}
/* set sample size */
if ( lightmapSampleSize > 0.0f ) {
ds->sampleSize = lightmapSampleSize;
if ( params.lightmapSampleSize > 0.0f ) {
ds->sampleSize = params.lightmapSampleSize;
}
/* set lightmap scale */
if ( lightmapScale > 0.0f ) {
ds->lightmapScale = lightmapScale;
if ( params.lightmapScale > 0.0f ) {
ds->lightmapScale = params.lightmapScale;
}
/* set shading angle */
if ( shadeAngle > 0.0f ) {
ds->shadeAngleDegrees = shadeAngle;
if ( params.shadeAngle > 0.0f ) {
ds->shadeAngleDegrees = params.shadeAngle;
}
/* set particulars */
@@ -1229,9 +1222,6 @@ void InsertModel( const char *name, const char *skin, int frame, const Matrix4&
}
}
/* set cel shader */
ds->celShader = celShader;
ClipModel( spawnFlags, clipDepth, si, ds, name, entity );
}
}
@@ -1284,19 +1274,6 @@ void AddTriangleModels( entity_t& eparent ){
/* get model frame */
const int frame = e.intForKey( "_frame", "frame" );
int castShadows, recvShadows;
if ( &eparent == &entities[0] ) { /* worldspawn (and func_groups) default to cast/recv shadows in worldspawn group */
castShadows = WORLDSPAWN_CAST_SHADOWS;
recvShadows = WORLDSPAWN_RECV_SHADOWS;
}
else{ /* other entities don't cast any shadows, but recv worldspawn shadows */
castShadows = ENTITY_CAST_SHADOWS;
recvShadows = ENTITY_RECV_SHADOWS;
}
/* get explicit shadow flags */
GetEntityShadowFlags( &e, &eparent, &castShadows, &recvShadows );
/* get spawnflags */
const int spawnFlags = e.intForKey( "spawnflags" );
@@ -1357,32 +1334,6 @@ void AddTriangleModels( entity_t& eparent ){
}
}
/* ydnar: cel shader support */
shaderInfo_t *celShader;
if( const char *value; e.read_keyvalue( value, "_celshader" ) ||
entities[ 0 ].read_keyvalue( value, "_celshader" ) ){
celShader = &ShaderInfoForShader( String64( "textures/", value ) );
}
else{
celShader = globalCelShader.empty() ? nullptr : &ShaderInfoForShader( globalCelShader );
}
/* jal : entity based _samplesize */
const int lightmapSampleSize = std::max( 0, e.intForKey( "_lightmapsamplesize", "_samplesize", "_ss" ) );
if ( lightmapSampleSize != 0 )
Sys_Printf( "misc_model has lightmap sample size of %.d\n", lightmapSampleSize );
/* get lightmap scale */
const float lightmapScale = std::max( 0.f, e.floatForKey( "lightmapscale", "_lightmapscale", "_ls" ) );
if ( lightmapScale != 0 )
Sys_Printf( "misc_model has lightmap scale of %.4f\n", lightmapScale );
/* jal : entity based _shadeangle */
const float shadeAngle = std::max( 0.f, e.floatForKey( "_shadeangle",
"_smoothnormals", "_sn", "_sa", "_smooth" ) ); /* vortex' aliases */
if ( shadeAngle != 0 )
Sys_Printf( "misc_model has shading angle of %.4f\n", shadeAngle );
const char *skin = nullptr;
e.read_keyvalue( skin, "_skin", "skin" );
@@ -1390,8 +1341,9 @@ void AddTriangleModels( entity_t& eparent ){
if ( e.read_keyvalue( clipDepth, "_clipdepth" ) )
Sys_Printf( "misc_model %s has autoclip depth of %.3f\n", model, clipDepth );
const EntityCompileParams params = ParseEntityCompileParams( e, &eparent, &eparent == &entities[ 0 ] );
/* insert the model */
InsertModel( model, skin, frame, transform, &remaps, celShader, eparent, castShadows, recvShadows, spawnFlags, lightmapScale, lightmapSampleSize, shadeAngle, clipDepth );
InsertModel( model, skin, frame, transform, &remaps, eparent, spawnFlags, clipDepth, params );
}
}
+25 -3
View File
@@ -720,6 +720,7 @@ struct brush_t
int lightmapSampleSize; /* jal : entity based _lightmapsamplesize */
float lightmapScale;
float shadeAngleDegrees; /* jal : entity based _shadeangle */
Vector3 ambientColor;
MinMax eMinmax;
indexMap_t *im;
@@ -767,6 +768,7 @@ struct parseMesh_t
/* ydnar: gs mods */
int lightmapSampleSize; /* jal : entity based _lightmapsamplesize */
float lightmapScale;
Vector3 ambientColor;
MinMax eMinmax;
indexMap_t *im;
@@ -776,6 +778,18 @@ struct parseMesh_t
};
struct EntityCompileParams
{
int castShadows;
int recvShadows;
shaderInfo_t *celShader;
int lightmapSampleSize;
float lightmapScale;
float shadeAngle;
Vector3 ambientColor;
};
/*
ydnar: the drawsurf struct was extended to allow for:
- non-convex planar surfaces
@@ -860,6 +874,9 @@ struct mapDrawSurface_t
/* jal: per-surface (per-entity, actually) shadeangle */
float shadeAngleDegrees;
/* per-surface (per-entity, actually) ambientColor */
Vector3 ambientColor;
/* ydnar: surface classification */
MinMax minmax;
Vector3 lightmapAxis;
@@ -1202,6 +1219,8 @@ struct rawLightmap_t
int sampleSize, actualSampleSize, axisNum;
Vector3 ambientColor;
/* vortex: per-surface floodlight */
float floodlightDirectionScale;
Vector3 floodlightRGB;
@@ -1322,6 +1341,7 @@ struct surfaceInfo_t
rawLightmap_t *lm;
int parentSurfaceNum, childSurfaceNum;
int entityNum, castShadows, recvShadows, sampleSize, patchIterations;
Vector3 ambientColor;
float longestCurve;
Plane3f *plane;
Vector3 axis;
@@ -1492,6 +1512,7 @@ inline int FindFloatPlane( const Vector3& normal, float dist, i
}
bool PlaneEqual( const plane_t& p, const Plane3f& plane );
void AddBrushBevels();
EntityCompileParams ParseEntityCompileParams( const entity_t& e, const entity_t *eparent, bool worldShadowGroup );
/* portals.c */
@@ -1568,7 +1589,8 @@ tree_t FaceBSP( facelist_t& list );
/* model.c */
void assimp_init();
void InsertModel( const char *name, const char *skin, int frame, const Matrix4& transform, const std::list<remap_t> *remaps, shaderInfo_t *celShader, entity_t& entity, int castShadows, int recvShadows, int spawnFlags, float lightmapScale, int lightmapSampleSize, float shadeAngle, float clipDepth );
void InsertModel( const char *name, const char *skin, int frame, const Matrix4& transform, const std::list<remap_t> *remaps,
entity_t& entity, int spawnFlags, float clipDepth, const EntityCompileParams& params );
void AddTriangleModels( entity_t& eparent );
@@ -1612,6 +1634,7 @@ void EmitMetaStats(); // vortex: print meta statistics ev
/* surface_extra.c */
void SetDefaultSampleSize( int sampleSize );
void SetDefaultAmbientColor( const Vector3& color );
void SetSurfaceExtra( const mapDrawSurface_t& ds );
void WriteSurfaceExtraFile( const char *path );
void LoadSurfaceExtraFile( const char *path );
@@ -1631,7 +1654,7 @@ int VisMain( Args& args );
/* light.c */
float PointToPolygonFormFactor( const Vector3& point, const Vector3& normal, const winding_t& w );
int LightContributionToSample( trace_t *trace );
void LightingAtSample( trace_t * trace, byte styles[ MAX_LIGHTMAPS ], Vector3 (&colors)[ MAX_LIGHTMAPS ] );
void LightingAtSample( trace_t * trace, byte styles[ MAX_LIGHTMAPS ], Vector3 (&colors)[ MAX_LIGHTMAPS ], const Vector3& ambientColor );
int LightMain( Args& args );
@@ -2064,7 +2087,6 @@ inline std::vector<bspDrawVert_t> yDrawVerts;
inline const int defaultLightSubdivide = 999;
inline Vector3 ambientColor;
inline Vector3 minLight, minVertexLight, minGridLight;
inline float maxLight = 255.f;
+12 -2
View File
@@ -760,6 +760,7 @@ mapDrawSurface_t *DrawSurfaceForSide( const entity_t& e, const brush_t& b, const
ds->fogNum = FOG_INVALID;
ds->sampleSize = b.lightmapSampleSize;
ds->lightmapScale = b.lightmapScale;
ds->ambientColor = b.ambientColor;
ds->numVerts = w.size();
ds->verts = safe_calloc( ds->numVerts * sizeof( *ds->verts ) );
@@ -930,6 +931,7 @@ mapDrawSurface_t *DrawSurfaceForMesh( const entity_t& e, parseMesh_t *p, mesh_t
ds->mapMesh = p;
ds->sampleSize = p->lightmapSampleSize;
ds->lightmapScale = p->lightmapScale; /* ydnar */
ds->ambientColor = p->ambientColor;
ds->patchWidth = mesh->width;
ds->patchHeight = mesh->height;
ds->numVerts = ds->patchWidth * ds->patchHeight;
@@ -2864,8 +2866,16 @@ static int AddSurfaceModelsToTriangle_r( mapDrawSurface_t *ds, const surfaceMode
}
/* insert the model */
InsertModel( model.model.c_str(), nullptr, 0, transform, nullptr, ds->celShader, entity, ds->castShadows, ds->recvShadows, 0, ds->lightmapScale, 0, 0, clipDepthGlobal );
InsertModel( model.model.c_str(), nullptr, 0, transform, nullptr, entity, 0, clipDepthGlobal,
EntityCompileParams{
.castShadows = ds->castShadows,
.recvShadows = ds->recvShadows,
.celShader = ds->celShader,
.lightmapSampleSize = 0,
.lightmapScale = ds->lightmapScale,
.shadeAngle = 0,
.ambientColor = ds->ambientColor
} );
/* return to sender */
return 1;
}
+13
View File
@@ -54,6 +54,10 @@ void SetDefaultSampleSize( int sampleSize ){
seDefault.sampleSize = sampleSize;
}
void SetDefaultAmbientColor( const Vector3& color ){
seDefault.ambientColor = color;
}
/*
@@ -73,6 +77,7 @@ void SetSurfaceExtra( const mapDrawSurface_t& ds ){
se.castShadows = ds.castShadows;
se.recvShadows = ds.recvShadows;
se.sampleSize = ds.sampleSize;
se.ambientColor = ds.ambientColor;
se.longestCurve = ds.longestCurve;
se.lightmapAxis = ds.lightmapAxis;
@@ -175,6 +180,10 @@ void WriteSurfaceExtraFile( const char *path ){
fprintf( sf, "\tsampleSize %d\n", se->sampleSize );
}
if ( se->ambientColor != seDefault.ambientColor || se == &seDefault ) {
fprintf( sf, "\tambientColor ( %f %f %f )\n", se->ambientColor[0], se->ambientColor[1], se->ambientColor[2] );
}
/* longest curve */
if ( se->longestCurve != seDefault.longestCurve || se == &seDefault ) {
fprintf( sf, "\tlongestCurve %f\n", se->longestCurve );
@@ -279,6 +288,10 @@ void LoadSurfaceExtraFile( const char *path ){
se->sampleSize = atoi( token );
}
else if ( striEqual( token, "ambientColor" ) ) {
Parse1DMatrix( 3, se->ambientColor.data() );
}
/* longest curve */
else if ( striEqual( token, "longestCurve" ) ) {
GetToken( false );
+1
View File
@@ -32,6 +32,7 @@ struct surfaceExtra_t
int castShadows = WORLDSPAWN_CAST_SHADOWS;
int recvShadows = WORLDSPAWN_RECV_SHADOWS;
int sampleSize = 0;
Vector3 ambientColor{ 0, 0, 0 };
float longestCurve = 0;
Vector3 lightmapAxis{ 0, 0, 0 };
};
+10 -1
View File
@@ -251,7 +251,16 @@ void Foliage( mapDrawSurface_t *src, entity_t& entity ){
const int oldNumMapDrawSurfs = numMapDrawSurfs;
/* add the model to the bsp */
InsertModel( foliage.model.c_str(), nullptr, 0, matrix4_scale_for_vec3( Vector3( foliage.scale ) ), nullptr, nullptr, entity, src->castShadows, src->recvShadows, 0, src->lightmapScale, 0, 0, clipDepthGlobal );
InsertModel( foliage.model.c_str(), nullptr, 0, matrix4_scale_for_vec3( Vector3( foliage.scale ) ), nullptr, entity, 0, clipDepthGlobal,
EntityCompileParams {
.castShadows = src->castShadows,
.recvShadows = src->recvShadows,
.celShader = nullptr,
.lightmapSampleSize = 0,
.lightmapScale = src->lightmapScale,
.shadeAngle = 0,
.ambientColor = src->ambientColor
} );
/* walk each new surface */
for ( int i = oldNumMapDrawSurfs; i < numMapDrawSurfs; ++i )
+14 -1
View File
@@ -73,6 +73,7 @@ struct metaTriangle_t
const side_t *side;
int entityNum, surfaceNum, planeNum, fogNum, sampleSize, castShadows, recvShadows;
float shadeAngleDegrees;
Vector3 ambientColor;
Plane3f plane;
Vector3 lightmapAxis;
std::array<metaVertex_t*, 3> m_vertices;
@@ -174,6 +175,15 @@ struct CompareMetaTriangles
else if ( a.sampleSize != b.sampleSize ) {
return a.sampleSize < b.sampleSize;
}
else if ( a.ambientColor[0] != b.ambientColor[0] ) { // may be different inside one entityNum for attached misc_models
return a.ambientColor[0] < b.ambientColor[0];
}
else if ( a.ambientColor[1] != b.ambientColor[1] ) {
return a.ambientColor[1] < b.ambientColor[1];
}
else if ( a.ambientColor[2] != b.ambientColor[2] ) {
return a.ambientColor[2] < b.ambientColor[2];
}
/* then position in world */
if constexpr ( sort_spatially ){
@@ -190,7 +200,8 @@ struct CompareMetaTriangles
&& ( a.entityNum == b.entityNum )
&& ( a.castShadows == b.castShadows )
&& ( a.recvShadows == b.recvShadows )
&& ( a.sampleSize == b.sampleSize );
&& ( a.sampleSize == b.sampleSize )
&& ( a.ambientColor == b.ambientColor );
}
};
@@ -319,6 +330,7 @@ static void SurfaceToMetaTriangles( mapDrawSurface_t *ds ){
src.fogNum = ds->fogNum;
src.sampleSize = ds->sampleSize;
src.shadeAngleDegrees = ds->shadeAngleDegrees;
src.ambientColor = ds->ambientColor;
src.lightmapAxis = ds->lightmapAxis;
metaTriangle_insert( src, { ds->verts[ ds->indexes[ i ] ],
@@ -1542,6 +1554,7 @@ static void MetaTrianglesToSurface( int *fOld, int *numAdded ){
ds->fogNum = seed.fogNum;
ds->sampleSize = seed.sampleSize;
ds->shadeAngleDegrees = seed.shadeAngleDegrees;
ds->ambientColor = seed.ambientColor;
ds->verts = verts;
ds->indexes = indexes;
ds->lightmapAxis = seed.lightmapAxis;