void Skeleton::add_animation(int track, const char* animation, bool loop, float delay) { spAnimationState_addAnimationByName(state_, track, animation, loop, delay); }
static void testRunner(const char* jsonName, const char* atlasName) { /////////////////////////////////////////////////////////////////////////// // Global Animation Information spAtlas* atlas = spAtlas_createFromFile(atlasName, 0); ASSERT(atlas != 0); spSkeletonData* skeletonData = readSkeletonJsonData(jsonName, atlas); ASSERT(skeletonData != 0); spAnimationStateData* stateData = spAnimationStateData_create(skeletonData); ASSERT(stateData != 0); stateData->defaultMix = 0.2f; // force mixing /////////////////////////////////////////////////////////////////////////// // Animation Instance spSkeleton* skeleton = spSkeleton_create(skeletonData); ASSERT(skeleton != 0); spAnimationState* state = spAnimationState_create(stateData); ASSERT(state != 0); /////////////////////////////////////////////////////////////////////////// // Run animation spSkeleton_setToSetupPose(skeleton); SpineEventMonitor eventMonitor(state); // eventMonitor.SetDebugLogging(true); AnimList anims; // Let's chain all the animations together as a test size_t count = enumerateAnimations(anims, skeletonData); if (count > 0) spAnimationState_setAnimationByName(state, 0, anims[0].c_str(), false); for (size_t i = 1; i < count; ++i) { spAnimationState_addAnimationByName(state, 0, anims[i].c_str(), false, 0.0f); } // Run Loop for (int i = 0; i < MAX_RUN_TIME && eventMonitor.isAnimationPlaying(); ++i) { const float timeSlice = 1.0f / 60.0f; spSkeleton_update(skeleton, timeSlice); spAnimationState_update(state, timeSlice); spAnimationState_apply(state, skeleton); } /////////////////////////////////////////////////////////////////////////// // Dispose Instance spSkeleton_dispose(skeleton); spAnimationState_dispose(state); /////////////////////////////////////////////////////////////////////////// // Dispose Global spAnimationStateData_dispose(stateData); spSkeletonData_dispose(skeletonData); spAtlas_dispose(atlas); }
////////////////////////////////////////////////////////////////////////// // Reproduce Memory leak as described in Issue #776 // https://github.com/EsotericSoftware/spine-runtimes/issues/776 void MemoryTestFixture::reproduceIssue_776() { spAtlas* atlas = nullptr; spSkeletonData* skeletonData = nullptr; spAnimationStateData* stateData = nullptr; spSkeleton* skeleton = nullptr; spAnimationState* state = nullptr; ////////////////////////////////////////////////////////////////////////// // Initialize Animations LoadSpineboyExample(atlas, skeletonData, stateData, skeleton, state); /////////////////////////////////////////////////////////////////////////// // Run animation spSkeleton_setToSetupPose(skeleton); InterruptMonitor eventMonitor(state); //eventMonitor.SetDebugLogging(true); // Interrupt the animation on this specific sequence of spEventType(s) eventMonitor .AddInterruptEvent(SP_ANIMATION_INTERRUPT, "jump") .AddInterruptEvent(SP_ANIMATION_START); spAnimationState_setAnimationByName(state, 0, "walk", true); spAnimationState_addAnimationByName(state, 0, "jump", false, 0.0f); spAnimationState_addAnimationByName(state, 0, "run", true, 0.0f); spAnimationState_addAnimationByName(state, 0, "jump", false, 3.0f); spAnimationState_addAnimationByName(state, 0, "walk", true, 0.0f); spAnimationState_addAnimationByName(state, 0, "idle", false, 1.0f); for (int i = 0; i < MAX_RUN_TIME && eventMonitor.isAnimationPlaying(); ++i) { const float timeSlice = 1.0f / 60.0f; spSkeleton_update(skeleton, timeSlice); spAnimationState_update(state, timeSlice); spAnimationState_apply(state, skeleton); } ////////////////////////////////////////////////////////////////////////// // Cleanup Animations DisposeAll(skeleton, state, stateData, skeletonData, atlas); }
UTrackEntry* USpineSkeletonAnimationComponent::AddAnimation (int trackIndex, FString animationName, bool loop, float delay) { CheckState(); if (state && spSkeletonData_findAnimation(skeleton->data, TCHAR_TO_UTF8(*animationName))) { _spAnimationState_disableQueue(state); spTrackEntry* entry = spAnimationState_addAnimationByName(state, trackIndex, TCHAR_TO_UTF8(*animationName), loop ? 1 : 0, delay); _spAnimationState_enableQueue(state); UTrackEntry* uEntry = NewObject<UTrackEntry>(); uEntry->SetTrackEntry(entry); trackEntries.Add(uEntry); return uEntry; } else return NewObject<UTrackEntry>(); }