oxygengine_composite_renderer/system/
mesh_animation.rs1use 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}