tween.cpp 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789
  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. Tween::interpolater Tween::interpolaters[Tween::TRANS_MAX][Tween::EASE_MAX] = {
  35. { &linear::in, &linear::in, &linear::in, &linear::in }, // Linear is the same for each easing.
  36. { &sine::in, &sine::out, &sine::in_out, &sine::out_in },
  37. { &quint::in, &quint::out, &quint::in_out, &quint::out_in },
  38. { &quart::in, &quart::out, &quart::in_out, &quart::out_in },
  39. { &quad::in, &quad::out, &quad::in_out, &quad::out_in },
  40. { &expo::in, &expo::out, &expo::in_out, &expo::out_in },
  41. { &elastic::in, &elastic::out, &elastic::in_out, &elastic::out_in },
  42. { &cubic::in, &cubic::out, &cubic::in_out, &cubic::out_in },
  43. { &circ::in, &circ::out, &circ::in_out, &circ::out_in },
  44. { &bounce::in, &bounce::out, &bounce::in_out, &bounce::out_in },
  45. { &back::in, &back::out, &back::in_out, &back::out_in },
  46. };
  47. void Tweener::set_tween(Ref<Tween> p_tween) {
  48. tween = p_tween;
  49. }
  50. void Tweener::clear_tween() {
  51. tween.unref();
  52. }
  53. void Tweener::_bind_methods() {
  54. ADD_SIGNAL(MethodInfo("finished"));
  55. }
  56. bool Tween::_validate_type_match(const Variant &p_from, Variant &r_to) {
  57. if (p_from.get_type() != r_to.get_type()) {
  58. // Cast r_to between double and int to avoid minor annoyances.
  59. if (p_from.get_type() == Variant::FLOAT && r_to.get_type() == Variant::INT) {
  60. r_to = double(r_to);
  61. } else if (p_from.get_type() == Variant::INT && r_to.get_type() == Variant::FLOAT) {
  62. r_to = int(r_to);
  63. } else {
  64. ERR_FAIL_V_MSG(false, "Type mismatch between initial and final value: " + Variant::get_type_name(p_from.get_type()) + " and " + Variant::get_type_name(r_to.get_type()));
  65. }
  66. }
  67. return true;
  68. }
  69. void Tween::_start_tweeners() {
  70. if (tweeners.is_empty()) {
  71. dead = true;
  72. ERR_FAIL_MSG("Tween without commands, aborting.");
  73. }
  74. for (Ref<Tweener> &tweener : tweeners.write[current_step]) {
  75. tweener->start();
  76. }
  77. }
  78. void Tween::_stop_internal(bool p_reset) {
  79. running = false;
  80. if (p_reset) {
  81. started = false;
  82. dead = false;
  83. total_time = 0;
  84. }
  85. }
  86. Ref<PropertyTweener> Tween::tween_property(Object *p_target, NodePath p_property, Variant p_to, double p_duration) {
  87. ERR_FAIL_NULL_V(p_target, nullptr);
  88. ERR_FAIL_COND_V_MSG(!valid, nullptr, "Tween invalid. Either finished or created outside scene tree.");
  89. ERR_FAIL_COND_V_MSG(started, nullptr, "Can't append to a Tween that has started. Use stop() first.");
  90. if (!_validate_type_match(p_target->get_indexed(p_property.get_as_property_path().get_subnames()), p_to)) {
  91. return nullptr;
  92. }
  93. Ref<PropertyTweener> tweener = memnew(PropertyTweener(p_target, p_property, p_to, p_duration));
  94. append(tweener);
  95. return tweener;
  96. }
  97. Ref<IntervalTweener> Tween::tween_interval(double p_time) {
  98. ERR_FAIL_COND_V_MSG(!valid, nullptr, "Tween invalid. Either finished or created outside scene tree.");
  99. ERR_FAIL_COND_V_MSG(started, nullptr, "Can't append to a Tween that has started. Use stop() first.");
  100. Ref<IntervalTweener> tweener = memnew(IntervalTweener(p_time));
  101. append(tweener);
  102. return tweener;
  103. }
  104. Ref<CallbackTweener> Tween::tween_callback(Callable p_callback) {
  105. ERR_FAIL_COND_V_MSG(!valid, nullptr, "Tween invalid. Either finished or created outside scene tree.");
  106. ERR_FAIL_COND_V_MSG(started, nullptr, "Can't append to a Tween that has started. Use stop() first.");
  107. Ref<CallbackTweener> tweener = memnew(CallbackTweener(p_callback));
  108. append(tweener);
  109. return tweener;
  110. }
  111. Ref<MethodTweener> Tween::tween_method(Callable p_callback, Variant p_from, Variant p_to, double p_duration) {
  112. ERR_FAIL_COND_V_MSG(!valid, nullptr, "Tween invalid. Either finished or created outside scene tree.");
  113. ERR_FAIL_COND_V_MSG(started, nullptr, "Can't append to a Tween that has started. Use stop() first.");
  114. if (!_validate_type_match(p_from, p_to)) {
  115. return nullptr;
  116. }
  117. Ref<MethodTweener> tweener = memnew(MethodTweener(p_callback, p_from, p_to, p_duration));
  118. append(tweener);
  119. return tweener;
  120. }
  121. void Tween::append(Ref<Tweener> p_tweener) {
  122. p_tweener->set_tween(this);
  123. if (parallel_enabled) {
  124. current_step = MAX(current_step, 0);
  125. } else {
  126. current_step++;
  127. }
  128. parallel_enabled = default_parallel;
  129. tweeners.resize(current_step + 1);
  130. tweeners.write[current_step].push_back(p_tweener);
  131. }
  132. void Tween::stop() {
  133. _stop_internal(true);
  134. }
  135. void Tween::pause() {
  136. _stop_internal(false);
  137. }
  138. void Tween::play() {
  139. ERR_FAIL_COND_MSG(!valid, "Tween invalid. Either finished or created outside scene tree.");
  140. ERR_FAIL_COND_MSG(dead, "Can't play finished Tween, use stop() first to reset its state.");
  141. running = true;
  142. }
  143. void Tween::kill() {
  144. running = false; // For the sake of is_running().
  145. dead = true;
  146. }
  147. bool Tween::is_running() {
  148. return running;
  149. }
  150. bool Tween::is_valid() {
  151. return valid;
  152. }
  153. void Tween::clear() {
  154. valid = false;
  155. for (List<Ref<Tweener>> &step : tweeners) {
  156. for (Ref<Tweener> &tweener : step) {
  157. tweener->clear_tween();
  158. }
  159. }
  160. tweeners.clear();
  161. }
  162. Ref<Tween> Tween::bind_node(Node *p_node) {
  163. ERR_FAIL_NULL_V(p_node, this);
  164. bound_node = p_node->get_instance_id();
  165. is_bound = true;
  166. return this;
  167. }
  168. Ref<Tween> Tween::set_process_mode(TweenProcessMode p_mode) {
  169. process_mode = p_mode;
  170. return this;
  171. }
  172. Tween::TweenProcessMode Tween::get_process_mode() {
  173. return process_mode;
  174. }
  175. Ref<Tween> Tween::set_pause_mode(TweenPauseMode p_mode) {
  176. pause_mode = p_mode;
  177. return this;
  178. }
  179. Tween::TweenPauseMode Tween::get_pause_mode() {
  180. return pause_mode;
  181. }
  182. Ref<Tween> Tween::set_parallel(bool p_parallel) {
  183. default_parallel = p_parallel;
  184. parallel_enabled = p_parallel;
  185. return this;
  186. }
  187. Ref<Tween> Tween::set_loops(int p_loops) {
  188. loops = p_loops;
  189. return this;
  190. }
  191. Ref<Tween> Tween::set_speed_scale(float p_speed) {
  192. speed_scale = p_speed;
  193. return this;
  194. }
  195. Ref<Tween> Tween::set_trans(TransitionType p_trans) {
  196. default_transition = p_trans;
  197. return this;
  198. }
  199. Tween::TransitionType Tween::get_trans() {
  200. return default_transition;
  201. }
  202. Ref<Tween> Tween::set_ease(EaseType p_ease) {
  203. default_ease = p_ease;
  204. return this;
  205. }
  206. Tween::EaseType Tween::get_ease() {
  207. return default_ease;
  208. }
  209. Ref<Tween> Tween::parallel() {
  210. parallel_enabled = true;
  211. return this;
  212. }
  213. Ref<Tween> Tween::chain() {
  214. parallel_enabled = false;
  215. return this;
  216. }
  217. bool Tween::custom_step(double p_delta) {
  218. bool r = running;
  219. running = true;
  220. bool ret = step(p_delta);
  221. running = running && r; // Running might turn false when Tween finished.
  222. return ret;
  223. }
  224. bool Tween::step(double p_delta) {
  225. if (dead) {
  226. return false;
  227. }
  228. if (!running) {
  229. return true;
  230. }
  231. if (is_bound) {
  232. Node *node = get_bound_node();
  233. if (node) {
  234. if (!node->is_inside_tree()) {
  235. return true;
  236. }
  237. } else {
  238. return false;
  239. }
  240. }
  241. if (!started) {
  242. if (tweeners.is_empty()) {
  243. String tween_id;
  244. Node *node = get_bound_node();
  245. if (node) {
  246. tween_id = vformat("Tween (bound to %s)", node->is_inside_tree() ? (String)node->get_path() : (String)node->get_name());
  247. } else {
  248. tween_id = to_string();
  249. }
  250. ERR_FAIL_V_MSG(false, tween_id + ": started with no Tweeners.");
  251. }
  252. current_step = 0;
  253. loops_done = 0;
  254. total_time = 0;
  255. _start_tweeners();
  256. started = true;
  257. }
  258. double rem_delta = p_delta * speed_scale;
  259. bool step_active = false;
  260. total_time += rem_delta;
  261. #ifdef DEBUG_ENABLED
  262. double initial_delta = rem_delta;
  263. bool potential_infinite = false;
  264. #endif
  265. while (rem_delta > 0 && running) {
  266. double step_delta = rem_delta;
  267. step_active = false;
  268. for (Ref<Tweener> &tweener : tweeners.write[current_step]) {
  269. // Modified inside Tweener.step().
  270. double temp_delta = rem_delta;
  271. // Turns to true if any Tweener returns true (i.e. is still not finished).
  272. step_active = tweener->step(temp_delta) || step_active;
  273. step_delta = MIN(temp_delta, step_delta);
  274. }
  275. rem_delta = step_delta;
  276. if (!step_active) {
  277. emit_signal(SNAME("step_finished"), current_step);
  278. current_step++;
  279. if (current_step == tweeners.size()) {
  280. loops_done++;
  281. if (loops_done == loops) {
  282. running = false;
  283. dead = true;
  284. emit_signal(SNAME("finished"));
  285. break;
  286. } else {
  287. emit_signal(SNAME("loop_finished"), loops_done);
  288. current_step = 0;
  289. _start_tweeners();
  290. #ifdef DEBUG_ENABLED
  291. if (loops <= 0 && Math::is_equal_approx(rem_delta, initial_delta)) {
  292. if (!potential_infinite) {
  293. potential_infinite = true;
  294. } else {
  295. // Looped twice without using any time, this is 100% certain infinite loop.
  296. ERR_FAIL_V_MSG(false, "Infinite loop detected. Check set_loops() description for more info.");
  297. }
  298. }
  299. #endif
  300. }
  301. } else {
  302. _start_tweeners();
  303. }
  304. }
  305. }
  306. return true;
  307. }
  308. bool Tween::can_process(bool p_tree_paused) const {
  309. if (is_bound && pause_mode == TWEEN_PAUSE_BOUND) {
  310. Node *node = get_bound_node();
  311. if (node) {
  312. return node->is_inside_tree() && node->can_process();
  313. }
  314. }
  315. return !p_tree_paused || pause_mode == TWEEN_PAUSE_PROCESS;
  316. }
  317. Node *Tween::get_bound_node() const {
  318. if (is_bound) {
  319. return Object::cast_to<Node>(ObjectDB::get_instance(bound_node));
  320. } else {
  321. return nullptr;
  322. }
  323. }
  324. double Tween::get_total_time() const {
  325. return total_time;
  326. }
  327. 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) {
  328. if (p_duration == 0) {
  329. // Special case to avoid dividing by 0 in equations.
  330. return p_initial + p_delta;
  331. }
  332. interpolater func = interpolaters[p_trans_type][p_ease_type];
  333. return func(p_time, p_initial, p_delta, p_duration);
  334. }
  335. Variant Tween::interpolate_variant(Variant p_initial_val, Variant p_delta_val, double p_time, double p_duration, TransitionType p_trans, EaseType p_ease) {
  336. ERR_FAIL_INDEX_V(p_trans, TransitionType::TRANS_MAX, Variant());
  337. ERR_FAIL_INDEX_V(p_ease, EaseType::EASE_MAX, Variant());
  338. // Special case for bool.
  339. if (p_initial_val.get_type() == Variant::BOOL) {
  340. return run_equation(p_trans, p_ease, p_time, p_initial_val, p_delta_val, p_duration) >= 0.5;
  341. }
  342. Variant ret = Animation::add_variant(p_initial_val, p_delta_val);
  343. ret = Animation::interpolate_variant(p_initial_val, ret, run_equation(p_trans, p_ease, p_time, 0.0, 1.0, p_duration));
  344. return ret;
  345. }
  346. String Tween::to_string() {
  347. String ret = Object::to_string();
  348. Node *node = get_bound_node();
  349. if (node) {
  350. ret += vformat(" (bound to %s)", node->get_name());
  351. }
  352. return ret;
  353. }
  354. void Tween::_bind_methods() {
  355. ClassDB::bind_method(D_METHOD("tween_property", "object", "property", "final_val", "duration"), &Tween::tween_property);
  356. ClassDB::bind_method(D_METHOD("tween_interval", "time"), &Tween::tween_interval);
  357. ClassDB::bind_method(D_METHOD("tween_callback", "callback"), &Tween::tween_callback);
  358. ClassDB::bind_method(D_METHOD("tween_method", "method", "from", "to", "duration"), &Tween::tween_method);
  359. ClassDB::bind_method(D_METHOD("custom_step", "delta"), &Tween::custom_step);
  360. ClassDB::bind_method(D_METHOD("stop"), &Tween::stop);
  361. ClassDB::bind_method(D_METHOD("pause"), &Tween::pause);
  362. ClassDB::bind_method(D_METHOD("play"), &Tween::play);
  363. ClassDB::bind_method(D_METHOD("kill"), &Tween::kill);
  364. ClassDB::bind_method(D_METHOD("get_total_elapsed_time"), &Tween::get_total_time);
  365. ClassDB::bind_method(D_METHOD("is_running"), &Tween::is_running);
  366. ClassDB::bind_method(D_METHOD("is_valid"), &Tween::is_valid);
  367. ClassDB::bind_method(D_METHOD("bind_node", "node"), &Tween::bind_node);
  368. ClassDB::bind_method(D_METHOD("set_process_mode", "mode"), &Tween::set_process_mode);
  369. ClassDB::bind_method(D_METHOD("set_pause_mode", "mode"), &Tween::set_pause_mode);
  370. ClassDB::bind_method(D_METHOD("set_parallel", "parallel"), &Tween::set_parallel, DEFVAL(true));
  371. ClassDB::bind_method(D_METHOD("set_loops", "loops"), &Tween::set_loops, DEFVAL(0));
  372. ClassDB::bind_method(D_METHOD("set_speed_scale", "speed"), &Tween::set_speed_scale);
  373. ClassDB::bind_method(D_METHOD("set_trans", "trans"), &Tween::set_trans);
  374. ClassDB::bind_method(D_METHOD("set_ease", "ease"), &Tween::set_ease);
  375. ClassDB::bind_method(D_METHOD("parallel"), &Tween::parallel);
  376. ClassDB::bind_method(D_METHOD("chain"), &Tween::chain);
  377. ClassDB::bind_static_method("Tween", D_METHOD("interpolate_value", "initial_value", "delta_value", "elapsed_time", "duration", "trans_type", "ease_type"), &Tween::interpolate_variant);
  378. ADD_SIGNAL(MethodInfo("step_finished", PropertyInfo(Variant::INT, "idx")));
  379. ADD_SIGNAL(MethodInfo("loop_finished", PropertyInfo(Variant::INT, "loop_count")));
  380. ADD_SIGNAL(MethodInfo("finished"));
  381. BIND_ENUM_CONSTANT(TWEEN_PROCESS_PHYSICS);
  382. BIND_ENUM_CONSTANT(TWEEN_PROCESS_IDLE);
  383. BIND_ENUM_CONSTANT(TWEEN_PAUSE_BOUND);
  384. BIND_ENUM_CONSTANT(TWEEN_PAUSE_STOP);
  385. BIND_ENUM_CONSTANT(TWEEN_PAUSE_PROCESS);
  386. BIND_ENUM_CONSTANT(TRANS_LINEAR);
  387. BIND_ENUM_CONSTANT(TRANS_SINE);
  388. BIND_ENUM_CONSTANT(TRANS_QUINT);
  389. BIND_ENUM_CONSTANT(TRANS_QUART);
  390. BIND_ENUM_CONSTANT(TRANS_QUAD);
  391. BIND_ENUM_CONSTANT(TRANS_EXPO);
  392. BIND_ENUM_CONSTANT(TRANS_ELASTIC);
  393. BIND_ENUM_CONSTANT(TRANS_CUBIC);
  394. BIND_ENUM_CONSTANT(TRANS_CIRC);
  395. BIND_ENUM_CONSTANT(TRANS_BOUNCE);
  396. BIND_ENUM_CONSTANT(TRANS_BACK);
  397. BIND_ENUM_CONSTANT(EASE_IN);
  398. BIND_ENUM_CONSTANT(EASE_OUT);
  399. BIND_ENUM_CONSTANT(EASE_IN_OUT);
  400. BIND_ENUM_CONSTANT(EASE_OUT_IN);
  401. }
  402. Tween::Tween() {
  403. ERR_FAIL_MSG("Tween can't be created directly. Use create_tween() method.");
  404. }
  405. Tween::Tween(bool p_valid) {
  406. valid = p_valid;
  407. }
  408. Ref<PropertyTweener> PropertyTweener::from(Variant p_value) {
  409. ERR_FAIL_COND_V(tween.is_null(), nullptr);
  410. if (!tween->_validate_type_match(p_value, final_val)) {
  411. return nullptr;
  412. }
  413. initial_val = p_value;
  414. do_continue = false;
  415. return this;
  416. }
  417. Ref<PropertyTweener> PropertyTweener::from_current() {
  418. do_continue = false;
  419. return this;
  420. }
  421. Ref<PropertyTweener> PropertyTweener::as_relative() {
  422. relative = true;
  423. return this;
  424. }
  425. Ref<PropertyTweener> PropertyTweener::set_trans(Tween::TransitionType p_trans) {
  426. trans_type = p_trans;
  427. return this;
  428. }
  429. Ref<PropertyTweener> PropertyTweener::set_ease(Tween::EaseType p_ease) {
  430. ease_type = p_ease;
  431. return this;
  432. }
  433. Ref<PropertyTweener> PropertyTweener::set_delay(double p_delay) {
  434. delay = p_delay;
  435. return this;
  436. }
  437. void PropertyTweener::start() {
  438. elapsed_time = 0;
  439. finished = false;
  440. Object *target_instance = ObjectDB::get_instance(target);
  441. if (!target_instance) {
  442. WARN_PRINT("Target object freed before starting, aborting Tweener.");
  443. return;
  444. }
  445. if (do_continue) {
  446. initial_val = target_instance->get_indexed(property);
  447. }
  448. if (relative) {
  449. final_val = Animation::add_variant(initial_val, base_final_val);
  450. }
  451. delta_val = Animation::subtract_variant(final_val, initial_val);
  452. }
  453. bool PropertyTweener::step(double &r_delta) {
  454. if (finished) {
  455. // This is needed in case there's a parallel Tweener with longer duration.
  456. return false;
  457. }
  458. Object *target_instance = ObjectDB::get_instance(target);
  459. if (!target_instance) {
  460. return false;
  461. }
  462. elapsed_time += r_delta;
  463. if (elapsed_time < delay) {
  464. r_delta = 0;
  465. return true;
  466. }
  467. double time = MIN(elapsed_time - delay, duration);
  468. if (time < duration) {
  469. target_instance->set_indexed(property, tween->interpolate_variant(initial_val, delta_val, time, duration, trans_type, ease_type));
  470. r_delta = 0;
  471. return true;
  472. } else {
  473. target_instance->set_indexed(property, final_val);
  474. finished = true;
  475. r_delta = elapsed_time - delay - duration;
  476. emit_signal(SNAME("finished"));
  477. return false;
  478. }
  479. }
  480. void PropertyTweener::set_tween(Ref<Tween> p_tween) {
  481. tween = p_tween;
  482. if (trans_type == Tween::TRANS_MAX) {
  483. trans_type = tween->get_trans();
  484. }
  485. if (ease_type == Tween::EASE_MAX) {
  486. ease_type = tween->get_ease();
  487. }
  488. }
  489. void PropertyTweener::_bind_methods() {
  490. ClassDB::bind_method(D_METHOD("from", "value"), &PropertyTweener::from);
  491. ClassDB::bind_method(D_METHOD("from_current"), &PropertyTweener::from_current);
  492. ClassDB::bind_method(D_METHOD("as_relative"), &PropertyTweener::as_relative);
  493. ClassDB::bind_method(D_METHOD("set_trans", "trans"), &PropertyTweener::set_trans);
  494. ClassDB::bind_method(D_METHOD("set_ease", "ease"), &PropertyTweener::set_ease);
  495. ClassDB::bind_method(D_METHOD("set_delay", "delay"), &PropertyTweener::set_delay);
  496. }
  497. PropertyTweener::PropertyTweener(Object *p_target, NodePath p_property, Variant p_to, double p_duration) {
  498. target = p_target->get_instance_id();
  499. property = p_property.get_as_property_path().get_subnames();
  500. initial_val = p_target->get_indexed(property);
  501. base_final_val = p_to;
  502. final_val = base_final_val;
  503. duration = p_duration;
  504. if (p_target->is_ref_counted()) {
  505. ref_copy = p_target;
  506. }
  507. }
  508. PropertyTweener::PropertyTweener() {
  509. ERR_FAIL_MSG("PropertyTweener can't be created directly. Use the tween_property() method in Tween.");
  510. }
  511. void IntervalTweener::start() {
  512. elapsed_time = 0;
  513. finished = false;
  514. }
  515. bool IntervalTweener::step(double &r_delta) {
  516. if (finished) {
  517. return false;
  518. }
  519. elapsed_time += r_delta;
  520. if (elapsed_time < duration) {
  521. r_delta = 0;
  522. return true;
  523. } else {
  524. finished = true;
  525. r_delta = elapsed_time - duration;
  526. emit_signal(SNAME("finished"));
  527. return false;
  528. }
  529. }
  530. IntervalTweener::IntervalTweener(double p_time) {
  531. duration = p_time;
  532. }
  533. IntervalTweener::IntervalTweener() {
  534. ERR_FAIL_MSG("IntervalTweener can't be created directly. Use the tween_interval() method in Tween.");
  535. }
  536. Ref<CallbackTweener> CallbackTweener::set_delay(double p_delay) {
  537. delay = p_delay;
  538. return this;
  539. }
  540. void CallbackTweener::start() {
  541. elapsed_time = 0;
  542. finished = false;
  543. }
  544. bool CallbackTweener::step(double &r_delta) {
  545. if (finished) {
  546. return false;
  547. }
  548. elapsed_time += r_delta;
  549. if (elapsed_time >= delay) {
  550. Variant result;
  551. Callable::CallError ce;
  552. callback.callp(nullptr, 0, result, ce);
  553. if (ce.error != Callable::CallError::CALL_OK) {
  554. ERR_FAIL_V_MSG(false, "Error calling method from CallbackTweener: " + Variant::get_callable_error_text(callback, nullptr, 0, ce));
  555. }
  556. finished = true;
  557. r_delta = elapsed_time - delay;
  558. emit_signal(SNAME("finished"));
  559. return false;
  560. }
  561. r_delta = 0;
  562. return true;
  563. }
  564. void CallbackTweener::_bind_methods() {
  565. ClassDB::bind_method(D_METHOD("set_delay", "delay"), &CallbackTweener::set_delay);
  566. }
  567. CallbackTweener::CallbackTweener(Callable p_callback) {
  568. callback = p_callback;
  569. Object *callback_instance = p_callback.get_object();
  570. if (callback_instance && callback_instance->is_ref_counted()) {
  571. ref_copy = callback_instance;
  572. }
  573. }
  574. CallbackTweener::CallbackTweener() {
  575. ERR_FAIL_MSG("CallbackTweener can't be created directly. Use the tween_callback() method in Tween.");
  576. }
  577. Ref<MethodTweener> MethodTweener::set_delay(double p_delay) {
  578. delay = p_delay;
  579. return this;
  580. }
  581. Ref<MethodTweener> MethodTweener::set_trans(Tween::TransitionType p_trans) {
  582. trans_type = p_trans;
  583. return this;
  584. }
  585. Ref<MethodTweener> MethodTweener::set_ease(Tween::EaseType p_ease) {
  586. ease_type = p_ease;
  587. return this;
  588. }
  589. void MethodTweener::start() {
  590. elapsed_time = 0;
  591. finished = false;
  592. }
  593. bool MethodTweener::step(double &r_delta) {
  594. if (finished) {
  595. return false;
  596. }
  597. elapsed_time += r_delta;
  598. if (elapsed_time < delay) {
  599. r_delta = 0;
  600. return true;
  601. }
  602. Variant current_val;
  603. double time = MIN(elapsed_time - delay, duration);
  604. if (time < duration) {
  605. current_val = tween->interpolate_variant(initial_val, delta_val, time, duration, trans_type, ease_type);
  606. } else {
  607. current_val = final_val;
  608. }
  609. const Variant **argptr = (const Variant **)alloca(sizeof(Variant *));
  610. argptr[0] = &current_val;
  611. Variant result;
  612. Callable::CallError ce;
  613. callback.callp(argptr, 1, result, ce);
  614. if (ce.error != Callable::CallError::CALL_OK) {
  615. ERR_FAIL_V_MSG(false, "Error calling method from MethodTweener: " + Variant::get_callable_error_text(callback, argptr, 1, ce));
  616. }
  617. if (time < duration) {
  618. r_delta = 0;
  619. return true;
  620. } else {
  621. finished = true;
  622. r_delta = elapsed_time - delay - duration;
  623. emit_signal(SNAME("finished"));
  624. return false;
  625. }
  626. }
  627. void MethodTweener::set_tween(Ref<Tween> p_tween) {
  628. tween = p_tween;
  629. if (trans_type == Tween::TRANS_MAX) {
  630. trans_type = tween->get_trans();
  631. }
  632. if (ease_type == Tween::EASE_MAX) {
  633. ease_type = tween->get_ease();
  634. }
  635. }
  636. void MethodTweener::_bind_methods() {
  637. ClassDB::bind_method(D_METHOD("set_delay", "delay"), &MethodTweener::set_delay);
  638. ClassDB::bind_method(D_METHOD("set_trans", "trans"), &MethodTweener::set_trans);
  639. ClassDB::bind_method(D_METHOD("set_ease", "ease"), &MethodTweener::set_ease);
  640. }
  641. MethodTweener::MethodTweener(Callable p_callback, Variant p_from, Variant p_to, double p_duration) {
  642. callback = p_callback;
  643. initial_val = p_from;
  644. delta_val = Animation::subtract_variant(p_to, p_from);
  645. final_val = p_to;
  646. duration = p_duration;
  647. Object *callback_instance = p_callback.get_object();
  648. if (callback_instance && callback_instance->is_ref_counted()) {
  649. ref_copy = callback_instance;
  650. }
  651. }
  652. MethodTweener::MethodTweener() {
  653. ERR_FAIL_MSG("MethodTweener can't be created directly. Use the tween_method() method in Tween.");
  654. }