Example #1
0
        public Voxel GetVoxelAtHeight(int height, int y)
        {
            // Top layer should be grass
            var id = VoxelDictionary.IdByName("grass");

            if (y < height)
            {
                id = VoxelDictionary.IdByName("dirt");
            }

            if (y < height - 2)
            {
                id = VoxelDictionary.IdByName("stone");
            }

            if (y > height && y <= Chunk.SEA_LEVEL)
            {
                id = VoxelDictionary.IdByName("water");
            }

            if (y == height && y <= Chunk.SEA_LEVEL)
            {
                id = VoxelDictionary.IdByName("sand");
            }

            if (y > height && y > Chunk.SEA_LEVEL)
            {
                id = 0;
            }

            return(new Voxel(id));
        }
Example #2
0
        // Initialization
        private void Initialize()
        {
            VoxelWorld = new VoxelWorld(4582);

            UpdateJobs    = new BlockingCollection <ChunkUpdateJob>(new ConcurrentStack <ChunkUpdateJob>());
            _meshResults  = new ConcurrentStack <ChunkMeshResult>();
            _lightResults = new ConcurrentStack <ChunkLightResult>();

            // Initialize the voxel dictionary
            VoxelDictionary.InitializeVoxelDictionary();

            // Instantiate a new runtime texture atlas
            AtlasGenerator = new RuntimeTextureAtlas();

            // Instantiate mesh workers proportional to system thread count
            var workerCount = Environment.ProcessorCount > 4 ? Environment.ProcessorCount - 2 : 2;

            _meshExtractors = new ChunkUpdateWorker[workerCount];
            for (var i = 0; i < _meshExtractors.Length; i++)
            {
                _meshExtractors[i] = new ChunkUpdateWorker(UpdateJobs, _meshResults);
            }

            // Start the chunk generation routine
            StartCoroutine(nameof(GenerateChunks));
        }
Example #3
0
        /// <summary>
        /// Handles stone, sea-level water, and eventually caves.
        /// Maybe Grass, dirt, etc
        /// </summary>
        private void GenerationFirstPass()
        {
            for (var z = 0; z < CHUNK_LENGTH; z++)
            {
                for (var y = 0; y < CHUNK_HEIGHT; y++)
                {
                    for (var x = 0; x < CHUNK_LENGTH; x++)
                    {
                        var seq = x + CHUNK_LENGTH * (y + CHUNK_HEIGHT * z);
                        // Fill according to height map
                        var height = _heightMap[x + z * CHUNK_LENGTH];
                        HeightMapMax = Mathf.Max(HeightMapMax, height);

                        // Skip voxels above the height map and sea level
                        if (y > height && y > SEA_LEVEL)
                        {
                            continue;
                        }

                        var voxel = _world.GetBiomeAtPosition(WorldPosition.x + x, WorldPosition.y + z).GetVoxelAtHeight(height, y);
                        if (voxel.Id == VoxelDictionary.IdByName("water"))
                        {
                            _heightMap[x + z * CHUNK_LENGTH] = Mathf.Max(height, y);
                        }
                        _voxels[seq] = voxel;
                    }
                }
            }
        }
Example #4
0
        private void Update()
        {
            if (Input.GetKeyDown(KeyCode.Mouse0))
            {
                RaycastHit hit;
                var        rayHit = Physics.Raycast(Camera.main.transform.position, Camera.main.transform.forward, out hit, 12f, Mask);

                if (rayHit)
                {
                    var hitPoint = hit.point + (Camera.main.transform.forward * 0.25f);
                    var voxelPos = new Vector3Int(Mathf.RoundToInt(hitPoint.x), Mathf.RoundToInt(hitPoint.y), Mathf.RoundToInt(hitPoint.z));

                    WorldSystem.Instance.VoxelWorld.TrySetVoxel(voxelPos, new Voxel(0));
                }
            }

            if (Input.GetKeyDown(KeyCode.Mouse1))
            {
                RaycastHit hit;
                var        rayHit = Physics.Raycast(Camera.main.transform.position, Camera.main.transform.forward, out hit, 12f, Mask);

                if (rayHit)
                {
                    var hitPoint = hit.point;
                    var voxelPos = new Vector3Int(Mathf.RoundToInt(hitPoint.x + hit.normal.x * 0.6f), Mathf.RoundToInt(hitPoint.y + hit.normal.y * 0.5f), Mathf.RoundToInt(hitPoint.z + hit.normal.z * 0.5f));

                    WorldSystem.Instance.VoxelWorld.TrySetVoxel(voxelPos, new Voxel(VoxelDictionary.IdByName("light_stone_lamp")));
                }
            }
        }
Example #5
0
        /// <summary>
        /// Sets a voxel at the specified position.
        /// Will throw an exception if the position is out of range.
        /// Chunk update event is invoked by default and should only be changed
        /// under special circumstances.
        /// </summary>
        private void SetVoxel(Vector3Int pos, Voxel voxel)
        {
            // Disallow editing of bedrock voxels
            if (_voxels[pos.x + CHUNK_LENGTH * (pos.y + CHUNK_HEIGHT * pos.z)].Id == VoxelDictionary.IdByName("bedrock"))
            {
                return;
            }

            // Set the voxel
            _voxels[pos.x + CHUNK_LENGTH * (pos.y + CHUNK_HEIGHT * pos.z)] = voxel;

            // Determine if this was a placement or removal (set to air)
            if (voxel.Id == 0)
            {
                // Update light sources
                lock (LightSources) {
                    if (LightSources.ContainsKey(pos))
                    {
                        LightSources.Remove(pos);
                    }
                }

                // Update height map
                HeightMapMax = Mathf.Max(HeightMapMax, pos.y);
                if (_heightMap[pos.x + pos.z * CHUNK_LENGTH] == pos.y)
                {
                    _heightMap[pos.x + pos.z * CHUNK_LENGTH] = pos.y - 1;
                }
            }
            else
            {
                // Update height map
                HeightMapMax = Mathf.Max(HeightMapMax, pos.y);
                if (_heightMap[pos.x + pos.z * CHUNK_LENGTH] < pos.y)
                {
                    _heightMap[pos.x + pos.z * CHUNK_LENGTH] = pos.y;
                }
            }

            // Update light sources if necessary
            var voxelData = VoxelDictionary.VoxelData[voxel.Id];

            if (voxelData.LightValue > 0)
            {
                SetBlockLight(pos, voxelData.LightValue);
                lock (LightSources) {
                    if (!LightSources.ContainsKey(pos))
                    {
                        LightSources.Add(pos, voxelData.LightValue);
                    }
                    else
                    {
                        LightSources[pos] = voxelData.LightValue;
                    }
                }
            }
        }