private void LoadAndRenderChunks() { if (_buildList.Count != 0) { for (int i = 0; i < _buildList.Count && i < 8; i++) { BuildChunk(_buildList[0]); _buildList.RemoveAt(0); } //If chunks were built return early return; } if (_updateList.Count != 0) { WixelChunk chunk = World.GetChunk(_updateList[0].x, _updateList[0].y, _updateList[0].z); if (chunk != null) { chunk.PerformUpdates = true; } _updateList.RemoveAt(0); } }
public void CreateChunk(int x, int y, int z) { WorldPosition worldPos = new WorldPosition(x, y, z); //Instantiate the chunk at the coordinates using the chunk prefab GameObject newChunkObject = Instantiate(chunkPrefab, new Vector3(x, y, z), Quaternion.Euler(Vector3.zero)) as GameObject; WixelChunk newChunk = newChunkObject.GetComponent <WixelChunk>(); newChunk.WorldPosition = worldPos; newChunk.World = this; // Parent all chunks to the world. newChunkObject.transform.SetParent(transform); //Add it to the chunks dictionary with the position as the key chunks.Add(worldPos, newChunk); //var terrainGen = new WixelTerrainGenerator(WixelRepository); var terrainGen = new DefaultChunkGenerator(WixelRepository); newChunk = terrainGen.GenerateChunk(newChunk); newChunk.SetBlocksUnmodified(); WixelRepository.LoadChunk(newChunk); }
protected virtual void OnBeforeGenerateChunk(WixelChunk chunk) { if (!_runMetrics) { return; } _startGenerateTime = Time.time; }
/// <summary> /// If this criteria's condition is true, perform the associated /// action. /// </summary> /// <param name="x">X chunk coordinate</param> /// <param name="y">Y chunk coordinate</param> /// <param name="z">Z chunk coordinate</param> /// <param name="chunk">Chunk to operate on</param> public void CheckCriteria(int x, int y, int z, WixelChunk chunk) { if (!Condition(x, y, z, chunk)) { return; } Action(x, y, z, chunk); }
private void UpdateIfEqual(int value1, int value2, WorldPosition pos) { if (value1 == value2) { WixelChunk chunk = GetChunk(pos.x, pos.y, pos.z); if (chunk != null) { chunk.PerformUpdates = true; } } }
public void DirtTreeGenerate(int x, int y, int z, WixelChunk chunk) { SetBlock(x, y, z, _grass, chunk); bool isAtDirtHeight = y == _dirtHeight; bool canMakeTree = GetNoise(x, 0, z, _treeFrequency, 100) < _treeDensity; if (isAtDirtHeight && canMakeTree) { CreateTree(x, y + 1, z, chunk); } }
public void DestroyChunk(int x, int y, int z) { WixelChunk chunk = null; if (chunks.TryGetValue(new WorldPosition(x, y, z), out chunk)) { WixelRepository.SaveChunk(chunk); Destroy(chunk.gameObject); chunks.Remove(new WorldPosition(x, y, z)); } }
private void FindChunksToLoad() { //Get the position of this gameobject to generate around WorldPosition playerPos = new WorldPosition( Mathf.FloorToInt(transform.position.x / WixelChunk.chunkSize) * WixelChunk.chunkSize, Mathf.FloorToInt(transform.position.y / WixelChunk.chunkSize) * WixelChunk.chunkSize, Mathf.FloorToInt(transform.position.z / WixelChunk.chunkSize) * WixelChunk.chunkSize ); //If there aren't already chunks to generate if (_updateList.Count == 0) { //Cycle through the array of positions for (int i = 0; i < _chunkPositions.Length; i++) { //translate the player position and array position into chunk position WorldPosition newChunkPos = new WorldPosition( _chunkPositions[i].x * WixelChunk.chunkSize + playerPos.x, 0, _chunkPositions[i].z * WixelChunk.chunkSize + playerPos.z ); //Get the chunk in the defined position WixelChunk newChunk = World.GetChunk(newChunkPos.x, newChunkPos.y, newChunkPos.z); //If the chunk already exists and it's already //rendered or in queue to be rendered continue if (newChunk != null && (newChunk.IsRendered || _updateList.Contains(newChunkPos))) { continue; } //load a column of chunks in this position // TODO: Make the y ranges configurable! for (int y = -4; y < 4; y++) { for (int x = newChunkPos.x - WixelChunk.chunkSize; x <= newChunkPos.x + WixelChunk.chunkSize; x += WixelChunk.chunkSize) { for (int z = newChunkPos.z - WixelChunk.chunkSize; z <= newChunkPos.z + WixelChunk.chunkSize; z += WixelChunk.chunkSize) { _buildList.Add(new WorldPosition(x, y * WixelChunk.chunkSize, z)); } } _updateList.Add(new WorldPosition(newChunkPos.x, y * WixelChunk.chunkSize, newChunkPos.z)); } return; } } }
/// <summary> /// Sets the given block at the X/Y/Z chunk coordinates for a chunk. /// </summary> /// <param name="x">Chunk X coordinate</param> /// <param name="y">Chunk Y coordinate</param> /// <param name="z">Chunk Z coordinate</param> /// <param name="block">Block to set</param> /// <param name="chunk">Chunk in which to set the block</param> /// <param name="replaceBlocks">Optional; if true, overwrite any block at the current chunk coordinate.</param> protected static void SetBlock(int x, int y, int z, Wixel block, WixelChunk chunk, bool replaceBlocks = false) { x -= chunk.WorldPosition.x; y -= chunk.WorldPosition.y; z -= chunk.WorldPosition.z; bool isInRange = WixelChunk.InRange(x) && WixelChunk.InRange(y) && WixelChunk.InRange(z); if (isInRange && (replaceBlocks || chunk.Blocks[x, y, z] == null)) { chunk.SetBlock(x, y, z, block); } }
protected virtual void OnAfterGenerateChunk(WixelChunk chunk) { if (!_runMetrics) { return; } _endGenerateTime = Time.time; float elapsedTime = _endGenerateTime - _startGenerateTime; string message = string.Format("Chunk at {0} was generated in {1} seconds", chunk.WorldPosition, elapsedTime); Debug.Log(message); }
protected override void OnBeforeGenerateColumn(int x, int z, WixelChunk chunk) { _stoneHeight = Mathf.FloorToInt(_stoneBaseHeight); _stoneHeight += GetNoise(x, 0, z, _stoneMountainFrequency, Mathf.FloorToInt(_stoneMountainHeight)); if (_stoneHeight < _stoneMinHeight) { _stoneHeight = Mathf.FloorToInt(_stoneMinHeight); } _stoneHeight += GetNoise(x, 0, z, _stoneBaseNoise, Mathf.FloorToInt(_stoneBaseNoiseHeight)); _dirtHeight = _stoneHeight + Mathf.FloorToInt(_dirtBaseHeight); _dirtHeight += GetNoise(x, 100, z, _dirtNoise, Mathf.FloorToInt(_dirtNoiseHeight)); }
public Wixel GetBlock(RaycastHit hit, bool adjacent = false) { WixelChunk chunk = hit.collider.GetComponent <WixelChunk>(); if (chunk == null) { return(null); } WorldPosition pos = GetBlockPosition(hit, adjacent); Wixel block = chunk.World.GetBlock(pos.x, pos.y, pos.z); return(block); }
public bool SetBlock(RaycastHit hit, Wixel block, bool adjacent = false) { WixelChunk chunk = hit.collider.GetComponent <WixelChunk>(); if (chunk == null) { return(false); } WorldPosition pos = GetBlockPosition(hit, adjacent); chunk.World.SetBlock(pos.x, pos.y, pos.z, block); return(true); }
public WixelChunk GetChunk(int x, int y, int z) { WorldPosition pos = new WorldPosition(); float multiple = WixelChunk.chunkSize; pos.x = Mathf.FloorToInt(x / multiple) * WixelChunk.chunkSize; pos.y = Mathf.FloorToInt(y / multiple) * WixelChunk.chunkSize; pos.z = Mathf.FloorToInt(z / multiple) * WixelChunk.chunkSize; WixelChunk containerChunk = null; chunks.TryGetValue(pos, out containerChunk); return(containerChunk); }
public WixelChunkMeshData BlockData(WixelChunk chunk, int x, int y, int z, WixelChunkMeshData meshData) { if (FaceInformation.Count == 0) { return(meshData); } // Programmer's Note // ----------------- // int x/y/z is fine due to how this is being used. Vector3 worldPosition = new Vector3(x, y, z); meshData.useRenderDataForCol = true; if (!chunk.GetBlock(x, y + 1, z).IsSolid(WixelDirection.Down)) { meshData = FaceData(WixelDirection.Up, chunk, worldPosition, meshData); } if (!chunk.GetBlock(x, y - 1, z).IsSolid(WixelDirection.Up)) { meshData = FaceData(WixelDirection.Down, chunk, worldPosition, meshData); } if (!chunk.GetBlock(x, y, z + 1).IsSolid(WixelDirection.South)) { meshData = FaceData(WixelDirection.North, chunk, worldPosition, meshData); } if (!chunk.GetBlock(x, y, z - 1).IsSolid(WixelDirection.North)) { meshData = FaceData(WixelDirection.South, chunk, worldPosition, meshData); } if (!chunk.GetBlock(x + 1, y, z).IsSolid(WixelDirection.West)) { meshData = FaceData(WixelDirection.East, chunk, worldPosition, meshData); } if (!chunk.GetBlock(x - 1, y, z).IsSolid(WixelDirection.East)) { meshData = FaceData(WixelDirection.West, chunk, worldPosition, meshData); } return(meshData); }
/// <summary> /// Generates wixels into the given chunk. /// </summary> /// <param name="chunk">Chunk in which to generate</param> /// <returns>Chunk with modifications.</returns> public WixelChunk GenerateChunk(WixelChunk chunk) { OnBeforeGenerateChunk(chunk); // Make the 3 a configurable thing (tree radius + 1?) for (int x = chunk.WorldPosition.x - 3; x < chunk.WorldPosition.x + WixelChunk.chunkSize + 3; x++) { for (int z = chunk.WorldPosition.z - 3; z < chunk.WorldPosition.z + WixelChunk.chunkSize + 3; z++) { chunk = GenerateColumn(chunk, x, z); } } OnAfterGenerateChunk(chunk); return(chunk); }
public void SetBlock(int x, int y, int z, Wixel block) { WixelChunk chunk = GetChunk(x, y, z); if (chunk == null) { return; } chunk.SetBlock(x - chunk.WorldPosition.x, y - chunk.WorldPosition.y, z - chunk.WorldPosition.z, block); chunk.PerformUpdates = true; UpdateIfEqual(x - chunk.WorldPosition.x, WixelChunk.chunkSize - 1, new WorldPosition(x + 1, y, z)); UpdateIfEqual(y - chunk.WorldPosition.y, 0, new WorldPosition(x, y - 1, z)); UpdateIfEqual(y - chunk.WorldPosition.y, WixelChunk.chunkSize - 1, new WorldPosition(x, y + 1, z)); UpdateIfEqual(z - chunk.WorldPosition.z, 0, new WorldPosition(x, y, z - 1)); UpdateIfEqual(z - chunk.WorldPosition.z, WixelChunk.chunkSize - 1, new WorldPosition(x, y, z + 1)); }
public WixelChunkSaveBuffer(WixelChunk chunk) { for (int x = 0; x < WixelChunk.chunkSize; x++) { for (int y = 0; y < WixelChunk.chunkSize; y++) { for (int z = 0; z < WixelChunk.chunkSize; z++) { if (!chunk.Blocks[x, y, z].HasChanged) { continue; } WorldPosition pos = new WorldPosition(x, y, z); Blocks.Add(pos, chunk.Blocks[x, y, z]); } } } }
public Wixel GetBlock(int x, int y, int z) { WixelChunk containerChunk = GetChunk(x, y, z); if (containerChunk != null) { Wixel block = containerChunk.GetBlock( x - containerChunk.WorldPosition.x, y - containerChunk.WorldPosition.y, z - containerChunk.WorldPosition.z ); return(block); } else { Wixel airWixel = WixelRepository.GetWixelByName("Air"); return(airWixel); } }
public void SaveChunk(WixelChunk chunk) { WixelChunkSaveBuffer save = new WixelChunkSaveBuffer(chunk); if (save.Blocks.Count == 0) { return; } string saveFile = SaveLocation(chunk.World.WorldName); saveFile += FileName(chunk.WorldPosition); IFormatter formatter = new BinaryFormatter(); using (Stream stream = new FileStream(saveFile, FileMode.Create, FileAccess.Write, FileShare.None)) { formatter.Serialize(stream, chunk.Blocks); stream.Close(); } }
private WixelChunkMeshData FaceData(WixelDirection direction, WixelChunk chunk, Vector3 worldPosition, WixelChunkMeshData meshData) { if (FaceInformation.Count == 0) { return(meshData); } WixelDirectionInformation faceInfo = GetInformationByDirection(direction); for (int i = 0; i < faceInfo.Vertices.Count; i++) { Vector3 vertexPosition = faceInfo.Vertices[i] * blockScale; Vector3 actualPosition = vertexPosition + worldPosition; meshData.AddVertex(actualPosition); } meshData.AddQuadTriangles(); meshData.uv.AddRange(FaceUVs(direction)); return(meshData); }
private void CreateTree(int x, int y, int z, WixelChunk chunk) { //create leaves // TODO - Make tree radius configurable/randomized? for (int xi = -2; xi <= 2; xi++) { for (int yi = 4; yi <= 8; yi++) { for (int zi = -2; zi <= 2; zi++) { SetBlock(x + xi, y + yi, z + zi, _leaves, chunk, true); } } } //create trunk // TODO - Make trunk height configurable/randomized? for (int yt = 0; yt < 6; yt++) { SetBlock(x, y + yt, z, _wood, chunk, true); } }
/// <summary> /// Generates a column of wixels in the given chunk. /// </summary> /// <param name="chunk">Chunk in which to generate wixels</param> /// <param name="x">X chunk coordinate</param> /// <param name="z">Z chunk coordinate</param> /// <returns>Chunk with modifications.</returns> protected WixelChunk GenerateColumn(WixelChunk chunk, int x, int z) { OnBeforeGenerateColumn(x, z, chunk); // TODO: Implement for (int y = chunk.WorldPosition.y - 8; y < chunk.WorldPosition.y + WixelChunk.chunkSize; y++) { OnBeforeGenerateBlock(x, y, z, chunk); for (int i = 0; i < _generationCriteria.Count; i++) { WixelGenerationCriteria current = _generationCriteria[i]; current.CheckCriteria(x, y, z, chunk); } OnAfterGenerateBlock(x, y, z, chunk); } OnAfterGenerateColumn(x, z, chunk); return(chunk); }
public bool LoadChunk(WixelChunk chunk) { string saveFile = SaveLocation(chunk.World.WorldName); saveFile += FileName(chunk.WorldPosition); if (!File.Exists(saveFile)) { return(false); } IFormatter formatter = new BinaryFormatter(); using (FileStream stream = new FileStream(saveFile, FileMode.Open)) { try { WixelChunkSaveBuffer save = (WixelChunkSaveBuffer)formatter.Deserialize(stream); foreach (var block in save.Blocks) { chunk.Blocks[block.Key.x, block.Key.y, block.Key.z] = block.Value; } } catch (Exception ex) { Console.WriteLine(ex.Message); } finally { stream.Close(); } } return(true); }
public bool CaveCondition(int x, int y, int z, WixelChunk chunk) { return(y <= _stoneHeight && _caveSize < _caveChance); }
public bool DirtTreeCondition(int x, int y, int z, WixelChunk chunk) { return(y <= _dirtHeight && _caveSize < _caveChance); }
protected virtual void OnAfterGenerateBlock(int x, int y, int z, WixelChunk chunk) { }
protected virtual void OnAfterGenerateColumn(int x, int z, WixelChunk chunk) { }
protected virtual void OnBeforeGenerateColumn(int x, int z, WixelChunk chunk) { }
/// <summary> /// Default condition for Wixel Chunk Generation. /// </summary> /// <returns>True always</returns> public bool DefaultCondition(int x, int y, int z, WixelChunk chunk) { return(true); }