mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2026-02-04 14:24:53 +08:00
[all] Source clean up, formatting, and tabs for indentation.
This commit is contained in:
parent
2fa85fc1c6
commit
842dffbd83
@ -54,7 +54,7 @@ package spine.animation {
|
|||||||
internal var queue : EventQueue;
|
internal var queue : EventQueue;
|
||||||
internal var propertyIDs : Dictionary = new Dictionary();
|
internal var propertyIDs : Dictionary = new Dictionary();
|
||||||
internal var mixingTo : Vector.<TrackEntry> = new Vector.<TrackEntry>();
|
internal var mixingTo : Vector.<TrackEntry> = new Vector.<TrackEntry>();
|
||||||
internal var animationsChanged : Boolean;
|
internal var animationsChanged : Boolean;
|
||||||
public var timeScale : Number = 1;
|
public var timeScale : Number = 1;
|
||||||
internal var trackEntryPool : Pool;
|
internal var trackEntryPool : Pool;
|
||||||
|
|
||||||
@ -131,7 +131,7 @@ package spine.animation {
|
|||||||
if (from == null) return true;
|
if (from == null) return true;
|
||||||
|
|
||||||
var finished : Boolean = updateMixingFrom(from, delta);
|
var finished : Boolean = updateMixingFrom(from, delta);
|
||||||
|
|
||||||
from.animationLast = from.nextAnimationLast;
|
from.animationLast = from.nextAnimationLast;
|
||||||
from.trackLast = from.nextTrackLast;
|
from.trackLast = from.nextTrackLast;
|
||||||
|
|
||||||
@ -142,11 +142,11 @@ package spine.animation {
|
|||||||
to.mixingFrom = from.mixingFrom;
|
to.mixingFrom = from.mixingFrom;
|
||||||
if (from.mixingFrom != null) from.mixingFrom.mixingTo = to;
|
if (from.mixingFrom != null) from.mixingFrom.mixingTo = to;
|
||||||
to.interruptAlpha = from.interruptAlpha;
|
to.interruptAlpha = from.interruptAlpha;
|
||||||
queue.end(from);
|
queue.end(from);
|
||||||
}
|
}
|
||||||
return finished;
|
return finished;
|
||||||
}
|
}
|
||||||
|
|
||||||
from.trackTime += delta * from.timeScale;
|
from.trackTime += delta * from.timeScale;
|
||||||
to.mixTime += delta;
|
to.mixTime += delta;
|
||||||
return false;
|
return false;
|
||||||
@ -182,11 +182,11 @@ package spine.animation {
|
|||||||
Timeline(timelines[ii]).apply(skeleton, animationLast, animationTime, events, mix, blend, MixDirection.In);
|
Timeline(timelines[ii]).apply(skeleton, animationLast, animationTime, events, mix, blend, MixDirection.In);
|
||||||
} else {
|
} else {
|
||||||
var timelineMode : Vector.<int> = current.timelineMode;
|
var timelineMode : Vector.<int> = current.timelineMode;
|
||||||
|
|
||||||
var firstFrame : Boolean = current.timelinesRotation.length == 0;
|
var firstFrame : Boolean = current.timelinesRotation.length == 0;
|
||||||
if (firstFrame) current.timelinesRotation.length = timelineCount << 1;
|
if (firstFrame) current.timelinesRotation.length = timelineCount << 1;
|
||||||
var timelinesRotation : Vector.<Number> = current.timelinesRotation;
|
var timelinesRotation : Vector.<Number> = current.timelinesRotation;
|
||||||
|
|
||||||
for (ii = 0; ii < timelineCount; ii++) {
|
for (ii = 0; ii < timelineCount; ii++) {
|
||||||
var timeline : Timeline = timelines[ii];
|
var timeline : Timeline = timelines[ii];
|
||||||
var timelineBlend : MixBlend = (timelineMode[ii] & (NOT_LAST - 1)) == SUBSEQUENT ? blend : MixBlend.setup;
|
var timelineBlend : MixBlend = (timelineMode[ii] & (NOT_LAST - 1)) == SUBSEQUENT ? blend : MixBlend.setup;
|
||||||
@ -234,11 +234,11 @@ package spine.animation {
|
|||||||
} else {
|
} else {
|
||||||
var timelineMode : Vector.<int> = from.timelineMode;
|
var timelineMode : Vector.<int> = from.timelineMode;
|
||||||
var timelineHoldMix : Vector.<TrackEntry> = from.timelineHoldMix;
|
var timelineHoldMix : Vector.<TrackEntry> = from.timelineHoldMix;
|
||||||
|
|
||||||
var firstFrame : Boolean = from.timelinesRotation.length == 0;
|
var firstFrame : Boolean = from.timelinesRotation.length == 0;
|
||||||
if (firstFrame) from.timelinesRotation.length = timelineCount << 1;
|
if (firstFrame) from.timelinesRotation.length = timelineCount << 1;
|
||||||
var timelinesRotation : Vector.<Number> = from.timelinesRotation;
|
var timelinesRotation : Vector.<Number> = from.timelinesRotation;
|
||||||
|
|
||||||
from.totalAlpha = 0;
|
from.totalAlpha = 0;
|
||||||
for (i = 0; i < timelineCount; i++) {
|
for (i = 0; i < timelineCount; i++) {
|
||||||
var timeline : Timeline = timelines[i];
|
var timeline : Timeline = timelines[i];
|
||||||
@ -264,7 +264,7 @@ package spine.animation {
|
|||||||
alpha = alphaHold;
|
alpha = alphaHold;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
timelineBlend = MixBlend.setup;
|
timelineBlend = MixBlend.setup;
|
||||||
var holdMix : TrackEntry = timelineHoldMix[i];
|
var holdMix : TrackEntry = timelineHoldMix[i];
|
||||||
alpha = alphaHold * Math.max(0, 1 - holdMix.mixTime / holdMix.mixDuration);
|
alpha = alphaHold * Math.max(0, 1 - holdMix.mixTime / holdMix.mixDuration);
|
||||||
break;
|
break;
|
||||||
@ -272,7 +272,7 @@ package spine.animation {
|
|||||||
from.totalAlpha += alpha;
|
from.totalAlpha += alpha;
|
||||||
if (timeline is RotateTimeline)
|
if (timeline is RotateTimeline)
|
||||||
applyRotateTimeline(timeline, skeleton, animationTime, alpha, timelineBlend, timelinesRotation, i << 1, firstFrame);
|
applyRotateTimeline(timeline, skeleton, animationTime, alpha, timelineBlend, timelinesRotation, i << 1, firstFrame);
|
||||||
else {
|
else {
|
||||||
if (timelineBlend == MixBlend.setup) {
|
if (timelineBlend == MixBlend.setup) {
|
||||||
if (timeline is AttachmentTimeline) {
|
if (timeline is AttachmentTimeline) {
|
||||||
if (attachments || ((timelineMode[i] & NOT_LAST) == NOT_LAST)) direction = MixDirection.In;
|
if (attachments || ((timelineMode[i] & NOT_LAST) == NOT_LAST)) direction = MixDirection.In;
|
||||||
@ -282,14 +282,14 @@ package spine.animation {
|
|||||||
}
|
}
|
||||||
timeline.apply(skeleton, animationLast, animationTime, events, alpha, timelineBlend, direction);
|
timeline.apply(skeleton, animationLast, animationTime, events, alpha, timelineBlend, direction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (to.mixDuration > 0) queueEvents(from, animationTime);
|
if (to.mixDuration > 0) queueEvents(from, animationTime);
|
||||||
this.events.length = 0;
|
this.events.length = 0;
|
||||||
from.nextAnimationLast = animationTime;
|
from.nextAnimationLast = animationTime;
|
||||||
from.nextTrackLast = from.trackTime;
|
from.nextTrackLast = from.trackTime;
|
||||||
|
|
||||||
return mix;
|
return mix;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -315,8 +315,8 @@ package spine.animation {
|
|||||||
case MixBlend.first:
|
case MixBlend.first:
|
||||||
r1 = bone.rotation;
|
r1 = bone.rotation;
|
||||||
r2 = bone.data.rotation;
|
r2 = bone.data.rotation;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
r1 = blend == MixBlend.setup ? bone.data.rotation : bone.rotation;
|
r1 = blend == MixBlend.setup ? bone.data.rotation : bone.rotation;
|
||||||
if (time >= frames[frames.length - RotateTimeline.ENTRIES]) // Time is after last frame.
|
if (time >= frames[frames.length - RotateTimeline.ENTRIES]) // Time is after last frame.
|
||||||
r2 = bone.data.rotation + frames[frames.length + RotateTimeline.PREV_ROTATION];
|
r2 = bone.data.rotation + frames[frames.length + RotateTimeline.PREV_ROTATION];
|
||||||
@ -326,7 +326,7 @@ package spine.animation {
|
|||||||
var prevRotation : Number = frames[frame + RotateTimeline.PREV_ROTATION];
|
var prevRotation : Number = frames[frame + RotateTimeline.PREV_ROTATION];
|
||||||
var frameTime : Number = frames[frame];
|
var frameTime : Number = frames[frame];
|
||||||
var percent : Number = rotateTimeline.getCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame + RotateTimeline.PREV_TIME] - frameTime));
|
var percent : Number = rotateTimeline.getCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame + RotateTimeline.PREV_TIME] - frameTime));
|
||||||
|
|
||||||
r2 = frames[frame + RotateTimeline.ROTATION] - prevRotation;
|
r2 = frames[frame + RotateTimeline.ROTATION] - prevRotation;
|
||||||
r2 -= (16384 - int((16384.499999999996 - r2 / 360))) * 360;
|
r2 -= (16384 - int((16384.499999999996 - r2 / 360))) * 360;
|
||||||
r2 = prevRotation + r2 * percent + bone.data.rotation;
|
r2 = prevRotation + r2 * percent + bone.data.rotation;
|
||||||
@ -334,12 +334,12 @@ package spine.animation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Mix between rotations using the direction of the shortest route on the first frame while detecting crosses.
|
// Mix between rotations using the direction of the shortest route on the first frame while detecting crosses.
|
||||||
var total : Number, diff : Number = r2 - r1;
|
var total : Number, diff : Number = r2 - r1;
|
||||||
diff -= (16384 - int((16384.499999999996 - diff / 360))) * 360;
|
diff -= (16384 - int((16384.499999999996 - diff / 360))) * 360;
|
||||||
if (diff == 0) {
|
if (diff == 0) {
|
||||||
total = timelinesRotation[i];
|
total = timelinesRotation[i];
|
||||||
} else {
|
} else {
|
||||||
var lastTotal : Number, lastDiff : Number;
|
var lastTotal : Number, lastDiff : Number;
|
||||||
if (firstFrame) {
|
if (firstFrame) {
|
||||||
lastTotal = 0;
|
lastTotal = 0;
|
||||||
@ -378,8 +378,8 @@ package spine.animation {
|
|||||||
if (event.time < trackLastWrapped) break;
|
if (event.time < trackLastWrapped) break;
|
||||||
if (event.time > animationEnd) continue; // Discard events outside animation start/end.
|
if (event.time > animationEnd) continue; // Discard events outside animation start/end.
|
||||||
queue.event(entry, event);
|
queue.event(entry, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Queue complete if completed a loop iteration or the animation.
|
// Queue complete if completed a loop iteration or the animation.
|
||||||
var complete:Boolean;
|
var complete:Boolean;
|
||||||
if (entry.loop)
|
if (entry.loop)
|
||||||
@ -433,20 +433,20 @@ package spine.animation {
|
|||||||
private function setCurrent(index : int, current : TrackEntry, interrupt : Boolean) : void {
|
private function setCurrent(index : int, current : TrackEntry, interrupt : Boolean) : void {
|
||||||
var from : TrackEntry = expandToIndex(index);
|
var from : TrackEntry = expandToIndex(index);
|
||||||
tracks[index] = current;
|
tracks[index] = current;
|
||||||
|
|
||||||
if (from != null) {
|
if (from != null) {
|
||||||
if (interrupt) queue.interrupt(from);
|
if (interrupt) queue.interrupt(from);
|
||||||
current.mixingFrom = from;
|
current.mixingFrom = from;
|
||||||
from.mixingTo = current;
|
from.mixingTo = current;
|
||||||
current.mixTime = 0;
|
current.mixTime = 0;
|
||||||
|
|
||||||
// Store the interrupted mix percentage.
|
// Store the interrupted mix percentage.
|
||||||
if (from.mixingFrom != null && from.mixDuration > 0)
|
if (from.mixingFrom != null && from.mixDuration > 0)
|
||||||
current.interruptAlpha *= Math.min(1, from.mixTime / from.mixDuration);
|
current.interruptAlpha *= Math.min(1, from.mixTime / from.mixDuration);
|
||||||
|
|
||||||
from.timelinesRotation.length = 0; // Reset rotation for mixing out, in case entry was mixed in.
|
from.timelinesRotation.length = 0; // Reset rotation for mixing out, in case entry was mixed in.
|
||||||
}
|
}
|
||||||
|
|
||||||
queue.start(current);
|
queue.start(current);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -504,9 +504,9 @@ package spine.animation {
|
|||||||
var duration : Number = last.animationEnd - last.animationStart;
|
var duration : Number = last.animationEnd - last.animationStart;
|
||||||
if (duration != 0) {
|
if (duration != 0) {
|
||||||
if (last.loop)
|
if (last.loop)
|
||||||
delay += duration * (1 + (int)(last.trackTime / duration));
|
delay += duration * (1 + (int)(last.trackTime / duration));
|
||||||
else
|
else
|
||||||
delay += Math.max(duration, last.trackTime);
|
delay += Math.max(duration, last.trackTime);
|
||||||
} else
|
} else
|
||||||
delay = last.trackTime;
|
delay = last.trackTime;
|
||||||
}
|
}
|
||||||
@ -590,7 +590,7 @@ package spine.animation {
|
|||||||
private function _animationsChanged() : void {
|
private function _animationsChanged() : void {
|
||||||
animationsChanged = false;
|
animationsChanged = false;
|
||||||
|
|
||||||
propertyIDs = new Dictionary();
|
propertyIDs = new Dictionary();
|
||||||
var i : int = 0;
|
var i : int = 0;
|
||||||
var n: int = 0;
|
var n: int = 0;
|
||||||
var entry : TrackEntry = null;
|
var entry : TrackEntry = null;
|
||||||
@ -601,7 +601,7 @@ package spine.animation {
|
|||||||
entry = entry.mixingFrom;
|
entry = entry.mixingFrom;
|
||||||
do {
|
do {
|
||||||
if (entry.mixingTo == null || entry.mixBlend != MixBlend.add) computeHold(entry);
|
if (entry.mixingTo == null || entry.mixBlend != MixBlend.add) computeHold(entry);
|
||||||
entry = entry.mixingTo;
|
entry = entry.mixingTo;
|
||||||
} while (entry != null);
|
} while (entry != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -614,7 +614,7 @@ package spine.animation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private function computeNotLast (entry: TrackEntry) : void {
|
private function computeNotLast (entry: TrackEntry) : void {
|
||||||
var timelines : Vector.<Timeline> = entry.animation.timelines;
|
var timelines : Vector.<Timeline> = entry.animation.timelines;
|
||||||
var timelinesCount : int = entry.animation.timelines.length;
|
var timelinesCount : int = entry.animation.timelines.length;
|
||||||
@ -636,19 +636,19 @@ package spine.animation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private function computeHold (entry: TrackEntry) : void {
|
private function computeHold (entry: TrackEntry) : void {
|
||||||
var to: TrackEntry = entry.mixingTo;
|
var to: TrackEntry = entry.mixingTo;
|
||||||
var timelines : Vector.<Timeline> = entry.animation.timelines;
|
var timelines : Vector.<Timeline> = entry.animation.timelines;
|
||||||
var timelinesCount : int = entry.animation.timelines.length;
|
var timelinesCount : int = entry.animation.timelines.length;
|
||||||
var timelineMode : Vector.<int> = entry.timelineMode;
|
var timelineMode : Vector.<int> = entry.timelineMode;
|
||||||
timelineMode.length = timelinesCount;
|
timelineMode.length = timelinesCount;
|
||||||
var timelineHoldMix : Vector.<TrackEntry> = entry.timelineHoldMix;
|
var timelineHoldMix : Vector.<TrackEntry> = entry.timelineHoldMix;
|
||||||
timelineHoldMix.length = 0;
|
timelineHoldMix.length = 0;
|
||||||
var propertyIDs: Dictionary = this.propertyIDs;
|
var propertyIDs: Dictionary = this.propertyIDs;
|
||||||
|
|
||||||
var i : int = 0;
|
var i : int = 0;
|
||||||
if (to != null && to.holdPrevious) {
|
if (to != null && to.holdPrevious) {
|
||||||
for (i = 0; i < timelinesCount; i++) {
|
for (i = 0; i < timelinesCount; i++) {
|
||||||
propertyIDs[timelines[i].getPropertyId().toString()] = true;
|
propertyIDs[timelines[i].getPropertyId().toString()] = true;
|
||||||
timelineMode[i] = HOLD;
|
timelineMode[i] = HOLD;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@ -658,7 +658,7 @@ package spine.animation {
|
|||||||
for (i = 0; i < timelinesCount; i++) {
|
for (i = 0; i < timelinesCount; i++) {
|
||||||
var timeline : Timeline = Timeline(timelines[i]);
|
var timeline : Timeline = Timeline(timelines[i]);
|
||||||
var intId : int = timeline.getPropertyId();
|
var intId : int = timeline.getPropertyId();
|
||||||
var id : String = intId.toString();
|
var id : String = intId.toString();
|
||||||
var contained: Object = propertyIDs[id];
|
var contained: Object = propertyIDs[id];
|
||||||
propertyIDs[id] = true;
|
propertyIDs[id] = true;
|
||||||
if (contained != null) {
|
if (contained != null) {
|
||||||
@ -666,11 +666,11 @@ package spine.animation {
|
|||||||
} else if (to == null || timeline is AttachmentTimeline || timeline is DrawOrderTimeline
|
} else if (to == null || timeline is AttachmentTimeline || timeline is DrawOrderTimeline
|
||||||
|| timeline is EventTimeline || !hasTimeline(to, intId)) {
|
|| timeline is EventTimeline || !hasTimeline(to, intId)) {
|
||||||
timelineMode[i] = AnimationState.FIRST;
|
timelineMode[i] = AnimationState.FIRST;
|
||||||
} else {
|
} else {
|
||||||
for (var next : TrackEntry = to.mixingTo; next != null; next = next.mixingTo) {
|
for (var next : TrackEntry = to.mixingTo; next != null; next = next.mixingTo) {
|
||||||
if (hasTimeline(next, intId)) continue;
|
if (hasTimeline(next, intId)) continue;
|
||||||
if (entry.mixDuration > 0) {
|
if (entry.mixDuration > 0) {
|
||||||
timelineMode[i] = AnimationState.HOLD_MIX;
|
timelineMode[i] = AnimationState.HOLD_MIX;
|
||||||
timelineHoldMix[i] = entry;
|
timelineHoldMix[i] = entry;
|
||||||
continue outer;
|
continue outer;
|
||||||
}
|
}
|
||||||
@ -678,7 +678,7 @@ package spine.animation {
|
|||||||
}
|
}
|
||||||
timelineMode[i] = AnimationState.HOLD;
|
timelineMode[i] = AnimationState.HOLD;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static function hasTimeline (entry: TrackEntry, id : int) : Boolean {
|
private static function hasTimeline (entry: TrackEntry, id : int) : Boolean {
|
||||||
|
|||||||
@ -34,7 +34,7 @@ package spine.animation {
|
|||||||
import spine.Skeleton;
|
import spine.Skeleton;
|
||||||
import spine.Slot;
|
import spine.Slot;
|
||||||
|
|
||||||
public class DeformTimeline extends CurveTimeline {
|
public class DeformTimeline extends CurveTimeline {
|
||||||
public var slotIndex : int;
|
public var slotIndex : int;
|
||||||
public var frames : Vector.<Number>;
|
public var frames : Vector.<Number>;
|
||||||
public var frameVertices : Vector.<Vector.<Number>>;
|
public var frameVertices : Vector.<Vector.<Number>>;
|
||||||
@ -63,16 +63,16 @@ package spine.animation {
|
|||||||
if (!slot.bone.active) return;
|
if (!slot.bone.active) return;
|
||||||
var slotAttachment : Attachment = slot.attachment;
|
var slotAttachment : Attachment = slot.attachment;
|
||||||
if (!(slotAttachment is VertexAttachment) || !(VertexAttachment(slotAttachment).deformAttachment == attachment)) return;
|
if (!(slotAttachment is VertexAttachment) || !(VertexAttachment(slotAttachment).deformAttachment == attachment)) return;
|
||||||
|
|
||||||
var deformArray : Vector.<Number> = slot.deform;
|
var deformArray : Vector.<Number> = slot.deform;
|
||||||
if (deformArray.length == 0) blend = MixBlend.setup;
|
if (deformArray.length == 0) blend = MixBlend.setup;
|
||||||
|
|
||||||
var frameVertices : Vector.<Vector.<Number>> = this.frameVertices;
|
var frameVertices : Vector.<Vector.<Number>> = this.frameVertices;
|
||||||
var vertexCount : int = frameVertices[0].length;
|
var vertexCount : int = frameVertices[0].length;
|
||||||
var deform : Vector.<Number>;
|
var deform : Vector.<Number>;
|
||||||
|
|
||||||
var frames : Vector.<Number> = this.frames;
|
var frames : Vector.<Number> = this.frames;
|
||||||
var i : int;
|
var i : int;
|
||||||
if (time < frames[0]) {
|
if (time < frames[0]) {
|
||||||
vertexAttachment = VertexAttachment(slotAttachment);
|
vertexAttachment = VertexAttachment(slotAttachment);
|
||||||
switch (blend) {
|
switch (blend) {
|
||||||
@ -99,27 +99,27 @@ package spine.animation {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
deformArray.length = vertexCount;
|
deformArray.length = vertexCount;
|
||||||
deform = deformArray;
|
deform = deformArray;
|
||||||
var n : int;
|
var n : int;
|
||||||
var setup : Number, prev : Number;
|
var setup : Number, prev : Number;
|
||||||
if (time >= frames[frames.length - 1]) { // Time is after last frame.
|
if (time >= frames[frames.length - 1]) { // Time is after last frame.
|
||||||
var lastVertices : Vector.<Number> = frameVertices[frames.length - 1];
|
var lastVertices : Vector.<Number> = frameVertices[frames.length - 1];
|
||||||
if (alpha == 1) {
|
if (alpha == 1) {
|
||||||
if (blend == MixBlend.add) {
|
if (blend == MixBlend.add) {
|
||||||
vertexAttachment = VertexAttachment(slotAttachment);
|
vertexAttachment = VertexAttachment(slotAttachment);
|
||||||
if (vertexAttachment.bones == null) {
|
if (vertexAttachment.bones == null) {
|
||||||
setupVertices = vertexAttachment.vertices;
|
setupVertices = vertexAttachment.vertices;
|
||||||
for (i = 0; i < vertexCount; i++) {
|
for (i = 0; i < vertexCount; i++) {
|
||||||
deform[i] += lastVertices[i] - setupVertices[i];
|
deform[i] += lastVertices[i] - setupVertices[i];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < vertexCount; i++)
|
for (i = 0; i < vertexCount; i++)
|
||||||
deform[i] += lastVertices[i];
|
deform[i] += lastVertices[i];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (i = 0, n = vertexCount; i < n; i++)
|
for (i = 0, n = vertexCount; i < n; i++)
|
||||||
deform[i] = lastVertices[i];
|
deform[i] = lastVertices[i];
|
||||||
}
|
}
|
||||||
@ -146,16 +146,16 @@ package spine.animation {
|
|||||||
deform[i] += (lastVertices[i] - deform[i]) * alpha;
|
deform[i] += (lastVertices[i] - deform[i]) * alpha;
|
||||||
case MixBlend.add:
|
case MixBlend.add:
|
||||||
vertexAttachment = VertexAttachment(slotAttachment);
|
vertexAttachment = VertexAttachment(slotAttachment);
|
||||||
if (vertexAttachment.bones == null) {
|
if (vertexAttachment.bones == null) {
|
||||||
setupVertices = vertexAttachment.vertices;
|
setupVertices = vertexAttachment.vertices;
|
||||||
for (i = 0; i < vertexCount; i++) {
|
for (i = 0; i < vertexCount; i++) {
|
||||||
deform[i] += (lastVertices[i] - setupVertices[i]) * alpha;
|
deform[i] += (lastVertices[i] - setupVertices[i]) * alpha;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < vertexCount; i++)
|
for (i = 0; i < vertexCount; i++)
|
||||||
deform[i] += lastVertices[i] * alpha;
|
deform[i] += lastVertices[i] * alpha;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -170,20 +170,20 @@ package spine.animation {
|
|||||||
if (alpha == 1) {
|
if (alpha == 1) {
|
||||||
if (blend == MixBlend.add) {
|
if (blend == MixBlend.add) {
|
||||||
vertexAttachment = VertexAttachment(slotAttachment);
|
vertexAttachment = VertexAttachment(slotAttachment);
|
||||||
if (vertexAttachment.bones == null) {
|
if (vertexAttachment.bones == null) {
|
||||||
setupVertices = vertexAttachment.vertices;
|
setupVertices = vertexAttachment.vertices;
|
||||||
for (i = 0; i < vertexCount; i++) {
|
for (i = 0; i < vertexCount; i++) {
|
||||||
prev = prevVertices[i];
|
prev = prevVertices[i];
|
||||||
deform[i] += prev + (nextVertices[i] - prev) * percent - setupVertices[i];
|
deform[i] += prev + (nextVertices[i] - prev) * percent - setupVertices[i];
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < vertexCount; i++) {
|
for (i = 0; i < vertexCount; i++) {
|
||||||
prev = prevVertices[i];
|
prev = prevVertices[i];
|
||||||
deform[i] += prev + (nextVertices[i] - prev) * percent;
|
deform[i] += prev + (nextVertices[i] - prev) * percent;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < vertexCount; i++) {
|
for (i = 0; i < vertexCount; i++) {
|
||||||
prev = prevVertices[i];
|
prev = prevVertices[i];
|
||||||
deform[i] = prev + (nextVertices[i] - prev) * percent;
|
deform[i] = prev + (nextVertices[i] - prev) * percent;
|
||||||
}
|
}
|
||||||
@ -216,19 +216,19 @@ package spine.animation {
|
|||||||
break;
|
break;
|
||||||
case MixBlend.add:
|
case MixBlend.add:
|
||||||
vertexAttachment = VertexAttachment(slotAttachment);
|
vertexAttachment = VertexAttachment(slotAttachment);
|
||||||
if (vertexAttachment.bones == null) {
|
if (vertexAttachment.bones == null) {
|
||||||
setupVertices = vertexAttachment.vertices;
|
setupVertices = vertexAttachment.vertices;
|
||||||
for (i = 0; i < vertexCount; i++) {
|
for (i = 0; i < vertexCount; i++) {
|
||||||
prev = prevVertices[i], setup = setupVertices[i];
|
prev = prevVertices[i], setup = setupVertices[i];
|
||||||
deform[i] += (prev + (nextVertices[i] - prev) * percent - setupVertices[i]) * alpha;
|
deform[i] += (prev + (nextVertices[i] - prev) * percent - setupVertices[i]) * alpha;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (i = 0; i < vertexCount; i++) {
|
for (i = 0; i < vertexCount; i++) {
|
||||||
prev = prevVertices[i];
|
prev = prevVertices[i];
|
||||||
deform[i] += (prev + (nextVertices[i] - prev) * percent) * alpha;
|
deform[i] += (prev + (nextVertices[i] - prev) * percent) * alpha;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -94,7 +94,7 @@ package spine.animation {
|
|||||||
constraint.bendDirection = int(frames[frames.length + PREV_BEND_DIRECTION]);
|
constraint.bendDirection = int(frames[frames.length + PREV_BEND_DIRECTION]);
|
||||||
constraint.compress = int(frames[frames.length + PREV_COMPRESS]) != 0;
|
constraint.compress = int(frames[frames.length + PREV_COMPRESS]) != 0;
|
||||||
constraint.stretch = int(frames[frames.length + PREV_STRETCH]) != 0;
|
constraint.stretch = int(frames[frames.length + PREV_STRETCH]) != 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
constraint.mix += (frames[frames.length + PREV_MIX] - constraint.mix) * alpha;
|
constraint.mix += (frames[frames.length + PREV_MIX] - constraint.mix) * alpha;
|
||||||
constraint.softness += (frames[frames.length + PREV_SOFTNESS] - constraint.softness) * alpha;
|
constraint.softness += (frames[frames.length + PREV_SOFTNESS] - constraint.softness) * alpha;
|
||||||
@ -121,12 +121,12 @@ package spine.animation {
|
|||||||
if (direction == MixDirection.Out) {
|
if (direction == MixDirection.Out) {
|
||||||
constraint.bendDirection = constraint.data.bendDirection;
|
constraint.bendDirection = constraint.data.bendDirection;
|
||||||
constraint.compress = constraint.data.compress;
|
constraint.compress = constraint.data.compress;
|
||||||
constraint.stretch = constraint.data.stretch;
|
constraint.stretch = constraint.data.stretch;
|
||||||
} else {
|
} else {
|
||||||
constraint.bendDirection = int(frames[frame + PREV_BEND_DIRECTION]);
|
constraint.bendDirection = int(frames[frame + PREV_BEND_DIRECTION]);
|
||||||
constraint.compress = int(frames[frame + PREV_COMPRESS]) != 0;
|
constraint.compress = int(frames[frame + PREV_COMPRESS]) != 0;
|
||||||
constraint.stretch = int(frames[frame + PREV_STRETCH]) != 0;
|
constraint.stretch = int(frames[frame + PREV_STRETCH]) != 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
constraint.mix += (mix + (frames[frame + MIX] - mix) * percent - constraint.mix) * alpha;
|
constraint.mix += (mix + (frames[frame + MIX] - mix) * percent - constraint.mix) * alpha;
|
||||||
constraint.softness += (softness + (frames[frame + SOFTNESS] - softness) * percent - constraint.softness) * alpha;
|
constraint.softness += (softness + (frames[frame + SOFTNESS] - softness) * percent - constraint.softness) * alpha;
|
||||||
|
|||||||
@ -36,6 +36,6 @@ package spine.animation {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static const In : MixDirection = new MixDirection(0);
|
public static const In : MixDirection = new MixDirection(0);
|
||||||
public static const Out : MixDirection = new MixDirection(1);
|
public static const Out : MixDirection = new MixDirection(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -85,7 +85,7 @@ package spine.animation {
|
|||||||
r -= (16384 - int((16384.499999999996 - r / 360))) * 360; // Wrap within -180 and 180.
|
r -= (16384 - int((16384.499999999996 - r / 360))) * 360; // Wrap within -180 and 180.
|
||||||
case MixBlend.add:
|
case MixBlend.add:
|
||||||
bone.rotation += r * alpha;
|
bone.rotation += r * alpha;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -96,16 +96,16 @@ package spine.animation {
|
|||||||
var percent : Number = getCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
|
var percent : Number = getCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame + PREV_TIME] - frameTime));
|
||||||
|
|
||||||
r = frames[frame + ROTATION] - prevRotation;
|
r = frames[frame + ROTATION] - prevRotation;
|
||||||
r = prevRotation + (r - (16384 - int((16384.499999999996 - r / 360))) * 360) * percent;
|
r = prevRotation + (r - (16384 - int((16384.499999999996 - r / 360))) * 360) * percent;
|
||||||
switch (blend) {
|
switch (blend) {
|
||||||
case MixBlend.setup:
|
case MixBlend.setup:
|
||||||
bone.rotation = bone.data.rotation + (r - (16384 - int((16384.499999999996 - r / 360))) * 360) * alpha;
|
bone.rotation = bone.data.rotation + (r - (16384 - int((16384.499999999996 - r / 360))) * 360) * alpha;
|
||||||
break;
|
break;
|
||||||
case MixBlend.first:
|
case MixBlend.first:
|
||||||
case MixBlend.replace:
|
case MixBlend.replace:
|
||||||
r += bone.data.rotation - bone.rotation;
|
r += bone.data.rotation - bone.rotation;
|
||||||
case MixBlend.add:
|
case MixBlend.add:
|
||||||
bone.rotation += (r - (16384 - int((16384.499999999996 - r / 360))) * 360) * alpha;
|
bone.rotation += (r - (16384 - int((16384.499999999996 - r / 360))) * 360) * alpha;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -78,7 +78,7 @@ package spine.animation {
|
|||||||
if (alpha == 1) {
|
if (alpha == 1) {
|
||||||
if (blend == MixBlend.add) {
|
if (blend == MixBlend.add) {
|
||||||
bone.scaleX += x - bone.data.scaleX;
|
bone.scaleX += x - bone.data.scaleX;
|
||||||
bone.scaleY += y - bone.data.scaleY;
|
bone.scaleY += y - bone.data.scaleY;
|
||||||
} else {
|
} else {
|
||||||
bone.scaleX = x;
|
bone.scaleX = x;
|
||||||
bone.scaleY = y;
|
bone.scaleY = y;
|
||||||
|
|||||||
@ -77,7 +77,7 @@ package spine.animation {
|
|||||||
timelineMode.length = 0;
|
timelineMode.length = 0;
|
||||||
timelineHoldMix.length = 0;
|
timelineHoldMix.length = 0;
|
||||||
timelinesRotation.length = 0;
|
timelinesRotation.length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function resetRotationDirection() : void {
|
public function resetRotationDirection() : void {
|
||||||
timelinesRotation.length = 0;
|
timelinesRotation.length = 0;
|
||||||
|
|||||||
@ -25,7 +25,7 @@ Depending on the test agent build environment, you should build the output solut
|
|||||||
|
|
||||||
### Test Runner Build Step
|
### Test Runner Build Step
|
||||||
This build step should not execute if the previous step did not successfully complete.
|
This build step should not execute if the previous step did not successfully complete.
|
||||||
Again, depending on the test agent build environment, you should have produced an executable. Run this executable.
|
Again, depending on the test agent build environment, you should have produced an executable. Run this executable.
|
||||||
|
|
||||||
|
|
||||||
## Usage
|
## Usage
|
||||||
|
|||||||
@ -62,7 +62,7 @@ int main(int argc, char* argv[])
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
extern "C" { // probably unnecessary
|
extern "C" { // probably unnecessary
|
||||||
|
|
||||||
void _spAtlasPage_createTexture(spAtlasPage* self, const char* path) {
|
void _spAtlasPage_createTexture(spAtlasPage* self, const char* path) {
|
||||||
self->rendererObject = 0;
|
self->rendererObject = 0;
|
||||||
|
|||||||
@ -81,8 +81,8 @@ extern "C" {
|
|||||||
} \
|
} \
|
||||||
void name##_add(name* self, itemType value) { \
|
void name##_add(name* self, itemType value) { \
|
||||||
if (self->size == self->capacity) { \
|
if (self->size == self->capacity) { \
|
||||||
self->capacity = MAX(8, (int)(self->size * 1.75f)); \
|
self->capacity = MAX(8, (int)(self->size * 1.75f)); \
|
||||||
self->items = REALLOC(self->items, itemType, self->capacity); \
|
self->items = REALLOC(self->items, itemType, self->capacity); \
|
||||||
} \
|
} \
|
||||||
self->items[self->size++] = value; \
|
self->items[self->size++] = value; \
|
||||||
} \
|
} \
|
||||||
|
|||||||
@ -45,9 +45,9 @@ typedef struct spAttachmentLoader {
|
|||||||
const void* const vtable;
|
const void* const vtable;
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
spAttachmentLoader () :
|
spAttachmentLoader () :
|
||||||
error1(0),
|
error1(0),
|
||||||
error2(0),
|
error2(0),
|
||||||
vtable(0) {
|
vtable(0) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
} spAttachmentLoader;
|
} spAttachmentLoader;
|
||||||
|
|||||||
@ -89,7 +89,7 @@ struct _SkinHashTableEntry {
|
|||||||
typedef struct {
|
typedef struct {
|
||||||
spSkin super;
|
spSkin super;
|
||||||
_Entry* entries; /* entries list stored for getting attachment name by attachment index */
|
_Entry* entries; /* entries list stored for getting attachment name by attachment index */
|
||||||
_SkinHashTableEntry* entriesHashTable[SKIN_ENTRIES_HASH_TABLE_SIZE]; /* hashtable for fast attachment lookup */
|
_SkinHashTableEntry* entriesHashTable[SKIN_ENTRIES_HASH_TABLE_SIZE]; /* hashtable for fast attachment lookup */
|
||||||
} _spSkin;
|
} _spSkin;
|
||||||
|
|
||||||
SP_API spSkin* spSkin_create (const char* name);
|
SP_API spSkin* spSkin_create (const char* name);
|
||||||
|
|||||||
@ -43,7 +43,7 @@ struct spVertexEffect;
|
|||||||
typedef void (*spVertexEffectBegin)(struct spVertexEffect *self, spSkeleton *skeleton);
|
typedef void (*spVertexEffectBegin)(struct spVertexEffect *self, spSkeleton *skeleton);
|
||||||
|
|
||||||
typedef void (*spVertexEffectTransform)(struct spVertexEffect *self, float *x, float *y, float *u, float *v,
|
typedef void (*spVertexEffectTransform)(struct spVertexEffect *self, float *x, float *y, float *u, float *v,
|
||||||
spColor *light, spColor *dark);
|
spColor *light, spColor *dark);
|
||||||
|
|
||||||
typedef void (*spVertexEffectEnd)(struct spVertexEffect *self);
|
typedef void (*spVertexEffectEnd)(struct spVertexEffect *self);
|
||||||
|
|
||||||
|
|||||||
@ -50,7 +50,8 @@ void spAnimation_dispose (spAnimation* self) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void spAnimation_apply (const spAnimation* self, spSkeleton* skeleton, float lastTime, float time, int loop, spEvent** events,
|
void spAnimation_apply (const spAnimation* self, spSkeleton* skeleton, float lastTime, float time, int loop, spEvent** events,
|
||||||
int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction) {
|
int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
|
||||||
|
) {
|
||||||
int i, n = self->timelinesCount;
|
int i, n = self->timelinesCount;
|
||||||
|
|
||||||
if (loop && self->duration) {
|
if (loop && self->duration) {
|
||||||
@ -66,15 +67,17 @@ void spAnimation_apply (const spAnimation* self, spSkeleton* skeleton, float las
|
|||||||
|
|
||||||
typedef struct _spTimelineVtable {
|
typedef struct _spTimelineVtable {
|
||||||
void (*apply) (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
|
void (*apply) (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
|
||||||
int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction);
|
int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction);
|
||||||
int (*getPropertyId) (const spTimeline* self);
|
int (*getPropertyId) (const spTimeline* self);
|
||||||
void (*dispose) (spTimeline* self);
|
void (*dispose) (spTimeline* self);
|
||||||
} _spTimelineVtable;
|
} _spTimelineVtable;
|
||||||
|
|
||||||
void _spTimeline_init (spTimeline* self, spTimelineType type, /**/
|
void _spTimeline_init (spTimeline* self, spTimelineType type, /**/
|
||||||
void (*dispose) (spTimeline* self), /**/
|
void (*dispose) (spTimeline* self), /**/
|
||||||
void (*apply) (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction),
|
void (*apply) (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
|
||||||
int (*getPropertyId) (const spTimeline* self)) {
|
int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction),
|
||||||
|
int (*getPropertyId) (const spTimeline* self)
|
||||||
|
) {
|
||||||
CONST_CAST(spTimelineType, self->type) = type;
|
CONST_CAST(spTimelineType, self->type) = type;
|
||||||
CONST_CAST(_spTimelineVtable*, self->vtable) = NEW(_spTimelineVtable);
|
CONST_CAST(_spTimelineVtable*, self->vtable) = NEW(_spTimelineVtable);
|
||||||
VTABLE(spTimeline, self)->dispose = dispose;
|
VTABLE(spTimeline, self)->dispose = dispose;
|
||||||
@ -105,9 +108,11 @@ static const float CURVE_LINEAR = 0, CURVE_STEPPED = 1, CURVE_BEZIER = 2;
|
|||||||
static const int BEZIER_SIZE = 10 * 2 - 1;
|
static const int BEZIER_SIZE = 10 * 2 - 1;
|
||||||
|
|
||||||
void _spCurveTimeline_init (spCurveTimeline* self, spTimelineType type, int framesCount, /**/
|
void _spCurveTimeline_init (spCurveTimeline* self, spTimelineType type, int framesCount, /**/
|
||||||
void (*dispose) (spTimeline* self), /**/
|
void (*dispose) (spTimeline* self), /**/
|
||||||
void (*apply) (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction),
|
void (*apply) (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
|
||||||
int (*getPropertyId)(const spTimeline* self)) {
|
int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction),
|
||||||
|
int (*getPropertyId)(const spTimeline* self)
|
||||||
|
) {
|
||||||
_spTimeline_init(SUPER(self), type, dispose, apply, getPropertyId);
|
_spTimeline_init(SUPER(self), type, dispose, apply, getPropertyId);
|
||||||
self->curves = CALLOC(float, (framesCount - 1) * BEZIER_SIZE);
|
self->curves = CALLOC(float, (framesCount - 1) * BEZIER_SIZE);
|
||||||
}
|
}
|
||||||
@ -223,9 +228,10 @@ void _spBaseTimeline_dispose (spTimeline* timeline) {
|
|||||||
|
|
||||||
/* Many timelines have structure identical to struct spBaseTimeline and extend spCurveTimeline. **/
|
/* Many timelines have structure identical to struct spBaseTimeline and extend spCurveTimeline. **/
|
||||||
struct spBaseTimeline* _spBaseTimeline_create (int framesCount, spTimelineType type, int frameSize, /**/
|
struct spBaseTimeline* _spBaseTimeline_create (int framesCount, spTimelineType type, int frameSize, /**/
|
||||||
void (*apply) (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
|
void (*apply) (const spTimeline* self, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
|
||||||
int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction),
|
int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction),
|
||||||
int (*getPropertyId) (const spTimeline* self)) {
|
int (*getPropertyId) (const spTimeline* self)
|
||||||
|
) {
|
||||||
struct spBaseTimeline* self = NEW(struct spBaseTimeline);
|
struct spBaseTimeline* self = NEW(struct spBaseTimeline);
|
||||||
_spCurveTimeline_init(SUPER(self), type, framesCount, _spBaseTimeline_dispose, apply, getPropertyId);
|
_spCurveTimeline_init(SUPER(self), type, framesCount, _spBaseTimeline_dispose, apply, getPropertyId);
|
||||||
|
|
||||||
@ -238,7 +244,8 @@ struct spBaseTimeline* _spBaseTimeline_create (int framesCount, spTimelineType t
|
|||||||
/**/
|
/**/
|
||||||
|
|
||||||
void _spRotateTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
|
void _spRotateTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
|
||||||
int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction) {
|
int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
|
||||||
|
) {
|
||||||
spBone *bone;
|
spBone *bone;
|
||||||
int frame;
|
int frame;
|
||||||
float prevRotation, frameTime, percent, r;
|
float prevRotation, frameTime, percent, r;
|
||||||
@ -248,16 +255,16 @@ void _spRotateTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton,
|
|||||||
if (!bone->active) return;
|
if (!bone->active) return;
|
||||||
if (time < self->frames[0]) {
|
if (time < self->frames[0]) {
|
||||||
switch (blend) {
|
switch (blend) {
|
||||||
case SP_MIX_BLEND_SETUP:
|
case SP_MIX_BLEND_SETUP:
|
||||||
bone->rotation = bone->data->rotation;
|
bone->rotation = bone->data->rotation;
|
||||||
return;
|
return;
|
||||||
case SP_MIX_BLEND_FIRST:
|
case SP_MIX_BLEND_FIRST:
|
||||||
r = bone->data->rotation - bone->rotation;
|
r = bone->data->rotation - bone->rotation;
|
||||||
r -= (16384 - (int)(16384.499999999996 - r / 360)) * 360;
|
r -= (16384 - (int)(16384.499999999996 - r / 360)) * 360;
|
||||||
bone->rotation += r * alpha;
|
bone->rotation += r * alpha;
|
||||||
case SP_MIX_BLEND_REPLACE:
|
case SP_MIX_BLEND_REPLACE:
|
||||||
case SP_MIX_BLEND_ADD:
|
case SP_MIX_BLEND_ADD:
|
||||||
; /* to appease compiler */
|
; /* to appease compiler */
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -265,15 +272,15 @@ void _spRotateTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton,
|
|||||||
if (time >= self->frames[self->framesCount - ROTATE_ENTRIES]) { /* Time is after last frame. */
|
if (time >= self->frames[self->framesCount - ROTATE_ENTRIES]) { /* Time is after last frame. */
|
||||||
r = self->frames[self->framesCount + ROTATE_PREV_ROTATION];
|
r = self->frames[self->framesCount + ROTATE_PREV_ROTATION];
|
||||||
switch (blend) {
|
switch (blend) {
|
||||||
case SP_MIX_BLEND_SETUP:
|
case SP_MIX_BLEND_SETUP:
|
||||||
bone->rotation = bone->data->rotation + r * alpha;
|
bone->rotation = bone->data->rotation + r * alpha;
|
||||||
break;
|
break;
|
||||||
case SP_MIX_BLEND_FIRST:
|
case SP_MIX_BLEND_FIRST:
|
||||||
case SP_MIX_BLEND_REPLACE:
|
case SP_MIX_BLEND_REPLACE:
|
||||||
r += bone->data->rotation - bone->rotation;
|
r += bone->data->rotation - bone->rotation;
|
||||||
r -= (16384 - (int)(16384.499999999996 - r / 360)) * 360; /* Wrap within -180 and 180. */
|
r -= (16384 - (int)(16384.499999999996 - r / 360)) * 360; /* Wrap within -180 and 180. */
|
||||||
case SP_MIX_BLEND_ADD:
|
case SP_MIX_BLEND_ADD:
|
||||||
bone->rotation += r * alpha;
|
bone->rotation += r * alpha;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -287,14 +294,14 @@ void _spRotateTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton,
|
|||||||
r = self->frames[frame + ROTATE_ROTATION] - prevRotation;
|
r = self->frames[frame + ROTATE_ROTATION] - prevRotation;
|
||||||
r = prevRotation + (r - (16384 - (int)(16384.499999999996 - r / 360)) * 360) * percent;
|
r = prevRotation + (r - (16384 - (int)(16384.499999999996 - r / 360)) * 360) * percent;
|
||||||
switch (blend) {
|
switch (blend) {
|
||||||
case SP_MIX_BLEND_SETUP:
|
case SP_MIX_BLEND_SETUP:
|
||||||
bone->rotation = bone->data->rotation + (r - (16384 - (int)(16384.499999999996 - r / 360)) * 360) * alpha;
|
bone->rotation = bone->data->rotation + (r - (16384 - (int)(16384.499999999996 - r / 360)) * 360) * alpha;
|
||||||
break;
|
break;
|
||||||
case SP_MIX_BLEND_FIRST:
|
case SP_MIX_BLEND_FIRST:
|
||||||
case SP_MIX_BLEND_REPLACE:
|
case SP_MIX_BLEND_REPLACE:
|
||||||
r += bone->data->rotation - bone->rotation;
|
r += bone->data->rotation - bone->rotation;
|
||||||
case SP_MIX_BLEND_ADD:
|
case SP_MIX_BLEND_ADD:
|
||||||
bone->rotation += (r - (16384 - (int)(16384.499999999996 - r / 360)) * 360) * alpha;
|
bone->rotation += (r - (16384 - (int)(16384.499999999996 - r / 360)) * 360) * alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
UNUSED(lastTime);
|
UNUSED(lastTime);
|
||||||
@ -323,7 +330,8 @@ static const int TRANSLATE_PREV_TIME = -3, TRANSLATE_PREV_X = -2, TRANSLATE_PREV
|
|||||||
static const int TRANSLATE_X = 1, TRANSLATE_Y = 2;
|
static const int TRANSLATE_X = 1, TRANSLATE_Y = 2;
|
||||||
|
|
||||||
void _spTranslateTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
|
void _spTranslateTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
|
||||||
spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction) {
|
spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
|
||||||
|
) {
|
||||||
spBone *bone;
|
spBone *bone;
|
||||||
int frame;
|
int frame;
|
||||||
float frameTime, percent;
|
float frameTime, percent;
|
||||||
@ -337,16 +345,16 @@ void _spTranslateTimeline_apply (const spTimeline* timeline, spSkeleton* skeleto
|
|||||||
if (!bone->active) return;
|
if (!bone->active) return;
|
||||||
if (time < self->frames[0]) {
|
if (time < self->frames[0]) {
|
||||||
switch (blend) {
|
switch (blend) {
|
||||||
case SP_MIX_BLEND_SETUP:
|
case SP_MIX_BLEND_SETUP:
|
||||||
bone->x = bone->data->x;
|
bone->x = bone->data->x;
|
||||||
bone->y = bone->data->y;
|
bone->y = bone->data->y;
|
||||||
return;
|
return;
|
||||||
case SP_MIX_BLEND_FIRST:
|
case SP_MIX_BLEND_FIRST:
|
||||||
bone->x += (bone->data->x - bone->x) * alpha;
|
bone->x += (bone->data->x - bone->x) * alpha;
|
||||||
bone->y += (bone->data->y - bone->y) * alpha;
|
bone->y += (bone->data->y - bone->y) * alpha;
|
||||||
case SP_MIX_BLEND_REPLACE:
|
case SP_MIX_BLEND_REPLACE:
|
||||||
case SP_MIX_BLEND_ADD:
|
case SP_MIX_BLEND_ADD:
|
||||||
; /* to appease compiler */
|
; /* to appease compiler */
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -363,24 +371,24 @@ void _spTranslateTimeline_apply (const spTimeline* timeline, spSkeleton* skeleto
|
|||||||
y = frames[frame + TRANSLATE_PREV_Y];
|
y = frames[frame + TRANSLATE_PREV_Y];
|
||||||
frameTime = frames[frame];
|
frameTime = frames[frame];
|
||||||
percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / TRANSLATE_ENTRIES - 1,
|
percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / TRANSLATE_ENTRIES - 1,
|
||||||
1 - (time - frameTime) / (frames[frame + TRANSLATE_PREV_TIME] - frameTime));
|
1 - (time - frameTime) / (frames[frame + TRANSLATE_PREV_TIME] - frameTime));
|
||||||
|
|
||||||
x += (frames[frame + TRANSLATE_X] - x) * percent;
|
x += (frames[frame + TRANSLATE_X] - x) * percent;
|
||||||
y += (frames[frame + TRANSLATE_Y] - y) * percent;
|
y += (frames[frame + TRANSLATE_Y] - y) * percent;
|
||||||
}
|
}
|
||||||
switch (blend) {
|
switch (blend) {
|
||||||
case SP_MIX_BLEND_SETUP:
|
case SP_MIX_BLEND_SETUP:
|
||||||
bone->x = bone->data->x + x * alpha;
|
bone->x = bone->data->x + x * alpha;
|
||||||
bone->y = bone->data->y + y * alpha;
|
bone->y = bone->data->y + y * alpha;
|
||||||
break;
|
break;
|
||||||
case SP_MIX_BLEND_FIRST:
|
case SP_MIX_BLEND_FIRST:
|
||||||
case SP_MIX_BLEND_REPLACE:
|
case SP_MIX_BLEND_REPLACE:
|
||||||
bone->x += (bone->data->x + x - bone->x) * alpha;
|
bone->x += (bone->data->x + x - bone->x) * alpha;
|
||||||
bone->y += (bone->data->y + y - bone->y) * alpha;
|
bone->y += (bone->data->y + y - bone->y) * alpha;
|
||||||
break;
|
break;
|
||||||
case SP_MIX_BLEND_ADD:
|
case SP_MIX_BLEND_ADD:
|
||||||
bone->x += x * alpha;
|
bone->x += x * alpha;
|
||||||
bone->y += y * alpha;
|
bone->y += y * alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
UNUSED(lastTime);
|
UNUSED(lastTime);
|
||||||
@ -407,7 +415,8 @@ void spTranslateTimeline_setFrame (spTranslateTimeline* self, int frameIndex, fl
|
|||||||
/**/
|
/**/
|
||||||
|
|
||||||
void _spScaleTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
|
void _spScaleTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
|
||||||
int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction) {
|
int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
|
||||||
|
) {
|
||||||
spBone *bone;
|
spBone *bone;
|
||||||
int frame;
|
int frame;
|
||||||
float frameTime, percent, x, y;
|
float frameTime, percent, x, y;
|
||||||
@ -420,16 +429,16 @@ void _spScaleTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, f
|
|||||||
if (!bone->active) return;
|
if (!bone->active) return;
|
||||||
if (time < self->frames[0]) {
|
if (time < self->frames[0]) {
|
||||||
switch (blend) {
|
switch (blend) {
|
||||||
case SP_MIX_BLEND_SETUP:
|
case SP_MIX_BLEND_SETUP:
|
||||||
bone->scaleX = bone->data->scaleX;
|
bone->scaleX = bone->data->scaleX;
|
||||||
bone->scaleY = bone->data->scaleY;
|
bone->scaleY = bone->data->scaleY;
|
||||||
return;
|
return;
|
||||||
case SP_MIX_BLEND_FIRST:
|
case SP_MIX_BLEND_FIRST:
|
||||||
bone->scaleX += (bone->data->scaleX - bone->scaleX) * alpha;
|
bone->scaleX += (bone->data->scaleX - bone->scaleX) * alpha;
|
||||||
bone->scaleY += (bone->data->scaleY - bone->scaleY) * alpha;
|
bone->scaleY += (bone->data->scaleY - bone->scaleY) * alpha;
|
||||||
case SP_MIX_BLEND_REPLACE:
|
case SP_MIX_BLEND_REPLACE:
|
||||||
case SP_MIX_BLEND_ADD:
|
case SP_MIX_BLEND_ADD:
|
||||||
; /* to appease compiler */
|
; /* to appease compiler */
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -446,7 +455,7 @@ void _spScaleTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, f
|
|||||||
y = frames[frame + TRANSLATE_PREV_Y];
|
y = frames[frame + TRANSLATE_PREV_Y];
|
||||||
frameTime = frames[frame];
|
frameTime = frames[frame];
|
||||||
percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / TRANSLATE_ENTRIES - 1,
|
percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / TRANSLATE_ENTRIES - 1,
|
||||||
1 - (time - frameTime) / (frames[frame + TRANSLATE_PREV_TIME] - frameTime));
|
1 - (time - frameTime) / (frames[frame + TRANSLATE_PREV_TIME] - frameTime));
|
||||||
|
|
||||||
x = (x + (frames[frame + TRANSLATE_X] - x) * percent) * bone->data->scaleX;
|
x = (x + (frames[frame + TRANSLATE_X] - x) * percent) * bone->data->scaleX;
|
||||||
y = (y + (frames[frame + TRANSLATE_Y] - y) * percent) * bone->data->scaleY;
|
y = (y + (frames[frame + TRANSLATE_Y] - y) * percent) * bone->data->scaleY;
|
||||||
@ -463,45 +472,45 @@ void _spScaleTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, f
|
|||||||
float bx, by;
|
float bx, by;
|
||||||
if (direction == SP_MIX_DIRECTION_OUT) {
|
if (direction == SP_MIX_DIRECTION_OUT) {
|
||||||
switch (blend) {
|
switch (blend) {
|
||||||
case SP_MIX_BLEND_SETUP:
|
case SP_MIX_BLEND_SETUP:
|
||||||
bx = bone->data->scaleX;
|
bx = bone->data->scaleX;
|
||||||
by = bone->data->scaleY;
|
by = bone->data->scaleY;
|
||||||
bone->scaleX = bx + (ABS(x) * SIGNUM(bx) - bx) * alpha;
|
bone->scaleX = bx + (ABS(x) * SIGNUM(bx) - bx) * alpha;
|
||||||
bone->scaleY = by + (ABS(y) * SIGNUM(by) - by) * alpha;
|
bone->scaleY = by + (ABS(y) * SIGNUM(by) - by) * alpha;
|
||||||
break;
|
break;
|
||||||
case SP_MIX_BLEND_FIRST:
|
case SP_MIX_BLEND_FIRST:
|
||||||
case SP_MIX_BLEND_REPLACE:
|
case SP_MIX_BLEND_REPLACE:
|
||||||
bx = bone->scaleX;
|
bx = bone->scaleX;
|
||||||
by = bone->scaleY;
|
by = bone->scaleY;
|
||||||
bone->scaleX = bx + (ABS(x) * SIGNUM(bx) - bx) * alpha;
|
bone->scaleX = bx + (ABS(x) * SIGNUM(bx) - bx) * alpha;
|
||||||
bone->scaleY = by + (ABS(y) * SIGNUM(by) - by) * alpha;
|
bone->scaleY = by + (ABS(y) * SIGNUM(by) - by) * alpha;
|
||||||
break;
|
break;
|
||||||
case SP_MIX_BLEND_ADD:
|
case SP_MIX_BLEND_ADD:
|
||||||
bx = bone->scaleX;
|
bx = bone->scaleX;
|
||||||
by = bone->scaleY;
|
by = bone->scaleY;
|
||||||
bone->scaleX = bx + (ABS(x) * SIGNUM(bx) - bone->data->scaleX) * alpha;
|
bone->scaleX = bx + (ABS(x) * SIGNUM(bx) - bone->data->scaleX) * alpha;
|
||||||
bone->scaleY = by + (ABS(y) * SIGNUM(by) - bone->data->scaleY) * alpha;
|
bone->scaleY = by + (ABS(y) * SIGNUM(by) - bone->data->scaleY) * alpha;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch (blend) {
|
switch (blend) {
|
||||||
case SP_MIX_BLEND_SETUP:
|
case SP_MIX_BLEND_SETUP:
|
||||||
bx = ABS(bone->data->scaleX) * SIGNUM(x);
|
bx = ABS(bone->data->scaleX) * SIGNUM(x);
|
||||||
by = ABS(bone->data->scaleY) * SIGNUM(y);
|
by = ABS(bone->data->scaleY) * SIGNUM(y);
|
||||||
bone->scaleX = bx + (x - bx) * alpha;
|
bone->scaleX = bx + (x - bx) * alpha;
|
||||||
bone->scaleY = by + (y - by) * alpha;
|
bone->scaleY = by + (y - by) * alpha;
|
||||||
break;
|
break;
|
||||||
case SP_MIX_BLEND_FIRST:
|
case SP_MIX_BLEND_FIRST:
|
||||||
case SP_MIX_BLEND_REPLACE:
|
case SP_MIX_BLEND_REPLACE:
|
||||||
bx = ABS(bone->scaleX) * SIGNUM(x);
|
bx = ABS(bone->scaleX) * SIGNUM(x);
|
||||||
by = ABS(bone->scaleY) * SIGNUM(y);
|
by = ABS(bone->scaleY) * SIGNUM(y);
|
||||||
bone->scaleX = bx + (x - bx) * alpha;
|
bone->scaleX = bx + (x - bx) * alpha;
|
||||||
bone->scaleY = by + (y - by) * alpha;
|
bone->scaleY = by + (y - by) * alpha;
|
||||||
break;
|
break;
|
||||||
case SP_MIX_BLEND_ADD:
|
case SP_MIX_BLEND_ADD:
|
||||||
bx = SIGNUM(x);
|
bx = SIGNUM(x);
|
||||||
by = SIGNUM(y);
|
by = SIGNUM(y);
|
||||||
bone->scaleX = ABS(bone->scaleX) * bx + (x - ABS(bone->data->scaleX) * bx) * alpha;
|
bone->scaleX = ABS(bone->scaleX) * bx + (x - ABS(bone->data->scaleX) * bx) * alpha;
|
||||||
bone->scaleY = ABS(bone->scaleY) * by + (y - ABS(bone->data->scaleY) * by) * alpha;
|
bone->scaleY = ABS(bone->scaleY) * by + (y - ABS(bone->data->scaleY) * by) * alpha;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -526,7 +535,8 @@ void spScaleTimeline_setFrame (spScaleTimeline* self, int frameIndex, float time
|
|||||||
/**/
|
/**/
|
||||||
|
|
||||||
void _spShearTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
|
void _spShearTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
|
||||||
int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction) {
|
int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
|
||||||
|
) {
|
||||||
spBone *bone;
|
spBone *bone;
|
||||||
int frame;
|
int frame;
|
||||||
float frameTime, percent, x, y;
|
float frameTime, percent, x, y;
|
||||||
@ -541,16 +551,16 @@ void _spShearTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, f
|
|||||||
framesCount = self->framesCount;
|
framesCount = self->framesCount;
|
||||||
if (time < self->frames[0]) {
|
if (time < self->frames[0]) {
|
||||||
switch (blend) {
|
switch (blend) {
|
||||||
case SP_MIX_BLEND_SETUP:
|
case SP_MIX_BLEND_SETUP:
|
||||||
bone->shearX = bone->data->shearX;
|
bone->shearX = bone->data->shearX;
|
||||||
bone->shearY = bone->data->shearY;
|
bone->shearY = bone->data->shearY;
|
||||||
return;
|
return;
|
||||||
case SP_MIX_BLEND_FIRST:
|
case SP_MIX_BLEND_FIRST:
|
||||||
bone->shearX += (bone->data->shearX - bone->shearX) * alpha;
|
bone->shearX += (bone->data->shearX - bone->shearX) * alpha;
|
||||||
bone->shearY += (bone->data->shearY - bone->shearY) * alpha;
|
bone->shearY += (bone->data->shearY - bone->shearY) * alpha;
|
||||||
case SP_MIX_BLEND_REPLACE:
|
case SP_MIX_BLEND_REPLACE:
|
||||||
case SP_MIX_BLEND_ADD:
|
case SP_MIX_BLEND_ADD:
|
||||||
; /* to appease compiler */
|
; /* to appease compiler */
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -565,24 +575,24 @@ void _spShearTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, f
|
|||||||
y = frames[frame + TRANSLATE_PREV_Y];
|
y = frames[frame + TRANSLATE_PREV_Y];
|
||||||
frameTime = frames[frame];
|
frameTime = frames[frame];
|
||||||
percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / TRANSLATE_ENTRIES - 1,
|
percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / TRANSLATE_ENTRIES - 1,
|
||||||
1 - (time - frameTime) / (frames[frame + TRANSLATE_PREV_TIME] - frameTime));
|
1 - (time - frameTime) / (frames[frame + TRANSLATE_PREV_TIME] - frameTime));
|
||||||
|
|
||||||
x = x + (frames[frame + TRANSLATE_X] - x) * percent;
|
x = x + (frames[frame + TRANSLATE_X] - x) * percent;
|
||||||
y = y + (frames[frame + TRANSLATE_Y] - y) * percent;
|
y = y + (frames[frame + TRANSLATE_Y] - y) * percent;
|
||||||
}
|
}
|
||||||
switch (blend) {
|
switch (blend) {
|
||||||
case SP_MIX_BLEND_SETUP:
|
case SP_MIX_BLEND_SETUP:
|
||||||
bone->shearX = bone->data->shearX + x * alpha;
|
bone->shearX = bone->data->shearX + x * alpha;
|
||||||
bone->shearY = bone->data->shearY + y * alpha;
|
bone->shearY = bone->data->shearY + y * alpha;
|
||||||
break;
|
break;
|
||||||
case SP_MIX_BLEND_FIRST:
|
case SP_MIX_BLEND_FIRST:
|
||||||
case SP_MIX_BLEND_REPLACE:
|
case SP_MIX_BLEND_REPLACE:
|
||||||
bone->shearX += (bone->data->shearX + x - bone->shearX) * alpha;
|
bone->shearX += (bone->data->shearX + x - bone->shearX) * alpha;
|
||||||
bone->shearY += (bone->data->shearY + y - bone->shearY) * alpha;
|
bone->shearY += (bone->data->shearY + y - bone->shearY) * alpha;
|
||||||
break;
|
break;
|
||||||
case SP_MIX_BLEND_ADD:
|
case SP_MIX_BLEND_ADD:
|
||||||
bone->shearX += x * alpha;
|
bone->shearX += x * alpha;
|
||||||
bone->shearY += y * alpha;
|
bone->shearY += y * alpha;
|
||||||
}
|
}
|
||||||
|
|
||||||
UNUSED(lastTime);
|
UNUSED(lastTime);
|
||||||
@ -609,7 +619,8 @@ static const int COLOR_PREV_TIME = -5, COLOR_PREV_R = -4, COLOR_PREV_G = -3, COL
|
|||||||
static const int COLOR_R = 1, COLOR_G = 2, COLOR_B = 3, COLOR_A = 4;
|
static const int COLOR_R = 1, COLOR_G = 2, COLOR_B = 3, COLOR_A = 4;
|
||||||
|
|
||||||
void _spColorTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
|
void _spColorTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
|
||||||
int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction) {
|
int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
|
||||||
|
) {
|
||||||
spSlot *slot;
|
spSlot *slot;
|
||||||
int frame;
|
int frame;
|
||||||
float percent, frameTime;
|
float percent, frameTime;
|
||||||
@ -622,17 +633,17 @@ void _spColorTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, f
|
|||||||
|
|
||||||
if (time < self->frames[0]) {
|
if (time < self->frames[0]) {
|
||||||
switch (blend) {
|
switch (blend) {
|
||||||
case SP_MIX_BLEND_SETUP:
|
case SP_MIX_BLEND_SETUP:
|
||||||
spColor_setFromColor(&slot->color, &slot->data->color);
|
spColor_setFromColor(&slot->color, &slot->data->color);
|
||||||
return;
|
return;
|
||||||
case SP_MIX_BLEND_FIRST:
|
case SP_MIX_BLEND_FIRST:
|
||||||
color = &slot->color;
|
color = &slot->color;
|
||||||
setup = &slot->data->color;
|
setup = &slot->data->color;
|
||||||
spColor_addFloats(color, (setup->r - color->r) * alpha, (setup->g - color->g) * alpha, (setup->b - color->b) * alpha,
|
spColor_addFloats(color, (setup->r - color->r) * alpha, (setup->g - color->g) * alpha, (setup->b - color->b) * alpha,
|
||||||
(setup->a - color->a) * alpha);
|
(setup->a - color->a) * alpha);
|
||||||
case SP_MIX_BLEND_REPLACE:
|
case SP_MIX_BLEND_REPLACE:
|
||||||
case SP_MIX_BLEND_ADD:
|
case SP_MIX_BLEND_ADD:
|
||||||
; /* to appease compiler */
|
; /* to appease compiler */
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -664,9 +675,7 @@ void _spColorTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, f
|
|||||||
if (alpha == 1) {
|
if (alpha == 1) {
|
||||||
spColor_setFromFloats(&slot->color, r, g, b, a);
|
spColor_setFromFloats(&slot->color, r, g, b, a);
|
||||||
} else {
|
} else {
|
||||||
if (blend == SP_MIX_BLEND_SETUP) {
|
if (blend == SP_MIX_BLEND_SETUP) spColor_setFromColor(&slot->color, &slot->data->color);
|
||||||
spColor_setFromColor(&slot->color, &slot->data->color);
|
|
||||||
}
|
|
||||||
spColor_addFloats(&slot->color, (r - slot->color.r) * alpha, (g - slot->color.g) * alpha, (b - slot->color.b) * alpha, (a - slot->color.a) * alpha);
|
spColor_addFloats(&slot->color, (r - slot->color.r) * alpha, (g - slot->color.g) * alpha, (b - slot->color.b) * alpha, (a - slot->color.a) * alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -700,7 +709,8 @@ static const int TWOCOLOR_PREV_R2 = -3, TWOCOLOR_PREV_G2 = -2, TWOCOLOR_PREV_B2
|
|||||||
static const int TWOCOLOR_R = 1, TWOCOLOR_G = 2, TWOCOLOR_B = 3, TWOCOLOR_A = 4, TWOCOLOR_R2 = 5, TWOCOLOR_G2 = 6, TWOCOLOR_B2 = 7;
|
static const int TWOCOLOR_R = 1, TWOCOLOR_G = 2, TWOCOLOR_B = 3, TWOCOLOR_A = 4, TWOCOLOR_R2 = 5, TWOCOLOR_G2 = 6, TWOCOLOR_B2 = 7;
|
||||||
|
|
||||||
void _spTwoColorTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
|
void _spTwoColorTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
|
||||||
int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction) {
|
int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
|
||||||
|
) {
|
||||||
spSlot *slot;
|
spSlot *slot;
|
||||||
int frame;
|
int frame;
|
||||||
float percent, frameTime;
|
float percent, frameTime;
|
||||||
@ -715,21 +725,21 @@ void _spTwoColorTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton
|
|||||||
|
|
||||||
if (time < self->frames[0]) {
|
if (time < self->frames[0]) {
|
||||||
switch (blend) {
|
switch (blend) {
|
||||||
case SP_MIX_BLEND_SETUP:
|
case SP_MIX_BLEND_SETUP:
|
||||||
spColor_setFromColor(&slot->color, &slot->data->color);
|
spColor_setFromColor(&slot->color, &slot->data->color);
|
||||||
spColor_setFromColor(slot->darkColor, slot->data->darkColor);
|
spColor_setFromColor(slot->darkColor, slot->data->darkColor);
|
||||||
return;
|
return;
|
||||||
case SP_MIX_BLEND_FIRST:
|
case SP_MIX_BLEND_FIRST:
|
||||||
light = &slot->color;
|
light = &slot->color;
|
||||||
dark = slot->darkColor;
|
dark = slot->darkColor;
|
||||||
setupLight = &slot->data->color;
|
setupLight = &slot->data->color;
|
||||||
setupDark = slot->data->darkColor;
|
setupDark = slot->data->darkColor;
|
||||||
spColor_addFloats(light, (setupLight->r - light->r) * alpha, (setupLight->g - light->g) * alpha, (setupLight->b - light->b) * alpha,
|
spColor_addFloats(light, (setupLight->r - light->r) * alpha, (setupLight->g - light->g) * alpha, (setupLight->b - light->b) * alpha,
|
||||||
(setupLight->a - light->a) * alpha);
|
(setupLight->a - light->a) * alpha);
|
||||||
spColor_addFloats(dark, (setupDark->r - dark->r) * alpha, (setupDark->g - dark->g) * alpha, (setupDark->b - dark->b) * alpha, 0);
|
spColor_addFloats(dark, (setupDark->r - dark->r) * alpha, (setupDark->g - dark->g) * alpha, (setupDark->b - dark->b) * alpha, 0);
|
||||||
case SP_MIX_BLEND_REPLACE:
|
case SP_MIX_BLEND_REPLACE:
|
||||||
case SP_MIX_BLEND_ADD:
|
case SP_MIX_BLEND_ADD:
|
||||||
; /* to appease compiler */
|
; /* to appease compiler */
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -757,7 +767,7 @@ void _spTwoColorTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton
|
|||||||
|
|
||||||
frameTime = self->frames[frame];
|
frameTime = self->frames[frame];
|
||||||
percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / TWOCOLOR_ENTRIES - 1,
|
percent = spCurveTimeline_getCurvePercent(SUPER(self), frame / TWOCOLOR_ENTRIES - 1,
|
||||||
1 - (time - frameTime) / (self->frames[frame + TWOCOLOR_PREV_TIME] - frameTime));
|
1 - (time - frameTime) / (self->frames[frame + TWOCOLOR_PREV_TIME] - frameTime));
|
||||||
|
|
||||||
r += (self->frames[frame + TWOCOLOR_R] - r) * percent;
|
r += (self->frames[frame + TWOCOLOR_R] - r) * percent;
|
||||||
g += (self->frames[frame + TWOCOLOR_G] - g) * percent;
|
g += (self->frames[frame + TWOCOLOR_G] - g) * percent;
|
||||||
@ -819,7 +829,7 @@ void _spAttachmentTimeline_apply (const spTimeline* timeline, spSkeleton* skelet
|
|||||||
|
|
||||||
if (direction == SP_MIX_DIRECTION_OUT && blend == SP_MIX_BLEND_SETUP) {
|
if (direction == SP_MIX_DIRECTION_OUT && blend == SP_MIX_BLEND_SETUP) {
|
||||||
attachmentName = slot->data->attachmentName;
|
attachmentName = slot->data->attachmentName;
|
||||||
spSlot_setAttachment(slot, attachmentName ? spSkeleton_getAttachmentForSlotIndex(skeleton, self->slotIndex, attachmentName) : 0);
|
spSlot_setAttachment(slot, attachmentName ? spSkeleton_getAttachmentForSlotIndex(skeleton, self->slotIndex, attachmentName) : 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -827,7 +837,7 @@ void _spAttachmentTimeline_apply (const spTimeline* timeline, spSkeleton* skelet
|
|||||||
if (blend == SP_MIX_BLEND_SETUP || blend == SP_MIX_BLEND_FIRST) {
|
if (blend == SP_MIX_BLEND_SETUP || blend == SP_MIX_BLEND_FIRST) {
|
||||||
attachmentName = slot->data->attachmentName;
|
attachmentName = slot->data->attachmentName;
|
||||||
spSlot_setAttachment(skeleton->slots[self->slotIndex],
|
spSlot_setAttachment(skeleton->slots[self->slotIndex],
|
||||||
attachmentName ? spSkeleton_getAttachmentForSlotIndex(skeleton, self->slotIndex, attachmentName) : 0);
|
attachmentName ? spSkeleton_getAttachmentForSlotIndex(skeleton, self->slotIndex, attachmentName) : 0);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -839,7 +849,7 @@ void _spAttachmentTimeline_apply (const spTimeline* timeline, spSkeleton* skelet
|
|||||||
|
|
||||||
attachmentName = self->attachmentNames[frameIndex];
|
attachmentName = self->attachmentNames[frameIndex];
|
||||||
spSlot_setAttachment(skeleton->slots[self->slotIndex],
|
spSlot_setAttachment(skeleton->slots[self->slotIndex],
|
||||||
attachmentName ? spSkeleton_getAttachmentForSlotIndex(skeleton, self->slotIndex, attachmentName) : 0);
|
attachmentName ? spSkeleton_getAttachmentForSlotIndex(skeleton, self->slotIndex, attachmentName) : 0);
|
||||||
|
|
||||||
UNUSED(lastTime);
|
UNUSED(lastTime);
|
||||||
UNUSED(firedEvents);
|
UNUSED(firedEvents);
|
||||||
@ -888,7 +898,8 @@ void spAttachmentTimeline_setFrame (spAttachmentTimeline* self, int frameIndex,
|
|||||||
/**/
|
/**/
|
||||||
|
|
||||||
void _spDeformTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
|
void _spDeformTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
|
||||||
int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction) {
|
int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
|
||||||
|
) {
|
||||||
int frame, i, vertexCount;
|
int frame, i, vertexCount;
|
||||||
float percent, frameTime;
|
float percent, frameTime;
|
||||||
const float* prevVertices;
|
const float* prevVertices;
|
||||||
@ -1053,42 +1064,42 @@ void _spDeformTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton,
|
|||||||
} else {
|
} else {
|
||||||
spVertexAttachment* vertexAttachment;
|
spVertexAttachment* vertexAttachment;
|
||||||
switch (blend) {
|
switch (blend) {
|
||||||
case SP_MIX_BLEND_SETUP:
|
case SP_MIX_BLEND_SETUP:
|
||||||
vertexAttachment = SUB_CAST(spVertexAttachment, slot->attachment);
|
vertexAttachment = SUB_CAST(spVertexAttachment, slot->attachment);
|
||||||
if (!vertexAttachment->bones) {
|
if (!vertexAttachment->bones) {
|
||||||
float *setupVertices = vertexAttachment->vertices;
|
float *setupVertices = vertexAttachment->vertices;
|
||||||
for (i = 0; i < vertexCount; i++) {
|
for (i = 0; i < vertexCount; i++) {
|
||||||
float prev = prevVertices[i], setup = setupVertices[i];
|
float prev = prevVertices[i], setup = setupVertices[i];
|
||||||
deformArray[i] = setup + (prev + (nextVertices[i] - prev) * percent - setup) * alpha;
|
deformArray[i] = setup + (prev + (nextVertices[i] - prev) * percent - setup) * alpha;
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for (i = 0; i < vertexCount; i++) {
|
|
||||||
float prev = prevVertices[i];
|
|
||||||
deformArray[i] = (prev + (nextVertices[i] - prev) * percent) * alpha;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
} else {
|
||||||
case SP_MIX_BLEND_FIRST:
|
|
||||||
case SP_MIX_BLEND_REPLACE:
|
|
||||||
for (i = 0; i < vertexCount; i++) {
|
for (i = 0; i < vertexCount; i++) {
|
||||||
float prev = prevVertices[i];
|
float prev = prevVertices[i];
|
||||||
deformArray[i] += (prev + (nextVertices[i] - prev) * percent - deformArray[i]) * alpha;
|
deformArray[i] = (prev + (nextVertices[i] - prev) * percent) * alpha;
|
||||||
}
|
}
|
||||||
break;
|
}
|
||||||
case SP_MIX_BLEND_ADD:
|
break;
|
||||||
vertexAttachment = SUB_CAST(spVertexAttachment, slot->attachment);
|
case SP_MIX_BLEND_FIRST:
|
||||||
if (!vertexAttachment->bones) {
|
case SP_MIX_BLEND_REPLACE:
|
||||||
float *setupVertices = vertexAttachment->vertices;
|
for (i = 0; i < vertexCount; i++) {
|
||||||
for (i = 0; i < vertexCount; i++) {
|
float prev = prevVertices[i];
|
||||||
float prev = prevVertices[i];
|
deformArray[i] += (prev + (nextVertices[i] - prev) * percent - deformArray[i]) * alpha;
|
||||||
deformArray[i] += (prev + (nextVertices[i] - prev) * percent - setupVertices[i]) * alpha;
|
}
|
||||||
}
|
break;
|
||||||
} else {
|
case SP_MIX_BLEND_ADD:
|
||||||
for (i = 0; i < vertexCount; i++) {
|
vertexAttachment = SUB_CAST(spVertexAttachment, slot->attachment);
|
||||||
float prev = prevVertices[i];
|
if (!vertexAttachment->bones) {
|
||||||
deformArray[i] += (prev + (nextVertices[i] - prev) * percent) * alpha;
|
float *setupVertices = vertexAttachment->vertices;
|
||||||
}
|
for (i = 0; i < vertexCount; i++) {
|
||||||
|
float prev = prevVertices[i];
|
||||||
|
deformArray[i] += (prev + (nextVertices[i] - prev) * percent - setupVertices[i]) * alpha;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
for (i = 0; i < vertexCount; i++) {
|
||||||
|
float prev = prevVertices[i];
|
||||||
|
deformArray[i] += (prev + (nextVertices[i] - prev) * percent) * alpha;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1142,7 +1153,8 @@ void spDeformTimeline_setFrame (spDeformTimeline* self, int frameIndex, float ti
|
|||||||
|
|
||||||
/** Fires events for frames > lastTime and <= time. */
|
/** Fires events for frames > lastTime and <= time. */
|
||||||
void _spEventTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
|
void _spEventTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time, spEvent** firedEvents,
|
||||||
int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction) {
|
int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
|
||||||
|
) {
|
||||||
spEventTimeline* self = (spEventTimeline*)timeline;
|
spEventTimeline* self = (spEventTimeline*)timeline;
|
||||||
int frame;
|
int frame;
|
||||||
if (!firedEvents) return;
|
if (!firedEvents) return;
|
||||||
@ -1211,7 +1223,8 @@ void spEventTimeline_setFrame (spEventTimeline* self, int frameIndex, spEvent* e
|
|||||||
/**/
|
/**/
|
||||||
|
|
||||||
void _spDrawOrderTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
|
void _spDrawOrderTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
|
||||||
spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction) {
|
spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
|
||||||
|
) {
|
||||||
int i;
|
int i;
|
||||||
int frame;
|
int frame;
|
||||||
const int* drawOrderToSetupIndex;
|
const int* drawOrderToSetupIndex;
|
||||||
@ -1294,7 +1307,8 @@ static const int IKCONSTRAINT_PREV_TIME = -6, IKCONSTRAINT_PREV_MIX = -5, IKCONS
|
|||||||
static const int IKCONSTRAINT_MIX = 1, IKCONSTRAINT_SOFTNESS = 2, IKCONSTRAINT_BEND_DIRECTION = 3, IKCONSTRAINT_COMPRESS = 4, IKCONSTRAINT_STRETCH = 5;
|
static const int IKCONSTRAINT_MIX = 1, IKCONSTRAINT_SOFTNESS = 2, IKCONSTRAINT_BEND_DIRECTION = 3, IKCONSTRAINT_COMPRESS = 4, IKCONSTRAINT_STRETCH = 5;
|
||||||
|
|
||||||
void _spIkConstraintTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
|
void _spIkConstraintTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
|
||||||
spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction) {
|
spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
|
||||||
|
) {
|
||||||
int frame;
|
int frame;
|
||||||
float frameTime, percent, mix, softness;
|
float frameTime, percent, mix, softness;
|
||||||
float *frames;
|
float *frames;
|
||||||
@ -1333,7 +1347,7 @@ void _spIkConstraintTimeline_apply (const spTimeline* timeline, spSkeleton* skel
|
|||||||
if (blend == SP_MIX_BLEND_SETUP) {
|
if (blend == SP_MIX_BLEND_SETUP) {
|
||||||
constraint->mix = constraint->data->mix + (frames[framesCount + IKCONSTRAINT_PREV_MIX] - constraint->data->mix) * alpha;
|
constraint->mix = constraint->data->mix + (frames[framesCount + IKCONSTRAINT_PREV_MIX] - constraint->data->mix) * alpha;
|
||||||
constraint->softness = constraint->data->softness
|
constraint->softness = constraint->data->softness
|
||||||
+ (frames[framesCount + IKCONSTRAINT_PREV_SOFTNESS] - constraint->data->softness) * alpha;
|
+ (frames[framesCount + IKCONSTRAINT_PREV_SOFTNESS] - constraint->data->softness) * alpha;
|
||||||
if (direction == SP_MIX_DIRECTION_OUT) {
|
if (direction == SP_MIX_DIRECTION_OUT) {
|
||||||
constraint->bendDirection = constraint->data->bendDirection;
|
constraint->bendDirection = constraint->data->bendDirection;
|
||||||
constraint->compress = constraint->data->compress;
|
constraint->compress = constraint->data->compress;
|
||||||
@ -1365,7 +1379,7 @@ void _spIkConstraintTimeline_apply (const spTimeline* timeline, spSkeleton* skel
|
|||||||
if (blend == SP_MIX_BLEND_SETUP) {
|
if (blend == SP_MIX_BLEND_SETUP) {
|
||||||
constraint->mix = constraint->data->mix + (mix + (frames[frame + IKCONSTRAINT_MIX] - mix) * percent - constraint->data->mix) * alpha;
|
constraint->mix = constraint->data->mix + (mix + (frames[frame + IKCONSTRAINT_MIX] - mix) * percent - constraint->data->mix) * alpha;
|
||||||
constraint->softness = constraint->data->softness
|
constraint->softness = constraint->data->softness
|
||||||
+ (softness + (frames[frame + IKCONSTRAINT_SOFTNESS] - softness) * percent - constraint->data->softness) * alpha;
|
+ (softness + (frames[frame + IKCONSTRAINT_SOFTNESS] - softness) * percent - constraint->data->softness) * alpha;
|
||||||
if (direction == SP_MIX_DIRECTION_OUT) {
|
if (direction == SP_MIX_DIRECTION_OUT) {
|
||||||
constraint->bendDirection = constraint->data->bendDirection;
|
constraint->bendDirection = constraint->data->bendDirection;
|
||||||
constraint->compress = constraint->data->compress;
|
constraint->compress = constraint->data->compress;
|
||||||
@ -1398,7 +1412,9 @@ spIkConstraintTimeline* spIkConstraintTimeline_create (int framesCount) {
|
|||||||
return (spIkConstraintTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_IKCONSTRAINT, IKCONSTRAINT_ENTRIES, _spIkConstraintTimeline_apply, _spIkConstraintTimeline_getPropertyId);
|
return (spIkConstraintTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_IKCONSTRAINT, IKCONSTRAINT_ENTRIES, _spIkConstraintTimeline_apply, _spIkConstraintTimeline_getPropertyId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void spIkConstraintTimeline_setFrame (spIkConstraintTimeline* self, int frameIndex, float time, float mix, float softness, int bendDirection, int /*boolean*/ compress, int /*boolean*/ stretch) {
|
void spIkConstraintTimeline_setFrame (spIkConstraintTimeline* self, int frameIndex, float time, float mix, float softness,
|
||||||
|
int bendDirection, int /*boolean*/ compress, int /*boolean*/ stretch
|
||||||
|
) {
|
||||||
frameIndex *= IKCONSTRAINT_ENTRIES;
|
frameIndex *= IKCONSTRAINT_ENTRIES;
|
||||||
self->frames[frameIndex] = time;
|
self->frames[frameIndex] = time;
|
||||||
self->frames[frameIndex + IKCONSTRAINT_MIX] = mix;
|
self->frames[frameIndex + IKCONSTRAINT_MIX] = mix;
|
||||||
@ -1420,7 +1436,8 @@ static const int TRANSFORMCONSTRAINT_SCALE = 3;
|
|||||||
static const int TRANSFORMCONSTRAINT_SHEAR = 4;
|
static const int TRANSFORMCONSTRAINT_SHEAR = 4;
|
||||||
|
|
||||||
void _spTransformConstraintTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
|
void _spTransformConstraintTimeline_apply (const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
|
||||||
spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction) {
|
spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
|
||||||
|
) {
|
||||||
int frame;
|
int frame;
|
||||||
float frameTime, percent, rotate, translate, scale, shear;
|
float frameTime, percent, rotate, translate, scale, shear;
|
||||||
spTransformConstraint* constraint;
|
spTransformConstraint* constraint;
|
||||||
@ -1501,10 +1518,13 @@ int _spTransformConstraintTimeline_getPropertyId (const spTimeline* timeline) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
spTransformConstraintTimeline* spTransformConstraintTimeline_create (int framesCount) {
|
spTransformConstraintTimeline* spTransformConstraintTimeline_create (int framesCount) {
|
||||||
return (spTransformConstraintTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_TRANSFORMCONSTRAINT, TRANSFORMCONSTRAINT_ENTRIES, _spTransformConstraintTimeline_apply, _spTransformConstraintTimeline_getPropertyId);
|
return (spTransformConstraintTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_TRANSFORMCONSTRAINT,
|
||||||
|
TRANSFORMCONSTRAINT_ENTRIES, _spTransformConstraintTimeline_apply, _spTransformConstraintTimeline_getPropertyId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void spTransformConstraintTimeline_setFrame (spTransformConstraintTimeline* self, int frameIndex, float time, float rotateMix, float translateMix, float scaleMix, float shearMix) {
|
void spTransformConstraintTimeline_setFrame (spTransformConstraintTimeline* self, int frameIndex, float time, float rotateMix,
|
||||||
|
float translateMix, float scaleMix, float shearMix
|
||||||
|
) {
|
||||||
frameIndex *= TRANSFORMCONSTRAINT_ENTRIES;
|
frameIndex *= TRANSFORMCONSTRAINT_ENTRIES;
|
||||||
self->frames[frameIndex] = time;
|
self->frames[frameIndex] = time;
|
||||||
self->frames[frameIndex + TRANSFORMCONSTRAINT_ROTATE] = rotateMix;
|
self->frames[frameIndex + TRANSFORMCONSTRAINT_ROTATE] = rotateMix;
|
||||||
@ -1520,7 +1540,8 @@ static const int PATHCONSTRAINTPOSITION_PREV_VALUE = -1;
|
|||||||
static const int PATHCONSTRAINTPOSITION_VALUE = 1;
|
static const int PATHCONSTRAINTPOSITION_VALUE = 1;
|
||||||
|
|
||||||
void _spPathConstraintPositionTimeline_apply(const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
|
void _spPathConstraintPositionTimeline_apply(const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
|
||||||
spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction) {
|
spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
|
||||||
|
) {
|
||||||
int frame;
|
int frame;
|
||||||
float frameTime, percent, position;
|
float frameTime, percent, position;
|
||||||
spPathConstraint* constraint;
|
spPathConstraint* constraint;
|
||||||
@ -1575,7 +1596,8 @@ int _spPathConstraintPositionTimeline_getPropertyId (const spTimeline* timeline)
|
|||||||
}
|
}
|
||||||
|
|
||||||
spPathConstraintPositionTimeline* spPathConstraintPositionTimeline_create (int framesCount) {
|
spPathConstraintPositionTimeline* spPathConstraintPositionTimeline_create (int framesCount) {
|
||||||
return (spPathConstraintPositionTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_PATHCONSTRAINTPOSITION, PATHCONSTRAINTPOSITION_ENTRIES, _spPathConstraintPositionTimeline_apply, _spPathConstraintPositionTimeline_getPropertyId);
|
return (spPathConstraintPositionTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_PATHCONSTRAINTPOSITION,
|
||||||
|
PATHCONSTRAINTPOSITION_ENTRIES, _spPathConstraintPositionTimeline_apply, _spPathConstraintPositionTimeline_getPropertyId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void spPathConstraintPositionTimeline_setFrame (spPathConstraintPositionTimeline* self, int frameIndex, float time, float value) {
|
void spPathConstraintPositionTimeline_setFrame (spPathConstraintPositionTimeline* self, int frameIndex, float time, float value) {
|
||||||
@ -1590,7 +1612,8 @@ static const int PATHCONSTRAINTSPACING_PREV_VALUE = -1;
|
|||||||
static const int PATHCONSTRAINTSPACING_VALUE = 1;
|
static const int PATHCONSTRAINTSPACING_VALUE = 1;
|
||||||
|
|
||||||
void _spPathConstraintSpacingTimeline_apply(const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
|
void _spPathConstraintSpacingTimeline_apply(const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
|
||||||
spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction) {
|
spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
|
||||||
|
) {
|
||||||
int frame;
|
int frame;
|
||||||
float frameTime, percent, spacing;
|
float frameTime, percent, spacing;
|
||||||
spPathConstraint* constraint;
|
spPathConstraint* constraint;
|
||||||
@ -1646,7 +1669,8 @@ int _spPathConstraintSpacingTimeline_getPropertyId (const spTimeline* timeline)
|
|||||||
}
|
}
|
||||||
|
|
||||||
spPathConstraintSpacingTimeline* spPathConstraintSpacingTimeline_create (int framesCount) {
|
spPathConstraintSpacingTimeline* spPathConstraintSpacingTimeline_create (int framesCount) {
|
||||||
return (spPathConstraintSpacingTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_PATHCONSTRAINTSPACING, PATHCONSTRAINTSPACING_ENTRIES, _spPathConstraintSpacingTimeline_apply, _spPathConstraintSpacingTimeline_getPropertyId);
|
return (spPathConstraintSpacingTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_PATHCONSTRAINTSPACING,
|
||||||
|
PATHCONSTRAINTSPACING_ENTRIES, _spPathConstraintSpacingTimeline_apply, _spPathConstraintSpacingTimeline_getPropertyId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void spPathConstraintSpacingTimeline_setFrame (spPathConstraintSpacingTimeline* self, int frameIndex, float time, float value) {
|
void spPathConstraintSpacingTimeline_setFrame (spPathConstraintSpacingTimeline* self, int frameIndex, float time, float value) {
|
||||||
@ -1664,7 +1688,8 @@ static const int PATHCONSTRAINTMIX_ROTATE = 1;
|
|||||||
static const int PATHCONSTRAINTMIX_TRANSLATE = 2;
|
static const int PATHCONSTRAINTMIX_TRANSLATE = 2;
|
||||||
|
|
||||||
void _spPathConstraintMixTimeline_apply(const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
|
void _spPathConstraintMixTimeline_apply(const spTimeline* timeline, spSkeleton* skeleton, float lastTime, float time,
|
||||||
spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction) {
|
spEvent** firedEvents, int* eventsCount, float alpha, spMixBlend blend, spMixDirection direction
|
||||||
|
) {
|
||||||
int frame;
|
int frame;
|
||||||
float frameTime, percent, rotate, translate;
|
float frameTime, percent, rotate, translate;
|
||||||
spPathConstraint* constraint;
|
spPathConstraint* constraint;
|
||||||
@ -1728,7 +1753,8 @@ int _spPathConstraintMixTimeline_getPropertyId (const spTimeline* timeline) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
spPathConstraintMixTimeline* spPathConstraintMixTimeline_create (int framesCount) {
|
spPathConstraintMixTimeline* spPathConstraintMixTimeline_create (int framesCount) {
|
||||||
return (spPathConstraintMixTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_PATHCONSTRAINTMIX, PATHCONSTRAINTMIX_ENTRIES, _spPathConstraintMixTimeline_apply, _spPathConstraintMixTimeline_getPropertyId);
|
return (spPathConstraintMixTimeline*)_spBaseTimeline_create(framesCount, SP_TIMELINE_PATHCONSTRAINTMIX,
|
||||||
|
PATHCONSTRAINTMIX_ENTRIES, _spPathConstraintMixTimeline_apply, _spPathConstraintMixTimeline_getPropertyId);
|
||||||
}
|
}
|
||||||
|
|
||||||
void spPathConstraintMixTimeline_setFrame (spPathConstraintMixTimeline* self, int frameIndex, float time, float rotateMix, float translateMix) {
|
void spPathConstraintMixTimeline_setFrame (spPathConstraintMixTimeline* self, int frameIndex, float time, float rotateMix, float translateMix) {
|
||||||
|
|||||||
@ -46,7 +46,7 @@ void spAnimationState_disposeStatics () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Forward declaration of some "private" functions so we can keep
|
/* Forward declaration of some "private" functions so we can keep
|
||||||
the same function order in C as we have method order in Java */
|
the same function order in C as we have method order in Java. */
|
||||||
void _spAnimationState_disposeTrackEntry (spTrackEntry* entry);
|
void _spAnimationState_disposeTrackEntry (spTrackEntry* entry);
|
||||||
void _spAnimationState_disposeTrackEntries (spAnimationState* state, spTrackEntry* entry);
|
void _spAnimationState_disposeTrackEntries (spAnimationState* state, spTrackEntry* entry);
|
||||||
int /*boolean*/ _spAnimationState_updateMixingFrom (spAnimationState* self, spTrackEntry* entry, float delta);
|
int /*boolean*/ _spAnimationState_updateMixingFrom (spAnimationState* self, spTrackEntry* entry, float delta);
|
||||||
@ -65,7 +65,6 @@ int _spAnimationState_addPropertyID(spAnimationState* self, int id);
|
|||||||
void _spTrackEntry_computeHold(spTrackEntry* self, spAnimationState* state);
|
void _spTrackEntry_computeHold(spTrackEntry* self, spAnimationState* state);
|
||||||
void _spTrackEntry_computeNotLast(spTrackEntry* self, spAnimationState* state);
|
void _spTrackEntry_computeNotLast(spTrackEntry* self, spAnimationState* state);
|
||||||
|
|
||||||
|
|
||||||
_spEventQueue* _spEventQueue_create (_spAnimationState* state) {
|
_spEventQueue* _spEventQueue_create (_spAnimationState* state) {
|
||||||
_spEventQueue *self = CALLOC(_spEventQueue, 1);
|
_spEventQueue *self = CALLOC(_spEventQueue, 1);
|
||||||
self->state = state;
|
self->state = state;
|
||||||
@ -78,7 +77,7 @@ _spEventQueue* _spEventQueue_create (_spAnimationState* state) {
|
|||||||
|
|
||||||
void _spEventQueue_free (_spEventQueue* self) {
|
void _spEventQueue_free (_spEventQueue* self) {
|
||||||
FREE(self->objects);
|
FREE(self->objects);
|
||||||
FREE(self);
|
FREE(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _spEventQueue_ensureCapacity (_spEventQueue* self, int newElements) {
|
void _spEventQueue_ensureCapacity (_spEventQueue* self, int newElements) {
|
||||||
@ -250,7 +249,7 @@ void spAnimationState_dispose (spAnimationState* self) {
|
|||||||
_spEventQueue_free(internal->queue);
|
_spEventQueue_free(internal->queue);
|
||||||
FREE(internal->events);
|
FREE(internal->events);
|
||||||
FREE(internal->propertyIDs);
|
FREE(internal->propertyIDs);
|
||||||
FREE(internal);
|
FREE(internal);
|
||||||
}
|
}
|
||||||
|
|
||||||
void spAnimationState_update (spAnimationState* self, float delta) {
|
void spAnimationState_update (spAnimationState* self, float delta) {
|
||||||
@ -370,9 +369,9 @@ int spAnimationState_apply (spAnimationState* self, spSkeleton* skeleton) {
|
|||||||
/* Apply mixing from entries first. */
|
/* Apply mixing from entries first. */
|
||||||
mix = current->alpha;
|
mix = current->alpha;
|
||||||
if (current->mixingFrom)
|
if (current->mixingFrom)
|
||||||
mix *= _spAnimationState_applyMixingFrom(self, current, skeleton, blend);
|
mix *= _spAnimationState_applyMixingFrom(self, current, skeleton, blend);
|
||||||
else if (current->trackTime >= current->trackEnd && current->next == 0)
|
else if (current->trackTime >= current->trackEnd && current->next == 0)
|
||||||
mix = 0;
|
mix = 0;
|
||||||
|
|
||||||
/* Apply current entry. */
|
/* Apply current entry. */
|
||||||
animationLast = current->animationLast; animationTime = spTrackEntry_getAnimationTime(current);
|
animationLast = current->animationLast; animationTime = spTrackEntry_getAnimationTime(current);
|
||||||
@ -493,7 +492,7 @@ float _spAnimationState_applyMixingFrom (spAnimationState* self, spTrackEntry* t
|
|||||||
from->totalAlpha += alpha;
|
from->totalAlpha += alpha;
|
||||||
if (timeline->type == SP_TIMELINE_ROTATE)
|
if (timeline->type == SP_TIMELINE_ROTATE)
|
||||||
_spAnimationState_applyRotateTimeline(self, timeline, skeleton, animationTime, alpha, timelineBlend,
|
_spAnimationState_applyRotateTimeline(self, timeline, skeleton, animationTime, alpha, timelineBlend,
|
||||||
timelinesRotation, i << 1, firstFrame);
|
timelinesRotation, i << 1, firstFrame);
|
||||||
else {
|
else {
|
||||||
if (timelineBlend == SP_MIX_BLEND_SETUP) {
|
if (timelineBlend == SP_MIX_BLEND_SETUP) {
|
||||||
if (timeline->type == SP_TIMELINE_ATTACHMENT) {
|
if (timeline->type == SP_TIMELINE_ATTACHMENT) {
|
||||||
@ -504,7 +503,7 @@ float _spAnimationState_applyMixingFrom (spAnimationState* self, spTrackEntry* t
|
|||||||
}
|
}
|
||||||
|
|
||||||
spTimeline_apply(timeline, skeleton, animationLast, animationTime, events, &internal->eventsCount,
|
spTimeline_apply(timeline, skeleton, animationLast, animationTime, events, &internal->eventsCount,
|
||||||
alpha, timelineBlend, direction);
|
alpha, timelineBlend, direction);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -518,7 +517,9 @@ float _spAnimationState_applyMixingFrom (spAnimationState* self, spTrackEntry* t
|
|||||||
return mix;
|
return mix;
|
||||||
}
|
}
|
||||||
|
|
||||||
void _spAnimationState_applyRotateTimeline (spAnimationState* self, spTimeline* timeline, spSkeleton* skeleton, float time, float alpha, spMixBlend blend, float* timelinesRotation, int i, int /*boolean*/ firstFrame) {
|
void _spAnimationState_applyRotateTimeline (spAnimationState* self, spTimeline* timeline, spSkeleton* skeleton, float time,
|
||||||
|
float alpha, spMixBlend blend, float* timelinesRotation, int i, int /*boolean*/ firstFrame
|
||||||
|
) {
|
||||||
spRotateTimeline *rotateTimeline;
|
spRotateTimeline *rotateTimeline;
|
||||||
float *frames;
|
float *frames;
|
||||||
spBone* bone;
|
spBone* bone;
|
||||||
@ -562,8 +563,7 @@ void _spAnimationState_applyRotateTimeline (spAnimationState* self, spTimeline*
|
|||||||
prevRotation = frames[frame + ROTATE_PREV_ROTATION];
|
prevRotation = frames[frame + ROTATE_PREV_ROTATION];
|
||||||
frameTime = frames[frame];
|
frameTime = frames[frame];
|
||||||
percent = spCurveTimeline_getCurvePercent(SUPER(rotateTimeline), (frame >> 1) - 1,
|
percent = spCurveTimeline_getCurvePercent(SUPER(rotateTimeline), (frame >> 1) - 1,
|
||||||
1 - (time - frameTime) /
|
1 - (time - frameTime) / (frames[frame + ROTATE_PREV_TIME] - frameTime));
|
||||||
(frames[frame + ROTATE_PREV_TIME] - frameTime));
|
|
||||||
|
|
||||||
r2 = frames[frame + ROTATE_ROTATION] - prevRotation;
|
r2 = frames[frame + ROTATE_ROTATION] - prevRotation;
|
||||||
r2 -= (16384 - (int) (16384.499999999996 - r2 / 360)) * 360;
|
r2 -= (16384 - (int) (16384.499999999996 - r2 / 360)) * 360;
|
||||||
@ -698,8 +698,7 @@ void _spAnimationState_setCurrent (spAnimationState* self, int index, spTrackEnt
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Set the current animation. Any queued animations are cleared. */
|
/** Set the current animation. Any queued animations are cleared. */
|
||||||
spTrackEntry* spAnimationState_setAnimationByName (spAnimationState* self, int trackIndex, const char* animationName,
|
spTrackEntry* spAnimationState_setAnimationByName (spAnimationState* self, int trackIndex, const char* animationName, int/*bool*/loop) {
|
||||||
int/*bool*/loop) {
|
|
||||||
spAnimation* animation = spSkeletonData_findAnimation(self->data->skeletonData, animationName);
|
spAnimation* animation = spSkeletonData_findAnimation(self->data->skeletonData, animationName);
|
||||||
return spAnimationState_setAnimation(self, trackIndex, animation, loop);
|
return spAnimationState_setAnimation(self, trackIndex, animation, loop);
|
||||||
}
|
}
|
||||||
@ -730,13 +729,13 @@ spTrackEntry* spAnimationState_setAnimation (spAnimationState* self, int trackIn
|
|||||||
/** Adds an animation to be played delay seconds after the current or last queued animation, taking into account any mix
|
/** Adds an animation to be played delay seconds after the current or last queued animation, taking into account any mix
|
||||||
* duration. */
|
* duration. */
|
||||||
spTrackEntry* spAnimationState_addAnimationByName (spAnimationState* self, int trackIndex, const char* animationName,
|
spTrackEntry* spAnimationState_addAnimationByName (spAnimationState* self, int trackIndex, const char* animationName,
|
||||||
int/*bool*/loop, float delay) {
|
int/*bool*/loop, float delay
|
||||||
|
) {
|
||||||
spAnimation* animation = spSkeletonData_findAnimation(self->data->skeletonData, animationName);
|
spAnimation* animation = spSkeletonData_findAnimation(self->data->skeletonData, animationName);
|
||||||
return spAnimationState_addAnimation(self, trackIndex, animation, loop, delay);
|
return spAnimationState_addAnimation(self, trackIndex, animation, loop, delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
spTrackEntry* spAnimationState_addAnimation (spAnimationState* self, int trackIndex, spAnimation* animation, int/*bool*/loop,
|
spTrackEntry* spAnimationState_addAnimation (spAnimationState* self, int trackIndex, spAnimation* animation, int/*bool*/loop, float delay) {
|
||||||
float delay) {
|
|
||||||
spTrackEntry* entry;
|
spTrackEntry* entry;
|
||||||
_spAnimationState* internal = SUB_CAST(_spAnimationState, self);
|
_spAnimationState* internal = SUB_CAST(_spAnimationState, self);
|
||||||
spTrackEntry* last = _spAnimationState_expandToIndex(self, trackIndex);
|
spTrackEntry* last = _spAnimationState_expandToIndex(self, trackIndex);
|
||||||
|
|||||||
@ -181,9 +181,8 @@ spAtlas* spAtlas_create(const char* begin, int length, const char* dir, void* re
|
|||||||
self->rendererObject = rendererObject;
|
self->rendererObject = rendererObject;
|
||||||
|
|
||||||
while (readLine(&begin, end, &str)) {
|
while (readLine(&begin, end, &str)) {
|
||||||
if (str.end - str.begin == 0) {
|
if (str.end - str.begin == 0)
|
||||||
page = 0;
|
page = 0;
|
||||||
}
|
|
||||||
else if (!page) {
|
else if (!page) {
|
||||||
char* name = mallocString(&str);
|
char* name = mallocString(&str);
|
||||||
char* path = MALLOC(char, dirLength + needsSlash + strlen(name) + 1);
|
char* path = MALLOC(char, dirLength + needsSlash + strlen(name) + 1);
|
||||||
@ -232,8 +231,7 @@ spAtlas* spAtlas_create(const char* begin, int length, const char* dir, void* re
|
|||||||
|
|
||||||
_spAtlasPage_createTexture(page, path);
|
_spAtlasPage_createTexture(page, path);
|
||||||
FREE(path);
|
FREE(path);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
spAtlasRegion *region = spAtlasRegion_create();
|
spAtlasRegion *region = spAtlasRegion_create();
|
||||||
if (lastRegion)
|
if (lastRegion)
|
||||||
lastRegion->next = region;
|
lastRegion->next = region;
|
||||||
@ -245,13 +243,12 @@ spAtlas* spAtlas_create(const char* begin, int length, const char* dir, void* re
|
|||||||
region->name = mallocString(&str);
|
region->name = mallocString(&str);
|
||||||
|
|
||||||
if (!readValue(&begin, end, &str)) return abortAtlas(self);
|
if (!readValue(&begin, end, &str)) return abortAtlas(self);
|
||||||
if (equals(&str, "true")) {
|
if (equals(&str, "true"))
|
||||||
region->degrees = 90;
|
region->degrees = 90;
|
||||||
} else if (equals(&str, "false")) {
|
else if (equals(&str, "false"))
|
||||||
region->degrees = 0;
|
region->degrees = 0;
|
||||||
} else {
|
else
|
||||||
region->degrees = toInt(&str);
|
region->degrees = toInt(&str);
|
||||||
}
|
|
||||||
region->rotate = region->degrees == 90;
|
region->rotate = region->degrees == 90;
|
||||||
|
|
||||||
if (readTuple(&begin, end, tuple) != 2) return abortAtlas(self);
|
if (readTuple(&begin, end, tuple) != 2) return abortAtlas(self);
|
||||||
@ -267,8 +264,7 @@ spAtlas* spAtlas_create(const char* begin, int length, const char* dir, void* re
|
|||||||
if (region->rotate) {
|
if (region->rotate) {
|
||||||
region->u2 = (region->x + region->height) / (float)page->width;
|
region->u2 = (region->x + region->height) / (float)page->width;
|
||||||
region->v2 = (region->y + region->width) / (float)page->height;
|
region->v2 = (region->y + region->width) / (float)page->height;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
region->u2 = (region->x + region->width) / (float)page->width;
|
region->u2 = (region->x + region->width) / (float)page->width;
|
||||||
region->v2 = (region->y + region->height) / (float)page->height;
|
region->v2 = (region->y + region->height) / (float)page->height;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,8 +32,7 @@
|
|||||||
#include <spine/extension.h>
|
#include <spine/extension.h>
|
||||||
|
|
||||||
typedef struct _spAttachmentLoaderVtable {
|
typedef struct _spAttachmentLoaderVtable {
|
||||||
spAttachment* (*createAttachment) (spAttachmentLoader* self, spSkin* skin, spAttachmentType type, const char* name,
|
spAttachment* (*createAttachment) (spAttachmentLoader* self, spSkin* skin, spAttachmentType type, const char* name, const char* path);
|
||||||
const char* path);
|
|
||||||
void (*configureAttachment) (spAttachmentLoader* self, spAttachment*);
|
void (*configureAttachment) (spAttachmentLoader* self, spAttachment*);
|
||||||
void (*disposeAttachment) (spAttachmentLoader* self, spAttachment*);
|
void (*disposeAttachment) (spAttachmentLoader* self, spAttachment*);
|
||||||
void (*dispose) (spAttachmentLoader* self);
|
void (*dispose) (spAttachmentLoader* self);
|
||||||
|
|||||||
@ -96,78 +96,78 @@ void spBone_updateWorldTransformWith (spBone* self, float x, float y, float rota
|
|||||||
CONST_CAST(float, self->worldY) = pc * x + pd * y + parent->worldY;
|
CONST_CAST(float, self->worldY) = pc * x + pd * y + parent->worldY;
|
||||||
|
|
||||||
switch (self->data->transformMode) {
|
switch (self->data->transformMode) {
|
||||||
case SP_TRANSFORMMODE_NORMAL: {
|
case SP_TRANSFORMMODE_NORMAL: {
|
||||||
float rotationY = rotation + 90 + shearY;
|
float rotationY = rotation + 90 + shearY;
|
||||||
float la = COS_DEG(rotation + shearX) * scaleX;
|
float la = COS_DEG(rotation + shearX) * scaleX;
|
||||||
float lb = COS_DEG(rotationY) * scaleY;
|
float lb = COS_DEG(rotationY) * scaleY;
|
||||||
float lc = SIN_DEG(rotation + shearX) * scaleX;
|
float lc = SIN_DEG(rotation + shearX) * scaleX;
|
||||||
float ld = SIN_DEG(rotationY) * scaleY;
|
float ld = SIN_DEG(rotationY) * scaleY;
|
||||||
CONST_CAST(float, self->a) = pa * la + pb * lc;
|
CONST_CAST(float, self->a) = pa * la + pb * lc;
|
||||||
CONST_CAST(float, self->b) = pa * lb + pb * ld;
|
CONST_CAST(float, self->b) = pa * lb + pb * ld;
|
||||||
CONST_CAST(float, self->c) = pc * la + pd * lc;
|
CONST_CAST(float, self->c) = pc * la + pd * lc;
|
||||||
CONST_CAST(float, self->d) = pc * lb + pd * ld;
|
CONST_CAST(float, self->d) = pc * lb + pd * ld;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case SP_TRANSFORMMODE_ONLYTRANSLATION: {
|
case SP_TRANSFORMMODE_ONLYTRANSLATION: {
|
||||||
float rotationY = rotation + 90 + shearY;
|
float rotationY = rotation + 90 + shearY;
|
||||||
CONST_CAST(float, self->a) = COS_DEG(rotation + shearX) * scaleX;
|
CONST_CAST(float, self->a) = COS_DEG(rotation + shearX) * scaleX;
|
||||||
CONST_CAST(float, self->b) = COS_DEG(rotationY) * scaleY;
|
CONST_CAST(float, self->b) = COS_DEG(rotationY) * scaleY;
|
||||||
CONST_CAST(float, self->c) = SIN_DEG(rotation + shearX) * scaleX;
|
CONST_CAST(float, self->c) = SIN_DEG(rotation + shearX) * scaleX;
|
||||||
CONST_CAST(float, self->d) = SIN_DEG(rotationY) * scaleY;
|
CONST_CAST(float, self->d) = SIN_DEG(rotationY) * scaleY;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SP_TRANSFORMMODE_NOROTATIONORREFLECTION: {
|
case SP_TRANSFORMMODE_NOROTATIONORREFLECTION: {
|
||||||
float s = pa * pa + pc * pc;
|
float s = pa * pa + pc * pc;
|
||||||
float prx, rx, ry, la, lb, lc, ld;
|
float prx, rx, ry, la, lb, lc, ld;
|
||||||
if (s > 0.0001f) {
|
if (s > 0.0001f) {
|
||||||
s = ABS(pa * pd - pb * pc) / s;
|
s = ABS(pa * pd - pb * pc) / s;
|
||||||
pb = pc * s;
|
pb = pc * s;
|
||||||
pd = pa * s;
|
pd = pa * s;
|
||||||
prx = ATAN2(pc, pa) * RAD_DEG;
|
prx = ATAN2(pc, pa) * RAD_DEG;
|
||||||
} else {
|
} else {
|
||||||
pa = 0;
|
pa = 0;
|
||||||
pc = 0;
|
pc = 0;
|
||||||
prx = 90 - ATAN2(pd, pb) * RAD_DEG;
|
prx = 90 - ATAN2(pd, pb) * RAD_DEG;
|
||||||
}
|
|
||||||
rx = rotation + shearX - prx;
|
|
||||||
ry = rotation + shearY - prx + 90;
|
|
||||||
la = COS_DEG(rx) * scaleX;
|
|
||||||
lb = COS_DEG(ry) * scaleY;
|
|
||||||
lc = SIN_DEG(rx) * scaleX;
|
|
||||||
ld = SIN_DEG(ry) * scaleY;
|
|
||||||
CONST_CAST(float, self->a) = pa * la - pb * lc;
|
|
||||||
CONST_CAST(float, self->b) = pa * lb - pb * ld;
|
|
||||||
CONST_CAST(float, self->c) = pc * la + pd * lc;
|
|
||||||
CONST_CAST(float, self->d) = pc * lb + pd * ld;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case SP_TRANSFORMMODE_NOSCALE:
|
|
||||||
case SP_TRANSFORMMODE_NOSCALEORREFLECTION: {
|
|
||||||
float za, zc, s;
|
|
||||||
float r, zb, zd, la, lb, lc, ld;
|
|
||||||
cosine = COS_DEG(rotation); sine = SIN_DEG(rotation);
|
|
||||||
za = (pa * cosine + pb * sine) / sx;
|
|
||||||
zc = (pc * cosine + pd * sine) / sy;
|
|
||||||
s = SQRT(za * za + zc * zc);
|
|
||||||
if (s > 0.00001f) s = 1 / s;
|
|
||||||
za *= s;
|
|
||||||
zc *= s;
|
|
||||||
s = SQRT(za * za + zc * zc);
|
|
||||||
if (self->data->transformMode == SP_TRANSFORMMODE_NOSCALE && (pa * pd - pb * pc < 0) != (sx < 0 != sy < 0))
|
|
||||||
s = -s;
|
|
||||||
r = PI / 2 + ATAN2(zc, za);
|
|
||||||
zb = COS(r) * s;
|
|
||||||
zd = SIN(r) * s;
|
|
||||||
la = COS_DEG(shearX) * scaleX;
|
|
||||||
lb = COS_DEG(90 + shearY) * scaleY;
|
|
||||||
lc = SIN_DEG(shearX) * scaleX;
|
|
||||||
ld = SIN_DEG(90 + shearY) * scaleY;
|
|
||||||
CONST_CAST(float, self->a) = za * la + zb * lc;
|
|
||||||
CONST_CAST(float, self->b) = za * lb + zb * ld;
|
|
||||||
CONST_CAST(float, self->c) = zc * la + zd * lc;
|
|
||||||
CONST_CAST(float, self->d) = zc * lb + zd * ld;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
rx = rotation + shearX - prx;
|
||||||
|
ry = rotation + shearY - prx + 90;
|
||||||
|
la = COS_DEG(rx) * scaleX;
|
||||||
|
lb = COS_DEG(ry) * scaleY;
|
||||||
|
lc = SIN_DEG(rx) * scaleX;
|
||||||
|
ld = SIN_DEG(ry) * scaleY;
|
||||||
|
CONST_CAST(float, self->a) = pa * la - pb * lc;
|
||||||
|
CONST_CAST(float, self->b) = pa * lb - pb * ld;
|
||||||
|
CONST_CAST(float, self->c) = pc * la + pd * lc;
|
||||||
|
CONST_CAST(float, self->d) = pc * lb + pd * ld;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case SP_TRANSFORMMODE_NOSCALE:
|
||||||
|
case SP_TRANSFORMMODE_NOSCALEORREFLECTION: {
|
||||||
|
float za, zc, s;
|
||||||
|
float r, zb, zd, la, lb, lc, ld;
|
||||||
|
cosine = COS_DEG(rotation); sine = SIN_DEG(rotation);
|
||||||
|
za = (pa * cosine + pb * sine) / sx;
|
||||||
|
zc = (pc * cosine + pd * sine) / sy;
|
||||||
|
s = SQRT(za * za + zc * zc);
|
||||||
|
if (s > 0.00001f) s = 1 / s;
|
||||||
|
za *= s;
|
||||||
|
zc *= s;
|
||||||
|
s = SQRT(za * za + zc * zc);
|
||||||
|
if (self->data->transformMode == SP_TRANSFORMMODE_NOSCALE && (pa * pd - pb * pc < 0) != (sx < 0 != sy < 0))
|
||||||
|
s = -s;
|
||||||
|
r = PI / 2 + ATAN2(zc, za);
|
||||||
|
zb = COS(r) * s;
|
||||||
|
zd = SIN(r) * s;
|
||||||
|
la = COS_DEG(shearX) * scaleX;
|
||||||
|
lb = COS_DEG(90 + shearY) * scaleY;
|
||||||
|
lc = SIN_DEG(shearX) * scaleX;
|
||||||
|
ld = SIN_DEG(90 + shearY) * scaleY;
|
||||||
|
CONST_CAST(float, self->a) = za * la + zb * lc;
|
||||||
|
CONST_CAST(float, self->b) = za * lb + zb * ld;
|
||||||
|
CONST_CAST(float, self->c) = zc * la + zd * lc;
|
||||||
|
CONST_CAST(float, self->d) = zc * lb + zd * ld;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CONST_CAST(float, self->a) *= sx;
|
CONST_CAST(float, self->a) *= sx;
|
||||||
|
|||||||
@ -59,12 +59,12 @@ void spIkConstraint_dispose(spIkConstraint *self) {
|
|||||||
|
|
||||||
void spIkConstraint_apply(spIkConstraint *self) {
|
void spIkConstraint_apply(spIkConstraint *self) {
|
||||||
switch (self->bonesCount) {
|
switch (self->bonesCount) {
|
||||||
case 1:
|
case 1:
|
||||||
spIkConstraint_apply1(self->bones[0], self->target->worldX, self->target->worldY, self->compress, self->stretch, self->data->uniform, self->mix);
|
spIkConstraint_apply1(self->bones[0], self->target->worldX, self->target->worldY, self->compress, self->stretch, self->data->uniform, self->mix);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
spIkConstraint_apply2(self->bones[0], self->bones[1], self->target->worldX, self->target->worldY, self->bendDirection, self->stretch, self->softness, self->mix);
|
spIkConstraint_apply2(self->bones[0], self->bones[1], self->target->worldX, self->target->worldY, self->bendDirection, self->stretch, self->softness, self->mix);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,25 +1,25 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2009, Dave Gamble
|
Copyright (c) 2009, Dave Gamble
|
||||||
Copyright (c) 2013, Esoteric Software
|
Copyright (c) 2013, Esoteric Software
|
||||||
|
|
||||||
Permission is hereby granted, dispose of charge, to any person obtaining a copy
|
Permission is hereby granted, dispose of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
furnished to do so, subject to the following conditions:
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
The above copyright notice and this permission notice shall be included in
|
||||||
all copies or substantial portions of the Software.
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
THE SOFTWARE.
|
THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Json */
|
/* Json */
|
||||||
/* JSON parser in C. */
|
/* JSON parser in C. */
|
||||||
@ -54,8 +54,7 @@ const char* Json_getError (void) {
|
|||||||
|
|
||||||
static int Json_strcasecmp (const char* s1, const char* s2) {
|
static int Json_strcasecmp (const char* s1, const char* s2) {
|
||||||
/* TODO we may be able to elide these NULL checks if we can prove
|
/* TODO we may be able to elide these NULL checks if we can prove
|
||||||
* the graph and input (only callsite is Json_getItem) should not have NULLs
|
the graph and input (only callsite is Json_getItem) should not have NULLs */
|
||||||
*/
|
|
||||||
if (s1 && s2) {
|
if (s1 && s2) {
|
||||||
#if defined(_WIN32)
|
#if defined(_WIN32)
|
||||||
return _stricmp(s1, s2);
|
return _stricmp(s1, s2);
|
||||||
|
|||||||
@ -1,16 +1,16 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2009 Dave Gamble
|
Copyright (c) 2009 Dave Gamble
|
||||||
|
|
||||||
Permission is hereby granted, dispose of charge, to any person obtaining a copy
|
Permission is hereby granted, dispose of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
furnished to do so, subject to the following conditions:
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in
|
The above copyright notice and this permission notice shall be included in
|
||||||
all copies or substantial portions of the Software.
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
|||||||
@ -187,7 +187,6 @@ void spMeshAttachment_updateUVs (spMeshAttachment* self) {
|
|||||||
void spMeshAttachment_setParentMesh (spMeshAttachment* self, spMeshAttachment* parentMesh) {
|
void spMeshAttachment_setParentMesh (spMeshAttachment* self, spMeshAttachment* parentMesh) {
|
||||||
CONST_CAST(spMeshAttachment*, self->parentMesh) = parentMesh;
|
CONST_CAST(spMeshAttachment*, self->parentMesh) = parentMesh;
|
||||||
if (parentMesh) {
|
if (parentMesh) {
|
||||||
|
|
||||||
self->super.bones = parentMesh->super.bones;
|
self->super.bones = parentMesh->super.bones;
|
||||||
self->super.bonesCount = parentMesh->super.bonesCount;
|
self->super.bonesCount = parentMesh->super.bonesCount;
|
||||||
|
|
||||||
@ -200,7 +199,7 @@ void spMeshAttachment_setParentMesh (spMeshAttachment* self, spMeshAttachment* p
|
|||||||
self->trianglesCount = parentMesh->trianglesCount;
|
self->trianglesCount = parentMesh->trianglesCount;
|
||||||
|
|
||||||
self->hullLength = parentMesh->hullLength;
|
self->hullLength = parentMesh->hullLength;
|
||||||
|
|
||||||
self->super.worldVerticesLength = parentMesh->super.worldVerticesLength;
|
self->super.worldVerticesLength = parentMesh->super.worldVerticesLength;
|
||||||
|
|
||||||
self->edges = parentMesh->edges;
|
self->edges = parentMesh->edges;
|
||||||
|
|||||||
@ -214,7 +214,7 @@ static void _addAfterPosition (float p, float* temp, int i, float* out, int o) {
|
|||||||
|
|
||||||
/* Need to pass 0 as an argument, so VC++ doesn't error with C2124 */
|
/* Need to pass 0 as an argument, so VC++ doesn't error with C2124 */
|
||||||
static int _isNan(float value, float zero) {
|
static int _isNan(float value, float zero) {
|
||||||
float _nan = (float)0.0 / zero;
|
float _nan = (float)0.0 / zero;
|
||||||
return 0 == memcmp((void*)&value, (void*)&_nan, sizeof(value));
|
return 0 == memcmp((void*)&value, (void*)&_nan, sizeof(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -235,11 +235,10 @@ static void _addCurvePosition (float p, float x1, float y1, float cx1, float cy1
|
|||||||
out[o] = x;
|
out[o] = x;
|
||||||
out[o + 1] = y;
|
out[o + 1] = y;
|
||||||
if (tangents) {
|
if (tangents) {
|
||||||
if (p < 0.001) {
|
if (p < 0.001)
|
||||||
out[o + 2] = ATAN2(cy1 - y1, cx1 - x1);
|
out[o + 2] = ATAN2(cy1 - y1, cx1 - x1);
|
||||||
} else {
|
else
|
||||||
out[o + 2] = ATAN2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt));
|
out[o + 2] = ATAN2(y - (y1 * uu + cy1 * ut * 2 + cy2 * tt), x - (x1 * uu + cx1 * ut * 2 + cx2 * tt));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -251,8 +251,7 @@ static void _sortIkConstraint (_spSkeleton* const internal, spIkConstraint* cons
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!contains)
|
if (!contains) _addToUpdateCacheReset(internal, child);
|
||||||
_addToUpdateCacheReset(internal, child);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_addToUpdateCache(internal, SP_UPDATE_IK_CONSTRAINT, constraint);
|
_addToUpdateCache(internal, SP_UPDATE_IK_CONSTRAINT, constraint);
|
||||||
|
|||||||
@ -35,7 +35,7 @@
|
|||||||
#include <spine/Array.h>
|
#include <spine/Array.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const unsigned char* cursor;
|
const unsigned char* cursor;
|
||||||
const unsigned char* end;
|
const unsigned char* end;
|
||||||
} _dataInput;
|
} _dataInput;
|
||||||
|
|
||||||
@ -118,13 +118,13 @@ static int readVarint (_dataInput* input, int/*bool*/optimizePositive) {
|
|||||||
b = readByte(input);
|
b = readByte(input);
|
||||||
value |= (b & 0x7F) << 7;
|
value |= (b & 0x7F) << 7;
|
||||||
if (b & 0x80) {
|
if (b & 0x80) {
|
||||||
|
b = readByte(input);
|
||||||
|
value |= (b & 0x7F) << 14;
|
||||||
|
if (b & 0x80) {
|
||||||
b = readByte(input);
|
b = readByte(input);
|
||||||
value |= (b & 0x7F) << 14;
|
value |= (b & 0x7F) << 21;
|
||||||
if (b & 0x80) {
|
if (b & 0x80) value |= (readByte(input) & 0x7F) << 28;
|
||||||
b = readByte(input);
|
}
|
||||||
value |= (b & 0x7F) << 21;
|
|
||||||
if (b & 0x80) value |= (readByte(input) & 0x7F) << 28;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!optimizePositive) value = (((unsigned int)value >> 1) ^ -(value & 1));
|
if (!optimizePositive) value = (((unsigned int)value >> 1) ^ -(value & 1));
|
||||||
@ -206,18 +206,18 @@ static void readColor (_dataInput* input, float *r, float *g, float *b, float *a
|
|||||||
|
|
||||||
static void readCurve (_dataInput* input, spCurveTimeline* timeline, int frameIndex) {
|
static void readCurve (_dataInput* input, spCurveTimeline* timeline, int frameIndex) {
|
||||||
switch (readByte(input)) {
|
switch (readByte(input)) {
|
||||||
case CURVE_STEPPED: {
|
case CURVE_STEPPED: {
|
||||||
spCurveTimeline_setStepped(timeline, frameIndex);
|
spCurveTimeline_setStepped(timeline, frameIndex);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CURVE_BEZIER: {
|
case CURVE_BEZIER: {
|
||||||
float cx1 = readFloat(input);
|
float cx1 = readFloat(input);
|
||||||
float cy1 = readFloat(input);
|
float cy1 = readFloat(input);
|
||||||
float cx2 = readFloat(input);
|
float cx2 = readFloat(input);
|
||||||
float cy2 = readFloat(input);
|
float cy2 = readFloat(input);
|
||||||
spCurveTimeline_setCurve(timeline, frameIndex, cx1, cy1, cx2, cy2);
|
spCurveTimeline_setCurve(timeline, frameIndex, cx1, cy1, cx2, cy2);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,56 +264,56 @@ static spAnimation* _spSkeletonBinary_readAnimation (spSkeletonBinary* self, con
|
|||||||
unsigned char timelineType = readByte(input);
|
unsigned char timelineType = readByte(input);
|
||||||
int frameCount = readVarint(input, 1);
|
int frameCount = readVarint(input, 1);
|
||||||
switch (timelineType) {
|
switch (timelineType) {
|
||||||
case SLOT_ATTACHMENT: {
|
case SLOT_ATTACHMENT: {
|
||||||
spAttachmentTimeline* timeline = spAttachmentTimeline_create(frameCount);
|
spAttachmentTimeline* timeline = spAttachmentTimeline_create(frameCount);
|
||||||
timeline->slotIndex = slotIndex;
|
timeline->slotIndex = slotIndex;
|
||||||
for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) {
|
for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) {
|
||||||
float time = readFloat(input);
|
float time = readFloat(input);
|
||||||
const char* attachmentName = readStringRef(input, skeletonData);
|
const char* attachmentName = readStringRef(input, skeletonData);
|
||||||
/* TODO Avoid copying of attachmentName inside */
|
/* TODO Avoid copying of attachmentName inside */
|
||||||
spAttachmentTimeline_setFrame(timeline, frameIndex, time, attachmentName);
|
spAttachmentTimeline_setFrame(timeline, frameIndex, time, attachmentName);
|
||||||
}
|
|
||||||
spTimelineArray_add(timelines, (spTimeline*)timeline);
|
|
||||||
duration = MAX(duration, timeline->frames[frameCount - 1]);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case SLOT_COLOR: {
|
spTimelineArray_add(timelines, (spTimeline*)timeline);
|
||||||
spColorTimeline* timeline = spColorTimeline_create(frameCount);
|
duration = MAX(duration, timeline->frames[frameCount - 1]);
|
||||||
timeline->slotIndex = slotIndex;
|
break;
|
||||||
for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) {
|
}
|
||||||
float time = readFloat(input);
|
case SLOT_COLOR: {
|
||||||
float r, g, b, a;
|
spColorTimeline* timeline = spColorTimeline_create(frameCount);
|
||||||
readColor(input, &r, &g, &b, &a);
|
timeline->slotIndex = slotIndex;
|
||||||
spColorTimeline_setFrame(timeline, frameIndex, time, r, g, b, a);
|
for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) {
|
||||||
if (frameIndex < frameCount - 1) readCurve(input, SUPER(timeline), frameIndex);
|
float time = readFloat(input);
|
||||||
}
|
float r, g, b, a;
|
||||||
spTimelineArray_add(timelines, (spTimeline*)timeline);
|
readColor(input, &r, &g, &b, &a);
|
||||||
duration = MAX(duration, timeline->frames[(frameCount - 1) * COLOR_ENTRIES]);
|
spColorTimeline_setFrame(timeline, frameIndex, time, r, g, b, a);
|
||||||
break;
|
if (frameIndex < frameCount - 1) readCurve(input, SUPER(timeline), frameIndex);
|
||||||
}
|
}
|
||||||
case SLOT_TWO_COLOR: {
|
spTimelineArray_add(timelines, (spTimeline*)timeline);
|
||||||
spTwoColorTimeline* timeline = spTwoColorTimeline_create(frameCount);
|
duration = MAX(duration, timeline->frames[(frameCount - 1) * COLOR_ENTRIES]);
|
||||||
timeline->slotIndex = slotIndex;
|
break;
|
||||||
for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) {
|
}
|
||||||
float time = readFloat(input);
|
case SLOT_TWO_COLOR: {
|
||||||
float r, g, b, a;
|
spTwoColorTimeline* timeline = spTwoColorTimeline_create(frameCount);
|
||||||
float r2, g2, b2, a2;
|
timeline->slotIndex = slotIndex;
|
||||||
readColor(input, &r, &g, &b, &a);
|
for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) {
|
||||||
readColor(input, &a2, &r2, &g2, &b2);
|
float time = readFloat(input);
|
||||||
spTwoColorTimeline_setFrame(timeline, frameIndex, time, r, g, b, a, r2, g2, b2);
|
float r, g, b, a;
|
||||||
if (frameIndex < frameCount - 1) readCurve(input, SUPER(timeline), frameIndex);
|
float r2, g2, b2, a2;
|
||||||
}
|
readColor(input, &r, &g, &b, &a);
|
||||||
spTimelineArray_add(timelines, (spTimeline*)timeline);
|
readColor(input, &a2, &r2, &g2, &b2);
|
||||||
duration = MAX(duration, timeline->frames[(frameCount - 1) * TWOCOLOR_ENTRIES]);
|
spTwoColorTimeline_setFrame(timeline, frameIndex, time, r, g, b, a, r2, g2, b2);
|
||||||
break;
|
if (frameIndex < frameCount - 1) readCurve(input, SUPER(timeline), frameIndex);
|
||||||
}
|
|
||||||
default: {
|
|
||||||
for (iii = 0; iii < timelines->size; ++iii)
|
|
||||||
spTimeline_dispose(timelines->items[iii]);
|
|
||||||
spTimelineArray_dispose(timelines);
|
|
||||||
_spSkeletonBinary_setError(self, "Invalid timeline type for a slot: ", skeletonData->slots[slotIndex]->name);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
spTimelineArray_add(timelines, (spTimeline*)timeline);
|
||||||
|
duration = MAX(duration, timeline->frames[(frameCount - 1) * TWOCOLOR_ENTRIES]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
for (iii = 0; iii < timelines->size; ++iii)
|
||||||
|
spTimeline_dispose(timelines->items[iii]);
|
||||||
|
spTimelineArray_dispose(timelines);
|
||||||
|
_spSkeletonBinary_setError(self, "Invalid timeline type for a slot: ", skeletonData->slots[slotIndex]->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -325,57 +325,57 @@ static spAnimation* _spSkeletonBinary_readAnimation (spSkeletonBinary* self, con
|
|||||||
unsigned char timelineType = readByte(input);
|
unsigned char timelineType = readByte(input);
|
||||||
int frameCount = readVarint(input, 1);
|
int frameCount = readVarint(input, 1);
|
||||||
switch (timelineType) {
|
switch (timelineType) {
|
||||||
case BONE_ROTATE: {
|
case BONE_ROTATE: {
|
||||||
spRotateTimeline *timeline = spRotateTimeline_create(frameCount);
|
spRotateTimeline *timeline = spRotateTimeline_create(frameCount);
|
||||||
timeline->boneIndex = boneIndex;
|
timeline->boneIndex = boneIndex;
|
||||||
for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) {
|
for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) {
|
||||||
float time = readFloat(input);
|
float time = readFloat(input);
|
||||||
float degrees = readFloat(input);
|
float degrees = readFloat(input);
|
||||||
spRotateTimeline_setFrame(timeline, frameIndex, time, degrees);
|
spRotateTimeline_setFrame(timeline, frameIndex, time, degrees);
|
||||||
if (frameIndex < frameCount - 1) readCurve(input, SUPER(timeline), frameIndex);
|
if (frameIndex < frameCount - 1) readCurve(input, SUPER(timeline), frameIndex);
|
||||||
}
|
|
||||||
spTimelineArray_add(timelines, (spTimeline*)timeline);
|
|
||||||
duration = MAX(duration, timeline->frames[(frameCount - 1) * ROTATE_ENTRIES]);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case BONE_TRANSLATE:
|
spTimelineArray_add(timelines, (spTimeline*)timeline);
|
||||||
case BONE_SCALE:
|
duration = MAX(duration, timeline->frames[(frameCount - 1) * ROTATE_ENTRIES]);
|
||||||
case BONE_SHEAR: {
|
break;
|
||||||
float timelineScale = 1;
|
}
|
||||||
spTranslateTimeline *timeline = 0;
|
case BONE_TRANSLATE:
|
||||||
switch (timelineType) {
|
case BONE_SCALE:
|
||||||
case BONE_SCALE:
|
case BONE_SHEAR: {
|
||||||
timeline = spScaleTimeline_create(frameCount);
|
float timelineScale = 1;
|
||||||
break;
|
spTranslateTimeline *timeline = 0;
|
||||||
case BONE_SHEAR:
|
switch (timelineType) {
|
||||||
timeline = spShearTimeline_create(frameCount);
|
case BONE_SCALE:
|
||||||
break;
|
timeline = spScaleTimeline_create(frameCount);
|
||||||
case BONE_TRANSLATE:
|
break;
|
||||||
timeline = spTranslateTimeline_create(frameCount);
|
case BONE_SHEAR:
|
||||||
timelineScale = self->scale;
|
timeline = spShearTimeline_create(frameCount);
|
||||||
break;
|
break;
|
||||||
default:
|
case BONE_TRANSLATE:
|
||||||
break;
|
timeline = spTranslateTimeline_create(frameCount);
|
||||||
}
|
timelineScale = self->scale;
|
||||||
timeline->boneIndex = boneIndex;
|
break;
|
||||||
for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) {
|
default:
|
||||||
float time = readFloat(input);
|
break;
|
||||||
float x = readFloat(input) * timelineScale;
|
|
||||||
float y = readFloat(input) * timelineScale;
|
|
||||||
spTranslateTimeline_setFrame(timeline, frameIndex, time, x, y);
|
|
||||||
if (frameIndex < frameCount - 1) readCurve(input, SUPER(timeline), frameIndex);
|
|
||||||
}
|
|
||||||
spTimelineArray_add(timelines, (spTimeline*)timeline);
|
|
||||||
duration = MAX(duration, timeline->frames[(frameCount - 1) * TRANSLATE_ENTRIES]);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
default: {
|
timeline->boneIndex = boneIndex;
|
||||||
for (iii = 0; iii < timelines->size; ++iii)
|
for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) {
|
||||||
spTimeline_dispose(timelines->items[iii]);
|
float time = readFloat(input);
|
||||||
spTimelineArray_dispose(timelines);
|
float x = readFloat(input) * timelineScale;
|
||||||
_spSkeletonBinary_setError(self, "Invalid timeline type for a bone: ", skeletonData->bones[boneIndex]->name);
|
float y = readFloat(input) * timelineScale;
|
||||||
return 0;
|
spTranslateTimeline_setFrame(timeline, frameIndex, time, x, y);
|
||||||
|
if (frameIndex < frameCount - 1) readCurve(input, SUPER(timeline), frameIndex);
|
||||||
}
|
}
|
||||||
|
spTimelineArray_add(timelines, (spTimeline*)timeline);
|
||||||
|
duration = MAX(duration, timeline->frames[(frameCount - 1) * TRANSLATE_ENTRIES]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
for (iii = 0; iii < timelines->size; ++iii)
|
||||||
|
spTimeline_dispose(timelines->items[iii]);
|
||||||
|
spTimelineArray_dispose(timelines);
|
||||||
|
_spSkeletonBinary_setError(self, "Invalid timeline type for a bone: ", skeletonData->bones[boneIndex]->name);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -413,7 +413,7 @@ static spAnimation* _spSkeletonBinary_readAnimation (spSkeletonBinary* self, con
|
|||||||
float scaleMix = readFloat(input);
|
float scaleMix = readFloat(input);
|
||||||
float shearMix = readFloat(input);
|
float shearMix = readFloat(input);
|
||||||
spTransformConstraintTimeline_setFrame(timeline, frameIndex, time, rotateMix, translateMix,
|
spTransformConstraintTimeline_setFrame(timeline, frameIndex, time, rotateMix, translateMix,
|
||||||
scaleMix, shearMix);
|
scaleMix, shearMix);
|
||||||
if (frameIndex < frameCount - 1) readCurve(input, SUPER(timeline), frameIndex);
|
if (frameIndex < frameCount - 1) readCurve(input, SUPER(timeline), frameIndex);
|
||||||
}
|
}
|
||||||
spTimelineArray_add(timelines, (spTimeline*)timeline);
|
spTimelineArray_add(timelines, (spTimeline*)timeline);
|
||||||
@ -428,43 +428,43 @@ static spAnimation* _spSkeletonBinary_readAnimation (spSkeletonBinary* self, con
|
|||||||
unsigned char timelineType = readByte(input);
|
unsigned char timelineType = readByte(input);
|
||||||
int frameCount = readVarint(input, 1);
|
int frameCount = readVarint(input, 1);
|
||||||
switch (timelineType) {
|
switch (timelineType) {
|
||||||
case PATH_POSITION:
|
case PATH_POSITION:
|
||||||
case PATH_SPACING: {
|
case PATH_SPACING: {
|
||||||
spPathConstraintPositionTimeline* timeline = 0;
|
spPathConstraintPositionTimeline* timeline = 0;
|
||||||
float timelineScale = 1;
|
float timelineScale = 1;
|
||||||
if (timelineType == PATH_SPACING) {
|
if (timelineType == PATH_SPACING) {
|
||||||
timeline = (spPathConstraintPositionTimeline*)spPathConstraintSpacingTimeline_create(frameCount);
|
timeline = (spPathConstraintPositionTimeline*)spPathConstraintSpacingTimeline_create(frameCount);
|
||||||
if (data->spacingMode == SP_SPACING_MODE_LENGTH || data->spacingMode == SP_SPACING_MODE_FIXED)
|
if (data->spacingMode == SP_SPACING_MODE_LENGTH || data->spacingMode == SP_SPACING_MODE_FIXED)
|
||||||
timelineScale = self->scale;
|
timelineScale = self->scale;
|
||||||
} else {
|
} else {
|
||||||
timeline = spPathConstraintPositionTimeline_create(frameCount);
|
timeline = spPathConstraintPositionTimeline_create(frameCount);
|
||||||
if (data->positionMode == SP_POSITION_MODE_FIXED)
|
if (data->positionMode == SP_POSITION_MODE_FIXED)
|
||||||
timelineScale = self->scale;
|
timelineScale = self->scale;
|
||||||
}
|
|
||||||
timeline->pathConstraintIndex = index;
|
|
||||||
for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) {
|
|
||||||
float time = readFloat(input);
|
|
||||||
float value = readFloat(input) * timelineScale;
|
|
||||||
spPathConstraintPositionTimeline_setFrame(timeline, frameIndex, time, value);
|
|
||||||
if (frameIndex < frameCount - 1) readCurve(input, SUPER(timeline), frameIndex);
|
|
||||||
}
|
|
||||||
spTimelineArray_add(timelines, (spTimeline*)timeline);
|
|
||||||
duration = MAX(duration, timeline->frames[(frameCount - 1) * PATHCONSTRAINTPOSITION_ENTRIES]);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case PATH_MIX: {
|
timeline->pathConstraintIndex = index;
|
||||||
spPathConstraintMixTimeline* timeline = spPathConstraintMixTimeline_create(frameCount);
|
for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) {
|
||||||
timeline->pathConstraintIndex = index;
|
float time = readFloat(input);
|
||||||
for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) {
|
float value = readFloat(input) * timelineScale;
|
||||||
float time = readFloat(input);
|
spPathConstraintPositionTimeline_setFrame(timeline, frameIndex, time, value);
|
||||||
float rotateMix = readFloat(input);
|
if (frameIndex < frameCount - 1) readCurve(input, SUPER(timeline), frameIndex);
|
||||||
float translateMix = readFloat(input);
|
|
||||||
spPathConstraintMixTimeline_setFrame(timeline, frameIndex, time, rotateMix, translateMix);
|
|
||||||
if (frameIndex < frameCount - 1) readCurve(input, SUPER(timeline), frameIndex);
|
|
||||||
}
|
|
||||||
spTimelineArray_add(timelines, (spTimeline*)timeline);
|
|
||||||
duration = MAX(duration, timeline->frames[(frameCount - 1) * PATHCONSTRAINTMIX_ENTRIES]);
|
|
||||||
}
|
}
|
||||||
|
spTimelineArray_add(timelines, (spTimeline*)timeline);
|
||||||
|
duration = MAX(duration, timeline->frames[(frameCount - 1) * PATHCONSTRAINTPOSITION_ENTRIES]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case PATH_MIX: {
|
||||||
|
spPathConstraintMixTimeline* timeline = spPathConstraintMixTimeline_create(frameCount);
|
||||||
|
timeline->pathConstraintIndex = index;
|
||||||
|
for (frameIndex = 0; frameIndex < frameCount; ++frameIndex) {
|
||||||
|
float time = readFloat(input);
|
||||||
|
float rotateMix = readFloat(input);
|
||||||
|
float translateMix = readFloat(input);
|
||||||
|
spPathConstraintMixTimeline_setFrame(timeline, frameIndex, time, rotateMix, translateMix);
|
||||||
|
if (frameIndex < frameCount - 1) readCurve(input, SUPER(timeline), frameIndex);
|
||||||
|
}
|
||||||
|
spTimelineArray_add(timelines, (spTimeline*)timeline);
|
||||||
|
duration = MAX(duration, timeline->frames[(frameCount - 1) * PATHCONSTRAINTMIX_ENTRIES]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -482,7 +482,7 @@ static spAnimation* _spSkeletonBinary_readAnimation (spSkeletonBinary* self, con
|
|||||||
int frameCount;
|
int frameCount;
|
||||||
|
|
||||||
spVertexAttachment* attachment = SUB_CAST(spVertexAttachment,
|
spVertexAttachment* attachment = SUB_CAST(spVertexAttachment,
|
||||||
spSkin_getAttachment(skin, slotIndex, attachmentName));
|
spSkin_getAttachment(skin, slotIndex, attachmentName));
|
||||||
if (!attachment) {
|
if (!attachment) {
|
||||||
for (i = 0; i < timelines->size; ++i)
|
for (i = 0; i < timelines->size; ++i)
|
||||||
spTimeline_dispose(timelines->items[i]);
|
spTimeline_dispose(timelines->items[i]);
|
||||||
@ -684,140 +684,140 @@ spAttachment* spSkeletonBinary_readAttachment(spSkeletonBinary* self, _dataInput
|
|||||||
type = (spAttachmentType)readByte(input);
|
type = (spAttachmentType)readByte(input);
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case SP_ATTACHMENT_REGION: {
|
case SP_ATTACHMENT_REGION: {
|
||||||
const char* path = readStringRef(input, skeletonData);
|
const char* path = readStringRef(input, skeletonData);
|
||||||
spAttachment* attachment;
|
spAttachment* attachment;
|
||||||
spRegionAttachment* region;
|
spRegionAttachment* region;
|
||||||
if (!path) MALLOC_STR(path, name);
|
if (!path) MALLOC_STR(path, name);
|
||||||
else {
|
else {
|
||||||
const char* tmp = 0;
|
const char* tmp = 0;
|
||||||
MALLOC_STR(tmp, path);
|
MALLOC_STR(tmp, path);
|
||||||
path = tmp;
|
path = tmp;
|
||||||
}
|
|
||||||
attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, path);
|
|
||||||
region = SUB_CAST(spRegionAttachment, attachment);
|
|
||||||
region->path = path;
|
|
||||||
region->rotation = readFloat(input);
|
|
||||||
region->x = readFloat(input) * self->scale;
|
|
||||||
region->y = readFloat(input) * self->scale;
|
|
||||||
region->scaleX = readFloat(input);
|
|
||||||
region->scaleY = readFloat(input);
|
|
||||||
region->width = readFloat(input) * self->scale;
|
|
||||||
region->height = readFloat(input) * self->scale;
|
|
||||||
readColor(input, ®ion->color.r, ®ion->color.g, ®ion->color.b, ®ion->color.a);
|
|
||||||
spRegionAttachment_updateOffset(region);
|
|
||||||
spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
|
|
||||||
return attachment;
|
|
||||||
}
|
}
|
||||||
case SP_ATTACHMENT_BOUNDING_BOX: {
|
attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, path);
|
||||||
int vertexCount = readVarint(input, 1);
|
region = SUB_CAST(spRegionAttachment, attachment);
|
||||||
spAttachment* attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, 0);
|
region->path = path;
|
||||||
_readVertices(self, input, SUB_CAST(spVertexAttachment, attachment), vertexCount);
|
region->rotation = readFloat(input);
|
||||||
if (nonessential) readInt(input); /* Skip color. */
|
region->x = readFloat(input) * self->scale;
|
||||||
spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
|
region->y = readFloat(input) * self->scale;
|
||||||
return attachment;
|
region->scaleX = readFloat(input);
|
||||||
|
region->scaleY = readFloat(input);
|
||||||
|
region->width = readFloat(input) * self->scale;
|
||||||
|
region->height = readFloat(input) * self->scale;
|
||||||
|
readColor(input, ®ion->color.r, ®ion->color.g, ®ion->color.b, ®ion->color.a);
|
||||||
|
spRegionAttachment_updateOffset(region);
|
||||||
|
spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
|
||||||
|
return attachment;
|
||||||
|
}
|
||||||
|
case SP_ATTACHMENT_BOUNDING_BOX: {
|
||||||
|
int vertexCount = readVarint(input, 1);
|
||||||
|
spAttachment* attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, 0);
|
||||||
|
_readVertices(self, input, SUB_CAST(spVertexAttachment, attachment), vertexCount);
|
||||||
|
if (nonessential) readInt(input); /* Skip color. */
|
||||||
|
spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
|
||||||
|
return attachment;
|
||||||
|
}
|
||||||
|
case SP_ATTACHMENT_MESH: {
|
||||||
|
int vertexCount;
|
||||||
|
spAttachment* attachment;
|
||||||
|
spMeshAttachment* mesh;
|
||||||
|
const char* path = readStringRef(input, skeletonData);
|
||||||
|
if (!path) MALLOC_STR(path, name);
|
||||||
|
else {
|
||||||
|
const char* tmp = 0;
|
||||||
|
MALLOC_STR(tmp, path);
|
||||||
|
path = tmp;
|
||||||
}
|
}
|
||||||
case SP_ATTACHMENT_MESH: {
|
attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, path);
|
||||||
int vertexCount;
|
mesh = SUB_CAST(spMeshAttachment, attachment);
|
||||||
spAttachment* attachment;
|
mesh->path = path;
|
||||||
spMeshAttachment* mesh;
|
readColor(input, &mesh->color.r, &mesh->color.g, &mesh->color.b, &mesh->color.a);
|
||||||
const char* path = readStringRef(input, skeletonData);
|
vertexCount = readVarint(input, 1);
|
||||||
if (!path) MALLOC_STR(path, name);
|
mesh->regionUVs = _readFloatArray(input, vertexCount << 1, 1);
|
||||||
else {
|
mesh->triangles = (unsigned short*)_readShortArray(input, &mesh->trianglesCount);
|
||||||
const char* tmp = 0;
|
_readVertices(self, input, SUPER(mesh), vertexCount);
|
||||||
MALLOC_STR(tmp, path);
|
spMeshAttachment_updateUVs(mesh);
|
||||||
path = tmp;
|
mesh->hullLength = readVarint(input, 1) << 1;
|
||||||
}
|
if (nonessential) {
|
||||||
attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, path);
|
mesh->edges = (int*)_readShortArray(input, &mesh->edgesCount);
|
||||||
mesh = SUB_CAST(spMeshAttachment, attachment);
|
mesh->width = readFloat(input) * self->scale;
|
||||||
mesh->path = path;
|
mesh->height = readFloat(input) * self->scale;
|
||||||
readColor(input, &mesh->color.r, &mesh->color.g, &mesh->color.b, &mesh->color.a);
|
} else {
|
||||||
vertexCount = readVarint(input, 1);
|
mesh->edges = 0;
|
||||||
mesh->regionUVs = _readFloatArray(input, vertexCount << 1, 1);
|
mesh->width = 0;
|
||||||
mesh->triangles = (unsigned short*)_readShortArray(input, &mesh->trianglesCount);
|
mesh->height = 0;
|
||||||
_readVertices(self, input, SUPER(mesh), vertexCount);
|
|
||||||
spMeshAttachment_updateUVs(mesh);
|
|
||||||
mesh->hullLength = readVarint(input, 1) << 1;
|
|
||||||
if (nonessential) {
|
|
||||||
mesh->edges = (int*)_readShortArray(input, &mesh->edgesCount);
|
|
||||||
mesh->width = readFloat(input) * self->scale;
|
|
||||||
mesh->height = readFloat(input) * self->scale;
|
|
||||||
} else {
|
|
||||||
mesh->edges = 0;
|
|
||||||
mesh->width = 0;
|
|
||||||
mesh->height = 0;
|
|
||||||
}
|
|
||||||
spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
|
|
||||||
return attachment;
|
|
||||||
}
|
}
|
||||||
case SP_ATTACHMENT_LINKED_MESH: {
|
spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
|
||||||
const char* skinName;
|
return attachment;
|
||||||
const char* parent;
|
}
|
||||||
spAttachment* attachment;
|
case SP_ATTACHMENT_LINKED_MESH: {
|
||||||
spMeshAttachment* mesh;
|
const char* skinName;
|
||||||
int inheritDeform;
|
const char* parent;
|
||||||
const char* path = readStringRef(input, skeletonData);
|
spAttachment* attachment;
|
||||||
if (!path) MALLOC_STR(path, name);
|
spMeshAttachment* mesh;
|
||||||
else {
|
int inheritDeform;
|
||||||
const char* tmp = 0;
|
const char* path = readStringRef(input, skeletonData);
|
||||||
MALLOC_STR(tmp, path);
|
if (!path) MALLOC_STR(path, name);
|
||||||
path = tmp;
|
else {
|
||||||
}
|
const char* tmp = 0;
|
||||||
attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, path);
|
MALLOC_STR(tmp, path);
|
||||||
mesh = SUB_CAST(spMeshAttachment, attachment);
|
path = tmp;
|
||||||
mesh->path = path;
|
|
||||||
readColor(input, &mesh->color.r, &mesh->color.g, &mesh->color.b, &mesh->color.a);
|
|
||||||
skinName = readStringRef(input, skeletonData);
|
|
||||||
parent = readStringRef(input, skeletonData);
|
|
||||||
inheritDeform = readBoolean(input);
|
|
||||||
if (nonessential) {
|
|
||||||
mesh->width = readFloat(input) * self->scale;
|
|
||||||
mesh->height = readFloat(input) * self->scale;
|
|
||||||
}
|
|
||||||
_spSkeletonBinary_addLinkedMesh(self, mesh, skinName, slotIndex, parent, inheritDeform);
|
|
||||||
return attachment;
|
|
||||||
}
|
}
|
||||||
case SP_ATTACHMENT_PATH: {
|
attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, path);
|
||||||
spAttachment* attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, 0);
|
mesh = SUB_CAST(spMeshAttachment, attachment);
|
||||||
spPathAttachment* path = SUB_CAST(spPathAttachment, attachment);
|
mesh->path = path;
|
||||||
int vertexCount = 0;
|
readColor(input, &mesh->color.r, &mesh->color.g, &mesh->color.b, &mesh->color.a);
|
||||||
path->closed = readBoolean(input);
|
skinName = readStringRef(input, skeletonData);
|
||||||
path->constantSpeed = readBoolean(input);
|
parent = readStringRef(input, skeletonData);
|
||||||
vertexCount = readVarint(input, 1);
|
inheritDeform = readBoolean(input);
|
||||||
_readVertices(self, input, SUPER(path), vertexCount);
|
if (nonessential) {
|
||||||
path->lengthsLength = vertexCount / 3;
|
mesh->width = readFloat(input) * self->scale;
|
||||||
path->lengths = MALLOC(float, path->lengthsLength);
|
mesh->height = readFloat(input) * self->scale;
|
||||||
for (i = 0; i < path->lengthsLength; ++i) {
|
|
||||||
path->lengths[i] = readFloat(input) * self->scale;
|
|
||||||
}
|
|
||||||
if (nonessential) readInt(input); /* Skip color. */
|
|
||||||
spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
|
|
||||||
return attachment;
|
|
||||||
}
|
}
|
||||||
case SP_ATTACHMENT_POINT: {
|
_spSkeletonBinary_addLinkedMesh(self, mesh, skinName, slotIndex, parent, inheritDeform);
|
||||||
spAttachment* attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, 0);
|
return attachment;
|
||||||
spPointAttachment* point = SUB_CAST(spPointAttachment, attachment);
|
}
|
||||||
point->rotation = readFloat(input);
|
case SP_ATTACHMENT_PATH: {
|
||||||
point->x = readFloat(input) * self->scale;
|
spAttachment* attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, 0);
|
||||||
point->y = readFloat(input) * self->scale;
|
spPathAttachment* path = SUB_CAST(spPathAttachment, attachment);
|
||||||
|
int vertexCount = 0;
|
||||||
|
path->closed = readBoolean(input);
|
||||||
|
path->constantSpeed = readBoolean(input);
|
||||||
|
vertexCount = readVarint(input, 1);
|
||||||
|
_readVertices(self, input, SUPER(path), vertexCount);
|
||||||
|
path->lengthsLength = vertexCount / 3;
|
||||||
|
path->lengths = MALLOC(float, path->lengthsLength);
|
||||||
|
for (i = 0; i < path->lengthsLength; ++i) {
|
||||||
|
path->lengths[i] = readFloat(input) * self->scale;
|
||||||
|
}
|
||||||
|
if (nonessential) readInt(input); /* Skip color. */
|
||||||
|
spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
|
||||||
|
return attachment;
|
||||||
|
}
|
||||||
|
case SP_ATTACHMENT_POINT: {
|
||||||
|
spAttachment* attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, 0);
|
||||||
|
spPointAttachment* point = SUB_CAST(spPointAttachment, attachment);
|
||||||
|
point->rotation = readFloat(input);
|
||||||
|
point->x = readFloat(input) * self->scale;
|
||||||
|
point->y = readFloat(input) * self->scale;
|
||||||
|
|
||||||
if (nonessential) {
|
if (nonessential) {
|
||||||
readColor(input, &point->color.r, &point->color.g, &point->color.b, &point->color.a);
|
readColor(input, &point->color.r, &point->color.g, &point->color.b, &point->color.a);
|
||||||
}
|
|
||||||
spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
|
|
||||||
return attachment;
|
|
||||||
}
|
|
||||||
case SP_ATTACHMENT_CLIPPING: {
|
|
||||||
int endSlotIndex = readVarint(input, 1);
|
|
||||||
int vertexCount = readVarint(input, 1);
|
|
||||||
spAttachment* attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, 0);
|
|
||||||
spClippingAttachment* clip = SUB_CAST(spClippingAttachment, attachment);
|
|
||||||
_readVertices(self, input, SUB_CAST(spVertexAttachment, attachment), vertexCount);
|
|
||||||
if (nonessential) readInt(input); /* Skip color. */
|
|
||||||
clip->endSlot = skeletonData->slots[endSlotIndex];
|
|
||||||
spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
|
|
||||||
return attachment;
|
|
||||||
}
|
}
|
||||||
|
spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
|
||||||
|
return attachment;
|
||||||
|
}
|
||||||
|
case SP_ATTACHMENT_CLIPPING: {
|
||||||
|
int endSlotIndex = readVarint(input, 1);
|
||||||
|
int vertexCount = readVarint(input, 1);
|
||||||
|
spAttachment* attachment = spAttachmentLoader_createAttachment(self->attachmentLoader, skin, type, name, 0);
|
||||||
|
spClippingAttachment* clip = SUB_CAST(spClippingAttachment, attachment);
|
||||||
|
_readVertices(self, input, SUB_CAST(spVertexAttachment, attachment), vertexCount);
|
||||||
|
if (nonessential) readInt(input); /* Skip color. */
|
||||||
|
clip->endSlot = skeletonData->slots[endSlotIndex];
|
||||||
|
spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
|
||||||
|
return attachment;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -942,11 +942,11 @@ spSkeletonData* spSkeletonBinary_readSkeletonData (spSkeletonBinary* self, const
|
|||||||
data->length = readFloat(input) * self->scale;
|
data->length = readFloat(input) * self->scale;
|
||||||
mode = readVarint(input, 1);
|
mode = readVarint(input, 1);
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case 0: data->transformMode = SP_TRANSFORMMODE_NORMAL; break;
|
case 0: data->transformMode = SP_TRANSFORMMODE_NORMAL; break;
|
||||||
case 1: data->transformMode = SP_TRANSFORMMODE_ONLYTRANSLATION; break;
|
case 1: data->transformMode = SP_TRANSFORMMODE_ONLYTRANSLATION; break;
|
||||||
case 2: data->transformMode = SP_TRANSFORMMODE_NOROTATIONORREFLECTION; break;
|
case 2: data->transformMode = SP_TRANSFORMMODE_NOROTATIONORREFLECTION; break;
|
||||||
case 3: data->transformMode = SP_TRANSFORMMODE_NOSCALE; break;
|
case 3: data->transformMode = SP_TRANSFORMMODE_NOSCALE; break;
|
||||||
case 4: data->transformMode = SP_TRANSFORMMODE_NOSCALEORREFLECTION; break;
|
case 4: data->transformMode = SP_TRANSFORMMODE_NOSCALEORREFLECTION; break;
|
||||||
}
|
}
|
||||||
data->skinRequired = readBoolean(input);
|
data->skinRequired = readBoolean(input);
|
||||||
if (nonessential) readInt(input); /* Skip bone color. */
|
if (nonessential) readInt(input); /* Skip bone color. */
|
||||||
|
|||||||
@ -166,8 +166,11 @@ int/*bool*/spSkeletonBounds_aabbContainsPoint (spSkeletonBounds* self, float x,
|
|||||||
|
|
||||||
int/*bool*/spSkeletonBounds_aabbIntersectsSegment (spSkeletonBounds* self, float x1, float y1, float x2, float y2) {
|
int/*bool*/spSkeletonBounds_aabbIntersectsSegment (spSkeletonBounds* self, float x1, float y1, float x2, float y2) {
|
||||||
float m, x, y;
|
float m, x, y;
|
||||||
if ((x1 <= self->minX && x2 <= self->minX) || (y1 <= self->minY && y2 <= self->minY) || (x1 >= self->maxX && x2 >= self->maxX)
|
if ((x1 <= self->minX && x2 <= self->minX)
|
||||||
|| (y1 >= self->maxY && y2 >= self->maxY)) return 0;
|
|| (y1 <= self->minY && y2 <= self->minY)
|
||||||
|
|| (x1 >= self->maxX && x2 >= self->maxX)
|
||||||
|
|| (y1 >= self->maxY && y2 >= self->maxY)
|
||||||
|
) return 0;
|
||||||
m = (y2 - y1) / (x2 - x1);
|
m = (y2 - y1) / (x2 - x1);
|
||||||
y = m * (self->minX - x1) + y1;
|
y = m * (self->minX - x1) + y1;
|
||||||
if (y > self->minY && y < self->maxY) return 1;
|
if (y > self->minY && y < self->maxY) return 1;
|
||||||
|
|||||||
@ -93,8 +93,7 @@ static float toColor (const char* value, int index) {
|
|||||||
char *error;
|
char *error;
|
||||||
int color;
|
int color;
|
||||||
|
|
||||||
if ((size_t)index >= strlen(value) / 2)
|
if ((size_t)index >= strlen(value) / 2) return -1;
|
||||||
return -1;
|
|
||||||
value += index * 2;
|
value += index * 2;
|
||||||
|
|
||||||
digits[0] = *value;
|
digits[0] = *value;
|
||||||
@ -120,7 +119,8 @@ static void readCurve (Json* frame, spCurveTimeline* timeline, int frameIndex) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void _spSkeletonJson_addLinkedMesh (spSkeletonJson* self, spMeshAttachment* mesh, const char* skin, int slotIndex,
|
static void _spSkeletonJson_addLinkedMesh (spSkeletonJson* self, spMeshAttachment* mesh, const char* skin, int slotIndex,
|
||||||
const char* parent, int inheritDeform) {
|
const char* parent, int inheritDeform
|
||||||
|
) {
|
||||||
_spLinkedMesh* linkedMesh;
|
_spLinkedMesh* linkedMesh;
|
||||||
_spSkeletonJson* internal = SUB_CAST(_spSkeletonJson, self);
|
_spSkeletonJson* internal = SUB_CAST(_spSkeletonJson, self);
|
||||||
|
|
||||||
@ -195,7 +195,7 @@ static spAnimation* _spSkeletonJson_readAnimation (spSkeletonJson* self, Json* r
|
|||||||
for (valueMap = timelineMap->child, frameIndex = 0; valueMap; valueMap = valueMap->next, ++frameIndex) {
|
for (valueMap = timelineMap->child, frameIndex = 0; valueMap; valueMap = valueMap->next, ++frameIndex) {
|
||||||
Json* name = Json_getItem(valueMap, "name");
|
Json* name = Json_getItem(valueMap, "name");
|
||||||
spAttachmentTimeline_setFrame(timeline, frameIndex, Json_getFloat(valueMap, "time", 0),
|
spAttachmentTimeline_setFrame(timeline, frameIndex, Json_getFloat(valueMap, "time", 0),
|
||||||
name->type == Json_NULL ? 0 : name->valueString);
|
name->type == Json_NULL ? 0 : name->valueString);
|
||||||
}
|
}
|
||||||
animation->timelines[animation->timelinesCount++] = SUPER_CAST(spTimeline, timeline);
|
animation->timelines[animation->timelinesCount++] = SUPER_CAST(spTimeline, timeline);
|
||||||
animation->duration = MAX(animation->duration, timeline->frames[timelineMap->size - 1]);
|
animation->duration = MAX(animation->duration, timeline->frames[timelineMap->size - 1]);
|
||||||
@ -206,8 +206,8 @@ static spAnimation* _spSkeletonJson_readAnimation (spSkeletonJson* self, Json* r
|
|||||||
|
|
||||||
for (valueMap = timelineMap->child, frameIndex = 0; valueMap; valueMap = valueMap->next, ++frameIndex) {
|
for (valueMap = timelineMap->child, frameIndex = 0; valueMap; valueMap = valueMap->next, ++frameIndex) {
|
||||||
const char* s = Json_getString(valueMap, "color", 0);
|
const char* s = Json_getString(valueMap, "color", 0);
|
||||||
spColorTimeline_setFrame(timeline, frameIndex, Json_getFloat(valueMap, "time", 0), toColor(s, 0), toColor(s, 1), toColor(s, 2),
|
spColorTimeline_setFrame(timeline, frameIndex, Json_getFloat(valueMap, "time", 0), toColor(s, 0), toColor(s, 1),
|
||||||
toColor(s, 3));
|
toColor(s, 2), toColor(s, 3));
|
||||||
readCurve(valueMap, SUPER(timeline), frameIndex);
|
readCurve(valueMap, SUPER(timeline), frameIndex);
|
||||||
}
|
}
|
||||||
animation->timelines[animation->timelinesCount++] = SUPER_CAST(spTimeline, timeline);
|
animation->timelines[animation->timelinesCount++] = SUPER_CAST(spTimeline, timeline);
|
||||||
@ -221,7 +221,7 @@ static spAnimation* _spSkeletonJson_readAnimation (spSkeletonJson* self, Json* r
|
|||||||
const char* s = Json_getString(valueMap, "light", 0);
|
const char* s = Json_getString(valueMap, "light", 0);
|
||||||
const char* ds = Json_getString(valueMap, "dark", 0);
|
const char* ds = Json_getString(valueMap, "dark", 0);
|
||||||
spTwoColorTimeline_setFrame(timeline, frameIndex, Json_getFloat(valueMap, "time", 0), toColor(s, 0), toColor(s, 1), toColor(s, 2),
|
spTwoColorTimeline_setFrame(timeline, frameIndex, Json_getFloat(valueMap, "time", 0), toColor(s, 0), toColor(s, 1), toColor(s, 2),
|
||||||
toColor(s, 3), toColor(ds, 0), toColor(ds, 1), toColor(ds, 2));
|
toColor(s, 3), toColor(ds, 0), toColor(ds, 1), toColor(ds, 2));
|
||||||
readCurve(valueMap, SUPER(timeline), frameIndex);
|
readCurve(valueMap, SUPER(timeline), frameIndex);
|
||||||
}
|
}
|
||||||
animation->timelines[animation->timelinesCount++] = SUPER_CAST(spTimeline, timeline);
|
animation->timelines[animation->timelinesCount++] = SUPER_CAST(spTimeline, timeline);
|
||||||
@ -275,8 +275,9 @@ static spAnimation* _spSkeletonJson_readAnimation (spSkeletonJson* self, Json* r
|
|||||||
timeline->boneIndex = boneIndex;
|
timeline->boneIndex = boneIndex;
|
||||||
|
|
||||||
for (valueMap = timelineMap->child, frameIndex = 0; valueMap; valueMap = valueMap->next, ++frameIndex) {
|
for (valueMap = timelineMap->child, frameIndex = 0; valueMap; valueMap = valueMap->next, ++frameIndex) {
|
||||||
spTranslateTimeline_setFrame(timeline, frameIndex, Json_getFloat(valueMap, "time", 0), Json_getFloat(valueMap, "x", defaultValue) * timelineScale,
|
spTranslateTimeline_setFrame(timeline, frameIndex, Json_getFloat(valueMap, "time", 0),
|
||||||
Json_getFloat(valueMap, "y", defaultValue) * timelineScale);
|
Json_getFloat(valueMap, "x", defaultValue) * timelineScale,
|
||||||
|
Json_getFloat(valueMap, "y", defaultValue) * timelineScale);
|
||||||
readCurve(valueMap, SUPER(timeline), frameIndex);
|
readCurve(valueMap, SUPER(timeline), frameIndex);
|
||||||
}
|
}
|
||||||
animation->timelines[animation->timelinesCount++] = SUPER_CAST(spTimeline, timeline);
|
animation->timelines[animation->timelinesCount++] = SUPER_CAST(spTimeline, timeline);
|
||||||
@ -641,16 +642,11 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
|
|||||||
data->shearY = Json_getFloat(boneMap, "shearY", 0);
|
data->shearY = Json_getFloat(boneMap, "shearY", 0);
|
||||||
transformMode = Json_getString(boneMap, "transform", "normal");
|
transformMode = Json_getString(boneMap, "transform", "normal");
|
||||||
data->transformMode = SP_TRANSFORMMODE_NORMAL;
|
data->transformMode = SP_TRANSFORMMODE_NORMAL;
|
||||||
if (strcmp(transformMode, "normal") == 0)
|
if (strcmp(transformMode, "normal") == 0) data->transformMode = SP_TRANSFORMMODE_NORMAL;
|
||||||
data->transformMode = SP_TRANSFORMMODE_NORMAL;
|
else if (strcmp(transformMode, "onlyTranslation") == 0) data->transformMode = SP_TRANSFORMMODE_ONLYTRANSLATION;
|
||||||
if (strcmp(transformMode, "onlyTranslation") == 0)
|
else if (strcmp(transformMode, "noRotationOrReflection") == 0) data->transformMode = SP_TRANSFORMMODE_NOROTATIONORREFLECTION;
|
||||||
data->transformMode = SP_TRANSFORMMODE_ONLYTRANSLATION;
|
else if (strcmp(transformMode, "noScale") == 0) data->transformMode = SP_TRANSFORMMODE_NOSCALE;
|
||||||
if (strcmp(transformMode, "noRotationOrReflection") == 0)
|
else if (strcmp(transformMode, "noScaleOrReflection") == 0) data->transformMode = SP_TRANSFORMMODE_NOSCALEORREFLECTION;
|
||||||
data->transformMode = SP_TRANSFORMMODE_NOROTATIONORREFLECTION;
|
|
||||||
if (strcmp(transformMode, "noScale") == 0)
|
|
||||||
data->transformMode = SP_TRANSFORMMODE_NOSCALE;
|
|
||||||
if (strcmp(transformMode, "noScaleOrReflection") == 0)
|
|
||||||
data->transformMode = SP_TRANSFORMMODE_NOSCALEORREFLECTION;
|
|
||||||
data->skinRequired = Json_getInt(boneMap, "skin", 0) ? 1 : 0;
|
data->skinRequired = Json_getInt(boneMap, "skin", 0) ? 1 : 0;
|
||||||
|
|
||||||
skeletonData->bones[i] = data;
|
skeletonData->bones[i] = data;
|
||||||
@ -682,20 +678,20 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
|
|||||||
color = Json_getString(slotMap, "color", 0);
|
color = Json_getString(slotMap, "color", 0);
|
||||||
if (color) {
|
if (color) {
|
||||||
spColor_setFromFloats(&data->color,
|
spColor_setFromFloats(&data->color,
|
||||||
toColor(color, 0),
|
toColor(color, 0),
|
||||||
toColor(color, 1),
|
toColor(color, 1),
|
||||||
toColor(color, 2),
|
toColor(color, 2),
|
||||||
toColor(color, 3));
|
toColor(color, 3));
|
||||||
}
|
}
|
||||||
|
|
||||||
dark = Json_getString(slotMap, "dark", 0);
|
dark = Json_getString(slotMap, "dark", 0);
|
||||||
if (dark) {
|
if (dark) {
|
||||||
data->darkColor = spColor_create();
|
data->darkColor = spColor_create();
|
||||||
spColor_setFromFloats(data->darkColor,
|
spColor_setFromFloats(data->darkColor,
|
||||||
toColor(dark, 0),
|
toColor(dark, 0),
|
||||||
toColor(dark, 1),
|
toColor(dark, 1),
|
||||||
toColor(dark, 2),
|
toColor(dark, 2),
|
||||||
toColor(dark, 3));
|
toColor(dark, 3));
|
||||||
}
|
}
|
||||||
|
|
||||||
item = Json_getItem(slotMap, "attachment");
|
item = Json_getItem(slotMap, "attachment");
|
||||||
@ -950,20 +946,13 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
|
|||||||
|
|
||||||
const char* typeString = Json_getString(attachmentMap, "type", "region");
|
const char* typeString = Json_getString(attachmentMap, "type", "region");
|
||||||
spAttachmentType type;
|
spAttachmentType type;
|
||||||
if (strcmp(typeString, "region") == 0)
|
if (strcmp(typeString, "region") == 0) type = SP_ATTACHMENT_REGION;
|
||||||
type = SP_ATTACHMENT_REGION;
|
else if (strcmp(typeString, "mesh") == 0) type = SP_ATTACHMENT_MESH;
|
||||||
else if (strcmp(typeString, "mesh") == 0)
|
else if (strcmp(typeString, "linkedmesh") == 0) type = SP_ATTACHMENT_LINKED_MESH;
|
||||||
type = SP_ATTACHMENT_MESH;
|
else if (strcmp(typeString, "boundingbox") == 0) type = SP_ATTACHMENT_BOUNDING_BOX;
|
||||||
else if (strcmp(typeString, "linkedmesh") == 0)
|
else if (strcmp(typeString, "path") == 0) type = SP_ATTACHMENT_PATH;
|
||||||
type = SP_ATTACHMENT_LINKED_MESH;
|
else if (strcmp(typeString, "clipping") == 0) type = SP_ATTACHMENT_CLIPPING;
|
||||||
else if (strcmp(typeString, "boundingbox") == 0)
|
else if (strcmp(typeString, "point") == 0) type = SP_ATTACHMENT_POINT;
|
||||||
type = SP_ATTACHMENT_BOUNDING_BOX;
|
|
||||||
else if (strcmp(typeString, "path") == 0)
|
|
||||||
type = SP_ATTACHMENT_PATH;
|
|
||||||
else if (strcmp(typeString, "clipping") == 0)
|
|
||||||
type = SP_ATTACHMENT_CLIPPING;
|
|
||||||
else if (strcmp(typeString, "point") == 0)
|
|
||||||
type = SP_ATTACHMENT_POINT;
|
|
||||||
else {
|
else {
|
||||||
spSkeletonData_dispose(skeletonData);
|
spSkeletonData_dispose(skeletonData);
|
||||||
_spSkeletonJson_setError(self, root, "Unknown attachment type: ", typeString);
|
_spSkeletonJson_setError(self, root, "Unknown attachment type: ", typeString);
|
||||||
@ -995,10 +984,10 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
|
|||||||
color = Json_getString(attachmentMap, "color", 0);
|
color = Json_getString(attachmentMap, "color", 0);
|
||||||
if (color) {
|
if (color) {
|
||||||
spColor_setFromFloats(®ion->color,
|
spColor_setFromFloats(®ion->color,
|
||||||
toColor(color, 0),
|
toColor(color, 0),
|
||||||
toColor(color, 1),
|
toColor(color, 1),
|
||||||
toColor(color, 2),
|
toColor(color, 2),
|
||||||
toColor(color, 3));
|
toColor(color, 3));
|
||||||
}
|
}
|
||||||
|
|
||||||
spRegionAttachment_updateOffset(region);
|
spRegionAttachment_updateOffset(region);
|
||||||
@ -1015,10 +1004,10 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
|
|||||||
color = Json_getString(attachmentMap, "color", 0);
|
color = Json_getString(attachmentMap, "color", 0);
|
||||||
if (color) {
|
if (color) {
|
||||||
spColor_setFromFloats(&mesh->color,
|
spColor_setFromFloats(&mesh->color,
|
||||||
toColor(color, 0),
|
toColor(color, 0),
|
||||||
toColor(color, 1),
|
toColor(color, 1),
|
||||||
toColor(color, 2),
|
toColor(color, 2),
|
||||||
toColor(color, 3));
|
toColor(color, 3));
|
||||||
}
|
}
|
||||||
|
|
||||||
mesh->width = Json_getFloat(attachmentMap, "width", 32) * self->scale;
|
mesh->width = Json_getFloat(attachmentMap, "width", 32) * self->scale;
|
||||||
@ -1056,8 +1045,8 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
|
|||||||
spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
|
spAttachmentLoader_configureAttachment(self->attachmentLoader, attachment);
|
||||||
} else {
|
} else {
|
||||||
int inheritDeform = Json_getInt(attachmentMap, "deform", 1);
|
int inheritDeform = Json_getInt(attachmentMap, "deform", 1);
|
||||||
_spSkeletonJson_addLinkedMesh(self, SUB_CAST(spMeshAttachment, attachment), Json_getString(attachmentMap, "skin", 0), slot->index,
|
_spSkeletonJson_addLinkedMesh(self, SUB_CAST(spMeshAttachment, attachment),
|
||||||
entry->valueString, inheritDeform);
|
Json_getString(attachmentMap, "skin", 0), slot->index, entry->valueString, inheritDeform);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1081,9 +1070,8 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
|
|||||||
pathAttachment->lengths = MALLOC(float, pathAttachment->lengthsLength);
|
pathAttachment->lengths = MALLOC(float, pathAttachment->lengthsLength);
|
||||||
|
|
||||||
curves = Json_getItem(attachmentMap, "lengths");
|
curves = Json_getItem(attachmentMap, "lengths");
|
||||||
for (curves = curves->child, ii = 0; curves; curves = curves->next, ++ii) {
|
for (curves = curves->child, ii = 0; curves; curves = curves->next, ++ii)
|
||||||
pathAttachment->lengths[ii] = curves->valueFloat * self->scale;
|
pathAttachment->lengths[ii] = curves->valueFloat * self->scale;
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case SP_ATTACHMENT_POINT: {
|
case SP_ATTACHMENT_POINT: {
|
||||||
@ -1095,10 +1083,10 @@ spSkeletonData* spSkeletonJson_readSkeletonData (spSkeletonJson* self, const cha
|
|||||||
color = Json_getString(attachmentMap, "color", 0);
|
color = Json_getString(attachmentMap, "color", 0);
|
||||||
if (color) {
|
if (color) {
|
||||||
spColor_setFromFloats(&point->color,
|
spColor_setFromFloats(&point->color,
|
||||||
toColor(color, 0),
|
toColor(color, 0),
|
||||||
toColor(color, 1),
|
toColor(color, 1),
|
||||||
toColor(color, 2),
|
toColor(color, 2),
|
||||||
toColor(color, 3));
|
toColor(color, 3));
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -226,7 +226,7 @@ void spSkin_copySkin(spSkin* self, const spSkin* other) {
|
|||||||
|
|
||||||
entry = spSkin_getAttachments(other);
|
entry = spSkin_getAttachments(other);
|
||||||
while (entry) {
|
while (entry) {
|
||||||
if (entry->attachment->type == SP_ATTACHMENT_MESH) {
|
if (entry->attachment->type == SP_ATTACHMENT_MESH) {
|
||||||
spMeshAttachment* attachment = spMeshAttachment_newLinkedMesh(SUB_CAST(spMeshAttachment, entry->attachment));
|
spMeshAttachment* attachment = spMeshAttachment_newLinkedMesh(SUB_CAST(spMeshAttachment, entry->attachment));
|
||||||
spSkin_setAttachment(self, entry->slotIndex, entry->name, SUPER(SUPER(attachment)));
|
spSkin_setAttachment(self, entry->slotIndex, entry->name, SUPER(SUPER(attachment)));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -74,7 +74,7 @@ void spSlot_setToSetupPose (spSlot* self) {
|
|||||||
spSlot_setAttachment(self, 0);
|
spSlot_setAttachment(self, 0);
|
||||||
else {
|
else {
|
||||||
spAttachment* attachment = spSkeleton_getAttachmentForSlotIndex(
|
spAttachment* attachment = spSkeleton_getAttachmentForSlotIndex(
|
||||||
self->bone->skeleton, self->data->index, self->data->attachmentName);
|
self->bone->skeleton, self->data->index, self->data->attachmentName);
|
||||||
CONST_CAST(spAttachment*, self->attachment) = 0;
|
CONST_CAST(spAttachment*, self->attachment) = 0;
|
||||||
spSlot_setAttachment(self, attachment);
|
spSlot_setAttachment(self, attachment);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -115,9 +115,9 @@ static int _isConcave(int index, int vertexCount, float* vertices, short* indice
|
|||||||
int previous = indices[(vertexCount + index - 1) % vertexCount] << 1;
|
int previous = indices[(vertexCount + index - 1) % vertexCount] << 1;
|
||||||
int current = indices[index] << 1;
|
int current = indices[index] << 1;
|
||||||
int next = indices[(index + 1) % vertexCount] << 1;
|
int next = indices[(index + 1) % vertexCount] << 1;
|
||||||
return !_positiveArea(vertices[previous], vertices[previous + 1], vertices[current], vertices[current + 1],
|
return !_positiveArea(vertices[previous], vertices[previous + 1],
|
||||||
vertices[next],
|
vertices[current], vertices[current + 1],
|
||||||
vertices[next + 1]);
|
vertices[next], vertices[next + 1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int _winding (float p1x, float p1y, float p2x, float p2y, float p3x, float p3y) {
|
static int _winding (float p1x, float p1y, float p2x, float p2y, float p3x, float p3y) {
|
||||||
|
|||||||
@ -44,7 +44,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#define STRINGIFY(A) #A
|
#define STRINGIFY(A) #A
|
||||||
#define MAX_VERTICES 64000
|
#define MAX_VERTICES 64000
|
||||||
#define MAX_INDICES 64000
|
#define MAX_INDICES 64000
|
||||||
|
|
||||||
@ -76,7 +76,7 @@ const char* TWO_COLOR_TINT_FRAGMENT_SHADER = STRINGIFY(
|
|||||||
\n#ifdef GL_ES\n
|
\n#ifdef GL_ES\n
|
||||||
precision lowp float;
|
precision lowp float;
|
||||||
\n#endif\n
|
\n#endif\n
|
||||||
|
|
||||||
uniform sampler2D texture;
|
uniform sampler2D texture;
|
||||||
|
|
||||||
varying vec4 v_light;
|
varying vec4 v_light;
|
||||||
@ -84,10 +84,10 @@ varying vec4 v_dark;
|
|||||||
varying vec2 v_texCoord;
|
varying vec2 v_texCoord;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
vec4 texColor = texture2D(texture, v_texCoord);
|
vec4 texColor = texture2D(texture, v_texCoord);
|
||||||
float alpha = texColor.a * v_light.a;
|
float alpha = texColor.a * v_light.a;
|
||||||
gl_FragColor.a = alpha;
|
gl_FragColor.a = alpha;
|
||||||
gl_FragColor.rgb = ((texColor.a - 1.0) * v_dark.a + 1.0 - texColor.rgb) * v_dark.rgb + texColor.rgb * v_light.rgb;
|
gl_FragColor.rgb = ((texColor.a - 1.0) * v_dark.a + 1.0 - texColor.rgb) * v_dark.rgb + texColor.rgb * v_light.rgb;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -111,7 +111,7 @@ void spMesh_allocatePart(spMesh* mesh, spMeshPart* part, uint32_t numVertices, u
|
|||||||
mesh->numIndices = mesh->numAllocatedIndices + numIndices;
|
mesh->numIndices = mesh->numAllocatedIndices + numIndices;
|
||||||
mesh->indices = REALLOC(mesh->indices, unsigned short, mesh->numIndices);
|
mesh->indices = REALLOC(mesh->indices, unsigned short, mesh->numIndices);
|
||||||
}
|
}
|
||||||
|
|
||||||
part->mesh = mesh;
|
part->mesh = mesh;
|
||||||
part->startVertex = mesh->numAllocatedVertices;
|
part->startVertex = mesh->numAllocatedVertices;
|
||||||
part->numIndices = numIndices;
|
part->numIndices = numIndices;
|
||||||
@ -120,7 +120,7 @@ void spMesh_allocatePart(spMesh* mesh, spMeshPart* part, uint32_t numVertices, u
|
|||||||
part->textureHandle = textureHandle;
|
part->textureHandle = textureHandle;
|
||||||
part->srcBlend = srcBlend;
|
part->srcBlend = srcBlend;
|
||||||
part->dstBlend = dstBlend;
|
part->dstBlend = dstBlend;
|
||||||
|
|
||||||
mesh->numAllocatedVertices += numVertices;
|
mesh->numAllocatedVertices += numVertices;
|
||||||
mesh->numAllocatedIndices += numIndices;
|
mesh->numAllocatedIndices += numIndices;
|
||||||
}
|
}
|
||||||
@ -161,19 +161,19 @@ GLuint compileShader(GLenum shaderType, const char* shaderSource) {
|
|||||||
spShader* spShader_create(const char* vertexShaderSource, const char* fragmentShaderSource) {
|
spShader* spShader_create(const char* vertexShaderSource, const char* fragmentShaderSource) {
|
||||||
GLuint vertexShader = compileShader(GL_VERTEX_SHADER, vertexShaderSource);
|
GLuint vertexShader = compileShader(GL_VERTEX_SHADER, vertexShaderSource);
|
||||||
GLuint fragmentShader = compileShader(GL_FRAGMENT_SHADER, fragmentShaderSource);
|
GLuint fragmentShader = compileShader(GL_FRAGMENT_SHADER, fragmentShaderSource);
|
||||||
|
|
||||||
GLuint program = glCreateProgram();
|
GLuint program = glCreateProgram();
|
||||||
glAttachShader(program, vertexShader);
|
glAttachShader(program, vertexShader);
|
||||||
glAttachShader(program, fragmentShader);
|
glAttachShader(program, fragmentShader);
|
||||||
glLinkProgram(program);
|
glLinkProgram(program);
|
||||||
|
|
||||||
GLint status;
|
GLint status;
|
||||||
glGetProgramiv(program, GL_LINK_STATUS, &status);
|
glGetProgramiv(program, GL_LINK_STATUS, &status);
|
||||||
if (!status) {
|
if (!status) {
|
||||||
printf("Unknown error while linking program\n");
|
printf("Unknown error while linking program\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
spShader* shader = MALLOC(spShader, 1);
|
spShader* shader = MALLOC(spShader, 1);
|
||||||
shader->program = program;
|
shader->program = program;
|
||||||
shader->vertexShader = vertexShader;
|
shader->vertexShader = vertexShader;
|
||||||
@ -190,14 +190,14 @@ void spShader_dispose(spShader* shader) {
|
|||||||
|
|
||||||
spTwoColorBatcher* spTwoColorBatcher_create() {
|
spTwoColorBatcher* spTwoColorBatcher_create() {
|
||||||
spTwoColorBatcher* batcher = MALLOC(spTwoColorBatcher, 1);
|
spTwoColorBatcher* batcher = MALLOC(spTwoColorBatcher, 1);
|
||||||
|
|
||||||
batcher->shader = spShader_create(TWO_COLOR_TINT_VERTEX_SHADER, TWO_COLOR_TINT_FRAGMENT_SHADER);
|
batcher->shader = spShader_create(TWO_COLOR_TINT_VERTEX_SHADER, TWO_COLOR_TINT_FRAGMENT_SHADER);
|
||||||
batcher->positionAttributeLocation = glGetAttribLocation(batcher->shader->program, "a_position");
|
batcher->positionAttributeLocation = glGetAttribLocation(batcher->shader->program, "a_position");
|
||||||
batcher->colorAttributeLocation = glGetAttribLocation(batcher->shader->program, "a_color");
|
batcher->colorAttributeLocation = glGetAttribLocation(batcher->shader->program, "a_color");
|
||||||
batcher->color2AttributeLocation = glGetAttribLocation(batcher->shader->program, "a_color2");
|
batcher->color2AttributeLocation = glGetAttribLocation(batcher->shader->program, "a_color2");
|
||||||
batcher->texCoordsAttributeLocation = glGetAttribLocation(batcher->shader->program, "a_texCoords");
|
batcher->texCoordsAttributeLocation = glGetAttribLocation(batcher->shader->program, "a_texCoords");
|
||||||
batcher->textureUniformLocation = glGetUniformLocation(batcher->shader->program, "texture");
|
batcher->textureUniformLocation = glGetUniformLocation(batcher->shader->program, "texture");
|
||||||
|
|
||||||
glGenBuffers(1, &batcher->vertexBufferHandle);
|
glGenBuffers(1, &batcher->vertexBufferHandle);
|
||||||
glGenBuffers(1, &batcher->indexBufferHandle);
|
glGenBuffers(1, &batcher->indexBufferHandle);
|
||||||
batcher->verticesBuffer = MALLOC(spVertex, MAX_VERTICES);
|
batcher->verticesBuffer = MALLOC(spVertex, MAX_VERTICES);
|
||||||
@ -214,20 +214,20 @@ void spTwoColorBatcher_add(spTwoColorBatcher* batcher, spMeshPart mesh) {
|
|||||||
if (batcher->numVertices + mesh.numVertices > MAX_VERTICES || batcher->numIndices + mesh.numIndices > MAX_INDICES) {
|
if (batcher->numVertices + mesh.numVertices > MAX_VERTICES || batcher->numIndices + mesh.numIndices > MAX_INDICES) {
|
||||||
spTwoColorBatcher_flush(batcher);
|
spTwoColorBatcher_flush(batcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (batcher->lastTextureHandle != mesh.textureHandle || batcher->lastSrcBlend != mesh.srcBlend || batcher->lastDstBlend != mesh.dstBlend) {
|
if (batcher->lastTextureHandle != mesh.textureHandle || batcher->lastSrcBlend != mesh.srcBlend || batcher->lastDstBlend != mesh.dstBlend) {
|
||||||
spTwoColorBatcher_flush(batcher);
|
spTwoColorBatcher_flush(batcher);
|
||||||
}
|
}
|
||||||
|
|
||||||
spVertex* vertices = &batcher->verticesBuffer[batcher->numVertices];
|
spVertex* vertices = &batcher->verticesBuffer[batcher->numVertices];
|
||||||
unsigned short* indices = &batcher->indicesBuffer[batcher->numIndices];
|
unsigned short* indices = &batcher->indicesBuffer[batcher->numIndices];
|
||||||
|
|
||||||
memcpy(vertices, &mesh.mesh->vertices[mesh.startVertex], mesh.numVertices * sizeof(spVertex));
|
memcpy(vertices, &mesh.mesh->vertices[mesh.startVertex], mesh.numVertices * sizeof(spVertex));
|
||||||
unsigned short offset = (unsigned short)batcher->numVertices;
|
unsigned short offset = (unsigned short)batcher->numVertices;
|
||||||
for (int i = 0, j = mesh.startIndex, n = mesh.numIndices; i < n; i++, j++) {
|
for (int i = 0, j = mesh.startIndex, n = mesh.numIndices; i < n; i++, j++) {
|
||||||
indices[i] = mesh.mesh->indices[j] + offset;
|
indices[i] = mesh.mesh->indices[j] + offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
batcher->numIndices += mesh.numIndices;
|
batcher->numIndices += mesh.numIndices;
|
||||||
batcher->numVertices += mesh.numVertices;
|
batcher->numVertices += mesh.numVertices;
|
||||||
batcher->lastSrcBlend = mesh.srcBlend;
|
batcher->lastSrcBlend = mesh.srcBlend;
|
||||||
@ -238,39 +238,39 @@ void spTwoColorBatcher_add(spTwoColorBatcher* batcher, spMeshPart mesh) {
|
|||||||
void spTwoColorBatcher_flush(spTwoColorBatcher* batcher) {
|
void spTwoColorBatcher_flush(spTwoColorBatcher* batcher) {
|
||||||
if (batcher->numVertices == 0 || batcher->numIndices == 0)
|
if (batcher->numVertices == 0 || batcher->numIndices == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
glUseProgram(batcher->shader->program);
|
glUseProgram(batcher->shader->program);
|
||||||
|
|
||||||
glActiveTexture(GL_TEXTURE0);
|
glActiveTexture(GL_TEXTURE0);
|
||||||
glBindTexture(GL_TEXTURE_2D, batcher->lastTextureHandle);
|
glBindTexture(GL_TEXTURE_2D, batcher->lastTextureHandle);
|
||||||
glUniform1i(batcher->textureUniformLocation, 0);
|
glUniform1i(batcher->textureUniformLocation, 0);
|
||||||
|
|
||||||
glBlendFunc(batcher->lastSrcBlend, batcher->lastDstBlend);
|
glBlendFunc(batcher->lastSrcBlend, batcher->lastDstBlend);
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, batcher->vertexBufferHandle);
|
glBindBuffer(GL_ARRAY_BUFFER, batcher->vertexBufferHandle);
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(spVertex) * batcher->numVertices , batcher->verticesBuffer, GL_DYNAMIC_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, sizeof(spVertex) * batcher->numVertices , batcher->verticesBuffer, GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
glEnableVertexAttribArray(batcher->positionAttributeLocation);
|
glEnableVertexAttribArray(batcher->positionAttributeLocation);
|
||||||
glEnableVertexAttribArray(batcher->colorAttributeLocation);
|
glEnableVertexAttribArray(batcher->colorAttributeLocation);
|
||||||
glEnableVertexAttribArray(batcher->color2AttributeLocation);
|
glEnableVertexAttribArray(batcher->color2AttributeLocation);
|
||||||
glEnableVertexAttribArray(batcher->texCoordsAttributeLocation);
|
glEnableVertexAttribArray(batcher->texCoordsAttributeLocation);
|
||||||
|
|
||||||
glVertexAttribPointer(batcher->positionAttributeLocation, 4, GL_FLOAT, GL_FALSE, sizeof(spVertex), (GLvoid*)offsetof(spVertex, x));
|
glVertexAttribPointer(batcher->positionAttributeLocation, 4, GL_FLOAT, GL_FALSE, sizeof(spVertex), (GLvoid*)offsetof(spVertex, x));
|
||||||
glVertexAttribPointer(batcher->colorAttributeLocation, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(spVertex), (GLvoid*)offsetof(spVertex, color));
|
glVertexAttribPointer(batcher->colorAttributeLocation, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(spVertex), (GLvoid*)offsetof(spVertex, color));
|
||||||
glVertexAttribPointer(batcher->color2AttributeLocation, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(spVertex), (GLvoid*)offsetof(spVertex, color2));
|
glVertexAttribPointer(batcher->color2AttributeLocation, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(spVertex), (GLvoid*)offsetof(spVertex, color2));
|
||||||
glVertexAttribPointer(batcher->texCoordsAttributeLocation, 2, GL_FLOAT, GL_FALSE, sizeof(spVertex), (GLvoid*)offsetof(spVertex, u));
|
glVertexAttribPointer(batcher->texCoordsAttributeLocation, 2, GL_FLOAT, GL_FALSE, sizeof(spVertex), (GLvoid*)offsetof(spVertex, u));
|
||||||
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, batcher->indexBufferHandle);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, batcher->indexBufferHandle);
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short) * batcher->numIndices, batcher->indicesBuffer, GL_STATIC_DRAW);
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short) * batcher->numIndices, batcher->indicesBuffer, GL_STATIC_DRAW);
|
||||||
|
|
||||||
glDrawElements(GL_TRIANGLES, (GLsizei)batcher->numIndices, GL_UNSIGNED_SHORT, 0);
|
glDrawElements(GL_TRIANGLES, (GLsizei)batcher->numIndices, GL_UNSIGNED_SHORT, 0);
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
glUseProgram(0);
|
glUseProgram(0);
|
||||||
glBindTexture(GL_TEXTURE_2D, 0);
|
glBindTexture(GL_TEXTURE_2D, 0);
|
||||||
|
|
||||||
batcher->numIndices = 0;
|
batcher->numIndices = 0;
|
||||||
batcher->numVertices = 0;
|
batcher->numVertices = 0;
|
||||||
batcher->lastSrcBlend = -1;
|
batcher->lastSrcBlend = -1;
|
||||||
|
|||||||
@ -75,21 +75,21 @@ void spShader_dispose(spShader* shader);
|
|||||||
|
|
||||||
typedef struct spTwoColorBatcher {
|
typedef struct spTwoColorBatcher {
|
||||||
spShader* shader;
|
spShader* shader;
|
||||||
|
|
||||||
uint32_t vertexBufferHandle;
|
uint32_t vertexBufferHandle;
|
||||||
spVertex* verticesBuffer;
|
spVertex* verticesBuffer;
|
||||||
uint32_t numVertices;
|
uint32_t numVertices;
|
||||||
|
|
||||||
uint32_t indexBufferHandle;
|
uint32_t indexBufferHandle;
|
||||||
unsigned short* indicesBuffer;
|
unsigned short* indicesBuffer;
|
||||||
uint32_t numIndices;
|
uint32_t numIndices;
|
||||||
|
|
||||||
int32_t positionAttributeLocation;
|
int32_t positionAttributeLocation;
|
||||||
int32_t colorAttributeLocation;
|
int32_t colorAttributeLocation;
|
||||||
int32_t color2AttributeLocation;
|
int32_t color2AttributeLocation;
|
||||||
int32_t texCoordsAttributeLocation;
|
int32_t texCoordsAttributeLocation;
|
||||||
int32_t textureUniformLocation;
|
int32_t textureUniformLocation;
|
||||||
|
|
||||||
uint32_t lastTextureHandle;
|
uint32_t lastTextureHandle;
|
||||||
uint32_t lastSrcBlend;
|
uint32_t lastSrcBlend;
|
||||||
uint32_t lastDstBlend;
|
uint32_t lastDstBlend;
|
||||||
|
|||||||
@ -48,9 +48,9 @@ typedef void(^spEventListener)(spTrackEntry* entry, spEvent* event);
|
|||||||
float _timeScale;
|
float _timeScale;
|
||||||
|
|
||||||
spStartListener _startListener;
|
spStartListener _startListener;
|
||||||
spInterruptListener _interruptListener;
|
spInterruptListener _interruptListener;
|
||||||
spEndListener _endListener;
|
spEndListener _endListener;
|
||||||
spDisposeListener _disposeListener;
|
spDisposeListener _disposeListener;
|
||||||
spCompleteListener _completeListener;
|
spCompleteListener _completeListener;
|
||||||
spEventListener _eventListener;
|
spEventListener _eventListener;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -107,27 +107,27 @@ static _TrackEntryListeners* getListeners (spTrackEntry* entry) {
|
|||||||
- (id) initWithData:(spSkeletonData*)skeletonData ownsSkeletonData:(bool)ownsSkeletonData {
|
- (id) initWithData:(spSkeletonData*)skeletonData ownsSkeletonData:(bool)ownsSkeletonData {
|
||||||
self = [super initWithData:skeletonData ownsSkeletonData:ownsSkeletonData];
|
self = [super initWithData:skeletonData ownsSkeletonData:ownsSkeletonData];
|
||||||
if (!self) return nil;
|
if (!self) return nil;
|
||||||
|
|
||||||
[self initialize];
|
[self initialize];
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) initWithFile:(NSString*)skeletonDataFile atlas:(spAtlas*)atlas scale:(float)scale {
|
- (id) initWithFile:(NSString*)skeletonDataFile atlas:(spAtlas*)atlas scale:(float)scale {
|
||||||
self = [super initWithFile:skeletonDataFile atlas:atlas scale:scale];
|
self = [super initWithFile:skeletonDataFile atlas:atlas scale:scale];
|
||||||
if (!self) return nil;
|
if (!self) return nil;
|
||||||
|
|
||||||
[self initialize];
|
[self initialize];
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id) initWithFile:(NSString*)skeletonDataFile atlasFile:(NSString*)atlasFile scale:(float)scale {
|
- (id) initWithFile:(NSString*)skeletonDataFile atlasFile:(NSString*)atlasFile scale:(float)scale {
|
||||||
self = [super initWithFile:skeletonDataFile atlasFile:atlasFile scale:scale];
|
self = [super initWithFile:skeletonDataFile atlasFile:atlasFile scale:scale];
|
||||||
if (!self) return nil;
|
if (!self) return nil;
|
||||||
|
|
||||||
[self initialize];
|
[self initialize];
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,7 +155,7 @@ static _TrackEntryListeners* getListeners (spTrackEntry* entry) {
|
|||||||
|
|
||||||
- (void) setAnimationStateData:(spAnimationStateData*)stateData {
|
- (void) setAnimationStateData:(spAnimationStateData*)stateData {
|
||||||
NSAssert(stateData, @"stateData cannot be null.");
|
NSAssert(stateData, @"stateData cannot be null.");
|
||||||
|
|
||||||
if (_ownsAnimationStateData) spAnimationStateData_dispose(_state->data);
|
if (_ownsAnimationStateData) spAnimationStateData_dispose(_state->data);
|
||||||
spAnimationState_dispose(_state);
|
spAnimationState_dispose(_state);
|
||||||
|
|
||||||
|
|||||||
@ -38,7 +38,7 @@
|
|||||||
bool _debugBones;
|
bool _debugBones;
|
||||||
bool _premultipliedAlpha;
|
bool _premultipliedAlpha;
|
||||||
bool _twoColorTint;
|
bool _twoColorTint;
|
||||||
bool _skipVisibilityCheck;
|
bool _skipVisibilityCheck;
|
||||||
ccBlendFunc _blendFunc;
|
ccBlendFunc _blendFunc;
|
||||||
CCDrawNode* _drawNode;
|
CCDrawNode* _drawNode;
|
||||||
bool _ownsSkeletonData;
|
bool _ownsSkeletonData;
|
||||||
|
|||||||
@ -68,7 +68,7 @@ static bool handlerQueued = false;
|
|||||||
batcher = spTwoColorBatcher_create();
|
batcher = spTwoColorBatcher_create();
|
||||||
mesh = spMesh_create(64000, 32000);
|
mesh = spMesh_create(64000, 32000);
|
||||||
}
|
}
|
||||||
|
|
||||||
_ownsSkeletonData = ownsSkeletonData;
|
_ownsSkeletonData = ownsSkeletonData;
|
||||||
|
|
||||||
_worldVertices = MALLOC(float, 1000); // Max number of vertices per mesh.
|
_worldVertices = MALLOC(float, 1000); // Max number of vertices per mesh.
|
||||||
@ -81,7 +81,7 @@ static bool handlerQueued = false;
|
|||||||
_drawNode = [[CCDrawNode alloc] init];
|
_drawNode = [[CCDrawNode alloc] init];
|
||||||
[_drawNode setBlendMode: [CCBlendMode premultipliedAlphaMode]];
|
[_drawNode setBlendMode: [CCBlendMode premultipliedAlphaMode]];
|
||||||
[self addChild:_drawNode];
|
[self addChild:_drawNode];
|
||||||
|
|
||||||
[self setShader:[CCShader positionTextureColorShader]];
|
[self setShader:[CCShader positionTextureColorShader]];
|
||||||
|
|
||||||
_premultipliedAlpha = true;
|
_premultipliedAlpha = true;
|
||||||
@ -89,7 +89,7 @@ static bool handlerQueued = false;
|
|||||||
CCBlendFuncSrcColor: @(GL_ONE),
|
CCBlendFuncSrcColor: @(GL_ONE),
|
||||||
CCBlendFuncDstColor: @(GL_ONE_MINUS_SRC_COLOR)}
|
CCBlendFuncDstColor: @(GL_ONE_MINUS_SRC_COLOR)}
|
||||||
];
|
];
|
||||||
|
|
||||||
_clipper = spSkeletonClipping_create();
|
_clipper = spSkeletonClipping_create();
|
||||||
_effect = 0;
|
_effect = 0;
|
||||||
}
|
}
|
||||||
@ -167,15 +167,15 @@ static bool handlerQueued = false;
|
|||||||
// notification system that may break if the block is called on a
|
// notification system that may break if the block is called on a
|
||||||
// separate thread.
|
// separate thread.
|
||||||
if (!handlerQueued) {
|
if (!handlerQueued) {
|
||||||
[[CCDirector sharedDirector] addFrameCompletionHandler: ^{
|
[[CCDirector sharedDirector] addFrameCompletionHandler: ^{
|
||||||
spMesh_clearParts(mesh);
|
spMesh_clearParts(mesh);
|
||||||
handlerQueued = false;
|
handlerQueued = false;
|
||||||
}];
|
}];
|
||||||
handlerQueued = true;
|
handlerQueued = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_effect) _effect->begin(_effect, _skeleton);
|
if (_effect) _effect->begin(_effect, _skeleton);
|
||||||
|
|
||||||
CCColor* nodeColor = self.color;
|
CCColor* nodeColor = self.color;
|
||||||
_skeleton->color.r = nodeColor.red;
|
_skeleton->color.r = nodeColor.red;
|
||||||
_skeleton->color.g = nodeColor.green;
|
_skeleton->color.g = nodeColor.green;
|
||||||
@ -232,7 +232,7 @@ static bool handlerQueued = false;
|
|||||||
}
|
}
|
||||||
default: ;
|
default: ;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (texture) {
|
if (texture) {
|
||||||
if (slot->data->blendMode != blendMode) {
|
if (slot->data->blendMode != blendMode) {
|
||||||
blendMode = slot->data->blendMode;
|
blendMode = slot->data->blendMode;
|
||||||
@ -283,9 +283,9 @@ static bool handlerQueued = false;
|
|||||||
GLKVector2 extents = GLKVector2Make((maxX - minX) / 2, (maxY - minY) / 2);
|
GLKVector2 extents = GLKVector2Make((maxX - minX) / 2, (maxY - minY) / 2);
|
||||||
isVisible = CCRenderCheckVisbility(transform, center, extents);
|
isVisible = CCRenderCheckVisbility(transform, center, extents);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isVisible) {
|
if (isVisible) {
|
||||||
|
|
||||||
if (spSkeletonClipping_isClipping(_clipper)) {
|
if (spSkeletonClipping_isClipping(_clipper)) {
|
||||||
spSkeletonClipping_clipTriangles(_clipper, vertices, verticesCount, triangles, trianglesCount, uvs, 2);
|
spSkeletonClipping_clipTriangles(_clipper, vertices, verticesCount, triangles, trianglesCount, uvs, 2);
|
||||||
vertices = _clipper->clippedVertices->items;
|
vertices = _clipper->clippedVertices->items;
|
||||||
@ -294,7 +294,7 @@ static bool handlerQueued = false;
|
|||||||
triangles = _clipper->clippedTriangles->items;
|
triangles = _clipper->clippedTriangles->items;
|
||||||
trianglesCount = _clipper->clippedTriangles->size;
|
trianglesCount = _clipper->clippedTriangles->size;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (trianglesCount > 0) {
|
if (trianglesCount > 0) {
|
||||||
if (!self.twoColorTint) {
|
if (!self.twoColorTint) {
|
||||||
CCRenderBuffer buffer = [renderer enqueueTriangles:(trianglesCount / 3) andVertexes:verticesCount withState:self.renderState globalSortOrder:0];
|
CCRenderBuffer buffer = [renderer enqueueTriangles:(trianglesCount / 3) andVertexes:verticesCount withState:self.renderState globalSortOrder:0];
|
||||||
@ -330,13 +330,13 @@ static bool handlerQueued = false;
|
|||||||
} else {
|
} else {
|
||||||
dr = dg = db = 0;
|
dr = dg = db = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
spMeshPart meshPart;
|
spMeshPart meshPart;
|
||||||
spMesh_allocatePart(mesh, &meshPart, verticesCount / 2, trianglesCount, self.texture.name, srcBlend, dstBlend);
|
spMesh_allocatePart(mesh, &meshPart, verticesCount / 2, trianglesCount, self.texture.name, srcBlend, dstBlend);
|
||||||
|
|
||||||
spVertex* verts = &meshPart.mesh->vertices[meshPart.startVertex];
|
spVertex* verts = &meshPart.mesh->vertices[meshPart.startVertex];
|
||||||
unsigned short* indices = &meshPart.mesh->indices[meshPart.startIndex];
|
unsigned short* indices = &meshPart.mesh->indices[meshPart.startIndex];
|
||||||
|
|
||||||
if (_effect) {
|
if (_effect) {
|
||||||
spColor light;
|
spColor light;
|
||||||
light.r = r;
|
light.r = r;
|
||||||
@ -351,13 +351,13 @@ static bool handlerQueued = false;
|
|||||||
for (int i = 0; i * 2 < verticesCount; i++, verts++) {
|
for (int i = 0; i * 2 < verticesCount; i++, verts++) {
|
||||||
spColor lightCopy = light;
|
spColor lightCopy = light;
|
||||||
spColor darkCopy = dark;
|
spColor darkCopy = dark;
|
||||||
|
|
||||||
CCVertex vertex;
|
CCVertex vertex;
|
||||||
vertex.position = GLKVector4Make(vertices[i * 2], vertices[i * 2 + 1], 0.0, 1.0);
|
vertex.position = GLKVector4Make(vertices[i * 2], vertices[i * 2 + 1], 0.0, 1.0);
|
||||||
verts->u = uvs[i * 2];
|
verts->u = uvs[i * 2];
|
||||||
verts->v = 1 - uvs[i * 2 + 1];
|
verts->v = 1 - uvs[i * 2 + 1];
|
||||||
_effect->transform(_effect, &vertex.position.x, &vertex.position.y, &verts->u, &verts->v, &lightCopy, &darkCopy);
|
_effect->transform(_effect, &vertex.position.x, &vertex.position.y, &verts->u, &verts->v, &lightCopy, &darkCopy);
|
||||||
|
|
||||||
vertex = CCVertexApplyTransform(vertex, transform);
|
vertex = CCVertexApplyTransform(vertex, transform);
|
||||||
verts->x = vertex.position.x;
|
verts->x = vertex.position.x;
|
||||||
verts->y = vertex.position.y;
|
verts->y = vertex.position.y;
|
||||||
@ -365,7 +365,7 @@ static bool handlerQueued = false;
|
|||||||
verts->w = vertex.position.w;
|
verts->w = vertex.position.w;
|
||||||
verts->color = ((unsigned short)(lightCopy.r * 255))| ((unsigned short)(lightCopy.g * 255)) << 8 | ((unsigned short)(lightCopy.b * 255)) <<16 | ((unsigned short)(lightCopy.a * 255)) << 24;
|
verts->color = ((unsigned short)(lightCopy.r * 255))| ((unsigned short)(lightCopy.g * 255)) << 8 | ((unsigned short)(lightCopy.b * 255)) <<16 | ((unsigned short)(lightCopy.a * 255)) << 24;
|
||||||
verts->color2 = ((unsigned short)(darkCopy.r * 255)) | ((unsigned short)(darkCopy.g * 255)) << 8 | ((unsigned short)(darkCopy.b * 255)) << 16 | ((unsigned short)(darkCopy.a * 255)) << 24;
|
verts->color2 = ((unsigned short)(darkCopy.r * 255)) | ((unsigned short)(darkCopy.g * 255)) << 8 | ((unsigned short)(darkCopy.b * 255)) << 16 | ((unsigned short)(darkCopy.a * 255)) << 24;
|
||||||
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i * 2 < verticesCount; i++, verts++) {
|
for (int i = 0; i * 2 < verticesCount; i++, verts++) {
|
||||||
@ -382,11 +382,11 @@ static bool handlerQueued = false;
|
|||||||
verts->v = 1 - uvs[i * 2 + 1];
|
verts->v = 1 - uvs[i * 2 + 1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int j = 0; j < trianglesCount; j++, indices++) {
|
for (int j = 0; j < trianglesCount; j++, indices++) {
|
||||||
*indices = triangles[j];
|
*indices = triangles[j];
|
||||||
}
|
}
|
||||||
|
|
||||||
[renderer enqueueBlock:^{
|
[renderer enqueueBlock:^{
|
||||||
spTwoColorBatcher_add(batcher, meshPart);
|
spTwoColorBatcher_add(batcher, meshPart);
|
||||||
} globalSortOrder:0 debugLabel: nil threadSafe: false];
|
} globalSortOrder:0 debugLabel: nil threadSafe: false];
|
||||||
@ -397,13 +397,13 @@ static bool handlerQueued = false;
|
|||||||
spSkeletonClipping_clipEnd(_clipper, slot);
|
spSkeletonClipping_clipEnd(_clipper, slot);
|
||||||
}
|
}
|
||||||
spSkeletonClipping_clipEnd2(_clipper);
|
spSkeletonClipping_clipEnd2(_clipper);
|
||||||
|
|
||||||
if (self.twoColorTint) {
|
if (self.twoColorTint) {
|
||||||
[renderer enqueueBlock:^{
|
[renderer enqueueBlock:^{
|
||||||
spTwoColorBatcher_flush(batcher);
|
spTwoColorBatcher_flush(batcher);
|
||||||
} globalSortOrder:0 debugLabel: nil threadSafe: false];
|
} globalSortOrder:0 debugLabel: nil threadSafe: false];
|
||||||
}
|
}
|
||||||
|
|
||||||
[_drawNode clear];
|
[_drawNode clear];
|
||||||
if (_debugSlots) {
|
if (_debugSlots) {
|
||||||
// Slots.
|
// Slots.
|
||||||
@ -430,7 +430,7 @@ static bool handlerQueued = false;
|
|||||||
float y = bone->data->length * bone->c + bone->worldY;
|
float y = bone->data->length * bone->c + bone->worldY;
|
||||||
[_drawNode drawSegmentFrom:ccp(bone->worldX, bone->worldY) to: ccp(x, y)radius:2 color:[CCColor redColor]];
|
[_drawNode drawSegmentFrom:ccp(bone->worldX, bone->worldY) to: ccp(x, y)radius:2 color:[CCColor redColor]];
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bone origins.
|
// Bone origins.
|
||||||
for (int i = 0, n = _skeleton->bonesCount; i < n; i++) {
|
for (int i = 0, n = _skeleton->bonesCount; i < n; i++) {
|
||||||
spBone *bone = _skeleton->bones[i];
|
spBone *bone = _skeleton->bones[i];
|
||||||
@ -439,7 +439,7 @@ static bool handlerQueued = false;
|
|||||||
if (i == 0) [_drawNode drawDot:ccp(bone->worldX, bone->worldY) radius:4 color:[CCColor blueColor]];
|
if (i == 0) [_drawNode drawDot:ccp(bone->worldX, bone->worldY) radius:4 color:[CCColor blueColor]];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_effect) _effect->end(_effect);
|
if (_effect) _effect->end(_effect);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -40,25 +40,26 @@ using std::vector;
|
|||||||
namespace spine {
|
namespace spine {
|
||||||
|
|
||||||
typedef struct _TrackEntryListeners {
|
typedef struct _TrackEntryListeners {
|
||||||
StartListener startListener;
|
StartListener startListener;
|
||||||
InterruptListener interruptListener;
|
InterruptListener interruptListener;
|
||||||
EndListener endListener;
|
EndListener endListener;
|
||||||
DisposeListener disposeListener;
|
DisposeListener disposeListener;
|
||||||
CompleteListener completeListener;
|
CompleteListener completeListener;
|
||||||
EventListener eventListener;
|
EventListener eventListener;
|
||||||
} _TrackEntryListeners;
|
} _TrackEntryListeners;
|
||||||
|
|
||||||
void animationCallback (AnimationState* state, EventType type, TrackEntry* entry, Event* event) {
|
void animationCallback (AnimationState* state, EventType type, TrackEntry* entry, Event* event) {
|
||||||
((SkeletonAnimation*)state->getRendererObject())->onAnimationStateEvent(entry, type, event);
|
((SkeletonAnimation*)state->getRendererObject())->onAnimationStateEvent(entry, type, event);
|
||||||
}
|
}
|
||||||
|
|
||||||
void trackEntryCallback (AnimationState* state, EventType type, TrackEntry* entry, Event* event) {
|
void trackEntryCallback (AnimationState* state, EventType type, TrackEntry* entry, Event* event) {
|
||||||
((SkeletonAnimation*)state->getRendererObject())->onTrackEntryEvent(entry, type, event);
|
((SkeletonAnimation*)state->getRendererObject())->onTrackEntryEvent(entry, type, event);
|
||||||
if (type == EventType_Dispose)
|
if (type == EventType_Dispose) {
|
||||||
if (entry->getRendererObject()) {
|
if (entry->getRendererObject()) {
|
||||||
delete (spine::_TrackEntryListeners*)entry->getRendererObject();
|
delete (spine::_TrackEntryListeners*)entry->getRendererObject();
|
||||||
entry->setRendererObject(NULL);
|
entry->setRendererObject(NULL);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static _TrackEntryListeners* getListeners (TrackEntry* entry) {
|
static _TrackEntryListeners* getListeners (TrackEntry* entry) {
|
||||||
@ -68,7 +69,7 @@ static _TrackEntryListeners* getListeners (TrackEntry* entry) {
|
|||||||
}
|
}
|
||||||
return (_TrackEntryListeners*)entry->getRendererObject();
|
return (_TrackEntryListeners*)entry->getRendererObject();
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
SkeletonAnimation* SkeletonAnimation::createWithData (SkeletonData* skeletonData, bool ownsSkeletonData) {
|
SkeletonAnimation* SkeletonAnimation::createWithData (SkeletonData* skeletonData, bool ownsSkeletonData) {
|
||||||
@ -150,7 +151,7 @@ void SkeletonAnimation::draw(cocos2d::Renderer *renderer, const cocos2d::Mat4 &t
|
|||||||
void SkeletonAnimation::setAnimationStateData (AnimationStateData* stateData) {
|
void SkeletonAnimation::setAnimationStateData (AnimationStateData* stateData) {
|
||||||
CCASSERT(stateData, "stateData cannot be null.");
|
CCASSERT(stateData, "stateData cannot be null.");
|
||||||
|
|
||||||
if (_ownsAnimationStateData) delete _state->getData();
|
if (_ownsAnimationStateData) delete _state->getData();
|
||||||
delete _state;
|
delete _state;
|
||||||
|
|
||||||
_ownsAnimationStateData = false;
|
_ownsAnimationStateData = false;
|
||||||
@ -180,7 +181,7 @@ TrackEntry* SkeletonAnimation::addAnimation (int trackIndex, const std::string&
|
|||||||
}
|
}
|
||||||
return _state->addAnimation(trackIndex, animation, loop, delay);
|
return _state->addAnimation(trackIndex, animation, loop, delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
TrackEntry* SkeletonAnimation::setEmptyAnimation (int trackIndex, float mixDuration) {
|
TrackEntry* SkeletonAnimation::setEmptyAnimation (int trackIndex, float mixDuration) {
|
||||||
return _state->setEmptyAnimation(trackIndex, mixDuration);
|
return _state->setEmptyAnimation(trackIndex, mixDuration);
|
||||||
}
|
}
|
||||||
@ -214,15 +215,15 @@ void SkeletonAnimation::onAnimationStateEvent (TrackEntry* entry, EventType type
|
|||||||
case EventType_Start:
|
case EventType_Start:
|
||||||
if (_startListener) _startListener(entry);
|
if (_startListener) _startListener(entry);
|
||||||
break;
|
break;
|
||||||
case EventType_Interrupt:
|
case EventType_Interrupt:
|
||||||
if (_interruptListener) _interruptListener(entry);
|
if (_interruptListener) _interruptListener(entry);
|
||||||
break;
|
break;
|
||||||
case EventType_End:
|
case EventType_End:
|
||||||
if (_endListener) _endListener(entry);
|
if (_endListener) _endListener(entry);
|
||||||
break;
|
break;
|
||||||
case EventType_Dispose:
|
case EventType_Dispose:
|
||||||
if (_disposeListener) _disposeListener(entry);
|
if (_disposeListener) _disposeListener(entry);
|
||||||
break;
|
break;
|
||||||
case EventType_Complete:
|
case EventType_Complete:
|
||||||
if (_completeListener) _completeListener(entry);
|
if (_completeListener) _completeListener(entry);
|
||||||
break;
|
break;
|
||||||
@ -239,15 +240,15 @@ void SkeletonAnimation::onTrackEntryEvent (TrackEntry* entry, EventType type, Ev
|
|||||||
case EventType_Start:
|
case EventType_Start:
|
||||||
if (listeners->startListener) listeners->startListener(entry);
|
if (listeners->startListener) listeners->startListener(entry);
|
||||||
break;
|
break;
|
||||||
case EventType_Interrupt:
|
case EventType_Interrupt:
|
||||||
if (listeners->interruptListener) listeners->interruptListener(entry);
|
if (listeners->interruptListener) listeners->interruptListener(entry);
|
||||||
break;
|
break;
|
||||||
case EventType_End:
|
case EventType_End:
|
||||||
if (listeners->endListener) listeners->endListener(entry);
|
if (listeners->endListener) listeners->endListener(entry);
|
||||||
break;
|
break;
|
||||||
case EventType_Dispose:
|
case EventType_Dispose:
|
||||||
if (listeners->disposeListener) listeners->disposeListener(entry);
|
if (listeners->disposeListener) listeners->disposeListener(entry);
|
||||||
break;
|
break;
|
||||||
case EventType_Complete:
|
case EventType_Complete:
|
||||||
if (listeners->completeListener) listeners->completeListener(entry);
|
if (listeners->completeListener) listeners->completeListener(entry);
|
||||||
break;
|
break;
|
||||||
@ -260,17 +261,17 @@ void SkeletonAnimation::onTrackEntryEvent (TrackEntry* entry, EventType type, Ev
|
|||||||
void SkeletonAnimation::setStartListener (const StartListener& listener) {
|
void SkeletonAnimation::setStartListener (const StartListener& listener) {
|
||||||
_startListener = listener;
|
_startListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonAnimation::setInterruptListener (const InterruptListener& listener) {
|
void SkeletonAnimation::setInterruptListener (const InterruptListener& listener) {
|
||||||
_interruptListener = listener;
|
_interruptListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonAnimation::setEndListener (const EndListener& listener) {
|
void SkeletonAnimation::setEndListener (const EndListener& listener) {
|
||||||
_endListener = listener;
|
_endListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonAnimation::setDisposeListener (const DisposeListener& listener) {
|
void SkeletonAnimation::setDisposeListener (const DisposeListener& listener) {
|
||||||
_disposeListener = listener;
|
_disposeListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonAnimation::setCompleteListener (const CompleteListener& listener) {
|
void SkeletonAnimation::setCompleteListener (const CompleteListener& listener) {
|
||||||
@ -284,17 +285,17 @@ void SkeletonAnimation::setEventListener (const EventListener& listener) {
|
|||||||
void SkeletonAnimation::setTrackStartListener (TrackEntry* entry, const StartListener& listener) {
|
void SkeletonAnimation::setTrackStartListener (TrackEntry* entry, const StartListener& listener) {
|
||||||
getListeners(entry)->startListener = listener;
|
getListeners(entry)->startListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonAnimation::setTrackInterruptListener (TrackEntry* entry, const InterruptListener& listener) {
|
void SkeletonAnimation::setTrackInterruptListener (TrackEntry* entry, const InterruptListener& listener) {
|
||||||
getListeners(entry)->interruptListener = listener;
|
getListeners(entry)->interruptListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonAnimation::setTrackEndListener (TrackEntry* entry, const EndListener& listener) {
|
void SkeletonAnimation::setTrackEndListener (TrackEntry* entry, const EndListener& listener) {
|
||||||
getListeners(entry)->endListener = listener;
|
getListeners(entry)->endListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonAnimation::setTrackDisposeListener (TrackEntry* entry, const DisposeListener& listener) {
|
void SkeletonAnimation::setTrackDisposeListener (TrackEntry* entry, const DisposeListener& listener) {
|
||||||
getListeners(entry)->disposeListener = listener;
|
getListeners(entry)->disposeListener = listener;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonAnimation::setTrackCompleteListener (TrackEntry* entry, const CompleteListener& listener) {
|
void SkeletonAnimation::setTrackCompleteListener (TrackEntry* entry, const CompleteListener& listener) {
|
||||||
|
|||||||
@ -82,16 +82,16 @@ public:
|
|||||||
void clearTrack (int trackIndex = 0);
|
void clearTrack (int trackIndex = 0);
|
||||||
|
|
||||||
void setStartListener (const StartListener& listener);
|
void setStartListener (const StartListener& listener);
|
||||||
void setInterruptListener (const InterruptListener& listener);
|
void setInterruptListener (const InterruptListener& listener);
|
||||||
void setEndListener (const EndListener& listener);
|
void setEndListener (const EndListener& listener);
|
||||||
void setDisposeListener (const DisposeListener& listener);
|
void setDisposeListener (const DisposeListener& listener);
|
||||||
void setCompleteListener (const CompleteListener& listener);
|
void setCompleteListener (const CompleteListener& listener);
|
||||||
void setEventListener (const EventListener& listener);
|
void setEventListener (const EventListener& listener);
|
||||||
|
|
||||||
void setTrackStartListener (TrackEntry* entry, const StartListener& listener);
|
void setTrackStartListener (TrackEntry* entry, const StartListener& listener);
|
||||||
void setTrackInterruptListener (TrackEntry* entry, const InterruptListener& listener);
|
void setTrackInterruptListener (TrackEntry* entry, const InterruptListener& listener);
|
||||||
void setTrackEndListener (TrackEntry* entry, const EndListener& listener);
|
void setTrackEndListener (TrackEntry* entry, const EndListener& listener);
|
||||||
void setTrackDisposeListener (TrackEntry* entry, const DisposeListener& listener);
|
void setTrackDisposeListener (TrackEntry* entry, const DisposeListener& listener);
|
||||||
void setTrackCompleteListener (TrackEntry* entry, const CompleteListener& listener);
|
void setTrackCompleteListener (TrackEntry* entry, const CompleteListener& listener);
|
||||||
void setTrackEventListener (TrackEntry* entry, const EventListener& listener);
|
void setTrackEventListener (TrackEntry* entry, const EventListener& listener);
|
||||||
|
|
||||||
@ -114,9 +114,9 @@ protected:
|
|||||||
bool _firstDraw;
|
bool _firstDraw;
|
||||||
|
|
||||||
StartListener _startListener;
|
StartListener _startListener;
|
||||||
InterruptListener _interruptListener;
|
InterruptListener _interruptListener;
|
||||||
EndListener _endListener;
|
EndListener _endListener;
|
||||||
DisposeListener _disposeListener;
|
DisposeListener _disposeListener;
|
||||||
CompleteListener _completeListener;
|
CompleteListener _completeListener;
|
||||||
EventListener _eventListener;
|
EventListener _eventListener;
|
||||||
|
|
||||||
|
|||||||
@ -56,9 +56,9 @@ SkeletonBatch::SkeletonBatch () {
|
|||||||
for (unsigned int i = 0; i < INITIAL_SIZE; i++) {
|
for (unsigned int i = 0; i < INITIAL_SIZE; i++) {
|
||||||
_commandsPool.push_back(new TrianglesCommand());
|
_commandsPool.push_back(new TrianglesCommand());
|
||||||
}
|
}
|
||||||
|
|
||||||
reset ();
|
reset ();
|
||||||
|
|
||||||
// callback after drawing is finished so we can clear out the batch state
|
// callback after drawing is finished so we can clear out the batch state
|
||||||
// for the next frame
|
// for the next frame
|
||||||
Director::getInstance()->getEventDispatcher()->addCustomEventListener(EVENT_AFTER_DRAW_RESET_POSITION, [this](EventCustom* eventCustom){
|
Director::getInstance()->getEventDispatcher()->addCustomEventListener(EVENT_AFTER_DRAW_RESET_POSITION, [this](EventCustom* eventCustom){
|
||||||
@ -68,7 +68,7 @@ SkeletonBatch::SkeletonBatch () {
|
|||||||
|
|
||||||
SkeletonBatch::~SkeletonBatch () {
|
SkeletonBatch::~SkeletonBatch () {
|
||||||
Director::getInstance()->getEventDispatcher()->removeCustomEventListeners(EVENT_AFTER_DRAW_RESET_POSITION);
|
Director::getInstance()->getEventDispatcher()->removeCustomEventListeners(EVENT_AFTER_DRAW_RESET_POSITION);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < _commandsPool.size(); i++) {
|
for (unsigned int i = 0; i < _commandsPool.size(); i++) {
|
||||||
delete _commandsPool[i];
|
delete _commandsPool[i];
|
||||||
_commandsPool[i] = nullptr;
|
_commandsPool[i] = nullptr;
|
||||||
@ -78,7 +78,7 @@ SkeletonBatch::~SkeletonBatch () {
|
|||||||
void SkeletonBatch::update (float delta) {
|
void SkeletonBatch::update (float delta) {
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
cocos2d::V3F_C4B_T2F* SkeletonBatch::allocateVertices(uint32_t numVertices) {
|
cocos2d::V3F_C4B_T2F* SkeletonBatch::allocateVertices(uint32_t numVertices) {
|
||||||
if (_vertices.size() - _numVertices < numVertices) {
|
if (_vertices.size() - _numVertices < numVertices) {
|
||||||
cocos2d::V3F_C4B_T2F* oldData = _vertices.data();
|
cocos2d::V3F_C4B_T2F* oldData = _vertices.data();
|
||||||
@ -90,18 +90,18 @@ cocos2d::V3F_C4B_T2F* SkeletonBatch::allocateVertices(uint32_t numVertices) {
|
|||||||
triangles.verts = newData + (triangles.verts - oldData);
|
triangles.verts = newData + (triangles.verts - oldData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cocos2d::V3F_C4B_T2F* vertices = _vertices.data() + _numVertices;
|
cocos2d::V3F_C4B_T2F* vertices = _vertices.data() + _numVertices;
|
||||||
_numVertices += numVertices;
|
_numVertices += numVertices;
|
||||||
return vertices;
|
return vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonBatch::deallocateVertices(uint32_t numVertices) {
|
void SkeletonBatch::deallocateVertices(uint32_t numVertices) {
|
||||||
_numVertices -= numVertices;
|
_numVertices -= numVertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
unsigned short* SkeletonBatch::allocateIndices(uint32_t numIndices) {
|
unsigned short* SkeletonBatch::allocateIndices(uint32_t numIndices) {
|
||||||
if (_indices.getCapacity() - _indices.size() < numIndices) {
|
if (_indices.getCapacity() - _indices.size() < numIndices) {
|
||||||
unsigned short* oldData = _indices.buffer();
|
unsigned short* oldData = _indices.buffer();
|
||||||
int oldSize = _indices.size();
|
int oldSize = _indices.size();
|
||||||
@ -115,7 +115,7 @@ unsigned short* SkeletonBatch::allocateIndices(uint32_t numIndices) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned short* indices = _indices.buffer() + _indices.size();
|
unsigned short* indices = _indices.buffer() + _indices.size();
|
||||||
_indices.setSize(_indices.size() + numIndices, 0);
|
_indices.setSize(_indices.size() + numIndices, 0);
|
||||||
return indices;
|
return indices;
|
||||||
@ -125,7 +125,7 @@ void SkeletonBatch::deallocateIndices(uint32_t numIndices) {
|
|||||||
_indices.setSize(_indices.size() - numIndices, 0);
|
_indices.setSize(_indices.size() - numIndices, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
cocos2d::TrianglesCommand* SkeletonBatch::addCommand(cocos2d::Renderer* renderer, float globalOrder, cocos2d::Texture2D* texture, cocos2d::GLProgramState* glProgramState, cocos2d::BlendFunc blendType, const cocos2d::TrianglesCommand::Triangles& triangles, const cocos2d::Mat4& mv, uint32_t flags) {
|
cocos2d::TrianglesCommand* SkeletonBatch::addCommand(cocos2d::Renderer* renderer, float globalOrder, cocos2d::Texture2D* texture, cocos2d::GLProgramState* glProgramState, cocos2d::BlendFunc blendType, const cocos2d::TrianglesCommand::Triangles& triangles, const cocos2d::Mat4& mv, uint32_t flags) {
|
||||||
TrianglesCommand* command = nextFreeCommand();
|
TrianglesCommand* command = nextFreeCommand();
|
||||||
command->init(globalOrder, texture, glProgramState, blendType, triangles, mv, flags);
|
command->init(globalOrder, texture, glProgramState, blendType, triangles, mv, flags);
|
||||||
@ -142,7 +142,7 @@ void SkeletonBatch::reset() {
|
|||||||
cocos2d::TrianglesCommand* SkeletonBatch::nextFreeCommand() {
|
cocos2d::TrianglesCommand* SkeletonBatch::nextFreeCommand() {
|
||||||
if (_commandsPool.size() <= _nextFreeCommand) {
|
if (_commandsPool.size() <= _nextFreeCommand) {
|
||||||
unsigned int newSize = _commandsPool.size() * 2 + 1;
|
unsigned int newSize = _commandsPool.size() * 2 + 1;
|
||||||
for (int i = _commandsPool.size(); i < newSize; i++) {
|
for (int i = _commandsPool.size(); i < newSize; i++) {
|
||||||
_commandsPool.push_back(new TrianglesCommand());
|
_commandsPool.push_back(new TrianglesCommand());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -35,41 +35,41 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
|
|
||||||
class SkeletonBatch {
|
class SkeletonBatch {
|
||||||
public:
|
public:
|
||||||
static SkeletonBatch* getInstance ();
|
static SkeletonBatch* getInstance ();
|
||||||
|
|
||||||
static void destroyInstance ();
|
static void destroyInstance ();
|
||||||
|
|
||||||
void update (float delta);
|
void update (float delta);
|
||||||
|
|
||||||
cocos2d::V3F_C4B_T2F* allocateVertices(uint32_t numVertices);
|
cocos2d::V3F_C4B_T2F* allocateVertices(uint32_t numVertices);
|
||||||
void deallocateVertices(uint32_t numVertices);
|
void deallocateVertices(uint32_t numVertices);
|
||||||
unsigned short* allocateIndices(uint32_t numIndices);
|
unsigned short* allocateIndices(uint32_t numIndices);
|
||||||
void deallocateIndices(uint32_t numVertices);
|
void deallocateIndices(uint32_t numVertices);
|
||||||
cocos2d::TrianglesCommand* addCommand(cocos2d::Renderer* renderer, float globalOrder, cocos2d::Texture2D* texture, cocos2d::GLProgramState* glProgramState, cocos2d::BlendFunc blendType, const cocos2d::TrianglesCommand::Triangles& triangles, const cocos2d::Mat4& mv, uint32_t flags);
|
cocos2d::TrianglesCommand* addCommand(cocos2d::Renderer* renderer, float globalOrder, cocos2d::Texture2D* texture, cocos2d::GLProgramState* glProgramState, cocos2d::BlendFunc blendType, const cocos2d::TrianglesCommand::Triangles& triangles, const cocos2d::Mat4& mv, uint32_t flags);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SkeletonBatch ();
|
SkeletonBatch ();
|
||||||
virtual ~SkeletonBatch ();
|
virtual ~SkeletonBatch ();
|
||||||
|
|
||||||
void reset ();
|
void reset ();
|
||||||
|
|
||||||
cocos2d::TrianglesCommand* nextFreeCommand ();
|
cocos2d::TrianglesCommand* nextFreeCommand ();
|
||||||
|
|
||||||
// pool of commands
|
// pool of commands
|
||||||
std::vector<cocos2d::TrianglesCommand*> _commandsPool;
|
std::vector<cocos2d::TrianglesCommand*> _commandsPool;
|
||||||
uint32_t _nextFreeCommand;
|
uint32_t _nextFreeCommand;
|
||||||
|
|
||||||
// pool of vertices
|
// pool of vertices
|
||||||
std::vector<cocos2d::V3F_C4B_T2F> _vertices;
|
std::vector<cocos2d::V3F_C4B_T2F> _vertices;
|
||||||
uint32_t _numVertices;
|
uint32_t _numVertices;
|
||||||
|
|
||||||
// pool of indices
|
// pool of indices
|
||||||
Vector<unsigned short> _indices;
|
Vector<unsigned short> _indices;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // SPINE_SKELETONBATCH_H_
|
#endif // SPINE_SKELETONBATCH_H_
|
||||||
|
|||||||
@ -52,7 +52,7 @@ namespace spine {
|
|||||||
Color4B ColorToColor4B(const Color& color);
|
Color4B ColorToColor4B(const Color& color);
|
||||||
bool slotIsOutRange(Slot& slot, int startSlotIndex, int endSlotIndex);
|
bool slotIsOutRange(Slot& slot, int startSlotIndex, int endSlotIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
// C Variable length array
|
// C Variable length array
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
// VLA not supported, use _malloca
|
// VLA not supported, use _malloca
|
||||||
@ -71,7 +71,7 @@ namespace spine {
|
|||||||
node->autorelease();
|
node->autorelease();
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
SkeletonRenderer* SkeletonRenderer::createWithData (SkeletonData* skeletonData, bool ownsSkeletonData) {
|
SkeletonRenderer* SkeletonRenderer::createWithData (SkeletonData* skeletonData, bool ownsSkeletonData) {
|
||||||
SkeletonRenderer* node = new SkeletonRenderer(skeletonData, ownsSkeletonData);
|
SkeletonRenderer* node = new SkeletonRenderer(skeletonData, ownsSkeletonData);
|
||||||
node->autorelease();
|
node->autorelease();
|
||||||
@ -101,13 +101,13 @@ namespace spine {
|
|||||||
_skeleton->setToSetupPose();
|
_skeleton->setToSetupPose();
|
||||||
_skeleton->updateWorldTransform();
|
_skeleton->updateWorldTransform();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonRenderer::setupGLProgramState (bool twoColorTintEnabled) {
|
void SkeletonRenderer::setupGLProgramState (bool twoColorTintEnabled) {
|
||||||
if (twoColorTintEnabled) {
|
if (twoColorTintEnabled) {
|
||||||
setGLProgramState(SkeletonTwoColorBatch::getInstance()->getTwoColorTintProgramState());
|
setGLProgramState(SkeletonTwoColorBatch::getInstance()->getTwoColorTintProgramState());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture2D *texture = nullptr;
|
Texture2D *texture = nullptr;
|
||||||
for (int i = 0, n = _skeleton->getSlots().size(); i < n; i++) {
|
for (int i = 0, n = _skeleton->getSlots().size(); i < n; i++) {
|
||||||
Slot* slot = _skeleton->getDrawOrder()[i];
|
Slot* slot = _skeleton->getDrawOrder()[i];
|
||||||
@ -123,7 +123,7 @@ namespace spine {
|
|||||||
else {
|
else {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (texture != nullptr) {
|
if (texture != nullptr) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -139,7 +139,7 @@ namespace spine {
|
|||||||
SkeletonRenderer::SkeletonRenderer ()
|
SkeletonRenderer::SkeletonRenderer ()
|
||||||
: _atlas(nullptr), _attachmentLoader(nullptr), _debugSlots(false), _debugBones(false), _debugMeshes(false), _debugBoundingRect(false), _timeScale(1), _effect(nullptr), _startSlotIndex(0), _endSlotIndex(std::numeric_limits<int>::max()) {
|
: _atlas(nullptr), _attachmentLoader(nullptr), _debugSlots(false), _debugBones(false), _debugMeshes(false), _debugBoundingRect(false), _timeScale(1), _effect(nullptr), _startSlotIndex(0), _endSlotIndex(std::numeric_limits<int>::max()) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SkeletonRenderer::SkeletonRenderer(Skeleton* skeleton, bool ownsSkeleton, bool ownsSkeletonData, bool ownsAtlas)
|
SkeletonRenderer::SkeletonRenderer(Skeleton* skeleton, bool ownsSkeleton, bool ownsSkeletonData, bool ownsAtlas)
|
||||||
: _atlas(nullptr), _attachmentLoader(nullptr), _debugSlots(false), _debugBones(false), _debugMeshes(false), _debugBoundingRect(false), _timeScale(1), _effect(nullptr), _startSlotIndex(0), _endSlotIndex(std::numeric_limits<int>::max()) {
|
: _atlas(nullptr), _attachmentLoader(nullptr), _debugSlots(false), _debugBones(false), _debugMeshes(false), _debugBoundingRect(false), _timeScale(1), _effect(nullptr), _startSlotIndex(0), _endSlotIndex(std::numeric_limits<int>::max()) {
|
||||||
initWithSkeleton(skeleton, ownsSkeleton, ownsSkeletonData, ownsAtlas);
|
initWithSkeleton(skeleton, ownsSkeleton, ownsSkeletonData, ownsAtlas);
|
||||||
@ -164,7 +164,7 @@ namespace spine {
|
|||||||
if (_ownsSkeletonData) delete _skeleton->getData();
|
if (_ownsSkeletonData) delete _skeleton->getData();
|
||||||
if (_ownsSkeleton) delete _skeleton;
|
if (_ownsSkeleton) delete _skeleton;
|
||||||
if (_ownsAtlas) delete _atlas;
|
if (_ownsAtlas) delete _atlas;
|
||||||
delete _attachmentLoader;
|
delete _attachmentLoader;
|
||||||
delete _clipper;
|
delete _clipper;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -175,7 +175,7 @@ namespace spine {
|
|||||||
_ownsAtlas = ownsAtlas;
|
_ownsAtlas = ownsAtlas;
|
||||||
initialize();
|
initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonRenderer::initWithData (SkeletonData* skeletonData, bool ownsSkeletonData) {
|
void SkeletonRenderer::initWithData (SkeletonData* skeletonData, bool ownsSkeletonData) {
|
||||||
_ownsSkeleton = true;
|
_ownsSkeleton = true;
|
||||||
setSkeletonData(skeletonData, ownsSkeletonData);
|
setSkeletonData(skeletonData, ownsSkeletonData);
|
||||||
@ -207,34 +207,34 @@ namespace spine {
|
|||||||
json.setScale(scale);
|
json.setScale(scale);
|
||||||
SkeletonData* skeletonData = json.readSkeletonDataFile(skeletonDataFile.c_str());
|
SkeletonData* skeletonData = json.readSkeletonDataFile(skeletonDataFile.c_str());
|
||||||
CCASSERT(skeletonData, !json.getError().isEmpty() ? json.getError().buffer() : "Error reading skeleton data.");
|
CCASSERT(skeletonData, !json.getError().isEmpty() ? json.getError().buffer() : "Error reading skeleton data.");
|
||||||
|
|
||||||
_ownsSkeleton = true;
|
_ownsSkeleton = true;
|
||||||
_ownsAtlas = true;
|
_ownsAtlas = true;
|
||||||
setSkeletonData(skeletonData, true);
|
setSkeletonData(skeletonData, true);
|
||||||
|
|
||||||
initialize();
|
initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonRenderer::initWithBinaryFile (const std::string& skeletonDataFile, Atlas* atlas, float scale) {
|
void SkeletonRenderer::initWithBinaryFile (const std::string& skeletonDataFile, Atlas* atlas, float scale) {
|
||||||
_atlas = atlas;
|
_atlas = atlas;
|
||||||
_attachmentLoader = new (__FILE__, __LINE__) Cocos2dAtlasAttachmentLoader(_atlas);
|
_attachmentLoader = new (__FILE__, __LINE__) Cocos2dAtlasAttachmentLoader(_atlas);
|
||||||
|
|
||||||
SkeletonBinary binary(_attachmentLoader);
|
SkeletonBinary binary(_attachmentLoader);
|
||||||
binary.setScale(scale);
|
binary.setScale(scale);
|
||||||
SkeletonData* skeletonData = binary.readSkeletonDataFile(skeletonDataFile.c_str());
|
SkeletonData* skeletonData = binary.readSkeletonDataFile(skeletonDataFile.c_str());
|
||||||
CCASSERT(skeletonData, !binary.getError().isEmpty() ? binary.getError().buffer() : "Error reading skeleton data.");
|
CCASSERT(skeletonData, !binary.getError().isEmpty() ? binary.getError().buffer() : "Error reading skeleton data.");
|
||||||
_ownsSkeleton = true;
|
_ownsSkeleton = true;
|
||||||
setSkeletonData(skeletonData, true);
|
setSkeletonData(skeletonData, true);
|
||||||
|
|
||||||
initialize();
|
initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonRenderer::initWithBinaryFile (const std::string& skeletonDataFile, const std::string& atlasFile, float scale) {
|
void SkeletonRenderer::initWithBinaryFile (const std::string& skeletonDataFile, const std::string& atlasFile, float scale) {
|
||||||
_atlas = new (__FILE__, __LINE__) Atlas(atlasFile.c_str(), &textureLoader, true);
|
_atlas = new (__FILE__, __LINE__) Atlas(atlasFile.c_str(), &textureLoader, true);
|
||||||
CCASSERT(_atlas, "Error reading atlas file.");
|
CCASSERT(_atlas, "Error reading atlas file.");
|
||||||
|
|
||||||
_attachmentLoader = new (__FILE__, __LINE__) Cocos2dAtlasAttachmentLoader(_atlas);
|
_attachmentLoader = new (__FILE__, __LINE__) Cocos2dAtlasAttachmentLoader(_atlas);
|
||||||
|
|
||||||
SkeletonBinary binary(_attachmentLoader);
|
SkeletonBinary binary(_attachmentLoader);
|
||||||
binary.setScale(scale);
|
binary.setScale(scale);
|
||||||
SkeletonData* skeletonData = binary.readSkeletonDataFile(skeletonDataFile.c_str());
|
SkeletonData* skeletonData = binary.readSkeletonDataFile(skeletonDataFile.c_str());
|
||||||
@ -242,7 +242,7 @@ namespace spine {
|
|||||||
_ownsSkeleton = true;
|
_ownsSkeleton = true;
|
||||||
_ownsAtlas = true;
|
_ownsAtlas = true;
|
||||||
setSkeletonData(skeletonData, true);
|
setSkeletonData(skeletonData, true);
|
||||||
|
|
||||||
initialize();
|
initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -295,7 +295,7 @@ namespace spine {
|
|||||||
nodeColor.g = displayedColor.g / 255.f;
|
nodeColor.g = displayedColor.g / 255.f;
|
||||||
nodeColor.b = displayedColor.b / 255.f;
|
nodeColor.b = displayedColor.b / 255.f;
|
||||||
nodeColor.a = getDisplayedOpacity() / 255.f;
|
nodeColor.a = getDisplayedOpacity() / 255.f;
|
||||||
|
|
||||||
Color color;
|
Color color;
|
||||||
Color darkColor;
|
Color darkColor;
|
||||||
const float darkPremultipliedAlpha = _premultipliedAlpha ? 1.f : 0;
|
const float darkPremultipliedAlpha = _premultipliedAlpha ? 1.f : 0;
|
||||||
@ -303,7 +303,7 @@ namespace spine {
|
|||||||
TwoColorTrianglesCommand* lastTwoColorTrianglesCommand = nullptr;
|
TwoColorTrianglesCommand* lastTwoColorTrianglesCommand = nullptr;
|
||||||
for (int i = 0, n = _skeleton->getSlots().size(); i < n; ++i) {
|
for (int i = 0, n = _skeleton->getSlots().size(); i < n; ++i) {
|
||||||
Slot* slot = _skeleton->getDrawOrder()[i];;
|
Slot* slot = _skeleton->getDrawOrder()[i];;
|
||||||
|
|
||||||
if (slotIsOutRange(*slot, _startSlotIndex, _endSlotIndex)) {
|
if (slotIsOutRange(*slot, _startSlotIndex, _endSlotIndex)) {
|
||||||
_clipper->clipEnd(*slot);
|
_clipper->clipEnd(*slot);
|
||||||
continue;
|
continue;
|
||||||
@ -322,11 +322,11 @@ namespace spine {
|
|||||||
|
|
||||||
cocos2d::TrianglesCommand::Triangles triangles;
|
cocos2d::TrianglesCommand::Triangles triangles;
|
||||||
TwoColorTriangles trianglesTwoColor;
|
TwoColorTriangles trianglesTwoColor;
|
||||||
|
|
||||||
if (slot->getAttachment()->getRTTI().isExactly(RegionAttachment::rtti)) {
|
if (slot->getAttachment()->getRTTI().isExactly(RegionAttachment::rtti)) {
|
||||||
RegionAttachment* attachment = static_cast<RegionAttachment*>(slot->getAttachment());
|
RegionAttachment* attachment = static_cast<RegionAttachment*>(slot->getAttachment());
|
||||||
attachmentVertices = static_cast<AttachmentVertices*>(attachment->getRendererObject());
|
attachmentVertices = static_cast<AttachmentVertices*>(attachment->getRendererObject());
|
||||||
|
|
||||||
// Early exit if attachment is invisible
|
// Early exit if attachment is invisible
|
||||||
if (attachment->getColor().a == 0) {
|
if (attachment->getColor().a == 0) {
|
||||||
_clipper->clipEnd(*slot);
|
_clipper->clipEnd(*slot);
|
||||||
@ -359,13 +359,13 @@ namespace spine {
|
|||||||
// Copy world vertices to triangle vertices
|
// Copy world vertices to triangle vertices
|
||||||
interleaveCoordinates(dstTriangleVertices, worldCoordPtr, 4, dstStride);
|
interleaveCoordinates(dstTriangleVertices, worldCoordPtr, 4, dstStride);
|
||||||
worldCoordPtr += 8;
|
worldCoordPtr += 8;
|
||||||
|
|
||||||
color = attachment->getColor();
|
color = attachment->getColor();
|
||||||
}
|
}
|
||||||
else if (slot->getAttachment()->getRTTI().isExactly(MeshAttachment::rtti)) {
|
else if (slot->getAttachment()->getRTTI().isExactly(MeshAttachment::rtti)) {
|
||||||
MeshAttachment* attachment = (MeshAttachment*)slot->getAttachment();
|
MeshAttachment* attachment = (MeshAttachment*)slot->getAttachment();
|
||||||
attachmentVertices = (AttachmentVertices*)attachment->getRendererObject();
|
attachmentVertices = (AttachmentVertices*)attachment->getRendererObject();
|
||||||
|
|
||||||
float* dstTriangleVertices = nullptr;
|
float* dstTriangleVertices = nullptr;
|
||||||
int dstStride = 0; // in floats
|
int dstStride = 0; // in floats
|
||||||
int dstVertexCount = 0;
|
int dstVertexCount = 0;
|
||||||
@ -390,12 +390,12 @@ namespace spine {
|
|||||||
dstStride = sizeof(V3F_C4B_C4B_T2F) / sizeof(float);
|
dstStride = sizeof(V3F_C4B_C4B_T2F) / sizeof(float);
|
||||||
dstVertexCount = trianglesTwoColor.vertCount;
|
dstVertexCount = trianglesTwoColor.vertCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Copy world vertices to triangle vertices
|
// Copy world vertices to triangle vertices
|
||||||
//assert(dstVertexCount * 2 == attachment->super.worldVerticesLength);
|
//assert(dstVertexCount * 2 == attachment->super.worldVerticesLength);
|
||||||
interleaveCoordinates(dstTriangleVertices, worldCoordPtr, dstVertexCount, dstStride);
|
interleaveCoordinates(dstTriangleVertices, worldCoordPtr, dstVertexCount, dstStride);
|
||||||
worldCoordPtr += dstVertexCount * 2;
|
worldCoordPtr += dstVertexCount * 2;
|
||||||
|
|
||||||
color = attachment->getColor();
|
color = attachment->getColor();
|
||||||
}
|
}
|
||||||
else if (slot->getAttachment()->getRTTI().isExactly(ClippingAttachment::rtti)) {
|
else if (slot->getAttachment()->getRTTI().isExactly(ClippingAttachment::rtti)) {
|
||||||
@ -406,7 +406,7 @@ namespace spine {
|
|||||||
_clipper->clipEnd(*slot);
|
_clipper->clipEnd(*slot);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (slot->hasDarkColor()) {
|
if (slot->hasDarkColor()) {
|
||||||
darkColor = slot->getDarkColor();
|
darkColor = slot->getDarkColor();
|
||||||
} else {
|
} else {
|
||||||
@ -415,7 +415,7 @@ namespace spine {
|
|||||||
darkColor.b = 0;
|
darkColor.b = 0;
|
||||||
}
|
}
|
||||||
darkColor.a = darkPremultipliedAlpha;
|
darkColor.a = darkPremultipliedAlpha;
|
||||||
|
|
||||||
color.a *= nodeColor.a * _skeleton->getColor().a * slot->getColor().a;
|
color.a *= nodeColor.a * _skeleton->getColor().a * slot->getColor().a;
|
||||||
// skip rendering if the color of this attachment is 0
|
// skip rendering if the color of this attachment is 0
|
||||||
if (color.a == 0){
|
if (color.a == 0){
|
||||||
@ -431,7 +431,7 @@ namespace spine {
|
|||||||
color.g *= color.a;
|
color.g *= color.a;
|
||||||
color.b *= color.a;
|
color.b *= color.a;
|
||||||
}
|
}
|
||||||
|
|
||||||
const cocos2d::Color4B color4B = ColorToColor4B(color);
|
const cocos2d::Color4B color4B = ColorToColor4B(color);
|
||||||
const cocos2d::Color4B darkColor4B = ColorToColor4B(darkColor);
|
const cocos2d::Color4B darkColor4B = ColorToColor4B(darkColor);
|
||||||
const BlendFunc blendFunc = makeBlendFunc(slot->getData().getBlendMode(), _premultipliedAlpha);
|
const BlendFunc blendFunc = makeBlendFunc(slot->getData().getBlendMode(), _premultipliedAlpha);
|
||||||
@ -440,21 +440,21 @@ namespace spine {
|
|||||||
if (_clipper->isClipping()) {
|
if (_clipper->isClipping()) {
|
||||||
_clipper->clipTriangles((float*)&triangles.verts[0].vertices, triangles.indices, triangles.indexCount, (float*)&triangles.verts[0].texCoords, sizeof(cocos2d::V3F_C4B_T2F) / 4);
|
_clipper->clipTriangles((float*)&triangles.verts[0].vertices, triangles.indices, triangles.indexCount, (float*)&triangles.verts[0].texCoords, sizeof(cocos2d::V3F_C4B_T2F) / 4);
|
||||||
batch->deallocateVertices(triangles.vertCount);
|
batch->deallocateVertices(triangles.vertCount);
|
||||||
|
|
||||||
if (_clipper->getClippedTriangles().size() == 0){
|
if (_clipper->getClippedTriangles().size() == 0){
|
||||||
_clipper->clipEnd(*slot);
|
_clipper->clipEnd(*slot);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
triangles.vertCount = _clipper->getClippedVertices().size() / 2;
|
triangles.vertCount = _clipper->getClippedVertices().size() / 2;
|
||||||
triangles.verts = batch->allocateVertices(triangles.vertCount);
|
triangles.verts = batch->allocateVertices(triangles.vertCount);
|
||||||
triangles.indexCount = _clipper->getClippedTriangles().size();
|
triangles.indexCount = _clipper->getClippedTriangles().size();
|
||||||
triangles.indices =
|
triangles.indices =
|
||||||
batch->allocateIndices(triangles.indexCount);
|
batch->allocateIndices(triangles.indexCount);
|
||||||
memcpy(triangles.indices, _clipper->getClippedTriangles().buffer(), sizeof(unsigned short) * _clipper->getClippedTriangles().size());
|
memcpy(triangles.indices, _clipper->getClippedTriangles().buffer(), sizeof(unsigned short) * _clipper->getClippedTriangles().size());
|
||||||
|
|
||||||
cocos2d::TrianglesCommand* batchedTriangles = batch->addCommand(renderer, _globalZOrder, attachmentVertices->_texture, _glProgramState, blendFunc, triangles, transform, transformFlags);
|
cocos2d::TrianglesCommand* batchedTriangles = batch->addCommand(renderer, _globalZOrder, attachmentVertices->_texture, _glProgramState, blendFunc, triangles, transform, transformFlags);
|
||||||
|
|
||||||
const float* verts = _clipper->getClippedVertices().buffer();
|
const float* verts = _clipper->getClippedVertices().buffer();
|
||||||
const float* uvs = _clipper->getClippedUVs().buffer();
|
const float* uvs = _clipper->getClippedUVs().buffer();
|
||||||
if (_effect) {
|
if (_effect) {
|
||||||
@ -481,9 +481,9 @@ namespace spine {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Not clipping
|
// Not clipping
|
||||||
|
|
||||||
cocos2d::TrianglesCommand* batchedTriangles = batch->addCommand(renderer, _globalZOrder, attachmentVertices->_texture, _glProgramState, blendFunc, triangles, transform, transformFlags);
|
cocos2d::TrianglesCommand* batchedTriangles = batch->addCommand(renderer, _globalZOrder, attachmentVertices->_texture, _glProgramState, blendFunc, triangles, transform, transformFlags);
|
||||||
|
|
||||||
if (_effect) {
|
if (_effect) {
|
||||||
V3F_C4B_T2F* vertex = batchedTriangles->getTriangles().verts;
|
V3F_C4B_T2F* vertex = batchedTriangles->getTriangles().verts;
|
||||||
Color darkTmp;
|
Color darkTmp;
|
||||||
@ -501,27 +501,27 @@ namespace spine {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Two tints
|
// Two tints
|
||||||
|
|
||||||
if (_clipper->isClipping()) {
|
if (_clipper->isClipping()) {
|
||||||
_clipper->clipTriangles((float*)&trianglesTwoColor.verts[0].position, trianglesTwoColor.indices, trianglesTwoColor.indexCount, (float*)&trianglesTwoColor.verts[0].texCoords, sizeof(V3F_C4B_C4B_T2F) / 4);
|
_clipper->clipTriangles((float*)&trianglesTwoColor.verts[0].position, trianglesTwoColor.indices, trianglesTwoColor.indexCount, (float*)&trianglesTwoColor.verts[0].texCoords, sizeof(V3F_C4B_C4B_T2F) / 4);
|
||||||
twoColorBatch->deallocateVertices(trianglesTwoColor.vertCount);
|
twoColorBatch->deallocateVertices(trianglesTwoColor.vertCount);
|
||||||
|
|
||||||
if (_clipper->getClippedTriangles().size() == 0){
|
if (_clipper->getClippedTriangles().size() == 0){
|
||||||
_clipper->clipEnd(*slot);
|
_clipper->clipEnd(*slot);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
trianglesTwoColor.vertCount = _clipper->getClippedVertices().size() / 2;
|
trianglesTwoColor.vertCount = _clipper->getClippedVertices().size() / 2;
|
||||||
trianglesTwoColor.verts = twoColorBatch->allocateVertices(trianglesTwoColor.vertCount);
|
trianglesTwoColor.verts = twoColorBatch->allocateVertices(trianglesTwoColor.vertCount);
|
||||||
trianglesTwoColor.indexCount = _clipper->getClippedTriangles().size();
|
trianglesTwoColor.indexCount = _clipper->getClippedTriangles().size();
|
||||||
trianglesTwoColor.indices = twoColorBatch->allocateIndices(trianglesTwoColor.indexCount);
|
trianglesTwoColor.indices = twoColorBatch->allocateIndices(trianglesTwoColor.indexCount);
|
||||||
memcpy(trianglesTwoColor.indices, _clipper->getClippedTriangles().buffer(), sizeof(unsigned short) * _clipper->getClippedTriangles().size());
|
memcpy(trianglesTwoColor.indices, _clipper->getClippedTriangles().buffer(), sizeof(unsigned short) * _clipper->getClippedTriangles().size());
|
||||||
|
|
||||||
TwoColorTrianglesCommand* batchedTriangles = lastTwoColorTrianglesCommand = twoColorBatch->addCommand(renderer, _globalZOrder, attachmentVertices->_texture->getName(), _glProgramState, blendFunc, trianglesTwoColor, transform, transformFlags);
|
TwoColorTrianglesCommand* batchedTriangles = lastTwoColorTrianglesCommand = twoColorBatch->addCommand(renderer, _globalZOrder, attachmentVertices->_texture->getName(), _glProgramState, blendFunc, trianglesTwoColor, transform, transformFlags);
|
||||||
|
|
||||||
const float* verts = _clipper->getClippedVertices().buffer();
|
const float* verts = _clipper->getClippedVertices().buffer();
|
||||||
const float* uvs = _clipper->getClippedUVs().buffer();
|
const float* uvs = _clipper->getClippedUVs().buffer();
|
||||||
|
|
||||||
if (_effect) {
|
if (_effect) {
|
||||||
V3F_C4B_C4B_T2F* vertex = batchedTriangles->getTriangles().verts;
|
V3F_C4B_C4B_T2F* vertex = batchedTriangles->getTriangles().verts;
|
||||||
for (int v = 0, vn = batchedTriangles->getTriangles().vertCount, vv = 0; v < vn; ++v, vv += 2, ++vertex) {
|
for (int v = 0, vn = batchedTriangles->getTriangles().vertCount, vv = 0; v < vn; ++v, vv += 2, ++vertex) {
|
||||||
@ -548,7 +548,7 @@ namespace spine {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
TwoColorTrianglesCommand* batchedTriangles = lastTwoColorTrianglesCommand = twoColorBatch->addCommand(renderer, _globalZOrder, attachmentVertices->_texture->getName(), _glProgramState, blendFunc, trianglesTwoColor, transform, transformFlags);
|
TwoColorTrianglesCommand* batchedTriangles = lastTwoColorTrianglesCommand = twoColorBatch->addCommand(renderer, _globalZOrder, attachmentVertices->_texture->getName(), _glProgramState, blendFunc, trianglesTwoColor, transform, transformFlags);
|
||||||
|
|
||||||
if (_effect) {
|
if (_effect) {
|
||||||
V3F_C4B_C4B_T2F* vertex = batchedTriangles->getTriangles().verts;
|
V3F_C4B_C4B_T2F* vertex = batchedTriangles->getTriangles().verts;
|
||||||
for (int v = 0, vn = batchedTriangles->getTriangles().vertCount; v < vn; ++v, ++vertex) {
|
for (int v = 0, vn = batchedTriangles->getTriangles().vertCount; v < vn; ++v, ++vertex) {
|
||||||
@ -570,10 +570,10 @@ namespace spine {
|
|||||||
_clipper->clipEnd(*slot);
|
_clipper->clipEnd(*slot);
|
||||||
}
|
}
|
||||||
_clipper->clipEnd();
|
_clipper->clipEnd();
|
||||||
|
|
||||||
if (lastTwoColorTrianglesCommand) {
|
if (lastTwoColorTrianglesCommand) {
|
||||||
Node* parent = this->getParent();
|
Node* parent = this->getParent();
|
||||||
|
|
||||||
// We need to decide if we can postpone flushing the current
|
// We need to decide if we can postpone flushing the current
|
||||||
// batch. We can postpone if the next sibling node is a
|
// batch. We can postpone if the next sibling node is a
|
||||||
// two color tinted skeleton with the same global-z.
|
// two color tinted skeleton with the same global-z.
|
||||||
@ -607,7 +607,7 @@ namespace spine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_effect) _effect->end();
|
if (_effect) _effect->end();
|
||||||
|
|
||||||
if (_debugBoundingRect || _debugSlots || _debugBones || _debugMeshes) {
|
if (_debugBoundingRect || _debugSlots || _debugBones || _debugMeshes) {
|
||||||
@ -627,7 +627,7 @@ namespace spine {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
DrawNode* drawNode = DrawNode::create();
|
DrawNode* drawNode = DrawNode::create();
|
||||||
|
|
||||||
// Draw bounding rectangle
|
// Draw bounding rectangle
|
||||||
if (_debugBoundingRect) {
|
if (_debugBoundingRect) {
|
||||||
glLineWidth(2);
|
glLineWidth(2);
|
||||||
@ -649,7 +649,7 @@ namespace spine {
|
|||||||
V3F_C4B_T2F_Quad quad;
|
V3F_C4B_T2F_Quad quad;
|
||||||
for (int i = 0, n = _skeleton->getSlots().size(); i < n; i++) {
|
for (int i = 0, n = _skeleton->getSlots().size(); i < n; i++) {
|
||||||
Slot* slot = _skeleton->getDrawOrder()[i];
|
Slot* slot = _skeleton->getDrawOrder()[i];
|
||||||
|
|
||||||
if (!slot->getBone().isActive()) continue;
|
if (!slot->getBone().isActive()) continue;
|
||||||
if (!slot->getAttachment() || !slot->getAttachment()->getRTTI().isExactly(RegionAttachment::rtti)) continue;
|
if (!slot->getAttachment() || !slot->getAttachment()->getRTTI().isExactly(RegionAttachment::rtti)) continue;
|
||||||
|
|
||||||
@ -670,7 +670,7 @@ namespace spine {
|
|||||||
drawNode->drawPoly(points, 4, true, Color4F::BLUE);
|
drawNode->drawPoly(points, 4, true, Color4F::BLUE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_debugBones) {
|
if (_debugBones) {
|
||||||
// Bone lengths.
|
// Bone lengths.
|
||||||
glLineWidth(2);
|
glLineWidth(2);
|
||||||
@ -690,7 +690,7 @@ namespace spine {
|
|||||||
if (i == 0) color = Color4F::GREEN;
|
if (i == 0) color = Color4F::GREEN;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_debugMeshes) {
|
if (_debugMeshes) {
|
||||||
// Meshes.
|
// Meshes.
|
||||||
glLineWidth(1);
|
glLineWidth(1);
|
||||||
@ -717,7 +717,7 @@ namespace spine {
|
|||||||
VLA_FREE(worldCoord);
|
VLA_FREE(worldCoord);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
drawNode->draw(renderer, transform, transformFlags);
|
drawNode->draw(renderer, transform, transformFlags);
|
||||||
#if !defined(USE_MATRIX_STACK_PROJECTION_ONLY)
|
#if !defined(USE_MATRIX_STACK_PROJECTION_ONLY)
|
||||||
director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
|
director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
|
||||||
@ -768,7 +768,7 @@ namespace spine {
|
|||||||
bool SkeletonRenderer::setAttachment (const std::string& slotName, const char* attachmentName) {
|
bool SkeletonRenderer::setAttachment (const std::string& slotName, const char* attachmentName) {
|
||||||
return _skeleton->getAttachment(slotName.c_str(), attachmentName) ? true : false;
|
return _skeleton->getAttachment(slotName.c_str(), attachmentName) ? true : false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonRenderer::setTwoColorTint(bool enabled) {
|
void SkeletonRenderer::setTwoColorTint(bool enabled) {
|
||||||
setupGLProgramState(enabled);
|
setupGLProgramState(enabled);
|
||||||
}
|
}
|
||||||
@ -776,11 +776,11 @@ namespace spine {
|
|||||||
bool SkeletonRenderer::isTwoColorTint() {
|
bool SkeletonRenderer::isTwoColorTint() {
|
||||||
return getGLProgramState() == SkeletonTwoColorBatch::getInstance()->getTwoColorTintProgramState();
|
return getGLProgramState() == SkeletonTwoColorBatch::getInstance()->getTwoColorTintProgramState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonRenderer::setVertexEffect(VertexEffect *effect) {
|
void SkeletonRenderer::setVertexEffect(VertexEffect *effect) {
|
||||||
this->_effect = effect;
|
this->_effect = effect;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonRenderer::setSlotsRange(int startSlotIndex, int endSlotIndex) {
|
void SkeletonRenderer::setSlotsRange(int startSlotIndex, int endSlotIndex) {
|
||||||
_startSlotIndex = startSlotIndex == -1 ? 0 : startSlotIndex;
|
_startSlotIndex = startSlotIndex == -1 ? 0 : startSlotIndex;
|
||||||
_endSlotIndex = endSlotIndex == -1 ? std::numeric_limits<int>::max() : endSlotIndex;
|
_endSlotIndex = endSlotIndex == -1 ? std::numeric_limits<int>::max() : endSlotIndex;
|
||||||
@ -810,7 +810,7 @@ namespace spine {
|
|||||||
bool SkeletonRenderer::getDebugBonesEnabled () const {
|
bool SkeletonRenderer::getDebugBonesEnabled () const {
|
||||||
return _debugBones;
|
return _debugBones;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonRenderer::setDebugMeshesEnabled (bool enabled) {
|
void SkeletonRenderer::setDebugMeshesEnabled (bool enabled) {
|
||||||
_debugMeshes = enabled;
|
_debugMeshes = enabled;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -63,10 +63,10 @@ namespace spine {
|
|||||||
|
|
||||||
void setDebugBonesEnabled(bool enabled);
|
void setDebugBonesEnabled(bool enabled);
|
||||||
bool getDebugBonesEnabled() const;
|
bool getDebugBonesEnabled() const;
|
||||||
|
|
||||||
void setDebugMeshesEnabled(bool enabled);
|
void setDebugMeshesEnabled(bool enabled);
|
||||||
bool getDebugMeshesEnabled() const;
|
bool getDebugMeshesEnabled() const;
|
||||||
|
|
||||||
void setDebugBoundingRectEnabled(bool enabled);
|
void setDebugBoundingRectEnabled(bool enabled);
|
||||||
bool getDebugBoundingRectEnabled() const;
|
bool getDebugBoundingRectEnabled() const;
|
||||||
|
|
||||||
@ -81,14 +81,14 @@ namespace spine {
|
|||||||
Bone* findBone (const std::string& boneName) const;
|
Bone* findBone (const std::string& boneName) const;
|
||||||
/* Returns 0 if the slot was not found. */
|
/* Returns 0 if the slot was not found. */
|
||||||
Slot* findSlot (const std::string& slotName) const;
|
Slot* findSlot (const std::string& slotName) const;
|
||||||
|
|
||||||
/* Sets the skin used to look up attachments not found in the SkeletonData defaultSkin. Attachments from the new skin are
|
/* Sets the skin used to look up attachments not found in the SkeletonData defaultSkin. Attachments from the new skin are
|
||||||
* attached if the corresponding attachment from the old skin was attached.
|
* attached if the corresponding attachment from the old skin was attached.
|
||||||
* @param skin May be empty string ("") for no skin.*/
|
* @param skin May be empty string ("") for no skin.*/
|
||||||
void setSkin (const std::string& skinName);
|
void setSkin (const std::string& skinName);
|
||||||
/** @param skin May be 0 for no skin.*/
|
/** @param skin May be 0 for no skin.*/
|
||||||
void setSkin (const char* skinName);
|
void setSkin (const char* skinName);
|
||||||
|
|
||||||
/* Returns 0 if the slot or attachment was not found. */
|
/* Returns 0 if the slot or attachment was not found. */
|
||||||
Attachment* getAttachment (const std::string& slotName, const std::string& attachmentName) const;
|
Attachment* getAttachment (const std::string& slotName, const std::string& attachmentName) const;
|
||||||
/* Returns false if the slot or attachment was not found.
|
/* Returns false if the slot or attachment was not found.
|
||||||
@ -96,15 +96,15 @@ namespace spine {
|
|||||||
bool setAttachment (const std::string& slotName, const std::string& attachmentName);
|
bool setAttachment (const std::string& slotName, const std::string& attachmentName);
|
||||||
/* @param attachmentName May be 0 for no attachment. */
|
/* @param attachmentName May be 0 for no attachment. */
|
||||||
bool setAttachment (const std::string& slotName, const char* attachmentName);
|
bool setAttachment (const std::string& slotName, const char* attachmentName);
|
||||||
|
|
||||||
/* Enables/disables two color tinting for this instance. May break batching */
|
/* Enables/disables two color tinting for this instance. May break batching */
|
||||||
void setTwoColorTint(bool enabled);
|
void setTwoColorTint(bool enabled);
|
||||||
/* Whether two color tinting is enabled */
|
/* Whether two color tinting is enabled */
|
||||||
bool isTwoColorTint();
|
bool isTwoColorTint();
|
||||||
|
|
||||||
/* Sets the vertex effect to be used, set to 0 to disable vertex effects */
|
/* Sets the vertex effect to be used, set to 0 to disable vertex effects */
|
||||||
void setVertexEffect(VertexEffect* effect);
|
void setVertexEffect(VertexEffect* effect);
|
||||||
|
|
||||||
/* Sets the range of slots that should be rendered. Use -1, -1 to clear the range */
|
/* Sets the range of slots that should be rendered. Use -1, -1 to clear the range */
|
||||||
void setSlotsRange(int startSlotIndex, int endSlotIndex);
|
void setSlotsRange(int startSlotIndex, int endSlotIndex);
|
||||||
|
|
||||||
@ -113,7 +113,7 @@ namespace spine {
|
|||||||
const cocos2d::BlendFunc& getBlendFunc () const override;
|
const cocos2d::BlendFunc& getBlendFunc () const override;
|
||||||
void setOpacityModifyRGB (bool value) override;
|
void setOpacityModifyRGB (bool value) override;
|
||||||
bool isOpacityModifyRGB () const override;
|
bool isOpacityModifyRGB () const override;
|
||||||
|
|
||||||
CC_CONSTRUCTOR_ACCESS:
|
CC_CONSTRUCTOR_ACCESS:
|
||||||
SkeletonRenderer ();
|
SkeletonRenderer ();
|
||||||
SkeletonRenderer(Skeleton* skeleton, bool ownsSkeleton = false, bool ownsSkeletonData = false, bool ownsAtlas = false);
|
SkeletonRenderer(Skeleton* skeleton, bool ownsSkeleton = false, bool ownsSkeletonData = false, bool ownsAtlas = false);
|
||||||
@ -131,7 +131,7 @@ namespace spine {
|
|||||||
void initWithBinaryFile (const std::string& skeletonDataFile, const std::string& atlasFile, float scale = 1);
|
void initWithBinaryFile (const std::string& skeletonDataFile, const std::string& atlasFile, float scale = 1);
|
||||||
|
|
||||||
virtual void initialize ();
|
virtual void initialize ();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void setSkeletonData (SkeletonData* skeletonData, bool ownsSkeletonData);
|
void setSkeletonData (SkeletonData* skeletonData, bool ownsSkeletonData);
|
||||||
void setupGLProgramState(bool twoColorTintEnabled);
|
void setupGLProgramState(bool twoColorTintEnabled);
|
||||||
@ -154,7 +154,7 @@ namespace spine {
|
|||||||
SkeletonClipping* _clipper;
|
SkeletonClipping* _clipper;
|
||||||
VertexEffect* _effect;
|
VertexEffect* _effect;
|
||||||
cocos2d::Rect _boundingRect;
|
cocos2d::Rect _boundingRect;
|
||||||
|
|
||||||
int _startSlotIndex;
|
int _startSlotIndex;
|
||||||
int _endSlotIndex;
|
int _endSlotIndex;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -83,7 +83,7 @@ void TwoColorTrianglesCommand::generateMaterialID() {
|
|||||||
setSkipBatching(true);
|
setSkipBatching(true);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
int glProgram = (int)_glProgram->getProgram();
|
int glProgram = (int)_glProgram->getProgram();
|
||||||
_materialID = glProgram + (int)_textureID + (int)_blendType.src + (int)_blendType.dst;
|
_materialID = glProgram + (int)_textureID + (int)_blendType.src + (int)_blendType.dst;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -91,17 +91,17 @@ void TwoColorTrianglesCommand::generateMaterialID() {
|
|||||||
void TwoColorTrianglesCommand::useMaterial() const {
|
void TwoColorTrianglesCommand::useMaterial() const {
|
||||||
//Set texture
|
//Set texture
|
||||||
GL::bindTexture2D(_textureID);
|
GL::bindTexture2D(_textureID);
|
||||||
|
|
||||||
if (_alphaTextureID > 0) {
|
if (_alphaTextureID > 0) {
|
||||||
// ANDROID ETC1 ALPHA supports.
|
// ANDROID ETC1 ALPHA supports.
|
||||||
GL::bindTexture2DN(1, _alphaTextureID);
|
GL::bindTexture2DN(1, _alphaTextureID);
|
||||||
}
|
}
|
||||||
//set blend mode
|
//set blend mode
|
||||||
GL::blendFunc(_blendType.src, _blendType.dst);
|
GL::blendFunc(_blendType.src, _blendType.dst);
|
||||||
|
|
||||||
_glProgramState->apply(_mv);
|
_glProgramState->apply(_mv);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TwoColorTrianglesCommand::draw() {
|
void TwoColorTrianglesCommand::draw() {
|
||||||
SkeletonTwoColorBatch::getInstance()->batch(this);
|
SkeletonTwoColorBatch::getInstance()->batch(this);
|
||||||
}
|
}
|
||||||
@ -143,7 +143,7 @@ varying vec2 v_texCoord;
|
|||||||
void main() {
|
void main() {
|
||||||
vec4 texColor = texture2D(CC_Texture0, v_texCoord);
|
vec4 texColor = texture2D(CC_Texture0, v_texCoord);
|
||||||
float alpha = texColor.a * v_light.a;
|
float alpha = texColor.a * v_light.a;
|
||||||
gl_FragColor.a = alpha;
|
gl_FragColor.a = alpha;
|
||||||
gl_FragColor.rgb = ((texColor.a - 1.0) * v_dark.a + 1.0 - texColor.rgb) * v_dark.rgb + texColor.rgb * v_light.rgb;
|
gl_FragColor.rgb = ((texColor.a - 1.0) * v_dark.a + 1.0 - texColor.rgb) * v_dark.rgb + texColor.rgb * v_light.rgb;
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -167,19 +167,19 @@ SkeletonTwoColorBatch::SkeletonTwoColorBatch () : _vertexBuffer(0), _indexBuffer
|
|||||||
for (unsigned int i = 0; i < INITIAL_SIZE; i++) {
|
for (unsigned int i = 0; i < INITIAL_SIZE; i++) {
|
||||||
_commandsPool.push_back(new TwoColorTrianglesCommand());
|
_commandsPool.push_back(new TwoColorTrianglesCommand());
|
||||||
}
|
}
|
||||||
|
|
||||||
reset ();
|
reset ();
|
||||||
|
|
||||||
// callback after drawing is finished so we can clear out the batch state
|
// callback after drawing is finished so we can clear out the batch state
|
||||||
// for the next frame
|
// for the next frame
|
||||||
Director::getInstance()->getEventDispatcher()->addCustomEventListener(EVENT_AFTER_DRAW_RESET_POSITION, [this](EventCustom* eventCustom){
|
Director::getInstance()->getEventDispatcher()->addCustomEventListener(EVENT_AFTER_DRAW_RESET_POSITION, [this](EventCustom* eventCustom){
|
||||||
this->update(0);
|
this->update(0);
|
||||||
});
|
});
|
||||||
|
|
||||||
_twoColorTintShader = cocos2d::GLProgram::createWithByteArrays(TWO_COLOR_TINT_VERTEX_SHADER, TWO_COLOR_TINT_FRAGMENT_SHADER);
|
_twoColorTintShader = cocos2d::GLProgram::createWithByteArrays(TWO_COLOR_TINT_VERTEX_SHADER, TWO_COLOR_TINT_FRAGMENT_SHADER);
|
||||||
_twoColorTintShaderState = GLProgramState::getOrCreateWithGLProgram(_twoColorTintShader);
|
_twoColorTintShaderState = GLProgramState::getOrCreateWithGLProgram(_twoColorTintShader);
|
||||||
_twoColorTintShaderState->retain();
|
_twoColorTintShaderState->retain();
|
||||||
|
|
||||||
glGenBuffers(1, &_vertexBufferHandle);
|
glGenBuffers(1, &_vertexBufferHandle);
|
||||||
_vertexBuffer = new V3F_C4B_C4B_T2F[MAX_VERTICES];
|
_vertexBuffer = new V3F_C4B_C4B_T2F[MAX_VERTICES];
|
||||||
glGenBuffers(1, &_indexBufferHandle);
|
glGenBuffers(1, &_indexBufferHandle);
|
||||||
@ -192,7 +192,7 @@ SkeletonTwoColorBatch::SkeletonTwoColorBatch () : _vertexBuffer(0), _indexBuffer
|
|||||||
|
|
||||||
SkeletonTwoColorBatch::~SkeletonTwoColorBatch () {
|
SkeletonTwoColorBatch::~SkeletonTwoColorBatch () {
|
||||||
Director::getInstance()->getEventDispatcher()->removeCustomEventListeners(EVENT_AFTER_DRAW_RESET_POSITION);
|
Director::getInstance()->getEventDispatcher()->removeCustomEventListeners(EVENT_AFTER_DRAW_RESET_POSITION);
|
||||||
|
|
||||||
for (unsigned int i = 0; i < _commandsPool.size(); i++) {
|
for (unsigned int i = 0; i < _commandsPool.size(); i++) {
|
||||||
delete _commandsPool[i];
|
delete _commandsPool[i];
|
||||||
_commandsPool[i] = nullptr;
|
_commandsPool[i] = nullptr;
|
||||||
@ -202,7 +202,7 @@ SkeletonTwoColorBatch::~SkeletonTwoColorBatch () {
|
|||||||
delete[] _indexBuffer;
|
delete[] _indexBuffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonTwoColorBatch::update (float delta) {
|
void SkeletonTwoColorBatch::update (float delta) {
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -217,13 +217,13 @@ V3F_C4B_C4B_T2F* SkeletonTwoColorBatch::allocateVertices(uint32_t numVertices) {
|
|||||||
triangles.verts = newData + (triangles.verts - oldData);
|
triangles.verts = newData + (triangles.verts - oldData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
V3F_C4B_C4B_T2F* vertices = _vertices.data() + _numVertices;
|
V3F_C4B_C4B_T2F* vertices = _vertices.data() + _numVertices;
|
||||||
_numVertices += numVertices;
|
_numVertices += numVertices;
|
||||||
return vertices;
|
return vertices;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SkeletonTwoColorBatch::deallocateVertices(uint32_t numVertices) {
|
void SkeletonTwoColorBatch::deallocateVertices(uint32_t numVertices) {
|
||||||
_numVertices -= numVertices;
|
_numVertices -= numVertices;
|
||||||
}
|
}
|
||||||
@ -243,7 +243,7 @@ unsigned short* SkeletonTwoColorBatch::allocateIndices(uint32_t numIndices) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned short* indices = _indices.buffer() + _indices.size();
|
unsigned short* indices = _indices.buffer() + _indices.size();
|
||||||
_indices.setSize(_indices.size() + numIndices, 0);
|
_indices.setSize(_indices.size() + numIndices, 0);
|
||||||
return indices;
|
return indices;
|
||||||
@ -256,68 +256,68 @@ void SkeletonTwoColorBatch::deallocateIndices(uint32_t numIndices) {
|
|||||||
TwoColorTrianglesCommand* SkeletonTwoColorBatch::addCommand(cocos2d::Renderer* renderer, float globalOrder, GLuint textureID, cocos2d::GLProgramState* glProgramState, cocos2d::BlendFunc blendType, const TwoColorTriangles& triangles, const cocos2d::Mat4& mv, uint32_t flags) {
|
TwoColorTrianglesCommand* SkeletonTwoColorBatch::addCommand(cocos2d::Renderer* renderer, float globalOrder, GLuint textureID, cocos2d::GLProgramState* glProgramState, cocos2d::BlendFunc blendType, const TwoColorTriangles& triangles, const cocos2d::Mat4& mv, uint32_t flags) {
|
||||||
TwoColorTrianglesCommand* command = nextFreeCommand();
|
TwoColorTrianglesCommand* command = nextFreeCommand();
|
||||||
command->init(globalOrder, textureID, glProgramState, blendType, triangles, mv, flags);
|
command->init(globalOrder, textureID, glProgramState, blendType, triangles, mv, flags);
|
||||||
renderer->addCommand(command);
|
renderer->addCommand(command);
|
||||||
return command;
|
return command;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonTwoColorBatch::batch (TwoColorTrianglesCommand* command) {
|
void SkeletonTwoColorBatch::batch (TwoColorTrianglesCommand* command) {
|
||||||
if (_numVerticesBuffer + command->getTriangles().vertCount >= MAX_VERTICES || _numIndicesBuffer + command->getTriangles().indexCount >= MAX_INDICES) {
|
if (_numVerticesBuffer + command->getTriangles().vertCount >= MAX_VERTICES || _numIndicesBuffer + command->getTriangles().indexCount >= MAX_INDICES) {
|
||||||
flush(_lastCommand);
|
flush(_lastCommand);
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t materialID = command->getMaterialID();
|
uint32_t materialID = command->getMaterialID();
|
||||||
if (_lastCommand && _lastCommand->getMaterialID() != materialID) {
|
if (_lastCommand && _lastCommand->getMaterialID() != materialID) {
|
||||||
flush(_lastCommand);
|
flush(_lastCommand);
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(_vertexBuffer + _numVerticesBuffer, command->getTriangles().verts, sizeof(V3F_C4B_C4B_T2F) * command->getTriangles().vertCount);
|
memcpy(_vertexBuffer + _numVerticesBuffer, command->getTriangles().verts, sizeof(V3F_C4B_C4B_T2F) * command->getTriangles().vertCount);
|
||||||
const Mat4& modelView = command->getModelView();
|
const Mat4& modelView = command->getModelView();
|
||||||
for (int i = _numVerticesBuffer; i < _numVerticesBuffer + command->getTriangles().vertCount; i++) {
|
for (int i = _numVerticesBuffer; i < _numVerticesBuffer + command->getTriangles().vertCount; i++) {
|
||||||
modelView.transformPoint(&_vertexBuffer[i].position);
|
modelView.transformPoint(&_vertexBuffer[i].position);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned short vertexOffset = (unsigned short)_numVerticesBuffer;
|
unsigned short vertexOffset = (unsigned short)_numVerticesBuffer;
|
||||||
unsigned short* indices = command->getTriangles().indices;
|
unsigned short* indices = command->getTriangles().indices;
|
||||||
for (int i = 0, j = _numIndicesBuffer; i < command->getTriangles().indexCount; i++, j++) {
|
for (int i = 0, j = _numIndicesBuffer; i < command->getTriangles().indexCount; i++, j++) {
|
||||||
_indexBuffer[j] = indices[i] + vertexOffset;
|
_indexBuffer[j] = indices[i] + vertexOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
_numVerticesBuffer += command->getTriangles().vertCount;
|
_numVerticesBuffer += command->getTriangles().vertCount;
|
||||||
_numIndicesBuffer += command->getTriangles().indexCount;
|
_numIndicesBuffer += command->getTriangles().indexCount;
|
||||||
|
|
||||||
if (command->isForceFlush()) {
|
if (command->isForceFlush()) {
|
||||||
flush(command);
|
flush(command);
|
||||||
}
|
}
|
||||||
_lastCommand = command;
|
_lastCommand = command;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SkeletonTwoColorBatch::flush (TwoColorTrianglesCommand* materialCommand) {
|
void SkeletonTwoColorBatch::flush (TwoColorTrianglesCommand* materialCommand) {
|
||||||
if (!materialCommand)
|
if (!materialCommand)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
materialCommand->useMaterial();
|
materialCommand->useMaterial();
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferHandle);
|
glBindBuffer(GL_ARRAY_BUFFER, _vertexBufferHandle);
|
||||||
glBufferData(GL_ARRAY_BUFFER, sizeof(V3F_C4B_C4B_T2F) * _numVerticesBuffer , _vertexBuffer, GL_DYNAMIC_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, sizeof(V3F_C4B_C4B_T2F) * _numVerticesBuffer , _vertexBuffer, GL_DYNAMIC_DRAW);
|
||||||
|
|
||||||
glEnableVertexAttribArray(_positionAttributeLocation);
|
glEnableVertexAttribArray(_positionAttributeLocation);
|
||||||
glEnableVertexAttribArray(_colorAttributeLocation);
|
glEnableVertexAttribArray(_colorAttributeLocation);
|
||||||
glEnableVertexAttribArray(_color2AttributeLocation);
|
glEnableVertexAttribArray(_color2AttributeLocation);
|
||||||
glEnableVertexAttribArray(_texCoordsAttributeLocation);
|
glEnableVertexAttribArray(_texCoordsAttributeLocation);
|
||||||
|
|
||||||
glVertexAttribPointer(_positionAttributeLocation, 3, GL_FLOAT, GL_FALSE, sizeof(V3F_C4B_C4B_T2F), (GLvoid*)offsetof(V3F_C4B_C4B_T2F, position));
|
glVertexAttribPointer(_positionAttributeLocation, 3, GL_FLOAT, GL_FALSE, sizeof(V3F_C4B_C4B_T2F), (GLvoid*)offsetof(V3F_C4B_C4B_T2F, position));
|
||||||
glVertexAttribPointer(_colorAttributeLocation, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(V3F_C4B_C4B_T2F), (GLvoid*)offsetof(V3F_C4B_C4B_T2F, color));
|
glVertexAttribPointer(_colorAttributeLocation, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(V3F_C4B_C4B_T2F), (GLvoid*)offsetof(V3F_C4B_C4B_T2F, color));
|
||||||
glVertexAttribPointer(_color2AttributeLocation, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(V3F_C4B_C4B_T2F), (GLvoid*)offsetof(V3F_C4B_C4B_T2F, color2));
|
glVertexAttribPointer(_color2AttributeLocation, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(V3F_C4B_C4B_T2F), (GLvoid*)offsetof(V3F_C4B_C4B_T2F, color2));
|
||||||
glVertexAttribPointer(_texCoordsAttributeLocation, 2, GL_FLOAT, GL_FALSE, sizeof(V3F_C4B_C4B_T2F), (GLvoid*)offsetof(V3F_C4B_C4B_T2F, texCoords));
|
glVertexAttribPointer(_texCoordsAttributeLocation, 2, GL_FLOAT, GL_FALSE, sizeof(V3F_C4B_C4B_T2F), (GLvoid*)offsetof(V3F_C4B_C4B_T2F, texCoords));
|
||||||
|
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBufferHandle);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, _indexBufferHandle);
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short) * _numIndicesBuffer, _indexBuffer, GL_STATIC_DRAW);
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(unsigned short) * _numIndicesBuffer, _indexBuffer, GL_STATIC_DRAW);
|
||||||
|
|
||||||
glDrawElements(GL_TRIANGLES, (GLsizei)_numIndicesBuffer, GL_UNSIGNED_SHORT, 0);
|
glDrawElements(GL_TRIANGLES, (GLsizei)_numIndicesBuffer, GL_UNSIGNED_SHORT, 0);
|
||||||
|
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
_numVerticesBuffer = 0;
|
_numVerticesBuffer = 0;
|
||||||
_numIndicesBuffer = 0;
|
_numIndicesBuffer = 0;
|
||||||
_numBatches++;
|
_numBatches++;
|
||||||
|
|||||||
@ -41,50 +41,50 @@ namespace spine {
|
|||||||
cocos2d::Color4B color2;
|
cocos2d::Color4B color2;
|
||||||
cocos2d::Tex2F texCoords;
|
cocos2d::Tex2F texCoords;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TwoColorTriangles {
|
struct TwoColorTriangles {
|
||||||
V3F_C4B_C4B_T2F* verts;
|
V3F_C4B_C4B_T2F* verts;
|
||||||
unsigned short* indices;
|
unsigned short* indices;
|
||||||
int vertCount;
|
int vertCount;
|
||||||
int indexCount;
|
int indexCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TwoColorTrianglesCommand : public cocos2d::CustomCommand {
|
class TwoColorTrianglesCommand : public cocos2d::CustomCommand {
|
||||||
public:
|
public:
|
||||||
TwoColorTrianglesCommand();
|
TwoColorTrianglesCommand();
|
||||||
|
|
||||||
~TwoColorTrianglesCommand();
|
~TwoColorTrianglesCommand();
|
||||||
|
|
||||||
void init(float globalOrder, GLuint textureID, cocos2d::GLProgramState* glProgramState, cocos2d::BlendFunc blendType, const TwoColorTriangles& triangles, const cocos2d::Mat4& mv, uint32_t flags);
|
void init(float globalOrder, GLuint textureID, cocos2d::GLProgramState* glProgramState, cocos2d::BlendFunc blendType, const TwoColorTriangles& triangles, const cocos2d::Mat4& mv, uint32_t flags);
|
||||||
|
|
||||||
void useMaterial() const;
|
void useMaterial() const;
|
||||||
|
|
||||||
inline uint32_t getMaterialID() const { return _materialID; }
|
inline uint32_t getMaterialID() const { return _materialID; }
|
||||||
|
|
||||||
inline GLuint getTextureID() const { return _textureID; }
|
inline GLuint getTextureID() const { return _textureID; }
|
||||||
|
|
||||||
inline const TwoColorTriangles& getTriangles() const { return _triangles; }
|
inline const TwoColorTriangles& getTriangles() const { return _triangles; }
|
||||||
|
|
||||||
inline ssize_t getVertexCount() const { return _triangles.vertCount; }
|
inline ssize_t getVertexCount() const { return _triangles.vertCount; }
|
||||||
|
|
||||||
inline ssize_t getIndexCount() const { return _triangles.indexCount; }
|
inline ssize_t getIndexCount() const { return _triangles.indexCount; }
|
||||||
|
|
||||||
inline const V3F_C4B_C4B_T2F* getVertices() const { return _triangles.verts; }
|
inline const V3F_C4B_C4B_T2F* getVertices() const { return _triangles.verts; }
|
||||||
|
|
||||||
inline const unsigned short* getIndices() const { return _triangles.indices; }
|
inline const unsigned short* getIndices() const { return _triangles.indices; }
|
||||||
|
|
||||||
inline cocos2d::GLProgramState* getGLProgramState() const { return _glProgramState; }
|
inline cocos2d::GLProgramState* getGLProgramState() const { return _glProgramState; }
|
||||||
|
|
||||||
inline cocos2d::BlendFunc getBlendType() const { return _blendType; }
|
inline cocos2d::BlendFunc getBlendType() const { return _blendType; }
|
||||||
|
|
||||||
inline const cocos2d::Mat4& getModelView() const { return _mv; }
|
inline const cocos2d::Mat4& getModelView() const { return _mv; }
|
||||||
|
|
||||||
void draw ();
|
void draw ();
|
||||||
|
|
||||||
void setForceFlush (bool forceFlush) { _forceFlush = forceFlush; }
|
void setForceFlush (bool forceFlush) { _forceFlush = forceFlush; }
|
||||||
|
|
||||||
bool isForceFlush () { return _forceFlush; };
|
bool isForceFlush () { return _forceFlush; };
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void generateMaterialID();
|
void generateMaterialID();
|
||||||
uint32_t _materialID;
|
uint32_t _materialID;
|
||||||
@ -98,33 +98,33 @@ namespace spine {
|
|||||||
bool _forceFlush;
|
bool _forceFlush;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SkeletonTwoColorBatch {
|
class SkeletonTwoColorBatch {
|
||||||
public:
|
public:
|
||||||
static SkeletonTwoColorBatch* getInstance ();
|
static SkeletonTwoColorBatch* getInstance ();
|
||||||
|
|
||||||
static void destroyInstance ();
|
static void destroyInstance ();
|
||||||
|
|
||||||
void update (float delta);
|
void update (float delta);
|
||||||
|
|
||||||
V3F_C4B_C4B_T2F* allocateVertices(uint32_t numVertices);
|
V3F_C4B_C4B_T2F* allocateVertices(uint32_t numVertices);
|
||||||
void deallocateVertices(uint32_t numVertices);
|
void deallocateVertices(uint32_t numVertices);
|
||||||
|
|
||||||
unsigned short* allocateIndices(uint32_t numIndices);
|
unsigned short* allocateIndices(uint32_t numIndices);
|
||||||
void deallocateIndices(uint32_t numIndices);
|
void deallocateIndices(uint32_t numIndices);
|
||||||
|
|
||||||
TwoColorTrianglesCommand* addCommand(cocos2d::Renderer* renderer, float globalOrder, GLuint textureID, cocos2d::GLProgramState* glProgramState, cocos2d::BlendFunc blendType, const TwoColorTriangles& triangles, const cocos2d::Mat4& mv, uint32_t flags);
|
TwoColorTrianglesCommand* addCommand(cocos2d::Renderer* renderer, float globalOrder, GLuint textureID, cocos2d::GLProgramState* glProgramState, cocos2d::BlendFunc blendType, const TwoColorTriangles& triangles, const cocos2d::Mat4& mv, uint32_t flags);
|
||||||
|
|
||||||
cocos2d::GLProgramState* getTwoColorTintProgramState () { return _twoColorTintShaderState; }
|
cocos2d::GLProgramState* getTwoColorTintProgramState () { return _twoColorTintShaderState; }
|
||||||
|
|
||||||
void batch (TwoColorTrianglesCommand* command);
|
void batch (TwoColorTrianglesCommand* command);
|
||||||
|
|
||||||
void flush (TwoColorTrianglesCommand* materialCommand);
|
void flush (TwoColorTrianglesCommand* materialCommand);
|
||||||
|
|
||||||
uint32_t getNumBatches () { return _numBatches; };
|
uint32_t getNumBatches () { return _numBatches; };
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
SkeletonTwoColorBatch ();
|
SkeletonTwoColorBatch ();
|
||||||
virtual ~SkeletonTwoColorBatch ();
|
virtual ~SkeletonTwoColorBatch ();
|
||||||
|
|
||||||
void reset ();
|
void reset ();
|
||||||
|
|
||||||
@ -137,14 +137,14 @@ namespace spine {
|
|||||||
// pool of vertices
|
// pool of vertices
|
||||||
std::vector<V3F_C4B_C4B_T2F> _vertices;
|
std::vector<V3F_C4B_C4B_T2F> _vertices;
|
||||||
uint32_t _numVertices;
|
uint32_t _numVertices;
|
||||||
|
|
||||||
// pool of indices
|
// pool of indices
|
||||||
Vector<unsigned short> _indices;
|
Vector<unsigned short> _indices;
|
||||||
|
|
||||||
// two color tint shader and state
|
// two color tint shader and state
|
||||||
cocos2d::GLProgram* _twoColorTintShader;
|
cocos2d::GLProgram* _twoColorTintShader;
|
||||||
cocos2d::GLProgramState* _twoColorTintShaderState;
|
cocos2d::GLProgramState* _twoColorTintShaderState;
|
||||||
|
|
||||||
// VBO handles & attribute locations
|
// VBO handles & attribute locations
|
||||||
GLuint _vertexBufferHandle;
|
GLuint _vertexBufferHandle;
|
||||||
V3F_C4B_C4B_T2F* _vertexBuffer;
|
V3F_C4B_C4B_T2F* _vertexBuffer;
|
||||||
@ -156,10 +156,10 @@ namespace spine {
|
|||||||
GLint _colorAttributeLocation;
|
GLint _colorAttributeLocation;
|
||||||
GLint _color2AttributeLocation;
|
GLint _color2AttributeLocation;
|
||||||
GLint _texCoordsAttributeLocation;
|
GLint _texCoordsAttributeLocation;
|
||||||
|
|
||||||
// last batched command, needed for flushing to set material
|
// last batched command, needed for flushing to set material
|
||||||
TwoColorTrianglesCommand* _lastCommand;
|
TwoColorTrianglesCommand* _lastCommand;
|
||||||
|
|
||||||
// number of batches in the last frame
|
// number of batches in the last frame
|
||||||
uint32_t _numBatches;
|
uint32_t _numBatches;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -48,7 +48,7 @@ static void setAttachmentVertices(RegionAttachment* attachment) {
|
|||||||
vertices[i].texCoords.u = attachment->getUVs()[ii];
|
vertices[i].texCoords.u = attachment->getUVs()[ii];
|
||||||
vertices[i].texCoords.v = attachment->getUVs()[ii + 1];
|
vertices[i].texCoords.v = attachment->getUVs()[ii + 1];
|
||||||
}
|
}
|
||||||
attachment->setRendererObject(attachmentVertices, deleteAttachmentVertices);
|
attachment->setRendererObject(attachmentVertices, deleteAttachmentVertices);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void setAttachmentVertices(MeshAttachment* attachment) {
|
static void setAttachmentVertices(MeshAttachment* attachment) {
|
||||||
@ -63,7 +63,7 @@ static void setAttachmentVertices(MeshAttachment* attachment) {
|
|||||||
attachment->setRendererObject(attachmentVertices, deleteAttachmentVertices);
|
attachment->setRendererObject(attachmentVertices, deleteAttachmentVertices);
|
||||||
}
|
}
|
||||||
|
|
||||||
Cocos2dAtlasAttachmentLoader::Cocos2dAtlasAttachmentLoader(Atlas* atlas): AtlasAttachmentLoader(atlas) {
|
Cocos2dAtlasAttachmentLoader::Cocos2dAtlasAttachmentLoader(Atlas* atlas): AtlasAttachmentLoader(atlas) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cocos2dAtlasAttachmentLoader::configureAttachment(Attachment* attachment) {
|
void Cocos2dAtlasAttachmentLoader::configureAttachment(Attachment* attachment) {
|
||||||
@ -113,7 +113,7 @@ void Cocos2dTextureLoader::load(AtlasPage& page, const spine::String& path) {
|
|||||||
page.height = texture->getPixelsHigh();
|
page.height = texture->getPixelsHigh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Cocos2dTextureLoader::unload(void* texture) {
|
void Cocos2dTextureLoader::unload(void* texture) {
|
||||||
if (texture)
|
if (texture)
|
||||||
{
|
{
|
||||||
@ -125,7 +125,7 @@ void Cocos2dTextureLoader::unload(void* texture) {
|
|||||||
char *Cocos2dExtension::_readFile(const spine::String &path, int *length) {
|
char *Cocos2dExtension::_readFile(const spine::String &path, int *length) {
|
||||||
Data data = FileUtils::getInstance()->getDataFromFile(FileUtils::getInstance()->fullPathForFilename(path.buffer()));
|
Data data = FileUtils::getInstance()->getDataFromFile(FileUtils::getInstance()->fullPathForFilename(path.buffer()));
|
||||||
if (data.isNull()) return nullptr;
|
if (data.isNull()) return nullptr;
|
||||||
|
|
||||||
// avoid buffer overflow (int is shorter than ssize_t in certain platforms)
|
// avoid buffer overflow (int is shorter than ssize_t in certain platforms)
|
||||||
#if COCOS2D_VERSION >= 0x00031200
|
#if COCOS2D_VERSION >= 0x00031200
|
||||||
ssize_t tmpLen;
|
ssize_t tmpLen;
|
||||||
|
|||||||
@ -43,18 +43,18 @@ namespace spine {
|
|||||||
Cocos2dAtlasAttachmentLoader(Atlas* atlas);
|
Cocos2dAtlasAttachmentLoader(Atlas* atlas);
|
||||||
virtual void configureAttachment(Attachment* attachment);
|
virtual void configureAttachment(Attachment* attachment);
|
||||||
};
|
};
|
||||||
|
|
||||||
class Cocos2dTextureLoader: public TextureLoader {
|
class Cocos2dTextureLoader: public TextureLoader {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
virtual void load(AtlasPage& page, const String& path);
|
virtual void load(AtlasPage& page, const String& path);
|
||||||
|
|
||||||
virtual void unload(void* texture);
|
virtual void unload(void* texture);
|
||||||
};
|
};
|
||||||
|
|
||||||
class Cocos2dExtension: public DefaultSpineExtension {
|
class Cocos2dExtension: public DefaultSpineExtension {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual char *_readFile(const String &path, int *length);
|
virtual char *_readFile(const String &path, int *length);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -129,7 +129,7 @@ function spine.Skeleton:updateWorldTransform()
|
|||||||
local premultipliedAlpha = self.premultipliedAlpha
|
local premultipliedAlpha = self.premultipliedAlpha
|
||||||
|
|
||||||
self.batches = 0
|
self.batches = 0
|
||||||
|
|
||||||
if (self.vertexEffect) then self.vertexEffect:beginEffect(self) end
|
if (self.vertexEffect) then self.vertexEffect:beginEffect(self) end
|
||||||
|
|
||||||
-- Remove old drawing group, we will start anew
|
-- Remove old drawing group, we will start anew
|
||||||
@ -154,94 +154,94 @@ function spine.Skeleton:updateWorldTransform()
|
|||||||
vertices = nil,
|
vertices = nil,
|
||||||
uvs = nil
|
uvs = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
for _,slot in ipairs(drawOrder) do
|
for _,slot in ipairs(drawOrder) do
|
||||||
local attachment = slot.attachment
|
local attachment = slot.attachment
|
||||||
local vertices = nil
|
local vertices = nil
|
||||||
local uvs = nil
|
local uvs = nil
|
||||||
local numVertices = 0
|
local numVertices = 0
|
||||||
local indices = nil
|
local indices = nil
|
||||||
|
|
||||||
if slot.bone.active then
|
|
||||||
|
|
||||||
if attachment then
|
|
||||||
if attachment.type == spine.AttachmentType.region then
|
|
||||||
numVertices = 4
|
|
||||||
vertices = worldVertices
|
|
||||||
attachment:computeWorldVertices(slot.bone, vertices, 0, 2)
|
|
||||||
uvs = attachment.uvs
|
|
||||||
indices = QUAD_TRIANGLES
|
|
||||||
texture = attachment.region.renderObject.texture
|
|
||||||
blendMode = toCoronaBlendMode(slot.data.blendMode)
|
|
||||||
elseif attachment.type == spine.AttachmentType.mesh then
|
|
||||||
numVertices = attachment.worldVerticesLength / 2
|
|
||||||
vertices = worldVertices
|
|
||||||
attachment:computeWorldVertices(slot, 0, attachment.worldVerticesLength, vertices, 0, 2)
|
|
||||||
uvs = attachment.uvs
|
|
||||||
indices = attachment.triangles
|
|
||||||
texture = attachment.region.renderObject.texture
|
|
||||||
blendMode = toCoronaBlendMode(slot.data.blendMode)
|
|
||||||
elseif attachment.type == spine.AttachmentType.clipping then
|
|
||||||
self.clipper:clipStart(slot, attachment)
|
|
||||||
end
|
|
||||||
|
|
||||||
if texture and vertices and indices then
|
if slot.bone.active then
|
||||||
local skeleton = slot.bone.skeleton
|
|
||||||
local skeletonColor = skeleton.color
|
|
||||||
local slotColor = slot.color
|
|
||||||
local attachmentColor = attachment.color
|
|
||||||
local alpha = skeletonColor.a * slotColor.a * attachmentColor.a
|
|
||||||
local multiplier = alpha
|
|
||||||
if premultipliedAlpha then multiplier = 1 end
|
|
||||||
color:set(skeletonColor.r * slotColor.r * attachmentColor.r * multiplier,
|
|
||||||
skeletonColor.g * slotColor.g * attachmentColor.g * multiplier,
|
|
||||||
skeletonColor.b * slotColor.b * attachmentColor.b * multiplier,
|
|
||||||
alpha)
|
|
||||||
|
|
||||||
if not lastTexture then lastTexture = texture end
|
|
||||||
if lastColor.r == -1 then lastColor:setFrom(color) end
|
|
||||||
if not lastBlendMode then lastBlendMode = blendMode end
|
|
||||||
|
|
||||||
if (texture ~= lastTexture or not colorEquals(color, lastColor) or blendMode ~= lastBlendMode) then
|
if attachment then
|
||||||
self:flush(groupVertices, groupUvs, groupIndices, lastTexture, lastColor, lastBlendMode, drawingGroup)
|
if attachment.type == spine.AttachmentType.region then
|
||||||
lastTexture = texture
|
numVertices = 4
|
||||||
lastColor:setFrom(color)
|
vertices = worldVertices
|
||||||
lastBlendMode = blendMode
|
attachment:computeWorldVertices(slot.bone, vertices, 0, 2)
|
||||||
groupVertices = {}
|
uvs = attachment.uvs
|
||||||
groupUvs = {}
|
indices = QUAD_TRIANGLES
|
||||||
groupIndices = {}
|
texture = attachment.region.renderObject.texture
|
||||||
end
|
blendMode = toCoronaBlendMode(slot.data.blendMode)
|
||||||
|
elseif attachment.type == spine.AttachmentType.mesh then
|
||||||
if self.clipper:isClipping() then
|
numVertices = attachment.worldVerticesLength / 2
|
||||||
self.clipper:clipTriangles(vertices, uvs, indices, #indices)
|
vertices = worldVertices
|
||||||
vertices = self.clipper.clippedVertices
|
attachment:computeWorldVertices(slot, 0, attachment.worldVerticesLength, vertices, 0, 2)
|
||||||
numVertices = #vertices / 2
|
uvs = attachment.uvs
|
||||||
uvs = self.clipper.clippedUVs
|
indices = attachment.triangles
|
||||||
indices = self.clipper.clippedTriangles
|
texture = attachment.region.renderObject.texture
|
||||||
end
|
blendMode = toCoronaBlendMode(slot.data.blendMode)
|
||||||
|
elseif attachment.type == spine.AttachmentType.clipping then
|
||||||
|
self.clipper:clipStart(slot, attachment)
|
||||||
|
end
|
||||||
|
|
||||||
self:batch(vertices, uvs, numVertices, indices, groupVertices, groupUvs, groupIndices)
|
if texture and vertices and indices then
|
||||||
end
|
local skeleton = slot.bone.skeleton
|
||||||
|
local skeletonColor = skeleton.color
|
||||||
self.clipper:clipEnd(slot)
|
local slotColor = slot.color
|
||||||
end
|
local attachmentColor = attachment.color
|
||||||
|
local alpha = skeletonColor.a * slotColor.a * attachmentColor.a
|
||||||
|
local multiplier = alpha
|
||||||
|
if premultipliedAlpha then multiplier = 1 end
|
||||||
|
color:set(skeletonColor.r * slotColor.r * attachmentColor.r * multiplier,
|
||||||
|
skeletonColor.g * slotColor.g * attachmentColor.g * multiplier,
|
||||||
|
skeletonColor.b * slotColor.b * attachmentColor.b * multiplier,
|
||||||
|
alpha)
|
||||||
|
|
||||||
|
if not lastTexture then lastTexture = texture end
|
||||||
|
if lastColor.r == -1 then lastColor:setFrom(color) end
|
||||||
|
if not lastBlendMode then lastBlendMode = blendMode end
|
||||||
|
|
||||||
|
if (texture ~= lastTexture or not colorEquals(color, lastColor) or blendMode ~= lastBlendMode) then
|
||||||
|
self:flush(groupVertices, groupUvs, groupIndices, lastTexture, lastColor, lastBlendMode, drawingGroup)
|
||||||
|
lastTexture = texture
|
||||||
|
lastColor:setFrom(color)
|
||||||
|
lastBlendMode = blendMode
|
||||||
|
groupVertices = {}
|
||||||
|
groupUvs = {}
|
||||||
|
groupIndices = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
if self.clipper:isClipping() then
|
||||||
|
self.clipper:clipTriangles(vertices, uvs, indices, #indices)
|
||||||
|
vertices = self.clipper.clippedVertices
|
||||||
|
numVertices = #vertices / 2
|
||||||
|
uvs = self.clipper.clippedUVs
|
||||||
|
indices = self.clipper.clippedTriangles
|
||||||
|
end
|
||||||
|
|
||||||
|
self:batch(vertices, uvs, numVertices, indices, groupVertices, groupUvs, groupIndices)
|
||||||
|
end
|
||||||
|
|
||||||
|
self.clipper:clipEnd(slot)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
if #groupVertices > 0 then
|
if #groupVertices > 0 then
|
||||||
self:flush(groupVertices, groupUvs, groupIndices, texture, color, blendMode, drawingGroup)
|
self:flush(groupVertices, groupUvs, groupIndices, texture, color, blendMode, drawingGroup)
|
||||||
end
|
end
|
||||||
|
|
||||||
self.clipper:clipEnd2()
|
self.clipper:clipEnd2()
|
||||||
if (self.vertexEffect) then self.vertexEffect:endEffect() end
|
if (self.vertexEffect) then self.vertexEffect:endEffect() end
|
||||||
end
|
end
|
||||||
|
|
||||||
function spine.Skeleton:flush(groupVertices, groupUvs, groupIndices, texture, color, blendMode, drawingGroup)
|
function spine.Skeleton:flush(groupVertices, groupUvs, groupIndices, texture, color, blendMode, drawingGroup)
|
||||||
local mesh = display.newMesh(drawingGroup, 0, 0, {
|
local mesh = display.newMesh(drawingGroup, 0, 0, {
|
||||||
mode = "indexed",
|
mode = "indexed",
|
||||||
vertices = groupVertices,
|
vertices = groupVertices,
|
||||||
uvs = groupUvs,
|
uvs = groupUvs,
|
||||||
indices = groupIndices
|
indices = groupIndices
|
||||||
})
|
})
|
||||||
mesh.fill = texture
|
mesh.fill = texture
|
||||||
mesh:setFillColor(color.r, color.g, color.b)
|
mesh:setFillColor(color.r, color.g, color.b)
|
||||||
|
|||||||
@ -88,7 +88,7 @@ public:
|
|||||||
/// Applies all the animation's timelines to the specified skeleton.
|
/// Applies all the animation's timelines to the specified skeleton.
|
||||||
/// See also Timeline::apply(Skeleton&, float, float, Vector, float, MixPose, MixDirection)
|
/// See also Timeline::apply(Skeleton&, float, float, Vector, float, MixPose, MixDirection)
|
||||||
void apply(Skeleton &skeleton, float lastTime, float time, bool loop, Vector<Event *> *pEvents, float alpha,
|
void apply(Skeleton &skeleton, float lastTime, float time, bool loop, Vector<Event *> *pEvents, float alpha,
|
||||||
MixBlend blend, MixDirection direction);
|
MixBlend blend, MixDirection direction);
|
||||||
|
|
||||||
const String &getName();
|
const String &getName();
|
||||||
|
|
||||||
|
|||||||
@ -42,23 +42,23 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
enum EventType {
|
enum EventType {
|
||||||
EventType_Start,
|
EventType_Start,
|
||||||
EventType_Interrupt,
|
EventType_Interrupt,
|
||||||
EventType_End,
|
EventType_End,
|
||||||
EventType_Complete,
|
EventType_Complete,
|
||||||
EventType_Dispose,
|
EventType_Dispose,
|
||||||
EventType_Event
|
EventType_Event
|
||||||
};
|
};
|
||||||
|
|
||||||
class AnimationState;
|
|
||||||
class TrackEntry;
|
|
||||||
|
|
||||||
class Animation;
|
class AnimationState;
|
||||||
class Event;
|
class TrackEntry;
|
||||||
class AnimationStateData;
|
|
||||||
class Skeleton;
|
class Animation;
|
||||||
class RotateTimeline;
|
class Event;
|
||||||
|
class AnimationStateData;
|
||||||
|
class Skeleton;
|
||||||
|
class RotateTimeline;
|
||||||
|
|
||||||
#ifdef SPINE_USE_STD_FUNCTION
|
#ifdef SPINE_USE_STD_FUNCTION
|
||||||
typedef std::function<void (AnimationState* state, EventType type, TrackEntry* entry, Event* event)> AnimationStateListener;
|
typedef std::function<void (AnimationState* state, EventType type, TrackEntry* entry, Event* event)> AnimationStateListener;
|
||||||
@ -75,400 +75,363 @@ namespace spine {
|
|||||||
/// The callback function to be called
|
/// The callback function to be called
|
||||||
virtual void callback(AnimationState* state, EventType type, TrackEntry* entry, Event* event) = 0;
|
virtual void callback(AnimationState* state, EventType type, TrackEntry* entry, Event* event) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
/// State for the playback of an animation
|
|
||||||
class SP_API TrackEntry : public SpineObject, public HasRendererObject {
|
|
||||||
friend class EventQueue;
|
|
||||||
friend class AnimationState;
|
|
||||||
|
|
||||||
public:
|
|
||||||
TrackEntry();
|
|
||||||
|
|
||||||
virtual ~TrackEntry();
|
/// State for the playback of an animation
|
||||||
|
class SP_API TrackEntry : public SpineObject, public HasRendererObject {
|
||||||
/// The index of the track where this entry is either current or queued.
|
friend class EventQueue;
|
||||||
int getTrackIndex();
|
friend class AnimationState;
|
||||||
|
|
||||||
/// The animation to apply for this track entry.
|
|
||||||
Animation* getAnimation();
|
|
||||||
|
|
||||||
///
|
|
||||||
/// If true, the animation will repeat. If false, it will not, instead its last frame is applied if played beyond its duration.
|
|
||||||
bool getLoop();
|
|
||||||
void setLoop(bool inValue);
|
|
||||||
|
|
||||||
///
|
public:
|
||||||
/// If true, when mixing from the previous animation to this animation, the previous animation is applied as normal instead
|
TrackEntry();
|
||||||
/// of being mixed out.
|
|
||||||
///
|
|
||||||
/// When mixing between animations that key the same property, if a lower track also keys that property then the value will
|
|
||||||
/// briefly dip toward the lower track value during the mix. This happens because the first animation mixes from 100% to 0%
|
|
||||||
/// while the second animation mixes from 0% to 100%. Setting holdPrevious to true applies the first animation
|
|
||||||
/// at 100% during the mix so the lower track value is overwritten. Such dipping does not occur on the lowest track which
|
|
||||||
/// keys the property, only when a higher track also keys the property.
|
|
||||||
///
|
|
||||||
/// Snapping will occur if holdPrevious is true and this animation does not key all the same properties as the
|
|
||||||
/// previous animation.
|
|
||||||
bool getHoldPrevious();
|
|
||||||
void setHoldPrevious(bool inValue);
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Seconds to postpone playing the animation. When a track entry is the current track entry, delay postpones incrementing
|
|
||||||
/// the track time. When a track entry is queued, delay is the time from the start of the previous animation to when the
|
|
||||||
/// track entry will become the current track entry.
|
|
||||||
float getDelay();
|
|
||||||
void setDelay(float inValue);
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Current time in seconds this track entry has been the current track entry. The track time determines
|
|
||||||
/// TrackEntry.AnimationTime. The track time can be set to start the animation at a time other than 0, without affecting looping.
|
|
||||||
float getTrackTime();
|
|
||||||
void setTrackTime(float inValue);
|
|
||||||
|
|
||||||
///
|
|
||||||
/// The track time in seconds when this animation will be removed from the track. Defaults to the animation duration for
|
|
||||||
/// non-looping animations and to int.MaxValue for looping animations. If the track end time is reached and no
|
|
||||||
/// other animations are queued for playback, and mixing from any previous animations is complete, properties keyed by the animation,
|
|
||||||
/// are set to the setup pose and the track is cleared.
|
|
||||||
///
|
|
||||||
/// It may be desired to use AnimationState.addEmptyAnimation(int, float, float) to mix the properties back to the
|
|
||||||
/// setup pose over time, rather than have it happen instantly.
|
|
||||||
///
|
|
||||||
float getTrackEnd();
|
|
||||||
void setTrackEnd(float inValue);
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Seconds when this animation starts, both initially and after looping. Defaults to 0.
|
|
||||||
///
|
|
||||||
/// When changing the animation start time, it often makes sense to set TrackEntry.AnimationLast to the same value to
|
|
||||||
/// prevent timeline keys before the start time from triggering.
|
|
||||||
///
|
|
||||||
float getAnimationStart();
|
|
||||||
void setAnimationStart(float inValue);
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Seconds for the last frame of this animation. Non-looping animations won't play past this time. Looping animations will
|
|
||||||
/// loop back to TrackEntry.AnimationStart at this time. Defaults to the animation duration.
|
|
||||||
float getAnimationEnd();
|
|
||||||
void setAnimationEnd(float inValue);
|
|
||||||
|
|
||||||
///
|
|
||||||
/// The time in seconds this animation was last applied. Some timelines use this for one-time triggers. Eg, when this
|
|
||||||
/// animation is applied, event timelines will fire all events between the animation last time (exclusive) and animation time
|
|
||||||
/// (inclusive). Defaults to -1 to ensure triggers on frame 0 happen the first time this animation is applied.
|
|
||||||
float getAnimationLast();
|
|
||||||
void setAnimationLast(float inValue);
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Uses TrackEntry.TrackTime to compute the animation time between TrackEntry.AnimationStart. and
|
|
||||||
/// TrackEntry.AnimationEnd. When the track time is 0, the animation time is equal to the animation start time.
|
|
||||||
///
|
|
||||||
float getAnimationTime();
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Multiplier for the delta time when the animation state is updated, causing time for this animation to play slower or
|
|
||||||
/// faster. Defaults to 1.
|
|
||||||
///
|
|
||||||
float getTimeScale();
|
|
||||||
void setTimeScale(float inValue);
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Values less than 1 mix this animation with the last skeleton pose. Defaults to 1, which overwrites the last skeleton pose with
|
|
||||||
/// this animation.
|
|
||||||
///
|
|
||||||
/// Typically track 0 is used to completely pose the skeleton, then alpha can be used on higher tracks. It doesn't make sense
|
|
||||||
/// to use alpha on track 0 if the skeleton pose is from the last frame render.
|
|
||||||
///
|
|
||||||
float getAlpha();
|
|
||||||
void setAlpha(float inValue);
|
|
||||||
|
|
||||||
///
|
|
||||||
/// When the mix percentage (mix time / mix duration) is less than the event threshold, event timelines for the animation
|
|
||||||
/// being mixed out will be applied. Defaults to 0, so event timelines are not applied for an animation being mixed out.
|
|
||||||
float getEventThreshold();
|
|
||||||
void setEventThreshold(float inValue);
|
|
||||||
|
|
||||||
///
|
|
||||||
/// When the mix percentage (mix time / mix duration) is less than the attachment threshold, attachment timelines for the
|
|
||||||
/// animation being mixed out will be applied. Defaults to 0, so attachment timelines are not applied for an animation being
|
|
||||||
/// mixed out.
|
|
||||||
float getAttachmentThreshold();
|
|
||||||
void setAttachmentThreshold(float inValue);
|
|
||||||
|
|
||||||
///
|
|
||||||
/// When the mix percentage (mix time / mix duration) is less than the draw order threshold, draw order timelines for the
|
|
||||||
/// animation being mixed out will be applied. Defaults to 0, so draw order timelines are not applied for an animation being
|
|
||||||
/// mixed out.
|
|
||||||
///
|
|
||||||
float getDrawOrderThreshold();
|
|
||||||
void setDrawOrderThreshold(float inValue);
|
|
||||||
|
|
||||||
///
|
|
||||||
/// The animation queued to start after this animation, or NULL.
|
|
||||||
TrackEntry* getNext();
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Returns true if at least one loop has been completed.
|
|
||||||
bool isComplete();
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Seconds from 0 to the mix duration when mixing from the previous animation to this animation. May be slightly more than
|
|
||||||
/// TrackEntry.MixDuration when the mix is complete.
|
|
||||||
float getMixTime();
|
|
||||||
void setMixTime(float inValue);
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Seconds for mixing from the previous animation to this animation. Defaults to the value provided by
|
|
||||||
/// AnimationStateData based on the animation before this animation (if any).
|
|
||||||
///
|
|
||||||
/// The mix duration can be set manually rather than use the value from AnimationStateData.GetMix.
|
|
||||||
/// In that case, the mixDuration must be set before AnimationState.update(float) is next called.
|
|
||||||
///
|
|
||||||
/// When using AnimationState::addAnimation(int, Animation, bool, float) with a delay
|
|
||||||
/// less than or equal to 0, note the Delay is set using the mix duration from the AnimationStateData
|
|
||||||
///
|
|
||||||
///
|
|
||||||
///
|
|
||||||
float getMixDuration();
|
|
||||||
void setMixDuration(float inValue);
|
|
||||||
|
|
||||||
|
virtual ~TrackEntry();
|
||||||
|
|
||||||
MixBlend getMixBlend();
|
/// The index of the track where this entry is either current or queued.
|
||||||
void setMixBlend(MixBlend blend);
|
int getTrackIndex();
|
||||||
|
|
||||||
///
|
|
||||||
/// The track entry for the previous animation when mixing from the previous animation to this animation, or NULL if no
|
|
||||||
/// mixing is currently occuring. When mixing from multiple animations, MixingFrom makes up a double linked list with MixingTo.
|
|
||||||
TrackEntry* getMixingFrom();
|
|
||||||
|
|
||||||
///
|
/// The animation to apply for this track entry.
|
||||||
/// The track entry for the next animation when mixing from this animation, or NULL if no mixing is currently occuring.
|
Animation* getAnimation();
|
||||||
/// When mixing from multiple animations, MixingTo makes up a double linked list with MixingFrom.
|
|
||||||
TrackEntry* getMixingTo();
|
/// If true, the animation will repeat. If false, it will not, instead its last frame is applied if played beyond its duration.
|
||||||
|
bool getLoop();
|
||||||
///
|
void setLoop(bool inValue);
|
||||||
/// Resets the rotation directions for mixing this entry's rotate timelines. This can be useful to avoid bones rotating the
|
|
||||||
/// long way around when using alpha and starting animations on other tracks.
|
/// If true, when mixing from the previous animation to this animation, the previous animation is applied as normal instead
|
||||||
///
|
/// of being mixed out.
|
||||||
/// Mixing involves finding a rotation between two others, which has two possible solutions: the short way or the long way around.
|
///
|
||||||
/// The two rotations likely change over time, so which direction is the short or long way also changes.
|
/// When mixing between animations that key the same property, if a lower track also keys that property then the value will
|
||||||
/// If the short way was always chosen, bones would flip to the other side when that direction became the long way.
|
/// briefly dip toward the lower track value during the mix. This happens because the first animation mixes from 100% to 0%
|
||||||
/// TrackEntry chooses the short way the first time it is applied and remembers that direction.
|
/// while the second animation mixes from 0% to 100%. Setting holdPrevious to true applies the first animation
|
||||||
void resetRotationDirections();
|
/// at 100% during the mix so the lower track value is overwritten. Such dipping does not occur on the lowest track which
|
||||||
|
/// keys the property, only when a higher track also keys the property.
|
||||||
void setListener(AnimationStateListener listener);
|
///
|
||||||
|
/// Snapping will occur if holdPrevious is true and this animation does not key all the same properties as the
|
||||||
|
/// previous animation.
|
||||||
|
bool getHoldPrevious();
|
||||||
|
void setHoldPrevious(bool inValue);
|
||||||
|
|
||||||
|
/// Seconds to postpone playing the animation. When a track entry is the current track entry, delay postpones incrementing
|
||||||
|
/// the track time. When a track entry is queued, delay is the time from the start of the previous animation to when the
|
||||||
|
/// track entry will become the current track entry.
|
||||||
|
float getDelay();
|
||||||
|
void setDelay(float inValue);
|
||||||
|
|
||||||
|
/// Current time in seconds this track entry has been the current track entry. The track time determines
|
||||||
|
/// TrackEntry.AnimationTime. The track time can be set to start the animation at a time other than 0, without affecting looping.
|
||||||
|
float getTrackTime();
|
||||||
|
void setTrackTime(float inValue);
|
||||||
|
|
||||||
|
/// The track time in seconds when this animation will be removed from the track. Defaults to the animation duration for
|
||||||
|
/// non-looping animations and to int.MaxValue for looping animations. If the track end time is reached and no
|
||||||
|
/// other animations are queued for playback, and mixing from any previous animations is complete, properties keyed by the animation,
|
||||||
|
/// are set to the setup pose and the track is cleared.
|
||||||
|
///
|
||||||
|
/// It may be desired to use AnimationState.addEmptyAnimation(int, float, float) to mix the properties back to the
|
||||||
|
/// setup pose over time, rather than have it happen instantly.
|
||||||
|
float getTrackEnd();
|
||||||
|
void setTrackEnd(float inValue);
|
||||||
|
|
||||||
|
/// Seconds when this animation starts, both initially and after looping. Defaults to 0.
|
||||||
|
///
|
||||||
|
/// When changing the animation start time, it often makes sense to set TrackEntry.AnimationLast to the same value to
|
||||||
|
/// prevent timeline keys before the start time from triggering.
|
||||||
|
float getAnimationStart();
|
||||||
|
void setAnimationStart(float inValue);
|
||||||
|
|
||||||
|
/// Seconds for the last frame of this animation. Non-looping animations won't play past this time. Looping animations will
|
||||||
|
/// loop back to TrackEntry.AnimationStart at this time. Defaults to the animation duration.
|
||||||
|
float getAnimationEnd();
|
||||||
|
void setAnimationEnd(float inValue);
|
||||||
|
|
||||||
|
/// The time in seconds this animation was last applied. Some timelines use this for one-time triggers. Eg, when this
|
||||||
|
/// animation is applied, event timelines will fire all events between the animation last time (exclusive) and animation time
|
||||||
|
/// (inclusive). Defaults to -1 to ensure triggers on frame 0 happen the first time this animation is applied.
|
||||||
|
float getAnimationLast();
|
||||||
|
void setAnimationLast(float inValue);
|
||||||
|
|
||||||
|
/// Uses TrackEntry.TrackTime to compute the animation time between TrackEntry.AnimationStart. and
|
||||||
|
/// TrackEntry.AnimationEnd. When the track time is 0, the animation time is equal to the animation start time.
|
||||||
|
float getAnimationTime();
|
||||||
|
|
||||||
|
/// Multiplier for the delta time when the animation state is updated, causing time for this animation to play slower or
|
||||||
|
/// faster. Defaults to 1.
|
||||||
|
float getTimeScale();
|
||||||
|
void setTimeScale(float inValue);
|
||||||
|
|
||||||
|
/// Values less than 1 mix this animation with the last skeleton pose. Defaults to 1, which overwrites the last skeleton pose with
|
||||||
|
/// this animation.
|
||||||
|
///
|
||||||
|
/// Typically track 0 is used to completely pose the skeleton, then alpha can be used on higher tracks. It doesn't make sense
|
||||||
|
/// to use alpha on track 0 if the skeleton pose is from the last frame render.
|
||||||
|
float getAlpha();
|
||||||
|
void setAlpha(float inValue);
|
||||||
|
|
||||||
|
///
|
||||||
|
/// When the mix percentage (mix time / mix duration) is less than the event threshold, event timelines for the animation
|
||||||
|
/// being mixed out will be applied. Defaults to 0, so event timelines are not applied for an animation being mixed out.
|
||||||
|
float getEventThreshold();
|
||||||
|
void setEventThreshold(float inValue);
|
||||||
|
|
||||||
|
/// When the mix percentage (mix time / mix duration) is less than the attachment threshold, attachment timelines for the
|
||||||
|
/// animation being mixed out will be applied. Defaults to 0, so attachment timelines are not applied for an animation being
|
||||||
|
/// mixed out.
|
||||||
|
float getAttachmentThreshold();
|
||||||
|
void setAttachmentThreshold(float inValue);
|
||||||
|
|
||||||
|
/// When the mix percentage (mix time / mix duration) is less than the draw order threshold, draw order timelines for the
|
||||||
|
/// animation being mixed out will be applied. Defaults to 0, so draw order timelines are not applied for an animation being
|
||||||
|
/// mixed out.
|
||||||
|
float getDrawOrderThreshold();
|
||||||
|
void setDrawOrderThreshold(float inValue);
|
||||||
|
|
||||||
|
/// The animation queued to start after this animation, or NULL.
|
||||||
|
TrackEntry* getNext();
|
||||||
|
|
||||||
|
/// Returns true if at least one loop has been completed.
|
||||||
|
bool isComplete();
|
||||||
|
|
||||||
|
/// Seconds from 0 to the mix duration when mixing from the previous animation to this animation. May be slightly more than
|
||||||
|
/// TrackEntry.MixDuration when the mix is complete.
|
||||||
|
float getMixTime();
|
||||||
|
void setMixTime(float inValue);
|
||||||
|
|
||||||
|
/// Seconds for mixing from the previous animation to this animation. Defaults to the value provided by
|
||||||
|
/// AnimationStateData based on the animation before this animation (if any).
|
||||||
|
///
|
||||||
|
/// The mix duration can be set manually rather than use the value from AnimationStateData.GetMix.
|
||||||
|
/// In that case, the mixDuration must be set before AnimationState.update(float) is next called.
|
||||||
|
///
|
||||||
|
/// When using AnimationState::addAnimation(int, Animation, bool, float) with a delay
|
||||||
|
/// less than or equal to 0, note the Delay is set using the mix duration from the AnimationStateData
|
||||||
|
float getMixDuration();
|
||||||
|
void setMixDuration(float inValue);
|
||||||
|
|
||||||
|
MixBlend getMixBlend();
|
||||||
|
void setMixBlend(MixBlend blend);
|
||||||
|
|
||||||
|
/// The track entry for the previous animation when mixing from the previous animation to this animation, or NULL if no
|
||||||
|
/// mixing is currently occuring. When mixing from multiple animations, MixingFrom makes up a double linked list with MixingTo.
|
||||||
|
TrackEntry* getMixingFrom();
|
||||||
|
|
||||||
|
/// The track entry for the next animation when mixing from this animation, or NULL if no mixing is currently occuring.
|
||||||
|
/// When mixing from multiple animations, MixingTo makes up a double linked list with MixingFrom.
|
||||||
|
TrackEntry* getMixingTo();
|
||||||
|
|
||||||
|
/// Resets the rotation directions for mixing this entry's rotate timelines. This can be useful to avoid bones rotating the
|
||||||
|
/// long way around when using alpha and starting animations on other tracks.
|
||||||
|
///
|
||||||
|
/// Mixing involves finding a rotation between two others, which has two possible solutions: the short way or the long way around.
|
||||||
|
/// The two rotations likely change over time, so which direction is the short or long way also changes.
|
||||||
|
/// If the short way was always chosen, bones would flip to the other side when that direction became the long way.
|
||||||
|
/// TrackEntry chooses the short way the first time it is applied and remembers that direction.
|
||||||
|
void resetRotationDirections();
|
||||||
|
|
||||||
|
void setListener(AnimationStateListener listener);
|
||||||
|
|
||||||
void setListener(AnimationStateListenerObject* listener);
|
void setListener(AnimationStateListenerObject* listener);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Animation* _animation;
|
Animation* _animation;
|
||||||
|
|
||||||
TrackEntry* _next;
|
|
||||||
TrackEntry* _mixingFrom;
|
|
||||||
TrackEntry* _mixingTo;
|
|
||||||
int _trackIndex;
|
|
||||||
|
|
||||||
bool _loop, _holdPrevious;
|
TrackEntry* _next;
|
||||||
float _eventThreshold, _attachmentThreshold, _drawOrderThreshold;
|
TrackEntry* _mixingFrom;
|
||||||
float _animationStart, _animationEnd, _animationLast, _nextAnimationLast;
|
TrackEntry* _mixingTo;
|
||||||
float _delay, _trackTime, _trackLast, _nextTrackLast, _trackEnd, _timeScale;
|
int _trackIndex;
|
||||||
float _alpha, _mixTime, _mixDuration, _interruptAlpha, _totalAlpha;
|
|
||||||
MixBlend _mixBlend;
|
bool _loop, _holdPrevious;
|
||||||
Vector<int> _timelineMode;
|
float _eventThreshold, _attachmentThreshold, _drawOrderThreshold;
|
||||||
Vector<TrackEntry*> _timelineHoldMix;
|
float _animationStart, _animationEnd, _animationLast, _nextAnimationLast;
|
||||||
Vector<float> _timelinesRotation;
|
float _delay, _trackTime, _trackLast, _nextTrackLast, _trackEnd, _timeScale;
|
||||||
AnimationStateListener _listener;
|
float _alpha, _mixTime, _mixDuration, _interruptAlpha, _totalAlpha;
|
||||||
|
MixBlend _mixBlend;
|
||||||
|
Vector<int> _timelineMode;
|
||||||
|
Vector<TrackEntry*> _timelineHoldMix;
|
||||||
|
Vector<float> _timelinesRotation;
|
||||||
|
AnimationStateListener _listener;
|
||||||
AnimationStateListenerObject* _listenerObject;
|
AnimationStateListenerObject* _listenerObject;
|
||||||
|
|
||||||
void reset();
|
|
||||||
};
|
|
||||||
|
|
||||||
class SP_API EventQueueEntry : public SpineObject {
|
|
||||||
friend class EventQueue;
|
|
||||||
|
|
||||||
public:
|
|
||||||
EventType _type;
|
|
||||||
TrackEntry* _entry;
|
|
||||||
Event* _event;
|
|
||||||
|
|
||||||
EventQueueEntry(EventType eventType, TrackEntry* trackEntry, Event* event = NULL);
|
|
||||||
};
|
|
||||||
|
|
||||||
class SP_API EventQueue : public SpineObject {
|
|
||||||
friend class AnimationState;
|
|
||||||
|
|
||||||
private:
|
|
||||||
Vector<EventQueueEntry> _eventQueueEntries;
|
|
||||||
AnimationState& _state;
|
|
||||||
Pool<TrackEntry>& _trackEntryPool;
|
|
||||||
bool _drainDisabled;
|
|
||||||
|
|
||||||
static EventQueue* newEventQueue(AnimationState& state, Pool<TrackEntry>& trackEntryPool);
|
|
||||||
|
|
||||||
static EventQueueEntry newEventQueueEntry(EventType eventType, TrackEntry* entry, Event* event = NULL);
|
void reset();
|
||||||
|
};
|
||||||
EventQueue(AnimationState& state, Pool<TrackEntry>& trackEntryPool);
|
|
||||||
|
|
||||||
~EventQueue();
|
|
||||||
|
|
||||||
void start(TrackEntry* entry);
|
|
||||||
|
|
||||||
void interrupt(TrackEntry* entry);
|
class SP_API EventQueueEntry : public SpineObject {
|
||||||
|
friend class EventQueue;
|
||||||
|
|
||||||
void end(TrackEntry* entry);
|
public:
|
||||||
|
EventType _type;
|
||||||
|
TrackEntry* _entry;
|
||||||
|
Event* _event;
|
||||||
|
|
||||||
void dispose(TrackEntry* entry);
|
EventQueueEntry(EventType eventType, TrackEntry* trackEntry, Event* event = NULL);
|
||||||
|
};
|
||||||
|
|
||||||
void complete(TrackEntry* entry);
|
class SP_API EventQueue : public SpineObject {
|
||||||
|
friend class AnimationState;
|
||||||
|
|
||||||
void event(TrackEntry* entry, Event* event);
|
private:
|
||||||
|
Vector<EventQueueEntry> _eventQueueEntries;
|
||||||
|
AnimationState& _state;
|
||||||
|
Pool<TrackEntry>& _trackEntryPool;
|
||||||
|
bool _drainDisabled;
|
||||||
|
|
||||||
/// Raises all events in the queue and drains the queue.
|
static EventQueue* newEventQueue(AnimationState& state, Pool<TrackEntry>& trackEntryPool);
|
||||||
void drain();
|
|
||||||
};
|
|
||||||
|
|
||||||
class SP_API AnimationState : public SpineObject, public HasRendererObject {
|
|
||||||
friend class TrackEntry;
|
|
||||||
friend class EventQueue;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit AnimationState(AnimationStateData* data);
|
|
||||||
|
|
||||||
~AnimationState();
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Increments the track entry times, setting queued animations as current if needed
|
|
||||||
/// @param delta delta time
|
|
||||||
void update(float delta);
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Poses the skeleton using the track entry animations. There are no side effects other than invoking listeners, so the
|
|
||||||
/// animation state can be applied to multiple skeletons to pose them identically.
|
|
||||||
bool apply(Skeleton& skeleton);
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Removes all animations from all tracks, leaving skeletons in their previous pose.
|
|
||||||
/// It may be desired to use AnimationState.setEmptyAnimations(float) to mix the skeletons back to the setup pose,
|
|
||||||
/// rather than leaving them in their previous pose.
|
|
||||||
void clearTracks();
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Removes all animations from the tracks, leaving skeletons in their previous pose.
|
|
||||||
/// It may be desired to use AnimationState.setEmptyAnimations(float) to mix the skeletons back to the setup pose,
|
|
||||||
/// rather than leaving them in their previous pose.
|
|
||||||
void clearTrack(size_t trackIndex);
|
|
||||||
|
|
||||||
/// Sets an animation by name. setAnimation(int, Animation, bool)
|
|
||||||
TrackEntry* setAnimation(size_t trackIndex, const String& animationName, bool loop);
|
|
||||||
|
|
||||||
/// Sets the current animation for a track, discarding any queued animations.
|
|
||||||
/// @param loop If true, the animation will repeat.
|
|
||||||
/// If false, it will not, instead its last frame is applied if played beyond its duration.
|
|
||||||
/// In either case TrackEntry.TrackEnd determines when the track is cleared.
|
|
||||||
/// @return
|
|
||||||
/// A track entry to allow further customization of animation playback. References to the track entry must not be kept
|
|
||||||
/// after AnimationState.Dispose.
|
|
||||||
TrackEntry* setAnimation(size_t trackIndex, Animation* animation, bool loop);
|
|
||||||
|
|
||||||
/// Queues an animation by name.
|
|
||||||
/// addAnimation(int, Animation, bool, float)
|
|
||||||
TrackEntry* addAnimation(size_t trackIndex, const String& animationName, bool loop, float delay);
|
|
||||||
|
|
||||||
/// Adds an animation to be played delay seconds after the current or last queued animation
|
|
||||||
/// for a track. If the track is empty, it is equivalent to calling setAnimation.
|
|
||||||
/// @param delay
|
|
||||||
/// Seconds to begin this animation after the start of the previous animation. May be <= 0 to use the animation
|
|
||||||
/// duration of the previous track minus any mix duration plus the negative delay.
|
|
||||||
///
|
|
||||||
/// @return A track entry to allow further customization of animation playback. References to the track entry must not be kept
|
|
||||||
/// after AnimationState.Dispose
|
|
||||||
TrackEntry* addAnimation(size_t trackIndex, Animation* animation, bool loop, float delay);
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Sets an empty animation for a track, discarding any queued animations, and mixes to it over the specified mix duration.
|
|
||||||
TrackEntry* setEmptyAnimation(size_t trackIndex, float mixDuration);
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Adds an empty animation to be played after the current or last queued animation for a track, and mixes to it over the
|
|
||||||
/// specified mix duration.
|
|
||||||
/// @return
|
|
||||||
/// A track entry to allow further customization of animation playback. References to the track entry must not be kept after AnimationState.Dispose.
|
|
||||||
///
|
|
||||||
/// @param trackIndex Track number.
|
|
||||||
/// @param mixDuration Mix duration.
|
|
||||||
/// @param delay Seconds to begin this animation after the start of the previous animation. May be <= 0 to use the animation
|
|
||||||
/// duration of the previous track minus any mix duration plus the negative delay.
|
|
||||||
TrackEntry* addEmptyAnimation(size_t trackIndex, float mixDuration, float delay);
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Sets an empty animation for every track, discarding any queued animations, and mixes to it over the specified mix duration.
|
|
||||||
void setEmptyAnimations(float mixDuration);
|
|
||||||
|
|
||||||
/// @return The track entry for the animation currently playing on the track, or NULL if no animation is currently playing.
|
|
||||||
TrackEntry* getCurrent(size_t trackIndex);
|
|
||||||
|
|
||||||
AnimationStateData* getData();
|
|
||||||
|
|
||||||
/// A list of tracks that have animations, which may contain NULLs.
|
|
||||||
Vector<TrackEntry*> &getTracks();
|
|
||||||
|
|
||||||
float getTimeScale();
|
static EventQueueEntry newEventQueueEntry(EventType eventType, TrackEntry* entry, Event* event = NULL);
|
||||||
void setTimeScale(float inValue);
|
|
||||||
|
|
||||||
void setListener(AnimationStateListener listener);
|
EventQueue(AnimationState& state, Pool<TrackEntry>& trackEntryPool);
|
||||||
|
|
||||||
|
~EventQueue();
|
||||||
|
|
||||||
|
void start(TrackEntry* entry);
|
||||||
|
|
||||||
|
void interrupt(TrackEntry* entry);
|
||||||
|
|
||||||
|
void end(TrackEntry* entry);
|
||||||
|
|
||||||
|
void dispose(TrackEntry* entry);
|
||||||
|
|
||||||
|
void complete(TrackEntry* entry);
|
||||||
|
|
||||||
|
void event(TrackEntry* entry, Event* event);
|
||||||
|
|
||||||
|
/// Raises all events in the queue and drains the queue.
|
||||||
|
void drain();
|
||||||
|
};
|
||||||
|
|
||||||
|
class SP_API AnimationState : public SpineObject, public HasRendererObject {
|
||||||
|
friend class TrackEntry;
|
||||||
|
friend class EventQueue;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit AnimationState(AnimationStateData* data);
|
||||||
|
|
||||||
|
~AnimationState();
|
||||||
|
|
||||||
|
/// Increments the track entry times, setting queued animations as current if needed
|
||||||
|
/// @param delta delta time
|
||||||
|
void update(float delta);
|
||||||
|
|
||||||
|
/// Poses the skeleton using the track entry animations. There are no side effects other than invoking listeners, so the
|
||||||
|
/// animation state can be applied to multiple skeletons to pose them identically.
|
||||||
|
bool apply(Skeleton& skeleton);
|
||||||
|
|
||||||
|
/// Removes all animations from all tracks, leaving skeletons in their previous pose.
|
||||||
|
/// It may be desired to use AnimationState.setEmptyAnimations(float) to mix the skeletons back to the setup pose,
|
||||||
|
/// rather than leaving them in their previous pose.
|
||||||
|
void clearTracks();
|
||||||
|
|
||||||
|
/// Removes all animations from the tracks, leaving skeletons in their previous pose.
|
||||||
|
/// It may be desired to use AnimationState.setEmptyAnimations(float) to mix the skeletons back to the setup pose,
|
||||||
|
/// rather than leaving them in their previous pose.
|
||||||
|
void clearTrack(size_t trackIndex);
|
||||||
|
|
||||||
|
/// Sets an animation by name. setAnimation(int, Animation, bool)
|
||||||
|
TrackEntry* setAnimation(size_t trackIndex, const String& animationName, bool loop);
|
||||||
|
|
||||||
|
/// Sets the current animation for a track, discarding any queued animations.
|
||||||
|
/// @param loop If true, the animation will repeat.
|
||||||
|
/// If false, it will not, instead its last frame is applied if played beyond its duration.
|
||||||
|
/// In either case TrackEntry.TrackEnd determines when the track is cleared.
|
||||||
|
/// @return
|
||||||
|
/// A track entry to allow further customization of animation playback. References to the track entry must not be kept
|
||||||
|
/// after AnimationState.Dispose.
|
||||||
|
TrackEntry* setAnimation(size_t trackIndex, Animation* animation, bool loop);
|
||||||
|
|
||||||
|
/// Queues an animation by name.
|
||||||
|
/// addAnimation(int, Animation, bool, float)
|
||||||
|
TrackEntry* addAnimation(size_t trackIndex, const String& animationName, bool loop, float delay);
|
||||||
|
|
||||||
|
/// Adds an animation to be played delay seconds after the current or last queued animation
|
||||||
|
/// for a track. If the track is empty, it is equivalent to calling setAnimation.
|
||||||
|
/// @param delay
|
||||||
|
/// Seconds to begin this animation after the start of the previous animation. May be <= 0 to use the animation
|
||||||
|
/// duration of the previous track minus any mix duration plus the negative delay.
|
||||||
|
///
|
||||||
|
/// @return A track entry to allow further customization of animation playback. References to the track entry must not be kept
|
||||||
|
/// after AnimationState.Dispose
|
||||||
|
TrackEntry* addAnimation(size_t trackIndex, Animation* animation, bool loop, float delay);
|
||||||
|
|
||||||
|
/// Sets an empty animation for a track, discarding any queued animations, and mixes to it over the specified mix duration.
|
||||||
|
TrackEntry* setEmptyAnimation(size_t trackIndex, float mixDuration);
|
||||||
|
|
||||||
|
/// Adds an empty animation to be played after the current or last queued animation for a track, and mixes to it over the
|
||||||
|
/// specified mix duration.
|
||||||
|
/// @return
|
||||||
|
/// A track entry to allow further customization of animation playback. References to the track entry must not be kept after AnimationState.Dispose.
|
||||||
|
///
|
||||||
|
/// @param trackIndex Track number.
|
||||||
|
/// @param mixDuration Mix duration.
|
||||||
|
/// @param delay Seconds to begin this animation after the start of the previous animation. May be <= 0 to use the animation
|
||||||
|
/// duration of the previous track minus any mix duration plus the negative delay.
|
||||||
|
TrackEntry* addEmptyAnimation(size_t trackIndex, float mixDuration, float delay);
|
||||||
|
|
||||||
|
/// Sets an empty animation for every track, discarding any queued animations, and mixes to it over the specified mix duration.
|
||||||
|
void setEmptyAnimations(float mixDuration);
|
||||||
|
|
||||||
|
/// @return The track entry for the animation currently playing on the track, or NULL if no animation is currently playing.
|
||||||
|
TrackEntry* getCurrent(size_t trackIndex);
|
||||||
|
|
||||||
|
AnimationStateData* getData();
|
||||||
|
|
||||||
|
/// A list of tracks that have animations, which may contain NULLs.
|
||||||
|
Vector<TrackEntry*> &getTracks();
|
||||||
|
|
||||||
|
float getTimeScale();
|
||||||
|
void setTimeScale(float inValue);
|
||||||
|
|
||||||
|
void setListener(AnimationStateListener listener);
|
||||||
void setListener(AnimationStateListenerObject* listener);
|
void setListener(AnimationStateListenerObject* listener);
|
||||||
|
|
||||||
void disableQueue();
|
void disableQueue();
|
||||||
void enableQueue();
|
void enableQueue();
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
AnimationStateData* _data;
|
|
||||||
|
|
||||||
Pool<TrackEntry> _trackEntryPool;
|
private:
|
||||||
Vector<TrackEntry*> _tracks;
|
|
||||||
Vector<Event*> _events;
|
|
||||||
EventQueue* _queue;
|
|
||||||
|
|
||||||
Vector<int> _propertyIDs;
|
AnimationStateData* _data;
|
||||||
bool _animationsChanged;
|
|
||||||
|
|
||||||
AnimationStateListener _listener;
|
Pool<TrackEntry> _trackEntryPool;
|
||||||
|
Vector<TrackEntry*> _tracks;
|
||||||
|
Vector<Event*> _events;
|
||||||
|
EventQueue* _queue;
|
||||||
|
|
||||||
|
Vector<int> _propertyIDs;
|
||||||
|
bool _animationsChanged;
|
||||||
|
|
||||||
|
AnimationStateListener _listener;
|
||||||
AnimationStateListenerObject* _listenerObject;
|
AnimationStateListenerObject* _listenerObject;
|
||||||
|
|
||||||
float _timeScale;
|
|
||||||
|
|
||||||
static Animation* getEmptyAnimation();
|
float _timeScale;
|
||||||
|
|
||||||
static void applyRotateTimeline(RotateTimeline* rotateTimeline, Skeleton& skeleton, float time, float alpha, MixBlend pose, Vector<float>& timelinesRotation, size_t i, bool firstFrame);
|
|
||||||
|
|
||||||
/// Returns true when all mixing from entries are complete.
|
|
||||||
bool updateMixingFrom(TrackEntry* to, float delta);
|
|
||||||
|
|
||||||
float applyMixingFrom(TrackEntry* to, Skeleton& skeleton, MixBlend currentPose);
|
|
||||||
|
|
||||||
void queueEvents(TrackEntry* entry, float animationTime);
|
|
||||||
|
|
||||||
/// Sets the active TrackEntry for a given track number.
|
|
||||||
void setCurrent(size_t index, TrackEntry *current, bool interrupt);
|
|
||||||
|
|
||||||
TrackEntry* expandToIndex(size_t index);
|
static Animation* getEmptyAnimation();
|
||||||
|
|
||||||
/// Object-pooling version of new TrackEntry. Obtain an unused TrackEntry from the pool and clear/initialize its values.
|
static void applyRotateTimeline(RotateTimeline* rotateTimeline, Skeleton& skeleton, float time, float alpha, MixBlend pose, Vector<float>& timelinesRotation, size_t i, bool firstFrame);
|
||||||
/// @param last May be NULL.
|
|
||||||
TrackEntry* newTrackEntry(size_t trackIndex, Animation *animation, bool loop, TrackEntry *last);
|
|
||||||
|
|
||||||
/// Dispose all track entries queued after the given TrackEntry.
|
/// Returns true when all mixing from entries are complete.
|
||||||
void disposeNext(TrackEntry* entry);
|
bool updateMixingFrom(TrackEntry* to, float delta);
|
||||||
|
|
||||||
void animationsChanged();
|
float applyMixingFrom(TrackEntry* to, Skeleton& skeleton, MixBlend currentPose);
|
||||||
|
|
||||||
void computeHold(TrackEntry *entry);
|
void queueEvents(TrackEntry* entry, float animationTime);
|
||||||
|
|
||||||
void computeNotLast(TrackEntry *entry);
|
/// Sets the active TrackEntry for a given track number.
|
||||||
|
void setCurrent(size_t index, TrackEntry *current, bool interrupt);
|
||||||
|
|
||||||
bool hasTimeline(TrackEntry *entry, int inId);
|
TrackEntry* expandToIndex(size_t index);
|
||||||
};
|
|
||||||
|
/// Object-pooling version of new TrackEntry. Obtain an unused TrackEntry from the pool and clear/initialize its values.
|
||||||
|
/// @param last May be NULL.
|
||||||
|
TrackEntry* newTrackEntry(size_t trackIndex, Animation *animation, bool loop, TrackEntry *last);
|
||||||
|
|
||||||
|
/// Dispose all track entries queued after the given TrackEntry.
|
||||||
|
void disposeNext(TrackEntry* entry);
|
||||||
|
|
||||||
|
void animationsChanged();
|
||||||
|
|
||||||
|
void computeHold(TrackEntry *entry);
|
||||||
|
|
||||||
|
void computeNotLast(TrackEntry *entry);
|
||||||
|
|
||||||
|
bool hasTimeline(TrackEntry *entry, int inId);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_AnimationState_h */
|
#endif /* Spine_AnimationState_h */
|
||||||
|
|||||||
@ -37,51 +37,49 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
class SkeletonData;
|
class SkeletonData;
|
||||||
class Animation;
|
class Animation;
|
||||||
|
|
||||||
/// Stores mix (crossfade) durations to be applied when AnimationState animations are changed.
|
/// Stores mix (crossfade) durations to be applied when AnimationState animations are changed.
|
||||||
class SP_API AnimationStateData : public SpineObject {
|
class SP_API AnimationStateData : public SpineObject {
|
||||||
friend class AnimationState;
|
friend class AnimationState;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit AnimationStateData(SkeletonData* skeletonData);
|
explicit AnimationStateData(SkeletonData* skeletonData);
|
||||||
|
|
||||||
/// The SkeletonData to look up animations when they are specified by name.
|
|
||||||
SkeletonData* getSkeletonData();
|
|
||||||
|
|
||||||
/// The mix duration to use when no mix duration has been specifically defined between two animations.
|
|
||||||
float getDefaultMix();
|
|
||||||
void setDefaultMix(float inValue);
|
|
||||||
|
|
||||||
/// Sets a mix duration by animation names.
|
|
||||||
void setMix(const String& fromName, const String& toName, float duration);
|
|
||||||
|
|
||||||
/// Sets a mix duration when changing from the specified animation to the other.
|
|
||||||
/// See TrackEntry.MixDuration.
|
|
||||||
void setMix(Animation* from, Animation* to, float duration);
|
|
||||||
|
|
||||||
///
|
|
||||||
/// The mix duration to use when changing from the specified animation to the other,
|
|
||||||
/// or the DefaultMix if no mix duration has been set.
|
|
||||||
///
|
|
||||||
float getMix(Animation* from, Animation* to);
|
|
||||||
|
|
||||||
private:
|
/// The SkeletonData to look up animations when they are specified by name.
|
||||||
class AnimationPair : public SpineObject {
|
SkeletonData* getSkeletonData();
|
||||||
public:
|
|
||||||
Animation* _a1;
|
|
||||||
Animation* _a2;
|
|
||||||
|
|
||||||
explicit AnimationPair(Animation* a1 = NULL, Animation* a2 = NULL);
|
/// The mix duration to use when no mix duration has been specifically defined between two animations.
|
||||||
|
float getDefaultMix();
|
||||||
bool operator==(const AnimationPair &other) const;
|
void setDefaultMix(float inValue);
|
||||||
};
|
|
||||||
|
/// Sets a mix duration by animation names.
|
||||||
SkeletonData* _skeletonData;
|
void setMix(const String& fromName, const String& toName, float duration);
|
||||||
float _defaultMix;
|
|
||||||
HashMap<AnimationPair, float> _animationToMixTime;
|
/// Sets a mix duration when changing from the specified animation to the other.
|
||||||
};
|
/// See TrackEntry.MixDuration.
|
||||||
|
void setMix(Animation* from, Animation* to, float duration);
|
||||||
|
|
||||||
|
/// The mix duration to use when changing from the specified animation to the other,
|
||||||
|
/// or the DefaultMix if no mix duration has been set.
|
||||||
|
float getMix(Animation* from, Animation* to);
|
||||||
|
|
||||||
|
private:
|
||||||
|
class AnimationPair : public SpineObject {
|
||||||
|
public:
|
||||||
|
Animation* _a1;
|
||||||
|
Animation* _a2;
|
||||||
|
|
||||||
|
explicit AnimationPair(Animation* a1 = NULL, Animation* a2 = NULL);
|
||||||
|
|
||||||
|
bool operator==(const AnimationPair &other) const;
|
||||||
|
};
|
||||||
|
|
||||||
|
SkeletonData* _skeletonData;
|
||||||
|
float _defaultMix;
|
||||||
|
HashMap<AnimationPair, float> _animationToMixTime;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_AnimationStateData_h */
|
#endif /* Spine_AnimationStateData_h */
|
||||||
|
|||||||
@ -76,8 +76,8 @@ public:
|
|||||||
int width, height;
|
int width, height;
|
||||||
|
|
||||||
explicit AtlasPage(const String &inName) : name(inName), format(Format_RGBA8888), minFilter(TextureFilter_Nearest),
|
explicit AtlasPage(const String &inName) : name(inName), format(Format_RGBA8888), minFilter(TextureFilter_Nearest),
|
||||||
magFilter(TextureFilter_Nearest), uWrap(TextureWrap_ClampToEdge),
|
magFilter(TextureFilter_Nearest), uWrap(TextureWrap_ClampToEdge),
|
||||||
vWrap(TextureWrap_ClampToEdge), width(0), height(0) {
|
vWrap(TextureWrap_ClampToEdge), width(0), height(0) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -36,38 +36,36 @@
|
|||||||
|
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
class Atlas;
|
class Atlas;
|
||||||
class AtlasRegion;
|
class AtlasRegion;
|
||||||
|
|
||||||
///
|
/// An AttachmentLoader that configures attachments using texture regions from an Atlas.
|
||||||
/// An AttachmentLoader that configures attachments using texture regions from an Atlas.
|
/// See http://esotericsoftware.com/spine-loading-skeleton-data#JSON-and-binary-data about Loading Skeleton Data in the Spine Runtimes Guide.
|
||||||
/// See http://esotericsoftware.com/spine-loading-skeleton-data#JSON-and-binary-data about Loading Skeleton Data in the Spine Runtimes Guide.
|
|
||||||
///
|
|
||||||
class SP_API AtlasAttachmentLoader : public AttachmentLoader {
|
class SP_API AtlasAttachmentLoader : public AttachmentLoader {
|
||||||
public:
|
public:
|
||||||
RTTI_DECL
|
RTTI_DECL
|
||||||
|
|
||||||
explicit AtlasAttachmentLoader(Atlas* atlas);
|
explicit AtlasAttachmentLoader(Atlas* atlas);
|
||||||
|
|
||||||
virtual RegionAttachment* newRegionAttachment(Skin& skin, const String& name, const String& path);
|
virtual RegionAttachment* newRegionAttachment(Skin& skin, const String& name, const String& path);
|
||||||
|
|
||||||
virtual MeshAttachment* newMeshAttachment(Skin& skin, const String& name, const String& path);
|
virtual MeshAttachment* newMeshAttachment(Skin& skin, const String& name, const String& path);
|
||||||
|
|
||||||
virtual BoundingBoxAttachment* newBoundingBoxAttachment(Skin& skin, const String& name);
|
virtual BoundingBoxAttachment* newBoundingBoxAttachment(Skin& skin, const String& name);
|
||||||
|
|
||||||
virtual PathAttachment* newPathAttachment(Skin& skin, const String& name);
|
virtual PathAttachment* newPathAttachment(Skin& skin, const String& name);
|
||||||
|
|
||||||
virtual PointAttachment* newPointAttachment(Skin& skin, const String& name);
|
virtual PointAttachment* newPointAttachment(Skin& skin, const String& name);
|
||||||
|
|
||||||
virtual ClippingAttachment* newClippingAttachment(Skin& skin, const String& name);
|
virtual ClippingAttachment* newClippingAttachment(Skin& skin, const String& name);
|
||||||
|
|
||||||
virtual void configureAttachment(Attachment* attachment);
|
virtual void configureAttachment(Attachment* attachment);
|
||||||
|
|
||||||
AtlasRegion* findRegion(const String& name);
|
AtlasRegion* findRegion(const String& name);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Atlas* _atlas;
|
Atlas* _atlas;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_AtlasAttachmentLoader_h */
|
#endif /* Spine_AtlasAttachmentLoader_h */
|
||||||
|
|||||||
@ -35,41 +35,41 @@
|
|||||||
#include <spine/SpineString.h>
|
#include <spine/SpineString.h>
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
class Skin;
|
class Skin;
|
||||||
class Attachment;
|
class Attachment;
|
||||||
class RegionAttachment;
|
class RegionAttachment;
|
||||||
class MeshAttachment;
|
class MeshAttachment;
|
||||||
class BoundingBoxAttachment;
|
class BoundingBoxAttachment;
|
||||||
class PathAttachment;
|
class PathAttachment;
|
||||||
class PointAttachment;
|
class PointAttachment;
|
||||||
class ClippingAttachment;
|
class ClippingAttachment;
|
||||||
|
|
||||||
class SP_API AttachmentLoader : public SpineObject {
|
|
||||||
public:
|
|
||||||
RTTI_DECL
|
|
||||||
|
|
||||||
AttachmentLoader();
|
|
||||||
|
|
||||||
virtual ~AttachmentLoader();
|
|
||||||
|
|
||||||
/// @return May be NULL to not load any attachment.
|
|
||||||
virtual RegionAttachment* newRegionAttachment(Skin& skin, const String& name, const String& path) = 0;
|
|
||||||
|
|
||||||
/// @return May be NULL to not load any attachment.
|
|
||||||
virtual MeshAttachment* newMeshAttachment(Skin& skin, const String& name, const String& path) = 0;
|
|
||||||
|
|
||||||
/// @return May be NULL to not load any attachment.
|
|
||||||
virtual BoundingBoxAttachment* newBoundingBoxAttachment(Skin& skin, const String& name) = 0;
|
|
||||||
|
|
||||||
/// @return May be NULL to not load any attachment
|
|
||||||
virtual PathAttachment* newPathAttachment(Skin& skin, const String& name) = 0;
|
|
||||||
|
|
||||||
virtual PointAttachment* newPointAttachment(Skin& skin, const String& name) = 0;
|
|
||||||
|
|
||||||
virtual ClippingAttachment* newClippingAttachment(Skin& skin, const String& name) = 0;
|
|
||||||
|
|
||||||
virtual void configureAttachment(Attachment* attachment) = 0;
|
class SP_API AttachmentLoader : public SpineObject {
|
||||||
};
|
public:
|
||||||
|
RTTI_DECL
|
||||||
|
|
||||||
|
AttachmentLoader();
|
||||||
|
|
||||||
|
virtual ~AttachmentLoader();
|
||||||
|
|
||||||
|
/// @return May be NULL to not load any attachment.
|
||||||
|
virtual RegionAttachment* newRegionAttachment(Skin& skin, const String& name, const String& path) = 0;
|
||||||
|
|
||||||
|
/// @return May be NULL to not load any attachment.
|
||||||
|
virtual MeshAttachment* newMeshAttachment(Skin& skin, const String& name, const String& path) = 0;
|
||||||
|
|
||||||
|
/// @return May be NULL to not load any attachment.
|
||||||
|
virtual BoundingBoxAttachment* newBoundingBoxAttachment(Skin& skin, const String& name) = 0;
|
||||||
|
|
||||||
|
/// @return May be NULL to not load any attachment
|
||||||
|
virtual PathAttachment* newPathAttachment(Skin& skin, const String& name) = 0;
|
||||||
|
|
||||||
|
virtual PointAttachment* newPointAttachment(Skin& skin, const String& name) = 0;
|
||||||
|
|
||||||
|
virtual ClippingAttachment* newClippingAttachment(Skin& skin, const String& name) = 0;
|
||||||
|
|
||||||
|
virtual void configureAttachment(Attachment* attachment) = 0;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_AttachmentLoader_h */
|
#endif /* Spine_AttachmentLoader_h */
|
||||||
|
|||||||
@ -39,35 +39,35 @@
|
|||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
|
|
||||||
class Skeleton;
|
class Skeleton;
|
||||||
class Event;
|
class Event;
|
||||||
|
|
||||||
class SP_API AttachmentTimeline : public Timeline {
|
class SP_API AttachmentTimeline : public Timeline {
|
||||||
friend class SkeletonBinary;
|
friend class SkeletonBinary;
|
||||||
friend class SkeletonJson;
|
friend class SkeletonJson;
|
||||||
|
|
||||||
RTTI_DECL
|
RTTI_DECL
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit AttachmentTimeline(int frameCount);
|
explicit AttachmentTimeline(int frameCount);
|
||||||
|
|
||||||
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
||||||
|
|
||||||
virtual int getPropertyId();
|
virtual int getPropertyId();
|
||||||
|
|
||||||
/// Sets the time and value of the specified keyframe.
|
/// Sets the time and value of the specified keyframe.
|
||||||
void setFrame(int frameIndex, float time, const String& attachmentName);
|
void setFrame(int frameIndex, float time, const String& attachmentName);
|
||||||
|
|
||||||
size_t getSlotIndex();
|
size_t getSlotIndex();
|
||||||
void setSlotIndex(size_t inValue);
|
void setSlotIndex(size_t inValue);
|
||||||
const Vector<float>& getFrames();
|
const Vector<float>& getFrames();
|
||||||
const Vector<String>& getAttachmentNames();
|
const Vector<String>& getAttachmentNames();
|
||||||
size_t getFrameCount();
|
size_t getFrameCount();
|
||||||
private:
|
private:
|
||||||
size_t _slotIndex;
|
size_t _slotIndex;
|
||||||
Vector<float> _frames;
|
Vector<float> _frames;
|
||||||
Vector<String> _attachmentNames;
|
Vector<String> _attachmentNames;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_AttachmentTimeline_h */
|
#endif /* Spine_AttachmentTimeline_h */
|
||||||
|
|||||||
@ -31,15 +31,15 @@
|
|||||||
#define Spine_AttachmentType_h
|
#define Spine_AttachmentType_h
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
enum AttachmentType {
|
enum AttachmentType {
|
||||||
AttachmentType_Region,
|
AttachmentType_Region,
|
||||||
AttachmentType_Boundingbox,
|
AttachmentType_Boundingbox,
|
||||||
AttachmentType_Mesh,
|
AttachmentType_Mesh,
|
||||||
AttachmentType_Linkedmesh,
|
AttachmentType_Linkedmesh,
|
||||||
AttachmentType_Path,
|
AttachmentType_Path,
|
||||||
AttachmentType_Point,
|
AttachmentType_Point,
|
||||||
AttachmentType_Clipping
|
AttachmentType_Clipping
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_AttachmentType_h */
|
#endif /* Spine_AttachmentType_h */
|
||||||
|
|||||||
@ -98,9 +98,7 @@ public:
|
|||||||
|
|
||||||
float localToWorldRotation(float localRotation);
|
float localToWorldRotation(float localRotation);
|
||||||
|
|
||||||
///
|
|
||||||
/// Rotates the world transform the specified amount and sets isAppliedValid to false.
|
/// Rotates the world transform the specified amount and sets isAppliedValid to false.
|
||||||
///
|
|
||||||
/// @param degrees Degrees.
|
/// @param degrees Degrees.
|
||||||
void rotateWorld(float degrees);
|
void rotateWorld(float degrees);
|
||||||
|
|
||||||
|
|||||||
@ -34,14 +34,14 @@
|
|||||||
#include <spine/SpineObject.h>
|
#include <spine/SpineObject.h>
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
/// Attachment that has a polygon for bounds checking.
|
/// Attachment that has a polygon for bounds checking.
|
||||||
class SP_API BoundingBoxAttachment : public VertexAttachment {
|
class SP_API BoundingBoxAttachment : public VertexAttachment {
|
||||||
RTTI_DECL
|
RTTI_DECL
|
||||||
|
|
||||||
explicit BoundingBoxAttachment(const String& name);
|
explicit BoundingBoxAttachment(const String& name);
|
||||||
|
|
||||||
virtual Attachment* copy();
|
virtual Attachment* copy();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_BoundingBoxAttachment_h */
|
#endif /* Spine_BoundingBoxAttachment_h */
|
||||||
|
|||||||
@ -33,27 +33,27 @@
|
|||||||
#include <spine/VertexAttachment.h>
|
#include <spine/VertexAttachment.h>
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
class SlotData;
|
class SlotData;
|
||||||
|
|
||||||
class SP_API ClippingAttachment : public VertexAttachment {
|
class SP_API ClippingAttachment : public VertexAttachment {
|
||||||
friend class SkeletonBinary;
|
friend class SkeletonBinary;
|
||||||
friend class SkeletonJson;
|
friend class SkeletonJson;
|
||||||
|
|
||||||
friend class SkeletonClipping;
|
friend class SkeletonClipping;
|
||||||
|
|
||||||
RTTI_DECL
|
RTTI_DECL
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ClippingAttachment(const String& name);
|
explicit ClippingAttachment(const String& name);
|
||||||
|
|
||||||
SlotData* getEndSlot();
|
SlotData* getEndSlot();
|
||||||
void setEndSlot(SlotData* inValue);
|
void setEndSlot(SlotData* inValue);
|
||||||
|
|
||||||
virtual Attachment* copy();
|
virtual Attachment* copy();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
SlotData* _endSlot;
|
SlotData* _endSlot;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_ClippingAttachment_h */
|
#endif /* Spine_ClippingAttachment_h */
|
||||||
|
|||||||
@ -47,7 +47,7 @@ public:
|
|||||||
|
|
||||||
virtual void
|
virtual void
|
||||||
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
|
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
|
||||||
MixDirection direction);
|
MixDirection direction);
|
||||||
|
|
||||||
virtual int getPropertyId();
|
virtual int getPropertyId();
|
||||||
|
|
||||||
|
|||||||
@ -39,89 +39,89 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
class SP_API ContainerUtil : public SpineObject {
|
class SP_API ContainerUtil : public SpineObject {
|
||||||
public:
|
public:
|
||||||
/// Finds an item by comparing each item's name.
|
/// Finds an item by comparing each item's name.
|
||||||
/// It is more efficient to cache the results of this method than to call it multiple times.
|
/// It is more efficient to cache the results of this method than to call it multiple times.
|
||||||
/// @return May be NULL.
|
/// @return May be NULL.
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static T* findWithName(Vector<T*>& items, const String& name) {
|
static T* findWithName(Vector<T*>& items, const String& name) {
|
||||||
assert(name.length() > 0);
|
assert(name.length() > 0);
|
||||||
|
|
||||||
for (size_t i = 0; i < items.size(); ++i) {
|
|
||||||
T* item = items[i];
|
|
||||||
if (item->getName() == name) {
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @return -1 if the item was not found.
|
|
||||||
template<typename T>
|
|
||||||
static int findIndexWithName(Vector<T*>& items, const String& name) {
|
|
||||||
assert(name.length() > 0);
|
|
||||||
|
|
||||||
for (size_t i = 0, len = items.size(); i < len; ++i) {
|
|
||||||
T* item = items[i];
|
|
||||||
if (item->getName() == name) {
|
|
||||||
return static_cast<int>(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Finds an item by comparing each item's name.
|
|
||||||
/// It is more efficient to cache the results of this method than to call it multiple times.
|
|
||||||
/// @return May be NULL.
|
|
||||||
template<typename T>
|
|
||||||
static T* findWithDataName(Vector<T*>& items, const String& name) {
|
|
||||||
assert(name.length() > 0);
|
|
||||||
|
|
||||||
for (size_t i = 0; i < items.size(); ++i) {
|
|
||||||
T* item = items[i];
|
|
||||||
if (item->getData().getName() == name) {
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// @return -1 if the item was not found.
|
|
||||||
template<typename T>
|
|
||||||
static int findIndexWithDataName(Vector<T*>& items, const String& name) {
|
|
||||||
assert(name.length() > 0);
|
|
||||||
|
|
||||||
for (size_t i = 0, len = items.size(); i < len; ++i) {
|
|
||||||
T* item = items[i];
|
|
||||||
if (item->getData().getName() == name) {
|
|
||||||
return static_cast<int>(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
template<typename T>
|
|
||||||
static void cleanUpVectorOfPointers(Vector<T*>& items) {
|
|
||||||
for (int i = (int)items.size() - 1; i >= 0; i--) {
|
|
||||||
T* item = items[i];
|
|
||||||
|
|
||||||
delete item;
|
|
||||||
|
|
||||||
items.removeAt(i);
|
for (size_t i = 0; i < items.size(); ++i) {
|
||||||
}
|
T* item = items[i];
|
||||||
}
|
if (item->getName() == name) {
|
||||||
|
return item;
|
||||||
private:
|
}
|
||||||
// ctor, copy ctor, and assignment should be private in a Singleton
|
}
|
||||||
ContainerUtil();
|
|
||||||
ContainerUtil(const ContainerUtil&);
|
return NULL;
|
||||||
ContainerUtil& operator=(const ContainerUtil&);
|
}
|
||||||
};
|
|
||||||
|
/// @return -1 if the item was not found.
|
||||||
|
template<typename T>
|
||||||
|
static int findIndexWithName(Vector<T*>& items, const String& name) {
|
||||||
|
assert(name.length() > 0);
|
||||||
|
|
||||||
|
for (size_t i = 0, len = items.size(); i < len; ++i) {
|
||||||
|
T* item = items[i];
|
||||||
|
if (item->getName() == name) {
|
||||||
|
return static_cast<int>(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Finds an item by comparing each item's name.
|
||||||
|
/// It is more efficient to cache the results of this method than to call it multiple times.
|
||||||
|
/// @return May be NULL.
|
||||||
|
template<typename T>
|
||||||
|
static T* findWithDataName(Vector<T*>& items, const String& name) {
|
||||||
|
assert(name.length() > 0);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < items.size(); ++i) {
|
||||||
|
T* item = items[i];
|
||||||
|
if (item->getData().getName() == name) {
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// @return -1 if the item was not found.
|
||||||
|
template<typename T>
|
||||||
|
static int findIndexWithDataName(Vector<T*>& items, const String& name) {
|
||||||
|
assert(name.length() > 0);
|
||||||
|
|
||||||
|
for (size_t i = 0, len = items.size(); i < len; ++i) {
|
||||||
|
T* item = items[i];
|
||||||
|
if (item->getData().getName() == name) {
|
||||||
|
return static_cast<int>(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<typename T>
|
||||||
|
static void cleanUpVectorOfPointers(Vector<T*>& items) {
|
||||||
|
for (int i = (int)items.size() - 1; i >= 0; i--) {
|
||||||
|
T* item = items[i];
|
||||||
|
|
||||||
|
delete item;
|
||||||
|
|
||||||
|
items.removeAt(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// ctor, copy ctor, and assignment should be private in a Singleton
|
||||||
|
ContainerUtil();
|
||||||
|
ContainerUtil(const ContainerUtil&);
|
||||||
|
ContainerUtil& operator=(const ContainerUtil&);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_ContainerUtil_h */
|
#endif /* Spine_ContainerUtil_h */
|
||||||
|
|||||||
@ -34,43 +34,43 @@
|
|||||||
#include <spine/Vector.h>
|
#include <spine/Vector.h>
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
/// Base class for frames that use an interpolation bezier curve.
|
/// Base class for frames that use an interpolation bezier curve.
|
||||||
class SP_API CurveTimeline : public Timeline {
|
class SP_API CurveTimeline : public Timeline {
|
||||||
RTTI_DECL
|
RTTI_DECL
|
||||||
|
|
||||||
public:
|
|
||||||
explicit CurveTimeline(int frameCount);
|
|
||||||
|
|
||||||
virtual ~CurveTimeline();
|
public:
|
||||||
|
explicit CurveTimeline(int frameCount);
|
||||||
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction) = 0;
|
|
||||||
|
virtual ~CurveTimeline();
|
||||||
virtual int getPropertyId() = 0;
|
|
||||||
|
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction) = 0;
|
||||||
size_t getFrameCount();
|
|
||||||
|
virtual int getPropertyId() = 0;
|
||||||
void setLinear(size_t frameIndex);
|
|
||||||
|
size_t getFrameCount();
|
||||||
void setStepped(size_t frameIndex);
|
|
||||||
|
void setLinear(size_t frameIndex);
|
||||||
/// Sets the control handle positions for an interpolation bezier curve used to transition from this keyframe to the next.
|
|
||||||
/// cx1 and cx2 are from 0 to 1, representing the percent of time between the two keyframes. cy1 and cy2 are the percent of
|
void setStepped(size_t frameIndex);
|
||||||
/// the difference between the keyframe's values.
|
|
||||||
void setCurve(size_t frameIndex, float cx1, float cy1, float cx2, float cy2);
|
/// Sets the control handle positions for an interpolation bezier curve used to transition from this keyframe to the next.
|
||||||
|
/// cx1 and cx2 are from 0 to 1, representing the percent of time between the two keyframes. cy1 and cy2 are the percent of
|
||||||
float getCurvePercent(size_t frameIndex, float percent);
|
/// the difference between the keyframe's values.
|
||||||
|
void setCurve(size_t frameIndex, float cx1, float cy1, float cx2, float cy2);
|
||||||
float getCurveType(size_t frameIndex);
|
|
||||||
|
float getCurvePercent(size_t frameIndex, float percent);
|
||||||
protected:
|
|
||||||
static const float LINEAR;
|
float getCurveType(size_t frameIndex);
|
||||||
static const float STEPPED;
|
|
||||||
static const float BEZIER;
|
protected:
|
||||||
static const int BEZIER_SIZE;
|
static const float LINEAR;
|
||||||
|
static const float STEPPED;
|
||||||
private:
|
static const float BEZIER;
|
||||||
Vector<float> _curves; // type, x, y, ...
|
static const int BEZIER_SIZE;
|
||||||
};
|
|
||||||
|
private:
|
||||||
|
Vector<float> _curves; // type, x, y, ...
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_CurveTimeline_h */
|
#endif /* Spine_CurveTimeline_h */
|
||||||
|
|||||||
@ -33,37 +33,37 @@
|
|||||||
#include <spine/CurveTimeline.h>
|
#include <spine/CurveTimeline.h>
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
class VertexAttachment;
|
class VertexAttachment;
|
||||||
|
|
||||||
class SP_API DeformTimeline : public CurveTimeline {
|
class SP_API DeformTimeline : public CurveTimeline {
|
||||||
friend class SkeletonBinary;
|
friend class SkeletonBinary;
|
||||||
friend class SkeletonJson;
|
friend class SkeletonJson;
|
||||||
|
|
||||||
RTTI_DECL
|
RTTI_DECL
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit DeformTimeline(int frameCount);
|
explicit DeformTimeline(int frameCount);
|
||||||
|
|
||||||
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
||||||
|
|
||||||
virtual int getPropertyId();
|
virtual int getPropertyId();
|
||||||
|
|
||||||
/// Sets the time and value of the specified keyframe.
|
/// Sets the time and value of the specified keyframe.
|
||||||
void setFrame(int frameIndex, float time, Vector<float>& vertices);
|
void setFrame(int frameIndex, float time, Vector<float>& vertices);
|
||||||
|
|
||||||
int getSlotIndex();
|
int getSlotIndex();
|
||||||
void setSlotIndex(int inValue);
|
void setSlotIndex(int inValue);
|
||||||
Vector<float>& getFrames();
|
Vector<float>& getFrames();
|
||||||
Vector< Vector<float> >& getVertices();
|
Vector< Vector<float> >& getVertices();
|
||||||
VertexAttachment* getAttachment();
|
VertexAttachment* getAttachment();
|
||||||
void setAttachment(VertexAttachment* inValue);
|
void setAttachment(VertexAttachment* inValue);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
int _slotIndex;
|
int _slotIndex;
|
||||||
Vector<float> _frames;
|
Vector<float> _frames;
|
||||||
Vector< Vector<float> > _frameVertices;
|
Vector< Vector<float> > _frameVertices;
|
||||||
VertexAttachment* _attachment;
|
VertexAttachment* _attachment;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_DeformTimeline_h */
|
#endif /* Spine_DeformTimeline_h */
|
||||||
|
|||||||
@ -33,31 +33,31 @@
|
|||||||
#include <spine/Timeline.h>
|
#include <spine/Timeline.h>
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
class SP_API DrawOrderTimeline : public Timeline {
|
class SP_API DrawOrderTimeline : public Timeline {
|
||||||
friend class SkeletonBinary;
|
friend class SkeletonBinary;
|
||||||
friend class SkeletonJson;
|
friend class SkeletonJson;
|
||||||
|
|
||||||
RTTI_DECL
|
RTTI_DECL
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit DrawOrderTimeline(int frameCount);
|
explicit DrawOrderTimeline(int frameCount);
|
||||||
|
|
||||||
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
||||||
|
|
||||||
virtual int getPropertyId();
|
virtual int getPropertyId();
|
||||||
|
|
||||||
/// Sets the time and value of the specified keyframe.
|
/// Sets the time and value of the specified keyframe.
|
||||||
/// @param drawOrder May be NULL to use bind pose draw order
|
/// @param drawOrder May be NULL to use bind pose draw order
|
||||||
void setFrame(size_t frameIndex, float time, Vector<int>& drawOrder);
|
void setFrame(size_t frameIndex, float time, Vector<int>& drawOrder);
|
||||||
|
|
||||||
Vector<float>& getFrames();
|
Vector<float>& getFrames();
|
||||||
Vector< Vector<int> >& getDrawOrders();
|
Vector< Vector<int> >& getDrawOrders();
|
||||||
size_t getFrameCount();
|
size_t getFrameCount();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Vector<float> _frames;
|
Vector<float> _frames;
|
||||||
Vector< Vector<int> > _drawOrders;
|
Vector< Vector<int> > _drawOrders;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_DrawOrderTimeline_h */
|
#endif /* Spine_DrawOrderTimeline_h */
|
||||||
|
|||||||
@ -33,32 +33,32 @@
|
|||||||
#include <spine/Timeline.h>
|
#include <spine/Timeline.h>
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
class SP_API EventTimeline : public Timeline {
|
class SP_API EventTimeline : public Timeline {
|
||||||
friend class SkeletonBinary;
|
friend class SkeletonBinary;
|
||||||
friend class SkeletonJson;
|
friend class SkeletonJson;
|
||||||
|
|
||||||
RTTI_DECL
|
RTTI_DECL
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit EventTimeline(int frameCount);
|
explicit EventTimeline(int frameCount);
|
||||||
|
|
||||||
~EventTimeline();
|
~EventTimeline();
|
||||||
|
|
||||||
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
||||||
|
|
||||||
virtual int getPropertyId();
|
virtual int getPropertyId();
|
||||||
|
|
||||||
/// Sets the time and value of the specified keyframe.
|
/// Sets the time and value of the specified keyframe.
|
||||||
void setFrame(size_t frameIndex, Event* event);
|
void setFrame(size_t frameIndex, Event* event);
|
||||||
|
|
||||||
Vector<float> getFrames();
|
Vector<float> getFrames();
|
||||||
Vector<Event*>& getEvents();
|
Vector<Event*>& getEvents();
|
||||||
size_t getFrameCount();
|
size_t getFrameCount();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Vector<float> _frames;
|
Vector<float> _frames;
|
||||||
Vector<Event*> _events;
|
Vector<Event*> _events;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_EventTimeline_h */
|
#endif /* Spine_EventTimeline_h */
|
||||||
|
|||||||
@ -34,7 +34,7 @@
|
|||||||
#include <spine/Vector.h>
|
#include <spine/Vector.h>
|
||||||
#include <spine/SpineObject.h>
|
#include <spine/SpineObject.h>
|
||||||
|
|
||||||
// Required for new with line number and file name in MSVC
|
// Required for new with line number and file name in MSVC
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
#pragma warning(disable:4291)
|
#pragma warning(disable:4291)
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@ -36,54 +36,54 @@
|
|||||||
#include <spine/ConstraintData.h>
|
#include <spine/ConstraintData.h>
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
class BoneData;
|
class BoneData;
|
||||||
|
|
||||||
class SP_API IkConstraintData : public ConstraintData {
|
|
||||||
friend class SkeletonBinary;
|
|
||||||
friend class SkeletonJson;
|
|
||||||
friend class IkConstraint;
|
|
||||||
friend class Skeleton;
|
|
||||||
friend class IkConstraintTimeline;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit IkConstraintData(const String& name);
|
|
||||||
|
|
||||||
/// The bones that are constrained by this IK Constraint.
|
|
||||||
Vector<BoneData*>& getBones();
|
|
||||||
|
|
||||||
/// The bone that is the IK target.
|
|
||||||
BoneData* getTarget();
|
|
||||||
void setTarget(BoneData* inValue);
|
|
||||||
|
|
||||||
/// Controls the bend direction of the IK bones, either 1 or -1.
|
|
||||||
int getBendDirection();
|
|
||||||
void setBendDirection(int inValue);
|
|
||||||
|
|
||||||
bool getCompress();
|
class SP_API IkConstraintData : public ConstraintData {
|
||||||
void setCompress(bool inValue);
|
friend class SkeletonBinary;
|
||||||
|
friend class SkeletonJson;
|
||||||
|
friend class IkConstraint;
|
||||||
|
friend class Skeleton;
|
||||||
|
friend class IkConstraintTimeline;
|
||||||
|
|
||||||
bool getStretch();
|
public:
|
||||||
void setStretch(bool inValue);
|
explicit IkConstraintData(const String& name);
|
||||||
|
|
||||||
bool getUniform();
|
/// The bones that are constrained by this IK Constraint.
|
||||||
void setUniform(bool inValue);
|
Vector<BoneData*>& getBones();
|
||||||
|
|
||||||
float getMix();
|
/// The bone that is the IK target.
|
||||||
void setMix(float inValue);
|
BoneData* getTarget();
|
||||||
|
void setTarget(BoneData* inValue);
|
||||||
|
|
||||||
|
/// Controls the bend direction of the IK bones, either 1 or -1.
|
||||||
|
int getBendDirection();
|
||||||
|
void setBendDirection(int inValue);
|
||||||
|
|
||||||
|
bool getCompress();
|
||||||
|
void setCompress(bool inValue);
|
||||||
|
|
||||||
|
bool getStretch();
|
||||||
|
void setStretch(bool inValue);
|
||||||
|
|
||||||
|
bool getUniform();
|
||||||
|
void setUniform(bool inValue);
|
||||||
|
|
||||||
|
float getMix();
|
||||||
|
void setMix(float inValue);
|
||||||
|
|
||||||
float getSoftness();
|
float getSoftness();
|
||||||
void setSoftness(float inValue);
|
void setSoftness(float inValue);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Vector<BoneData*> _bones;
|
Vector<BoneData*> _bones;
|
||||||
BoneData* _target;
|
BoneData* _target;
|
||||||
int _bendDirection;
|
int _bendDirection;
|
||||||
bool _compress;
|
bool _compress;
|
||||||
bool _stretch;
|
bool _stretch;
|
||||||
bool _uniform;
|
bool _uniform;
|
||||||
float _mix;
|
float _mix;
|
||||||
float _softness;
|
float _softness;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_IkConstraintData_h */
|
#endif /* Spine_IkConstraintData_h */
|
||||||
|
|||||||
@ -34,25 +34,25 @@
|
|||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
|
|
||||||
class SP_API IkConstraintTimeline : public CurveTimeline {
|
class SP_API IkConstraintTimeline : public CurveTimeline {
|
||||||
friend class SkeletonBinary;
|
friend class SkeletonBinary;
|
||||||
friend class SkeletonJson;
|
friend class SkeletonJson;
|
||||||
|
|
||||||
RTTI_DECL
|
RTTI_DECL
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const int ENTRIES;
|
static const int ENTRIES;
|
||||||
|
|
||||||
explicit IkConstraintTimeline(int frameCount);
|
explicit IkConstraintTimeline(int frameCount);
|
||||||
|
|
||||||
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
||||||
|
|
||||||
virtual int getPropertyId();
|
virtual int getPropertyId();
|
||||||
|
|
||||||
/// Sets the time, mix and bend direction of the specified keyframe.
|
/// Sets the time, mix and bend direction of the specified keyframe.
|
||||||
void setFrame (int frameIndex, float time, float mix, float softness, int bendDirection, bool compress, bool stretch);
|
void setFrame (int frameIndex, float time, float mix, float softness, int bendDirection, bool compress, bool stretch);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const int PREV_TIME;
|
static const int PREV_TIME;
|
||||||
static const int PREV_MIX;
|
static const int PREV_MIX;
|
||||||
static const int PREV_SOFTNESS;
|
static const int PREV_SOFTNESS;
|
||||||
@ -65,9 +65,9 @@ namespace spine {
|
|||||||
static const int COMPRESS;
|
static const int COMPRESS;
|
||||||
static const int STRETCH;
|
static const int STRETCH;
|
||||||
|
|
||||||
Vector<float> _frames;
|
Vector<float> _frames;
|
||||||
int _ikConstraintIndex;
|
int _ikConstraintIndex;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_IkConstraintTimeline_h */
|
#endif /* Spine_IkConstraintTimeline_h */
|
||||||
|
|||||||
@ -36,105 +36,105 @@
|
|||||||
#include <spine/HasRendererObject.h>
|
#include <spine/HasRendererObject.h>
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
/// Attachment that displays a texture region using a mesh.
|
/// Attachment that displays a texture region using a mesh.
|
||||||
class SP_API MeshAttachment : public VertexAttachment, public HasRendererObject {
|
class SP_API MeshAttachment : public VertexAttachment, public HasRendererObject {
|
||||||
friend class SkeletonBinary;
|
friend class SkeletonBinary;
|
||||||
friend class SkeletonJson;
|
friend class SkeletonJson;
|
||||||
friend class AtlasAttachmentLoader;
|
friend class AtlasAttachmentLoader;
|
||||||
|
|
||||||
RTTI_DECL
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit MeshAttachment(const String& name);
|
|
||||||
|
|
||||||
virtual ~MeshAttachment();
|
RTTI_DECL
|
||||||
|
|
||||||
void updateUVs();
|
public:
|
||||||
|
explicit MeshAttachment(const String& name);
|
||||||
int getHullLength();
|
|
||||||
void setHullLength(int inValue);
|
virtual ~MeshAttachment();
|
||||||
|
|
||||||
Vector<float>& getRegionUVs();
|
void updateUVs();
|
||||||
|
|
||||||
/// The UV pair for each vertex, normalized within the entire texture. See also MeshAttachment::updateUVs
|
int getHullLength();
|
||||||
Vector<float>& getUVs();
|
void setHullLength(int inValue);
|
||||||
|
|
||||||
Vector<unsigned short>& getTriangles();
|
Vector<float>& getRegionUVs();
|
||||||
|
|
||||||
Color& getColor();
|
/// The UV pair for each vertex, normalized within the entire texture. See also MeshAttachment::updateUVs
|
||||||
|
Vector<float>& getUVs();
|
||||||
const String& getPath();
|
|
||||||
void setPath(const String& inValue);
|
Vector<unsigned short>& getTriangles();
|
||||||
|
|
||||||
float getRegionU();
|
Color& getColor();
|
||||||
void setRegionU(float inValue);
|
|
||||||
|
const String& getPath();
|
||||||
float getRegionV();
|
void setPath(const String& inValue);
|
||||||
void setRegionV(float inValue);
|
|
||||||
|
float getRegionU();
|
||||||
float getRegionU2();
|
void setRegionU(float inValue);
|
||||||
void setRegionU2(float inValue);
|
|
||||||
|
float getRegionV();
|
||||||
float getRegionV2();
|
void setRegionV(float inValue);
|
||||||
void setRegionV2(float inValue);
|
|
||||||
|
float getRegionU2();
|
||||||
bool getRegionRotate();
|
void setRegionU2(float inValue);
|
||||||
void setRegionRotate(bool inValue);
|
|
||||||
|
float getRegionV2();
|
||||||
float getRegionOffsetX();
|
void setRegionV2(float inValue);
|
||||||
void setRegionOffsetX(float inValue);
|
|
||||||
|
bool getRegionRotate();
|
||||||
// Pixels stripped from the bottom left, unrotated.
|
void setRegionRotate(bool inValue);
|
||||||
float getRegionOffsetY();
|
|
||||||
void setRegionOffsetY(float inValue);
|
float getRegionOffsetX();
|
||||||
|
void setRegionOffsetX(float inValue);
|
||||||
float getRegionWidth();
|
|
||||||
void setRegionWidth(float inValue);
|
// Pixels stripped from the bottom left, unrotated.
|
||||||
|
float getRegionOffsetY();
|
||||||
// Unrotated, stripped size.
|
void setRegionOffsetY(float inValue);
|
||||||
float getRegionHeight();
|
|
||||||
void setRegionHeight(float inValue);
|
float getRegionWidth();
|
||||||
|
void setRegionWidth(float inValue);
|
||||||
float getRegionOriginalWidth();
|
|
||||||
void setRegionOriginalWidth(float inValue);
|
// Unrotated, stripped size.
|
||||||
|
float getRegionHeight();
|
||||||
// Unrotated, unstripped size.
|
void setRegionHeight(float inValue);
|
||||||
float getRegionOriginalHeight();
|
|
||||||
void setRegionOriginalHeight(float inValue);
|
float getRegionOriginalWidth();
|
||||||
|
void setRegionOriginalWidth(float inValue);
|
||||||
MeshAttachment* getParentMesh();
|
|
||||||
void setParentMesh(MeshAttachment* inValue);
|
// Unrotated, unstripped size.
|
||||||
|
float getRegionOriginalHeight();
|
||||||
// Nonessential.
|
void setRegionOriginalHeight(float inValue);
|
||||||
Vector<unsigned short>& getEdges();
|
|
||||||
float getWidth();
|
MeshAttachment* getParentMesh();
|
||||||
void setWidth(float inValue);
|
void setParentMesh(MeshAttachment* inValue);
|
||||||
float getHeight();
|
|
||||||
void setHeight(float inValue);
|
// Nonessential.
|
||||||
|
Vector<unsigned short>& getEdges();
|
||||||
|
float getWidth();
|
||||||
|
void setWidth(float inValue);
|
||||||
|
float getHeight();
|
||||||
|
void setHeight(float inValue);
|
||||||
|
|
||||||
virtual Attachment* copy();
|
virtual Attachment* copy();
|
||||||
|
|
||||||
MeshAttachment* newLinkedMesh();
|
MeshAttachment* newLinkedMesh();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float _regionOffsetX, _regionOffsetY, _regionWidth, _regionHeight, _regionOriginalWidth, _regionOriginalHeight;
|
float _regionOffsetX, _regionOffsetY, _regionWidth, _regionHeight, _regionOriginalWidth, _regionOriginalHeight;
|
||||||
MeshAttachment* _parentMesh;
|
MeshAttachment* _parentMesh;
|
||||||
Vector<float> _uvs;
|
Vector<float> _uvs;
|
||||||
Vector<float> _regionUVs;
|
Vector<float> _regionUVs;
|
||||||
Vector<unsigned short> _triangles;
|
Vector<unsigned short> _triangles;
|
||||||
Vector<unsigned short> _edges;
|
Vector<unsigned short> _edges;
|
||||||
String _path;
|
String _path;
|
||||||
float _regionU;
|
float _regionU;
|
||||||
float _regionV;
|
float _regionV;
|
||||||
float _regionU2;
|
float _regionU2;
|
||||||
float _regionV2;
|
float _regionV2;
|
||||||
float _width;
|
float _width;
|
||||||
float _height;
|
float _height;
|
||||||
Color _color;
|
Color _color;
|
||||||
int _hullLength;
|
int _hullLength;
|
||||||
bool _regionRotate;
|
bool _regionRotate;
|
||||||
int _regionDegrees;
|
int _regionDegrees;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_MeshAttachment_h */
|
#endif /* Spine_MeshAttachment_h */
|
||||||
|
|||||||
@ -31,7 +31,7 @@
|
|||||||
#define Spine_MixPose_h
|
#define Spine_MixPose_h
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
///
|
|
||||||
/// Controls how a timeline is mixed with the setup or current pose.
|
/// Controls how a timeline is mixed with the setup or current pose.
|
||||||
/// See also Timeline::apply(Skeleton&, float, float, Vector&, float, Blend, MixDirection)
|
/// See also Timeline::apply(Skeleton&, float, float, Vector&, float, Blend, MixDirection)
|
||||||
enum MixBlend {
|
enum MixBlend {
|
||||||
|
|||||||
@ -31,13 +31,14 @@
|
|||||||
#define Spine_MixDirection_h
|
#define Spine_MixDirection_h
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
///
|
|
||||||
/// Indicates whether a timeline's alpha is mixing out over time toward 0 (the setup or current pose) or mixing in toward 1 (the timeline's pose).
|
/// Indicates whether a timeline's alpha is mixing out over time toward 0 (the setup or current pose) or mixing in toward 1 (the timeline's pose).
|
||||||
/// See also Timeline::apply(Skeleton&, float, float, Vector&, float, MixPose, MixDirection)
|
/// See also Timeline::apply(Skeleton&, float, float, Vector&, float, MixPose, MixDirection)
|
||||||
enum MixDirection {
|
enum MixDirection {
|
||||||
MixDirection_In = 0,
|
MixDirection_In = 0,
|
||||||
MixDirection_Out
|
MixDirection_Out
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_MixDirection_h */
|
#endif /* Spine_MixDirection_h */
|
||||||
|
|||||||
@ -33,28 +33,28 @@
|
|||||||
#include <spine/VertexAttachment.h>
|
#include <spine/VertexAttachment.h>
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
class SP_API PathAttachment : public VertexAttachment {
|
class SP_API PathAttachment : public VertexAttachment {
|
||||||
friend class SkeletonBinary;
|
friend class SkeletonBinary;
|
||||||
friend class SkeletonJson;
|
friend class SkeletonJson;
|
||||||
|
|
||||||
RTTI_DECL
|
RTTI_DECL
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit PathAttachment(const String& name);
|
explicit PathAttachment(const String& name);
|
||||||
|
|
||||||
/// The length in the setup pose from the start of the path to the end of each curve.
|
/// The length in the setup pose from the start of the path to the end of each curve.
|
||||||
Vector<float>& getLengths();
|
Vector<float>& getLengths();
|
||||||
bool isClosed();
|
bool isClosed();
|
||||||
void setClosed(bool inValue);
|
void setClosed(bool inValue);
|
||||||
bool isConstantSpeed();
|
bool isConstantSpeed();
|
||||||
void setConstantSpeed(bool inValue);
|
void setConstantSpeed(bool inValue);
|
||||||
|
|
||||||
virtual Attachment* copy();
|
virtual Attachment* copy();
|
||||||
private:
|
private:
|
||||||
Vector<float> _lengths;
|
Vector<float> _lengths;
|
||||||
bool _closed;
|
bool _closed;
|
||||||
bool _constantSpeed;
|
bool _constantSpeed;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_PathAttachment_h */
|
#endif /* Spine_PathAttachment_h */
|
||||||
|
|||||||
@ -35,81 +35,81 @@
|
|||||||
#include <spine/Vector.h>
|
#include <spine/Vector.h>
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
class PathConstraintData;
|
class PathConstraintData;
|
||||||
class Skeleton;
|
class Skeleton;
|
||||||
class PathAttachment;
|
class PathAttachment;
|
||||||
class Bone;
|
class Bone;
|
||||||
class Slot;
|
class Slot;
|
||||||
|
|
||||||
class SP_API PathConstraint : public Updatable {
|
class SP_API PathConstraint : public Updatable {
|
||||||
friend class Skeleton;
|
friend class Skeleton;
|
||||||
friend class PathConstraintMixTimeline;
|
friend class PathConstraintMixTimeline;
|
||||||
friend class PathConstraintPositionTimeline;
|
friend class PathConstraintPositionTimeline;
|
||||||
friend class PathConstraintSpacingTimeline;
|
friend class PathConstraintSpacingTimeline;
|
||||||
|
|
||||||
RTTI_DECL
|
RTTI_DECL
|
||||||
|
|
||||||
public:
|
public:
|
||||||
PathConstraint(PathConstraintData& data, Skeleton& skeleton);
|
PathConstraint(PathConstraintData& data, Skeleton& skeleton);
|
||||||
|
|
||||||
/// Applies the constraint to the constrained bones.
|
/// Applies the constraint to the constrained bones.
|
||||||
void apply();
|
void apply();
|
||||||
|
|
||||||
virtual void update();
|
virtual void update();
|
||||||
|
|
||||||
virtual int getOrder();
|
virtual int getOrder();
|
||||||
|
|
||||||
float getPosition();
|
float getPosition();
|
||||||
void setPosition(float inValue);
|
void setPosition(float inValue);
|
||||||
|
|
||||||
float getSpacing();
|
float getSpacing();
|
||||||
void setSpacing(float inValue);
|
void setSpacing(float inValue);
|
||||||
|
|
||||||
float getRotateMix();
|
float getRotateMix();
|
||||||
void setRotateMix(float inValue);
|
void setRotateMix(float inValue);
|
||||||
|
|
||||||
float getTranslateMix();
|
float getTranslateMix();
|
||||||
void setTranslateMix(float inValue);
|
void setTranslateMix(float inValue);
|
||||||
|
|
||||||
Vector<Bone*>& getBones();
|
Vector<Bone*>& getBones();
|
||||||
|
|
||||||
Slot* getTarget();
|
Slot* getTarget();
|
||||||
void setTarget(Slot* inValue);
|
void setTarget(Slot* inValue);
|
||||||
|
|
||||||
PathConstraintData& getData();
|
PathConstraintData& getData();
|
||||||
|
|
||||||
bool isActive();
|
bool isActive();
|
||||||
|
|
||||||
void setActive(bool inValue);
|
void setActive(bool inValue);
|
||||||
|
|
||||||
private:
|
|
||||||
static const float EPSILON;
|
|
||||||
static const int NONE;
|
|
||||||
static const int BEFORE;
|
|
||||||
static const int AFTER;
|
|
||||||
|
|
||||||
PathConstraintData& _data;
|
|
||||||
Vector<Bone*> _bones;
|
|
||||||
Slot* _target;
|
|
||||||
float _position, _spacing, _rotateMix, _translateMix;
|
|
||||||
|
|
||||||
Vector<float> _spaces;
|
|
||||||
Vector<float> _positions;
|
|
||||||
Vector<float> _world;
|
|
||||||
Vector<float> _curves;
|
|
||||||
Vector<float> _lengths;
|
|
||||||
Vector<float> _segments;
|
|
||||||
|
|
||||||
bool _active;
|
private:
|
||||||
|
static const float EPSILON;
|
||||||
Vector<float>& computeWorldPositions(PathAttachment& path, int spacesCount, bool tangents, bool percentPosition, bool percentSpacing);
|
static const int NONE;
|
||||||
|
static const int BEFORE;
|
||||||
static void addBeforePosition(float p, Vector<float>& temp, int i, Vector<float>& output, int o);
|
static const int AFTER;
|
||||||
|
|
||||||
static void addAfterPosition(float p, Vector<float>& temp, int i, Vector<float>& output, int o);
|
PathConstraintData& _data;
|
||||||
|
Vector<Bone*> _bones;
|
||||||
static void addCurvePosition(float p, float x1, float y1, float cx1, float cy1, float cx2, float cy2, float x2, float y2, Vector<float>& output, int o, bool tangents);
|
Slot* _target;
|
||||||
};
|
float _position, _spacing, _rotateMix, _translateMix;
|
||||||
|
|
||||||
|
Vector<float> _spaces;
|
||||||
|
Vector<float> _positions;
|
||||||
|
Vector<float> _world;
|
||||||
|
Vector<float> _curves;
|
||||||
|
Vector<float> _lengths;
|
||||||
|
Vector<float> _segments;
|
||||||
|
|
||||||
|
bool _active;
|
||||||
|
|
||||||
|
Vector<float>& computeWorldPositions(PathAttachment& path, int spacesCount, bool tangents, bool percentPosition, bool percentSpacing);
|
||||||
|
|
||||||
|
static void addBeforePosition(float p, Vector<float>& temp, int i, Vector<float>& output, int o);
|
||||||
|
|
||||||
|
static void addAfterPosition(float p, Vector<float>& temp, int i, Vector<float>& output, int o);
|
||||||
|
|
||||||
|
static void addCurvePosition(float p, float x1, float y1, float cx1, float cy1, float cx2, float cy2, float x2, float y2, Vector<float>& output, int o, bool tangents);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_PathConstraint_h */
|
#endif /* Spine_PathConstraint_h */
|
||||||
|
|||||||
@ -39,60 +39,60 @@
|
|||||||
#include <spine/ConstraintData.h>
|
#include <spine/ConstraintData.h>
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
class BoneData;
|
class BoneData;
|
||||||
class SlotData;
|
class SlotData;
|
||||||
|
|
||||||
class SP_API PathConstraintData : public ConstraintData {
|
|
||||||
friend class SkeletonBinary;
|
|
||||||
friend class SkeletonJson;
|
|
||||||
|
|
||||||
friend class PathConstraint;
|
|
||||||
friend class Skeleton;
|
|
||||||
friend class PathConstraintMixTimeline;
|
|
||||||
friend class PathConstraintPositionTimeline;
|
|
||||||
friend class PathConstraintSpacingTimeline;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit PathConstraintData(const String& name);
|
|
||||||
|
|
||||||
Vector<BoneData*>& getBones();
|
|
||||||
|
|
||||||
SlotData* getTarget();
|
|
||||||
void setTarget(SlotData* inValue);
|
|
||||||
|
|
||||||
PositionMode getPositionMode();
|
|
||||||
void setPositionMode(PositionMode inValue);
|
|
||||||
|
|
||||||
SpacingMode getSpacingMode();
|
|
||||||
void setSpacingMode(SpacingMode inValue);
|
|
||||||
|
|
||||||
RotateMode getRotateMode();
|
|
||||||
void setRotateMode(RotateMode inValue);
|
|
||||||
|
|
||||||
float getOffsetRotation();
|
|
||||||
void setOffsetRotation(float inValue);
|
|
||||||
|
|
||||||
float getPosition();
|
|
||||||
void setPosition(float inValue);
|
|
||||||
|
|
||||||
float getSpacing();
|
|
||||||
void setSpacing(float inValue);
|
|
||||||
|
|
||||||
float getRotateMix();
|
|
||||||
void setRotateMix(float inValue);
|
|
||||||
|
|
||||||
float getTranslateMix();
|
|
||||||
void setTranslateMix(float inValue);
|
|
||||||
|
|
||||||
private:
|
class SP_API PathConstraintData : public ConstraintData {
|
||||||
Vector<BoneData*> _bones;
|
friend class SkeletonBinary;
|
||||||
SlotData* _target;
|
friend class SkeletonJson;
|
||||||
PositionMode _positionMode;
|
|
||||||
SpacingMode _spacingMode;
|
friend class PathConstraint;
|
||||||
RotateMode _rotateMode;
|
friend class Skeleton;
|
||||||
float _offsetRotation;
|
friend class PathConstraintMixTimeline;
|
||||||
float _position, _spacing, _rotateMix, _translateMix;
|
friend class PathConstraintPositionTimeline;
|
||||||
};
|
friend class PathConstraintSpacingTimeline;
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit PathConstraintData(const String& name);
|
||||||
|
|
||||||
|
Vector<BoneData*>& getBones();
|
||||||
|
|
||||||
|
SlotData* getTarget();
|
||||||
|
void setTarget(SlotData* inValue);
|
||||||
|
|
||||||
|
PositionMode getPositionMode();
|
||||||
|
void setPositionMode(PositionMode inValue);
|
||||||
|
|
||||||
|
SpacingMode getSpacingMode();
|
||||||
|
void setSpacingMode(SpacingMode inValue);
|
||||||
|
|
||||||
|
RotateMode getRotateMode();
|
||||||
|
void setRotateMode(RotateMode inValue);
|
||||||
|
|
||||||
|
float getOffsetRotation();
|
||||||
|
void setOffsetRotation(float inValue);
|
||||||
|
|
||||||
|
float getPosition();
|
||||||
|
void setPosition(float inValue);
|
||||||
|
|
||||||
|
float getSpacing();
|
||||||
|
void setSpacing(float inValue);
|
||||||
|
|
||||||
|
float getRotateMix();
|
||||||
|
void setRotateMix(float inValue);
|
||||||
|
|
||||||
|
float getTranslateMix();
|
||||||
|
void setTranslateMix(float inValue);
|
||||||
|
|
||||||
|
private:
|
||||||
|
Vector<BoneData*> _bones;
|
||||||
|
SlotData* _target;
|
||||||
|
PositionMode _positionMode;
|
||||||
|
SpacingMode _spacingMode;
|
||||||
|
RotateMode _rotateMode;
|
||||||
|
float _offsetRotation;
|
||||||
|
float _position, _spacing, _rotateMix, _translateMix;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_PathConstraintData_h */
|
#endif /* Spine_PathConstraintData_h */
|
||||||
|
|||||||
@ -35,34 +35,34 @@
|
|||||||
namespace spine {
|
namespace spine {
|
||||||
#define SP_PATHCONSTRAINTMIXTIMELINE_ENTRIES 5
|
#define SP_PATHCONSTRAINTMIXTIMELINE_ENTRIES 5
|
||||||
|
|
||||||
class SP_API PathConstraintMixTimeline : public CurveTimeline {
|
class SP_API PathConstraintMixTimeline : public CurveTimeline {
|
||||||
friend class SkeletonBinary;
|
friend class SkeletonBinary;
|
||||||
friend class SkeletonJson;
|
friend class SkeletonJson;
|
||||||
|
|
||||||
RTTI_DECL
|
RTTI_DECL
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static const int ENTRIES;
|
static const int ENTRIES;
|
||||||
|
|
||||||
explicit PathConstraintMixTimeline(int frameCount);
|
explicit PathConstraintMixTimeline(int frameCount);
|
||||||
|
|
||||||
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
||||||
|
|
||||||
virtual int getPropertyId();
|
virtual int getPropertyId();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static const int PREV_TIME;
|
static const int PREV_TIME;
|
||||||
static const int PREV_ROTATE;
|
static const int PREV_ROTATE;
|
||||||
static const int PREV_TRANSLATE;
|
static const int PREV_TRANSLATE;
|
||||||
static const int ROTATE;
|
static const int ROTATE;
|
||||||
static const int TRANSLATE;
|
static const int TRANSLATE;
|
||||||
|
|
||||||
Vector<float> _frames;
|
Vector<float> _frames;
|
||||||
int _pathConstraintIndex;
|
int _pathConstraintIndex;
|
||||||
|
|
||||||
/// Sets the time and mixes of the specified keyframe.
|
/// Sets the time and mixes of the specified keyframe.
|
||||||
void setFrame(int frameIndex, float time, float rotateMix, float translateMix);
|
void setFrame(int frameIndex, float time, float rotateMix, float translateMix);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_PathConstraintMixTimeline_h */
|
#endif /* Spine_PathConstraintMixTimeline_h */
|
||||||
|
|||||||
@ -34,34 +34,34 @@
|
|||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
|
|
||||||
class SP_API PathConstraintPositionTimeline : public CurveTimeline {
|
class SP_API PathConstraintPositionTimeline : public CurveTimeline {
|
||||||
friend class SkeletonBinary;
|
friend class SkeletonBinary;
|
||||||
friend class SkeletonJson;
|
friend class SkeletonJson;
|
||||||
|
|
||||||
RTTI_DECL
|
|
||||||
|
|
||||||
public:
|
|
||||||
static const int ENTRIES;
|
|
||||||
|
|
||||||
explicit PathConstraintPositionTimeline(int frameCount);
|
|
||||||
|
|
||||||
virtual ~PathConstraintPositionTimeline();
|
RTTI_DECL
|
||||||
|
|
||||||
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
public:
|
||||||
|
static const int ENTRIES;
|
||||||
virtual int getPropertyId();
|
|
||||||
|
explicit PathConstraintPositionTimeline(int frameCount);
|
||||||
/// Sets the time and value of the specified keyframe.
|
|
||||||
void setFrame(int frameIndex, float time, float value);
|
virtual ~PathConstraintPositionTimeline();
|
||||||
|
|
||||||
protected:
|
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
||||||
|
|
||||||
|
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;
|
static const int PREV_TIME;
|
||||||
static const int PREV_VALUE;
|
static const int PREV_VALUE;
|
||||||
static const int VALUE;
|
static const int VALUE;
|
||||||
|
|
||||||
Vector<float> _frames;
|
Vector<float> _frames;
|
||||||
int _pathConstraintIndex;
|
int _pathConstraintIndex;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_PathConstraintPositionTimeline_h */
|
#endif /* Spine_PathConstraintPositionTimeline_h */
|
||||||
|
|||||||
@ -33,19 +33,19 @@
|
|||||||
#include <spine/PathConstraintPositionTimeline.h>
|
#include <spine/PathConstraintPositionTimeline.h>
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
class SP_API PathConstraintSpacingTimeline : public PathConstraintPositionTimeline {
|
class SP_API PathConstraintSpacingTimeline : public PathConstraintPositionTimeline {
|
||||||
friend class SkeletonBinary;
|
friend class SkeletonBinary;
|
||||||
friend class SkeletonJson;
|
friend class SkeletonJson;
|
||||||
|
|
||||||
RTTI_DECL
|
RTTI_DECL
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit PathConstraintSpacingTimeline(int frameCount);
|
explicit PathConstraintSpacingTimeline(int frameCount);
|
||||||
|
|
||||||
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
||||||
|
|
||||||
virtual int getPropertyId();
|
virtual int getPropertyId();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_PathConstraintSpacingTimeline_h */
|
#endif /* Spine_PathConstraintSpacingTimeline_h */
|
||||||
|
|||||||
@ -33,42 +33,41 @@
|
|||||||
#include <spine/Attachment.h>
|
#include <spine/Attachment.h>
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
class Bone;
|
class Bone;
|
||||||
|
|
||||||
///
|
|
||||||
/// An attachment which is a single point and a rotation. This can be used to spawn projectiles, particles, etc. A bone can be
|
|
||||||
/// used in similar ways, but a PointAttachment is slightly less expensive to compute and can be hidden, shown, and placed in a
|
|
||||||
/// skin.
|
|
||||||
///
|
|
||||||
/// See http://esotericsoftware.com/spine-point-attachments for Point Attachments in the Spine User Guide.
|
|
||||||
///
|
|
||||||
class SP_API PointAttachment : public Attachment {
|
|
||||||
friend class SkeletonBinary;
|
|
||||||
friend class SkeletonJson;
|
|
||||||
|
|
||||||
RTTI_DECL
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit PointAttachment(const String& name);
|
|
||||||
|
|
||||||
void computeWorldPosition(Bone& bone, float& ox, float& oy);
|
|
||||||
|
|
||||||
float computeWorldRotation(Bone& bone);
|
|
||||||
|
|
||||||
float getX();
|
|
||||||
void setX(float inValue);
|
|
||||||
|
|
||||||
float getY();
|
|
||||||
void setY(float inValue);
|
|
||||||
|
|
||||||
float getRotation();
|
|
||||||
void setRotation(float inValue);
|
|
||||||
|
|
||||||
virtual Attachment* copy();
|
/// An attachment which is a single point and a rotation. This can be used to spawn projectiles, particles, etc. A bone can be
|
||||||
|
/// used in similar ways, but a PointAttachment is slightly less expensive to compute and can be hidden, shown, and placed in a
|
||||||
private:
|
/// skin.
|
||||||
float _x, _y, _rotation;
|
///
|
||||||
};
|
/// See http://esotericsoftware.com/spine-point-attachments for Point Attachments in the Spine User Guide.
|
||||||
|
///
|
||||||
|
class SP_API PointAttachment : public Attachment {
|
||||||
|
friend class SkeletonBinary;
|
||||||
|
friend class SkeletonJson;
|
||||||
|
|
||||||
|
RTTI_DECL
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit PointAttachment(const String& name);
|
||||||
|
|
||||||
|
void computeWorldPosition(Bone& bone, float& ox, float& oy);
|
||||||
|
|
||||||
|
float computeWorldRotation(Bone& bone);
|
||||||
|
|
||||||
|
float getX();
|
||||||
|
void setX(float inValue);
|
||||||
|
|
||||||
|
float getY();
|
||||||
|
void setY(float inValue);
|
||||||
|
|
||||||
|
float getRotation();
|
||||||
|
void setRotation(float inValue);
|
||||||
|
|
||||||
|
virtual Attachment* copy();
|
||||||
|
|
||||||
|
private:
|
||||||
|
float _x, _y, _rotation;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_PointAttachment_h */
|
#endif /* Spine_PointAttachment_h */
|
||||||
|
|||||||
@ -54,7 +54,7 @@ public:
|
|||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
} else {
|
} else {
|
||||||
T *ret = new(__FILE__, __LINE__) T();
|
T *ret = new(__FILE__, __LINE__) T();
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -40,95 +40,95 @@
|
|||||||
#define NUM_UVS 8
|
#define NUM_UVS 8
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
class Bone;
|
class Bone;
|
||||||
|
|
||||||
/// Attachment that displays a texture region.
|
|
||||||
class SP_API RegionAttachment : public Attachment, public HasRendererObject {
|
|
||||||
friend class SkeletonBinary;
|
|
||||||
friend class SkeletonJson;
|
|
||||||
friend class AtlasAttachmentLoader;
|
|
||||||
|
|
||||||
RTTI_DECL
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit RegionAttachment(const String& name);
|
|
||||||
|
|
||||||
void updateOffset();
|
/// Attachment that displays a texture region.
|
||||||
|
class SP_API RegionAttachment : public Attachment, public HasRendererObject {
|
||||||
void setUVs(float u, float v, float u2, float v2, bool rotate);
|
friend class SkeletonBinary;
|
||||||
|
friend class SkeletonJson;
|
||||||
/// Transforms the attachment's four vertices to world coordinates.
|
friend class AtlasAttachmentLoader;
|
||||||
/// @param bone The parent bone.
|
|
||||||
/// @param worldVertices The output world vertices. Must have a length greater than or equal to offset + 8.
|
RTTI_DECL
|
||||||
/// @param offset The worldVertices index to begin writing values.
|
|
||||||
/// @param stride The number of worldVertices entries between the value pairs written.
|
public:
|
||||||
|
explicit RegionAttachment(const String& name);
|
||||||
|
|
||||||
|
void updateOffset();
|
||||||
|
|
||||||
|
void setUVs(float u, float v, float u2, float v2, bool rotate);
|
||||||
|
|
||||||
|
/// Transforms the attachment's four vertices to world coordinates.
|
||||||
|
/// @param bone The parent bone.
|
||||||
|
/// @param worldVertices The output world vertices. Must have a length greater than or equal to offset + 8.
|
||||||
|
/// @param offset The worldVertices index to begin writing values.
|
||||||
|
/// @param stride The number of worldVertices entries between the value pairs written.
|
||||||
void computeWorldVertices(Bone& bone, float *worldVertices, size_t offset, size_t stride = 2);
|
void computeWorldVertices(Bone& bone, float *worldVertices, size_t offset, size_t stride = 2);
|
||||||
void computeWorldVertices(Bone& bone, Vector<float>& worldVertices, size_t offset, size_t stride = 2);
|
void computeWorldVertices(Bone& bone, Vector<float>& worldVertices, size_t offset, size_t stride = 2);
|
||||||
|
|
||||||
float getX();
|
|
||||||
void setX(float inValue);
|
|
||||||
float getY();
|
|
||||||
void setY(float inValue);
|
|
||||||
float getRotation();
|
|
||||||
void setRotation(float inValue);
|
|
||||||
float getScaleX();
|
|
||||||
void setScaleX(float inValue);
|
|
||||||
float getScaleY();
|
|
||||||
void setScaleY(float inValue);
|
|
||||||
float getWidth();
|
|
||||||
void setWidth(float inValue);
|
|
||||||
float getHeight();
|
|
||||||
void setHeight(float inValue);
|
|
||||||
|
|
||||||
Color& getColor();
|
float getX();
|
||||||
|
void setX(float inValue);
|
||||||
|
float getY();
|
||||||
|
void setY(float inValue);
|
||||||
|
float getRotation();
|
||||||
|
void setRotation(float inValue);
|
||||||
|
float getScaleX();
|
||||||
|
void setScaleX(float inValue);
|
||||||
|
float getScaleY();
|
||||||
|
void setScaleY(float inValue);
|
||||||
|
float getWidth();
|
||||||
|
void setWidth(float inValue);
|
||||||
|
float getHeight();
|
||||||
|
void setHeight(float inValue);
|
||||||
|
|
||||||
const String& getPath();
|
Color& getColor();
|
||||||
void setPath(const String& inValue);
|
|
||||||
|
|
||||||
float getRegionOffsetX();
|
const String& getPath();
|
||||||
void setRegionOffsetX(float inValue);
|
void setPath(const String& inValue);
|
||||||
|
|
||||||
float getRegionOffsetY();
|
float getRegionOffsetX();
|
||||||
void setRegionOffsetY(float inValue);
|
void setRegionOffsetX(float inValue);
|
||||||
|
|
||||||
float getRegionWidth();
|
float getRegionOffsetY();
|
||||||
void setRegionWidth(float inValue);
|
void setRegionOffsetY(float inValue);
|
||||||
|
|
||||||
float getRegionHeight();
|
float getRegionWidth();
|
||||||
void setRegionHeight(float inValue);
|
void setRegionWidth(float inValue);
|
||||||
|
|
||||||
float getRegionOriginalWidth();
|
float getRegionHeight();
|
||||||
void setRegionOriginalWidth(float inValue);
|
void setRegionHeight(float inValue);
|
||||||
|
|
||||||
float getRegionOriginalHeight();
|
float getRegionOriginalWidth();
|
||||||
void setRegionOriginalHeight(float inValue);
|
void setRegionOriginalWidth(float inValue);
|
||||||
|
|
||||||
Vector<float>& getOffset();
|
|
||||||
Vector<float>& getUVs();
|
|
||||||
|
|
||||||
virtual Attachment* copy();
|
float getRegionOriginalHeight();
|
||||||
|
void setRegionOriginalHeight(float inValue);
|
||||||
private:
|
|
||||||
static const int BLX;
|
Vector<float>& getOffset();
|
||||||
static const int BLY;
|
Vector<float>& getUVs();
|
||||||
static const int ULX;
|
|
||||||
static const int ULY;
|
virtual Attachment* copy();
|
||||||
static const int URX;
|
|
||||||
static const int URY;
|
private:
|
||||||
static const int BRX;
|
static const int BLX;
|
||||||
static const int BRY;
|
static const int BLY;
|
||||||
|
static const int ULX;
|
||||||
float _x, _y, _rotation, _scaleX, _scaleY, _width, _height;
|
static const int ULY;
|
||||||
float _regionOffsetX, _regionOffsetY, _regionWidth, _regionHeight, _regionOriginalWidth, _regionOriginalHeight;
|
static const int URX;
|
||||||
Vector<float> _vertexOffset;
|
static const int URY;
|
||||||
Vector<float> _uvs;
|
static const int BRX;
|
||||||
String _path;
|
static const int BRY;
|
||||||
float _regionU;
|
|
||||||
float _regionV;
|
float _x, _y, _rotation, _scaleX, _scaleY, _width, _height;
|
||||||
float _regionU2;
|
float _regionOffsetX, _regionOffsetY, _regionWidth, _regionHeight, _regionOriginalWidth, _regionOriginalHeight;
|
||||||
float _regionV2;
|
Vector<float> _vertexOffset;
|
||||||
Color _color;
|
Vector<float> _uvs;
|
||||||
};
|
String _path;
|
||||||
|
float _regionU;
|
||||||
|
float _regionV;
|
||||||
|
float _regionU2;
|
||||||
|
float _regionV2;
|
||||||
|
Color _color;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_RegionAttachment_h */
|
#endif /* Spine_RegionAttachment_h */
|
||||||
|
|||||||
@ -33,38 +33,38 @@
|
|||||||
#include <spine/CurveTimeline.h>
|
#include <spine/CurveTimeline.h>
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
class SP_API RotateTimeline : public CurveTimeline {
|
class SP_API RotateTimeline : public CurveTimeline {
|
||||||
friend class SkeletonBinary;
|
friend class SkeletonBinary;
|
||||||
friend class SkeletonJson;
|
friend class SkeletonJson;
|
||||||
friend class AnimationState;
|
friend class AnimationState;
|
||||||
|
|
||||||
RTTI_DECL
|
|
||||||
|
|
||||||
public:
|
|
||||||
static const int ENTRIES = 2;
|
|
||||||
|
|
||||||
explicit RotateTimeline(int frameCount);
|
RTTI_DECL
|
||||||
|
|
||||||
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
public:
|
||||||
|
static const int ENTRIES = 2;
|
||||||
virtual int getPropertyId();
|
|
||||||
|
explicit RotateTimeline(int frameCount);
|
||||||
/// Sets the time and value of the specified keyframe.
|
|
||||||
void setFrame(int frameIndex, float time, float degrees);
|
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
||||||
|
|
||||||
int getBoneIndex();
|
virtual int getPropertyId();
|
||||||
void setBoneIndex(int inValue);
|
|
||||||
|
/// Sets the time and value of the specified keyframe.
|
||||||
Vector<float>& getFrames();
|
void setFrame(int frameIndex, float time, float degrees);
|
||||||
|
|
||||||
private:
|
int getBoneIndex();
|
||||||
static const int PREV_TIME = -2;
|
void setBoneIndex(int inValue);
|
||||||
static const int PREV_ROTATION = -1;
|
|
||||||
static const int ROTATION = 1;
|
Vector<float>& getFrames();
|
||||||
|
|
||||||
int _boneIndex;
|
private:
|
||||||
Vector<float> _frames; // time, angle, ...
|
static const int PREV_TIME = -2;
|
||||||
};
|
static const int PREV_ROTATION = -1;
|
||||||
|
static const int ROTATION = 1;
|
||||||
|
|
||||||
|
int _boneIndex;
|
||||||
|
Vector<float> _frames; // time, angle, ...
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_RotateTimeline_h */
|
#endif /* Spine_RotateTimeline_h */
|
||||||
|
|||||||
@ -33,19 +33,19 @@
|
|||||||
#include <spine/TranslateTimeline.h>
|
#include <spine/TranslateTimeline.h>
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
class SP_API ScaleTimeline : public TranslateTimeline {
|
class SP_API ScaleTimeline : public TranslateTimeline {
|
||||||
friend class SkeletonBinary;
|
friend class SkeletonBinary;
|
||||||
friend class SkeletonJson;
|
friend class SkeletonJson;
|
||||||
|
|
||||||
RTTI_DECL
|
RTTI_DECL
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ScaleTimeline(int frameCount);
|
explicit ScaleTimeline(int frameCount);
|
||||||
|
|
||||||
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
||||||
|
|
||||||
virtual int getPropertyId();
|
virtual int getPropertyId();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_ScaleTimeline_h */
|
#endif /* Spine_ScaleTimeline_h */
|
||||||
|
|||||||
@ -33,19 +33,19 @@
|
|||||||
#include <spine/TranslateTimeline.h>
|
#include <spine/TranslateTimeline.h>
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
class SP_API ShearTimeline : public TranslateTimeline {
|
class SP_API ShearTimeline : public TranslateTimeline {
|
||||||
friend class SkeletonBinary;
|
friend class SkeletonBinary;
|
||||||
friend class SkeletonJson;
|
friend class SkeletonJson;
|
||||||
|
|
||||||
RTTI_DECL
|
RTTI_DECL
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit ShearTimeline(int frameCount);
|
explicit ShearTimeline(int frameCount);
|
||||||
|
|
||||||
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
||||||
|
|
||||||
virtual int getPropertyId();
|
virtual int getPropertyId();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_ShearTimeline_h */
|
#endif /* Spine_ShearTimeline_h */
|
||||||
|
|||||||
@ -135,7 +135,6 @@ public:
|
|||||||
/// See Skeleton::setSlotsToSetupPose()
|
/// See Skeleton::setSlotsToSetupPose()
|
||||||
/// Also, often AnimationState::apply(Skeleton&) is called before the next time the
|
/// Also, often AnimationState::apply(Skeleton&) is called before the next time the
|
||||||
/// skeleton is rendered to allow any attachment keys in the current animation(s) to hide or show attachments from the new skin.
|
/// skeleton is rendered to allow any attachment keys in the current animation(s) to hide or show attachments from the new skin.
|
||||||
///
|
|
||||||
/// @param newSkin May be NULL.
|
/// @param newSkin May be NULL.
|
||||||
void setSkin(Skin *newSkin);
|
void setSkin(Skin *newSkin);
|
||||||
|
|
||||||
|
|||||||
@ -37,95 +37,95 @@
|
|||||||
#include <spine/Color.h>
|
#include <spine/Color.h>
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
class SkeletonData;
|
class SkeletonData;
|
||||||
class Atlas;
|
class Atlas;
|
||||||
class AttachmentLoader;
|
class AttachmentLoader;
|
||||||
class LinkedMesh;
|
class LinkedMesh;
|
||||||
class Skin;
|
class Skin;
|
||||||
class Attachment;
|
class Attachment;
|
||||||
class VertexAttachment;
|
class VertexAttachment;
|
||||||
class Animation;
|
class Animation;
|
||||||
class CurveTimeline;
|
class CurveTimeline;
|
||||||
|
|
||||||
class SP_API SkeletonBinary : public SpineObject {
|
|
||||||
public:
|
|
||||||
static const int BONE_ROTATE;
|
|
||||||
static const int BONE_TRANSLATE;
|
|
||||||
static const int BONE_SCALE;
|
|
||||||
static const int BONE_SHEAR;
|
|
||||||
|
|
||||||
static const int SLOT_ATTACHMENT;
|
|
||||||
static const int SLOT_COLOR;
|
|
||||||
static const int SLOT_TWO_COLOR;
|
|
||||||
|
|
||||||
static const int PATH_POSITION;
|
|
||||||
static const int PATH_SPACING;
|
|
||||||
static const int PATH_MIX;
|
|
||||||
|
|
||||||
static const int CURVE_LINEAR;
|
|
||||||
static const int CURVE_STEPPED;
|
|
||||||
static const int CURVE_BEZIER;
|
|
||||||
|
|
||||||
explicit SkeletonBinary(Atlas* atlasArray);
|
class SP_API SkeletonBinary : public SpineObject {
|
||||||
|
public:
|
||||||
|
static const int BONE_ROTATE;
|
||||||
|
static const int BONE_TRANSLATE;
|
||||||
|
static const int BONE_SCALE;
|
||||||
|
static const int BONE_SHEAR;
|
||||||
|
|
||||||
explicit SkeletonBinary(AttachmentLoader* attachmentLoader);
|
static const int SLOT_ATTACHMENT;
|
||||||
|
static const int SLOT_COLOR;
|
||||||
~SkeletonBinary();
|
static const int SLOT_TWO_COLOR;
|
||||||
|
|
||||||
SkeletonData* readSkeletonData(const unsigned char* binary, int length);
|
|
||||||
|
|
||||||
SkeletonData* readSkeletonDataFile(const String& path);
|
|
||||||
|
|
||||||
void setScale(float scale) { _scale = scale; }
|
static const int PATH_POSITION;
|
||||||
|
static const int PATH_SPACING;
|
||||||
|
static const int PATH_MIX;
|
||||||
|
|
||||||
String& getError() { return _error; }
|
static const int CURVE_LINEAR;
|
||||||
|
static const int CURVE_STEPPED;
|
||||||
private:
|
static const int CURVE_BEZIER;
|
||||||
struct DataInput : public SpineObject {
|
|
||||||
const unsigned char* cursor;
|
|
||||||
const unsigned char* end;
|
|
||||||
};
|
|
||||||
|
|
||||||
AttachmentLoader* _attachmentLoader;
|
|
||||||
Vector<LinkedMesh*> _linkedMeshes;
|
|
||||||
String _error;
|
|
||||||
float _scale;
|
|
||||||
const bool _ownsLoader;
|
|
||||||
|
|
||||||
void setError(const char* value1, const char* value2);
|
|
||||||
|
|
||||||
char* readString(DataInput* input);
|
|
||||||
|
|
||||||
char* readStringRef(DataInput* input, SkeletonData* skeletonData);
|
explicit SkeletonBinary(Atlas* atlasArray);
|
||||||
|
|
||||||
float readFloat(DataInput* input);
|
explicit SkeletonBinary(AttachmentLoader* attachmentLoader);
|
||||||
|
|
||||||
unsigned char readByte(DataInput* input);
|
~SkeletonBinary();
|
||||||
|
|
||||||
signed char readSByte(DataInput* input);
|
SkeletonData* readSkeletonData(const unsigned char* binary, int length);
|
||||||
|
|
||||||
bool readBoolean(DataInput* input);
|
SkeletonData* readSkeletonDataFile(const String& path);
|
||||||
|
|
||||||
int readInt(DataInput* input);
|
void setScale(float scale) { _scale = scale; }
|
||||||
|
|
||||||
void readColor(DataInput* input, Color& color);
|
String& getError() { return _error; }
|
||||||
|
|
||||||
int readVarint(DataInput* input, bool optimizePositive);
|
private:
|
||||||
|
struct DataInput : public SpineObject {
|
||||||
Skin* readSkin(DataInput* input, bool defaultSkin, SkeletonData* skeletonData, bool nonessential);
|
const unsigned char* cursor;
|
||||||
|
const unsigned char* end;
|
||||||
Attachment* readAttachment(DataInput* input, Skin* skin, int slotIndex, const String& attachmentName, SkeletonData* skeletonData, bool nonessential);
|
};
|
||||||
|
|
||||||
void readVertices(DataInput* input, VertexAttachment* attachment, int vertexCount);
|
AttachmentLoader* _attachmentLoader;
|
||||||
|
Vector<LinkedMesh*> _linkedMeshes;
|
||||||
void readFloatArray(DataInput *input, int n, float scale, Vector<float>& array);
|
String _error;
|
||||||
|
float _scale;
|
||||||
void readShortArray(DataInput *input, Vector<unsigned short>& array);
|
const bool _ownsLoader;
|
||||||
|
|
||||||
Animation* readAnimation(const String& name, DataInput* input, SkeletonData *skeletonData);
|
void setError(const char* value1, const char* value2);
|
||||||
|
|
||||||
void readCurve(DataInput* input, int frameIndex, CurveTimeline* timeline);
|
char* readString(DataInput* input);
|
||||||
};
|
|
||||||
|
char* readStringRef(DataInput* input, SkeletonData* skeletonData);
|
||||||
|
|
||||||
|
float readFloat(DataInput* input);
|
||||||
|
|
||||||
|
unsigned char readByte(DataInput* input);
|
||||||
|
|
||||||
|
signed char readSByte(DataInput* input);
|
||||||
|
|
||||||
|
bool readBoolean(DataInput* input);
|
||||||
|
|
||||||
|
int readInt(DataInput* input);
|
||||||
|
|
||||||
|
void readColor(DataInput* input, Color& color);
|
||||||
|
|
||||||
|
int readVarint(DataInput* input, bool optimizePositive);
|
||||||
|
|
||||||
|
Skin* readSkin(DataInput* input, bool defaultSkin, SkeletonData* skeletonData, bool nonessential);
|
||||||
|
|
||||||
|
Attachment* readAttachment(DataInput* input, Skin* skin, int slotIndex, const String& attachmentName, SkeletonData* skeletonData, bool nonessential);
|
||||||
|
|
||||||
|
void readVertices(DataInput* input, VertexAttachment* attachment, int vertexCount);
|
||||||
|
|
||||||
|
void readFloatArray(DataInput *input, int n, float scale, Vector<float>& array);
|
||||||
|
|
||||||
|
void readShortArray(DataInput *input, Vector<unsigned short>& array);
|
||||||
|
|
||||||
|
Animation* readAnimation(const String& name, DataInput* input, SkeletonData *skeletonData);
|
||||||
|
|
||||||
|
void readCurve(DataInput* input, int frameIndex, CurveTimeline* timeline);
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_SkeletonBinary_h */
|
#endif /* Spine_SkeletonBinary_h */
|
||||||
|
|||||||
@ -34,74 +34,71 @@
|
|||||||
#include <spine/SpineObject.h>
|
#include <spine/SpineObject.h>
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
class Skeleton;
|
class Skeleton;
|
||||||
class BoundingBoxAttachment;
|
class BoundingBoxAttachment;
|
||||||
class Polygon;
|
class Polygon;
|
||||||
|
|
||||||
///
|
|
||||||
/// Collects each BoundingBoxAttachment that is visible and computes the world vertices for its polygon.
|
|
||||||
/// The polygon vertices are provided along with convenience methods for doing hit detection.
|
|
||||||
///
|
|
||||||
class SP_API SkeletonBounds : public SpineObject {
|
|
||||||
public:
|
|
||||||
SkeletonBounds();
|
|
||||||
|
|
||||||
///
|
|
||||||
/// Clears any previous polygons, finds all visible bounding box attachments,
|
|
||||||
/// and computes the world vertices for each bounding box's polygon.
|
|
||||||
/// @param skeleton The skeleton.
|
|
||||||
/// @param updateAabb
|
|
||||||
/// If true, the axis aligned bounding box containing all the polygons is computed.
|
|
||||||
/// If false, the SkeletonBounds AABB methods will always return true.
|
|
||||||
///
|
|
||||||
void update(Skeleton& skeleton, bool updateAabb);
|
|
||||||
|
|
||||||
/// Returns true if the axis aligned bounding box contains the point.
|
|
||||||
bool aabbcontainsPoint(float x, float y);
|
|
||||||
|
|
||||||
/// Returns true if the axis aligned bounding box intersects the line segment.
|
|
||||||
bool aabbintersectsSegment(float x1, float y1, float x2, float y2);
|
|
||||||
|
|
||||||
/// Returns true if the axis aligned bounding box intersects the axis aligned bounding box of the specified bounds.
|
|
||||||
bool aabbIntersectsSkeleton(SkeletonBounds bounds);
|
|
||||||
|
|
||||||
/// Returns true if the polygon contains the point.
|
|
||||||
bool containsPoint(Polygon* polygon, float x, float y);
|
|
||||||
|
|
||||||
/// Returns the first bounding box attachment that contains the point, or NULL. When doing many checks, it is usually more
|
|
||||||
/// efficient to only call this method if {@link #aabbcontainsPoint(float, float)} returns true.
|
|
||||||
BoundingBoxAttachment* containsPoint(float x, float y);
|
|
||||||
|
|
||||||
/// Returns the first bounding box attachment that contains the line segment, or NULL. When doing many checks, it is usually
|
|
||||||
/// more efficient to only call this method if {@link #aabbintersectsSegment(float, float, float, float)} returns true.
|
|
||||||
BoundingBoxAttachment* intersectsSegment(float x1, float y1, float x2, float y2);
|
|
||||||
|
|
||||||
/// Returns true if the polygon contains the line segment.
|
|
||||||
bool intersectsSegment(Polygon* polygon, float x1, float y1, float x2, float y2);
|
|
||||||
|
|
||||||
Polygon* getPolygon(BoundingBoxAttachment* attachment);
|
|
||||||
|
|
||||||
float getWidth();
|
/// Collects each BoundingBoxAttachment that is visible and computes the world vertices for its polygon.
|
||||||
float getHeight();
|
/// The polygon vertices are provided along with convenience methods for doing hit detection.
|
||||||
|
class SP_API SkeletonBounds : public SpineObject {
|
||||||
|
public:
|
||||||
|
SkeletonBounds();
|
||||||
|
|
||||||
private:
|
/// Clears any previous polygons, finds all visible bounding box attachments,
|
||||||
Vector<Polygon*> _polygonPool;
|
/// and computes the world vertices for each bounding box's polygon.
|
||||||
Vector<BoundingBoxAttachment*> _boundingBoxes;
|
/// @param skeleton The skeleton.
|
||||||
Vector<Polygon*> _polygons;
|
/// @param updateAabb
|
||||||
float _minX, _minY, _maxX, _maxY;
|
/// If true, the axis aligned bounding box containing all the polygons is computed.
|
||||||
|
/// If false, the SkeletonBounds AABB methods will always return true.
|
||||||
void aabbCompute();
|
///
|
||||||
};
|
void update(Skeleton& skeleton, bool updateAabb);
|
||||||
|
|
||||||
class Polygon : public SpineObject {
|
/// Returns true if the axis aligned bounding box contains the point.
|
||||||
public:
|
bool aabbcontainsPoint(float x, float y);
|
||||||
Vector<float> _vertices;
|
|
||||||
int _count;
|
/// Returns true if the axis aligned bounding box intersects the line segment.
|
||||||
|
bool aabbintersectsSegment(float x1, float y1, float x2, float y2);
|
||||||
Polygon() : _count(0) {
|
|
||||||
|
/// Returns true if the axis aligned bounding box intersects the axis aligned bounding box of the specified bounds.
|
||||||
|
bool aabbIntersectsSkeleton(SkeletonBounds bounds);
|
||||||
|
|
||||||
|
/// Returns true if the polygon contains the point.
|
||||||
|
bool containsPoint(Polygon* polygon, float x, float y);
|
||||||
|
|
||||||
|
/// Returns the first bounding box attachment that contains the point, or NULL. When doing many checks, it is usually more
|
||||||
|
/// efficient to only call this method if {@link #aabbcontainsPoint(float, float)} returns true.
|
||||||
|
BoundingBoxAttachment* containsPoint(float x, float y);
|
||||||
|
|
||||||
|
/// Returns the first bounding box attachment that contains the line segment, or NULL. When doing many checks, it is usually
|
||||||
|
/// more efficient to only call this method if {@link #aabbintersectsSegment(float, float, float, float)} returns true.
|
||||||
|
BoundingBoxAttachment* intersectsSegment(float x1, float y1, float x2, float y2);
|
||||||
|
|
||||||
|
/// Returns true if the polygon contains the line segment.
|
||||||
|
bool intersectsSegment(Polygon* polygon, float x1, float y1, float x2, float y2);
|
||||||
|
|
||||||
|
Polygon* getPolygon(BoundingBoxAttachment* attachment);
|
||||||
|
|
||||||
|
float getWidth();
|
||||||
|
float getHeight();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Vector<Polygon*> _polygonPool;
|
||||||
|
Vector<BoundingBoxAttachment*> _boundingBoxes;
|
||||||
|
Vector<Polygon*> _polygons;
|
||||||
|
float _minX, _minY, _maxX, _maxY;
|
||||||
|
|
||||||
|
void aabbCompute();
|
||||||
|
};
|
||||||
|
|
||||||
|
class Polygon : public SpineObject {
|
||||||
|
public:
|
||||||
|
Vector<float> _vertices;
|
||||||
|
int _count;
|
||||||
|
|
||||||
|
Polygon() : _count(0) {
|
||||||
_vertices.ensureCapacity(16);
|
_vertices.ensureCapacity(16);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_SkeletonBounds_h */
|
#endif /* Spine_SkeletonBounds_h */
|
||||||
|
|||||||
@ -34,46 +34,46 @@
|
|||||||
#include <spine/Triangulator.h>
|
#include <spine/Triangulator.h>
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
class Slot;
|
class Slot;
|
||||||
class ClippingAttachment;
|
class ClippingAttachment;
|
||||||
|
|
||||||
class SP_API SkeletonClipping : public SpineObject {
|
class SP_API SkeletonClipping : public SpineObject {
|
||||||
public:
|
public:
|
||||||
SkeletonClipping();
|
SkeletonClipping();
|
||||||
|
|
||||||
|
size_t clipStart(Slot& slot, ClippingAttachment* clip);
|
||||||
|
|
||||||
|
void clipEnd(Slot& slot);
|
||||||
|
|
||||||
|
void clipEnd();
|
||||||
|
|
||||||
size_t clipStart(Slot& slot, ClippingAttachment* clip);
|
|
||||||
|
|
||||||
void clipEnd(Slot& slot);
|
|
||||||
|
|
||||||
void clipEnd();
|
|
||||||
|
|
||||||
void clipTriangles(float* vertices, unsigned short* triangles, size_t trianglesLength, float* uvs, size_t stride);
|
void clipTriangles(float* vertices, unsigned short* triangles, size_t trianglesLength, float* uvs, size_t stride);
|
||||||
|
|
||||||
void clipTriangles(Vector<float>& vertices, Vector<unsigned short>& triangles, Vector<float>& uvs, size_t stride);
|
void clipTriangles(Vector<float>& vertices, Vector<unsigned short>& triangles, Vector<float>& uvs, size_t stride);
|
||||||
|
|
||||||
bool isClipping();
|
bool isClipping();
|
||||||
|
|
||||||
Vector<float>& getClippedVertices();
|
Vector<float>& getClippedVertices();
|
||||||
Vector<unsigned short>& getClippedTriangles();
|
Vector<unsigned short>& getClippedTriangles();
|
||||||
Vector<float>& getClippedUVs();
|
Vector<float>& getClippedUVs();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Triangulator _triangulator;
|
Triangulator _triangulator;
|
||||||
Vector<float> _clippingPolygon;
|
Vector<float> _clippingPolygon;
|
||||||
Vector<float> _clipOutput;
|
Vector<float> _clipOutput;
|
||||||
Vector<float> _clippedVertices;
|
Vector<float> _clippedVertices;
|
||||||
Vector<unsigned short> _clippedTriangles;
|
Vector<unsigned short> _clippedTriangles;
|
||||||
Vector<float> _clippedUVs;
|
Vector<float> _clippedUVs;
|
||||||
Vector<float> _scratch;
|
Vector<float> _scratch;
|
||||||
ClippingAttachment* _clipAttachment;
|
ClippingAttachment* _clipAttachment;
|
||||||
Vector< Vector<float>* > *_clippingPolygons;
|
Vector< Vector<float>* > *_clippingPolygons;
|
||||||
|
|
||||||
/** Clips the input triangle against the convex, clockwise clipping area. If the triangle lies entirely within the clipping
|
/** Clips the input triangle against the convex, clockwise clipping area. If the triangle lies entirely within the clipping
|
||||||
* area, false is returned. The clipping area must duplicate the first vertex at the end of the vertices list. */
|
* area, false is returned. The clipping area must duplicate the first vertex at the end of the vertices list. */
|
||||||
bool clip(float x1, float y1, float x2, float y2, float x3, float y3, Vector<float>* clippingArea, Vector<float>* output);
|
bool clip(float x1, float y1, float x2, float y2, float x3, float y3, Vector<float>* clippingArea, Vector<float>* output);
|
||||||
|
|
||||||
static void makeClockwise(Vector<float>& polygon);
|
static void makeClockwise(Vector<float>& polygon);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_SkeletonClipping_h */
|
#endif /* Spine_SkeletonClipping_h */
|
||||||
|
|||||||
@ -112,7 +112,6 @@ public:
|
|||||||
|
|
||||||
/// The skeleton's default skin.
|
/// The skeleton's default skin.
|
||||||
/// By default this skin contains all attachments that were not in a skin in Spine.
|
/// By default this skin contains all attachments that were not in a skin in Spine.
|
||||||
///
|
|
||||||
/// @return May be NULL.
|
/// @return May be NULL.
|
||||||
Skin *getDefaultSkin();
|
Skin *getDefaultSkin();
|
||||||
|
|
||||||
|
|||||||
@ -34,18 +34,18 @@
|
|||||||
#include <spine/SpineString.h>
|
#include <spine/SpineString.h>
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
class AtlasPage;
|
class AtlasPage;
|
||||||
|
|
||||||
class SP_API TextureLoader : public SpineObject {
|
class SP_API TextureLoader : public SpineObject {
|
||||||
public:
|
public:
|
||||||
TextureLoader();
|
TextureLoader();
|
||||||
|
|
||||||
virtual ~TextureLoader();
|
virtual ~TextureLoader();
|
||||||
|
|
||||||
virtual void load(AtlasPage& page, const String& path) = 0;
|
virtual void load(AtlasPage& page, const String& path) = 0;
|
||||||
|
|
||||||
virtual void unload(void* texture) = 0;
|
virtual void unload(void* texture) = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_TextureLoader_h */
|
#endif /* Spine_TextureLoader_h */
|
||||||
|
|||||||
@ -55,14 +55,13 @@ public:
|
|||||||
/// @param time The time within the animation. Most timelines find the key before and the key after this time so they can interpolate between the keys.
|
/// @param time The time within the animation. Most timelines find the key before and the key after this time so they can interpolate between the keys.
|
||||||
/// @param pEvents If any events are fired, they are added to this array. Can be NULL to ignore firing events or if the timeline does not fire events. May be NULL.
|
/// @param pEvents If any events are fired, they are added to this array. Can be NULL to ignore firing events or if the timeline does not fire events. May be NULL.
|
||||||
/// @param alpha alpha 0 applies the current or setup pose value (depending on pose parameter). 1 applies the timeline
|
/// @param alpha alpha 0 applies the current or setup pose value (depending on pose parameter). 1 applies the timeline
|
||||||
/// value. Between 0 and 1 applies a value between the current or setup pose and the timeline value. By adjusting
|
/// value. Between 0 and 1 applies a value between the current or setup pose and the timeline value. By adjusting alpha over
|
||||||
/// alpha over time, an animation can be mixed in or out. alpha can also be useful to
|
/// time, an animation can be mixed in or out. alpha can also be useful to apply animations on top of each other (layered).
|
||||||
/// apply animations on top of each other (layered).
|
|
||||||
/// @param blend Controls how mixing is applied when alpha is than 1.
|
/// @param blend Controls how mixing is applied when alpha is than 1.
|
||||||
/// @param direction Indicates whether the timeline is mixing in or out. Used by timelines which perform instant transitions such as DrawOrderTimeline and AttachmentTimeline.
|
/// @param direction Indicates whether the timeline is mixing in or out. Used by timelines which perform instant transitions such as DrawOrderTimeline and AttachmentTimeline.
|
||||||
virtual void
|
virtual void
|
||||||
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
|
apply(Skeleton &skeleton, float lastTime, float time, Vector<Event *> *pEvents, float alpha, MixBlend blend,
|
||||||
MixDirection direction) = 0;
|
MixDirection direction) = 0;
|
||||||
|
|
||||||
virtual int getPropertyId() = 0;
|
virtual int getPropertyId() = 0;
|
||||||
};
|
};
|
||||||
|
|||||||
@ -35,63 +35,63 @@
|
|||||||
#include <spine/Vector.h>
|
#include <spine/Vector.h>
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
class TransformConstraintData;
|
class TransformConstraintData;
|
||||||
class Skeleton;
|
class Skeleton;
|
||||||
class Bone;
|
class Bone;
|
||||||
|
|
||||||
class SP_API TransformConstraint : public Updatable {
|
class SP_API TransformConstraint : public Updatable {
|
||||||
friend class Skeleton;
|
friend class Skeleton;
|
||||||
friend class TransformConstraintTimeline;
|
friend class TransformConstraintTimeline;
|
||||||
|
|
||||||
RTTI_DECL
|
RTTI_DECL
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TransformConstraint(TransformConstraintData& data, Skeleton& skeleton);
|
TransformConstraint(TransformConstraintData& data, Skeleton& skeleton);
|
||||||
|
|
||||||
void apply();
|
void apply();
|
||||||
|
|
||||||
virtual void update();
|
virtual void update();
|
||||||
|
|
||||||
virtual int getOrder();
|
virtual int getOrder();
|
||||||
|
|
||||||
TransformConstraintData& getData();
|
TransformConstraintData& getData();
|
||||||
|
|
||||||
Vector<Bone*>& getBones();
|
Vector<Bone*>& getBones();
|
||||||
|
|
||||||
Bone* getTarget();
|
Bone* getTarget();
|
||||||
void setTarget(Bone* inValue);
|
void setTarget(Bone* inValue);
|
||||||
|
|
||||||
float getRotateMix();
|
float getRotateMix();
|
||||||
void setRotateMix(float inValue);
|
void setRotateMix(float inValue);
|
||||||
|
|
||||||
float getTranslateMix();
|
float getTranslateMix();
|
||||||
void setTranslateMix(float inValue);
|
void setTranslateMix(float inValue);
|
||||||
|
|
||||||
float getScaleMix();
|
float getScaleMix();
|
||||||
void setScaleMix(float inValue);
|
void setScaleMix(float inValue);
|
||||||
|
|
||||||
float getShearMix();
|
float getShearMix();
|
||||||
void setShearMix(float inValue);
|
void setShearMix(float inValue);
|
||||||
|
|
||||||
bool isActive();
|
bool isActive();
|
||||||
|
|
||||||
void setActive(bool inValue);
|
void setActive(bool inValue);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TransformConstraintData& _data;
|
TransformConstraintData& _data;
|
||||||
Vector<Bone*> _bones;
|
Vector<Bone*> _bones;
|
||||||
Bone* _target;
|
Bone* _target;
|
||||||
float _rotateMix, _translateMix, _scaleMix, _shearMix;
|
float _rotateMix, _translateMix, _scaleMix, _shearMix;
|
||||||
bool _active;
|
bool _active;
|
||||||
|
|
||||||
void applyAbsoluteWorld();
|
void applyAbsoluteWorld();
|
||||||
|
|
||||||
void applyRelativeWorld();
|
void applyRelativeWorld();
|
||||||
|
|
||||||
void applyAbsoluteLocal();
|
void applyAbsoluteLocal();
|
||||||
|
|
||||||
void applyRelativeLocal();
|
void applyRelativeLocal();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_TransformConstraint_h */
|
#endif /* Spine_TransformConstraint_h */
|
||||||
|
|||||||
@ -36,43 +36,43 @@
|
|||||||
#include <spine/ConstraintData.h>
|
#include <spine/ConstraintData.h>
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
class BoneData;
|
class BoneData;
|
||||||
|
|
||||||
class SP_API TransformConstraintData : public ConstraintData {
|
|
||||||
friend class SkeletonBinary;
|
|
||||||
friend class SkeletonJson;
|
|
||||||
|
|
||||||
friend class TransformConstraint;
|
|
||||||
friend class Skeleton;
|
|
||||||
friend class TransformConstraintTimeline;
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit TransformConstraintData(const String& name);
|
|
||||||
|
|
||||||
Vector<BoneData*>& getBones();
|
class SP_API TransformConstraintData : public ConstraintData {
|
||||||
BoneData* getTarget();
|
friend class SkeletonBinary;
|
||||||
float getRotateMix();
|
friend class SkeletonJson;
|
||||||
float getTranslateMix();
|
|
||||||
float getScaleMix();
|
friend class TransformConstraint;
|
||||||
float getShearMix();
|
friend class Skeleton;
|
||||||
|
friend class TransformConstraintTimeline;
|
||||||
float getOffsetRotation();
|
|
||||||
float getOffsetX();
|
public:
|
||||||
float getOffsetY();
|
explicit TransformConstraintData(const String& name);
|
||||||
float getOffsetScaleX();
|
|
||||||
float getOffsetScaleY();
|
Vector<BoneData*>& getBones();
|
||||||
float getOffsetShearY();
|
BoneData* getTarget();
|
||||||
|
float getRotateMix();
|
||||||
bool isRelative();
|
float getTranslateMix();
|
||||||
bool isLocal();
|
float getScaleMix();
|
||||||
|
float getShearMix();
|
||||||
private:
|
|
||||||
Vector<BoneData*> _bones;
|
float getOffsetRotation();
|
||||||
BoneData* _target;
|
float getOffsetX();
|
||||||
float _rotateMix, _translateMix, _scaleMix, _shearMix;
|
float getOffsetY();
|
||||||
float _offsetRotation, _offsetX, _offsetY, _offsetScaleX, _offsetScaleY, _offsetShearY;
|
float getOffsetScaleX();
|
||||||
bool _relative, _local;
|
float getOffsetScaleY();
|
||||||
};
|
float getOffsetShearY();
|
||||||
|
|
||||||
|
bool isRelative();
|
||||||
|
bool isLocal();
|
||||||
|
|
||||||
|
private:
|
||||||
|
Vector<BoneData*> _bones;
|
||||||
|
BoneData* _target;
|
||||||
|
float _rotateMix, _translateMix, _scaleMix, _shearMix;
|
||||||
|
float _offsetRotation, _offsetX, _offsetY, _offsetScaleX, _offsetScaleY, _offsetShearY;
|
||||||
|
bool _relative, _local;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_TransformConstraintData_h */
|
#endif /* Spine_TransformConstraintData_h */
|
||||||
|
|||||||
@ -34,24 +34,24 @@
|
|||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
|
|
||||||
class SP_API TransformConstraintTimeline : public CurveTimeline {
|
class SP_API TransformConstraintTimeline : public CurveTimeline {
|
||||||
friend class SkeletonBinary;
|
friend class SkeletonBinary;
|
||||||
friend class SkeletonJson;
|
friend class SkeletonJson;
|
||||||
|
|
||||||
RTTI_DECL
|
|
||||||
|
|
||||||
public:
|
|
||||||
static const int ENTRIES;
|
|
||||||
|
|
||||||
explicit TransformConstraintTimeline(int frameCount);
|
RTTI_DECL
|
||||||
|
|
||||||
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
public:
|
||||||
|
static const int ENTRIES;
|
||||||
virtual int getPropertyId();
|
|
||||||
|
explicit TransformConstraintTimeline(int frameCount);
|
||||||
void setFrame(size_t frameIndex, float time, float rotateMix, float translateMix, float scaleMix, float shearMix);
|
|
||||||
|
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
||||||
private:
|
|
||||||
|
virtual int getPropertyId();
|
||||||
|
|
||||||
|
void setFrame(size_t frameIndex, float time, float rotateMix, float translateMix, float scaleMix, float shearMix);
|
||||||
|
|
||||||
|
private:
|
||||||
static const int PREV_TIME;
|
static const int PREV_TIME;
|
||||||
static const int PREV_ROTATE;
|
static const int PREV_ROTATE;
|
||||||
static const int PREV_TRANSLATE;
|
static const int PREV_TRANSLATE;
|
||||||
@ -61,10 +61,10 @@ namespace spine {
|
|||||||
static const int TRANSLATE;
|
static const int TRANSLATE;
|
||||||
static const int SCALE;
|
static const int SCALE;
|
||||||
static const int SHEAR;
|
static const int SHEAR;
|
||||||
|
|
||||||
Vector<float> _frames;
|
Vector<float> _frames;
|
||||||
int _transformConstraintIndex;
|
int _transformConstraintIndex;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_TransformConstraintTimeline_h */
|
#endif /* Spine_TransformConstraintTimeline_h */
|
||||||
|
|||||||
@ -31,13 +31,13 @@
|
|||||||
#define Spine_TransformMode_h
|
#define Spine_TransformMode_h
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
enum TransformMode {
|
enum TransformMode {
|
||||||
TransformMode_Normal = 0,
|
TransformMode_Normal = 0,
|
||||||
TransformMode_OnlyTranslation,
|
TransformMode_OnlyTranslation,
|
||||||
TransformMode_NoRotationOrReflection,
|
TransformMode_NoRotationOrReflection,
|
||||||
TransformMode_NoScale,
|
TransformMode_NoScale,
|
||||||
TransformMode_NoScaleOrReflection
|
TransformMode_NoScaleOrReflection
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_TransformMode_h */
|
#endif /* Spine_TransformMode_h */
|
||||||
|
|||||||
@ -37,36 +37,36 @@
|
|||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
|
|
||||||
class SP_API TranslateTimeline : public CurveTimeline {
|
class SP_API TranslateTimeline : public CurveTimeline {
|
||||||
friend class SkeletonBinary;
|
friend class SkeletonBinary;
|
||||||
friend class SkeletonJson;
|
friend class SkeletonJson;
|
||||||
|
|
||||||
RTTI_DECL
|
|
||||||
|
|
||||||
public:
|
|
||||||
static const int ENTRIES;
|
|
||||||
|
|
||||||
explicit TranslateTimeline(int frameCount);
|
RTTI_DECL
|
||||||
|
|
||||||
virtual ~TranslateTimeline();
|
public:
|
||||||
|
static const int ENTRIES;
|
||||||
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
|
||||||
|
explicit TranslateTimeline(int frameCount);
|
||||||
virtual int getPropertyId();
|
|
||||||
|
virtual ~TranslateTimeline();
|
||||||
/// Sets the time and value of the specified keyframe.
|
|
||||||
void setFrame(int frameIndex, float time, float x, float y);
|
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
||||||
|
|
||||||
protected:
|
virtual int getPropertyId();
|
||||||
|
|
||||||
|
/// Sets the time and value of the specified keyframe.
|
||||||
|
void setFrame(int frameIndex, float time, float x, float y);
|
||||||
|
|
||||||
|
protected:
|
||||||
static const int PREV_TIME;
|
static const int PREV_TIME;
|
||||||
static const int PREV_X;
|
static const int PREV_X;
|
||||||
static const int PREV_Y;
|
static const int PREV_Y;
|
||||||
static const int X;
|
static const int X;
|
||||||
static const int Y;
|
static const int Y;
|
||||||
|
|
||||||
Vector<float> _frames;
|
Vector<float> _frames;
|
||||||
int _boneIndex;
|
int _boneIndex;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_TranslateTimeline_h */
|
#endif /* Spine_TranslateTimeline_h */
|
||||||
|
|||||||
@ -34,28 +34,28 @@
|
|||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
|
|
||||||
class SP_API TwoColorTimeline : public CurveTimeline {
|
class SP_API TwoColorTimeline : public CurveTimeline {
|
||||||
friend class SkeletonBinary;
|
friend class SkeletonBinary;
|
||||||
friend class SkeletonJson;
|
friend class SkeletonJson;
|
||||||
|
|
||||||
RTTI_DECL
|
|
||||||
|
|
||||||
public:
|
|
||||||
static const int ENTRIES;
|
|
||||||
|
|
||||||
explicit TwoColorTimeline(int frameCount);
|
RTTI_DECL
|
||||||
|
|
||||||
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
public:
|
||||||
|
static const int ENTRIES;
|
||||||
virtual int getPropertyId();
|
|
||||||
|
explicit TwoColorTimeline(int frameCount);
|
||||||
/// 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);
|
virtual void apply(Skeleton& skeleton, float lastTime, float time, Vector<Event*>* pEvents, float alpha, MixBlend blend, MixDirection direction);
|
||||||
|
|
||||||
int getSlotIndex();
|
virtual int getPropertyId();
|
||||||
void setSlotIndex(int inValue);
|
|
||||||
|
/// Sets the time and value of the specified keyframe.
|
||||||
private:
|
void setFrame(int frameIndex, float time, float r, float g, float b, float a, float r2, float g2, float b2);
|
||||||
|
|
||||||
|
int getSlotIndex();
|
||||||
|
void setSlotIndex(int inValue);
|
||||||
|
|
||||||
|
private:
|
||||||
static const int PREV_TIME;
|
static const int PREV_TIME;
|
||||||
static const int PREV_R;
|
static const int PREV_R;
|
||||||
static const int PREV_G;
|
static const int PREV_G;
|
||||||
@ -71,10 +71,10 @@ namespace spine {
|
|||||||
static const int R2;
|
static const int R2;
|
||||||
static const int G2;
|
static const int G2;
|
||||||
static const int B2;
|
static const int B2;
|
||||||
|
|
||||||
Vector<float> _frames; // time, r, g, b, a, r2, g2, b2, ...
|
Vector<float> _frames; // time, r, g, b, a, r2, g2, b2, ...
|
||||||
int _slotIndex;
|
int _slotIndex;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_TwoColorTimeline_h */
|
#endif /* Spine_TwoColorTimeline_h */
|
||||||
|
|||||||
@ -35,59 +35,59 @@
|
|||||||
#include <spine/Vector.h>
|
#include <spine/Vector.h>
|
||||||
|
|
||||||
namespace spine {
|
namespace spine {
|
||||||
class Slot;
|
class Slot;
|
||||||
|
|
||||||
/// An attachment with vertices that are transformed by one or more bones and can be deformed by a slot's vertices.
|
/// An attachment with vertices that are transformed by one or more bones and can be deformed by a slot's vertices.
|
||||||
class SP_API VertexAttachment : public Attachment {
|
class SP_API VertexAttachment : public Attachment {
|
||||||
friend class SkeletonBinary;
|
friend class SkeletonBinary;
|
||||||
friend class SkeletonJson;
|
friend class SkeletonJson;
|
||||||
friend class DeformTimeline;
|
friend class DeformTimeline;
|
||||||
|
|
||||||
RTTI_DECL
|
RTTI_DECL
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit VertexAttachment(const String& name);
|
explicit VertexAttachment(const String& name);
|
||||||
|
|
||||||
|
virtual ~VertexAttachment();
|
||||||
|
|
||||||
virtual ~VertexAttachment();
|
|
||||||
|
|
||||||
void computeWorldVertices(Slot& slot, float* worldVertices);
|
void computeWorldVertices(Slot& slot, float* worldVertices);
|
||||||
void computeWorldVertices(Slot& slot, Vector<float>& worldVertices);
|
void computeWorldVertices(Slot& slot, Vector<float>& worldVertices);
|
||||||
|
|
||||||
/// Transforms local vertices to world coordinates.
|
|
||||||
/// @param start The index of the first Vertices value to transform. Each vertex has 2 values, x and y.
|
|
||||||
/// @param count The number of world vertex values to output. Must be less than or equal to WorldVerticesLength - start.
|
|
||||||
/// @param worldVertices The output world vertices. Must have a length greater than or equal to offset + count.
|
|
||||||
/// @param offset The worldVertices index to begin writing values.
|
|
||||||
/// @param stride The number of worldVertices entries between the value pairs written.
|
|
||||||
void computeWorldVertices(Slot& slot, size_t start, size_t count, float* worldVertices, size_t offset, size_t stride = 2);
|
|
||||||
void computeWorldVertices(Slot& slot, size_t start, size_t count, Vector<float>& worldVertices, size_t offset, size_t stride = 2);
|
|
||||||
|
|
||||||
/// Gets a unique ID for this attachment.
|
|
||||||
int getId();
|
|
||||||
|
|
||||||
Vector<size_t>& getBones();
|
|
||||||
|
|
||||||
Vector<float>& getVertices();
|
|
||||||
|
|
||||||
size_t getWorldVerticesLength();
|
|
||||||
void setWorldVerticesLength(size_t inValue);
|
|
||||||
|
|
||||||
VertexAttachment* getDeformAttachment();
|
/// Transforms local vertices to world coordinates.
|
||||||
|
/// @param start The index of the first Vertices value to transform. Each vertex has 2 values, x and y.
|
||||||
|
/// @param count The number of world vertex values to output. Must be less than or equal to WorldVerticesLength - start.
|
||||||
|
/// @param worldVertices The output world vertices. Must have a length greater than or equal to offset + count.
|
||||||
|
/// @param offset The worldVertices index to begin writing values.
|
||||||
|
/// @param stride The number of worldVertices entries between the value pairs written.
|
||||||
|
void computeWorldVertices(Slot& slot, size_t start, size_t count, float* worldVertices, size_t offset, size_t stride = 2);
|
||||||
|
void computeWorldVertices(Slot& slot, size_t start, size_t count, Vector<float>& worldVertices, size_t offset, size_t stride = 2);
|
||||||
|
|
||||||
|
/// Gets a unique ID for this attachment.
|
||||||
|
int getId();
|
||||||
|
|
||||||
|
Vector<size_t>& getBones();
|
||||||
|
|
||||||
|
Vector<float>& getVertices();
|
||||||
|
|
||||||
|
size_t getWorldVerticesLength();
|
||||||
|
void setWorldVerticesLength(size_t inValue);
|
||||||
|
|
||||||
|
VertexAttachment* getDeformAttachment();
|
||||||
void setDeformAttachment(VertexAttachment* attachment);
|
void setDeformAttachment(VertexAttachment* attachment);
|
||||||
|
|
||||||
void copyTo(VertexAttachment* other);
|
void copyTo(VertexAttachment* other);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Vector<size_t> _bones;
|
Vector<size_t> _bones;
|
||||||
Vector<float> _vertices;
|
Vector<float> _vertices;
|
||||||
size_t _worldVerticesLength;
|
size_t _worldVerticesLength;
|
||||||
VertexAttachment* _deformAttachment;
|
VertexAttachment* _deformAttachment;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const int _id;
|
const int _id;
|
||||||
|
|
||||||
static int getNextID();
|
static int getNextID();
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* Spine_VertexAttachment_h */
|
#endif /* Spine_VertexAttachment_h */
|
||||||
|
|||||||
@ -52,7 +52,8 @@ Animation::~Animation() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Animation::apply(Skeleton &skeleton, float lastTime, float time, bool loop, Vector<Event *> *pEvents, float alpha,
|
void Animation::apply(Skeleton &skeleton, float lastTime, float time, bool loop, Vector<Event *> *pEvents, float alpha,
|
||||||
MixBlend blend, MixDirection direction) {
|
MixBlend blend, MixDirection direction
|
||||||
|
) {
|
||||||
if (loop && _duration != 0) {
|
if (loop && _duration != 0) {
|
||||||
time = MathUtil::fmod(time, _duration);
|
time = MathUtil::fmod(time, _duration);
|
||||||
if (lastTime > 0) {
|
if (lastTime > 0) {
|
||||||
@ -91,15 +92,12 @@ int Animation::binarySearch(Vector<float> &values, float target, int step) {
|
|||||||
|
|
||||||
int current = (int) (static_cast<uint32_t>(high) >> 1);
|
int current = (int) (static_cast<uint32_t>(high) >> 1);
|
||||||
while (true) {
|
while (true) {
|
||||||
if (values[(current + 1) * step] <= target) {
|
if (values[(current + 1) * step] <= target)
|
||||||
low = current + 1;
|
low = current + 1;
|
||||||
} else {
|
else
|
||||||
high = current;
|
high = current;
|
||||||
}
|
|
||||||
|
|
||||||
if (low == high) {
|
if (low == high) return (low + 1) * step;
|
||||||
return (low + 1) * step;
|
|
||||||
}
|
|
||||||
|
|
||||||
current = (int) (static_cast<uint32_t>(low + high) >> 1);
|
current = (int) (static_cast<uint32_t>(low + high) >> 1);
|
||||||
}
|
}
|
||||||
@ -109,21 +107,16 @@ int Animation::binarySearch(Vector<float> &values, float target) {
|
|||||||
int low = 0;
|
int low = 0;
|
||||||
int size = (int)values.size();
|
int size = (int)values.size();
|
||||||
int high = size - 2;
|
int high = size - 2;
|
||||||
if (high == 0) {
|
if (high == 0) return 1;
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int current = (int) (static_cast<uint32_t>(high) >> 1);
|
int current = (int) (static_cast<uint32_t>(high) >> 1);
|
||||||
while (true) {
|
while (true) {
|
||||||
if (values[(current + 1)] <= target) {
|
if (values[(current + 1)] <= target)
|
||||||
low = current + 1;
|
low = current + 1;
|
||||||
} else {
|
else
|
||||||
high = current;
|
high = current;
|
||||||
}
|
|
||||||
|
|
||||||
if (low == high) {
|
if (low == high) return (low + 1);
|
||||||
return (low + 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
current = (int) (static_cast<uint32_t>(low + high) >> 1);
|
current = (int) (static_cast<uint32_t>(low + high) >> 1);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -54,11 +54,11 @@ void dummyOnAnimationEventFunc(AnimationState *state, spine::EventType type, Tra
|
|||||||
}
|
}
|
||||||
|
|
||||||
TrackEntry::TrackEntry() : _animation(NULL), _next(NULL), _mixingFrom(NULL), _mixingTo(0), _trackIndex(0), _loop(false), _holdPrevious(false),
|
TrackEntry::TrackEntry() : _animation(NULL), _next(NULL), _mixingFrom(NULL), _mixingTo(0), _trackIndex(0), _loop(false), _holdPrevious(false),
|
||||||
_eventThreshold(0), _attachmentThreshold(0), _drawOrderThreshold(0), _animationStart(0),
|
_eventThreshold(0), _attachmentThreshold(0), _drawOrderThreshold(0), _animationStart(0),
|
||||||
_animationEnd(0), _animationLast(0), _nextAnimationLast(0), _delay(0), _trackTime(0),
|
_animationEnd(0), _animationLast(0), _nextAnimationLast(0), _delay(0), _trackTime(0),
|
||||||
_trackLast(0), _nextTrackLast(0), _trackEnd(0), _timeScale(1.0f), _alpha(0), _mixTime(0),
|
_trackLast(0), _nextTrackLast(0), _trackEnd(0), _timeScale(1.0f), _alpha(0), _mixTime(0),
|
||||||
_mixDuration(0), _interruptAlpha(0), _totalAlpha(0), _mixBlend(MixBlend_Replace),
|
_mixDuration(0), _interruptAlpha(0), _totalAlpha(0), _mixBlend(MixBlend_Replace),
|
||||||
_listener(dummyOnAnimationEventFunc), _listenerObject(NULL) {
|
_listener(dummyOnAnimationEventFunc), _listenerObject(NULL) {
|
||||||
}
|
}
|
||||||
|
|
||||||
TrackEntry::~TrackEntry() { }
|
TrackEntry::~TrackEntry() { }
|
||||||
@ -105,10 +105,7 @@ void TrackEntry::setAnimationLast(float inValue) {
|
|||||||
float TrackEntry::getAnimationTime() {
|
float TrackEntry::getAnimationTime() {
|
||||||
if (_loop) {
|
if (_loop) {
|
||||||
float duration = _animationEnd - _animationStart;
|
float duration = _animationEnd - _animationStart;
|
||||||
if (duration == 0) {
|
if (duration == 0) return _animationStart;
|
||||||
return _animationStart;
|
|
||||||
}
|
|
||||||
|
|
||||||
return MathUtil::fmod(_trackTime, duration) + _animationStart;
|
return MathUtil::fmod(_trackTime, duration) + _animationStart;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,8 +199,8 @@ EventQueueEntry EventQueue::newEventQueueEntry(EventType eventType, TrackEntry *
|
|||||||
}
|
}
|
||||||
|
|
||||||
EventQueue::EventQueue(AnimationState &state, Pool<TrackEntry> &trackEntryPool) : _state(state),
|
EventQueue::EventQueue(AnimationState &state, Pool<TrackEntry> &trackEntryPool) : _state(state),
|
||||||
_trackEntryPool(trackEntryPool),
|
_trackEntryPool(trackEntryPool),
|
||||||
_drainDisabled(false) {
|
_drainDisabled(false) {
|
||||||
}
|
}
|
||||||
|
|
||||||
EventQueue::~EventQueue() {
|
EventQueue::~EventQueue() {
|
||||||
@ -251,36 +248,35 @@ void EventQueue::drain() {
|
|||||||
TrackEntry *trackEntry = queueEntry->_entry;
|
TrackEntry *trackEntry = queueEntry->_entry;
|
||||||
|
|
||||||
switch (queueEntry->_type) {
|
switch (queueEntry->_type) {
|
||||||
case EventType_Start:
|
case EventType_Start:
|
||||||
case EventType_Interrupt:
|
case EventType_Interrupt:
|
||||||
case EventType_Complete:
|
case EventType_Complete:
|
||||||
if (!trackEntry->_listenerObject) trackEntry->_listener(&state, queueEntry->_type, trackEntry, NULL);
|
if (!trackEntry->_listenerObject) trackEntry->_listener(&state, queueEntry->_type, trackEntry, NULL);
|
||||||
else trackEntry->_listenerObject->callback(&state, queueEntry->_type, trackEntry, NULL);
|
else trackEntry->_listenerObject->callback(&state, queueEntry->_type, trackEntry, NULL);
|
||||||
if(!state._listenerObject) state._listener(&state, queueEntry->_type, trackEntry, NULL);
|
if(!state._listenerObject) state._listener(&state, queueEntry->_type, trackEntry, NULL);
|
||||||
else state._listenerObject->callback(&state, queueEntry->_type, trackEntry, NULL);
|
else state._listenerObject->callback(&state, queueEntry->_type, trackEntry, NULL);
|
||||||
break;
|
break;
|
||||||
case EventType_End:
|
case EventType_End:
|
||||||
if (!trackEntry->_listenerObject) trackEntry->_listener(&state, queueEntry->_type, trackEntry, NULL);
|
if (!trackEntry->_listenerObject) trackEntry->_listener(&state, queueEntry->_type, trackEntry, NULL);
|
||||||
else trackEntry->_listenerObject->callback(&state, queueEntry->_type, trackEntry, NULL);
|
else trackEntry->_listenerObject->callback(&state, queueEntry->_type, trackEntry, NULL);
|
||||||
if (!state._listenerObject) state._listener(&state, queueEntry->_type, trackEntry, NULL);
|
if (!state._listenerObject) state._listener(&state, queueEntry->_type, trackEntry, NULL);
|
||||||
else state._listenerObject->callback(&state, queueEntry->_type, trackEntry, NULL);
|
else state._listenerObject->callback(&state, queueEntry->_type, trackEntry, NULL);
|
||||||
/* Yes, we want to fall through here */
|
/* Fall through. */
|
||||||
case EventType_Dispose:
|
case EventType_Dispose:
|
||||||
|
if (!trackEntry->_listenerObject) trackEntry->_listener(&state, EventType_Dispose, trackEntry, NULL);
|
||||||
|
else trackEntry->_listenerObject->callback(&state, EventType_Dispose, trackEntry, NULL);
|
||||||
|
if (!state._listenerObject) state._listener(&state, EventType_Dispose, trackEntry, NULL);
|
||||||
|
else state._listenerObject->callback(&state, EventType_Dispose, trackEntry, NULL);
|
||||||
|
|
||||||
if (!trackEntry->_listenerObject) trackEntry->_listener(&state, EventType_Dispose, trackEntry, NULL);
|
trackEntry->reset();
|
||||||
else trackEntry->_listenerObject->callback(&state, EventType_Dispose, trackEntry, NULL);
|
_trackEntryPool.free(trackEntry);
|
||||||
if (!state._listenerObject) state._listener(&state, EventType_Dispose, trackEntry, NULL);
|
break;
|
||||||
else state._listenerObject->callback(&state, EventType_Dispose, trackEntry, NULL);
|
case EventType_Event:
|
||||||
|
if (!trackEntry->_listenerObject) trackEntry->_listener(&state, queueEntry->_type, trackEntry, queueEntry->_event);
|
||||||
trackEntry->reset();
|
else trackEntry->_listenerObject->callback(&state, queueEntry->_type, trackEntry, queueEntry->_event);
|
||||||
_trackEntryPool.free(trackEntry);
|
if (!state._listenerObject) state._listener(&state, queueEntry->_type, trackEntry, queueEntry->_event);
|
||||||
break;
|
else state._listenerObject->callback(&state, queueEntry->_type, trackEntry, queueEntry->_event);
|
||||||
case EventType_Event:
|
break;
|
||||||
if (!trackEntry->_listenerObject) trackEntry->_listener(&state, queueEntry->_type, trackEntry, queueEntry->_event);
|
|
||||||
else trackEntry->_listenerObject->callback(&state, queueEntry->_type, trackEntry, queueEntry->_event);
|
|
||||||
if (!state._listenerObject) state._listener(&state, queueEntry->_type, trackEntry, queueEntry->_event);
|
|
||||||
else state._listenerObject->callback(&state, queueEntry->_type, trackEntry, queueEntry->_event);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_eventQueueEntries.clear();
|
_eventQueueEntries.clear();
|
||||||
@ -420,17 +416,13 @@ bool AnimationState::apply(Skeleton &skeleton) {
|
|||||||
size_t timelineCount = current._animation->_timelines.size();
|
size_t timelineCount = current._animation->_timelines.size();
|
||||||
Vector<Timeline *> &timelines = current._animation->_timelines;
|
Vector<Timeline *> &timelines = current._animation->_timelines;
|
||||||
if ((i == 0 && mix == 1) || blend == MixBlend_Add) {
|
if ((i == 0 && mix == 1) || blend == MixBlend_Add) {
|
||||||
for (size_t ii = 0; ii < timelineCount; ++ii) {
|
for (size_t ii = 0; ii < timelineCount; ++ii)
|
||||||
timelines[ii]->apply(skeleton, animationLast, animationTime, &_events, mix, blend,
|
timelines[ii]->apply(skeleton, animationLast, animationTime, &_events, mix, blend, MixDirection_In);
|
||||||
MixDirection_In);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
Vector<int> &timelineMode = current._timelineMode;
|
Vector<int> &timelineMode = current._timelineMode;
|
||||||
|
|
||||||
bool firstFrame = current._timelinesRotation.size() == 0;
|
bool firstFrame = current._timelinesRotation.size() == 0;
|
||||||
if (firstFrame) {
|
if (firstFrame) current._timelinesRotation.setSize(timelines.size() << 1, 0);
|
||||||
current._timelinesRotation.setSize(timelines.size() << 1, 0);
|
|
||||||
}
|
|
||||||
Vector<float> &timelinesRotation = current._timelinesRotation;
|
Vector<float> &timelinesRotation = current._timelinesRotation;
|
||||||
|
|
||||||
for (size_t ii = 0; ii < timelineCount; ++ii) {
|
for (size_t ii = 0; ii < timelineCount; ++ii) {
|
||||||
@ -440,16 +432,12 @@ bool AnimationState::apply(Skeleton &skeleton) {
|
|||||||
MixBlend timelineBlend = (timelineMode[ii] & (NotLast - 1)) == Subsequent ? blend : MixBlend_Setup;
|
MixBlend timelineBlend = (timelineMode[ii] & (NotLast - 1)) == Subsequent ? blend : MixBlend_Setup;
|
||||||
|
|
||||||
RotateTimeline *rotateTimeline = NULL;
|
RotateTimeline *rotateTimeline = NULL;
|
||||||
if (timeline->getRTTI().isExactly(RotateTimeline::rtti)) {
|
if (timeline->getRTTI().isExactly(RotateTimeline::rtti)) rotateTimeline = static_cast<RotateTimeline *>(timeline);
|
||||||
rotateTimeline = static_cast<RotateTimeline *>(timeline);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (rotateTimeline != NULL) {
|
if (rotateTimeline != NULL)
|
||||||
applyRotateTimeline(rotateTimeline, skeleton, animationTime, mix, timelineBlend, timelinesRotation, ii << 1,
|
applyRotateTimeline(rotateTimeline, skeleton, animationTime, mix, timelineBlend, timelinesRotation, ii << 1, firstFrame);
|
||||||
firstFrame);
|
else
|
||||||
} else {
|
|
||||||
timeline->apply(skeleton, animationLast, animationTime, &_events, mix, timelineBlend, MixDirection_In);
|
timeline->apply(skeleton, animationLast, animationTime, &_events, mix, timelineBlend, MixDirection_In);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -466,23 +454,18 @@ bool AnimationState::apply(Skeleton &skeleton) {
|
|||||||
void AnimationState::clearTracks() {
|
void AnimationState::clearTracks() {
|
||||||
bool oldDrainDisabled = _queue->_drainDisabled;
|
bool oldDrainDisabled = _queue->_drainDisabled;
|
||||||
_queue->_drainDisabled = true;
|
_queue->_drainDisabled = true;
|
||||||
for (size_t i = 0, n = _tracks.size(); i < n; ++i) {
|
for (size_t i = 0, n = _tracks.size(); i < n; ++i)
|
||||||
clearTrack(i);
|
clearTrack(i);
|
||||||
}
|
|
||||||
_tracks.clear();
|
_tracks.clear();
|
||||||
_queue->_drainDisabled = oldDrainDisabled;
|
_queue->_drainDisabled = oldDrainDisabled;
|
||||||
_queue->drain();
|
_queue->drain();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AnimationState::clearTrack(size_t trackIndex) {
|
void AnimationState::clearTrack(size_t trackIndex) {
|
||||||
if (trackIndex >= _tracks.size()) {
|
if (trackIndex >= _tracks.size()) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
TrackEntry *current = _tracks[trackIndex];
|
TrackEntry *current = _tracks[trackIndex];
|
||||||
if (current == NULL) {
|
if (current == NULL) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
_queue->end(current);
|
_queue->end(current);
|
||||||
|
|
||||||
@ -491,9 +474,7 @@ void AnimationState::clearTrack(size_t trackIndex) {
|
|||||||
TrackEntry *entry = current;
|
TrackEntry *entry = current;
|
||||||
while (true) {
|
while (true) {
|
||||||
TrackEntry *from = entry->_mixingFrom;
|
TrackEntry *from = entry->_mixingFrom;
|
||||||
if (from == NULL) {
|
if (from == NULL) break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
_queue->end(from);
|
_queue->end(from);
|
||||||
entry->_mixingFrom = NULL;
|
entry->_mixingFrom = NULL;
|
||||||
@ -509,7 +490,6 @@ void AnimationState::clearTrack(size_t trackIndex) {
|
|||||||
TrackEntry *AnimationState::setAnimation(size_t trackIndex, const String &animationName, bool loop) {
|
TrackEntry *AnimationState::setAnimation(size_t trackIndex, const String &animationName, bool loop) {
|
||||||
Animation *animation = _data->_skeletonData->findAnimation(animationName);
|
Animation *animation = _data->_skeletonData->findAnimation(animationName);
|
||||||
assert(animation != NULL);
|
assert(animation != NULL);
|
||||||
|
|
||||||
return setAnimation(trackIndex, animation, loop);
|
return setAnimation(trackIndex, animation, loop);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -542,7 +522,6 @@ TrackEntry *AnimationState::setAnimation(size_t trackIndex, Animation *animation
|
|||||||
TrackEntry *AnimationState::addAnimation(size_t trackIndex, const String &animationName, bool loop, float delay) {
|
TrackEntry *AnimationState::addAnimation(size_t trackIndex, const String &animationName, bool loop, float delay) {
|
||||||
Animation *animation = _data->_skeletonData->findAnimation(animationName);
|
Animation *animation = _data->_skeletonData->findAnimation(animationName);
|
||||||
assert(animation != NULL);
|
assert(animation != NULL);
|
||||||
|
|
||||||
return addAnimation(trackIndex, animation, loop, delay);
|
return addAnimation(trackIndex, animation, loop, delay);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -551,9 +530,8 @@ TrackEntry *AnimationState::addAnimation(size_t trackIndex, Animation *animation
|
|||||||
|
|
||||||
TrackEntry *last = expandToIndex(trackIndex);
|
TrackEntry *last = expandToIndex(trackIndex);
|
||||||
if (last != NULL) {
|
if (last != NULL) {
|
||||||
while (last->_next != NULL) {
|
while (last->_next != NULL)
|
||||||
last = last->_next;
|
last = last->_next;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TrackEntry *entry = newTrackEntry(trackIndex, animation, loop, last);
|
TrackEntry *entry = newTrackEntry(trackIndex, animation, loop, last);
|
||||||
@ -657,10 +635,9 @@ Animation *AnimationState::getEmptyAnimation() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void AnimationState::applyRotateTimeline(RotateTimeline *rotateTimeline, Skeleton &skeleton, float time, float alpha,
|
void AnimationState::applyRotateTimeline(RotateTimeline *rotateTimeline, Skeleton &skeleton, float time, float alpha,
|
||||||
MixBlend blend, Vector<float> &timelinesRotation, size_t i, bool firstFrame) {
|
MixBlend blend, Vector<float> &timelinesRotation, size_t i, bool firstFrame
|
||||||
if (firstFrame) {
|
) {
|
||||||
timelinesRotation[i] = 0;
|
if (firstFrame) timelinesRotation[i] = 0;
|
||||||
}
|
|
||||||
|
|
||||||
if (alpha == 1) {
|
if (alpha == 1) {
|
||||||
rotateTimeline->apply(skeleton, 0, time, NULL, 1, blend, MixDirection_In);
|
rotateTimeline->apply(skeleton, 0, time, NULL, 1, blend, MixDirection_In);
|
||||||
@ -673,13 +650,13 @@ void AnimationState::applyRotateTimeline(RotateTimeline *rotateTimeline, Skeleto
|
|||||||
float r1, r2;
|
float r1, r2;
|
||||||
if (time < frames[0]) {
|
if (time < frames[0]) {
|
||||||
switch (blend) {
|
switch (blend) {
|
||||||
case MixBlend_Setup:
|
case MixBlend_Setup:
|
||||||
bone->_rotation = bone->_data._rotation;
|
bone->_rotation = bone->_data._rotation;
|
||||||
default:
|
default:
|
||||||
return;
|
return;
|
||||||
case MixBlend_First:
|
case MixBlend_First:
|
||||||
r1 = bone->_rotation;
|
r1 = bone->_rotation;
|
||||||
r2 = bone->_data._rotation;
|
r2 = bone->_data._rotation;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
r1 = blend == MixBlend_Setup ? bone->_data._rotation : bone->_rotation;
|
r1 = blend == MixBlend_Setup ? bone->_data._rotation : bone->_rotation;
|
||||||
@ -692,9 +669,7 @@ void AnimationState::applyRotateTimeline(RotateTimeline *rotateTimeline, Skeleto
|
|||||||
float prevRotation = frames[frame + RotateTimeline::PREV_ROTATION];
|
float prevRotation = frames[frame + RotateTimeline::PREV_ROTATION];
|
||||||
float frameTime = frames[frame];
|
float frameTime = frames[frame];
|
||||||
float percent = rotateTimeline->getCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame +
|
float percent = rotateTimeline->getCurvePercent((frame >> 1) - 1, 1 - (time - frameTime) / (frames[frame +
|
||||||
RotateTimeline::PREV_TIME] -
|
RotateTimeline::PREV_TIME] - frameTime));
|
||||||
frameTime));
|
|
||||||
|
|
||||||
r2 = frames[frame + RotateTimeline::ROTATION] - prevRotation;
|
r2 = frames[frame + RotateTimeline::ROTATION] - prevRotation;
|
||||||
r2 -= (16384 - (int) (16384.499999999996 - r2 / 360)) * 360;
|
r2 -= (16384 - (int) (16384.499999999996 - r2 / 360)) * 360;
|
||||||
r2 = prevRotation + r2 * percent + bone->_data._rotation;
|
r2 = prevRotation + r2 * percent + bone->_data._rotation;
|
||||||
@ -721,9 +696,7 @@ void AnimationState::applyRotateTimeline(RotateTimeline *rotateTimeline, Skeleto
|
|||||||
// Detect cross at 0 (not 180).
|
// Detect cross at 0 (not 180).
|
||||||
if (MathUtil::sign(lastDiff) != MathUtil::sign(diff) && MathUtil::abs(lastDiff) <= 90) {
|
if (MathUtil::sign(lastDiff) != MathUtil::sign(diff) && MathUtil::abs(lastDiff) <= 90) {
|
||||||
// A cross after a 360 rotation is a loop.
|
// A cross after a 360 rotation is a loop.
|
||||||
if (MathUtil::abs(lastTotal) > 180) {
|
if (MathUtil::abs(lastTotal) > 180) lastTotal += 360 * MathUtil::sign(lastTotal);
|
||||||
lastTotal += 360 * MathUtil::sign(lastTotal);
|
|
||||||
}
|
|
||||||
dir = current;
|
dir = current;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -769,9 +742,7 @@ bool AnimationState::updateMixingFrom(TrackEntry *to, float delta) {
|
|||||||
|
|
||||||
float AnimationState::applyMixingFrom(TrackEntry *to, Skeleton &skeleton, MixBlend blend) {
|
float AnimationState::applyMixingFrom(TrackEntry *to, Skeleton &skeleton, MixBlend blend) {
|
||||||
TrackEntry *from = to->_mixingFrom;
|
TrackEntry *from = to->_mixingFrom;
|
||||||
if (from->_mixingFrom != NULL) {
|
if (from->_mixingFrom != NULL) applyMixingFrom(from, skeleton, blend);
|
||||||
applyMixingFrom(from, skeleton, blend);
|
|
||||||
}
|
|
||||||
|
|
||||||
float mix;
|
float mix;
|
||||||
if (to->_mixDuration == 0) {
|
if (to->_mixDuration == 0) {
|
||||||
@ -801,9 +772,7 @@ float AnimationState::applyMixingFrom(TrackEntry *to, Skeleton &skeleton, MixBle
|
|||||||
Vector<TrackEntry *> &timelineHoldMix = from->_timelineHoldMix;
|
Vector<TrackEntry *> &timelineHoldMix = from->_timelineHoldMix;
|
||||||
|
|
||||||
bool firstFrame = from->_timelinesRotation.size() == 0;
|
bool firstFrame = from->_timelinesRotation.size() == 0;
|
||||||
if (firstFrame) {
|
if (firstFrame) from->_timelinesRotation.setSize(timelines.size() << 1, 0);
|
||||||
from->_timelinesRotation.setSize(timelines.size() << 1, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector<float> &timelinesRotation = from->_timelinesRotation;
|
Vector<float> &timelinesRotation = from->_timelinesRotation;
|
||||||
|
|
||||||
@ -839,8 +808,7 @@ float AnimationState::applyMixingFrom(TrackEntry *to, Skeleton &skeleton, MixBle
|
|||||||
}
|
}
|
||||||
from->_totalAlpha += alpha;
|
from->_totalAlpha += alpha;
|
||||||
if ((timeline->getRTTI().isExactly(RotateTimeline::rtti))) {
|
if ((timeline->getRTTI().isExactly(RotateTimeline::rtti))) {
|
||||||
applyRotateTimeline((RotateTimeline*)timeline, skeleton, animationTime, alpha, timelineBlend, timelinesRotation, i << 1,
|
applyRotateTimeline((RotateTimeline*)timeline, skeleton, animationTime, alpha, timelineBlend, timelinesRotation, i << 1, firstFrame);
|
||||||
firstFrame);
|
|
||||||
} else {
|
} else {
|
||||||
if (timelineBlend == MixBlend_Setup) {
|
if (timelineBlend == MixBlend_Setup) {
|
||||||
if (timeline->getRTTI().isExactly(AttachmentTimeline::rtti)) {
|
if (timeline->getRTTI().isExactly(AttachmentTimeline::rtti)) {
|
||||||
@ -849,8 +817,7 @@ float AnimationState::applyMixingFrom(TrackEntry *to, Skeleton &skeleton, MixBle
|
|||||||
if (drawOrder) direction = MixDirection_In;
|
if (drawOrder) direction = MixDirection_In;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
timeline->apply(skeleton, animationLast, animationTime, eventBuffer, alpha, timelineBlend,
|
timeline->apply(skeleton, animationLast, animationTime, eventBuffer, alpha, timelineBlend, direction);
|
||||||
direction);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -875,13 +842,8 @@ void AnimationState::queueEvents(TrackEntry *entry, float animationTime) {
|
|||||||
size_t i = 0, n = _events.size();
|
size_t i = 0, n = _events.size();
|
||||||
for (; i < n; ++i) {
|
for (; i < n; ++i) {
|
||||||
Event *e = _events[i];
|
Event *e = _events[i];
|
||||||
if (e->_time < trackLastWrapped) {
|
if (e->_time < trackLastWrapped) break;
|
||||||
break;
|
if (e->_time > animationEnd) continue; // Discard events outside animation start/end.
|
||||||
}
|
|
||||||
if (e->_time > animationEnd) {
|
|
||||||
// Discard events outside animation start/end.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
_queue->event(entry, e);
|
_queue->event(entry, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -896,10 +858,7 @@ void AnimationState::queueEvents(TrackEntry *entry, float animationTime) {
|
|||||||
// Queue events after complete.
|
// Queue events after complete.
|
||||||
for (; i < n; ++i) {
|
for (; i < n; ++i) {
|
||||||
Event *e = _events[i];
|
Event *e = _events[i];
|
||||||
if (e->_time < animationStart) {
|
if (e->_time < animationStart) continue; // Discard events outside animation start/end.
|
||||||
// Discard events outside animation start/end.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
_queue->event(entry, _events[i]);
|
_queue->event(entry, _events[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -909,9 +868,7 @@ void AnimationState::setCurrent(size_t index, TrackEntry *current, bool interrup
|
|||||||
_tracks[index] = current;
|
_tracks[index] = current;
|
||||||
|
|
||||||
if (from != NULL) {
|
if (from != NULL) {
|
||||||
if (interrupt) {
|
if (interrupt) _queue->interrupt(from);
|
||||||
_queue->interrupt(from);
|
|
||||||
}
|
|
||||||
|
|
||||||
current->_mixingFrom = from;
|
current->_mixingFrom = from;
|
||||||
from->_mixingTo = current;
|
from->_mixingTo = current;
|
||||||
@ -929,14 +886,9 @@ void AnimationState::setCurrent(size_t index, TrackEntry *current, bool interrup
|
|||||||
}
|
}
|
||||||
|
|
||||||
TrackEntry *AnimationState::expandToIndex(size_t index) {
|
TrackEntry *AnimationState::expandToIndex(size_t index) {
|
||||||
if (index < _tracks.size()) {
|
if (index < _tracks.size()) return _tracks[index];
|
||||||
return _tracks[index];
|
while (index >= _tracks.size())
|
||||||
}
|
|
||||||
|
|
||||||
while (index >= _tracks.size()) {
|
|
||||||
_tracks.add(NULL);
|
_tracks.add(NULL);
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -989,7 +941,6 @@ void AnimationState::animationsChanged() {
|
|||||||
|
|
||||||
for (size_t i = 0, n = _tracks.size(); i < n; ++i) {
|
for (size_t i = 0, n = _tracks.size(); i < n; ++i) {
|
||||||
TrackEntry *entry = _tracks[i];
|
TrackEntry *entry = _tracks[i];
|
||||||
|
|
||||||
if (!entry) continue;
|
if (!entry) continue;
|
||||||
|
|
||||||
while (entry->_mixingFrom != NULL)
|
while (entry->_mixingFrom != NULL)
|
||||||
@ -1069,21 +1020,17 @@ void AnimationState::computeNotLast(TrackEntry *entry) {
|
|||||||
for (size_t i = 0; i < timelinesCount; i++) {
|
for (size_t i = 0; i < timelinesCount; i++) {
|
||||||
if (timelines[i]->getRTTI().isExactly(AttachmentTimeline::rtti)) {
|
if (timelines[i]->getRTTI().isExactly(AttachmentTimeline::rtti)) {
|
||||||
AttachmentTimeline *timeline = static_cast<AttachmentTimeline *>(timelines[i]);
|
AttachmentTimeline *timeline = static_cast<AttachmentTimeline *>(timelines[i]);
|
||||||
if (!_propertyIDs.contains(timeline->getSlotIndex())) {
|
if (!_propertyIDs.contains(timeline->getSlotIndex()))
|
||||||
_propertyIDs.add(timeline->getSlotIndex());
|
_propertyIDs.add(timeline->getSlotIndex());
|
||||||
} else {
|
else
|
||||||
timelineMode[i] |= NotLast;
|
timelineMode[i] |= NotLast;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AnimationState::hasTimeline(TrackEntry* entry, int inId) {
|
bool AnimationState::hasTimeline(TrackEntry* entry, int inId) {
|
||||||
Vector<Timeline *> &timelines = entry->_animation->_timelines;
|
Vector<Timeline *> &timelines = entry->_animation->_timelines;
|
||||||
for (size_t i = 0, n = timelines.size(); i < n; ++i) {
|
for (size_t i = 0, n = timelines.size(); i < n; ++i)
|
||||||
if (timelines[i]->getPropertyId() == inId) {
|
if (timelines[i]->getPropertyId() == inId) return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -89,12 +89,8 @@ void Atlas::flipV() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
AtlasRegion *Atlas::findRegion(const String &name) {
|
AtlasRegion *Atlas::findRegion(const String &name) {
|
||||||
for (size_t i = 0, n = _regions.size(); i < n; ++i) {
|
for (size_t i = 0, n = _regions.size(); i < n; ++i)
|
||||||
if (_regions[i]->name == name) {
|
if (_regions[i]->name == name) return _regions[i];
|
||||||
return _regions[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -103,11 +99,9 @@ Vector<AtlasPage*> &Atlas::getPages() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Atlas::load(const char *begin, int length, const char *dir, bool createTexture) {
|
void Atlas::load(const char *begin, int length, const char *dir, bool createTexture) {
|
||||||
static const char *formatNames[] = {"", "Alpha", "Intensity", "LuminanceAlpha", "RGB565", "RGBA4444", "RGB888",
|
static const char *formatNames[] = {"", "Alpha", "Intensity", "LuminanceAlpha", "RGB565", "RGBA4444", "RGB888", "RGBA8888"};
|
||||||
"RGBA8888"};
|
static const char *textureFilterNames[] = {"", "Nearest", "Linear", "MipMap", "MipMapNearestNearest", "MipMapLinearNearest",
|
||||||
static const char *textureFilterNames[] = {"", "Nearest", "Linear", "MipMap", "MipMapNearestNearest",
|
"MipMapNearestLinear", "MipMapLinearLinear"};
|
||||||
"MipMapLinearNearest",
|
|
||||||
"MipMapNearestLinear", "MipMapLinearLinear"};
|
|
||||||
|
|
||||||
int count;
|
int count;
|
||||||
const char *end = begin + length;
|
const char *end = begin + length;
|
||||||
@ -125,9 +119,7 @@ void Atlas::load(const char *begin, int length, const char *dir, bool createText
|
|||||||
char *name = mallocString(&str);
|
char *name = mallocString(&str);
|
||||||
char *path = SpineExtension::calloc<char>(dirLength + needsSlash + strlen(name) + 1, __FILE__, __LINE__);
|
char *path = SpineExtension::calloc<char>(dirLength + needsSlash + strlen(name) + 1, __FILE__, __LINE__);
|
||||||
memcpy(path, dir, dirLength);
|
memcpy(path, dir, dirLength);
|
||||||
if (needsSlash) {
|
if (needsSlash) path[dirLength] = '/';
|
||||||
path[dirLength] = '/';
|
|
||||||
}
|
|
||||||
strcpy(path + dirLength + needsSlash, name);
|
strcpy(path + dirLength + needsSlash, name);
|
||||||
|
|
||||||
page = new(__FILE__, __LINE__) AtlasPage(String(name, true));
|
page = new(__FILE__, __LINE__) AtlasPage(String(name, true));
|
||||||
@ -163,15 +155,11 @@ void Atlas::load(const char *begin, int length, const char *dir, bool createText
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (createTexture)
|
if (createTexture) {
|
||||||
{
|
|
||||||
if (_textureLoader) _textureLoader->load(*page, String(path));
|
if (_textureLoader) _textureLoader->load(*page, String(path));
|
||||||
SpineExtension::free(path, __FILE__, __LINE__);
|
SpineExtension::free(path, __FILE__, __LINE__);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
{
|
|
||||||
page->texturePath = String(path, true);
|
page->texturePath = String(path, true);
|
||||||
}
|
|
||||||
|
|
||||||
_pages.add(page);
|
_pages.add(page);
|
||||||
} else {
|
} else {
|
||||||
@ -181,13 +169,9 @@ void Atlas::load(const char *begin, int length, const char *dir, bool createText
|
|||||||
region->name = String(mallocString(&str), true);
|
region->name = String(mallocString(&str), true);
|
||||||
|
|
||||||
readValue(&begin, end, &str);
|
readValue(&begin, end, &str);
|
||||||
if (equals(&str, "true")) {
|
if (equals(&str, "true")) region->degrees = 90;
|
||||||
region->degrees = 90;
|
else if (equals(&str, "false")) region->degrees = 0;
|
||||||
} else if (equals(&str, "false")) {
|
else region->degrees = toInt(&str);
|
||||||
region->degrees = 0;
|
|
||||||
} else {
|
|
||||||
region->degrees = toInt(&str);
|
|
||||||
}
|
|
||||||
region->rotate = region->degrees == 90;
|
region->rotate = region->degrees == 90;
|
||||||
|
|
||||||
readTuple(&begin, end, tuple);
|
readTuple(&begin, end, tuple);
|
||||||
@ -251,41 +235,32 @@ void Atlas::load(const char *begin, int length, const char *dir, bool createText
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Atlas::trim(Str *str) {
|
void Atlas::trim(Str *str) {
|
||||||
while (isspace((unsigned char) *str->begin) && str->begin < str->end) {
|
while (isspace((unsigned char) *str->begin) && str->begin < str->end)
|
||||||
(str->begin)++;
|
(str->begin)++;
|
||||||
}
|
|
||||||
|
|
||||||
if (str->begin == str->end) {
|
if (str->begin == str->end) return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
str->end--;
|
str->end--;
|
||||||
|
|
||||||
while (((unsigned char)*str->end == '\r') && str->end >= str->begin) {
|
while (((unsigned char)*str->end == '\r') && str->end >= str->begin)
|
||||||
str->end--;
|
str->end--;
|
||||||
}
|
|
||||||
|
|
||||||
str->end++;
|
str->end++;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Atlas::readLine(const char **begin, const char *end, Str *str) {
|
int Atlas::readLine(const char **begin, const char *end, Str *str) {
|
||||||
if (*begin == end) {
|
if (*begin == end) return 0;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
str->begin = *begin;
|
str->begin = *begin;
|
||||||
|
|
||||||
/* Find next delimiter. */
|
/* Find next delimiter. */
|
||||||
while (*begin != end && **begin != '\n') {
|
while (*begin != end && **begin != '\n')
|
||||||
(*begin)++;
|
(*begin)++;
|
||||||
}
|
|
||||||
|
|
||||||
str->end = *begin;
|
str->end = *begin;
|
||||||
trim(str);
|
trim(str);
|
||||||
|
|
||||||
if (*begin != end) {
|
if (*begin != end) (*begin)++;
|
||||||
(*begin)++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -294,13 +269,9 @@ int Atlas::beginPast(Str *str, char c) {
|
|||||||
const char *begin = str->begin;
|
const char *begin = str->begin;
|
||||||
while (true) {
|
while (true) {
|
||||||
char lastSkippedChar = *begin;
|
char lastSkippedChar = *begin;
|
||||||
if (begin == str->end) {
|
if (begin == str->end) return 0;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
begin++;
|
begin++;
|
||||||
if (lastSkippedChar == c) {
|
if (lastSkippedChar == c) break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
str->begin = begin;
|
str->begin = begin;
|
||||||
return 1;
|
return 1;
|
||||||
@ -308,10 +279,7 @@ int Atlas::beginPast(Str *str, char c) {
|
|||||||
|
|
||||||
int Atlas::readValue(const char **begin, const char *end, Str *str) {
|
int Atlas::readValue(const char **begin, const char *end, Str *str) {
|
||||||
readLine(begin, end, str);
|
readLine(begin, end, str);
|
||||||
if (!beginPast(str, ':')) {
|
if (!beginPast(str, ':')) return 0;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
trim(str);
|
trim(str);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -320,16 +288,11 @@ int Atlas::readTuple(const char **begin, const char *end, Str tuple[]) {
|
|||||||
int i;
|
int i;
|
||||||
Str str = {NULL, NULL};
|
Str str = {NULL, NULL};
|
||||||
readLine(begin, end, &str);
|
readLine(begin, end, &str);
|
||||||
if (!beginPast(&str, ':')) {
|
if (!beginPast(&str, ':')) return 0;
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < 3; ++i) {
|
for (i = 0; i < 3; ++i) {
|
||||||
tuple[i].begin = str.begin;
|
tuple[i].begin = str.begin;
|
||||||
if (!beginPast(&str, ',')) {
|
if (!beginPast(&str, ',')) break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
tuple[i].end = str.begin - 2;
|
tuple[i].end = str.begin - 2;
|
||||||
trim(&tuple[i]);
|
trim(&tuple[i]);
|
||||||
}
|
}
|
||||||
@ -352,11 +315,8 @@ char *Atlas::mallocString(Str *str) {
|
|||||||
int Atlas::indexOf(const char **array, int count, Str *str) {
|
int Atlas::indexOf(const char **array, int count, Str *str) {
|
||||||
int length = (int) (str->end - str->begin);
|
int length = (int) (str->end - str->begin);
|
||||||
int i;
|
int i;
|
||||||
for (i = count - 1; i >= 0; i--) {
|
for (i = count - 1; i >= 0; i--)
|
||||||
if (strncmp(array[i], str->begin, length) == 0) {
|
if (strncmp(array[i], str->begin, length) == 0) return i;
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -100,7 +100,7 @@ MeshAttachment *AtlasAttachmentLoader::newMeshAttachment(Skin &skin, const Strin
|
|||||||
|
|
||||||
BoundingBoxAttachment *AtlasAttachmentLoader::newBoundingBoxAttachment(Skin &skin, const String &name) {
|
BoundingBoxAttachment *AtlasAttachmentLoader::newBoundingBoxAttachment(Skin &skin, const String &name) {
|
||||||
SP_UNUSED(skin);
|
SP_UNUSED(skin);
|
||||||
return new(__FILE__, __LINE__) BoundingBoxAttachment(name);
|
return new(__FILE__, __LINE__) BoundingBoxAttachment(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
PathAttachment *AtlasAttachmentLoader::newPathAttachment(Skin &skin, const String &name) {
|
PathAttachment *AtlasAttachmentLoader::newPathAttachment(Skin &skin, const String &name) {
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user