Exemplo n.º 1
0
 private void OnRemoveBlockBefore(ChunkPrimer chunk, int x, int y, int z, VoxelMaterial voxel)
 {
     if (_events.OnRemoveBlockBefore != null)
     {
         _events.OnRemoveBlockBefore.Invoke(chunk, x, y, z, voxel);
     }
 }
Exemplo n.º 2
0
 private void OnAddBlockAfter(ChunkPrimer chunk, int x, int y, int z, VoxelMaterial voxel)
 {
     if (_events.OnAddBlockAfter != null)
     {
         _events.OnAddBlockAfter.Invoke(chunk, x, y, z, voxel);
     }
 }
Exemplo n.º 3
0
        public VoxelMaterial[] GetMaterialAll()
        {
            VoxelMaterial[] materials = new VoxelMaterial[_lives.Count];

            for (int i = 0; i < _lives.Count; i++)
            {
                materials[i] = _lives[i];
            }

            return(materials);
        }
Exemplo n.º 4
0
        public IVoxelModel CalcVoxelCruncher(VoxelData <VoxelMaterial> voxels)
        {
            var map = new VoxelMaterial[voxels.Bound.x, voxels.Bound.y, voxels.Bound.z];

            for (int i = 0; i < voxels.Bound.x; ++i)
            {
                for (int j = 0; j < voxels.Bound.y; ++j)
                {
                    for (int k = 0; k < voxels.Bound.z; ++k)
                    {
                        map[i, j, k] = null;
                    }
                }
            }

            var crunchers = new List <VoxelPrimitive>();
            var faces     = new VoxelVisiableFaces();

            Bounds bound = new Bounds();

            foreach (var it in voxels.GetEnumerator())
            {
                if (it.value.canMerge)
                {
                    bound.Encapsulate(new Vector3(it.position.x, it.position.y, it.position.z));
                    map[it.position.x, it.position.y, it.position.z] = it.value;
                }
                else
                {
                    crunchers.Add(new VoxelPrimitive(it.position.x, it.position.x, it.position.y, it.position.y, it.position.z, it.position.z, faces, it.value));
                }
            }

            var max = bound.max;

            max.x     = System.Math.Min(max.x + 1, voxels.Bound.x);
            max.y     = System.Math.Min(max.y + 2, voxels.Bound.y);
            max.z     = System.Math.Min(max.z + 1, voxels.Bound.z);
            bound.max = max;

            CalcVoxelCruncher(map, bound, ref crunchers);

            return(new VoxelModelList(crunchers));
        }
Exemplo n.º 5
0
        public VoxelMaterial CreateMaterial(string name, VoxelMaterialModels models)
        {
            UnityEngine.Debug.Assert(!System.String.IsNullOrEmpty(name));

            if (_liveIndex.ContainsKey(name))
            {
                throw new System.Exception(string.Format("Material has been created ({0})", name));
            }

            var newMaterial = new VoxelMaterial(name, models, _lives.Count + 1)
            {
                canMerge       = models.merge,
                is_transparent = models.transparent
            };

            _liveIndex.Add(name, _lives.Count + 1);
            _lives.Add(newMaterial);

            return(newMaterial);
        }
