mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-04 22:34:53 +08:00
Timelines are done.
This commit is contained in:
parent
8b53400425
commit
3038a90cc5
@ -57,6 +57,9 @@ namespace Spine
|
||||
friend class Skeleton;
|
||||
friend class RegionAttachment;
|
||||
friend class PointAttachment;
|
||||
friend class ScaleTimeline;
|
||||
friend class ShearTimeline;
|
||||
friend class TranslateTimeline;
|
||||
|
||||
public:
|
||||
static void setYDown(bool inValue);
|
||||
|
||||
@ -40,6 +40,9 @@ namespace Spine
|
||||
class BoneData
|
||||
{
|
||||
friend class RotateTimeline;
|
||||
friend class ScaleTimeline;
|
||||
friend class ShearTimeline;
|
||||
friend class TranslateTimeline;
|
||||
|
||||
public:
|
||||
BoneData(int index, std::string name, BoneData* parent = NULL);
|
||||
|
||||
@ -39,56 +39,25 @@ namespace Spine
|
||||
{
|
||||
RTTI_DECL;
|
||||
|
||||
public:
|
||||
EventTimeline(int frameCount);
|
||||
|
||||
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>& events, float alpha, MixPose pose, MixDirection direction);
|
||||
|
||||
virtual int getPropertyId();
|
||||
|
||||
// internal float[] frames;
|
||||
// private Event[] events;
|
||||
//
|
||||
// public float[] Frames { return frames; } set { frames = inValue; } // time, ...
|
||||
// public Event[] Events { return events; } set { events = inValue; }
|
||||
// public int FrameCount { return frames.Length; }
|
||||
//
|
||||
//
|
||||
// public EventTimeline (int frameCount) {
|
||||
// frames = new float[frameCount];
|
||||
// events = new Event[frameCount];
|
||||
// }
|
||||
//
|
||||
// /// Sets the time and value of the specified keyframe.
|
||||
// public void setFrame (int frameIndex, Event e) {
|
||||
// frames[frameIndex] = e.Time;
|
||||
// events[frameIndex] = e;
|
||||
// }
|
||||
//
|
||||
// /// Fires events for frames > lastTime and <= time.
|
||||
// public void Apply (Skeleton skeleton, float lastTime, float time, Vector<Event> firedEvents, float alpha, MixPose pose, MixDirection direction) {
|
||||
// if (firedEvents == NULL) return;
|
||||
// float[] frames = _frames;
|
||||
// int frameCount = frames.Length;
|
||||
//
|
||||
// if (lastTime > time) { // Fire events after last time for looped animations.
|
||||
// Apply(skeleton, lastTime, int.MaxValue, firedEvents, alpha, pose, direction);
|
||||
// lastTime = -1f;
|
||||
// } else if (lastTime >= frames[frameCount - 1]) // Last time is after last frame.
|
||||
// return;
|
||||
// if (time < frames[0]) return; // Time is before first frame.
|
||||
//
|
||||
// int frame;
|
||||
// if (lastTime < frames[0])
|
||||
// frame = 0;
|
||||
// else {
|
||||
// frame = Animation::binarySearch(frames, lastTime);
|
||||
// float frameTime = frames[frame];
|
||||
// while (frame > 0) { // Fire multiple events with the same frame.
|
||||
// if (frames[frame - 1] != frameTime) break;
|
||||
// frame--;
|
||||
// }
|
||||
// }
|
||||
// for (; frame < frameCount && time >= frames[frame]; frame++)
|
||||
// firedEvents.push_back(events[frame]);
|
||||
// }
|
||||
/// Sets the time and value of the specified keyframe.
|
||||
void setFrame(int frameIndex, Event* e);
|
||||
|
||||
Vector<float> getFrames();
|
||||
void setFrames(Vector<float>& inValue);
|
||||
Vector<Event*>& getEvents();
|
||||
void setEvents(Vector<Event*>& inValue);
|
||||
int getFrameCount();
|
||||
|
||||
private:
|
||||
Vector<float> _frames;
|
||||
Vector<Event*> _events;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -44,6 +44,7 @@ namespace Spine
|
||||
class IkConstraint : public Constraint
|
||||
{
|
||||
friend class Skeleton;
|
||||
friend class IkConstraintTimeline;
|
||||
|
||||
RTTI_DECL;
|
||||
|
||||
|
||||
@ -43,6 +43,7 @@ namespace Spine
|
||||
{
|
||||
friend class IkConstraint;
|
||||
friend class Skeleton;
|
||||
friend class IkConstraintTimeline;
|
||||
|
||||
public:
|
||||
IkConstraintData(std::string name);
|
||||
|
||||
@ -48,69 +48,15 @@ namespace Spine
|
||||
|
||||
virtual int getPropertyId();
|
||||
|
||||
/// Sets the time, mix and bend direction of the specified keyframe.
|
||||
void setFrame (int frameIndex, float time, float mix, int bendDirection);
|
||||
|
||||
private:
|
||||
static const int PREV_TIME, PREV_MIX, PREV_BEND_DIRECTION;
|
||||
static const int MIX, BEND_DIRECTION;
|
||||
|
||||
Vector<float> _frames;
|
||||
int _ikConstraintIndex;
|
||||
|
||||
// public int IkConstraintIndex { return ikConstraintIndex; } set { ikConstraintIndex = inValue; }
|
||||
// public float[] Frames { return frames; } set { frames = inValue; } // time, mix, bendDirection, ...
|
||||
//
|
||||
//
|
||||
//
|
||||
// /// Sets the time, mix and bend direction of the specified keyframe.
|
||||
// public void setFrame (int frameIndex, float time, float mix, int bendDirection) {
|
||||
// frameIndex *= ENTRIES;
|
||||
// frames[frameIndex] = time;
|
||||
// frames[frameIndex + MIX] = mix;
|
||||
// frames[frameIndex + BEND_DIRECTION] = bendDirection;
|
||||
// }
|
||||
//
|
||||
// override public void Apply (Skeleton skeleton, float lastTime, float time, Vector<Event> firedEvents, float alpha, MixPose pose, MixDirection direction) {
|
||||
// IkConstraint constraint = skeleton.ikConstraints.Items[ikConstraintIndex];
|
||||
// float[] frames = _frames;
|
||||
// if (time < frames[0]) {
|
||||
// switch (pose) {
|
||||
// case MixPose_Setup:
|
||||
// constraint.mix = constraint.data.mix;
|
||||
// constraint.bendDirection = constraint.data.bendDirection;
|
||||
// return;
|
||||
// case MixPose_Current:
|
||||
// constraint.mix += (constraint.data.mix - constraint.mix) * alpha;
|
||||
// constraint.bendDirection = constraint.data.bendDirection;
|
||||
// return;
|
||||
// }
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if (time >= frames[frames.Length - ENTRIES]) { // Time is after last frame.
|
||||
// if (pose == MixPose_Setup) {
|
||||
// constraint.mix = constraint.data.mix + (frames[frames.Length + PREV_MIX] - constraint.data.mix) * alpha;
|
||||
// constraint.bendDirection = direction == MixDirection_Out ? constraint.data.bendDirection
|
||||
// : (int)frames[frames.Length + PREV_BEND_DIRECTION];
|
||||
// } else {
|
||||
// constraint.mix += (frames[frames.Length + PREV_MIX] - constraint.mix) * alpha;
|
||||
// if (direction == MixDirection_In) constraint.bendDirection = (int)frames[frames.Length + PREV_BEND_DIRECTION];
|
||||
// }
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// // Interpolate between the previous frame and the current frame.
|
||||
// int frame = Animation::binarySearch(frames, time, ENTRIES);
|
||||
// float mix = frames[frame + PREV_MIX];
|
||||
// float frameTime = frames[frame];
|
||||
// float percent = GetCurvePercent(frame / ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
|
||||
//
|
||||
// if (pose == MixPose_Setup) {
|
||||
// constraint.mix = constraint.data.mix + (mix + (frames[frame + MIX] - mix) * percent - constraint.data.mix) * alpha;
|
||||
// constraint.bendDirection = direction == MixDirection_Out ? constraint.data.bendDirection : (int)frames[frame + PREV_BEND_DIRECTION];
|
||||
// } else {
|
||||
// constraint.mix += (mix + (frames[frame + MIX] - mix) * percent - constraint.mix) * alpha;
|
||||
// if (direction == MixDirection_In) constraint.bendDirection = (int)frames[frame + PREV_BEND_DIRECTION];
|
||||
// }
|
||||
// }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -46,6 +46,9 @@ namespace Spine
|
||||
class PathConstraint : public Constraint
|
||||
{
|
||||
friend class Skeleton;
|
||||
friend class PathConstraintMixTimeline;
|
||||
friend class PathConstraintPositionTimeline;
|
||||
friend class PathConstraintSpacingTimeline;
|
||||
|
||||
RTTI_DECL;
|
||||
|
||||
|
||||
@ -47,6 +47,9 @@ namespace Spine
|
||||
{
|
||||
friend class PathConstraint;
|
||||
friend class Skeleton;
|
||||
friend class PathConstraintMixTimeline;
|
||||
friend class PathConstraintPositionTimeline;
|
||||
friend class PathConstraintSpacingTimeline;
|
||||
|
||||
public:
|
||||
PathConstraintData(std::string name);
|
||||
|
||||
@ -40,78 +40,23 @@ namespace Spine
|
||||
RTTI_DECL;
|
||||
|
||||
public:
|
||||
static const int ENTRIES;
|
||||
|
||||
PathConstraintMixTimeline(int frameCount);
|
||||
|
||||
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>& events, float alpha, MixPose pose, MixDirection direction);
|
||||
|
||||
virtual int getPropertyId();
|
||||
|
||||
private:
|
||||
static const int PREV_TIME, PREV_ROTATE, PREV_TRANSLATE;
|
||||
static const int ROTATE, TRANSLATE;
|
||||
|
||||
Vector<float> _frames;
|
||||
int _pathConstraintIndex;
|
||||
|
||||
// public const int ENTRIES = 3;
|
||||
// private const int PREV_TIME = -3, PREV_ROTATE = -2, PREV_TRANSLATE = -1;
|
||||
// private const int ROTATE = 1, TRANSLATE = 2;
|
||||
//
|
||||
// internal float[] frames;
|
||||
//
|
||||
// public int PathConstraintIndex { return pathConstraintIndex; } set { pathConstraintIndex = inValue; }
|
||||
// public float[] Frames { return frames; } set { frames = inValue; } // time, rotate mix, translate mix, ...
|
||||
//
|
||||
//
|
||||
// public PathConstraintMixTimeline (int frameCount)
|
||||
// : base(frameCount) {
|
||||
// frames = new float[frameCount * ENTRIES];
|
||||
// }
|
||||
//
|
||||
// /// Sets the time and mixes of the specified keyframe.
|
||||
// public void setFrame (int frameIndex, float time, float rotateMix, float translateMix) {
|
||||
// frameIndex *= ENTRIES;
|
||||
// frames[frameIndex] = time;
|
||||
// frames[frameIndex + ROTATE] = rotateMix;
|
||||
// frames[frameIndex + TRANSLATE] = translateMix;
|
||||
// }
|
||||
//
|
||||
// override public void Apply (Skeleton skeleton, float lastTime, float time, Vector<Event> firedEvents, float alpha, MixPose pose, MixDirection direction) {
|
||||
// PathConstraint constraint = skeleton.pathConstraints.Items[pathConstraintIndex];
|
||||
// float[] frames = _frames;
|
||||
// if (time < frames[0]) {
|
||||
// switch (pose) {
|
||||
// case MixPose_Setup:
|
||||
// constraint.rotateMix = constraint.data.rotateMix;
|
||||
// constraint.translateMix = constraint.data.translateMix;
|
||||
// return;
|
||||
// case MixPose_Current:
|
||||
// constraint.rotateMix += (constraint.data.rotateMix - constraint.rotateMix) * alpha;
|
||||
// constraint.translateMix += (constraint.data.translateMix - constraint.translateMix) * alpha;
|
||||
// return;
|
||||
// }
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// float rotate, translate;
|
||||
// if (time >= frames[frames.Length - ENTRIES]) { // Time is after last frame.
|
||||
// rotate = frames[frames.Length + PREV_ROTATE];
|
||||
// translate = frames[frames.Length + PREV_TRANSLATE];
|
||||
// } else {
|
||||
// // Interpolate between the previous frame and the current frame.
|
||||
// int frame = Animation::binarySearch(frames, time, ENTRIES);
|
||||
// rotate = frames[frame + PREV_ROTATE];
|
||||
// translate = frames[frame + PREV_TRANSLATE];
|
||||
// float frameTime = frames[frame];
|
||||
// float percent = GetCurvePercent(frame / ENTRIES - 1,
|
||||
// 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
|
||||
//
|
||||
// rotate += (frames[frame + ROTATE] - rotate) * percent;
|
||||
// translate += (frames[frame + TRANSLATE] - translate) * percent;
|
||||
// }
|
||||
//
|
||||
// if (pose == MixPose_Setup) {
|
||||
// constraint.rotateMix = constraint.data.rotateMix + (rotate - constraint.data.rotateMix) * alpha;
|
||||
// constraint.translateMix = constraint.data.translateMix + (translate - constraint.data.translateMix) * alpha;
|
||||
// } else {
|
||||
// constraint.rotateMix += (rotate - constraint.rotateMix) * alpha;
|
||||
// constraint.translateMix += (translate - constraint.translateMix) * alpha;
|
||||
// }
|
||||
// }
|
||||
/// Sets the time and mixes of the specified keyframe.
|
||||
void setFrame(int frameIndex, float time, float rotateMix, float translateMix);
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -48,61 +48,15 @@ namespace Spine
|
||||
|
||||
virtual int getPropertyId();
|
||||
|
||||
/// Sets the time and value of the specified keyframe.
|
||||
void setFrame(int frameIndex, float time, float value);
|
||||
|
||||
protected:
|
||||
static const int PREV_TIME, PREV_VALUE;
|
||||
static const int VALUE;
|
||||
|
||||
Vector<float> _frames;
|
||||
int _pathConstraintIndex;
|
||||
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
// public int PathConstraintIndex { return pathConstraintIndex; } set { pathConstraintIndex = inValue; }
|
||||
// public float[] Frames { return frames; } set { frames = inValue; } // time, position, ...
|
||||
//
|
||||
// /// Sets the time and value of the specified keyframe.
|
||||
// public void setFrame (int frameIndex, float time, float value) {
|
||||
// frameIndex *= ENTRIES;
|
||||
// frames[frameIndex] = time;
|
||||
// frames[frameIndex + VALUE] = inValue;
|
||||
// }
|
||||
//
|
||||
// override public void Apply (Skeleton skeleton, float lastTime, float time, Vector<Event> firedEvents, float alpha, MixPose pose, MixDirection direction) {
|
||||
// PathConstraint constraint = skeleton.pathConstraints.Items[pathConstraintIndex];
|
||||
// float[] frames = _frames;
|
||||
// if (time < frames[0]) {
|
||||
// switch (pose) {
|
||||
// case MixPose_Setup:
|
||||
// constraint.position = constraint.data.position;
|
||||
// return;
|
||||
// case MixPose_Current:
|
||||
// constraint.position += (constraint.data.position - constraint.position) * alpha;
|
||||
// return;
|
||||
// }
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// float position;
|
||||
// if (time >= frames[frames.Length - ENTRIES]) // Time is after last frame.
|
||||
// position = frames[frames.Length + PREV_VALUE];
|
||||
// else {
|
||||
// // Interpolate between the previous frame and the current frame.
|
||||
// int frame = Animation::binarySearch(frames, time, ENTRIES);
|
||||
// position = frames[frame + PREV_VALUE];
|
||||
// float frameTime = frames[frame];
|
||||
// float percent = GetCurvePercent(frame / ENTRIES - 1,
|
||||
// 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
|
||||
//
|
||||
// position += (frames[frame + VALUE] - position) * percent;
|
||||
// }
|
||||
// if (pose == MixPose_Setup)
|
||||
// constraint.position = constraint.data.position + (position - constraint.data.position) * alpha;
|
||||
// else
|
||||
// constraint.position += (position - constraint.position) * alpha;
|
||||
// }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -45,41 +45,6 @@ namespace Spine
|
||||
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>& events, float alpha, MixPose pose, MixDirection direction);
|
||||
|
||||
virtual int getPropertyId();
|
||||
|
||||
// override public void Apply (Skeleton skeleton, float lastTime, float time, Vector<Event> firedEvents, float alpha, MixPose pose, MixDirection direction) {
|
||||
// PathConstraint constraint = skeleton.pathConstraints.Items[pathConstraintIndex];
|
||||
// float[] frames = _frames;
|
||||
// if (time < frames[0]) {
|
||||
// switch (pose) {
|
||||
// case MixPose_Setup:
|
||||
// constraint.spacing = constraint.data.spacing;
|
||||
// return;
|
||||
// case MixPose_Current:
|
||||
// constraint.spacing += (constraint.data.spacing - constraint.spacing) * alpha;
|
||||
// return;
|
||||
// }
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// float spacing;
|
||||
// if (time >= frames[frames.Length - ENTRIES]) // Time is after last frame.
|
||||
// spacing = frames[frames.Length + PREV_VALUE];
|
||||
// else {
|
||||
// // Interpolate between the previous frame and the current frame.
|
||||
// int frame = Animation::binarySearch(frames, time, ENTRIES);
|
||||
// spacing = frames[frame + PREV_VALUE];
|
||||
// float frameTime = frames[frame];
|
||||
// float percent = GetCurvePercent(frame / ENTRIES - 1,
|
||||
// 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
|
||||
//
|
||||
// spacing += (frames[frame + VALUE] - spacing) * percent;
|
||||
// }
|
||||
//
|
||||
// if (pose == MixPose_Setup)
|
||||
// constraint.spacing = constraint.data.spacing + (spacing - constraint.data.spacing) * alpha;
|
||||
// else
|
||||
// constraint.spacing += (spacing - constraint.spacing) * alpha;
|
||||
// }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -39,72 +39,12 @@ namespace Spine
|
||||
{
|
||||
RTTI_DECL;
|
||||
|
||||
public:
|
||||
ScaleTimeline(int frameCount);
|
||||
|
||||
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>& events, float alpha, MixPose pose, MixDirection direction);
|
||||
|
||||
virtual int getPropertyId();
|
||||
|
||||
// public ScaleTimeline (int frameCount)
|
||||
// : base(frameCount) {
|
||||
// }
|
||||
//
|
||||
// override public void Apply (Skeleton skeleton, float lastTime, float time, Vector<Event> firedEvents, float alpha, MixPose pose, MixDirection direction) {
|
||||
// Bone bone = skeleton.bones.Items[boneIndex];
|
||||
//
|
||||
// float[] frames = _frames;
|
||||
// if (time < frames[0]) {
|
||||
// switch (pose) {
|
||||
// case MixPose_Setup:
|
||||
// bone.scaleX = bone.data.scaleX;
|
||||
// bone.scaleY = bone.data.scaleY;
|
||||
// return;
|
||||
// case MixPose_Current:
|
||||
// bone.scaleX += (bone.data.scaleX - bone.scaleX) * alpha;
|
||||
// bone.scaleY += (bone.data.scaleY - bone.scaleY) * alpha;
|
||||
// return;
|
||||
// }
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// float x, y;
|
||||
// if (time >= frames[frames.Length - ENTRIES]) { // Time is after last frame.
|
||||
// x = frames[frames.Length + PREV_X] * bone.data.scaleX;
|
||||
// y = frames[frames.Length + PREV_Y] * bone.data.scaleY;
|
||||
// } else {
|
||||
// // Interpolate between the previous frame and the current frame.
|
||||
// int frame = Animation::binarySearch(frames, time, ENTRIES);
|
||||
// x = frames[frame + PREV_X];
|
||||
// y = frames[frame + PREV_Y];
|
||||
// float frameTime = frames[frame];
|
||||
// float percent = GetCurvePercent(frame / ENTRIES - 1,
|
||||
// 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
|
||||
//
|
||||
// x = (x + (frames[frame + X] - x) * percent) * bone.data.scaleX;
|
||||
// y = (y + (frames[frame + Y] - y) * percent) * bone.data.scaleY;
|
||||
// }
|
||||
// if (alpha == 1) {
|
||||
// bone.scaleX = x;
|
||||
// bone.scaleY = y;
|
||||
// } else {
|
||||
// float bx, by;
|
||||
// if (pose == MixPose_Setup) {
|
||||
// bx = bone.data.scaleX;
|
||||
// by = bone.data.scaleY;
|
||||
// } else {
|
||||
// bx = bone.scaleX;
|
||||
// by = bone.scaleY;
|
||||
// }
|
||||
// // Mixing out uses sign of setup or current pose, else use sign of key.
|
||||
// if (direction == MixDirection_Out) {
|
||||
// x = (x >= 0 ? x : -x) * (bx >= 0 ? 1 : -1);
|
||||
// y = (y >= 0 ? y : -y) * (by >= 0 ? 1 : -1);
|
||||
// } else {
|
||||
// bx = (bx >= 0 ? bx : -bx) * (x >= 0 ? 1 : -1);
|
||||
// by = (by >= 0 ? by : -by) * (y >= 0 ? 1 : -1);
|
||||
// }
|
||||
// bone.scaleX = bx + (x - bx) * alpha;
|
||||
// bone.scaleY = by + (y - by) * alpha;
|
||||
// }
|
||||
// }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -40,55 +40,11 @@ namespace Spine
|
||||
RTTI_DECL;
|
||||
|
||||
public:
|
||||
ShearTimeline(int frameCount);
|
||||
|
||||
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>& events, float alpha, MixPose pose, MixDirection direction);
|
||||
|
||||
virtual int getPropertyId();
|
||||
|
||||
// public ShearTimeline (int frameCount)
|
||||
// : base(frameCount) {
|
||||
// }
|
||||
//
|
||||
// override public void Apply (Skeleton skeleton, float lastTime, float time, Vector<Event> firedEvents, float alpha, MixPose pose, MixDirection direction) {
|
||||
// Bone bone = skeleton.bones.Items[boneIndex];
|
||||
// float[] frames = _frames;
|
||||
// if (time < frames[0]) {
|
||||
// switch (pose) {
|
||||
// case MixPose_Setup:
|
||||
// bone.shearX = bone.data.shearX;
|
||||
// bone.shearY = bone.data.shearY;
|
||||
// return;
|
||||
// case MixPose_Current:
|
||||
// bone.shearX += (bone.data.shearX - bone.shearX) * alpha;
|
||||
// bone.shearY += (bone.data.shearY - bone.shearY) * alpha;
|
||||
// return;
|
||||
// }
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// float x, y;
|
||||
// if (time >= frames[frames.Length - ENTRIES]) { // Time is after last frame.
|
||||
// x = frames[frames.Length + PREV_X];
|
||||
// y = frames[frames.Length + PREV_Y];
|
||||
// } else {
|
||||
// // Interpolate between the previous frame and the current frame.
|
||||
// int frame = Animation::binarySearch(frames, time, ENTRIES);
|
||||
// x = frames[frame + PREV_X];
|
||||
// y = frames[frame + PREV_Y];
|
||||
// float frameTime = frames[frame];
|
||||
// float percent = GetCurvePercent(frame / ENTRIES - 1,
|
||||
// 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
|
||||
//
|
||||
// x = x + (frames[frame + X] - x) * percent;
|
||||
// y = y + (frames[frame + Y] - y) * percent;
|
||||
// }
|
||||
// if (pose == MixPose_Setup) {
|
||||
// bone.shearX = bone.data.shearX + x * alpha;
|
||||
// bone.shearY = bone.data.shearY + y * alpha;
|
||||
// } else {
|
||||
// bone.shearX += (bone.data.shearX + x - bone.shearX) * alpha;
|
||||
// bone.shearY += (bone.data.shearY + y - bone.shearY) * alpha;
|
||||
// }
|
||||
// }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -44,6 +44,7 @@ namespace Spine
|
||||
class TransformConstraint : public Constraint
|
||||
{
|
||||
friend class Skeleton;
|
||||
friend class TransformConstraintTimeline;
|
||||
|
||||
RTTI_DECL;
|
||||
|
||||
|
||||
@ -43,6 +43,7 @@ namespace Spine
|
||||
{
|
||||
friend class TransformConstraint;
|
||||
friend class Skeleton;
|
||||
friend class TransformConstraintTimeline;
|
||||
|
||||
public:
|
||||
TransformConstraintData(std::string name);
|
||||
|
||||
@ -42,94 +42,20 @@ namespace Spine
|
||||
public:
|
||||
static const int ENTRIES;
|
||||
|
||||
TransformConstraintTimeline(int frameCount);
|
||||
|
||||
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>& events, float alpha, MixPose pose, MixDirection direction);
|
||||
|
||||
virtual int getPropertyId();
|
||||
|
||||
void setFrame(int frameIndex, float time, float rotateMix, float translateMix, float scaleMix, float shearMix);
|
||||
|
||||
private:
|
||||
static const int PREV_TIME, PREV_ROTATE, PREV_TRANSLATE, PREV_SCALE, PREV_SHEAR;
|
||||
static const int ROTATE, TRANSLATE, SCALE, SHEAR;
|
||||
|
||||
Vector<float> _frames;
|
||||
int _transformConstraintIndex;
|
||||
|
||||
// internal float[] frames;
|
||||
//
|
||||
// public int TransformConstraintIndex { return transformConstraintIndex; } set { transformConstraintIndex = inValue; }
|
||||
// public float[] Frames { return frames; } set { frames = inValue; } // time, rotate mix, translate mix, scale mix, shear mix, ...
|
||||
//
|
||||
//
|
||||
// public TransformConstraintTimeline (int frameCount)
|
||||
// : base(frameCount) {
|
||||
// frames = new float[frameCount * ENTRIES];
|
||||
// }
|
||||
//
|
||||
// public void setFrame (int frameIndex, float time, float rotateMix, float translateMix, float scaleMix, float shearMix) {
|
||||
// frameIndex *= ENTRIES;
|
||||
// frames[frameIndex] = time;
|
||||
// frames[frameIndex + ROTATE] = rotateMix;
|
||||
// frames[frameIndex + TRANSLATE] = translateMix;
|
||||
// frames[frameIndex + SCALE] = scaleMix;
|
||||
// frames[frameIndex + SHEAR] = shearMix;
|
||||
// }
|
||||
//
|
||||
// override public void Apply (Skeleton skeleton, float lastTime, float time, Vector<Event> firedEvents, float alpha, MixPose pose, MixDirection direction) {
|
||||
// TransformConstraint constraint = skeleton.transformConstraints.Items[transformConstraintIndex];
|
||||
// float[] frames = _frames;
|
||||
// if (time < frames[0]) {
|
||||
// var data = constraint.data;
|
||||
// switch (pose) {
|
||||
// case MixPose_Setup:
|
||||
// constraint.rotateMix = data.rotateMix;
|
||||
// constraint.translateMix = data.translateMix;
|
||||
// constraint.scaleMix = data.scaleMix;
|
||||
// constraint.shearMix = data.shearMix;
|
||||
// return;
|
||||
// case MixPose_Current:
|
||||
// constraint.rotateMix += (data.rotateMix - constraint.rotateMix) * alpha;
|
||||
// constraint.translateMix += (data.translateMix - constraint.translateMix) * alpha;
|
||||
// constraint.scaleMix += (data.scaleMix - constraint.scaleMix) * alpha;
|
||||
// constraint.shearMix += (data.shearMix - constraint.shearMix) * alpha;
|
||||
// return;
|
||||
// }
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// float rotate, translate, scale, shear;
|
||||
// if (time >= frames[frames.Length - ENTRIES]) { // Time is after last frame.
|
||||
// int i = frames.Length;
|
||||
// rotate = frames[i + PREV_ROTATE];
|
||||
// translate = frames[i + PREV_TRANSLATE];
|
||||
// scale = frames[i + PREV_SCALE];
|
||||
// shear = frames[i + PREV_SHEAR];
|
||||
// } else {
|
||||
// // Interpolate between the previous frame and the current frame.
|
||||
// int frame = Animation::binarySearch(frames, time, ENTRIES);
|
||||
// rotate = frames[frame + PREV_ROTATE];
|
||||
// translate = frames[frame + PREV_TRANSLATE];
|
||||
// scale = frames[frame + PREV_SCALE];
|
||||
// shear = frames[frame + PREV_SHEAR];
|
||||
// float frameTime = frames[frame];
|
||||
// float percent = GetCurvePercent(frame / ENTRIES - 1,
|
||||
// 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
|
||||
//
|
||||
// rotate += (frames[frame + ROTATE] - rotate) * percent;
|
||||
// translate += (frames[frame + TRANSLATE] - translate) * percent;
|
||||
// scale += (frames[frame + SCALE] - scale) * percent;
|
||||
// shear += (frames[frame + SHEAR] - shear) * percent;
|
||||
// }
|
||||
// if (pose == MixPose_Setup) {
|
||||
// TransformConstraintData data = constraint.data;
|
||||
// constraint.rotateMix = data.rotateMix + (rotate - data.rotateMix) * alpha;
|
||||
// constraint.translateMix = data.translateMix + (translate - data.translateMix) * alpha;
|
||||
// constraint.scaleMix = data.scaleMix + (scale - data.scaleMix) * alpha;
|
||||
// constraint.shearMix = data.shearMix + (shear - data.shearMix) * alpha;
|
||||
// } else {
|
||||
// constraint.rotateMix += (rotate - constraint.rotateMix) * alpha;
|
||||
// constraint.translateMix += (translate - constraint.translateMix) * alpha;
|
||||
// constraint.scaleMix += (scale - constraint.scaleMix) * alpha;
|
||||
// constraint.shearMix += (shear - constraint.shearMix) * alpha;
|
||||
// }
|
||||
// }
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -43,89 +43,23 @@ namespace Spine
|
||||
RTTI_DECL;
|
||||
|
||||
public:
|
||||
static const int ENTRIES;
|
||||
|
||||
TranslateTimeline(int frameCount);
|
||||
|
||||
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>& events, float alpha, MixPose pose, MixDirection direction);
|
||||
|
||||
virtual int getPropertyId();
|
||||
|
||||
protected:
|
||||
int _boneIndex;
|
||||
/// Sets the time and value of the specified keyframe.
|
||||
void setFrame(int frameIndex, float time, float x, float y);
|
||||
|
||||
// public const int ENTRIES = 3;
|
||||
// protected const int PREV_TIME = -3, PREV_X = -2, PREV_Y = -1;
|
||||
// protected const int X = 1, Y = 2;
|
||||
//
|
||||
// internal float[] frames;
|
||||
//
|
||||
// public int getBoneIndex { return boneIndex; } set { boneIndex = inValue; }
|
||||
// public Vector<float> getFrames { return frames; } set { frames = inValue; } // time, value, value, ...
|
||||
//
|
||||
//
|
||||
// public TranslateTimeline(int frameCount) : CurveTimeline(frameCount)
|
||||
// {
|
||||
// frames = new float[frameCount * ENTRIES];
|
||||
// }
|
||||
//
|
||||
// /// Sets the time and value of the specified keyframe.
|
||||
// public void setFrame(int frameIndex, float time, float x, float y)
|
||||
// {
|
||||
// frameIndex *= ENTRIES;
|
||||
// frames[frameIndex] = time;
|
||||
// frames[frameIndex + X] = x;
|
||||
// frames[frameIndex + Y] = y;
|
||||
// }
|
||||
//
|
||||
// override public void apply(Skeleton skeleton, float lastTime, float time, Vector<Event> firedEvents, float alpha, MixPose pose, MixDirection direction)
|
||||
// {
|
||||
// Bone bone = skeleton.bones.Items[boneIndex];
|
||||
//
|
||||
// float[] frames = _frames;
|
||||
// if (time < frames[0])
|
||||
// {
|
||||
// switch (pose)
|
||||
// {
|
||||
// case MixPose_Setup:
|
||||
// bone.x = bone.data.x;
|
||||
// bone.y = bone.data.y;
|
||||
// return;
|
||||
// case MixPose_Current:
|
||||
// bone.x += (bone.data.x - bone.x) * alpha;
|
||||
// bone.y += (bone.data.y - bone.y) * alpha;
|
||||
// return;
|
||||
// }
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// float x, y;
|
||||
// if (time >= frames[frames.Length - ENTRIES])
|
||||
// {
|
||||
// // Time is after last frame.
|
||||
// x = frames[frames.Length + PREV_X];
|
||||
// y = frames[frames.Length + PREV_Y];
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// // Interpolate between the previous frame and the current frame.
|
||||
// int frame = Animation::binarySearch(frames, time, ENTRIES);
|
||||
// x = frames[frame + PREV_X];
|
||||
// y = frames[frame + PREV_Y];
|
||||
// float frameTime = frames[frame];
|
||||
// float percent = GetCurvePercent(frame / ENTRIES - 1, 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
|
||||
//
|
||||
// x += (frames[frame + X] - x) * percent;
|
||||
// y += (frames[frame + Y] - y) * percent;
|
||||
// }
|
||||
//
|
||||
// if (pose == MixPose_Setup)
|
||||
// {
|
||||
// bone.x = bone.data.x + x * alpha;
|
||||
// bone.y = bone.data.y + y * alpha;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// bone.x += (bone.data.x + x - bone.x) * alpha;
|
||||
// bone.y += (bone.data.y + y - bone.y) * alpha;
|
||||
// }
|
||||
// }
|
||||
protected:
|
||||
static const int PREV_TIME, PREV_X, PREV_Y;
|
||||
static const int X, Y;
|
||||
|
||||
Vector<float> _frames;
|
||||
int _boneIndex;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -40,146 +40,27 @@ namespace Spine
|
||||
RTTI_DECL;
|
||||
|
||||
public:
|
||||
static const int ENTRIES;
|
||||
|
||||
TwoColorTimeline(int frameCount);
|
||||
|
||||
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>& events, float alpha, MixPose pose, MixDirection direction);
|
||||
|
||||
virtual int getPropertyId();
|
||||
|
||||
private:
|
||||
int _slotIndex;
|
||||
/// Sets the time and value of the specified keyframe.
|
||||
void setFrame(int frameIndex, float time, float r, float g, float b, float a, float r2, float g2, float b2);
|
||||
|
||||
// public const int ENTRIES = 8;
|
||||
// protected const int PREV_TIME = -8, PREV_R = -7, PREV_G = -6, PREV_B = -5, PREV_A = -4;
|
||||
// protected const int PREV_R2 = -3, PREV_G2 = -2, PREV_B2 = -1;
|
||||
// protected const int R = 1, G = 2, B = 3, A = 4, R2 = 5, G2 = 6, B2 = 7;
|
||||
//
|
||||
// internal float[] frames; // time, r, g, b, a, r2, g2, b2, ...
|
||||
// public float[] Frames { return frames; }
|
||||
//
|
||||
// public int SlotIndex {
|
||||
// get { return slotIndex; }
|
||||
// set {
|
||||
// if (value < 0) throw new ArgumentOutOfRangeException("index must be >= 0.");
|
||||
// slotIndex = inValue;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
//
|
||||
// public TwoColorTimeline (int frameCount) :
|
||||
// base(frameCount) {
|
||||
// frames = new float[frameCount * ENTRIES];
|
||||
// }
|
||||
//
|
||||
// /// Sets the time and value of the specified keyframe.
|
||||
// public void setFrame (int frameIndex, float time, float r, float g, float b, float a, float r2, float g2, float b2) {
|
||||
// frameIndex *= ENTRIES;
|
||||
// frames[frameIndex] = time;
|
||||
// frames[frameIndex + R] = r;
|
||||
// frames[frameIndex + G] = g;
|
||||
// frames[frameIndex + B] = b;
|
||||
// frames[frameIndex + A] = a;
|
||||
// frames[frameIndex + R2] = r2;
|
||||
// frames[frameIndex + G2] = g2;
|
||||
// frames[frameIndex + B2] = b2;
|
||||
// }
|
||||
//
|
||||
// override public void Apply (Skeleton skeleton, float lastTime, float time, Vector<Event> firedEvents, float alpha, MixPose pose, MixDirection direction) {
|
||||
// Slot slot = skeleton.slots.Items[slotIndex];
|
||||
// float[] frames = _frames;
|
||||
// if (time < frames[0]) { // Time is before first frame.
|
||||
// var slotData = slot.data;
|
||||
// switch (pose) {
|
||||
// case MixPose_Setup:
|
||||
// // slot.color.set(slot.data.color);
|
||||
// // slot.darkColor.set(slot.data.darkColor);
|
||||
// slot.r = slotData.r;
|
||||
// slot.g = slotData.g;
|
||||
// slot.b = slotData.b;
|
||||
// slot.a = slotData.a;
|
||||
// slot.r2 = slotData.r2;
|
||||
// slot.g2 = slotData.g2;
|
||||
// slot.b2 = slotData.b2;
|
||||
// return;
|
||||
// case MixPose_Current:
|
||||
// slot.r += (slot.r - slotData.r) * alpha;
|
||||
// slot.g += (slot.g - slotData.g) * alpha;
|
||||
// slot.b += (slot.b - slotData.b) * alpha;
|
||||
// slot.a += (slot.a - slotData.a) * alpha;
|
||||
// slot.r2 += (slot.r2 - slotData.r2) * alpha;
|
||||
// slot.g2 += (slot.g2 - slotData.g2) * alpha;
|
||||
// slot.b2 += (slot.b2 - slotData.b2) * alpha;
|
||||
// return;
|
||||
// }
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// float r, g, b, a, r2, g2, b2;
|
||||
// if (time >= frames[frames.Length - ENTRIES]) { // Time is after last frame.
|
||||
// int i = frames.Length;
|
||||
// r = frames[i + PREV_R];
|
||||
// g = frames[i + PREV_G];
|
||||
// b = frames[i + PREV_B];
|
||||
// a = frames[i + PREV_A];
|
||||
// r2 = frames[i + PREV_R2];
|
||||
// g2 = frames[i + PREV_G2];
|
||||
// b2 = frames[i + PREV_B2];
|
||||
// } else {
|
||||
// // Interpolate between the previous frame and the current frame.
|
||||
// int frame = Animation::binarySearch(frames, time, ENTRIES);
|
||||
// r = frames[frame + PREV_R];
|
||||
// g = frames[frame + PREV_G];
|
||||
// b = frames[frame + PREV_B];
|
||||
// a = frames[frame + PREV_A];
|
||||
// r2 = frames[frame + PREV_R2];
|
||||
// g2 = frames[frame + PREV_G2];
|
||||
// b2 = frames[frame + PREV_B2];
|
||||
// float frameTime = frames[frame];
|
||||
// float percent = GetCurvePercent(frame / ENTRIES - 1,
|
||||
// 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
|
||||
//
|
||||
// r += (frames[frame + R] - r) * percent;
|
||||
// g += (frames[frame + G] - g) * percent;
|
||||
// b += (frames[frame + B] - b) * percent;
|
||||
// a += (frames[frame + A] - a) * percent;
|
||||
// r2 += (frames[frame + R2] - r2) * percent;
|
||||
// g2 += (frames[frame + G2] - g2) * percent;
|
||||
// b2 += (frames[frame + B2] - b2) * percent;
|
||||
// }
|
||||
// if (alpha == 1) {
|
||||
// slot.r = r;
|
||||
// slot.g = g;
|
||||
// slot.b = b;
|
||||
// slot.a = a;
|
||||
// slot.r2 = r2;
|
||||
// slot.g2 = g2;
|
||||
// slot.b2 = b2;
|
||||
// } else {
|
||||
// float br, bg, bb, ba, br2, bg2, bb2;
|
||||
// if (pose == MixPose_Setup) {
|
||||
// br = slot.data.r;
|
||||
// bg = slot.data.g;
|
||||
// bb = slot.data.b;
|
||||
// ba = slot.data.a;
|
||||
// br2 = slot.data.r2;
|
||||
// bg2 = slot.data.g2;
|
||||
// bb2 = slot.data.b2;
|
||||
// } else {
|
||||
// br = slot.r;
|
||||
// bg = slot.g;
|
||||
// bb = slot.b;
|
||||
// ba = slot.a;
|
||||
// br2 = slot.r2;
|
||||
// bg2 = slot.g2;
|
||||
// bb2 = slot.b2;
|
||||
// }
|
||||
// slot.r = br + ((r - br) * alpha);
|
||||
// slot.g = bg + ((g - bg) * alpha);
|
||||
// slot.b = bb + ((b - bb) * alpha);
|
||||
// slot.a = ba + ((a - ba) * alpha);
|
||||
// slot.r2 = br2 + ((r2 - br2) * alpha);
|
||||
// slot.g2 = bg2 + ((g2 - bg2) * alpha);
|
||||
// slot.b2 = bb2 + ((b2 - bb2) * alpha);
|
||||
// }
|
||||
// }
|
||||
int getSlotIndex();
|
||||
void setSlotIndex(int inValue);
|
||||
|
||||
private:
|
||||
static const int PREV_TIME, PREV_R, PREV_G, PREV_B, PREV_A;
|
||||
static const int PREV_R2, PREV_G2, PREV_B2;
|
||||
static const int R, G, B, A, R2, G2, B2;
|
||||
|
||||
Vector<float> _frames; // time, r, g, b, a, r2, g2, b2, ...
|
||||
int _slotIndex;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -48,18 +48,53 @@ namespace Spine
|
||||
// Empty
|
||||
}
|
||||
|
||||
Vector(const Vector& inArray) : _size(inArray._size), _capacity(inArray._capacity), _buffer(NULL)
|
||||
Vector(const Vector& inVector) : _size(inVector._size), _capacity(inVector._capacity), _buffer(NULL)
|
||||
{
|
||||
if (_capacity > 0)
|
||||
{
|
||||
_buffer = allocate(_capacity);
|
||||
for (size_t i = 0; i < _size; ++i)
|
||||
{
|
||||
construct(_buffer + i, inArray._buffer[i]);
|
||||
construct(_buffer + i, inVector._buffer[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vector(Vector& inVector) : _size(inVector._size), _capacity(inVector._capacity), _buffer(NULL)
|
||||
{
|
||||
if (_capacity > 0)
|
||||
{
|
||||
_buffer = allocate(_capacity);
|
||||
for (size_t i = 0; i < _size; ++i)
|
||||
{
|
||||
construct(_buffer + i, inVector._buffer[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Vector& operator=(Vector& inVector)
|
||||
{
|
||||
if (this != &inVector)
|
||||
{
|
||||
clear();
|
||||
deallocate(_buffer);
|
||||
|
||||
_size = inVector._size;
|
||||
_capacity = inVector._capacity;
|
||||
|
||||
if (_capacity > 0)
|
||||
{
|
||||
_buffer = allocate(_capacity);
|
||||
for (size_t i = 0; i < _size; ++i)
|
||||
{
|
||||
construct(_buffer + i, inVector._buffer[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
~Vector()
|
||||
{
|
||||
clear();
|
||||
@ -179,6 +214,29 @@ namespace Spine
|
||||
return &_buffer[_size];
|
||||
}
|
||||
|
||||
friend bool operator==(Vector<T>& lhs, Vector<T>& rhs)
|
||||
{
|
||||
if (lhs.size() != rhs.size())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0, n = static_cast<int>(lhs.size()); i < n; ++i)
|
||||
{
|
||||
if (lhs[i] != rhs[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
friend bool operator!=(Vector<T>& lhs, Vector<T>& rhs)
|
||||
{
|
||||
return !(lhs == rhs);
|
||||
}
|
||||
|
||||
private:
|
||||
size_t _size;
|
||||
size_t _capacity;
|
||||
|
||||
@ -37,18 +37,83 @@
|
||||
#include <spine/TimelineType.h>
|
||||
#include <spine/Slot.h>
|
||||
#include <spine/SlotData.h>
|
||||
#include <spine/Event.h>
|
||||
|
||||
namespace Spine
|
||||
{
|
||||
RTTI_IMPL(EventTimeline, Timeline);
|
||||
|
||||
EventTimeline::EventTimeline(int frameCount) : Timeline()
|
||||
{
|
||||
_frames.reserve(frameCount);
|
||||
_events.reserve(frameCount);
|
||||
}
|
||||
|
||||
void EventTimeline::apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>& events, float alpha, MixPose pose, MixDirection direction)
|
||||
{
|
||||
// TODO
|
||||
if (events.size() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int frameCount = static_cast<int>(_frames.size());
|
||||
|
||||
if (lastTime > time)
|
||||
{
|
||||
// Fire events after last time for looped animations.
|
||||
apply(skeleton, lastTime, std::numeric_limits<int>::max(), events, alpha, pose, direction);
|
||||
lastTime = -1.0f;
|
||||
}
|
||||
else if (lastTime >= _frames[frameCount - 1]) // Last time is after last frame.
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (time < _frames[0])
|
||||
{
|
||||
return; // Time is before first frame.
|
||||
}
|
||||
|
||||
int frame;
|
||||
if (lastTime < _frames[0])
|
||||
{
|
||||
frame = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
frame = Animation::binarySearch(_frames, lastTime);
|
||||
float frameTime = _frames[frame];
|
||||
while (frame > 0)
|
||||
{
|
||||
// Fire multiple events with the same frame.
|
||||
if (_frames[frame - 1] != frameTime)
|
||||
{
|
||||
break;
|
||||
}
|
||||
frame--;
|
||||
}
|
||||
}
|
||||
|
||||
for (; frame < frameCount && time >= _frames[frame]; ++frame)
|
||||
{
|
||||
events.push_back(_events[frame]);
|
||||
}
|
||||
}
|
||||
|
||||
int EventTimeline::getPropertyId()
|
||||
{
|
||||
return ((int)TimelineType_Event << 24);
|
||||
}
|
||||
|
||||
void EventTimeline::setFrame(int frameIndex, Event* e)
|
||||
{
|
||||
_frames[frameIndex] = e->getTime();
|
||||
_events[frameIndex] = e;
|
||||
}
|
||||
|
||||
Vector<float> EventTimeline::getFrames() { return _frames; }
|
||||
void EventTimeline::setFrames(Vector<float>& inValue) { _frames = inValue; } // time, ...
|
||||
Vector<Event*>& EventTimeline::getEvents() { return _events; }
|
||||
void EventTimeline::setEvents(Vector<Event*>& inValue) { _events = inValue; }
|
||||
int EventTimeline::getFrameCount() { return static_cast<int>(_frames.size()); }
|
||||
}
|
||||
|
||||
@ -37,6 +37,8 @@
|
||||
#include <spine/TimelineType.h>
|
||||
#include <spine/Slot.h>
|
||||
#include <spine/SlotData.h>
|
||||
#include <spine/IkConstraint.h>
|
||||
#include <spine/IkConstraintData.h>
|
||||
|
||||
namespace Spine
|
||||
{
|
||||
@ -56,11 +58,77 @@ namespace Spine
|
||||
|
||||
void IkConstraintTimeline::apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>& events, float alpha, MixPose pose, MixDirection direction)
|
||||
{
|
||||
// TODO
|
||||
IkConstraint* constraintP = skeleton._ikConstraints[_ikConstraintIndex];
|
||||
IkConstraint& constraint = *constraintP;
|
||||
if (time < _frames[0])
|
||||
{
|
||||
switch (pose)
|
||||
{
|
||||
case MixPose_Setup:
|
||||
constraint._mix = constraint._data._mix;
|
||||
constraint._bendDirection = constraint._data._bendDirection;
|
||||
return;
|
||||
case MixPose_Current:
|
||||
constraint._mix += (constraint._data._mix - constraint._mix) * alpha;
|
||||
constraint._bendDirection = constraint._data._bendDirection;
|
||||
return;
|
||||
case MixPose_CurrentLayered:
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (time >= _frames[_frames.size() - ENTRIES])
|
||||
{
|
||||
// Time is after last frame.
|
||||
if (pose == MixPose_Setup)
|
||||
{
|
||||
constraint._mix = constraint._data._mix + (_frames[_frames.size() + PREV_MIX] - constraint._data._mix) * alpha;
|
||||
constraint._bendDirection = direction == MixDirection_Out ? constraint._data._bendDirection
|
||||
: (int)_frames[_frames.size() + PREV_BEND_DIRECTION];
|
||||
}
|
||||
else
|
||||
{
|
||||
constraint._mix += (_frames[_frames.size() + PREV_MIX] - constraint._mix) * alpha;
|
||||
if (direction == MixDirection_In)
|
||||
{
|
||||
constraint._bendDirection = (int)_frames[_frames.size() + PREV_BEND_DIRECTION];
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Interpolate between the previous frame and the current frame.
|
||||
int frame = Animation::binarySearch(_frames, time, ENTRIES);
|
||||
float mix = _frames[frame + PREV_MIX];
|
||||
float frameTime = _frames[frame];
|
||||
float percent = getCurvePercent(frame / ENTRIES - 1, 1 - (time - frameTime) / (_frames[frame + PREV_TIME] - frameTime));
|
||||
|
||||
if (pose == MixPose_Setup)
|
||||
{
|
||||
constraint._mix = constraint._data._mix + (mix + (_frames[frame + MIX] - mix) * percent - constraint._data._mix) * alpha;
|
||||
constraint._bendDirection = direction == MixDirection_Out ? constraint._data._bendDirection : (int)_frames[frame + PREV_BEND_DIRECTION];
|
||||
}
|
||||
else
|
||||
{
|
||||
constraint._mix += (mix + (_frames[frame + MIX] - mix) * percent - constraint._mix) * alpha;
|
||||
if (direction == MixDirection_In)
|
||||
{
|
||||
constraint._bendDirection = (int)_frames[frame + PREV_BEND_DIRECTION];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int IkConstraintTimeline::getPropertyId()
|
||||
{
|
||||
return ((int)TimelineType_IkConstraint << 24) + _ikConstraintIndex;
|
||||
}
|
||||
|
||||
void IkConstraintTimeline::setFrame(int frameIndex, float time, float mix, int bendDirection)
|
||||
{
|
||||
frameIndex *= ENTRIES;
|
||||
_frames[frameIndex] = time;
|
||||
_frames[frameIndex + MIX] = mix;
|
||||
_frames[frameIndex + BEND_DIRECTION] = bendDirection;
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,18 +37,90 @@
|
||||
#include <spine/TimelineType.h>
|
||||
#include <spine/Slot.h>
|
||||
#include <spine/SlotData.h>
|
||||
#include <spine/PathConstraint.h>
|
||||
#include <spine/PathConstraintData.h>
|
||||
|
||||
namespace Spine
|
||||
{
|
||||
RTTI_IMPL(PathConstraintMixTimeline, CurveTimeline);
|
||||
|
||||
const int PathConstraintMixTimeline::ENTRIES = 3;
|
||||
const int PathConstraintMixTimeline::PREV_TIME = -3;
|
||||
const int PathConstraintMixTimeline::PREV_ROTATE = -2;
|
||||
const int PathConstraintMixTimeline::PREV_TRANSLATE = -1;
|
||||
const int PathConstraintMixTimeline::ROTATE = 1;
|
||||
const int PathConstraintMixTimeline::TRANSLATE = 2;
|
||||
|
||||
PathConstraintMixTimeline::PathConstraintMixTimeline(int frameCount) : CurveTimeline(frameCount), _pathConstraintIndex(0)
|
||||
{
|
||||
_frames.reserve(frameCount * ENTRIES);
|
||||
}
|
||||
|
||||
void PathConstraintMixTimeline::apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>& events, float alpha, MixPose pose, MixDirection direction)
|
||||
{
|
||||
// TODO
|
||||
PathConstraint* constraintP = skeleton._pathConstraints[_pathConstraintIndex];
|
||||
PathConstraint& constraint = *constraintP;
|
||||
if (time < _frames[0])
|
||||
{
|
||||
switch (pose)
|
||||
{
|
||||
case MixPose_Setup:
|
||||
constraint._rotateMix = constraint._data._rotateMix;
|
||||
constraint._translateMix = constraint._data._translateMix;
|
||||
return;
|
||||
case MixPose_Current:
|
||||
constraint._rotateMix += (constraint._data._rotateMix - constraint._rotateMix) * alpha;
|
||||
constraint._translateMix += (constraint._data._translateMix - constraint._translateMix) * alpha;
|
||||
return;
|
||||
case MixPose_CurrentLayered:
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
float rotate, translate;
|
||||
if (time >= _frames[_frames.size() - ENTRIES])
|
||||
{
|
||||
// Time is after last frame.
|
||||
rotate = _frames[_frames.size() + PREV_ROTATE];
|
||||
translate = _frames[_frames.size() + PREV_TRANSLATE];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Interpolate between the previous frame and the current frame.
|
||||
int frame = Animation::binarySearch(_frames, time, ENTRIES);
|
||||
rotate = _frames[frame + PREV_ROTATE];
|
||||
translate = _frames[frame + PREV_TRANSLATE];
|
||||
float frameTime = _frames[frame];
|
||||
float percent = getCurvePercent(frame / ENTRIES - 1,
|
||||
1 - (time - frameTime) / (_frames[frame + PREV_TIME] - frameTime));
|
||||
|
||||
rotate += (_frames[frame + ROTATE] - rotate) * percent;
|
||||
translate += (_frames[frame + TRANSLATE] - translate) * percent;
|
||||
}
|
||||
|
||||
if (pose == MixPose_Setup)
|
||||
{
|
||||
constraint._rotateMix = constraint._data._rotateMix + (rotate - constraint._data._rotateMix) * alpha;
|
||||
constraint._translateMix = constraint._data._translateMix + (translate - constraint._data._translateMix) * alpha;
|
||||
}
|
||||
else
|
||||
{
|
||||
constraint._rotateMix += (rotate - constraint._rotateMix) * alpha;
|
||||
constraint._translateMix += (translate - constraint._translateMix) * alpha;
|
||||
}
|
||||
}
|
||||
|
||||
int PathConstraintMixTimeline::getPropertyId()
|
||||
{
|
||||
return ((int)TimelineType_PathConstraintMix << 24) + _pathConstraintIndex;
|
||||
}
|
||||
|
||||
void PathConstraintMixTimeline::setFrame(int frameIndex, float time, float rotateMix, float translateMix)
|
||||
{
|
||||
frameIndex *= ENTRIES;
|
||||
_frames[frameIndex] = time;
|
||||
_frames[frameIndex + ROTATE] = rotateMix;
|
||||
_frames[frameIndex + TRANSLATE] = translateMix;
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,6 +37,8 @@
|
||||
#include <spine/TimelineType.h>
|
||||
#include <spine/Slot.h>
|
||||
#include <spine/SlotData.h>
|
||||
#include <spine/PathConstraint.h>
|
||||
#include <spine/PathConstraintData.h>
|
||||
|
||||
namespace Spine
|
||||
{
|
||||
@ -47,18 +49,66 @@ namespace Spine
|
||||
const int PathConstraintPositionTimeline::PREV_VALUE = -1;
|
||||
const int PathConstraintPositionTimeline::VALUE = 1;
|
||||
|
||||
PathConstraintPositionTimeline::PathConstraintPositionTimeline(int frameCount) : CurveTimeline(frameCount)
|
||||
PathConstraintPositionTimeline::PathConstraintPositionTimeline(int frameCount) : CurveTimeline(frameCount), _pathConstraintIndex(0)
|
||||
{
|
||||
_frames.reserve(frameCount * ENTRIES);
|
||||
}
|
||||
|
||||
void PathConstraintPositionTimeline::apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>& events, float alpha, MixPose pose, MixDirection direction)
|
||||
{
|
||||
// TODO
|
||||
PathConstraint* constraintP = skeleton._pathConstraints[_pathConstraintIndex];
|
||||
PathConstraint& constraint = *constraintP;
|
||||
if (time < _frames[0])
|
||||
{
|
||||
switch (pose)
|
||||
{
|
||||
case MixPose_Setup:
|
||||
constraint._position = constraint._data._position;
|
||||
return;
|
||||
case MixPose_Current:
|
||||
constraint._position += (constraint._data._position - constraint._position) * alpha;
|
||||
return;
|
||||
case MixPose_CurrentLayered:
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
float position;
|
||||
if (time >= _frames[_frames.size() - ENTRIES]) // Time is after last frame.
|
||||
{
|
||||
position = _frames[_frames.size() + PREV_VALUE];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Interpolate between the previous frame and the current frame.
|
||||
int frame = Animation::binarySearch(_frames, time, ENTRIES);
|
||||
position = _frames[frame + PREV_VALUE];
|
||||
float frameTime = _frames[frame];
|
||||
float percent = getCurvePercent(frame / ENTRIES - 1,
|
||||
1 - (time - frameTime) / (_frames[frame + PREV_TIME] - frameTime));
|
||||
|
||||
position += (_frames[frame + VALUE] - position) * percent;
|
||||
}
|
||||
if (pose == MixPose_Setup)
|
||||
{
|
||||
constraint._position = constraint._data._position + (position - constraint._data._position) * alpha;
|
||||
}
|
||||
else
|
||||
{
|
||||
constraint._position += (position - constraint._position) * alpha;
|
||||
}
|
||||
}
|
||||
|
||||
int PathConstraintPositionTimeline::getPropertyId()
|
||||
{
|
||||
return ((int)TimelineType_PathConstraintPosition << 24) + _pathConstraintIndex;
|
||||
}
|
||||
|
||||
void PathConstraintPositionTimeline::setFrame(int frameIndex, float time, float value)
|
||||
{
|
||||
frameIndex *= ENTRIES;
|
||||
_frames[frameIndex] = time;
|
||||
_frames[frameIndex + VALUE] = value;
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,6 +37,8 @@
|
||||
#include <spine/TimelineType.h>
|
||||
#include <spine/Slot.h>
|
||||
#include <spine/SlotData.h>
|
||||
#include <spine/PathConstraint.h>
|
||||
#include <spine/PathConstraintData.h>
|
||||
|
||||
namespace Spine
|
||||
{
|
||||
@ -49,7 +51,49 @@ namespace Spine
|
||||
|
||||
void PathConstraintSpacingTimeline::apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>& events, float alpha, MixPose pose, MixDirection direction)
|
||||
{
|
||||
// TODO
|
||||
PathConstraint* constraintP = skeleton._pathConstraints[_pathConstraintIndex];
|
||||
PathConstraint& constraint = *constraintP;
|
||||
if (time < _frames[0])
|
||||
{
|
||||
switch (pose)
|
||||
{
|
||||
case MixPose_Setup:
|
||||
constraint._spacing = constraint._data._spacing;
|
||||
return;
|
||||
case MixPose_Current:
|
||||
constraint._spacing += (constraint._data._spacing - constraint._spacing) * alpha;
|
||||
return;
|
||||
case MixPose_CurrentLayered:
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
float spacing;
|
||||
if (time >= _frames[_frames.size() - ENTRIES]) // Time is after last frame.
|
||||
{
|
||||
spacing = _frames[_frames.size() + PREV_VALUE];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Interpolate between the previous frame and the current frame.
|
||||
int frame = Animation::binarySearch(_frames, time, ENTRIES);
|
||||
spacing = _frames[frame + PREV_VALUE];
|
||||
float frameTime = _frames[frame];
|
||||
float percent = getCurvePercent(frame / ENTRIES - 1,
|
||||
1 - (time - frameTime) / (_frames[frame + PREV_TIME] - frameTime));
|
||||
|
||||
spacing += (_frames[frame + VALUE] - spacing) * percent;
|
||||
}
|
||||
|
||||
if (pose == MixPose_Setup)
|
||||
{
|
||||
constraint._spacing = constraint._data._spacing + (spacing - constraint._data._spacing) * alpha;
|
||||
}
|
||||
else
|
||||
{
|
||||
constraint._spacing += (spacing - constraint._spacing) * alpha;
|
||||
}
|
||||
}
|
||||
|
||||
int PathConstraintSpacingTimeline::getPropertyId()
|
||||
|
||||
@ -37,14 +37,94 @@
|
||||
#include <spine/TimelineType.h>
|
||||
#include <spine/Slot.h>
|
||||
#include <spine/SlotData.h>
|
||||
#include <spine/Bone.h>
|
||||
#include <spine/BoneData.h>
|
||||
|
||||
namespace Spine
|
||||
{
|
||||
RTTI_IMPL(ScaleTimeline, TranslateTimeline);
|
||||
|
||||
ScaleTimeline::ScaleTimeline(int frameCount) : TranslateTimeline(frameCount)
|
||||
{
|
||||
// Empty
|
||||
}
|
||||
|
||||
void ScaleTimeline::apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>& events, float alpha, MixPose pose, MixDirection direction)
|
||||
{
|
||||
// TODO
|
||||
Bone* boneP = skeleton._bones[_boneIndex];
|
||||
Bone& bone = *boneP;
|
||||
|
||||
if (time < _frames[0])
|
||||
{
|
||||
switch (pose)
|
||||
{
|
||||
case MixPose_Setup:
|
||||
bone._scaleX = bone._data._scaleX;
|
||||
bone._scaleY = bone._data._scaleY;
|
||||
return;
|
||||
case MixPose_Current:
|
||||
bone._scaleX += (bone._data._scaleX - bone._scaleX) * alpha;
|
||||
bone._scaleY += (bone._data._scaleY - bone._scaleY) * alpha;
|
||||
return;
|
||||
case MixPose_CurrentLayered:
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
float x, y;
|
||||
if (time >= _frames[_frames.size() - ENTRIES])
|
||||
{
|
||||
// Time is after last frame.
|
||||
x = _frames[_frames.size() + PREV_X] * bone._data._scaleX;
|
||||
y = _frames[_frames.size() + PREV_Y] * bone._data._scaleY;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Interpolate between the previous frame and the current frame.
|
||||
int frame = Animation::binarySearch(_frames, time, ENTRIES);
|
||||
x = _frames[frame + PREV_X];
|
||||
y = _frames[frame + PREV_Y];
|
||||
float frameTime = _frames[frame];
|
||||
float percent = getCurvePercent(frame / ENTRIES - 1,
|
||||
1 - (time - frameTime) / (_frames[frame + PREV_TIME] - frameTime));
|
||||
|
||||
x = (x + (_frames[frame + X] - x) * percent) * bone._data._scaleX;
|
||||
y = (y + (_frames[frame + Y] - y) * percent) * bone._data._scaleY;
|
||||
}
|
||||
|
||||
if (alpha == 1)
|
||||
{
|
||||
bone._scaleX = x;
|
||||
bone._scaleY = y;
|
||||
}
|
||||
else
|
||||
{
|
||||
float bx, by;
|
||||
if (pose == MixPose_Setup)
|
||||
{
|
||||
bx = bone._data._scaleX;
|
||||
by = bone._data._scaleY;
|
||||
}
|
||||
else
|
||||
{
|
||||
bx = bone._scaleX;
|
||||
by = bone._scaleY;
|
||||
}
|
||||
// Mixing out uses sign of setup or current pose, else use sign of key.
|
||||
if (direction == MixDirection_Out)
|
||||
{
|
||||
x = (x >= 0 ? x : -x) * (bx >= 0 ? 1 : -1);
|
||||
y = (y >= 0 ? y : -y) * (by >= 0 ? 1 : -1);
|
||||
}
|
||||
else
|
||||
{
|
||||
bx = (bx >= 0 ? bx : -bx) * (x >= 0 ? 1 : -1);
|
||||
by = (by >= 0 ? by : -by) * (y >= 0 ? 1 : -1);
|
||||
}
|
||||
bone._scaleX = bx + (x - bx) * alpha;
|
||||
bone._scaleY = by + (y - by) * alpha;
|
||||
}
|
||||
}
|
||||
|
||||
int ScaleTimeline::getPropertyId()
|
||||
|
||||
@ -37,14 +37,72 @@
|
||||
#include <spine/TimelineType.h>
|
||||
#include <spine/Slot.h>
|
||||
#include <spine/SlotData.h>
|
||||
#include <spine/Bone.h>
|
||||
#include <spine/BoneData.h>
|
||||
|
||||
namespace Spine
|
||||
{
|
||||
RTTI_IMPL(ShearTimeline, TranslateTimeline);
|
||||
|
||||
ShearTimeline::ShearTimeline(int frameCount) : TranslateTimeline(frameCount)
|
||||
{
|
||||
// Empty
|
||||
}
|
||||
|
||||
void ShearTimeline::apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>& events, float alpha, MixPose pose, MixDirection direction)
|
||||
{
|
||||
// TODO
|
||||
Bone* boneP = skeleton._bones[_boneIndex];
|
||||
Bone& bone = *boneP;
|
||||
|
||||
if (time < _frames[0])
|
||||
{
|
||||
switch (pose)
|
||||
{
|
||||
case MixPose_Setup:
|
||||
bone._shearX = bone._data._shearX;
|
||||
bone._shearY = bone._data._shearY;
|
||||
return;
|
||||
case MixPose_Current:
|
||||
bone._shearX += (bone._data._shearX - bone._shearX) * alpha;
|
||||
bone._shearY += (bone._data._shearY - bone._shearY) * alpha;
|
||||
return;
|
||||
case MixPose_CurrentLayered:
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
float x, y;
|
||||
if (time >= _frames[_frames.size() - ENTRIES])
|
||||
{
|
||||
// Time is after last frame.
|
||||
x = _frames[_frames.size() + PREV_X];
|
||||
y = _frames[_frames.size() + PREV_Y];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Interpolate between the previous frame and the current frame.
|
||||
int frame = Animation::binarySearch(_frames, time, ENTRIES);
|
||||
x = _frames[frame + PREV_X];
|
||||
y = _frames[frame + PREV_Y];
|
||||
float frameTime = _frames[frame];
|
||||
float percent = getCurvePercent(frame / ENTRIES - 1,
|
||||
1 - (time - frameTime) / (_frames[frame + PREV_TIME] - frameTime));
|
||||
|
||||
x = x + (_frames[frame + X] - x) * percent;
|
||||
y = y + (_frames[frame + Y] - y) * percent;
|
||||
}
|
||||
|
||||
if (pose == MixPose_Setup)
|
||||
{
|
||||
bone._shearX = bone._data._shearX + x * alpha;
|
||||
bone._shearY = bone._data._shearY + y * alpha;
|
||||
}
|
||||
else
|
||||
{
|
||||
bone._shearX += (bone._data._shearX + x - bone._shearX) * alpha;
|
||||
bone._shearY += (bone._data._shearY + y - bone._shearY) * alpha;
|
||||
}
|
||||
}
|
||||
|
||||
int ShearTimeline::getPropertyId()
|
||||
|
||||
@ -56,7 +56,9 @@ namespace Spine
|
||||
_clippingPolygon.reserve(n);
|
||||
clip->computeWorldVertices(slot, 0, n, _clippingPolygon, 0, 2);
|
||||
makeClockwise(_clippingPolygon);
|
||||
_clippingPolygons = _triangulator.decompose(_clippingPolygon, _triangulator.triangulate(_clippingPolygon));
|
||||
Vector< Vector<float>* > clippingPolygons = _triangulator.decompose(_clippingPolygon, _triangulator.triangulate(_clippingPolygon));
|
||||
|
||||
_clippingPolygons = clippingPolygons;
|
||||
|
||||
for (Vector<float>** i = _clippingPolygons.begin(); i != _clippingPolygons.end(); ++i)
|
||||
{
|
||||
@ -97,14 +99,13 @@ namespace Spine
|
||||
Vector<float>& clipOutput = _clipOutput, clippedVertices = _clippedVertices;
|
||||
Vector<int>& clippedTriangles = _clippedTriangles;
|
||||
Vector< Vector<float>* >& polygons = _clippingPolygons;
|
||||
int polygonsCount = _clippingPolygons.size();
|
||||
int polygonsCount = static_cast<int>(_clippingPolygons.size());
|
||||
|
||||
int index = 0;
|
||||
clippedVertices.clear();
|
||||
_clippedUVs.clear();
|
||||
clippedTriangles.clear();
|
||||
|
||||
//outer:
|
||||
for (int i = 0; i < trianglesLength; i += 3)
|
||||
{
|
||||
int vertexOffset = triangles[i] << 1;
|
||||
@ -121,73 +122,72 @@ namespace Spine
|
||||
|
||||
for (int p = 0; p < polygonsCount; p++)
|
||||
{
|
||||
int s = clippedVertices.size();
|
||||
// if (clip(x1, y1, x2, y2, x3, y3, polygons[p], clipOutput))
|
||||
// {
|
||||
// int clipOutputLength = clipOutput.Count;
|
||||
// if (clipOutputLength == 0)
|
||||
// {
|
||||
// continue;
|
||||
// }
|
||||
// float d0 = y2 - y3, d1 = x3 - x2, d2 = x1 - x3, d4 = y3 - y1;
|
||||
// float d = 1 / (d0 * d2 + d1 * (y1 - y3));
|
||||
//
|
||||
// int clipOutputCount = clipOutputLength >> 1;
|
||||
// float[] clipOutputItems = clipOutput.Items;
|
||||
// float[] clippedVerticesItems = clippedVertices.Resize(s + clipOutputCount * 2).Items;
|
||||
// float[] clippedUVsItems = clippedUVs.Resize(s + clipOutputCount * 2).Items;
|
||||
// for (int ii = 0; ii < clipOutputLength; ii += 2)
|
||||
// {
|
||||
// float x = clipOutputItems[ii], y = clipOutputItems[ii + 1];
|
||||
// clippedVerticesItems[s] = x;
|
||||
// clippedVerticesItems[s + 1] = y;
|
||||
// float c0 = x - x3, c1 = y - y3;
|
||||
// float a = (d0 * c0 + d1 * c1) * d;
|
||||
// float b = (d4 * c0 + d2 * c1) * d;
|
||||
// float c = 1 - a - b;
|
||||
// clippedUVsItems[s] = u1 * a + u2 * b + u3 * c;
|
||||
// clippedUVsItems[s + 1] = v1 * a + v2 * b + v3 * c;
|
||||
// s += 2;
|
||||
// }
|
||||
//
|
||||
// s = clippedTriangles.Count;
|
||||
// int[] clippedTrianglesItems = clippedTriangles.Resize(s + 3 * (clipOutputCount - 2)).Items;
|
||||
// clipOutputCount--;
|
||||
// for (int ii = 1; ii < clipOutputCount; ii++)
|
||||
// {
|
||||
// clippedTrianglesItems[s] = index;
|
||||
// clippedTrianglesItems[s + 1] = index + ii;
|
||||
// clippedTrianglesItems[s + 2] = index + ii + 1;
|
||||
// s += 3;
|
||||
// }
|
||||
// index += clipOutputCount + 1;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// float[] clippedVerticesItems = clippedVertices.Resize(s + 3 * 2).Items;
|
||||
// float[] clippedUVsItems = clippedUVs.Resize(s + 3 * 2).Items;
|
||||
// clippedVerticesItems[s] = x1;
|
||||
// clippedVerticesItems[s + 1] = y1;
|
||||
// clippedVerticesItems[s + 2] = x2;
|
||||
// clippedVerticesItems[s + 3] = y2;
|
||||
// clippedVerticesItems[s + 4] = x3;
|
||||
// clippedVerticesItems[s + 5] = y3;
|
||||
//
|
||||
// clippedUVsItems[s] = u1;
|
||||
// clippedUVsItems[s + 1] = v1;
|
||||
// clippedUVsItems[s + 2] = u2;
|
||||
// clippedUVsItems[s + 3] = v2;
|
||||
// clippedUVsItems[s + 4] = u3;
|
||||
// clippedUVsItems[s + 5] = v3;
|
||||
//
|
||||
// s = clippedTriangles.Count;
|
||||
// int[] clippedTrianglesItems = clippedTriangles.Resize(s + 3).Items;
|
||||
// clippedTrianglesItems[s] = index;
|
||||
// clippedTrianglesItems[s + 1] = index + 1;
|
||||
// clippedTrianglesItems[s + 2] = index + 2;
|
||||
// index += 3;
|
||||
// break; //continue outer;
|
||||
// }
|
||||
int s = static_cast<int>(clippedVertices.size());
|
||||
if (clip(x1, y1, x2, y2, x3, y3, *polygons[p], clipOutput))
|
||||
{
|
||||
int clipOutputLength = static_cast<int>(clipOutput.size());
|
||||
if (clipOutputLength == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
float d0 = y2 - y3, d1 = x3 - x2, d2 = x1 - x3, d4 = y3 - y1;
|
||||
float d = 1 / (d0 * d2 + d1 * (y1 - y3));
|
||||
|
||||
int clipOutputCount = clipOutputLength >> 1;
|
||||
clippedVertices.reserve(s + clipOutputCount * 2);
|
||||
_clippedUVs.reserve(s + clipOutputCount * 2);
|
||||
for (int ii = 0; ii < clipOutputLength; ii += 2)
|
||||
{
|
||||
float x = clipOutput[ii], y = clipOutput[ii + 1];
|
||||
clippedVertices[s] = x;
|
||||
clippedVertices[s + 1] = y;
|
||||
float c0 = x - x3, c1 = y - y3;
|
||||
float a = (d0 * c0 + d1 * c1) * d;
|
||||
float b = (d4 * c0 + d2 * c1) * d;
|
||||
float c = 1 - a - b;
|
||||
_clippedUVs[s] = u1 * a + u2 * b + u3 * c;
|
||||
_clippedUVs[s + 1] = v1 * a + v2 * b + v3 * c;
|
||||
s += 2;
|
||||
}
|
||||
|
||||
s = static_cast<int>(clippedTriangles.size());
|
||||
clippedTriangles.reserve(s + 3 * (clipOutputCount - 2));
|
||||
clipOutputCount--;
|
||||
for (int ii = 1; ii < clipOutputCount; ii++)
|
||||
{
|
||||
clippedTriangles[s] = index;
|
||||
clippedTriangles[s + 1] = index + ii;
|
||||
clippedTriangles[s + 2] = index + ii + 1;
|
||||
s += 3;
|
||||
}
|
||||
index += clipOutputCount + 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
clippedVertices.reserve(s + 3 * 2);
|
||||
_clippedUVs.reserve(s + 3 * 2);
|
||||
clippedVertices[s] = x1;
|
||||
clippedVertices[s + 1] = y1;
|
||||
clippedVertices[s + 2] = x2;
|
||||
clippedVertices[s + 3] = y2;
|
||||
clippedVertices[s + 4] = x3;
|
||||
clippedVertices[s + 5] = y3;
|
||||
|
||||
_clippedUVs[s] = u1;
|
||||
_clippedUVs[s + 1] = v1;
|
||||
_clippedUVs[s + 2] = u2;
|
||||
_clippedUVs[s + 3] = v2;
|
||||
_clippedUVs[s + 4] = u3;
|
||||
_clippedUVs[s + 5] = v3;
|
||||
|
||||
s = static_cast<int>(clippedTriangles.size());
|
||||
clippedTriangles.reserve(s + 3);
|
||||
clippedTriangles[s] = index;
|
||||
clippedTriangles[s + 1] = index + 1;
|
||||
clippedTriangles[s + 2] = index + 2;
|
||||
index += 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -201,105 +201,105 @@ namespace Spine
|
||||
{
|
||||
Vector<float> originalOutput = output;
|
||||
bool clipped = false;
|
||||
//
|
||||
// // Avoid copy at the end.
|
||||
// Vector<float> input = NULL;
|
||||
// if (clippingArea.Count % 4 >= 2)
|
||||
// {
|
||||
// input = output;
|
||||
// output = scratch;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// input = scratch;
|
||||
// }
|
||||
//
|
||||
// input.Clear();
|
||||
// input.push_back(x1);
|
||||
// input.push_back(y1);
|
||||
// input.push_back(x2);
|
||||
// input.push_back(y2);
|
||||
// input.push_back(x3);
|
||||
// input.push_back(y3);
|
||||
// input.push_back(x1);
|
||||
// input.push_back(y1);
|
||||
// output.Clear();
|
||||
//
|
||||
// Vector<float> clippingVertices = clippingArea.Items;
|
||||
// int clippingVerticesLast = clippingArea.Count - 4;
|
||||
// for (int i = 0; ; i += 2)
|
||||
// {
|
||||
// float edgeX = clippingVertices[i], edgeY = clippingVertices[i + 1];
|
||||
// float edgeX2 = clippingVertices[i + 2], edgeY2 = clippingVertices[i + 3];
|
||||
// float deltaX = edgeX - edgeX2, deltaY = edgeY - edgeY2;
|
||||
//
|
||||
// Vector<float> inputVertices = input.Items;
|
||||
// int inputVerticesLength = input.Count - 2, outputStart = output.Count;
|
||||
// for (int ii = 0; ii < inputVerticesLength; ii += 2)
|
||||
// {
|
||||
// float inputX = inputVertices[ii], inputY = inputVertices[ii + 1];
|
||||
// float inputX2 = inputVertices[ii + 2], inputY2 = inputVertices[ii + 3];
|
||||
// bool side2 = deltaX * (inputY2 - edgeY2) - deltaY * (inputX2 - edgeX2) > 0;
|
||||
// if (deltaX * (inputY - edgeY2) - deltaY * (inputX - edgeX2) > 0)
|
||||
// {
|
||||
// if (side2)
|
||||
// {
|
||||
// // v1 inside, v2 inside
|
||||
// output.push_back(inputX2);
|
||||
// output.push_back(inputY2);
|
||||
// continue;
|
||||
// }
|
||||
// // v1 inside, v2 outside
|
||||
// float c0 = inputY2 - inputY, c2 = inputX2 - inputX;
|
||||
// float ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / (c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY));
|
||||
// output.push_back(edgeX + (edgeX2 - edgeX) * ua);
|
||||
// output.push_back(edgeY + (edgeY2 - edgeY) * ua);
|
||||
// }
|
||||
// else if (side2)
|
||||
// {
|
||||
// // v1 outside, v2 inside
|
||||
// float c0 = inputY2 - inputY, c2 = inputX2 - inputX;
|
||||
// float ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / (c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY));
|
||||
// output.push_back(edgeX + (edgeX2 - edgeX) * ua);
|
||||
// output.push_back(edgeY + (edgeY2 - edgeY) * ua);
|
||||
// output.push_back(inputX2);
|
||||
// output.push_back(inputY2);
|
||||
// }
|
||||
// clipped = true;
|
||||
// }
|
||||
//
|
||||
// if (outputStart == output.Count)
|
||||
// {
|
||||
// // All edges outside.
|
||||
// originalOutput.Clear();
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// output.push_back(output.Items[0]);
|
||||
// output.push_back(output.Items[1]);
|
||||
//
|
||||
// if (i == clippingVerticesLast)
|
||||
// {
|
||||
// break;
|
||||
// }
|
||||
// var temp = output;
|
||||
// output = input;
|
||||
// output.Clear();
|
||||
// input = temp;
|
||||
// }
|
||||
//
|
||||
// if (originalOutput != output)
|
||||
// {
|
||||
// originalOutput.Clear();
|
||||
// for (int i = 0, n = output.Count - 2; i < n; i++)
|
||||
// {
|
||||
// originalOutput.push_back(output.Items[i]);
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// originalOutput.Resize(originalOutput.Count - 2);
|
||||
// }
|
||||
|
||||
// Avoid copy at the end.
|
||||
Vector<float> input;
|
||||
if (clippingArea.size() % 4 >= 2)
|
||||
{
|
||||
input = output;
|
||||
output = _scratch;
|
||||
}
|
||||
else
|
||||
{
|
||||
input = _scratch;
|
||||
}
|
||||
|
||||
input.clear();
|
||||
input.push_back(x1);
|
||||
input.push_back(y1);
|
||||
input.push_back(x2);
|
||||
input.push_back(y2);
|
||||
input.push_back(x3);
|
||||
input.push_back(y3);
|
||||
input.push_back(x1);
|
||||
input.push_back(y1);
|
||||
output.clear();
|
||||
|
||||
Vector<float> clippingVertices = clippingArea;
|
||||
int clippingVerticesLast = static_cast<int>(clippingArea.size()) - 4;
|
||||
for (int i = 0; ; i += 2)
|
||||
{
|
||||
float edgeX = clippingVertices[i], edgeY = clippingVertices[i + 1];
|
||||
float edgeX2 = clippingVertices[i + 2], edgeY2 = clippingVertices[i + 3];
|
||||
float deltaX = edgeX - edgeX2, deltaY = edgeY - edgeY2;
|
||||
|
||||
Vector<float> inputVertices = input;
|
||||
int inputVerticesLength = static_cast<int>(input.size()) - 2, outputStart = static_cast<int>(output.size());
|
||||
for (int ii = 0; ii < inputVerticesLength; ii += 2)
|
||||
{
|
||||
float inputX = inputVertices[ii], inputY = inputVertices[ii + 1];
|
||||
float inputX2 = inputVertices[ii + 2], inputY2 = inputVertices[ii + 3];
|
||||
bool side2 = deltaX * (inputY2 - edgeY2) - deltaY * (inputX2 - edgeX2) > 0;
|
||||
if (deltaX * (inputY - edgeY2) - deltaY * (inputX - edgeX2) > 0)
|
||||
{
|
||||
if (side2)
|
||||
{
|
||||
// v1 inside, v2 inside
|
||||
output.push_back(inputX2);
|
||||
output.push_back(inputY2);
|
||||
continue;
|
||||
}
|
||||
// v1 inside, v2 outside
|
||||
float c0 = inputY2 - inputY, c2 = inputX2 - inputX;
|
||||
float ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / (c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY));
|
||||
output.push_back(edgeX + (edgeX2 - edgeX) * ua);
|
||||
output.push_back(edgeY + (edgeY2 - edgeY) * ua);
|
||||
}
|
||||
else if (side2)
|
||||
{
|
||||
// v1 outside, v2 inside
|
||||
float c0 = inputY2 - inputY, c2 = inputX2 - inputX;
|
||||
float ua = (c2 * (edgeY - inputY) - c0 * (edgeX - inputX)) / (c0 * (edgeX2 - edgeX) - c2 * (edgeY2 - edgeY));
|
||||
output.push_back(edgeX + (edgeX2 - edgeX) * ua);
|
||||
output.push_back(edgeY + (edgeY2 - edgeY) * ua);
|
||||
output.push_back(inputX2);
|
||||
output.push_back(inputY2);
|
||||
}
|
||||
clipped = true;
|
||||
}
|
||||
|
||||
if (outputStart == output.size())
|
||||
{
|
||||
// All edges outside.
|
||||
originalOutput.clear();
|
||||
return true;
|
||||
}
|
||||
|
||||
output.push_back(output[0]);
|
||||
output.push_back(output[1]);
|
||||
|
||||
if (i == clippingVerticesLast)
|
||||
{
|
||||
break;
|
||||
}
|
||||
Vector<float> temp = output;
|
||||
output = input;
|
||||
output.clear();
|
||||
input = temp;
|
||||
}
|
||||
|
||||
if (originalOutput != output)
|
||||
{
|
||||
originalOutput.clear();
|
||||
for (int i = 0, n = static_cast<int>(output.size()) - 2; i < n; ++i)
|
||||
{
|
||||
originalOutput.push_back(output[i]);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
originalOutput.reserve(originalOutput.size() - 2);
|
||||
}
|
||||
|
||||
return clipped;
|
||||
}
|
||||
|
||||
@ -37,6 +37,8 @@
|
||||
#include <spine/TimelineType.h>
|
||||
#include <spine/Slot.h>
|
||||
#include <spine/SlotData.h>
|
||||
#include <spine/TransformConstraint.h>
|
||||
#include <spine/TransformConstraintData.h>
|
||||
|
||||
namespace Spine
|
||||
{
|
||||
@ -53,13 +55,95 @@ namespace Spine
|
||||
const int TransformConstraintTimeline::SCALE = 3;
|
||||
const int TransformConstraintTimeline::SHEAR = 4;
|
||||
|
||||
TransformConstraintTimeline::TransformConstraintTimeline(int frameCount) : CurveTimeline(frameCount), _transformConstraintIndex(0)
|
||||
{
|
||||
_frames.reserve(frameCount * ENTRIES);
|
||||
}
|
||||
|
||||
void TransformConstraintTimeline::apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>& events, float alpha, MixPose pose, MixDirection direction)
|
||||
{
|
||||
// TODO
|
||||
TransformConstraint* constraintP = skeleton._transformConstraints[_transformConstraintIndex];
|
||||
TransformConstraint& constraint = *constraintP;
|
||||
|
||||
if (time < _frames[0])
|
||||
{
|
||||
switch (pose)
|
||||
{
|
||||
case MixPose_Setup:
|
||||
constraint._rotateMix = constraint._data._rotateMix;
|
||||
constraint._translateMix = constraint._data._translateMix;
|
||||
constraint._scaleMix = constraint._data._scaleMix;
|
||||
constraint._shearMix = constraint._data._shearMix;
|
||||
return;
|
||||
case MixPose_Current:
|
||||
constraint._rotateMix += (constraint._data._rotateMix - constraint._rotateMix) * alpha;
|
||||
constraint._translateMix += (constraint._data._translateMix - constraint._translateMix) * alpha;
|
||||
constraint._scaleMix += (constraint._data._scaleMix - constraint._scaleMix) * alpha;
|
||||
constraint._shearMix += (constraint._data._shearMix - constraint._shearMix) * alpha;
|
||||
return;
|
||||
case MixPose_CurrentLayered:
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
float rotate, translate, scale, shear;
|
||||
if (time >= _frames[_frames.size() - ENTRIES])
|
||||
{
|
||||
// Time is after last frame.
|
||||
int i = static_cast<int>(_frames.size());
|
||||
rotate = _frames[i + PREV_ROTATE];
|
||||
translate = _frames[i + PREV_TRANSLATE];
|
||||
scale = _frames[i + PREV_SCALE];
|
||||
shear = _frames[i + PREV_SHEAR];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Interpolate between the previous frame and the current frame.
|
||||
int frame = Animation::binarySearch(_frames, time, ENTRIES);
|
||||
rotate = _frames[frame + PREV_ROTATE];
|
||||
translate = _frames[frame + PREV_TRANSLATE];
|
||||
scale = _frames[frame + PREV_SCALE];
|
||||
shear = _frames[frame + PREV_SHEAR];
|
||||
float frameTime = _frames[frame];
|
||||
float percent = getCurvePercent(frame / ENTRIES - 1,
|
||||
1 - (time - frameTime) / (_frames[frame + PREV_TIME] - frameTime));
|
||||
|
||||
rotate += (_frames[frame + ROTATE] - rotate) * percent;
|
||||
translate += (_frames[frame + TRANSLATE] - translate) * percent;
|
||||
scale += (_frames[frame + SCALE] - scale) * percent;
|
||||
shear += (_frames[frame + SHEAR] - shear) * percent;
|
||||
}
|
||||
|
||||
if (pose == MixPose_Setup)
|
||||
{
|
||||
TransformConstraintData& data = constraint._data;
|
||||
constraint._rotateMix = data._rotateMix + (rotate - data._rotateMix) * alpha;
|
||||
constraint._translateMix = data._translateMix + (translate - data._translateMix) * alpha;
|
||||
constraint._scaleMix = data._scaleMix + (scale - data._scaleMix) * alpha;
|
||||
constraint._shearMix = data._shearMix + (shear - data._shearMix) * alpha;
|
||||
}
|
||||
else
|
||||
{
|
||||
constraint._rotateMix += (rotate - constraint._rotateMix) * alpha;
|
||||
constraint._translateMix += (translate - constraint._translateMix) * alpha;
|
||||
constraint._scaleMix += (scale - constraint._scaleMix) * alpha;
|
||||
constraint._shearMix += (shear - constraint._shearMix) * alpha;
|
||||
}
|
||||
}
|
||||
|
||||
int TransformConstraintTimeline::getPropertyId()
|
||||
{
|
||||
return ((int)TimelineType_TransformConstraint << 24) + _transformConstraintIndex;
|
||||
}
|
||||
|
||||
void TransformConstraintTimeline::setFrame(int frameIndex, float time, float rotateMix, float translateMix, float scaleMix, float shearMix)
|
||||
{
|
||||
frameIndex *= ENTRIES;
|
||||
_frames[frameIndex] = time;
|
||||
_frames[frameIndex + ROTATE] = rotateMix;
|
||||
_frames[frameIndex + TRANSLATE] = translateMix;
|
||||
_frames[frameIndex + SCALE] = scaleMix;
|
||||
_frames[frameIndex + SHEAR] = shearMix;
|
||||
}
|
||||
}
|
||||
|
||||
@ -37,18 +37,90 @@
|
||||
#include <spine/TimelineType.h>
|
||||
#include <spine/Slot.h>
|
||||
#include <spine/SlotData.h>
|
||||
#include <spine/Bone.h>
|
||||
#include <spine/BoneData.h>
|
||||
|
||||
namespace Spine
|
||||
{
|
||||
RTTI_IMPL(TranslateTimeline, CurveTimeline);
|
||||
|
||||
const int TranslateTimeline::ENTRIES = 3;
|
||||
const int TranslateTimeline::PREV_TIME = -3;
|
||||
const int TranslateTimeline::PREV_X = -2;
|
||||
const int TranslateTimeline::PREV_Y = -1;
|
||||
const int TranslateTimeline::X = 1;
|
||||
const int TranslateTimeline::Y = 2;
|
||||
|
||||
TranslateTimeline::TranslateTimeline(int frameCount) : CurveTimeline(frameCount), _boneIndex(0)
|
||||
{
|
||||
_frames.reserve(frameCount * ENTRIES);
|
||||
}
|
||||
|
||||
void TranslateTimeline::apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>& events, float alpha, MixPose pose, MixDirection direction)
|
||||
{
|
||||
// TODO
|
||||
Bone* boneP = skeleton._bones[_boneIndex];
|
||||
Bone& bone = *boneP;
|
||||
|
||||
if (time < _frames[0])
|
||||
{
|
||||
switch (pose)
|
||||
{
|
||||
case MixPose_Setup:
|
||||
bone._x = bone._data._x;
|
||||
bone._y = bone._data._y;
|
||||
return;
|
||||
case MixPose_Current:
|
||||
bone._x += (bone._data._x - bone._x) * alpha;
|
||||
bone._y += (bone._data._y - bone._y) * alpha;
|
||||
return;
|
||||
case MixPose_CurrentLayered:
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
float x, y;
|
||||
if (time >= _frames[_frames.size() - ENTRIES])
|
||||
{
|
||||
// Time is after last frame.
|
||||
x = _frames[_frames.size() + PREV_X];
|
||||
y = _frames[_frames.size() + PREV_Y];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Interpolate between the previous frame and the current frame.
|
||||
int frame = Animation::binarySearch(_frames, time, ENTRIES);
|
||||
x = _frames[frame + PREV_X];
|
||||
y = _frames[frame + PREV_Y];
|
||||
float frameTime = _frames[frame];
|
||||
float percent = getCurvePercent(frame / ENTRIES - 1, 1 - (time - frameTime) / (_frames[frame + PREV_TIME] - frameTime));
|
||||
|
||||
x += (_frames[frame + X] - x) * percent;
|
||||
y += (_frames[frame + Y] - y) * percent;
|
||||
}
|
||||
|
||||
if (pose == MixPose_Setup)
|
||||
{
|
||||
bone._x = bone._data._x + x * alpha;
|
||||
bone._y = bone._data._y + y * alpha;
|
||||
}
|
||||
else
|
||||
{
|
||||
bone._x += (bone._data._x + x - bone._x) * alpha;
|
||||
bone._y += (bone._data._y + y - bone._y) * alpha;
|
||||
}
|
||||
}
|
||||
|
||||
int TranslateTimeline::getPropertyId()
|
||||
{
|
||||
return ((int)TimelineType_Translate << 24) + _boneIndex;
|
||||
}
|
||||
|
||||
void TranslateTimeline::setFrame(int frameIndex, float time, float x, float y)
|
||||
{
|
||||
frameIndex *= ENTRIES;
|
||||
_frames[frameIndex] = time;
|
||||
_frames[frameIndex + X] = x;
|
||||
_frames[frameIndex + Y] = y;
|
||||
}
|
||||
}
|
||||
|
||||
@ -42,13 +42,169 @@ namespace Spine
|
||||
{
|
||||
RTTI_IMPL(TwoColorTimeline, CurveTimeline);
|
||||
|
||||
const int TwoColorTimeline::ENTRIES = 8;
|
||||
const int TwoColorTimeline::PREV_TIME = -8;
|
||||
const int TwoColorTimeline::PREV_R = -7;
|
||||
const int TwoColorTimeline::PREV_G = -6;
|
||||
const int TwoColorTimeline::PREV_B = -5;
|
||||
const int TwoColorTimeline::PREV_A = -4;
|
||||
const int TwoColorTimeline::PREV_R2 = -3;
|
||||
const int TwoColorTimeline::PREV_G2 = -2;
|
||||
const int TwoColorTimeline::PREV_B2 = -1;
|
||||
const int TwoColorTimeline::R = 1;
|
||||
const int TwoColorTimeline::G = 2;
|
||||
const int TwoColorTimeline::B = 3;
|
||||
const int TwoColorTimeline::A = 4;
|
||||
const int TwoColorTimeline::R2 = 5;
|
||||
const int TwoColorTimeline::G2 = 6;
|
||||
const int TwoColorTimeline::B2 = 7;
|
||||
|
||||
TwoColorTimeline::TwoColorTimeline(int frameCount) : CurveTimeline(frameCount)
|
||||
{
|
||||
_frames.reserve(frameCount * ENTRIES);
|
||||
}
|
||||
|
||||
void TwoColorTimeline::apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>& events, float alpha, MixPose pose, MixDirection direction)
|
||||
{
|
||||
// TODO
|
||||
Slot* slotP = skeleton._slots[_slotIndex];
|
||||
Slot& slot = *slotP;
|
||||
|
||||
if (time < _frames[0])
|
||||
{
|
||||
// Time is before first frame.
|
||||
switch (pose)
|
||||
{
|
||||
case MixPose_Setup:
|
||||
slot._r = slot._data._r;
|
||||
slot._g = slot._data._g;
|
||||
slot._b = slot._data._b;
|
||||
slot._a = slot._data._a;
|
||||
slot._r2 = slot._data._r2;
|
||||
slot._g2 = slot._data._g2;
|
||||
slot._b2 = slot._data._b2;
|
||||
return;
|
||||
case MixPose_Current:
|
||||
slot._r += (slot._r - slot._data._r) * alpha;
|
||||
slot._g += (slot._g - slot._data._g) * alpha;
|
||||
slot._b += (slot._b - slot._data._b) * alpha;
|
||||
slot._a += (slot._a - slot._data._a) * alpha;
|
||||
slot._r2 += (slot._r2 - slot._data._r2) * alpha;
|
||||
slot._g2 += (slot._g2 - slot._data._g2) * alpha;
|
||||
slot._b2 += (slot._b2 - slot._data._b2) * alpha;
|
||||
return;
|
||||
case MixPose_CurrentLayered:
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
float r, g, b, a, r2, g2, b2;
|
||||
if (time >= _frames[_frames.size() - ENTRIES])
|
||||
{
|
||||
// Time is after last frame.
|
||||
int i = static_cast<int>(_frames.size());
|
||||
r = _frames[i + PREV_R];
|
||||
g = _frames[i + PREV_G];
|
||||
b = _frames[i + PREV_B];
|
||||
a = _frames[i + PREV_A];
|
||||
r2 = _frames[i + PREV_R2];
|
||||
g2 = _frames[i + PREV_G2];
|
||||
b2 = _frames[i + PREV_B2];
|
||||
}
|
||||
else
|
||||
{
|
||||
// Interpolate between the previous frame and the current frame.
|
||||
int frame = Animation::binarySearch(_frames, time, ENTRIES);
|
||||
r = _frames[frame + PREV_R];
|
||||
g = _frames[frame + PREV_G];
|
||||
b = _frames[frame + PREV_B];
|
||||
a = _frames[frame + PREV_A];
|
||||
r2 = _frames[frame + PREV_R2];
|
||||
g2 = _frames[frame + PREV_G2];
|
||||
b2 = _frames[frame + PREV_B2];
|
||||
float frameTime = _frames[frame];
|
||||
float percent = getCurvePercent(frame / ENTRIES - 1,
|
||||
1 - (time - frameTime) / (_frames[frame + PREV_TIME] - frameTime));
|
||||
|
||||
r += (_frames[frame + R] - r) * percent;
|
||||
g += (_frames[frame + G] - g) * percent;
|
||||
b += (_frames[frame + B] - b) * percent;
|
||||
a += (_frames[frame + A] - a) * percent;
|
||||
r2 += (_frames[frame + R2] - r2) * percent;
|
||||
g2 += (_frames[frame + G2] - g2) * percent;
|
||||
b2 += (_frames[frame + B2] - b2) * percent;
|
||||
}
|
||||
|
||||
if (alpha == 1)
|
||||
{
|
||||
slot._r = r;
|
||||
slot._g = g;
|
||||
slot._b = b;
|
||||
slot._a = a;
|
||||
slot._r2 = r2;
|
||||
slot._g2 = g2;
|
||||
slot._b2 = b2;
|
||||
}
|
||||
else
|
||||
{
|
||||
float br, bg, bb, ba, br2, bg2, bb2;
|
||||
if (pose == MixPose_Setup)
|
||||
{
|
||||
br = slot._data._r;
|
||||
bg = slot._data._g;
|
||||
bb = slot._data._b;
|
||||
ba = slot._data._a;
|
||||
br2 = slot._data._r2;
|
||||
bg2 = slot._data._g2;
|
||||
bb2 = slot._data._b2;
|
||||
}
|
||||
else
|
||||
{
|
||||
br = slot._r;
|
||||
bg = slot._g;
|
||||
bb = slot._b;
|
||||
ba = slot._a;
|
||||
br2 = slot._r2;
|
||||
bg2 = slot._g2;
|
||||
bb2 = slot._b2;
|
||||
}
|
||||
|
||||
slot._r = br + ((r - br) * alpha);
|
||||
slot._g = bg + ((g - bg) * alpha);
|
||||
slot._b = bb + ((b - bb) * alpha);
|
||||
slot._a = ba + ((a - ba) * alpha);
|
||||
slot._r2 = br2 + ((r2 - br2) * alpha);
|
||||
slot._g2 = bg2 + ((g2 - bg2) * alpha);
|
||||
slot._b2 = bb2 + ((b2 - bb2) * alpha);
|
||||
}
|
||||
}
|
||||
|
||||
int TwoColorTimeline::getPropertyId()
|
||||
{
|
||||
return ((int)TimelineType_TwoColor << 24) + _slotIndex;
|
||||
}
|
||||
|
||||
void TwoColorTimeline::setFrame(int frameIndex, float time, float r, float g, float b, float a, float r2, float g2, float b2)
|
||||
{
|
||||
frameIndex *= ENTRIES;
|
||||
_frames[frameIndex] = time;
|
||||
_frames[frameIndex + R] = r;
|
||||
_frames[frameIndex + G] = g;
|
||||
_frames[frameIndex + B] = b;
|
||||
_frames[frameIndex + A] = a;
|
||||
_frames[frameIndex + R2] = r2;
|
||||
_frames[frameIndex + G2] = g2;
|
||||
_frames[frameIndex + B2] = b2;
|
||||
}
|
||||
|
||||
int TwoColorTimeline::getSlotIndex()
|
||||
{
|
||||
return _slotIndex;
|
||||
}
|
||||
|
||||
void TwoColorTimeline::setSlotIndex(int inValue)
|
||||
{
|
||||
assert(inValue >= 0);
|
||||
_slotIndex = inValue;
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user