misc_model _skin/skin key: handle both DP and Q3 naming conventions

disable trying skin 0 by default
not that it does much atm, as assimp md3 loader handles .skin and shader name substitution alters non path names
handle \r\n endlines in .skin
This commit is contained in:
Garux 2021-11-10 22:25:45 +03:00
parent 76017a8ce3
commit b474073ebe
6 changed files with 22 additions and 21 deletions

View File

@ -211,7 +211,7 @@ td.formatted_questions ol { margin-top: 0px; margin-bottom: 0px; }
<li><strong><code>_clipdepth</code>:</strong> thickness of autoclip brushes</li> <li><strong><code>_clipdepth</code>:</strong> thickness of autoclip brushes</li>
<li><strong><code>_frame</code>, <code>frame</code>:</strong> frame of model to load (doesn't work)</li> <li><strong><code>_frame</code>, <code>frame</code>:</strong> frame of model to load (doesn't work)</li>
<li><strong><code>_remapXXX</code>:</strong> <code>XXX</code> can be any string to allow multiple keys for this; contains a string of the form <code>from;to</code>, and any shader <code>from</code> in the model will be replaced by <code>to</code>; the special value <code>*</code> in <code>from</code> matches all shader names</li> <li><strong><code>_remapXXX</code>:</strong> <code>XXX</code> can be any string to allow multiple keys for this; contains a string of the form <code>from;to</code>, and any shader <code>from</code> in the model will be replaced by <code>to</code>; the special value <code>*</code> in <code>from</code> matches all shader names</li>
<li><strong><code>_skin</code>, <code>skin</code>:</strong> skin number to use</li> <li><strong><code>_skin</code>, <code>skin</code>:</strong> skin number (DarkPlaces convention) or name (Quake3 convention) to use</li>
<!-- <li><strong><code>model2</code>:</strong> path name of second model to load</li> light code reads this for brush entities--> <!-- <li><strong><code>model2</code>:</strong> path name of second model to load</li> light code reads this for brush entities-->
<li><strong><code>model</code>:</strong> path name of model to load</li> <li><strong><code>model</code>:</strong> path name of model to load</li>
<li><strong><code>modelscale</code>:</strong> scaling factor for the model to include</li> <li><strong><code>modelscale</code>:</strong> scaling factor for the model to include</li>

View File

@ -88,7 +88,7 @@ textures/liquids/lavahell2 //path and name of new texture
--> -->
<h2 id="trans">qer_trans N.N</h2> <h2 id="trans">qer_trans N.N</h2>
<p>This directive makes brush transparent when seen in the editor (no effect on game rendering at all). It can have a positive value between 0 and 1. The higher the value, the less transparent the texture. Example: qer_trans 0.2 means the brush is 20% opaque and nearly invisible.</p> <p>This directive makes brush transparent when seen in the editor and filterable by 'translucent' filter (no effect on game rendering at all). It can have a positive value between 0 and 1. The higher the value, the less transparent the texture. Example: qer_trans 0.2 means the brush is 20% opaque and nearly invisible.</p>
<blockquote> <blockquote>
<h4>Design Notes:</h4> <h4>Design Notes:</h4>
<p>On GtkRadiant 1.4 and earlier, if the shader uses qer_trans and a qer_editorImage with an alpha channel, the transparent areas of the editorImage will be 100% transparent. To keep the solid areas of the editorImage opaque, use a near 1 value for qer_trans (eg. 0.9999). This is useful for grates, windows, fences, etc. If using GtkRadiant 1.5 or later, use qer_alphaFunc for editorImage masking instead.</p> <p>On GtkRadiant 1.4 and earlier, if the shader uses qer_trans and a qer_editorImage with an alpha channel, the transparent areas of the editorImage will be 100% transparent. To keep the solid areas of the editorImage opaque, use a near 1 value for qer_trans (eg. 0.9999). This is useful for grates, windows, fences, etc. If using GtkRadiant 1.5 or later, use qer_alphaFunc for editorImage masking instead.</p>

View File

