fyrox_animation/track.rs
1// Copyright (c) 2019-present Dmitry Stepanov and Fyrox Engine contributors.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and associated documentation files (the "Software"), to deal
5// in the Software without restriction, including without limitation the rights
6// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7// copies of the Software, and to permit persons to whom the Software is
8// furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in all
11// copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19// SOFTWARE.
20
21//! Track is responsible in animating a property of a single scene node. See [`Track`] docs for more info.
22
23use crate::{
24 container::{TrackDataContainer, TrackValueKind},
25 core::{reflect::prelude::*, uuid::Uuid, visitor::prelude::*},
26 value::{BoundValue, ValueBinding},
27 EntityId,
28};
29use std::fmt::Debug;
30
31/// Track binding contains a handle to a target object that will be animated by an animation track.
32/// Additionally, the binding could be disabled to temporarily prevent animation from affecting the
33/// target.
34#[derive(Debug, Visit, Reflect, Clone, PartialEq)]
35pub struct TrackBinding<T: EntityId> {
36 /// The binding could be disabled to temporarily prevent animation from affecting the target.
37 pub enabled: bool,
38 /// A target bound to a track. The actual track id is stored as a key in hash map of bindings in
39 /// the animation.
40 pub target: T,
41}
42
43impl<T: EntityId> Default for TrackBinding<T> {
44 fn default() -> Self {
45 Self {
46 enabled: true,
47 target: Default::default(),
48 }
49 }
50}
51
52impl<T: EntityId> TrackBinding<T> {
53 /// Creates a new enabled track binding.
54 pub fn new(target: T) -> Self {
55 Self {
56 enabled: true,
57 target,
58 }
59 }
60
61 /// Sets a handle of a node that will be animated.
62 pub fn set_target(&mut self, target: T) {
63 self.target = target;
64 }
65
66 /// Returns a handle of a node that will be animated.
67 pub fn target(&self) -> T {
68 self.target
69 }
70
71 /// Enables or disables the track. Disabled tracks won't animate their nodes/properties.
72 pub fn set_enabled(&mut self, enabled: bool) {
73 self.enabled = enabled;
74 }
75
76 /// Returns `true` if the track is enabled, `false` - otherwise.
77 pub fn is_enabled(&self) -> bool {
78 self.enabled
79 }
80
81 /// Sets target of the track.
82 pub fn with_target(mut self, target: T) -> Self {
83 self.target = target;
84 self
85 }
86}
87
88/// Track is responsible in animating a property of a single scene node. The track consists up to 4 parametric curves
89/// that contains the actual property data. Parametric curves allows the engine to perform various interpolations between
90/// key values.
91#[derive(Debug, Reflect, Clone, PartialEq, Visit)]
92pub struct Track {
93 pub(super) binding: ValueBinding,
94 pub(super) frames: TrackDataContainer,
95 pub(super) id: Uuid,
96}
97
98impl Default for Track {
99 fn default() -> Self {
100 Self {
101 binding: ValueBinding::Position,
102 frames: TrackDataContainer::default(),
103 id: Uuid::new_v4(),
104 }
105 }
106}
107
108impl Track {
109 /// Creates a new track that will animate a property in the given binding. The `container` must have enough parametric
110 /// curves to be able to produces property values.
111 pub fn new(container: TrackDataContainer, binding: ValueBinding) -> Self {
112 Self {
113 frames: container,
114 binding,
115 ..Default::default()
116 }
117 }
118
119 /// Creates a new track that is responsible in animating a position property of a scene node.
120 pub fn new_position() -> Self {
121 Self {
122 frames: TrackDataContainer::new(TrackValueKind::Vector3),
123 binding: ValueBinding::Position,
124 ..Default::default()
125 }
126 }
127
128 /// Creates a new track that is responsible in animating a rotation property of a scene node.
129 pub fn new_rotation() -> Self {
130 Self {
131 frames: TrackDataContainer::new(TrackValueKind::UnitQuaternionEuler),
132 binding: ValueBinding::Rotation,
133 ..Default::default()
134 }
135 }
136
137 /// Creates a new track that is responsible in animating a scaling property of a scene node.
138 pub fn new_scale() -> Self {
139 Self {
140 frames: TrackDataContainer::new(TrackValueKind::Vector3),
141 binding: ValueBinding::Scale,
142 ..Default::default()
143 }
144 }
145
146 /// Sets new track binding. See [`ValueBinding`] docs for more info.
147 pub fn set_value_binding(&mut self, binding: ValueBinding) {
148 self.binding = binding;
149 }
150
151 /// Returns current track binding.
152 pub fn value_binding(&self) -> &ValueBinding {
153 &self.binding
154 }
155
156 /// Returns a reference to the data container.
157 pub fn data_container(&self) -> &TrackDataContainer {
158 &self.frames
159 }
160
161 /// Returns a reference to the data container.
162 pub fn data_container_mut(&mut self) -> &mut TrackDataContainer {
163 &mut self.frames
164 }
165
166 /// Sets new data container and returns the previous one.
167 pub fn set_data_container(&mut self, container: TrackDataContainer) -> TrackDataContainer {
168 std::mem::replace(&mut self.frames, container)
169 }
170
171 /// Tries to get a new property value at a given time position.
172 pub fn fetch(&self, time: f32) -> Option<BoundValue> {
173 self.frames.fetch(time).map(|v| BoundValue {
174 binding: self.binding.clone(),
175 value: v,
176 })
177 }
178
179 /// Returns length of the track in seconds.
180 pub fn time_length(&self) -> f32 {
181 self.frames.time_length()
182 }
183
184 /// Sets a new id for the track.
185 pub fn set_id(&mut self, id: Uuid) {
186 self.id = id;
187 }
188
189 /// Returns the id of the track.
190 pub fn id(&self) -> Uuid {
191 self.id
192 }
193}