From 32509d2fb1cb2aa1358ad9f7dd1c4b251c546226 Mon Sep 17 00:00:00 2001 From: robojumper Date: Sun, 28 Apr 2019 16:29:54 +0200 Subject: [PATCH 1/3] Add terrain ambient occlusion Former-commit-id: de73dcb09f68bcad5dc7431c30849e16f68c5ab7 --- voxygen/src/mesh/terrain.rs | 108 +++++++++++++++++++++++++----------- 1 file changed, 77 insertions(+), 31 deletions(-) diff --git a/voxygen/src/mesh/terrain.rs b/voxygen/src/mesh/terrain.rs index b6cd2dd67e..f6500d7ca4 100644 --- a/voxygen/src/mesh/terrain.rs +++ b/voxygen/src/mesh/terrain.rs @@ -3,43 +3,46 @@ use vek::*; // Project use common::{ - vol::{ - Vox, - SizedVol, - ReadVol, - }, - volumes::dyna::Dyna, terrain::Block, + vol::{ReadVol, SizedVol, Vox}, + volumes::dyna::Dyna, }; // Crate use crate::{ mesh::Meshable, - render::{ - self, - Mesh, - Quad, - TerrainPipeline, - }, + render::{self, Mesh, Quad, TerrainPipeline}, }; type TerrainVertex = ::Vertex; // Utility function -// TODO: Evaluate how useful this is fn create_quad( origin: Vec3, unit_x: Vec3, unit_y: Vec3, norm: Vec3, col: Rgb, + ao: Vec4, ) -> Quad { - Quad::new( - TerrainVertex::new(origin, norm, col), - TerrainVertex::new(origin + unit_x, norm, col), - TerrainVertex::new(origin + unit_x + unit_y, norm, col), - TerrainVertex::new(origin + unit_y, norm, col), - ) + let ao_scale = 1.0; + let dark = col * (1.0 - ao_scale); + + if ao[0] + ao[2] < ao[1] + ao[3] { + Quad::new( + TerrainVertex::new(origin + unit_y, norm, Rgb::lerp(dark, col, ao[3])), + TerrainVertex::new(origin, norm, Rgb::lerp(dark, col, ao[0])), + TerrainVertex::new(origin + unit_x, norm, Rgb::lerp(dark, col, ao[1])), + TerrainVertex::new(origin + unit_x + unit_y, norm, Rgb::lerp(dark, col, ao[2])), + ) + } else { + Quad::new( + TerrainVertex::new(origin, norm, Rgb::lerp(dark, col, ao[0])), + TerrainVertex::new(origin + unit_x, norm, Rgb::lerp(dark, col, ao[1])), + TerrainVertex::new(origin + unit_x + unit_y, norm, Rgb::lerp(dark, col, ao[2])), + TerrainVertex::new(origin + unit_y, norm, Rgb::lerp(dark, col, ao[3])), + ) + } } impl Meshable for Dyna { @@ -52,19 +55,51 @@ impl Meshable for Dyna { for pos in self .iter_positions() .filter(|pos| pos.map(|e| e >= 1).reduce_and()) - .filter(|pos| pos.map2(self.get_size(), |e, sz| e < sz as i32 - 1).reduce_and()) + .filter(|pos| { + pos.map2(self.get_size(), |e, sz| e < sz as i32 - 1) + .reduce_and() + }) { let offs = pos.map(|e| e as f32 - 1.0); - if let Some(col) = self - .get(pos) - .ok() - .and_then(|vox| vox.get_color()) - { + if let Some(col) = self.get(pos).ok().and_then(|vox| vox.get_color()) { let col = col.map(|e| e as f32 / 255.0); + let (x, y, z) = (Vec3::unit_x(), Vec3::unit_y(), Vec3::unit_z()); + + fn get_ao( + dyna: &Dyna, + pos: Vec3, + dirs: &[Vec3], + ) -> Vec4 { + dirs.windows(2) + .map(|offs| { + let (s1, s2) = ( + dyna.get(pos + offs[0]) + .map(|v| v.is_empty() as i32) + .unwrap_or(1), + dyna.get(pos + offs[1]) + .map(|v| v.is_empty() as i32) + .unwrap_or(1), + ); + + if s1 == 0 && s2 == 0 { + 0 + } else { + let corner = dyna + .get(pos + offs[0] + offs[1]) + .map(|v| v.is_empty() as i32) + .unwrap_or(1); + s1 + s2 + corner + } + }) + .map(|i| i as f32 / 3.0) + .collect::>() + } + // -x - if self.get(pos - Vec3::unit_x()) + if self + .get(pos - Vec3::unit_x()) .map(|v| v.is_empty()) .unwrap_or(true) { @@ -74,10 +109,12 @@ impl Meshable for Dyna { Vec3::unit_y(), -Vec3::unit_x(), col, + get_ao(self, pos - Vec3::unit_x(), &[-z, -y, z, y, -z]), )); } // +x - if self.get(pos + Vec3::unit_x()) + if self + .get(pos + Vec3::unit_x()) .map(|v| v.is_empty()) .unwrap_or(true) { @@ -87,10 +124,12 @@ impl Meshable for Dyna { Vec3::unit_z(), Vec3::unit_x(), col, + get_ao(self, pos + Vec3::unit_x(), &[-y, -z, y, z, -y]), )); } // -y - if self.get(pos - Vec3::unit_y()) + if self + .get(pos - Vec3::unit_y()) .map(|v| v.is_empty()) .unwrap_or(true) { @@ -100,10 +139,12 @@ impl Meshable for Dyna { Vec3::unit_z(), -Vec3::unit_y(), col, + get_ao(self, pos - Vec3::unit_y(), &[-x, -z, x, z, -x]), )); } // +y - if self.get(pos + Vec3::unit_y()) + if self + .get(pos + Vec3::unit_y()) .map(|v| v.is_empty()) .unwrap_or(true) { @@ -113,10 +154,12 @@ impl Meshable for Dyna { Vec3::unit_x(), Vec3::unit_y(), col, + get_ao(self, pos + Vec3::unit_y(), &[-z, -x, z, x, -z]), )); } // -z - if self.get(pos - Vec3::unit_z()) + if self + .get(pos - Vec3::unit_z()) .map(|v| v.is_empty()) .unwrap_or(true) { @@ -126,10 +169,12 @@ impl Meshable for Dyna { Vec3::unit_x(), -Vec3::unit_z(), col, + get_ao(self, pos - Vec3::unit_z(), &[-y, -x, y, x, -y]), )); } // +z - if self.get(pos + Vec3::unit_z()) + if self + .get(pos + Vec3::unit_z()) .map(|v| v.is_empty()) .unwrap_or(true) { @@ -139,6 +184,7 @@ impl Meshable for Dyna { Vec3::unit_y(), Vec3::unit_z(), col, + get_ao(self, pos + Vec3::unit_z(), &[-x, -y, x, y, -x]), )); } } From 021c6eeda1dfbf62759679e90e377a38cc14c9c3 Mon Sep 17 00:00:00 2001 From: robojumper Date: Sun, 28 Apr 2019 19:12:45 +0200 Subject: [PATCH 2/3] Generalize meshing and AO code over terrain, figure Former-commit-id: f0a91173ec5a0a9c683e6d1c222cb74e858625b7 --- voxygen/src/mesh/ao.rs | 177 ++++++++++++++++++++++++++++++++++++ voxygen/src/mesh/mod.rs | 6 +- voxygen/src/mesh/segment.rs | 131 +++----------------------- voxygen/src/mesh/terrain.rs | 154 +------------------------------ 4 files changed, 195 insertions(+), 273 deletions(-) create mode 100644 voxygen/src/mesh/ao.rs diff --git a/voxygen/src/mesh/ao.rs b/voxygen/src/mesh/ao.rs new file mode 100644 index 0000000000..8edeaec63b --- /dev/null +++ b/voxygen/src/mesh/ao.rs @@ -0,0 +1,177 @@ +use vek::*; + +use common::vol::{ReadVol, Vox}; + +use crate::render::{ + mesh::{Mesh, Quad}, + Pipeline, +}; + +/// Given a volume, a position and the cardinal directions, compute each vertex' AO value +/// `dirs` should be a slice of length 5 so that the sliding window of size 2 over the slice +/// yields each vertex' adjacent positions. +fn get_quad_ao(vol: &V, pos: Vec3, dirs: &[Vec3]) -> Vec4 { + dirs.windows(2) + .map(|offs| { + let (s1, s2) = ( + vol.get(pos + offs[0]) + .map(|v| v.is_empty() as i32) + .unwrap_or(1), + vol.get(pos + offs[1]) + .map(|v| v.is_empty() as i32) + .unwrap_or(1), + ); + + if s1 == 0 && s2 == 0 { + 0 + } else { + let corner = vol + .get(pos + offs[0] + offs[1]) + .map(|v| v.is_empty() as i32) + .unwrap_or(1); + s1 + s2 + corner + } + }) + .map(|i| i as f32 / 3.0) + .collect::>() +} + +type VertexCons = fn(Vec3, Vec3, Rgb) -> P::Vertex; + +// Utility function +fn create_quad( + origin: Vec3, + unit_x: Vec3, + unit_y: Vec3, + norm: Vec3, + col: Rgb, + ao: Vec4, + vcons: VertexCons

