Esempio n. 1
0
    void SpineDrawable::setOffset(const ouzel::Vector2& offset)
    {
        skeleton->x = offset.x;
        skeleton->y = offset.y;

        spSkeleton_updateWorldTransform(skeleton);
    }
Esempio n. 2
0
	void SpineAnimation::doUpdate(const oxygine::UpdateState& us)
	{
		SpineSkeleton::doUpdate(us);
		spAnimationState_update(state, (float)us.dt / 1000);
        spAnimationState_apply(state, skeleton);
        spSkeleton_updateWorldTransform(skeleton);
	}
Esempio n. 3
0
void SkeletonAnimationFbo::updateSkeletonAnimation()
{
    if (!isSkeletonValid()) {
        update();
        return;
    }

    if (!mEventCache.isEmpty()){
        Q_FOREACH(SpineEvent* event, mEventCache)
            SAFE_DELETE(event);
        mEventCache.clear();
    }

    qint64 mSecs = 0;
    if (!mTimer.isValid())
        mTimer.start();
    else
        mSecs = mTimer.restart();

    const float deltaTime = mSecs/1000.0 * mTimeScale;
    spSkeleton_update(mspSkeleton, deltaTime);
    spAnimationState_update(mspAnimationState, deltaTime);
    spAnimationState_apply(mspAnimationState, mspSkeleton);
    spSkeleton_updateWorldTransform(mspSkeleton);

    const QRectF rect = calculateSkeletonRect();
    setSourceSize(QSize(rect.width(), rect.height()));
    setImplicitSize(rect.width(), rect.height());
    setPosition(QPointF(rect.left(), -1.0f*(rect.top() + rect.height())));
    update();
}
Esempio n. 4
0
void SkeletonAnimation::update (float deltaTime) {
	super::update(deltaTime);

	deltaTime *= _timeScale;
	spAnimationState_update(_state, deltaTime);
	spAnimationState_apply(_state, _skeleton);
	spSkeleton_updateWorldTransform(_skeleton);
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
void SkeletonAnimation::initialize () {
	_ownsAnimationStateData = true;
	_state = spAnimationState_create(spAnimationStateData_create(_skeleton->data));
	_state->rendererObject = this;
	_state->listener = animationCallback;

	_spAnimationState* stateInternal = (_spAnimationState*)_state;
	stateInternal->disposeTrackEntry = disposeTrackEntry;
	spSkeleton_updateWorldTransform(_skeleton);
}
void SpineAnimation::step(JNIEnv* env, float deltaTime) {

	pthread_mutex_lock(&mutex);

	spAnimationState_update(state, deltaTime);
	spAnimationState_apply(state, skeleton);
	spSkeleton_updateWorldTransform(skeleton);

	pthread_mutex_unlock(&mutex);
}
void USpineSkeletonAnimationComponent::InternalTick(float DeltaTime, bool CallDelegates) {
	CheckState();

	if (state) {
		spAnimationState_update(state, DeltaTime);
		spAnimationState_apply(state, skeleton);
		if (CallDelegates) BeforeUpdateWorldTransform.Broadcast(this);
		spSkeleton_updateWorldTransform(skeleton);
		if (CallDelegates) AfterUpdateWorldTransform.Broadcast(this);
	}
}
Esempio n. 9
0
void SkeletonDrawable::update (float deltaTime) {
	spSkeleton_update(skeleton, deltaTime);
	spAnimationState_update(state, deltaTime * timeScale);
	spAnimationState_apply(state, skeleton);
	spSkeleton_updateWorldTransform(skeleton);
}
ENTITY_COMPONENT_METHOD(ComponentSpine, update)
{
    if(!self.skeleton)
    {
        return 0;
    }

    auto dt = System::getInstance().getCurrentDt();
    auto & mesh = self.mesh;

    Transform transform;

    getTransformFromComponent(state, transform);

    mesh.setPosition(transform.position);
    mesh.setRotation(transform.rotation);
    mesh.setScale(transform.scale);

    spSkeleton_update(self.skeleton, dt * self.timeFactor);
    spAnimationState_update(self.animationState, dt * self.timeFactor);
    spAnimationState_apply(self.animationState, self.skeleton);
    spSkeleton_updateWorldTransform(self.skeleton);

    auto vertices = self.mesh.getVertexBuffer().map();
    auto indices = self.mesh.getIndexBuffer().map();
    uint vertex_count = 0;
    uint index_count = 0;

    for(int i = 0; i < self.skeleton->slotsCount; ++i)
    {
        auto slot = self.skeleton->drawOrder[i];
        auto attachment = slot->attachment;

        if(!attachment)
        {
            continue;
        }

        switch(attachment->type)
        {
            case SP_ATTACHMENT_REGION:
            {
                Vector2 computed_vertices[4];
                auto region_attachment = (spRegionAttachment*)attachment;
                auto color = Vector4(
                    self.skeleton->r * slot->r,
                    self.skeleton->g * slot->g,
                    self.skeleton->b * slot->b,
                    self.skeleton->a * slot->a
                    );

                self.mesh.setTexture(* (graphics::Texture*)((spAtlasRegion*)region_attachment->rendererObject)->page->rendererObject);

                spRegionAttachment_computeWorldVertices(region_attachment, slot->bone, (float *)computed_vertices);

                vertices[vertex_count].color = color;
                vertices[vertex_count].position = computed_vertices[0];
                vertices[vertex_count].texCoords.x = region_attachment->uvs[SP_VERTEX_X1];
                vertices[vertex_count].texCoords.y = region_attachment->uvs[SP_VERTEX_Y1];

                vertices[vertex_count + 1].color = color;
                vertices[vertex_count + 1].position = computed_vertices[1];
                vertices[vertex_count + 1].texCoords.x = region_attachment->uvs[SP_VERTEX_X2];
                vertices[vertex_count + 1].texCoords.y = region_attachment->uvs[SP_VERTEX_Y2];

                vertices[vertex_count + 2].color = color;
                vertices[vertex_count + 2].position = computed_vertices[2];
                vertices[vertex_count + 2].texCoords.x = region_attachment->uvs[SP_VERTEX_X3];
                vertices[vertex_count + 2].texCoords.y = region_attachment->uvs[SP_VERTEX_Y3];

                vertices[vertex_count + 3].color = color;
                vertices[vertex_count + 3].position = computed_vertices[3];
                vertices[vertex_count + 3].texCoords.x = region_attachment->uvs[SP_VERTEX_X4];
                vertices[vertex_count + 3].texCoords.y = region_attachment->uvs[SP_VERTEX_Y4];


                indices[index_count + 0] = vertex_count + 0;
                indices[index_count + 1] = vertex_count + 1;
                indices[index_count + 2] = vertex_count + 2;
                indices[index_count + 3] = vertex_count + 2;
                indices[index_count + 4] = vertex_count + 3;
                indices[index_count + 5] = vertex_count + 0;

                vertex_count += 4;
                index_count += 6;
            }
            break;

            case SP_ATTACHMENT_MESH:
            {
                auto mesh = (spMeshAttachment*)attachment;
                auto initial_vertex_count = vertex_count;
                auto color = Vector4(
                    self.skeleton->r * slot->r,
                    self.skeleton->g * slot->g,
                    self.skeleton->b * slot->b,
                    self.skeleton->a * slot->a
                    );

                float *_vertices = mesh->vertices;
                const spBone* bone = slot->bone;
                float x = bone->skeleton->x + bone->worldX, y = bone->skeleton->y + bone->worldY;

                self.mesh.setTexture(* (graphics::Texture*)((spAtlasRegion*)mesh->rendererObject)->page->rendererObject);

                if(slot->attachmentVerticesCount == mesh->verticesCount)
                {
                    _vertices = slot->attachmentVertices;
                }

                for(int i = 0; i < mesh->verticesCount; i += 2)
                {
                    const float vx = _vertices[i], vy = _vertices[i + 1];
                    auto & vertex = vertices[initial_vertex_count + i / 2];
                    vertex.position.x = vx * bone->m00 + vy * bone->m01 + x;
                    vertex.position.y = vx * bone->m10 + vy * bone->m11 + y;
                    vertex.texCoords.u = mesh->uvs[i];
                    vertex.texCoords.v = mesh->uvs[i + 1];
                    vertex.color = color;
                    ++vertex_count;
                }

                for(int i = 0; i < mesh->trianglesCount; ++i)
                {
                    int index = mesh->triangles[i] << 1;
                    indices[index_count] = initial_vertex_count + index / 2;
                    ++index_count;
                }
            }
            break;

            case SP_ATTACHMENT_SKINNED_MESH:
            {
                auto mesh = (spSkinnedMeshAttachment*)attachment;
                auto initial_vertex_count = vertex_count;
                auto color = Vector4(
                    self.skeleton->r * slot->r,
                    self.skeleton->g * slot->g,
                    self.skeleton->b * slot->b,
                    self.skeleton->a * slot->a
                    );

                self.mesh.setTexture(* (graphics::Texture*)((spAtlasRegion*)mesh->rendererObject)->page->rendererObject);

                int w = 0, v = 0, b = 0, f = 0;
                float x = slot->bone->skeleton->x, y = slot->bone->skeleton->y;
                spBone** skeletonBones = slot->bone->skeleton->bones;

                if(slot->attachmentVerticesCount == 0)
                {
                    for(; v < mesh->bonesCount; w += 2)
                    {
                        float wx = 0, wy = 0;
                        const int nn = mesh->bones[v] + v;
                        v++;
                        for(; v <= nn; v++, b += 3)
                        {
                            const spBone* bone = skeletonBones[mesh->bones[v]];
                            const float vx = mesh->weights[b], vy = mesh->weights[b + 1], weight = mesh->weights[b + 2];
                            wx += (vx * bone->m00 + vy * bone->m01 + bone->worldX) * weight;
                            wy += (vx * bone->m10 + vy * bone->m11 + bone->worldY) * weight;
                        }
                        auto & vertex = vertices[initial_vertex_count + w / 2];
                        ++vertex_count;
                        vertex.position.x = wx + x;
                        vertex.position.y = wy + y;
                        vertex.texCoords.u = mesh->uvs[w];
                        vertex.texCoords.v = mesh->uvs[w + 1];
                        vertex.color = color;
                    }
                }
                else
                {
                    const float* ffd = slot->attachmentVertices;
                    for(; v < mesh->bonesCount; w += 2)
                    {
                        float wx = 0, wy = 0;
                        const int nn = mesh->bones[v] + v;
                        v++;
                        for(; v <= nn; v++, b += 3, f += 2)
                        {
                            const spBone* bone = skeletonBones[mesh->bones[v]];
                            const float vx = mesh->weights[b] + ffd[f], vy = mesh->weights[b + 1] + ffd[f + 1], weight = mesh->weights[b + 2];
                            wx += (vx * bone->m00 + vy * bone->m01 + bone->worldX) * weight;
                            wy += (vx * bone->m10 + vy * bone->m11 + bone->worldY) * weight;
                        }
                        auto & vertex = vertices[initial_vertex_count + w / 2];
                        ++vertex_count;
                        vertex.position.x = wx + x;
                        vertex.position.y = wy + y;
                        vertex.texCoords.u = mesh->uvs[w];
                        vertex.texCoords.v = mesh->uvs[w + 1];
                        vertex.color = color;
                    }
                }

                for(int i = 0; i < mesh->trianglesCount; ++i)
                {
                    int index = mesh->triangles[i] << 1;
                    indices[index_count] = initial_vertex_count + index / 2;
                    ++index_count;
                }
            }
            break;

            default:
            break;
        }
    }

    self.mesh.setVertexCount(vertex_count);
    self.mesh.setIndexCount(index_count);
    self.mesh.getVertexBuffer().unMap();
    self.mesh.getIndexBuffer().unMap();
}
Esempio n. 11
0
void PrincessModel::initMakeFaceRender(RenderTexture *render, WJLayer *topLayer)
{
	spSkeleton_updateWorldTransform(m_skeleton->getSkeleton());

	Vec2 anchorPoint;
	Vec2 pos;
	Size size;
	// head layer
	m_boneRoot = m_skeleton->findBone("root");
	m_slotHead = m_skeleton->findSlot("layer");
	m_skeleton->getSlotInfo(m_slotHead, &anchorPoint, &pos, &size, &m_faceBoneDefaultRotation);
	// top layer
	m_modelTopLayerHead = WJLayer::create();
	m_modelTopLayerHead->setContentSize(size);
	m_modelTopLayerHead->ignoreAnchorPointForPosition(false);
	m_modelTopLayerHead->setAnchorPoint(anchorPoint);
	m_modelTopLayerHead->setPosition(pos);
	m_modelTopLayerHead->setVisible(false);
	this->addChild(m_modelTopLayerHead, 100);

	// 头部layer的item
	const Size &oldSize = topLayer->getContentSize();
	WJSprite *sprite;
	WJSprite *newSprite;
	Vector<Node*> _vectorNode = topLayer->getChildren();
	for (int i = 0; i < _vectorNode.size(); i++)
	{
		sprite = (WJSprite*)_vectorNode.at(i);
		sprite->setClickAble(false);
		sprite->setMoveAble(false);
		newSprite = (WJSprite*)sprite->clone();
		if (newSprite)
		{
			float x = (float(sprite->getPositionX() / oldSize.width)) * size.width;
			float y = (float(sprite->getPositionY() / oldSize.height)) * size.height;
			newSprite->setPosition(Vec2(x, y));
			newSprite->setScaleX(float(size.width / oldSize.width));
			newSprite->setScaleX(float(size.height/ oldSize.width));
			m_modelTopLayerHead->addChild(newSprite, sprite->getLocalZOrder());
		}
	}

	//// test
	//LayerColor *colorLayerHead = LayerColor::create(Color4B(0, 255, 255, 80));
	//colorLayerHead->setContentSize(size);
	//m_modelTopLayerHead->addChild(colorLayerHead);

	// 头部layer
	m_modelTopLayerHead->setAnchorPoint(Vec2(0.5f, 0.5f));
	m_modelTopLayerHead->setScaleY(-m_modelTopLayerHead->getScaleY());

	// 画脸
	m_faceRenderTexture = RenderTexture::create(431, 494);
	m_faceRenderTexture->setAnchorPoint(Vec2(0.5f, 0.5f));
	m_faceRenderTexture->ignoreAnchorPointForPosition(false);
	m_faceRenderTexture->getSprite()->getTexture()->setAntiAliasTexParameters();
	m_faceRenderTexture->retain();

	m_faceRenderTexture->beginWithClear(0, 0, 0, 0);
	visitNodeWithMakeFace(render);
	visitNodeWithMakeFace(m_modelTopLayerHead);
	m_faceRenderTexture->end();
	Director::getInstance()->getRenderer()->render();

	getSkeleton()->setSlotTexture("dress", m_faceRenderTexture->getSprite()->getTexture());
}
void SkeletonRenderer::updateWorldTransform () {
	spSkeleton_updateWorldTransform(_skeleton);
}
Esempio n. 13
0
void WIPAnimator::update(f32 dt)
{
	if(!_frame_ref)
		return;

	f32 iww = 1.f/g_app_manager->get_window_width();
	f32 iwh = 1.f/g_app_manager->get_window_height();

	f32 sw = _out_buffer->get_width()*iww;
	f32 sh = _out_buffer->get_height()*iwh;

	f32 hw =g_app_manager->get_window_width()*0.5f;
	f32 hh = g_app_manager->get_window_height()*0.65f;


	_out_buffer->begin();
	glClear(GL_COLOR_BUFFER_BIT);
	_out_buffer->end();
	spSkeleton_update(skeleton, dt);
	spAnimationState_update(state, dt * time_scale);
	spAnimationState_apply(state, skeleton);
	spSkeleton_updateWorldTransform(skeleton);
	_out_buffer->begin();
	for(int i=0;i<skeleton->slotCount; ++i)
	{
		spSlot* slot = skeleton->drawOrder[i];
		spAttachment* attachment = slot->attachment;
		if (!attachment) continue;
		WIPTexture* p = 0;
		if (attachment->type == SP_ATTACHMENT_REGION) 
		{
			//available
			spRegionAttachment* regionAttachment = (spRegionAttachment*)attachment;
			p = (WIPTexture*)((spAtlasRegion*)regionAttachment->rendererObject)->page->rendererObject;
			spRegionAttachment_computeWorldVertices(regionAttachment,  slot->skeleton->x, slot->skeleton->y,slot->bone, _world_vertices);
		}

		if(p)
		{
			spRegionAttachment* regionAttachment = (spRegionAttachment*)attachment;
			int tex_x = p->get_width();
			int tex_y = p->get_height();

			RenderQuad uv_q;
			uv_q.lt.x = regionAttachment->uvs[SP_VERTEX_X1];
			uv_q.lt.y =regionAttachment->uvs[SP_VERTEX_Y1];
			uv_q.lb.x = regionAttachment->uvs[SP_VERTEX_X2];
			uv_q.lb.y =regionAttachment->uvs[SP_VERTEX_Y2];
			uv_q.rt.x = regionAttachment->uvs[SP_VERTEX_X4];
			uv_q.rt.y =regionAttachment->uvs[SP_VERTEX_Y4];
			uv_q.rb.x = regionAttachment->uvs[SP_VERTEX_X3];
			uv_q.rb.y =regionAttachment->uvs[SP_VERTEX_Y3];

			int x1 = _world_vertices[SP_VERTEX_X1];
			int y1 = _world_vertices[SP_VERTEX_Y1];
			int x2 = _world_vertices[SP_VERTEX_X2];
			int y2 = _world_vertices[SP_VERTEX_Y2];
			int x4 = _world_vertices[SP_VERTEX_X3];
			int y4 = _world_vertices[SP_VERTEX_Y3];
			int x3 = _world_vertices[SP_VERTEX_X4];
			int y3 = _world_vertices[SP_VERTEX_Y4];

			

			RenderQuad q;
			q.lb.x = x1+hw;
			q.lb.y = y1+hh;
			q.lt.x = x2+hw;
			q.lt.y = y2+hh;
			q.rb.x = x3+hw;
			q.rb.y = y3+hh;
			q.rt.x = x4+hw;
			q.rt.y = y4+hh;

			
			
			g_renderer->render(p,&q,&uv_q);
			

		}
		
	}
	_out_buffer->end();
	_frame_ref->texture = _out_buffer;
	_frame_ref->framebox->set_quickly(0,0,0,1,1,1,1,0,0,0);

	
}
Esempio n. 14
0
    void SpineDrawable::draw(const ouzel::Matrix4& transformMatrix,
                             float opacity,
                             const ouzel::Matrix4& renderViewProjection,
                             bool wireframe)
    {
        Component::draw(transformMatrix,
                        opacity,
                        renderViewProjection,
                        wireframe);

        spAnimationState_apply(animationState, skeleton);
        spSkeleton_updateWorldTransform(skeleton);

        std::vector<std::vector<float>> vertexShaderConstants(1);

        ouzel::Matrix4 modelViewProj = renderViewProjection * transformMatrix;
        vertexShaderConstants[0] = {std::begin(modelViewProj.m), std::end(modelViewProj.m)};

        ouzel::graphics::Vertex vertex;

        uint16_t currentVertexIndex = 0;
        indices.clear();
        vertices.clear();

        uint32_t offset = 0;

        boundingBox.reset();

        struct DrawCommand
        {
            std::shared_ptr<ouzel::graphics::Material> material;
            uint32_t indexCount;
            uint32_t offset;
            std::vector<std::vector<float>> pixelShaderConstants = std::vector<std::vector<float>>(1);
        };

        std::vector<DrawCommand> drawCommands;

        for (int i = 0; i < skeleton->slotsCount; ++i)
        {
            spSlot* slot = skeleton->drawOrder[i];
            spAttachment* attachment = slot->attachment;
            if (!attachment) continue;

            DrawCommand drawCommand;
            drawCommand.material = materials[static_cast<size_t>(i)];

            float colorVector[] = {slot->color.r * drawCommand.material->diffuseColor.normR(),
                slot->color.g * drawCommand.material->diffuseColor.normG(),
                slot->color.b * drawCommand.material->diffuseColor.normB(),
                slot->color.a * drawCommand.material->diffuseColor.normA() * opacity};
            drawCommand.pixelShaderConstants[0] = {std::begin(colorVector), std::end(colorVector)};

            if (attachment->type == SP_ATTACHMENT_REGION)
            {
                spRegionAttachment* regionAttachment = reinterpret_cast<spRegionAttachment*>(attachment);

                spRegionAttachment_computeWorldVertices(regionAttachment, slot->bone, worldVertices, 0, 2);

                uint8_t r = static_cast<uint8_t>(skeleton->color.r * 255.0f);
                uint8_t g = static_cast<uint8_t>(skeleton->color.g * 255.0f);
                uint8_t b = static_cast<uint8_t>(skeleton->color.b * 255.0f);
                uint8_t a = static_cast<uint8_t>(skeleton->color.a * 255.0f);

                vertex.color.r = r;
                vertex.color.g = g;
                vertex.color.b = b;
                vertex.color.a = a;
                vertex.position.x = worldVertices[0];
                vertex.position.y = worldVertices[1];
                vertex.texCoords[0].x = regionAttachment->uvs[0];
                vertex.texCoords[0].y = regionAttachment->uvs[1];
                vertex.normal = ouzel::Vector3(0.0f, 0.0f, -1.0f);
                vertices.push_back(vertex);

                vertex.color.r = r;
                vertex.color.g = g;
                vertex.color.b = b;
                vertex.color.a = a;
                vertex.position.x = worldVertices[2];
                vertex.position.y = worldVertices[3];
                vertex.texCoords[0].x = regionAttachment->uvs[2];
                vertex.texCoords[0].y = regionAttachment->uvs[3];
                vertex.normal = ouzel::Vector3(0.0f, 0.0f, -1.0f);
                vertices.push_back(vertex);

                vertex.color.r = r;
                vertex.color.g = g;
                vertex.color.b = b;
                vertex.color.a = a;
                vertex.position.x = worldVertices[4];
                vertex.position.y = worldVertices[5];
                vertex.texCoords[0].x = regionAttachment->uvs[4];
                vertex.texCoords[0].y = regionAttachment->uvs[5];
                vertex.normal = ouzel::Vector3(0.0f, 0.0f, -1.0f);
                vertices.push_back(vertex);

                vertex.color.r = r;
                vertex.color.g = g;
                vertex.color.b = b;
                vertex.color.a = a;
                vertex.position.x = worldVertices[6];
                vertex.position.y = worldVertices[7];
                vertex.texCoords[0].x = regionAttachment->uvs[6];
                vertex.texCoords[0].y = regionAttachment->uvs[7];
                vertex.normal = ouzel::Vector3(0.0f, 0.0f, -1.0f);
                vertices.push_back(vertex);

                indices.push_back(currentVertexIndex + 0);
                indices.push_back(currentVertexIndex + 1);
                indices.push_back(currentVertexIndex + 2);
                indices.push_back(currentVertexIndex + 0);
                indices.push_back(currentVertexIndex + 2);
                indices.push_back(currentVertexIndex + 3);

                currentVertexIndex += 4;

                boundingBox.insertPoint(ouzel::Vector3(worldVertices[0], worldVertices[1], 0.0F));
                boundingBox.insertPoint(ouzel::Vector3(worldVertices[2], worldVertices[3], 0.0F));
                boundingBox.insertPoint(ouzel::Vector3(worldVertices[4], worldVertices[5], 0.0F));
                boundingBox.insertPoint(ouzel::Vector3(worldVertices[6], worldVertices[7], 0.0F));

                if (!materials[static_cast<size_t>(i)]->textures[0])
                {
                    SpineTexture* texture = static_cast<SpineTexture*>((static_cast<spAtlasRegion*>(regionAttachment->rendererObject))->page->rendererObject);
                    if (texture) materials[static_cast<size_t>(i)]->textures[0] = texture->texture;
                }
            }
            else if (attachment->type == SP_ATTACHMENT_MESH)
            {
                spMeshAttachment* meshAttachment = reinterpret_cast<spMeshAttachment*>(attachment);
                if (meshAttachment->trianglesCount * 3 > SPINE_MESH_VERTEX_COUNT_MAX) continue;
                spVertexAttachment_computeWorldVertices(SUPER(meshAttachment), slot, 0, meshAttachment->super.worldVerticesLength, worldVertices, 0, 2);

                vertex.color.r = static_cast<uint8_t>(skeleton->color.r * 255.0f);
                vertex.color.g = static_cast<uint8_t>(skeleton->color.g * 255.0f);
                vertex.color.b = static_cast<uint8_t>(skeleton->color.b * 255.0f);
                vertex.color.a = static_cast<uint8_t>(skeleton->color.a * 255.0f);

                for (int t = 0; t < meshAttachment->trianglesCount; ++t)
                {
                    int index = meshAttachment->triangles[t] << 1;
                    vertex.position.x = worldVertices[index];
                    vertex.position.y = worldVertices[index + 1];
                    vertex.texCoords[0].x = meshAttachment->uvs[index];
                    vertex.texCoords[0].y = meshAttachment->uvs[index + 1];

                    indices.push_back(currentVertexIndex);
                    currentVertexIndex++;
                    vertices.push_back(vertex);

                    boundingBox.insertPoint(ouzel::Vector3(worldVertices[index], worldVertices[index + 1], 0.0F));
                }

                if (!materials[static_cast<size_t>(i)]->textures[0])
                {
                    SpineTexture* texture = static_cast<SpineTexture*>((static_cast<spAtlasRegion*>(meshAttachment->rendererObject))->page->rendererObject);
                    if (texture) materials[static_cast<size_t>(i)]->textures[0] = texture->texture;
                }
            }
            else
            {
                continue;
            }

            if (indices.size() - offset > 0)
            {
                drawCommand.indexCount = static_cast<uint32_t>(indices.size()) - offset;
                drawCommand.offset = offset;
                drawCommands.push_back(drawCommand);
            }

            offset = static_cast<uint32_t>(indices.size());
        }

        indexBuffer->setData(indices.data(), static_cast<uint32_t>(ouzel::getVectorSize(indices)));
        vertexBuffer->setData(vertices.data(), static_cast<uint32_t>(ouzel::getVectorSize(vertices)));

        for (const DrawCommand& drawCommand : drawCommands)
        {
            std::vector<uintptr_t> textures;
            if (wireframe) textures.push_back(whitePixelTexture->getResource());
            else
                for (const auto& texture : drawCommand.material->textures)
                    textures.push_back(texture ? texture->getResource() : 0);

            ouzel::engine->getRenderer()->setCullMode(drawCommand.material->cullMode);
            ouzel::engine->getRenderer()->setPipelineState(drawCommand.material->blendState->getResource(),
                                                           drawCommand.material->shader->getResource());
            ouzel::engine->getRenderer()->setShaderConstants(drawCommand.pixelShaderConstants,
                                                             vertexShaderConstants);
            ouzel::engine->getRenderer()->setTextures(textures);
            ouzel::engine->getRenderer()->draw(indexBuffer->getResource(),
                                               drawCommand.indexCount,
                                               sizeof(uint16_t),
                                               vertexBuffer->getResource(),
                                               ouzel::graphics::DrawMode::TRIANGLE_LIST,
                                               drawCommand.offset);
        }
    }
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));
	}
}
Esempio n. 16
0
    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);
    }
