/// <summary> /// Parses a vertex found in a polygon's vertex list. Parses texture and /// lightmap coordinates based on the polygon's material type. /// </summary> /// <param name="xmlNode">Xml Poly node</param> /// <param name="dxsPrim">Dxs Primitive this Poly belongs to</param> /// <param name="dxsPoly">Dxs Poly the vertex belongs to</param> private void ParseVertex(XmlNode xmlNode, DxsPrimitive dxsPrim, DxsPoly dxsPoly) { //Get the vertex ID so we can look up the position info int vid = int.Parse(xmlNode.Attributes["vid"].Value); //Copy the master vertex (position + vertex color) DxsVertex vertex = new DxsVertex(dxsPrim.MasterVertexList[vid]); //Get the material of the polygon DxsMaterial material = dxsPrim.Materials[dxsPoly.MaterialID]; //If the first layer is a texture, parse texture coordinates if (material.Layers.Count > 0 && material.Layers[0].MaterialType == MaterialType.Texture) { float u0 = float.Parse(xmlNode.Attributes["u0"].Value); float v0 = float.Parse(xmlNode.Attributes["v0"].Value); vertex.TextureCoordinate = new Vector2(u0, v0); } //If one of the layers (last one) is a lightmap, parse its texture coordinates for (int i = 1; i < material.Layers.Count; i++) { if (material.Layers[i].MaterialType == MaterialType.Lightmap) { float ui = float.Parse(xmlNode.Attributes["u" + i].Value); float vi = float.Parse(xmlNode.Attributes["v" + i].Value); vertex.LightMapCoordinate = new Vector2(ui, vi); break; } } //Add vertex to the poly dxsPoly.Vertices.Add(vertex); }
/// <summary> /// Parses a vertex listing in a primitive node, this pertains to the /// position data used by the primitive - hence it being the "master list". /// All other data such as texture coordinates are referenced by the vertex /// ID's to these vertices. /// /// Also, if a vertex color is supplied it will be caught here. By default /// vertex colors are white, and if a single vertex color is found the /// dxs primitive is enabled to use vertex colors. /// </summary> /// <param name="xmlNode">Xml primitive node</param> /// <param name="dxsPrim">Dxs primitive</param> private void ParseMasterVertex(XmlNode xmlNode, DxsPrimitive dxsPrim) { //Parse attributes int vid = int.Parse(xmlNode.Attributes["id"].Value); float x = float.Parse(xmlNode.Attributes["x"].Value); float y = float.Parse(xmlNode.Attributes["y"].Value); float z = float.Parse(xmlNode.Attributes["z"].Value); int jointID = -1;// int.Parse(xmlNode.Attributes["jointID"].Value); //create a new dxs vertex DxsVertex vertex = new DxsVertex(vid, new Vector3(x, y, z), jointID); //See if we have a vertex color if (xmlNode.HasChildNodes && xmlNode.LastChild.Name.Equals("color")) { XmlNode child = xmlNode.FirstChild; byte r = byte.Parse(child.Attributes["r"].Value); byte g = byte.Parse(child.Attributes["b"].Value); byte b = byte.Parse(child.Attributes["g"].Value); byte a = byte.Parse(child.Attributes["a"].Value); vertex.VertexColor = new Color(r, g, b, a); dxsPrim.VertexColorEnabled = true; } //Add master vertex to primitive dxsPrim.MasterVertexList.Add(vertex); }
/// <summary> /// Parses a polygon node, which is a vertex list. Each vertex's /// position is referenced by its vertex ID to the primitive's master list. /// Texture coordinates and lightmap coordinates are picked up here, /// as well as triangulation. Polys are added to a primitive grouped by /// their material ID so they can be split up later into multiple meshes. /// </summary> /// <param name="xmlNode">Xml Poly node</param> /// <param name="dxsPrim">Dxs Primitive this polygon belongs to</param> private void ParsePolygon(XmlNode xmlNode, DxsPrimitive dxsPrim) { //Parse attributes int mid = int.Parse(xmlNode.Attributes["mid"].Value); int count = xmlNode.ChildNodes.Count; DxsPoly poly = new DxsPoly(mid); //Add the material to the primitive - if its a newly encountered material if (materialList.ContainsKey(mid)) { dxsPrim.AddMaterial(materialList[mid]); } //Now go through each vertex and parse it for (int i = count - 1; i >= 0; i--) { // for(int i = 0; i < count; i++) { XmlNode vertex = xmlNode.ChildNodes[i]; ParseVertex(vertex, dxsPrim, poly); } //Either triangulate the polygon, or simply add it if its already a triangle if (count > 3) { TriangulatePolygon(dxsPrim, poly); } else { poly.ComputeFaceNormal(); dxsPrim.AddPoly(poly); } }
/// <summary> /// Parse a xml primitive node. Result is attached to the specified /// Dxs node. /// </summary> /// <param name="xmlNode">Xml Primitive Node</param> /// <param name="dxsNode">Parent Dxs Node</param> private void ParsePrimitive(XmlNode xmlNode, DxsNode dxsNode) { //Process attributes String name = xmlNode.Attributes["name"].Value; int groupID = -1; // int.Parse(xmlNode.Attributes["groupID"].Value); int skeletonID = -1; // int.Parse(xmlNode.Attributes["skeletonID"].Value); //Create a new DXS primitive DxsPrimitive prim = new DxsPrimitive(name, groupID, skeletonID); //Go through its children - first process the master vertex list, //then the polygon list foreach (XmlNode node in xmlNode.ChildNodes) { switch (node.Name) { case "vertices": for (int i = 0; i < node.ChildNodes.Count; i++) { ParseMasterVertex(node.ChildNodes[i], prim); } break; case "polygons": for (int i = 0; i < node.ChildNodes.Count; i++) { ParsePolygon(node.ChildNodes[i], prim); } break; } } dxsNode.AddChild(prim); }
/// <summary> /// Uses the first vertex in a polygon as a pivot to triangulate the polygon, /// which get added to the dxs primitive. /// </summary> /// <param name="dxsPrim">Dxs Primitive the poly belongs to</param> /// <param name="dxsPoly">Dxs Poly to be triangulated</param> private void TriangulatePolygon(DxsPrimitive dxsPrim, DxsPoly dxsPoly) { DxsVertex[] vertices = dxsPoly.Vertices.ToArray(); DxsVertex v0 = vertices[0]; //Use the first vertex as a pivot and create triangles. for (int v = 1; v < vertices.Length - 1; v++) { DxsPoly poly = new DxsPoly(dxsPoly.MaterialID); poly.Vertices.Add(v0); poly.Vertices.Add(vertices[v]); poly.Vertices.Add(vertices[v + 1]); poly.ComputeFaceNormal(); dxsPrim.AddPoly(poly); } }