public override void LoadContent() { InputManager.LockMouseToCenter = true; game.IsMouseVisible = false; VoxelRenderer.Init( Game ); Voxelizer.Init(); cameraPosition = new Vector3( 25, 50, 150 ); chunk = Voxelizer.CreateChunk( 0.5f ); marker = new SpherePrimitive( 8, 16 ); }
void Start() { //Random.seed = Random.Range (0, 65000); m_surfaceSeed = Random.Range (0, 65000); //Make 2 perlin noise objects, one is used for the surface and the other for the caves m_surfacePerlin = new PerlinNoise(m_surfaceSeed); m_voronoi = new VoronoiNoise(m_surfaceSeed); GameObject.Find ("SaveTracker").GetComponent<SaveSceneComponent>().save.m_surfaceSeed = m_surfaceSeed; player = GameObject.FindWithTag ("Player").transform; // PerlinNoise m_cavePerlin = new PerlinNoise(m_caveSeed); //Set some varibles for the marching cubes plugin MarchingCubes.SetTarget(0.0f); MarchingCubes.SetWindingOrder(2, 1, 0); MarchingCubes.SetModeToCubes(); //create a array to hold the voxel chunks m_voxelChunk = new VoxelChunk[m_chunksX,m_chunksY,m_chunksZ]; //The offset is used to centre the terrain on the x and z axis. For the Y axis //you can have a certain amount of chunks above the y=0 and the rest will be below Vector3 offset = new Vector3(m_chunksX*m_voxelWidth*-0.5f, -(m_chunksY-m_chunksAbove0)*m_voxelHeight, m_chunksZ*m_voxelLength*-0.5f); for(int x = 0; x < m_chunksX; x++) { for(int y = 0; y < m_chunksY; y++) { for(int z = 0; z < m_chunksZ; z++) { //The position of the voxel chunk Vector3 pos = new Vector3(x*m_voxelWidth, y*m_voxelHeight, z*m_voxelLength); //Create the voxel object m_voxelChunk[x,y,z] = new VoxelChunk(pos+offset, m_voxelWidth, m_voxelHeight, m_voxelLength, m_surfaceLevel); //Create the voxel data m_voxelChunk[x,y,z].CreateVoxels(m_surfacePerlin, m_voronoi);//, m_cavePerlin); i++; //Smooth the voxels, is optional but I think it looks nicer // m_voxelChunk[x,y,z].SmoothVoxels(); //Create the normals. This will create smoothed normal. //This is optional and if not called the unsmoothed mesh normals will be used // m_voxelChunk[x,y,z].CalculateNormals(); //Creates the mesh form voxel data using the marching cubes plugin and creates the mesh collider m_voxelChunk[x,y,z].CreateMesh(m_material); } } } currentX = m_chunksX * m_voxelWidth; currentZ = m_chunksZ * m_voxelLength; }
public void CalculateChunkMesh() // Iterates over all blocks to only add visible faces to the model { List <Vector3Int> airBlocks = new List <Vector3Int>(); // All emtpy blocks in the chunk // Store all block of air for (int x = 0; x < 16; x++) { for (int y = 0; y < 16; y++) { for (int z = 0; z < 16; z++) { if (chunkBlocks[x, y, z] == 0) { airBlocks.Add(new Vector3Int(x, y, z)); } } } } ModelBuilder modelBuilder = new ModelBuilder(); modelBuilder.Start(); foreach (Vector3Int v in airBlocks) { // Check the neighbours of the air, a block can only be seen if has air next to one side // Valid() will return true if the block is still inside of the chunk if (Valid(v + new Vector3Int(1, 0, 0)) && chunkBlocks[v.x + 1, v.y, v.z] != 0) { modelBuilder.AddLeftFace(v + new Vector3Int(1, 0, 0), chunkBlocks[v.x + 1, v.y, v.z]); // If the block right to the air is solid a left face has to be created } if (Valid(v + new Vector3Int(-1, 0, 0)) && chunkBlocks[v.x - 1, v.y, v.z] != 0) { modelBuilder.AddRightFace(v + new Vector3Int(-1, 0, 0), chunkBlocks[v.x - 1, v.y, v.z]); } if (Valid(v + new Vector3Int(0, 0, 1)) && chunkBlocks[v.x, v.y, v.z + 1] != 0) { modelBuilder.AddFrontFace(v + new Vector3Int(0, 0, 1), chunkBlocks[v.x, v.y, v.z + 1]); } if (Valid(v + new Vector3Int(0, 0, -1)) && chunkBlocks[v.x, v.y, v.z - 1] != 0) { modelBuilder.AddBackFace(v + new Vector3Int(0, 0, -1), chunkBlocks[v.x, v.y, v.z - 1]); } if (Valid(v + new Vector3Int(0, 1, 0)) && chunkBlocks[v.x, v.y + 1, v.z] != 0) { modelBuilder.AddBottomFace(v + new Vector3Int(0, 1, 0), chunkBlocks[v.x, v.y + 1, v.z]); } if (Valid(v + new Vector3Int(0, -1, 0)) && chunkBlocks[v.x, v.y - 1, v.z] != 0) { modelBuilder.AddTopFace(v + new Vector3Int(0, -1, 0), chunkBlocks[v.x, v.y - 1, v.z]); } } // The outer blocks need to be checked extra, because they might be hidden by another chunk if (world.ChunkLoaded(Mathf.FloorToInt(start.x / 16) + "." + (Mathf.FloorToInt(start.z / 16) - 1))) { VoxelChunk chunk = world.GetChunk(Mathf.FloorToInt(start.x / 16) + "." + (Mathf.FloorToInt(start.z / 16) - 1)); // The chunk next to this chunk for (int x = 0; x < 16; x++) { for (int y = 0; y < 16; y++) { if (chunk.chunkBlocks[x, y, 15] == 0 && chunkBlocks[x, y, 0] != 0) // If the block is not of type air and also not covered by the other chunk, a face has to be created { modelBuilder.AddFrontFace(new Vector3(x, y, 0), chunkBlocks[x, y, 0]); } } } } // The same as the code above, only for another side if (world.ChunkLoaded(Mathf.FloorToInt(start.x / 16) + "." + (Mathf.FloorToInt(start.z / 16) + 1))) { VoxelChunk chunk = world.GetChunk(Mathf.FloorToInt(start.x / 16) + "." + (Mathf.FloorToInt(start.z / 16) + 1)); for (int x = 0; x < 16; x++) { for (int y = 0; y < 16; y++) { if (chunk.chunkBlocks[x, y, 0] == 0 && chunkBlocks[x, y, 15] != 0) { modelBuilder.AddBackFace(new Vector3(x, y, 15), chunkBlocks[x, y, 15]); } } } } // The same as the code above, only for another side if (world.ChunkLoaded((Mathf.FloorToInt(start.x / 16) - 1) + "." + Mathf.FloorToInt(start.z / 16))) { VoxelChunk chunk = world.GetChunk((Mathf.FloorToInt(start.x / 16) - 1) + "." + Mathf.FloorToInt(start.z / 16)); for (int z = 0; z < 16; z++) { for (int y = 0; y < 16; y++) { if (chunk.chunkBlocks[15, y, z] == 0 && chunkBlocks[0, y, z] != 0) { modelBuilder.AddLeftFace(new Vector3(0, y, z), chunkBlocks[0, y, z]); } } } } // The same as the code above, only for another side if (world.ChunkLoaded((Mathf.FloorToInt(start.x / 16) + 1) + "." + Mathf.FloorToInt(start.z / 16))) { VoxelChunk chunk = world.GetChunk((Mathf.FloorToInt(start.x / 16) + 1) + "." + Mathf.FloorToInt(start.z / 16)); for (int z = 0; z < 16; z++) { for (int y = 0; y < 16; y++) { if (chunk.chunkBlocks[0, y, z] == 0 && chunkBlocks[15, y, z] != 0) { modelBuilder.AddRightFace(new Vector3(15, y, z), chunkBlocks[15, y, z]); } } } } // Recreate the mesh chunkMesh = new Mesh(); // Set all vertices, triangles and uvs chunkMesh.vertices = modelBuilder.GetModel().vertices.ToArray(); chunkMesh.triangles = modelBuilder.GetModel().triangles.ToArray(); chunkMesh.uv = modelBuilder.GetModel().uv.ToArray(); // Add a collider if there is none MeshCollider collider; if (chunkObject.GetComponent <MeshCollider>() == null) { collider = (MeshCollider)chunkObject.AddComponent(typeof(MeshCollider)); } else { collider = chunkObject.GetComponent <MeshCollider>(); } collider.sharedMesh = chunkMesh; // Set the mesh // chunkMesh.RecalculateNormals(); // Recalculate the normals to avoid lightning problems modelBuilder.Clear(); calculatedMesh = true; // The mesh is calculated and can be used by other chunks to check if this chunk covers any of their blocks }
public static GeometricPrimitive CreateFromChunk(VoxelChunk Chunk, WorldManager World) { DebugHelper.AssertNotNull(Chunk); DebugHelper.AssertNotNull(World); var sliceStack = new List <RawPrimitive>(); var sliceCache = new SliceCache(); int maxViewingLevel = World.Renderer.PersistentSettings.MaxViewingLevel; var terrainTileSheet = new TerrainTileSheet(512, 512, 32, 32); for (var localY = 0; localY < maxViewingLevel - Chunk.Origin.Y && localY < VoxelConstants.ChunkSizeY; ++localY) { RawPrimitive sliceGeometry = null; sliceCache.ClearSliceCache(); lock (Chunk.Data.SliceCache) { var cachedSlice = Chunk.Data.SliceCache[localY]; if (cachedSlice != null) { sliceStack.Add(cachedSlice); // Todo: Get rid of the raw primitive / geometric primitive bullshit entirely if (GameSettings.Current.GrassMotes) { Chunk.RebuildMoteLayerIfNull(localY); } continue; } sliceGeometry = new RawPrimitive(); Chunk.Data.SliceCache[localY] = sliceGeometry; } if (GameSettings.Current.CalculateRamps) { PrecomputeVoxelSlopesSlice(World.ChunkManager, Chunk, localY); } if (GameSettings.Current.GrassMotes) { Chunk.RebuildMoteLayer(localY); } DebugHelper.AssertNotNull(sliceGeometry); GenerateSliceGeometry(sliceGeometry, Chunk, localY, terrainTileSheet, World, sliceCache); sliceStack.Add(sliceGeometry); } var chunkGeo = RawPrimitive.Concat(sliceStack); var r = new GeometricPrimitive(); r.Vertices = chunkGeo.Vertices; r.VertexCount = chunkGeo.VertexCount; r.Indexes = chunkGeo.Indexes.Select(c => (ushort)c).ToArray(); r.IndexCount = chunkGeo.IndexCount; return(r); }
void ResizeGrid(int newGridWidth, int newGridHeight, int newGridDepth) { // DEBUG: // Debug.Log ("- Resizing grid: from (" + gridWidth + ", " + gridHeight + ", " + gridDepth + ") to (" + newGridWidth + ", " + newGridHeight + ", " + newGridDepth + ")"); VoxelChunk[] newGrid = new VoxelChunk[newGridHeight * newGridDepth * newGridWidth]; int i = 0; for (int y = 0; y < gridHeight; y++) { int y1 = y * newGridDepth * newGridWidth; for (int z = 0; z < gridDepth; z++) { int z1 = z * newGridWidth; for (int x = 0; x < gridWidth; x++) { newGrid [y1 + z1 + x] = grid [i++]; } } } gridWidth = newGridWidth; gridHeight = newGridHeight; gridDepth = newGridDepth; grid = null; grid = newGrid; }
private void GetChunk(ref Vector3I coord, out VoxelChunk chunk, MyStorageDataTypeFlags required) { using (m_cacheLock.AcquireExclusiveUsing()) { if (!m_cachedChunks.TryGetValue(coord, out chunk)) { chunk = new VoxelChunk(coord); var rangeStart = coord << VoxelChunk.SizeBits; var rangeEnd = ((coord + 1) << VoxelChunk.SizeBits) - 1; if (required != 0) { using (m_storageLock.AcquireSharedUsing()) ReadDatForChunk(chunk, required); } m_chunksbyAge.Enqueue(coord); m_cachedChunks.Add(coord, chunk); var bb = new BoundingBox(rangeStart, rangeEnd); chunk.TreeProxy = m_cacheMap.AddProxy(ref bb, chunk, 0); } else if ((chunk.Cached & required) != required) { using (m_storageLock.AcquireSharedUsing()) ReadDatForChunk(chunk, required & ~chunk.Cached); } } }
public bool isGridBlock(VoxelChunk chunk, int voxelIndex) { return(IsGridChuck(chunk) && IsRootVoxel(voxelIndex)); }
/// <summary> /// Update a specific voxel (Called from world update thread) /// </summary> /// <param name="Tick">Current tick number</param> /// <param name="LocalPosition">Voxel position in chunk</param> /// <param name="Voxel">Voxel object in question</param> /// <param name="Chunk">Chunk the voxel belongs to</param> /// <returns>Has there been any changes</returns> public abstract bool UpdateVoxel(uint Tick, Point LocalPosition, VoxelInstance Voxel, VoxelChunk Chunk);
public bool GetChunk(Vector3 position, out VoxelChunk chunk, bool forceCreation = false) { FastMath.FloorToInt(position.X / CHUNK_SIZE, position.Y / CHUNK_SIZE, position.Z / CHUNK_SIZE, out int chunkX, out int chunkY, out int chunkZ); return(GetChunkFast(chunkX, chunkY, chunkZ, out chunk, forceCreation)); }
public bool Execute(VoxelChunk chunk, int x, int y, int z) { return _executeCallback (chunk, x, y, z); }
void OnEnable() { _target = (VoxelChunk)target; if (_target.data != null) { newDataString = GetStringFromData (_target.width, _target.height, _target.depth, _target.data); } else { newDataString = ""; } }
static void Build( ref VoxelChunk res, int tianglesNum ) { for( int i = 0; i < tianglesNum; i++ ) { //res.AddIndex( res.VertexCount + 0 ); //res.AddIndex( res.VertexCount + 1 ); //res.AddIndex( res.VertexCount + 2 ); Vector3 normal = Vector3.Cross( _triangles[ i ].P[ 1 ] - _triangles[ i ].P[ 0 ], _triangles[ i ].P[ 2 ] - _triangles[ i ].P[ 0 ] ); res.AddVertex( _triangles[ i ].P[ 0 ], normal ); res.AddVertex( _triangles[ i ].P[ 1 ], normal ); res.AddVertex( _triangles[ i ].P[ 2 ], normal ); } }
/// <summary> /// Remove and create new triangles in bounding box. Very Slow! /// </summary> /// <param name="graphicsDevice"></param> /// <param name="isolevel"></param> /// <param name="primitive"></param> /// <param name="box"></param> public static void ReProcess( GraphicsDevice graphicsDevice, double isolevel, ref VoxelChunk primitive, BoundingBox box ) { //primitive.Remove( box ); primitive.RemoveBorderCubes( box ); int triNum = 0; int minx = (int)box.Minimum.X; int miny = (int)box.Minimum.Y; int minz = (int)box.Minimum.Z; int maxx = (int)box.Maximum.X; int maxy = (int)box.Maximum.Y; int maxz = (int)box.Maximum.Z; for( int i = minx; i < maxx; i++ ) { for( int j = miny; j < maxy; j++ ) { for( int k = minz; k < maxz; k++ ) { triNum = Polygonise( i, j, k, isolevel ); if( triNum > 0 ) { primitive.borderCubes.Add( new Vector3( i, j, k ) ); Build( ref primitive, triNum ); } } } } //if( primitive.VertexCount == 0 ) //{ // primitive.isDrawable = false; //} //else //{ // primitive.InitializePrimitive( graphicsDevice ); //} }
public static void Process( GraphicsDevice graphicsDevice, double isolevel, ref VoxelChunk primitive ) { //primitive.Clear(); primitive.borderCubes.Clear(); int triNum = 0; for( int i = 0; i < _size; i++ ) { for( int j = 0; j < _size; j++ ) { for( int k = 0; k < _size; k++ ) { triNum = Polygonise( i, j, k, isolevel ); if( triNum > 0 ) { //primitive.borderCubes.Add(new Vector3(i,j,k)); Build( ref primitive, triNum ); } } } } //if (primitive.VertexCount == 0) primitive.isDrawable = false; //else primitive.InitializePrimitive(graphicsDevice); primitive.NeedRecalculation = false; }
public static VoxelChunk Process( GraphicsDevice graphicsDevice, double isolevel ) { var res = new VoxelChunk(); Process( graphicsDevice, isolevel, ref res ); return res; }
/// <summary> /// Paints the terrain inside the chunk defined by its central "position" /// </summary> /// <returns><c>true</c>, if terrain was painted, <c>false</c> otherwise.</returns> /// <param name="position">Central position of the chunk.</param> public override bool PaintChunk(VoxelChunk chunk) { return(PaintChunkA(chunk)); }
Stack <Vector3> Dijkstra(Vector3 start, Vector3 end, VoxelChunk vc) { Stack <Vector3> waypoints = new Stack <Vector3>(); List <Vector3> l = new List <Vector3>(); disDictionary = new Dictionary <Vector3, int>(); Dictionary <Vector3, Vector3> visitedParent = new Dictionary <Vector3, Vector3>(); bool found = false; Vector3 current = start; int newDist; disDictionary[start] = 0; if (vc.isTraversable(current)) { l.Add(current); } while (l.Count > 0 && !found) { int minDistance = disDictionary[l[0]]; current = l[0]; for (int i = 0; i < l.Count; i++) { if (minDistance > disDictionary[l[i]]) { current = l[i]; minDistance = vc.GetDistanceCost(l[i]); } } l.Remove(current); if (current != end) { List <Vector3> neighbourList = new List <Vector3>(); neighbourList.Add(current + new Vector3(1, 0, 0)); neighbourList.Add(current + new Vector3(-1, 0, 0)); neighbourList.Add(current + new Vector3(0, 0, 1)); neighbourList.Add(current + new Vector3(0, 0, -1)); foreach (Vector3 n in neighbourList) { if (n.x >= 0 && n.x < vc.GetChunkSize() && n.z >= 0 && n.z < vc.GetChunkSize() && vc.isTraversable(n)) { newDist = disDictionary[current] + vc.GetDistanceCost(n); if (!visitedParent.ContainsKey(n) || newDist < disDictionary[n]) { disDictionary[n] = newDist; visitedParent[n] = current; l.Add(n); } } } } else { found = true; } } if (found) { Debug.Log("The path cost is: " + disDictionary[current]); while (current != start) { waypoints.Push(current + offset); current = visitedParent[current]; } waypoints.Push(start + offset); } return(waypoints); }
private void CreateTree(Vector3 position, ModelSettings tree, int rotation) { if (tree == null) { return; } Vector3 pos = new Vector3(); mTreeChunkRefreshRequests.Clear(); VoxelChunk lastChunk = null; int modelOneYRow = tree.SizeZ * tree.SizeX; int modelOneZRow = tree.SizeX; int halfSizeX = tree.SizeX / 2; int halfSizeZ = tree.SizeZ / 2; for (int b = 0; b < tree.Bits.Length; b++) { int bitIndex = tree.Bits[b].VoxelIndex; int py = bitIndex / modelOneYRow; int remy = bitIndex - py * modelOneYRow; int pz = remy / modelOneZRow; int px = remy - pz * modelOneZRow; // Random rotation int tmp; switch (rotation) { case 0: tmp = px; px = halfSizeZ - pz; pz = tmp - halfSizeX; break; case 1: tmp = px; px = pz - halfSizeZ; pz = tmp - halfSizeX; break; case 2: tmp = px; px = pz - halfSizeZ; pz = halfSizeX - tmp; break; default: px -= halfSizeX; pz -= halfSizeZ; break; } pos.X = position.X + tree.OffsetX + px; pos.Y = position.Y + tree.OffsetY + py; pos.Z = position.Z + tree.OffsetZ + pz; if (GetVoxelIndex(pos, out VoxelChunk chunk, out int voxelIndex)) { if (chunk.Voxels[voxelIndex].Color != 0) { chunk.Voxels[voxelIndex].Color = tree.Bits[b].Color.ColorToUInt(); if (py == 0) { if (voxelIndex >= ONE_Y_ROW) { if (chunk.Voxels[voxelIndex - ONE_Y_ROW].Color != 0) { chunk.Voxels[voxelIndex - ONE_Y_ROW].Color = tree.Bits[b].Color.ColorToUInt(); } } else { VoxelChunk bottom = chunk.Bottom; if (bottom != null) { int bottomIndex = voxelIndex + (CHUNK_SIZE - 1) * ONE_Y_ROW; if (bottom.Voxels[bottomIndex].Color != 0) { chunk.Voxels[bottomIndex].Color = tree.Bits[b].Color.ColorToUInt(); if (!mTreeChunkRefreshRequests.Contains(bottom)) { mTreeChunkRefreshRequests.Add(bottom); } } } } } if (chunk != lastChunk) { lastChunk = chunk; if (!mTreeChunkRefreshRequests.Contains(chunk)) { mTreeChunkRefreshRequests.Add(chunk); } } } } } }
public void PaintChunk(VoxelChunk chunk) { Vector3 position = chunk.Position; if (position.Y + TerrainEnvironment.CHUNK_HALF_SIZE < MinHeight) { return; } int bedrockRow = -1; if (position.Y < MinHeight + TerrainEnvironment.CHUNK_HALF_SIZE) { bedrockRow = (int)(MinHeight - (position.Y - TerrainEnvironment.CHUNK_HALF_SIZE) + 1) * ONE_Y_ROW - 1; } position.X -= TerrainEnvironment.CHUNK_HALF_SIZE; position.Y -= TerrainEnvironment.CHUNK_HALF_SIZE; position.Z -= TerrainEnvironment.CHUNK_HALF_SIZE; Vector3 pos = new Vector3(); int waterLevel = WaterLevel > 0 ? WaterLevel : -1; Voxel[] voxels = chunk.Voxels; mGeneration++; TerrainEnvironment.Instance.GetHeightMapInfo(position.X, position.Z, mHeightChunkData); int shiftAmount = (int)MathF.Log(TerrainEnvironment.CHUNK_SIZE, 2); for (int arrayIndex = 0; arrayIndex < TerrainEnvironment.CHUNK_SIZE * TerrainEnvironment.CHUNK_SIZE; arrayIndex++) { float groundLevel = mHeightChunkData[arrayIndex].GroundLevel; float surfaceLevel = waterLevel > groundLevel ? waterLevel : groundLevel; if (surfaceLevel < pos.Y) { continue; } BiomeSettings biome = mHeightChunkData[arrayIndex].Biome; if (biome == null) { biome = TerrainEnvironment.Instance.WorldTerrainData.DefaultBiome; if (biome == null) { continue; } } int y = (int)(surfaceLevel - position.Y); if (y >= TerrainEnvironment.CHUNK_SIZE) { y = TerrainEnvironment.CHUNK_SIZE - 1; } pos.Y = position.Y + y; pos.X = position.X + (arrayIndex & (TerrainEnvironment.CHUNK_SIZE - 1)); pos.Z = position.Z + (arrayIndex >> shiftAmount); int voxelIndex = y * ONE_Y_ROW + arrayIndex; if (voxelIndex < 0) { continue; } if (pos.Y > groundLevel) { while (pos.Y > groundLevel && voxelIndex >= 0) { voxels[voxelIndex].Color = WaterColor.ColorToUInt(); voxelIndex -= ONE_Y_ROW; pos.Y--; } } else if (pos.Y == groundLevel) { voxels[voxelIndex].Color = 0; if (voxels[voxelIndex].Color == 0) { if (pos.Y == waterLevel) { voxels[voxelIndex].Color = ShoreColor.ColorToUInt(); } else { voxels[voxelIndex].Color = biome.VoxelTop.ColorToUInt(); if (pos.Y > waterLevel) { float rdn = WorldRandom.GetValue(pos); if (biome.TreeDensity > 0 && rdn < biome.TreeDensity && biome.Trees.Length > 0) { TerrainEnvironment.Instance.RequestTreeCreation(chunk, pos, TerrainEnvironment.Instance.GetTree(biome.Trees, rdn / biome.TreeDensity)); } else if (biome.VegetationDensity > 0 && rdn < biome.VegetationDensity && biome.Vegetation.Length > 0) { if (voxelIndex >= (TerrainEnvironment.CHUNK_SIZE - 1) * ONE_Y_ROW) { TerrainEnvironment.Instance.RequestVegetationCreation(chunk.Top, voxelIndex - ONE_Y_ROW * (TerrainEnvironment.CHUNK_SIZE - 1), TerrainEnvironment.Instance.GetVegetation(biome, rdn / biome.VegetationDensity)); } else { voxels[voxelIndex + ONE_Y_ROW].Color = TerrainEnvironment.Instance.GetVegetation(biome, rdn / biome.VegetationDensity).ColorToUInt(); } } } } voxelIndex -= ONE_Y_ROW; pos.Y--; } } biome.BiomeGeneration = mGeneration; while (voxelIndex >= 0 && voxels[voxelIndex].Color == 0 && pos.Y <= waterLevel) { voxels[voxelIndex].Color = WaterColor.ColorToUInt(); voxelIndex -= ONE_Y_ROW; pos.Y--; } for (; voxelIndex > bedrockRow; voxelIndex -= ONE_Y_ROW, pos.Y--) { if (voxels[voxelIndex].Color == 0) { voxels[voxelIndex].Color = biome.VoxelDirt.ColorToUInt(); } else if (voxels[voxelIndex].Color == 0 && pos.Y <= waterLevel) { // hole under water level -> fill with water voxels[voxelIndex].Color = WaterColor.ColorToUInt(); } } if (bedrockRow >= 0 && voxelIndex >= 0) { voxels[voxelIndex].Color = BedrockColor.ColorToUInt(); } } }
private void UpdateChunk(VoxelChunk chunk) { chunk.threadReady = true; chunk.MeshReady(); }
private void FindSurfaceEdgesAndVertices(VoxelChunk chunk, EdgeSet edgeSet, List <Vector3> vertices, List <Vector3> normals, Dictionary <Vector3Int, int> blockVertexMap) { for (int x = 0; x < VoxelChunk.CHUNK_SIZE; x += 1) { for (int y = 0; y < VoxelChunk.CHUNK_SIZE; y += 1) { for (int z = 0; z < VoxelChunk.CHUNK_SIZE; z += 1) { Vector3Int p0 = new Vector3Int(x, y, z); Voxel v0 = chunk.VoxelAtPosition(p0); Vector3 vertex = Vector3.zero; Vector3 normal = Vector3.zero; int numIntersectingEdges = 0; foreach (EdgeOffset offset in EdgeOffsets) { // P1 & P2 represent the actual edge Vector3Int p1 = p0 + offset.p1; Vector3Int p2 = p0 + offset.p2; // Bounds check - can't be an edge if any of these exist outside the chunk // TODO: In a real-world scenario, we would evaluate neighboring chunks if (p1.x < 0 || p1.y < 0 || p1.z < 0 || p2.x < 0 || p2.y < 0 || p2.z < 0) { continue; } if (p1.x >= VoxelChunk.CHUNK_SIZE || p1.y >= VoxelChunk.CHUNK_SIZE || p1.z >= VoxelChunk.CHUNK_SIZE || p2.x >= VoxelChunk.CHUNK_SIZE || p2.y >= VoxelChunk.CHUNK_SIZE || p2.z >= VoxelChunk.CHUNK_SIZE) { continue; } Voxel v1 = chunk.VoxelAtPosition(p1); Voxel v2 = chunk.VoxelAtPosition(p2); // Sign change - this is an edge we're interested in. if (!Mathf.Approximately(Mathf.Sign(v1.signedDistance), Mathf.Sign(v2.signedDistance))) { // Keep track of the vertex, we'll be adding to the vertex list while we're in here vertex += DetermineEdgePoint(p1, p2, v1, v2); ++numIntersectingEdges; // Add to our edge list AddEdge(p0, p1, p2, v1, v2, edgeSet); // Normal is the sum of all the gradients normal += DetermineGradient(p1, p2, v1, v2); } } if (numIntersectingEdges != 0) { vertex /= numIntersectingEdges; vertices.Add(vertex); normals.Add(normal); blockVertexMap[p0] = vertices.Count - 1; } } } } }
private void Start() { testChunk = GenerateTestChunk(); UpdateTestChunk(); }
bool ExecuteQueryCallback(VoxelChunk chunk, int voxelX, int voxelY, int voxelZ) { // DEBUG: //Debug.Log ("- Removing voxel [chunk=(" + chunk.x + ", " + chunk.y + ", " + chunk.z + "), voxel=(" + voxelX + ", " + voxelY + ", " + voxelZ + ")]"); List<VoxelPosition> voxelPositions; if (!queryResults.TryGetValue (chunk, out voxelPositions)) { voxelPositions = new List<VoxelPosition> (); queryResults.Add (chunk, voxelPositions); } voxelPositions.Add (new VoxelPosition (voxelX, voxelY, voxelZ)); return true; }
private void DequeueDirtyChunk(out VoxelChunk chunk, out Vector3I coords) { coords = m_pendingChunksToWrite.Dequeue(); m_cachedChunks.TryGetValue(coords, out chunk); Debug.Assert(chunk != null); }
void checkChunk(ChunkData chunk) { for(int i = 0; i <= uncoverArea; i++) { //N if(!GameObject.Find ("Voxel Mesh " + (chunk.m_pos.x+(i*8)).ToString() + " " + (chunk.m_pos.y).ToString() + " " + (chunk.m_pos.z).ToString())) { PerlinNoise m_surfacePerlin = new PerlinNoise(terrain.m_surfaceSeed); Vector3 pos = new Vector3(chunk.m_pos.x+8*i+1, chunk.m_pos.y+1, chunk.m_pos.z+1); m_voxelChunktemp = new VoxelChunk(pos, terrain.m_voxelWidth, terrain.m_voxelHeight, terrain.m_voxelLength, terrain.m_surfaceLevel); m_voxelChunktemp.CreateVoxels (m_surfacePerlin); m_voxelChunktemp.CreateMesh (terrain.m_material); //chunk.bOnce = true; } //NW if(!GameObject.Find ("Voxel Mesh " + (chunk.m_pos.x+8*i).ToString() + " " + (chunk.m_pos.y).ToString() + " " + (chunk.m_pos.z + 8*i).ToString())) { PerlinNoise m_surfacePerlin = new PerlinNoise(terrain.m_surfaceSeed); Vector3 pos = new Vector3(chunk.m_pos.x+8*i+1, chunk.m_pos.y+1, chunk.m_pos.z+8*i+1); m_voxelChunktemp = new VoxelChunk(pos, terrain.m_voxelWidth, terrain.m_voxelHeight, terrain.m_voxelLength, terrain.m_surfaceLevel); m_voxelChunktemp.CreateVoxels (m_surfacePerlin); m_voxelChunktemp.CreateMesh (terrain.m_material); //chunk.bOnce = true; } //NE if(!GameObject.Find ("Voxel Mesh " + (chunk.m_pos.x+8*i).ToString() + " " + (chunk.m_pos.y).ToString() + " " + (chunk.m_pos.z - 8*i).ToString())) { PerlinNoise m_surfacePerlin = new PerlinNoise(terrain.m_surfaceSeed); Vector3 pos = new Vector3(chunk.m_pos.x+8*i+1, chunk.m_pos.y+1, chunk.m_pos.z-8*i+1); m_voxelChunktemp = new VoxelChunk(pos, terrain.m_voxelWidth, terrain.m_voxelHeight, terrain.m_voxelLength, terrain.m_surfaceLevel); m_voxelChunktemp.CreateVoxels (m_surfacePerlin); m_voxelChunktemp.CreateMesh (terrain.m_material); //chunk.bOnce = true; } //S if(!GameObject.Find ("Voxel Mesh " + (chunk.m_pos.x-8*i).ToString() + " " + (chunk.m_pos.y).ToString() + " " + (chunk.m_pos.z).ToString())) { PerlinNoise m_surfacePerlin = new PerlinNoise(terrain.m_surfaceSeed); Vector3 pos = new Vector3(chunk.m_pos.x-8*i+1, chunk.m_pos.y+1, chunk.m_pos.z+1); m_voxelChunktemp = new VoxelChunk(pos, terrain.m_voxelWidth, terrain.m_voxelHeight, terrain.m_voxelLength, terrain.m_surfaceLevel); m_voxelChunktemp.CreateVoxels (m_surfacePerlin); m_voxelChunktemp.CreateMesh (terrain.m_material); //chunk.bOnce = true; } //SW if(!GameObject.Find ("Voxel Mesh " + (chunk.m_pos.x-8*i).ToString() + " " + (chunk.m_pos.y).ToString() + " " + (chunk.m_pos.z + 8*i).ToString())) { PerlinNoise m_surfacePerlin = new PerlinNoise(terrain.m_surfaceSeed); Vector3 pos = new Vector3(chunk.m_pos.x-8*i+1, chunk.m_pos.y+1, chunk.m_pos.z+8*i+1); m_voxelChunktemp = new VoxelChunk(pos, terrain.m_voxelWidth, terrain.m_voxelHeight, terrain.m_voxelLength, terrain.m_surfaceLevel); m_voxelChunktemp.CreateVoxels (m_surfacePerlin); m_voxelChunktemp.CreateMesh (terrain.m_material); //chunk.bOnce = true; } //SE if(!GameObject.Find ("Voxel Mesh " + (chunk.m_pos.x-8*i).ToString() + " " + (chunk.m_pos.y).ToString() + " " + (chunk.m_pos.z - 8*i).ToString())) { PerlinNoise m_surfacePerlin = new PerlinNoise(terrain.m_surfaceSeed); Vector3 pos = new Vector3(chunk.m_pos.x-8*i+1, chunk.m_pos.y+1, chunk.m_pos.z-8*i+1); m_voxelChunktemp = new VoxelChunk(pos, terrain.m_voxelWidth, terrain.m_voxelHeight, terrain.m_voxelLength, terrain.m_surfaceLevel); m_voxelChunktemp.CreateVoxels (m_surfacePerlin); m_voxelChunktemp.CreateMesh (terrain.m_material); //chunk.bOnce = true; } //W if(!GameObject.Find ("Voxel Mesh " + (chunk.m_pos.x).ToString() + " " + (chunk.m_pos.y).ToString() + " " + (chunk.m_pos.z + 8*i).ToString())) { PerlinNoise m_surfacePerlin = new PerlinNoise(terrain.m_surfaceSeed); Vector3 pos = new Vector3(chunk.m_pos.x+1, chunk.m_pos.y+1, chunk.m_pos.z+8*i+1); m_voxelChunktemp = new VoxelChunk(pos, terrain.m_voxelWidth, terrain.m_voxelHeight, terrain.m_voxelLength, terrain.m_surfaceLevel); m_voxelChunktemp.CreateVoxels (m_surfacePerlin); m_voxelChunktemp.CreateMesh (terrain.m_material); //chunk.bOnce = true; } //E if(!GameObject.Find ("Voxel Mesh " + (chunk.m_pos.x).ToString() + " " + (chunk.m_pos.y).ToString() + " " + (chunk.m_pos.z - 8*i).ToString())) { PerlinNoise m_surfacePerlin = new PerlinNoise(terrain.m_surfaceSeed); Vector3 pos = new Vector3(chunk.m_pos.x+1, chunk.m_pos.y+1, chunk.m_pos.z-8*i+1); m_voxelChunktemp = new VoxelChunk(pos, terrain.m_voxelWidth, terrain.m_voxelHeight, terrain.m_voxelLength, terrain.m_surfaceLevel); m_voxelChunktemp.CreateVoxels (m_surfacePerlin); m_voxelChunktemp.CreateMesh (terrain.m_material); //chunk.bOnce = true; } } //Debug.Log ("Difference: " + (chunk.m_pos - centerChunkPos) + " Chunk name: " + chunk.name + " Current Dir: " + currentDir); /*if((((chunk.m_pos.z - centerChunkPos.z == -8 || chunk.m_pos.z - centerChunkPos.z == 8) && chunk.m_pos.x - centerChunkPos.x == 0) || (chunk.m_pos.x - centerChunkPos.x == 0 && chunk.m_pos.z - centerChunkPos.z == 0)) && currentDir == Dir.North) { if(!GameObject.Find ("Voxel Mesh " + (chunk.m_pos.x+8).ToString() + " " + (chunk.m_pos.y).ToString() + " " + (chunk.m_pos.z).ToString())) { PerlinNoise m_surfacePerlin = new PerlinNoise(terrain.m_surfaceSeed); Vector3 pos = new Vector3(chunk.m_pos.x+9, chunk.m_pos.y+1, chunk.m_pos.z+1); m_voxelChunktemp = new VoxelChunk(pos, terrain.m_voxelWidth, terrain.m_voxelHeight, terrain.m_voxelLength, terrain.m_surfaceLevel); m_voxelChunktemp.CreateVoxels (m_surfacePerlin); m_voxelChunktemp.CreateMesh (terrain.m_material); Debug.Log ("Voxel Mesh " + (chunk.m_pos.x+8).ToString() + " " + (chunk.m_pos.y).ToString() + " " + (chunk.m_pos.z).ToString()); //chunk.bOnce = true; } }*/ /*if(((chunk.m_pos.x - centerChunkPos.x == -8 || chunk.m_pos.x - centerChunkPos.x == 8) && (chunk.m_pos.z - centerChunkPos.z == 0)) || (chunk.m_pos - centerChunkPos) == new Vector3(0,0,0)) { Debug.Log ("CurrentDir (wersja 1)" + currentDir); PerlinNoise m_surfacePerlin = new PerlinNoise(terrain.m_surfaceSeed); // m_voxelChunktemp = new VoxelChunk[1, 2, 1]; // for(int x = 0; x<1; x++) // { // for (int y = 0; y<2; y++) // { // for(int z = 0; z< 1; z++) // { Vector3 pos = new Vector3(chunk.m_pos.x+9, chunk.m_pos.y, chunk.m_pos.z + 9); m_voxelChunktemp = new VoxelChunk(pos, terrain.m_voxelWidth, terrain.m_voxelHeight, terrain.m_voxelLength, terrain.m_surfaceLevel); m_voxelChunktemp.CreateVoxels (m_surfacePerlin); m_voxelChunktemp.CreateMesh (terrain.m_material); // } // } // } i++; Debug.Log ("Stworzylem : " + i + " obiektow " + pos); }*/ /* if(((chunk.m_pos.z - centerChunkPos.z == -8 || chunk.m_pos.z - centerChunkPos.z == 8) && (chunk.m_pos.x - centerChunkPos.x == 0)) || (chunk.m_pos - centerChunkPos) == new Vector3(0,0,0)) { Debug.Log ("CurrentDir (wersja 2)" + currentDir); PerlinNoise m_surfacePerlin = new PerlinNoise(terrain.m_surfaceSeed); m_voxelChunktemp = new VoxelChunk[1, 2, 1]; for(int x = 0; x<1; x++) { for (int y = 0; y<2; y++) { for(int z = 0; z< 1; z++) { Vector3 pos = new Vector3(chunk.m_pos.x+9, chunk.m_pos.y, chunk.m_pos.z + 1); m_voxelChunktemp[x, y, z] = new VoxelChunk(pos, terrain.m_voxelWidth, terrain.m_voxelHeight, terrain.m_voxelLength, terrain.m_surfaceLevel); m_voxelChunktemp[x, y, z].CreateVoxels (m_surfacePerlin); m_voxelChunktemp[x, y, z].CreateMesh (terrain.m_material); } } } }*/ //return chunk; chunk.bUsed = true; chunks.Remove (chunk); }
public static void GenerateRuin(VoxelChunk Chunk, ChunkGeneratorSettings Settings) { var noiseVector = Chunk.Origin.ToVector3() * Settings.CaveNoiseScale; var ruinsNoise = Settings.CaveNoise.GetValue(noiseVector.X, noiseVector.Y, noiseVector.Z); if (Math.Abs(ruinsNoise) > GameSettings.Default.GenerationRuinsRate) { return; } int structureWidth = MathFunctions.RandInt(4, 16); int structureDepth = MathFunctions.RandInt(4, 16); int xOffset = MathFunctions.RandInt(0, VoxelConstants.ChunkSizeX - structureWidth); int zOffset = MathFunctions.RandInt(0, VoxelConstants.ChunkSizeZ - structureDepth); int wallHeight = MathFunctions.RandInt(2, 6); int heightOffset = MathFunctions.RandInt(-4, 2); if (Settings.Overworld.Map.GetBiomeAt(Chunk.Origin.ToVector3(), Settings.Overworld.InstanceSettings.Origin).HasValue(out var biome)) { var avgHeight = GetAverageHeight(Chunk.Origin.X, Chunk.Origin.Z, structureWidth, structureDepth, Settings); bool[] doors = new bool[4]; for (int k = 0; k < 4; k++) { doors[k] = MathFunctions.RandEvent(0.5f); } for (int dx = 0; dx < structureWidth; dx++) { for (int dz = 0; dz < structureDepth; dz++) { var worldPos = new Vector3(Chunk.Origin.X + dx + xOffset, avgHeight + heightOffset, Chunk.Origin.Z + dz + zOffset); var baseVoxel = Settings.World.ChunkManager.CreateVoxelHandle(GlobalVoxelCoordinate.FromVector3(worldPos)); var underVoxel = VoxelHelpers.FindFirstVoxelBelow(Settings.World.ChunkManager.CreateVoxelHandle(GlobalVoxelCoordinate.FromVector3(worldPos))); var decay = Settings.NoiseGenerator.Generate(worldPos.X * 0.05f, worldPos.Y * 0.05f, worldPos.Z * 0.05f); if (decay > 0.7f) { continue; } if (!baseVoxel.IsValid) { continue; } if (baseVoxel.Coordinate.Y == (Settings.WorldSizeInChunks.Y * VoxelConstants.ChunkSizeY) - 1) { continue; } if (!underVoxel.IsValid) { continue; } var edge = (dx == 0 || dx == structureWidth - 1) || (dz == 0 || dz == structureDepth - 1); if (!edge && !baseVoxel.IsEmpty) { continue; } if (edge) { baseVoxel.RawSetType(Library.GetVoxelType(biome.RuinWallType)); } else { baseVoxel.RawSetType(Library.GetVoxelType(biome.RuinFloorType)); } bool[] wallState = new bool[4]; wallState[0] = dx == 0; wallState[1] = dx == structureWidth - 1; wallState[2] = dz == 0; wallState[3] = dz == structureDepth - 1; bool[] doorState = new bool[4]; doorState[0] = Math.Abs(dz - structureDepth / 2) < 1; doorState[1] = doorState[0]; doorState[2] = Math.Abs(dx - structureWidth / 2) < 1; doorState[3] = doorState[2]; for (int dy = 1; dy < (baseVoxel.Coordinate.Y - underVoxel.Coordinate.Y); dy++) { var currVoxel = Settings.World.ChunkManager.CreateVoxelHandle(underVoxel.Coordinate + new GlobalVoxelOffset(0, dy, 0)); if (!currVoxel.IsValid) { continue; } currVoxel.RawSetType(underVoxel.Type); } underVoxel.RawSetGrass(0); if (edge) { for (int dy = 1; dy < wallHeight * (1.0f - decay) && dy < (Settings.WorldSizeInChunks.Y * VoxelConstants.ChunkSizeY) - 2; dy++) { var currVoxel = Settings.World.ChunkManager.CreateVoxelHandle(baseVoxel.Coordinate + new GlobalVoxelOffset(0, dy, 0)); if (!currVoxel.IsValid) { continue; } if (currVoxel.Coordinate.Y == VoxelConstants.ChunkSizeY - 1) { continue; } bool door = false; for (int k = 0; k < 4; k++) { if (wallState[k] && doors[k] && doorState[k]) { door = true; break; } } if (door && dy < 3) { continue; } currVoxel.RawSetType(Library.GetVoxelType(biome.RuinWallType)); } } } } } }
private static void AddTriangleToDictionary(int vertexIndexKey, Triangle triangle, VoxelChunk chunk) { if (chunk.triangleDictionary.ContainsKey(chunk.vertices[vertexIndexKey])) { chunk.triangleDictionary[chunk.vertices[vertexIndexKey]].Add(triangle); } else { var triangleList = new List <Triangle> { triangle }; chunk.triangleDictionary.Add(chunk.vertices[vertexIndexKey], triangleList); } }
public VertexArray Voxelize(VoxelCollection collection, VoxelChunk chunk) { List<float> verts = new List<float>(); return null; }
public VoxelChunkCreatedEvent(VoxelChunk chunk) { Chunk = chunk; }
void Temp() { RaycastHit hit; /* * ------- * | |x| | * ------- * | | | | * ------- * | | | | * ------- */ if(Physics.Raycast (player.position + player.forward * 32 * m_voxelWidth, player.position + player.forward * 32 * m_voxelWidth - new Vector3(0, 128, 0), out hit)) { Debug.DrawLine(player.position + player.forward * 32 * m_voxelWidth, player.position + player.forward * 32 * m_voxelWidth - new Vector3(0, 128, 0), Color.red); //Debug.Log ("N Trafilem w: " + hit.transform.GetComponent<ChunkData>().m_pos); lastPosN = hit.transform.GetComponent<ChunkData>().m_pos; } else { if(Physics.Raycast (player.position + player.forward * 16 * m_voxelWidth, player.position + player.forward * 16 * m_voxelWidth - new Vector3(0, 128, 0), out hit)) { Debug.DrawLine(player.position + player.forward * 16 * m_voxelWidth, player.position + player.forward * 16 * m_voxelWidth - new Vector3(0, 128, 0), Color.green); //Debug.Log ("N Trafilem w: " + hit.transform.GetComponent<ChunkData>().m_pos); lastPosN = hit.transform.GetComponent<ChunkData>().m_pos; PerlinNoise m_surfacePerlin = new PerlinNoise(m_surfaceSeed); Vector3 offset = new Vector3(m_chunksX*m_voxelWidth*0.5f, -(m_chunksY-m_chunksAbove0)*m_voxelHeight, m_chunksZ*m_voxelLength*0.5f); // Vector3 pos = lastPosN + new Vector3(108, 0, 0); m_voxelChunktemp = new VoxelChunk[1, 2, 1]; for(int x = 0; x<1; x++) { for (int y = 0; y<2; y++) { for(int z = 0; z< 1; z++) { Vector3 pos = new Vector3((x+lastPosN.x)*m_voxelWidth/32, y*m_voxelHeight, z*m_voxelLength); Debug.Log ("POS: " + (pos + offset) + " / " + (lastPosN + pos) + " / " + lastPosN); m_voxelChunktemp[x, y, z] = new VoxelChunk(lastPosN + pos, m_voxelWidth, m_voxelHeight, m_voxelLength, m_surfaceLevel); m_voxelChunktemp[x, y, z].CreateVoxels (m_surfacePerlin); m_voxelChunktemp[x, y, z].CreateMesh (m_material); } } } Debug.DrawLine(player.position + player.forward * 32 * m_voxelWidth, -Vector3.up * 128, Color.red); m_chunksX++; } } /* * ------- * | | |x| * ------- * | | | | * ------- * | | | | * ------- */ if(Physics.Raycast (player.position + player.forward * 32 * m_voxelWidth + player.right * 128, player.position + player.forward * 16 * m_voxelWidth + player.right * 128 - new Vector3(0, 128, 0), out hit)) { lastPosNE = hit.transform.GetComponent<ChunkData>().m_pos; } else { if(Physics.Raycast (player.position + player.forward * 16 * m_voxelWidth + player.right * 128, player.position + player.forward * 16 * m_voxelWidth + player.right * 128 - new Vector3(0, 128, 0), out hit)) { Debug.DrawLine(player.position + player.forward * 16 * m_voxelWidth + player.right * 128, player.position + player.forward * 16 * m_voxelWidth + player.right * 128 - new Vector3(0, 128, 0), Color.green); //Debug.Log ("N Trafilem w: " + hit.transform.GetComponent<ChunkData>().m_pos); lastPosNE = hit.transform.GetComponent<ChunkData>().m_pos; PerlinNoise m_surfacePerlin = new PerlinNoise(m_surfaceSeed); Vector3 offset = new Vector3(m_chunksX*m_voxelWidth*0.5f, -(m_chunksY-m_chunksAbove0)*m_voxelHeight, m_chunksZ*m_voxelLength*0.5f); // Vector3 pos = lastPosN + new Vector3(108, 0, 0); m_voxelChunktemp = new VoxelChunk[1, 2, 1]; for(int x = 0; x<1; x++) { for (int y = 0; y<2; y++) { for(int z = 0; z< 1; z++) { Vector3 pos = new Vector3((x+lastPosNE.x)*m_voxelWidth/32, y*m_voxelHeight, (z+lastPosNE.z)*m_voxelLength); //Debug.Log ("POS: " + (pos + offset) + " / " + (lastPosNE + pos) + " / " + lastPosN); m_voxelChunktemp[x, y, z] = new VoxelChunk(lastPosNE + pos, m_voxelWidth, m_voxelHeight, m_voxelLength, m_surfaceLevel); m_voxelChunktemp[x, y, z].CreateVoxels (m_surfacePerlin); m_voxelChunktemp[x, y, z].CreateMesh (m_material); } } } //Debug.DrawLine(player.position + player.forward * 32 * m_voxelWidth, -Vector3.up * 128, Color.red); m_chunksX++; } } /* * ------- * |x| | | * ------- * | | | | * ------- * | | | | * ------- */ if(Physics.Raycast (player.position + player.forward * 32 * m_voxelWidth - player.right * 128, -Vector3.up, out hit)) { //Debug.Log ("NW Trafilem w: " + hit.transform.name); } else { //Debug.Log ("Pudlo NW"); } }
public VoxelChunk GetOrCreateChunkFromWorldPosition(int worldX, int worldY, int worldZ) { VoxelChunk.ConvertWorldToChunk(ref worldX, ref worldY, ref worldZ); return(GetOrCreateChunk(worldX, worldY, worldZ)); }
void Start() { Stopwatch stopWatch = new Stopwatch(); stopWatch.Reset(); stopWatch.Start(); for (int i = 0; i < loadSize; i++) { for (int ii = 0; ii < loadSize; ii++) { for (int iii = 0; iii < loadHeight; iii++) { VoxelChunk c = Instantiate <VoxelChunk>(Chunk); c.LoadChunk(-loadSize / 2 + i, -loadSize / 2 + ii, -loadHeight / 2 + iii); chunks[i, ii, iii] = c; } } } for (int i = 0; i < loadSize; i++) { for (int ii = 0; ii < loadSize; ii++) { for (int iii = 0; iii < loadHeight; iii++) { VoxelChunk[,,] chunkers = new VoxelChunk[3, 3, 3]; for (int ier = 0; ier < 3; ier++) { for (int iier = 0; iier < 3; iier++) { for (int iiier = 0; iiier < 3; iiier++) { int o = i - 1 + ier < 0 ? loadSize - 1 : i - 1 + ier >= loadSize ? 0 : i - 1 + ier; int oo = ii - 1 + iier < 0 ? loadSize - 1 : ii - 1 + iier >= loadSize ? 0 : ii - 1 + iier; int ooo = iii - 1 + iiier < 0 ? loadHeight - 1 : iii - 1 + iiier >= loadHeight ? 0 : iii - 1 + iiier; chunkers[ier, iier, iiier] = chunks[o, oo, ooo]; } } } chunks[i, ii, iii].loadChunks(chunkers); } } } stopWatch.Stop(); UnityEngine.Debug.Log(stopWatch.ElapsedMilliseconds); /*stopWatch.Reset(); * stopWatch.Start(); * for (int i = 1; i < loadSize-1; i++) * { * for (int ii = 1; ii < loadSize-1; ii++) * { * for (int iii = 1; iii < loadHeight - 1; iii++) * { * VoxelChunk[,,] chunkers = new VoxelChunk[3, 3, 3]; * for (int ier = 0; ier < 3; ier++) * { * for (int iier = 0; iier < 3; iier++) * { * for (int iiier = 0; iiier < 3; iiier++) * { * chunkers[ier, iier, iiier] = chunks[i - 1 + ier, ii - 1 + iier, iii - 1 + iiier]; * } * } * } * chunks[i, ii, iii].loadChunks(chunkers); * chunks[i, ii, iii].Load(); * } * } * } * stopWatch.Stop(); * UnityEngine.Debug.Log(stopWatch.ElapsedMilliseconds); * stopWatch.Reset(); * stopWatch.Start(); * for (int i = 2; i < loadSize - 2; i++) * { * for (int ii = 2; ii < loadSize - 2; ii++) * { * for (int iii = 2; iii < loadHeight - 2; iii++) * { * chunks[i, ii, iii].Smooth(); * } * } * } * stopWatch.Stop(); * UnityEngine.Debug.Log(stopWatch.ElapsedMilliseconds);*/ if (VoxelChunk.numThreads < VoxelChunk.maxNumThreads()) { if (thread == null) { thread = new Thread(VoxelChunk.Run); pos = player.pos; VoxelChunk.numThreads++; VoxelChunk.RunLoadGraphics(); thread.Start(); } else if (VoxelChunk.Done) { VoxelChunk.Done = false; thread = new Thread(VoxelChunk.Run); pos = player.pos; VoxelChunk.RunLoadGraphics(); VoxelChunk.numThreads++; thread.Start(); } } }
bool OnQueryExecute(VoxelChunk chunk, int voxelX, int voxelY, int voxelZ) { List<VoxelPosition> voxelPositions; if (!queryResults.TryGetValue (chunk, out voxelPositions)) { voxelPositions = new List<VoxelPosition> (); queryResults.Add (chunk, voxelPositions); } voxelPositions.Add (new VoxelPosition (voxelX, voxelY, voxelZ)); return true; }
bool PaintChunkA(VoxelChunk chunk) { if (chunk.position.y + 8 < minHeight) { chunk.isAboveSurface = false; return(false); } int chunkBottomPos = FastMath.FloorToInt(chunk.position.y - 8); int chunkTopPos = FastMath.FloorToInt(chunk.position.y + 8); bool isAboveSurface = false; bool atleastOneVoxel = false; Voxel[] voxels = chunk.voxels; VoxelDefinition voxDef = topVoxel; Vector3 pos; Vector3 position = chunk.position - new Vector3(8, 8, 8); int z, x, y; for (z = 0; z < 16; z++) { pos.z = position.z + z; for (x = 0; x < 16; x++) { pos.x = position.x + x; var heightMapInfo = env.GetHeightMapInfoFast(pos.x, pos.z); int surfaceLevel = heightMapInfo.groundLevel; int groundLevel = heightMapInfo.groundLevel; int waterLevel = env.waterLevel > 0 ? env.waterLevel : -1; BiomeDefinition biome = heightMapInfo.biome; if (biome == null) { continue; } if (chunkTopPos > surfaceLevel) { isAboveSurface = true; } int localY = (int)(surfaceLevel - chunkBottomPos); if (localY > 15) { localY = 15; } int index = z * ONE_Z_ROW + x; for (y = 0; y <= localY; y++) { pos.y = position.y + y; if ((int)pos.y == groundLevel) { voxDef = biome.voxelTop; } else { voxDef = biome.voxelDirt; } voxels[index].SetFast(voxDef, 15, 1, Misc.color32White); atleastOneVoxel = true; //Check if we should add trees or vegetation if ((int)pos.y == groundLevel) { if (pos.y > waterLevel) { float rn = WorldRand.GetValue(pos); if (env.enableTrees && biome.treeDensity > 0 && rn < biome.treeDensity && biome.trees.Length > 0) { // request a tree env.RequestTreeCreation( chunk, pos, env.GetTree(biome.trees, rn / biome.treeDensity)); } else if (env.enableVegetation && biome.vegetationDensity > 0 && rn < biome.vegetationDensity && biome.vegetation.Length > 0) { if (index >= 15 * ONE_Y_ROW) { // we're at the top layer for this chunk // place a request for vegetation for the chunk above us env.RequestVegetationCreation(chunk.top, index - ONE_Y_ROW * 15, env.GetVegetation(biome, rn / biome.vegetationDensity)); } else { // set a vegetation voxel voxels[index + ONE_Y_ROW].Set(env.GetVegetation(biome, rn / biome.vegetationDensity), Misc.color32White); } } } } index += ONE_Y_ROW; } } } chunk.isAboveSurface = isAboveSurface; return(atleastOneVoxel); }
public InstancedChunk(VoxelChunk chunk) { this.chunk = chunk; instancedVoxels = new FastList <InstancedVoxel>(); }
public static void GenerateRuin(VoxelChunk Chunk, ChunkGeneratorSettings Settings) { // Todo: Support ruins deep underground - empty out their interiors. LoadRuinTemplates(); var noiseVector = Chunk.Origin.ToVector3() * Settings.CaveNoiseScale; var ruinsNoise = Settings.CaveNoise.GetValue(noiseVector.X, noiseVector.Y, noiseVector.Z); if (Math.Abs(ruinsNoise) > GameSettings.Current.GenerationRuinsRate) { return; } var avgHeight = GetAverageHeight(Chunk.Origin.X, Chunk.Origin.Z, 16, 16, Settings); var ruinWallType = Library.GetVoxelType("Cobble"); // Todo: Should make this data so this doesn't break if tile names change? var ruinFloorType = Library.GetVoxelType("Blue Tile"); if (Settings.Overworld.Map.GetBiomeAt(Chunk.Origin.ToVector3(), Settings.Overworld.InstanceSettings.Origin).HasValue(out var biome)) { ruinWallType = Library.GetVoxelType(biome.RuinWallType); ruinFloorType = Library.GetVoxelType(biome.RuinFloorType); } if (!ruinWallType.HasValue() || !ruinFloorType.HasValue()) { return; } int wallHeight = MathFunctions.RandInt(2, 6); var template = RuinTemplates[MathFunctions.RandInt(0, RuinTemplates.Count)]; var rotations = MathFunctions.RandInt(0, 3); for (var i = 0; i < rotations; ++i) { template = TextureTool.RotatedCopy(template); } for (int dx = 0; dx < 16; dx++) { for (int dz = 0; dz < 16; dz++) { var worldPos = new Vector3(Chunk.Origin.X + dx, avgHeight, Chunk.Origin.Z + dz); var baseVoxel = Settings.World.ChunkManager.CreateVoxelHandle(GlobalVoxelCoordinate.FromVector3(worldPos)); var underVoxel = VoxelHelpers.FindFirstVoxelBelow(Settings.World.ChunkManager.CreateVoxelHandle(GlobalVoxelCoordinate.FromVector3(worldPos))); var decay = Settings.NoiseGenerator.Generate(worldPos.X * 0.05f, worldPos.Y * 0.05f, worldPos.Z * 0.05f); if (decay > 0.7f) { continue; } if (!baseVoxel.IsValid) { continue; } if (baseVoxel.Coordinate.Y == (Settings.WorldSizeInChunks.Y * VoxelConstants.ChunkSizeY) - 1) { continue; } if (!underVoxel.IsValid) { continue; } var templateColor = template.Data[template.Index(dx, dz)]; if (templateColor == new Color(0, 0, 255, 255)) // Border { continue; } else if (templateColor == new Color(0, 0, 0, 255)) // Space { continue; } else if (templateColor == new Color(255, 0, 0, 255)) // Wall { baseVoxel.RawSetType(ruinWallType); FillBelowRuins(Settings, ruinWallType, baseVoxel, underVoxel); FillRuinColumn(Settings, ruinWallType, 1, wallHeight, baseVoxel, decay); } else if (templateColor == new Color(128, 128, 0, 255)) // Door { baseVoxel.RawSetType(ruinWallType); FillBelowRuins(Settings, ruinWallType, baseVoxel, underVoxel); FillRuinColumn(Settings, ruinWallType, 3, wallHeight, baseVoxel, decay); } else if (templateColor == new Color(128, 0, 0, 255)) // Floor { FillBelowRuins(Settings, ruinWallType, baseVoxel, underVoxel); baseVoxel.RawSetType(ruinFloorType); } } } }
public VMap(uint size, VoxelChunk chunk) { this.chunk = chunk; this.size = size; map = new Color[size, size, size]; }
public VertexArray Voxelize(VoxelCollection collection, VoxelChunk chunk) { List <float> verts = new List <float>(); return(null); }
public static void GenerateSurfaceLife(VoxelChunk TopChunk, ChunkGeneratorSettings Settings) { var creatureCounts = new Dictionary <string, Dictionary <string, int> >(); var worldDepth = Settings.WorldSizeInChunks.Y * VoxelConstants.ChunkSizeY; for (var x = TopChunk.Origin.X; x < TopChunk.Origin.X + VoxelConstants.ChunkSizeX; x++) { for (var z = TopChunk.Origin.Z; z < TopChunk.Origin.Z + VoxelConstants.ChunkSizeZ; z++) { var overworldPosition = OverworldMap.WorldToOverworld(new Vector2(x, z), Settings.Overworld.InstanceSettings.Origin); if (Settings.Overworld.Map.GetBiomeAt(new Vector3(x, 0, z), Settings.Overworld.InstanceSettings.Origin).HasValue(out var biome)) { var normalizedHeight = NormalizeHeight(Settings.Overworld.Map.LinearInterpolate(overworldPosition, OverworldField.Height)); var height = (int)MathFunctions.Clamp(normalizedHeight * worldDepth, 0.0f, worldDepth - 2); var voxel = Settings.World.ChunkManager.CreateVoxelHandle(new GlobalVoxelCoordinate(x, height, z)); if (!voxel.IsValid || voxel.Coordinate.Y == 0 || voxel.Coordinate.Y >= worldDepth - Settings.TreeLine) { continue; } if (voxel.LiquidLevel != 0) { continue; } var above = VoxelHelpers.GetVoxelAbove(voxel); if (above.IsValid && (above.LiquidLevel != 0 || !above.IsEmpty)) { continue; } foreach (var animal in biome.Fauna) { if (MathFunctions.RandEvent(animal.SpawnProbability)) { if (!creatureCounts.ContainsKey(biome.Name)) { creatureCounts[biome.Name] = new Dictionary <string, int>(); } var dict = creatureCounts[biome.Name]; if (!dict.ContainsKey(animal.Name)) { dict[animal.Name] = 0; } if (dict[animal.Name] < animal.MaxPopulation) { EntityFactory.CreateEntity <GameComponent>(animal.Name, voxel.WorldPosition + Vector3.Up * 1.5f); } break; } } if (voxel.Type.Name != biome.SoilLayer.VoxelType) { continue; } foreach (VegetationData veg in biome.Vegetation) { if (voxel.GrassType == 0) { continue; } if (MathFunctions.RandEvent(veg.SpawnProbability) && Settings.NoiseGenerator.Noise(voxel.Coordinate.X / veg.ClumpSize, veg.NoiseOffset, voxel.Coordinate.Z / veg.ClumpSize) >= veg.ClumpThreshold) { var treeSize = MathFunctions.Rand() * veg.SizeVariance + veg.MeanSize; var blackboard = new Blackboard(); blackboard.SetData("Scale", treeSize); EntityFactory.CreateEntity <Plant>(veg.Name, voxel.WorldPosition + new Vector3(0.5f, 1.0f, 0.5f), blackboard); break; } } } } } }
public static void QueueDirtyChunk(VoxelChunk c) { dirtyChuncks.Enqueue(c); }
public static void GenerateCaves(VoxelChunk Chunk, ChunkGeneratorSettings Settings) { if (Library.GetBiome("Cave").HasValue(out BiomeData caveBiome) && Library.GetBiome("Hell").HasValue(out BiomeData hellBiome)) { for (int x = 0; x < VoxelConstants.ChunkSizeX; x++) { for (int z = 0; z < VoxelConstants.ChunkSizeZ; z++) { for (int i = 0; i < Settings.CaveLevels.Count; i++) { // Does layer intersect this voxel? int y = Settings.CaveLevels[i]; if (y + Settings.MaxCaveHeight < Chunk.Origin.Y) { continue; } if (y >= Chunk.Origin.Y + VoxelConstants.ChunkSizeY) { continue; } var coordinate = new GlobalVoxelCoordinate(Chunk.Origin.X + x, y, Chunk.Origin.Z + z); var data = GetCaveGenerationData(coordinate, i, Settings); var biome = (y <= Settings.HellLevel) ? hellBiome : caveBiome; if (!data.CaveHere) { continue; } for (int dy = 0; dy < data.Height; dy++) { var globalY = y + dy; // Prevent caves punching holes in bedrock. if (globalY <= 0) { continue; } // Check if voxel is inside chunk. if (globalY <= 0 || globalY < Chunk.Origin.Y || globalY >= Chunk.Origin.Y + VoxelConstants.ChunkSizeY) { continue; } var voxel = VoxelHandle.UnsafeCreateLocalHandle(Chunk, new LocalVoxelCoordinate(x, globalY - Chunk.Origin.Y, z)); // Prevent caves from breaking surface. bool caveBreaksSurface = false; foreach (var neighborCoordinate in VoxelHelpers.EnumerateAllNeighbors(voxel.Coordinate)) { var v = Chunk.Manager.CreateVoxelHandle(neighborCoordinate); if (!v.IsValid || (v.Sunlight)) { caveBreaksSurface = true; break; } } if (caveBreaksSurface) { break; } voxel.RawSetType(Library.EmptyVoxelType); if (dy == 0) { // Place soil voxel and grass below cave. var below = VoxelHelpers.GetVoxelBelow(voxel); if (below.IsValid) { below.RawSetType(Library.GetVoxelType(biome.SoilLayer.VoxelType)); var grassType = Library.GetGrassType(biome.GrassDecal); if (grassType != null) { below.RawSetGrass(grassType.ID); } } // Spawn flora and fauna. if (data.Noise > Settings.CaveSize * 1.8f && globalY > Settings.LavaLevel) { GenerateCaveFlora(below, biome, Settings); GenerateCaveFauna(below, biome, Settings); } } } } } } } }
IEnumerator lV(Vector3 pos) { MarchingCubes.SetTarget(0.0f); MarchingCubes.SetWindingOrder(2, 1, 0); MarchingCubes.SetModeToCubes(); m_surfacePerlin = new PerlinNoise(save.m_surfaceSeed); m_voronoi = new VoronoiNoise(save.m_surfaceSeed); m_voxelChunk = new VoxelChunk(pos, m_Width, m_Height, m_Length, surfaceLevel); m_voxelChunk.bDodane = true; m_voxelChunk.CreateVoxels(m_surfacePerlin, m_voronoi);//, m_cavePerlin); m_voxelChunk.CreateMesh (GameObject.Find ("TerrainGenerator").GetComponent<GenerateTerrain>().m_material); yield return new WaitForFixedUpdate(); }
bool _PaintChunk(VoxelChunk chunk) { // // We already determined the height. // Here we need to fill in any voxels that should exists below the height, in this chunk. // You'll use the height, to know how high up to go before you've hit air. // Or, if the entire chunk is below the surface, you'll just fill the whole thing // // // You'll use these variables in a moment // /* * int startX = FastMath.FloorToInt(chunk.position.x - 8); * int startZ = FastMath.FloorToInt(chunk.position.z - 8); * * int chunkBottomPos = FastMath.FloorToInt(chunk.position.y - 8); * int chunkTopPos = FastMath.FloorToInt(chunk.position.y + 8); */ // TODO: if chunkTopPos < minHeight // set chunk.isAboveSurface to false // and return false (no point in proceeding further) // TODO: make a bool isAboveSurface. set it to false to begin with. // You can uncomment the following line. Most of the rest of the variables won't be // written for you however. // bool isAboveSurface = false; // make a bool atleastOneVoxel. also false to begin with // Make a reference to the array of voxels in the chunk: // Voxel[] voxels = chunk.voxels; // or just uncomment this line // TODO: write two nested for-loops. // The outer one should be: /* * for(int z = 0; z < 16; ++z) * { * // stuff goes here * } */ // The next one should be int x = 0 , x < 16 // Write a very similar for loop inside of the z for loop // except use x instead of z // (or the outer one could be x and the next one z, the order doesn't matter here) // VoxelFun chunks are size 16*16*16, by the way // BIG TODO (don't get too scared; a lot of this is long-winded explanation): // Inside the x for-loop // declare a var heightMapInfo = env.GetHeightMapInfoFast(startX + x, startZ + z); // ('var' in C# means "computer, please infer the correct type for me. I don't feel like typing it out myself") // make an int surfaceLevel = heightMapInfo.groundLevel // // if chunkTopPos is above surfaceLevel // set isAboveSurface to true // // declare an int localY equal to surfaceLevel minus chunkBottomPos // if localY is greater than 16, set it to 16 // // Note: if the bottom of this chunk is above the surface, localY will be negative and we want that // // Iterate over the y column. // for y = 0 ... y < localY ... y++ // // // find the correct array index in the 'voxels' array based on which x, y, z we're at. // (EXPLANATION: take a second to ponder the situation: the 'voxels' array is a '1D' array. // you get items from it with one number not three: voxels[ SOME_NUMBER ]. // we have to find the right way to map x, y, and z to a number. // The people who made voxel play decided to order the indices such that: // x is least significant. each x counts for 1 // z is next. each z counts for a column. so each z counts for 16 // y is most significant. each y counts for an 'xz' layer. so each y counts for 16 * 16) // // // So, find the correct index: // Make an int index equal to y times ONE_Y_ROW plus z times ONE_Z_ROW plus x // (ONE_Y_ROW = 16*16, ONE_Z_ROW = 16. you may as well use these constants instead of writing out the numbers) // // Finally...set the voxel to grass // use // voxels[index].SetFast(topVoxel, 15, 1, Misc.color32White); // also...we now know that this chunk has at least one voxel: // atleastOneVoxel = true; // set to true // // After the end of all three for-loops // chunk.isAboveSurface = isAboveSurface; // return atleastOneVoxel; return(true); }
public bool IsGridChuck(VoxelChunk chunk) { return(chunk.position.y == 8); }
public Job_BuildLiquidMesh(VoxelChunk Chunk, Mesh Target) : base(Chunk) { mTarget = Target; }
private void WriteChunk(ref Vector3I coords, VoxelChunk chunk) { // We assume that we are locked here. Debug.Assert(m_storageLock.Owned); var start = coords << VoxelChunk.SizeBits; var end = ((coords + 1) << VoxelChunk.SizeBits) - 1; MyStorageData storage = chunk.MakeData(); WriteRangeInternal(storage, chunk.Dirty, ref start, ref end); chunk.Dirty = 0; }
public InstancedChunk(VoxelChunk chunk, BatchedCell cell) { this.chunk = chunk; this.batchedCell = cell; instancedVoxels = new FastList <InstancedVoxel>(); }
private void ReadDatForChunk(VoxelChunk chunk, MyStorageDataTypeFlags data) { var rangeStart = chunk.Coords << VoxelChunk.SizeBits; var rangeEnd = ((chunk.Coords + 1) << VoxelChunk.SizeBits) - 1; MyStorageData storage = chunk.MakeData(); MyVoxelRequestFlags flags = 0; ReadRangeInternal(storage, ref Vector3I.Zero, data, 0, ref rangeStart, ref rangeEnd, ref flags); chunk.Cached |= data; chunk.MaxLod = 0; }
public static VoxelChunk GenerateChunk(GlobalChunkCoordinate ID, ChunkGeneratorSettings Settings) { var origin = new GlobalVoxelCoordinate(ID, new LocalVoxelCoordinate(0, 0, 0)); var worldDepth = Settings.WorldSizeInChunks.Y * VoxelConstants.ChunkSizeY; var waterHeight = NormalizeHeight(Settings.Overworld.GenerationSettings.SeaLevel + 1.0f / worldDepth); var c = new VoxelChunk(Settings.World.ChunkManager, ID); if (GameSettings.Current.NoStone) { return(c); } for (int x = 0; x < VoxelConstants.ChunkSizeX; x++) { for (int z = 0; z < VoxelConstants.ChunkSizeZ; z++) { var overworldPosition = OverworldMap.WorldToOverworld(new Vector2(x + origin.X, z + origin.Z), Settings.Overworld.InstanceSettings.Origin); if (Settings.Overworld.Map.GetBiomeAt(new Vector3(x + origin.X, 0, z + origin.Z), Settings.Overworld.InstanceSettings.Origin).HasValue(out var biomeData)) { var normalizedHeight = NormalizeHeight(Settings.Overworld.Map.LinearInterpolate(overworldPosition, OverworldField.Height)); var height = MathFunctions.Clamp(normalizedHeight * worldDepth, 0.0f, worldDepth - 2); var stoneHeight = (int)MathFunctions.Clamp((int)(height - (biomeData.SoilLayer.Depth + (Math.Sin(overworldPosition.X) + Math.Cos(overworldPosition.Y)))), 1, height); for (int y = 0; y < VoxelConstants.ChunkSizeY; y++) { var globalY = origin.Y + y; var voxel = VoxelHandle.UnsafeCreateLocalHandle(c, new LocalVoxelCoordinate(x, y, z)); if (globalY == 0) { voxel.RawSetType(Library.GetVoxelType("Bedrock")); continue; } // Below the stone line, use subsurface layers. if (globalY <= stoneHeight && stoneHeight > 1) { var depth = stoneHeight - globalY - biomeData.SubsurfaceLayers[0].Depth + 1; var subsurfaceLayer = 0; while (depth > 0 && subsurfaceLayer < biomeData.SubsurfaceLayers.Count - 1) { depth -= biomeData.SubsurfaceLayers[subsurfaceLayer].Depth; subsurfaceLayer += 1; } voxel.RawSetType(Library.GetVoxelType(biomeData.SubsurfaceLayers[subsurfaceLayer].VoxelType)); } // Otherwise, on the surface. else if ((globalY == (int)height || globalY == stoneHeight) && normalizedHeight > waterHeight) { voxel.RawSetType(Library.GetVoxelType(biomeData.SoilLayer.VoxelType)); if (!String.IsNullOrEmpty(biomeData.GrassDecal)) { if (!biomeData.ClumpGrass || (biomeData.ClumpGrass && Settings.NoiseGenerator.Noise(overworldPosition.X / biomeData.ClumpSize, 0, overworldPosition.Y / biomeData.ClumpSize) > biomeData.ClumpTreshold)) { voxel.RawSetGrass(Library.GetGrassType(biomeData.GrassDecal).ID); } } } else if (globalY > height && globalY > 0) { voxel.RawSetType(Library.EmptyVoxelType); } else if (normalizedHeight <= waterHeight) { voxel.RawSetType(Library.GetVoxelType(biomeData.ShoreVoxel)); } else { voxel.RawSetType(Library.GetVoxelType(biomeData.SoilLayer.VoxelType)); } } } } } return(c); }
/// <summary> /// Generates a random set of dwarves in the given chunk. /// </summary> /// <param name="numDwarves">Number of dwarves to generate</param> /// <param name="c">The chunk the dwarves belong to</param> public void CreateInitialDwarves(VoxelChunk c) { int numWorkers = 3; int numAxes = 1; int numCrafters = 1; Vector3 g = c.WorldToGrid(Camera.Position); // Find the height of the world at the camera float h = c.GetFilledVoxelGridHeightAt((int) g.X, ChunkHeight - 1, (int) g.Z); // This is done just to make sure the camera is in the correct place. Camera.UpdateBasisVectors(); Camera.UpdateProjectionMatrix(); Camera.UpdateViewMatrix(); // Spawn the dwarves above the terrain for (int i = 0; i < numWorkers; i++) { Vector3 dorfPos = new Vector3(Camera.Position.X + (float) Random.NextDouble(), h + 10, Camera.Position.Z + (float) Random.NextDouble()); Physics creat = (Physics) EntityFactory.GenerateDwarf(dorfPos, ComponentManager, Content, GraphicsDevice, ChunkManager, Camera, ComponentManager.Factions.Factions["Player"], PlanService, "Player", JobLibrary.Classes[JobLibrary.JobType.Worker], 0); creat.Velocity = new Vector3(1, 0, 0); } for (int i = 0; i < numAxes; i++) { Vector3 dorfPos = new Vector3(Camera.Position.X + (float)Random.NextDouble(), h + 10, Camera.Position.Z + (float)Random.NextDouble()); Physics creat = (Physics)EntityFactory.GenerateDwarf(dorfPos, ComponentManager, Content, GraphicsDevice, ChunkManager, Camera, ComponentManager.Factions.Factions["Player"], PlanService, "Player", JobLibrary.Classes[JobLibrary.JobType.AxeDwarf], 0); creat.Velocity = new Vector3(1, 0, 0); } for (int i = 0; i < numCrafters; i++) { Vector3 dorfPos = new Vector3(Camera.Position.X + (float)Random.NextDouble(), h + 10, Camera.Position.Z + (float)Random.NextDouble()); Physics creat = (Physics)EntityFactory.GenerateDwarf(dorfPos, ComponentManager, Content, GraphicsDevice, ChunkManager, Camera, ComponentManager.Factions.Factions["Player"], PlanService, "Player", JobLibrary.Classes[JobLibrary.JobType.CraftsDwarf], 0); creat.Velocity = new Vector3(1, 0, 0); } // Turn the camera to face the dwarves Camera.Target = new Vector3(Camera.Position.X, h + 10, Camera.Position.Z + 10); Camera.Phi = -(float) Math.PI * 0.3f; }
IEnumerator test2() { PerlinNoise m_surfacePerlin = new PerlinNoise(terrain.m_surfaceSeed); VoronoiNoise m_voronoi = new VoronoiNoise(terrain.m_surfaceSeed); //List<ChunkData> chunks2 = new List<ChunkData>(); foreach(ChunkData chunk in chunks.ToArray ()) { for(int i = 0; i <= uncoverArea; i++) { //N if(!GameObject.Find ("Voxel Mesh " + (chunk.m_pos.x+(i*8)).ToString() + " " + (chunk.m_pos.y).ToString() + " " + (chunk.m_pos.z).ToString())) { // PerlinNoise m_surfacePerlin = new PerlinNoise(terrain.m_surfaceSeed); // VoronoiNoise m_voronoi = new VoronoiNoise(terrain.m_surfaceSeed); Vector3 pos = new Vector3(chunk.m_pos.x+8*i+1, chunk.m_pos.y+1, chunk.m_pos.z+1); m_voxelChunktemp = new VoxelChunk(pos, terrain.m_voxelWidth, terrain.m_voxelHeight, terrain.m_voxelLength, terrain.m_surfaceLevel); m_voxelChunktemp.CreateVoxels (m_surfacePerlin, m_voronoi); m_voxelChunktemp.CreateMesh (terrain.m_material); // yield return new WaitForSeconds(.1f); //chunk.bOnce = true; } //NW if(!GameObject.Find ("Voxel Mesh " + (chunk.m_pos.x+8*i).ToString() + " " + (chunk.m_pos.y).ToString() + " " + (chunk.m_pos.z + 8*i).ToString())) { // PerlinNoise m_surfacePerlin = new PerlinNoise(terrain.m_surfaceSeed); // VoronoiNoise m_voronoi = new VoronoiNoise(terrain.m_surfaceSeed); Vector3 pos = new Vector3(chunk.m_pos.x+8*i+1, chunk.m_pos.y+1, chunk.m_pos.z+8*i+1); m_voxelChunktemp = new VoxelChunk(pos, terrain.m_voxelWidth, terrain.m_voxelHeight, terrain.m_voxelLength, terrain.m_surfaceLevel); m_voxelChunktemp.CreateVoxels (m_surfacePerlin, m_voronoi); m_voxelChunktemp.CreateMesh (terrain.m_material); // yield return new WaitForSeconds(.1f); //chunk.bOnce = true; } //NE if(!GameObject.Find ("Voxel Mesh " + (chunk.m_pos.x+8*i).ToString() + " " + (chunk.m_pos.y).ToString() + " " + (chunk.m_pos.z - 8*i).ToString())) { // PerlinNoise m_surfacePerlin = new PerlinNoise(terrain.m_surfaceSeed); // VoronoiNoise m_voronoi = new VoronoiNoise(terrain.m_surfaceSeed); Vector3 pos = new Vector3(chunk.m_pos.x+8*i+1, chunk.m_pos.y+1, chunk.m_pos.z-8*i+1); m_voxelChunktemp = new VoxelChunk(pos, terrain.m_voxelWidth, terrain.m_voxelHeight, terrain.m_voxelLength, terrain.m_surfaceLevel); m_voxelChunktemp.CreateVoxels (m_surfacePerlin, m_voronoi); m_voxelChunktemp.CreateMesh (terrain.m_material); // yield return new WaitForSeconds(.1f); //chunk.bOnce = true; } //S if(!GameObject.Find ("Voxel Mesh " + (chunk.m_pos.x-8*i).ToString() + " " + (chunk.m_pos.y).ToString() + " " + (chunk.m_pos.z).ToString())) { // PerlinNoise m_surfacePerlin = new PerlinNoise(terrain.m_surfaceSeed); // VoronoiNoise m_voronoi = new VoronoiNoise(terrain.m_surfaceSeed); Vector3 pos = new Vector3(chunk.m_pos.x-8*i+1, chunk.m_pos.y+1, chunk.m_pos.z+1); m_voxelChunktemp = new VoxelChunk(pos, terrain.m_voxelWidth, terrain.m_voxelHeight, terrain.m_voxelLength, terrain.m_surfaceLevel); m_voxelChunktemp.CreateVoxels (m_surfacePerlin, m_voronoi); m_voxelChunktemp.CreateMesh (terrain.m_material); // yield return new WaitForSeconds(.1f); //chunk.bOnce = true; } //SW if(!GameObject.Find ("Voxel Mesh " + (chunk.m_pos.x-8*i).ToString() + " " + (chunk.m_pos.y).ToString() + " " + (chunk.m_pos.z + 8*i).ToString())) { // PerlinNoise m_surfacePerlin = new PerlinNoise(terrain.m_surfaceSeed); // VoronoiNoise m_voronoi = new VoronoiNoise(terrain.m_surfaceSeed); Vector3 pos = new Vector3(chunk.m_pos.x-8*i+1, chunk.m_pos.y+1, chunk.m_pos.z+8*i+1); m_voxelChunktemp = new VoxelChunk(pos, terrain.m_voxelWidth, terrain.m_voxelHeight, terrain.m_voxelLength, terrain.m_surfaceLevel); m_voxelChunktemp.CreateVoxels (m_surfacePerlin, m_voronoi); m_voxelChunktemp.CreateMesh (terrain.m_material); // yield return new WaitForSeconds(.1f); //chunk.bOnce = true; } //SE if(!GameObject.Find ("Voxel Mesh " + (chunk.m_pos.x-8*i).ToString() + " " + (chunk.m_pos.y).ToString() + " " + (chunk.m_pos.z - 8*i).ToString())) { // PerlinNoise m_surfacePerlin = new PerlinNoise(terrain.m_surfaceSeed); // VoronoiNoise m_voronoi = new VoronoiNoise(terrain.m_surfaceSeed); Vector3 pos = new Vector3(chunk.m_pos.x-8*i+1, chunk.m_pos.y+1, chunk.m_pos.z-8*i+1); m_voxelChunktemp = new VoxelChunk(pos, terrain.m_voxelWidth, terrain.m_voxelHeight, terrain.m_voxelLength, terrain.m_surfaceLevel); m_voxelChunktemp.CreateVoxels (m_surfacePerlin, m_voronoi); m_voxelChunktemp.CreateMesh (terrain.m_material); // yield return new WaitForSeconds(.1f); //chunk.bOnce = true; } //W if(!GameObject.Find ("Voxel Mesh " + (chunk.m_pos.x).ToString() + " " + (chunk.m_pos.y).ToString() + " " + (chunk.m_pos.z + 8*i).ToString())) { // PerlinNoise m_surfacePerlin = new PerlinNoise(terrain.m_surfaceSeed); // VoronoiNoise m_voronoi = new VoronoiNoise(terrain.m_surfaceSeed); Vector3 pos = new Vector3(chunk.m_pos.x+1, chunk.m_pos.y+1, chunk.m_pos.z+8*i+1); m_voxelChunktemp = new VoxelChunk(pos, terrain.m_voxelWidth, terrain.m_voxelHeight, terrain.m_voxelLength, terrain.m_surfaceLevel); m_voxelChunktemp.CreateVoxels (m_surfacePerlin, m_voronoi); m_voxelChunktemp.CreateMesh (terrain.m_material); // yield return new WaitForSeconds(.1f); //chunk.bOnce = true; } //E if(!GameObject.Find ("Voxel Mesh " + (chunk.m_pos.x).ToString() + " " + (chunk.m_pos.y).ToString() + " " + (chunk.m_pos.z - 8*i).ToString())) { // PerlinNoise m_surfacePerlin = new PerlinNoise(terrain.m_surfaceSeed); // VoronoiNoise m_voronoi = new VoronoiNoise(terrain.m_surfaceSeed); Vector3 pos = new Vector3(chunk.m_pos.x+1, chunk.m_pos.y+1, chunk.m_pos.z-8*i+1); m_voxelChunktemp = new VoxelChunk(pos, terrain.m_voxelWidth, terrain.m_voxelHeight, terrain.m_voxelLength, terrain.m_surfaceLevel); m_voxelChunktemp.CreateVoxels (m_surfacePerlin, m_voronoi); m_voxelChunktemp.CreateMesh (terrain.m_material); // yield return new WaitForSeconds(.1f); //chunk.bOnce = true; } yield return new WaitForSeconds(0.001f); } chunk.bUsed = true; //chunks2.Add (chunk); chunks.Remove (chunk); yield return new WaitForSeconds(0.001f); } //chunks = chunks.Except (chunks2).ToList (); //chunks2.Clear (); //yield return new WaitForSeconds(.2f); }