private void ReadSkeleton(DataReader reader, int count) { for (int i = 0; i < count; i++) { // three matrices Matrix4 m1 = 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()); 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()); 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()); reader.Position += 0xC; GenericBone b = new GenericBone(); b.ParentIndex = reader.ReadSByte(); b.Transform = m1; Skeleton.Bones.Add(b); reader.Position += 5; } Skeleton.Bones[0].Scale = new Vector3(90, 90, 90); // TODO: Remove }
private void ParseJOBJs(HSD_JOBJ jobj, HSD_JOBJ parent) { //Debug.WriteLine(node.GetType()); { if (FirstJOBJ == null) { FirstJOBJ = jobj; } var bone = new GenericBone(); bone.Name = "JOBJ_" + skeleton.Bones.Count; jobjToIndex.Add(jobj, skeleton.Bones.Count); skeleton.Bones.Add(bone); bone.Position = new Vector3(jobj.Transforms.TX, jobj.Transforms.TY, jobj.Transforms.TZ); bone.Rotation = new Vector3(jobj.Transforms.RX, jobj.Transforms.RY, jobj.Transforms.RZ); bone.Scale = new Vector3(jobj.Transforms.SX, jobj.Transforms.SY, jobj.Transforms.SZ); if (parent != null && jobjToIndex.ContainsKey(parent)) { bone.ParentIndex = jobjToIndex[parent]; } } if (jobj != null) { foreach (var child in jobj.Children) { ParseJOBJs(child, jobj); } } }
/// <summary> /// Export Animation /// </summary> /// <param name="filePath"></param> /// <param name="skeleton"></param> /// <param name="animation"></param> public void Export(string filePath, GenericSkeleton skeleton, GenericAnimation animation) { using (StreamWriter w = new StreamWriter(new FileStream(filePath, FileMode.Create))) { w.WriteLine("version 1"); if (skeleton != null) { w.WriteLine("nodes"); foreach (GenericBone bone in skeleton.Bones) { w.WriteLine($" {skeleton.IndexOf(bone)} \"{bone.Name}\" {bone.ParentIndex}"); } w.WriteLine("end"); w.WriteLine("skeleton"); for (int i = 0; i < animation.FrameCount; i++) { animation.UpdateSkeleton(i, skeleton); w.WriteLine("time " + i); foreach (GenericBone bone in skeleton.Bones) { GenericBone b = new GenericBone(); b.Transform = bone.GetTransform(true); w.WriteLine($" {skeleton.IndexOf(bone)} {b.Position.X} {b.Position.Y} {b.Position.Z} {b.Rotation.X} {b.Rotation.Y} {b.Rotation.Z}"); } } w.WriteLine("end"); } } }
private void ReadSkelData(byte[] data) { model.Skeleton = new GenericSkeleton(); using (DataReader r = new DataReader(data)) { r.BigEndian = false; r.Seek(4); var dataOff = r.ReadUInt16(); r.Seek(0x20); var boneCount = r.ReadInt16(); r.Seek(dataOff); r.Skip(0x30 * (uint)boneCount); // transforms r.Skip(0x30 * (uint)boneCount); // transforms for (int i = 0; i < boneCount; i++) { var bone = new GenericBone(); bone.Scale = new OpenTK.Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); r.ReadSingle(); bone.QuaternionRotation = new OpenTK.Quaternion(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle()).Inverted(); bone.Position = new OpenTK.Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); r.ReadSingle(); model.Skeleton.Bones.Add(bone); } for (int i = 0; i < boneCount; i++) { var hash = r.ReadUInt32(); } for (int i = 0; i < boneCount; i++) { var parent = r.ReadInt16() - 1; if (parent == boneCount - 1) { parent = -1; } model.Skeleton.Bones[i].ParentIndex = parent; } r.Skip((uint)boneCount * 2); r.Skip((uint)boneCount); r.Skip((uint)boneCount * 4); // more hashes? var strStart = r.Position; for (int i = 0; i < boneCount; i++) { model.Skeleton.Bones[i].Name = r.ReadString(r.ReadUInt16() + strStart, -1); } } }
public G1MS(DataReader r) { var myStart = 0; var start = r.Position - 12; var dataoffset = start + r.ReadUInt32(); var skelCount = r.ReadInt32(); // 0? some other offset var boneCount = r.ReadInt16(); var boneTableCount = r.ReadInt16(); r.ReadInt16(); r.ReadInt16(); BoneIndices = new short[boneTableCount]; for (int i = 0; i < boneTableCount; i++) { BoneIndices[i] = r.ReadInt16(); if (BoneIndices[i] != -1) { var temp = r.Position; r.Seek(dataoffset + (uint)(0x30 * BoneIndices[i])); GenericBone b = new GenericBone(); b.Transform = Matrix4.Identity; b.Scale = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); b.ParentIndex = r.ReadInt32(); if ((b.ParentIndex & 0x80000000) > 0 && b.ParentIndex != -1) { b.ParentIndex = b.ParentIndex & 0x7FFFFFFF; } else { b.ParentIndex = myStart + b.ParentIndex; } Quaternion q = new Quaternion(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); b.QuaternionRotation = q.Inverted(); b.Position = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); r.Skip(4); b.Name = "Bone_" + i.ToString(); Skeleton.Bones.Add(b); r.Seek(temp); } } }
/// <summary> /// /// </summary> /// <param name="path"></param> private void ParseSMC(string path) { using (DataReader r = new DataReader(path)) { r.BigEndian = false; r.ReadInt32(); // magic var ver = r.ReadInt32(); // 14 counts for the sections var unk1 = r.ReadInt32(); var unk2 = r.ReadInt32(); var texCount = r.ReadInt32(); var unk3 = r.ReadInt32(); var unk4 = r.ReadInt32(); var skelCount = r.ReadInt32(); r.Seek(0x40); if (skelCount > 0) { r.ReadInt16(); var skelNameLength = r.ReadUInt32(); r.Skip(skelNameLength); var boneCount = r.ReadInt32(); for (int i = 0; i < boneCount; i++) { var boneNameLength = r.ReadInt32(); GenericBone b = new GenericBone(); b.Name = new string(r.ReadChars(boneNameLength - 1)); r.Skip(1); var index = r.ReadInt32(); b.ParentIndex = r.ReadInt32(); b.Transform = new OpenTK.Matrix4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); b.Position = new OpenTK.Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); r.ReadSingle(); Skeleton.Bones.Add(b); } } } }
private static GenericSkeleton ReadSkel(string path) { GenericSkeleton skel = new GenericSkeleton(); using (DataReader r = new DataReader(path)) { r.BigEndian = false; r.Seek(0x10); var count = r.ReadInt16(); var count2 = r.ReadInt16(); var count3 = r.ReadInt32(); var boneInfoOffset = r.Position + r.ReadUInt32(); var boneParentInfoOffset = r.Position + r.ReadUInt32(); var hashOffset = r.Position + r.ReadUInt32(); // various hash table offsets for (uint i = 0; i < count; i++) { GenericBone b = new GenericBone(); r.Seek(boneInfoOffset + 48 * i); var rot = new OpenTK.Quaternion(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle()).Inverted(); rot.Normalize(); b.QuaternionRotation = rot; b.Position = new OpenTK.Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); r.ReadSingle(); b.Scale = new OpenTK.Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); r.ReadSingle(); r.Seek(boneParentInfoOffset + 2 * i); b.ParentIndex = r.ReadInt16(); r.Seek(hashOffset + 4 * i); b.Name = "B_" + r.ReadInt32().ToString("X8"); skel.Bones.Add(b); } } return(skel); }
public void Open(FileItem file) { using (RenderWareBinaryStreamReader r = new RenderWareBinaryStreamReader(file)) { if (r.ReadSection() is RWClump clump) { Model.Skeleton = new GenericSkeleton(); foreach (var skel in clump.FrameList.Frames) { var bone = new GenericBone(); bone.Transform = new Matrix4(skel.Transform); bone.Position = skel.Position; bone.ParentIndex = skel.Parent; Model.Skeleton.Bones.Add(bone); } Console.WriteLine("Clump " + clump.FrameList.Frames.Length); } } }
public static GenericBone ToBone(byte[] data) { if (data.Length == 0) { return(null); } GenericBone bone = new GenericBone(); using (DataReader r = new DataReader(new System.IO.MemoryStream(data))) { bone.ID = r.ReadInt32(); bone.ParentIndex = r.ReadInt32(); r.Skip(4); r.Seek(0xC); bone.Position = new OpenTK.Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); var rot = new OpenTK.Matrix3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); bone.QuaternionRotation = rot.ExtractRotation().Inverted(); bone.Scale = new OpenTK.Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); } return(bone); }
public void Open(FileItem file) { using (DataReader r = new DataReader(file)) { r.BigEndian = true; r.Skip(0xC); // magic var faceOffset = r.ReadUInt32(); var faceLength = r.ReadInt32(); var vertexLength = r.ReadInt32(); var boneTableOffset = r.ReadUInt32(); r.ReadInt32(); // some flag usually 1 var vertOffset = r.ReadUInt32(); var faceOffset2 = r.ReadUInt32(); r.ReadInt32(); // some flag usually 1 var nameCount = r.ReadInt32(); var boneCount = r.ReadInt32(); var polyCount = r.ReadInt32(); var matLength = r.ReadInt32(); var polyNameCount2 = r.ReadInt32(); var polyNameCount3 = r.ReadInt32(); var boneTableCount = r.ReadInt32(); var boneTableCount2 = r.ReadInt32(); var stringCount = r.ReadInt32(); var UnkOffset = r.ReadInt32(); var unk = r.ReadInt32(); var boneOffset = r.ReadUInt32(); var polyInfoOffset = r.ReadUInt32(); var materialOffset = r.ReadUInt32(); var unkOffset2 = r.ReadUInt32(); var materialOffset2 = r.ReadUInt32(); var matrixOffset = r.ReadUInt32(); r.ReadInt32(); // same matrix offset var stringOffset = r.ReadInt32(); r.Seek(boneOffset); for (int i = 0; i < boneCount; i++) { GenericBone bone = new GenericBone(); bone.Name = r.ReadString(r.ReadUInt32(), -1); r.ReadInt32(); // hash var parentName = r.ReadString(r.ReadUInt32(), -1); r.ReadInt32(); // hash r.Skip(0x14); // various unimportant stuff var pos = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); var sca = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); r.Skip(0x14); // various unimportant stuff var inverseMatrix = new Matrix4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); var matrix = new Matrix4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); r.Skip(0xC); // various unimportant stuff bone.Transform = inverseMatrix.Inverted(); bone.Position = pos; bone.ParentIndex = Skeleton.Bones.FindIndex(e => e.Name == parentName); Skeleton.Bones.Add(bone); } r.Seek(materialOffset); for (int i = 0; i < matLength / 6; i++) { GenericMaterial mat = new GenericMaterial(); r.PrintPosition(); var name = r.ReadString(r.ReadUInt32(), -1); if (name == "") { name = "null"; } r.Skip(0x110); mat.TextureDiffuse = r.ReadString(r.ReadUInt32(), -1); r.Skip(0x110); if (Generic.MaterialBank.ContainsKey(name)) { name += "_" + i; } if (!Generic.TextureBank.ContainsKey(mat.TextureDiffuse)) { Generic.TextureBank.Add(mat.TextureDiffuse, new GenericTexture() { Name = mat.TextureDiffuse }); } Generic.MaterialBank.Add(name, mat); } r.Seek(faceOffset); var Indices = new ushort[faceLength / 2]; for (int i = 0; i < Indices.Length; i++) { Indices[i] = r.ReadUInt16(); } r.Seek(vertOffset); var Vertices = new GenericVertex[vertexLength / 44]; for (int i = 0; i < Vertices.Length; i++) { Vertices[i] = new GenericVertex() { Pos = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()), Nrm = new Vector3(r.ReadByte() / 255f, r.ReadByte() / 255f, r.ReadByte() / 255f), Extra = new Vector4(r.ReadByte()), Clr = new Vector4(r.ReadByte() / 255f, r.ReadByte() / 255f, r.ReadByte() / 255f, r.ReadByte() / 255f), UV0 = new Vector2(r.ReadHalfSingle(), r.ReadHalfSingle()), UV1 = new Vector2(r.ReadHalfSingle(), r.ReadHalfSingle()), Bones = new Vector4(r.ReadByte(), r.ReadByte(), r.ReadByte(), r.ReadByte()), Weights = new Vector4(r.ReadByte() / 255f, r.ReadByte() / 255f, r.ReadByte() / 255f, r.ReadByte() / 255f), Extra2 = new Vector4(r.ReadSingle(), r.ReadSingle(), 0, 0) }; } var indexOffset = 0; var vertexOffset = 0; r.Seek(polyInfoOffset); for (int i = 0; i < polyCount; i++) { GenericMesh mesh = new GenericMesh(); mesh.Name = r.ReadString(r.ReadUInt32(), -1); r.ReadInt32();//hash var myboneTableOffset = r.ReadUInt32(); var myPolyOffset = r.ReadInt32(); r.Skip(8); var indexCount = r.ReadInt32(); var vertCount = r.ReadInt32(); var boneIDCount = r.ReadInt32(); var materialID = r.ReadInt32(); r.Skip(8); mesh.MaterialName = Generic.MaterialBank.Keys.ToList()[materialID]; // read bone table var temp = r.Position; var boneTable = new int[boneIDCount]; r.Seek(myboneTableOffset); for (int j = 0; j < boneIDCount; j++) { boneTable[j] = r.ReadInt32(); } // get indices for (int j = 0; j < indexCount; j++) { mesh.Triangles.Add(Indices[indexOffset + j]); } indexOffset += indexCount; // get vertices for (int j = 0; j < vertCount; j++) { var vert = Vertices[vertexOffset + j]; if (boneIDCount == 1) { vert.Weights = new Vector4(1, 0, 0, 0); vert.Bones = new Vector4(0, 0, 0, 0); } if (boneIDCount != 0) { for (int k = 0; k < 4; k++) { if (vert.Weights[k] > 0) { vert.Bones[k] = boneTable[(int)vert.Bones[k]]; } } } if (vert.Weights[0] == 1 && boneIDCount == 1) { vert.Pos = Vector3.TransformPosition(vert.Pos, Skeleton.GetWorldTransform(Skeleton.Bones[(int)vert.Bones[0]])); vert.Nrm = Vector3.TransformNormal(vert.Nrm, Skeleton.GetWorldTransform(Skeleton.Bones[(int)vert.Bones[0]])); } vert.Nrm.Normalize(); mesh.Vertices.Add(vert); } vertexOffset += vertCount; r.Seek(temp); //Console.WriteLine(mesh.Name + " " + (myPolyOffset / 2).ToString("X") + " " + myboneTableOffset.ToString("X")); Generic.Meshes.Add(mesh); } } }
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); } }
private void ParseBone(DataReader reader, uint offset, int parentIndex = -1) { var myIndex = Skeleton.Bones.Count; var myOffset = offset; if (offsetToIndex.ContainsKey(myOffset)) { return; } Console.WriteLine("Bone " + myIndex + " " + offset.ToString("x")); var bone = new GenericBone(); bone.Name = $"Bone_{myIndex}"; reader.Position = offset + 0x130; // 0x120 uint NameOffset = reader.ReadUInt32(); if (NameOffset > 0) { bone.Name = reader.ReadString(NameOffset, -1); } reader.Position = offset + 0; bone.Position = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); reader.Position = offset + 0x20; bone.QuaternionRotation = new Quaternion(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); reader.Position = offset + 0x50; bone.Scale = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); offsetToIndex.Add(myOffset, myIndex); Skeleton.Bones.Add(bone); //bone.ParentIndex = parentIndex; /*reader.Position = offset + 0x80; // 0x70 * bone.Transform = 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()); * try * { * bone.Transform.Invert(); * } * catch (Exception) * { * Console.WriteLine("Invert Exception " + bone.Name); * }*/ reader.Position = offset + 0x110; // 0x100 var siblingLeft = reader.ReadUInt32(); var siblingRight = reader.ReadUInt32(); var parentOffset = reader.ReadUInt32(); var childOffset = reader.ReadUInt32(); var flags = reader.ReadUInt32(); //console.log(flags.toString(16)); if (childOffset != myOffset && childOffset != 0) { ParseBone(reader, childOffset, myIndex); } /*if (siblingRight != myOffset) * { * ParseBone(reader, siblingRight, parentIndex); * }*/ if (siblingLeft != myOffset && siblingLeft != 0) { ParseBone(reader, siblingLeft, parentIndex); } /*if (parentOffset != myOffset && parentOffset != 0) * bone.ParentIndex = offsetToIndex[parentOffset];*/ bone.ParentIndex = parentIndex; }
public void Open(FileItem file) { Model = new GenericModel(); var skelPath = file.FilePath.Replace(".gfx", ".skel"); if (File.Exists(skelPath)) { Model.Skeleton = ReadSkel(skelPath); } using (DataReader r = new DataReader(file)) { r.BigEndian = false; r.Seek(0x10); var mCount = r.ReadInt32(); var infoOffset = r.ReadUInt32(); var dataOffset = r.ReadUInt32(); for (uint i = 0; i < mCount; i++) { r.Seek(0x30 + i * 16); var entry = r.ReadStruct <Entry>(); //Console.WriteLine(i + " " + hash.ToString("X") + " " + index); r.Seek(infoOffset + entry.Offset); if (entry.ID == 2) { var b = new GenericBone(); b.Rotation = new OpenTK.Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); r.ReadSingle(); b.Position = new OpenTK.Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); r.ReadSingle(); b.Scale = new OpenTK.Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); r.ReadSingle(); var unk = r.ReadInt32(); var flag = r.ReadInt16(); var meshCount = r.ReadInt16(); var unk2 = r.ReadInt32(); var hash2 = r.ReadInt32(); uint[] bt = new uint[meshCount]; for (int j = 0; j < meshCount; j++) { bt[j] = r.ReadUInt32(); var temp = r.Position; r.Seek(0x30 + bt[j] * 0x10); var m = ReadMesh(r, infoOffset, dataOffset); if (m != null) { Model.Meshes.Add(m); } r.Seek(temp); } } // material /*if(index == 0x08 && (flags & 0x00FF) == 0x0022) * { * var fl = r.ReadInt32(); * var index1 = r.ReadUInt32(); * var index2 = r.ReadUInt32(); * var index3 = r.ReadUInt32(); * var index4 = r.ReadUInt32(); * var index5 = r.ReadUInt32(); * var index6 = r.ReadUInt32(); * var index7 = r.ReadUInt32(); * * GetBuffer(r, index7, infoOffset, dataOffset); * }*/ } } }
public GenericModel ToGenericModel() { GenericSkeleton skel = new GenericSkeleton(); foreach (var node in Nodes) { GenericBone bone = new GenericBone() { Name = node.Name, Position = node.Position, Rotation = node.Rotation, Scale = node.Scale, ParentIndex = node.ParentIndex }; skel.Bones.Add(bone); } GenericModel m = new GenericModel(); m.Skeleton = skel; // Textures var tindex = 0; foreach (var tex in Textures) { if (m.TextureBank.ContainsKey(tex.Name)) { tex.Name += "_" + tindex++; } m.TextureBank.Add(tex.Name, tex); } int index = -1; foreach (var meshObject in MeshObjects) { index++; Dictionary <int, List <GenericVertex> > MaterialToVertexBank = new Dictionary <int, List <GenericVertex> >(); //Console.WriteLine($"{meshObject.Key} {skel.Bones[meshObject.Value.SingleBind].Name}"); foreach (var d in meshObject.Value.Primitives) { if (!MaterialToVertexBank.ContainsKey(d.Material)) { MaterialToVertexBank.Add(d.Material, new List <GenericVertex>()); } var vertices = MaterialToVertexBank[d.Material]; switch (d.PrimitiveType) { case 0x02: // Triangle vertices.Add(GetVertex(meshObject.Value, d.Vertices[0], skel)); vertices.Add(GetVertex(meshObject.Value, d.Vertices[1], skel)); vertices.Add(GetVertex(meshObject.Value, d.Vertices[2], skel)); break; case 0x03: // Quad vertices.Add(GetVertex(meshObject.Value, d.Vertices[0], skel)); vertices.Add(GetVertex(meshObject.Value, d.Vertices[1], skel)); vertices.Add(GetVertex(meshObject.Value, d.Vertices[2], skel)); vertices.Add(GetVertex(meshObject.Value, d.Vertices[1], skel)); vertices.Add(GetVertex(meshObject.Value, d.Vertices[3], skel)); vertices.Add(GetVertex(meshObject.Value, d.Vertices[2], skel)); break; case 0x04: // Triangle Strip var verts = new List <GenericVertex>(); foreach (var dv in d.Vertices) { verts.Add(GetVertex(meshObject.Value, dv, skel)); } Tools.TriangleConverter.StripToList(verts, out verts); vertices.AddRange(verts); break; default: throw new Exception("Unsupported Primitive Type " + d.PrimitiveType.ToString("X")); } } foreach (var v in MaterialToVertexBank) { GenericMesh mesh = new GenericMesh(); mesh.Name = meshObject.Key; if (MaterialToVertexBank.Count > 1) { mesh.Name += "_" + m.Meshes.Count;// Textures[Materials[Materials1[v.Key].MaterialIndex].TextureIndex].Name; } GenericMaterial mat = new GenericMaterial(); mesh.MaterialName = "material_" + m.MaterialBank.Count; m.MaterialBank.Add(mesh.MaterialName, mat); var mat1Index = Materials1[v.Key].MaterialIndex; mat1Index = Math.Min(mat1Index, Materials.Count - 1); var textureIndex = Materials[mat1Index].TextureIndex; mat.TextureDiffuse = Textures[textureIndex].Name; m.Meshes.Add(mesh); mesh.Vertices.AddRange(v.Value); //Console.WriteLine(mesh.Name + " " + v.Key + " " + Materials[v.Key].TextureIndex + " " + Textures.Count + " " + Materials.Count); mesh.Optimize(); } } return(m); }
public void Open(FileItem File) { using (DataReader r = new DataReader(File)) { r.BigEndian = false; r.Seek(0x34); var skelTableOffset = r.Position + r.ReadUInt32(); Model = new GenericModel(); Model.Skeleton = new GenericSkeleton(); r.Seek(skelTableOffset + 8); var boneCount = r.ReadInt32(); for (int i = 0; i < boneCount; i++) { var temp = r.Position + 4; r.Seek(r.Position + r.ReadUInt32()); //r.PrintPosition(); var unk1 = r.ReadInt32(); var unk2 = r.ReadInt32(); GenericBone bone = new GenericBone(); bone.Transform = new OpenTK.Matrix4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); var boneInfoOffset = r.Position + r.ReadUInt32(); var boneFlag = r.ReadInt32(); var parentCount = r.ReadInt32(); var childCount = r.ReadUInt32(); r.Skip(4 * childCount); // parent count intofmration r.Seek(boneInfoOffset); var parentName = r.ReadString(r.ReadInt32()); r.Skip(1); r.Align(4); bone.Name = r.ReadString(r.ReadInt32()); r.Skip(1); r.Align(4); if (parentName != "") { bone.ParentIndex = Model.Skeleton.IndexOf(Model.Skeleton.Bones.Find(e => e.Name == parentName)); } Model.Skeleton.Bones.Add(bone); r.Seek(temp); } r.Seek(0x48); var objectCount = r.ReadInt32(); var unkOffset = r.Position + r.ReadUInt32(); var vcount = 0; for (int i = 0; i < objectCount - 1; i++) { GenericMesh mesh = new GenericMesh(); Model.Meshes.Add(mesh); var temp = r.Position + 4; r.Seek(r.Position + r.ReadUInt32()); r.Skip(8); mesh.Name = r.ReadString(r.Position + r.ReadUInt32() + 4, -1); var nameOff2 = r.Position + r.ReadUInt32(); var parentBoneOff = r.Position + r.ReadUInt32(); mesh.MaterialName = r.ReadString(r.Position + r.ReadUInt32() + 12, -1); var transform = new OpenTK.Matrix4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); var boneTableOffset = r.Position + r.ReadUInt32(); // bonetable offset r.ReadInt32(); // some matrix table? r.Skip(0x18); // floats var somecount = r.ReadInt32(); var indexTableOffset = r.Position + r.ReadUInt32(); var attributeBuffer = r.Position + r.ReadUInt32(); var vertCount = r.ReadInt32(); var primType = r.ReadInt32(); var unkownOffset2 = r.ReadUInt32(); if (unkownOffset2 > 0xFFFF) { r.ReadInt32(); } else { r.ReadInt16(); } var t = r.Position; r.Seek(attributeBuffer); var attributes = r.ReadStructArray <AttributeBuffer>(r.ReadInt32()); foreach (var a in attributes) { Console.WriteLine(a.Format + " " + a.Type + " " + a.Size); } r.Seek(t); for (int v = 0; v < vertCount; v++) { var vert = new GenericVertex(); foreach (var a in attributes) { float[] values = new float[a.Size]; for (int vi = 0; vi < values.Length; vi++) { switch (a.Format) { case 0x00: values[vi] = r.ReadSingle(); break; case 0x07: values[vi] = r.ReadInt16() / (float)short.MaxValue; break; case 0x06: values[vi] = r.ReadSByte(); break; case 0x0B: values[vi] = r.ReadUInt16() / (float)ushort.MaxValue; break; case 0x0E: values[vi] = r.ReadByte() / (float)255; break; default: throw new NotSupportedException("Unknown Attribute Format " + a.Format); } } switch (a.Type) { case 0: vert.Pos = new OpenTK.Vector3(values[0], values[1], values[2]); break; case 1: vert.Clr = new OpenTK.Vector4(values[0], values[1], values[2], values[3]); break; case 3: vert.UV0 = new OpenTK.Vector2(values[0], values[1]); break; case 15: vert.Bones = new OpenTK.Vector4(values[0], values[1], values[2], values[3]); break; case 16: vert.Weights = new OpenTK.Vector4(values[0], values[1], values[2], values[3]); break; //default: // throw new NotSupportedException("Unknown vertex attribute " + a.Type); } } mesh.Vertices.Add(vert); } r.Seek(indexTableOffset); var indexBufferSize = r.ReadInt32(); var indexCount = (indexBufferSize - 6) / 2; if (indexBufferSize > 0xFFFF) { r.ReadInt32(); } else { r.ReadInt16(); } for (int j = 0; j < indexCount; j++) { var v = r.ReadUInt16(); mesh.Triangles.Add(mesh.VertexCount < 0xFF ? (uint)(v & 0xFF) : v); } //r.PrintPosition(); Console.WriteLine(mesh.Name + " " + mesh.VertexCount.ToString("X") + " " + mesh.Triangles.Min().ToString("X") + " " + mesh.Triangles.Max().ToString("X")); //mesh.PrimitiveType = OpenTK.Graphics.OpenGL.PrimitiveType.TriangleStrip; r.Seek(temp); } } }
private void ParseMDLD(byte[] data) { using (DataReader r = new DataReader(data)) { r.BigEndian = false; r.ReadInt32(); // magic var offset1 = r.ReadUInt32(); var polyInfoOffset = r.ReadUInt32(); var polyInfoCount = r.ReadInt32(); var boneOffset = r.ReadUInt32(); var boneCount = r.ReadInt32(); var bufferOffset = r.ReadUInt32(); var bufferLength = r.ReadInt32(); var vertexCount = r.ReadInt32(); var att = r.ReadString(0x68, -1).Split('_'); r.Seek(boneOffset); model.Skeleton = new GenericSkeleton(); for (int i = 0; i < boneCount; i++) { var bone = new GenericBone(); bone.Name = r.ReadString(r.Position, -1); r.Skip(0x20); bone.Transform = Matrix4.Identity; bone.QuaternionRotation = new Quaternion(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); bone.Position = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); bone.Scale = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); bone.ParentIndex = r.ReadInt32(); model.Skeleton.Bones.Add(bone); } model.Skeleton.TransformWorldToRelative(); List <GenericVertex> vertices = new List <GenericVertex>(); for (uint i = 0; i < vertexCount; i++) { r.Seek(bufferOffset + 60 * i); var vert = new GenericVertex(); var stop = false; foreach (var va in att) { switch (va) { case "vp3": vert.Pos = new OpenTK.Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); break; case "vc": vert.Clr = new OpenTK.Vector4(r.ReadByte() / 255f, r.ReadByte() / 255f, r.ReadByte() / 255f, r.ReadByte() / 255f); break; case "vn": vert.Nrm = new OpenTK.Vector3(r.ReadHalfSingle(), r.ReadHalfSingle(), r.ReadHalfSingle()); r.ReadHalfSingle(); break; case "vt": vert.UV0 = new OpenTK.Vector2(r.ReadHalfSingle(), r.ReadHalfSingle()); break; case "von": r.Skip(8); break; case "vb4": vert.Bones = new OpenTK.Vector4(r.ReadInt16(), r.ReadInt16(), r.ReadInt16(), r.ReadInt16()); vert.Weights = new OpenTK.Vector4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); break; case "vs": break; default: stop = true; break; } if (stop) { break; } } vertices.Add(vert); } r.Seek(polyInfoOffset); for (int i = 0; i < polyInfoCount; i++) { GenericMesh mesh = new GenericMesh(); model.Meshes.Add(mesh); mesh.Name = r.ReadString(r.Position, -1); r.Skip(0x40); var polyBufferOffset = r.ReadUInt32(); var polyBufferLength = r.ReadUInt32(); var polyBufferCount = r.ReadUInt32(); var primType = r.ReadInt32(); r.Skip(0x60); var temp = r.Position; r.Seek(polyBufferOffset); for (int j = 0; j < polyBufferCount; j++) { if (primType == 4) { mesh.Vertices.Add(vertices[r.ReadInt32()]); } } mesh.Optimize(); r.Seek(temp); } } }
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(); } } }
private void ReadFrameData(DataReader d, int offset, int count, uint dataOffset, int boneCount, AnimTrack Track) { for (int i = offset; i < offset + count; i++) { d.Seek((uint)(dataOffset + 4 * 4 * i)); var flagOffset = d.ReadUInt32(); var keyFrameOffset = d.ReadUInt32(); var keyDataOffset = d.ReadUInt32(); d.Seek(flagOffset); var boneIndex = d.ReadInt16(); var keyFrameCount = d.ReadByte(); var flag = d.ReadByte(); var node = anim.TransformNodes[boneIndex + (flag == 0 ? boneCount : 0)]; d.Seek(keyDataOffset); for (int k = 0; k < keyFrameCount; k++) { var temp = d.Position; d.Seek((uint)(keyFrameOffset + k * 2)); var frame = d.ReadInt16(); d.Seek(temp); float[] animdata = new float[Track.DataCount]; for (int j = 0; j < Track.DataCount; j++) { switch (Track.DataType) { case 1: animdata[j] = d.ReadInt16() / (float)short.MaxValue; break; case 2: animdata[j] = d.ReadSingle(); break; case 4: animdata[j] = d.ReadInt16(); break; default: throw new NotImplementedException("Data Type " + Track.DataType + " not implemented"); } } switch (Track.Type) { case 1: node.AddKey(frame, animdata[0], AnimationTrackFormat.TranslateX); node.AddKey(frame, animdata[1], AnimationTrackFormat.TranslateY); node.AddKey(frame, animdata[2], AnimationTrackFormat.TranslateZ); break; case 2: var e = GenericBone.ToEulerAngles(new OpenTK.Quaternion(animdata[0], animdata[1], animdata[2], animdata[3]).Inverted()); node.AddKey(frame, e.X, AnimationTrackFormat.RotateX); node.AddKey(frame, e.Y, AnimationTrackFormat.RotateY); node.AddKey(frame, e.Z, AnimationTrackFormat.RotateZ); break; case 3: node.AddKey(frame, animdata[0], AnimationTrackFormat.ScaleX); node.AddKey(frame, animdata[1], AnimationTrackFormat.ScaleY); node.AddKey(frame, animdata[2], AnimationTrackFormat.ScaleZ); break; } } } }
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) { var skelPath = File.FilePath.Replace(".mdg", ".anm"); var skelAngPath = File.FilePath.Replace(".mdg", ".ang"); var modelPath = File.FilePath.Replace(".mdg", ".mdl"); var texPath = File.FilePath.Replace(".mdg", ".tex"); if (!System.IO.File.Exists(skelPath)) { System.Windows.Forms.MessageBox.Show("Missing Skeleton File " + Path.GetFileName(skelPath)); return; } if (!System.IO.File.Exists(skelAngPath)) { System.Windows.Forms.MessageBox.Show("Missing Skeleton File " + Path.GetFileName(skelAngPath)); return; } if (!System.IO.File.Exists(modelPath)) { System.Windows.Forms.MessageBox.Show("Missing Model File " + Path.GetFileName(modelPath)); return; } Model = new GenericModel(); Model.Skeleton = new GenericSkeleton(); if (System.IO.File.Exists(texPath)) { using (DataReader r = new DataReader(new FileStream(texPath, FileMode.Open))) { r.BigEndian = true; var unk = r.ReadInt32(); var width = r.ReadInt32(); var height = r.ReadInt32(); var dataLength = r.ReadInt32(); var padding = r.ReadInt32(); var format = r.ReadByte(); var data = r.GetSection(0x20, (int)(r.BaseStream.Length - 0x20)); var bmp = HSDLib.Helpers.TPL.ConvertFromTextureMelee(data, width, height, (int)TPL_TextureFormat.CMP, null, 0, 0); GenericTexture t = new GenericTexture(); t.FromBitmap(bmp); bmp.Dispose(); Model.TextureBank.Add("texture", t); Model.MaterialBank.Add("material", new GenericMaterial() { TextureDiffuse = "texture" }); } } using (DataReader r = new DataReader(new FileStream(skelPath, FileMode.Open))) { r.BigEndian = false; r.ReadInt32(); // magic r.ReadInt32(); // header var boneCount = r.ReadInt32(); var boneOffset = r.ReadUInt32(); using (DataReader angr = new DataReader(new FileStream(skelAngPath, FileMode.Open))) { angr.BigEndian = false; for (int i = 0; i < boneCount; i++) { r.Seek(boneOffset + (uint)(i * 0x20)); var bone = new GenericBone(); bone.Position = new OpenTK.Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle()); r.ReadSingle(); //r.Skip(0x10); // inverted world position bone.Name = r.ReadString(r.ReadUInt32(), -1); bone.ParentIndex = r.ReadInt32(); var flags = r.ReadInt32(); var angOffset = r.ReadUInt32(); /*angr.Seek(angOffset); * angr.Skip(4); * var posOff = angr.ReadUInt32(); * var rotOff = angr.ReadUInt32(); * var scaOff = angr.ReadUInt32(); * angr.Seek(posOff); * bone.Position = new OpenTK.Vector3(angr.ReadSingle(), angr.ReadSingle(), angr.ReadSingle()); * angr.Seek(rotOff); * bone.Rotation = new OpenTK.Vector3(angr.ReadSingle(), angr.ReadSingle(), angr.ReadSingle()); * angr.Seek(scaOff); * bone.Scale = new OpenTK.Vector3(angr.ReadSingle(), angr.ReadSingle(), angr.ReadSingle());*/ Model.Skeleton.Bones.Add(bone); } } } Model.Skeleton.TransformWorldToRelative(); using (DataReader r = new DataReader(new FileStream(modelPath, FileMode.Open))) { r.BigEndian = true; r.ReadInt32(); // magic int boneCount = r.ReadInt16(); var meshCount = r.ReadInt16(); boneCount = r.ReadInt32(); var meshOffset = r.ReadUInt32(); r.ReadUInt32(); var boneOffset = r.ReadUInt32(); for (int i = 0; i < meshCount; i++) { r.Seek(meshOffset + (uint)(i * 80)); r.Skip(0x30); // bounding stuff var mesh = new GenericMesh(); mesh.MaterialName = "material"; mesh.Name = r.ReadString(r.ReadUInt32(), -1); r.Skip(4 * 4); var datInfoOffset = r.ReadUInt32(); Model.Meshes.Add(mesh); r.Seek(datInfoOffset); var flag = r.ReadInt32(); var bufferOffset = r.ReadUInt32(); var someCount = r.ReadInt32(); var primCount = r.ReadInt32(); using (DataReader buffer = new DataReader(new FileStream(File.FilePath, FileMode.Open))) { buffer.BigEndian = true; if (new string(buffer.ReadChars(4)) == "MDG5") { buffer.Seek(0x10); } else { buffer.Seek(0); } buffer.Skip(bufferOffset); for (int p = 0; p < primCount; p++) { var primitiveType = buffer.ReadInt16(); var pcount = buffer.ReadInt16(); if (primitiveType != 0x98) { throw new NotSupportedException("Unknown prim type " + primitiveType.ToString("X")); } var strip = new List <GenericVertex>(); for (int v = 0; v < pcount; v++) { var vert = new GenericVertex(); vert.Pos = new OpenTK.Vector3(buffer.ReadSingle(), buffer.ReadSingle(), buffer.ReadSingle()); vert.Nrm = new OpenTK.Vector3(buffer.ReadSByte(), buffer.ReadSByte(), buffer.ReadSByte()); vert.Nrm.Normalize(); // Color? int col = buffer.ReadInt16(); var R = (col >> 12) & 0xF; var G = (col >> 8) & 0xF; var B = (col >> 4) & 0xF; var A = (col) & 0xF; vert.Clr = new OpenTK.Vector4( (R | R << 4) / (float)0xFF, (G | G << 4) / (float)0xFF, (B | B << 4) / (float)0xFF, (A | A << 4) / (float)0xFF); vert.UV0 = new OpenTK.Vector2(buffer.ReadInt16() / (float)0xFFF, buffer.ReadInt16() / (float)0xFFF); var weight1 = buffer.ReadByte() / (float)0xFF; float weight2 = 0; if (weight1 != 1) { weight2 = 1 - weight1; } var bone1 = buffer.ReadByte(); var bone2 = buffer.ReadByte(); vert.Bones = new OpenTK.Vector4(bone1, bone2, 0, 0); vert.Weights = new OpenTK.Vector4(weight1, weight2, 0, 0); strip.Add(vert); } TriangleConverter.StripToList(strip, out strip); mesh.Vertices.AddRange(strip); } } mesh.Optimize(); } } }
private void ReadRES(DataReader r) { if (new string(r.ReadChars(4)) != "$RSF") { Console.WriteLine("error"); } int resourceCount1 = r.ReadInt32(); r.ReadInt32(); r.ReadInt32(); int resourceCount2 = r.ReadInt32(); r.ReadInt32(); r.ReadInt32(); r.ReadInt32(); string name = r.ReadString(r.Position, -1); r.Position += (uint)name.Length; r.Align(0x10); Console.WriteLine(name); VTX prevVTX = null; TXR prevTXR = null; while (true) { var start = r.Position; if (r.Position >= r.Length) { break; } r.BigEndian = true; string key = r.ReadString(4); var size = r.ReadUInt32(); var flag1 = r.ReadInt32(); var flag2 = r.ReadInt32(); var sectionStart = r.Position; r.BigEndian = false; Console.WriteLine(start.ToString("X") + " " + key + " " + size.ToString("X")); switch (key) { case "$CT0": r.Position += 12; break; case "$VTX": prevVTX = new VTX(r); VTXs.Add(prevVTX); break; case "$TXR": prevTXR = new TXR(r); TXRs.Add(prevTXR); break; case "$TXI": break; case "$RSI": if (prevVTX != null) { prevVTX.ReadResource(r); } if (prevTXR != null) { prevTXR.ReadResource(r); } prevVTX = null; prevTXR = null; break; case "$SKL": { var f = r.ReadInt32(); r.ReadInt16(); // dunno var boneCount = r.ReadInt16(); r.ReadInt16(); // dunno r.ReadInt16(); // dunno Stack <int> boneStack = new Stack <int>(); for (int i = 0; i < boneCount; i++) { GenericBone bone = new GenericBone(); bone.Name = r.ReadString(sectionStart + r.ReadUInt32(), -1); bone.ParentIndex = boneStack.Count > 0 ? boneStack.Peek() : -1; r.ReadByte(); var depth = r.ReadByte(); var pop = r.ReadSByte() + 1; r.ReadByte(); boneStack.Push(i); for (int j = 0; j < pop; j++) { boneStack.Pop(); } bone.Transform = new OpenTK.Matrix4(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), 0, r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), 0, r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), 0, r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), 1); r.Skip(0x48); Skeleton.Bones.Add(bone); } } break; case "$SCN": break; case "$MSH": break; case "$TRE": break; case "$CLT": break; } r.Seek(start + size + 0x10); if (r.Position % 16 != 0) { r.Position += 16 - (r.Position % 16); } } }
/// <summary> /// /// </summary> /// <returns></returns> public GenericModel ToGenericModel() { var model = new GenericModel(); model.Skeleton = Skeleton; var tindex = 0; foreach (var t in Textures) { model.TextureBank.Add("T" + tindex.ToString("X3"), t); tindex++; } foreach (var g1m in Models) { var mod = g1m.G1MG; var nuno = g1m.NUNO; var nunv = g1m.NUNV; model.Skeleton = g1m.Skeleton.Skeleton; var idTonunoBoneToBone33 = new List <Dictionary <int, int> >(); List <int> nunoParents = new List <int>(); //var idTonunoBoneToBone32 = new List<int>(); var entries = new List <NUNO.NUNOv33Entry>(); var nunoIndexOffset = 0; if (nunv != null) { nunoIndexOffset = nunv.V33Entries.Count; } if (nunv != null) { entries.AddRange(nunv.V33Entries); } if (nuno != null) { entries.AddRange(nuno.V33Entries); } foreach (var entry in entries) { var boneStart = model.Skeleton.Bones.Count; var parentBone = mod.BindMatches[entry.ParentBoneID - 1][0]; nunoParents.Add(parentBone); Dictionary <int, int> nunoBoneToBone = new Dictionary <int, int>(); idTonunoBoneToBone33.Add(nunoBoneToBone); GenericMesh driverMesh = new GenericMesh(); driverMesh.Name = "driver_" + (idTonunoBoneToBone33.Count - 1) + "_" + model.Skeleton.Bones[parentBone].Name; model.Meshes.Add(driverMesh); driverMesh.Visible = false; for (int pointIndex = 0; pointIndex < entry.Points.Count; pointIndex++) { // fake bone generation var p = entry.Points[pointIndex]; var link = entry.Influences[pointIndex]; GenericBone b = new GenericBone(); b.Name = $"CP_{idTonunoBoneToBone33.Count}_{model.Skeleton.Bones[parentBone].Name}_{pointIndex}"; b.Transform = Matrix4.Identity; nunoBoneToBone.Add(pointIndex, model.Skeleton.Bones.Count); model.Skeleton.Bones.Add(b); b.Position = p.Xyz; b.ParentIndex = link.P3; if (b.ParentIndex == -1) { b.ParentIndex = parentBone; } else { b.ParentIndex += boneStart; b.Position = Vector3.TransformPosition(p.Xyz, model.Skeleton.GetWorldTransform(parentBone) * model.Skeleton.GetWorldTransform(b.ParentIndex).Inverted()); } // fake driver mesh generation driverMesh.Vertices.Add(new GenericVertex() { Pos = Vector3.TransformPosition(Vector3.Zero, model.Skeleton.GetWorldTransform(model.Skeleton.Bones.Count - 1)), Weights = new Vector4(1, 0, 0, 0), Bones = new Vector4(model.Skeleton.Bones.Count - 1, 0, 0, 0) }); if (link.P1 > 0 && link.P3 > 0) { driverMesh.Triangles.Add((uint)pointIndex); driverMesh.Triangles.Add((uint)link.P1); driverMesh.Triangles.Add((uint)link.P3); } if (link.P2 > 0 && link.P4 > 0) { driverMesh.Triangles.Add((uint)pointIndex); driverMesh.Triangles.Add((uint)link.P2); driverMesh.Triangles.Add((uint)link.P4); } } } foreach (var group in mod.Lods[0].Groups) { var isCloth = (group.ID & 0xF) == 1; var isPoint = (group.ID & 0xF) == 2; var NunSection = (group.ID2 - (group.ID2 % 10000)) / 10000; Console.WriteLine(group.Name + " " + group.ID + " " + group.ID2 + " " + NunSection); foreach (var polyindex in group.Indices) { if (polyindex > mod.Polygons.Count) { continue; } var poly = mod.Polygons[polyindex]; GenericMesh mesh = new GenericMesh(); mesh.Name = System.Text.RegularExpressions.Regex.Replace(group.Name, @"\p{C}+", string.Empty) + model.Meshes.Count;// + "_" + polyindex; model.MaterialBank.Add("MP_" + polyindex, new GenericMaterial() { MaterialInfo = mod.Materials[poly.MaterialIndex].ToString(), TextureDiffuse = "T" + mod.TextureBanks[poly.TextureBankIndex].DiffuseTextureIndex.ToString("X3"), EnableBlend = false, }); mesh.MaterialName = "MP_" + polyindex; mesh.Vertices = mod.GetVertices(poly, out mesh.Triangles, !isCloth); if (isPoint) { for (int i = 0; i < mesh.VertexCount; i++) { var vert = mesh.Vertices[i]; vert.Nrm = Vector3.TransformNormal(vert.Nrm, model.Skeleton.GetWorldTransform(mod.BindMatches[poly.BoneTableIndex][0])); vert.Pos = Vector3.TransformPosition(vert.Pos, model.Skeleton.GetWorldTransform(mod.BindMatches[poly.BoneTableIndex][0])); mesh.Vertices[i] = vert; } } if (isCloth) { Dictionary <int, int> nunoBoneToBone = idTonunoBoneToBone33[group.ID2 & 0xF]; if (NunSection == 2 && nunv != null && nuno != null) { nunoBoneToBone = idTonunoBoneToBone33[(group.ID2 & 0xF) + nunoIndexOffset]; } //mesh.Name += "_driver_" + (group.ID2 & 0xF); for (int i = 0; i < mesh.VertexCount; i++) { var vert = mesh.Vertices[i]; if (vert.Bit == Vector4.Zero) { //Console.WriteLine(vert.Weights.ToString() + " " + vert.Bones.ToString()); vert.Pos = Vector3.TransformPosition(vert.Pos, model.Skeleton.GetWorldTransform(mod.BindMatches[poly.BoneTableIndex][0])); vert.Nrm = Vector3.TransformNormal(vert.Nrm, model.Skeleton.GetWorldTransform(mod.BindMatches[poly.BoneTableIndex][0])); //vert.Weights = new Vector4(1, 0, 0, 0); vert.Bones = new Vector4(mod.BindMatches[poly.BoneTableIndex][(int)vert.Bones.X / 3], mod.BindMatches[poly.BoneTableIndex][(int)vert.Bones.Y / 3], mod.BindMatches[poly.BoneTableIndex][(int)vert.Bones.Z / 3], mod.BindMatches[poly.BoneTableIndex][(int)vert.Bones.W / 3]); mesh.Vertices[i] = vert; continue; } Vector3 finpos = Vector3.Zero; //Console.WriteLine(vert.Nrm + " " + vert.Nrm.Normalized()); var tempb = new GenericBone(); tempb.Transform = Matrix4.Identity; tempb.Rotation = vert.Clr1.Xyz; var weights1 = new Vector4(vert.Pos, vert.Extra3.X); { var pos = Vector3.Zero; var d4 = Vector3.Zero; d4 += Weight(pos, model.Skeleton, weights1, vert.Bones, nunoBoneToBone) * vert.Weights.X; d4 += Weight(pos, model.Skeleton, weights1, vert.Extra, nunoBoneToBone) * vert.Weights.Y; d4 += Weight(pos, model.Skeleton, weights1, vert.Fog, nunoBoneToBone) * vert.Weights.Z; d4 += Weight(pos, model.Skeleton, weights1, vert.Extra2, nunoBoneToBone) * vert.Weights.W; var d5 = Vector3.Zero; d5 += Weight(pos, model.Skeleton, weights1, vert.Bones, nunoBoneToBone) * vert.Clr1.X; d5 += Weight(pos, model.Skeleton, weights1, vert.Extra, nunoBoneToBone) * vert.Clr1.Y; d5 += Weight(pos, model.Skeleton, weights1, vert.Fog, nunoBoneToBone) * vert.Clr1.Z; d5 += Weight(pos, model.Skeleton, weights1, vert.Extra2, nunoBoneToBone) * vert.Clr1.W; var d6 = Vector3.Zero; d6 += Weight(pos, model.Skeleton, vert.Bit, vert.Bones, nunoBoneToBone) * vert.Weights.X; d6 += Weight(pos, model.Skeleton, vert.Bit, vert.Extra, nunoBoneToBone) * vert.Weights.Y; d6 += Weight(pos, model.Skeleton, vert.Bit, vert.Fog, nunoBoneToBone) * vert.Weights.Z; d6 += Weight(pos, model.Skeleton, vert.Bit, vert.Extra2, nunoBoneToBone) * vert.Weights.W; vert.Pos = Vector3.Cross(d5, d6) * (vert.Extra3.Y) + d4; } vert.Weights = Vector4.Zero; // new Vector4(1, 0, 0, 0); vert.Bones = Vector4.Zero; // new Vector4(mod.BindMatches[poly.BoneTableIndex][0], 0, 0, 0); //RigMe(vert.Pos, model.Skeleton, nunoBoneToBone, out vert.Bones, out vert.Weights); mesh.Vertices[i] = vert; } } mesh.PrimitiveType = OpenTK.Graphics.OpenGL.PrimitiveType.TriangleStrip; model.Meshes.Add(mesh); } } } return(model); }
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 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); * }*/ }