Vesper 0.5.1
Vesper is short form for the Latin word for "Bat", as Vesper is designed to be small, lightweight, and easily handle things like particles and flocking behaviors in accordance with the nature of bats. \n It is meant to be a particle simulation, VFX editor, and CAN be used secondarily as a small game engine.
GitHub | Vesper Updates | Creator
Loading...
Searching...
No Matches
Vesper::SceneHierarchyPanel Class Reference

#include <SceneHierarchyPanel.h>

Public Member Functions

 SceneHierarchyPanel ()=default
 SceneHierarchyPanel (const Ref< Scene > &context)
void SetContext (const Ref< Scene > &context)
void OnImGuiRender ()
Entity GetSelectedEntity () const
void SetSelectedEntity (Entity entity)

Private Member Functions

template<typename T>
void DisplayAddComponentEntry (const std::string &entryName)
void DrawEntityNode (Entity entity)
void DrawComponents (Entity entity)

Private Attributes

Ref< Scenem_Context
Entity m_SelectionContext
Ref< Framebufferm_Framebuffer

Constructor & Destructor Documentation

◆ SceneHierarchyPanel() [1/2]

Vesper::SceneHierarchyPanel::SceneHierarchyPanel ( )
default

◆ SceneHierarchyPanel() [2/2]

Vesper::SceneHierarchyPanel::SceneHierarchyPanel ( const Ref< Scene > & context)
17 {
18 SetContext(context);
19 }
void SetContext(const Ref< Scene > &context)
Definition SceneHierarchyPanel.cpp:21

Member Function Documentation

◆ DisplayAddComponentEntry()

template<typename T>
void Vesper::SceneHierarchyPanel::DisplayAddComponentEntry ( const std::string & entryName)
private
545 {
546 if (!m_SelectionContext.HasComponent<T>())
547 {
548 if (ImGui::MenuItem(entryName.c_str()))
549 {
550 m_SelectionContext.AddComponent<T>();
551 ImGui::CloseCurrentPopup();
552 }
553 }
554 }
Entity m_SelectionContext
Definition SceneHierarchyPanel.h:31
@ T
Definition KeyCodes.h:57

◆ DrawComponents()

