mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Added terrain sprite LoD
This commit is contained in:
parent
8a855ea423
commit
b2c8dc0806
@ -2,7 +2,7 @@ pub mod cell;
|
|||||||
pub mod mat_cell;
|
pub mod mat_cell;
|
||||||
pub use mat_cell::Material;
|
pub use mat_cell::Material;
|
||||||
|
|
||||||
use self::{cell::Cell, mat_cell::MatCell};
|
pub use self::{cell::Cell, mat_cell::MatCell};
|
||||||
use crate::{
|
use crate::{
|
||||||
vol::{IntoFullPosIterator, IntoFullVolIterator, ReadVol, SizedVol, Vox, WriteVol},
|
vol::{IntoFullPosIterator, IntoFullVolIterator, ReadVol, SizedVol, Vox, WriteVol},
|
||||||
volumes::dyna::Dyna,
|
volumes::dyna::Dyna,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::ray::Ray;
|
use crate::{ray::Ray, volumes::scaled::Scaled};
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
@ -24,6 +24,13 @@ pub trait Vox: Sized + Clone + PartialEq {
|
|||||||
pub trait BaseVol {
|
pub trait BaseVol {
|
||||||
type Vox: Vox;
|
type Vox: Vox;
|
||||||
type Error: Debug;
|
type Error: Debug;
|
||||||
|
|
||||||
|
fn scaled_by(&self, scale: Vec3<f32>) -> Scaled<Self>
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
|
Scaled { inner: self, scale }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implementing `BaseVol` for any `&'a BaseVol` makes it possible to implement
|
/// Implementing `BaseVol` for any `&'a BaseVol` makes it possible to implement
|
||||||
@ -159,6 +166,7 @@ where
|
|||||||
/// Unfortunately we can't just implement `IntoIterator` in this generic way
|
/// Unfortunately we can't just implement `IntoIterator` in this generic way
|
||||||
/// because it's defined in another crate. That's actually the only reason why
|
/// because it's defined in another crate. That's actually the only reason why
|
||||||
/// the trait `IntoFullVolIterator` exists.
|
/// the trait `IntoFullVolIterator` exists.
|
||||||
|
// TODO: See whether relaxed orphan rules permit this to be replaced now
|
||||||
impl<'a, T: 'a + SizedVol> IntoFullVolIterator<'a> for &'a T
|
impl<'a, T: 'a + SizedVol> IntoFullVolIterator<'a> for &'a T
|
||||||
where
|
where
|
||||||
Self: IntoVolIterator<'a>,
|
Self: IntoVolIterator<'a>,
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
pub mod chunk;
|
pub mod chunk;
|
||||||
pub mod dyna;
|
pub mod dyna;
|
||||||
|
pub mod scaled;
|
||||||
pub mod vol_grid_2d;
|
pub mod vol_grid_2d;
|
||||||
pub mod vol_grid_3d;
|
pub mod vol_grid_3d;
|
||||||
|
47
common/src/volumes/scaled.rs
Normal file
47
common/src/volumes/scaled.rs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
use crate::vol::{BaseVol, ReadVol, SizedVol, Vox};
|
||||||
|
use vek::*;
|
||||||
|
|
||||||
|
pub struct Scaled<'a, V> {
|
||||||
|
pub inner: &'a V,
|
||||||
|
pub scale: Vec3<f32>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, V: BaseVol> BaseVol for Scaled<'a, V> {
|
||||||
|
type Error = V::Error;
|
||||||
|
type Vox = V::Vox;
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, V: ReadVol> ReadVol for Scaled<'a, V> {
|
||||||
|
#[inline(always)]
|
||||||
|
fn get(&self, pos: Vec3<i32>) -> Result<&Self::Vox, Self::Error> {
|
||||||
|
let pos = pos.map2(self.scale, |e, scale| (e as f32 / scale).trunc() as i32);
|
||||||
|
let search_size = (Vec3::one() / self.scale).map(|e: f32| e.ceil() as i32);
|
||||||
|
(-search_size.x / 2..search_size.x / 2)
|
||||||
|
.map(|i| {
|
||||||
|
(-search_size.y / 2..search_size.y / 2).map(move |j| {
|
||||||
|
(-search_size.z / 2..search_size.z / 2).map(move |k| Vec3::new(i, j, k))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.flatten()
|
||||||
|
.flatten()
|
||||||
|
.map(|offs| self.inner.get(pos + offs))
|
||||||
|
.find(|vox| vox.as_ref().map(|v| !v.is_empty()).unwrap_or(false))
|
||||||
|
.unwrap_or_else(|| self.inner.get(pos))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, V: SizedVol> SizedVol for Scaled<'a, V> {
|
||||||
|
#[inline(always)]
|
||||||
|
fn lower_bound(&self) -> Vec3<i32> {
|
||||||
|
self.inner
|
||||||
|
.lower_bound()
|
||||||
|
.map2(self.scale, |e, scale| (e as f32 * scale).floor() as i32)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
fn upper_bound(&self) -> Vec3<i32> {
|
||||||
|
self.inner
|
||||||
|
.upper_bound()
|
||||||
|
.map2(self.scale, |e, scale| (e as f32 * scale).floor() as i32)
|
||||||
|
}
|
||||||
|
}
|
@ -4,14 +4,14 @@ mod vol;
|
|||||||
|
|
||||||
use crate::render::{self, Mesh};
|
use crate::render::{self, Mesh};
|
||||||
|
|
||||||
pub trait Meshable<P: render::Pipeline, T: render::Pipeline> {
|
pub trait Meshable<'a, P: render::Pipeline, T: render::Pipeline> {
|
||||||
type Pipeline: render::Pipeline;
|
type Pipeline: render::Pipeline;
|
||||||
type TranslucentPipeline: render::Pipeline;
|
type TranslucentPipeline: render::Pipeline;
|
||||||
type Supplement;
|
type Supplement;
|
||||||
|
|
||||||
// Generate meshes - one opaque, one translucent
|
// Generate meshes - one opaque, one translucent
|
||||||
fn generate_mesh(
|
fn generate_mesh(
|
||||||
&self,
|
&'a self,
|
||||||
supp: Self::Supplement,
|
supp: Self::Supplement,
|
||||||
) -> (Mesh<Self::Pipeline>, Mesh<Self::TranslucentPipeline>);
|
) -> (Mesh<Self::Pipeline>, Mesh<Self::TranslucentPipeline>);
|
||||||
}
|
}
|
||||||
|
@ -3,27 +3,43 @@ use crate::{
|
|||||||
render::{self, FigurePipeline, Mesh, SpritePipeline},
|
render::{self, FigurePipeline, Mesh, SpritePipeline},
|
||||||
};
|
};
|
||||||
use common::{
|
use common::{
|
||||||
figure::Segment,
|
figure::Cell,
|
||||||
util::{linear_to_srgb, srgb_to_linear},
|
util::{linear_to_srgb, srgb_to_linear},
|
||||||
vol::{IntoFullVolIterator, ReadVol, Vox},
|
vol::{BaseVol, ReadVol, SizedVol, Vox},
|
||||||
};
|
};
|
||||||
use vek::*;
|
use vek::*;
|
||||||
|
|
||||||
type FigureVertex = <FigurePipeline as render::Pipeline>::Vertex;
|
type FigureVertex = <FigurePipeline as render::Pipeline>::Vertex;
|
||||||
type SpriteVertex = <SpritePipeline as render::Pipeline>::Vertex;
|
type SpriteVertex = <SpritePipeline as render::Pipeline>::Vertex;
|
||||||
|
|
||||||
impl Meshable<FigurePipeline, FigurePipeline> for Segment {
|
impl<'a, V: 'a> Meshable<'a, FigurePipeline, FigurePipeline> for V
|
||||||
|
where
|
||||||
|
V: BaseVol<Vox = Cell> + ReadVol + SizedVol,
|
||||||
|
/* TODO: Use VolIterator instead of manually iterating
|
||||||
|
* &'a V: IntoVolIterator<'a> + IntoFullVolIterator<'a>,
|
||||||
|
* &'a V: BaseVol<Vox=Cell>, */
|
||||||
|
{
|
||||||
type Pipeline = FigurePipeline;
|
type Pipeline = FigurePipeline;
|
||||||
type Supplement = Vec3<f32>;
|
type Supplement = (Vec3<f32>, Vec3<f32>);
|
||||||
type TranslucentPipeline = FigurePipeline;
|
type TranslucentPipeline = FigurePipeline;
|
||||||
|
|
||||||
fn generate_mesh(
|
fn generate_mesh(
|
||||||
&self,
|
&'a self,
|
||||||
offs: Self::Supplement,
|
(offs, scale): Self::Supplement,
|
||||||
) -> (Mesh<Self::Pipeline>, Mesh<Self::TranslucentPipeline>) {
|
) -> (Mesh<Self::Pipeline>, Mesh<Self::TranslucentPipeline>) {
|
||||||
let mut mesh = Mesh::new();
|
let mut mesh = Mesh::new();
|
||||||
|
|
||||||
for (pos, vox) in self.full_vol_iter() {
|
let vol_iter = (self.lower_bound().x..self.upper_bound().x)
|
||||||
|
.map(|i| {
|
||||||
|
(self.lower_bound().y..self.upper_bound().y).map(move |j| {
|
||||||
|
(self.lower_bound().z..self.upper_bound().z).map(move |k| Vec3::new(i, j, k))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.flatten()
|
||||||
|
.flatten()
|
||||||
|
.map(|pos| (pos, self.get(pos).unwrap()));
|
||||||
|
|
||||||
|
for (pos, vox) in vol_iter {
|
||||||
if let Some(col) = vox.get_color() {
|
if let Some(col) = vox.get_color() {
|
||||||
vol::push_vox_verts(
|
vol::push_vox_verts(
|
||||||
&mut mesh,
|
&mut mesh,
|
||||||
@ -32,7 +48,7 @@ impl Meshable<FigurePipeline, FigurePipeline> for Segment {
|
|||||||
&[[[Rgba::from_opaque(col); 3]; 3]; 3],
|
&[[[Rgba::from_opaque(col); 3]; 3]; 3],
|
||||||
|origin, norm, col, light, ao| {
|
|origin, norm, col, light, ao| {
|
||||||
FigureVertex::new(
|
FigureVertex::new(
|
||||||
origin,
|
origin * scale,
|
||||||
norm,
|
norm,
|
||||||
linear_to_srgb(srgb_to_linear(col) * light),
|
linear_to_srgb(srgb_to_linear(col) * light),
|
||||||
ao,
|
ao,
|
||||||
@ -62,18 +78,34 @@ impl Meshable<FigurePipeline, FigurePipeline> for Segment {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Meshable<SpritePipeline, SpritePipeline> for Segment {
|
impl<'a, V: 'a> Meshable<'a, SpritePipeline, SpritePipeline> for V
|
||||||
|
where
|
||||||
|
V: BaseVol<Vox = Cell> + ReadVol + SizedVol,
|
||||||
|
/* TODO: Use VolIterator instead of manually iterating
|
||||||
|
* &'a V: IntoVolIterator<'a> + IntoFullVolIterator<'a>,
|
||||||
|
* &'a V: BaseVol<Vox=Cell>, */
|
||||||
|
{
|
||||||
type Pipeline = SpritePipeline;
|
type Pipeline = SpritePipeline;
|
||||||
type Supplement = Vec3<f32>;
|
type Supplement = (Vec3<f32>, Vec3<f32>);
|
||||||
type TranslucentPipeline = SpritePipeline;
|
type TranslucentPipeline = SpritePipeline;
|
||||||
|
|
||||||
fn generate_mesh(
|
fn generate_mesh(
|
||||||
&self,
|
&'a self,
|
||||||
offs: Self::Supplement,
|
(offs, scale): Self::Supplement,
|
||||||
) -> (Mesh<Self::Pipeline>, Mesh<Self::TranslucentPipeline>) {
|
) -> (Mesh<Self::Pipeline>, Mesh<Self::TranslucentPipeline>) {
|
||||||
let mut mesh = Mesh::new();
|
let mut mesh = Mesh::new();
|
||||||
|
|
||||||
for (pos, vox) in self.full_vol_iter() {
|
let vol_iter = (self.lower_bound().x..self.upper_bound().x)
|
||||||
|
.map(|i| {
|
||||||
|
(self.lower_bound().y..self.upper_bound().y).map(move |j| {
|
||||||
|
(self.lower_bound().z..self.upper_bound().z).map(move |k| Vec3::new(i, j, k))
|
||||||
|
})
|
||||||
|
})
|
||||||
|
.flatten()
|
||||||
|
.flatten()
|
||||||
|
.map(|pos| (pos, self.get(pos).unwrap()));
|
||||||
|
|
||||||
|
for (pos, vox) in vol_iter {
|
||||||
if let Some(col) = vox.get_color() {
|
if let Some(col) = vox.get_color() {
|
||||||
vol::push_vox_verts(
|
vol::push_vox_verts(
|
||||||
&mut mesh,
|
&mut mesh,
|
||||||
@ -82,7 +114,7 @@ impl Meshable<SpritePipeline, SpritePipeline> for Segment {
|
|||||||
&[[[Rgba::from_opaque(col); 3]; 3]; 3],
|
&[[[Rgba::from_opaque(col); 3]; 3]; 3],
|
||||||
|origin, norm, col, light, ao| {
|
|origin, norm, col, light, ao| {
|
||||||
SpriteVertex::new(
|
SpriteVertex::new(
|
||||||
origin,
|
origin * scale,
|
||||||
norm,
|
norm,
|
||||||
linear_to_srgb(srgb_to_linear(col) * light),
|
linear_to_srgb(srgb_to_linear(col) * light),
|
||||||
ao,
|
ao,
|
||||||
|
@ -198,15 +198,15 @@ fn calc_light<V: RectRasterableVol<Vox = Block> + ReadVol + Debug>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<V: RectRasterableVol<Vox = Block> + ReadVol + Debug> Meshable<TerrainPipeline, FluidPipeline>
|
impl<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug>
|
||||||
for VolGrid2d<V>
|
Meshable<'a, TerrainPipeline, FluidPipeline> for VolGrid2d<V>
|
||||||
{
|
{
|
||||||
type Pipeline = TerrainPipeline;
|
type Pipeline = TerrainPipeline;
|
||||||
type Supplement = Aabb<i32>;
|
type Supplement = Aabb<i32>;
|
||||||
type TranslucentPipeline = FluidPipeline;
|
type TranslucentPipeline = FluidPipeline;
|
||||||
|
|
||||||
fn generate_mesh(
|
fn generate_mesh(
|
||||||
&self,
|
&'a self,
|
||||||
range: Self::Supplement,
|
range: Self::Supplement,
|
||||||
) -> (Mesh<Self::Pipeline>, Mesh<Self::TranslucentPipeline>) {
|
) -> (Mesh<Self::Pipeline>, Mesh<Self::TranslucentPipeline>) {
|
||||||
let mut light = calc_light(range, self);
|
let mut light = calc_light(range, self);
|
||||||
|
@ -55,7 +55,7 @@ fn graceful_load_mat_segment_flipped(mesh_name: &str) -> MatSegment {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn generate_mesh(segment: &Segment, offset: Vec3<f32>) -> Mesh<FigurePipeline> {
|
fn generate_mesh(segment: &Segment, offset: Vec3<f32>) -> Mesh<FigurePipeline> {
|
||||||
Meshable::<FigurePipeline, FigurePipeline>::generate_mesh(segment, offset).0
|
Meshable::<FigurePipeline, FigurePipeline>::generate_mesh(segment, (offset, Vec3::one())).0
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load_mesh(mesh_name: &str, position: Vec3<f32>) -> Mesh<FigurePipeline> {
|
pub fn load_mesh(mesh_name: &str, position: Vec3<f32>) -> Mesh<FigurePipeline> {
|
||||||
|
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user