Skip to content

Commit

Permalink
Camera Component UI
Browse files Browse the repository at this point in the history
  • Loading branch information
fszewczyk committed Jan 30, 2025
1 parent fe67b75 commit 40f3858
Show file tree
Hide file tree
Showing 8 changed files with 142 additions and 8 deletions.
8 changes: 4 additions & 4 deletions src/Components/CameraComponent.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ class CameraComponent {
}

glm::mat4 getProjectionMatrix() const {
return getProjectionMatrix(nearPlane, farPlane);
return getProjectionMatrix(projectionType, nearPlane, farPlane);
}

Ray getRayAt(const TransformComponent& transformComponent, float x, float y) const {
Expand All @@ -67,7 +67,7 @@ class CameraComponent {
}

std::vector<glm::vec3> getFrustumCornersWorldSpace(float localNearPlane, float localFarPlane, const TransformComponent& transformComponent) const {
glm::mat4 invViewProj = glm::inverse(getProjectionMatrix(localNearPlane, localFarPlane) * getViewMatrix(transformComponent));
glm::mat4 invViewProj = glm::inverse(getProjectionMatrix(ProjectionType::Perspective, localNearPlane, localFarPlane) * getViewMatrix(transformComponent));

std::vector<glm::vec3> frustumCorners;
for (int x = -1; x <= 1; x += 2) {
Expand All @@ -83,11 +83,11 @@ class CameraComponent {
}

private:
glm::mat4 getProjectionMatrix(float localNearPlane, float localFarPlane) const {
glm::mat4 getProjectionMatrix(ProjectionType projection, float localNearPlane, float localFarPlane) const {
if (projectionType == ProjectionType::Perspective) {
return glm::perspective(glm::radians(fov), aspectRatio, localNearPlane, localFarPlane);
} else {
float orthoSize = 10.0f; // Can be configurable
float orthoSize = fov; // Can be configurable
float halfWidth = orthoSize * aspectRatio * 0.5f;
float halfHeight = orthoSize * 0.5f;
return glm::ortho(-halfWidth, halfWidth, -halfHeight, halfHeight, localNearPlane, localFarPlane);
Expand Down
1 change: 1 addition & 0 deletions src/ui/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ add_library(

${CMAKE_CURRENT_LIST_DIR}/Components/TransformComponentUI.cpp
${CMAKE_CURRENT_LIST_DIR}/Components/ModelComponentUI.cpp
${CMAKE_CURRENT_LIST_DIR}/Components/CameraComponentUI.cpp
${CMAKE_CURRENT_LIST_DIR}/Components/PointLightComponentUI.cpp
${CMAKE_CURRENT_LIST_DIR}/Components/SpotLightComponentUI.cpp
${CMAKE_CURRENT_LIST_DIR}/Components/DirectionalLightComponentUI.cpp
Expand Down
67 changes: 67 additions & 0 deletions src/ui/Common/EnumSelector.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#pragma once

#include <string>
#include <functional>
#include <map>

#include <glm/glm.hpp>
#include "imgui.h"

namespace shkyera {

template<typename EnumType>
class EnumSelector {
public:
EnumSelector(const std::string& title, EnumType value, const std::map<EnumType, std::string>& options) :
_title(title),
_value(value),
_options(options)
{}

void setUpdateCallback(std::function<void(EnumType value)> callback)
{
_updateCallback = callback;
}

void draw()
{
EnumType oldValue = _value;
ImGui::PushItemWidth(50);
ImGui::TextUnformatted(_title.c_str());
ImGui::PopItemWidth();

ImGui::SameLine(120);
ImGui::PushItemWidth(190);

if(ImGui::BeginCombo((std::string("##" + _title + "EnumSelectorCombo").c_str()), _options.at(_value).c_str()))
{
for(const auto& [value, name] : _options)
{
if (ImGui::Selectable(name.c_str()))
{
_value = value;
}
}

ImGui::EndCombo();
}

ImGui::PopItemWidth();

if(oldValue != _value)
{
if(_updateCallback)
{
_updateCallback(_value);
}
}
}

private:
std::string _title;
EnumType _value;
std::map<EnumType, std::string> _options;
std::function<void(EnumType value)> _updateCallback;
};

}
6 changes: 3 additions & 3 deletions src/ui/Common/FloatSlider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@

namespace shkyera {

FloatSlider::FloatSlider(const std::string& title, float min, float max) : _title(title), _imguiIdentifier("##" + _title + "Slider"), _value((min + max) / 2), _minimum(min), _maximum(max) {}
FloatSlider::FloatSlider(const std::string& title, float min, float max) : _title(title), _value((min + max) / 2), _minimum(min), _maximum(max) {}

FloatSlider::FloatSlider(const std::string& title, float value, float min, float max) : _title(title), _imguiIdentifier("##" + _title + "Slider"), _value(value), _minimum(min), _maximum(max) {}
FloatSlider::FloatSlider(const std::string& title, float value, float min, float max) : _title(title), _value(value), _minimum(min), _maximum(max) {}

void FloatSlider::setUpdateCallback(std::function<void(float value)> callback) {
_updateCallback = callback;
Expand All @@ -22,7 +22,7 @@ void FloatSlider::draw() {

ImGui::SameLine(120);
ImGui::PushItemWidth(190);
ImGui::SliderFloat(_imguiIdentifier.c_str(), &_value, _minimum, _maximum, "%.3f");
ImGui::SliderFloat((std::string("##") + _title + "Slider").c_str(), &_value, _minimum, _maximum, "%.3f");
ImGui::PopItemWidth();

if(oldValue != _value)
Expand Down
1 change: 0 additions & 1 deletion src/ui/Common/FloatSlider.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ class FloatSlider {

private:
std::string _title;
std::string _imguiIdentifier;
float _value;
float _minimum, _maximum;
std::function<void(float value)> _updateCallback;
Expand Down
37 changes: 37 additions & 0 deletions src/ui/Components/CameraComponentUI.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#include "imgui.h"

#include <glm/glm.hpp>
#include <AssetManager/Image.hpp>
#include <UI/Components/CameraComponentUI.hpp>

namespace shkyera {

CameraComponentUI::CameraComponentUI(CameraComponent* cameraComponent) :
_cameraComponent(cameraComponent),
_fovSlider("Field of View", cameraComponent->fov, 5, 160),
_projectionSelector("Projection", cameraComponent->projectionType, {
{ CameraComponent::ProjectionType::Perspective, "Perspective" },
{ CameraComponent::ProjectionType::Orthographic, "Orthographic" },
})
{
_fovSlider.setUpdateCallback([this](float fov) {
_cameraComponent->fov = fov;
});
_projectionSelector.setUpdateCallback([this](const auto projection) {
_cameraComponent->projectionType = projection;
});
}

void CameraComponentUI::draw() {
ImGui::Image(_icon->getImguiTextureID(),
ImVec2(16, 16));
ImGui::SameLine();
if (ImGui::TreeNodeEx("Camera", ImGuiTreeNodeFlags_DefaultOpen)) {
_projectionSelector.draw();
_fovSlider.draw();

ImGui::TreePop();
}
}

}
22 changes: 22 additions & 0 deletions src/ui/Components/CameraComponentUI.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#pragma once

#include <UI/ComponentUI.hpp>
#include <UI/Common/FloatSlider.hpp>
#include <UI/Common/EnumSelector.hpp>
#include <Components/CameraComponent.hpp>

namespace shkyera {

class CameraComponentUI : public ComponentUI {
public:
CameraComponentUI(CameraComponent* cameraComponent);

void draw() override;

private:
FloatSlider _fovSlider;
EnumSelector<CameraComponent::ProjectionType> _projectionSelector;
CameraComponent* _cameraComponent;
};

}
8 changes: 8 additions & 0 deletions src/ui/widgets/PropertiesWidget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <UI/Components/TransformComponentUI.hpp>
#include <UI/Components/ModelComponentUI.hpp>
#include <UI/Components/WireframeComponentUI.hpp>
#include <UI/Components/CameraComponentUI.hpp>
#include <UI/Components/AmbientLightComponentUI.hpp>
#include <UI/Components/PointLightComponentUI.hpp>
#include <UI/Components/SpotLightComponentUI.hpp>
Expand Down Expand Up @@ -89,6 +90,13 @@ void PropertiesWidget::setupComponentsUI() {
_componentsUi.emplace_back(std::move(componentUi));
}

if(_registry->hasComponent<CameraComponent>(*_selectedEntity)) {
auto &component = _registry->getComponent<CameraComponent>(*_selectedEntity);
auto componentUi = std::make_unique<CameraComponentUI>(&component);

_componentsUi.emplace_back(std::move(componentUi));
}

if(_registry->hasComponent<ModelComponent>(*_selectedEntity)) {
auto &component = _registry->getComponent<ModelComponent>(*_selectedEntity);
auto componentUi = std::make_unique<ModelComponentUI>(_registry, &component);
Expand Down

0 comments on commit 40f3858

Please sign in to comment.