Пример #1
0
    private void Update()
    {
        if (requests.Count > 0)
        {
            MeshRequest request = requests.OrderBy(x => Vector3.SqrMagnitude(x.chunk.centerPos - Observer.transform.position)).First();
            requests.Remove(request);

            lock (requests) {
                ThreadStart thread = delegate {
                    request.chunk.March(request.callback);
                };
                thread.Invoke();
            }
        }
    }
Пример #2
0
        /// <summary>
        /// Returns the next logical mesh to generate.
        /// </summary>
        /// <returns></returns>
        public static MeshRequest[] getNextRequests()
        {
            int size = Math.Min(10, getRequestCount());

            MeshRequest[] ret = new MeshRequest[size];

            lock (requestArray)
            {
                for (int i = 0; i < ret.Length; i++)
                {
                    ret[i] = getNextRequest();
                }
            }

            return(ret);
        }
Пример #3
0
        /// <summary>
        /// Adds a request to generate a mesh
        /// </summary>
        /// <param name="_node">The node the mesh is for</param>
        public static void requestMesh(Node _node)
        {
            MeshRequest req = new MeshRequest
            {
                node         = _node,
                pos          = _node.position,
                LOD          = _node.LOD,
                isDone       = false,
                hasDensities = (_node.densityData != null)
            };

            if (!req.hasDensities)
            {
                lock (requestArray[req.LOD + 1])
                    requestArray[req.LOD + 1].Enqueue(req);
            }
            else
            {
                lock (requestArray[0])
                    requestArray[0].Enqueue(req);
            }
        }
Пример #4
0
        public static void update()
        {
            if (setMeshQueue.Count > 0)
            {
                MeshRequest req = setMeshQueue.Dequeue();
                req.node.setMesh(req.meshData);
            }

            for (int i = 0; i < generatorThreads.Length; i++)
            {
                MeshRequest req;
                while ((req = generatorThreads[i].getFinishedMesh()) != null)
                {
                    chunksFinished++;
                    if (req.node.disposed == false)
                    {
                        req.node.densityData = req.densities;
                        if (req.meshData.triangleArray.Length > 0)
                        {
                            setMeshQueue.Enqueue(req);
                        }
                        else
                        {
                            req.node.setMesh(req.meshData);
                        }
                    }
                }
            }

            #region Save/Load threads
            Node node;
            while ((node = fileThread.getFinishedLoadRequest()) != null)
            {
                node.regenerateChunk(); nodesLoaded++;
            }
            #endregion
        }
Пример #5
0
        /// <summary>
        /// Adds a request to generate a mesh
        /// </summary>
        /// <param name="_node">The node the mesh is for</param>
        public static void requestMesh(Node _node)
        {
            MeshRequest req = new MeshRequest
            {
                node = _node,
                pos = _node.position,
                LOD = _node.LOD,
                isDone = false,
                hasDensities = (_node.densityData != null)
            };

            if (!req.hasDensities)
                lock (requestArray[req.LOD + 1])
                    requestArray[req.LOD + 1].Enqueue(req);
            else
                lock (requestArray[0])
                    requestArray[0].Enqueue(req);
        }
Пример #6
0
        /// <summary>
        /// Returns the next logical mesh to generate.
        /// </summary>
        /// <returns></returns>
        public static MeshRequest[] getNextRequests()
        {
            int size = Math.Min(10, getRequestCount());
            MeshRequest[] ret = new MeshRequest[size];

            lock (requestArray)
            {
                for (int i = 0; i < ret.Length; i++)
                {
                    ret[i] = getNextRequest();
                }
            }

            return ret;
        }
