New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Animation of properties of LocalTransform #453

Merged
merged 2 commits into from Nov 1, 2017

Conversation

Projects
None yet
5 participants
@Rhuagh
Member

Rhuagh commented Oct 25, 2017

Opening early to get feedback. Note that this PR only contains animation of properties on LocalTransform, and have no skinning support. That will come in a later PR.

Work left:

  • Testing!!!
  • Documentation
  • Interpolation needs a rework
amethyst_animation/src/resources.rs
+}
+
+/// Defines a single animation.
+/// Defines relationships between the node index in `AnimationHierarchy` and a `Sampler` in

This comment has been minimized.

@Rhuagh

Rhuagh Oct 25, 2017

Member

Outdated docs.

@Rhuagh

Rhuagh Oct 25, 2017

Member

Outdated docs.

amethyst_animation/src/resources.rs
+ Done,
+}
+
+/// The actual animation data for a single attribute

This comment has been minimized.

@Rhuagh

Rhuagh Oct 25, 2017

Member

Outdated docs.

@Rhuagh

Rhuagh Oct 25, 2017

Member

Outdated docs.

amethyst_animation/src/resources.rs
+/// Attaches to an entity, to control what animations are currently active
+#[derive(Clone)]
+pub struct AnimationControl {
+ /// Animation index into `AnimationStorage`

This comment has been minimized.

@Rhuagh

Rhuagh Oct 25, 2017

Member

Outdated docs.

@Rhuagh

Rhuagh Oct 25, 2017

Member

Outdated docs.

@torkleyy

A few first comments^^

Cargo.toml
@@ -42,6 +42,7 @@ thread_profiler = { version = "0.1", optional = true }
[dev-dependencies]
cgmath = "0.14"
genmesh = "0.4"
+amethyst_animation = { path = "amethyst_animation", version = "0.1.0" }

This comment has been minimized.

@torkleyy

torkleyy Oct 25, 2017

Member

So you decided not to reexport this package? Should we maybe do the same for the gltf crate then, which also doesn't seem like a "mandatory" crate?

@torkleyy

torkleyy Oct 25, 2017

Member

So you decided not to reexport this package? Should we maybe do the same for the gltf crate then, which also doesn't seem like a "mandatory" crate?

This comment has been minimized.

@Rhuagh

Rhuagh Oct 25, 2017

Member

Yeah, we should.

@Rhuagh

Rhuagh Oct 25, 2017

Member

Yeah, we should.

amethyst_animation/Cargo.toml
+repository = "https://github.com/amethyst/amethyst"
+
+readme = "README.md"
+license = "MIT OR Apache-2.0"

This comment has been minimized.

@torkleyy

torkleyy Oct 25, 2017

Member

should be MIT/Apache-2.0

@torkleyy

torkleyy Oct 25, 2017

Member

should be MIT/Apache-2.0

amethyst_animation/src/bundle.rs
+ }
+}
+
+/// Bundle for a complete animation setup including sampler interpolation and animation control

This comment has been minimized.

@torkleyy

torkleyy Oct 25, 2017

Member

Should add comment that this automatically adds a SamplingBundle

@torkleyy

torkleyy Oct 25, 2017

Member

Should add comment that this automatically adds a SamplingBundle

amethyst_animation/src/interpolation.rs
+}
+
+pub trait Interpolate: Debug + Send + Sync {
+ fn interpolate_vec(

This comment has been minimized.

@torkleyy

torkleyy Oct 25, 2017

Member

Are you planning on replacing this?

@torkleyy

torkleyy Oct 25, 2017

Member

Are you planning on replacing this?

This comment has been minimized.

@Rhuagh

Rhuagh Oct 25, 2017

Member

Yes.

@Rhuagh

Rhuagh Oct 25, 2017

Member

Yes.

amethyst_animation/src/interpolation.rs
+ }
+}
+
+fn linear<D>(time_index: usize, time: f32, times: &Vec<f32>, values: &Vec<D>, normalize: bool) -> D

This comment has been minimized.

@torkleyy

torkleyy Oct 25, 2017

Member

Still gotta check these functions

@torkleyy

torkleyy Oct 25, 2017

Member

Still gotta check these functions

