tween.cpp 24 KB

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