protected void requestMeshes(object sender, IRequestInterface args) // Only works with the v2 server using the v1 API // Meshes are safe because they will be called only once { MeshesRequest reqObj = args as MeshesRequest; HashSet <int> collectIds = new HashSet <int> (); foreach (Eppy.Tuple <int, int, OpenCTM.Mesh> item in reqObj._openctm) { collectIds.Add(item.Item1); } string dbIds = string.Join(",", collectIds); reqObj.uri = new System.Uri(ForgeLoaderConstants._endpoint + URN + "/meshes/" + dbIds); //UnityEngine.Debug.Log ("URI request: " + reqObj.uri.ToString ()); _mgr.Register(reqObj); }
public override GameObject BuildScene(string name, bool saveToDisk = false) { try { foreach (Eppy.Tuple <int, int, OpenCTM.Mesh> openctm in _openctm) { OpenCTM.Mesh ctmMesh = openctm.Item3; if (ctmMesh == null || ctmMesh.getVertexCount() == 0 || ctmMesh.getTriangleCount() == 0) { state = SceneLoadingStatus.eCancelled; return(gameObject); } Eppy.Tuple <int, int, GameObject, JSONNode> item = fragments.Single(x => x.Item1 == openctm.Item2); GameObject meshObject = item.Item3; Mesh mesh = new Mesh(); Vector3 [] vertices = MeshesRequest.getAsVector3(ctmMesh.vertices); mesh.vertices = vertices; mesh.triangles = ctmMesh.indices; if (ctmMesh.hasNormals()) { mesh.normals = MeshesRequest.getAsVector3(ctmMesh.normals); } for (int i = 0; i < ctmMesh.getUVCount(); i++) { mesh.SetUVs(i, MeshesRequest.getAsVector2List(ctmMesh.texcoordinates [i].values)); } mesh.RecalculateNormals(); mesh.RecalculateBounds(); MeshFilter filter = meshObject.AddComponent <MeshFilter> (); filter.sharedMesh = mesh; MeshRenderer renderer = meshObject.AddComponent <MeshRenderer> (); renderer.sharedMaterial = ForgeLoaderEngine.GetDefaultMaterial(); if (createCollider) { MeshCollider collider = meshObject.AddComponent <MeshCollider> (); collider.sharedMesh = mesh; } #if UNITY_EDITOR if (saveToDisk) { AssetDatabase.CreateAsset(mesh, ForgeConstants._resourcesPath + this.loader.PROJECTID + "/" + GetName(openctm.Item1, openctm.Item2) + ".asset"); //AssetDatabase.SaveAssets () ; //AssetDatabase.Refresh () ; //mesh =AssetDatabase.LoadAssetAtPath<Mesh> (ForgeConstants._resourcesPath + this.loader.PROJECTID + "/" + name + ".asset") ; } #endif // Add our material to the queue loader.GetMgr()._materials.Add(item.Item2); //if ( loader.GetMgr ()._materials.Add (item.Item2) ) { // MaterialRequest req = new MaterialRequest (loader, null, bearer, item.Item2, item.Item4); // req.gameObject = meshObject; // if ( fireRequestCallback != null ) // fireRequestCallback (this, req); //} } base.BuildScene(name, saveToDisk); state = SceneLoadingStatus.eWaitingMaterial; } catch (Exception ex) { Debug.Log(ForgeLoader.GetCurrentMethod() + " " + ex.Message); state = SceneLoadingStatus.eError; } return(gameObject); }
public virtual void Update() { //UnityEngine.Profiling.Profiler.BeginSample ("Forge AR|VR Toolkit"); if (!Active) { return; } // Do we got more requests to fire? int pending = _mgr.Count(SceneLoadingStatus.ePending); if (pending < ForgeLoaderConstants.NB_MAX_REQUESTS) { RequestQueueMgrEnumerator news = _mgr.GetTypeEnumerator(SceneLoadingStatus.eNew); pending = _mgr.Count(SceneLoadingStatus.eNew); if (news.MoveNext()) { //UnityEngine.Debug.Log (DateTime.Now.ToString ("HH:mm:ss.f") + " / " + ((IRequestInterface)news.Current).uri.ToString ()); _mgr.FireRequest(news.Current); } } // For each request we got an answer for, we build the corresponding scene object RequestQueueMgrEnumerator items = _mgr.GetCompletedEnumerator(); while (items.MoveNext()) { IRequestInterface item = items.Current; if (item.resolved == SceneLoadingStatus.eInstanceTree) { item.fireRequestCallback += requestSceneObjectDetails; } //else if ( item.resolved == SceneLoadingStatus.eMesh ) // item.fireRequestCallback += requestMaterials; else if (item.resolved == SceneLoadingStatus.eMaterial) { item.fireRequestCallback += requestTextures; } GameObject obj = item.BuildScene( item.resolved == SceneLoadingStatus.eInstanceTree ? SCENEID : item.GetName(), SaveToDisk ); if (obj != null && item.resolved == SceneLoadingStatus.eInstanceTree) { if (ROOT == null) { ROOT = obj; } else { obj.transform.parent = ROOT.transform; obj.transform.localPosition = Vector3.zero; } } else if (item.resolved == SceneLoadingStatus.eMaterial) { _materialLib = (item as MaterialsRequest).materials; // Safe as we make only 1 request for all materials // otherwise, _materialLib.Add ((item as MaterialRequest).matId, (item as MaterialRequest).material) ; } else if (item.resolved == SceneLoadingStatus.eProperties) { foreach (KeyValuePair <int, ForgeProperties> props in (item as PropertiesRequest2).properties) { _properties.Add(props.Key, props.Value); } // otherwise, _properties.Add ((item as PropertiesRequest).dbId, (item as PropertiesRequest).properties); // Safe as we make only 1 request per propertyset } // else if ( item.resolved == SceneLoadingStatus.eTexture ) } // Assign Material to Mesh waiting for it items = _mgr.GetTypeEnumerator(SceneLoadingStatus.eWaitingMaterial); while (items.MoveNext()) { MeshesRequest item = items.Current as MeshesRequest; int nb = 0; foreach (Eppy.Tuple <int, int, GameObject, JSONNode> fragment in item.fragments) { if (!_materialLib.ContainsKey(fragment.Item2)) { continue; } nb++; MeshRenderer renderer = fragment.Item3.GetComponent <MeshRenderer> (); renderer.sharedMaterial = _materialLib [fragment.Item2]; } if (nb == item.fragments.Count) { item.state = item.resolved; } } // Showing progress if (ProcessedNodes != null) { int total = _mgr.Count(); int built = _mgr.Count(new SceneLoadingStatus [] { SceneLoadingStatus.eInstanceTree, SceneLoadingStatus.eMesh, SceneLoadingStatus.eMaterial, SceneLoadingStatus.eTexture, SceneLoadingStatus.eProperties, SceneLoadingStatus.eWaitingMaterial, SceneLoadingStatus.eWaitingTexture }); int completed = _mgr.Count(SceneLoadingStatus.eReceived); float val = 100.0f * Math.Min(completed + built, total) / total; ProcessedNodes(this, val); if (ProcessingNodesCompleted != null) { built = _mgr.Count(new SceneLoadingStatus [] { SceneLoadingStatus.eInstanceTree, SceneLoadingStatus.eMesh, SceneLoadingStatus.eMaterial, SceneLoadingStatus.eTexture, SceneLoadingStatus.eProperties, }); int unprocessed = _mgr.Count(new SceneLoadingStatus [] { SceneLoadingStatus.eCancelled, SceneLoadingStatus.eError, }); if (built + unprocessed == total) { ProcessingNodesCompleted(this, unprocessed); TimeSpan tm = DateTime.Now - started; UnityEngine.Debug.Log(URN + "-" + SCENEID + " loaded in: " + tm.TotalSeconds.ToString()); Sleep(); // Sleep ourself } } } //UnityEngine.Profiling.Profiler.EndSample (); }
public override GameObject BuildScene(string name, bool saveToDisk = false) { Clear(); GameObject pivot = null; try { gameObject = new GameObject(name); if (lmvtkDef == null) { return(null); } ForgeProperties properties = gameObject.AddComponent <ForgeProperties> (); properties.Properties = lmvtkDef ["metadata"]; foreach (JSONNode child in lmvtkDef["childs"].AsArray) { IteratorNodes(child, gameObject); } base.BuildScene(name, saveToDisk); pivot = ForgeLoaderEngine.SetupForSceneOrientationAndUnits(gameObject, properties.Properties); // Create as much Meshes requests we need to load chunks of 0.5Mb-0.7Mb pack files // 1-499 polys = factor of 25 // >500 poly = factor of 17 int compSize = 0; List <Eppy.Tuple <int, int> > components = new List <Eppy.Tuple <int, int> > (); List <Eppy.Tuple <int, int, GameObject, JSONNode> > fragments = new List <Eppy.Tuple <int, int, GameObject, JSONNode> > (); foreach (KeyValuePair <int, InstanceTreeData> data in _components) { //if ( data.Value.fragments.Count == 0 ) //continue; foreach (Eppy.Tuple <int, int, GameObject, JSONNode> frag in data.Value.fragments) { JSONArray json = frag.Item4 ["fragments"].AsArray; JSONArray json2 = frag.Item4 ["fragPolys"].AsArray; int index = 0; for ( ; index < json.Count && json [index].AsInt != frag.Item1; index++) { } if (index >= json2.Count) { continue; } compSize += json2 [index].AsInt; //Debug.Log (data.Key + "-" + frag.Item1 + " " + json2 [index].AsInt); components.Add(new Eppy.Tuple <int, int> (data.Key, frag.Item1)); fragments.Add(frag); } if (compSize > 29411 /* 29411 * 17 = 500kb */) { MeshesRequest reqMeshes = new MeshesRequest(loader, null, bearer, components, fragments, null); reqMeshes.gameObject = null; if (fireRequestCallback != null) { fireRequestCallback(this, reqMeshes); } compSize = 0; components = new List <Eppy.Tuple <int, int> > (); fragments = new List <Eppy.Tuple <int, int, GameObject, JSONNode> > (); } } if (components.Count > 0) { MeshesRequest reqMeshes = new MeshesRequest(loader, null, bearer, components, fragments, null); reqMeshes.gameObject = null; if (fireRequestCallback != null) { fireRequestCallback(this, reqMeshes); } } if (loader.GetMgr()._materials.Count > 0) { MaterialsRequest reqMaterials = new MaterialsRequest(loader, null, bearer, loader.GetMgr()._materials, lmvtkDef); reqMaterials.gameObject = null; if (fireRequestCallback != null) { fireRequestCallback(this, reqMaterials); } } // Textures will be requested by the material request (one by one) // Now Properties int [] dbIds = _components.Keys.ToArray(); int [] [] chunks = dbIds .Select((s, i) => new { Value = s, Index = i }) .GroupBy(x => x.Index / 100) .Select(grp => grp.Select(x => x.Value).ToArray()) .ToArray(); for (int i = 0; i < chunks.Length; i++) { List <Eppy.Tuple <int, GameObject> > dbIdsTuple = new List <Eppy.Tuple <int, GameObject> > (); foreach (int dbId in chunks[i]) { dbIdsTuple.Add(new Eppy.Tuple <int, GameObject> (dbId, _components [dbId].obj)); } PropertiesRequest2 reqProps = new PropertiesRequest2(loader, null, bearer, dbIdsTuple); reqProps.gameObject = null; if (fireRequestCallback != null) { fireRequestCallback(this, reqProps); } } Clear(); } catch (Exception /*ex*/) { if (gameObject) { GameObject.DestroyImmediate(gameObject); } gameObject = null; pivot = null; } return(pivot); }