//what the devil is a nodeHandle?
        public override Mesh BuildMeshFromNodeHandle(uint nodeHandle)
        {
            Debug.Log("Trying to build ColoredCubes mesh from node");

            // Create rendering and possible collision meshes.
            Mesh collisionMesh = new Mesh();

            collisionMesh.hideFlags = HideFlags.DontSave;

            // Get the data from Cubiquity.
            int[] indices = CubiquityDLL.GetIndices(nodeHandle);
            ColoredCubesVertex[] cubiquityVertices = CubiquityDLL.GetVertices(nodeHandle);

            // Create the arrays which we'll copy the data to.
            Vector3[] vertices = new Vector3[cubiquityVertices.Length];

            for (int ct = 0; ct < cubiquityVertices.Length; ct++)
            {
                // Get the vertex data from Cubiquity.
                vertices[ct] = new Vector3(cubiquityVertices[ct].x, cubiquityVertices[ct].y, cubiquityVertices[ct].z);
            }

            //FIXME - set collision mesh bounds as we do with rendering mesh?
            collisionMesh.vertices  = vertices;
            collisionMesh.triangles = indices;

            Debug.Log("Collision Mesh Built from verticies of length: " + cubiquityVertices.Length.ToString());

            return(collisionMesh);
        }
예제 #2
0
        public static bool PickLastEmptyVoxel(CogBlockVolume volume, Vector3 origin, Vector3 direction, float distance, out PickVoxelResult pickResult)
        {
            // This 'out' value needs to be initialised even if we don't hit
            // anything (in which case it will be left at it's default value).
            pickResult = new PickVoxelResult();

            // Can't hit it the volume if there's no data.
            if ((volume.data == null) || (volume.data.volumeHandle == null))
            {
                return(false);
            }

            //again, transforming to volume space
            Vector3 target = origin + direction * distance;

            origin    = volume.transform.InverseTransformPoint(origin);
            target    = volume.transform.InverseTransformPoint(target);
            direction = target - origin;

            // Now call through to the Cubiquity dll to do the actual picking.
            pickResult = new PickVoxelResult();
            uint hit = CubiquityDLL.PickLastEmptyVoxel((uint)volume.data.volumeHandle,
                                                       origin.x, origin.y, origin.z,
                                                       direction.x, direction.y, direction.z,
                                                       out pickResult.volumeSpacePos.x, out pickResult.volumeSpacePos.y, out pickResult.volumeSpacePos.z);

            //transform back out into worldspace
            pickResult.worldSpacePos = volume.transform.TransformPoint((Vector3)(pickResult.volumeSpacePos));

            // Return true if we hit a surface.
            return(hit == 1);
        }
 public override void DiscardChanges()
 {
     if (!IsVolumeHandleNull())
     {
         CubiquityDLL.DiscardOverrideChunks(volumeHandle.Value);
     }
 }
예제 #4
0
        /// \cond
        protected override void Synchronize()
        {
            base.Synchronize();

            // Syncronize the mesh data.
            if (data != null)
            {
                if (data.volumeHandle.HasValue)
                {
                    CubiquityDLL.UpdateVolumeMC(data.volumeHandle.Value);

                    if (CubiquityDLL.HasRootOctreeNodeMC(data.volumeHandle.Value) == 1)
                    {
                        uint rootNodeHandle = CubiquityDLL.GetRootOctreeNodeMC(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);
                    }
                }
            }
        }
