using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Globalization; using System.Xml; using System.Drawing; using System.IO; using OpenTK; using System.Runtime.InteropServices; using System.Windows.Forms; using System.Diagnostics; namespace ColladaHelper { public class DAEHelper { private static XmlAttribute createAttribute(XmlDocument doc, string att, string value) { XmlAttribute at = doc.CreateAttribute(att); at.Value = value; return at; } Dictionary sourceLinks = new Dictionary(); List library_images = new List(); List library_materials = new List(); List library_effects = new List(); List library_geometries = new List(); List library_controllers = new List(); ColladaVisualScene scene = new ColladaVisualScene(); public int v1, v2, v3; #region ENUMS public enum ColladaPrimitiveType { None, polygons, polylist, triangles, trifans, tristrips, lines, linestrips } public enum SemanticType { None, POSITION, VERTEX, NORMAL, TEXCOORD, COLOR, WEIGHT, JOINT, INV_BIND_MATRIX, TEXTANGENT, TEXBINORMAL } #endregion #region Assets public void ParseAssets(XmlNode root) { foreach (XmlNode node in root.ChildNodes) { if (node.Name.Equals("unit")) { } if (node.Name.Equals("up_axis")) { } } } #endregion #region Geometry public void ParseGeometry(XmlNode root) { foreach (XmlNode node in root.ChildNodes) { ColladaGeometry g = new ColladaGeometry(); g.Read(node); library_geometries.Add(g); } } public class ColladaGeometry { public string id; public string name; public ColladaMesh mesh; public void Read(XmlNode root) { id = (string)root.Attributes["id"].Value; name = (string)root.Attributes["name"].Value; mesh = new ColladaMesh(); foreach (XmlNode node in root.ChildNodes) { if (node.Name.Equals("mesh")) mesh.Read(node); } } public void Write(XmlDocument doc, XmlNode parent) { XmlNode node = doc.CreateElement("geometry"); node.Attributes.Append(createAttribute(doc, "id", id)); node.Attributes.Append(createAttribute(doc, "name", name)); // write mesh mesh.Write(doc, node); parent.AppendChild(node); } } public class ColladaMesh { public List sources = new List(); public ColladaVertices vertices = new ColladaVertices(); public List polygons = new List(); public void Read(XmlNode root) { foreach (XmlNode node in root.ChildNodes) { if (node.Name.Equals("source")) { ColladaSource source = new ColladaSource(); source.Read(node); sources.Add(source); } if (node.Name.Equals("vertices")) { vertices.Read(node); } if (node.Name.Equals("triangles")) { ColladaPolygons source = new ColladaPolygons(); source.type = ColladaPrimitiveType.triangles; source.Read(node); polygons.Add(source); } if (node.Name.Equals("polylist")) { ColladaPolygons source = new ColladaPolygons(); source.type = ColladaPrimitiveType.polylist; source.Read(node); polygons.Add(source); } } } public void Write(XmlDocument doc, XmlNode parent) { XmlNode node = doc.CreateElement("mesh"); foreach (ColladaSource src in sources) { src.Write(doc, node); } vertices.Write(doc, node); foreach (ColladaPolygons p in polygons) { p.Write(doc, node); } parent.AppendChild(node); } } public enum ArrayType { float_array, Name_array } public class ColladaSource { public string id; public string[] data; public int count; public int stride; public ArrayType type; public List accessor = new List(); public void Read(XmlNode root) { id = (string)root.Attributes["id"].Value; foreach (XmlNode node in root.ChildNodes) { if (node.Name.Equals("float_array")) { count = int.Parse((string)node.Attributes["count"].Value); data = node.InnerText.Trim().Replace("\n", " ").Split(' '); } if (node.Name.Equals("Name_array")) { count = int.Parse((string)node.Attributes["count"].Value); data = node.InnerText.Trim().Replace("\n", " ").Split(' '); } if (node.Name.Equals("technique_common") && node.ChildNodes.Count > 0 && node.ChildNodes[0].Attributes["stride"] != null) { stride = int.Parse((string)node.ChildNodes[0].Attributes["stride"].Value); } } } public void Write(XmlDocument doc, XmlNode parent) { XmlNode node = doc.CreateElement("source"); node.Attributes.Append(createAttribute(doc, "id", id)); //node.Attributes.Append(createAttribute(doc, "count", count)); XmlNode arr = doc.CreateElement(type + ""); node.AppendChild(arr); arr.Attributes.Append(createAttribute(doc, "id", id + "-array")); arr.Attributes.Append(createAttribute(doc, "count", count + "")); string aa = ""; foreach (string s in data) aa += s + " "; arr.InnerText = aa; XmlNode tc = doc.CreateElement("technique_common"); node.AppendChild(tc); XmlNode accessor = doc.CreateElement("accessor"); accessor.Attributes.Append(createAttribute(doc, "source", "#" + id + "-array")); accessor.Attributes.Append(createAttribute(doc, "count", (count / this.accessor.Count) + "")); if (this.accessor.Count > 0 && this.accessor[0].Equals("TRANSFORM")) accessor.Attributes.Append(createAttribute(doc, "stride", 16 + "")); else accessor.Attributes.Append(createAttribute(doc, "stride", this.accessor.Count + "")); tc.AppendChild(accessor); foreach (string param in this.accessor) { XmlNode pa = doc.CreateElement("param"); accessor.AppendChild(pa); pa.Attributes.Append(createAttribute(doc, "name", param)); if (param.Equals("TRANSFORM")) pa.Attributes.Append(createAttribute(doc, "type", "float4x4")); else pa.Attributes.Append(createAttribute(doc, "type", type.ToString().Replace("_array", ""))); } parent.AppendChild(node); } } public class ColladaVertices { public string id; public List inputs = new List(); public void Read(XmlNode root) { id = (string)root.Attributes["id"].Value; foreach (XmlNode node in root.ChildNodes) { if (node.Name.Equals("input")) { ColladaInput input = new ColladaInput(); input.Read(node); inputs.Add(input); } } } public void Write(XmlDocument doc, XmlNode parent) { XmlNode node = doc.CreateElement("vertices"); node.Attributes.Append(createAttribute(doc, "id", id)); foreach (ColladaInput input in inputs) { input.Write(doc, node); } parent.AppendChild(node); } } public class ColladaPolygons { public ColladaPrimitiveType type = ColladaPrimitiveType.triangles; public List inputs = new List(); public int[] p; public int count; public string materialid; public void Read(XmlNode root) { foreach (XmlAttribute att in root.Attributes) { if (att.Name.Equals("material")) materialid = (string)att.Value; if (att.Name.Equals("count")) int.TryParse((string)att.Value, out count); } foreach (XmlNode node in root.ChildNodes) { if (node.Name.Equals("input")) { ColladaInput input = new ColladaInput(); input.Read(node); inputs.Add(input); } if (node.Name.Equals("p")) { string[] ps = node.InnerText.Trim().Split(' '); p = new int[ps.Length]; for (int i = 0; i < ps.Length; i++) p[i] = int.Parse(ps[i]); } } } public void Write(XmlDocument doc, XmlNode parent) { XmlNode node = doc.CreateElement(type.ToString()); node.Attributes.Append(createAttribute(doc, "material", materialid)); node.Attributes.Append(createAttribute(doc, "count", count + "")); foreach (ColladaInput input in inputs) { input.Write(doc, node); } string p = ""; foreach (int i in this.p) { p += i + " "; } XmlNode pi = doc.CreateElement("p"); pi.InnerText = p; node.AppendChild(pi); parent.AppendChild(node); } } public class ColladaInput { public SemanticType semantic; public string source; public int set = -99, offset = 0; public void Read(XmlNode root) { semantic = (SemanticType)Enum.Parse(typeof(SemanticType), (string)root.Attributes["semantic"].Value); source = (string)root.Attributes["source"].Value; if (root.Attributes["set"] != null) int.TryParse((string)root.Attributes["set"].Value, out set); if (root.Attributes["offset"] != null) int.TryParse((string)root.Attributes["offset"].Value, out offset); } public void Write(XmlDocument doc, XmlNode parent) { XmlNode node = doc.CreateElement("input"); node.Attributes.Append(createAttribute(doc, "semantic", semantic.ToString())); node.Attributes.Append(createAttribute(doc, "source", source)); if (set != -99) node.Attributes.Append(createAttribute(doc, "set", set + "")); if (offset != -99) node.Attributes.Append(createAttribute(doc, "offset", offset + "")); parent.AppendChild(node); } } #endregion #region Materials // Images and Materials public void ParseMaterials(XmlNode root) { foreach (XmlNode node in root.ChildNodes) { ColladaMaterials m = new ColladaMaterials(); m.Read(node); library_materials.Add(m); } } public void ParseImages(XmlNode root) { foreach (XmlNode node in root.ChildNodes) { ColladaImages m = new ColladaImages(); m.Read(node); library_images.Add(m); } } public void ParseEffects(XmlNode root) { foreach (XmlNode node in root.ChildNodes) { ColladaEffects m = new ColladaEffects(); m.Read(node); library_effects.Add(m); } } public class ColladaImages { public string id, name, initref; public void Read(XmlNode root) { id = root.Attributes["id"].Value; //name = root.Attributes["name"].Value; foreach (XmlNode child in root.ChildNodes) { if (child.Name.Equals("init_from")) { initref = child.InnerText; if (initref.StartsWith("file://")) initref = initref.Substring(7, initref.Length - 7); } } } public void Write(XmlDocument doc, XmlNode parent) { XmlNode node = doc.CreateElement("image"); node.Attributes.Append(createAttribute(doc, "id", id)); node.Attributes.Append(createAttribute(doc, "name", name)); XmlNode init = doc.CreateElement("init_from"); init.InnerText = initref; node.AppendChild(init); parent.AppendChild(node); } } public class ColladaMaterials { public string id, effecturl; public void Read(XmlNode root) { id = root.Attributes["id"].Value; foreach (XmlNode node in root.ChildNodes) if (node.Name.Equals("instance_effect") && node.Attributes["url"] != null) effecturl = node.Attributes["url"].Value; } public void Write(XmlDocument doc, XmlNode parent) { XmlNode node = doc.CreateElement("material"); node.Attributes.Append(createAttribute(doc, "id", id)); XmlNode init = doc.CreateElement("instance_effect"); init.Attributes.Append(createAttribute(doc, "url", effecturl)); node.AppendChild(init); parent.AppendChild(node); } } public class ColladaEffects { public string id, name; public string source = "#"; public ColladaSampler2D sampler; public void Read(XmlNode root) { foreach (XmlAttribute att in root.Attributes) { if (att.Name.Equals("id")) id = att.Value; if (att.Name.Equals("name")) name = root.Attributes["name"].Value; } foreach (XmlNode node in root.ChildNodes) { if (node.Name.Equals("profile_COMMON")) { readEffectTechnique(node); } } } private void readEffectTechnique(XmlNode root) { Dictionary surfaces = new Dictionary(); Dictionary samplers = new Dictionary(); foreach (XmlNode node in root.ChildNodes) { if (node.Name.Equals("newparam") && node.ChildNodes[0].Name.Equals("surface")) surfaces.Add(node.Attributes["sid"].Value, node.ChildNodes[0]); if (node.Name.Equals("newparam") && node.ChildNodes[0].Name.Equals("sampler2D")) samplers.Add(node.Attributes["sid"].Value, node.ChildNodes[0]); } foreach (XmlNode node in root.ChildNodes) { if (node.Name.Equals("technique") && node.ChildNodes[0].Name.Equals("phong")) { foreach (XmlNode node1 in node.ChildNodes[0].ChildNodes) { if (node1.Name.Equals("diffuse")) { foreach (XmlNode node2 in node1.ChildNodes) { if (node2.Name.Equals("texture")) { string texture = node2.Attributes["texture"].Value; XmlNode temp = null; samplers.TryGetValue(texture, out temp); if (temp != null) { foreach (XmlNode node3 in temp.ChildNodes) { if (node3.Name.Equals("source")) { //if you are reading this I am sorry XmlNode temp2 = null; surfaces.TryGetValue(node3.InnerText, out temp2); if (temp2 != null) { texture = temp2.ChildNodes[0].InnerText; } } } } source = "#" + texture; } } } } } } } // for writing public void Write(XmlDocument doc, XmlNode parent) { XmlNode node = doc.CreateElement("effect"); node.Attributes.Append(createAttribute(doc, "id", id)); node.Attributes.Append(createAttribute(doc, "name", name)); XmlNode prof = doc.CreateElement("profile_COMMON"); node.AppendChild(prof); { XmlNode np = doc.CreateElement("newparam"); prof.AppendChild(np); np.Attributes.Append(createAttribute(doc, "sid", id + "-surface")); XmlNode sur = doc.CreateElement("surface"); np.AppendChild(sur); XmlNode init = doc.CreateElement("init_from"); sur.AppendChild(init); init.InnerText = source.Replace("#", ""); sur.Attributes.Append(createAttribute(doc, "type", "2D")); } { XmlNode np = doc.CreateElement("newparam"); prof.AppendChild(np); np.Attributes.Append(createAttribute(doc, "sid", id + "-sampler")); sampler.source = id + "-surface"; sampler.Write(doc, np); } { XmlNode tech = doc.CreateElement("technique"); prof.AppendChild(tech); tech.Attributes.Append(createAttribute(doc, "sid", "COMMON")); XmlNode sur = doc.CreateElement("phong"); tech.AppendChild(sur); XmlNode init = doc.CreateElement("diffuse"); sur.AppendChild(init); XmlNode reff = doc.CreateElement("texture"); init.AppendChild(reff); reff.Attributes.Append(createAttribute(doc, "texture", id + "-sampler")); reff.Attributes.Append(createAttribute(doc, "texcoord", "")); } parent.AppendChild(node); } } public enum COLLADA_WRAPMODE { WRAP, REPEAT, CLAMP, CLAMP_TO_EDGE, MIRROR } public enum COLLADA_FILTER { NONE, NEAREST, LINEAR } public class ColladaSampler2D { public string source, url; public COLLADA_WRAPMODE wrap_s, wrap_t; public COLLADA_FILTER minfilter, magfilter; public void Write(XmlDocument doc, XmlNode parent) { XmlNode node = doc.CreateElement("sampler2D"); { XmlNode src = doc.CreateElement("source"); src.InnerText = source; node.AppendChild(src); } { XmlNode src = doc.CreateElement("wrap_s"); src.InnerText = wrap_s.ToString(); node.AppendChild(src); } { XmlNode src = doc.CreateElement("wrap_t"); src.InnerText = wrap_t.ToString(); node.AppendChild(src); } parent.AppendChild(node); } } #endregion #region Controllers public void ParseControllers(XmlNode root) { foreach (XmlNode node in root.ChildNodes) { ColladaController g = new ColladaController(); g.Read(node); library_controllers.Add(g); } } public class ColladaController { public string id; public ColladaSkin skin = new ColladaSkin(); public void Read(XmlNode root) { id = (string)root.Attributes["id"].Value; foreach (XmlNode node in root.ChildNodes) { if (node.Name.Equals("skin")) { skin.Read(node); } } } public void Write(XmlDocument doc, XmlNode parent) { XmlNode node = doc.CreateElement("controller"); node.Attributes.Append(createAttribute(doc, "id", id)); skin.Write(doc, node); parent.AppendChild(node); } } public class ColladaSkin { public string source; public Matrix4 mat = Matrix4.CreateScale(1, 1, 1); public List sources = new List(); public ColladaJoints joints = new ColladaJoints(); public ColladaVertexWeights weights = new ColladaVertexWeights(); public void Read(XmlNode root) { source = (string)root.Attributes["source"].Value; foreach (XmlNode node in root.ChildNodes) { if (node.Name.Equals("bind_shape_matrix")) { string[] data = node.InnerText.Trim().Replace("\n", " ").Split(' '); mat.M11 = float.Parse(data[0]); mat.M12 = float.Parse(data[1]); mat.M13 = float.Parse(data[2]); mat.M14 = float.Parse(data[3]); mat.M21 = float.Parse(data[4]); mat.M22 = float.Parse(data[5]); mat.M23 = float.Parse(data[6]); mat.M24 = float.Parse(data[7]); mat.M31 = float.Parse(data[8]); mat.M32 = float.Parse(data[9]); mat.M33 = float.Parse(data[10]); mat.M34 = float.Parse(data[11]); mat.M41 = float.Parse(data[12]); mat.M42 = float.Parse(data[13]); mat.M43 = float.Parse(data[14]); mat.M44 = float.Parse(data[15]); } if (node.Name.Equals("source")) { ColladaSource source = new ColladaSource(); source.Read(node); sources.Add(source); } if (node.Name.Equals("joints")) { joints.Read(node); } if (node.Name.Equals("vertex_weights")) { weights.Read(node); } } } public void Write(XmlDocument doc, XmlNode parent) { XmlNode node = doc.CreateElement("skin"); node.Attributes.Append(createAttribute(doc, "source", source)); XmlNode matrix = doc.CreateElement("matrix"); node.AppendChild(matrix); matrix.InnerText = mat.M11 + " " + mat.M21 + " " + mat.M31 + " " + mat.M41 + " " + mat.M12 + " " + mat.M22 + " " + mat.M32 + " " + mat.M42 + " " + mat.M13 + " " + mat.M23 + " " + mat.M33 + " " + mat.M43 + " " + mat.M14 + " " + mat.M24 + " " + mat.M34 + " " + mat.M44; foreach (ColladaSource src in sources) { src.Write(doc, node); } joints.Write(doc, node); weights.Write(doc, node); parent.AppendChild(node); } } public class ColladaJoints { public List inputs = new List(); public void Read(XmlNode root) { foreach (XmlNode node in root.ChildNodes) { if (node.Name.Equals("input")) { ColladaInput input = new ColladaInput(); input.Read(node); inputs.Add(input); } } } public void Write(XmlDocument doc, XmlNode parent) { XmlNode node = doc.CreateElement("joints"); foreach (ColladaInput input in inputs) { input.Write(doc, node); } parent.AppendChild(node); } } public class ColladaVertexWeights { public List inputs = new List(); public int[] v, vcount; public int count; public void Read(XmlNode root) { count = int.Parse((string)root.Attributes["count"].Value); foreach (XmlNode node in root.ChildNodes) { if (node.Name.Equals("input")) { ColladaInput input = new ColladaInput(); input.Read(node); inputs.Add(input); } if (node.Name.Equals("vcount")) { string[] ps = node.InnerText.Trim().Split(' '); vcount = new int[ps.Length]; for (int i = 0; i < ps.Length; i++) vcount[i] = int.Parse(ps[i]); } if (node.Name.Equals("v")) { string[] ps = node.InnerText.Trim().Split(' '); v = new int[ps.Length]; for (int i = 0; i < ps.Length; i++) v[i] = int.Parse(ps[i]); } } } public void Write(XmlDocument doc, XmlNode parent) { XmlNode node = doc.CreateElement("vertex_weights"); node.Attributes.Append(createAttribute(doc, "count", vcount.Length.ToString())); foreach (ColladaInput input in inputs) { input.Write(doc, node); } XmlNode vc = doc.CreateElement("vcount"); XmlNode p = doc.CreateElement("v"); node.AppendChild(vc); node.AppendChild(p); string ar = ""; foreach (int i in vcount) ar += i + " "; vc.InnerText = ar; ar = ""; foreach (int i in v) ar += i + " "; p.InnerText = ar; parent.AppendChild(node); } } #endregion #region Visual Nodes public class ColladaVisualScene { public List nodes = new List(); public string id, name; public Dictionary MaterialIds = new Dictionary(); public void Read(XmlNode root) { root = root.ChildNodes[0]; id = (string)root.Attributes["id"].Value; name = (string)root.Attributes["name"].Value; foreach (XmlNode node in root.ChildNodes) { if (node.Name.Equals("node")) { ColladaNode n = new ColladaNode(); n.Read(node, null); nodes.Add(n); foreach (var v in n.materialIds) { if (!MaterialIds.ContainsKey(v.Key)) MaterialIds.Add(v.Key, v.Value); } } } } public void Write(XmlDocument doc, XmlNode parent) { XmlNode node = doc.CreateElement("library_visual_scenes"); XmlNode vs = doc.CreateElement("visual_scene"); vs.Attributes.Append(createAttribute(doc, "id", "VisualSceneNode")); vs.Attributes.Append(createAttribute(doc, "name", "rdmscene")); node.AppendChild(vs); foreach (ColladaNode no in nodes) { no.Write(doc, vs); } parent.AppendChild(node); } } public class ColladaNode { public ColladaNode parent; public string id, name, type = "NODE", geomid, instance = ""; public List children = new List(); public Matrix4 mat = Matrix4.CreateScale(1, 1, 1); public Vector3 pos = new Vector3(); public Vector3 scale = new Vector3(); public Vector3 rot = new Vector3(); // material public string materialSymbol, materialTarget; public Dictionary materialIds = new Dictionary(); // instance geometry public string geom_id = ""; public void Read(XmlNode root, ColladaNode parent) { this.parent = parent; id = (string)root.Attributes["id"].Value; name = (string)root.Attributes["name"].Value; if (root.Attributes["type"] != null) type = (string)root.Attributes["type"].Value; foreach (XmlNode node in root.ChildNodes) { if (node.Name.Equals("node")) { ColladaNode n = new ColladaNode(); n.Read(node, this); children.Add(n); } else if (node.Name.Equals("matrix")) { string[] data = node.InnerText.Trim().Replace("\n", " ").Split(' '); mat = new Matrix4(); mat.M11 = float.Parse(data[0]); mat.M12 = float.Parse(data[1]); mat.M13 = float.Parse(data[2]); mat.M14 = float.Parse(data[3]); mat.M21 = float.Parse(data[4]); mat.M22 = float.Parse(data[5]); mat.M23 = float.Parse(data[6]); mat.M24 = float.Parse(data[7]); mat.M31 = float.Parse(data[8]); mat.M32 = float.Parse(data[9]); mat.M33 = float.Parse(data[10]); mat.M34 = float.Parse(data[11]); mat.M41 = float.Parse(data[12]); mat.M42 = float.Parse(data[13]); mat.M43 = float.Parse(data[14]); mat.M44 = float.Parse(data[15]); pos = new Vector3(mat.M14, mat.M24, mat.M34); scale = mat.ExtractScale(); mat.ClearScale(); mat.ClearTranslation(); mat.Invert(); var quat = mat.ExtractRotation(); rot = Toolbox.Library.AssimpHelper.ToEulerAngles(quat); if (float.IsNaN(rot.X)) rot.X = 0; if (float.IsNaN(rot.Y)) rot.Y = 0; if (float.IsNaN(rot.Z)) rot.Z = 0; mat.M11 = float.Parse(data[0]); mat.M12 = float.Parse(data[1]); mat.M13 = float.Parse(data[2]); mat.M14 = float.Parse(data[3]); mat.M21 = float.Parse(data[4]); mat.M22 = float.Parse(data[5]); mat.M23 = float.Parse(data[6]); mat.M24 = float.Parse(data[7]); mat.M31 = float.Parse(data[8]); mat.M32 = float.Parse(data[9]); mat.M33 = float.Parse(data[10]); mat.M34 = float.Parse(data[11]); mat.M41 = float.Parse(data[12]); mat.M42 = float.Parse(data[13]); mat.M43 = float.Parse(data[14]); mat.M44 = float.Parse(data[15]); } else if (node.Name.Equals("extra")) { } else if (node.Name.Equals("instance_controller") || node.Name.Equals("instance_geometry")) { if (node.Name.Equals("instance_geometry")) { geom_id = node.Attributes["url"].Value.Replace("#", ""); } foreach (XmlNode node1 in node.ChildNodes) { if (node1.Name.Equals("bind_material")) { foreach (XmlNode node2 in node1.ChildNodes) { if (node2.Name.Equals("technique_common")) { if (node2.ChildNodes[0].Attributes["symbol"] != null && !materialIds.ContainsKey(node2.ChildNodes[0].Attributes["symbol"].Value)) materialIds.Add(node2.ChildNodes[0].Attributes["symbol"].Value, node2.ChildNodes[0].Attributes["target"].Value); } } } } } else if (node.Name.Equals("translate")) { string[] data = node.InnerText.Trim().Replace("\n", " ").Split(' '); pos = new Vector3(float.Parse(data[0]), float.Parse(data[1]), float.Parse(data[2])); } else if (node.Name.Equals("scale")) { string[] data = node.InnerText.Trim().Replace("\n", " ").Split(' '); scale = new Vector3(float.Parse(data[0]), float.Parse(data[1]), float.Parse(data[2])); } else if (node.Name.Equals("rotate")) { string[] data = node.InnerText.Trim().Replace("\n", " ").Split(' '); rot = new Vector3(float.Parse(data[0]), float.Parse(data[1]), float.Parse(data[2])); } } } public void Write(XmlDocument doc, XmlNode parent) { XmlNode node = doc.CreateElement("node"); node.Attributes.Append(createAttribute(doc, "id", id)); node.Attributes.Append(createAttribute(doc, "name", name)); node.Attributes.Append(createAttribute(doc, "type", type)); if (type.Equals("JOINT")) node.Attributes.Append(createAttribute(doc, "sid", name)); // transform matrix XmlNode matrix = doc.CreateElement("matrix"); node.AppendChild(matrix); matrix.InnerText = mat.M11 + " " + mat.M21 + " " + mat.M31 + " " + mat.M41 + " " + mat.M12 + " " + mat.M22 + " " + mat.M32 + " " + mat.M42 + " " + mat.M13 + " " + mat.M23 + " " + mat.M33 + " " + mat.M43 + " " + mat.M14 + " " + mat.M24 + " " + mat.M34 + " " + mat.M44; // instance geometry (no rigging) instance controller for rigging if (!instance.Equals("")) { XmlNode inst = doc.CreateElement(instance); inst.Attributes.Append(createAttribute(doc, "url", geomid)); node.AppendChild(inst); if (instance.Equals("instance_controller")) { XmlNode skel = doc.CreateElement("skeleton"); inst.AppendChild(skel); skel.InnerText = "#Bone_0_id"; } if (materialSymbol != null && materialTarget != null) { XmlNode bn = doc.CreateElement("bind_material"); inst.AppendChild(bn); XmlNode tc = doc.CreateElement("technique_common"); bn.AppendChild(tc); XmlNode im = doc.CreateElement("instance_material"); tc.AppendChild(im); im.Attributes.Append(createAttribute(doc, "symbol", materialSymbol)); im.Attributes.Append(createAttribute(doc, "target", materialTarget)); } } foreach (ColladaNode no in children) { no.Write(doc, node); } parent.AppendChild(node); } } #endregion } }