Esempio n. 17
0
void Skeleton::updateWorldTransform () {
	spSkeleton_updateWorldTransform(skeleton);
}
Esempio n. 18
0
void Skeleton::update(unsigned long dt)
{
    const float delta = dt / 1000.0f;
    spSkeleton_update(skeleton_, delta);
    spAnimationState_update(state_, delta * time_scale_);
    spAnimationState_apply(state_, skeleton_);
    spSkeleton_updateWorldTransform(skeleton_);

    // This solution is not ideal. We iterate over the bones twice: First to
    // determine number of vertices, second to update the vertex buffer.
    num_vertices_ = get_vertex_count(skeleton_, &texture_);
    if (num_vertices_ > max_vertices_)
    {
        max_vertices_ = num_vertices_;
        vertices_ = std::make_unique<SpriteVertex[]>(max_vertices_);
    }

    size_t i = 0;
    for_each(skeleton_, [this, &i](spSlot* slot) {
        if (!slot->attachment)
            return;

        switch (slot->attachment->type)
        {
            case SP_ATTACHMENT_REGION: {
                float vertices[8];
                spRegionAttachment* region =
                    reinterpret_cast<spRegionAttachment*>(slot->attachment);
                R_ASSERT(texture_ == get_texture(region),
                         kErrorMultipleTexturesUnsupported);
                spRegionAttachment_computeWorldVertices(
                    region, slot->bone, vertices);

                const char r = skeleton_->r * slot->r * 0xff;
                const char g = skeleton_->g * slot->g * 0xff;
                const char b = skeleton_->b * slot->b * 0xff;
                const char a = skeleton_->a * slot->a * 0xff;

                vertices_[i].color.r = r;
                vertices_[i].color.g = g;
                vertices_[i].color.b = b;
                vertices_[i].color.a = a;
                vertices_[i].texcoord.x = region->uvs[SP_VERTEX_X1];
                vertices_[i].texcoord.y = region->uvs[SP_VERTEX_Y1];
                vertices_[i].position.x = vertices[SP_VERTEX_X1];
                vertices_[i].position.y = vertices[SP_VERTEX_Y1];

                vertices_[++i].color.r = r;
                vertices_[i].color.g = g;
                vertices_[i].color.b = b;
                vertices_[i].color.a = a;
                vertices_[i].texcoord.x = region->uvs[SP_VERTEX_X2];
                vertices_[i].texcoord.y = region->uvs[SP_VERTEX_Y2];
                vertices_[i].position.x = vertices[SP_VERTEX_X2];
                vertices_[i].position.y = vertices[SP_VERTEX_Y2];

                vertices_[++i].color.r = r;
                vertices_[i].color.g = g;
                vertices_[i].color.b = b;
                vertices_[i].color.a = a;
                vertices_[i].texcoord.x = region->uvs[SP_VERTEX_X3];
                vertices_[i].texcoord.y = region->uvs[SP_VERTEX_Y3];
                vertices_[i].position.x = vertices[SP_VERTEX_X3];
                vertices_[i].position.y = vertices[SP_VERTEX_Y3];

                ++i;
                vertices_[i] = vertices_[i - 1];

                vertices_[++i].color.r = r;
                vertices_[i].color.g = g;
                vertices_[i].color.b = b;
                vertices_[i].color.a = a;
                vertices_[i].texcoord.x = region->uvs[SP_VERTEX_X4];
                vertices_[i].texcoord.y = region->uvs[SP_VERTEX_Y4];
                vertices_[i].position.x = vertices[SP_VERTEX_X4];
                vertices_[i].position.y = vertices[SP_VERTEX_Y4];

                ++i;
                vertices_[i] = vertices_[i - 5];

                ++i;
                break;
            }
            case SP_ATTACHMENT_BOUNDING_BOX:
                break;
            case SP_ATTACHMENT_MESH: {
                spMeshAttachment* mesh =
                    reinterpret_cast<spMeshAttachment*>(slot->attachment);
                R_ASSERT(texture_ == get_texture(mesh),
                         kErrorMultipleTexturesUnsupported);
                i += update_mesh(&vertices_[i], skeleton_, mesh, slot);
                break;
            }
            case SP_ATTACHMENT_SKINNED_MESH: {
                spSkinnedMeshAttachment* mesh =
                    reinterpret_cast<spSkinnedMeshAttachment*>(
                        slot->attachment);
                R_ASSERT(texture_ == get_texture(mesh),
                         kErrorMultipleTexturesUnsupported);
                i += update_mesh(&vertices_[i], skeleton_, mesh, slot);
                break;
            }
        }
        if (slot->data->blendMode != SP_BLEND_MODE_NORMAL)  // TODO: Implement.
            LOGE("Non-normal blend mode not yet implemented");
    });

    vertex_buffer_.upload(vertices_.get(), i * sizeof(SpriteVertex));
}