예제 #5
0
        public static bool PickFirstSolidVoxel(CogBlockVolume volume, Vector3 origin, Vector3 direction, float distance, out PickVoxelResult pickResult)
        {
            //initialization of an empty struct
            pickResult = new PickVoxelResult();

            // Can't hit it the volume if there's no data.
            if ((volume.data == null) || (volume.data.volumeHandle == null))
            {
                return(false);
            }

            //As noted by cubiquity, where cubqity's picking code works in volume space, Unity needs to work in world space...
            // Cubiquity's picking code works in volume space whereas we expose an interface that works in world

            //Grab our ray's components and transform them for volume space.
            Vector3 target = origin + direction * distance;

            origin    = volume.transform.InverseTransformPoint(origin);
            target    = volume.transform.InverseTransformPoint(target);
            direction = target - origin;

            // Now call through to the Cubiquity dll to do the actual picking.
            //Recall that CubiquityDLL will only have to work with ColoredCubeData, but that we are translating that boldface into CogBlockVolume data.
            uint hit = CubiquityDLL.PickFirstSolidVoxel((uint)volume.data.volumeHandle,
                                                        origin.x, origin.y, origin.z,
                                                        direction.x, direction.y, direction.z,
                                                        out pickResult.volumeSpacePos.x, out pickResult.volumeSpacePos.y, out pickResult.volumeSpacePos.z);

            // The result is in volume space, but again it is more convienient for Unity users to have the result
            // in world space. Therefore we apply the volume's volume-to-world transform to the volume space position.
            pickResult.worldSpacePos = volume.transform.TransformPoint((Vector3)(pickResult.volumeSpacePos));

            // Return true if we hit a surface.
            return(hit == 1);
        }
        public override Mesh BuildMeshFromNodeHandle(uint nodeHandle)
        {
            // At some point I should read this: http://forum.unity3d.com/threads/5687-C-plugin-pass-arrays-from-C

            // Create rendering and possible collision meshes.
            Mesh collisionMesh = new Mesh();

            collisionMesh.hideFlags = HideFlags.DontSave;

            // Get the data from Cubiquity.
            int[] indices = CubiquityDLL.GetIndices(nodeHandle);
            ColoredCubesVertex[] cubiquityVertices = CubiquityDLL.GetVertices(nodeHandle);

            // Create the arrays which we'll copy the data to.
            Vector3[] vertices = new Vector3[cubiquityVertices.Length];

            for (int ct = 0; ct < cubiquityVertices.Length; ct++)
            {
                // Get the vertex data from Cubiquity.
                vertices[ct] = new Vector3(cubiquityVertices[ct].x, cubiquityVertices[ct].y, cubiquityVertices[ct].z);
            }

            //FIXME - set collision mesh bounds as we do with rendering mesh?
            collisionMesh.vertices  = vertices;
            collisionMesh.triangles = indices;

            return(collisionMesh);
        }
예제 #7
0
        /// \cond
        protected override void InitializeEmptyCubiquityVolume(Region region)
        {
            // We check 'mVolumeHandle' instead of 'volumeHandle' as the getter for the latter will in turn call this method.
            if (mVolumeHandle != null)
            {
                Debug.LogAssertion("Volume handle should be null prior to initializing volume"); return;
            }

            if (!initializeAlreadyFailed) // If it failed before it will fail again - avoid spamming error messages.
            {
                try
                {
                    // Create an empty region of the desired size.
                    volumeHandle = CubiquityDLL.NewEmptyColoredCubesVolume(region.lowerCorner.x, region.lowerCorner.y, region.lowerCorner.z,
                                                                           region.upperCorner.x, region.upperCorner.y, region.upperCorner.z, fullPathToVoxelDatabase, DefaultBaseNodeSize);
                }
                catch (CubiquityException exception)
                {
                    volumeHandle            = null;
                    initializeAlreadyFailed = true;
                    Debug.LogException(exception);
                    Debug.LogError("Failed to open voxel database '" + fullPathToVoxelDatabase + "'");
                }
            }
        }
예제 #8
0
        public override Mesh BuildMeshFromNodeHandle(uint nodeHandle)
        {
            Mesh collisionMesh = new Mesh();

            collisionMesh.hideFlags = HideFlags.DontSave;

            // Get the data from Cubiquity.
            int[]           indices           = CubiquityDLL.GetIndicesMC(nodeHandle);
            TerrainVertex[] cubiquityVertices = CubiquityDLL.GetVerticesMC(nodeHandle);

            // Create the arrays which we'll copy the data to.
            Vector3[] vertices = new Vector3[cubiquityVertices.Length];

            for (int ct = 0; ct < cubiquityVertices.Length; ct++)
            {
                // Get the vertex data from Cubiquity.
                vertices[ct]  = new Vector3(cubiquityVertices[ct].x, cubiquityVertices[ct].y, cubiquityVertices[ct].z);
                vertices[ct] *= (1.0f / 256.0f);
            }

            // Assign vertex data to the meshes.
            collisionMesh.vertices  = vertices;
            collisionMesh.triangles = indices;

            return(collisionMesh);
        }
    /// \endcond

    /// \cond
    public override void InitializeExistingCubiquityVolume()
    {
        // This function might get called multiple times. E.g the user might call it striaght after crating the volume (so
        // they can add some initial data to the volume) and it might then get called again by OnEnable(). Handle this safely.
        if (volumeHandle == null)
        {
            // Create an empty region of the desired size.
            volumeHandle = CubiquityDLL.NewTerrainVolumeFromVDB(fullPathToVoxelDatabase, DefaultBaseNodeSize);
        }
    }