+
+
+fn do_control_set_pause(control_set: &mut SamplerControlSet) {
+ match control_set.translation {

This comment has been minimized.

@torkleyy

torkleyy Oct 25, 2017

Member

Same as above

@torkleyy

torkleyy Oct 25, 2017

Member

Same as above

+}
+
+fn do_control_set_unpause(now: &Instant, control_set: &mut SamplerControlSet) {
+ match control_set.translation {

This comment has been minimized.

@torkleyy

torkleyy Oct 25, 2017

Member

Same as above

@torkleyy

torkleyy Oct 25, 2017

Member

Same as above

+ fn run(&mut self, (samplers, mut controls, mut transforms): Self::SystemData) {
+ let now = Instant::now();
+ for (control_set, transform) in (&mut controls, &mut transforms).join() {
+ match control_set.translation {

This comment has been minimized.

@torkleyy

torkleyy Oct 25, 2017

Member

could be if let Some(sampler) = control_set.translation.as_mut().and_then(|c| samplers.get(c.sampler))

@torkleyy

torkleyy Oct 25, 2017

Member

could be if let Some(sampler) = control_set.translation.as_mut().and_then(|c| samplers.get(c.sampler))

+ do_sampling(&sampler, &duration, transform);
+ }
+ Done => do_end_control(&control, transform),
+ _ => (),

This comment has been minimized.

@torkleyy

torkleyy Oct 25, 2017

Member

The idiomatic version would be _ => {} I think

@torkleyy

torkleyy Oct 25, 2017

Member

The idiomatic version would be _ => {} I think

+ RestState::Scale(s) => transform.scale = s,
+ },
+ // looping is handled during duration update
+ _ => (),

This comment has been minimized.

@torkleyy

torkleyy Oct 25, 2017

Member

Same as above

@torkleyy

torkleyy Oct 25, 2017

Member

Same as above

@Rhuagh Rhuagh changed the title from [WIP] feat: Animation of properties of LocalTransform to feat: Animation of properties of LocalTransform Oct 26, 2017

@Rhuagh

This comment has been minimized.

Show comment
Hide comment
@Rhuagh

Rhuagh Oct 26, 2017

Member

After minterpolate has been released this will be ready. Need to get more testing done on that first though.

Member

Rhuagh commented Oct 26, 2017

After minterpolate has been released this will be ready. Need to get more testing done on that first though.

@Rhuagh

This comment has been minimized.

Show comment
Hide comment
@Rhuagh

Rhuagh Oct 27, 2017

Member

Ready for review.

Member

Rhuagh commented Oct 27, 2017

Ready for review.

+/// - `sampler_storage`: `AssetStorage` for all `Sampler`s
+/// - `samplers`: the active sampler sets
+/// - `transforms`: `LocalTransform`s, used to retrieve the rest pose before animation starts.
+/// - `remove`: all entities pushed here will have the control object removed at the end of the system execution

This comment has been minimized.

@torkleyy

torkleyy Oct 28, 2017

Member

If that's the case, could you use .drain() on the control storage?

Ah with "here" you mean pushed to the vector.

@torkleyy

torkleyy Oct 28, 2017

Member

If that's the case, could you use .drain() on the control storage?

Ah with "here" you mean pushed to the vector.

This comment has been minimized.

@torkleyy

torkleyy Oct 28, 2017

Member

Btw, I love how nicely documented this is 👍

@torkleyy

torkleyy Oct 28, 2017

Member

Btw, I love how nicely documented this is 👍

+ // and remove control object if all samplers are done and removed
+ (_, &AnimationCommand::Abort) | (&ControlState::Abort, _) | (&ControlState::Done, _) => {
+ if check_and_terminate_animation(hierarchy, samplers) {
+ remove.push(entity.clone());

This comment has been minimized.

@torkleyy

torkleyy Oct 28, 2017

Member

🤔 This looks like a conditional push, so maybe that doc comment above is inaccurate?

@torkleyy

torkleyy Oct 28, 2017

Member

🤔 This looks like a conditional push, so maybe that doc comment above is inaccurate?

amethyst_animation/src/util.rs
+ None => false,
+ } {
+ controls.insert(
+ entity.clone(),

This comment has been minimized.

@torkleyy

torkleyy Oct 28, 2017

Member

Entities are Copy, no need to clone()

@torkleyy

torkleyy Oct 28, 2017

Member

Entities are Copy, no need to clone()

amethyst_animation/src/util.rs
+ entity: &Entity,
+) {
+ if let Some(ref mut control) = controls.get_mut(*entity) {
+ if let ControlState::Running(..) = control.state {

This comment has been minimized.

@torkleyy

torkleyy Oct 28, 2017

Member

Maybe it would be convenient to have is_running and is_paused as methods?

@torkleyy

torkleyy Oct 28, 2017

Member

Maybe it would be convenient to have is_running and is_paused as methods?

amethyst_animation/src/util.rs
+pub fn toggle_animation(
+ controls: &mut WriteStorage<AnimationControl>,
+ animation: &Handle<Animation>,
+ entity: &Entity,

This comment has been minimized.

@torkleyy

torkleyy Oct 28, 2017

Member

And since they're Copy, you don't need a reference.

@torkleyy

torkleyy Oct 28, 2017

Member

And since they're Copy, you don't need a reference.

amethyst_animation/src/util.rs
+ }) => true,
+ _ => false,
+ };
+ if running {

This comment has been minimized.

@torkleyy

torkleyy Oct 28, 2017

Member

If you add those methods above, this could be

if controls.get(entity).map(|c| c.state.is_running()).unwrap_or(false) {}
@torkleyy

torkleyy Oct 28, 2017

Member

If you add those methods above, this could be

if controls.get(entity).map(|c| c.state.is_running()).unwrap_or(false) {}
@torkleyy

Thanks for addressing, got a couple of nits but otherwise it's great

amethyst_animation/src/resources.rs
@@ -54,6 +55,7 @@ impl Component for AnimationHierarchy {
/// Defines a single animation.
/// Defines relationships between the node index in `AnimationHierarchy` and a `Sampler` handle.
+/// If the animation only target a single node index, `AnimationHierarchy` is not required.

This comment has been minimized.

@torkleyy

torkleyy Oct 28, 2017

Member

should be "targets" I think

@torkleyy

torkleyy Oct 28, 2017

Member

should be "targets" I think

@@ -11,7 +11,8 @@ use resources::{Animation, AnimationCommand, AnimationControl, AnimationHierarch
/// System for setting up animations, should run before `SamplerInterpolationSystem`.
///
/// Will process all active `AnimationControl` + `AnimationHierarchy`, and do processing of the
-/// animations they describe.
+/// animations they describe. If an animation only target a single node/entity, there is no need for

This comment has been minimized.

@torkleyy

torkleyy Oct 28, 2017

Member

Same here

@torkleyy

torkleyy Oct 28, 2017

Member

Same here

+/// Check if the given animation list is for a single node. If so, we don't need an
+/// `AnimationHierarchy`.
+fn only_one_index(nodes: &Vec<(usize, Handle<Sampler>)>) -> bool {
+ if nodes.len() == 0 {

This comment has been minimized.

@torkleyy

torkleyy Oct 28, 2017

Member

nit: should be nodes.is_empty()

@torkleyy

torkleyy Oct 28, 2017

Member

nit: should be nodes.is_empty()

@@ -70,14 +71,36 @@ impl<'a> System<'a> for AnimationControlSystem {
}
}
+/// Check if the given animation list is for a single node. If so, we don't need an
+/// `AnimationHierarchy`.
+fn only_one_index(nodes: &Vec<(usize, Handle<Sampler>)>) -> bool {

This comment has been minimized.

@torkleyy

torkleyy Oct 28, 2017

Member

Can take slice here

@torkleyy

torkleyy Oct 28, 2017

Member

Can take slice here

@Rhuagh

This comment has been minimized.

Show comment
Hide comment
@Rhuagh

Rhuagh Oct 28, 2017

Member

I'll squash after approvals are in place.

Member

Rhuagh commented Oct 28, 2017

I'll squash after approvals are in place.

@Rhuagh

This comment has been minimized.

Show comment
Hide comment
Member

Rhuagh commented Oct 28, 2017

@torkleyy torkleyy requested a review from amethyst/engine-devs Oct 29, 2017

@omni-viral

I like it. We really need good animation system.
I have a few questions.
Does this system supports

  • blending of animations
  • control animation speed
  • animations stacking
    ?
+#[derive(Clone, Debug)]
+pub struct Animation {
+ /// node index -> sampler handle
+ pub nodes: Vec<(usize, Handle<Sampler>)>,

This comment has been minimized.

@omni-viral

omni-viral Oct 29, 2017

Member

Here should be Entity instead of usize.
Mappings such as in AnimationHierarchy should be covered by specs saveload feature.
But we need to develop PrefabMarker first.

@omni-viral

omni-viral Oct 29, 2017

Member

Here should be Entity instead of usize.
Mappings such as in AnimationHierarchy should be covered by specs saveload feature.
But we need to develop PrefabMarker first.

This comment has been minimized.

@Rhuagh

Rhuagh Oct 29, 2017

Member

No, because you can play animation on many different entities when you use prefabs.

@Rhuagh

Rhuagh Oct 29, 2017

Member

No, because you can play animation on many different entities when you use prefabs.

This comment has been minimized.

@Rhuagh

Rhuagh Oct 29, 2017

Member

You want to be able to share animations between many families of entities.

@Rhuagh

Rhuagh Oct 29, 2017

Member

You want to be able to share animations between many families of entities.

This comment has been minimized.

@omni-viral

omni-viral Oct 29, 2017

Member

Can you describe use case? Which can't be done with attaching other entities to entities of prefab.

@omni-viral

omni-viral Oct 29, 2017

Member

Can you describe use case? Which can't be done with attaching other entities to entities of prefab.

This comment has been minimized.

@Rhuagh

Rhuagh Oct 29, 2017

Member

A quite common scenario for indie game development is that you have a single bone structure for many different units (think human, vulkan, klingon etc), and all units that share bone structure can share animations. This saves on time and cost of developing the game, because you don't have to produce as many animations.

So, animations are loaded once and then potentially shared between many different types of units/entities whatever.

The second issue with the suggestion you have is one of forward lookup. Given an animation and entity to play that animation on, how do i find which child entities to add samplers to ? If the only link we have is that the child entities have a reference to the entity of the prefab they were created from, you would have to look through the entire Parent (or some other component) storage to find the entitites that should be animated, which would be far to expensive imho. The other solution would be to have the AnimationHierarchy contain Entity -> Entity mappings. I went with the "node index -> Entity" solution, because it makes animation asset loading much, much easier.

@Rhuagh

Rhuagh Oct 29, 2017

Member

A quite common scenario for indie game development is that you have a single bone structure for many different units (think human, vulkan, klingon etc), and all units that share bone structure can share animations. This saves on time and cost of developing the game, because you don't have to produce as many animations.

So, animations are loaded once and then potentially shared between many different types of units/entities whatever.

The second issue with the suggestion you have is one of forward lookup. Given an animation and entity to play that animation on, how do i find which child entities to add samplers to ? If the only link we have is that the child entities have a reference to the entity of the prefab they were created from, you would have to look through the entire Parent (or some other component) storage to find the entitites that should be animated, which would be far to expensive imho. The other solution would be to have the AnimationHierarchy contain Entity -> Entity mappings. I went with the "node index -> Entity" solution, because it makes animation asset loading much, much easier.

This comment has been minimized.

@Rhuagh

Rhuagh Oct 29, 2017

Member

Animations can also target only a part of a hierarchy, not necessarily the entire hierarchy. Example: Sword swing will probably only affect arms and upper torso.

And it would force anyone that wants to do animation on something to go via the prefab system, which might be unwanted. Note that this animation system has wider support than just skeletal animation, it can do animation of any LocalTransform, as long as the Animation can target it via AnimationHierarchy.

@Rhuagh

Rhuagh Oct 29, 2017

Member

Animations can also target only a part of a hierarchy, not necessarily the entire hierarchy. Example: Sword swing will probably only affect arms and upper torso.

And it would force anyone that wants to do animation on something to go via the prefab system, which might be unwanted. Note that this animation system has wider support than just skeletal animation, it can do animation of any LocalTransform, as long as the Animation can target it via AnimationHierarchy.

This comment has been minimized.

@Rhuagh

Rhuagh Oct 29, 2017

Member

Regardless, this is not something that can be done within the scope of this PR, because it needs prefab loading first.

@Rhuagh

Rhuagh Oct 29, 2017

Member

Regardless, this is not something that can be done within the scope of this PR, because it needs prefab loading first.

This comment has been minimized.

@omni-viral

omni-viral Oct 30, 2017

Member

Example: Sword swing will probably only affect arms and upper torso.

But this system animate LocalTransform of entities. Will it share some parts with skeletal animation system?

@omni-viral

omni-viral Oct 30, 2017

Member

Example: Sword swing will probably only affect arms and upper torso.

But this system animate LocalTransform of entities. Will it share some parts with skeletal animation system?

This comment has been minimized.

@Rhuagh

Rhuagh Oct 30, 2017

Member

Skeletal animation is this system together with vertex skinning.

@Rhuagh

Rhuagh Oct 30, 2017

Member

Skeletal animation is this system together with vertex skinning.

+/// Sampler control set, containing optional samplers for each of the possible channels.
+///
+/// Note that the `AnimationOutput` in the `Sampler` referenced, and the `RestState` referenced in
+/// each `SamplerControl` should match the attribute channel from the set here. There is no check

This comment has been minimized.

@omni-viral

omni-viral Oct 29, 2017

Member

Shouldn't be SamplerControl parametrised in this case?

@omni-viral

omni-viral Oct 29, 2017

Member

Shouldn't be SamplerControl parametrised in this case?

This comment has been minimized.

@Rhuagh

Rhuagh Oct 29, 2017

Member

This is in part due to how it looked at the start. I did consider changing this note, but came to the conclusion I wanted to get something out first. I will deal with this in a later PR.

@Rhuagh

Rhuagh Oct 29, 2017

Member

This is in part due to how it looked at the start. I did consider changing this note, but came to the conclusion I wanted to get something out first. I will deal with this in a later PR.

+ let mut remove = Vec::default();
+ for (entity, control) in (&*entities, &mut controls).join() {
+ if let Some(state) = animation_storage.get(&control.animation).and_then(
+ |ref animation| {

This comment has been minimized.

@omni-viral

omni-viral Oct 29, 2017

Member

What the point of ref keyword here?

@omni-viral

omni-viral Oct 29, 2017

Member

What the point of ref keyword here?

This comment has been minimized.

@Rhuagh

Rhuagh Oct 29, 2017

Member

Remnant of old code

@Rhuagh

Rhuagh Oct 29, 2017

Member

Remnant of old code

+ match times {
+ // finite amount of looping, if 0 go do done,
+ // else reduce iteration count and keep sampling
+ Some(i) => if i <= 1 {

This comment has been minimized.

@omni-viral

omni-viral Oct 29, 2017

Member

Use guards to avoid too many nesting levels

@omni-viral

omni-viral Oct 29, 2017

Member

Use guards to avoid too many nesting levels

This comment has been minimized.

@Rhuagh

Rhuagh Oct 29, 2017

Member

Guards?

@Rhuagh

Rhuagh Oct 29, 2017

Member

Guards?

@Rhuagh

This comment has been minimized.

Show comment
Hide comment
@Rhuagh

Rhuagh Oct 29, 2017

Member

This is a first version, so no blending, speed cobtrol or stacking no.

Member

Rhuagh commented Oct 29, 2017

This is a first version, so no blending, speed cobtrol or stacking no.

@omni-viral

This comment has been minimized.

Show comment
Hide comment
@omni-viral

omni-viral Oct 29, 2017

Member

@Rhuagh ok. But you need to keep those features in mind so that adding them won't require total rewrite.

Member

omni-viral commented Oct 29, 2017

@Rhuagh ok. But you need to keep those features in mind so that adding them won't require total rewrite.

@Rhuagh

This comment has been minimized.

Show comment
Hide comment
@Rhuagh

Rhuagh Oct 29, 2017

Member

For the most part it will go something like this:

Speed control: additional parameter on AnimationCommand, and on SamplerControl.
Animation blending: SamplerControlSet gets a weight parameter, and it becomes Many<SamplerControlSet> as Component, Many<AnimationControl> as Component. Needs support in both systems.
Animation stacking: Basically the same as blending with the addition AnimationControl gets a control type parameter to differentiate between blend and stacking, and animation control system needs support for determining what to do at animation end.

Member

Rhuagh commented Oct 29, 2017

For the most part it will go something like this:

Speed control: additional parameter on AnimationCommand, and on SamplerControl.
Animation blending: SamplerControlSet gets a weight parameter, and it becomes Many<SamplerControlSet> as Component, Many<AnimationControl> as Component. Needs support in both systems.
Animation stacking: Basically the same as blending with the addition AnimationControl gets a control type parameter to differentiate between blend and stacking, and animation control system needs support for determining what to do at animation end.

@Rhuagh

This comment has been minimized.

Show comment
Hide comment
@Rhuagh

Rhuagh Oct 29, 2017

Member

@omni-viral review addressed and issues fixed, please review again.

Member

Rhuagh commented Oct 29, 2017

@omni-viral review addressed and issues fixed, please review again.

@omni-viral

omni-viral requested changes Oct 30, 2017 edited

A few more questions and suggestions.

+ );
+
+ fn run(&mut self, (samplers, mut controls, mut transforms): Self::SystemData) {
+ let now = Instant::now();

This comment has been minimized.

@omni-viral

omni-viral Oct 30, 2017

Member

I believe that all systems should use central timer from amethyst_core

@omni-viral

omni-viral Oct 30, 2017

Member

I believe that all systems should use central timer from amethyst_core

+ type HandleStorage = DenseVecStorage<Handle<Self>>;
+}
+
+impl Into<Result<Animation>> for Animation {

This comment has been minimized.

@omni-viral

omni-viral Oct 30, 2017

Member

What for? Can't you use Ok function where you need to convert?

@omni-viral

omni-viral Oct 30, 2017

Member

What for? Can't you use Ok function where you need to convert?

This comment has been minimized.

@Rhuagh

Rhuagh Oct 30, 2017

Member

For asset processor.

@Rhuagh

Rhuagh Oct 30, 2017

Member

For asset processor.

This comment has been minimized.

@omni-viral

omni-viral Oct 30, 2017

Member

You've answered only first question.

@omni-viral

omni-viral Oct 30, 2017

Member

You've answered only first question.

This comment has been minimized.

@Rhuagh

Rhuagh Oct 30, 2017

Member

I'm using the Processor from the assets crate to do asset processing for Sampler and Animation, and it has Asset::Data = Animation (it converts into itself since it doesn't need a factory to convert or such), and that requires an impl Into<assets::Result<Asset>> for Asset::Data

@Rhuagh

Rhuagh Oct 30, 2017

Member

I'm using the Processor from the assets crate to do asset processing for Sampler and Animation, and it has Asset::Data = Animation (it converts into itself since it doesn't need a factory to convert or such), and that requires an impl Into<assets::Result<Asset>> for Asset::Data

This comment has been minimized.

@Rhuagh

Rhuagh Oct 30, 2017

Member

Yes, I could do manual processing of them in my own system, just felt silly to build a new system for something that already exists.

@Rhuagh

Rhuagh Oct 30, 2017

Member

Yes, I could do manual processing of them in my own system, just felt silly to build a new system for something that already exists.

+ }
+}
+
+fn next_duration(last_frame: f32, mut dur_s: f32) -> Duration {

This comment has been minimized.

@omni-viral

omni-viral Oct 30, 2017

Member

It should return number of loops eaten by loop. This number should be subtracted from number of loops here

@omni-viral

omni-viral Oct 30, 2017

Member

It should return number of loops eaten by loop. This number should be subtracted from number of loops here

+ ),
+ EndControl::Loop(Some(i)) => (
+ Running(now.clone(), next_duration(last_frame, duration_secs)),
+ Some(EndControl::Loop(Some(i - 1))),

This comment has been minimized.

@omni-viral

omni-viral Oct 30, 2017

Member

You should subtract number equal to time_elapsed / animation_duration and put time_elapsed % animation_duration into Running(_, >here<)

@omni-viral

omni-viral Oct 30, 2017

Member

You should subtract number equal to time_elapsed / animation_duration and put time_elapsed % animation_duration into Running(_, >here<)

This comment has been minimized.

@Rhuagh

Rhuagh Oct 30, 2017

Member

isn't modulo on floats kind of frowned upon?

@Rhuagh

Rhuagh Oct 30, 2017

Member

isn't modulo on floats kind of frowned upon?

+
+fn next_duration(last_frame: f32, mut dur_s: f32) -> Duration {
+ while last_frame != 0. && dur_s > last_frame {
+ dur_s -= last_frame;

This comment has been minimized.

@omni-viral

omni-viral Oct 30, 2017

Member

Division should work faster then loop.
And you probably want to work with milliseconds in u32 (or nanoseconds in u64) instead of seconds in f32.

@omni-viral

omni-viral Oct 30, 2017

Member

Division should work faster then loop.
And you probably want to work with milliseconds in u32 (or nanoseconds in u64) instead of seconds in f32.

+ },
+ ))
+ }
+ Weights => Err(GltfError::NotImplemented),

This comment has been minimized.

@omni-viral

omni-viral Oct 30, 2017

Member

What are those? Skinning weights?

@omni-viral

omni-viral Oct 30, 2017

Member

What are those? Skinning weights?

This comment has been minimized.

@Rhuagh

Rhuagh Oct 30, 2017

Member

Morph target weights.

@Rhuagh

Rhuagh Oct 30, 2017

Member

Morph target weights.

amethyst_animation/src/util.rs
+) {
+ if !match controls.get_mut(entity) {
+ Some(ref mut control) => {
+ if control.state.is_paused() {

This comment has been minimized.

@omni-viral

omni-viral Oct 30, 2017

Member

If pause was requested then it will be paused on next system run.
Command should be set to Start unconditionally.

@omni-viral

omni-viral Oct 30, 2017

Member

If pause was requested then it will be paused on next system run.
Command should be set to Start unconditionally.

amethyst_animation/src/util.rs
+ end: EndControl,
+) {
+ if !match controls.get_mut(entity) {
+ Some(ref mut control) => {

This comment has been minimized.

@omni-viral

omni-viral Oct 30, 2017

Member

Should check if it is the same animation.

@omni-viral

omni-viral Oct 30, 2017

Member

Should check if it is the same animation.

amethyst_animation/src/util.rs
+ entity: Entity,
+ end: EndControl,
+) {
+ if !match controls.get_mut(entity) {

This comment has been minimized.

@omni-viral

omni-viral Oct 30, 2017

Member

if !match is poorly readable.
Use single match block with guards or if let Some if appropriate.

@omni-viral

omni-viral Oct 30, 2017

Member

if !match is poorly readable.
Use single match block with guards or if let Some if appropriate.

This comment has been minimized.

@Rhuagh

Rhuagh Oct 30, 2017

Member

The problem is borrowing rules. I'd have to break it up into two if let ..

@Rhuagh

Rhuagh Oct 30, 2017

Member

The problem is borrowing rules. I'd have to break it up into two if let ..

amethyst_animation/src/util.rs
+ .map(|c| c.state.is_running())
+ .unwrap_or(false)
+ {
+ pause_animation(controls, entity);

This comment has been minimized.

@omni-viral

omni-viral Oct 30, 2017

Member

What if another animation is running?

@omni-viral

omni-viral Oct 30, 2017

Member

What if another animation is running?

This comment has been minimized.

@Rhuagh

Rhuagh Oct 30, 2017

Member

Since we only support a single animation atm, it felt like an unnecessary check for now.

@Rhuagh

Rhuagh Oct 30, 2017

Member

Since we only support a single animation atm, it felt like an unnecessary check for now.

@Xaeroxe

Due to my inexperience with 3D animation it's really hard for me to say whether this is adequate or not, however I don't see anything here that particularly upsets me so I'll give this an approval with the disclaimer that I don't know a ton about what I'm reading here.

@Rhuagh

This comment has been minimized.

Show comment
Hide comment
@Rhuagh

Rhuagh Oct 30, 2017

Member

@omni-viral review comments addressed, please review again.

Member

Rhuagh commented Oct 30, 2017

@omni-viral review comments addressed, please review again.

@torkleyy

This comment has been minimized.

Show comment
Hide comment
@torkleyy

torkleyy Nov 1, 2017

Member

Some more reviews on this would be really appreciated. I'll try to do another in-depth review on this, but one or two more wouldn't hurt.

Member

torkleyy commented Nov 1, 2017

Some more reviews on this would be really appreciated. I'll try to do another in-depth review on this, but one or two more wouldn't hurt.

@Xaeroxe

This comment has been minimized.

Show comment
Hide comment
@Xaeroxe

Xaeroxe Nov 1, 2017

Member

bors r+

Member

Xaeroxe commented Nov 1, 2017

bors r+

bors bot added a commit that referenced this pull request Nov 1, 2017

Merge #453
453: feat: Animation of properties of LocalTransform r=Xaeroxe a=Rhuagh

Opening early to get feedback. Note that this PR only contains animation of properties on LocalTransform, and have no skinning support. That will come in a later PR.

Work left:

* ~Testing!!!~
* ~Documentation~
* ~Interpolation needs a rework~
@bors

This comment has been minimized.

Show comment
Hide comment

@bors bors bot merged commit a41d4fa into amethyst:develop Nov 1, 2017

2 of 3 checks passed

continuous-integration/appveyor/pr AppVeyor build failed
Details
bors Build succeeded
continuous-integration/travis-ci/pr The Travis CI build passed
Details

@Rhuagh Rhuagh deleted the Rhuagh:animation branch Nov 1, 2017

@Aceeri Aceeri added this to the 0.6.0 milestone Nov 28, 2017

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment