diff --git a/spine-cpp/spine-cpp/include/spine/AnimationState.h b/spine-cpp/spine-cpp/include/spine/AnimationState.h index 269868142..dcdd4334e 100644 --- a/spine-cpp/spine-cpp/include/spine/AnimationState.h +++ b/spine-cpp/spine-cpp/include/spine/AnimationState.h @@ -250,6 +250,8 @@ namespace spine { void setMixDuration(float inValue); + void setMixDuration(float mixDuration, float delay); + MixBlend getMixBlend(); void setMixBlend(MixBlend blend); @@ -277,6 +279,9 @@ namespace spine { void setListener(AnimationStateListenerObject *listener); + /// Returns true if this track entry has been applied at least once. + /// + /// See AnimationState::apply(Skeleton). bool wasApplied(); private: diff --git a/spine-cpp/spine-cpp/include/spine/Bone.h b/spine-cpp/spine-cpp/include/spine/Bone.h index 108bba150..1af0aeda6 100644 --- a/spine-cpp/spine-cpp/include/spine/Bone.h +++ b/spine-cpp/spine-cpp/include/spine/Bone.h @@ -33,6 +33,7 @@ #include #include #include +#include namespace spine { class BoneData; @@ -95,6 +96,8 @@ namespace spine { friend class TranslateYTimeline; + friend class InheritTimeline; + RTTI_DECL public: @@ -125,8 +128,12 @@ namespace spine { 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); @@ -255,6 +262,10 @@ namespace spine { void setActive(bool inValue); + Inherit getInherit() { return _inherit; } + + void setInherit(Inherit inValue) { _inherit = inValue; } + private: static bool yDown; @@ -268,6 +279,7 @@ namespace spine { float _c, _d, _worldY; bool _sorted; bool _active; + Inherit _inherit; }; } diff --git a/spine-cpp/spine-cpp/include/spine/BoneData.h b/spine-cpp/spine-cpp/include/spine/BoneData.h index eb608bf7c..8e7a29370 100644 --- a/spine-cpp/spine-cpp/include/spine/BoneData.h +++ b/spine-cpp/spine-cpp/include/spine/BoneData.h @@ -30,7 +30,7 @@ #ifndef Spine_BoneData_h #define Spine_BoneData_h -#include +#include #include #include #include @@ -115,9 +115,9 @@ namespace spine { void setShearY(float inValue); /// The transform mode for how parent world transforms affect this bone. - TransformMode getTransformMode(); + Inherit getInherit(); - void setTransformMode(TransformMode inValue); + void setInherit(Inherit inValue); bool isSkinRequired(); @@ -139,7 +139,7 @@ namespace spine { BoneData *_parent; float _length; float _x, _y, _rotation, _scaleX, _scaleY, _shearX, _shearY; - TransformMode _transformMode; + Inherit _inherit; bool _skinRequired; Color _color; String _icon; diff --git a/spine-cpp/spine-cpp/include/spine/TransformMode.h b/spine-cpp/spine-cpp/include/spine/Inherit.h similarity index 90% rename from spine-cpp/spine-cpp/include/spine/TransformMode.h rename to spine-cpp/spine-cpp/include/spine/Inherit.h index 9b75ccf73..aa2253f77 100644 --- a/spine-cpp/spine-cpp/include/spine/TransformMode.h +++ b/spine-cpp/spine-cpp/include/spine/Inherit.h @@ -31,12 +31,12 @@ #define Spine_TransformMode_h namespace spine { - enum TransformMode { - TransformMode_Normal = 0, - TransformMode_OnlyTranslation, - TransformMode_NoRotationOrReflection, - TransformMode_NoScale, - TransformMode_NoScaleOrReflection + enum Inherit { + Inherit_Normal = 0, + Inherit_OnlyTranslation, + Inherit_NoRotationOrReflection, + Inherit_NoScale, + Inherit_NoScaleOrReflection }; } diff --git a/spine-cpp/spine-cpp/include/spine/InheritTimeline.h b/spine-cpp/spine-cpp/include/spine/InheritTimeline.h new file mode 100644 index 000000000..325b88a71 --- /dev/null +++ b/spine-cpp/spine-cpp/include/spine/InheritTimeline.h @@ -0,0 +1,68 @@ +/****************************************************************************** + * Spine Runtimes License Agreement + * Last updated July 28, 2023. Replaces all prior versions. + * + * Copyright (c) 2013-2023, 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_InheritTimeline_h +#define Spine_InheritTimeline_h + +#include + +#include +#include +#include + +namespace spine { + + class SP_API InheritTimeline : public Timeline { + friend class SkeletonBinary; + + friend class SkeletonJson; + + RTTI_DECL + + public: + explicit InheritTimeline(size_t frameCount, int boneIndex); + + virtual ~InheritTimeline(); + + void setFrame(int frame, float time, Inherit inherit); + + virtual void + apply(Skeleton &skeleton, float lastTime, float time, Vector *pEvents, float alpha, MixBlend blend, + MixDirection direction); + + int getBoneIndex() { return _boneIndex; } + + void setBoneIndex(int inValue) { _boneIndex = inValue; } + + private: + int _boneIndex; + }; +} + +#endif /* Spine_InheritTimeline_h */ diff --git a/spine-cpp/spine-cpp/include/spine/PhysicsConstraintData.h b/spine-cpp/spine-cpp/include/spine/PhysicsConstraintData.h index 81a95f673..c3bb9c338 100644 --- a/spine-cpp/spine-cpp/include/spine/PhysicsConstraintData.h +++ b/spine-cpp/spine-cpp/include/spine/PhysicsConstraintData.h @@ -76,6 +76,10 @@ namespace spine { float getShearX() const; + void setLimit(float limit); + + float getLimit() const; + void setStep(float step); float getStep() const; @@ -138,7 +142,7 @@ namespace spine { private: BoneData *_bone; - float _x, _y, _rotate, _scaleX, _shearX; + float _x, _y, _rotate, _scaleX, _shearX, _limit; float _step, _inertia, _strength, _damping, _massInverse, _wind, _gravity, _mix; bool _inertiaGlobal, _strengthGlobal, _dampingGlobal, _massGlobal, _windGlobal, _gravityGlobal, _mixGlobal; }; diff --git a/spine-cpp/spine-cpp/include/spine/Property.h b/spine-cpp/spine-cpp/include/spine/Property.h index 52e3ca7df..e51ab3eba 100644 --- a/spine-cpp/spine-cpp/include/spine/Property.h +++ b/spine-cpp/spine-cpp/include/spine/Property.h @@ -40,27 +40,28 @@ namespace spine { Property_ScaleY = 1 << 4, Property_ShearX = 1 << 5, Property_ShearY = 1 << 6, - Property_Rgb = 1 << 7, - Property_Alpha = 1 << 8, - Property_Rgb2 = 1 << 9, - Property_Attachment = 1 << 10, - Property_Deform = 1 << 11, - Property_Event = 1 << 12, - Property_DrawOrder = 1 << 13, - Property_IkConstraint = 1 << 14, - Property_TransformConstraint = 1 << 15, - Property_PathConstraintPosition = 1 << 16, - Property_PathConstraintSpacing = 1 << 17, - Property_PathConstraintMix = 1 << 18, - Property_PhysicsConstraintInertia = 1 << 19, - Property_PhysicsConstraintStrength = 1 << 20, - Property_PhysicsConstraintDamping = 1 << 21, - Property_PhysicsConstraintMass = 1 << 22, - Property_PhysicsConstraintWind = 1 << 23, - Property_PhysicsConstraintGravity = 1 << 24, - Property_PhysicsConstraintMix = 1 << 25, - Property_PhysicsConstraintReset = 1 << 26, - Property_Sequence = 1 << 27 + Property_Inherit = 1 << 7, + Property_Rgb = 1 << 8, + Property_Alpha = 1 << 9, + Property_Rgb2 = 1 << 10, + Property_Attachment = 1 << 11, + Property_Deform = 1 << 12, + Property_Event = 1 << 13, + Property_DrawOrder = 1 << 14, + Property_IkConstraint = 1 << 15, + Property_TransformConstraint = 1 << 16, + Property_PathConstraintPosition = 1 << 17, + Property_PathConstraintSpacing = 1 << 18, + Property_PathConstraintMix = 1 << 19, + Property_PhysicsConstraintInertia = 1 << 20, + Property_PhysicsConstraintStrength = 1 << 21, + Property_PhysicsConstraintDamping = 1 << 22, + Property_PhysicsConstraintMass = 1 << 23, + Property_PhysicsConstraintWind = 1 << 24, + Property_PhysicsConstraintGravity = 1 << 25, + Property_PhysicsConstraintMix = 1 << 26, + Property_PhysicsConstraintReset = 1 << 27, + Property_Sequence = 1 << 28 }; } diff --git a/spine-cpp/spine-cpp/include/spine/SkeletonBinary.h b/spine-cpp/spine-cpp/include/spine/SkeletonBinary.h index a1ade7d34..2f1fff497 100644 --- a/spine-cpp/spine-cpp/include/spine/SkeletonBinary.h +++ b/spine-cpp/spine-cpp/include/spine/SkeletonBinary.h @@ -30,7 +30,7 @@ #ifndef Spine_SkeletonBinary_h #define Spine_SkeletonBinary_h -#include +#include #include #include #include diff --git a/spine-cpp/spine-cpp/include/spine/SkeletonData.h b/spine-cpp/spine-cpp/include/spine/SkeletonData.h index f04f5a9b4..1fedd7728 100644 --- a/spine-cpp/spine-cpp/include/spine/SkeletonData.h +++ b/spine-cpp/spine-cpp/include/spine/SkeletonData.h @@ -141,6 +141,10 @@ namespace spine { void setHeight(float inValue); + float getReferenceScale(); + + void setReferenceScale(float inValue); + /// The Spine version used to export this data, or NULL. const String &getVersion(); @@ -176,6 +180,7 @@ namespace spine { Vector _pathConstraints; Vector _physicsConstraints; float _x, _y, _width, _height; + float _referenceScale; String _version; String _hash; Vector _strings; diff --git a/spine-cpp/spine-cpp/include/spine/Skin.h b/spine-cpp/spine-cpp/include/spine/Skin.h index ea6542e45..e023eae4b 100644 --- a/spine-cpp/spine-cpp/include/spine/Skin.h +++ b/spine-cpp/spine-cpp/include/spine/Skin.h @@ -32,6 +32,7 @@ #include #include +#include namespace spine { class Attachment; @@ -153,11 +154,14 @@ namespace spine { Vector &getConstraints(); + Color &getColor() { return _color; } + private: const String _name; AttachmentMap _attachments; Vector _bones; Vector _constraints; + Color _color; /// Attach all attachments from this skin if the corresponding attachment from the old skin is currently attached. void attachAll(Skeleton &skeleton, Skin &oldSkin); diff --git a/spine-cpp/spine-cpp/include/spine/SlotData.h b/spine-cpp/spine-cpp/include/spine/SlotData.h index 045198b05..f942b7d3a 100644 --- a/spine-cpp/spine-cpp/include/spine/SlotData.h +++ b/spine-cpp/spine-cpp/include/spine/SlotData.h @@ -109,6 +109,10 @@ namespace spine { void setVisible(bool inValue); + String &getPath() { return _path; } + + void setPath(const String &inValue) { _path = inValue; } + private: const int _index; String _name; @@ -120,6 +124,7 @@ namespace spine { String _attachmentName; BlendMode _blendMode; bool _visible; + String _path; }; } diff --git a/spine-cpp/spine-cpp/include/spine/spine.h b/spine-cpp/spine-cpp/include/spine/spine.h index 416c306fe..8271eb941 100644 --- a/spine-cpp/spine-cpp/include/spine/spine.h +++ b/spine-cpp/spine-cpp/include/spine/spine.h @@ -60,6 +60,7 @@ #include #include #include +#include #include #include #include @@ -101,7 +102,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/spine-cpp/spine-cpp/src/spine/AnimationState.cpp b/spine-cpp/spine-cpp/src/spine/AnimationState.cpp index aad19d668..c6bf6ba3e 100644 --- a/spine-cpp/spine-cpp/src/spine/AnimationState.cpp +++ b/spine-cpp/spine-cpp/src/spine/AnimationState.cpp @@ -162,6 +162,12 @@ float TrackEntry::getMixDuration() { return _mixDuration; } void TrackEntry::setMixDuration(float inValue) { _mixDuration = inValue; } +void TrackEntry::setMixDuration(float mixDuration, float delay) { + _mixDuration = mixDuration; + if (_previous && delay <= 0) delay += _previous->getTrackComplete() - mixDuration; + this->_delay = delay; +} + TrackEntry *TrackEntry::getMixingFrom() { return _mixingFrom; } TrackEntry *TrackEntry::getMixingTo() { return _mixingTo; } @@ -484,7 +490,7 @@ bool AnimationState::apply(Skeleton &skeleton) { timelineBlend, timelinesRotation, ii << 1, firstFrame); else if (timeline->getRTTI().isExactly(AttachmentTimeline::rtti)) applyAttachmentTimeline(static_cast(timeline), skeleton, applyTime, - timelineBlend, true); + blend, attachments); else timeline->apply(skeleton, animationLast, applyTime, applyEvents, alpha, timelineBlend, MixDirection_In); @@ -928,10 +934,16 @@ void AnimationState::queueEvents(TrackEntry *entry, float animationTime) { // Queue complete if completed a loop iteration or the animation. bool complete = false; - if (entry->_loop) - complete = duration == 0 || (trackLastWrapped > MathUtil::fmod(entry->_trackTime, duration)); - else - complete = animationTime >= animationEnd && entry->_animationLast < animationEnd; + if (entry->_loop) { + if (duration == 0) + complete = true; + else { + int cycles = (int) (entry->_trackTime / duration); + complete = cycles > 0 && cycles > (int) (entry->_trackLast / duration); + } + } else { + complete = animationTime >= animationEnd && entry->_animationLast < animationEnd; + } if (complete) _queue->complete(entry); // Queue events after complete. @@ -985,8 +997,8 @@ TrackEntry *AnimationState::newTrackEntry(size_t trackIndex, Animation *animatio entry._shortestRotation = false; entry._eventThreshold = 0; - entry._mixAttachmentThreshold = 0; entry._alphaAttachmentThreshold = 0; + entry._mixAttachmentThreshold = 0; entry._mixDrawOrderThreshold = 0; entry._animationStart = 0; diff --git a/spine-cpp/spine-cpp/src/spine/Bone.cpp b/spine-cpp/spine-cpp/src/spine/Bone.cpp index 8317e87ce..ae0b8e2a9 100644 --- a/spine-cpp/spine-cpp/src/spine/Bone.cpp +++ b/spine-cpp/spine-cpp/src/spine/Bone.cpp @@ -71,7 +71,8 @@ Bone::Bone(BoneData &data, Skeleton &skeleton, Bone *parent) : Updatable(), _d(1), _worldY(0), _sorted(false), - _active(false) { + _active(false), + _inherit(Inherit_Normal){ setToSetupPose(); } @@ -118,8 +119,8 @@ void Bone::updateWorldTransform(float x, float y, float rotation, float scaleX, _worldX = pa * x + pb * y + parent->_worldX; _worldY = pc * x + pd * y + parent->_worldY; - switch (_data.getTransformMode()) { - case TransformMode_Normal: { + 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; @@ -132,7 +133,7 @@ void Bone::updateWorldTransform(float x, float y, float rotation, float scaleX, _d = pc * lb + pd * ld; return; } - case TransformMode_OnlyTranslation: { + case Inherit_OnlyTranslation: { float rx = (rotation + shearX) * MathUtil::Deg_Rad; float ry = (rotation + 90 + shearY) * MathUtil::Deg_Rad; _a = MathUtil::cos(rx) * scaleX; @@ -141,7 +142,7 @@ void Bone::updateWorldTransform(float x, float y, float rotation, float scaleX, _d = MathUtil::sin(ry) * scaleY; break; } - case TransformMode_NoRotationOrReflection: { + case Inherit_NoRotationOrReflection: { float s = pa * pa + pc * pc; float prx; if (s > 0.0001f) { @@ -150,11 +151,11 @@ void Bone::updateWorldTransform(float x, float y, float rotation, float scaleX, pc /= _skeleton.getScaleY(); pb = pc * s; pd = pa * s; - prx = MathUtil::atan2(pc, pa) * MathUtil::Rad_Deg; + prx = MathUtil::atan2Deg(pc, pa); } else { pa = 0; pc = 0; - prx = 90 - MathUtil::atan2(pd, pb) * MathUtil::Rad_Deg; + prx = 90 - MathUtil::atan2Deg(pd, pb); } float rx = (rotation + shearX - prx) * MathUtil::Deg_Rad; float ry = (rotation + shearY - prx + 90) * MathUtil::Deg_Rad; @@ -168,8 +169,8 @@ void Bone::updateWorldTransform(float x, float y, float rotation, float scaleX, _d = pc * lb + pd * ld; break; } - case TransformMode_NoScale: - case TransformMode_NoScaleOrReflection: { + case Inherit_NoScale: + case Inherit_NoScaleOrReflection: { rotation *= MathUtil::Deg_Rad; float cosine = MathUtil::cos(rotation); float sine = MathUtil::sin(rotation); @@ -180,7 +181,7 @@ void Bone::updateWorldTransform(float x, float y, float rotation, float scaleX, za *= s; zc *= s; s = MathUtil::sqrt(za * za + zc * zc); - if (_data.getTransformMode() == TransformMode_NoScale && + 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); @@ -213,6 +214,7 @@ void Bone::setToSetupPose() { _scaleY = data.getScaleY(); _shearX = data.getShearX(); _shearY = data.getShearY(); + _inherit = data.getInherit(); } void Bone::worldToLocal(float worldX, float worldY, float &outLocalX, float &outLocalY) { @@ -229,25 +231,39 @@ void Bone::worldToLocal(float worldX, float worldY, float &outLocalX, float &out 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; } -float Bone::worldToLocalRotation(float worldRotation) { - float sin = MathUtil::sinDeg(worldRotation); - float cos = MathUtil::cosDeg(worldRotation); +void Bone::parentToWorld(float worldX, float worldY, float &outX, float &outY) { + if (!_parent) { + outX = worldX; + outY = worldY; + } else { + _parent->localToWorld(worldX, worldY, outX, outY); + } +} - return MathUtil::atan2(_a * sin - _c * cos, _d * cos - _b * sin) * MathUtil::Rad_Deg + this->_rotation - - this->_shearX; +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 -= this->_rotation - this->_shearX; - float sin = MathUtil::sinDeg(localRotation); - float cos = MathUtil::cosDeg(localRotation); - - return MathUtil::atan2(cos * _c + sin * _d, cos * _a + sin * _b) * MathUtil::Rad_Deg; + 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) { @@ -469,11 +485,11 @@ void Bone::setWorldY(float inValue) { } float Bone::getWorldRotationX() { - return MathUtil::atan2(_c, _a) * MathUtil::Rad_Deg; + return MathUtil::atan2Deg(_c, _a); } float Bone::getWorldRotationY() { - return MathUtil::atan2(_d, _b) * MathUtil::Rad_Deg; + return MathUtil::atan2Deg(_d, _b); } float Bone::getWorldScaleX() { @@ -489,11 +505,11 @@ void Bone::updateAppliedTransform() { if (!parent) { _ax = _worldX - _skeleton.getX(); _ay = _worldY - _skeleton.getY(); - _arotation = MathUtil::atan2(_c, _a) * MathUtil::Rad_Deg; + _arotation = MathUtil::atan2Deg(_c, _a); _ascaleX = MathUtil::sqrt(_a * _a + _c * _c); _ascaleY = MathUtil::sqrt(_b * _b + _d * _d); _ashearX = 0; - _ashearY = MathUtil::atan2(_a * _b + _c * _d, _a * _d - _b * _c) * MathUtil::Rad_Deg; + _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); @@ -503,14 +519,14 @@ void Bone::updateAppliedTransform() { _ay = (dy * id - dx * ic); float ra, rb, rc, rd; - if (_data.getTransformMode() == TransformMode_OnlyTranslation) { + if (_inherit == Inherit_OnlyTranslation) { ra = _a; rb = _b; rc = _c; rd = _d; } else { - switch (_data.getTransformMode()) { - case TransformMode_NoRotationOrReflection: { + 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(); @@ -521,9 +537,10 @@ void Bone::updateAppliedTransform() { ib = pb * pid; break; } - case TransformMode_NoScale: - case TransformMode_NoScaleOrReflection: { - float cos = MathUtil::cosDeg(_rotation), sin = MathUtil::sinDeg(_rotation); + 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); @@ -531,10 +548,10 @@ void Bone::updateAppliedTransform() { pa *= s; pc *= s; s = MathUtil::sqrt(pa * pa + pc * pc); - if (_data.getTransformMode() == TransformMode_NoScale && + if (_inherit == Inherit_NoScale && pid < 0 != (_skeleton.getScaleX() < 0 != _skeleton.getScaleY() < 0)) s = -s; - float r = MathUtil::Pi / 2 + MathUtil::atan2(pc, pa); + r = MathUtil::Pi / 2 + MathUtil::atan2(pc, pa); pb = MathUtil::cos(r) * s; pd = MathUtil::sin(r) * s; pid = 1 / (pa * pd - pb * pc); @@ -544,8 +561,8 @@ void Bone::updateAppliedTransform() { id = pa * pid; break; } - case TransformMode_Normal: - case TransformMode_OnlyTranslation: + case Inherit_Normal: + case Inherit_OnlyTranslation: break; } ra = ia * _a - ib * _c; @@ -559,13 +576,13 @@ void Bone::updateAppliedTransform() { if (_ascaleX > 0.0001f) { float det = ra * rd - rb * rc; _ascaleY = det / _ascaleX; - _ashearY = -MathUtil::atan2(ra * rb + rc * rd, det) * MathUtil::Rad_Deg; - _arotation = MathUtil::atan2(rc, ra) * MathUtil::Rad_Deg; + _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::atan2(rd, rb) * MathUtil::Rad_Deg; + _arotation = 90 - MathUtil::atan2Deg(rd, rb); } } diff --git a/spine-cpp/spine-cpp/src/spine/BoneData.cpp b/spine-cpp/spine-cpp/src/spine/BoneData.cpp index 5fc6e4395..4e7d4a405 100644 --- a/spine-cpp/spine-cpp/src/spine/BoneData.cpp +++ b/spine-cpp/spine-cpp/src/spine/BoneData.cpp @@ -34,21 +34,21 @@ using namespace spine; BoneData::BoneData(int index, const String &name, BoneData *parent) : _index(index), - _name(name), - _parent(parent), - _length(0), - _x(0), - _y(0), - _rotation(0), - _scaleX(1), - _scaleY(1), - _shearX(0), - _shearY(0), - _transformMode(TransformMode_Normal), - _skinRequired(false), - _color(), - _icon(), - _visible(true) { + _name(name), + _parent(parent), + _length(0), + _x(0), + _y(0), + _rotation(0), + _scaleX(1), + _scaleY(1), + _shearX(0), + _shearY(0), + _inherit(Inherit_Normal), + _skinRequired(false), + _color(), + _icon(), + _visible(true) { assert(index >= 0); assert(_name.length() > 0); } @@ -129,12 +129,12 @@ void BoneData::setShearY(float inValue) { _shearY = inValue; } -TransformMode BoneData::getTransformMode() { - return _transformMode; +Inherit BoneData::getInherit() { + return _inherit; } -void BoneData::setTransformMode(TransformMode inValue) { - _transformMode = inValue; +void BoneData::setInherit(Inherit inValue) { + _inherit = inValue; } bool BoneData::isSkinRequired() { diff --git a/spine-cpp/spine-cpp/src/spine/IkConstraint.cpp b/spine-cpp/spine-cpp/src/spine/IkConstraint.cpp index ee47a7c4b..645838834 100644 --- a/spine-cpp/spine-cpp/src/spine/IkConstraint.cpp +++ b/spine-cpp/spine-cpp/src/spine/IkConstraint.cpp @@ -45,18 +45,18 @@ void IkConstraint::apply(Bone &bone, float targetX, float targetY, bool compress float rotationIK = -bone._ashearX - bone._arotation; float tx = 0, ty = 0; - switch (bone._data.getTransformMode()) { - case TransformMode_OnlyTranslation: + switch (bone._data.getInherit()) { + case Inherit_OnlyTranslation: tx = (targetX - bone._worldX) * MathUtil::sign(bone.getSkeleton().getScaleX()); ty = (targetY - bone._worldY) * MathUtil::sign(bone.getSkeleton().getScaleY()); break; - case TransformMode_NoRotationOrReflection: { + case Inherit_NoRotationOrReflection: { float s = MathUtil::abs(pa * pd - pb * pc) / MathUtil::max(0.0001f, pa * pa + pc * pc); float sa = pa / bone._skeleton.getScaleX(); float sc = pc / bone._skeleton.getScaleY(); pb = -sc * s * bone._skeleton.getScaleX(); pd = sa * s * bone._skeleton.getScaleY(); - rotationIK += MathUtil::atan2(sc, sa) * MathUtil::Rad_Deg; + rotationIK += MathUtil::atan2Deg(sc, sa); } default: float x = targetX - p->_worldX, y = targetY - p->_worldY; @@ -69,7 +69,7 @@ void IkConstraint::apply(Bone &bone, float targetX, float targetY, bool compress ty = (y * pa - x * pc) / d - bone._ay; } } - rotationIK += MathUtil::atan2(ty, tx) * MathUtil::Rad_Deg; + rotationIK += MathUtil::atan2Deg(ty, tx); if (bone._ascaleX < 0) rotationIK += 180; if (rotationIK > 180) rotationIK -= 360; else if (rotationIK < -180) @@ -77,9 +77,9 @@ void IkConstraint::apply(Bone &bone, float targetX, float targetY, bool compress float sx = bone._ascaleX; float sy = bone._ascaleY; if (compress || stretch) { - switch (bone._data.getTransformMode()) { - case TransformMode_NoScale: - case TransformMode_NoScaleOrReflection: + switch (bone._data.getInherit()) { + case Inherit_NoScale: + case Inherit_NoScaleOrReflection: tx = targetX - bone._worldX; ty = targetY - bone._worldY; default:; diff --git a/spine-cpp/spine-cpp/src/spine/InheritTimeline.cpp b/spine-cpp/spine-cpp/src/spine/InheritTimeline.cpp new file mode 100644 index 000000000..a5289a8ec --- /dev/null +++ b/spine-cpp/spine-cpp/src/spine/InheritTimeline.cpp @@ -0,0 +1,80 @@ +/****************************************************************************** + * Spine Runtimes License Agreement + * Last updated July 28, 2023. Replaces all prior versions. + * + * Copyright (c) 2013-2023, 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. + *****************************************************************************/ + +#include + +#include +#include + +#include +#include +#include +#include + +using namespace spine; + +RTTI_IMPL(InheritTimeline, Timeline) + +#define ENTRIES 2 +#define INHERIT 1 + +InheritTimeline::InheritTimeline(size_t frameCount, int boneIndex) : Timeline(frameCount, ENTRIES), + _boneIndex(boneIndex) { + PropertyId ids[] = {((PropertyId) Property_Inherit << 32) | boneIndex }; + setPropertyIds(ids, 1); +} + +InheritTimeline::~InheritTimeline() { +} + +void InheritTimeline::setFrame(int frame, float time, Inherit inherit) { + frame *= ENTRIES; + _frames[frame] = time; + _frames[frame + INHERIT] = inherit; +} + + +void InheritTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vector *pEvents, float alpha, + MixBlend blend, MixDirection direction) { + SP_UNUSED(lastTime); + SP_UNUSED(pEvents); + SP_UNUSED(direction); + SP_UNUSED(alpha); + + Bone *bone = skeleton.getBones()[_boneIndex]; + if (!bone->isActive()) return; + + if (time < _frames[0]) { + if (blend == MixBlend_Setup || blend == MixBlend_First) bone->_inherit = bone->_data.getInherit(); + return; + } + int idx = Animation::search(_frames, time, ENTRIES) + INHERIT; + bone->_inherit = (Inherit)_frames[idx]; +} + diff --git a/spine-cpp/spine-cpp/src/spine/PhysicsConstraint.cpp b/spine-cpp/spine-cpp/src/spine/PhysicsConstraint.cpp index a2694ad05..c632b3eb1 100644 --- a/spine-cpp/spine-cpp/src/spine/PhysicsConstraint.cpp +++ b/spine-cpp/spine-cpp/src/spine/PhysicsConstraint.cpp @@ -32,6 +32,7 @@ #include #include +#include #include using namespace spine; @@ -41,7 +42,6 @@ RTTI_IMPL(PhysicsConstraint, Updatable) PhysicsConstraint::PhysicsConstraint(PhysicsConstraintData &data, Skeleton &skeleton) : _data(data), _skeleton(skeleton) { _bone = skeleton.getBones()[data.getBone()->getIndex()]; - _inertia = data.getInertia(); _strength = data.getStrength(); _damping = data.getDamping(); @@ -324,7 +324,8 @@ void PhysicsConstraint::update(Physics physics) { reset(); // Fall through. case Physics::Physics_Update: { - _remaining += MathUtil::max(_skeleton.getTime() - _lastTime, 0.0f); + float delta = MathUtil::max(_skeleton.getTime() - _lastTime, 0.0f); + _remaining += delta; _lastTime = _skeleton.getTime(); float bx = bone->_worldX, by = bone->_worldY; @@ -333,83 +334,92 @@ void PhysicsConstraint::update(Physics physics) { _ux = bx; _uy = by; } else { - float remaining = _remaining, i = _inertia, step = _data._step; + float a = _remaining, i = _inertia, q = _data._limit * delta, t = _data._step, f = _skeleton.getData()->getReferenceScale(), d = -1; if (x || y) { - if (x) { - _xOffset += (_ux - bx) * i; - _ux = bx; - } - if (y) { - _yOffset += (_uy - by) * i; - _uy = by; - } - if (remaining >= step) { - float m = _massInverse * step, e = _strength, w = _wind * 100, g = _gravity * -100; - float d = MathUtil::pow(_damping, 60 * step); - do { - if (x) { - _xVelocity += (w - _xOffset * e) * m; - _xOffset += _xVelocity * step; - _xVelocity *= d; - } - if (y) { - _yVelocity += (g - _yOffset * e) * m; - _yOffset += _yVelocity * step; - _yVelocity *= d; - } - remaining -= step; - } while (remaining >= step); + if (x) { + float u = (_ux - bx) * i; + _xOffset += u > q ? q : u < -q ? -q : u; + _ux = bx; + } + if (y) { + float u = (_uy - by) * i; + _yOffset += u > q ? q : u < -q ? -q : u; + _uy = by; + } + if (a >= t) { + d = MathUtil::pow(_damping, 60 * t); + float m = _massInverse * t, e = _strength, w = _wind * f, g = _gravity * f; + do { + if (x) { + _xVelocity += (w - _xOffset * e) * m; + _xOffset += _xVelocity * t; + _xVelocity *= d; + } + if (y) { + _yVelocity -= (g + _yOffset * e) * m; + _yOffset += _yVelocity * t; + _yVelocity *= d; + } + a -= t; + } while (a >= t); } if (x) bone->_worldX += _xOffset * mix * _data._x; if (y) bone->_worldY += _yOffset * mix * _data._y; } - if (rotateOrShearX || scaleX) { - float ca = MathUtil::atan2(bone->_c, bone->_a), c = 0, s = 0, mr = 0; - if (rotateOrShearX) { - mr = (_data._rotate + _data._shearX) * mix; - float dx = _cx - bone->_worldX, dy = _cy - bone->_worldY; - float r = MathUtil::atan2(dy + _ty, dx + _tx) - ca - _rotateOffset * mr; - _rotateOffset += (r - MathUtil::ceil(r * MathUtil::InvPi_2 - 0.5) * MathUtil::Pi_2) * i; - r = _rotateOffset * mr + ca; - c = MathUtil::cos(r); - s = MathUtil::sin(r); - if (scaleX) { - r = l * bone->getWorldScaleX(); - if (r > 0) _scaleOffset += (dx * c + dy * s) * i / r; - } - } else { - c = MathUtil::cos(ca); - s = MathUtil::sin(ca); - float r = l * bone->getWorldScaleX(); - if (r > 0) _scaleOffset += ((this->_cx - bone->_worldX) * c + (this->_cy - bone->_worldY) * s) * i / r; - } - - remaining = _remaining; - if (remaining >= step) { - float m = _massInverse * step, e = _strength; - float d = MathUtil::pow(_damping, 60 * step); - while (true) { - remaining -= step; - if (scaleX) { - _scaleVelocity += (_wind * c - _gravity * s - _scaleOffset * e) * m; - _scaleOffset += _scaleVelocity * step; - _scaleVelocity *= d; - } - if (rotateOrShearX) { - _rotateVelocity += (-0.01f * l * (_wind * s + _gravity * c) - _rotateOffset * e) * m; - _rotateOffset += _rotateVelocity * step; - _rotateVelocity *= d; - if (remaining < step) break; - float r = _rotateOffset * mr + ca; - c = MathUtil::cos(r); - s = MathUtil::sin(r); - } else if (remaining < step)// - break; - } - } - } - _remaining = remaining; + if (rotateOrShearX || scaleX) { + float ca = MathUtil::atan2(bone->_c, bone->_a), c, s, mr = 0; + float dx = _cx - bone->_worldX, dy = _cy - bone->_worldY; + if (dx > q) + dx = q; + else if (dx < -q) // + dx = -q; + if (dy > q) + dy = q; + else if (dy < -q) // + dy = -q; + if (rotateOrShearX) { + mr = (_data._rotate + _data._shearX) * mix; + float r = MathUtil::atan2(dy + _ty, dx + _tx) - ca - _rotateOffset * mr; + _rotateOffset += (r - MathUtil::ceil(r * MathUtil::InvPi_2 - 0.5f) * MathUtil::Pi_2) * i; + r = _rotateOffset * mr + ca; + c = MathUtil::cos(r); + s = MathUtil::sin(r); + if (scaleX) { + r = l * bone->getWorldScaleX(); + if (r > 0) _scaleOffset += (dx * c + dy * s) * i / r; + } + } else { + c = MathUtil::cos(ca); + s = MathUtil::sin(ca); + float r = l * bone->getWorldScaleX(); + if (r > 0) _scaleOffset += (dx * c + dy * s) * i / r; + } + a = _remaining; + if (a >= t) { + if (d == -1) d = MathUtil::pow(_damping, 60 * t); + float m = _massInverse * t, e = _strength, w = _wind, g = _gravity, h = l / f; + while (true) { + a -= t; + if (scaleX) { + _scaleVelocity += (w * c - g * s - _scaleOffset * e) * m; + _scaleOffset += _scaleVelocity * t; + _scaleVelocity *= d; + } + if (rotateOrShearX) { + _rotateVelocity -= ((w * s + g * c) * h + _rotateOffset * e) * m; + _rotateOffset += _rotateVelocity * t; + _rotateVelocity *= d; + if (a < t) break; + float r = _rotateOffset * mr + ca; + c = MathUtil::cos(r); + s = MathUtil::sin(r); + } else if (a < t) // + break; + } + } + } + _remaining = a; } _cx = bone->_worldX; @@ -466,12 +476,9 @@ void PhysicsConstraint::update(Physics physics) { } void PhysicsConstraint::rotate(float x, float y, float degrees) { - float r = degrees * MathUtil::Deg_Rad, cos = MathUtil::cos(r), sin = MathUtil::sin(r); - r = _tx * cos - _ty * sin; - _ty = _tx * sin + _ty * cos; - _tx = r; - float dx = _cx - x, dy = _cy - y; - translate(dx * cos - dy * sin - dx, dx * sin + dy * cos - dy); + float r = degrees * MathUtil::Deg_Rad, cos = MathUtil::cos(r), sin = MathUtil::sin(r); + float dx = _cx - x, dy = _cy - y; + translate(dx * cos - dy * sin - dx, dx * sin + dy * cos - dy); } void PhysicsConstraint::translate(float x, float y) { diff --git a/spine-cpp/spine-cpp/src/spine/PhysicsConstraintData.cpp b/spine-cpp/spine-cpp/src/spine/PhysicsConstraintData.cpp index fbaa4404a..9fd92f69e 100644 --- a/spine-cpp/spine-cpp/src/spine/PhysicsConstraintData.cpp +++ b/spine-cpp/spine-cpp/src/spine/PhysicsConstraintData.cpp @@ -39,7 +39,7 @@ RTTI_IMPL(PhysicsConstraintData, ConstraintData) PhysicsConstraintData::PhysicsConstraintData(const String &name) : ConstraintData(name), _bone(nullptr), - _x(0), _y(0), _rotate(0), _scaleX(0), _shearX(0), + _x(0), _y(0), _rotate(0), _scaleX(0), _shearX(0), _limit(0), _step(0), _inertia(0), _strength(0), _damping(0), _massInverse(0), _wind(0), _gravity(0), _mix(0), _inertiaGlobal(false), _strengthGlobal(false), _dampingGlobal(false), _massGlobal(false), _windGlobal(false), _gravityGlobal(false), _mixGlobal(false) { @@ -94,6 +94,14 @@ float PhysicsConstraintData::getShearX() const { return _shearX; } +void PhysicsConstraintData::setLimit(float limit) { + _limit = limit; +} + +float PhysicsConstraintData::getLimit() const { + return _limit; +} + void PhysicsConstraintData::setStep(float step) { _step = step; } diff --git a/spine-cpp/spine-cpp/src/spine/SequenceTimeline.cpp b/spine-cpp/spine-cpp/src/spine/SequenceTimeline.cpp index c13acfe7f..38d307b33 100644 --- a/spine-cpp/spine-cpp/src/spine/SequenceTimeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/SequenceTimeline.cpp @@ -93,7 +93,7 @@ void SequenceTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vec int index = modeAndIndex >> 4, count = (int) sequence->getRegions().size(); int mode = modeAndIndex & 0xf; if (mode != SequenceMode::hold) { - index += (int) (((time - before) / delay + 0.00001)); + index += (int) (((time - before) / delay + 0.0001)); switch (mode) { case SequenceMode::once: index = MathUtil::min(count - 1, index); diff --git a/spine-cpp/spine-cpp/src/spine/ShearTimeline.cpp b/spine-cpp/spine-cpp/src/spine/ShearTimeline.cpp index 176d429fe..8434d0ff2 100644 --- a/spine-cpp/spine-cpp/src/spine/ShearTimeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/ShearTimeline.cpp @@ -158,5 +158,5 @@ void ShearYTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vecto SP_UNUSED(direction); Bone *bone = skeleton._bones[_boneIndex]; - if (bone->_active) bone->_shearY = getRelativeValue(time, alpha, blend, bone->_shearX, bone->_data._shearY); + if (bone->_active) bone->_shearY = getRelativeValue(time, alpha, blend, bone->_shearY, bone->_data._shearY); } diff --git a/spine-cpp/spine-cpp/src/spine/Skeleton.cpp b/spine-cpp/spine-cpp/src/spine/Skeleton.cpp index e39e6fe92..e6c38c096 100644 --- a/spine-cpp/spine-cpp/src/spine/Skeleton.cpp +++ b/spine-cpp/spine-cpp/src/spine/Skeleton.cpp @@ -163,7 +163,6 @@ void Skeleton::updateCache() { size_t transformCount = _transformConstraints.size(); size_t pathCount = _pathConstraints.size(); size_t physicsCount = _physicsConstraints.size(); - size_t constraintCount = ikCount + transformCount + pathCount + physicsCount; size_t i = 0; @@ -510,6 +509,10 @@ Vector &Skeleton::getTransformConstraints() { return _transformConstraints; } +Vector &Skeleton::getPhysicsConstraints() { + return _physicsConstraints; +} + Skin *Skeleton::getSkin() { return _skin; } diff --git a/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp b/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp index a19463515..9db71116a 100644 --- a/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp +++ b/spine-cpp/spine-cpp/src/spine/SkeletonBinary.cpp @@ -157,7 +157,7 @@ SkeletonData *SkeletonBinary::readSkeletonData(const unsigned char *binary, cons data->_shearX = readFloat(input); data->_shearY = readFloat(input); data->_length = readFloat(input) * _scale; - data->_transformMode = static_cast(readVarint(input, true)); + data->_inherit = static_cast(readVarint(input, true)); data->_skinRequired = readBoolean(input); if (nonessential) { readColor(input, data->getColor()); diff --git a/spine-cpp/spine-cpp/src/spine/SkeletonData.cpp b/spine-cpp/spine-cpp/src/spine/SkeletonData.cpp index 00a9bbcce..c3f4fd6e8 100644 --- a/spine-cpp/spine-cpp/src/spine/SkeletonData.cpp +++ b/spine-cpp/spine-cpp/src/spine/SkeletonData.cpp @@ -49,6 +49,7 @@ SkeletonData::SkeletonData() : _name(), _y(0), _width(0), _height(0), + _referenceScale(100), _version(), _hash(), _fps(0), @@ -193,6 +194,14 @@ void SkeletonData::setHeight(float inValue) { _height = inValue; } +float SkeletonData::getReferenceScale() { + return _referenceScale; +} + +void SkeletonData::setReferenceScale(float inValue) { + _referenceScale = inValue; +} + const String &SkeletonData::getVersion() { return _version; } diff --git a/spine-cpp/spine-cpp/src/spine/SkeletonJson.cpp b/spine-cpp/spine-cpp/src/spine/SkeletonJson.cpp index ac21f0ab7..92c2903dc 100644 --- a/spine-cpp/spine-cpp/src/spine/SkeletonJson.cpp +++ b/spine-cpp/spine-cpp/src/spine/SkeletonJson.cpp @@ -194,17 +194,17 @@ SkeletonData *SkeletonJson::readSkeletonData(const char *json) { data->_scaleY = Json::getFloat(boneMap, "scaleY", 1); data->_shearX = Json::getFloat(boneMap, "shearX", 0); data->_shearY = Json::getFloat(boneMap, "shearY", 0); - transformMode = Json::getString(boneMap, "transform", "normal"); - data->_transformMode = TransformMode_Normal; - if (strcmp(transformMode, "normal") == 0) data->_transformMode = TransformMode_Normal; + transformMode = Json::getString(boneMap, "inherit", "normal"); + data->_inherit = Inherit_Normal; + if (strcmp(transformMode, "normal") == 0) data->_inherit = Inherit_Normal; else if (strcmp(transformMode, "onlyTranslation") == 0) - data->_transformMode = TransformMode_OnlyTranslation; + data->_inherit = Inherit_OnlyTranslation; else if (strcmp(transformMode, "noRotationOrReflection") == 0) - data->_transformMode = TransformMode_NoRotationOrReflection; + data->_inherit = Inherit_NoRotationOrReflection; else if (strcmp(transformMode, "noScale") == 0) - data->_transformMode = TransformMode_NoScale; + data->_inherit = Inherit_NoScale; else if (strcmp(transformMode, "noScaleOrReflection") == 0) - data->_transformMode = TransformMode_NoScaleOrReflection; + data->_inherit = Inherit_NoScaleOrReflection; data->_skinRequired = Json::getBoolean(boneMap, "skin", false); const char *color = Json::getString(boneMap, "color", NULL); diff --git a/spine-cpp/spine-cpp/src/spine/Skin.cpp b/spine-cpp/spine-cpp/src/spine/Skin.cpp index 57ec0e19a..782b59491 100644 --- a/spine-cpp/spine-cpp/src/spine/Skin.cpp +++ b/spine-cpp/spine-cpp/src/spine/Skin.cpp @@ -88,7 +88,7 @@ Skin::AttachmentMap::Entries Skin::AttachmentMap::getEntries() { return Skin::AttachmentMap::Entries(_buckets); } -Skin::Skin(const String &name) : _name(name), _attachments() { +Skin::Skin(const String &name) : _name(name), _attachments(), _color(0.99607843f, 0.61960787f, 0.30980393f, 1) { assert(_name.length() > 0); } diff --git a/spine-sdl/src/spine-sdl-cpp.cpp b/spine-sdl/src/spine-sdl-cpp.cpp index 1438a3afb..9c213aec4 100644 --- a/spine-sdl/src/spine-sdl-cpp.cpp +++ b/spine-sdl/src/spine-sdl-cpp.cpp @@ -54,7 +54,8 @@ SkeletonDrawable::~SkeletonDrawable() { void SkeletonDrawable::update(float delta) { animationState->update(delta); animationState->apply(*skeleton); - skeleton->updateWorldTransform(); + skeleton->update(delta); + skeleton->updateWorldTransform(Physics_Update); } void SkeletonDrawable::draw(SDL_Renderer *renderer) {