Skip to main content

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}