diff --git a/AssetStudio/StudioClasses/ModelConverter.cs b/AssetStudio/StudioClasses/ModelConverter.cs index 2c4c5cd..0f9f26a 100644 --- a/AssetStudio/StudioClasses/ModelConverter.cs +++ b/AssetStudio/StudioClasses/ModelConverter.cs @@ -15,7 +15,7 @@ namespace AssetStudio public List MeshList { get; protected set; } = new List(); public List MaterialList { get; protected set; } = new List(); public List TextureList { get; protected set; } = new List(); - public List AnimationList { get; protected set; } = new List(); + public List AnimationList { get; protected set; } = new List(); public List MorphList { get; protected set; } = new List(); private Avatar avatar; @@ -651,14 +651,14 @@ namespace AssetStudio { foreach (var assetPreloadData in animationClipHashSet) { - var clip = new AnimationClip(assetPreloadData); - if (clip.m_Legacy) + var animationClip = new AnimationClip(assetPreloadData); + var iAnim = new ImportedKeyframedAnimation(); + AnimationList.Add(iAnim); + iAnim.Name = animationClip.m_Name; + iAnim.TrackList = new List(); + if (animationClip.m_Legacy) { - var iAnim = new ImportedKeyframedAnimation(); - iAnim.Name = clip.m_Name; - AnimationList.Add(iAnim); - iAnim.TrackList = new List(); - foreach (var m_RotationCurve in clip.m_RotationCurves) + foreach (var m_RotationCurve in animationClip.m_RotationCurves) { var path = m_RotationCurve.path; var boneName = path.Substring(path.LastIndexOf('/') + 1); @@ -675,7 +675,7 @@ namespace AssetStudio track.Rotations.Add(new ImportedKeyframe(m_Curve.time, value)); } } - foreach (var m_PositionCurve in clip.m_PositionCurves) + foreach (var m_PositionCurve in animationClip.m_PositionCurves) { var path = m_PositionCurve.path; var boneName = path.Substring(path.LastIndexOf('/') + 1); @@ -691,7 +691,7 @@ namespace AssetStudio track.Translations.Add(new ImportedKeyframe(m_Curve.time, new Vector3(-m_Curve.value.X, m_Curve.value.Y, m_Curve.value.Z))); } } - foreach (var m_ScaleCurve in clip.m_ScaleCurves) + foreach (var m_ScaleCurve in animationClip.m_ScaleCurves) { var path = m_ScaleCurve.path; var boneName = path.Substring(path.LastIndexOf('/') + 1); @@ -707,184 +707,122 @@ namespace AssetStudio track.Scalings.Add(new ImportedKeyframe(m_Curve.time, new Vector3(m_Curve.value.X, m_Curve.value.Y, m_Curve.value.Z))); } } - - if ((bool)Properties.Settings.Default["FixRotation"]) - { - foreach (var track in iAnim.TrackList) - { - var prevKey = new Vector3(); - foreach (var rotation in track.Rotations) - { - var value = rotation.value; - ReplaceOutOfBound(ref prevKey, ref value); - prevKey = value; - rotation.value = value; - } - } - } } else { - var iAnim = new ImportedSampledAnimation(); - iAnim.Name = clip.m_Name; - iAnim.SampleRate = clip.m_SampleRate; - AnimationList.Add(iAnim); - int numTracks = (clip.m_MuscleClip.m_Clip.m_ConstantClip.data.Length + (int)clip.m_MuscleClip.m_Clip.m_DenseClip.m_CurveCount + (int)clip.m_MuscleClip.m_Clip.m_StreamedClip.curveCount + 9) / 10; - iAnim.TrackList = new List(numTracks); - var streamedFrames = clip.m_MuscleClip.m_Clip.m_StreamedClip.ReadData(); - float[] streamedValues = new float[clip.m_MuscleClip.m_Clip.m_StreamedClip.curveCount]; - int numFrames = Math.Max(clip.m_MuscleClip.m_Clip.m_DenseClip.m_FrameCount, streamedFrames.Count - 2); - for (int frameIdx = 0; frameIdx < numFrames; frameIdx++) + var m_Clip = animationClip.m_MuscleClip.m_Clip; + var streamedFrames = m_Clip.m_StreamedClip.ReadData(); + var m_ClipBindingConstant = animationClip.m_ClipBindingConstant; + for (int frameIndex = 1; frameIndex < streamedFrames.Count - 1; frameIndex++) { - if (1 + frameIdx < streamedFrames.Count) + var frame = streamedFrames[frameIndex]; + var streamedValues = frame.keyList.Select(x => x.value).ToArray(); + for (int curveIndex = 0; curveIndex < frame.keyList.Count;) { - for (int i = 0; i < streamedFrames[1 + frameIdx].keyList.Count; i++) - { - streamedValues[i] = streamedFrames[1 + frameIdx].keyList[i].value; - } - } - - int numStreamedCurves = 1 + frameIdx < streamedFrames.Count ? streamedFrames[1 + frameIdx].keyList.Count : 0; - int numCurves = numStreamedCurves + (int)clip.m_MuscleClip.m_Clip.m_DenseClip.m_CurveCount + clip.m_MuscleClip.m_Clip.m_ConstantClip.data.Length; - int streamOffset = numStreamedCurves - (int)clip.m_MuscleClip.m_Clip.m_StreamedClip.curveCount; - for (int curveIdx = 0; curveIdx < numCurves;) - { - GenericBinding binding; - float[] data; - int dataOffset; - if (1 + frameIdx < streamedFrames.Count && curveIdx < streamedFrames[1 + frameIdx].keyList.Count) - { - binding = clip.m_ClipBindingConstant.FindBinding(streamedFrames[1 + frameIdx].keyList[curveIdx].index); - data = streamedValues; - dataOffset = 0; - } - else if (curveIdx < numStreamedCurves + clip.m_MuscleClip.m_Clip.m_DenseClip.m_CurveCount) - { - binding = clip.m_ClipBindingConstant.FindBinding(curveIdx - streamOffset); - data = clip.m_MuscleClip.m_Clip.m_DenseClip.m_SampleArray; - dataOffset = numStreamedCurves - frameIdx * (int)clip.m_MuscleClip.m_Clip.m_DenseClip.m_CurveCount; - } - else - { - binding = clip.m_ClipBindingConstant.FindBinding(curveIdx - streamOffset); - data = clip.m_MuscleClip.m_Clip.m_ConstantClip.data; - dataOffset = numStreamedCurves + (int)clip.m_MuscleClip.m_Clip.m_DenseClip.m_CurveCount; - } - - if (binding.path == 0) - { - curveIdx++; - continue; - } - - string boneName = GetNameFromHashes(binding.path, binding.attribute); - ImportedAnimationSampledTrack track = iAnim.FindTrack(boneName); - if (track == null) - { - track = new ImportedAnimationSampledTrack(); - track.Name = boneName; - iAnim.TrackList.Add(track); - } - - try - { - switch (binding.attribute) - { - case 1: - if (track.Translations == null) - { - track.Translations = new Vector3?[numFrames]; - } - - track.Translations[frameIdx] = new Vector3 - ( - -data[curveIdx++ - dataOffset], - data[curveIdx++ - dataOffset], - data[curveIdx++ - dataOffset] - ); - break; - case 2: - if (track.Rotations == null) - { - track.Rotations = new Vector3?[numFrames]; - } - - track.Rotations[frameIdx] = Fbx.QuaternionToEuler(new Quaternion - ( - data[curveIdx++ - dataOffset], - -data[curveIdx++ - dataOffset], - -data[curveIdx++ - dataOffset], - data[curveIdx++ - dataOffset] - )); - break; - case 3: - if (track.Scalings == null) - { - track.Scalings = new Vector3?[numFrames]; - } - - track.Scalings[frameIdx] = new Vector3 - ( - data[curveIdx++ - dataOffset], - data[curveIdx++ - dataOffset], - data[curveIdx++ - dataOffset] - ); - break; - case 4: - if (track.Rotations == null) - { - track.Rotations = new Vector3?[numFrames]; - } - - track.Rotations[frameIdx] = new Vector3 - ( - data[curveIdx++ - dataOffset], - -data[curveIdx++ - dataOffset], - -data[curveIdx++ - dataOffset] - ); - break; - default: - if (track.Curve == null) - { - track.Curve = new float?[numFrames]; - } - - track.Curve[frameIdx] = data[curveIdx++ - dataOffset]; - break; - } - } - catch - { - //errors.Append(" ").Append(boneName).Append(" a=").Append(binding.attribute).Append(" ci=").Append(curveIdx).Append("/#=").Append(numCurves).Append(" of=").Append(dataOffset).Append(" f=").Append(frameIdx).Append("/#=").Append(numFrames).Append("\n"); - //TODO Display error - break; - } + ReadCurveData(iAnim, m_ClipBindingConstant, frame.keyList[curveIndex].index, frame.time, streamedValues, 0, ref curveIndex); } } - - if ((bool)Properties.Settings.Default["FixRotation"]) + var m_DenseClip = m_Clip.m_DenseClip; + var streamCount = m_Clip.m_StreamedClip.curveCount; + for (int frameIndex = 0; frameIndex < m_DenseClip.m_FrameCount; frameIndex++) { - foreach (var track in iAnim.TrackList) + var time = frameIndex / m_DenseClip.m_SampleRate; + var frameOffset = frameIndex * m_DenseClip.m_CurveCount; + for (int curveIndex = 0; curveIndex < m_DenseClip.m_CurveCount;) { - if (track.Rotations == null) - continue; - var prevKey = new Vector3(); - for (var i = 0; i < track.Rotations.Length; i++) - { - var rotation = track.Rotations[i]; - if (rotation == null) - continue; - var value = new Vector3(rotation.Value.X, rotation.Value.Y, rotation.Value.Z); - ReplaceOutOfBound(ref prevKey, ref value); - prevKey = value; - track.Rotations[i] = value; - } + var index = streamCount + curveIndex; + ReadCurveData(iAnim, m_ClipBindingConstant, (int)index, time, m_DenseClip.m_SampleArray, (int)frameOffset, ref curveIndex); + } + } + var m_ConstantClip = m_Clip.m_ConstantClip; + var denseCount = m_Clip.m_DenseClip.m_CurveCount; + var time2 = 0.0f; + for (int i = 0; i < 2; i++) + { + for (int curveIndex = 0; curveIndex < m_ConstantClip.data.Length;) + { + var index = streamCount + denseCount + curveIndex; + ReadCurveData(iAnim, m_ClipBindingConstant, (int)index, time2, m_ConstantClip.data, 0, ref curveIndex); + } + time2 = animationClip.m_MuscleClip.m_StopTime; + } + } + + if ((bool)Properties.Settings.Default["FixRotation"]) + { + foreach (var track in iAnim.TrackList) + { + var prevKey = new Vector3(); + foreach (var rotation in track.Rotations) + { + var value = rotation.value; + ReplaceOutOfBound(ref prevKey, ref value); + prevKey = value; + rotation.value = value; } } } } } + private void ReadCurveData(ImportedKeyframedAnimation iAnim, AnimationClipBindingConstant m_ClipBindingConstant, int index, float time, float[] data, int offset, ref int curveIndex) + { + var binding = m_ClipBindingConstant.FindBinding(index); + if (binding.path == 0) + { + curveIndex++; + return; + } + var boneName = GetNameFromHashes(binding.path, binding.attribute); + var track = iAnim.FindTrack(boneName); + if (track == null) + { + track = new ImportedAnimationKeyframedTrack { Name = boneName }; + iAnim.TrackList.Add(track); + } + + switch (binding.attribute) + { + case 1: + track.Translations.Add(new ImportedKeyframe(time, new Vector3 + ( + -data[curveIndex++ + offset], + data[curveIndex++ + offset], + data[curveIndex++ + offset] + ))); + break; + case 2: + var value = Fbx.QuaternionToEuler(new Quaternion + ( + data[curveIndex++ + offset], + -data[curveIndex++ + offset], + -data[curveIndex++ + offset], + data[curveIndex++ + offset] + )); + track.Rotations.Add(new ImportedKeyframe(time, value)); + break; + case 3: + track.Scalings.Add(new ImportedKeyframe(time, new Vector3 + ( + data[curveIndex++ + offset], + data[curveIndex++ + offset], + data[curveIndex++ + offset] + ))); + break; + case 4: + track.Rotations.Add(new ImportedKeyframe(time, new Vector3 + ( + data[curveIndex++ + offset], + -data[curveIndex++ + offset], + -data[curveIndex++ + offset] + ))); + break; + default: + track.Curve.Add(new ImportedKeyframe(time, data[curveIndex++])); + break; + } + } + private string GetNameFromHashes(uint path, uint attribute) { var boneName = GetNameFromBonePathHashes(path); diff --git a/AssetStudioFBX/AssetStudioFBX.h b/AssetStudioFBX/AssetStudioFBX.h index dbe0954..51a91dc 100644 --- a/AssetStudioFBX/AssetStudioFBX.h +++ b/AssetStudioFBX/AssetStudioFBX.h @@ -66,8 +66,7 @@ namespace AssetStudio { void ExportMesh(FbxNode* pFrameNode, ImportedMesh^ meshList, bool normals); FbxFileTexture* ExportTexture(ImportedTexture^ matTex, FbxMesh* pMesh); void ExportAnimations(bool EulerFilter, float filterValue, bool flatInbetween); - void ExportKeyframedAnimation(ImportedKeyframedAnimation^ parser, FbxString& kTakeName, FbxAnimCurveFilterUnroll* EulerFilter, float filterPrecision, List^ pNotFound); - void ExportSampledAnimation(ImportedSampledAnimation^ parser, FbxString& kTakeName, FbxAnimCurveFilterUnroll* EulerFilter, float filterPrecision, bool flatInbetween, List^ pNotFound); + void ExportKeyframedAnimation(ImportedKeyframedAnimation^ parser, FbxString& kTakeName, FbxAnimCurveFilterUnroll* EulerFilter, float filterPrecision, bool flatInbetween); void ExportMorphs(IImported^ imported, bool morphMask, bool flatInbetween); }; diff --git a/AssetStudioFBX/AssetStudioFBXExporter.cpp b/AssetStudioFBX/AssetStudioFBXExporter.cpp index c98b77e..5cf00b4 100644 --- a/AssetStudioFBX/AssetStudioFBXExporter.cpp +++ b/AssetStudioFBX/AssetStudioFBXExporter.cpp @@ -713,14 +713,12 @@ namespace AssetStudio void Fbx::Exporter::ExportAnimations(bool EulerFilter, float filterPrecision, bool flatInbetween) { - List^ importedAnimationList = imported->AnimationList; + auto importedAnimationList = imported->AnimationList; if (importedAnimationList == nullptr) { return; } - List^ pNotFound = gcnew List(); - FbxAnimCurveFilterUnroll* lFilter = EulerFilter ? new FbxAnimCurveFilterUnroll() : NULL; for (int i = 0; i < importedAnimationList->Count; i++) @@ -740,37 +738,16 @@ namespace AssetStudio { kTakeName = FbxString("Take") + FbxString(i); } - bool keyframed = dynamic_cast(importedAnimation) != nullptr; - if (keyframed) - { - ImportedKeyframedAnimation^ parser = (ImportedKeyframedAnimation^)importedAnimation; - ExportKeyframedAnimation(parser, kTakeName, lFilter, filterPrecision, pNotFound); - } - else - { - ImportedSampledAnimation^ parser = (ImportedSampledAnimation^)importedAnimation; - ExportSampledAnimation(parser, kTakeName, lFilter, filterPrecision, flatInbetween, pNotFound); - } + ExportKeyframedAnimation(importedAnimation, kTakeName, lFilter, filterPrecision, flatInbetween); } - - /*if (pNotFound->Count > 0) - { - String^ pNotFoundString = gcnew String("Warning: Animations weren't exported for the following missing frames or morphs: "); - for (int i = 0; i < pNotFound->Count; i++) - { - pNotFoundString += pNotFound[i] + ", "; - } - Report::ReportLog(pNotFoundString->Substring(0, pNotFoundString->Length - 2)); - }*/ } - void Fbx::Exporter::ExportKeyframedAnimation(ImportedKeyframedAnimation^ parser, FbxString& kTakeName, FbxAnimCurveFilterUnroll* EulerFilter, float filterPrecision, List^ pNotFound) + void Fbx::Exporter::ExportKeyframedAnimation(ImportedKeyframedAnimation^ parser, FbxString& kTakeName, FbxAnimCurveFilterUnroll* EulerFilter, float filterPrecision, bool flatInbetween) { List^ pAnimationList = parser->TrackList; char* lTakeName = kTakeName.Buffer(); - FbxTime lTime; FbxAnimStack* lAnimStack = FbxAnimStack::Create(pScene, lTakeName); FbxAnimLayer* lAnimLayer = FbxAnimLayer::Create(pScene, "Base Layer"); lAnimStack->AddMember(lAnimLayer); @@ -796,14 +773,7 @@ namespace AssetStudio Marshal::FreeHGlobal((IntPtr)pName); } - if (pNode == NULL) - { - if (!pNotFound->Contains(name)) - { - pNotFound->Add(name); - } - } - else + if (pNode != NULL) { FbxAnimCurve* lCurveSX = pNode->LclScaling.GetCurve(lAnimLayer, FBXSDK_CURVENODE_COMPONENT_X, true); FbxAnimCurve* lCurveSY = pNode->LclScaling.GetCurve(lAnimLayer, FBXSDK_CURVENODE_COMPONENT_Y, true); @@ -825,6 +795,8 @@ namespace AssetStudio lCurveTY->KeyModifyBegin(); lCurveTZ->KeyModifyBegin(); + FbxTime lTime; + for each (auto Scaling in keyframeList->Scalings) { lTime.SetSecondDouble(Scaling->time); @@ -871,163 +843,14 @@ namespace AssetStudio EulerFilter->SetQualityTolerance(filterPrecision); EulerFilter->Apply(lCurve, 3); } - } - } - } - void Fbx::Exporter::ExportSampledAnimation(ImportedSampledAnimation^ parser, FbxString& kTakeName, FbxAnimCurveFilterUnroll* EulerFilter, float filterPrecision, bool flatInbetween, List^ pNotFound) - { - List^ pAnimationList = parser->TrackList; - - char* lTakeName = kTakeName.Buffer(); - - FbxTime lTime; - FbxAnimStack* lAnimStack = FbxAnimStack::Create(pScene, lTakeName); - FbxAnimLayer* lAnimLayer = FbxAnimLayer::Create(pScene, "Base Layer"); - lAnimStack->AddMember(lAnimLayer); - - const double fps = 1.0 / parser->SampleRate; - - for (int j = 0; j < pAnimationList->Count; j++) - { - ImportedAnimationSampledTrack^ sampleList = pAnimationList[j]; - - int endAt; - if (sampleList->Scalings && sampleList->Scalings->Length > 0) - { - endAt = sampleList->Scalings->Length; - } - else if (sampleList->Rotations && sampleList->Rotations->Length > 0) - { - endAt = sampleList->Rotations->Length; - } - else if (sampleList->Translations && sampleList->Translations->Length > 0) - { - endAt = sampleList->Translations->Length; - } - else if (sampleList->Curve && sampleList->Curve->Length > 0) - { - endAt = sampleList->Curve->Length; - } - - String^ name = sampleList->Name; - int dotPos = name->IndexOf('.'); - if (dotPos >= 0 && !ImportedHelpers::FindFrame(name, imported->FrameList[0])) - { - name = name->Substring(0, dotPos); - } - FbxNode* pNode = NULL; - char* pName = NULL; - try - { - pName = Fbx::StringToCharArray(name); - pNode = pScene->GetRootNode()->FindChild(pName); - } - finally - { - Marshal::FreeHGlobal((IntPtr)pName); - } - - if (pNode == NULL) - { - if (!pNotFound->Contains(name)) - { - pNotFound->Add(name); - } - } - else - { - if (sampleList->Scalings) - { - FbxAnimCurve* lCurveSX = pNode->LclScaling.GetCurve(lAnimLayer, FBXSDK_CURVENODE_COMPONENT_X, true); - FbxAnimCurve* lCurveSY = pNode->LclScaling.GetCurve(lAnimLayer, FBXSDK_CURVENODE_COMPONENT_Y, true); - FbxAnimCurve* lCurveSZ = pNode->LclScaling.GetCurve(lAnimLayer, FBXSDK_CURVENODE_COMPONENT_Z, true); - lCurveSX->KeyModifyBegin(); - lCurveSY->KeyModifyBegin(); - lCurveSZ->KeyModifyBegin(); - for (int k = 0; k < endAt; k++) - { - if (!sampleList->Scalings[k].HasValue) - continue; - - lTime.SetSecondDouble(fps * k); - - lCurveSX->KeySet(lCurveSX->KeyAdd(lTime), lTime, sampleList->Scalings[k].Value.X); - lCurveSY->KeySet(lCurveSY->KeyAdd(lTime), lTime, sampleList->Scalings[k].Value.Y); - lCurveSZ->KeySet(lCurveSZ->KeyAdd(lTime), lTime, sampleList->Scalings[k].Value.Z); - } - lCurveSX->KeyModifyEnd(); - lCurveSY->KeyModifyEnd(); - lCurveSZ->KeyModifyEnd(); - } - - if (sampleList->Rotations) - { - FbxAnimCurve* lCurveRX = pNode->LclRotation.GetCurve(lAnimLayer, FBXSDK_CURVENODE_COMPONENT_X, true); - FbxAnimCurve* lCurveRY = pNode->LclRotation.GetCurve(lAnimLayer, FBXSDK_CURVENODE_COMPONENT_Y, true); - FbxAnimCurve* lCurveRZ = pNode->LclRotation.GetCurve(lAnimLayer, FBXSDK_CURVENODE_COMPONENT_Z, true); - lCurveRX->KeyModifyBegin(); - lCurveRY->KeyModifyBegin(); - lCurveRZ->KeyModifyBegin(); - for (int k = 0; k < endAt; k++) - { - if (!sampleList->Rotations[k].HasValue) - continue; - - lTime.SetSecondDouble(fps * k); - - lCurveRX->KeySet(lCurveRX->KeyAdd(lTime), lTime, sampleList->Rotations[k].Value.X); - lCurveRY->KeySet(lCurveRY->KeyAdd(lTime), lTime, sampleList->Rotations[k].Value.Y); - lCurveRZ->KeySet(lCurveRZ->KeyAdd(lTime), lTime, sampleList->Rotations[k].Value.Z); - } - lCurveRX->KeyModifyEnd(); - lCurveRY->KeyModifyEnd(); - lCurveRZ->KeyModifyEnd(); - - if (EulerFilter) - { - FbxAnimCurve* lCurve[3]; - lCurve[0] = lCurveRX; - lCurve[1] = lCurveRY; - lCurve[2] = lCurveRZ; - EulerFilter->Reset(); - EulerFilter->SetTestForPath(true); - EulerFilter->SetQualityTolerance(filterPrecision); - EulerFilter->Apply(lCurve, 3); - } - } - - if (sampleList->Translations) - { - FbxAnimCurve* lCurveTX = pNode->LclTranslation.GetCurve(lAnimLayer, FBXSDK_CURVENODE_COMPONENT_X, true); - FbxAnimCurve* lCurveTY = pNode->LclTranslation.GetCurve(lAnimLayer, FBXSDK_CURVENODE_COMPONENT_Y, true); - FbxAnimCurve* lCurveTZ = pNode->LclTranslation.GetCurve(lAnimLayer, FBXSDK_CURVENODE_COMPONENT_Z, true); - lCurveTX->KeyModifyBegin(); - lCurveTY->KeyModifyBegin(); - lCurveTZ->KeyModifyBegin(); - for (int k = 0; k < endAt; k++) - { - if (!sampleList->Translations[k].HasValue) - continue; - - lTime.SetSecondDouble(fps * k); - - lCurveTX->KeySet(lCurveTX->KeyAdd(lTime), lTime, sampleList->Translations[k].Value.X); - lCurveTY->KeySet(lCurveTY->KeyAdd(lTime), lTime, sampleList->Translations[k].Value.Y); - lCurveTZ->KeySet(lCurveTZ->KeyAdd(lTime), lTime, sampleList->Translations[k].Value.Z); - } - lCurveTX->KeyModifyEnd(); - lCurveTY->KeyModifyEnd(); - lCurveTZ->KeyModifyEnd(); - } - - if (sampleList->Curve) + if (keyframeList->Curve->Count > 0) { FbxNode* pMeshNode = pNode->GetChild(0); FbxMesh* pMesh = pMeshNode ? pMeshNode->GetMesh() : NULL; if (pMesh) { - name = sampleList->Name->Substring(dotPos + 1); + name = keyframeList->Name->Substring(dotPos + 1); int numBlendShapes = pMesh->GetDeformerCount(FbxDeformer::eBlendShape); for (int bsIdx = 0; bsIdx < numBlendShapes; bsIdx++) { @@ -1067,28 +890,22 @@ namespace AssetStudio else { flatMaxStrength = 100; - //Report::ReportLog("Error! Weight for flat Blend-Shape " + shapeName + " not found! Using a value of " + flatMaxStrength); } } lCurve->KeyModifyBegin(); - for (int k = 0; k < endAt; k++) + for each (auto Curve in keyframeList->Curve) { - if (!sampleList->Curve[k].HasValue) - { - continue; - } - - lTime.SetSecondDouble(fps * k); + lTime.SetSecondDouble(Curve->time); auto keySetIndex = lCurve->KeyAdd(lTime); if (!flatInbetween) { - lCurve->KeySet(keySetIndex, lTime, sampleList->Curve[k].Value); + lCurve->KeySet(keySetIndex, lTime, Curve->value); } else { - float val = sampleList->Curve[k].Value; + float val = Curve->value; if (val >= flatMinStrength && val <= flatMaxStrength) { val = (val - flatMinStrength) * 100 / (flatMaxStrength - flatMinStrength); @@ -1118,14 +935,6 @@ namespace AssetStudio } } } - else - { - name = sampleList->Name; - if (!pNotFound->Contains(name)) - { - pNotFound->Add(name); - } - } } } } diff --git a/AssetStudioUtility/Imported.cs b/AssetStudioUtility/Imported.cs index 556262d..a56cbe3 100644 --- a/AssetStudioUtility/Imported.cs +++ b/AssetStudioUtility/Imported.cs @@ -12,7 +12,7 @@ namespace AssetStudio List MeshList { get; } List MaterialList { get; } List TextureList { get; } - List AnimationList { get; } + List AnimationList { get; } List MorphList { get; } } @@ -140,34 +140,25 @@ namespace AssetStudio } } - public abstract class ImportedAnimation + public class ImportedKeyframedAnimation { public string Name { get; set; } - } - public abstract class ImportedAnimationTrackContainer : ImportedAnimation where TrackType : ImportedAnimationTrack - { - public List TrackList { get; set; } + public List TrackList { get; set; } - public TrackType FindTrack(string name) + public ImportedAnimationKeyframedTrack FindTrack(string name) { return TrackList.Find(track => track.Name == name); } } - public class ImportedKeyframedAnimation : ImportedAnimationTrackContainer - { - - } - - public class ImportedSampledAnimation : ImportedAnimationTrackContainer - { - public float SampleRate { get; set; } - } - - public abstract class ImportedAnimationTrack + public class ImportedAnimationKeyframedTrack { public string Name { get; set; } + public List> Scalings = new List>(); + public List> Rotations = new List>(); + public List> Translations = new List>(); + public List> Curve = new List>(); } public class ImportedKeyframe @@ -182,21 +173,6 @@ namespace AssetStudio } } - public class ImportedAnimationKeyframedTrack : ImportedAnimationTrack - { - public List> Scalings = new List>(); - public List> Rotations = new List>(); - public List> Translations = new List>(); - } - - public class ImportedAnimationSampledTrack : ImportedAnimationTrack - { - public Vector3?[] Scalings; - public Vector3?[] Rotations; - public Vector3?[] Translations; - public float?[] Curve; - } - public class ImportedMorph { public string Name { get; set; }