/// <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 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); } }
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 void AddPoly(DxsPoly poly) { if (!_polys.ContainsKey(poly.MaterialID)) { List <DxsPoly> list = new List <DxsPoly>(); list.Add(poly); _polys.Add(poly.MaterialID, list); } else { _polys[poly.MaterialID].Add(poly); } }
/// <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); } }