implemented asynchronous loading of 3d models when poi is activated
This commit is contained in:
@@ -27,6 +27,10 @@ namespace RothenburgAR
|
||||
|
||||
InputManager.Instance.Initialize();
|
||||
var init = DisplayManager.Instance;
|
||||
|
||||
//OBJLoader.defaultShader = Shader.Find("Standard (Specular setup)")
|
||||
OBJLoader.defaultShader = Shader.Find("Standard");
|
||||
OBJLoader.defaultMaterial = new Material(OBJLoader.defaultShader);
|
||||
}
|
||||
|
||||
void InitializeData()
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace RothenburgAR.PointOfInterest
|
||||
var poiIds = exhibits.Values.SelectMany(l => l.SelectMany(e => e.Pois.Select(p => p.Id))).Distinct().ToList();
|
||||
|
||||
Dictionary<string, List<Poi>> poisPerLang = new Dictionary<string, List<Poi>>();
|
||||
exhibits.Keys.ToList().ForEach(k =>
|
||||
exhibits.Keys.ToList().ForEach(k =>
|
||||
poisPerLang.Add(k, exhibits[k].SelectMany(l => l.Pois.Select(p => p)).Distinct().ToList()));
|
||||
|
||||
foreach (var poiID in poiIds)
|
||||
@@ -75,7 +75,7 @@ namespace RothenburgAR.PointOfInterest
|
||||
if (mediaID != null)
|
||||
{
|
||||
var modelDescription = new PoiModelDescription();
|
||||
modelDescription.ModelPath = mediaID;
|
||||
modelDescription.ModelPath = PathHelper.CombinePaths(PathHelper.MediaPath, mediaID, mediaID + ".obj");
|
||||
|
||||
//TODO dont have model size information, find a way to scale model to fit into view?
|
||||
modelDescription.ModelPrefabName = string.Empty;
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
using RothenburgAR.Common;
|
||||
using System.Collections;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RothenburgAR.PointOfInterest
|
||||
@@ -21,6 +24,48 @@ namespace RothenburgAR.PointOfInterest
|
||||
get { return ModelDescription.ModelPath != null; }
|
||||
}
|
||||
|
||||
public bool IsModelLoaded
|
||||
{
|
||||
get
|
||||
{
|
||||
return _modelPrefab != null;
|
||||
}
|
||||
}
|
||||
|
||||
public IEnumerator LoadModel()
|
||||
{
|
||||
if (!File.Exists(ModelDescription.ModelPath))
|
||||
{
|
||||
throw new FileNotFoundException(ModelDescription.ModelPath + " does not exist;");
|
||||
}
|
||||
|
||||
var loader = new OBJLoader(ModelDescription.ModelPath);
|
||||
|
||||
//TODO do this in new thread
|
||||
ThreadStart start = new ThreadStart(loader.ParseObjFile);
|
||||
Thread t = new Thread(start);
|
||||
t.Start();
|
||||
|
||||
while (t.ThreadState != ThreadState.Stopped)
|
||||
{
|
||||
Debug.Log("loading model from subthread");
|
||||
yield return null;
|
||||
}
|
||||
Debug.Log("loaded model from subthread");
|
||||
|
||||
//TODO wait for thread finish with yield return null
|
||||
var model = loader.BuildUnityObjects();
|
||||
|
||||
if (!model)
|
||||
{
|
||||
Debug.LogError("Failed to load Model!");
|
||||
}
|
||||
|
||||
|
||||
model.SetActive(false);
|
||||
_modelPrefab = model;
|
||||
}
|
||||
|
||||
public GameObject GetModelPrefab()
|
||||
{
|
||||
if (!HasModelDescription)
|
||||
@@ -28,8 +73,7 @@ namespace RothenburgAR.PointOfInterest
|
||||
if (_modelPrefab != null)
|
||||
return _modelPrefab;
|
||||
|
||||
_modelPrefab = new PoiModelLoader().LoadModel(ModelDescription);
|
||||
_modelPrefab.SetActive(false);
|
||||
LoadModel();
|
||||
return _modelPrefab;
|
||||
}
|
||||
|
||||
@@ -38,7 +82,7 @@ namespace RothenburgAR.PointOfInterest
|
||||
if (!HasModelDescription)
|
||||
return null;
|
||||
var modelPrefab = GetModelPrefab();
|
||||
var gameObject = UnityEngine.Object.Instantiate(modelPrefab);
|
||||
var gameObject = GameObject.Instantiate(modelPrefab);
|
||||
|
||||
gameObject.SetActive(true);
|
||||
gameObject.transform.localRotation = Quaternion.identity;
|
||||
@@ -46,7 +90,7 @@ namespace RothenburgAR.PointOfInterest
|
||||
|
||||
var modelGO = gameObject.transform.GetChild(0);
|
||||
modelGO.transform.eulerAngles = ModelDescription.Rotation;
|
||||
modelGO.gameObject.layer = LayerMask.NameToLayer("UIModel");
|
||||
modelGO.gameObject.layer = LayerMask.NameToLayer("UIModel");
|
||||
|
||||
return gameObject;
|
||||
}
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
using RothenburgAR.Common;
|
||||
using System.IO;
|
||||
using UnityEngine;
|
||||
|
||||
namespace RothenburgAR.PointOfInterest
|
||||
{
|
||||
class PoiModelLoader
|
||||
{
|
||||
public GameObject LoadModel(PoiModelDescription description)
|
||||
{
|
||||
var path = PathHelper.CombinePaths(PathHelper.MediaPath, description.ModelPath, description.ModelPath + ".obj");
|
||||
if (!File.Exists(path))
|
||||
{
|
||||
throw new FileNotFoundException(description.ModelPath + " does not exist;");
|
||||
}
|
||||
|
||||
return OBJLoader.LoadOBJFile(path);
|
||||
|
||||
var asset = AssetBundle.LoadFromFile(description.ModelPath);
|
||||
if (!asset)
|
||||
{
|
||||
Debug.Log("Failed to load AssetBundle!");
|
||||
return null;
|
||||
}
|
||||
|
||||
var prefab = asset.LoadAsset(description.ModelPrefabName) as GameObject;
|
||||
|
||||
prefab.transform.localScale = description.Scale;
|
||||
prefab.transform.localPosition = description.Position;
|
||||
prefab.transform.Rotate(description.Rotation);
|
||||
return prefab;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7ba5d1ae3dd7b284a99ab7858988692b
|
||||
timeCreated: 1505023463
|
||||
licenseType: Free
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -70,7 +70,7 @@ namespace RothenburgAR.PointOfInterest
|
||||
|
||||
var poiModelDescription = new PoiModelDescription
|
||||
{
|
||||
ModelPath = pathNode.Attributes["value"].Value,
|
||||
ModelPath = PathHelper.CombinePaths(PathHelper.MediaPath, pathNode.Attributes["value"].Value, pathNode.Attributes["value"].Value + ".obj"),
|
||||
ModelPrefabName = pathNode.Attributes["prefabName"].Value,
|
||||
Scale = GetVector3FromXmlNode(scaleNode).GetValueOrDefault(Vector3.one),
|
||||
Rotation = GetVector3FromXmlNode(rotationNode).GetValueOrDefault(Vector3.zero),
|
||||
|
||||
@@ -30,21 +30,20 @@ namespace RothenburgAR.UI
|
||||
|
||||
if (data.HasModelDescription)
|
||||
DetailsPanel.SetModelFromPoi(data);
|
||||
|
||||
|
||||
DetailsPanel.UpdateOpeningAnimation(poi.transform.position);
|
||||
|
||||
|
||||
poi.SetActive(true);
|
||||
|
||||
ProjectionEffect.SelectedPOI = poi.gameObject;
|
||||
ProjectionEffect.SetActive(true);
|
||||
}
|
||||
|
||||
|
||||
public void HidePoiDetails()
|
||||
{
|
||||
DetailsPanel.gameObject.SetActive(false);
|
||||
ProjectionEffect.SetActive(false);
|
||||
|
||||
|
||||
if (ProjectionEffect.SelectedPOI != null)
|
||||
{
|
||||
var poi = ProjectionEffect.SelectedPOI.GetComponent<PoiBehaviour>();
|
||||
|
||||
@@ -5,6 +5,8 @@ using TMPro;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UI;
|
||||
using UnityEngine.EventSystems;
|
||||
using System.Collections;
|
||||
using System.Threading;
|
||||
|
||||
namespace RothenburgAR.UI
|
||||
{
|
||||
@@ -24,6 +26,7 @@ namespace RothenburgAR.UI
|
||||
get { return _currentDisplayedModelGo != null; }
|
||||
}
|
||||
|
||||
private string modelToBeDisplayed = null;
|
||||
private GameObject _currentDisplayedModelGo;
|
||||
|
||||
public void SetText(TextElement el)
|
||||
@@ -34,14 +37,52 @@ namespace RothenburgAR.UI
|
||||
public void SetText(String el)
|
||||
{
|
||||
DetailsText.text = el;
|
||||
|
||||
|
||||
// Scroll to top
|
||||
DetailsTextScrollRect.normalizedPosition = new Vector2(0, 1);
|
||||
}
|
||||
|
||||
public void SetModelFromPoi(PoiData data)
|
||||
{
|
||||
if (!data.HasModelDescription) return;
|
||||
|
||||
StartCoroutine("SetModelCoroutine", data);
|
||||
}
|
||||
|
||||
public IEnumerator SetModelCoroutine(PoiData data)
|
||||
{
|
||||
modelToBeDisplayed = data.ID;
|
||||
|
||||
if (!data.IsModelLoaded)
|
||||
{
|
||||
Debug.Log("Model not loaded, starting thread...");
|
||||
StartCoroutine(data.LoadModel());
|
||||
|
||||
while (!data.IsModelLoaded)
|
||||
{
|
||||
// display loading icon or sth idk
|
||||
Debug.Log("waiting for data to be loaded..");
|
||||
yield return null;
|
||||
}
|
||||
|
||||
Debug.Log("exited while loop");
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
if (modelToBeDisplayed == data.ID)
|
||||
SetModel(data.InstantiateModelPrefab());
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignore, just do not display an object
|
||||
_currentDisplayedModelGo = null;
|
||||
modelToBeDisplayed = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void SetModel(GameObject modelGo)
|
||||
{
|
||||
RemoveModel();
|
||||
modelGo.transform.SetParent(UIManager.Instance.UIObjectCamera.transform, false);
|
||||
modelGo.transform.localPosition += new Vector3(0, 0, 450);
|
||||
|
||||
@@ -51,24 +92,11 @@ namespace RothenburgAR.UI
|
||||
DetailsModel.gameObject.SetActive(true);
|
||||
}
|
||||
|
||||
public void SetModelFromPoi(PoiData data)
|
||||
{
|
||||
if (!data.HasModelDescription) return;
|
||||
try
|
||||
{
|
||||
SetModel(data.InstantiateModelPrefab());
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// ignore, just do not display an object
|
||||
_currentDisplayedModelGo = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void RemoveModel()
|
||||
{
|
||||
DetailsModel.gameObject.SetActive(false);
|
||||
DetailsModel.CurrentModel = null;
|
||||
modelToBeDisplayed = null;
|
||||
if (HasModel)
|
||||
{
|
||||
Destroy(_currentDisplayedModelGo);
|
||||
|
||||
Reference in New Issue
Block a user