public Texture2D GenerateHeightMap(SliceContract sliceContract)
        {
            var heightMap = new Texture2D(sliceContract.Width, sliceContract.Height);

            for (var i = 0; i < heightMap.width; i++)
            {
                for (var j = 0; j < heightMap.height; j++)
                {
                    heightMap.SetPixel(i, j, Color.white);
                }
            }

            var rows = sliceContract.Vertexes.GetLength(0) - 1;
            var columns = sliceContract.Vertexes.GetLength(1) - 1;
            var lines = null as Point[];

            for (var i = 0; i < rows - 1; i++)
            {
                for (var j = 0; j < columns - 1; j++)
                {
                    lines = sliceContract.Lines[i + 1, j, i + 1, j + 1];
                    DrawLine(heightMap, sliceContract.Vertexes[i + 1, j], lines[0]);
                    DrawLine(heightMap, lines);
                    DrawLine(heightMap, lines[lines.Length - 1], sliceContract.Vertexes[i + 1, j + 1]);

                    lines = sliceContract.Lines[i, j + 1, i + 1, j + 1];
                    DrawLine(heightMap, sliceContract.Vertexes[i, j + 1], lines[0]);
                    DrawLine(heightMap, lines);
                    DrawLine(heightMap, lines[lines.Length - 1], sliceContract.Vertexes[i + 1, j + 1]);
                }
            }

            for (var i = 0; i < rows - 1; i++)
            {
                lines = sliceContract.Lines[i + 1, columns - 1, i + 1, columns];
                DrawLine(heightMap, sliceContract.Vertexes[i + 1, columns - 1], lines[0]);
                DrawLine(heightMap, lines);
                DrawLine(heightMap, lines[lines.Length - 1], sliceContract.Vertexes[i + 1, columns]);
            }

            for (var j = 0; j < columns - 1; j++)
            {
                lines = sliceContract.Lines[rows - 1, j + 1, rows, j + 1];
                DrawLine(heightMap, sliceContract.Vertexes[rows - 1, j + 1], lines[0]);
                DrawLine(heightMap, lines);
                DrawLine(heightMap, lines[lines.Length - 1], sliceContract.Vertexes[rows, j + 1]);
            }

            heightMap.Apply();

            return heightMap;
        }
        public PieceContract[,] GeneratePiece(SliceContract sliceContract)
        {
            var rows = sliceContract.Vertexes.GetLength(0) - 1;
            var columns = sliceContract.Vertexes.GetLength(1) - 1;

            var sliceStart = sliceContract.Vertexes[0, 0];
            var sliceValidRange = sliceContract.Vertexes[rows, columns] - sliceStart;
            var conversionRate = GlobalConfiguration.PictureHeightInMeter / sliceValidRange.Y;

            var range = new Vector2(sliceContract.Width, sliceContract.Height) * conversionRate;
            var pieceRange = new Vector2(1f * sliceValidRange.X / columns, 1f * sliceValidRange.Y / rows) * conversionRate;
            var offset = new Vector2(sliceStart.X, sliceStart.Y) * conversionRate;

            var result = new PieceContract[rows, columns];

            for (var i = 0; i < rows; i++)
            {
                for (var j = 0; j < columns; j++)
                {
                    var vertexes = GetVertexes(sliceContract, i, j, conversionRate);
                    var center = new Vector2(offset.x + (j + 0.5f) * pieceRange.x, offset.y + (i + 0.5f) * pieceRange.y);

                    var topVertexes = Array.ConvertAll<Vector2, Vector3>(vertexes, refer => new Vector3(refer.x - center.x, refer.y - center.y, -GlobalConfiguration.PieceThicknessInMeter / 2));
                    var bottomVertexes = Array.ConvertAll<Vector3, Vector3>(topVertexes, refer => new Vector3(refer.x, refer.y, refer.z + GlobalConfiguration.PieceThicknessInMeter));

                    var backseatSurfaces = GetSurfaces(topVertexes, bottomVertexes);

                    var mappingMesh = new Mesh();
                    mappingMesh.vertices = topVertexes;
                    mappingMesh.triangles = GetTriangles(topVertexes);
                    mappingMesh.uv = GetUVs(vertexes, range);
                    mappingMesh.RecalculateNormals();

                    var backseatMesh = new Mesh();
                    backseatMesh.vertices = GetVertices(backseatSurfaces);
                    backseatMesh.triangles = GetTriangles(backseatSurfaces);
                    backseatMesh.RecalculateNormals();

                    result[i, j] = new PieceContract { MappingMesh = mappingMesh, BackseatMesh = backseatMesh, Position = center - range / 2 };
                }
            }

            return result;
        }
        private Vector2[] GetVertexes(SliceContract sliceContract, int x, int y, float conversionRate)
        {
            var vertexes = new List<Vector2>();

            vertexes.Add(sliceContract.Vertexes[x, y].ToVector2(conversionRate));
            var points = sliceContract.Lines[x, y, x + 1, y];
            if (points != null) { for (var i = 0; i < points.Length; i++) { vertexes.Add(points[i].ToVector2(conversionRate)); } }

            vertexes.Add(sliceContract.Vertexes[x + 1, y].ToVector2(conversionRate));
            points = sliceContract.Lines[x + 1, y, x + 1, y + 1];
            if (points != null) { for (var i = 0; i < points.Length; i++) { vertexes.Add(points[i].ToVector2(conversionRate)); } }

            vertexes.Add(sliceContract.Vertexes[x + 1, y + 1].ToVector2(conversionRate));
            points = Point.Reverse(sliceContract.Lines[x, y + 1, x + 1, y + 1]);
            if (points != null) { for (var i = 0; i < points.Length; i++) { vertexes.Add(points[i].ToVector2(conversionRate)); } }

            vertexes.Add(sliceContract.Vertexes[x, y + 1].ToVector2(conversionRate));
            points = Point.Reverse(sliceContract.Lines[x, y, x, y + 1]);
            if (points != null) { for (var i = 0; i < points.Length; i++) { vertexes.Add(points[i].ToVector2(conversionRate)); } }

            return vertexes.ToArray();
        }
 public Texture2D GenerateNormalMap(SliceContract sliceContract)
 {
     var heightMap = _graphicsService.GenerateHeightMap(sliceContract);
     return _graphicsService.GenerateNormalMap(heightMap);
 }
 public PieceContract[,] GeneratePieceContracts(SliceContract sliceContract)
 {
     return _pieceService.GeneratePiece(sliceContract);
 }