mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-06 23:34:53 +08:00
[cpp] 4.3 porting WIP
This commit is contained in:
parent
cb6916c3c3
commit
fb331a19c0
@ -30,7 +30,7 @@
|
||||
#ifndef Spine_Bone_h
|
||||
#define Spine_Bone_h
|
||||
|
||||
#include <spine/Updatable.h>
|
||||
#include <spine/Update.h>
|
||||
#include <spine/SpineObject.h>
|
||||
#include <spine/Vector.h>
|
||||
#include <spine/Inherit.h>
|
||||
@ -45,7 +45,7 @@ namespace spine {
|
||||
/// A bone has a local transform which is used to compute its world transform. A bone also has an applied transform, which is a
|
||||
/// local transform that can be applied to compute the world transform. The local transform and applied transform may differ if a
|
||||
/// constraint or application code modifies the world transform after it was computed from the local transform.
|
||||
class SP_API Bone : public Updatable {
|
||||
class SP_API Bone : public Update {
|
||||
friend class AnimationState;
|
||||
|
||||
friend class RotateTimeline;
|
||||
|
||||
@ -40,7 +40,7 @@ namespace spine {
|
||||
class SP_API BoneLocal : public Pose<BoneLocal> {
|
||||
RTTI_DECL
|
||||
|
||||
private:
|
||||
protected:
|
||||
float _x, _y, _rotation, _scaleX, _scaleY, _shearX, _shearY;
|
||||
Inherit _inherit;
|
||||
|
||||
|
||||
141
spine-cpp/spine-cpp/include/spine/BonePose.h
Normal file
141
spine-cpp/spine-cpp/include/spine/BonePose.h
Normal file
@ -0,0 +1,141 @@
|
||||
/******************************************************************************
|
||||
* Spine Runtimes License Agreement
|
||||
* Last updated April 5, 2025. Replaces all prior versions.
|
||||
*
|
||||
* Copyright (c) 2013-2025, Esoteric Software LLC
|
||||
*
|
||||
* Integration of the Spine Runtimes into software or otherwise creating
|
||||
* derivative works of the Spine Runtimes is permitted under the terms and
|
||||
* conditions of Section 2 of the Spine Editor License Agreement:
|
||||
* http://esotericsoftware.com/spine-editor-license
|
||||
*
|
||||
* Otherwise, it is permitted to integrate the Spine Runtimes into software
|
||||
* or otherwise create derivative works of the Spine Runtimes (collectively,
|
||||
* "Products"), provided that each user of the Products must obtain their own
|
||||
* Spine Editor license and redistribution of the Products in any form must
|
||||
* include this license and copyright notice.
|
||||
*
|
||||
* THE SPINE RUNTIMES ARE PROVIDED BY ESOTERIC SOFTWARE LLC "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL ESOTERIC SOFTWARE LLC BE LIABLE FOR ANY
|
||||
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES,
|
||||
* BUSINESS INTERRUPTION, OR LOSS OF USE, DATA, OR PROFITS) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THE SPINE RUNTIMES, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef SPINE_BONEPOSE_H_
|
||||
#define SPINE_BONEPOSE_H_
|
||||
|
||||
#include <spine/BoneLocal.h>
|
||||
#include <spine/Update.h>
|
||||
#include <spine/RTTI.h>
|
||||
|
||||
namespace spine {
|
||||
class Bone;
|
||||
class Skeleton;
|
||||
|
||||
class SP_API BonePose : public BoneLocal, public Update {
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
Bone* _bone;
|
||||
float _a, _b, _worldX;
|
||||
float _c, _d, _worldY;
|
||||
int _world, _local;
|
||||
|
||||
BonePose();
|
||||
virtual ~BonePose();
|
||||
|
||||
/// Called by Skeleton::updateCache() to compute the world transform, if needed.
|
||||
virtual void update(Skeleton& skeleton, Physics physics) override;
|
||||
|
||||
/// Computes the world transform using the parent bone's applied pose and this pose. Child bones are not updated.
|
||||
///
|
||||
/// See <a href="https://esotericsoftware.com/spine-runtime-skeletons#World-transforms">World transforms</a> in the Spine
|
||||
/// Runtimes Guide.
|
||||
void updateWorldTransform(Skeleton& skeleton);
|
||||
|
||||
/// Computes the local transform values from the world transform.
|
||||
///
|
||||
/// If the world transform is modified (by a constraint, rotateWorld(), etc) then this method should be called so
|
||||
/// the local transform matches the world transform. The local transform may be needed by other code (eg to apply another
|
||||
/// constraint).
|
||||
///
|
||||
/// Some information is ambiguous in the world transform, such as -1,-1 scale versus 180 rotation. The local transform after
|
||||
/// calling this method is equivalent to the local transform used to compute the world transform, but may not be identical.
|
||||
void updateLocalTransform(Skeleton& skeleton);
|
||||
|
||||
/// If the world transform has been modified and the local transform no longer matches, updateLocalTransform() is called.
|
||||
void validateLocalTransform(Skeleton& skeleton);
|
||||
|
||||
void modifyLocal(Skeleton& skeleton);
|
||||
void modifyWorld(int update);
|
||||
void resetWorld(int update);
|
||||
|
||||
/// Part of the world transform matrix for the X axis. If changed, updateLocalTransform() should be called.
|
||||
float getA();
|
||||
void setA(float a);
|
||||
|
||||
/// Part of the world transform matrix for the Y axis. If changed, updateLocalTransform() should be called.
|
||||
float getB();
|
||||
void setB(float b);
|
||||
|
||||
/// Part of the world transform matrix for the X axis. If changed, updateLocalTransform() should be called.
|
||||
float getC();
|
||||
void setC(float c);
|
||||
|
||||
/// Part of the world transform matrix for the Y axis. If changed, updateLocalTransform() should be called.
|
||||
float getD();
|
||||
void setD(float d);
|
||||
|
||||
/// The world X position. If changed, updateLocalTransform() should be called.
|
||||
float getWorldX();
|
||||
void setWorldX(float worldX);
|
||||
|
||||
/// The world Y position. If changed, updateLocalTransform() should be called.
|
||||
float getWorldY();
|
||||
void setWorldY(float worldY);
|
||||
|
||||
/// The world rotation for the X axis, calculated using a and c.
|
||||
float getWorldRotationX();
|
||||
|
||||
/// The world rotation for the Y axis, calculated using b and d.
|
||||
float getWorldRotationY();
|
||||
|
||||
/// The magnitude (always positive) of the world scale X, calculated using a and c.
|
||||
float getWorldScaleX();
|
||||
|
||||
/// The magnitude (always positive) of the world scale Y, calculated using b and d.
|
||||
float getWorldScaleY();
|
||||
|
||||
/// Transforms a point from world coordinates to the bone's local coordinates.
|
||||
void worldToLocal(float worldX, float worldY, float& outLocalX, float& outLocalY);
|
||||
|
||||
/// Transforms a point from the bone's local coordinates to world coordinates.
|
||||
void localToWorld(float localX, float localY, float& outWorldX, float& outWorldY);
|
||||
|
||||
/// Transforms a point from world coordinates to the parent bone's local coordinates.
|
||||
void worldToParent(float worldX, float worldY, float& outParentX, float& outParentY);
|
||||
|
||||
/// Transforms a point from the parent bone's coordinates to world coordinates.
|
||||
void parentToWorld(float parentX, float parentY, float& outWorldX, float& outWorldY);
|
||||
|
||||
/// Transforms a world rotation to a local rotation.
|
||||
float worldToLocalRotation(float worldRotation);
|
||||
|
||||
/// Transforms a local rotation to a world rotation.
|
||||
float localToWorldRotation(float localRotation);
|
||||
|
||||
/// Rotates the world transform the specified amount.
|
||||
///
|
||||
/// After changes are made to the world transform, updateLocalTransform() should be called on this bone and any
|
||||
/// child bones, recursively.
|
||||
void rotateWorld(float degrees);
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* SPINE_BONEPOSE_H_ */
|
||||
57
spine-cpp/spine-cpp/include/spine/FromProperty.h
Normal file
57
spine-cpp/spine-cpp/include/spine/FromProperty.h
Normal file
@ -0,0 +1,57 @@
|
||||
/******************************************************************************
|
||||
* 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_FROMPROPERTY_H_
|
||||
#define SPINE_FROMPROPERTY_H_
|
||||
|
||||
#include <spine/dll.h>
|
||||
#include <spine/Vector.h>
|
||||
|
||||
namespace spine {
|
||||
class ToProperty;
|
||||
class BonePose;
|
||||
|
||||
/// Source property for a TransformConstraint.
|
||||
class SP_API FromProperty {
|
||||
public:
|
||||
FromProperty();
|
||||
virtual ~FromProperty();
|
||||
|
||||
/// The value of this property that corresponds to ToProperty::offset.
|
||||
float offset;
|
||||
|
||||
/// Constrained properties.
|
||||
Vector<ToProperty*> to;
|
||||
|
||||
/// Reads this property from the specified bone.
|
||||
virtual float value(BonePose& source, bool local, Vector<float>& offsets) = 0;
|
||||
};
|
||||
}
|
||||
|
||||
#endif /* SPINE_FROMPROPERTY_H_ */
|
||||
@ -43,6 +43,7 @@
|
||||
#include <spine/Bone.h>
|
||||
#include <spine/BoneData.h>
|
||||
#include <spine/BoneLocal.h>
|
||||
#include <spine/BonePose.h>
|
||||
#include <spine/BoneTimeline.h>
|
||||
#include <spine/BoundingBoxAttachment.h>
|
||||
#include <spine/ClippingAttachment.h>
|
||||
@ -58,6 +59,7 @@
|
||||
#include <spine/EventData.h>
|
||||
#include <spine/EventTimeline.h>
|
||||
#include <spine/Extension.h>
|
||||
#include <spine/FromProperty.h>
|
||||
#include <spine/HasRendererObject.h>
|
||||
#include <spine/HashMap.h>
|
||||
#include <spine/IkConstraint.h>
|
||||
|
||||
388
spine-cpp/spine-cpp/src/spine/BonePose.cpp
Normal file
388
spine-cpp/spine-cpp/src/spine/BonePose.cpp
Normal file
@ -0,0 +1,388 @@
|
||||
/******************************************************************************
|
||||
* 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 <spine/BonePose.h>
|
||||
#include <spine/Bone.h>
|
||||
#include <spine/BoneData.h>
|
||||
#include <spine/Skeleton.h>
|
||||
#include <spine/Physics.h>
|
||||
#include <spine/MathUtil.h>
|
||||
|
||||
using namespace spine;
|
||||
|
||||
RTTI_IMPL(BonePose, BoneLocal)
|
||||
|
||||
BonePose::BonePose() : BoneLocal(), _bone(nullptr), _a(0), _b(0), _worldX(0), _c(0), _d(0), _worldY(0), _world(0), _local(0) {
|
||||
}
|
||||
|
||||
BonePose::~BonePose() {
|
||||
}
|
||||
|
||||
void BonePose::update(Skeleton& skeleton, Physics physics) {
|
||||
if (_world != skeleton.getUpdate()) updateWorldTransform(skeleton);
|
||||
}
|
||||
|
||||
void BonePose::updateWorldTransform(Skeleton& skeleton) {
|
||||
if (_local == skeleton.getUpdate())
|
||||
updateLocalTransform(skeleton);
|
||||
else
|
||||
_world = skeleton.getUpdate();
|
||||
|
||||
if (_bone->getParent() == nullptr) { // Root bone.
|
||||
float sx = skeleton.getScaleX(), sy = skeleton.getScaleY();
|
||||
float rx = (_rotation + _shearX) * MathUtil::Deg_Rad;
|
||||
float ry = (_rotation + 90 + _shearY) * MathUtil::Deg_Rad;
|
||||
_a = MathUtil::cos(rx) * _scaleX * sx;
|
||||
_b = MathUtil::cos(ry) * _scaleY * sx;
|
||||
_c = MathUtil::sin(rx) * _scaleX * sy;
|
||||
_d = MathUtil::sin(ry) * _scaleY * sy;
|
||||
_worldX = _x * sx + skeleton.getX();
|
||||
_worldY = _y * sy + skeleton.getY();
|
||||
return;
|
||||
}
|
||||
|
||||
BonePose& parent = _bone->getParent()->getApplied();
|
||||
float pa = parent._a, pb = parent._b, pc = parent._c, pd = parent._d;
|
||||
_worldX = pa * _x + pb * _y + parent._worldX;
|
||||
_worldY = pc * _x + pd * _y + parent._worldY;
|
||||
|
||||
switch (_inherit) {
|
||||
case Inherit_Normal: {
|
||||
float rx = (_rotation + _shearX) * MathUtil::Deg_Rad;
|
||||
float ry = (_rotation + 90 + _shearY) * MathUtil::Deg_Rad;
|
||||
float la = MathUtil::cos(rx) * _scaleX;
|
||||
float lb = MathUtil::cos(ry) * _scaleY;
|
||||
float lc = MathUtil::sin(rx) * _scaleX;
|
||||
float ld = MathUtil::sin(ry) * _scaleY;
|
||||
_a = pa * la + pb * lc;
|
||||
_b = pa * lb + pb * ld;
|
||||
_c = pc * la + pd * lc;
|
||||
_d = pc * lb + pd * ld;
|
||||
return;
|
||||
}
|
||||
case Inherit_OnlyTranslation: {
|
||||
float rx = (_rotation + _shearX) * MathUtil::Deg_Rad;
|
||||
float ry = (_rotation + 90 + _shearY) * MathUtil::Deg_Rad;
|
||||
_a = MathUtil::cos(rx) * _scaleX;
|
||||
_b = MathUtil::cos(ry) * _scaleY;
|
||||
_c = MathUtil::sin(rx) * _scaleX;
|
||||
_d = MathUtil::sin(ry) * _scaleY;
|
||||
break;
|
||||
}
|
||||
case Inherit_NoRotationOrReflection: {
|
||||
float sx = 1 / skeleton.getScaleX(), sy = 1 / skeleton.getScaleY();
|
||||
pa *= sx;
|
||||
pc *= sy;
|
||||
float s = pa * pa + pc * pc, prx;
|
||||
if (s > 0.0001f) {
|
||||
s = MathUtil::abs(pa * pd * sy - pb * sx * pc) / s;
|
||||
pb = pc * s;
|
||||
pd = pa * s;
|
||||
prx = MathUtil::atan2(pc, pa) * MathUtil::Rad_Deg;
|
||||
} else {
|
||||
pa = 0;
|
||||
pc = 0;
|
||||
prx = 90 - MathUtil::atan2(pd, pb) * MathUtil::Rad_Deg;
|
||||
}
|
||||
float rx = (_rotation + _shearX - prx) * MathUtil::Deg_Rad;
|
||||
float ry = (_rotation + _shearY - prx + 90) * MathUtil::Deg_Rad;
|
||||
float la = MathUtil::cos(rx) * _scaleX;
|
||||
float lb = MathUtil::cos(ry) * _scaleY;
|
||||
float lc = MathUtil::sin(rx) * _scaleX;
|
||||
float ld = MathUtil::sin(ry) * _scaleY;
|
||||
_a = pa * la - pb * lc;
|
||||
_b = pa * lb - pb * ld;
|
||||
_c = pc * la + pd * lc;
|
||||
_d = pc * lb + pd * ld;
|
||||
break;
|
||||
}
|
||||
case Inherit_NoScale:
|
||||
case Inherit_NoScaleOrReflection: {
|
||||
float rot = _rotation * MathUtil::Deg_Rad;
|
||||
float cosRot = MathUtil::cos(rot), sinRot = MathUtil::sin(rot);
|
||||
float za = (pa * cosRot + pb * sinRot) / skeleton.getScaleX();
|
||||
float zc = (pc * cosRot + pd * sinRot) / skeleton.getScaleY();
|
||||
float s = MathUtil::sqrt(za * za + zc * zc);
|
||||
if (s > 0.00001f) s = 1 / s;
|
||||
za *= s;
|
||||
zc *= s;
|
||||
s = MathUtil::sqrt(za * za + zc * zc);
|
||||
if (_inherit == Inherit_NoScale && (pa * pd - pb * pc < 0) != (skeleton.getScaleX() < 0 != skeleton.getScaleY() < 0)) s = -s;
|
||||
rot = MathUtil::Pi / 2 + MathUtil::atan2(zc, za);
|
||||
float zb = MathUtil::cos(rot) * s;
|
||||
float zd = MathUtil::sin(rot) * s;
|
||||
float _shearXRad = _shearX * MathUtil::Deg_Rad;
|
||||
float _shearYRad = (90 + _shearY) * MathUtil::Deg_Rad;
|
||||
float la = MathUtil::cos(_shearXRad) * _scaleX;
|
||||
float lb = MathUtil::cos(_shearYRad) * _scaleY;
|
||||
float lc = MathUtil::sin(_shearXRad) * _scaleX;
|
||||
float ld = MathUtil::sin(_shearYRad) * _scaleY;
|
||||
_a = za * la + zb * lc;
|
||||
_b = za * lb + zb * ld;
|
||||
_c = zc * la + zd * lc;
|
||||
_d = zc * lb + zd * ld;
|
||||
break;
|
||||
}
|
||||
}
|
||||
_a *= skeleton.getScaleX();
|
||||
_b *= skeleton.getScaleX();
|
||||
_c *= skeleton.getScaleY();
|
||||
_d *= skeleton.getScaleY();
|
||||
}
|
||||
|
||||
void BonePose::updateLocalTransform(Skeleton& skeleton) {
|
||||
_local = 0;
|
||||
_world = skeleton.getUpdate();
|
||||
|
||||
if (_bone->getParent() == nullptr) {
|
||||
_x = _worldX - skeleton.getX();
|
||||
_y = _worldY - skeleton.getY();
|
||||
float _a = this->_a, _b = this->_b, _c = this->_c, _d = this->_d;
|
||||
_rotation = MathUtil::atan2(_c, _a) * MathUtil::Rad_Deg;
|
||||
_scaleX = MathUtil::sqrt(_a * _a + _c * _c);
|
||||
_scaleY = MathUtil::sqrt(_b * _b + _d * _d);
|
||||
_shearX = 0;
|
||||
_shearY = MathUtil::atan2(_a * _b + _c * _d, _a * _d - _b * _c) * MathUtil::Rad_Deg;
|
||||
return;
|
||||
}
|
||||
|
||||
BonePose& parent = _bone->getParent()->getApplied();
|
||||
float pa = parent._a, pb = parent._b, pc = parent._c, pd = parent._d;
|
||||
float pid = 1 / (pa * pd - pb * pc);
|
||||
float ia = pd * pid, ib = pb * pid, ic = pc * pid, id = pa * pid;
|
||||
float dx = _worldX - parent._worldX, dy = _worldY - parent._worldY;
|
||||
_x = (dx * ia - dy * ib);
|
||||
_y = (dy * id - dx * ic);
|
||||
|
||||
float ra, rb, rc, rd;
|
||||
if (_inherit == Inherit_OnlyTranslation) {
|
||||
ra = _a;
|
||||
rb = _b;
|
||||
rc = _c;
|
||||
rd = _d;
|
||||
} else {
|
||||
switch (_inherit) {
|
||||
case Inherit_NoRotationOrReflection: {
|
||||
float s = MathUtil::abs(pa * pd - pb * pc) / (pa * pa + pc * pc);
|
||||
pb = -pc * skeleton.getScaleX() * s / skeleton.getScaleY();
|
||||
pd = pa * skeleton.getScaleY() * s / skeleton.getScaleX();
|
||||
pid = 1 / (pa * pd - pb * pc);
|
||||
ia = pd * pid;
|
||||
ib = pb * pid;
|
||||
break;
|
||||
}
|
||||
case Inherit_NoScale:
|
||||
case Inherit_NoScaleOrReflection: {
|
||||
float r = _rotation * MathUtil::Deg_Rad, cosR = MathUtil::cos(r), sinR = MathUtil::sin(r);
|
||||
pa = (pa * cosR + pb * sinR) / skeleton.getScaleX();
|
||||
pc = (pc * cosR + pd * sinR) / skeleton.getScaleY();
|
||||
float s = MathUtil::sqrt(pa * pa + pc * pc);
|
||||
if (s > 0.00001f) s = 1 / s;
|
||||
pa *= s;
|
||||
pc *= s;
|
||||
s = MathUtil::sqrt(pa * pa + pc * pc);
|
||||
if (_inherit == Inherit_NoScale && pid < 0 != (skeleton.getScaleX() < 0 != skeleton.getScaleY() < 0)) s = -s;
|
||||
r = MathUtil::Pi / 2 + MathUtil::atan2(pc, pa);
|
||||
pb = MathUtil::cos(r) * s;
|
||||
pd = MathUtil::sin(r) * s;
|
||||
pid = 1 / (pa * pd - pb * pc);
|
||||
ia = pd * pid;
|
||||
ib = pb * pid;
|
||||
ic = pc * pid;
|
||||
id = pa * pid;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
ra = ia * _a - ib * _c;
|
||||
rb = ia * _b - ib * _d;
|
||||
rc = id * _c - ic * _a;
|
||||
rd = id * _d - ic * _b;
|
||||
}
|
||||
|
||||
_shearX = 0;
|
||||
_scaleX = MathUtil::sqrt(ra * ra + rc * rc);
|
||||
if (_scaleX > 0.0001f) {
|
||||
float det = ra * rd - rb * rc;
|
||||
_scaleY = det / _scaleX;
|
||||
_shearY = -MathUtil::atan2(ra * rb + rc * rd, det) * MathUtil::Rad_Deg;
|
||||
_rotation = MathUtil::atan2(rc, ra) * MathUtil::Rad_Deg;
|
||||
} else {
|
||||
_scaleX = 0;
|
||||
_scaleY = MathUtil::sqrt(rb * rb + rd * rd);
|
||||
_shearY = 0;
|
||||
_rotation = 90 - MathUtil::atan2(rd, rb) * MathUtil::Rad_Deg;
|
||||
}
|
||||
}
|
||||
|
||||
void BonePose::validateLocalTransform(Skeleton& skeleton) {
|
||||
if (_local == skeleton.getUpdate()) updateLocalTransform(skeleton);
|
||||
}
|
||||
|
||||
void BonePose::modifyLocal(Skeleton& skeleton) {
|
||||
if (_local == skeleton.getUpdate()) updateLocalTransform(skeleton);
|
||||
_world = 0;
|
||||
resetWorld(skeleton.getUpdate());
|
||||
}
|
||||
|
||||
void BonePose::modifyWorld(int update) {
|
||||
_local = update;
|
||||
_world = update;
|
||||
resetWorld(update);
|
||||
}
|
||||
|
||||
void BonePose::resetWorld(int update) {
|
||||
Vector<Bone*>& children = _bone->getChildren();
|
||||
for (size_t i = 0, n = children.size(); i < n; i++) {
|
||||
BonePose& child = children[i]->getApplied();
|
||||
if (child._world == update) {
|
||||
child._world = 0;
|
||||
child._local = 0;
|
||||
child.resetWorld(update);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
float BonePose::getA() {
|
||||
return _a;
|
||||
}
|
||||
|
||||
void BonePose::setA(float a) {
|
||||
this->_a = a;
|
||||
}
|
||||
|
||||
float BonePose::getB() {
|
||||
return _b;
|
||||
}
|
||||
|
||||
void BonePose::setB(float b) {
|
||||
this->_b = b;
|
||||
}
|
||||
|
||||
float BonePose::getC() {
|
||||
return _c;
|
||||
}
|
||||
|
||||
void BonePose::setC(float c) {
|
||||
this->_c = c;
|
||||
}
|
||||
|
||||
float BonePose::getD() {
|
||||
return _d;
|
||||
}
|
||||
|
||||
void BonePose::setD(float d) {
|
||||
this->_d = d;
|
||||
}
|
||||
|
||||
float BonePose::getWorldX() {
|
||||
return _worldX;
|
||||
}
|
||||
|
||||
void BonePose::setWorldX(float _worldX) {
|
||||
this->_worldX = _worldX;
|
||||
}
|
||||
|
||||
float BonePose::getWorldY() {
|
||||
return _worldY;
|
||||
}
|
||||
|
||||
void BonePose::setWorldY(float _worldY) {
|
||||
this->_worldY = _worldY;
|
||||
}
|
||||
|
||||
float BonePose::getWorldRotationX() {
|
||||
return MathUtil::atan2(_c, _a) * MathUtil::Rad_Deg;
|
||||
}
|
||||
|
||||
float BonePose::getWorldRotationY() {
|
||||
return MathUtil::atan2(_d, _b) * MathUtil::Rad_Deg;
|
||||
}
|
||||
|
||||
float BonePose::getWorldScaleX() {
|
||||
return MathUtil::sqrt(_a * _a + _c * _c);
|
||||
}
|
||||
|
||||
float BonePose::getWorldScaleY() {
|
||||
return MathUtil::sqrt(_b * _b + _d * _d);
|
||||
}
|
||||
|
||||
|
||||
void BonePose::worldToLocal(float worldX, float worldY, float& outLocalX, float& outLocalY) {
|
||||
float det = _a * _d - _b * _c;
|
||||
float _x = worldX - _worldX, _y = worldY - _worldY;
|
||||
outLocalX = (_x * _d - _y * _b) / det;
|
||||
outLocalY = (_y * _a - _x * _c) / det;
|
||||
}
|
||||
|
||||
void BonePose::localToWorld(float localX, float localY, float& outWorldX, float& outWorldY) {
|
||||
outWorldX = localX * _a + localY * _b + _worldX;
|
||||
outWorldY = localX * _c + localY * _d + _worldY;
|
||||
}
|
||||
|
||||
void BonePose::worldToParent(float worldX, float worldY, float& outParentX, float& outParentY) {
|
||||
if (_bone->getParent() == nullptr) {
|
||||
outParentX = worldX;
|
||||
outParentY = worldY;
|
||||
} else {
|
||||
_bone->getParent()->getApplied().worldToLocal(worldX, worldY, outParentX, outParentY);
|
||||
}
|
||||
}
|
||||
|
||||
void BonePose::parentToWorld(float parentX, float parentY, float& outWorldX, float& outWorldY) {
|
||||
if (_bone->getParent() == nullptr) {
|
||||
outWorldX = parentX;
|
||||
outWorldY = parentY;
|
||||
} else {
|
||||
_bone->getParent()->getApplied().localToWorld(parentX, parentY, outWorldX, outWorldY);
|
||||
}
|
||||
}
|
||||
|
||||
float BonePose::worldToLocalRotation(float worldRotation) {
|
||||
worldRotation *= MathUtil::Deg_Rad;
|
||||
float sinRot = MathUtil::sin(worldRotation), cosRot = MathUtil::cos(worldRotation);
|
||||
return MathUtil::atan2(_a * sinRot - _c * cosRot, _d * cosRot - _b * sinRot) * MathUtil::Rad_Deg + _rotation - _shearX;
|
||||
}
|
||||
|
||||
float BonePose::localToWorldRotation(float localRotation) {
|
||||
localRotation = (localRotation - _rotation - _shearX) * MathUtil::Deg_Rad;
|
||||
float sinRot = MathUtil::sin(localRotation), cosRot = MathUtil::cos(localRotation);
|
||||
return MathUtil::atan2(cosRot * _c + sinRot * _d, cosRot * _a + sinRot * _b) * MathUtil::Rad_Deg;
|
||||
}
|
||||
|
||||
void BonePose::rotateWorld(float degrees) {
|
||||
degrees *= MathUtil::Deg_Rad;
|
||||
float sinRot = MathUtil::sin(degrees), cosRot = MathUtil::cos(degrees);
|
||||
float ra = _a, rb = _b;
|
||||
_a = cosRot * ra - sinRot * _c;
|
||||
_b = cosRot * rb - sinRot * _d;
|
||||
_c = sinRot * ra + cosRot * _c;
|
||||
_d = sinRot * rb + cosRot * _d;
|
||||
}
|
||||
38
spine-cpp/spine-cpp/src/spine/FromProperty.cpp
Normal file
38
spine-cpp/spine-cpp/src/spine/FromProperty.cpp
Normal file
@ -0,0 +1,38 @@
|
||||
/******************************************************************************
|
||||
* 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 <spine/FromProperty.h>
|
||||
|
||||
using namespace spine;
|
||||
|
||||
FromProperty::FromProperty() : offset(0) {
|
||||
}
|
||||
|
||||
FromProperty::~FromProperty() {
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user