Пример #7
0
        /// <summary>
        /// Generates the mesh data
        /// </summary>
        public static void GenerateMeshData(MeshRequest request)
        {
            MeshData meshData = new MeshData();
            request.meshData = meshData;

            //Check if the node requesting a generation has been disposed
            if (request == null || request.node.disposed)
            {
                meshData.triangleArray = new Vector3[0];
                meshData.indexArray = new int[0][];
                meshData.uvArray = new Vector2[0];
                meshData.normalArray = new Vector3[0];
                request.isDone = true;
                return;
            }

            DensityData densityArray = request.densities;

            Vector3[, ,] densityNormals = new Vector3[17, 17, 17];
            List<Triangle> triangleList = new List<Triangle>();
            List<int> subMeshIDList = new List<int>();
            int[] subMeshTriCount = new int[QuixelEngine.materials.Length];
            Node node = request.node;
            request.meshData = meshData;

            //Unoptimized generation
            densityNormals = new Vector3[18, 18, 18];
            if (!request.hasDensities)
            {
                for (int x = -1; x < 18; x++)
                {
                    for (int y = -1; y < 18; y++)
                    {
                        for (int z = -1; z < 18; z++)
                        {
                            VoxelData data = calculateDensity(node, new Vector3I(x, y, z));
                            densityArray.set(x, y, z, data.density);
                            densityArray.setMaterial(x, y, z, data.material);
                        }
                    }
                }
            }

            for (int x = 0; x < 17; x++)
            {
                for (int y = 0; y < 17; y++)
                {
                    for (int z = 0; z < 17; z++)
                    {
                        densityNormals[x, y, z] = calculateDensityNormal(new Vector3I(x, y, z), densityArray, node.LOD);
                    }
                }
            }
            for (int x = 0; x < 16; x++)
            {
                for (int y = 0; y < 16; y++)
                {
                    for (int z = 0; z < 16; z++)
                    {
                        generateTriangles(node, new Vector3I(x, y, z), triangleList, subMeshIDList, subMeshTriCount, densityArray, densityNormals);
                    }
                }
            }
            int ppos = 0;
            int li = 0;
            try
            {
                meshData.triangleArray = new Vector3[triangleList.Count * 3];
                meshData.indexArray = new int[QuixelEngine.materials.Length][];
                for (int i = 0; i < QuixelEngine.materials.Length; i++)
                    meshData.indexArray[i] = new int[(subMeshTriCount[i] * 3) * 3];
                meshData.uvArray = new Vector2[meshData.triangleArray.Length];
                meshData.normalArray = new Vector3[meshData.triangleArray.Length];

                int count = 0;
                int[] indCount = new int[QuixelEngine.materials.Length];
                for (int i = 0; i < triangleList.Count; i++)
                {
                    ppos = i;
                    Triangle triangle = triangleList[i];
                    meshData.triangleArray[count + 2] = triangle.pointOne;
                    meshData.triangleArray[count + 1] = triangle.pointTwo;
                    meshData.triangleArray[count + 0] = triangle.pointThree;

                    meshData.normalArray[count + 2] = triangle.nOne;
                    meshData.normalArray[count + 1] = triangle.nTwo;
                    meshData.normalArray[count + 0] = triangle.nThree;

                    int ind = subMeshIDList[i];
                    li = subMeshIDList[i];
                    meshData.indexArray[ind][indCount[ind] + 0] = count + 0;
                    meshData.indexArray[ind][indCount[ind] + 1] = count + 1;
                    meshData.indexArray[ind][indCount[ind] + 2] = count + 2;

                    meshData.uvArray[count + 0] = new Vector2(meshData.triangleArray[count + 0].x, meshData.triangleArray[count + 0].z);
                    meshData.uvArray[count + 1] = new Vector2(meshData.triangleArray[count + 1].x, meshData.triangleArray[count + 1].z);
                    meshData.uvArray[count + 2] = new Vector2(meshData.triangleArray[count + 2].x, meshData.triangleArray[count + 2].z);
                    count += 3;
                    indCount[subMeshIDList[i]] += 3;
                }
            }
            catch (Exception e)
            {
                StreamWriter sw = new StreamWriter("Error Log.txt");
                sw.WriteLine(e.Message + "\r\n" + e.StackTrace);
                for (int i = 0; i < QuixelEngine.materials.Length; i++)
                    sw.WriteLine(i + ": " + subMeshTriCount[i]);
                sw.WriteLine(ppos);
                sw.WriteLine(li);
                sw.Close();
            }
            request.isDone = true;
        }
