From 2868c79f7ce29622465fdf1ba26a8389da917a81 Mon Sep 17 00:00:00 2001 From: Mario Zechner Date: Mon, 23 Jun 2025 16:40:17 +0200 Subject: [PATCH] [cpp] 4.3 porting WIP --- spine-cpp/spine-cpp/include/spine/BoneData.h | 2 +- .../spine-cpp/include/spine/ConstraintData.h | 4 +- .../include/spine/IkConstraintTimeline.h | 2 +- spine-cpp/spine-cpp/include/spine/Posed.h | 10 +- spine-cpp/spine-cpp/include/spine/PosedData.h | 74 +-- spine-cpp/spine-cpp/include/spine/Skeleton.h | 2 +- .../spine-cpp/include/spine/SkeletonData.h | 2 +- spine-cpp/spine-cpp/include/spine/SlotData.h | 2 +- spine-cpp/spine-cpp/src/spine/BoneData.cpp | 2 +- .../src/spine/IkConstraintTimeline.cpp | 55 +- .../spine-cpp/src/spine/RegionAttachment.cpp | 2 +- spine-cpp/spine-cpp/src/spine/SkeletonNew.cpp | 569 ------------------ spine-cpp/spine-cpp/src/spine/Slot.cpp | 2 +- spine-cpp/spine-cpp/src/spine/SlotData.cpp | 2 +- 14 files changed, 86 insertions(+), 644 deletions(-) delete mode 100644 spine-cpp/spine-cpp/src/spine/SkeletonNew.cpp diff --git a/spine-cpp/spine-cpp/include/spine/BoneData.h b/spine-cpp/spine-cpp/include/spine/BoneData.h index a40a5a41a..8a1361a23 100644 --- a/spine-cpp/spine-cpp/include/spine/BoneData.h +++ b/spine-cpp/spine-cpp/include/spine/BoneData.h @@ -37,7 +37,7 @@ #include namespace spine { - class SP_API BoneData : public PosedData { + class SP_API BoneData : public PosedDataGeneric { friend class SkeletonBinary; friend class SkeletonJson; diff --git a/spine-cpp/spine-cpp/include/spine/ConstraintData.h b/spine-cpp/spine-cpp/include/spine/ConstraintData.h index 6b4421891..1622fa08f 100644 --- a/spine-cpp/spine-cpp/include/spine/ConstraintData.h +++ b/spine-cpp/spine-cpp/include/spine/ConstraintData.h @@ -50,12 +50,12 @@ namespace spine { /// Generic base class for all constraint data. template - class SP_API ConstraintDataGeneric : public PosedData

