public GeoMeshCacheEntry ImportMesh(string filename, Vtf vtf, int textureGroup) { if (MeshCache.TryGetValue(filename, out GeoMeshCacheEntry cacheEntry)) { return(cacheEntry); } GeoMesh geoMesh = GeoParser.ReadGeoMesh(filename); Mesh mesh = new Mesh(); List <Vector3> vertices = new List <Vector3>(); List <Vector2> uvs = new List <Vector2>(); List <Vector3> normals = new List <Vector3>(); Dictionary <Material, List <GeoFace> > facesGroupedByMaterial = new Dictionary <Material, List <GeoFace> >(); GeoFace[] faces = geoMesh.Faces; for (int i = 0; i < faces.Length; ++i) { Material material = GetMaterial(faces[i], vtf, textureGroup); if (facesGroupedByMaterial.TryGetValue(material, out List <GeoFace> faceGroup)) { faceGroup.Add(faces[i]); } else { facesGroupedByMaterial.Add(material, new List <GeoFace> { faces[i] }); } } mesh.subMeshCount = facesGroupedByMaterial.Count; Dictionary <Material, List <int> > submeshTriangles = new Dictionary <Material, List <int> >(); foreach (KeyValuePair <Material, List <GeoFace> > faceGroup in facesGroupedByMaterial) { submeshTriangles[faceGroup.Key] = new List <int>(); List <GeoFace> faceGroupValues = faceGroup.Value; foreach (GeoFace face in faceGroupValues) { int numTriangles = face.VertexRefs.Length - 3 + 1; int viStart = vertices.Count; foreach (GeoVertexRef vertexRef in face.VertexRefs) { vertices.Add(geoMesh.Vertices[vertexRef.VertexIndex]); normals.Add(geoMesh.Normals[vertexRef.VertexIndex] * -1); uvs.Add(vertexRef.Uv); } for (int t = 1; t <= numTriangles; t++) { submeshTriangles[faceGroup.Key].Add(viStart + t); submeshTriangles[faceGroup.Key].Add(viStart); submeshTriangles[faceGroup.Key].Add(viStart + t + 1); } } } mesh.SetVertices(vertices); mesh.SetUVs(0, uvs); mesh.SetNormals(normals); int subMeshIndex = 0; foreach (KeyValuePair <Material, List <int> > submeshTriangle in submeshTriangles) { mesh.SetTriangles(submeshTriangles[submeshTriangle.Key], subMeshIndex++); } mesh.RecalculateBounds(); cacheEntry = new GeoMeshCacheEntry { GeoMesh = geoMesh, Mesh = mesh, Materials = facesGroupedByMaterial.Select(x => x.Key).ToArray() }; MeshCache.Add(filename, cacheEntry); return(cacheEntry); }
public GameObject ImportGeo(string filename, Vtf vtf, GameObject prefab) { var geoMesh = GeoParser.ReadGeoMesh(filename); var mesh = new Mesh(); var vertices = new List <Vector3>(); var uvs = new List <Vector2>(); var normals = new List <Vector3>(); var facesGroupedByMaterial = geoMesh.Faces.GroupBy(face => GetMaterial(face, vtf)).ToArray(); mesh.subMeshCount = facesGroupedByMaterial.Length; var submeshTriangles = new Dictionary <Material, List <int> >(); foreach (var faceGroup in facesGroupedByMaterial) { submeshTriangles[faceGroup.Key] = new List <int>(); foreach (var face in faceGroup) { var numTriangles = face.VertexRefs.Length - 3 + 1; var viStart = vertices.Count; foreach (var vertexRef in face.VertexRefs) { vertices.Add(geoMesh.Vertices[vertexRef.VertexIndex]); normals.Add(geoMesh.Normals[vertexRef.VertexIndex] * -1); uvs.Add(vertexRef.Uv); } for (var t = 1; t <= numTriangles; t++) { submeshTriangles[faceGroup.Key].Add(viStart + t); submeshTriangles[faceGroup.Key].Add(viStart); submeshTriangles[faceGroup.Key].Add(viStart + t + 1); } } } mesh.vertices = vertices.ToArray(); mesh.uv = uvs.ToArray(); mesh.normals = normals.ToArray(); var i = 0; foreach (var submeshTriangle in submeshTriangles) { mesh.SetTriangles(submeshTriangles[submeshTriangle.Key].ToArray(), i); i++; } var obj = Instantiate(prefab); obj.gameObject.name = geoMesh.Name; obj.GetComponent <MeshFilter>().sharedMesh = mesh; obj.GetComponent <MeshRenderer>().materials = facesGroupedByMaterial.Select(x => x.Key).ToArray(); var collider = obj.GetComponent <MeshCollider>(); if (collider != null) { collider.sharedMesh = mesh; } return(obj.gameObject); }