Beispiel #1
0
        //The purpose of availableNodeSyncs is because: This function is recursive. availableNodeSyncs tells it how deep to plumb
        /// <summary>
        /// A recursive function responsible for synchronizing Unity data with the CubiquityDLL data.
        /// </summary>
        /// <returns>The amount of synchronization steps left unexpended.</returns>
        /// <param name="availableNodeSyncs">a parameter to track how much synchronization can and will be done from recrusive layer to recursive layer.</param>
        public int SyncNode(int availableNodeSyncs)
        {
            //terminator of the all-powerful recursion
            if (availableNodeSyncs <= 0)
            {
                return(0);
            }

            //-------------------------------------------
            //				PHASE ONE: Building Meshes!
            //-------------------------------------------

            //is a synchronization even called for?
            uint meshLastUpdated = CubiquityDLL.GetMeshLastUpdated(nodeHandle);


            //we don't have to synchronize this node if it wasn't updated.
            if (meshLastSyncronised < meshLastUpdated)
            {
                //I like major control branches that are concise to read!
                if (CubiquityDLL.NodeHasMesh(nodeHandle) == 1)
                {
                    NodeMeshUp();
                }
                else
                {
                    NodeMeshDown();
                }

                //absolutely do not decrement availableNodesyncs if no meshSyncing occured, or we'll never
                //explore the whole tree @.@
                meshLastSyncronised = CubiquityDLL.GetCurrentTime();
                availableNodeSyncs--;
            }

            //-------------------------------------------
            //			PHASE TWO: RECURSE!
            //-------------------------------------------

            //we needs to know if any children were ever used in the making of this node. (that way we can children == null) at the end if necessary.
            bool usedChildren = false;

            //normally we would have to iterate across the two x children, the two y children, and the two z children using 3 nested
            //for-loops. Typically speaking, nesting for loops in a recursive function causes nausea, dry mouth, dizzinss and vomiting.
            //Let's flatten the array!
            for (uint x = 0, y = 0, z = 0, i = 0;; x++, i++)
            {
                //iteration code!
                if (x > 1)
                {
                    y++; x = 0;
                }
                if (y > 1)
                {
                    z++; y = 0;
                }
                if (z > 1)
                {
                    break;
                }

                //At this point we know i is an element of [0,8)
                //And we know children exists. So we can directly getChild by using children[i];

                //Steps:
                // 1) Ascertain whether we SHOULD have a unity node
                // 2) Ascertain whether we have a children array to store the unity node in.
                // 3) Ascertain whether we DO have a unity node
                // 4) See if the unity node is right, and then Synchronize it.

                //Test whether we have a child node and, if not, clean up leaves and bare branches
                if (CubiquityDLL.HasChildNode(nodeHandle, x, y, z) != 1)
                {
                    //check to make sure we aren't about to dispose and a nonexistant child/array.
                    //Use continue to check the next child
                    if (children == null)
                    {
                        continue;
                    }
                    if (children[i] == null)
                    {
                        continue;
                    }

                    //Testing will need to be done, but TECHNICALLY this should destroy not only the octree node, but all octree nodes that come afterward (because it is
                    //done on the game object, and the game object is the parent of the other octreenodes game objects)
                    Destroy(children[i].gameObject);
                    children[i] = null;

                    continue;
                }

                //if we need a child Node and haven't even a child array, we need to init the array.
                else if (children == null)
                {
                    children = new OctreeNodeAlt[8] {
                        null, null, null, null, null, null, null, null
                    };
                }

                //nab the child Node Handle
                uint childNodeHandle = CubiquityDLL.GetChildNode(nodeHandle, x, y, z);

                //and create the Unity-side child, if necessary
                SetChild(i, childNodeHandle);

                //and synchronize the child if syncs are available.
                availableNodeSyncs = children[i].SyncNode(availableNodeSyncs);

                //if even one spot in the childArray is used, we set this to true
                usedChildren = true;
            }

            //delete children array to save space.
            if (usedChildren == false)
            {
                children = null;
            }

            //return any Syncs we have left!
            return(availableNodeSyncs);
        }
