oxygengine_composite_renderer/system/
mesh_animation.rs

1use crate::{
2    component::{CompositeMesh, CompositeMeshAnimation},
3    mesh_animation_asset_protocol::{MeshAnimation, MeshAnimationAsset},
4};
5use core::{
6    app::AppLifeCycle,
7    assets::{asset::AssetId, database::AssetsDatabase},
8    ecs::{Comp, Universe, WorldRef},
9    Scalar,
10};
11use std::collections::HashMap;
12
13#[derive(Debug, Default)]
14pub struct CompositeMeshAnimationSystemCache {
15    animations_cache: HashMap<String, MeshAnimation>,
16    animations_table: HashMap<AssetId, String>,
17}
18
19pub type CompositeMeshAnimationSystemResources<'a> = (
20    WorldRef,
21    &'a AppLifeCycle,
22    &'a AssetsDatabase,
23    &'a mut CompositeMeshAnimationSystemCache,
24    Comp<&'a mut CompositeMesh>,
25    Comp<&'a mut CompositeMeshAnimation>,
26);
27
28pub fn composite_mesh_animation_system(universe: &mut Universe) {
29    let (world, lifecycle, assets, mut cache, ..) =
30        universe.query_resources::<CompositeMeshAnimationSystemResources>();
31
32    for id in assets.lately_loaded_protocol("mesh-anim") {
33        let id = *id;
34        let asset = assets
35            .asset_by_id(id)
36            .expect("trying to use not loaded mesh animation asset");
37        let path = asset.path().to_owned();
38        let asset = asset
39            .get::<MeshAnimationAsset>()
40            .expect("trying to use non-mesh-animation asset");
41        let animation = asset.animation().clone();
42        cache.animations_cache.insert(path.clone(), animation);
43        cache.animations_table.insert(id, path);
44    }
45    for id in assets.lately_unloaded_protocol("mesh-anim") {
46        if let Some(path) = cache.animations_table.remove(id) {
47            cache.animations_cache.remove(&path);
48        }
49    }
50
51    let dt = lifecycle.delta_time_seconds() as Scalar;
52    for (_, (mesh, animation)) in world
53        .query::<(&mut CompositeMesh, &mut CompositeMeshAnimation)>()
54        .iter()
55    {
56        if animation.dirty {
57            if let Some(asset) = cache.animations_cache.get(animation.animation()) {
58                animation.process(dt, asset, mesh);
59            }
60        }
61    }
62}