mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Fixed particles for non-body entities, AO for non-volumetric illumination
This commit is contained in:
parent
b5662163f0
commit
07ba4dcc33
@ -92,9 +92,9 @@ void main() {
|
|||||||
// vec3 f_col = f_col_light.rgb;
|
// vec3 f_col = f_col_light.rgb;
|
||||||
// float f_ao = f_col_light.a;
|
// float f_ao = f_col_light.a;
|
||||||
|
|
||||||
float f_ao, f_glow;
|
float f_ao, f_glow, f_ao_unused;
|
||||||
uint material = 0xFFu;
|
uint material = 0xFFu;
|
||||||
vec3 f_col = greedy_extract_col_light_attr(t_col_light, s_col_light, f_uv_pos, f_ao, f_glow, material);
|
vec3 f_col = greedy_extract_col_light_attr(t_col_light, s_col_light, f_uv_pos, f_ao, f_glow, f_ao_unused, material);
|
||||||
|
|
||||||
#ifdef EXPERIMENTAL_BAREMINIMUM
|
#ifdef EXPERIMENTAL_BAREMINIMUM
|
||||||
tgt_color = vec4(simple_lighting(f_pos.xyz, f_col, f_ao), 1);
|
tgt_color = vec4(simple_lighting(f_pos.xyz, f_col, f_ao), 1);
|
||||||
|
@ -620,35 +620,36 @@ vec3 compute_attenuation_point(vec3 wpos, vec3 ray_dir, vec3 mu, float surface_a
|
|||||||
//}
|
//}
|
||||||
//#endif
|
//#endif
|
||||||
|
|
||||||
vec3 greedy_extract_col_light_attr(texture2D t_col_light, sampler s_col_light, vec2 f_uv_pos, out float f_light, out float f_glow, out uint f_attr) {
|
vec3 greedy_extract_col_light_attr(texture2D t_col_light, sampler s_col_light, vec2 f_uv_pos, out float f_light, out float f_glow, out float f_ao, out uint f_attr) {
|
||||||
uvec4 f_col_light = uvec4(texelFetch(sampler2D(t_col_light, s_col_light), ivec2(f_uv_pos), 0) * 255);
|
uvec4 f_col_light = uvec4(texelFetch(sampler2D(t_col_light, s_col_light), ivec2(f_uv_pos), 0) * 255);
|
||||||
vec3 f_col = vec3(
|
vec3 f_col = vec3(
|
||||||
float(((f_col_light.r & 0x7u) << 1u) | (f_col_light.b & 0xF0u)),
|
float(((f_col_light.r & 0x7u) << 1u) | (f_col_light.b & 0xF0u)),
|
||||||
float(f_col_light.a),
|
float(f_col_light.a & 0xFE),
|
||||||
float(((f_col_light.g & 0x7u) << 1u) | ((f_col_light.b & 0x0Fu) << 4u))
|
float(((f_col_light.g & 0x7u) << 1u) | ((f_col_light.b & 0x0Fu) << 4u))
|
||||||
) / 255.0;
|
) / 255.0;
|
||||||
|
|
||||||
// TODO: Figure out how to use `texture` and modulation to avoid needing to do manual filtering
|
// TODO: Figure out how to use `texture` and modulation to avoid needing to do manual filtering
|
||||||
vec2 light_00 = vec2(uvec2(f_col_light.rg) >> 3u);
|
vec3 light_00 = vec3(uvec2(f_col_light.rg) >> 3u, f_col_light.a & 1u);
|
||||||
vec2 light_10 = vec2(uvec2(texelFetch(sampler2D(t_col_light, s_col_light), ivec2(f_uv_pos) + ivec2(1, 0), 0).rg * 255.0) >> 3u);
|
vec3 light_10 = vec3(uvec2(texelFetch(sampler2D(t_col_light, s_col_light), ivec2(f_uv_pos) + ivec2(1, 0), 0).rg * 255.0) >> 3u, uint(texelFetch(sampler2D(t_col_light, s_col_light), ivec2(f_uv_pos) + ivec2(1, 0), 0).a * 255.0) & 1u);
|
||||||
vec2 light_01 = vec2(uvec2(texelFetch(sampler2D(t_col_light, s_col_light), ivec2(f_uv_pos) + ivec2(0, 1), 0).rg * 255.0) >> 3u);
|
vec3 light_01 = vec3(uvec2(texelFetch(sampler2D(t_col_light, s_col_light), ivec2(f_uv_pos) + ivec2(0, 1), 0).rg * 255.0) >> 3u, uint(texelFetch(sampler2D(t_col_light, s_col_light), ivec2(f_uv_pos) + ivec2(0, 1), 0).a * 255.0) & 1u);
|
||||||
vec2 light_11 = vec2(uvec2(texelFetch(sampler2D(t_col_light, s_col_light), ivec2(f_uv_pos) + ivec2(1, 1), 0).rg * 255.0) >> 3u);
|
vec3 light_11 = vec3(uvec2(texelFetch(sampler2D(t_col_light, s_col_light), ivec2(f_uv_pos) + ivec2(1, 1), 0).rg * 255.0) >> 3u, uint(texelFetch(sampler2D(t_col_light, s_col_light), ivec2(f_uv_pos) + ivec2(1, 1), 0).a * 255.0) & 1u);
|
||||||
vec2 light_0 = mix(light_00, light_01, fract(f_uv_pos.y));
|
vec3 light_0 = mix(light_00, light_01, fract(f_uv_pos.y));
|
||||||
vec2 light_1 = mix(light_10, light_11, fract(f_uv_pos.y));
|
vec3 light_1 = mix(light_10, light_11, fract(f_uv_pos.y));
|
||||||
vec2 light = mix(light_0, light_1, fract(f_uv_pos.x));
|
vec3 light = mix(light_0, light_1, fract(f_uv_pos.x));
|
||||||
// TODO: Use `texture` instead
|
// TODO: Use `texture` instead
|
||||||
//vec2 light = texture(t_col_light, f_uv_pos).xy / 31;
|
//vec2 light = texture(t_col_light, f_uv_pos).xy / 31;
|
||||||
|
|
||||||
|
|
||||||
|
f_ao = light.z;
|
||||||
f_light = light.x / 31.0;
|
f_light = light.x / 31.0;
|
||||||
f_glow = light.y / 31.0;
|
f_glow = light.y / 31.0;
|
||||||
f_attr = f_col_light.g >> 3u;
|
f_attr = f_col_light.g >> 3u;
|
||||||
return srgb_to_linear(f_col);
|
return srgb_to_linear(f_col);
|
||||||
}
|
}
|
||||||
|
|
||||||
vec3 greedy_extract_col_light_glow(texture2D t_col_light, sampler s_col_light, vec2 f_uv_pos, out float f_light, out float f_glow) {
|
vec3 greedy_extract_col_light_glow(texture2D t_col_light, sampler s_col_light, vec2 f_uv_pos, out float f_light, out float f_ao, out float f_glow) {
|
||||||
uint f_attr;
|
uint f_attr;
|
||||||
return greedy_extract_col_light_attr(t_col_light, s_col_light, f_uv_pos, f_light, f_glow, f_attr);
|
return greedy_extract_col_light_attr(t_col_light, s_col_light, f_uv_pos, f_light, f_glow, f_ao, f_attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -40,8 +40,8 @@ layout(location = 0) out vec4 tgt_color;
|
|||||||
const float FADE_DIST = 32.0;
|
const float FADE_DIST = 32.0;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
float f_ao, f_glow;
|
float f_ao, f_glow, f_ao_unused;
|
||||||
vec3 f_col = greedy_extract_col_light_glow(t_col_light, s_col_light, f_uv_pos, f_ao, f_glow);
|
vec3 f_col = greedy_extract_col_light_glow(t_col_light, s_col_light, f_uv_pos, f_ao, f_ao_unused, f_glow);
|
||||||
|
|
||||||
#ifdef EXPERIMENTAL_BAREMINIMUM
|
#ifdef EXPERIMENTAL_BAREMINIMUM
|
||||||
tgt_color = vec4(simple_lighting(f_pos.xyz, f_col, f_ao), 1);
|
tgt_color = vec4(simple_lighting(f_pos.xyz, f_col, f_ao), 1);
|
||||||
|
@ -84,8 +84,8 @@ void main() {
|
|||||||
vec2 f_uv_pos = f_uv_pos + atlas_offs.xy;
|
vec2 f_uv_pos = f_uv_pos + atlas_offs.xy;
|
||||||
// vec4 f_col_light = textureProj(t_col_light, vec3(f_uv_pos + 0.5, textureSize(t_col_light, 0)));//(f_uv_pos/* + 0.5*/) / texSize);
|
// vec4 f_col_light = textureProj(t_col_light, vec3(f_uv_pos + 0.5, textureSize(t_col_light, 0)));//(f_uv_pos/* + 0.5*/) / texSize);
|
||||||
// float f_light = textureProj(t_col_light, vec3(f_uv_pos + 0.5, textureSize(t_col_light, 0))).a;//1.0;//f_col_light.a * 4.0;// f_light = float(v_col_light & 0x3Fu) / 64.0;
|
// float f_light = textureProj(t_col_light, vec3(f_uv_pos + 0.5, textureSize(t_col_light, 0))).a;//1.0;//f_col_light.a * 4.0;// f_light = float(v_col_light & 0x3Fu) / 64.0;
|
||||||
float f_light, f_glow;
|
float f_light, f_glow, f_ao;
|
||||||
vec3 f_col = greedy_extract_col_light_glow(t_col_light, s_col_light, f_uv_pos, f_light, f_glow);
|
vec3 f_col = greedy_extract_col_light_glow(t_col_light, s_col_light, f_uv_pos, f_light, f_ao, f_glow);
|
||||||
|
|
||||||
#ifdef EXPERIMENTAL_BAREMINIMUM
|
#ifdef EXPERIMENTAL_BAREMINIMUM
|
||||||
tgt_color = vec4(simple_lighting(f_pos.xyz, f_col, f_light), 1);
|
tgt_color = vec4(simple_lighting(f_pos.xyz, f_col, f_light), 1);
|
||||||
@ -391,6 +391,8 @@ void main() {
|
|||||||
|
|
||||||
max_light += lights_at(f_pos, f_norm, view_dir, mu, cam_attenuation, fluid_alt, k_a, k_d, k_s, alpha, f_norm, 1.0, emitted_light, reflected_light);
|
max_light += lights_at(f_pos, f_norm, view_dir, mu, cam_attenuation, fluid_alt, k_a, k_d, k_s, alpha, f_norm, 1.0, emitted_light, reflected_light);
|
||||||
|
|
||||||
|
reflected_light *= 0.3 + f_ao * 0.7;
|
||||||
|
|
||||||
#ifndef EXPERIMENTAL_NOCAUSTICS
|
#ifndef EXPERIMENTAL_NOCAUSTICS
|
||||||
#if (FLUID_MODE == FLUID_MODE_SHINY)
|
#if (FLUID_MODE == FLUID_MODE_SHINY)
|
||||||
if (faces_fluid) {
|
if (faces_fluid) {
|
||||||
|
@ -9,7 +9,7 @@ type TodoRect = (
|
|||||||
Vec3<i32>,
|
Vec3<i32>,
|
||||||
);
|
);
|
||||||
|
|
||||||
pub struct GreedyConfig<D, FL, FG, FO, FS, FP, FT> {
|
pub struct GreedyConfig<D, FA, FL, FG, FO, FS, FP, FT> {
|
||||||
pub data: D,
|
pub data: D,
|
||||||
/// The minimum position to mesh, in the coordinate system used
|
/// The minimum position to mesh, in the coordinate system used
|
||||||
/// for queries against the volume.
|
/// for queries against the volume.
|
||||||
@ -31,6 +31,9 @@ pub struct GreedyConfig<D, FL, FG, FO, FS, FP, FT> {
|
|||||||
/// the number of *horizontal* planes large enough to cover the whole
|
/// the number of *horizontal* planes large enough to cover the whole
|
||||||
/// chunk.
|
/// chunk.
|
||||||
pub greedy_size_cross: Vec3<usize>,
|
pub greedy_size_cross: Vec3<usize>,
|
||||||
|
/// Given a position, return the AO information for the voxel at that
|
||||||
|
/// position (0.0 - 1.0).
|
||||||
|
pub get_ao: FA,
|
||||||
/// Given a position, return the lighting information for the voxel at that
|
/// Given a position, return the lighting information for the voxel at that
|
||||||
/// position.
|
/// position.
|
||||||
pub get_light: FL,
|
pub get_light: FL,
|
||||||
@ -367,16 +370,17 @@ impl<'a, Allocator: AtlasAllocator> GreedyMesh<'a, Allocator> {
|
|||||||
/// Returns an estimate of the bounds of the current meshed model.
|
/// Returns an estimate of the bounds of the current meshed model.
|
||||||
///
|
///
|
||||||
/// For more information on the config parameter, see [GreedyConfig].
|
/// For more information on the config parameter, see [GreedyConfig].
|
||||||
pub fn push<M: PartialEq, D: 'a, FL, FG, FO, FS, FP, FT>(
|
pub fn push<M: PartialEq, D: 'a, FA, FL, FG, FO, FS, FP, FT>(
|
||||||
&mut self,
|
&mut self,
|
||||||
config: GreedyConfig<D, FL, FG, FO, FS, FP, FT>,
|
config: GreedyConfig<D, FA, FL, FG, FO, FS, FP, FT>,
|
||||||
) where
|
) where
|
||||||
|
FA: for<'r> FnMut(&'r mut D, Vec3<i32>) -> f32 + 'a,
|
||||||
FL: for<'r> FnMut(&'r mut D, Vec3<i32>) -> f32 + 'a,
|
FL: for<'r> FnMut(&'r mut D, Vec3<i32>) -> f32 + 'a,
|
||||||
FG: for<'r> FnMut(&'r mut D, Vec3<i32>) -> f32 + 'a,
|
FG: for<'r> FnMut(&'r mut D, Vec3<i32>) -> f32 + 'a,
|
||||||
FO: for<'r> FnMut(&'r mut D, Vec3<i32>) -> bool + 'a,
|
FO: for<'r> FnMut(&'r mut D, Vec3<i32>) -> bool + 'a,
|
||||||
FS: for<'r> FnMut(&'r mut D, Vec3<i32>, Vec3<i32>, Vec2<Vec3<i32>>) -> Option<(bool, M)>,
|
FS: for<'r> FnMut(&'r mut D, Vec3<i32>, Vec3<i32>, Vec2<Vec3<i32>>) -> Option<(bool, M)>,
|
||||||
FP: FnMut(Vec2<u16>, Vec2<Vec2<u16>>, Vec3<f32>, Vec2<Vec3<f32>>, Vec3<f32>, &M),
|
FP: FnMut(Vec2<u16>, Vec2<Vec2<u16>>, Vec3<f32>, Vec2<Vec3<f32>>, Vec3<f32>, &M),
|
||||||
FT: for<'r> FnMut(&'r mut D, Vec3<i32>, u8, u8) -> [u8; 4] + 'a,
|
FT: for<'r> FnMut(&'r mut D, Vec3<i32>, u8, u8, bool) -> [u8; 4] + 'a,
|
||||||
{
|
{
|
||||||
span!(_guard, "push", "GreedyMesh::push");
|
span!(_guard, "push", "GreedyMesh::push");
|
||||||
let cont = greedy_mesh(
|
let cont = greedy_mesh(
|
||||||
@ -401,7 +405,7 @@ impl<'a, Allocator: AtlasAllocator> GreedyMesh<'a, Allocator> {
|
|||||||
span!(_guard, "finalize", "GreedyMesh::finalize");
|
span!(_guard, "finalize", "GreedyMesh::finalize");
|
||||||
let cur_size = self.col_lights_size;
|
let cur_size = self.col_lights_size;
|
||||||
let col_lights = vec![
|
let col_lights = vec![
|
||||||
TerrainVertex::make_col_light(254, 0, Rgb::broadcast(254));
|
TerrainVertex::make_col_light(254, 0, Rgb::broadcast(254), true);
|
||||||
cur_size.x as usize * cur_size.y as usize
|
cur_size.x as usize * cur_size.y as usize
|
||||||
];
|
];
|
||||||
let mut col_lights_info = (col_lights, cur_size);
|
let mut col_lights_info = (col_lights, cur_size);
|
||||||
@ -414,7 +418,9 @@ impl<'a, Allocator: AtlasAllocator> GreedyMesh<'a, Allocator> {
|
|||||||
pub fn max_size(&self) -> Vec2<u16> { self.max_size }
|
pub fn max_size(&self) -> Vec2<u16> { self.max_size }
|
||||||
}
|
}
|
||||||
|
|
||||||
fn greedy_mesh<'a, M: PartialEq, D: 'a, FL, FG, FO, FS, FP, FT, Allocator: AtlasAllocator>(
|
|
||||||
|
|
||||||
|
fn greedy_mesh<'a, M: PartialEq, D: 'a, FA, FL, FG, FO, FS, FP, FT, Allocator: AtlasAllocator>(
|
||||||
atlas: &mut Allocator,
|
atlas: &mut Allocator,
|
||||||
col_lights_size: &mut Vec2<u16>,
|
col_lights_size: &mut Vec2<u16>,
|
||||||
max_size: Vec2<u16>,
|
max_size: Vec2<u16>,
|
||||||
@ -423,21 +429,23 @@ fn greedy_mesh<'a, M: PartialEq, D: 'a, FL, FG, FO, FS, FP, FT, Allocator: Atlas
|
|||||||
draw_delta,
|
draw_delta,
|
||||||
greedy_size,
|
greedy_size,
|
||||||
greedy_size_cross,
|
greedy_size_cross,
|
||||||
|
get_ao,
|
||||||
get_light,
|
get_light,
|
||||||
get_glow,
|
get_glow,
|
||||||
get_opacity,
|
get_opacity,
|
||||||
mut should_draw,
|
mut should_draw,
|
||||||
mut push_quad,
|
mut push_quad,
|
||||||
make_face_texel,
|
make_face_texel,
|
||||||
}: GreedyConfig<D, FL, FG, FO, FS, FP, FT>,
|
}: GreedyConfig<D, FA, FL, FG, FO, FS, FP, FT>,
|
||||||
) -> Box<SuspendedMesh<'a>>
|
) -> Box<SuspendedMesh<'a>>
|
||||||
where
|
where
|
||||||
|
FA: for<'r> FnMut(&'r mut D, Vec3<i32>) -> f32 + 'a,
|
||||||
FL: for<'r> FnMut(&'r mut D, Vec3<i32>) -> f32 + 'a,
|
FL: for<'r> FnMut(&'r mut D, Vec3<i32>) -> f32 + 'a,
|
||||||
FG: for<'r> FnMut(&'r mut D, Vec3<i32>) -> f32 + 'a,
|
FG: for<'r> FnMut(&'r mut D, Vec3<i32>) -> f32 + 'a,
|
||||||
FO: for<'r> FnMut(&'r mut D, Vec3<i32>) -> bool + 'a,
|
FO: for<'r> FnMut(&'r mut D, Vec3<i32>) -> bool + 'a,
|
||||||
FS: for<'r> FnMut(&'r mut D, Vec3<i32>, Vec3<i32>, Vec2<Vec3<i32>>) -> Option<(bool, M)>,
|
FS: for<'r> FnMut(&'r mut D, Vec3<i32>, Vec3<i32>, Vec2<Vec3<i32>>) -> Option<(bool, M)>,
|
||||||
FP: FnMut(Vec2<u16>, Vec2<Vec2<u16>>, Vec3<f32>, Vec2<Vec3<f32>>, Vec3<f32>, &M),
|
FP: FnMut(Vec2<u16>, Vec2<Vec2<u16>>, Vec3<f32>, Vec2<Vec3<f32>>, Vec3<f32>, &M),
|
||||||
FT: for<'r> FnMut(&'r mut D, Vec3<i32>, u8, u8) -> [u8; 4] + 'a,
|
FT: for<'r> FnMut(&'r mut D, Vec3<i32>, u8, u8, bool) -> [u8; 4] + 'a,
|
||||||
{
|
{
|
||||||
span!(_guard, "greedy_mesh");
|
span!(_guard, "greedy_mesh");
|
||||||
// TODO: Collect information to see if we can choose a good value here.
|
// TODO: Collect information to see if we can choose a good value here.
|
||||||
@ -573,6 +581,7 @@ where
|
|||||||
&mut data,
|
&mut data,
|
||||||
todo_rects,
|
todo_rects,
|
||||||
draw_delta,
|
draw_delta,
|
||||||
|
get_ao,
|
||||||
get_light,
|
get_light,
|
||||||
get_glow,
|
get_glow,
|
||||||
get_opacity,
|
get_opacity,
|
||||||
@ -725,10 +734,11 @@ fn draw_col_lights<D>(
|
|||||||
data: &mut D,
|
data: &mut D,
|
||||||
todo_rects: Vec<TodoRect>,
|
todo_rects: Vec<TodoRect>,
|
||||||
draw_delta: Vec3<i32>,
|
draw_delta: Vec3<i32>,
|
||||||
|
mut get_ao: impl FnMut(&mut D, Vec3<i32>) -> f32,
|
||||||
mut get_light: impl FnMut(&mut D, Vec3<i32>) -> f32,
|
mut get_light: impl FnMut(&mut D, Vec3<i32>) -> f32,
|
||||||
mut get_glow: impl FnMut(&mut D, Vec3<i32>) -> f32,
|
mut get_glow: impl FnMut(&mut D, Vec3<i32>) -> f32,
|
||||||
mut get_opacity: impl FnMut(&mut D, Vec3<i32>) -> bool,
|
mut get_opacity: impl FnMut(&mut D, Vec3<i32>) -> bool,
|
||||||
mut make_face_texel: impl FnMut(&mut D, Vec3<i32>, u8, u8) -> [u8; 4],
|
mut make_face_texel: impl FnMut(&mut D, Vec3<i32>, u8, u8, bool) -> [u8; 4],
|
||||||
) {
|
) {
|
||||||
todo_rects.into_iter().for_each(|(pos, uv, rect, delta)| {
|
todo_rects.into_iter().for_each(|(pos, uv, rect, delta)| {
|
||||||
// NOTE: Conversions are safe because width, height, and offset must be
|
// NOTE: Conversions are safe because width, height, and offset must be
|
||||||
@ -793,6 +803,15 @@ fn draw_col_lights<D>(
|
|||||||
0.0
|
0.0
|
||||||
}
|
}
|
||||||
) / 4.0;
|
) / 4.0;
|
||||||
|
let ao = (get_ao(data, light_pos)
|
||||||
|
+ get_ao(data, light_pos - uv.x)
|
||||||
|
+ get_ao(data, light_pos - uv.y)
|
||||||
|
+ if direct_u_opacity || direct_v_opacity {
|
||||||
|
get_ao(data, light_pos - uv.x - uv.y)
|
||||||
|
} else {
|
||||||
|
0.0
|
||||||
|
})
|
||||||
|
/ 4.0;
|
||||||
let glowiness = (get_glow(data, light_pos)
|
let glowiness = (get_glow(data, light_pos)
|
||||||
+ get_glow(data, light_pos - uv.x)
|
+ get_glow(data, light_pos - uv.x)
|
||||||
+ get_glow(data, light_pos - uv.y)
|
+ get_glow(data, light_pos - uv.y)
|
||||||
@ -804,7 +823,8 @@ fn draw_col_lights<D>(
|
|||||||
/ 4.0;
|
/ 4.0;
|
||||||
let light = (darkness * 31.5) as u8;
|
let light = (darkness * 31.5) as u8;
|
||||||
let glow = (glowiness * 31.5) as u8;
|
let glow = (glowiness * 31.5) as u8;
|
||||||
*col_light = make_face_texel(data, pos, light, glow);
|
let ao = ao > 0.7;
|
||||||
|
*col_light = make_face_texel(data, pos, light, glow, ao);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -78,6 +78,7 @@ where
|
|||||||
draw_delta,
|
draw_delta,
|
||||||
greedy_size,
|
greedy_size,
|
||||||
greedy_size_cross,
|
greedy_size_cross,
|
||||||
|
get_ao: |_: &mut V, _: Vec3<i32>| 1.0,
|
||||||
get_light,
|
get_light,
|
||||||
get_glow,
|
get_glow,
|
||||||
get_opacity,
|
get_opacity,
|
||||||
@ -93,7 +94,7 @@ where
|
|||||||
|atlas_pos, pos, norm, &_meta| create_opaque(atlas_pos, pos, norm),
|
|atlas_pos, pos, norm, &_meta| create_opaque(atlas_pos, pos, norm),
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
make_face_texel: |vol: &mut V, pos, light, _| {
|
make_face_texel: |vol: &mut V, pos, light, _, _| {
|
||||||
let cell = vol.get(pos).ok();
|
let cell = vol.get(pos).ok();
|
||||||
let (glowy, shiny) = cell
|
let (glowy, shiny) = cell
|
||||||
.map(|c| (c.is_glowy(), c.is_shiny()))
|
.map(|c| (c.is_glowy(), c.is_shiny()))
|
||||||
@ -218,6 +219,7 @@ where
|
|||||||
draw_delta,
|
draw_delta,
|
||||||
greedy_size,
|
greedy_size,
|
||||||
greedy_size_cross,
|
greedy_size_cross,
|
||||||
|
get_ao: |_: &mut _, _: Vec3<i32>| 1.0,
|
||||||
get_light,
|
get_light,
|
||||||
get_glow,
|
get_glow,
|
||||||
get_opacity,
|
get_opacity,
|
||||||
@ -233,8 +235,8 @@ where
|
|||||||
|atlas_pos, pos, norm, &meta| create_opaque(atlas_pos, pos, norm, meta),
|
|atlas_pos, pos, norm, &meta| create_opaque(atlas_pos, pos, norm, meta),
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
make_face_texel: move |flat: &mut _, pos, light, glow| {
|
make_face_texel: move |flat: &mut _, pos, light, glow, ao| {
|
||||||
TerrainVertex::make_col_light(light, glow, get_color(flat, pos))
|
TerrainVertex::make_col_light(light, glow, get_color(flat, pos), ao)
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -305,6 +307,7 @@ where
|
|||||||
draw_delta,
|
draw_delta,
|
||||||
greedy_size,
|
greedy_size,
|
||||||
greedy_size_cross,
|
greedy_size_cross,
|
||||||
|
get_ao: |_: &mut V, _: Vec3<i32>| 1.0,
|
||||||
get_light,
|
get_light,
|
||||||
get_glow,
|
get_glow,
|
||||||
get_opacity,
|
get_opacity,
|
||||||
@ -320,8 +323,8 @@ where
|
|||||||
|atlas_pos, pos, norm, &_meta| create_opaque(atlas_pos, pos, norm),
|
|atlas_pos, pos, norm, &_meta| create_opaque(atlas_pos, pos, norm),
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
make_face_texel: move |vol: &mut V, pos, light, glow| {
|
make_face_texel: move |vol: &mut V, pos, light, glow, ao| {
|
||||||
TerrainVertex::make_col_light(light, glow, get_color(vol, pos))
|
TerrainVertex::make_col_light(light, glow, get_color(vol, pos), ao)
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -375,6 +375,9 @@ pub fn generate_mesh<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug + '
|
|||||||
light(pos + range.min)
|
light(pos + range.min)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
let get_ao = |_: &mut (), pos: Vec3<i32>| {
|
||||||
|
if flat_get(pos).is_opaque() { 0.0 } else { 1.0 }
|
||||||
|
};
|
||||||
let get_glow = |_: &mut (), pos: Vec3<i32>| glow(pos + range.min);
|
let get_glow = |_: &mut (), pos: Vec3<i32>| glow(pos + range.min);
|
||||||
let get_color =
|
let get_color =
|
||||||
|_: &mut (), pos: Vec3<i32>| flat_get(pos).get_color().unwrap_or_else(Rgb::zero);
|
|_: &mut (), pos: Vec3<i32>| flat_get(pos).get_color().unwrap_or_else(Rgb::zero);
|
||||||
@ -399,6 +402,7 @@ pub fn generate_mesh<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug + '
|
|||||||
draw_delta,
|
draw_delta,
|
||||||
greedy_size,
|
greedy_size,
|
||||||
greedy_size_cross,
|
greedy_size_cross,
|
||||||
|
get_ao,
|
||||||
get_light,
|
get_light,
|
||||||
get_glow,
|
get_glow,
|
||||||
get_opacity,
|
get_opacity,
|
||||||
@ -427,8 +431,8 @@ pub fn generate_mesh<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug + '
|
|||||||
));
|
));
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
make_face_texel: |data: &mut (), pos, light, glow| {
|
make_face_texel: |data: &mut (), pos, light, glow, ao| {
|
||||||
TerrainVertex::make_col_light(light, glow, get_color(data, pos))
|
TerrainVertex::make_col_light(light, glow, get_color(data, pos), ao)
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -67,6 +67,7 @@ impl Vertex {
|
|||||||
// 0 to 31
|
// 0 to 31
|
||||||
glow: u8,
|
glow: u8,
|
||||||
col: Rgb<u8>,
|
col: Rgb<u8>,
|
||||||
|
ao: bool,
|
||||||
) -> [u8; 4] {
|
) -> [u8; 4] {
|
||||||
//[col.r, col.g, col.b, light]
|
//[col.r, col.g, col.b, light]
|
||||||
// It would be nice for this to be cleaner, but we want to squeeze 5 fields into
|
// It would be nice for this to be cleaner, but we want to squeeze 5 fields into
|
||||||
@ -92,7 +93,7 @@ impl Vertex {
|
|||||||
(light.min(31) << 3) | ((col.r >> 1) & 0b111),
|
(light.min(31) << 3) | ((col.r >> 1) & 0b111),
|
||||||
(glow.min(31) << 3) | ((col.b >> 1) & 0b111),
|
(glow.min(31) << 3) | ((col.b >> 1) & 0b111),
|
||||||
(col.r & 0b11110000) | (col.b >> 4),
|
(col.r & 0b11110000) | (col.b >> 4),
|
||||||
col.g, // Green is lucky, it remains unscathed
|
(col.g & 0xFE) | ao as u8, // Green is lucky, it remains unscathed
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ use common::{
|
|||||||
assets::{AssetExt, DotVoxAsset},
|
assets::{AssetExt, DotVoxAsset},
|
||||||
comp::{
|
comp::{
|
||||||
self, aura, beam, body, buff, item::Reagent, object, shockwave, BeamSegment, Body,
|
self, aura, beam, body, buff, item::Reagent, object, shockwave, BeamSegment, Body,
|
||||||
CharacterState, Shockwave, Vel,
|
CharacterState, Ori, Pos, Shockwave, Vel,
|
||||||
},
|
},
|
||||||
figure::Segment,
|
figure::Segment,
|
||||||
outcome::Outcome,
|
outcome::Outcome,
|
||||||
@ -763,13 +763,18 @@ impl ParticleMgr {
|
|||||||
let time = state.get_time();
|
let time = state.get_time();
|
||||||
let dt = scene_data.state.ecs().fetch::<DeltaTime>().0;
|
let dt = scene_data.state.ecs().fetch::<DeltaTime>().0;
|
||||||
|
|
||||||
for (interpolated, beam) in (
|
for (interp, pos, ori, beam) in (
|
||||||
&ecs.read_storage::<Interpolated>(),
|
ecs.read_storage::<Interpolated>().maybe(),
|
||||||
|
&ecs.read_storage::<Pos>(),
|
||||||
|
&ecs.read_storage::<Ori>(),
|
||||||
&ecs.read_storage::<BeamSegment>(),
|
&ecs.read_storage::<BeamSegment>(),
|
||||||
)
|
)
|
||||||
.join()
|
.join()
|
||||||
.filter(|(_, b)| b.creation.map_or(true, |c| (c + dt as f64) >= time))
|
.filter(|(_, _, _, b)| b.creation.map_or(true, |c| (c + dt as f64) >= time))
|
||||||
{
|
{
|
||||||
|
let pos = interp.map_or(pos.0, |i| i.pos);
|
||||||
|
let ori = interp.map_or(*ori, |i| i.ori);
|
||||||
|
|
||||||
// TODO: Handle this less hackily. Done this way as beam segments are created
|
// TODO: Handle this less hackily. Done this way as beam segments are created
|
||||||
// every server tick, which is approximately 33 ms. Heartbeat scheduler used to
|
// every server tick, which is approximately 33 ms. Heartbeat scheduler used to
|
||||||
// account for clients with less than 30 fps because they start the creation
|
// account for clients with less than 30 fps because they start the creation
|
||||||
@ -779,11 +784,11 @@ impl ParticleMgr {
|
|||||||
match beam.properties.specifier {
|
match beam.properties.specifier {
|
||||||
beam::FrontendSpecifier::Flamethrower => {
|
beam::FrontendSpecifier::Flamethrower => {
|
||||||
let mut rng = thread_rng();
|
let mut rng = thread_rng();
|
||||||
let (from, to) = (Vec3::<f32>::unit_z(), *interpolated.ori.look_dir());
|
let (from, to) = (Vec3::<f32>::unit_z(), *ori.look_dir());
|
||||||
let m = Mat3::<f32>::rotation_from_to_3d(from, to);
|
let m = Mat3::<f32>::rotation_from_to_3d(from, to);
|
||||||
// Emit a light when using flames
|
// Emit a light when using flames
|
||||||
lights.push(Light::new(
|
lights.push(Light::new(
|
||||||
interpolated.pos,
|
pos,
|
||||||
Rgb::new(1.0, 0.25, 0.05).map(|e| e * rng.gen_range(0.8..1.2)),
|
Rgb::new(1.0, 0.25, 0.05).map(|e| e * rng.gen_range(0.8..1.2)),
|
||||||
2.0,
|
2.0,
|
||||||
));
|
));
|
||||||
@ -802,19 +807,19 @@ impl ParticleMgr {
|
|||||||
beam.properties.duration,
|
beam.properties.duration,
|
||||||
time,
|
time,
|
||||||
ParticleMode::FlameThrower,
|
ParticleMode::FlameThrower,
|
||||||
interpolated.pos,
|
pos,
|
||||||
interpolated.pos + random_ori * range,
|
pos + random_ori * range,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
beam::FrontendSpecifier::Cultist => {
|
beam::FrontendSpecifier::Cultist => {
|
||||||
let mut rng = thread_rng();
|
let mut rng = thread_rng();
|
||||||
let (from, to) = (Vec3::<f32>::unit_z(), *interpolated.ori.look_dir());
|
let (from, to) = (Vec3::<f32>::unit_z(), *ori.look_dir());
|
||||||
let m = Mat3::<f32>::rotation_from_to_3d(from, to);
|
let m = Mat3::<f32>::rotation_from_to_3d(from, to);
|
||||||
// Emit a light when using flames
|
// Emit a light when using flames
|
||||||
lights.push(Light::new(
|
lights.push(Light::new(
|
||||||
interpolated.pos,
|
pos,
|
||||||
Rgb::new(1.0, 0.0, 1.0).map(|e| e * rng.gen_range(0.5..1.0)),
|
Rgb::new(1.0, 0.0, 1.0).map(|e| e * rng.gen_range(0.5..1.0)),
|
||||||
2.0,
|
2.0,
|
||||||
));
|
));
|
||||||
@ -833,23 +838,23 @@ impl ParticleMgr {
|
|||||||
beam.properties.duration,
|
beam.properties.duration,
|
||||||
time,
|
time,
|
||||||
ParticleMode::CultistFlame,
|
ParticleMode::CultistFlame,
|
||||||
interpolated.pos,
|
pos,
|
||||||
interpolated.pos + random_ori * range,
|
pos + random_ori * range,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
beam::FrontendSpecifier::LifestealBeam => {
|
beam::FrontendSpecifier::LifestealBeam => {
|
||||||
// Emit a light when using lifesteal beam
|
// Emit a light when using lifesteal beam
|
||||||
lights.push(Light::new(interpolated.pos, Rgb::new(0.8, 1.0, 0.5), 1.0));
|
lights.push(Light::new(pos, Rgb::new(0.8, 1.0, 0.5), 1.0));
|
||||||
self.particles.reserve(beam_tick_count as usize);
|
self.particles.reserve(beam_tick_count as usize);
|
||||||
for i in 0..beam_tick_count {
|
for i in 0..beam_tick_count {
|
||||||
self.particles.push(Particle::new_directed(
|
self.particles.push(Particle::new_directed(
|
||||||
beam.properties.duration,
|
beam.properties.duration,
|
||||||
time + i as f64 / 1000.0,
|
time + i as f64 / 1000.0,
|
||||||
ParticleMode::LifestealBeam,
|
ParticleMode::LifestealBeam,
|
||||||
interpolated.pos,
|
pos,
|
||||||
interpolated.pos + *interpolated.ori.look_dir() * range,
|
pos + *ori.look_dir() * range,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -859,8 +864,8 @@ impl ParticleMgr {
|
|||||||
beam.properties.duration,
|
beam.properties.duration,
|
||||||
time,
|
time,
|
||||||
ParticleMode::Laser,
|
ParticleMode::Laser,
|
||||||
interpolated.pos,
|
pos,
|
||||||
interpolated.pos + *interpolated.ori.look_dir() * range,
|
pos + *ori.look_dir() * range,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
@ -870,14 +875,14 @@ impl ParticleMgr {
|
|||||||
beam.properties.duration,
|
beam.properties.duration,
|
||||||
time,
|
time,
|
||||||
ParticleMode::WebStrand,
|
ParticleMode::WebStrand,
|
||||||
interpolated.pos,
|
pos,
|
||||||
interpolated.pos + *interpolated.ori.look_dir() * range,
|
pos + *ori.look_dir() * range,
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
beam::FrontendSpecifier::Bubbles => {
|
beam::FrontendSpecifier::Bubbles => {
|
||||||
let mut rng = thread_rng();
|
let mut rng = thread_rng();
|
||||||
let (from, to) = (Vec3::<f32>::unit_z(), *interpolated.ori.look_dir());
|
let (from, to) = (Vec3::<f32>::unit_z(), *ori.look_dir());
|
||||||
let m = Mat3::<f32>::rotation_from_to_3d(from, to);
|
let m = Mat3::<f32>::rotation_from_to_3d(from, to);
|
||||||
self.particles.resize_with(
|
self.particles.resize_with(
|
||||||
self.particles.len() + usize::from(beam_tick_count) / 15,
|
self.particles.len() + usize::from(beam_tick_count) / 15,
|
||||||
@ -894,15 +899,15 @@ impl ParticleMgr {
|
|||||||
beam.properties.duration,
|
beam.properties.duration,
|
||||||
time,
|
time,
|
||||||
ParticleMode::Bubbles,
|
ParticleMode::Bubbles,
|
||||||
interpolated.pos,
|
pos,
|
||||||
interpolated.pos + random_ori * range,
|
pos + random_ori * range,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
beam::FrontendSpecifier::Frost => {
|
beam::FrontendSpecifier::Frost => {
|
||||||
let mut rng = thread_rng();
|
let mut rng = thread_rng();
|
||||||
let (from, to) = (Vec3::<f32>::unit_z(), *interpolated.ori.look_dir());
|
let (from, to) = (Vec3::<f32>::unit_z(), *ori.look_dir());
|
||||||
let m = Mat3::<f32>::rotation_from_to_3d(from, to);
|
let m = Mat3::<f32>::rotation_from_to_3d(from, to);
|
||||||
self.particles.resize_with(
|
self.particles.resize_with(
|
||||||
self.particles.len() + usize::from(beam_tick_count) / 4,
|
self.particles.len() + usize::from(beam_tick_count) / 4,
|
||||||
@ -919,8 +924,8 @@ impl ParticleMgr {
|
|||||||
beam.properties.duration,
|
beam.properties.duration,
|
||||||
time,
|
time,
|
||||||
ParticleMode::Ice,
|
ParticleMode::Ice,
|
||||||
interpolated.pos,
|
pos,
|
||||||
interpolated.pos + random_ori * range,
|
pos + random_ori * range,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -936,12 +941,15 @@ impl ParticleMgr {
|
|||||||
let mut rng = thread_rng();
|
let mut rng = thread_rng();
|
||||||
let dt = scene_data.state.get_delta_time();
|
let dt = scene_data.state.get_delta_time();
|
||||||
|
|
||||||
for (interpolated, auras) in (
|
for (interp, pos, auras) in (
|
||||||
&ecs.read_storage::<Interpolated>(),
|
ecs.read_storage::<Interpolated>().maybe(),
|
||||||
|
&ecs.read_storage::<Pos>(),
|
||||||
&ecs.read_storage::<comp::Auras>(),
|
&ecs.read_storage::<comp::Auras>(),
|
||||||
)
|
)
|
||||||
.join()
|
.join()
|
||||||
{
|
{
|
||||||
|
let pos = interp.map_or(pos.0, |i| i.pos);
|
||||||
|
|
||||||
for (_, aura) in auras.auras.iter() {
|
for (_, aura) in auras.auras.iter() {
|
||||||
match aura.aura_kind {
|
match aura.aura_kind {
|
||||||
aura::AuraKind::Buff {
|
aura::AuraKind::Buff {
|
||||||
@ -960,8 +968,8 @@ impl ParticleMgr {
|
|||||||
aura.duration.map_or(max_dur, |dur| dur.min(max_dur)),
|
aura.duration.map_or(max_dur, |dur| dur.min(max_dur)),
|
||||||
time,
|
time,
|
||||||
ParticleMode::EnergyNature,
|
ParticleMode::EnergyNature,
|
||||||
interpolated.pos,
|
pos,
|
||||||
interpolated.pos + init_pos,
|
pos + init_pos,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -992,8 +1000,8 @@ impl ParticleMgr {
|
|||||||
aura.duration.map_or(max_dur, |dur| dur.min(max_dur)),
|
aura.duration.map_or(max_dur, |dur| dur.min(max_dur)),
|
||||||
time,
|
time,
|
||||||
ParticleMode::EnergyHealing,
|
ParticleMode::EnergyHealing,
|
||||||
interpolated.pos,
|
pos,
|
||||||
interpolated.pos + init_pos,
|
pos + init_pos,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -1016,15 +1024,15 @@ impl ParticleMgr {
|
|||||||
let radius = aura.radius * rng.gen::<f32>().sqrt();
|
let radius = aura.radius * rng.gen::<f32>().sqrt();
|
||||||
let x = radius * theta.sin();
|
let x = radius * theta.sin();
|
||||||
let y = radius * theta.cos();
|
let y = radius * theta.cos();
|
||||||
Vec2::new(x, y) + interpolated.pos.xy()
|
Vec2::new(x, y) + pos.xy()
|
||||||
};
|
};
|
||||||
let max_dur = Duration::from_secs(1);
|
let max_dur = Duration::from_secs(1);
|
||||||
Particle::new_directed(
|
Particle::new_directed(
|
||||||
aura.duration.map_or(max_dur, |dur| dur.min(max_dur)),
|
aura.duration.map_or(max_dur, |dur| dur.min(max_dur)),
|
||||||
time,
|
time,
|
||||||
ParticleMode::FlameThrower,
|
ParticleMode::FlameThrower,
|
||||||
rand_pos.with_z(interpolated.pos.z),
|
rand_pos.with_z(pos.z),
|
||||||
rand_pos.with_z(interpolated.pos.z + 1.0),
|
rand_pos.with_z(pos.z + 1.0),
|
||||||
)
|
)
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -1044,8 +1052,8 @@ impl ParticleMgr {
|
|||||||
aura.duration.map_or(max_dur, |dur| dur.min(max_dur)),
|
aura.duration.map_or(max_dur, |dur| dur.min(max_dur)),
|
||||||
time,
|
time,
|
||||||
ParticleMode::EnergyBuffing,
|
ParticleMode::EnergyBuffing,
|
||||||
interpolated.pos,
|
pos,
|
||||||
interpolated.pos + init_pos,
|
pos + init_pos,
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -1062,13 +1070,16 @@ impl ParticleMgr {
|
|||||||
let time = state.get_time();
|
let time = state.get_time();
|
||||||
let mut rng = rand::thread_rng();
|
let mut rng = rand::thread_rng();
|
||||||
|
|
||||||
for (interpolated, buffs, body) in (
|
for (interp, pos, buffs, body) in (
|
||||||
&ecs.read_storage::<Interpolated>(),
|
ecs.read_storage::<Interpolated>().maybe(),
|
||||||
|
&ecs.read_storage::<Pos>(),
|
||||||
&ecs.read_storage::<comp::Buffs>(),
|
&ecs.read_storage::<comp::Buffs>(),
|
||||||
&ecs.read_storage::<comp::Body>(),
|
&ecs.read_storage::<comp::Body>(),
|
||||||
)
|
)
|
||||||
.join()
|
.join()
|
||||||
{
|
{
|
||||||
|
let pos = interp.map_or(pos.0, |i| i.pos);
|
||||||
|
|
||||||
for (buff_kind, _) in buffs.kinds.iter() {
|
for (buff_kind, _) in buffs.kinds.iter() {
|
||||||
use buff::BuffKind;
|
use buff::BuffKind;
|
||||||
match buff_kind {
|
match buff_kind {
|
||||||
@ -1077,7 +1088,7 @@ impl ParticleMgr {
|
|||||||
self.particles.len()
|
self.particles.len()
|
||||||
+ usize::from(self.scheduler.heartbeats(Duration::from_millis(15))),
|
+ usize::from(self.scheduler.heartbeats(Duration::from_millis(15))),
|
||||||
|| {
|
|| {
|
||||||
let start_pos = interpolated.pos
|
let start_pos = pos
|
||||||
+ Vec3::unit_z() * body.height() * 0.25
|
+ Vec3::unit_z() * body.height() * 0.25
|
||||||
+ Vec3::<f32>::zero()
|
+ Vec3::<f32>::zero()
|
||||||
.map(|_| rng.gen_range(-1.0..1.0))
|
.map(|_| rng.gen_range(-1.0..1.0))
|
||||||
@ -1107,7 +1118,7 @@ impl ParticleMgr {
|
|||||||
self.particles.len()
|
self.particles.len()
|
||||||
+ usize::from(self.scheduler.heartbeats(Duration::from_millis(15))),
|
+ usize::from(self.scheduler.heartbeats(Duration::from_millis(15))),
|
||||||
|| {
|
|| {
|
||||||
let start_pos = interpolated.pos
|
let start_pos = pos
|
||||||
+ Vec3::new(
|
+ Vec3::new(
|
||||||
body.max_radius(),
|
body.max_radius(),
|
||||||
body.max_radius(),
|
body.max_radius(),
|
||||||
@ -1361,13 +1372,18 @@ impl ParticleMgr {
|
|||||||
let dt = scene_data.state.ecs().fetch::<DeltaTime>().0;
|
let dt = scene_data.state.ecs().fetch::<DeltaTime>().0;
|
||||||
let terrain = scene_data.state.ecs().fetch::<TerrainGrid>();
|
let terrain = scene_data.state.ecs().fetch::<TerrainGrid>();
|
||||||
|
|
||||||
for (_entity, interpolated, shockwave) in (
|
for (_entity, interp, pos, ori, shockwave) in (
|
||||||
&ecs.entities(),
|
&ecs.entities(),
|
||||||
&ecs.read_storage::<Interpolated>(),
|
ecs.read_storage::<Interpolated>().maybe(),
|
||||||
|
&ecs.read_storage::<Pos>(),
|
||||||
|
&ecs.read_storage::<Ori>(),
|
||||||
&ecs.read_storage::<Shockwave>(),
|
&ecs.read_storage::<Shockwave>(),
|
||||||
)
|
)
|
||||||
.join()
|
.join()
|
||||||
{
|
{
|
||||||
|
let pos = interp.map_or(pos.0, |i| i.pos);
|
||||||
|
let ori = interp.map_or(*ori, |i| i.ori);
|
||||||
|
|
||||||
let elapsed = time - shockwave.creation.unwrap_or(time);
|
let elapsed = time - shockwave.creation.unwrap_or(time);
|
||||||
let speed = shockwave.properties.speed;
|
let speed = shockwave.properties.speed;
|
||||||
|
|
||||||
@ -1377,7 +1393,7 @@ impl ParticleMgr {
|
|||||||
|
|
||||||
let radians = shockwave.properties.angle.to_radians();
|
let radians = shockwave.properties.angle.to_radians();
|
||||||
|
|
||||||
let ori_vec = interpolated.ori.look_vec();
|
let ori_vec = ori.look_vec();
|
||||||
let theta = ori_vec.y.atan2(ori_vec.x) - radians / 2.0;
|
let theta = ori_vec.y.atan2(ori_vec.x) - radians / 2.0;
|
||||||
let dtheta = radians / distance;
|
let dtheta = radians / distance;
|
||||||
|
|
||||||
@ -1406,7 +1422,7 @@ impl ParticleMgr {
|
|||||||
for d in 0..(new_particle_count as i32) {
|
for d in 0..(new_particle_count as i32) {
|
||||||
let arc_position = theta + dtheta * d as f32 / particle_count_factor;
|
let arc_position = theta + dtheta * d as f32 / particle_count_factor;
|
||||||
|
|
||||||
let position = interpolated.pos
|
let position = pos
|
||||||
+ distance * Vec3::new(arc_position.cos(), arc_position.sin(), 0.0);
|
+ distance * Vec3::new(arc_position.cos(), arc_position.sin(), 0.0);
|
||||||
|
|
||||||
// Arbitrary number chosen that is large enough to be able to accurately
|
// Arbitrary number chosen that is large enough to be able to accurately
|
||||||
@ -1456,7 +1472,7 @@ impl ParticleMgr {
|
|||||||
for d in 0..3 * distance as i32 {
|
for d in 0..3 * distance as i32 {
|
||||||
let arc_position = theta + dtheta * d as f32 / 3.0;
|
let arc_position = theta + dtheta * d as f32 / 3.0;
|
||||||
|
|
||||||
let position = interpolated.pos
|
let position = pos
|
||||||
+ distance * Vec3::new(arc_position.cos(), arc_position.sin(), 0.0);
|
+ distance * Vec3::new(arc_position.cos(), arc_position.sin(), 0.0);
|
||||||
|
|
||||||
self.particles.push(Particle::new(
|
self.particles.push(Particle::new(
|
||||||
@ -1489,7 +1505,7 @@ impl ParticleMgr {
|
|||||||
// Sub tick dt
|
// Sub tick dt
|
||||||
let dt = (j as f32 / heartbeats as f32) * dt;
|
let dt = (j as f32 / heartbeats as f32) * dt;
|
||||||
let distance = distance + speed * dt;
|
let distance = distance + speed * dt;
|
||||||
let pos1 = interpolated.pos + distance * direction - Vec3::unit_z();
|
let pos1 = pos + distance * direction - Vec3::unit_z();
|
||||||
let pos2 = pos1 + (Vec3::unit_z() + direction) * 3.0;
|
let pos2 = pos1 + (Vec3::unit_z() + direction) * 3.0;
|
||||||
let time = time + dt as f64;
|
let time = time + dt as f64;
|
||||||
|
|
||||||
@ -1532,8 +1548,7 @@ impl ParticleMgr {
|
|||||||
// Sub tick dt
|
// Sub tick dt
|
||||||
let dt = (j as f32 / heartbeats as f32) * dt;
|
let dt = (j as f32 / heartbeats as f32) * dt;
|
||||||
let scaled_distance = scaled_distance + scaled_speed * dt;
|
let scaled_distance = scaled_distance + scaled_speed * dt;
|
||||||
let pos1 =
|
let pos1 = pos + (scaled_distance * direction).floor() * scale;
|
||||||
interpolated.pos + (scaled_distance * direction).floor() * scale;
|
|
||||||
let time = time + dt as f64;
|
let time = time + dt as f64;
|
||||||
|
|
||||||
let get_positions = |a| {
|
let get_positions = |a| {
|
||||||
|
@ -695,7 +695,7 @@ fn write_column<R: Rng>(
|
|||||||
* bridge) as i32)
|
* bridge) as i32)
|
||||||
.min(h - 2)
|
.min(h - 2)
|
||||||
&& z < bedrock + h
|
&& z < bedrock + h
|
||||||
&& radius > 30.0
|
&& radius > 25.0
|
||||||
} {
|
} {
|
||||||
Block::new(BlockKind::Rock, col.stone_col)
|
Block::new(BlockKind::Rock, col.stone_col)
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user