Beispiel #1
0
int spSkeletonClipping_clipStart(spSkeletonClipping* self, spSlot* slot, spClippingAttachment* clip) {
	int i, n;
	float* vertices;
	if (self->clipAttachment) return 0;
	self->clipAttachment = clip;

	n = clip->super.worldVerticesLength;
	vertices = spFloatArray_setSize(self->clippingPolygon, n)->items;
	spVertexAttachment_computeWorldVertices(SUPER(clip), slot, 0, n, vertices, 0, 2);
	_makeClockwise(self->clippingPolygon);
	self->clippingPolygons = spTriangulator_decompose(self->triangulator, self->clippingPolygon, spTriangulator_triangulate(self->triangulator, self->clippingPolygon));
	for (i = 0, n = self->clippingPolygons->size; i < n; i++) {
		spFloatArray* polygon = self->clippingPolygons->items[i];
		_makeClockwise(polygon);
		spFloatArray_add(polygon, polygon->items[0]);
		spFloatArray_add(polygon, polygon->items[1]);
	}
	return self->clippingPolygons->size;
}
    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));
                    }
                }
            }
        }
    }
    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);
        }
    }
Beispiel #4
0
void spMeshAttachment_computeWorldVertices (spMeshAttachment* self, spSlot* slot, float* worldVertices) {
	spVertexAttachment_computeWorldVertices(SUPER(self), slot, worldVertices);
}