This commit is contained in:
Razmoth
2023-01-06 22:33:59 +04:00
parent a3cf868dfb
commit 2b31232b30
178 changed files with 5213 additions and 23780 deletions

View File

@@ -19,17 +19,5 @@ namespace AssetStudio
m_Animations[i] = new PPtr<AnimationClip>(reader);
}
}
public bool IsContainsAnimationClip(AnimationClip clip)
{
foreach (PPtr<AnimationClip> ptr in m_Animations)
{
if (ptr.TryGet(out var animationClip) && animationClip.Equals(clip))
{
return true;
}
}
return false;
}
}
}

View File

@@ -1,12 +1,12 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace AssetStudio
{
public class Keyframe<T> : IYAMLExportable
where T : struct, IYAMLExportable
public class Keyframe<T>
{
public float time;
public T value;
@@ -15,7 +15,6 @@ namespace AssetStudio
public int weightedMode;
public T inWeight;
public T outWeight;
public int tangentMode;
public Keyframe(ObjectReader reader, Func<T> readerFunc)
@@ -31,46 +30,9 @@ namespace AssetStudio
outWeight = readerFunc();
}
}
public Keyframe(float time, T value, T weight) : this(time, value, default, default, weight)
{
tangentMode = 0;
}
public Keyframe(float time, T value, T inSlope, T outSlope, T weight)
{
this.time = time;
this.value = value;
this.inSlope = inSlope;
this.outSlope = outSlope;
weightedMode = 0;
inWeight = weight;
outWeight = weight;
tangentMode = 1;
}
public YAMLNode ExportYAML()
{
var node = new YAMLMappingNode();
node.AddSerializedVersion(2);
node.Add(nameof(time), time);
node.Add(nameof(value), value.ExportYAML());
node.Add(nameof(inSlope), inSlope.ExportYAML());
node.Add(nameof(outSlope), outSlope.ExportYAML());
node.Add(nameof(tangentMode), tangentMode);
node.Add(nameof(weightedMode), weightedMode);
node.Add(nameof(inWeight), inWeight.ExportYAML());
node.Add(nameof(outWeight), outWeight.ExportYAML());
return node;
}
public static Float DefaultFloatWeight => 1.0f / 3.0f;
public static Vector3 DefaultVector3Weight => new Vector3(1.0f / 3.0f, 1.0f / 3.0f, 1.0f / 3.0f);
public static Quaternion DefaultQuaternionWeight => new Quaternion(1.0f / 3.0f, 1.0f / 3.0f, 1.0f / 3.0f, 1.0f / 3.0f);
}
public class AnimationCurve<T> : IYAMLExportable
where T : struct, IYAMLExportable
public class AnimationCurve<T>
{
public Keyframe<T>[] m_Curve;
public int m_PreInfinity;
@@ -94,40 +56,9 @@ namespace AssetStudio
m_RotationOrder = reader.ReadInt32();
}
}
public AnimationCurve()
{
m_PreInfinity = 2;
m_PostInfinity = 2;
m_RotationOrder = 4;
m_Curve = Array.Empty<Keyframe<T>>();
}
public AnimationCurve(List<Keyframe<T>> keyframes)
{
m_PreInfinity = 2;
m_PostInfinity = 2;
m_RotationOrder = 4;
m_Curve = new Keyframe<T>[keyframes.Count];
for (int i = 0; i < keyframes.Count; i++)
{
m_Curve[i] = keyframes[i];
}
}
public YAMLNode ExportYAML()
{
var node = new YAMLMappingNode();
node.AddSerializedVersion(2);
node.Add(nameof(m_Curve), m_Curve.ExportYAML());
node.Add(nameof(m_PreInfinity), m_PreInfinity);
node.Add(nameof(m_PostInfinity), m_PostInfinity);
node.Add(nameof(m_RotationOrder), m_RotationOrder);
return node;
}
}
public class QuaternionCurve : IYAMLExportable
public class QuaternionCurve
{
public AnimationCurve<Quaternion> curve;
public string path;
@@ -137,79 +68,9 @@ namespace AssetStudio
curve = new AnimationCurve<Quaternion>(reader, reader.ReadQuaternion);
path = reader.ReadAlignedString();
}
public QuaternionCurve(string path)
{
curve = new AnimationCurve<Quaternion>();
this.path = path;
}
public QuaternionCurve(QuaternionCurve copy, List<Keyframe<Quaternion>> keyframes) : this(copy.path, keyframes) { }
public QuaternionCurve(string path, List<Keyframe<Quaternion>> keyframes)
{
curve = new AnimationCurve<Quaternion>(keyframes);
this.path = path;
}
public YAMLNode ExportYAML()
{
YAMLMappingNode node = new YAMLMappingNode();
node.Add(nameof(curve), curve.ExportYAML());
node.Add(nameof(path), path);
return node;
}
public override bool Equals(object obj)
{
if (obj is QuaternionCurve quaternionCurve)
{
return path == quaternionCurve.path;
}
return false;
}
public override int GetHashCode()
{
int hash = 199;
unchecked
{
hash = 617 + hash * path.GetHashCode();
}
return hash;
}
}
public class ACLClip
{
public byte[] m_ClipData;
public uint[] m_ClipDataUint;
public uint m_CurveCount;
public uint m_ConstCurveCount;
public ACLClip(ObjectReader reader)
{
if (reader.Game.Name == "SR_CB2" || reader.Game.Name == "SR_CB3")
{
m_ClipDataUint = reader.ReadUInt32Array();
}
else
{
m_ClipData = reader.ReadUInt8Array();
reader.AlignStream();
}
m_CurveCount = reader.ReadUInt32();
if (reader.Game.Name == "SR_CB2" || reader.Game.Name == "SR_CB3")
{
m_ConstCurveCount = reader.ReadUInt32();
}
}
public bool IsSet => m_ClipDataUint != null && m_ClipDataUint.Length > 0 || m_ClipData != null && m_ClipData.Length > 0;
}
public class PackedFloatVector : IYAMLExportable
public class PackedFloatVector
{
public uint m_NumItems;
public float m_Range;
@@ -231,17 +92,6 @@ namespace AssetStudio
reader.AlignStream();
}
public YAMLNode ExportYAML()
{
var node = new YAMLMappingNode();
node.Add(nameof(m_NumItems), m_NumItems);
node.Add(nameof(m_Range), m_Range);
node.Add(nameof(m_Start), m_Start);
node.Add(nameof(m_Data), m_Data.ExportYAML());
node.Add(nameof(m_BitSize), m_BitSize);
return node;
}
public float[] UnpackFloats(int itemCountInChunk, int chunkStride, int start = 0, int numChunks = -1)
{
int bitPos = m_BitSize * start;
@@ -281,7 +131,7 @@ namespace AssetStudio
}
}
public class PackedIntVector : IYAMLExportable
public class PackedIntVector
{
public uint m_NumItems;
public byte[] m_Data;
@@ -299,15 +149,6 @@ namespace AssetStudio
reader.AlignStream();
}
public YAMLNode ExportYAML()
{
var node = new YAMLMappingNode();
node.Add(nameof(m_NumItems), m_NumItems);
node.Add(nameof(m_Data), m_Data.ExportYAML());
node.Add(nameof(m_BitSize), m_BitSize);
return node;
}
public int[] UnpackInts()
{
var data = new int[m_NumItems];
@@ -335,7 +176,7 @@ namespace AssetStudio
}
}
public class PackedQuatVector : IYAMLExportable
public class PackedQuatVector
{
public uint m_NumItems;
public byte[] m_Data;
@@ -350,14 +191,6 @@ namespace AssetStudio
reader.AlignStream();
}
public YAMLNode ExportYAML()
{
var node = new YAMLMappingNode();
node.Add(nameof(m_NumItems), m_NumItems);
node.Add(nameof(m_Data), m_Data.ExportYAML());
return node;
}
public Quaternion[] UnpackQuats()
{
var data = new Quaternion[m_NumItems];
@@ -423,7 +256,7 @@ namespace AssetStudio
}
}
public class CompressedAnimationCurve : IYAMLExportable
public class CompressedAnimationCurve
{
public string m_Path;
public PackedIntVector m_Times;
@@ -441,21 +274,9 @@ namespace AssetStudio
m_PreInfinity = reader.ReadInt32();
m_PostInfinity = reader.ReadInt32();
}
public YAMLNode ExportYAML()
{
var node = new YAMLMappingNode();
node.Add(nameof(m_Path), m_Path);
node.Add(nameof(m_Times), m_Times.ExportYAML());
node.Add(nameof(m_Values), m_Values.ExportYAML());
node.Add(nameof(m_Slopes), m_Slopes.ExportYAML());
node.Add(nameof(m_PreInfinity), m_PreInfinity);
node.Add(nameof(m_PostInfinity), m_PostInfinity);
return node;
}
}
public class Vector3Curve : IYAMLExportable
public class Vector3Curve
{
public AnimationCurve<Vector3> curve;
public string path;
@@ -465,51 +286,11 @@ namespace AssetStudio
curve = new AnimationCurve<Vector3>(reader, reader.ReadVector3);
path = reader.ReadAlignedString();
}
public Vector3Curve(Vector3Curve copy, List<Keyframe<Vector3>> keyframes)
: this(copy.path, keyframes) { }
public Vector3Curve(string path)
{
curve = new AnimationCurve<Vector3>();
this.path = path;
}
public Vector3Curve(string path, List<Keyframe<Vector3>> keyframes)
{
curve = new AnimationCurve<Vector3>(keyframes);
this.path = path;
}
public YAMLNode ExportYAML()
{
YAMLMappingNode node = new YAMLMappingNode();
node.Add(nameof(curve), curve.ExportYAML());
node.Add(nameof(path), path);
return node;
}
public override bool Equals(object obj)
{
if (obj is Vector3Curve vector3Curve)
{
return path == vector3Curve.path;
}
return false;
}
public override int GetHashCode()
{
int hash = 577;
unchecked
{
hash = 419 + hash * path.GetHashCode();
}
return hash;
}
}
public class FloatCurve : IYAMLExportable
public class FloatCurve
{
public AnimationCurve<Float> curve;
public AnimationCurve<float> curve;
public string attribute;
public string path;
public ClassIDType classID;
@@ -518,64 +299,15 @@ namespace AssetStudio
public FloatCurve(ObjectReader reader)
{
curve = new AnimationCurve<Float>(reader, reader.ReadFloat);
curve = new AnimationCurve<float>(reader, reader.ReadSingle);
attribute = reader.ReadAlignedString();
path = reader.ReadAlignedString();
classID = (ClassIDType)reader.ReadInt32();
script = new PPtr<MonoScript>(reader);
}
public FloatCurve(FloatCurve copy, List<Keyframe<Float>> keyframes) : this(copy.path, copy.attribute, copy.classID, copy.script, keyframes) { }
public FloatCurve(string path, string attribute, ClassIDType classID, PPtr<MonoScript> script)
{
curve = new AnimationCurve<Float>();
this.attribute = attribute;
this.path = path;
this.classID = classID;
this.script = script;
}
public FloatCurve(string path, string attribute, ClassIDType classID, PPtr<MonoScript> script, List<Keyframe<Float>> keyframes)
: this(path, attribute, classID, script)
{
curve = new AnimationCurve<Float>(keyframes);
this.attribute = attribute;
this.path = path;
this.classID = classID;
this.script = script;
}
public YAMLNode ExportYAML()
{
YAMLMappingNode node = new YAMLMappingNode();
node.Add(nameof(curve), curve.ExportYAML());
node.Add(nameof(attribute), attribute);
node.Add(nameof(path), path);
node.Add(nameof(classID), (int)classID);
node.Add(nameof(script), script.ExportYAML());
return node;
}
public override bool Equals(object obj)
{
if (obj is FloatCurve floatCurve)
{
return attribute == floatCurve.attribute && path == floatCurve.path && classID == floatCurve.classID;
}
return false;
}
public override int GetHashCode()
{
int hash = 17;
unchecked
{
hash = hash * 23 + path.GetHashCode();
}
return hash;
}
}
public class PPtrKeyframe : IYAMLExportable
public class PPtrKeyframe
{
public float time;
public PPtr<Object> value;
@@ -586,27 +318,14 @@ namespace AssetStudio
time = reader.ReadSingle();
value = new PPtr<Object>(reader);
}
public PPtrKeyframe(float time, PPtr<Object> script)
{
this.time = time;
value = script;
}
public YAMLNode ExportYAML()
{
var node = new YAMLMappingNode();
node.Add(nameof(time), time);
node.Add(nameof(value), value.ExportYAML());
return node;
}
}
public class PPtrCurve : IYAMLExportable
public class PPtrCurve
{
public PPtrKeyframe[] curve;
public string attribute;
public string path;
public ClassIDType classID;
public int classID;
public PPtr<MonoScript> script;
@@ -621,63 +340,12 @@ namespace AssetStudio
attribute = reader.ReadAlignedString();
path = reader.ReadAlignedString();
classID = (ClassIDType)reader.ReadInt32();
classID = reader.ReadInt32();
script = new PPtr<MonoScript>(reader);
}
public PPtrCurve(PPtrCurve copy, List<PPtrKeyframe> keyframes) : this(copy.path, copy.attribute, copy.classID, copy.script, keyframes) { }
public PPtrCurve(string path, string attribute, ClassIDType classID, PPtr<MonoScript> script)
{
this.attribute = attribute;
this.path = path;
this.classID = classID;
this.script = script;
}
public PPtrCurve(string path, string attribute, ClassIDType classID, PPtr<MonoScript> script, IReadOnlyList<PPtrKeyframe> keyframes) :
this(path, attribute, classID, script)
{
curve = new PPtrKeyframe[keyframes.Count];
for (int i = 0; i < keyframes.Count; i++)
{
curve[i] = keyframes[i];
}
}
public YAMLNode ExportYAML()
{
YAMLMappingNode node = new YAMLMappingNode();
node.Add(nameof(curve), curve.ExportYAML());
node.Add(nameof(attribute), attribute);
node.Add(nameof(path), path);
node.Add(nameof(classID), ((int)classID).ToString());
node.Add(nameof(script), script.ExportYAML());
return node;
}
public override bool Equals(object obj)
{
if (obj is PPtrCurve pptrCurve)
{
return this == pptrCurve;
}
return false;
}
public override int GetHashCode()
{
int hash = 113;
unchecked
{
hash = hash + 457 * attribute.GetHashCode();
hash = hash * 433 + path.GetHashCode();
hash = hash * 223 + classID.GetHashCode();
hash = hash * 911 + script.GetHashCode();
}
return hash;
}
}
public class AABB : IYAMLExportable
public class AABB
{
public Vector3 m_Center;
public Vector3 m_Extent;
@@ -687,14 +355,6 @@ namespace AssetStudio
m_Center = reader.ReadVector3();
m_Extent = reader.ReadVector3();
}
public YAMLNode ExportYAML()
{
var node = new YAMLMappingNode();
node.Add(nameof(m_Center), m_Center.ExportYAML());
node.Add(nameof(m_Extent), m_Extent.ExportYAML());
return node;
}
}
public class xform
@@ -796,6 +456,33 @@ namespace AssetStudio
}
}
public class ACLClip
{
public byte[] m_ClipData;
public uint m_CurveCount;
public uint m_ConstCurveCount;
public ACLClip(ObjectReader reader)
{
var byteCount = reader.ReadInt32();
if (reader.Game.Type.IsSRGroup())
{
byteCount *= 4;
}
m_ClipData = reader.ReadBytes(byteCount);
reader.AlignStream();
m_CurveCount = reader.ReadUInt32();
if (reader.Game.Type.IsSRGroup())
{
m_ConstCurveCount = reader.ReadUInt32();
}
}
}
public class StreamedClip
{
public uint[] data;
@@ -816,7 +503,7 @@ namespace AssetStudio
public float outSlope;
public float inSlope;
public StreamedCurveKey(BinaryReader reader)
public StreamedCurveKey(EndianBinaryReader reader)
{
index = reader.ReadInt32();
coeff = reader.ReadSingleArray(4);
@@ -847,7 +534,7 @@ namespace AssetStudio
public float time;
public StreamedCurveKey[] keyList;
public StreamedFrame(BinaryReader reader)
public StreamedFrame(EndianBinaryReader reader)
{
time = reader.ReadSingle();
@@ -865,7 +552,7 @@ namespace AssetStudio
var frameList = new List<StreamedFrame>();
var buffer = new byte[data.Length * 4];
Buffer.BlockCopy(data, 0, buffer, 0, buffer.Length);
using (var reader = new BinaryReader(new MemoryStream(buffer)))
using (var reader = new EndianBinaryReader(new MemoryStream(buffer), EndianType.LittleEndian))
{
while (reader.BaseStream.Position < reader.BaseStream.Length)
{
@@ -959,10 +646,10 @@ namespace AssetStudio
public class Clip
{
public ACLClip m_ACLClip;
public StreamedClip m_StreamedClip;
public DenseClip m_DenseClip;
public ConstantClip m_ConstantClip;
public ACLClip m_ACLClip;
public ValueArrayConstant m_Binding;
public Clip(ObjectReader reader)
@@ -970,7 +657,7 @@ namespace AssetStudio
var version = reader.version;
m_StreamedClip = new StreamedClip(reader);
m_DenseClip = new DenseClip(reader);
if (reader.Game.Name == "SR_CB2" || reader.Game.Name == "SR_CB3")
if (reader.Game.Type.IsSRGroup())
{
m_ACLClip = new ACLClip(reader);
}
@@ -978,7 +665,7 @@ namespace AssetStudio
{
m_ConstantClip = new ConstantClip(reader);
}
if (reader.Game.Name != "SR_CB2" && reader.Game.Name != "SR_CB3" && reader.Game.Name != "TOT")
if (reader.Game.Type.IsGIGroup() || reader.Game.Type.IsBH3() || reader.Game.Type.IsZZZCB1())
{
m_ACLClip = new ACLClip(reader);
}
@@ -1045,7 +732,7 @@ namespace AssetStudio
}
}
public class ClipMuscleConstant : IYAMLExportable
public class ClipMuscleConstant
{
public HumanPose m_DeltaPose;
public xform m_StartX;
@@ -1137,45 +824,23 @@ namespace AssetStudio
m_HeightFromFeet = reader.ReadBoolean();
reader.AlignStream();
}
public YAMLNode ExportYAML()
{
var node = new YAMLMappingNode();
node.AddSerializedVersion(2);
node.Add(nameof(m_StartTime), m_StartTime);
node.Add(nameof(m_StopTime), m_StopTime);
node.Add(nameof(m_OrientationOffsetY), m_OrientationOffsetY);
node.Add(nameof(m_Level), m_Level);
node.Add(nameof(m_CycleOffset), m_CycleOffset);
node.Add(nameof(m_LoopTime), m_LoopTime);
node.Add(nameof(m_LoopBlend), m_LoopBlend);
node.Add(nameof(m_LoopBlendOrientation), m_LoopBlendOrientation);
node.Add(nameof(m_LoopBlendPositionY), m_LoopBlendPositionY);
node.Add(nameof(m_LoopBlendPositionXZ), m_LoopBlendPositionXZ);
node.Add(nameof(m_KeepOriginalOrientation), m_KeepOriginalOrientation);
node.Add(nameof(m_KeepOriginalPositionY), m_KeepOriginalPositionY);
node.Add(nameof(m_KeepOriginalPositionXZ), m_KeepOriginalPositionXZ);
node.Add(nameof(m_HeightFromFeet), m_HeightFromFeet);
node.Add(nameof(m_Mirror), m_Mirror);
return node;
}
}
public class GenericBinding : IYAMLExportable
public class GenericBinding
{
public int[] version;
public uint path;
public uint attribute;
public PPtr<Object> script;
public ClassIDType typeID;
public byte customType;
public byte isPPtrCurve;
public byte isIntCurve;
public GenericBinding() { }
public GenericBinding(ObjectReader reader)
{
version = reader.version;
var version = reader.version;
path = reader.ReadUInt32();
attribute = reader.ReadUInt32();
script = new PPtr<Object>(reader);
@@ -1189,24 +854,15 @@ namespace AssetStudio
}
customType = reader.ReadByte();
isPPtrCurve = reader.ReadByte();
if (version[0] > 2022 || (version[0] == 2022 && version[1] >= 1)) //2022.1 and up
{
isIntCurve = reader.ReadByte();
}
reader.AlignStream();
}
public YAMLNode ExportYAML()
{
var node = new YAMLMappingNode();
node.Add(nameof(path), path);
node.Add(nameof(attribute), attribute);
node.Add(nameof(script), script.ExportYAML());
node.Add("classID", ((int)typeID).ToString());
node.Add(nameof(customType), ((int)customType).ToString());
node.Add(nameof(isPPtrCurve), isPPtrCurve);
return node;
}
public int GetDimension() => attribute == 2 ? 4 : 3;
}
public class AnimationClipBindingConstant : IYAMLExportable
public class AnimationClipBindingConstant
{
public GenericBinding[] genericBindings;
public PPtr<Object>[] pptrCurveMapping;
@@ -1230,14 +886,6 @@ namespace AssetStudio
}
}
public YAMLNode ExportYAML()
{
var node = new YAMLMappingNode();
node.Add(nameof(genericBindings), genericBindings.ExportYAML());
node.Add(nameof(pptrCurveMapping), pptrCurveMapping.ExportYAML());
return node;
}
public GenericBinding FindBinding(int index)
{
int curves = 0;
@@ -1274,7 +922,7 @@ namespace AssetStudio
}
}
public class AnimationEvent : IYAMLExportable
public class AnimationEvent
{
public float time;
public string functionName;
@@ -1299,19 +947,6 @@ namespace AssetStudio
}
messageOptions = reader.ReadInt32();
}
public YAMLNode ExportYAML()
{
var node = new YAMLMappingNode();
node.Add(nameof(time), time);
node.Add(nameof(functionName), functionName);
node.Add(nameof(data), data);
node.Add(nameof(objectReferenceParameter), objectReferenceParameter.ExportYAML());
node.Add(nameof(floatParameter), floatParameter);
node.Add(nameof(intParameter), intParameter);
node.Add(nameof(messageOptions), messageOptions);
return node;
}
}
public enum AnimationType
@@ -1321,7 +956,7 @@ namespace AssetStudio
Humanoid = 3
};
public sealed class AnimationClip : NamedObject, IYAMLExportable
public sealed class AnimationClip : NamedObject
{
public AnimationType m_AnimationType;
public bool m_Legacy;
@@ -1339,9 +974,6 @@ namespace AssetStudio
public AABB m_Bounds;
public uint m_MuscleClipSize;
public ClipMuscleConstant m_MuscleClip;
public byte[] m_AclClipData;
public GenericBinding[] m_AclBindings;
public KeyValuePair<float, float> m_AclRange;
public AnimationClipBindingConstant m_ClipBindingConstant;
public AnimationEvent[] m_Events;
@@ -1363,10 +995,6 @@ namespace AssetStudio
m_Legacy = true;
}
m_Compressed = reader.ReadBoolean();
if (m_Compressed && reader.Game.Name != "ToT")
{
m_Compressed = false;
}
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3))//4.3 and up
{
m_UseHighQualityCurve = reader.ReadBoolean();
@@ -1438,19 +1066,19 @@ namespace AssetStudio
m_MuscleClipSize = reader.ReadUInt32();
m_MuscleClip = new ClipMuscleConstant(reader);
}
if (reader.Game.Type.IsSRGroup())
{
var m_AclClipData = reader.ReadUInt8Array();
var aclBindingsCount = reader.ReadInt32();
var m_AclBindings = new GenericBinding[aclBindingsCount];
for (int i = 0; i < aclBindingsCount; i++)
{
m_AclBindings[i] = new GenericBinding(reader);
}
var m_AclRange = new KeyValuePair<float, float>(reader.ReadSingle(), reader.ReadSingle());
}
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
{
if (reader.Game.Name == "SR_CB2" || reader.Game.Name == "SR_CB3")
{
m_AclClipData = reader.ReadUInt8Array();
var aclBindingsCount = reader.ReadInt32();
m_AclBindings = new GenericBinding[aclBindingsCount];
for (int i = 0; i < aclBindingsCount; i++)
{
m_AclBindings[i] = new GenericBinding(reader);
}
m_AclRange = new KeyValuePair<float, float>(reader.ReadSingle(), reader.ReadSingle());
}
m_ClipBindingConstant = new AnimationClipBindingConstant(reader);
}
if (version[0] > 2018 || (version[0] == 2018 && version[1] >= 3)) //2018.3 and up
@@ -1470,158 +1098,5 @@ namespace AssetStudio
reader.AlignStream();
}
}
public YAMLNode ExportYAML()
{
var node = new YAMLMappingNode();
node.Add(nameof(m_Name), m_Name);
node.AddSerializedVersion(6);
node.Add(nameof(m_Legacy), m_Legacy);
node.Add(nameof(m_Compressed), m_Compressed);
node.Add(nameof(m_UseHighQualityCurve), m_UseHighQualityCurve);
node.Add(nameof(m_RotationCurves), m_RotationCurves.ExportYAML());
node.Add(nameof(m_CompressedRotationCurves), m_CompressedRotationCurves.ExportYAML());
node.Add(nameof(m_EulerCurves), m_EulerCurves.ExportYAML());
node.Add(nameof(m_PositionCurves), m_PositionCurves.ExportYAML());
node.Add(nameof(m_ScaleCurves), m_ScaleCurves.ExportYAML());
node.Add(nameof(m_FloatCurves), m_FloatCurves.ExportYAML());
node.Add(nameof(m_PPtrCurves), m_PPtrCurves.ExportYAML());
node.Add(nameof(m_SampleRate), m_SampleRate);
node.Add(nameof(m_WrapMode), m_WrapMode);
node.Add(nameof(m_Bounds), m_Bounds.ExportYAML());
node.Add(nameof(m_ClipBindingConstant), m_ClipBindingConstant.ExportYAML());
node.Add("m_AnimationClipSettings", m_MuscleClip.ExportYAML());
node.Add(nameof(m_Events), m_Events.ExportYAML());
return node;
}
public Dictionary<uint, string> FindTOS()
{
var tos = new Dictionary<uint, string>() { { 0, string.Empty } };
foreach (var asset in assetsFile.assetsManager.assetsFileList.SelectMany(x => x.Objects).OrderBy(x => x.type).ToArray())
{
switch (asset.type)
{
case ClassIDType.Avatar:
var avatar = asset as Avatar;
if (AddAvatarTOS(avatar, tos))
{
return tos;
}
break;
case ClassIDType.Animator:
var animator = asset as Animator;
if (IsAnimatorContainsClip(animator))
{
if (AddAnimatorTOS(animator, tos))
{
return tos;
}
}
break;
case ClassIDType.Animation:
var animation = asset as Animation;
if (IsAnimationContainsClip(animation))
{
if (AddAnimationTOS(animation, tos))
{
return tos;
}
}
break;
}
}
return tos;
}
public IEnumerable<GameObject> FindRoots()
{
foreach (var asset in assetsFile.assetsManager.assetsFileList.SelectMany(x => x.Objects))
{
switch (asset.type)
{
case ClassIDType.Animator:
Animator animator = (Animator)asset;
if (IsAnimatorContainsClip(animator))
{
if (animator.m_GameObject.TryGet(out var go))
{
yield return go;
}
}
break;
case ClassIDType.Animation:
Animation animation = (Animation)asset;
if (IsAnimationContainsClip(animation))
{
if (animation.m_GameObject.TryGet(out var go))
{
yield return go;
}
}
break;
}
}
yield break;
}
private bool IsAnimatorContainsClip(Animator animator)
{
if (animator.m_Controller.TryGet(out var runtime))
{
return runtime.IsContainsAnimationClip(this);
}
else
{
return false;
}
}
private bool IsAnimationContainsClip(Animation animation)
{
return animation.IsContainsAnimationClip(this);
}
private bool AddAvatarTOS(Avatar avatar, Dictionary<uint, string> tos)
{
return AddTOS(avatar.m_TOS.ToDictionary(x => x.Key, x => x.Value), tos);
}
private bool AddAnimatorTOS(Animator animator, Dictionary<uint, string> tos)
{
if (animator.m_Avatar.TryGet(out var avatar))
{
if (AddAvatarTOS(avatar, tos))
{
return true;
}
}
Dictionary<uint, string> animatorTOS = animator.BuildTOS();
return AddTOS(animatorTOS, tos);
}
private bool AddAnimationTOS(Animation animation, Dictionary<uint, string> tos)
{
if (animation.m_GameObject.TryGet(out var go))
{
Dictionary<uint, string> animationTOS = go.BuildTOS();
return AddTOS(animationTOS, tos);
}
return false;
}
private bool AddTOS(Dictionary<uint, string> src, Dictionary<uint, string> dest)
{
int tosCount = m_ClipBindingConstant.genericBindings.Length;
for (int i = 0; i < tosCount; i++)
{
ref GenericBinding binding = ref m_ClipBindingConstant.genericBindings[i];
if (src.TryGetValue(binding.path, out string path))
{
dest[binding.path] = path;
if (dest.Count == tosCount)
{
return true;
}
}
}
return false;
}
}
}

