/// <summary> /// This will find if the vertex is already contained and return its index, otherwise it adds it as new /// </summary> public OBJFaceVertex AddOrGet(Vertex vertex) { OBJFaceVertex face = new OBJFaceVertex(); // Position for (int i = 0; i < positions.Count; i++) { if (positions[i] == vertex.Position) { face.PositionIndex = i + 1; } } if (face.PositionIndex == 0) { positions.Add(vertex.Position); face.PositionIndex = positions.Count; } // UV for (int i = 0; i < uvs.Count; i++) { if (uvs[i] == vertex.UV) { face.UVIndex = i + 1; } } if (face.UVIndex == 0) { uvs.Add(vertex.UV); face.UVIndex = uvs.Count; } // Normal for (int i = 0; i < normals.Count; i++) { if (normals[i] == vertex.Normal) { face.NormalIndex = i + 1; } } if (face.NormalIndex == 0) { normals.Add(vertex.Normal); face.NormalIndex = normals.Count; } return(face); }
/// <summary> /// This will find if the vertex is already contained and return its index, otherwise it adds it as new /// </summary> public OBJFaceVertex AddOrGet(Vertex vertex) { OBJFaceVertex face = new OBJFaceVertex(); // Position for (int i = 0; i < positions.Count; i++) { if (positions[i] == vertex.Position) { face.PositionIndex = i+1; } } if(face.PositionIndex == 0) { positions.Add(vertex.Position); face.PositionIndex = positions.Count; } // UV for (int i = 0; i < uvs.Count; i++) { if (uvs[i] == vertex.UV) { face.UVIndex = i+1; } } if(face.UVIndex == 0) { uvs.Add(vertex.UV); face.UVIndex = uvs.Count; } // Normal for (int i = 0; i < normals.Count; i++) { if (normals[i] == vertex.Normal) { face.NormalIndex = i+1; } } if(face.NormalIndex == 0) { normals.Add(vertex.Normal); face.NormalIndex = normals.Count; } return face; }
public static string ExportToString(Transform transform, List <Polygon> polygons, Material defaultMaterial) { // If a transform is provided, convert the world positions and normals to local to the transform if (transform != null) { for (int polygonIndex = 0; polygonIndex < polygons.Count; polygonIndex++) { Polygon polygon = polygons[polygonIndex]; for (int vertexIndex = 0; vertexIndex < polygon.Vertices.Length; vertexIndex++) { Vertex vertex = polygon.Vertices[vertexIndex]; vertex.Position = transform.InverseTransformPoint(vertex.Position); vertex.Normal = transform.InverseTransformDirection(vertex.Normal); } } } // Create polygon subsets for each material Dictionary <Material, List <Polygon> > polygonMaterialTable = new Dictionary <Material, List <Polygon> >(); // Iterate through every polygon adding it to the appropiate material list foreach (Polygon polygon in polygons) { if (polygon.UserExcludeFromFinal) { continue; } Material material = polygon.Material; if (material == null) { material = defaultMaterial; } if (!polygonMaterialTable.ContainsKey(material)) { polygonMaterialTable.Add(material, new List <Polygon>()); } polygonMaterialTable[material].Add(polygon); } // Use a string builder as this should allow faster concatenation StringBuilder stringBuilder = new StringBuilder(); OBJVertexList vertexList = new OBJVertexList(); int positionIndexOffset = 0; int uvIndexOffset = 0; int normalIndexOffset = 0; int meshIndex = 1; // Create a separate mesh for polygons of each material so that we batch by material foreach (KeyValuePair <Material, List <Polygon> > polygonMaterialGroup in polygonMaterialTable) { List <List <OBJFaceVertex> > faces = new List <List <OBJFaceVertex> >(polygonMaterialGroup.Value.Count); // Iterate through every polygon and triangulate foreach (Polygon polygon in polygonMaterialGroup.Value) { List <OBJFaceVertex> faceVertices = new List <OBJFaceVertex>(polygon.Vertices.Length); for (int i = 0; i < polygon.Vertices.Length; i++) { OBJFaceVertex faceVertex = vertexList.AddOrGet(polygon.Vertices[i]); faceVertices.Add(faceVertex); } faces.Add(faceVertices); } List <Vector3> positions = vertexList.Positions; List <Vector2> uvs = vertexList.UVs; List <Vector3> normals = vertexList.Normals; // Start a new group for the mesh stringBuilder.AppendLine("g Mesh" + meshIndex); // Write all the positions stringBuilder.AppendLine("# Vertex Positions: " + (positions.Count - positionIndexOffset)); for (int i = positionIndexOffset; i < positions.Count; i++) { stringBuilder.AppendLine("v " + WriteVector3(positions[i])); } // Write all the texture coordinates (UVs) stringBuilder.AppendLine("# Vertex UVs: " + (uvs.Count - uvIndexOffset)); for (int i = uvIndexOffset; i < uvs.Count; i++) { stringBuilder.AppendLine("vt " + WriteVector2(uvs[i])); } // Write all the normals stringBuilder.AppendLine("# Vertex Normals: " + (normals.Count - normalIndexOffset)); for (int i = normalIndexOffset; i < normals.Count; i++) { stringBuilder.AppendLine("vn " + WriteVector3(normals[i])); } // Write all the faces stringBuilder.AppendLine("# Faces: " + faces.Count); for (int i = 0; i < faces.Count; i++) { stringBuilder.Append("f "); for (int j = faces[i].Count - 1; j >= 0; j--) { stringBuilder.Append((faces[i][j].PositionIndex) + "/" + (faces[i][j].UVIndex) + "/" + (faces[i][j].NormalIndex) + " "); } stringBuilder.AppendLine(); } // Add some padding between this and the next mesh stringBuilder.AppendLine(); stringBuilder.AppendLine(); meshIndex++; // Update the offsets so that the next pass only writes new vertex information positionIndexOffset = positions.Count; uvIndexOffset = uvs.Count; normalIndexOffset = normals.Count; } return(stringBuilder.ToString()); }