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(); } }
///////////////////////// //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)); }
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; }
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)); }