Skip to content
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

Refactor animations #795

Merged
merged 6 commits into from
Sep 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
429 changes: 420 additions & 9 deletions Cargo.lock

Large diffs are not rendered by default.

55 changes: 31 additions & 24 deletions crates/animation/src/player.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,17 @@ use ambient_ecs::{
children, components,
generated::animation::components::{
animation_errors, apply_animation_player, apply_base_pose, bind_ids, blend, clip_duration,
freeze_at_percentage, freeze_at_time, is_animation_player, looping, mask_bind_ids,
mask_weights, play_clip_from_url, retarget_animation_scaled, retarget_model_from_url,
speed, start_time,
clip_loaded, freeze_at_percentage, freeze_at_time, is_animation_player, looping,
mask_bind_ids, mask_weights, play_clip_from_url, retarget_animation_scaled,
retarget_model_from_url, speed, start_time,
},
query, ComponentDesc, Debuggable, EntityId, SystemGroup, World,
};
use ambient_model::{animation_binder, ModelFromUrl};
use ambient_native_std::{
asset_cache::{AssetCache, AsyncAssetKeyExt},
asset_url::{AnimationAssetType, TypedAssetUrl},
download_asset::AssetResult,
};
use anyhow::Context;
use glam::{Quat, Vec3};
Expand Down Expand Up @@ -202,6 +203,7 @@ pub fn animation_player_systems() -> SystemGroup {
query(play_clip_from_url().changed()).to_system(|q, world, qs, _| {
let runtime = world.resource(runtime()).clone();
for (id, url) in q.collect_cloned(world, qs) {
world.remove_component(id, clip_loaded()).ok();
let async_run = world.resource(async_run()).clone();
let assets = world.resource(asset_cache()).clone();
let url = match TypedAssetUrl::<AnimationAssetType>::from_str(&url) {
Expand All @@ -226,35 +228,40 @@ pub fn animation_player_systems() -> SystemGroup {
} else {
AnimationRetargeting::None
};
runtime.spawn(async move {
let clip = AnimationClipRetargetedFromModel {
clip: url,
translation_retargeting: retargeting,
retarget_model,
}
.get(&assets)
.await;
let duration = clip.as_ref().map(|clip| clip.duration()).unwrap_or(0.);
let binders = clip
.as_ref()
.map(|clip| {
clip.tracks
let clip_ref = AnimationClipRetargetedFromModel {
clip: url,
translation_retargeting: retargeting,
retarget_model,
};
let apply_clip =
move |world: &mut World, clip: AssetResult<Arc<AnimationClip>>| {
if let Ok(clip) = clip {
world
.add_component(id, clip_duration(), clip.duration())
.ok();
let binders = clip
.tracks
.iter()
.filter_map(|x| match &x.target {
AnimationTarget::BinderId(binder) => Some(binder.clone()),
AnimationTarget::Entity(_entity) => None,
})
.collect::<Vec<_>>()
})
.unwrap_or_default();
async_run.run(move |world| {
world.add_component(id, clip_duration(), duration).ok();
world.add_component(id, bind_ids(), binders).ok();
if let Ok(clip) = clip {
.collect::<Vec<_>>();
world.add_component(id, bind_ids(), binders).ok();
world.add_component(id, play_clip(), clip).ok();
}
world.add_component(id, clip_loaded(), ()).ok();
};
if let Some(clip) = clip_ref.peek(&assets) {
apply_clip(world, clip);
} else {
runtime.spawn(async move {
let clip = clip_ref.get(&assets).await;
async_run.run(move |world| {
apply_clip(world, clip);
});
});
});
}
}
}),
query(play_clip_from_url().changed())
Expand Down
2 changes: 1 addition & 1 deletion crates/ecs/src/generated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ mod raw {
};
use glam::{Mat4, Quat, UVec2, UVec3, UVec4, Vec2, Vec3, Vec4};
use std::time::Duration;
components ! ("animation" , { # [doc = "**Is animation player**: This entity is treated as an animation player. Attach an animation node as a child for it to play.\n\n*Attributes*: MaybeResource, Debuggable, Networked"] @ [MaybeResource , Debuggable , Networked , Name ["Is animation player"] , Description ["This entity is treated as an animation player. Attach an animation node as a child for it to play."]] is_animation_player : () , # [doc = "**Animation errors**: A list of errors that were produced trying to play the animation.\n\n*Attributes*: MaybeResource, Debuggable"] @ [MaybeResource , Debuggable , Name ["Animation errors"] , Description ["A list of errors that were produced trying to play the animation."]] animation_errors : Vec :: < String > , # [doc = "**Apply animation player**: Apply the designated animation player to this entity and its sub-tree.\n\n*Attributes*: MaybeResource, Debuggable, Networked"] @ [MaybeResource , Debuggable , Networked , Name ["Apply animation player"] , Description ["Apply the designated animation player to this entity and its sub-tree."]] apply_animation_player : EntityId , # [doc = "**Play clip from URL**: Make this entity a 'play animation clip' node. The value is the URL to the clip we'd like to play.\n\n*Attributes*: MaybeResource, Debuggable, Networked"] @ [MaybeResource , Debuggable , Networked , Name ["Play clip from URL"] , Description ["Make this entity a 'play animation clip' node. The value is the URL to the clip we'd like to play."]] play_clip_from_url : String , # [doc = "**Looping**: When this is true, the animation clip will repeat infinitely.\n\n*Attributes*: MaybeResource, Debuggable, Networked"] @ [MaybeResource , Debuggable , Networked , Name ["Looping"] , Description ["When this is true, the animation clip will repeat infinitely."]] looping : bool , # [doc = "**Speed**: Animation playback speed. Default is 1, higher values speeds up the animation.\n\n*Attributes*: MaybeResource, Debuggable, Networked"] @ [MaybeResource , Debuggable , Networked , Name ["Speed"] , Description ["Animation playback speed. Default is 1, higher values speeds up the animation."]] speed : f32 , # [doc = "**Start time**: Start time of an animation node.\n\n*Attributes*: MaybeResource, Debuggable, Networked"] @ [MaybeResource , Debuggable , Networked , Name ["Start time"] , Description ["Start time of an animation node."]] start_time : Duration , # [doc = "**Freeze at percentage**: Sample the input animation at a certain percentage of the animation track length.\n\n*Attributes*: MaybeResource, Debuggable, Networked"] @ [MaybeResource , Debuggable , Networked , Name ["Freeze at percentage"] , Description ["Sample the input animation at a certain percentage of the animation track length."]] freeze_at_percentage : f32 , # [doc = "**Freeze at time**: Sample the input animation at a certain time (in seconds).\n\n*Attributes*: MaybeResource, Debuggable, Networked"] @ [MaybeResource , Debuggable , Networked , Name ["Freeze at time"] , Description ["Sample the input animation at a certain time (in seconds)."]] freeze_at_time : f32 , # [doc = "**Clip duration**: The clip duration is loaded from the clip, and then applied to the entity.\n\n*Attributes*: MaybeResource, Debuggable"] @ [MaybeResource , Debuggable , Name ["Clip duration"] , Description ["The clip duration is loaded from the clip, and then applied to the entity."]] clip_duration : f32 , # [doc = "**Blend**: Blend two animations together. The values is the blend weight. Use `children` to set the animations. Blend 0 means we only sample from the first animation, 1 means only the second one, and values in between blend between them.\n\n*Attributes*: MaybeResource, Debuggable, Networked"] @ [MaybeResource , Debuggable , Networked , Name ["Blend"] , Description ["Blend two animations together. The values is the blend weight. Use `children` to set the animations. Blend 0 means we only sample from the first animation, 1 means only the second one, and values in between blend between them."]] blend : f32 , # [doc = "**Mask bind ids**: List of bind ids that will be masked.\n\n*Attributes*: MaybeResource, Debuggable, Networked"] @ [MaybeResource , Debuggable , Networked , Name ["Mask bind ids"] , Description ["List of bind ids that will be masked."]] mask_bind_ids : Vec :: < String > , # [doc = "**Mask weights**: Weights for each bind id in `mask_bind_ids`.\n\n*Attributes*: MaybeResource, Debuggable, Networked"] @ [MaybeResource , Debuggable , Networked , Name ["Mask weights"] , Description ["Weights for each bind id in `mask_bind_ids`."]] mask_weights : Vec :: < f32 > , # [doc = "**Retarget Model from URL**: Retarget the animation using the model at the given URL.\n\n*Attributes*: Debuggable, Networked, Store"] @ [Debuggable , Networked , Store , Name ["Retarget Model from URL"] , Description ["Retarget the animation using the model at the given URL."]] retarget_model_from_url : String , # [doc = "**Retarget animation scaled**: Retarget animation scaled. True means normalize hip.\n\n*Attributes*: Debuggable, Networked, Store"] @ [Debuggable , Networked , Store , Name ["Retarget animation scaled"] , Description ["Retarget animation scaled. True means normalize hip."]] retarget_animation_scaled : bool , # [doc = "**Apply base pose**: Apply the base pose to this clip.\n\n*Attributes*: Debuggable, Networked, Store"] @ [Debuggable , Networked , Store , Name ["Apply base pose"] , Description ["Apply the base pose to this clip."]] apply_base_pose : () , # [doc = "**Bind id**: Animation bind ID.\n\n*Attributes*: Debuggable, Networked, Store"] @ [Debuggable , Networked , Store , Name ["Bind id"] , Description ["Animation bind ID."]] bind_id : String , # [doc = "**Bind ids**: Animation bind IDs.\n\n*Attributes*: Debuggable, Store"] @ [Debuggable , Store , Name ["Bind ids"] , Description ["Animation bind IDs."]] bind_ids : Vec :: < String > , });
components ! ("animation" , { # [doc = "**Is animation player**: This entity is treated as an animation player. Attach an animation node as a child for it to play.\n\n*Attributes*: Debuggable, Networked"] @ [Debuggable , Networked , Name ["Is animation player"] , Description ["This entity is treated as an animation player. Attach an animation node as a child for it to play."]] is_animation_player : () , # [doc = "**Animation errors**: A list of errors that were produced trying to play the animation.\n\n*Attributes*: Debuggable"] @ [Debuggable , Name ["Animation errors"] , Description ["A list of errors that were produced trying to play the animation."]] animation_errors : Vec :: < String > , # [doc = "**Apply animation player**: Apply the designated animation player to this entity and its sub-tree.\n\n*Attributes*: Debuggable, Networked"] @ [Debuggable , Networked , Name ["Apply animation player"] , Description ["Apply the designated animation player to this entity and its sub-tree."]] apply_animation_player : EntityId , # [doc = "**Play clip from URL**: Make this entity a 'play animation clip' node. The value is the URL to the clip we'd like to play.\n\n*Attributes*: Debuggable, Networked"] @ [Debuggable , Networked , Name ["Play clip from URL"] , Description ["Make this entity a 'play animation clip' node. The value is the URL to the clip we'd like to play."]] play_clip_from_url : String , # [doc = "**Looping**: When this is true, the animation clip will repeat infinitely.\n\n*Attributes*: Debuggable, Networked"] @ [Debuggable , Networked , Name ["Looping"] , Description ["When this is true, the animation clip will repeat infinitely."]] looping : bool , # [doc = "**Speed**: Animation playback speed. Default is 1, higher values speeds up the animation.\n\n*Attributes*: Debuggable, Networked"] @ [Debuggable , Networked , Name ["Speed"] , Description ["Animation playback speed. Default is 1, higher values speeds up the animation."]] speed : f32 , # [doc = "**Start time**: Start time of an animation node.\n\n*Attributes*: Debuggable, Networked"] @ [Debuggable , Networked , Name ["Start time"] , Description ["Start time of an animation node."]] start_time : Duration , # [doc = "**Freeze at percentage**: Sample the input animation at a certain percentage of the animation track length.\n\n*Attributes*: Debuggable, Networked"] @ [Debuggable , Networked , Name ["Freeze at percentage"] , Description ["Sample the input animation at a certain percentage of the animation track length."]] freeze_at_percentage : f32 , # [doc = "**Freeze at time**: Sample the input animation at a certain time (in seconds).\n\n*Attributes*: Debuggable, Networked"] @ [Debuggable , Networked , Name ["Freeze at time"] , Description ["Sample the input animation at a certain time (in seconds)."]] freeze_at_time : f32 , # [doc = "**Clip duration**: The clip duration is loaded from the clip, and then applied to the entity.\n\n*Attributes*: Debuggable"] @ [Debuggable , Name ["Clip duration"] , Description ["The clip duration is loaded from the clip, and then applied to the entity."]] clip_duration : f32 , # [doc = "**Clip loaded**: The clip has been loaded.\n\n*Attributes*: Debuggable"] @ [Debuggable , Name ["Clip loaded"] , Description ["The clip has been loaded."]] clip_loaded : () , # [doc = "**Blend**: Blend two animations together. The values is the blend weight. Use `children` to set the animations. Blend 0 means we only sample from the first animation, 1 means only the second one, and values in between blend between them.\n\n*Attributes*: Debuggable, Networked"] @ [Debuggable , Networked , Name ["Blend"] , Description ["Blend two animations together. The values is the blend weight. Use `children` to set the animations. Blend 0 means we only sample from the first animation, 1 means only the second one, and values in between blend between them."]] blend : f32 , # [doc = "**Mask bind ids**: List of bind ids that will be masked.\n\n*Attributes*: Debuggable, Networked"] @ [Debuggable , Networked , Name ["Mask bind ids"] , Description ["List of bind ids that will be masked."]] mask_bind_ids : Vec :: < String > , # [doc = "**Mask weights**: Weights for each bind id in `mask_bind_ids`.\n\n*Attributes*: Debuggable, Networked"] @ [Debuggable , Networked , Name ["Mask weights"] , Description ["Weights for each bind id in `mask_bind_ids`."]] mask_weights : Vec :: < f32 > , # [doc = "**Retarget Model from URL**: Retarget the animation using the model at the given URL.\n\n*Attributes*: Debuggable, Networked, Store"] @ [Debuggable , Networked , Store , Name ["Retarget Model from URL"] , Description ["Retarget the animation using the model at the given URL."]] retarget_model_from_url : String , # [doc = "**Retarget animation scaled**: Retarget animation scaled. True means normalize hip.\n\n*Attributes*: Debuggable, Networked, Store"] @ [Debuggable , Networked , Store , Name ["Retarget animation scaled"] , Description ["Retarget animation scaled. True means normalize hip."]] retarget_animation_scaled : bool , # [doc = "**Apply base pose**: Apply the base pose to this clip.\n\n*Attributes*: Debuggable, Networked, Store"] @ [Debuggable , Networked , Store , Name ["Apply base pose"] , Description ["Apply the base pose to this clip."]] apply_base_pose : () , # [doc = "**Bind id**: Animation bind ID.\n\n*Attributes*: Debuggable, Networked, Store"] @ [Debuggable , Networked , Store , Name ["Bind id"] , Description ["Animation bind ID."]] bind_id : String , # [doc = "**Bind ids**: Animation bind IDs.\n\n*Attributes*: Debuggable, Store"] @ [Debuggable , Store , Name ["Bind ids"] , Description ["Animation bind IDs."]] bind_ids : Vec :: < String > , });
}
}
#[allow(unused)]
Expand Down
Loading