pub struct BlendTree { /* private fields */ }Implementations§
Source§impl BlendTree
impl BlendTree
pub fn clear(&mut self)
pub fn is_empty(&self) -> bool
pub fn len(&self) -> usize
pub fn with_capacity(len: usize) -> Self
pub fn from_vec(tasks: Vec<BlendSample>) -> Self
pub fn into_inner(self) -> Vec<BlendSample>
Sourcepub fn get(&self) -> &[BlendSample]
pub fn get(&self) -> &[BlendSample]
Examples found in repository?
examples/third_person.rs (line 62)
8fn main() -> anyhow::Result<()> {
9 let (locomotion_definition, default_locomotion_skeleton, default_locomotion_resources) =
10 locomotion_graph_example()?;
11
12 let mut locomotion = create_instance(
13 locomotion_definition,
14 default_locomotion_skeleton,
15 default_locomotion_resources,
16 );
17
18 let (action_definition, default_action_skeleton, default_action_resources) =
19 action_graph_example()?;
20
21 let mut action = create_instance(
22 action_definition,
23 default_action_skeleton,
24 default_action_resources,
25 );
26
27 // Parameter lookups can be done ahead of time using the definition which each graph has a reference to.
28 let locomotion_speed = locomotion
29 .definition()
30 .get_number_parameter::<f32>("locomotion_speed")
31 .expect("Valid parameter");
32 let action_sit = action
33 .definition()
34 .get_event_parameter("sit")
35 .expect("Valid parameter");
36
37 // Parameters are specific to a definition
38 locomotion_speed.set(&mut locomotion, 2.0);
39
40 // Event has multiple states that micmics that of a state in a statemachine (entering, entered, exiting, exited)
41 action_sit.set(&mut action, FlowState::Entered);
42
43 let delta_time = 0.1;
44 let mut context = DefaultRunContext::new(delta_time);
45 let resources = RESOURCES.lock().expect("Single threaded");
46 for frame in 1..=5 {
47 // Multiple graphs can be concatenated where the output of the first is set
48 // as a reference to the next. It's ultimately up to the next graph if it decides
49 // to blend with the reference task at all.
50 context.run(&mut action);
51
52 // In this example the second graph looks for an emitted event from previous graphs
53 // to decided if it should blend or not.
54 context.run_and_append(&mut locomotion);
55
56 // The resulting blend tree is all the active animations that could be sampled
57 // even if they dont contribute to the final blend for things like animation events.
58 // The tree can be evaluated from the last sample to form a trimmed blend stack.
59
60 println!("Frame #{frame}:");
61 println!("- Blend Tree:");
62 for (index, task) in context.tree.get().iter().enumerate() {
63 let n = index + 1;
64 match task {
65 BlendSample::Animation {
66 id,
67 normalized_time,
68 } => {
69 println!(
70 " #{n} Sample {} at t={normalized_time}",
71 &resources.animations[id.0 as usize].name
72 );
73 }
74 BlendSample::Blend(_, _, a, g) => {
75 if *g == BoneGroupId::All {
76 println!(" #{n} Blend a={a}");
77 } else {
78 println!(" #{n} Masked blend a={a}");
79 }
80 }
81 BlendSample::Interpolate(_, _, a) => {
82 println!(" #{n} Interpolate a={a}");
83 }
84 }
85 }
86
87 struct BlendStack<'a>(&'a GlobalResources);
88 impl<'a> BlendTreeVisitor for BlendStack<'a> {
89 fn visit(&mut self, tree: &BlendTree, sample: &BlendSample) {
90 match *sample {
91 BlendSample::Animation {
92 id,
93 normalized_time,
94 } => {
95 println!(
96 " Sample {} at t={normalized_time}",
97 &self.0.animations[id.0 as usize].name
98 );
99 }
100 BlendSample::Interpolate(x, y, a) => {
101 if a < 1.0 {
102 tree.visit(self, x);
103 }
104 if a > 0.0 {
105 tree.visit(self, y);
106 }
107
108 if a > 0.0 && a < 1.0 {
109 println!(" Interpolate a={a}");
110 }
111 }
112 BlendSample::Blend(x, y, a, g) => {
113 if g == BoneGroupId::All {
114 if a < 1.0 {
115 tree.visit(self, x);
116 }
117 if a > 0.0 {
118 tree.visit(self, y);
119 }
120
121 if a > 0.0 && a < 1.0 {
122 println!(" Interpolate a={a}");
123 }
124 } else {
125 tree.visit(self, x);
126 tree.visit(self, y);
127 println!(" Masked Blend a={a}");
128 }
129 }
130 }
131 }
132 }
133
134 println!("\n- Blend Stack:");
135 context.tree.visit_root(&mut BlendStack(&resources));
136 println!("");
137 }
138
139 Ok(())
140}pub fn get_reference_task(&mut self) -> Option<BlendSampleId>
pub fn set_reference_task(&mut self, task: Option<BlendSampleId>)
pub fn sample_animation_clip( &mut self, animation: AnimationId, time: Alpha, ) -> BlendSampleId
pub fn interpolate( &mut self, a: BlendSampleId, b: BlendSampleId, w: Alpha, ) -> BlendSampleId
pub fn blend_masked( &mut self, a: BlendSampleId, b: BlendSampleId, w: Alpha, ) -> BlendSampleId
pub fn append( &mut self, graph: &Graph, layers: &LayerBuilder, ) -> Result<Option<BlendSampleId>>
pub fn set( &mut self, graph: &Graph, layers: &LayerBuilder, ) -> Result<Option<BlendSampleId>>
pub fn apply_mask( &mut self, sample: BlendSampleId, group: BoneGroupId, ) -> BlendSampleId
Sourcepub fn visit<T: BlendTreeVisitor>(&self, visitor: &mut T, sample: BlendSampleId)
pub fn visit<T: BlendTreeVisitor>(&self, visitor: &mut T, sample: BlendSampleId)
Examples found in repository?
examples/third_person.rs (line 102)
89 fn visit(&mut self, tree: &BlendTree, sample: &BlendSample) {
90 match *sample {
91 BlendSample::Animation {
92 id,
93 normalized_time,
94 } => {
95 println!(
96 " Sample {} at t={normalized_time}",
97 &self.0.animations[id.0 as usize].name
98 );
99 }
100 BlendSample::Interpolate(x, y, a) => {
101 if a < 1.0 {
102 tree.visit(self, x);
103 }
104 if a > 0.0 {
105 tree.visit(self, y);
106 }
107
108 if a > 0.0 && a < 1.0 {
109 println!(" Interpolate a={a}");
110 }
111 }
112 BlendSample::Blend(x, y, a, g) => {
113 if g == BoneGroupId::All {
114 if a < 1.0 {
115 tree.visit(self, x);
116 }
117 if a > 0.0 {
118 tree.visit(self, y);
119 }
120
121 if a > 0.0 && a < 1.0 {
122 println!(" Interpolate a={a}");
123 }
124 } else {
125 tree.visit(self, x);
126 tree.visit(self, y);
127 println!(" Masked Blend a={a}");
128 }
129 }
130 }
131 }Sourcepub fn visit_root<T: BlendTreeVisitor>(&self, visitor: &mut T)
pub fn visit_root<T: BlendTreeVisitor>(&self, visitor: &mut T)
Examples found in repository?
examples/third_person.rs (line 135)
8fn main() -> anyhow::Result<()> {
9 let (locomotion_definition, default_locomotion_skeleton, default_locomotion_resources) =
10 locomotion_graph_example()?;
11
12 let mut locomotion = create_instance(
13 locomotion_definition,
14 default_locomotion_skeleton,
15 default_locomotion_resources,
16 );
17
18 let (action_definition, default_action_skeleton, default_action_resources) =
19 action_graph_example()?;
20
21 let mut action = create_instance(
22 action_definition,
23 default_action_skeleton,
24 default_action_resources,
25 );
26
27 // Parameter lookups can be done ahead of time using the definition which each graph has a reference to.
28 let locomotion_speed = locomotion
29 .definition()
30 .get_number_parameter::<f32>("locomotion_speed")
31 .expect("Valid parameter");
32 let action_sit = action
33 .definition()
34 .get_event_parameter("sit")
35 .expect("Valid parameter");
36
37 // Parameters are specific to a definition
38 locomotion_speed.set(&mut locomotion, 2.0);
39
40 // Event has multiple states that micmics that of a state in a statemachine (entering, entered, exiting, exited)
41 action_sit.set(&mut action, FlowState::Entered);
42
43 let delta_time = 0.1;
44 let mut context = DefaultRunContext::new(delta_time);
45 let resources = RESOURCES.lock().expect("Single threaded");
46 for frame in 1..=5 {
47 // Multiple graphs can be concatenated where the output of the first is set
48 // as a reference to the next. It's ultimately up to the next graph if it decides
49 // to blend with the reference task at all.
50 context.run(&mut action);
51
52 // In this example the second graph looks for an emitted event from previous graphs
53 // to decided if it should blend or not.
54 context.run_and_append(&mut locomotion);
55
56 // The resulting blend tree is all the active animations that could be sampled
57 // even if they dont contribute to the final blend for things like animation events.
58 // The tree can be evaluated from the last sample to form a trimmed blend stack.
59
60 println!("Frame #{frame}:");
61 println!("- Blend Tree:");
62 for (index, task) in context.tree.get().iter().enumerate() {
63 let n = index + 1;
64 match task {
65 BlendSample::Animation {
66 id,
67 normalized_time,
68 } => {
69 println!(
70 " #{n} Sample {} at t={normalized_time}",
71 &resources.animations[id.0 as usize].name
72 );
73 }
74 BlendSample::Blend(_, _, a, g) => {
75 if *g == BoneGroupId::All {
76 println!(" #{n} Blend a={a}");
77 } else {
78 println!(" #{n} Masked blend a={a}");
79 }
80 }
81 BlendSample::Interpolate(_, _, a) => {
82 println!(" #{n} Interpolate a={a}");
83 }
84 }
85 }
86
87 struct BlendStack<'a>(&'a GlobalResources);
88 impl<'a> BlendTreeVisitor for BlendStack<'a> {
89 fn visit(&mut self, tree: &BlendTree, sample: &BlendSample) {
90 match *sample {
91 BlendSample::Animation {
92 id,
93 normalized_time,
94 } => {
95 println!(
96 " Sample {} at t={normalized_time}",
97 &self.0.animations[id.0 as usize].name
98 );
99 }
100 BlendSample::Interpolate(x, y, a) => {
101 if a < 1.0 {
102 tree.visit(self, x);
103 }
104 if a > 0.0 {
105 tree.visit(self, y);
106 }
107
108 if a > 0.0 && a < 1.0 {
109 println!(" Interpolate a={a}");
110 }
111 }
112 BlendSample::Blend(x, y, a, g) => {
113 if g == BoneGroupId::All {
114 if a < 1.0 {
115 tree.visit(self, x);
116 }
117 if a > 0.0 {
118 tree.visit(self, y);
119 }
120
121 if a > 0.0 && a < 1.0 {
122 println!(" Interpolate a={a}");
123 }
124 } else {
125 tree.visit(self, x);
126 tree.visit(self, y);
127 println!(" Masked Blend a={a}");
128 }
129 }
130 }
131 }
132 }
133
134 println!("\n- Blend Stack:");
135 context.tree.visit_root(&mut BlendStack(&resources));
136 println!("");
137 }
138
139 Ok(())
140}Trait Implementations§
Auto Trait Implementations§
impl Freeze for BlendTree
impl RefUnwindSafe for BlendTree
impl Send for BlendTree
impl Sync for BlendTree
impl Unpin for BlendTree
impl UnwindSafe for BlendTree
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more