Beispiel #1
0
        /// <summary>
        /// Checks if mesh generation on other thread or on the GPU is finished. If so, it is applied to the mesh.
        /// </summary>
        public void Update()
        {
            if (cookie != null && cookie.IsCompleted)
            {
                MeshData result = method.EndInvoke(cookie);
                ApplyToMesh(result);
                UpdateDistances();
                cookie = null;
                method = null;
            }

            if (isComputingOnGPU && gpuReadbackReq.done)
            {
                isComputingOnGPU = false;

                if (gpuReadbackReq.hasError)
                {
                    computeBuffer.Dispose();
                    computeBuffer    = null;
                    configurationOld = bool4.True;
                    GetNeighbors();
                }
                else
                {
                    var      a  = gpuReadbackReq.GetData <Vector3>().ToArray();
                    MeshData md = new MeshData(a, planet.quadMesh.normals, planet.quadMesh.uv);

                    //print(md.vertices.Length + ", [0]: " + md.vertices[0].ToString("F4") + ", [1089]: " + md.vertices[1089].ToString("F4"));
                    method = SpherifyAndDisplace;
                    cookie = method.BeginInvoke(md, null, null);
                    computeBuffer.Dispose();
                    computeBuffer = null;
                }
            }

            //Foliage Stuff:

            if (planet.generateDetails && (planet.generateFoliageInEveryBiome || planet.foliageBiomes.Contains(uniformBiome))) //Generating details if enabled and right biome.
            {
                if (level >= planet.grassLevel && foliageRenderer == null && renderedQuad && collider && distance < planet.dtDisSqr && planet.detailObjectsGenerating < planet.detailObjectsGeneratingSimultaneously)
                {
                    var        down = planet.Vector3Down(renderedQuad.transform.position);
                    Ray        ray  = new Ray(collider.bounds.center - (down * 500), down);
                    RaycastHit hit;

                    if (collider.Raycast(ray, out hit, 5000f)) //Only start foliage generation if the collider is working, it needs a few frames to initialize
                    {
                        foliageRenderer        = renderedQuad.AddComponent <FoliageRenderer>();
                        foliageRenderer.planet = planet;
                        foliageRenderer.quad   = this;
                        planet.detailObjectsGenerating++;
                    }
                }
                if (foliageRenderer != null && distance > planet.dtDisSqr)
                {
                    MonoBehaviour.Destroy(foliageRenderer);
                    foliageRenderer = null;
                }
            }
        }
Beispiel #2
0
 public bool4(bool4 bools)
 {
     this.x = bools.x;
     this.y = bools.y;
     this.z = bools.z;
     this.w = bools.w;
 }
Beispiel #3
0
 /// <summary>
 /// Resets all variables. Used for pooling.
 /// </summary>
 public void Reset()
 {
     uniformBiome     = 0;
     parent           = null;
     children         = null;
     neighbors        = null;
     configuration    = bool4.False;
     hasSplit         = false;
     isSplitting      = false;
     initialized      = false;
     isComputingOnGPU = false;
     computeBuffer    = null;
     configurationOld = bool4.True;
     collider         = null;
     neighborIds      = null;
     meshOffset       = Vector3.zero;
     foliageRenderer  = null;
     distance         = Mathf.Infinity;
     coroutine        = null;
     level            = 1;
     msd            = 0f;
     gpuReadbackReq = new AsyncGPUReadbackRequest();
 }
Beispiel #4
0
        /// <summary>
        /// Finds this Quad's neighbors, then checks if edge fans are needed. If so, they are applied.
        /// </summary>
        public void GetNeighbors()
        {
            if (neighborIds == null) //Finding the IDs of all neigbors. This is only done once.
            {
                neighborIds = new string[4];
                for (int i = 0; i < 4; i++)
                {
                    neighborIds[i] = QuadNeighbor.GetNeighbor(index, i.ToString());
                }
            }
            neighbors = new Quad[4];
            for (int i = 0; i < neighbors.Length; i++) //Trying to find neighbors by id. If not there, neighbor has a lower subdivision level, last char of id is removed.
            {
                int j = 0;
                while (neighbors[i] == null && j < 4)
                {
                    neighbors[i] = planet.FindQuad(neighborIds[i].Substring(0, neighborIds[i].Length - j));
                    j++;
                }

                /*neighbors[i] = null;
                 * neighbors[i] = planet.FindQuad(neighborIds[i]);
                 *
                 * if (neighbors[i] == null)
                 *  neighbors[i] = planet.FindQuad(neighborIds[i].Substring(0, neighborIds[i].Length - 1));*/
            }

            configuration = bool4.False;

            for (int i = 0; i < neighbors.Length; i++) //Creating configuration based on neighbor levels.
            {
                if (neighbors[i] != null)
                {
                    if (neighbors[i].level == level - 1)
                    {
                        configuration[i] = true;
                    }
                    else
                    {
                        configuration[i] = false;
                    }
                }
                else
                {
                    configuration[i] = false;
                }
            }

            if (configuration != configurationOld) //Loading plane mesh and starting generation on another thread or GPU.
            {
                configurationOld = new bool4(configuration);

                if (!initialized)
                {
                    MeshData md = new MeshData(ConstantTriArrays.extendedPlane, planet.quadMesh.normals, planet.quadMesh.uv);

                    if (planet.mode == Mode.ComputeShader)
                    {
                        int kernelIndex = planet.computeShader.FindKernel("ComputePositions");

                        computeBuffer = new ComputeBuffer(1225, 12);
                        computeBuffer.SetData(ConstantTriArrays.extendedPlane);

                        planet.computeShader.SetFloat("scale", scale);
                        planet.computeShader.SetFloats("trPosition", new float[] { trPosition.x, trPosition.y, trPosition.z });
                        planet.computeShader.SetFloat("radius", planet.radius);
                        planet.computeShader.SetFloats("rotation", new float[] { rotation.x, rotation.y, rotation.z, rotation.w });
                        planet.computeShader.SetFloat("noiseDiv", 1f / planet.heightScale);

                        planet.computeShader.SetBuffer(kernelIndex, "dataBuffer", computeBuffer);

                        planet.computeShader.Dispatch(kernelIndex, 5, 1, 1);

                        gpuReadbackReq = AsyncGPUReadback.Request(computeBuffer);

                        isComputingOnGPU = true;
                    }
                    else
                    {
                        method = SpherifyAndDisplace;
                        cookie = method.BeginInvoke(md, null, null);
                    }
                }
                else
                {
                    if (mesh.vertices.Length > 0)
                    {
                        mesh.triangles = Utils.GetTriangles(configuration.ToString());
                    }
                    if (renderedQuad)
                    {
                        renderedQuad.GetComponent <MeshFilter>().mesh = mesh;
                    }
                }
            }
        }