Beispiel #1
0
    public override void GenerateMeshes()
    {
        base.GenerateMeshes();
        if (!park)
        {
            Polygon asPoly   = GetPolygon();
            Vector2 centroid = asPoly.centroid;
            if (asPoly.area > minBuildingArea)
            {
                int floors = Mathf.CeilToInt(1 + Mathf.Pow(Random.value, 8) * 5);

                Building building = new Building(this, Random.Range(2.5f, 3f), floors, city);
                building.PlaceBuilding();
            }
            else
            {
                LandBuilder land = new LandBuilder(this, city);
                land.PlaceLand();
            }
        }
        else
        {
            LandBuilder land = new LandBuilder(this, city);
            land.PlaceLand();
        }
    }
Beispiel #2
0
    /////////////////////////

    //polygon union
    static public List <Vector2> PolygonUnion(List <Vector2> _polygon1, Vector2[] _polygon)
    {
        List <Vector2> _polygon2 = new List <Vector2> (_polygon);

        if (_polygon1 == null)
        {
            return(_polygon2);
        }
        if (_polygon1.Count == 0)
        {
            return(_polygon2);
        }

        // List<Vector2> result = new List<Vector2>();

        // _polygon1.AddRange(polygon2);
        // return _polygon1;
        // return result;
        EPPZ.Geometry.Model.Polygon polygon1 = EPPZ.Geometry.Model.Polygon.PolygonWithPointList(_polygon1);
        EPPZ.Geometry.Model.Polygon polygon2 = EPPZ.Geometry.Model.Polygon.PolygonWithPointList(_polygon2);
        polygon1.AddPolygon(polygon2);
        EPPZ.Geometry.Model.Polygon polygon_union = polygon1.UnionPolygon();

        return(new List <Vector2> (polygon_union.points));
    }
Beispiel #3
0
    public override SubdividableEdgeLoop <CityEdge> GetNextChild(CityEdge[] edges)
    {
        //return new Park(edges, rootCity);
        Polygon polygonTemplate = GetPolygon();
        float   childArea       = Mathf.Abs(polygonTemplate.area);
        float   parkChance      = 0.025f;

        if (Random.value < parkChance)
        {
            return(new Plot(edges, rootCity, true, depth + 1));
        }
        else
        {
            if (childArea > City.MINSUBDIVAREA)
            {
                return(new Block(edges, rootCity, depth + 1));
                //return new Plot(edges, rootCity);
            }
            else
            {
                return(new Plot(edges, rootCity, false, depth + 1));
            }
        }
    }
    /*    public float clipperScale = 1000;
     *  public float clipperArcTolerance = 10e+3f; // 2 magnitude smaller*/

    void UpdateModel()
    {
        // Update polygon model with transforms, also update calculations.
        _polygon = Polygon.PolygonWithSource(this);
        //_polygon.UpdatePointPositionsWithSource( this );

        //if( offset != 0.0f )
        {
/*            EPPZ.Geometry.Model.Polygon.clipperArcTolerance = clipperArcTolerance;
 *          EPPZ.Geometry.Model.Polygon.clipperScale = clipperScale;*/
            _offsetPolygon = _polygon.SimplifiedNotRoundedOffsetPolygon(offset);
            //_offsetPolygon = _polygon.SimplifiedAndRoundedOffsetPolygon( offset );
            //.SimplifiedAndRoundedOffsetPolygon( offset );
        }



        #region Border points


        borderPoints = new List <BorderPoint>();
        //BorderPoint prevPoint = null;
        polygon.EnumerateEdgesRecursive(( Edge eachEdge ) =>
        {
            BorderPoint newBorderPoint = new BorderPoint()
            {
                circle = this,
                pointA = transform.TransformPoint(new Vector3(eachEdge.a.x, 0, eachEdge.a.y)),
                pointB = transform.TransformPoint(new Vector3(eachEdge.b.x, 0, eachEdge.b.y)),
                normal = new Vector3(eachEdge.normal.x, 0, eachEdge.normal.y).normalized,
                //prevPoint = prevPoint
            };
            borderPoints.Add(newBorderPoint);

/*            if (prevPoint != null) prevPoint.nextPoint = newBorderPoint;
 *          prevPoint = newBorderPoint;*/
        });


/*        if( InfluenceCirclesManager._instance != null )
 *      {
 *          float bpDebugShift = 0;
 *          float step = 3f / (float)borderPoints.Count;
 *          foreach( BorderPoint bp in borderPoints )
 *          {
 *              Debug.DrawLine(
 *                  bp.pointA + Vector3.up * bpDebugShift,
 *                  bp.pointB + Vector3.up * bpDebugShift,
 *                  Color.red, InfluenceCirclesManager._instance.loopWaitTime );
 *
 *              bpDebugShift += step;
 *          }
 *      }*/

        #endregion



        #region Setup mesh

        //cast points to local space

/*        for( var i = 0; i < polygon.points.Length; i++ )
 *      {
 *          Vector3 localPoint = transform.InverseTransformPoint( new Vector3( polygon.points [ i ].x, 0, polygon.points [ i ].y) );
 *          polygon.points [ i ] = new Vector2( localPoint.x, localPoint.z );
 *      }*/


        MeshFilter meshFilter = GetComponent <MeshFilter>();
        meshFilter.sharedMesh = polygon.Mesh(lineColor, TriangulatorType.Dwyer);

        MeshRenderer meshRenderer = GetComponent <MeshRenderer>();
        if (meshRenderer == null)
        {
            meshRenderer = gameObject.AddComponent <MeshRenderer>();
        }
        if (meshRenderer != null)
        {
            if (mat != null /*&& meshRenderer.sharedMaterial ==null*/)
            {
                meshRenderer.sharedMaterial = new Material(mat);
                //meshRenderer./*material*/sharedMaterial.SetColor( "_FillColor", lineColor );
                meshRenderer./*material*/ sharedMaterial.SetColor("_Color", lineColor);
            }
        }

        #endregion


        area = polygon.area;
    }
