mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Better house generation
This commit is contained in:
parent
14bac81dc4
commit
9e20d7390f
@ -33,10 +33,11 @@ impl Fill {
|
||||
|
||||
Primitive::Aabb(aabb) => aabb_contains(*aabb, pos),
|
||||
Primitive::Pyramid { aabb, inset } => {
|
||||
let inner = Aabr { min: aabb.min.xy() + *inset, max: aabb.max.xy() - *inset };
|
||||
let inset = (*inset).max(aabb.size().reduce_min());
|
||||
let inner = Aabr { min: aabb.min.xy() - 1 + inset, max: aabb.max.xy() - inset };
|
||||
aabb_contains(*aabb, pos) && (inner.projected_point(pos.xy()) - pos.xy())
|
||||
.map(|e| e.abs())
|
||||
.reduce_max() as f32 / (*inset as f32) < 1.0 - (pos.z - aabb.min.z) as f32 / (aabb.max.z - aabb.min.z) as f32
|
||||
.reduce_max() as f32 / (inset as f32) < 1.0 - ((pos.z - aabb.min.z) as f32 + 0.5) / (aabb.max.z - aabb.min.z) as f32
|
||||
},
|
||||
|
||||
Primitive::And(a, b) => self.contains_at(tree, *a, pos) & self.contains_at(tree, *b, pos),
|
||||
|
@ -241,9 +241,9 @@ impl Site {
|
||||
// House
|
||||
1 => {
|
||||
let size = (2.0 + rng.gen::<f32>().powf(8.0) * 3.0).round() as u32;
|
||||
if let Some((aabr, _)) = attempt(10, || site.find_roadside_aabr(rng, 4..(size + 1).pow(2), Extent2::broadcast(size))) {
|
||||
if let Some((aabr, door_tile)) = attempt(10, || site.find_roadside_aabr(rng, 4..(size + 1).pow(2), Extent2::broadcast(size))) {
|
||||
let plot = site.create_plot(Plot {
|
||||
kind: PlotKind::House(plot::House::generate(land, rng, &site, aabr)),
|
||||
kind: PlotKind::House(plot::House::generate(land, rng, &site, door_tile, aabr)),
|
||||
root_tile: aabr.center(),
|
||||
tiles: aabr_tiles(aabr).collect(),
|
||||
seed: rng.gen(),
|
||||
|
@ -1,22 +1,26 @@
|
||||
use super::*;
|
||||
use crate::Land;
|
||||
use crate::{Land, util::SQUARE_4};
|
||||
use common::terrain::{Block, BlockKind};
|
||||
use vek::*;
|
||||
use rand::prelude::*;
|
||||
|
||||
pub struct House {
|
||||
door_tile: Vec2<i32>,
|
||||
bounds: Aabr<i32>,
|
||||
alt: i32,
|
||||
levels: u32,
|
||||
}
|
||||
|
||||
impl House {
|
||||
pub fn generate(land: &Land, rng: &mut impl Rng, site: &Site, tile_aabr: Aabr<i32>) -> Self {
|
||||
pub fn generate(land: &Land, rng: &mut impl Rng, site: &Site, door_tile: Vec2<i32>, tile_aabr: Aabr<i32>) -> Self {
|
||||
Self {
|
||||
door_tile,
|
||||
bounds: Aabr {
|
||||
min: site.tile_wpos(tile_aabr.min),
|
||||
max: site.tile_wpos(tile_aabr.max),
|
||||
},
|
||||
alt: land.get_alt_approx(site.tile_center_wpos(tile_aabr.center())) as i32,
|
||||
alt: land.get_alt_approx(site.tile_center_wpos(door_tile)) as i32,
|
||||
levels: rng.gen_range(1..3),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -27,36 +31,71 @@ impl Structure for House {
|
||||
mut emit_prim: F,
|
||||
mut emit_fill: G,
|
||||
) {
|
||||
let ceiling = 12;
|
||||
let storey = 8;
|
||||
let roof = storey * self.levels as i32;
|
||||
let foundations = 8;
|
||||
|
||||
// Walls
|
||||
let wall = emit_prim(Primitive::Aabb(Aabb {
|
||||
min: Vec3::new(self.bounds.min.x, self.bounds.min.y, self.alt - 8),
|
||||
max: Vec3::new(self.bounds.max.x, self.bounds.max.y, self.alt + ceiling),
|
||||
min: Vec3::new(self.bounds.min.x, self.bounds.min.y, self.alt - foundations),
|
||||
max: Vec3::new(self.bounds.max.x, self.bounds.max.y, self.alt + roof),
|
||||
}));
|
||||
let inner = emit_prim(Primitive::Aabb(Aabb {
|
||||
min: Vec3::new(self.bounds.min.x + 1, self.bounds.min.y + 1, self.alt - 8),
|
||||
max: Vec3::new(self.bounds.max.x - 1, self.bounds.max.y - 1, self.alt + ceiling),
|
||||
min: Vec3::new(self.bounds.min.x + 1, self.bounds.min.y + 1, self.alt + 0),
|
||||
max: Vec3::new(self.bounds.max.x - 1, self.bounds.max.y - 1, self.alt + roof),
|
||||
}));
|
||||
emit_fill(Fill {
|
||||
prim: emit_prim(Primitive::Xor(wall, inner)),
|
||||
block: Block::new(BlockKind::Rock, Rgb::new(150, 50, 10)),
|
||||
block: Block::new(BlockKind::Rock, Rgb::new(181, 170, 148)),
|
||||
});
|
||||
|
||||
// Floor
|
||||
for i in 0..self.levels + 1 {
|
||||
let height = storey * i as i32;
|
||||
emit_fill(Fill {
|
||||
prim: emit_prim(Primitive::Aabb(Aabb {
|
||||
min: Vec3::new(self.bounds.min.x, self.bounds.min.y, self.alt + height + 0),
|
||||
max: Vec3::new(self.bounds.max.x, self.bounds.max.y, self.alt + height + 1),
|
||||
})),
|
||||
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;
|
||||
emit_fill(Fill {
|
||||
prim: emit_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 = 3;
|
||||
let roof_height = self.bounds.size().reduce_min() / 2 + roof_lip;
|
||||
let roof_height = (self.bounds.min - self.bounds.max).map(|e| e.abs()).reduce_min() / 2 + roof_lip;
|
||||
|
||||
// Roof
|
||||
emit_fill(Fill {
|
||||
prim: emit_prim(Primitive::Pyramid {
|
||||
aabb: Aabb {
|
||||
min: Vec3::new(self.bounds.min.x - roof_lip, self.bounds.min.y - roof_lip, self.alt + ceiling),
|
||||
max: Vec3::new(self.bounds.max.x + roof_lip, self.bounds.max.y + roof_lip, self.alt + ceiling + roof_height),
|
||||
min: Vec3::new(self.bounds.min.x - roof_lip, self.bounds.min.y - roof_lip, self.alt + roof),
|
||||
max: Vec3::new(self.bounds.max.x + roof_lip, self.bounds.max.y + roof_lip, self.alt + roof + roof_height),
|
||||
},
|
||||
inset: roof_height,
|
||||
}),
|
||||
block: Block::new(BlockKind::Wood, Rgb::new(100, 80, 100)),
|
||||
block: Block::new(BlockKind::Wood, Rgb::new(21, 43, 48)),
|
||||
});
|
||||
|
||||
// Foundations
|
||||
emit_fill(Fill {
|
||||
prim: emit_prim(Primitive::Aabb(Aabb {
|
||||
min: Vec3::new(self.bounds.min.x - 1, self.bounds.min.y - 1, self.alt - foundations),
|
||||
max: Vec3::new(self.bounds.max.x + 1, self.bounds.max.y + 1, self.alt + 1),
|
||||
})),
|
||||
block: Block::new(BlockKind::Rock, Rgb::new(31, 33, 32)),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user