예제 #10
0
            public Mesh BuildMeshFromNodeHandleForTerrainVolume(uint nodeHandle)
            {
                // At some point I should read this: http://forum.unity3d.com/threads/5687-C-plugin-pass-arrays-from-C

                // Create rendering and possible collision meshes.
                Mesh renderingMesh = new Mesh();

                renderingMesh.hideFlags = HideFlags.DontSave;

                // Get the data from Cubiquity.
                int[]           indices           = CubiquityDLL.GetIndicesMC(nodeHandle);
                TerrainVertex[] cubiquityVertices = CubiquityDLL.GetVerticesMC(nodeHandle);

                // Create the arrays which we'll copy the data to.
                Vector3[] renderingVertices = new Vector3[cubiquityVertices.Length];
                Vector3[] renderingNormals  = new Vector3[cubiquityVertices.Length];
                Color32[] renderingColors   = new Color32[cubiquityVertices.Length];
                //Vector4[] renderingTangents = new Vector4[cubiquityVertices.Length];
                Vector2[] renderingUV  = new Vector2[cubiquityVertices.Length];
                Vector2[] renderingUV2 = new Vector2[cubiquityVertices.Length];


                for (int ct = 0; ct < cubiquityVertices.Length; ct++)
                {
                    // Get the vertex data from Cubiquity.
                    Vector3 position = new Vector3(cubiquityVertices[ct].x, cubiquityVertices[ct].y, cubiquityVertices[ct].z);
                    Vector3 normal   = new Vector3(cubiquityVertices[ct].nx, cubiquityVertices[ct].ny, cubiquityVertices[ct].nz);
                    Color32 color    = new Color32(cubiquityVertices[ct].m0, cubiquityVertices[ct].m1, cubiquityVertices[ct].m2, cubiquityVertices[ct].m3);
                    //Vector4 tangents = new Vector4(cubiquityVertices[ct].m4 / 255.0f, cubiquityVertices[ct].m5 / 255.0f, cubiquityVertices[ct].m6 / 255.0f, cubiquityVertices[ct].m7 / 255.0f);
                    Vector2 uv  = new Vector2(cubiquityVertices[ct].m4 / 255.0f, cubiquityVertices[ct].m5 / 255.0f);
                    Vector2 uv2 = new Vector2(cubiquityVertices[ct].m6 / 255.0f, cubiquityVertices[ct].m7 / 255.0f);

                    // Copy it to the arrays.
                    renderingVertices[ct] = position;
                    renderingNormals[ct]  = normal;
                    renderingColors[ct]   = color;
                    //renderingTangents[ct] = tangents;
                    renderingUV[ct]  = uv;
                    renderingUV2[ct] = uv2;
                }

                // Assign vertex data to the meshes.
                renderingMesh.vertices = renderingVertices;
                renderingMesh.normals  = renderingNormals;
                renderingMesh.colors32 = renderingColors;
                //renderingMesh.tangents = renderingTangents;
                renderingMesh.uv        = renderingUV;
                renderingMesh.uv2       = renderingUV2;
                renderingMesh.triangles = indices;

                // FIXME - Get proper bounds
                renderingMesh.bounds.SetMinMax(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(32.0f, 32.0f, 32.0f));

                return(renderingMesh);
            }
