From e3fb50da5bc4ee596c143f107d142728a45f3606 Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Wed, 11 Jun 2025 14:39:38 +0200 Subject: [PATCH] [cpp] 4.3 porting WIP --- spine-cpp/spine-cpp/include/spine/Bone.h | 234 +------- .../spine-cpp/include/spine/Constraint.h | 62 ++ .../spine-cpp/include/spine/ConstraintData.h | 3 + spine-cpp/spine-cpp/include/spine/Posed.h | 96 +-- .../spine-cpp/include/spine/PosedActive.h | 4 +- spine-cpp/spine-cpp/include/spine/PosedData.h | 3 + spine-cpp/spine-cpp/include/spine/Timeline.h | 3 +- spine-cpp/spine-cpp/src/spine/Bone.cpp | 566 +----------------- spine-cpp/spine-cpp/src/spine/Timeline.cpp | 60 +- 9 files changed, 191 insertions(+), 840 deletions(-) create mode 100644 spine-cpp/spine-cpp/include/spine/Constraint.h diff --git a/spine-cpp/spine-cpp/include/spine/Bone.h b/spine-cpp/spine-cpp/include/spine/Bone.h index db1bc42d8..8a1ac557b 100644 --- a/spine-cpp/spine-cpp/include/spine/Bone.h +++ b/spine-cpp/spine-cpp/include/spine/Bone.h @@ -30,256 +30,62 @@ #ifndef Spine_Bone_h #define Spine_Bone_h -#include -#include +#include +#include +#include +#include #include -#include namespace spine { - class BoneData; - - class Skeleton; - -/// Stores a bone's current pose. -/// -/// A bone has a local transform which is used to compute its world transform. A bone also has an applied transform, which is a -/// local transform that can be applied to compute the world transform. The local transform and applied transform may differ if a -/// constraint or application code modifies the world transform after it was computed from the local transform. - class SP_API Bone : public Update { + /// The current pose for a bone, before constraints are applied. + /// + /// A bone has a local transform which is used to compute its world transform. A bone also has an applied transform, which is a + /// local transform that can be applied to compute the world transform. The local transform and applied transform may differ if a + /// constraint or application code modifies the world transform after it was computed from the local transform. + class SP_API Bone : public PosedActive { friend class AnimationState; - friend class RotateTimeline; - friend class IkConstraint; - friend class TransformConstraint; - friend class VertexAttachment; - friend class PathConstraint; - - friend class PhysicsConstraint; - + friend class PhysicsConstraint; friend class Skeleton; - friend class RegionAttachment; - friend class PointAttachment; - friend class AttachmentTimeline; - friend class RGBATimeline; - friend class RGBTimeline; - friend class AlphaTimeline; - friend class RGBA2Timeline; - friend class RGB2Timeline; - friend class ScaleTimeline; - friend class ScaleXTimeline; - friend class ScaleYTimeline; - friend class ShearTimeline; - friend class ShearXTimeline; - friend class ShearYTimeline; - friend class TranslateTimeline; - friend class TranslateXTimeline; - friend class TranslateYTimeline; + friend class InheritTimeline; - friend class InheritTimeline; - - RTTI_DECL + RTTI_DECL public: - static void setYDown(bool inValue); - - static bool isYDown(); - /// @param parent May be NULL. - Bone(BoneData &data, Skeleton &skeleton, Bone *parent = NULL); + Bone(BoneData& data, Bone* parent); - /// Same as updateWorldTransform. This method exists for Bone to implement Spine::Updatable. - virtual void update(Physics physics); + /// The parent bone, or null if this is the root bone. + Bone* getParent(); - /// Computes the world transform using the parent bone and this bone's local transform. - void updateWorldTransform(); - - /// Computes the world transform using the parent bone and the specified local transform. - void - updateWorldTransform(float x, float y, float rotation, float scaleX, float scaleY, float shearX, float shearY); - - /// Computes the individual applied transform values from the world transform. This can be useful to perform processing using - /// the applied transform after the world transform has been modified directly (eg, by a constraint).. - /// - /// Some information is ambiguous in the world transform, such as -1,-1 scale versus 180 rotation. - void updateAppliedTransform(); - - void setToSetupPose(); - - void worldToLocal(float worldX, float worldY, float &outLocalX, float &outLocalY); - - void worldToParent(float worldX, float worldY, float &outParentX, float &outParentY); - - void localToWorld(float localX, float localY, float &outWorldX, float &outWorldY); - - void parentToWorld(float worldX, float worldY, float &outX, float &outY); - - float worldToLocalRotation(float worldRotation); - - float localToWorldRotation(float localRotation); - - /// Rotates the world transform the specified amount and sets isAppliedValid to false. - /// @param degrees Degrees. - void rotateWorld(float degrees); - - float getWorldToLocalRotationX(); - - float getWorldToLocalRotationY(); - - BoneData &getData(); - - Skeleton &getSkeleton(); - - Bone *getParent(); - - Vector &getChildren(); - - /// The local X translation. - float getX(); - - void setX(float inValue); - - /// The local Y translation. - float getY(); - - void setY(float inValue); - - /// The local rotation. - float getRotation(); - - void setRotation(float inValue); - - /// The local scaleX. - float getScaleX(); - - void setScaleX(float inValue); - - /// The local scaleY. - float getScaleY(); - - void setScaleY(float inValue); - - /// The local shearX. - float getShearX(); - - void setShearX(float inValue); - - /// The local shearY. - float getShearY(); - - void setShearY(float inValue); - - /// The rotation, as calculated by any constraints. - float getAppliedRotation(); - - void setAppliedRotation(float inValue); - - /// The applied local x translation. - float getAX(); - - void setAX(float inValue); - - /// The applied local y translation. - float getAY(); - - void setAY(float inValue); - - /// The applied local scaleX. - float getAScaleX(); - - void setAScaleX(float inValue); - - /// The applied local scaleY. - float getAScaleY(); - - void setAScaleY(float inValue); - - /// The applied local shearX. - float getAShearX(); - - void setAShearX(float inValue); - - /// The applied local shearY. - float getAShearY(); - - void setAShearY(float inValue); - - float getA(); - - void setA(float inValue); - - float getB(); - - void setB(float inValue); - - float getC(); - - void setC(float inValue); - - float getD(); - - void setD(float inValue); - - float getWorldX(); - - void setWorldX(float inValue); - - float getWorldY(); - - void setWorldY(float inValue); - - float getWorldRotationX(); - - float getWorldRotationY(); - - /// Returns the magnitide (always positive) of the world scale X. - float getWorldScaleX(); - - /// Returns the magnitide (always positive) of the world scale Y. - float getWorldScaleY(); - - bool isActive(); - - void setActive(bool inValue); - - Inherit getInherit() { return _inherit; } - - void setInherit(Inherit inValue) { _inherit = inValue; } + /// The immediate children of this bone. + Vector& getChildren(); private: - static bool yDown; - - BoneData &_data; - Skeleton &_skeleton; - Bone *_parent; - Vector _children; - float _x, _y, _rotation, _scaleX, _scaleY, _shearX, _shearY; - float _ax, _ay, _arotation, _ascaleX, _ascaleY, _ashearX, _ashearY; - float _a, _b, _worldX; - float _c, _d, _worldY; + Bone* const _parent; + Vector _children; bool _sorted; - bool _active; - Inherit _inherit; }; } diff --git a/spine-cpp/spine-cpp/include/spine/Constraint.h b/spine-cpp/spine-cpp/include/spine/Constraint.h new file mode 100644 index 000000000..69528e753 --- /dev/null +++ b/spine-cpp/spine-cpp/include/spine/Constraint.h @@ -0,0 +1,62 @@ +/****************************************************************************** + * Spine Runtimes License Agreement + * Last updated April 5, 2025. Replaces all prior versions. + * + * Copyright (c) 2013-2025, Esoteric Software LLC + * + * Integration of the Spine Runtimes into software or otherwise creating + * derivative works of the Spine Runtimes is permitted under the terms and + * conditions of Section 2 of the Spine Editor License Agreement: + * http://esotericsoftware.com/spine-editor-license + * + * Otherwise, it is permitted to integrate the Spine Runtimes into software + * or otherwise create derivative works of the Spine Runtimes (collectively, + * "Products"), provided that each user of the Products must obtain their own + * Spine Editor license and redistribution of the Products in any form must + * include this license and copyright notice. + * + * THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES, + * BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + *****************************************************************************/ + +#ifndef Spine_Constraint_h +#define Spine_Constraint_h + +#include +#include +#include + +namespace spine { + class Skeleton; + + template + class SP_API Constraint : public PosedActive, public Update { + RTTI_DECL + + public: + Constraint(D& data, P& pose, P& constrained) : PosedActive(data, pose, constrained) { + } + + virtual ~Constraint() { + } + + virtual void sort(Skeleton& skeleton) = 0; + + virtual bool isSourceActive() { + return true; + } + + // Inherited from Update + virtual void update(Skeleton& skeleton, Physics physics) = 0; + }; +} + +#endif /* Spine_Constraint_h */ \ No newline at end of file diff --git a/spine-cpp/spine-cpp/include/spine/ConstraintData.h b/spine-cpp/spine-cpp/include/spine/ConstraintData.h index 9b9e51e5e..c3c6dcf4d 100644 --- a/spine-cpp/spine-cpp/include/spine/ConstraintData.h +++ b/spine-cpp/spine-cpp/include/spine/ConstraintData.h @@ -41,6 +41,9 @@ namespace spine { /// Base class for all constraint data. template class SP_API ConstraintData : public PosedData

