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
@@ -126,13 +126,26 @@ fn prefab_house_wall(o) {
|
||||
gaps.push(opening_span(o, m.u, m.p.w));
|
||||
}
|
||||
gaps.sort(|a, b| if a[0] < b[0] { -1 } else if a[0] > b[0] { 1 } else { 0 });
|
||||
let x = -p.w / 2.0 - wall_ext(o, -1.0);
|
||||
let c0 = house_wall_end(o, -1.0);
|
||||
let c1 = house_wall_end(o, 1.0);
|
||||
let x = c0.x;
|
||||
let k = c0.k;
|
||||
for g in gaps {
|
||||
if g[0] > x + 0.01 { wall_run(x, g[0], t, top, p.mat, cap); }
|
||||
if g[0] > x + 0.01 { wall_run(x, k, g[0], 0.0, t, top, p.mat, cap); }
|
||||
if g[1] > x { k = 0.0; }
|
||||
x = fmax(x, g[1]);
|
||||
}
|
||||
let end = p.w / 2.0 + wall_ext(o, 1.0);
|
||||
if end > x + 0.01 { wall_run(x, end, t, top, p.mat, cap); }
|
||||
if c1.x > x + 0.01 { wall_run(x, k, c1.x, c1.k, t, top, p.mat, cap); }
|
||||
}
|
||||
|
||||
/// Where house wall o ends at e (-1 or 1): #{ x, k } (see end_cut); mitred
|
||||
/// at corners and slanted at T-junctions where a wall is diagonal.
|
||||
fn house_wall_end(o, e) {
|
||||
let m = line_meet(o, e, wall_types(), []);
|
||||
if m.kind == "axis" { return end_cut(o.p.w, e, #{ ext: wall_ext(o, e), k: 0.0 }); }
|
||||
if m.kind == "free" { return end_cut(o.p.w, e, #{ ext: o.p.t / 2.0, k: 0.0 }); }
|
||||
if m.kind == "run" { return end_cut(o.p.w, e, #{ ext: 0.0, k: 0.0 }); }
|
||||
end_cut(o.p.w, e, m)
|
||||
}
|
||||
|
||||
/// How far wall o reaches past end e (-1 or 1) of its centre line. Alone:
|
||||
@@ -162,12 +175,14 @@ fn wall_ext(o, e) {
|
||||
ext
|
||||
}
|
||||
|
||||
/// A solid stretch of wall from x0 to x1, one sprite per 30 m at most.
|
||||
fn wall_run(x0, x1, t, top, mat, cap) {
|
||||
/// A solid stretch of wall from x0 to x1 (ends slanted by k0, k1), one
|
||||
/// sprite per 30 m at most.
|
||||
fn wall_run(x0, k0, x1, k1, t, top, mat, cap) {
|
||||
let n = ((x1 - x0) / 30.0).ceiling().to_int();
|
||||
let L = (x1 - x0) / n;
|
||||
for i in 0..n {
|
||||
sprite().box(x0 + i * L, -t, x0 + (i + 1) * L, t, 0.0, top, mat, #{ top: cap });
|
||||
sprite().cut_box(x0 + i * L, if i == 0 { k0 } else { 0.0 }, x0 + (i + 1) * L, if i == n - 1 { k1 } else { 0.0 },
|
||||
-t, t, 0.0, top, mat, #{ top: cap });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user