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); } }
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); } }
public VoxelMaterial[] GetMaterialAll() { VoxelMaterial[] materials = new VoxelMaterial[_lives.Count]; for (int i = 0; i < _lives.Count; i++) { materials[i] = _lives[i]; } return(materials); }
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)); }
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); }
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); }
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); }
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); }
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; } } } } }