{ + friend class SkeletonBinary; + friend class SkeletonJson; + public: ConstraintData(const String &name, P* setup); virtual ~ConstraintData(); diff --git a/spine-cpp/spine-cpp/include/spine/Posed.h b/spine-cpp/spine-cpp/include/spine/Posed.h index a06c07fb3..1f1d5ffbf 100644 --- a/spine-cpp/spine-cpp/include/spine/Posed.h +++ b/spine-cpp/spine-cpp/include/spine/Posed.h @@ -31,58 +31,76 @@ #define Spine_Posed_h #include +#include namespace spine { template class SP_API Posed : public SpineObject { - public: - Posed(D& data, P& pose, A& constrained); - virtual ~Posed(); + friend class AnimationState; + friend class RotateTimeline; + friend class IkConstraint; + friend class TransformConstraint; + friend class VertexAttachment; + friend class PathConstraint; + friend class PhysicsConstraint; + friend class Skeleton; + friend class RegionAttachment; + friend class PointAttachment; + friend class AttachmentTimeline; + friend class RGBATimeline; + friend class RGBTimeline; + friend class AlphaTimeline; + friend class RGBA2Timeline; + friend class RGB2Timeline; + friend class ScaleTimeline; + friend class ScaleXTimeline; + friend class ScaleYTimeline; + friend class ShearTimeline; + friend class ShearXTimeline; + friend class ShearYTimeline; + friend class TranslateTimeline; + friend class TranslateXTimeline; + friend class TranslateYTimeline; + friend class InheritTimeline; - void setupPose(); + public: + Posed(D& data) : _data(data), _pose(), _constrained() { + static_assert(std::is_base_of::value, "A must extend P"); + // Match Java behavior: applied initially points to pose + // Note: Both _pose and _constrained are stored as type A to match Java's + // "new BonePose(), new BonePose()" pattern. For most classes P==A, but + // Bone uses P=BoneLocal, A=BonePose where BonePose extends BoneLocal. + _applied = &_pose; + } + + virtual ~Posed() { + } + + void setupPose() { + _pose.set(*_data.getSetupPose()); + } /// The constraint's setup pose data. - D& getData(); + D& getData() { + return _data; + } - P& getPose(); + P& getPose() { + // Upcast A to P (safe due to static_assert that A extends P) + // For most classes P==A so this is a no-op, but for Bone it casts BonePose->BoneLocal + return _pose; + } - A& getAppliedPose(); + A& getAppliedPose() { + return *_applied; + } protected: D& _data; - P& _pose; - A& _constrained; - A* _applied; + A _pose; ///< Stored as A type (concrete pose type) to match Java behavior + A _constrained; ///< Stored as A type (concrete pose type) to match Java behavior + A* _applied; ///< Points to either _pose or _constrained, reassignable like Java }; - - template - Posed::Posed(D& data, P& pose, A& constrained) : _data(data), _pose(pose), _constrained(constrained) { - _applied = &pose; - } - - template - Posed::~Posed() { - } - - template - void Posed::setupPose() { - _pose.set(_data.setup); - } - - template - D& Posed::getData() { - return _data; - } - - template - P& Posed::getPose() { - return _pose; - } - - template - A& Posed::getAppliedPose() { - return *_applied; - } } #endif /* Spine_Posed_h */ \ No newline at end of file diff --git a/spine-cpp/spine-cpp/include/spine/PosedActive.h b/spine-cpp/spine-cpp/include/spine/PosedActive.h index 2968f6dd7..a75951942 100644 --- a/spine-cpp/spine-cpp/include/spine/PosedActive.h +++ b/spine-cpp/spine-cpp/include/spine/PosedActive.h @@ -40,7 +40,7 @@ namespace spine { bool _active; public: - PosedActive(D& data, P& pose, A& constrained); + PosedActive(D& data); virtual ~PosedActive(); /// Returns false when this constraint won't be updated by @@ -54,7 +54,7 @@ namespace spine { }; template - PosedActive::PosedActive(D& data, P& pose, A& constrained) : Posed(data, pose, constrained), _active(false) { + PosedActive::PosedActive(D& data) : Posed(data), _active(false) { this->setupPose(); } diff --git a/spine-cpp/spine-cpp/include/spine/PosedData.h b/spine-cpp/spine-cpp/include/spine/PosedData.h index edb7423ab..b3aa8ad4b 100644 --- a/spine-cpp/spine-cpp/include/spine/PosedData.h +++ b/spine-cpp/spine-cpp/include/spine/PosedData.h @@ -40,6 +40,9 @@ namespace spine { /// The base class for all constrained datas. template class SP_API PosedData : public SpineObject { + friend class SkeletonBinary; + friend class SkeletonJson; + private: spine::String _name; P* _setup; diff --git a/spine-cpp/spine-cpp/include/spine/Timeline.h b/spine-cpp/spine-cpp/include/spine/Timeline.h index c9ded4b64..5e34d1193 100644 --- a/spine-cpp/spine-cpp/include/spine/Timeline.h +++ b/spine-cpp/spine-cpp/include/spine/Timeline.h @@ -60,9 +60,10 @@ namespace spine { /// time, an animation can be mixed in or out. alpha can also be useful to apply animations on top of each other (layered). /// @param blend Controls how mixing is applied when alpha is than 1. /// @param direction Indicates whether the timeline is mixing in or out. Used by timelines which perform instant transitions such as DrawOrderTimeline and AttachmentTimeline. + /// @param appliedPose True to modify the applied pose. virtual void apply(Skeleton &skeleton, float lastTime, float time, Vector *pEvents, float alpha, MixBlend blend, - MixDirection direction) = 0; + MixDirection direction, bool appliedPose) = 0; size_t getFrameEntries(); diff --git a/spine-cpp/spine-cpp/src/spine/Bone.cpp b/spine-cpp/spine-cpp/src/spine/Bone.cpp index 9a78078d2..e3f4dd373 100644 --- a/spine-cpp/spine-cpp/src/spine/Bone.cpp +++ b/spine-cpp/spine-cpp/src/spine/Bone.cpp @@ -28,568 +28,26 @@ *****************************************************************************/ #include - #include -#include +#include +#include using namespace spine; -RTTI_IMPL(Bone, Updatable) +RTTI_IMPL_NOPARENT(Bone) -bool Bone::yDown = false; - -void Bone::setYDown(bool inValue) { - yDown = inValue; +Bone::Bone(BoneData& data, Bone* parent) : PosedActive(data), + _parent(parent), + _children(), + _sorted(false) { + _constrained._bone = this; + _applied->_bone = this; } -bool Bone::isYDown() { - return yDown; -} - -Bone::Bone(BoneData &data, Skeleton &skeleton, Bone *parent) : Updatable(), - _data(data), - _skeleton(skeleton), - _parent(parent), - _x(0), - _y(0), - _rotation(0), - _scaleX(0), - _scaleY(0), - _shearX(0), - _shearY(0), - _ax(0), - _ay(0), - _arotation(0), - _ascaleX(0), - _ascaleY(0), - _ashearX(0), - _ashearY(0), - _a(1), - _b(0), - _worldX(0), - _c(0), - _d(1), - _worldY(0), - _sorted(false), - _active(false), - _inherit(Inherit_Normal) { - setToSetupPose(); -} - -void Bone::update(Physics) { - updateWorldTransform(_ax, _ay, _arotation, _ascaleX, _ascaleY, _ashearX, _ashearY); -} - -void Bone::updateWorldTransform() { - updateWorldTransform(_x, _y, _rotation, _scaleX, _scaleY, _shearX, _shearY); -} - -void Bone::updateWorldTransform(float x, float y, float rotation, float scaleX, float scaleY, float shearX, float shearY) { - float pa, pb, pc, pd; - Bone *parent = _parent; - - _ax = x; - _ay = y; - _arotation = rotation; - _ascaleX = scaleX; - _ascaleY = scaleY; - _ashearX = shearX; - _ashearY = shearY; - - if (!parent) { /* Root bone. */ - Skeleton &skeleton = this->_skeleton; - float sx = skeleton.getScaleX(); - float sy = skeleton.getScaleY(); - float rx = (rotation + shearX) * MathUtil::Deg_Rad; - float ry = (rotation + 90 + shearY) * MathUtil::Deg_Rad; - _a = MathUtil::cos(rx) * scaleX * sx; - _b = MathUtil::cos(ry) * scaleY * sx; - _c = MathUtil::sin(rx) * scaleX * sy; - _d = MathUtil::sin(ry) * scaleY * sy; - _worldX = x * sx + _skeleton.getX(); - _worldY = y * sy + _skeleton.getY(); - return; - } - - pa = parent->_a; - pb = parent->_b; - pc = parent->_c; - pd = parent->_d; - - _worldX = pa * x + pb * y + parent->_worldX; - _worldY = pc * x + pd * y + parent->_worldY; - - switch (_inherit) { - case Inherit_Normal: { - float rx = (rotation + shearX) * MathUtil::Deg_Rad; - float ry = (rotation + 90 + shearY) * MathUtil::Deg_Rad; - float la = MathUtil::cos(rx) * scaleX; - float lb = MathUtil::cos(ry) * scaleY; - float lc = MathUtil::sin(rx) * scaleX; - float ld = MathUtil::sin(ry) * scaleY; - _a = pa * la + pb * lc; - _b = pa * lb + pb * ld; - _c = pc * la + pd * lc; - _d = pc * lb + pd * ld; - return; - } - case Inherit_OnlyTranslation: { - float rx = (rotation + shearX) * MathUtil::Deg_Rad; - float ry = (rotation + 90 + shearY) * MathUtil::Deg_Rad; - _a = MathUtil::cos(rx) * scaleX; - _b = MathUtil::cos(ry) * scaleY; - _c = MathUtil::sin(rx) * scaleX; - _d = MathUtil::sin(ry) * scaleY; - break; - } - case Inherit_NoRotationOrReflection: { - float s = pa * pa + pc * pc; - float prx; - if (s > 0.0001f) { - s = MathUtil::abs(pa * pd - pb * pc) / s; - pa /= _skeleton.getScaleX(); - pc /= _skeleton.getScaleY(); - pb = pc * s; - pd = pa * s; - prx = MathUtil::atan2Deg(pc, pa); - } else { - pa = 0; - pc = 0; - prx = 90 - MathUtil::atan2Deg(pd, pb); - } - float rx = (rotation + shearX - prx) * MathUtil::Deg_Rad; - float ry = (rotation + shearY - prx + 90) * MathUtil::Deg_Rad; - float la = MathUtil::cos(rx) * scaleX; - float lb = MathUtil::cos(ry) * scaleY; - float lc = MathUtil::sin(rx) * scaleX; - float ld = MathUtil::sin(ry) * scaleY; - _a = pa * la - pb * lc; - _b = pa * lb - pb * ld; - _c = pc * la + pd * lc; - _d = pc * lb + pd * ld; - break; - } - case Inherit_NoScale: - case Inherit_NoScaleOrReflection: { - rotation *= MathUtil::Deg_Rad; - float cosine = MathUtil::cos(rotation); - float sine = MathUtil::sin(rotation); - float za = (pa * cosine + pb * sine) / _skeleton.getScaleX(); - float zc = (pc * cosine + pd * sine) / _skeleton.getScaleY(); - float s = MathUtil::sqrt(za * za + zc * zc); - if (s > 0.00001f) s = 1 / s; - za *= s; - zc *= s; - s = MathUtil::sqrt(za * za + zc * zc); - if (_inherit == Inherit_NoScale && - (pa * pd - pb * pc < 0) != (_skeleton.getScaleX() < 0 != _skeleton.getScaleY() < 0)) - s = -s; - rotation = MathUtil::Pi / 2 + MathUtil::atan2(zc, za); - float zb = MathUtil::cos(rotation) * s; - float zd = MathUtil::sin(rotation) * s; - shearX *= MathUtil::Deg_Rad; - shearY = (90 + shearY) * MathUtil::Deg_Rad; - float la = MathUtil::cos(shearX) * scaleX; - float lb = MathUtil::cos(shearY) * scaleY; - float lc = MathUtil::sin(shearX) * scaleX; - float ld = MathUtil::sin(shearY) * scaleY; - _a = za * la + zb * lc; - _b = za * lb + zb * ld; - _c = zc * la + zd * lc; - _d = zc * lb + zd * ld; - } - } - _a *= _skeleton.getScaleX(); - _b *= _skeleton.getScaleX(); - _c *= _skeleton.getScaleY(); - _d *= _skeleton.getScaleY(); -} - -void Bone::setToSetupPose() { - BoneData &data = _data; - _x = data.getX(); - _y = data.getY(); - _rotation = data.getRotation(); - _scaleX = data.getScaleX(); - _scaleY = data.getScaleY(); - _shearX = data.getShearX(); - _shearY = data.getShearY(); - _inherit = data.getInherit(); -} - -void Bone::worldToLocal(float worldX, float worldY, float &outLocalX, float &outLocalY) { - float a = _a; - float b = _b; - float c = _c; - float d = _d; - - float invDet = 1 / (a * d - b * c); - float x = worldX - _worldX; - float y = worldY - _worldY; - - outLocalX = (x * d * invDet - y * b * invDet); - outLocalY = (y * a * invDet - x * c * invDet); -} - -void Bone::worldToParent(float worldX, float worldY, float &outParentX, float &outParentY) { - if (!_parent) { - outParentX = worldX; - outParentY = worldY; - } else { - _parent->worldToLocal(worldX, worldY, outParentX, outParentY); - } -} - -void Bone::localToWorld(float localX, float localY, float &outWorldX, float &outWorldY) { - outWorldX = localX * _a + localY * _b + _worldX; - outWorldY = localX * _c + localY * _d + _worldY; -} - -void Bone::parentToWorld(float worldX, float worldY, float &outX, float &outY) { - if (!_parent) { - outX = worldX; - outY = worldY; - } else { - _parent->localToWorld(worldX, worldY, outX, outY); - } -} - -float Bone::worldToLocalRotation(float worldRotation) { - worldRotation *= MathUtil::Deg_Rad; - float sine = MathUtil::sin(worldRotation), cosine = MathUtil::cos(worldRotation); - return MathUtil::atan2Deg(_a * sine - _c * cosine, _d * cosine - _b * sine) + _rotation - _shearX; -} - -float Bone::localToWorldRotation(float localRotation) { - localRotation = (localRotation - _rotation - _shearX) * MathUtil::Deg_Rad; - float sine = MathUtil::sin(localRotation), cosine = MathUtil::cos(localRotation); - return MathUtil::atan2Deg(cosine * _c + sine * _d, cosine * _a + sine * _b); -} - -void Bone::rotateWorld(float degrees) { - degrees *= MathUtil::Deg_Rad; - float sine = MathUtil::sin(degrees), cosine = MathUtil::cos(degrees); - float ra = _a, rb = _b; - _a = cosine * ra - sine * _c; - _b = cosine * rb - sine * _d; - _c = sine * ra + cosine * _c; - _d = sine * rb + cosine * _d; -} - -float Bone::getWorldToLocalRotationX() { - Bone *parent = _parent; - if (!parent) { - return _arotation; - } - - float pa = parent->_a; - float pb = parent->_b; - float pc = parent->_c; - float pd = parent->_d; - float a = _a; - float c = _c; - - return MathUtil::atan2(pa * c - pc * a, pd * a - pb * c) * MathUtil::Rad_Deg; -} - -float Bone::getWorldToLocalRotationY() { - Bone *parent = _parent; - if (!parent) { - return _arotation; - } - - float pa = parent->_a; - float pb = parent->_b; - float pc = parent->_c; - float pd = parent->_d; - float b = _b; - float d = _d; - - return MathUtil::atan2(pa * d - pc * b, pd * b - pb * d) * MathUtil::Rad_Deg; -} - -BoneData &Bone::getData() { - return _data; -} - -Skeleton &Bone::getSkeleton() { - return _skeleton; -} - -Bone *Bone::getParent() { +Bone* Bone::getParent() { return _parent; } -Vector &Bone::getChildren() { +Vector& Bone::getChildren() { return _children; -} - -float Bone::getX() { - return _x; -} - -void Bone::setX(float inValue) { - _x = inValue; -} - -float Bone::getY() { - return _y; -} - -void Bone::setY(float inValue) { - _y = inValue; -} - -float Bone::getRotation() { - return _rotation; -} - -void Bone::setRotation(float inValue) { - _rotation = inValue; -} - -float Bone::getScaleX() { - return _scaleX; -} - -void Bone::setScaleX(float inValue) { - _scaleX = inValue; -} - -float Bone::getScaleY() { - return _scaleY; -} - -void Bone::setScaleY(float inValue) { - _scaleY = inValue; -} - -float Bone::getShearX() { - return _shearX; -} - -void Bone::setShearX(float inValue) { - _shearX = inValue; -} - -float Bone::getShearY() { - return _shearY; -} - -void Bone::setShearY(float inValue) { - _shearY = inValue; -} - -float Bone::getAppliedRotation() { - return _arotation; -} - -void Bone::setAppliedRotation(float inValue) { - _arotation = inValue; -} - -float Bone::getAX() { - return _ax; -} - -void Bone::setAX(float inValue) { - _ax = inValue; -} - -float Bone::getAY() { - return _ay; -} - -void Bone::setAY(float inValue) { - _ay = inValue; -} - -float Bone::getAScaleX() { - return _ascaleX; -} - -void Bone::setAScaleX(float inValue) { - _ascaleX = inValue; -} - -float Bone::getAScaleY() { - return _ascaleY; -} - -void Bone::setAScaleY(float inValue) { - _ascaleY = inValue; -} - -float Bone::getAShearX() { - return _ashearX; -} - -void Bone::setAShearX(float inValue) { - _ashearX = inValue; -} - -float Bone::getAShearY() { - return _ashearY; -} - -void Bone::setAShearY(float inValue) { - _ashearY = inValue; -} - -float Bone::getA() { - return _a; -} - -void Bone::setA(float inValue) { - _a = inValue; -} - -float Bone::getB() { - return _b; -} - -void Bone::setB(float inValue) { - _b = inValue; -} - -float Bone::getC() { - return _c; -} - -void Bone::setC(float inValue) { - _c = inValue; -} - -float Bone::getD() { - return _d; -} - -void Bone::setD(float inValue) { - _d = inValue; -} - -float Bone::getWorldX() { - return _worldX; -} - -void Bone::setWorldX(float inValue) { - _worldX = inValue; -} - -float Bone::getWorldY() { - return _worldY; -} - -void Bone::setWorldY(float inValue) { - _worldY = inValue; -} - -float Bone::getWorldRotationX() { - return MathUtil::atan2Deg(_c, _a); -} - -float Bone::getWorldRotationY() { - return MathUtil::atan2Deg(_d, _b); -} - -float Bone::getWorldScaleX() { - return MathUtil::sqrt(_a * _a + _c * _c); -} - -float Bone::getWorldScaleY() { - return MathUtil::sqrt(_b * _b + _d * _d); -} - -void Bone::updateAppliedTransform() { - Bone *parent = _parent; - if (!parent) { - _ax = _worldX - _skeleton.getX(); - _ay = _worldY - _skeleton.getY(); - _arotation = MathUtil::atan2Deg(_c, _a); - _ascaleX = MathUtil::sqrt(_a * _a + _c * _c); - _ascaleY = MathUtil::sqrt(_b * _b + _d * _d); - _ashearX = 0; - _ashearY = MathUtil::atan2Deg(_a * _b + _c * _d, _a * _d - _b * _c); - } - float pa = parent->_a, pb = parent->_b, pc = parent->_c, pd = parent->_d; - float pid = 1 / (pa * pd - pb * pc); - float ia = pd * pid, ib = pb * pid, ic = pc * pid, id = pa * pid; - float dx = _worldX - parent->_worldX, dy = _worldY - parent->_worldY; - _ax = (dx * ia - dy * ib); - _ay = (dy * id - dx * ic); - - float ra, rb, rc, rd; - if (_inherit == Inherit_OnlyTranslation) { - ra = _a; - rb = _b; - rc = _c; - rd = _d; - } else { - switch (_inherit) { - case Inherit_NoRotationOrReflection: { - float s = MathUtil::abs(pa * pd - pb * pc) / (pa * pa + pc * pc); - float sa = pa / _skeleton.getScaleX(); - float sc = pc / _skeleton.getScaleY(); - pb = -sc * s * _skeleton.getScaleX(); - pd = sa * s * _skeleton.getScaleY(); - pid = 1 / (pa * pd - pb * pc); - ia = pd * pid; - ib = pb * pid; - break; - } - case Inherit_NoScale: - case Inherit_NoScaleOrReflection: { - float r = _rotation * MathUtil::Deg_Rad; - float cos = MathUtil::cos(r), sin = MathUtil::sin(r); - pa = (pa * cos + pb * sin) / _skeleton.getScaleX(); - pc = (pc * cos + pd * sin) / _skeleton.getScaleY(); - float s = MathUtil::sqrt(pa * pa + pc * pc); - if (s > 0.00001) s = 1 / s; - pa *= s; - pc *= s; - s = MathUtil::sqrt(pa * pa + pc * pc); - if (_inherit == Inherit_NoScale && - pid < 0 != (_skeleton.getScaleX() < 0 != _skeleton.getScaleY() < 0)) - s = -s; - r = MathUtil::Pi / 2 + MathUtil::atan2(pc, pa); - pb = MathUtil::cos(r) * s; - pd = MathUtil::sin(r) * s; - pid = 1 / (pa * pd - pb * pc); - ia = pd * pid; - ib = pb * pid; - ic = pc * pid; - id = pa * pid; - break; - } - case Inherit_Normal: - case Inherit_OnlyTranslation: - break; - } - ra = ia * _a - ib * _c; - rb = ia * _b - ib * _d; - rc = id * _c - ic * _a; - rd = id * _d - ic * _b; - } - - _ashearX = 0; - _ascaleX = MathUtil::sqrt(ra * ra + rc * rc); - if (_ascaleX > 0.0001f) { - float det = ra * rd - rb * rc; - _ascaleY = det / _ascaleX; - _ashearY = -MathUtil::atan2Deg(ra * rb + rc * rd, det); - _arotation = MathUtil::atan2Deg(rc, ra); - } else { - _ascaleX = 0; - _ascaleY = MathUtil::sqrt(rb * rb + rd * rd); - _ashearY = 0; - _arotation = 90 - MathUtil::atan2Deg(rd, rb); - } -} - -bool Bone::isActive() { - return _active; -} - -void Bone::setActive(bool inValue) { - _active = inValue; -} +} \ No newline at end of file diff --git a/spine-cpp/spine-cpp/src/spine/Timeline.cpp b/spine-cpp/spine-cpp/src/spine/Timeline.cpp index b8624c0a3..196bc3d75 100644 --- a/spine-cpp/spine-cpp/src/spine/Timeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/Timeline.cpp @@ -32,42 +32,42 @@ #include #include -namespace spine { - RTTI_IMPL_NOPARENT(Timeline) +using namespace spine; - Timeline::Timeline(size_t frameCount, size_t frameEntries) - : _propertyIds(), _frames(), _frameEntries(frameEntries) { - _frames.setSize(frameCount * frameEntries, 0); - } +RTTI_IMPL_NOPARENT(Timeline) - Timeline::~Timeline() { - } +Timeline::Timeline(size_t frameCount, size_t frameEntries) + : _propertyIds(), _frames(), _frameEntries(frameEntries) { + _frames.setSize(frameCount * frameEntries, 0); +} - Vector &Timeline::getPropertyIds() { - return _propertyIds; - } +Timeline::~Timeline() { +} - void Timeline::setPropertyIds(PropertyId propertyIds[], size_t propertyIdsCount) { - _propertyIds.clear(); - _propertyIds.ensureCapacity(propertyIdsCount); - for (size_t i = 0; i < propertyIdsCount; i++) { - _propertyIds.add(propertyIds[i]); - } - } +Vector &Timeline::getPropertyIds() { + return _propertyIds; +} - size_t Timeline::getFrameCount() { - return _frames.size() / _frameEntries; +void Timeline::setPropertyIds(PropertyId propertyIds[], size_t propertyIdsCount) { + _propertyIds.clear(); + _propertyIds.ensureCapacity(propertyIdsCount); + for (size_t i = 0; i < propertyIdsCount; i++) { + _propertyIds.add(propertyIds[i]); } +} - Vector &Timeline::getFrames() { - return _frames; - } +size_t Timeline::getFrameCount() { + return _frames.size() / _frameEntries; +} - size_t Timeline::getFrameEntries() { - return _frameEntries; - } +Vector &Timeline::getFrames() { + return _frames; +} - float Timeline::getDuration() { - return _frames[_frames.size() - getFrameEntries()]; - } -}// namespace spine +size_t Timeline::getFrameEntries() { + return _frameEntries; +} + +float Timeline::getDuration() { + return _frames[_frames.size() - getFrameEntries()]; +}