Compare commits
	
		
			3 Commits
		
	
	
		
			16baf6cdaf
			...
			8dc5d82c8d
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 8dc5d82c8d | |||
| 78639cf1c2 | |||
| 941f2d228c | 
							
								
								
									
										60
									
								
								README.md
									
									
									
									
									
								
							
							
						
						@ -3,45 +3,59 @@
 | 
			
		||||
[](https://github.com/shaunrd0/qtk/actions/workflows/all-builds.yml)
 | 
			
		||||
[](https://github.com/shaunrd0/qtk/actions/workflows/linting.yml)
 | 
			
		||||
 | 
			
		||||
Qtk is a Qt OpenGL graphics library created primarily for my own learning
 | 
			
		||||
purposes. The library wraps some QOpenGL functionality in convenience classes
 | 
			
		||||
Qtk is a Qt OpenGL graphics library that wraps some QOpenGL functionality in convenience classes
 | 
			
		||||
that allow rendering geometry in 2D and 3D using custom GLSL shader programs.
 | 
			
		||||
 | 
			
		||||
The Qtk desktop application provides a model loader using [Assimp](https://assimp.org/) within a Qt widget application.
 | 
			
		||||
You can fly around the scene using WASD while holding down the right mouse button.
 | 
			
		||||
 | 
			
		||||
Object names can be double-clicked in the tree view panel for quick camera navigation.
 | 
			
		||||
Properties of the object, like shader code and translation / scale, can be viewed and modified in the side panel.
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
All side panels and toolbars are dockable widgets that can be popped out
 | 
			
		||||
and reorganized as needed. Panels can also be stacked to create a docked widget with
 | 
			
		||||
tabs. The central widget that provides the camera view into the scene cannot be
 | 
			
		||||
detached from the main window in this way.
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
The small triangles floating near 3D models represent the light source being used for the shader.
 | 
			
		||||
These appear on models using phong, specular, and diffuse lighting techniques.
 | 
			
		||||
 | 
			
		||||
The default scene contains basic examples like texture mapping to make a crate from basic cube geometry
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
Examples of Ambient, Diffuse, and Specular GLSL shaders.
 | 
			
		||||
 | 
			
		||||
| Ambient                                               | Diffuse                                               | Specular                                               |
 | 
			
		||||
|-------------------------------------------------------|-------------------------------------------------------|--------------------------------------------------------|
 | 
			
		||||
| <img src="resources/screenshots/screen-ambient.png"/> | <img src="resources/screenshots/screen-diffuse.png"/> | <img src="resources/screenshots/screen-specular.png"/> |
 | 
			
		||||
 | 
			
		||||
And more advanced techniques like Phong lighting (ambient + diffuse + specular) and normal mapping.
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
| Normal Mapping Disabled                              | Normal Mapping Enabled                                 | 
 | 
			
		||||
|------------------------------------------------------|--------------------------------------------------------|
 | 
			
		||||
| <img src="resources/screenshots/spartan-phong.png"/> | <img src="resources/screenshots/spartan-normals.png"/> |
 | 
			
		||||
 | 
			
		||||
See the `View` toolbar menu to enable debug console widgets for open scenes or reopen previously closed panels.
 | 
			
		||||
 | 
			
		||||
Key features that are planned:
 | 
			
		||||
 | 
			
		||||
- [x] Runtime loading of `.obj` or similar 3D models.
 | 
			
		||||
- [x] Drag-and-drop interaction for adding objects to the scene.
 | 
			
		||||
- [x] Shader / object properties panel to modify related settings.
 | 
			
		||||
- [ ] Runtime reloading of modified GLSL shaders attached to objects within scenes.
 | 
			
		||||
- [ ] Multiple views of a scene at one time.
 | 
			
		||||
- [ ] Camera control modes such as panning, orbiting, or following objects.
 | 
			
		||||
- [ ] Save / load for scene data. The current inheritance model is temporary.
 | 
			
		||||
- [ ] Basic text editor for quickly modifying shaders attached to objects.
 | 
			
		||||
- [ ] Shader / object properties panel to modify related settings.
 | 
			
		||||
- [ ] Reduce size of application resources and git references.
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
Spartan with no normals -
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
Spartan with normals -
 | 
			
		||||
 | 
			
		||||

 | 
			
		||||
 | 
			
		||||
Object names can be double-clicked in the tree view panel for quick camera
 | 
			
		||||
navigation. All side panels and toolbars are dockable widgets that can be popped out
 | 
			
		||||
and reorganized as needed. Panels can also be stacked to create a docked widget with
 | 
			
		||||
tabs. The central widget that provides the camera view into the scene cannot be
 | 
			
		||||
detached from the main window in this way. See the `View` menu to enable debug
 | 
			
		||||
console widgets for open scenes or reopen previously closed panels.
 | 
			
		||||
 | 
			
		||||
The small triangles floating near 3D models represent the light source being used for the shader.
 | 
			
		||||
These appear on models using phong, specular, and diffuse lighting techniques.
 | 
			
		||||
 | 
			
		||||
For examples of using the Qtk API, see the `example-app` project in the root of
 | 
			
		||||
this repository.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -46,8 +46,8 @@
 | 
			
		||||
        <file alias="solid-phong.vert">shaders/vertex/solid-phong.vert</file>
 | 
			
		||||
        <file alias="model-basic.frag">shaders/fragment/model-basic.frag</file>
 | 
			
		||||
        <file alias="model-basic.vert">shaders/vertex/model-basic.vert</file>
 | 
			
		||||
        <file alias="model-specular.frag">shaders/fragment/model-specular.frag</file>
 | 
			
		||||
        <file alias="model-specular.vert">shaders/vertex/model-specular.vert</file>
 | 
			
		||||
        <file alias="model-phong.frag">shaders/fragment/model-phong.frag</file>
 | 
			
		||||
        <file alias="model-phong.vert">shaders/vertex/model-phong.vert</file>
 | 
			
		||||
        <file alias="model-normals.frag">shaders/fragment/model-normals.frag</file>
 | 
			
		||||
        <file alias="model-normals.vert">shaders/vertex/model-normals.vert</file>
 | 
			
		||||
        <file alias="skybox.frag">skybox/skybox.frag</file>
 | 
			
		||||
 | 
			
		||||
| 
		 Before Width: | Height: | Size: 316 KiB  | 
| 
		 Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 30 KiB  | 
| 
		 Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 89 KiB  | 
| 
		 Before Width: | Height: | Size: 263 KiB After Width: | Height: | Size: 263 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/screenshots/screen-1.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 428 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/screenshots/screen-ambient.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 205 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/screenshots/screen-diffuse.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 188 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/screenshots/screen-phong.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 264 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/screenshots/screen-specular.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 176 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/screenshots/screen-texture.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 288 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/screenshots/screen.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 437 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/screenshots/spartan-normals.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 359 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								resources/screenshots/spartan-phong.png
									
									
									
									
									
										Normal file
									
								
							
							
						
						| 
		 After Width: | Height: | Size: 349 KiB  | 
| 
		 Before Width: | Height: | Size: 660 KiB  | 
| 
		 Before Width: | Height: | Size: 646 KiB  | 
@ -9,8 +9,6 @@
 | 
			
		||||
#include "qtkmainwindow.h"
 | 
			
		||||
#include "ui_qtkmainwindow.h"
 | 
			
		||||
 | 
			
		||||
MainWindow * MainWindow::mainWindow_ = Q_NULLPTR;
 | 
			
		||||
 | 
			
		||||
/*******************************************************************************
 | 
			
		||||
 * Constructors / Destructors
 | 
			
		||||
 ******************************************************************************/
 | 
			
		||||
@ -27,6 +25,10 @@ MainWindow::MainWindow(QWidget * parent) : QMainWindow(parent)
 | 
			
		||||
  // Initialize static container for all active QtkWidgets
 | 
			
		||||
  auto qtkWidgets = findChildren<Qtk::QtkWidget *>();
 | 
			
		||||
  for (auto & qtkWidget : qtkWidgets) {
 | 
			
		||||
    // NOTE: Set a temporary scene for the widget to use for initialization.
 | 
			
		||||
    // This should be replaced by loading a scene, or creating a new (unsaved)
 | 
			
		||||
    // scene when Qtk is opened.
 | 
			
		||||
    qtkWidget->setScene(new EmptyScene);
 | 
			
		||||
    views_.emplace(qtkWidget->getScene()->getSceneName(), qtkWidget);
 | 
			
		||||
 | 
			
		||||
    // Add GUI 'view' toolbar option to show debug console.
 | 
			
		||||
@ -36,8 +38,7 @@ MainWindow::MainWindow(QWidget * parent) : QMainWindow(parent)
 | 
			
		||||
            &Qtk::Scene::sceneUpdated,
 | 
			
		||||
            this,
 | 
			
		||||
            &MainWindow::refreshScene);
 | 
			
		||||
    connect(qtkWidget,
 | 
			
		||||
            &Qtk::QtkWidget::objectFocusChanged,
 | 
			
		||||
    connect(qtkWidget, &Qtk::QtkWidget::objectFocusChanged,
 | 
			
		||||
            ui_->qtk__ToolBox,
 | 
			
		||||
            &Qtk::ToolBox::updateFocus);
 | 
			
		||||
  }
 | 
			
		||||
@ -70,10 +71,8 @@ MainWindow::~MainWindow()
 | 
			
		||||
 | 
			
		||||
MainWindow * MainWindow::getMainWindow()
 | 
			
		||||
{
 | 
			
		||||
  if (mainWindow_ == Q_NULLPTR) {
 | 
			
		||||
    mainWindow_ = new MainWindow;
 | 
			
		||||
  }
 | 
			
		||||
  return mainWindow_;
 | 
			
		||||
  static MainWindow window;
 | 
			
		||||
  return &window;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Qtk::QtkWidget * MainWindow::getQtkWidget(int64_t index)
 | 
			
		||||
 | 
			
		||||
@ -22,6 +22,38 @@ namespace Ui
 | 
			
		||||
  class MainWindow;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * An empty scene used for initializing all QtkWidgets within the MainWindow.
 | 
			
		||||
 * This serves as a temporary placeholder for QtkScene (for example), which is
 | 
			
		||||
 * defined in the separate qtk_gui target. The reason for this separation is to
 | 
			
		||||
 * support the use of QtkWidgets (the qtk_plugins target) within the Qt Designer
 | 
			
		||||
 * application without implementations provided in the Qtk Desktop Application.
 | 
			
		||||
 *
 | 
			
		||||
 * For the Qtk application, this should be replaced by loading the previous
 | 
			
		||||
 * scene or creating a new _unsaved_ scene when the application is opened.
 | 
			
		||||
 * Currently we have essentially hard-coded QtkScene to use as examples for
 | 
			
		||||
 * testing the application. This means that the only way to create or modify a
 | 
			
		||||
 * scene is to write code. Any modifications made in the application, such as
 | 
			
		||||
 * moving or resizing objects, will not persist and cannot be saved.
 | 
			
		||||
 *
 | 
			
		||||
 * For users of Qtk Designer Plugins, this means that installing
 | 
			
		||||
 * the `qtk_plugins` target to Qt Designer allows use all of the designer's
 | 
			
		||||
 * features to build an interface and position or resize a QtkWidget as needed.
 | 
			
		||||
 * The QtkWidget also appears as widget in the IDE's toolbars and can be added
 | 
			
		||||
 * to any new application easily, once the plugins are installed.
 | 
			
		||||
 *
 | 
			
		||||
 * Once the application is designed, you can define a custom scene and use the
 | 
			
		||||
 * Qtk API or Qt OpenGL funtions directly to render to it.
 | 
			
		||||
 *
 | 
			
		||||
 * Any application using a QtkWidget can set a custom scene in their main
 | 
			
		||||
 * function. See the MainWindow::MainWindow constructor as an example.
 | 
			
		||||
 */
 | 
			
		||||
class EmptyScene : public Qtk::Scene {
 | 
			
		||||
  void init() override {
 | 
			
		||||
    setSceneName("Empty Scene");
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * MainWindow class to provide an example of using a QtkWidget within a Qt
 | 
			
		||||
 * window application.
 | 
			
		||||
@ -82,7 +114,6 @@ class MainWindow : public QMainWindow
 | 
			
		||||
    MainWindow(const MainWindow &) {};
 | 
			
		||||
 | 
			
		||||
    Ui::MainWindow * ui_ {};
 | 
			
		||||
    static MainWindow * mainWindow_;
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Maps a scene name to the QtkWidget viewing it.
 | 
			
		||||
 | 
			
		||||
@ -114,7 +114,7 @@ void QtkScene::init()
 | 
			
		||||
  // Simple cube lighting examples.
 | 
			
		||||
 | 
			
		||||
  /* Phong lighting example on a basic cube. */
 | 
			
		||||
  mTestPhong = new Qtk::MeshRenderer("phong", Qtk::Cube());
 | 
			
		||||
  mTestPhong = addObject(new Qtk::MeshRenderer("phongCube", Qtk::Cube()));
 | 
			
		||||
  mTestPhong->getTransform().setTranslation(3.0f, 0.0f, -2.0f);
 | 
			
		||||
  // NOTE: You no longer need to manually bind shader program to set uniforms.
 | 
			
		||||
  // + You can still bind it if you want to for performance reasons.
 | 
			
		||||
@ -152,7 +152,7 @@ void QtkScene::init()
 | 
			
		||||
  // No light source needed for this lighting technique
 | 
			
		||||
 | 
			
		||||
  /* Initialize Ambient example cube */
 | 
			
		||||
  mTestAmbient = new Qtk::MeshRenderer("ambient", Cube());
 | 
			
		||||
  mTestAmbient = addObject(new Qtk::MeshRenderer("ambientCube", Cube()));
 | 
			
		||||
  mTestAmbient->getTransform().setTranslation(7.0f, 0.0f, -2.0f);
 | 
			
		||||
  mTestAmbient->setShaders(":/shaders/solid-ambient.vert",
 | 
			
		||||
                           ":/shaders/solid-ambient.frag");
 | 
			
		||||
@ -164,7 +164,7 @@ void QtkScene::init()
 | 
			
		||||
  // No light source needed for this lighting technique
 | 
			
		||||
 | 
			
		||||
  /* Initialize Diffuse example cube */
 | 
			
		||||
  mTestDiffuse = new Qtk::MeshRenderer("diffuse", Cube());
 | 
			
		||||
  mTestDiffuse = addObject(new Qtk::MeshRenderer("diffuseCube", Cube()));
 | 
			
		||||
  mTestDiffuse->getTransform().setTranslation(9.0f, 0.0f, -2.0f);
 | 
			
		||||
  mTestDiffuse->setShaders(":/shaders/solid-diffuse.vert",
 | 
			
		||||
                           ":/shaders/solid-diffuse.frag");
 | 
			
		||||
@ -180,7 +180,7 @@ void QtkScene::init()
 | 
			
		||||
  mesh->getTransform().scale(0.25f);
 | 
			
		||||
 | 
			
		||||
  /* Initialize Specular example cube */
 | 
			
		||||
  mTestSpecular = new Qtk::MeshRenderer("specular", Cube());
 | 
			
		||||
  mTestSpecular = addObject(new Qtk::MeshRenderer("specularCube", Cube()));
 | 
			
		||||
  mTestSpecular->getTransform().setTranslation(11.0f, 0.0f, -2.0f);
 | 
			
		||||
  mTestSpecular->setShaders(":/shaders/solid-specular.vert",
 | 
			
		||||
                            ":/shaders/solid-specular.frag");
 | 
			
		||||
@ -233,8 +233,8 @@ void QtkScene::init()
 | 
			
		||||
  /* Test alien Model with phong lighting and specular mapping. */
 | 
			
		||||
  model = addObject(new Qtk::Model("alienTest",
 | 
			
		||||
                                   ":/models/models/alien-hominid/alien.obj",
 | 
			
		||||
                                   ":/shaders/model-specular.vert",
 | 
			
		||||
                                   ":/shaders/model-specular.frag"));
 | 
			
		||||
                                   ":/shaders/model-phong.vert",
 | 
			
		||||
                                   ":/shaders/model-phong.frag"));
 | 
			
		||||
  model->getTransform().setTranslation(3.0f, -1.0f, 10.0f);
 | 
			
		||||
  model->getTransform().scale(0.15f);
 | 
			
		||||
  model->setUniform("uMaterial.ambient", QVector3D(1.0f, 1.0f, 1.0f));
 | 
			
		||||
@ -242,7 +242,7 @@ void QtkScene::init()
 | 
			
		||||
  model->setUniform("uMaterial.specular", QVector3D(1.0f, 1.0f, 1.0f));
 | 
			
		||||
  model->setUniform("uMaterial.ambientStrength", 0.8f);
 | 
			
		||||
  model->setUniform("uMaterial.diffuseStrength", 0.8f);
 | 
			
		||||
  model->setUniform("uMaterial.specularStrength", 1.0f);
 | 
			
		||||
  model->setUniform("uMaterial.specularStrength", 0.5f);
 | 
			
		||||
  model->setUniform("uMaterial.shine", 32.0f);
 | 
			
		||||
 | 
			
		||||
  model->setUniform("uLight.ambient", QVector3D(1.0f, 1.0f, 1.0f));
 | 
			
		||||
@ -260,8 +260,8 @@ void QtkScene::init()
 | 
			
		||||
  /* Test spartan Model with phong lighting, specular and normal mapping. */
 | 
			
		||||
  model = addObject(new Qtk::Model("spartanTest",
 | 
			
		||||
                                   ":/models/models/spartan/spartan.obj",
 | 
			
		||||
                                   ":/shaders/model-normals.vert",
 | 
			
		||||
                                   ":/shaders/model-normals.frag"));
 | 
			
		||||
                                   ":/shaders/model-phong.vert",
 | 
			
		||||
                                   ":/shaders/model-phong.frag"));
 | 
			
		||||
  model->getTransform().setTranslation(0.0f, -1.0f, 10.0f);
 | 
			
		||||
  model->getTransform().scale(2.0f);
 | 
			
		||||
  model->setUniform("uMaterial.ambient", QVector3D(1.0f, 1.0f, 1.0f));
 | 
			
		||||
 | 
			
		||||
@ -41,36 +41,33 @@ void Qtk::TreeView::updateView(const Qtk::Scene * scene)
 | 
			
		||||
  mSceneName = scene->getSceneName();
 | 
			
		||||
  auto objects = scene->getObjects();
 | 
			
		||||
  for (const auto & object : objects) {
 | 
			
		||||
    auto item =
 | 
			
		||||
        new QTreeWidgetItem(QStringList(QString(object->getName().c_str())));
 | 
			
		||||
    ui->treeWidget->insertTopLevelItem(0, item);
 | 
			
		||||
    QStringList list(QStringList(QString(object->getName().c_str())));
 | 
			
		||||
    ui->treeWidget->insertTopLevelItem(0, new QTreeWidgetItem(list));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Qtk::TreeView::itemFocus(QTreeWidgetItem * item, int column)
 | 
			
		||||
{
 | 
			
		||||
  QString name = item->text(column);
 | 
			
		||||
  const QString & name = item->text(column);
 | 
			
		||||
  auto scene = MainWindow::getMainWindow()->getQtkWidget()->getScene();
 | 
			
		||||
  auto & transform = Qtk::Scene::getCamera().getTransform();
 | 
			
		||||
  auto object = scene->getObject(name);
 | 
			
		||||
  Transform3D * objectTransform;
 | 
			
		||||
  // If the object is a mesh or model, focus the camera on it.
 | 
			
		||||
  if (object == Q_NULLPTR) {
 | 
			
		||||
    qDebug() << "Attempt to get non-existing object with name '" << name
 | 
			
		||||
             << "'\n";
 | 
			
		||||
  } else if (object->getType() == Object::QTK_MESH) {
 | 
			
		||||
    objectTransform = &dynamic_cast<MeshRenderer *>(object)->getTransform();
 | 
			
		||||
  } else if (object->getType() == Object::QTK_MODEL) {
 | 
			
		||||
    objectTransform = &dynamic_cast<Model *>(object)->getTransform();
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  auto focusScale = objectTransform->getScale();
 | 
			
		||||
  const Transform3D& objectTransform = object->getTransform();
 | 
			
		||||
 | 
			
		||||
  auto & camera_transform = Qtk::Scene::getCamera().getTransform();
 | 
			
		||||
  auto focusScale = objectTransform.getScale();
 | 
			
		||||
  float width = focusScale.x() / 2.0f;
 | 
			
		||||
  float height = focusScale.y() / 2.0f;
 | 
			
		||||
  QVector3D pos = objectTransform->getTranslation();
 | 
			
		||||
  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);
 | 
			
		||||
  camera_transform.setTranslation(pos);
 | 
			
		||||
  camera_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);
 | 
			
		||||
 | 
			
		||||
@ -111,6 +111,11 @@ namespace Qtk
 | 
			
		||||
        return mTransform;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      [[nodiscard]] inline virtual Transform3D & getTransform()
 | 
			
		||||
      {
 | 
			
		||||
        return mTransform;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      [[nodiscard]] inline virtual std::string getVertexShader() const
 | 
			
		||||
      {
 | 
			
		||||
        return "Base Object has no vertex shader.";
 | 
			
		||||
 | 
			
		||||
@ -118,11 +118,9 @@ void Scene::setSkybox(Skybox * skybox)
 | 
			
		||||
 | 
			
		||||
void Scene::initSceneObjectName(Object * object)
 | 
			
		||||
{
 | 
			
		||||
  if (!mObjectCount.count(object->getName())) {
 | 
			
		||||
    mObjectCount[object->getName()] = 1;
 | 
			
		||||
  } else {
 | 
			
		||||
    mObjectCount[object->getName()]++;
 | 
			
		||||
  }
 | 
			
		||||
  mObjectCount[object->getName()] = mObjectCount.count(object->getName()) + 1;
 | 
			
		||||
 | 
			
		||||
  // If the object exists make it's name unique.
 | 
			
		||||
  auto count = mObjectCount[object->getName()];
 | 
			
		||||
  if (count > 1) {
 | 
			
		||||
    object->setName(object->getName() + " (" + std::to_string(count) + ")");
 | 
			
		||||
 | 
			
		||||