smpl_gloss_integration/
scene.rs1use crate::components::GlossInterop;
2use gloss_hecs::EntityBuilder;
3use gloss_renderer::components::Name;
4use log::info;
5use ndarray::s;
6use smpl_core::{
7 codec::scene::McsCodec,
8 common::{
9 animation::{AnimWrap, Animation, AnimationConfig, AnimationRunner},
10 betas::Betas,
11 pose_override::PoseOverride,
12 smpl_params::SmplParams,
13 },
14};
15use std::time::Duration;
16pub trait McsCodecGloss {
19 fn to_entity_builders(&mut self) -> Vec<EntityBuilder>;
20}
21impl McsCodecGloss for McsCodec {
23 #[allow(clippy::cast_precision_loss)]
24 fn to_entity_builders(&mut self) -> Vec<EntityBuilder> {
25 let mut builders: Vec<EntityBuilder> = Vec::new();
26 if let Some(camera_track) = &self.camera_track {
27 let mut camera_builder = EntityBuilder::new();
28 camera_builder.add(Name("TrackedCamera".to_string()));
29 camera_builder.add(camera_track.clone());
30 builders.push(camera_builder);
31 }
32 for smpl_body in self.smpl_bodies.iter() {
33 let start_offset = smpl_body.frame_presence[0];
34 let fps = smpl_body.codec.frame_rate.unwrap();
35 self.frame_rate = fps;
36 let mut builder = EntityBuilder::new();
37 let smpl_params = SmplParams::new_from_smpl_codec(&smpl_body.codec);
38 info!("Found smpl_params in the .smpl file");
39 builder.add(smpl_params);
40 if let Some(mut betas) = Betas::new_from_smpl_codec(&smpl_body.codec) {
41 info!("Found betas in the .smpl file");
42 let trimmed_betas = betas.betas.slice(s![..10]).to_owned();
43 betas.betas = trimmed_betas;
44 builder.add(betas);
45 }
46 if let Some(mut anim) = Animation::new_from_smpl_codec(&smpl_body.codec, AnimWrap::Clamp) {
47 anim.start_offset = start_offset;
48 builder.add(anim);
49 }
50 let pose_override = PoseOverride::allow_all();
51 builder.add(pose_override);
52 builder.add(GlossInterop { with_uv: true });
53 builders.push(builder);
54 }
55 builders
56 }
57}
58#[derive(Default)]
59pub struct SceneAnimation {
60 pub num_frames: usize,
61 pub runner: AnimationRunner,
62 pub config: AnimationConfig,
63}
64impl SceneAnimation {
65 pub fn new(num_frames: usize) -> Self {
66 Self {
67 num_frames,
68 runner: AnimationRunner::default(),
69 config: AnimationConfig::default(),
70 }
71 }
72 pub fn new_with_fps(num_frames: usize, fps: f32) -> Self {
73 Self {
74 num_frames,
75 runner: AnimationRunner::default(),
76 config: AnimationConfig { fps, ..Default::default() },
77 }
78 }
79 pub fn new_with_config(num_frames: usize, config: AnimationConfig) -> Self {
80 Self {
81 num_frames,
82 runner: AnimationRunner::default(),
83 config,
84 }
85 }
86 #[allow(clippy::cast_precision_loss)]
87 pub fn duration(&self) -> Duration {
88 Duration::from_secs_f32(self.num_frames as f32 / self.config.fps)
89 }
90 pub fn get_cur_time(&self) -> Duration {
91 self.runner.anim_current_time
92 }
93 pub fn set_cur_time_as_sec(&mut self, time_sec: f32) {
94 self.runner.anim_current_time = Duration::from_secs_f32(time_sec);
95 }
96 pub fn is_finished(&self) -> bool {
97 self.config.wrap_behaviour == AnimWrap::Clamp && self.runner.anim_current_time >= self.duration()
98 }
99 pub fn advance(&mut self, dt_raw: Duration, first_time: bool) {
102 let duration = self.duration();
103 let runner = &mut self.runner;
104 let config = &self.config;
105 let mut dt = dt_raw;
106 if first_time {
107 dt = Duration::ZERO;
108 }
109 let will_overflow = runner.anim_current_time + dt > duration;
110 let will_underflow = runner.anim_current_time < dt && runner.anim_reversed;
111 if will_overflow || will_underflow {
112 if will_overflow {
113 match config.wrap_behaviour {
114 AnimWrap::Clamp => {
115 dt = Duration::ZERO;
116 runner.anim_current_time = duration;
117 }
118 AnimWrap::Loop => {
119 dt = Duration::from_secs_f64(dt.as_secs_f64() % duration.as_secs_f64());
120 runner.anim_current_time = Duration::ZERO;
121 runner.nr_repetitions += 1;
122 }
123 AnimWrap::Reverse => {
124 dt = Duration::from_secs_f64(dt.as_secs_f64() % duration.as_secs_f64());
125 runner.anim_current_time = duration;
126 runner.anim_reversed = !runner.anim_reversed;
127 runner.nr_repetitions += 1;
128 }
129 }
130 } else {
131 match config.wrap_behaviour {
132 AnimWrap::Clamp => {
133 dt = Duration::ZERO;
134 runner.anim_current_time = Duration::ZERO;
135 }
136 AnimWrap::Loop => {
137 dt = Duration::from_secs_f64(dt.as_secs_f64() % duration.as_secs_f64());
138 runner.anim_current_time = duration;
139 runner.nr_repetitions += 1;
140 }
141 AnimWrap::Reverse => {
142 dt = Duration::from_secs_f64(dt.as_secs_f64() % duration.as_secs_f64());
143 runner.anim_reversed = !runner.anim_reversed;
144 runner.nr_repetitions += 1;
145 }
146 }
147 }
148 }
149 if runner.anim_reversed {
150 runner.anim_current_time = runner.anim_current_time.saturating_sub(dt);
151 } else {
152 runner.anim_current_time = runner.anim_current_time.saturating_add(dt);
153 }
154 }
155}