From 9e3d279d39389e1f784fc419d52c981c68c7a1aa Mon Sep 17 00:00:00 2001 From: Joshua Barretto Date: Thu, 16 Apr 2020 22:01:13 +0100 Subject: [PATCH] Basic boss spawning in dungeons, better AO --- assets/voxygen/shaders/terrain-frag.glsl | 2 +- common/src/generation.rs | 3 +- voxygen/src/mesh/segment.rs | 6 +-- world/src/lib.rs | 17 +++++++- world/src/site/dungeon/mod.rs | 50 +++++++++++++++++++++++- world/src/site/mod.rs | 13 ++++++ world/src/site/settlement/mod.rs | 10 +++++ 7 files changed, 91 insertions(+), 10 deletions(-) diff --git a/assets/voxygen/shaders/terrain-frag.glsl b/assets/voxygen/shaders/terrain-frag.glsl index 21001e4f7c..7f3a00558f 100644 --- a/assets/voxygen/shaders/terrain-frag.glsl +++ b/assets/voxygen/shaders/terrain-frag.glsl @@ -30,7 +30,7 @@ void main() { // Use an array to avoid conditional branching vec3 f_norm = normals[(f_pos_norm >> 29) & 0x7u]; - float ao = pow(f_ao, 0.5) * 0.9 + 0.1; + float ao = pow(f_ao, 0.6) * 0.9 + 0.1; vec3 light, diffuse_light, ambient_light; get_sun_diffuse(f_norm, time_of_day.x, light, diffuse_light, ambient_light, 1.0); diff --git a/common/src/generation.rs b/common/src/generation.rs index c88ddc9c5c..06de93e0ab 100644 --- a/common/src/generation.rs +++ b/common/src/generation.rs @@ -17,8 +17,7 @@ pub struct ChunkSupplement { } impl ChunkSupplement { - pub fn with_entity(mut self, entity: EntityInfo) -> Self { + pub fn add_entity(&mut self, entity: EntityInfo) { self.entities.push(entity); - self } } diff --git a/voxygen/src/mesh/segment.rs b/voxygen/src/mesh/segment.rs index 4558c88f09..9669528288 100644 --- a/voxygen/src/mesh/segment.rs +++ b/voxygen/src/mesh/segment.rs @@ -31,11 +31,10 @@ impl Meshable for Segment { offs + pos.map(|e| e as f32), &[[[Rgba::from_opaque(col); 3]; 3]; 3], |origin, norm, col, ao, light| { - let ao = ao * 0.95 + 0.05; FigureVertex::new( origin, norm, - linear_to_srgb(srgb_to_linear(col) * light.min(ao)), + linear_to_srgb(srgb_to_linear(col) * light.min(ao.powf(0.5) * 0.75 + 0.25)), 0, ) }, @@ -85,11 +84,10 @@ impl Meshable for Segment { offs + pos.map(|e| e as f32), &[[[Rgba::from_opaque(col); 3]; 3]; 3], |origin, norm, col, ao, light| { - let ao = ao * 0.95 + 0.05; SpriteVertex::new( origin, norm, - linear_to_srgb(srgb_to_linear(col) * light.min(ao)), + linear_to_srgb(srgb_to_linear(col) * light.min(ao.powf(0.5) * 0.75 + 0.25)), ) }, &{ diff --git a/world/src/lib.rs b/world/src/lib.rs index 073e0f15b6..03b78ce578 100644 --- a/world/src/lib.rs +++ b/world/src/lib.rs @@ -194,12 +194,27 @@ impl World { }; if sim_chunk.contains_waypoint { - supplement = supplement.with_entity(EntityInfo { + supplement.add_entity(EntityInfo { pos: gen_entity_pos(), kind: EntityKind::Waypoint, }); } + // Apply site supplementary information + sim_chunk.sites.iter().for_each(|site| { + site.apply_supplement( + chunk_wpos2d, + |offs| { + zcache_grid + .get(grid_border + offs) + .map(Option::as_ref) + .flatten() + .map(|zc| &zc.sample) + }, + &mut supplement, + ) + }); + Ok((chunk, supplement)) } } diff --git a/world/src/site/dungeon/mod.rs b/world/src/site/dungeon/mod.rs index cb181b8c57..8b7199d309 100644 --- a/world/src/site/dungeon/mod.rs +++ b/world/src/site/dungeon/mod.rs @@ -12,6 +12,7 @@ use common::{ terrain::{Block, BlockKind, TerrainChunkSize}, vol::{BaseVol, RectSizedVol, RectVolSize, ReadVol, WriteVol, Vox}, store::{Id, Store}, + generation::{ChunkSupplement, EntityInfo, EntityKind}, }; use hashbrown::{HashMap, HashSet}; use rand::prelude::*; @@ -50,7 +51,7 @@ impl Dungeon { let mut ctx = GenCtx { sim, rng }; let mut this = Self { origin: wpos, - alt: ctx.sim.and_then(|sim| sim.get_alt_approx(wpos)).unwrap_or(0.0) as i32, + alt: ctx.sim.and_then(|sim| sim.get_alt_approx(wpos)).unwrap_or(0.0) as i32 + 6, noise: RandomField::new(ctx.rng.gen()), floors: (0..6) .scan(Vec2::zero(), |stair_tile, level| { @@ -98,7 +99,7 @@ impl Dungeon { let tile_pos = rpos.map(|e| e.div_euclid(TILE_SIZE)); let tile_center = tile_pos * TILE_SIZE + TILE_SIZE / 2; - let mut z = self.alt + 6; + let mut z = self.alt; for floor in &self.floors { let mut sampler = floor.col_sampler(rpos); @@ -112,6 +113,26 @@ impl Dungeon { } } } + + pub fn apply_supplement<'a>( + &'a self, + wpos2d: Vec2, + mut get_column: impl FnMut(Vec2) -> Option<&'a ColumnSample<'a>>, + supplement: &mut ChunkSupplement, + ) { + let rpos = wpos2d - self.origin; + let area = Aabr { + min: rpos, + max: rpos + TerrainChunkSize::RECT_SIZE.map(|e| e as i32), + }; + + let mut z = self.alt; + for floor in &self.floors { + z -= floor.total_depth(); + let origin = Vec3::new(self.origin.x, self.origin.y, z); + floor.apply_supplement(area, origin, supplement); + } + } } const CARDINALS: [Vec2; 4] = [ @@ -271,6 +292,31 @@ impl Floor { } } + pub fn apply_supplement(&self, area: Aabr, origin: Vec3, supplement: &mut ChunkSupplement) { + let align = |e: i32| e.div_euclid(TILE_SIZE) + if e.rem_euclid(TILE_SIZE) > TILE_SIZE / 2 { + 1 + } else { + 0 + }; + let aligned_area = Aabr { + min: area.min.map(align) + self.tile_offset, + max: area.max.map(align) + self.tile_offset, + }; + + for x in aligned_area.min.x..aligned_area.max.x { + for y in aligned_area.min.y..aligned_area.max.y { + let tile_pos = Vec2::new(x, y); + if let Some(Tile::Room) = self.tiles.get(tile_pos) { + if tile_pos.x % 4 != 0 || tile_pos.y % 4 != 0 { continue; } // This is so bad + supplement.add_entity(EntityInfo { + pos: (origin + Vec3::from(self.tile_offset + tile_pos) * TILE_SIZE).map(|e| e as f32), + kind: EntityKind::Boss, + }); + } + } + } + } + pub fn total_depth(&self) -> i32 { self.solid_depth + self.hollow_depth } diff --git a/world/src/site/mod.rs b/world/src/site/mod.rs index 27f5369522..baebf2814a 100644 --- a/world/src/site/mod.rs +++ b/world/src/site/mod.rs @@ -12,6 +12,7 @@ use crate::{ use common::{ terrain::Block, vol::{Vox, BaseVol, RectSizedVol, ReadVol, WriteVol}, + generation::ChunkSupplement, }; use std::{fmt, sync::Arc}; use vek::*; @@ -100,6 +101,18 @@ impl Site { Site::Dungeon(dungeon) => dungeon.apply_to(wpos2d, get_column, vol), } } + + pub fn apply_supplement<'a>( + &'a self, + wpos2d: Vec2, + get_column: impl FnMut(Vec2) -> Option<&'a ColumnSample<'a>>, + supplement: &mut ChunkSupplement, + ) { + match self { + Site::Settlement(settlement) => settlement.apply_supplement(wpos2d, get_column, supplement), + Site::Dungeon(dungeon) => dungeon.apply_supplement(wpos2d, get_column, supplement), + } + } } impl From for Site { diff --git a/world/src/site/settlement/mod.rs b/world/src/site/settlement/mod.rs index e340f96e3d..d78c484dd2 100644 --- a/world/src/site/settlement/mod.rs +++ b/world/src/site/settlement/mod.rs @@ -14,6 +14,7 @@ use common::{ terrain::{Block, BlockKind, TerrainChunkSize}, vol::{BaseVol, RectSizedVol, RectVolSize, ReadVol, WriteVol, Vox}, store::{Id, Store}, + generation::ChunkSupplement, }; use hashbrown::{HashMap, HashSet}; use rand::prelude::*; @@ -676,6 +677,15 @@ impl Settlement { } } + pub fn apply_supplement<'a>( + &'a self, + wpos2d: Vec2, + mut get_column: impl FnMut(Vec2) -> Option<&'a ColumnSample<'a>>, + supplement: &mut ChunkSupplement, + ) { + // TODO + } + pub fn get_color(&self, pos: Vec2) -> Option> { let sample = self.land.get_at_block(pos);