예제 #1
0
        private Mesh ReadShape(FileReader reader)
        {
            Mesh mesh = new Mesh();

            ushort unk          = reader.ReadUInt16();
            ushort numPackets   = reader.ReadUInt16();
            uint   packetOffset = reader.ReadUInt32() * 4;

            using (reader.TemporarySeek(packetOffset, SeekOrigin.Begin))
            {
                for (int j = 0; j < numPackets; j++)
                {
                    reader.SeekBegin(packetOffset + (j * 12));
                    Packet packet = new Packet()
                    {
                        Offset             = reader.ReadUInt32() * 4,
                        Size               = reader.ReadUInt32(),
                        Flags1             = reader.ReadByte(),
                        Flags2             = reader.ReadByte(),
                        MaterialColorIndex = reader.ReadSByte(),
                        TextureIndex       = reader.ReadSByte(),
                    };

                    MeshGroup meshGroup = new MeshGroup()
                    {
                        Packet       = packet,
                        TextureIndex = packet.TextureIndex,
                    };
                    mesh.Groups.Add(meshGroup);



                    //  Console.WriteLine($"Material {packet.MaterialColorIndex} TextureIndex {packet.TextureIndex}");
                    //  Console.WriteLine($"Flags1 {packet.Flags1 >> 4} {packet.Flags1 & 0xF} Flags2 {packet.Flags2}");

                    if (packet.MaterialColorIndex != -1)
                    {
                        using (reader.TemporarySeek(materialColorsOffset + (packet.MaterialColorIndex * 4), SeekOrigin.Begin)) {
                            meshGroup.Color = reader.ReadColor8RGBA();
                        }
                    }

                    DisplayListHelper.Config config = new DisplayListHelper.Config();

                    List <GXVertexLayout> layouts = new List <GXVertexLayout>();
                    if (packet.Flags2 != 3 && packet.Flags2 != 15 && packet.Flags2 != 16 &&
                        packet.Flags2 != 14 && packet.Flags2 != 0)
                    {
                        layouts.Add(new GXVertexLayout(
                                        GXAttributes.PosNormMatrix,
                                        GXComponentType.U8, GXAttributeType.INDEX8, 48));
                    }
                    if (packet.Flags2 == 18)
                    {
                        layouts.Add(new GXVertexLayout(
                                        GXAttributes.Tex0Matrix,
                                        GXComponentType.U8, GXAttributeType.INDEX8, 48));
                    }
                    if (packet.Flags2 == 19)
                    {
                        layouts.Add(new GXVertexLayout(
                                        GXAttributes.Tex0Matrix,
                                        GXComponentType.U8, GXAttributeType.INDEX8, 48));
                        layouts.Add(new GXVertexLayout(
                                        GXAttributes.Tex1Matrix,
                                        GXComponentType.U8, GXAttributeType.INDEX8, 48));
                        layouts.Add(new GXVertexLayout(
                                        GXAttributes.Tex2Matrix,
                                        GXComponentType.U8, GXAttributeType.INDEX8, 48));
                    }

                    layouts.Add(new GXVertexLayout(
                                    GXAttributes.Position,
                                    GXComponentType.S16, GXAttributeType.INDEX16, positionsOffset));

                    if (normalsoffset != 0)
                    {
                        layouts.Add(new GXVertexLayout(
                                        GXAttributes.Normal,
                                        GXComponentType.S16, GXAttributeType.INDEX16, normalsoffset));
                    }

                    if (packet.Flags2 >= 16)
                    {
                        layouts.Add(new GXVertexLayout(
                                        GXAttributes.NormalBinormalTangent,
                                        GXComponentType.S16, GXAttributeType.INDEX16, normalsoffset));
                        layouts.Add(new GXVertexLayout(
                                        GXAttributes.NormalBinormalTangent,
                                        GXComponentType.S16, GXAttributeType.INDEX16, normalsoffset));
                    }
                    if (packet.Flags2 == 14 || packet.Flags2 == 15)
                    {
                        layouts.Add(new GXVertexLayout(
                                        GXAttributes.NormalBinormalTangent,
                                        GXComponentType.S16, GXAttributeType.INDEX16, normalsoffset));
                    }

                    if (colorsOffset != 0 && packet.Flags2 != 0)
                    {
                        layouts.Add(new GXVertexLayout(
                                        GXAttributes.Color0,
                                        GXComponentType.RGBA4, GXAttributeType.INDEX16, colorsOffset));
                    }
                    if (texCoordsOffset != 0 && packet.Flags2 != 0)
                    {
                        layouts.Add(new GXVertexLayout(
                                        GXAttributes.TexCoord0,
                                        GXComponentType.S16, GXAttributeType.INDEX16, texCoordsOffset)
                        {
                            Divisor = 1024.0f,
                        });
                    }

                    if (packet.Flags2 == 16 || packet.Flags2 == 17 || packet.Flags2 == 19)
                    {
                        config.OpCodeShift = -2;
                    }

                    var displayListData = new SubStream(reader.BaseStream, packet.Offset, packet.Size);
                    meshGroup.Vertices.AddRange(DisplayListHelper.ReadDisplayLists(
                                                    displayListData, reader.BaseStream, layouts.ToArray(), config));
                }
            }
            return(mesh);
        }