Exemplo n.º 6
0
        public IVoxelModel CalcVoxelCruncher(VoxelData <VoxelMaterial> voxels)
        {
            var map = new VoxelMaterial[voxels.Bound.x, voxels.Bound.y, voxels.Bound.z];

            for (int i = 0; i < voxels.Bound.x; ++i)
            {
                for (int j = 0; j < voxels.Bound.y; ++j)
                {
                    for (int k = 0; k < voxels.Bound.z; ++k)
                    {
                        map[i, j, k] = null;
                    }
                }
            }

            foreach (var it in voxels.GetEnumerator())
            {
                map[it.position.x, it.position.y, it.position.z] = it.value;
            }

            var crunchers = new List <VoxelPrimitive>();
            var bound     = new Vector3Int(voxels.Bound.x, voxels.Bound.y, voxels.Bound.z);

            foreach (var it in voxels.GetEnumerator())
            {
                var x = it.position.x;
                var y = it.position.y;
                var z = it.position.z;
                var c = it.value;

                VoxelVisiableFaces faces;
                if (!GetVisiableFaces(map, bound, x, y, z, c, out faces))
                {
                    continue;
                }

                crunchers.Add(new VoxelPrimitive(x, x, y, y, z, z, faces, c));
            }

            return(new VoxelModelList(crunchers));
        }
        public void BuildGrass(ChunkPrimer map, byte ix, byte iz, int dx, int dz, VoxelMaterial main, out float f, out byte h)
        {
            f = Noise.Simplex2(_params.grass.loopX * dx, _params.grass.loopZ * dz, _params.grass.octaves, _params.grass.persistence, _params.grass.lacunarity);
            f = (f * (f * _params.floorHeightLismit + _params.floorBase));

            h = System.Math.Max((byte)1, (byte)f);

            if (_params.isGenGrass || _params.isGenSand)
            {
                if (_params.isGenGrass && _params.isGenSand)
                {
                    for (byte iy = 0; iy < h; iy++)
                    {
                        map.voxels.Set(ix, iy, iz, random.Next() > _params.thresholdSand ? _materials.grass : _materials.sand);
                    }
                }
                else
                {
                    var waterHeight = _params.floorBase - _params.floorHeightLismit * 0.2f;
                    if (h < waterHeight)
                    {
                        for (byte iy = 0; iy < h; iy++)
                        {
                            map.voxels.Set(ix, iy, iz, _materials.dirt);
                        }
                    }
                    else
                    {
                        for (byte iy = 0; iy < h - 1; iy++)
                        {
                            map.voxels.Set(ix, iy, iz, _materials.dirt);
                        }

                        map.voxels.Set(ix, (byte)(h - 1), iz, main);
                    }
                }
            }
        }
        public ChunkPrimer Buildland(CubizerBehaviour terrain, int x, int y, int z, VoxelMaterial main)
        {
            var size = terrain.profile.chunk.settings.chunkSize;
            var map  = new ChunkPrimer(size, x, y, z, size * size * _params.floorBase);

            int offsetX = x * map.voxels.Bound.x;
            int offsetZ = z * map.voxels.Bound.z;

            for (byte ix = 0; ix < map.voxels.Bound.x; ix++)
            {
                for (byte iz = 0; iz < map.voxels.Bound.z; iz++)
                {
                    int dx = offsetX + ix;
                    int dz = offsetZ + iz;

                    float f; byte h;
                    this.BuildGrass(map, ix, iz, dx, dz, main, out f, out h);

                    var waterHeight = (byte)(_params.floorBase - _params.floorHeightLismit * 0.2f);
                    if (_params.isGenWater && h <= waterHeight)
                    {
                        for (byte iy = h; iy <= waterHeight; iy++)
                        {
                            map.voxels.Set(ix, iy, iz, _materials.water);
                        }
                    }
                    else
                    {
                        if (f > waterHeight && f < (waterHeight + 0.1))
                        {
                            map.voxels.Set(ix, (byte)(h - 1), iz, _materials.sand);
                        }

                        if (_params.isGenWeed && Noise.Simplex2(
                                _params.weeds.loopX * dx,
                                _params.weeds.loopZ * dz,
                                _params.weeds.octaves,
                                _params.weeds.persistence,
                                _params.weeds.lacunarity) > _params.weeds.threshold)
                        {
                            map.voxels.Set(ix, h, iz, _materials.weed[random.Next(0, _materials.weed.Length - 1)]);
                        }
                        else if (_params.isGenFlower && Noise.Simplex2(
                                     _params.flowers.loopX * dx,
                                     _params.flowers.loopZ * dz,
                                     _params.flowers.octaves,
                                     _params.flowers.persistence,
                                     _params.flowers.lacunarity) > _params.flowers.threshold)
                        {
                            map.voxels.Set(ix, h, iz, _materials.flower[random.Next(0, _materials.flower.Length - 1)]);
                        }
                        else if (_params.isGenTree && h < map.voxels.Bound.y - 8)
                        {
                            if (ix > 3 && ix < map.voxels.Bound.y - 3 && iz > 3 && iz < map.voxels.Bound.y - 3)
                            {
                                if (Noise.Simplex2(
                                        _params.tree.loopX * dx,
                                        _params.tree.loopZ * dz,
                                        _params.tree.octaves,
                                        _params.tree.persistence,
                                        _params.tree.lacunarity) > _params.tree.threshold)
                                {
                                    this.BuildTree(map, ix, iz, h);
                                }
                            }
                        }
                    }
                }
            }

            return(map);
        }