예제 #11
0
            public static void BuildMeshFromNodeHandleForColoredCubesVolume(Mesh mesh, uint nodeHandle, bool onlyPositions)
            {
                // Get the data from Cubiquity.
                ColoredCubesVertex[] vertices;
                ushort[]             indices;
                CubiquityDLL.GetMesh <ColoredCubesVertex>(nodeHandle, out vertices, out indices);
                int noOfVertices = vertices.Length;
                int noOfIndices  = indices.Length;
#endif

                // Cubiquity uses 16-bit index arrays to save space, and it appears Unity does the same (at least, there is
                // a limit of 65535 vertices per mesh). However, the Mesh.triangles property is of the signed 32-bit int[]
                // type rather than the unsigned 16-bit ushort[] type. Perhaps this is so they can switch to 32-bit index
                // buffers in the future? At any rate, it means we have to perform a conversion.
                int[] indicesAsInt = new int[noOfIndices];
                for (int ct = 0; ct < noOfIndices; ct++)
                {
                    indicesAsInt[ct] = indices[ct];
                }

                // Clear any previous mesh data.
                mesh.Clear(true);

                // Required for the CubicVertex decoding process.
                Vector3 offset = new Vector3(0.5f, 0.5f, 0.5f);

                // Copy the vertex positions from Cubiquity into the Unity mesh.
                Vector3[] positions = new Vector3[noOfVertices];
                for (int ct = 0; ct < noOfVertices; ct++)
                {
                    // Get and decode the position
                    positions[ct].Set(vertices[ct].x, vertices[ct].y, vertices[ct].z);
                    positions[ct] -= offset;
                }
                // Assign vertex data to the mesh.
                mesh.vertices = positions;

                // For collision meshes the vertex positions are enough, but
                // for meshes which are rendered we want all vertex attributes.
                if (!onlyPositions)
                {
                    Color32[] colors32 = new Color32[noOfVertices];
                    for (int ct = 0; ct < noOfVertices; ct++)
                    {
                        // Get and decode the color
                        colors32[ct] = (Color32)vertices[ct].color;
                    }
                    // Assign vertex data to the mesh.
                    mesh.colors32 = colors32;
                }

                // Assign index data to the mesh.
                mesh.triangles = indicesAsInt;
            }
 /// \cond
 protected override void InitializeEmptyCubiquityVolume(Region region)
 {
     // This function might get called multiple times. E.g the user might call it striaght after crating the volume (so
     // they can add some initial data to the volume) and it might then get called again by OnEnable(). Handle this safely.
     if (volumeHandle == null)
     {
         // Create an empty region of the desired size.
         volumeHandle = CubiquityDLL.NewEmptyTerrainVolume(region.lowerCorner.x, region.lowerCorner.y, region.lowerCorner.z,
                                                           region.upperCorner.x, region.upperCorner.y, region.upperCorner.z, fullPathToVoxelDatabase, DefaultBaseNodeSize);
     }
 }
    /// Sets the material weights of the specified position.

    /**
     * \param x The 'x' position of the voxel to set.
     * \param y The 'y' position of the voxel to set.
     * \param z The 'z' position of the voxel to set.
     * \param materialSet The material weights the voxel should be set to.
     */
    public void SetVoxel(int x, int y, int z, MaterialSet materialSet)
    {
        if (volumeHandle.HasValue)
        {
            if (x >= enclosingRegion.lowerCorner.x && y >= enclosingRegion.lowerCorner.y && z >= enclosingRegion.lowerCorner.z &&
                x <= enclosingRegion.upperCorner.x && y <= enclosingRegion.upperCorner.y && z <= enclosingRegion.upperCorner.z)
            {
                CubiquityDLL.SetVoxelMC(volumeHandle.Value, x, y, z, materialSet);
            }
        }
    }
