| | 1 | | /* |
| | 2 | | (C) 2015 AARO4130 |
| | 3 | | DO NOT USE PARTS OF, OR THE ENTIRE SCRIPT, AND CLAIM AS YOUR OWN WORK |
| | 4 | | */ |
| | 5 | |
|
| | 6 | | using System; |
| | 7 | | using UnityEngine; |
| | 8 | | using System.Collections.Generic; |
| | 9 | | using System.IO; |
| | 10 | | using System.Linq; |
| | 11 | | #if UNITY_EDITOR |
| | 12 | | using UnityEditor; |
| | 13 | | #endif |
| | 14 | |
|
| | 15 | | public class OBJLoader |
| | 16 | | { |
| 1 | 17 | | public static bool splitByMaterial = false; |
| 1 | 18 | | public static string[] searchPaths = new string[] { "", "%FileName%_Textures" + Path.DirectorySeparatorChar }; |
| | 19 | | //structures |
| | 20 | | struct OBJFace |
| | 21 | | { |
| | 22 | | public string materialName; |
| | 23 | | public string meshName; |
| | 24 | | public int[] indexes; |
| | 25 | | } |
| | 26 | |
|
| | 27 | |
|
| | 28 | | //functions |
| | 29 | | #if UNITY_EDITOR |
| | 30 | | [MenuItem("GameObject/Import From OBJ")] |
| | 31 | | static void ObjLoadMenu() |
| | 32 | | { |
| 0 | 33 | | string pth = UnityEditor.EditorUtility.OpenFilePanel("Import OBJ", "", "obj"); |
| 0 | 34 | | if (!string.IsNullOrEmpty(pth)) |
| | 35 | | { |
| 0 | 36 | | System.Diagnostics.Stopwatch s = new System.Diagnostics.Stopwatch(); |
| 0 | 37 | | s.Start(); |
| 0 | 38 | | LoadOBJFile(pth); |
| 0 | 39 | | Debug.Log("OBJ load took " + s.ElapsedMilliseconds + "ms"); |
| 0 | 40 | | s.Stop(); |
| | 41 | | } |
| 0 | 42 | | } |
| | 43 | | #endif |
| | 44 | |
|
| | 45 | | public static Vector3 ParseVectorFromCMPS(string[] cmps) |
| | 46 | | { |
| 3644 | 47 | | float x = float.Parse(cmps[1]); |
| 3644 | 48 | | float y = float.Parse(cmps[2]); |
| 3644 | 49 | | if (cmps.Length == 4) |
| | 50 | | { |
| 3644 | 51 | | float z = float.Parse(cmps[3]); |
| 3644 | 52 | | return new Vector3(x, y, z); |
| | 53 | | } |
| 0 | 54 | | return new Vector2(x, y); |
| | 55 | | } |
| | 56 | |
|
| | 57 | | public static Color ParseColorFromCMPS(string[] cmps, float scalar = 1.0f) |
| | 58 | | { |
| 0 | 59 | | float Kr = float.Parse(cmps[1]) * scalar; |
| 0 | 60 | | float Kg = float.Parse(cmps[2]) * scalar; |
| 0 | 61 | | float Kb = float.Parse(cmps[3]) * scalar; |
| 0 | 62 | | return new Color(Kr, Kg, Kb); |
| | 63 | | } |
| | 64 | |
|
| | 65 | | public static string OBJGetFilePath(string path, string basePath, string fileName) |
| | 66 | | { |
| 0 | 67 | | foreach (string sp in searchPaths) |
| | 68 | | { |
| 0 | 69 | | string s = sp.Replace("%FileName%", fileName); |
| | 70 | |
|
| 0 | 71 | | if (File.Exists(basePath + s + path)) |
| | 72 | | { |
| 0 | 73 | | return basePath + s + path; |
| | 74 | | } |
| 0 | 75 | | else if (File.Exists(path)) |
| | 76 | | { |
| 0 | 77 | | return path; |
| | 78 | | } |
| | 79 | | } |
| | 80 | |
|
| 0 | 81 | | return null; |
| | 82 | | } |
| | 83 | |
|
| | 84 | | public static Material[] LoadMTLFile(string fn) |
| | 85 | | { |
| 0 | 86 | | Material currentMaterial = null; |
| 0 | 87 | | List<Material> matlList = new List<Material>(); |
| 0 | 88 | | FileInfo mtlFileInfo = new FileInfo(fn); |
| 0 | 89 | | string baseFileName = Path.GetFileNameWithoutExtension(fn); |
| 0 | 90 | | string mtlFileDirectory = mtlFileInfo.Directory.FullName + Path.DirectorySeparatorChar; |
| | 91 | |
|
| 0 | 92 | | foreach (string ln in File.ReadAllLines(fn)) |
| | 93 | | { |
| 0 | 94 | | string l = ln.Trim().Replace(" ", " "); |
| 0 | 95 | | string[] cmps = l.Split(' '); |
| 0 | 96 | | string data = l.Remove(0, l.IndexOf(' ') + 1); |
| | 97 | |
|
| 0 | 98 | | if (cmps[0] == "newmtl") |
| | 99 | | { |
| 0 | 100 | | if (currentMaterial != null) |
| | 101 | | { |
| 0 | 102 | | matlList.Add(currentMaterial); |
| | 103 | | } |
| | 104 | | //NOTE(Brian): This will get pink with LWRP? |
| 0 | 105 | | currentMaterial = new Material(Shader.Find("Standard (Specular setup)")); |
| 0 | 106 | | currentMaterial.name = data; |
| 0 | 107 | | } |
| 0 | 108 | | else if (cmps[0] == "Kd") |
| | 109 | | { |
| 0 | 110 | | currentMaterial.SetColor("_Color", ParseColorFromCMPS(cmps)); |
| 0 | 111 | | } |
| 0 | 112 | | else if (cmps[0] == "map_Kd") |
| | 113 | | { |
| | 114 | | //TEXTURE |
| 0 | 115 | | string fpth = OBJGetFilePath(data, mtlFileDirectory, baseFileName); |
| 0 | 116 | | if (fpth != null) |
| | 117 | | { |
| | 118 | | //NOTE(Brian): This will break because we don't download the textures? |
| 0 | 119 | | currentMaterial.SetTexture("_MainTex", TextureLoader.LoadTexture(fpth)); |
| | 120 | | } |
| 0 | 121 | | } |
| 0 | 122 | | else if (cmps[0] == "map_Bump") |
| | 123 | | { |
| | 124 | | //TEXTURE |
| 0 | 125 | | string fpth = OBJGetFilePath(data, mtlFileDirectory, baseFileName); |
| | 126 | |
|
| 0 | 127 | | if (fpth != null) |
| | 128 | | { |
| | 129 | | //NOTE(Brian): This will break because we don't download the textures? |
| 0 | 130 | | currentMaterial.SetTexture("_BumpMap", TextureLoader.LoadTexture(fpth, true)); |
| 0 | 131 | | currentMaterial.EnableKeyword("_NORMALMAP"); |
| | 132 | | } |
| 0 | 133 | | } |
| 0 | 134 | | else if (cmps[0] == "Ks") |
| | 135 | | { |
| 0 | 136 | | currentMaterial.SetColor("_SpecColor", ParseColorFromCMPS(cmps)); |
| 0 | 137 | | } |
| 0 | 138 | | else if (cmps[0] == "Ka") |
| | 139 | | { |
| 0 | 140 | | currentMaterial.SetColor("_EmissionColor", ParseColorFromCMPS(cmps, 0.05f)); |
| 0 | 141 | | currentMaterial.EnableKeyword("_EMISSION"); |
| 0 | 142 | | } |
| 0 | 143 | | else if (cmps[0] == "d") |
| | 144 | | { |
| 0 | 145 | | float visibility = float.Parse(cmps[1]); |
| 0 | 146 | | if (visibility < 1) |
| | 147 | | { |
| 0 | 148 | | Color temp = currentMaterial.color; |
| | 149 | |
|
| 0 | 150 | | temp.a = visibility; |
| 0 | 151 | | currentMaterial.SetColor("_Color", temp); |
| | 152 | |
|
| | 153 | | //TRANSPARENCY ENABLER |
| 0 | 154 | | currentMaterial.SetFloat("_Mode", 3); |
| 0 | 155 | | currentMaterial.SetInt("_SrcBlend", (int)UnityEngine.Rendering.BlendMode.SrcAlpha); |
| 0 | 156 | | currentMaterial.SetInt("_DstBlend", (int)UnityEngine.Rendering.BlendMode.OneMinusSrcAlpha); |
| 0 | 157 | | currentMaterial.SetInt("_ZWrite", 0); |
| 0 | 158 | | currentMaterial.DisableKeyword("_ALPHATEST_ON"); |
| 0 | 159 | | currentMaterial.EnableKeyword("_ALPHABLEND_ON"); |
| 0 | 160 | | currentMaterial.DisableKeyword("_ALPHAPREMULTIPLY_ON"); |
| 0 | 161 | | currentMaterial.renderQueue = 3000; |
| | 162 | | } |
| 0 | 163 | | } |
| 0 | 164 | | else if (cmps[0] == "Ns") |
| | 165 | | { |
| 0 | 166 | | float Ns = float.Parse(cmps[1]); |
| 0 | 167 | | Ns = (Ns / 1000); |
| 0 | 168 | | currentMaterial.SetFloat("_Glossiness", Ns); |
| | 169 | |
|
| | 170 | | } |
| | 171 | | } |
| | 172 | |
|
| 0 | 173 | | if (currentMaterial != null) |
| | 174 | | { |
| 0 | 175 | | matlList.Add(currentMaterial); |
| | 176 | | } |
| | 177 | |
|
| 0 | 178 | | return matlList.ToArray(); |
| | 179 | | } |
| | 180 | |
|
| | 181 | | public static GameObject LoadOBJFile(string filePath, bool inputIsRawOBJ = false) |
| | 182 | | { |
| | 183 | |
|
| 1 | 184 | | string meshName = !inputIsRawOBJ ? Path.GetFileNameWithoutExtension(filePath) : "LoadedOBJMesh"; |
| | 185 | |
|
| 1 | 186 | | bool hasNormals = false; |
| | 187 | | //OBJ LISTS |
| 1 | 188 | | List<Vector3> vertices = new List<Vector3>(); |
| 1 | 189 | | List<Vector3> normals = new List<Vector3>(); |
| 1 | 190 | | List<Vector2> uvs = new List<Vector2>(); |
| | 191 | | //UMESH LISTS |
| 1 | 192 | | List<Vector3> uvertices = new List<Vector3>(); |
| 1 | 193 | | List<Vector3> unormals = new List<Vector3>(); |
| 1 | 194 | | List<Vector2> uuvs = new List<Vector2>(); |
| | 195 | | //MESH CONSTRUCTION |
| 1 | 196 | | List<string> materialNames = new List<string>(); |
| 1 | 197 | | List<string> objectNames = new List<string>(); |
| 1 | 198 | | Dictionary<string, int> hashtable = new Dictionary<string, int>(); |
| 1 | 199 | | List<OBJFace> faceList = new List<OBJFace>(); |
| 1 | 200 | | string cmaterial = ""; |
| 1 | 201 | | string cmesh = "default"; |
| | 202 | |
|
| | 203 | | //CACHE |
| 1 | 204 | | Material[] materialCache = null; |
| | 205 | |
|
| | 206 | | //save this info for later |
| 1 | 207 | | FileInfo OBJFileInfo = null; |
| | 208 | |
|
| | 209 | | string[] OBJLines; |
| | 210 | |
|
| 1 | 211 | | if (!inputIsRawOBJ) |
| | 212 | | { |
| 0 | 213 | | OBJFileInfo = new FileInfo(filePath); |
| | 214 | |
|
| 0 | 215 | | OBJLines = File.ReadAllLines(filePath); |
| 0 | 216 | | } |
| | 217 | | else |
| | 218 | | { |
| 1 | 219 | | OBJLines = filePath.Split(new[] { "\r", "\n" }, StringSplitOptions.None); |
| | 220 | | } |
| | 221 | |
|
| 19938 | 222 | | foreach (string ln in OBJLines) |
| | 223 | | { |
| 9968 | 224 | | if (ln.Length > 0 && ln[0] != '#') |
| | 225 | | { |
| 9965 | 226 | | string l = ln.Trim().Replace(" ", " "); |
| 9965 | 227 | | string[] cmps = l.Split(' '); |
| 9965 | 228 | | string data = l.Remove(0, l.IndexOf(' ') + 1); |
| | 229 | |
|
| 9965 | 230 | | if (cmps[0] == "mtllib" && !inputIsRawOBJ && OBJFileInfo != null) |
| | 231 | | { |
| | 232 | | //load cache |
| 0 | 233 | | string pth = OBJGetFilePath(data, OBJFileInfo.Directory.FullName + Path.DirectorySeparatorChar, mesh |
| 0 | 234 | | if (pth != null) |
| | 235 | | { |
| 0 | 236 | | materialCache = LoadMTLFile(pth); |
| | 237 | | } |
| 0 | 238 | | } |
| 9965 | 239 | | else if ((cmps[0] == "g" || cmps[0] == "o") && splitByMaterial == false) |
| | 240 | | { |
| 0 | 241 | | cmesh = data; |
| 0 | 242 | | if (!objectNames.Contains(cmesh)) |
| | 243 | | { |
| 0 | 244 | | objectNames.Add(cmesh); |
| | 245 | | } |
| 0 | 246 | | } |
| 9965 | 247 | | else if (cmps[0] == "usemtl") |
| | 248 | | { |
| 1 | 249 | | cmaterial = data; |
| 1 | 250 | | if (!materialNames.Contains(cmaterial)) |
| | 251 | | { |
| 1 | 252 | | materialNames.Add(cmaterial); |
| | 253 | | } |
| | 254 | |
|
| 1 | 255 | | if (splitByMaterial) |
| | 256 | | { |
| 0 | 257 | | if (!objectNames.Contains(cmaterial)) |
| | 258 | | { |
| 0 | 259 | | objectNames.Add(cmaterial); |
| | 260 | | } |
| | 261 | | } |
| 0 | 262 | | } |
| 9964 | 263 | | else if (cmps[0] == "v") |
| | 264 | | { |
| | 265 | | //VERTEX |
| 3644 | 266 | | vertices.Add(ParseVectorFromCMPS(cmps)); |
| 3644 | 267 | | } |
| 6320 | 268 | | else if (cmps[0] == "vn") |
| | 269 | | { |
| | 270 | | //VERTEX NORMAL |
| 0 | 271 | | normals.Add(ParseVectorFromCMPS(cmps)); |
| 0 | 272 | | } |
| 6320 | 273 | | else if (cmps[0] == "vt") |
| | 274 | | { |
| | 275 | | //VERTEX UV |
| 0 | 276 | | uvs.Add(ParseVectorFromCMPS(cmps)); |
| 0 | 277 | | } |
| 6320 | 278 | | else if (cmps[0] == "f") |
| | 279 | | { |
| 6320 | 280 | | int[] indexes = new int[cmps.Length - 1]; |
| 50560 | 281 | | for (int i = 1; i < cmps.Length; i++) |
| | 282 | | { |
| 18960 | 283 | | string felement = cmps[i]; |
| 18960 | 284 | | int vertexIndex = -1; |
| 18960 | 285 | | int normalIndex = -1; |
| 18960 | 286 | | int uvIndex = -1; |
| 18960 | 287 | | if (felement.Contains("//")) |
| | 288 | | { |
| | 289 | | //doubleslash, no UVS. |
| 0 | 290 | | string[] elementComps = felement.Split('/'); |
| 0 | 291 | | vertexIndex = int.Parse(elementComps[0]) - 1; |
| 0 | 292 | | normalIndex = int.Parse(elementComps[2]) - 1; |
| 0 | 293 | | } |
| 88884 | 294 | | else if (felement.Count(x => x == '/') == 2) |
| | 295 | | { |
| | 296 | | //contains everything |
| 0 | 297 | | string[] elementComps = felement.Split('/'); |
| 0 | 298 | | vertexIndex = int.Parse(elementComps[0]) - 1; |
| 0 | 299 | | uvIndex = int.Parse(elementComps[1]) - 1; |
| 0 | 300 | | normalIndex = int.Parse(elementComps[2]) - 1; |
| 0 | 301 | | } |
| 18960 | 302 | | else if (!felement.Contains("/")) |
| | 303 | | { |
| | 304 | | //just vertex inedx |
| 18960 | 305 | | vertexIndex = int.Parse(felement) - 1; |
| 18960 | 306 | | } |
| | 307 | | else |
| | 308 | | { |
| | 309 | | //vertex and uv |
| 0 | 310 | | string[] elementComps = felement.Split('/'); |
| 0 | 311 | | vertexIndex = int.Parse(elementComps[0]) - 1; |
| 0 | 312 | | uvIndex = int.Parse(elementComps[1]) - 1; |
| | 313 | | } |
| 18960 | 314 | | string hashEntry = vertexIndex + "|" + normalIndex + "|" + uvIndex; |
| 18960 | 315 | | if (hashtable.ContainsKey(hashEntry)) |
| | 316 | | { |
| 15316 | 317 | | indexes[i - 1] = hashtable[hashEntry]; |
| 15316 | 318 | | } |
| | 319 | | else |
| | 320 | | { |
| | 321 | | //create a new hash entry |
| 3644 | 322 | | indexes[i - 1] = hashtable.Count; |
| 3644 | 323 | | hashtable[hashEntry] = hashtable.Count; |
| 3644 | 324 | | uvertices.Add(vertices[vertexIndex]); |
| 3644 | 325 | | if (normalIndex < 0 || (normalIndex > (normals.Count - 1))) |
| | 326 | | { |
| 3644 | 327 | | unormals.Add(Vector3.zero); |
| 3644 | 328 | | } |
| | 329 | | else |
| | 330 | | { |
| 0 | 331 | | hasNormals = true; |
| 0 | 332 | | unormals.Add(normals[normalIndex]); |
| | 333 | | } |
| 3644 | 334 | | if (uvIndex < 0 || (uvIndex > (uvs.Count - 1))) |
| | 335 | | { |
| 3644 | 336 | | uuvs.Add(Vector2.zero); |
| 3644 | 337 | | } |
| | 338 | | else |
| | 339 | | { |
| 0 | 340 | | uuvs.Add(uvs[uvIndex]); |
| | 341 | | } |
| | 342 | |
|
| | 343 | | } |
| | 344 | | } |
| 6320 | 345 | | if (indexes.Length < 5 && indexes.Length >= 3) |
| | 346 | | { |
| 6320 | 347 | | OBJFace f1 = new OBJFace(); |
| 6320 | 348 | | f1.materialName = cmaterial; |
| 6320 | 349 | | f1.indexes = new int[] { indexes[0], indexes[1], indexes[2] }; |
| 6320 | 350 | | f1.meshName = (splitByMaterial) ? cmaterial : cmesh; |
| 6320 | 351 | | faceList.Add(f1); |
| | 352 | |
|
| 6320 | 353 | | if (indexes.Length > 3) |
| | 354 | | { |
| 0 | 355 | | OBJFace f2 = new OBJFace(); |
| 0 | 356 | | f2.materialName = cmaterial; |
| 0 | 357 | | f2.meshName = (splitByMaterial) ? cmaterial : cmesh; |
| 0 | 358 | | f2.indexes = new int[] { indexes[2], indexes[3], indexes[0] }; |
| 0 | 359 | | faceList.Add(f2); |
| | 360 | | } |
| | 361 | | } |
| | 362 | | } |
| | 363 | | } |
| | 364 | | } |
| | 365 | |
|
| 1 | 366 | | if (objectNames.Count == 0) |
| | 367 | | { |
| 1 | 368 | | objectNames.Add("default"); |
| | 369 | | } |
| | 370 | |
|
| | 371 | | //build objects |
| 1 | 372 | | GameObject parentObject = new GameObject(meshName); |
| | 373 | |
|
| | 374 | |
|
| 4 | 375 | | for (int objectNamesIndex = 0; objectNamesIndex < objectNames.Count; objectNamesIndex++) |
| | 376 | | { |
| 1 | 377 | | string obj = objectNames[objectNamesIndex]; |
| 1 | 378 | | GameObject subObjectParent = new GameObject(obj); |
| 1 | 379 | | subObjectParent.transform.parent = parentObject.transform; |
| | 380 | |
|
| 1 | 381 | | GameObject subObject = new GameObject("ChildMesh"); |
| 1 | 382 | | subObject.transform.parent = subObjectParent.transform; |
| 1 | 383 | | subObject.transform.localScale = new Vector3(-1, 1, 1); |
| | 384 | | //Create mesh |
| 1 | 385 | | Mesh m = new Mesh(); |
| 1 | 386 | | m.name = obj; |
| | 387 | | //LISTS FOR REORDERING |
| 1 | 388 | | List<Vector3> processedVertices = new List<Vector3>(); |
| 1 | 389 | | List<Vector3> processedNormals = new List<Vector3>(); |
| 1 | 390 | | List<Vector2> processedUVs = new List<Vector2>(); |
| 1 | 391 | | List<int[]> processedIndexes = new List<int[]>(); |
| 1 | 392 | | Dictionary<int, int> remapTable = new Dictionary<int, int>(); |
| | 393 | | //POPULATE MESH |
| 1 | 394 | | List<string> meshMaterialNames = new List<string>(); |
| | 395 | |
|
| 6321 | 396 | | OBJFace[] ofaces = faceList.Where(x => x.meshName == obj).ToArray(); |
| | 397 | |
|
| 4 | 398 | | foreach (string mn in materialNames) |
| | 399 | | { |
| 6321 | 400 | | OBJFace[] faces = ofaces.Where(x => x.materialName == mn).ToArray(); |
| | 401 | |
|
| 1 | 402 | | if (faces.Length > 0) |
| | 403 | | { |
| 1 | 404 | | int[] indexes = new int[0]; |
| | 405 | |
|
| 12642 | 406 | | foreach (OBJFace f in faces) |
| | 407 | | { |
| 6320 | 408 | | int l = indexes.Length; |
| 6320 | 409 | | System.Array.Resize(ref indexes, l + f.indexes.Length); |
| 6320 | 410 | | System.Array.Copy(f.indexes, 0, indexes, l, f.indexes.Length); |
| | 411 | | } |
| | 412 | |
|
| 1 | 413 | | meshMaterialNames.Add(mn); |
| | 414 | |
|
| 1 | 415 | | if (m.subMeshCount != meshMaterialNames.Count) |
| | 416 | | { |
| 0 | 417 | | m.subMeshCount = meshMaterialNames.Count; |
| | 418 | | } |
| | 419 | |
|
| 37922 | 420 | | for (int i = 0; i < indexes.Length; i++) |
| | 421 | | { |
| 18960 | 422 | | int idx = indexes[i]; |
| | 423 | | //build remap table |
| 18960 | 424 | | if (remapTable.ContainsKey(idx)) |
| | 425 | | { |
| | 426 | | //ezpz |
| 15316 | 427 | | indexes[i] = remapTable[idx]; |
| 15316 | 428 | | } |
| | 429 | | else |
| | 430 | | { |
| 3644 | 431 | | processedVertices.Add(uvertices[idx]); |
| 3644 | 432 | | processedNormals.Add(unormals[idx]); |
| 3644 | 433 | | processedUVs.Add(uuvs[idx]); |
| 3644 | 434 | | remapTable[idx] = processedVertices.Count - 1; |
| 3644 | 435 | | indexes[i] = remapTable[idx]; |
| | 436 | | } |
| | 437 | | } |
| | 438 | |
|
| 1 | 439 | | processedIndexes.Add(indexes); |
| | 440 | | } |
| | 441 | | } |
| | 442 | |
|
| | 443 | | //apply stuff |
| 1 | 444 | | m.vertices = processedVertices.ToArray(); |
| 1 | 445 | | m.normals = processedNormals.ToArray(); |
| 1 | 446 | | m.uv = processedUVs.ToArray(); |
| | 447 | |
|
| 4 | 448 | | for (int i = 0; i < processedIndexes.Count; i++) |
| | 449 | | { |
| 1 | 450 | | m.SetTriangles(processedIndexes[i], i); |
| | 451 | | } |
| | 452 | |
|
| 1 | 453 | | if (!hasNormals) |
| | 454 | | { |
| 1 | 455 | | m.RecalculateNormals(); |
| | 456 | | } |
| | 457 | |
|
| 1 | 458 | | m.RecalculateBounds(); |
| | 459 | |
|
| 1 | 460 | | MeshFilter mf = subObject.AddComponent<MeshFilter>(); |
| 1 | 461 | | MeshRenderer mr = subObject.AddComponent<MeshRenderer>(); |
| | 462 | |
|
| 1 | 463 | | Material[] processedMaterials = new Material[meshMaterialNames.Count]; |
| | 464 | |
|
| 4 | 465 | | for (int i = 0; i < meshMaterialNames.Count; i++) |
| | 466 | | { |
| 1 | 467 | | if (materialCache == null) |
| | 468 | | { |
| 1 | 469 | | processedMaterials[i] = new Material(Shader.Find("Universal Render Pipeline/Simple Lit")); |
| 1 | 470 | | } |
| | 471 | | else |
| | 472 | | { |
| 0 | 473 | | Material mfn = Array.Find(materialCache, x => x.name == meshMaterialNames[i]); |
| | 474 | |
|
| 0 | 475 | | if (mfn == null) |
| | 476 | | { |
| 0 | 477 | | processedMaterials[i] = new Material(Shader.Find("Universal Render Pipeline/Simple Lit")); |
| 0 | 478 | | } |
| | 479 | | else |
| | 480 | | { |
| 0 | 481 | | processedMaterials[i] = mfn; |
| | 482 | | } |
| | 483 | | } |
| | 484 | |
|
| 1 | 485 | | processedMaterials[i].name = meshMaterialNames[i]; |
| | 486 | | } |
| | 487 | |
|
| 1 | 488 | | mr.materials = processedMaterials; |
| 1 | 489 | | mf.mesh = m; |
| | 490 | |
|
| | 491 | | } |
| | 492 | |
|
| 1 | 493 | | return parentObject; |
| | 494 | | } |
| | 495 | | } |