Example #1
0
        public void GenerateRoadPolygon(int steps)
        {
            if (RoadPolygons == null)
            {
                RoadPolygons = new Ets2Point[0];
            }

            if (RoadPolygons != null && RoadPolygons.Count() == steps)
            {
                return;
            }

            if (StartNode == null || EndNode == null)
            {
                return;
            }

            if (Type != Ets2ItemType.Road)
            {
                return;
            }

            var ps = new Ets2Point[steps];

            var sx = StartNode.X;
            var ex = EndNode.X;
            var sz = StartNode.Z;
            var ez = EndNode.Z;

            var radius = (float)Math.Sqrt((sx - ex) * (sx - ex) + (sz - ez) * (sz - ez));

            var tangentSX = (float)Math.Cos(-StartNode.Yaw) * radius;
            var tangentEX = (float)Math.Cos(-EndNode.Yaw) * radius;
            var tangentSZ = (float)Math.Sin(-StartNode.Yaw) * radius;
            var tangentEZ = (float)Math.Sin(-EndNode.Yaw) * radius;

            for (int k = 0; k < steps; k++)
            {
                var s = (float)k / (float)(steps - 1);
                var x = (float)Ets2CurveHelper.Hermite(s, sx, ex, tangentSX, tangentEX);
                var z = (float)Ets2CurveHelper.Hermite(s, sz, ez, tangentSZ, tangentEZ);

                ps[k] = new Ets2Point(x, 0, z, 0);
            }

            RoadPolygons = ps;
        }
Example #2
0
        /// <summary>
        /// Generate road curves for a specific lane. The curve is generated with [steps]
        /// nodes and positioned left or right from the road's middle point.
        /// Additionally, each extra lane is shifted 4.5 game units outward.
        /// </summary>
        /// <param name="steps"></param>
        /// <param name="leftlane"></param>
        /// <param name="lane"></param>
        /// <returns></returns>
        public IEnumerable <Ets2Point> GenerateRoadCurve(int steps, bool leftlane, int lane)
        {
            var ps = new Ets2Point[steps];

            var sx = StartNode.X;
            var ex = EndNode.X;
            var sz = StartNode.Z;
            var ez = EndNode.Z;

            if (steps == 2)
            {
                sx += (float)Math.Sin(-StartNode.Yaw) * (leftlane ? -1 : 1) * (RoadLook.Offset + (0.5f + lane) * 4.5f);
                sz += (float)Math.Cos(-StartNode.Yaw) * (leftlane ? -1 : 1) * (RoadLook.Offset + (0.5f + lane) * 4.5f);

                ex += (float)Math.Sin(-EndNode.Yaw) * (leftlane ? -1 : 1) * (RoadLook.Offset + (0.5f + lane) * 4.5f);
                ez += (float)Math.Cos(-EndNode.Yaw) * (leftlane ? -1 : 1) * (RoadLook.Offset + (0.5f + lane) * 4.5f);

                ps[0] = new Ets2Point(sx, 0, sz, StartNode.Yaw);
                ps[1] = new Ets2Point(ex, 0, ez, EndNode.Yaw);
                return(ps);
            }


            var radius = (float)Math.Sqrt((sx - ex) * (sx - ex) + (sz - ez) * (sz - ez));

            var tangentSX = (float)Math.Cos(-StartNode.Yaw) * radius;
            var tangentEX = (float)Math.Cos(-EndNode.Yaw) * radius;
            var tangentSZ = (float)Math.Sin(-StartNode.Yaw) * radius;
            var tangentEZ = (float)Math.Sin(-EndNode.Yaw) * radius;

            for (int k = 0; k < steps; k++)
            {
                var s   = (float)k / (float)(steps - 1);
                var x   = (float)Ets2CurveHelper.Hermite(s, sx, ex, tangentSX, tangentEX);
                var z   = (float)Ets2CurveHelper.Hermite(s, sz, ez, tangentSZ, tangentEZ);
                var tx  = (float)Ets2CurveHelper.HermiteTangent(s, sx, ex, tangentSX, tangentEX);
                var ty  = (float)Ets2CurveHelper.HermiteTangent(s, sz, ez, tangentSZ, tangentEZ);
                var yaw = (float)Math.Atan2(ty, tx);
                x    += (float)Math.Sin(-yaw) * (leftlane ? -1 : 1) * (RoadLook.Offset + (0.5f + lane) * 4.5f);
                z    += (float)Math.Cos(-yaw) * (leftlane ? -1 : 1) * (RoadLook.Offset + (0.5f + lane) * 4.5f);
                ps[k] = new Ets2Point(x, 0, z, yaw);
            }

            return(ps);
        }