scene.h 2.33 KB
Newer Older
TheNumbat's avatar
TheNumbat committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99

#pragma once

#include <map>
#include <optional>
#include <functional>

#include "../lib/mathlib.h"
#include "../util/camera.h"
#include "../platform/gl.h"
#include "../geometry/halfedge.h"

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

class Undo;
class Halfedge_Editor;
namespace Gui { class Manager; class Animate; }

class Scene_Item {
public:
	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);
	}	

private:
	std::variant<Scene_Object, Scene_Light> data;
};

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

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

	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);

    bool empty();
    size_t size();
	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;

    Scene_Maybe get(Scene_ID id);
    Scene_Object& get_obj(Scene_ID id);
	Scene_Light& get_light(Scene_ID id);
	std::string set_env_map(std::string file);

	bool has_env_light() const;

private:
	std::map<Scene_ID, Scene_Item> objs;
	std::map<Scene_ID, Scene_Item> erased;
	Scene_ID next_id, first_id;
};