Skip to content

Commit cb9dfab

Browse files
authored
Merge pull request #20 from adriengivry/feature/actor_picking
Scene actor picking implemented
2 parents e7eab70 + 5b83b13 commit cb9dfab

9 files changed

Lines changed: 203 additions & 61 deletions

File tree

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

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,29 @@ namespace OvEditor::Core
3838
*/
3939
void InitMaterials();
4040

41+
/**
42+
* Prepare the picking material by send it the color corresponding to the given actor
43+
* @param p_actor
44+
*/
45+
void PreparePickingMaterial(OvCore::ECS::Actor& p_actor);
46+
47+
/**
48+
* Calculate the model matrix for a camera attached to the given actor
49+
* @param p_actor
50+
*/
51+
OvMaths::FMatrix4 CalculateCameraModelMatrix(OvCore::ECS::Actor& p_actor);
52+
4153
/**
4254
* Render the scene
4355
* @param p_cameraPosition
4456
*/
4557
void RenderScene(const OvMaths::FVector3& p_cameraPosition);
4658

59+
/**
60+
* Render the scene for actor picking (Unlit version of the scene with colors indicating actor IDs)
61+
*/
62+
void RenderSceneForActorPicking();
63+
4764
/**
4865
* Render the User Interface
4966
*/
@@ -131,5 +148,6 @@ namespace OvEditor::Core
131148
OvCore::Resources::Material m_cameraMaterial;
132149
OvCore::Resources::Material m_guizmoArrowMaterial;
133150
OvCore::Resources::Material m_guizmoBallMaterial;
151+
OvCore::Resources::Material m_actorPickingMaterial;
134152
};
135153
}

Sources/Overload/OvEditor/include/OvEditor/Panels/AView.h

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -42,16 +42,6 @@ namespace OvEditor::Panels
4242
*/
4343
virtual void Update(float p_deltaTime);
4444

45-
/**
46-
* Bind the FBO attached to the view
47-
*/
48-
void Bind();
49-
50-
/**
51-
* Unbind the FBO attached to the view
52-
*/
53-
void Unbind();
54-
5545
/**
5646
* Custom implementation of the draw method
5747
*/
@@ -112,7 +102,6 @@ namespace OvEditor::Panels
112102

113103
OvMaths::FVector3 m_gridColor = OvMaths::FVector3::One;
114104

115-
private:
116105
OvRendering::Buffers::Framebuffer m_fbo;
117106
};
118107
}

Sources/Overload/OvEditor/include/OvEditor/Panels/SceneView.h

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,17 +27,23 @@ namespace OvEditor::Panels
2727
);
2828

2929
/**
30-
* Update the scene view (Inputs logic)
31-
* @param p_deltaTime
30+
* Custom implementation of the render method
3231
*/
33-
virtual void Update(float p_deltaTime) override;
32+
virtual void _Render_Impl() override;
3433

3534
/**
36-
* Custom implementation of the render method
35+
* Render the actual scene
36+
* @param p_defaultRenderState
3737
*/
38-
virtual void _Render_Impl() override;
38+
void RenderScene(uint8_t p_defaultRenderState);
39+
40+
/**
41+
* Render the scene for actor picking and handle the logic behind it
42+
*/
43+
void HandleActorPicking();
3944

4045
private:
4146
OvCore::SceneSystem::SceneManager& m_sceneManager;
47+
OvRendering::Buffers::Framebuffer m_actorPickingFramebuffer;
4248
};
4349
}

