public void optimizeVertexCount() { return; if (areVerticesOptimized) { return; } List <Vector3> tmpList = new List <Vector3>(); for (int j = 0; j < Faces.Count; j++) { OBJFace c = Faces[j]; int count = c.VertexIndieces.Count; for (int i = 0; i < count; i++) { int index = tmpList.FindIndex(v => v == Vertices[c.VertexIndieces[i]]); if (index == -1) { tmpList.Add(Vertices[c.VertexIndieces[i]]); c.VertexIndieces[i] = tmpList.Count - 1; } else { c.VertexIndieces[i] = index; } } } Vertices = tmpList; areVerticesOptimized = true; }
//------------------------------------------------------------------------------------------------------------ public static OBJData EncodeOBJ(this Mesh lMesh) { OBJData lData = new OBJData { m_Vertices = new List <Vector3>(lMesh.vertices), m_UVs = new List <Vector2>(lMesh.uv), m_Normals = new List <Vector3>(lMesh.normals), m_UV2s = new List <Vector2>(lMesh.uv2), m_Colors = new List <Color>(lMesh.colors) }; int[] lIndices = null; OBJGroup lGroup = null; OBJFace lFace = null; OBJFaceVertex lFaceVertex = null; for (int lMCount = 0; lMCount < lMesh.subMeshCount; ++lMCount) { lIndices = lMesh.GetTriangles(lMCount); lGroup = new OBJGroup(lMesh.name + "_" + lMCount.ToString()); for (int lCount = 0; lCount < lIndices.Length; lCount += 3) { lFace = new OBJFace(); lFaceVertex = new OBJFaceVertex(); lFaceVertex.m_VertexIndex = lData.m_Vertices.Count > 0 ? lIndices[lCount] : -1; lFaceVertex.m_UVIndex = lData.m_UVs.Count > 0 ? lIndices[lCount] : -1; lFaceVertex.m_NormalIndex = lData.m_Normals.Count > 0 ? lIndices[lCount] : -1; lFaceVertex.m_UV2Index = lData.m_UV2s.Count > 0 ? lIndices[lCount] : -1; lFaceVertex.m_ColorIndex = lData.m_Colors.Count > 0 ? lIndices[lCount] : -1; lFace.AddVertex(lFaceVertex); lFaceVertex = new OBJFaceVertex(); lFaceVertex.m_VertexIndex = lData.m_Vertices.Count > 0 ? lIndices[lCount + 1] : -1; lFaceVertex.m_UVIndex = lData.m_UVs.Count > 0 ? lIndices[lCount + 1] : -1; lFaceVertex.m_NormalIndex = lData.m_Normals.Count > 0 ? lIndices[lCount + 1] : -1; lFaceVertex.m_UV2Index = lData.m_UV2s.Count > 0 ? lIndices[lCount + 1] : -1; lFaceVertex.m_ColorIndex = lData.m_Colors.Count > 0 ? lIndices[lCount + 1] : -1; lFace.AddVertex(lFaceVertex); lFaceVertex = new OBJFaceVertex(); lFaceVertex.m_VertexIndex = lData.m_Vertices.Count > 0 ? lIndices[lCount + 2] : -1; lFaceVertex.m_UVIndex = lData.m_UVs.Count > 0 ? lIndices[lCount + 2] : -1; lFaceVertex.m_NormalIndex = lData.m_Normals.Count > 0 ? lIndices[lCount + 2] : -1; lFaceVertex.m_UV2Index = lData.m_UV2s.Count > 0 ? lIndices[lCount + 2] : -1; lFaceVertex.m_ColorIndex = lData.m_Colors.Count > 0 ? lIndices[lCount + 2] : -1; lFace.AddVertex(lFaceVertex); lGroup.AddFace(lFace); } lData.m_Groups.Add(lGroup); } return(lData); }
//------------------------------------------------------------------------------------------------------------ private static void PushOBJFace(string lFaceLine) { PushOBJGroupIfNeeded(); var vertices = lFaceLine.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); var face = new OBJFace(); foreach (var vertexString in vertices) { face.ParseVertex(vertexString); } m_CurrentGroup.AddFace(face); }
public static OBJFace readFace(string faceLine) { char[] split = { '/' }; string[] faceStrings = faceLine.Split(split); OBJFace face = new OBJFace(); if (faceStrings.Length == 3) // #/#/# { face.positionIndex = Convert.ToUInt32(faceStrings[0].Trim()); face.texCoordIndex = Convert.ToUInt32(faceStrings[1].Trim()); face.normalIndex = Convert.ToUInt32(faceStrings[2].Trim()); } return(face); }
public void Triangulate() { List< OBJFace > triangulatedFaces = new List< OBJFace >( faces.Count ); foreach( OBJFace face in faces ) { int nVertices = face.NumVertices; int v0 = face.PositionIndices[ 0 ]; for( int v = 1; v < nVertices - 1; ++v ) { int v1 = face.PositionIndices[ v ]; int v2 = face.PositionIndices[ v + 1 ]; OBJFace triangle = new OBJFace( face.HasTextureCoordinates, face.HasNormals ); triangle.PositionIndices.Add( v0 ); triangle.PositionIndices.Add( v1 ); triangle.PositionIndices.Add( v2 ); if( face.HasTextureCoordinates ) { triangle.TextureCoordinateIndices.Add( face.TextureCoordinateIndices[ 0 ] ); triangle.TextureCoordinateIndices.Add( face.TextureCoordinateIndices[ v ] ); triangle.TextureCoordinateIndices.Add( face.TextureCoordinateIndices[ v + 1 ] ); } if( face.HasNormals ) { triangle.NormalIndices.Add( face.NormalIndices[ 0 ] ); triangle.NormalIndices.Add( face.NormalIndices[ v ] ); triangle.NormalIndices.Add( face.NormalIndices[ v + 1 ] ); } triangulatedFaces.Add( triangle ); } } faces = triangulatedFaces; }
//------------------------------------------------------------------------------------------------------------ public static void LoadOBJ(this Mesh lMesh, OBJData lData) { List <Vector3> lVertices = new List <Vector3>(); List <Vector3> lNormals = new List <Vector3>(); List <Vector2> lUVs = new List <Vector2>(); List <int>[] lIndices = new List <int> [lData.m_Groups.Count]; Dictionary <OBJFaceVertex, int> lVertexIndexRemap = new Dictionary <OBJFaceVertex, int>(); bool lHasNormals = lData.m_Normals.Count > 0; bool lHasUVs = lData.m_UVs.Count > 0; lMesh.subMeshCount = lData.m_Groups.Count; for (int lGCount = 0; lGCount < lData.m_Groups.Count; ++lGCount) { OBJGroup lGroup = lData.m_Groups[lGCount]; lIndices[lGCount] = new List <int>(); for (int lFCount = 0; lFCount < lGroup.Faces.Count; ++lFCount) { OBJFace lFace = lGroup.Faces[lFCount]; // Unity3d doesn't support non-triangle faces // so we do simple fan triangulation for (int lVCount = 1; lVCount < lFace.Count - 1; ++lVCount) { foreach (int i in new int[] { 0, lVCount, lVCount + 1 }) { OBJFaceVertex lFaceVertex = lFace[i]; int lVertexIndex = -1; if (!lVertexIndexRemap.TryGetValue(lFaceVertex, out lVertexIndex)) { lVertexIndexRemap[lFaceVertex] = lVertices.Count; lVertexIndex = lVertices.Count; lVertices.Add(lData.m_Vertices[lFaceVertex.m_VertexIndex]); if (lHasUVs) { lUVs.Add(lData.m_UVs[lFaceVertex.m_UVIndex]); } if (lHasNormals) { lNormals.Add(lData.m_Normals[lFaceVertex.m_NormalIndex]); } } lIndices[lGCount].Add(lVertexIndex); } } } } lMesh.triangles = new int[] { }; lMesh.vertices = lVertices.ToArray(); lMesh.uv = lUVs.ToArray(); lMesh.normals = lNormals.ToArray(); if (!lHasNormals) { lMesh.RecalculateNormals(); } lMesh.RecalculateTangents(); for (int lGCount = 0; lGCount < lData.m_Groups.Count; ++lGCount) { lMesh.SetTriangles(lIndices[lGCount].ToArray(), lGCount); } }
//------------------------------------------------------------------------------------------------------------ public static OBJData EncodeOBJ(this Mesh lMesh) { OBJData lData = new OBJData { m_Vertices = new List<Vector3>(lMesh.vertices), m_UVs = new List<Vector2>(lMesh.uv), m_Normals = new List<Vector3>(lMesh.normals), m_UV2s = new List<Vector2>(lMesh.uv1), m_Colors = new List<Color>(lMesh.colors) }; int[] lIndices = null; OBJGroup lGroup = null; OBJFace lFace = null; OBJFaceVertex lFaceVertex = null; for (int lMCount = 0; lMCount < lMesh.subMeshCount; ++lMCount) { lIndices = lMesh.GetTriangles(lMCount); lGroup = new OBJGroup(lMesh.name + "_" + lMCount.ToString()); for (int lCount = 0; lCount < lIndices.Length; lCount += 3) { lFace = new OBJFace(); lFaceVertex = new OBJFaceVertex(); lFaceVertex.m_VertexIndex = lData.m_Vertices.Count > 0 ? lIndices[lCount] : -1; lFaceVertex.m_UVIndex = lData.m_UVs.Count > 0 ? lIndices[lCount] : -1; lFaceVertex.m_NormalIndex = lData.m_Normals.Count > 0 ? lIndices[lCount] : -1; lFaceVertex.m_UV2Index = lData.m_UV2s.Count > 0 ? lIndices[lCount] : -1; lFaceVertex.m_ColorIndex = lData.m_Colors.Count > 0 ? lIndices[lCount] : -1; lFace.AddVertex(lFaceVertex); lFaceVertex = new OBJFaceVertex(); lFaceVertex.m_VertexIndex = lData.m_Vertices.Count > 0 ? lIndices[lCount + 1] : -1; lFaceVertex.m_UVIndex = lData.m_UVs.Count > 0 ? lIndices[lCount + 1] : -1; lFaceVertex.m_NormalIndex = lData.m_Normals.Count > 0 ? lIndices[lCount + 1] : -1; lFaceVertex.m_UV2Index = lData.m_UV2s.Count > 0 ? lIndices[lCount + 1] : -1; lFaceVertex.m_ColorIndex = lData.m_Colors.Count > 0 ? lIndices[lCount + 1] : -1; lFace.AddVertex(lFaceVertex); lFaceVertex = new OBJFaceVertex(); lFaceVertex.m_VertexIndex = lData.m_Vertices.Count > 0 ? lIndices[lCount + 2] : -1; lFaceVertex.m_UVIndex = lData.m_UVs.Count > 0 ? lIndices[lCount + 2] : -1; lFaceVertex.m_NormalIndex = lData.m_Normals.Count > 0 ? lIndices[lCount + 2] : -1; lFaceVertex.m_UV2Index = lData.m_UV2s.Count > 0 ? lIndices[lCount + 2] : -1; lFaceVertex.m_ColorIndex = lData.m_Colors.Count > 0 ? lIndices[lCount + 2] : -1; lFace.AddVertex(lFaceVertex); lGroup.AddFace(lFace); } lData.m_Groups.Add(lGroup); } return lData; }
public OBJFinder(OBJFace target) { targetFace = target; }
public void Parse(TextReader reader) { // For each line: string line; var whitespace = new char[] { ' ', '\t' }; var slash = new char[] { '/' }; OBJGroup currentGroup = null; while ((line = reader.ReadLine()) != null) { // Strip comment var commentIdx = line.IndexOf('#'); if (commentIdx >= 0) { line = line.Substring(0, commentIdx); } // Segment var parts = line.Split(whitespace, StringSplitOptions.RemoveEmptyEntries); if (parts.Length == 0) { continue; } // Parse var type = parts[0].ToLowerInvariant(); switch (type) { case "mtllib": { var path = parts[1]; MTLLib = path; break; } case "o": case "g": { var name = parts[1]; currentGroup = new OBJGroup(name); Groups.Add(currentGroup); break; } case "v": { var x = float.Parse(parts[1], CultureInfo.InvariantCulture); var y = float.Parse(parts[2], CultureInfo.InvariantCulture); var z = float.Parse(parts[3], CultureInfo.InvariantCulture); Positions.Add(new Vector3(x, y, z)); if (parts.Length > 4) { var r = float.Parse(parts[4], CultureInfo.InvariantCulture); var g = float.Parse(parts[5], CultureInfo.InvariantCulture); var b = float.Parse(parts[6], CultureInfo.InvariantCulture); var a = (parts.Length > 7) ? float.Parse(parts[7], CultureInfo.InvariantCulture) : 1.0f; Colours.Add(new Vector4(r, g, b, a)); } else { Colours.Add(Vector4.One); } break; } case "vt": { var x = float.Parse(parts[1], CultureInfo.InvariantCulture); var y = float.Parse(parts[2], CultureInfo.InvariantCulture); TexCoords.Add(new Vector2(x, y)); break; } case "vn": { var x = float.Parse(parts[1], CultureInfo.InvariantCulture); var y = float.Parse(parts[2], CultureInfo.InvariantCulture); var z = float.Parse(parts[3], CultureInfo.InvariantCulture); Normals.Add(new Vector3(x, y, z)); break; } case "usemtl": { var name = parts[1]; currentGroup.MaterialName = name; break; } case "f": { var face = new OBJFace(); face.FirstVertex = Verts.Count; for (int i = 1; i < parts.Length; ++i) { var part = parts[i]; var subParts = part.Split(slash, StringSplitOptions.None); var vert = new OBJVert(); if (subParts.Length > 0) { int posIndex; if (int.TryParse(subParts[0], NumberStyles.Integer, CultureInfo.InvariantCulture, out posIndex)) { vert.PositionIndex = posIndex; } } if (subParts.Length > 1) { int texCoordIndex; if (int.TryParse(subParts[1], NumberStyles.Integer, CultureInfo.InvariantCulture, out texCoordIndex)) { vert.TexCoordIndex = texCoordIndex; } } if (subParts.Length > 2) { int normalIndex; if (int.TryParse(subParts[2], NumberStyles.Integer, CultureInfo.InvariantCulture, out normalIndex)) { vert.NormalIndex = normalIndex; } } Verts.Add(vert); face.VertexCount++; } currentGroup.Faces.Add(face); break; } } } }
public static GameObject LoadOBJFile(string filePath, bool inputIsRawOBJ = false) { string meshName = !inputIsRawOBJ?Path.GetFileNameWithoutExtension(filePath) : "LoadedOBJMesh"; bool hasNormals = false; //OBJ LISTS List <Vector3> vertices = new List <Vector3>(); List <Vector3> normals = new List <Vector3>(); List <Vector2> uvs = new List <Vector2>(); //UMESH LISTS List <Vector3> uvertices = new List <Vector3>(); List <Vector3> unormals = new List <Vector3>(); List <Vector2> uuvs = new List <Vector2>(); //MESH CONSTRUCTION List <string> materialNames = new List <string>(); List <string> objectNames = new List <string>(); Dictionary <string, int> hashtable = new Dictionary <string, int>(); List <OBJFace> faceList = new List <OBJFace>(); string cmaterial = ""; string cmesh = "default"; //CACHE Material[] materialCache = null; //save this info for later FileInfo OBJFileInfo = null; string[] OBJLines; if (!inputIsRawOBJ) { OBJFileInfo = new FileInfo(filePath); OBJLines = File.ReadAllLines(filePath); } else { OBJLines = filePath.Split(new[] { "\r", "\n" }, StringSplitOptions.None); } foreach (string ln in OBJLines) { if (ln.Length > 0 && ln[0] != '#') { string l = ln.Trim().Replace(" ", " "); string[] cmps = l.Split(' '); string data = l.Remove(0, l.IndexOf(' ') + 1); if (cmps[0] == "mtllib" && !inputIsRawOBJ && OBJFileInfo != null) { //load cache string pth = OBJGetFilePath(data, OBJFileInfo.Directory.FullName + Path.DirectorySeparatorChar, meshName); if (pth != null) { materialCache = LoadMTLFile(pth); } } else if ((cmps[0] == "g" || cmps[0] == "o") && splitByMaterial == false) { cmesh = data; if (!objectNames.Contains(cmesh)) { objectNames.Add(cmesh); } } else if (cmps[0] == "usemtl") { cmaterial = data; if (!materialNames.Contains(cmaterial)) { materialNames.Add(cmaterial); } if (splitByMaterial) { if (!objectNames.Contains(cmaterial)) { objectNames.Add(cmaterial); } } } else if (cmps[0] == "v") { //VERTEX vertices.Add(ParseVectorFromCMPS(cmps)); } else if (cmps[0] == "vn") { //VERTEX NORMAL normals.Add(ParseVectorFromCMPS(cmps)); } else if (cmps[0] == "vt") { //VERTEX UV uvs.Add(ParseVectorFromCMPS(cmps)); } else if (cmps[0] == "f") { int[] indexes = new int[cmps.Length - 1]; for (int i = 1; i < cmps.Length; i++) { string felement = cmps[i]; int vertexIndex = -1; int normalIndex = -1; int uvIndex = -1; if (felement.Contains("//")) { //doubleslash, no UVS. string[] elementComps = felement.Split('/'); vertexIndex = int.Parse(elementComps[0]) - 1; normalIndex = int.Parse(elementComps[2]) - 1; } else if (felement.Count(x => x == '/') == 2) { //contains everything string[] elementComps = felement.Split('/'); vertexIndex = int.Parse(elementComps[0]) - 1; uvIndex = int.Parse(elementComps[1]) - 1; normalIndex = int.Parse(elementComps[2]) - 1; } else if (!felement.Contains("/")) { //just vertex inedx vertexIndex = int.Parse(felement) - 1; } else { //vertex and uv string[] elementComps = felement.Split('/'); vertexIndex = int.Parse(elementComps[0]) - 1; uvIndex = int.Parse(elementComps[1]) - 1; } string hashEntry = vertexIndex + "|" + normalIndex + "|" + uvIndex; if (hashtable.ContainsKey(hashEntry)) { indexes[i - 1] = hashtable[hashEntry]; } else { //create a new hash entry indexes[i - 1] = hashtable.Count; hashtable[hashEntry] = hashtable.Count; uvertices.Add(vertices[vertexIndex]); if (normalIndex < 0 || (normalIndex > (normals.Count - 1))) { unormals.Add(Vector3.zero); } else { hasNormals = true; unormals.Add(normals[normalIndex]); } if (uvIndex < 0 || (uvIndex > (uvs.Count - 1))) { uuvs.Add(Vector2.zero); } else { uuvs.Add(uvs[uvIndex]); } } } if (indexes.Length < 5 && indexes.Length >= 3) { OBJFace f1 = new OBJFace(); f1.materialName = cmaterial; f1.indexes = new int[] { indexes[0], indexes[1], indexes[2] }; f1.meshName = (splitByMaterial) ? cmaterial : cmesh; faceList.Add(f1); if (indexes.Length > 3) { OBJFace f2 = new OBJFace(); f2.materialName = cmaterial; f2.meshName = (splitByMaterial) ? cmaterial : cmesh; f2.indexes = new int[] { indexes[2], indexes[3], indexes[0] }; faceList.Add(f2); } } } } } if (objectNames.Count == 0) { objectNames.Add("default"); } //build objects GameObject parentObject = new GameObject(meshName); for (int objectNamesIndex = 0; objectNamesIndex < objectNames.Count; objectNamesIndex++) { string obj = objectNames[objectNamesIndex]; GameObject subObjectParent = new GameObject(obj); subObjectParent.transform.parent = parentObject.transform; GameObject subObject = new GameObject("ChildMesh"); subObject.transform.parent = subObjectParent.transform; subObject.transform.localScale = new Vector3(-1, 1, 1); //Create mesh Mesh m = new Mesh(); m.name = obj; //LISTS FOR REORDERING List <Vector3> processedVertices = new List <Vector3>(); List <Vector3> processedNormals = new List <Vector3>(); List <Vector2> processedUVs = new List <Vector2>(); List <int[]> processedIndexes = new List <int[]>(); Dictionary <int, int> remapTable = new Dictionary <int, int>(); //POPULATE MESH List <string> meshMaterialNames = new List <string>(); OBJFace[] ofaces = faceList.Where(x => x.meshName == obj).ToArray(); foreach (string mn in materialNames) { OBJFace[] faces = ofaces.Where(x => x.materialName == mn).ToArray(); if (faces.Length > 0) { int[] indexes = new int[0]; foreach (OBJFace f in faces) { int l = indexes.Length; System.Array.Resize(ref indexes, l + f.indexes.Length); System.Array.Copy(f.indexes, 0, indexes, l, f.indexes.Length); } meshMaterialNames.Add(mn); if (m.subMeshCount != meshMaterialNames.Count) { m.subMeshCount = meshMaterialNames.Count; } for (int i = 0; i < indexes.Length; i++) { int idx = indexes[i]; //build remap table if (remapTable.ContainsKey(idx)) { //ezpz indexes[i] = remapTable[idx]; } else { processedVertices.Add(uvertices[idx]); processedNormals.Add(unormals[idx]); processedUVs.Add(uuvs[idx]); remapTable[idx] = processedVertices.Count - 1; indexes[i] = remapTable[idx]; } } processedIndexes.Add(indexes); } } //apply stuff m.vertices = processedVertices.ToArray(); m.normals = processedNormals.ToArray(); m.uv = processedUVs.ToArray(); for (int i = 0; i < processedIndexes.Count; i++) { m.SetTriangles(processedIndexes[i], i); } if (!hasNormals) { m.RecalculateNormals(); } m.RecalculateBounds(); MeshFilter mf = subObject.AddComponent <MeshFilter>(); MeshRenderer mr = subObject.AddComponent <MeshRenderer>(); Material[] processedMaterials = new Material[meshMaterialNames.Count]; for (int i = 0; i < meshMaterialNames.Count; i++) { if (materialCache == null) { processedMaterials[i] = new Material(Shader.Find("Universal Render Pipeline/Simple Lit")); } else { Material mfn = Array.Find(materialCache, x => x.name == meshMaterialNames[i]); if (mfn == null) { processedMaterials[i] = new Material(Shader.Find("Universal Render Pipeline/Simple Lit")); } else { processedMaterials[i] = mfn; } } processedMaterials[i].name = meshMaterialNames[i]; } mr.materials = processedMaterials; mf.mesh = m; } return(parentObject); }
//------------------------------------------------------------------------------------------------------------ public void AddFace(OBJFace lFace) { m_Faces.Add(lFace); }
public static PreparedMesh prepare(string fn) { PreparedMesh prepMesh = new PreparedMesh(); List <string> objectNames = prepMesh.objectNames; List <OBJFace> faceList = prepMesh.faceList; string meshName = Path.GetFileNameWithoutExtension(fn); //OBJ LISTS List <Vector3> vertices = new List <Vector3>(1000); List <Vector3> normals = new List <Vector3>(1000); List <Vector2> uvs = new List <Vector2>(1000); //UMESH LISTS //MESH CONSTRUCTION List <string> materialNames = prepMesh.materialNames; Dictionary <string, int> hashtable = new Dictionary <string, int>(); string cmaterial = ""; string cmesh = "default"; //CACHE //save this info for later FileInfo OBJFileInfo = new FileInfo(fn); Debug.Log("cmesh:" + cmesh); Debug.Log("cmaterial:" + cmaterial); String ln = ""; StreamReader reader = new StreamReader(fn); while ((ln = reader.ReadLine()) != null) { if (ln.Length > 0 && ln[0] != '#') { string l = ln.Trim().Replace(" ", " "); string[] cmps = l.Split(' '); string data = l.Remove(0, l.IndexOf(' ') + 1); //Debug.Log("parse: " + l); if (cmps[0] == "mtllib") { //load cache string pth = OBJGetFilePath(data, OBJFileInfo.Directory.FullName + Path.DirectorySeparatorChar, meshName); if (pth != null) { prepMesh.materialCache = LoadMTLFile(pth); } } else if ((cmps[0] == "g" || cmps[0] == "o") && splitByMaterial == false) { cmesh = data; if (!objectNames.Contains(cmesh)) { objectNames.Add(cmesh); } } else if (cmps[0] == "usemtl") { cmaterial = data; if (!materialNames.Contains(cmaterial)) { materialNames.Add(cmaterial); } if (splitByMaterial) { if (!objectNames.Contains(cmaterial)) { objectNames.Add(cmaterial); } } } else if (cmps[0] == "v") { //VERTEX vertices.Add(ParseVectorFromCMPS(cmps)); } else if (cmps[0] == "vn") { //VERTEX NORMAL normals.Add(ParseVectorFromCMPS(cmps)); } else if (cmps[0] == "vt") { //VERTEX UV uvs.Add(ParseVectorFromCMPS(cmps)); } else if (cmps[0] == "f") { int[] indexes = new int[cmps.Length - 1]; for (int i = 1; i < cmps.Length; i++) { string felement = cmps[i]; int vertexIndex = -1; int normalIndex = -1; int uvIndex = -1; if (felement.Contains("//")) { //doubleslash, no UVS. string[] elementComps = felement.Split('/'); vertexIndex = int.Parse(elementComps[0]) - 1; normalIndex = int.Parse(elementComps[2]) - 1; } else if (felement.Count(x => x == '/') == 2) { //contains everything string[] elementComps = felement.Split('/'); vertexIndex = int.Parse(elementComps[0]) - 1; uvIndex = int.Parse(elementComps[1]) - 1; normalIndex = int.Parse(elementComps[2]) - 1; } else if (!felement.Contains("/")) { //just vertex inedx vertexIndex = int.Parse(felement) - 1; } else { //vertex and uv string[] elementComps = felement.Split('/'); vertexIndex = int.Parse(elementComps[0]) - 1; uvIndex = int.Parse(elementComps[1]) - 1; } string hashEntry = vertexIndex + "|" + normalIndex + "|" + uvIndex; if (hashtable.ContainsKey(hashEntry)) { indexes[i - 1] = hashtable[hashEntry]; } else { //create a new hash entry indexes[i - 1] = hashtable.Count; hashtable[hashEntry] = hashtable.Count; prepMesh.uvertices.Add(vertices[vertexIndex]); if (normalIndex < 0 || (normalIndex > (normals.Count - 1))) { prepMesh.unormals.Add(Vector3.zero); } else { prepMesh.hasNormals = true; prepMesh.unormals.Add(normals[normalIndex]); } if (uvIndex < 0 || (uvIndex > (uvs.Count - 1))) { prepMesh.uuvs.Add(Vector2.zero); } else { prepMesh.uuvs.Add(uvs[uvIndex]); } } } if (indexes.Length < 5 && indexes.Length >= 3) { OBJFace f1 = new OBJFace(); f1.materialName = cmaterial; f1.indexes = new int[] { indexes[0], indexes[1], indexes[2] }; f1.meshName = (splitByMaterial) ? cmaterial : cmesh; faceList.Add(f1); if (indexes.Length > 3) { OBJFace f2 = new OBJFace(); f2.materialName = cmaterial; f2.meshName = (splitByMaterial) ? cmaterial : cmesh; f2.indexes = new int[] { indexes[2], indexes[3], indexes[0] }; faceList.Add(f2); } } } } } reader.Close(); if (objectNames.Count == 0) { objectNames.Add("default"); } prepMesh.pMesh2 = prepMesh2(prepMesh, fn); return(prepMesh); }
public static OBJMesh LoadOBJMesh(string fn) { string meshName = Path.GetFileNameWithoutExtension(fn); bool hasNormals = false; //OBJ LISTS List <Vector3> vertices = new List <Vector3>(); List <Vector3> normals = new List <Vector3>(); List <Vector2> uvs = new List <Vector2>(); //MESH CONSTRUCTION List <string> materialNames = new List <string>(); List <string> objectNames = new List <string>(); Dictionary <string, int> hashtable = new Dictionary <string, int>(); List <OBJFace> faceList = new List <OBJFace>(); string cmaterial = ""; string cmesh = "default"; //CACHE Material[] materialCache = null; //save this info for later FileInfo OBJFileInfo = new FileInfo(fn); foreach (string ln in File.ReadAllLines(fn)) { if (ln.Length > 0 && ln[0] != '#') { string l = ln.Trim().Replace(" ", " "); string[] cmps = l.Split(' '); string data = l.Remove(0, l.IndexOf(' ') + 1); if (cmps[0] == "mtllib") { //load cache string pth = OBJGetFilePath(data, OBJFileInfo.Directory.FullName + Path.DirectorySeparatorChar, meshName); if (pth != null) { materialCache = LoadMTLFile(pth); } } else if ((cmps[0] == "g" || cmps[0] == "o") && splitByMaterial == false) { cmesh = data; if (!objectNames.Contains(cmesh)) { objectNames.Add(cmesh); } } else if (cmps[0] == "usemtl") { cmaterial = data; if (!materialNames.Contains(cmaterial)) { materialNames.Add(cmaterial); } if (splitByMaterial) { if (!objectNames.Contains(cmaterial)) { objectNames.Add(cmaterial); } } } else if (cmps[0] == "v") { //VERTEX vertices.Add(ParseVectorFromCMPS(cmps)); } else if (cmps[0] == "vn") { //VERTEX NORMAL normals.Add(ParseVectorFromCMPS(cmps)); } else if (cmps[0] == "vt") { //VERTEX UV uvs.Add(ParseVectorFromCMPS(cmps)); } else if (cmps[0] == "f") { int[] indexes = new int[cmps.Length - 1]; for (int i = 1; i < cmps.Length; i++) { string felement = cmps[i]; int vertexIndex = -1; int normalIndex = -1; int uvIndex = -1; if (felement.Contains("//")) { //doubleslash, no UVS. string[] elementComps = felement.Split('/'); vertexIndex = int.Parse(elementComps[0]) - 1; normalIndex = int.Parse(elementComps[2]) - 1; } else if (felement.Count(x => x == '/') == 2) { //contains everything string[] elementComps = felement.Split('/'); vertexIndex = int.Parse(elementComps[0]) - 1; uvIndex = int.Parse(elementComps[1]) - 1; normalIndex = int.Parse(elementComps[2]) - 1; } else if (!felement.Contains("/")) { //just vertex inedx vertexIndex = int.Parse(felement) - 1; } else { //vertex and uv string[] elementComps = felement.Split('/'); vertexIndex = int.Parse(elementComps[0]) - 1; uvIndex = int.Parse(elementComps[1]) - 1; } indexes[i - 1] = vertexIndex; } if (indexes.Length < 5 && indexes.Length >= 3) { OBJFace f1 = new OBJFace(); f1.materialName = cmaterial; f1.indexes = new int[] { indexes[0], indexes[1], indexes[2] }; f1.meshName = (splitByMaterial) ? cmaterial : cmesh; faceList.Add(f1); if (indexes.Length > 3) { OBJFace f2 = new OBJFace(); f2.materialName = cmaterial; f2.meshName = (splitByMaterial) ? cmaterial : cmesh; f2.indexes = new int[] { indexes[2], indexes[3], indexes[0] }; faceList.Add(f2); } } } } } // return object with verts and faces OBJMesh finalMesh = new OBJMesh(); finalMesh.vertices = vertices; finalMesh.faces = faceList; return(finalMesh); }
public bool isSame(OBJFace test) { FaceComparer f = new FaceComparer(); return(f.Compare(targetFace, test) == 0); }
public static GameObject LoadOBJFile(string fn) { string meshName = Path.GetFileNameWithoutExtension(fn); bool hasNormals = false; //OBJ LISTS List<Vector3> vertices = new List<Vector3>(); List<Vector3> normals = new List<Vector3>(); List<Vector2> uvs = new List<Vector2>(); //UMESH LISTS List<Vector3> uvertices = new List<Vector3>(); List<Vector3> unormals = new List<Vector3>(); List<Vector2> uuvs = new List<Vector2>(); //MESH CONSTRUCTION List<string> materialNames = new List<string>(); List<string> objectNames = new List<string>(); Dictionary<string,int> hashtable = new Dictionary<string, int>(); List<OBJFace> faceList = new List<OBJFace>(); string cmaterial = ""; string cmesh = "default"; //CACHE Material[] materialCache = null; //save this info for later FileInfo OBJFileInfo = new FileInfo(fn); foreach (string ln in File.ReadAllLines(fn)) { if (ln.Length > 0 && ln[0] != '#') { string l = ln.Trim().Replace(" "," "); string[] cmps = l.Split(' '); string data = l.Remove(0, l.IndexOf(' ') + 1); if (cmps[0] == "mtllib") { //load cache string pth = OBJGetFilePath(data, OBJFileInfo.Directory.FullName + Path.DirectorySeparatorChar, meshName); if (pth != null) materialCache = LoadMTLFile(pth); } else if ((cmps[0] == "g" || cmps[0] == "o") && splitByMaterial == false) { cmesh = data; if (!objectNames.Contains(cmesh)) { objectNames.Add(cmesh); } } else if (cmps[0] == "usemtl") { cmaterial = data; if (!materialNames.Contains(cmaterial)) { materialNames.Add(cmaterial); } if (splitByMaterial) { if (!objectNames.Contains(cmaterial)) { objectNames.Add(cmaterial); } } } else if (cmps[0] == "v") { //VERTEX vertices.Add(ParseVectorFromCMPS(cmps)); } else if (cmps[0] == "vn") { //VERTEX NORMAL normals.Add(ParseVectorFromCMPS(cmps)); } else if (cmps[0] == "vt") { //VERTEX UV uvs.Add(ParseVectorFromCMPS(cmps)); } else if (cmps[0] == "f") { int[] indexes = new int[cmps.Length - 1]; for (int i = 1; i < cmps.Length ; i++) { string felement = cmps[i]; int vertexIndex = -1; int normalIndex = -1; int uvIndex = -1; if (felement.Contains("//")) { //doubleslash, no UVS. string[] elementComps = felement.Split('/'); vertexIndex = int.Parse(elementComps[0]) - 1; normalIndex = int.Parse(elementComps[2]) - 1; } else if (felement.Count(x => x == '/') == 2) { //contains everything string[] elementComps = felement.Split('/'); vertexIndex = int.Parse(elementComps[0]) - 1; uvIndex = int.Parse(elementComps[1]) - 1; normalIndex = int.Parse(elementComps[2]) - 1; } else if (!felement.Contains("/")) { //just vertex inedx vertexIndex = int.Parse(felement) - 1; } else { //vertex and uv string[] elementComps = felement.Split('/'); vertexIndex = int.Parse(elementComps[0]) - 1; uvIndex = int.Parse(elementComps[1]) - 1; } string hashEntry = vertexIndex + "|" + normalIndex + "|" +uvIndex; if (hashtable.ContainsKey(hashEntry)) { indexes[i - 1] = hashtable[hashEntry]; } else { //create a new hash entry indexes[i - 1] = hashtable.Count; hashtable[hashEntry] = hashtable.Count; uvertices.Add(vertices[vertexIndex]); if (normalIndex < 0 || (normalIndex > (normals.Count - 1))) { unormals.Add(Vector3.zero); } else { hasNormals = true; unormals.Add(normals[normalIndex]); } if (uvIndex < 0 || (uvIndex > (uvs.Count - 1))) { uuvs.Add(Vector2.zero); } else { uuvs.Add(uvs[uvIndex]); } } } if (indexes.Length < 5 && indexes.Length >= 3) { OBJFace f1 = new OBJFace(); f1.materialName = cmaterial; f1.indexes = new int[] { indexes[0], indexes[1], indexes[2] }; f1.meshName = (splitByMaterial) ? cmaterial : cmesh; faceList.Add(f1); if (indexes.Length > 3) { OBJFace f2 = new OBJFace(); f2.materialName = cmaterial; f2.meshName = (splitByMaterial) ? cmaterial : cmesh; f2.indexes = new int[] { indexes[2], indexes[3], indexes[0] }; faceList.Add(f2); } } } } } if (objectNames.Count == 0) objectNames.Add("default"); //build objects GameObject parentObject = new GameObject(meshName); foreach (string obj in objectNames) { GameObject subObject = new GameObject(obj); subObject.transform.parent = parentObject.transform; subObject.transform.localScale = new Vector3(-1, 1, 1); //Create mesh Mesh m = new Mesh(); m.name = obj; //LISTS FOR REORDERING List<Vector3> processedVertices = new List<Vector3>(); List<Vector3> processedNormals = new List<Vector3>(); List<Vector2> processedUVs = new List<Vector2>(); List<int[]> processedIndexes = new List<int[]>(); Dictionary<int,int> remapTable = new Dictionary<int, int>(); //POPULATE MESH List<string> meshMaterialNames = new List<string>(); OBJFace[] ofaces = faceList.Where(x => x.meshName == obj).ToArray(); foreach (string mn in materialNames) { OBJFace[] faces = ofaces.Where(x => x.materialName == mn).ToArray(); if (faces.Length > 0) { int[] indexes = new int[0]; foreach (OBJFace f in faces) { int l = indexes.Length; System.Array.Resize(ref indexes, l + f.indexes.Length); System.Array.Copy(f.indexes, 0, indexes, l, f.indexes.Length); } meshMaterialNames.Add(mn); if (m.subMeshCount != meshMaterialNames.Count) m.subMeshCount = meshMaterialNames.Count; for (int i = 0; i < indexes.Length; i++) { int idx = indexes[i]; //build remap table if (remapTable.ContainsKey(idx)) { //ezpz indexes[i] = remapTable[idx]; } else { processedVertices.Add(uvertices[idx]); processedNormals.Add(unormals[idx]); processedUVs.Add(uuvs[idx]); remapTable[idx] = processedVertices.Count - 1; indexes[i] = remapTable[idx]; } } processedIndexes.Add(indexes); } else { } } //apply stuff m.vertices = processedVertices.ToArray(); m.normals = processedNormals.ToArray(); m.uv = processedUVs.ToArray(); for (int i = 0; i < processedIndexes.Count; i++) { m.SetTriangles(processedIndexes[i],i); } if (!hasNormals) { m.RecalculateNormals(); } m.RecalculateBounds(); m.Optimize(); MeshFilter mf = subObject.AddComponent<MeshFilter>(); MeshRenderer mr = subObject.AddComponent<MeshRenderer>(); Material[] processedMaterials = new Material[meshMaterialNames.Count]; for(int i=0 ; i < meshMaterialNames.Count; i++) { if (materialCache == null) { processedMaterials[i] = new Material(Shader.Find("Standard (Specular setup)")); } else { Material mfn = Array.Find(materialCache, x => x.name == meshMaterialNames[i]); ; if (mfn == null) { processedMaterials[i] = new Material(Shader.Find("Standard (Specular setup)")); } else { processedMaterials[i] = mfn; } } processedMaterials[i].name = meshMaterialNames[i]; } mr.materials = processedMaterials; mf.mesh = m; } return parentObject; }
public static GameObject LoadOBJ(string meshName, List <string> fileContents, Material baseMaterial) { bool hasNormals = false; //OBJ LISTS List <Vector3> vertices = new List <Vector3>(); List <Vector3> normals = new List <Vector3>(); List <Vector2> uvs = new List <Vector2>(); //UMESH LISTS List <Vector3> uvertices = new List <Vector3>(); List <Vector3> unormals = new List <Vector3>(); List <Vector2> uuvs = new List <Vector2>(); //MESH CONSTRUCTION List <string> materialNames = new List <string>(); List <string> objectNames = new List <string>(); Dictionary <string, int> hashtable = new Dictionary <string, int>(); List <OBJFace> faceList = new List <OBJFace>(); string cmaterial = ""; string cmesh = "default"; foreach (string ln in fileContents) { if (ln.Length > 0 && ln[0] != '#') { string l = ln.Trim().Replace(" ", " "); string[] cmps = l.Split(' '); string data = l.Remove(0, l.IndexOf(' ') + 1); if (cmps[0] == "mtllib") { } else if ((cmps[0] == "g" || cmps[0] == "o") && splitByMaterial == false) { cmesh = data; if (!objectNames.Contains(cmesh)) { objectNames.Add(cmesh); } } else if (cmps[0] == "usemtl") { cmaterial = data; if (!materialNames.Contains(cmaterial)) { materialNames.Add(cmaterial); } if (splitByMaterial) { if (!objectNames.Contains(cmaterial)) { objectNames.Add(cmaterial); } } } else if (cmps[0] == "v") { //VERTEX vertices.Add(ParseVectorFromCMPS(cmps)); } else if (cmps[0] == "vn") { //VERTEX NORMAL normals.Add(ParseVectorFromCMPS(cmps)); } else if (cmps[0] == "vt") { //VERTEX UV uvs.Add(ParseVectorFromCMPS(cmps)); } else if (cmps[0] == "f") { int[] indexes = new int[cmps.Length - 1]; for (int i = 1; i < cmps.Length; i++) { string felement = cmps[i]; int vertexIndex = -1; int normalIndex = -1; int uvIndex = -1; if (felement.Contains("//")) { //doubleslash, no UVS. string[] elementComps = felement.Split('/'); vertexIndex = int.Parse(elementComps[0]) - 1; normalIndex = int.Parse(elementComps[2]) - 1; } else if (felement.Count(x => x == '/') == 2) { //contains everything string[] elementComps = felement.Split('/'); vertexIndex = int.Parse(elementComps[0]) - 1; uvIndex = int.Parse(elementComps[1]) - 1; normalIndex = int.Parse(elementComps[2]) - 1; } else if (!felement.Contains("/")) { //just vertex inedx vertexIndex = int.Parse(felement) - 1; } else { //vertex and uv string[] elementComps = felement.Split('/'); vertexIndex = int.Parse(elementComps[0]) - 1; uvIndex = int.Parse(elementComps[1]) - 1; } string hashEntry = vertexIndex + "|" + normalIndex + "|" + uvIndex; if (hashtable.ContainsKey(hashEntry)) { indexes[i - 1] = hashtable[hashEntry]; } else { //create a new hash entry indexes[i - 1] = hashtable.Count; hashtable[hashEntry] = hashtable.Count; uvertices.Add(vertices[vertexIndex]); if (normalIndex < 0 || (normalIndex > (normals.Count - 1))) { unormals.Add(Vector3.zero); } else { hasNormals = true; unormals.Add(normals[normalIndex]); } if (uvIndex < 0 || (uvIndex > (uvs.Count - 1))) { uuvs.Add(Vector2.zero); } else { uuvs.Add(uvs[uvIndex]); } } } if (indexes.Length < 5 && indexes.Length >= 3) { OBJFace f1 = new OBJFace(); f1.materialName = cmaterial; f1.indexes = new int[] { indexes[0], indexes[1], indexes[2] }; f1.meshName = (splitByMaterial) ? cmaterial : cmesh; faceList.Add(f1); if (indexes.Length > 3) { OBJFace f2 = new OBJFace(); f2.materialName = cmaterial; f2.meshName = (splitByMaterial) ? cmaterial : cmesh; f2.indexes = new int[] { indexes[2], indexes[3], indexes[0] }; faceList.Add(f2); } } } } } if (objectNames.Count == 0) { objectNames.Add("default"); } if (materialNames.Count == 0) { materialNames.Add(""); } //build objects GameObject parentObject = new GameObject(meshName); foreach (string obj in objectNames) { GameObject subObject = new GameObject(obj); subObject.transform.parent = parentObject.transform; subObject.transform.localScale = new Vector3(-1, 1, 1); //Create mesh Mesh m = new Mesh(); m.name = obj; //LISTS FOR REORDERING List <Vector3> processedVertices = new List <Vector3>(); List <Vector3> processedNormals = new List <Vector3>(); List <Vector2> processedUVs = new List <Vector2>(); List <int[]> processedIndexes = new List <int[]>(); Dictionary <int, int> remapTable = new Dictionary <int, int>(); //POPULATE MESH List <string> meshMaterialNames = new List <string>(); OBJFace[] ofaces = faceList.Where(x => x.meshName == obj).ToArray(); foreach (string mn in materialNames) { OBJFace[] faces = ofaces.Where(x => x.materialName == mn).ToArray(); if (faces.Length > 0) { int[] indexes = new int[0]; foreach (OBJFace f in faces) { int l = indexes.Length; System.Array.Resize(ref indexes, l + f.indexes.Length); System.Array.Copy(f.indexes, 0, indexes, l, f.indexes.Length); } meshMaterialNames.Add(mn); if (m.subMeshCount != meshMaterialNames.Count) { m.subMeshCount = meshMaterialNames.Count; } for (int i = 0; i < indexes.Length; i++) { int idx = indexes[i]; //build remap table if (remapTable.ContainsKey(idx)) { //ezpz indexes[i] = remapTable[idx]; } else { processedVertices.Add(uvertices[idx]); processedNormals.Add(unormals[idx]); processedUVs.Add(uuvs[idx]); remapTable[idx] = processedVertices.Count - 1; indexes[i] = remapTable[idx]; } } processedIndexes.Add(indexes); } else { } } //apply stuff m.vertices = processedVertices.ToArray(); m.normals = processedNormals.ToArray(); m.uv = processedUVs.ToArray(); for (int i = 0; i < processedIndexes.Count; i++) { m.SetTriangles(processedIndexes[i], i); } if (!hasNormals) { m.RecalculateNormals(); } m.RecalculateBounds(); MeshFilter mf = subObject.AddComponent <MeshFilter>(); MeshRenderer mr = subObject.AddComponent <MeshRenderer>(); Material[] processedMaterials = new Material[meshMaterialNames.Count]; for (int i = 0; i < meshMaterialNames.Count; i++) { processedMaterials[i] = new Material(baseMaterial); processedMaterials[i].name = meshMaterialNames[i]; } mr.materials = processedMaterials; mf.mesh = m; } return(parentObject); }
public static Mesh LoadOBJFileToMesh(string fn) { Mesh m = new Mesh(); string meshName = Path.GetFileNameWithoutExtension(fn); bool hasNormals = false; //OBJ LISTS List <Vector3> vertices = new List <Vector3>(); List <Vector3> normals = new List <Vector3>(); List <Vector2> uvs = new List <Vector2>(); //UMESH LISTS List <Vector3> uvertices = new List <Vector3>(); List <Vector3> unormals = new List <Vector3>(); List <Vector2> uuvs = new List <Vector2>(); //MESH CONSTRUCTION List <string> materialNames = new List <string>(); List <string> objectNames = new List <string>(); Dictionary <string, int> hashtable = new Dictionary <string, int>(); List <OBJFace> faceList = new List <OBJFace>(); string cmaterial = ""; string cmesh = "default"; //CACHE Material[] materialCache = null; //save this info for later FileInfo OBJFileInfo = new FileInfo(fn); foreach (string ln in File.ReadAllLines(fn)) { if (ln.Length > 0 && ln[0] != '#') { string l = ln.Trim().Replace(" ", " "); string[] cmps = l.Split(' '); string data = l.Remove(0, l.IndexOf(' ') + 1); if (cmps[0] == "mtllib") { //load cache string pth = OBJGetFilePath(data, OBJFileInfo.Directory.FullName + Path.DirectorySeparatorChar, meshName); if (pth != null) { materialCache = LoadMTLFile(pth); } } else if ((cmps[0] == "g" || cmps[0] == "o") && splitByMaterial == false) { cmesh = data; if (!objectNames.Contains(cmesh)) { objectNames.Add(cmesh); } } else if (cmps[0] == "usemtl") { cmaterial = data; if (!materialNames.Contains(cmaterial)) { materialNames.Add(cmaterial); } if (splitByMaterial) { if (!objectNames.Contains(cmaterial)) { objectNames.Add(cmaterial); } } } else if (cmps[0] == "v") { //VERTEX vertices.Add(ParseVectorFromCMPS(cmps)); } else if (cmps[0] == "vn") { //VERTEX NORMAL normals.Add(ParseVectorFromCMPS(cmps)); } else if (cmps[0] == "vt") { //VERTEX UV uvs.Add(ParseVectorFromCMPS(cmps)); } else if (cmps[0] == "f") { int[] indexes = new int[cmps.Length - 1]; for (int i = 1; i < cmps.Length; i++) { string felement = cmps[i]; int vertexIndex = -1; int normalIndex = -1; int uvIndex = -1; if (felement.Contains("//")) { //doubleslash, no UVS. string[] elementComps = felement.Split('/'); vertexIndex = int.Parse(elementComps[0]) - 1; normalIndex = int.Parse(elementComps[2]) - 1; } else if (felement.Count(x => x == '/') == 2) { //contains everything string[] elementComps = felement.Split('/'); vertexIndex = int.Parse(elementComps[0]) - 1; uvIndex = int.Parse(elementComps[1]) - 1; normalIndex = int.Parse(elementComps[2]) - 1; } else if (!felement.Contains("/")) { //just vertex inedx vertexIndex = int.Parse(felement) - 1; } else { //vertex and uv string[] elementComps = felement.Split('/'); vertexIndex = int.Parse(elementComps[0]) - 1; uvIndex = int.Parse(elementComps[1]) - 1; } string hashEntry = vertexIndex + "|" + normalIndex + "|" + uvIndex; if (hashtable.ContainsKey(hashEntry)) { indexes[i - 1] = hashtable[hashEntry]; } else { //create a new hash entry indexes[i - 1] = hashtable.Count; hashtable[hashEntry] = hashtable.Count; uvertices.Add(vertices[vertexIndex]); if (normalIndex < 0 || (normalIndex > (normals.Count - 1))) { unormals.Add(Vector3.zero); } else { hasNormals = true; unormals.Add(normals[normalIndex]); } if (uvIndex < 0 || (uvIndex > (uvs.Count - 1))) { uuvs.Add(Vector2.zero); } else { uuvs.Add(uvs[uvIndex]); } } } if (indexes.Length < 5 && indexes.Length >= 3) { OBJFace f1 = new OBJFace(); f1.materialName = cmaterial; f1.indexes = new int[] { indexes[0], indexes[1], indexes[2] }; f1.meshName = (splitByMaterial) ? cmaterial : cmesh; faceList.Add(f1); if (indexes.Length > 3) { OBJFace f2 = new OBJFace(); f2.materialName = cmaterial; f2.meshName = (splitByMaterial) ? cmaterial : cmesh; f2.indexes = new int[] { indexes[2], indexes[3], indexes[0] }; faceList.Add(f2); } } } } } foreach (string obj in objectNames) { //LISTS FOR REORDERING List <Vector3> processedVertices = new List <Vector3>(); List <Vector3> processedNormals = new List <Vector3>(); List <Vector2> processedUVs = new List <Vector2>(); List <int[]> processedIndexes = new List <int[]>(); Dictionary <int, int> remapTable = new Dictionary <int, int>(); //POPULATE MESH List <string> meshMaterialNames = new List <string>(); OBJFace[] ofaces = faceList.Where(x => x.meshName == obj).ToArray(); foreach (string mn in materialNames) { OBJFace[] faces = ofaces.Where(x => x.materialName == mn).ToArray(); if (faces.Length > 0) { int[] indexes = new int[0]; foreach (OBJFace f in faces) { int l = indexes.Length; System.Array.Resize(ref indexes, l + f.indexes.Length); System.Array.Copy(f.indexes, 0, indexes, l, f.indexes.Length); } meshMaterialNames.Add(mn); if (m.subMeshCount != meshMaterialNames.Count) { m.subMeshCount = meshMaterialNames.Count; } for (int i = 0; i < indexes.Length; i++) { int idx = indexes[i]; //build remap table if (remapTable.ContainsKey(idx)) { //ezpz indexes[i] = remapTable[idx]; } else { processedVertices.Add(uvertices[idx]); processedNormals.Add(unormals[idx]); processedUVs.Add(uuvs[idx]); remapTable[idx] = processedVertices.Count - 1; indexes[i] = remapTable[idx]; } } processedIndexes.Add(indexes); } else { } } //apply stuff m.vertices = processedVertices.ToArray(); m.normals = processedNormals.ToArray(); m.uv = processedUVs.ToArray(); for (int i = 0; i < processedIndexes.Count; i++) { m.SetTriangles(processedIndexes[i], i); } if (!hasNormals) { m.RecalculateNormals(); } m.RecalculateNormals(); m.RecalculateTangents(); m.RecalculateBounds(); ; } return(m); }
public OBJ(byte[] Data) { var enusculture = new CultureInfo("en-US"); string curmat = null; Vertices = new List <Vector3>(); Normals = new List <Vector3>(); TexCoords = new List <Vector2>(); Faces = new List <OBJFace>(); TextReader tr = new StreamReader(new MemoryStream(Data)); String line; while ((line = tr.ReadLine()) != null) { line = line.Trim(); if (line.Length < 1 || line.StartsWith("#")) { continue; } string[] parts = line.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (parts.Length < 1) { continue; } switch (parts[0]) { case "mtllib": if (parts.Length < 2) { continue; } MTLPath = line.Substring(parts[0].Length + 1).Trim(); break; case "usemtl": if (parts.Length < 2) { continue; } curmat = parts[1]; break; case "v": { if (parts.Length < 4) { continue; } float x = float.Parse(parts[1], enusculture); float y = float.Parse(parts[2], enusculture); float z = float.Parse(parts[3], enusculture); Vertices.Add(new Vector3(x, y, z)); break; } case "vn": { if (parts.Length < 4) { continue; } float x = float.Parse(parts[1], enusculture); float y = float.Parse(parts[2], enusculture); float z = float.Parse(parts[3], enusculture); Normals.Add(new Vector3(x, y, z)); break; } case "vt": { if (parts.Length < 3) { continue; } float s = float.Parse(parts[1], enusculture); float t = float.Parse(parts[2], enusculture); TexCoords.Add(new Vector2(s, t)); break; } case "f": { if (parts.Length < 4) { continue; } OBJFace f = new OBJFace(); f.Material = curmat; for (int i = 0; i < parts.Length - 1; i++) { String[] Parts = parts[i + 1].Split('/'); f.VertexIndieces.Add(int.Parse(Parts[0]) - 1); if (Parts.Length > 1) { if (Parts[1] != "") { f.TexCoordIndieces.Add(int.Parse(Parts[1]) - 1); } if (Parts.Length > 2 && Parts[2] != "") { f.NormalIndieces.Add(int.Parse(Parts[2]) - 1); } } } Faces.Add(f); break; } } } tr.Close(); //optimizeVertexCount(); }
private void ParseFile() { StreamReader sr = new StreamReader(_path, Encoding.Default); string ln; while (!sr.EndOfStream) { ln = sr.ReadLine(); if (ln.Length > 0 && ln[0] != '#') { LineTokenizer lk = new LineTokenizer(ln); if (lk.Type == "mtllib") { // Loads cache string mtlPath = OBJLoader.OBJGetFilePath(lk.Data, OBJFileInfo.Directory.FullName + Path.DirectorySeparatorChar, _meshName); if (mtlPath != null) { materialCache = OBJLoader.LoadMTLFile(mtlPath); } } else if ((lk.Type == "g" || lk.Type == "o") && _splitByMaterial == false) { cmesh = lk.Data; if (!objectNames.Contains(cmesh)) { objectNames.Add(cmesh); } } else if (lk.Type == "usemtl") { cmaterial = lk.Data; if (!materialNames.Contains(cmaterial)) { materialNames.Add(cmaterial); } if (_splitByMaterial) { if (!objectNames.Contains(cmaterial)) { objectNames.Add(cmaterial); } } } // Vertices else if (lk.Type == "v") { vertices.Add(OBJLoader.ParseVectorFromCMPS(lk.Tokens)); } // Vertex normals else if (lk.Type == "vn") { normals.Add(OBJLoader.ParseVectorFromCMPS(lk.Tokens)); } // Textures coordinates else if (lk.Type == "vt") { uvs.Add(OBJLoader.ParseVectorFromCMPS(lk.Tokens)); } // Polygonal face element else if (lk.Type == "f") { int[] indexes = new int[lk.Tokens.Length - 1]; for (int i = 1; i < lk.Tokens.Length; i++) { string felement = lk.Tokens[i]; int vertexIndex = -1; int normalIndex = -1; int uvIndex = -1; if (felement.Contains("//")) { //doubleslash, no UVS. string[] elementComps = felement.Split('/'); vertexIndex = int.Parse(elementComps[0]) - 1; normalIndex = int.Parse(elementComps[2]) - 1; } else if (felement.Count(x => x == '/') == 2) { //contains everything string[] elementComps = felement.Split('/'); vertexIndex = int.Parse(elementComps[0]) - 1; uvIndex = int.Parse(elementComps[1]) - 1; normalIndex = int.Parse(elementComps[2]) - 1; } else if (!felement.Contains("/")) { //just vertex inedx vertexIndex = int.Parse(felement) - 1; } else { //vertex and uv string[] elementComps = felement.Split('/'); vertexIndex = int.Parse(elementComps[0]) - 1; uvIndex = int.Parse(elementComps[1]) - 1; } string hashEntry = vertexIndex + "|" + normalIndex + "|" + uvIndex; if (hashtable.ContainsKey(hashEntry)) { indexes[i - 1] = hashtable[hashEntry]; } else { //create a new hash entry indexes[i - 1] = hashtable.Count; hashtable[hashEntry] = hashtable.Count; uvertices.Add(vertices[vertexIndex]); if (normalIndex < 0 || (normalIndex > (normals.Count - 1))) { unormals.Add(Vector3.zero); } else { _hasNormals = true; unormals.Add(normals[normalIndex]); } if (uvIndex < 0 || (uvIndex > (uvs.Count - 1))) { uuvs.Add(Vector2.zero); } else { uuvs.Add(uvs[uvIndex]); } } } if (indexes.Length < 5 && indexes.Length >= 3) { OBJFace f1 = new OBJFace(); f1.materialName = cmaterial; f1.indexes = new int[] { indexes[0], indexes[1], indexes[2] }; f1.meshName = (_splitByMaterial) ? cmaterial : cmesh; faceList.Add(f1); if (indexes.Length > 3) { OBJFace f2 = new OBJFace(); f2.materialName = cmaterial; f2.meshName = (_splitByMaterial) ? cmaterial : cmesh; f2.indexes = new int[] { indexes[2], indexes[3], indexes[0] }; faceList.Add(f2); } } } } } }
IEnumerator LoadOBJFile(string fn) { string meshName = Path.GetFileNameWithoutExtension(fn); bool hasNormals = false; //OBJ LISTS List <Vector3> vertices = new List <Vector3>(); List <Vector3> normals = new List <Vector3>(); List <Vector2> uvs = new List <Vector2>(); //UMESH LISTS List <Vector3> uvertices = new List <Vector3>(); List <Vector3> unormals = new List <Vector3>(); List <Vector2> uuvs = new List <Vector2>(); //MESH CONSTRUCTION List <string> materialNames = new List <string>(); List <string> objectNames = new List <string>(); Dictionary <string, int> hashtable = new Dictionary <string, int>(); List <OBJFace> faceList = new List <OBJFace>(); string cmaterial = ""; string cmesh = "default"; //CACHE Material[] materialCache = null; //save this info for later FileInfo OBJFileInfo = new FileInfo(fn); string[] lines = File.ReadAllLines(fn); string ln; string l; string[] cmps; string data; int[] indexes1; string felement; int vertexIndex = -1; int normalIndex = -1; int uvIndex = -1; string[] elementComps; for (int xl = 0; xl < lines.Length; xl++) //foreach (string ln in File.ReadAllLines(fn)) { ln = lines[xl]; if (ln.Length > 0 && ln[0] != '#') { l = ln.Trim().Replace(" ", " "); cmps = l.Split(' '); data = l.Remove(0, l.IndexOf(' ') + 1); if (cmps[0] == "mtllib") { //load cache string pth = OBJGetFilePath(data, OBJFileInfo.Directory.FullName + Path.DirectorySeparatorChar, meshName); if (pth != null) { materialCache = LoadMTLFile(pth); } } else if ((cmps[0] == "g" || cmps[0] == "o") && splitByMaterial == false) { cmesh = data; if (!objectNames.Contains(cmesh)) { objectNames.Add(cmesh); } } else if (cmps[0] == "usemtl") { cmaterial = data; if (!materialNames.Contains(cmaterial)) { materialNames.Add(cmaterial); } if (splitByMaterial) { if (!objectNames.Contains(cmaterial)) { objectNames.Add(cmaterial); } } } else if (cmps[0] == "v") { //VERTEX vertices.Add(ParseVectorFromCMPSY(cmps, true)); } else if (cmps[0] == "vn") { //VERTEX NORMAL normals.Add(ParseVectorFromCMPSY(cmps, true)); } else if (cmps[0] == "vt") { //VERTEX UV uvs.Add(ParseVectorFromCMPSY2(cmps, true)); } else if (cmps[0] == "f") { indexes1 = new int[cmps.Length - 1]; for (int i = 1; i < cmps.Length; i++) { felement = cmps[i]; vertexIndex = -1; normalIndex = -1; uvIndex = -1; if (felement.Contains("//")) { //doubleslash, no UVS. elementComps = felement.Split('/'); vertexIndex = int.Parse(elementComps[0]) - 1; normalIndex = int.Parse(elementComps[2]) - 1; } else if (felement.Count(x => x == '/') == 2) { //contains everything elementComps = felement.Split('/'); vertexIndex = int.Parse(elementComps[0]) - 1; uvIndex = int.Parse(elementComps[1]) - 1; normalIndex = int.Parse(elementComps[2]) - 1; } else if (!felement.Contains("/")) { //just vertex inedx vertexIndex = int.Parse(felement) - 1; } else { //vertex and uv elementComps = felement.Split('/'); vertexIndex = int.Parse(elementComps[0]) - 1; uvIndex = int.Parse(elementComps[1]) - 1; } string hashEntry = vertexIndex + "|" + normalIndex + "|" + uvIndex; if (hashtable.ContainsKey(hashEntry)) { indexes1[i - 1] = hashtable[hashEntry]; } else { //create a new hash entry indexes1[i - 1] = hashtable.Count; hashtable[hashEntry] = hashtable.Count; uvertices.Add(vertices[vertexIndex]); if (normalIndex < 0 || (normalIndex > (normals.Count - 1))) { unormals.Add(Vector3.zero); } else { hasNormals = true; unormals.Add(normals[normalIndex]); } if (uvIndex < 0 || (uvIndex > (uvs.Count - 1))) { uuvs.Add(Vector2.zero); } else { uuvs.Add(uvs[uvIndex]); } } } if (indexes1.Length < 5 && indexes1.Length >= 3) { OBJFace f1 = new OBJFace(); f1.materialName = cmaterial; f1.indexes = new int[] { indexes1[0], indexes1[2], indexes1[1] };//modified by kfir for right2left f1.meshName = (splitByMaterial) ? cmaterial : cmesh; faceList.Add(f1); if (indexes1.Length > 3) { OBJFace f2 = new OBJFace(); f2.materialName = cmaterial; f2.meshName = (splitByMaterial) ? cmaterial : cmesh; f2.indexes = new int[] { indexes1[2], indexes1[0], indexes1[3] };//modified by kfir for right2left faceList.Add(f2); } } } } } if (objectNames.Count == 0) { objectNames.Add("default"); } //build objects GameObject parentObject = new GameObject(meshName); for (int obji = 0; obji < objectNames.Count; obji++) //foreach (string obj in objectNames) { string obj = objectNames[obji]; GameObject subObject = new GameObject(obj); subObject.transform.parent = parentObject.transform; subObject.transform.localScale = new Vector3(1, 1, 1); //Debug.LogWarning("subObject : " + subObject.name); //Create mesh Mesh m = new Mesh(); m.name = obj; //LISTS FOR REORDERING List <Vector3> processedVertices = new List <Vector3>(); List <Vector3> processedNormals = new List <Vector3>(); List <Vector2> processedUVs = new List <Vector2>(); List <int[]> processedIndexes = new List <int[]>(); Dictionary <int, int> remapTable = new Dictionary <int, int>(); //POPULATE MESH List <string> meshMaterialNames = new List <string>(); OBJFace[] ofaces = faceList.Where(x => x.meshName == obj).ToArray(); foreach (string mn in materialNames) { OBJFace[] faces = ofaces.Where(x => x.materialName == mn).ToArray(); if (faces.Length > 0) { //int[] indexes = new int[0]; List <int> indexes = new List <int>();; for (int face_i = 0; face_i < faces.Length; face_i++) //foreach (OBJFace f in faces) { OBJFace f = faces[face_i]; indexes.AddRange(f.indexes); //int l = indexes.Length; //System.Array.Resize(ref indexes, l + f.indexes.Length); //System.Array.Copy(f.indexes, 0, indexes, l, f.indexes.Length); } meshMaterialNames.Add(mn); if (m.subMeshCount != meshMaterialNames.Count) { m.subMeshCount = meshMaterialNames.Count; } for (int i = 0; i < indexes.Count; i++) { int idx = indexes[i]; //build remap table if (remapTable.ContainsKey(idx)) { //ezpz indexes[i] = remapTable[idx]; } else { processedVertices.Add(uvertices[idx]); processedNormals.Add(unormals[idx]); processedUVs.Add(uuvs[idx]); remapTable[idx] = processedVertices.Count - 1; indexes[i] = remapTable[idx]; } } processedIndexes.Add(indexes.ToArray()); } else { } } //apply stuff m.vertices = processedVertices.ToArray(); m.normals = processedNormals.ToArray(); m.uv = processedUVs.ToArray(); for (int i = 0; i < processedIndexes.Count; i++) { m.SetTriangles(processedIndexes[i], i); } if (!hasNormals) { m.RecalculateNormals(); } m.RecalculateBounds(); MeshFilter mf = subObject.AddComponent <MeshFilter>(); MeshRenderer mr = subObject.AddComponent <MeshRenderer>(); Material[] processedMaterials = new Material[meshMaterialNames.Count]; for (int i = 0; i < meshMaterialNames.Count; i++) { if (materialCache == null) { processedMaterials[i] = new Material(Shader.Find("Standard")); } else { Material mfn = Array.Find(materialCache, x => x.name == meshMaterialNames[i]);; if (mfn == null) { processedMaterials[i] = new Material(Shader.Find("Standard")); } else { processedMaterials[i] = mfn; } } processedMaterials[i].name = meshMaterialNames[i]; } mr.materials = processedMaterials; mf.mesh = m; } //return parentObject; yield return(null); }
public static GameObject LoadOBJFile(string fn) { Debug.Log("Loading map...."); Debug.Log(fn); MaterialLoader.LoadAlphaMaterial(); string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(fn); if (fileNameWithoutExtension.Contains("alpha")) { alphaIsEnabledOld = true; } else { alphaIsEnabledOld = false; } bool flag2 = false; List <Vector3> list = new List <Vector3>(); List <Vector3> list2 = new List <Vector3>(); List <Vector2> list3 = new List <Vector2>(); List <Vector3> list4 = new List <Vector3>(); List <Vector3> list5 = new List <Vector3>(); List <Vector2> list6 = new List <Vector2>(); List <string> list7 = new List <string>(); List <string> list8 = new List <string>(); Dictionary <string, int> dictionary = new Dictionary <string, int>(); List <OBJFace> list9 = new List <OBJFace>(); string text = ""; string text2 = "default"; Material[] array = null; FileInfo fileInfo = new FileInfo(fn); string[] text3 = File.ReadAllLines(fn); for (int e = 0; e < text3.Length; e++) { if (text3[e].Length > 0 && text3[e][0] != '#') { string text4 = text3[e].Trim().Replace(" ", " "); string[] array2 = text4.Split(new char[] { ' ' }); string text5 = text4.Remove(0, text4.IndexOf(' ') + 1); switch (array2[0]) { case "o": text2 = text5; if (!list8.Contains(text2)) { list8.Add(text2); } break; case "mtllib": string text6 = Search.OBJGetFilePath(text5, fileInfo.Directory.FullName + Path.DirectorySeparatorChar.ToString(), fileNameWithoutExtension); if (text6 != null) { array = MaterialLoader.LoadMTLFile(text6, alphaIsEnabledOld); } break; case "usemtl": text = text5; if (!list7.Contains(text)) { list7.Add(text); } if (splitByMaterial && !list8.Contains(text)) { list8.Add(text); } break; case "v": list.Add(ParseVectorFromCMPS(array2)); break; case "vn": list2.Add(ParseVectorFromCMPS(array2)); break; case "vt": list3.Add(ParseVectorFromCMPS(array2)); break; case "f": int[] array3 = new int[array2.Length - 1]; for (int i = 1; i < array2.Length; i++) { string text7 = array2[i]; int num = -1; int num2 = -1; int num3; if (text7.Contains("//")) { string[] array8 = text7.Split(new char[] { '/' }); num3 = int.Parse(array8[0]) - 1; num = int.Parse(array8[2]) - 1; } else if (text7.Count(new Func <char, bool>(OBJLoader.Func1)) == 2) { string[] array9 = text7.Split(new char[] { '/' }); num3 = int.Parse(array9[0]) - 1; num2 = int.Parse(array9[1]) - 1; num = int.Parse(array9[2]) - 1; } else if (!text7.Contains("/")) { num3 = int.Parse(text7) - 1; } else { string[] array10 = text7.Split(new char[] { '/' }); num3 = int.Parse(array10[0]) - 1; num2 = int.Parse(array10[1]) - 1; } string key = string.Concat(new object[] { num3, "|", num, "|", num2 }); if (dictionary.ContainsKey(key)) { array3[i - 1] = dictionary[key]; } else { array3[i - 1] = dictionary.Count; dictionary[key] = dictionary.Count; list4.Add(list[num3]); if (num < 0 || num > list2.Count - 1) { list5.Add(Vector3.zero); } else { flag2 = true; list5.Add(list2[num]); } if (num2 < 0 || num2 > list3.Count - 1) { list6.Add(Vector2.zero); } else { list6.Add(list3[num2]); } } } if (array3.Length < 5 && array3.Length >= 3) { List <OBJFace> list10 = list9; OBJFace objface3 = new OBJFace { materialName = text, indexes = new int[] { array3[0], array3[1], array3[2] }, meshName = (splitByMaterial ? text : text2) }; OBJFace item = objface3; list10.Add(item); if (array3.Length > 3) { List <OBJFace> list11 = list9; objface3 = new OBJFace { materialName = text, meshName = (splitByMaterial ? text : text2), indexes = new int[] { array3[2], array3[3], array3[0] } }; item = objface3; list11.Add(item); } } break; } } } if (list8.Count == 0) { list8.Add("default"); } GameObject gameObject = new GameObject("ModdedMap"); using (List <string> .Enumerator enumerator = list8.GetEnumerator()) { while (enumerator.MoveNext()) { string obj = enumerator.Current; GameObject gameObject2 = new GameObject(obj); gameObject2.transform.parent = gameObject.transform; gameObject2.transform.localScale = new Vector3(-1f, 1f, 1f); Mesh mesh = new Mesh(); mesh.name = obj; List <Vector3> list12 = new List <Vector3>(); List <Vector3> list13 = new List <Vector3>(); List <Vector2> list14 = new List <Vector2>(); List <int[]> list15 = new List <int[]>(); Dictionary <int, int> dictionary2 = new Dictionary <int, int>(); OBJLoader.meshMaterialNames = new List <string>(); OBJFace[] source = list9.Where(x => x.meshName == obj).ToArray <OBJFace>(); using (List <string> .Enumerator enumerator2 = list7.GetEnumerator()) { while (enumerator2.MoveNext()) { mn = enumerator2.Current; OBJFace[] array4 = source.Where(x => x.materialName == mn).ToArray <OBJFace>(); if (array4.Length != 0) { int[] array5 = new int[0]; foreach (OBJFace objface2 in array4) { int num4 = array5.Length; Array.Resize <int>(ref array5, num4 + objface2.indexes.Length); Array.Copy(objface2.indexes, 0, array5, num4, objface2.indexes.Length); } meshMaterialNames.Add(mn); if (mesh.subMeshCount != meshMaterialNames.Count) { mesh.subMeshCount = meshMaterialNames.Count; } for (int j = 0; j < array5.Length; j++) { int num5 = array5[j]; if (dictionary2.ContainsKey(num5)) { array5[j] = dictionary2[num5]; } else { list12.Add(list4[num5]); list13.Add(list5[num5]); list14.Add(list6[num5]); dictionary2[num5] = list12.Count - 1; array5[j] = dictionary2[num5]; } } list15.Add(array5); } } } mesh.SetVertices(list12); mesh.SetNormals(list13); mesh.SetUVs(0, list14); for (int k = 0; k < list15.Count; k++) { mesh.SetIndices(list15[k], MeshTopology.Triangles, k); } if (!flag2) { mesh.RecalculateNormals(); } mesh.RecalculateBounds(); Material[] array6 = new Material[meshMaterialNames.Count]; counter = 0; while (counter < meshMaterialNames.Count) { if (array == null) { Debug.Log("array null"); array6[counter] = new Material(Shader.Find("HDRP/Lit")); } else { Material[] array12 = array; Predicate <Material> match; if ((match = haha3) == null) { match = haha3 = new Predicate <Material>(LoadOBJFile3); } Material material = Array.Find(array12, match); Debug.Log(material); if (material == null) { Debug.Log("material null"); array6[counter] = new Material(Shader.Find("HDRP/Lit")); } else { array6[counter] = material; } } array6[counter].name = meshMaterialNames[counter]; int i2 = counter; counter = i2 + 1; } meshFilter = gameObject2.AddComponent <MeshFilter>(); meshRenderer = gameObject2.AddComponent <MeshRenderer>(); meshRenderer.receiveShadows = true; meshFilter.mesh = mesh; meshRenderer.materials = array6; if (MaterialLoader.alphaIsEnabled || alphaIsEnabledOld) { Renderer[] newRenderer = new Renderer[1]; newRenderer[0] = meshRenderer; LODGroup lods = gameObject2.AddComponent <LODGroup>(); LOD[] lod = new LOD[1]; lod[0].renderers = newRenderer; lod[0].screenRelativeTransitionHeight = 0.8f; lods.SetLODs(lod); lods.RecalculateBounds(); } if (!alphaIsEnabledOld) { meshCollider = gameObject2.AddComponent <MeshCollider>(); meshCollider.convex = false; meshCollider.sharedMesh = mesh; CarX.Material carXMaterial = gameObject2.AddComponent <CarX.Material>(); string objectParams = gameObject2.name.Split('_')[0].ToLower(); switch (objectParams) { case "road": Debug.Log("road set"); gameObject2.AddComponent <CARXSurface>(); carXMaterial.SetParameters(CarX.SurfaceType.Asphalt, 1, 0.01f, 0f, 0f, 100f, 0f, 0f, 100f); gameObject2.isStatic = true; break; case "kerb": Debug.Log("kerb set"); gameObject2.AddComponent <CARXSurface>(); carXMaterial.SetParameters(CarX.SurfaceType.Asphalt, 1, 0.015f, -0.007f, 0f, 12f, -0.007f, 0f, 12f); gameObject2.isStatic = true; break; case "sand": Debug.Log("sand set"); gameObject2.AddComponent <CARXSurface>(); carXMaterial.SetParameters(CarX.SurfaceType.Sand, 1, 0.13f, 0.06f, 0.05f, 25f, 0.06f, 0.05f, 25f); gameObject2.isStatic = true; break; case "snow": Debug.Log("snow set"); gameObject2.AddComponent <CARXSurface>(); carXMaterial.SetParameters(CarX.SurfaceType.Snow, 2, 0.1f, -0.01f, -0.01f, 30f, -0.01f, -0.01f, 30f); gameObject2.isStatic = true; break; case "grass": Debug.Log("grass set"); gameObject2.AddComponent <CARXSurface>(); carXMaterial.SetParameters(CarX.SurfaceType.Grass, 1, 0f, 0.05f, 0.04f, 25f, 0.05f, 0.04f, 25f); gameObject2.isStatic = true; break; case "gravel": Debug.Log("gravel set"); gameObject2.AddComponent <CARXSurface>(); carXMaterial.SetParameters(CarX.SurfaceType.Sand, 2, 0.1f, -0.01f, -0.01f, 30f, -0.01f, -0.01f, 30f); gameObject2.isStatic = true; break; case "icyroad": Debug.Log("icyroad set"); gameObject2.AddComponent <CARXSurface>(); carXMaterial.SetParameters(CarX.SurfaceType.Asphalt, 0.73f, 0.025f, 0f, 0f, 30f, 0f, 0f, 30f); gameObject2.isStatic = true; break; case "dirt": Debug.Log("dirt set"); gameObject2.AddComponent <CARXSurface>(); carXMaterial.SetParameters(CarX.SurfaceType.Earth, 1, 0.025f, -0.007f, 0f, 12f, -0.007f, 0f, 12f); gameObject2.isStatic = true; break; case "nocol": Debug.Log("nocol set"); meshCollider.enabled = false; gameObject2.isStatic = true; break; case "rb": Debug.Log("rb set"); gameObject2.transform.SetParent(null); meshCollider.convex = true; Rigidbody rb = gameObject2.AddComponent <Rigidbody>(); rbGos.Add(gameObject2); gameObject2.isStatic = false; break; default: gameObject2.AddComponent <CARXSurface>(); carXMaterial.SetParameters(CarX.SurfaceType.Asphalt, 1, 0.01f, 0f, 0f, 100f, 0f, 0f, 100f); gameObject2.isStatic = true; Debug.Log("Surface not set for this object"); break; } } gameObject2.layer = 11; } } return(gameObject); }