SpineAnimationState.cpp 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /******************************************************************************
  2. * Spine Runtimes License Agreement
  3. * Last updated April 5, 2025. Replaces all prior versions.
  4. *
  5. * Copyright (c) 2013-2025, Esoteric Software LLC
  6. *
  7. * Integration of the Spine Runtimes into software or otherwise creating
  8. * derivative works of the Spine Runtimes is permitted under the terms and
  9. * conditions of Section 2 of the Spine Editor License Agreement:
  10. * http://esotericsoftware.com/spine-editor-license
  11. *
  12. * Otherwise, it is permitted to integrate the Spine Runtimes into software
  13. * or otherwise create derivative works of the Spine Runtimes (collectively,
  14. * "Products"), provided that each user of the Products must obtain their own
  15. * Spine Editor license and redistribution of the Products in any form must
  16. * include this license and copyright notice.
  17. *
  18. * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
  19. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  20. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  21. * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
  22. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  23. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
  24. * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
  25. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  27. * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  28. *****************************************************************************/
  29. #include "SpineAnimationState.h"
  30. #include "SpineTrackEntry.h"
  31. void SpineAnimationState::_bind_methods() {
  32. ClassDB::bind_method(D_METHOD("update", "delta"), &SpineAnimationState::update, DEFVAL(0));
  33. ClassDB::bind_method(D_METHOD("apply", "skeleton"), &SpineAnimationState::apply);
  34. ClassDB::bind_method(D_METHOD("clear_tracks"), &SpineAnimationState::clear_tracks);
  35. ClassDB::bind_method(D_METHOD("clear_track"), &SpineAnimationState::clear_track);
  36. ClassDB::bind_method(D_METHOD("get_num_tracks"), &SpineAnimationState::get_num_tracks);
  37. ClassDB::bind_method(D_METHOD("set_animation", "animation_name", "loop", "track_id"), &SpineAnimationState::set_animation, DEFVAL(true), DEFVAL(0));
  38. ClassDB::bind_method(D_METHOD("add_animation", "animation_name", "delay", "loop", "track_id"), &SpineAnimationState::add_animation, DEFVAL(0), DEFVAL(true), DEFVAL(0));
  39. ClassDB::bind_method(D_METHOD("set_empty_animation", "track_id", "mix_duration"), &SpineAnimationState::set_empty_animation);
  40. ClassDB::bind_method(D_METHOD("add_empty_animation", "track_id", "mix_duration", "delay"), &SpineAnimationState::add_empty_animation);
  41. ClassDB::bind_method(D_METHOD("set_empty_animations", "mix_duration"), &SpineAnimationState::set_empty_animations);
  42. ClassDB::bind_method(D_METHOD("get_current", "track_id"), &SpineAnimationState::get_current);
  43. ClassDB::bind_method(D_METHOD("get_time_scale"), &SpineAnimationState::get_time_scale);
  44. ClassDB::bind_method(D_METHOD("set_time_scale", "time_scale"), &SpineAnimationState::set_time_scale);
  45. ClassDB::bind_method(D_METHOD("disable_queue"), &SpineAnimationState::disable_queue);
  46. ClassDB::bind_method(D_METHOD("enable_queue"), &SpineAnimationState::enable_queue);
  47. }
  48. SpineAnimationState::SpineAnimationState() : animation_state(nullptr), sprite(nullptr) {
  49. }
  50. SpineAnimationState::~SpineAnimationState() {
  51. delete animation_state;
  52. }
  53. void SpineAnimationState::set_spine_sprite(SpineSprite *_sprite) {
  54. delete animation_state;
  55. animation_state = nullptr;
  56. sprite = _sprite;
  57. if (!sprite || !sprite->get_skeleton_data_res().is_valid() || !sprite->get_skeleton_data_res()->is_skeleton_data_loaded()) return;
  58. animation_state = new spine::AnimationState(sprite->get_skeleton_data_res()->get_animation_state_data());
  59. }
  60. void SpineAnimationState::update(float delta) {
  61. SPINE_CHECK(animation_state, )
  62. animation_state->update(delta);
  63. }
  64. bool SpineAnimationState::apply(Ref<SpineSkeleton> skeleton) {
  65. SPINE_CHECK(animation_state, false)
  66. if (!skeleton->get_spine_object()) return false;
  67. return animation_state->apply(*(skeleton->get_spine_object()));
  68. }
  69. void SpineAnimationState::clear_tracks() {
  70. SPINE_CHECK(animation_state, )
  71. animation_state->clearTracks();
  72. }
  73. void SpineAnimationState::clear_track(int track_id) {
  74. SPINE_CHECK(animation_state, )
  75. animation_state->clearTrack(track_id);
  76. }
  77. int SpineAnimationState::get_num_tracks() {
  78. SPINE_CHECK(animation_state, 0)
  79. int highest_index = -1;
  80. for (int i = 0; i < animation_state->getTracks().size(); i++) {
  81. if (animation_state->getTracks()[i]) highest_index = i;
  82. }
  83. return highest_index + 1;
  84. }
  85. Ref<SpineTrackEntry> SpineAnimationState::set_animation(const String &animation_name, bool loop, int track) {
  86. SPINE_CHECK(animation_state, nullptr)
  87. auto skeleton_data = animation_state->getData()->getSkeletonData();
  88. auto animation = skeleton_data->findAnimation(animation_name.utf8().ptr());
  89. if (!animation) {
  90. ERR_PRINT(String("Can not find animation: ") + animation_name);
  91. return nullptr;
  92. }
  93. auto track_entry = animation_state->setAnimation(track, animation, loop);
  94. Ref<SpineTrackEntry> track_entry_ref(memnew(SpineTrackEntry));
  95. track_entry_ref->set_spine_object(sprite, track_entry);
  96. return track_entry_ref;
  97. }
  98. Ref<SpineTrackEntry> SpineAnimationState::add_animation(const String &animation_name, float delay, bool loop, int track) {
  99. SPINE_CHECK(animation_state, nullptr)
  100. auto skeleton_data = animation_state->getData()->getSkeletonData();
  101. auto animation = skeleton_data->findAnimation(animation_name.utf8().ptr());
  102. if (!animation) {
  103. ERR_PRINT(String("Can not find animation: ") + animation_name);
  104. return nullptr;
  105. }
  106. auto track_entry = animation_state->addAnimation(track, animation, loop, delay);
  107. Ref<SpineTrackEntry> track_entry_ref(memnew(SpineTrackEntry));
  108. track_entry_ref->set_spine_object(sprite, track_entry);
  109. return track_entry_ref;
  110. }
  111. Ref<SpineTrackEntry> SpineAnimationState::set_empty_animation(int track_id, float mix_duration) {
  112. SPINE_CHECK(animation_state, nullptr)
  113. auto track_entry = animation_state->setEmptyAnimation(track_id, mix_duration);
  114. Ref<SpineTrackEntry> track_entry_ref(memnew(SpineTrackEntry));
  115. track_entry_ref->set_spine_object(sprite, track_entry);
  116. return track_entry_ref;
  117. }
  118. Ref<SpineTrackEntry> SpineAnimationState::add_empty_animation(int track_id, float mix_duration, float delay) {
  119. SPINE_CHECK(animation_state, nullptr)
  120. auto track_entry = animation_state->addEmptyAnimation(track_id, mix_duration, delay);
  121. Ref<SpineTrackEntry> track_entry_ref(memnew(SpineTrackEntry));
  122. track_entry_ref->set_spine_object(sprite, track_entry);
  123. return track_entry_ref;
  124. }
  125. void SpineAnimationState::set_empty_animations(float mix_duration) {
  126. SPINE_CHECK(animation_state, )
  127. animation_state->setEmptyAnimations(mix_duration);
  128. }
  129. Ref<SpineTrackEntry> SpineAnimationState::get_current(int track_index) {
  130. SPINE_CHECK(animation_state, nullptr)
  131. auto track_entry = animation_state->getCurrent(track_index);
  132. if (!track_entry) return nullptr;
  133. Ref<SpineTrackEntry> track_entry_ref(memnew(SpineTrackEntry));
  134. track_entry_ref->set_spine_object(sprite, track_entry);
  135. return track_entry_ref;
  136. }
  137. float SpineAnimationState::get_time_scale() {
  138. SPINE_CHECK(animation_state, 0)
  139. return animation_state->getTimeScale();
  140. }
  141. void SpineAnimationState::set_time_scale(float time_scale) {
  142. SPINE_CHECK(animation_state, )
  143. animation_state->setTimeScale(time_scale);
  144. }
  145. void SpineAnimationState::disable_queue() {
  146. SPINE_CHECK(animation_state, )
  147. animation_state->disableQueue();
  148. }
  149. void SpineAnimationState::enable_queue() {
  150. SPINE_CHECK(animation_state, )
  151. animation_state->enableQueue();
  152. }