tween.cpp 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930
  1. /**************************************************************************/
  2. /* tween.cpp */
  3. /**************************************************************************/
  4. /* This file is part of: */
  5. /* GODOT ENGINE */
  6. /* https://godotengine.org */
  7. /**************************************************************************/
  8. /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */
  9. /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */
  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. #include "tween.h"
  31. #include "scene/animation/easing_equations.h"
  32. #include "scene/main/node.h"
  33. #include "scene/resources/animation.h"
  34. #define CHECK_VALID() \
  35. ERR_FAIL_COND_V_MSG(!valid, nullptr, "Tween invalid. Either finished or created outside scene tree."); \
  36. ERR_FAIL_COND_V_MSG(started, nullptr, "Can't append to a Tween that has started. Use stop() first.");
  37. Tween::interpolater Tween::interpolaters[Tween::TRANS_MAX][Tween::EASE_MAX] = {
  38. { &Linear::in, &Linear::in, &Linear::in, &Linear::in }, // Linear is the same for each easing.
  39. { &Sine::in, &Sine::out, &Sine::in_out, &Sine::out_in },
  40. { &Quint::in, &Quint::out, &Quint::in_out, &Quint::out_in },
  41. { &Quart::in, &Quart::out, &Quart::in_out, &Quart::out_in },
  42. { &Quad::in, &Quad::out, &Quad::in_out, &Quad::out_in },
  43. { &Expo::in, &Expo::out, &Expo::in_out, &Expo::out_in },
  44. { &Elastic::in, &Elastic::out, &Elastic::in_out, &Elastic::out_in },
  45. { &Cubic::in, &Cubic::out, &Cubic::in_out, &Cubic::out_in },
  46. { &Circ::in, &Circ::out, &Circ::in_out, &Circ::out_in },
  47. { &Bounce::in, &Bounce::out, &Bounce::in_out, &Bounce::out_in },
  48. { &Back::in, &Back::out, &Back::in_out, &Back::out_in },
  49. { &Spring::in, &Spring::out, &Spring::in_out, &Spring::out_in },
  50. };
  51. void Tweener::set_tween(const Ref<Tween> &p_tween) {
  52. tween_id = p_tween->get_instance_id();
  53. }
  54. void Tweener::start() {
  55. elapsed_time = 0;
  56. finished = false;
  57. }
  58. Ref<Tween> Tweener::_get_tween() {
  59. return ObjectDB::get_ref<Tween>(tween_id);
  60. }
  61. void Tweener::_finish() {
  62. finished = true;
  63. emit_signal(SceneStringName(finished));
  64. }
  65. void Tweener::_bind_methods() {
  66. ADD_SIGNAL(MethodInfo("finished"));
  67. }
  68. void Tween::_start_tweeners() {
  69. if (tweeners.is_empty()) {
  70. dead = true;
  71. ERR_FAIL_MSG("Tween without commands, aborting.");
  72. }
  73. for (Ref<Tweener> &tweener : tweeners[current_step]) {
  74. tweener->start();
  75. }
  76. }
  77. void Tween::_stop_internal(bool p_reset) {
  78. running = false;
  79. if (p_reset) {
  80. started = false;
  81. dead = false;
  82. total_time = 0;
  83. }
  84. }
  85. RequiredResult<PropertyTweener> Tween::tween_property(RequiredParam<const Object> rp_target, const NodePath &p_property, Variant p_to, double p_duration) {
  86. EXTRACT_PARAM_OR_FAIL_V(p_target, rp_target, nullptr);
  87. CHECK_VALID();
  88. Vector<StringName> property_subnames = p_property.get_as_property_path().get_subnames();
  89. #ifdef DEBUG_ENABLED
  90. bool prop_valid;
  91. const Variant &prop_value = p_target->get_indexed(property_subnames, &prop_valid);
  92. ERR_FAIL_COND_V_MSG(!prop_valid, nullptr, vformat("The tweened property \"%s\" does not exist in object \"%s\".", p_property, p_target));
  93. #else
  94. const Variant &prop_value = p_target->get_indexed(property_subnames);
  95. #endif
  96. if (!Animation::validate_type_match(prop_value, p_to)) {
  97. return nullptr;
  98. }
  99. Ref<PropertyTweener> tweener;
  100. tweener.instantiate(p_target, property_subnames, p_to, p_duration);
  101. append(tweener);
  102. return tweener;
  103. }
  104. RequiredResult<IntervalTweener> Tween::tween_interval(double p_time) {
  105. CHECK_VALID();
  106. Ref<IntervalTweener> tweener;
  107. tweener.instantiate(p_time);
  108. append(tweener);
  109. return tweener;
  110. }
  111. RequiredResult<CallbackTweener> Tween::tween_callback(const Callable &p_callback) {
  112. CHECK_VALID();
  113. Ref<CallbackTweener> tweener;
  114. tweener.instantiate(p_callback);
  115. append(tweener);
  116. return tweener;
  117. }
  118. RequiredResult<MethodTweener> Tween::tween_method(const Callable &p_callback, const Variant p_from, Variant p_to, double p_duration) {
  119. CHECK_VALID();
  120. if (!Animation::validate_type_match(p_from, p_to)) {
  121. return nullptr;
  122. }
  123. Ref<MethodTweener> tweener;
  124. tweener.instantiate(p_callback, p_from, p_to, p_duration);
  125. append(tweener);
  126. return tweener;
  127. }
  128. RequiredResult<SubtweenTweener> Tween::tween_subtween(RequiredParam<Tween> rp_subtween) {
  129. CHECK_VALID();
  130. // Ensure that the subtween being added is not null.
  131. EXTRACT_PARAM_OR_FAIL_V(p_subtween, rp_subtween, nullptr);
  132. Ref<SubtweenTweener> tweener;
  133. tweener.instantiate(p_subtween);
  134. // Remove the tween from its parent tree, if it has one.
  135. // If the user created this tween without a parent tree attached,
  136. // then this step isn't necessary.
  137. if (tweener->subtween->parent_tree != nullptr) {
  138. tweener->subtween->parent_tree->remove_tween(tweener->subtween);
  139. }
  140. subtweens.push_back(p_subtween);
  141. append(tweener);
  142. return tweener;
  143. }
  144. void Tween::append(Ref<Tweener> p_tweener) {
  145. p_tweener->set_tween(this);
  146. if (parallel_enabled) {
  147. current_step = MAX(current_step, 0);
  148. } else {
  149. current_step++;
  150. }
  151. parallel_enabled = default_parallel;
  152. tweeners.resize(current_step + 1);
  153. tweeners[current_step].push_back(p_tweener);
  154. }
  155. void Tween::stop() {
  156. _stop_internal(true);
  157. }
  158. void Tween::pause() {
  159. _stop_internal(false);
  160. }
  161. void Tween::play() {
  162. ERR_FAIL_COND_MSG(!valid, "Tween invalid. Either finished or created outside scene tree.");
  163. ERR_FAIL_COND_MSG(dead, "Can't play finished Tween, use stop() first to reset its state.");
  164. running = true;
  165. }
  166. void Tween::kill() {
  167. running = false; // For the sake of is_running().
  168. valid = false;
  169. dead = true;
  170. // Kill all subtweens of this tween.
  171. for (Ref<Tween> &st : subtweens) {
  172. st->kill();
  173. }
  174. }
  175. bool Tween::is_running() {
  176. return running;
  177. }
  178. bool Tween::is_valid() {
  179. return valid;
  180. }
  181. void Tween::clear() {
  182. valid = false;
  183. tweeners.clear();
  184. }
  185. RequiredResult<Tween> Tween::bind_node(RequiredParam<const Node> rp_node) {
  186. EXTRACT_PARAM_OR_FAIL_V(p_node, rp_node, this);
  187. bound_node = p_node->get_instance_id();
  188. is_bound = true;
  189. return this;
  190. }
  191. RequiredResult<Tween> Tween::set_process_mode(TweenProcessMode p_mode) {
  192. process_mode = p_mode;
  193. return this;
  194. }
  195. Tween::TweenProcessMode Tween::get_process_mode() const {
  196. return process_mode;
  197. }
  198. RequiredResult<Tween> Tween::set_pause_mode(TweenPauseMode p_mode) {
  199. pause_mode = p_mode;
  200. return this;
  201. }
  202. Tween::TweenPauseMode Tween::get_pause_mode() const {
  203. return pause_mode;
  204. }
  205. RequiredResult<Tween> Tween::set_ignore_time_scale(bool p_ignore) {
  206. ignore_time_scale = p_ignore;
  207. return this;
  208. }
  209. bool Tween::is_ignoring_time_scale() const {
  210. return ignore_time_scale;
  211. }
  212. RequiredResult<Tween> Tween::set_parallel(bool p_parallel) {
  213. default_parallel = p_parallel;
  214. parallel_enabled = p_parallel;
  215. return this;
  216. }
  217. RequiredResult<Tween> Tween::set_loops(int p_loops) {
  218. loops = p_loops;
  219. return this;
  220. }
  221. int Tween::get_loops_left() const {
  222. if (loops <= 0) {
  223. return -1; // Infinite loop.
  224. } else {
  225. return loops - loops_done;
  226. }
  227. }
  228. RequiredResult<Tween> Tween::set_speed_scale(float p_speed) {
  229. speed_scale = p_speed;
  230. return this;
  231. }
  232. RequiredResult<Tween> Tween::set_trans(TransitionType p_trans) {
  233. default_transition = p_trans;
  234. return this;
  235. }
  236. Tween::TransitionType Tween::get_trans() const {
  237. return default_transition;
  238. }
  239. RequiredResult<Tween> Tween::set_ease(EaseType p_ease) {
  240. default_ease = p_ease;
  241. return this;
  242. }
  243. Tween::EaseType Tween::get_ease() const {
  244. return default_ease;
  245. }
  246. RequiredResult<Tween> Tween::parallel() {
  247. parallel_enabled = true;
  248. return this;
  249. }
  250. RequiredResult<Tween> Tween::chain() {
  251. parallel_enabled = false;
  252. return this;
  253. }
  254. bool Tween::custom_step(double p_delta) {
  255. ERR_FAIL_COND_V_MSG(in_step, true, "Can't call custom_step() during another Tween step.");
  256. bool r = running;
  257. running = true;
  258. bool ret = step(p_delta);
  259. running = running && r; // Running might turn false when Tween finished.
  260. return ret;
  261. }
  262. bool Tween::step(double p_delta) {
  263. if (dead) {
  264. return false;
  265. }
  266. if (is_bound) {
  267. Node *node = get_bound_node();
  268. if (node) {
  269. if (!node->is_inside_tree()) {
  270. return true;
  271. }
  272. } else {
  273. return false;
  274. }
  275. }
  276. if (!running) {
  277. return true;
  278. }
  279. in_step = true;
  280. if (!started) {
  281. if (tweeners.is_empty()) {
  282. String tween_id;
  283. Node *node = get_bound_node();
  284. if (node) {
  285. tween_id = vformat("Tween (bound to %s)", node->is_inside_tree() ? (String)node->get_path() : (String)node->get_name());
  286. } else {
  287. tween_id = to_string();
  288. }
  289. in_step = false;
  290. ERR_FAIL_V_MSG(false, tween_id + ": started with no Tweeners.");
  291. }
  292. current_step = 0;
  293. loops_done = 0;
  294. total_time = 0;
  295. _start_tweeners();
  296. started = true;
  297. }
  298. double rem_delta = p_delta * speed_scale;
  299. bool step_active = false;
  300. total_time += rem_delta;
  301. #ifdef DEBUG_ENABLED
  302. double initial_delta = rem_delta;
  303. bool potential_infinite = false;
  304. #endif
  305. while (running && rem_delta > 0) {
  306. double step_delta = rem_delta;
  307. step_active = false;
  308. for (Ref<Tweener> &tweener : tweeners[current_step]) {
  309. // Modified inside Tweener.step().
  310. double temp_delta = rem_delta;
  311. // Turns to true if any Tweener returns true (i.e. is still not finished).
  312. step_active = tweener->step(temp_delta) || step_active;
  313. step_delta = MIN(temp_delta, step_delta);
  314. }
  315. rem_delta = step_delta;
  316. if (!step_active) {
  317. emit_signal(SNAME("step_finished"), current_step);
  318. current_step++;
  319. if (current_step == (int)tweeners.size()) {
  320. loops_done++;
  321. if (loops_done == loops) {
  322. running = false;
  323. dead = true;
  324. emit_signal(SceneStringName(finished));
  325. break;
  326. } else {
  327. emit_signal(SNAME("loop_finished"), loops_done);
  328. current_step = 0;
  329. _start_tweeners();
  330. #ifdef DEBUG_ENABLED
  331. if (loops <= 0 && Math::is_equal_approx(rem_delta, initial_delta)) {
  332. if (!potential_infinite) {
  333. potential_infinite = true;
  334. } else {
  335. // Looped twice without using any time, this is 100% certain infinite loop.
  336. in_step = false;
  337. ERR_FAIL_V_MSG(false, "Infinite loop detected. Check set_loops() description for more info.");
  338. }
  339. }
  340. #endif
  341. }
  342. } else {
  343. _start_tweeners();
  344. }
  345. }
  346. }
  347. in_step = false;
  348. return true;
  349. }
  350. bool Tween::can_process(bool p_tree_paused) const {
  351. if (is_bound && pause_mode == TWEEN_PAUSE_BOUND) {
  352. Node *node = get_bound_node();
  353. if (node) {
  354. return node->is_inside_tree() && node->can_process();
  355. }
  356. }
  357. return !p_tree_paused || pause_mode == TWEEN_PAUSE_PROCESS;
  358. }
  359. Node *Tween::get_bound_node() const {
  360. if (is_bound) {
  361. return ObjectDB::get_instance<Node>(bound_node);
  362. } else {
  363. return nullptr;
  364. }
  365. }
  366. double Tween::get_total_time() const {
  367. return total_time;
  368. }
  369. real_t Tween::run_equation(TransitionType p_trans_type, EaseType p_ease_type, real_t p_time, real_t p_initial, real_t p_delta, real_t p_duration) {
  370. if (p_duration == 0) {
  371. // Special case to avoid dividing by 0 in equations.
  372. return p_initial + p_delta;
  373. }
  374. interpolater func = interpolaters[p_trans_type][p_ease_type];
  375. return func(p_time, p_initial, p_delta, p_duration);
  376. }
  377. Variant Tween::interpolate_variant(const Variant &p_initial_val, const Variant &p_delta_val, double p_time, double p_duration, TransitionType p_trans, EaseType p_ease) {
  378. ERR_FAIL_INDEX_V(p_trans, TransitionType::TRANS_MAX, Variant());
  379. ERR_FAIL_INDEX_V(p_ease, EaseType::EASE_MAX, Variant());
  380. Variant ret = Animation::add_variant(p_initial_val, p_delta_val);
  381. ret = Animation::interpolate_variant(p_initial_val, ret, run_equation(p_trans, p_ease, p_time, 0.0, 1.0, p_duration), p_initial_val.is_string());
  382. return ret;
  383. }
  384. String Tween::_to_string() {
  385. String ret = Object::_to_string();
  386. Node *node = get_bound_node();
  387. if (node) {
  388. ret += vformat(" (bound to %s)", node->get_name());
  389. }
  390. return ret;
  391. }
  392. void Tween::_bind_methods() {
  393. ClassDB::bind_method(D_METHOD("tween_property", "object", "property", "final_val", "duration"), &Tween::tween_property);
  394. ClassDB::bind_method(D_METHOD("tween_interval", "time"), &Tween::tween_interval);
  395. ClassDB::bind_method(D_METHOD("tween_callback", "callback"), &Tween::tween_callback);
  396. ClassDB::bind_method(D_METHOD("tween_method", "method", "from", "to", "duration"), &Tween::tween_method);
  397. ClassDB::bind_method(D_METHOD("tween_subtween", "subtween"), &Tween::tween_subtween);
  398. ClassDB::bind_method(D_METHOD("custom_step", "delta"), &Tween::custom_step);
  399. ClassDB::bind_method(D_METHOD("stop"), &Tween::stop);
  400. ClassDB::bind_method(D_METHOD("pause"), &Tween::pause);
  401. ClassDB::bind_method(D_METHOD("play"), &Tween::play);
  402. ClassDB::bind_method(D_METHOD("kill"), &Tween::kill);
  403. ClassDB::bind_method(D_METHOD("get_total_elapsed_time"), &Tween::get_total_time);
  404. ClassDB::bind_method(D_METHOD("is_running"), &Tween::is_running);
  405. ClassDB::bind_method(D_METHOD("is_valid"), &Tween::is_valid);
  406. ClassDB::bind_method(D_METHOD("bind_node", "node"), &Tween::bind_node);
  407. ClassDB::bind_method(D_METHOD("set_process_mode", "mode"), &Tween::set_process_mode);
  408. ClassDB::bind_method(D_METHOD("set_pause_mode", "mode"), &Tween::set_pause_mode);
  409. ClassDB::bind_method(D_METHOD("set_ignore_time_scale", "ignore"), &Tween::set_ignore_time_scale, DEFVAL(true));
  410. ClassDB::bind_method(D_METHOD("set_parallel", "parallel"), &Tween::set_parallel, DEFVAL(true));
  411. ClassDB::bind_method(D_METHOD("set_loops", "loops"), &Tween::set_loops, DEFVAL(0));
  412. ClassDB::bind_method(D_METHOD("get_loops_left"), &Tween::get_loops_left);
  413. ClassDB::bind_method(D_METHOD("set_speed_scale", "speed"), &Tween::set_speed_scale);
  414. ClassDB::bind_method(D_METHOD("set_trans", "trans"), &Tween::set_trans);
  415. ClassDB::bind_method(D_METHOD("set_ease", "ease"), &Tween::set_ease);
  416. ClassDB::bind_method(D_METHOD("parallel"), &Tween::parallel);
  417. ClassDB::bind_method(D_METHOD("chain"), &Tween::chain);
  418. ClassDB::bind_static_method("Tween", D_METHOD("interpolate_value", "initial_value", "delta_value", "elapsed_time", "duration", "trans_type", "ease_type"), &Tween::interpolate_variant);
  419. ADD_SIGNAL(MethodInfo("step_finished", PropertyInfo(Variant::INT, "idx")));
  420. ADD_SIGNAL(MethodInfo("loop_finished", PropertyInfo(Variant::INT, "loop_count")));
  421. ADD_SIGNAL(MethodInfo("finished"));
  422. BIND_ENUM_CONSTANT(TWEEN_PROCESS_PHYSICS);
  423. BIND_ENUM_CONSTANT(TWEEN_PROCESS_IDLE);
  424. BIND_ENUM_CONSTANT(TWEEN_PAUSE_BOUND);
  425. BIND_ENUM_CONSTANT(TWEEN_PAUSE_STOP);
  426. BIND_ENUM_CONSTANT(TWEEN_PAUSE_PROCESS);
  427. BIND_ENUM_CONSTANT(TRANS_LINEAR);
  428. BIND_ENUM_CONSTANT(TRANS_SINE);
  429. BIND_ENUM_CONSTANT(TRANS_QUINT);
  430. BIND_ENUM_CONSTANT(TRANS_QUART);
  431. BIND_ENUM_CONSTANT(TRANS_QUAD);
  432. BIND_ENUM_CONSTANT(TRANS_EXPO);
  433. BIND_ENUM_CONSTANT(TRANS_ELASTIC);
  434. BIND_ENUM_CONSTANT(TRANS_CUBIC);
  435. BIND_ENUM_CONSTANT(TRANS_CIRC);
  436. BIND_ENUM_CONSTANT(TRANS_BOUNCE);
  437. BIND_ENUM_CONSTANT(TRANS_BACK);
  438. BIND_ENUM_CONSTANT(TRANS_SPRING);
  439. BIND_ENUM_CONSTANT(EASE_IN);
  440. BIND_ENUM_CONSTANT(EASE_OUT);
  441. BIND_ENUM_CONSTANT(EASE_IN_OUT);
  442. BIND_ENUM_CONSTANT(EASE_OUT_IN);
  443. }
  444. Tween::Tween() {
  445. ERR_FAIL_MSG("Tween can't be created directly. Use create_tween() method.");
  446. }
  447. Tween::Tween(SceneTree *p_parent_tree) {
  448. parent_tree = p_parent_tree;
  449. valid = true;
  450. }
  451. double PropertyTweener::_get_custom_interpolated_value(const Variant &p_value) {
  452. const Variant *argptr = &p_value;
  453. Variant result;
  454. Callable::CallError ce;
  455. custom_method.callp(&argptr, 1, result, ce);
  456. if (ce.error != Callable::CallError::CALL_OK) {
  457. ERR_FAIL_V_MSG(false, "Error calling custom method from PropertyTweener: " + Variant::get_callable_error_text(custom_method, &argptr, 1, ce) + ".");
  458. } else if (result.get_type() != Variant::FLOAT) {
  459. ERR_FAIL_V_MSG(false, vformat("Wrong return type in PropertyTweener custom method. Expected float, got %s.", Variant::get_type_name(result.get_type())));
  460. }
  461. return result;
  462. }
  463. RequiredResult<PropertyTweener> PropertyTweener::from(const Variant &p_value) {
  464. Ref<Tween> tween = _get_tween();
  465. ERR_FAIL_COND_V(tween.is_null(), nullptr);
  466. Variant from_value = p_value;
  467. if (!Animation::validate_type_match(final_val, from_value)) {
  468. return nullptr;
  469. }
  470. initial_val = from_value;
  471. do_continue = false;
  472. return this;
  473. }
  474. RequiredResult<PropertyTweener> PropertyTweener::from_current() {
  475. do_continue = false;
  476. return this;
  477. }
  478. RequiredResult<PropertyTweener> PropertyTweener::as_relative() {
  479. relative = true;
  480. return this;
  481. }
  482. RequiredResult<PropertyTweener> PropertyTweener::set_trans(Tween::TransitionType p_trans) {
  483. trans_type = p_trans;
  484. return this;
  485. }
  486. RequiredResult<PropertyTweener> PropertyTweener::set_ease(Tween::EaseType p_ease) {
  487. ease_type = p_ease;
  488. return this;
  489. }
  490. RequiredResult<PropertyTweener> PropertyTweener::set_custom_interpolator(const Callable &p_method) {
  491. custom_method = p_method;
  492. return this;
  493. }
  494. RequiredResult<PropertyTweener> PropertyTweener::set_delay(double p_delay) {
  495. delay = p_delay;
  496. return this;
  497. }
  498. void PropertyTweener::start() {
  499. Tweener::start();
  500. Object *target_instance = ObjectDB::get_instance(target);
  501. if (!target_instance) {
  502. return;
  503. }
  504. if (do_continue) {
  505. if (Math::is_zero_approx(delay)) {
  506. initial_val = target_instance->get_indexed(property);
  507. } else {
  508. do_continue_delayed = true;
  509. }
  510. }
  511. if (relative) {
  512. final_val = Animation::add_variant(initial_val, base_final_val);
  513. }
  514. delta_val = Animation::subtract_variant(final_val, initial_val);
  515. }
  516. bool PropertyTweener::step(double &r_delta) {
  517. if (finished) {
  518. // This is needed in case there's a parallel Tweener with longer duration.
  519. return false;
  520. }
  521. Object *target_instance = ObjectDB::get_instance(target);
  522. if (!target_instance) {
  523. _finish();
  524. return false;
  525. }
  526. elapsed_time += r_delta;
  527. if (elapsed_time < delay) {
  528. r_delta = 0;
  529. return true;
  530. } else if (do_continue_delayed && !Math::is_zero_approx(delay)) {
  531. initial_val = target_instance->get_indexed(property);
  532. delta_val = Animation::subtract_variant(final_val, initial_val);
  533. do_continue_delayed = false;
  534. }
  535. Ref<Tween> tween = _get_tween();
  536. double time = MIN(elapsed_time - delay, duration);
  537. if (time < duration) {
  538. if (custom_method.is_valid()) {
  539. const Variant t = tween->interpolate_variant(0.0, 1.0, time, duration, trans_type, ease_type);
  540. double result = _get_custom_interpolated_value(t);
  541. target_instance->set_indexed(property, Animation::interpolate_variant(initial_val, final_val, result));
  542. } else {
  543. target_instance->set_indexed(property, tween->interpolate_variant(initial_val, delta_val, time, duration, trans_type, ease_type));
  544. }
  545. r_delta = 0;
  546. return true;
  547. } else {
  548. if (custom_method.is_valid()) {
  549. double final_t = _get_custom_interpolated_value(1.0);
  550. target_instance->set_indexed(property, Animation::interpolate_variant(initial_val, final_val, final_t));
  551. } else {
  552. target_instance->set_indexed(property, final_val);
  553. }
  554. r_delta = elapsed_time - delay - duration;
  555. _finish();
  556. return false;
  557. }
  558. }
  559. void PropertyTweener::set_tween(const Ref<Tween> &p_tween) {
  560. Tweener::set_tween(p_tween);
  561. if (trans_type == Tween::TRANS_MAX) {
  562. trans_type = p_tween->get_trans();
  563. }
  564. if (ease_type == Tween::EASE_MAX) {
  565. ease_type = p_tween->get_ease();
  566. }
  567. }
  568. void PropertyTweener::_bind_methods() {
  569. ClassDB::bind_method(D_METHOD("from", "value"), &PropertyTweener::from);
  570. ClassDB::bind_method(D_METHOD("from_current"), &PropertyTweener::from_current);
  571. ClassDB::bind_method(D_METHOD("as_relative"), &PropertyTweener::as_relative);
  572. ClassDB::bind_method(D_METHOD("set_trans", "trans"), &PropertyTweener::set_trans);
  573. ClassDB::bind_method(D_METHOD("set_ease", "ease"), &PropertyTweener::set_ease);
  574. ClassDB::bind_method(D_METHOD("set_custom_interpolator", "interpolator_method"), &PropertyTweener::set_custom_interpolator);
  575. ClassDB::bind_method(D_METHOD("set_delay", "delay"), &PropertyTweener::set_delay);
  576. }
  577. PropertyTweener::PropertyTweener(const Object *p_target, const Vector<StringName> &p_property, const Variant &p_to, double p_duration) {
  578. target = p_target->get_instance_id();
  579. property = p_property;
  580. initial_val = p_target->get_indexed(property);
  581. base_final_val = p_to;
  582. final_val = base_final_val;
  583. duration = p_duration;
  584. if (p_target->is_ref_counted()) {
  585. ref_copy = p_target;
  586. }
  587. }
  588. PropertyTweener::PropertyTweener() {
  589. ERR_FAIL_MSG("PropertyTweener can't be created directly. Use the tween_property() method in Tween.");
  590. }
  591. bool IntervalTweener::step(double &r_delta) {
  592. if (finished) {
  593. return false;
  594. }
  595. elapsed_time += r_delta;
  596. if (elapsed_time < duration) {
  597. r_delta = 0;
  598. return true;
  599. } else {
  600. r_delta = elapsed_time - duration;
  601. _finish();
  602. return false;
  603. }
  604. }
  605. IntervalTweener::IntervalTweener(double p_time) {
  606. duration = p_time;
  607. }
  608. IntervalTweener::IntervalTweener() {
  609. ERR_FAIL_MSG("IntervalTweener can't be created directly. Use the tween_interval() method in Tween.");
  610. }
  611. RequiredResult<CallbackTweener> CallbackTweener::set_delay(double p_delay) {
  612. delay = p_delay;
  613. return this;
  614. }
  615. bool CallbackTweener::step(double &r_delta) {
  616. if (finished) {
  617. return false;
  618. }
  619. if (!callback.is_valid()) {
  620. _finish();
  621. return false;
  622. }
  623. elapsed_time += r_delta;
  624. if (elapsed_time >= delay) {
  625. Variant result;
  626. Callable::CallError ce;
  627. callback.callp(nullptr, 0, result, ce);
  628. if (ce.error != Callable::CallError::CALL_OK) {
  629. ERR_FAIL_V_MSG(false, "Error calling method from CallbackTweener: " + Variant::get_callable_error_text(callback, nullptr, 0, ce) + ".");
  630. }
  631. r_delta = elapsed_time - delay;
  632. _finish();
  633. return false;
  634. }
  635. r_delta = 0;
  636. return true;
  637. }
  638. void CallbackTweener::_bind_methods() {
  639. ClassDB::bind_method(D_METHOD("set_delay", "delay"), &CallbackTweener::set_delay);
  640. }
  641. CallbackTweener::CallbackTweener(const Callable &p_callback) {
  642. callback = p_callback;
  643. Object *callback_instance = p_callback.get_object();
  644. if (callback_instance && callback_instance->is_ref_counted()) {
  645. ref_copy = callback_instance;
  646. }
  647. }
  648. CallbackTweener::CallbackTweener() {
  649. ERR_FAIL_MSG("CallbackTweener can't be created directly. Use the tween_callback() method in Tween.");
  650. }
  651. RequiredResult<MethodTweener> MethodTweener::set_delay(double p_delay) {
  652. delay = p_delay;
  653. return this;
  654. }
  655. RequiredResult<MethodTweener> MethodTweener::set_trans(Tween::TransitionType p_trans) {
  656. trans_type = p_trans;
  657. return this;
  658. }
  659. RequiredResult<MethodTweener> MethodTweener::set_ease(Tween::EaseType p_ease) {
  660. ease_type = p_ease;
  661. return this;
  662. }
  663. bool MethodTweener::step(double &r_delta) {
  664. if (finished) {
  665. return false;
  666. }
  667. if (!callback.is_valid()) {
  668. _finish();
  669. return false;
  670. }
  671. elapsed_time += r_delta;
  672. if (elapsed_time < delay) {
  673. r_delta = 0;
  674. return true;
  675. }
  676. Ref<Tween> tween = _get_tween();
  677. Variant current_val;
  678. double time = MIN(elapsed_time - delay, duration);
  679. if (time < duration) {
  680. current_val = tween->interpolate_variant(initial_val, delta_val, time, duration, trans_type, ease_type);
  681. } else {
  682. current_val = final_val;
  683. }
  684. const Variant **argptr = (const Variant **)alloca(sizeof(Variant *));
  685. argptr[0] = &current_val;
  686. Variant result;
  687. Callable::CallError ce;
  688. callback.callp(argptr, 1, result, ce);
  689. if (ce.error != Callable::CallError::CALL_OK) {
  690. ERR_FAIL_V_MSG(false, "Error calling method from MethodTweener: " + Variant::get_callable_error_text(callback, argptr, 1, ce) + ".");
  691. }
  692. if (time < duration) {
  693. r_delta = 0;
  694. return true;
  695. } else {
  696. r_delta = elapsed_time - delay - duration;
  697. _finish();
  698. return false;
  699. }
  700. }
  701. void MethodTweener::set_tween(const Ref<Tween> &p_tween) {
  702. Tweener::set_tween(p_tween);
  703. if (trans_type == Tween::TRANS_MAX) {
  704. trans_type = p_tween->get_trans();
  705. }
  706. if (ease_type == Tween::EASE_MAX) {
  707. ease_type = p_tween->get_ease();
  708. }
  709. }
  710. void MethodTweener::_bind_methods() {
  711. ClassDB::bind_method(D_METHOD("set_delay", "delay"), &MethodTweener::set_delay);
  712. ClassDB::bind_method(D_METHOD("set_trans", "trans"), &MethodTweener::set_trans);
  713. ClassDB::bind_method(D_METHOD("set_ease", "ease"), &MethodTweener::set_ease);
  714. }
  715. MethodTweener::MethodTweener(const Callable &p_callback, const Variant &p_from, const Variant &p_to, double p_duration) {
  716. callback = p_callback;
  717. initial_val = p_from;
  718. delta_val = Animation::subtract_variant(p_to, p_from);
  719. final_val = p_to;
  720. duration = p_duration;
  721. Object *callback_instance = p_callback.get_object();
  722. if (callback_instance && callback_instance->is_ref_counted()) {
  723. ref_copy = callback_instance;
  724. }
  725. }
  726. MethodTweener::MethodTweener() {
  727. ERR_FAIL_MSG("MethodTweener can't be created directly. Use the tween_method() method in Tween.");
  728. }
  729. void SubtweenTweener::start() {
  730. Tweener::start();
  731. // Reset the subtween.
  732. subtween->stop();
  733. // It's possible that a subtween could be killed before it is started;
  734. // if so, we just want to skip it entirely.
  735. if (subtween->is_valid()) {
  736. subtween->play();
  737. } else {
  738. _finish();
  739. }
  740. }
  741. bool SubtweenTweener::step(double &r_delta) {
  742. if (finished) {
  743. return false;
  744. }
  745. elapsed_time += r_delta;
  746. if (elapsed_time < delay) {
  747. r_delta = 0;
  748. return true;
  749. }
  750. if (!subtween->step(r_delta)) {
  751. r_delta = elapsed_time - delay - subtween->get_total_time();
  752. _finish();
  753. return false;
  754. }
  755. r_delta = 0;
  756. return true;
  757. }
  758. RequiredResult<SubtweenTweener> SubtweenTweener::set_delay(double p_delay) {
  759. delay = p_delay;
  760. return this;
  761. }
  762. void SubtweenTweener::_bind_methods() {
  763. ClassDB::bind_method(D_METHOD("set_delay", "delay"), &SubtweenTweener::set_delay);
  764. }
  765. SubtweenTweener::SubtweenTweener(const Ref<Tween> &p_subtween) {
  766. subtween = p_subtween;
  767. }
  768. SubtweenTweener::SubtweenTweener() {
  769. ERR_FAIL_MSG("SubtweenTweener can't be created directly. Use the tween_subtween() method in Tween.");
  770. }