diff --git a/neo/d3xp/anim/Anim.cpp b/neo/d3xp/anim/Anim.cpp index f002b7fe..200bc9fb 100644 --- a/neo/d3xp/anim/Anim.cpp +++ b/neo/d3xp/anim/Anim.cpp @@ -189,18 +189,16 @@ bool idMD5Anim::LoadAnim( const char* filename ) generatedFileName.AppendPath( filename ); generatedFileName.SetFileExtension( ".bMD5anim" ); - idStr gltfFileName = idStr( filename ); - int gltfAnimId = -1; - idStr gltfAnimName; - - // Get the timestamp on the original file, if it's newer than what is stored in binary model, regenerate it ID_TIME_T sourceTimeStamp; bool isGLTF = ( extension.Icmp( GLTF_GLB_EXT ) == 0 ) || ( extension.Icmp( GLTF_EXT ) == 0 ) ; - if( isGLTF ) { + idStr gltfFileName = idStr( filename ); + int gltfAnimId = -1; + idStr gltfAnimName; + gltfManager::ExtractIdentifier( gltfFileName, gltfAnimId, gltfAnimName ); sourceTimeStamp = fileSystem->GetTimestamp( gltfFileName ); diff --git a/neo/d3xp/anim/Anim_Blend.cpp b/neo/d3xp/anim/Anim_Blend.cpp index 88200e80..3b14fece 100644 --- a/neo/d3xp/anim/Anim_Blend.cpp +++ b/neo/d3xp/anim/Anim_Blend.cpp @@ -3387,10 +3387,15 @@ bool idDeclModelDef::Parse( const char* text, const int textLength, bool allowBi MakeDefault(); return false; } + + modelHandle = renderModelManager->FindModel( filename, &options ); + } + else + { + modelHandle = renderModelManager->FindModel( filename ); } // RB end - modelHandle = renderModelManager->FindModel( filename ); if( !modelHandle ) { src.Warning( "Model '%s' not found", filename.c_str() ); diff --git a/neo/renderer/Model_gltf.cpp b/neo/renderer/Model_gltf.cpp index e5b2647f..8b27392b 100644 --- a/neo/renderer/Model_gltf.cpp +++ b/neo/renderer/Model_gltf.cpp @@ -57,7 +57,7 @@ bool idRenderModelStatic::ConvertGltfMeshToModelsurfaces( const gltfMesh* mesh ) return false; } -void idRenderModelGLTF::ProcessNode_r( gltfNode* modelNode, idMat4 parentTransform, gltfData* data ) +void idRenderModelGLTF::ProcessNode_r( gltfNode* modelNode, const idMat4& parentTransform, const idMat4& globalTransform, gltfData* data ) { auto& meshList = data->MeshList(); auto& nodeList = data->NodeList(); @@ -73,7 +73,7 @@ void idRenderModelGLTF::ProcessNode_r( gltfNode* modelNode, idMat4 parentTransfo for( auto prim : targetMesh->primitives ) { //ConvertFromMeshGltf should only be used for the map, ConvertGltfMeshToModelsurfaces should be used. - auto* mesh = MapPolygonMesh::ConvertFromMeshGltf( prim, data, blenderToDoomTransform * nodeToWorldTransform ); + auto* mesh = MapPolygonMesh::ConvertFromMeshGltf( prim, data, globalTransform * nodeToWorldTransform ); modelSurface_t surf; gltfMaterial* mat = NULL; @@ -126,7 +126,7 @@ void idRenderModelGLTF::ProcessNode_r( gltfNode* modelNode, idMat4 parentTransfo for( auto& child : modelNode->children ) { - ProcessNode_r( nodeList[child], nodeToWorldTransform, data ); + ProcessNode_r( nodeList[child], nodeToWorldTransform, globalTransform, data ); } } @@ -144,6 +144,7 @@ void idRenderModelGLTF::InitFromFile( const char* fileName, idImportOptions* opt int meshID = -1; name = fileName; currentSkin = nullptr; + globalTransform = blenderToDoomTransform; PurgeModel(); @@ -231,7 +232,19 @@ void idRenderModelGLTF::InitFromFile( const char* fileName, idImportOptions* opt hasAnimations = totalAnims > 0; model_state = hasAnimations ? DM_CACHED : DM_STATIC; - ProcessNode_r( root, mat4_identity, data ); + //idMat4 globalTransform = blenderToDoomTransform; + + if( options ) + { + const auto blenderToDoomRotation = idAngles( 0.0f, 0.0f, 90 ).ToMat3(); + + float scale = options->scale; + idMat3 scaleMat( scale, 0, 0, 0, scale, 0, 0, 0, scale ); + + globalTransform = idMat4( scaleMat * blenderToDoomRotation, vec3_origin ); + } + + ProcessNode_r( root, mat4_identity, globalTransform, data ); if( surfaces.Num() <= 0 ) { @@ -508,7 +521,7 @@ static bool GatherBoneInfo( gltfData* data, gltfAnimation* gltfAnim, const idLis return boneLess; } -static idList GetPose( idList& bones, idJointMat* poseMat ) +static idList GetPose( idList& bones, idJointMat* poseMat, const idMat4& globalTransform ) { idList ret; ret.AssureSize( bones.Num() ); @@ -522,7 +535,7 @@ static idList GetPose( idList& bones, idJointMat* poseMat if( node->parent == nullptr ) { - node->matrix *= blenderToDoomTransform; + node->matrix *= globalTransform; trans = node->matrix; } @@ -587,7 +600,8 @@ static int CopyBones( gltfData* data, const idList& bones, idList idFile_Memory* idRenderModelGLTF::GetAnimBin( idStr animName, const ID_TIME_T sourceTimeStamp ) { assert( lastMeshFromFile ); - ///keep in sync with game! + + //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; GLTF_Parser gltf; @@ -631,6 +645,9 @@ idFile_Memory* idRenderModelGLTF::GetAnimBin( idStr animName, const ID_TIME_T so gameLocal.Printf( "Generating MD5Anim for GLTF anim %s from scene %s\n", name.c_str(), gltf_ModelSceneName.GetString() ); + // TODO use idImportOptions to build globalTransform + + gltfNode* root = nullptr; int channelCount = 0; for( auto channel : gltfAnim->channels ) @@ -725,7 +742,7 @@ idFile_Memory* idRenderModelGLTF::GetAnimBin( idStr animName, const ID_TIME_T so baseFrame.SetNum( bones.Num() ); idJointMat* poseMat = ( idJointMat* ) _alloca16( bones.Num() * sizeof( poseMat[0] ) ); - baseFrame = GetPose( animBones[0], poseMat ); + baseFrame = GetPose( animBones[0], poseMat, blenderToDoomTransform ); componentFrames.SetGranularity( 1 ); componentFrames.SetNum( ( ( numAnimatedComponents * numFrames ) ) + 1 ); @@ -846,7 +863,7 @@ idFile_Memory* idRenderModelGLTF::GetAnimBin( idStr animName, const ID_TIME_T so } idList joints; - GetPose( animBones[i], currJoints ); + GetPose( animBones[i], currJoints, blenderToDoomTransform ); for( int b = 0; b < animBones[i].Num(); b++ ) { idJointMat mat = poseMat[b]; @@ -1140,7 +1157,7 @@ void idRenderModelGLTF::LoadModel() idJointMat* poseMat = ( idJointMat* ) _alloca16( bones.Num() * sizeof( poseMat[0] ) ); idList animBones; int totalCopied = CopyBones( data, bones, animBones ); - defaultPose = GetPose( animBones, poseMat ); + defaultPose = GetPose( animBones, poseMat, globalTransform ); if( !currentSkin ) { diff --git a/neo/renderer/Model_gltf.h b/neo/renderer/Model_gltf.h index 856c5a44..03c4301c 100644 --- a/neo/renderer/Model_gltf.h +++ b/neo/renderer/Model_gltf.h @@ -57,7 +57,7 @@ public: static idFile_Memory* GetAnimBin( idStr animName, const ID_TIME_T sourceTimeStamp ); int rootID; private: - void ProcessNode_r( gltfNode* modelNode, idMat4 trans, gltfData* data ); + void ProcessNode_r( gltfNode* modelNode, const idMat4& parentTransform, const idMat4& globalTransform, gltfData* data ); void UpdateSurface( const struct renderEntity_s* ent, const idJointMat* entJoints, const idJointMat* entJointsInverted, modelSurface_t* surf, const modelSurface_t& sourceSurf ); void UpdateMd5Joints(); @@ -78,6 +78,9 @@ private: idList defaultPose; idList invertedDefaultPose; gltfSkin* currentSkin; + + // derived reimport options + idMat4 globalTransform; // Blender to Doom + exta scaling, rotation private: void DrawJoints( const struct renderEntity_s* ent, const viewDef_t* view ); }; \ No newline at end of file diff --git a/neo/renderer/Model_local.h b/neo/renderer/Model_local.h index 1cd32bd4..34544de9 100644 --- a/neo/renderer/Model_local.h +++ b/neo/renderer/Model_local.h @@ -359,7 +359,7 @@ class idRenderModelPrt : public idRenderModelStatic public: idRenderModelPrt(); - virtual void InitFromFile( const char* fileName ); + virtual void InitFromFile( const char* fileName, idImportOptions* options ); virtual bool SupportsBinaryModel() { return false; diff --git a/neo/renderer/Model_prt.cpp b/neo/renderer/Model_prt.cpp index 66a5f6d8..94519795 100644 --- a/neo/renderer/Model_prt.cpp +++ b/neo/renderer/Model_prt.cpp @@ -49,7 +49,7 @@ idRenderModelPrt::idRenderModelPrt() idRenderModelPrt::InitFromFile ==================== */ -void idRenderModelPrt::InitFromFile( const char* fileName ) +void idRenderModelPrt::InitFromFile( const char* fileName, idImportOptions* options ) { name = fileName; particleSystem = static_cast( declManager->FindType( DECL_PARTICLE, fileName ) );