diff options
author | rtk0c <[email protected]> | 2022-05-06 19:52:12 -0700 |
---|---|---|
committer | rtk0c <[email protected]> | 2022-05-06 19:52:12 -0700 |
commit | cde94efdd44553f3f6575ce84b44c6799e1a1425 (patch) | |
tree | 593b9f280f2e223268f8d5c73f5d1dd1aba50c36 /source/EditorCore.cpp | |
parent | 4c9f5ee706faa1435b7dc2f3b6d4753e1289c351 (diff) |
Changeset: 22 Improved camera and various cleanups
Diffstat (limited to 'source/EditorCore.cpp')
-rw-r--r-- | source/EditorCore.cpp | 181 |
1 files changed, 122 insertions, 59 deletions
diff --git a/source/EditorCore.cpp b/source/EditorCore.cpp index bd5d78d..1841dfb 100644 --- a/source/EditorCore.cpp +++ b/source/EditorCore.cpp @@ -203,21 +203,22 @@ void EditorContentBrowser::Show(bool* open) { ImGui::End(); } -void EditorTransformEdit::ShowWorld(float* cameraView, float* cameraProjection) { - glm::mat4 identityMatrix(1.00f); +void EditorTransformEdit::ShowWorld(Camera* camera) { + // TODO + // glm::mat4 identityMatrix(1.00f); - ImGuiIO& io = ImGui::GetIO(); - float viewManipulateRight = io.DisplaySize.x; - float viewManipulateTop = 0; - static ImGuiWindowFlags gizmoWindowFlags = 0; + // ImGuiIO& io = ImGui::GetIO(); + // float viewManipulateRight = io.DisplaySize.x; + // float viewManipulateTop = 0; + // static ImGuiWindowFlags gizmoWindowFlags = 0; - ImGuizmo::SetRect(0, 0, io.DisplaySize.x, io.DisplaySize.y); + // ImGuizmo::SetRect(0, 0, io.DisplaySize.x, io.DisplaySize.y); - if (showGrid) { - ImGuizmo::DrawGrid(cameraView, cameraProjection, &identityMatrix[0][0], 100.f); - } + // if (showGrid) { + // ImGuizmo::DrawGrid(cameraView, cameraProjection, &identityMatrix[0][0], 100.f); + // } - ImGuizmo::ViewManipulate(cameraView, camDistance, ImVec2(viewManipulateRight - 128, viewManipulateTop), ImVec2(128, 128), 0x10101010); + // ImGuizmo::ViewManipulate(cameraView, camDistance, ImVec2(viewManipulateRight - 128, viewManipulateTop), ImVec2(128, 128), 0x10101010); } bool EditorTransformEdit::ShowObjectInspector(float* cameraView, float* cameraProjection, glm::vec3* pos, glm::quat* rotation, glm::vec3* scale) { @@ -412,23 +413,22 @@ struct CreatableGameObject { EditorInstance::EditorInstance(App* app) : mApp{ app } - , mFallbackFrameInfo{ - .camera = nullptr, - .matrixCombined = {}, - .time = 0.0f, - .deltaTime = 0.0f, - } - , mCurrentFrameInfo{ &mFallbackFrameInfo } - , mEdContentBrowser(&mEdInspector) {} - -EditorInstance::~EditorInstance() { + , mEdContentBrowser(&mEdInspector) { + mEditorCamera.name = "Editor Camera"s; + mEditorCamera.Move(glm::vec3(0, 0, 1)); + mEditorCamera.LookAt(glm::vec3(0, 0, 0)); + mEditorCamera.SetHasPerspective(false); } -void EditorInstance::OnUpdate() { +EditorInstance::~EditorInstance() { } -void EditorInstance::OnDraw(const RendererFrameInfo& frameInfo) { - mCurrentFrameInfo = &frameInfo; +void EditorInstance::OnGameStateChanged(bool running) { + if (running) { + mApp->UnbindActiveCamera(); + } else { + mApp->BindActiveCamera(&mEditorCamera); + } } void EditorInstance::Show() { @@ -468,17 +468,56 @@ void EditorInstance::Show() { mEdContentBrowser.Show(&mWindowVisible_ContentBrowser); } - auto cameraViewMat = mCurrentFrameInfo->matrixView; - auto cameraView = &cameraViewMat[0][0]; - auto cameraProjMat = mCurrentFrameInfo->matrixProj; - auto cameraProj = &cameraProjMat[0][0]; - // auto cameraView = &mCurrentFrameInfo->matrixView[0][0]; - // auto cameraProj = &mCurrentFrameInfo->matrixProj[0][0]; - // TODO moving camera - // mEdTransformEdit.ShowWorld(cameraView, cameraProj); + auto& camera = *mApp->GetActiveCamera(); ImGuizmo::SetRect(0, 0, io.DisplaySize.x, io.DisplaySize.y); ImGuizmo::SetDrawlist(ImGui::GetForegroundDrawList()); + auto cameraPos = camera.pos; + { + mEdTransformEdit.ShowWorld(&camera); + if (ImGui::IsMouseClicked(ImGuiMouseButton_Right) && !io.WantCaptureMouse && !mDragCam_Happening) { + mDragCam_CamInitial = camera.pos; + mDragCam_CursorInitial = ImGui::GetMousePos(); + mDragCam_Happening = true; + } + if (mDragCam_Happening) { + auto newPos = ImGui::GetMousePos(); + // NOTE: we are emulating as if the mouse is dragging the "canvas", through moving the camera in the opposite direction of the natural position delta + cameraPos.x = mDragCam_CamInitial.x + mDragCam_CursorInitial.x - newPos.x; + cameraPos.y = mDragCam_CamInitial.y + -(mDragCam_CursorInitial.y - newPos.y); // Invert Y delta because ImGui uses top-left origin (mouse moving down translates to positive value, but in our coordinate system down is negative) + + // Draw movement indicator + auto drawList = ImGui::GetForegroundDrawList(); + ImGui::DrawArrow(drawList, ImVec2(mDragCam_CursorInitial.x, mDragCam_CursorInitial.y), newPos, IM_COL32(0, 255, 255, 255)); + } + if (ImGui::IsMouseReleased(ImGuiMouseButton_Right)) { + mDragCam_Happening = false; + } + + constexpr float kCameraMoveSpeed = 5.0f; + if (ImGui::IsKeyDown(ImGuiKey_W)) { + cameraPos.y += kCameraMoveSpeed; + } + if (ImGui::IsKeyDown(ImGuiKey_S)) { + cameraPos.y -= kCameraMoveSpeed; + } + if (ImGui::IsKeyDown(ImGuiKey_A)) { + cameraPos.x -= kCameraMoveSpeed; + } + if (ImGui::IsKeyDown(ImGuiKey_D)) { + cameraPos.x += kCameraMoveSpeed; + } + } + // 2D camera: always look straight ahead + camera.pos = cameraPos; + camera.lookAt = cameraPos; + + // TODO get rid of this massive hack: how to manage const better for intuitively read-only, but write doesn't-care data? + auto& lastFrameInfo = const_cast<RendererFrameInfo&>(mApp->mWorldRenderer.GetLastFrameInfo()); + auto& cameraViewMat = lastFrameInfo.matrixView; + float* cameraView = &cameraViewMat[0][0]; + auto& cameraProjMat = lastFrameInfo.matrixProj; + float* cameraProj = &cameraProjMat[0][0]; if (mWindowVisible_Inspector) { ImGui::Begin("Inspector"); switch (mEdInspector.selectedItt) { @@ -516,46 +555,48 @@ void EditorInstance::Show() { if (mWindowVisible_WorldStructure) { ImGui::Begin("World structure"); - { - GobjTreeNodeShowInfo showInfo{ - .in_editor = this, - }; - GobjTreeNode(showInfo, &world->GetRoot()); + GobjTreeNodeShowInfo showInfo{ + .in_editor = this, + }; + GobjTreeNode(showInfo, &world->GetRoot()); - if (showInfo.out_openPopup) { - mPopupCurrent_GameObject = showInfo.out_openPopup; + if (showInfo.out_openPopup) { + mPopupCurrent_GameObject = showInfo.out_openPopup; - ImGui::OpenPopup("GameObject Popup"); - ImGui::SetNextWindowPos(ImGui::GetMousePos()); + ImGui::OpenPopup("GameObject Popup"); + ImGui::SetNextWindowPos(ImGui::GetMousePos()); + } + if (ImGui::BeginPopup("GameObject Popup")) { + // Target no longer selected during popup open + if (!mPopupCurrent_GameObject) { + ImGui::CloseCurrentPopup(); } - if (ImGui::BeginPopup("GameObject Popup")) { - // Target no longer selected during popup open - if (!mPopupCurrent_GameObject) { - ImGui::CloseCurrentPopup(); - } - if (ImGui::BeginMenu("Add child")) { - for (size_t i = 0; i < std::size(creatableGameObjects); ++i) { - auto& info = creatableGameObjects[i]; - if (ImGui::MenuItem(info.name)) { - auto object = info.factory(world); - mPopupCurrent_GameObject->AddChild(object); - } + if (ImGui::BeginMenu("Add child")) { + for (size_t i = 0; i < std::size(creatableGameObjects); ++i) { + auto& info = creatableGameObjects[i]; + if (ImGui::MenuItem(info.name)) { + auto object = info.factory(world); + mPopupCurrent_GameObject->AddChild(object); } - ImGui::EndMenu(); - } - ImGui::Separator(); - if (ImGui::MenuItem("Remove")) { - // TODO } - ImGui::EndPopup(); + ImGui::EndMenu(); + } + ImGui::Separator(); + if (ImGui::MenuItem("Remove")) { + ImGui::DialogConfirmation("Are you sure you want to delete this GameObject?", [object = mPopupCurrent_GameObject](bool yes) { + object->RemoveSelfFromParent(); + delete object; + }); } + ImGui::EndPopup(); } ImGui::End(); } ShowSpriteViewer(); + ImGui::ShowDialogs(); ImGui::ShowNotifications(); } @@ -575,6 +616,28 @@ void EditorInstance::ShowWorldProperties() { ImGui::SetTooltip("The game is currently paused. Click to run."); } } + + auto& camera = *mApp->GetActiveCamera(); + ImGui::TextUnformatted("Active camera:"); + ImGui::Indent(); +#define CAMERA_POS_TEXT "at (%.3f, %.3f, %.3f)\nlooking at (%.3f, %.3f, %.3f)", camera.pos.x, camera.pos.y, camera.pos.z, camera.lookAt.x, camera.lookAt.y, camera.lookAt.z + ImGui::TextUnformatted(camera.name.c_str()); + ImGui::Text(CAMERA_POS_TEXT); + if (ImGui::BeginPopupContextItem("##CTXMENU")) { + if (ImGui::MenuItem("Reset to origin")) { + camera.pos = {}; + camera.lookAt = {}; + } + if (ImGui::MenuItem("Copy")) { + char buffer[2048]; + int result = snprintf(buffer, sizeof(buffer), CAMERA_POS_TEXT); + ImGui::SetClipboardText(buffer); + ImGui::AddNotification(ImGuiToast(ImGuiToastType_Success, "Copied to clipboard.")); + } + ImGui::EndPopup(); + } +#undef CAMERA_POS_TEXT + ImGui::Unindent(); } // TOOD move resource-specific and gameobject-specific inspector code into attachments mechanism |