Fix cylinder primitive and better ramp function

This commit is contained in:
Isse 2022-11-30 00:50:41 +01:00
parent dda54bcb01
commit c81fbf50c4
4 changed files with 50 additions and 40 deletions

View File

@ -289,7 +289,8 @@ impl Fill {
- ((pos.z - aabb.min.z) as f32 + 0.5) / (aabb.max.z - aabb.min.z) as f32 - ((pos.z - aabb.min.z) as f32 + 0.5) / (aabb.max.z - aabb.min.z) as f32
}, },
Primitive::Cylinder(aabb) => { Primitive::Cylinder(aabb) => {
let fpos = pos.as_::<f32>().xy() - aabb.as_::<f32>().center().xy(); // Add 0.5 since the aabb is exclusive.
let fpos = pos.as_::<f32>().xy() - aabb.as_::<f32>().center().xy() + 0.5;
let size = Vec3::from(aabb.size().as_::<f32>()).xy(); let size = Vec3::from(aabb.size().as_::<f32>()).xy();
(aabb.min.z..aabb.max.z).contains(&pos.z) (aabb.min.z..aabb.max.z).contains(&pos.z)
&& (2.0 * fpos / size).magnitude_squared() <= 1.0 && (2.0 * fpos / size).magnitude_squared() <= 1.0
@ -980,11 +981,20 @@ impl Painter {
/// Returns a `PrimitiveRef` of an Aabb with a slope cut into it. The /// Returns a `PrimitiveRef` of an Aabb with a slope cut into it. The
/// `inset` governs the slope. The `dir` determines which direction the /// `inset` governs the slope. The `dir` determines which direction the
/// ramp points. /// ramp points.
pub fn ramp(&self, aabb: Aabb<i32>, inset: i32, dir: Dir) -> PrimitiveRef { pub fn ramp_inset(&self, aabb: Aabb<i32>, inset: i32, dir: Dir) -> PrimitiveRef {
let aabb = aabb.made_valid(); let aabb = aabb.made_valid();
self.prim(Primitive::Ramp { aabb, inset, dir }) self.prim(Primitive::Ramp { aabb, inset, dir })
} }
pub fn ramp(&self, aabb: Aabb<i32>, dir: Dir) -> PrimitiveRef {
let aabb = aabb.made_valid();
self.prim(Primitive::Ramp {
aabb,
inset: dir.select((aabb.size().w, aabb.size().h)),
dir,
})
}
/// Returns a `PrimitiveRef` of a triangular prism with the base being /// Returns a `PrimitiveRef` of a triangular prism with the base being
/// vertical. A gable is a tent shape. The `inset` governs the slope of /// vertical. A gable is a tent shape. The `inset` governs the slope of
/// the gable. The `dir` determines which way the gable points. /// the gable. The `dir` determines which way the gable points.
@ -1070,6 +1080,7 @@ impl Painter {
/// | | / /// | | /
/// |_____|/ /// |_____|/
/// ``` /// ```
/// A horizontal half cylinder on top of an `Aabb`.
pub fn vault(&self, aabb: Aabb<i32>, dir: Dir) -> PrimitiveRef { pub fn vault(&self, aabb: Aabb<i32>, dir: Dir) -> PrimitiveRef {
let h = dir.orthogonal().select(Vec3::from(aabb.size()).xy()); let h = dir.orthogonal().select(Vec3::from(aabb.size()).xy());
@ -1150,7 +1161,6 @@ impl Painter {
.with_z(z + 1), .with_z(z + 1),
} }
.made_valid(), .made_valid(),
stair_len + 1,
right, right,
); );

View File

@ -108,7 +108,7 @@ fn aabb(min: Vec3<i32>, max: Vec3<i32>) -> Aabb<i32> {
fn render_short(bridge: &Bridge, painter: &Painter) { fn render_short(bridge: &Bridge, painter: &Painter) {
let (bridge_fill, edge_fill) = match bridge.biome { let (bridge_fill, edge_fill) = match bridge.biome {
BiomeKind::Desert | BiomeKind::Savannah => ( BiomeKind::Desert => (
Fill::Block(Block::new(BlockKind::Rock, Rgb::new(212, 191, 142))), Fill::Block(Block::new(BlockKind::Rock, Rgb::new(212, 191, 142))),
Fill::Block(Block::new(BlockKind::Rock, Rgb::gray(190))), Fill::Block(Block::new(BlockKind::Rock, Rgb::gray(190))),
), ),
@ -130,44 +130,45 @@ fn render_short(bridge: &Bridge, painter: &Painter) {
.reduce_max(); .reduce_max();
let inset = 4; let inset = 4;
let height = bridge.end.z + len / 3 - inset; let top = bridge.end.z + (len / 5).max(8) - inset;
let side = orthogonal * bridge_width; let side = orthogonal * bridge_width;
let remove = painter.vault( let remove = painter.vault(
aabb( aabb(
(bridge.start.xy() - side + forward * inset).with_z(bridge.start.z), (bridge.start.xy() - side + forward * inset).with_z(bridge.start.z),
(bridge.end.xy() + side - forward * inset).with_z(height), (bridge.end.xy() + side - forward * inset).with_z(top - 2),
), ),
orth_dir, orth_dir,
); );
let ramp_in = len / 3; // let outset = 7;
let top = height + 2;
let outset = 7;
let up_ramp = |point: Vec3<i32>, dir: Dir, side_len: i32| { let up_ramp = |point: Vec3<i32>, dir: Dir, side_len: i32| {
let forward = dir.to_vec2(); let forward = dir.to_vec2();
let side = dir.orthogonal().to_vec2() * side_len; let side = dir.orthogonal().to_vec2() * side_len;
painter.ramp( let ramp_in = top - point.z;
aabb( painter
(point.xy() - side - forward * (top - point.z - ramp_in + outset)) .ramp(
.with_z(bridge.start.z), aabb(
(point.xy() + side + forward * ramp_in).with_z(top), point - side,
), (point.xy() + side + forward * ramp_in).with_z(top),
top - point.z + 1 + outset, ),
dir, dir,
) )
.union(painter.aabb(aabb(
(point - side).with_z(point.z - 4),
point + side + forward * ramp_in,
)))
}; };
let bridge_prim = |side_len: i32| { let bridge_prim = |side_len: i32| {
let side = orthogonal * side_len; let side = orthogonal * side_len;
painter painter
.aabb(aabb( .aabb(aabb(
(bridge.start.xy() - side + forward * ramp_in).with_z(bridge.start.z), (bridge.start.xy() - side + forward * (top - bridge.start.z))
(bridge.end.xy() + side - forward * ramp_in).with_z(top), .with_z(bridge.start.z),
(bridge.end.xy() + side - forward * (top - bridge.end.z)).with_z(top),
)) ))
.union(up_ramp(bridge.start, bridge.dir, side_len).union(up_ramp( .union(up_ramp(bridge.start, bridge.dir, side_len).union(up_ramp(
bridge.end, bridge.end,
@ -178,18 +179,20 @@ fn render_short(bridge: &Bridge, painter: &Painter) {
let b = bridge_prim(bridge_width); let b = bridge_prim(bridge_width);
/*
let t = 4; let t = 4;
b.union( b.union(
painter.aabb(aabb( painter.aabb(aabb(
(bridge.start.xy() - side - forward * (top - bridge.start.z - ramp_in + outset)) (bridge.start.xy() - side - forward * (top - bridge.start.z))
.with_z(bridge.start.z - t), .with_z(bridge.start.z - t),
(bridge.end.xy() + side + forward * (top - bridge.end.z - ramp_in + outset)) (bridge.end.xy() + side + forward * (top - bridge.end.z))
.with_z(bridge.start.z), .with_z(bridge.start.z),
)), )),
) )
.translate(Vec3::new(0, 0, t)) .translate(Vec3::new(0, 0, t))
.without(b) .without(b)
.clear(); .clear();
*/
b.without(remove).fill(bridge_fill); b.without(remove).fill(bridge_fill);
@ -198,8 +201,8 @@ fn render_short(bridge: &Bridge, painter: &Painter) {
prim.translate(Vec3::unit_z()) prim.translate(Vec3::unit_z())
.without(prim) .without(prim)
.without(painter.aabb(aabb( .without(painter.aabb(aabb(
bridge.start - side - forward * outset, bridge.start - side - forward,
(bridge.end.xy() + side + forward * outset).with_z(top + 1), (bridge.end.xy() + side + forward).with_z(top + 1),
))) )))
.fill(edge_fill); .fill(edge_fill);
} }
@ -237,7 +240,6 @@ fn render_flat(bridge: &Bridge, painter: &Painter) {
ramp_aabr.min.with_z(bridge.start.z + offset), ramp_aabr.min.with_z(bridge.start.z + offset),
ramp_aabr.max.with_z(bridge.end.z + offset), ramp_aabr.max.with_z(bridge.end.z + offset),
), ),
height + 1,
bridge.dir, bridge.dir,
)) ))
}; };
@ -340,7 +342,7 @@ fn render_heightened_viaduct(bridge: &Bridge, painter: &Painter, data: &Heighten
let ramp_in_aabr = |aabr: Aabr<i32>, dir: Dir, zmin, zmax| { let ramp_in_aabr = |aabr: Aabr<i32>, dir: Dir, zmin, zmax| {
let inset = dir.select(aabr.size()); let inset = dir.select(aabr.size());
painter.ramp( painter.ramp_inset(
aabb(aabr.min.with_z(zmin), aabr.max.with_z(zmax)), aabb(aabr.min.with_z(zmin), aabr.max.with_z(zmax)),
inset, inset,
dir, dir,
@ -565,7 +567,7 @@ fn render_tower(bridge: &Bridge, painter: &Painter, roof_kind: &RoofKind) {
painter painter
.aabb(ramp_aabb) .aabb(ramp_aabb)
.without(painter.ramp(ramp_aabb, ramp_height, -bridge.dir)) .without(painter.ramp(ramp_aabb, -bridge.dir))
.clear(); .clear();
let c = bridge.dir.select_aabr_with(tower_aabr, tower_aabr.center()); let c = bridge.dir.select_aabr_with(tower_aabr, tower_aabr.center());
@ -755,7 +757,7 @@ fn render_hang(bridge: &Bridge, painter: &Painter) {
)) ))
.fill(rock.clone()); .fill(rock.clone());
painter painter
.ramp( .ramp_inset(
aabb(ramp_f.min.with_z(bridge.start.z), ramp_f.max.with_z(top)), aabb(ramp_f.min.with_z(bridge.start.z), ramp_f.max.with_z(top)),
top - bridge.start.z + 1, top - bridge.start.z + 1,
bridge.dir, bridge.dir,
@ -772,7 +774,6 @@ fn render_hang(bridge: &Bridge, painter: &Painter) {
painter painter
.ramp( .ramp(
aabb(ramp_b.min.with_z(bridge.end.z), ramp_b.max.with_z(top)), aabb(ramp_b.min.with_z(bridge.end.z), ramp_b.max.with_z(top)),
top - bridge.end.z,
-bridge.dir, -bridge.dir,
) )
.fill(rock.clone()); .fill(rock.clone());

View File

@ -349,7 +349,7 @@ impl Structure for DesertCityMultiPlot {
.clear(); .clear();
// Stairs for each storey // Stairs for each storey
painter painter
.ramp( .ramp_inset(
Aabb { Aabb {
min: Vec2::new(center.x - room_length, center.y - room_length + 1) min: Vec2::new(center.x - room_length, center.y - room_length + 1)
.with_z(floor_level), .with_z(floor_level),
@ -1016,7 +1016,7 @@ impl Structure for DesertCityMultiPlot {
.clear(); .clear();
// Stairs for each storey // Stairs for each storey
painter painter
.ramp( .ramp_inset(
Aabb { Aabb {
min: Vec2::new( min: Vec2::new(
subplot_center.x - room_length, subplot_center.x - room_length,
@ -1628,7 +1628,6 @@ impl Structure for DesertCityMultiPlot {
) )
.with_z(base + tower_height + 1), .with_z(base + tower_height + 1),
}, },
2,
Dir::NegX, Dir::NegX,
) )
.fill(sandstone.clone()); .fill(sandstone.clone());

View File

@ -241,7 +241,7 @@ impl Structure for SeaChapel {
}) })
.fill(white.clone()); .fill(white.clone());
painter painter
.ramp( .ramp_inset(
Aabb { Aabb {
min: Vec3::new( min: Vec3::new(
center.x - (diameter / 2) - 12, center.x - (diameter / 2) - 12,
@ -275,7 +275,7 @@ impl Structure for SeaChapel {
}) })
.fill(white.clone()); .fill(white.clone());
painter painter
.ramp( .ramp_inset(
Aabb { Aabb {
min: Vec3::new( min: Vec3::new(
center.x + (diameter / 2) - 2, center.x + (diameter / 2) - 2,
@ -3059,7 +3059,7 @@ impl Structure for SeaChapel {
.fill(window_ver.clone()); .fill(window_ver.clone());
// chapel main room pulpit stairs1 // chapel main room pulpit stairs1
painter painter
.ramp( .ramp_inset(
Aabb { Aabb {
min: Vec3::new(center.x - 8, center.y - (diameter / 4) - 2, base - 3), min: Vec3::new(center.x - 8, center.y - (diameter / 4) - 2, base - 3),
max: Vec3::new(center.x - 3, center.y - (diameter / 4) + 7, base + 2), max: Vec3::new(center.x - 3, center.y - (diameter / 4) + 7, base + 2),
@ -3070,7 +3070,7 @@ impl Structure for SeaChapel {
.fill(white.clone()); .fill(white.clone());
// chapel main room pulpit stairs2 // chapel main room pulpit stairs2
painter painter
.ramp( .ramp_inset(
Aabb { Aabb {
min: Vec3::new(center.x + 3, center.y - (diameter / 4) - 2, base - 3), min: Vec3::new(center.x + 3, center.y - (diameter / 4) - 2, base - 3),
max: Vec3::new(center.x + 8, center.y - (diameter / 4) + 7, base + 2), max: Vec3::new(center.x + 8, center.y - (diameter / 4) + 7, base + 2),
@ -3081,7 +3081,7 @@ impl Structure for SeaChapel {
.fill(white.clone()); .fill(white.clone());
// chapel main room pulpit stairs2 // chapel main room pulpit stairs2
painter painter
.ramp( .ramp_inset(
Aabb { Aabb {
min: Vec3::new(center.x - 8, center.y + (diameter / 4) - 7, base - 3), min: Vec3::new(center.x - 8, center.y + (diameter / 4) - 7, base - 3),
max: Vec3::new(center.x - 3, center.y + (diameter / 4) + 2, base + 2), max: Vec3::new(center.x - 3, center.y + (diameter / 4) + 2, base + 2),
@ -3092,7 +3092,7 @@ impl Structure for SeaChapel {
.fill(white.clone()); .fill(white.clone());
// chapel main room pulpit stairs4 // chapel main room pulpit stairs4
painter painter
.ramp( .ramp_inset(
Aabb { Aabb {
min: Vec3::new(center.x + 3, center.y + (diameter / 4) - 7, base - 3), min: Vec3::new(center.x + 3, center.y + (diameter / 4) - 7, base - 3),
max: Vec3::new(center.x + 8, center.y + (diameter / 4) + 2, base + 2), max: Vec3::new(center.x + 8, center.y + (diameter / 4) + 2, base + 2),