mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Better Fill type
This commit is contained in:
parent
97141d12a6
commit
173a127d5e
@ -18,9 +18,8 @@ pub enum Primitive {
|
||||
Xor(Id<Primitive>, Id<Primitive>),
|
||||
}
|
||||
|
||||
pub struct Fill {
|
||||
pub prim: Id<Primitive>,
|
||||
pub block: Block,
|
||||
pub enum Fill {
|
||||
Block(Block),
|
||||
}
|
||||
|
||||
impl Fill {
|
||||
@ -63,8 +62,19 @@ impl Fill {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sample_at(&self, tree: &Store<Primitive>, pos: Vec3<i32>) -> Option<Block> {
|
||||
Some(self.block).filter(|_| self.contains_at(tree, self.prim, pos))
|
||||
pub fn sample_at(
|
||||
&self,
|
||||
tree: &Store<Primitive>,
|
||||
prim: Id<Primitive>,
|
||||
pos: Vec3<i32>,
|
||||
) -> Option<Block> {
|
||||
if self.contains_at(tree, prim, pos) {
|
||||
match self {
|
||||
Fill::Block(block) => Some(*block),
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
fn get_bounds_inner(&self, tree: &Store<Primitive>, prim: Id<Primitive>) -> Option<Aabb<i32>> {
|
||||
@ -93,26 +103,25 @@ impl Fill {
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_bounds(&self, tree: &Store<Primitive>) -> Aabb<i32> {
|
||||
self.get_bounds_inner(tree, self.prim)
|
||||
pub fn get_bounds(&self, tree: &Store<Primitive>, prim: Id<Primitive>) -> Aabb<i32> {
|
||||
self.get_bounds_inner(tree, prim)
|
||||
.unwrap_or_else(|| Aabb::new_empty(Vec3::zero()))
|
||||
}
|
||||
}
|
||||
|
||||
pub trait Structure {
|
||||
fn render<F: FnMut(Primitive) -> Id<Primitive>, G: FnMut(Fill)>(
|
||||
fn render<F: FnMut(Primitive) -> Id<Primitive>, G: FnMut(Id<Primitive>, Fill)>(
|
||||
&self,
|
||||
site: &Site,
|
||||
prim: F,
|
||||
fill: G,
|
||||
) {
|
||||
}
|
||||
);
|
||||
|
||||
// Generate a primitive tree and fills for this structure
|
||||
fn render_collect(&self, site: &Site) -> (Store<Primitive>, Vec<Fill>) {
|
||||
fn render_collect(&self, site: &Site) -> (Store<Primitive>, Vec<(Id<Primitive>, Fill)>) {
|
||||
let mut tree = Store::default();
|
||||
let mut fills = Vec::new();
|
||||
let root = self.render(site, |p| tree.insert(p), |f| fills.push(f));
|
||||
let root = self.render(site, |p| tree.insert(p), |p, f| fills.push((p, f)));
|
||||
(tree, fills)
|
||||
}
|
||||
}
|
||||
|
@ -470,16 +470,16 @@ impl Site {
|
||||
|
||||
match &tile.kind {
|
||||
TileKind::Plaza => {
|
||||
let near_roads = CARDINALS
|
||||
.iter()
|
||||
.filter_map(|rpos| if self.tiles.get(tpos + rpos) == tile {
|
||||
let near_roads = CARDINALS.iter().filter_map(|rpos| {
|
||||
if self.tiles.get(tpos + rpos) == tile {
|
||||
Some(Aabr {
|
||||
min: self.tile_wpos(tpos).map(|e| e as f32),
|
||||
max: self.tile_wpos(tpos + 1).map(|e| e as f32),
|
||||
})
|
||||
} else {
|
||||
None
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
cols.for_each(|(wpos2d, offs)| {
|
||||
let wpos2df = wpos2d.map(|e| e as f32);
|
||||
@ -490,18 +490,19 @@ impl Site {
|
||||
|
||||
if dist.map_or(false, |d| d <= 3.0) {
|
||||
let alt = canvas.col(wpos2d).map_or(0, |col| col.alt as i32);
|
||||
(-8..6).for_each(|z| canvas.map(
|
||||
Vec3::new(wpos2d.x, wpos2d.y, alt + z),
|
||||
|b| if z >= 0 {
|
||||
if b.is_filled() {
|
||||
Block::empty()
|
||||
(-8..6).for_each(|z| {
|
||||
canvas.map(Vec3::new(wpos2d.x, wpos2d.y, alt + z), |b| {
|
||||
if z >= 0 {
|
||||
if b.is_filled() {
|
||||
Block::empty()
|
||||
} else {
|
||||
b.with_sprite(SpriteKind::Empty)
|
||||
}
|
||||
} else {
|
||||
b.with_sprite(SpriteKind::Empty)
|
||||
Block::new(BlockKind::Rock, Rgb::new(55, 45, 50))
|
||||
}
|
||||
} else {
|
||||
Block::new(BlockKind::Rock, Rgb::new(55, 45, 50))
|
||||
},
|
||||
));
|
||||
})
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
@ -625,15 +626,15 @@ impl Site {
|
||||
_ => continue,
|
||||
};
|
||||
|
||||
for fill in fills {
|
||||
let aabb = fill.get_bounds(&prim_tree);
|
||||
for (prim, fill) in fills {
|
||||
let aabb = fill.get_bounds(&prim_tree, prim);
|
||||
|
||||
for x in aabb.min.x..aabb.max.x {
|
||||
for y in aabb.min.y..aabb.max.y {
|
||||
for z in aabb.min.z..aabb.max.z {
|
||||
let pos = Vec3::new(x, y, z);
|
||||
|
||||
if let Some(block) = fill.sample_at(&prim_tree, pos) {
|
||||
if let Some(block) = fill.sample_at(&prim_tree, prim, pos) {
|
||||
canvas.set(pos, block);
|
||||
}
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ impl House {
|
||||
}
|
||||
|
||||
impl Structure for House {
|
||||
fn render<F: FnMut(Primitive) -> Id<Primitive>, G: FnMut(Fill)>(
|
||||
fn render<F: FnMut(Primitive) -> Id<Primitive>, G: FnMut(Id<Primitive>, Fill)>(
|
||||
&self,
|
||||
site: &Site,
|
||||
mut prim: F,
|
||||
@ -66,14 +66,11 @@ impl Structure for House {
|
||||
min: self.bounds.min.with_z(self.alt - foundations),
|
||||
max: (self.bounds.max + 1).with_z(self.alt + roof),
|
||||
}));
|
||||
fill(Fill {
|
||||
prim: outer,
|
||||
block: Block::new(BlockKind::Rock, Rgb::new(181, 170, 148)),
|
||||
});
|
||||
fill(Fill {
|
||||
prim: inner,
|
||||
block: Block::empty(),
|
||||
});
|
||||
fill(
|
||||
outer,
|
||||
Fill::Block(Block::new(BlockKind::Rock, Rgb::new(181, 170, 148))),
|
||||
);
|
||||
fill(inner, Fill::Block(Block::empty()));
|
||||
let walls = prim(Primitive::Xor(outer, inner));
|
||||
|
||||
// wall pillars
|
||||
@ -100,10 +97,10 @@ impl Structure for House {
|
||||
pillars_x = prim(Primitive::Or(pillars_x, pillar));
|
||||
}
|
||||
let pillars = prim(Primitive::And(pillars_x, pillars_y));
|
||||
fill(Fill {
|
||||
prim: pillars,
|
||||
block: Block::new(BlockKind::Wood, Rgb::new(55, 25, 8)),
|
||||
});
|
||||
fill(
|
||||
pillars,
|
||||
Fill::Block(Block::new(BlockKind::Wood, Rgb::new(55, 25, 8))),
|
||||
);
|
||||
|
||||
// For each storey...
|
||||
for i in 0..self.levels + 1 {
|
||||
@ -124,10 +121,10 @@ impl Structure for House {
|
||||
}));
|
||||
windows = prim(Primitive::Or(windows, window));
|
||||
}
|
||||
fill(Fill {
|
||||
prim: prim(Primitive::And(walls, windows)),
|
||||
block: Block::air(SpriteKind::Window1).with_ori(2).unwrap(),
|
||||
});
|
||||
fill(
|
||||
prim(Primitive::And(walls, windows)),
|
||||
Fill::Block(Block::air(SpriteKind::Window1).with_ori(2).unwrap()),
|
||||
);
|
||||
}
|
||||
// Windows y axis
|
||||
{
|
||||
@ -143,34 +140,22 @@ impl Structure for House {
|
||||
}));
|
||||
windows = prim(Primitive::Or(windows, window));
|
||||
}
|
||||
fill(Fill {
|
||||
prim: prim(Primitive::And(walls, windows)),
|
||||
block: Block::air(SpriteKind::Window1).with_ori(0).unwrap(),
|
||||
});
|
||||
fill(
|
||||
prim(Primitive::And(walls, windows)),
|
||||
Fill::Block(Block::air(SpriteKind::Window1).with_ori(0).unwrap()),
|
||||
);
|
||||
}
|
||||
|
||||
// Floor
|
||||
fill(Fill {
|
||||
prim: prim(Primitive::Aabb(Aabb {
|
||||
fill(
|
||||
prim(Primitive::Aabb(Aabb {
|
||||
min: self.bounds.min.with_z(self.alt + height),
|
||||
max: (self.bounds.max + 1).with_z(self.alt + height + 1),
|
||||
})),
|
||||
block: Block::new(BlockKind::Rock, Rgb::new(89, 44, 14)),
|
||||
});
|
||||
Fill::Block(Block::new(BlockKind::Rock, Rgb::new(89, 44, 14))),
|
||||
);
|
||||
}
|
||||
|
||||
// Corner pillars
|
||||
// for &rpos in SQUARE_4.iter() {
|
||||
// let pos = self.bounds.min + (self.bounds.max - self.bounds.min) * rpos;
|
||||
// fill(Fill {
|
||||
// prim: prim(Primitive::Aabb(Aabb {
|
||||
// min: Vec3::new(pos.x - 1, pos.y - 1, self.alt - foundations),
|
||||
// max: Vec3::new(pos.x + 1, pos.y + 1, self.alt + roof),
|
||||
// })),
|
||||
// block: Block::new(BlockKind::Wood, Rgb::new(89, 44, 14)),
|
||||
// });
|
||||
// }
|
||||
|
||||
let roof_lip = 2;
|
||||
let roof_height = (self.bounds.min - self.bounds.max)
|
||||
.map(|e| e.abs())
|
||||
@ -180,24 +165,24 @@ impl Structure for House {
|
||||
+ 1;
|
||||
|
||||
// Roof
|
||||
fill(Fill {
|
||||
prim: prim(Primitive::Pyramid {
|
||||
fill(
|
||||
prim(Primitive::Pyramid {
|
||||
aabb: Aabb {
|
||||
min: (self.bounds.min - roof_lip).with_z(self.alt + roof),
|
||||
max: (self.bounds.max + 1 + roof_lip).with_z(self.alt + roof + roof_height),
|
||||
},
|
||||
inset: roof_height,
|
||||
}),
|
||||
block: Block::new(BlockKind::Wood, self.roof_color),
|
||||
});
|
||||
Fill::Block(Block::new(BlockKind::Wood, self.roof_color)),
|
||||
);
|
||||
|
||||
// Foundations
|
||||
fill(Fill {
|
||||
prim: prim(Primitive::Aabb(Aabb {
|
||||
fill(
|
||||
prim(Primitive::Aabb(Aabb {
|
||||
min: (self.bounds.min - 1).with_z(self.alt - foundations),
|
||||
max: (self.bounds.max + 2).with_z(self.alt + 1),
|
||||
})),
|
||||
block: Block::new(BlockKind::Rock, Rgb::new(31, 33, 32)),
|
||||
});
|
||||
Fill::Block(Block::new(BlockKind::Rock, Rgb::new(31, 33, 32))),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user