Improve Tuanjie support

This commit is contained in:
VaDiM
2025-08-22 02:16:29 +03:00
parent f0a69025fe
commit 521e2f3bbc
7 changed files with 176 additions and 52 deletions

View File

@@ -55,7 +55,7 @@
public enum TuanjieBuildTarget public enum TuanjieBuildTarget
{ {
WeixinMiniGame = 47, MiniGame = 47,
OpenHarmony, OpenHarmony,
HMIAndroid, HMIAndroid,
ArmLinux, ArmLinux,

View File

@@ -679,6 +679,45 @@ namespace AssetStudio
} }
} }
public class ACLClip //Tuanjie
{
public uint m_FrameCount;
public uint m_BoneCount;
public float m_SampleRate;
public uint m_CurveCount;
public byte[] m_Tracks;
public uint[] m_ACLDecoderMap;
public bool m_UseACLFastSampleMode;
public ACLClip() { }
public ACLClip(ObjectReader reader)
{
var version = reader.version;
m_FrameCount = reader.ReadUInt32();
m_BoneCount = reader.ReadUInt32();
m_SampleRate = reader.ReadSingle();
if (version >= (2022, 3, 55)) //2022.3.55t1(1.5.0) and up
{
m_CurveCount = reader.ReadUInt32();
}
m_Tracks = reader.ReadUInt8Array();
if (version >= (2022, 3, 61)) //2022.3.61t1(1.6.0) and up
{
reader.AlignStream();
}
m_ACLDecoderMap = reader.ReadUInt32Array();
if (version > (2022, 3, 55) || (version == (2022, 3, 55) && version.Build >= 4)) //2022.3.55t4(1.5.3) and up
{
m_UseACLFastSampleMode = reader.ReadBoolean();
if (version >= (2022, 3, 61)) //2022.3.61t1(1.6.0) and up
{
reader.AlignStream();
}
}
}
}
public class OffsetPtr public class OffsetPtr
{ {
public Clip data; public Clip data;
@@ -697,6 +736,7 @@ namespace AssetStudio
public DenseClip m_DenseClip; public DenseClip m_DenseClip;
public ConstantClip m_ConstantClip; public ConstantClip m_ConstantClip;
public ValueArrayConstant m_Binding; public ValueArrayConstant m_Binding;
public ACLClip m_ACLClip;
public Clip() { } public Clip() { }
@@ -713,6 +753,10 @@ namespace AssetStudio
{ {
m_Binding = new ValueArrayConstant(reader); m_Binding = new ValueArrayConstant(reader);
} }
if (version.IsTuanjie && (version > (2022, 3, 48) || (version == (2022, 3, 48) && version.Build >= 3))) //2022.3.48t3(1.4.0) and up
{
m_ACLClip = new ACLClip(reader);
}
} }
public AnimationClipBindingConstant ConvertValueArrayToGenericBinding() public AnimationClipBindingConstant ConvertValueArrayToGenericBinding()
@@ -1174,17 +1218,28 @@ namespace AssetStudio
} }
if (version >= 4)//4.0 and up if (version >= 4)//4.0 and up
{ {
m_MuscleClipSize = reader.ReadUInt32(); //m_AnimDataSize (Tuanjie) if (version.IsTuanjie && version >= (2022, 3, 61)) //2022.3.61t1(1.6.0) and up
if (!version.IsTuanjie) {
m_EulerCurves = Vector3CurveList(reader);
m_PositionCurves = Vector3CurveList(reader);
m_ScaleCurves = Vector3CurveList(reader);
}
m_MuscleClipSize = reader.ReadUInt32(); //m_AnimDataSize (Tuanjie 1.0-1.5)
if (!version.IsTuanjie || version >= (2022, 3, 61))
{ {
m_MuscleClip = new ClipMuscleConstant(reader); m_MuscleClip = new ClipMuscleConstant(reader);
if (version.IsTuanjie) //2022.3.61t1(1.6.0) and up
{
m_StreamingInfo = new StreamingInfo(reader);
}
} }
else if (m_MuscleClipSize > 0) else if (m_MuscleClipSize > 0)
{ {
if (!m_Legacy) if (!m_Legacy)
{ {
_ = reader.ReadInt32(); _ = reader.ReadInt32();
m_MuscleClip = new ClipMuscleConstant(reader); //m_AnimData (Tuanjie) m_MuscleClip = new ClipMuscleConstant(reader); //m_AnimData (Tuanjie 1.0-1.5)
m_StreamingInfo = new StreamingInfo(reader); m_StreamingInfo = new StreamingInfo(reader);
} }
else else

View File

@@ -17,6 +17,12 @@
var m_UpdateMode = reader.ReadInt32(); var m_UpdateMode = reader.ReadInt32();
} }
if (version.IsTuanjie && (version > (2022, 3, 48) || version == (2022, 3, 48) && version.Build >= 7)) //2022.3.48t7(1.4.4) and up
{
var m_UpdateFrequencyMode = reader.ReadInt32();
var m_UpdateFrequency = reader.ReadSingle();
}
var m_ApplyRootMotion = reader.ReadBoolean(); var m_ApplyRootMotion = reader.ReadBoolean();
if (version == 4 && version.Minor >= 5) //4.5 and up - 5.0 down if (version == 4 && version.Minor >= 5) //4.5 and up - 5.0 down
{ {

View File

@@ -31,7 +31,7 @@ namespace AssetStudio
} }
var m_Layer = reader.ReadInt32(); var m_Layer = reader.ReadInt32();
if (version.IsTuanjie && (version > (2022, 3, 2) || (version == (2022, 3, 2) && version.Build >= 13))) //2022.3.2t13(?) and up if (version.IsTuanjie && (version > (2022, 3, 2) || (version == (2022, 3, 2) && version.Build >= 11))) //2022.3.2t11(1.1.3) and up
{ {
var m_HasEditorInfo = reader.ReadBoolean(); var m_HasEditorInfo = reader.ReadBoolean();
reader.AlignStream(); reader.AlignStream();

View File

@@ -445,43 +445,98 @@ namespace AssetStudio
public class VGPackedHierarchyNode public class VGPackedHierarchyNode
{ {
public Vector4[] LODBounds = new Vector4[8]; public Vector4[] LODBounds = new Vector4[8];
public Vector3[] BoxBoundsCenter = new Vector3[8]; public Vector3[] AABBCenter = new Vector3[8];
public uint[] MinLODError_MaxParentLODError = new uint[8]; public uint[] MinLODError_MaxParentLODError = new uint[8];
public Vector3[] BoxBoundsExtent = new Vector3[8]; public Vector3[] AABBExtent = new Vector3[8];
public uint[] ChildStartReference = new uint[8]; public uint[] ChildStartIndex = new uint[8];
public uint[] ResourcePageIndex_NumPages_GroupPartSize = new uint[8]; public uint[] PageIndex_PageCount_PageBlockCount = new uint[8];
public VGPackedHierarchyNode(BinaryReader reader) public VGPackedHierarchyNode(BinaryReader reader)
{ {
for (var i = 0; i < 8; i++) for (var i = 0; i < 8; i++)
{ {
LODBounds[i] = reader.ReadVector4(); LODBounds[i] = reader.ReadVector4();
BoxBoundsCenter[i] = reader.ReadVector3(); AABBCenter[i] = reader.ReadVector3();
MinLODError_MaxParentLODError[i] = reader.ReadUInt32(); MinLODError_MaxParentLODError[i] = reader.ReadUInt32();
BoxBoundsExtent[i] = reader.ReadVector3(); AABBExtent[i] = reader.ReadVector3();
ChildStartReference[i] = reader.ReadUInt32(); ChildStartIndex[i] = reader.ReadUInt32();
ResourcePageIndex_NumPages_GroupPartSize[i] = reader.ReadUInt32(); PageIndex_PageCount_PageBlockCount[i] = reader.ReadUInt32();
} }
} }
} }
public class VGPageStreamingState public class VGPageStreamingInfo
{ {
public uint BulkOffset; public uint offset;
public uint BulkSize; public uint wholeSize;
public uint PageSize; public uint dataSize;
public uint DependenciesStart; public uint dependencyOffset;
public uint DependenciesNum; public uint dependencyCount;
public uint Flags; public uint flags;
public VGPageStreamingState(BinaryReader reader) public VGPageStreamingInfo(BinaryReader reader)
{ {
BulkOffset = reader.ReadUInt32(); offset = reader.ReadUInt32();
BulkSize = reader.ReadUInt32(); wholeSize = reader.ReadUInt32();
PageSize = reader.ReadUInt32(); dataSize = reader.ReadUInt32();
DependenciesStart = reader.ReadUInt32(); dependencyOffset = reader.ReadUInt32();
DependenciesNum = reader.ReadUInt32(); dependencyCount = reader.ReadUInt32();
Flags = reader.ReadUInt32(); flags = reader.ReadUInt32();
}
}
public class SharedClusterData //Tuanjie
{
public SharedClusterData(ObjectReader reader, byte rev)
{
var m_LightmapUseUV1 = reader.ReadInt32();
var m_fileScale = reader.ReadSingle();
if (rev == 1)
{
var NumInputTriangles = reader.ReadUInt32();
var NumInputVertices = reader.ReadUInt32();
var NumInputMeshes = reader.ReadUInt16();
var NumInputTexCoords = reader.ReadUInt16();
var ResourceFlags = reader.ReadUInt32();
}
var rootClusterPageSize = reader.ReadInt32();
reader.Position += rootClusterPageSize; //skip byte[] rootClusterPage
if (rev == 1)
{
var imposterAtlasSize = reader.ReadInt32();
reader.Position += imposterAtlasSize * 2; //skip ushort[] imposterAtlas
}
var hierarchyNodesSize = reader.ReadInt32();
for (var i = 0; i < hierarchyNodesSize; i++)
{
var hierarchyNode = new VGPackedHierarchyNode(reader);
}
if (rev == 1)
{
var hierarchyRootOffsetsSize = reader.ReadInt32();
reader.Position += hierarchyRootOffsetsSize * 4; //skip uint[] hierarchyRootOffsets
}
var pageStreamingInfosSize = reader.ReadInt32();
for (var i = 0; i < pageStreamingInfosSize; i++)
{
var pageStreamingInfo = new VGPageStreamingInfo(reader);
}
var pageIndicesOfDependenciesSize = reader.ReadInt32();
reader.Position += pageIndicesOfDependenciesSize * 4; //skip uint[] pageIndicesOfDependencies
if (rev == 2)
{
var inputTrianglesCount = reader.ReadUInt32();
var inputVerticesCount = reader.ReadUInt32();
var inputMeshesCount = reader.ReadUInt16();
var inputTexCoordsCount = reader.ReadUInt16();
var resourceFlags = reader.ReadUInt32();
var imposterAtlasSize = reader.ReadInt32();
reader.Position += imposterAtlasSize * 2; //skip ushort[] imposterAtlas
var hierarchyRootOffsetsSize = reader.ReadInt32();
reader.Position += hierarchyRootOffsetsSize * 4; //skip uint[] hierarchyRootOffsets
}
var streamableClusterPageSize = reader.ReadInt32();
reader.Position += streamableClusterPageSize; //skip byte[] streamableClusterPageSize
} }
} }
@@ -507,6 +562,7 @@ namespace AssetStudio
public float[] m_UV6; public float[] m_UV6;
public float[] m_UV7; public float[] m_UV7;
public float[] m_Tangents; public float[] m_Tangents;
private bool m_HasVirtualGeometryMesh;
private VertexData m_VertexData; private VertexData m_VertexData;
private CompressedMesh m_CompressedMesh; private CompressedMesh m_CompressedMesh;
private StreamingInfo m_StreamData; private StreamingInfo m_StreamData;
@@ -584,35 +640,23 @@ namespace AssetStudio
var m_KeepVertices = reader.ReadBoolean(); var m_KeepVertices = reader.ReadBoolean();
var m_KeepIndices = reader.ReadBoolean(); var m_KeepIndices = reader.ReadBoolean();
} }
if (version.IsTuanjie) if (version.IsTuanjie)
{ {
var m_LightmapUseUV1 = reader.ReadInt32(); if (version < (2022, 3, 48) || (version == (2022, 3, 48) && version.Build < 3)) //2022.3.48t3(1.4.0) down
var m_fileScale = reader.ReadSingle();
var NumInputTriangles = reader.ReadUInt32();
var NumInputVertices = reader.ReadUInt32();
var NumInputMeshes = reader.ReadUInt16();
var NumInputTexCoords = reader.ReadUInt16();
var ResourceFlags = reader.ReadUInt32();
var RootClusterPageSize = reader.ReadInt32();
reader.Position += RootClusterPageSize; //skip byte[] RootClusterPage
var ImposterAtlasSize = reader.ReadInt32();
reader.Position += ImposterAtlasSize * 2; //skip ushort[] ImposterAtlas
var HierarchyNodesSize = reader.ReadInt32();
for (var i = 0; i < HierarchyNodesSize; i++)
{ {
_ = new VGPackedHierarchyNode(reader); _ = new SharedClusterData(reader, rev: 1);
} }
var HierarchyRootOffsetsSize = reader.ReadInt32(); else if (version < (2022, 3, 61) || (version == (2022, 3, 61) && version.Build < 2)) //2022.3.48t3(1.4.0) - 2022.3.61t1(1.6.0)
reader.Position += HierarchyRootOffsetsSize * 4; //skip uint[] HierarchyRootOffsets
var PageStreamingStatesSize = reader.ReadInt32();
for (var i = 0; i < PageStreamingStatesSize; i++)
{ {
_ = new VGPageStreamingState(reader); _ = new SharedClusterData(reader, rev: 2);
} }
var PageDependenciesSize = reader.ReadInt32(); else //2022.3.61t2(1.6.1) and up
reader.Position += PageDependenciesSize * 4; //skip uint[] PageDependencies {
var streamableClusterPageSize = reader.ReadInt32(); reader.AlignStream();
reader.Position += streamableClusterPageSize; //skip byte[] streamableClusterPageSize _ = new SharedClusterData(reader, rev: 3);
}
} }
reader.AlignStream(); reader.AlignStream();
@@ -756,6 +800,12 @@ namespace AssetStudio
m_StreamData = new StreamingInfo(reader); m_StreamData = new StreamingInfo(reader);
} }
if (version.IsTuanjie && (version > (2022, 3, 2) || (version == (2022, 3, 2) && version.Build >= 13))) //2022.3.2t13(1.2.0) and up
{
var m_GenerateGeometryBuffer = reader.ReadBoolean();
m_HasVirtualGeometryMesh = reader.ReadBoolean();
}
ProcessData(); ProcessData();
} }
@@ -779,7 +829,10 @@ namespace AssetStudio
DecompressCompressedMesh(); DecompressCompressedMesh();
} }
GetTriangles(); if (m_HasVirtualGeometryMesh && m_IndexBuffer.Length == 0)
Logger.Warning($"Unsupported mesh type: Virtual Geometry | PathID: {m_PathID} | Name: \"{m_Name}\"");
else
GetTriangles();
} }
private void ReadVertexData() private void ReadVertexData()