Sources/Overload/OvEditor/src/OvEditor/Core/Editor.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,8 @@ void OvEditor::Core::Editor::PreUpdate()
8282
void OvEditor::Core::Editor::Update(float p_deltaTime)
8383
{
8484
UpdateCurrentEditorMode(p_deltaTime);
85-
UpdateEditorPanels(p_deltaTime);
8685
PrepareRendering(p_deltaTime);
86+
UpdateEditorPanels(p_deltaTime);
8787
RenderViews(p_deltaTime);
8888
RenderEditorUI(p_deltaTime);
8989
m_editorActions.ExecuteDelayedActions();

Sources/Overload/OvEditor/src/OvEditor/Core/EditorRenderer.cpp

Lines changed: 98 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#include <OvCore/ECS/Components/CDirectionalLight.h>
1414
#include <OvCore/ECS/Components/CSpotLight.h>
1515

16+
#include <OvDebug/Utils/Assertion.h>
17+
1618
#include "OvEditor/Core/EditorRenderer.h"
1719
#include "OvEditor/Core/EditorResources.h"
1820
#include "OvEditor/Panels/AView.h"
@@ -105,6 +107,32 @@ void OvEditor::Core::EditorRenderer::InitMaterials()
105107
m_guizmoBallMaterial.SetShader(m_context.editorResources->GetShader("Guizmo"));
106108
m_guizmoBallMaterial.SetShader(m_context.editorResources->GetShader("Guizmo"));
107109
m_guizmoBallMaterial.Set("u_IsBall", true);
110+
111+
/* Picking Material */
112+
m_actorPickingMaterial.SetShader(m_context.shaderManager[":Shaders\\Unlit.glsl"]);
113+
m_actorPickingMaterial.Set("u_Diffuse", FVector4(1.f, 1.f, 1.f, 1.0f));
114+
m_actorPickingMaterial.Set<OvRendering::Resources::Texture*>("u_DiffuseMap", nullptr);
115+
m_actorPickingMaterial.SetFrontfaceCulling(false);
116+
m_actorPickingMaterial.SetBackfaceCulling(false);
117+
}
118+
119+
void OvEditor::Core::EditorRenderer::PreparePickingMaterial(OvCore::ECS::Actor& p_actor)
120+
{
121+
uint32_t actorID = static_cast<uint32_t>(p_actor.GetID());
122+
123+
auto bytes = reinterpret_cast<uint8_t*>(&actorID);
124+
auto color = FVector4{ bytes[0] / 255.0f, bytes[1] / 255.0f, bytes[2] / 255.0f, 1.0f };
125+
126+
m_actorPickingMaterial.Set("u_Diffuse", color);
127+
}
128+
129+
OvMaths::FMatrix4 OvEditor::Core::EditorRenderer::CalculateCameraModelMatrix(OvCore::ECS::Actor& p_actor)
130+
{
131+
auto translation = FMatrix4::Translation(p_actor.transform.GetWorldPosition());
132+
auto rotation = FQuaternion::ToMatrix4(p_actor.transform.GetWorldRotation());
133+
auto scale = FMatrix4::Scaling({ 0.4f, 0.4f, 0.4f });
134+
135+
return translation * rotation * scale;
108136
}
109137

110138
void OvEditor::Core::EditorRenderer::RenderScene(const OvMaths::FVector3& p_cameraPosition)
@@ -115,6 +143,69 @@ void OvEditor::Core::EditorRenderer::RenderScene(const OvMaths::FVector3& p_came
115143
m_context.lightSSBO->Unbind();
116144
}
117145

