예제 #1
0
 /// <summary>
 /// Regenerates the Chunk on recompile.
 /// </summary>
 private void OnValidate()
 {
     pointsHaveBeenGenerated = false;
     waterChunk = GetComponentInChildren <WaterChunk>();
     waterChunk.pointsHaveBeenGenerated = false;
     GetMesh();
 }
예제 #2
0
        /// <summary>
        /// This is called by the <seealso cref="GraphicsSystem"/> to query the WaterComponent for information
        /// needed to render the water plane.
        /// </summary>
        /// <param name="desc"></param>
        public override void QueryForChunks(ref RenderPassDesc desc)
        {
            // We don't render water on geometry render passes
            if (desc.GeometryChunksOnlyThisPass)
            {
                return;
            }

            // Check to see if the water plane is in the view frustum
            if (!desc.ViewFrustum.Intersects(this.boundingBox))
            {
                return;
            }

            WaterChunk chunk = this.parentEntity.Game.Graphics.AllocateWaterChunk();

            chunk.Vertices          = this.waterVertices;
            chunk.VertexDeclaration = vertexDeclaration;
            chunk.Material          = this.material;
            chunk.Type            = PrimitiveType.TriangleList;
            chunk.PrimitiveCount  = 2;  // The water plane is only two triangles.
            chunk.Elevation       = this.WaterElevation;
            chunk.Reflectivity    = this.reflectivity;
            chunk.WaterColorLight = this.waterColorLight;
            chunk.WaterColorDark  = this.waterColorDark;
        }
예제 #3
0
    TerrainChunkObject LoadChunk(ChunkPos cp, bool instant)
    {
        if (chunks.ContainsKey(cp))
        {
            return(chunks[cp]);
        }

        TerrainChunk chunk = TerrainChunkGenerator.request(cp, instant);

        if (chunk == null)
        {
            return(null);
        }

        int                xPos        = cp.x;
        int                zPos        = cp.z;
        GameObject         chunkGO     = Instantiate(terrainChunkPrefab, new Vector3(xPos, 0, zPos), Quaternion.identity);
        TerrainChunkObject chunkObject = chunkGO.GetComponent <TerrainChunkObject>();

        chunkObject.transform.parent = transform;
        chunkObject.name             = "Chunk:" + cp;

        chunkObject.BuildMesh(chunk);

        WaterChunk wat = chunkObject.transform.GetComponentInChildren <WaterChunk>();

        wat.SetLocs(chunk.blocks, chunkObject.Chunk);

        wat.BuildMesh();

        chunks.Add(cp, chunkObject);

        return(chunkObject);
    }
예제 #4
0
    private void BuildChunk(int4 chunkPos, int3[] blocks)
    {
        if (chunks.ContainsKey(chunkPos))
        {
            return;
        }
        Chunk chunk;

        if (pooledChunks.Count > 0)
        {
            chunk = pooledChunks[0];
            chunk.gameObject.SetActive(true);
            pooledChunks.RemoveAt(0);
            chunk.transform.position = new Vector3(chunkPos.x * Chunk.Width, chunkPos.y * Chunk.Height, chunkPos.z * Chunk.Width);
        }
        else
        {
            GameObject chunkGO = Instantiate(GameAssets.i.pfChunk.gameObject, new Vector3(chunkPos.x * Chunk.Width, chunkPos.y * Chunk.Height, chunkPos.z * Chunk.Width), Quaternion.identity);
            chunk = chunkGO.GetComponent <Chunk>();
        }

        GenerateTrees(chunkPos, ref blocks);
        chunk.blocks = blocks;

        WaterChunk wat = chunk.transform.GetComponentInChildren <WaterChunk>();

        wat.SetLocs(chunk.blocks);
        wat.BuildMesh();

        chunk.BuildMesh();
        chunks.Add(chunkPos, chunk);
    }