void Vesper::SceneHierarchyPanel::DrawComponents ( Entity entity)
private
373 {
374 if (entity.HasComponent<NameComponent>())
375 {
376 auto& name = entity.GetComponent<NameComponent>().Name;
377
378 char buffer[256];
379 memset(buffer, 0, sizeof(buffer));
380 strncpy_s(buffer, sizeof(buffer), name.c_str(), sizeof(buffer));
381 if (ImGui::InputText("##Name", buffer, sizeof(buffer)))
382 {
383 name = std::string(buffer);
384 }
385 }
386
387 ImGui::SameLine();
388 ImGui::PushItemWidth(-1);
389
390 if (ImGui::Button("Add Component"))
391 ImGui::OpenPopup("AddComponent");
392
393 if (ImGui::BeginPopup("AddComponent"))
394 {
396 //DisplayAddComponentEntry<ScriptComponent>("Script");
399
400 ImGui::EndPopup();
401 }
402
403 ImGui::PopItemWidth();
404
405 DrawComponent<TransformComponent>("Transform", entity, [](auto& component)
406 {
407 DrawVec3Control("Translation", component.Translation);
408 glm::vec3 rotation = glm::degrees(component.Rotation);
409 DrawVec3Control("Rotation", rotation);
410 component.Rotation = glm::radians(rotation);
411 DrawVec3Control("Scale", component.Scale, 1.0f);
412 });
413
414 DrawComponent<CameraComponent>("Camera", entity, [](auto& component)
415 {
416 auto& camera = component.Camera;
417
418 ImGui::Checkbox("Primary", &component.Primary);
419
420 const char* projectionTypeStrings[] = { "Perspective", "Orthographic" };
421 const char* currentProjectionTypeString = projectionTypeStrings[(int)camera.GetProjectionType()];
422 if (ImGui::BeginCombo("Projection", currentProjectionTypeString))
423 {
424 for (int i = 0; i < 2; i++)
425 {
426 bool isSelected = currentProjectionTypeString == projectionTypeStrings[i];
427 if (ImGui::Selectable(projectionTypeStrings[i], isSelected))
428 {
429 currentProjectionTypeString = projectionTypeStrings[i];
430 camera.SetProjectionType((SceneCamera::ProjectionType)i);
431 }
432
433 if (isSelected)
434 ImGui::SetItemDefaultFocus();
435 }
436
437 ImGui::EndCombo();
438 }
439
440 if (camera.GetProjectionType() == SceneCamera::ProjectionType::Perspective)
441 {
442 float perspectiveVerticalFov = glm::degrees(camera.GetPerspectiveVerticalFOV());
443 if (ImGui::DragFloat("Vertical FOV", &perspectiveVerticalFov))
444 camera.SetPerspectiveVerticalFOV(glm::radians(perspectiveVerticalFov));
445
446 float perspectiveNear = camera.GetPerspectiveNearClip();
447 if (ImGui::DragFloat("Near", &perspectiveNear))
448 camera.SetPerspectiveNearClip(perspectiveNear);
449
450 float perspectiveFar = camera.GetPerspectiveFarClip();
451 if (ImGui::DragFloat("Far", &perspectiveFar))
452 camera.SetPerspectiveFarClip(perspectiveFar);
453 }
454
455 if (camera.GetProjectionType() == SceneCamera::ProjectionType::Orthographic)
456 {
457 float orthoSize = camera.GetOrthographicSize();
458 if (ImGui::DragFloat("Size", &orthoSize))
459 camera.SetOrthographicSize(orthoSize);
460
461 float orthoNear = camera.GetOrthographicNearClip();
462 if (ImGui::DragFloat("Near", &orthoNear))
463 camera.SetOrthographicNearClip(orthoNear);
464
465 float orthoFar = camera.GetOrthographicFarClip();
466 if (ImGui::DragFloat("Far", &orthoFar))
467 camera.SetOrthographicFarClip(orthoFar);
468
469 ImGui::Checkbox("Fixed Aspect Ratio", &component.FixedAspectRatio);
470 }
471 });
472
473 DrawComponent<SpriteRendererComponent>("Sprite Renderer", entity, [](auto& component)
474 {
475 ImGui::ColorEdit4("Color", glm::value_ptr(component.Color));
476
477 // Separate checkbox for enabling/disabling texture usage
478 ImGui::Checkbox("Texture Enabled", &component.TextureEnabled);
479 ImGui::SameLine();
480
481 // Display current texture name (if any) and buttons to Set / Change / Clear the texture
482 if (component.Texture)
483 {
484 ImGui::TextUnformatted(component.Texture->GetName().c_str());
485 ImGui::SameLine();
486 if (ImGui::Button("Change Texture"))
487 {
488 std::string filePath = FileDialogs::OpenFile("Image Files (*.png;*.jpg;*.jpeg;*.bmp;*.tga)\0*.png;*.jpg;*.jpeg;*.bmp;*.tga\0All Files (*.*)\0*.*\0");
489 if (!filePath.empty())
490 {
491 auto tex = Texture2D::Create(filePath);
492 if (tex)
493 {
494 component.Texture = tex;
495 component.TextureEnabled = true;
496 }
497 else
498 {
499 VZ_WARN("Could not load texture {0}", filePath);
500 }
501 }
502 }
503 ImGui::SameLine();
504 if (ImGui::Button("Clear Texture"))
505 {
506 component.Texture = nullptr;
507 component.TextureEnabled = false;
508 }
509 }
510 else
511 {
512 ImGui::SameLine();
513 if (ImGui::Button("Set Texture"))
514 {
515 std::string filePath = FileDialogs::OpenFile("Image Files (*.png;*.jpg;*.jpeg;*.bmp;*.tga)\0*.png;*.jpg;*.jpeg;*.bmp;*.tga\0All Files (*.*)\0*.*\0");
516 if (!filePath.empty())
517 {
518 auto tex = Texture2D::Create(filePath);
519 if (tex)
520 {
521 component.Texture = tex;
522 component.TextureEnabled = true;
523 }
524 else
525 {
526 VZ_WARN("Could not load texture {0}", filePath);
527 }
528 }
529 }
530 }
531
532 ImGui::DragFloat("Tiling Factor", &component.TilingFactor, 0.1f, 0.0f, 100.0f);
533
534 });
535
536 DrawComponent<SubTextureComponent>("SubTexture", entity, [](auto& component)
537 {
538 SubTextureEdit(component.SubTexture->GetTexture()->GetName(), component);
539
540 });
541 }
#define VZ_WARN(...)
warn: indicates a potential issue or important event
Definition Log.h:50
static std::string OpenFile(const char *filter)
Opens a file dialog to select a file to open.
Definition WindowsPlatformUtils.cpp:12
ProjectionType
Definition SceneCamera.h:9
@ Orthographic
Definition SceneCamera.h:9
@ Perspective
Definition SceneCamera.h:9
void DisplayAddComponentEntry(const std::string &entryName)
Definition SceneHierarchyPanel.cpp:545
static Ref< Texture2D > Create(uint32_t width, uint32_t height)
Definition Texture.cpp:10
static void SubTextureEdit(const std::string &label, SubTextureComponent &subTexture)
Definition SceneHierarchyPanel.cpp:297
static void DrawVec3Control(const std::string &label, glm::vec3 &values, float resetValue=0.0f, float columnWidth=100.0f)
Definition SceneHierarchyPanel.cpp:155
static void DrawComponent(const std::string &name, Entity entity, UIFunction uiFunction)
Definition SceneHierarchyPanel.cpp:332

◆ DrawEntityNode()

void Vesper::SceneHierarchyPanel::DrawEntityNode ( Entity entity)
private

TODO: Improve name duplication logic

TODO: Draw child entities here in the future

