using System; using System.Collections.Generic; using System.IO; using System.Xml; namespace Oni.Level { internal partial class LevelImporter : Importer { private readonly TextWriter info; private readonly TextWriter error; private bool debug; private string outputDirPath; private LevelDatWriter.DatLevel level; private string sharedPath; private InstanceFileManager sharedManager; private Dictionary sharedCache; private Dictionary sceneCache; public LevelImporter() { info = Console.Out; error = Console.Error; } public bool Debug { get { return debug; } set { debug = value; } } public override void Import(string filePath, string outputDirPath) { this.outputDirPath = outputDirPath; this.textureImporter = new Motoko.TextureImporter3(outputDirPath); Read(filePath); WriteLevel(); WriteObjects(); } private void Read(string filePath) { level = new LevelDatWriter.DatLevel(); level.name = Path.GetFileNameWithoutExtension(filePath); string basePath = Path.GetDirectoryName(filePath); var settings = new XmlReaderSettings { IgnoreWhitespace = true, IgnoreProcessingInstructions = true, IgnoreComments = true }; using (var xml = XmlReader.Create(filePath, settings)) { xml.ReadStartElement("Oni"); ReadLevel(xml, basePath); xml.ReadEndElement(); } ImportModel(basePath); } private void ReadLevel(XmlReader xml, string basePath) { string path = xml.GetAttribute("SharedPath"); if (!string.IsNullOrEmpty(path)) sharedPath = Path.GetFullPath(Path.Combine(basePath, path)); else sharedPath = Path.GetFullPath(Path.Combine(basePath, "classes")); sharedManager = new InstanceFileManager(); sharedManager.AddSearchPath(sharedPath); string name = xml.GetAttribute("Name"); if (!string.IsNullOrEmpty(name)) level.name = name; xml.ReadStartElement("Level"); ReadModel(xml, basePath); ReadSky(xml, basePath); ReadObjects(xml, basePath); ReadFilms(xml, basePath); ReadCameras(xml, basePath); xml.ReadEndElement(); } private void WriteLevel() { BeginImport(); LevelDatWriter.Write(this, level); Write(outputDirPath); textureImporter.Write(); } private Dae.Scene LoadScene(string filePath) { if (sceneCache == null) { sceneCache = new Dictionary(StringComparer.OrdinalIgnoreCase); } filePath = Path.GetFullPath(filePath); Dae.Scene scene; if (!sceneCache.TryGetValue(filePath, out scene)) { scene = Dae.Reader.ReadFile(filePath); sceneCache.Add(filePath, scene); } return scene; } private InstanceDescriptor FindSharedInstance(TemplateTag tag, string name) { if (sharedCache == null) sharedCache = new Dictionary(StringComparer.Ordinal); string fullName = tag.ToString() + name; InstanceDescriptor descriptor; if (!sharedCache.TryGetValue(fullName, out descriptor)) { var file = sharedManager.FindInstance(fullName); if (file == null) error.WriteLine("Could not find {0} instance {1}", tag, name); else if (file.Descriptors[0].Template.Tag != tag) error.WriteLine("Found '{0}' but its type {1} doesn't match the expected type {2}", name, file.Descriptors[0].Template.Tag, tag); else descriptor = file.Descriptors[0]; sharedCache.Add(fullName, descriptor); } return descriptor; } } }