From b8bf1eac041f0bbb406019a28f310509dad51b86 Mon Sep 17 00:00:00 2001 From: Inho Lee Date: Mon, 7 Dec 2020 09:51:19 +0100 Subject: [PATCH 1/2] FBXConverter : Fix timescales of FBX animations FBX animations were recorded by framenumber, not by time. This patch will change it as a base of milliseconds. --- code/AssetLib/FBX/FBXConverter.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/code/AssetLib/FBX/FBXConverter.cpp b/code/AssetLib/FBX/FBXConverter.cpp index 1a484a38a..c27e48076 100644 --- a/code/AssetLib/FBX/FBXConverter.cpp +++ b/code/AssetLib/FBX/FBXConverter.cpp @@ -79,7 +79,7 @@ using namespace Util; #define MAGIC_NODE_TAG "_$AssimpFbx$" -#define CONVERT_FBX_TIME(time) static_cast(time) / 46186158000LL +#define CONVERT_FBX_TIME(time) (static_cast(time) * 1000.0 / 46186158000LL) FBXConverter::FBXConverter(aiScene *out, const Document &doc, bool removeEmptyBones) : defaultMaterialIndex(), @@ -2560,7 +2560,7 @@ void FBXConverter::ConvertAnimationStack(const AnimationStack &st) { meshMorphAnim->mKeys[j].mNumValuesAndWeights = numValuesAndWeights; meshMorphAnim->mKeys[j].mValues = new unsigned int[numValuesAndWeights]; meshMorphAnim->mKeys[j].mWeights = new double[numValuesAndWeights]; - meshMorphAnim->mKeys[j].mTime = CONVERT_FBX_TIME(animIt.first) * anim_fps; + meshMorphAnim->mKeys[j].mTime = CONVERT_FBX_TIME(animIt.first); for (unsigned int k = 0; k < numValuesAndWeights; k++) { meshMorphAnim->mKeys[j].mValues[k] = keyData->values.at(k); meshMorphAnim->mKeys[j].mWeights[k] = keyData->weights.at(k); @@ -2578,8 +2578,8 @@ void FBXConverter::ConvertAnimationStack(const AnimationStack &st) { return; } - double start_time_fps = has_local_startstop ? (CONVERT_FBX_TIME(start_time) * anim_fps) : min_time; - double stop_time_fps = has_local_startstop ? (CONVERT_FBX_TIME(stop_time) * anim_fps) : max_time; + double start_time_fps = has_local_startstop ? CONVERT_FBX_TIME(start_time) : min_time; + double stop_time_fps = has_local_startstop ? CONVERT_FBX_TIME(stop_time) : max_time; // adjust relative timing for animation for (unsigned int c = 0; c < anim->mNumChannels; c++) { @@ -3099,7 +3099,7 @@ aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim(const std::string& name, InterpolateKeys(outTranslations, keytimes, keyframeLists[TransformationComp_Translation], defTranslate, maxTime, minTime); } else { for (size_t i = 0; i < keyCount; ++i) { - outTranslations[i].mTime = CONVERT_FBX_TIME(keytimes[i]) * anim_fps; + outTranslations[i].mTime = CONVERT_FBX_TIME(keytimes[i]); outTranslations[i].mValue = defTranslate; } } @@ -3108,7 +3108,7 @@ aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim(const std::string& name, InterpolateKeys(outRotations, keytimes, keyframeLists[TransformationComp_Rotation], defRotation, maxTime, minTime, rotOrder); } else { for (size_t i = 0; i < keyCount; ++i) { - outRotations[i].mTime = CONVERT_FBX_TIME(keytimes[i]) * anim_fps; + outRotations[i].mTime = CONVERT_FBX_TIME(keytimes[i]); outRotations[i].mValue = defQuat; } } @@ -3117,7 +3117,7 @@ aiNodeAnim* FBXConverter::GenerateSimpleNodeAnim(const std::string& name, InterpolateKeys(outScales, keytimes, keyframeLists[TransformationComp_Scaling], defScale, maxTime, minTime); } else { for (size_t i = 0; i < keyCount; ++i) { - outScales[i].mTime = CONVERT_FBX_TIME(keytimes[i]) * anim_fps; + outScales[i].mTime = CONVERT_FBX_TIME(keytimes[i]); outScales[i].mValue = defScale; } } @@ -3306,7 +3306,7 @@ void FBXConverter::InterpolateKeys(aiVectorKey *valOut, const KeyTimeList &keys, } // magic value to convert fbx times to seconds - valOut->mTime = CONVERT_FBX_TIME(time) * anim_fps; + valOut->mTime = CONVERT_FBX_TIME(time); min_time = std::min(min_time, valOut->mTime); max_time = std::max(max_time, valOut->mTime); From 4e5b25cd81990003e2035d39e58e1df5629b403f Mon Sep 17 00:00:00 2001 From: Inho Lee Date: Wed, 16 Dec 2020 17:55:05 +0100 Subject: [PATCH 2/2] Keep AnimMesh data during the SortByPTypeProcess A Postprocessing step, SortByPTypeProcess, can rebuild Mesh data, but it does not handle AnimMesh. This patch helps to rebuild appropriate AnimMeshes for the Mesh. --- code/PostProcessing/SortByPTypeProcess.cpp | 64 ++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/code/PostProcessing/SortByPTypeProcess.cpp b/code/PostProcessing/SortByPTypeProcess.cpp index c4f9c7e4d..332d9d7ef 100644 --- a/code/PostProcessing/SortByPTypeProcess.cpp +++ b/code/PostProcessing/SortByPTypeProcess.cpp @@ -243,6 +243,45 @@ void SortByPTypeProcess::Execute(aiScene *pScene) { } } + if (mesh->mNumAnimMeshes > 0 && mesh->mAnimMeshes) { + out->mNumAnimMeshes = mesh->mNumAnimMeshes; + out->mAnimMeshes = new aiAnimMesh *[out->mNumAnimMeshes]; + } + + for (unsigned int j = 0; j < mesh->mNumAnimMeshes; ++j) { + aiAnimMesh *animMesh = mesh->mAnimMeshes[j]; + aiAnimMesh *outAnimMesh = out->mAnimMeshes[j] = new aiAnimMesh; + outAnimMesh->mNumVertices = out->mNumVertices; + if (animMesh->mVertices) + outAnimMesh->mVertices = new aiVector3D[out->mNumVertices]; + else + outAnimMesh->mVertices = nullptr; + if (animMesh->mNormals) + outAnimMesh->mNormals = new aiVector3D[out->mNumVertices]; + else + outAnimMesh->mNormals = nullptr; + if (animMesh->mTangents) + outAnimMesh->mTangents = new aiVector3D[out->mNumVertices]; + else + outAnimMesh->mTangents = nullptr; + if (animMesh->mBitangents) + outAnimMesh->mBitangents = new aiVector3D[out->mNumVertices]; + else + outAnimMesh->mBitangents = nullptr; + for (int jj = 0; jj < AI_MAX_NUMBER_OF_COLOR_SETS; ++jj) { + if (animMesh->mColors[jj]) + outAnimMesh->mColors[jj] = new aiColor4D[out->mNumVertices]; + else + outAnimMesh->mColors[jj] = nullptr; + } + for (int jj = 0; jj < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++jj) { + if (animMesh->mTextureCoords[jj]) + outAnimMesh->mTextureCoords[jj] = new aiVector3D[out->mNumVertices]; + else + outAnimMesh->mTextureCoords[jj] = nullptr; + } + } + typedef std::vector TempBoneInfo; std::vector tempBones(mesh->mNumBones); @@ -252,6 +291,7 @@ void SortByPTypeProcess::Execute(aiScene *pScene) { } unsigned int outIdx = 0; + unsigned int amIdx = 0; // AnimMesh index for (unsigned int m = 0; m < mesh->mNumFaces; ++m) { aiFace &in = mesh->mFaces[m]; if ((real == 3 && in.mNumIndices <= 3) || (real != 3 && in.mNumIndices != real + 1)) { @@ -293,6 +333,30 @@ void SortByPTypeProcess::Execute(aiScene *pScene) { *cols[pp]++ = mesh->mColors[pp][idx]; } + unsigned int pp = 0; + for (; pp < mesh->mNumAnimMeshes; ++pp) { + aiAnimMesh *animMesh = mesh->mAnimMeshes[pp]; + aiAnimMesh *outAnimMesh = out->mAnimMeshes[pp]; + if (animMesh->mVertices) + outAnimMesh->mVertices[amIdx] = animMesh->mVertices[idx]; + if (animMesh->mNormals) + outAnimMesh->mNormals[amIdx] = animMesh->mNormals[idx]; + if (animMesh->mTangents) + outAnimMesh->mTangents[amIdx] = animMesh->mTangents[idx]; + if (animMesh->mBitangents) + outAnimMesh->mBitangents[amIdx] = animMesh->mBitangents[idx]; + for (int jj = 0; jj < AI_MAX_NUMBER_OF_COLOR_SETS; ++jj) { + if (animMesh->mColors[jj]) + outAnimMesh->mColors[jj][amIdx] = animMesh->mColors[jj][idx]; + } + for (int jj = 0; jj < AI_MAX_NUMBER_OF_TEXTURECOORDS; ++jj) { + if (animMesh->mTextureCoords[jj]) + outAnimMesh->mTextureCoords[jj][amIdx] = animMesh->mTextureCoords[jj][idx]; + } + } + if (pp == mesh->mNumAnimMeshes) + amIdx++; + in.mIndices[q] = outIdx++; }