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);
        }
    }
Beispiel #2
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;
    }
Beispiel #4
0
    /// <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);
    }
Beispiel #5
0
 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;
         }
     }
 }
Beispiel #6
0
    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);
        }
    }
Beispiel #7
0
    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);
    }
Beispiel #11
0
    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);
    }
Beispiel #14
0
    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);
    }
Beispiel #15
0
    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);
    }
Beispiel #17
0
    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));
    }
Beispiel #18
0
    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]);
                }
            }
        }
    }
Beispiel #19
0
    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);
        }
    }
Beispiel #20
0
    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();
        }
    }
Beispiel #21
0
    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);
    }
Beispiel #22
0
    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);
    }
Beispiel #24
0
    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);
    }
Beispiel #25
0
 public bool CaveCondition(int x, int y, int z, WixelChunk chunk)
 {
     return(y <= _stoneHeight && _caveSize < _caveChance);
 }
Beispiel #26
0
 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);
 }