예제 #1
0
        /// \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);
                    }
                }
            }
        }
예제 #2
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);
        }
예제 #3
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();
                }
            }
        }