Beispiel #1
0
        /// <summary>
        /// Triangulate an height map and generates a base of given height
        /// </summary>
        /// <param name="heightMap">Gridded set of points. Corrdinates can differ,
        /// but height map should be organized a set of rows and columns</param>
        /// <returns>TriangulationResult</returns>
        public Triangulation GenerateTriangleMesh_Boxed(HeightMap heightMap
                                                        , BoxBaseThickness thickness, float zValue)
        {
            Triangulation triangulationResult = new Triangulation();

            triangulationResult.NumIndices  = ((heightMap.Width - 1) * 6) * (heightMap.Height - 1); // height map plane
            triangulationResult.NumIndices += ((heightMap.Width - 1) * 6) * 2;                      // two sides
            triangulationResult.NumIndices += ((heightMap.Height - 1) * 6) * 2;                     // two sizes
            triangulationResult.NumIndices += 6;                                                    // bottom (two big triangles)

            // Regular triangulation
            triangulationResult.Positions = heightMap.Coordinates;
            triangulationResult.Indices   = TriangulateHeightMap_Internal(heightMap, true);

            // Generate box vertices and trianglation
            AddHeightMapBase(triangulationResult, heightMap, thickness, zValue);

            return(triangulationResult);
        }
Beispiel #2
0
        private void AddHeightMapBase(Triangulation triangulation, HeightMap heightMap, BoxBaseThickness thickness, float zValue)
        {
            // bake coordinates to avoid executing the coords transfrom pipeline
            var coords      = heightMap.Coordinates.ToList();
            int capacity    = heightMap.Width * 2 + (heightMap.Height - 2) * 2;
            var basePoints  = new List <GeoPoint>(capacity);
            var baseIndexes = new List <int>(capacity);

            float baseElevation = 0;

            switch (thickness)
            {
            case BoxBaseThickness.FromMinimumPoint:
                baseElevation = (float)coords.Min(p => p.Elevation).GetValueOrDefault(0) - zValue;
                break;

            default:
            case BoxBaseThickness.FixedElevation:
                baseElevation = zValue;
                break;
            }

            // x : 0 => width // y : 0
            int baseIndex0 = coords.Count;
            int baseIndex  = baseIndex0;

            for (int x = 0; x < heightMap.Width - 1; x++)
            {
                var pBase = coords[x].Clone();
                pBase.Elevation = baseElevation;
                basePoints.Add(pBase);

                baseIndexes.Add(x);
                baseIndexes.Add(baseIndex + 1);
                baseIndexes.Add(baseIndex);

                baseIndexes.Add(x + 1);
                baseIndexes.Add(baseIndex + 1);
                baseIndexes.Add(x);

                baseIndex++;
            }
            // x : width // y : 0 => height
            //
            for (int y = 0; y < heightMap.Height - 1; y++)
            {
                int x     = heightMap.Width - 1;
                int index = x + y * heightMap.Width;

                var pBase = coords[index].Clone();
                pBase.Elevation = baseElevation;
                basePoints.Add(pBase);

                baseIndexes.Add(x + y * heightMap.Width);
                baseIndexes.Add(baseIndex + 1);
                baseIndexes.Add(baseIndex);

                baseIndexes.Add(x + y * heightMap.Width);
                baseIndexes.Add(x + (y + 1) * heightMap.Width);
                baseIndexes.Add(baseIndex + 1);

                baseIndex++;
            }
            //// x : width => 0 // y : height
            for (int x = heightMap.Width - 1; x > 0; x--)
            {
                int index = x + (heightMap.Height - 1) * heightMap.Width;
                var pBase = coords[index].Clone();
                pBase.Elevation = baseElevation;
                basePoints.Add(pBase);

                baseIndexes.Add(index);
                baseIndexes.Add(index - 1);
                baseIndexes.Add(baseIndex);

                baseIndexes.Add(index - 1);
                baseIndexes.Add(baseIndex + 1);
                baseIndexes.Add(baseIndex);

                baseIndex++;
            }
            //// x : 0 // y : height => 0
            for (int y = heightMap.Height - 1; y > 0; y--)
            {
                int x     = 0;
                int index = x + y * heightMap.Width;

                var pBase = coords[index].Clone();
                pBase.Elevation = baseElevation;
                basePoints.Add(pBase);

                // last base position is the first base generated
                int nextBaseIndex = baseIndex + 1 > baseIndex0 + capacity - 1 ? baseIndex0 : baseIndex + 1;

                baseIndexes.Add(x + y * heightMap.Width);
                baseIndexes.Add(nextBaseIndex);
                baseIndexes.Add(baseIndex);

                baseIndexes.Add(x + y * heightMap.Width);
                baseIndexes.Add(x + (y - 1) * heightMap.Width);
                baseIndexes.Add(nextBaseIndex);


                baseIndex++;
            }


            // base (2 big triangles)
            baseIndexes.Add(baseIndex0);
            baseIndexes.Add(baseIndex0 + heightMap.Width - 1);
            baseIndexes.Add(baseIndex0 + heightMap.Width - 1 + heightMap.Height - 1);

            baseIndexes.Add(baseIndex0);
            baseIndexes.Add(baseIndex0 + heightMap.Width - 1 + heightMap.Height - 1);
            baseIndexes.Add(baseIndex0 + 2 * (heightMap.Width - 1) + heightMap.Height - 1);



            triangulation.Positions     = triangulation.Positions.Concat(basePoints);
            triangulation.NumPositions += basePoints.Count;
            triangulation.Indices       = triangulation.Indices.Concat(baseIndexes);
        }
Beispiel #3
0
        /// <summary>
        /// Generate a triangle mesh from supplied height map, triangulating and optionaly mapping UVs
        /// and generate sides and bottom (like a box where the top is the triangulated height map)
        /// </summary>
        /// <param name="heightMap">Height map.</param>
        /// <param name="thickness">Determines how box height will be calculated</param>
        /// <param name="zValue">Z value to apply for box calculation</param>
        /// <returns></returns>
        public MeshPrimitive GenerateTriangleMesh_Boxed(HeightMap heightMap, BoxBaseThickness thickness = BoxBaseThickness.FixedElevation, float zValue = 0f)
        {
            Triangulation triangulation = _meshService.GenerateTriangleMesh_Boxed(heightMap, thickness, zValue);

            return(GenerateTriangleMesh(triangulation));
        }