Example #1
0
            public void Read(FileReader reader, LM2_ARCADE_Model root)
            {
                Skeleton         = new STSkeleton();
                DrawableRenderer = new GenericModelRenderer();
                root.DrawableContainer.Drawables.Add(Skeleton);
                root.DrawableContainer.Drawables.Add(DrawableRenderer);

                reader.ReadSignature(4, "VM61");
                ushort Type    = reader.ReadUInt16();
                ushort Unknown = reader.ReadUInt16();

                if (Type == 0)
                {
                }
                else if ((Type == 1))
                {
                    throw new Exception("Animation files not supported yet!");
                }
                else
                {
                    throw new Exception("Unknown type found! " + Type);
                }

                Alignment = reader.ReadUInt32();
                uint  Padding       = reader.ReadUInt32();
                ulong MaterialCount = reader.ReadUInt64();

                HeaderSize = reader.ReadUInt64();
                ulong TextureMapsCount  = reader.ReadUInt64();
                ulong TextureMapsOffset = reader.ReadUInt64();

                ulong BoneCount       = reader.ReadUInt64();
                ulong BoneOffset      = reader.ReadUInt64();
                ulong FirstNodeOffset = reader.ReadUInt64(); //Either an offset or the total size of section up to the node
                ulong LinkNodeCount   = reader.ReadUInt64();
                ulong LinkNodeOffset  = reader.ReadUInt64();
                ulong TotalNodeCount  = reader.ReadUInt64();
                ulong TotalNodeOffset = reader.ReadUInt64();
                ulong Padding2        = reader.ReadUInt64();

                root.Nodes.Add("Materials");
                root.Nodes.Add("Root");
                root.Nodes.Add("All Nodes");

                long pos = reader.Position;

                if (TextureMapsOffset != 0)
                {
                    reader.SeekBegin(TextureMapsOffset);
                    for (int i = 0; i < (int)TextureMapsCount; i++)
                    {
                        TextureMaps.Add(reader.ReadNameOffset(false, typeof(ulong)));
                    }
                }

                reader.SeekBegin(pos);
                for (int i = 0; i < (int)MaterialCount; i++)
                {
                    Material mat = new Material();
                    mat.Read(reader);
                    Materials.Add(mat);

                    var genericMat = new STGenericMaterial();
                    genericMat.Text = mat.Name;

                    for (int t = 0; t < mat.TextureIndices.Length; t++)
                    {
                        if (mat.TextureIndices[t] != -1)
                        {
                            Console.WriteLine("TextureIndices " + mat.TextureIndices[t]);
                            string Texture = TextureMaps[mat.TextureIndices[t]];

                            var textureMap = new STGenericMatTexture();
                            textureMap.Name = Texture;
                            genericMat.TextureMaps.Add(textureMap);

                            if (Texture.EndsWith("col.dds"))
                            {
                                textureMap.Type = STGenericMatTexture.TextureType.Diffuse;
                            }
                            if (Texture.EndsWith("col.mot"))
                            {
                                textureMap.Type = STGenericMatTexture.TextureType.Diffuse;
                            }
                        }
                    }

                    root.Nodes[0].Nodes.Add(genericMat);
                }

                if (TotalNodeCount != 0)
                {
                    for (int i = 0; i < (int)TotalNodeCount; i++)
                    {
                        reader.SeekBegin((int)TotalNodeOffset + (i * 16));

                        string NodeName = reader.ReadNameOffset(false, typeof(ulong));
                        var    Offset   = reader.ReadUInt64();

                        Console.WriteLine($"{NodeName}");

                        if (Offset != 0)
                        {
                            reader.SeekBegin(Offset);
                            Node node = new Node();
                            node.Name = NodeName;
                            node.Read(reader);
                            TotalNodes.Add(node);
                        }
                    }
                }

                if (BoneCount != 0)
                {
                    for (int i = 0; i < (int)BoneCount; i++)
                    {
                        reader.SeekBegin((int)BoneOffset + (i * 16));

                        string NodeName = reader.ReadNameOffset(false, typeof(ulong));
                        ulong  Offset   = reader.ReadUInt64();

                        if (Offset != 0)
                        {
                            reader.SeekBegin(Offset);
                            Node node = new Node();
                            node.Name = NodeName;
                            node.Read(reader);
                            BoneList.Add(node); //This list is for mapping to meshes
                        }
                    }
                }

                foreach (var node in TotalNodes)
                {
                    // TreeNode lowerWrapper = new TreeNode($"{node.Name}");
                    // root.Nodes[3].Nodes.Add(lowerWrapper);

                    LoadChildern(TotalNodes, node, root.Nodes[2]);
                }

                if (FirstNodeOffset != 0)
                {
                    reader.SeekBegin(FirstNodeOffset);
                    ulong NodeOffset = reader.ReadUInt64();
                    reader.SeekBegin(NodeOffset);
                    Node node = new Node();
                    node.Name = GetNodeName(TotalNodes, node);
                    node.Read(reader);

                    LoadBones(TotalNodes, node, root.Nodes[1]);
                }



                if (LinkNodeCount != 0)
                {
                    root.Nodes.Add("Links");

                    for (int i = 0; i < (int)LinkNodeCount; i++)
                    {
                        TreeNode linkWrapper = new TreeNode($"Link {i}");
                        root.Nodes[3].Nodes.Add(linkWrapper);

                        reader.SeekBegin((int)LinkNodeOffset + (i * 16));

                        ulong NodeOffset1 = reader.ReadUInt64();
                        ulong NodeOffset2 = reader.ReadUInt64();

                        reader.SeekBegin(NodeOffset1);
                        Node node1 = new Node();
                        node1.Name = GetNodeName(TotalNodes, node1);
                        node1.Read(reader);

                        reader.SeekBegin(NodeOffset2);
                        Node node2 = new Node();
                        node2.Name = GetNodeName(TotalNodes, node1);
                        node2.Read(reader);

                        //  LoadChildern(TotalNodes, node1, linkWrapper);
                        // LoadChildern(TotalNodes, node2, linkWrapper);

                        LinkNodes.Add(Tuple.Create(node1, node2));
                    }
                }

                Skeleton.update();
                Skeleton.reset();
            }
