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

View File

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

View File

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

View File

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