146+
void OvEditor::Core::EditorRenderer::RenderSceneForActorPicking()
147+
{
148+
auto& scene = *m_context.sceneManager.GetCurrentScene();
149+
150+
/* Render models */
151+
for (auto modelRenderer : scene.GetFastAccessComponents().modelRenderers)
152+
{
153+
auto& actor = modelRenderer->owner;
154+
155+
if (actor.IsActive())
156+
{
157+
if (auto model = modelRenderer->GetModel())
158+
{
159+
160+
if (auto materialRenderer = modelRenderer->owner.GetComponent<OvCore::ECS::Components::CMaterialRenderer>())
161+
{
162+
const OvCore::ECS::Components::CMaterialRenderer::MaterialList& materials = materialRenderer->GetMaterials();
163+
auto modelMatrix = actor.transform.GetWorldMatrix();
164+
PreparePickingMaterial(actor);
165+
166+
for (auto mesh : model->GetMeshes())
167+
{
168+
OvCore::Resources::Material* material = nullptr;
169+
170+
if (mesh->GetMaterialIndex() < MAX_MATERIAL_COUNT)
171+
{
172+
material = materials.at(mesh->GetMaterialIndex());
173+
if (!material || !material->GetShader())
174+
material = &m_emptyMaterial;
175+
}
176+
177+
if (material)
178+
{
179+
m_actorPickingMaterial.SetBackfaceCulling(material->HasBackfaceCulling());
180+
m_actorPickingMaterial.SetFrontfaceCulling(material->HasFrontfaceCulling());
181+
m_actorPickingMaterial.SetColorWriting(material->HasColorWriting());
182+
m_actorPickingMaterial.SetDepthTest(material->HasDepthTest());
183+
m_actorPickingMaterial.SetDepthWriting(material->HasDepthWriting());
184+
185+
m_context.renderer->DrawMesh(*mesh, m_actorPickingMaterial, &modelMatrix);
186+
}
187+
}
188+
}
189+
}
190+
}
191+
}
192+
193+
/* Render cameras */
194+
for (auto camera : m_context.sceneManager.GetCurrentScene()->GetFastAccessComponents().cameras)
195+
{
196+
auto& actor = camera->owner;
197+
198+
if (actor.IsActive())
199+
{
200+
PreparePickingMaterial(actor);
201+
auto& model = *m_context.editorResources->GetModel("Camera");
202+
auto modelMatrix = CalculateCameraModelMatrix(actor);
203+
204+
m_context.renderer->DrawModelWithSingleMaterial(model, m_actorPickingMaterial, &modelMatrix);
205+
}
206+
}
207+
}
208+
118209
void OvEditor::Core::EditorRenderer::RenderUI()
119210
{
120211
m_context.uiManager->Render();
@@ -124,10 +215,14 @@ void OvEditor::Core::EditorRenderer::RenderCameras()
124215
{
125216
for (auto camera : m_context.sceneManager.GetCurrentScene()->GetFastAccessComponents().cameras)
126217
{
127-
if (camera->owner.IsActive())
218+
auto& actor = camera->owner;
219+
220+
if (actor.IsActive())
128221
{
129-
auto modelMatrix = FMatrix4::Translation(camera->owner.transform.GetWorldPosition()) * FQuaternion::ToMatrix4(camera->owner.transform.GetWorldRotation()) * FMatrix4::Scaling({ 0.4f, 0.4f, 0.4f });
130-
m_context.renderer->DrawModelWithSingleMaterial(*m_context.editorResources->GetModel("Camera"), m_cameraMaterial, &modelMatrix);
222+
auto& model = *m_context.editorResources->GetModel("Camera");
223+
auto modelMatrix = CalculateCameraModelMatrix(actor);
224+
225+
m_context.renderer->DrawModelWithSingleMaterial(model, m_cameraMaterial, &modelMatrix);
131226
}
132227
}
133228
}

Sources/Overload/OvEditor/src/OvEditor/Panels/AView.cpp

Lines changed: 1 addition & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,29 +25,11 @@ OvEditor::Panels::AView::AView
2525

2626
void OvEditor::Panels::AView::Update(float p_deltaTime)
2727
{
28-
Bind();
29-
3028
auto[winWidth, winHeight] = GetSafeSize();
3129

3230
m_image->size = OvMaths::FVector2(static_cast<float>(winWidth), static_cast<float>(winHeight));
3331

3432
m_fbo.Resize(winWidth, winHeight);
35-
36-
Unbind();
37-
}
38-
39-
void OvEditor::Panels::AView::Bind()
40-
{
41-
auto[winWidth, winHeight] = GetSafeSize();
42-
43-
glViewport(0, 0, winWidth, winHeight);
44-
45-
m_fbo.Bind();
46-
}
47-
48-
void OvEditor::Panels::AView::Unbind()
49-
{
50-
m_fbo.Unbind();
5133
}
5234

5335
void OvEditor::Panels::AView::_Draw_Impl()
@@ -67,10 +49,9 @@ void OvEditor::Panels::AView::Render()
6749
auto projection = m_camera.GetProjectionMatrix(winWidth, winHeight);
6850
auto view = m_camera.GetViewMatrix(m_cameraPosition);
6951
EDITOR_CONTEXT(shapeDrawer)->SetViewProjection(projection * view);
52+
glViewport(0, 0, winWidth, winHeight); // TODO: Move this OpenGL call to OvRendering
7053

71-
Bind();
7254
_Render_Impl();
73-
Unbind();
7455
}
7556

7657
void OvEditor::Panels::AView::SetCameraPosition(const OvMaths::FVector3 & p_position)

Sources/Overload/OvEditor/src/OvEditor/Panels/AssetView.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ void OvEditor::Panels::AssetView::_Render_Impl()
4949
{
5050
auto& baseRenderer = *EDITOR_CONTEXT(renderer).get();
5151

52+
m_fbo.Bind();
53+
5254
baseRenderer.SetStencilMask(0xFF);
5355
baseRenderer.Clear(m_camera);
5456
baseRenderer.SetStencilMask(0x00);
@@ -68,6 +70,8 @@ void OvEditor::Panels::AssetView::_Render_Impl()
6870
m_editorRenderer.RenderMaterialAsset(**pval);
6971

7072
baseRenderer.ApplyStateMask(glState);
73+
74+
m_fbo.Unbind();
7175
}
7276

7377
void OvEditor::Panels::AssetView::SetResource(ViewableResource p_resource)

Sources/Overload/OvEditor/src/OvEditor/Panels/GameView.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ void OvEditor::Panels::GameView::Update(float p_deltaTime)
4545
void OvEditor::Panels::GameView::_Render_Impl()
4646
{
4747
auto& baseRenderer = *EDITOR_CONTEXT(renderer).get();
48+
49+
m_fbo.Bind();
4850

4951
baseRenderer.Clear(m_camera);
5052

@@ -54,5 +56,8 @@ void OvEditor::Panels::GameView::_Render_Impl()
5456
if (m_hasCamera)
5557
m_editorRenderer.RenderScene(m_cameraPosition);
5658

59+
5760
baseRenderer.ApplyStateMask(glState);
61+
62+
m_fbo.Unbind();
5863
}

0 commit comments

Comments
 (0)