Beispiel #5
0
    public static Mesh GetTriangulationMesh(Vector3[] verts, HashSet <int> borderVerts, Polygon boundary)
    {
        TriangleNet.Geometry.Polygon polygon = new TriangleNet.Geometry.Polygon();
        //Dictionary<TriangleNet.Geometry.Vertex, float> vertexElevMap = new Dictionary<TriangleNet.Geometry.Vertex, float>();
        foreach (Vector3 vert in verts)
        {
            TriangleNet.Geometry.Vertex triangulationVert = new TriangleNet.Geometry.Vertex(vert.x, vert.z);
            //vertexElevMap.Add(triangulationVert, vert.y);
            polygon.Add(triangulationVert);
        }

        TriangleNet.Meshing.ConstraintOptions options =
            new TriangleNet.Meshing.ConstraintOptions()
        {
            ConformingDelaunay = true
        };
        TriangleNet.Meshing.GenericMesher mesher = new TriangleNet.Meshing.GenericMesher();
        TriangleNet.Meshing.IMesh         mesh   = mesher.Triangulate(polygon);

        Vector3[]  meshVerts     = new Vector3[mesh.Vertices.Count];
        List <int> meshTriangles = new List <int>();

        Dictionary <TriangleNet.Geometry.Vertex, int> vertexIndexMap = new Dictionary <TriangleNet.Geometry.Vertex, int>();

        int v = 0;

        foreach (TriangleNet.Geometry.Vertex triangulatorVert in mesh.Vertices)
        {
            meshVerts[v] = new Vector3((float)triangulatorVert.X, verts[v].y, (float)triangulatorVert.Y);
            vertexIndexMap[triangulatorVert] = v;
            v++;
        }
        //for (int i = 0; i < vertexList.Length; i ++)
        //{
        //    TriangleNet.Geometry.Vertex triangulatorVert = vertexList[i];
        //    meshVerts[i] = new Vector3((float)triangulatorVert.X, vertexElevMap[triangulatorVert], (float)triangulatorVert.Y);
        //    vertexIndexMap[triangulatorVert] = i;
        //}

        foreach (TriangleNet.Topology.Triangle tri in mesh.Triangles)
        {
            int     ind1   = vertexIndexMap[tri.GetVertex(0)];
            int     ind2   = vertexIndexMap[tri.GetVertex(2)];
            int     ind3   = vertexIndexMap[tri.GetVertex(1)];
            Vector2 center = new Vector2((float)(tri.GetVertex(0).X + tri.GetVertex(1).X + tri.GetVertex(2).X) / 3f, (float)(tri.GetVertex(0).Y + tri.GetVertex(1).Y + tri.GetVertex(2).Y) / 3f);

            if (!(borderVerts.Contains(ind1) && borderVerts.Contains(ind2) && borderVerts.Contains(ind3)) || (boundary.ContainsPoint(center) && !boundary.PermiterContainsPoint(center)))
            {
                meshTriangles.Add(ind1);
                meshTriangles.Add(ind2);
                meshTriangles.Add(ind3);
            }
        }

        Mesh unityMesh = new Mesh();

        unityMesh.vertices  = meshVerts;
        unityMesh.triangles = meshTriangles.ToArray();
        unityMesh.RecalculateBounds();
        unityMesh.RecalculateNormals();
        return(unityMesh);
    }
        public Polygon UnionPolygon()
        {
            // Calculate Polygon-Clipper scale.
            float maximum      = Mathf.Max(bounds.width, bounds.height);
            float maximumScale = (float)Int32.MaxValue / maximum;
            float scale        = Mathf.Min(clipperScale, maximumScale);

            // Convert to Clipper.
            Paths subjectPaths = new Paths();
            Paths clipPaths    = new Paths();

            {
                Path path = new Path();
                EnumeratePoints((Vector2 eachPoint) =>
                {
                    path.Add(new IntPoint(eachPoint.x * scale, eachPoint.y * scale));
                });
                subjectPaths.Add(path);
            }
            foreach (Polygon eachPolygon in polygons)
            {
                Path path = new Path();
                eachPolygon.EnumeratePoints((Vector2 eachPoint) =>
                {
                    path.Add(new IntPoint(eachPoint.x * scale, eachPoint.y * scale));
                });
                clipPaths.Add(path);
            }

            // Clipper union.
            Paths   unionPaths = new Paths();
            Clipper clipper    = new Clipper();

            clipper.AddPaths(subjectPaths, PolyType.ptSubject, true);
            clipper.AddPaths(clipPaths, PolyType.ptClip, true);
            clipper.Execute(ClipType.ctUnion, unionPaths);

            // Remove self intersections.
            Paths simplifiedUnionPaths = new Paths();

            simplifiedUnionPaths = Clipper.SimplifyPolygons(unionPaths);

            // Convert from Cipper.
            Polygon simplifiedUnionPolygon = null;

            for (int index = 0; index < simplifiedUnionPaths.Count; index++)
            {
                Path    eachSolutionPath    = simplifiedUnionPaths[index];
                Polygon eachSolutionPolygon = PolygonFromClipperPath(eachSolutionPath, scale);

                if (index == 0)
                {
                    simplifiedUnionPolygon = Polygon.PolygonWithPoints(eachSolutionPolygon.points);                     // Copy
                }
                else
                {
                    simplifiedUnionPolygon.AddPolygon(eachSolutionPolygon);
                }
            }

            // Back to Polygon.
            return(simplifiedUnionPolygon);
        }
 public static Polygon PolygonWithPointList(List <Vector2> pointList)
 {
     return(Polygon.PolygonWithPoints(pointList.ToArray()));
 }
        Polygon OffsetPolygon(float offset, bool simplify, bool rounded)
        {
            // Calculate Polygon-Clipper scale.
            float maximum      = Mathf.Max(bounds.width, bounds.height) + offset * 2.0f + offset;
            float maximumScale = (float)Int32.MaxValue / maximum;
            float scale        = Mathf.Min(clipperScale, maximumScale);


            // Convert to Clipper.
            Paths paths = new Paths();

            {
                Path path = new Path();
                EnumeratePoints((Vector2 eachPoint) =>
                {
                    path.Add(new IntPoint(eachPoint.x * scale, eachPoint.y * scale));
                });
                paths.Add(path);
            }
            foreach (Polygon eachPolygon in polygons)
            {
                Path path = new Path();
                eachPolygon.EnumeratePoints((Vector2 eachPoint) =>
                {
                    path.Add(new IntPoint(eachPoint.x * scale, eachPoint.y * scale));
                });
                paths.Add(path);
            }

            // Mode.
            JoinType joinType = (rounded) ? JoinType.jtRound : JoinType.jtMiter;

            // Clipper offset.
            Paths         offsetPaths   = new Paths();
            ClipperOffset clipperOffset = new ClipperOffset();

            if (rounded)
            {
                clipperOffset.ArcTolerance = 0.25 * clipperArcTolerance;
            }                                                                                     // "The default ArcTolerance is 0.25 units." from http://www.angusj.com/delphi/clipper/documentation/Docs/Units/ClipperLib/Classes/ClipperOffset/Properties/ArcTolerance.htm
            clipperOffset.AddPaths(paths, joinType, EndType.etClosedPolygon);


            clipperOffset.Execute(ref offsetPaths, (double)offset * scale);
            clipperOffset.Clear();
            //Clipper.CleanPolygon( paths [ 0 ] );

            // Remove self intersections (if requested).
            if (simplify)
            {
                offsetPaths = Clipper.SimplifyPolygons(offsetPaths);
            }


            // Convert from Clipper.
            Polygon offsetPolygon = null;

            for (int index = 0; index < offsetPaths.Count; index++)
            {
                Path    eachSolutionPath    = offsetPaths[index];
                Polygon eachSolutionPolygon = PolygonFromClipperPath(eachSolutionPath, scale);

                if (index == 0)
                {
                    offsetPolygon = Polygon.PolygonWithPoints(eachSolutionPolygon.points);                     // Copy
                }
                else
                {
                    offsetPolygon.AddPolygon(eachSolutionPolygon);
                }
            }

            // Back to Polygon.
            return(offsetPolygon);
        }
 public Polygon Copy()
 {
     return(Polygon.PolygonWithPolygon(this));
 }