예제 #5
0
    void UpdateVisibleChunks()
    {
        HashSet <Vector2> alreadyUpdatedChunkCoord = new HashSet <Vector2>();

        //HashSet<Vector2> alreadyUpdatedWaterCoord = new HashSet<Vector2>();
        for (int i = visibleTerrainChunks.Count - 1; i >= 0; i--)
        {
            alreadyUpdatedChunkCoord.Add(visibleTerrainChunks[i].coord);
            visibleTerrainChunks[i].UpdateTerrainChunk();

            //alreadyUpdatedWaterCoord.Add(visibleWaterChunks[i].coord);
            //visibleWaterChunks[i].UpdateWaterChunk();
        }

        int currentChunkCoordX = Mathf.RoundToInt(viewerPosition.x / meshWorldSize);
        int currentChunkCoordY = Mathf.RoundToInt(viewerPosition.y / meshWorldSize);

        for (int yOffset = -chunksVisibleInViewDist; yOffset <= chunksVisibleInViewDist; yOffset++)
        {
            for (int xOffset = -chunksVisibleInViewDist; xOffset <= chunksVisibleInViewDist; xOffset++)
            {
                Vector2 viewedChunkCoord = new Vector2(currentChunkCoordX + xOffset, currentChunkCoordY + yOffset);
                if (!alreadyUpdatedChunkCoord.Contains(viewedChunkCoord))
                {
                    if (terrainChunkDictionary.ContainsKey(viewedChunkCoord))
                    {
                        terrainChunkDictionary[viewedChunkCoord].UpdateTerrainChunk();
                        waterChunkDictionary[viewedChunkCoord].UpdateWaterChunk();
                    }
                    else
                    {
                        TerrainChunk newChunk = new TerrainChunk(viewedChunkCoord, heightMapSettings, meshSettings, detailLevels, coliderLODIndex, transform, viewer, mapMaterial);
                        terrainChunkDictionary.Add(viewedChunkCoord, newChunk);
                        newChunk.onVisibilityChanged += OnChunkVisibilityChanged;
                        newChunk.Load();


                        //overwater Object
                        waterObject = Instantiate(waterSettings.waterPrefab, transform);
                        WaterChunk newWater = new WaterChunk(waterObject, true, viewedChunkCoord, heightMapSettings, meshSettings, waterSettings, detailLevels, transform, viewer);
                        waterChunkDictionary.Add(viewedChunkCoord, newWater);
                        newWater.onVisibilityChanged += OnWaterVisibilityChanged;
                        newWater.Load();

                        //underwater Object
                        waterObject = Instantiate(waterSettings.waterPrefab, transform);
                        WaterChunk newUnderwater = new WaterChunk(waterObject, false, viewedChunkCoord, heightMapSettings, meshSettings, waterSettings, detailLevels, transform, viewer);
                        underwaterChunkDictionary.Add(viewedChunkCoord, newUnderwater);
                        //newUnderwater.onVisibilityChanged += OnWaterVisibilityChanged;
                        newUnderwater.Load();
                    }
                }
            }
        }
    }
예제 #6
0
 void OnWaterVisibilityChanged(WaterChunk chunk, bool isVisible)
 {
     if (isVisible)
     {
         visibleWaterChunks.Add(chunk);
     }
     else
     {
         visibleWaterChunks.Remove(chunk);
     }
 }
예제 #7
0
    void BuildChunk(int xPos, int zPos)
    {
        TerrainChunk chunk;

        if (pooledChunks.Count > 0)//look in the poo first
        {
            chunk = pooledChunks[0];
            chunk.gameObject.SetActive(true);
            pooledChunks.RemoveAt(0);
            chunk.transform.position = new Vector3(xPos, 0, zPos);
        }
        else
        {
            GameObject chunkGO = Instantiate(terrainChunk, new Vector3(xPos, 0, zPos), Quaternion.identity);
            chunk = chunkGO.GetComponent <TerrainChunk>();
        }


        for (int x = 0; x < TerrainChunk.chunkWidth + 2; x++)
        {
            for (int z = 0; z < TerrainChunk.chunkWidth + 2; z++)
            {
                for (int y = 0; y < TerrainChunk.chunkHeight; y++)
                {
                    //if(Mathf.PerlinNoise((xPos + x-1) * .1f, (zPos + z-1) * .1f) * 10 + y < TerrainChunk.chunkHeight * .5f)
                    chunk.blocks[x, y, z] = GetBlockType(xPos + x - 1, y, zPos + z - 1);
                }
            }
        }


        GenerateTrees(chunk.blocks, xPos, zPos);

        chunk.BuildMesh();


        WaterChunk wat = chunk.transform.GetComponentInChildren <WaterChunk>();

        wat.SetLocs(chunk.blocks);
        wat.BuildMesh();



        chunks.Add(new ChunkPos(xPos, zPos), chunk);
    }
예제 #8
0
    private void Awake()
    {
        // Gets a reference to the MeshFilter, MeshRenderer, and MeshCollider components attached to the GameObject
        meshFilter   = GetComponent <MeshFilter>();
        meshRenderer = GetComponent <MeshRenderer>();
        meshCollider = GetComponent <MeshCollider>();

        // Gets a reference to the WaterChunk associated with this chunk.
        waterChunk = GetComponentInChildren <WaterChunk>();

        // Instantiates an empty mesh.
        mesh = new Mesh();

        // Initializes the points array to the appropriate size.
        points = new float[VoxelUtilities.pointsPerAxis * VoxelUtilities.pointsPerAxis * VoxelUtilities.pointsPerAxis];
        pointsHaveBeenGenerated = false;

        // Requests that a new mesh be created.
        GetMesh();
    }
