Skip to content

Commit 027b579

Browse files
authored
Merge pull request #102 from adriengivry/feature/orthographic_camera
Adding orthographic camera mode
2 parents 0f4b849 + 17f4b62 commit 027b579

12 files changed

Lines changed: 337 additions & 73 deletions

File tree

Sources/Overload/OvCore/include/OvCore/ECS/Components/CCamera.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,12 @@ namespace OvCore::ECS::Components
4141
*/
4242
void SetFov(float p_value);
4343

44+
/**
45+
* Sets the size of the camera to the given value
46+
* @param p_value
47+
*/
48+
void SetSize(float p_value);
49+
4450
/**
4551
* Sets the near of the camera to the given value
4652
* @param p_value
@@ -71,11 +77,22 @@ namespace OvCore::ECS::Components
7177
*/
7278
void SetFrustumLightCulling(bool p_enable);
7379

80+
/**
81+
* Defines the projection mode the camera should adopt
82+
* @param p_projectionMode
83+
*/
84+
void SetProjectionMode(OvRendering::Settings::EProjectionMode p_projectionMode);
85+
7486
/**
7587
* Returns the fov of the camera
7688
*/
7789
float GetFov() const;
7890

91+
/**
92+
* Returns the size of the camera
93+
*/
94+
float GetSize() const;
95+
7996
/**
8097
* Returns the near of the camera
8198
*/
@@ -101,6 +118,11 @@ namespace OvCore::ECS::Components
101118
*/
102119
bool HasFrustumLightCulling() const;
103120

121+
/**
122+
* Returns the current projection mode
123+
*/
124+
OvRendering::Settings::EProjectionMode GetProjectionMode() const;
125+
104126
/**
105127
* Returns the OvRendering camera instance attached to this component
106128
*/

Sources/Overload/OvCore/src/OvCore/ECS/Components/CCamera.cpp

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
*/
66

77
#include <OvUI/Widgets/Drags/DragFloat.h>
8+
#include <OvUI/Widgets/Selection/ComboBox.h>
89
#include <OvUI/Plugins/DataDispatcher.h>
910

1011
#include "OvCore/ECS/Components/CCamera.h"
@@ -26,6 +27,11 @@ void OvCore::ECS::Components::CCamera::SetFov(float p_value)
2627
m_camera.SetFov(p_value);
2728
}
2829

30+
void OvCore::ECS::Components::CCamera::SetSize(float p_value)
31+
{
32+
m_camera.SetSize(p_value);
33+
}
34+
2935
void OvCore::ECS::Components::CCamera::SetNear(float p_value)
3036
{
3137
m_camera.SetNear(p_value);
@@ -46,11 +52,21 @@ void OvCore::ECS::Components::CCamera::SetFrustumLightCulling(bool p_enable)
4652
m_camera.SetFrustumLightCulling(p_enable);
4753
}
4854

55+
void OvCore::ECS::Components::CCamera::SetProjectionMode(OvRendering::Settings::EProjectionMode p_projectionMode)
56+
{
57+
m_camera.SetProjectionMode(p_projectionMode);
58+
}
59+
4960
float OvCore::ECS::Components::CCamera::GetFov() const
5061
{
5162
return m_camera.GetFov();
5263
}
5364

65+
float OvCore::ECS::Components::CCamera::GetSize() const
66+
{
67+
return m_camera.GetSize();
68+
}
69+
5470
float OvCore::ECS::Components::CCamera::GetNear() const
5571
{
5672
return m_camera.GetNear();
@@ -81,6 +97,11 @@ bool OvCore::ECS::Components::CCamera::HasFrustumLightCulling() const
8197
return m_camera.HasFrustumLightCulling();
8298
}
8399