, +) -> Quad

{ + let ao_scale = 1.0; + let dark = col * (1.0 - ao_scale); + + if ao[0] + ao[2] < ao[1] + ao[3] { + Quad::new( + vcons(origin + unit_y, norm, Rgb::lerp(dark, col, ao[3])), + vcons(origin, norm, Rgb::lerp(dark, col, ao[0])), + vcons(origin + unit_x, norm, Rgb::lerp(dark, col, ao[1])), + vcons(origin + unit_x + unit_y, norm, Rgb::lerp(dark, col, ao[2])), + ) + } else { + Quad::new( + vcons(origin, norm, Rgb::lerp(dark, col, ao[0])), + vcons(origin + unit_x, norm, Rgb::lerp(dark, col, ao[1])), + vcons(origin + unit_x + unit_y, norm, Rgb::lerp(dark, col, ao[2])), + vcons(origin + unit_y, norm, Rgb::lerp(dark, col, ao[3])), + ) + } +} + +pub fn push_vox_verts_ao( + mesh: &mut Mesh

, + vol: &V, + pos: Vec3, + offs: Vec3, + col: Rgb, + vcons: VertexCons

, +) { + let (x, y, z) = (Vec3::unit_x(), Vec3::unit_y(), Vec3::unit_z()); + + // -x + if vol + .get(pos - Vec3::unit_x()) + .map(|v| v.is_empty()) + .unwrap_or(true) + { + mesh.push_quad(create_quad( + offs, + Vec3::unit_z(), + Vec3::unit_y(), + -Vec3::unit_x(), + col, + get_quad_ao(vol, pos - Vec3::unit_x(), &[-z, -y, z, y, -z]), + vcons, + )); + } + // +x + if vol + .get(pos + Vec3::unit_x()) + .map(|v| v.is_empty()) + .unwrap_or(true) + { + mesh.push_quad(create_quad( + offs + Vec3::unit_x(), + Vec3::unit_y(), + Vec3::unit_z(), + Vec3::unit_x(), + col, + get_quad_ao(vol, pos + Vec3::unit_x(), &[-y, -z, y, z, -y]), + vcons, + )); + } + // -y + if vol + .get(pos - Vec3::unit_y()) + .map(|v| v.is_empty()) + .unwrap_or(true) + { + mesh.push_quad(create_quad( + offs, + Vec3::unit_x(), + Vec3::unit_z(), + -Vec3::unit_y(), + col, + get_quad_ao(vol, pos - Vec3::unit_y(), &[-x, -z, x, z, -x]), + vcons, + )); + } + // +y + if vol + .get(pos + Vec3::unit_y()) + .map(|v| v.is_empty()) + .unwrap_or(true) + { + mesh.push_quad(create_quad( + offs + Vec3::unit_y(), + Vec3::unit_z(), + Vec3::unit_x(), + Vec3::unit_y(), + col, + get_quad_ao(vol, pos + Vec3::unit_y(), &[-z, -x, z, x, -z]), + vcons, + )); + } + // -z + if vol + .get(pos - Vec3::unit_z()) + .map(|v| v.is_empty()) + .unwrap_or(true) + { + mesh.push_quad(create_quad( + offs, + Vec3::unit_y(), + Vec3::unit_x(), + -Vec3::unit_z(), + col, + get_quad_ao(vol, pos - Vec3::unit_z(), &[-y, -x, y, x, -y]), + vcons, + )); + } + // +z + if vol + .get(pos + Vec3::unit_z()) + .map(|v| v.is_empty()) + .unwrap_or(true) + { + mesh.push_quad(create_quad( + offs + Vec3::unit_z(), + Vec3::unit_x(), + Vec3::unit_y(), + Vec3::unit_z(), + col, + get_quad_ao(vol, pos + Vec3::unit_z(), &[-x, -y, x, y, -x]), + vcons, + )); + } +} diff --git a/voxygen/src/mesh/mod.rs b/voxygen/src/mesh/mod.rs index 1f938ff930..e9ff529c9d 100644 --- a/voxygen/src/mesh/mod.rs +++ b/voxygen/src/mesh/mod.rs @@ -1,11 +1,9 @@ +mod ao; pub mod segment; pub mod terrain; // Crate -use crate::render::{ - self, - Mesh, -}; +use crate::render::{self, Mesh}; pub trait Meshable { type Pipeline: render::Pipeline; diff --git a/voxygen/src/mesh/segment.rs b/voxygen/src/mesh/segment.rs index d7eb6d4274..97333017ef 100644 --- a/voxygen/src/mesh/segment.rs +++ b/voxygen/src/mesh/segment.rs @@ -3,43 +3,20 @@ use vek::*; // Project use common::{ - vol::{ - Vox, - SizedVol, - ReadVol, - }, figure::Segment, + vol::{ReadVol, SizedVol, Vox}, }; // Crate use crate::{ - mesh::Meshable, - render::{ - self, - Mesh, - Quad, - FigurePipeline, - }, + mesh::{ao, Meshable}, + render::{self, FigurePipeline, Mesh, Quad}, }; type FigureVertex = ::Vertex; -// Utility function -// TODO: Evaluate how useful this is -fn create_quad( - origin: Vec3, - unit_x: Vec3, - unit_y: Vec3, - norm: Vec3, - col: Rgb, - bone: u8, -) -> Quad { - Quad::new( - FigureVertex::new(origin, norm, col, bone), - FigureVertex::new(origin + unit_x, norm, col, bone), - FigureVertex::new(origin + unit_x + unit_y, norm, col, bone), - FigureVertex::new(origin + unit_y, norm, col, bone), - ) +fn create_vertex(origin: Vec3, norm: Vec3, col: Rgb) -> FigureVertex { + FigureVertex::new(origin, norm, col, 0) } impl Meshable for Segment { @@ -50,97 +27,17 @@ impl Meshable for Segment { let mut mesh = Mesh::new(); for pos in self.iter_positions() { - if let Some(col) = self - .get(pos) - .ok() - .and_then(|vox| vox.get_color()) - { + if let Some(col) = self.get(pos).ok().and_then(|vox| vox.get_color()) { let col = col.map(|e| e as f32 / 255.0); - // -x - if self.get(pos - Vec3::unit_x()) - .map(|v| v.is_empty()) - .unwrap_or(true) - { - mesh.push_quad(create_quad( - offs + pos.map(|e| e as f32) + Vec3::unit_y(), - -Vec3::unit_y(), - Vec3::unit_z(), - -Vec3::unit_x(), - col, - 0, - )); - } - // +x - if self.get(pos + Vec3::unit_x()) - .map(|v| v.is_empty()) - .unwrap_or(true) - { - mesh.push_quad(create_quad( - offs + pos.map(|e| e as f32) + Vec3::unit_x(), - Vec3::unit_y(), - Vec3::unit_z(), - Vec3::unit_x(), - col, - 0, - )); - } - // -y - if self.get(pos - Vec3::unit_y()) - .map(|v| v.is_empty()) - .unwrap_or(true) - { - mesh.push_quad(create_quad( - offs + pos.map(|e| e as f32), - Vec3::unit_x(), - Vec3::unit_z(), - -Vec3::unit_y(), - col, - 0, - )); - } - // +y - if self.get(pos + Vec3::unit_y()) - .map(|v| v.is_empty()) - .unwrap_or(true) - { - mesh.push_quad(create_quad( - offs + pos.map(|e| e as f32) + Vec3::unit_y(), - Vec3::unit_z(), - Vec3::unit_x(), - Vec3::unit_y(), - col, - 0, - )); - } - // -z - if self.get(pos - Vec3::unit_z()) - .map(|v| v.is_empty()) - .unwrap_or(true) - { - mesh.push_quad(create_quad( - offs + pos.map(|e| e as f32), - Vec3::unit_y(), - Vec3::unit_x(), - -Vec3::unit_z(), - col, - 0, - )); - } - // +z - if self.get(pos + Vec3::unit_z()) - .map(|v| v.is_empty()) - .unwrap_or(true) - { - mesh.push_quad(create_quad( - offs + pos.map(|e| e as f32) + Vec3::unit_z(), - Vec3::unit_x(), - Vec3::unit_y(), - Vec3::unit_z(), - col, - 0, - )); - } + ao::push_vox_verts_ao( + &mut mesh, + self, + pos, + offs + pos.map(|e| e as f32), + col, + create_vertex, + ); } } diff --git a/voxygen/src/mesh/terrain.rs b/voxygen/src/mesh/terrain.rs index f6500d7ca4..7e4334b449 100644 --- a/voxygen/src/mesh/terrain.rs +++ b/voxygen/src/mesh/terrain.rs @@ -10,41 +10,12 @@ use common::{ // Crate use crate::{ - mesh::Meshable, + mesh::{ao, Meshable}, render::{self, Mesh, Quad, TerrainPipeline}, }; type TerrainVertex = ::Vertex; -// Utility function -fn create_quad( - origin: Vec3, - unit_x: Vec3, - unit_y: Vec3, - norm: Vec3, - col: Rgb, - ao: Vec4, -) -> Quad { - let ao_scale = 1.0; - let dark = col * (1.0 - ao_scale); - - if ao[0] + ao[2] < ao[1] + ao[3] { - Quad::new( - TerrainVertex::new(origin + unit_y, norm, Rgb::lerp(dark, col, ao[3])), - TerrainVertex::new(origin, norm, Rgb::lerp(dark, col, ao[0])), - TerrainVertex::new(origin + unit_x, norm, Rgb::lerp(dark, col, ao[1])), - TerrainVertex::new(origin + unit_x + unit_y, norm, Rgb::lerp(dark, col, ao[2])), - ) - } else { - Quad::new( - TerrainVertex::new(origin, norm, Rgb::lerp(dark, col, ao[0])), - TerrainVertex::new(origin + unit_x, norm, Rgb::lerp(dark, col, ao[1])), - TerrainVertex::new(origin + unit_x + unit_y, norm, Rgb::lerp(dark, col, ao[2])), - TerrainVertex::new(origin + unit_y, norm, Rgb::lerp(dark, col, ao[3])), - ) - } -} - impl Meshable for Dyna { type Pipeline = TerrainPipeline; type Supplement = (); @@ -65,128 +36,7 @@ impl Meshable for Dyna { if let Some(col) = self.get(pos).ok().and_then(|vox| vox.get_color()) { let col = col.map(|e| e as f32 / 255.0); - let (x, y, z) = (Vec3::unit_x(), Vec3::unit_y(), Vec3::unit_z()); - - fn get_ao( - dyna: &Dyna, - pos: Vec3, - dirs: &[Vec3], - ) -> Vec4 { - dirs.windows(2) - .map(|offs| { - let (s1, s2) = ( - dyna.get(pos + offs[0]) - .map(|v| v.is_empty() as i32) - .unwrap_or(1), - dyna.get(pos + offs[1]) - .map(|v| v.is_empty() as i32) - .unwrap_or(1), - ); - - if s1 == 0 && s2 == 0 { - 0 - } else { - let corner = dyna - .get(pos + offs[0] + offs[1]) - .map(|v| v.is_empty() as i32) - .unwrap_or(1); - s1 + s2 + corner - } - }) - .map(|i| i as f32 / 3.0) - .collect::>() - } - - // -x - if self - .get(pos - Vec3::unit_x()) - .map(|v| v.is_empty()) - .unwrap_or(true) - { - mesh.push_quad(create_quad( - offs, - Vec3::unit_z(), - Vec3::unit_y(), - -Vec3::unit_x(), - col, - get_ao(self, pos - Vec3::unit_x(), &[-z, -y, z, y, -z]), - )); - } - // +x - if self - .get(pos + Vec3::unit_x()) - .map(|v| v.is_empty()) - .unwrap_or(true) - { - mesh.push_quad(create_quad( - offs + Vec3::unit_x(), - Vec3::unit_y(), - Vec3::unit_z(), - Vec3::unit_x(), - col, - get_ao(self, pos + Vec3::unit_x(), &[-y, -z, y, z, -y]), - )); - } - // -y - if self - .get(pos - Vec3::unit_y()) - .map(|v| v.is_empty()) - .unwrap_or(true) - { - mesh.push_quad(create_quad( - offs, - Vec3::unit_x(), - Vec3::unit_z(), - -Vec3::unit_y(), - col, - get_ao(self, pos - Vec3::unit_y(), &[-x, -z, x, z, -x]), - )); - } - // +y - if self - .get(pos + Vec3::unit_y()) - .map(|v| v.is_empty()) - .unwrap_or(true) - { - mesh.push_quad(create_quad( - offs + Vec3::unit_y(), - Vec3::unit_z(), - Vec3::unit_x(), - Vec3::unit_y(), - col, - get_ao(self, pos + Vec3::unit_y(), &[-z, -x, z, x, -z]), - )); - } - // -z - if self - .get(pos - Vec3::unit_z()) - .map(|v| v.is_empty()) - .unwrap_or(true) - { - mesh.push_quad(create_quad( - offs, - Vec3::unit_y(), - Vec3::unit_x(), - -Vec3::unit_z(), - col, - get_ao(self, pos - Vec3::unit_z(), &[-y, -x, y, x, -y]), - )); - } - // +z - if self - .get(pos + Vec3::unit_z()) - .map(|v| v.is_empty()) - .unwrap_or(true) - { - mesh.push_quad(create_quad( - offs + Vec3::unit_z(), - Vec3::unit_x(), - Vec3::unit_y(), - Vec3::unit_z(), - col, - get_ao(self, pos + Vec3::unit_z(), &[-x, -y, x, y, -x]), - )); - } + ao::push_vox_verts_ao(&mut mesh, self, pos, offs, col, TerrainVertex::new); } } From 7091557b82b184438047caf2424a774dffc98e21 Mon Sep 17 00:00:00 2001 From: robojumper Date: Sun, 28 Apr 2019 23:34:58 +0200 Subject: [PATCH 3/3] Rename mod ao to vol Former-commit-id: ef126e03761b18151594780777fa27e94efe24d7 --- voxygen/src/mesh/mod.rs | 2 +- voxygen/src/mesh/segment.rs | 4 +-- voxygen/src/mesh/terrain.rs | 4 +-- voxygen/src/mesh/{ao.rs => vol.rs} | 40 ++++++++++++++++-------------- 4 files changed, 26 insertions(+), 24 deletions(-) rename voxygen/src/mesh/{ao.rs => vol.rs} (80%) diff --git a/voxygen/src/mesh/mod.rs b/voxygen/src/mesh/mod.rs index e9ff529c9d..7fb9f8e43d 100644 --- a/voxygen/src/mesh/mod.rs +++ b/voxygen/src/mesh/mod.rs @@ -1,4 +1,4 @@ -mod ao; +mod vol; pub mod segment; pub mod terrain; diff --git a/voxygen/src/mesh/segment.rs b/voxygen/src/mesh/segment.rs index 97333017ef..620adcfc30 100644 --- a/voxygen/src/mesh/segment.rs +++ b/voxygen/src/mesh/segment.rs @@ -9,7 +9,7 @@ use common::{ // Crate use crate::{ - mesh::{ao, Meshable}, + mesh::{vol, Meshable}, render::{self, FigurePipeline, Mesh, Quad}, }; @@ -30,7 +30,7 @@ impl Meshable for Segment { if let Some(col) = self.get(pos).ok().and_then(|vox| vox.get_color()) { let col = col.map(|e| e as f32 / 255.0); - ao::push_vox_verts_ao( + vol::push_vox_verts( &mut mesh, self, pos, diff --git a/voxygen/src/mesh/terrain.rs b/voxygen/src/mesh/terrain.rs index 7e4334b449..a9157419e7 100644 --- a/voxygen/src/mesh/terrain.rs +++ b/voxygen/src/mesh/terrain.rs @@ -10,7 +10,7 @@ use common::{ // Crate use crate::{ - mesh::{ao, Meshable}, + mesh::{vol, Meshable}, render::{self, Mesh, Quad, TerrainPipeline}, }; @@ -36,7 +36,7 @@ impl Meshable for Dyna { if let Some(col) = self.get(pos).ok().and_then(|vox| vox.get_color()) { let col = col.map(|e| e as f32 / 255.0); - ao::push_vox_verts_ao(&mut mesh, self, pos, offs, col, TerrainVertex::new); + vol::push_vox_verts(&mut mesh, self, pos, offs, col, TerrainVertex::new); } } diff --git a/voxygen/src/mesh/ao.rs b/voxygen/src/mesh/vol.rs similarity index 80% rename from voxygen/src/mesh/ao.rs rename to voxygen/src/mesh/vol.rs index 8edeaec63b..ea47d9bde5 100644 --- a/voxygen/src/mesh/ao.rs +++ b/voxygen/src/mesh/vol.rs @@ -10,7 +10,7 @@ use crate::render::{ /// Given a volume, a position and the cardinal directions, compute each vertex' AO value /// `dirs` should be a slice of length 5 so that the sliding window of size 2 over the slice /// yields each vertex' adjacent positions. -fn get_quad_ao(vol: &V, pos: Vec3, dirs: &[Vec3]) -> Vec4 { +fn get_ao_quad(vol: &V, pos: Vec3, dirs: &[Vec3]) -> Vec4 { dirs.windows(2) .map(|offs| { let (s1, s2) = ( @@ -36,17 +36,15 @@ fn get_quad_ao(vol: &V, pos: Vec3, dirs: &[Vec3]) -> Vec4< .collect::>() } -type VertexCons = fn(Vec3, Vec3, Rgb) -> P::Vertex; - // Utility function -fn create_quad( +fn create_quad, Vec3, Rgb) -> P::Vertex>( origin: Vec3, unit_x: Vec3, unit_y: Vec3, norm: Vec3, col: Rgb, ao: Vec4, - vcons: VertexCons

, + vcons: &F, ) -> Quad

