//Add GameObjects to dictionary // Traverse function iterates the scene graph to build local branches on Unity GameObject Traverse(Node n, Material currentMaterial) { // We must be called in edit lock if (n == null || !n.IsValid()) { return(null); } // --------------------------- Add game object --------------------------------------- string name = n.GetName(); if (String.IsNullOrEmpty(name)) { name = n.GetNativeTypeName(); } GameObject gameObject = new GameObject(name); var nodeHandle = gameObject.AddComponent <NodeHandle>(); //nodeHandle.Renderer = Renderer; nodeHandle.node = n; nodeHandle.currentMaterial = currentMaterial; nodeHandle.ComputeShader = Settings.ComputeShader; // ---------------------------- Check material state ---------------------------------- if (n.HasState()) { State state = n.State; if (state.HasTexture(0) && state.GetMode(StateMode.TEXTURE) == StateModeActivation.ON) { gzTexture texture = state.GetTexture(0); if (!textureMaterialStorage.TryGetValue(texture.GetNativeReference(), out currentMaterial)) { if (texture.HasImage()) { ImageFormat image_format; ComponentType comp_type; uint components; uint depth; uint width; uint height; uint size; bool uncompress = false; Image image = texture.GetImage(); image_format = image.GetFormat(); image.Dispose(); switch (image_format) // Not yet { case ImageFormat.COMPRESSED_RGBA8_ETC2: if (!SystemInfo.SupportsTextureFormat(TextureFormat.ETC2_RGBA8)) { uncompress = true; } break; case ImageFormat.COMPRESSED_RGB8_ETC2: if (!SystemInfo.SupportsTextureFormat(TextureFormat.ETC2_RGB)) { uncompress = true; } break; case ImageFormat.COMPRESSED_RGBA_S3TC_DXT1: case ImageFormat.COMPRESSED_RGB_S3TC_DXT1: if (!SystemInfo.SupportsTextureFormat(TextureFormat.DXT1)) { uncompress = true; } break; case ImageFormat.COMPRESSED_RGBA_S3TC_DXT5: if (!SystemInfo.SupportsTextureFormat(TextureFormat.DXT5)) { uncompress = true; } break; } if (texture.GetMipMapImageArray(ref _image_texture_data, out size, out image_format, out comp_type, out components, out width, out height, out depth, true, uncompress)) { if (depth == 1) { if (n is Crossboard) { currentMaterial = new Material(Settings.CrossboardShader); } else { currentMaterial = new Material(Settings.DefaultShader); } TextureFormat format = TextureFormat.ARGB32; switch (comp_type) { case ComponentType.UNSIGNED_BYTE: { switch (image_format) { case ImageFormat.RGBA: format = TextureFormat.RGBA32; break; case ImageFormat.RGB: format = TextureFormat.RGB24; break; case ImageFormat.COMPRESSED_RGBA_S3TC_DXT1: case ImageFormat.COMPRESSED_RGB_S3TC_DXT1: format = TextureFormat.DXT1; break; case ImageFormat.COMPRESSED_RGBA_S3TC_DXT5: format = TextureFormat.DXT5; break; case ImageFormat.COMPRESSED_RGB8_ETC2: format = TextureFormat.ETC2_RGB; break; case ImageFormat.COMPRESSED_RGBA8_ETC2: format = TextureFormat.ETC2_RGBA8; break; default: // Issue your own error here because we can not use this texture yet return(null); } } break; default: // Issue your own error here because we can not use this texture yet return(null); } Texture2D tex = new Texture2D((int)width, (int)height, format, true); tex.LoadRawTextureData(_image_texture_data); switch (texture.MinFilter) { default: tex.filterMode = FilterMode.Point; break; case gzTexture.TextureMinFilter.LINEAR: case gzTexture.TextureMinFilter.LINEAR_MIPMAP_NEAREST: tex.filterMode = FilterMode.Bilinear; break; case gzTexture.TextureMinFilter.LINEAR_MIPMAP_LINEAR: tex.filterMode = FilterMode.Trilinear; break; } tex.Apply(texture.UseMipMaps, true); currentMaterial.mainTexture = tex; } } } // Add some kind of check for textures shared by many // Right now only for crossboards if (n is Crossboard) { textureMaterialStorage.Add(texture.GetNativeReference(), currentMaterial); } } nodeHandle.currentMaterial = currentMaterial; texture.Dispose(); } state.Dispose(); } // ---------------------------- Transform check ------------------------------------- gzTransform tr = n as gzTransform; if (tr != null) { Vec3 translation; if (tr.GetTranslation(out translation)) { Vector3 trans = new Vector3(translation.x, translation.y, translation.z); gameObject.transform.localPosition = trans; } // Notify subscribers of new Transform OnNewTransform?.Invoke(gameObject); } // ---------------------------- DynamicLoader check ------------------------------------- DynamicLoader dl = n as DynamicLoader; // Add dynamic loader as game object in dictionary // so other dynamic loaded data can parent them as child to loader if (dl != null) { List <GameObject> list; if (!NodeUtils.FindGameObjects(dl.GetNativeReference(), out list)) // We are not registered { NodeUtils.AddGameObjectReference(dl.GetNativeReference(), gameObject); nodeHandle.inNodeUtilsRegistry = true; // Added to registry // We shall continue to iterate as a group to see if we already have loaded children } else // We are already in list { return(list[0]); // Lets return first object wich is our main registered node } // Notify subscribers of new Loader OnNewLoader?.Invoke(gameObject); } // ---------------------------- Lod check ------------------------------------- Lod ld = n as Lod; if (ld != null) { foreach (Node child in ld) { GameObject go_child = Traverse(child, currentMaterial); if (go_child == null) { return(null); } NodeHandle h = go_child.GetComponent <NodeHandle>(); if (h != null) { if (!NodeUtils.HasGameObjects(h.node.GetNativeReference())) { NodeUtils.AddGameObjectReference(h.node.GetNativeReference(), go_child); h.inNodeUtilsRegistry = true; h.node.AddActionInterface(_actionReceiver, NodeActionEvent.IS_TRAVERSABLE); h.node.AddActionInterface(_actionReceiver, NodeActionEvent.IS_NOT_TRAVERSABLE); } } go_child.transform.SetParent(gameObject.transform, false); } // Notify subscribers of new Lod OnNewLod?.Invoke(gameObject); // Dont process group as group is already processed return(gameObject); } // ---------------------------- Roi check ------------------------------------- Roi roi = n as Roi; if (roi != null) { nodeHandle.updateTransform = true; nodeHandle.inNodeUpdateList = true; updateNodeObjects.AddLast(gameObject); foreach (Node child in roi) { GameObject go_child = Traverse(child, currentMaterial); if (go_child == null) { return(null); } NodeHandle h = go_child.GetComponent <NodeHandle>(); if (h != null) { if (!NodeUtils.HasGameObjects(h.node.GetNativeReference())) { NodeUtils.AddGameObjectReference(h.node.GetNativeReference(), go_child); h.inNodeUtilsRegistry = true; h.node.AddActionInterface(_actionReceiver, NodeActionEvent.IS_TRAVERSABLE); h.node.AddActionInterface(_actionReceiver, NodeActionEvent.IS_NOT_TRAVERSABLE); } } go_child.transform.SetParent(gameObject.transform, false); } // Dont process group return(gameObject); } // ---------------------------- RoiNode check ------------------------------------- RoiNode roinode = n as RoiNode; if (roinode != null) { nodeHandle.updateTransform = true; nodeHandle.inNodeUpdateList = true; updateNodeObjects.AddLast(gameObject); } // ---------------------------- Group check ------------------------------------- Group g = n as Group; if (g != null) { foreach (Node child in g) { GameObject go_child = Traverse(child, currentMaterial); if (go_child == null) { return(null); } go_child.transform.SetParent(gameObject.transform, false); } return(gameObject); } // ---------------------------ExtRef check ----------------------------------------- ExtRef ext = n as ExtRef; if (ext != null) { AssetLoadInfo info = new AssetLoadInfo(gameObject, ext.ResourceURL, ext.ObjectID); pendingAssetLoads.Push(info); } // ---------------------------- Crossboard check ----------------------------------- Crossboard cb = n as Crossboard; if (cb != null && GfxCaps.HasCapability(Capability.UseTreeCrossboards)) { // Scheduled for later build pendingBuilds.Enqueue(nodeHandle); } // ---------------------------- Geometry check ------------------------------------- Geometry geom = n as Geometry; if (geom != null) { nodeHandle.BuildGameObject(); // Notify subscribers of new Geometry OnNewGeometry?.Invoke(gameObject); // Later on we will identify types of geoemtry that will be scheduled later if they are extensive and not ground that covers other geometry // and build them in a later pass distributed over time // pendingBuilds.Enqueue(nodeHandle); } return(gameObject); }
// Traverse function iterates the scene graph to build local branches on Unity GameObject Traverse(Node n, Material currentMaterial) { if (n == null || !n.IsValid()) { return(null); } string name = n.GetName(); if (String.IsNullOrEmpty(name)) { name = n.GetNativeTypeName(); } GameObject gameObject = new GameObject(name); var nodeHandle = gameObject.AddComponent <NodeHandle>(); nodeHandle.node = n; nodeHandle.inObjectDict = false; // ---------------------------- Check material state ---------------------------------- if (n.HasState()) { State state = n.State; if (state.HasTexture(0) && state.GetMode(StateMode.TEXTURE) == StateModeActivation.ON) { gzTexture texture = state.GetTexture(0); if (texture.HasImage()) { gzImage image = texture.GetImage(); int depth = (int)image.GetDepth(); int width = (int)image.GetWidth(); int height = (int)image.GetHeight(); if (depth == 1) { if (currentMaterial == null) { currentMaterial = new Material(Shader); } TextureFormat format = TextureFormat.ARGB32; ImageType image_type = image.GetImageType(); switch (image_type) { case ImageType.RGB_8_DXT1: format = TextureFormat.DXT1; break; } Texture2D tex = new Texture2D(width, height, format, false); byte[] image_data; image.GetImageArray(out image_data); tex.LoadRawTextureData(image_data); tex.filterMode = FilterMode.Trilinear; tex.Apply(); currentMaterial.mainTexture = tex; } image.Dispose(); } texture.Dispose(); } state.Dispose(); } // ---------------------------- Transform check ------------------------------------- gzTransform tr = n as gzTransform; if (tr != null) { Vec3 translation; if (tr.GetTranslation(out translation)) { Vector3 trans = new Vector3(translation.x, translation.y, translation.z); gameObject.transform.localPosition = trans; } } // ---------------------------- DynamicLoader check ------------------------------------- DynamicLoader dl = n as DynamicLoader; if (dl != null) { if (!nodeHandle.inObjectDict) { AddGameObjectReference(dl.GetNativeReference(), gameObject); nodeHandle.inObjectDict = true; } } // ---------------------------- Lod check ------------------------------------- Lod ld = n as Lod; if (ld != null) { foreach (Node child in ld) { GameObject go_child = Traverse(child, currentMaterial); NodeHandle h = go_child.GetComponent <NodeHandle>(); if (h != null) { if (!h.inObjectDict) { AddGameObjectReference(h.node.GetNativeReference(), go_child); h.node.AddActionInterface(_actionReceiver, NodeActionEvent.IS_TRAVERSABLE); h.node.AddActionInterface(_actionReceiver, NodeActionEvent.IS_NOT_TRAVERSABLE); h.inObjectDict = true; } } go_child.transform.SetParent(gameObject.transform, false); } // Dont process group return(gameObject); } // ---------------------------- Roi check ------------------------------------- Roi roi = n as Roi; if (roi != null) { nodeHandle.updateTransform = true; foreach (Node child in roi) { GameObject go_child = Traverse(child, currentMaterial); NodeHandle h = go_child.GetComponent <NodeHandle>(); if (h != null) { if (!h.inObjectDict) { AddGameObjectReference(h.node.GetNativeReference(), go_child); h.node.AddActionInterface(_actionReceiver, NodeActionEvent.IS_TRAVERSABLE); h.node.AddActionInterface(_actionReceiver, NodeActionEvent.IS_NOT_TRAVERSABLE); h.inObjectDict = true; } } go_child.transform.SetParent(gameObject.transform, false); } // Dont process group return(gameObject); } // ---------------------------- RoiNode check ------------------------------------- RoiNode roinode = n as RoiNode; if (roinode != null) { nodeHandle.updateTransform = true; } // ---------------------------- Group check ------------------------------------- Group g = n as Group; if (g != null) { foreach (Node child in g) { GameObject go_child = Traverse(child, currentMaterial); go_child.transform.SetParent(gameObject.transform, false); } return(gameObject); } // ---------------------------ExtRef check ----------------------------------------- ExtRef ext = n as ExtRef; if (ext != null) { AssetLoadInfo info = new AssetLoadInfo(gameObject, ext.ResourceURL, ext.ObjectID); pendingAssetLoads.Push(info); } // ---------------------------- Geometry check ------------------------------------- Geometry geom = n as Geometry; if (geom != null) { float[] float_data; int[] indices; if (geom.GetVertexData(out float_data, out indices)) { MeshFilter filter = gameObject.AddComponent <MeshFilter>(); MeshRenderer renderer = gameObject.AddComponent <MeshRenderer>(); Mesh mesh = new Mesh(); Vector3[] vertices = new Vector3[float_data.Length / 3]; int float_index = 0; for (int i = 0; i < vertices.Length; i++) { vertices[i] = new Vector3(float_data[float_index], float_data[float_index + 1], float_data[float_index + 2]); float_index += 3; } mesh.vertices = vertices; mesh.triangles = indices; if (geom.GetColorData(out float_data)) { if (float_data.Length / 4 == vertices.Length) { float_index = 0; Color[] cols = new Color[vertices.Length]; for (int i = 0; i < vertices.Length; i++) { cols[i] = new Color(float_data[float_index], float_data[float_index + 1], float_data[float_index + 2], float_data[float_index + 3]); float_index += 4; } mesh.colors = cols; } } if (geom.GetNormalData(out float_data)) { if (float_data.Length / 3 == vertices.Length) { float_index = 0; Vector3[] normals = new Vector3[vertices.Length]; for (int i = 0; i < vertices.Length; i++) { normals[i] = new Vector3(float_data[float_index], float_data[float_index + 1], float_data[float_index + 2]); float_index += 3; } mesh.normals = normals; } } //else // mesh.RecalculateNormals(); uint texture_units = geom.GetTextureUnits(); if (texture_units > 0) { if (geom.GetTexCoordData(out float_data, 0)) { if (float_data.Length / 2 == vertices.Length) { float_index = 0; Vector2[] tex_coords = new Vector2[vertices.Length]; for (int i = 0; i < vertices.Length; i++) { tex_coords[i] = new Vector2(float_data[float_index], float_data[float_index + 1]); float_index += 2; } mesh.uv = tex_coords; } } if ((texture_units > 1) && geom.GetTexCoordData(out float_data, 1)) { if (float_data.Length / 2 == vertices.Length) { float_index = 0; Vector2[] tex_coords = new Vector2[vertices.Length]; for (int i = 0; i < vertices.Length; i++) { tex_coords[i] = new Vector2(float_data[float_index], float_data[float_index + 1]); float_index += 2; } mesh.uv2 = tex_coords; } } if ((texture_units > 2) && geom.GetTexCoordData(out float_data, 2)) { if (float_data.Length / 2 == vertices.Length) { float_index = 0; Vector2[] tex_coords = new Vector2[vertices.Length]; for (int i = 0; i < vertices.Length; i++) { tex_coords[i] = new Vector2(float_data[float_index], float_data[float_index + 1]); float_index += 2; } mesh.uv3 = tex_coords; } } if ((texture_units > 3) && geom.GetTexCoordData(out float_data, 3)) { if (float_data.Length / 2 == vertices.Length) { float_index = 0; Vector2[] tex_coords = new Vector2[vertices.Length]; for (int i = 0; i < vertices.Length; i++) { tex_coords[i] = new Vector2(float_data[float_index], float_data[float_index + 1]); float_index += 2; } mesh.uv4 = tex_coords; } } } filter.sharedMesh = mesh; renderer.sharedMaterial = currentMaterial; } } return(gameObject); }
private static bool CopyTexture(gzTexture gzTexture, out Texture2D result, bool mipChain = true) { result = null; if (!gzTexture.HasImage()) { return(false); } using (var image = gzTexture.GetImage()) { var imageFormat = image.GetFormat(); var textureFormat = GetUnityTextureFormat(imageFormat); var uncompress = !IsTextureFormatSupported(textureFormat); var nativePtr = IntPtr.Zero; if (!gzTexture.GetMipMapImageArray(ref nativePtr, out uint size, out _, out _, out _, out uint width, out uint height, out uint depth, mipChain, uncompress)) { return(false); } if (depth != 1) { return(false); } result = new Texture2D((int)width, (int)height, textureFormat, mipChain); #if false unsafe { void *pointer = nativePtr.ToPointer(); NativeArray <byte> _image_data = NativeArrayUnsafeUtility.ConvertExistingDataToNativeArray <byte>(pointer, (int)size, Allocator.None); result.LoadRawTextureData(_image_data); } #else result.LoadRawTextureData(nativePtr, (int)size); #endif switch (gzTexture.MinFilter) { case gzTexture.TextureMinFilter.LINEAR: case gzTexture.TextureMinFilter.LINEAR_MIPMAP_NEAREST: result.filterMode = FilterMode.Bilinear; break; case gzTexture.TextureMinFilter.LINEAR_MIPMAP_LINEAR: result.filterMode = FilterMode.Trilinear; break; default: result.filterMode = FilterMode.Point; break; } result.Apply(mipChain, true); } return(true); }