示例#1
0
        internal int[][] GenerateFacesInternal(MeshGenerator g)
        {
            if (IsEdge)
            {
                return(new int[0][]);
            }
            // Normal case
            {
                var below    = g.Allocated[RelativeId(0, 1)];
                var right    = g.Allocated[RelativeId(1, 0)];
                var diagonal = g.Allocated[RelativeId(1, 1)];
                var edges    = new List <int[]>();

                // Simple case
                for (var row = 0; row < Size; row += Zoom)
                {
                    for (var col = 0; col < Size; col += Zoom)
                    {
                        var v1 = VertexIndex(col, row);
                        if (col + Zoom == Size)
                        {     // to right
                            if (row + Zoom == Size)
                            { // diagonal
                                if (DrawDiagonal)
                                {
                                    if (false) // (Zoom == right.Zoom && Zoom == below.Zoom)
                                    {
                                        var right_row = right.Zoom * (row / right.Zoom);
                                        var v2        = right.VertexIndex(0, right_row);
                                        var below_col = below.Zoom * (col / below.Zoom);
                                        var v3        = below.VertexIndex(below_col, 0);
                                        var v4        = diagonal.VertexIndex(0, 0);
                                        edges.Add(new[] { v1, v3, v2 });
                                        edges.Add(new[] { v2, v3, v4 });
                                    }
                                    else
                                    {
                                        // Compare right
                                        if (Zoom == right.Zoom)
                                        {
                                            edges.Add(new[] { v1, diagonal.VertexIndex(0, 0), right.VertexIndex(0, Size - right.Zoom) });
                                        }
                                        else if (Zoom < right.Zoom && below.IsVertexIndex(col, 0))
                                        {
                                            var v2 = below.VertexIndex(col, 0);
                                            var v3 = diagonal.VertexIndex(0, 0);
                                            edges.Add(new[] { v1, v2, v3 });
                                        }
                                        else if (Zoom > right.Zoom)
                                        {
                                            for (var right_row = row; right_row < Size - right.Zoom; right_row += right.Zoom)
                                            {
                                                edges.Add(new[] { v1, right.VertexIndex(0, right_row + right.Zoom), right.VertexIndex(0, right_row) });
                                            }
                                            edges.Add(new[] { v1, diagonal.VertexIndex(0, 0), right.VertexIndex(0, Size - right.Zoom) });
                                        }

                                        // Compare below
                                        if (Zoom == below.Zoom)
                                        {
                                            edges.Add(new[] { v1, below.VertexIndex(Size - below.Zoom, 0), diagonal.VertexIndex(0, 0) });
                                        }
                                        else if (Zoom < below.Zoom && right.IsVertexIndex(0, row))
                                        {
                                            var v2 = right.VertexIndex(0, row);
                                            var v3 = diagonal.VertexIndex(0, 0);
                                            edges.Add(new[] { v1, v3, v2 });
                                        }
                                        else if (Zoom > below.Zoom)
                                        {
                                            for (var below_col = col; below_col < Size - below.Zoom; below_col += below.Zoom)
                                            {
                                                edges.Add(new[] { v1, below.VertexIndex(below_col, 0), below.VertexIndex(below_col + below.Zoom, 0) });
                                            }
                                            edges.Add(new[] { v1, below.VertexIndex(Size - below.Zoom, 0), diagonal.VertexIndex(0, 0) });
                                        }
                                    }
                                }
                            }
                            else
                            {   // to right only, same zoom
                                if (Zoom == right.Zoom)
                                {
                                    if (DrawRight1)
                                    {
                                        var v2 = right.VertexIndex(0, row);
                                        var v3 = VertexIndex(col, row + Zoom);
                                        var v4 = right.VertexIndex(0, row + Zoom);
                                        edges.Add(new[] { v1, v3, v2 });
                                        edges.Add(new[] { v2, v3, v4 });
                                    }
                                }
                                else if (Zoom > right.Zoom)
                                {   // right only, spacing getting tighter
                                    if (DrawRight2)
                                    {
                                        var v2             = VertexIndex(col, row + Zoom);
                                        var other_vertices = new List <int>(Zoom / right.Zoom + 1);
                                        for (var i = row; i < row + Zoom; i += right.Zoom)
                                        {
                                            other_vertices.Add(right.VertexIndex(0, i));
                                        }
                                        other_vertices.Add(row + Zoom == Size ? diagonal.VertexIndex(0, 0) : right.VertexIndex(0, row + Zoom));
                                        for (var i = 0; i < other_vertices.Count - 1; i++)
                                        {
                                            edges.Add(new[] { v1, other_vertices[i + 1], other_vertices[i] });
                                        }
                                        edges.Add(new[] { v1, v2, other_vertices[other_vertices.Count - 1] });
                                    }
                                }
                                else if (Zoom < right.Zoom)
                                {   // right only, spacing getting looser
                                    if (DrawRight3)
                                    {
                                        var v2        = VertexIndex(col, row + Zoom);
                                        var other_row = right.Zoom * (row / right.Zoom);
                                        if (row == other_row)
                                        {
                                            var v3 = right.VertexIndex(0, row);
                                            var v4 = other_row + right.Zoom == Size?diagonal.VertexIndex(0, 0) : right.VertexIndex(0, other_row + right.Zoom);

                                            edges.Add(new[] { v1, v4, v3 });
                                            edges.Add(new[] { v1, v2, v4 });
                                        }
                                        else
                                        {
                                            var v3 = other_row + right.Zoom == Size?diagonal.VertexIndex(0, 0) : right.VertexIndex(0, other_row + right.Zoom);

                                            edges.Add(new[] { v1, v2, v3 });
                                        }
                                    }
                                }
                                else
                                {
                                    System.Diagnostics.Debug.Assert(false, $"invalid pair of zooms: {Zoom} vs {right.Zoom}");
                                }
                            }
                        }
                        else
                        {     // Below
                            if (row + Zoom == Size)
                            { // below only, same zoom
                                if (Zoom == below.Zoom)
                                {
                                    if (DrawDown1)
                                    {
                                        var v2 = VertexIndex(col + Zoom, row);
                                        var v3 = below.VertexIndex(col, 0);
                                        var v4 = below.VertexIndex(col + Zoom, 0);
                                        edges.Add(new[] { v1, v3, v2 });
                                        edges.Add(new[] { v2, v3, v4 });
                                    }
                                }
                                else if (Zoom > below.Zoom)
                                {   // below only, spacing getting tighter
                                    if (DrawDown2)
                                    {
                                        var v2             = VertexIndex(col + Zoom, row);
                                        var other_vertices = new List <int>(Zoom / below.Zoom + 1);
                                        for (var i = col; i < col + Zoom; i += below.Zoom)
                                        {
                                            other_vertices.Add(below.VertexIndex(i, 0));
                                        }
                                        other_vertices.Add(col + Zoom == Size ? diagonal.VertexIndex(0, 0) : below.VertexIndex(col + Zoom, 0));
                                        for (var i = 0; i < other_vertices.Count - 1; i++)
                                        {
                                            edges.Add(new[] { v1, other_vertices[i], other_vertices[i + 1] });
                                        }
                                        edges.Add(new[] { v1, other_vertices[other_vertices.Count - 1], v2 });
                                    }
                                }
                                else if (Zoom < below.Zoom)
                                {   // below only, spacing getting looser
                                    if (DrawDown3)
                                    {
                                        var v2        = VertexIndex(col + Zoom, row);
                                        var other_col = below.Zoom * (col / below.Zoom);
                                        if (col == other_col)
                                        {
                                            var v3 = below.VertexIndex(col, 0);
                                            var v4 = other_col + below.Zoom == Size?diagonal.VertexIndex(0, 0) : below.VertexIndex(other_col + below.Zoom, 0);

                                            edges.Add(new[] { v1, v3, v4 });
                                            edges.Add(new[] { v1, v4, v2 });
                                        }
                                        else
                                        {
                                            var v3 = other_col + below.Zoom == Size?diagonal.VertexIndex(0, 0) : below.VertexIndex(other_col + below.Zoom, 0);

                                            edges.Add(new[] { v1, v3, v2 });
                                        }
                                    }
                                }
                                else
                                {
                                    System.Diagnostics.Debug.Assert(false, $"invalid pair of zooms: {Zoom} vs {below.Zoom}");
                                }
                            }
                            else
                            {   // inside center patch
                                if (DrawCenter)
                                {
                                    var v2 = VertexIndex(col + Zoom, row);
                                    var v3 = VertexIndex(col, row + Zoom);
                                    var v4 = VertexIndex(col + Zoom, row + Zoom);
                                    edges.Add(new[] { v1, v3, v2 });
                                    edges.Add(new[] { v2, v3, v4 });
                                }
                            }
                        }
                    }
                }
                return(edges.ToArray());
            }
        }
