Пример #1
0
            public ImmutableMesh(Mdlx.DmaChain dmaChain)
            {
                DmaChain   = dmaChain;
                VpuPackets = dmaChain.DmaVifs
                             .Select(dmaVif =>
                {
                    var unpacker = new VifUnpacker(dmaVif.VifPacket);
                    unpacker.Run();

                    using (var stream = new MemoryStream(unpacker.Memory))
                        return(VpuPacket.Read(stream));
                })
                             .ToList();
            }
Пример #2
0
        private static MeshDescriptor Parse(Mdlx.VifPacketDescriptor vifPacketDescriptor)
        {
            var vertices = new List <CustomVertex.PositionColoredTextured>();
            var indices  = new List <int>();
            var unpacker = new VifUnpacker(vifPacketDescriptor.VifPacket);

            var indexBuffer = new int[4];
            var recentIndex = 0;

            while (unpacker.Run() != VifUnpacker.State.End)
            {
                var vpu = new MemoryStream(unpacker.Memory, false)
                          .Using(stream => VpuPacket.Read(stream));

                var baseVertexIndex = vertices.Count;
                for (var i = 0; i < vpu.Indices.Length; i++)
                {
                    var vertexIndex = vpu.Indices[i];
                    var position    = new Vector3(
                        vpu.Vertices[vertexIndex.Index].X,
                        vpu.Vertices[vertexIndex.Index].Y,
                        vpu.Vertices[vertexIndex.Index].Z);

                    int colorR, colorG, colorB, colorA;
                    if (vpu.Colors.Length != 0)
                    {
                        colorR = vpu.Colors[i].R;
                        colorG = vpu.Colors[i].G;
                        colorB = vpu.Colors[i].B;
                        colorA = vpu.Colors[i].A;
                    }
                    else
                    {
                        colorR = 0x80;
                        colorG = 0x80;
                        colorB = 0x80;
                        colorA = 0x80;
                    }

                    var color = Math.Min(byte.MaxValue, colorB * 2) |
                                (Math.Min(byte.MaxValue, colorG * 2) << 8) |
                                (Math.Min(byte.MaxValue, colorR * 2) << 16) |
                                (Math.Min(byte.MaxValue, colorA * 2) << 24);

                    vertices.Add(new CustomVertex.PositionColoredTextured(
                                     position, color, (short)(ushort)vertexIndex.U / 4096.0f, (short)(ushort)vertexIndex.V / 4096.0f));

                    indexBuffer[(recentIndex++) & 3] = baseVertexIndex + i;
                    switch (vertexIndex.Function)
                    {
                    case VpuPacket.VertexFunction.DrawTriangleDoubleSided:
                        indices.Add(indexBuffer[(recentIndex - 1) & 3]);
                        indices.Add(indexBuffer[(recentIndex - 3) & 3]);
                        indices.Add(indexBuffer[(recentIndex - 2) & 3]);
                        indices.Add(indexBuffer[(recentIndex - 1) & 3]);
                        indices.Add(indexBuffer[(recentIndex - 2) & 3]);
                        indices.Add(indexBuffer[(recentIndex - 3) & 3]);
                        break;

                    case VpuPacket.VertexFunction.Stock:
                        break;

                    case VpuPacket.VertexFunction.DrawTriangle:
                        indices.Add(indexBuffer[(recentIndex - 1) & 3]);
                        indices.Add(indexBuffer[(recentIndex - 3) & 3]);
                        indices.Add(indexBuffer[(recentIndex - 2) & 3]);
                        break;

                    case VpuPacket.VertexFunction.DrawTriangleInverse:
                        indices.Add(indexBuffer[(recentIndex - 1) & 3]);
                        indices.Add(indexBuffer[(recentIndex - 2) & 3]);
                        indices.Add(indexBuffer[(recentIndex - 3) & 3]);
                        break;
                    }
                }
            }

            return(new MeshDescriptor
            {
                Vertices = vertices.ToArray(),
                Indices = indices.ToArray(),
                TextureIndex = vifPacketDescriptor.TextureId,
                IsOpaque = vifPacketDescriptor.IsTransparentFlag == 0,
            });
        }
Пример #3
0
        private void Parse(List <Mdlx.VifPacketDescriptor> packetDescriptors)
        {
            var textureIndex = 0;
            var indexBuffer  = new int[4];
            var recenti      = 0;

            var model = new Model();

            for (var pdIndex = 0; pdIndex < packetDescriptors.Count; pdIndex++)
            {
                var vifPacketDescriptor = packetDescriptors[pdIndex];
                var unpacker            = new VifUnpacker(vifPacketDescriptor.VifPacket);

                VifUnpacker.State state;
                do
                {
                    var indices = new List <int>();

                    state = unpacker.Run();

                    var vpu = new MemoryStream(unpacker.Memory, false)
                              .Using(stream => VpuPacket.Read(stream));

                    var baseVertexIndex = Vertices.Count;
                    for (var i = 0; i < vpu.Indices.Length; i++)
                    {
                        var vertexIndex = vpu.Indices[i];

                        Vector3 position;
                        position.X = -vpu.Vertices[vertexIndex.Index].X;
                        position.Y = vpu.Vertices[vertexIndex.Index].Y;
                        position.Z = vpu.Vertices[vertexIndex.Index].Z;

                        int colorR, colorG, colorB, colorA;
                        if (vpu.Colors.Length != 0)
                        {
                            colorR = vpu.Colors[i].R;
                            colorG = vpu.Colors[i].G;
                            colorB = vpu.Colors[i].B;
                            colorA = vpu.Colors[i].A;
                        }
                        else
                        {
                            colorR = 0x80;
                            colorG = 0x80;
                            colorB = 0x80;
                            colorA = 0x80;
                        }

                        var color = Math.Min(byte.MaxValue, colorB * 2) |
                                    (Math.Min(byte.MaxValue, colorG * 2) << 8) |
                                    (Math.Min(byte.MaxValue, colorR * 2) << 16) |
                                    (Math.Min(byte.MaxValue, colorA * 2) << 24);

                        Vertices.Add(new CustomVertex.PositionColoredTextured(
                                         position, color, vertexIndex.U / 4096.0f, vertexIndex.V / 4096.0f));

                        indexBuffer[(recenti++) & 3] = baseVertexIndex + i;
                        switch (vertexIndex.Function)
                        {
                        case VpuPacket.VertexFunction.None:
                            break;

                        case VpuPacket.VertexFunction.Stock:
                            break;

                        case VpuPacket.VertexFunction.DrawTriangle:
                            indices.Add(indexBuffer[(recenti - 1) & 3]);
                            indices.Add(indexBuffer[(recenti - 2) & 3]);
                            indices.Add(indexBuffer[(recenti - 3) & 3]);
                            break;

                        case VpuPacket.VertexFunction.DrawTriangleInverse:
                            indices.Add(indexBuffer[(recenti - 1) & 3]);
                            indices.Add(indexBuffer[(recenti - 3) & 3]);
                            indices.Add(indexBuffer[(recenti - 2) & 3]);
                            break;
                        }
                    }

                    MeshDescriptors.Add(new MeshDescriptor
                    {
                        Indices      = indices.ToArray(),
                        TextureIndex = textureIndex + vifPacketDescriptor.TextureId,
                        SegmentIndex = pdIndex
                    });
                } while (state == VifUnpacker.State.Microprogram);
            }
        }