public void Open(FileItem File) { var chunks = GetChunks(File.GetFileBinary()); var outputpath = Path.GetDirectoryName(File.FilePath); int i = 0; foreach (var c in chunks) { System.IO.File.WriteAllBytes(outputpath + "\\" + i + "_" + c.Flags.ToString("X8"), c.Data); //HSF h = new HSF(); // h.Open(new FileItem(outputpath + "\\" + i + "_" + c.Flags.ToString("X8"))); //mod = h; i++; } }
public void Open(FileItem File) { var Data = File.GetFileBinary(); byte[] DecompressedData = null; /*using (DataReader reader = new DataReader(new MemoryStream(Data))) * { * reader.BigEndian = true; * reader.Seek(0x14); // skip header stuff * ushort CompressedChunkCount = reader.ReadUInt16(); * * ushort[] CompressedSize = new ushort[CompressedChunkCount]; * for(int i = 0; i < CompressedChunkCount; i++) * { * CompressedSize[i] = reader.ReadUInt16(); * reader.ReadUInt16(); * } * * MemoryStream data = new MemoryStream(); * using (BinaryWriter o = new BinaryWriter(data)) * { * foreach (ushort compsize in CompressedSize) * { * o.Write(Metanoia.Tools.Decompress.ZLIB(reader.ReadBytes(compsize))); * } * DecompressedData = data.GetBuffer(); * data.Close(); * System.IO.File.WriteAllBytes("LBP\\Decomp.bin", DecompressedData); * } * * reader.PrintPosition(); * }*/ using (DataReader reader = new DataReader(new MemoryStream(File.GetFileBinary()))) { reader.BigEndian = true; // bit pack hell reader.Seek(0x10); int bufferSizeCount = reader.ReadInt32(); int uvchannelCount = reader.ReadInt32(); int morphCount = reader.ReadInt32(); Console.WriteLine(bufferSizeCount); reader.Seek(0x220); Console.WriteLine(reader.ReadSingle() + " " + reader.ReadSingle() + " " + reader.ReadInt32()); Console.WriteLine(reader.ReadSingle() + " " + reader.ReadSingle() + " " + reader.ReadSingle() + " " + reader.ReadInt32()); int[] bufferOffsets = new int[bufferSizeCount]; for (int i = 0; i < bufferSizeCount; i++) { bufferOffsets[i] = reader.ReadInt32(); } var vertexBufferSize = reader.ReadUInt32(); var start = reader.Position; PositionBuffer = new Vector4[bufferOffsets[0] / 0x10]; for (int i = 0; i < PositionBuffer.Length; i++) { PositionBuffer[i] = new Vector4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); } reader.Seek(start + vertexBufferSize); var uvbufferSize = reader.ReadUInt32(); UV0Buffer = new Vector2[uvbufferSize / 0x18]; UV1Buffer = new Vector2[uvbufferSize / 0x18]; UV2Buffer = new Vector2[uvbufferSize / 0x18]; for (int i = 0; i < uvbufferSize / 0x18; i++) { if (uvchannelCount > 0) { UV0Buffer[i] = new Vector2(reader.ReadSingle(), reader.ReadSingle()); } if (uvchannelCount > 1) { UV1Buffer[i] = new Vector2(reader.ReadSingle(), reader.ReadSingle()); } if (uvchannelCount > 2) { UV2Buffer[i] = new Vector2(reader.ReadSingle(), reader.ReadSingle()); } } Console.WriteLine(PositionBuffer.Length + " " + UV0Buffer.Length); var trianglebufferSize = reader.ReadInt32(); IndexBuffer = new short[trianglebufferSize / 2]; for (int i = 0; i < IndexBuffer.Length; i++) { IndexBuffer[i] = reader.ReadInt16(); } uint boneCount = reader.ReadUInt32(); reader.Skip(0x22 * boneCount); uint boneCount2 = reader.ReadUInt32(); var boneStart = reader.Position; Matrix4[] wtransforms = new Matrix4[boneCount2]; Matrix4[] itransforms = new Matrix4[boneCount2]; for (int i = 0; i < boneCount2; i++) { reader.Seek((uint)(boneStart + (i * 0x114))); // 0xD4 for older versions var bone = new GenericBone(); bone.Name = reader.ReadString((uint)(boneStart + (i * 0x114)), -1); reader.Skip(0x28); bone.ParentIndex = reader.ReadInt32(); reader.Skip(0x8); wtransforms[i] = new Matrix4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); itransforms[i] = new Matrix4(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); if (bone.ParentIndex != -1 && bone.ParentIndex != 0) { var par = skeleton.GetWorldTransform(bone.ParentIndex).Inverted(); var reltransform = wtransforms[i] * par; bone.Transform = reltransform; bone.QuaternionRotation = wtransforms[i].ExtractRotation() * par.ExtractRotation(); } else if (i != 0) { bone.Transform = wtransforms[i]; } else { bone.Transform = Matrix4.Identity; } skeleton.Bones.Add(bone); } reader.Seek(boneStart + (boneCount2 * 0x114)); var boneIndexTableCount = reader.ReadUInt32(); reader.Skip(boneIndexTableCount * 2); var bonecountTableCount = reader.ReadUInt32(); reader.Skip(bonecountTableCount); var boneIndexTableCount2 = reader.ReadUInt32(); reader.Skip(boneIndexTableCount2 * 2); reader.Skip(5); reader.Skip(reader.ReadUInt32() * 0x10); // vector 4s? reader.Skip(reader.ReadUInt32() * 0x40); // some matrices? reader.Skip(reader.ReadUInt32() * 0x4); // float table? maybe weights? int clusterStringCount = reader.ReadInt32(); var clusterstringstart = reader.Position; for (int i = 0; i < clusterStringCount; i++) { } reader.Seek(clusterstringstart + 0x20 * (uint)clusterStringCount); reader.Skip(reader.ReadUInt32() * 0x8); // ?? may have something to do with weighting reader.Skip(reader.ReadUInt32() * 0x4); // ?? may have something to do with weighting reader.Skip(reader.ReadUInt32() * 0x4); // ?? another float table?? reader.PrintPosition(); } }
public void Open(FileItem File) { var igb = new IGBFile(File.GetFileBinary()); var igbSkel = new IGSkeleton(igb); Matrix4[] transforms = new Matrix4[igbSkel.Bones.Count]; Matrix4[] inverts = new Matrix4[igbSkel.Bones.Count]; int boneIndex = 0; foreach (var v in igbSkel.Bones) { if (v == null) continue; GenericBone b = new GenericBone(); b.Name = v.Name; b.ParentIndex = v.ParentIndex; transforms[boneIndex] = new Matrix4( v.WorldInverseMatrix.M11, v.WorldInverseMatrix.M12, v.WorldInverseMatrix.M13, v.WorldInverseMatrix.M14, v.WorldInverseMatrix.M21, v.WorldInverseMatrix.M22, v.WorldInverseMatrix.M23, v.WorldInverseMatrix.M24, v.WorldInverseMatrix.M31, v.WorldInverseMatrix.M32, v.WorldInverseMatrix.M33, v.WorldInverseMatrix.M34, v.WorldInverseMatrix.M41, v.WorldInverseMatrix.M42, v.WorldInverseMatrix.M43, v.WorldInverseMatrix.M44); inverts[boneIndex] = transforms[boneIndex].Inverted(); b.Transform = inverts[boneIndex]; boneIndex++; Skeleton.Bones.Add(b); } foreach (var b in Skeleton.Bones) { if (b.ParentIndex != -1) { b.Transform = inverts[b.ParentIndex] * transforms[Skeleton.Bones.IndexOf(b)]; b.Transform = b.Transform.Inverted(); var position = igbSkel.Bones[Skeleton.Bones.IndexOf(b)].Position; b.Position = new Vector3(position.X, position.Y, position.Z); } } var vertexBuffers = IGVertexAccessor.ToDivaModels(igb); Model.Skeleton = Skeleton; Console.WriteLine(vertexBuffers.Count); foreach (var model in vertexBuffers) { GenericMesh m = new GenericMesh(); m.Name = model.Name; if (m.Name.Equals("")) m.Name = "Mesh_" + vertexBuffers.IndexOf(model); Console.WriteLine(m.Name + " " + !(model.Texture==null)); if(model.Texture != null) { GenericTexture t = new GenericTexture(); t.Name = System.IO.Path.GetFileNameWithoutExtension(model.Texture.Name); t.Width = (uint)model.Texture.Width; t.Height = (uint)model.Texture.Height; t.Mipmaps.Add(model.Texture.RGBA); if(!Model.MaterialBank.ContainsKey(t.Name)) Model.TextureBank.Add(t.Name, t); GenericMaterial mat = new GenericMaterial(); mat.TextureDiffuse = t.Name; if (!Model.MaterialBank.ContainsKey(t.Name)) Model.MaterialBank.Add(t.Name, mat); m.MaterialName = t.Name; } foreach (var mesh in model.Mesh) { var vertices = ToGenericVertices(mesh.Vertices); foreach (var dl in mesh.DisplayList) { if (dl.PrimitiveType == PrimType.Triangles) { foreach(var f in dl.Indices) m.Vertices.Add(vertices[f]); } if (dl.PrimitiveType == PrimType.TriangleStrip) { var tempList = new List<GenericVertex>(); foreach (var f in dl.Indices) tempList.Add(vertices[f]); Tools.TriangleConverter.StripToList(tempList, out tempList); m.Vertices.AddRange(tempList); } } } if(model.SingleBindBone != null && model.SingleBindBone != "") { var singleBone = Skeleton.Bones.Find(e => e.Name.Equals(model.SingleBindBone)); var singleBindTransform = Skeleton.GetWorldTransform(singleBone); var singleBindIndex = Skeleton.Bones.IndexOf(singleBone); for (int i = 0; i < m.VertexCount;i++) { var vert = m.Vertices[i]; vert.Pos = Vector3.TransformPosition(vert.Pos, singleBindTransform); vert.Nrm = Vector3.TransformNormal(vert.Nrm, singleBindTransform); vert.Bones = new Vector4(singleBindIndex, 0, 0, 0); vert.Weights = new Vector4(1, 0, 0, 0); m.Vertices[i] = vert; } } m.Optimize(); Model.Meshes.Add(m); } }
public void Open(FileItem File) { using (DataReader reader = new DataReader(new MemoryStream(File.GetFileBinary()))) { reader.BigEndian = true; var header = ParseVAPS(reader); uint polyOff = 0; for (int h = 0; h < header.Offsets.Length; h++) { reader.Seek(header[h]); var contentHeader = ParseVAPS(reader); switch (contentHeader.ContentType) { case 0x0C: // Bones var boneCount = reader.ReadInt16(); reader.Position += 0xA; for (int i = 0; i < boneCount; i++) { GenericBone b = new GenericBone(); b.Name = "Bone_" + i; Skeleton.Bones.Add(b); b.QuaternionRotation = new Quaternion(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); b.Position = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); b.Scale = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); b.ParentIndex = reader.ReadSByte(); reader.Position += 3; } break; case 0x03: // textures Console.WriteLine(contentHeader.Indices.Length + " " + contentHeader.Offsets.Length); break; case 0x04: // mesh objects polyOff = header[h]; break; case 0x09: // uv buffer break; case 0x0E: // materials? break; case 0x0D: // sounds? break; case 0x16: // vertices ReadVertices(reader); break; default: System.Diagnostics.Debug.WriteLine("Unknown content type " + contentHeader.ContentType.ToString("X") + " " + reader.Position.ToString("X")); break; } } //Polygons reader.Seek(polyOff); ParseVAPS(reader); ReadPolygons(reader); } }
public void Open(FileItem File) { ParseOBE(File.GetFileBinary()); }
public void Open(FileItem File) { dynamic stuff = JObject.Parse(System.Text.Encoding.UTF8.GetString(File.GetFileBinary())); Model = new GenericModel(); Model.Skeleton = new GenericSkeleton(); var skeletons = stuff.skeletons; foreach (var skel in skeletons) { if (((string)skel.name).Contains("carryable")) { foreach (var bone in skel.bones) { var gBone = new GenericBone(); Model.Skeleton.Bones.Add(gBone); gBone.Name = "Bone_" + bone.index; gBone.ParentIndex = bone.parent; gBone.Position = new OpenTK.Vector3((float)bone.local.position[0], (float)bone.local.position[1], (float)bone.local.position[2]); gBone.QuaternionRotation = new OpenTK.Quaternion((float)bone.local.rotation[0], (float)bone.local.rotation[1], (float)bone.local.rotation[2], (float)bone.local.rotation[3]).Inverted(); gBone.Scale = new OpenTK.Vector3((float)bone.local.scale[0], (float)bone.local.scale[1], (float)bone.local.scale[2]); } break; } } var models = stuff.models; foreach (var modl in models) { foreach (var batch in modl.batches) { GenericMesh mesh = new GenericMesh(); Model.Meshes.Add(mesh); mesh.Name = batch.id; foreach (int index in batch.indices) { var vertex = new GenericVertex(); if (((JArray)batch.positions).Count > 0) { vertex.Pos = new OpenTK.Vector3((float)batch.positions[index * 3 + 0], (float)batch.positions[index * 3 + 1], (float)batch.positions[index * 3 + 2]); } if (((JArray)batch.normals).Count > 0) { vertex.Nrm = new OpenTK.Vector3((float)batch.normals[index * 3 + 0], (float)batch.normals[index * 3 + 1], (float)batch.normals[index * 3 + 2]); } if (((JArray)batch.uvs).Count > 0) { vertex.UV0 = new OpenTK.Vector2((float)batch.uvs[index * 2 + 0], (float)batch.uvs[index * 2 + 1]); } if (((JArray)batch.uvs2).Count > 0) { vertex.UV1 = new OpenTK.Vector2((float)batch.uvs2[index * 2 + 0], (float)batch.uvs2[index * 2 + 1]); } if (((JArray)batch.uvs3).Count > 0) { vertex.UV2 = new OpenTK.Vector2((float)batch.uvs3[index * 2 + 0], (float)batch.uvs3[index * 2 + 1]); } if (((JArray)batch.colors).Count > 0) { vertex.Clr = new OpenTK.Vector4((float)batch.colors[index * 4 + 0] * 255, (float)batch.colors[index * 4 + 1] * 255, (float)batch.colors[index * 4 + 2] * 255, (float)batch.colors[index * 4 + 3] * 255); } if (((JArray)batch.bindings).Count > 0) { vertex.Bones = new OpenTK.Vector4((int)batch.bindings[index * 4 + 0], (int)batch.bindings[index * 4 + 1], (int)batch.bindings[index * 4 + 2], (int)batch.bindings[index * 4 + 3]); } if (((JArray)batch.weights).Count > 0) { vertex.Weights = new OpenTK.Vector4(((int)batch.weights[index * 4 + 0]) / 255f, ((int)batch.weights[index * 4 + 1]) / 255f, ((int)batch.weights[index * 4 + 2]) / 255f, ((int)batch.weights[index * 4 + 3]) / 255f); } mesh.Vertices.Add(vertex); } mesh.Optimize(); } } }
public void Open(FileItem File) { var Data = File.GetFileBinary(); Model = new GenericModel(); Model.Skeleton = new GenericSkeleton(); Model.Skeleton.RotationOrder = RotationOrder.ZYX; // decompress using (DataReader reader = new DataReader(new MemoryStream(Data))) { reader.BigEndian = true; if (reader.BaseStream.Length < 8 || !reader.ReadString(8).Equals("PERS-SZP")) { // not compressed } else { reader.BigEndian = true; uint compressedoffset = reader.ReadUInt32(); reader.Seek(compressedoffset); Data = Tools.Decompress.YAY0(reader.ReadBytes((int)(reader.BaseStream.Length - compressedoffset))); } } // decode file contents using (DataReader reader = new DataReader(new MemoryStream(Data))) { reader.BigEndian = true; reader.Seek(0x8); if (!reader.ReadString(8).Equals("FRAGMENT")) { return; } reader.Seek(0x10); uint DataOffset = reader.ReadUInt32(); uint RelocationTableOffset = reader.ReadUInt32(); reader.Skip(4); // filesize reader.Skip(4); // tableOffset again // Relocation Table reader.Seek(RelocationTableOffset); int entryCount = reader.ReadInt32(); int[] offsets = new int[entryCount]; for (int i = 0; i < entryCount; i++) { int mask = 0xFFFF; offsets[i] = reader.ReadInt32(); if (RelocationTableOffset > 0xFFFF) { mask = 0x1FFFF; // hack } uint temp = reader.Position; reader.Seek((uint)(offsets[i] & 0x1FFFF)); reader.WriteInt32At(reader.ReadInt32() & mask, offsets[i] & 0x1FFFF); reader.Seek((uint)(offsets[i] & 0x1FFFF)); reader.Seek(temp); } // main data reader.Seek(DataOffset); reader.Skip(0x10); uint mainOffset = reader.ReadUInt32(); // main stuff reader.Seek(mainOffset); reader.Skip(8); // i dunno uint offsetToTextureOffset = reader.ReadUInt32(); reader.Seek(offsetToTextureOffset); uint textureOffset = reader.ReadUInt32(); // may be objects instead of just textures reader.Seek(textureOffset); int TextureCount = reader.ReadInt32() & 0xFFFF; // should have 0x17 in front int PaletteCount = reader.ReadInt16(); int VertexCount = reader.ReadInt16(); uint TextureOffset = reader.ReadUInt32(); uint PaletteOffset = reader.ReadUInt32(); uint VertexOffset = reader.ReadUInt32(); reader.Skip(0x1C); //I dunno uint objectOffset = reader.ReadUInt32(); // Textures------------------------------------------------------- List <GenericTexture> Textures = new List <GenericTexture>(); List <byte[]> Palettes = new List <byte[]>(); //Read Palettes reader.Seek(PaletteOffset); for (int i = 0; i < PaletteCount; i++) { int colorcount = reader.ReadInt32(); uint OffsetData = reader.ReadUInt32(); int OffsetSomething = reader.ReadInt32(); Palettes.Add(reader.GetSection(OffsetData, colorcount * 2)); } // Read Textures? reader.Seek(TextureOffset); //Console.WriteLine(reader.pos().ToString("x")); for (int i = 0; i < TextureCount; i++) { int format = reader.ReadByte(); int bitsize = reader.ReadByte(); uint width = reader.ReadUInt16(); uint height = reader.ReadUInt16(); uint size = reader.ReadUInt16(); // sometimes 8 maybe an id? pointer? uint texDataOffset = reader.ReadUInt32() & 0x1FFFF; Console.WriteLine("Texture " + format + " " + bitsize + " " + size + " " + width + " " + height); GenericTexture tex = new GenericTexture(); Textures.Add(tex); tex.Name = "Texture_" + i; byte[] data; tex.Width = width; tex.Height = height; tex.PixelFormat = PixelFormat.Rgba; if (format == 4) { // Raw if (bitsize == 1) //RGBA { data = reader.GetSection(texDataOffset, (int)size * bitsize); tex.Mipmaps.Add(data); tex.InternalFormat = PixelInternalFormat.Luminance8; tex.PixelFormat = PixelFormat.Luminance; } } else if (format == 2) { // Paletted if (bitsize == 0) //4bpp { data = reader.GetSection(texDataOffset, (int)size / 2); tex.Mipmaps.Add(data); tex.InternalFormat = PixelInternalFormat.Alpha4; } else if (bitsize == 1) //8bpp { data = reader.GetSection(texDataOffset, (int)size * bitsize); tex.Mipmaps.Add(data); tex.InternalFormat = PixelInternalFormat.Alpha8; } } else { if (bitsize == 2) { data = reader.GetSection(texDataOffset, (int)size * bitsize); // swap endian for (int j = 0; j < data.Length / 2; j++) { byte temp = data[j * 2]; data[j * 2] = data[(j * 2) + 1]; data[(j * 2) + 1] = temp; } tex.Mipmaps.Add(data); tex.InternalFormat = PixelInternalFormat.Rgb5A1; } else if (bitsize == 3) { tex.InternalFormat = PixelInternalFormat.Rgba8; data = reader.GetSection(texDataOffset, (int)size * 4); tex.Mipmaps.Add(data); } } } // Objects-------------------------------------------------------- // now parse until end bool done = false; Stack <GenericBone> boneStack = new Stack <GenericBone>(); GenericBone parentBone = null; reader.Seek(objectOffset); reader.Skip(4); // idk int maybeCount = reader.ReadInt32(); string currentMaterialName = ""; GenericMaterial currentMaterial = new GenericMaterial(); GenericBone CurrentBone = null; while (!done) { int doff, temp; //Console.WriteLine(reader.Position().ToString("x") + " " + reader.ReadByte().ToString("x")); reader.ReadByte(); reader.Seek(reader.Position - 1); switch (reader.ReadByte()) { case 0x03: // Perhaps some object offset? Offset goes to beginning of file. Material maybe? reader.Skip(0x08 - 1); break; case 0x05: reader.Skip(0x04 - 1); boneStack.Push(CurrentBone); parentBone = boneStack.Peek(); break; case 0x06: reader.Skip(0x04 - 1); if (boneStack.Count > 0) { boneStack.Pop(); if (boneStack.Count > 0) { parentBone = boneStack.Peek(); } } break; case 0x08: reader.Skip(4 - 1); int s1 = reader.ReadByte() & 0x7F; reader.Skip(1); int s2 = reader.ReadInt16(); reader.Skip(4); // pops matrix // maybe pop until you get to this bone? //Also maybe some texture thing? Console.WriteLine("What dis?" + " " + s1 + " " + s2); //throw new Exception("Weird Special Thing"); /*for (int i = popto - s1; i < popto + s2; i++) * { * Bone bo = skel.GetBoneByID(i); * boneStack.Push(bo); * }*/ break; case 0x18: // idk has 4 values reader.Skip(0x08 - 1); break; case 0x1D: int id = reader.ReadByte(); int what = reader.ReadByte(); int parent = (sbyte)reader.ReadByte(); // read bone properties Vector3 trans = new Vector3((short)reader.ReadInt16(), (short)reader.ReadInt16(), (short)reader.ReadInt16()); Vector3 rot = new Vector3((short)reader.ReadInt16() / 180, ((short)reader.ReadInt16()) / 180, (short)reader.ReadInt16() / 180); // to radians rot.X = (rot.X * (float)Math.PI) / 180f; rot.Y = (rot.Y * (float)Math.PI) / 180f; rot.Z = (rot.Z * (float)Math.PI) / 180f; //rot = new Vector3(rot.Z, rot.X, rot.Y); Vector3 scale = new Vector3(); scale.X = reader.ReadInt16() + reader.ReadInt16() / (float)0xFFFF; scale.Y = reader.ReadInt16() + reader.ReadInt16() / (float)0xFFFF; scale.Z = reader.ReadInt16() + reader.ReadInt16() / (float)0xFFFF; int parent2 = boneStack.Count; GenericBone b = new GenericBone(); b.Name = "Bone_" + id; if (parentBone != null) { b.ParentIndex = Model.Skeleton.IndexOf(parentBone); } else { b.ParentIndex = -1; } b.ID = id; b.Scale = new Vector3(1, 1, 1); // scale b.Position = trans; b.Rotation = rot; CurrentBone = b; Model.Skeleton.Bones.Add(b); //Console.WriteLine(reader.Position().ToString("x") + " " + b.Name + " " + b.p1 + " " + what + " " + parent + " " + boneStack.Count + " " + trans.ToString() + " " + rot.ToString() + " " + scale.ToString()); //Console.WriteLine(b.transform.ToString()); break; case 0x1E: //reader.Skip(3); reader.Skip(1); int w = reader.ReadInt16(); // bone index doff = reader.ReadInt32(); temp = (int)reader.Position; reader.Seek((uint)doff); { GenericMesh mesh = DisplayListToGenericMesh(N64Tools.ReadDisplayList(reader, Model.Skeleton.IndexOf(Model.Skeleton.GetBoneByID(w)), Model.Skeleton.GetWorldTransform(Model.Skeleton.GetBoneByID(w)))); mesh.MaterialName = currentMaterialName; Model.Meshes.Add(mesh); } reader.Seek((uint)temp); break; case 0x22: int materialIndex = reader.ReadByte(); int ww = (short)reader.ReadInt16(); doff = reader.ReadInt32(); temp = (int)reader.Position; if (doff == 0) { continue; } reader.Seek((uint)doff); { GenericMesh mesh = DisplayListToGenericMesh(N64Tools.ReadDisplayList(reader, Model.Skeleton.IndexOf(parentBone), Model.Skeleton.GetWorldTransform(parentBone))); mesh.MaterialName = currentMaterialName; Model.Meshes.Add(mesh); } reader.Seek((uint)temp); //((DisplayList)DisplayLists.Nodes[DisplayLists.Nodes.Count - 1]).Mat = unk; //Console.WriteLine("Material Maybe 0x" + reader.pos().ToString("x") + " " + unk + " " + .Count); break; case 0x23: reader.Skip(1); int tidunk = (short)reader.ReadInt16(); int texOff = reader.ReadInt32(); //& 0x1FFFF Material Offset? int tid = (short)reader.ReadInt16(); int pid = (short)reader.ReadInt16(); reader.Skip(4); // 0xFF padding //Console.WriteLine("TextureCount " + tid + " " + pid + " " + tidunk + " " + texOfreader.ToString("x")); if (tid != -1) { currentMaterial = new GenericMaterial(); currentMaterialName = "material_" + Model.MaterialBank.Count; var diffuse = BakeTexturePalette(Textures[tid], pid, Palettes); diffuse.Name = "texture_" + Model.TextureBank.Count; currentMaterial.TextureDiffuse = diffuse.Name; Model.TextureBank.Add(diffuse.Name, diffuse); Model.MaterialBank.Add(currentMaterialName, currentMaterial); } else { var currentTexture = currentMaterial.TextureDiffuse; currentMaterial = new GenericMaterial(); currentMaterialName = "material_" + Model.MaterialBank.Count; currentMaterial.TextureDiffuse = currentTexture; Model.MaterialBank.Add(currentMaterialName, currentMaterial); } // Read Texture Info At Offset int tt = (int)reader.Position; reader.Seek((uint)texOff); ReadTextureCodes(reader, currentMaterial); reader.Seek((uint)tt); break; // Texture Binding case 0x24: reader.Skip(3); break; // has to do with matrix popping case 0x25: reader.Skip(0x04 - 1); //Console.WriteLine("Unknown 0x" + reader.pos().ToString("x")); break; default: done = true; break; } ; } } // Post Process // optimized texture sharing Dictionary <string, string> newTexName = new Dictionary <string, string>(); Dictionary <string, GenericTexture> newTexBank = new Dictionary <string, GenericTexture>(); Dictionary <byte[], string> TextureBank = new Dictionary <byte[], string>(); foreach (var tex in Model.TextureBank) { if (!TextureBank.ContainsKey(tex.Value.Mipmaps[0])) { string newName = "texture_" + newTexName.Count; newTexName.Add(tex.Key, newName); newTexBank.Add(newName, tex.Value); TextureBank.Add(tex.Value.Mipmaps[0], newName); } else { newTexName.Add(tex.Key, TextureBank[tex.Value.Mipmaps[0]]); } } Model.TextureBank = newTexBank; foreach (var mesh in Model.Meshes) { var material = Model.GetMaterial(mesh); if (material != null && material.TextureDiffuse != null) { material.TextureDiffuse = newTexName[material.TextureDiffuse]; } } Console.WriteLine(TextureBank.Count + " total textures"); // Transform Verts /*int meshindex = 0; * foreach(GenericMesh mesh in Model.Meshes) * { * mesh.Name = "Mesh_" + meshindex; * GenericVertex[] CorrectedVertices = mesh.Vertices.ToArray(); * for(int i =0; i < CorrectedVertices.Length; i++) * { * CorrectedVertices[i].Pos = Vector3.TransformPosition(CorrectedVertices[i].Pos, Model.Skeleton.GetWorldTransform((int)CorrectedVertices[i].Bones.X)); * } * mesh.Vertices.Clear(); * mesh.Vertices.AddRange(CorrectedVertices); * }*/ }
public void Open(FileItem File) { using (DataReader r = new DataReader(new MemoryStream(File.GetFileBinary()))) { if (!new string(r.ReadChars(4)).Equals("XPCK")) { throw new Exception("File header error"); } uint fileCount = (uint)(r.ReadUInt16() & 0xFFF); var fileInfoOffset = r.ReadUInt16() * 4; var fileTableOffset = r.ReadUInt16() * 4; var dataOffset = r.ReadUInt16() * 4; r.ReadUInt16(); var filenameTableSize = r.ReadUInt16() * 4; var hashToData = new Dictionary <uint, byte[]>(); r.Seek((uint)fileInfoOffset); for (int i = 0; i < fileCount; i++) { var nameCRC = r.ReadUInt32(); r.ReadInt16(); var offset = (uint)r.ReadUInt16(); var size = (uint)r.ReadUInt16(); var offsetExt = (uint)r.ReadByte(); var sizeExt = (uint)r.ReadByte(); offset |= offsetExt << 16; size |= sizeExt << 16; offset = (uint)(offset * 4 + dataOffset); var data = r.GetSection(offset, (int)size); //Decompress.CheckLevel5Zlib(data, out data); hashToData.Add(nameCRC, data); } byte[] nameTable = r.GetSection((uint)fileTableOffset, filenameTableSize); if (!Decompress.CheckLevel5Zlib(nameTable, out nameTable)) { nameTable = Decompress.lzss_Decompress(nameTable); } using (DataReader nt = new DataReader(new MemoryStream(nameTable))) { for (int i = 0; i < fileCount; i++) { var name = nt.ReadString(); if (hashToData.ContainsKey(CRC32.Crc32C(name))) { Files.Add(name, hashToData[CRC32.Crc32C(name)]); } else { Console.WriteLine("Couldn't find " + name + " " + CRC32.Crc32C(name).ToString("X")); } } } } }