Beispiel #1
0
        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;
            }
        }
Beispiel #2
0
        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();
                }
            }
        }
Beispiel #3
0
        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;
        }
Beispiel #4
0
        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))
                           );
        }