sculpto
scene_serializer.cpp
Go to the documentation of this file.
1/*!****************************************************************//*!*
2 * \file scene_serializer.cpp
3 * \brief Scene serialization class implemenation module.
4 *
5 * \author Sabitov Kirill
6 * \date 17 July 2022
7 *********************************************************************/
8
9#include "sclpch.h"
10
11#include "scene_serializer.h"
13#include "core/gui/gui.h"
18
19void scl::to_json(json &Json, const name_component &NameComponent)
20{
21 Json["name"] = NameComponent.Name;
22}
23
24void scl::to_json(json &Json, const transform_component &TransformComponent)
25{
26 Json["scale"] = TransformComponent.Scale;
27 Json["angles"] = TransformComponent.Angles;
28 Json["position"] = TransformComponent.Position;
29}
30
31void scl::to_json(json &Json, const camera_component &CameraComponent)
32{
33 const auto &camera = CameraComponent.Camera;
34 Json["is_primary"] = CameraComponent.IsPrimary;
35 Json["projection_type"] = (int)camera.GetProjectionType();
36 Json["fov"] = camera.GetFieldOfView();
37 Json["position"] = camera.GetPosition();
38 Json["focus_point"] = camera.GetFocus();
39 Json["up_direction"] = camera.GetUpDirection();
40 Json["viewport_width"] = camera.GetViewportWidth();
41 Json["viewport_height"] = camera.GetViewportHeight();
42 Json["effects"] = {
43 { "is_hdr", camera.Effects.HDR },
44 { "exposure", camera.Effects.Exposure },
45 { "is_bloom", camera.Effects.Bloom },
46 { "bloom_amount", camera.Effects.BloomAmount }
47 };
48}
49
50void scl::to_json(json &Json, const point_light_component &PointLightComponent)
51{
52 Json["color"] = PointLightComponent.Color;
53 Json["strength"] = PointLightComponent.Strength;
54 Json["constant_attitution"] = PointLightComponent.Constant;
55 Json["linear_attitution"] = PointLightComponent.Linear;
56 Json["quafratic_attitution"] = PointLightComponent.Quadratic;
57}
58
59void scl::to_json(json &Json, const directional_light_component &DirectionalLightComponent)
60{
61 Json["color"] = DirectionalLightComponent.Color;
62 Json["strength"] = DirectionalLightComponent.Strength;
63 Json["is_casting_shadows"] = DirectionalLightComponent.GetIsShadow();
64 Json["projection_box_size"] = DirectionalLightComponent.GetBoxSize();
65 Json["projection_box_depth"] = DirectionalLightComponent.GetBoxDepth();
66 Json["shadow_map_width"] = DirectionalLightComponent.GetShadowMapWidth();
67 Json["shadow_map_height"] = DirectionalLightComponent.GetShadowMapHeight();
68}
69
70void scl::to_json(json &Json, const spot_light_component &SpotLightComponent)
71{
72 Json["color"] = SpotLightComponent.Color;
73 Json["strength"] = SpotLightComponent.Strength;
74 Json["inner_cutoff_angle"] = SpotLightComponent.GetInnerCutoff();
75 Json["outer_cutoff_angle"] = SpotLightComponent.GetOuterCutoff();
76}
77
78bool scl::from_json(const json &Json, name_component &NameComponent)
79{
80 const auto &name = Json.find("name");
81 if (name == Json.end()) return false;
82
83 NameComponent.Name = name->get<std::string>();
84 return true;
85}
86
87bool scl::from_json(const json &Json, transform_component &TransformComponent)
88{
89 const auto &scale = Json.find("scale");
90 const auto &angles = Json.find("angles");
91 const auto &position = Json.find("position");
92
93 if (scale != Json.end()) TransformComponent.SetScale(scale->get<vec3>());
94 if (angles != Json.end()) TransformComponent.SetAngles(angles->get<vec3>());
95 if (position != Json.end()) TransformComponent.SetPosition(position->get<vec3>());
96 return true;
97}
98
99bool scl::from_json(const json &Json, camera_component &CameraComponent)
100{
101 const auto &is_primary = Json.find("is_primary");
102 const auto &projection_type = Json.find("projection_type");
103 const auto &fov = Json.find("fov");
104 const auto &position = Json.find("position");
105 const auto &focus_point = Json.find("focus_point");
106 const auto &up_direction = Json.find("up_direction");
107 const auto &viewport_width = Json.find("viewport_width");
108 const auto &viewport_height = Json.find("viewport_height");
109
110 auto &camera = CameraComponent.Camera;
111 if (is_primary != Json.end()) CameraComponent.IsPrimary = is_primary->get<bool>();
112 if (projection_type != Json.end()) camera.SetProjectionType((camera_projection_type)projection_type->get<int>());
113 if (fov != Json.end()) camera.SetFieldOfView(fov->get<float>());
114 if (position != Json.end()) camera.SetPosition(position->get<vec3>());
115 if (focus_point != Json.end()) camera.SetFocus(focus_point->get<vec3>());
116 if (up_direction != Json.end()) camera.SetUpDirection(up_direction->get<vec3>());
117 if (viewport_width != Json.end()) camera.SetViewportWidth(viewport_width->get<int>());
118 if (viewport_height != Json.end()) camera.SetViewportHeight(viewport_height->get<int>());
119
120 const auto &effects = Json.find("effects");
121 if (effects != Json.end())
122 {
123 const auto &effects_is_hdr = effects->find("is_hdr");
124 const auto &effects_exposure = effects->find("exposure");
125 const auto &effects_is_bloom = effects->find("is_bloom");
126 const auto &effects_bloom_amount = effects->find("bloom_amount");
127
128 if (effects_is_hdr != effects->end()) camera.Effects.HDR = effects_is_hdr->get<bool>();
129 if (effects_exposure != effects->end()) camera.Effects.Exposure = effects_exposure->get<float>();
130 if (effects_is_bloom != effects->end()) camera.Effects.Bloom = effects_is_bloom->get<bool>();
131 if (effects_bloom_amount != effects->end()) camera.Effects.BloomAmount = effects_bloom_amount->get<int>();
132 }
133 return true;
134}
135
136bool scl::from_json(const json &Json, point_light_component &PointLightComponent)
137{
138 const auto &color = Json.find("color");
139 const auto &strength = Json.find("strength");
140 const auto &constant_attitution = Json.find("constant_attitution");
141 const auto &linear_attitution = Json.find("linear_attitution");
142 const auto &quadratic_attitution = Json.find("quafratic_attitution");
143
144 if (color != Json.end()) PointLightComponent.Color = color->get<vec3>();
145 if (strength != Json.end()) PointLightComponent.Strength = strength->get<float>();
146 if (constant_attitution != Json.end()) PointLightComponent.Constant = constant_attitution->get<float>();
147 if (linear_attitution != Json.end()) PointLightComponent.Linear = linear_attitution->get<float>();
148 if (quadratic_attitution != Json.end()) PointLightComponent.Quadratic = quadratic_attitution->get<float>();
149 return true;
150}
151
152bool scl::from_json(const json &Json, directional_light_component &DirectionalLightComponent)
153{
154 const auto &color = Json.find("color");
155 const auto &strength = Json.find("strength");
156 const auto &is_casting_shadows = Json.find("is_casting_shadows");
157 const auto &projection_box_size = Json.find("projection_box_size");
158 const auto &projection_box_depth = Json.find("projection_box_depth");
159 const auto &shadow_map_width = Json.find("shadow_map_width");
160 const auto &shadow_map_height = Json.find("shadow_map_height");
161
162 if (color != Json.end()) DirectionalLightComponent.Color = color->get<vec3>();
163 if (strength != Json.end()) DirectionalLightComponent.Strength = strength->get<float>();
164 if (is_casting_shadows != Json.end()) DirectionalLightComponent.SetIsShadows(is_casting_shadows->get<bool>());
165 if (projection_box_size != Json.end()) DirectionalLightComponent.SetBoxSize(projection_box_size->get<float>());
166 if (projection_box_depth != Json.end()) DirectionalLightComponent.SetBoxDepth(projection_box_depth->get<float>());
167 if (shadow_map_width != Json.end()) DirectionalLightComponent.SetShadowMapWidth(shadow_map_width->get<int>());
168 if (shadow_map_height != Json.end()) DirectionalLightComponent.SetShadowMapHeight(shadow_map_height->get<int>());
169 return true;
170}
171
172bool scl::from_json(const json &Json, spot_light_component &SpotLightComponent)
173{
174 const auto &color = Json.find("color");
175 const auto &strength = Json.find("strength");
176 const auto &inner_cutoff_angle = Json.find("inner_cutoff_angle");
177 const auto &outer_cutoff_angle = Json.find("outer_cutoff_angle");
178
179 if (color != Json.end()) SpotLightComponent.Color = color->get<vec3>();
180 if (strength != Json.end()) SpotLightComponent.Strength = strength->get<float>();
181 if (inner_cutoff_angle != Json.end()) SpotLightComponent.SetInnerCutoff(inner_cutoff_angle->get<float>());
182 if (outer_cutoff_angle != Json.end()) SpotLightComponent.SetOuterCutoff(outer_cutoff_angle->get<float>());
183 return true;
184}
185
186void scl::scene_serializer::SerializeObject(json &Json, const scene_object &SceneObject)
187{
188 SerializeComponent<name_component>(Json, SceneObject);
189 SerializeComponent<transform_component>(Json, SceneObject);
190 SerializeComponent<camera_component>(Json, SceneObject);
191 SerializeComponent<point_light_component>(Json, SceneObject);
192 SerializeComponent<directional_light_component>(Json, SceneObject);
193 SerializeComponent<spot_light_component>(Json, SceneObject);
194}
195
196void scl::scene_serializer::DeserializeObject(const json &Json, scene_object &SceneObject)
197{
198 DeserializeComponent<transform_component>(Json, SceneObject);
199 DeserializeComponent<camera_component>(Json, SceneObject);
200 DeserializeComponent<point_light_component>(Json, SceneObject);
201 DeserializeComponent<directional_light_component>(Json, SceneObject);
202 DeserializeComponent<spot_light_component>(Json, SceneObject);
203}
204
205void scl::scene_serializer::Serialize(const shared<scene> &Scene, const std::filesystem::path &OutFileName)
206{
207 if (!Scene) return;
208
209 json objects_json;
210 Scene->Registry.each([&](auto Entity)
211 {
212 scene_object object = Scene->GetSceneObject(Entity);
213 if (!object) return;
214
215 json j;
216 SerializeObject(j, object);
217 objects_json.push_back(j);
218 });
219
220 json scene_json = {
221 { "gui", {
222 { "is_gui_enabled", application::Get().GuiEnabled },
223 { "is_dockspace", gui::IsDockspace },
224 } },
225 { "render", {
226 { "clear_color", render_bridge::GetClearColor() },
227 { "is_wireframe", render_bridge::GetWireframeMode() },
228 { "is_vsync", render_bridge::GetVSync() },
229 } },
230 { "scene_data", {
231 { "viewport_id", Scene->GetViewportId(), },
232 { "enviroment_ambient", Scene->GetEnviromentAmbient(), }
233 } },
234 { "objects", objects_json }
235 };
236 assets_manager::SaveFile(scene_json.dump(4), OutFileName);
237 SCL_CORE_INFO("Scene saved to file \"{}\".", OutFileName.string());
238}
239
240void scl::scene_serializer::Deserialize(shared<scene> &Scene, const std::filesystem::path &InFileName)
241{
242 const std::string root_json_string = assets_manager::LoadFile(InFileName);
243 const json root_json = json::parse(root_json_string);
244
245 const auto &gui_json = root_json.find("gui");
246 const auto &render_json = root_json.find("render");
247 const auto &scene_data_json = root_json.find("scene_data");
248 const auto &objects_json = root_json.find("objects");
249
250 if (gui_json != root_json.end())
251 {
252 const auto &is_gui_enabled = gui_json->find("is_gui_enabled");
253 const auto &is_dockspace = gui_json->find("is_dockspace");
254
255 if (is_gui_enabled != gui_json->end()) application::Get().GuiEnabled = is_gui_enabled->get<bool>();
256 if (is_dockspace != gui_json->end()) gui::IsDockspace = is_dockspace->get<bool>();
257 }
258 if (render_json != root_json.end())
259 {
260 const auto &clear_color = render_json->find("clear_color");
261 const auto &is_wireframe = render_json->find("is_wireframe");
262 const auto &is_vsync = render_json->find("is_vsync");
263
264 if (clear_color != render_json->end()) render_bridge::SetClearColor(clear_color->get<vec4>());
265 if (is_wireframe != render_json->end()) render_bridge::SetWireframeMode(is_wireframe->get<bool>());
266 if (is_vsync != render_json->end()) render_bridge::SetVSync(is_vsync->get<bool>());
267 }
268 if (scene_data_json != root_json.end())
269 {
270 const auto &viewport_id = scene_data_json->find("viewport_id");
271 const auto &enviroment_ambient = scene_data_json->find("enviroment_ambient");
272
273 if (viewport_id != scene_data_json->end()) Scene->SetViewportId(viewport_id->get<int>());
274 if (enviroment_ambient != scene_data_json->end()) Scene->SetEnviromentAmbient(enviroment_ambient->get<vec3>());
275 }
276 if (objects_json != root_json.end())
277 {
278 for (const auto &object_json : *objects_json)
279 {
280 scene_object object;
281 const auto &name_json = object_json.find(typeid(name_component).name());
282 if (name_json == object_json.end())
283 {
284 object = Scene->CreateObject();
285 }
286 else
287 {
288 name_component object_name_component { "" };
289 from_json(*name_json, object_name_component);
290 object = Scene->CreaetOrGetObject(object_name_component.Name);
291 }
292
293 DeserializeObject(object_json, object);
294 }
295 }
296
297}
const vec3 & GetUpDirection() const
Definition: camera.h:102
int GetViewportWidth() const
Definition: camera.h:93
const vec3 & GetFocus() const
Definition: camera.h:110
camera_projection_type GetProjectionType() const
Definition: camera.h:85
void SetProjectionType(camera_projection_type ProjectionType)
Definition: camera.cpp:13
void SetFieldOfView(float FieldOfView)
Definition: camera.cpp:18
float GetFieldOfView() const
Definition: camera.h:87
void SetViewportHeight(int ViewportHeight)
Definition: camera.cpp:38
camera_effects Effects
Definition: camera.h:74
const vec3 & GetPosition() const
Definition: camera.h:108
int GetViewportHeight() const
Definition: camera.h:95
void SetPosition(const vec3 &Position)
Definition: camera.cpp:55
void SetUpDirection(const vec3 &UpDirection)
Definition: camera.cpp:43
void SetViewportWidth(int ViewportWidth)
Definition: camera.cpp:33
void SetFocus(const vec3 &Focus)
Definition: camera.cpp:62
static bool IsDockspace
Definition: gui.h:20
static void SetVSync(bool VSync)
Definition: render_bridge.h:44
static void SetClearColor(const vec4 &ClearColor)
Definition: render_bridge.h:38
static void SetWireframeMode(bool IsWireframe)
Definition: render_bridge.h:40
static const vec4 & GetClearColor()
Definition: render_bridge.h:29
static bool GetVSync()
Definition: render_bridge.h:35
static bool GetWireframeMode()
Definition: render_bridge.h:31
static void Serialize(const shared< scene > &Scene, const std::filesystem::path &OutFileName)
static void Deserialize(shared< scene > &Scene, const std::filesystem::path &InFileName)
#define SCL_CORE_INFO(...)
Definition: log.h:41
void SaveFile(const std::string &Data, const std::filesystem::path &FilePath)
Definition: files_save.cpp:12
std::string LoadFile(const std::filesystem::path &FilePath)
Definition: files_load.cpp:12
std::shared_ptr< T > shared
Definition: smart_ptr.h:15
void to_json(json &Json, const name_component &NameComponent)
nlohmann::json json
camera_projection_type
Definition: camera.h:20
bool from_json(const json &Json, name_component &NameComponent)
Render bridge class implementation module. Static class for making calls to low-level render api,...
Scene serializer (also could perform deserialization) class definition module.
Sculpto library prehompiled header. Defines common definitions, includes commonly used modules.
void SetOuterCutoff(degrees Angle)
void SetInnerCutoff(degrees Angle)
void SetPosition(const vec3 &Position)
void SetAngles(const vec3 &Angles)
void SetScale(const vec3 &Scale)