mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Fixed stupid generation bugs, made houses more interesting
This commit is contained in:
parent
7bf62d59fd
commit
5fd93ee5e5
@ -1,3 +1,4 @@
|
|||||||
|
use super::*;
|
||||||
use common::{
|
use common::{
|
||||||
terrain::Block,
|
terrain::Block,
|
||||||
store::{Id, Store},
|
store::{Id, Store},
|
||||||
@ -26,7 +27,8 @@ impl Fill {
|
|||||||
fn contains_at(&self, tree: &Store<Primitive>, prim: Id<Primitive>, pos: Vec3<i32>) -> bool {
|
fn contains_at(&self, tree: &Store<Primitive>, prim: Id<Primitive>, pos: Vec3<i32>) -> bool {
|
||||||
// Custom closure because vek's impl of `contains_point` is inclusive :(
|
// Custom closure because vek's impl of `contains_point` is inclusive :(
|
||||||
let aabb_contains = |aabb: Aabb<i32>, pos: Vec3<i32>| (aabb.min.x..aabb.max.x).contains(&pos.x)
|
let aabb_contains = |aabb: Aabb<i32>, pos: Vec3<i32>| (aabb.min.x..aabb.max.x).contains(&pos.x)
|
||||||
&& (aabb.min.y..aabb.max.y).contains(&pos.y);
|
&& (aabb.min.y..aabb.max.y).contains(&pos.y)
|
||||||
|
&& (aabb.min.z..aabb.max.z).contains(&pos.z);
|
||||||
|
|
||||||
match &tree[prim] {
|
match &tree[prim] {
|
||||||
Primitive::Empty => false,
|
Primitive::Empty => false,
|
||||||
@ -40,8 +42,8 @@ impl Fill {
|
|||||||
.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
|
.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),
|
Primitive::And(a, b) => self.contains_at(tree, *a, pos) && self.contains_at(tree, *b, pos),
|
||||||
Primitive::Or(a, b) => self.contains_at(tree, *a, pos) | self.contains_at(tree, *b, pos),
|
Primitive::Or(a, b) => self.contains_at(tree, *a, pos) || self.contains_at(tree, *b, pos),
|
||||||
Primitive::Xor(a, b) => self.contains_at(tree, *a, pos) ^ self.contains_at(tree, *b, pos),
|
Primitive::Xor(a, b) => self.contains_at(tree, *a, pos) ^ self.contains_at(tree, *b, pos),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -68,15 +70,16 @@ impl Fill {
|
|||||||
pub trait Structure {
|
pub trait Structure {
|
||||||
fn render<F: FnMut(Primitive) -> Id<Primitive>, G: FnMut(Fill)>(
|
fn render<F: FnMut(Primitive) -> Id<Primitive>, G: FnMut(Fill)>(
|
||||||
&self,
|
&self,
|
||||||
|
site: &Site,
|
||||||
prim: F,
|
prim: F,
|
||||||
fill: G,
|
fill: G,
|
||||||
) {}
|
) {}
|
||||||
|
|
||||||
// Generate a primitive tree and fills for this structure
|
// Generate a primitive tree and fills for this structure
|
||||||
fn render_collect(&self) -> (Store<Primitive>, Vec<Fill>) {
|
fn render_collect(&self, site: &Site) -> (Store<Primitive>, Vec<Fill>) {
|
||||||
let mut tree = Store::default();
|
let mut tree = Store::default();
|
||||||
let mut fills = Vec::new();
|
let mut fills = Vec::new();
|
||||||
let root = self.render(|p| tree.insert(p), |f| fills.push(f));
|
let root = self.render(site, |p| tree.insert(p), |f| fills.push(f));
|
||||||
(tree, fills)
|
(tree, fills)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -437,7 +437,7 @@ impl Site {
|
|||||||
|
|
||||||
for plot in plots_to_render {
|
for plot in plots_to_render {
|
||||||
let (prim_tree, fills) = match &self.plots[plot].kind {
|
let (prim_tree, fills) = match &self.plots[plot].kind {
|
||||||
PlotKind::House(house) => house.render_collect(),
|
PlotKind::House(house) => house.render_collect(self),
|
||||||
_ => continue,
|
_ => continue,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,11 +1,12 @@
|
|||||||
use super::*;
|
use super::*;
|
||||||
use crate::{Land, util::SQUARE_4};
|
use crate::{Land, util::SQUARE_4};
|
||||||
use common::terrain::{Block, BlockKind};
|
use common::terrain::{Block, BlockKind, SpriteKind};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
use rand::prelude::*;
|
use rand::prelude::*;
|
||||||
|
|
||||||
pub struct House {
|
pub struct House {
|
||||||
door_tile: Vec2<i32>,
|
door_tile: Vec2<i32>,
|
||||||
|
tile_aabr: Aabr<i32>,
|
||||||
bounds: Aabr<i32>,
|
bounds: Aabr<i32>,
|
||||||
alt: i32,
|
alt: i32,
|
||||||
levels: u32,
|
levels: u32,
|
||||||
@ -15,11 +16,12 @@ impl House {
|
|||||||
pub fn generate(land: &Land, rng: &mut impl Rng, site: &Site, door_tile: Vec2<i32>, 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 {
|
Self {
|
||||||
door_tile,
|
door_tile,
|
||||||
|
tile_aabr,
|
||||||
bounds: Aabr {
|
bounds: Aabr {
|
||||||
min: site.tile_wpos(tile_aabr.min),
|
min: site.tile_wpos(tile_aabr.min),
|
||||||
max: site.tile_wpos(tile_aabr.max),
|
max: site.tile_wpos(tile_aabr.max),
|
||||||
},
|
},
|
||||||
alt: land.get_alt_approx(site.tile_center_wpos(door_tile)) as i32,
|
alt: land.get_alt_approx(site.tile_center_wpos(door_tile)) as i32 + 2,
|
||||||
levels: rng.gen_range(1..3),
|
levels: rng.gen_range(1..3),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -28,15 +30,16 @@ impl House {
|
|||||||
impl Structure for House {
|
impl Structure for House {
|
||||||
fn render<F: FnMut(Primitive) -> Id<Primitive>, G: FnMut(Fill)>(
|
fn render<F: FnMut(Primitive) -> Id<Primitive>, G: FnMut(Fill)>(
|
||||||
&self,
|
&self,
|
||||||
|
site: &Site,
|
||||||
mut prim: F,
|
mut prim: F,
|
||||||
mut fill: G,
|
mut fill: G,
|
||||||
) {
|
) {
|
||||||
let storey = 8;
|
let storey = 6;
|
||||||
let roof = storey * self.levels as i32;
|
let roof = storey * self.levels as i32;
|
||||||
let foundations = 8;
|
let foundations = 12;
|
||||||
|
|
||||||
// Walls
|
// Walls
|
||||||
let wall = prim(Primitive::Aabb(Aabb {
|
let outer = prim(Primitive::Aabb(Aabb {
|
||||||
min: Vec3::new(self.bounds.min.x, self.bounds.min.y, self.alt - foundations),
|
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),
|
max: Vec3::new(self.bounds.max.x, self.bounds.max.y, self.alt + roof),
|
||||||
}));
|
}));
|
||||||
@ -44,14 +47,73 @@ impl Structure for House {
|
|||||||
min: Vec3::new(self.bounds.min.x + 1, self.bounds.min.y + 1, self.alt + 0),
|
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),
|
max: Vec3::new(self.bounds.max.x - 1, self.bounds.max.y - 1, self.alt + roof),
|
||||||
}));
|
}));
|
||||||
|
let walls = prim(Primitive::Xor(outer, inner));
|
||||||
fill(Fill {
|
fill(Fill {
|
||||||
prim: prim(Primitive::Xor(wall, inner)),
|
prim: walls,
|
||||||
block: Block::new(BlockKind::Rock, Rgb::new(181, 170, 148)),
|
block: Block::new(BlockKind::Rock, Rgb::new(181, 170, 148)),
|
||||||
});
|
});
|
||||||
|
|
||||||
// Floor
|
// wall pillars
|
||||||
|
let mut pillars = prim(Primitive::Empty);
|
||||||
|
for x in self.tile_aabr.min.x + 1..self.tile_aabr.max.x {
|
||||||
|
let pillar = prim(Primitive::Aabb(Aabb {
|
||||||
|
min: Vec3::from(site.tile_wpos(Vec2::new(x, self.tile_aabr.min.y))) + Vec3::unit_z() * self.alt,
|
||||||
|
max: Vec3::from(site.tile_wpos(Vec2::new(x, self.tile_aabr.max.y)) + Vec2::unit_x()) + Vec3::unit_z() * (self.alt + roof),
|
||||||
|
}));
|
||||||
|
pillars = prim(Primitive::Or(pillars, pillar));
|
||||||
|
}
|
||||||
|
for y in self.tile_aabr.min.y + 1..self.tile_aabr.max.y {
|
||||||
|
let pillar = prim(Primitive::Aabb(Aabb {
|
||||||
|
min: Vec3::from(site.tile_wpos(Vec2::new(self.tile_aabr.min.x, y))) + Vec3::unit_z() * self.alt,
|
||||||
|
max: Vec3::from(site.tile_wpos(Vec2::new(self.tile_aabr.max.x, y)) + Vec2::unit_y()) + Vec3::unit_z() * (self.alt + roof),
|
||||||
|
}));
|
||||||
|
pillars = prim(Primitive::Or(pillars, pillar));
|
||||||
|
}
|
||||||
|
fill(Fill {
|
||||||
|
prim: prim(Primitive::And(walls, pillars)),
|
||||||
|
block: Block::new(BlockKind::Wood, Rgb::new(89, 44, 14)),
|
||||||
|
});
|
||||||
|
|
||||||
|
// For each storey...
|
||||||
for i in 0..self.levels + 1 {
|
for i in 0..self.levels + 1 {
|
||||||
let height = storey * i as i32;
|
let height = storey * i as i32;
|
||||||
|
|
||||||
|
// Windows x axis
|
||||||
|
{
|
||||||
|
let mut windows = prim(Primitive::Empty);
|
||||||
|
for y in self.tile_aabr.min.y..self.tile_aabr.max.y {
|
||||||
|
let window = prim(Primitive::Aabb(Aabb {
|
||||||
|
min: Vec3::from(site.tile_wpos(Vec2::new(self.tile_aabr.min.x, y)) + Vec2::unit_y() * 2) + Vec3::unit_z() * (self.alt + height + 2),
|
||||||
|
max: Vec3::from(site.tile_wpos(Vec2::new(self.tile_aabr.max.x, y + 1)) - Vec2::unit_y() * 1) + Vec3::unit_z() * (self.alt + height + 5),
|
||||||
|
}));
|
||||||
|
windows = prim(Primitive::Or(windows, window));
|
||||||
|
}
|
||||||
|
fill(Fill {
|
||||||
|
prim: prim(Primitive::And(walls, windows)),
|
||||||
|
block: Block::air(SpriteKind::Window1)
|
||||||
|
.with_ori(2)
|
||||||
|
.unwrap(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
// Windows y axis
|
||||||
|
{
|
||||||
|
let mut windows = prim(Primitive::Empty);
|
||||||
|
for x in self.tile_aabr.min.x..self.tile_aabr.max.x {
|
||||||
|
let window = prim(Primitive::Aabb(Aabb {
|
||||||
|
min: Vec3::from(site.tile_wpos(Vec2::new(x, self.tile_aabr.min.y)) + Vec2::unit_x() * 2) + Vec3::unit_z() * (self.alt + height + 2),
|
||||||
|
max: Vec3::from(site.tile_wpos(Vec2::new(x + 1, self.tile_aabr.max.y)) - Vec2::unit_x() * 1) + Vec3::unit_z() * (self.alt + height + 5),
|
||||||
|
}));
|
||||||
|
windows = prim(Primitive::Or(windows, window));
|
||||||
|
}
|
||||||
|
fill(Fill {
|
||||||
|
prim: prim(Primitive::And(walls, windows)),
|
||||||
|
block: Block::air(SpriteKind::Window1)
|
||||||
|
.with_ori(0)
|
||||||
|
.unwrap(),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Floor
|
||||||
fill(Fill {
|
fill(Fill {
|
||||||
prim: prim(Primitive::Aabb(Aabb {
|
prim: prim(Primitive::Aabb(Aabb {
|
||||||
min: Vec3::new(self.bounds.min.x, self.bounds.min.y, self.alt + height + 0),
|
min: Vec3::new(self.bounds.min.x, self.bounds.min.y, self.alt + height + 0),
|
||||||
|
Loading…
Reference in New Issue
Block a user