diff options
Diffstat (limited to 'source/EditorCore.cpp')
-rw-r--r-- | source/EditorCore.cpp | 314 |
1 files changed, 159 insertions, 155 deletions
diff --git a/source/EditorCore.cpp b/source/EditorCore.cpp index 1841dfb..8bdec40 100644 --- a/source/EditorCore.cpp +++ b/source/EditorCore.cpp @@ -203,119 +203,15 @@ void EditorContentBrowser::Show(bool* open) { ImGui::End(); } -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; - - // ImGuizmo::SetRect(0, 0, io.DisplaySize.x, io.DisplaySize.y); - - // if (showGrid) { - // ImGuizmo::DrawGrid(cameraView, cameraProjection, &identityMatrix[0][0], 100.f); - // } - - // 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) { - glm::mat4 identityMatrix(1.00f); - - if (ImGui::IsKeyPressed(90)) - mCurrentGizmoOperation = ImGuizmo::TRANSLATE; - if (ImGui::IsKeyPressed(69)) - mCurrentGizmoOperation = ImGuizmo::ROTATE; - if (ImGui::IsKeyPressed(82)) // r Key - mCurrentGizmoOperation = ImGuizmo::SCALE; - if (ImGui::RadioButton("Translate", mCurrentGizmoOperation == ImGuizmo::TRANSLATE)) - mCurrentGizmoOperation = ImGuizmo::TRANSLATE; - ImGui::SameLine(); - if (ImGui::RadioButton("Rotate", mCurrentGizmoOperation == ImGuizmo::ROTATE)) - mCurrentGizmoOperation = ImGuizmo::ROTATE; - ImGui::SameLine(); - if (ImGui::RadioButton("Scale", mCurrentGizmoOperation == ImGuizmo::SCALE)) - mCurrentGizmoOperation = ImGuizmo::SCALE; - if (ImGui::RadioButton("Universal", mCurrentGizmoOperation == ImGuizmo::UNIVERSAL)) - mCurrentGizmoOperation = ImGuizmo::UNIVERSAL; - - bool edited = false; - - float* matTranslation = &pos->x; - edited |= ImGui::InputFloat3("Tr", matTranslation); - - glm::vec3 eulerAngleRotation = glm::eulerAngles(*rotation); - float* matRotation = &eulerAngleRotation.x; - edited |= ImGui::InputFloat3("Rt", matRotation); - - float* matScale = &scale->x; - edited |= ImGui::InputFloat3("Sc", matScale); - - if (mCurrentGizmoOperation != ImGuizmo::SCALE) { - if (ImGui::RadioButton("Local", mCurrentGizmoMode == ImGuizmo::LOCAL)) - mCurrentGizmoMode = ImGuizmo::LOCAL; - ImGui::SameLine(); - if (ImGui::RadioButton("World", mCurrentGizmoMode == ImGuizmo::WORLD)) - mCurrentGizmoMode = ImGuizmo::WORLD; - } - if (ImGui::IsKeyPressed(83)) - useSnap = !useSnap; - ImGui::Checkbox("##UseSnap", &useSnap); - ImGui::SameLine(); - - switch (mCurrentGizmoOperation) { - case ImGuizmo::TRANSLATE: - ImGui::InputFloat3("Snap", &snap[0]); - break; - case ImGuizmo::ROTATE: - ImGui::InputFloat("Angle Snap", &snap[0]); - break; - case ImGuizmo::SCALE: - ImGui::InputFloat("Scale Snap", &snap[0]); - break; - default: break; - } - ImGui::Checkbox("Bound Sizing", &boundSizing); - if (boundSizing) { - ImGui::PushID(3); - ImGui::Checkbox("##BoundSizing", &boundSizingSnap); - ImGui::SameLine(); - ImGui::InputFloat3("Snap", boundsSnap); - ImGui::PopID(); - } - - return edited; -} - -bool EditorTransformEdit::ShowObject(float* cameraView, float* cameraProjection, glm::vec3* pos, glm::quat* rotation, glm::vec3* scale) { - glm::mat4 identityMatrix(1.00f); - glm::vec3 eulerAngleRotation = glm::eulerAngles(*rotation); - - float matrix[16]; - ImGuizmo::RecomposeMatrixFromComponents(&pos->x, &eulerAngleRotation.x, &scale->x, matrix); - - bool edited = ImGuizmo::Manipulate( - cameraView, - cameraProjection, - mCurrentGizmoOperation, - mCurrentGizmoMode, - matrix, - nullptr, - useSnap ? &snap[0] : nullptr, - boundSizing ? bounds : nullptr, - boundSizingSnap ? boundsSnap : nullptr); - - if (edited) { - ImGuizmo::DecomposeMatrixToComponents(matrix, &pos->x, &eulerAngleRotation.x, &scale->x); - *rotation = glm::quat(eulerAngleRotation); - } - - return edited; +namespace ProjectBrussel_UNITY_ID { +glm::quat CalcQuaternionFromDegreesEulerAngle(glm::vec3 eulerAngleDegrees) { + glm::vec3 eulerAngleRadians; + eulerAngleRadians.x = eulerAngleDegrees.x / 180 * M_PI; + eulerAngleRadians.y = eulerAngleDegrees.y / 180 * M_PI; + eulerAngleRadians.z = eulerAngleDegrees.z / 180 * M_PI; + return glm::quat(eulerAngleRadians); } -namespace ProjectBrussel_UNITY_ID { void PushKeyCodeRecorder(App* app, int* writeKey, bool* writeKeyStatus) { app->PushKeyCaptureCallback([=](int key, int action) { // Allow the user to cancel by pressing Esc @@ -416,7 +312,7 @@ EditorInstance::EditorInstance(App* app) , mEdContentBrowser(&mEdInspector) { mEditorCamera.name = "Editor Camera"s; mEditorCamera.Move(glm::vec3(0, 0, 1)); - mEditorCamera.LookAt(glm::vec3(0, 0, 0)); + mEditorCamera.LookAtAngle(glm::vec3(0, 0, -1)); mEditorCamera.SetHasPerspective(false); } @@ -474,7 +370,6 @@ void EditorInstance::Show() { auto cameraPos = camera.pos; { - mEdTransformEdit.ShowWorld(&camera); if (ImGui::IsMouseClicked(ImGuiMouseButton_Right) && !io.WantCaptureMouse && !mDragCam_Happening) { mDragCam_CamInitial = camera.pos; mDragCam_CursorInitial = ImGui::GetMousePos(); @@ -494,46 +389,29 @@ void EditorInstance::Show() { 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; + if (mMoveCamKeyboard) { + 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; + camera.Move(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) { case EditorInspector::ITT_GameObject: { auto object = static_cast<GameObject*>(mEdInspector.selectedItPtr); - - auto objectPos = object->GetPos(); - auto objectRot = object->GetRotation(); - glm::vec3 scale(1.0f); - if (mEdTransformEdit.ShowObjectInspector(cameraView, cameraProj, &objectPos, &objectRot, &scale) || - mEdTransformEdit.ShowObject(cameraView, cameraProj, &objectPos, &objectRot, &scale)) - { - object->SetPos(objectPos); - object->SetRotation(objectRot); - } - ShowInspector(object); } break; @@ -625,8 +503,7 @@ void EditorInstance::ShowWorldProperties() { ImGui::Text(CAMERA_POS_TEXT); if (ImGui::BeginPopupContextItem("##CTXMENU")) { if (ImGui::MenuItem("Reset to origin")) { - camera.pos = {}; - camera.lookAt = {}; + camera.Move(glm::vec3(1.0f, 1.0f, 1.0f)); } if (ImGui::MenuItem("Copy")) { char buffer[2048]; @@ -637,6 +514,7 @@ void EditorInstance::ShowWorldProperties() { ImGui::EndPopup(); } #undef CAMERA_POS_TEXT + ImGui::Checkbox("Move camera with WASD", &mMoveCamKeyboard); ImGui::Unindent(); } @@ -650,18 +528,128 @@ void EditorInstance::ShowInspector(GameObject* object) { using namespace Tags; using namespace ProjectBrussel_UNITY_ID; - auto ShowBasics = [&]() { - // TODO + auto& io = ImGui::GetIO(); + + auto objectEa = static_cast<EaGameObject*>(object->GetEditorAttachment()); + + auto ShowInspector = [&](/*array[6]*/ float* bounds = nullptr) { + glm::mat4 identityMatrix(1.00f); + + if (io.KeyAlt && ImGui::IsKeyPressed(ImGuiKey_T)) + mGuizmo.currOperation = ImGuizmo::TRANSLATE; + if (io.KeyAlt && ImGui::IsKeyPressed(ImGuiKey_R)) + mGuizmo.currOperation = ImGuizmo::ROTATE; + if (io.KeyAlt && ImGui::IsKeyPressed(ImGuiKey_S)) + mGuizmo.currOperation = ImGuizmo::SCALE; + if (ImGui::RadioButton("Translate", mGuizmo.currOperation == ImGuizmo::TRANSLATE)) + mGuizmo.currOperation = ImGuizmo::TRANSLATE; + ImGui::SameLine(); + if (ImGui::RadioButton("Rotate", mGuizmo.currOperation == ImGuizmo::ROTATE)) + mGuizmo.currOperation = ImGuizmo::ROTATE; + ImGui::SameLine(); + if (ImGui::RadioButton("Scale", mGuizmo.currOperation == ImGuizmo::SCALE)) + mGuizmo.currOperation = ImGuizmo::SCALE; + ImGui::SameLine(); + if (ImGui::RadioButton("Universal", mGuizmo.currOperation == ImGuizmo::UNIVERSAL)) + mGuizmo.currOperation = ImGuizmo::UNIVERSAL; + + if (mGuizmo.currOperation != ImGuizmo::SCALE) { + if (ImGui::RadioButton("Local", mGuizmo.currMode == ImGuizmo::LOCAL)) + mGuizmo.currMode = ImGuizmo::LOCAL; + ImGui::SameLine(); + if (ImGui::RadioButton("World", mGuizmo.currMode == ImGuizmo::WORLD)) + mGuizmo.currMode = ImGuizmo::WORLD; + } + + ImGui::Checkbox("##UseSnap", &mGuizmo.useSnap); + ImGui::SameLine(); + switch (mGuizmo.currOperation) { + case ImGuizmo::TRANSLATE: + ImGui::InputFloat3("Pos Snap", &mGuizmo.snap[0]); + break; + case ImGuizmo::ROTATE: + ImGui::InputFloat("Angle Snap", &mGuizmo.snap[0]); + break; + case ImGuizmo::SCALE: + ImGui::InputFloat("Scale Snap", &mGuizmo.snap[0]); + break; + default: break; + } + + if (bounds) { + ImGui::Checkbox("Bound Sizing", &mGuizmo.boundSizing); + if (mGuizmo.boundSizing) { + ImGui::PushID(3); + ImGui::Checkbox("##BoundSizing", &mGuizmo.boundSizingSnap); + ImGui::SameLine(); + ImGui::InputFloat3("Bound Snap", mGuizmo.boundsSnap); + ImGui::PopID(); + } + } + + ImGui::Separator(); + + auto objectPos = object->GetPos(); + if (ImGui::InputFloat3("Translation", &objectPos.x)) { + object->SetPos(objectPos); + } + + auto objectRot = object->GetRotation(); + if (ImGui::InputFloat3("Rotation", &objectEa->eulerAnglesRotation.x)) { + objectRot = CalcQuaternionFromDegreesEulerAngle(objectEa->eulerAnglesRotation); + object->SetRotation(objectRot); + } + + auto objectScale = object->GetScale(); + if (ImGui::InputFloat3("Scale", &objectScale.x)) { + object->SetScale(objectScale); + } + }; + + auto ShowGuizmo = [&](/*array[6]*/ float* bounds = nullptr) { + glm::mat4 identityMatrix(1.00f); + + // 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]; + + auto objectPos = object->GetPos(); + auto objectScale = object->GetScale(); + + float matrix[16]; + ImGuizmo::RecomposeMatrixFromComponents(&objectPos.x, &objectEa->eulerAnglesRotation.x, &objectScale.x, matrix); + + bool edited = ImGuizmo::Manipulate( + cameraView, + cameraProj, + mGuizmo.currOperation, + mGuizmo.currMode, + matrix, + nullptr, + mGuizmo.useSnap ? mGuizmo.snap : nullptr, + mGuizmo.boundSizing ? bounds : nullptr, + (bounds && mGuizmo.boundSizingSnap) ? mGuizmo.boundsSnap : nullptr); + + if (edited) { + ImGuizmo::DecomposeMatrixToComponents(matrix, &objectPos.x, &objectEa->eulerAnglesRotation.x, &objectScale.x); + object->SetPos(objectPos); + object->SetRotation(CalcQuaternionFromDegreesEulerAngle(objectEa->eulerAnglesRotation)); + object->SetScale(objectScale); + } }; auto type = object->GetKind(); switch (type) { case GameObject::KD_Player: { - ShowBasics(); + ShowInspector(); + ShowGuizmo(); ImGui::Separator(); auto player = static_cast<Player*>(object); - auto ea = static_cast<EaPlayer*>(player->GetEditorAttachment()); + auto ea = static_cast<EaPlayer*>(objectEa); auto& kb = player->keybinds; ImGui::Text("Player #%d", player->GetId()); @@ -734,7 +722,20 @@ void EditorInstance::ShowInspector(GameObject* object) { case GameObject::KD_SimpleGeometry: { auto sg = static_cast<SimpleGeometryObject*>(object); - ShowBasics(); + float bounds[6] = { + /*x1*/ -sg->GetSize().x / 2.0f, + /*y1*/ -sg->GetSize().y / 2.0f, + /*z1*/ 0.0f, + /*x2*/ +sg->GetSize().x / 2.0f, + /*y2*/ +sg->GetSize().y / 2.0f, + /*z2*/ 0.0f, + }; + + ShowInspector(bounds); + ShowGuizmo(bounds); + ImGui::Separator(); + + sg->SetSize(glm::vec2(bounds[3] - bounds[0], bounds[4] - bounds[1])); auto size = sg->GetSize(); if (ImGui::InputFloat2("Size", &size.x)) { @@ -743,7 +744,8 @@ void EditorInstance::ShowInspector(GameObject* object) { } break; case GameObject::KD_Building: { - ShowBasics(); + ShowInspector(); + ShowGuizmo(); ImGui::Separator(); auto b = static_cast<BuildingObject*>(object); @@ -751,7 +753,8 @@ void EditorInstance::ShowInspector(GameObject* object) { } break; case GameObject::KD_LevelWrapper: { - ShowBasics(); + ShowInspector(); + ShowGuizmo(); ImGui::Separator(); auto lwo = static_cast<LevelWrapperObject*>(object); @@ -759,7 +762,8 @@ void EditorInstance::ShowInspector(GameObject* object) { } break; default: { - ShowBasics(); + ShowInspector(); + ShowGuizmo(); } break; } } |