예제 #14
0
        /// <summary>
        /// Initializes the GameObject to which a new node will belong, and does not have to be called by the average Editor-User. Already called in CreateOctreeNode, immediately after InitializeNode.
        /// It may be overwritten with care (nodeHandle is particularly important).
        /// </summary>
        /// <param name="nodeHandle">The CubiquityDLL handle of the node we're creating. </param>
        protected virtual void InitializeNode(uint nodeHandle)
        {
            //DIS IS VEDDY, VEDDY IMPORTANT. Without this, we can do nothing. NOTHING! Call super to let this happpen!
            this.nodeHandle = nodeHandle;

            //All Octree nodes have positions. Let's get ours in 3 easy steps.
            int nx, ny, nz;

            CubiquityDLL.GetNodePosition(nodeHandle, out nx, out ny, out nz);
            lowerCorner = new Vector3(nx, ny, nz);
        }
    /// Sets the color of the specified position.

    /**
     * \param x The 'x' position of the voxel to set.
     * \param y The 'y' position of the voxel to set.
     * \param z The 'z' position of the voxel to set.
     * \param quantizedColor The color the voxel should be set to.
     */
    public void SetVoxel(int x, int y, int z, QuantizedColor quantizedColor)
    {
        if (volumeHandle.HasValue)
        {
            if (x >= enclosingRegion.lowerCorner.x && y >= enclosingRegion.lowerCorner.y && z >= enclosingRegion.lowerCorner.z &&
                x <= enclosingRegion.upperCorner.x && y <= enclosingRegion.upperCorner.y && z <= enclosingRegion.upperCorner.z)
            {
                CubiquityDLL.SetVoxel(volumeHandle.Value, x, y, z, quantizedColor);
            }
        }
    }
        /// Gets the color of the specified position.

        /**
         * \param x The 'x' position of the voxel to get.
         * \param y The 'y' position of the voxel to get.
         * \param z The 'z' position of the voxel to get.
         * \return The color of the voxel.
         */
        public QuantizedColor GetVoxel(int x, int y, int z)
        {
            // The initialization can fail (bad filename, database locked, etc), so the volume handle could still be null.
            if (volumeHandle.HasValue)
            {
                return(CubiquityDLL.GetQuantizedColorVoxel(volumeHandle.Value, x, y, z));
            }
            else
            {
                return(new QuantizedColor());
            }
        }
        /// Sets the color of the specified position.

        /**
         * \param x The 'x' position of the voxel to set.
         * \param y The 'y' position of the voxel to set.
         * \param z The 'z' position of the voxel to set.
         * \param quantizedColor The color the voxel should be set to.
         */
        public void SetVoxel(int x, int y, int z, QuantizedColor quantizedColor)
        {
            // The initialization can fail (bad filename, database locked, etc), so the volume handle could still be null.
            if (volumeHandle.HasValue)
            {
                if (x >= enclosingRegion.lowerCorner.x && y >= enclosingRegion.lowerCorner.y && z >= enclosingRegion.lowerCorner.z &&
                    x <= enclosingRegion.upperCorner.x && y <= enclosingRegion.upperCorner.y && z <= enclosingRegion.upperCorner.z)
                {
                    CubiquityDLL.SetVoxel(volumeHandle.Value, x, y, z, quantizedColor);
                }
            }
        }
        public override void CommitChanges()
        {
            if (!IsVolumeHandleNull())
            {
                if (writePermissions == WritePermissions.ReadOnly)
                {
                    throw new InvalidOperationException("Cannot commit changes to read-only voxel database (" + fullPathToVoxelDatabase + ")");
                }

                CubiquityDLL.AcceptOverrideChunks(volumeHandle.Value);
                //We can discard the chunks now that they have been accepted.
                CubiquityDLL.DiscardOverrideChunks(volumeHandle.Value);
            }
        }
        /// <summary>
        /// Builds the Mesh represented by the Node. Uses the Node's nodeHandle (inherited from OctreeNodeAlt)
        /// </summary>
        /// <returns>The mesh.</returns>
        public override Mesh BuildMesh()
        {
            // At some point I should read this: http://forum.unity3d.com/threads/5687-C-plugin-pass-arrays-from-C

            Vector3 offset = new Vector3(0.5f, 0.5f, 0.5f);             // Required for the CubicVertex decoding process.

            // Meshes for rendering and collition.
            Mesh mesh = new Mesh();

            //prevents memory leaks >:)
            mesh.hideFlags = HideFlags.DontSave;

            // Get the data from where it is stored in Cubiquity.
            int[] indices = CubiquityDLL.GetIndices(nodeHandle);
            ColoredCubesVertex[] cubiquityVertices = CubiquityDLL.GetVertices(nodeHandle);

            // Create the arrays which we'll copy the data to.
            Vector3[] rendererVertices = new Vector3[cubiquityVertices.Length];
            Color32[] rendererColors   = new Color32[cubiquityVertices.Length];

            //translate the data from Cubiquity's forms to Unity's
            for (int ct = 0; ct < cubiquityVertices.Length; ct++)
            {
                // Get the vertex data from Cubiquity.
                Vector3 position = new Vector3(cubiquityVertices[ct].x, cubiquityVertices[ct].y, cubiquityVertices[ct].z);

                // Part of the CubicVertex decoding process.
                position -= offset;

                //nab the color
                QuantizedColor color = cubiquityVertices[ct].color;

                // Copy it to the arrays.
                rendererVertices[ct] = position;
                rendererColors[ct]   = (Color32)color;
            }

            // Assign vertex data to the meshes.
            mesh.vertices  = rendererVertices;
            mesh.colors32  = rendererColors;
            mesh.triangles = indices;

            // FIXME - Get proper bounds
            mesh.bounds.SetMinMax(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(32.0f, 32.0f, 32.0f));
            mesh.name = "nodeHandle: " + nodeHandle.ToString();

            return(mesh);
            //return null;
        }
    /// Gets the material weights of the specified position.

    /**
     * \param x The 'x' position of the voxel to get.
     * \param y The 'y' position of the voxel to get.
     * \param z The 'z' position of the voxel to get.
     * \return The material weights of the voxel.
     */
    public MaterialSet GetVoxel(int x, int y, int z)
    {
        MaterialSet materialSet;

        if (volumeHandle.HasValue)
        {
            CubiquityDLL.GetVoxelMC(volumeHandle.Value, x, y, z, out materialSet);
        }
        else
        {
            // Should maybe throw instead?
            materialSet = new MaterialSet();
        }
        return(materialSet);
    }
    /// Gets the color of the specified position.

    /**
     * \param x The 'x' position of the voxel to get.
     * \param y The 'y' position of the voxel to get.
     * \param z The 'z' position of the voxel to get.
     * \return The color of the voxel.
     */
    public QuantizedColor GetVoxel(int x, int y, int z)
    {
        QuantizedColor result;

        if (volumeHandle.HasValue)
        {
            CubiquityDLL.GetVoxel(volumeHandle.Value, x, y, z, out result);
        }
        else
        {
            //Should maybe throw instead.
            result = new QuantizedColor();
        }
        return(result);
    }