View File

@@ -15,7 +15,7 @@ namespace AssetStudio
{
m_Avatar = new PPtr<Avatar>(reader);
m_Controller = new PPtr<RuntimeAnimatorController>(reader);
if (reader.Game.Name == "GI" || reader.Game.Name == "GI_CB2" || reader.Game.Name == "GI_CB3")
if (reader.Game.Type.IsGISubGroup())
{
var m_FBIKAvatar = new PPtr<Object>(reader); //FBIKAvatar placeholder
}
@@ -67,31 +67,5 @@ namespace AssetStudio
reader.AlignStream();
}
}
public Dictionary<uint, string> BuildTOS()
{
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3))
{
if (m_HasTransformHierarchy)
{
if (m_GameObject.TryGet(out var go))
{
return go.BuildTOS();
}
}
else
{
return new Dictionary<uint, string>() { { 0, string.Empty } };
}
}
else
{
if (m_GameObject.TryGet(out var go))
{
return go.BuildTOS();
}
}
return null;
}
}
}

View File

@@ -580,6 +580,7 @@ namespace AssetStudio
public sealed class AnimatorController : RuntimeAnimatorController
{
public Dictionary<uint, string> m_TOS;
public PPtr<AnimationClip>[] m_AnimationClips;
public AnimatorController(ObjectReader reader) : base(reader)
@@ -588,7 +589,7 @@ namespace AssetStudio
var m_Controller = new ControllerConstant(reader);
int tosSize = reader.ReadInt32();
var m_TOS = new Dictionary<uint, string>(tosSize);
m_TOS = new Dictionary<uint, string>(tosSize);
for (int i = 0; i < tosSize; i++)
{
m_TOS.Add(reader.ReadUInt32(), reader.ReadAlignedString());
@@ -601,17 +602,5 @@ namespace AssetStudio
m_AnimationClips[i] = new PPtr<AnimationClip>(reader);
}
}
public override bool IsContainsAnimationClip(AnimationClip clip)
{
foreach (PPtr<AnimationClip> ptr in m_AnimationClips)
{
if (ptr.TryGet(out var animationClip) && animationClip.Equals(clip))
{
return true;
}
}
return false;
}
}
}

