2018.3.0b support

Refactor mesh read
Fixed bug
This commit is contained in:
Perfare 2018-12-05 22:35:05 +08:00
parent 98c9eea58a
commit eb13585174
13 changed files with 1006 additions and 1220 deletions

View File

@ -632,7 +632,10 @@ namespace AssetStudio
{
m_ConstantClip = new ConstantClip(reader);
}
m_Binding = new ValueArrayConstant(reader);
if (version[0] < 2018 || (version[0] == 2018 && version[1] < 3)) //2018.3 down
{
m_Binding = new ValueArrayConstant(reader);
}
}
}
@ -947,6 +950,8 @@ namespace AssetStudio
{
m_ClipBindingConstant = new AnimationClipBindingConstant(reader);
}
//m_HasGenericRootTransform 2018.3
//m_HasMotionFloatCurves 2018.3
/*int numEvents = reader.ReadInt32();
m_Events = new List<AnimationEvent>(numEvents);
for (int i = 0; i < numEvents; i++)

File diff suppressed because it is too large Load Diff

View File

@ -62,6 +62,11 @@ namespace AssetStudio
var m_RenderingLayerMask = reader.ReadUInt32();
}
if (version[0] > 2018 || (version[0] == 2018 && version[1] >= 3)) //2018.3 and up
{
var m_RendererPriority = reader.ReadInt32();
}
var m_LightmapIndex = reader.ReadUInt16();
var m_LightmapIndexDynamic = reader.ReadUInt16();
}

View File

@ -58,154 +58,6 @@ namespace AssetStudio
}
}
public class BoneWeights4
{
public float[] weight;
public int[] boneIndex;
public BoneWeights4(ObjectReader reader)
{
weight = reader.ReadSingleArray(4);
boneIndex = reader.ReadInt32Array(4);
}
}
public class StreamInfo
{
public uint channelMask;
public uint offset;
public uint stride;
public uint align;
public byte dividerOp;
public ushort frequency;
public StreamInfo() { }
public StreamInfo(ObjectReader reader)
{
var version = reader.version;
channelMask = reader.ReadUInt32();
offset = reader.ReadUInt32();
if (version[0] < 4)
{
stride = reader.ReadUInt32();
align = reader.ReadUInt32();
}
else
{
stride = reader.ReadByte();
dividerOp = reader.ReadByte();
frequency = reader.ReadUInt16();
}
}
}
public class ChannelInfo
{
public byte stream;
public byte offset;
public byte format;
public byte dimension;
public ChannelInfo(ObjectReader reader)
{
stream = reader.ReadByte();
offset = reader.ReadByte();
format = reader.ReadByte();
dimension = reader.ReadByte();
}
}
public class VertexData
{
public uint m_CurrentChannels;
public uint m_VertexCount;
public ChannelInfo[] m_Channels;
public StreamInfo[] m_Streams;
public byte[] m_DataSize;
public VertexData(ObjectReader reader)
{
var version = reader.version;
if (version[0] < 2018)//2018 down
{
m_CurrentChannels = reader.ReadUInt32();
}
m_VertexCount = reader.ReadUInt32();
if (version[0] >= 4)
{
var m_ChannelsSize = reader.ReadInt32();
m_Channels = new ChannelInfo[m_ChannelsSize];
for (int i = 0; i < m_ChannelsSize; i++)
{
m_Channels[i] = new ChannelInfo(reader);
}
}
if (version[0] < 5) //5.0 down
{
if (version[0] < 4)
{
m_Streams = new StreamInfo[4];
}
else
{
m_Streams = new StreamInfo[reader.ReadInt32()];
}
for (int i = 0; i < m_Streams.Length; i++)
{
m_Streams[i] = new StreamInfo(reader);
}
}
m_DataSize = reader.ReadBytes(reader.ReadInt32());
reader.AlignStream();
}
}
public class SubMesh
{
public uint firstByte;
public uint indexCount;
public int topology;
public uint triangleCount;
public uint baseVertex;
public uint firstVertex;
public uint vertexCount;
public AABB localAABB;
public SubMesh(ObjectReader reader)
{
var version = reader.version;
firstByte = reader.ReadUInt32();
indexCount = reader.ReadUInt32();
topology = reader.ReadInt32();
if (version[0] < 4) //4.0 down
{
triangleCount = reader.ReadUInt32();
}
if (version[0] > 2017 || (version[0] == 2017 && version[1] >= 3)) //2017.3 and up
{
baseVertex = reader.ReadUInt32();
}
if (version[0] >= 3) //3.0 and up
{
firstVertex = reader.ReadUInt32();
vertexCount = reader.ReadUInt32();
localAABB = new AABB(reader);
}
}
}
public class SpriteRenderData
{
public PPtr<Texture2D> texture;

View File

@ -7,74 +7,37 @@ using System.Runtime.InteropServices;
namespace AssetStudio
{
public sealed class Texture2D : Texture
public class StreamingInfo
{
public int m_Width;
public int m_Height;
public int m_CompleteImageSize;
public TextureFormat m_TextureFormat;
public bool m_MipMap;
public int m_MipCount;
public bool m_IsReadable;
public bool m_ReadAllowed;
public int m_ImageCount;
public int m_TextureDimension;
//m_TextureSettings
public int m_FilterMode;
public int m_Aniso;
public float m_MipBias;
public int m_WrapMode;
public int m_LightmapFormat;
public int m_ColorSpace;
//image dataa
public int image_data_size;
public Lazy<byte[]> image_data;
//m_StreamData
public uint offset;
public uint size;
public string path;
public Texture2D(ObjectReader reader) : base(reader)
public StreamingInfo(ObjectReader reader)
{
m_Width = reader.ReadInt32();
m_Height = reader.ReadInt32();
m_CompleteImageSize = reader.ReadInt32();
m_TextureFormat = (TextureFormat)reader.ReadInt32();
offset = reader.ReadUInt32();
size = reader.ReadUInt32();
path = reader.ReadAlignedString();
}
}
if (version[0] < 5 || (version[0] == 5 && version[1] < 2))
{
m_MipMap = reader.ReadBoolean();
}
else
{
m_MipCount = reader.ReadInt32();
}
public class GLTextureSettings
{
public int m_FilterMode;
public int m_Aniso;
public float m_MipBias;
public int m_WrapMode;
public GLTextureSettings(ObjectReader reader)
{
var version = reader.version;
m_IsReadable = reader.ReadBoolean(); //2.6.0 and up
m_ReadAllowed = reader.ReadBoolean(); //3.0.0 - 5.4
//m_StreamingMipmaps 2018.2 and up
reader.AlignStream();
if (version[0] > 2018 || (version[0] == 2018 && version[1] >= 2)) //2018.2 and up
{
var m_StreamingMipmapsPriority = reader.ReadInt32();
}
else if (HasStructMember("m_StreamingMipmapsPriority")) //will fix in some patch version bundle
{
var m_StreamingMipmapsPriority = reader.ReadInt32();
}
if (HasStructMember("m_StreamingGroupID")) //What the hell is this?
{
var m_StreamingGroupID = reader.ReadUInt32();
}
m_ImageCount = reader.ReadInt32();
m_TextureDimension = reader.ReadInt32();
//m_TextureSettings
m_FilterMode = reader.ReadInt32();
m_Aniso = reader.ReadInt32();
m_MipBias = reader.ReadSingle();
if (version[0] >= 2017)//2017.x and up
{
int m_WrapU = reader.ReadInt32();
m_WrapMode = reader.ReadInt32(); //m_WrapU
int m_WrapV = reader.ReadInt32();
int m_WrapW = reader.ReadInt32();
}
@ -82,29 +45,63 @@ namespace AssetStudio
{
m_WrapMode = reader.ReadInt32();
}
if (version[0] >= 3)
}
}
public sealed class Texture2D : Texture
{
public int m_Width;
public int m_Height;
public TextureFormat m_TextureFormat;
public bool m_MipMap;
public int m_MipCount;
public GLTextureSettings m_TextureSettings;
public Lazy<byte[]> image_data;
public StreamingInfo m_StreamData;
public Texture2D(ObjectReader reader) : base(reader)
{
m_Width = reader.ReadInt32();
m_Height = reader.ReadInt32();
var m_CompleteImageSize = reader.ReadInt32();
m_TextureFormat = (TextureFormat)reader.ReadInt32();
if (version[0] < 5 || (version[0] == 5 && version[1] < 2)) //5.2 down
{
m_LightmapFormat = reader.ReadInt32();
if (version[0] >= 4 || version[1] >= 5)//3.5.0 and up
{
m_ColorSpace = reader.ReadInt32();
}
m_MipMap = reader.ReadBoolean();
}
image_data_size = reader.ReadInt32();
else
{
m_MipCount = reader.ReadInt32();
}
var m_IsReadable = reader.ReadBoolean(); //2.6.0 and up
var m_ReadAllowed = reader.ReadBoolean(); //3.0.0 - 5.4
//bool m_StreamingMipmaps 2018.2 and up
reader.AlignStream();
if (version[0] > 2018 || (version[0] == 2018 && version[1] >= 2)) //2018.2 and up
{
var m_StreamingMipmapsPriority = reader.ReadInt32();
}
var m_ImageCount = reader.ReadInt32();
var m_TextureDimension = reader.ReadInt32();
m_TextureSettings = new GLTextureSettings(reader);
if (version[0] >= 3) //3.0 and up
{
var m_LightmapFormat = reader.ReadInt32();
}
if (version[0] > 3 || (version[0] == 3 && version[1] >= 5)) //3.5.0 and up
{
var m_ColorSpace = reader.ReadInt32();
}
var image_data_size = reader.ReadInt32();
if (image_data_size == 0 && ((version[0] == 5 && version[1] >= 3) || version[0] > 5))//5.3.0 and up
{
offset = reader.ReadUInt32();
size = reader.ReadUInt32();
image_data_size = (int)size;
path = reader.ReadAlignedString();
m_StreamData = new StreamingInfo(reader);
}
ResourceReader resourceReader;
if (!string.IsNullOrEmpty(path))
if (!string.IsNullOrEmpty(m_StreamData?.path))
{
resourceReader = new ResourceReader(path, assetsFile, offset, image_data_size);
resourceReader = new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, (int)m_StreamData.size);
}
else
{

View File

@ -76,7 +76,7 @@ namespace AssetStudio
{
public Vector3 Position { get; set; }
public float[] Weights { get; set; }
public byte[] BoneIndices { get; set; }
public int[] BoneIndices { get; set; }
public Vector3 Normal { get; set; }
public float[] UV { get; set; }
public Vector4 Tangent { get; set; }

View File

@ -554,8 +554,8 @@ namespace AssetStudio
if (hasBones && vertex->BoneIndices != nullptr)
{
array<unsigned char>^ boneIndices = vertex->BoneIndices;
array<float>^ weights4 = vertex->Weights;
auto boneIndices = vertex->BoneIndices;
auto weights4 = vertex->Weights;
for (int k = 0; k < weights4->Length; k++)
{
if (boneIndices[k] < boneList->Count && weights4[k] > 0)

View File

@ -713,14 +713,14 @@ namespace AssetStudioGUI
if (bitmap != null)
{
assetItem.InfoText = $"Width: {m_Texture2D.m_Width}\nHeight: {m_Texture2D.m_Height}\nFormat: {m_Texture2D.m_TextureFormat}";
switch (m_Texture2D.m_FilterMode)
switch (m_Texture2D.m_TextureSettings.m_FilterMode)
{
case 0: assetItem.InfoText += "\nFilter Mode: Point "; break;
case 1: assetItem.InfoText += "\nFilter Mode: Bilinear "; break;
case 2: assetItem.InfoText += "\nFilter Mode: Trilinear "; break;
}
assetItem.InfoText += $"\nAnisotropic level: {m_Texture2D.m_Aniso}\nMip map bias: {m_Texture2D.m_MipBias}";
switch (m_Texture2D.m_WrapMode)
assetItem.InfoText += $"\nAnisotropic level: {m_Texture2D.m_TextureSettings.m_Aniso}\nMip map bias: {m_Texture2D.m_TextureSettings.m_MipBias}";
switch (m_Texture2D.m_TextureSettings.m_WrapMode)
{
case 0: assetItem.InfoText += "\nWrap mode: Repeat"; break;
case 1: assetItem.InfoText += "\nWrap mode: Clamp"; break;
@ -1061,10 +1061,14 @@ namespace AssetStudioGUI
#endregion
glControl1.Visible = true;
createVAO();
StatusStripUpdate("Using OpenGL Version: " + GL.GetString(StringName.Version) + "\n"
+ "'Mouse Left'=Rotate | 'Mouse Right'=Move | 'Mouse Wheel'=Zoom \n"
+ "'Ctrl W'=Wireframe | 'Ctrl S'=Shade | 'Ctrl N'=ReNormal ");
}
else
{
StatusStripUpdate("Unable to preview this mesh");
}
StatusStripUpdate("Using OpenGL Version: " + GL.GetString(StringName.Version) + "\n"
+ "'Mouse Left'=Rotate | 'Mouse Right'=Move | 'Mouse Wheel'=Zoom \n"
+ "'Ctrl W'=Wireframe | 'Ctrl S'=Shade | 'Ctrl N'=ReNormal ");
}
private void PreviewSprite(AssetItem assetItem, Sprite m_Sprite)

View File

@ -190,7 +190,7 @@ namespace AssetStudioGUI
#region Face
int sum = 0;
for (var i = 0; i < m_Mesh.m_SubMeshes.Count; i++)
for (var i = 0; i < m_Mesh.m_SubMeshes.Length; i++)
{
sb.AppendLine($"g {m_Mesh.m_Name}_{i}");
int indexCount = (int)m_Mesh.m_SubMeshes[i].indexCount;

View File

@ -115,8 +115,8 @@ namespace AssetStudioGUI
assetItem.Text = m_GameObject.m_Name;
break;
case Texture2D m_Texture2D:
if (!string.IsNullOrEmpty(m_Texture2D.path))
assetItem.FullSize = asset.byteSize + m_Texture2D.size;
if (!string.IsNullOrEmpty(m_Texture2D.m_StreamData?.path))
assetItem.FullSize = asset.byteSize + m_Texture2D.m_StreamData.size;
assetItem.Text = m_Texture2D.m_Name;
exportable = true;
break;

View File

@ -263,7 +263,7 @@ namespace AssetStudio
combine = true;
}
int firstFace = 0;
for (int i = 0; i < mesh.m_SubMeshes.Count; i++)
for (int i = 0; i < mesh.m_SubMeshes.Length; i++)
{
int numFaces = (int)mesh.m_SubMeshes[i].indexCount / 3;
if (subHashSet.Count > 0 && !subHashSet.Contains(i))
@ -338,12 +338,12 @@ namespace AssetStudio
if (mesh.m_Skin?.Length > 0)
{
var inf = mesh.m_Skin[j];
iVertex.BoneIndices = new byte[inf.Count];
iVertex.Weights = new float[inf.Count];
for (var k = 0; k < inf.Count; k++)
iVertex.BoneIndices = new int[4];
iVertex.Weights = new float[4];
for (var k = 0; k < 4; k++)
{
iVertex.BoneIndices[k] = (byte)inf[k].boneIndex;
iVertex.Weights[k] = inf[k].weight;
iVertex.BoneIndices[k] = inf.boneIndex[k];
iVertex.Weights[k] = inf.weight[k];
}
}
iSubmesh.VertexList.Add(iVertex);
@ -490,7 +490,7 @@ namespace AssetStudio
int shapeIdx = mesh.m_Shapes.channels[i].frameIndex + frameIdx;
keyframe.VertexList = new List<ImportedVertex>((int)mesh.m_Shapes.shapes[shapeIdx].vertexCount);
keyframe.MorphedVertexIndices = new List<ushort>((int)mesh.m_Shapes.shapes[shapeIdx].vertexCount);
keyframe.Weight = shapeIdx < mesh.m_Shapes.fullWeights.Count ? mesh.m_Shapes.fullWeights[shapeIdx] : 100f;
keyframe.Weight = shapeIdx < mesh.m_Shapes.fullWeights.Length ? mesh.m_Shapes.fullWeights[shapeIdx] : 100f;
int lastVertIndex = (int)(mesh.m_Shapes.shapes[shapeIdx].firstVertex + mesh.m_Shapes.shapes[shapeIdx].vertexCount);
for (int j = (int)mesh.m_Shapes.shapes[shapeIdx].firstVertex; j < lastVertIndex; j++)
{

View File

@ -138,7 +138,6 @@ namespace AssetStudio
private static Vector2[][] GetTriangles(VertexData m_VertexData, SubMesh[] m_SubMeshes, byte[] m_IndexBuffer)
{
var triangles = new List<Vector2[]>();
GetStreams(m_VertexData);
var m_Channel = m_VertexData.m_Channels[0]; //kShaderChannelVertex
var m_Stream = m_VertexData.m_Streams[m_Channel.stream];
using (BinaryReader vertexReader = new BinaryReader(new MemoryStream(m_VertexData.m_DataSize)),
@ -170,62 +169,5 @@ namespace AssetStudio
}
return triangles.ToArray();
}
private static void GetStreams(VertexData vertexData)
{
var m_Channels = vertexData.m_Channels;
var streamCount = m_Channels.Max(x => x.stream) + 1;
var m_Streams = new StreamInfo[streamCount];
uint offset = 0;
for (int s = 0; s < streamCount; s++)
{
uint chnMask = 0;
uint stride = 0;
for (int chn = 0; chn < m_Channels.Length; chn++)
{
var m_Channel = m_Channels[chn];
if (m_Channel.stream == s)
{
if (m_Channel.dimension > 0)
{
chnMask |= 1u << chn;
stride += m_Channel.dimension * GetChannelFormatSize(m_Channel.format);
}
}
}
m_Streams[s] = new StreamInfo
{
channelMask = chnMask,
offset = offset,
stride = stride,
dividerOp = 0,
frequency = 0
};
offset += vertexData.m_VertexCount * stride;
//static size_t AlignStreamSize (size_t size) { return (size + (kVertexStreamAlign-1)) & ~(kVertexStreamAlign-1); }
offset = (offset + (16u - 1u)) & ~(16u - 1u);
}
vertexData.m_Streams = m_Streams;
}
private static uint GetChannelFormatSize(int format)
{
switch (format)
{
case 0: //kChannelFormatFloat
return 4u;
case 1: //kChannelFormatFloat16
return 2u;
case 2: //kChannelFormatColor, in 4.x is size 4
return 1u;
case 3: //kChannelFormatByte
return 1u;
case 11: //kChannelFormatInt32
return 4u;
default:
return 0;
}
}
}
}

View File

@ -86,8 +86,10 @@ namespace AssetStudio
public Texture2DConverter(Texture2D m_Texture2D)
{
image_data_size = m_Texture2D.image_data_size;
image_data = m_Texture2D.image_data.Value;
var image_data_value = m_Texture2D.image_data.Value;
image_data_size = image_data_value.Length;
image_data = new byte[image_data_size];
Buffer.BlockCopy(image_data_value, 0, image_data, 0, image_data_size);
m_Width = m_Texture2D.m_Width;
m_Height = m_Texture2D.m_Height;
m_TextureFormat = m_Texture2D.m_TextureFormat;