Daikoku ramps: chevrons are barrier panels, not deck paint

Corrected against 4K dusk onboard footage of the junction
(jct_tsubasa_dusk, t=110..140s), which shows the previous pass got the
chevrons wrong in kind, not just in placement.

What the footage actually shows: red-and-white chevron delineators are
VERTICAL PANELS mounted on the outside face of the concrete barrier,
running continuously along the outside of each curve. The first pass
built them as flat red slabs lying on the road surface. On the deck they
were nearly invisible from the driver's seat, which defeats the point --
these panels are the main thing that makes a helix legible from inside
the car. Now modelled as 0.5 x 2.0 x segLen panels on the barrier face,
alternating red/white per segment (Roblox part granularity can't put a
diagonal stripe inside a single panel).

Also fixes a placement bug found by measurement. Offsetting the panel
along the raw radial (segMid - O) is correct on the circular arc but
wrong on the straight tangent tail, where the radial is no longer
perpendicular to travel: the panel line walked diagonally across the
deck instead of tracking its edge, up to 33 studs of along-travel error
over the last ~9 segments. Panels now always offset along the true
perpendicular (rightV); the radial only picks which side is outboard.

Measured on the built geometry:

  PAOnRamp   84 segs   0 misaligned   worst along-travel 0.06 studs
  PAOffRamp  64 segs   0 misaligned   worst along-travel 0.08 studs

(excluding the last 3 segments of each ramp, the merge mouth, which
carries no kerb or chevron by design so the merge stays open)

144 panels total, 72 red / 72 white. Ramp geometry is unchanged: grades
still 1.48% / 1.95%, rotation 344 / 282 deg.

Barrier colour was checked at the same time and left alone -- the green
cast in the night footage is sodium-vapour lighting on pale concrete,
not paint. C_PARAPET stays as is.
This commit is contained in:
2026-08-03 05:45:17 -04:00
parent f4f95ec9cc
commit 6c753505f0
+33 -13
View File
@@ -1528,21 +1528,41 @@ local function buildPA(map: Folder)
kerb.Parent = pa
end
-- Red/white shoulder chevrons. Every Shuto ramp carries
-- these on the outside of the curve -- they read as speed
-- cues in the onboard footage and are the main thing that
-- makes a helix legible from inside the car. Alternating
-- segments only, so they stripe rather than smear.
if s % 2 == 0 then
-- Red/white chevron delineators.
--
-- CORRECTED 2026-08-03 against 4K dusk onboard footage of
-- the junction (jct_tsubasa_dusk, t=110..140s). These are
-- NOT road-surface paint, which is what the first pass
-- built -- a flat red slab lying on the deck. In reality
-- they are VERTICAL PANELS bolted to the outside face of
-- the concrete barrier, alternating red and white, running
-- continuously along the outside of the curve. They are
-- the main thing that makes a helix legible from inside
-- the car, and on the deck they were nearly invisible.
--
-- Roblox part granularity can't do a diagonal stripe
-- inside one panel, so alternating whole panels per
-- segment stands in for the diagonal hatching.
--
-- Outward side of the curve. Taking the raw radial
-- (segMid - O) as the offset direction is WRONG on the
-- straight tangent tail: there the radial is no longer
-- perpendicular to travel, so panels skew along the road
-- (measured: up to 33 studs of along-travel error over the
-- last ~9 segments, walking the panel line diagonally
-- across the deck instead of tracking its edge).
--
-- Offset along the true perpendicular `rightV` always, and
-- use the radial ONLY to choose which side is outboard.
local radial = Vector3.new(segMid.X - O.X, 0, segMid.Z - O.Z)
if radial.Magnitude > 0.01 and rightV.Magnitude > 0.01 then
local sgn = (rightV:Dot(radial.Unit) >= 0) and 1 or -1
local face = segMid + rightV * (sgn * RING_W / 2)
local chev = part({
Name = "PARampChevron",
Size = Vector3.new(2.2, 0.4, segLen * 0.55),
CFrame = CFrame.lookAt(
segMid + rightV * (turn * RING_W / 2 * 0.86),
segMid + rightV * (turn * RING_W / 2 * 0.86) + (b - a).Unit,
UP
) * CFrame.new(0, 1.3, 0),
Color = Color3.fromRGB(198, 46, 40),
Size = Vector3.new(0.5, 2.0, segLen),
CFrame = CFrame.lookAt(face, face + (b - a).Unit, UP) * CFrame.new(0, 2.7, 0),
Color = (s % 2 == 0) and Color3.fromRGB(198, 46, 40) or Color3.fromRGB(240, 238, 232),
Material = Enum.Material.SmoothPlastic,
})
chev.Parent = pa