Now rendering live preview when dragging models into viewport

This commit is contained in:
Antoine Pilote
2024-08-11 00:45:02 -04:00
parent 91b3e5d4b0
commit 6da7cb9d3f
6 changed files with 124 additions and 16 deletions

View File

@@ -55,6 +55,7 @@
#include <src/Scripting/ScriptingEngineNet.h>
#include <src/Threading/JobSystem.h>
#include "../Commands/Commands/Commands.h"
#include <src/Resource/ModelLoader.h>
namespace Nuake {
@@ -63,6 +64,38 @@ namespace Nuake {
ImFont* boldFont;
ImFont* EditorInterface::bigIconFont;
glm::vec3 DepthToWorldPosition(const glm::vec2& pixelPos, float depth, const glm::mat4& projectionMatrix, const glm::mat4& viewMatrix, const glm::vec2& viewportSize)
{
// Convert pixel position to normalized device coordinates (NDC)
glm::vec2 ndcPos;
ndcPos.x = (2.0f * pixelPos.x) / viewportSize.x - 1.0f;
ndcPos.y = 1.0f - (2.0f * pixelPos.y) / viewportSize.y; // Y-axis inversion
// Depth value ranges from 0 to 1 in NDC space
float ndcDepth = depth * 2.0f - 1.0f;
// Construct the NDC position
glm::vec4 ndcPos4(ndcPos.x, ndcPos.y, ndcDepth, 1.0f);
// Compute the inverse of the projection and view matrices
glm::mat4 invProj = glm::inverse(projectionMatrix);
glm::mat4 invView = glm::inverse(viewMatrix);
// Transform the NDC position to eye space
glm::vec4 eyePos4 = invProj * ndcPos4;
eyePos4.z = -1.0f; // Set Z to -1 as it's on the near plane
eyePos4 /= eyePos4.w;
//eyePos4.w = 0.0f;
// Transform the eye space position to world space
glm::vec4 worldPos4 = invView * eyePos4;
// Return the 3D world position
glm::vec3 worldPos(worldPos4.x, worldPos4.y, worldPos4.z);
return worldPos;
}
EditorInterface::EditorInterface(CommandBuffer& commandBuffer) :
mCommandBuffer(&commandBuffer)
{
@@ -98,7 +131,7 @@ namespace Nuake {
ImVec2 LastSize = ImVec2();
void EditorInterface::DrawViewport()
{
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(4, 4));
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(0, 0));
std::string name = ICON_FA_GAMEPAD + std::string(" Scene");
if (ImGui::Begin(name.c_str()))
{
@@ -125,12 +158,86 @@ namespace Nuake {
ImGui::PopStyleVar();
const Vector2& mousePos = Input::GetMousePosition();
const ImVec2& windowPos = ImGui::GetWindowPos() + ImVec2(0, 30.0);
const ImVec2& windowSize = ImGui::GetWindowSize() - ImVec2(0, 30.0);
const ImVec2& windowPos = ImGui::GetWindowPos();
const auto windowPosNuake = Vector2(windowPos.x, windowPos.y);
const ImVec2& windowSize = ImGui::GetWindowSize();
const bool isInsideWidth = mousePos.x > windowPos.x && mousePos.x < windowPos.x + windowSize.x;
const bool isInsideHeight = mousePos.y > windowPos.y && mousePos.y < windowPos.y + windowSize.y;
m_IsHoveringViewport = isInsideWidth && isInsideHeight;
if (ImGui::BeginDragDropTarget())
{
auto& gbuffer = Engine::GetCurrentScene()->m_SceneRenderer->GetGBuffer();
Vector2 textureSize = gbuffer.GetTexture(GL_DEPTH_ATTACHMENT)->GetSize();
auto pixelPos = Input::GetMousePosition() - windowPosNuake;
pixelPos.y = gbuffer.GetSize().y - pixelPos.y; // imgui coords are inverted on the Y axis
auto gizmoBuffer = Engine::GetCurrentWindow()->GetFrameBuffer();
gizmoBuffer->Bind();
bool foundSomethingToSelect = false;
Vector3 dragnDropWorldPos = Vector3(0, 0, 0);
if (const float result = gizmoBuffer->ReadDepth(pixelPos); result > 0)
{
const Matrix4& proj = Engine::GetCurrentScene()->m_EditorCamera->GetPerspective();
Matrix4 view = Engine::GetCurrentScene()->m_EditorCamera->GetTransform();
pixelPos.y = (Input::GetMousePosition() - windowPosNuake).y;
dragnDropWorldPos = DepthToWorldPosition(pixelPos, result, proj, view, textureSize);
auto renderer = Engine::GetCurrentScene()->m_SceneRenderer;
const ImGuiPayload* payload = ImGui::GetDragDropPayload();
if(payload && payload->IsDataType("_Model"))
{
char* file = (char*)payload->Data;
std::string fullPath = std::string(file, 256);
fullPath = Nuake::FileSystem::AbsoluteToRelative(fullPath);
Matrix4 transform = Matrix4(1.0f);
transform = glm::translate(transform, dragnDropWorldPos);
if (!renderer->IsTempModelLoaded(fullPath))
{
auto loader = ModelLoader();
auto modelResource = loader.LoadModel(fullPath);
Matrix4 transform = Matrix4(1.0f);
transform = glm::translate(transform, dragnDropWorldPos);
renderer->DrawTemporaryModel(fullPath, modelResource, transform);
}
else
{
renderer->DrawTemporaryModel(fullPath, nullptr, transform);
}
}
Engine::GetCurrentScene()->m_SceneRenderer->DrawDebugLine(dragnDropWorldPos, dragnDropWorldPos + Vector3{0, 5, 0}, Vector4(1, 0, 1, 1));
}
gizmoBuffer->Unbind();
if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("_Model"))
{
char* file = (char*)payload->Data;
std::string fullPath = std::string(file, 256);
fullPath = Nuake::FileSystem::AbsoluteToRelative(fullPath);
auto loader = ModelLoader();
auto modelResource = loader.LoadModel(fullPath);
auto entity = Engine::GetCurrentScene()->CreateEntity(FileSystem::GetFileNameFromPath(fullPath));
ModelComponent& modelComponent = entity.AddComponent<ModelComponent>();
modelComponent.ModelPath = fullPath;
modelComponent.ModelResource = modelResource;
entity.GetComponent<TransformComponent>().SetLocalPosition(dragnDropWorldPos);
}
}
else
{
Engine::GetCurrentScene()->m_SceneRenderer->ClearTemporaryModels();
}
ImGuizmo::SetDrawlist();
ImGuizmo::AllowAxisFlip(true);
ImGuizmo::SetRect(imagePos.x, imagePos.y + 0.0f, viewportPanelSize.x, viewportPanelSize.y);

View File

@@ -281,15 +281,12 @@ namespace Nuake
{
for (unsigned int i = 0; i < CSM_AMOUNT; i++)
{
// Bind shadowmap texture
light.m_Framebuffers[i]->GetTexture(GL_DEPTH_ATTACHMENT)->Bind(17 + i);
const uint32_t shadowMapId = shadowmapAmount + i;
Ref<Texture> shadowMapTexture = light.m_Framebuffers[i]->GetTexture(GL_DEPTH_ATTACHMENT);
deferredShader->SetUniformTex("ShadowMaps[" + std::to_string(shadowMapId) + "]", shadowMapTexture, 17 + i);
const std::string stringIndex = std::to_string(i);
deferredShader->SetUniform1i("u_DirectionalLight.ShadowMapsIDs[" + stringIndex + "]", shadowMapId);
deferredShader->SetUniform1f("u_DirectionalLight.CascadeDepth[" + stringIndex + "]", light.mCascadeSplitDepth[i]);
deferredShader->SetUniformMat4f("u_DirectionalLight.LightTransforms[" + stringIndex + "]", light.mViewProjections[i]);
deferredShader->SetUniform1i("ShadowMaps[" + std::to_string(shadowMapId) + "]", 17 + i);
deferredShader->SetUniform1i("u_DirectionalLight.ShadowMapsIDs[" + std::to_string(i) + "]", shadowMapId);
deferredShader->SetUniform1f("u_DirectionalLight.CascadeDepth[" + std::to_string(i) + "]", light.mCascadeSplitDepth[i]);
deferredShader->SetUniformMat4f("u_DirectionalLight.LightTransforms[" + std::to_string(i) + "]", light.mViewProjections[i]);
}
}

View File

@@ -400,7 +400,7 @@ namespace Nuake
Shader* shader = ShaderManager::GetShader("Resources/Shaders/shadowMap.shader");
shader->Bind();
RenderCommand::Disable(RendererEnum::FACE_CULL);
RenderCommand::Enable(RendererEnum::FACE_CULL);
glCullFace(GL_BACK);
auto meshView = scene.m_Registry.view<TransformComponent, ModelComponent, VisibilityComponent>();

View File

@@ -53,7 +53,7 @@ namespace Nuake
// TODO: Automate this
const float nearClip = 0.01f;
const float farClip = 500.0f;
const float farClip = 800.0f;
const float clipRange = farClip - nearClip;
const float mCascadeNearPlaneOffset = -100.0f;
@@ -73,7 +73,7 @@ namespace Nuake
mCascadeSplits[i] = (d - nearClip) / clipRange;
}
//mCascadeSplits[0] = 0.01f;
mCascadeSplits[0] = 0.01f;
//mCascadeSplits[1] = 0.45f;
//mCascadeSplits[2] = 1.0f;

View File

@@ -198,6 +198,8 @@ namespace Nuake
copy->Translation = this->Translation;
copy->Yaw = this->Yaw;
copy->Pitch = this->Pitch;
copy->TargetYaw = copy->Yaw;
copy->TargetPitch = copy->Pitch;
return copy;
}
@@ -232,7 +234,7 @@ namespace Nuake
SERIALIZE_VEC3(Translation);
j["Yaw"] = glm::clamp(Yaw, 0.f, 360.f);
j["Pitch"] = glm::clamp(Pitch, -90.f, 90.f);
SERIALIZE_VAL(Speed);
return j;
}
@@ -241,6 +243,8 @@ namespace Nuake
DESERIALIZE_VEC3(j["Translation"], Translation);
SetYaw(j["Yaw"]);
SetPitch(j["Pitch"]);
UpdateDirection();
DESERIALIZE_VAL(Speed);
return true;
}

View File

@@ -198,7 +198,7 @@ float ShadowCalculation(vec3 FragPos, vec3 normal)
const float NUM_SAMPLES = 4.f;
const float SAMPLES_START = (NUM_SAMPLES - 1.0f) / 2.0f;
const float NUM_SAMPLES_SQUARED = NUM_SAMPLES * NUM_SAMPLES;
vec2 texelSize = 1.0 / vec2(2048, 2048);
vec2 texelSize = 1.0 / vec2(4096, 4096);
float result = 0.0f;
for (float y = -SAMPLES_START; y <= SAMPLES_START; y += 1.0f)