asset.h

cross platform rendering playground

src/asset/asset.h

2.93 KB
#pragma once

#include <string>
#include <vector>

#include "core/globals.h"
#include "core/math_rtm.h"
#include "shaders/renderer_types.h"

constexpr u32 ASSET_INVALID = 0xffffffffu;

struct AssetHandle {
    u32 id = ASSET_INVALID;

    bool valid() const {
        return id != ASSET_INVALID;
    }
    bool operator==(const AssetHandle &o) const {
        return id == o.id;
    }
    explicit operator bool() const {
        return valid();
    }
};

struct AssetGeometry {
    u32 first_vertex;
    u32 vertex_count;
    u32 first_index;
    u32 index_count;
};

struct AssetTexture {
    std::string name;
    std::string path;
    u8 *blob = nullptr;
    usize blob_size = 0;
    bool is_ktx = false;
    bool is_srgb = true;
    bool is_hdr = false;
};

struct AssetMaterial {
    std::string name;
    vec4 base_color = vec4(1.0f, 1.0f, 1.0f, 1.0f);
    f32 metallic = 0.2f;
    f32 roughness = 0.8f;
    vec3 emissive = vec3(0.0f);
    u32 base_color_tex = ASSET_INVALID;
    u32 normal_tex = ASSET_INVALID;
    u32 mr_tex = ASSET_INVALID;
    u32 emissive_tex = ASSET_INVALID;
    bool double_sided = false;
};

struct AssetSubmesh {
    u32 geometry = ASSET_INVALID;
    u32 material = ASSET_INVALID;
    vec3 aabb_min = vec3(0.0f);
    vec3 aabb_max = vec3(0.0f);
    vec4 sphere = vec4(0.0f, 0.0f, 0.0f, 1.0f);
};

struct AssetMesh {
    u32 first_submesh;
    u32 submesh_count;
};

struct AssetCamera {
    enum Type {
        Perspective,
        Orthographic
    };
    Type type;
    f32 yfov;
    f32 znear;
    f32 zfar;
    f32 aspect_ratio;
};

struct AssetLight {
    enum Type {
        Directional,
        Point
    };
    Type type;
    vec3 color = {1.0f, 1.0f, 1.0f};
    f32 intensity = 1.0f;
    f32 range = 0.0f;
};

struct AssetNode {
    mat4 local = identity();
    int parent = -1;
    u32 first_child;
    u32 child_count;
    u32 mesh = ASSET_INVALID;
    i32 camera = -1;
    i32 light = -1;
    u32 first_instance;
    u32 instance_count;
};

struct AssetScene {
    std::string name;
    std::vector<Vertex> vertices;
    std::vector<u32> indices;
    std::vector<AssetGeometry> geometries;
    std::vector<AssetTexture> textures;
    std::vector<AssetMaterial> materials;
    std::vector<AssetSubmesh> submeshes;
    std::vector<AssetMesh> meshes;
    std::vector<AssetNode> nodes;
    std::vector<AssetCamera> cameras;
    std::vector<AssetLight> lights;
    std::vector<u32> child_indices;
    std::vector<u32> mesh_submeshes;
    std::vector<TRS> instance_locals;
    std::vector<u32> root_nodes;

    std::vector<std::string> submesh_names;
    std::vector<std::string> mesh_names;
    std::vector<std::string> node_names;
};

class AssetManager {
  public:
    AssetHandle load(const char *path);
    const AssetScene *get(AssetHandle h) const;
    AssetScene *get(AssetHandle h);
    u32 count() const {
        return (u32)assets.size();
    }

  private:
    std::vector<AssetScene> assets;
};

bool load_gltf_asset(const char *path, AssetScene &out);