Exemplo n.º 1
0
Rect Skeleton::getBoundingBox () const {
	float minX = FLT_MAX, minY = FLT_MAX, maxX = FLT_MIN, maxY = FLT_MIN;
	float scaleX = getScaleX();
	float scaleY = getScaleY();
	float vertices[8];
	for (int i = 0; i < skeleton->slotCount; ++i) {
		spSlot* slot = skeleton->slots[i];
		if (!slot->attachment || slot->attachment->type != ATTACHMENT_REGION) continue;
		spRegionAttachment* attachment = (spRegionAttachment*)slot->attachment;
		spRegionAttachment_computeWorldVertices(attachment, slot->skeleton->x, slot->skeleton->y, slot->bone, vertices);
		minX = min(minX, vertices[VERTEX_X1] * scaleX);
		minY = min(minY, vertices[VERTEX_Y1] * scaleY);
		maxX = max(maxX, vertices[VERTEX_X1] * scaleX);
		maxY = max(maxY, vertices[VERTEX_Y1] * scaleY);
		minX = min(minX, vertices[VERTEX_X4] * scaleX);
		minY = min(minY, vertices[VERTEX_Y4] * scaleY);
		maxX = max(maxX, vertices[VERTEX_X4] * scaleX);
		maxY = max(maxY, vertices[VERTEX_Y4] * scaleY);
		minX = min(minX, vertices[VERTEX_X2] * scaleX);
		minY = min(minY, vertices[VERTEX_Y2] * scaleY);
		maxX = max(maxX, vertices[VERTEX_X2] * scaleX);
		maxY = max(maxY, vertices[VERTEX_Y2] * scaleY);
		minX = min(minX, vertices[VERTEX_X3] * scaleX);
		minY = min(minY, vertices[VERTEX_Y3] * scaleY);
		maxX = max(maxX, vertices[VERTEX_X3] * scaleX);
		maxY = max(maxY, vertices[VERTEX_Y3] * scaleY);
	}
	Vec2 position = getPosition();
	return Rect(position.x + minX, position.y + minY, maxX - minX, maxY - minY);
}
Rect SkeletonRenderer::getBoundingBox () const {
	float minX = FLT_MAX, minY = FLT_MAX, maxX = FLT_MIN, maxY = FLT_MIN;
	float scaleX = getScaleX(), scaleY = getScaleY();
	for (int i = 0; i < _skeleton->slotsCount; ++i) {
		spSlot* slot = _skeleton->slots[i];
		if (!slot->attachment) continue;
		int verticesCount;
		if (slot->attachment->type == SP_ATTACHMENT_REGION) {
			spRegionAttachment* attachment = (spRegionAttachment*)slot->attachment;
			spRegionAttachment_computeWorldVertices(attachment, slot->bone, _worldVertices);
			verticesCount = 8;
		} else if (slot->attachment->type == SP_ATTACHMENT_MESH) {
			spMeshAttachment* mesh = (spMeshAttachment*)slot->attachment;
			spMeshAttachment_computeWorldVertices(mesh, slot, _worldVertices);
			verticesCount = mesh->super.worldVerticesLength;
		} else
			continue;
		for (int ii = 0; ii < verticesCount; ii += 2) {
			float x = _worldVertices[ii] * scaleX, y = _worldVertices[ii + 1] * scaleY;
			minX = min(minX, x);
			minY = min(minY, y);
			maxX = max(maxX, x);
			maxY = max(maxY, y);
		}
	}
	Vec2 position = getPosition();
    if (minX == FLT_MAX) minX = minY = maxX = maxY = 0;    
	return Rect(position.x + minX, position.y + minY, maxX - minX, maxY - minY);
}
void spRegionAttachment_updateQuad (spRegionAttachment* self, spSlot* slot, V3F_C4B_T2F_Quad* quad, bool premultipliedAlpha) {
	float vertices[8];
	spRegionAttachment_computeWorldVertices(self, slot->skeleton->x, slot->skeleton->y, slot->bone, vertices);

	GLubyte r = slot->skeleton->r * slot->r * 255;
	GLubyte g = slot->skeleton->g * slot->g * 255;
	GLubyte b = slot->skeleton->b * slot->b * 255;
	float normalizedAlpha = slot->skeleton->a * slot->a;
	if (premultipliedAlpha) {
		r *= normalizedAlpha;
		g *= normalizedAlpha;
		b *= normalizedAlpha;
	}
	GLubyte a = normalizedAlpha * 255;
	quad->bl.colors.r = r;
	quad->bl.colors.g = g;
	quad->bl.colors.b = b;
	quad->bl.colors.a = a;
	quad->tl.colors.r = r;
	quad->tl.colors.g = g;
	quad->tl.colors.b = b;
	quad->tl.colors.a = a;
	quad->tr.colors.r = r;
	quad->tr.colors.g = g;
	quad->tr.colors.b = b;
	quad->tr.colors.a = a;
	quad->br.colors.r = r;
	quad->br.colors.g = g;
	quad->br.colors.b = b;
	quad->br.colors.a = a;

	quad->bl.vertices.x = vertices[VERTEX_X1];
	quad->bl.vertices.y = vertices[VERTEX_Y1];
	quad->tl.vertices.x = vertices[VERTEX_X2];
	quad->tl.vertices.y = vertices[VERTEX_Y2];
	quad->tr.vertices.x = vertices[VERTEX_X3];
	quad->tr.vertices.y = vertices[VERTEX_Y3];
	quad->br.vertices.x = vertices[VERTEX_X4];
	quad->br.vertices.y = vertices[VERTEX_Y4];

	quad->bl.texCoords.u = self->uvs[VERTEX_X1];
	quad->bl.texCoords.v = self->uvs[VERTEX_Y1];
	quad->tl.texCoords.u = self->uvs[VERTEX_X2];
	quad->tl.texCoords.v = self->uvs[VERTEX_Y2];
	quad->tr.texCoords.u = self->uvs[VERTEX_X3];
	quad->tr.texCoords.v = self->uvs[VERTEX_Y3];
	quad->br.texCoords.u = self->uvs[VERTEX_X4];
	quad->br.texCoords.v = self->uvs[VERTEX_Y4];
}
void SkeletonRenderer::drawDebug (Renderer* renderer, const Mat4 &transform, uint32_t transformFlags) {

    Director* director = Director::getInstance();
    director->pushMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
    director->loadMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW, transform);
    
    DrawNode* drawNode = DrawNode::create();
    
    if (_debugSlots) {
        // Slots.
        // DrawPrimitives::setDrawColor4B(0, 0, 255, 255);
        glLineWidth(1);
        Vec2 points[4];
        V3F_C4B_T2F_Quad quad;
        for (int i = 0, n = _skeleton->slotsCount; i < n; i++) {
            spSlot* slot = _skeleton->drawOrder[i];
            if (!slot->attachment || slot->attachment->type != SP_ATTACHMENT_REGION) continue;
            spRegionAttachment* attachment = (spRegionAttachment*)slot->attachment;
            spRegionAttachment_computeWorldVertices(attachment, slot->bone, _worldVertices);
            points[0] = Vec2(_worldVertices[0], _worldVertices[1]);
            points[1] = Vec2(_worldVertices[2], _worldVertices[3]);
            points[2] = Vec2(_worldVertices[4], _worldVertices[5]);
            points[3] = Vec2(_worldVertices[6], _worldVertices[7]);
            drawNode->drawPoly(points, 4, true, Color4F::BLUE);
        }
    }
    if (_debugBones) {
        // Bone lengths.
        glLineWidth(2);
        for (int i = 0, n = _skeleton->bonesCount; i < n; i++) {
            spBone *bone = _skeleton->bones[i];
            float x = bone->data->length * bone->a + bone->worldX;
            float y = bone->data->length * bone->c + bone->worldY;
            drawNode->drawLine(Vec2(bone->worldX, bone->worldY), Vec2(x, y), Color4F::RED);
        }
        // Bone origins.
        auto color = Color4F::BLUE; // Root bone is blue.
        for (int i = 0, n = _skeleton->bonesCount; i < n; i++) {
            spBone *bone = _skeleton->bones[i];
            drawNode->drawPoint(Vec2(bone->worldX, bone->worldY), 4, color);
            if (i == 0) color = Color4F::GREEN;
        }
    }
    
    drawNode->draw(renderer, transform, transformFlags);
    director->popMatrix(MATRIX_STACK_TYPE::MATRIX_STACK_MODELVIEW);
}
Exemplo n.º 5
0
QRectF SkeletonAnimationFbo::calculateSkeletonRect()
{
    if (!isSkeletonValid())
        return QRectF();

    float minX = FLT_MAX, minY = FLT_MAX, maxX = FLT_MIN, maxY = FLT_MIN;
    for (int i = 0; i < mspSkeleton->slotsCount; ++i) {
        spSlot* slot = mspSkeleton->slots[i];
        if (!slot->attachment)
            continue;

        int verticesCount;
        if (slot->attachment->type == SP_ATTACHMENT_REGION) {
            spRegionAttachment* attachment = (spRegionAttachment*)slot->attachment;
            spRegionAttachment_computeWorldVertices(attachment, slot->bone, mWorldVertices);
            verticesCount = 8;
        } else if (slot->attachment->type == SP_ATTACHMENT_MESH) {
            spMeshAttachment* mesh = (spMeshAttachment*)slot->attachment;
            spMeshAttachment_computeWorldVertices(mesh, slot, mWorldVertices);
            verticesCount = mesh->verticesCount;
        } else if (slot->attachment->type == SP_ATTACHMENT_SKINNED_MESH) {
            spSkinnedMeshAttachment* mesh = (spSkinnedMeshAttachment*)slot->attachment;
            spSkinnedMeshAttachment_computeWorldVertices(mesh, slot, mWorldVertices);
            verticesCount = mesh->uvsCount;
        } else
            continue;

        for (int ii = 0; ii < verticesCount; ii += 2) {
            float x = mWorldVertices[ii], y = mWorldVertices[ii + 1];
            minX = qMin(minX, x);
            minY = qMin(minY, y);
            maxX = qMax(maxX, x);
            maxY = qMax(maxY, y);
        }
    }

    QRectF rect(minX, minY, maxX - minX, maxY - minY);
    return rect;
}
void SpineAnimation::draw(JNIEnv* env, int offset) {

	int i, bufferIndex = offset;

	pthread_mutex_lock(&mutex);

	for(i = 0; i < skeleton->slotCount; i++) {

		spSlot* slot = skeleton->drawOrder[i];

		spBone* bone = slot->bone;

		if(bone && slot->attachment) {
			float* buffer = this->boneVertBuffers[ bone->data->name ];

			spRegionAttachment_computeWorldVertices((spRegionAttachment*) slot->attachment, x, y, bone, buffer);

			if(this->translator) {
				if(this->vertices) {
					bufferIndex = this->translator->translate( buffer, this->vertices, bufferIndex, this->stride);
				}
				else {
					callback->onError(env, "No vertex buffer found!");
					__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "No vertex buffer found!");
					break;
				}
			}
			else {
				callback->onError(env, "No vertex translator found!");
				__android_log_print(ANDROID_LOG_ERROR, LOG_TAG, "No vertex translator defined!");
				break;
			}
		}
	}

	pthread_mutex_unlock(&mutex);
}
Exemplo n.º 7
0
    void SpineDrawable::updateBoundingBox()
    {
        boundingBox.reset();

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

            if (attachment)
            {
                if (attachment->type == SP_ATTACHMENT_REGION)
                {
                    spRegionAttachment* regionAttachment = reinterpret_cast<spRegionAttachment*>(attachment);
                    spRegionAttachment_computeWorldVertices(regionAttachment, slot->bone, worldVertices, 0, 2);

                    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));
                }
                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);

                    for (int t = 0; t < meshAttachment->trianglesCount; ++t)
                    {
                        int index = meshAttachment->triangles[t] << 1;

                        boundingBox.insertPoint(ouzel::Vector3(worldVertices[index], worldVertices[index + 1], 0.0F));
                    }
                }
            }
        }
    }