@ -988,7 +988,7 @@ default_CLIPMODEL:
adds a picomodel into the bsp adds a picomodel into the bsp
*/ */
void InsertModel( const char *name, int 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, shaderInfo_t *celShader, entity_t& entity, int castShadows, int recvShadows, int spawnFlags, float lightmapScale, int lightmapSampleSize, float shadeAngle, float clipDepth ){
int i, j; int i, j;
const Matrix4 nTransform( matrix4_for_normal_transform( transform ) ); const Matrix4 nTransform( matrix4_for_normal_transform( transform ) );
const bool transform_lefthanded = MATRIX4_LEFTHANDED == matrix4_handedness( transform ); const bool transform_lefthanded = MATRIX4_LEFTHANDED == matrix4_handedness( transform );
@ -1006,27 +1006,27 @@ void InsertModel( const char *name, int skin, int frame, const Matrix4& transfor
/* load skin file */ /* load skin file */
std::list<remap_t> skins; std::list<remap_t> skins;
{ if( !strEmptyOrNull( skin ) ){
auto skinfilename = StringOutputStream(99)( PathExtensionless( name ), '_', skin, ".skin" ); const bool isnumber = std::all_of( skin, skin + strlen( skin ), ::isdigit );
MemBuffer skinfile = vfsLoadFile( skinfilename );
if ( skinfile && skin != 0 ) { StringOutputStream skinfilename( 99 );
/* fallback to skin 0 if invalid */ if( isnumber )
skinfilename( PathExtensionless( name ), "_0.skin" ); skinfilename( name, '_', skin, ".skin" ); // DarkPlaces naming: models/relics/relic.md3_14.skin for models/relics/relic.md3
skinfile = vfsLoadFile( skinfilename ); else
if ( skinfile ) { skinfilename( PathExtensionless( name ), '_', skin, ".skin" ); // Q3 naming: models/players/sarge/head_roderic.skin for models/players/sarge/head.md3
Sys_Printf( "Skin %d of %s does not exist, using 0 instead\n", skin, name );
} if ( MemBuffer skinfile = vfsLoadFile( skinfilename ) ) {
} Sys_Printf( "Using skin %s of %s\n", skin, name );
if ( skinfile ) {
Sys_Printf( "Using skin %d of %s\n", skin, name );
for ( char *skinfilenextptr, *skinfileptr = skinfile.data(); !strEmpty( skinfileptr ); skinfileptr = skinfilenextptr ) for ( char *skinfilenextptr, *skinfileptr = skinfile.data(); !strEmpty( skinfileptr ); skinfileptr = skinfilenextptr )
{ {
// for fscanf // for sscanf
char format[64]; char format[64];
skinfilenextptr = strchr( skinfileptr, '\r' ); skinfilenextptr = strchr( skinfileptr, '\r' );
if ( skinfilenextptr != NULL ) { if ( skinfilenextptr != NULL ) {
strClear( skinfilenextptr++ ); strClear( skinfilenextptr++ );
if( *skinfilenextptr == '\n' ) // handle \r\n
++skinfilenextptr;
} }
else else
{ {
@ -1400,7 +1400,8 @@ void AddTriangleModels( entity_t& eparent ){
if ( shadeAngle != 0 ) if ( shadeAngle != 0 )
Sys_Printf( "misc_model has shading angle of %.4f\n", shadeAngle ); Sys_Printf( "misc_model has shading angle of %.4f\n", shadeAngle );
const int skin = e.intForKey( "_skin", "skin" ); const char *skin = nullptr;
e.read_keyvalue( skin, "_skin", "skin" );
float clipDepth = clipDepthGlobal; float clipDepth = clipDepthGlobal;
if ( e.read_keyvalue( clipDepth, "_clipdepth" ) ) if ( e.read_keyvalue( clipDepth, "_clipdepth" ) )

View File

@ -1523,7 +1523,7 @@ tree_t FaceBSP( facelist_t& list );
/* model.c */ /* model.c */
void assimp_init(); void assimp_init();
void InsertModel( const char *name, int 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, shaderInfo_t *celShader, entity_t& entity, int castShadows, int recvShadows, int spawnFlags, float lightmapScale, int lightmapSampleSize, float shadeAngle, float clipDepth );
void AddTriangleModels( entity_t& eparent ); void AddTriangleModels( entity_t& eparent );

View File

@ -2811,7 +2811,7 @@ static int AddSurfaceModelsToTriangle_r( mapDrawSurface_t *ds, const surfaceMode
} }
/* insert the model */ /* insert the model */
InsertModel( model.model.c_str(), 0, 0, transform, NULL, ds->celShader, entity, ds->castShadows, ds->recvShadows, 0, ds->lightmapScale, 0, 0, clipDepthGlobal ); InsertModel( model.model.c_str(), NULL, 0, transform, NULL, ds->celShader, entity, ds->castShadows, ds->recvShadows, 0, ds->lightmapScale, 0, 0, clipDepthGlobal );
/* return to sender */ /* return to sender */
return 1; return 1;

View File

@ -255,7 +255,7 @@ void Foliage( mapDrawSurface_t *src, entity_t& entity ){
oldNumMapDrawSurfs = numMapDrawSurfs; oldNumMapDrawSurfs = numMapDrawSurfs;
/* add the model to the bsp */ /* add the model to the bsp */
InsertModel( foliage.model.c_str(), 0, 0, matrix4_scale_for_vec3( Vector3( foliage.scale ) ), NULL, NULL, entity, src->castShadows, src->recvShadows, 0, src->lightmapScale, 0, 0, clipDepthGlobal ); InsertModel( foliage.model.c_str(), NULL, 0, matrix4_scale_for_vec3( Vector3( foliage.scale ) ), NULL, NULL, entity, src->castShadows, src->recvShadows, 0, src->lightmapScale, 0, 0, clipDepthGlobal );
/* walk each new surface */ /* walk each new surface */
for ( i = oldNumMapDrawSurfs; i < numMapDrawSurfs; i++ ) for ( i = oldNumMapDrawSurfs; i < numMapDrawSurfs; i++ )