View File

@@ -33,26 +33,5 @@ namespace AssetStudio
m_Clips[i] = new AnimationClipOverride(reader);
}
}
public override bool IsContainsAnimationClip(AnimationClip clip)
{
AnimationClip animationClip;
foreach (AnimationClipOverride overClip in m_Clips)
{
if (overClip.m_OriginalClip.TryGet(out animationClip) && animationClip.Equals(clip))
{
return true;
}
else if (overClip.m_OverrideClip.TryGet(out animationClip) && animationClip.Equals(clip))
{
return true;
}
}
if (m_Controller.TryGet(out var baseController))
{
return baseController.IsContainsAnimationClip(clip);
}
return false;
}
}
}

View File

@@ -1,5 +1,8 @@
using Newtonsoft.Json;
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace AssetStudio
{
@@ -19,76 +22,64 @@ namespace AssetStudio
public sealed class AssetBundle : NamedObject
{
public static bool Exportable;
public PPtr<Object>[] PreloadTable;
public KeyValuePair<string, AssetInfo>[] Container;
public AssetInfo MainAsset;
public uint RuntimeComaptability;
public string AssetBundleName;
public int DependencyCount;
public string[] Dependencies;
public bool IsStreamedScenessetBundle;
public int ExplicitDataLayout;
public int PathFlags;
public int SceneHashCount;
public KeyValuePair<string, string>[] SceneHashes;
public PPtr<Object>[] m_PreloadTable;
public KeyValuePair<string, AssetInfo>[] m_Container;
//public AssetInfo m_MainAsset;
//public uint m_RuntimeComaptability;
//public string m_AssetBundleName;
//public string[] m_Dependencies;
//public bool m_IsStreamedSceneAssetBundle;
//public int m_ExplicitDataLayout;
//public int m_PathFlags;
//public KeyValuePair<string, string>[] m_SceneHashes;
public AssetBundle(ObjectReader reader) : base(reader)
{
var m_PreloadTableSize = reader.ReadInt32();
PreloadTable = new PPtr<Object>[m_PreloadTableSize];
m_PreloadTable = new PPtr<Object>[m_PreloadTableSize];
for (int i = 0; i < m_PreloadTableSize; i++)
{
PreloadTable[i] = new PPtr<Object>(reader);
m_PreloadTable[i] = new PPtr<Object>(reader);
}
var m_ContainerSize = reader.ReadInt32();
Container = new KeyValuePair<string, AssetInfo>[m_ContainerSize];
m_Container = new KeyValuePair<string, AssetInfo>[m_ContainerSize];
for (int i = 0; i < m_ContainerSize; i++)
{
Container[i] = new KeyValuePair<string, AssetInfo>(reader.ReadAlignedString(), new AssetInfo(reader));
m_Container[i] = new KeyValuePair<string, AssetInfo>(reader.ReadAlignedString(), new AssetInfo(reader));
}
if (reader.Game.Name == "GI" || reader.Game.Name == "GI_CB1" || reader.Game.Name == "GI_CB2" || reader.Game.Name == "GI_CB3")
{
MainAsset = new AssetInfo(reader);
RuntimeComaptability = reader.ReadUInt32();
}
AssetBundleName = reader.ReadAlignedString();
DependencyCount = reader.ReadInt32();
Dependencies = new string[DependencyCount];
for (int k = 0; k < DependencyCount; k++)
{
Dependencies[k] = reader.ReadAlignedString();
}
if (reader.Game.Name == "GI_CB1" || reader.Game.Name == "GI_CB2")
{
IsStreamedScenessetBundle = reader.ReadBoolean();
reader.AlignStream();
PathFlags = reader.ReadInt32();
}
else if (reader.Game.Name == "GI_CB3")
{
IsStreamedScenessetBundle = reader.ReadBoolean();
reader.AlignStream();
ExplicitDataLayout = reader.ReadInt32();
PathFlags = reader.ReadInt32();
}
else if (reader.Game.Name == "GI")
{
IsStreamedScenessetBundle = reader.ReadBoolean();
reader.AlignStream();
ExplicitDataLayout = reader.ReadInt32();
PathFlags = reader.ReadInt32();
SceneHashCount = reader.ReadInt32();
SceneHashes = new KeyValuePair<string, string>[SceneHashCount];
for (int l = 0; l < SceneHashCount; l++)
{
SceneHashes[l] = new KeyValuePair<string, string>(reader.ReadAlignedString(), reader.ReadAlignedString());
}
}
//if (reader.Game.Type.IsMhyGroup())
//{
// m_MainAsset = new AssetInfo(reader);
// m_RuntimeComaptability = reader.ReadUInt32();
// m_AssetBundleName = reader.ReadAlignedString();
// var dependencyCount = reader.ReadInt32();
// m_Dependencies = new string[dependencyCount];
// for (int k = 0; k < dependencyCount; k++)
// {
// m_Dependencies[k] = reader.ReadAlignedString();
// }
// if (reader.Game.Type.IsGIGroup())
// {
// m_IsStreamedSceneAssetBundle = reader.ReadBoolean();
// reader.AlignStream();
// if (reader.Game.Type.IsGICB3() || reader.Game.Type.IsGI())
// {
// m_ExplicitDataLayout = reader.ReadInt32();
// }
// m_PathFlags = reader.ReadInt32();
// if (reader.Game.Type.IsGI())
// {
// var sceneHashCount = reader.ReadInt32();
// m_SceneHashes = new KeyValuePair<string, string>[sceneHashCount];
// for (int l = 0; l < sceneHashCount; l++)
// {
// m_SceneHashes[l] = new KeyValuePair<string, string>(reader.ReadAlignedString(), reader.ReadAlignedString());
// }
// }
// }
//}
}
}
}

