From f73c572eae36727a6749e76568bc444b57eaa6e2 Mon Sep 17 00:00:00 2001 From: Evgeny Prikazchikov Date: Wed, 31 Dec 2025 14:16:04 +0300 Subject: [PATCH] Editor: First start angle view in Viewport #1169 --- engine/includes/components/camera.h | 6 +- .../editor/viewport/cameracontroller.h | 64 ++-- engine/src/components/camera.cpp | 78 +++-- .../src/editor/viewport/cameracontroller.cpp | 276 +++++++++++------- engine/src/editor/viewport/viewport.cpp | 1 + engine/src/pipelinetasks/shadowmap.cpp | 2 - .../editor/graph/graphcontroller.cpp | 6 +- modules/uikit/src/editor/widgetcontroller.cpp | 2 +- thirdparty/next/src/math/aabb.cpp | 3 +- .../scenecomposer/actions/deleteobjects.cpp | 19 +- .../scenecomposer/objectcontroller.cpp | 5 +- .../screens/scenecomposer/scenecomposer.cpp | 27 +- .../src/screens/scenecomposer/scenecomposer.h | 1 + .../screens/scenecomposer/scenecomposer.ui | 2 +- 14 files changed, 303 insertions(+), 189 deletions(-) diff --git a/engine/includes/components/camera.h b/engine/includes/components/camera.h index f5343de26..d203ea75e 100644 --- a/engine/includes/components/camera.h +++ b/engine/includes/components/camera.h @@ -81,10 +81,8 @@ class ENGINE_EXPORT Camera : public Component { void drawGizmos() override; void drawGizmosSelected() override; - void recalcProjection(); - private: - Matrix4 m_projection; + mutable Matrix4 m_projection; Vector4 m_color; @@ -104,6 +102,8 @@ class ENGINE_EXPORT Camera : public Component { bool m_screen; + mutable bool m_dirty; + }; #endif // CAMERA_H diff --git a/engine/includes/editor/viewport/cameracontroller.h b/engine/includes/editor/viewport/cameracontroller.h index d6ef65fd2..a47d18d1c 100644 --- a/engine/includes/editor/viewport/cameracontroller.h +++ b/engine/includes/editor/viewport/cameracontroller.h @@ -2,7 +2,6 @@ #define CAMERACONTROLLER_H #include -#include #include #include @@ -13,8 +12,6 @@ class Actor; class Camera; class Viewport; -class QMenu; - class ENGINE_EXPORT CameraController : public QObject { Q_OBJECT @@ -25,6 +22,18 @@ class ENGINE_EXPORT CameraController : public QObject { Z }; + struct CameraData { + Vector3 rotation; + + Vector3 position; + + float focalDistance = 1.0f; + + float orthoSize = 1.0f; + + bool ortho = false; + }; + public: CameraController(); @@ -43,7 +52,7 @@ class ENGINE_EXPORT CameraController : public QObject { void setFocusOn(Actor *actor, float &bottom); - void setFree(bool flag) { m_cameraFree = flag; m_cameraFreeSaved = m_cameraFree; } + void setFree(bool flag) { m_cameraFree = flag; } bool isMovementBlocked() const { return m_blockMove; } void blockMovement(bool flag) { m_blockMove = flag; } @@ -63,13 +72,16 @@ class ENGINE_EXPORT CameraController : public QObject { void setGridAxis(Axis axis) { m_gridAxis = axis; } void restoreState(const VariantMap &state); - VariantMap saveState() const; + VariantMap saveState(); void setActiveRootObject(Object *object); void setZoomLimits(const Vector2 &limit); void doRotation(const Vector3 &vector); + void activateCamera(int index); + + void resetCamera(); signals: void setCursor(const QCursor &cursor); @@ -89,42 +101,34 @@ public slots: void drawHelpers(Object *object, bool selected); protected: - uint8_t m_cameraMove; - Axis m_gridAxis; + std::vector m_cameras; - bool m_blockMove; - bool m_blockRotation; - bool m_blockPicking; - bool m_overlapPicking; - - bool m_cameraFree; - bool m_cameraFreeSaved; - bool m_rotationTransfer; - - bool m_cameraInMove; + CameraData m_targetCamera; Vector2 m_screenSize; + Vector2 m_mouseSaved; + Vector2 m_mouseDelta; + Vector2 m_zoomLimit; Vector3 m_cameraSpeed; - Vector3 m_rotation; - Vector3 m_position; - - Vector3 m_rotationTarget; - Vector3 m_positionTarget; + Camera *m_activeCamera; - float m_orthoWidthTarget; - float m_focalLengthTarget; - float m_transferProgress; + Object *m_activeRootObject; - Vector2 m_delta; - Vector2 m_saved; + Axis m_gridAxis; - Camera *m_activeCamera; + float m_transferProgress; + int m_currentCamera; - Object *m_activeRootObject; + bool m_blockMove; + bool m_blockMoveOnTransfer; + bool m_blockRotation; + bool m_blockPicking; + bool m_overlapPicking; - Vector2 m_zoomLimit; + bool m_cameraFree; + bool m_cameraInMove; }; diff --git a/engine/src/components/camera.cpp b/engine/src/components/camera.cpp index 7be6d775f..f63580a88 100644 --- a/engine/src/components/camera.cpp +++ b/engine/src/components/camera.cpp @@ -24,9 +24,9 @@ Camera::Camera() : m_focal(1.0f), m_orthoSize(1.0f), m_ortho(false), - m_screen(false) { + m_screen(false), + m_dirty(true) { - recalcProjection(); } /*! @@ -42,6 +42,20 @@ Matrix4 Camera::viewMatrix() const { Returns projection matrix for the camera. */ Matrix4 Camera::projectionMatrix() const { + if(m_dirty) { + if(m_ortho) { + float width = m_orthoSize * m_ratio; + if(m_screen) { + m_projection = Matrix4::ortho(0, width, 0, m_orthoSize, m_near, m_far); + } else { + m_projection = Matrix4::ortho(-width / 2, width / 2, -m_orthoSize / 2, m_orthoSize / 2, m_near, m_far); + } + } else { + m_projection = Matrix4::perspective(m_fov, m_ratio, m_near, m_far); + } + + m_dirty = false; + } return m_projection; } /*! @@ -51,7 +65,7 @@ Matrix4 Camera::projectionMatrix() const { Vector3 Camera::project(const Vector3 &worldSpace) { Vector4 in(worldSpace.x, worldSpace.y, worldSpace.z, 1.0f); Vector4 out(viewMatrix() * in); - in = m_projection * out; + in = projectionMatrix() * out; if(in.w == 0.0f) { return Vector3(); // false; @@ -68,7 +82,7 @@ Vector3 Camera::project(const Vector3 &worldSpace) { Returns result of transformation. */ Vector3 Camera::unproject(const Vector3 &screenSpace) { - Matrix4 final((m_projection * viewMatrix()).inverse()); + Matrix4 final((projectionMatrix() * viewMatrix()).inverse()); Vector4 in(2.0f * screenSpace.x - 1.0f, 2.0f * screenSpace.y - 1.0f, @@ -117,8 +131,10 @@ float Camera::fov() const { \note Applicable only for the perspective mode. */ void Camera::setFov(const float angle) { - m_fov = angle; - recalcProjection(); + if(angle != m_fov) { + m_fov = angle; + m_dirty = true; + } } /*! Returns a distance to near cut plane. @@ -130,8 +146,10 @@ float Camera::nearPlane() const { Sets a \a distance to near cut plane. */ void Camera::setNear(const float distance) { - m_near = distance; - recalcProjection(); + if(distance != m_near) { + m_near = distance; + m_dirty = true; + } } /*! Returns a distance to far cut plane. @@ -143,8 +161,10 @@ float Camera::farPlane() const { Sets a \a distance to far cut plane. */ void Camera::setFar(const float distance) { - m_far = distance; - recalcProjection(); + if(distance != m_far) { + m_far = distance; + m_dirty = true; + } } /*! Returns the aspect ratio (width divided by height). @@ -156,8 +176,10 @@ float Camera::ratio() const { Sets the aspect \a ratio (width divided by height). */ void Camera::setRatio(float ratio) { - m_ratio = ratio; - recalcProjection(); + if(ratio != m_ratio) { + m_ratio = ratio; + m_dirty = true; + } } /*! Returns a focal distance for the camera. @@ -193,8 +215,11 @@ float Camera::orthoSize() const { Sets camera \a size for orthographic mode. */ void Camera::setOrthoSize(const float size) { - m_orthoSize = CLAMP(size, FLT_EPSILON, 100000.0f); - recalcProjection(); + float s = CLAMP(size, FLT_EPSILON, FLT_MAX); + if(s != m_orthoSize) { + m_orthoSize = s; + m_dirty = true; + } } /*! Returns true for the orthographic mode; for the perspective mode, returns false. @@ -206,8 +231,10 @@ bool Camera::orthographic() const { Sets orthographic \a mode. */ void Camera::setOrthographic(const bool mode) { - m_ortho = mode; - recalcProjection(); + if(m_ortho != mode) { + m_ortho = mode; + m_dirty = true; + } } /*! Returns true is this camera in the screen space mode. @@ -221,8 +248,10 @@ bool Camera::isScreenSpace() const { Typically used for Editor. */ void Camera::setScreenSpace(bool mode) { - m_screen = mode; - recalcProjection(); + if(mode != m_screen) { + m_screen = mode; + m_dirty = true; + } } /*! Returns current active camera. @@ -338,16 +367,3 @@ void Camera::drawGizmosSelected() { Gizmos::drawLines(points, indices, Vector4(0.5f, 0.5f, 0.5f, 1.0f)); } - -void Camera::recalcProjection() { - if(m_ortho) { - float width = m_orthoSize * m_ratio; - if(m_screen) { - m_projection = Matrix4::ortho(0, width, 0, m_orthoSize, m_near, m_far); - } else { - m_projection = Matrix4::ortho(-width / 2, width / 2, -m_orthoSize / 2, m_orthoSize / 2, m_near, m_far); - } - } else { - m_projection = Matrix4::perspective(m_fov, m_ratio, m_near, m_far); - } -} diff --git a/engine/src/editor/viewport/cameracontroller.cpp b/engine/src/editor/viewport/cameracontroller.cpp index 415f74bac..34ffc7026 100644 --- a/engine/src/editor/viewport/cameracontroller.cpp +++ b/engine/src/editor/viewport/cameracontroller.cpp @@ -6,16 +6,19 @@ #include #include +#include #include #include #include #include -#define DT 0.0625f - namespace { const char *gCamera("Camera"); + + const char *gCameras("cameras"); + const char *gCameraIndex("cameraIndex"); + const char *gPosition("position"); const char *gRotation("rotation"); const char *gOrthographic("orthographic"); @@ -25,30 +28,25 @@ namespace { } CameraController::CameraController() : + m_activeCamera(nullptr), + m_activeRootObject(nullptr), m_gridAxis(Axis::X), + m_transferProgress(1.0f), + m_currentCamera(-1), + m_zoomLimit(0.001f, 10000.0f), m_blockMove(false), + m_blockMoveOnTransfer(false), m_blockRotation(false), m_blockPicking(false), m_overlapPicking(false), m_cameraFree(true), - m_cameraFreeSaved(true), - m_rotationTransfer(false), - m_cameraInMove(false), - m_orthoWidthTarget(-1.0f), - m_focalLengthTarget(-1.0f), - m_transferProgress(1.0f), - m_activeCamera(nullptr), - m_activeRootObject(nullptr), - m_zoomLimit(0.001f, 10000.0f) { + m_cameraInMove(false) { Actor *actor = Engine::composeActor(gCamera); m_activeCamera = actor->getComponent(); - m_activeCamera->setFocalDistance(10.0f); - m_activeCamera->setOrthoSize(10.0f); - m_activeCamera->setColor(Vector4(0.2f, 0.2f, 0.2f, 0.0f)); - m_activeCamera->transform()->setPosition(Vector3(0.0f, 0.0f, 10.0f)); + resetCamera(); } void CameraController::drawHandles() { @@ -107,7 +105,7 @@ void CameraController::update() { Vector4 pos(Input::mousePosition()); if(Input::isMouseButtonDown(Input::MOUSE_RIGHT) || Input::isMouseButtonDown(Input::MOUSE_MIDDLE)) { - m_saved = Vector2(pos.x, pos.y); + m_mouseSaved = Vector2(pos.x, pos.y); } if(Input::isMouseButtonUp(Input::MOUSE_RIGHT) || Input::isMouseButtonUp(Input::MOUSE_MIDDLE)) { @@ -115,9 +113,9 @@ void CameraController::update() { } // Mouse control - m_delta = Vector2(pos.x, pos.y) - m_saved; + m_mouseDelta = Vector2(pos.x - m_mouseSaved.x, pos.y - m_mouseSaved.y); - Vector3 p(m_delta.x / m_screenSize.x * m_activeCamera->ratio(), m_delta.y / m_screenSize.y, 0.0f); + Vector3 p(m_mouseDelta.x / m_screenSize.x * m_activeCamera->ratio(), m_mouseDelta.y / m_screenSize.y, 0.0f); Handles::s_Mouse = Vector2(pos.z, pos.w); Handles::s_Screen = m_screenSize; @@ -130,26 +128,26 @@ void CameraController::update() { Vector2 p(pos.x, pos.y); - if(m_saved != p) { + if(m_mouseSaved != p) { m_cameraInMove = true; } - m_saved = p; + m_mouseSaved = p; } } else if(!m_blockRotation) { - cameraRotate(Vector3(-m_delta.y, m_delta.x, 0.0f) * 0.1f); - m_saved = Vector2(pos.x, pos.y); + cameraRotate(Vector3(-m_mouseDelta.y, m_mouseDelta.x, 0.0f) * 0.1f); + m_mouseSaved = Vector2(pos.x, pos.y); } } else if(Input::isMouseButton(Input::MOUSE_MIDDLE) && !m_blockMove) { Transform *t = m_activeCamera->transform(); float mult = m_activeCamera->orthographic() ? 1.0f : m_activeCamera->focalDistance() * 0.1f; cameraMove((t->quaternion() * p) * mult); - m_saved = Vector2(pos.x, pos.y); + m_mouseSaved = Vector2(pos.x, pos.y); } // Camera zoom - float delta = Input::mouseScrollDelta(); - if(delta != 0.0f) { - cameraZoom(delta); + float scrollDelta = Input::mouseScrollDelta(); + if(scrollDelta != 0.0f) { + cameraZoom(scrollDelta); } } @@ -158,38 +156,27 @@ void CameraController::move() { if(m_activeCamera) { Transform *t = m_activeCamera->transform(); if(m_transferProgress < 1.0f) { - if(m_rotationTransfer) { - cameraRotate(t->rotation() - MIX(t->rotation(), m_rotation, m_transferProgress)); - } else { - t->setPosition(MIX(t->position(), m_positionTarget, m_transferProgress)); - } - - if(m_orthoWidthTarget > 0.0f) { - m_activeCamera->setOrthoSize(MIX(m_activeCamera->orthoSize(), m_orthoWidthTarget, m_transferProgress)); - } + m_transferProgress = CLAMP(m_transferProgress + 2.0f * Timer::deltaTime(), 0.0f, 1.0f); - if(m_focalLengthTarget > 0.0f) { - m_activeCamera->setFocalDistance(MIX(m_activeCamera->focalDistance(), m_focalLengthTarget, m_transferProgress)); + if(!m_blockMoveOnTransfer) { + t->setPosition(MIX(t->position(), m_targetCamera.position, m_transferProgress)); } - m_transferProgress += 2.0f * DT; + Vector3 euler(MIX(t->rotation(), m_targetCamera.rotation, m_transferProgress)); - if(m_transferProgress >= 1.0f) { - m_cameraFree = m_cameraFreeSaved; + if(!m_cameraFree || m_blockMoveOnTransfer) { + Vector3 forward(0.0f, 0.0f, m_activeCamera->focalDistance()); + Vector3 dir(t->position() - t->quaternion() * forward); - if(m_rotationTransfer) { - cameraRotate(t->rotation() - m_rotation); - } else { - t->setPosition(m_positionTarget); - } + t->setPosition(dir + Quaternion(euler) * forward); + } + t->setRotation(euler); - if(m_orthoWidthTarget > 0.0f) { - m_activeCamera->setOrthoSize(m_orthoWidthTarget); - } + m_activeCamera->setOrthoSize(MIX(m_activeCamera->orthoSize(), m_targetCamera.orthoSize, m_transferProgress)); + m_activeCamera->setFocalDistance(MIX(m_activeCamera->focalDistance(), m_targetCamera.focalDistance, m_transferProgress)); - if(m_focalLengthTarget > 0.0f) { - m_activeCamera->setFocalDistance(m_focalLengthTarget); - } + if(m_transferProgress >= 1.0f) { + m_blockMoveOnTransfer = false; } } @@ -204,7 +191,7 @@ void CameraController::move() { t->setPosition(pos - delta * m_activeCamera->focalDistance() * 0.1f); - m_cameraSpeed -= m_cameraSpeed * 4.0f * DT; + m_cameraSpeed -= m_cameraSpeed * 8.0f * Timer::deltaTime(); if(m_cameraSpeed.length() <= .01f) { m_cameraSpeed = Vector3(); } @@ -213,64 +200,99 @@ void CameraController::move() { } void CameraController::onOrthographic(bool flag) { - if(m_activeCamera->orthographic() != flag) { - m_activeCamera->setOrthographic(flag); - if(flag) { - m_rotation = m_activeCamera->transform()->rotation(); - // Front - doRotation(Vector3()); - setGridAxis(Axis::Z); - } else { - setGridAxis(Axis::Y); - doRotation(m_rotation); + m_activeCamera->setOrthographic(flag); +} + +void CameraController::doRotation(const Vector3 &rotation) { + m_targetCamera.rotation = rotation; + m_targetCamera.focalDistance = m_activeCamera->focalDistance(); + m_targetCamera.orthoSize = m_activeCamera->orthoSize(); + m_blockMoveOnTransfer = true; + m_transferProgress = 0.0f; +} + +void CameraController::activateCamera(int index) { + if(index < m_cameras.size()) { + if(m_currentCamera >= 0) { + m_cameras[m_currentCamera].ortho = m_activeCamera->orthographic(); + m_cameras[m_currentCamera].orthoSize = m_activeCamera->orthoSize(); + m_cameras[m_currentCamera].focalDistance = m_activeCamera->focalDistance(); + + Transform *t = m_activeCamera->transform(); + m_cameras[m_currentCamera].position = t->position(); + m_cameras[m_currentCamera].rotation = t->rotation(); } - m_orthoWidthTarget = -1.0f; - m_focalLengthTarget = -1.0f; + + m_currentCamera = index; + m_targetCamera = m_cameras[m_currentCamera]; + m_transferProgress = 0.0f; + + onOrthographic(m_targetCamera.ortho); } } +void CameraController::resetCamera() { + float dist = 10.0f; + + Vector3 rotation(-30.0f,-45.0f, 0.0f); + + Vector3 forward(0.0f, 0.0f, dist); + Vector3 position(Quaternion(rotation) * forward); + + m_cameras.clear(); + m_cameras.push_back({rotation, position, dist, false}); + m_cameras.push_back({Vector3(), Vector3(0.0f, 0.0f, -10.0f), dist, true}); + + Transform *t = m_activeCamera->transform(); + t->setPosition(m_cameras[0].position); + t->setRotation(m_cameras[0].rotation); + + m_activeCamera->setFocalDistance(m_cameras[0].focalDistance); + m_activeCamera->setOrthoSize(m_cameras[0].orthoSize); + m_activeCamera->setOrthographic(m_cameras[0].ortho); +} + void CameraController::setFocusOn(Actor *actor, float &bottom) { - bottom = 0; + bottom = 0.0f; if(actor) { AABBox bb(Vector3(FLT_MAX), Vector3(-FLT_MAX)); for(auto it : actor->findChildren()) { bb.encapsulate(it->bound()); } + float radius = 1.0f; + bottom = radius; + Vector3 center(actor->transform()->worldPosition()); if(bb.isValid()) { - float radius = (bb.radius * 2.0f) / sinf(m_activeCamera->fov() * DEG2RAD); + radius = bb.radius * 2.0f; Vector3 min, max; bb.box(min, max); bottom = min.y; - m_focalLengthTarget = radius; - m_orthoWidthTarget = radius; - Transform *camera = m_activeCamera->transform(); - m_positionTarget = bb.center + camera->quaternion() * Vector3(0.0f, 0.0f, radius); - m_transferProgress = 0.0f; - m_rotationTransfer = false; + center = bb.center; } - } -} -void CameraController::doRotation(const Vector3 &vector) { - m_rotation = vector; - m_positionTarget = m_activeCamera->transform()->position(); + if(m_activeCamera->orthographic()) { + radius /= sinf(m_activeCamera->fov() * DEG2RAD); + } + radius = CLAMP(radius, FLT_EPSILON, FLT_MAX); - m_cameraFreeSaved = m_cameraFree; - m_cameraFree = false; - m_transferProgress = 0.0f; - m_rotationTransfer = true; + Transform *camera = m_activeCamera->transform(); + m_targetCamera.position = center + camera->quaternion() * Vector3(0.0f, 0.0f, radius); + m_targetCamera.rotation = camera->rotation(); + m_targetCamera.focalDistance = radius; + m_targetCamera.orthoSize = radius; + + m_transferProgress = 0.0f; + } } void CameraController::cameraZoom(float delta) { if(m_activeCamera) { if(m_activeCamera->orthographic()) { float size = m_activeCamera->orthoSize(); - float scale = size / m_screenSize.x; - scale = CLAMP(size - (delta * scale), m_zoomLimit.x, m_zoomLimit.y); m_activeCamera->setOrthoSize(scale); @@ -290,9 +312,10 @@ void CameraController::cameraRotate(const Vector3 &delta) { Transform *t = m_activeCamera->transform(); Vector3 euler = t->rotation() - delta; - if(!m_cameraFree) { - Vector3 dir = t->position() - t->quaternion() * Vector3(0.0f, 0.0f, m_activeCamera->focalDistance()); - t->setPosition(dir + Quaternion(euler) * Vector3(0.0f, 0.0f, m_activeCamera->focalDistance())); + if(!m_cameraFree || Input::isKey(Input::KEY_LEFT_ALT) || m_transferProgress < 1.0f) { + Vector3 forward(0.0f, 0.0f, m_activeCamera->focalDistance()); + Vector3 dir = t->position() - t->quaternion() * forward; + t->setPosition(dir + Quaternion(euler) * forward); } t->setRotation(euler); } @@ -304,49 +327,98 @@ void CameraController::cameraMove(const Vector3 &delta) { void CameraController::restoreState(const VariantMap &state) { if(m_activeCamera) { - Transform *t = m_activeCamera->transform(); - auto it = state.find(gPosition); + int currentCamera = 0; + + auto it = state.find(gOrthographic); if(it != state.end()) { - t->setPosition((*it).second.toVector3()); + bool ortho = (*it).second.toBool(); + currentCamera = ortho ? 1 : 0; + m_cameras[currentCamera].ortho = ortho; } - it = state.find(gRotation); + it = state.find(gPosition); if(it != state.end()) { - t->setRotation((*it).second.toVector3()); + m_cameras[currentCamera].rotation = (*it).second.toVector3(); } - it = state.find(gOrthographic); + it = state.find(gRotation); if(it != state.end()) { - m_activeCamera->setOrthographic((*it).second.toBool()); + m_cameras[currentCamera].position = (*it).second.toVector3(); } it = state.find(gFocal); if(it != state.end()) { - m_activeCamera->setFocalDistance((*it).second.toFloat()); + m_cameras[currentCamera].focalDistance = (*it).second.toFloat(); } it = state.find(gOrthoSize); if(it != state.end()) { - m_activeCamera->setOrthoSize((*it).second.toFloat()); + m_cameras[currentCamera].orthoSize = (*it).second.toFloat(); } it = state.find(gGridAxis); if(it != state.end()) { m_gridAxis = static_cast((*it).second.toInt()); } + + it = state.find(gCameras); + if(it != state.end()) { + m_cameras.clear(); + + for(auto &camera : (*it).second.toList()) { + VariantList fields = camera.toList(); + + auto field = fields.begin(); + + CameraData data; + data.rotation = (*field).toVector3(); + ++field; + data.position = (*field).toVector3(); + ++field; + data.orthoSize = (*field).toFloat(); + ++field; + data.focalDistance = (*field).toFloat(); + ++field; + data.ortho = (*field).toBool(); + + m_cameras.push_back(data); + } + } + + it = state.find(gCameraIndex); + if(it != state.end()) { + currentCamera = (*it).second.toInt(); + } + + activateCamera(currentCamera); } } -VariantMap CameraController::saveState() const { +VariantMap CameraController::saveState() { VariantMap result; if(m_activeCamera) { - Transform *t = m_activeCamera->transform(); - result[gPosition] = t->position(); - result[gRotation] = t->rotation(); - result[gOrthographic] = m_activeCamera->orthographic(); - result[gFocal] = m_activeCamera->focalDistance(); - result[gOrthoSize] = m_activeCamera->orthoSize(); result[gGridAxis] = static_cast(m_gridAxis); + result[gCameraIndex] = m_currentCamera; + + Transform *t = m_activeCamera->transform(); + m_cameras[m_currentCamera].rotation = t->rotation(); + m_cameras[m_currentCamera].position = t->position(); + m_cameras[m_currentCamera].ortho = m_activeCamera->orthographic(); + m_cameras[m_currentCamera].orthoSize = m_activeCamera->orthoSize(); + m_cameras[m_currentCamera].focalDistance = m_activeCamera->focalDistance(); + + VariantList cameras; + for(auto &it : m_cameras) { + VariantList fields; + fields.push_back(it.rotation); + fields.push_back(it.position); + fields.push_back(it.orthoSize); + fields.push_back(it.focalDistance); + fields.push_back(it.ortho); + + cameras.push_back(fields); + } + result[gCameras] = cameras; } return result; } diff --git a/engine/src/editor/viewport/viewport.cpp b/engine/src/editor/viewport/viewport.cpp index 968c915dd..973f8079d 100644 --- a/engine/src/editor/viewport/viewport.cpp +++ b/engine/src/editor/viewport/viewport.cpp @@ -16,6 +16,7 @@ #include #include #include +#include #include #include diff --git a/engine/src/pipelinetasks/shadowmap.cpp b/engine/src/pipelinetasks/shadowmap.cpp index 96eb81b1e..8ee744f0d 100644 --- a/engine/src/pipelinetasks/shadowmap.cpp +++ b/engine/src/pipelinetasks/shadowmap.cpp @@ -160,8 +160,6 @@ void ShadowMap::areaLightUpdate(AreaLight *light, const RenderList &components) void ShadowMap::directLightUpdate(DirectLight *light, const RenderList &components) { const Camera *camera = m_context->currentCamera(); - - float nearPlane = camera->nearPlane(); Matrix4 p(camera->projectionMatrix()); diff --git a/modules/editor/grapheditor/editor/graph/graphcontroller.cpp b/modules/editor/grapheditor/editor/graph/graphcontroller.cpp index d88f69aa3..6f8318679 100644 --- a/modules/editor/grapheditor/editor/graph/graphcontroller.cpp +++ b/modules/editor/grapheditor/editor/graph/graphcontroller.cpp @@ -296,8 +296,6 @@ void GraphController::update() { } if(m_dragWidget) { - RectTransform *dragRect = m_dragWidget->rectTransform(); - if(Input::isMouseButton(Input::MOUSE_LEFT)) { Vector2 deltaPos = pos - m_originMousePos; @@ -306,7 +304,7 @@ void GraphController::update() { auto selectedOrigin = m_selectedOrigins.begin(); for(auto it : m_selected) { GraphNode *node = m_graph->node(it); - RectTransform *rect = m_graph->node(it)->widget()->rectTransform(); + RectTransform *rect = node->widget()->rectTransform(); Vector2 newPos(*selectedOrigin + deltaPos); for(int n = 0; n < 2; n++) { @@ -387,7 +385,7 @@ void GraphController::cameraMove(const Vector3 &delta) { CameraController::cameraMove(delta); Transform *t = m_view->view().transform(); - t->setPosition(t->position() + Vector3(m_delta, 0.0f)); + t->setPosition(t->position() + Vector3(m_mouseDelta, 0.0f)); } void GraphController::cameraZoom(float delta) { diff --git a/modules/uikit/src/editor/widgetcontroller.cpp b/modules/uikit/src/editor/widgetcontroller.cpp index 657f64573..a5888234a 100644 --- a/modules/uikit/src/editor/widgetcontroller.cpp +++ b/modules/uikit/src/editor/widgetcontroller.cpp @@ -184,7 +184,7 @@ void WidgetController::update() { void WidgetController::cameraMove(const Vector3 &delta) { Transform *rootTransform = m_rootObject->transform(); - rootTransform->setPosition(rootTransform->position() + Vector3(m_delta, 0.0f)); + rootTransform->setPosition(rootTransform->position() + Vector3(m_mouseDelta, 0.0f)); Transform *cameraTransform = m_activeCamera->transform(); cameraTransform->setPosition(cameraTransform->position() - delta * m_activeCamera->orthoSize()); diff --git a/thirdparty/next/src/math/aabb.cpp b/thirdparty/next/src/math/aabb.cpp index e6433852b..217dc6899 100644 --- a/thirdparty/next/src/math/aabb.cpp +++ b/thirdparty/next/src/math/aabb.cpp @@ -20,6 +20,7 @@ #include #include +#include /*! \class AABBox @@ -64,7 +65,7 @@ AABBox &AABBox::operator=(const AABBox &value) { Returns true in case of AABBox is valid; otherwise returns false. */ bool AABBox::isValid() const { - return radius > 0.0f; + return std::isfinite(radius); } /*! Grow the AABBox to encapsulate a spehere with \a position and \a radius. diff --git a/worldeditor/src/screens/scenecomposer/actions/deleteobjects.cpp b/worldeditor/src/screens/scenecomposer/actions/deleteobjects.cpp index 25812f46c..273e754d1 100644 --- a/worldeditor/src/screens/scenecomposer/actions/deleteobjects.cpp +++ b/worldeditor/src/screens/scenecomposer/actions/deleteobjects.cpp @@ -3,6 +3,8 @@ #include #include +#include + DeleteObjects::DeleteObjects(const Object::ObjectList &objects, ObjectController *ctrl, const TString &name, UndoCommand *group) : UndoCommand(name, group), m_controller(ctrl) { @@ -13,7 +15,7 @@ DeleteObjects::DeleteObjects(const Object::ObjectList &objects, ObjectController } void DeleteObjects::undo() { - QSet scenes; + std::set scenes; auto it = m_parents.begin(); auto index = m_indices.begin(); @@ -51,7 +53,7 @@ void DeleteObjects::undo() { } void DeleteObjects::redo() { - QSet scenes; + std::set scenes; m_parents.clear(); m_dump.clear(); @@ -61,9 +63,16 @@ void DeleteObjects::redo() { m_dump.push_back(Engine::toVariant(object)); m_parents.push_back(object->parent()->uuid()); - auto c = object->parent()->getChildren(); - QList children(c.begin(), c.end()); - m_indices.push_back(children.indexOf(object)); + int index = -1; + for(auto it : object->parent()->getChildren()) { + index++; + if(it == object) { + break; + } + } + if(index != -1) { + m_indices.push_back(index); + } } } for(auto it : m_objects) { diff --git a/worldeditor/src/screens/scenecomposer/objectcontroller.cpp b/worldeditor/src/screens/scenecomposer/objectcontroller.cpp index 960614882..e046f7df8 100644 --- a/worldeditor/src/screens/scenecomposer/objectcontroller.cpp +++ b/worldeditor/src/screens/scenecomposer/objectcontroller.cpp @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -307,9 +308,9 @@ void ObjectController::drawHandles() { } if(m_isolatedPrefab) { - m_activeRootObject = m_isolatedPrefab->actor(); + setActiveRootObject(m_isolatedPrefab->actor()); } else { - m_activeRootObject = Engine::world(); + setActiveRootObject(Engine::world()); } CameraController::drawHandles(); diff --git a/worldeditor/src/screens/scenecomposer/scenecomposer.cpp b/worldeditor/src/screens/scenecomposer/scenecomposer.cpp index 4cc586029..7fd14c7d0 100644 --- a/worldeditor/src/screens/scenecomposer/scenecomposer.cpp +++ b/worldeditor/src/screens/scenecomposer/scenecomposer.cpp @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -204,18 +205,14 @@ SceneComposer::SceneComposer(QWidget *parent) : connect(m_controller, &ObjectController::propertyChanged, this, &SceneComposer::objectsChanged); connect(m_controller, &ObjectController::showToolPanel, this, &SceneComposer::onShowToolPanel); - connect(m_controller, &ObjectController::setCursor, ui->viewport, &Viewport::onCursorSet, Qt::DirectConnection); - connect(m_controller, &ObjectController::unsetCursor, ui->viewport, &Viewport::onCursorUnset, Qt::DirectConnection); - - connect(ui->orthoButton, &QPushButton::toggled, m_controller, &ObjectController::onOrthographic); - connect(ui->localButton, &QPushButton::toggled, m_controller, &ObjectController::onLocal); + connect(ui->camera2DButton, &QPushButton::toggled, this, &SceneComposer::onCamera2D); connect(ui->localButton, &QPushButton::toggled, this, &SceneComposer::onLocal); connect(PluginManager::instance(), &PluginManager::pluginReloaded, m_controller, &ObjectController::onUpdateSelected); connect(AssetManager::instance(), &AssetManager::buildSuccessful, this, &SceneComposer::onRepickSelected); connect(AssetManager::instance(), &AssetManager::importFinished, this, &SceneComposer::onReloadPrefab); - ui->orthoButton->setProperty("checkgreen", true); + ui->camera2DButton->setProperty("checkgreen", true); m_objectActions.push_back(createAction(m_actorMenu, tr("Rename"), nullptr, true, QKeySequence(Qt::Key_F2))); m_objectActions.push_back(createAction(m_actorMenu, tr("Duplicate"), SLOT(onActorDuplicate()), false)); @@ -279,7 +276,7 @@ void SceneComposer::restoreState(const VariantMap &data) { } } - ui->orthoButton->setChecked(m_controller->activeCamera()->orthographic()); + ui->camera2DButton->setChecked(m_controller->activeCamera()->orthographic()); } void SceneComposer::takeScreenshot() { @@ -592,6 +589,8 @@ void SceneComposer::onNewAsset() { m_settings.clear(); m_sceneSettings.clear(); + m_controller->resetCamera(); + Map *map = Engine::objectCreate(""); map->setScene(Engine::world()->createScene("Untitled")); @@ -622,6 +621,20 @@ void SceneComposer::saveAsset(const TString &path) { void SceneComposer::onLocal(bool flag) { ui->localButton->setIcon(flag ? QIcon(":/Style/styles/dark/icons/local.png") : QIcon(":/Style/styles/dark/icons/global.png")); + + m_controller->onLocal(flag); +} + +void SceneComposer::onCamera2D(bool flag) { + if(flag) { + m_controller->setGridAxis(CameraController::Axis::Z); + m_controller->activateCamera(1); + } else { + m_controller->setGridAxis(CameraController::Axis::Y); + m_controller->activateCamera(0); + } + + m_controller->onOrthographic(flag); } void SceneComposer::onCreateActor() { diff --git a/worldeditor/src/screens/scenecomposer/scenecomposer.h b/worldeditor/src/screens/scenecomposer/scenecomposer.h index 1dd2c51b9..04b59f7d1 100644 --- a/worldeditor/src/screens/scenecomposer/scenecomposer.h +++ b/worldeditor/src/screens/scenecomposer/scenecomposer.h @@ -72,6 +72,7 @@ private slots: void onDropMap(QString name, bool additive); void onLocal(bool flag); + void onCamera2D(bool flag); void onSetActiveScene(); diff --git a/worldeditor/src/screens/scenecomposer/scenecomposer.ui b/worldeditor/src/screens/scenecomposer/scenecomposer.ui index 0a73b0694..aeb7e11d7 100644 --- a/worldeditor/src/screens/scenecomposer/scenecomposer.ui +++ b/worldeditor/src/screens/scenecomposer/scenecomposer.ui @@ -127,7 +127,7 @@ - + 10