{ let ao_scale = 1.0; let dark = col * (1.0 - ao_scale); @@ -68,13 +66,17 @@ fn create_quad( } } -pub fn push_vox_verts_ao( +pub fn push_vox_verts< + V: ReadVol, + P: Pipeline, + F: Fn(Vec3, Vec3, Rgb) -> P::Vertex, +>( mesh: &mut Mesh

, vol: &V, pos: Vec3, offs: Vec3, col: Rgb, - vcons: VertexCons

, + vcons: F, ) { let (x, y, z) = (Vec3::unit_x(), Vec3::unit_y(), Vec3::unit_z()); @@ -90,8 +92,8 @@ pub fn push_vox_verts_ao( Vec3::unit_y(), -Vec3::unit_x(), col, - get_quad_ao(vol, pos - Vec3::unit_x(), &[-z, -y, z, y, -z]), - vcons, + get_ao_quad(vol, pos - Vec3::unit_x(), &[-z, -y, z, y, -z]), + &vcons, )); } // +x @@ -106,8 +108,8 @@ pub fn push_vox_verts_ao( Vec3::unit_z(), Vec3::unit_x(), col, - get_quad_ao(vol, pos + Vec3::unit_x(), &[-y, -z, y, z, -y]), - vcons, + get_ao_quad(vol, pos + Vec3::unit_x(), &[-y, -z, y, z, -y]), + &vcons, )); } // -y @@ -122,8 +124,8 @@ pub fn push_vox_verts_ao( Vec3::unit_z(), -Vec3::unit_y(), col, - get_quad_ao(vol, pos - Vec3::unit_y(), &[-x, -z, x, z, -x]), - vcons, + get_ao_quad(vol, pos - Vec3::unit_y(), &[-x, -z, x, z, -x]), + &vcons, )); } // +y @@ -138,8 +140,8 @@ pub fn push_vox_verts_ao( Vec3::unit_x(), Vec3::unit_y(), col, - get_quad_ao(vol, pos + Vec3::unit_y(), &[-z, -x, z, x, -z]), - vcons, + get_ao_quad(vol, pos + Vec3::unit_y(), &[-z, -x, z, x, -z]), + &vcons, )); } // -z @@ -154,8 +156,8 @@ pub fn push_vox_verts_ao( Vec3::unit_x(), -Vec3::unit_z(), col, - get_quad_ao(vol, pos - Vec3::unit_z(), &[-y, -x, y, x, -y]), - vcons, + get_ao_quad(vol, pos - Vec3::unit_z(), &[-y, -x, y, x, -y]), + &vcons, )); } // +z @@ -170,8 +172,8 @@ pub fn push_vox_verts_ao( Vec3::unit_y(), Vec3::unit_z(), col, - get_quad_ao(vol, pos + Vec3::unit_z(), &[-x, -y, x, y, -x]), - vcons, + get_ao_quad(vol, pos + Vec3::unit_z(), &[-x, -y, x, y, -x]), + &vcons, )); } }