Exemplo n.º 8
0
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();
}
Exemplo n.º 9
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);

	
}
Exemplo n.º 10
0
void SkeletonRenderer::draw (Renderer* renderer, const Mat4& transform, uint32_t transformFlags) {
	SkeletonBatch* batch = SkeletonBatch::getInstance();

	Color3B nodeColor = getColor();
	_skeleton->r = nodeColor.r / (float)255;
	_skeleton->g = nodeColor.g / (float)255;
	_skeleton->b = nodeColor.b / (float)255;
	_skeleton->a = getDisplayedOpacity() / (float)255;
    
    Color4F color;
	AttachmentVertices* attachmentVertices = nullptr;
	for (int i = 0, n = _skeleton->slotsCount; i < n; ++i) {
		spSlot* slot = _skeleton->drawOrder[i];
		if (!slot->attachment) continue;

		switch (slot->attachment->type) {
		case SP_ATTACHMENT_REGION: {
			spRegionAttachment* attachment = (spRegionAttachment*)slot->attachment;
			spRegionAttachment_computeWorldVertices(attachment, slot->bone, _worldVertices);
			attachmentVertices = getAttachmentVertices(attachment);
            color.r = attachment->r;
			color.g = attachment->g;
			color.b = attachment->b;
			color.a = attachment->a;
			break;
		}
		case SP_ATTACHMENT_MESH: {
			spMeshAttachment* attachment = (spMeshAttachment*)slot->attachment;
			spMeshAttachment_computeWorldVertices(attachment, slot, _worldVertices);
			attachmentVertices = getAttachmentVertices(attachment);
            color.r = attachment->r;
            color.g = attachment->g;
            color.b = attachment->b;
            color.a = attachment->a;
			break;
		}
		default:
			continue;
		}

		color.a *= _skeleton->a * slot->a * 255;
		float multiplier = _premultipliedAlpha ? color.a : 255;
		color.r *= _skeleton->r * slot->r * multiplier;
		color.g *= _skeleton->g * slot->g * multiplier;
		color.b *= _skeleton->b * slot->b * multiplier;
        
        
        
		for (int v = 0, w = 0, vn = attachmentVertices->_triangles->vertCount; v < vn; ++v, w += 2) {
			V3F_C4B_T2F* vertex = attachmentVertices->_triangles->verts + v;
			vertex->vertices.x = _worldVertices[w];
			vertex->vertices.y = _worldVertices[w + 1];
            vertex->colors.r = (GLubyte)color.r;
            vertex->colors.g = (GLubyte)color.g;
            vertex->colors.b = (GLubyte)color.b;
            vertex->colors.a = (GLubyte)color.a;
		}

		BlendFunc blendFunc;
		switch (slot->data->blendMode) {
		case SP_BLEND_MODE_ADDITIVE:
			blendFunc.src = _premultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
			blendFunc.dst = GL_ONE;
			break;
		case SP_BLEND_MODE_MULTIPLY:
			blendFunc.src = GL_DST_COLOR;
			blendFunc.dst = GL_ONE_MINUS_SRC_ALPHA;
			break;
		case SP_BLEND_MODE_SCREEN:
			blendFunc.src = GL_ONE;
			blendFunc.dst = GL_ONE_MINUS_SRC_COLOR;
			break;
		default:
			blendFunc.src = _premultipliedAlpha ? GL_ONE : GL_SRC_ALPHA;
			blendFunc.dst = GL_ONE_MINUS_SRC_ALPHA;
		}

		batch->addCommand(renderer, _globalZOrder, attachmentVertices->_texture->getName(), _glProgramState, blendFunc,
			*attachmentVertices->_triangles, transform, transformFlags);
	}

	if (_debugSlots || _debugBones) {
        drawDebug(renderer, transform, transformFlags);
	}
}
Exemplo n.º 11
0
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));
	}
}
Exemplo n.º 12
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));
}
Exemplo n.º 13
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);
        }
    }
