mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Make models require a non-zero amount of vertices
This commit is contained in:
parent
2c074ac52b
commit
b61793142e
@ -29,10 +29,15 @@ pub struct Model<V: Vertex> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<V: Vertex> Model<V> {
|
impl<V: Vertex> Model<V> {
|
||||||
pub fn new(device: &wgpu::Device, mesh: &Mesh<V>) -> Self {
|
/// Returns None if the provided mesh is empty
|
||||||
Self {
|
pub fn new(device: &wgpu::Device, mesh: &Mesh<V>) -> Option<Self> {
|
||||||
vbuf: Buffer::new(device, wgpu::BufferUsage::VERTEX, mesh.vertices()),
|
if mesh.vertices().is_empty() {
|
||||||
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Some(Self {
|
||||||
|
vbuf: Buffer::new(device, wgpu::BufferUsage::VERTEX, mesh.vertices()),
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a model with a slice of a portion of this model to send to the
|
/// Create a model with a slice of a portion of this model to send to the
|
||||||
|
@ -980,9 +980,10 @@ impl Renderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new model from the provided mesh.
|
/// Create a new model from the provided mesh.
|
||||||
pub fn create_model<V: Vertex>(&mut self, mesh: &Mesh<V>) -> Result<Model<V>, RenderError> {
|
/// If the provided mesh is empty this returns None
|
||||||
|
pub fn create_model<V: Vertex>(&mut self, mesh: &Mesh<V>) -> Option<Model<V>> {
|
||||||
self.ensure_sufficient_index_length::<V>(mesh.vertices().len());
|
self.ensure_sufficient_index_length::<V>(mesh.vertices().len());
|
||||||
Ok(Model::new(&self.device, mesh))
|
Model::new(&self.device, mesh)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a new dynamic model with the specified size.
|
/// Create a new dynamic model with the specified size.
|
||||||
|
@ -370,16 +370,12 @@ where
|
|||||||
vertex_range,
|
vertex_range,
|
||||||
}) = Arc::get_mut(recv).take().and_then(|cell| cell.take())
|
}) = Arc::get_mut(recv).take().and_then(|cell| cell.take())
|
||||||
{
|
{
|
||||||
// FIXME: We really need to stop hard failing on failure to upload
|
let model_entry = col_lights.create_figure(
|
||||||
// to the GPU.
|
|
||||||
let model_entry = col_lights
|
|
||||||
.create_figure(
|
|
||||||
renderer,
|
renderer,
|
||||||
col_light,
|
col_light,
|
||||||
(opaque, bounds),
|
(opaque, bounds),
|
||||||
vertex_range,
|
vertex_range,
|
||||||
)
|
);
|
||||||
.expect("Failed to upload figure data to the GPU!");
|
|
||||||
*model = FigureModelEntryFuture::Done(model_entry);
|
*model = FigureModelEntryFuture::Done(model_entry);
|
||||||
// NOTE: Borrow checker isn't smart enough to figure this out.
|
// NOTE: Borrow checker isn't smart enough to figure this out.
|
||||||
if let FigureModelEntryFuture::Done(model) = model {
|
if let FigureModelEntryFuture::Done(model) = model {
|
||||||
|
@ -5200,13 +5200,15 @@ impl FigureColLights {
|
|||||||
/// NOTE: Panics if the vertex range bounds are not in range of the opaque
|
/// NOTE: Panics if the vertex range bounds are not in range of the opaque
|
||||||
/// model stored in the BoneMeshes parameter. This is part of the
|
/// model stored in the BoneMeshes parameter. This is part of the
|
||||||
/// function contract.
|
/// function contract.
|
||||||
|
///
|
||||||
|
/// NOTE: Panics if the provided mesh is empty. FIXME: do something else
|
||||||
pub fn create_figure<const N: usize>(
|
pub fn create_figure<const N: usize>(
|
||||||
&mut self,
|
&mut self,
|
||||||
renderer: &mut Renderer,
|
renderer: &mut Renderer,
|
||||||
(tex, tex_size): ColLightInfo,
|
(tex, tex_size): ColLightInfo,
|
||||||
(opaque, bounds): (Mesh<TerrainVertex>, math::Aabb<f32>),
|
(opaque, bounds): (Mesh<TerrainVertex>, math::Aabb<f32>),
|
||||||
vertex_ranges: [Range<u32>; N],
|
vertex_ranges: [Range<u32>; N],
|
||||||
) -> Result<FigureModelEntry<N>, RenderError> {
|
) -> FigureModelEntry<N> {
|
||||||
span!(_guard, "create_figure", "FigureColLights::create_figure");
|
span!(_guard, "create_figure", "FigureColLights::create_figure");
|
||||||
let atlas = &mut self.atlas;
|
let atlas = &mut self.atlas;
|
||||||
let allocation = atlas
|
let allocation = atlas
|
||||||
@ -5216,7 +5218,9 @@ impl FigureColLights {
|
|||||||
let col_lights = renderer.figure_bind_col_light(col_lights);
|
let col_lights = renderer.figure_bind_col_light(col_lights);
|
||||||
let model_len = u32::try_from(opaque.vertices().len())
|
let model_len = u32::try_from(opaque.vertices().len())
|
||||||
.expect("The model size for this figure does not fit in a u32!");
|
.expect("The model size for this figure does not fit in a u32!");
|
||||||
let model = renderer.create_model(&opaque)?;
|
let model = renderer
|
||||||
|
.create_model(&opaque)
|
||||||
|
.expect("The model contains no vertices!");
|
||||||
|
|
||||||
vertex_ranges.iter().for_each(|range| {
|
vertex_ranges.iter().for_each(|range| {
|
||||||
assert!(
|
assert!(
|
||||||
@ -5228,13 +5232,13 @@ impl FigureColLights {
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(FigureModelEntry {
|
FigureModelEntry {
|
||||||
_bounds: bounds,
|
_bounds: bounds,
|
||||||
allocation,
|
allocation,
|
||||||
col_lights,
|
col_lights,
|
||||||
lod_vertex_ranges: vertex_ranges,
|
lod_vertex_ranges: vertex_ranges,
|
||||||
model: FigureModel { opaque: model },
|
model: FigureModel { opaque: model },
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::unnecessary_wraps)]
|
#[allow(clippy::unnecessary_wraps)]
|
||||||
|
@ -140,9 +140,9 @@ impl Scene {
|
|||||||
// total size is bounded by 2^24 * 3 * 1.5 which is bounded by
|
// total size is bounded by 2^24 * 3 * 1.5 which is bounded by
|
||||||
// 2^27, which fits in a u32.
|
// 2^27, which fits in a u32.
|
||||||
let range = 0..opaque_mesh.vertices().len() as u32;
|
let range = 0..opaque_mesh.vertices().len() as u32;
|
||||||
let model = col_lights
|
let model =
|
||||||
.create_figure(renderer, greedy.finalize(), (opaque_mesh, bounds), [range])
|
col_lights
|
||||||
.unwrap();
|
.create_figure(renderer, greedy.finalize(), (opaque_mesh, bounds), [range]);
|
||||||
let mut buf = [Default::default(); anim::MAX_BONE_COUNT];
|
let mut buf = [Default::default(); anim::MAX_BONE_COUNT];
|
||||||
state.update(
|
state.update(
|
||||||
renderer,
|
renderer,
|
||||||
|
@ -72,7 +72,7 @@ type LightMapFn = Arc<dyn Fn(Vec3<i32>) -> f32 + Send + Sync>;
|
|||||||
pub struct TerrainChunkData {
|
pub struct TerrainChunkData {
|
||||||
// GPU data
|
// GPU data
|
||||||
load_time: f32,
|
load_time: f32,
|
||||||
opaque_model: Model<TerrainVertex>,
|
opaque_model: Option<Model<TerrainVertex>>,
|
||||||
fluid_model: Option<Model<FluidVertex>>,
|
fluid_model: Option<Model<FluidVertex>>,
|
||||||
/// If this is `None`, this texture is not allocated in the current atlas,
|
/// If this is `None`, this texture is not allocated in the current atlas,
|
||||||
/// and therefore there is no need to free its allocation.
|
/// and therefore there is no need to free its allocation.
|
||||||
@ -1146,18 +1146,8 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
|
|
||||||
self.insert_chunk(response.pos, TerrainChunkData {
|
self.insert_chunk(response.pos, TerrainChunkData {
|
||||||
load_time,
|
load_time,
|
||||||
opaque_model: renderer
|
opaque_model: renderer.create_model(&mesh.opaque_mesh),
|
||||||
.create_model(&mesh.opaque_mesh)
|
fluid_model: renderer.create_model(&mesh.fluid_mesh),
|
||||||
.expect("Failed to upload chunk mesh to the GPU!"),
|
|
||||||
fluid_model: if mesh.fluid_mesh.vertices().len() > 0 {
|
|
||||||
Some(
|
|
||||||
renderer
|
|
||||||
.create_model(&mesh.fluid_mesh)
|
|
||||||
.expect("Failed to upload chunk mesh to the GPU!"),
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
col_lights_alloc: Some(allocation.id),
|
col_lights_alloc: Some(allocation.id),
|
||||||
col_lights: Arc::clone(&self.col_lights),
|
col_lights: Arc::clone(&self.col_lights),
|
||||||
light_map: mesh.light_map,
|
light_map: mesh.light_map,
|
||||||
@ -1422,7 +1412,13 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
chunk_iter
|
chunk_iter
|
||||||
.filter(|chunk| chunk.can_shadow_sun())
|
.filter(|chunk| chunk.can_shadow_sun())
|
||||||
.chain(self.shadow_chunks.iter().map(|(_, chunk)| chunk))
|
.chain(self.shadow_chunks.iter().map(|(_, chunk)| chunk))
|
||||||
.for_each(|chunk| drawer.draw(&chunk.opaque_model, &chunk.locals));
|
.filter_map(|chunk| {
|
||||||
|
chunk
|
||||||
|
.opaque_model
|
||||||
|
.as_ref()
|
||||||
|
.map(|model| (model, &chunk.locals))
|
||||||
|
})
|
||||||
|
.for_each(|(model, locals)| drawer.draw(model, locals));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn chunks_for_point_shadows(
|
pub fn chunks_for_point_shadows(
|
||||||
@ -1452,7 +1448,12 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
// don't use `shadow_chunks` here.
|
// don't use `shadow_chunks` here.
|
||||||
chunk_iter
|
chunk_iter
|
||||||
.filter(|chunk| chunk.can_shadow_point)
|
.filter(|chunk| chunk.can_shadow_point)
|
||||||
.map(|chunk| (&chunk.opaque_model, &chunk.locals))
|
.filter_map(|chunk| {
|
||||||
|
chunk
|
||||||
|
.opaque_model
|
||||||
|
.as_ref()
|
||||||
|
.map(|model| (model, &chunk.locals))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render<'a>(&'a self, drawer: &mut FirstPassDrawer<'a>, focus_pos: Vec3<f32>) {
|
pub fn render<'a>(&'a self, drawer: &mut FirstPassDrawer<'a>, focus_pos: Vec3<f32>) {
|
||||||
@ -1470,7 +1471,13 @@ impl<V: RectRasterableVol> Terrain<V> {
|
|||||||
})
|
})
|
||||||
.take(self.chunks.len())
|
.take(self.chunks.len())
|
||||||
.filter(|chunk| chunk.visible.is_visible())
|
.filter(|chunk| chunk.visible.is_visible())
|
||||||
.for_each(|chunk| drawer.draw(&chunk.opaque_model, &chunk.col_lights, &chunk.locals));
|
.filter_map(|chunk| {
|
||||||
|
chunk
|
||||||
|
.opaque_model
|
||||||
|
.as_ref()
|
||||||
|
.map(|model| (model, &chunk.col_lights, &chunk.locals))
|
||||||
|
})
|
||||||
|
.for_each(|(model, col_lights, locals)| drawer.draw(model, col_lights, locals));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render_translucent<'a>(
|
pub fn render_translucent<'a>(
|
||||||
|
Loading…
Reference in New Issue
Block a user