diff --git a/voxygen/src/mesh/vol.rs b/voxygen/src/mesh/vol.rs index e24279bbb7..d78dd231af 100644 --- a/voxygen/src/mesh/vol.rs +++ b/voxygen/src/mesh/vol.rs @@ -1,183 +1,183 @@ -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_ao_quad(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()) - .unwrap_or(false), - vol.get(pos + offs[1]) - .map(|v| !v.is_empty()) - .unwrap_or(false), - ); - - if s1 && s2 { - 0.0 - } else { - let corner = vol - .get(pos + offs[0] + offs[1]) - .map(|v| !v.is_empty()) - .unwrap_or(false); - // Map both 1 and 2 neighbors to 0.5 occlusion - if s1 || s2 || corner { - 0.5 - } else { - 1.0 - } - } - }) - .collect::>() -} - -// Utility function -fn create_quad, Vec3, Rgb) -> P::Vertex>( - origin: Vec3, - unit_x: Vec3, - unit_y: Vec3, - norm: Vec3, - col: Rgb, - ao: Vec4, - vcons: &F, -) -> 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< - V: ReadVol, - P: Pipeline, - F: Fn(Vec3, Vec3, Rgb) -> P::Vertex, ->( - mesh: &mut Mesh

, - vol: &V, - pos: Vec3, - offs: Vec3, - col: Rgb, - vcons: F, -) { - 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_ao_quad(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_ao_quad(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_ao_quad(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_ao_quad(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_ao_quad(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_ao_quad(vol, pos + Vec3::unit_z(), &[-x, -y, x, y, -x]), - &vcons, - )); - } -} +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_ao_quad(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()) + .unwrap_or(false), + vol.get(pos + offs[1]) + .map(|v| !v.is_empty()) + .unwrap_or(false), + ); + + if s1 && s2 { + 0.0 + } else { + let corner = vol + .get(pos + offs[0] + offs[1]) + .map(|v| !v.is_empty()) + .unwrap_or(false); + // Map both 1 and 2 neighbors to 0.5 occlusion + if s1 || s2 || corner { + 0.5 + } else { + 1.0 + } + } + }) + .collect::>() +} + +// Utility function +fn create_quad, Vec3, Rgb) -> P::Vertex>( + origin: Vec3, + unit_x: Vec3, + unit_y: Vec3, + norm: Vec3, + col: Rgb, + ao: Vec4, + vcons: &F, +) -> 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< + V: ReadVol, + P: Pipeline, + F: Fn(Vec3, Vec3, Rgb) -> P::Vertex, +>( + mesh: &mut Mesh

, + vol: &V, + pos: Vec3, + offs: Vec3, + col: Rgb, + vcons: F, +) { + 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_ao_quad(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_ao_quad(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_ao_quad(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_ao_quad(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_ao_quad(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_ao_quad(vol, pos + Vec3::unit_z(), &[-x, -y, x, y, -x]), + &vcons, + )); + } +}