mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Fix clippy warnings, part 1.
There aer still a bunch of type too complex and function takes too many arguments warnings that I'll fix later (or ignore, since in the one case I did fix a function takes too many arguments warning I think it made the code *less* readable).
This commit is contained in:
parent
ba54307540
commit
a428a3ebba
@ -316,7 +316,7 @@ impl Client {
|
||||
// Should not fail if the dimensions are correct.
|
||||
let map =
|
||||
image::ImageBuffer::from_raw(u32::from(map_size.x), u32::from(map_size.y), raw);
|
||||
map.ok_or(Error::Other("Server sent a bad world map image".into()))?
|
||||
map.ok_or_else(|| Error::Other("Server sent a bad world map image".into()))?
|
||||
})
|
||||
// Flip the image, since Voxygen uses an orientation where rotation from
|
||||
// positive x axis to positive y axis is counterclockwise around the z axis.
|
||||
|
@ -142,6 +142,12 @@ pub const MAX_WORLD_BLOCKS_LG: Vec2<u32> = Vec2 { x: 19, y: 19 };
|
||||
pub struct MapSizeLg(Vec2<u32>);
|
||||
|
||||
impl MapSizeLg {
|
||||
// FIXME: We cannot use is_some() here because it is not currently marked as a
|
||||
// `const fn`. Since being able to use conditionals in constant expressions has
|
||||
// not technically been stabilized yet, Clippy probably doesn't check for this
|
||||
// case yet. When it can, or when is_some() is stabilized as a `const fn`,
|
||||
// we should deal with this.
|
||||
#[allow(clippy::redundant_pattern_matching)]
|
||||
/// Construct a new `MapSizeLg`, returning an error if the needed invariants
|
||||
/// do not hold and the vector otherwise.
|
||||
///
|
||||
@ -509,23 +515,17 @@ impl<'a> MapConfig<'a> {
|
||||
// accurate (though I'm not sure if it can matter for these
|
||||
// purposes).
|
||||
chunk_idx
|
||||
.map(|chunk_idx| neighbors(map_size_lg, chunk_idx).chain(iter::once(chunk_idx)))
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.flat_map(|chunk_idx| {
|
||||
neighbors(map_size_lg, chunk_idx).chain(iter::once(chunk_idx))
|
||||
})
|
||||
.for_each(|neighbor_posi| {
|
||||
let neighbor_pos = uniform_idx_as_vec2(map_size_lg, neighbor_posi);
|
||||
let neighbor_wpos = neighbor_pos.map(|e| e as f64) * chunk_size;
|
||||
let MapSample { connections, .. } = sample_pos(neighbor_pos);
|
||||
NEIGHBOR_DELTA
|
||||
.iter()
|
||||
.zip(
|
||||
connections
|
||||
.as_ref()
|
||||
.map(|e| e.iter())
|
||||
.into_iter()
|
||||
.flatten()
|
||||
.into_iter(),
|
||||
)
|
||||
.zip(connections.iter().flatten())
|
||||
.for_each(|(&delta, connection)| {
|
||||
let connection = if let Some(connection) = connection {
|
||||
connection
|
||||
|
@ -2185,7 +2185,6 @@ impl<'a> Widget for SettingsWindow<'a> {
|
||||
events.push(Event::ChangeRenderMode(RenderMode {
|
||||
shadow: ShadowMode::Map(ShadowMapMode {
|
||||
resolution: 2.0f32.powf(f32::from(new_val) / 4.0),
|
||||
..shadow_map_mode
|
||||
}),
|
||||
..render_mode
|
||||
}));
|
||||
|
@ -3,6 +3,77 @@ use vek::*;
|
||||
|
||||
type TerrainVertex = <TerrainPipeline as render::Pipeline>::Vertex;
|
||||
|
||||
/// `max_size`:
|
||||
///
|
||||
/// `draw_delta`:
|
||||
///
|
||||
/// `greedy_size`:
|
||||
///
|
||||
/// `greedy_size_cross`:
|
||||
///
|
||||
/// `get_light`:
|
||||
///
|
||||
/// `get_color`:
|
||||
///
|
||||
///
|
||||
/// `create_shadow`:
|
||||
/// Create a shadow vertex (used for both shadow and display rendering)
|
||||
/// given its position, normal, and meta information. Note that the position
|
||||
/// received here is relative to `draw_delta`--it still needs to be translated
|
||||
/// to mesh coordinates.
|
||||
///
|
||||
/// `create_opaque`:
|
||||
pub struct GreedyConfig<D, FL, FC, FO, FS, FP> {
|
||||
pub data: D,
|
||||
/// The minimum position to mesh, in the coordinate system used
|
||||
/// for queries against the volume.
|
||||
pub draw_delta: Vec3<i32>,
|
||||
/// For each dimension i, for faces drawn in planes *parallel* to i,
|
||||
/// represents the number of voxels considered along dimenson i in those
|
||||
/// planes, starting from `draw_delta`.
|
||||
pub greedy_size: Vec3<usize>,
|
||||
/// For each dimension i, represents the number of planes considered
|
||||
/// *orthogonal* to dimension i, starting from `draw_delta`. This should
|
||||
/// usually be the same as greedy_size.
|
||||
///
|
||||
/// An important exception is during chunk rendering (where vertical faces
|
||||
/// at chunk boundaries would otherwise be rendered twice, and also
|
||||
/// force us to use more than 5 bits to represent x and y
|
||||
/// positions--though there may be a clever way aruond the latter).
|
||||
/// Thus, for chunk rendering we set the number of *vertical* planes to
|
||||
/// one less than the chunk size along the x and y dimensions, but keep
|
||||
/// the number of *horizontal* planes large enough to cover the whole
|
||||
/// chunk.
|
||||
pub greedy_size_cross: Vec3<usize>,
|
||||
/// Given a position, return the lighting information for the voxel at that
|
||||
/// position.
|
||||
pub get_light: FL,
|
||||
/// Given a position, return the color information for the voxel at that
|
||||
/// position.
|
||||
pub get_color: FC,
|
||||
/// Given a position, return the opacity information for the voxel at that
|
||||
/// position. Currently, we don't support real translucent lighting, so the
|
||||
/// value should either be `false` (for opaque blocks) or `true`
|
||||
/// (otherwise).
|
||||
pub get_opacity: FO,
|
||||
/// Given a position and a normal, should we draw the face between the
|
||||
/// position and position - normal (i.e. the voxel "below" this vertex)?
|
||||
/// If so, provide its orientation, together with any other meta
|
||||
/// information required for the mesh that needs to split up faces. For
|
||||
/// example, terrain faces currently record a bit indicating whether
|
||||
/// they are exposed to water or not, so we should not merge faces where
|
||||
/// one is submerged in water and the other is not, even if they
|
||||
/// otherwise have the same orientation, dimensions, and are
|
||||
/// next to each other.
|
||||
pub should_draw: FS,
|
||||
/// Create an opauqe quad (used for only display rendering) from its
|
||||
/// top-left atlas position, the rectangle's dimensions in (2D) atlas
|
||||
/// space, a world position, the u and v axes of the rectangle in (3D)
|
||||
/// world space, the normal facing out frmo the rectangle in world
|
||||
/// space, and meta information common to every voxel in this rectangle.
|
||||
pub push_quad: FP,
|
||||
}
|
||||
|
||||
/// A suspended greedy mesh, with enough information to recover color data.
|
||||
///
|
||||
/// The reason this exists is that greedy meshing is split into two parts.
|
||||
@ -28,6 +99,20 @@ pub struct GreedyMesh<'a> {
|
||||
}
|
||||
|
||||
impl<'a> GreedyMesh<'a> {
|
||||
/// Construct a new greedy mesher.
|
||||
///
|
||||
/// Takes as input the maximum allowable size of the texture atlas used to
|
||||
/// store the light/color data for this mesh.
|
||||
///
|
||||
/// NOTE: It is an error to pass any size > u16::MAX.
|
||||
///
|
||||
/// Even aside from the above limitation, this will not necessarily always
|
||||
/// be the same as the maximum atlas size supported by the hardware.
|
||||
/// For instance, since we want to reserve 4 bits for a bone index for
|
||||
/// figures in their shadow vertex, the atlas parameter for figures has
|
||||
/// to have at least 2 bits of the normal; thus, it can only take up at
|
||||
/// most 30 bits total, meaning we are restricted to "only" at most 2^15
|
||||
/// × 2^15 atlases even if the hardware supports larger ones.
|
||||
pub fn new(max_size: guillotiere::Size) -> Self {
|
||||
let min_max_dim = max_size.width.min(max_size.height);
|
||||
assert!(
|
||||
@ -55,45 +140,55 @@ impl<'a> GreedyMesh<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn push</* S: render::Pipeline, *//*O: render::Pipeline, */ M: PartialEq, D: 'a>(
|
||||
/// Perform greedy meshing on a model, separately producing "pure" model
|
||||
/// data (the opaque mesh, ttogether with atlas positions connecting
|
||||
/// each rectangle with texture information), and raw light and color
|
||||
/// data ready to be used as a texture (accessible with `finalize`).
|
||||
/// Texture data built up within the same greedy mesh will be inserted
|
||||
/// into the same atlas, which can be used to group texture data for
|
||||
/// things like figures that are the result of meshing multiple models.
|
||||
///
|
||||
/// Returns an estimate of the bounds of the current meshed model.
|
||||
///
|
||||
/// For more information on the config parameter, see [GreedyConfig].
|
||||
pub fn push<
|
||||
M: PartialEq,
|
||||
D: 'a,
|
||||
FL,
|
||||
FC,
|
||||
FO,
|
||||
FS,
|
||||
FP,
|
||||
>(
|
||||
&mut self,
|
||||
data: D,
|
||||
draw_delta: Vec3<i32>,
|
||||
greedy_size: Vec3<usize>,
|
||||
greedy_size_cross: Vec3<usize>,
|
||||
get_light: impl for<'r> FnMut(&'r mut D, Vec3<i32>) -> f32 + 'a,
|
||||
get_color: impl for<'r> FnMut(&'r mut D, Vec3<i32>) -> Rgb<u8> + 'a,
|
||||
get_opacity: impl for<'r> FnMut(&'r mut D, Vec3<i32>) -> bool + 'a,
|
||||
should_draw: impl for<'r> FnMut(
|
||||
&'r mut D,
|
||||
Vec3<i32>,
|
||||
Vec3<i32>,
|
||||
Vec2<Vec3<i32>>,
|
||||
) -> Option<(bool, M)>,
|
||||
// create_shadow: impl for<'r> Fn(Vec3<f32>, Vec3<f32>, &'r M) -> S::Vertex,
|
||||
// create_opaque: impl for<'r> Fn(Vec2<u16>, Vec3<f32>, Vec3<f32>, &'r M) -> O::Vertex,
|
||||
push_quad: impl FnMut(Vec2<u16>, Vec2<Vec2<u16>>, Vec3<f32>, Vec2<Vec3<f32>>, Vec3<f32>, &M),
|
||||
) -> Aabb<u16> {
|
||||
config: GreedyConfig<D, FL, FC, FO, FS, FP>,
|
||||
) -> Aabb<u16>
|
||||
where
|
||||
FL: for<'r> FnMut(&'r mut D, Vec3<i32>) -> f32 + 'a,
|
||||
FC: for<'r> FnMut(&'r mut D, Vec3<i32>) -> Rgb<u8> + '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)>,
|
||||
FP: FnMut(Vec2<u16>, Vec2<Vec2<u16>>, Vec3<f32>, Vec2<Vec3<f32>>, Vec3<f32>, &M),
|
||||
{
|
||||
let (bounds, /* opaque, *//*shadow, */ cont) = greedy_mesh(
|
||||
&mut self.atlas,
|
||||
&mut self.col_lights_size,
|
||||
self.max_size,
|
||||
data,
|
||||
draw_delta,
|
||||
greedy_size,
|
||||
greedy_size_cross,
|
||||
get_light,
|
||||
get_color,
|
||||
get_opacity,
|
||||
should_draw,
|
||||
// create_shadow,
|
||||
// create_opaque,
|
||||
push_quad,
|
||||
config,
|
||||
);
|
||||
self.suspended.push(cont);
|
||||
bounds
|
||||
}
|
||||
|
||||
/// Finalize the mesh, producing texture color data for the whole model.
|
||||
///
|
||||
/// By delaying finalization until the contents of the whole texture atlas
|
||||
/// are known, we can perform just a single allocation to construct a
|
||||
/// precisely fitting atlas. This will also let us (in the future)
|
||||
/// suspend meshing partway through in order to meet frame budget, and
|
||||
/// potentially use a single staged upload to the GPU.
|
||||
///
|
||||
/// Returns the ColLightsInfo corresponding to the consstructed atlas.
|
||||
pub fn finalize(self) -> ColLightInfo {
|
||||
let cur_size = self.col_lights_size;
|
||||
let col_lights = vec![/*Default::default()*/TerrainVertex::make_col_light(254, Rgb::broadcast(254)); usize::from(cur_size.x) * usize::from(cur_size.y)];
|
||||
@ -107,122 +202,34 @@ impl<'a> GreedyMesh<'a> {
|
||||
pub fn max_size(&self) -> guillotiere::Size { self.max_size }
|
||||
}
|
||||
|
||||
/// Perform greedy meshing on a model, separately producing "pure" model data
|
||||
/// (the shadow mesh), raw light and color data ready to be used as a texture
|
||||
/// (the returned vector of ColLights, together with their width and height),
|
||||
/// and the atlas positions (the opaque mesh) used to connect the shadow
|
||||
/// information with the light and color information.
|
||||
///
|
||||
/// The opaque and shadow data are in the same order and it is intended that
|
||||
/// they be used together as vertex buffers for display purposes. Thus, if you
|
||||
/// perform further manipulation on the meshes after this function returns, such
|
||||
/// as merges, please be sure that all those operations preserve this
|
||||
/// relationship.
|
||||
///
|
||||
/// TODO: Consider supporting shared texture atlases (this might come in handy
|
||||
/// for mobs or sprites, for instance).a
|
||||
///
|
||||
/// TODO: Add assertions to make this more robust.
|
||||
///
|
||||
/// Parameter description:
|
||||
///
|
||||
/// `max_size`:
|
||||
/// The maximum allowable size of the texture atlas used to store the
|
||||
/// light/color data for this mesh.
|
||||
///
|
||||
/// NOTE: It is an error to pass any size > u16::MAX.
|
||||
///
|
||||
/// Even aside from the above limitation, this will not necessarily always be
|
||||
/// the same as the maximum atlas size supported by the hardware. For instance,
|
||||
/// since we want to reserve 4 bits for a bone index for figures in their shadow
|
||||
/// vertex, the atlas parameter for figures has to have at least 2 bits of the
|
||||
/// normal; thus, it can only take up at most 30 bits total, meaning we are
|
||||
/// restricted to "only" at most 2^15 × 2^15 atlases even if the hardware
|
||||
/// supports larger ones.
|
||||
///
|
||||
/// `draw_delta`: The minimum position to mesh, in the coordinate system used
|
||||
/// for queries against the volume.
|
||||
///
|
||||
/// `greedy_size`:
|
||||
/// For each dimension i, for faces drawn in planes *parallel* to i, represents
|
||||
/// the number of voxels considered along dimenson i in those planes, starting
|
||||
/// from `draw_delta`.
|
||||
///
|
||||
/// `greedy_size_cross`:
|
||||
/// For each dimension i, represents the number of planes considered
|
||||
/// *orthogonal* to dimension i, starting from `draw_delta`. This should
|
||||
/// usually be the same as greedy_size.
|
||||
///
|
||||
/// An important exception is during chunk rendering (where vertical faces at
|
||||
/// chunk boundaries would otherwise be rendered twice, and also force us to use
|
||||
/// more than 5 bits to represent x and y positions--though there may be a
|
||||
/// clever way aruond the latter). Thus, for chunk rendering we set the number
|
||||
/// of *vertical* planes to one less than the chunk size along the
|
||||
/// x and y dimensions, but keep the number of *horizontal* planes large enough
|
||||
/// to cover the whole chunk.
|
||||
///
|
||||
/// `get_light`:
|
||||
/// Given a position, return the lighting information for the voxel at that
|
||||
/// position.
|
||||
///
|
||||
/// `get_color`:
|
||||
/// Given a position, return the color information for the voxel at that
|
||||
/// position.
|
||||
///
|
||||
/// `get_opacity`:
|
||||
/// Given a position, return the opacity information for the voxel at that
|
||||
/// position. Currently, we don't support real translucent lighting, so the
|
||||
/// value should either be `false` (for opaque blocks) or `true` (otherwise).
|
||||
///
|
||||
/// `should_draw`:
|
||||
/// Given a position and a normal, should we draw the face between the position
|
||||
/// and position - normal (i.e. the voxel "below" this vertex)? If so, provide
|
||||
/// its orientation, together with any other meta information required for the
|
||||
/// mesh that needs to split up faces. For example, terrain faces currently
|
||||
/// record a bit indicating whether they are exposed to water or not, so we
|
||||
/// should not merge faces where one is submerged in water and the other is not,
|
||||
/// even if they otherwise have the same orientation, dimensions, and are
|
||||
/// next to each other.
|
||||
///
|
||||
/// `create_shadow`:
|
||||
/// Create a shadow vertex (used for both shadow and display rendering)
|
||||
/// given its position, normal, and meta information. Note that the position
|
||||
/// received here is relative to `draw_delta`--it still needs to be translated
|
||||
/// to mesh coordinates.
|
||||
///
|
||||
/// `create_opaque`:
|
||||
/// Create an opauqe vertex (used for only display rendering) from an atlas
|
||||
/// position, normal, and meta information.
|
||||
fn greedy_mesh<
|
||||
'a, /* , S: render::Pipeline*//*, O: render::Pipeline */
|
||||
M: PartialEq,
|
||||
D: 'a,
|
||||
>(
|
||||
fn greedy_mesh<'a, M: PartialEq, D: 'a, FL, FC, FO, FS, FP>(
|
||||
atlas: &mut guillotiere::SimpleAtlasAllocator,
|
||||
col_lights_size: &mut Vec2<u16>,
|
||||
max_size: guillotiere::Size,
|
||||
mut data: D,
|
||||
draw_delta: Vec3<i32>,
|
||||
greedy_size: Vec3<usize>,
|
||||
greedy_size_cross: Vec3<usize>,
|
||||
get_light: impl for<'r> FnMut(&'r mut D, Vec3<i32>) -> f32 + 'a,
|
||||
get_color: impl for<'r> FnMut(&'r mut D, Vec3<i32>) -> Rgb<u8> + 'a,
|
||||
get_opacity: impl for<'r> FnMut(&'r mut D, Vec3<i32>) -> bool + 'a,
|
||||
mut should_draw: impl for<'r> FnMut(
|
||||
&'r mut D,
|
||||
Vec3<i32>,
|
||||
Vec3<i32>,
|
||||
Vec2<Vec3<i32>>,
|
||||
) -> Option<(bool, M)>,
|
||||
// create_shadow: impl Fn(Vec3<f32>, Vec3<f32>, &M) -> S::Vertex,
|
||||
// create_opaque: impl Fn(Vec2<u16>, Vec3<f32>, Vec3<f32>, &M) -> O::Vertex,
|
||||
mut push_quad: impl FnMut(Vec2<u16>, Vec2<Vec2<u16>>, Vec3<f32>, Vec2<Vec3<f32>>, Vec3<f32>, &M),
|
||||
GreedyConfig {
|
||||
mut data,
|
||||
draw_delta,
|
||||
greedy_size,
|
||||
greedy_size_cross,
|
||||
get_light,
|
||||
get_color,
|
||||
get_opacity,
|
||||
mut should_draw,
|
||||
mut push_quad,
|
||||
}: GreedyConfig<D, FL, FC, FO, FS, FP>,
|
||||
) -> (
|
||||
Aabb<u16>,
|
||||
// Mesh<O>,
|
||||
// Mesh<S>,
|
||||
Box<SuspendedMesh<'a>>,
|
||||
) {
|
||||
)
|
||||
where
|
||||
FL: for<'r> FnMut(&'r mut D, Vec3<i32>) -> f32 + 'a,
|
||||
FC: for<'r> FnMut(&'r mut D, Vec3<i32>) -> Rgb<u8> + '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)>,
|
||||
FP: FnMut(Vec2<u16>, Vec2<Vec2<u16>>, Vec3<f32>, Vec2<Vec3<f32>>, Vec3<f32>, &M),
|
||||
{
|
||||
// let mut opaque_mesh = Mesh::new();
|
||||
// let mut shadow_mesh = Mesh::new();
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
mesh::{
|
||||
greedy::{self, GreedyMesh},
|
||||
greedy::{self, GreedyConfig, GreedyMesh},
|
||||
Meshable,
|
||||
},
|
||||
render::{self, FigurePipeline, Mesh, ShadowPipeline, SpritePipeline, TerrainPipeline},
|
||||
@ -77,30 +77,32 @@ where
|
||||
vol.get(vox).map(|vox| *vox).unwrap_or(Vox::empty())
|
||||
})
|
||||
};
|
||||
let create_opaque = |atlas_pos, pos, norm, _meta| {
|
||||
let create_opaque = |atlas_pos, pos, norm| {
|
||||
TerrainVertex::new_figure(atlas_pos, (pos + offs) * scale, norm, 0)
|
||||
};
|
||||
|
||||
let mut opaque_mesh = Mesh::new();
|
||||
let bounds = greedy.push(
|
||||
self,
|
||||
draw_delta,
|
||||
greedy_size,
|
||||
greedy_size_cross,
|
||||
get_light,
|
||||
get_color,
|
||||
get_opacity,
|
||||
should_draw,
|
||||
|atlas_origin, dim, origin, draw_dim, norm, meta| {
|
||||
opaque_mesh.push_quad(greedy::create_quad(
|
||||
atlas_origin,
|
||||
dim,
|
||||
origin,
|
||||
draw_dim,
|
||||
norm,
|
||||
meta,
|
||||
|atlas_pos, pos, norm, &meta| create_opaque(atlas_pos, pos, norm, meta),
|
||||
));
|
||||
GreedyConfig {
|
||||
data: self,
|
||||
draw_delta,
|
||||
greedy_size,
|
||||
greedy_size_cross,
|
||||
get_light,
|
||||
get_color,
|
||||
get_opacity,
|
||||
should_draw,
|
||||
push_quad: |atlas_origin, dim, origin, draw_dim, norm, meta: &()| {
|
||||
opaque_mesh.push_quad(greedy::create_quad(
|
||||
atlas_origin,
|
||||
dim,
|
||||
origin,
|
||||
draw_dim,
|
||||
norm,
|
||||
meta,
|
||||
|atlas_pos, pos, norm, &_meta| create_opaque(atlas_pos, pos, norm),
|
||||
));
|
||||
},
|
||||
},
|
||||
);
|
||||
let bounds = bounds.map(f32::from);
|
||||
@ -194,24 +196,26 @@ where
|
||||
|
||||
let mut opaque_mesh = Mesh::new();
|
||||
let _bounds = greedy.push(
|
||||
self,
|
||||
draw_delta,
|
||||
greedy_size,
|
||||
greedy_size_cross,
|
||||
get_light,
|
||||
get_color,
|
||||
get_opacity,
|
||||
should_draw,
|
||||
|atlas_origin, dim, origin, draw_dim, norm, meta| {
|
||||
opaque_mesh.push_quad(greedy::create_quad(
|
||||
atlas_origin,
|
||||
dim,
|
||||
origin,
|
||||
draw_dim,
|
||||
norm,
|
||||
meta,
|
||||
|atlas_pos, pos, norm, &meta| create_opaque(atlas_pos, pos, norm, meta),
|
||||
));
|
||||
GreedyConfig {
|
||||
data: self,
|
||||
draw_delta,
|
||||
greedy_size,
|
||||
greedy_size_cross,
|
||||
get_light,
|
||||
get_color,
|
||||
get_opacity,
|
||||
should_draw,
|
||||
push_quad: |atlas_origin, dim, origin, draw_dim, norm, meta: &bool| {
|
||||
opaque_mesh.push_quad(greedy::create_quad(
|
||||
atlas_origin,
|
||||
dim,
|
||||
origin,
|
||||
draw_dim,
|
||||
norm,
|
||||
meta,
|
||||
|atlas_pos, pos, norm, &meta| create_opaque(atlas_pos, pos, norm, meta),
|
||||
));
|
||||
},
|
||||
},
|
||||
);
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
mesh::{
|
||||
greedy::{self, GreedyMesh},
|
||||
greedy::{self, GreedyConfig, GreedyMesh},
|
||||
Meshable,
|
||||
},
|
||||
render::{self, ColLightInfo, FluidPipeline, Mesh, ShadowPipeline, TerrainPipeline},
|
||||
@ -503,8 +503,9 @@ impl<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug>
|
||||
let get_color =
|
||||
|_: &mut (), pos: Vec3<i32>| flat_get(pos).get_color().unwrap_or(Rgb::zero());
|
||||
let get_opacity = |_: &mut (), pos: Vec3<i32>| !flat_get(pos).is_opaque();
|
||||
let flat_get = |pos| flat_get(pos);
|
||||
let should_draw = |_: &mut (), pos: Vec3<i32>, delta: Vec3<i32>, _uv| {
|
||||
should_draw_greedy(pos, delta, |pos| flat_get(pos))
|
||||
should_draw_greedy(pos, delta, flat_get)
|
||||
};
|
||||
// NOTE: Conversion to f32 is fine since this i32 is actually in bounds for u16.
|
||||
// let create_shadow = |pos, norm, meta| ShadowVertex::new(pos + Vec3::new(0.0,
|
||||
@ -513,45 +514,44 @@ impl<'a, V: RectRasterableVol<Vox = Block> + ReadVol + Debug>
|
||||
let create_opaque = |atlas_pos, pos, norm, meta| {
|
||||
TerrainVertex::new(atlas_pos, pos + mesh_delta, norm, meta)
|
||||
};
|
||||
let create_transparent =
|
||||
|_atlas_pos, pos, norm, _meta| FluidVertex::new(pos + mesh_delta, norm);
|
||||
let create_transparent = |_atlas_pos, pos, norm| FluidVertex::new(pos + mesh_delta, norm);
|
||||
|
||||
let mut greedy = GreedyMesh::new(max_size);
|
||||
let mut opaque_mesh = Mesh::new();
|
||||
let mut fluid_mesh = Mesh::new();
|
||||
let bounds = greedy.push(
|
||||
(),
|
||||
draw_delta,
|
||||
greedy_size,
|
||||
greedy_size_cross,
|
||||
get_light,
|
||||
get_color,
|
||||
get_opacity,
|
||||
should_draw,
|
||||
|atlas_origin, dim, origin, draw_dim, norm, meta| match meta {
|
||||
FaceKind::Opaque(meta) => {
|
||||
opaque_mesh.push_quad(greedy::create_quad(
|
||||
atlas_origin,
|
||||
dim,
|
||||
origin,
|
||||
draw_dim,
|
||||
norm,
|
||||
meta,
|
||||
|atlas_pos, pos, norm, &meta| create_opaque(atlas_pos, pos, norm, meta),
|
||||
));
|
||||
},
|
||||
FaceKind::Fluid => {
|
||||
fluid_mesh.push_quad(greedy::create_quad(
|
||||
atlas_origin,
|
||||
dim,
|
||||
origin,
|
||||
draw_dim,
|
||||
norm,
|
||||
&(),
|
||||
|atlas_pos, pos, norm, &meta| {
|
||||
create_transparent(atlas_pos, pos, norm, meta)
|
||||
},
|
||||
));
|
||||
GreedyConfig {
|
||||
data: (),
|
||||
draw_delta,
|
||||
greedy_size,
|
||||
greedy_size_cross,
|
||||
get_light,
|
||||
get_color,
|
||||
get_opacity,
|
||||
should_draw,
|
||||
push_quad: |atlas_origin, dim, origin, draw_dim, norm, meta: &FaceKind| match meta {
|
||||
FaceKind::Opaque(meta) => {
|
||||
opaque_mesh.push_quad(greedy::create_quad(
|
||||
atlas_origin,
|
||||
dim,
|
||||
origin,
|
||||
draw_dim,
|
||||
norm,
|
||||
meta,
|
||||
|atlas_pos, pos, norm, &meta| create_opaque(atlas_pos, pos, norm, meta),
|
||||
));
|
||||
},
|
||||
FaceKind::Fluid => {
|
||||
fluid_mesh.push_quad(greedy::create_quad(
|
||||
atlas_origin,
|
||||
dim,
|
||||
origin,
|
||||
draw_dim,
|
||||
norm,
|
||||
&(),
|
||||
|atlas_pos, pos, norm, &_meta| create_transparent(atlas_pos, pos, norm),
|
||||
));
|
||||
},
|
||||
},
|
||||
},
|
||||
);
|
||||
|
@ -128,7 +128,7 @@ impl<P: Pipeline> Quad<P> {
|
||||
let verts = [self.a, self.b, self.c, self.d];
|
||||
|
||||
Self {
|
||||
a: verts[(0 + n) % 4].clone(),
|
||||
a: verts[n % 4].clone(),
|
||||
b: verts[(1 + n) % 4].clone(),
|
||||
c: verts[(2 + n) % 4].clone(),
|
||||
d: verts[(3 + n) % 4].clone(),
|
||||
|
@ -163,7 +163,7 @@ impl FigureModel {
|
||||
// in order to store the bone index. The two bits are instead taken out
|
||||
// of the atlas coordinates, which is why we "only" allow 1 << 15 per
|
||||
// coordinate instead of 1 << 16.
|
||||
let max_size = guillotiere::Size::new(1 << 15 - 1, 1 << 15 - 1);
|
||||
let max_size = guillotiere::Size::new((1 << 15) - 1, (1 << 15) - 1);
|
||||
GreedyMesh::new(max_size)
|
||||
}
|
||||
}
|
||||
|
@ -84,8 +84,10 @@ impl Vertex {
|
||||
if norm.x < 0.0 { 0 } else { 1 }
|
||||
} else if norm.y != 0.0 {
|
||||
if norm.y < 0.0 { 2 } else { 3 }
|
||||
} else if norm.z < 0.0 {
|
||||
4
|
||||
} else {
|
||||
if norm.z < 0.0 { 4 } else { 5 }
|
||||
5
|
||||
};
|
||||
// let ao = 0xFFu32;
|
||||
// let light = 0xFFu32;
|
||||
|
@ -82,10 +82,7 @@ impl fmt::Display for Vertex {
|
||||
.field("pos", &Vec3::<f32>::from(self.pos))
|
||||
.field(
|
||||
"atlas_pos",
|
||||
&Vec2::new(
|
||||
(self.atlas_pos >> 0) & 0xFFFF,
|
||||
(self.atlas_pos >> 16) & 0xFFFF,
|
||||
),
|
||||
&Vec2::new(self.atlas_pos & 0xFFFF, (self.atlas_pos >> 16) & 0xFFFF),
|
||||
)
|
||||
.field("norm_ao", &self.norm_ao)
|
||||
.finish()
|
||||
|
@ -58,8 +58,10 @@ impl Vertex {
|
||||
if norm.x < 0.0 { 0 } else { 1 }
|
||||
} else if norm.y != 0.0 {
|
||||
if norm.y < 0.0 { 2 } else { 3 }
|
||||
} else if norm.z < 0.0 {
|
||||
4
|
||||
} else {
|
||||
if norm.z < 0.0 { 4 } else { 5 }
|
||||
5
|
||||
};
|
||||
Self {
|
||||
pos_norm: 0
|
||||
|
@ -166,7 +166,7 @@ impl Renderer {
|
||||
let shadow_views = Self::create_shadow_views(
|
||||
&mut factory,
|
||||
(dims.0, dims.1),
|
||||
&ShadowMapMode::try_from(mode.shadow).unwrap_or(ShadowMapMode::default()),
|
||||
&ShadowMapMode::try_from(mode.shadow).unwrap_or_default(),
|
||||
)
|
||||
.map_err(|err| {
|
||||
warn!("Could not create shadow map views: {:?}", err);
|
||||
@ -1192,7 +1192,6 @@ impl Renderer {
|
||||
_alt: &Texture<LodAltFmt>,
|
||||
_horizon: &Texture<LodTextureFmt>,
|
||||
) {
|
||||
return;
|
||||
/* let (point_shadow_maps, directed_shadow_maps) =
|
||||
if let Some(shadow_map) = &mut self.shadow_map {
|
||||
(
|
||||
@ -2222,7 +2221,7 @@ fn create_shadow_pipeline<P: gfx::pso::PipelineInit>(
|
||||
factory.create_shader_set(vs.as_bytes(), fs.as_bytes())?
|
||||
};
|
||||
|
||||
let result = Ok(GfxPipeline {
|
||||
Ok(GfxPipeline {
|
||||
pso: factory.create_pipeline_state(
|
||||
&shader_set,
|
||||
gfx::Primitive::TriangleList,
|
||||
@ -2242,7 +2241,5 @@ fn create_shadow_pipeline<P: gfx::pso::PipelineInit>(
|
||||
},
|
||||
pipe,
|
||||
)?,
|
||||
});
|
||||
|
||||
result
|
||||
})
|
||||
}
|
||||
|
@ -59,7 +59,8 @@ where
|
||||
filter_method.unwrap_or(gfx::texture::FilterMethod::Scale),
|
||||
wrap_mode.unwrap_or(gfx::texture::WrapMode::Clamp),
|
||||
);
|
||||
sampler_info.border = border.unwrap_or([0.0, 0.0, 0.0, 1.0].into());
|
||||
let transparent = [0.0, 0.0, 0.0, 1.0].into();
|
||||
sampler_info.border = border.unwrap_or(transparent);
|
||||
Ok(Self {
|
||||
tex,
|
||||
srv,
|
||||
|
@ -185,7 +185,7 @@ impl FigureMgrStates {
|
||||
}
|
||||
}
|
||||
|
||||
fn retain<'a>(&'a mut self, mut f: impl FnMut(&EcsEntity, &mut FigureStateMeta) -> bool) {
|
||||
fn retain(&mut self, mut f: impl FnMut(&EcsEntity, &mut FigureStateMeta) -> bool) {
|
||||
self.character_states.retain(|k, v| f(k, &mut *v));
|
||||
self.quadruped_small_states.retain(|k, v| f(k, &mut *v));
|
||||
self.quadruped_medium_states.retain(|k, v| f(k, &mut *v));
|
||||
|
@ -53,7 +53,7 @@ pub fn mat_mul_points<T: Float + MulAdd<T, T, Output = T>>(
|
||||
pts: &mut [Vec3<T>],
|
||||
mut do_p: impl FnMut(Vec4<T>) -> Vec3<T>,
|
||||
) {
|
||||
pts.into_iter().for_each(|p| {
|
||||
pts.iter_mut().for_each(|p| {
|
||||
*p = do_p(mat * Vec4::from_point(*p));
|
||||
});
|
||||
}
|
||||
@ -480,12 +480,10 @@ pub fn clip_test<T: Float + core::fmt::Debug>(p: T, q: T, (u1, u2): (T, T)) -> O
|
||||
} else {
|
||||
Some((if r > u1 { r } else { u1 }, u2))
|
||||
}
|
||||
} else if r < u1 {
|
||||
None
|
||||
} else {
|
||||
if r < u1 {
|
||||
None
|
||||
} else {
|
||||
Some((u1, if r < u2 { r } else { u2 }))
|
||||
}
|
||||
Some((u1, if r < u2 { r } else { u2 }))
|
||||
}
|
||||
} /*;
|
||||
// println!("clip_test@(p={:?}, q={:?}, (u1, u2)=({:?}. {:?})):
|
||||
|
@ -1195,19 +1195,19 @@ impl Scene {
|
||||
let w_p: math::Mat4<f32> = {
|
||||
if /*sin_gamma > EPISLON_GAMMA*/factor > EPSILON_UPSILON {
|
||||
// Projection for y
|
||||
let n = directed_near;// - near_dist;
|
||||
let f = directed_far;
|
||||
let l = -1.0;// bounds0.min.x;//-1.0;// bounds0.min.x - light_focus_pos.x;
|
||||
let r = 1.0;// bounds0.max.x;//1.0;// bounds0.max.x - light_focus_pos.x;
|
||||
let b = -1.0;// bounds0.max.z;// bounds0.max.z - light_focus_pos.z;
|
||||
let t = 1.0;// bounds0.min.z;// bounds0.min.z - light_focus_pos.z;
|
||||
let s_x = 2.0 * n / (r - l);
|
||||
let o_x = (r + l) / (r - l);
|
||||
let s_z = 2.0 * n / (t - b);
|
||||
let o_z = (t + b) / (t - b);
|
||||
let near = directed_near;// - near_dist;
|
||||
let far = directed_far;
|
||||
let left = -1.0;// bounds0.min.x;//-1.0;// bounds0.min.x - light_focus_pos.x;
|
||||
let right = 1.0;// bounds0.max.x;//1.0;// bounds0.max.x - light_focus_pos.x;
|
||||
let bottom = -1.0;// bounds0.max.z;// bounds0.max.z - light_focus_pos.z;
|
||||
let top = 1.0;// bounds0.min.z;// bounds0.min.z - light_focus_pos.z;
|
||||
let s_x = 2.0 * near / (right - left);
|
||||
let o_x = (right + left) / (right - left);
|
||||
let s_z = 2.0 * near / (top - bottom);
|
||||
let o_z = (top + bottom) / (top - bottom);
|
||||
|
||||
let s_y = (f + n) / (f - n);
|
||||
let o_y = -2.0 * f * n / (f - n);
|
||||
let s_y = (far + near) / (far - near);
|
||||
let o_y = -2.0 * far * near / (far - near);
|
||||
// y(y₀) = s_y y₀ + o_y
|
||||
// = ((f + n)y₀ - 2fn) / (f - n)
|
||||
// y(f) = s_y f + o_y
|
||||
@ -1337,22 +1337,12 @@ impl Scene {
|
||||
let o_x = -(xmax + xmin) / (xmax - xmin);
|
||||
let o_y = -(ymax + ymin) / (ymax - ymin);
|
||||
let o_z = -(zmax + zmin) / (zmax - zmin);
|
||||
let directed_proj_mat = if /*sin_gamma > EPISLON_GAMMA*/factor > EPSILON_UPSILON {
|
||||
// Mat4::identity()
|
||||
Mat4::new(
|
||||
s_x, 0.0, 0.0, o_x,
|
||||
0.0, s_y, 0.0, o_y,
|
||||
0.0, 0.0, /*-*/s_z, /*-*/o_z,
|
||||
0.0, 0.0, 0.0, 1.0,
|
||||
)/*.scaled_3d(Vec3::new(1.0, 1.0, -1.0))*/
|
||||
} else {
|
||||
Mat4::new(
|
||||
s_x, 0.0, 0.0, o_x,
|
||||
0.0, s_y, 0.0, o_y,
|
||||
0.0, 0.0, s_z, o_z,
|
||||
0.0, 0.0, 0.0, 1.0,
|
||||
)/*.scaled_3d(Vec3::new(1.0, 1.0, -1.0))*/
|
||||
}/*.scaled_3d(Vec3::new(1.0, 1.0, -1.0))*//* * w_p * w_v*//* * l_r*/;//Mat4::identity();
|
||||
let directed_proj_mat = Mat4::new(
|
||||
s_x, 0.0, 0.0, o_x,
|
||||
0.0, s_y, 0.0, o_y,
|
||||
0.0, 0.0, s_z, o_z,
|
||||
0.0, 0.0, 0.0, 1.0,
|
||||
)/*.scaled_3d(Vec3::new(1.0, 1.0, -1.0))*//* * w_p * w_v*//* * l_r*/;//Mat4::identity();
|
||||
// println!("proj_mat: {:?}", directed_proj_mat);
|
||||
// println!("all_mat: {:?}", directed_proj_mat * view_mat);
|
||||
// let _w_p_arr = directed_proj_mat.cols.iter().map(|e| (e.x, e.y, e.z, e.w)).collect::<Vec<_>>();
|
||||
|
@ -525,6 +525,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
let mut make_models = |(kind, variation), s, offset, lod_axes: Vec3<f32>| {
|
||||
let scaled = [1.0, 0.8, 0.6, 0.4, 0.2];
|
||||
let model = assets::load_expect::<DotVoxData>(s);
|
||||
let zero = Vec3::zero();
|
||||
let model_size = model
|
||||
.models
|
||||
.first()
|
||||
@ -534,7 +535,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
..
|
||||
}| Vec3::new(x, y, z),
|
||||
)
|
||||
.unwrap_or(Vec3::zero());
|
||||
.unwrap_or(zero);
|
||||
let max_model_size = Vec3::new(15.0, 15.0, 63.0);
|
||||
let model_scale = max_model_size.map2(model_size, |max_sz: f32, cur_sz| {
|
||||
let scale = max_sz / max_sz.max(cur_sz as f32);
|
||||
@ -2663,7 +2664,7 @@ impl<V: RectRasterableVol> Terrain<V> {
|
||||
// store it. Only pull out one chunk per frame to avoid an unacceptable
|
||||
// amount of blocking lag due to the GPU upload. That still gives us a
|
||||
// 60 chunks / second budget to play with.
|
||||
if let Some(response) = self.mesh_recv.recv_timeout(Duration::new(0, 0)).ok() {
|
||||
if let Ok(response) = self.mesh_recv.recv_timeout(Duration::new(0, 0)) {
|
||||
match self.mesh_todo.get(&response.pos) {
|
||||
// It's the mesh we want, insert the newly finished model into the terrain model
|
||||
// data structure (convert the mesh to a model first of course).
|
||||
|
@ -6,7 +6,8 @@
|
||||
const_if_match,
|
||||
const_generics,
|
||||
const_panic,
|
||||
label_break_value
|
||||
label_break_value,
|
||||
or_patterns
|
||||
)]
|
||||
|
||||
mod all;
|
||||
|
@ -232,7 +232,7 @@ pub fn sample_pos(
|
||||
);
|
||||
Rgb::new((r * 255.0) as u8, (g * 255.0) as u8, (b * 255.0) as u8)
|
||||
},
|
||||
(None, _) | (Some(RiverKind::Lake { .. }), _) | (Some(RiverKind::Ocean), _) => Rgb::new(
|
||||
(None | Some(RiverKind::Lake { .. } | RiverKind::Ocean), _) => Rgb::new(
|
||||
0,
|
||||
((g_water - water_depth * g_water) * 1.0) as u8,
|
||||
((b_water - water_depth * b_water) * 1.0) as u8,
|
||||
|
@ -1440,7 +1440,7 @@ impl WorldSim {
|
||||
/* let z_cache = block_gen.get_z_cache(wpos);
|
||||
sample.alt = alt.max(z_cache.get_z_limits(&mut block_gen).2); */
|
||||
sample.alt = alt.max(BlockGen::get_cliff_height(
|
||||
&mut block_gen.column_gen,
|
||||
&block_gen.column_gen,
|
||||
&mut block_gen.column_cache,
|
||||
wpos.map(|e| e as f32),
|
||||
&sample.close_cliffs,
|
||||
@ -1719,12 +1719,12 @@ impl WorldSim {
|
||||
}
|
||||
|
||||
pub fn get_base_z(&self, chunk_pos: Vec2<i32>) -> Option<f32> {
|
||||
if !chunk_pos
|
||||
let in_bounds = chunk_pos
|
||||
.map2(self.map_size_lg().chunks(), |e, sz| {
|
||||
e > 0 && e < sz as i32 - 2
|
||||
})
|
||||
.reduce_and()
|
||||
{
|
||||
.reduce_and();
|
||||
if !in_bounds {
|
||||
return None;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user