public void SetVoxel(int x, int y, int z, Voxel voxel) { int idx = x + y * (Width) + z * (Width) * (Height); Voxels[idx] = new VoxelNode(voxel); //Voxels[idx].SetVoxel(voxel); }
public void SetVoxelNode(int x, int y, int z, VoxelNode vox) { int cx = WorldToChunk(x); int cz = WorldToChunk(z); int tx = x % World.ChunkSize; int tz = z % World.ChunkSize; ChunkVoxels[cx, cz].SetVoxelNode(tx, y, tz, vox); //Debug.Log(tx + "," + y); try { // ChunkVoxels[cx, cz].SetVoxelNode(tx, y, tz, vox); }catch (System.Exception e) { Debug.Log(x + "," + y + "," + z); Debug.Log(cx + ", " + cz + "," + tx + "," + tz); } if (tx == 0 && tz == 0 && cx > 0 && cz > 0) { ChunkVoxels[cx - 1, cz - 1].SetVoxelNode(World.ChunkSize, y, World.ChunkSize, vox); ChunkVoxels[cx - 1, cz].SetVoxelNode(World.ChunkSize, y, tz, vox); ChunkVoxels[cx, cz - 1].SetVoxelNode(tx, y, World.ChunkSize, vox); } else if (tx == 0 && cx > 0) { ChunkVoxels[cx - 1, cz].SetVoxelNode(World.ChunkSize, y, tz, vox); } else if (tz == 0 && cz > 0) { ChunkVoxels[cx, cz - 1].SetVoxelNode(tx, y, World.ChunkSize, vox); } /* * if(tx==World.ChunkSize-1 && tz==World.ChunkSize-1 && cx<ChunkSize.x -1 && cz < ChunkSize.z - 1) * { * int dChunkHeight = (int)(ChunkBaseHeights[cx, cz] - ChunkBaseHeights[cx + 1, cz + 1]); * ChunkVoxels[cx + 1, cz + 1].SetVoxel(0, Mathf.Clamp(y + dChunkHeight,0,World.ChunkHeight), 0, vox); * }else if (tx == World.ChunkSize - 1&& cx < ChunkSize.x - 1 ) * { * int dChunkHeight = (int)(ChunkBaseHeights[cx, cz] - ChunkBaseHeights[cx + 1, cz]); * ChunkVoxels[cx + 1, cz].SetVoxel(0, Mathf.Clamp(y + dChunkHeight, 0, World.ChunkHeight), tz, vox); * }else if ( tz == World.ChunkSize - 1 &&cz < ChunkSize.z - 1) * { * int dChunkHeight = (int)(ChunkBaseHeights[cx, cz] - ChunkBaseHeights[cx , cz + 1]); * ChunkVoxels[cx, cz + 1].SetVoxel(tx, Mathf.Clamp(y + dChunkHeight, 0, World.ChunkHeight), 0, vox); * } * */ }
public static bool ContainsVoxel(this VoxelNode node, Voxel query) { if (node.Voxel == query) { return(true); } if (node.OtherVoxels == null) { return(false); } return(node.OtherVoxels.Contains(query)); }
public void AddVoxel(int x, int y, int z, Voxel voxel) { int idx = x + y * (Width) + z * (Width) * (Height); if (!Voxels[idx].IsNode) { Voxels[idx] = new VoxelNode(voxel); } else { Voxels[idx].AddVoxel(voxel); } }
public static void AddVoxel(this VoxelNode node, Voxel add) { if (node.Voxel == add) { return; } if (node.OtherVoxels == null) { node.OtherVoxels = new List <Voxel>(); node.OtherVoxels.Add(add); } else if (!node.OtherVoxels.Contains(add)) { node.OtherVoxels.Add(add); } }
void addTriangle(VoxelNode a, VoxelNode b, VoxelNode c) { if (_vertices.Count > 64990) { nextChildMesh(); } if (smooth_normal) { //a if (!_voxelPointIndexTable.ContainsKey(a)) { _voxelPointIndexTable.Add(a, _vertices.Count); addVertex(a); } //b if (!_voxelPointIndexTable.ContainsKey(b)) { _voxelPointIndexTable.Add(b, _vertices.Count); addVertex(b); } //c if (!_voxelPointIndexTable.ContainsKey(c)) { _voxelPointIndexTable.Add(c, _vertices.Count); addVertex(c); } _triangles.Add(_voxelPointIndexTable [a]); _triangles.Add(_voxelPointIndexTable [b]); _triangles.Add(_voxelPointIndexTable [c]); } else { _triangles.Add(_vertices.Count); addVertex(a); _triangles.Add(_vertices.Count); addVertex(b); _triangles.Add(_vertices.Count); addVertex(c); } }
public void AddBuilding(Building b, BuildingVoxels vox, Vec2i pos) { float minHeight = 0; //SetTiles(pos.x, pos.z, b.Width, b.Height, b.BuildingTiles); for (int x = 0; x < b.Width; x++) { for (int z = 0; z < b.Height; z++) { int cx = WorldToChunk(x); int cz = WorldToChunk(z); int deltaHeight = ChunkBases != null ? (int)(minHeight - ChunkBases[cx, cz].Height) : 0; SetTile(x + pos.x, z + pos.z, b.BuildingTiles[x, z]); SetHeight(x + pos.x, z + pos.z, minHeight); for (int y = 0; y < vox.Height; y++) { VoxelNode voxNode = vox.GetVoxelNode(x, y, z); if (voxNode.IsNode) { //Debug.Log("Adding vox node: " + voxNode); SetVoxelNode(x + pos.x, y, z + pos.z, vox.GetVoxelNode(x, y, z)); } } } } foreach (WorldObjectData obj in b.GetBuildingExternalObjects()) { obj.SetPosition(obj.Position + pos.AsVector3()); //We (should) already have checked for object validity when creating the building AddObject(obj, true); } }
/// <summary> /// /// </summary> /// <param name="genRan">The RNG used for this building</param> /// <param name="obj">The object to place in the building</param> /// <param name="height">The height above the ground the object should sit</param> /// <param name="vox">The voxel data of this building. Only required if 'requireWallBacking' is true</param> /// <param name="build">The building to place the object in</param> /// <param name="distFromWall">The distance from a wall the object should be placed</param> /// <param name="wallIndex">Defines the wall we should attempt to place this object on. The 'i'th wall defines the wall /// connecting build.BoundingWall[i] -> build.BoundingWall[i+1]. If left as default value (-1), an index will be randomly generated</param> /// <param name="requireWallBacking">If true, then we will search for a point on the wall that is backed against a wall. /// Used to stop certain objects being placed in front of windows</param> /// <param name="forcePlace">If true, then we do not check for intersection with other objects in the building</param> /// <param name="attemptsCount">The number of attempts made to place the object on this wall</param> /// <returns>True if object is placed sucesfully, false otherwise</returns> public static bool PlaceObjectAgainstWall(GenerationRandom genRan, WorldObjectData obj, float height, BuildingVoxels vox, Building build, float distFromWall = 0, bool requireWallBacking = false, int distToEntr = 2, bool forcePlace = false, int attemptsCount = 5) { if (build.InsideWallPoints == null) { build.InsideWallPoints = FindInsideWallBoundryPoints(vox, build); } //Check attempts count attemptsCount--; if (attemptsCount == 0) { return(false); } float wallDisp = genRan.Random(); //Define the position as the start pos + lambda*dir //Select a random position from all wall points Vec2i pos = genRan.RandomFromArray(build.InsideWallPoints); //If too close to entrance, try another placement if (build.Entrance != null && pos.QuickDistance(build.Entrance) < distToEntr * distToEntr) { return(PlaceObjectAgainstWall(genRan, obj, height, vox, build, distFromWall, requireWallBacking, distToEntr, forcePlace, attemptsCount)); } //If the object is too close to any of the corners, try again foreach (Vec2i v in build.BoundingWall) { if (v.QuickDistance(pos) < 2) { return(PlaceObjectAgainstWall(genRan, obj, height, vox, build, distFromWall, requireWallBacking, distToEntr, forcePlace, attemptsCount)); } } Vec2i faceDirection = GetWallPointDirection(build, pos); //If we require a backing wall, we check the position if (requireWallBacking) { Vec2i wPos = pos - faceDirection; for (int y = 0; y < 4; y++) { VoxelNode vn = vox.GetVoxelNode(wPos.x, y, wPos.z); //If there is no node (nothing set) then this position is not valid if (!vn.IsNode) { return(PlaceObjectAgainstWall(genRan, obj, height, vox, build, distFromWall, requireWallBacking, distToEntr, forcePlace, attemptsCount)); } if (vn.Voxel == Voxel.glass || vn.Voxel == Voxel.none) { return(PlaceObjectAgainstWall(genRan, obj, height, vox, build, distFromWall, requireWallBacking, distToEntr, forcePlace, attemptsCount)); } } } Vector3 finPos = pos.AsVector3() + faceDirection.AsVector3() * distFromWall + Vector3.up * height; float rotation = Vec2i.Angle(Vec2i.Forward, faceDirection); obj.SetPosition(finPos).SetRotation(rotation); if (!forcePlace) { foreach (WorldObjectData obj_ in build.GetBuildingExternalObjects()) { if (obj.Intersects(obj_)) { return(PlaceObjectAgainstWall(genRan, obj, height, vox, build, distFromWall, requireWallBacking, distToEntr, forcePlace, attemptsCount)); } } } //obj.SetPosition(finPos); build.AddInternalObject(obj); return(true); }
public static void ClearVoxel(this VoxelNode node) { node.OtherVoxels.Clear(); node.Voxel = Voxel.none; }
public static void SetVoxel(this VoxelNode node, Voxel set) { node.Voxel = set; // Debug.Log("setting voxel: " + set); }
/// <summary> /// Creates a pre loaded chunk from chunk data. /// This entire function is run in a thread /// </summary> /// <param name="cData"></param> /// <returns></returns> private PreLoadedChunk GeneratePreLoadedChunk(ChunkData chunk, int lod = 1) { //We create a thread safe mesh for the terrain // PreMesh terrainMesh = GenerateMarchingCubesTerrain(chunk); ChunkData[] neighbors = ChunkRegionManager.GetNeighbors(new Vec2i(chunk.X, chunk.Z)); PreMesh terrainMesh = GenerateSmoothTerrain(chunk, neighbors, lod); terrainMesh.RecalculateNormals(); Debug.Log("[ChunkLoader] Terrain mesh for " + chunk + " created - " + CurrentVerticies.Count + " verticies", Debug.CHUNK_LOADING); //Create the base pre-loaded chunk PreLoadedChunk preChunk = new PreLoadedChunk(new Vec2i(chunk.X, chunk.Z), terrainMesh, chunk); //if we have no voxel data, return just the terrain map if (chunk.VoxelData == null) { return(preChunk); } int maxHeight = 0; if (neighbors != null) { foreach (ChunkData cd in neighbors) { if (cd != null && cd.VoxelData != null) { if (maxHeight < cd.VoxelData.TotalHeight()) { maxHeight = cd.VoxelData.TotalHeight(); } } } } //If the chunk hasn't had its boundry points defined, we do it now if (!chunk.VoxelData.HasBoundryVoxels) { for (int y = 0; y < maxHeight; y++) { for (int i = 0; i < World.ChunkSize; i++) { if (neighbors[0] != null && neighbors[0].VoxelData != null) { VoxelNode node = neighbors[0].VoxelData.GetVoxelNode(i, y, 0); if (node.IsNode) { chunk.VoxelData.SetVoxelNode(i, y, World.ChunkSize, node); } } if (neighbors[2] != null && neighbors[2].VoxelData != null) { VoxelNode node = neighbors[2].VoxelData.GetVoxelNode(0, y, i); if (node.IsNode) { chunk.VoxelData.SetVoxelNode(World.ChunkSize, y, i, node); } } } if (neighbors[1] != null && neighbors[1].VoxelData != null) { VoxelNode node = neighbors[1].VoxelData.GetVoxelNode(0, y, 0); if (node.IsNode) { chunk.VoxelData.SetVoxelNode(World.ChunkSize, y, World.ChunkSize, node); } } } chunk.VoxelData.HasBoundryVoxels = true; } //Next we generate all relevent voxel meshes foreach (Voxel v in MiscUtils.GetValues <Voxel>()) { if (v == Voxel.none) { continue; } //If the chunk has this type of voxel in it if (chunk.VoxelData.VoxelTypeBounds.TryGetValue(v, out VoxelBounds vb)) { //Clear all lists to prepair CurrentVerticies.Clear(); CurrentTriangles.Clear(); CurrentColours.Clear(); CurrentUVs.Clear(); //Generate the voxel mesh //MarchingCubes.Generate(chunk.VoxelData.Voxels, vb, v, World.ChunkSize+1, World.ChunkHeight+1, World.ChunkSize+1, CurrentVerticies, CurrentTriangles); //MarchingCubes.Generate(chunk.VoxelData.Voxels, vb, v, World.ChunkSize + 1, chunk.VoxelData.TotalHeight(), World.ChunkSize + 1, CurrentVerticies, CurrentTriangles); //MarchingCubes.Generate(chunk.VoxelData.AllVoxels, vb, v, World.ChunkSize + 1, chunk.VoxelData.TotalHeight(), World.ChunkSize + 1, CurrentVerticies, CurrentTriangles); MarchingCubes.Generate(chunk.VoxelData.AllVoxels, vb, v, World.ChunkSize + 1, chunk.VoxelData.TotalHeight(), World.ChunkSize + 1, CurrentVerticies, CurrentTriangles); PreMesh voxelMesh = new PreMesh(); voxelMesh.Verticies = CurrentVerticies.ToArray(); voxelMesh.Triangles = CurrentTriangles.ToArray(); voxelMesh.UV = CreateUV(voxelMesh); voxelMesh.RecalculateNormals(); //Add it the the pre loaded chunk preChunk.VoxelMesh.Add(v, voxelMesh); } } /* * if(chunk.WorldObjects != null) * { * * lock (ObjectsToLoadLock) * { * Debug.Log("[ChunkLoader] Chunk " + chunk.X + "," + chunk.Z + " has " + chunk.WorldObjects.Count + " objects to load", Debug.CHUNK_LOADING); * ObjectsToLoad.AddRange(chunk.WorldObjects); * } * * }*/ return(preChunk); }
public virtual void UpdateNeighbours(VoxelNode octreeNode) { }
void addVertex(VoxelNode node) { _vertices.Add(node.toVector()); _uvs.Add(node.toUV(_voxels.GetLength(0), _voxels.GetLength(2))); }
public void ClearVoxel(int x, int y, int z) { int idx = x + y * (Width) + z * (Width) * (Height); Voxels[idx] = new VoxelNode(Voxel.none); }