mirror of
https://github.com/Garux/netradiant-custom.git
synced 2026-09-28 00:00:03 +02:00
* support separated _ambient, _color per group, misc_model entities
This commit is contained in:
@@ -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>
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -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 ) );
|
||||
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
@@ -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, ¶ms.castShadows, ¶ms.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 */
|
||||
|
||||
@@ -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 );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 );
|
||||
|
||||
@@ -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 };
|
||||
};
|
||||
|
||||
@@ -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 )
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user