, public ConstraintData { + class SP_API ConstraintDataGeneric : public PosedDataGeneric

, public ConstraintData { friend class SkeletonBinary; friend class SkeletonJson; public: - ConstraintDataGeneric(const String &name) : PosedData

(name), ConstraintData(name) { + ConstraintDataGeneric(const String &name) : PosedDataGeneric

(name), ConstraintData(name) { } virtual ~ConstraintDataGeneric() { } diff --git a/spine-cpp/spine-cpp/include/spine/IkConstraintTimeline.h b/spine-cpp/spine-cpp/include/spine/IkConstraintTimeline.h index 18bfd0f2f..c0cff1bd3 100644 --- a/spine-cpp/spine-cpp/include/spine/IkConstraintTimeline.h +++ b/spine-cpp/spine-cpp/include/spine/IkConstraintTimeline.h @@ -46,7 +46,7 @@ namespace spine { virtual void apply(Skeleton &skeleton, float lastTime, float time, Vector *pEvents, float alpha, MixBlend blend, - MixDirection direction) override; + MixDirection direction, bool appliedPose) override; /// Sets the time, mix and bend direction of the specified keyframe. void setFrame(int frame, float time, float mix, float softness, int bendDirection, bool compress, bool stretch); diff --git a/spine-cpp/spine-cpp/include/spine/Posed.h b/spine-cpp/spine-cpp/include/spine/Posed.h index 7cd986b37..9104efd72 100644 --- a/spine-cpp/spine-cpp/include/spine/Posed.h +++ b/spine-cpp/spine-cpp/include/spine/Posed.h @@ -39,6 +39,8 @@ namespace spine { Posed() {} virtual ~Posed() {} + virtual void setupPose() = 0; + virtual void resetConstrained() = 0; virtual void pose() = 0; @@ -84,7 +86,7 @@ namespace spine { virtual ~PosedGeneric() { } - void setupPose() { + virtual void setupPose() override { _pose.set(_data.getSetupPose()); } @@ -103,15 +105,15 @@ namespace spine { return *_applied; } - virtual void resetConstrained() { + virtual void resetConstrained() override { _constrained.set(_pose); } - virtual void pose() { + virtual void pose() override { _applied = &_pose; } - virtual void constrained() { + virtual void constrained() override { _applied = &_constrained; } diff --git a/spine-cpp/spine-cpp/include/spine/PosedData.h b/spine-cpp/spine-cpp/include/spine/PosedData.h index 172f8bdb4..415632787 100644 --- a/spine-cpp/spine-cpp/include/spine/PosedData.h +++ b/spine-cpp/spine-cpp/include/spine/PosedData.h @@ -37,8 +37,6 @@ namespace spine { template class Pose; - /// The base class for all constrained datas. - template class SP_API PosedData : public SpineObject { friend class SkeletonBinary; friend class SkeletonJson; @@ -62,62 +60,66 @@ namespace spine { friend class TranslateYTimeline; friend class InheritTimeline; - protected: - spine::String _name; - P _setup; - bool _skinRequired; - public: PosedData(const spine::String& name); virtual ~PosedData(); /// The constraint's name, which is unique across all constraints in the skeleton of the same type. - const spine::String& getName(); - - P& getSetupPose(); + const spine::String& getName() { return _name; }; /// When true, Skeleton::updateWorldTransform(Physics) only updates this constraint if the Skeleton::getSkin() /// contains this constraint. /// /// See Skin::getConstraints(). - bool getSkinRequired(); - void setSkinRequired(bool skinRequired); + bool getSkinRequired() { return _skinRequired; }; + void setSkinRequired(bool skinRequired) { _skinRequired = skinRequired; }; - virtual spine::String toString(); + protected: + spine::String _name; + bool _skinRequired; }; - template - PosedData

::PosedData(const spine::String& name) : _name(name), _setup(), _skinRequired(false) { + inline PosedData::PosedData(const spine::String& name) : _name(name), _skinRequired(false) { } - template - PosedData

::~PosedData() { + inline PosedData::~PosedData() { } + /// The base class for all constrained datas. template - const spine::String& PosedData

::getName() { - return _name; - } + class SP_API PosedDataGeneric : public PosedData { + friend class SkeletonBinary; + friend class SkeletonJson; + friend class BoneTimeline1; + friend class BoneTimeline2; + friend class RotateTimeline; + 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; - template - P& PosedData

::getSetupPose() { - return _setup; - } + protected: + P _setup; - template - bool PosedData

::getSkinRequired() { - return _skinRequired; + public: + PosedDataGeneric(const spine::String& name): PosedData(name), _setup() { } + virtual ~PosedDataGeneric() {}; - template - void PosedData

::setSkinRequired(bool skinRequired) { - _skinRequired = skinRequired; - } - - template - spine::String PosedData

::toString() { - return _name; - } + P& getSetupPose() { return _setup; }; + }; } #endif \ No newline at end of file diff --git a/spine-cpp/spine-cpp/include/spine/Skeleton.h b/spine-cpp/spine-cpp/include/spine/Skeleton.h index a23aca6f1..e1dede9d8 100644 --- a/spine-cpp/spine-cpp/include/spine/Skeleton.h +++ b/spine-cpp/spine-cpp/include/spine/Skeleton.h @@ -222,7 +222,7 @@ namespace spine { Vector &getPhysicsConstraints(); - template + template T *findConstraint(const String &constraintName) { if (constraintName.isEmpty()) return NULL; for (size_t i = 0; i < _constraints.size(); i++) { diff --git a/spine-cpp/spine-cpp/include/spine/SkeletonData.h b/spine-cpp/spine-cpp/include/spine/SkeletonData.h index 2362ce620..b6df5c3fd 100644 --- a/spine-cpp/spine-cpp/include/spine/SkeletonData.h +++ b/spine-cpp/spine-cpp/include/spine/SkeletonData.h @@ -141,7 +141,7 @@ namespace spine { /// Finds a constraint by name and type. /// @return May be NULL. - template + template T *findConstraint(const String &constraintName) { getConstraints(); // Ensure constraints array is populated for (size_t i = 0, n = _constraints.size(); i < n; i++) { diff --git a/spine-cpp/spine-cpp/include/spine/SlotData.h b/spine-cpp/spine-cpp/include/spine/SlotData.h index 7caf4fb09..456b2f28a 100644 --- a/spine-cpp/spine-cpp/include/spine/SlotData.h +++ b/spine-cpp/spine-cpp/include/spine/SlotData.h @@ -40,7 +40,7 @@ namespace spine { class BoneData; /// Stores the setup pose for a Slot. - class SP_API SlotData : public PosedData { + class SP_API SlotData : public PosedDataGeneric { friend class SkeletonBinary; friend class SkeletonJson; friend class PathConstraint; diff --git a/spine-cpp/spine-cpp/src/spine/BoneData.cpp b/spine-cpp/spine-cpp/src/spine/BoneData.cpp index ba3ce6508..a78ccbc5b 100644 --- a/spine-cpp/spine-cpp/src/spine/BoneData.cpp +++ b/spine-cpp/spine-cpp/src/spine/BoneData.cpp @@ -33,7 +33,7 @@ using namespace spine; -BoneData::BoneData(int index, const String &name, BoneData *parent) : PosedData(name), +BoneData::BoneData(int index, const String &name, BoneData *parent) : PosedDataGeneric(name), _index(index), _parent(parent), _length(0), diff --git a/spine-cpp/spine-cpp/src/spine/IkConstraintTimeline.cpp b/spine-cpp/spine-cpp/src/spine/IkConstraintTimeline.cpp index f0d0cb14c..b9221c70d 100644 --- a/spine-cpp/spine-cpp/src/spine/IkConstraintTimeline.cpp +++ b/spine-cpp/spine-cpp/src/spine/IkConstraintTimeline.cpp @@ -50,9 +50,10 @@ IkConstraintTimeline::IkConstraintTimeline(size_t frameCount, size_t bezierCount } void IkConstraintTimeline::apply(Skeleton &skeleton, float lastTime, float time, Vector *pEvents, float alpha, - MixBlend blend, MixDirection direction) { + MixBlend blend, MixDirection direction, bool appliedPose) { SP_UNUSED(lastTime); SP_UNUSED(pEvents); + SP_UNUSED(appliedPose); IkConstraint *constraintP = (IkConstraint *) skeleton._constraints[_constraintIndex]; IkConstraint &constraint = *constraintP; @@ -61,18 +62,20 @@ void IkConstraintTimeline::apply(Skeleton &skeleton, float lastTime, float time, if (time < _frames[0]) { switch (blend) { case MixBlend_Setup: - constraint._mix = constraint._data._mix; - constraint._softness = constraint._data._softness; - constraint._bendDirection = constraint._data._bendDirection; - constraint._compress = constraint._data._compress; - constraint._stretch = constraint._data._stretch; + constraint.getAppliedPose().setMix(constraint._data.getSetupPose().getMix()); + constraint.getAppliedPose().setSoftness(constraint._data.getSetupPose().getSoftness()); + constraint.getAppliedPose().setBendDirection(constraint._data.getSetupPose().getBendDirection()); + constraint.getAppliedPose().setCompress(constraint._data.getSetupPose().getCompress()); + constraint.getAppliedPose().setStretch(constraint._data.getSetupPose().getStretch()); return; case MixBlend_First: - constraint._mix += (constraint._data._mix - constraint._mix) * alpha; - constraint._softness += (constraint._data._softness - constraint._softness) * alpha; - constraint._bendDirection = constraint._data._bendDirection; - constraint._compress = constraint._data._compress; - constraint._stretch = constraint._data._stretch; + constraint.getAppliedPose().setMix(constraint.getAppliedPose().getMix() + + (constraint._data.getSetupPose().getMix() - constraint.getAppliedPose().getMix()) * alpha); + constraint.getAppliedPose().setSoftness(constraint.getAppliedPose().getSoftness() + + (constraint._data.getSetupPose().getSoftness() - constraint.getAppliedPose().getSoftness()) * alpha); + constraint.getAppliedPose().setBendDirection(constraint._data.getSetupPose().getBendDirection()); + constraint.getAppliedPose().setCompress(constraint._data.getSetupPose().getCompress()); + constraint.getAppliedPose().setStretch(constraint._data.getSetupPose().getStretch()); return; default: return; @@ -106,25 +109,29 @@ void IkConstraintTimeline::apply(Skeleton &skeleton, float lastTime, float time, } if (blend == MixBlend_Setup) { - constraint._mix = constraint._data._mix + (mix - constraint._data._mix) * alpha; - constraint._softness = constraint._data._softness + (softness - constraint._data._softness) * alpha; + constraint.getAppliedPose().setMix(constraint._data.getSetupPose().getMix() + + (mix - constraint._data.getSetupPose().getMix()) * alpha); + constraint.getAppliedPose().setSoftness(constraint._data.getSetupPose().getSoftness() + + (softness - constraint._data.getSetupPose().getSoftness()) * alpha); if (direction == MixDirection_Out) { - constraint._bendDirection = constraint._data._bendDirection; - constraint._compress = constraint._data._compress; - constraint._stretch = constraint._data._stretch; + constraint.getAppliedPose().setBendDirection(constraint._data.getSetupPose().getBendDirection()); + constraint.getAppliedPose().setCompress(constraint._data.getSetupPose().getCompress()); + constraint.getAppliedPose().setStretch(constraint._data.getSetupPose().getStretch()); } else { - constraint._bendDirection = _frames[i + IkConstraintTimeline::BEND_DIRECTION]; - constraint._compress = _frames[i + IkConstraintTimeline::COMPRESS] != 0; - constraint._stretch = _frames[i + IkConstraintTimeline::STRETCH] != 0; + constraint.getAppliedPose().setBendDirection(_frames[i + IkConstraintTimeline::BEND_DIRECTION]); + constraint.getAppliedPose().setCompress(_frames[i + IkConstraintTimeline::COMPRESS] != 0); + constraint.getAppliedPose().setStretch(_frames[i + IkConstraintTimeline::STRETCH] != 0); } } else { - constraint._mix += (mix - constraint._mix) * alpha; - constraint._softness += (softness - constraint._softness) * alpha; + constraint.getAppliedPose().setMix(constraint.getAppliedPose().getMix() + + (mix - constraint.getAppliedPose().getMix()) * alpha); + constraint.getAppliedPose().setSoftness(constraint.getAppliedPose().getSoftness() + + (softness - constraint.getAppliedPose().getSoftness()) * alpha); if (direction == MixDirection_In) { - constraint._bendDirection = _frames[i + IkConstraintTimeline::BEND_DIRECTION]; - constraint._compress = _frames[i + IkConstraintTimeline::COMPRESS] != 0; - constraint._stretch = _frames[i + IkConstraintTimeline::STRETCH] != 0; + constraint.getAppliedPose().setBendDirection(_frames[i + IkConstraintTimeline::BEND_DIRECTION]); + constraint.getAppliedPose().setCompress(_frames[i + IkConstraintTimeline::COMPRESS] != 0); + constraint.getAppliedPose().setStretch(_frames[i + IkConstraintTimeline::STRETCH] != 0); } } } diff --git a/spine-cpp/spine-cpp/src/spine/RegionAttachment.cpp b/spine-cpp/spine-cpp/src/spine/RegionAttachment.cpp index 875db9591..c0245db54 100644 --- a/spine-cpp/spine-cpp/src/spine/RegionAttachment.cpp +++ b/spine-cpp/spine-cpp/src/spine/RegionAttachment.cpp @@ -133,7 +133,7 @@ void RegionAttachment::computeWorldVertices(Slot &slot, Vector &worldVert } void RegionAttachment::computeWorldVertices(Slot &slot, float *worldVertices, size_t offset, size_t stride) { - if (_sequence) _sequence->apply(slot.getAppliedPose(), this); + if (_sequence) _sequence->apply(&slot.getAppliedPose(), this); BonePose &bone = slot.getBone().getAppliedPose(); float x = bone.getWorldX(), y = bone.getWorldY(); diff --git a/spine-cpp/spine-cpp/src/spine/SkeletonNew.cpp b/spine-cpp/spine-cpp/src/spine/SkeletonNew.cpp deleted file mode 100644 index aef67cce1..000000000 --- a/spine-cpp/spine-cpp/src/spine/SkeletonNew.cpp +++ /dev/null @@ -1,569 +0,0 @@ -/****************************************************************************** - * 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. - *****************************************************************************/ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace spine; - -static const unsigned short quadTriangles[] = {0, 1, 2, 2, 3, 0}; - -Skeleton::Skeleton(SkeletonData &skeletonData) : _data(skeletonData), _skin(NULL), _color(1, 1, 1, 1), - _scaleX(1), _scaleY(1), _x(0), _y(0), _time(0), _windX(1), _windY(0), _gravityX(0), _gravityY(1), _update(0) { - - // Create bones - _bones.ensureCapacity(_data.getBones().size()); - Vector &boneDataArray = _data.getBones(); - for (size_t i = 0; i < boneDataArray.size(); ++i) { - BoneData *boneData = boneDataArray[i]; - Bone *bone; - if (boneData->getParent() == NULL) { - bone = new (__FILE__, __LINE__) Bone(*boneData, NULL); - } else { - Bone *parent = _bones[boneData->getParent()->getIndex()]; - bone = new (__FILE__, __LINE__) Bone(*boneData, parent); - parent->getChildren().add(bone); - } - _bones.add(bone); - } - - // Create slots - _slots.ensureCapacity(_data.getSlots().size()); - _drawOrder.ensureCapacity(_data.getSlots().size()); - Vector &slotDataArray = _data.getSlots(); - for (size_t i = 0; i < slotDataArray.size(); ++i) { - SlotData *slotData = slotDataArray[i]; - Slot *slot = new (__FILE__, __LINE__) Slot(*slotData, *this); - _slots.add(slot); - _drawOrder.add(slot); - } - - // Create constraints and physics - _physics.ensureCapacity(8); - _constraints.ensureCapacity(_data.getConstraints().size()); - Vector &constraintDataArray = _data.getConstraints(); - for (size_t i = 0; i < constraintDataArray.size(); ++i) { - ConstraintData *constraintData = constraintDataArray[i]; - Constraint *constraint = constraintData->create(*this); - PhysicsConstraint *physicsConstraint = dynamic_cast(constraint); - if (physicsConstraint != NULL) { - _physics.add(physicsConstraint); - } - _constraints.add(constraint); - } - _physics.shrink(); - - updateCache(); -} - -Skeleton::~Skeleton() { - for (size_t i = 0; i < _bones.size(); ++i) { - delete _bones[i]; - } - for (size_t i = 0; i < _slots.size(); ++i) { - delete _slots[i]; - } - for (size_t i = 0; i < _constraints.size(); ++i) { - delete _constraints[i]; - } -} - -void Skeleton::updateCache() { - _updateCache.clear(); - - // Reset slot applied poses to current pose - for (size_t i = 0; i < _slots.size(); ++i) { - Slot *slot = _slots[i]; - slot->getAppliedPose().set(slot->getPose()); - } - - // Mark bones based on skin requirements - size_t boneCount = _bones.size(); - for (size_t i = 0; i < boneCount; ++i) { - Bone *bone = _bones[i]; - bone->_sorted = bone->getData().getSkinRequired(); - bone->_active = !bone->_sorted; - bone->getAppliedPose().set(bone->getPose()); - } - - // Activate bones required by skin - if (_skin != NULL) { - Vector &skinBones = _skin->getBones(); - for (size_t i = 0; i < skinBones.size(); ++i) { - Bone *bone = _bones[skinBones[i]->getIndex()]; - do { - bone->_sorted = false; - bone->_active = true; - bone = bone->getParent(); - } while (bone != NULL); - } - } - - // Set constraint applied poses and mark active constraints - for (size_t i = 0; i < _constraints.size(); ++i) { - Constraint *constraint = _constraints[i]; - constraint->getAppliedPose().set(constraint->getPose()); - } - - for (size_t i = 0; i < _constraints.size(); ++i) { - Constraint *constraint = _constraints[i]; - constraint->_active = constraint->isSourceActive() && - (!constraint->getData().getSkinRequired() || (_skin != NULL && _skin->getConstraints().contains(&constraint->getData(), true))); - if (constraint->_active) { - constraint->sort(*this); - } - } - - // Sort all bones - for (size_t i = 0; i < boneCount; ++i) { - sortBone(_bones[i]); - } - - // Replace bone references in update cache with their applied poses - for (size_t i = 0; i < _updateCache.size(); ++i) { - Update *updateItem = _updateCache[i]; - Bone *bone = dynamic_cast(updateItem); - if (bone != NULL) { - _updateCache[i] = &bone->getAppliedPose(); - } - } -} - -void Skeleton::constrained(Posed &object) { - if (&object.getPose() == &object.getAppliedPose()) { - object.setAppliedPose(object.getConstrainedPose()); - // Add to reset cache - this would need a resetCache member like Java - } -} - -void Skeleton::sortBone(Bone *bone) { - if (bone->_sorted || !bone->_active) return; - Bone *parent = bone->getParent(); - if (parent != NULL) sortBone(parent); - bone->_sorted = true; - _updateCache.add(bone); -} - -void Skeleton::sortReset(Vector &bones) { - for (size_t i = 0; i < bones.size(); ++i) { - Bone *bone = bones[i]; - if (bone->_active) { - if (bone->_sorted) sortReset(bone->getChildren()); - bone->_sorted = false; - } - } -} - -void Skeleton::updateWorldTransform(Physics physics) { - _update++; - - // Reset all applied poses to their base poses - // This would require a resetCache implementation like Java has - - // Update all items in update cache - for (size_t i = 0; i < _updateCache.size(); ++i) { - Update *updateItem = _updateCache[i]; - updateItem->update(*this, physics); - } -} - -void Skeleton::updateWorldTransform(Physics physics, BonePose *parent) { - if (parent == NULL) return; - - _update++; - - // Reset all applied poses to their base poses - // This would require a resetCache implementation like Java has - - // Apply the parent bone transform to the root bone - BonePose &rootBone = getRootBone()->getAppliedPose(); - float pa = parent->getA(), pb = parent->getB(), pc = parent->getC(), pd = parent->getD(); - rootBone.setWorldX(pa * _x + pb * _y + parent->getWorldX()); - rootBone.setWorldY(pc * _x + pd * _y + parent->getWorldY()); - - float rx = (rootBone.getRotation() + rootBone.getShearX()) * MathUtil::Deg_Rad; - float ry = (rootBone.getRotation() + 90 + rootBone.getShearY()) * MathUtil::Deg_Rad; - float la = MathUtil::cos(rx) * rootBone.getScaleX(); - float lb = MathUtil::cos(ry) * rootBone.getScaleY(); - float lc = MathUtil::sin(rx) * rootBone.getScaleX(); - float ld = MathUtil::sin(ry) * rootBone.getScaleY(); - rootBone.setA((pa * la + pb * lc) * _scaleX); - rootBone.setB((pa * lb + pb * ld) * _scaleX); - rootBone.setC((pc * la + pd * lc) * _scaleY); - rootBone.setD((pc * lb + pd * ld) * _scaleY); - - // Update everything except root bone - for (size_t i = 0; i < _updateCache.size(); ++i) { - Update *updateItem = _updateCache[i]; - if (updateItem != &rootBone) { - updateItem->update(*this, physics); - } - } -} - -void Skeleton::setupPose() { - setupPoseBones(); - setupPoseSlots(); -} - -void Skeleton::setupPoseBones() { - for (size_t i = 0; i < _bones.size(); ++i) { - _bones[i]->setupPose(); - } - for (size_t i = 0; i < _constraints.size(); ++i) { - _constraints[i]->setupPose(); - } -} - -void Skeleton::setupPoseSlots() { - // Copy slots to draw order in setup pose order - for (size_t i = 0; i < _slots.size(); ++i) { - _drawOrder[i] = _slots[i]; - } - for (size_t i = 0; i < _slots.size(); ++i) { - _slots[i]->setupPose(); - } -} - -SkeletonData *Skeleton::getData() { - return &_data; -} - -Vector &Skeleton::getBones() { - return _bones; -} - -Vector &Skeleton::getUpdateCache() { - return _updateCache; -} - -Bone *Skeleton::getRootBone() { - return _bones.size() == 0 ? NULL : _bones[0]; -} - -Bone *Skeleton::findBone(const String &boneName) { - if (boneName.isEmpty()) return NULL; - for (size_t i = 0; i < _bones.size(); ++i) { - if (_bones[i]->getData().getName() == boneName) { - return _bones[i]; - } - } - return NULL; -} - -Vector &Skeleton::getSlots() { - return _slots; -} - -Slot *Skeleton::findSlot(const String &slotName) { - if (slotName.isEmpty()) return NULL; - for (size_t i = 0; i < _slots.size(); ++i) { - if (_slots[i]->getData().getName() == slotName) { - return _slots[i]; - } - } - return NULL; -} - -Vector &Skeleton::getDrawOrder() { - return _drawOrder; -} - -Skin *Skeleton::getSkin() { - return _skin; -} - -void Skeleton::setSkin(const String &skinName) { - Skin *skin = _data.findSkin(skinName); - if (skin == NULL && !skinName.isEmpty()) { - // Handle error - skin not found - return; - } - setSkin(skin); -} - -void Skeleton::setSkin(Skin *newSkin) { - if (newSkin == _skin) return; - if (newSkin != NULL) { - if (_skin != NULL) { - newSkin->attachAll(*this, *_skin); - } else { - for (size_t i = 0; i < _slots.size(); ++i) { - Slot *slot = _slots[i]; - const String &name = slot->getData().getAttachmentName(); - if (!name.isEmpty()) { - Attachment *attachment = newSkin->getAttachment((int) i, name); - if (attachment != NULL) { - slot->getPose().setAttachment(attachment); - } - } - } - } - } - _skin = newSkin; - updateCache(); -} - -Attachment *Skeleton::getAttachment(const String &slotName, const String &attachmentName) { - SlotData *slotData = _data.findSlot(slotName); - if (slotData == NULL) return NULL; - return getAttachment(slotData->getIndex(), attachmentName); -} - -Attachment *Skeleton::getAttachment(int slotIndex, const String &attachmentName) { - if (attachmentName.isEmpty()) return NULL; - if (_skin != NULL) { - Attachment *attachment = _skin->getAttachment(slotIndex, attachmentName); - if (attachment != NULL) return attachment; - } - if (_data.getDefaultSkin() != NULL) { - return _data.getDefaultSkin()->getAttachment(slotIndex, attachmentName); - } - return NULL; -} - -void Skeleton::setAttachment(const String &slotName, const String &attachmentName) { - if (slotName.isEmpty()) return; - Slot *slot = findSlot(slotName); - if (slot == NULL) return; - Attachment *attachment = NULL; - if (!attachmentName.isEmpty()) { - attachment = getAttachment(slot->getData().getIndex(), attachmentName); - if (attachment == NULL) { - // Handle error - attachment not found - return; - } - } - slot->getPose().setAttachment(attachment); -} - -Vector &Skeleton::getConstraints() { - return _constraints; -} - -Vector &Skeleton::getPhysicsConstraints() { - return _physics; -} - -void Skeleton::getBounds(float &outX, float &outY, float &outWidth, float &outHeight, Vector &outVertexBuffer) { - getBounds(outX, outY, outWidth, outHeight, outVertexBuffer, NULL); -} - -void Skeleton::getBounds(float &outX, float &outY, float &outWidth, float &outHeight, Vector &outVertexBuffer, SkeletonClipping *clipper) { - float minX = FLT_MAX, minY = FLT_MAX, maxX = -FLT_MAX, maxY = -FLT_MAX; - - for (size_t i = 0; i < _drawOrder.size(); ++i) { - Slot *slot = _drawOrder[i]; - if (!slot->getBone().isActive()) continue; - - size_t verticesLength = 0; - float *vertices = NULL; - const unsigned short *triangles = NULL; - Attachment *attachment = slot->getPose().getAttachment(); - - if (attachment != NULL) { - RegionAttachment *region = dynamic_cast(attachment); - if (region != NULL) { - verticesLength = 8; - outVertexBuffer.setSize(8); - vertices = outVertexBuffer.buffer(); - region->computeWorldVertices(*slot, vertices, 0, 2); - triangles = quadTriangles; - } else { - MeshAttachment *mesh = dynamic_cast(attachment); - if (mesh != NULL) { - verticesLength = mesh->getWorldVerticesLength(); - outVertexBuffer.setSize(verticesLength); - vertices = outVertexBuffer.buffer(); - mesh->computeWorldVertices(*this, *slot, 0, verticesLength, vertices, 0, 2); - triangles = mesh->getTriangles().buffer(); - } else { - ClippingAttachment *clip = dynamic_cast(attachment); - if (clip != NULL && clipper != NULL) { - clipper->clipEnd(*slot); - clipper->clipStart(*this, *slot, *clip); - continue; - } - } - } - - if (vertices != NULL) { - if (clipper != NULL && clipper->isClipping() && clipper->clipTriangles(vertices, triangles, 6)) { - vertices = clipper->getClippedVertices().buffer(); - verticesLength = clipper->getClippedVertices().size(); - } - for (size_t ii = 0; ii < verticesLength; ii += 2) { - float x = vertices[ii], y = vertices[ii + 1]; - minX = MathUtil::min(minX, x); - minY = MathUtil::min(minY, y); - maxX = MathUtil::max(maxX, x); - maxY = MathUtil::max(maxY, y); - } - } - } - if (clipper != NULL) clipper->clipEnd(*slot); - } - if (clipper != NULL) clipper->clipEnd(); - - outX = minX; - outY = minY; - outWidth = maxX - minX; - outHeight = maxY - minY; -} - -Color &Skeleton::getColor() { - return _color; -} - -void Skeleton::setColor(Color &color) { - _color = color; -} - -float Skeleton::getScaleX() { - return _scaleX; -} - -void Skeleton::setScaleX(float inValue) { - _scaleX = inValue; -} - -float Skeleton::getScaleY() { - return _scaleY; -} - -void Skeleton::setScaleY(float inValue) { - _scaleY = inValue; -} - -void Skeleton::setScale(float scaleX, float scaleY) { - _scaleX = scaleX; - _scaleY = scaleY; -} - -float Skeleton::getX() { - return _x; -} - -void Skeleton::setX(float inValue) { - _x = inValue; -} - -float Skeleton::getY() { - return _y; -} - -void Skeleton::setY(float inValue) { - _y = inValue; -} - -void Skeleton::setPosition(float x, float y) { - _x = x; - _y = y; -} - -float Skeleton::getWindX() { - return _windX; -} - -void Skeleton::setWindX(float windX) { - _windX = windX; -} - -float Skeleton::getWindY() { - return _windY; -} - -void Skeleton::setWindY(float windY) { - _windY = windY; -} - -float Skeleton::getGravityX() { - return _gravityX; -} - -void Skeleton::setGravityX(float gravityX) { - _gravityX = gravityX; -} - -float Skeleton::getGravityY() { - return _gravityY; -} - -void Skeleton::setGravityY(float gravityY) { - _gravityY = gravityY; -} - -void Skeleton::physicsTranslate(float x, float y) { - for (size_t i = 0; i < _physics.size(); ++i) { - _physics[i]->translate(x, y); - } -} - -void Skeleton::physicsRotate(float x, float y, float degrees) { - for (size_t i = 0; i < _physics.size(); ++i) { - _physics[i]->rotate(x, y, degrees); - } -} - -float Skeleton::getTime() { - return _time; -} - -void Skeleton::setTime(float time) { - _time = time; -} - -void Skeleton::update(float delta) { - _time += delta; -} \ No newline at end of file diff --git a/spine-cpp/spine-cpp/src/spine/Slot.cpp b/spine-cpp/spine-cpp/src/spine/Slot.cpp index 888f48e0a..e40c7bde0 100644 --- a/spine-cpp/spine-cpp/src/spine/Slot.cpp +++ b/spine-cpp/spine-cpp/src/spine/Slot.cpp @@ -37,7 +37,7 @@ using namespace spine; -Slot::Slot(SlotData &data, Skeleton &skeleton) : Posed(data), +Slot::Slot(SlotData &data, Skeleton &skeleton) : PosedGeneric(data), _skeleton(skeleton), _bone(*skeleton.getBones()[data.getBoneData().getIndex()]), _attachmentState(0) { diff --git a/spine-cpp/spine-cpp/src/spine/SlotData.cpp b/spine-cpp/spine-cpp/src/spine/SlotData.cpp index b08e59c65..509eda2ec 100644 --- a/spine-cpp/spine-cpp/src/spine/SlotData.cpp +++ b/spine-cpp/spine-cpp/src/spine/SlotData.cpp @@ -35,7 +35,7 @@ using namespace spine; -SlotData::SlotData(int index, const String &name, BoneData &boneData) : PosedData(name), +SlotData::SlotData(int index, const String &name, BoneData &boneData) : PosedDataGeneric(name), _index(index), _boneData(boneData), _attachmentName(),