100+
OvRendering::Settings::EProjectionMode OvCore::ECS::Components::CCamera::GetProjectionMode() const
101+
{
102+
return m_camera.GetProjectionMode();
103+
}
104+
84105
OvRendering::LowRenderer::Camera & OvCore::ECS::Components::CCamera::GetCamera()
85106
{
86107
return m_camera;
@@ -89,29 +110,63 @@ OvRendering::LowRenderer::Camera & OvCore::ECS::Components::CCamera::GetCamera()
89110
void OvCore::ECS::Components::CCamera::OnSerialize(tinyxml2::XMLDocument & p_doc, tinyxml2::XMLNode * p_node)
90111
{
91112
OvCore::Helpers::Serializer::SerializeFloat(p_doc, p_node, "fov", m_camera.GetFov());
113+
OvCore::Helpers::Serializer::SerializeFloat(p_doc, p_node, "size", m_camera.GetSize());
92114
OvCore::Helpers::Serializer::SerializeFloat(p_doc, p_node, "near", m_camera.GetNear());
93115
OvCore::Helpers::Serializer::SerializeFloat(p_doc, p_node, "far", m_camera.GetFar());
94116
OvCore::Helpers::Serializer::SerializeVec3(p_doc, p_node, "clear_color", m_camera.GetClearColor());
95117
OvCore::Helpers::Serializer::SerializeBoolean(p_doc, p_node, "frustum_geometry_culling", m_camera.HasFrustumGeometryCulling());
96118
OvCore::Helpers::Serializer::SerializeBoolean(p_doc, p_node, "frustum_light_culling", m_camera.HasFrustumLightCulling());
119+
OvCore::Helpers::Serializer::SerializeInt(p_doc, p_node, "projection_mode", static_cast<int>(m_camera.GetProjectionMode()));
97120
}
98121

99122
void OvCore::ECS::Components::CCamera::OnDeserialize(tinyxml2::XMLDocument & p_doc, tinyxml2::XMLNode * p_node)
100123
{
101124
m_camera.SetFov(OvCore::Helpers::Serializer::DeserializeFloat(p_doc, p_node, "fov"));
125+
m_camera.SetSize(OvCore::Helpers::Serializer::DeserializeFloat(p_doc, p_node, "size"));
102126
m_camera.SetNear(OvCore::Helpers::Serializer::DeserializeFloat(p_doc, p_node, "near"));
103127
m_camera.SetFar(OvCore::Helpers::Serializer::DeserializeFloat(p_doc, p_node, "far"));
104128
m_camera.SetClearColor(OvCore::Helpers::Serializer::DeserializeVec3(p_doc, p_node, "clear_color"));
105129
m_camera.SetFrustumGeometryCulling(OvCore::Helpers::Serializer::DeserializeBoolean(p_doc, p_node, "frustum_geometry_culling"));
106130
m_camera.SetFrustumLightCulling(OvCore::Helpers::Serializer::DeserializeBoolean(p_doc, p_node, "frustum_light_culling"));
131+
132+
// We have to make sure the "projection_mode" exists in the serialized component, otherwise we do not want to modify the default setting (Perspective).
133+
// This is a bad practice to have each components calling setters in `OnDeserialize` even if no XML node hasn't been found for a given property.
134+
// We should rework this system later. As it is out of the scope of the orthographic projection scope, this will be left as is for now.
135+
if (p_node->FirstChildElement("projection_mode"))
136+
{
137+
m_camera.SetProjectionMode(static_cast<OvRendering::Settings::EProjectionMode>(OvCore::Helpers::Serializer::DeserializeInt(p_doc, p_node, "projection_mode")));
138+
}
107139
}
108140

109141
void OvCore::ECS::Components::CCamera::OnInspector(OvUI::Internal::WidgetContainer& p_root)
110142
{
143+
auto currentProjectionMode = GetProjectionMode();
144+
111145
OvCore::Helpers::GUIDrawer::DrawScalar<float>(p_root, "Field of view", std::bind(&CCamera::GetFov, this), std::bind(&CCamera::SetFov, this, std::placeholders::_1));
146+
auto& fovWidget = *p_root.GetWidgets()[p_root.GetWidgets().size() - 1].first;
147+
auto& fovWidgetLabel = *p_root.GetWidgets()[p_root.GetWidgets().size() - 2].first;
148+
fovWidget.enabled = fovWidgetLabel.enabled = currentProjectionMode == OvRendering::Settings::EProjectionMode::PERSPECTIVE;
149+
150+
OvCore::Helpers::GUIDrawer::DrawScalar<float>(p_root, "Size", std::bind(&CCamera::GetSize, this), std::bind(&CCamera::SetSize, this, std::placeholders::_1));
151+
auto& sizeWidget = *p_root.GetWidgets()[p_root.GetWidgets().size() - 1].first;
152+
auto& sizeWidgetLabel = *p_root.GetWidgets()[p_root.GetWidgets().size() - 2].first;
153+
sizeWidget.enabled = sizeWidgetLabel.enabled = currentProjectionMode == OvRendering::Settings::EProjectionMode::ORTHOGRAPHIC;
154+
112155
OvCore::Helpers::GUIDrawer::DrawScalar<float>(p_root, "Near", std::bind(&CCamera::GetNear, this), std::bind(&CCamera::SetNear, this, std::placeholders::_1));
113156
OvCore::Helpers::GUIDrawer::DrawScalar<float>(p_root, "Far", std::bind(&CCamera::GetFar, this), std::bind(&CCamera::SetFar, this, std::placeholders::_1));
114157
OvCore::Helpers::GUIDrawer::DrawColor(p_root, "Clear color", [this]() {return reinterpret_cast<const OvUI::Types::Color&>(GetClearColor()); }, [this](OvUI::Types::Color p_color) { SetClearColor({ p_color.r, p_color.g, p_color.b }); }, false);
115158
OvCore::Helpers::GUIDrawer::DrawBoolean(p_root, "Frustum Geometry Culling", std::bind(&CCamera::HasFrustumGeometryCulling, this), std::bind(&CCamera::SetFrustumGeometryCulling, this, std::placeholders::_1));
116159
OvCore::Helpers::GUIDrawer::DrawBoolean(p_root, "Frustum Light Culling", std::bind(&CCamera::HasFrustumLightCulling, this), std::bind(&CCamera::SetFrustumLightCulling, this, std::placeholders::_1));
160+
161+
Helpers::GUIDrawer::CreateTitle(p_root, "Projection Mode");
162+
auto& projectionMode = p_root.CreateWidget<OvUI::Widgets::Selection::ComboBox>(static_cast<int>(GetProjectionMode()));
163+
projectionMode.choices.emplace(0, "Orthographic");
164+
projectionMode.choices.emplace(1, "Perspective");
165+
projectionMode.ValueChangedEvent += [this, &fovWidget, &fovWidgetLabel, &sizeWidget, &sizeWidgetLabel](int p_choice)
166+
{
167+
const auto newProjectionMode = static_cast<OvRendering::Settings::EProjectionMode>(p_choice);
168+
SetProjectionMode(newProjectionMode);
169+
fovWidget.enabled = fovWidgetLabel.enabled = newProjectionMode == OvRendering::Settings::EProjectionMode::PERSPECTIVE;
170+
sizeWidget.enabled = sizeWidgetLabel.enabled = newProjectionMode == OvRendering::Settings::EProjectionMode::ORTHOGRAPHIC;
171+
};
117172
}

Sources/Overload/OvCore/src/OvCore/Scripting/LuaComponentBinder.cpp

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,20 +137,30 @@ void OvCore::Scripting::LuaComponentBinder::BindComponent(sol::state & p_luaStat
137137
"SetHeight", &CPhysicalCapsule::SetHeight
138138
);
139139

140+
p_luaState.new_enum<OvRendering::Settings::EProjectionMode>("ProjectionMode",
141+
{
142+
{"ORTHOGRAPHIC", OvRendering::Settings::EProjectionMode::ORTHOGRAPHIC},
143+
{"PERSPECTIVE", OvRendering::Settings::EProjectionMode::PERSPECTIVE}
144+
});
145+
140146
p_luaState.new_usertype<CCamera>("Camera",
141147
sol::base_classes, sol::bases<AComponent>(),
142148
"GetFov", &CCamera::GetFov,
149+
"GetSize", &CCamera::GetSize,
143150
"GetNear", &CCamera::GetNear,
144151
"GetFar", &CCamera::GetFar,
145152
"GetClearColor", &CCamera::GetClearColor,
146153
"SetFov", &CCamera::SetFov,
154+
"SetSize", &CCamera::SetSize,
147155
"SetNear", &CCamera::SetNear,
148156
"SetFar", &CCamera::SetFar,
149157
"SetClearColor", &CCamera::SetClearColor,
150158
"HasFrustumGeometryCulling", &CCamera::HasFrustumGeometryCulling,
151159
"HasFrustumLightCulling", &CCamera::HasFrustumLightCulling,
160+
"GetProjectionMode", &CCamera::GetProjectionMode,
152161
"SetFrustumGeometryCulling", &CCamera::SetFrustumGeometryCulling,
153-
"SetFrustumLightCulling", &CCamera::SetFrustumLightCulling
162+
"SetFrustumLightCulling", &CCamera::SetFrustumLightCulling,
163+
"SetProjectionMode", &CCamera::SetProjectionMode
154164
);
155165

156166
p_luaState.new_usertype<CLight>("Light",

Sources/Overload/OvEditor/include/OvEditor/Core/EditorRenderer.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,20 @@ namespace OvEditor::Core
110110
*/
111111
void RenderActorOutlinePass(OvCore::ECS::Actor& p_actor, bool p_toStencil, bool p_isSelected = false);
112112

113+
/**
114+
* Render the camera perspective frustum
115+
* @param p_size
116+
* @param p_camera
117+
*/
118+
void RenderCameraPerspectiveFrustum(std::pair<uint16_t, uint16_t>& p_size, OvCore::ECS::Components::CCamera& p_camera);
119+
120+
/**
121+
* Render the camera orthographic frustum
122+
* @param p_size
123+
* @param p_camera
124+
*/
125+
void RenderCameraOrthographicFrustum(std::pair<uint16_t, uint16_t>& p_size, OvCore::ECS::Components::CCamera& p_camera);
126+
113127
/**
114128
* Render the camera frustum
115129
*/

0 commit comments

Comments
 (0)