Example #2
0
        public void Load(System.IO.Stream stream)
        {
            fileSize = stream.Length;
            using (var reader = new FileReader(stream))
            {
                pmdlCount = 0;
                ptexCount = 0;
                ptexList.Clear();
                ddsList.Clear();
                // Read header for data locations
                files.Clear();
                reader.Position  = 4;
                reader.ByteOrder = byteOrder;
                if (reader.ReadUInt32() != 2001)
                {
                    byteOrder = ByteOrder.BigEndian;
                }
                reader.ByteOrder            = byteOrder;
                reader.Position             = 0;
                header.version              = reader.ReadUInt32(4);
                reader.Position            += 4;
                header.flag1                = reader.ReadUInt16();
                header.flag2                = reader.ReadUInt16();
                header.dataInfoCount        = reader.ReadUInt32();
                header.dataInfoSize         = reader.ReadUInt32();
                header.tagCount             = reader.ReadUInt32();
                header.tagSize              = reader.ReadUInt32();
                header.relocationDataOffset = reader.ReadUInt32();
                header.relocationDataSize   = reader.ReadInt32();
                reader.Position            += 92;
                // Create arrays for multiple data and tag info objects
                DataInfo[] dataInfos = new DataInfo[header.dataInfoCount];
                TagInfo[]  tagInfos  = new TagInfo[header.tagCount];

                for (int i = 0; i < header.dataInfoCount; i++)
                {
                    // Create and assign properties to a new DataInfo until the count specified in the header is reached
                    dataInfos[i] = new DataInfo()
                    {
                        unknown1   = reader.ReadUInt32(),
                        textOffset = reader.ReadUInt32(),
                        unknown2   = reader.ReadUInt32(),
                        unknown3   = reader.ReadUInt32(),
                        dataSize   = reader.ReadInt32(),
                        dataSize2  = reader.ReadUInt32(),
                        dataOffset = reader.ReadInt32(),
                        unknown4   = reader.ReadUInt32(),
                        zero1      = reader.ReadUInt32(),
                        zero2      = reader.ReadUInt32(),
                        zero3      = reader.ReadUInt32(),
                        zero4      = reader.ReadUInt32()
                    };
                }
                saveData = dataInfos;

                for (int i = 0; i < header.tagCount; i++)
                {
                    // Get tags for file extensions, data, and names
                    tagInfos[i] = new TagInfo()
                    {
                        magic      = System.Text.Encoding.ASCII.GetString(reader.ReadBytes(4)),
                        dataOffset = reader.ReadInt32(),
                        flag       = reader.ReadUInt32(),
                        textOffset = reader.ReadInt32(),
                        name       = "default"
                    };
                }


                // Get extra data, currently unused except for saving the file
                if (header.dataInfoCount > 2)
                {
                    reader.Position = dataInfos[2].dataOffset;
                    extraData       = reader.ReadBytes(dataInfos[2].dataSize);
                }

                // Get relocation data and write to byte array
                reader.Position = header.relocationDataOffset;
                relocationData  = reader.ReadBytes(header.relocationDataSize);

                // Compile filenames and add as files
                for (long i = 0; i < header.tagCount - 1; i++)
                {
                    reader.Position = dataInfos[0].dataOffset + tagInfos[i].textOffset;
                    string filename = reader.ReadZeroTerminatedString();
                    tagInfos[i].name = filename;
                    saveTag          = tagInfos;
                    if (!tagInfos[i].magic.StartsWith("\0"))
                    {
                        filename = filename + "." + tagInfos[i].magic.ToLower();
                    }
                    reader.Position = dataInfos[1].dataOffset + tagInfos[i].dataOffset;
                    FileEntry file = new FileEntry()
                    {
                        FileName = filename,
                        FileData = reader.ReadBytes(tagInfos[i + 1].dataOffset - tagInfos[i].dataOffset)
                    };
                    reader.Position = dataInfos[1].dataOffset + tagInfos[i].dataOffset;

                    // Load textures as a dds using the PTEX pointer
                    if (tagInfos[i].magic == "PTEX")
                    {
                        reader.Position += 88;
                        Ptex ptex = new Ptex()
                        {
                            ptexOffset = reader.Position,
                            width      = reader.ReadUInt32(),
                            height     = reader.ReadUInt32(),
                            unknown    = reader.ReadUInt32(),
                            ddsOffset  = reader.ReadUInt32(),
                            ddsSize    = reader.ReadInt32()
                        };
                        reader.Position  = dataInfos[header.dataInfoCount - 1].dataOffset;
                        reader.Position += ptex.ddsOffset;
                        DDS dds = new DDS(reader.ReadBytes(ptex.ddsSize))
                        {
                            WiiUSwizzle = false,
                            FileType    = FileType.Image,
                            Text        = filename + ".dds",
                            FileName    = filename,
                            CanReplace  = true
                        };
                        reader.Position  = dataInfos[header.dataInfoCount - 1].dataOffset;
                        reader.Position += ptex.ddsOffset;
                        ptexList.Add(ptex);
                        Nodes.Add(dds);
                        ddsList.Add(dds);
                        FileType = FileType.Image;
                        ptexCount++;
                    }

                    if (tagInfos[i].magic == "PMDL")
                    {
                        reader.Position += 8;
                        Pmdl pmdl = new Pmdl()
                        {
                            relocationDataCount = reader.ReadInt16(),
                            pmdlSize            = reader.ReadInt16()
                        };
                        reader.Position             += 4;
                        pmdl.modelTextOffset         = reader.ReadInt32();
                        reader.Position             += 36;
                        pmdl.sumVertCount            = reader.ReadInt32();
                        pmdl.faceStartOffsetRelative = reader.ReadInt32();
                        pmdl.vertexStartOffset       = reader.ReadInt32();
                        reader.Position             += 4;
                        pmdl.sumFaceCount            = reader.ReadInt32();
                        pmdl.faceStartOffset         = reader.ReadInt32();
                        reader.Position             += 48;
                        pmdl.subInfoCount            = reader.ReadInt32();
                        pmdl.offsetToSubInfosStart   = reader.ReadInt32();
                        pmdl.endOfSubInfos           = reader.ReadInt32();
                        reader.Position              = pmdl.offsetToSubInfosStart + dataInfos[1].dataOffset;
                        int[] subInfoStarts = new int[pmdl.subInfoCount];
                        subInfoStarts = reader.ReadInt32s(pmdl.subInfoCount);
                        SubInfoData[] subInfoDatas = new SubInfoData[pmdl.subInfoCount];
                        for (int t = 0; t < pmdl.subInfoCount; t++)
                        {
                            reader.Position = subInfoStarts[t] + dataInfos[1].dataOffset;
                            SubInfoData subInfoData = new SubInfoData()
                            {
                                unknown1             = reader.ReadInt32(),
                                unknown2             = reader.ReadInt32(),
                                unknown3             = reader.ReadInt32(),
                                unknown4             = reader.ReadInt32(),
                                unknown5             = reader.ReadInt32(),
                                unknown6             = reader.ReadInt32(),
                                vertexCount          = reader.ReadInt32(),
                                unknown8             = reader.ReadInt32(),
                                previousFaceCount    = reader.ReadInt32(),
                                faceCount            = reader.ReadInt32(),
                                unknown11            = reader.ReadInt32(),
                                unknown12            = reader.ReadInt32(),
                                vertexOffsetRelative = reader.ReadInt32(),
                                normalUVOffset       = reader.ReadInt32(),
                                faceOffset           = reader.ReadInt32(),
                                sameSizeorOffset     = reader.ReadInt32(),
                                sameSizeorOffset2    = reader.ReadInt32(),
                                sameSizeorOffset3    = reader.ReadInt32(),
                                sameSizeorOffset4    = reader.ReadInt32(),
                                sameSizeorOffset5    = reader.ReadInt32()
                            };

                            pmdl.verticesCount = subInfoData.vertexCount;
                            pmdl.facesCount    = subInfoData.faceCount;
                            subInfoDatas[t]    = subInfoData;
                        }
                        var renderedMesh = new GenericRenderedObject();
                        var renderer     = new GenericModelRenderer();
                        renderedMesh.ImageKey         = "mesh";
                        renderedMesh.SelectedImageKey = "mesh";
                        renderedMesh.Checked          = true;
                        int[] normalUVSize = new int[pmdl.subInfoCount];
                        if (pmdl.subInfoCount > 1)
                        {
                            int remember = 0;
                            for (int a = 0; a + 1 < pmdl.subInfoCount; a++)
                            {
                                pmdl.normalUVStart = subInfoDatas[a].normalUVOffset;
                                pmdl.normalUVEnd   = subInfoDatas[a + 1].normalUVOffset;
                                normalUVSize[a]    = (int)(pmdl.normalUVEnd - pmdl.normalUVStart);
                                remember           = a;
                            }
                            pmdl.normalUVStart = subInfoDatas[remember + 1].normalUVOffset;
                            pmdl.normalUVEnd   = subInfoDatas[remember + 1].normalUVOffset;
                        }
                        else if (pmdl.subInfoCount >= 1)
                        {
                            for (int x = 0; x < pmdl.subInfoCount; x++)
                            {
                                int stride = (int)(normalUVSize[x] / subInfoDatas[x].vertexCount);
                                reader.Position = pmdl.vertexStartOffset + subInfoDatas[x].vertexOffsetRelative;
                                for (int j = 0; j < subInfoDatas[x].vertexCount; j++)
                                {
                                    Vertex vert = new Vertex();
                                    vert.pos = new OpenTK.Vector3(reader.ReadInt32(), reader.ReadInt32(), reader.ReadInt32());
                                }
                            }
                        }
                    }
                    files.Add(file);
                }

                // For the last file, read until the end of the raw data section
                TagInfo lastTag = tagInfos[header.tagCount - 1];
                reader.Position = dataInfos[0].dataOffset + lastTag.textOffset;
                string filename2 = reader.ReadZeroTerminatedString();
                tagInfos[header.tagCount - 1].name = filename2;
                saveTag = tagInfos;
                if (!lastTag.magic.StartsWith("\0"))
                {
                    filename2 = filename2 + "." + lastTag.magic.ToLower();
                }
                reader.Position = dataInfos[1].dataOffset + lastTag.dataOffset;
                FileEntry file2 = new FileEntry()
                {
                    FileName = filename2,
                    FileData = reader.ReadBytes(dataInfos[1].dataSize - lastTag.dataOffset)
                };
                if (tagInfos[header.tagCount - 1].magic == "PTEX")
                {
                    reader.Position = dataInfos[1].dataOffset + tagInfos[header.tagCount - 1].dataOffset + 88;
                    Ptex ptex = new Ptex()
                    {
                        ptexOffset = reader.Position,
                        width      = reader.ReadUInt32(),
                        height     = reader.ReadUInt32(),
                        unknown    = reader.ReadUInt32(),
                        ddsOffset  = reader.ReadUInt32(),
                        ddsSize    = reader.ReadInt32()
                    };
                    reader.Position  = dataInfos[header.dataInfoCount - 1].dataOffset;
                    reader.Position += ptex.ddsOffset;
                    DDS dds = new DDS(reader.ReadBytes(ptex.ddsSize))
                    {
                        WiiUSwizzle = false,
                        FileType    = FileType.Image,
                        Text        = filename2 + ".dds",
                        FileName    = filename2,
                        CanReplace  = true,
                    };
                    reader.Position  = dataInfos[header.dataInfoCount - 1].dataOffset;
                    reader.Position += ptex.ddsOffset;
                    ptexList.Add(ptex);
                    Nodes.Add(dds);
                    ddsList.Add(dds);
                    FileType = FileType.Image;
                    ptexCount++;
                }
                if (tagInfos[0].magic == "enti")
                {
                    reader.Position = dataInfos[1].dataOffset + tagInfos[0].dataOffset;
                    var position     = reader.Position;
                    var entityHeader = new Entity.EntityHeader()
                    {
                        entitiesOffset = reader.ReadUInt32(),
                        entitiesCount  = reader.ReadUInt32(),
                        unknown1       = reader.ReadUInt32(),
                        unknown2       = reader.ReadUInt32()
                    };
                    reader.Position = position + entityHeader.entitiesOffset;
                    var properties = new Entity.Property[entityHeader.entitiesCount];
                    //var entities = new Entity.Entity[entityHeader.entitiesCount];
                    //for (int i = 0; i < entityHeader.entitiesCount; i++)
                    //{
                    //    entities[i].entityNameOffset = reader.ReadUInt32();
                    //    entities[i].propertiesCount = reader.ReadUInt16();
                    //    entities[i].propertiesCount2 = reader.ReadUInt16();
                    //    entities[i].propertiesOffset = reader.ReadUInt32();
                    //    entities[i].matrixOffset = reader.ReadUInt32();
                    //    entities[i].positionOffset = reader.ReadUInt32();
                    //    entities[i].unknown = reader.ReadUInt32();
                    //    entities[i].flag = reader.ReadUInt32();
                    //    entities[i].valuesOffset = reader.ReadUInt32();
                    //}

                    var entities = new Entity.Entity[entityHeader.entitiesCount];


                    for (int i = 0; i < entityHeader.entitiesCount; i++)
                    {
                        reader.Position = position + entities[i].propertiesOffset;
                    }
                }

                files.Add(file2);
            }
        }