Results 1 to 4 of 4

Thread: Some C# code to help get started loading a Collada document

  1. #1
    Junior Member
    Join Date
    Oct 2005
    Posts
    16

    Some C# code to help get started loading a Collada document

    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.

    Code :
    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
    [/code]

  2. #2
    Junior Member
    Join Date
    Oct 2005
    Posts
    16

    Better example

    Hopefully, by the end of the week, I'll post a better, more usable example too. An example that parses through the rest of the geometry data, and stores it off. I might even have an opengl renderer done by then too, so that you will be able to view the file in an application.

  3. #3
    what_nick
    Guest

    Progress

    Has there been any progress with the C# loader?

  4. #4
    Junior Member
    Join Date
    Oct 2005
    Posts
    16

    yes

    Yes, I have a working loader for models in C#. Though it is for collada version 1.3 ... meaning that 1.4 models do not load due to the breaking changes in the way that the xml is formatted.

    Mostly, easy changes, but I just haven't gotten around to fixing it yet.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •