diff --git a/assets/voxygen/shaders/debug-frag.glsl b/assets/voxygen/shaders/debug-frag.glsl index f5909d13b7..34e0e5014c 100644 --- a/assets/voxygen/shaders/debug-frag.glsl +++ b/assets/voxygen/shaders/debug-frag.glsl @@ -60,17 +60,20 @@ void main() { float R_s = (f_pos.z < f_alt) ? mix(R_s2s1 * R_s1s0, R_s1s0, medium.x) : mix(R_s2s0, R_s1s2 * R_s2s0, medium.x); vec3 k_a = vec3(1.0); - vec3 k_d = vec3(1.0); + vec3 k_d = vec3(0.8); vec3 k_s = vec3(R_s); float max_light = 0.0; vec3 cam_attenuation = vec3(1); float fluid_alt = max(f_pos.z + 1, floor(f_alt + 1)); vec3 mu = medium.x == MEDIUM_WATER ? MU_WATER : vec3(0.0); - vec3 emitted_light, reflected_light; + vec3 emitted_light = vec3(1); + vec3 reflected_light = vec3(1); + max_light += get_sun_diffuse2(sun_info, moon_info, f_norm, view_dir, f_pos, 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); surf_color = illuminate(max_light, view_dir, surf_color * emitted_light, surf_color * reflected_light * 1.0); tgt_color = vec4(surf_color, 1.0); + //tgt_color = vec4(f_norm, 1.0); } diff --git a/assets/voxygen/shaders/terrain-frag.glsl b/assets/voxygen/shaders/terrain-frag.glsl index 16480d77b6..d46de874d0 100644 --- a/assets/voxygen/shaders/terrain-frag.glsl +++ b/assets/voxygen/shaders/terrain-frag.glsl @@ -530,4 +530,5 @@ void main() { surf_color += f_select * (surf_color + 0.1) * vec3(0.5, 0.5, 0.5); tgt_color = vec4(surf_color, f_alpha); + //tgt_color = vec4(f_norm, f_alpha); } diff --git a/voxygen/src/hud/chat.rs b/voxygen/src/hud/chat.rs index c9f85178c1..39b340e22e 100644 --- a/voxygen/src/hud/chat.rs +++ b/voxygen/src/hud/chat.rs @@ -226,7 +226,7 @@ impl<'a> Widget for Chat<'a> { // Log the output of commands since the ingame terminal doesn't support copying // the output to the clipboard if let ChatType::CommandInfo = message.chat_type { - tracing::info!("{}", message.message); + tracing::info!("Chat command info: {}", message.message); } } //new messages - update chat w/ them & scroll down if at bottom of chat diff --git a/voxygen/src/scene/debug.rs b/voxygen/src/scene/debug.rs index 3f28b69c6c..9cd121a621 100644 --- a/voxygen/src/scene/debug.rs +++ b/voxygen/src/scene/debug.rs @@ -51,7 +51,7 @@ fn box_along_line( ) { // dx is along b-a // dz is along b-d - let dx = Vec3::unit_z().cross(line.end - line.start).normalized(); + let dx = -Vec3::unit_z().cross(line.end - line.start).normalized(); let dz = dx.cross(line.end - line.start).normalized(); let w = width / 2.0; let h = height / 2.0; @@ -66,7 +66,7 @@ fn box_along_line( let h = r + w * dx - h * dz; let quad = |x: Vec3, y: Vec3, z: Vec3, w: Vec3| { - let normal = x.cross(y); + let normal = (y - x).cross(z - y).normalized(); Quad::::new( (x, color, normal).into(), (y, color, normal).into(), @@ -228,8 +228,8 @@ impl DebugShape { let end = path.evaluate((i + 1) as f32 * step_size); let center = LineSegment3 { start, end }; let dx = - *rail_sep * Vec3::unit_z().cross(center.end - center.start).normalized(); - let dz = -dx.cross(center.end - center.start).normalized(); + *rail_sep * -Vec3::unit_z().cross(center.end - center.start).normalized(); + let dz = dx.cross(center.end - center.start).normalized(); let left = LineSegment3 { start: center.start + dx, end: center.end + dx, diff --git a/voxygen/src/scene/mod.rs b/voxygen/src/scene/mod.rs index 99a98d0752..5a20ddbb3f 100644 --- a/voxygen/src/scene/mod.rs +++ b/voxygen/src/scene/mod.rs @@ -1305,8 +1305,10 @@ impl Scene { ) { let ecs = client.state().ecs(); { + let mut current_chunks = hashbrown::HashSet::new(); let terrain_grid = ecs.read_resource::(); for (key, chunk) in terrain_grid.iter() { + current_chunks.insert(key); tracks.entry(key).or_insert_with(|| { let mut ret = Vec::new(); for bezier in chunk.meta().tracks().iter() { @@ -1346,6 +1348,15 @@ impl Scene { ret }); } + tracks.retain(|k, v| { + let keep = current_chunks.contains(k); + if !keep { + for shape in v.iter() { + self.debug.remove_shape(*shape); + } + } + keep + }); } let mut current_entities = hashbrown::HashSet::new(); if settings.interface.toggle_hitboxes { diff --git a/world/src/layer/mod.rs b/world/src/layer/mod.rs index 87cbee9b6c..099f3e7cb4 100644 --- a/world/src/layer/mod.rs +++ b/world/src/layer/mod.rs @@ -14,6 +14,7 @@ pub use self::{ use crate::{ column::ColumnSample, config::CONFIG, + sim, util::{FastNoise, RandomField, RandomPerm, Sampler}, Canvas, CanvasInfo, IndexRef, }; @@ -148,6 +149,70 @@ pub fn apply_paths_to(canvas: &mut Canvas) { }); } +pub fn apply_trains_to( + canvas: &mut Canvas, + sim: &sim::WorldSim, + sim_chunk: &sim::SimChunk, + chunk_center_wpos2d: Vec2, +) { + let mut splines = Vec::new(); + let g = |v: Vec2| -> Vec3 { + let path_nearest = sim + .get_nearest_path(v.as_::()) + .map(|x| x.1) + .unwrap_or(v.as_::()); + let alt = if let Some(c) = canvas.col_or_gen(v.as_::()) { + let pl = PathLocals::new(canvas, &c, path_nearest); + pl.riverless_alt + pl.bridge_offset + 0.75 + } else { + sim_chunk.alt + }; + v.with_z(alt) + }; + fn hermite_to_bezier( + p0: Vec3, + m0: Vec3, + p3: Vec3, + m3: Vec3, + ) -> CubicBezier3 { + let hermite = Vec4::new(p0, p3, m0, m3); + let hermite = hermite.map(|v| v.with_w(0.0)); + let hermite: [[f32; 4]; 4] = hermite.map(|v: Vec4| v.into_array()).into_array(); + // https://courses.engr.illinois.edu/cs418/sp2009/notes/12-MoreSplines.pdf + let mut m = Mat4::from_row_arrays([ + [1.0, 0.0, 0.0, 0.0], + [0.0, 0.0, 0.0, 1.0], + [-3.0, 3.0, 0.0, 0.0], + [0.0, 0.0, -3.0, 3.0], + ]); + m.invert(); + let bezier = m * Mat4::from_row_arrays(hermite); + let bezier: Vec4> = + Vec4::<[f32; 4]>::from(bezier.into_row_arrays()).map(Vec4::from); + let bezier = bezier.map(Vec3::from); + CubicBezier3::from(bezier) + } + for sim::NearestWaysData { bezier: bez, .. } in + sim.get_nearest_ways(chunk_center_wpos2d, &|chunk| Some(chunk.path)) + { + if bez.length_by_discretization(16) < 0.125 { + continue; + } + let a = 0.0; + let b = 1.0; + for bez in bez.split((a + b) / 2.0) { + let p0 = g(bez.evaluate(a)); + let p1 = g(bez.evaluate(a + (b - a) / 3.0)); + let p2 = g(bez.evaluate(a + 2.0 * (b - a) / 3.0)); + let p3 = g(bez.evaluate(b)); + splines.push(hermite_to_bezier(p0, 3.0 * (p1 - p0), p3, 3.0 * (p3 - p2))); + } + } + for spline in splines.into_iter() { + canvas.chunk.meta_mut().add_track(spline); + } +} + pub fn apply_caves_to(canvas: &mut Canvas, rng: &mut impl Rng) { let info = canvas.info(); canvas.foreach_col(|canvas, wpos2d, col| { diff --git a/world/src/lib.rs b/world/src/lib.rs index 94635400e6..de5d9f6251 100644 --- a/world/src/lib.rs +++ b/world/src/lib.rs @@ -360,65 +360,7 @@ impl World { }; if index.features.train_tracks { - let mut splines = Vec::new(); - let g = |v: Vec2| -> Vec3 { - let path_nearest = self - .sim - .get_nearest_path(v.as_::()) - .map(|x| x.1) - .unwrap_or(v.as_::()); - let alt = if let Some(c) = canvas.col_or_gen(v.as_::()) { - let pl = PathLocals::new(&canvas, &c, path_nearest); - pl.riverless_alt + pl.bridge_offset + 0.75 - } else { - sim_chunk.alt - }; - v.with_z(alt) - }; - fn hermite_to_bezier( - p0: Vec3, - m0: Vec3, - p3: Vec3, - m3: Vec3, - ) -> CubicBezier3 { - let hermite = Vec4::new(p0, p3, m0, m3); - let hermite = hermite.map(|v| v.with_w(0.0)); - let hermite: [[f32; 4]; 4] = - hermite.map(|v: Vec4| v.into_array()).into_array(); - // https://courses.engr.illinois.edu/cs418/sp2009/notes/12-MoreSplines.pdf - let mut m = Mat4::from_row_arrays([ - [1.0, 0.0, 0.0, 0.0], - [0.0, 0.0, 0.0, 1.0], - [-3.0, 3.0, 0.0, 0.0], - [0.0, 0.0, -3.0, 3.0], - ]); - m.invert(); - let bezier = m * Mat4::from_row_arrays(hermite); - let bezier: Vec4> = - Vec4::<[f32; 4]>::from(bezier.into_row_arrays()).map(Vec4::from); - let bezier = bezier.map(Vec3::from); - CubicBezier3::from(bezier) - } - for (_, _, _, _, bez, _) in self - .sim - .get_nearest_ways(chunk_center_wpos2d, &|chunk| Some(chunk.path)) - { - if bez.length_by_discretization(16) < 0.125 { - continue; - } - let a = 0.0; - let b = 1.0; - for bez in bez.split((a + b) / 2.0) { - let p0 = g(bez.evaluate(a)); - let p1 = g(bez.evaluate(a + (b - a) / 3.0)); - let p2 = g(bez.evaluate(a + 2.0 * (b - a) / 3.0)); - let p3 = g(bez.evaluate(b)); - splines.push(hermite_to_bezier(p0, 3.0 * (p1 - p0), p3, 3.0 * (p3 - p2))); - } - } - for spline in splines.into_iter() { - canvas.chunk.meta_mut().add_track(spline); - } + layer::apply_trains_to(&mut canvas, &self.sim, sim_chunk, chunk_center_wpos2d); } if index.features.caverns { diff --git a/world/src/sim/mod.rs b/world/src/sim/mod.rs index 57a33e73d3..c9d5761993 100644 --- a/world/src/sim/mod.rs +++ b/world/src/sim/mod.rs @@ -2137,16 +2137,7 @@ impl WorldSim { &'a self, wpos: Vec2, get_way: &'a impl Fn(&SimChunk) -> Option<(Way, M)>, - ) -> impl Iterator< - Item = ( - usize, - f32, - Vec2, - M, - QuadraticBezier2, - impl FnOnce() -> Vec2, - ), - > + 'a { + ) -> impl Iterator Vec2>> + 'a { let chunk_pos = wpos.map2(TerrainChunkSize::RECT_SIZE, |e, sz: u32| { e.div_euclid(sz as i32) }); @@ -2216,9 +2207,16 @@ impl WorldSim { } else { Lerp::lerp(meta.clone(), end_meta, nearest_interval - 0.5) }; - Some((i, dist_sqrd, pos, meta, bez, move || { - bez.evaluate_derivative(nearest_interval).normalized() - })) + Some(NearestWaysData { + i, + dist_sqrd, + pos, + meta, + bezier: bez, + calc_tangent: move || { + bez.evaluate_derivative(nearest_interval).normalized() + }, + }) }), ) }) @@ -2235,8 +2233,16 @@ impl WorldSim { ) -> Option<(f32, Vec2, M, Vec2)> { let get_way = &get_way; self.get_nearest_ways(wpos, get_way) - .min_by_key(|(_, dist_sqrd, _, _, _, _)| (dist_sqrd * 1024.0) as i32) - .map(|(_, dist, pos, meta, _, calc_tangent)| (dist.sqrt(), pos, meta, calc_tangent())) + .min_by_key(|NearestWaysData { dist_sqrd, .. }| (dist_sqrd * 1024.0) as i32) + .map( + |NearestWaysData { + dist_sqrd, + pos, + meta, + calc_tangent, + .. + }| (dist_sqrd.sqrt(), pos, meta, calc_tangent()), + ) } pub fn get_nearest_path(&self, wpos: Vec2) -> Option<(f32, Vec2, Path, Vec2)> { @@ -2247,19 +2253,6 @@ impl WorldSim { self.get_nearest_way(wpos, |chunk| Some(chunk.cave)) } - pub fn get_nearest_path_for_direction( - &self, - wpos: Vec2, - dir: usize, - ) -> Option<(f32, Vec2, Path, QuadraticBezier2, Vec2)> { - self.get_nearest_ways(wpos, &|chunk| Some(chunk.path)) - .filter(|(i, _, _, _, _, _)| *i == dir) - .min_by_key(|(_, dist_sqrd, _, _, _, _)| (dist_sqrd * 1024.0) as i32) - .map(|(_, dist, pos, meta, bez, calc_tangent)| { - (dist.sqrt(), pos, meta, bez, calc_tangent()) - }) - } - /// Create a [`Lottery>`] that generates [`ForestKind`]s /// according to the conditions at the given position. If no or fewer /// trees are appropriate for the conditions, `None` may be generated. @@ -2366,6 +2359,15 @@ pub struct RegionInfo { pub seed: u32, } +pub struct NearestWaysData Vec2> { + pub i: usize, + pub dist_sqrd: f32, + pub pos: Vec2, + pub meta: M, + pub bezier: QuadraticBezier2, + pub calc_tangent: F, +} + impl SimChunk { fn generate(map_size_lg: MapSizeLg, posi: usize, gen_ctx: &GenCtx, gen_cdf: &GenCdf) -> Self { let pos = uniform_idx_as_vec2(map_size_lg, posi);