internal static AniModel LoadCharacter(string path, string name) { using (var zip = ZipFile.OpenRead(path)) { using (var ms = new MemoryStream()) { using (var temp = zip.GetEntry("main.oes")?.Open()) temp?.CopyTo(ms); ms.Position = 0; var root = OESFile.Read <OESRoot>(ms); var model = root.Find <OESCharacter>().First(x => x.Name == name); WriteLine($"Loading {model.Name}"); var materials = FromSkin(model.Find <OESSkin>().First(), zip); var anisets = model.Find <OESAnimationSet>().Select(x => (x.Name, x.Find <OESAnimationBuffer>().ToList())).ToDictionary(); var animodel = new AniModel(); model.Find <OESAnimatedMesh>().ForEach((oam, i) => { var animations = anisets.Select(kv => (kv.Key, kv.Value[i])).ToDictionary(); animations[""] = oam.Find <OESAnimationBuffer>().First(); animodel.Add(new AnimatedMesh(materials[i], animations.Select(kv => (kv.Key, kv.Value.VertexBuffers)).ToDictionary(), oam.IndexBuffer.ToArray())); }); return(animodel); } } }
internal static OESChunk Deserialize(OESFile file, BinaryReader br) { var tc = Encoding.ASCII.GetString(br.ReadBytes(4)).TrimEnd(' '); var id = br.ReadUInt32(); var dlen = br.ReadUInt32(); var cdlen = br.ReadUInt32(); var numChildren = br.ReadUInt32(); var epos = br.BaseStream.Position + dlen; OESChunk instance; switch (tc) { case "root": instance = new OESRoot(tc, id); break; case "mat": instance = new OESMaterial(tc, id); break; case "fx": instance = new OESEffect(tc, id); break; case "tex": instance = new OESTexture(tc, id); break; case "zone": instance = new OESZone(tc, id); break; case "regn": instance = new OESRegion(tc, id); break; case "char": instance = new OESCharacter(tc, id); break; case "obj": instance = new OESObject(tc, id); break; case "inst": instance = new OESInstance(tc, id); break; case "lit": instance = new OESLight(tc, id); break; case "skin": instance = new OESSkin(tc, id); break; case "mesh": instance = new OESStaticMesh(tc, id); break; case "aset": instance = new OESAnimationSet(tc, id); break; case "amsh": instance = new OESAnimatedMesh(tc, id); break; case "abuf": instance = new OESAnimationBuffer(tc, id); break; default: instance = new OESChunk(tc, id); break; } file.Add(instance); instance.OESFile = file; instance.DeserializeData(br); Debug.Assert(br.BaseStream.Position <= epos); br.BaseStream.Position = epos; for (var i = 0; i < numChildren; ++i) { instance.Add(Deserialize(file, br)); } Debug.Assert(br.BaseStream.Position == epos + cdlen); return(instance); }
internal static void LoadZoneFile(string path, EngineCore engine) { using (var zip = ZipFile.OpenRead(path)) { using (var ms = new MemoryStream()) { using (var temp = zip.GetEntry("main.oes")?.Open()) temp?.CopyTo(ms); ms.Position = 0; var zone = OESFile.Read <OESZone>(ms); WriteLine($"Loading {zone.Name}"); engine.Add(FromMeshes(FromSkin(zone.Find <OESSkin>().First(), zip), new[] { Matrix4x4.Identity }, zone.Find <OESStaticMesh>())); var objInstances = zone.Find <OESObject>().ToDictionary(x => x, x => new List <Matrix4x4>()); zone.Find <OESInstance>().ForEach(inst => { objInstances[inst.Object].Add(Matrix4x4.CreateScale(inst.Scale) * Matrix4x4.CreateFromQuaternion(inst.Rotation) * Matrix4x4.CreateTranslation(inst.Position)); }); foreach (var(obj, instances) in objInstances) { engine.Add(FromMeshes( FromSkin(obj.Find <OESSkin>().First(), zip), instances.ToArray(), obj.Find <OESStaticMesh>() )); } zone.Find <OESLight>().ForEach(light => engine.AddLight(light.Position, light.Radius, light.Attenuation, light.Color)); } } }
static void Main(string[] args) { using (var zip = ZipFile.OpenRead(args[0])) { using (var ms = new MemoryStream()) { using (var temp = zip.GetEntry("main.oes")?.Open()) temp?.CopyTo(ms); ms.Position = 0; void Display(OESChunk chunk, int indentation) { WriteLine($"{new string('\t', indentation)}{chunk}"); chunk.ForEach(x => Display(x, indentation + 1)); } Display(OESFile.Read(ms), 0); } } }