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
{
WeixinMiniGame = 47,
MiniGame = 47,
OpenHarmony,
HMIAndroid,
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 Clip data;
@ -697,6 +736,7 @@ namespace AssetStudio
public DenseClip m_DenseClip;
public ConstantClip m_ConstantClip;
public ValueArrayConstant m_Binding;
public ACLClip m_ACLClip;
public Clip() { }
@ -713,6 +753,10 @@ namespace AssetStudio
{
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()
@ -1174,21 +1218,32 @@ namespace AssetStudio
}
if (version >= 4)//4.0 and up
{
m_MuscleClipSize = reader.ReadUInt32(); //m_AnimDataSize (Tuanjie)
if (!version.IsTuanjie)
if (version.IsTuanjie && version >= (2022, 3, 61)) //2022.3.61t1(1.6.0) and up
{
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);
if (version.IsTuanjie) //2022.3.61t1(1.6.0) and up
{
m_StreamingInfo = new StreamingInfo(reader);
}
}
else if (m_MuscleClipSize > 0)
{
if (!m_Legacy)
{
_ = 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);
}
else
{
{
m_EulerCurves = Vector3CurveList(reader);
m_PositionCurves = Vector3CurveList(reader);
m_ScaleCurves = Vector3CurveList(reader);

View File

@ -17,6 +17,12 @@
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();
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();
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();
reader.AlignStream();

View File

@ -445,43 +445,98 @@ namespace AssetStudio
public class VGPackedHierarchyNode
{
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 Vector3[] BoxBoundsExtent = new Vector3[8];
public uint[] ChildStartReference = new uint[8];
public uint[] ResourcePageIndex_NumPages_GroupPartSize = new uint[8];
public Vector3[] AABBExtent = new Vector3[8];
public uint[] ChildStartIndex = new uint[8];
public uint[] PageIndex_PageCount_PageBlockCount = new uint[8];
public VGPackedHierarchyNode(BinaryReader reader)
{
for (var i = 0; i < 8; i++)
{
LODBounds[i] = reader.ReadVector4();
BoxBoundsCenter[i] = reader.ReadVector3();
AABBCenter[i] = reader.ReadVector3();
MinLODError_MaxParentLODError[i] = reader.ReadUInt32();
BoxBoundsExtent[i] = reader.ReadVector3();
ChildStartReference[i] = reader.ReadUInt32();
ResourcePageIndex_NumPages_GroupPartSize[i] = reader.ReadUInt32();
AABBExtent[i] = reader.ReadVector3();
ChildStartIndex[i] = reader.ReadUInt32();
PageIndex_PageCount_PageBlockCount[i] = reader.ReadUInt32();
}
}
}
public class VGPageStreamingState
public class VGPageStreamingInfo
{
public uint BulkOffset;
public uint BulkSize;
public uint PageSize;
public uint DependenciesStart;
public uint DependenciesNum;
public uint Flags;
public uint offset;
public uint wholeSize;
public uint dataSize;
public uint dependencyOffset;
public uint dependencyCount;
public uint flags;
public VGPageStreamingState(BinaryReader reader)
public VGPageStreamingInfo(BinaryReader reader)
{
BulkOffset = reader.ReadUInt32();
BulkSize = reader.ReadUInt32();
PageSize = reader.ReadUInt32();
DependenciesStart = reader.ReadUInt32();
DependenciesNum = reader.ReadUInt32();
Flags = reader.ReadUInt32();
offset = reader.ReadUInt32();
wholeSize = reader.ReadUInt32();
dataSize = reader.ReadUInt32();
dependencyOffset = reader.ReadUInt32();
dependencyCount = 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_UV7;
public float[] m_Tangents;
private bool m_HasVirtualGeometryMesh;
private VertexData m_VertexData;
private CompressedMesh m_CompressedMesh;
private StreamingInfo m_StreamData;
@ -584,35 +640,23 @@ namespace AssetStudio
var m_KeepVertices = reader.ReadBoolean();
var m_KeepIndices = reader.ReadBoolean();
}
if (version.IsTuanjie)
{
var m_LightmapUseUV1 = reader.ReadInt32();
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++)
if (version < (2022, 3, 48) || (version == (2022, 3, 48) && version.Build < 3)) //2022.3.48t3(1.4.0) down
{
_ = new VGPackedHierarchyNode(reader);
_ = new SharedClusterData(reader, rev: 1);
}
var HierarchyRootOffsetsSize = reader.ReadInt32();
reader.Position += HierarchyRootOffsetsSize * 4; //skip uint[] HierarchyRootOffsets
var PageStreamingStatesSize = reader.ReadInt32();
for (var i = 0; i < PageStreamingStatesSize; i++)
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)
{
_ = new VGPageStreamingState(reader);
_ = new SharedClusterData(reader, rev: 2);
}
var PageDependenciesSize = reader.ReadInt32();
reader.Position += PageDependenciesSize * 4; //skip uint[] PageDependencies
var streamableClusterPageSize = reader.ReadInt32();
reader.Position += streamableClusterPageSize; //skip byte[] streamableClusterPageSize
else //2022.3.61t2(1.6.1) and up
{
reader.AlignStream();
_ = new SharedClusterData(reader, rev: 3);
}
}
reader.AlignStream();
@ -756,6 +800,12 @@ namespace AssetStudio
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();
}
@ -779,7 +829,10 @@ namespace AssetStudio
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()

View File

@ -63,6 +63,10 @@ namespace AssetStudio
{
reader.AlignStream();
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

View File

@ -97,6 +97,12 @@ namespace AssetStudio
};
}
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
{
m_MipMap = reader.ReadBoolean();