using System; using System.Collections.Generic; using Oni.Akira; using Oni.Motoko; namespace Oni.Physics { internal class ObjectDatReader { public static ObjectNode ReadObjectGeometry(InstanceDescriptor ofga) { ObjectGeometry[] geometries = null; ObjectParticle[] particles = new ObjectParticle[0]; if (ofga.Template.Tag == TemplateTag.OFGA) { using (var reader = ofga.OpenRead(16)) { var particlesDescriptor = reader.ReadInstance(); geometries = ReadGeometries(reader); if (particlesDescriptor != null) particles = ReadParticles(particlesDescriptor); } } else if (ofga.Template.Tag == TemplateTag.M3GM) { geometries = new ObjectGeometry[1]; geometries[0] = new ObjectGeometry { Flags = GunkFlags.NoOcclusion, Geometry = GeometryDatReader.Read(ofga) }; } return new ObjectNode(geometries, particles); } private static ObjectGeometry[] ReadGeometries(BinaryReader reader) { uint partCount = reader.ReadUInt32(); var nodes = new ObjectGeometry[partCount]; for (int i = 0; i < nodes.Length; i++) nodes[i] = ReadGeometry(reader); return nodes; } private static ObjectGeometry ReadGeometry(BinaryReader reader) { var node = new ObjectGeometry { Flags = (GunkFlags)reader.ReadInt32(), Geometry = GeometryDatReader.Read(reader.ReadInstance()) }; reader.Skip(4); return node; } private static ObjectParticle[] ReadParticles(InstanceDescriptor particlesDescriptor) { using (var reader = particlesDescriptor.OpenRead(22)) { var particles = new ObjectParticle[reader.ReadUInt16()]; for (int i = 0; i < particles.Length; i++) particles[i] = ReadParticle(reader); return particles; } } private static ObjectParticle ReadParticle(BinaryReader reader) { var particle = new ObjectParticle { ParticleClass = reader.ReadString(64), Tag = reader.ReadString(48), Matrix = reader.ReadMatrix4x3(), DecalScale = reader.ReadVector2(), Flags = (Objects.ParticleFlags)reader.ReadUInt16() }; reader.Skip(38); return particle; } public static ObjectAnimation ReadAnimation(InstanceDescriptor oban) { var animation = new ObjectAnimation { Name = oban.Name }; using (var reader = oban.OpenRead(12)) { animation.Flags = (ObjectAnimationFlags)reader.ReadInt32(); reader.Skip(48); var scale = reader.ReadMatrix4x3().Scale; reader.Skip(2); animation.Length = reader.ReadUInt16(); animation.Stop = reader.ReadInt16(); animation.Keys = new ObjectAnimationKey[reader.ReadUInt16()]; for (int i = 0; i < animation.Keys.Length; i++) { animation.Keys[i] = new ObjectAnimationKey { Scale = scale, Rotation = reader.ReadQuaternion(), Translation = reader.ReadVector3(), Time = reader.ReadInt32() }; } } return animation; } } }