Пример #8
0
        /// <summary>
        /// Generates the mesh data
        /// </summary>
        public static void GenerateMeshData(MeshRequest request)
        {
            MeshData meshData = new MeshData();

            request.meshData = meshData;

            //Check if the node requesting a generation has been disposed
            if (request == null || request.node.disposed)
            {
                meshData.triangleArray = new Vector3[0];
                meshData.indexArray    = new int[0][];
                meshData.uvArray       = new Vector2[0];
                meshData.normalArray   = new Vector3[0];
                request.isDone         = true;
                return;
            }

            DensityData densityArray = request.densities;

            Vector3[, ,] densityNormals = new Vector3[17, 17, 17];
            List <Triangle> triangleList  = new List <Triangle>();
            List <int>      subMeshIDList = new List <int>();

            int[] subMeshTriCount = new int[QuixelEngine.materials.Length];
            Node  node            = request.node;

            request.meshData = meshData;

            //Unoptimized generation
            densityNormals = new Vector3[18, 18, 18];
            if (!request.hasDensities)
            {
                for (int x = -1; x < 18; x++)
                {
                    for (int y = -1; y < 18; y++)
                    {
                        for (int z = -1; z < 18; z++)
                        {
                            VoxelData data = calculateDensity(node, new Vector3I(x, y, z));
                            densityArray.set(x, y, z, data.density);
                            densityArray.setMaterial(x, y, z, data.material);
                        }
                    }
                }
            }

            for (int x = 0; x < 17; x++)
            {
                for (int y = 0; y < 17; y++)
                {
                    for (int z = 0; z < 17; z++)
                    {
                        densityNormals[x, y, z] = calculateDensityNormal(new Vector3I(x, y, z), densityArray, node.LOD);
                    }
                }
            }
            for (int x = 0; x < 16; x++)
            {
                for (int y = 0; y < 16; y++)
                {
                    for (int z = 0; z < 16; z++)
                    {
                        generateTriangles(node, new Vector3I(x, y, z), triangleList, subMeshIDList, subMeshTriCount, densityArray, densityNormals);
                    }
                }
            }
            int ppos = 0;
            int li   = 0;

            try
            {
                meshData.triangleArray = new Vector3[triangleList.Count * 3];
                meshData.indexArray    = new int[QuixelEngine.materials.Length][];
                for (int i = 0; i < QuixelEngine.materials.Length; i++)
                {
                    meshData.indexArray[i] = new int[(subMeshTriCount[i] * 3) * 3];
                }
                meshData.uvArray     = new Vector2[meshData.triangleArray.Length];
                meshData.normalArray = new Vector3[meshData.triangleArray.Length];

                int   count    = 0;
                int[] indCount = new int[QuixelEngine.materials.Length];
                for (int i = 0; i < triangleList.Count; i++)
                {
                    ppos = i;
                    Triangle triangle = triangleList[i];
                    meshData.triangleArray[count + 2] = triangle.pointOne;
                    meshData.triangleArray[count + 1] = triangle.pointTwo;
                    meshData.triangleArray[count + 0] = triangle.pointThree;

                    meshData.normalArray[count + 2] = triangle.nOne;
                    meshData.normalArray[count + 1] = triangle.nTwo;
                    meshData.normalArray[count + 0] = triangle.nThree;

                    int ind = subMeshIDList[i];
                    li = subMeshIDList[i];
                    meshData.indexArray[ind][indCount[ind] + 0] = count + 0;
                    meshData.indexArray[ind][indCount[ind] + 1] = count + 1;
                    meshData.indexArray[ind][indCount[ind] + 2] = count + 2;

                    meshData.uvArray[count + 0] = new Vector2(meshData.triangleArray[count + 0].x, meshData.triangleArray[count + 0].z);
                    meshData.uvArray[count + 1] = new Vector2(meshData.triangleArray[count + 1].x, meshData.triangleArray[count + 1].z);
                    meshData.uvArray[count + 2] = new Vector2(meshData.triangleArray[count + 2].x, meshData.triangleArray[count + 2].z);
                    count += 3;
                    indCount[subMeshIDList[i]] += 3;
                }
            }
            catch (Exception e)
            {
                StreamWriter sw = new StreamWriter("Error Log.txt");
                sw.WriteLine(e.Message + "\r\n" + e.StackTrace);
                for (int i = 0; i < QuixelEngine.materials.Length; i++)
                {
                    sw.WriteLine(i + ": " + subMeshTriCount[i]);
                }
                sw.WriteLine(ppos);
                sw.WriteLine(li);
                sw.Close();
            }
            request.isDone = true;
        }