public void Build(RenderDrawContext context)
        {
            if (Mesh == null && TryGetHeightMapImageData(context.CommandList, out var data))
            {
                Data               = new GeometryBuilder(data).BuildTerrainData(Size, MaxHeight, UvScale);
                MeshBoundingBox    = Utils.FromPoints(Data.Vertices);
                MeshBoundingSphere = BoundingSphere.FromBox(MeshBoundingBox);
                BoundingBox        = new BoundingBoxExt(MeshBoundingBox);

                var vertexBuffer        = Buffer.Vertex.New(context.GraphicsDevice, Data.Vertices, GraphicsResourceUsage.Dynamic);
                var indexBuffer         = Buffer.Index.New(context.GraphicsDevice, Data.Indices);
                var vertexBufferBinding = new VertexBufferBinding(vertexBuffer, VertexPositionNormalTexture.Layout, vertexBuffer.ElementCount);
                var indexBufferBinding  = new IndexBufferBinding(indexBuffer, true, indexBuffer.ElementCount);

                MeshDraw = new MeshDraw
                {
                    StartLocation = 0,
                    PrimitiveType = PrimitiveType.TriangleList,
                    VertexBuffers = new[] { vertexBufferBinding },
                    IndexBuffer   = indexBufferBinding,
                    DrawCount     = indexBuffer.ElementCount
                };

                Mesh = new Mesh(MeshDraw, new ParameterCollection());
            }
        }
        private async void Save(string path, GeometryData data)
        {
            var vertIdx     = 0;
            var uvIdx       = 0;
            var normIdx     = 0;
            var fileContent = new StringBuilder();

            fileContent.AppendLine("# Generated by XenkoTerrain " + DateTime.Now.ToLongDateString());
            fileContent.AppendLine("# Vertices: " + data.Vertices.Length);
            fileContent.AppendLine("# Size: " + data.Size);
            fileContent.AppendLine("usemtl Terrain");

            for (var row = 0; row < data.TessellationY - 1; row++)
            {
                for (var col = 0; col < data.TessellationX - 1; col++)
                {
                    var topLeft     = col + row * (int)data.TessellationX;
                    var topRight    = topLeft + 1;
                    var bottomLeft  = topLeft + (int)data.TessellationX;
                    var bottomRight = bottomLeft + 1;

                    var topLeftVertex    = data.Vertices[topLeft];
                    var topRightVertex   = data.Vertices[topRight];
                    var bottomLeftVertex = data.Vertices[bottomLeft];
                    var botomRightVertex = data.Vertices[bottomRight];

                    fileContent.AppendLine("v " + Print(topRightVertex.Position));
                    fileContent.AppendLine("v " + Print(topLeftVertex.Position));
                    fileContent.AppendLine("v " + Print(bottomLeftVertex.Position));
                    fileContent.AppendLine("v " + Print(botomRightVertex.Position));

                    fileContent.AppendLine("vn " + Print(topRightVertex.Normal));
                    fileContent.AppendLine("vn " + Print(topLeftVertex.Normal));
                    fileContent.AppendLine("vn " + Print(bottomLeftVertex.Normal));
                    fileContent.AppendLine("vn " + Print(botomRightVertex.Normal));

                    fileContent.AppendLine("vt " + Print(data.Size * topRightVertex.TextureCoordinate));
                    fileContent.AppendLine("vt " + Print(data.Size * topLeftVertex.TextureCoordinate));
                    fileContent.AppendLine("vt " + Print(data.Size * bottomLeftVertex.TextureCoordinate));
                    fileContent.AppendLine("vt " + Print(data.Size * botomRightVertex.TextureCoordinate));

                    fileContent.AppendLine($"f {++vertIdx}/{++uvIdx}/{++normIdx} {++vertIdx}/{++uvIdx}/{++normIdx} {++vertIdx}/{++uvIdx}/{++normIdx} {++vertIdx}/{++uvIdx}/{++normIdx}");
                }
            }

            using (var streamWriter = new StreamWriter(path))
            {
                await streamWriter.WriteAsync(fileContent.ToString());
            }
        }
        public void Update(TerrainTileComponent component)
        {
            var shouldClear = Size != component.Size ||
                              MaxHeight != component.MaxHeight ||
                              HeightMap != component.HeightMap ||
                              UvScale != component.UvScale;

            Enabled   = component.Enabled;
            Size      = component.Size;
            HeightMap = component.HeightMap;
            MaxHeight = component.MaxHeight;
            UvScale   = component.UvScale;
            Material  = component.Material;

            if (shouldClear)
            {
                Mesh = null;
                Data = null;
                component.Clear();
            }
        }
        public void RegenCollider(GeometryData data = null)
        {
            //If no new data is provided, use the existing data
            if (data == null)
            {
                data = CurrentGeometryData; //Use the existing data
            }
            else
            {
                CurrentGeometryData = data; //Save the new data, there's been an update
            }
            //Whether or not to add the collider to the entity
            var add = false;

            //Get or create a collider
            StaticColliderComponent colliderComponent = Entity.Get <StaticColliderComponent>();

            if (colliderComponent == null)
            {
                colliderComponent = new StaticColliderComponent();
                add = true;
            }

            //Create collider
            var heightfield = CreateHeightfield((int)data.TessellationX, (int)data.TessellationY, -MaxHeight, MaxHeight, data.Vertices.Select(v => v.Position.Y).ToArray(), out var points);

            //Clear any existing colliders
            colliderComponent.ColliderShapes.Clear();

            //Add the collider
            colliderComponent.ColliderShapes.Add(new BoxColliderShapeDesc());
            colliderComponent.ColliderShape = heightfield;

            //Add to entity if it does not already exist
            if (add)
            {
                Entity.Add(colliderComponent);
            }
        }
Exemple #5
0
        public void Build(TerrainTileRenderObject renderObject)
        {
            IsSet               = true;
            hiddenGeometry      = null;
            CurrentMeshDraw     = renderObject.MeshDraw;
            CurrentGeometryData = renderObject.Data;

            var model = new Model
            {
                Meshes = new List <Mesh> {
                    renderObject.Mesh
                },
                BoundingBox    = renderObject.MeshBoundingBox,
                BoundingSphere = renderObject.MeshBoundingSphere
            };

            var modelComponent = new ModelComponent(model);

            modelComponent.Materials.Add(0, renderObject.Material);

            Entity.Add(modelComponent);
        }
 public Task SaveAsync(string path, GeometryData data)
 {
     return(Task.Run(() => Save(path, data)));
 }