private static List <ModelGeometry> LoadGeometries(XElement geometryNode, SemanticAssociations association, List <Vector4> weights = null, List <Vector4> joints = null) { List <ModelGeometry> geometries = new List <ModelGeometry>(); //geometry if (geometryNode.GetNode("mesh") != null) { //if mesh load data var mesh = geometryNode.GetNode("mesh"); var sources = mesh.GetNodes("source"); var vertices = mesh.GetNodes("vertices"); //load data, only triangles supported foreach (var elem in mesh.Elements()) { ModelGeometry geometry = new ModelGeometry(); geometry.Name = geometryNode.GetAttribute("id"); //lines //linestrips switch (elem.Name.LocalName) { case "polygons": break; case "polylist": break; case "triangles": GetTriangleMesh(geometry, elem, mesh, association, weights, joints); geometry.Optimize(); geometries.Add(geometry); break; case "trifans": break; case "tristrips": break; default: break; } } } return(geometries); }
/// <summary> /// Load From File /// </summary> /// <param name="filename">Filename</param> /// <param name="association">Custom Semantic Association</param> /// <returns>Model</returns> public static ModelData Import(string filename, SemanticAssociations association) { ModelData data = new ModelData(); XDocument doc = XDocument.Load(filename); //search for visual scene //instance_visual_scene XElement scene = doc.GetNode("instance_visual_scene"); if (scene == null) { return(null); } XElement sceneReference = doc.GetReference(scene); data.Name = sceneReference.GetAttribute("name"); //Search for Nodes foreach (XElement c in sceneReference.GetChildren("node")) { data.Nodes.Add(LoadNodes(c, association)); } //Search for Animations XElement animation = doc.GetNode("library_animations"); Animation anim = new Animation(); if (animation != null) { var list = animation.GetNodes("animation"); foreach (XElement a in list) { anim.Nodes.Add(CreateAnimationTrack(a)); } } data.Animations.Add(anim); return(data); }
private static ModelNode LoadNodes(XElement element, SemanticAssociations association) { ModelNode node = new ModelNode(); node.Name = element.GetAttribute("id"); //type string type = element.GetAttribute("type").ToLower(); if (string.IsNullOrEmpty(type) || type == "node") { node.Type = NodeType.Node; } else { node.Type = NodeType.Joint; } //world matrix node.World = ComputeMatrix(element); //Iterate each node foreach (XElement c in element.GetChildren("node")) { //Load Children node.Children.Add(LoadNodes(c, association)); } //Iterate Geometries foreach (XElement g in element.GetNodes("instance_geometry")) { node.Geometries.AddRange(LoadGeometries(g.GetReference(), association)); } //Get Animation Controller foreach (XElement c in element.GetNodes("instance_controller")) { SkinInformation skin; node.Geometries.AddRange(LoadController(c, association, out skin)); node.Skinning = skin; } return(node); }
/// <summary> /// Load From File /// </summary> /// <param name="filename">Filename</param> /// <param name="association">Custom Semantic Association</param> /// <returns>Model</returns> public static ModelData Import(string filename, SemanticAssociations association) { ModelData data = new ModelData(); XDocument doc = XDocument.Load(filename); //search for visual scene //instance_visual_scene XElement scene = doc.GetNode("instance_visual_scene"); if (scene == null) return null; XElement sceneReference = doc.GetReference(scene); data.Name = sceneReference.GetAttribute("name"); //Search for Nodes foreach (XElement c in sceneReference.GetChildren("node")) { data.Nodes.Add(LoadNodes(c, association)); } //Search for Animations XElement animation = doc.GetNode("library_animations"); Animation anim = new Animation(); if (animation != null) { var list = animation.GetNodes("animation"); foreach (XElement a in list) anim.Nodes.Add(CreateAnimationTrack(a)); } data.Animations.Add(anim); return data; }
private static ModelNode LoadNodes(XElement element, SemanticAssociations association) { ModelNode node = new ModelNode(); node.Name = element.GetAttribute("id"); //type string type = element.GetAttribute("type").ToLower(); if (string.IsNullOrEmpty(type) || type == "node") node.Type = NodeType.Node; else node.Type = NodeType.Joint; //world matrix node.World = ComputeMatrix(element); //Iterate each node foreach (XElement c in element.GetChildren("node")) { //Load Children node.Children.Add(LoadNodes(c, association)); } //Iterate Geometries foreach (XElement g in element.GetNodes("instance_geometry")) { node.Geometries.AddRange(LoadGeometries(g.GetReference(), association)); } //Get Animation Controller foreach (XElement c in element.GetNodes("instance_controller")) { SkinInformation skin; node.Geometries.AddRange(LoadController(c, association, out skin)); node.Skinning = skin; } return node; }
private static List<ModelGeometry> LoadGeometries(XElement geometryNode, SemanticAssociations association, List<Vector4> weights = null, List<Vector4> joints = null) { List<ModelGeometry> geometries = new List<ModelGeometry>(); //geometry if (geometryNode.GetNode("mesh") != null) { //if mesh load data var mesh = geometryNode.GetNode("mesh"); var sources = mesh.GetNodes("source"); var vertices = mesh.GetNodes("vertices"); //load data, only triangles supported foreach (var elem in mesh.Elements()) { ModelGeometry geometry = new ModelGeometry(); geometry.Name = geometryNode.GetAttribute("id"); //lines //linestrips switch (elem.Name.LocalName) { case "polygons": break; case "polylist": break; case "triangles": GetTriangleMesh(geometry, elem, mesh, association, weights, joints); geometry.Optimize(); geometries.Add(geometry); break; case "trifans": break; case "tristrips": break; default: break; } } } return geometries; }
private static List<ModelGeometry> LoadController(XElement element, SemanticAssociations association, out SkinInformation skinInfo) { skinInfo = new SkinInformation(); XElement skin = element.GetReference().GetChild("skin"); if (skin == null) { //only skinned animation supported throw new NotSupportedException("Only Skin Animation supported"); } //target geometry string geometryUrl = skin.GetAttribute("source"); //bind matrix XElement bind = skin.GetChild("bind_shape_matrix"); if (bind == null) skinInfo.BindMatrix = Matrix.Identity; else skinInfo.BindMatrix = MatrixFromString(bind.Value); //load joint and input XElement joints = skin.GetChild("joints"); var jointName = joints.GetChildren("input").Where(i => i.GetAttribute("semantic") == "JOINT").First(); skinInfo.JointNames = jointName.GetSource().Value.Replace('\n', ' ').Split(' ').Where(s => !string.IsNullOrWhiteSpace(s)).ToList(); var bindMatrix = joints.GetChildren("input").Where(i => i.GetAttribute("semantic") == "INV_BIND_MATRIX").First(); var values = GetFloatList(bindMatrix.GetSource().Value); for (int i = 0; i < values.Count; i += 16) { skinInfo.InverseBinding.Add(new Matrix(values.GetRange(i, 16).ToArray()).ToTranspose()); } //Weight XElement vertex_weights = skin.GetChild("vertex_weights"); var weights = GetFloatList(vertex_weights.GetChildren("input").Where(i => i.GetAttribute("semantic") == "WEIGHT").First().GetSource().Value); var v = GetIntList(vertex_weights.GetChild("v").Value); var vCount = GetIntList(vertex_weights.GetChild("vcount").Value); //Prepare vertex data int k = 0; List<Vector4> weightsTemp = new List<Vector4>(); List<Vector4> jointsTemp = new List<Vector4>(); foreach (int i in vCount) { Vector4 wei = new Vector4(); Vector4 joy = new Vector4(); for (int j = 0; j < i; j++) { switch (j) { case 0: joy.X = v[k]; k++; wei.X = weights[v[k]]; k++; break; case 1: joy.Y = v[k]; k++; wei.Y = weights[v[k]]; k++; break; case 2: joy.Z = v[k]; k++; wei.Z = weights[v[k]]; k++; break; case 3: joy.W = v[k]; k++; wei.W = weights[v[k]]; k++; break; default: break; } } float sum = wei.X + wei.Y + wei.Z + wei.W; wei *= 1.0F / sum; weightsTemp.Add(wei); jointsTemp.Add(joy); } return LoadGeometries(element.Document.GetByID(geometryUrl.Replace("#", "")), association, weightsTemp, jointsTemp); }
//Load Triangle Mesh private static void GetTriangleMesh(ModelGeometry model, XElement triangle, XElement mesh, SemanticAssociations association, List<Vector4> weights = null, List<Vector4> joints = null) { //Indices List<int> indices = GetIntList(triangle.GetNode("p").Value); //Load Channel var inputs = triangle.GetNodes("input"); List<ChannelData> inputData = new List<ChannelData>(); foreach (XElement elem in inputs) { inputData.Add(new ChannelData(elem)); } //Load Material model.Material = new MaterialData(); model.Material = GetMaterial(triangle.Document, triangle.GetAttribute("material")); //Create Vertices int k = 0; while (k < indices.Count) { VertexFormat v = new VertexFormat(); foreach (ChannelData e in inputData) { var data = e.GetChannel(indices[k]); switch (association[e.Semantic]) { case ChannelCode.Position: v.Position = new Vector3(data); //Add weights and joints if loaded for skinned model if (weights != null) { v.Weight = weights[indices[k]]; } if (joints != null) { v.Joint = joints[indices[k]]; } break; case ChannelCode.Normal: v.Normal = new Vector3(data); break; case ChannelCode.Tangent: v.Tangent = new Vector3(data); break; case ChannelCode.Binormal: v.Binormal = new Vector3(data); break; case ChannelCode.TexCoord1: if (data.Length >= 2) v.TextureSet1 = new Vector2(data.Take(2).ToArray()); break; case ChannelCode.TexCoord2: v.TextureSet2 = new Vector2(data.Take(2).ToArray()); break; case ChannelCode.Joint: v.Joint = new Vector4(data); break; case ChannelCode.Weight: v.Weight = new Vector4(data); break; case ChannelCode.None: break; default: break; } k++; } //Save to model model.Vertices.Add(v); model.Indices.Add(model.Indices.Count); } }
private static List <ModelGeometry> LoadController(XElement element, SemanticAssociations association, out SkinInformation skinInfo) { skinInfo = new SkinInformation(); XElement skin = element.GetReference().GetChild("skin"); if (skin == null) { //only skinned animation supported throw new NotSupportedException("Only Skin Animation supported"); } //target geometry string geometryUrl = skin.GetAttribute("source"); //bind matrix XElement bind = skin.GetChild("bind_shape_matrix"); if (bind == null) { skinInfo.BindMatrix = Matrix.Identity; } else { skinInfo.BindMatrix = MatrixFromString(bind.Value); } //load joint and input XElement joints = skin.GetChild("joints"); var jointName = joints.GetChildren("input").Where(i => i.GetAttribute("semantic") == "JOINT").First(); skinInfo.JointNames = jointName.GetSource().Value.Replace('\n', ' ').Split(' ').Where(s => !string.IsNullOrWhiteSpace(s)).ToList(); var bindMatrix = joints.GetChildren("input").Where(i => i.GetAttribute("semantic") == "INV_BIND_MATRIX").First(); var values = GetFloatList(bindMatrix.GetSource().Value); for (int i = 0; i < values.Count; i += 16) { skinInfo.InverseBinding.Add(new Matrix(values.GetRange(i, 16).ToArray()).ToTranspose()); } //Weight XElement vertex_weights = skin.GetChild("vertex_weights"); var weights = GetFloatList(vertex_weights.GetChildren("input").Where(i => i.GetAttribute("semantic") == "WEIGHT").First().GetSource().Value); var v = GetIntList(vertex_weights.GetChild("v").Value); var vCount = GetIntList(vertex_weights.GetChild("vcount").Value); //Prepare vertex data int k = 0; List <Vector4> weightsTemp = new List <Vector4>(); List <Vector4> jointsTemp = new List <Vector4>(); foreach (int i in vCount) { Vector4 wei = new Vector4(); Vector4 joy = new Vector4(); for (int j = 0; j < i; j++) { switch (j) { case 0: joy.X = v[k]; k++; wei.X = weights[v[k]]; k++; break; case 1: joy.Y = v[k]; k++; wei.Y = weights[v[k]]; k++; break; case 2: joy.Z = v[k]; k++; wei.Z = weights[v[k]]; k++; break; case 3: joy.W = v[k]; k++; wei.W = weights[v[k]]; k++; break; default: break; } } float sum = wei.X + wei.Y + wei.Z + wei.W; wei *= 1.0F / sum; weightsTemp.Add(wei); jointsTemp.Add(joy); } return(LoadGeometries(element.Document.GetByID(geometryUrl.Replace("#", "")), association, weightsTemp, jointsTemp)); }
//Load Triangle Mesh private static void GetTriangleMesh(ModelGeometry model, XElement triangle, XElement mesh, SemanticAssociations association, List <Vector4> weights = null, List <Vector4> joints = null) { //Indices List <int> indices = GetIntList(triangle.GetNode("p").Value); //Load Channel var inputs = triangle.GetNodes("input"); List <ChannelData> inputData = new List <ChannelData>(); foreach (XElement elem in inputs) { inputData.Add(new ChannelData(elem)); } //Load Material model.Material = new MaterialData(); model.Material = GetMaterial(triangle.Document, triangle.GetAttribute("material")); //Create Vertices int k = 0; while (k < indices.Count) { VertexFormat v = new VertexFormat(); foreach (ChannelData e in inputData) { var data = e.GetChannel(indices[k]); switch (association[e.Semantic]) { case ChannelCode.Position: v.Position = new Vector3(data); //Add weights and joints if loaded for skinned model if (weights != null) { v.Weight = weights[indices[k]]; } if (joints != null) { v.Joint = joints[indices[k]]; } break; case ChannelCode.Normal: v.Normal = new Vector3(data); break; case ChannelCode.Tangent: v.Tangent = new Vector3(data); break; case ChannelCode.Binormal: v.Binormal = new Vector3(data); break; case ChannelCode.TexCoord1: if (data.Length >= 2) { v.TextureSet1 = new Vector2(data.Take(2).ToArray()); } break; case ChannelCode.TexCoord2: v.TextureSet2 = new Vector2(data.Take(2).ToArray()); break; case ChannelCode.Joint: v.Joint = new Vector4(data); break; case ChannelCode.Weight: v.Weight = new Vector4(data); break; case ChannelCode.None: break; default: break; } k++; } //Save to model model.Vertices.Add(v); model.Indices.Add(model.Indices.Count); } }