This commit is contained in:
Perfare 2019-08-12 04:17:06 +08:00
parent c6b7e04c47
commit 1d2c0ab6cb
1 changed files with 165 additions and 31 deletions

View File

@ -166,19 +166,19 @@ namespace AssetStudio
if (version[0] < 4) //4.0 down
{
GetChannels();
GetChannels(version);
}
}
else //5.0 and up
{
GetStreams();
GetStreams(version);
}
m_DataSize = reader.ReadBytes(reader.ReadInt32());
reader.AlignStream();
}
private void GetStreams()
private void GetStreams(int[] version)
{
var streamCount = m_Channels.Max(x => x.stream) + 1;
m_Streams = new StreamInfo[streamCount];
@ -195,7 +195,7 @@ namespace AssetStudio
if (m_Channel.dimension > 0)
{
chnMask |= 1u << chn;
stride += m_Channel.dimension * MeshHelper.GetChannelFormatSize(m_Channel.format);
stride += m_Channel.dimension * MeshHelper.GetFormatSize(version, m_Channel.format);
}
}
}
@ -213,7 +213,7 @@ namespace AssetStudio
}
}
private void GetChannels()
private void GetChannels(int[] version)
{
m_Channels = new ChannelInfo[6];
for (int i = 0; i < 6; i++)
@ -253,7 +253,7 @@ namespace AssetStudio
m_Channel.dimension = 4;
break;
}
offset += (byte)(m_Channel.dimension * MeshHelper.GetChannelFormatSize(m_Channel.format));
offset += (byte)(m_Channel.dimension * MeshHelper.GetFormatSize(version, m_Channel.format));
}
}
}
@ -705,7 +705,7 @@ namespace AssetStudio
m_Channel.dimension = 4;
}
var componentByteSize = (int)MeshHelper.GetChannelFormatSize(m_Channel.format);
var componentByteSize = (int)MeshHelper.GetFormatSize(version, m_Channel.format);
var componentBytes = new byte[m_VertexCount * m_Channel.dimension * componentByteSize];
for (int v = 0; v < m_VertexCount; v++)
{
@ -730,8 +730,8 @@ namespace AssetStudio
int[] componentsIntArray = null;
float[] componentsFloatArray = null;
if (m_Channel.format == 10 || m_Channel.format == 11)
componentsIntArray = MeshHelper.BytesToIntArray(componentBytes);
if (MeshHelper.IsIntFormat(version, m_Channel.format))
componentsIntArray = MeshHelper.BytesToIntArray(componentBytes, componentByteSize);
else
componentsFloatArray = MeshHelper.BytesToFloatArray(componentBytes, componentByteSize);
@ -1132,26 +1132,149 @@ namespace AssetStudio
public static class MeshHelper
{
public static uint GetChannelFormatSize(int format)
private enum VertexChannelFormat
{
switch (format)
kChannelFormatFloat,
kChannelFormatFloat16,
kChannelFormatColor,
kChannelFormatByte,
kChannelFormatUInt32
}
private enum VertexFormat
{
kVertexFormatFloat,
kVertexFormatFloat16,
kVertexFormatColor,
kVertexFormatUNorm8,
kVertexFormatSNorm8,
kVertexFormatUNorm16,
kVertexFormatSNorm16,
kVertexFormatUInt8,
kVertexFormatSInt8,
kVertexFormatUInt16,
kVertexFormatSInt16,
kVertexFormatUInt32,
kVertexFormatSInt32
}
private enum VertexFormatV2019
{
kVertexFormatFloat,
kVertexFormatFloat16,
kVertexFormatUNorm8,
kVertexFormatSNorm8,
kVertexFormatUNorm16,
kVertexFormatSNorm16,
kVertexFormatUInt8,
kVertexFormatSInt8,
kVertexFormatUInt16,
kVertexFormatSInt16,
kVertexFormatUInt32,
kVertexFormatSInt32
}
public static uint GetFormatSize(int[] version, int format)
{
if (version[0] < 2017)
{
case 0: //kChannelFormatFloat
return 4u;
case 1: //kChannelFormatFloat16
return 2u;
case 2: //kChannelFormatColor
return 1u;
case 3: //kChannelFormatByte
return 1u;
case 4: //kChannelFormatUInt32
return 4u;
case 10: //kChannelFormatInt32
return 4u;
case 11: //kChannelFormatInt32
return 4u;
default:
return 0;
switch ((VertexChannelFormat)format)
{
case VertexChannelFormat.kChannelFormatFloat:
return 4u;
case VertexChannelFormat.kChannelFormatFloat16:
return 2u;
case VertexChannelFormat.kChannelFormatColor: //in 4.x is size 4
return 1u;
case VertexChannelFormat.kChannelFormatByte:
return 1u;
case VertexChannelFormat.kChannelFormatUInt32: //in 5.x
return 4u;
default:
throw new ArgumentOutOfRangeException(nameof(format), format, null);
}
}
else if (version[0] < 2019)
{
switch ((VertexFormat)format)
{
case VertexFormat.kVertexFormatFloat:
return 4u;
case VertexFormat.kVertexFormatFloat16:
return 2u;
case VertexFormat.kVertexFormatColor:
return 1u;
case VertexFormat.kVertexFormatUNorm8:
return 1u;
case VertexFormat.kVertexFormatSNorm8:
return 1u;
case VertexFormat.kVertexFormatUNorm16:
return 2u;
case VertexFormat.kVertexFormatSNorm16:
return 2u;
case VertexFormat.kVertexFormatUInt8:
return 1u;
case VertexFormat.kVertexFormatSInt8:
return 1u;
case VertexFormat.kVertexFormatUInt16:
return 2u;
case VertexFormat.kVertexFormatSInt16:
return 2u;
case VertexFormat.kVertexFormatUInt32:
return 4u;
case VertexFormat.kVertexFormatSInt32:
return 4u;
default:
throw new ArgumentOutOfRangeException(nameof(format), format, null);
}
}
else
{
switch ((VertexFormatV2019)format)
{
case VertexFormatV2019.kVertexFormatFloat:
return 4u;
case VertexFormatV2019.kVertexFormatFloat16:
return 2u;
case VertexFormatV2019.kVertexFormatUNorm8:
return 1u;
case VertexFormatV2019.kVertexFormatSNorm8:
return 1u;
case VertexFormatV2019.kVertexFormatUNorm16:
return 2u;
case VertexFormatV2019.kVertexFormatSNorm16:
return 2u;
case VertexFormatV2019.kVertexFormatUInt8:
return 1u;
case VertexFormatV2019.kVertexFormatSInt8:
return 1u;
case VertexFormatV2019.kVertexFormatUInt16:
return 2u;
case VertexFormatV2019.kVertexFormatSInt16:
return 2u;
case VertexFormatV2019.kVertexFormatUInt32:
return 4u;
case VertexFormatV2019.kVertexFormatSInt32:
return 4u;
default:
throw new ArgumentOutOfRangeException(nameof(format), format, null);
}
}
}
public static bool IsIntFormat(int[] version, int format)
{
if (version[0] < 2017)
{
return format == 4;
}
else if (version[0] < 2019)
{
return format >= 7;
}
else
{
return format >= 6;
}
}
@ -1178,12 +1301,23 @@ namespace AssetStudio
return result;
}
public static int[] BytesToIntArray(byte[] inputBytes)
public static int[] BytesToIntArray(byte[] inputBytes, int size)
{
var result = new int[inputBytes.Length / 4];
for (int i = 0; i < inputBytes.Length / 4; i++)
var result = new int[inputBytes.Length / size];
for (int i = 0; i < inputBytes.Length / size; i++)
{
result[i] = BitConverter.ToInt32(inputBytes, i * 4);
switch (size)
{
case 1:
result[i] = inputBytes[i];
break;
case 2:
result[i] = BitConverter.ToInt16(inputBytes, i * 2);
break;
case 4:
result[i] = BitConverter.ToInt32(inputBytes, i * 4);
break;
}
}
return result;
}