View File

@@ -1,5 +1,4 @@
using SevenZip;
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -10,8 +9,6 @@ namespace AssetStudio
{
public PPtr<Component>[] m_Components;
public string m_Name;
public uint m_Tag;
public bool m_IsActive;
public Transform m_Transform;
public MeshRenderer m_MeshRenderer;
@@ -35,67 +32,6 @@ namespace AssetStudio
var m_Layer = reader.ReadInt32();
m_Name = reader.ReadAlignedString();
m_Tag = reader.ReadUInt16();
m_IsActive = reader.ReadBoolean();
}
public Transform GetTransform()
{
foreach (PPtr<Component> ptr in FetchComponents())
{
if (!ptr.TryGet(out var comp))
{
continue;
}
if (comp.type == ClassIDType.Transform)
{
return comp as Transform;
}
}
throw new Exception("Can't find transform component");
}
private List<PPtr<Component>> FetchComponents()
{
return m_Components.ToList();
}
public T FindComponent<T>()
where T : Component
{
foreach (PPtr<Component> ptr in FetchComponents())
{
// component could has not impelemented asset type
if (ptr.TryGet(out var comp) && comp is T t)
{
return t;
}
}
return null;
}
public Dictionary<uint, string> BuildTOS()
{
Dictionary<uint, string> tos = new Dictionary<uint, string>() { { 0, string.Empty } };
BuildTOS(this, string.Empty, tos);
return tos;
}
private void BuildTOS(GameObject parent, string parentPath, Dictionary<uint, string> tos)
{
Transform transform = parent.GetTransform();
foreach (PPtr<Transform> childPtr in transform.m_Children)
{
if (childPtr.TryGet(out var childTransform))
{
if (childTransform.m_GameObject.TryGet(out var child))
{
string path = parentPath != string.Empty ? parentPath + '/' + child.m_Name : child.m_Name;
var pathHash = CRC.CalculateDigestUTF8(path);
tos[pathHash] = path;
BuildTOS(child, path, tos);
}
}
}
}
}
}

View File

