public void GenerateRoadPolygon(int steps) { if (RoadPolygons == null) { RoadPolygons = new PointF[0]; } if (RoadPolygons != null && RoadPolygons.Count() == steps) { return; } if (StartNode == null || EndNode == null) { return; } if (Type != Ets2ItemType.Road) { return; } var ps = new PointF[steps]; var sx = StartNode.X; var ex = EndNode.X; var sy = StartNode.Z; var ey = EndNode.Z; var radius = (float)Math.Sqrt((sx - ex) * (sx - ex) + (sy - ey) * (sy - ey)); var tangentSX = (float)Math.Cos(-StartNode.Yaw) * radius; var tangentEX = (float)Math.Cos(-EndNode.Yaw) * radius; var tangentSY = (float)Math.Sin(-StartNode.Yaw) * radius; var tangentEY = (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 y = (float)Ets2CurveHelper.Hermite(s, sy, ey, tangentSY, tangentEY); ps[k] = new PointF(x, y); } RoadPolygons = ps; }
/// <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); }
public IEnumerable <IEnumerable <PointF> > GeneratePolygonCurves(Ets2Node node, int nodeOr) { List <IEnumerable <PointF> > ks = new List <IEnumerable <PointF> >(); var steps = 16; if (nodeOr >= this.Nodes.Count) { nodeOr = 0; } if (Nodes.Any() == false) { return(ks); } //Console.WriteLine("Rendering prefab " + Path.GetFileNameWithoutExtension(FilePath) + " Or " + nodeOr + " yaw " + Math.Round(180.0f/Math.PI*yaw)); var xOr = node.X; var yOr = node.Z; var yaw = node.Yaw - this.Nodes[nodeOr].Yaw + Math.PI / 2; foreach (var curve in Curves) { var ps = new PointF[steps]; var srx = curve.StartX - this.Nodes[nodeOr].X; var erx = curve.EndX - this.Nodes[nodeOr].X; var sry = curve.StartZ - this.Nodes[nodeOr].Z; var ery = curve.EndZ - this.Nodes[nodeOr].Z; var sr = (float)Math.Sqrt(srx * srx + sry * sry); var er = (float)Math.Sqrt(erx * erx + ery * ery); var ans = yaw - Math.Atan2(sry, srx); var ane = yaw - Math.Atan2(ery, erx); var sx = xOr - sr * (float)Math.Sin(ans); var ex = xOr - er * (float)Math.Sin(ane); var sy = yOr - sr * (float)Math.Cos(ans); var ey = yOr - er * (float)Math.Cos(ane); // tmp ps = new PointF[2]; ps[0] = new PointF(sx, sy); ps[1] = new PointF(ex, ey); ks.Add(ps); continue; var tangentSX = (float)Math.Cos(ans) * curve.Length; var tangentEX = (float)Math.Cos(ane) * curve.Length; var tangentSY = (float)Math.Sin(ans) * curve.Length; var tangentEY = (float)Math.Sin(ane) * curve.Length; for (int k = 0; k < steps; k++) { var s = (float)k / (float)steps; var x = (float)Ets2CurveHelper.Hermite(s, sx, ex, tangentSX, tangentEX); var y = (float)Ets2CurveHelper.Hermite(s, sy, ey, tangentSY, tangentEY); ps[k] = new PointF(x, y); } ks.Add(ps); } return(ks); }