void SkeletonAnimationFbo::setToSetupPose() { if (!isSkeletonValid()){ qDebug()<<"SkeletonAnimation::setToSetupPose Error: Skeleton is not ready"; return; } spSkeleton_setToSetupPose(mspSkeleton); }
WIPAnimator::WIPAnimator(const char* atlas_path,const char* json_path,i32 w,i32 h):time_scale(1) { _out_buffer = WIPRenderTexture::create(w,h); _frame_ref = 0; spAtlas* atlas = spAtlas_createFromFile(atlas_path, 0); spSkeletonJson* json = spSkeletonJson_create(atlas); json->scale = 0.8f; spSkeletonData *skeletonData = spSkeletonJson_readSkeletonDataFile(json, json_path); if (!skeletonData) { printf("Error: %s\n", json->error); getchar(); exit(0); } //spAnimation* walkAnimation = spSkeletonData_findAnimation(skeletonData, "walk"); spSkeletonJson_dispose(json); spSkeletonBounds* bounds = spSkeletonBounds_create(); spAnimationStateData* stateData = spAnimationStateData_create(skeletonData); //spAnimationStateData_setMixByName(stateData, "walk", "jump", 0.2f); //spAnimationStateData_setMixByName(stateData, "jump", "run", 0.2f); //spAnimationStateData_setMixByName(stateData, "shoot", "walk", 0.2f); //drawable = new SkeletonDrawable(skeletonData,stateData); spBone_setYDown(true); skeleton = spSkeleton_create(skeletonData); state = spAnimationState_create(stateData); time_scale = 1; //spSkeleton* skeleton = drawable->skeleton; skeleton->flipX = false; skeleton->flipY = false; //spSkeleton_setSkinByName(skeleton, "goblin"); spSkeleton_setToSetupPose(skeleton); skeleton->x = 0; skeleton->y = 0; spSkeleton_updateWorldTransform(skeleton); spSlot* headSlot = spSkeleton_findSlot(skeleton, "head"); state->listener = callback; if (false) { spAnimationState_setAnimationByName(state, 0, "test", true); } else { spAnimationState_setAnimationByName(state, 0, "flying", true); /* spAnimationState_addAnimationByName(drawable->state, 0, "jump", false, 3); spAnimationState_addAnimationByName(drawable->state, 0, "run", true, 0); spAnimationState_addAnimationByName(drawable->state,0,"shoot",true,3); spAnimationState_addAnimationByName(drawable->state, 0, "walk", true,3); */ } //spAnimationState_setAnimation(drawable->state, 0, walkAnimation, false); //drawable->bounds = bounds; }
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); }
Skeleton::Skeleton(spSkeletonData* data, spAtlas* atlas) : skeleton_(nullptr), state_(nullptr), time_scale_(1.0f), num_vertices_(0), texture_(nullptr), max_vertices_(0), animation_data_(nullptr), atlas_(atlas), data_(data) { skeleton_ = spSkeleton_create(data); spSkeleton_setToSetupPose(skeleton_); animation_data_ = spAnimationStateData_create(data); state_ = spAnimationState_create(animation_data_); array_.reconfigure([this] { vertex_buffer_.bind(); }); }
void MemoryTestFixture::reproduceIssue_777() { 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); SpineEventMonitor eventMonitor(state); //eventMonitor.SetDebugLogging(true); // Set Animation and Play for 5 frames spAnimationState_setAnimationByName(state, 0, "walk", true); for (int i = 0; i < 5; ++i) { const float timeSlice = 1.0f / 60.0f; spSkeleton_update(skeleton, timeSlice); spAnimationState_update(state, timeSlice); spAnimationState_apply(state, skeleton); } // Change animation twice in a row spAnimationState_setAnimationByName(state, 0, "walk", false); spAnimationState_setAnimationByName(state, 0, "run", false); // run normal update for (int i = 0; i < 5; ++i) { const float timeSlice = 1.0f / 60.0f; spSkeleton_update(skeleton, timeSlice); spAnimationState_update(state, timeSlice); spAnimationState_apply(state, skeleton); } // Now we'd lose mixingFrom (the first "walk" entry we set above) and should leak spAnimationState_setAnimationByName(state, 0, "run", false); ////////////////////////////////////////////////////////////////////////// // Cleanup Animations DisposeAll(skeleton, state, stateData, skeletonData, 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); }
void SkeletonRenderer::setToSetupPose () { spSkeleton_setToSetupPose(_skeleton); }
SpineAnimation::SpineAnimation(JNIEnv* env, spSkeletonData* sd, SpineCallback* cb) { this->callback = cb; this->skeleton = spSkeleton_create(sd); this->state = spAnimationState_create(spAnimationStateData_create(skeleton->data)); this->bounds = new spBounds(); this->x = 0; this->y = 0; // Count slots with attachments AND bones only int i, bCount = 0; for(i = 0; i < skeleton->slotCount; i++) { spSlot* slot = skeleton->drawOrder[i]; spBone* bone = slot->bone; if(bone && slot->attachment) { bCount++; } } // This will allocate the native array this->callback->onSkeletonCreate(env, bCount); int bIndex = 0; // Set to initial pose spSkeleton_setToSetupPose(this->skeleton); // Update transform so the bone's world position is set spSkeleton_updateWorldTransform(skeleton); for(i = 0; i < skeleton->slotCount; i++) { spSlot* slot = skeleton->drawOrder[i]; spBone* bone = slot->bone; if(bone && slot->attachment) { this->callback->addBone( env, bIndex, slot); // create the buffer for this bone const char* boneName = slot->bone->data->name; this->boneVertBuffers[boneName] = new float[BUFFER_SIZE]; // 4 x 2 coords // Compute the starting verts spRegionAttachment_computeWorldVertices((spRegionAttachment*) slot->attachment, x, y, bone, this->boneVertBuffers[boneName]); bIndex++; } } // Loop again tp set the parents bIndex = 0; for(i = 0; i < skeleton->slotCount; i++) { spSlot* slot = skeleton->drawOrder[i]; if(slot->bone && slot->attachment) { spBone* parent = slot->bone->parent; if(parent) { this->callback->setBoneParent( env, bIndex, parent->data->name); } bIndex++; } } this->center = new float[2]; // x, y // Initialize the mutex to lock between draw and step int mutexInitState = pthread_mutex_init (&mutex , NULL ); if(mutexInitState != 0) { callback->onError(env, "Error initializing mutex: %s", strerror(errno)); } }
void Skeleton::setToSetupPose () { spSkeleton_setToSetupPose(skeleton); }
void Skeleton::set_skin(const char* skin) { spSkeleton_setSkinByName(skeleton_, skin); spSkeleton_setToSetupPose(skeleton_); }
SpineDrawable::SpineDrawable(const std::string& atlasFile, const std::string& skeletonFile): Component(TYPE) { atlas = spAtlas_createFromFile(atlasFile.c_str(), 0); if (!atlas) { ouzel::Log(ouzel::Log::Level::ERR) << "Failed to load atlas"; return; } if (skeletonFile.find(".json") != std::string::npos) { // is json format spSkeletonJson* json = spSkeletonJson_create(atlas); skeletonData = spSkeletonJson_readSkeletonDataFile(json, skeletonFile.c_str()); if (!skeletonData) { ouzel::Log(ouzel::Log::Level::ERR) << "Failed to load skeleton: " << json->error; return; } spSkeletonJson_dispose(json); } else { // binary format spSkeletonBinary* binary = spSkeletonBinary_create(atlas); skeletonData = spSkeletonBinary_readSkeletonDataFile(binary, skeletonFile.c_str()); if (!skeletonData) { ouzel::Log(ouzel::Log::Level::ERR) << "Failed to load skeleton: " << binary->error; return; } spSkeletonBinary_dispose(binary); } bounds = spSkeletonBounds_create(); skeleton = spSkeleton_create(skeletonData); animationStateData = spAnimationStateData_create(skeletonData); animationState = spAnimationState_create(animationStateData); animationState->listener = listener; animationState->rendererObject = this; spSkeleton_setToSetupPose(skeleton); spSkeleton_updateWorldTransform(skeleton); updateMaterials(); updateBoundingBox(); indexBuffer = std::make_shared<ouzel::graphics::Buffer>(*ouzel::engine->getRenderer()); indexBuffer->init(ouzel::graphics::Buffer::Usage::INDEX, ouzel::graphics::Buffer::DYNAMIC); vertexBuffer = std::make_shared<ouzel::graphics::Buffer>(*ouzel::engine->getRenderer()); vertexBuffer->init(ouzel::graphics::Buffer::Usage::VERTEX, ouzel::graphics::Buffer::DYNAMIC); whitePixelTexture = ouzel::engine->getCache().getTexture(ouzel::TEXTURE_WHITE_PIXEL); updateHandler.updateHandler = std::bind(&SpineDrawable::handleUpdate, this, std::placeholders::_1); ouzel::engine->getEventDispatcher().addEventHandler(&updateHandler); }
void SpineDrawable::reset() { spSkeleton_setToSetupPose(skeleton); }