View File

@@ -63,6 +63,10 @@ namespace AssetStudio
{ {
reader.AlignStream(); reader.AlignStream();
var m_ShadingRate = reader.ReadByte(); var m_ShadingRate = reader.ReadByte();
if (version >= (2022, 3, 61)) //2022.3.61t1(1.6.0) and up
{
var m_ForceDisableGRD = reader.ReadByte();
}
} }
} }
if (version >= (2023, 2)) //2023.2 and up if (version >= (2023, 2)) //2023.2 and up

View File

@@ -97,6 +97,12 @@ namespace AssetStudio
}; };
} }
m_TextureFormat = (TextureFormat)reader.ReadInt32(); m_TextureFormat = (TextureFormat)reader.ReadInt32();
if (version.IsTuanjie && version >= (2022, 3, 62)) //2022.3.62t1(1.7.0) and up
{
var m_TextureManagerMultiFormatSettingSize = reader.ReadInt32();
reader.Position += m_TextureManagerMultiFormatSettingSize; //skip byte[] m_TextureManagerMultiFormatSetting
reader.AlignStream();
}
if (version < (5, 2)) //5.2 down if (version < (5, 2)) //5.2 down
{ {
m_MipMap = reader.ReadBoolean(); m_MipMap = reader.ReadBoolean();