private TreeNode SetWrapperNode(Node Node, TreeNode parentNode) { if (Node.IsMesh) { List <TreeNode> MeshNodes = new List <TreeNode>(); int i = 0; foreach (SubMesh subMesh in Node.SubMeshes) { GenericRenderedObject subMeshNode = new GenericRenderedObject(); subMeshNode.ImageKey = "mesh"; subMeshNode.SelectedImageKey = "mesh"; subMeshNode.Checked = true; subMeshNode.Text = $"{Node.Name} {i}"; subMeshNode.lodMeshes = new List <GenericRenderedObject.LOD_Mesh>(); var submsh = new GenericRenderedObject.LOD_Mesh(); submsh.PrimativeType = STPrimitiveType.Triangles; submsh.FirstVertex = 0; submsh.faces = subMesh.Faces; subMeshNode.lodMeshes.Add(submsh); subMeshNode.vertices = subMesh.Vertices; //Check duplicate models being rendered if (!AddedMeshes.Contains(subMesh)) { DrawableRenderer.Meshes.Add(subMeshNode); } AddedMeshes.Add(subMesh); if (i == 0) { parentNode.Nodes.Add(subMeshNode); } else { parentNode.Nodes[0].Nodes.Add(subMeshNode); } MeshNodes.Add(subMeshNode); i++; } var FirstNode = MeshNodes[0]; MeshNodes.Clear(); return(FirstNode); } else { var NewNode = new TreeNode(Node.Name); parentNode.Nodes.Add(NewNode); return(NewNode); } }
private void ToGenericMeshes(bool isBigEndian) { foreach (SubMeshInfo meshInfo in SubMeshInfos) { GenericRenderedObject genericMesh = new GenericRenderedObject(); genericMesh.Text = $"Mesh_{GenericMeshes.Count}"; GenericMeshes.Add(genericMesh); STGenericPolygonGroup polyGroup = new STGenericPolygonGroup(); genericMesh.PolygonGroups.Add(polyGroup); var mat = Materials[(int)meshInfo.TextureID]; mat.Text = $"Material_{meshInfo.TextureID}"; mat.Diffuse.TextureIndex = mat.TextureIndices[0][0]; polyGroup.Material = mat; Console.WriteLine($"TextureID {meshInfo.TextureID}"); Console.WriteLine($"MaterialID {meshInfo.MaterialID}"); //Set face type if (meshInfo.IndexBufferFormat == 3) { polyGroup.PrimativeType = STPrimitiveType.Triangles; } else if (meshInfo.IndexBufferFormat == 4) { polyGroup.PrimativeType = STPrimitiveType.TrangleStrips; } //Get faces var buffer = IndexBuffers[(int)meshInfo.IndexBufferID]; var indcies = buffer.GetIndices(isBigEndian, meshInfo.IndexBufferOffset, meshInfo.IndexBufferCount).ToArray(); for (int f = 0; f < indcies.Length; f++) { polyGroup.faces.Add((int)indcies[f]); } //Get vertices genericMesh.vertices.AddRange(GetVertices((int)meshInfo.VertexBufferID, (int)meshInfo.IndexIntoJointMap, meshInfo.VertexBufferOffset, isBigEndian)); } }
public void Load(System.IO.Stream stream) { CanSave = true; Text = FileName; //Set renderer //Load it to a drawables list Renderer = new MDL_Renderer(); DrawableContainer.Name = FileName; DrawableContainer.Drawables.Add(Renderer); using (var reader = new FileReader(stream)) { reader.SetByteOrder(true); while (reader.EndOfStream == false) { long chunkStart = reader.Position; int opcode = reader.ReadInt32(); int lengthOfStruct = reader.ReadInt32(); // basic error checking if ((chunkStart & 0x1F) != 0) { throw new Exception($"Chunk start ({chunkStart}) not on boundary!"); } switch (opcode) { case 0x10: // VERTICES int vertexCount = reader.ReadInt32(); Vertices = new Vertex[vertexCount]; SkipPadding(reader, 0x20); for (int i = 0; i < vertexCount; i++) { float x = reader.ReadSingle(); float y = reader.ReadSingle(); float z = reader.ReadSingle(); Vertices[i] = new Vertex { pos = new Vector3(x, y, z) }; } SkipPadding(reader, 0x20); break; case 0x11: int vertexNormalCount = reader.ReadInt32(); VertexNormals = new Vertex[vertexNormalCount]; SkipPadding(reader, 0x20); for (int i = 0; i < vertexNormalCount; i++) { float x = reader.ReadSingle(); float y = reader.ReadSingle(); float z = reader.ReadSingle(); VertexNormals[i] = new Vertex { nrm = new Vector3(x, y, z) }; } SkipPadding(reader, 0x20); break; case 0x13: // COLOURS int colorCount = reader.ReadInt32(); Colors = new Vertex[colorCount]; SkipPadding(reader, 0x20); for (int i = 0; i < colorCount; i++) { byte x = reader.ReadByte(); byte y = reader.ReadByte(); byte z = reader.ReadByte(); byte w = reader.ReadByte(); Colors[i] = new Vertex { col = new Vector4(x, y, z, w) }; } SkipPadding(reader, 0x20); break; case 0x50: int meshCount = reader.ReadInt32(); SkipPadding(reader, 0x20); for (int i = 0; i < meshCount; i++) { //Create a renderable object for our mesh var renderedMesh = new GenericRenderedObject { Checked = true, ImageKey = "mesh", SelectedImageKey = "mesh", Text = $"Mesh {i}" }; Nodes.Add(renderedMesh); Renderer.Meshes.Add(renderedMesh); STGenericPolygonGroup polyGroup = new STGenericPolygonGroup(); renderedMesh.PolygonGroups.Add(polyGroup); reader.ReadInt32(); int vtxDescriptor = reader.ReadInt32(); int mtxGroupCount = reader.ReadInt32(); Console.WriteLine("mtxGroupCount " + mtxGroupCount); for (int a = 0; a < mtxGroupCount; a++) { int unkCount = reader.ReadInt32(); for (int unkIter = 0; unkIter < unkCount; unkIter++) { reader.ReadInt16(); } int dispListCount = reader.ReadInt32(); Console.WriteLine("dispListCount " + dispListCount); for (int b = 0; b < dispListCount; b++) { reader.ReadInt32(); reader.ReadInt32(); int displacementSize = reader.ReadInt32(); SkipPadding(reader, 0x20); long end_displist = reader.Position + displacementSize; Console.WriteLine("end_displist " + end_displist); Console.WriteLine("displacementSize " + displacementSize); Console.WriteLine("reader.Position " + reader.Position); while (reader.Position < end_displist) { byte faceOpCode = reader.ReadByte(); if (faceOpCode == 0x98 || faceOpCode == 0xA0) { short vCount = reader.ReadInt16(); int[] polys = new int[vCount]; for (int vc = 0; vc < vCount; vc++) { if ((vtxDescriptor & 0x1) == 0x1) { reader.ReadByte(); // Position Matrix } if ((vtxDescriptor & 0x2) == 0x2) { reader.ReadByte(); // tex1 matrix } ushort vtxPosIndex = reader.ReadUInt16(); uint normalID = 0; if (VertexNormals.Length > 0) { normalID = reader.ReadUInt16(); } uint colorID = 0; if ((vtxDescriptor & 0x4) == 0x4) { colorID = reader.ReadUInt16(); } int tmpVar = vtxDescriptor >> 3; uint texCoordID = 0; for (int c = 0; c < 8; c++) { if ((tmpVar & 0x1) == 0x1) { if (c == 0) { texCoordID = reader.ReadUInt16(); } } tmpVar >>= 1; } Vertex vert = new Vertex { pos = Vertices[vtxPosIndex].pos, nrm = VertexNormals[normalID].nrm, //col = Colors[colorID].col }; polys[vc] = renderedMesh.vertices.Count; renderedMesh.vertices.Add(vert); } List <Triangle> curPolys = ToTris(polys, faceOpCode); foreach (Triangle poly in curPolys) { Console.WriteLine($"{poly.A} {poly.B} {poly.C}"); polyGroup.faces.Add(poly.A); polyGroup.faces.Add(poly.B); polyGroup.faces.Add(poly.C); } } } } } Console.WriteLine("vertices " + renderedMesh.vertices.Count); Console.WriteLine("faces " + renderedMesh.PolygonGroups[0].faces.Count); Console.WriteLine("Vertices " + Vertices.Length); } break; default: reader.Seek(lengthOfStruct, System.IO.SeekOrigin.Current); break; } } } }
public void Load(System.IO.Stream stream) { CanSave = true; //Set renderer Renderer = new GMX_Renderer(); DrawableContainer.Name = FileName; DrawableContainer.Drawables.Add(Renderer); //Read file GMXHeader = new Header(); GMXHeader.Read(new FileReader(stream)); int MeshIndex = 0; for (int i = 0; i < GMXHeader.Meshes.Count; i++) { var renderedMesh = new GenericRenderedObject(); renderedMesh.ImageKey = "mesh"; renderedMesh.SelectedImageKey = "mesh"; renderedMesh.Checked = true; if (GMXHeader.Meshes[i].VertexGroup != null) { renderedMesh.vertices = GMXHeader.Meshes[i].VertexGroup.Vertices; } if (GMXHeader.Meshes[i].IndexGroup != null) { renderedMesh.lodMeshes = new List <STGenericObject.LOD_Mesh>(); var msh = new STGenericObject.LOD_Mesh(); msh.PrimitiveType = STPolygonType.Triangle; msh.FirstVertex = 0; /* int VertexID = 0; * for (int f = 0; f < GMXHeader.Meshes[i].VertexCount; f+= 3) * { * msh.faces.AddRange(new List<int>() { VertexID + 2, VertexID + 1, VertexID }); * VertexID++; * }*/ for (int f = 0; f < GMXHeader.Meshes[i].IndexGroup.Indices.Length; f++) { msh.faces.AddRange(new int[3] { GMXHeader.Meshes[i].IndexGroup.Indices[f++], GMXHeader.Meshes[i].IndexGroup.Indices[f++], GMXHeader.Meshes[i].IndexGroup.Indices[f] }); } renderedMesh.lodMeshes.Add(msh); } renderedMesh.Tag = GMXHeader.Meshes[i]; if (GMXHeader.Meshes[i].VertexGroup != null) { renderedMesh.Text = $"Mesh ({MeshIndex++})"; Nodes.Add(renderedMesh); Renderer.Meshes.Add(renderedMesh); } } }
/// <summary> /// Computes mesh and bone cloth drivers /// </summary> public void ComputeClothDrivers() { var boneList = G1MSkeleton.GenericSkeleton.bones; var nunProps = new List <NUNO.NUNOType0303Struct>(); uint nunoOffset = 0; if (NUNO != null) { nunoOffset = (uint)NUNO.NUNO0303StructList.Count; foreach (var nuno0303 in NUNO.NUNO0303StructList) { nunProps.Add(nuno0303); } } if (NUNV != null) { foreach (var nuno0303 in NUNV.NUNV0303StructList) { nunProps.Add(nuno0303); } } foreach (var prop in nunProps) { int boneStart = boneList.Count; var parentBone = Model.JointInfos[prop.BoneParentID - 1].JointIndices[0]; GenericRenderedObject mesh = new GenericRenderedObject(); mesh.Text = $"driver_{boneList.Count}"; mesh.Checked = true; Renderer.Meshes.Add(mesh); meshNode.Nodes.Add(mesh); var polyGroup = new STGenericPolygonGroup(); polyGroup.Material = new STGenericMaterial(); polyGroup.Material.Text = "driver_cloth"; polyGroup.PrimativeType = STPrimitiveType.Triangles; mesh.PolygonGroups.Add(polyGroup); for (int p = 0; p < prop.Points.Length; p++) { var point = prop.Points[p]; var link = prop.Influences[p]; STBone b = new STBone(G1MSkeleton.GenericSkeleton); b.Text = $"CP_{boneList.Count}"; b.FromTransform(OpenTK.Matrix4.Identity); b.Position = point.Xyz; b.parentIndex = link.P3; if (b.parentIndex == -1) { b.parentIndex = (int)parentBone; } else { b.parentIndex += boneStart; b.Position = OpenTK.Vector3.TransformPosition( point.Xyz, G1MSkeleton.GenericSkeleton.GetBoneTransform((int)parentBone) * G1MSkeleton.GenericSkeleton.GetBoneTransform(b.parentIndex).Inverted()); } boneList.Add(b); G1MSkeleton.GenericSkeleton.reset(); G1MSkeleton.GenericSkeleton.update(); mesh.vertices.Add(new Vertex() { pos = Vector3.TransformPosition(Vector3.Zero, G1MSkeleton.GenericSkeleton.GetBoneTransform(boneList.Count - 1)), boneWeights = new List <float>() { 1 }, boneIds = new List <int>() { boneList.Count - 1 }, }); if (link.P1 > 0 && link.P3 > 0) { polyGroup.faces.Add(p); polyGroup.faces.Add(link.P1); polyGroup.faces.Add(link.P3); } if (link.P2 > 0 && link.P4 > 0) { polyGroup.faces.Add(p); polyGroup.faces.Add(link.P2); polyGroup.faces.Add(link.P4); } } mesh.CalculateNormals(); } }
private void ReadMeshChunk(FileReader reader) { int meshCount = reader.ReadInt32(); SkipPadding(reader, 0x20); for (int mIdx = 0; mIdx < meshCount; mIdx++) { //Create a renderable object for our mesh var renderedMesh = new GenericRenderedObject { Checked = true, ImageKey = "mesh", SelectedImageKey = "mesh", Text = $"Mesh {mIdx}" }; Nodes.Add(renderedMesh); Renderer.Meshes.Add(renderedMesh); STGenericPolygonGroup polyGroup = new STGenericPolygonGroup(); renderedMesh.PolygonGroups.Add(polyGroup); renderedMesh.BoneIndex = reader.ReadInt32(); int vtxDescriptor = reader.ReadInt32(); int mtxGroupCount = reader.ReadInt32(); for (int mgIdx = 0; mgIdx < mtxGroupCount; mgIdx++) { int dependencyCount = reader.ReadInt32(); for (int ll = 0; ll < dependencyCount; ll++) { reader.ReadInt16(); } int dListCount = reader.ReadInt32(); for (int dlIdx = 0; dlIdx < dListCount; dlIdx++) { int flags = reader.ReadInt32(); int unk1 = reader.ReadInt32(); int dataSize = reader.ReadInt32(); SkipPadding(reader, 0x20); long endPosition = reader.Position + dataSize; while (reader.Position < endPosition) { byte faceType = reader.ReadByte(); if (faceType == 0x98 || faceType == 0xA0) { short faceCount = reader.ReadInt16(); int[] polygons = new int[faceCount]; for (int fIdx = 0; fIdx < faceCount; fIdx++) { if ((vtxDescriptor & 1) == 1) { reader.ReadByte(); // posmat index } if ((vtxDescriptor & 2) == 2) { reader.ReadByte(); // tex1 index } ushort vtxIdx = reader.ReadUInt16(); ushort nrmIdx = 0; if (VertexNormals.Length > 0) { nrmIdx = reader.ReadUInt16(); } ushort colIdx = 0; if ((vtxDescriptor & 4) == 4) { colIdx = reader.ReadUInt16(); } int txCoordIdx = 0; int txCoordDescriptor = vtxDescriptor >> 3; for (int tcoordIdx = 0; tcoordIdx < 8; tcoordIdx++) { if ((txCoordDescriptor & 1) == 0x1) { // Only read for the first texcoord txCoordIdx = reader.ReadInt16(); txCoordDescriptor >>= 1; } } Vertex newVertex = new Vertex { pos = Vertices[vtxIdx] }; int envIdx = 0; if (Envelopes.Length > envIdx) { for (int i = 0; i < Envelopes[envIdx].Indices?.Length; i++) { newVertex.boneIds.Add(Envelopes[envIdx].Indices[i]); newVertex.boneWeights.Add(Envelopes[envIdx].Weights[i]); } } if (VertexNormals != null) { newVertex.nrm = VertexNormals[nrmIdx]; } if (Colors != null) { newVertex.col = Colors[colIdx]; } polygons[fIdx] = renderedMesh.vertices.Count; renderedMesh.vertices.Add(newVertex); } List <Triangle> currentPolygons = ToTris(polygons, faceType); Console.WriteLine($"faceType {faceType} polygons {polygons.Length} "); foreach (Triangle triangle in currentPolygons) { if (faceType == 0x98) { polyGroup.faces.Add(triangle.B); polyGroup.faces.Add(triangle.C); polyGroup.faces.Add(triangle.A); } else { polyGroup.faces.Add(triangle.C); polyGroup.faces.Add(triangle.B); polyGroup.faces.Add(triangle.A); } } } } } } } }
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); } }