示例#2
0
        public void WritePlyFile(InMemoryTerrainManager manager, string path, bool?writeASCII = null, bool?writeColorVertices = null)
        {
            if (Allocated == null)
            {
                return;
            }
            var ascii = writeASCII.HasValue ? writeASCII.Value : WriteASCII;
            var color = writeColorVertices.HasValue ? writeColorVertices.Value : WriteColorVertices;

            var vertex_count = EnumerateVertices().Count();
            var face_count   = EnumerateFaces().Count();

            var file = File.Open(path, FileMode.Create);
            var sw   = new StreamWriter(file);

            using (var bw = new BinaryWriter(file))
            {
                using (var ms = new MemoryStream(500))
                    using (var msw = new StreamWriter(ms))
                    {
                        msw.WriteLine("ply");
                        msw.WriteLine(ascii ? "format ascii 1.0" : "format binary_little_endian 1.0");

                        msw.WriteLine($"element vertex {vertex_count}");
                        msw.WriteLine("property double x");
                        msw.WriteLine("property double y");
                        msw.WriteLine("property double z");

                        if (color)
                        {
                            msw.WriteLine("property uchar red");
                            msw.WriteLine("property uchar green");
                            msw.WriteLine("property uchar blue");
                        }

                        msw.WriteLine($"element face {face_count}");
                        msw.WriteLine("property list uchar int vertex_index");

                        msw.WriteLine("end_header");
                        msw.Flush();
                        var bytes = ms.GetBuffer();
                        if (ascii)
                        {
                            for (var i = 0; i < ms.Length; i++)
                            {
                                sw.Write((char)bytes[i]);
                            }
                        }
                        else
                        {
                            bw.Write(bytes, 0, (int)ms.Length);
                        }
                    }

                sw.Flush();
                bw.Flush();

                var count_vertices = 0;

                // testing
                math.Vector3d offset;
                {
                    var vo  = Allocated.Values.First();
                    var off = vo.VertexOffsets[0];
                    offset = MeshGenerator.LineSampleToMoonME(manager, vo.Line + off.Y, vo.Sample + off.X);
                }

                // Write the vertices
                foreach (var m in Allocated.Values)
                {
                    var colorFromTile = m.Color;
                    foreach (var vertex_offset in m.VertexOffsets)
                    {
                        var sample = m.Sample + vertex_offset.X;
                        var line   = m.Line + vertex_offset.Y;
                        var pos    = MeshGenerator.LineSampleToMoonME(manager, line, sample);

                        // Testing
                        pos = pos - offset;

                        count_vertices++;
                        if (ascii)
                        {
                            sw.Write($"{pos.X} {pos.Y} {pos.Z}");
                            if (color)
                            {
                                sw.WriteLine($" {colorFromTile.R} {colorFromTile.G} {colorFromTile.B}");
                            }
                        }
                        else
                        {
                            bw.Write(pos.X);
                            bw.Write(pos.Y);
                            bw.Write(pos.Z);
                            if (color)
                            {
                                bw.Write(colorFromTile.R);
                                bw.Write(colorFromTile.G);
                                bw.Write(colorFromTile.B);
                            }
                        }
                    }
                }

                System.Diagnostics.Debug.Assert(count_vertices == vertex_count);

                // write the faces
                if (ascii)
                {
                    foreach (var face in EnumerateFaces())
                    {
                        sw.Write(face.Length);
                        for (var i = 0; i < face.Length; i++)
                        {
                            var idx = face[i];
                            System.Diagnostics.Debug.Assert(idx >= 0 && idx < vertex_count);
                            sw.Write(' ');
                            sw.Write(idx);
                        }
                        sw.WriteLine();
                    }
                }
                else
                {
                    foreach (var face in EnumerateFaces())
                    {
                        bw.Write((byte)face.Length);
                        for (var i = 0; i < face.Length; i++)
                        {
                            var idx = face[i];
                            System.Diagnostics.Debug.Assert(idx >= 0 && idx < vertex_count);
                            bw.Write(idx);
                        }
                    }
                }

                bw.Flush();
                sw.Flush();
            }
        }