diff --git a/assets/voxygen/shaders/include/light.glsl b/assets/voxygen/shaders/include/light.glsl index cbcee4770e..1fbe9b1876 100644 --- a/assets/voxygen/shaders/include/light.glsl +++ b/assets/voxygen/shaders/include/light.glsl @@ -25,7 +25,7 @@ vec3 illuminate(vec3 color, vec3 light, vec3 diffuse, vec3 ambience) { } float attenuation_strength(vec3 rpos) { - return 1.0 / pow(rpos.x * rpos.x + rpos.y * rpos.y + rpos.z * rpos.z, 0.8); + return 0.3 / pow(rpos.x * rpos.x + rpos.y * rpos.y + rpos.z * rpos.z, 0.5); } vec3 light_at(vec3 wpos, vec3 wnorm) { diff --git a/world/src/site/settlement/building/mod.rs b/world/src/site/settlement/building/mod.rs new file mode 100644 index 0000000000..416c94767a --- /dev/null +++ b/world/src/site/settlement/building/mod.rs @@ -0,0 +1 @@ +mod skeleton; diff --git a/world/src/site/settlement/building/skeleton.rs b/world/src/site/settlement/building/skeleton.rs new file mode 100644 index 0000000000..e278136307 --- /dev/null +++ b/world/src/site/settlement/building/skeleton.rs @@ -0,0 +1,64 @@ +use vek::*; + +#[derive(Copy, Clone)] +pub enum Ori { + East, + North, +} + +impl Ori { + pub fn flip(self) -> Self { + match self { + Ori::East => Ori::North, + Ori::North => Ori::East, + } + } + + pub fn dir(self) -> Vec2 { + match self { + Ori::East => Vec2::unit_x(), + Ori::North => Vec2::unit_y(), + } + } +} + +pub struct Branch { + len: i32, + locus: i32, + children: Vec<(i32, Branch)>, +} + +impl Branch { + fn for_each<'a>(&'a self, node: Vec2, ori: Ori, f: &mut impl FnMut(Vec2, Ori, &'a Branch)) { + f(node, ori, self); + for (offset, child) in &self.children { + child.for_each(node + ori.dir() * *offset, ori.flip(), f); + } + } +} + +pub struct Skeleton { + offset: i32, + ori: Ori, + root: Branch, +} + +impl Skeleton { + pub fn for_each<'a>(&'a self, mut f: impl FnMut(Vec2, Ori, &'a Branch)) { + self.root.for_each(self.ori.dir() * self.offset, self.ori, &mut f); + } + + pub fn closest(&self, pos: Vec2) -> (i32, &Branch) { + let mut min = None; + self.for_each(|node, ori, branch| { + let bounds = Aabr::new_empty(node - ori.flip().dir() * branch.locus) + .expanded_to_contain_point(node + ori.dir() * branch.len + ori.flip().dir() * branch.locus); + let projected = pos.map2(bounds.min.zip(bounds.max), |e, (min, max)| Clamp::clamp(e, min, max)); + let dist = (projected - pos).map(|e| e.abs()).reduce_max(); + if min.map(|(min_dist, _)| dist < min_dist).unwrap_or(true) { + min = Some((dist, branch)); + } + }); + min.unwrap() + } +} diff --git a/world/src/site/settlement/mod.rs b/world/src/site/settlement/mod.rs index 1c43e5f965..37b0be67b9 100644 --- a/world/src/site/settlement/mod.rs +++ b/world/src/site/settlement/mod.rs @@ -1,3 +1,5 @@ +mod building; + use crate::{ column::ColumnSample, sim::{SimChunk, WorldSim},