scene.h 2.45 KB
Newer Older
TheNumbat's avatar
TheNumbat committed
1
2
3

#pragma once

TheNumbat's avatar
TheNumbat committed
4
#include <functional>
TheNumbat's avatar
TheNumbat committed
5
6
7
#include <map>
#include <optional>

TheNumbat's avatar
TheNumbat committed
8
#include "../geometry/halfedge.h"
TheNumbat's avatar
TheNumbat committed
9
10
#include "../lib/mathlib.h"
#include "../platform/gl.h"
TheNumbat's avatar
TheNumbat committed
11
#include "../util/camera.h"
TheNumbat's avatar
TheNumbat committed
12
13
14
15
16
17

#include "light.h"
#include "object.h"

class Undo;
class Halfedge_Editor;
TheNumbat's avatar
TheNumbat committed
18
19
20
21
namespace Gui {
class Manager;
class Animate;
} // namespace Gui
TheNumbat's avatar
TheNumbat committed
22
23
24

class Scene_Item {
public:
TheNumbat's avatar
TheNumbat committed
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
    Scene_Item() = default;
    Scene_Item(Scene_Object &&obj);
    Scene_Item(Scene_Light &&light);

    Scene_Item(Scene_Item &&src);
    Scene_Item(const Scene_Item &src) = delete;

    Scene_Item &operator=(Scene_Item &&src);
    Scene_Item &operator=(const Scene_Item &src) = delete;

    BBox bbox();
    void render(const Mat4 &view, bool solid = false, bool depth_only = false, bool posed = true);
    Scene_ID id() const;

    Pose &pose();
    const Pose &pose() const;
    Anim_Pose &animation();
    const Anim_Pose &animation() const;
    void set_time(float time);

    std::string name() const;
    std::pair<char *, int> name();

    template <typename T> bool is() const { return std::holds_alternative<T>(data); }
    template <typename T> T &get() { return std::get<T>(data); }
    template <typename T> const T &get() const { return std::get<T>(data); }
TheNumbat's avatar
TheNumbat committed
51
52

private:
TheNumbat's avatar
TheNumbat committed
53
    std::variant<Scene_Object, Scene_Light> data;
TheNumbat's avatar
TheNumbat committed
54
55
56
57
58
59
60
61
62
};

using Scene_Maybe = std::optional<std::reference_wrapper<Scene_Item>>;

class Scene {
public:
    Scene(Scene_ID start);
    ~Scene() = default;

TheNumbat's avatar
TheNumbat committed
63
64
65
    std::string write(std::string file, const Camera &cam, const Gui::Animate &animation);
    std::string load(bool new_scene, Undo &undo, Gui::Manager &gui, std::string file);
    void clear(Undo &undo);
TheNumbat's avatar
TheNumbat committed
66
67
68

    bool empty();
    size_t size();
TheNumbat's avatar
TheNumbat committed
69
70
71
72
73
74
75
76
77
78
79
80
    Scene_ID add(Scene_Object &&obj);
    Scene_ID add(Scene_Light &&obj);
    Scene_ID add(Pose pose, GL::Mesh &&mesh, std::string n = {}, Scene_ID id = 0);
    Scene_ID add(Pose pose, Halfedge_Mesh &&mesh, std::string n = {}, Scene_ID id = 0);
    Scene_ID reserve_id();
    Scene_ID used_ids();

    void erase(Scene_ID id);
    void restore(Scene_ID id);

    void for_items(std::function<void(Scene_Item &)> func);
    void for_items(std::function<void(const Scene_Item &)> func) const;
TheNumbat's avatar
TheNumbat committed
81
82

    Scene_Maybe get(Scene_ID id);
TheNumbat's avatar
TheNumbat committed
83
84
85
    Scene_Object &get_obj(Scene_ID id);
    Scene_Light &get_light(Scene_ID id);
    std::string set_env_map(std::string file);
TheNumbat's avatar
TheNumbat committed
86

TheNumbat's avatar
TheNumbat committed
87
    bool has_env_light() const;
TheNumbat's avatar
TheNumbat committed
88
89

private:
TheNumbat's avatar
TheNumbat committed
90
91
92
    std::map<Scene_ID, Scene_Item> objs;
    std::map<Scene_ID, Scene_Item> erased;
    Scene_ID next_id, first_id;
TheNumbat's avatar
TheNumbat committed
93
};