Exemplo n.º 14
0
void SkeletonAnimationFbo::renderToCache(Renderer* renderer, RenderCmdsCache* cache)
{
    if (!cache)
        return;
    cache->clear();

    if (!renderer)
        return;

    SkeletonRenderer* skeletonRenderer = (SkeletonRenderer*)renderer;
    if (mShouldRelaseCacheTexture){
        mShouldRelaseCacheTexture = false;
        skeletonRenderer->releaseTextures();
    }

    const QRectF rect = calculateSkeletonRect();

    if (!isSkeletonValid())
        return;

    cache->setSkeletonRect(rect);

    cache->bindShader(RenderCmdsCache::ShaderTexture);
    int additive = -1;
    Color color;
    const float* uvs = 0;
    int verticesCount = 0;
    const int* triangles = 0;
    int trianglesCount = 0;
    float r = 0, g = 0, b = 0, a = 0;
    for (int i = 0, n = mspSkeleton->slotsCount; i < n; i++) {
        spSlot* slot = mspSkeleton->drawOrder[i];
        if (!slot->attachment)
            continue;

        Texture *texture = 0;
        switch (slot->attachment->type) {
        case SP_ATTACHMENT_REGION: {
            spRegionAttachment* attachment = (spRegionAttachment*)slot->attachment;
            spRegionAttachment_computeWorldVertices(attachment, slot->bone, mWorldVertices);
            texture = getTexture(attachment);
            uvs = attachment->uvs;
            verticesCount = 8;
            triangles = quadTriangles;
            trianglesCount = 6;
            r = attachment->r;
            g = attachment->g;
            b = attachment->b;
            a = attachment->a;
            break;
        }
        case SP_ATTACHMENT_MESH: {
            spMeshAttachment* attachment = (spMeshAttachment*)slot->attachment;
            spMeshAttachment_computeWorldVertices(attachment, slot, mWorldVertices);
            texture = getTexture(attachment);
            uvs = attachment->uvs;
            verticesCount = attachment->verticesCount;
            triangles = attachment->triangles;
            trianglesCount = attachment->trianglesCount;
            r = attachment->r;
            g = attachment->g;
            b = attachment->b;
            a = attachment->a;
            break;
        }
        case SP_ATTACHMENT_SKINNED_MESH: {
            spSkinnedMeshAttachment* attachment = (spSkinnedMeshAttachment*)slot->attachment;
            spSkinnedMeshAttachment_computeWorldVertices(attachment, slot, mWorldVertices);
            texture = getTexture(attachment);
            uvs = attachment->uvs;
            verticesCount = attachment->uvsCount;
            triangles = attachment->triangles;
            trianglesCount = attachment->trianglesCount;
            r = attachment->r;
            g = attachment->g;
            b = attachment->b;
            a = attachment->a;
            break;
        }
        default:
            break;
        }// END switch (slot->attachment->type)

        if (texture) {
            if (slot->data->additiveBlending != additive) {
                cache->cacheTriangleDrawCall();
                cache->blendFunc(GL_ONE, slot->data->additiveBlending ? GL_ONE : GL_ONE_MINUS_SRC_ALPHA);
                additive = slot->data->additiveBlending;
            }
            color.a = mspSkeleton->a * slot->a * a * 255;
            float multiplier = mPremultipliedAlapha ? color.a : 255;
            color.r = mspSkeleton->r * slot->r * r * multiplier;
            color.g = mspSkeleton->g * slot->g * g * multiplier;
            color.b = mspSkeleton->b * slot->b * b * multiplier;
            cache->drawTriangles(skeletonRenderer->getGLTexture(texture, window()), mWorldVertices, uvs, verticesCount, triangles, trianglesCount, color);
        }// END if (texture)
    }// END for (int i = 0, n = skeleton->slotsCount; i < n; i++)
    cache->cacheTriangleDrawCall();

    if (mDebugSlots || mDebugBones) {
        cache->bindShader(RenderCmdsCache::ShaderColor);
        if (mDebugSlots) {
            // Slots.
            cache->drawColor(0, 0, 255, 255);
            cache->lineWidth(1);

            Point points[4];
            for (int i = 0, n = mspSkeleton->slotsCount; i < n; i++) {
                spSlot* slot = mspSkeleton->drawOrder[i];
                if (!slot->attachment || slot->attachment->type != SP_ATTACHMENT_REGION) continue;
                spRegionAttachment* attachment = (spRegionAttachment*)slot->attachment;
                spRegionAttachment_computeWorldVertices(attachment, slot->bone, mWorldVertices);
                points[0] = Point(mWorldVertices[0], mWorldVertices[1]);
                points[1] = Point(mWorldVertices[2], mWorldVertices[3]);
                points[2] = Point(mWorldVertices[4], mWorldVertices[5]);
                points[3] = Point(mWorldVertices[6], mWorldVertices[7]);
                cache->drawPoly(points, 4);
            }
        }// END if (mDebugSlots)

        if (mDebugBones) {
            // Bone lengths.
            cache->lineWidth(2);
            cache->drawColor(255, 0, 0, 255);
            for (int i = 0, n = mspSkeleton->bonesCount; i < n; i++) {
                spBone *bone = mspSkeleton->bones[i];
                float x = bone->data->length * bone->m00 + bone->worldX;
                float y = bone->data->length * bone->m10 + bone->worldY;
                cache->drawLine(Point(bone->worldX, bone->worldY), Point(x, y));
            }
            // Bone origins.
            cache->pointSize(4.0);
            cache->drawColor(0, 0, 255, 255); // Root bone is blue.
            for (int i = 0, n = mspSkeleton->bonesCount; i < n; i++) {
                spBone *bone = mspSkeleton->bones[i];
                cache->drawPoint(Point(bone->worldX, bone->worldY));
                if (i == 0) cache->drawColor(0, 255, 0, 255);
            }
        }// END if (mDebugBones)
    }//END if (mDebugSlots || mDebugBones)
}
Exemplo n.º 15
0
void SkeletonDrawable::draw (RenderTarget& target, RenderStates states) const {
	vertexArray->clear();
	states.blendMode = BlendAlpha;

	float worldVertices[8];
	for (int i = 0; i < skeleton->slotCount; ++i) {
		spSlot* slot = skeleton->drawOrder[i];
		spAttachment* attachment = slot->attachment;
		if (!attachment || attachment->type != ATTACHMENT_REGION) continue;
		spRegionAttachment* regionAttachment = (spRegionAttachment*)attachment;

		BlendMode blend = slot->data->additiveBlending ? BlendAdd : BlendAlpha;
		if (states.blendMode != blend) {
			target.draw(*vertexArray, states);
			vertexArray->clear();
			states.blendMode = blend;
		}

		spRegionAttachment_computeWorldVertices(regionAttachment, slot->skeleton->x, slot->skeleton->y, slot->bone, worldVertices);

		Uint8 r = skeleton->r * slot->r * 255;
		Uint8 g = skeleton->g * slot->g * 255;
		Uint8 b = skeleton->b * slot->b * 255;
		Uint8 a = skeleton->a * slot->a * 255;

		sf::Vertex vertices[4];
		vertices[0].color.r = r;
		vertices[0].color.g = g;
		vertices[0].color.b = b;
		vertices[0].color.a = a;
		vertices[1].color.r = r;
		vertices[1].color.g = g;
		vertices[1].color.b = b;
		vertices[1].color.a = a;
		vertices[2].color.r = r;
		vertices[2].color.g = g;
		vertices[2].color.b = b;
		vertices[2].color.a = a;
		vertices[3].color.r = r;
		vertices[3].color.g = g;
		vertices[3].color.b = b;
		vertices[3].color.a = a;

		vertices[0].position.x = worldVertices[VERTEX_X1];
		vertices[0].position.y = worldVertices[VERTEX_Y1];
		vertices[1].position.x = worldVertices[VERTEX_X2];
		vertices[1].position.y = worldVertices[VERTEX_Y2];
		vertices[2].position.x = worldVertices[VERTEX_X3];
		vertices[2].position.y = worldVertices[VERTEX_Y3];
		vertices[3].position.x = worldVertices[VERTEX_X4];
		vertices[3].position.y = worldVertices[VERTEX_Y4];

		// SMFL doesn't handle batching for us, so we'll just force a single texture per skeleton.
		states.texture = (Texture*)((spAtlasRegion*)regionAttachment->rendererObject)->page->rendererObject;

		Vector2u size = states.texture->getSize();
		vertices[0].texCoords.x = regionAttachment->uvs[VERTEX_X1] * size.x;
		vertices[0].texCoords.y = regionAttachment->uvs[VERTEX_Y1] * size.y;
		vertices[1].texCoords.x = regionAttachment->uvs[VERTEX_X2] * size.x;
		vertices[1].texCoords.y = regionAttachment->uvs[VERTEX_Y2] * size.y;
		vertices[2].texCoords.x = regionAttachment->uvs[VERTEX_X3] * size.x;
		vertices[2].texCoords.y = regionAttachment->uvs[VERTEX_Y3] * size.y;
		vertices[3].texCoords.x = regionAttachment->uvs[VERTEX_X4] * size.x;
		vertices[3].texCoords.y = regionAttachment->uvs[VERTEX_Y4] * size.y;

		vertexArray->append(vertices[0]);
		vertexArray->append(vertices[1]);
		vertexArray->append(vertices[2]);
		vertexArray->append(vertices[3]);
	}
	target.draw(*vertexArray, states);
}