Beispiel #2
0
            public int syncNode(int availableNodeSyncs, GameObject voxelTerrainGameObject)
            {
                int nodeSyncsPerformed = 0;

                if (availableNodeSyncs <= 0)
                {
                    return(nodeSyncsPerformed);
                }

                uint meshLastUpdated = CubiquityDLL.GetMeshLastUpdated(nodeHandle);

                if (meshLastSyncronised < meshLastUpdated)
                {
                    if (CubiquityDLL.NodeHasMesh(nodeHandle) == 1)
                    {
                        // Set up the rendering mesh
                        VolumeRenderer volumeRenderer = voxelTerrainGameObject.GetComponent <VolumeRenderer>();
                        if (volumeRenderer != null)
                        {
                            //Mesh renderingMesh = volumeRenderer.BuildMeshFromNodeHandle(nodeHandle);

                            Mesh renderingMesh = null;
                            if (voxelTerrainGameObject.GetComponent <Volume>().GetType() == typeof(TerrainVolume))
                            {
                                renderingMesh = BuildMeshFromNodeHandleForTerrainVolume(nodeHandle);
                            }
                            else if (voxelTerrainGameObject.GetComponent <Volume>().GetType() == typeof(ColoredCubesVolume))
                            {
                                renderingMesh = BuildMeshFromNodeHandleForColoredCubesVolume(nodeHandle);
                            }

                            MeshFilter   meshFilter   = gameObject.GetOrAddComponent <MeshFilter>() as MeshFilter;
                            MeshRenderer meshRenderer = gameObject.GetOrAddComponent <MeshRenderer>() as MeshRenderer;

                            if (meshFilter.sharedMesh != null)
                            {
                                DestroyImmediate(meshFilter.sharedMesh);
                            }

                            meshFilter.sharedMesh = renderingMesh;

                            meshRenderer.sharedMaterial = volumeRenderer.material;

                                                        #if UNITY_EDITOR
                            EditorUtility.SetSelectedWireframeHidden(meshRenderer, true);
                                                        #endif
                        }

                        // Set up the collision mesh
                        VolumeCollider volumeCollider = voxelTerrainGameObject.GetComponent <VolumeCollider>();
                        if ((volumeCollider != null) && (Application.isPlaying))
                        {
                            Mesh         collisionMesh = volumeCollider.BuildMeshFromNodeHandle(nodeHandle);
                            MeshCollider meshCollider  = gameObject.GetOrAddComponent <MeshCollider>() as MeshCollider;
                            meshCollider.sharedMesh = collisionMesh;
                        }
                    }
                    // If there is no mesh in Cubiquity then we make sure there isn't on in Unity.
                    else
                    {
                        MeshCollider meshCollider = gameObject.GetComponent <MeshCollider>() as MeshCollider;
                        if (meshCollider)
                        {
                            DestroyImmediate(meshCollider);
                        }

                        MeshRenderer meshRenderer = gameObject.GetComponent <MeshRenderer>() as MeshRenderer;
                        if (meshRenderer)
                        {
                            DestroyImmediate(meshRenderer);
                        }

                        MeshFilter meshFilter = gameObject.GetComponent <MeshFilter>() as MeshFilter;
                        if (meshFilter)
                        {
                            DestroyImmediate(meshFilter);
                        }
                    }

                    meshLastSyncronised = CubiquityDLL.GetCurrentTime();
                    availableNodeSyncs--;
                    nodeSyncsPerformed++;
                }

                VolumeRenderer vr = voxelTerrainGameObject.GetComponent <VolumeRenderer>();
                MeshRenderer   mr = gameObject.GetComponent <MeshRenderer>();
                if (vr != null && mr != null)
                {
                    if (mr.enabled != vr.enabled)                    // Not sure we really need this check?
                    {
                        mr.enabled = vr.enabled;
                    }

                    if (lastSyncronisedWithVolumeRenderer < vr.lastModified)
                    {
                        mr.receiveShadows = vr.receiveShadows;
                        mr.castShadows    = vr.castShadows;
                        lastSyncronisedWithVolumeRenderer = Clock.timestamp;
                    }
                }

                VolumeCollider vc = voxelTerrainGameObject.GetComponent <VolumeCollider>();
                MeshCollider   mc = gameObject.GetComponent <MeshCollider>();
                if (vc != null && mc != null)
                {
                    if (mc.enabled != vc.enabled)                    // Not sure we really need this check?
                    {
                        mc.enabled = vc.enabled;
                    }

                    if (lastSyncronisedWithVolumeCollider < vc.lastModified)
                    {
                        // Actual syncronization to be filled in in the future when we have something to syncronize.
                        lastSyncronisedWithVolumeCollider = Clock.timestamp;
                    }
                }

                //Now syncronise any children
                for (uint z = 0; z < 2; z++)
                {
                    for (uint y = 0; y < 2; y++)
                    {
                        for (uint x = 0; x < 2; x++)
                        {
                            if (CubiquityDLL.HasChildNode(nodeHandle, x, y, z) == 1)
                            {
                                uint childNodeHandle = CubiquityDLL.GetChildNode(nodeHandle, x, y, z);

                                GameObject childGameObject = GetChild(x, y, z);

                                if (childGameObject == null)
                                {
                                    childGameObject = OctreeNode.CreateOctreeNode(childNodeHandle, gameObject);

                                    SetChild(x, y, z, childGameObject);
                                }

                                //syncNode(childNodeHandle, childGameObject);

                                OctreeNode childOctreeNode = childGameObject.GetComponent <OctreeNode>();
                                int        syncs           = childOctreeNode.syncNode(availableNodeSyncs, voxelTerrainGameObject);
                                availableNodeSyncs -= syncs;
                                nodeSyncsPerformed += syncs;
                            }
                        }
                    }
                }

                return(nodeSyncsPerformed);
            }