/// <summary> /// Regenerates the Chunk on recompile. /// </summary> private void OnValidate() { pointsHaveBeenGenerated = false; waterChunk = GetComponentInChildren <WaterChunk>(); waterChunk.pointsHaveBeenGenerated = false; GetMesh(); }
/// <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; }
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); }
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); }
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(); } } } } }
void OnWaterVisibilityChanged(WaterChunk chunk, bool isVisible) { if (isVisible) { visibleWaterChunks.Add(chunk); } else { visibleWaterChunks.Remove(chunk); } }
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); }
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(); }
//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(); }
/// <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(); }
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; } }