Exemplo n.º 9
0
        public bool GetVisiableFaces(VoxelMaterial[,,] map, Vector3Int bound, int x, int y, int z, VoxelMaterial material, out VoxelVisiableFaces faces)
        {
            for (int i = 0; i < 6; i++)
            {
                instanceID[i] = null;
            }

            if (x >= 1)
            {
                instanceID[0] = map[(byte)(x - 1), y, z];
            }
            if (y >= 1)
            {
                instanceID[2] = map[x, (byte)(y - 1), z];
            }
            if (z >= 1)
            {
                instanceID[4] = map[x, y, (byte)(z - 1)];
            }
            if (x < bound.x - 1)
            {
                instanceID[1] = map[(byte)(x + 1), y, z];
            }
            if (y < bound.y - 1)
            {
                instanceID[3] = map[x, (byte)(y + 1), z];
            }
            if (z < bound.z - 1)
            {
                instanceID[5] = map[x, y, (byte)(z + 1)];
            }

            if (material.is_transparent)
            {
                var name = material.Name;

                faces.left   = (instanceID[0] == null) ? true : instanceID[0].Name != name ? true : false;
                faces.right  = (instanceID[1] == null) ? true : instanceID[1].Name != name ? true : false;
                faces.bottom = (instanceID[2] == null) ? true : instanceID[2].Name != name ? true : false;
                faces.top    = (instanceID[3] == null) ? true : instanceID[3].Name != name ? true : false;
                faces.front  = (instanceID[4] == null) ? true : instanceID[4].Name != name ? true : false;
                faces.back   = (instanceID[5] == null) ? true : instanceID[5].Name != name ? true : false;

                if (material.canMerge)
                {
                    if (x == 0)
                    {
                        faces.left = false;
                    }
                    if (z == 0)
                    {
                        faces.front = false;
                    }
                    if (x + 1 == bound.x)
                    {
                        faces.right = false;
                    }
                    if (z + 1 == bound.z)
                    {
                        faces.back = false;
                    }
                }
            }
            else
            {
                faces.left   = (instanceID[0] == null) ? true : instanceID[0].is_transparent ? true : false;
                faces.right  = (instanceID[1] == null) ? true : instanceID[1].is_transparent ? true : false;
                faces.bottom = (instanceID[2] == null) ? true : instanceID[2].is_transparent ? true : false;
                faces.top    = (instanceID[3] == null) ? true : instanceID[3].is_transparent ? true : false;
                faces.front  = (instanceID[4] == null) ? true : instanceID[4].is_transparent ? true : false;
                faces.back   = (instanceID[5] == null) ? true : instanceID[5].is_transparent ? true : false;
            }

            if (!material.canMerge)
            {
                faces = new VoxelVisiableFaces(faces.Any);
            }

            return(faces.Any);
        }
Exemplo n.º 10
0
        private bool HitTestByRay(Ray ray, int hitDistance, out ChunkPrimer chunk, out byte outX, out byte outY, out byte outZ, out ChunkPrimer lastChunk, out byte lastX, out byte lastY, out byte lastZ)
        {
            var chunkX = CalculateChunkPosByWorld(ray.origin.x);
            var chunkY = CalculateChunkPosByWorld(ray.origin.y);
            var chunkZ = CalculateChunkPosByWorld(ray.origin.z);

            lastChunk = null;
            lastX     = lastY = lastZ = outX = outY = outZ = 255;

            if (!this.manager.Get(chunkX, chunkY, chunkZ, out chunk))
            {
                return(false);
            }

            Vector3 origin = ray.origin;

            origin.x -= chunk.position.x * model.settings.chunkSize;
            origin.y -= chunk.position.y * model.settings.chunkSize;
            origin.z -= chunk.position.z * model.settings.chunkSize;

            VoxelMaterial block = null;

            for (int i = 0; i < hitDistance && block == null; i++)
            {
                int ix = Mathf.RoundToInt(origin.x);
                int iy = Mathf.RoundToInt(origin.y);
                int iz = Mathf.RoundToInt(origin.z);

                if (outX == ix && outY == iy && outZ == iz)
                {
                    continue;
                }

                bool isOutOfChunk = false;
                if (ix < 0)
                {
                    ix = ix + model.settings.chunkSize; origin.x += model.settings.chunkSize; chunkX--; isOutOfChunk = true;
                }
                if (iy < 0)
                {
                    iy = iy + model.settings.chunkSize; origin.y += model.settings.chunkSize; chunkY--; isOutOfChunk = true;
                }
                if (iz < 0)
                {
                    iz = iz + model.settings.chunkSize; origin.z += model.settings.chunkSize; chunkZ--; isOutOfChunk = true;
                }
                if (ix + 1 > model.settings.chunkSize)
                {
                    ix = ix - model.settings.chunkSize; origin.x -= model.settings.chunkSize; chunkX++; isOutOfChunk = true;
                }
                if (iy + 1 > model.settings.chunkSize)
                {
                    iy = iy - model.settings.chunkSize; origin.y -= model.settings.chunkSize; chunkY++; isOutOfChunk = true;
                }
                if (iz + 1 > model.settings.chunkSize)
                {
                    iz = iz - model.settings.chunkSize; origin.z -= model.settings.chunkSize; chunkZ++; isOutOfChunk = true;
                }

                lastX     = outX;
                lastY     = outY;
                lastZ     = outZ;
                lastChunk = chunk;

                if (isOutOfChunk)
                {
                    chunk = FindChunk(chunkX, chunkY, chunkZ);
                    if (chunk == null)
                    {
                        return(false);
                    }
                }

                chunk.voxels.Get(ix, iy, iz, ref block);

                origin += ray.direction;

                outX = (byte)ix;
                outY = (byte)iy;
                outZ = (byte)iz;
            }

            return(block != null);
        }
