//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); }
private void ProcessPendingUpdates() { // We must be called in edit lock var timer = System.Diagnostics.Stopwatch.StartNew(); // Measure time precise in update #region Dynamic Loading/Add/Remove native handles --------------------------------------------------------------- Performance.Enter("PendNative"); foreach (NodeLoadInfo nodeLoadInfo in pendingLoaders) { if (nodeLoadInfo.state == DynamicLoadingState.LOADED) // We got a callback from dyn loader that we were loaded or unloaded { unTransform transform = NodeUtils.FindFirstGameObjectTransform(nodeLoadInfo.loader.GetNativeReference()); if (transform == null) // We have been unloaded or not registered { continue; } if (transform.childCount != 0) // We have already a child and our sub graph was loaded { continue; } GameObject go = Traverse(nodeLoadInfo.node, null); // Build sub graph if (go != null) { go.transform.SetParent(transform, false); // Connect to our parent } } else if (nodeLoadInfo.state == DynamicLoadingState.UNLOADED) { List <GameObject> list; if (NodeUtils.FindGameObjects(nodeLoadInfo.loader.GetNativeReference(), out list)) { foreach (GameObject go in list) { foreach (unTransform child in go.transform) //We need to unload all limked go in hierarchy { RemoveGameObjectHandles(child.gameObject); GameObject.Destroy(child.gameObject); } } } } } pendingLoaders.Clear(); Performance.Leave(); #endregion #region Activate/Deactivate GameObjects based on scenegraph ----------------------------------------------------- Performance.Enter("PendActGO"); foreach (ActivationInfo activationInfo in pendingActivations) { List <GameObject> list; // We need to activate the correct nodes if (NodeUtils.FindGameObjects(activationInfo.node.GetNativeReference(), out list)) { foreach (GameObject obj in list) { if (activationInfo.state == NodeActionEvent.IS_TRAVERSABLE) { obj.SetActive(true); } else { obj.SetActive(false); } } } } pendingActivations.Clear(); Performance.Leave(); #endregion #region Update slow loading assets ------------------------------------------------------------------------------ Performance.Enter("PendSlow"); while (pendingBuilds.Count > 0 && timer.Elapsed.TotalSeconds < Settings.MaxBuildTime) { NodeHandle handle = pendingBuilds.Dequeue(); handle.BuildGameObject(); } Performance.Leave(); #endregion // Right now we use this as a dirty fix to handle unused shared materials _unusedCounter = (_unusedCounter + 1) % Settings.FrameCleanupInterval; if (_unusedCounter == 0) { Performance.Enter("PendCleanup"); Resources.UnloadUnusedAssets(); Performance.Leave(); } }
// Update is called once per frame void Update() { // Check mouse click if (Input.GetButtonDown("Fire1")) { Map.MapPos mapPos; if (Map.MapControl.SystemMap.GetScreenGroundPosition((int)Input.mousePosition.x, (int)(Screen.height - Input.mousePosition.y), (uint)Screen.width, (uint)Screen.height, out mapPos, Map.ClampFlags.DEFAULT)) { List <GameObject> list; if (NodeUtils.FindGameObjects(mapPos.node.GetNativeReference(), out list)) { foreach (GameObject o in list) { GameObject sphere = GameObject.CreatePrimitive(PrimitiveType.Sphere); sphere.transform.parent = o.transform; sphere.transform.transform.localPosition = new Vector3((float)mapPos.position.x, (float)mapPos.position.y, (float)mapPos.position.z); sphere.transform.localScale = new Vector3(10, 10, 10); } } } } if (Input.GetButtonDown("Fire2")) { GizmoSDK.Coordinate.LatPos latpos = new GizmoSDK.Coordinate.LatPos { Altitude = 245.52585220821, Latitude = 1.00778345058085, Longitude = 0.251106492463706 }; Map.MapPos mappos; if (Map.MapControl.SystemMap.GetPosition(latpos, out mappos, Map.GroundClampType.GROUND, Map.ClampFlags.WAIT_FOR_DATA)) { Debug.Log("Hit Ground ok"); } } //transform.position; if (Input.GetKey("w")) { MoveForward(speed); } if (Input.GetKey("s")) { MoveForward(-speed); } if (Input.GetKey("d")) { MoveRight(speed); } if (Input.GetKey("a")) { MoveRight(-speed); } //transform.position = pos; Quaternion rot = transform.rotation; if (Input.GetKey(KeyCode.UpArrow)) { rot = rot * Tilt(rotspeed); } if (Input.GetKey(KeyCode.DownArrow)) { rot = rot * Tilt(-rotspeed); } if (Input.GetKey(KeyCode.LeftArrow)) { rot = Pan(-rotspeed) * rot; } if (Input.GetKey(KeyCode.RightArrow)) { rot = Pan(rotspeed) * rot; } #if TEST_ROTATION rot = Pan(-rotspeed) * rot; #endif transform.rotation = rot; }