Switch-Toolbox/Switch_Toolbox_Library/FileFormats/DAE/ColladaHelper.cs
2019-07-28 12:45:39 -04:00

1048 lines
39 KiB
C#

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<string, object> sourceLinks = new Dictionary<string, object>();
List<ColladaImages> library_images = new List<ColladaImages>();
List<ColladaMaterials> library_materials = new List<ColladaMaterials>();
List<ColladaEffects> library_effects = new List<ColladaEffects>();
List<ColladaGeometry> library_geometries = new List<ColladaGeometry>();
List<ColladaController> library_controllers = new List<ColladaController>();
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<ColladaSource> sources = new List<ColladaSource>();
public ColladaVertices vertices = new ColladaVertices();
public List<ColladaPolygons> polygons = new List<ColladaPolygons>();
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<string> accessor = new List<string>();
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<ColladaInput> inputs = new List<ColladaInput>();
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<ColladaInput> inputs = new List<ColladaInput>();
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<string, XmlNode> surfaces = new Dictionary<string, XmlNode>();
Dictionary<string, XmlNode> samplers = new Dictionary<string, XmlNode>();
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<ColladaSource> sources = new List<ColladaSource>();
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<ColladaInput> inputs = new List<ColladaInput>();
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<ColladaInput> inputs = new List<ColladaInput>();
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<ColladaNode> nodes = new List<ColladaNode>();
public string id, name;
public Dictionary<string, string> MaterialIds = new Dictionary<string, string>();
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<ColladaNode> children = new List<ColladaNode>();
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<string, string> materialIds = new Dictionary<string, string>();
// 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
}
}