private static float ReadDataLayout(FileReader reader, GXVertexLayout layout) { if (layout.Divisor != 0) { switch (layout.CompType) { case GXComponentType.S8: return(reader.ReadSByte() / layout.Divisor); case GXComponentType.U8: return(reader.ReadByte() / layout.Divisor); case GXComponentType.U16: return(reader.ReadUInt16() / layout.Divisor); case GXComponentType.S16: return(reader.ReadInt16() / layout.Divisor); } } switch (layout.CompType) { case GXComponentType.S8: return(reader.ReadSByte()); case GXComponentType.U8: return(reader.ReadByte()); case GXComponentType.U16: return(reader.ReadUInt16()); case GXComponentType.S16: return(reader.ReadInt16()); case GXComponentType.F32: return(reader.ReadSingle()); } return(0); }
private static Vector4 ReadDataColorLayout(FileReader reader, GXVertexLayout layout) { switch (layout.CompType) { case GXComponentType.RGBA8: return(new Vector4( reader.ReadByte() / 255.0f, reader.ReadByte() / 255.0f, reader.ReadByte() / 255.0f, reader.ReadByte() / 255.0f)); case GXComponentType.RGB8: return(new Vector4( reader.ReadByte() / 255.0f, reader.ReadByte() / 255.0f, reader.ReadByte() / 255.0f, 1.0f)); case GXComponentType.RGBX8: return(new Vector4( reader.ReadByte() / 255.0f, reader.ReadByte() / 255.0f, reader.ReadByte() / 255.0f, 1.0f)); case GXComponentType.RGB565: { short value = reader.ReadInt16(); int R = (value & 0xF800) >> 11; int G = (value & 0x07E0) >> 5; int B = (value & 0x001F); return(new Vector4(R / 255f, G / 255f, B / 255f, 1.0f)); } case GXComponentType.RGBA4: { ushort value = reader.ReadUInt16(); float R = (float)((value >> 12) & 0x0F) / 0x0F; float G = (float)((value >> 8) & 0x0F) / 0x0F; float B = (float)((value >> 4) & 0x0F) / 0x0F; float A = (float)((value >> 0) & 0x0F) / 0x0F; return(new Vector4(R, G, B, A)); } case GXComponentType.RGBA6: { int value = reader.ReadInt32(); int R = (value & 0xFC0000) >> 18; int G = (value & 0x03F000) >> 12; int B = (value & 0x000FC0) >> 6; int A = (value & 0x00003F); return(new Vector4(R / 255f, G / 255f, B / 255f, A / 255f)); } default: return(new Vector4( reader.ReadByte() / 255f, reader.ReadByte() / 255f, reader.ReadByte() / 255f, reader.ReadByte() / 255f)); } return(new Vector4(255, 255, 255, 255)); }
private static ushort ReadLayout(FileReader reader, GXVertexLayout layout) { switch (layout.AttType) { case GXAttributeType.INDEX16: return(reader.ReadUInt16()); case GXAttributeType.INDEX8: return(reader.ReadByte()); } return(0); }
static bool IsColor(GXVertexLayout layout) { switch (layout.CompType) { case GXComponentType.RGBA4: case GXComponentType.RGBA8: case GXComponentType.RGBX8: case GXComponentType.RGB565: case GXComponentType.RGB8: return(layout.Attribute == GXAttributes.Color0 || layout.Attribute == GXAttributes.Color1); default: return(false); } }
private static void ParseData(STVertex vertex, FileReader dataReader, GXVertexLayout layout, int index, ushort[] matrixIndices) { int numElements = GetElementCount(layout.Attribute); int stride = GetDataStride(layout.CompType) * numElements; if (IsColor(layout)) { stride = GetColorDataStride(layout.CompType); } using (dataReader.TemporarySeek(layout.DataOffset + (index * stride), SeekOrigin.Begin)) { // Console.WriteLine($"attribute {layout.Attribute} stride {stride} index {index}"); switch (layout.Attribute) { case GXAttributes.Position: { float X = ReadDataLayout(dataReader, layout); float Y = ReadDataLayout(dataReader, layout); float Z = ReadDataLayout(dataReader, layout); vertex.Position = new OpenTK.Vector3(X, Y, Z); } break; case GXAttributes.Normal: { float X = ReadDataLayout(dataReader, layout); float Y = ReadDataLayout(dataReader, layout); float Z = ReadDataLayout(dataReader, layout); vertex.Normal = new OpenTK.Vector3(X, Y, Z).Normalized(); } break; case GXAttributes.NormalBinormalTangent: { float NormalX = ReadDataLayout(dataReader, layout); float NormalY = ReadDataLayout(dataReader, layout); float NormalZ = ReadDataLayout(dataReader, layout); float BinormalX = ReadDataLayout(dataReader, layout); float BinormalY = ReadDataLayout(dataReader, layout); float BinormalZ = ReadDataLayout(dataReader, layout); float TangentX = ReadDataLayout(dataReader, layout); float TangentY = ReadDataLayout(dataReader, layout); float TangentZ = ReadDataLayout(dataReader, layout); vertex.Normal = new OpenTK.Vector3(NormalX, NormalY, NormalZ).Normalized(); vertex.Bitangent = new OpenTK.Vector4(BinormalX, BinormalY, BinormalZ, 1); vertex.Tangent = new OpenTK.Vector4(TangentX, TangentY, TangentZ, 1); } break; case GXAttributes.TexCoord0: case GXAttributes.TexCoord1: case GXAttributes.TexCoord2: case GXAttributes.TexCoord3: case GXAttributes.TexCoord4: case GXAttributes.TexCoord5: case GXAttributes.TexCoord6: case GXAttributes.TexCoord7: { int channel = GetChannel(layout.Attribute); float X = ReadDataLayout(dataReader, layout); float Y = ReadDataLayout(dataReader, layout); vertex.TexCoords[channel] = new OpenTK.Vector2(X, Y); } break; case GXAttributes.Color0: case GXAttributes.Color1: { int channel = GetChannel(layout.Attribute); var color = ReadDataColorLayout(dataReader, layout); vertex.Colors[0] = new OpenTK.Vector4(color.X, color.Y, color.Z, color.W); } break; case GXAttributes.PosNormMatrix: { if (index != -1) { int boneID = index / 3; if (matrixIndices != null) { boneID = matrixIndices[index / 3]; } Console.WriteLine($"BONEID {index} real {boneID}"); vertex.BoneIndices.Add(boneID); vertex.BoneWeights.Add(1.0f); } } break; } } }
private static void ParseData(STVertex vertex, FileReader dataReader, GXVertexLayout layout, int index) { int numElements = GetElementCount(layout.Attribute); int stride = GetDataStride(layout.CompType) * numElements; if (IsColor(layout)) { stride = GetColorDataStride(layout.CompType); } using (dataReader.TemporarySeek(layout.DataOffset + (index * stride), SeekOrigin.Begin)) { // Console.WriteLine($"attribute {layout.Attribute} stride {stride} index {index}"); switch (layout.Attribute) { case GXAttributes.Position: { float X = ReadDataLayout(dataReader, layout); float Y = ReadDataLayout(dataReader, layout); float Z = ReadDataLayout(dataReader, layout); vertex.Position = new OpenTK.Vector3(X, Y, Z); } break; case GXAttributes.Normal: { float X = ReadDataLayout(dataReader, layout); float Y = ReadDataLayout(dataReader, layout); float Z = ReadDataLayout(dataReader, layout); vertex.Normal = new OpenTK.Vector3(X, Y, Z).Normalized(); } break; case GXAttributes.TexCoord0: case GXAttributes.TexCoord1: case GXAttributes.TexCoord2: case GXAttributes.TexCoord3: case GXAttributes.TexCoord4: case GXAttributes.TexCoord5: case GXAttributes.TexCoord6: case GXAttributes.TexCoord7: { int channel = (int)(layout.Attribute - GXAttributes.TexCoord0); float X = ReadDataLayout(dataReader, layout); float Y = ReadDataLayout(dataReader, layout); vertex.TexCoords[0] = new OpenTK.Vector2(X, Y); } break; case GXAttributes.Color0: case GXAttributes.Color1: { int channel = (int)(layout.Attribute - GXAttributes.Color0); var color = ReadDataColorLayout(dataReader, layout); vertex.Colors[0] = new OpenTK.Vector4(color.X, color.Y, color.Z, color.W); } break; case GXAttributes.PosNormMatrix: { if (index != -1) { int boneID = index / 3; vertex.BoneIndices.Add(boneID); vertex.BoneWeights.Add(1.0f); } } break; } } }