ScaleTimeline.cpp 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /******************************************************************************
  2. * Spine Runtimes License Agreement
  3. * Last updated January 1, 2020. Replaces all prior versions.
  4. *
  5. * Copyright (c) 2013-2020, 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. #ifdef SPINE_UE4
  30. #include "SpinePluginPrivatePCH.h"
  31. #endif
  32. #include <spine/ScaleTimeline.h>
  33. #include <spine/Skeleton.h>
  34. #include <spine/Event.h>
  35. #include <spine/Slot.h>
  36. #include <spine/SlotData.h>
  37. #include <spine/Bone.h>
  38. #include <spine/BoneData.h>
  39. using namespace spine;
  40. RTTI_IMPL(ScaleTimeline, TranslateTimeline)
  41. ScaleTimeline::ScaleTimeline(int frameCount) : TranslateTimeline(frameCount) {
  42. }
  43. void ScaleTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha,
  44. MixBlend blend, MixDirection direction
  45. ) {
  46. SP_UNUSED(lastTime);
  47. SP_UNUSED(pEvents);
  48. Bone *boneP = skeleton._bones[_boneIndex];
  49. Bone &bone = *boneP;
  50. if (!bone._active) return;
  51. if (time < _frames[0]) {
  52. switch (blend) {
  53. case MixBlend_Setup:
  54. bone._scaleX = bone._data._scaleX;
  55. bone._scaleY = bone._data._scaleY;
  56. return;
  57. case MixBlend_First:
  58. bone._scaleX += (bone._data._scaleX - bone._scaleX) * alpha;
  59. bone._scaleY += (bone._data._scaleY - bone._scaleY) * alpha;
  60. default: {}
  61. }
  62. return;
  63. }
  64. float x, y;
  65. if (time >= _frames[_frames.size() - ENTRIES]) {
  66. // Time is after last frame.
  67. x = _frames[_frames.size() + PREV_X] * bone._data._scaleX;
  68. y = _frames[_frames.size() + PREV_Y] * bone._data._scaleY;
  69. } else {
  70. // Interpolate between the previous frame and the current frame.
  71. int frame = Animation::binarySearch(_frames, time, ENTRIES);
  72. x = _frames[frame + PREV_X];
  73. y = _frames[frame + PREV_Y];
  74. float frameTime = _frames[frame];
  75. float percent = getCurvePercent(frame / ENTRIES - 1,
  76. 1 - (time - frameTime) / (_frames[frame + PREV_TIME] - frameTime));
  77. x = (x + (_frames[frame + X] - x) * percent) * bone._data._scaleX;
  78. y = (y + (_frames[frame + Y] - y) * percent) * bone._data._scaleY;
  79. }
  80. if (alpha == 1) {
  81. if (blend == MixBlend_Add) {
  82. bone._scaleX += x - bone._data._scaleX;
  83. bone._scaleY += y - bone._data._scaleY;
  84. } else {
  85. bone._scaleX = x;
  86. bone._scaleY = y;
  87. }
  88. } else {
  89. // Mixing out uses sign of setup or current pose, else use sign of key.
  90. float bx, by;
  91. if (direction == MixDirection_Out) {
  92. switch (blend) {
  93. case MixBlend_Setup:
  94. bx = bone._data._scaleX;
  95. by = bone._data._scaleY;
  96. bone._scaleX = bx + (MathUtil::abs(x) * MathUtil::sign(bx) - bx) * alpha;
  97. bone._scaleY = by + (MathUtil::abs(y) * MathUtil::sign(by) - by) * alpha;
  98. break;
  99. case MixBlend_First:
  100. case MixBlend_Replace:
  101. bx = bone._scaleX;
  102. by = bone._scaleY;
  103. bone._scaleX = bx + (MathUtil::abs(x) * MathUtil::sign(bx) - bx) * alpha;
  104. bone._scaleY = by + (MathUtil::abs(y) * MathUtil::sign(by) - by) * alpha;
  105. break;
  106. case MixBlend_Add:
  107. bx = bone._scaleX;
  108. by = bone._scaleY;
  109. bone._scaleX = bx + (MathUtil::abs(x) * MathUtil::sign(bx) - bone._data._scaleX) * alpha;
  110. bone._scaleY = by + (MathUtil::abs(y) * MathUtil::sign(by) - bone._data._scaleY) * alpha;
  111. }
  112. } else {
  113. switch (blend) {
  114. case MixBlend_Setup:
  115. bx = MathUtil::abs(bone._data._scaleX) * MathUtil::sign(x);
  116. by = MathUtil::abs(bone._data._scaleY) * MathUtil::sign(y);
  117. bone._scaleX = bx + (x - bx) * alpha;
  118. bone._scaleY = by + (y - by) * alpha;
  119. break;
  120. case MixBlend_First:
  121. case MixBlend_Replace:
  122. bx = MathUtil::abs(bone._scaleX) * MathUtil::sign(x);
  123. by = MathUtil::abs(bone._scaleY) * MathUtil::sign(y);
  124. bone._scaleX = bx + (x - bx) * alpha;
  125. bone._scaleY = by + (y - by) * alpha;
  126. break;
  127. case MixBlend_Add:
  128. bx = MathUtil::sign(x);
  129. by = MathUtil::sign(y);
  130. bone._scaleX = MathUtil::abs(bone._scaleX) * bx + (x - MathUtil::abs(bone._data._scaleX) * bx) * alpha;
  131. bone._scaleY = MathUtil::abs(bone._scaleY) * by + (y - MathUtil::abs(bone._data._scaleY) * by) * alpha;
  132. }
  133. }
  134. }
  135. }
  136. int ScaleTimeline::getPropertyId() {
  137. return ((int) TimelineType_Scale << 24) + _boneIndex;
  138. }