1 /*************************************************************************/ 2 /* animation.h */ 3 /*************************************************************************/ 4 /* This file is part of: */ 5 /* GODOT ENGINE */ 6 /* https://godotengine.org */ 7 /*************************************************************************/ 8 /* Copyright (c) 2007-2019 Juan Linietsky, Ariel Manzur. */ 9 /* Copyright (c) 2014-2019 Godot Engine contributors (cf. AUTHORS.md) */ 10 /* */ 11 /* Permission is hereby granted, free of charge, to any person obtaining */ 12 /* a copy of this software and associated documentation files (the */ 13 /* "Software"), to deal in the Software without restriction, including */ 14 /* without limitation the rights to use, copy, modify, merge, publish, */ 15 /* distribute, sublicense, and/or sell copies of the Software, and to */ 16 /* permit persons to whom the Software is furnished to do so, subject to */ 17 /* the following conditions: */ 18 /* */ 19 /* The above copyright notice and this permission notice shall be */ 20 /* included in all copies or substantial portions of the Software. */ 21 /* */ 22 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ 23 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ 24 /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.*/ 25 /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ 26 /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ 27 /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ 28 /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ 29 /*************************************************************************/ 30 #ifndef ANIMATION_H 31 #define ANIMATION_H 32 33 #include "resource.h" 34 /** 35 @author Juan Linietsky <reduzio@gmail.com> 36 */ 37 class Animation : public Resource { 38 39 OBJ_TYPE(Animation, Resource); 40 RES_BASE_EXTENSION("anm"); 41 42 public: 43 enum LoopMode { 44 45 LOOP_NONE, 46 LOOP_ENABLED, 47 LOOP_WRAP 48 }; 49 50 enum TrackType { 51 TYPE_VALUE, ///< Set a value in a property, can be interpolated. 52 TYPE_TRANSFORM, ///< Transform a node or a bone. 53 TYPE_METHOD, ///< Call any method on a specific node. 54 }; 55 56 enum InterpolationType { 57 INTERPOLATION_NEAREST, 58 INTERPOLATION_LINEAR, 59 INTERPOLATION_CUBIC 60 }; 61 62 enum UpdateMode { 63 UPDATE_CONTINUOUS, 64 UPDATE_DISCRETE, 65 UPDATE_TRIGGER, 66 67 }; 68 69 private: 70 struct Track { 71 72 TrackType type; 73 InterpolationType interpolation; 74 NodePath path; // path to something 75 bool imported; TrackTrack76 Track() { 77 interpolation = INTERPOLATION_LINEAR; 78 imported = false; 79 } ~TrackTrack80 virtual ~Track() {} 81 }; 82 83 struct Key { 84 85 float transition; 86 float time; // time in secs KeyKey87 Key() { transition = 1; } 88 }; 89 90 // transform key holds either Vector3 or Quaternion 91 template <class T> 92 struct TKey : public Key { 93 94 float time; 95 T value; 96 }; 97 98 struct TransformKey { 99 100 Vector3 loc; 101 Quat rot; 102 Vector3 scale; 103 }; 104 105 /* TRANSFORM TRACK */ 106 107 struct TransformTrack : public Track { 108 109 Vector<TKey<TransformKey> > transforms; 110 TransformTrackTransformTrack111 TransformTrack() { type = TYPE_TRANSFORM; } 112 }; 113 114 /* PROPERTY VALUE TRACK */ 115 116 struct ValueTrack : public Track { 117 118 UpdateMode update_mode; 119 bool update_on_seek; 120 Vector<TKey<Variant> > values; 121 ValueTrackValueTrack122 ValueTrack() { 123 type = TYPE_VALUE; 124 update_mode = UPDATE_CONTINUOUS; 125 } 126 }; 127 128 /* METHOD TRACK */ 129 130 struct MethodKey : public Key { 131 132 StringName method; 133 Vector<Variant> params; 134 }; 135 136 struct MethodTrack : public Track { 137 138 Vector<MethodKey> methods; MethodTrackMethodTrack139 MethodTrack() { type = TYPE_METHOD; } 140 }; 141 142 Vector<Track *> tracks; 143 144 /* 145 template<class T> 146 int _insert_pos(float p_time, T& p_keys);*/ 147 148 template <class T> 149 void _clear(T &p_keys); 150 151 template <class T, class V> 152 int _insert(float p_time, T &p_keys, const V &p_value); 153 154 template <class K> 155 inline int _find(const Vector<K> &p_keys, float p_time) const; 156 157 _FORCE_INLINE_ Animation::TransformKey _interpolate(const Animation::TransformKey &p_a, const Animation::TransformKey &p_b, float p_c) const; 158 159 _FORCE_INLINE_ Vector3 _interpolate(const Vector3 &p_a, const Vector3 &p_b, float p_c) const; 160 _FORCE_INLINE_ Quat _interpolate(const Quat &p_a, const Quat &p_b, float p_c) const; 161 _FORCE_INLINE_ Variant _interpolate(const Variant &p_a, const Variant &p_b, float p_c) const; 162 _FORCE_INLINE_ float _interpolate(const float &p_a, const float &p_b, float p_c) const; 163 164 _FORCE_INLINE_ Animation::TransformKey _cubic_interpolate(const Animation::TransformKey &p_pre_a, const Animation::TransformKey &p_a, const Animation::TransformKey &p_b, const Animation::TransformKey &p_post_b, float p_c) const; 165 _FORCE_INLINE_ Vector3 _cubic_interpolate(const Vector3 &p_pre_a, const Vector3 &p_a, const Vector3 &p_b, const Vector3 &p_post_b, float p_c) const; 166 _FORCE_INLINE_ Quat _cubic_interpolate(const Quat &p_pre_a, const Quat &p_a, const Quat &p_b, const Quat &p_post_b, float p_c) const; 167 _FORCE_INLINE_ Variant _cubic_interpolate(const Variant &p_pre_a, const Variant &p_a, const Variant &p_b, const Variant &p_post_b, float p_c) const; 168 _FORCE_INLINE_ float _cubic_interpolate(const float &p_pre_a, const float &p_a, const float &p_b, const float &p_post_b, float p_c) const; 169 170 template <class T> 171 _FORCE_INLINE_ T _interpolate(const Vector<TKey<T> > &p_keys, float p_time, InterpolationType p_interp, bool *p_ok) const; 172 173 _FORCE_INLINE_ void _value_track_get_key_indices_in_range(const ValueTrack *vt, float from_time, float to_time, List<int> *p_indices) const; 174 _FORCE_INLINE_ void _method_track_get_key_indices_in_range(const MethodTrack *mt, float from_time, float to_time, List<int> *p_indices) const; 175 176 float length; 177 float step; 178 bool loop; 179 180 // bind helpers 181 private: _transform_track_interpolate(int p_track,float p_time)182 Array _transform_track_interpolate(int p_track, float p_time) const { 183 Vector3 loc; 184 Quat rot; 185 Vector3 scale; 186 transform_track_interpolate(p_track, p_time, &loc, &rot, &scale); 187 Array ret; 188 ret.push_back(loc); 189 ret.push_back(rot); 190 ret.push_back(scale); 191 return ret; 192 } 193 _value_track_get_key_indices(int p_track,float p_time,float p_delta)194 DVector<int> _value_track_get_key_indices(int p_track, float p_time, float p_delta) const { 195 196 List<int> idxs; 197 value_track_get_key_indices(p_track, p_time, p_delta, &idxs); 198 DVector<int> idxr; 199 200 for (List<int>::Element *E = idxs.front(); E; E = E->next()) { 201 202 idxr.push_back(E->get()); 203 } 204 return idxr; 205 } _method_track_get_key_indices(int p_track,float p_time,float p_delta)206 DVector<int> _method_track_get_key_indices(int p_track, float p_time, float p_delta) const { 207 208 List<int> idxs; 209 method_track_get_key_indices(p_track, p_time, p_delta, &idxs); 210 DVector<int> idxr; 211 212 for (List<int>::Element *E = idxs.front(); E; E = E->next()) { 213 214 idxr.push_back(E->get()); 215 } 216 return idxr; 217 } 218 219 bool _transform_track_optimize_key(const TKey<TransformKey> &t0, const TKey<TransformKey> &t1, const TKey<TransformKey> &t2, float p_alowed_linear_err, float p_alowed_angular_err, float p_max_optimizable_angle, const Vector3 &p_norm); 220 void _transform_track_optimize(int p_idx, float p_allowed_err = 0.05, float p_alowed_angular_err = 0.01, float p_max_optimizable_angle = Math_PI * 0.125); 221 222 protected: 223 bool _set(const StringName &p_name, const Variant &p_value); 224 bool _get(const StringName &p_name, Variant &r_ret) const; 225 void _get_property_list(List<PropertyInfo> *p_list) const; 226 227 static void _bind_methods(); 228 229 public: 230 int add_track(TrackType p_type, int p_at_pos = -1); 231 void remove_track(int p_track); 232 233 int get_track_count() const; 234 TrackType track_get_type(int p_track) const; 235 236 void track_set_path(int p_track, const NodePath &p_path); 237 NodePath track_get_path(int p_track) const; 238 int find_track(const NodePath &p_path) const; 239 // transform 240 241 void track_move_up(int p_track); 242 void track_move_down(int p_track); 243 244 void track_set_imported(int p_track, bool p_imported); 245 bool track_is_imported(int p_track) const; 246 247 int transform_track_insert_key(int p_track, float p_time, const Vector3 p_loc, const Quat &p_rot = Quat(), const Vector3 &p_scale = Vector3()); 248 void track_insert_key(int p_track, float p_time, const Variant &p_key, float p_transition = 1); 249 void track_set_key_transition(int p_track, int p_key_idx, float p_transition); 250 void track_set_key_value(int p_track, int p_key_idx, const Variant &p_value); 251 int track_find_key(int p_track, float p_time, bool p_exact = false) const; 252 void track_remove_key(int p_track, int p_idx); 253 void track_remove_key_at_pos(int p_track, float p_pos); 254 int track_get_key_count(int p_track) const; 255 Variant track_get_key_value(int p_track, int p_key_idx) const; 256 float track_get_key_time(int p_track, int p_key_idx) const; 257 float track_get_key_transition(int p_track, int p_key_idx) const; 258 259 Error transform_track_get_key(int p_track, int p_key, Vector3 *r_loc, Quat *r_rot, Vector3 *r_scale) const; 260 void track_set_interpolation_type(int p_track, InterpolationType p_interp); 261 InterpolationType track_get_interpolation_type(int p_track) const; 262 263 Error transform_track_interpolate(int p_track, float p_time, Vector3 *r_loc, Quat *r_rot, Vector3 *r_scale) const; 264 265 Variant value_track_interpolate(int p_track, float p_time) const; 266 void value_track_get_key_indices(int p_track, float p_time, float p_delta, List<int> *p_indices) const; 267 void value_track_set_update_mode(int p_track, UpdateMode p_mode); 268 UpdateMode value_track_get_update_mode(int p_track) const; 269 270 void method_track_get_key_indices(int p_track, float p_time, float p_delta, List<int> *p_indices) const; 271 Vector<Variant> method_track_get_params(int p_track, int p_key_idx) const; 272 StringName method_track_get_name(int p_track, int p_key_idx) const; 273 274 void set_length(float p_length); 275 float get_length() const; 276 277 void set_loop(bool p_enabled); 278 bool has_loop() const; 279 280 void set_step(float p_step); 281 float get_step() const; 282 283 void clear(); 284 285 void optimize(float p_allowed_linear_err = 0.05, float p_allowed_angular_err = 0.01, float p_max_optimizable_angle = Math_PI * 0.125); 286 287 Animation(); 288 ~Animation(); 289 }; 290 291 VARIANT_ENUM_CAST(Animation::TrackType); 292 VARIANT_ENUM_CAST(Animation::InterpolationType); 293 VARIANT_ENUM_CAST(Animation::UpdateMode); 294 295 #endif 296