Exemple #1
0
        private static (Mesh Mesh, double MaxElevation, double MinElevation) GenerateMesh(
            double[] elevations,
            Vector3 origin,
            int rowWidth,
            double cellWidth,
            double cellHeight)
        {
            var minElevation = double.MaxValue;
            var maxElevation = double.MinValue;
            var mesh         = new Mesh();
            var triangles    = (Math.Sqrt(elevations.Length) - 1) * rowWidth * 2;

            for (var y = 0; y < rowWidth; y++)
            {
                for (var x = 0; x < rowWidth; x++)
                {
                    var ei = x + y * rowWidth;
                    var el = elevations[ei];
                    minElevation = Math.Min(minElevation, el);
                    maxElevation = Math.Max(maxElevation, el);

                    var u = (double)x / (double)(rowWidth - 1);
                    var v = (double)y / (double)(rowWidth - 1);

                    // Shrink the UV space slightly to avoid
                    // visible edges on applied textures.
                    var uvTol = 0.001;
                    u = u == 0.0 ? uvTol : u;
                    v = v == 0.0 ? uvTol : v;
                    u = u == 1.0 ? 1 - uvTol : u;
                    v = v == 1.0 ? 1 - uvTol : v;

                    var uv = new UV(u, v);

                    mesh.AddVertex(origin + new Vector3(x * cellWidth, y * cellHeight, el), uv: uv);

                    if (y > 0 && x > 0)
                    {
                        var i = x + y * rowWidth;

                        // Top triangle
                        var a  = mesh.Vertices[i];
                        var b  = mesh.Vertices[i - 1];
                        var c  = mesh.Vertices[i - rowWidth];
                        var tt = mesh.AddTriangle(a, b, c);

                        // Bottom triangle
                        var d  = mesh.Vertices[i - 1];
                        var e  = mesh.Vertices[i - 1 - rowWidth];
                        var f  = mesh.Vertices[i - rowWidth];
                        var tb = mesh.AddTriangle(d, e, f);
                    }
                }
            }

            mesh.ComputeNormals();
            return(mesh, maxElevation, minElevation);
        }
Exemple #2
0
        /// <summary>
        /// Create a topography from a custom mesh. It is assumed that the mesh is an open mesh that's roughly parallel to the XY plane.
        /// </summary>
        /// <param name="mesh">The mesh geometry of the topography.</param>
        /// <param name="material">The topography's material.</param>
        /// <param name="transform">The topography's transform.</param>
        /// <param name="id">The topography's id.</param>
        /// <param name="name">The topography's name.</param>
        /// <returns></returns>
        public Topography(Mesh mesh, Material material, Transform transform, Guid id, string name) : base(material,
                                                                                                          transform,
                                                                                                          false,
                                                                                                          id,
                                                                                                          name)
        {
            var newMesh = new Mesh(mesh);
            var bbox    = new BBox3(mesh.Vertices.Select(v => v.Position));

            this._minElevation = bbox.Min.Z;
            this._maxElevation = bbox.Max.Z;
            double absoluteMinimumElevation = this.AbsoluteMinimumElevation ?? this.MinElevation - this.DepthBelowMinimumElevation;
            var    nakedBoundaries          = mesh.GetNakedBoundaries();
            var    basePlane = new Plane((0, 0, absoluteMinimumElevation), (0, 0, 1));

            foreach (var polygon in nakedBoundaries)
            {
                // construct bottom
                var bottomPolygon = polygon.Project(basePlane);
                var tess          = new Tess
                {
                    NoEmptyPolygons = true
                };
                tess.AddContour(bottomPolygon.Reversed().ToContourVertexArray());
                tess.Tessellate(WindingRule.Positive, ElementType.Polygons, 3);
                var faceMesh = tess.ToMesh(normal: (0, 0, -1));
                this._baseVerts = new List <Vertex>(faceMesh.Vertices);
                newMesh.AddMesh(faceMesh);
                // construct sides
                var upperSegments = polygon.Segments();
                var lowerSegments = bottomPolygon.Segments();
                for (int i = 0; i < upperSegments.Count(); i++)
                {
                    var topEdge    = upperSegments[i];
                    var bottomEdge = lowerSegments[i];
                    var normal     = topEdge.Direction().Cross(Vector3.ZAxis).Unitized();
                    var a          = newMesh.AddVertex(topEdge.Start, normal: normal);
                    var b          = newMesh.AddVertex(topEdge.End, normal: normal);
                    var c          = newMesh.AddVertex(bottomEdge.End, normal: normal);
                    var d          = newMesh.AddVertex(bottomEdge.Start, normal: normal);
                    newMesh.AddTriangle(a, c, b);
                    newMesh.AddTriangle(a, d, c);
                }
            }
            this.Mesh = newMesh;
        }
