Compare commits
33 Commits
f5de113c9a
...
0ef62ebfa5
Author | SHA1 | Date |
---|---|---|
Shaun Reed | 0ef62ebfa5 | |
Shaun Reed | 2476d125f7 | |
Shaun Reed | 5118726cde | |
Shaun Reed | b3f9e3230e | |
Shaun Reed | 5015c5c3a4 | |
Shaun Reed | 2087f10681 | |
Shaun Reed | e6b197d6fa | |
Shaun Reed | 6a52eee501 | |
Shaun Reed | 6d51aef9cf | |
Shaun Reed | 5bde82d956 | |
Shaun Reed | ae5abb9939 | |
Shaun Reed | d9c59a04ec | |
Shaun Reed | e6bcd131b7 | |
Shaun Reed | 0659df94bd | |
Shaun Reed | 0dcb6d337b | |
Shaun Reed | 002bedd7ef | |
Shaun Reed | 6ce71dda86 | |
Shaun Reed | b3484ced03 | |
Shaun Reed | 5e886672da | |
Shaun Reed | 126cd438e1 | |
Shaun Reed | 39fa8e8cdc | |
Shaun Reed | 48719412f2 | |
Shaun Reed | aa32cbcc17 | |
Shaun Reed | cfefc49c53 | |
Shaun Reed | 195a4ef30d | |
Shaun Reed | 55dd8e5c3c | |
Shaun Reed | cf433ad7fc | |
Shaun Reed | 4bc0ae22c6 | |
Shaun Reed | faa9fe28f7 | |
Shaun Reed | f83f68207d | |
Shaun Reed | 85c9e2eac1 | |
Shaun Reed | 194888ed19 | |
Shaun Reed | c948d9e1a6 |
|
@ -118,7 +118,7 @@ jobs:
|
||||||
- name: Upload Qtk install directory
|
- name: Upload Qtk install directory
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: qtk-gui-${{ matrix.os }}-installdir
|
name: qtk-gui-${{ matrix.os }}-install
|
||||||
path: install/*
|
path: install/*
|
||||||
|
|
||||||
# TODO: Enable after trimming resources.
|
# TODO: Enable after trimming resources.
|
||||||
|
@ -238,7 +238,7 @@ jobs:
|
||||||
uses: actions/upload-artifact@v3
|
uses: actions/upload-artifact@v3
|
||||||
if: always()
|
if: always()
|
||||||
with:
|
with:
|
||||||
name: libqtk-${{ matrix.os }}-installdir
|
name: libqtk-${{ matrix.os }}-install
|
||||||
path: install/*
|
path: install/*
|
||||||
|
|
||||||
Qtk-Plugins:
|
Qtk-Plugins:
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
# CLion
|
# CLion
|
||||||
**/.idea/**
|
**/.idea/**
|
||||||
|
|
||||||
|
# VS Code
|
||||||
|
**/.vscode/**
|
||||||
|
|
||||||
# CMake build files
|
# CMake build files
|
||||||
**/cmake-build-debug/**
|
**/cmake-build-debug/**
|
||||||
**/build/**
|
**/build/**
|
||||||
|
|
|
@ -67,7 +67,7 @@ option(
|
||||||
OFF
|
OFF
|
||||||
)
|
)
|
||||||
|
|
||||||
if(QTK_DEBUG OR CMAKE_BUILD_TYPE MATCHES "[Dd][Ee][Bb][Uu][Gg]")
|
if(QTK_DEBUG OR CMAKE_BUILD_TYPE MATCHES "^[Dd][Ee][Bb][Uu][Gg]$")
|
||||||
set(QTK_DEBUG ON)
|
set(QTK_DEBUG ON)
|
||||||
set(CMAKE_BUILD_TYPE Debug)
|
set(CMAKE_BUILD_TYPE Debug)
|
||||||
else()
|
else()
|
||||||
|
@ -96,6 +96,21 @@ list(SORT VAR_NAMES)
|
||||||
# If Qtk is built within Qt Creator this is not required.
|
# If Qtk is built within Qt Creator this is not required.
|
||||||
list(APPEND CMAKE_PREFIX_PATH "${QT_INSTALL_DIR}")
|
list(APPEND CMAKE_PREFIX_PATH "${QT_INSTALL_DIR}")
|
||||||
|
|
||||||
|
set(
|
||||||
|
QT_CREATOR_DIR
|
||||||
|
"${QT_INSTALL_DIR}/../../Tools/QtCreator"
|
||||||
|
CACHE PATH "Qt Creator path used to install Qtk plugins for Qt Designer."
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
# Print all QTK options and their values.
|
||||||
|
get_cmake_property(VAR_NAMES VARIABLES)
|
||||||
|
list(FILTER VAR_NAMES INCLUDE REGEX "^Q[tT][kK]_.*$")
|
||||||
|
list(SORT VAR_NAMES)
|
||||||
|
|
||||||
|
################################################################################
|
||||||
|
# External Dependencies
|
||||||
|
################################################################################
|
||||||
# Find Qt
|
# Find Qt
|
||||||
find_package(Qt6 COMPONENTS Core UiPlugin OpenGLWidgets)
|
find_package(Qt6 COMPONENTS Core UiPlugin OpenGLWidgets)
|
||||||
qt_standard_project_setup()
|
qt_standard_project_setup()
|
||||||
|
@ -111,12 +126,6 @@ if(NOT Qt6_FOUND)
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# TODO: This might be a bit strange and needs more testing.
|
|
||||||
if (QTK_PREFIX_QTCREATOR)
|
|
||||||
set(CMAKE_INSTALL_PREFIX "${QT_INSTALL_DIR}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# To use custom plugins, set QT_PLUGIN_PATH environment variable before running designer
|
# To use custom plugins, set QT_PLUGIN_PATH environment variable before running designer
|
||||||
# Or, we can install plugins to the designer for use across all projects.
|
# Or, we can install plugins to the designer for use across all projects.
|
||||||
|
@ -137,8 +146,9 @@ set(
|
||||||
set(
|
set(
|
||||||
VAR_PATHS
|
VAR_PATHS
|
||||||
CMAKE_PREFIX_PATH CMAKE_INSTALL_PREFIX QTK_PLUGIN_INSTALL_DIR QT6_INSTALL_PREFIX
|
CMAKE_PREFIX_PATH CMAKE_INSTALL_PREFIX QTK_PLUGIN_INSTALL_DIR QT6_INSTALL_PREFIX
|
||||||
QT_INSTALL_DIR QT6_INSTALL_PLUGINS
|
QT_INSTALL_DIR
|
||||||
)
|
)
|
||||||
|
list(APPEND VAR_NAMES QT6_INSTALL_PLUGINS)
|
||||||
|
|
||||||
# Find Assimp.
|
# Find Assimp.
|
||||||
if(QTK_SUBMODULES)
|
if(QTK_SUBMODULES)
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit eb328ce69dd7b06977aed125e967a41e835b8431
|
Subproject commit 5d5496f1ad895297cede723b3c96b513263f82ed
|
|
@ -32,7 +32,7 @@ install(
|
||||||
FILE_SET HEADERS DESTINATION include
|
FILE_SET HEADERS DESTINATION include
|
||||||
INCLUDES DESTINATION include
|
INCLUDES DESTINATION include
|
||||||
LIBRARY DESTINATION lib
|
LIBRARY DESTINATION lib
|
||||||
ARCHIVE DESTINATION lib/static
|
ARCHIVE DESTINATION lib
|
||||||
RUNTIME DESTINATION bin
|
RUNTIME DESTINATION bin
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -57,7 +57,7 @@ if(QTK_GUI)
|
||||||
COMPONENT qtk_gui
|
COMPONENT qtk_gui
|
||||||
BUNDLE DESTINATION .
|
BUNDLE DESTINATION .
|
||||||
LIBRARY DESTINATION lib
|
LIBRARY DESTINATION lib
|
||||||
ARCHIVE DESTINATION lib/static
|
ARCHIVE DESTINATION lib
|
||||||
RUNTIME DESTINATION bin
|
RUNTIME DESTINATION bin
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -29,17 +29,25 @@ MainWindow::MainWindow(QWidget * parent) : QMainWindow(parent) {
|
||||||
for(auto & qtkWidget : qtkWidgets) {
|
for(auto & qtkWidget : qtkWidgets) {
|
||||||
qtkWidget->setScene(new Qtk::SceneEmpty);
|
qtkWidget->setScene(new Qtk::SceneEmpty);
|
||||||
views_.emplace(qtkWidget->getScene()->getSceneName(), qtkWidget);
|
views_.emplace(qtkWidget->getScene()->getSceneName(), qtkWidget);
|
||||||
|
|
||||||
|
// Add GUI 'view' toolbar option to show debug console.
|
||||||
ui_->menuView->addAction(qtkWidget->getActionToggleConsole());
|
ui_->menuView->addAction(qtkWidget->getActionToggleConsole());
|
||||||
|
// Refresh GUI widgets when scene or objects are updated.
|
||||||
connect(
|
connect(
|
||||||
qtkWidget->getScene(), &Qtk::Scene::sceneUpdated, this,
|
qtkWidget->getScene(), &Qtk::Scene::sceneUpdated, this,
|
||||||
&MainWindow::refreshScene);
|
&MainWindow::refreshScene);
|
||||||
|
connect(
|
||||||
|
qtkWidget, &Qtk::QtkWidget::objectFocusChanged, ui_->qtk__ToolBox,
|
||||||
|
&Qtk::ToolBox::updateFocus);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto docks = findChildren<QDockWidget *>();
|
// Dock the toolbox widget to the main window.
|
||||||
for(auto & dock : docks) {
|
addDockWidget(Qt::LeftDockWidgetArea, ui_->qtk__ToolBox);
|
||||||
addDockWidget(Qt::RightDockWidgetArea, dock);
|
// Add an option to toggle active widgets in the GUI's toolbar 'view' menu.
|
||||||
ui_->menuView->addAction(dock->toggleViewAction());
|
ui_->menuView->addAction(ui_->qtk__ToolBox->toggleViewAction());
|
||||||
}
|
|
||||||
|
addDockWidget(Qt::RightDockWidgetArea, ui_->qtk__TreeView);
|
||||||
|
ui_->menuView->addAction(ui_->qtk__TreeView->toggleViewAction());
|
||||||
|
|
||||||
// Set the window icon used for Qtk.
|
// Set the window icon used for Qtk.
|
||||||
setWindowIcon(Qtk::getIcon());
|
setWindowIcon(Qtk::getIcon());
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>824</width>
|
<width>1034</width>
|
||||||
<height>601</height>
|
<height>601</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
@ -28,11 +28,27 @@
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="centralwidget">
|
<widget class="QWidget" name="centralwidget">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||||
|
<item>
|
||||||
|
<widget class="Qtk::ToolBox" name="qtk::ToolBox">
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>1</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="toolTip">
|
||||||
|
<string>A custom widget tool tip.</string>
|
||||||
|
</property>
|
||||||
|
<property name="whatsThis">
|
||||||
|
<string>Custom widget what's this?</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QTabWidget" name="tabWidget">
|
<widget class="QTabWidget" name="tabWidget">
|
||||||
<property name="sizePolicy">
|
<property name="sizePolicy">
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
||||||
<horstretch>0</horstretch>
|
<horstretch>3</horstretch>
|
||||||
<verstretch>0</verstretch>
|
<verstretch>0</verstretch>
|
||||||
</sizepolicy>
|
</sizepolicy>
|
||||||
</property>
|
</property>
|
||||||
|
@ -67,28 +83,20 @@
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
<widget class="Qtk::TreeView" name="qtk::TreeView">
|
||||||
<item>
|
<property name="sizePolicy">
|
||||||
<widget class="Qtk::TreeView" name="qtk::TreeView">
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
<property name="toolTip">
|
<horstretch>1</horstretch>
|
||||||
<string>A custom widget tool tip.</string>
|
<verstretch>0</verstretch>
|
||||||
</property>
|
</sizepolicy>
|
||||||
<property name="whatsThis">
|
</property>
|
||||||
<string>Custom widget what's this?</string>
|
<property name="toolTip">
|
||||||
</property>
|
<string>A custom widget tool tip.</string>
|
||||||
</widget>
|
</property>
|
||||||
</item>
|
<property name="whatsThis">
|
||||||
<item>
|
<string>Custom widget what's this?</string>
|
||||||
<widget class="Qtk::ToolBox" name="qtk::ToolBox">
|
</property>
|
||||||
<property name="toolTip">
|
</widget>
|
||||||
<string>A custom widget tool tip.</string>
|
|
||||||
</property>
|
|
||||||
<property name="whatsThis">
|
|
||||||
<string>Custom widget what's this?</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -97,7 +105,7 @@
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>0</y>
|
||||||
<width>824</width>
|
<width>1034</width>
|
||||||
<height>22</height>
|
<height>22</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
@ -179,7 +187,7 @@
|
||||||
</widget>
|
</widget>
|
||||||
<action name="actionOpen">
|
<action name="actionOpen">
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../../resources/resources.qrc">
|
<iconset>
|
||||||
<normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/regular/folder-open.svg</normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/regular/folder-open.svg</iconset>
|
<normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/regular/folder-open.svg</normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/regular/folder-open.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
@ -188,7 +196,7 @@
|
||||||
</action>
|
</action>
|
||||||
<action name="actionSave">
|
<action name="actionSave">
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../../resources/resources.qrc">
|
<iconset>
|
||||||
<normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/regular/floppy-disk.svg</normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/regular/floppy-disk.svg</iconset>
|
<normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/regular/floppy-disk.svg</normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/regular/floppy-disk.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
@ -215,7 +223,7 @@
|
||||||
</action>
|
</action>
|
||||||
<action name="actionLoad_Model">
|
<action name="actionLoad_Model">
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../../resources/resources.qrc">
|
<iconset>
|
||||||
<normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/solid/cube.svg</normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/solid/cube.svg</iconset>
|
<normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/solid/cube.svg</normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/solid/cube.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
@ -227,7 +235,7 @@
|
||||||
</action>
|
</action>
|
||||||
<action name="actionDelete_Object">
|
<action name="actionDelete_Object">
|
||||||
<property name="icon">
|
<property name="icon">
|
||||||
<iconset resource="../../resources/resources.qrc">
|
<iconset>
|
||||||
<normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/regular/trash-can.svg</normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/regular/trash-can.svg</iconset>
|
<normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/regular/trash-can.svg</normaloff>:/icons/fontawesome-free-6.2.1-desktop/svgs/regular/trash-can.svg</iconset>
|
||||||
</property>
|
</property>
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
@ -318,9 +326,7 @@
|
||||||
<container>1</container>
|
<container>1</container>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources>
|
<resources/>
|
||||||
<include location="../../resources/resources.qrc"/>
|
|
||||||
</resources>
|
|
||||||
<connections>
|
<connections>
|
||||||
<connection>
|
<connection>
|
||||||
<sender>actionExit</sender>
|
<sender>actionExit</sender>
|
||||||
|
|
|
@ -38,11 +38,12 @@ void QtkScene::init() {
|
||||||
/* Create a red cube with a mini master chief on top. */
|
/* Create a red cube with a mini master chief on top. */
|
||||||
auto myCube = new MeshRenderer("My cube", Cube(Qtk::QTK_DRAW_ELEMENTS));
|
auto myCube = new MeshRenderer("My cube", Cube(Qtk::QTK_DRAW_ELEMENTS));
|
||||||
myCube->setColor(RED);
|
myCube->setColor(RED);
|
||||||
|
myCube->getTransform().setTranslation(5.0f, 0.0f, 0.0f);
|
||||||
addObject(myCube);
|
addObject(myCube);
|
||||||
|
|
||||||
auto mySpartan =
|
auto mySpartan =
|
||||||
new Model("My spartan", ":/models/models/spartan/spartan.obj");
|
new Model("My spartan", ":/models/models/spartan/spartan.obj");
|
||||||
mySpartan->getTransform().setTranslation(0.0f, 0.5f, 0.0f);
|
mySpartan->getTransform().setTranslation(5.0f, 0.5f, 0.0f);
|
||||||
mySpartan->getTransform().setScale(0.5f);
|
mySpartan->getTransform().setScale(0.5f);
|
||||||
addObject(mySpartan);
|
addObject(mySpartan);
|
||||||
|
|
||||||
|
|
|
@ -7,6 +7,12 @@
|
||||||
##############################################################################*/
|
##############################################################################*/
|
||||||
|
|
||||||
#include <QKeyEvent>
|
#include <QKeyEvent>
|
||||||
|
#include <QMimeData>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
|
#include <qtk/input.h>
|
||||||
|
#include <qtk/scene.h>
|
||||||
|
#include <qtk/shape.h>
|
||||||
#include <QVBoxLayout>
|
#include <QVBoxLayout>
|
||||||
|
|
||||||
#include <qtk/input.h>
|
#include <qtk/input.h>
|
||||||
|
@ -31,6 +37,7 @@ QtkWidget::QtkWidget(QWidget * parent, const QString & name) :
|
||||||
QtkWidget::QtkWidget(QWidget * parent, const QString & name, Scene * scene) :
|
QtkWidget::QtkWidget(QWidget * parent, const QString & name, Scene * scene) :
|
||||||
QOpenGLWidget(parent), mDebugLogger(Q_NULLPTR),
|
QOpenGLWidget(parent), mDebugLogger(Q_NULLPTR),
|
||||||
mConsole(new DebugConsole(this, name)), mScene(Q_NULLPTR) {
|
mConsole(new DebugConsole(this, name)), mScene(Q_NULLPTR) {
|
||||||
|
setAcceptDrops(true);
|
||||||
setScene(scene);
|
setScene(scene);
|
||||||
setObjectName(name);
|
setObjectName(name);
|
||||||
QSurfaceFormat format;
|
QSurfaceFormat format;
|
||||||
|
@ -77,6 +84,9 @@ void QtkWidget::initializeGL() {
|
||||||
connect(
|
connect(
|
||||||
mDebugLogger, SIGNAL(messageLogged(QOpenGLDebugMessage)), this,
|
mDebugLogger, SIGNAL(messageLogged(QOpenGLDebugMessage)), this,
|
||||||
SLOT(messageLogged(QOpenGLDebugMessage)));
|
SLOT(messageLogged(QOpenGLDebugMessage)));
|
||||||
|
// connect(
|
||||||
|
// mDebugLogger, SIGNAL(messageLogged(QOpenGLDebugMessage)),
|
||||||
|
// mConsole, SLOT(sendLog(QOpenGLDebugMessage)));
|
||||||
mDebugLogger->startLogging();
|
mDebugLogger->startLogging();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -107,11 +117,11 @@ void QtkWidget::paintGL() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void QtkWidget::setScene(Qtk::Scene * scene) {
|
void QtkWidget::setScene(Scene * scene) {
|
||||||
if(mScene != Q_NULLPTR) {
|
if(mScene != Q_NULLPTR) {
|
||||||
delete mScene;
|
delete mScene;
|
||||||
connect(
|
connect(
|
||||||
scene, &Qtk::Scene::sceneUpdated, MainWindow::getMainWindow(),
|
scene, &Scene::sceneUpdated, MainWindow::getMainWindow(),
|
||||||
&MainWindow::refreshScene);
|
&MainWindow::refreshScene);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -129,8 +139,7 @@ void QtkWidget::toggleConsole() {
|
||||||
mConsoleActive = false;
|
mConsoleActive = false;
|
||||||
} else {
|
} else {
|
||||||
MainWindow::getMainWindow()->addDockWidget(
|
MainWindow::getMainWindow()->addDockWidget(
|
||||||
Qt::DockWidgetArea::BottomDockWidgetArea,
|
Qt::DockWidgetArea::BottomDockWidgetArea, mConsole);
|
||||||
dynamic_cast<QDockWidget *>(mConsole));
|
|
||||||
mConsole->setHidden(false);
|
mConsole->setHidden(false);
|
||||||
mConsoleActive = true;
|
mConsoleActive = true;
|
||||||
}
|
}
|
||||||
|
@ -140,6 +149,34 @@ void QtkWidget::toggleConsole() {
|
||||||
* Protected Methods
|
* Protected Methods
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
void QtkWidget::dragEnterEvent(QDragEnterEvent * event) {
|
||||||
|
if(event->mimeData()->hasFormat("text/plain")) {
|
||||||
|
event->acceptProposedAction();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void QtkWidget::dropEvent(QDropEvent * event) {
|
||||||
|
mConsole->sendLog(event->mimeData()->text());
|
||||||
|
if(event->mimeData()->hasUrls()) {
|
||||||
|
auto urls = event->mimeData()->urls();
|
||||||
|
if(urls.size() > 1) {
|
||||||
|
qDebug() << "Cannot accept drop of multiple files.";
|
||||||
|
event->ignore();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Support other object types.
|
||||||
|
auto url = urls.front();
|
||||||
|
if(url.fileName().endsWith(".obj")) {
|
||||||
|
mScene->loadModel(url);
|
||||||
|
event->acceptProposedAction();
|
||||||
|
} else {
|
||||||
|
qDebug() << "Unsupported file type.";
|
||||||
|
event->ignore();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void QtkWidget::keyPressEvent(QKeyEvent * event) {
|
void QtkWidget::keyPressEvent(QKeyEvent * event) {
|
||||||
if(event->isAutoRepeat()) {
|
if(event->isAutoRepeat()) {
|
||||||
// Do not repeat input while a key is held down
|
// Do not repeat input while a key is held down
|
||||||
|
@ -253,7 +290,8 @@ void QtkWidget::teardownGL() { /* Nothing to teardown yet... */
|
||||||
void QtkWidget::updateCameraInput() {
|
void QtkWidget::updateCameraInput() {
|
||||||
Input::update();
|
Input::update();
|
||||||
// Camera Transformation
|
// Camera Transformation
|
||||||
if(Input::buttonPressed(Qt::RightButton)) {
|
if(Input::buttonPressed(Qt::LeftButton)
|
||||||
|
|| Input::buttonPressed(Qt::RightButton)) {
|
||||||
static const float transSpeed = 0.1f;
|
static const float transSpeed = 0.1f;
|
||||||
static const float rotSpeed = 0.5f;
|
static const float rotSpeed = 0.5f;
|
||||||
|
|
||||||
|
|
|
@ -131,11 +131,19 @@ namespace Qtk {
|
||||||
*/
|
*/
|
||||||
void sendLog(const QString & message, DebugContext context = Status);
|
void sendLog(const QString & message, DebugContext context = Status);
|
||||||
|
|
||||||
|
// TODO: Use this signal in treeview and toolbox to update object
|
||||||
|
// properties
|
||||||
|
void objectFocusChanged(const QString objectName);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Protected Methods
|
* Protected Methods
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
|
void dragEnterEvent(QDragEnterEvent * event) override;
|
||||||
|
|
||||||
|
void dropEvent(QDropEvent * event) override;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param event Key press event to update camera input manager.
|
* @param event Key press event to update camera input manager.
|
||||||
*/
|
*/
|
||||||
|
@ -166,6 +174,7 @@ namespace Qtk {
|
||||||
/**
|
/**
|
||||||
* Called when the `messageLogged` signal is caught.
|
* Called when the `messageLogged` signal is caught.
|
||||||
* See definition of initializeGL()
|
* See definition of initializeGL()
|
||||||
|
* https://doc.qt.io/qt-6/qopengldebuglogger.html#signals
|
||||||
*
|
*
|
||||||
* @param msg The message logged.
|
* @param msg The message logged.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
#ifndef QTK_RESOURCES_H_IN_H
|
||||||
|
#define QTK_RESOURCES_H_IN_H
|
||||||
|
|
||||||
|
// Not currently in use, but will be in the future.
|
||||||
|
|
||||||
|
#endif // QTK_RESOURCES_H_IN_H
|
|
@ -8,13 +8,143 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "toolbox.h"
|
#include "toolbox.h"
|
||||||
|
#include "qtkmainwindow.h"
|
||||||
#include "ui_toolbox.h"
|
#include "ui_toolbox.h"
|
||||||
|
|
||||||
Qtk::ToolBox::ToolBox(QWidget * parent) :
|
#include <QFormLayout>
|
||||||
QDockWidget(parent), ui(new Ui::ToolBox) {
|
#include <QLabel>
|
||||||
|
|
||||||
|
using namespace Qtk;
|
||||||
|
|
||||||
|
ToolBox::ToolBox(QWidget * parent) : QDockWidget(parent), ui(new Ui::ToolBox) {
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
setMinimumWidth(350);
|
||||||
}
|
}
|
||||||
|
|
||||||
Qtk::ToolBox::~ToolBox() {
|
void ToolBox::updateFocus(const QString & name) {
|
||||||
|
qDebug() << "Called updateFocus on Toolbox.";
|
||||||
|
auto object =
|
||||||
|
MainWindow::getMainWindow()->getQtkWidget()->getScene()->getObject(name);
|
||||||
|
if(object != Q_NULLPTR) {
|
||||||
|
removePages();
|
||||||
|
createPageProperties(object);
|
||||||
|
createPageShader(object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ToolBox::~ToolBox() {
|
||||||
delete ui;
|
delete ui;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ToolBox::removePages() {
|
||||||
|
// Remove all existing pages.
|
||||||
|
for(size_t i = 0; i < ui->toolBox->count(); i++) {
|
||||||
|
delete ui->toolBox->widget(i);
|
||||||
|
ui->toolBox->removeItem(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToolBox::createPageProperties(const Object * object) {
|
||||||
|
auto transform = object->getTransform();
|
||||||
|
auto type = object->getType();
|
||||||
|
auto * widget = new QWidget;
|
||||||
|
ui->toolBox->addItem(widget, "Properties");
|
||||||
|
ui->toolBox->setCurrentWidget(widget);
|
||||||
|
|
||||||
|
auto * layout = new QFormLayout;
|
||||||
|
layout->addRow(
|
||||||
|
new QLabel(tr("Name:")), new QLabel(object->getName().c_str()));
|
||||||
|
|
||||||
|
layout->addRow(
|
||||||
|
new QLabel(tr("Type:")),
|
||||||
|
new QLabel(type == Object::Type::QTK_MESH ? "Mesh" : "Model"));
|
||||||
|
|
||||||
|
auto rowLayout = new QHBoxLayout;
|
||||||
|
rowLayout->addWidget(new QLabel(tr("Translation:")));
|
||||||
|
int minWidth = 75;
|
||||||
|
for(size_t i = 0; i < 3; i++) {
|
||||||
|
auto spinBox = new QDoubleSpinBox;
|
||||||
|
spinBox->setMinimum(std::numeric_limits<double>::lowest());
|
||||||
|
spinBox->setSingleStep(0.1);
|
||||||
|
spinBox->setValue(transform.getTranslation()[i]);
|
||||||
|
spinBox->setFixedWidth(minWidth);
|
||||||
|
rowLayout->addWidget(spinBox);
|
||||||
|
|
||||||
|
if(i == 0) {
|
||||||
|
connect(
|
||||||
|
spinBox, &QDoubleSpinBox::valueChanged, object,
|
||||||
|
&Object::setTranslationX);
|
||||||
|
} else if(i == 1) {
|
||||||
|
connect(
|
||||||
|
spinBox, &QDoubleSpinBox::valueChanged, object,
|
||||||
|
&Object::setTranslationY);
|
||||||
|
} else if(i == 2) {
|
||||||
|
connect(
|
||||||
|
spinBox, &QDoubleSpinBox::valueChanged, object,
|
||||||
|
&Object::setTranslationZ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
layout->addRow(rowLayout);
|
||||||
|
|
||||||
|
rowLayout = new QHBoxLayout;
|
||||||
|
rowLayout->addWidget(new QLabel(tr("Scale:")));
|
||||||
|
for(size_t i = 0; i < 3; i++) {
|
||||||
|
auto spinBox = new QDoubleSpinBox;
|
||||||
|
spinBox->setMinimum(std::numeric_limits<double>::lowest());
|
||||||
|
spinBox->setSingleStep(0.1);
|
||||||
|
spinBox->setValue(transform.getScale()[i]);
|
||||||
|
spinBox->setFixedWidth(minWidth);
|
||||||
|
rowLayout->addWidget(spinBox);
|
||||||
|
|
||||||
|
if(i == 0) {
|
||||||
|
connect(
|
||||||
|
spinBox, &QDoubleSpinBox::valueChanged, object, &Object::setScaleX);
|
||||||
|
} else if(i == 1) {
|
||||||
|
connect(
|
||||||
|
spinBox, &QDoubleSpinBox::valueChanged, object, &Object::setScaleY);
|
||||||
|
} else if(i == 2) {
|
||||||
|
connect(
|
||||||
|
spinBox, &QDoubleSpinBox::valueChanged, object, &Object::setScaleZ);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
layout->addRow(rowLayout);
|
||||||
|
widget->setLayout(layout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ToolBox::createPageShader(const Object * object) {
|
||||||
|
// Shaders page.
|
||||||
|
auto widget = new QWidget;
|
||||||
|
ui->toolBox->addItem(widget, "Shaders");
|
||||||
|
auto mainLayout = new QFormLayout;
|
||||||
|
auto rowLayout = new QHBoxLayout;
|
||||||
|
rowLayout->addWidget(new QLabel("Vertex Shader:"));
|
||||||
|
rowLayout->addWidget(new QLabel(object->getVertexShader().c_str()));
|
||||||
|
mainLayout->addRow(rowLayout);
|
||||||
|
|
||||||
|
auto shaderView = new QTextEdit;
|
||||||
|
shaderView->setReadOnly(true);
|
||||||
|
auto vertexFile = QFile(object->getVertexShader().c_str());
|
||||||
|
if(vertexFile.exists()) {
|
||||||
|
vertexFile.open(QIODeviceBase::ReadOnly);
|
||||||
|
shaderView->setText(vertexFile.readAll());
|
||||||
|
vertexFile.close();
|
||||||
|
mainLayout->addRow(shaderView);
|
||||||
|
}
|
||||||
|
|
||||||
|
rowLayout = new QHBoxLayout;
|
||||||
|
rowLayout->addWidget(new QLabel("Fragment Shader:"));
|
||||||
|
rowLayout->addWidget(new QLabel(object->getFragmentShader().c_str()));
|
||||||
|
mainLayout->addRow(rowLayout);
|
||||||
|
|
||||||
|
shaderView = new QTextEdit;
|
||||||
|
shaderView->setReadOnly(true);
|
||||||
|
auto fragmentfile = QFile(object->getFragmentShader().c_str());
|
||||||
|
if(fragmentfile.exists()) {
|
||||||
|
fragmentfile.open(QIODeviceBase::ReadOnly);
|
||||||
|
shaderView->setText(fragmentfile.readAll());
|
||||||
|
fragmentfile.close();
|
||||||
|
mainLayout->addRow(shaderView);
|
||||||
|
}
|
||||||
|
|
||||||
|
widget->setLayout(mainLayout);
|
||||||
|
}
|
||||||
|
|
|
@ -12,6 +12,11 @@
|
||||||
|
|
||||||
#include <QDesignerExportWidget>
|
#include <QDesignerExportWidget>
|
||||||
#include <QDockWidget>
|
#include <QDockWidget>
|
||||||
|
#include <QDoubleSpinBox>
|
||||||
|
#include <QGroupBox>
|
||||||
|
|
||||||
|
|
||||||
|
#include "qtk/scene.h"
|
||||||
|
|
||||||
namespace Ui {
|
namespace Ui {
|
||||||
class ToolBox;
|
class ToolBox;
|
||||||
|
@ -30,6 +35,15 @@ namespace Qtk {
|
||||||
|
|
||||||
~ToolBox();
|
~ToolBox();
|
||||||
|
|
||||||
|
void removePages();
|
||||||
|
|
||||||
|
void createPageProperties(const Object * object);
|
||||||
|
|
||||||
|
void createPageShader(const Object * object);
|
||||||
|
|
||||||
|
void updateFocus(const QString & name);
|
||||||
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Private Members
|
* Private Members
|
||||||
|
|
|
@ -10,17 +10,57 @@
|
||||||
<height>300</height>
|
<height>300</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<property name="minimumSize">
|
||||||
|
<size>
|
||||||
|
<width>86</width>
|
||||||
|
<height>167</height>
|
||||||
|
</size>
|
||||||
|
</property>
|
||||||
<property name="windowTitle">
|
<property name="windowTitle">
|
||||||
<string>Object Details</string>
|
<string>Object Details</string>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="dockWidgetContents">
|
<widget class="QWidget" name="dockWidgetContents">
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<layout class="QVBoxLayout" name="verticalLayout">
|
||||||
<item>
|
<item>
|
||||||
<widget class="QToolBox" name="toolBox">
|
<widget class="QToolBox" name="toolBox">
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
<number>0</number>
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="page">
|
<widget class="QWidget" name="page_properties">
|
||||||
|
<property name="enabled">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
<property name="geometry">
|
||||||
|
<rect>
|
||||||
|
<x>0</x>
|
||||||
|
<y>0</y>
|
||||||
|
<width>382</width>
|
||||||
|
<height>201</height>
|
||||||
|
</rect>
|
||||||
|
</property>
|
||||||
|
<property name="sizePolicy">
|
||||||
|
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
|
||||||
|
<horstretch>0</horstretch>
|
||||||
|
<verstretch>0</verstretch>
|
||||||
|
</sizepolicy>
|
||||||
|
</property>
|
||||||
|
<attribute name="label">
|
||||||
|
<string>Properties</string>
|
||||||
|
</attribute>
|
||||||
|
</widget>
|
||||||
|
<widget class="QWidget" name="page_shaders">
|
||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
|
@ -33,19 +73,6 @@
|
||||||
<string>Shaders</string>
|
<string>Shaders</string>
|
||||||
</attribute>
|
</attribute>
|
||||||
</widget>
|
</widget>
|
||||||
<widget class="QWidget" name="page_2">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>382</width>
|
|
||||||
<height>201</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<attribute name="label">
|
|
||||||
<string>Properties</string>
|
|
||||||
</attribute>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
|
|
|
@ -48,16 +48,25 @@ void Qtk::TreeView::itemFocus(QTreeWidgetItem * item, int column) {
|
||||||
auto scene = MainWindow::getMainWindow()->getQtkWidget()->getScene();
|
auto scene = MainWindow::getMainWindow()->getQtkWidget()->getScene();
|
||||||
auto & transform = scene->getCamera().getTransform();
|
auto & transform = scene->getCamera().getTransform();
|
||||||
auto object = scene->getObject(name);
|
auto object = scene->getObject(name);
|
||||||
|
Transform3D * objectTransform;
|
||||||
|
// If the object is a mesh or model, focus the camera on it.
|
||||||
if(object == Q_NULLPTR) {
|
if(object == Q_NULLPTR) {
|
||||||
qDebug() << "Attempt to get non-existing object with name '" << name
|
qDebug() << "Attempt to get non-existing object with name '" << name
|
||||||
<< "'\n";
|
<< "'\n";
|
||||||
}
|
} else if(object->getType() == Object::QTK_MESH) {
|
||||||
Transform3D * objectTransform;
|
|
||||||
if(object->getType() == Object::QTK_MESH) {
|
|
||||||
objectTransform = &dynamic_cast<MeshRenderer *>(object)->getTransform();
|
objectTransform = &dynamic_cast<MeshRenderer *>(object)->getTransform();
|
||||||
} else if(object->getType() == Object::QTK_MODEL) {
|
} else if(object->getType() == Object::QTK_MODEL) {
|
||||||
objectTransform = &dynamic_cast<Model *>(object)->getTransform();
|
objectTransform = &dynamic_cast<Model *>(object)->getTransform();
|
||||||
}
|
}
|
||||||
transform.setTranslation(objectTransform->getTranslation());
|
auto focusScale = objectTransform->getScale();
|
||||||
|
float width = focusScale.x() / 2.0f;
|
||||||
|
float height = focusScale.y() / 2.0f;
|
||||||
|
QVector3D pos = objectTransform->getTranslation();
|
||||||
|
// pos.setX(pos.x() + width);
|
||||||
|
pos.setY(pos.y() + height);
|
||||||
|
transform.setTranslation(pos);
|
||||||
transform.translate(0.0f, 0.0f, 3.0f);
|
transform.translate(0.0f, 0.0f, 3.0f);
|
||||||
|
|
||||||
|
// Emit signal from qtk widget for new object focus. Triggers GUI updates.
|
||||||
|
emit MainWindow::getMainWindow()->getQtkWidget()->objectFocusChanged(name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -211,6 +211,14 @@ namespace Qtk {
|
||||||
*/
|
*/
|
||||||
inline Transform3D & getTransform() { return mTransform; }
|
inline Transform3D & getTransform() { return mTransform; }
|
||||||
|
|
||||||
|
inline std::string getVertexShader() const override {
|
||||||
|
return mVertexShader;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string getFragmentShader() const override {
|
||||||
|
return mFragmentShader;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Private Members
|
* Private Members
|
||||||
|
|
|
@ -18,6 +18,9 @@
|
||||||
#include <assimp/Importer.hpp>
|
#include <assimp/Importer.hpp>
|
||||||
|
|
||||||
// Qtk
|
// Qtk
|
||||||
|
#include <QFileInfo>
|
||||||
|
|
||||||
|
|
||||||
#include "modelmesh.h"
|
#include "modelmesh.h"
|
||||||
#include "qtkapi.h"
|
#include "qtkapi.h"
|
||||||
|
|
||||||
|
@ -58,14 +61,6 @@ namespace Qtk {
|
||||||
loadModel(mModelPath);
|
loadModel(mModelPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Model(
|
|
||||||
std::string name, std::string path,
|
|
||||||
std::string vertexShader = ":/shaders/model-basic.vert",
|
|
||||||
std::string fragmentShader = ":/shaders/model-basic.frag") :
|
|
||||||
Model(
|
|
||||||
name.c_str(), path.c_str(), vertexShader.c_str(),
|
|
||||||
fragmentShader.c_str()) {}
|
|
||||||
|
|
||||||
inline ~Model() override { mManager.remove(getName().c_str()); }
|
inline ~Model() override { mManager.remove(getName().c_str()); }
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
|
@ -132,6 +127,14 @@ namespace Qtk {
|
||||||
*/
|
*/
|
||||||
inline Transform3D & getTransform() { return mTransform; }
|
inline Transform3D & getTransform() { return mTransform; }
|
||||||
|
|
||||||
|
inline std::string getVertexShader() const override {
|
||||||
|
return mVertexShader;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline std::string getFragmentShader() const override {
|
||||||
|
return mFragmentShader;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Private Methods
|
* Private Methods
|
||||||
|
|
|
@ -96,10 +96,24 @@ namespace Qtk {
|
||||||
|
|
||||||
[[nodiscard]] inline const Type & getType() const { return mType; }
|
[[nodiscard]] inline const Type & getType() const { return mType; }
|
||||||
|
|
||||||
|
[[nodiscard]] inline virtual const Transform3D & getTransform() const {
|
||||||
|
return mTransform;
|
||||||
|
}
|
||||||
|
|
||||||
|
[[nodiscard]] inline virtual std::string getVertexShader() const {
|
||||||
|
return "Base Object has no vertex shader.";
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual inline std::string getFragmentShader() const {
|
||||||
|
return "Base Object has no fragment shader.";
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Setters
|
* Setters
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
||||||
|
virtual inline void setName(const std::string & name) { mName = name; }
|
||||||
|
|
||||||
virtual inline void setColors(const Colors & value) {
|
virtual inline void setColors(const Colors & value) {
|
||||||
mShape.mColors = value;
|
mShape.mColors = value;
|
||||||
}
|
}
|
||||||
|
@ -135,6 +149,39 @@ namespace Qtk {
|
||||||
mShape.mVertices = value;
|
mShape.mVertices = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void setScaleX(double x) {
|
||||||
|
mTransform.setScale(
|
||||||
|
x, mTransform.getScale().y(), mTransform.getScale().z());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void setScaleY(double y) {
|
||||||
|
mTransform.setScale(
|
||||||
|
mTransform.getScale().x(), y, mTransform.getScale().z());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void setScaleZ(double z) {
|
||||||
|
mTransform.setScale(
|
||||||
|
mTransform.getScale().x(), mTransform.getScale().y(), z);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void setTranslationX(double x) {
|
||||||
|
mTransform.setTranslation(
|
||||||
|
x, mTransform.getTranslation().y(),
|
||||||
|
mTransform.getTranslation().z());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void setTranslationY(double y) {
|
||||||
|
mTransform.setTranslation(
|
||||||
|
mTransform.getTranslation().x(), y,
|
||||||
|
mTransform.getTranslation().z());
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void setTranslationZ(double z) {
|
||||||
|
mTransform.setTranslation(
|
||||||
|
mTransform.getTranslation().x(), mTransform.getTranslation().y(),
|
||||||
|
z);
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Public Methods
|
* Public Methods
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
|
|
@ -37,16 +37,42 @@ Scene::~Scene() {
|
||||||
* Public Methods
|
* Public Methods
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
|
|
||||||
|
template <> MeshRenderer * Scene::addObject(MeshRenderer * object) {
|
||||||
|
initSceneObjectName(object);
|
||||||
|
mMeshes.push_back(object);
|
||||||
|
sceneUpdated(mSceneName);
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <> Model * Scene::addObject(Model * object) {
|
||||||
|
initSceneObjectName(object);
|
||||||
|
mModels.push_back(object);
|
||||||
|
sceneUpdated(mSceneName);
|
||||||
|
return object;
|
||||||
|
}
|
||||||
|
|
||||||
void Scene::draw() {
|
void Scene::draw() {
|
||||||
if(!mInit) {
|
if(!mInit) {
|
||||||
initializeOpenGLFunctions();
|
initializeOpenGLFunctions();
|
||||||
init();
|
init();
|
||||||
mInit = true;
|
mInit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
while(!mModelLoadQueue.empty()) {
|
||||||
|
auto modelSpec = mModelLoadQueue.front();
|
||||||
|
// Load the model and add it to the scene.
|
||||||
|
addObject(new Model(modelSpec.first.c_str(), modelSpec.second.c_str()));
|
||||||
|
mModelLoadQueue.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(mPause) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(mSkybox != Q_NULLPTR) {
|
if(mSkybox != Q_NULLPTR) {
|
||||||
mSkybox->draw();
|
mSkybox->draw();
|
||||||
}
|
}
|
||||||
for(auto & model : mModels) {
|
for(const auto & model : mModels) {
|
||||||
model->draw();
|
model->draw();
|
||||||
}
|
}
|
||||||
for(const auto & mesh : mMeshes) {
|
for(const auto & mesh : mMeshes) {
|
||||||
|
@ -57,8 +83,8 @@ void Scene::draw() {
|
||||||
std::vector<Object *> Scene::getObjects() const {
|
std::vector<Object *> Scene::getObjects() const {
|
||||||
// All scene objects must inherit from Qtk::Object.
|
// All scene objects must inherit from Qtk::Object.
|
||||||
std::vector<Object *> objects(mMeshes.begin(), mMeshes.end());
|
std::vector<Object *> objects(mMeshes.begin(), mMeshes.end());
|
||||||
for(auto model : mModels) {
|
for(const auto & model : mModels) {
|
||||||
objects.push_back(dynamic_cast<Object *>(model));
|
objects.push_back(model);
|
||||||
if(objects.back() == nullptr) {
|
if(objects.back() == nullptr) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
@ -66,8 +92,8 @@ std::vector<Object *> Scene::getObjects() const {
|
||||||
return objects;
|
return objects;
|
||||||
}
|
}
|
||||||
|
|
||||||
Object * Scene::getObject(const QString & name) {
|
Object * Scene::getObject(const QString & name) const {
|
||||||
for(auto object : getObjects()) {
|
for(const auto & object : getObjects()) {
|
||||||
if(object->getName() == name.toStdString()) {
|
if(object->getName() == name.toStdString()) {
|
||||||
return object;
|
return object;
|
||||||
}
|
}
|
||||||
|
@ -80,14 +106,14 @@ void Scene::setSkybox(Skybox * skybox) {
|
||||||
mSkybox = skybox;
|
mSkybox = skybox;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <> MeshRenderer * Scene::addObject(MeshRenderer * object) {
|
void Scene::initSceneObjectName(Object * object) {
|
||||||
mMeshes.push_back(object);
|
if(!mObjectCount.count(object->getName())) {
|
||||||
sceneUpdated(mSceneName);
|
mObjectCount[object->getName()] = 1;
|
||||||
return object;
|
} else {
|
||||||
}
|
mObjectCount[object->getName()]++;
|
||||||
|
}
|
||||||
template <> Model * Scene::addObject(Model * object) {
|
auto count = mObjectCount[object->getName()];
|
||||||
mModels.push_back(object);
|
if(count > 1) {
|
||||||
sceneUpdated(mSceneName);
|
object->setName(object->getName() + " (" + std::to_string(count) + ")");
|
||||||
return object;
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,9 @@
|
||||||
#define QTK_SCENE_H
|
#define QTK_SCENE_H
|
||||||
|
|
||||||
#include <QMatrix4x4>
|
#include <QMatrix4x4>
|
||||||
|
#include <QUrl>
|
||||||
|
|
||||||
|
#include <queue>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
|
|
||||||
#include "camera3d.h"
|
#include "camera3d.h"
|
||||||
|
@ -75,6 +77,18 @@ namespace Qtk {
|
||||||
*/
|
*/
|
||||||
virtual void update() {}
|
virtual void update() {}
|
||||||
|
|
||||||
|
void loadModel(const QUrl & url) {
|
||||||
|
auto fileName = url.fileName().replace(".obj", "").toStdString();
|
||||||
|
auto filePath = url.toLocalFile().toStdString();
|
||||||
|
loadModel(fileName, filePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
void loadModel(const std::string & name, const std::string & path) {
|
||||||
|
// Add the dropped model to the load queue.
|
||||||
|
// This is consumed during rendering of the scene if not empty.
|
||||||
|
mModelLoadQueue.push({name, path});
|
||||||
|
}
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Accessors
|
* Accessors
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
@ -91,7 +105,16 @@ namespace Qtk {
|
||||||
* @param name The objectName to look for within this scene.
|
* @param name The objectName to look for within this scene.
|
||||||
* @return The found object or Q_NULLPTR if none found.
|
* @return The found object or Q_NULLPTR if none found.
|
||||||
*/
|
*/
|
||||||
[[nodiscard]] Object * getObject(const QString & name);
|
[[nodiscard]] Object * getObject(const QString & name) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return The number of objects within the scene with the given name.
|
||||||
|
*/
|
||||||
|
[[nodiscard]] uint64_t getObjectCount(const QString & name) {
|
||||||
|
return mObjectCount.count(name.toStdString())
|
||||||
|
? mObjectCount[name.toStdString()]
|
||||||
|
: 0;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Camera attached to this scene.
|
* @return Camera attached to this scene.
|
||||||
|
@ -166,6 +189,8 @@ namespace Qtk {
|
||||||
*/
|
*/
|
||||||
inline void setSceneName(QString name) { mSceneName = std::move(name); }
|
inline void setSceneName(QString name) { mSceneName = std::move(name); }
|
||||||
|
|
||||||
|
inline void setPause(bool pause) { mPause = pause; }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
/**
|
/**
|
||||||
* Signal thrown when the scene is modified by adding or removing objects.
|
* Signal thrown when the scene is modified by adding or removing objects.
|
||||||
|
@ -175,7 +200,26 @@ namespace Qtk {
|
||||||
*/
|
*/
|
||||||
void sceneUpdated(QString sceneName);
|
void sceneUpdated(QString sceneName);
|
||||||
|
|
||||||
|
|
||||||
|
/*************************************************************************
|
||||||
|
* Public Members
|
||||||
|
************************************************************************/
|
||||||
|
public:
|
||||||
|
/* Models used for storing 3D models in the scene. */
|
||||||
|
std::vector<Model *> mModels {};
|
||||||
|
|
||||||
|
/* Queue of models requested to load at runtime. */
|
||||||
|
std::queue<std::pair<std::string, std::string>> mModelLoadQueue;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
/**
|
||||||
|
* Initialize an object name relative to other objects already loaded.
|
||||||
|
* Protects against having two objects with the same name.
|
||||||
|
*
|
||||||
|
* @param object Qtk Object to name within this scene.
|
||||||
|
*/
|
||||||
|
void initSceneObjectName(Qtk::Object * object);
|
||||||
|
|
||||||
/*************************************************************************
|
/*************************************************************************
|
||||||
* Private Members
|
* Private Members
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
|
@ -183,14 +227,16 @@ namespace Qtk {
|
||||||
static Camera3D mCamera;
|
static Camera3D mCamera;
|
||||||
static QMatrix4x4 mProjection;
|
static QMatrix4x4 mProjection;
|
||||||
bool mInit = false;
|
bool mInit = false;
|
||||||
|
/* Pause rendering of the scene. */
|
||||||
|
bool mPause = false;
|
||||||
|
|
||||||
QString mSceneName;
|
QString mSceneName;
|
||||||
/* The skybox for this scene. */
|
/* The skybox for this scene. */
|
||||||
Skybox * mSkybox {};
|
Skybox * mSkybox {};
|
||||||
/* MeshRenderers used simple geometry. */
|
/* MeshRenderers used simple geometry. */
|
||||||
std::vector<MeshRenderer *> mMeshes {};
|
std::vector<MeshRenderer *> mMeshes {};
|
||||||
/* Models used for storing 3D models in the scene. */
|
/* Track count of objects with same initial name. */
|
||||||
std::vector<Model *> mModels {};
|
std::unordered_map<std::string, uint64_t> mObjectCount;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SceneEmpty : public Scene {
|
class SceneEmpty : public Scene {
|
||||||
|
|
Loading…
Reference in New Issue