sculpto
scene_object_config_window.h
Go to the documentation of this file.
1/*!****************************************************************//*!*
2 * \file scene_object_config_window.h
3 * \brief Scene object components configuration GUI window class declaration module.
4 *
5 * \author Sabitov Kirill
6 * \date 09 July 2022
7 *********************************************************************/
8
9#pragma once
10
11#include <entt.hpp>
12#include <imgui.h>
13
16#include "core/resources/mesh.h"
23
24namespace scl
25{
28 {
29 private:
30 float PanelWidth {};
31
32 static const char AddComponentComboItemsCames[7][64];
33 std::vector<std::string> SubmeshSelectComboItems {};
34 int CurrentSubmeshIndex {};
35 int GBufferPreviewColorAttachment {};
36 int CurrentAddingComponentIndex {};
37 int CameraProjectionTypeIndex {};
38
39 char NameTextBuffer[128] {};
40
42 scene_object ConfiguringObject {};
43
47 bool IsTransformComponent {};
48 bool IsMeshComponent {};
49 bool IsCameraComponent {};
50 bool IsPointLightComponent {};
51 bool IsDirectionalLightComponent {};
52 bool IsSpotLightComponent {};
53
54 public:
58 void SetConfiguringObject(scene_object ConfiguringObject);
59
60 private:
61 /*!*
62 * Reset stored data about configuring object function.
63 *
64 * \param None.
65 * \return None.
66 */
67 void ResetData();
68
69 /*!*
70 * Draw GUI panel for specific component of currently editing object function.
71 *
72 * \param None.
73 * \return None.
74 */
75 template <typename Tcomponent>
76 void DrawComponentPanel() {}
77
78 template <>
79 void DrawComponentPanel<name_component>()
80 {
81 auto &name = ConfiguringObject.GetComponent<name_component>();
82 if (strcmp(NameTextBuffer, name.Name.c_str()) != 0) strcpy_s(NameTextBuffer, name.Name.c_str());
83 if (ImGui::InputText("Name", NameTextBuffer, 128))
84 name.Name = std::string(NameTextBuffer);
85 ImGui::Separator();
86 }
87
88 template <>
89 void DrawComponentPanel<transform_component>()
90 {
91 ImGui::Text("Transformation");
92 if (DrawDeleteComponentButton<transform_component>()) return;
93 ImGui::NewLine();
94
95 auto &transform = ConfiguringObject.GetComponent<transform_component>();
96 if (ImGui::DragFloat3("Scale", transform.Scale, 0.05f, 0.005f, 10.0f))
97 transform.InvalidateScale();
98 if (ImGui::DragFloat3("Rotation", transform.Angles, 0.25f, -180.0f, 180.0f))
99 transform.InvalidateRotation();
100 if (ImGui::DragFloat3("Position", transform.Position, 0.1f, -50.0f, 50.0f))
101 transform.InvalidatePosition();
102 ImGui::Separator();
103 }
104
105 template <>
106 void DrawComponentPanel<native_script_component>()
107 {
108 ImGui::Text("Native script");
109 if (DrawDeleteComponentButton<native_script_component>()) return;
110 ImGui::NewLine();
111
112 auto &native_script = ConfiguringObject.GetComponent<native_script_component>();
113 ImGui::Text("Name \"%s\"", native_script.Name.c_str());
114 ImGui::Checkbox("Is active", &native_script.IsActive);
115 ImGui::Separator();
116 }
117
118 template <>
119 void DrawComponentPanel<mesh_component>()
120 {
121 ImGui::Text("Mesh");
122 if (DrawDeleteComponentButton<mesh_component>()) return;
123 ImGui::NewLine();
124
125 auto &mesh = ConfiguringObject.GetComponent<mesh_component>().Mesh;
126 if (mesh == nullptr) return;
127
128 ImGui::SetNextItemWidth(PanelWidth * 0.7f - 5);
129 if (ImGui::Button("Load model", { PanelWidth - 10, 0 })); // mesh = assets_manager::LoadMeshes(std::string(LoadModelTextBuffer));
130
131 if (ImGui::BeginCombo("Select Submesh", SubmeshSelectComboItems[CurrentSubmeshIndex].c_str()))
132 {
133 for (int i = 0; i < SubmeshSelectComboItems.size(); ++i)
134 {
135 const bool isSelected = (CurrentSubmeshIndex == i);
136 if (ImGui::Selectable(SubmeshSelectComboItems[i].c_str(), isSelected))
137 CurrentSubmeshIndex = i;
138 if (isSelected)
139 ImGui::SetItemDefaultFocus();
140 }
141 ImGui::EndCombo();
142 }
143 ImGui::Checkbox("Drawing", &mesh->IsDrawing);
144 ImGui::Checkbox("Casting shadows", &mesh->IsCastingShadow);
145 ImGui::NewLine();
146
147 auto &submesh = mesh->SubMeshes[CurrentSubmeshIndex];
148 ImGui::Text("Submesh Data");
149 ImGui::Text("Vertice count: %d", submesh.VertexBuffer->GetCount());
150 ImGui::Text("Indices count: %d", submesh.IndexBuffer->GetCount());
151 ImGui::NewLine();
152
153 auto material_ph = std::dynamic_pointer_cast<material_phong>(submesh.Material);
154 auto material_single = std::dynamic_pointer_cast<material_single_color>(submesh.Material);
155
156 ImGui::SetNextItemWidth(PanelWidth * 0.7f - 5);
157 ImGui::Text("Shader \"%s\"", submesh.Material->Shader->DebugName.c_str()); ImGui::SameLine(PanelWidth * 0.7f + 5);
158 if (ImGui::Button("Reload##shdmtl", { PanelWidth * 0.3f - 10, 0 })) assets_manager::UpdateShader(submesh.Material->Shader);
159 ImGui::NewLine();
160
161 ImGui::BeginDisabled();
162 if (material_ph) {
163 // Diffuse map
164 if (material_ph->GetIsDiffuseMap()) {
165 ImGui::Text("Diffuse");
166 const shared<texture_2d> &texture = material_ph->GetDiffuseMapTexture();
167 ImGui::Image((ImTextureID)texture->GetHandle(), { PanelWidth, PanelWidth * texture->GetHeight() / texture->GetWidth() }, { 0, 1 }, { 1, 0 });
168 }
169 vec3 color = material_ph->GetDiffuse();
170 ImGui::ColorEdit3("Diffuse", color);
171 ImGui::NewLine();
172
173 // Specular map
174 if (material_ph->GetIsSpecularMap()) {
175 ImGui::Text("Specular");
176 const shared<texture_2d> &texture = material_ph->GetSpecularMapTexture();
177 ImGui::Image((ImTextureID)texture->GetHandle(), { PanelWidth, PanelWidth * texture->GetHeight() / texture->GetWidth() }, { 0, 1 }, { 1, 0 });
178 }
179 color = material_ph->GetSpecular();
180 ImGui::ColorEdit3("Specular", color);
181 ImGui::NewLine();
182
183 float shininess = material_ph->GetShininess();
184 ImGui::DragFloat("Shininess", &shininess, 0.05, 0.001, 512);
185 ImGui::NewLine();
186
187 // Emission map
188 if (material_ph->GetIsEmissionMap()) {
189 ImGui::Text("Emission map");
190 const shared<texture_2d> &texture = material_ph->GetEmissionMapTexture();
191 ImGui::Image((ImTextureID)texture->GetHandle(), { PanelWidth, PanelWidth * texture->GetHeight() / texture->GetWidth() }, { 0, 1 }, { 1, 0 });
192 }
193 ImGui::NewLine();
194
195 // Normal map
196 if (material_ph->GetIsNormalMap()) {
197 ImGui::Text("Normal map");
198 const shared<texture_2d> &texture = material_ph->GetNormalMapTexture();
199 ImGui::Image((ImTextureID)texture->GetHandle(), { PanelWidth, PanelWidth * texture->GetHeight() / texture->GetWidth() }, { 0, 1 }, { 1, 0 });
200 }
201
202 } else if (material_single) {
203 if (material_single->GetIsTexture()) {
204 const shared<texture_2d> &texture = material_single->GetTexture();
205 ImGui::Text("Texture");
206 ImGui::Image((ImTextureID)texture->GetHandle(), { PanelWidth, PanelWidth * texture->GetHeight() / texture->GetWidth() }, { 0, 1 }, { 1, 0 });
207 }
208 vec3 color = material_single->GetColor();
209 ImGui::ColorEdit3("Color", color, 0.001);
210 }
211 ImGui::EndDisabled();
212 ImGui::Separator();
213 }
214
215 template <>
216 void DrawComponentPanel<camera_component>()
217 {
218 ImGui::Text("Camera");
219 if (DrawDeleteComponentButton<camera_component>()) return;
220 ImGui::NewLine();
221
222 auto &camera_comp = ConfiguringObject.GetComponent<camera_component>();
223 auto &camera = camera_comp.Camera;
224 ImGui::Checkbox("Is primary", &camera_comp.IsPrimary);
225 CameraProjectionTypeIndex = (int)camera.GetProjectionType();
226 if (ImGui::Combo("Projection type", &CameraProjectionTypeIndex, "Orthographic\0Perspective"))
227 camera.SetProjectionType((camera_projection_type)CameraProjectionTypeIndex);
228 float fov = camera.GetFieldOfView();
229 if (ImGui::DragFloat("Field of view", &fov, 0.001, 0.0001, 2)) camera.SetFieldOfView(fov);
230 ImGui::NewLine();
231
232 vec3 position = camera.GetPosition();
233 if (ImGui::DragFloat3("Camera Position", position, 0.05, -100, 100)) camera.SetPosition(position);
234 vec3 focus = camera.GetFocus();
235 if (ImGui::DragFloat3("Focus point", focus, 0.05, -100, 100)) camera.SetFocus(focus);
237 if (ImGui::DragFloat3("Up direction", up, 0.001, -1, 1)) camera.SetUpDirection(up);
238 ImGui::NewLine();
239
240 ImGui::Combo("GBuffer", &GBufferPreviewColorAttachment, "None\0Position\0Normals\0Color\0Diffuse\0Specular\0Shininess");
241 if (GBufferPreviewColorAttachment > 0)
242 ImGui::Image((ImTextureID)camera.GetGBuffer()->GetColorAttachment(GBufferPreviewColorAttachment - 1)->GetHandle(),
243 { PanelWidth, PanelWidth * camera.GetViewportHeight() / camera.GetViewportWidth() }, { 0, 1 }, { 1, 0 });
244 ImGui::NewLine();
245
246 ImGui::Text("Camera effects");
247 ImGui::Checkbox("HDR mode", &camera.Effects.HDR);
248 if (camera.Effects.HDR)
249 {
250 ImGui::SliderFloat("Exposure level", &camera.Effects.Exposure, 0.01, 10);
251 ImGui::NewLine();
252
253 ImGui::Checkbox("Bloom effect", &camera.Effects.Bloom);
254 if (camera.Effects.Bloom) ImGui::SliderInt("Bloom amount", &camera.Effects.BloomAmount, 4, 12);
255 }
256
257 ImGui::Separator();
258 }
259
260 template <>
261 void DrawComponentPanel<point_light_component>()
262 {
263 ImGui::Text("Point Light");
264 if (DrawDeleteComponentButton<point_light_component>()) return;
265 ImGui::NewLine();
266
267 auto &light = ConfiguringObject.GetComponent<point_light_component>();
268 ImGui::ColorEdit3("Light color", light.Color);
269 ImGui::SliderFloat("Light strength", &light.Strength, 0.001, 10);
270 ImGui::NewLine();
271
272 ImGui::DragFloat("Constant attitution", &light.Constant, 0.01, 0.001, 3);
273 ImGui::DragFloat("Linear attitution", &light.Linear, 0.01, 0.001, 2);
274 ImGui::DragFloat("Quadratic attitution", &light.Quadratic, 0.0001, 0.00000001, 2, "%.8f");
275
276 ImGui::Separator();
277 }
278
279 template <>
280 void DrawComponentPanel<directional_light_component>()
281 {
282 ImGui::Text("Directiona Light");
283 if (DrawDeleteComponentButton<directional_light_component>()) return;
284 ImGui::NewLine();
285
286 auto &light = ConfiguringObject.GetComponent<directional_light_component>();
287 ImGui::ColorEdit3("Light color", light.Color);
288 ImGui::SliderFloat("Light strength", &light.Strength, 0.001, 10);
289 ImGui::NewLine();
290
291 bool is_shadows = light.GetIsShadow();
292 if (ImGui::Checkbox("Is casting shadows", &is_shadows)) light.SetIsShadows(is_shadows);
293 if (is_shadows)
294 {
295 float size = light.GetBoxSize(), depth = light.GetBoxDepth();
296 if (ImGui::DragFloat("Projection box size", &size, 0.01, 5, 500)) light.SetBoxSize(size);
297 if (ImGui::DragFloat("Projection box depth", &depth, 0.01, 5, 500)) light.SetBoxDepth(depth);
298 ImGui::NewLine();
299
300 auto &depth_texture = light.GetShadowMap()->GetDepthAttachment();
301 int w = depth_texture->GetWidth(), h = depth_texture->GetHeight();
302 ImGui::Text("Shadow map");
303 if (ImGui::DragInt("Shadow map width", &w, 5, 100, 10000)) light.SetShadowMapWidth(w);
304 if (ImGui::DragInt("Shadow map height", &h, 5, 100, 10000)) light.SetShadowMapHeight(h);
305 ImGui::Image((ImTextureID)depth_texture->GetHandle(),
306 { PanelWidth, PanelWidth * h / w }, {0, 1}, {1, 0});
307 ImGui::NewLine();
308 }
309
310 ImGui::Separator();
311 }
312
313 template <>
314 void DrawComponentPanel<spot_light_component>()
315 {
316
317 ImGui::Text("Spot Light");
318 if (DrawDeleteComponentButton<spot_light_component>()) return;
319 ImGui::NewLine();
320
321 auto &light = ConfiguringObject.GetComponent<spot_light_component>();
322 ImGui::ColorEdit3("Light color", light.Color);
323 ImGui::SliderFloat("Light strength", &light.Strength, 0.001, 10);
324 ImGui::NewLine();
325
326 float inner_cutoff = light.GetInnerCutoff();
327 float outer_cutoff = light.GetOuterCutoff();
328 if (ImGui::DragFloat("Inner cutoff angle", &inner_cutoff)) light.SetInnerCutoff(inner_cutoff);
329 if (ImGui::DragFloat("Outer cutoff angle", &outer_cutoff)) light.SetOuterCutoff(outer_cutoff);
330 ImGui::Separator();
331 }
332
333 void DrawAddComponentComboItem(int ComponentIndex)
334 {
335 const bool isSelected = (CurrentAddingComponentIndex == ComponentIndex);
336 if (ImGui::Selectable(AddComponentComboItemsCames[ComponentIndex], isSelected))
337 CurrentAddingComponentIndex = ComponentIndex;
338 if (isSelected)
339 ImGui::SetItemDefaultFocus();
340 }
341
342 void DrawAddComponentPanel()
343 {
344 ImGui::SetNextItemWidth(PanelWidth * 0.7f - 5);
345 if (ImGui::BeginCombo("##adding_component_selection", AddComponentComboItemsCames[CurrentAddingComponentIndex]))
346 {
347 if (!IsTransformComponent) DrawAddComponentComboItem(1);
348 if (!IsCameraComponent) DrawAddComponentComboItem(2);
349 if (!IsPointLightComponent) DrawAddComponentComboItem(3);
350 if (!IsDirectionalLightComponent) DrawAddComponentComboItem(4);
351 if (!IsSpotLightComponent) DrawAddComponentComboItem(5);
352
353 ImGui::EndCombo();
354 }
355
356 ImGui::SameLine(PanelWidth * 0.7f + 5);
357 if (ImGui::Button("Add component", { PanelWidth * 0.3f - 10, 0 }))
358 {
359 switch (CurrentAddingComponentIndex)
360 {
361 case 1: ConfiguringObject.AddComponent<transform_component>(); break;
362 break;
363 case 2: ConfiguringObject.AddComponent<camera_component>(); break;
364 case 3: ConfiguringObject.AddComponent<point_light_component>(); break;
365 case 4: ConfiguringObject.AddComponent<directional_light_component>(); break;
366 case 5: ConfiguringObject.AddComponent<spot_light_component>(); break;
367 }
368 ResetData();
369 }
370 }
371
372 template <typename Tcomponent>
373 bool DrawDeleteComponentButton()
374 {
375 static std::string button_name = std::string("Delete##") + typeid(Tcomponent).name();
376
377 ImGui::SameLine(PanelWidth * 0.7f + 5);
378 if (ImGui::Button(button_name.c_str(), { PanelWidth * 0.3f - 5, 0}))
379 {
380 ConfiguringObject.RemovetComponent<Tcomponent>();
381 ResetData();
382 return true;
383 }
384 return false;
385 }
386
387 public:
388
391
392 /*!*
393 * Draw scene object configuration window function.
394 *
395 * \param None.
396 * \return None.
397 */
398 void Draw();
399 };
400}
const vec3 & GetUpDirection() const
Definition: camera.h:102
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
camera_effects Effects
Definition: camera.h:74
const vec3 & GetPosition() const
Definition: camera.h:108
const shared< frame_buffer > & GetGBuffer() const
Definition: camera.h:115
void SetPosition(const vec3 &Position)
Definition: camera.cpp:55
void SetUpDirection(const vec3 &UpDirection)
Definition: camera.cpp:43
void SetFocus(const vec3 &Focus)
Definition: camera.cpp:62
Definition: mesh.h:31
bool IsCastingShadow
Definition: mesh.h:50
std::vector< submesh_data > SubMeshes
Definition: mesh.h:46
bool IsDrawing
Definition: mesh.h:49
void SetConfiguringObject(scene_object ConfiguringObject)
decltype(auto) AddComponent(Targs &&... Args)
Definition: scene_object.h:84
Application scene objects system components include module.
Mesh material for bling-phone lighting model class deinition module.
Mesh interfaces definition module. Mesh stores vertex and index buffer and implement their binding du...
void UpdateShader(shared< shader_program > ShaderProgram)
Definition: base.h:33
std::shared_ptr< T > shared
Definition: smart_ptr.h:15
camera_projection_type
Definition: camera.h:20
Application scene object class defintion module.
Topology sphere object class implementation module.
Assets manager texture load function defintion modulule.