Browse Source

[cpp] More physics porting, fix sanitizer issues

Mario Zechner 1 year ago
parent
commit
a190bc8899

+ 34 - 29
spine-cpp/spine-cpp/include/spine/PhysicsConstraint.h

@@ -43,96 +43,101 @@ namespace spine {
 
 
     class SP_API PhysicsConstraint : public Updatable {
     class SP_API PhysicsConstraint : public Updatable {
 
 
+        friend class Skeleton;
+
     RTTI_DECL
     RTTI_DECL
+
     public:
     public:
-        explicit PhysicsConstraint(PhysicsConstraintData& data, Skeleton& skeleton);
+        PhysicsConstraint(PhysicsConstraintData& data, Skeleton& skeleton);
+
+        PhysicsConstraintData &getData();
 
 
         void setBone(Bone* bone);
         void setBone(Bone* bone);
-        Bone* getBone() const;
+        Bone* getBone();
 
 
         void setInertia(float value);
         void setInertia(float value);
-        float getInertia() const;
+        float getInertia();
 
 
         void setStrength(float value);
         void setStrength(float value);
-        float getStrength() const;
+        float getStrength();
 
 
         void setDamping(float value);
         void setDamping(float value);
-        float getDamping() const;
+        float getDamping();
 
 
         void setMassInverse(float value);
         void setMassInverse(float value);
-        float getMassInverse() const;
+        float getMassInverse();
 
 
         void setWind(float value);
         void setWind(float value);
-        float getWind() const;
+        float getWind();
 
 
         void setGravity(float value);
         void setGravity(float value);
-        float getGravity() const;
+        float getGravity();
 
 
         void setMix(float value);
         void setMix(float value);
-        float getMix() const;
+        float getMix();
 
 
         void setReset(bool value);
         void setReset(bool value);
-        bool getReset() const;
+        bool getReset();
 
 
         void setUx(float value);
         void setUx(float value);
-        float getUx() const;
+        float getUx();
 
 
         void setUy(float value);
         void setUy(float value);
-        float getUy() const;
+        float getUy();
 
 
         void setCx(float value);
         void setCx(float value);
-        float getCx() const;
+        float getCx();
 
 
         void setCy(float value);
         void setCy(float value);
-        float getCy() const;
+        float getCy();
 
 
         void setTx(float value);
         void setTx(float value);
-        float getTx() const;
+        float getTx();
 
 
         void setTy(float value);
         void setTy(float value);
-        float getTy() const;
+        float getTy();
 
 
         void setXOffset(float value);
         void setXOffset(float value);
-        float getXOffset() const;
+        float getXOffset();
 
 
         void setXVelocity(float value);
         void setXVelocity(float value);
-        float getXVelocity() const;
+        float getXVelocity();
 
 
         void setYOffset(float value);
         void setYOffset(float value);
-        float getYOffset() const;
+        float getYOffset();
 
 
         void setYVelocity(float value);
         void setYVelocity(float value);
-        float getYVelocity() const;
+        float getYVelocity();
 
 
         void setRotateOffset(float value);
         void setRotateOffset(float value);
-        float getRotateOffset() const;
+        float getRotateOffset();
 
 
         void setRotateVelocity(float value);
         void setRotateVelocity(float value);
-        float getRotateVelocity() const;
+        float getRotateVelocity();
 
 
         void setScaleOffset(float value);
         void setScaleOffset(float value);
-        float getScaleOffset() const;
+        float getScaleOffset();
 
 
         void setScaleVelocity(float value);
         void setScaleVelocity(float value);
-        float getScaleVelocity() const;
+        float getScaleVelocity();
 
 
         void setActive(bool value);
         void setActive(bool value);
-        bool isActive() const;
+        bool isActive();
 
 
         void setRemaining(float value);
         void setRemaining(float value);
-        float getRemaining() const;
+        float getRemaining();
 
 
         void setLastTime(float value);
         void setLastTime(float value);
-        float getLastTime() const;
+        float getLastTime();
 
 
         void reset();
         void reset();
 
 
         void setToSetupPose();
         void setToSetupPose();
 
 
-        void update(Physics physics) override;
+        virtual void update(Physics physics);
 
 
     private:
     private:
-        const PhysicsConstraintData& _data;
+        PhysicsConstraintData& _data;
         Bone* _bone;
         Bone* _bone;
 
 
         float _inertia;
         float _inertia;

+ 14 - 4
spine-cpp/spine-cpp/include/spine/Skeleton.h

@@ -35,6 +35,7 @@
 #include <spine/SpineObject.h>
 #include <spine/SpineObject.h>
 #include <spine/SpineString.h>
 #include <spine/SpineString.h>
 #include <spine/Color.h>
 #include <spine/Color.h>
+#include <spine/Physics.h>
 
 
 namespace spine {
 namespace spine {
 	class SkeletonData;
 	class SkeletonData;
@@ -125,10 +126,13 @@ namespace spine {
 
 
 		void printUpdateCache();
 		void printUpdateCache();
 
 
-		/// Updates the world transform for each bone and applies constraints.
-		void updateWorldTransform();
+        /// Updates the world transform for each bone and applies all constraints.
+        ///
+        /// See [World transforms](http://esotericsoftware.com/spine-runtime-skeletons#World-transforms) in the Spine
+        /// Runtimes Guide.
+		void updateWorldTransform(Physics physics);
 
 
-		void updateWorldTransform(Bone *parent);
+		void updateWorldTransform(Physics physics, Bone *parent);
 
 
 		/// Sets the bones, constraints, and slots to their setup pose values.
 		/// Sets the bones, constraints, and slots to their setup pose values.
 		void setToSetupPose();
 		void setToSetupPose();
@@ -174,6 +178,9 @@ namespace spine {
 		/// @return May be NULL.
 		/// @return May be NULL.
 		PathConstraint *findPathConstraint(const String &constraintName);
 		PathConstraint *findPathConstraint(const String &constraintName);
 
 
+        /// @return May be NULL.
+        PhysicsConstraint *findPhysicsConstraint(const String &constraintName);
+
 		/// Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the current pose.
 		/// Returns the axis aligned bounding box (AABB) of the region and mesh attachments for the current pose.
 		/// @param outX The horizontal distance between the skeleton origin and the left side of the AABB.
 		/// @param outX The horizontal distance between the skeleton origin and the left side of the AABB.
 		/// @param outY The vertical distance between the skeleton origin and the bottom side of the AABB.
 		/// @param outY The vertical distance between the skeleton origin and the bottom side of the AABB.
@@ -200,6 +207,8 @@ namespace spine {
 
 
 		Vector<TransformConstraint *> &getTransformConstraints();
 		Vector<TransformConstraint *> &getTransformConstraints();
 
 
+        Vector<PhysicsConstraint *> &getPhysicsConstraints();
+
 		Skin *getSkin();
 		Skin *getSkin();
 
 
 		Color &getColor();
 		Color &getColor();
@@ -224,7 +233,7 @@ namespace spine {
 
 
         float getTime();
         float getTime();
 
 
-        float setTime(float time);
+        void setTime(float time);
 
 
         void update(float delta);
         void update(float delta);
 
 
@@ -236,6 +245,7 @@ namespace spine {
 		Vector<IkConstraint *> _ikConstraints;
 		Vector<IkConstraint *> _ikConstraints;
 		Vector<TransformConstraint *> _transformConstraints;
 		Vector<TransformConstraint *> _transformConstraints;
 		Vector<PathConstraint *> _pathConstraints;
 		Vector<PathConstraint *> _pathConstraints;
+        Vector<PhysicsConstraint *> _physicsConstraints;
 		Vector<Updatable *> _updateCache;
 		Vector<Updatable *> _updateCache;
 		Skin *_skin;
 		Skin *_skin;
 		Color _color;
 		Color _color;

+ 8 - 0
spine-cpp/spine-cpp/include/spine/SkeletonData.h

@@ -50,6 +50,8 @@ namespace spine {
 
 
 	class PathConstraintData;
 	class PathConstraintData;
 
 
+    class PhysicsConstraintData;
+
 /// Stores the setup pose and all of the stateless data for a skeleton.
 /// Stores the setup pose and all of the stateless data for a skeleton.
 	class SP_API SkeletonData : public SpineObject {
 	class SP_API SkeletonData : public SpineObject {
 		friend class SkeletonBinary;
 		friend class SkeletonBinary;
@@ -89,6 +91,9 @@ namespace spine {
 		/// @return May be NULL.
 		/// @return May be NULL.
 		PathConstraintData *findPathConstraint(const String &constraintName);
 		PathConstraintData *findPathConstraint(const String &constraintName);
 
 
+        /// @return May be NULL.
+        PhysicsConstraintData *findPhysicsConstraint(const String &constraintName);
+
 		const String &getName();
 		const String &getName();
 
 
 		void setName(const String &inValue);
 		void setName(const String &inValue);
@@ -118,6 +123,8 @@ namespace spine {
 
 
 		Vector<PathConstraintData *> &getPathConstraints();
 		Vector<PathConstraintData *> &getPathConstraints();
 
 
+        Vector<PhysicsConstraintData *> &getPhysicsConstraints();
+
 		float getX();
 		float getX();
 
 
 		void setX(float inValue);
 		void setX(float inValue);
@@ -167,6 +174,7 @@ namespace spine {
 		Vector<IkConstraintData *> _ikConstraints;
 		Vector<IkConstraintData *> _ikConstraints;
 		Vector<TransformConstraintData *> _transformConstraints;
 		Vector<TransformConstraintData *> _transformConstraints;
 		Vector<PathConstraintData *> _pathConstraints;
 		Vector<PathConstraintData *> _pathConstraints;
+        Vector<PhysicsConstraintData *> _physicsConstraints;
 		float _x, _y, _width, _height;
 		float _x, _y, _width, _height;
 		String _version;
 		String _version;
 		String _hash;
 		String _hash;

+ 4 - 4
spine-cpp/spine-cpp/include/spine/Version.h

@@ -27,11 +27,11 @@
  * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  * SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  *****************************************************************************/
  *****************************************************************************/
 
 
-#ifndef SPINE_VERTEXEFFECT_H_
-#define SPINE_VERTEXEFFECT_H_
+#ifndef SPINE_VERSION_H_
+#define SPINE_VERSION_H_
 
 
 #define SPINE_MAJOR_VERSION 4
 #define SPINE_MAJOR_VERSION 4
-#define SPINE_MINOR_VERSION 1
-#define SPINE_VERSION_STRING "4.1"
+#define SPINE_MINOR_VERSION 2
+#define SPINE_VERSION_STRING "4.2"
 
 
 #endif
 #endif

+ 2 - 0
spine-cpp/spine-cpp/include/spine/spine.h

@@ -72,6 +72,8 @@
 #include <spine/PathConstraintMixTimeline.h>
 #include <spine/PathConstraintMixTimeline.h>
 #include <spine/PathConstraintPositionTimeline.h>
 #include <spine/PathConstraintPositionTimeline.h>
 #include <spine/PathConstraintSpacingTimeline.h>
 #include <spine/PathConstraintSpacingTimeline.h>
+#include <spine/PhysicsConstraintData.h>
+#include <spine/PhysicsConstraint.h>
 #include <spine/PointAttachment.h>
 #include <spine/PointAttachment.h>
 #include <spine/Pool.h>
 #include <spine/Pool.h>
 #include <spine/PositionMode.h>
 #include <spine/PositionMode.h>

+ 10 - 4
spine-cpp/spine-cpp/src/spine/Bone.cpp

@@ -75,7 +75,7 @@ Bone::Bone(BoneData &data, Skeleton &skeleton, Bone *parent) : Updatable(),
 	setToSetupPose();
 	setToSetupPose();
 }
 }
 
 
-void Bone::update(Physics physics) {
+void Bone::update(Physics) {
 	updateWorldTransform(_ax, _ay, _arotation, _ascaleX, _ascaleY, _ashearX, _ashearY);
 	updateWorldTransform(_ax, _ay, _arotation, _ascaleX, _ascaleY, _ashearX, _ashearY);
 }
 }
 
 
@@ -96,7 +96,7 @@ void Bone::updateWorldTransform(float x, float y, float rotation, float scaleX,
 	_ashearY = shearY;
 	_ashearY = shearY;
 
 
 	if (!parent) { /* Root bone. */
 	if (!parent) { /* Root bone. */
-        auto skeleton = this->_skeleton;
+        Skeleton &skeleton = this->_skeleton;
         float sx = skeleton.getScaleX();
         float sx = skeleton.getScaleX();
         float sy = skeleton.getScaleY();
         float sy = skeleton.getScaleY();
         float rx = (rotation + shearX) * MathUtil::Deg_Rad;
         float rx = (rotation + shearX) * MathUtil::Deg_Rad;
@@ -522,7 +522,7 @@ void Bone::updateAppliedTransform() {
                 break;
                 break;
             }
             }
             case TransformMode_NoScale:
             case TransformMode_NoScale:
-            case TransformMode_NoScaleOrReflection:
+            case TransformMode_NoScaleOrReflection: {
                 float cos = MathUtil::cosDeg(_rotation), sin = MathUtil::sinDeg(_rotation);
                 float cos = MathUtil::cosDeg(_rotation), sin = MathUtil::sinDeg(_rotation);
                 pa = (pa * cos + pb * sin) / _skeleton.getScaleX();
                 pa = (pa * cos + pb * sin) / _skeleton.getScaleX();
                 pc = (pc * cos + pd * sin) / _skeleton.getScaleY();
                 pc = (pc * cos + pd * sin) / _skeleton.getScaleY();
@@ -531,7 +531,9 @@ void Bone::updateAppliedTransform() {
                 pa *= s;
                 pa *= s;
                 pc *= s;
                 pc *= s;
                 s = MathUtil::sqrt(pa * pa + pc * pc);
                 s = MathUtil::sqrt(pa * pa + pc * pc);
-                if (_data.getTransformMode() == TransformMode_NoScale && pid < 0 != (_skeleton.getScaleX() < 0 != _skeleton.getScaleY() < 0)) s = -s;
+                if (_data.getTransformMode() == TransformMode_NoScale &&
+                    pid < 0 != (_skeleton.getScaleX() < 0 != _skeleton.getScaleY() < 0))
+                    s = -s;
                 float r = MathUtil::Pi / 2 + MathUtil::atan2(pc, pa);
                 float r = MathUtil::Pi / 2 + MathUtil::atan2(pc, pa);
                 pb = MathUtil::cos(r) * s;
                 pb = MathUtil::cos(r) * s;
                 pd = MathUtil::sin(r) * s;
                 pd = MathUtil::sin(r) * s;
@@ -541,6 +543,10 @@ void Bone::updateAppliedTransform() {
                 ic = pc * pid;
                 ic = pc * pid;
                 id = pa * pid;
                 id = pa * pid;
                 break;
                 break;
+            }
+            case TransformMode_Normal:
+            case TransformMode_OnlyTranslation:
+                break;
         }
         }
         ra = ia * _a - ib * _c;
         ra = ia * _a - ib * _c;
         rb = ia * _b - ib * _d;
         rb = ia * _b - ib * _d;

+ 2 - 2
spine-cpp/spine-cpp/src/spine/IkConstraint.cpp

@@ -283,7 +283,7 @@ IkConstraint::IkConstraint(IkConstraintData &data, Skeleton &skeleton) : Updatab
 	}
 	}
 }
 }
 
 
-void IkConstraint::update(Physics physics) {
+void IkConstraint::update(Physics) {
 	if (_mix == 0) return;
 	if (_mix == 0) return;
 	switch (_bones.size()) {
 	switch (_bones.size()) {
 		case 1: {
 		case 1: {
@@ -369,7 +369,7 @@ void IkConstraint::setSoftness(float inValue) {
 }
 }
 
 
 void IkConstraint::setToSetupPose() {
 void IkConstraint::setToSetupPose() {
-    auto data = this->_data;
+    IkConstraintData &data = this->_data;
     this->_mix = data._mix;
     this->_mix = data._mix;
     this->_softness = data._softness;
     this->_softness = data._softness;
     this->_bendDirection = data._bendDirection;
     this->_bendDirection = data._bendDirection;

+ 0 - 2
spine-cpp/spine-cpp/src/spine/Json.cpp

@@ -372,7 +372,6 @@ const char *Json::parseNumber(Json *item, const char *num) {
 	if (*ptr == 'e' || *ptr == 'E') {
 	if (*ptr == 'e' || *ptr == 'E') {
 		double exponent = 0;
 		double exponent = 0;
 		int expNegative = 0;
 		int expNegative = 0;
-		int n = 0;
 		++ptr;
 		++ptr;
 
 
 		if (*ptr == '-') {
 		if (*ptr == '-') {
@@ -385,7 +384,6 @@ const char *Json::parseNumber(Json *item, const char *num) {
 		while (*ptr >= '0' && *ptr <= '9') {
 		while (*ptr >= '0' && *ptr <= '9') {
 			exponent = (exponent * 10.0) + (*ptr - '0');
 			exponent = (exponent * 10.0) + (*ptr - '0');
 			++ptr;
 			++ptr;
-			++n;
 		}
 		}
 
 
 		if (expNegative) {
 		if (expNegative) {

+ 2 - 2
spine-cpp/spine-cpp/src/spine/PathConstraint.cpp

@@ -66,7 +66,7 @@ PathConstraint::PathConstraint(PathConstraintData &data, Skeleton &skeleton) : U
 	_segments.setSize(10, 0);
 	_segments.setSize(10, 0);
 }
 }
 
 
-void PathConstraint::update(Physics physics) {
+void PathConstraint::update(Physics) {
 	Attachment *baseAttachment = _target->getAttachment();
 	Attachment *baseAttachment = _target->getAttachment();
 	if (baseAttachment == NULL || !baseAttachment->getRTTI().instanceOf(PathAttachment::rtti)) {
 	if (baseAttachment == NULL || !baseAttachment->getRTTI().instanceOf(PathAttachment::rtti)) {
 		return;
 		return;
@@ -580,7 +580,7 @@ void PathConstraint::setActive(bool inValue) {
 }
 }
 
 
 void PathConstraint::setToSetupPose() {
 void PathConstraint::setToSetupPose() {
-    auto data = this->_data;
+    PathConstraintData &data = this->_data;
     this->_position = data._position;
     this->_position = data._position;
     this->_spacing = data._spacing;
     this->_spacing = data._spacing;
     this->_mixRotate = data._mixRotate;
     this->_mixRotate = data._mixRotate;

+ 34 - 32
spine-cpp/spine-cpp/src/spine/PhysicsConstraint.cpp

@@ -40,9 +40,7 @@ RTTI_IMPL(PhysicsConstraint, Updatable)
 
 
 PhysicsConstraint::PhysicsConstraint(PhysicsConstraintData& data, Skeleton& skeleton)
 PhysicsConstraint::PhysicsConstraint(PhysicsConstraintData& data, Skeleton& skeleton)
         : _data(data), _skeleton(skeleton) {
         : _data(data), _skeleton(skeleton) {
-    // Assuming 'bones' is a vector or similar container in 'Skeleton'
-    // and 'index' is an accessible member of 'BoneData' in 'PhysicsConstraintData'
-    _bone = skeleton.getBones()[data.getBone()->getIndex()];  // Adjust based on actual data structure
+    _bone = skeleton.getBones()[data.getBone()->getIndex()];
 
 
     _inertia = data.getInertia();
     _inertia = data.getInertia();
     _strength = data.getStrength();
     _strength = data.getStrength();
@@ -72,11 +70,15 @@ PhysicsConstraint::PhysicsConstraint(PhysicsConstraintData& data, Skeleton& skel
     _lastTime = 0;
     _lastTime = 0;
 }
 }
 
 
+PhysicsConstraintData &PhysicsConstraint::getData() {
+    return _data;
+}
+
 void PhysicsConstraint::setBone(Bone* bone) {
 void PhysicsConstraint::setBone(Bone* bone) {
     _bone = bone;
     _bone = bone;
 }
 }
 
 
-Bone* PhysicsConstraint::getBone() const {
+Bone* PhysicsConstraint::getBone(){
     return _bone;
     return _bone;
 }
 }
 
 
@@ -84,7 +86,7 @@ void PhysicsConstraint::setInertia(float value) {
     _inertia = value;
     _inertia = value;
 }
 }
 
 
-float PhysicsConstraint::getInertia() const {
+float PhysicsConstraint::getInertia(){
     return _inertia;
     return _inertia;
 }
 }
 
 
@@ -92,7 +94,7 @@ void PhysicsConstraint::setStrength(float value) {
     _strength = value;
     _strength = value;
 }
 }
 
 
-float PhysicsConstraint::getStrength() const {
+float PhysicsConstraint::getStrength(){
     return _strength;
     return _strength;
 }
 }
 
 
@@ -100,7 +102,7 @@ void PhysicsConstraint::setDamping(float value) {
     _damping = value;
     _damping = value;
 }
 }
 
 
-float PhysicsConstraint::getDamping() const {
+float PhysicsConstraint::getDamping(){
     return _damping;
     return _damping;
 }
 }
 
 
@@ -108,7 +110,7 @@ void PhysicsConstraint::setMassInverse(float value) {
     _massInverse = value;
     _massInverse = value;
 }
 }
 
 
-float PhysicsConstraint::getMassInverse() const {
+float PhysicsConstraint::getMassInverse(){
     return _massInverse;
     return _massInverse;
 }
 }
 
 
@@ -116,7 +118,7 @@ void PhysicsConstraint::setWind(float value) {
     _wind = value;
     _wind = value;
 }
 }
 
 
-float PhysicsConstraint::getWind() const {
+float PhysicsConstraint::getWind(){
     return _wind;
     return _wind;
 }
 }
 
 
@@ -124,7 +126,7 @@ void PhysicsConstraint::setGravity(float value) {
     _gravity = value;
     _gravity = value;
 }
 }
 
 
-float PhysicsConstraint::getGravity() const {
+float PhysicsConstraint::getGravity(){
     return _gravity;
     return _gravity;
 }
 }
 
 
@@ -132,7 +134,7 @@ void PhysicsConstraint::setMix(float value) {
     _mix = value;
     _mix = value;
 }
 }
 
 
-float PhysicsConstraint::getMix() const {
+float PhysicsConstraint::getMix(){
     return _mix;
     return _mix;
 }
 }
 
 
@@ -140,7 +142,7 @@ void PhysicsConstraint::setReset(bool value) {
     _reset = value;
     _reset = value;
 }
 }
 
 
-bool PhysicsConstraint::getReset() const {
+bool PhysicsConstraint::getReset(){
     return _reset;
     return _reset;
 }
 }
 
 
@@ -148,7 +150,7 @@ void PhysicsConstraint::setUx(float value) {
     _ux = value;
     _ux = value;
 }
 }
 
 
-float PhysicsConstraint::getUx() const {
+float PhysicsConstraint::getUx(){
     return _ux;
     return _ux;
 }
 }
 
 
@@ -156,7 +158,7 @@ void PhysicsConstraint::setUy(float value) {
     _uy = value;
     _uy = value;
 }
 }
 
 
-float PhysicsConstraint::getUy() const {
+float PhysicsConstraint::getUy(){
     return _uy;
     return _uy;
 }
 }
 
 
@@ -164,7 +166,7 @@ void PhysicsConstraint::setCx(float value) {
     _cx = value;
     _cx = value;
 }
 }
 
 
-float PhysicsConstraint::getCx() const {
+float PhysicsConstraint::getCx(){
     return _cx;
     return _cx;
 }
 }
 
 
@@ -172,7 +174,7 @@ void PhysicsConstraint::setCy(float value) {
     _cy = value;
     _cy = value;
 }
 }
 
 
-float PhysicsConstraint::getCy() const {
+float PhysicsConstraint::getCy(){
     return _cy;
     return _cy;
 }
 }
 
 
@@ -180,7 +182,7 @@ void PhysicsConstraint::setTx(float value) {
     _tx = value;
     _tx = value;
 }
 }
 
 
-float PhysicsConstraint::getTx() const {
+float PhysicsConstraint::getTx(){
     return _tx;
     return _tx;
 }
 }
 
 
@@ -188,7 +190,7 @@ void PhysicsConstraint::setTy(float value) {
     _ty = value;
     _ty = value;
 }
 }
 
 
-float PhysicsConstraint::getTy() const {
+float PhysicsConstraint::getTy(){
     return _ty;
     return _ty;
 }
 }
 
 
@@ -196,7 +198,7 @@ void PhysicsConstraint::setXOffset(float value) {
     _xOffset = value;
     _xOffset = value;
 }
 }
 
 
-float PhysicsConstraint::getXOffset() const {
+float PhysicsConstraint::getXOffset(){
     return _xOffset;
     return _xOffset;
 }
 }
 
 
@@ -204,7 +206,7 @@ void PhysicsConstraint::setXVelocity(float value) {
     _xVelocity = value;
     _xVelocity = value;
 }
 }
 
 
-float PhysicsConstraint::getXVelocity() const {
+float PhysicsConstraint::getXVelocity(){
     return _xVelocity;
     return _xVelocity;
 }
 }
 
 
@@ -212,7 +214,7 @@ void PhysicsConstraint::setYOffset(float value) {
     _yOffset = value;
     _yOffset = value;
 }
 }
 
 
-float PhysicsConstraint::getYOffset() const {
+float PhysicsConstraint::getYOffset(){
     return _yOffset;
     return _yOffset;
 }
 }
 
 
@@ -220,7 +222,7 @@ void PhysicsConstraint::setYVelocity(float value) {
     _yVelocity = value;
     _yVelocity = value;
 }
 }
 
 
-float PhysicsConstraint::getYVelocity() const {
+float PhysicsConstraint::getYVelocity(){
     return _yVelocity;
     return _yVelocity;
 }
 }
 
 
@@ -228,7 +230,7 @@ void PhysicsConstraint::setRotateOffset(float value) {
     _rotateOffset = value;
     _rotateOffset = value;
 }
 }
 
 
-float PhysicsConstraint::getRotateOffset() const {
+float PhysicsConstraint::getRotateOffset(){
     return _rotateOffset;
     return _rotateOffset;
 }
 }
 
 
@@ -236,7 +238,7 @@ void PhysicsConstraint::setRotateVelocity(float value) {
     _rotateVelocity = value;
     _rotateVelocity = value;
 }
 }
 
 
-float PhysicsConstraint::getRotateVelocity() const {
+float PhysicsConstraint::getRotateVelocity(){
     return _rotateVelocity;
     return _rotateVelocity;
 }
 }
 
 
@@ -244,7 +246,7 @@ void PhysicsConstraint::setScaleOffset(float value) {
     _scaleOffset = value;
     _scaleOffset = value;
 }
 }
 
 
-float PhysicsConstraint::getScaleOffset() const {
+float PhysicsConstraint::getScaleOffset(){
     return _scaleOffset;
     return _scaleOffset;
 }
 }
 
 
@@ -252,7 +254,7 @@ void PhysicsConstraint::setScaleVelocity(float value) {
     _scaleVelocity = value;
     _scaleVelocity = value;
 }
 }
 
 
-float PhysicsConstraint::getScaleVelocity() const {
+float PhysicsConstraint::getScaleVelocity(){
     return _scaleVelocity;
     return _scaleVelocity;
 }
 }
 
 
@@ -260,7 +262,7 @@ void PhysicsConstraint::setActive(bool value) {
     _active = value;
     _active = value;
 }
 }
 
 
-bool PhysicsConstraint::isActive() const {
+bool PhysicsConstraint::isActive(){
     return _active;
     return _active;
 }
 }
 
 
@@ -268,7 +270,7 @@ void PhysicsConstraint::setRemaining(float value) {
     _remaining = value;
     _remaining = value;
 }
 }
 
 
-float PhysicsConstraint::getRemaining() const {
+float PhysicsConstraint::getRemaining(){
     return _remaining;
     return _remaining;
 }
 }
 
 
@@ -276,13 +278,13 @@ void PhysicsConstraint::setLastTime(float value) {
     _lastTime = value;
     _lastTime = value;
 }
 }
 
 
-float PhysicsConstraint::getLastTime() const {
+float PhysicsConstraint::getLastTime(){
     return _lastTime;
     return _lastTime;
 }
 }
 
 
 void PhysicsConstraint::reset() {
 void PhysicsConstraint::reset() {
     _remaining = 0;
     _remaining = 0;
-    _lastTime = _skeleton.getTime();  // Assuming Skeleton has a method getTime()
+    _lastTime = _skeleton.getTime();
     _reset = true;
     _reset = true;
     _xOffset = 0;
     _xOffset = 0;
     _xVelocity = 0;
     _xVelocity = 0;
@@ -313,7 +315,7 @@ void PhysicsConstraint::update(Physics physics) {
     bool scaleX = _data._scaleX > 0;
     bool scaleX = _data._scaleX > 0;
 
 
     Bone* bone = _bone;
     Bone* bone = _bone;
-    float l = bone->_data.getLength();  // Direct access to Bone's length
+    float l = bone->_data.getLength();
 
 
     switch (physics) {
     switch (physics) {
         case Physics::none:
         case Physics::none:
@@ -461,4 +463,4 @@ void PhysicsConstraint::update(Physics physics) {
         _ty = l * bone->_c;
         _ty = l * bone->_c;
     }
     }
     bone->updateAppliedTransform();
     bone->updateAppliedTransform();
-}
+}

+ 63 - 47
spine-cpp/spine-cpp/src/spine/Skeleton.cpp

@@ -33,6 +33,7 @@
 #include <spine/Bone.h>
 #include <spine/Bone.h>
 #include <spine/IkConstraint.h>
 #include <spine/IkConstraint.h>
 #include <spine/PathConstraint.h>
 #include <spine/PathConstraint.h>
+#include <spine/PhysicsConstraint.h>
 #include <spine/SkeletonData.h>
 #include <spine/SkeletonData.h>
 #include <spine/Skin.h>
 #include <spine/Skin.h>
 #include <spine/Slot.h>
 #include <spine/Slot.h>
@@ -43,6 +44,7 @@
 #include <spine/MeshAttachment.h>
 #include <spine/MeshAttachment.h>
 #include <spine/PathAttachment.h>
 #include <spine/PathAttachment.h>
 #include <spine/PathConstraintData.h>
 #include <spine/PathConstraintData.h>
+#include <spine/PhysicsConstraintData.h>
 #include <spine/RegionAttachment.h>
 #include <spine/RegionAttachment.h>
 #include <spine/SlotData.h>
 #include <spine/SlotData.h>
 #include <spine/TransformConstraintData.h>
 #include <spine/TransformConstraintData.h>
@@ -116,6 +118,15 @@ Skeleton::Skeleton(SkeletonData *skeletonData) : _data(skeletonData),
 		_pathConstraints.add(constraint);
 		_pathConstraints.add(constraint);
 	}
 	}
 
 
+    _physicsConstraints.ensureCapacity(_data->getPhysicsConstraints().size());
+    for (size_t i = 0; i < _data->getPhysicsConstraints().size(); ++i) {
+        PhysicsConstraintData *data = _data->getPhysicsConstraints()[i];
+
+        PhysicsConstraint *constraint = new (__FILE__, __LINE__) PhysicsConstraint(*data, *this);
+
+        _physicsConstraints.add(constraint);
+    }
+
 	updateCache();
 	updateCache();
 }
 }
 
 
@@ -151,8 +162,9 @@ void Skeleton::updateCache() {
 	size_t ikCount = _ikConstraints.size();
 	size_t ikCount = _ikConstraints.size();
 	size_t transformCount = _transformConstraints.size();
 	size_t transformCount = _transformConstraints.size();
 	size_t pathCount = _pathConstraints.size();
 	size_t pathCount = _pathConstraints.size();
+    size_t physicsCount = _physicsConstraints.size();
 
 
-	size_t constraintCount = ikCount + transformCount + pathCount;
+	size_t constraintCount = ikCount + transformCount + pathCount + physicsCount;
 
 
 	size_t i = 0;
 	size_t i = 0;
 continue_outer:
 continue_outer:
@@ -183,6 +195,15 @@ continue_outer:
 				goto continue_outer;
 				goto continue_outer;
 			}
 			}
 		}
 		}
+
+        for (size_t ii = 0; ii < pathCount; ++ii) {
+            PhysicsConstraint *constraint = _physicsConstraints[ii];
+            if (constraint->getData().getOrder() == i) {
+                sortPhysicsConstraint(constraint);
+                i++;
+                goto continue_outer;
+            }
+        }
 	}
 	}
 
 
 	size_t n = _bones.size();
 	size_t n = _bones.size();
