internal static IEnumerable<Polygon> CreatePolygons(float height, Vector2[] points, Func<Vector3, Vector3, Vertex> vertexFactory, bool guaranteeNormals = true) { vertexFactory = vertexFactory ?? ((p, n) => new Vertex(p, n)); //top circle var top = new Polygon(points.Select(a => new Vector3(a.X, height / 2, a.Y)).Select(a => vertexFactory(a, Vector3.Zero))); float dot = Vector3.Dot(Vector3.Up, top.Plane.Normal); if (dot < 0 && guaranteeNormals) { foreach (var item in CreatePolygons(height, points.Reverse().ToArray(), vertexFactory, false)) yield return item; yield break; } yield return top; //bottom circle var bottom = new Polygon(points.Reverse().Select(a => new Vector3(a.X, -height / 2, a.Y)).Select(a => vertexFactory(a, Vector3.Zero))); yield return bottom; //sides for (int i = 0; i < points.Length; i++) { Vector2 pos1 = points[(i + 1) % points.Length]; Vector2 pos2 = points[i]; var poly = new Polygon(new Vertex[] { vertexFactory(new Vector3(pos2.X, height / 2, pos2.Y), Vector3.Zero), vertexFactory(new Vector3(pos2.X, -height / 2, pos2.Y), Vector3.Zero), vertexFactory(new Vector3(pos1.X, -height / 2, pos1.Y), Vector3.Zero), vertexFactory(new Vector3(pos1.X, height / 2, pos1.Y), Vector3.Zero), }); yield return poly; } }
public static void ApplyMaterials(CityGml2GO cityGml2Go) { //var path = Path.GetFullPath(cityGml2Go.Filename); var path = Application.dataPath + "/StreamingAssets/test/"; foreach (var texture in cityGml2Go.Textures) { var fn = Path.Combine(path, texture.Url); var b = File.ReadAllBytes(fn); var tex2D = new Texture2D(1, 1); tex2D.LoadImage(b); var mat = new Material(Shader.Find("Standard")) { mainTexture = tex2D }; foreach (var textureTarget in texture.Targets) { if (!cityGml2Go.Polygons.Any(x => x != null && x.name == textureTarget.Id && x.activeSelf)) { continue; } GameObject go = cityGml2Go.Polygons.First(x => x != null && x.name == textureTarget.Id && x.activeSelf); MeshRenderer mr = go.GetComponent <MeshRenderer>(); mr.material = mat; MeshFilter mf = go.GetComponent <MeshFilter>(); Vector3[] vertices = mf.sharedMesh.vertices; var uv = new Vector2[vertices.Length]; foreach (var x in cityGml2Go.oriPoly) { if (x.name == textureTarget.Id) { x.outsideUVs = textureTarget.Coords; for (int i = 0; i < vertices.Length; i++) { uv[i] = x.ClosestUV(vertices[i]); } } } uv.Reverse(); mf.sharedMesh.uv = uv.ToArray(); mf.sharedMesh.RecalculateTangents(); } } }
public static List<Vector2> convex2D(Vector2[] points, bool reverse = true) { if (points.Length < 3) return new List<Vector2>(); if (reverse) { var clockwise = area.simplePolygon(points) <= 0; if (!clockwise) points = points.Reverse().ToArray(); } var result = new List<Vector2>((points.Length - 2) * 3); for (int i = 1; i < points.Length - 1; i++) { result.Add(points[0]); result.Add(points[i]); result.Add(points[i + 1]); } return result; }
public void Update() { base.UpdateInput(ref InputEventDispatcher.CurrentControlState); _topCurves.GetParameterizedPoint(0, true); var topPts = new Vector2[_meshVertexWidth]; for (double i = 0; i < _meshVertexWidth; i++) { double t = i / ((_meshVertexWidth - 1) * 2); topPts[(int)i] = _topCurves.GetParameterizedPoint(t); } topPts = topPts.Reverse().ToArray(); float reflectionPoint = topPts[0].Y; var yDelta = new float[_meshVertexWidth]; for (int i = 0; i < _meshVertexWidth; i++) { yDelta[i] = Math.Abs(topPts[i].Y - reflectionPoint) * 2 / _meshVertexWidth; } _sideCurves.GetParameterizedPoint(0, true); //this refreshes internal fields //orient controllers correctly for the bezierintersect var li = _sideCurves.Select(bezierCurve => new BezierInfo( _sideCurves.ToMeters(bezierCurve.CenterHandlePos), _sideCurves.ToMeters(bezierCurve.PrevHandlePos), _sideCurves.ToMeters(bezierCurve.NextHandlePos))).ToList(); var sideIntersectGenerator = new BezierDependentGenerator(li); var sideIntersectionCache = new float[_meshVertexWidth]; for (int x = 0; x < _meshVertexWidth; x++) { sideIntersectionCache[x] = sideIntersectGenerator.GetValueFromIndependent(topPts[x].X).Y; } var maxY = (float)_backCurves.ToMetersY(_backCurves.MaxY); var backCurvesMaxWidth = (float)(_backCurves.ToMetersX(_backCurves[_backCurves.Count - 1].CenterHandlePos.X) - _backCurves.ToMetersX(_backCurves[0].CenterHandlePos.X)); for (int x = 0; x < _meshVertexWidth; x++) { float scaleX = Math.Abs((reflectionPoint - topPts[x].Y) * 2) / backCurvesMaxWidth; float scaleY = sideIntersectionCache[x] / maxY; var bezierInfo = _backCurves.GetControllerInfo(scaleX, scaleY); var crossIntersectGenerator = new BezierDependentGenerator(bezierInfo); for (int z = 0; z < _meshVertexWidth / 2; z++) { Vector2 pos = crossIntersectGenerator.GetValueFromIndependent(yDelta[x] * (z)); _mesh[x, z] = new Vector3(topPts[x].X, -pos.Y, topPts[x].Y + yDelta[x] * (z)); _mesh[x, _meshVertexWidth - 1 - z] = new Vector3(topPts[x].X, -pos.Y, topPts[x].Y + yDelta[x] * (_meshVertexWidth - 1 - z)); } } var normals = new Vector3[_meshVertexWidth, _meshVertexWidth]; MeshHelper.GenerateMeshNormals(_mesh, ref normals); MeshHelper.ConvertMeshToVertList(_mesh, normals, ref _verticies); _geometryBuffer.Vertexbuffer.SetData(_verticies); var p = new Vector3(); p += _mesh[0, 0]; p += _mesh[_meshVertexWidth - 1, 0]; p += _mesh[0, _meshVertexWidth - 1]; p += _mesh[_meshVertexWidth - 1, _meshVertexWidth - 1]; p /= 4; base.SetCameraTarget(p); }
private void CreateFootpath2Outer(ISubdivisionGeometry geometry, string material, float height, IHalfEdgeBuilder r1, IHalfEdgeBuilder r2) { Contract.Requires(geometry != null); Contract.Requires(r1 != null); Contract.Requires(r2 != null); //r1.LeftEnd and r2.RightEnd are the outsides of the roads //Trace a path along the boundary between these points, use the path which does *not* include the other points Vector2[] cwp, ccwp; bool cw, ccw; Bounds.Footprint.TraceConnectingPath( Vector3.Transform(r1.LeftEnd.X_Y(0), InverseWorldTransformation).XZ(), Vector3.Transform(r2.RightEnd.X_Y(0), InverseWorldTransformation).XZ(), 0.01f, out cwp, out cw, out ccwp, out ccw, Vector3.Transform(r1.RightEnd.X_Y(0), InverseWorldTransformation).XZ(), Vector3.Transform(r2.LeftEnd.X_Y(0), InverseWorldTransformation).XZ()); //Sanity check (only 1 direction should be acceptable) if (!(cw ^ ccw)) { return; } //Follow along edge, then back along edge (pushed inwards by footpath width) //todo: Offset width by angle at end of road var outerPoints = cw ? cwp : ccwp; var innerPoints = new Vector2[cw ? cwp.Length : ccwp.Length]; Contract.Assert(innerPoints.Length == outerPoints.Length); var widthStart = cw ? r1.SidewalkWidth : r2.SidewalkWidth; var widthEnd = cw ? r2.SidewalkWidth : r1.SidewalkWidth; for (var i = 0; i < outerPoints.Length && outerPoints.Length > 1; i++) { Vector2 dir; float w; if (i == 0) { dir = Vector2.Normalize(cw ? r1.RightEnd - r1.LeftEnd : r2.LeftEnd - r2.RightEnd); w = CalculateFootpathAngleScale(cw ? r1.Direction : r2.Direction, dir, widthStart); } else if (i == outerPoints.Length - 1) { dir = Vector2.Normalize(cw ? r2.LeftEnd - r2.RightEnd : r1.RightEnd - r1.LeftEnd); w = CalculateFootpathAngleScale(cw ? r2.Direction : r1.Direction, -dir, widthEnd); } else { //perpendicular to path direction dir = Vector2.Normalize(outerPoints[i] - outerPoints[i - 1]).Perpendicular() * (cw ? 1 : -1); //Interpolate widths along path var t = i / (float)(outerPoints.Length - 1); w = MathHelper.Lerp(widthStart, widthEnd, t); } innerPoints[i] = outerPoints[i] + dir * w; } //Create footprint from 2 halves var footprint = cw ? outerPoints.Concat(innerPoints.Reverse()) : outerPoints.Reverse().Concat(innerPoints); geometry.Union(geometry .CreatePrism(material, footprint.ToArray(), height) .Translate(new Vector3(0, this.GroundOffset(height), 0)) ); }