public static SCNE Load(string path) { SCNE scne = new SCNE(); int count; using (MemoryStream ms = new MemoryStream(File.ReadAllBytes(path))) using (BinaryReader br = new BinaryReader(ms, System.Text.Encoding.UTF8)) { while (br.BaseStream.Position < br.BaseStream.Length) { string section = br.ReadString(4); int unknown; switch (section) { case "ldom": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); int modelCount = (int)br.ReadUInt32(); for (int k = 0; k < modelCount; k++) { Logger.LogToFile(Logger.LogLevel.Debug, "{0} of {1}", k, modelCount); SCNEBone bone = new SCNEBone(); bone.Name = br.ReadString((int)br.ReadUInt32()); string dntpName = br.ReadString((int)br.ReadUInt32()); Logger.LogToFile(Logger.LogLevel.Debug, dntpName); br.ReadString(4); // ptnd string dntpFile = br.ReadString((int)br.ReadUInt32()); Logger.LogToFile(Logger.LogLevel.Debug, dntpFile); bone.Transform = new Matrix4D( br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle() ); new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); bool bLoop = true; do { section = br.ReadString(4); switch (section) { case "hsmp": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); } break; case "hsem": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); int meshCount = (int)br.ReadUInt32(); for (int mi = 0; mi < meshCount; mi++) { Logger.LogToFile(Logger.LogLevel.Debug, "{0} of {1}", mi, meshCount); SCNEMesh mesh = new SCNEMesh(); mesh.Name = br.ReadString((int)br.ReadUInt32()); Logger.LogToFile(Logger.LogLevel.Debug, mesh.Name); if ((section = br.ReadString(4)) != "hctb") { throw new InvalidDataException("Expected hctb"); } unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); int batchCount = (int)br.ReadUInt32(); for (int bi = 0; bi < batchCount; bi++) { Logger.LogToFile(Logger.LogLevel.Debug, "{0} of {1}", bi, batchCount); SCNEMeshPart part = new SCNEMeshPart(); int ia = (int)br.ReadUInt32(); int ib = (int)br.ReadUInt32(); int ic = (int)br.ReadUInt32(); Single sa = br.ReadSingle(); Single sb = br.ReadSingle(); Single sc = br.ReadSingle(); Single sd = br.ReadSingle(); Single se = br.ReadSingle(); Single sf = br.ReadSingle(); Single sg = br.ReadSingle(); Logger.LogToFile(Logger.LogLevel.Info, mesh.Name); Logger.LogToFile(Logger.LogLevel.Info, "{0} : {1} : {2}", ia, ib, ic); Logger.LogToFile(Logger.LogLevel.Info, "{0} : {1} : {2}", sa, sb, sc); Logger.LogToFile(Logger.LogLevel.Info, "{0} : {1} : {2}", sd, se, sf); Logger.LogToFile(Logger.LogLevel.Info, "{0}", sg); if ((section = br.ReadString(4)) != "lrtm") { throw new InvalidDataException("Expected lrtm"); } unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { Logger.LogToFile(Logger.LogLevel.Debug, "{0} of {1}", i, count); part.Materials.Add(br.ReadString((int)br.ReadUInt32())); br.ReadUInt32(); // 0x37 br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); for (int j = 0; j < 10; j++) { br.ReadUInt32(); } // 0 } if ((section = br.ReadString(4)) != "rtxt") { throw new InvalidDataException("Expected rtxt"); } unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { br.ReadUInt32(); part.Textures.Add(new SCNETexture { Format = br.ReadString(4).ToEnum<SCNETexture.TextureType>(), Name = br.ReadString((int)br.ReadUInt32()) }); } if ((section = br.ReadString(4)) != "rtlc") { throw new InvalidDataException("Expected rtlc"); } unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); br.ReadUInt32(); br.ReadUInt32(); br.ReadString(4); br.ReadString((int)br.ReadUInt32()); br.ReadString((int)br.ReadUInt32()); } if ((section = br.ReadString(4)) != "trev") { throw new InvalidDataException("Expected trev"); } unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { SCNEVertex v = new SCNEVertex(); v.Position = unpack(br.ReadUInt64()).ToVector3(); v.Normal = unpackNormal(br.ReadUInt32()).ToVector3(); v.UV = unpack(br.ReadUInt32()); part.Verts.Add(v); br.ReadBytes(16); } if ((section = br.ReadString(4)) != "airt") { throw new InvalidDataException("Expected airt"); } unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { part.IndexBuffer.Add((int)br.ReadUInt16()); part.IndexBuffer.Add((int)br.ReadUInt16()); part.IndexBuffer.Add((int)br.ReadUInt16()); } if ((section = br.ReadString(4)) != "mgde") { throw new InvalidDataException("Expected mgde"); } unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); if (count > 0) { throw new NotImplementedException("Can't handle mgde!"); } for (int i = 0; i < count; i++) { } mesh.Parts.Add(part); } bone.Meshes.Add(mesh); } break; case "ephs": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { br.ReadUInt32(); // 1 br.ReadBytes((int)br.ReadUInt32()); } break; case "xbhs": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { for (int j = 0; j < 22; j++) { br.ReadSingle(); } } break; case "mina": // mina = anim unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { // arfk = key frame if ((section = br.ReadString(4)) != "arfk") { throw new InvalidDataException("Expected arfk"); } unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); int animFrameCount = (int)br.ReadUInt32(); for (int ki = 0; ki < animFrameCount; ki++) { br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); } } break; case "niks": // niks = skin unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { // enob = bone if ((section = br.ReadString(4)) != "enob") { throw new InvalidDataException("Expected enob"); } unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); int boneCount = (int)br.ReadUInt32(); for (int bi = 0; bi < boneCount; bi++) { br.ReadString((int)br.ReadUInt32()); // bone name new Matrix4D( br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle() ); // arfk = key frame if ((section = br.ReadString(4)) != "arfk") { throw new InvalidDataException("Expected arfk"); } unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); int boneFrameCount = (int)br.ReadUInt32(); for (int ki = 0; ki < boneFrameCount; ki++) { br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); } } } break; case "ymmd": // ymmd = dummy, signifies the end of batch when inside a mesh and a null node when not unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { new Matrix4D( br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle() ); br.ReadString((int)br.ReadUInt32()); // null node name } break; default: // bloody unicode if (section[0] == 0xfffd && section[1] == 0xfffd && section[2] == 0xfffd && section[3] == 0xfffd) { br.ReadUInt32(); // 0xe2c9 (example value, not fixed) br.ReadUInt32(); // 0 bLoop = false; break; } else { throw new NotImplementedException(string.Format("Unknown section \"{0}\" at {1:x2}", section, br.BaseStream.Position)); } } } while (bLoop); scne.bones.Add(bone); } break; case "ymmd": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { new Matrix4D( br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle() ); br.ReadString((int)br.ReadUInt32()); } break; case "dptl": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { new Matrix4D( br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle() ); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); } break; case "ecss": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { new Matrix4D( br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle() ); br.ReadUInt32(); // 0 br.ReadUInt32(); // 0 br.ReadString((int)br.ReadUInt32()); br.ReadString(4); br.ReadString((int)br.ReadUInt32()); } break; case "lrpa": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { br.ReadUInt32(); // 0 br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); } break; case "tria": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); if (count > 0) { throw new NotImplementedException("Can't handle tria!"); } for (int i = 0; i < count; i++) { } break; case "csia": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); } br.ReadByte(); br.ReadByte(); br.ReadByte(); br.ReadByte(); // 0xff br.ReadByte(); br.ReadByte(); br.ReadByte(); br.ReadByte(); // 0xff br.ReadUInt32(); // 0 break; case "psrt": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { br.ReadString((int)br.ReadUInt32()); new Matrix4D( br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle() ); } break; case "pcrt": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); } break; case "mlvt": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { new Matrix4D( br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle() ); new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); br.ReadString((int)br.ReadUInt32()); } break; case "lpvt": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); } break; case "fpcs": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { br.ReadString(4); br.ReadString((int)br.ReadUInt32()); } break; case "hpsv": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { br.ReadString((int)br.ReadUInt32()); br.ReadSingle(); new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); } break; case "tcev": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); Vector4 lastValue = new Vector4(0); for (int i = 0; i < count; i++) { lastValue = new Vector4(br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); } if (lastValue.W == 0) { br.ReadSingle(); } break; case "enil": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { br.ReadUInt16(); br.ReadUInt16(); } break; case "rtet": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { br.ReadUInt16(); br.ReadUInt16(); br.ReadUInt16(); br.ReadUInt16(); } break; case "xobv": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { br.ReadString((int)br.ReadUInt32()); new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); } break; default: throw new NotImplementedException(string.Format("Unknown section \"{0}\" at {1:x2}", section, br.BaseStream.Position)); } } } return scne; }
public static SCNE Load(string path) { SCNE scne = new SCNE(); int count; using (MemoryStream ms = new MemoryStream(File.ReadAllBytes(path))) using (BinaryReader br = new BinaryReader(ms, System.Text.Encoding.UTF8)) { while (br.BaseStream.Position < br.BaseStream.Length) { string section = br.ReadString(4); int unknown; switch (section) { case "ldom": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); int modelCount = (int)br.ReadUInt32(); for (int k = 0; k < modelCount; k++) { Logger.LogToFile(Logger.LogLevel.Debug, "{0} of {1}", k, modelCount); SCNEBone bone = new SCNEBone() { Name = br.ReadString((int)br.ReadUInt32()) }; string dntpName = br.ReadString((int)br.ReadUInt32()); Logger.LogToFile(Logger.LogLevel.Debug, dntpName); br.ReadString(4); // ptnd string dntpFile = br.ReadString((int)br.ReadUInt32()); Logger.LogToFile(Logger.LogLevel.Debug, dntpFile); bone.Transform = new Matrix4D( br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle() ); new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); bool bLoop = true; do { section = br.ReadString(4); switch (section) { case "hsmp": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); } break; case "hsem": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); int meshCount = (int)br.ReadUInt32(); for (int mi = 0; mi < meshCount; mi++) { Logger.LogToFile(Logger.LogLevel.Debug, "{0} of {1}", mi, meshCount); SCNEMesh mesh = new SCNEMesh() { Name = br.ReadString((int)br.ReadUInt32()) }; Logger.LogToFile(Logger.LogLevel.Debug, mesh.Name); if ((section = br.ReadString(4)) != "hctb") { throw new InvalidDataException("Expected hctb"); } unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); int batchCount = (int)br.ReadUInt32(); for (int bi = 0; bi < batchCount; bi++) { Logger.LogToFile(Logger.LogLevel.Debug, "{0} of {1}", bi, batchCount); SCNEMeshPart part = new SCNEMeshPart(); int ia = (int)br.ReadUInt32(); int ib = (int)br.ReadUInt32(); int ic = (int)br.ReadUInt32(); float sa = br.ReadSingle(); float sb = br.ReadSingle(); float sc = br.ReadSingle(); float sd = br.ReadSingle(); float se = br.ReadSingle(); float sf = br.ReadSingle(); float sg = br.ReadSingle(); Logger.LogToFile(Logger.LogLevel.Info, mesh.Name); Logger.LogToFile(Logger.LogLevel.Info, "{0} : {1} : {2}", ia, ib, ic); Logger.LogToFile(Logger.LogLevel.Info, "{0} : {1} : {2}", sa, sb, sc); Logger.LogToFile(Logger.LogLevel.Info, "{0} : {1} : {2}", sd, se, sf); Logger.LogToFile(Logger.LogLevel.Info, "{0}", sg); if ((section = br.ReadString(4)) != "lrtm") { throw new InvalidDataException("Expected lrtm"); } unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { Logger.LogToFile(Logger.LogLevel.Debug, "{0} of {1}", i, count); part.Materials.Add(br.ReadString((int)br.ReadUInt32())); br.ReadUInt32(); // 0x37 br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); for (int j = 0; j < 10; j++) { br.ReadUInt32(); } // 0 } if ((section = br.ReadString(4)) != "rtxt") { throw new InvalidDataException("Expected rtxt"); } unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { br.ReadUInt32(); part.Textures.Add(new SCNETexture { Format = br.ReadString(4).ToEnum <SCNETexture.TextureType>(), Name = br.ReadString((int)br.ReadUInt32()) }); } if ((section = br.ReadString(4)) != "rtlc") { throw new InvalidDataException("Expected rtlc"); } unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); br.ReadUInt32(); br.ReadUInt32(); br.ReadString(4); br.ReadString((int)br.ReadUInt32()); br.ReadString((int)br.ReadUInt32()); } if ((section = br.ReadString(4)) != "trev") { throw new InvalidDataException("Expected trev"); } unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { SCNEVertex v = new SCNEVertex() { Position = (Vector3)Unpack(br.ReadUInt64()), Normal = (Vector3)UnpackNormal(br.ReadUInt32()), UV = Unpack(br.ReadUInt32()) }; part.Verts.Add(v); br.ReadBytes(16); } if ((section = br.ReadString(4)) != "airt") { throw new InvalidDataException("Expected airt"); } unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { part.IndexBuffer.Add((int)br.ReadUInt16()); part.IndexBuffer.Add((int)br.ReadUInt16()); part.IndexBuffer.Add((int)br.ReadUInt16()); } if ((section = br.ReadString(4)) != "mgde") { throw new InvalidDataException("Expected mgde"); } unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); if (count > 0) { throw new NotImplementedException("Can't handle mgde!"); } for (int i = 0; i < count; i++) { } mesh.Parts.Add(part); } bone.Meshes.Add(mesh); } break; case "ephs": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { br.ReadUInt32(); // 1 br.ReadBytes((int)br.ReadUInt32()); } break; case "xbhs": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { for (int j = 0; j < 22; j++) { br.ReadSingle(); } } break; case "mina": // mina = anim unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { // arfk = key frame if ((section = br.ReadString(4)) != "arfk") { throw new InvalidDataException("Expected arfk"); } unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); int animFrameCount = (int)br.ReadUInt32(); for (int ki = 0; ki < animFrameCount; ki++) { br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); } } break; case "niks": // niks = skin unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { // enob = bone if ((section = br.ReadString(4)) != "enob") { throw new InvalidDataException("Expected enob"); } unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); int boneCount = (int)br.ReadUInt32(); for (int bi = 0; bi < boneCount; bi++) { br.ReadString((int)br.ReadUInt32()); // bone name new Matrix4D( br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle() ); // arfk = key frame if ((section = br.ReadString(4)) != "arfk") { throw new InvalidDataException("Expected arfk"); } unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); int boneFrameCount = (int)br.ReadUInt32(); for (int ki = 0; ki < boneFrameCount; ki++) { br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); } } } break; case "ymmd": // ymmd = dummy, signifies the end of batch when inside a mesh and a null node when not unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { new Matrix4D( br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle() ); br.ReadString((int)br.ReadUInt32()); // null node name } break; default: // bloody unicode if (section[0] == 0xfffd && section[1] == 0xfffd && section[2] == 0xfffd && section[3] == 0xfffd) { br.ReadUInt32(); // 0xe2c9 (example value, not fixed) br.ReadUInt32(); // 0 bLoop = false; break; } else { throw new NotImplementedException(string.Format("Unknown section \"{0}\" at {1:x2}", section, br.BaseStream.Position)); } } } while (bLoop); scne.Bones.Add(bone); } break; case "ymmd": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { new Matrix4D( br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle() ); br.ReadString((int)br.ReadUInt32()); } break; case "dptl": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { new Matrix4D( br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle() ); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); } break; case "ecss": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { new Matrix4D( br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle() ); br.ReadUInt32(); // 0 br.ReadUInt32(); // 0 br.ReadString((int)br.ReadUInt32()); br.ReadString(4); br.ReadString((int)br.ReadUInt32()); } break; case "lrpa": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { br.ReadUInt32(); // 0 br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); } break; case "tria": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); if (count > 0) { throw new NotImplementedException("Can't handle tria!"); } for (int i = 0; i < count; i++) { } break; case "csia": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); } br.ReadByte(); br.ReadByte(); br.ReadByte(); br.ReadByte(); // 0xff br.ReadByte(); br.ReadByte(); br.ReadByte(); br.ReadByte(); // 0xff br.ReadUInt32(); // 0 break; case "psrt": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { br.ReadString((int)br.ReadUInt32()); new Matrix4D( br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle() ); } break; case "pcrt": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); } break; case "mlvt": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { new Matrix4D( br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle() ); new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); br.ReadString((int)br.ReadUInt32()); } break; case "lpvt": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); br.ReadSingle(); } break; case "fpcs": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { br.ReadString(4); br.ReadString((int)br.ReadUInt32()); } break; case "hpsv": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { br.ReadString((int)br.ReadUInt32()); br.ReadSingle(); new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); } break; case "tcev": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); Vector4 lastValue = new Vector4(0); for (int i = 0; i < count; i++) { lastValue = new Vector4(br.ReadSingle(), br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); } if (lastValue.W == 0) { br.ReadSingle(); } break; case "enil": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { br.ReadUInt16(); br.ReadUInt16(); } break; case "rtet": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { br.ReadUInt16(); br.ReadUInt16(); br.ReadUInt16(); br.ReadUInt16(); } break; case "xobv": unknown = (int)br.ReadUInt32(); Logger.LogToFile(Logger.LogLevel.Debug, "{0} => {1}", section, unknown); count = (int)br.ReadUInt32(); for (int i = 0; i < count; i++) { br.ReadString((int)br.ReadUInt32()); new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); new Vector3(br.ReadSingle(), br.ReadSingle(), br.ReadSingle()); } break; default: throw new NotImplementedException(string.Format("Unknown section \"{0}\" at {1:x2}", section, br.BaseStream.Position)); } } } return(scne); }