@@ -206,7 +227,7 @@ void Skeleton::printUpdateCache() {
 	}
 	}
 }
 }
 
 
-void Skeleton::updateWorldTransform() {
+void Skeleton::updateWorldTransform(Physics physics) {
 	for (size_t i = 0, n = _bones.size(); i < n; i++) {
 	for (size_t i = 0, n = _bones.size(); i < n; i++) {
 		Bone *bone = _bones[i];
 		Bone *bone = _bones[i];
 		bone->_ax = bone->_x;
 		bone->_ax = bone->_x;
@@ -219,32 +240,34 @@ void Skeleton::updateWorldTransform() {
 	}
 	}
 
 
 	for (size_t i = 0, n = _updateCache.size(); i < n; ++i) {
 	for (size_t i = 0, n = _updateCache.size(); i < n; ++i) {
-		_updateCache[i]->update();
+		Updatable *updatable = _updateCache[i];
+        updatable->update(physics);
 	}
 	}
 }
 }
 
 
-void Skeleton::updateWorldTransform(Bone *parent) {
+void Skeleton::updateWorldTransform(Physics physics, Bone *parent) {
 	// Apply the parent bone transform to the root bone. The root bone always inherits scale, rotation and reflection.
 	// Apply the parent bone transform to the root bone. The root bone always inherits scale, rotation and reflection.
-	Bone &rootBone = *getRootBone();
+	Bone *rootBone = getRootBone();
 	float pa = parent->_a, pb = parent->_b, pc = parent->_c, pd = parent->_d;
 	float pa = parent->_a, pb = parent->_b, pc = parent->_c, pd = parent->_d;
-	rootBone._worldX = pa * _x + pb * _y + parent->_worldX;
-	rootBone._worldY = pc * _x + pd * _y + parent->_worldY;
-
-	float rotationY = rootBone._rotation + 90 + rootBone._shearY;
-	float la = MathUtil::cosDeg(rootBone._rotation + rootBone._shearX) * rootBone._scaleX;
-	float lb = MathUtil::cosDeg(rotationY) * rootBone._scaleY;
-	float lc = MathUtil::sinDeg(rootBone._rotation + rootBone._shearX) * rootBone._scaleX;
-	float ld = MathUtil::sinDeg(rotationY) * rootBone._scaleY;
-	rootBone._a = (pa * la + pb * lc) * _scaleX;
-	rootBone._b = (pa * lb + pb * ld) * _scaleX;
-	rootBone._c = (pc * la + pd * lc) * _scaleY;
-	rootBone._d = (pc * lb + pd * ld) * _scaleY;
+	rootBone->_worldX = pa * _x + pb * _y + parent->_worldX;
+	rootBone->_worldY = pc * _x + pd * _y + parent->_worldY;
+
+    float rx = (rootBone->_rotation + rootBone->_shearX) * MathUtil::Deg_Rad;
+    float ry = (rootBone->_rotation + 90 + rootBone->_shearY) * MathUtil::Deg_Rad;
+    float la = MathUtil::cos(rx) * rootBone->_scaleX;
+    float lb = MathUtil::cos(ry) * rootBone->_scaleY;
+    float lc = MathUtil::sin(rx) * rootBone->_scaleX;
+    float ld = MathUtil::sin(ry) * rootBone->_scaleY;
+	rootBone->_a = (pa * la + pb * lc) * _scaleX;
+	rootBone->_b = (pa * lb + pb * ld) * _scaleX;
+	rootBone->_c = (pc * la + pd * lc) * _scaleY;
+	rootBone->_d = (pc * lb + pd * ld) * _scaleY;
 
 
 	// Update everything except root bone.
 	// Update everything except root bone.
 	Bone *rb = getRootBone();
 	Bone *rb = getRootBone();
 	for (size_t i = 0, n = _updateCache.size(); i < n; i++) {
 	for (size_t i = 0, n = _updateCache.size(); i < n; i++) {
 		Updatable *updatable = _updateCache[i];
 		Updatable *updatable = _updateCache[i];
-		if (updatable != rb) updatable->update();
+		if (updatable != rb) updatable->update(physics);
 	}
 	}
 }
 }
 
 
@@ -259,40 +282,20 @@ void Skeleton::setBonesToSetupPose() {
 	}
 	}
 
 
 	for (size_t i = 0, n = _ikConstraints.size(); i < n; ++i) {
 	for (size_t i = 0, n = _ikConstraints.size(); i < n; ++i) {
-		IkConstraint *constraintP = _ikConstraints[i];
-		IkConstraint &constraint = *constraintP;
-
-		constraint._bendDirection = constraint._data._bendDirection;
-		constraint._compress = constraint._data._compress;
-		constraint._stretch = constraint._data._stretch;
-		constraint._mix = constraint._data._mix;
-		constraint._softness = constraint._data._softness;
+		_ikConstraints[i]->setToSetupPose();
 	}
 	}
 
 
 	for (size_t i = 0, n = _transformConstraints.size(); i < n; ++i) {
 	for (size_t i = 0, n = _transformConstraints.size(); i < n; ++i) {
-		TransformConstraint *constraintP = _transformConstraints[i];
-		TransformConstraint &constraint = *constraintP;
-		TransformConstraintData &constraintData = constraint._data;
-
-		constraint._mixRotate = constraintData._mixRotate;
-		constraint._mixX = constraintData._mixX;
-		constraint._mixY = constraintData._mixY;
-		constraint._mixScaleX = constraintData._mixScaleX;
-		constraint._mixScaleY = constraintData._mixScaleY;
-		constraint._mixShearY = constraintData._mixShearY;
+		_transformConstraints[i]->setToSetupPose();
 	}
 	}
 
 
 	for (size_t i = 0, n = _pathConstraints.size(); i < n; ++i) {
 	for (size_t i = 0, n = _pathConstraints.size(); i < n; ++i) {
-		PathConstraint *constraintP = _pathConstraints[i];
-		PathConstraint &constraint = *constraintP;
-		PathConstraintData &constraintData = constraint._data;
-
-		constraint._position = constraintData._position;
-		constraint._spacing = constraintData._spacing;
-		constraint._mixRotate = constraintData._mixRotate;
-		constraint._mixX = constraintData._mixX;
-		constraint._mixY = constraintData._mixY;
+		_pathConstraints[i]->setToSetupPose();
 	}
 	}
