public Unity3mxLoader(PagedLOD parent) { Parent = parent; this.dir = parent.dir; this.loader = Loader.AbstractWebRequestLoader.CreateDefaultRequestLoader(dir); _TextureCache = new Dictionary <string, Texture2D>(); _MeshCache = new Dictionary <string, Mesh>(); _PointCloudCache = new Dictionary <string, Mesh>(); _meshTextureIdCache = new Dictionary <string, string>(); }
public PagedLOD(string name, string dir, PagedLOD parent) { this.dir = dir; this.Go = new GameObject(); this.Go.name = name; this.Go.transform.SetParent(parent.Go.transform, false); //this.Go.hideFlags = HideFlags.HideInHierarchy | HideFlags.HideInInspector; this.childrenStatus = ChildrenStatus.Unstaged; this.CommitedChildren = new List <PagedLOD>(); this.FrameNumberOfLastTraversal = -1; this.Depth = parent.Depth + 1; }
public IEnumerator Download(Promise <bool> loadComplete) { string url = UrlUtils.ReplaceDataProtocol(Url); string dir = UrlUtils.GetBaseUri(url); string file = UrlUtils.GetLastPathSegment(url); if (file.EndsWith(".3mxb", StringComparison.OrdinalIgnoreCase) || file.EndsWith(".3mx", StringComparison.OrdinalIgnoreCase)) { this.Root = new PagedLOD("root", dir, this.transform, 0); this.Root.unity3mxComponent = this; this.Root.MaxScreenDiameter = 0; this.Root.BoundingSphere = new TileBoundingSphere(new Vector3(0, 0, 0), 1e30f); this.Root.ChildrenFiles = new List <string>(); this.Root.ChildrenFiles.Add(file); yield return(null); } }
public IEnumerator LoadStreamCo(string relativeFilePath) { if (Parent.Go == null) { yield break; } yield return(this.loader.LoadStreamCo(relativeFilePath)); if (this.loader.LoadedStream.Length == 0) { LoadedStream = new MemoryStream(0); } else { using (BinaryReader br = new BinaryReader(this.loader.LoadedStream)) { if (relativeFilePath.EndsWith(".3mx", StringComparison.OrdinalIgnoreCase)) { string _3mxJson = new String(br.ReadChars((int)this.loader.LoadedStream.Length)); Schema._3mx _3mx = JsonConvert.DeserializeObject <Schema._3mx>(_3mxJson); PagedLOD commitedChild = new PagedLOD(_3mx.Layers[0].Id, Parent.dir, Parent); commitedChild.unity3mxComponent = Parent.unity3mxComponent; commitedChild.MaxScreenDiameter = 0; commitedChild.BoundingSphere = new TileBoundingSphere(new Vector3(0, 0, 0), 1e30f); commitedChild.ChildrenFiles = new List <string>(); commitedChild.ChildrenFiles.Add(_3mx.Layers[0].Root); Parent.CommitedChildren.Add(commitedChild); yield return(null); } else { #if DEBUG_TIME System.Diagnostics.Stopwatch swHeader = new System.Diagnostics.Stopwatch(); swHeader.Start(); #endif // Remove query parameters if there are any string filename = relativeFilePath.Split('?')[0]; const int magicNumberLen = 5; // magic number string magicNumber = new String(br.ReadChars((int)magicNumberLen)); if (magicNumber != "3MXBO") { Debug.LogError("Unsupported magic number in 3mxb file: " + magicNumber + " " + relativeFilePath); } // header size UInt32 headerSize = br.ReadUInt32(); if (headerSize == 0) { Debug.LogError("Unexpected zero length header in 3mxb file: " + relativeFilePath); } // header string headerJson = new String(br.ReadChars((int)headerSize)); Schema.Header3mxb header3mxb = JsonConvert.DeserializeObject <Schema.Header3mxb>(headerJson); #if DEBUG_TIME swHeader.Stop(); System.Diagnostics.Stopwatch swTexture = new System.Diagnostics.Stopwatch(); System.Diagnostics.Stopwatch swGeometry = new System.Diagnostics.Stopwatch(); #endif // resources for (int i = 0; i < header3mxb.Resources.Count; ++i) { Schema.Resource resource = header3mxb.Resources[i]; if (resource.Type == "textureBuffer" && resource.Format == "jpg") { #if DEBUG_TIME swTexture.Start(); #endif yield return(ConstructTexture(resource.Id, br, resource.Size)); #if DEBUG_TIME swTexture.Stop(); #endif } else if (resource.Type == "geometryBuffer" && resource.Format == "ctm") { #if DEBUG_TIME swGeometry.Start(); #endif yield return(ConstructMesh(resource.Id, br, resource.Size, new Vector3(resource.BBMin[0], resource.BBMin[2], resource.BBMin[1]), new Vector3(resource.BBMax[0], resource.BBMax[2], resource.BBMax[1]))); _meshTextureIdCache.Add(resource.Id, resource.Texture); #if DEBUG_TIME swGeometry.Stop(); #endif } else if (resource.Type == "geometryBuffer" && resource.Format == "xyz") { #if DEBUG_TIME swGeometry.Start(); #endif yield return(ConstructPointCloud(resource.Id, br, resource.Size, new Vector3(resource.BBMin[0], resource.BBMin[2], resource.BBMin[1]), new Vector3(resource.BBMax[0], resource.BBMax[2], resource.BBMax[1]))); #if DEBUG_TIME swGeometry.Stop(); #endif } else { Debug.LogError("Unexpected buffer type in 3mxb file: " + relativeFilePath); } } #if DEBUG_TIME System.Diagnostics.Stopwatch swNodes = new System.Diagnostics.Stopwatch(); swNodes.Start(); #endif // nodes for (int i = 0; i < header3mxb.Nodes.Count; ++i) { string url = UrlUtils.ReplaceDataProtocol(this.dir + relativeFilePath); string childDir = UrlUtils.GetBaseUri(url); Schema.Node node = header3mxb.Nodes[i]; PagedLOD commitedChild = new PagedLOD(node.Id, childDir, Parent); commitedChild.unity3mxComponent = Parent.unity3mxComponent; commitedChild.BBMin = new Vector3(node.BBMin[0], node.BBMin[2], node.BBMin[1]); commitedChild.BBMax = new Vector3(node.BBMax[0], node.BBMax[2], node.BBMax[1]); commitedChild.BoundingSphere = new TileBoundingSphere((commitedChild.BBMax + commitedChild.BBMin) / 2, (commitedChild.BBMax - commitedChild.BBMin).magnitude / 2); commitedChild.MaxScreenDiameter = node.MaxScreenDiameter; commitedChild.ChildrenFiles = node.Children; for (int j = 0; j < node.Resources.Count; ++j) { GameObject goSingleMesh = new GameObject(); goSingleMesh.name = "Drawable"; //goSingleMesh.hideFlags = HideFlags.HideInHierarchy | HideFlags.HideInInspector; goSingleMesh.transform.SetParent(commitedChild.Go.transform, false); MeshRenderer mr = goSingleMesh.AddComponent <MeshRenderer>(); mr.enabled = false; MeshFilter mf = goSingleMesh.AddComponent <MeshFilter>(); Mesh model; if (_MeshCache.TryGetValue(node.Resources[j], out model)) { mf.mesh = model; string textureId; if (_meshTextureIdCache.TryGetValue(node.Resources[j], out textureId)) { if (textureId != null) { Texture2D texture; _TextureCache.TryGetValue(textureId, out texture); mr.material.SetTexture("_MainTex", texture); } } } else if (_PointCloudCache.TryGetValue(node.Resources[j], out model)) { mf.mesh = model; } } commitedChild.renderers = commitedChild.Go.GetComponentsInChildren <MeshRenderer>(); Parent.CommitedChildren.Add(commitedChild); yield return(null); } if (!Parent.unity3mxComponent.HasBounds() && Parent.CommitedChildren.Count > 0) { Vector3 center = new Vector3(); Vector3 size = new Vector3(); bool hasBounds = false; { PagedLOD commitedChild = Parent.CommitedChildren[0]; center = (commitedChild.BBMax + commitedChild.BBMin) / 2; size = commitedChild.BBMax - commitedChild.BBMin; hasBounds = true; } if (hasBounds) { Bounds bounds = new Bounds(center, size); foreach (PagedLOD commitedChild in Parent.CommitedChildren) { bounds.Encapsulate(commitedChild.BBMin); bounds.Encapsulate(commitedChild.BBMax); } Parent.unity3mxComponent.SetBounds(bounds); } } #if DEBUG_TIME swNodes.Stop(); UnityEngine.Debug.Log(string.Format("Header: {0} ms, Texture: {1} ms, Geometry: {2} ms, Nodes: {3} m", swHeader.ElapsedMilliseconds, swTexture.ElapsedMilliseconds, swGeometry.ElapsedMilliseconds, swNodes.ElapsedMilliseconds)); #endif } } } Dispose(); }