Exemple #3
0
        private void CreateSidesAndBottomMesh(Mesh mesh,
                                              int rowWidth,
                                              double depth,
                                              double cellHeight,
                                              double cellWidth,
                                              Vector3 origin)
        {
            // Track the last created "low"
            // point so that we can merge
            // vertices in the side meshes.
            Vertex lastL = null;
            Vertex lastR = null;
            Vertex lastT = null;
            Vertex lastB = null;

            (Vector3 U, Vector3 V)basisLeft   = (default(Vector3), default(Vector3));
            (Vector3 U, Vector3 V)basisRight  = (default(Vector3), default(Vector3));
            (Vector3 U, Vector3 V)basisTop    = (default(Vector3), default(Vector3));
            (Vector3 U, Vector3 V)basisBottom = (default(Vector3), default(Vector3));

            this._baseVerts.Clear();

            for (var u = 0; u < rowWidth - 1; u++)
            {
                if (u == 0)
                {
                    basisLeft   = Vector3.XAxis.Negate().ComputeDefaultBasisVectors();
                    basisRight  = Vector3.XAxis.ComputeDefaultBasisVectors();
                    basisTop    = Vector3.YAxis.ComputeDefaultBasisVectors();
                    basisBottom = Vector3.YAxis.Negate().ComputeDefaultBasisVectors();
                }

                // Left side
                Vertex l1         = null;
                var    i1         = u * rowWidth;
                var    v1Existing = mesh.Vertices[i1];
                var    v1         = mesh.AddVertex(v1Existing.Position, normal: Vector3.XAxis.Negate());
                if (lastL != null)
                {
                    l1 = lastL;
                }
                else
                {
                    var p = new Vector3(v1.Position.X, v1.Position.Y, depth);
                    l1 = mesh.AddVertex(p);
                    _baseVerts.Add(l1);
                }

                var i2         = i1 + rowWidth;
                var v2Existing = mesh.Vertices[i2];
                var v2         = mesh.AddVertex(v2Existing.Position);

                var pl2 = new Vector3(v2.Position.X, v2.Position.Y, depth);
                var l2  = mesh.AddVertex(pl2);
                _baseVerts.Add(l2);
                lastL = l2;

                mesh.AddTriangle(l1, v1, v2);
                mesh.AddTriangle(l2, l1, v2);

                // Right side
                Vertex l3         = null;
                var    i3         = u * (rowWidth) + (rowWidth - 1);
                var    v3Existing = mesh.Vertices[i3];
                var    v3         = mesh.AddVertex(v3Existing.Position, normal: Vector3.XAxis);

                if (lastR != null)
                {
                    l3 = lastR;
                }
                else
                {
                    var p = new Vector3(v3.Position.X, v3.Position.Y, depth);
                    l3 = mesh.AddVertex(p);
                    _baseVerts.Add(l3);
                }

                var i4         = i3 + rowWidth;
                var v4Existing = mesh.Vertices[i4];
                var v4         = mesh.AddVertex(v4Existing.Position);
                var pl4        = new Vector3(v4.Position.X, v4.Position.Y, depth);
                var l4         = mesh.AddVertex(pl4);
                _baseVerts.Add(l4);
                lastR = l4;

                mesh.AddTriangle(l3, v4, v3);
                mesh.AddTriangle(l3, l4, v4);

                // Top side
                Vertex l5         = null;
                var    i5         = u;
                var    v5Existing = mesh.Vertices[i5];
                var    v5         = mesh.AddVertex(v5Existing.Position, normal: Vector3.YAxis);
                if (lastT != null)
                {
                    l5 = lastT;
                }
                else
                {
                    var p = new Vector3(v5.Position.X, v5.Position.Y, depth);
                    l5 = mesh.AddVertex(p);
                    _baseVerts.Add(l5);
                }

                var i6         = i5 + 1;
                var v6Existing = mesh.Vertices[i6];
                var v6         = mesh.AddVertex(v6Existing.Position);
                var pl6        = new Vector3(v6.Position.X, v6.Position.Y, depth);
                var l6         = mesh.AddVertex(pl6);
                _baseVerts.Add(l6);
                lastT = l6;

                mesh.AddTriangle(l5, v6, v5);
                mesh.AddTriangle(l5, l6, v6);

                // Bottom side
                Vertex l7         = null;
                var    i7         = rowWidth * rowWidth - u - 1;
                var    v7Existing = mesh.Vertices[i7];
                var    v7         = mesh.AddVertex(v7Existing.Position, normal: Vector3.YAxis.Negate());

                if (lastB != null)
                {
                    l7 = lastB;
                }
                else
                {
                    var p = new Vector3(v7.Position.X, v7.Position.Y, depth);
                    l7 = mesh.AddVertex(p);
                    _baseVerts.Add(l7);
                }

                var i8         = i7 - 1;
                var v8Existing = mesh.Vertices[i8];
                var v8         = mesh.AddVertex(v8Existing.Position);
                var pl8        = new Vector3(v8.Position.X, v8.Position.Y, depth);
                var l8         = mesh.AddVertex(pl8);
                _baseVerts.Add(l8);
                lastB = l8;

                mesh.AddTriangle(l7, v8, v7);
                mesh.AddTriangle(l7, l8, v8);
            }

            // Add the bottom
            var bb1 = mesh.AddVertex(origin + new Vector3(0, 0, depth));
            var bb2 = mesh.AddVertex(origin + new Vector3((rowWidth - 1) * cellWidth, 0, depth));
            var bb3 = mesh.AddVertex(origin + new Vector3((rowWidth - 1) * cellWidth, (rowWidth - 1) * cellHeight, depth));
            var bb4 = mesh.AddVertex(origin + new Vector3(0, (rowWidth - 1) * cellHeight, depth));

            _baseVerts.AddRange(new[] { bb1, bb2, bb3, bb4 });

            mesh.AddTriangle(bb1, bb3, bb2);
            mesh.AddTriangle(bb1, bb4, bb3);

            mesh.ComputeNormals();
        }