Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 107 additions & 12 deletions atlas/application/window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2028,6 +2028,21 @@ void Window::setEditorControlsEnabled(bool enabled) {
}
}

void Window::setEditorSceneCamera(Camera *sceneCamera) {
editorSceneCamera = sceneCamera;
editorCameraFrustumInitialized = false;
}

void Window::setEditorCameraFocused(bool focused) {
editorCameraFocused = focused;
editorCameraDragging = false;
editorCameraPanning = false;
editorOrbitVelocityX = 0.0f;
editorOrbitVelocityY = 0.0f;
editorZoomVelocity = 0.0f;
editorCameraKeys.fill(false);
}

void Window::setEditorSimulationEnabled(bool enabled) {
editorSimulationEnabled = enabled;
editorDragging = false;
Expand Down Expand Up @@ -2260,6 +2275,8 @@ void Window::editorPointerEvent(int action, float x, float y, int button,
}

if (button == 3) {
if (editorCameraFocused)
return;
if (action == 0) {
editorCameraPanning = true;
editorCameraLastX = x;
Expand All @@ -2273,6 +2290,8 @@ void Window::editorPointerEvent(int action, float x, float y, int button,
}

if (button == 2) {
if (editorCameraFocused)
return;
if (action == 0) {
editorCameraDragging = true;
editorCameraLastX = x;
Expand Down Expand Up @@ -2348,7 +2367,7 @@ void Window::editorPointerEvent(int action, float x, float y, int button,
}

void Window::editorScrollEvent(float delta, float scale) {
if (!editorControlsEnabled || camera == nullptr) {
if (!editorControlsEnabled || camera == nullptr || editorCameraFocused) {
return;
}

Expand All @@ -2370,6 +2389,10 @@ void Window::editorKeyEvent(int key, bool pressed) {
if (key < 0 || key >= static_cast<int>(editorCameraKeys.size())) {
return;
}
if (editorCameraFocused) {
editorCameraKeys.fill(false);
return;
}
editorCameraKeys[static_cast<std::size_t>(key)] = pressed;
}

Expand Down Expand Up @@ -2989,7 +3012,7 @@ void Window::applyEditorZoomDelta(float scrollAmount) {
}

void Window::updateEditorCameraMovement(float deltaTime) {
if (camera == nullptr) {
if (camera == nullptr || editorCameraFocused) {
return;
}

Expand Down Expand Up @@ -3040,7 +3063,7 @@ void Window::updateEditorCameraMovement(float deltaTime) {
}

void Window::updateEditorCameraInertia(float deltaTime) {
if (camera == nullptr) {
if (camera == nullptr || editorCameraFocused) {
return;
}

Expand Down Expand Up @@ -3141,6 +3164,62 @@ void Window::updateEditorControlGeometry() {
ensureEditorLineObject(editorGridObject, editorGridInitialized,
gridVertices);

if (editorSceneCamera != nullptr && !editorCameraFocused) {
const glm::vec3 scenePosition = editorSceneCamera->position.toGlm();
glm::vec3 sceneForward =
editorSceneCamera->target.toGlm() - scenePosition;
if (glm::length(sceneForward) < 0.000001f)
sceneForward = editorSceneCamera->getFrontVector().toGlm();
sceneForward = glm::normalize(sceneForward);
glm::vec3 sceneUp(0.0f, 1.0f, 0.0f);
if (std::abs(glm::dot(sceneForward, sceneUp)) > 0.98f)
sceneUp = glm::vec3(1.0f, 0.0f, 0.0f);
const glm::vec3 sceneRight =
glm::normalize(glm::cross(sceneForward, sceneUp));
sceneUp = glm::normalize(glm::cross(sceneRight, sceneForward));

const float depth = std::clamp(editorSceneCamera->farClip, 1.5f, 4.0f);
float halfHeight =
editorSceneCamera->useOrthographic
? std::max(0.1f, editorSceneCamera->orthographicSize)
: std::tan(glm::radians(editorSceneCamera->fov) * 0.5f) * depth;
halfHeight = std::clamp(halfHeight, 0.15f, 6.0f);
const float halfWidth = halfHeight * aspect;
const glm::vec3 planeCenter = scenePosition + sceneForward * depth;
const glm::vec3 bottomLeft =
planeCenter - sceneRight * halfWidth - sceneUp * halfHeight;
const glm::vec3 bottomRight =
planeCenter + sceneRight * halfWidth - sceneUp * halfHeight;
const glm::vec3 topRight =
planeCenter + sceneRight * halfWidth + sceneUp * halfHeight;
const glm::vec3 topLeft =
planeCenter - sceneRight * halfWidth + sceneUp * halfHeight;
const Color cameraColor{0.2f, 0.78f, 1.0f, 0.95f};
const Color directionColor{1.0f, 0.72f, 0.2f, 1.0f};
std::vector<CoreVertex> cameraVertices;
cameraVertices.reserve(30);
appendEditorLine(cameraVertices, bottomLeft, bottomRight, cameraColor);
appendEditorLine(cameraVertices, bottomRight, topRight, cameraColor);
appendEditorLine(cameraVertices, topRight, topLeft, cameraColor);
appendEditorLine(cameraVertices, topLeft, bottomLeft, cameraColor);
appendEditorLine(cameraVertices, scenePosition, bottomLeft,
cameraColor);
appendEditorLine(cameraVertices, scenePosition, bottomRight,
cameraColor);
appendEditorLine(cameraVertices, scenePosition, topRight, cameraColor);
appendEditorLine(cameraVertices, scenePosition, topLeft, cameraColor);
appendEditorLine(cameraVertices, scenePosition,
scenePosition + sceneForward * (depth * 1.18f),
directionColor);
const glm::vec3 markerCenter =
(topLeft + topRight) * 0.5f + sceneUp * (halfHeight * 0.18f);
appendEditorLine(cameraVertices, topLeft, markerCenter, directionColor);
appendEditorLine(cameraVertices, markerCenter, topRight,
directionColor);
ensureEditorLineObject(editorCameraFrustumObject,
editorCameraFrustumInitialized, cameraVertices);
}

if (selectedEditorObject == nullptr) {
return;
}
Expand Down Expand Up @@ -3374,7 +3453,9 @@ void Window::renderEditorGrid(
void Window::renderEditorOverlays(
const std::shared_ptr<opal::CommandBuffer> &commandBuffer) {
if (!editorControlsEnabled || commandBuffer == nullptr ||
camera == nullptr || selectedEditorObject == nullptr) {
camera == nullptr ||
(selectedEditorObject == nullptr &&
(editorSceneCamera == nullptr || editorCameraFocused))) {
return;
}

Expand All @@ -3399,17 +3480,31 @@ void Window::renderEditorOverlays(
updatePipelineStateField(this->dstBlend, opal::BlendFunc::OneMinusSrcAlpha);
updatePipelineStateField(this->writeDepth, false);

updatePipelineStateField(this->primitiveStyle,
opal::PrimitiveStyle::Triangles);
updatePipelineStateField(this->useDepth, true);
updatePipelineStateField(this->depthCompareOp, opal::CompareOp::Less);
renderEditorLineObject(editorOutlineObject.get(), view, projection,
commandBuffer);
if (editorControlMode != EditorControlMode::None) {
if (editorSceneCamera != nullptr && !editorCameraFocused &&
editorCameraFrustumObject != nullptr) {
updatePipelineStateField(this->primitiveStyle,
opal::PrimitiveStyle::Lines);
updatePipelineStateField(this->useDepth, false);
updatePipelineStateField(this->depthCompareOp, opal::CompareOp::Always);
renderEditorLineObject(editorGizmoObject.get(), view, projection,
updatePipelineStateField(this->lineWidth, 2.2f);
renderEditorLineObject(editorCameraFrustumObject.get(), view,
projection, commandBuffer);
}

if (selectedEditorObject != nullptr) {
updatePipelineStateField(this->primitiveStyle,
opal::PrimitiveStyle::Triangles);
updatePipelineStateField(this->useDepth, true);
updatePipelineStateField(this->depthCompareOp, opal::CompareOp::Less);
renderEditorLineObject(editorOutlineObject.get(), view, projection,
commandBuffer);
if (editorControlMode != EditorControlMode::None) {
updatePipelineStateField(this->useDepth, false);
updatePipelineStateField(this->depthCompareOp,
opal::CompareOp::Always);
renderEditorLineObject(editorGizmoObject.get(), view, projection,
commandBuffer);
}
}

updatePipelineStateField(this->primitiveStyle, previousPrimitiveStyle);
Expand Down
24 changes: 24 additions & 0 deletions editor/views/editor/inspector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1679,6 +1679,30 @@ void InspectorPanel::showCamera() {
headerLayout->addWidget(identity, 1);
contentLayout->addWidget(header);

auto *cameraView = new QToolButton(content);
cameraView->setObjectName("inspectorAddComponentButton");
cameraView->setCheckable(true);
cameraView->setChecked(viewport != nullptr && viewport->isCameraFocused());
cameraView->setIcon(styling::icon(styling::Icon::Camera, "#9E897D"));
cameraView->setText(cameraView->isChecked() ? "Camera View Active"
: "Look Through Camera");
cameraView->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
cameraView->setToolTip("Toggle Main Camera view · Numpad 0");
contentLayout->addWidget(cameraView);
connect(cameraView, &QToolButton::clicked, this, [this] {
if (viewport != nullptr)
viewport->toggleCameraFocus();
});
if (viewport != nullptr) {
connect(viewport, &ViewportPanel::cameraFocusChanged, cameraView,
[cameraView](bool focused) {
const QSignalBlocker blocker(cameraView);
cameraView->setChecked(focused);
cameraView->setText(focused ? "Camera View Active"
: "Look Through Camera");
});
}

auto update = [this](const QString &path, const QJsonValue &value) {
if (viewport != nullptr) {
viewport->setRuntimeSceneProperty("camera", -1, path, value);
Expand Down
31 changes: 31 additions & 0 deletions editor/views/editor/viewport.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -501,6 +501,17 @@ void ViewportPanel::wheelEvent(QWheelEvent *event) {
void ViewportPanel::keyPressEvent(QKeyEvent *event) {
if (!event->isAutoRepeat() && runtimeContext != nullptr &&
playbackState == 0) {
if (event->key() == Qt::Key_0 &&
event->modifiers().testFlag(Qt::KeypadModifier)) {
toggleCameraFocus();
event->accept();
return;
}
if (event->key() == Qt::Key_Escape && isCameraFocused()) {
setCameraFocused(false);
event->accept();
return;
}
if (keyboardTransformActive) {
if (event->key() == Qt::Key_Escape) {
finishKeyboardTransform(false);
Expand Down Expand Up @@ -617,6 +628,7 @@ void ViewportPanel::startRuntime() {
}
}
emit runtimeAvailabilityChanged(true);
emit cameraFocusChanged(false);
playbackState = 0;
emit playbackStateChanged(playbackState);
frameTimer->start(16);
Expand Down Expand Up @@ -661,6 +673,7 @@ void ViewportPanel::stopRuntime() {
if (undoStack != nullptr)
undoStack->clear();
emit runtimeAvailabilityChanged(false);
emit cameraFocusChanged(false);
playbackState = 0;
emit playbackStateChanged(playbackState);
try {
Expand Down Expand Up @@ -747,6 +760,24 @@ bool ViewportPanel::selectRuntimeObject(int id, bool focusCamera) {
return true;
}

bool ViewportPanel::setCameraFocused(bool focused) {
if (runtimeContext == nullptr || playbackState != 0 ||
!runtimeContext->setEditorCameraFocused(focused)) {
return false;
}
emit cameraFocusChanged(focused);
setFocus(Qt::OtherFocusReason);
return true;
}

void ViewportPanel::toggleCameraFocus() {
setCameraFocused(!isCameraFocused());
}

bool ViewportPanel::isCameraFocused() const {
return runtimeContext != nullptr && runtimeContext->isEditorCameraFocused();
}

bool ViewportPanel::focusRuntimeObjects(const QList<int> &ids) {
if (runtimeContext == nullptr || ids.isEmpty())
return false;
Expand Down
34 changes: 31 additions & 3 deletions editor/views/editor/viewportTools.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,19 @@ ViewportTools::ViewportTools(ViewportPanel *viewport,
spaceButton->setToolTip("World transform space · Shift+T");
tools->addWidget(spaceButton);

cameraButton = new QToolButton(toolbar);
cameraButton->setObjectName("viewportOptionButton");
cameraButton->setIcon(styling::icon(styling::Icon::Camera, "#9E897D"));
cameraButton->setCheckable(true);
cameraButton->setToolTip("Look through Main Camera · Numpad 0");
tools->addWidget(cameraButton);

tools->addStretch();

cameraLabel = new QLabel("MAIN CAMERA", toolbar);
cameraLabel->setObjectName("viewportFpsLabel");
cameraLabel->setVisible(false);
tools->addWidget(cameraLabel);
tools->addWidget(playButton);
tools->addWidget(pauseButton);
tools->addWidget(stepButton);
Expand Down Expand Up @@ -147,9 +159,10 @@ ViewportTools::ViewportTools(ViewportPanel *viewport,

layout->addWidget(toolbar);
layout->addWidget(viewport, 1);
shortcutHint = new QLabel(
"Tab Frame · Right-Drag Pan · Middle-Drag Orbit · G Move · R Rotate · S Scale · X Delete",
this);
shortcutHint =
new QLabel("Tab Frame · Num 0 Camera · Right-Drag Pan · Middle-Drag "
"Orbit · G Move · R Rotate · S Scale · X Delete",
this);
shortcutHint->setObjectName("viewportShortcutHint");
shortcutHint->setTextInteractionFlags(Qt::NoTextInteraction);
layout->addWidget(shortcutHint);
Expand All @@ -174,6 +187,21 @@ ViewportTools::ViewportTools(ViewportPanel *viewport,
});
connect(spaceButton, &QToolButton::clicked, viewport,
&ViewportPanel::toggleTransformSpace);
connect(cameraButton, &QToolButton::clicked, viewport,
&ViewportPanel::toggleCameraFocus);
connect(viewport, &ViewportPanel::cameraFocusChanged, this,
[this](bool focused) {
const QSignalBlocker blocker(cameraButton);
cameraButton->setChecked(focused);
cameraButton->setIcon(styling::icon(
styling::Icon::Camera,
focused ? QColor("#5CC8FF") : QColor("#9E897D")));
cameraButton->setToolTip(
focused
? "Main Camera view active · Esc or Numpad 0 to exit"
: "Look through Main Camera · Numpad 0");
cameraLabel->setVisible(focused);
});
connect(viewport, &ViewportPanel::transformSpaceChanged, this,
[this](bool local) {
spaceButton->setIcon(styling::icon(
Expand Down
4 changes: 4 additions & 0 deletions include/atlas/runtime/context.h
Original file line number Diff line number Diff line change
Expand Up @@ -71,13 +71,15 @@ class Context {
std::string scriptBundleModuleName = "__atlas_scripts__";

std::unique_ptr<Camera> camera;
std::unique_ptr<Camera> editorViewCamera;
std::map<std::string, std::unique_ptr<RenderTarget>> renderTargets;
std::vector<std::unique_ptr<DirectionalLight>> directionalLights;
std::vector<std::unique_ptr<Light>> pointLights;
std::vector<std::unique_ptr<Spotlight>> spotlights;
std::vector<std::unique_ptr<AreaLight>> areaLights;
std::vector<std::string> cameraActions;
bool cameraAutomaticMoving = false;
bool editorCameraFocused = false;
bool editorRuntime = false;

std::unique_ptr<Window> window;
Expand Down Expand Up @@ -115,6 +117,8 @@ class Context {
bool resize(int width, int height, float scale);
bool setEditorControlsEnabled(bool enabled);
bool setEditorSimulationEnabled(bool enabled);
bool setEditorCameraFocused(bool focused);
bool isEditorCameraFocused() const { return editorCameraFocused; }
bool setEditorControlMode(int mode);
bool setEditorShadingMode(int mode);
float frameRate() const;
Expand Down
6 changes: 6 additions & 0 deletions include/atlas/window.h
Original file line number Diff line number Diff line change
Expand Up @@ -440,6 +440,8 @@ class Window {
void resize(int width, int height, float scale = 1.0f);
void setEditorControlsEnabled(bool enabled);
bool areEditorControlsEnabled() const { return editorControlsEnabled; }
void setEditorSceneCamera(Camera *sceneCamera);
void setEditorCameraFocused(bool focused);
void setEditorSimulationEnabled(bool enabled);
bool isEditorSimulationEnabled() const { return editorSimulationEnabled; }
void setEditorControlMode(EditorControlMode mode);
Expand Down Expand Up @@ -1033,9 +1035,13 @@ class Window {
std::unique_ptr<CoreObject> editorGridObject;
std::unique_ptr<CoreObject> editorOutlineObject;
std::unique_ptr<CoreObject> editorGizmoObject;
std::unique_ptr<CoreObject> editorCameraFrustumObject;
bool editorGridInitialized = false;
bool editorOutlineInitialized = false;
bool editorGizmoInitialized = false;
bool editorCameraFrustumInitialized = false;
bool editorCameraFocused = false;
Camera *editorSceneCamera = nullptr;
std::array<bool, 6> editorCameraKeys{};
std::unordered_map<GameObject *, GameObject *> editorObjectParents;
std::unordered_map<GameObject *, std::vector<GameObject *>>
Expand Down
Loading
Loading