<commit_before>// Copyright (C) 2016 <NAME>
// This file is part of the Ouzel engine.

#include <rapidjson/rapidjson.h>
#include <rapidjson/memorystream.h>
#include <rapidjson/document.h>
#include "SpriteFrame.h"
#include "core/Engine.h"
#include "core/Cache.h"
#include "graphics/Texture.h"
#include "graphics/MeshBuffer.h"
#include "utils/Utils.h"

namespace ouzel
{
    namespace scene
    {
        std::vector<SpriteFramePtr> SpriteFrame::loadSpriteFrames(const std::string& filename, bool mipmaps)
        {
            std::vector<SpriteFramePtr> frames;

            std::vector<uint8_t> data;
            if (!sharedEngine->getFileSystem()->loadFile(filename, data))
            {
                return frames;
            }

            rapidjson::MemoryStream is(reinterpret_cast<char*>(data.data()), data.size());

            rapidjson::Document document;
            document.ParseStream<0>(is);

            if (document.HasParseError())
            {
                log("Failed to parse %s", filename.c_str());
                return frames;
            }

            const rapidjson::Value& metaObject = document["meta"];
            const rapidjson::Value& sizeObject = metaObject["size"];

            Size2 textureSize(static_cast<float>(sizeObject["w"].GetInt()),
                              static_cast<float>(sizeObject["h"].GetInt()));

            graphics::TexturePtr texture = sharedEngine->getCache()->getTexture(metaObject["image"].GetString(), false, mipmaps);

            const rapidjson::Value& framesArray = document["frames"];

            frames.reserve(framesArray.Size());

            for (rapidjson::SizeType index = 0; index < framesArray.Size(); ++index)
            {
                const rapidjson::Value& frameObject = framesArray[index];

                const rapidjson::Value& frameRectangleObject = frameObject["frame"];

                Rectangle frameRectangle(static_cast<float>(frameRectangleObject["x"].GetInt()),
                                         static_cast<float>(frameRectangleObject["y"].GetInt()),
                                         static_cast<float>(frameRectangleObject["w"].GetInt()),
                                         static_cast<float>(frameRectangleObject["h"].GetInt()));

                bool rotated = frameObject["rotated"].GetBool();

                const rapidjson::Value& sourceSizeObject = frameObject["sourceSize"];

                Size2 sourceSize(static_cast<float>(sourceSizeObject["w"].GetInt()),
                                 static_cast<float>(sourceSizeObject["h"].GetInt()));

                const rapidjson::Value& spriteSourceSizeObject = frameObject["spriteSourceSize"];

                Vector2 sourceOffset(static_cast<float>(spriteSourceSizeObject["x"].GetInt()),
                                     static_cast<float>(spriteSourceSizeObject["y"].GetInt()));

                const rapidjson::Value& pivotObject = frameObject["pivot"];

                Vector2 pivot(pivotObject["x"].GetFloat(),
                              pivotObject["y"].GetFloat());

                frames.push_back(std::make_shared<SpriteFrame>(texture, frameRectangle, rotated, sourceSize, sourceOffset, pivot));
            }

            return frames;
        }

