maj00r
2c3ab90db5
fix(track): the tip of a blade lying tangent to its stock rail, as in 60E1 and 49E1 switches with cut tips, is where its theoretical arc gets 5 mm off the gauge face of the stock rail less the 125 mm the nose is planed over, instead of where it gets 3 mm off, so the tips lie 1.25, 1.60, 2.11, 2.63 and 3.34 m from the start of the switch at R190, 300, 500, 760 and 1200 as in the tables of these switches instead of 0.2 to 0.65 m nearer it; blades cutting into the stock rail at an angle, as in S42 switches, keep their tips
2026-10-17 23:32:43 +02:00
maj00r
22dbfb77e6
feat(editor): the tutorial lesson of laying track lists Ctrl+wheel for the radius and Shift+wheel for the shape, the lesson of fixing tells the gizmo can be turned off so the track isn't moved or stretched by chance, and the clips only draw each frame over the last one, so every GIF reader shows them alike
2026-10-17 23:32:43 +02:00
maj00r
0093791067
fix(stb): a GIF frame after one with the disposal "restore to previous" is restored from the frame two back in the output instead of from memory before the start of the output, which crashed the editor at random when the tutorial played its clips
2026-10-17 23:32:43 +02:00
maj00r
513daa52cc
merge feat/rail-crossings: the split rail code, mitred wide crossings, guard rail treads, check rail spacers and frogs for every rail profile, with the geometric switch blades moved into RailCrossings, their shape in track_rails::switch_blade and the lowering of the head in loft_span
2026-10-17 23:32:43 +02:00
maj00r
970c6b52c5
feat(editor): clips of the tutorial lessons (looking around, laying track, curves, joining, switches, fixing), recorded in the editor with a badge of the mouse button or key in use
2026-10-17 23:30:37 +02:00
maj00r
a890087b8b
fix(editor): the tooltip of the Terrain work area is translated
2026-10-17 23:30:37 +02:00
maj00r
dfeb1b9e23
fix(editor): the hints of laying and dragging track (start, starts at the end of, joins, no track fits, moved) are translated
2026-10-17 23:30:37 +02:00
maj00r
2a3d7f2e29
feat(editor): scripted mouse and keys of a self-test are delivered between frames like real input events, so a press seen by ImGui starts a drag as it does by hand; while a script drives the input the real mouse and keyboard are ignored
2026-10-17 23:30:37 +02:00
maj00r
92aa39ce6e
fix(editor): dragging a point of a selected track no longer hands the drag to the gizmo, which jumped under the cursor and lifted the point in the plane of the screen; the gizmo is switched off while a point is dragged
2026-10-17 23:30:37 +02:00
maj00r
d0ebb01c2f
fix(editor): a blank standard orthophoto tile that the geoportal sent while it was busy is removed from the disk cache and fetched once more, instead of staying a black hole in the map for good
2026-10-17 23:30:37 +02:00
maj00r
fc3f391e19
feat(editor): Help > Tutorial instead of First steps: seven lessons (looking around, laying track, curves, joining, switches, selecting and fixing, saving and driving), each with a looping clip from lang/editor_tutorial/<lesson>.gif played from the start on a click, the mouse buttons and keys drawn as pictures beside what they do, ticks that fill in when the user does it, a button that turns the right tool on, Back / Next and a dot per lesson that turns green when it is done
2026-10-17 23:30:37 +02:00
maj00r
6d0423b58a
feat(editor): friendlier track editing: the point labels of a path are translated, a selected switch says that the turnout tool sets its geometry and offers Edit the switch (T), the geometry of its paths starts collapsed, the gizmo options show only on the tabs that use the gizmo, cancelling a laying clears its status and the status of a laying counts pieces and metres
2026-10-17 23:30:37 +02:00
maj00r
1dc61eaf31
feat(editor): scripted mouse and keys for the self-tests and the launcher: mouse, mouseat, glide, button, wheel, press, release, tap, type and softcursor drive the window as the user does, EU07_LAUNCHER_SELFTEST runs a script in the launcher and the scenery wizard and hands an editor script on with editorscript; selectat selects the path nearest a point, switchlink no longer takes over a crossover left in the tool, joints without points logs every issue with free ends
2026-10-17 23:30:37 +02:00
maj00r
58a0b0c864
Merge branch 'feat/track-join-ux' into feat/switch-blades
2026-10-17 23:30:37 +02:00
maj00r
20c4b6542e
feat(track): the blades of a switch whose frog is cut from the rails are made from its geometry: the tip is where the gauge lines of both paths are 3 mm apart, the head reaches its full width where they are a head plus 0.5 mm apart, and the heel is the shortest blade whose open flangeway stays at least 58 mm with a throw of 160 mm bent like a cantilever from the heel, or straight when that does not fit as in slips; the blade is the whole rail profile lofted from the tip to the heel, cut along the head of the stock rail, with the head lowered by the drop of the blade half of the profile file towards the tip and back to the top at a 50 mm head, and thrown with knots every 0.5 m so the vertex count does not change between the positions; the stock rails get stations every 0.5 m along the blades so their curve follows the blade, the fixed rail behind the heel starts at the heel, the old blades take their segment count per path, and the self-test command blade logs the tip, heel, drop, flangeway and the gauge lines against x^2/2R and faults on a short flangeway, a heel past the throat or a change of the vertex count
2026-10-17 23:30:36 +02:00
maj00r
df2bbae449
Merge branch 'feat/rail-crossings' into feat/switch-blades
...
The frogs, crossings and check rails of feat/rail-crossings next to the track editor and the switch paths made of pieces of feat/track-join-ux. The self-test commands of the crossings (frog, geomhash, frogkey, guards, railtime, crossings and switches 0|1, now called throw 0|1 because the editor already has switches) go into their own group selftest_rails.
2026-10-17 23:30:36 +02:00
maj00r
3307cb94e8
feat(track): frogs, crossings, guard rails with their castings and spacers, check rails and shared running surfaces for every rail profile again, not only for tracks without a profile, default, s60, uic60 and s39; grooved profiles keep their shared grooves without check rails
2026-10-17 23:29:08 +02:00
maj00r
306555a654
feat(track): a check rail is held to its running rail by spacer blocks every 0.5 m along its straight part, laid in the same way as the spacers of a guard rail at a wide crossing, below the head from the web of the running rail to the face of the check rail, so the flangeway stays open above them; a check rail replaced by a wing rail gets none; the spacing of spacers and castings is shared by guard rails and check rails
2026-10-17 23:29:08 +02:00
maj00r
16f3a63bb2
fix(track): at a crossing at nearly a right angle the tip of a guard rail under the wheels of the other track takes their rolling surface on its top, bright under a used track and rusty under an unused one, with the sides staying matte, instead of the whole tip going matte because the plain span of the tread was laid as a band between two lines it does not have; plain spans of treads are painted in the debug colour of EU07_EDITOR_TREADS too
2026-10-17 23:29:08 +02:00
maj00r
7d130be3de
fix(track): at a crossing at a wide angle the floor of the flangeway between a running rail and its guard rail is laid only where real crossings have it, as the cast floor of each corner up to 0.3 m past the rail of the other track and as separate spacer blocks every 0.5 m along the rest of the guard, and the floor takes its texture across its width at the scale of the head instead of one stretched column; the wheels of the other track roll over a guard rail across their whole tread instead of only over the head of their rail; and when the tracks cross at nearly a right angle the treads of the other track are laid as plain spans along the rail instead of lines running almost straight across it, which left fins standing up at every edge of a tread
2026-10-17 23:29:08 +02:00
maj00r
df192fc5e0
fix(track): a point of a rail profile clamped to a cut edge of a lofted span is never moved past its own place nor raised past its own height, and the edges at a station are read from the side of the span being laid, so the rings at a step of an edge or at a bent mitred end no longer stretch points out of the profile and stand them up to 18 mm above the head as thin fins at the corners of wide crossings, and points of other cut rails sit exactly on the profile instead of up to a millimetre off it
2026-10-17 23:29:08 +02:00
maj00r
c5df55802f
fix(track): the part of a guard rail under the running rail of the other track at a wide crossing takes the rail material of the other track, whose wheels alone roll there, instead of the brighter of the two, so a guard of a used track under an unused rail stays rusty, and it ends at the head of that rail without a tinted fade, since the guard itself is never rolled on
2026-10-17 23:29:08 +02:00
maj00r
ae4e828ed2
feat(track): at a crossing at a wide angle the tread of the other track is laid where its wheels roll over the mitred corners: the part of a guard rail under the running rail of the other track becomes a running surface in the shared tread material instead of matte, and running rails of different materials share the tread over the rolled band of the other track instead of over a square span; wide_tread draws the edges of the band from the crossing itself, since the gauge lines meet in one point at right angles, and a tread gives its own fade, widened for bands lying across the rail; treaded keeps the matte parts of a guard rail matte, lay_treads splits guard rails at their treads, and a piece of no triangles is not inserted
2026-10-17 23:29:08 +02:00
maj00r
f03c6b8ebc
feat(track): at a crossing at a wide angle every head of one track meets every head of the other in a mitre from the corner of their flangeways to the far corner of the heads, the way the corners of a cast diamond look, so the running rails and guard rails of both tracks form closed corners and only the flangeways stay open, instead of the rails of one track going through and the other ones glued to their sides; corner_cut gives the mitres, as bends of the running rails and as miters of the guard rails; the fit of a loft end to the profile of another rail and the field and gauge outlines of the rail profile are gone with the gluing
2026-10-17 23:29:08 +02:00
maj00r
4016c4ce04
feat(track): the guard rails of a crossing at a wide angle reach a metre past the rails of the other track instead of 0.3 m and open their flangeway over 0.6 m at the ends, the way the guard arms of the corners of a diamond run out on real crossings, the reach and the flare are the constants guard_reach and guard_flare shared by the plan and the layer
2026-10-17 23:29:08 +02:00
maj00r
08d439a2f6
refactor(track): the cap of a lofted rail end takes its texture from cap_texture and its triangles from ear_clip instead of computing both inside cap_loft
2026-10-17 23:29:08 +02:00
maj00r
3d1c97442c
refactor(track): the plates, fillers and check rails of a rail drawing are made from one box_profile and one helper for both sides, and the colour of a tread is sampled by sample_dds and sample_image into one colour_mean, a block of a DXT texture decoded by add_dxt_block, instead of one function
2026-10-17 23:29:08 +02:00
maj00r
697592c4aa
refactor(track): the crossings of the rails are found in steps, the tracks nearby, the meeting of two rails with its refined place and the crossing made of it, and the crossings of the neighbours mapped on this track, and the check rails are planned, merged, kept clear of blocks and cut in separate functions instead of two long functions; path_count and path_neighbour replace the repeated choice of the paths and the ends of a switch or a plain track
2026-10-17 23:29:08 +02:00
maj00r
569194ceae
refactor(track): the rails are planned by the class TTrack::rail_planner instead of one function: each crossing is added by its kind (grooved, wide, acute, obtuse), the acute frog of a crossing and of a switch is one acute_frog and the vee of grooved rails one add_vee, the switch frog is described as a rail_crossing, the corners of crossings at a middle angle are kept as rail_crossing instead of a copy of its fields and framed by frame_guard, wide() takes the crossing and a wide_cut value instead of ten arguments, and the knots are sorted by knots::sort
2026-10-17 23:29:08 +02:00
maj00r
22e378b910
refactor(track): a rail is laid by the class TTrack::rail_layer instead of one function of lambdas sharing a current material and the bends and fits of the ends; a piece of rail is a rail_piece value with its material, the ends of a run are passed as piece_ends, the bands across the top of the head of a running and of a shared tread are laid from one table each by lay_top, the guard and check rails take their flared offsets from one helper, and the grooved profile is split by split_grooved and cut by top_cuts
2026-10-17 23:29:08 +02:00
maj00r
f67380f843
refactor(track): the rail code is split by concern into gauge lines, crossings and check rails, rail materials, rail profile measuring, planning the cuts and laying the geometry, instead of one TrackRails.cpp; rail_offset reuses nearest_distance and lateral; TTrack::rail_dimensions measures the profile through track_rails::measure_rail
2026-10-17 23:29:08 +02:00
maj00r
a88774d279
refactor(track): the rail layout value types (crossings, sizes, check and guard rails, cuts, bands, fills, treads, layout) and the wheel and rail constants live in world/RailLayout.h in track_rails instead of inside TTrack
2026-10-17 23:28:42 +02:00
maj00r
2143cfc043
refactor(track): a lofted rail span is described by one loft_span value instead of twenty arguments, and the knot line helpers (sample, bound, meetings, middle, shifted) live once in world/Knots.h instead of in lambdas of the segment and of lay_rail
2026-10-17 23:28:42 +02:00
maj00r
38c8adaec3
test(editor): geomhash also logs an exact hash of the bits of every vertex value, the userdata and the names of the tread materials, so a refactor can be checked to change nothing
2026-10-17 23:28:42 +02:00
maj00r
2804978464
feat(track): at a crossing at a wide angle the rails and guard rails ending against the side of another rail or guard rail are glued to it, their ends fitted to its profile height by height instead of square ends with caps and a gap of 5 mm, so the corners of the crossing are closed; the ends at the flangeways stay open for the flanges; a loft span can shift its first and last cross-section along the track by a fit given per height of the profile, and the rail profile gives the outlines of its field and gauge sides
2026-10-17 23:28:42 +02:00
maj00r
5544fbc43b
revert(track): no filler block at obtuse crossings, the flangeway between the point rail and the knuckle rail stays open as before
2026-10-17 23:28:41 +02:00
maj00r
c47147d277
fix(track): the filler block of an obtuse crossing ends where the head of the point rail reaches its full width, so it only closes the flangeway and no longer shows as a plate in the widening vee between the point and the knuckle rail
2026-10-17 23:28:41 +02:00
maj00r
7786076bda
feat(track): at a crossing at a wide angle each guard rail is glued to its running rail by a filler block between their webs along its whole length, so the flangeways and the gaps cut for the wheels of the other track have a floor instead of showing the ballast; the filler of the track not going through lies a millimetre lower where both overlap
2026-10-17 23:28:41 +02:00
maj00r
618a3004dd
feat(track): at an obtuse crossing the flangeway between the point rail and the knuckle rail is closed below by a filler block at the height of the webs, from the meeting point to where the point reaches its full profile, so the ballast no longer shows through the gap; the rail profile gives the middle of its web and the height where its head starts above it
2026-10-17 23:28:41 +02:00
maj00r
a30918a95e
fix(track): at an obtuse crossing the rail ending at the meeting point and the rail going on from it are joined by a mitre on the bisector of the bend, like one bent knuckle rail, instead of two square ends overlapping in a wedge, and the check rails of the two tracks meet there the same way instead of overlapping each other by 3 cm; a loft span can turn its first and last cross-section about the gauge line for such joints
2026-10-17 23:28:41 +02:00
maj00r
156c118308
fix(track): the legs of an acute nose are cut along the line halfway between the gauge lines of the two rails, followed every 10 cm from the tip to where the full profiles part, instead of a straight bisector, so the nose of a switch frog with a curved diverging path has no seam opening along its middle
2026-10-17 23:28:41 +02:00
maj00r
649dde731c
fix(track): a loft cut along its length keeps its surface where the cut crosses a point of the profile: each span between stations sorts the points as clamped or open by its middle, so the ring at a station where a point lies right on the edge does not drop the next point to its own height and leave a dark groove along the top of the rail; clamped points that are not on the edge are kept between the heights of the edge on both sides of the run, so they never stand above the surface
2026-10-17 23:28:41 +02:00
maj00r
275f732c66
fix(track): the pieces of the top of a rail head are laid only where they have width on the head between its cut edges, split where the edges of the wheel treads cross those cut edges, and the shared spans reach 2 cm further for the fade, so no inverted piece is drawn inside the neighbouring rail and no fin stands out of the head; EU07_EDITOR_TREADS paints the pieces in plain colours: blue shared, green and red the fades, yellow the edge of the rolled band, magenta the matte part out of reach of the wheels
2026-10-17 23:28:41 +02:00
maj00r
a107b04fcf
fix(track): the treads of the wheels reach from the gauge line as far as a wheel 140 mm wide with the back faces 1360 mm apart does, 820 mm from the axis of a standard gauge track, instead of a flat 100 mm
2026-10-17 23:28:41 +02:00
maj00r
674efade70
feat(track): frogs, crossings and shared running surfaces only for the rail profiles the sceneries of the package use: tracks without a profile, default, s60, uic60 and s39; rails of other profiles are laid whole again
2026-10-17 23:28:41 +02:00
maj00r
7100cec12f
feat(track): the texture of a shared running surface blends into the texture of the rail it lies on: 2 cm on each side of the boundary both are drawn in tinted variants of their materials that fade per vertex into the mean colour of the two treads, sampled from the texture files, so the edge of the wheels of the other track leaves a soft band instead of a line
2026-10-17 23:28:41 +02:00
maj00r
93d512c0f2
fix(track): obtuse crossings share the running surface too: the top of a rail crossed by the treads of the wheels of the other track takes the brighter texture between the gauge line of the other rail and the edge of its treads, so the boundary runs aslant on both sides
2026-10-17 23:28:41 +02:00
maj00r
2c8e8d00c4
fix(track): the shared running surface ends along the edge of the treads of the wheels of the other track, not across the rail: on a nose leg the edge runs aslant over the head, on a stock rail it follows the curve of the other path; only the top of the head takes the other texture, the rest of the rail keeps its own
2026-10-17 23:28:41 +02:00
maj00r
45ef9c470f
fix(track): the two legs of a V nose are cut along the bisector of their gauge lines and meet in the middle as one nose, from a tip 12 mm wide to where their full profiles part, instead of the splice rail giving way under the head of the point rail
2026-10-17 23:28:41 +02:00
maj00r
59446f9a98
fix(track): flat rail frogs have no plates in the V; the shared running surface of a nose leg goes from its tip to where the wheels of the other track stop reaching its head, on the leg only and not on the wing beside it; the stock rail of a switch is shared up to a quarter of the blade length, where the blade head is half its width and takes the wheel
2026-10-17 23:28:41 +02:00