mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-03-14 22:50:45 +00:00
[!] Fixed runtime reloading for gltf models
[!] Fixed timestamp check for static models
This commit is contained in:
parent
e9284c3818
commit
3d366ba386
6 changed files with 89 additions and 32 deletions
|
@ -1150,7 +1150,7 @@ void GLTF_Parser::Shutdown()
|
|||
bufferViewsDone = false;
|
||||
}
|
||||
GLTF_Parser::GLTF_Parser()
|
||||
: parser( LEXFL_ALLOWPATHNAMES | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_NOSTRINGESCAPECHARS | LEXFL_ALLOWPATHNAMES ) , buffersDone( false ), bufferViewsDone( false ) { }
|
||||
: parser( LEXFL_ALLOWPATHNAMES | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_NOSTRINGESCAPECHARS | LEXFL_ALLOWPATHNAMES ) , buffersDone( false ), bufferViewsDone( false ), currentAsset( nullptr ) { }
|
||||
|
||||
void GLTF_Parser::Parse_ASSET( idToken& token )
|
||||
{
|
||||
|
|
|
@ -401,11 +401,6 @@ public:
|
|||
{
|
||||
return false;
|
||||
}
|
||||
const idVec3& TotalMovementDelta() const
|
||||
{
|
||||
static idVec3 temp;
|
||||
return temp;
|
||||
}
|
||||
int NumFrames() const
|
||||
{
|
||||
return numFrames;
|
||||
|
|
|
@ -315,8 +315,12 @@ void idRenderModelStatic::InitFromFile( const char* fileName )
|
|||
ID_TIME_T sourceTimeStamp;
|
||||
|
||||
name.ExtractFileExtension( extension );
|
||||
|
||||
if( extension.Icmp( "ase" ) == 0 )
|
||||
if( extension.Icmp( "glb" ) == 0 || extension.Icmp( "gltf" ) == 0 )
|
||||
{
|
||||
loaded = false;
|
||||
reloadable = true;
|
||||
}
|
||||
else if( extension.Icmp( "ase" ) == 0 )
|
||||
{
|
||||
loaded = LoadASE( name, &sourceTimeStamp );
|
||||
reloadable = true;
|
||||
|
|
|
@ -291,6 +291,13 @@ idRenderModel* idRenderModelManagerLocal::GetModel( const char* _modelName, bool
|
|||
idStrStatic< MAX_OSPATH > extension;
|
||||
canonical.ExtractFileExtension( extension );
|
||||
|
||||
bool isGLTF = false;
|
||||
// HvG: GLTF 2 support
|
||||
if( ( extension.Icmp( GLTF_GLB_EXT ) == 0 ) || ( extension.Icmp( GLTF_EXT ) == 0 ) )
|
||||
{
|
||||
isGLTF = true;
|
||||
}
|
||||
|
||||
// see if it is already present
|
||||
int key = hash.GenerateKey( canonical, false );
|
||||
for( int i = hash.First( key ); i != -1; i = hash.Next( i ) )
|
||||
|
@ -307,7 +314,22 @@ idRenderModel* idRenderModelManagerLocal::GetModel( const char* _modelName, bool
|
|||
generatedFileName.SetFileExtension( va( "b%s", extension.c_str() ) );
|
||||
|
||||
// Get the timestamp on the original file, if it's newer than what is stored in binary model, regenerate it
|
||||
ID_TIME_T sourceTimeStamp = fileSystem->GetTimestamp( canonical );
|
||||
|
||||
ID_TIME_T sourceTimeStamp;
|
||||
|
||||
if( isGLTF )
|
||||
{
|
||||
idStr gltfFileName = idStr( canonical );
|
||||
int gltfMeshId = -1;
|
||||
idStr gltfMeshName;
|
||||
gltfManager::ExtractIdentifier( gltfFileName, gltfMeshId, gltfMeshName );
|
||||
|
||||
sourceTimeStamp = fileSystem->GetTimestamp( gltfFileName );
|
||||
}
|
||||
else
|
||||
{
|
||||
sourceTimeStamp = fileSystem->GetTimestamp( canonical );
|
||||
}
|
||||
|
||||
if( model->SupportsBinaryModel() && binaryLoadRenderModels.GetBool() )
|
||||
{
|
||||
|
@ -315,7 +337,14 @@ idRenderModel* idRenderModelManagerLocal::GetModel( const char* _modelName, bool
|
|||
model->PurgeModel();
|
||||
if( !model->LoadBinaryModel( file, sourceTimeStamp ) )
|
||||
{
|
||||
model->LoadModel();
|
||||
if( isGLTF )
|
||||
{
|
||||
model->InitFromFile( canonical );
|
||||
}
|
||||
else
|
||||
{
|
||||
model->LoadModel();
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -342,7 +371,7 @@ idRenderModel* idRenderModelManagerLocal::GetModel( const char* _modelName, bool
|
|||
|
||||
idRenderModel* model = NULL;
|
||||
// HvG: GLTF 2 support
|
||||
if( ( extension.Icmp( GLTF_GLB_EXT ) == 0 ) || ( extension.Icmp( GLTF_EXT ) == 0 ) )
|
||||
if( isGLTF )
|
||||
{
|
||||
model = new( TAG_MODEL ) idRenderModelGLTF;
|
||||
}
|
||||
|
@ -615,22 +644,42 @@ void idRenderModelManagerLocal::ReloadModels( bool forceAll )
|
|||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
bool isGltf = false;
|
||||
idStr name = model->Name();
|
||||
idStr extension;
|
||||
idStr assetName = name;
|
||||
assetName.ExtractFileExtension( extension );
|
||||
isGltf = extension.Icmp( "glb" ) == 0 || extension.Icmp( "gltf" ) == 0;
|
||||
if( !forceAll )
|
||||
{
|
||||
// check timestamp
|
||||
ID_TIME_T current;
|
||||
|
||||
fileSystem->ReadFile( model->Name(), NULL, ¤t );
|
||||
if( isGltf )
|
||||
{
|
||||
idStr meshName;
|
||||
int meshID = -1;
|
||||
gltfManager::ExtractIdentifier( name, meshID, meshName );
|
||||
}
|
||||
|
||||
fileSystem->ReadFile( name, NULL, ¤t );
|
||||
if( current <= model->Timestamp() )
|
||||
{
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
common->DPrintf( "reloading %s.\n", model->Name() );
|
||||
common->DPrintf( "^1Reloading %s.\n", model->Name() );
|
||||
|
||||
if( isGltf )
|
||||
{
|
||||
model->InitFromFile( model->Name() );
|
||||
}
|
||||
else
|
||||
{
|
||||
model->LoadModel();
|
||||
}
|
||||
|
||||
model->LoadModel();
|
||||
}
|
||||
|
||||
// we must force the world to regenerate, because models may
|
||||
|
|
|
@ -149,7 +149,7 @@ void idRenderModelGLTF::InitFromFile( const char* fileName )
|
|||
|
||||
//FIXME FIXME FIXME
|
||||
maxJointVertDist = 10;
|
||||
idStr gltfFileName = idStr( fileName );
|
||||
gltfFileName = idStr( fileName );
|
||||
model_state = DM_STATIC;
|
||||
|
||||
gltfManager::ExtractIdentifier( gltfFileName, meshID, meshName );
|
||||
|
@ -162,13 +162,13 @@ void idRenderModelGLTF::InitFromFile( const char* fileName )
|
|||
bounds.Clear();
|
||||
|
||||
int sceneId = data->DefaultScene();
|
||||
assert( sceneId >= 0 );
|
||||
idassert( sceneId >= 0 );
|
||||
|
||||
auto scene = data->SceneList()[sceneId];
|
||||
assert( scene );
|
||||
idassert( scene );
|
||||
|
||||
auto nodes = data->NodeList();
|
||||
assert( nodes.Num() );
|
||||
idassert( nodes.Num() );
|
||||
|
||||
//determine root node
|
||||
if( !meshName[0] )
|
||||
|
@ -212,7 +212,7 @@ void idRenderModelGLTF::InitFromFile( const char* fileName )
|
|||
if( tmpNode->skin >= 0 )
|
||||
{
|
||||
currentSkin = data->SkinList()[tmpNode->skin];
|
||||
assert( currentSkin );
|
||||
idassert( currentSkin );
|
||||
if( currentSkin->joints.Num() )
|
||||
{
|
||||
bones.Append( currentSkin->joints );
|
||||
|
@ -237,6 +237,7 @@ void idRenderModelGLTF::InitFromFile( const char* fileName )
|
|||
{
|
||||
common->Warning( "Couldn't load model: '%s'", name.c_str() );
|
||||
MakeDefaultModel();
|
||||
data = nullptr;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -244,6 +245,7 @@ void idRenderModelGLTF::InitFromFile( const char* fileName )
|
|||
// derive mikktspace tangents from normals
|
||||
FinishSurfaces( true );
|
||||
|
||||
|
||||
LoadModel();
|
||||
UpdateMd5Joints();
|
||||
|
||||
|
@ -259,6 +261,7 @@ bool idRenderModelGLTF::LoadBinaryModel( idFile* file, const ID_TIME_T sourceTim
|
|||
|
||||
if( !idRenderModelStatic::LoadBinaryModel( file, sourceTimeStamp ) )
|
||||
{
|
||||
data = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -267,6 +270,7 @@ bool idRenderModelGLTF::LoadBinaryModel( idFile* file, const ID_TIME_T sourceTim
|
|||
|
||||
if( magic != GLMB_MAGIC )
|
||||
{
|
||||
data = nullptr;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -343,6 +347,7 @@ bool idRenderModelGLTF::LoadBinaryModel( idFile* file, const ID_TIME_T sourceTim
|
|||
model_state = hasAnimations ? DM_CONTINUOUS : DM_STATIC;
|
||||
|
||||
lastMeshFromFile = this;
|
||||
data = nullptr;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -355,7 +360,7 @@ const idMD5Joint* idRenderModelGLTF::FindMD5Joint( const idStr& name ) const
|
|||
return &joint;
|
||||
}
|
||||
}
|
||||
assert( 0 );
|
||||
idassert( 0 );
|
||||
static idMD5Joint staticJoint;
|
||||
return &staticJoint;
|
||||
}
|
||||
|
@ -488,7 +493,7 @@ bool gatherBoneInfo( gltfData* data, gltfAnimation* gltfAnim, const idList<gltfN
|
|||
{
|
||||
skin = data->GetSkin( targetNode );
|
||||
}
|
||||
assert( skin );
|
||||
idassert( skin );
|
||||
bones.Append( skin->joints );
|
||||
}
|
||||
else
|
||||
|
@ -586,7 +591,7 @@ int copyBones( gltfData* data, const idList<int>& bones, idList<gltfNode>& out )
|
|||
|
||||
idFile_Memory* idRenderModelGLTF::GetAnimBin( idStr animName , const ID_TIME_T sourceTimeStamp )
|
||||
{
|
||||
assert( lastMeshFromFile );
|
||||
idassert( lastMeshFromFile );
|
||||
///keep in sync with game!
|
||||
static const byte B_ANIM_MD5_VERSION = 101;
|
||||
static const unsigned int B_ANIM_MD5_MAGIC = ( 'B' << 24 ) | ( 'M' << 16 ) | ( 'D' << 8 ) | B_ANIM_MD5_VERSION;
|
||||
|
@ -696,7 +701,7 @@ idFile_Memory* idRenderModelGLTF::GetAnimBin( idStr animName , const ID_TIME_T
|
|||
for( int i = 0; i < numFrames; i++ )
|
||||
{
|
||||
int totalCopied = copyBones( data, bones, animBones[i] );
|
||||
assert( totalCopied );
|
||||
idassert( totalCopied );
|
||||
}
|
||||
|
||||
gameLocal.Printf( "Total bones %i \n", bones.Num() );
|
||||
|
@ -815,7 +820,7 @@ idFile_Memory* idRenderModelGLTF::GetAnimBin( idStr animName , const ID_TIME_T
|
|||
}
|
||||
}
|
||||
|
||||
assert( componentFrames.Num() == ( componentFrameIndex + 1 ) );
|
||||
idassert( componentFrames.Num() == ( componentFrameIndex + 1 ) );
|
||||
|
||||
bounds.SetGranularity( 1 );
|
||||
bounds.AssureSize( numFrames );
|
||||
|
@ -1049,6 +1054,7 @@ void idRenderModelGLTF::WriteBinaryModel( idFile* file, ID_TIME_T* _timeStamp /*
|
|||
|
||||
void idRenderModelGLTF::PurgeModel()
|
||||
{
|
||||
idRenderModelStatic::PurgeModel();
|
||||
purged = true;
|
||||
md5joints.Clear();
|
||||
defaultPose.Clear();
|
||||
|
@ -1057,16 +1063,20 @@ void idRenderModelGLTF::PurgeModel()
|
|||
animIds.Clear();
|
||||
bones.Clear();
|
||||
MeshNodeIds.Clear();
|
||||
gltfFileName.Clear();
|
||||
|
||||
//if no root id was set, it is a generated one.
|
||||
if( rootID == -1 && root )
|
||||
{
|
||||
delete root;
|
||||
}
|
||||
data = nullptr;
|
||||
}
|
||||
|
||||
void idRenderModelGLTF::LoadModel()
|
||||
{
|
||||
idassert( data );
|
||||
|
||||
int num;
|
||||
auto& accessors = data->AccessorList();
|
||||
auto& nodes = data->NodeList();
|
||||
|
@ -1074,6 +1084,7 @@ void idRenderModelGLTF::LoadModel()
|
|||
if( !fileExclusive )
|
||||
{
|
||||
meshRoot = data->GetNode( gltf_ModelSceneName.GetString(), meshName );
|
||||
idassert( meshRoot );
|
||||
}
|
||||
|
||||
gltfSkin* skin = nullptr;
|
||||
|
@ -1462,9 +1473,6 @@ idRenderModel* idRenderModelGLTF::InstantiateDynamicModel( const struct renderEn
|
|||
if( purged )
|
||||
{
|
||||
common->DWarning( "model %s instantiated while purged", Name() );
|
||||
GLTF_Parser gltf;
|
||||
gltf.Load( name );
|
||||
data = gltf.currentAsset;
|
||||
LoadModel();
|
||||
}
|
||||
|
||||
|
@ -1484,8 +1492,8 @@ idRenderModel* idRenderModelGLTF::InstantiateDynamicModel( const struct renderEn
|
|||
idRenderModelStatic* staticModel;
|
||||
if( cachedModel != NULL )
|
||||
{
|
||||
assert( dynamic_cast< idRenderModelStatic* >( cachedModel ) != NULL );
|
||||
assert( idStr::Icmp( cachedModel->Name(), GLTF_SnapshotName ) == 0 );
|
||||
idassert( dynamic_cast< idRenderModelStatic* >( cachedModel ) != NULL );
|
||||
idassert( idStr::Icmp( cachedModel->Name(), GLTF_SnapshotName ) == 0 );
|
||||
staticModel = static_cast< idRenderModelStatic* >( cachedModel );
|
||||
}
|
||||
else
|
||||
|
@ -1523,7 +1531,7 @@ idRenderModel* idRenderModelGLTF::InstantiateDynamicModel( const struct renderEn
|
|||
}
|
||||
else
|
||||
{
|
||||
assert( staticModel->numInvertedJoints == numInvertedJoints );
|
||||
idassert( staticModel->numInvertedJoints == numInvertedJoints );
|
||||
}
|
||||
|
||||
TransformJointsFast( staticModel->jointsInverted, md5joints.Num(), ent->joints, invertedDefaultPose.Ptr() );
|
||||
|
@ -1552,7 +1560,7 @@ idRenderModel* idRenderModelGLTF::InstantiateDynamicModel( const struct renderEn
|
|||
}
|
||||
|
||||
UpdateSurface( ent, ent->joints, staticModel->jointsInverted, &surf, surfaces[surfIdx++] );
|
||||
assert( surf.geometry != NULL );
|
||||
idassert( surf.geometry != NULL );
|
||||
surf.geometry->staticModelWithJoints = staticModel;
|
||||
staticModel->bounds.AddBounds( surf.geometry->bounds );
|
||||
}
|
||||
|
|
|
@ -73,6 +73,7 @@ private:
|
|||
idList<int, TAG_MODEL> MeshNodeIds;
|
||||
dynamicModel_t model_state;
|
||||
idStr meshName;
|
||||
idStr gltfFileName;
|
||||
|
||||
idList<idMD5Joint, TAG_MODEL> md5joints;
|
||||
idList<idJointQuat, TAG_MODEL> defaultPose;
|
||||
|
|
Loading…
Reference in a new issue