Diagonals: streets, walls, fences, hedges and house walls at any angle
Deploy web Studio / deploy (push) Successful in 1m5s
Deploy web Studio / deploy (push) Successful in 1m5s
Object frames turn by any angle (quarter turns stay exact, so scenes along the axes render byte for byte as before); a box in a turned frame is a prism with its own corners. Rotation is kept as given (normalised to 0..360), no longer snapped to quarter turns. Depth sort: sprites whose plan outline is not their box carry their convex outline; when boxes overlap, an outline edge that separates two sprites orders them. A long diagonal wall sorts right against both sides. Joints (line_meet, end_cut, cut_box in util.rhai): where a piece off the axes is involved, corners are mitred and T-junctions slanted; fences put a corner post or pillar in its own sprite and mitre stone bases; Y joints let the lowest id run through. Streets: every end part is a cut e + k*w, so side streets come in at any angle (slanted sidewalk gaps), two streets meet in a mitre with seam patches; fixes a curve's outer sidewalk that was skipped when its kerb and back lines had different point counts. Studio: runs and drags keep to x/y or snap to 45 degree diagonals, Ctrl gives any angle; a road run turning 45 degrees gets a 45 degree curve; Rotation is a number box. Streets demo: a diagonal lane with a hedge. MCP guidance, SCRIPTING/README/ROADMAP. Tests: Rust 76, Studio and web checks green.
This commit is contained in:
1 parent
c91d63663b
commit
96d472625f
18 files changed
+1051
-178
No files matched your search
+38
-8
@@ -66,7 +66,7 @@ shaded automatically by face direction.
|
||||
| `objects_on(types, x, y, tol)` | … whose centre line (local x, length `p.w`) passes within `p.t / 2 + tol` of the point, with `u, v` = the point in their frame |
|
||||
| `mount_of(o, hosts[, tol])` | the host o sits on (nearest centre line within `p.t / 2 + tol`, default 0.3 m, same height), with `u, v` = o's position in the host's frame; `()` if none |
|
||||
| `mounted(h, types, hosts[, tol])` | the objects of `types` whose host is h, each with `u, v` |
|
||||
| `frame(o)`, `frame(x, y, z, rot)` | draw in another frame from here on (a window draws in its wall's frame) |
|
||||
| `frame(o)`, `frame(x, y, z, rot)` | draw in another frame from here on (a window draws in its wall's frame); `rot` is any angle in degrees (quarter turns stay exact) |
|
||||
| `to_world(x, y)`, `to_local(x, y)`, `local_of(o, x, y)`, `world_of(o, u, v)` | between the current frame (or o's) and world plan coordinates |
|
||||
| `vis(nx, ny)` | is a face with that outward normal turned to the viewer? |
|
||||
| `dv(dx, dy, dz)` | screen vector of a world vector (CSS motion) |
|
||||
@@ -122,6 +122,29 @@ depth sort needs. `fence` (designs `style`: mesh, wood, bars, half stone,
|
||||
cobble, brick) and the site `wall` use it; `house_wall` has its own version
|
||||
(`wall_ext`, house.rhai).
|
||||
|
||||
### Diagonal pieces
|
||||
|
||||
Objects turn by any angle (`rot` in degrees); a box drawn in a turned frame
|
||||
becomes a prism with its own four corners. Where a piece off the axes is
|
||||
involved, `line_meet(o, e, same, stops)` (util.rhai) replaces the rules above
|
||||
for that end: `#{ kind, ext, k, ... }` with kind `axis` (every piece there
|
||||
keeps to the axes: use the old rules, so such scenes draw as before),
|
||||
`free`, `run` (in line), `corner` (a mitre on the bisector; `owner` draws a
|
||||
fence's corner post) or `tee` (stop at the other's face). The end is
|
||||
slanted: the line `v` to the piece's left reaches `ext + k * v` past it.
|
||||
`end_cut(w, e, m)` turns that into `#{ x, k }` and `s.cut_box(x0, k0, x1, k1,
|
||||
y0, y1, z0, z1, mat[, opts])` draws a box with such ends. Fences put their
|
||||
corner post (or brick pillar) in its own sprite and stop their panels at it;
|
||||
stone bases and cobble walls are mitred. Helpers: `on_axes(rot)`,
|
||||
`dir_of(o)`, `dot2(a, b)`.
|
||||
|
||||
The depth sort keeps diagonal pieces right through outlines: a sprite whose
|
||||
plan outline is not its box (turned or mitred pieces) carries its convex
|
||||
outline, and when two boxes overlap an outline edge that separates them
|
||||
orders them, the one on the viewer's side going later. A long diagonal wall
|
||||
therefore sorts right against everything on either side of it, and mitred
|
||||
pieces against each other.
|
||||
|
||||
## Production lines
|
||||
|
||||
`producer`, `conveyor` and `robot_arm` (stdlib/industry.rhai) work together
|
||||
@@ -166,12 +189,16 @@ ground.rhai) meet by their centre lines:
|
||||
arcs when cut and offset, so a curve meets a straight road exactly.
|
||||
- End to end (a curve continuing a road, a road continuing a roundabout arm)
|
||||
the pieces carry on, overlapping by 4 cm so no hairline shows.
|
||||
- A street ending on a road's centre line makes a T: the road leaves a gap in
|
||||
its kerb and sidewalk on that side, the street stops its centre line and
|
||||
kerbs at the road's edge and its sidewalks at the road's sidewalk.
|
||||
- Two roads ending at one point at right angles close the corner: both run
|
||||
over it, the inner sidewalks stop at the other road's kerb, the outer ones
|
||||
go round.
|
||||
- A street ending on a road's centre line makes a T, at any angle: the road
|
||||
leaves a gap in its kerb and sidewalk on that side (slanted along the
|
||||
street coming in), the street ends its asphalt on the road's centre line,
|
||||
its centre line and kerbs at the road's edge and its sidewalks at the
|
||||
road's sidewalk.
|
||||
- Two streets ending at one point at any angle meet in a mitre on the
|
||||
bisector (thin seam patches reach over it, so no hairline shows).
|
||||
- Every part of a street end is a cut `#{ e, k }`: the line `w` to the left
|
||||
looking out reaches `e + k * w` past the end (`street_join`); gaps are
|
||||
`#{ lo, hi, c }` ranges that slant with the side offset (`street_gaps`).
|
||||
- A roundabout's arms end `r + arm_len` from its centre, along its local
|
||||
+x, +y, -x, -y. Its kerbs flare into the ring with a fillet; splitter
|
||||
islands and give-way lines sit on the entry side for `drive` left or right.
|
||||
@@ -220,7 +247,10 @@ These are lessons from the CNX/Mooban views, and the engine relies on them:
|
||||
the same sprite as the storey below. Start walls and furniture standing on
|
||||
them a little above the floor (+0.02 m).
|
||||
- **Movers** (`drive`) run along the axis the sort compares second
|
||||
(`along_x()`). Along the other axis they stay still.
|
||||
(`along_x()`). Along the other axis (and on diagonals) they stay still.
|
||||
- **Diagonal pieces** sort by their outlines (see Diagonal pieces), so they
|
||||
need no extra splitting; things standing exactly on a wall's line still
|
||||
interpenetrate it and sort by their centres.
|
||||
- Street furniture stays off drive areas, and pipe runs end on walls or supports.
|
||||
|
||||
## Themes
|
||||
|
||||
Reference in new issue
Block a user