diff --git a/Engine/source/ts/assimp/assimpAppMesh.cpp b/Engine/source/ts/assimp/assimpAppMesh.cpp index 8270ce1f3..d78898c32 100644 --- a/Engine/source/ts/assimp/assimpAppMesh.cpp +++ b/Engine/source/ts/assimp/assimpAppMesh.cpp @@ -226,7 +226,6 @@ void AssimpAppMesh::lockMesh(F32 t, const MatrixF& objOffset) bonePos /= scaleMult; } - bonePos *= ColladaUtils::getOptions().unit * ColladaUtils::getOptions().formatScaleFactor; boneTransform.setPosition(bonePos); initialTransforms.push_back(boneTransform); diff --git a/Engine/source/ts/assimp/assimpAppNode.cpp b/Engine/source/ts/assimp/assimpAppNode.cpp index 88d5af975..5c90e11ec 100644 --- a/Engine/source/ts/assimp/assimpAppNode.cpp +++ b/Engine/source/ts/assimp/assimpAppNode.cpp @@ -178,12 +178,16 @@ Point3F AssimpAppNode::interpolateVectorKey(const aiVectorKey* keys, U32 numKeys { if (frameTime < keys[i].mTime) { + Assimp::Interpolator interp; + + const aiVectorKey& next = keys[i]; + const aiVectorKey& prev = keys[i - 1]; + const F32 factor = (frameTime - keys[i - 1].mTime) / (keys[i].mTime - keys[i - 1].mTime); - Point3F start(keys[i - 1].mValue.x, keys[i - 1].mValue.y, keys[i - 1].mValue.z); - Point3F end(keys[i].mValue.x, keys[i].mValue.y, keys[i].mValue.z); - Point3F result; - result.interpolate(start, end, factor); - return result; + + aiVector3D out; + interp(out, prev, next, factor); + return Point3F(out.x, out.y, out.z); } } @@ -196,6 +200,16 @@ QuatF AssimpAppNode::interpolateQuaternionKey(const aiQuatKey* keys, U32 numKeys if (numKeys == 1) // Single keyframe: use it directly return QuatF(keys[0].mValue.x, keys[0].mValue.y, keys[0].mValue.z, keys[0].mValue.w); + // Clamp frameTime to the bounds of the keyframes + if (frameTime <= keys[0].mTime) { + // Before the first keyframe, return the first key + return QuatF(keys[0].mValue.x, keys[0].mValue.y, keys[0].mValue.z, keys[0].mValue.w); + } + if (frameTime >= keys[numKeys - 1].mTime) { + // After the last keyframe, return the last key + return QuatF(keys[numKeys - 1].mValue.x, keys[numKeys - 1].mValue.y, keys[numKeys - 1].mValue.z, keys[numKeys - 1].mValue.w); + } + for (U32 i = 1; i < numKeys; ++i) { if (frameTime < keys[i].mTime) diff --git a/Engine/source/ts/assimp/assimpAppSequence.cpp b/Engine/source/ts/assimp/assimpAppSequence.cpp index f34d612ed..0c31b6ca0 100644 --- a/Engine/source/ts/assimp/assimpAppSequence.cpp +++ b/Engine/source/ts/assimp/assimpAppSequence.cpp @@ -15,7 +15,7 @@ AssimpAppSequence::AssimpAppSequence(aiAnimation* a) : seqStart(0.0f), seqEnd(0.0f), mTimeMultiplier(1.0f) { - fps = 30.0f; + fps = ColladaUtils::getOptions().animFPS; // Deep copy animation structure mAnim = new aiAnimation(*a); mAnim->mChannels = new aiNodeAnim * [a->mNumChannels]; diff --git a/Engine/source/ts/assimp/assimpShapeLoader.cpp b/Engine/source/ts/assimp/assimpShapeLoader.cpp index 1f05f0fab..e96a24c25 100644 --- a/Engine/source/ts/assimp/assimpShapeLoader.cpp +++ b/Engine/source/ts/assimp/assimpShapeLoader.cpp @@ -279,7 +279,6 @@ void AssimpShapeLoader::enumerateScene() detectDetails(); aiNode* root = mScene->mRootNode; - for (S32 iNode = 0; iNode < root->mNumChildren; iNode++) { aiNode* child = root->mChildren[iNode]; @@ -352,6 +351,10 @@ void AssimpShapeLoader::configureImportUnits() { { opts.unit = (F32)unit; } + + F32 fps; + getMetaFloat("CustomFrameRate", fps); + opts.animFPS = fps; } } @@ -388,21 +391,18 @@ void AssimpShapeLoader::processAnimations() Vector ambientChannels; F32 duration = 0.0f; - F32 ticks = 0.0f; + F32 maxKeyTime = 0.0f; if (mScene->mNumAnimations > 0) { for (U32 i = 0; i < mScene->mNumAnimations; ++i) { aiAnimation* anim = mScene->mAnimations[i]; - ticks = anim->mTicksPerSecond; - duration = 0.0f; for (U32 j = 0; j < anim->mNumChannels; j++) { aiNodeAnim* nodeAnim = anim->mChannels[j]; // Determine the maximum keyframe time for this animation - F32 maxKeyTime = 0.0f; for (U32 k = 0; k < nodeAnim->mNumPositionKeys; k++) { maxKeyTime = getMax(maxKeyTime, (F32)nodeAnim->mPositionKeys[k].mTime); } @@ -422,7 +422,7 @@ void AssimpShapeLoader::processAnimations() ambientSeq->mNumChannels = ambientChannels.size(); ambientSeq->mChannels = ambientChannels.address(); ambientSeq->mDuration = duration; - ambientSeq->mTicksPerSecond = ticks; + ambientSeq->mTicksPerSecond = ColladaUtils::getOptions().animFPS; AssimpAppSequence* defaultAssimpSeq = new AssimpAppSequence(ambientSeq); appSequences.push_back(defaultAssimpSeq);