Added fireflies, reeds near rivers

This commit is contained in:
Joshua Barretto 2020-08-30 13:25:54 +01:00
parent 4405227ffb
commit 88add8456f
15 changed files with 173 additions and 37 deletions

View File

@ -71,6 +71,9 @@ void main() {
max_light += lights_at(f_pos, f_norm, view_dir, k_a, k_d, k_s, alpha, emitted_light, reflected_light);
// TODO: Not this
emitted_light += max(f_col.rgb - 1.0, vec3(0));
surf_color = illuminate(max_light, view_dir, surf_color * emitted_light, surf_color * reflected_light);
#if (CLOUD_MODE == CLOUD_MODE_REGULAR)

View File

@ -45,6 +45,7 @@ const int FIREWORK_PURPLE = 6;
const int FIREWORK_RED = 7;
const int FIREWORK_YELLOW = 8;
const int LEAF = 9;
const int FIREFLY = 10;
// meters per second squared (acceleration)
const float earth_gravity = 9.807;
@ -214,6 +215,18 @@ void main() {
vec4(vec3(0.2 + rand7 * 0.2, 0.2 + (0.5 + rand6 * 0.5) * 0.6, 0), 1),
spin_in_axis(vec3(rand6, rand7, rand8), rand9 * 3 + lifetime * 5)
);
} else if (inst_mode == FIREFLY) {
float raise = pow(sin(3.1416 * lifetime / inst_lifespan), 0.2);
attr = Attr(
vec3(0, 0, raise * 5.0) + vec3(
sin(lifetime * 1.0 + rand0) + sin(lifetime * 7.0 + rand3) * 0.3,
sin(lifetime * 3.0 + rand1) + sin(lifetime * 8.0 + rand4) * 0.3,
sin(lifetime * 2.0 + rand2) + sin(lifetime * 9.0 + rand5) * 0.3
),
raise,
vec4(vec3(5, 5, 1.1), 1),
spin_in_axis(vec3(rand6, rand7, rand8), rand9 * 3 + lifetime * 5)
);
} else {
attr = Attr(
linear_motion(

BIN
assets/voxygen/voxel/sprite/reed/reed-0.vox (Stored with Git LFS) Normal file

Binary file not shown.

View File

@ -1947,4 +1947,16 @@ GrassSnow: Some((
],
wind_sway: 0.2,
)),
// Reed
Reed: Some((
variations: [
(
model: "voxygen.voxel.sprite.reed.reed-0",
offset: (-6.5, -6.5, 0.0),
lod_axes: (0.0, 0.0, 0.5),
),
],
wind_sway: 0.65,
)),
)

View File

@ -42,6 +42,7 @@ pub mod store;
pub mod sync;
pub mod sys;
pub mod terrain;
pub mod time;
pub mod typed;
pub mod util;
pub mod vol;

View File

@ -5,6 +5,7 @@ use crate::{
sync::WorldSyncExt,
sys,
terrain::{Block, TerrainChunk, TerrainGrid},
time::DayPeriod,
vol::WriteVol,
};
use hashbrown::{HashMap, HashSet};
@ -230,6 +231,22 @@ impl State {
/// localised timings.
pub fn get_time_of_day(&self) -> f64 { self.ecs.read_resource::<TimeOfDay>().0 }
/// Get the current in-game day period (period of the day/night cycle)
pub fn get_day_period(&self) -> DayPeriod {
let tod = self.get_time_of_day().rem_euclid(60.0 * 60.0 * 24.0);
if tod < 60.0 * 60.0 * 4.0 {
DayPeriod::Night
} else if tod < 60.0 * 60.0 * 10.0 {
DayPeriod::Morning
} else if tod < 60.0 * 60.0 * 16.0 {
DayPeriod::Noon
} else if tod < 60.0 * 60.0 * 20.0 {
DayPeriod::Evening
} else {
DayPeriod::Night
}
}
/// Get the current in-game time.
///
/// Note that this does not correspond to the time of day.

View File

@ -93,6 +93,7 @@ make_case_elim!(
DropGate = 0x50,
DropGateBottom = 0x51,
GrassSnow = 0x52,
Reed = 0x53,
}
);
@ -200,6 +201,7 @@ impl BlockKind {
BlockKind::DropGate => false,
BlockKind::DropGateBottom => false,
BlockKind::GrassSnow => true,
BlockKind::Reed => true,
_ => false,
}
}
@ -296,6 +298,7 @@ impl BlockKind {
BlockKind::DropGate => false,
BlockKind::DropGateBottom => false,
BlockKind::GrassSnow => false,
BlockKind::Reed => false,
_ => true,
}
}
@ -373,6 +376,7 @@ impl BlockKind {
BlockKind::DropGate => true,
BlockKind::DropGateBottom => false,
BlockKind::GrassSnow => false,
BlockKind::Reed => false,
_ => true,
}
}

