188 lines
7.0 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|
|
} |