@@ -1,5 +1,4 @@
using Newtonsoft.Json;
using System.Collections.Generic;
using System.Collections.Generic;
namespace AssetStudio
{
@@ -10,7 +9,6 @@ namespace AssetStudio
public Index(ObjectReader reader)
{
Object = new PPtr<Object>(reader);
Size = reader.ReadUInt64();
}
@@ -18,25 +16,16 @@ namespace AssetStudio
public sealed class IndexObject : NamedObject
{
public static bool Exportable;
public int Count;
public Dictionary<string, Index> AssetMap;
public Dictionary<long, string> Names = new Dictionary<long, string>();
public KeyValuePair<string, Index>[] AssetMap;
public IndexObject(ObjectReader reader) : base(reader)
{
Count = reader.ReadInt32();
AssetMap = new Dictionary<string, Index>(Count);
AssetMap = new KeyValuePair<string, Index>[Count];
for (int i = 0; i < Count; i++)
{
var key = reader.ReadAlignedString();
var value = new Index(reader);
AssetMap.Add(key, value);
if (value.Object.m_FileID == 0)
Names.Add(value.Object.m_PathID, key);
AssetMap[i] = new KeyValuePair<string, Index>(reader.ReadAlignedString(), new Index(reader));
}
}
}

View File

@@ -1,7 +1,4 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using SevenZip;
using System.Collections.Generic;
using System.Collections.Generic;
namespace AssetStudio
{
@@ -21,94 +18,52 @@ namespace AssetStudio
public class UnityPropertySheet
{
private const string HDRPostfixName = "_HDR";
private const string STPostfixName = "_ST";
private const string TexelSizePostfixName = "_TexelSize";
public Dictionary<string, UnityTexEnv> m_TexEnvs;
public Dictionary<string, int> m_Ints;
public Dictionary<string, float> m_Floats;
public Dictionary<string, Color> m_Colors;
public KeyValuePair<string, UnityTexEnv>[] m_TexEnvs;
public KeyValuePair<string, int>[] m_Ints;
public KeyValuePair<string, float>[] m_Floats;
public KeyValuePair<string, Color>[] m_Colors;
public UnityPropertySheet(ObjectReader reader)
{
var version = reader.version;
int m_TexEnvsSize = reader.ReadInt32();
m_TexEnvs = new Dictionary<string, UnityTexEnv>(m_TexEnvsSize);
m_TexEnvs = new KeyValuePair<string, UnityTexEnv>[m_TexEnvsSize];
for (int i = 0; i < m_TexEnvsSize; i++)
{
m_TexEnvs.Add(reader.ReadAlignedString(), new UnityTexEnv(reader));
m_TexEnvs[i] = new KeyValuePair<string, UnityTexEnv>(reader.ReadAlignedString(), new UnityTexEnv(reader));
}
if (version[0] >= 2021) //2021.1 and up
{
int m_IntsSize = reader.ReadInt32();
m_Ints = new Dictionary<string, int>(m_IntsSize);
m_Ints = new KeyValuePair<string, int>[m_IntsSize];
for (int i = 0; i < m_IntsSize; i++)
{
m_Ints.Add(reader.ReadAlignedString(), reader.ReadInt32());
m_Ints[i] = new KeyValuePair<string, int>(reader.ReadAlignedString(), reader.ReadInt32());
}
}
int m_FloatsSize = reader.ReadInt32();
m_Floats = new Dictionary<string, float>(m_FloatsSize);
m_Floats = new KeyValuePair<string, float>[m_FloatsSize];
for (int i = 0; i < m_FloatsSize; i++)
{
m_Floats.Add(reader.ReadAlignedString(), reader.ReadSingle());
m_Floats[i] = new KeyValuePair<string, float>(reader.ReadAlignedString(), reader.ReadSingle());
}
int m_ColorsSize = reader.ReadInt32();
m_Colors = new Dictionary<string, Color>(m_ColorsSize);
m_Colors = new KeyValuePair<string, Color>[m_ColorsSize];
for (int i = 0; i < m_ColorsSize; i++)
{
m_Colors.Add(reader.ReadAlignedString(), reader.ReadColor4());
m_Colors[i] = new KeyValuePair<string, Color>(reader.ReadAlignedString(), reader.ReadColor4());
}
}
public string FindPropertyNameByCRC28(uint crc)
{
foreach (var property in m_TexEnvs.Keys)
{
string hdrName = property + HDRPostfixName;
if (CRC.Verify28DigestUTF8(hdrName, crc))
{
return hdrName;
}
string stName = property + STPostfixName;
if (CRC.Verify28DigestUTF8(stName, crc))
{
return stName;
}
string texelName = property + TexelSizePostfixName;
if (CRC.Verify28DigestUTF8(texelName, crc))
{
return texelName;
}
}
foreach (var property in m_Floats.Keys)
{
if (CRC.Verify28DigestUTF8(property, crc))
{
return property;
}
}
foreach (var property in m_Colors.Keys)
{
if (CRC.Verify28DigestUTF8(property, crc))
{
return property;
}
}
return null;
}
}
public sealed class Material : NamedObject
{
public PPtr<Shader> m_Shader;
public UnityPropertySheet m_SavedProperties;
public Dictionary<string, string> m_StringTagMap;
public Material(ObjectReader reader) : base(reader)
{
@@ -119,16 +74,25 @@ namespace AssetStudio
var m_ShaderKeywords = reader.ReadStringArray();
}
if (version[0] >= 5) //5.0 and up
if (version[0] > 2021 || (version[0] == 2021 && version[1] >= 3)) //2021.3 and up
{
var m_ValidKeywords = reader.ReadStringArray();
var m_InvalidKeywords = reader.ReadStringArray();
}
else if (version[0] >= 5) //5.0 ~ 2021.2
{
var m_ShaderKeywords = reader.ReadAlignedString();
}
if (version[0] >= 5) //5.0 and up
{
var m_LightmapFlags = reader.ReadUInt32();
}
if (version[0] > 5 || (version[0] == 5 && version[1] >= 6)) //5.6 and up
{
var m_EnableInstancingVariants = reader.ReadBoolean();
var m_DoubleSidedGI = reader.ReadBoolean(); //2017 and up
//var m_DoubleSidedGI = a_Stream.ReadBoolean(); //2017 and up
reader.AlignStream();
}
@@ -140,15 +104,18 @@ namespace AssetStudio
if (version[0] > 5 || (version[0] == 5 && version[1] >= 1)) //5.1 and up
{
var stringTagMapSize = reader.ReadInt32();
m_StringTagMap = new Dictionary<string, string>(stringTagMapSize);
for (int i = 0; i < stringTagMapSize; i++)
{
var first = reader.ReadAlignedString();
var second = reader.ReadAlignedString();
m_StringTagMap.Add(first, second);
}
}
if (reader.Game.Type.IsNaraka())
{
var value = reader.ReadInt32();
}
if (version[0] > 5 || (version[0] == 5 && version[1] >= 6)) //5.6 and up
{
var disabledShaderPasses = reader.ReadStringArray();
@@ -158,10 +125,5 @@ namespace AssetStudio
//vector m_BuildTextureStacks 2020 and up
}
public string FindPropertyNameByCRC28(uint crc)
{
return m_SavedProperties.FindPropertyNameByCRC28(crc);
}
}
}

View File

@@ -1,12 +1,9 @@
using SevenZip;
using System;
using System;
using System.Buffers.Binary;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection.Metadata.Ecma335;
using System.Text;
using System.Xml.Linq;
namespace AssetStudio
{
@@ -15,7 +12,7 @@ namespace AssetStudio
public Vector3 m_Min;
public Vector3 m_Max;
public MinMaxAABB(BinaryReader reader)
public MinMaxAABB(EndianBinaryReader reader)
{
m_Min = reader.ReadVector3();
m_Max = reader.ReadVector3();
@@ -300,7 +297,6 @@ namespace AssetStudio
public class MeshBlendShape
{
public string name;
public uint firstVertex;
public uint vertexCount;
public bool hasNormals;
@@ -312,7 +308,7 @@ namespace AssetStudio
if (version[0] == 4 && version[1] < 3) //4.3 down
{
name = reader.ReadAlignedString();
var name = reader.ReadAlignedString();
}
firstVertex = reader.ReadUInt32();
vertexCount = reader.ReadUInt32();
@@ -328,11 +324,6 @@ namespace AssetStudio
reader.AlignStream();
}
}
public bool IsCRCMatch(uint digest)
{
return CRC.VerifyDigestUTF8(name, digest);
}
}
public class MeshBlendShapeChannel
@@ -404,20 +395,9 @@ namespace AssetStudio
}
}
}
public string FindShapeNameByCRC(uint crc)
{
foreach (var blendChannel in channels)
{
if (blendChannel.nameHash == crc)
{
return blendChannel.name;
}
}
return null;
}
}
public enum GfxPrimitiveType : int
public enum GfxPrimitiveType
{
Triangles = 0,
TriangleStrip = 1,
@@ -560,7 +540,7 @@ namespace AssetStudio
var m_StreamCompression = reader.ReadByte();
}
var m_IsReadable = reader.ReadBoolean();
if (reader.Game.Name == "BH3")
if (reader.Game.Type.IsBH3())
{
var m_IsHighPrecisionPosition = reader.ReadBoolean();
var m_IsHighPrecisionTangent = reader.ReadBoolean();
@@ -568,9 +548,9 @@ namespace AssetStudio
}
var m_KeepVertices = reader.ReadBoolean();
var m_KeepIndices = reader.ReadBoolean();
reader.AlignStream();
}
if (reader.Game.Name == "GI" || reader.Game.Name == "GI_CB2" || reader.Game.Name == "GI_CB3")
reader.AlignStream();
if (reader.Game.Type.IsGISubGroup())
{
var m_PackSkinDataToUV2UV3 = reader.ReadBoolean();
reader.AlignStream();
@@ -665,7 +645,7 @@ namespace AssetStudio
m_CompressedMesh = new CompressedMesh(reader);
}
var m_LocalAABB = new AABB(reader);
reader.Position += 24; //AABB m_LocalAABB
if (version[0] < 3 || (version[0] == 3 && version[1] <= 4)) //3.4.2 and earlier
{
@@ -683,19 +663,24 @@ namespace AssetStudio
int m_MeshUsageFlags = reader.ReadInt32();
if (version[0] > 2022 || (version[0] == 2022 && version[1] >= 1)) //2022.1 and up
{
int m_CookingOptions = reader.ReadInt32();
}
if (version[0] >= 5) //5.0 and up
{
var m_BakedConvexCollisionMesh = reader.ReadUInt8Array();
reader.AlignStream();
var m_BakedTriangleCollisionMesh = reader.ReadUInt8Array();
reader.AlignStream();
if (reader.Game.Name == "BH3")
if (reader.Game.Type.IsBH3())
{
var m_MeshOptimized = reader.ReadBoolean();
}
}
if (reader.Game.Name == "ZZZ_CB1")
if (reader.Game.Type.IsZZZCB1())
{
var m_CloseMeshDynamicCompression = reader.ReadBoolean();
reader.AlignStream();
@@ -705,21 +690,20 @@ namespace AssetStudio
var m_CompressLevelTexCoordinates = reader.ReadInt32();
}
if (reader.Game.Name == "GI" || reader.Game.Name == "GI_CB1" || reader.Game.Name == "GI_CB2" || reader.Game.Name == "GI_CB3"
|| version[0] > 2018 || (version[0] == 2018 && version[1] >= 2)) //2018.2 and up
if (reader.Game.Type.IsGIGroup() || version[0] > 2018 || (version[0] == 2018 && version[1] >= 2)) //2018.2 and up
{
var m_MeshMetrics = new float[2];
m_MeshMetrics[0] = reader.ReadSingle();
m_MeshMetrics[1] = reader.ReadSingle();
}
if (reader.Game.Name == "GI" || reader.Game.Name == "GI_CB1" || reader.Game.Name == "GI_CB2" || reader.Game.Name == "GI_CB3")
if (reader.Game.Type.IsGIGroup())
{
var m_MetricsDirty = reader.ReadBoolean();
reader.AlignStream();
var m_CloseMeshDynamicCompression = reader.ReadBoolean();
reader.AlignStream();
if (reader.Game.Name != "GI_CB1")
if (!reader.Game.Type.IsGICB1() && !reader.Game.Type.IsGIPack())
{
var m_IsStreamingMesh = reader.ReadBoolean();
reader.AlignStream();
@@ -830,13 +814,9 @@ namespace AssetStudio
m_UV1 = componentsFloatArray;
break;
case 6: //kShaderChannelTexCoord2
if (reader.Game.Name == "GI" || reader.Game.Name == "GI_CB1" || reader.Game.Name == "GI_CB2" || reader.Game.Name == "GI_CB3")
continue;
m_UV2 = componentsFloatArray;
break;
case 7: //kShaderChannelTexCoord3
if (reader.Game.Name == "GI" || reader.Game.Name == "GI_CB1" || reader.Game.Name == "GI_CB2" || reader.Game.Name == "GI_CB3")
continue;
m_UV3 = componentsFloatArray;
break;
case 8: //kShaderChannelTexCoord4
@@ -900,8 +880,6 @@ namespace AssetStudio
m_UV1 = componentsFloatArray;
break;
case 5:
if (reader.Game.Name == "GI" || reader.Game.Name == "GI_CB1" || reader.Game.Name == "GI_CB2" || reader.Game.Name == "GI_CB3")
continue;
if (version[0] >= 5) //kShaderChannelTexCoord2
{
m_UV2 = componentsFloatArray;
@@ -912,8 +890,6 @@ namespace AssetStudio
}
break;
case 6: //kShaderChannelTexCoord3
if (reader.Game.Name == "GI" || reader.Game.Name == "GI_CB1" || reader.Game.Name == "GI_CB2" || reader.Game.Name == "GI_CB3")
continue;
m_UV3 = componentsFloatArray;
break;
case 7: //kShaderChannelTangent
@@ -1255,25 +1231,6 @@ namespace AssetStudio
throw new ArgumentOutOfRangeException();
}
}
public string FindBlendShapeNameByCRC(uint crc)
{
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3))
{
return m_Shapes.FindShapeNameByCRC(crc);
}
else
{
foreach (var blendShape in m_Shapes.shapes)
{
if (blendShape.IsCRCMatch(crc))
{
return blendShape.name;
}
}
return null;
}
}
}
public static class MeshHelper
@@ -1419,7 +1376,7 @@ namespace AssetStudio
switch (format)
{
case VertexFormat.Float:
result[i] = BitConverter.ToSingle(inputBytes, i * 4);
result[i] = BinaryPrimitives.ReadSingleLittleEndian(inputBytes.AsSpan(i * 4));
break;
case VertexFormat.Float16:
result[i] = Half.ToHalf(inputBytes, i * 2);
@@ -1431,10 +1388,10 @@ namespace AssetStudio
result[i] = Math.Max((sbyte)inputBytes[i] / 127f, -1f);
break;
case VertexFormat.UNorm16:
result[i] = BitConverter.ToUInt16(inputBytes, i * 2) / 65535f;
result[i] = BinaryPrimitives.ReadUInt16LittleEndian(inputBytes.AsSpan(i * 2)) / 65535f;
break;
case VertexFormat.SNorm16:
result[i] = Math.Max(BitConverter.ToInt16(inputBytes, i * 2) / 32767f, -1f);
result[i] = Math.Max(BinaryPrimitives.ReadInt16LittleEndian(inputBytes.AsSpan(i * 2)) / 32767f, -1f);
break;
}
}
@@ -1456,11 +1413,11 @@ namespace AssetStudio
break;
case VertexFormat.UInt16:
case VertexFormat.SInt16:
result[i] = BitConverter.ToInt16(inputBytes, i * 2);
result[i] = BinaryPrimitives.ReadInt16LittleEndian(inputBytes.AsSpan(i * 2));
break;
case VertexFormat.UInt32:
case VertexFormat.SInt32:
result[i] = BitConverter.ToInt32(inputBytes, i * 4);
result[i] = BinaryPrimitives.ReadInt32LittleEndian(inputBytes.AsSpan(i * 4));
break;
}
}

