diff --git a/neo/idlib/gltfParser.cpp b/neo/idlib/gltfParser.cpp index a0198180..5adc672f 100644 --- a/neo/idlib/gltfParser.cpp +++ b/neo/idlib/gltfParser.cpp @@ -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 ) { diff --git a/neo/idlib/gltfProperties.h b/neo/idlib/gltfProperties.h index 2e9aee96..dc5fb5dc 100644 --- a/neo/idlib/gltfProperties.h +++ b/neo/idlib/gltfProperties.h @@ -401,11 +401,6 @@ public: { return false; } - const idVec3& TotalMovementDelta() const - { - static idVec3 temp; - return temp; - } int NumFrames() const { return numFrames; diff --git a/neo/renderer/Model.cpp b/neo/renderer/Model.cpp index 8ab03312..790512ae 100644 --- a/neo/renderer/Model.cpp +++ b/neo/renderer/Model.cpp @@ -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; diff --git a/neo/renderer/ModelManager.cpp b/neo/renderer/ModelManager.cpp index 22a1b38a..efa2837c 100644 --- a/neo/renderer/ModelManager.cpp +++ b/neo/renderer/ModelManager.cpp @@ -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 diff --git a/neo/renderer/Model_gltf.cpp b/neo/renderer/Model_gltf.cpp index d500719c..e2a9e3c0 100644 --- a/neo/renderer/Model_gltf.cpp +++ b/neo/renderer/Model_gltf.cpp @@ -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 idListGetSkin( targetNode ); } - assert( skin ); + idassert( skin ); bones.Append( skin->joints ); } else @@ -586,7 +591,7 @@ int copyBones( gltfData* data, const idList& bones, idList& 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 ); } diff --git a/neo/renderer/Model_gltf.h b/neo/renderer/Model_gltf.h index c8a5bf32..cc1441ef 100644 --- a/neo/renderer/Model_gltf.h +++ b/neo/renderer/Model_gltf.h @@ -73,6 +73,7 @@ private: idList MeshNodeIds; dynamicModel_t model_state; idStr meshName; + idStr gltfFileName; idList md5joints; idList defaultPose;