mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-12 18:18:43 +08:00
[cpp] 4.3 porting WIP
This commit is contained in:
parent
da36386f4a
commit
98b9a056f3
@ -37,26 +37,37 @@
|
||||
namespace spine {
|
||||
class Skeleton;
|
||||
|
||||
/// Base class for all constraint data.
|
||||
/// Base class for all constraint data types.
|
||||
class SP_API ConstraintData : public SpineObject {
|
||||
RTTI_DECL
|
||||
public:
|
||||
ConstraintData(const String &name);
|
||||
virtual ~ConstraintData();
|
||||
const String &getName() const;
|
||||
private:
|
||||
String _name;
|
||||
};
|
||||
|
||||
/// Generic base class for all constraint data.
|
||||
template<class T, class P>
|
||||
class SP_API ConstraintData : public PosedData<P> {
|
||||
class SP_API ConstraintDataGeneric : public PosedData<P>, public ConstraintData {
|
||||
friend class SkeletonBinary;
|
||||
friend class SkeletonJson;
|
||||
|
||||
public:
|
||||
ConstraintData(const String &name);
|
||||
virtual ~ConstraintData();
|
||||
ConstraintDataGeneric(const String &name);
|
||||
virtual ~ConstraintDataGeneric();
|
||||
|
||||
/// Creates a constraint instance.
|
||||
virtual T* create(Skeleton& skeleton) = 0;
|
||||
};
|
||||
|
||||
template<class T, class P>
|
||||
ConstraintData<T, P>::ConstraintData(const String &name) : PosedData<P>(name) {
|
||||
ConstraintDataGeneric<T, P>::ConstraintDataGeneric(const String &name) : PosedData<P>(name), ConstraintData(name) {
|
||||
}
|
||||
|
||||
template<class T, class P>
|
||||
ConstraintData<T, P>::~ConstraintData() {
|
||||
ConstraintDataGeneric<T, P>::~ConstraintDataGeneric() {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -40,7 +40,7 @@ namespace spine {
|
||||
class BoneData;
|
||||
class IkConstraint;
|
||||
|
||||
class SP_API IkConstraintData : public ConstraintData<IkConstraint, IkConstraintPose> {
|
||||
class SP_API IkConstraintData : public ConstraintDataGeneric<IkConstraint, IkConstraintPose> {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
@ -73,7 +73,7 @@ namespace spine {
|
||||
/// Stores the setup pose for a PathConstraint.
|
||||
///
|
||||
/// See https://esotericsoftware.com/spine-path-constraints Path constraints in the Spine User Guide.
|
||||
class SP_API PathConstraintData : public ConstraintData<PathConstraint, PathConstraintPose> {
|
||||
class SP_API PathConstraintData : public ConstraintDataGeneric<PathConstraint, PathConstraintPose> {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
friend class SkeletonJson;
|
||||
|
||||
@ -40,7 +40,7 @@ namespace spine {
|
||||
/// Stores the setup pose for a PhysicsConstraint.
|
||||
///
|
||||
/// See https://esotericsoftware.com/spine-physics-constraints Physics constraints in the Spine User Guide.
|
||||
class SP_API PhysicsConstraintData : public ConstraintData<PhysicsConstraint, PhysicsConstraintPose> {
|
||||
class SP_API PhysicsConstraintData : public ConstraintDataGeneric<PhysicsConstraint, PhysicsConstraintPose> {
|
||||
friend class SkeletonBinary;
|
||||
friend class SkeletonJson;
|
||||
friend class PhysicsConstraint;
|
||||
|
||||
@ -52,7 +52,12 @@ namespace spine {
|
||||
|
||||
class PhysicsConstraintData;
|
||||
|
||||
class ConstraintData;
|
||||
|
||||
/// Stores the setup pose and all of the stateless data for a skeleton.
|
||||
///
|
||||
/// See <a href="https://esotericsoftware.com/spine-runtime-architecture#Data-objects">Data objects</a> in the Spine Runtimes
|
||||
/// Guide.
|
||||
class SP_API SkeletonData : public SpineObject {
|
||||
friend class SkeletonBinary;
|
||||
|
||||
@ -94,6 +99,8 @@ namespace spine {
|
||||
/// @return May be NULL.
|
||||
PhysicsConstraintData *findPhysicsConstraint(const String &constraintName);
|
||||
|
||||
/// The skeleton's name, which by default is the name of the skeleton data file when possible, or null when a name hasn't been
|
||||
/// set.
|
||||
const String &getName();
|
||||
|
||||
void setName(const String &inValue);
|
||||
@ -101,6 +108,7 @@ namespace spine {
|
||||
/// The skeleton's bones, sorted parent first. The root bone is always the first bone.
|
||||
Vector<BoneData *> &getBones();
|
||||
|
||||
/// The skeleton's slots in the setup pose draw order.
|
||||
Vector<SlotData *> &getSlots();
|
||||
|
||||
/// All skins, including the default skin.
|
||||
@ -113,8 +121,10 @@ namespace spine {
|
||||
|
||||
void setDefaultSkin(Skin *inValue);
|
||||
|
||||
/// The skeleton's events.
|
||||
Vector<spine::EventData *> &getEvents();
|
||||
|
||||
/// The skeleton's animations.
|
||||
Vector<Animation *> &getAnimations();
|
||||
|
||||
Vector<IkConstraintData *> &getIkConstraints();
|
||||
@ -125,22 +135,47 @@ namespace spine {
|
||||
|
||||
Vector<PhysicsConstraintData *> &getPhysicsConstraints();
|
||||
|
||||
/// The skeleton's constraints.
|
||||
Vector<ConstraintData *> &getConstraints();
|
||||
|
||||
/// Finds a constraint by name and type.
|
||||
/// @return May be NULL.
|
||||
template<typename T>
|
||||
T *findConstraint(const String &constraintName) {
|
||||
getConstraints(); // Ensure constraints array is populated
|
||||
for (size_t i = 0, n = _constraints.size(); i < n; i++) {
|
||||
ConstraintData *constraint = _constraints[i];
|
||||
if (constraint->getName().equals(constraintName)) {
|
||||
if (constraint->rtti.isExactly(T::rtti)) {
|
||||
return static_cast<T*>(constraint);
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/// The X coordinate of the skeleton's axis aligned bounding box in the setup pose.
|
||||
float getX();
|
||||
|
||||
void setX(float inValue);
|
||||
|
||||
/// The Y coordinate of the skeleton's axis aligned bounding box in the setup pose.
|
||||
float getY();
|
||||
|
||||
void setY(float inValue);
|
||||
|
||||
/// The width of the skeleton's axis aligned bounding box in the setup pose.
|
||||
float getWidth();
|
||||
|
||||
void setWidth(float inValue);
|
||||
|
||||
/// The height of the skeleton's axis aligned bounding box in the setup pose.
|
||||
float getHeight();
|
||||
|
||||
void setHeight(float inValue);
|
||||
|
||||
/// Baseline scale factor for applying physics and other effects based on distance to non-scalable properties, such as angle or
|
||||
/// scale. Default is 100.
|
||||
float getReferenceScale();
|
||||
|
||||
void setReferenceScale(float inValue);
|
||||
@ -150,14 +185,17 @@ namespace spine {
|
||||
|
||||
void setVersion(const String &inValue);
|
||||
|
||||
/// The skeleton data hash. This value will change if any of the skeleton data has changed.
|
||||
const String &getHash();
|
||||
|
||||
void setHash(const String &inValue);
|
||||
|
||||
/// The path to the images directory as defined in Spine, or null if nonessential data was not exported.
|
||||
const String &getImagesPath();
|
||||
|
||||
void setImagesPath(const String &inValue);
|
||||
|
||||
/// The path to the audio directory as defined in Spine, or null if nonessential data was not exported.
|
||||
const String &getAudioPath();
|
||||
|
||||
void setAudioPath(const String &inValue);
|
||||
@ -179,6 +217,7 @@ namespace spine {
|
||||
Vector<TransformConstraintData *> _transformConstraints;
|
||||
Vector<PathConstraintData *> _pathConstraints;
|
||||
Vector<PhysicsConstraintData *> _physicsConstraints;
|
||||
Vector<ConstraintData *> _constraints;
|
||||
float _x, _y, _width, _height;
|
||||
float _referenceScale;
|
||||
String _version;
|
||||
|
||||
@ -30,83 +30,45 @@
|
||||
#ifndef Spine_TransformConstraint_h
|
||||
#define Spine_TransformConstraint_h
|
||||
|
||||
#include <spine/ConstraintData.h>
|
||||
|
||||
#include <spine/Constraint.h>
|
||||
#include <spine/TransformConstraintData.h>
|
||||
#include <spine/TransformConstraintPose.h>
|
||||
#include <spine/Vector.h>
|
||||
|
||||
namespace spine {
|
||||
class TransformConstraintData;
|
||||
|
||||
class Skeleton;
|
||||
|
||||
class Bone;
|
||||
class BonePose;
|
||||
|
||||
class SP_API TransformConstraint : public Updatable {
|
||||
class SP_API TransformConstraint : public Constraint<TransformConstraint, TransformConstraintData, TransformConstraintPose> {
|
||||
friend class Skeleton;
|
||||
|
||||
friend class TransformConstraintTimeline;
|
||||
|
||||
RTTI_DECL
|
||||
|
||||
public:
|
||||
TransformConstraint(TransformConstraintData &data, Skeleton &skeleton);
|
||||
TransformConstraint(TransformConstraintData& data, Skeleton& skeleton);
|
||||
|
||||
virtual void update(Physics physics);
|
||||
TransformConstraint copy(Skeleton& skeleton);
|
||||
|
||||
virtual int getOrder();
|
||||
/// Applies the constraint to the constrained bones.
|
||||
void update(Skeleton& skeleton, Physics physics);
|
||||
|
||||
TransformConstraintData &getData();
|
||||
void sort(Skeleton& skeleton);
|
||||
|
||||
Vector<Bone *> &getBones();
|
||||
bool isSourceActive();
|
||||
|
||||
Bone *getTarget();
|
||||
/// The bones that will be modified by this transform constraint.
|
||||
Vector<BonePose*>& getBones();
|
||||
|
||||
void setTarget(Bone *inValue);
|
||||
/// The bone whose world transform will be copied to the constrained bones.
|
||||
Bone* getSource();
|
||||
|
||||
float getMixRotate();
|
||||
|
||||
void setMixRotate(float inValue);
|
||||
|
||||
float getMixX();
|
||||
|
||||
void setMixX(float inValue);
|
||||
|
||||
float getMixY();
|
||||
|
||||
void setMixY(float inValue);
|
||||
|
||||
float getMixScaleX();
|
||||
|
||||
void setMixScaleX(float inValue);
|
||||
|
||||
float getMixScaleY();
|
||||
|
||||
void setMixScaleY(float inValue);
|
||||
|
||||
float getMixShearY();
|
||||
|
||||
void setMixShearY(float inValue);
|
||||
|
||||
bool isActive();
|
||||
|
||||
void setActive(bool inValue);
|
||||
|
||||
void setToSetupPose();
|
||||
void setSource(Bone* source);
|
||||
|
||||
private:
|
||||
TransformConstraintData &_data;
|
||||
Vector<Bone *> _bones;
|
||||
Bone *_target;
|
||||
float _mixRotate, _mixX, _mixY, _mixScaleX, _mixScaleY, _mixShearY;
|
||||
bool _active;
|
||||
|
||||
void applyAbsoluteWorld();
|
||||
|
||||
void applyRelativeWorld();
|
||||
|
||||
void applyAbsoluteLocal();
|
||||
|
||||
void applyRelativeLocal();
|
||||
Vector<BonePose*> _bones;
|
||||
Bone* _source;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -43,7 +43,6 @@ namespace spine {
|
||||
/// Source property for a TransformConstraint.
|
||||
class SP_API FromProperty : public SpineObject {
|
||||
public:
|
||||
RTTI_DECL
|
||||
|
||||
/// The value of this property that corresponds to ToProperty offset.
|
||||
float offset;
|
||||
@ -61,7 +60,6 @@ namespace spine {
|
||||
/// Constrained property for a TransformConstraint.
|
||||
class SP_API ToProperty : public SpineObject {
|
||||
public:
|
||||
RTTI_DECL
|
||||
|
||||
/// The value of this property that corresponds to FromProperty offset.
|
||||
float offset;
|
||||
@ -84,78 +82,66 @@ namespace spine {
|
||||
|
||||
class SP_API FromRotate : public FromProperty {
|
||||
public:
|
||||
RTTI_DECL
|
||||
float value(BonePose& source, bool local, float* offsets) override;
|
||||
};
|
||||
|
||||
class SP_API ToRotate : public ToProperty {
|
||||
public:
|
||||
RTTI_DECL
|
||||
float mix(TransformConstraintPose& pose) override;
|
||||
void apply(TransformConstraintPose& pose, BonePose& bone, float value, bool local, bool additive) override;
|
||||
};
|
||||
|
||||
class SP_API FromX : public FromProperty {
|
||||
public:
|
||||
RTTI_DECL
|
||||
float value(BonePose& source, bool local, float* offsets) override;
|
||||
};
|
||||
|
||||
class SP_API ToX : public ToProperty {
|
||||
public:
|
||||
RTTI_DECL
|
||||
float mix(TransformConstraintPose& pose) override;
|
||||
void apply(TransformConstraintPose& pose, BonePose& bone, float value, bool local, bool additive) override;
|
||||
};
|
||||
|
||||
class SP_API FromY : public FromProperty {
|
||||
public:
|
||||
RTTI_DECL
|
||||
float value(BonePose& source, bool local, float* offsets) override;
|
||||
};
|
||||
|
||||
class SP_API ToY : public ToProperty {
|
||||
public:
|
||||
RTTI_DECL
|
||||
float mix(TransformConstraintPose& pose) override;
|
||||
void apply(TransformConstraintPose& pose, BonePose& bone, float value, bool local, bool additive) override;
|
||||
};
|
||||
|
||||
class SP_API FromScaleX : public FromProperty {
|
||||
public:
|
||||
RTTI_DECL
|
||||
float value(BonePose& source, bool local, float* offsets) override;
|
||||
};
|
||||
|
||||
class SP_API ToScaleX : public ToProperty {
|
||||
public:
|
||||
RTTI_DECL
|
||||
float mix(TransformConstraintPose& pose) override;
|
||||
void apply(TransformConstraintPose& pose, BonePose& bone, float value, bool local, bool additive) override;
|
||||
};
|
||||
|
||||
class SP_API FromScaleY : public FromProperty {
|
||||
public:
|
||||
RTTI_DECL
|
||||
float value(BonePose& source, bool local, float* offsets) override;
|
||||
};
|
||||
|
||||
class SP_API ToScaleY : public ToProperty {
|
||||
public:
|
||||
RTTI_DECL
|
||||
float mix(TransformConstraintPose& pose) override;
|
||||
void apply(TransformConstraintPose& pose, BonePose& bone, float value, bool local, bool additive) override;
|
||||
};
|
||||
|
||||
class SP_API FromShearY : public FromProperty {
|
||||
public:
|
||||
RTTI_DECL
|
||||
float value(BonePose& source, bool local, float* offsets) override;
|
||||
};
|
||||
|
||||
class SP_API ToShearY : public ToProperty {
|
||||
public:
|
||||
RTTI_DECL
|
||||
float mix(TransformConstraintPose& pose) override;
|
||||
void apply(TransformConstraintPose& pose, BonePose& bone, float value, bool local, bool additive) override;
|
||||
};
|
||||
@ -163,7 +149,7 @@ namespace spine {
|
||||
/// Stores the setup pose for a TransformConstraint.
|
||||
///
|
||||
/// See https://esotericsoftware.com/spine-transform-constraints Transform constraints in the Spine User Guide.
|
||||
class SP_API TransformConstraintData : public ConstraintData<TransformConstraint, TransformConstraintPose> {
|
||||
class SP_API TransformConstraintData : public ConstraintDataGeneric<TransformConstraint, TransformConstraintPose> {
|
||||
public:
|
||||
static const int ROTATION = 0, X = 1, Y = 2, SCALEX = 3, SCALEY = 4, SHEARY = 5;
|
||||
friend class SkeletonBinary;
|
||||
|
||||
@ -29,5 +29,16 @@
|
||||
|
||||
#include <spine/ConstraintData.h>
|
||||
|
||||
// Template class - implementation is in the header file
|
||||
using namespace spine;
|
||||
using namespace spine;
|
||||
|
||||
RTTI_IMPL_NOPARENT(ConstraintData)
|
||||
|
||||
ConstraintData::ConstraintData(const String &name) : _name(name) {
|
||||
}
|
||||
|
||||
ConstraintData::~ConstraintData() {
|
||||
}
|
||||
|
||||
const String &ConstraintData::getName() const {
|
||||
return _name;
|
||||
}
|
||||
@ -33,9 +33,9 @@
|
||||
|
||||
using namespace spine;
|
||||
|
||||
RTTI_IMPL_NOPARENT(IkConstraintData)
|
||||
RTTI_IMPL(IkConstraintData, ConstraintData)
|
||||
|
||||
IkConstraintData::IkConstraintData(const String &name) : ConstraintData<IkConstraint, IkConstraintPose>(name),
|
||||
IkConstraintData::IkConstraintData(const String &name) : ConstraintDataGeneric<IkConstraint, IkConstraintPose>(name),
|
||||
_target(NULL),
|
||||
_uniform(false) {
|
||||
}
|
||||
|
||||
@ -34,9 +34,9 @@
|
||||
|
||||
using namespace spine;
|
||||
|
||||
RTTI_IMPL_NOPARENT(PathConstraintData)
|
||||
RTTI_IMPL(PathConstraintData, ConstraintData)
|
||||
|
||||
PathConstraintData::PathConstraintData(const String &name) : ConstraintData<PathConstraint, PathConstraintPose>(name),
|
||||
PathConstraintData::PathConstraintData(const String &name) : ConstraintDataGeneric<PathConstraint, PathConstraintPose>(name),
|
||||
_slot(NULL),
|
||||
_positionMode(PositionMode_Fixed),
|
||||
_spacingMode(SpacingMode_Length),
|
||||
|
||||
@ -32,9 +32,9 @@
|
||||
|
||||
using namespace spine;
|
||||
|
||||
RTTI_IMPL_NOPARENT(PhysicsConstraintData)
|
||||
RTTI_IMPL(PhysicsConstraintData, ConstraintData)
|
||||
|
||||
PhysicsConstraintData::PhysicsConstraintData(const String &name) : ConstraintData<PhysicsConstraint, PhysicsConstraintPose>(name),
|
||||
PhysicsConstraintData::PhysicsConstraintData(const String &name) : ConstraintDataGeneric<PhysicsConstraint, PhysicsConstraintPose>(name),
|
||||
_bone(NULL),
|
||||
_x(0), _y(0), _rotate(0), _scaleX(0), _shearX(0), _limit(0), _step(0),
|
||||
_inertiaGlobal(false), _strengthGlobal(false), _dampingGlobal(false), _massGlobal(false),
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
|
||||
#include <spine/Animation.h>
|
||||
#include <spine/BoneData.h>
|
||||
#include <spine/ConstraintData.h>
|
||||
#include <spine/EventData.h>
|
||||
#include <spine/IkConstraintData.h>
|
||||
#include <spine/PathConstraintData.h>
|
||||
@ -52,8 +53,9 @@ SkeletonData::SkeletonData() : _name(),
|
||||
_referenceScale(100),
|
||||
_version(),
|
||||
_hash(),
|
||||
_fps(0),
|
||||
_imagesPath() {
|
||||
_fps(30),
|
||||
_imagesPath(),
|
||||
_audioPath() {
|
||||
}
|
||||
|
||||
SkeletonData::~SkeletonData() {
|
||||
@ -69,6 +71,8 @@ SkeletonData::~SkeletonData() {
|
||||
ContainerUtil::cleanUpVectorOfPointers(_transformConstraints);
|
||||
ContainerUtil::cleanUpVectorOfPointers(_pathConstraints);
|
||||
ContainerUtil::cleanUpVectorOfPointers(_physicsConstraints);
|
||||
// Note: _constraints contains pointers to objects already cleaned up above, so just clear
|
||||
_constraints.clear();
|
||||
for (size_t i = 0; i < _strings.size(); i++) {
|
||||
SpineExtension::free(_strings[i], __FILE__, __LINE__);
|
||||
}
|
||||
@ -242,3 +246,21 @@ float SkeletonData::getFps() {
|
||||
void SkeletonData::setFps(float inValue) {
|
||||
_fps = inValue;
|
||||
}
|
||||
|
||||
Vector<ConstraintData *> &SkeletonData::getConstraints() {
|
||||
// Build unified constraints array by aggregating all constraint types
|
||||
_constraints.clear();
|
||||
for (size_t i = 0, n = _ikConstraints.size(); i < n; i++) {
|
||||
_constraints.add(static_cast<ConstraintData*>(_ikConstraints[i]));
|
||||
}
|
||||
for (size_t i = 0, n = _transformConstraints.size(); i < n; i++) {
|
||||
_constraints.add(static_cast<ConstraintData*>(_transformConstraints[i]));
|
||||
}
|
||||
for (size_t i = 0, n = _pathConstraints.size(); i < n; i++) {
|
||||
_constraints.add(static_cast<ConstraintData*>(_pathConstraints[i]));
|
||||
}
|
||||
for (size_t i = 0, n = _physicsConstraints.size(); i < n; i++) {
|
||||
_constraints.add(static_cast<ConstraintData*>(_physicsConstraints[i]));
|
||||
}
|
||||
return _constraints;
|
||||
}
|
||||
|
||||
@ -30,321 +30,116 @@
|
||||
#include <spine/TransformConstraint.h>
|
||||
|
||||
#include <spine/Bone.h>
|
||||
#include <spine/BonePose.h>
|
||||
#include <spine/Skeleton.h>
|
||||
#include <spine/TransformConstraintData.h>
|
||||
#include <spine/MathUtil.h>
|
||||
|
||||
#include <spine/BoneData.h>
|
||||
|
||||
using namespace spine;
|
||||
|
||||
RTTI_IMPL(TransformConstraint, Updatable)
|
||||
RTTI_IMPL_NOPARENT(TransformConstraint)
|
||||
|
||||
TransformConstraint::TransformConstraint(TransformConstraintData &data, Skeleton &skeleton) : Updatable(),
|
||||
_data(data),
|
||||
_target(skeleton.findBone(
|
||||
data.getTarget()->getName())),
|
||||
_mixRotate(
|
||||
data.getMixRotate()),
|
||||
_mixX(data.getMixX()),
|
||||
_mixY(data.getMixY()),
|
||||
_mixScaleX(
|
||||
data.getMixScaleX()),
|
||||
_mixScaleY(
|
||||
data.getMixScaleY()),
|
||||
_mixShearY(
|
||||
data.getMixShearY()),
|
||||
_active(false) {
|
||||
_bones.ensureCapacity(_data.getBones().size());
|
||||
for (size_t i = 0; i < _data.getBones().size(); ++i) {
|
||||
BoneData *boneData = _data.getBones()[i];
|
||||
_bones.add(skeleton.findBone(boneData->getName()));
|
||||
TransformConstraint::TransformConstraint(TransformConstraintData& data, Skeleton& skeleton) :
|
||||
Constraint<TransformConstraint, TransformConstraintData, TransformConstraintPose>(data) {
|
||||
if (&skeleton == NULL) throw;
|
||||
|
||||
_bones.ensureCapacity(data.getBones().size());
|
||||
for (size_t i = 0; i < data.getBones().size(); i++) {
|
||||
BoneData* boneData = data.getBones()[i];
|
||||
_bones.add(&skeleton.findBone(boneData->getName())->getAppliedPose());
|
||||
}
|
||||
|
||||
_source = skeleton.findBone(data.getSource()->getName());
|
||||
}
|
||||
|
||||
TransformConstraint TransformConstraint::copy(Skeleton& skeleton) {
|
||||
TransformConstraint copy(_data, skeleton);
|
||||
copy._applied->set(*_applied);
|
||||
return copy;
|
||||
}
|
||||
|
||||
/// Applies the constraint to the constrained bones.
|
||||
void TransformConstraint::update(Skeleton& skeleton, Physics physics) {
|
||||
TransformConstraintPose& p = *_applied;
|
||||
if (p.getMixRotate() == 0 && p.getMixX() == 0 && p.getMixY() == 0 && p.getMixScaleX() == 0 && p.getMixScaleY() == 0 && p.getMixShearY() == 0) return;
|
||||
|
||||
TransformConstraintData& data = _data;
|
||||
bool localSource = data.getLocalSource(), localTarget = data.getLocalTarget(), additive = data.getAdditive(), clamp = data.getClamp();
|
||||
float* offsets = data._offsets; // Access friend field directly
|
||||
BonePose& source = _source->getAppliedPose();
|
||||
if (localSource) {
|
||||
source.validateLocalTransform(skeleton);
|
||||
}
|
||||
Vector<FromProperty*>& properties = data.getProperties();
|
||||
FromProperty** fromItems = properties.buffer();
|
||||
size_t fn = properties.size();
|
||||
int update = 1; // TODO: Add skeleton.update field
|
||||
BonePose** bones = _bones.buffer();
|
||||
for (size_t i = 0, n = _bones.size(); i < n; i++) {
|
||||
BonePose* bone = bones[i];
|
||||
if (localTarget) {
|
||||
bone->modifyLocal(skeleton);
|
||||
} else {
|
||||
bone->modifyWorld(update);
|
||||
}
|
||||
for (size_t f = 0; f < fn; f++) {
|
||||
FromProperty* from = fromItems[f];
|
||||
float value = from->value(source, localSource, offsets) - from->offset;
|
||||
Vector<ToProperty*>& toProps = from->to;
|
||||
ToProperty** toItems = toProps.buffer();
|
||||
for (size_t t = 0, tn = toProps.size(); t < tn; t++) {
|
||||
ToProperty* to = toItems[t];
|
||||
if (to->mix(p) != 0) {
|
||||
float clamped = to->offset + value * to->scale;
|
||||
if (clamp) {
|
||||
if (to->offset < to->max)
|
||||
clamped = MathUtil::clamp(clamped, to->offset, to->max);
|
||||
else
|
||||
clamped = MathUtil::clamp(clamped, to->max, to->offset);
|
||||
}
|
||||
to->apply(p, *bone, clamped, localTarget, additive);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void TransformConstraint::update(Physics) {
|
||||
if (_mixRotate == 0 && _mixX == 0 && _mixY == 0 && _mixScaleX == 0 && _mixScaleY == 0 && _mixShearY == 0) return;
|
||||
|
||||
if (_data.isLocal()) {
|
||||
if (_data.isRelative())
|
||||
applyRelativeLocal();
|
||||
else
|
||||
applyAbsoluteLocal();
|
||||
} else {
|
||||
if (_data.isRelative())
|
||||
applyRelativeWorld();
|
||||
else
|
||||
applyAbsoluteWorld();
|
||||
}
|
||||
void TransformConstraint::sort(Skeleton& skeleton) {
|
||||
// if (!_data.getLocalSource()) skeleton.sortBone(_source); // TODO: sortBone is private, need friend access
|
||||
BonePose** bones = _bones.buffer();
|
||||
size_t boneCount = _bones.size();
|
||||
bool worldTarget = !_data.getLocalTarget();
|
||||
// if (worldTarget) {
|
||||
// for (size_t i = 0; i < boneCount; i++)
|
||||
// skeleton.sortBone(bones[i]->_bone); // TODO: sortBone is private, need friend access
|
||||
// }
|
||||
// skeleton._updateCache.add(this); // TODO: _updateCache is private, need friend access
|
||||
// for (size_t i = 0; i < boneCount; i++) {
|
||||
// Bone* bone = bones[i]->_bone;
|
||||
// skeleton.sortReset(bone->getChildren()); // TODO: sortReset is private, need friend access
|
||||
// // skeleton.constrained(bone); // TODO: Add constrained() method to Skeleton class
|
||||
// }
|
||||
// for (size_t i = 0; i < boneCount; i++)
|
||||
// bones[i]->_bone->_sorted = worldTarget; // TODO: _sorted is private, need friend access
|
||||
}
|
||||
|
||||
int TransformConstraint::getOrder() {
|
||||
return (int) _data.getOrder();
|
||||
bool TransformConstraint::isSourceActive() {
|
||||
return _source->isActive();
|
||||
}
|
||||
|
||||
TransformConstraintData &TransformConstraint::getData() {
|
||||
return _data;
|
||||
}
|
||||
|
||||
Vector<Bone *> &TransformConstraint::getBones() {
|
||||
/// The bones that will be modified by this transform constraint.
|
||||
Vector<BonePose*>& TransformConstraint::getBones() {
|
||||
return _bones;
|
||||
}
|
||||
|
||||
Bone *TransformConstraint::getTarget() {
|
||||
return _target;
|
||||
/// The bone whose world transform will be copied to the constrained bones.
|
||||
Bone* TransformConstraint::getSource() {
|
||||
return _source;
|
||||
}
|
||||
|
||||
void TransformConstraint::setTarget(Bone *inValue) {
|
||||
_target = inValue;
|
||||
}
|
||||
|
||||
float TransformConstraint::getMixRotate() {
|
||||
return _mixRotate;
|
||||
}
|
||||
|
||||
void TransformConstraint::setMixRotate(float inValue) {
|
||||
_mixRotate = inValue;
|
||||
}
|
||||
|
||||
float TransformConstraint::getMixX() {
|
||||
return _mixX;
|
||||
}
|
||||
|
||||
void TransformConstraint::setMixX(float inValue) {
|
||||
_mixX = inValue;
|
||||
}
|
||||
|
||||
float TransformConstraint::getMixY() {
|
||||
return _mixY;
|
||||
}
|
||||
|
||||
void TransformConstraint::setMixY(float inValue) {
|
||||
_mixY = inValue;
|
||||
}
|
||||
|
||||
void TransformConstraint::setMixScaleX(float inValue) {
|
||||
_mixScaleX = inValue;
|
||||
}
|
||||
|
||||
float TransformConstraint::getMixScaleX() {
|
||||
return _mixScaleX;
|
||||
}
|
||||
|
||||
float TransformConstraint::getMixScaleY() {
|
||||
return _mixScaleY;
|
||||
}
|
||||
|
||||
void TransformConstraint::setMixScaleY(float inValue) {
|
||||
_mixScaleY = inValue;
|
||||
}
|
||||
|
||||
float TransformConstraint::getMixShearY() {
|
||||
return _mixShearY;
|
||||
}
|
||||
|
||||
void TransformConstraint::setMixShearY(float inValue) {
|
||||
_mixShearY = inValue;
|
||||
}
|
||||
|
||||
void TransformConstraint::applyAbsoluteWorld() {
|
||||
float mixRotate = _mixRotate, mixX = _mixX, mixY = _mixY, mixScaleX = _mixScaleX, mixScaleY = _mixScaleY, mixShearY = _mixShearY;
|
||||
bool translate = mixX != 0 || mixY != 0;
|
||||
Bone &target = *_target;
|
||||
float ta = target._a, tb = target._b, tc = target._c, td = target._d;
|
||||
float degRadReflect = ta * td - tb * tc > 0 ? MathUtil::Deg_Rad : -MathUtil::Deg_Rad;
|
||||
float offsetRotation = _data._offsetRotation * degRadReflect, offsetShearY = _data._offsetShearY * degRadReflect;
|
||||
|
||||
for (size_t i = 0; i < _bones.size(); ++i) {
|
||||
Bone *item = _bones[i];
|
||||
Bone &bone = *item;
|
||||
|
||||
if (mixRotate != 0) {
|
||||
float a = bone._a, b = bone._b, c = bone._c, d = bone._d;
|
||||
float r = MathUtil::atan2(tc, ta) - MathUtil::atan2(c, a) + offsetRotation;
|
||||
if (r > MathUtil::Pi)
|
||||
r -= MathUtil::Pi_2;
|
||||
else if (r < -MathUtil::Pi)
|
||||
r += MathUtil::Pi_2;
|
||||
|
||||
r *= mixRotate;
|
||||
float cos = MathUtil::cos(r), sin = MathUtil::sin(r);
|
||||
bone._a = cos * a - sin * c;
|
||||
bone._b = cos * b - sin * d;
|
||||
bone._c = sin * a + cos * c;
|
||||
bone._d = sin * b + cos * d;
|
||||
}
|
||||
|
||||
if (translate) {
|
||||
float tx, ty;
|
||||
target.localToWorld(_data._offsetX, _data._offsetY, tx, ty);
|
||||
bone._worldX += (tx - bone._worldX) * mixX;
|
||||
bone._worldY += (ty - bone._worldY) * mixY;
|
||||
}
|
||||
|
||||
if (mixScaleX > 0) {
|
||||
float s = MathUtil::sqrt(bone._a * bone._a + bone._c * bone._c);
|
||||
if (s != 0) s = (s + (MathUtil::sqrt(ta * ta + tc * tc) - s + _data._offsetScaleX) * mixScaleX) / s;
|
||||
bone._a *= s;
|
||||
bone._c *= s;
|
||||
}
|
||||
|
||||
if (mixScaleY > 0) {
|
||||
float s = MathUtil::sqrt(bone._b * bone._b + bone._d * bone._d);
|
||||
if (s != 0) s = (s + (MathUtil::sqrt(tb * tb + td * td) - s + _data._offsetScaleY) * mixScaleY) / s;
|
||||
bone._b *= s;
|
||||
bone._d *= s;
|
||||
}
|
||||
|
||||
if (mixShearY > 0) {
|
||||
float b = bone._b, d = bone._d;
|
||||
float by = MathUtil::atan2(d, b);
|
||||
float r = MathUtil::atan2(td, tb) - MathUtil::atan2(tc, ta) - (by - MathUtil::atan2(bone._c, bone._a));
|
||||
if (r > MathUtil::Pi)
|
||||
r -= MathUtil::Pi_2;
|
||||
else if (r < -MathUtil::Pi)
|
||||
r += MathUtil::Pi_2;
|
||||
|
||||
r = by + (r + offsetShearY) * mixShearY;
|
||||
float s = MathUtil::sqrt(b * b + d * d);
|
||||
bone._b = MathUtil::cos(r) * s;
|
||||
bone._d = MathUtil::sin(r) * s;
|
||||
}
|
||||
|
||||
bone.updateAppliedTransform();
|
||||
}
|
||||
}
|
||||
|
||||
void TransformConstraint::applyRelativeWorld() {
|
||||
float mixRotate = _mixRotate, mixX = _mixX, mixY = _mixY, mixScaleX = _mixScaleX, mixScaleY = _mixScaleY, mixShearY = _mixShearY;
|
||||
bool translate = mixX != 0 || mixY != 0;
|
||||
Bone &target = *_target;
|
||||
float ta = target._a, tb = target._b, tc = target._c, td = target._d;
|
||||
float degRadReflect = ta * td - tb * tc > 0 ? MathUtil::Deg_Rad : -MathUtil::Deg_Rad;
|
||||
float offsetRotation = _data._offsetRotation * degRadReflect, offsetShearY = _data._offsetShearY * degRadReflect;
|
||||
for (size_t i = 0; i < _bones.size(); ++i) {
|
||||
Bone *item = _bones[i];
|
||||
Bone &bone = *item;
|
||||
|
||||
if (mixRotate != 0) {
|
||||
float a = bone._a, b = bone._b, c = bone._c, d = bone._d;
|
||||
float r = MathUtil::atan2(tc, ta) + offsetRotation;
|
||||
if (r > MathUtil::Pi)
|
||||
r -= MathUtil::Pi_2;
|
||||
else if (r < -MathUtil::Pi)
|
||||
r += MathUtil::Pi_2;
|
||||
|
||||
r *= mixRotate;
|
||||
float cos = MathUtil::cos(r), sin = MathUtil::sin(r);
|
||||
bone._a = cos * a - sin * c;
|
||||
bone._b = cos * b - sin * d;
|
||||
bone._c = sin * a + cos * c;
|
||||
bone._d = sin * b + cos * d;
|
||||
}
|
||||
|
||||
if (translate) {
|
||||
float tx, ty;
|
||||
target.localToWorld(_data._offsetX, _data._offsetY, tx, ty);
|
||||
bone._worldX += tx * mixX;
|
||||
bone._worldY += ty * mixY;
|
||||
}
|
||||
|
||||
if (mixScaleX != 0) {
|
||||
float s = (MathUtil::sqrt(ta * ta + tc * tc) - 1 + _data._offsetScaleX) * mixScaleX + 1;
|
||||
bone._a *= s;
|
||||
bone._c *= s;
|
||||
}
|
||||
if (mixScaleY != 0) {
|
||||
float s = (MathUtil::sqrt(tb * tb + td * td) - 1 + _data._offsetScaleY) * mixScaleY + 1;
|
||||
bone._b *= s;
|
||||
bone._d *= s;
|
||||
}
|
||||
|
||||
if (mixShearY > 0) {
|
||||
float r = MathUtil::atan2(td, tb) - MathUtil::atan2(tc, ta);
|
||||
if (r > MathUtil::Pi)
|
||||
r -= MathUtil::Pi_2;
|
||||
else if (r < -MathUtil::Pi)
|
||||
r += MathUtil::Pi_2;
|
||||
|
||||
float b = bone._b, d = bone._d;
|
||||
r = MathUtil::atan2(d, b) + (r - MathUtil::Pi / 2 + offsetShearY) * mixShearY;
|
||||
float s = MathUtil::sqrt(b * b + d * d);
|
||||
bone._b = MathUtil::cos(r) * s;
|
||||
bone._d = MathUtil::sin(r) * s;
|
||||
}
|
||||
|
||||
bone.updateAppliedTransform();
|
||||
}
|
||||
}
|
||||
|
||||
void TransformConstraint::applyAbsoluteLocal() {
|
||||
float mixRotate = _mixRotate, mixX = _mixX, mixY = _mixY, mixScaleX = _mixScaleX, mixScaleY = _mixScaleY, mixShearY = _mixShearY;
|
||||
Bone &target = *_target;
|
||||
|
||||
for (size_t i = 0; i < _bones.size(); ++i) {
|
||||
Bone *item = _bones[i];
|
||||
Bone &bone = *item;
|
||||
|
||||
float rotation = bone._arotation;
|
||||
if (mixRotate != 0) {
|
||||
float r = target._arotation - rotation + _data._offsetRotation;
|
||||
r -= MathUtil::ceil(r / 360 - 0.5) * 360;
|
||||
rotation += r * mixRotate;
|
||||
}
|
||||
|
||||
float x = bone._ax, y = bone._ay;
|
||||
x += (target._ax - x + _data._offsetX) * mixX;
|
||||
y += (target._ay - y + _data._offsetY) * mixY;
|
||||
|
||||
float scaleX = bone._ascaleX, scaleY = bone._ascaleY;
|
||||
if (mixScaleX != 0 && scaleX != 0)
|
||||
scaleX = (scaleX + (target._ascaleX - scaleX + _data._offsetScaleX) * mixScaleX) / scaleX;
|
||||
if (mixScaleY != 0 && scaleY != 0)
|
||||
scaleY = (scaleY + (target._ascaleY - scaleY + _data._offsetScaleY) * mixScaleY) / scaleY;
|
||||
|
||||
float shearY = bone._ashearY;
|
||||
if (mixShearY != 0) {
|
||||
float r = target._ashearY - shearY + _data._offsetShearY;
|
||||
r -= MathUtil::ceil(r / 360 - 0.5) * 360;
|
||||
bone._shearY += r * mixShearY;
|
||||
}
|
||||
|
||||
bone.updateWorldTransform(x, y, rotation, scaleX, scaleY, bone._ashearX, shearY);
|
||||
}
|
||||
}
|
||||
|
||||
void TransformConstraint::applyRelativeLocal() {
|
||||
float mixRotate = _mixRotate, mixX = _mixX, mixY = _mixY, mixScaleX = _mixScaleX, mixScaleY = _mixScaleY, mixShearY = _mixShearY;
|
||||
Bone &target = *_target;
|
||||
|
||||
for (size_t i = 0; i < _bones.size(); ++i) {
|
||||
Bone *item = _bones[i];
|
||||
Bone &bone = *item;
|
||||
|
||||
float rotation = bone._arotation + (target._arotation + _data._offsetRotation) * mixRotate;
|
||||
float x = bone._ax + (target._ax + _data._offsetX) * mixX;
|
||||
float y = bone._ay + (target._ay + _data._offsetY) * mixY;
|
||||
float scaleX = bone._ascaleX * (((target._ascaleX - 1 + _data._offsetScaleX) * mixScaleX) + 1);
|
||||
float scaleY = bone._ascaleY * (((target._ascaleY - 1 + _data._offsetScaleY) * mixScaleY) + 1);
|
||||
float shearY = bone._ashearY + (target._ashearY + _data._offsetShearY) * mixShearY;
|
||||
|
||||
bone.updateWorldTransform(x, y, rotation, scaleX, scaleY, bone._ashearX, shearY);
|
||||
}
|
||||
}
|
||||
|
||||
bool TransformConstraint::isActive() {
|
||||
return _active;
|
||||
}
|
||||
|
||||
void TransformConstraint::setActive(bool inValue) {
|
||||
_active = inValue;
|
||||
}
|
||||
|
||||
void TransformConstraint::setToSetupPose() {
|
||||
TransformConstraintData &data = this->_data;
|
||||
this->_mixRotate = data._mixRotate;
|
||||
this->_mixX = data._mixX;
|
||||
this->_mixY = data._mixY;
|
||||
this->_mixScaleX = data._mixScaleX;
|
||||
this->_mixScaleY = data._mixScaleY;
|
||||
this->_mixShearY = data._mixShearY;
|
||||
}
|
||||
void TransformConstraint::setSource(Bone* source) {
|
||||
if (source == NULL) throw;
|
||||
_source = source;
|
||||
}
|
||||
@ -36,9 +36,9 @@
|
||||
|
||||
using namespace spine;
|
||||
|
||||
RTTI_IMPL_NOPARENT(TransformConstraintData)
|
||||
RTTI_IMPL(TransformConstraintData, ConstraintData)
|
||||
|
||||
TransformConstraintData::TransformConstraintData(const String &name) : ConstraintData<TransformConstraint, TransformConstraintPose>(name),
|
||||
TransformConstraintData::TransformConstraintData(const String &name) : ConstraintDataGeneric<TransformConstraint, TransformConstraintPose>(name),
|
||||
_source(NULL),
|
||||
_localSource(false),
|
||||
_localTarget(false),
|
||||
@ -149,7 +149,7 @@ Vector<FromProperty*>& TransformConstraintData::getProperties() {
|
||||
// Property Classes
|
||||
// ============================================================================
|
||||
|
||||
RTTI_IMPL_NOPARENT(FromProperty)
|
||||
// No RTTI for FromProperty
|
||||
|
||||
FromProperty::FromProperty() : SpineObject(), offset(0) {
|
||||
}
|
||||
@ -157,7 +157,7 @@ FromProperty::FromProperty() : SpineObject(), offset(0) {
|
||||
FromProperty::~FromProperty() {
|
||||
}
|
||||
|
||||
RTTI_IMPL_NOPARENT(ToProperty)
|
||||
// No RTTI for ToProperty
|
||||
|
||||
ToProperty::ToProperty() : offset(0), max(0), scale(1) {
|
||||
}
|
||||
@ -165,17 +165,17 @@ ToProperty::ToProperty() : offset(0), max(0), scale(1) {
|
||||
ToProperty::~ToProperty() {
|
||||
}
|
||||
|
||||
RTTI_IMPL(FromRotate, FromProperty)
|
||||
// No RTTI for FromRotate
|
||||
|
||||
float FromRotate::value(BonePose& source, bool local, float* offsets) {
|
||||
if (local) return source.getRotation() + offsets[ROTATION];
|
||||
if (local) return source.getRotation() + offsets[TransformConstraintData::ROTATION];
|
||||
float value = MathUtil::atan2(source._c, source._a) * MathUtil::Rad_Deg
|
||||
+ (source._a * source._d - source._b * source._c > 0 ? offsets[ROTATION] : -offsets[ROTATION]);
|
||||
+ (source._a * source._d - source._b * source._c > 0 ? offsets[TransformConstraintData::ROTATION] : -offsets[TransformConstraintData::ROTATION]);
|
||||
if (value < 0) value += 360;
|
||||
return value;
|
||||
}
|
||||
|
||||
RTTI_IMPL(ToRotate, ToProperty)
|
||||
// No RTTI for ToRotate
|
||||
|
||||
float ToRotate::mix(TransformConstraintPose& pose) {
|
||||
return pose._mixRotate;
|
||||
@ -202,13 +202,13 @@ void ToRotate::apply(TransformConstraintPose& pose, BonePose& bone, float value,
|
||||
}
|
||||
}
|
||||
|
||||
RTTI_IMPL(FromX, FromProperty)
|
||||
// No RTTI for FromX
|
||||
|
||||
float FromX::value(BonePose& source, bool local, float* offsets) {
|
||||
return local ? source.getX() + offsets[X] : offsets[X] * source._a + offsets[Y] * source._b + source.getWorldX();
|
||||
return local ? source.getX() + offsets[TransformConstraintData::X] : offsets[TransformConstraintData::X] * source._a + offsets[TransformConstraintData::Y] * source._b + source.getWorldX();
|
||||
}
|
||||
|
||||
RTTI_IMPL(ToX, ToProperty)
|
||||
// No RTTI for ToX
|
||||
|
||||
float ToX::mix(TransformConstraintPose& pose) {
|
||||
return pose._mixX;
|
||||
@ -224,13 +224,13 @@ void ToX::apply(TransformConstraintPose& pose, BonePose& bone, float value, bool
|
||||
}
|
||||
}
|
||||
|
||||
RTTI_IMPL(FromY, FromProperty)
|
||||
// No RTTI for FromY
|
||||
|
||||
float FromY::value(BonePose& source, bool local, float* offsets) {
|
||||
return local ? source.getY() + offsets[Y] : offsets[X] * source._c + offsets[Y] * source._d + source.getWorldY();
|
||||
return local ? source.getY() + offsets[TransformConstraintData::Y] : offsets[TransformConstraintData::X] * source._c + offsets[TransformConstraintData::Y] * source._d + source.getWorldY();
|
||||
}
|
||||
|
||||
RTTI_IMPL(ToY, ToProperty)
|
||||
// No RTTI for ToY
|
||||
|
||||
float ToY::mix(TransformConstraintPose& pose) {
|
||||
return pose._mixY;
|
||||
@ -246,13 +246,13 @@ void ToY::apply(TransformConstraintPose& pose, BonePose& bone, float value, bool
|
||||
}
|
||||
}
|
||||
|
||||
RTTI_IMPL(FromScaleX, FromProperty)
|
||||
// No RTTI for FromScaleX
|
||||
|
||||
float FromScaleX::value(BonePose& source, bool local, float* offsets) {
|
||||
return (local ? source.getScaleX() : MathUtil::sqrt(source._a * source._a + source._c * source._c)) + offsets[SCALEX];
|
||||
return (local ? source.getScaleX() : MathUtil::sqrt(source._a * source._a + source._c * source._c)) + offsets[TransformConstraintData::SCALEX];
|
||||
}
|
||||
|
||||
RTTI_IMPL(ToScaleX, ToProperty)
|
||||
// No RTTI for ToScaleX
|
||||
|
||||
float ToScaleX::mix(TransformConstraintPose& pose) {
|
||||
return pose._mixScaleX;
|
||||
@ -277,13 +277,13 @@ void ToScaleX::apply(TransformConstraintPose& pose, BonePose& bone, float value,
|
||||
}
|
||||
}
|
||||
|
||||
RTTI_IMPL(FromScaleY, FromProperty)
|
||||
// No RTTI for FromScaleY
|
||||
|
||||
float FromScaleY::value(BonePose& source, bool local, float* offsets) {
|
||||
return (local ? source.getScaleY() : MathUtil::sqrt(source._b * source._b + source._d * source._d)) + offsets[SCALEY];
|
||||
return (local ? source.getScaleY() : MathUtil::sqrt(source._b * source._b + source._d * source._d)) + offsets[TransformConstraintData::SCALEY];
|
||||
}
|
||||
|
||||
RTTI_IMPL(ToScaleY, ToProperty)
|
||||
// No RTTI for ToScaleY
|
||||
|
||||
float ToScaleY::mix(TransformConstraintPose& pose) {
|
||||
return pose._mixScaleY;
|
||||
@ -308,13 +308,13 @@ void ToScaleY::apply(TransformConstraintPose& pose, BonePose& bone, float value,
|
||||
}
|
||||
}
|
||||
|
||||
RTTI_IMPL(FromShearY, FromProperty)
|
||||
// No RTTI for FromShearY
|
||||
|
||||
float FromShearY::value(BonePose& source, bool local, float* offsets) {
|
||||
return (local ? source.getShearY() : (MathUtil::atan2(source._d, source._b) - MathUtil::atan2(source._c, source._a)) * MathUtil::Rad_Deg - 90) + offsets[SHEARY];
|
||||
return (local ? source.getShearY() : (MathUtil::atan2(source._d, source._b) - MathUtil::atan2(source._c, source._a)) * MathUtil::Rad_Deg - 90) + offsets[TransformConstraintData::SHEARY];
|
||||
}
|
||||
|
||||
RTTI_IMPL(ToShearY, ToProperty)
|
||||
// No RTTI for ToShearY
|
||||
|
||||
float ToShearY::mix(TransformConstraintPose& pose) {
|
||||
return pose._mixShearY;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user