Beispiel #1
0
        public BuildingPart BuildPart(XElement way, bool volume = true)
        {
            var tags = way.Descendants("tag")
                       .ToDictionary(
                tag => tag.Attribute("k").Value,  // add key
                tag => tag.Attribute("v").Value); // add value

            // Building creation
            var buildingPart = new BuildingPart(
                tags.ContainsKey("name") ? tags["name"] : "",
                Convert.ToInt64(way.Attribute("id").Value));

            // Outline construction
            // TODO check if closed?
            foreach (var elt in way.Descendants("nd"))
            {
                // find node that matches ways' node ref
                var query = (from node in Xdoc.Descendants("node")
                             where (string)node.Attribute("id") == (string)elt.Attribute("ref")
                             select node).First();

                var pos = Mercator.ToMeters(Convert.ToDouble(query.Attribute("lat").Value), Convert.ToDouble(query.Attribute("lon").Value));
                var x   = pos.X - Tile.Center.X;
                var y   = pos.Y - Tile.Center.Y;
                buildingPart.Outline.Add(new Vector2(x, y));
            }

            // Part data
            PartData part;

            part.volume       = volume;
            part.height       = float.Parse(tags.ContainsKey("height") ? Regex.Match(tags["height"], @"\d+").Value : "-1", CultureInfo.InvariantCulture);
            part.min_height   = float.Parse(tags.ContainsKey("min_height") ? Regex.Match(tags["min_height"], @"\d+").Value : "-1", CultureInfo.InvariantCulture);
            part.levels       = Convert.ToInt16(tags.ContainsKey("building:levels") ? tags["building:levels"] : "-1");
            part.min_level    = Convert.ToInt16(tags.ContainsKey("building:min_level") ? tags["building:min_level"] : "-1");
            buildingPart.Data = part;

            Surface surf;

            surf.colour              = tags.ContainsKey("building:colour") ? tags["building:colour"] : "";
            surf.material            = tags.ContainsKey("building:material") ? tags["building:material"] : "";
            buildingPart.PartSurface = surf;

            return(buildingPart);
        }
Beispiel #2
0
        /// <summary>
        /// Create builidng esh
        /// </summary>
        /// <param name="building"></param>
        /// <returns></returns>
        public static Mesh CreateMesh(BuildingPart building)
        {
            var minY  = building.Body.min_height;
            var maxY  = building.Body.height;
            var poly  = building.Footprint;
            var total = poly.Points.Count;

            if (poly is MultiPolygon)
            {
                (poly as MultiPolygon).Holes.ForEach(x => total += x.Points.Count);
            }

            // Build mesh
            var vertices = new Vector3[total * 2];
            var faces    = new List <int>();
            var colors   = Enumerable.Repeat(building.Body.surface.color, total * 2).ToArray();

            // Create vertices and polygon for triangulation
            var idx       = 0;
            var P2Tpoints = new List <PolygonPointExt>();

            foreach (var point in poly.Points)
            {
                vertices[idx]         = new Vector3(point.X, minY, -point.Y);
                vertices[idx + total] = new Vector3(point.X, maxY, -point.Y);
                P2Tpoints.Add(new PolygonPointExt(point.X, point.Y, idx++));
            }
            var P2Tpoly = new Poly2TriPolygon.Polygon(P2Tpoints);

            // add faces = 2 triangles
            for (var i = 0; i < poly.Points.Count - 1; i++)
            {
                faces.Add(i + total);
                faces.Add(i);
                faces.Add(i + 1);
                faces.Add(i + total);
                faces.Add(i + 1);
                faces.Add(i + total + 1);
            }

            if (poly is MultiPolygon)
            {
                (poly as MultiPolygon).Holes.ForEach(hole =>
                {
                    // Create holes vertices and holes for triangulation
                    var P2Thole = new List <PolygonPointExt>();
                    for (var i = 0; i < hole.Points.Count; i++)
                    {
                        vertices[idx + i]         = new Vector3(hole.Points[i].X, minY, -hole.Points[i].Y);
                        vertices[idx + i + total] = new Vector3(hole.Points[i].X, maxY, -hole.Points[i].Y);
                        P2Thole.Add(new PolygonPointExt(hole.Points[i].X, hole.Points[i].Y, idx + i));
                    }

                    // Create holes faces = 2 triangles
                    for (var i = 0; i < hole.Points.Count - 1; i++)
                    {
                        faces.Add(idx + i + total);
                        faces.Add(idx + i);
                        faces.Add(idx + i + 1);
                        faces.Add(idx + i + total);
                        faces.Add(idx + i + 1);
                        faces.Add(idx + i + total + 1);
                    }

                    P2Tpoly.AddHole(new Poly2TriPolygon.Polygon(P2Thole));
                    idx += hole.Points.Count;
                });
            }

            try
            {
                P2T.Triangulate(P2Tpoly);

                // Add triangulated top faces
                foreach (var tri in P2Tpoly.Triangles)
                {
                    var i0 = tri.Points[0] as PolygonPointExt;
                    var i1 = tri.Points[1] as PolygonPointExt;
                    var i2 = tri.Points[2] as PolygonPointExt;

                    // apply to bottom
                    //                    faces.Add(i2.Idx);
                    //                    faces.Add(i1.Idx);
                    //                    faces.Add(i0.Idx);

                    // apply to top
                    faces.Add(i2.Idx + total);
                    faces.Add(i1.Idx + total);
                    faces.Add(i0.Idx + total);

                    // Add roof color
                    colors[i0.Idx + total] = building.Roof.surface.color;
                    colors[i2.Idx + total] = building.Roof.surface.color;
                    colors[i1.Idx + total] = building.Roof.surface.color;
                }
                return(new Mesh(vertices, faces.ToArray(), colors));
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }

            return(null);
        }