17
common/src/time.rs Normal file
View File

@ -0,0 +1,17 @@
#[derive(Copy, Clone, PartialEq, Eq)]
pub enum DayPeriod {
Night,
Morning,
Noon,
Evening,
}
impl DayPeriod {
pub fn is_dark(&self) -> bool {
*self == DayPeriod::Night
}
pub fn is_light(&self) -> bool {
!self.is_dark()
}
}

View File

@ -103,6 +103,7 @@ pub enum ParticleMode {
FireworkRed = 7,
FireworkYellow = 8,
Leaf = 9,
Firefly = 10,
}
impl ParticleMode {

View File

@ -14,6 +14,7 @@ use common::{
spiral::Spiral2d,
state::DeltaTime,
terrain::TerrainChunk,
time::DayPeriod,
vol::{RectRasterableVol, SizedVol},
};
use dot_vox::DotVoxData;
@ -283,7 +284,7 @@ impl ParticleMgr {
});
type BoiFn<'a> = fn(&'a BlocksOfInterest) -> &'a [Vec3<i32>];
// blocks, chunk range, emission density, lifetime, particle mode
// blocks, chunk range, emission density, lifetime, particle mode, condition
//
// - blocks: the function to select the blocks of interest that we should emit
// from
@ -293,14 +294,48 @@ impl ParticleMgr {
// particles
// - lifetime: the number of seconds that each particle should live for
// - particle mode: the visual mode of the generated particle
let particles: &[(BoiFn, usize, f32, f32, ParticleMode)] = &[
(|boi| &boi.leaves, 4, 0.001, 30.0, ParticleMode::Leaf),
(|boi| &boi.embers, 2, 20.0, 0.25, ParticleMode::CampfireFire),
(|boi| &boi.embers, 8, 3.0, 40.0, ParticleMode::CampfireSmoke),
// - Condition required for emissions
let particles: &[(BoiFn, usize, f32, f32, ParticleMode, fn(&SceneData) -> bool)] = &[
(
|boi| &boi.leaves,
4,
0.001,
30.0,
ParticleMode::Leaf,
|_| true,
),
(
|boi| &boi.embers,
2,
20.0,
0.25,
ParticleMode::CampfireFire,
|_| true,
),
(
|boi| &boi.embers,
8,
3.0,
40.0,
ParticleMode::CampfireSmoke,
|_| true,
),
(
|boi| &boi.grass,
5,
0.001,
40.0,
ParticleMode::Firefly,
|sd| sd.state.get_day_period().is_dark(),
),
];
let mut rng = thread_rng();
for (get_blocks, range, rate, dur, mode) in particles.iter() {
for (get_blocks, range, rate, dur, mode, cond) in particles.iter() {
if !cond(scene_data) {
continue;
}
for offset in Spiral2d::new().take((*range * 2 + 1).pow(2)) {
let chunk_pos = player_chunk + offset;

View File

@ -91,6 +91,7 @@ struct SpriteModelConfig<Model> {
lod_axes: (f32, f32, f32),
}
<<<<<<< HEAD
#[derive(Deserialize)]
/// Configuration data for a group of sprites (currently associated with a
/// particular BlockKind).

View File

@ -7,12 +7,14 @@ use vek::*;
pub struct BlocksOfInterest {
pub leaves: Vec<Vec3<i32>>,
pub grass: Vec<Vec3<i32>>,
pub embers: Vec<Vec3<i32>>,
}
impl BlocksOfInterest {
pub fn from_chunk(chunk: &TerrainChunk) -> Self {
let mut leaves = Vec::new();
let mut grass = Vec::new();
let mut embers = Vec::new();
chunk
@ -27,11 +29,17 @@ impl BlocksOfInterest {
.for_each(|(pos, block)| {
if block.kind() == BlockKind::Leaves && thread_rng().gen_range(0, 16) == 0 {
leaves.push(pos);
} else if block.kind() == BlockKind::Grass && thread_rng().gen_range(0, 16) == 0 {
grass.push(pos);
} else if block.kind() == BlockKind::Ember {
embers.push(pos);
}
});
Self { leaves, embers }
Self {
leaves,
grass,
embers,
}
}
}

View File

@ -774,6 +774,7 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
.div(100.0)
.into_array(),
) as f32)
//.mul(water_dist.map(|wd| (wd / 2.0).clamped(0.0, 1.0).powf(0.5)).unwrap_or(1.0))
.mul(rockiness)
.sub(0.4)
.max(0.0)
@ -996,6 +997,11 @@ impl<'a> Sampler<'a> for ColumnGen<'a> {
(alt, ground, sub_surface_color)
};
// Make river banks not have grass
let ground = water_dist
.map(|wd| Lerp::lerp(sub_surface_color, ground, (wd / 3.0).clamped(0.0, 1.0)))
.unwrap_or(ground);
let near_ocean = max_river.and_then(|(_, _, river_data, _)| {
if (river_data.is_lake() || river_data.river_kind == Some(RiverKind::Ocean))
&& ((alt <= water_level.max(CONFIG.sea_level + 5.0) && !is_cliffs) || !near_cliffs)

View File

@ -41,10 +41,14 @@ pub fn apply_scatter_to<'a>(
use BlockKind::*;
#[allow(clippy::type_complexity)]
// TODO: Add back all sprites we had before
let scatter: &[(_, bool, fn(&SimChunk) -> (f32, Option<(f32, f32)>))] = &[
let scatter: &[(
_,
bool,
fn(&SimChunk, &ColumnSample) -> (f32, Option<(f32, f32)>),
)] = &[
// (density, Option<(wavelen, threshold)>)
// Flowers
(BlueFlower, false, |c| {
(BlueFlower, false, |c, col| {
(
close(c.temp, 0.1, 0.2).min(close(c.humidity, CONFIG.forest_hum, 0.35))
* MUSH_FACT
@ -52,7 +56,7 @@ pub fn apply_scatter_to<'a>(
Some((48.0, 0.2)),
)
}),
(PinkFlower, false, |c| {
(PinkFlower, false, |c, col| {
(
close(c.temp, 0.2, 0.2).min(close(c.humidity, CONFIG.forest_hum, 0.35))
* MUSH_FACT
@ -60,7 +64,7 @@ pub fn apply_scatter_to<'a>(
Some((48.0, 0.2)),
)
}),
(PurpleFlower, false, |c| {
(PurpleFlower, false, |c, col| {
(
close(c.temp, 0.3, 0.2).min(close(c.humidity, CONFIG.forest_hum, 0.35))
* MUSH_FACT
@ -68,7 +72,7 @@ pub fn apply_scatter_to<'a>(
Some((48.0, 0.2)),
)
}),
(RedFlower, false, |c| {
(RedFlower, false, |c, col| {
(
close(c.temp, 0.5, 0.2).min(close(c.humidity, CONFIG.forest_hum, 0.35))
* MUSH_FACT
@ -76,7 +80,7 @@ pub fn apply_scatter_to<'a>(
Some((48.0, 0.2)),
)
}),
(WhiteFlower, false, |c| {
(WhiteFlower, false, |c, col| {
(
close(c.temp, 0.0, 0.3).min(close(c.humidity, CONFIG.forest_hum, 0.35))
* MUSH_FACT
@ -84,7 +88,7 @@ pub fn apply_scatter_to<'a>(
Some((48.0, 0.2)),
)
}),
(YellowFlower, false, |c| {
(YellowFlower, false, |c, col| {
(
close(c.temp, 0.3, 0.2).min(close(c.humidity, CONFIG.forest_hum, 0.35))
* MUSH_FACT
@ -93,7 +97,7 @@ pub fn apply_scatter_to<'a>(
)
}),
// Herbs and Spices
(LingonBerry, false, |c| {
(LingonBerry, false, |c, col| {
(
close(c.temp, 0.3, 0.4).min(close(c.humidity, CONFIG.forest_hum, 0.35))
* MUSH_FACT
@ -101,7 +105,7 @@ pub fn apply_scatter_to<'a>(
None,
)
}),
(LeafyPlant, false, |c| {
(LeafyPlant, false, |c, col| {
(
close(c.temp, 0.3, 0.4).min(close(c.humidity, CONFIG.forest_hum, 0.35))
* MUSH_FACT
@ -109,7 +113,7 @@ pub fn apply_scatter_to<'a>(
None,
)
}),
(Fern, false, |c| {
(Fern, false, |c, col| {
(
close(c.temp, 0.3, 0.4).min(close(c.humidity, CONFIG.forest_hum, 0.35))
* MUSH_FACT
@ -117,7 +121,7 @@ pub fn apply_scatter_to<'a>(
Some((48.0, 0.4)),
)
}),
(Blueberry, false, |c| {
(Blueberry, false, |c, col| {
(
close(c.temp, CONFIG.temperate_temp, 0.5).min(close(
c.humidity,
@ -130,40 +134,40 @@ pub fn apply_scatter_to<'a>(
}),
// Collectable Objects
// Only spawn twigs in temperate forests
(Twigs, false, |c| {
(Twigs, false, |c, col| {
((c.tree_density - 0.5).max(0.0) * 1.0e-3, None)
}),
(Stones, false, |c| {
(Stones, false, |c, col| {
((c.rockiness - 0.5).max(0.0) * 1.0e-3, None)
}),
// Don't spawn Mushrooms in snowy regions
(Mushroom, false, |c| {
(Mushroom, false, |c, col| {
(
close(c.temp, 0.3, 0.4).min(close(c.humidity, CONFIG.forest_hum, 0.35)) * MUSH_FACT,
None,
)
}),
// Grass
(ShortGrass, false, |c| {
(ShortGrass, false, |c, col| {
(
close(c.temp, 0.3, 0.4).min(close(c.humidity, 0.6, 0.35)) * 0.05,
Some((48.0, 0.4)),
)
}),
(MediumGrass, false, |c| {
(MediumGrass, false, |c, col| {
(
close(c.temp, 0.0, 0.6).min(close(c.humidity, 0.6, 0.35)) * 0.05,
Some((48.0, 0.2)),
)
}),
(LongGrass, false, |c| {
(LongGrass, false, |c, col| {
(
close(c.temp, 0.4, 0.4).min(close(c.humidity, 0.8, 0.2)) * 0.08,
Some((48.0, 0.1)),
)
}),
// Jungle Sprites
(LongGrass, false, |c| {
(LongGrass, false, |c, col| {
(
close(c.temp, CONFIG.tropical_temp, 0.4).min(close(
c.humidity,
@ -173,7 +177,7 @@ pub fn apply_scatter_to<'a>(
Some((60.0, 5.0)),
)
}),
/*(WheatGreen, false, |c| {
/*(WheatGreen, false, |c, col| {
(
close(c.temp, 0.4, 0.2).min(close(c.humidity, CONFIG.forest_hum, 0.1))
* MUSH_FACT
@ -181,7 +185,7 @@ pub fn apply_scatter_to<'a>(
None,
)
}),*/
(GrassSnow, false, |c| {
(GrassSnow, false, |c, col| {
(
close(c.temp, CONFIG.snow_temp - 0.2, 0.4).min(close(
c.humidity,
@ -192,7 +196,7 @@ pub fn apply_scatter_to<'a>(
)
}),
// Desert Plants
(DeadBush, false, |c| {
(DeadBush, false, |c, col| {
(
close(c.temp, CONFIG.desert_temp + 0.2, 0.3).min(close(
c.humidity,
@ -203,7 +207,7 @@ pub fn apply_scatter_to<'a>(
None,
)
}),
(LargeCactus, false, |c| {
(LargeCactus, false, |c, col| {
(
close(c.temp, CONFIG.desert_temp + 0.2, 0.3).min(close(
c.humidity,
@ -214,7 +218,7 @@ pub fn apply_scatter_to<'a>(
None,
)
}),
/*(BarrelCactus, false, |c| {
/*(BarrelCactus, false, |c, col| {
(
close(c.temp, CONFIG.desert_temp + 0.2, 0.3).min(close(
c.humidity,
@ -225,7 +229,7 @@ pub fn apply_scatter_to<'a>(
None,
)
}),
(RoundCactus, false, |c| {
(RoundCactus, false, |c, col| {
(
close(c.temp, CONFIG.desert_temp + 0.2, 0.3).min(close(
c.humidity,
@ -236,7 +240,7 @@ pub fn apply_scatter_to<'a>(
None,
)
}),
(ShortCactus, false, |c| {
(ShortCactus, false, |c, col| {
(
close(c.temp, CONFIG.desert_temp + 0.2, 0.3).min(close(
c.humidity,
@ -247,7 +251,7 @@ pub fn apply_scatter_to<'a>(
None,
)
}),
(MedFlatCactus, false, |c| {
(MedFlatCactus, false, |c, col| {
(
close(c.temp, CONFIG.desert_temp + 0.2, 0.3).min(close(
c.humidity,
@ -258,7 +262,7 @@ pub fn apply_scatter_to<'a>(
None,
)
}),
(ShortFlatCactus, false, |c| {
(ShortFlatCactus, false, |c, col| {
(
close(c.temp, CONFIG.desert_temp + 0.2, 0.3).min(close(
c.humidity,
@ -269,6 +273,16 @@ pub fn apply_scatter_to<'a>(
None,
)
}),*/
(Reed, false, |c, col| {
(
close(c.humidity, CONFIG.jungle_hum, 0.7)
* col
.water_dist
.map(|wd| Lerp::lerp(0.2, 0.0, (wd / 8.0).clamped(0.0, 1.0)))
.unwrap_or(0.0),
None,
)
}),
];
for y in 0..vol.size_xy().y as i32 {
@ -290,7 +304,7 @@ pub fn apply_scatter_to<'a>(
.iter()
.enumerate()
.find_map(|(i, (bk, is_underwater, f))| {
let (density, patch) = f(chunk);
let (density, patch) = f(chunk, col_sample);
let is_patch = patch
.map(|(wavelen, threshold)| {
index.noise.scatter_nz.get(

View File

@ -1657,7 +1657,7 @@ impl WorldSim {
let new_chunk = this.get(downhill_pos)?;
const SLIDE_THRESHOLD: f32 = 5.0;
if new_chunk.is_underwater() || new_chunk.alt + SLIDE_THRESHOLD < chunk.alt {
if new_chunk.river.near_water() || new_chunk.alt + SLIDE_THRESHOLD < chunk.alt {
break;
} else {
chunk = new_chunk;
@ -2182,8 +2182,9 @@ impl SimChunk {
downhill,
temp,
humidity,
rockiness: if true && !river.is_river() {
rockiness: if true {
(gen_ctx.rock_nz.get((wposf.div(1024.0)).into_array()) as f32)
//.add(if river.near_river() { 20.0 } else { 0.0 })
.sub(0.1)
.mul(1.3)
.max(0.0)