/// \cond protected override void Synchronize() { base.Synchronize(); ColoredCubesVolumeRenderer volumeRenderer = gameObject.GetComponent <ColoredCubesVolumeRenderer>(); if (volumeRenderer != null) { if (volumeRenderer.material != null) { // We compute surface normals using derivative operations in the fragment shader, but for some reason // these are backwards on Linux. We can correct for this in the shader by setting the multiplier below. #if UNITY_STANDALONE_LINUX && !UNITY_EDITOR float normalMultiplier = -1.0f; #else float normalMultiplier = 1.0f; #endif volumeRenderer.material.SetFloat("normalMultiplier", normalMultiplier); } } // Syncronize the mesh data. if (data != null) { // Syncronize the mesh data. if (data.volumeHandle.HasValue) { CubiquityDLL.UpdateVolume(data.volumeHandle.Value); if (CubiquityDLL.HasRootOctreeNode(data.volumeHandle.Value) == 1) { uint rootNodeHandle = CubiquityDLL.GetRootOctreeNode(data.volumeHandle.Value); if (rootOctreeNodeGameObject == null) { rootOctreeNodeGameObject = OctreeNode.CreateOctreeNode(rootNodeHandle, gameObject); } OctreeNode rootOctreeNode = rootOctreeNodeGameObject.GetComponent <OctreeNode>(); int nodeSyncsPerformed = rootOctreeNode.syncNode(maxNodesPerSync, gameObject); // If no node were syncronized then the mesh data is up to // date and we can set the flag to convey this to the user. isMeshSyncronized = (nodeSyncsPerformed == 0); } } } }
/// \cond protected override bool SynchronizeOctree(uint availableSyncOperations) { VolumeCollider volumeCollider = gameObject.GetComponent <VolumeCollider>(); ColoredCubesVolumeRenderer volumeRenderer = gameObject.GetComponent <ColoredCubesVolumeRenderer>(); Vector3 camPos = CameraUtils.getCurrentCameraPosition(); // This is messy - perhaps the LOD thresold shold not be a parameter to update. Instead it could be passed // as a parameter during traversal, so different traversal could retrieve differnt LODs. We then wouldn't // want a single 'renderThisNode' member of Cubiquity nodes, but instead some threshold we could compare to. float lodThreshold = GetComponent <VolumeRenderer>() ? GetComponent <VolumeRenderer>().lodThreshold : 0.0f; int minimumLOD = GetComponent <VolumeRenderer>() ? GetComponent <VolumeRenderer>().minimumLOD : 0; // Although the LOD system is partially functional I don't feel it's ready for release yet. // The following line disables it by forcing the highest level of detail to always be used. minimumLOD = 0; // Next line commented out so the system starts up with LOD disabled. //if (volumeRenderer != null && volumeRenderer.hasChanged) { CubiquityDLL.SetLodRange(data.volumeHandle.Value, minimumLOD, 0); } bool cubiquityUpToDate = CubiquityDLL.UpdateVolume(data.volumeHandle.Value, camPos.x, camPos.y, camPos.z, lodThreshold); if (CubiquityDLL.HasRootOctreeNode(data.volumeHandle.Value) == 1) { uint rootNodeHandle = CubiquityDLL.GetRootOctreeNode(data.volumeHandle.Value); if (rootOctreeNodeGameObject == null) { rootOctreeNodeGameObject = OctreeNode.CreateOctreeNode(rootNodeHandle, gameObject); } OctreeNode.syncNode(ref availableSyncOperations, rootOctreeNodeGameObject, rootNodeHandle, gameObject); if (volumeRenderer != null && volumeRenderer.hasChanged) { OctreeNode.syncNodeWithVolumeRenderer(rootOctreeNodeGameObject, volumeRenderer, true); } if (volumeCollider != null && volumeCollider.hasChanged) { OctreeNode.syncNodeWithVolumeCollider(rootOctreeNodeGameObject, volumeCollider, true); } } // These properties might have to be synced with the volume (e.g. LOD settings) or with components // (e.g. shadow/material settings). Therefore we don't clear the flags until all syncing is completed. if (volumeRenderer != null) { volumeRenderer.hasChanged = false; } if (volumeCollider != null) { volumeCollider.hasChanged = false; } // If there were still sync operations available then there was no more syncing to be done with the // Cubiquity octree. So if the Cubiquity octree was also up to date then we have synced everything. return(cubiquityUpToDate && availableSyncOperations > 0); }
/// <summary> /// Synchronize this instance. /// </summary> protected override void Synchronize() { //super! base.Synchronize(); //Not sure if this needs to be done every synchronization but okay CogBlockVolumeRenderer volRend = gameObject.GetComponent <CogBlockVolumeRenderer>(); //initialize the volume renderer so that it's normals face in the correct direction if (volRend != null) //I miss actionscript with lazy evaluation so I could string these all together in one big if.. { if (volRend.material != null) { // We compute surface normals using derivative operations in the fragment shader, but for some reason // these are backwards on Linux. We can correct for this in the shader by setting the multiplier below. #if UNITY_STANDALONE_LINUX && !UNITY_EDITOR float normalMultiplier = -1.0f; #else float normalMultiplier = 1.0f; #endif volRend.material.SetFloat("normalMultiplier", normalMultiplier); } } // Check to make sure we have anything to Synchronize if (data == null) { return; } //still checking if (!data.volumeHandle.HasValue) { return; } //update the volume CubiquityDLL.UpdateVolume(data.volumeHandle.Value); //try to synchronize the octrees if (CubiquityDLL.HasRootOctreeNode(data.volumeHandle.Value) == 1) { if (rootOctreeNode == null || rootOctreeNodeGameObject == null) { //Debug.Log("Creating RootOctreeNode from null"); uint rootNodeHandle = CubiquityDLL.GetRootOctreeNode(data.volumeHandle.Value); rootOctreeNode = OctreeNodeAlt.CreateOctreeNode(typeof(CogBlockOctreeNode), rootNodeHandle, gameObject) as CogBlockOctreeNode; rootOctreeNodeGameObject = rootOctreeNode.gameObject; } //Sync the Node and remember SyncNode will return syncs remaining. If some are remaining, the mesh is syncronized. isMeshSyncronized = (rootOctreeNode.SyncNode(maxNodesPerSync) != 0); //Where Sync nodes handles re-informed a bunch of nodes based on mesh changes, RelayComponentChanges assumes that something happened //which every node of the octree needs to know about. By setting this flag = true, we can relay those changes quickly down through the whole tree. //of course since RelayComponentChanges doesn't really 'yield' after a certain number of units are updated, it is important to realize this function is //called sparingly, usually only in edit mode, and should not perform incredibly complex per-update operations. if (RelayComponentChanges) { rootOctreeNode.RelayComponentChanges(); } } }