68 {
69 auto& name = entity.GetComponent<NameComponent>().Name;
70 void* nodeID = (void*)(uint64_t)(uint32_t)entity;
71
72 ImGuiTreeNodeFlags flags = ((m_SelectionContext == entity) ? ImGuiTreeNodeFlags_Selected : 0) | ImGuiTreeNodeFlags_OpenOnArrow;
73 flags |= ImGuiTreeNodeFlags_SpanAvailWidth;
74 bool opened = ImGui::TreeNodeEx(nodeID, flags, name.c_str());
75 if (ImGui::IsItemClicked())
76 {
77 m_SelectionContext = entity;
78 }
79
80 bool entityDeleted = false;
81 if (ImGui::BeginPopupContextItem())
82 {
83 if (ImGui::MenuItem("Delete Entity"))
84 entityDeleted = true;
85
86 if (ImGui::MenuItem("Duplicate Entity"))
87 {
88 Entity newEntity = m_Context->CreateEntity(name);
89 // Copy components
90 if (entity.HasComponent<NameComponent>()) {
91 auto& src = entity.GetComponent<NameComponent>();
92 auto& newEntName = newEntity.GetComponent<NameComponent>();
94 if (src.Name.capacity() > 0 && isdigit(src.Name.back()))
95 {
96 // Increment trailing number
97 size_t i = src.Name.size() - 1;
98 while (i > 0 && isdigit(src.Name[i - 1]))
99 --i;
100 std::string baseName = src.Name.substr(0, i);
101 std::string numberStr = src.Name.substr(i);
102 int number = std::stoi(numberStr);
103 newEntName.Name = baseName + std::to_string(number + 1);
104 }
105 else
106 newEntName.Name = src.Name + "1";
107 }
108 if (entity.HasComponent<SpriteRendererComponent>())
109 {
110 auto& src = entity.GetComponent<SpriteRendererComponent>();
111 newEntity.AddComponent<SpriteRendererComponent>(src);
112 }
113 if (entity.HasComponent<CameraComponent>())
114 {
115 auto& cc = entity.GetComponent<CameraComponent>();
116 newEntity.AddComponent<CameraComponent>(cc);
117 }
118 if (entity.HasComponent<NativeScriptComponent>())
119 {
120 auto& nsc = entity.GetComponent<NativeScriptComponent>();
121 newEntity.AddComponent<NativeScriptComponent>(nsc);
122 }
123 if (entity.HasComponent<TextureAnimationComponent>())
124 {
125 auto& tac = entity.GetComponent<TextureAnimationComponent>();
126 newEntity.AddComponent<TextureAnimationComponent>(tac);
127 }
128 // Add more components as needed
129 m_SelectionContext = newEntity;
130 }
131
132 ImGui::EndPopup();
133 }
134
135 if (opened)
136 {
137 ImGuiTreeNodeFlags flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_SpanAvailWidth;
138 bool opened = ImGui::TreeNodeEx((void*)9817239, flags, name.c_str());
139 if (opened)
140 {
142 ImGui::TreePop();
143 }
144 ImGui::TreePop();
145 }
146
147 if (entityDeleted)
148 {
149 m_Context->DestroyEntity(entity);
150 if (m_SelectionContext == entity)
152 }
153 }
Ref< Scene > m_Context
Definition SceneHierarchyPanel.h:30

◆ GetSelectedEntity()

Entity Vesper::SceneHierarchyPanel::GetSelectedEntity ( ) const
inline
21{ return m_SelectionContext; }

◆ OnImGuiRender()

void Vesper::SceneHierarchyPanel::OnImGuiRender ( )
28 {
29 ImGui::Begin("Scene Hierarchy");
30 if (m_Context) {
31
32 auto view = m_Context->m_Registry.view<NameComponent>();
33
34 for (auto entity : view) {
35 Entity e{ entity, m_Context.get() };
37 }
38
39 if (ImGui::IsMouseDown(0) && ImGui::IsWindowHovered())
41
42 // Right-click on blank space
43 if (ImGui::BeginPopupContextWindow(0, ImGuiPopupFlags_NoOpenOverItems | ImGuiPopupFlags_MouseButtonRight))
44 {
45 if (ImGui::MenuItem("Create Empty Entity"))
46 m_SelectionContext = m_Context->CreateEntity("Empty Entity");
47
48 ImGui::EndPopup();
49 }
50 }
51 ImGui::End();
52
53 ImGui::Begin("Properties");
55 {
57 }
58
59 ImGui::End();
60 }
void DrawComponents(Entity entity)
Definition SceneHierarchyPanel.cpp:372
void DrawEntityNode(Entity entity)
Definition SceneHierarchyPanel.cpp:67

◆ SetContext()

void Vesper::SceneHierarchyPanel::SetContext ( const Ref< Scene > & context)
22 {
23 m_Context = context;
25 }

◆ SetSelectedEntity()

void Vesper::SceneHierarchyPanel::SetSelectedEntity ( Entity entity)
63 {
64 m_SelectionContext = entity;
65 }

Member Data Documentation

◆ m_Context

Ref<Scene> Vesper::SceneHierarchyPanel::m_Context
private

◆ m_Framebuffer

Ref<Framebuffer> Vesper::SceneHierarchyPanel::m_Framebuffer
private

◆ m_SelectionContext

Entity Vesper::SceneHierarchyPanel::m_SelectionContext
private

The documentation for this class was generated from the following files: