Add AnimationClip loading via typetree

This commit is contained in:
VaDiM 2024-03-12 02:33:00 +03:00
parent 9b69b5607c
commit 4f0afffeba
5 changed files with 134 additions and 34 deletions

View File

@ -502,7 +502,9 @@ namespace AssetStudio
obj = new Animation(objectReader);
break;
case ClassIDType.AnimationClip:
obj = new AnimationClip(objectReader);
obj = objectReader.serializedType?.m_Type == null
? new AnimationClip(objectReader)
: new AnimationClip(objectReader, TypeTreeHelper.ReadType(objectReader.serializedType.m_Type, objectReader));
break;
case ClassIDType.Animator:
obj = new Animator(objectReader);

View File

@ -1,4 +1,6 @@
using System;
using Newtonsoft.Json;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@ -15,6 +17,8 @@ namespace AssetStudio
public T inWeight;
public T outWeight;
public Keyframe() { }
public Keyframe(ObjectReader reader, Func<T> readerFunc)
{
time = reader.ReadSingle();
@ -37,6 +41,8 @@ namespace AssetStudio
public int m_PostInfinity;
public int m_RotationOrder;
public AnimationCurve() { }
public AnimationCurve(ObjectReader reader, Func<T> readerFunc)
{
var version = reader.version;
@ -61,6 +67,8 @@ namespace AssetStudio
public AnimationCurve<Quaternion> curve;
public string path;
public QuaternionCurve() { }
public QuaternionCurve(ObjectReader reader)
{
curve = new AnimationCurve<Quaternion>(reader, reader.ReadQuaternion);
@ -76,6 +84,8 @@ namespace AssetStudio
public byte[] m_Data;
public byte m_BitSize;
public PackedFloatVector() { }
public PackedFloatVector(ObjectReader reader)
{
m_NumItems = reader.ReadUInt32();
@ -135,6 +145,8 @@ namespace AssetStudio
public byte[] m_Data;
public byte m_BitSize;
public PackedIntVector() { }
public PackedIntVector(ObjectReader reader)
{
m_NumItems = reader.ReadUInt32();
@ -179,6 +191,8 @@ namespace AssetStudio
public uint m_NumItems;
public byte[] m_Data;
public PackedQuatVector() { }
public PackedQuatVector(ObjectReader reader)
{
m_NumItems = reader.ReadUInt32();
@ -263,6 +277,8 @@ namespace AssetStudio
public int m_PreInfinity;
public int m_PostInfinity;
public CompressedAnimationCurve() { }
public CompressedAnimationCurve(ObjectReader reader)
{
m_Path = reader.ReadAlignedString();
@ -279,6 +295,8 @@ namespace AssetStudio
public AnimationCurve<Vector3> curve;
public string path;
public Vector3Curve() { }
public Vector3Curve(ObjectReader reader)
{
curve = new AnimationCurve<Vector3>(reader, reader.ReadVector3);
@ -295,6 +313,8 @@ namespace AssetStudio
public PPtr<MonoScript> script;
public int flags;
public FloatCurve() { }
public FloatCurve(ObjectReader reader)
{
var version = reader.version;
@ -315,6 +335,8 @@ namespace AssetStudio
public float time;
public PPtr<Object> value;
public PPtrKeyframe() { }
public PPtrKeyframe(ObjectReader reader)
{
time = reader.ReadSingle();
@ -331,6 +353,8 @@ namespace AssetStudio
public PPtr<MonoScript> script;
public int flags;
public PPtrCurve() { }
public PPtrCurve(ObjectReader reader)
{
var version = reader.version;
@ -357,6 +381,8 @@ namespace AssetStudio
public Vector3 m_Center;
public Vector3 m_Extent;
public AABB() { }
public AABB(ObjectReader reader)
{
m_Center = reader.ReadVector3();
@ -370,6 +396,8 @@ namespace AssetStudio
public Quaternion q;
public Vector3 s;
public xform() { }
public xform(ObjectReader reader)
{
var version = reader.version;
@ -388,6 +416,8 @@ namespace AssetStudio
public float m_InOut;
public float m_Grab;
public HandPose() { }
public HandPose(ObjectReader reader)
{
m_GrabX = new xform(reader);
@ -407,6 +437,8 @@ namespace AssetStudio
public Vector3 m_HintT;
public float m_HintWeightT;
public HumanGoal() { }
public HumanGoal(ObjectReader reader)
{
var version = reader.version;
@ -432,6 +464,8 @@ namespace AssetStudio
public float[] m_DoFArray;
public Vector3[] m_TDoFArray;
public HumanPose() { }
public HumanPose(ObjectReader reader)
{
var version = reader.version;
@ -468,6 +502,8 @@ namespace AssetStudio
public uint[] data;
public uint curveCount;
public StreamedClip() { }
public StreamedClip(ObjectReader reader)
{
data = reader.ReadUInt32Array();
@ -483,6 +519,8 @@ namespace AssetStudio
public float outSlope;
public float inSlope;
public StreamedCurveKey() { }
public StreamedCurveKey(BinaryReader reader)
{
index = reader.ReadInt32();
@ -514,6 +552,8 @@ namespace AssetStudio
public float time;
public StreamedCurveKey[] keyList;
public StreamedFrame() { }
public StreamedFrame(BinaryReader reader)
{
time = reader.ReadSingle();
@ -569,6 +609,8 @@ namespace AssetStudio
public float m_BeginTime;
public float[] m_SampleArray;
public DenseClip() { }
public DenseClip(ObjectReader reader)
{
m_FrameCount = reader.ReadInt32();
@ -583,6 +625,8 @@ namespace AssetStudio
{
public float[] data;
public ConstantClip() { }
public ConstantClip(ObjectReader reader)
{
data = reader.ReadSingleArray();
@ -596,6 +640,8 @@ namespace AssetStudio
public uint m_Type;
public uint m_Index;
public ValueConstant() { }
public ValueConstant(ObjectReader reader)
{
var version = reader.version;
@ -613,6 +659,8 @@ namespace AssetStudio
{
public ValueConstant[] m_ValueArray;
public ValueArrayConstant() { }
public ValueArrayConstant(ObjectReader reader)
{
int numVals = reader.ReadInt32();
@ -624,6 +672,18 @@ namespace AssetStudio
}
}
public class OffsetPtr
{
public Clip data;
public OffsetPtr() { }
public OffsetPtr(ObjectReader reader)
{
data = new Clip(reader);
}
}
public class Clip
{
public StreamedClip m_StreamedClip;
@ -631,6 +691,8 @@ namespace AssetStudio
public ConstantClip m_ConstantClip;
public ValueArrayConstant m_Binding;
public Clip() { }
public Clip(ObjectReader reader)
{
var version = reader.version;
@ -696,6 +758,8 @@ namespace AssetStudio
public float m_Start;
public float m_Stop;
public ValueDelta() { }
public ValueDelta(ObjectReader reader)
{
m_Start = reader.ReadSingle();
@ -713,7 +777,7 @@ namespace AssetStudio
public xform m_MotionStartX;
public xform m_MotionStopX;
public Vector3 m_AverageSpeed;
public Clip m_Clip;
public OffsetPtr m_Clip;
public float m_StartTime;
public float m_StopTime;
public float m_OrientationOffsetY;
@ -735,6 +799,8 @@ namespace AssetStudio
public bool m_KeepOriginalPositionXZ;
public bool m_HeightFromFeet;
public ClipMuscleConstant() { }
public ClipMuscleConstant(ObjectReader reader)
{
var version = reader.version;
@ -752,7 +818,7 @@ namespace AssetStudio
m_MotionStopX = new xform(reader);
}
m_AverageSpeed = version[0] > 5 || (version[0] == 5 && version[1] >= 4) ? reader.ReadVector3() : (Vector3)reader.ReadVector4();//5.4 and up
m_Clip = new Clip(reader);
m_Clip = new OffsetPtr(reader);
m_StartTime = reader.ReadSingle();
m_StopTime = reader.ReadSingle();
m_OrientationOffsetY = reader.ReadSingle();
@ -903,6 +969,8 @@ namespace AssetStudio
public int intParameter;
public int messageOptions;
public AnimationEvent() { }
public AnimationEvent(ObjectReader reader)
{
var version = reader.version;
@ -948,6 +1016,33 @@ namespace AssetStudio
public AnimationClipBindingConstant m_ClipBindingConstant;
public AnimationEvent[] m_Events;
public AnimationClip() { }
public AnimationClip(ObjectReader reader, IDictionary typeDict) : base(reader)
{
var parsedAnimClip = JsonConvert.DeserializeObject<AnimationClip>(JsonConvert.SerializeObject(typeDict));
m_AnimationType = parsedAnimClip.m_AnimationType;
m_Legacy = parsedAnimClip.m_Legacy;
m_Compressed = parsedAnimClip.m_Compressed;
m_UseHighQualityCurve = parsedAnimClip.m_UseHighQualityCurve;
m_RotationCurves = parsedAnimClip.m_RotationCurves;
m_CompressedRotationCurves = parsedAnimClip.m_CompressedRotationCurves;
m_EulerCurves = parsedAnimClip.m_EulerCurves;
m_PositionCurves = parsedAnimClip.m_PositionCurves;
m_ScaleCurves = parsedAnimClip.m_ScaleCurves;
m_FloatCurves = parsedAnimClip.m_FloatCurves;
m_PPtrCurves = parsedAnimClip.m_PPtrCurves;
m_SampleRate = parsedAnimClip.m_SampleRate;
m_WrapMode = parsedAnimClip.m_WrapMode;
m_Bounds = parsedAnimClip.m_Bounds;
m_MuscleClipSize = parsedAnimClip.m_MuscleClipSize;
m_MuscleClip = parsedAnimClip.m_MuscleClip;
m_ClipBindingConstant = parsedAnimClip.m_ClipBindingConstant;
m_Events = parsedAnimClip.m_Events;
typeDict.Clear();
}
public AnimationClip(ObjectReader reader) : base(reader)
{
if (version[0] >= 5)//5.0 and up

View File

@ -7,45 +7,47 @@ namespace AssetStudio
public int m_FileID;
public long m_PathID;
private SerializedFile assetsFile;
private int index = -2; //-2 - Prepare, -1 - Missing
private SerializedFile _assetsFile;
private int _index = -2; //-2 - Prepare, -1 - Missing
public PPtr(ObjectReader reader)
{
m_FileID = reader.ReadInt32();
m_PathID = reader.m_Version < SerializedFileFormatVersion.Unknown_14 ? reader.ReadInt32() : reader.ReadInt64();
assetsFile = reader.assetsFile;
_assetsFile = reader.assetsFile;
}
public PPtr() { }
private bool TryGetAssetsFile(out SerializedFile result)
{
result = null;
if (m_FileID == 0)
{
result = assetsFile;
result = _assetsFile;
return true;
}
if (m_FileID > 0 && m_FileID - 1 < assetsFile.m_Externals.Count)
if (m_FileID > 0 && m_FileID - 1 < _assetsFile.m_Externals.Count)
{
var assetsManager = assetsFile.assetsManager;
var assetsManager = _assetsFile.assetsManager;
var assetsFileList = assetsManager.assetsFileList;
var assetsFileIndexCache = assetsManager.assetsFileIndexCache;
if (index == -2)
if (_index == -2)
{
var m_External = assetsFile.m_Externals[m_FileID - 1];
var m_External = _assetsFile.m_Externals[m_FileID - 1];
var name = m_External.fileName;
if (!assetsFileIndexCache.TryGetValue(name, out index))
if (!assetsFileIndexCache.TryGetValue(name, out _index))
{
index = assetsFileList.FindIndex(x => x.fileName.Equals(name, StringComparison.OrdinalIgnoreCase));
assetsFileIndexCache.Add(name, index);
_index = assetsFileList.FindIndex(x => x.fileName.Equals(name, StringComparison.OrdinalIgnoreCase));
assetsFileIndexCache.Add(name, _index);
}
}
if (index >= 0)
if (_index >= 0)
{
result = assetsFileList[index];
result = assetsFileList[_index];
return true;
}
}
@ -53,8 +55,9 @@ namespace AssetStudio
return false;
}
public bool TryGet(out T result)
public bool TryGet(out T result, SerializedFile assetsFile = null)
{
_assetsFile = _assetsFile ?? assetsFile;
if (TryGetAssetsFile(out var sourceFile))
{
if (sourceFile.ObjectsDic.TryGetValue(m_PathID, out var obj))
@ -71,8 +74,9 @@ namespace AssetStudio
return false;
}
public bool TryGet<T2>(out T2 result) where T2 : Object
public bool TryGet<T2>(out T2 result, SerializedFile assetsFile = null) where T2 : Object
{
_assetsFile = _assetsFile ?? assetsFile;
if (TryGetAssetsFile(out var sourceFile))
{
if (sourceFile.ObjectsDic.TryGetValue(m_PathID, out var obj))
@ -92,20 +96,20 @@ namespace AssetStudio
public void Set(T m_Object)
{
var name = m_Object.assetsFile.fileName;
if (string.Equals(assetsFile.fileName, name, StringComparison.OrdinalIgnoreCase))
if (string.Equals(_assetsFile.fileName, name, StringComparison.OrdinalIgnoreCase))
{
m_FileID = 0;
}
else
{
m_FileID = assetsFile.m_Externals.FindIndex(x => string.Equals(x.fileName, name, StringComparison.OrdinalIgnoreCase));
m_FileID = _assetsFile.m_Externals.FindIndex(x => string.Equals(x.fileName, name, StringComparison.OrdinalIgnoreCase));
if (m_FileID == -1)
{
assetsFile.m_Externals.Add(new FileIdentifier
_assetsFile.m_Externals.Add(new FileIdentifier
{
fileName = m_Object.assetsFile.fileName
});
m_FileID = assetsFile.m_Externals.Count;
m_FileID = _assetsFile.m_Externals.Count;
}
else
{
@ -113,14 +117,14 @@ namespace AssetStudio
}
}
var assetsManager = assetsFile.assetsManager;
var assetsManager = _assetsFile.assetsManager;
var assetsFileList = assetsManager.assetsFileList;
var assetsFileIndexCache = assetsManager.assetsFileIndexCache;
if (!assetsFileIndexCache.TryGetValue(name, out index))
if (!assetsFileIndexCache.TryGetValue(name, out _index))
{
index = assetsFileList.FindIndex(x => x.fileName.Equals(name, StringComparison.OrdinalIgnoreCase));
assetsFileIndexCache.Add(name, index);
_index = assetsFileList.FindIndex(x => x.fileName.Equals(name, StringComparison.OrdinalIgnoreCase));
assetsFileIndexCache.Add(name, _index);
}
m_PathID = m_Object.m_PathID;

View File

@ -7,6 +7,7 @@ namespace CubismLive2DExtractor
{
class CubismMotion3Converter
{
private SerializedFile assetsFile;
private Dictionary<uint, string> bonePathHash = new Dictionary<uint, string>();
public List<ImportedKeyframedAnimation> AnimationList { get; protected set; } = new List<ImportedKeyframedAnimation>();
@ -29,11 +30,12 @@ namespace CubismLive2DExtractor
foreach (var animationClip in animationClips)
{
var iAnim = new ImportedKeyframedAnimation();
assetsFile = animationClip.assetsFile;
AnimationList.Add(iAnim);
iAnim.Name = animationClip.m_Name;
iAnim.SampleRate = animationClip.m_SampleRate;
iAnim.Duration = animationClip.m_MuscleClip.m_StopTime;
var m_Clip = animationClip.m_MuscleClip.m_Clip;
var m_Clip = animationClip.m_MuscleClip.m_Clip.data;
var streamedFrames = m_Clip.m_StreamedClip.ReadData();
var m_ClipBindingConstant = animationClip.m_ClipBindingConstant;
for (int frameIndex = 1; frameIndex < streamedFrames.Count - 1; frameIndex++)
@ -134,7 +136,7 @@ namespace CubismLive2DExtractor
target = "PartOpacity";
}
}
else if (binding.script.TryGet(out MonoScript script))
else if (binding.script.TryGet(out MonoScript script, assetsFile))
{
switch (script.m_ClassName)
{

View File

@ -873,7 +873,7 @@ namespace AssetStudio
}
else
{
var m_Clip = animationClip.m_MuscleClip.m_Clip;
var m_Clip = animationClip.m_MuscleClip.m_Clip.data;
var streamedFrames = m_Clip.m_StreamedClip.ReadData();
var m_ClipBindingConstant = animationClip.m_ClipBindingConstant ?? m_Clip.ConvertValueArrayToGenericBinding();
for (int frameIndex = 1; frameIndex < streamedFrames.Count - 1; frameIndex++)
@ -1096,10 +1096,7 @@ namespace AssetStudio
{
return name;
}
else
{
return null;
}
return null;
}
}
}