Fixed bug

This commit is contained in:
Perfare 2018-07-15 03:36:51 +08:00
parent d39e24246e
commit 380afbf295

View File

@ -257,7 +257,7 @@ namespace AssetStudio
} }
} }
public float bytesToFloat(byte[] inputBytes) private float BytesToFloat(byte[] inputBytes)
{ {
float result = 0; float result = 0;
if (reader.endian == EndianType.BigEndian) { Array.Reverse(inputBytes); } if (reader.endian == EndianType.BigEndian) { Array.Reverse(inputBytes); }
@ -278,7 +278,7 @@ namespace AssetStudio
return result; return result;
} }
public uint[] UnpackBitVector(PackedBitVector pakData) private static uint[] UnpackBitVector(PackedBitVector pakData)
{ {
uint[] unpackedVectors = new uint[pakData.m_NumItems]; uint[] unpackedVectors = new uint[pakData.m_NumItems];
//int bitmax = 0;//used to convert int value to float //int bitmax = 0;//used to convert int value to float
@ -417,6 +417,69 @@ namespace AssetStudio
return unpackedVectors; return unpackedVectors;
} }
private static int GetChannelFormatLength(int format)
{
switch (format)
{
case 0: //float
return 4;
case 1: //half float
return 2;
case 2: //byte float
return 1;
case 11: //int
return 4;
default:
return 0;
}
}
private static float[] BytesToFloatArray(byte[] inputBytes, int size)
{
var result = new float[inputBytes.Length / size];
for (int i = 0; i < inputBytes.Length / size; i++)
{
float value = 0f;
switch (size)
{
case 1:
value = inputBytes[i] / 255.0f;
break;
case 2:
value = System.Half.ToHalf(inputBytes, i * 2);
break;
case 4:
value = BitConverter.ToSingle(inputBytes, i * 4);
break;
}
result[i] = value;
}
return result;
}
private static int[] BytesToIntArray(byte[] inputBytes)
{
var result = new int[inputBytes.Length / 4];
for (int i = 0; i < inputBytes.Length / 4; i++)
{
result[i] = BitConverter.ToInt32(inputBytes, i * 4);
}
return result;
}
private void InitMSkin()
{
m_Skin = new List<BoneInfluence>[m_VertexCount];
for (int i = 0; i < m_VertexCount; i++)
{
m_Skin[i] = new List<BoneInfluence>(4);
for (int j = 0; j < 4; j++)
{
m_Skin[i].Add(new BoneInfluence());
}
}
}
public Mesh(AssetPreloadData preloadData, bool readSwitch) public Mesh(AssetPreloadData preloadData, bool readSwitch)
{ {
var version = preloadData.sourceFile.version; var version = preloadData.sourceFile.version;
@ -653,7 +716,7 @@ namespace AssetStudio
m_Skin[s] = new List<BoneInfluence>(); m_Skin[s] = new List<BoneInfluence>();
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
{ {
m_Skin[s].Add(new BoneInfluence() {weight = reader.ReadSingle()}); m_Skin[s].Add(new BoneInfluence() { weight = reader.ReadSingle() });
} }
for (int i = 0; i < 4; i++) for (int i = 0; i < 4; i++)
@ -738,7 +801,7 @@ namespace AssetStudio
for (int s = 0; s < m_Streams.Length; s++) for (int s = 0; s < m_Streams.Length; s++)
{ {
m_Streams[s] = new StreamInfo(); m_Streams[s] = new StreamInfo();
m_Streams[s].channelMask = new BitArray(new int[1] { reader.ReadInt32() }); m_Streams[s].channelMask = new BitArray(new[] { reader.ReadInt32() });
m_Streams[s].offset = reader.ReadInt32(); m_Streams[s].offset = reader.ReadInt32();
m_Streams[s].stride = reader.ReadByte(); m_Streams[s].stride = reader.ReadByte();
m_Streams[s].dividerOp = reader.ReadByte(); m_Streams[s].dividerOp = reader.ReadByte();
@ -747,59 +810,47 @@ namespace AssetStudio
} }
} }
#endregion #endregion
//actual Vertex Buffer if (version[0] >= 5) //ComputeCompressedStreams
byte[] m_DataSize = new byte[reader.ReadInt32()];
reader.Read(m_DataSize, 0, m_DataSize.Length);
if (version[0] >= 5) //create streams
{ {
m_Streams = new StreamInfo[streamCount]; m_Streams = new StreamInfo[streamCount];
for (int s = 0; s < streamCount; s++) int offset = 0;
for (int str = 0; str < streamCount; str++)
{ {
m_Streams[s] = new StreamInfo(); int chnMask = 0;
m_Streams[s].offset = 0; int stride = 0;
m_Streams[s].stride = 0; for (int chn = 0; chn < m_Channels.Length; chn++)
uint chnMask = 0;
for (var chn = 0; chn < m_Channels.Length; chn++)
{ {
var m_Channel = m_Channels[chn]; var m_Channel = m_Channels[chn];
if (m_Channel.stream == s) if (m_Channel.stream == str)
{ {
if (m_Channel.dimension > 0) if (m_Channel.dimension > 0)
{ {
chnMask |= 1u << chn; chnMask |= 1 << chn;
stride += m_Channel.dimension * GetChannelFormatLength(m_Channel.format);
} }
m_Streams[s].stride += m_Channel.dimension * (4 / (int)Math.Pow(2, m_Channel.format));
} }
} }
m_Streams[str] = new StreamInfo
if (s > 0)
{ {
m_Streams[s].offset = m_Streams[s - 1].offset + m_Streams[s - 1].stride * m_VertexCount; channelMask = new BitArray(new[] { chnMask }),
//sometimes there are 8 bytes between streams offset = offset,
//this is NOT an alignment, even if sometimes it may seem so stride = stride,
dividerOp = 0,
if (streamCount >= 2) frequency = 0
{ };
m_Streams[s].offset = m_DataSize.Length - m_Streams[s].stride * m_VertexCount; offset += m_VertexCount * stride + ((m_VertexCount & 1) != 0 ? 8 : 0);
}
/*var absoluteOffset = a_Stream.Position + 4 + m_Streams[s].offset;
if ((absoluteOffset % m_Streams[s].stride) != 0)
{
m_Streams[s].offset += m_Streams[s].stride - (int)(absoluteOffset % m_Streams[s].stride);
}*/
}
m_Streams[s].channelMask = new BitArray(new[] { (int)chnMask });
} }
} }
//actual Vertex Buffer
byte[] m_DataSize = new byte[reader.ReadInt32()];
reader.Read(m_DataSize, 0, m_DataSize.Length);
#endregion #endregion
#region compute FvF #region compute FvF
int componentByteSize = 0; int componentByteSize = 0;
byte[] componentBytes; byte[] componentBytes;
float[] componentsArray; float[] componentsArray = null;
#region 4.0.0 and later #region 4.0.0 and later
if (m_Channels != null) if (m_Channels != null)
@ -812,7 +863,7 @@ namespace AssetStudio
{ {
var m_Stream = m_Streams[m_Channel.stream]; var m_Stream = m_Streams[m_Channel.stream];
for (int b = 0; b < 8; b++) for (int b = 0; b < 32; b++)
{ {
if (m_Stream.channelMask.Get(b)) if (m_Stream.channelMask.Get(b))
{ {
@ -822,24 +873,9 @@ namespace AssetStudio
m_Channel.dimension = 4; m_Channel.dimension = 4;
} }
componentByteSize = 4 / (int)Math.Pow(2, m_Channel.format); int[] componentsIntArray = null;
componentByteSize = GetChannelFormatLength(m_Channel.format);
/*switch (m_Channel.format) componentBytes = new byte[m_VertexCount * m_Channel.dimension * componentByteSize];
{
case 0: //32bit
valueBufferSize = 4;
break;
case 1: //16bit
valueBufferSize = 2;
break;
case 2: //8bit
valueBufferSize = 1;
m_Channel.dimension = 4;//in older versions this is 1, as in 1 color with 4 components
break;
}*/
componentBytes = new byte[componentByteSize];
componentsArray = new float[m_VertexCount * m_Channel.dimension];
for (int v = 0; v < m_VertexCount; v++) for (int v = 0; v < m_VertexCount; v++)
{ {
@ -847,24 +883,71 @@ namespace AssetStudio
for (int d = 0; d < m_Channel.dimension; d++) for (int d = 0; d < m_Channel.dimension; d++)
{ {
int componentOffset = vertexOffset + componentByteSize * d; int componentOffset = vertexOffset + componentByteSize * d;
Buffer.BlockCopy(m_DataSize, componentOffset, componentBytes, 0, componentByteSize); Buffer.BlockCopy(m_DataSize, componentOffset, componentBytes, componentByteSize * (v * m_Channel.dimension + d), componentByteSize);
componentsArray[v * m_Channel.dimension + d] = bytesToFloat(componentBytes);
} }
} }
if (m_Channel.format == 11)
componentsIntArray = BytesToIntArray(componentBytes);
else
componentsArray = BytesToFloatArray(componentBytes, componentByteSize);
switch (b) switch (b)
{ {
case 0: m_Vertices = componentsArray; break; case 0:
case 1: m_Normals = componentsArray; break; m_Vertices = componentsArray;
case 2: m_Colors = componentsArray; break; break;
case 3: m_UV1 = componentsArray; break; case 1:
case 4: m_UV2 = componentsArray; break; m_Normals = componentsArray;
case 5: break;
if (version[0] >= 5) { m_UV3 = componentsArray; } case 2:
else { m_Tangents = componentsArray; } m_Colors = componentsArray;
break;
case 3:
m_UV1 = componentsArray;
break;
case 4:
m_UV2 = componentsArray;
break;
case 5:
if (version[0] >= 5)
{
m_UV3 = componentsArray;
}
else
{
m_Tangents = componentsArray;
}
break;
case 6:
m_UV4 = componentsArray;
break;
case 7:
m_Tangents = componentsArray;
break;
//2018.2 and up
case 12:
if (m_Skin == null)
InitMSkin();
for (int i = 0; i < m_VertexCount; i++)
{
for (int j = 0; j < 4; j++)
{
m_Skin[i][j].weight = componentsArray[i * 4 + j];
}
}
break;
case 13:
if (m_Skin == null)
InitMSkin();
for (int i = 0; i < m_VertexCount; i++)
{
for (int j = 0; j < 4; j++)
{
m_Skin[i][j].boneIndex = componentsIntArray[i * 4 + j];
}
}
break; break;
case 6: m_UV4 = componentsArray; break;
case 7: m_Tangents = componentsArray; break;
} }
m_Stream.channelMask.Set(b, false); m_Stream.channelMask.Set(b, false);
@ -922,7 +1005,7 @@ namespace AssetStudio
{ {
int m_DataSizeOffset = vertexOffset + componentByteSize * d; int m_DataSizeOffset = vertexOffset + componentByteSize * d;
Buffer.BlockCopy(m_DataSize, m_DataSizeOffset, componentBytes, 0, componentByteSize); Buffer.BlockCopy(m_DataSize, m_DataSizeOffset, componentBytes, 0, componentByteSize);
componentsArray[v * m_Channel.dimension + d] = bytesToFloat(componentBytes); componentsArray[v * m_Channel.dimension + d] = BytesToFloat(componentBytes);
} }
} }