Exemplo n.º 11
0
        public void CalcVoxelCruncher(VoxelMaterial[,,] voxels, Bounds bound, ref List <VoxelPrimitive> crunchers)
        {
            var min = new int[] { (int)bound.min.x, (int)bound.min.y, (int)bound.min.z };
            var max = new int[] { (int)bound.max.x, (int)bound.max.y, (int)bound.max.z };

            var alloc = System.Math.Max(max[0], System.Math.Max(max[1], max[2]));

            var mask  = new VoxelMaterial[alloc * alloc];
            var mask2 = new bool[alloc * alloc];

            for (var d = 0; d < 3; ++d)
            {
                var u = (d + 1) % 3;
                var v = (d + 2) % 3;

                x[0] = 0; x[1] = 0; x[2] = 0;
                q[0] = 0; q[1] = 0; q[2] = 0;
                q[d] = 1;

                for (x[d] = min[d] - 1; x[d] < max[d];)
                {
                    var n = 0;

                    for (x[v] = min[v]; x[v] < max[v]; ++x[v])
                    {
                        for (x[u] = min[u]; x[u] < max[u]; ++x[u])
                        {
                            bool edge = x[d] < 0 || x[d] + q[d] >= max[d];
                            var  a    = x[d] >= 0 ? voxels[x[0], x[1], x[2]] : null;
                            var  b    = x[d] < max[d] - 1 ? voxels[x[0] + q[0], x[1] + q[1], x[2] + q[2]] : null;
                            if (a != b)
                            {
                                if (a == null)
                                {
                                    if (!b.is_transparent)
                                    {
                                        mask2[n]  = true;
                                        mask[n++] = b;
                                    }
                                    else
                                    {
                                        mask[n++] = null;
                                    }
                                }
                                else if (b == null)
                                {
                                    if (!edge || !a.is_transparent)
                                    {
                                        mask2[n]  = false;
                                        mask[n++] = a;
                                    }
                                    else
                                    {
                                        mask[n++] = null;
                                    }
                                }
                                else
                                {
                                    mask2[n]  = b.is_transparent ? false : true;
                                    mask[n++] = b.is_transparent ? a : b;
                                }
                            }
                            else
                            {
                                mask[n++] = null;
                            }
                        }
                    }

                    ++x[d];

                    n = 0;

                    for (var j = min[v]; j < max[v]; ++j)
                    {
                        for (var i = min[u]; i < max[u];)
                        {
                            var c = mask[n];
                            if (c == null)
                            {
                                ++i; ++n;
                                continue;
                            }

                            var w = 1;
                            var h = 1;
                            var k = 0;

                            for (; (i + w) < max[u] && c == mask[n + w]; ++w)
                            {
                            }

                            var done = false;
                            for (; (j + h) < max[v]; ++h)
                            {
                                for (k = 0; k < w; ++k)
                                {
                                    if (c != mask[n + k + h * max[u]])
                                    {
                                        done = true;
                                        break;
                                    }
                                }

                                if (done)
                                {
                                    break;
                                }
                            }

                            x[u] = i; x[v] = j;

                            du[0] = 0; du[1] = 0; du[2] = 0;
                            dv[0] = 0; dv[1] = 0; dv[2] = 0;

                            du[u] = w;
                            dv[v] = h;

                            var v1 = new Vector3(x[0], x[1], x[2]);
                            var v2 = new Vector3(x[0] + du[0] + dv[0], x[1] + du[1] + dv[1], x[2] + du[2] + dv[2]);

                            v2.x = System.Math.Max(v2.x - 1, 0);
                            v2.y = System.Math.Max(v2.y - 1, 0);
                            v2.z = System.Math.Max(v2.z - 1, 0);

                            if (mask2[n])
                            {
                                faces.front  = d == 2;
                                faces.back   = false;
                                faces.left   = d == 0;
                                faces.right  = false;
                                faces.top    = false;
                                faces.bottom = d == 1;
                            }
                            else
                            {
                                faces.front  = false;
                                faces.back   = d == 2;
                                faces.left   = false;
                                faces.right  = d == 0;
                                faces.top    = d == 1;
                                faces.bottom = false;
                            }

                            crunchers.Add(new VoxelPrimitive((byte)v1.x, (byte)(v2.x), (byte)(v1.y), (byte)(v2.y), (byte)(v1.z), (byte)(v2.z), faces, c));

                            for (var l = 0; l < h; ++l)
                            {
                                for (k = 0; k < w; ++k)
                                {
                                    mask[n + k + l * max[u]] = null;
                                }
                            }

                            i += w; n += w;
                        }
                    }
                }
            }
        }