+
+    for (size_t i = 0, n = _physicsConstraints.size(); i < n; ++i) {
+        _physicsConstraints[i]->setToSetupPose();
+    }
 }
 }
 
 
 void Skeleton::setSlotsToSetupPose() {
 void Skeleton::setSlotsToSetupPose() {
@@ -640,6 +643,18 @@ void Skeleton::sortTransformConstraint(TransformConstraint *constraint) {
 		constrained[i]->_sorted = true;
 		constrained[i]->_sorted = true;
 }
 }
 
 
+void Skeleton::sortPhysicsConstraint(PhysicsConstraint *constraint) {
+    Bone *bone = constraint->getBone();
+    constraint->_active = bone->_active && (!constraint->_data.isSkinRequired() ||
+                                                           (_skin && _skin->_constraints.contains(&constraint->_data)));
+    if (!constraint->_active) return;
+
+    sortBone(bone);
+    _updateCache.add(constraint);
+    sortReset(bone->getChildren());
+    bone->_sorted = true;
+}
+
 void Skeleton::sortPathConstraintAttachment(Skin *skin, size_t slotIndex, Bone &slotBone) {
 void Skeleton::sortPathConstraintAttachment(Skin *skin, size_t slotIndex, Bone &slotBone) {
 	Skin::AttachmentMap::Entries attachments = skin->getAttachments();
 	Skin::AttachmentMap::Entries attachments = skin->getAttachments();
 
 
@@ -689,10 +704,11 @@ float Skeleton::getTime() {
     return _time;
     return _time;
 }
 }
 
 
-float Skeleton::setTime(float time) {
+void Skeleton::setTime(float time) {
     _time = time;
     _time = time;
 }
 }
 
 
 void Skeleton::update(float delta) {
 void Skeleton::update(float delta) {
     _time += delta;
     _time += delta;
-}
+}
+

+ 10 - 0
spine-cpp/spine-cpp/src/spine/SkeletonData.cpp

@@ -34,6 +34,7 @@
 #include <spine/EventData.h>
 #include <spine/EventData.h>
 #include <spine/IkConstraintData.h>
 #include <spine/IkConstraintData.h>
 #include <spine/PathConstraintData.h>
 #include <spine/PathConstraintData.h>
+#include <spine/PhysicsConstraintData.h>
 #include <spine/Skin.h>
 #include <spine/Skin.h>
 #include <spine/SlotData.h>
 #include <spine/SlotData.h>
 #include <spine/TransformConstraintData.h>
 #include <spine/TransformConstraintData.h>
@@ -66,6 +67,7 @@ SkeletonData::~SkeletonData() {
 	ContainerUtil::cleanUpVectorOfPointers(_ikConstraints);
 	ContainerUtil::cleanUpVectorOfPointers(_ikConstraints);
 	ContainerUtil::cleanUpVectorOfPointers(_transformConstraints);
 	ContainerUtil::cleanUpVectorOfPointers(_transformConstraints);
 	ContainerUtil::cleanUpVectorOfPointers(_pathConstraints);
 	ContainerUtil::cleanUpVectorOfPointers(_pathConstraints);
+    ContainerUtil::cleanUpVectorOfPointers(_physicsConstraints);
 	for (size_t i = 0; i < _strings.size(); i++) {
 	for (size_t i = 0; i < _strings.size(); i++) {
 		SpineExtension::free(_strings[i], __FILE__, __LINE__);
 		SpineExtension::free(_strings[i], __FILE__, __LINE__);
 	}
 	}
@@ -103,6 +105,10 @@ PathConstraintData *SkeletonData::findPathConstraint(const String &constraintNam
 	return ContainerUtil::findWithName(_pathConstraints, constraintName);
 	return ContainerUtil::findWithName(_pathConstraints, constraintName);
 }
 }
 
 
+PhysicsConstraintData *SkeletonData::findPhysicsConstraint(const String &constraintName) {
+    return ContainerUtil::findWithName(_physicsConstraints, constraintName);
+}
+
 const String &SkeletonData::getName() {
 const String &SkeletonData::getName() {
 	return _name;
 	return _name;
 }
 }
@@ -151,6 +157,10 @@ Vector<PathConstraintData *> &SkeletonData::getPathConstraints() {
 	return _pathConstraints;
 	return _pathConstraints;
 }
 }
 
 
+Vector<PhysicsConstraintData *> &SkeletonData::getPhysicsConstraints() {
+    return _physicsConstraints;
+}
+
 float SkeletonData::getX() {
 float SkeletonData::getX() {
 	return _x;
 	return _x;
 }
 }

+ 2 - 2
spine-cpp/spine-cpp/src/spine/TransformConstraint.cpp

@@ -61,7 +61,7 @@ TransformConstraint::TransformConstraint(TransformConstraintData &data, Skeleton
 	}
 	}
 }
 }
 
 
