diff --git a/example-app/examplescene.cpp b/example-app/examplescene.cpp index 3d436e2..68869c6 100644 --- a/example-app/examplescene.cpp +++ b/example-app/examplescene.cpp @@ -11,7 +11,8 @@ using namespace Qtk; -ExampleScene::ExampleScene(Qtk::Scene * scene) : Qtk::SceneInterface(scene) { +ExampleScene::ExampleScene() +{ setSceneName("Example Scene"); getCamera().getTransform().setTranslation(-8.0f, 0.0f, 10.0f); getCamera().getTransform().setRotation(-5.0f, 0.0f, 1.0f, 0.0f); @@ -19,18 +20,17 @@ ExampleScene::ExampleScene(Qtk::Scene * scene) : Qtk::SceneInterface(scene) { ExampleScene::~ExampleScene() = default; -void ExampleScene::init() { - auto skybox = new Qtk::Skybox("Skybox"); - setSkybox(skybox); +void ExampleScene::init() +{ + setSkybox(new Qtk::Skybox("Skybox")); std::string spartanPath = QTK_EXAMPLE_SOURCE_DIR; - spartanPath += "/resources/models/spartan/spartan.obj"; - auto spartan = new Model("spartan", spartanPath.c_str()); - addObject(spartan); + spartanPath += "/../resources/models/spartan/spartan.obj"; + auto spartan = addObject(new Model("spartan", spartanPath.c_str())); spartan->getTransform().setTranslation(-4.0f, 0.0f, 0.0f); auto mesh = addObject( - new Qtk::MeshRenderer("rightTriangle", Triangle(QTK_DRAW_ARRAYS))); + new Qtk::MeshRenderer("rightTriangle", Triangle(QTK_DRAW_ELEMENTS))); mesh->getTransform().setTranslation(-5.0f, 0.0f, -2.0f); // QTK_DRAW_ARRAYS is the default for generic shapes in qtk/shape.h @@ -56,11 +56,17 @@ void ExampleScene::init() { mesh->setColor(GREEN); } -void ExampleScene::draw() { +void ExampleScene::draw() +{ + // No custom draw logic for this example. Scene::draw(); } -void ExampleScene::update() { +void ExampleScene::update() +{ + auto top_triangle = MeshRenderer::getInstance("topTriangle"); + auto bottom_triangle = MeshRenderer::getInstance("bottomTriangle"); + // Pitch forward and roll sideways MeshRenderer::getInstance("leftTriangle") ->getTransform() @@ -69,29 +75,21 @@ void ExampleScene::update() { ->getTransform() .rotate(0.75f, 0.0f, 0.0f, 1.0f); + // Make the top and bottom triangles slide left-to-right. static float translateX = 0.025f; float limit = -9.0f; // Origin position.x - 2.0f - float posX = MeshRenderer::getInstance("topTriangle") - ->getTransform() - .getTranslation() - .x(); - if(posX < limit || posX > limit + 4.0f) { + float posX = top_triangle->getTransform().getTranslation().x(); + if (posX < limit || posX > limit + 4.0f) { translateX = -translateX; } - MeshRenderer::getInstance("topTriangle") - ->getTransform() - .translate(translateX, 0.0f, 0.0f); - MeshRenderer::getInstance("bottomTriangle") - ->getTransform() - .translate(-translateX, 0.0f, 0.0f); - MeshRenderer::getInstance("topTriangle") - ->getTransform() - .rotate(0.75f, 0.2f, 0.0f, 0.4f); - MeshRenderer::getInstance("bottomTriangle") - ->getTransform() - .rotate(0.75f, 0.0f, 0.2f, 0.4f); - MeshRenderer::getInstance("centerCube") - ->getTransform() + top_triangle->getTransform().translate(translateX, 0.0f, 0.0f); + bottom_triangle->getTransform().translate(-translateX, 0.0f, 0.0f); + + // Apply some rotation to the triangles as they move left-to-right. + top_triangle->getTransform().rotate(0.75f, 0.2f, 0.0f, 0.4f); + bottom_triangle->getTransform().rotate(0.75f, 0.0f, 0.2f, 0.4f); + + MeshRenderer::getInstance("centerCube")->getTransform() .rotate(0.75f, 0.2f, 0.4f, 0.6f); } diff --git a/example-app/examplescene.h b/example-app/examplescene.h index e218341..875c6cb 100644 --- a/example-app/examplescene.h +++ b/example-app/examplescene.h @@ -11,16 +11,29 @@ #include -class ExampleScene : public Qtk::SceneInterface { +class ExampleScene : public Qtk::Scene { public: - explicit ExampleScene(Qtk::Scene * scene); + explicit ExampleScene(); ~ExampleScene(); + /** + * Override the initialization logic for the scene. + * This method should up the scene's objects, skybox, etc. + */ void init() override; + /** + * Optionally override the draw method for the scene. + * + * This is just here for example, it should be omitted entirely if we don't + * want to provide a custom implementation for the ExampleScene. + */ void draw() override; + /** + * Update objects in the scene for translation or rotation. + */ void update() override; }; diff --git a/example-app/examplewidget.cpp b/example-app/examplewidget.cpp index fc5a97b..86304f7 100644 --- a/example-app/examplewidget.cpp +++ b/example-app/examplewidget.cpp @@ -11,7 +11,7 @@ #include "examplewidget.h" ExampleWidget::ExampleWidget(QWidget * parent) : - QOpenGLWidget(parent), mScene(new ExampleScene(new Qtk::SceneEmpty)) { + QOpenGLWidget(parent), mScene(new ExampleScene) { // NOTE: The decorator pattern is used to save / load scenes in Qtk currently. // The initializer above sets mScene to the concrete decorator ExampleScene. // Qtk::SceneEmpty provides an empty scene as the concrete component. diff --git a/src/qtk/scene.cpp b/src/qtk/scene.cpp index b107c94..62a0bfc 100644 --- a/src/qtk/scene.cpp +++ b/src/qtk/scene.cpp @@ -58,6 +58,8 @@ void Scene::draw() { mInit = true; } + // Check if there were new models added that still need to be loaded. + // This is for objects added at runtime via click-and-drag events, etc. while(!mModelLoadQueue.empty()) { auto modelSpec = mModelLoadQueue.front(); // Load the model and add it to the scene. diff --git a/src/qtk/scene.h b/src/qtk/scene.h index 6abd403..0ff42b8 100644 --- a/src/qtk/scene.h +++ b/src/qtk/scene.h @@ -53,7 +53,7 @@ namespace Qtk { Scene(); - virtual ~Scene(); + ~Scene() override; /************************************************************************* * Public Methods @@ -73,10 +73,13 @@ namespace Qtk { /** * Function called to update the QOpenGLWidget. Does not trigger a redraw. - * + * This method can translate or rotate objects to simulate movement. * Calling this several times will still result in only one repaint. + * + * It's very possible a client will not want to move objects in the scene + * using this method. This is intentially not pure virtual. */ - virtual void update() {} + virtual void update() { } void loadModel(const QUrl & url) { auto fileName = url.fileName().replace(".obj", "").toStdString(); @@ -239,30 +242,6 @@ namespace Qtk { /* Track count of objects with same initial name. */ std::unordered_map mObjectCount; }; - - class SceneEmpty : public Scene { - public: - void init() override { setSceneName("Empty Scene"); } - - void draw() override { Scene::draw(); } - - void update() override { Scene::update(); } - }; - - class SceneInterface : public Scene { - public: - explicit SceneInterface(Scene * scene) : mScene(scene) {} - - void init() override { mScene->init(); } - - void draw() override { mScene->draw(); } - - void update() override { mScene->update(); } - - protected: - Scene * mScene; - }; - } // namespace Qtk #endif // QTK_SCENE_H