Solved 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.htmlExcept 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.