private void GenerateTerrain(int seed) { if (terrainManager != null) if (terrainManager.cellsInitialized > 0 && (terrainManager.cellsInitialized < terrainManager.terrainCells.Length)) return; // currently generating terrain terrainManager = new TerrainManager((int)terrainRes, (int)cellRes); terrainManager.InitializeCells(); terrainManager.Initialized = false; terrainManager.cellsInitialized = 0; //set texture scale for shader if (terrainDrawContext != null) SetTextureScale(); object terrainLock = new object(); terrainGenerationTimer = new Stopwatch(); terrainGenerationTimer.Start(); vertexCount = 0; // generate terrain Thread terrainProcessing = new Thread(delegate() { terrainManager.ForEachCell((pos, cell) => { // do each cell in its own thread Thread t = new Thread(delegate() { // generate perlin 3d noise Vector3 noiseOffset = pos; noiseOffset.Y *= -1; cell.PerlinNoise(noiseOffset * cellRes, terrainNoiseDensity, seed); // generate mesh for the cell TerrainCellMesh mesh = new TerrainCellMesh(terrainManager.GetCell(pos), pos); mesh.Calculate(cubicTerrain, GraphicsDevice); if (mesh == null) { throw new Exception("Problem generating mesh from volume!"); } terrainManager.terrainCellMeshes[(int)pos.X, (int)pos.Y, (int)pos.Z] = mesh; /* terrainManager.terrainCells[(int)pos.X, (int)pos.Y, (int)pos.Z].ForEach(voxelPos => terrainManager.terrainCells[(int)pos.X, (int)pos.Y, (int)pos.Z].setDensityAt(voxelPos, 255)); //terrainManager.terrainCells[(int)pos.X, (int)pos.Y, (int)pos.Z].CreateSphere(19, 255); terrainManager.terrainCellMeshes[(int)pos.X, (int)pos.Y, (int)pos.Z] = new TerrainCellMesh(terrainManager.GetCell(pos), pos); terrainManager.terrainCellMeshes[(int)pos.X, (int)pos.Y, (int)pos.Z].Calculate(); */ lock (terrainLock) { terrainManager.cellsInitialized++; if (mesh.VerticesNormal != null) { vertexCount += mesh.VerticesNormal.Length; //triangleCount += mesh.Indices.Length / 3; } } }); t.IsBackground = true; t.Start(); }); }); terrainProcessing.IsBackground = true; terrainProcessing.Start(); /* // test sphere terrainManager.terrainCells[0, 0, 0].CreateSphere(18, 255); terrainManager.terrainCellMeshes[0, 0, 0] = new TerrainCellMesh(terrainManager.GetCell(0, 0, 0)); terrainManager.terrainCellMeshes[0, 0, 0].Calculate(); terrainManager.Initialized = true;*/ }
public static TerrainCellMesh GetMesh(this VolumeDensity8 volume, Vector3 pos, bool cubic, GraphicsDevice graphicsDevice) { TerrainCellMesh mesh = new TerrainCellMesh(volume, pos); mesh.Calculate(cubic); return mesh; }
private void GenerateTerrain(int seed) { if (terrainManager != null) if (terrainManager.cellsInitialized > 0 && (terrainManager.cellsInitialized < terrainManager.terrainCells.Length)) return; // currently generating terrain const int initialCellRes = 16; const int initialTerrainRes = 4; terrainManager = new TerrainManager(initialTerrainRes, initialCellRes); terrainManager.InitializeCells(); // set initialization state to false until we're actually done generating the cells terrainManager.Initialized = false; terrainManager.cellsInitialized = 0; //set texture scale for shader //if (terrainDrawContext != null) //SetTriplanarTextureScale(); object terrainLock = new object(); terrainGenerationTimer = new Stopwatch(); terrainGenerationTimer.Start(); // generate terrain Thread terrainProcessing = new Thread(delegate() { terrainManager.ForEachCell((cellPos, cell) => { // do each cell in its own thread var t = Task.Factory.StartNew(() => { // generate perlin 3d noise Vector3 noiseOffset = cellPos; noiseOffset.Y *= -1; cell.PerlinNoise(noiseOffset * terrainManager.cellDimensions.X, terrainNoiseDensity, seed); TerrainCellMesh mesh = new TerrainCellMesh(cell, cellPos, terrainManager.cellGap); mesh.Calculate(terrainManager.cubicTerrain); if (mesh == null) { throw new Exception("Problem generating mesh from volume!"); } // calculate convex hull mesh.CalculatePhysicsHull(); // add mesh's convex hull to the physics sim world.AddBody(mesh.RigidBody); lock (terrainLock) { terrainManager.terrainCellMeshes[(int)cellPos.X, (int)cellPos.Y, (int)cellPos.Z] = mesh; if (mesh.Vertices != null) terrainManager.vertexCount += mesh.Vertices.Count; terrainManager.cellsInitialized++; } //drawToRenderTarget.Add(new DrawRotated(terrainManager.terrainCellMeshes[(int)pos.X, (int)pos.Y, (int)pos.Z])); }); }); // for each cell, create overlapping data with // neighboring cells so we can avoid ugly border seams // then, generate a mesh for each cell /* cell.ForEach(innerPos => { if ((cellPos.X != 0) && (innerPos.X == 0)) { // get neighbor cell border density VolumeDensity8 neighborCell = terrainManager.GetCell(cellPos.X - 1, cellPos.Y, cellPos.Z); byte density = neighborCell.getVoxelAt(cell.getWidth(), innerPos.Y, innerPos.Z).getDensity(); //byte density2 = cell.getVoxelAt(innerPos).getDensity(); //density = (byte)((density + density2) / 2); // set current cell border to match cell.setDensityAt(innerPos.X - 1, innerPos.Y, innerPos.Z, density); } if ((cellPos.X != terrainManager.terrainDimensions.X) && (innerPos.X == cell.getWidth())) { // get neighbor cell border density VolumeDensity8 neighborCell = terrainManager.GetCell(cellPos.X + 1, cellPos.Y, cellPos.Z); byte density = neighborCell.getVoxelAt(0, innerPos.Y, innerPos.Z).getDensity(); //byte density2 = cell.getVoxelAt(innerPos).getDensity(); //density = (byte)((density + density2) / 2); // set current cell border to match cell.setDensityAt(innerPos.X + 1, innerPos.Y, innerPos.Z, density); } if ((cellPos.Y != 0) && (innerPos.Y == 0)) { // get neighbor cell border density VolumeDensity8 neighborCell = terrainManager.GetCell(cellPos.X, cellPos.Y - 1, cellPos.Z); byte density = neighborCell.getVoxelAt(innerPos.X, cell.getHeight(), innerPos.Z).getDensity(); //byte density2 = cell.getVoxelAt(innerPos).getDensity(); //density = (byte)((density + density2) / 2); // set current cell border to match cell.setDensityAt(innerPos.X, innerPos.Y - 1, innerPos.Z, density); } if ((cellPos.Y != terrainManager.terrainDimensions.Y) && (innerPos.Y == cell.getHeight())) { // get neighbor cell border density VolumeDensity8 neighborCell = terrainManager.GetCell(cellPos.X, cellPos.Y + 1, cellPos.Z); byte density = neighborCell.getVoxelAt(innerPos.X, 0, innerPos.Z).getDensity(); //byte density2 = cell.getVoxelAt(innerPos).getDensity(); //density = (byte)((density + density2) / 2); // set current cell border to match cell.setDensityAt(innerPos.X, innerPos.Y + 1, innerPos.Z, density); } if ((cellPos.Z != 0) && (innerPos.Z == 0)) { // get neighbor cell border density VolumeDensity8 neighborCell = terrainManager.GetCell(cellPos.X, cellPos.Y, cellPos.Z - 1); byte density = neighborCell.getVoxelAt(innerPos.X, innerPos.Y, cell.getDepth()).getDensity(); //byte density2 = cell.getVoxelAt(innerPos).getDensity(); //density = (byte)((density + density2) / 2); // set current cell border to match cell.setDensityAt(innerPos.X, innerPos.Y, innerPos.Z - 1, density); } if ((cellPos.Z != terrainManager.terrainDimensions.Z) && (innerPos.Z == cell.getDepth())) { // get neighbor cell border density VolumeDensity8 neighborCell = terrainManager.GetCell(cellPos.X, cellPos.Y, cellPos.Z + 1); byte density = neighborCell.getVoxelAt(innerPos.X, innerPos.Y, 0).getDensity(); //byte density2 = cell.getVoxelAt(innerPos).getDensity(); //density = (byte)((density + density2) / 2); // set current cell border to match cell.setDensityAt(innerPos.X, innerPos.Y, innerPos.Z + 1, density); } });*/ }); terrainProcessing.IsBackground = true; terrainProcessing.Start(); drawToRenderTarget.Add(terrainManager); }