implemented asynchronous loading of 3d models when poi is activated

This commit is contained in:
2018-09-27 20:02:34 +02:00
parent 43ced99445
commit 93006f880c
9 changed files with 164 additions and 111 deletions

View File

@@ -19,6 +19,8 @@ public class OBJLoader
{
public static bool splitByMaterial = false;
public static string[] searchPaths = new string[] { "", "%FileName%_Textures" + Path.DirectorySeparatorChar };
public static Material defaultMaterial;
public static Shader defaultShader;
//structures
struct OBJFace
@@ -38,14 +40,14 @@ public class OBJLoader
{
System.Diagnostics.Stopwatch s = new System.Diagnostics.Stopwatch();
s.Start();
LoadOBJFile(pth);
new OBJLoader(pth).LoadOBJFile();
Debug.Log("OBJ load took " + s.ElapsedMilliseconds + "ms");
s.Stop();
}
}
#endif
public static Vector3 ParseVectorFromCMPS(string[] cmps)
private Vector3 ParseVectorFromCMPS(string[] cmps)
{
float x = float.Parse(cmps[1]);
float y = float.Parse(cmps[2]);
@@ -57,7 +59,7 @@ public class OBJLoader
return new Vector2(x, y);
}
public static Color ParseColorFromCMPS(string[] cmps, float scalar = 1.0f)
private Color ParseColorFromCMPS(string[] cmps, float scalar = 1.0f)
{
float Kr = float.Parse(cmps[1]) * scalar;
float Kg = float.Parse(cmps[2]) * scalar;
@@ -83,7 +85,12 @@ public class OBJLoader
return null;
}
public static Material[] LoadMTLFile(string fn)
public OBJLoader(string filePath)
{
this.filePath = filePath;
}
private Material[] LoadMTLFile(string fn)
{
Material currentMaterial = null;
List<Material> matlList = new List<Material>();
@@ -103,8 +110,7 @@ public class OBJLoader
matlList.Add(currentMaterial);
}
//currentMaterial = new Material(Shader.Find("Standard (Specular setup)"));
currentMaterial = new Material(Shader.Find("Standard"));
currentMaterial = new Material(defaultShader);
currentMaterial.name = data;
}
else if (cmps[0] == "Kd")
@@ -174,36 +180,47 @@ public class OBJLoader
return matlList.ToArray();
}
public static GameObject LoadOBJFile(string fn)
private string filePath;
private string meshName;
private bool hasNormals = false;
//OBJ LISTS
private List<Vector3> vertices = new List<Vector3>();
private List<Vector3> normals = new List<Vector3>();
private List<Vector2> uvs = new List<Vector2>();
//UMESH LISTS
private List<Vector3> uvertices = new List<Vector3>();
private List<Vector3> unormals = new List<Vector3>();
private List<Vector2> uuvs = new List<Vector2>();
//MESH CONSTRUCTION
private List<string> materialNames = new List<string>();
private List<string> objectNames = new List<string>();
private Dictionary<string, int> hashtable = new Dictionary<string, int>();
private List<OBJFace> faceList = new List<OBJFace>();
private string cmaterial = "";
private string cmesh = "default";
//CACHE
private List<string> mtlFiles = new List<string>();
private List<Material> materialCache = new List<Material>();
public GameObject LoadOBJFile()
{
string meshName = Path.GetFileNameWithoutExtension(fn);
bool hasNormals = false;
ParseObjFile();
GameObject parentObject = BuildUnityObjects();
//OBJ LISTS
List<Vector3> vertices = new List<Vector3>();
List<Vector3> normals = new List<Vector3>();
List<Vector2> uvs = new List<Vector2>();
return parentObject;
}
//UMESH LISTS
List<Vector3> uvertices = new List<Vector3>();
List<Vector3> unormals = new List<Vector3>();
List<Vector2> uuvs = new List<Vector2>();
public void ParseObjFile()
{
meshName = Path.GetFileNameWithoutExtension(filePath);
FileInfo OBJFileInfo = new FileInfo(filePath);
//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))
foreach (string ln in File.ReadAllLines(filePath))
{
if (ln.Length > 0 && ln[0] != '#')
{
@@ -216,7 +233,7 @@ public class OBJLoader
//load cache
string pth = OBJGetFilePath(data, OBJFileInfo.Directory.FullName + Path.DirectorySeparatorChar, meshName);
if (pth != null)
materialCache = LoadMTLFile(pth);
mtlFiles.Add(pth);
}
else if ((cmps[0] == "g" || cmps[0] == "o") && splitByMaterial == false)
{
@@ -345,10 +362,17 @@ public class OBJLoader
if (objectNames.Count == 0)
objectNames.Add("default");
}
public GameObject BuildUnityObjects()
{
//build objects
GameObject parentObject = new GameObject(meshName);
foreach (var matfile in mtlFiles)
{
materialCache.AddRange(LoadMTLFile(matfile));
}
foreach (string obj in objectNames)
{
GameObject subObject = new GameObject(obj);
@@ -380,7 +404,7 @@ public class OBJLoader
m.subMeshCount = meshMaterialNames.Count;
var indexes = faces.SelectMany(f => f.indexes).ToArray();
for (int i = 0; i < indexes.Length; i++)
{
int idx = indexes[i];
@@ -428,14 +452,14 @@ public class OBJLoader
{
if (materialCache == null)
{
processedMaterials[i] = new Material(Shader.Find("Standard (Specular setup)"));
processedMaterials[i] = defaultMaterial;
}
else
{
Material mfn = Array.Find(materialCache, x => x.name == meshMaterialNames[i]); ;
Material mfn = materialCache.Find(x => x.name == meshMaterialNames[i]);
if (mfn == null)
{
processedMaterials[i] = new Material(Shader.Find("Standard (Specular setup)"));
processedMaterials[i] = defaultMaterial;
}
else
{