View File

@@ -7,9 +7,10 @@ namespace AssetStudio
{
public sealed class MeshRenderer : Renderer
{
public PPtr<Mesh> m_AdditionalVertexStreams;
public MeshRenderer(ObjectReader reader) : base(reader)
{
var m_AdditionalVertexStreams = new PPtr<Mesh>(reader);
m_AdditionalVertexStreams = new PPtr<Mesh>(reader);
}
}
}

View File

@@ -1,8 +1,8 @@
using System;
using System.Text;
using System.Text.RegularExpressions;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Text.RegularExpressions;
namespace AssetStudio
{
@@ -12,17 +12,57 @@ namespace AssetStudio
Bytes,
JSON
}
public sealed class MiHoYoBinData : Object
public sealed partial class MiHoYoBinData : Object
{
public static bool doXOR;
public static bool Exportable;
public static bool Encrypted;
public static byte Key;
public byte[] RawData;
public byte[] Data
public MiHoYoBinData(ObjectReader reader) : base(reader)
{
var length = reader.ReadInt32();
RawData = reader.ReadBytes(length);
}
public string AsString => Type switch
{
MiHoYoBinDataType.JSON => JToken.Parse(DataStr).ToString(Formatting.Indented),
MiHoYoBinDataType.Bytes => Chars().Replace(DataStr, string.Empty),
_ => "",
};
public new object Dump() => Type switch
{
MiHoYoBinDataType.JSON => AsString,
MiHoYoBinDataType.Bytes => Data,
_ => null,
};
private string DataStr => Encoding.UTF8.GetString(Data);
public MiHoYoBinDataType Type
{
get
{
if (doXOR)
try
{
var asToken = JToken.Parse(DataStr);
if (asToken.Type == JTokenType.Object || asToken.Type == JTokenType.Array)
return MiHoYoBinDataType.JSON;
}
catch (Exception)
{
return MiHoYoBinDataType.Bytes;
}
return MiHoYoBinDataType.None;
}
}
private byte[] Data
{
get
{
if (Encrypted)
{
byte[] bytes = new byte[RawData.Length];
for (int i = 0; i < RawData.Length; i++)
@@ -35,59 +75,7 @@ namespace AssetStudio
}
}
public string Str
{
get
{
var str = Encoding.UTF8.GetString(Data);
switch (Type)
{
case MiHoYoBinDataType.JSON:
return JToken.Parse(str).ToString(Formatting.Indented);
case MiHoYoBinDataType.Bytes:
return Regex.Replace(str, @"[^\u0020-\u007E]", string.Empty);
default:
return "";
}
}
}
public MiHoYoBinDataType Type
{
get
{
try
{
var str = Encoding.UTF8.GetString(Data);
var asToken = JToken.Parse(str);
if (asToken.Type == JTokenType.Object || asToken.Type == JTokenType.Array)
return MiHoYoBinDataType.JSON;
}
catch (Exception)
{
return MiHoYoBinDataType.Bytes;
}
return MiHoYoBinDataType.None;
}
}
public MiHoYoBinData(ObjectReader reader) : base(reader)
{
var length = reader.ReadInt32();
RawData = reader.ReadBytes(length);
}
public new dynamic Dump()
{
switch (Type)
{
case MiHoYoBinDataType.JSON:
return Str;
case MiHoYoBinDataType.Bytes:
return Data;
default:
return null;
}
}
[GeneratedRegex("[^\\u0020-\\u007E]")]
private static partial Regex Chars();
}
}

View File

@@ -1,9 +1,11 @@
using System;
using System.IO;
using System.Collections.Generic;
using static AssetStudio.AssetsHelper;
namespace AssetStudio
{
public sealed class PPtr<T> : IYAMLExportable
where T : Object
public sealed class PPtr<T> where T : Object
{
public int m_FileID;
public long m_PathID;
@@ -18,21 +20,6 @@ namespace AssetStudio
assetsFile = reader.assetsFile;
}
public PPtr(int fileID, long pathID, SerializedFile assetsFile)
{
m_FileID = fileID;
m_PathID = pathID;
this.assetsFile = assetsFile;
}
public YAMLNode ExportYAML()
{
var node = new YAMLMappingNode();
node.Style = MappingStyle.Flow;
node.Add("fileID", m_FileID);
return node;
}
private bool TryGetAssetsFile(out SerializedFile result)
{
result = null;
@@ -142,11 +129,6 @@ namespace AssetStudio
m_PathID = m_Object.m_PathID;
}
public PPtr<T2> CastTo<T2>() where T2 : Object
{
return new PPtr<T2>(m_FileID, m_PathID, assetsFile);
}
public bool IsNull => m_PathID == 0 || m_FileID < 0;
}
}

View File

