scene.h

cross platform rendering playground

src/scene/scene.h

2.68 KB
#pragma once

#include <vector>

#include "asset/asset.h"
#include "core/globals.h"
#include "core/math_rtm.h"
#include "scene/camera.h"
#include "scene/ibl.h"
#include "scene/light.h"
#include "shaders/renderer_types.h"

class AssetManager;

constexpr u32 SCENE_INVALID = 0xffffffffu;

struct SceneGraph {
    // Hierarchy (sibling-chain)
    std::vector<int> parent;       // parent index (-1 = root)
    std::vector<u32> first_child;  // first child index (SCENE_INVALID = none)
    std::vector<u32> next_sibling; // next sibling index (SCENE_INVALID = none)
    std::vector<u8> alive;
    std::vector<u32> free_nodes;

    // Local transforms (SoA)
    std::vector<vec3> translations;
    std::vector<rtm::quatf> rotations;
    std::vector<vec3> scales;
    std::vector<mat4> locals;

    // Computed world transforms
    std::vector<mat4> worlds;

    // Roots
    std::vector<u32> roots;

    // Per-node source asset link (parallel; ASSET_INVALID = manual node)
    std::vector<AssetHandle> asset;
    std::vector<u32> asset_index;

    // Per-node runtime instance state (parallel; block base/count in Scene::instance_locals)
    std::vector<u32> instance_base;
    std::vector<u32> instance_count;

    u32 node_count = 0;

    u32 add_node(int parent_idx, const TRS &local);
    u32 add_node(int parent_idx, const mat4 &local);

    bool delete_node(u32 node);
    bool is_node_alive(u32 node) const;
    bool is_descendant(u32 node, u32 ancestor) const;

    bool reparent(u32 node, int new_parent);
    bool reparent_keep_world(u32 node, int new_parent);

    void set_local_trs(u32 index, const TRS &trs);
    void set_local_matrix(u32 index, const mat4 &m);
    void set_translation(u32 index, const vec3 &translation);
    void set_rotation(u32 index, const rtm::quatf &rotation);
    void set_scale(u32 index, const vec3 &scale);

    void update_world_transforms();

    TRS get_local_trs(u32 index) const;
    mat4 get_local_matrix(u32 index) const;
    mat4 get_world(u32 index) const;
};

struct Scene {
    SceneGraph scene_graph;
    EnvMap env;

    std::vector<TRS> instance_locals; // per-instance local TRS pool; slot index == GPU transform slot
    std::vector<u32> mesh_nodes;      // scene nodes that carry a mesh (built at instantiate)

    // Cameras / lights
    std::vector<Camera> cameras;
    u32 active_camera = NODE_INVALID;
    std::vector<Light> directional_lights;
    std::vector<PointLight> point_lights;

    u32 instantiate(AssetManager &mgr, AssetHandle handle, int parent_idx = -1);
    void evaluate();

    mat4 instance_world(u32 node, u32 k) const;

    const AssetScene *node_source(const AssetManager &mgr, u32 node) const;
    const char *node_name(const AssetManager &mgr, u32 node) const;
};