예제 #22
0
            public static GameObject CreateOctreeNode(uint nodeHandle, GameObject parentGameObject)
            {
                int xPos, yPos, zPos;

                //Debug.Log("Getting position for node handle = " + nodeHandle);
                CubiquityDLL.GetNodePosition(nodeHandle, out xPos, out yPos, out zPos);

                StringBuilder name = new StringBuilder("(" + xPos + ", " + yPos + ", " + zPos + ")");

                GameObject newGameObject = new GameObject(name.ToString());

                newGameObject.AddComponent <OctreeNode>();

                OctreeNode octreeNode = newGameObject.GetComponent <OctreeNode>();

                octreeNode.lowerCorner = new Vector3(xPos, yPos, zPos);
                octreeNode.nodeHandle  = nodeHandle;

                if (parentGameObject)
                {
                    newGameObject.layer = parentGameObject.layer;

                    newGameObject.transform.parent        = parentGameObject.transform;
                    newGameObject.transform.localPosition = new Vector3();
                    newGameObject.transform.localRotation = new Quaternion();
                    newGameObject.transform.localScale    = new Vector3(1.0f, 1.0f, 1.0f);

                    OctreeNode parentOctreeNode = parentGameObject.GetComponent <OctreeNode>();

                    if (parentOctreeNode != null)
                    {
                        Vector3 parentLowerCorner = parentOctreeNode.lowerCorner;
                        newGameObject.transform.localPosition = octreeNode.lowerCorner - parentLowerCorner;
                    }
                    else
                    {
                        newGameObject.transform.localPosition = octreeNode.lowerCorner;
                    }
                }
                else
                {
                    newGameObject.transform.localPosition = octreeNode.lowerCorner;
                }

                newGameObject.hideFlags = HideFlags.HideInHierarchy;

                return(newGameObject);
            }
예제 #23
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);
                    }
                }
            }
        }
