Program Listing for File libcacaoasset.hpp

↰ Return to documentation for file (libs/asset/include/libcacaoasset.hpp)

#pragma once

#include "libjaguar/Document.hpp"
#include "libjaguar/Traits.hpp"

#include <string>
#include <cstdint>
#include <variant>

#include "DllHelper.hpp"

namespace libcacaoasset {
    struct CACAO_API Resource {
        enum class Type : uint8_t {
            Blob = 0,
            Shader = 1,
            Material = 2,
            Tex2D = 3,
            Cubemap = 4,
            Audio = 5,
            Font = 6,
            Model = 7,
            Mesh = 8,
            World = 9
        };

        std::string id;
        std::vector<unsigned char> bytes;
        Type type;
    };

    struct CACAO_API World {
        std::string skybox;
        libjaguar::Vector<float, 4> initialSkyRot;
        libjaguar::Vector<float, 3> initialCamPos;
        libjaguar::Vector<float, 4> initialCamRot;
        bool camOrthographic;
        libjaguar::Vector<uint8_t, 3> camClearColor;

        struct CACAO_API Component {
            std::string typeID;
            bool enabled;
            std::vector<unsigned char> reflection;
        };

        struct CACAO_API Actor {
            std::array<unsigned char, 16> guid;
            std::array<unsigned char, 16> parentGUID;
            std::string name;
            libjaguar::Vector<float, 3> initialPos;
            libjaguar::Vector<float, 4> initialRot;
            libjaguar::Vector<float, 3> initialScale;
            std::vector<Component> components;
            bool active;
        };
        std::vector<Actor> actors;
    };

    struct CACAO_API Shader {
        std::vector<unsigned char> irCode;
        struct CACAO_API Descriptor {
            enum class Domain : uint8_t {
                Geometry3D = 0xA,
                Canvas2D = 0xD
            } domain;

            enum class VertexMode : uint8_t {
                NoProcess = 0x00,
                PreprocessOnly = 0xD0,
                PostprocessOnly = 0x0D,
                PreprocessPostprocess = 0xDD,
                Custom = 0x37
            } mode;

            struct CACAO_API UniformParameter {
                enum class DataType : uint8_t {
                    Int = 0xD1,
                    UInt = 0xE1,
                    Float = 0xF1,
                    Bool = 0xB1,
                    Int2 = 0xD2,
                    Int3 = 0xD3,
                    Int4 = 0xD4,
                    UInt2 = 0xE2,
                    UInt3 = 0xE3,
                    UInt4 = 0xE4,
                    Float2 = 0xF2,
                    Float3 = 0xF3,
                    Float4 = 0xF4,
                    Float2x2 = 0x22,
                    Float3x3 = 0x33,
                    Float4x4 = 0x44,
                } type;

                std::string name;
                unsigned int bufferOffset;
            };

            struct CACAO_API TextureParameter {
                std::string name;
                unsigned int binding;
                bool isCubemap;
            };

            std::vector<UniformParameter> uniformParams;
            std::vector<TextureParameter> texParams;
        } descriptor;
    };

    struct CACAO_API Cubemap {
        std::vector<unsigned char> left;
        std::vector<unsigned char> right;
        std::vector<unsigned char> top;
        std::vector<unsigned char> bottom;
        std::vector<unsigned char> front;
        std::vector<unsigned char> back;
    };

    struct CACAO_API Material {
        struct CACAO_API TexRef {
            std::string address;
            bool isCubemap;
        };

        using Storage = std::variant<int, unsigned int, float, bool, TexRef, libjaguar::Vector<float, 2>, libjaguar::Vector<float, 3>, libjaguar::Vector<float, 4>,
            libjaguar::Vector<int, 2>, libjaguar::Vector<int, 3>, libjaguar::Vector<int, 4>, libjaguar::Vector<unsigned int, 2>, libjaguar::Vector<unsigned int, 3>,
            libjaguar::Vector<unsigned int, 4>, libjaguar::Matrix<float, 2, 2>, libjaguar::Matrix<float, 3, 3>, libjaguar::Matrix<float, 4, 4>>;

        struct CACAO_API Param {
            std::string target;
            Storage storage;
        };

        enum class RenderMode : uint8_t {
            Opaque = 0,
            Cutout = 1,
            Transparent = 2
        };

        std::string shaderAddress;
        std::vector<Param> parameters;
        RenderMode renderMode;
    };

    class CACAO_API AssetPack {
      public:
        AssetPack();

        static AssetPack OpenFromFile(const std::string& filePath);

        static AssetPack OpenFromStream(std::istream* stream);

        Resource GetResource(const std::string& address);

        void DeleteResource(const std::string& address);

        std::vector<std::string> ListResources();

        std::vector<std::string> ListResourcesOfType(Resource::Type type);

        bool HasResource(const std::string& address);

        void PutResource(const std::string& address, Resource&& resource);

        void Export(std::ostream* stream);

        AssetPack(const AssetPack&) = delete;
        AssetPack& operator=(const AssetPack&) = delete;
        AssetPack(AssetPack&&) = default;
        AssetPack& operator=(AssetPack&&) = default;

      private:
        libjaguar::Document doc;

        void RegisterResourceType();
        static Resource _DecResource(libjaguar::Document::ObjReader& rd);
        static void _EncResource(const Resource& r, libjaguar::Document::ObjWriter& wr);
    };

    CACAO_API bool ValidateResourceAddress(const std::string& address, Resource::Type type);

    CACAO_API World DecodeWorld(std::istream* stream);

    CACAO_API void EncodeWorld(const World& world, std::ostream* stream);

    CACAO_API Shader DecodeShader(std::istream* stream);

    CACAO_API void EncodeShader(const Shader& shader, std::ostream* stream);

    CACAO_API Material DecodeMaterial(std::istream* stream);

    CACAO_API void EncodeMaterial(const Material& material, std::ostream* stream);

    CACAO_API Cubemap DecodeCubemap(std::istream* stream);

    CACAO_API void EncodeCubemap(const Cubemap& cubemap, std::ostream* stream);
}