mirror of
https://gitlab.com/veloren/veloren.git
synced 2024-08-30 18:12:32 +00:00
Clean up figure cache models when necessary
Former-commit-id: 7653217b2f4c02f5c179e35907fa47c3526b2a2e
This commit is contained in:
parent
df7a145bbc
commit
7baecff1f0
@ -48,7 +48,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub struct FigureCache {
|
pub struct FigureCache {
|
||||||
models: HashMap<Character, Model<FigurePipeline>>,
|
models: HashMap<Character, (Model<FigurePipeline>, u64)>,
|
||||||
states: HashMap<EcsEntity, FigureState<CharacterSkeleton>>,
|
states: HashMap<EcsEntity, FigureState<CharacterSkeleton>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,11 +61,17 @@ impl FigureCache {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_or_create_model<'a>(
|
pub fn get_or_create_model<'a>(
|
||||||
models: &'a mut HashMap<Character, Model<FigurePipeline>>,
|
models: &'a mut HashMap<Character, (Model<FigurePipeline>, u64)>,
|
||||||
renderer: &mut Renderer,
|
renderer: &mut Renderer,
|
||||||
|
tick: u64,
|
||||||
character: Character)
|
character: Character)
|
||||||
-> &'a Model<FigurePipeline> {
|
-> &'a (Model<FigurePipeline>, u64) {
|
||||||
models.entry(character).or_insert_with(|| {
|
match models.get_mut(&character) {
|
||||||
|
Some((model, last_used)) => {
|
||||||
|
*last_used = tick;
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
models.insert(character, ({
|
||||||
let bone_meshes = [
|
let bone_meshes = [
|
||||||
Some(Self::load_head(character.head)),
|
Some(Self::load_head(character.head)),
|
||||||
Some(Self::load_chest(character.chest)),
|
Some(Self::load_chest(character.chest)),
|
||||||
@ -95,7 +101,16 @@ impl FigureCache {
|
|||||||
});
|
});
|
||||||
|
|
||||||
renderer.create_model(&mesh).unwrap()
|
renderer.create_model(&mesh).unwrap()
|
||||||
})
|
}, tick));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
&models[&character]
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clean(&mut self, tick: u64) {
|
||||||
|
// TODO: Don't hard-code this
|
||||||
|
self.models.retain(|_, (_, last_used)| *last_used + 60 > tick);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn load_mesh(filename: &'static str, position: Vec3<f32>) -> Mesh<FigurePipeline> {
|
fn load_mesh(filename: &'static str, position: Vec3<f32>) -> Mesh<FigurePipeline> {
|
||||||
@ -191,17 +206,19 @@ impl FigureCache {
|
|||||||
self.states.retain(|entity, _| ecs.entities().is_alive(*entity));
|
self.states.retain(|entity, _| ecs.entities().is_alive(*entity));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn render(&mut self, renderer: &mut Renderer, client: &Client, globals: &Consts<Globals>) {
|
pub fn render(&mut self, renderer: &mut Renderer, client: &mut Client, globals: &Consts<Globals>) {
|
||||||
|
let tick = client.get_tick();
|
||||||
let ecs = client.state().ecs();
|
let ecs = client.state().ecs();
|
||||||
let models = &mut self.models;
|
let models = &mut self.models;
|
||||||
|
|
||||||
for (entity, &character) in (
|
for (entity, &character) in (
|
||||||
&ecs.entities(),
|
&ecs.entities(),
|
||||||
&ecs.read_storage::<comp::Character>(),
|
&ecs.read_storage::<comp::Character>(),
|
||||||
).join() {
|
).join() {
|
||||||
let model = Self::get_or_create_model(models, renderer, character);
|
let model = Self::get_or_create_model(models, renderer, tick, character);
|
||||||
let state = self.states.get(&entity).unwrap();
|
let state = self.states.get(&entity).unwrap();
|
||||||
renderer.render_figure(
|
renderer.render_figure(
|
||||||
model,
|
&model.0,
|
||||||
globals,
|
globals,
|
||||||
&state.locals,
|
&state.locals,
|
||||||
&state.bone_consts,
|
&state.bone_consts,
|
||||||
|
@ -139,10 +139,13 @@ impl Scene {
|
|||||||
|
|
||||||
// Maintain the figures
|
// Maintain the figures
|
||||||
self.figure_cache.maintain(renderer, client);
|
self.figure_cache.maintain(renderer, client);
|
||||||
|
|
||||||
|
// Remove unused figures
|
||||||
|
self.figure_cache.clean(client.get_tick());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Render the scene using the provided `Renderer`
|
/// Render the scene using the provided `Renderer`
|
||||||
pub fn render(&mut self, renderer: &mut Renderer, client: &Client) {
|
pub fn render(&mut self, renderer: &mut Renderer, client: &mut Client) {
|
||||||
// Render the skybox first (it appears over everything else so must be rendered first)
|
// Render the skybox first (it appears over everything else so must be rendered first)
|
||||||
renderer.render_skybox(
|
renderer.render_skybox(
|
||||||
&self.skybox.model,
|
&self.skybox.model,
|
||||||
|
@ -87,7 +87,7 @@ impl SessionState {
|
|||||||
renderer.clear(BG_COLOR);
|
renderer.clear(BG_COLOR);
|
||||||
|
|
||||||
// Render the screen using the global renderer
|
// Render the screen using the global renderer
|
||||||
self.scene.render(renderer, &self.client.borrow());
|
self.scene.render(renderer, &mut self.client.borrow_mut());
|
||||||
// Draw the UI to the screen
|
// Draw the UI to the screen
|
||||||
self.hud.render(renderer);
|
self.hud.render(renderer);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user