        SpriteFrame::SpriteFrame(const graphics::TexturePtr& pTexture,
                                 const Rectangle& frameRectangle,
                                 bool rotated,
                                 const Size2& sourceSize,
                                 const Vector2& sourceOffset,
                                 const Vector2& pivot)
        {
            texture = pTexture;

            std::vector<uint16_t> indices = {0, 1, 2, 1, 3, 2};

            Vector2 textCoords[4];
            Vector2 finalOffset(-sourceSize.width * pivot.x + sourceOffset.x,
                                -sourceSize.height * pivot.y + (sourceSize.height - frameRectangle.height - sourceOffset.y));

            const Size2& textureSize = texture->getSize();

            if (!rotated)
            {
                Vector2 leftTop(frameRectangle.x / textureSize.width,
                                frameRectangle.y / textureSize.height);

                Vector2 rightBottom((frameRectangle.x + frameRectangle.width) / textureSize.width,
                                    (frameRectangle.y + frameRectangle.height) / textureSize.height);
<commit_msg>Implement sprite mesh loading from json file<commit_after>// Copyright (C) 2016 <NAME>
// This file is part of the Ouzel engine.

#include <rapidjson/rapidjson.h>
#include <rapidjson/memorystream.h>
#include <rapidjson/document.h>
#include "SpriteFrame.h"
#include "core/Engine.h"
#include "core/Cache.h"
#include "graphics/Texture.h"
#include "graphics/MeshBuffer.h"
#include "utils/Utils.h"

namespace ouzel
{
    namespace scene
    {
        std::vector<SpriteFramePtr> SpriteFrame::loadSpriteFrames(const std::string& filename, bool mipmaps)
        {
            std::vector<SpriteFramePtr> frames;

            std::vector<uint8_t> data;
            if (!sharedEngine->getFileSystem()->loadFile(filename, data))
            {
                return frames;
            }

            rapidjson::MemoryStream is(reinterpret_cast<char*>(data.data()), data.size());

            rapidjson::Document document;
            document.ParseStream<0>(is);

            if (document.HasParseError())
            {
                log("Failed to parse %s", filename.c_str());
                return frames;
            }

            const rapidjson::Value& metaObject = document["meta"];
            const rapidjson::Value& sizeObject = metaObject["size"];

            Size2 textureSize(static_cast<float>(sizeObject["w"].GetInt()),
                              static_cast<float>(sizeObject["h"].GetInt()));

            graphics::TexturePtr texture = sharedEngine->getCache()->getTexture(metaObject["image"].GetString(), false, mipmaps);

            const rapidjson::Value& framesArray = document["frames"];

            frames.reserve(framesArray.Size());

            for (rapidjson::SizeType index = 0; index < framesArray.Size(); ++index)
            {
                const rapidjson::Value& frameObject = framesArray[index];

                const rapidjson::Value& frameRectangleObject = frameObject["frame"];

                Rectangle frameRectangle(static_cast<float>(frameRectangleObject["x"].GetInt()),
                                         static_cast<float>(frameRectangleObject["y"].GetInt()),
                                         static_cast<float>(frameRectangleObject["w"].GetInt()),
                                         static_cast<float>(frameRectangleObject["h"].GetInt()));

                const rapidjson::Value& sourceSizeObject = frameObject["sourceSize"];

                Size2 sourceSize(static_cast<float>(sourceSizeObject["w"].GetInt()),
                                 static_cast<float>(sourceSizeObject["h"].GetInt()));

                const rapidjson::Value& spriteSourceSizeObject = frameObject["spriteSourceSize"];

                Vector2 sourceOffset(static_cast<float>(spriteSourceSizeObject["x"].GetInt()),
                                     static_cast<float>(spriteSourceSizeObject["y"].GetInt()));

                const rapidjson::Value& pivotObject = frameObject["pivot"];

                Vector2 pivot(pivotObject["x"].GetFloat(),
                              pivotObject["y"].GetFloat());

                if (frameObject.HasMember("vertices") &&
                    frameObject.HasMember("verticesUV") &&
                    frameObject.HasMember("triangles"))
                {
                    std::vector<uint16_t> indices;

                    const rapidjson::Value& trianglesObject = frameObject["triangles"];

                    for (rapidjson::SizeType triangleIndex = 0; triangleIndex < trianglesObject.Size(); ++triangleIndex)
                    {
                        const rapidjson::Value& triangleObject = trianglesObject[triangleIndex];

                        for (rapidjson::SizeType i = 0; i < triangleObject.Size(); ++i)
                        {
                            indices.push_back(static_cast<uint16_t>(triangleObject[i].GetUint()));
                        }
                    }

                    std::vector<graphics::VertexPCT> vertices;

                    const rapidjson::Value& verticesObject = frameObject["vertices"];
                    const rapidjson::Value& verticesUVObject = frameObject["verticesUV"];

                    const Size2& textureSize = texture->getSize();

                    Vector2 finalOffset(-sourceSize.width * pivot.x + sourceOffset.x,
                                        -sourceSize.height * pivot.y + (sourceSize.height - frameRectangle.height - sourceOffset.y));

                    for (rapidjson::SizeType vertexIndex = 0; vertexIndex < verticesObject.Size(); ++vertexIndex)
                    {
                        const rapidjson::Value& vertexObject = verticesObject[vertexIndex];
                        const rapidjson::Value& vertexUVObject = verticesUVObject[vertexIndex];

                        vertices.push_back(graphics::VertexPCT(Vector3(static_cast<float>(vertexObject[0].GetInt()) + finalOffset.x,
                                                                       -static_cast<float>(vertexObject[1].GetInt()) - finalOffset.y,
                                                                       0.0f),
                                                               graphics::Color(255, 255, 255, 255),
                                                               Vector2(static_cast<float>(vertexUVObject[0].GetInt()) / textureSize.width,
                                                                       static_cast<float>(vertexUVObject[1].GetInt()) / textureSize.height)));
                    }

                    frames.push_back(std::make_shared<SpriteFrame>(texture, indices, vertices, frameRectangle, sourceSize, sourceOffset, pivot));
                }
                else
                {
                    bool rotated = frameObject["rotated"].GetBool();

                    frames.push_back(std::make_shared<SpriteFrame>(texture, frameRectangle, rotated, sourceSize, sourceOffset, pivot));
                }
            }

            return frames;
        }

        SpriteFrame::SpriteFrame(const graphics::TexturePtr& pTexture,
                                 const Rectangle& frameRectangle,
                                 bool rotated,
                                 const Size2& sourceSize,
                                 const Vector2& sourceOffset,
                                 const Vector2& pivot)
        {
            texture = pTexture;

            std::vector<uint16_t> indices = {0, 1, 2, 1, 3, 2};

            Vector2 textCoords[4];
            Vector2 finalOffset(-sourceSize.width * pivot.x + sourceOffset.x,
                                -sourceSize.height * pivot.y + (sourceSize.height - frameRectangle.height - sourceOffset.y));

            const Size2& textureSize = texture->getSize();

            if (!rotated)
            {
                Vector2 leftTop(frameRectangle.x / textureSize.width,
                                frameRectangle.y / textureSize.height);

                Vector2 rightBottom((frameRectangle.x + frameRectangle.width) / textureSize.width,
                                    (frameRectangle.y + frameRectangle.height) / textureSize.height);

{'fraction_non_alphanumeric': 0.11250540891389009, 'fraction_numerical': 0.0073561228905235825, 'mean_word_length': 1.771887742863996, 'pattern_counts': {'":': 0, '<': 58, '<?xml version=': 0, '>': 64, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 42, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2855852', 'n_tokens_mistral': 2868, 'n_tokens_neox': 2686, 'n_words': 482}