-void TransformConstraint::update(Physics physics) {
+void TransformConstraint::update(Physics) {
 	if (_mixRotate == 0 && _mixX == 0 && _mixY == 0 && _mixScaleX == 0 && _mixScaleY == 0 && _mixShearY == 0) return;
 	if (_mixRotate == 0 && _mixX == 0 && _mixY == 0 && _mixScaleX == 0 && _mixScaleY == 0 && _mixShearY == 0) return;
 
 
 	if (_data.isLocal()) {
 	if (_data.isLocal()) {
@@ -340,7 +340,7 @@ void TransformConstraint::setActive(bool inValue) {
 }
 }
 
 
 void TransformConstraint::setToSetupPose() {
 void TransformConstraint::setToSetupPose() {
-	auto data = this->_data;
+	TransformConstraintData &data = this->_data;
 	this->_mixRotate = data._mixRotate;
 	this->_mixRotate = data._mixRotate;
 	this->_mixX = data._mixX;
 	this->_mixX = data._mixX;
 	this->_mixY = data._mixY;
 	this->_mixY = data._mixY;

+ 14 - 14
spine-sfml/cpp/example/main.cpp

@@ -39,7 +39,7 @@ using namespace spine;
 
 
 template<typename T, typename... Args>
 template<typename T, typename... Args>
 unique_ptr<T> make_unique_test(Args &&...args) {
 unique_ptr<T> make_unique_test(Args &&...args) {
-	return unique_ptr<T>(new T(forward<Args>(args)...));
+	return unique_ptr<T>(new T(std::forward<Args>(args)...));
 }
 }
 
 
 void callback(AnimationState *state, EventType type, TrackEntry *entry, Event *event) {
 void callback(AnimationState *state, EventType type, TrackEntry *entry, Event *event) {
@@ -124,7 +124,7 @@ void spineboy(SkeletonData *skeletonData, Atlas *atlas) {
 	skeleton->setToSetupPose();
 	skeleton->setToSetupPose();
 
 
 	skeleton->setPosition(320, 590);
 	skeleton->setPosition(320, 590);
-	skeleton->updateWorldTransform();
+	skeleton->updateWorldTransform(Physics::update);
 
 
 	Slot *headSlot = skeleton->findSlot("head");
 	Slot *headSlot = skeleton->findSlot("head");
 
 
@@ -227,7 +227,7 @@ void ikDemo(SkeletonData *skeletonData, Atlas *atlas) {
 		// Calculate final world transform with the
 		// Calculate final world transform with the
 		// crosshair bone set to the mouse cursor
 		// crosshair bone set to the mouse cursor
 		// position.
 		// position.
-		drawable.skeleton->updateWorldTransform();
+		drawable.skeleton->updateWorldTransform(Physics::update);
 
 
 		window.clear();
 		window.clear();
 		window.draw(drawable);
 		window.draw(drawable);
@@ -246,7 +246,7 @@ void goblins(SkeletonData *skeletonData, Atlas *atlas) {
 	skeleton->setSkin("goblingirl");
 	skeleton->setSkin("goblingirl");
 	skeleton->setSlotsToSetupPose();
 	skeleton->setSlotsToSetupPose();
 	skeleton->setPosition(320, 590);
 	skeleton->setPosition(320, 590);
-	skeleton->updateWorldTransform();
+	skeleton->updateWorldTransform(Physics::update);
 
 
 	drawable.state->setAnimation(0, "walk", true);
 	drawable.state->setAnimation(0, "walk", true);
 
 
@@ -281,7 +281,7 @@ void raptor(SkeletonData *skeletonData, Atlas *atlas) {
 
 
 	Skeleton *skeleton = drawable.skeleton;
 	Skeleton *skeleton = drawable.skeleton;
 	skeleton->setPosition(320, 590);
 	skeleton->setPosition(320, 590);
-	skeleton->updateWorldTransform();
+	skeleton->updateWorldTransform(Physics::update);
 
 
 	drawable.state->setAnimation(0, "walk", true);
 	drawable.state->setAnimation(0, "walk", true);
 	drawable.state->addAnimation(1, "gun-grab", false, 2);
 	drawable.state->addAnimation(1, "gun-grab", false, 2);
@@ -314,7 +314,7 @@ void tank(SkeletonData *skeletonData, Atlas *atlas) {
 
 
 	Skeleton *skeleton = drawable.skeleton;
 	Skeleton *skeleton = drawable.skeleton;
 	skeleton->setPosition(500, 590);
 	skeleton->setPosition(500, 590);
-	skeleton->updateWorldTransform();
+	skeleton->updateWorldTransform(Physics::update);
 
 
 	drawable.state->setAnimation(0, "drive", true);
 	drawable.state->setAnimation(0, "drive", true);
 
 
@@ -345,7 +345,7 @@ void vine(SkeletonData *skeletonData, Atlas *atlas) {
 
 
 	Skeleton *skeleton = drawable.skeleton;
 	Skeleton *skeleton = drawable.skeleton;
 	skeleton->setPosition(320, 590);
 	skeleton->setPosition(320, 590);
-	skeleton->updateWorldTransform();
+	skeleton->updateWorldTransform(Physics::update);
 
 
 	drawable.state->setAnimation(0, "grow", true);
 	drawable.state->setAnimation(0, "grow", true);
 
 
@@ -378,7 +378,7 @@ void stretchyman(SkeletonData *skeletonData, Atlas *atlas) {
 	Skeleton *skeleton = drawable.skeleton;
 	Skeleton *skeleton = drawable.skeleton;
 
 
 	skeleton->setPosition(100, 590);
 	skeleton->setPosition(100, 590);
-	skeleton->updateWorldTransform();
+	skeleton->updateWorldTransform(Physics::update);
 
 
 	drawable.state->setAnimation(0, "sneak", true);
 	drawable.state->setAnimation(0, "sneak", true);
 
 
@@ -411,7 +411,7 @@ void stretchymanStrechyIk(SkeletonData *skeletonData, Atlas *atlas) {
 	Skeleton *skeleton = drawable->skeleton;
 	Skeleton *skeleton = drawable->skeleton;
 
 
 	skeleton->setPosition(100, 590);
 	skeleton->setPosition(100, 590);
-	skeleton->updateWorldTransform();
+	skeleton->updateWorldTransform(Physics::update);
 
 
 	drawable->state->setAnimation(0, "sneak", true);
 	drawable->state->setAnimation(0, "sneak", true);
 
 
@@ -445,7 +445,7 @@ void coin(SkeletonData *skeletonData, Atlas *atlas) {
 
 
 	Skeleton *skeleton = drawable.skeleton;
 	Skeleton *skeleton = drawable.skeleton;
 	skeleton->setPosition(320, 320);
 	skeleton->setPosition(320, 320);
-	skeleton->updateWorldTransform();
+	skeleton->updateWorldTransform(Physics::update);
 
 
 	drawable.state->setAnimation(0, "animation", true);
 	drawable.state->setAnimation(0, "animation", true);
 
 
@@ -479,7 +479,7 @@ void dragon(SkeletonData *skeletonData, Atlas *atlas) {
 
 
 	Skeleton *skeleton = drawable.skeleton;
 	Skeleton *skeleton = drawable.skeleton;
 	skeleton->setPosition(320, 320);
 	skeleton->setPosition(320, 320);
-	skeleton->updateWorldTransform();
+	skeleton->updateWorldTransform(Physics::update);
 
 
 	drawable.state->setAnimation(0, "flying", true);
 	drawable.state->setAnimation(0, "flying", true);
 
 
@@ -513,7 +513,7 @@ void owl(SkeletonData *skeletonData, Atlas *atlas) {
 
 
 	Skeleton *skeleton = drawable.skeleton;
 	Skeleton *skeleton = drawable.skeleton;
 	skeleton->setPosition(320, 400);
 	skeleton->setPosition(320, 400);
-	skeleton->updateWorldTransform();
+	skeleton->updateWorldTransform(Physics::update);
 
 
 	drawable.state->setAnimation(0, "idle", true);
 	drawable.state->setAnimation(0, "idle", true);
 	drawable.state->setAnimation(1, "blink", true);
 	drawable.state->setAnimation(1, "blink", true);
@@ -588,7 +588,7 @@ void mixAndMatch(SkeletonData *skeletonData, Atlas *atlas) {
 	skeleton->setSlotsToSetupPose();
 	skeleton->setSlotsToSetupPose();
 
 
 	skeleton->setPosition(320, 590);
 	skeleton->setPosition(320, 590);
-	skeleton->updateWorldTransform();
+	skeleton->updateWorldTransform(Physics::update);
 
 
 	drawable.state->setAnimation(0, "dance", true);
 	drawable.state->setAnimation(0, "dance", true);
 
 
@@ -626,7 +626,7 @@ void test(SkeletonData *skeletonData, Atlas *atlas) {
 	for (int i = 0; i < 1; i++) {
 	for (int i = 0; i < 1; i++) {
 		animationState.update(d);
 		animationState.update(d);
 		animationState.apply(skeleton);
 		animationState.apply(skeleton);
-		skeleton.updateWorldTransform();
+		skeleton.updateWorldTransform(Physics::update);
 		d += 0.1f;
 		d += 0.1f;
 	}
 	}
 }
 }

+ 18 - 17
spine-sfml/cpp/example/testbed.cpp

@@ -35,47 +35,47 @@ using namespace spine;
 
 
 class NullTextureLoader : public TextureLoader {
 class NullTextureLoader : public TextureLoader {
 public:
 public:
-	virtual void load(AtlasPage &page, const String &path) {}
+	virtual void load(AtlasPage &, const String &) {}
 
 
-	virtual void unload(void *texture) {}
+	virtual void unload(void *) {}
 };
 };
 
 
 class NullAttachmentLoader : public AttachmentLoader {
 class NullAttachmentLoader : public AttachmentLoader {
-	virtual RegionAttachment *newRegionAttachment(Skin &skin, const String &name, const String &path, Sequence *sequence) {
+	virtual RegionAttachment *newRegionAttachment(Skin &, const String &name, const String &, Sequence *) {
 		return new (__FILE__, __LINE__) RegionAttachment(name);
 		return new (__FILE__, __LINE__) RegionAttachment(name);
 	}
 	}
 
 
-	virtual MeshAttachment *newMeshAttachment(Skin &skin, const String &name, const String &path, Sequence *sequence) {
+	virtual MeshAttachment *newMeshAttachment(Skin &, const String &name, const String &, Sequence *) {
 		return new (__FILE__, __LINE__) MeshAttachment(name);
 		return new (__FILE__, __LINE__) MeshAttachment(name);
 	}
 	}
 
 
-	virtual BoundingBoxAttachment *newBoundingBoxAttachment(Skin &skin, const String &name) {
+	virtual BoundingBoxAttachment *newBoundingBoxAttachment(Skin &, const String &name) {
 		return new (__FILE__, __LINE__) BoundingBoxAttachment(name);
 		return new (__FILE__, __LINE__) BoundingBoxAttachment(name);
 	}
 	}
 
 
-	virtual PathAttachment *newPathAttachment(Skin &skin, const String &name) {
+	virtual PathAttachment *newPathAttachment(Skin &, const String &name) {
 		return new (__FILE__, __LINE__) PathAttachment(name);
 		return new (__FILE__, __LINE__) PathAttachment(name);
 	}
 	}
 
 
-	virtual PointAttachment *newPointAttachment(Skin &skin, const String &name) {
+	virtual PointAttachment *newPointAttachment(Skin &, const String &name) {
 		return new (__FILE__, __LINE__) PointAttachment(name);
 		return new (__FILE__, __LINE__) PointAttachment(name);
 	}
 	}
 
 
-	virtual ClippingAttachment *newClippingAttachment(Skin &skin, const String &name) {
+	virtual ClippingAttachment *newClippingAttachment(Skin &, const String &name) {
 		return new (__FILE__, __LINE__) ClippingAttachment(name);
 		return new (__FILE__, __LINE__) ClippingAttachment(name);
 	}
 	}
 
 
-	virtual void configureAttachment(Attachment *attachment) {
+	virtual void configureAttachment(Attachment *) {
 	}
 	}
 };
 };
 
 
 int main(void) {
 int main(void) {
-	String atlasFile("/Users/badlogic/Desktop/basemodel-male/basemodel-male.atlas");
-	String skeletonFile("/Users/badlogic/Desktop/basemodel-male/basemodel-male.skel");
-	String animation = "";
-	String skin = "BasicBody";
+	String atlasFile("data/sack-pma.atlas");
+	String skeletonFile("data/sack-pro.json");
+	String animation = "walk";
+	String skin = "";
 
 
-	float scale = 0.1f;
+	float scale = 0.6f;
 	SFMLTextureLoader textureLoader;
 	SFMLTextureLoader textureLoader;
 	NullAttachmentLoader nullLoader;
 	NullAttachmentLoader nullLoader;
 	Atlas *atlas = atlasFile.length() == 0 ? nullptr : new Atlas(atlasFile, &textureLoader);
 	Atlas *atlas = atlasFile.length() == 0 ? nullptr : new Atlas(atlasFile, &textureLoader);
@@ -104,12 +104,13 @@ int main(void) {
 
 
 	AnimationStateData stateData(skeletonData);
 	AnimationStateData stateData(skeletonData);
 	SkeletonDrawable drawable(skeletonData, &stateData);
 	SkeletonDrawable drawable(skeletonData, &stateData);
-	drawable.skeleton->updateWorldTransform();
-	drawable.skeleton->setPosition(320, 590);
+    drawable.skeleton->getRootBone()->update(Physics::update);
+	drawable.skeleton->updateWorldTransform(Physics::update);
+	drawable.skeleton->setPosition(320, 960);
 	if (animation.length() > 0) drawable.state->setAnimation(0, animation, true);
 	if (animation.length() > 0) drawable.state->setAnimation(0, animation, true);
 	if (skin.length() > 0) drawable.skeleton->setSkin(skin);
 	if (skin.length() > 0) drawable.skeleton->setSkin(skin);
 
 
-	sf::RenderWindow window(sf::VideoMode(640, 640), "Spine SFML - testbed");
+	sf::RenderWindow window(sf::VideoMode(1024, 1024), "Spine SFML - testbed");
 	window.setFramerateLimit(60);
 	window.setFramerateLimit(60);
 	sf::Event event;
 	sf::Event event;
 	sf::Clock deltaClock;
 	sf::Clock deltaClock;

+ 3 - 3
spine-sfml/cpp/src/spine/spine-sfml.cpp

@@ -49,7 +49,7 @@ namespace spine {
 
 
 	SkeletonDrawable::SkeletonDrawable(SkeletonData *skeletonData, AnimationStateData *stateData) : timeScale(1),
 	SkeletonDrawable::SkeletonDrawable(SkeletonData *skeletonData, AnimationStateData *stateData) : timeScale(1),
 																									vertexArray(new VertexArray(Triangles, skeletonData->getBones().size() * 4)),
 																									vertexArray(new VertexArray(Triangles, skeletonData->getBones().size() * 4)),
-																									worldVertices(), clipper() {
+																									worldVertices(), clipper(), usePremultipliedAlpha(false) {
 		Bone::setYDown(true);
 		Bone::setYDown(true);
 		worldVertices.ensureCapacity(SPINE_MESH_VERTEX_COUNT_MAX);
 		worldVertices.ensureCapacity(SPINE_MESH_VERTEX_COUNT_MAX);
 		skeleton = new (__FILE__, __LINE__) Skeleton(skeletonData);
 		skeleton = new (__FILE__, __LINE__) Skeleton(skeletonData);
@@ -76,10 +76,10 @@ namespace spine {
 		delete skeleton;
 		delete skeleton;
 	}
 	}
 
 
-	void SkeletonDrawable::update(float deltaTime) {
+	void SkeletonDrawable::update(float deltaTime, Physics physics) {
 		state->update(deltaTime * timeScale);
 		state->update(deltaTime * timeScale);
 		state->apply(*skeleton);
 		state->apply(*skeleton);
-		skeleton->updateWorldTransform();
+		skeleton->updateWorldTransform(physics);
 	}
 	}
 
 
 	void SkeletonDrawable::draw(RenderTarget &target, RenderStates states) const {
 	void SkeletonDrawable::draw(RenderTarget &target, RenderStates states) const {

+ 1 - 1
spine-sfml/cpp/src/spine/spine-sfml.h

@@ -52,7 +52,7 @@ namespace spine {
 
 
 		~SkeletonDrawable();
 		~SkeletonDrawable();
 
 
-		void update(float deltaTime);
+		void update(float deltaTime, Physics physics = Physics::update);
 
 
 		virtual void draw(sf::RenderTarget &target, sf::RenderStates states) const;
 		virtual void draw(sf::RenderTarget &target, sf::RenderStates states) const;