N
N
Nikita Savinykh2019-12-13 15:14:11
Qt
Nikita Savinykh, 2019-12-13 15:14:11

How to organize the storage of elements so that some can be referred to by name?

Hello.
There are a number of objects - 3D objects (class Object3D), Lines (Line_3D), Skyboxes (Skybox) and so on.
Let's say they are inherited from the Drawable class, which looks like this:

class Drawable{
public:
    virtual void draw(QOpenGLFunctions * functions, Camera * camera, QMatrix4x4 projection_matrix) = 0;
};

This makes it possible to create a render queue, and use the following construct in the openGL loop:
// Где-то вне цикла отрисовки
   QList<Drawable *> drawQueue;

   // ...

void WidgetGL::paintGL() {

    foreach (Drawable drawable, objList)
        drawable.draw(context()->functions(),&_camera,m_projectionMatrix);

}

Good.
Now consider the situation.
We have 3 lines that form the basis, which is located at the point O(0;0;0)
Line_3D * ox = new Line_3D(QVector3D(0.0,0.0,0.0),QVector3D(1.0,0.0,0.0),QVector3D(1.0,0.0,0.0));
    Line_3D * oy = new Line_3D(QVector3D(0.0,0.0,0.0),QVector3D(0.0,1.0,0.0),QVector3D(0.0,1.0,0.0));
    Line_3D * oz = new Line_3D(QVector3D(0.0,0.0,0.0),QVector3D(0.0,0.0,1.0),QVector3D(0.0,0.0,1.0));

    drawQueue.append(dynamic_cast<Drawable*>(ox));
    drawQueue.append(dynamic_cast<Drawable*>(oy));
    drawQueue.append(dynamic_cast<Drawable*>(oz));

Before these 3 lines were added to the drawQueue sheet, an arbitrary number of both Line_3D and Object3D objects were added to this sheet.
Now a synthetic example:
At some point it was necessary to refer to one of the basis lines, but this is completely impossible if we do not we know the index under which this line was added to drawQueue.
What solutions to the problem can be?
Now I have created an additional class SceneComponents to store all the objects:
class SceneComponents : public QObject
{
    Q_OBJECT
public:
    explicit SceneComponents(QObject *parent = nullptr);

    void addDrawable(Drawable * drawable);
    QList<Drawable *> getDrawQueue() const;

private:
    QList<Drawable *> drawQueue;

    QList<Object3D *> _object3dList;
    QList<Line_3D *> _line3dList;
    QList<Skybox *> _skyboxList;
    QList<Ray *> _rayList;

};

A few basic ideas I have about this:
1) Create a name field for the Drawable class, or inherit Line_3D, Skybox, Object3D and Ray from QObject - and use objectName and setObjectName.
A very controversial way, because to search for an object, you will have to iterate through all the objects in one of the sheets ( _object3dList, _line3dList, ... )
2) Use QMap, in which, if necessary, a pointer to an object of the Drawable class will be added, use QString as a key:
class SceneComponents : public QObject
{
    Q_OBJECT
public:
    explicit SceneComponents(QObject *parent = nullptr);

    void addDrawable(Drawable * drawable);
    QList<Drawable *> getDrawQueue() const;

private:
    QList<Drawable *> drawQueue;

    QList<Object3D *> _object3dList;
    QList<Line_3D *> _line3dList;
    QList<Skybox *> _skyboxList;
    QList<Ray *> _rayList;

   QMap<QString,Drawable*> _objectByName;
};

I like this method more, but then if any object is deleted (delete is called), it will be necessary to update the rest of the lists of the object of the SceneComponents class (after all, no one wants to call the draw method on an object that has been deleted)
Why not use only QMap instead of QList?
Because not all objects will need names. This means that not all objects are supposed to have a name, which also needs to be taken into account.

Answer the question

In order to leave comments, you need to log in

1 answer(s)
I
Ighor July, 2019-12-27
@Ukio_G

And you QMap<QString,Drawable*> _objectByName;replace with QMap<Drawable*, QString> _objectByName;
Then the name can be empty, and you can get the object by name through the key (..) method

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question