예제 #9
0
    //Add a new water square if needed
    private void AddNewWaterSquare()
    {
        //Create a new water chunk
        WaterChunk newChunk = new WaterChunk();

        //Add it to the list of all chunks
        allWaterChunks.Add(newChunk);

        //Need to set its width and resolution before instantiating a chunk because we
        //are creating the mesh in awake
        WaterSquare waterSquareScript = waterSquareObj.GetComponent <WaterSquare>();

        waterSquareScript.width = chunkWidth;


        //Add water chunks with different resolutions
        waterSquareScript.resolution = 2;

        GameObject highDetailedWaterChunk = Instantiate(waterSquareObj, transform) as GameObject;

        newChunk.highDetailedWaterChunk = highDetailedWaterChunk;


        waterSquareScript.resolution = 5;

        GameObject mediumDetailedWaterChunk = Instantiate(waterSquareObj, transform) as GameObject;

        newChunk.mediumDetailedWaterChunk = mediumDetailedWaterChunk;


        waterSquareScript.resolution = 50;

        GameObject lowDetailedWaterChunk = Instantiate(waterSquareObj, transform) as GameObject;

        newChunk.lowDetailedWaterChunk = lowDetailedWaterChunk;

        //Deactivate the chunk
        newChunk.DeactivateChunk();
    }
예제 #10
0
    /// <summary>
    /// Static method <c>BuildMesh</c> takes the prepared <c>VoxelUtilities.MeshData</c>
    /// and creates a <c>Mesh</c>. This is necessary because the Unity API only allows
    /// meshes to be created on the main thread.
    /// </summary>
    /// <param name="chunk">The <c>WaterChunk</c> which has requested a <c>Mesh</c>.</param>
    private static void BuildMesh(WaterChunk chunk)
    {
        // Clears the old mesh
        chunk.mesh.Clear();

        // Sets the vertices, triangles, and colors.
        chunk.mesh.vertices  = chunk.meshData.vertices;
        chunk.mesh.triangles = chunk.meshData.triangles;
        chunk.mesh.colors    = chunk.meshData.colors;

        // Optimizes the mesh for faster rendering and CollisionMesh baking
        chunk.mesh.Optimize();

        // Calculates the normals of the mesh
        chunk.mesh.RecalculateNormals();

        // Assigns the mesh to the meshFilter and meshCollider to update it.
        chunk.meshFilter.sharedMesh   = chunk.mesh;
        chunk.meshCollider.sharedMesh = chunk.mesh;

        // Calls the chunk's MeshBuilt callback, to allow for post-generation steps.
        chunk.MeshBuilt();
    }
예제 #11
0
    private void UpdateTerrainChunks()
    {
        if (Vector3.Distance(viewer.position, viewerPositionLastUpdate) > viewerMoveThreshold)
        {
            // Reset the visible chunks from from the last update
            visibleChunksLastUpdate.ForEach(delegate(Chunk chunk) {
                chunk.SetVisible(false);
            });

            // Clear the list
            visibleChunksLastUpdate.Clear();

            // Find the current chunk that the viewer is on
            int currentChunkX = Mathf.RoundToInt(viewer.position.x / terrainData.size);
            int currentChunkY = Mathf.RoundToInt(viewer.position.z / terrainData.size);

            // Parse all the visible chunks and create/update them
            for (int x = -chunkNumber; x <= chunkNumber; x++)
            {
                for (int y = -chunkNumber; y <= chunkNumber; y++)
                {
                    TerrainChunk terrainChunk = null;
                    WaterChunk   waterChunk   = null;

                    // Current chunk coordinates
                    Vector2Int viewChunkCoords = new Vector2Int(x + currentChunkX, y + currentChunkY);

                    // If the chunk exists in the dictionary, try and get it
                    if (terrainChunkDict.ContainsKey(viewChunkCoords))
                    {
                        terrainChunkDict.TryGetValue(viewChunkCoords, out terrainChunk);
                    }
                    // Else, create it and add it to the dictionary
                    else
                    {
                        terrainChunk = terrainData.useVoxels
              ? new VoxelTerrainChunk(lodInfo, terrainData, viewChunkCoords, terrainMaterial, useColliders, transform)
              : new TerrainChunk(lodInfo, terrainData, viewChunkCoords, terrainMaterial, useColliders, transform);

                        terrainChunkDict.Add(viewChunkCoords, terrainChunk);
                    }

                    // Then update the chunk and add it to the visible last update list
                    if (terrainChunk != null)
                    {
                        terrainChunk.UpdateChunk(viewer.position);

                        if (terrainChunk.IsVisible())
                        {
                            visibleChunksLastUpdate.Add(terrainChunk);
                        }
                    }

                    // If the chunk exists in the dictionary, try and get it
                    if (waterChunkDict.ContainsKey(viewChunkCoords))
                    {
                        waterChunkDict.TryGetValue(viewChunkCoords, out waterChunk);
                    }
                    // Else, create it and add it to the dictionary
                    else
                    {
                        waterChunk = new WaterChunk(lodInfo, waterData, viewChunkCoords, waterMaterial, transform);

                        waterChunkDict.Add(viewChunkCoords, waterChunk);
                    }

                    // Then update the chunk and add it to the visible last update list
                    if (terrainChunk != null)
                    {
                        waterChunk.UpdateChunk(viewer.position);

                        if (waterChunk.IsVisible())
                        {
                            visibleChunksLastUpdate.Add(waterChunk);
                        }
                    }
                }
            }

            viewerPositionLastUpdate = viewer.position;
        }
    }