Qt3D adding custom geometry from arrays & creating entities?



  • Hey !

    Well, this is exciting, long story short, I implemented FBX library in my CPP application - imported arrays of vertexes[],normals[],faceIndices[] and more to get mesh data. I then passed it to a raytracer library and wuaila it renders! Now the time has come to pass the same data to 3d renderer for user - quick feedback & synchronize camera/views/geometry/everything else. From what I can see I sadly can't use the existing arrays of data to share between the 2 engines so I have to copy all vertex/etc(boo ) - or I'm wrong? In any case, I started to read on how to import custom meshes into Qt3D. Oh boy, thats a read... in any case I noticed there are quite a few "versions" of qt3D older, never etc. I got a little lost. So to start it clear I used this amazing example > https://vicrucann.github.io/tutorials/qt3d-cmake/ to start with (by the way I'm QtWidgets guy, no qml here ), once I got that in I started dropping in this example > https://github.com/qt/qt3d/commit/891ef957f9d0a2890d4917649eb48ab5d17634ab

    The resulting code is something like this (scroll below)

    Now what I hit a wall with is the new/old naming...
    What are the new calls for these functions? :
    //positionAttribute->setType(GL_FLOAT_VEC3);
    //positionAttribute->setName(Qt3DRender::QMeshData::defaultPositionAttributeName());
    And how to create new "node/mesh/QtEntity" that can house mesh data that then I attached to another node that goes inside the render engine? I take the engine is a "treeView" that I add to it/or to its children to build up tree?

    Thanks in advance for help!

    #include <iostream>
    #include <QGuiApplication>
    
    #include <Qt3DCore/QEntity>
    #include <Qt3DCore/QTransform>
    #include <Qt3DCore/QAspectEngine>
    
    #include <Qt3DRender/qrenderaspect.h>
    #include <Qt3DRender/QCamera>
    #include <Qt3DRender/QMaterial>
    
    #include <Qt3DExtras/Qt3DWindow>
    #include <Qt3DExtras/QTorusMesh>
    #include <Qt3DExtras/QOrbitCameraController>
    #include <Qt3DExtras/QPhongMaterial>
    #include <Qt3DRender/qbuffer.h>
    
    
    #include <Qt3DRender>
    
    #include "quadMesh.h"
    
    Qt3DCore::QEntity *createTestScene() {
       Qt3DCore::QEntity *root = new Qt3DCore::QEntity;
       Qt3DCore::QEntity *torus = new Qt3DCore::QEntity(root);
    
       Qt3DExtras::QTorusMesh *mesh = new Qt3DExtras::QTorusMesh;
    
       mesh->setRadius(5);
       mesh->setMinorRadius(1);
       mesh->setRings(100);
       mesh->setSlices(20);
    
       Qt3DCore::QTransform *transform = new Qt3DCore::QTransform;
    //    transform->setScale3D(QVector3D(1.5, 1, 0.5));
       transform->setRotation(QQuaternion::fromAxisAndAngle(QVector3D(1, 0, 0), 45.f));
    
       Qt3DRender::QMaterial *material = new Qt3DExtras::QPhongMaterial(root);
    
       torus->addComponent(mesh);
       torus->addComponent(transform);
       torus->addComponent(material);
    
    
    
    
       Qt3DCore::QEntity *mePyramide = new Qt3DCore::QEntity(root);
    
       QtSomething::Node? *myMesh = new Mesh?
       // add my pyramide object here for mesh ?
    
       Qt3DRender::QGeometryRenderer *customMeshRenderer = new Qt3DRender::QGeometryRenderer;
       Qt3DRender::QGeometry *customGeometry = new Qt3DRender::QGeometry(myMesh );
    
       Qt3DRender::QBuffer *vertexDataBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::VertexBuffer, customGeometry);
       Qt3DRender::QBuffer *indexDataBuffer = new Qt3DRender::QBuffer(Qt3DRender::QBuffer::IndexBuffer, customGeometry);
       QByteArray vertexBufferData;
       vertexBufferData.resize(4 * (3 + 3 + 3) * sizeof(float));
    
       // Vertices
       QVector3D v0(-1.0f, 0.0f, -1.0f);
       QVector3D v1(1.0f, 0.0f, -1.0f);
       QVector3D v2(0.0f, 1.0f, 0.0f);
       QVector3D v3(0.0f, 0.0f, 1.0f);
    
       // Faces Normals
       QVector3D n023 = QVector3D::normal(v0, v2, v3);
       QVector3D n012 = QVector3D::normal(v0, v1, v2);
       QVector3D n310 = QVector3D::normal(v3, v1, v0);
       QVector3D n132 = QVector3D::normal(v1, v3, v2);
    
       // Vector Normals
       QVector3D n0 = QVector3D(n023 + n012 + n310).normalized();
       QVector3D n1 = QVector3D(n132 + n012 + n310).normalized();
       QVector3D n2 = QVector3D(n132 + n012 + n023).normalized();
       QVector3D n3 = QVector3D(n132 + n310 + n023).normalized();
    
       // Colors
       QVector3D red(1.0f, 0.0f, 0.0f);
       QVector3D green(0.0f, 1.0f, 0.0f);
       QVector3D blue(0.0f, 0.0f, 1.0f);
       QVector3D white(1.0f, 1.0f, 1.0f);
    
       QVector<QVector3D> vertices = QVector<QVector3D>()
               << v0 << n0 << red
               << v1 << n1 << blue
               << v2 << n2 << green
               << v3 << n3 << white;
    
       float *rawVertexArray = reinterpret_cast<float *>(vertexBufferData.data());
       int idx = 0;
    
    
       Q_FOREACH (const QVector3D &v, vertices) {
               rawVertexArray[idx++] = v.x();
               rawVertexArray[idx++] = v.y();
               rawVertexArray[idx++] = v.z();
           }
    
       // Indices (12)
       QByteArray indexBufferData;
       indexBufferData.resize(4 * 3 * sizeof(ushort));
       ushort *rawIndexArray = reinterpret_cast<ushort *>(indexBufferData.data());
    
       // Front
       rawIndexArray[0] = 0;
       rawIndexArray[1] = 1;
       rawIndexArray[2] = 2;
       // Bottom
       rawIndexArray[3] = 3;
       rawIndexArray[4] = 1;
       rawIndexArray[5] = 0;
       // Left
       rawIndexArray[6] = 0;
       rawIndexArray[7] = 2;
       rawIndexArray[8] = 3;
       // Right
       rawIndexArray[9] = 1;
       rawIndexArray[10] = 3;
       rawIndexArray[11] = 2;
    
       vertexDataBuffer->setData(vertexBufferData);
       indexDataBuffer->setData(indexBufferData);
    
       Qt3DRender::QAttribute *positionAttribute = new Qt3DRender::QAttribute();
       positionAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
       positionAttribute->setBuffer(vertexDataBuffer);
       //positionAttribute->setType(GL_FLOAT_VEC3);
       positionAttribute->setByteOffset(0);
       positionAttribute->setByteStride(9 * sizeof(float));
       positionAttribute->setCount(4);
       //positionAttribute->setName(Qt3DRender::QMeshData::defaultPositionAttributeName());
    
       Qt3DRender::QAttribute *normalAttribute = new Qt3DRender::QAttribute();
       normalAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
       normalAttribute->setBuffer(vertexDataBuffer);
       //normalAttribute->setType(GL_FLOAT_VEC3);
       normalAttribute->setByteOffset(3 * sizeof(float));
       normalAttribute->setByteStride(9 * sizeof(float));
       normalAttribute->setCount(4);
       //normalAttribute->setName(Qt3DRender::QMeshData::defaultNormalAttributeName());
    
       Qt3DRender::QAttribute *colorAttribute = new Qt3DRender::QAttribute();
       colorAttribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);
       colorAttribute->setBuffer(vertexDataBuffer);
       //colorAttribute->setType(GL_FLOAT_VEC3);
       colorAttribute->setByteOffset(6 * sizeof(float));
       colorAttribute->setByteStride(9 * sizeof(float));
       colorAttribute->setCount(4);
       //colorAttribute->setName(Qt3DRender::QMeshData::defaultColorAttributeName());
    
       Qt3DRender::QAttribute *indexAttribute = new Qt3DRender::QAttribute();
       indexAttribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute);
       indexAttribute->setBuffer(indexDataBuffer);
       //colorAttribute->setType(GL_UNSIGNED_SHORT);
       colorAttribute->setByteOffset(0);
       colorAttribute->setByteStride(0);
       colorAttribute->setCount(12);
    
       customGeometry->addAttribute(positionAttribute);
       customGeometry->addAttribute(normalAttribute);
       customGeometry->addAttribute(colorAttribute);
       customGeometry->addAttribute(indexAttribute);
    
       customMeshRenderer->setGeometry(customGeometry);
    
       myPyramide->addComponent(myMesh );
       myPyramide->addComponent(transform);
       myPyramide->addComponent(material);
    
    
       root->addComponent(myPyramide);
    
       return root;
    }
    
    
    int main(int argc, char *argv[]) {
    
       //qmlRegisterType<quadMesh>("de.wplm.mesh", 1, 0, "QuadMesh");
       //qRegisterMetaType<quadMesh>("de.wplm.mesh", 1, 0, "QuadMesh")
    
       QGuiApplication app(argc, argv);
       Qt3DExtras::Qt3DWindow view;
       Qt3DCore::QEntity *scene = createTestScene();
    
       // camera
       Qt3DRender::QCamera *camera = view.camera();
       camera->lens()->setPerspectiveProjection(45.0f, 16.0f / 9.0f, 0.1f, 1000.0f);
       camera->setPosition(QVector3D(0, 0, 40.0f));
       camera->setViewCenter(QVector3D(0, 0, 0));
    
       // manipulator
       Qt3DExtras::QOrbitCameraController *manipulator = new Qt3DExtras::QOrbitCameraController(scene);
       manipulator->setLinearSpeed(50.f);
       manipulator->setLookSpeed(180.f);
       manipulator->setCamera(camera);
    
       view.setRootEntity(scene);
       view.show();
    
       return app.exec();
    }
    
    


  • Wops got sorta lucky, found out updated part of the triangle part:
    https://code.woboq.org/qt5/qt3d/tests/manual/custom-mesh-cpp-indirect/main.cpp.html

    Except that triangle normals are flipped and messed up ;- )

    humh the longer I look at it the less I like it, I think this is old/outdated way of adding meshes to the scene. Just by going here https://doc.qt.io/qt-5.10/qt3drender-qbuffer-obsolete.html we can see that they marked the 2 buffers we made as absolute. So I'm fairly sure this is NOT the way to do it.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.