using System.Collections.Generic; using System.Globalization; using System.IO; using System.Xml; using RothenburgAR.Common; using UnityEngine; namespace RothenburgAR.Exhibition { public class ExhibitionXmlPreloader : IExhibitionPreloader { public bool CanLoadExhibitionDirectory(string exhibitionDirectory) { if (!Directory.Exists(exhibitionDirectory)) return false; string xmlFilePath = PathHelper.GetXmlPathFromDirectoryPath(exhibitionDirectory); if (!File.Exists(xmlFilePath)) return false; if (!File.Exists(Path.Combine(exhibitionDirectory, "tracker.xml"))) return false; if (!File.Exists(Path.Combine(exhibitionDirectory, "tracker.dat"))) return false; // Todo: More validations return true; } public PreloadedExhibition PreloadExhibition(string exhibitionDirectory) { string xmlFilePath = PathHelper.GetXmlPathFromDirectoryPath(exhibitionDirectory); if (!File.Exists(xmlFilePath)) throw new FileNotFoundException(xmlFilePath); XmlDocument doc = new XmlDocument(); doc.Load(xmlFilePath); // Read the ID from the xml if (doc.DocumentElement == null || doc.DocumentElement.Attributes == null || doc.DocumentElement.Attributes["id"] == null) throw new InvalidXMLException("Could not read doc.DocumentElement.Attributes['id] "); string exhibitionId = doc.DocumentElement.Attributes["id"].Value; PreloadedExhibition resultExhibition = new PreloadedExhibition { ContainedExhibits = new List(), ID = exhibitionId, DatasetPath = exhibitionDirectory }; var exhibitNodes = doc.SelectNodes("//exhibition/exhibit"); foreach (XmlNode exhibitNode in exhibitNodes) { if (exhibitNode.Attributes == null || exhibitNode.Attributes["id"] == null) { // Todo: Log error continue; } var newExhibit = PreloadExhibit(exhibitionDirectory, exhibitNode); resultExhibition.ContainedExhibits.Add(newExhibit); } return resultExhibition; } private PreloadedExhibit PreloadExhibit(string exhibitionDirectory, XmlNode exhibitNode) { PreloadedExhibit newExhibit = new PreloadedExhibit(); newExhibit.ID = exhibitNode.Attributes["id"].Value; newExhibit.ReferencedPoiEntries = new List(); // Load Description Text XmlNodeList descrList = exhibitNode.SelectNodes("description/text"); if (descrList != null && descrList.Count > 0) { TextElement exhibitDescr = TextElement.BuildFromXmlNode(exhibitionDirectory, descrList); newExhibit.Description = exhibitDescr; } // Load Title Text XmlNodeList titleList = exhibitNode.SelectNodes("title/text"); if (titleList != null && titleList.Count > 0) { TextElement exhibitTitle = TextElement.BuildFromXmlNode(exhibitionDirectory, titleList); var fontSize = GetFloatFromXmlNode(exhibitNode.SelectSingleNode("title/font"), "size"); var boxHeight = GetFloatFromXmlNode(exhibitNode.SelectSingleNode("title/dimensions"), "height"); var boxWidth = GetFloatFromXmlNode(exhibitNode.SelectSingleNode("title/dimensions"), "width"); PreloadedExhibitTitle preTitle = new PreloadedExhibitTitle { Text = exhibitTitle, Position = GetVector3FromXmlNode(exhibitNode.SelectSingleNode("title/position")), Rotation = GetVector3FromXmlNode(exhibitNode.SelectSingleNode("title/rotation")), FontSize = fontSize ?? 20, BoxWidth = boxWidth ?? 200, BoxHeight = boxHeight ?? 25 }; newExhibit.Title = preTitle; } // Load POI References XmlNodeList poiRefList = exhibitNode.SelectNodes("poiList/poi"); if (poiRefList != null && poiRefList.Count > 0) { foreach (XmlNode poiRefEntry in poiRefList) { if (poiRefEntry.Attributes == null || poiRefEntry.Attributes["ref-id"] == null) continue; PreloadedPoiReference poiReference = new PreloadedPoiReference { ReferencedId = poiRefEntry.Attributes["ref-id"].Value, Position = GetVector3FromXmlNode(poiRefEntry.SelectSingleNode("position")), Rotation = GetVector3FromXmlNode(poiRefEntry.SelectSingleNode("rotation")), Scale = GetVector3FromXmlNode(poiRefEntry.SelectSingleNode("scale")) }; newExhibit.ReferencedPoiEntries.Add(poiReference); } } return newExhibit; } private string GetStringFromXmlNode(XmlNode node, string key) { if (node == null) return null; if (node.Attributes == null) return null; if (node.Attributes[key] == null) return null; return node.Attributes[key].Value; } private float? GetFloatFromXmlNode(XmlNode node, string key) { var str = GetStringFromXmlNode(node, key); if (str == null) return null; try { return float.Parse(str, CultureInfo.InvariantCulture.NumberFormat); } catch { return null; } } private Vector3? GetVector3FromXmlNode(XmlNode node) { if (node == null) return null; if (node.Attributes == null) return null; if (node.Attributes["x"] == null) return null; if (node.Attributes["y"] == null) return null; if (node.Attributes["z"] == null) return null; try { float posX = float.Parse(node.Attributes["x"].Value, CultureInfo.InvariantCulture.NumberFormat); float posY = float.Parse(node.Attributes["y"].Value, CultureInfo.InvariantCulture.NumberFormat); float posZ = float.Parse(node.Attributes["z"].Value, CultureInfo.InvariantCulture.NumberFormat); return new Vector3(posX, posY, posZ); } catch { // TODO: log error return null; } } } }