Files
RothenburgAR/Assets/RothenburgAR/Scripts/Exhibition/ExhibitionXmlPreloader.cs
2018-08-15 20:58:47 +02:00

188 lines
7.0 KiB
C#

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<PreloadedExhibit>(),
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<PreloadedPoiReference>();
// 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;
}
}
}
}