Beispiel #1
0
    ///////////////////////////////////////////////////////////////////
    // GENERATION FUNCTIONS ///////////////////////////////////////////
    ///////////////////////////////////////////////////////////////////
    ///
    public void GenBlock()
    {
        //List<Vector2f> points = new List<Vector2f>();
        List <Vector2> startLotCenters = new List <Vector2>();

        // find corners
        for (int i = 0; i < verts.Count - 1; i++)
        {
            Vector2 vc = (Vector2)verts[i];
            Vector2 vp = (Vector2)(i == 0 ? verts[verts.Count - 1] : verts[i - 1]);
            Vector2 vn = (Vector2)verts[i + 1];

            Vector2 diffP = vp - vc;
            Vector2 diffN = vn - vc;
            float   angle = Mathf.Abs(Vector2.Angle(diffP, diffN));
            if (angle < 165)
            {
                corners.Add(vc);
                cornersIdx.Add(i);
                //points.Add(new Vector2f(vc.x, vc.y));
            }
        }
        Vector2 avgCorner = Vector2.zero;

        foreach (Vector2 c in corners)
        {
            avgCorner += c;
        }
        avgCorner /= corners.Count;

        foreach (Vector2 c in corners)
        {
            Vector2 dir = (avgCorner - c).normalized;
            startLotCenters.Add(c + dir * 3);
        }
        //corners = new List<Vector2>(tempCorners);

        // gen points

        if (true)
        {
            for (int i = 0; i < startLotCenters.Count - 1; i++)
            {
                Vector2 corner1 = startLotCenters[i];
                Vector2 corner2 = startLotCenters[i + 1];
                lotCenters.Add(corner1);

                Vector2 diff     = corner2 - corner1;
                Vector2 dir      = diff.normalized;
                float   lineDist = diff.magnitude;
                int     numLots  = (int)(lineDist / 7);
                float   lotWidth = lineDist / numLots;

                //traverse corner to corner
                Vector2 cur           = corner1 + (lotWidth / 2) * dir;
                float   distTraversed = lotWidth / 2;

                if (!(
                        cur.x == Mathf.Infinity || cur.x == -Mathf.Infinity || cur.y == Mathf.Infinity || cur.y == -Mathf.Infinity ||
                        float.IsNaN(cur.x) || float.IsNaN(cur.y)
                        ))
                {
                    lotCenters.Add(cur);
                    //points.Add(new Vector2f(cur.x, cur.y));
                    int lotsPlaced = 1;
                    while (distTraversed < lineDist && lotsPlaced < numLots)
                    {
                        cur += (lotWidth / 2) * dir;
                        if (!bounds.InBounds(cur))
                        {
                            break;
                        }
                        //points.Add(new Vector2f(cur.x, cur.y));
                        lotCenters.Add(cur);
                        lotsPlaced++;
                    }
                }
            }
        }



        // Build lot graph
        if (lotCenters.Count >= 3)
        {
            List <Vector2> lotGuides = new List <Vector2>(lotCenters);
            for (int i = 0; i < verts.Count - 1; i++)
            {
                Vector2 v    = (Vector2)verts[i];
                Vector2 dir  = (avgCorner - v).normalized;
                Vector2 newv = v + dir * 1;
                lotGuides.Add(newv);
                outerBoundary.Add(newv);
            }

            List <Vertex> points = new List <Vertex>();
            foreach (Vector2 v in lotGuides)
            {
                points.Add(new Vertex(v.x, v.y));
            }
            //Debug.Log("LotCenters: " + Util.List2String(lotCenters));
            // Generate a default mesher
            var mesher = new GenericMesher(new Dwyer());
            // Generate mesh (Delaunay Triangulation)
            IMesh mesh = mesher.Triangulate(points);
            // Init edge/vertex lists for mutation
            ArrayList vertices = new ArrayList();
            foreach (Vertex v in mesh.Vertices)
            {
                vertices.Add(v);
            }
            foreach (Edge e in mesh.Edges)
            {
                Vertex  vert1 = (Vertex)vertices[e.P0];
                Vertex  vert2 = (Vertex)vertices[e.P1];
                Vector2 vec1  = Util.VertexToVector2(vert1);
                Vector2 vec2  = Util.VertexToVector2(vert2);

                edges.Add((vec1, vec2));

                // build neighbor map
                if (!neighbors.ContainsKey(vec1))
                {
                    neighbors[vec1] = new List <Vector2>();
                }
                if (!neighbors.ContainsKey(vec2))
                {
                    neighbors[vec2] = new List <Vector2>();
                }
                neighbors[vec1].Add(vec2);
                neighbors[vec2].Add(vec1);
            }

            // find lot bounds
            foreach (Vector2 v in lotCenters)
            {
                Lot lot = new Lot(v);
                foreach (Vector2 vn in neighbors[v])
                {
                    Vector2 vNew;
                    if (outerBoundary.Contains(vn))
                    {
                        vNew = vn;
                        // accept as outer bound
                        // 0=N, 1=E, 2=S, 3=W

                        /*if (vn.y > (float)lot.extrema[0]) {
                         * lot.extrema[0] = vn.y;
                         * }
                         * if (vn.x > (float)lot.extrema[1]) {
                         * lot.extrema[1] = vn.x;
                         * }
                         * if (vn.y < (float)lot.extrema[2]) {
                         * lot.extrema[2] = vn.y;
                         * }
                         * if (vn.x < (float)lot.extrema[3]) {
                         * lot.extrema[3] = vn.x;
                         * }*/
                    }
                    else
                    {
                        vNew = (v + vn) / 2;
                    }
                    if (vNew.y > v.y && vNew.y < (float)lot.extrema[0])
                    {
                        lot.extrema[0] = vNew.y;
                    }
                    if (vNew.x > v.x && vNew.x < (float)lot.extrema[1])
                    {
                        lot.extrema[1] = vNew.x;
                    }
                    if (vNew.y < v.y && vNew.y > (float)lot.extrema[2])
                    {
                        lot.extrema[2] = vNew.y;
                    }
                    if (vNew.x < v.x && vNew.x > (float)lot.extrema[3])
                    {
                        lot.extrema[3] = vNew.x;
                    }
                }
                lot.Calc();
                if (!lots.ContainsKey(v))
                {
                    lots.Add(v, lot);
                }
            }
        }


        ///////////////////////////////////////////////////////////////

        /*for (int i = 0; i < verts.Count; i++) {
         * if (i % 6 == 0) {
         *    Vector2 v = (Vector2)verts[i];
         *    points.Add(new Vector2f(v.x, v.y));
         * }
         * }*/

        /*
         * //List<Vector2f> p = CreateRandomPoint();
         *
         *
         * Rectf rect = new Rectf(//0, 0, 20, 20);
         *  bounds.xMin - 500, bounds.zMin - 500,
         *  bounds.xMax + 500, bounds.zMax + 500);
         *
         * Voronoi voronoi = new Voronoi(points, rect, 0);
         *
         * // Now retreive the edges from it, and the new sites position if you used lloyd relaxtion
         * sites = voronoi.SitesIndexedByLocation;
         * edges = voronoi.Edges;
         *
         * //GenVoronoi(points);
         *
         * Debug.Log("Voronoi sites: " + sites.Count + " edges:" + edges.Count);
         */
        // place points along road side

        // building plots

        // extrude plots into buildings
    }