mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-03-14 22:50:45 +00:00
Parse idImportOptions for model declarations
This commit is contained in:
parent
e499514fea
commit
81d70dc5d8
3 changed files with 591 additions and 1 deletions
|
@ -3266,6 +3266,10 @@ bool idDeclModelDef::Parse( const char* text, const int textLength, bool allowBi
|
|||
jointHandle_t jointnum;
|
||||
idList<jointHandle_t> jointList;
|
||||
int numDefaultAnims;
|
||||
// RB: import options
|
||||
idStr defaultCommands;
|
||||
idStr temp;
|
||||
idStr parms;
|
||||
|
||||
src.LoadMemory( text, textLength, GetFileName(), GetLineNum() );
|
||||
src.SetFlags( DECL_LEXER_FLAGS );
|
||||
|
@ -3284,7 +3288,19 @@ bool idDeclModelDef::Parse( const char* text, const int textLength, bool allowBi
|
|||
break;
|
||||
}
|
||||
|
||||
if( token == "inherit" )
|
||||
// RB: add import options
|
||||
if( token == "options" )
|
||||
{
|
||||
src.ParseRestOfLine( defaultCommands );
|
||||
}
|
||||
else if( token == "addoptions" )
|
||||
{
|
||||
src.ParseRestOfLine( temp );
|
||||
defaultCommands += " ";
|
||||
defaultCommands += temp;
|
||||
}
|
||||
// RB end
|
||||
else if( token == "inherit" )
|
||||
{
|
||||
if( !src.ReadToken( &token2 ) )
|
||||
{
|
||||
|
@ -3344,6 +3360,36 @@ bool idDeclModelDef::Parse( const char* text, const int textLength, bool allowBi
|
|||
MakeDefault();
|
||||
return false;
|
||||
}
|
||||
|
||||
// RB: parse import options right after filename
|
||||
src.ParseRestOfLine( parms );
|
||||
|
||||
if( defaultCommands.Length() )
|
||||
{
|
||||
sprintf( temp, "%s %s", temp.c_str(), defaultCommands.c_str() );
|
||||
}
|
||||
|
||||
if( parms.Length() )
|
||||
{
|
||||
sprintf( temp, "%s %s", temp.c_str(), parms.c_str() );
|
||||
}
|
||||
|
||||
idImportOptions options;
|
||||
if( isGltf )
|
||||
{
|
||||
try
|
||||
{
|
||||
options.Init( temp.c_str(), filename.c_str() );
|
||||
}
|
||||
catch( idException& ex )
|
||||
{
|
||||
src.Warning( "Model '%s': Failed to parse import options'%s'", filename.c_str(), ex.GetError() );
|
||||
MakeDefault();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
// RB end
|
||||
|
||||
modelHandle = renderModelManager->FindModel( filename );
|
||||
if( !modelHandle )
|
||||
{
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
Copyright (C) 2022 Robert Beckebans
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
|
@ -899,3 +900,483 @@ void idRenderModelManagerLocal::PrintMemInfo( MemInfo_t* mi )
|
|||
f->Printf( "\nTotal model bytes allocated: %s\n", idStr::FormatNumber( totalMem ).c_str() );
|
||||
fileSystem->CloseFile( f );
|
||||
}
|
||||
|
||||
|
||||
|
||||
// RB: added Maya exporter options
|
||||
/*
|
||||
==============================================================================================
|
||||
|
||||
idTokenizer
|
||||
|
||||
==============================================================================================
|
||||
*/
|
||||
|
||||
/*
|
||||
=================
|
||||
MayaError
|
||||
=================
|
||||
*/
|
||||
void MayaError( const char* fmt, ... )
|
||||
{
|
||||
va_list argptr;
|
||||
char text[ 8192 ];
|
||||
|
||||
va_start( argptr, fmt );
|
||||
idStr::vsnPrintf( text, sizeof( text ), fmt, argptr );
|
||||
va_end( argptr );
|
||||
|
||||
throw idException( text );
|
||||
}
|
||||
|
||||
|
||||
class idTokenizer
|
||||
{
|
||||
private:
|
||||
int currentToken;
|
||||
idStrList tokens;
|
||||
|
||||
public:
|
||||
idTokenizer()
|
||||
{
|
||||
Clear();
|
||||
};
|
||||
void Clear()
|
||||
{
|
||||
currentToken = 0;
|
||||
tokens.Clear();
|
||||
};
|
||||
|
||||
int SetTokens( const char* buffer );
|
||||
const char* NextToken( const char* errorstring = NULL );
|
||||
|
||||
bool TokenAvailable()
|
||||
{
|
||||
return currentToken < tokens.Num();
|
||||
};
|
||||
int Num()
|
||||
{
|
||||
return tokens.Num();
|
||||
};
|
||||
void UnGetToken()
|
||||
{
|
||||
if( currentToken > 0 )
|
||||
{
|
||||
currentToken--;
|
||||
}
|
||||
};
|
||||
const char* GetToken( int index )
|
||||
{
|
||||
if( ( index >= 0 ) && ( index < tokens.Num() ) )
|
||||
{
|
||||
return tokens[ index ];
|
||||
}
|
||||
else
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
};
|
||||
const char* CurrentToken()
|
||||
{
|
||||
return GetToken( currentToken );
|
||||
};
|
||||
};
|
||||
|
||||
/*
|
||||
====================
|
||||
idTokenizer::SetTokens
|
||||
====================
|
||||
*/
|
||||
int idTokenizer::SetTokens( const char* buffer )
|
||||
{
|
||||
const char* cmd;
|
||||
|
||||
Clear();
|
||||
|
||||
// tokenize commandline
|
||||
cmd = buffer;
|
||||
while( *cmd )
|
||||
{
|
||||
// skip whitespace
|
||||
while( *cmd && isspace( *cmd ) )
|
||||
{
|
||||
cmd++;
|
||||
}
|
||||
|
||||
if( !*cmd )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
idStr& current = tokens.Alloc();
|
||||
while( *cmd && !isspace( *cmd ) )
|
||||
{
|
||||
current += *cmd;
|
||||
cmd++;
|
||||
}
|
||||
}
|
||||
|
||||
return tokens.Num();
|
||||
}
|
||||
|
||||
/*
|
||||
====================
|
||||
idTokenizer::NextToken
|
||||
====================
|
||||
*/
|
||||
const char* idTokenizer::NextToken( const char* errorstring )
|
||||
{
|
||||
if( currentToken < tokens.Num() )
|
||||
{
|
||||
return tokens[ currentToken++ ];
|
||||
}
|
||||
|
||||
if( errorstring )
|
||||
{
|
||||
MayaError( "Error: %s", errorstring );
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/*
|
||||
==============================================================================================
|
||||
|
||||
idImportOptions
|
||||
|
||||
==============================================================================================
|
||||
*/
|
||||
|
||||
#define DEFAULT_ANIM_EPSILON 0.125f
|
||||
#define DEFAULT_QUAT_EPSILON ( 1.0f / 8192.0f )
|
||||
|
||||
void idImportOptions::Init( const char* commandline, const char* ospath )
|
||||
{
|
||||
idStr token;
|
||||
idNamePair joints;
|
||||
int i;
|
||||
idAnimGroup* group;
|
||||
idStr sourceDir;
|
||||
idStr destDir;
|
||||
|
||||
//Reset( commandline );
|
||||
scale = 1.0f;
|
||||
//type = WRITE_MESH;
|
||||
startframe = -1;
|
||||
endframe = -1;
|
||||
ignoreMeshes = false;
|
||||
clearOrigin = false;
|
||||
clearOriginAxis = false;
|
||||
framerate = 24;
|
||||
align = "";
|
||||
rotate = 0.0f;
|
||||
commandLine = commandline;
|
||||
prefix = "";
|
||||
jointThreshold = 0.05f;
|
||||
ignoreScale = false;
|
||||
xyzPrecision = DEFAULT_ANIM_EPSILON;
|
||||
quatPrecision = DEFAULT_QUAT_EPSILON;
|
||||
cycleStart = -1;
|
||||
|
||||
src.Clear();
|
||||
dest.Clear();
|
||||
|
||||
idTokenizer tokens;
|
||||
tokens.SetTokens( commandline );
|
||||
|
||||
keepjoints.Clear();
|
||||
renamejoints.Clear();
|
||||
remapjoints.Clear();
|
||||
exportgroups.Clear();
|
||||
skipmeshes.Clear();
|
||||
keepmeshes.Clear();
|
||||
groups.Clear();
|
||||
|
||||
/*
|
||||
token = tokens.NextToken( "Missing export command" );
|
||||
if( token == "mesh" )
|
||||
{
|
||||
type = WRITE_MESH;
|
||||
}
|
||||
else if( token == "anim" )
|
||||
{
|
||||
type = WRITE_ANIM;
|
||||
}
|
||||
else if( token == "camera" )
|
||||
{
|
||||
type = WRITE_CAMERA;
|
||||
}
|
||||
else
|
||||
{
|
||||
MayaError( "Unknown export command '%s'", token.c_str() );
|
||||
}
|
||||
*/
|
||||
|
||||
//src = tokens.NextToken( "Missing source filename" );
|
||||
//dest = src;
|
||||
|
||||
for( token = tokens.NextToken(); token != ""; token = tokens.NextToken() )
|
||||
{
|
||||
if( token == "-" )
|
||||
{
|
||||
token = tokens.NextToken( "Missing import parameter" );
|
||||
|
||||
if( token == "force" )
|
||||
{
|
||||
// skip
|
||||
}
|
||||
else if( token == "game" )
|
||||
{
|
||||
// parse game name
|
||||
game = tokens.NextToken( "Expecting game name after -game" );
|
||||
|
||||
}
|
||||
else if( token == "rename" )
|
||||
{
|
||||
// parse joint to rename
|
||||
joints.from = tokens.NextToken( "Missing joint name for -rename. Usage: -rename [joint name] [new name]" );
|
||||
joints.to = tokens.NextToken( "Missing new name for -rename. Usage: -rename [joint name] [new name]" );
|
||||
renamejoints.Append( joints );
|
||||
|
||||
}
|
||||
else if( token == "prefix" )
|
||||
{
|
||||
prefix = tokens.NextToken( "Missing name for -prefix. Usage: -prefix [joint prefix]" );
|
||||
|
||||
}
|
||||
else if( token == "parent" )
|
||||
{
|
||||
// parse joint to reparent
|
||||
joints.from = tokens.NextToken( "Missing joint name for -parent. Usage: -parent [joint name] [new parent]" );
|
||||
joints.to = tokens.NextToken( "Missing new parent for -parent. Usage: -parent [joint name] [new parent]" );
|
||||
remapjoints.Append( joints );
|
||||
|
||||
}
|
||||
else if( !token.Icmp( "sourcedir" ) )
|
||||
{
|
||||
// parse source directory
|
||||
sourceDir = tokens.NextToken( "Missing filename for -sourcedir. Usage: -sourcedir [directory]" );
|
||||
|
||||
}
|
||||
else if( !token.Icmp( "destdir" ) )
|
||||
{
|
||||
// parse destination directory
|
||||
destDir = tokens.NextToken( "Missing filename for -destdir. Usage: -destdir [directory]" );
|
||||
|
||||
}
|
||||
else if( token == "dest" )
|
||||
{
|
||||
// parse destination filename
|
||||
dest = tokens.NextToken( "Missing filename for -dest. Usage: -dest [filename]" );
|
||||
|
||||
}
|
||||
else if( token == "range" )
|
||||
{
|
||||
// parse frame range to export
|
||||
token = tokens.NextToken( "Missing start frame for -range. Usage: -range [start frame] [end frame]" );
|
||||
startframe = atoi( token );
|
||||
token = tokens.NextToken( "Missing end frame for -range. Usage: -range [start frame] [end frame]" );
|
||||
endframe = atoi( token );
|
||||
|
||||
if( startframe > endframe )
|
||||
{
|
||||
MayaError( "Start frame is greater than end frame." );
|
||||
}
|
||||
|
||||
}
|
||||
else if( !token.Icmp( "cycleStart" ) )
|
||||
{
|
||||
// parse start frame of cycle
|
||||
token = tokens.NextToken( "Missing cycle start frame for -cycleStart. Usage: -cycleStart [first frame of cycle]" );
|
||||
cycleStart = atoi( token );
|
||||
|
||||
}
|
||||
else if( token == "scale" )
|
||||
{
|
||||
// parse scale
|
||||
token = tokens.NextToken( "Missing scale amount for -scale. Usage: -scale [scale amount]" );
|
||||
scale = atof( token );
|
||||
|
||||
}
|
||||
else if( token == "align" )
|
||||
{
|
||||
// parse align joint
|
||||
align = tokens.NextToken( "Missing joint name for -align. Usage: -align [joint name]" );
|
||||
|
||||
}
|
||||
else if( token == "rotate" )
|
||||
{
|
||||
// parse angle rotation
|
||||
token = tokens.NextToken( "Missing value for -rotate. Usage: -rotate [yaw]" );
|
||||
rotate = -atof( token );
|
||||
|
||||
}
|
||||
else if( token == "nomesh" )
|
||||
{
|
||||
ignoreMeshes = true;
|
||||
|
||||
}
|
||||
else if( token == "clearorigin" )
|
||||
{
|
||||
clearOrigin = true;
|
||||
clearOriginAxis = true;
|
||||
|
||||
}
|
||||
else if( token == "clearoriginaxis" )
|
||||
{
|
||||
clearOriginAxis = true;
|
||||
|
||||
}
|
||||
else if( token == "ignorescale" )
|
||||
{
|
||||
ignoreScale = true;
|
||||
|
||||
}
|
||||
else if( token == "xyzprecision" )
|
||||
{
|
||||
// parse quaternion precision
|
||||
token = tokens.NextToken( "Missing value for -xyzprecision. Usage: -xyzprecision [precision]" );
|
||||
xyzPrecision = atof( token );
|
||||
if( xyzPrecision < 0.0f )
|
||||
{
|
||||
MayaError( "Invalid value for -xyzprecision. Must be >= 0" );
|
||||
}
|
||||
|
||||
}
|
||||
else if( token == "quatprecision" )
|
||||
{
|
||||
// parse quaternion precision
|
||||
token = tokens.NextToken( "Missing value for -quatprecision. Usage: -quatprecision [precision]" );
|
||||
quatPrecision = atof( token );
|
||||
if( quatPrecision < 0.0f )
|
||||
{
|
||||
MayaError( "Invalid value for -quatprecision. Must be >= 0" );
|
||||
}
|
||||
|
||||
}
|
||||
else if( token == "jointthreshold" )
|
||||
{
|
||||
// parse joint threshold
|
||||
token = tokens.NextToken( "Missing weight for -jointthreshold. Usage: -jointthreshold [minimum joint weight]" );
|
||||
jointThreshold = atof( token );
|
||||
|
||||
}
|
||||
else if( token == "skipmesh" )
|
||||
{
|
||||
token = tokens.NextToken( "Missing name for -skipmesh. Usage: -skipmesh [name of mesh to skip]" );
|
||||
skipmeshes.AddUnique( token );
|
||||
|
||||
}
|
||||
else if( token == "keepmesh" )
|
||||
{
|
||||
token = tokens.NextToken( "Missing name for -keepmesh. Usage: -keepmesh [name of mesh to keep]" );
|
||||
keepmeshes.AddUnique( token );
|
||||
|
||||
}
|
||||
else if( token == "jointgroup" )
|
||||
{
|
||||
token = tokens.NextToken( "Missing name for -jointgroup. Usage: -jointgroup [group name] [joint1] [joint2]...[joint n]" );
|
||||
group = groups.Ptr();
|
||||
for( i = 0; i < groups.Num(); i++, group++ )
|
||||
{
|
||||
if( group->name == token )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( i >= groups.Num() )
|
||||
{
|
||||
// create a new group
|
||||
group = &groups.Alloc();
|
||||
group->name = token;
|
||||
}
|
||||
|
||||
while( tokens.TokenAvailable() )
|
||||
{
|
||||
token = tokens.NextToken();
|
||||
if( token[ 0 ] == '-' )
|
||||
{
|
||||
tokens.UnGetToken();
|
||||
break;
|
||||
}
|
||||
|
||||
group->joints.AddUnique( token );
|
||||
}
|
||||
}
|
||||
else if( token == "group" )
|
||||
{
|
||||
// add the list of groups to export (these don't affect the hierarchy)
|
||||
while( tokens.TokenAvailable() )
|
||||
{
|
||||
token = tokens.NextToken();
|
||||
if( token[ 0 ] == '-' )
|
||||
{
|
||||
tokens.UnGetToken();
|
||||
break;
|
||||
}
|
||||
|
||||
group = groups.Ptr();
|
||||
for( i = 0; i < groups.Num(); i++, group++ )
|
||||
{
|
||||
if( group->name == token )
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( i >= groups.Num() )
|
||||
{
|
||||
MayaError( "Unknown group '%s'", token.c_str() );
|
||||
}
|
||||
|
||||
exportgroups.AddUnique( group );
|
||||
}
|
||||
}
|
||||
else if( token == "keep" )
|
||||
{
|
||||
// add joints that are kept whether they're used by a mesh or not
|
||||
while( tokens.TokenAvailable() )
|
||||
{
|
||||
token = tokens.NextToken();
|
||||
if( token[ 0 ] == '-' )
|
||||
{
|
||||
tokens.UnGetToken();
|
||||
break;
|
||||
}
|
||||
keepjoints.AddUnique( token );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
MayaError( "Unknown option '%s'", token.c_str() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
token = src;
|
||||
src = ospath;
|
||||
src.BackSlashesToSlashes();
|
||||
src.AppendPath( sourceDir );
|
||||
src.AppendPath( token );
|
||||
|
||||
token = dest;
|
||||
dest = ospath;
|
||||
dest.BackSlashesToSlashes();
|
||||
dest.AppendPath( destDir );
|
||||
dest.AppendPath( token );
|
||||
|
||||
// Maya only accepts unix style path separators
|
||||
src.BackSlashesToSlashes();
|
||||
dest.BackSlashesToSlashes();
|
||||
|
||||
if( skipmeshes.Num() && keepmeshes.Num() )
|
||||
{
|
||||
MayaError( "Can't use -keepmesh and -skipmesh together." );
|
||||
}
|
||||
}
|
||||
|
||||
// RB end
|
|
@ -3,6 +3,7 @@
|
|||
|
||||
Doom 3 BFG Edition GPL Source Code
|
||||
Copyright (C) 1993-2012 id Software LLC, a ZeniMax Media company.
|
||||
Copyright (C) 2022 Robert Beckebans
|
||||
|
||||
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
|
||||
|
||||
|
@ -29,6 +30,68 @@ If you have questions concerning this license or the applicable additional terms
|
|||
#ifndef __MODELMANAGER_H__
|
||||
#define __MODELMANAGER_H__
|
||||
|
||||
/*
|
||||
==============================================================================================
|
||||
|
||||
idImportOptions
|
||||
|
||||
==============================================================================================
|
||||
*/
|
||||
|
||||
class idNamePair
|
||||
{
|
||||
public:
|
||||
idStr from;
|
||||
idStr to;
|
||||
};
|
||||
|
||||
class idAnimGroup
|
||||
{
|
||||
public:
|
||||
idStr name;
|
||||
idStrList joints;
|
||||
};
|
||||
|
||||
class idImportOptions
|
||||
{
|
||||
private:
|
||||
//idTokenizer tokens;
|
||||
//void Reset( const char* commandline );
|
||||
|
||||
public:
|
||||
idStr commandLine;
|
||||
idStr src;
|
||||
idStr dest;
|
||||
idStr game;
|
||||
idStr prefix;
|
||||
float scale;
|
||||
//exportType_t type;
|
||||
bool ignoreMeshes;
|
||||
bool clearOrigin;
|
||||
bool clearOriginAxis;
|
||||
bool ignoreScale;
|
||||
int startframe;
|
||||
int endframe;
|
||||
int framerate;
|
||||
float xyzPrecision;
|
||||
float quatPrecision;
|
||||
idStr align;
|
||||
idList<idNamePair> renamejoints;
|
||||
idList<idNamePair> remapjoints;
|
||||
idStrList keepjoints;
|
||||
idStrList skipmeshes;
|
||||
idStrList keepmeshes;
|
||||
idList<idAnimGroup*> exportgroups;
|
||||
idList<idAnimGroup> groups;
|
||||
float rotate;
|
||||
float jointThreshold;
|
||||
int cycleStart;
|
||||
|
||||
void Init( const char* commandline, const char* ospath );
|
||||
|
||||
//bool JointInExportGroup( const char* jointname );
|
||||
};
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
|
|
Loading…
Reference in a new issue