@@ -1,5 +1,4 @@
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
@@ -20,11 +19,13 @@ namespace AssetStudio
public abstract class Renderer : Component
{
public static bool Parsable;
public static bool Skipped;
public PPtr<Material>[] m_Materials;
public StaticBatchInfo m_StaticBatchInfo;
public uint[] m_SubsetIndices;
private bool isNewHeader = false;
protected Renderer(ObjectReader reader) : base(reader)
{
if (version[0] < 5) //5.0 down
@@ -38,7 +39,7 @@ namespace AssetStudio
{
if (version[0] > 5 || (version[0] == 5 && version[1] >= 4)) //5.4 and up
{
if (reader.Game.Name == "GI")
if (reader.Game.Type.IsGI())
{
CheckHeader(reader);
}
@@ -48,39 +49,44 @@ namespace AssetStudio
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 2)) //2017.2 and up
{
var m_DynamicOccludee = reader.ReadByte();
if (reader.Game.Name == "BH3")
}
if (reader.Game.Type.IsBH3())
{
var m_AllowHalfResolution = reader.ReadByte();
}
if (reader.Game.Type.IsGIGroup())
{
var m_ReceiveDecals = reader.ReadByte();
var m_EnableShadowCulling = reader.ReadByte();
var m_EnableGpuQuery = reader.ReadByte();
var m_AllowHalfResolution = reader.ReadByte();
if (!reader.Game.Type.IsGICB1())
{
var m_AllowHalfResolution = reader.ReadByte();
}
else if (reader.Game.Name == "GI_CB3")
{
var m_ReceiveDecals = reader.ReadByte();
var m_EnableShadowCulling = reader.ReadByte();
var m_EnableGpuQuery = reader.ReadByte();
var m_AllowHalfResolution = reader.ReadByte();
var m_IsRainOccluder = reader.ReadByte();
var m_IsDynamicAOOccluder = reader.ReadByte();
var m_IsDynamic = reader.ReadByte();
}
else if (reader.Game.Name == "GI")
{
var m_ReceiveDecals = reader.ReadByte();
var m_EnableShadowCulling = reader.ReadByte();
var m_EnableGpuQuery = reader.ReadByte();
var m_AllowHalfResolution = reader.ReadByte();
var m_IsRainOccluder = reader.ReadByte();
var m_IsDynamicAOOccluder = reader.ReadByte();
var m_IsCloudObject = reader.ReadByte();
var m_IsInteriorVolume = reader.ReadByte();
var m_IsDynamic = reader.ReadByte();
var m_UseTessellation = reader.ReadByte();
var m_IsTerrainTessInfo = reader.ReadByte();
if (isNewHeader)
if (reader.Game.Type.IsGI())
{
var m_UseVertexLightInForward = reader.ReadByte();
var m_CombineSubMeshInGeoPass = reader.ReadByte();
var m_AllowPerMaterialProp = reader.ReadByte();
var m_IsHQDynamicAOOccluder = reader.ReadByte();
var m_AllowPerMaterialProp = isNewHeader ? reader.ReadByte() : 0;
}
var m_IsRainOccluder = reader.ReadByte();
if (!reader.Game.Type.IsGICB2())
{
var m_IsDynamicAOOccluder = reader.ReadByte();
if (reader.Game.Type.IsGI())
{
var m_IsHQDynamicAOOccluder = reader.ReadByte();
var m_IsCloudObject = reader.ReadByte();
var m_IsInteriorVolume = reader.ReadByte();
}
}
if (!reader.Game.Type.IsGIPack())
{
var m_IsDynamic = reader.ReadByte();
}
if (reader.Game.Type.IsGI())
{
var m_UseTessellation = reader.ReadByte();
var m_IsTerrainTessInfo = isNewHeader ? reader.ReadByte() : 0;
var m_UseVertexLightInForward = isNewHeader ? reader.ReadByte() : 0;
var m_CombineSubMeshInGeoPass = isNewHeader ? reader.ReadByte() : 0;
}
}
}
@@ -88,22 +94,6 @@ namespace AssetStudio
{
var m_StaticShadowCaster = reader.ReadByte();
}
if (reader.Game.Name == "GI_CB2")
{
var m_ReceiveDecals = reader.ReadByte();
var m_EnableShadowCulling = reader.ReadByte();
var m_EnableGpuQuery = reader.ReadByte();
var m_AllowHalfResolution = reader.ReadByte();
var m_IsRainOccluder = reader.ReadByte();
var m_IsDynamic = reader.ReadByte();
}
if (reader.Game.Name == "GI_CB1")
{
var m_ReceiveDecals = reader.ReadByte();
var m_EnableShadowCulling = reader.ReadByte();
var m_EnableGpuQuery = reader.ReadByte();
var m_AllowHalfResolution = reader.ReadByte();
}
var m_MotionVectors = reader.ReadByte();
var m_LightProbeUsage = reader.ReadByte();
var m_ReflectionProbeUsage = reader.ReadByte();
@@ -115,7 +105,7 @@ namespace AssetStudio
{
var m_RayTraceProcedural = reader.ReadByte();
}
if (reader.Game.Name == "GI" || reader.Game.Name == "GI_CB3")
if (reader.Game.Type.IsGI() || reader.Game.Type.IsGICB3() || reader.Game.Type.IsGICB3Pre())
{
var m_MeshShowQuality = reader.ReadByte();
}
@@ -140,12 +130,11 @@ namespace AssetStudio
var m_RendererPriority = reader.ReadInt32();
}
var m_LightmapIndex = reader.ReadInt16();
var m_LightmapIndexDynamic = reader.ReadInt16();
if (reader.Game.Name == "GI" || reader.Game.Name == "GI_CB1" || reader.Game.Name == "GI_CB2" || reader.Game.Name == "GI_CB3")
var m_LightmapIndex = reader.ReadUInt16();
var m_LightmapIndexDynamic = reader.ReadUInt16();
if (reader.Game.Type.IsGIGroup() && (m_LightmapIndex != 0xFFFF || m_LightmapIndexDynamic != 0xFFFF))
{
if (m_LightmapIndex != -1 || m_LightmapIndexDynamic != -1)
throw new Exception("Not Supported !! skipping....");
throw new Exception("Not Supported !! skipping....");
}
}
@@ -159,7 +148,7 @@ namespace AssetStudio
var m_LightmapTilingOffsetDynamic = reader.ReadVector4();
}
if (reader.Game.Name == "GI" || reader.Game.Name == "GI_CB1" || reader.Game.Name == "GI_CB2" || reader.Game.Name == "GI_CB3")
if (reader.Game.Type.IsGIGroup())
{
var m_ViewDistanceRatio = reader.ReadSingle();
var m_ShaderLODDistanceRatio = reader.ReadSingle();
@@ -188,7 +177,8 @@ namespace AssetStudio
var m_StaticBatchRoot = new PPtr<Transform>(reader);
}
if (reader.Game.Name == "GI" || reader.Game.Name == "GI_CB1" || reader.Game.Name == "GI_CB2" || reader.Game.Name == "GI_CB3")
if (reader.Game.Type.IsGIGroup())
{
var m_MatLayers = reader.ReadInt32();
}
@@ -219,21 +209,20 @@ namespace AssetStudio
}
else
{
var m_SortingLayerID = reader.ReadInt32();
var m_SortingLayer = reader.ReadInt16();
var m_SortingLayerID = reader.ReadUInt32();
}
//SInt16 m_SortingLayer 5.6 and up
var m_SortingOrder = reader.ReadInt16();
reader.AlignStream();
if (reader.Game.Name == "GI" || reader.Game.Name == "GI_CB1" || reader.Game.Name == "GI_CB2" || reader.Game.Name == "GI_CB3" || reader.Game.Name == "BH3")
if (reader.Game.Type.IsGIGroup() || reader.Game.Type.IsBH3())
{
var m_UseHighestMip = reader.ReadBoolean();
reader.AlignStream();
}
if (reader.Game.Name == "SR_CB3")
if (reader.Game.Type.IsSRCB3())
{
var _RenderFlag = reader.ReadUInt32();
var RenderFlag = reader.ReadUInt32();
reader.AlignStream();
}
}
@@ -241,31 +230,14 @@ namespace AssetStudio
private void CheckHeader(ObjectReader reader)
{
short index = 0;
short value = 0;
var pos = reader.Position;
while (index != -1 && reader.Position <= pos + 0x1A)
index = reader.ReadInt16();
while (value != -1 && reader.Position <= pos + 0x1A)
{
value = reader.ReadInt16();
}
isNewHeader = (reader.Position - pos) == 0x1A;
reader.Position = pos;
}
public string FindMaterialPropertyNameByCRC28(uint crc)
{
foreach (PPtr<Material> materialPtr in m_Materials)
{
if (!materialPtr.TryGet(out var material))
{
continue;
}
string property = material.FindPropertyNameByCRC28(crc);
if (property == null)
{
continue;
}
return property;
}
return null;
}
}
}

View File

@@ -11,7 +11,5 @@ namespace AssetStudio
{
}
public abstract bool IsContainsAnimationClip(AnimationClip clip);
}
}

View File

