Skip to content

Striping smarts: hatched as a width-cropping generator (#1728) + auto-striping on segment edits - #1907

Draft
kfarr wants to merge 2 commits into
mainfrom
claude/epic-1720-task-groupings-mdfxie
Draft

Striping smarts: hatched as a width-cropping generator (#1728) + auto-striping on segment edits#1907
kfarr wants to merge 2 commits into
mainfrom
claude/epic-1720-task-groupings-mdfxie

Conversation

@kfarr

@kfarr kfarr commented Aug 4, 2026

Copy link
Copy Markdown
Collaborator

Part of epic #1720. Closes #1728. Covers three related items from §2/§3:

  1. Convert hatched from a segment surface to a striping generator that crops to segment width (Convert hatched from a segment surface type to a clone/striping generator #1728)
  2. Auto-striping on segment type/direction change (§3: "if a lane is changed double check its neighbors to see if they need striping adjustments")
  3. Confirm street-generated-pedestrians handles inbound (the remaining checkbox blocking bug: direction of parking and street lamps incorrect when importing from streetmix #1282)

1. Hatched → generator (#1728)

Hatching is now a street-generated-striping treatment (striping: hatched) instead of a street-segment surface material. The generator renders a full-width plane whose square seamless texture tiles at a fixed 4m period in both axes, so the diagonal bars keep their natural angle and density and crop to the segment width instead of stretching across it (the old surface behavior over/under-extended on narrow/wide dividers).

Acceptance criteria from the ticket:

  • ✅ Hatching is produced by a repeating generator that fits/crops to the segment width — new hatched value in street-generated-striping
  • ✅ The divider preset uses the generator, not surface: hatched — preset is now surface: asphalt + generated.striping: [{striping: hatched}]; the streetmix importer attaches the same generator (street-generated-striping__2, keeping clear of the bare edge-stripe slot) to every divider-preset segment
  • ✅ Streetmix import parity preserved — dividers render asphalt + hatch bars as before, minus the stretching
  • ✅ Existing scenes still render — three migration paths:
    • json-blob imports (parseStreetObject): surface: hatched rewritten on the fly to asphalt + a hatched striping entry
    • saved scenes: migrateSegmentHatchedSurface in createEntityFromObj, following the existing levelelevation / buildingboundary migration pattern (handles prop-string and object forms, picks the first free striping slot)
    • belt and suspenders: hatched stays in textureMaps as a deprecated render alias, but is removed from the pickable surface oneOf (it left the dropdown; Fix/1728 segment sidebar surface update #1730 had only kept it there because the divider preset set it)

2. Auto-striping on segment edits

When a segment's type or direction changes, managed-street recomputes the auto separator stripes on the segment's two shared edges:

  • flip one of two same-direction drive lanes to opposing → separator becomes solid-doubleyellow
  • change a lane to a sidewalk → the now-stale separator on the neighboring edge is removed
  • change a lane to a divider → the preset regenerates the hatch, and a solid-stripe edge line is added against the adjacent lane

Mechanics: street-segment now includes directionChanged in its segment-changed emit (generators already self-guard on width/length, so no spurious clone regeneration). managed-street.updateAutoStriping reuses the same getStripingFromSegments rules as import, only touches left-side separator slots, and never touches full-width hatched treatments or user right-side stripes. getStripingFromSegments also gained the streetmix importer's divider rule (edge stripe where a divider meets a lane, none between adjacent dividers), so edit-time recompute, json-blob import, and streetmix import all agree.

Undo-friendliness: the recompute is reactive — undoing the type/direction change re-fires the event and the stripes recompute back.

3. Pedestrians inbound (#1282)

street-generated-pedestrians handled inbound only as an implicit fallthrough (no rotation set, relying on the entity default of 0 — which happens to match the clones convention of inbound = 0 / outbound = 180). The branch is now explicit with the convention documented. No behavior change; this confirms the remaining epic checkbox for #1282.

Tests

  • test/components/managed-street-striping.test.js (browser-mode, real Chromium): import migration of a hatched divider, hatch plane geometry (full width, centered, 4m tiling), divider edge stripes on both sides, direction-flip → double yellow, type→divider → hatch + edge stripe in the next free slot, type→sidewalk → stale separator removed
  • test/core/street-segment-utils.test.js: 6 new unit tests for migrateSegmentHatchedSurface (string/object forms, slot collision, no-ops)
  • Full suite green: test:core 195 passing, test:modern 762 passing, test:components 64 passing; lint + prettier clean

Notes for review

  • The hatch texture (hatched-base, 512² seamless) has its asphalt background baked in, so the plane renders opaque above the segment's (now asphalt) surface — same look as before at lane scale.
  • Old exports of hatched dividers migrate to asphalt + hatch but do not gain the new divider edge stripes (the migration writes an explicit striping list, which suppresses import-side auto-striping) — they keep looking as authored.

🤖 Generated with Claude Code

https://claude.ai/code/session_016fuSkZRhP57HDz5RvoELK5


Generated by Claude Code

claude added 2 commits August 4, 2026 03:43
…ent edits (#1728)

Hatched is no longer a street-segment surface material. It is now a
street-generated-striping treatment (striping: hatched) that renders a
full-width plane whose square seamless texture tiles at a fixed 4m period
in both axes, so the diagonal bars keep their natural angle and crop to
the segment width instead of stretching across it.

- divider type preset now uses surface: asphalt + a generated hatched
  striping entry; the streetmix importer attaches the same generator to
  divider-preset segments
- surface: hatched is removed from the pickable surface list but still
  renders (deprecated alias in textureMaps) so un-migrated content works
- migrations: json-blob imports rewrite surface: hatched on the fly
  (parseStreetObject); saved scenes migrate at load via
  migrateSegmentHatchedSurface in createEntityFromObj

Auto-striping on segment edits (#1720 §3): when a segment's type or
direction changes, managed-street recomputes the separator stripes on the
segment's shared edges (e.g. two drive lanes get a double yellow once
their directions oppose; a lane that becomes a sidewalk loses its
separator). street-segment now emits directionChanged in segment-changed
to feed this. getStripingFromSegments also gained the streetmix
importer's divider rule: an edge stripe where a divider meets a lane,
none between adjacent dividers.

Covered by new browser-mode component tests (import migration, hatch
plane geometry, divider edge stripes, type/direction recompute) and unit
tests for the saved-scene migration.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016fuSkZRhP57HDz5RvoELK5
street-generated-pedestrians handled inbound only as an implicit
fallthrough (no rotation attribute, relying on the default of 0, which
happens to match the clones convention of inbound = 0 / outbound = 180).
Make the branch explicit so the direction contract is visible and the
epic checkbox "confirm street-generated-pedestrians handles inbound" can
close. No behavior change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016fuSkZRhP57HDz5RvoELK5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Convert hatched from a segment surface type to a clone/striping generator

2 participants