Dandelion 1.1.2
A light-weight 3D builder for educational usage
载入中...
搜索中...
未找到
scene.h
浏览该文件的文档.
1#ifndef DANDELION_SCENE_SCENE_H
2#define DANDELION_SCENE_SCENE_H
3
4#include <memory>
5#include <string>
6#include <vector>
7#include <list>
8#include <chrono>
9#include <string_view>
10
11#include <spdlog/spdlog.h>
12
13#include "group.h"
14#include "camera.h"
15#include "light.h"
16#include "../platform/gl.hpp"
20
21/*!
22 * \file scene/scene.h
23 * \ingroup rendering
24 * \ingroup simulation
25 * \~chinese
26 * \brief 包含场景的类。
27 */
28
29/*!
30 * \ingroup rendering
31 * \ingroup simulation
32 * \~chinese
33 * \brief 表示一个包含相机、光源、物体等对象的完整场景。
34 *
35 * `Scene` 是一个对象语义的类,它既包含完成图形设计和渲染所需的全部数据,
36 * 也具有渲染自身预览效果的功能。当前的设计是:控制器 (Controller) 在 OpenGL
37 * 上下文被创建后即创建场景实例,该实例在程序的整个生命周期中都是唯一的。因此,
38 * 复制或移动 `Scene` 实例都是错误的行为,因为这有可能导致场景数据不一致。
39 * 未来加入修改历史记录时,此设计思路有可能被改变。
40 *
41 * 场景可以是空的,如果它非空,则可以包含若干个物体组 (Group);
42 * 每个组也可以为空或包含若干物体 (Object),物体是场景中的最小单元,不能再分了。
43 * 各种数据遵循“尽可能存储到更小单元中”的原则,因此 `Scene` 类中只存储相机、
44 * 光源这些与任何物体都无关的数据,而材质、mesh 等数据则存储到物体中。
45 * 所有物体都由 `Scene` 对象创建并持有,当 `Scene` 对象析构时,所有的组、
46 * 物体都会自行析构。
47 */
48class Scene
49{
50public:
51
52 Scene();
53 ///@{
54 /*! \~chinese 禁止复制场景。 */
55 Scene(Scene& other) = delete;
56 Scene(const Scene& other) = delete;
57 ///@}
58 /*! \~chinese 禁止移动场景。 */
59 Scene(Scene&& other) = delete;
60 ~Scene() = default;
61 /*!
62 * \~chinese
63 * \brief 从指定路径导入模型文件到这个场景中。
64 *
65 * 这个函数只会根据文件名创建一个物体组,然后调用物体组的 `load_models` 方法加载文件。
66 *
67 * \param file_path 要导入的模型文件路径
68 * \returns 加载是否成功
69 */
70 bool import_model(const std::string& file_path);
71 /*!
72 * \~chinese
73 * \brief 保存所有场景数据到指定的目录中。
74 *
75 * 保存场景时涉及两类数据:
76 * - 模型数据(包括几何数据和材质数据),会被保存为通用模型文件格式
77 * - 元数据,Dandelion 特有的组、物体信息等,会被保存为 metadata.json 文件
78 *
79 * \param directory 场景文件夹路径
80 * \returns 是否保存成功
81 */
82 bool save(const std::string_view directory);
83 /*!
84 * \~chinese
85 * \brief 从指定目录中加载保存的场景数据。
86 *
87 * 与 `save` 方法相对应,`load` 会从保存的数据中恢复模型、物体、组、相机、
88 * 光源等全部信息。
89 * \param directory 要加载的场景文件夹路径
90 * \returns 是否加载成功
91 */
92 bool load(const std::string_view directory);
93 /*!
94 * \~chinese
95 * \brief 清除场景中所有元素
96 */
97 void clear();
98 /*! \~chinese 备份物体当前状态并开始模拟,此后每一帧都会调用所有物体的 `update` 方法。 */
99 void start_simulation();
100 /*! \~chinese 停止模拟,此后不再调用物体的 `update` 方法。 */
101 void stop_simulation();
102 /*! \~chinese 恢复物体在动画开始前的状态。 */
103 void reset_simulation();
104 /*! \~chinese 查询当前是否正在进行物理模拟。 */
106 /*! \~chinese
107 * \brief 绘制整个场景。
108 *
109 * `render` 方法是场景对外的绘制接口,不会直接绘制任何内容,只负责调用每个 `Object` 的 `render`
110 * 方法、`render_camera` 和 `render_lights` 方法。
111 *
112 * \param shader `Shader` 对象的引用,会传给待渲染的每个物体
113 * \param mode 当前工作模式,根据模式的不同,会选择性渲染某些元素。
114 * 例如只有建模模式下,才会渲染半边网格
115 */
116 void render(const Shader& shader, WorkingMode mode);
117
118 /*! \~chinese 场景中所有的物体组。 */
119 std::vector<std::unique_ptr<Group>> groups;
120 /*!
121 * \~chinese
122 * \brief 当前被选中的物体。
123 *
124 * 在布局模式和物理模拟模式下,它决定当前被高亮的物体;在建模模式下,仅有这个物体被绘制。
125 */
127 /*! \~chinese 用于预览场景的观察相机(主相机)。 */
129 /*! \~chinese 用于 **离线渲染** 的相机,和用于预览场景的观察相机(主相机)无关。 */
131 /*! \~chinese 用于 **离线渲染** 的光源,和预览时照亮物体的光源无关。 */
132 std::list<Light> lights;
133 /*! \~chinese 用于建模模式的半边网格。 */
134 std::unique_ptr<HalfedgeMesh> halfedge_mesh;
135
136private:
137
138 /*! \~chinese
139 * \brief 绘制空间坐标轴和 \f$y=1\f$ 平面上表示地面的网格线。
140 *
141 * 这个函数在 \f$x\f$ 和 \f$z\f$ 方向各绘制 1000 条网格线,并分别用红、绿、蓝三色绘制
142 * \f$x,y,z\f$ 三轴正半轴。
143 *
144 * \param shader `Shader` 对象的引用
145 */
146 static void render_ground(const Shader& shader);
147 /*!
148 * \~chinese
149 * 主相机的初始位置。
150 */
151 static Eigen::Vector3f initial_camera_pos;
152 /*!
153 * \~chinese
154 * 主相机的初始观察目标点(看向的位置)。
155 */
156 static Eigen::Vector3f initial_camera_target;
157 /*!
158 * \~chinese
159 * 保存场景元数据的文件名。
160 */
161 static constexpr std::string_view metadata_filename = "metadata.json";
162 /*! \~chinese
163 * \brief 在渲染模式 (Rendering mode) 下绘制代表相机视锥的线框。
164 *
165 * 根据场景对象的相机参数(位置、目标点、远近平面、视角),绘制四棱锥形的相机视锥。
166 * 由于近平面通常离相机视点很近,这个函数不会绘制近平面。离线渲染时,
167 * 会裁剪掉视锥范围外的所有内容。
168 *
169 * \param shader `Shader` 对象的引用
170 */
171 void render_camera(const Shader& shader);
172 /*! \~chinese
173 * \brief 在渲染模式下绘制光源。
174 *
175 * 这个函数将一个点光源表示成一个中心点和六个亮点。
176 *
177 * \param shader `Shader` 对象的引用
178 */
179 void render_lights(const Shader& shader);
180 /*!
181 * \~chinese
182 * \brief 计算场景中所有物体下一帧要渲染的运动状态。
183 *
184 * 这个函数按照固定的时间步长模拟物体运动。
185 *
186 * 每一帧的渲染过程可以概括为更新数据(几何、运动等等)和渲染图像两步。
187 * 约定当前屏幕上显示的是上一帧的图像,正在计算的是当前帧的数据。
188 * 更新运动状态时首先用当前时间减去 `last_update` 得到上一帧和之前帧剩余时长之和;
189 * 再循环模拟物体运动。每循环一次走过一个长度为 `time_step` 的时间步、
190 * 剩余时长减去 `time_step` ;当剩余时长不足一个 `time_step` 时停止模拟,
191 * 并将这一帧模拟走过的总时长累加到 `last_update` 上。
192 */
193 void simulation_update();
194 /*! \~chinese 状态变量,表示当前是否正在进行物理模拟。 */
196 /*! \~chinese 上一次将模拟状态同步到渲染的时间点。 */
197 std::chrono::time_point<std::chrono::steady_clock> last_update;
198 /*! \~chinese 碰撞检测时记录所有物体,其他情况下无效。 */
199 std::vector<Object*> all_objects;
200 /*! \~chinese 用于在物理模拟模式下显示速度向量。 */
202 /*! \~chinese 日志记录器。 */
203 std::shared_ptr<spdlog::logger> logger;
204};
205
206#endif // DANDELION_SCENE_SCENE_H
包含相机的类,用来表示场景中的相机。
表示物体的类。
定义 object.h:42
bool during_animation
定义 scene.h:195
void reset_simulation()
定义 scene.cpp:362
bool check_during_simulation()
定义 scene.cpp:375
Scene(Scene &other)=delete
void render_lights(const Shader &shader)
在渲染模式下绘制光源。
定义 scene.cpp:161
void render(const Shader &shader, WorkingMode mode)
绘制整个场景。
定义 scene.cpp:380
std::vector< std::unique_ptr< Group > > groups
定义 scene.h:119
bool load(const std::string_view directory)
从指定目录中加载保存的场景数据。
定义 scene.cpp:274
void render_camera(const Shader &shader)
在渲染模式 (Rendering mode) 下绘制代表相机视锥的线框。
定义 scene.cpp:114
static void render_ground(const Shader &shader)
绘制空间坐标轴和 平面上表示地面的网格线。
定义 scene.cpp:54
std::shared_ptr< spdlog::logger > logger
定义 scene.h:203
void stop_simulation()
定义 scene.cpp:357
GL::LineSet arrows
定义 scene.h:201
static Eigen::Vector3f initial_camera_target
定义 scene.h:156
bool import_model(const std::string &file_path)
从指定路径导入模型文件到这个场景中。
定义 scene.cpp:196
void clear()
清除场景中所有元素
定义 scene.cpp:329
std::list< Light > lights
定义 scene.h:132
static Eigen::Vector3f initial_camera_pos
定义 scene.h:151
void start_simulation()
定义 scene.cpp:340
std::unique_ptr< HalfedgeMesh > halfedge_mesh
定义 scene.h:134
Scene(const Scene &other)=delete
Camera main_camera
定义 scene.h:128
bool save(const std::string_view directory)
保存所有场景数据到指定的目录中。
定义 scene.cpp:212
static constexpr std::string_view metadata_filename
定义 scene.h:161
std::chrono::time_point< std::chrono::steady_clock > last_update
定义 scene.h:197
std::vector< Object * > all_objects
定义 scene.h:199
Object * selected_object
当前被选中的物体。
定义 scene.h:126
Scene(Scene &&other)=delete
void simulation_update()
计算场景中所有物体下一帧要渲染的运动状态。
定义 scene.cpp:437
Camera camera
定义 scene.h:130
对 GLSL Shader 的简单封装。
定义 shader.hpp:24
包含物体组的类。
半边网格所需各种类型的公共头文件。
包含光源的类,目前只有一个点光源。
这个文件定义了一些和渲染(离线渲染或场景预览)相关的常量、枚举等。
WorkingMode
定义 rendering.hpp:46
表示观察点的相机,既可以用于预览视角,也可以用于渲染视角。
定义 camera.h:24
在预览场景时绘制若干线条。
定义 gl.hpp:334