예제 #24
0
        /// Gets the material weights of the specified position.

        /**
         * \param x The 'x' position of the voxel to get.
         * \param y The 'y' position of the voxel to get.
         * \param z The 'z' position of the voxel to get.
         * \return The material weights of the voxel.
         */
        public MaterialSet GetVoxel(int x, int y, int z)
        {
            // The initialization can fail (bad filename, database locked, etc), so the volume handle could still be null.
            MaterialSet materialSet;

            if (volumeHandle.HasValue)
            {
                CubiquityDLL.GetVoxelMC(volumeHandle.Value, x, y, z, out materialSet);
            }
            else
            {
                materialSet = new MaterialSet();
            }

            return(materialSet);
        }
예제 #25
0
            public static GameObject CreateOctreeNode(uint nodeHandle, GameObject parentGameObject)
            {
                // Get node position from Cubiquity
                CuOctreeNode cuOctreeNode = CubiquityDLL.GetOctreeNode(nodeHandle);
                int          xPos = cuOctreeNode.posX, yPos = cuOctreeNode.posY, zPos = cuOctreeNode.posZ;

                // Build a corresponding game object
                StringBuilder name          = new StringBuilder("OctreeNode (" + xPos + ", " + yPos + ", " + zPos + ")");
                GameObject    newGameObject = new GameObject(name.ToString());

                newGameObject.hideFlags = HideFlags.HideInHierarchy;

                // Use parent properties as appropriate
                newGameObject.transform.parent = parentGameObject.transform;
                newGameObject.layer            = parentGameObject.layer;

                // It seems that setting the parent does not cause the object to move as Unity adjusts
                // the child transform to compensate (this can be seen when moving objects between parents
                // in the hierarchy view). Reset the local transform as shown here: http://goo.gl/k5n7M7
                newGameObject.transform.localRotation = Quaternion.identity;
                newGameObject.transform.localPosition = Vector3.zero;
                newGameObject.transform.localScale    = Vector3.one;

                // Attach an OctreeNode component
                OctreeNode octreeNode = newGameObject.AddComponent <OctreeNode>();

                octreeNode.lowerCorner = new Vector3(xPos, yPos, zPos);

                // Does the parent game object have an octree node attached?
                OctreeNode parentOctreeNode = parentGameObject.GetComponent <OctreeNode>();

                if (parentOctreeNode)
                {
                    // Cubiquity gives us absolute positions for the Octree nodes, but for a hierarchy of
                    // GameObjects we need relative positions. Obtain these by subtracting parent position.
                    newGameObject.transform.localPosition = octreeNode.lowerCorner - parentOctreeNode.lowerCorner;
                }
                else
                {
                    // If not then the parent must be the Volume GameObject and the one we are creating
                    // must be the root of the Octree. In this case we can use the position directly.
                    newGameObject.transform.localPosition = octreeNode.lowerCorner;
                }

                return(newGameObject);
            }
    /// \endcond

    /// \cond
    public override void ShutdownCubiquityVolume()
    {
        if (volumeHandle.HasValue)
        {
            // We only save if we are in editor mode, not if we are playing.
            bool saveChanges = !Application.isPlaying;

            if (saveChanges)
            {
                CubiquityDLL.AcceptOverrideBlocks(volumeHandle.Value);
            }
            CubiquityDLL.DiscardOverrideBlocks(volumeHandle.Value);

            CubiquityDLL.DeleteColoredCubesVolume(volumeHandle.Value);
            volumeHandle = null;
        }
    }
        /// Sets the color of the specified position.

        /**
         * \param x The 'x' position of the voxel to set.
         * \param y The 'y' position of the voxel to set.
         * \param z The 'z' position of the voxel to set.
         * \param quantizedColor The color the voxel should be set to.
         */

        public String printData()
        {
            String         toReturn = "";
            QuantizedColor result   = new QuantizedColor();

            int lx = enclosingRegion.lowerCorner.x;
            int ux = enclosingRegion.upperCorner.x;
            int ly = enclosingRegion.lowerCorner.y;
            int uy = enclosingRegion.upperCorner.y;
            int lz = enclosingRegion.lowerCorner.z;
            int uz = enclosingRegion.upperCorner.z;

            Debug.Log("Dimensions on x: " + lx.ToString() + " to " + ux.ToString());
            Debug.Log("Dimensions on z: " + lz.ToString() + " to " + uz.ToString());
            Debug.Log("Dimensions on y: " + ly.ToString() + " to " + uy.ToString());
            Debug.Log("volume Handle: " + volumeHandle.Value.ToString());


            if (volumeHandle == null)
            {
                Debug.Log("null volume handle");
                return(toReturn);
            }

            int i = 0;
            //for(int i = lx; i < ux; i++)
            //{

            int j = 0;

            //for(int j = lz; j < uz; j++)
            //{
            for (int k = ly; k < uy; k++)
            {
                CubiquityDLL.GetVoxel(volumeHandle.Value, i, k, j, out result);

                Debug.Log(" " + i + "," + j + "," + k + ": " + result.red + "|" + result.green + "|" + result.blue + "|" + result.alpha);
            }
            //toReturn = toReturn + "|";
            //}
            //toReturn = toReturn + ";";
            //}

            return(toReturn);
        }
    /// \endcond

    /// \cond
    public override void ShutdownCubiquityVolume()
    {
        // Shutdown could get called multiple times. E.g by OnDisable() and then by OnDestroy().
        if (volumeHandle.HasValue)
        {
            // We only save if we are in editor mode, not if we are playing.
            bool saveChanges = !Application.isPlaying;

            if (saveChanges)
            {
                CubiquityDLL.AcceptOverrideBlocksMC(volumeHandle.Value);
            }
            CubiquityDLL.DiscardOverrideBlocksMC(volumeHandle.Value);

            CubiquityDLL.DeleteTerrainVolume(volumeHandle.Value);
            volumeHandle = null;
        }
    }
        /// \endcond

        /// \cond
        public override void ShutdownCubiquityVolume()
        {
            if (!IsVolumeHandleNull())
            {
                // We only save if we are in editor mode, not if we are playing.
                bool saveChanges = (!Application.isPlaying) && (writePermissions == WritePermissions.ReadWrite);

                if (saveChanges)
                {
                    CommitChanges();
                }
                else
                {
                    DiscardChanges();
                }

                CubiquityDLL.DeleteVolume(volumeHandle.Value);
                volumeHandle = null;
            }
        }
