C# kickstart for loading the xmlNodes of a collada document.
This code does not render the mesh, or scene or whatever, but it provides a pretty good starting point for loading the data contained in a collada file.
This basically consists of a function that walks over the xml and loads the various libraries into a dictionary based on their id.
There is a todo statement to help you find where you can load the mesh data. TODO: Save off the mesh data for rendering.
There is an additional class at that provides the string constants that are the elements that we are iterating over.
using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
using System.Xml.XPath;
namespace Game.Model
{
public class Collada
{
public void Load(string fileName)
{
fileName = Environment.ExpandEnvironmentVariables(fileName);
if (! System.IO.File.Exists(fileName) )
return;
//XPathDocument means we are doing a readonly traversal
XPathDocument doc = new XPathDocument(fileName);
XPathNavigator navigator = doc.CreateNavigator();
//Move to the first child element of the document.
//This will be the root element.
navigator.MoveToChild(XPathNodeType.Element);
string uri = string.Empty;
if (navigator.HasAttributes == true)
{
uri = navigator.NamespaceURI;
}
//temp variable -- to get key for data dictionary
string id;
//Since everything is pretty much organized by id semantics
//I've chosen to just add the nodes to a dictionary
//This should make processing the doucment easier.
Dictionary<string, XPathNavigator> data;
data = new Dictionary<string, XPathNavigator>();
//Handle Asset data
structAssetData assetData;
assetData = Collada.GetAssetData(navigator, uri);
////Handle Library data
XPathNodeIterator libraryNodesIterator;
libraryNodesIterator = navigator.SelectChildren(XmlCollada.Library.root, uri);
while (libraryNodesIterator.MoveNext())
{
XPathNodeIterator typeAttributeIterator = libraryNodesIterator.Current.Select("@" + XmlCollada.Library.type);
while (typeAttributeIterator.MoveNext())
{
string typeAttributeValue = typeAttributeIterator.Current.Value;
//Parse the material node
switch (typeAttributeValue)
{
case XmlCollada.Library.VMATERIAL:
XPathNodeIterator materialNodeIterator = libraryNodesIterator.Current.SelectChildren(XmlCollada.Material.root, uri);
while (materialNodeIterator.MoveNext())
{
XPathNodeIterator attributeIterator = materialNodeIterator.Current.Select("@" + XmlCollada.Material.id);
attributeIterator.MoveNext();
id = attributeIterator.Current.Value;
data[id] = libraryNodesIterator.Current;
}
break;
case XmlCollada.Library.VGEOMETRY:
XPathNodeIterator geometryNodeIterator = libraryNodesIterator.Current.SelectChildren(XmlCollada.Geometry.root, uri);
while (geometryNodeIterator.MoveNext())
{
XPathNodeIterator meshNodeIterator = geometryNodeIterator.Current.SelectChildren(XmlCollada.Mesh.root, uri);
while (meshNodeIterator.MoveNext())
{
//Here is the data
XPathNodeIterator sourceNodeIterator = meshNodeIterator.Current.SelectChildren(XmlCollada.Mesh.source, uri);
while (sourceNodeIterator.MoveNext())
{
XPathNodeIterator attributeIterator = sourceNodeIterator.Current.Select("@" + XmlCollada.Source.id);
attributeIterator.MoveNext();
id = attributeIterator.Current.Value;
data[id] = sourceNodeIterator.Current;
}
XPathNodeIterator verticesNodeIterator = meshNodeIterator.Current.SelectChildren(XmlCollada.Mesh.vertices, uri);
while (verticesNodeIterator.MoveNext())
{
XPathNodeIterator attributeIterator = verticesNodeIterator.Current.Select("@" + XmlCollada.Vertices.id);
attributeIterator.MoveNext();
id = attributeIterator.Current.Value;
data[id] = verticesNodeIterator.Current;
}
XPathNodeIterator polygonNodeIterator = meshNodeIterator.Current.SelectChildren(XmlCollada.Mesh.polygons, uri);
XPathNodeIterator linesNodeIterator = meshNodeIterator.Current.SelectChildren(XmlCollada.Mesh.lines, uri);
XPathNodeIterator lineStripsNodeIterator = meshNodeIterator.Current.SelectChildren(XmlCollada.Mesh.linestrips, uri);
XPathNodeIterator trianglesNodeIterator = meshNodeIterator.Current.SelectChildren(XmlCollada.Mesh.triangles, uri);
XPathNodeIterator trifansNodeIterator = meshNodeIterator.Current.SelectChildren(XmlCollada.Mesh.trifans, uri);
XPathNodeIterator tristripsNodeIterator = meshNodeIterator.Current.SelectChildren(XmlCollada.Mesh.tristrips, uri);
//TODO: Save off the mesh data for rendering.
}
}
break;
case XmlCollada.Library.VLIGHT:
XPathNodeIterator lightNodeIterator = libraryNodesIterator.Current.SelectChildren(XmlCollada.Light.root, uri);
while (lightNodeIterator.MoveNext())
{
XPathNodeIterator attributeIterator = lightNodeIterator.Current.Select("@" + XmlCollada.Light.id);
attributeIterator.MoveNext();
id = attributeIterator.Current.Value;
data[id] = lightNodeIterator.Current;
}
break;
case XmlCollada.Library.VCAMERA:
XPathNodeIterator cameraNodeIterator = libraryNodesIterator.Current.SelectChildren(XmlCollada.Camera.root, uri);
while (cameraNodeIterator.MoveNext())
{
XPathNodeIterator attributeIterator = cameraNodeIterator.Current.Select("@" + XmlCollada.Camera.id);
attributeIterator.MoveNext();
id = attributeIterator.Current.Value;
data[id] = cameraNodeIterator.Current;
}
break;
} //end switch library typeAttribte value
}
}
////Handle Scene data
//Keep in mind that according to the specification there will only be one scene element per document.
XPathNodeIterator sceneNodeIterator = navigator.SelectChildren(XmlCollada.Scene.root, uri);
while (sceneNodeIterator.MoveNext())
{
XPathNodeIterator sceneExtraNodeIterator = sceneNodeIterator.Current.SelectChildren(XmlCollada.Extra.root, uri);
XPathNodeIterator sceneNodesNodeIterator = sceneNodeIterator.Current.SelectChildren(XmlCollada.Node.root, uri);
while (sceneNodesNodeIterator.MoveNext())
{
XPathNodeIterator attributeIterator = sceneNodesNodeIterator.Current.Select("@" + XmlCollada.Node.id);
attributeIterator.MoveNext();
id = attributeIterator.Current.Value;
data[id] = sceneNodeIterator.Current;
}
}
}
private struct structAssetData
{
public string copyRight;
public string authoringTool;
public string sourceData;
public string upAxis;
public string unitName;
public string unitMeter;
public string author;
public string dateModified;
}
private static structAssetData GetAssetData(XPathNavigator navigator, string uri)
{
structAssetData result;
result.copyRight = string.Empty;
result.authoringTool = string.Empty;
result.sourceData = string.Empty;
result.upAxis = string.Empty;
result.unitName = string.Empty;
result.unitMeter = string.Empty;
result.author = string.Empty;
result.dateModified = string.Empty;
XPathNodeIterator assetNodeIterator = navigator.SelectDescendants(XmlCollada.Asset.root, uri, false);
while (assetNodeIterator.MoveNext())
{
XPathNodeIterator assetChildrenNodeIterator = assetNodeIterator.Current.SelectChildren(XPathNodeType.Element);
while (assetChildrenNodeIterator.MoveNext())
{
switch (assetChildrenNodeIterator.Current.Name)
{
case XmlCollada.Asset.copyright:
result.copyRight = assetChildrenNodeIterator.Current.Value;
break;
case XmlCollada.Asset.authoringTool:
result.authoringTool = assetChildrenNodeIterator.Current.Value;
break;
case XmlCollada.Asset.sourceData:
result.sourceData = assetChildrenNodeIterator.Current.Value;
break;
case XmlCollada.Asset.upaxis:
result.upAxis = assetChildrenNodeIterator.Current.Value;
break;
case XmlCollada.Asset.unit:
XPathNodeIterator attributeIterator = assetChildrenNodeIterator.Current.Select("@" + XmlCollada.Asset.name);
attributeIterator.MoveNext();
result.unitName = attributeIterator.Current.Value;
attributeIterator = assetChildrenNodeIterator.Current.Select("@" + XmlCollada.Asset.meter);
attributeIterator.MoveNext();
result.unitMeter = attributeIterator.Current.Value;
break;
case XmlCollada.Asset.author:
result.author = assetChildrenNodeIterator.Current.Value;
break;
case XmlCollada.Asset.modified:
result.dateModified = assetChildrenNodeIterator.Current.Value;
break;
}
}
}
return result;
}
} //class
//Here are the constants
public class XmlCollada
{
public class Collada
{
public const string root = "COLLADA";
public const string xmlns = "xmlns";
public const string version = "version";
public const string V130 = "1.3.0";
}
public class Instance
{
public const string root = "instance";
public const string url = "url";
}
public class Camera
{
public const string root = "camera";
public const string id = "id";
public const string name = "name";
}
public class Skew
{
public const string root = "skew";
public const string sid = "sid";
public const string VshearYZ = "shearYZ";
}
public class Vertices
{
public const string root = "vertices";
public const string id = "id";
}
public class Rotate
{
public const string root = "rotate";
public const string sid = "sid";
public const string VrotateY = "rotateY";
public const string VrotateX = "rotateX";
}
public class Program
{
public const string root = "program";
public const string url = "url";
public const string VPHONG = "PHONG";
public const string VPERSPECTIVE = "PERSPECTIVE";
}
public class Float_array
{
public const string root = "float_array";
public const string id = "id";
public const string count = "count";
}
public class Param
{
public const string root = "param";
public const string name = "name";
public const string type = "type";
public const string flow = "flow";
public const string sid = "sid";
public const string VDIFFUSE = "DIFFUSE";
public const string Vfloat3 = "float3";
public const string VIN = "IN";
public const string Vdiffuse = "diffuse";
public const string VAMBIENT = "AMBIENT";
public const string Vparam1 = "param1";
public const string VTRANSPARENT = "TRANSPARENT";
public const string Vtransparent = "transparent";
public const string VTRANSPARENCY = "TRANSPARENCY";
public const string Vfloat = "float";
public const string VEMISSION = "EMISSION";
public const string Vparam4 = "param4";
public const string VSPECULAR = "SPECULAR";
public const string Vparam5 = "param5";
public const string VREFLECTIVE = "REFLECTIVE";
public const string Vparam6 = "param6";
public const string VREFLECTIVITY = "REFLECTIVITY";
public const string Vparam7 = "param7";
public const string VSHININESS = "SHININESS";
public const string Vparam8 = "param8";
public const string VX = "X";
public const string VOUT = "OUT";
public const string VY = "Y";
public const string VZ = "Z";
public const string VDOUBLESIDED = "DOUBLE_SIDED";
public const string Vbool = "bool";
public const string VCOLOR = "COLOR";
public const string Vparam0 = "param0";
public const string VATTENUATION = "ATTENUATION";
public const string Vfunction = "function";
public const string VATTENUATIONSCALE = "ATTENUATION_SCALE";
public const string VVERTICALAPERTURE = "VERTICAL_APERTURE";
public const string VHORIZONTALAPERTURE = "HORIZONTAL_APERTURE";
public const string VLENSSQUEEZE = "LENS_SQUEEZE";
public const string Vparam2 = "param2";
public const string VYFOV = "YFOV";
public const string VZNEAR = "ZNEAR";
public const string VZFAR = "ZFAR";
public const string VSTARTTIME = "START_TIME";
public const string VENDTIME = "END_TIME";
}
public class Geometry
{
public const string root = "geometry";
public const string id = "id";
public const string name = "name";
public const string Vfloor = "floor";
public const string Vcollada = "collada";
}
public class Boundingbox
{
public const string root = "boundingbox";
public const string min = "min";
public const string max = "max";
}
public class Translate
{
public const string root = "translate";
public const string sid = "sid";
public const string Vtranslate = "translate";
}
public class Input
{
public const string root = "input";
public const string semantic = "semantic";
public const string source = "source";
public const string idx = "idx";
public const string VPOSITION = "POSITION";
public const string VNORMAL = "NORMAL";
public const string VVERTEX = "VERTEX";
public const string V0 = "0";
public const string V1 = "1";
}
public class Source
{
public const string root = "source";
public const string id = "id";
}
public class Polygons
{
public const string root = "polygons";
public const string material = "material";
public const string count = "count";
}
public class Node
{
public const string root = "node";
public const string id = "id";
public const string name = "name";
public const string VCamera = "Camera";
public const string VLight = "Light";
public const string VFloor = "Floor";
public const string VCollada = "Collada";
}
public class Extra
{
public const string root = "extra";
}
public class Pass
{
public const string root = "pass";
}
public class Asset
{
public const string root = "asset";
public const string author = "author";
public const string upaxis = "up_axis";
public const string modified = "modified";
public const string unit = "unit";
public const string name = "name";
public const string meter = "meter";
public const string Vcentimeter = "centimeter";
public const string V1e002 = "1.e-002";
public const string sourceData = "source_data";
public const string authoringTool = "authoring_tool";
public const string copyright = "copyright";
}
public class Library
{
public const string root = "library";
public const string type = "type";
public const string VMATERIAL = "MATERIAL";
public const string VGEOMETRY = "GEOMETRY";
public const string VLIGHT = "LIGHT";
public const string VCAMERA = "CAMERA";
}
public class Scene
{
public const string root = "scene";
public const string name = "name";
public const string VcolladaIMaya = "collada_I-Maya";
}
public class Material
{
public const string root = "material";
public const string id = "id";
public const string name = "name";
public const string asset = "asset";
public const string param = "param";
public const string shader = "shader";
public const string VStone = "Stone";
public const string VRedPlastic = "RedPlastic";
}
public class Accessor
{
public const string root = "accessor";
public const string source = "source";
public const string count = "count";
public const string stride = "stride";
public const string V4 = "4";
public const string V3 = "3";
}
public class Mesh
{
public const string root = "mesh";
public const string source = "source";
public const string vertices = "vertices";
public const string lines = "lines";
public const string linestrips = "linestrips";
public const string polygons = "polygons";
public const string triangles = "triangles";
public const string trifans = "trifans";
public const string tristrips = "tristrips";
}
public class Optics
{
public const string root = "optics";
}
public class Shader
{
public const string root = "shader";
}
public class Light
{
public const string root = "light";
public const string id = "id";
public const string name = "name";
public const string type = "type";
public const string Vlight = "light";
public const string VPOINT = "POINT";
}
public class Technique
{
public const string root = "technique";
public const string profile = "profile";
public const string VCOMMON = "COMMON";
public const string VMAYA = "MAYA";
}
/// <summary>
/// Primitive
/// </summary>
public class P
{
public const string root = "p";
}
} //class
} //namespace