private void GetChannels() { m_Channels = new ChannelInfo[6]; for (int i = 0; i < 6; i++) { m_Channels[i] = new ChannelInfo(); } for (var s = 0; s < m_Streams.Length; s++) { var m_Stream = m_Streams[s]; var channelMask = new BitArray(new[] { (int)m_Stream.channelMask }); byte offset = 0; for (int i = 0; i < 6; i++) { if (channelMask.Get(i)) { var m_Channel = m_Channels[i]; m_Channel.stream = (byte)s; m_Channel.offset = offset; switch (i) { case 0: //kShaderChannelVertex case 1: //kShaderChannelNormal m_Channel.format = 0; //kChannelFormatFloat m_Channel.dimension = 3; break; case 2: //kShaderChannelColor m_Channel.format = 2; //kChannelFormatColor m_Channel.dimension = 4; break; case 3: //kShaderChannelTexCoord0 case 4: //kShaderChannelTexCoord1 m_Channel.format = 0; //kChannelFormatFloat m_Channel.dimension = 2; break; case 5: //kShaderChannelTangent m_Channel.format = 0; //kChannelFormatFloat m_Channel.dimension = 4; break; } offset += (byte)(m_Channel.dimension * MeshHelper.GetChannelFormatSize(m_Channel.format)); } } } }
private void ProcessData() { //Fix normal channel in 2018.3 and up if (version[0] > 2018 || (version[0] == 2018 && version[1] >= 3)) { if (m_VertexData.m_Channels[1].dimension > 4) { for (int i = 2; i < m_VertexData.m_Channels.Length; i++) { if (m_VertexData.m_Channels[i].dimension > 0) { var offset = m_VertexData.m_Channels[i].offset - m_VertexData.m_Channels[1].offset; m_VertexData.m_Channels[1].dimension = (byte)(offset / MeshHelper.GetChannelFormatSize(m_VertexData.m_Channels[1].format)); m_VertexData.GetStreams(); break; } } } } if (!string.IsNullOrEmpty(m_StreamData?.path)) { if (m_VertexData.m_VertexCount > 0) { var resourceReader = new ResourceReader(m_StreamData.path, assetsFile, m_StreamData.offset, (int)m_StreamData.size); m_VertexData.m_DataSize = resourceReader.GetData(); } } if (version[0] > 3 || (version[0] == 3 && version[1] >= 5)) //3.5 and up { ReadVertexData(); } if (version[0] > 2 || (version[0] == 2 && version[1] >= 6)) //2.6.0 and later { DecompressCompressedMesh(); } BuildFaces(); }
private void GetStreams() { var streamCount = m_Channels.Max(x => x.stream) + 1; 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 * MeshHelper.GetChannelFormatSize(m_Channel.format); } } } m_Streams[s] = new StreamInfo { channelMask = chnMask, offset = offset, stride = stride, dividerOp = 0, frequency = 0 }; offset += m_VertexCount * stride; //static size_t AlignStreamSize (size_t size) { return (size + (kVertexStreamAlign-1)) & ~(kVertexStreamAlign-1); } offset = (offset + (16u - 1u)) & ~(16u - 1u); } }
public void FixChannel() { if (m_Channels.FirstOrDefault(x => x.dimension > 4) != null) { var fixStream = m_Channels.Max(x => x.stream); var fixChannels = m_Channels.Where(x => x.dimension > 0 && x.stream == fixStream).ToArray(); var stride = 0; for (int i = 1, l = fixChannels.Length; i < l; i++) { var curChannel = fixChannels[i]; var preChannel = fixChannels[i - 1]; var offset = curChannel.offset - preChannel.offset; preChannel.dimension = (byte)(offset / MeshHelper.GetChannelFormatSize(preChannel.format)); stride += offset; } //Fix Last var m_Channel = fixChannels.Last(); var streamSize = m_DataSize.Length - m_Streams[fixStream].offset; var totalStride = streamSize / m_VertexCount; var channelStride = totalStride - stride; m_Channel.dimension = (byte)(channelStride / MeshHelper.GetChannelFormatSize(m_Channel.format)); GetStreams(); } }
private void ReadVertexData() { m_VertexCount = (int)m_VertexData.m_VertexCount; for (var chn = 0; chn < m_VertexData.m_Channels.Length; chn++) { var m_Channel = m_VertexData.m_Channels[chn]; if (m_Channel.dimension > 0) { var m_Stream = m_VertexData.m_Streams[m_Channel.stream]; var channelMask = new BitArray(new[] { (int)m_Stream.channelMask }); if (channelMask.Get(chn)) { if (version[0] < 2018 && chn == 2 && m_Channel.format == 2) { m_Channel.dimension = 4; } var componentByteSize = (int)MeshHelper.GetChannelFormatSize(m_Channel.format); var componentBytes = new byte[m_VertexCount * m_Channel.dimension * componentByteSize]; for (int v = 0; v < m_VertexCount; v++) { var vertexOffset = (int)m_Stream.offset + m_Channel.offset + (int)m_Stream.stride * v; for (int d = 0; d < m_Channel.dimension; d++) { var componentOffset = vertexOffset + componentByteSize * d; Buffer.BlockCopy(m_VertexData.m_DataSize, componentOffset, componentBytes, componentByteSize * (v * m_Channel.dimension + d), componentByteSize); } } if (reader.endian == EndianType.BigEndian && componentByteSize > 1) //swap bytes { for (var i = 0; i < componentBytes.Length / componentByteSize; i++) { var buff = new byte[componentByteSize]; Buffer.BlockCopy(componentBytes, i * componentByteSize, buff, 0, componentByteSize); buff = buff.Reverse().ToArray(); Buffer.BlockCopy(buff, 0, componentBytes, i * componentByteSize, componentByteSize); } } int[] componentsIntArray = null; float[] componentsFloatArray = null; if (m_Channel.format == 10 || m_Channel.format == 11) { componentsIntArray = MeshHelper.BytesToIntArray(componentBytes); } else { componentsFloatArray = MeshHelper.BytesToFloatArray(componentBytes, componentByteSize); } if (version[0] >= 2018) { switch (chn) { case 0: //kShaderChannelVertex m_Vertices = componentsFloatArray; break; case 1: //kShaderChannelNormal m_Normals = componentsFloatArray; break; case 2: //kShaderChannelTangent m_Tangents = componentsFloatArray; break; case 3: //kShaderChannelColor m_Colors = componentsFloatArray; break; case 4: //kShaderChannelTexCoord0 m_UV0 = componentsFloatArray; break; case 5: //kShaderChannelTexCoord1 m_UV1 = componentsFloatArray; break; case 6: //kShaderChannelTexCoord2 m_UV2 = componentsFloatArray; break; case 7: //kShaderChannelTexCoord3 m_UV3 = componentsFloatArray; break; //kShaderChannelTexCoord4 8 //kShaderChannelTexCoord5 9 //kShaderChannelTexCoord6 10 //kShaderChannelTexCoord7 11 //2018.2 and up case 12: //kShaderChannelBlendWeight if (m_Skin == null) { InitMSkin(); } for (int i = 0; i < m_VertexCount; i++) { for (int j = 0; j < m_Channel.dimension; j++) { m_Skin[i].weight[j] = componentsFloatArray[i * m_Channel.dimension + j]; } } break; case 13: //kShaderChannelBlendIndices if (m_Skin == null) { InitMSkin(); } for (int i = 0; i < m_VertexCount; i++) { for (int j = 0; j < m_Channel.dimension; j++) { m_Skin[i].boneIndex[j] = componentsIntArray[i * m_Channel.dimension + j]; } } break; } } else { switch (chn) { case 0: //kShaderChannelVertex m_Vertices = componentsFloatArray; break; case 1: //kShaderChannelNormal m_Normals = componentsFloatArray; break; case 2: //kShaderChannelColor m_Colors = componentsFloatArray; break; case 3: //kShaderChannelTexCoord0 m_UV0 = componentsFloatArray; break; case 4: //kShaderChannelTexCoord1 m_UV1 = componentsFloatArray; break; case 5: if (version[0] >= 5) //kShaderChannelTexCoord2 { m_UV2 = componentsFloatArray; } else //kShaderChannelTangent { m_Tangents = componentsFloatArray; } break; case 6: //kShaderChannelTexCoord3 m_UV3 = componentsFloatArray; break; case 7: //kShaderChannelTangent m_Tangents = componentsFloatArray; break; } } } } } }