예제 #30
0
            public Mesh BuildMeshFromNodeHandleForColoredCubesVolume(uint nodeHandle)
            {
                // At some point I should read this: http://forum.unity3d.com/threads/5687-C-plugin-pass-arrays-from-C

                Vector3 offset = new Vector3(0.5f, 0.5f, 0.5f);                 // Required for the CubicVertex decoding process.

                // Create rendering and possible collision meshes.
                Mesh renderingMesh = new Mesh();

                renderingMesh.hideFlags = HideFlags.DontSave;

                // Get the data from Cubiquity.
                int[] indices = CubiquityDLL.GetIndices(nodeHandle);
                ColoredCubesVertex[] cubiquityVertices = CubiquityDLL.GetVertices(nodeHandle);

                // Create the arrays which we'll copy the data to.
                Vector3[] renderingVertices = new Vector3[cubiquityVertices.Length];
                Color32[] renderingColors   = new Color32[cubiquityVertices.Length];

                for (int ct = 0; ct < cubiquityVertices.Length; ct++)
                {
                    // Get the vertex data from Cubiquity.
                    Vector3 position = new Vector3(cubiquityVertices[ct].x, cubiquityVertices[ct].y, cubiquityVertices[ct].z);
                    position -= offset;                     // Part of the CubicVertex decoding process.
                    QuantizedColor color = cubiquityVertices[ct].color;

                    // Copy it to the arrays.
                    renderingVertices[ct] = position;
                    renderingColors[ct]   = (Color32)color;
                }

                // Assign vertex data to the meshes.
                renderingMesh.vertices  = renderingVertices;
                renderingMesh.colors32  = renderingColors;
                renderingMesh.triangles = indices;

                // FIXME - Get proper bounds
                renderingMesh.bounds.SetMinMax(new Vector3(0.0f, 0.0f, 0.0f), new Vector3(32.0f, 32.0f, 32.0f));

                return(renderingMesh);
            }