protected override void Executing(ISceneSnapshot ss) { var snapshot = (SceneSnapshot)ss; var emanager = ContextState.GetEntityManager(); foreach (var entity in emanager.GetEntities()) { var coms = entity.GetComponents <ITerrainComponent>(); if (!coms.Any()) { continue; } var conf = coms.OfType <TerrainConfigurationComponent>().Single(); if (conf.IsModified) { entity.RemoveComponents <TerrainGeneratorComponent>(); conf.IsModified = false; var generator = new TerrainGeneratorComponent(conf.Width, conf.Height, conf); generator.StartGeneratingAsync(); entity.AddComponent(generator); continue; } var generating = coms.OfType <TerrainGeneratorComponent>().SingleOrDefault(); if (generating.IsNull()) { continue; } if (generating.IsGenerated) { entity.RemoveComponent(generating); var geo = entity.GetComponents <TerrainGeometryCellsComponent>(); if (geo.Any()) { entity.RemoveComponent(geo.First()); } var newgeo = new TerrainGeometryCellsComponent(); newgeo.MaxHeight = generating.MaxHeight; newgeo.MinHeight = generating.MinHeight; BuildGeometry(generating.HeightMap, conf, newgeo); entity.AddComponent(newgeo); conf.Texture = generating.Texture; var box = BoundingBox.CreateFromVertices(newgeo.Positions.ToArray()); entity.UpdateComponent(TransformComponent.Create(Matrix4x4.CreateTranslation(-box.GetCenter()))); entity.GetComponent <IRenderableComponent>().CanRender = true; BuildCellsAsync(newgeo, conf); break; } } }
Task BuildCellsAsync(TerrainGeometryCellsComponent geo, TerrainConfigurationComponent config) { // Set the height and width of each terrain cell to a fixed 33x33 vertex array. int cellHeight = 33; int cellWidth = 33; // Calculate the number of cells needed to store the terrain data. int cellRowCount = (config.Width - 1) / (cellWidth - 1); var m_CellCount = cellRowCount * cellRowCount; // Create the terrain cell array. var TerrainCells = new TerrainGeometryCellsComponent.TerrainCell[m_CellCount]; try { // Loop through and initialize all the terrain cells. for (int j = 0; j < cellRowCount; j++) { for (int i = 0; i < cellRowCount; i++) { int index = (cellRowCount * j) + i; TerrainCells[index] = geo.BuildCell(i, j, cellHeight, cellWidth, config.Width); } } }catch (Exception ex) { ex.ToString(); } geo.Cells = TerrainCells; return(Task.FromResult(0)); }
public static void RenderCells(GraphicsDevice graphics, Frustum frustum, TerrainGeometryCellsComponent geo, D3DTerrainRenderComponent render, TransformComponent transform) { var context = graphics.ImmediateContext; if (render.TransformWorldBuffer.HasValue) { context.VertexShader.SetConstantBuffer(TransforStructBuffer.RegisterResourceSlot, render.TransformWorldBuffer.Get()); } context.InputAssembler.InputLayout = render.Layout.Get(); context.InputAssembler.PrimitiveTopology = render.PrimitiveTopology; graphics.UpdateRasterizerState(render.RasterizerState.GetDescription()); context.OutputMerger.SetDepthStencilState(render.DepthStencilState.Get(), 0); var blendFactor = new SharpDX.Mathematics.Interop.RawColor4(0, 0, 0, 0); context.OutputMerger.SetBlendState(render.BlendingState.Get(), blendFactor, -1); for (var index = 0; index < geo.Cells.Length; ++index) { var cell = geo.Cells[index]; var box = cell.Tree.GetBounds().Transform(transform.MatrixWorld); if (cell.Tree.IsBuilt && frustum.Contains(ref box) != Frustum.ContainmentType.Disjoint) { context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(render.VertexBuffers.Get()[index], TerrainVertex.Size, 0)); context.InputAssembler.SetIndexBuffer(render.IndexBuffers.Get()[index], SharpDX.DXGI.Format.R32_UInt, 0); graphics.ImmediateContext.DrawIndexed(cell.IndexCount, 0, 0); } } }
void UpdateCellBuffers(GraphicsDevice graphics, TerrainGeometryCellsComponent geo, D3DTerrainRenderComponent render) { var vbuff = new SharpDX.Direct3D11.Buffer[geo.Cells.Length]; var ibuff = new SharpDX.Direct3D11.Buffer[geo.Cells.Length]; for (var cellIndex = 0; cellIndex < geo.Cells.Length; cellIndex++) { var cell = geo.Cells[cellIndex]; var pool = ArrayPool <TerrainClipmapsVertex> .Shared; TerrainClipmapsVertex[] vertex = null; try { //vertex = new TerrainVertex[pos.Length]; vertex = pool.Rent(cell.VertexCount);// for (var i = 0; i < cell.VertexCount; i++) { vertex[i] = new TerrainClipmapsVertex { texcoor = cell.TextureCoordinates[i], }; } vbuff[cellIndex] = graphics.CreateBuffer(BindFlags.VertexBuffer, vertex); ibuff[cellIndex] = graphics.CreateBuffer(BindFlags.IndexBuffer, cell.Indices); } finally { pool.Return(vertex); } } render.VertexBuffers.Set(vbuff); render.IndexBuffers.Set(ibuff); }
public static void UpdateCellBuffers(GraphicsDevice graphics, TerrainGeometryCellsComponent geo, D3DTerrainRenderComponent render) { var vbuff = new SharpDX.Direct3D11.Buffer[geo.Cells.Length]; var ibuff = new SharpDX.Direct3D11.Buffer[geo.Cells.Length]; for (var cellIndex = 0; cellIndex < geo.Cells.Length; cellIndex++) { var cell = geo.Cells[cellIndex]; var pool = ArrayPool <TerrainVertex> .Shared; TerrainVertex[] vertex = null; try { //vertex = new TerrainVertex[pos.Length]; vertex = pool.Rent(cell.VertexCount);// for (var i = 0; i < cell.VertexCount; i++) { var weight = new Vector4( SharpDX.MathUtil.Clamp(1.0f - (float)Math.Abs(cell.Positions[i].Y - 0f) / 8.0f, 0f, 1f), SharpDX.MathUtil.Clamp(1.0f - (float)Math.Abs(cell.Positions[i].Y - 10) / 6.0f, 0f, 1f), SharpDX.MathUtil.Clamp(1.0f - (float)Math.Abs(cell.Positions[i].Y - 15) / 6.0f, 0f, 1f), SharpDX.MathUtil.Clamp(1.0f - (float)Math.Abs(cell.Positions[i].Y - geo.MaxHeight) / 4.0f, 0f, 1f) ); var total = weight.X + weight.Y + weight.Z + weight.W; weight.X /= total; weight.Y /= total; weight.Z /= total; weight.W /= total; vertex[i] = new TerrainVertex { position = cell.Positions[i], normal = cell.Normals[i], tangent = cell.Tangents[i], binormal = cell.Binormal[i], color = cell.Colors[i], texcoor = cell.TextureCoordinates[i], normapMapTexCoor = cell.NormalMapTexCoordinates[i], texWeights = weight, }; } vbuff[cellIndex] = graphics.CreateBuffer(BindFlags.VertexBuffer, vertex); ibuff[cellIndex] = graphics.CreateBuffer(BindFlags.IndexBuffer, cell.Indices); } finally { pool.Return(vertex); } } render.VertexBuffers.Set(vbuff); render.IndexBuffers.Set(ibuff); }
static void BuildGeometry(Vector3[] HeightMap, TerrainConfigurationComponent config, TerrainGeometryCellsComponent geometry) { var width = config.Width; var height = config.Height; var count = (width - 1) * (height - 1) * 6; var indices = new int[count]; var vertices = HeightMap;//.ToArray(); var index = 0; for (int j = 0; j < (height - 1); j++) { var row = height * j; var row2 = height * (j + 1); for (int i = 0; i < (width - 1); i++) { var indx1 = row + i; var indx2 = row + i + 1; var indx3 = row2 + i; var indx4 = row2 + i + 1; indices[index++] = indx1; indices[index++] = indx2; indices[index++] = indx3; indices[index++] = indx2; indices[index++] = indx4; indices[index++] = indx3; } } var normals = vertices.CalculateNormals(indices); geometry.Indices = indices.ToImmutableArray(); geometry.Positions = vertices.ToImmutableArray(); geometry.Normals = normals.ToImmutableArray(); CalculateTextureCoordinates(HeightMap, width, height, config.TextureRepeat, out var t1, out var t2); geometry.TextureCoordinates = t1.ToImmutableArray(); geometry.NormalMapTexCoordinates = t2; geometry.Color = V4Colors.White; ComputeTangents(geometry); //Light.SetAmbientColor(0.05f, 0.05f, 0.05f, 1.0f); //Light.SetDiffuseColor(1.0f, 1.0f, 1.0f, 1.0f); }