Browse Source

[lua] Tiny fix in Animation

badlogic 9 năm trước cách đây
mục cha
commit
7c8f38a821

+ 25 - 25
spine-c/include/spine/AnimationState.h

@@ -44,40 +44,45 @@ typedef enum {
 } spEventType;
 
 typedef struct spAnimationState spAnimationState;
+typedef struct spTrackEntry spTrackEntry;
 
-typedef void (*spAnimationStateListener) (spAnimationState* state, int trackIndex, spEventType type, spEvent* event,
-		int loopCount);
+typedef void (*spAnimationStateListener) (spAnimationState* state, spEventType type, spTrackEntry* entry, spEvent* event);
 
-typedef struct spTrackEntry spTrackEntry;
 struct spTrackEntry {
-	spAnimationState* const state;
-	spTrackEntry* next;
-	spTrackEntry* previous;
 	spAnimation* animation;
-	int/*bool*/loop;
-	float delay, time, lastTime, endTime, timeScale;
+	spTrackEntry* next;
+	spTrackEntry* mixingFrom;
 	spAnimationStateListener listener;
-	float mixTime, mixDuration, mix;
-
-	void* rendererObject;
+	int trackIndex;
+	int /*boolean*/ loop;
+	float eventThreshold, attachmentThreshold, drawOrderThreshold;
+	float animationStart, animationEnd, animationLast, nextAnimationLast;
+	float delay, trackTime, trackLast, nextTrackLast, trackEnd, timeScale;
+	float alpha, mixTime, mixDuration, mixAlpha;
+	int* /*boolean*/ timelinesFirst;
+	int timelinesFirstCount;
+	float* timelinesRotation;
+	int timelinesRotationCount;
 
 #ifdef __cplusplus
 	spTrackEntry() :
-		state(0),
-		next(0),
-		previous(0),
 		animation(0),
-		loop(0),
-		delay(0), time(0), lastTime(0), endTime(0), timeScale(0),
+		next(0), mixingFrom(0),
 		listener(0),
-		mixTime(0), mixDuration(0), mix(0),
-		rendererObject(0) {
+		trackIndex(0),
+		loop(0),
+		eventThreshold(0), attachmentThreshold(0), drawOrderThreshold(0),
+		animationStart(0), animationEnd(0), animationLast(0), nextAnimationLast(0),
+		delay(0), trackTime(0), trackLast(0), nextTrackLast(0), trackEnd(0), timeScale(0),
+		alpha(0), mixTime(0), mixDuration(0), mixAlpha(0),
+		timelinesFirst(0),
+		timelinesFirstCount(0),
+		timelinesRotation(0),
+		timelinesRotationCount(0) {
 	}
 #endif
 };
 
-typedef struct spEventQueue spEventQueue;
-
 struct spAnimationState {
 	spAnimationStateData* const data;
 
@@ -93,12 +98,7 @@ struct spAnimationState {
 		data(0),
 		tracks(0),
 		tracksCount(0),
-		events(0),
-		eventsCount(0),
 		listener(0),
-		queue(0),
-		propertyIDs(0),
-		animationsChanged(0),
 		timeScale(0) {
 	}
 #endif

+ 25 - 9
spine-c/include/spine/extension.h

@@ -171,21 +171,41 @@ char* _readFile (const char* path, int* length);
 
 /**/
 
+typedef union _spEventQueueItem {
+	int type;
+	spTrackEntry* entry;
+	spEvent* event;
+} _spEventQueueItem;
+
+typedef struct _spEventQueue {
+	spAnimationState* state;
+	_spEventQueueItem* objects;
+	int objectsCount;
+	int objectsCapacity;
+	int /*boolean*/ drainDisabled;
+
+#ifdef __cplusplus
+	_spEventQueue() :
+		state(0),
+		objects(0),
+		objectsCount(0),
+		drainDisabled(0) {
+	}
+#endif
+} _spEventQueue;
+
 typedef struct _spAnimationState {
 	spAnimationState super;
 
 	int eventsCount;
 	spEvent** events;
 
-	spEventQueue* queue;
+	_spEventQueue* queue;
 
 	void* propertyIDs;
 
 	int /*boolean*/ animationsChanged;
 
-	spTrackEntry* (*createTrackEntry) (spAnimationState* self);
-	void (*disposeTrackEntry) (spTrackEntry* entry);
-
 #ifdef __cplusplus
 	_spAnimationState() :
 		super(),
@@ -193,15 +213,11 @@ typedef struct _spAnimationState {
 		events(0),
 		queue(0),
 		propertyIDs(0),
-		animationsChanged(0),
-		createTrackEntry(0),
-		disposeTrackEntry(0) {
+		animationsChanged(0) {
 	}
 #endif
 } _spAnimationState;
 
-spTrackEntry* _spTrackEntry_create (spAnimationState* self);
-void _spTrackEntry_dispose (spTrackEntry* self);
 
 /**/
 

+ 70 - 257
spine-c/src/spine/AnimationState.c

@@ -32,291 +32,104 @@
 #include <spine/extension.h>
 #include <string.h>
 
-spTrackEntry* _spTrackEntry_create (spAnimationState* state) {
-	spTrackEntry* self = NEW(spTrackEntry);
-	CONST_CAST(spAnimationState*, self->state) = state;
-	self->timeScale = 1;
-	self->lastTime = -1;
-	self->mix = 1;
+_spEventQueue* _spEventQueue_create (spAnimationState* state) {
+	_spEventQueue *self = MALLOC(_spEventQueue, 1);
+	self->state = state;
+	self->objectsCount = 0;
+	self->objectsCapacity = 16;
+	self->objects = MALLOC(_spEventQueueItem, self->objectsCapacity * sizeof(_spEventQueueItem));
+	self->drainDisabled = 0;
 	return self;
 }
 
-void _spTrackEntry_dispose (spTrackEntry* self) {
-	if (self->previous) SUB_CAST(_spAnimationState, self->state)->disposeTrackEntry(self->previous);
-	FREE(self);
+void _spEventQueue_free (_spEventQueue* self) {
+	if (!self) return;
+	if (self->objects) FREE(self->objects);
 }
 
-/**/
-
-spTrackEntry* _spAnimationState_createTrackEntry (spAnimationState* self) {
-	return _spTrackEntry_create(self);
-}
-
-void _spAnimationState_disposeTrackEntry (spTrackEntry* entry) {
-	_spTrackEntry_dispose(entry);
-}
-
-spAnimationState* spAnimationState_create (spAnimationStateData* data) {
-	_spAnimationState* internal = NEW(_spAnimationState);
-	spAnimationState* self = SUPER(internal);
-	internal->events = MALLOC(spEvent*, 64);
-	self->timeScale = 1;
-	CONST_CAST(spAnimationStateData*, self->data) = data;
-	internal->createTrackEntry = _spAnimationState_createTrackEntry;
-	internal->disposeTrackEntry = _spAnimationState_disposeTrackEntry;
-	return self;
-}
-
-void _spAnimationState_disposeAllEntries (spAnimationState* self, spTrackEntry* entry) {
-	_spAnimationState* internal = SUB_CAST(_spAnimationState, self);
-	while (entry) {
-		spTrackEntry* next = entry->next;
-		internal->disposeTrackEntry(entry);
-		entry = next;
+void _spEventQueue_ensureCapacity (_spEventQueue* self, int newElements) {
+	if (self->objectsCount + newElements > self->objectsCapacity) {
+		_spEventQueueItem* newObjects;
+		self->objectsCapacity <<= 1;
+		newObjects = MALLOC(_spEventQueueItem, self->objectsCapacity);
+		memcpy(newObjects, self->objects, self->objectsCount * sizeof(_spEventQueueItem));
+		FREE(self->objects);
+		self->objects = newObjects;
 	}
 }
 
-void spAnimationState_dispose (spAnimationState* self) {
-	int i;
-	_spAnimationState* internal = SUB_CAST(_spAnimationState, self);
-	FREE(internal->events);
-	for (i = 0; i < self->tracksCount; ++i)
-		_spAnimationState_disposeAllEntries(self, self->tracks[i]);
-	FREE(self->tracks);
-	FREE(self);
+void _spEventQueue_addType (_spEventQueue* self, spEventType type) {
+	_spEventQueue_ensureCapacity(self, 1);
+	self->objects[self->objectsCount++].type = type;
 }
 
-void _spAnimationState_setCurrent (spAnimationState* self, int index, spTrackEntry* entry);
-
-void spAnimationState_update (spAnimationState* self, float delta) {
-	int i;
-	float previousDelta;
-	delta *= self->timeScale;
-	for (i = 0; i < self->tracksCount; ++i) {
-		spTrackEntry* current = self->tracks[i];
-		if (!current) continue;
-
-		current->time += delta * current->timeScale;
-		if (current->previous) {
-			previousDelta = delta * current->previous->timeScale;
-			current->previous->time += previousDelta;
-			current->mixTime += previousDelta;
-		}
-
-		if (current->next) {
-			current->next->time = current->lastTime - current->next->delay;
-			if (current->next->time >= 0) _spAnimationState_setCurrent(self, i, current->next);
-		} else {
-			/* End non-looping animation when it reaches its end time and there is no next entry. */
-			if (!current->loop && current->lastTime >= current->endTime) spAnimationState_clearTrack(self, i);
-		}
-	}
+void _spEventQueue_addEntry (_spEventQueue* self, spTrackEntry* entry) {
+	_spEventQueue_ensureCapacity(self, 1);
+	self->objects[self->objectsCount++].entry = entry;
 }
 
-void spAnimationState_apply (spAnimationState* self, spSkeleton* skeleton) {
-	_spAnimationState* internal = SUB_CAST(_spAnimationState, self);
-
-	int i, ii;
-	int eventsCount;
-	int entryChanged;
-	float time;
-	spTrackEntry* previous;
-	for (i = 0; i < self->tracksCount; ++i) {
-		spTrackEntry* current = self->tracks[i];
-		if (!current) continue;
-
-		eventsCount = 0;
-
-		time = current->time;
-		if (!current->loop && time > current->endTime) time = current->endTime;
-
-		previous = current->previous;
-		if (!previous) {
-			if (current->mix == 1) {
-				spAnimation_apply(current->animation, skeleton, current->lastTime, time,
-					current->loop, internal->events, &eventsCount);
-			} else {
-				spAnimation_mix(current->animation, skeleton, current->lastTime, time,
-					current->loop, internal->events, &eventsCount, current->mix);
-			}
-		} else {
-			float alpha = current->mixTime / current->mixDuration * current->mix;
-
-			float previousTime = previous->time;
-			if (!previous->loop && previousTime > previous->endTime) previousTime = previous->endTime;
-			spAnimation_apply(previous->animation, skeleton, previousTime, previousTime, previous->loop, 0, 0);
-
-			if (alpha >= 1) {
-				alpha = 1;
-				internal->disposeTrackEntry(current->previous);
-				current->previous = 0;
-			}
-			spAnimation_mix(current->animation, skeleton, current->lastTime, time,
-				current->loop, internal->events, &eventsCount, alpha);
-		}
-
-		entryChanged = 0;
-		for (ii = 0; ii < eventsCount; ++ii) {
-			spEvent* event = internal->events[ii];
-			if (current->listener) {
-				current->listener(self, i, SP_ANIMATION_EVENT, event, 0);
-				if (self->tracks[i] != current) {
-					entryChanged = 1;
-					break;
-				}
-			}
-			if (self->listener) {
-				self->listener(self, i, SP_ANIMATION_EVENT, event, 0);
-				if (self->tracks[i] != current) {
-					entryChanged = 1;
-					break;
-				}
-			}
-		}
-		if (entryChanged) continue;
-
-		/* Check if completed the animation or a loop iteration. */
-		if (current->loop ? (FMOD(current->lastTime, current->endTime) > FMOD(time, current->endTime))
-				: (current->lastTime < current->endTime && time >= current->endTime)) {
-			int count = (int)(time / current->endTime);
-			if (current->listener) {
-				current->listener(self, i, SP_ANIMATION_COMPLETE, 0, count);
-				if (self->tracks[i] != current) continue;
-			}
-			if (self->listener) {
-				self->listener(self, i, SP_ANIMATION_COMPLETE, 0, count);
-				if (self->tracks[i] != current) continue;
-			}
-		}
-
-		current->lastTime = current->time;
-	}
+void _spEventQueue_addEvent (_spEventQueue* self, spEvent* event) {
+	_spEventQueue_ensureCapacity(self, 1);
+	self->objects[self->objectsCount++].event = event;
 }
 
-void spAnimationState_clearTracks (spAnimationState* self) {
-	int i;
-	for (i = 0; i < self->tracksCount; ++i)
-		spAnimationState_clearTrack(self, i);
-	self->tracksCount = 0;
+void _spEventQueue_start (_spEventQueue* self, spTrackEntry* entry) {
+	_spAnimationState* internalState = (_spAnimationState*)self->state;
+	_spEventQueue_addType(self, SP_ANIMATION_START);
+	_spEventQueue_addEntry(self, entry);
+	internalState->animationsChanged = 1;
 }
 
-void spAnimationState_clearTrack (spAnimationState* self, int trackIndex) {
-	spTrackEntry* current;
-	if (trackIndex >= self->tracksCount) return;
-	current = self->tracks[trackIndex];
-	if (!current) return;
-
-	if (current->listener) current->listener(self, trackIndex, SP_ANIMATION_END, 0, 0);
-	if (self->listener) self->listener(self, trackIndex, SP_ANIMATION_END, 0, 0);
-
-	self->tracks[trackIndex] = 0;
-
-	_spAnimationState_disposeAllEntries(self, current);
+void _spEventQueue_interrupt (_spEventQueue* self, spTrackEntry* entry) {
+	_spEventQueue_addType(self, SP_ANIMATION_INTERRUPT);
+	_spEventQueue_addEntry(self, entry);
 }
 
-spTrackEntry* _spAnimationState_expandToIndex (spAnimationState* self, int index) {
-	spTrackEntry** newTracks;
-	if (index < self->tracksCount) return self->tracks[index];
-	newTracks = CALLOC(spTrackEntry*, index + 1);
-	memcpy(newTracks, self->tracks, self->tracksCount * sizeof(spTrackEntry*));
-	FREE(self->tracks);
-	self->tracks = newTracks;
-	self->tracksCount = index + 1;
-	return 0;
+void _spEventQueue_end (_spEventQueue* self, spTrackEntry* entry) {
+	_spAnimationState* internalState = (_spAnimationState*)self->state;
+	_spEventQueue_addType(self, SP_ANIMATION_END);
+	_spEventQueue_addEntry(self, entry);
+	internalState->animationsChanged = 1;
 }
 
-void _spAnimationState_setCurrent (spAnimationState* self, int index, spTrackEntry* entry) {
-	_spAnimationState* internal = SUB_CAST(_spAnimationState, self);
-
-	spTrackEntry* current = _spAnimationState_expandToIndex(self, index);
-	if (current) {
-		spTrackEntry* previous = current->previous;
-		current->previous = 0;
-
-		if (current->listener) current->listener(self, index, SP_ANIMATION_END, 0, 0);
-		if (self->listener) self->listener(self, index, SP_ANIMATION_END, 0, 0);
-
-		entry->mixDuration = spAnimationStateData_getMix(self->data, current->animation, entry->animation);
-		if (entry->mixDuration > 0) {
-			entry->mixTime = 0;
-			/* If a mix is in progress, mix from the closest animation. */
-			if (previous && current->mixTime / current->mixDuration < 0.5f) {
-				entry->previous = previous;
-				previous = current;
-			} else
-				entry->previous = current;
-		} else
-			internal->disposeTrackEntry(current);
-
-		if (previous) internal->disposeTrackEntry(previous);
-	}
-
-	self->tracks[index] = entry;
-
-	if (entry->listener) {
-		entry->listener(self, index, SP_ANIMATION_START, 0, 0);
-		if (self->tracks[index] != entry) return;
-	}
-	if (self->listener) self->listener(self, index, SP_ANIMATION_START, 0, 0);
+void _spEventQueue_dispose (_spEventQueue* self, spTrackEntry* entry) {
+	_spEventQueue_addType(self, SP_ANIMATION_DISPOSE);
+	_spEventQueue_addEntry(self, entry);
 }
 
-spTrackEntry* spAnimationState_setAnimationByName (spAnimationState* self, int trackIndex, const char* animationName,
-		int/*bool*/loop) {
-	spAnimation* animation = spSkeletonData_findAnimation(self->data->skeletonData, animationName);
-	return spAnimationState_setAnimation(self, trackIndex, animation, loop);
+void _spEventQueue_complete (_spEventQueue* self, spTrackEntry* entry) {
+	_spEventQueue_addType(self, SP_ANIMATION_COMPLETE);
+	_spEventQueue_addEntry(self, entry);
 }
 
-spTrackEntry* spAnimationState_setAnimation (spAnimationState* self, int trackIndex, spAnimation* animation, int/*bool*/loop) {
-	_spAnimationState* internal = SUB_CAST(_spAnimationState, self);
-
-	spTrackEntry* entry;
-	spTrackEntry* current = _spAnimationState_expandToIndex(self, trackIndex);
-	if (current) _spAnimationState_disposeAllEntries(self, current->next);
-
-	entry = internal->createTrackEntry(self);
-	entry->animation = animation;
-	entry->loop = loop;
-	entry->endTime = animation->duration;
-	_spAnimationState_setCurrent(self, trackIndex, entry);
-	return entry;
+void _spEventQueue_event (_spEventQueue* self, spTrackEntry* entry, spEvent* event) {
+	_spEventQueue_addType(self, SP_ANIMATION_EVENT);
+	_spEventQueue_addEntry(self, entry);
+	_spEventQueue_addEvent(self, event);
 }
 
-spTrackEntry* spAnimationState_addAnimationByName (spAnimationState* self, int trackIndex, const char* animationName,
-		int/*bool*/loop, float delay) {
-	spAnimation* animation = spSkeletonData_findAnimation(self->data->skeletonData, animationName);
-	return spAnimationState_addAnimation(self, trackIndex, animation, loop, delay);
+void _spEventQueue_clear (_spEventQueue* self) {
+	self->objectsCount = 0;
 }
 
-spTrackEntry* spAnimationState_addAnimation (spAnimationState* self, int trackIndex, spAnimation* animation, int/*bool*/loop,
-		float delay) {
-	_spAnimationState* internal = SUB_CAST(_spAnimationState, self);
-	spTrackEntry* last;
-
-	spTrackEntry* entry = internal->createTrackEntry(self);
-	entry->animation = animation;
-	entry->loop = loop;
-	entry->endTime = animation->duration;
-
-	last = _spAnimationState_expandToIndex(self, trackIndex);
-	if (last) {
-		while (last->next)
-			last = last->next;
-		last->next = entry;
-	} else
-		self->tracks[trackIndex] = entry;
-
-	if (delay <= 0) {
-		if (last)
-			delay += last->endTime - spAnimationStateData_getMix(self->data, last->animation, animation);
-		else
-			delay = 0;
+void _spEventQueue_drain (_spEventQueue* self) {
+	int i;
+	if (self->drainDisabled) return;
+	self->drainDisabled = 1;
+	for (i = 0; i < self->objectsCount; i += 2) {
+		spEventType type = self->objects[i].type;
+		spTrackEntry* entry = self->objects[i+1].entry;
+		if (type != SP_ANIMATION_EVENT) {
+			if (entry->listener) entry->listener(self->state, type, entry, 0);
+			if (self->state->listener) self->state->listener(self->state, type, entry, 0);
+		} else {
+			spEvent* event = self->objects[i+2].event;
+			if (entry->listener) entry->listener(self->state, type, entry, event);
+			if (self->state->listener) self->state->listener(self->state, type, entry, event);
+			i++;
+		}
 	}
-	entry->delay = delay;
-
-	return entry;
-}
 
-spTrackEntry* spAnimationState_getCurrent (spAnimationState* self, int trackIndex) {
-	if (trackIndex >= self->tracksCount) return 0;
-	return self->tracks[trackIndex];
+	_spEventQueue_clear(self);
+	self->drainDisabled = 0;
 }

+ 1 - 1
spine-lua/Animation.lua

@@ -522,7 +522,7 @@ function Animation.ColorTimeline.new (frameCount)
 		local slot = skeleton.slots[self.slotIndex]
 		if time < frames[0] then 
 			if setupPose then
-				slot.color.setFromt(slot.data.color)
+				slot.color:setFrom(slot.data.color)
 			end
 			return
 		end

+ 9 - 6
spine-sfml/example/main.cpp

@@ -39,22 +39,25 @@ using namespace spine;
 #include <stdio.h>
 #include <stdlib.h>
 
-void callback (AnimationState* state, int trackIndex, EventType type, Event* event, int loopCount) {
-	TrackEntry* entry = AnimationState_getCurrent(state, trackIndex);
+void callback (AnimationState* state, EventType type, TrackEntry* entry, Event* event) {
 	const char* animationName = (entry && entry->animation) ? entry->animation->name : 0;
 
 	switch (type) {
 	case ANIMATION_START:
-		printf("%d start: %s\n", trackIndex, animationName);
+		printf("%d start: %s\n", entry->trackIndex, animationName);
 		break;
+	case ANIMATION_INTERRUPT:
+		printf("%d interrupt: %s\n", entry->trackIndex, animationName);
 	case ANIMATION_END:
-		printf("%d end: %s\n", trackIndex, animationName);
+		printf("%d end: %s\n", entry->trackIndex, animationName);
 		break;
 	case ANIMATION_COMPLETE:
-		printf("%d complete: %s, %d\n", trackIndex, animationName, loopCount);
+		printf("%d complete: %s\n", entry->trackIndex, animationName);
 		break;
+	case ANIMATION_DISPOSE:
+		printf("%d dispose: %s\n", entry->trackIndex, animationName);
 	case ANIMATION_EVENT:
-		printf("%d event: %s, %s: %d, %f, %s\n", trackIndex, animationName, event->data->name, event->intValue, event->floatValue,
+		printf("%d event: %s, %s: %d, %f, %s\n", entry->trackIndex, animationName, event->data->name, event->intValue, event->floatValue,
 				event->stringValue);
 		break;
 	}