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
60 changes: 33 additions & 27 deletions atlas/application/window.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1462,11 +1462,6 @@ bool Window::stepFrame() {
this->uiRenderables.erase(std::remove(this->uiRenderables.begin(),
this->uiRenderables.end(), obj),
this->uiRenderables.end());
if (auto *fluid = dynamic_cast<Fluid *>(obj)) {
this->lateFluids.erase(std::remove(this->lateFluids.begin(),
this->lateFluids.end(), fluid),
this->lateFluids.end());
}
}
this->pendingRemovals.clear();

Expand Down Expand Up @@ -3122,32 +3117,43 @@ void Window::removeObject(Renderable *obj) {
editorActiveGizmoAxis = 0;
}

if (this->physicsWorld != nullptr) {
this->pendingRemovals.push_back(obj);
const auto pendingObject =
std::find(this->pendingObjects.begin(), this->pendingObjects.end(), obj);
const bool wasPending = pendingObject != this->pendingObjects.end();
if (wasPending) {
this->pendingObjects.erase(pendingObject);
}

this->lateForwardRenderables.erase(
std::remove(this->lateForwardRenderables.begin(),
this->lateForwardRenderables.end(), obj),
this->lateForwardRenderables.end());
this->preferenceRenderables.erase(
std::remove(this->preferenceRenderables.begin(),
this->preferenceRenderables.end(), obj),
this->preferenceRenderables.end());
this->firstRenderables.erase(std::remove(this->firstRenderables.begin(),
this->firstRenderables.end(), obj),
this->firstRenderables.end());
this->uiRenderables.erase(std::remove(this->uiRenderables.begin(),
this->uiRenderables.end(), obj),
this->uiRenderables.end());
if (auto *fluid = dynamic_cast<Fluid *>(obj)) {
this->lateFluids.erase(std::remove(this->lateFluids.begin(),
this->lateFluids.end(), fluid),
this->lateFluids.end());
}

if (this->physicsWorld != nullptr && !wasPending) {
if (std::find(this->pendingRemovals.begin(),
this->pendingRemovals.end(), obj) ==
this->pendingRemovals.end()) {
this->pendingRemovals.push_back(obj);
}
} else {
this->renderables.erase(std::remove(this->renderables.begin(),
this->renderables.end(), obj),
this->renderables.end());
this->lateForwardRenderables.erase(
std::remove(this->lateForwardRenderables.begin(),
this->lateForwardRenderables.end(), obj),
this->lateForwardRenderables.end());
this->preferenceRenderables.erase(
std::remove(this->preferenceRenderables.begin(),
this->preferenceRenderables.end(), obj),
this->preferenceRenderables.end());
this->firstRenderables.erase(std::remove(this->firstRenderables.begin(),
this->firstRenderables.end(),
obj),
this->firstRenderables.end());
this->uiRenderables.erase(std::remove(this->uiRenderables.begin(),
this->uiRenderables.end(), obj),
this->uiRenderables.end());
if (auto *fluid = dynamic_cast<Fluid *>(obj)) {
this->lateFluids.erase(std::remove(this->lateFluids.begin(),
this->lateFluids.end(), fluid),
this->lateFluids.end());
}
}
this->shadowMapsDirty = true;
this->shadowUpdateCooldown = 0.0f;
Expand Down
7 changes: 5 additions & 2 deletions editor/core/dockManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,18 @@ ads::DockWidgetArea EditorDockManager::toAdsArea(EditorDockArea area) const {
ads::CDockWidget* EditorDockManager::addPanel(const EditorDockPanelDesc& desc) {
auto* dock = new ads::CDockWidget(desc.title);
dock->setWidget(desc.widget);
dock->setFeature(ads::CDockWidget::DockWidgetMovable, true);
dock->setFeature(ads::CDockWidget::DockWidgetFloatable, true);

if (!desc.icon.isNull()) {
dock->setIcon(desc.icon);
}

if (desc.area == EditorDockArea::Center) {
centerArea = dockManager->setCentralWidget(dock);
centerArea = dockManager->addDockWidget(ads::CenterDockWidgetArea,
dock);
if (centerArea != nullptr) {
centerArea->setAllowedAreas(ads::OuterDockAreas);
centerArea->setAllowedAreas(ads::AllDockAreas);
}
} else if (centerArea) {
dockManager->addDockWidget(toAdsArea(desc.area), dock, centerArea);
Expand Down
57 changes: 45 additions & 12 deletions editor/views/editor/editor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

#include <QAction>
#include <QList>
#include <QKeySequence>
#include <QMenuBar>
#include <QStyle>
#include <QSettings>
Expand Down Expand Up @@ -56,7 +57,7 @@ void EditorWindow::setupWindow() {
ads::CDockManager::setConfigFlag(
ads::CDockManager::DockAreaHasTabsMenuButton, false);
ads::CDockManager::setConfigFlag(ads::CDockManager::DockAreaHasUndockButton,
false);
true);
ads::CDockManager::setConfigFlag(ads::CDockManager::DockAreaHasCloseButton,
false);

Expand All @@ -72,7 +73,14 @@ void EditorWindow::setupMenus() {
"Open");
auto *saveAction = fileMenu->addAction(
style()->standardIcon(QStyle::SP_DialogSaveButton), "Save Scene");
saveAction->setShortcut(QKeySequence::Save);
saveAction->setShortcutContext(Qt::ApplicationShortcut);
connect(saveAction, &QAction::triggered, this, [this] {
if (materialEditorPanel != nullptr &&
materialEditorPanel->isVisible()) {
materialEditorPanel->saveMaterial();
return;
}
if (viewportPanel != nullptr) {
viewportPanel->saveRuntimeScene();
}
Expand All @@ -82,8 +90,30 @@ void EditorWindow::setupMenus() {
"Quit", this, &QWidget::close);

auto *editMenu = menuBar()->addMenu("Edit");
editMenu->addAction(style()->standardIcon(QStyle::SP_ArrowBack), "Undo");
editMenu->addAction(style()->standardIcon(QStyle::SP_ArrowForward), "Redo");
auto *undoAction = editMenu->addAction(
style()->standardIcon(QStyle::SP_ArrowBack), "Undo");
undoAction->setShortcut(QKeySequence::Undo);
undoAction->setShortcutContext(Qt::ApplicationShortcut);
connect(undoAction, &QAction::triggered, this, [this] {
if (materialEditorPanel != nullptr &&
materialEditorPanel->isVisible()) {
materialEditorPanel->undo();
} else if (viewportPanel != nullptr) {
viewportPanel->undo();
}
});
auto *redoAction = editMenu->addAction(
style()->standardIcon(QStyle::SP_ArrowForward), "Redo");
redoAction->setShortcut(QKeySequence::Redo);
redoAction->setShortcutContext(Qt::ApplicationShortcut);
connect(redoAction, &QAction::triggered, this, [this] {
if (materialEditorPanel != nullptr &&
materialEditorPanel->isVisible()) {
materialEditorPanel->redo();
} else if (viewportPanel != nullptr) {
viewportPanel->redo();
}
});
editMenu->addSeparator();
editMenu->addAction("Preferences");

Expand All @@ -106,7 +136,7 @@ void EditorWindow::setupMenus() {
void EditorWindow::setupDocks() {
viewportPanel = new ViewportPanel(projectFile);
auto *viewportTools = new ViewportTools(viewportPanel);
dockManager->addPanel(
auto *viewportDock = dockManager->addPanel(
{.id = "viewport",
.title = "Viewport",
.widget = viewportTools,
Expand All @@ -121,7 +151,7 @@ void EditorWindow::setupDocks() {
.area = EditorDockArea::Left,
.icon = style()->standardIcon(QStyle::SP_DirOpenIcon)});

inspectorPanel = new InspectorPanel(viewportPanel);
inspectorPanel = new InspectorPanel(viewportPanel, projectFile);
dockManager->addPanel(
{.id = "inspector",
.title = "Inspector",
Expand All @@ -137,13 +167,16 @@ void EditorWindow::setupDocks() {
.area = EditorDockArea::Bottom,
.icon = style()->standardIcon(QStyle::SP_DirOpenIcon)});

auto *materialEditor = new MaterialEditorPanel(viewportPanel);
materialEditorPanel = new MaterialEditorPanel(viewportPanel);
auto *materialDock = dockManager->addPanel(
{.id = "materialEditor",
.title = "Material Editor",
.widget = materialEditor,
.widget = materialEditorPanel,
.area = EditorDockArea::Right,
.icon = style()->standardIcon(QStyle::SP_FileDialogContentsView)});
coreManager->addDockWidgetTabToArea(materialDock,
viewportDock->dockAreaWidget());
viewportDock->setAsCurrentTab();

connect(hierarchyPanel, &HierarchyPanel::objectActivated, inspectorPanel,
&InspectorPanel::inspectRuntimeObject);
Expand All @@ -163,8 +196,8 @@ void EditorWindow::setupDocks() {
this->inspectorPanel->inspectFile(path);
});
connect(contentBrowser, &ContentBrowserPanel::assetActivated, this,
[materialEditor, materialDock](const QString &path) {
materialEditor->openMaterial(path);
[this, materialDock](const QString &path) {
materialEditorPanel->openMaterial(path);
materialDock->toggleView(true);
materialDock->raise();
});
Expand All @@ -175,7 +208,7 @@ void EditorWindow::saveLayout() {

settings.setValue("window/geometry", saveGeometry());
settings.setValue("window/state", saveState());
settings.setValue("docking/state/v2", coreManager->saveState(2));
settings.setValue("docking/state/v4", coreManager->saveState(4));
if (inspectorPanel != nullptr) {
settings.setValue("panels/inspector/width", inspectorPanel->width());
}
Expand All @@ -199,10 +232,10 @@ void EditorWindow::restoreLayout() {
restoreState(settings.value("window/state").toByteArray());

const QByteArray dockState =
settings.value("docking/state/v2").toByteArray();
settings.value("docking/state/v4").toByteArray();

if (!dockState.isEmpty()) {
coreManager->restoreState(dockState, 2);
coreManager->restoreState(dockState, 4);
}

const int inspectorWidth =
Expand Down
84 changes: 83 additions & 1 deletion editor/views/editor/hierarchy.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@

#include <QAction>
#include <QAbstractItemView>
#include <QDropEvent>
#include <QFileInfo>
#include <QIcon>
#include <QInputDialog>
#include <QItemSelectionModel>
Expand All @@ -22,6 +24,7 @@
#include <QList>
#include <QMenu>
#include <QMessageBox>
#include <QMimeData>
#include <QPair>
#include <QSignalBlocker>
#include <QStandardItem>
Expand Down Expand Up @@ -128,6 +131,10 @@ HierarchyPanel::HierarchyPanel(ViewportPanel *viewport, QWidget *parent)
treeView->setSelectionMode(QAbstractItemView::SingleSelection);
treeView->setContextMenuPolicy(Qt::CustomContextMenu);
treeView->setUniformRowHeights(true);
treeView->setAcceptDrops(true);
treeView->setDragDropMode(QAbstractItemView::DropOnly);
treeView->viewport()->setAcceptDrops(true);
treeView->viewport()->installEventFilter(this);
layout->addWidget(treeView);

auto *addMenu = new QMenu(addButton);
Expand Down Expand Up @@ -256,7 +263,46 @@ void HierarchyPanel::rebuildScene(const QString &sceneName,
root->setData(-1, ObjectIdRole);
root->setData("scene", ObjectTypeRole);
root->setEditable(false);
appendObjects(root, objects);
QJsonArray regularObjects;
QJsonArray cameraObjects;
QJsonArray lightObjects;
for (const QJsonValue &value : objects) {
const QString type = value.toObject().value("type").toString().toLower();
if (type.contains("light") || type == "sun") {
lightObjects.append(value);
} else if (type.contains("camera")) {
cameraObjects.append(value);
} else {
regularObjects.append(value);
}
}
appendObjects(root, regularObjects);

auto *cameras =
new QStandardItem(hierarchyIcon(this, "camera"), "Cameras");
cameras->setData(-1, ObjectIdRole);
cameras->setEditable(false);
cameras->setSelectable(false);
auto *mainCamera =
new QStandardItem(hierarchyIcon(this, "camera"), "Main Camera");
mainCamera->setData(-1, ObjectIdRole);
mainCamera->setData("camera", ObjectTypeRole);
mainCamera->setToolTip("Scene camera");
mainCamera->setEditable(false);
mainCamera->setSelectable(false);
cameras->appendRow(mainCamera);
appendObjects(cameras, cameraObjects);
root->appendRow(cameras);

if (!lightObjects.isEmpty()) {
auto *lights =
new QStandardItem(hierarchyIcon(this, "light"), "Lights");
lights->setData(-1, ObjectIdRole);
lights->setEditable(false);
lights->setSelectable(false);
appendObjects(lights, lightObjects);
root->appendRow(lights);
}
model->appendRow(root);
treeView->expandAll();

Expand All @@ -268,6 +314,42 @@ void HierarchyPanel::rebuildScene(const QString &sceneName,
applyingSnapshot = false;
}

bool HierarchyPanel::eventFilter(QObject *watched, QEvent *event) {
if (treeView != nullptr && watched == treeView->viewport() &&
(event->type() == QEvent::DragEnter ||
event->type() == QEvent::DragMove || event->type() == QEvent::Drop)) {
auto *drop = static_cast<QDropEvent *>(event);
const QModelIndex index = treeView->indexAt(drop->position().toPoint());
const int objectId = index.data(ObjectIdRole).toInt();
if (drop->mimeData()->hasUrls() && objectId >= 0) {
const QString suffix =
QFileInfo(drop->mimeData()->urls().constFirst().toLocalFile())
.suffix()
.toLower();
const bool supported = suffix == "amat" || suffix == "material" ||
suffix == "ts" || suffix == "js";
if (supported && event->type() == QEvent::Drop &&
viewport != nullptr &&
viewport->attachRuntimeAsset(
objectId,
drop->mimeData()->urls().constFirst().toLocalFile())) {
treeView->setCurrentIndex(index);
viewport->selectRuntimeObject(objectId, false);
emit objectActivated(objectId);
drop->acceptProposedAction();
return true;
}
if (supported && event->type() != QEvent::Drop) {
drop->acceptProposedAction();
return true;
}
}
drop->ignore();
return true;
}
return QWidget::eventFilter(watched, event);
}

void HierarchyPanel::appendObjects(QStandardItem *parent,
const QJsonArray &objects) {
for (const QJsonValue &value : objects) {
Expand Down
Loading
Loading