@@ -1,4 +1,5 @@
using System;
using System.Buffers.Binary;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -9,7 +10,7 @@ namespace AssetStudio
{
public byte[] bytes;
public Hash128(BinaryReader reader)
public Hash128(EndianBinaryReader reader)
{
bytes = reader.ReadBytes(16);
}
@@ -20,7 +21,7 @@ namespace AssetStudio
public MatrixParameter[] m_MatrixParams;
public VectorParameter[] m_VectorParams;
public StructParameter(BinaryReader reader)
public StructParameter(EndianBinaryReader reader)
{
var m_NameIndex = reader.ReadInt32();
var m_Index = reader.ReadInt32();
@@ -48,7 +49,7 @@ namespace AssetStudio
public uint sampler;
public int bindPoint;
public SamplerParameter(BinaryReader reader)
public SamplerParameter(EndianBinaryReader reader)
{
sampler = reader.ReadUInt32();
bindPoint = reader.ReadInt32();
@@ -71,7 +72,7 @@ namespace AssetStudio
public string m_DefaultName;
public TextureDimension m_TexDim;
public SerializedTextureProperty(BinaryReader reader)
public SerializedTextureProperty(EndianBinaryReader reader)
{
m_DefaultName = reader.ReadAlignedString();
m_TexDim = (TextureDimension)reader.ReadInt32();
@@ -98,7 +99,7 @@ namespace AssetStudio
public float[] m_DefValue;
public SerializedTextureProperty m_DefTexture;
public SerializedProperty(BinaryReader reader)
public SerializedProperty(EndianBinaryReader reader)
{
m_Name = reader.ReadAlignedString();
m_Description = reader.ReadAlignedString();
@@ -114,7 +115,7 @@ namespace AssetStudio
{
public SerializedProperty[] m_Props;
public SerializedProperties(BinaryReader reader)
public SerializedProperties(EndianBinaryReader reader)
{
int numProps = reader.ReadInt32();
m_Props = new SerializedProperty[numProps];
@@ -130,7 +131,7 @@ namespace AssetStudio
public float val;
public string name;
public SerializedShaderFloatValue(BinaryReader reader)
public SerializedShaderFloatValue(EndianBinaryReader reader)
{
val = reader.ReadSingle();
name = reader.ReadAlignedString();
@@ -147,7 +148,7 @@ namespace AssetStudio
public SerializedShaderFloatValue blendOpAlpha;
public SerializedShaderFloatValue colMask;
public SerializedShaderRTBlendState(BinaryReader reader)
public SerializedShaderRTBlendState(EndianBinaryReader reader)
{
srcBlend = new SerializedShaderFloatValue(reader);
destBlend = new SerializedShaderFloatValue(reader);
@@ -166,7 +167,7 @@ namespace AssetStudio
public SerializedShaderFloatValue zFail;
public SerializedShaderFloatValue comp;
public SerializedStencilOp(BinaryReader reader)
public SerializedStencilOp(EndianBinaryReader reader)
{
pass = new SerializedShaderFloatValue(reader);
fail = new SerializedShaderFloatValue(reader);
@@ -183,7 +184,7 @@ namespace AssetStudio
public SerializedShaderFloatValue w;
public string name;
public SerializedShaderVectorValue(BinaryReader reader)
public SerializedShaderVectorValue(EndianBinaryReader reader)
{
x = new SerializedShaderFloatValue(reader);
y = new SerializedShaderFloatValue(reader);
@@ -281,7 +282,7 @@ namespace AssetStudio
public sbyte source;
public sbyte target;
public ShaderBindChannel(BinaryReader reader)
public ShaderBindChannel(EndianBinaryReader reader)
{
source = reader.ReadSByte();
target = reader.ReadSByte();
@@ -293,7 +294,7 @@ namespace AssetStudio
public ShaderBindChannel[] m_Channels;
public uint m_SourceMap;
public ParserBindChannels(BinaryReader reader)
public ParserBindChannels(EndianBinaryReader reader)
{
int numChannels = reader.ReadInt32();
m_Channels = new ShaderBindChannel[numChannels];
@@ -315,7 +316,7 @@ namespace AssetStudio
public sbyte m_Type;
public sbyte m_Dim;
public VectorParameter(BinaryReader reader)
public VectorParameter(EndianBinaryReader reader)
{
m_NameIndex = reader.ReadInt32();
m_Index = reader.ReadInt32();
@@ -334,7 +335,7 @@ namespace AssetStudio
public sbyte m_Type;
public sbyte m_RowCount;
public MatrixParameter(BinaryReader reader)
public MatrixParameter(EndianBinaryReader reader)
{
m_NameIndex = reader.ReadInt32();
m_Index = reader.ReadInt32();
@@ -428,6 +429,7 @@ namespace AssetStudio
if ((version[0] == 2020 && version[1] > 3) ||
(version[0] == 2020 && version[1] == 3 && version[2] >= 2) || //2020.3.2f1 and up
(version[0] > 2021) ||
(version[0] == 2021 && version[1] > 1) ||
(version[0] == 2021 && version[1] == 1 && version[2] >= 4)) //2021.1.4f1 and up
{
@@ -443,7 +445,7 @@ namespace AssetStudio
public int m_Index;
public int m_OriginalIndex;
public UAVParameter(BinaryReader reader)
public UAVParameter(EndianBinaryReader reader)
{
m_NameIndex = reader.ReadInt32();
m_Index = reader.ReadInt32();
@@ -605,6 +607,7 @@ namespace AssetStudio
if ((version[0] == 2020 && version[1] > 3) ||
(version[0] == 2020 && version[1] == 3 && version[2] >= 2) || //2020.3.2f1 and up
(version[0] > 2021) ||
(version[0] == 2021 && version[1] > 1) ||
(version[0] == 2021 && version[1] == 1 && version[2] >= 1)) //2021.1.1f1 and up
{
@@ -690,6 +693,7 @@ namespace AssetStudio
{
public SerializedSubProgram[] m_SubPrograms;
public SerializedProgramParameters m_CommonParameters;
public ushort[] m_SerializedKeywordStateMask;
public SerializedProgram(ObjectReader reader)
{
@@ -704,11 +708,18 @@ namespace AssetStudio
if ((version[0] == 2020 && version[1] > 3) ||
(version[0] == 2020 && version[1] == 3 && version[2] >= 2) || //2020.3.2f1 and up
(version[0] > 2021) ||
(version[0] == 2021 && version[1] > 1) ||
(version[0] == 2021 && version[1] == 1 && version[2] >= 1)) //2021.1.4f1 and up
(version[0] == 2021 && version[1] == 1 && version[2] >= 1)) //2021.1.1f1 and up
{
m_CommonParameters = new SerializedProgramParameters(reader);
}
if (version[0] > 2022 || (version[0] == 2022 && version[1] >= 1)) //2022.1 and up
{
m_SerializedKeywordStateMask = reader.ReadUInt16Array();
reader.AlignStream();
}
}
}
@@ -795,7 +806,7 @@ namespace AssetStudio
m_Name = reader.ReadAlignedString();
m_TextureName = reader.ReadAlignedString();
m_Tags = new SerializedTagMap(reader);
if (version[0] > 2021 || (version[0] == 2021 && version[1] >= 2)) //2021.2 and up
if (version[0] == 2021 && version[1] >= 2) //2021.2 ~2021.x
{
m_SerializedKeywordStateMask = reader.ReadUInt16Array();
reader.AlignStream();
@@ -807,7 +818,7 @@ namespace AssetStudio
{
public KeyValuePair<string, string>[] tags;
public SerializedTagMap(BinaryReader reader)
public SerializedTagMap(EndianBinaryReader reader)
{
int numTags = reader.ReadInt32();
tags = new KeyValuePair<string, string>[numTags];
@@ -843,7 +854,7 @@ namespace AssetStudio
public string from;
public string to;
public SerializedShaderDependency(BinaryReader reader)
public SerializedShaderDependency(EndianBinaryReader reader)
{
from = reader.ReadAlignedString();
to = reader.ReadAlignedString();
@@ -855,7 +866,7 @@ namespace AssetStudio
public string customEditorName;
public string renderPipelineType;
public SerializedCustomEditorForRenderPipeline(BinaryReader reader)
public SerializedCustomEditorForRenderPipeline(EndianBinaryReader reader)
{
customEditorName = reader.ReadAlignedString();
renderPipelineType = reader.ReadAlignedString();
@@ -953,7 +964,6 @@ namespace AssetStudio
public class Shader : NamedObject
{
public static bool Parsable;
public byte[] m_Script;
//5.3 - 5.4
public uint decompressedSize;
@@ -985,22 +995,22 @@ namespace AssetStudio
decompressedLengths = reader.ReadUInt32Array().Select(x => new[] { x }).ToArray();
}
compressedBlob = reader.ReadUInt8Array();
if (reader.Game.Name == "GI" || reader.Game.Name == "GI_CB2" || reader.Game.Name == "GI_CB3")
reader.AlignStream();
if (reader.Game.Type.IsGISubGroup())
{
if (BitConverter.ToInt32(compressedBlob, 0) == -1)
compressedBlob = reader.ReadUInt8Array();
if (BinaryPrimitives.ReadInt32LittleEndian(compressedBlob) == -1)
{
compressedBlob = reader.ReadUInt8Array(); //blobDataBlocks
reader.AlignStream();
}
}
else
{
reader.AlignStream();
}
var m_DependenciesCount = reader.ReadInt32();
for (int i = 0; i < m_DependenciesCount; i++)
{
new PPtr<Shader>(reader);
}
if (version[0] >= 2018)
{
var m_NonModifiableTexturesCount = reader.ReadInt32();
@@ -1010,7 +1020,7 @@ namespace AssetStudio
new PPtr<Texture>(reader);
}
}
var m_ShaderIsBaked = reader.ReadBoolean();
reader.AlignStream();
}

View File

@@ -9,11 +9,12 @@ namespace AssetStudio
{
public PPtr<Mesh> m_Mesh;
public PPtr<Transform>[] m_Bones;
public PPtr<Transform> m_RootBone;
public float[] m_BlendShapeWeights;
public PPtr<Transform> m_RootBone;
public AABB m_AABB;
public bool m_DirtyAABB;
public SkinnedMeshRenderer(ObjectReader reader) : base(reader)
{
int m_Quality = reader.ReadInt32();
@@ -33,16 +34,19 @@ namespace AssetStudio
{
m_Bones[b] = new PPtr<Transform>(reader);
}
reader.AlignStream();
if (version[0] > 4 || (version[0] == 4 && version[1] >= 3)) //4.3 and up
{
m_BlendShapeWeights = reader.ReadSingleArray();
}
reader.AlignStream();
m_RootBone = new PPtr<Transform>(reader);
m_AABB = new AABB(reader);
m_DirtyAABB = reader.ReadBoolean();
reader.AlignStream();
if (reader.Game.Type.IsGIGroup())
{
m_RootBone = new PPtr<Transform>(reader);
m_AABB = new AABB(reader);
m_DirtyAABB = reader.ReadBoolean();
reader.AlignStream();
}
}
}
}

View File

@@ -1,5 +1,4 @@
using System;
using System.IO;
namespace AssetStudio
{
@@ -134,9 +133,13 @@ namespace AssetStudio
ResourceReader resourceReader;
if (!string.IsNullOrEmpty(m_StreamData?.path))
{
resourceReader = new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, m_StreamData.size);
}
else
{
resourceReader = new ResourceReader(reader, reader.BaseStream.Position, image_data_size);
}
image_data = resourceReader;
}
}
@@ -204,7 +207,7 @@ namespace AssetStudio
R8,
ETC_RGB4Crunched,
ETC2_RGBA8Crunched,
R16_2,
R16_Alt,
ASTC_HDR_4x4,
ASTC_HDR_5x5,
ASTC_HDR_6x6,

View File

@@ -27,32 +27,5 @@ namespace AssetStudio
}
m_Father = new PPtr<Transform>(reader);
}
public Transform FindChild(string path)
{
if (path.Length == 0)
{
return this;
}
return FindChild(path, 0);
}
private Transform FindChild(string path, int startIndex)
{
int separatorIndex = path.IndexOf('/', startIndex);
string childName = separatorIndex == -1 ?
path.Substring(startIndex, path.Length - startIndex) :
path.Substring(startIndex, separatorIndex - startIndex);
foreach (PPtr<Transform> childPtr in m_Children)
{
if(childPtr.TryGet(out var child))
{
if (child.m_GameObject.TryGet(out var childGO) && childGO.m_Name == childName)
{
return separatorIndex == -1 ? child : child.FindChild(path, separatorIndex + 1);
}
}
}
return null;
}
}
}

View File

@@ -8,7 +8,7 @@ namespace AssetStudio
public long m_Offset; //ulong
public long m_Size; //ulong
public StreamedResource(BinaryReader reader)
public StreamedResource(EndianBinaryReader reader)
{
m_Source = reader.ReadAlignedString();
m_Offset = reader.ReadInt64();