/// <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); }
private void CalculateNormals(List <DxsPoly> polyList, NormalGeneration normalOptions, double creaseAngle) { if (normalOptions == NormalGeneration.None) { return; } double cosAngle = System.Math.Cos(MathHelper.DegreesToRadians * creaseAngle); //Loop through each polygon for (int i = 0; i < polyList.Count; i++) { DxsPoly poly = polyList[i]; //For each vertex for (int j = 0; j < 3; j++) { DxsVertex vert = poly.Vertices[j]; int vid = vert.ID; Vector3 smoothNormal = poly.FaceNormal; if (normalOptions != NormalGeneration.Face) { //Find every poly that shares this vertex for (int k = 0; k < polyList.Count; k++) { if (i != k) { DxsPoly otherPoly = polyList[k]; for (int m = 0; m < 3; m++) { DxsVertex otherVertex = otherPoly.Vertices[m]; int otherVid = otherVertex.ID; //Other poly uses this vertex position, then take their normal into account if (vid == otherVid) { if (normalOptions == NormalGeneration.Crease) { if (Vector3.Dot(poly.FaceNormal, otherPoly.FaceNormal) > cosAngle) { smoothNormal += otherPoly.FaceNormal; } } else { smoothNormal += otherPoly.FaceNormal; } } } } } } smoothNormal.Normalize(); vert.Normal = smoothNormal; poly.Vertices[j] = vert; } } }
public DxsVertex(DxsVertex vertex) { ID = vertex.ID; Position = vertex.Position; Normal = vertex.Normal; TextureCoordinate = vertex.TextureCoordinate; LightMapCoordinate = vertex.LightMapCoordinate; VertexColor = vertex.VertexColor; JointID = vertex.JointID; }
private bool VertexEquals(ref DxsVertex a, ref DxsVertex b) { Vector2 aTex = a.TextureCoordinate; Vector2 bTex = b.TextureCoordinate; Vector2 aLight = a.LightMapCoordinate; Vector2 bLight = b.LightMapCoordinate; Vector3 aNormal = a.Normal; Vector3 bNormal = b.Normal; return(Vector2Equals(ref aTex, ref bTex) && Vector2Equals(ref aLight, ref bLight) && Vector3Equals(ref aNormal, ref bNormal)); }
/// <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); } }
public DxsMesh(List <DxsPoly> polyList, NormalGeneration normalOptions, double creaseAngle, bool swapWinding) { _matID = polyList[0].MaterialID; _indices = new DataBuffer <int>(polyList.Count * 3); _vertList = new List <DxsVertex>(); if (swapWinding) { foreach (DxsPoly poly in polyList) { DxsVertex temp = poly.Vertices[0]; poly.Vertices[0] = poly.Vertices[2]; poly.Vertices[2] = temp; } } CalculateNormals(polyList, normalOptions, creaseAngle); //Get all the unique vertices and build the index list foreach (DxsPoly poly in polyList) { for (int i = 0; i < 3; i++) { DxsVertex vertex = poly.Vertices[i]; int index; if (IsUniqueVertex(_vertList, vertex, out index)) { _vertList.Add(vertex); index = _vertList.Count - 1; } _indices.Set(index); } } Vector3 center = GetCenter(); for (int i = 0; i < _vertList.Count; i++) { DxsVertex v = _vertList[i]; v.Position = v.Position - center; _vertList[i] = v; } _translation = center; }
private bool IsUniqueVertex(List <DxsVertex> list, DxsVertex vertex, out int index) { bool isUnique = true; index = -1; for (int i = 0; i < list.Count; i++) { DxsVertex test = list[i]; if (test.ID == vertex.ID) { if (VertexEquals(ref vertex, ref test)) { isUnique = false; index = i; break; } } } return(isUnique); }