From 2087b306b9119314119d81cb8854a4bbdde86dd4 Mon Sep 17 00:00:00 2001 From: Shaun Reed Date: Sun, 10 Mar 2024 15:19:43 -0400 Subject: [PATCH] Fix order of arguments for rotation functions. --- example-app/examplescene.cpp | 14 ++++---- src/app/qtkscene.cpp | 47 +++++++++++++------------- src/app/qtkwidget.cpp | 15 +++------ src/app/treeview.cpp | 7 ++-- src/qtk/camera3d.h | 65 +++++++++++++++++++++++++++++++++++- src/qtk/scene.cpp | 4 +-- src/qtk/transform3D.h | 8 ++--- 7 files changed, 108 insertions(+), 52 deletions(-) diff --git a/example-app/examplescene.cpp b/example-app/examplescene.cpp index d4d8deb..d5d469e 100644 --- a/example-app/examplescene.cpp +++ b/example-app/examplescene.cpp @@ -13,8 +13,8 @@ using namespace Qtk; ExampleScene::ExampleScene(Qtk::Scene * scene) : Qtk::SceneInterface(scene) { setSceneName("Example Scene"); - getCamera().getTransform().setTranslation(-8.0f, 0.0f, 10.0f); - getCamera().getTransform().setRotation(-5.0f, 0.0f, 1.0f, 0.0f); + getCamera().setTranslation({-8.0f, 0.0f, 10.0f}); + getCamera().setRotation(0.0f, 1.0f, 0.0f, -5.0f); } ExampleScene::~ExampleScene() {} @@ -64,10 +64,10 @@ void ExampleScene::update() { // Pitch forward and roll sideways MeshRenderer::getInstance("leftTriangle") ->getTransform() - .rotate(0.75f, 1.0f, 0.0f, 0.0f); + .rotate(1.0f, 0.0f, 0.0f, 0.75f); MeshRenderer::getInstance("rightTriangle") ->getTransform() - .rotate(0.75f, 0.0f, 0.0f, 1.0f); + .rotate(0.0f, 0.0f, 1.0f, 0.75f); static float translateX = 0.025f; float limit = -9.0f; // Origin position.x - 2.0f @@ -86,12 +86,12 @@ void ExampleScene::update() { .translate(-translateX, 0.0f, 0.0f); MeshRenderer::getInstance("topTriangle") ->getTransform() - .rotate(0.75f, 0.2f, 0.0f, 0.4f); + .rotate(0.2f, 0.0f, 0.4f, 0.75f); MeshRenderer::getInstance("bottomTriangle") ->getTransform() - .rotate(0.75f, 0.0f, 0.2f, 0.4f); + .rotate(0.0f, 0.2f, 0.4f, 0.75f); MeshRenderer::getInstance("centerCube") ->getTransform() - .rotate(0.75f, 0.2f, 0.4f, 0.6f); + .rotate(0.2f, 0.4f, 0.6f, 0.75f); } diff --git a/src/app/qtkscene.cpp b/src/app/qtkscene.cpp index 4216d9c..353c47e 100644 --- a/src/app/qtkscene.cpp +++ b/src/app/qtkscene.cpp @@ -16,8 +16,9 @@ using namespace Qtk; QtkScene::QtkScene(Qtk::Scene * scene) : Qtk::SceneInterface(scene) { setSceneName("Qtk Scene"); - getCamera().getTransform().setTranslation(0.0f, 0.0f, 20.0f); - getCamera().getTransform().setRotation(-5.0f, 0.0f, 1.0f, 0.0f); + getCamera().setTranslation({0.0f, 0.0f, 20.0f}); + getCamera().setRotation( + QQuaternion::fromAxisAndAngle(0.0f, 1.0f, 0.0f, -5.0f)); } QtkScene::~QtkScene() { @@ -89,7 +90,7 @@ void QtkScene::init() { model->getTransform().setTranslation(2.0f, 2.0f, -10.0f); // Sometimes the models are very large model->getTransform().scale(0.0025f); - model->getTransform().rotate(-110.0f, 0.0f, 1.0f, 0.0f); + model->getTransform().rotate(0.0f, 1.0f, 0.0f, -110.0f); model = addObject( new Qtk::Model("alien", ":/models/models/alien-hominid/alien.obj")); @@ -99,8 +100,8 @@ void QtkScene::init() { model = addObject( new Qtk::Model("My scythe", ":/models/models/scythe/scythe.obj")); model->getTransform().setTranslation(-6.0f, 0.0f, -10.0f); - model->getTransform().rotate(-90.0f, 1.0f, 0.0f, 0.0f); - model->getTransform().rotate(90.0f, 0.0f, 1.0f, 0.0f); + model->getTransform().rotate(1.0f, 0.0f, 0.0f, -90.0f); + model->getTransform().rotate(0.0f, 1.0f, 0.0f, 90.0f); model = addObject( new Qtk::Model("masterChief", ":/models/models/spartan/spartan.obj")); @@ -331,14 +332,14 @@ void QtkScene::init() { mesh->reallocateNormals(mesh->getNormals()); mesh->reallocateTexCoords(mesh->getTexCoords(), 3); mesh->releaseShaders(); - mesh->getTransform().rotate(45.0f, 0.0f, 1.0f, 0.0f); + mesh->getTransform().rotate(0.0f, 1.0f, 0.0f, 45.0f); // Texturing a cube using a cube map // + Cube map texturing works with both QTK_DRAW_ARRAYS and QTK_DRAW_ELEMENTS mesh = addObject(new Qtk::MeshRenderer("testCubeMap", Cube(QTK_DRAW_ELEMENTS))); mesh->getTransform().setTranslation(-3.0f, 1.0f, -2.0f); - mesh->getTransform().setRotation(45.0f, 0.0f, 1.0f, 0.0f); + mesh->getTransform().setRotation(0.0f, 1.0f, 0.0f, 45.0f); mesh->setShaders( ":/shaders/texture-cubemap.vert", ":/shaders/texture-cubemap.frag"); mesh->setCubeMap(":/textures/crate.png"); @@ -439,10 +440,10 @@ void QtkScene::draw() { void QtkScene::update() { auto mySpartan = Model::getInstance("My spartan"); - mySpartan->getTransform().rotate(0.75f, 0.0f, 1.0f, 0.0f); + mySpartan->getTransform().rotate(0.0f, 1.0f, 0.0f, 0.75f); auto myCube = MeshRenderer::getInstance("My cube"); - myCube->getTransform().rotate(-0.75f, 0.0f, 1.0f, 0.0f); + myCube->getTransform().rotate(-0.0f, 1.0f, 0.0f, 0.75f); auto position = MeshRenderer::getInstance("alienTestLight") ->getTransform() @@ -456,7 +457,7 @@ void QtkScene::update() { alien->setUniform("uMVP.model", posMatrix); alien->setUniform("uMVP.view", QtkScene::getCamera().toMatrix()); alien->setUniform("uMVP.projection", QtkScene::getProjectionMatrix()); - alien->getTransform().rotate(0.75f, 0.0f, 1.0f, 0.0f); + alien->getTransform().rotate(0.0f, 1.0f, 0.0f, 0.75f); position = MeshRenderer::getInstance("spartanTestLight") ->getTransform() @@ -470,10 +471,10 @@ void QtkScene::update() { spartan->setUniform("uMVP.model", posMatrix); spartan->setUniform("uMVP.view", QtkScene::getCamera().toMatrix()); spartan->setUniform("uMVP.projection", QtkScene::getProjectionMatrix()); - spartan->getTransform().rotate(0.75f, 0.0f, 1.0f, 0.0f); + spartan->getTransform().rotate(0.0f, 1.0f, 0.0f, 0.75f); auto phong = MeshRenderer::getInstance("testPhong"); - phong->getTransform().rotate(0.75f, 1.0f, 0.5f, 0.0f); + phong->getTransform().rotate(1.0f, 0.5f, 0.0f, 0.75f); phong->bindShaders(); position = MeshRenderer::getInstance("testLight")->getTransform().getTranslation(); @@ -488,27 +489,27 @@ void QtkScene::update() { phong->releaseShaders(); // Rotate lighting example cubes - mTestPhong->getTransform().rotate(0.75f, 0.5f, 0.3f, 0.2f); + mTestPhong->getTransform().rotate(0.5f, 0.3f, 0.2f, 0.75f); MeshRenderer::getInstance("noLight")->getTransform().rotate( - 0.75f, 0.5f, 0.3f, 0.2f); - mTestAmbient->getTransform().rotate(0.75f, 0.5f, 0.3f, 0.2f); - mTestDiffuse->getTransform().rotate(0.75f, 0.5f, 0.3f, 0.2f); - mTestSpecular->getTransform().rotate(0.75f, 0.5f, 0.3f, 0.2f); + 0.5f, 0.3f, 0.2f, 0.75f); + mTestAmbient->getTransform().rotate(0.5f, 0.3f, 0.2f, 0.75f); + mTestDiffuse->getTransform().rotate(0.5f, 0.3f, 0.2f, 0.75f); + mTestSpecular->getTransform().rotate(0.5f, 0.3f, 0.2f, 0.75f); // Examples of various translations and rotations // Rotate in multiple directions simultaneously MeshRenderer::getInstance("rgbNormalsCube") ->getTransform() - .rotate(0.75f, 0.2f, 0.4f, 0.6f); + .rotate(0.2f, 0.4f, 0.6f, 0.75f); // Pitch forward and roll sideways MeshRenderer::getInstance("leftTriangle") ->getTransform() - .rotate(0.75f, 1.0f, 0.0f, 0.0f); + .rotate(1.0f, 0.0f, 0.0f, 0.75f); MeshRenderer::getInstance("rightTriangle") ->getTransform() - .rotate(0.75f, 0.0f, 0.0f, 1.0f); + .rotate(0.0f, 0.0f, 1.0f, 0.75f); // Move between two positions over time static float translateX = 0.025f; @@ -529,15 +530,15 @@ void QtkScene::update() { // And lets rotate the triangles in two directions at once MeshRenderer::getInstance("topTriangle") ->getTransform() - .rotate(0.75f, 0.2f, 0.0f, 0.4f); + .rotate(0.2f, 0.0f, 0.4f, 0.75f); MeshRenderer::getInstance("bottomTriangle") ->getTransform() - .rotate(0.75f, 0.0f, 0.2f, 0.4f); + .rotate(0.0f, 0.2f, 0.4f, 0.75f); // And make the bottom triangle green, instead of RGB // Rotate center cube in several directions simultaneously // + Not subject to gimbal lock since we are using quaternions :) MeshRenderer::getInstance("centerCube") ->getTransform() - .rotate(0.75f, 0.2f, 0.4f, 0.6f); + .rotate(0.2f, 0.4f, 0.6f, 0.75f); } diff --git a/src/app/qtkwidget.cpp b/src/app/qtkwidget.cpp index 6c2b91b..d02c0ea 100644 --- a/src/app/qtkwidget.cpp +++ b/src/app/qtkwidget.cpp @@ -10,11 +10,6 @@ #include #include -#include -#include -#include -#include - #include #include #include @@ -294,10 +289,10 @@ void QtkWidget::updateCameraInput() { static const float rotSpeed = 0.5f; // Handle rotations - Scene::getCamera().getTransform().rotate( - -rotSpeed * Input::mouseDelta().x(), Camera3D::LocalUp); - Scene::getCamera().getTransform().rotate( - -rotSpeed * Input::mouseDelta().y(), Scene::getCamera().getRight()); + Scene::getCamera().rotate(QQuaternion::fromAxisAndAngle( + Camera3D::LocalUp, -rotSpeed * Input::mouseDelta().x())); + Scene::getCamera().rotate(QQuaternion::fromAxisAndAngle( + Scene::getCamera().getRight(), -rotSpeed * Input::mouseDelta().y())); // Handle translations QVector3D translation; @@ -319,7 +314,7 @@ void QtkWidget::updateCameraInput() { if(Input::keyPressed(Qt::Key_E)) { translation += Scene::getCamera().getUp() / 2.0f; } - Scene::getCamera().getTransform().translate(transSpeed * translation); + Scene::getCamera().translate(transSpeed * translation); } } diff --git a/src/app/treeview.cpp b/src/app/treeview.cpp index 0239b90..4589e17 100644 --- a/src/app/treeview.cpp +++ b/src/app/treeview.cpp @@ -46,7 +46,6 @@ void Qtk::TreeView::updateView(const Qtk::Scene * scene) { void Qtk::TreeView::itemFocus(QTreeWidgetItem * item, int column) { QString name = item->text(column); auto scene = MainWindow::getMainWindow()->getQtkWidget()->getScene(); - auto & transform = scene->getCamera().getTransform(); auto object = scene->getObject(name); Transform3D * objectTransform; // If the object is a mesh or model, focus the camera on it. @@ -59,13 +58,11 @@ void Qtk::TreeView::itemFocus(QTreeWidgetItem * item, int column) { objectTransform = &dynamic_cast(object)->getTransform(); } 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); + Qtk::Scene::getCamera().setTranslation(pos); + Qtk::Scene::getCamera().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); diff --git a/src/qtk/camera3d.h b/src/qtk/camera3d.h index 5d76221..24cc2b9 100644 --- a/src/qtk/camera3d.h +++ b/src/qtk/camera3d.h @@ -32,7 +32,9 @@ namespace Qtk { /** * @return Transform3D associated with this camera. */ - inline Transform3D & getTransform() { return mTransform; } + [[nodiscard]] inline const Transform3D & getTransform() const { + return mTransform; + } /** * @return Current translation of the camera as a QVector3D. @@ -78,6 +80,67 @@ namespace Qtk { */ const QMatrix4x4 & toMatrix(); + /** + * Set the translation for this camera. + * TODO: Replace these methods by inheriting from a base class. + * + * @param translation QVector3D for the new translation. + */ + inline void setTranslation(const QVector3D & translation) { + mTransform.setTranslation(translation); + } + + /** + * Set the rotation for this camera. + * + * @param rotation QQuaternion for the new rotation. + */ + inline void setRotation(const QQuaternion & rotation) { + mTransform.setRotation(rotation); + } + + /** + * Sets a rotation upon an axis represented by the 3D vector (x, y, z) + * + * @param ax X axis to set angle for. + * @param ay Y axis to set angle for. + * @param az Z axis to set angle for. + * @param angle Angle to set rotation. + */ + inline void setRotation(float ax, float ay, float az, float angle) { + mTransform.setRotation(ax, ay, az, angle); + } + + /** + * Translate the camera by the given position. + * + * @param position QVector3D for the position to translate by. + */ + inline void translate(const QVector3D & position) { + mTransform.translate(position); + } + + /** + * Rotate the camera by the given rotation. + * + * @param rotation QQaternion for the rotation to apply. + */ + inline void rotate(const QQuaternion & rotation) { + mTransform.rotate(rotation); + } + + /** + * Sets a rotation upon an axis represented by the 3D vector (x, y, z) + * + * @param ax X axis to set angle for. + * @param ay Y axis to set angle for. + * @param az Z axis to set angle for. + * @param angle Angle to set rotation. + */ + inline void rotate(float ax, float ay, float az, float angle) { + mTransform.rotate(ax, ay, az, angle); + } + private: /************************************************************************* * Private Methods diff --git a/src/qtk/scene.cpp b/src/qtk/scene.cpp index b107c94..bc93830 100644 --- a/src/qtk/scene.cpp +++ b/src/qtk/scene.cpp @@ -19,8 +19,8 @@ QMatrix4x4 Scene::mProjection; ******************************************************************************/ Scene::Scene() : mSceneName("Default Scene") { - mCamera.getTransform().setTranslation(0.0f, 0.0f, 20.0f); - mCamera.getTransform().setRotation(-5.0f, 0.0f, 1.0f, 0.0f); + mCamera.setTranslation({0.0f, 0.0f, 20.0f}); + mCamera.setRotation({-5.0f, 0.0f, 1.0f, 0.0f}); } Scene::~Scene() { diff --git a/src/qtk/transform3D.h b/src/qtk/transform3D.h index 71d1f38..8981835 100644 --- a/src/qtk/transform3D.h +++ b/src/qtk/transform3D.h @@ -116,12 +116,12 @@ namespace Qtk { /** * Apply rotation upon an axis represented by the 3D vector (x, y, z) * - * @param angle Angle to rotate. * @param ax X axis to apply the rotation on. * @param ay Y axis to apply the rotation on. * @param az Z axis to apply the rotation on. + * @param angle Angle to rotate. */ - inline void rotate(float angle, float ax, float ay, float az) { + inline void rotate(float ax, float ay, float az, float angle) { rotate(QQuaternion::fromAxisAndAngle(ax, ay, az, angle)); } @@ -178,12 +178,12 @@ namespace Qtk { /** * Sets a rotation upon an axis represented by the 3D vector (x, y, z) * - * @param angle Angle to set rotation. * @param ax X axis to set angle for. * @param ay Y axis to set angle for. * @param az Z axis to set angle for. + * @param angle Angle to set rotation. */ - inline void setRotation(float angle, float ax, float ay, float az) { + inline void setRotation(float ax, float ay, float az, float angle) { setRotation(QQuaternion::fromAxisAndAngle(ax, ay, az, angle)); }