Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
212 views
in Technique[技术] by (71.8m points)

c++ - Qt3D Can I list all vertexes from Qt3DRender::QGeometryRenderer?

e.g.

    Qt3DCore::QEntity *sphereEntity = new Qt3DCore::QEntity(rootEntity);
    Qt3DExtras::QSphereMesh *sphereMesh = new Qt3DExtras::QSphereMesh;
    sphereMesh->setRadius(3);

    Qt3DCore::QTransform *sphereTransform = new Qt3DCore::QTransform;
    sphereTransform->setScale(3);

    sphereEntity->addComponent(sphereMesh);
    sphereEntity->addComponent(sphereTransform);

Can I get all sphereMesh's vertexes ?

And are it's vertexes tranformed by sphereTransform ?

or How can I get the tranformed vertexes ?

I think I can use QAttribute, but I need some examples.


update:

I have tried:

    // plane
    Qt3DCore::QEntity *planeEntity = new Qt3DCore::QEntity(rootEntity);
    Qt3DExtras::QPlaneMesh *planeMesh = new Qt3DExtras::QPlaneMesh;
    planeMesh->setWidth(1);
    planeMesh->setHeight(1);

    Qt3DCore::QTransform *planeform = new Qt3DCore::QTransform;
    planeform->setRotation(QQuaternion::fromAxisAndAngle(QVector3D(1, 0, 0), 90.0f));
    planeform->setScale(10);
    planeEntity->addComponent(planeMesh);
    planeEntity->addComponent(material);
    planeEntity->addComponent(planeform);

    // ----------------

    QList<QVector4D> list;
    for ( auto attribute : planeMesh->geometry()->attributes() ) {
        if (attribute->name() == Qt3DRender::QAttribute::defaultPositionAttributeName()) {
            Qt3DRender::QBuffer *buffer = attribute->buffer();

            const QByteArray &data = buffer->data();
            for ( int i = 0 ; i < attribute->count() ; i++ ) {
                int vertexOffset = i * attribute->byteStride();
                int offset = vertexOffset + attribute->byteOffset();


                const char *vertexData = attribute->buffer()->data().constData() + (i * attribute->byteStride() + attribute->byteOffset());
                qDebug() << (int)vertexData;
                const float *typedVertexData = reinterpret_cast<const float*>(vertexData);
                list << QVector4D(typedVertexData[0], typedVertexData[1], typedVertexData[2], 1.0) ;

                qDebug() << list.last();

            } // for
        } // if
    } // for

and it's output:

QVector4D(0, 0, 0, 1)
QVector4D(1.57402e-38, 1.34525e-43, 0, 1)
QVector4D(0, 7.00649e-45, 1.52015e-23, 1)
QVector4D(1.52015e-23, 0, 0, 1)

and I transform it :

    qDebug() << (list[0] * planeform->matrix());
    qDebug() << (list[1] * planeform->matrix());
    qDebug() << (list[2] * planeform->matrix());
    qDebug() << (list[3] * planeform->matrix());
    // ---- output --------
    QVector4D(0, 0, 0, 1)
    QVector4D(1.57402e-37, 0, -1.34525e-42, 1)
    QVector4D(0, 1.52015e-22, 9.06081e-30, 1)
    QVector4D(1.52015e-22, 0, 0, 1)

I think it is too small. How do I fix it?

question from:https://stackoverflow.com/questions/65886488/qt3d-can-i-list-all-vertexes-from-qt3drenderqgeometryrenderer

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Regarding your first question:

QSphereMesh is an instance of QGeometryRenderer. QGeometryRenderer has a function geometry() which returns the respective QGeometry. QGeometry in turn has a function attributes() which returns a vector of the stored attributes (vertices, normals, indices, etc.). You can iterate over this vector of attributes and check the name() of the attribute, i.e. whether it is equal to QAttribute::defaultPositionAttributeName(). This (I think at least) returns the default name for the vertex attribute used by Qt3D ready-made meshes. You can then use the other functions of QAttribute like byteStride(), count(), etc. to reconstruct the actual vertices (look for something like "QByteArray to array of X" where X is the data type of the buffer of the attribute).

Regarding your second question:

No, the vertices won't be transformed. Qt3D constructs a modelView matrix for you and adds it to the shader - which means you can use e.g. modelView in your custom shader without having to manually add it. Checkout this list of variables and uniforms that Qt3D adds automatically. You could put the values for each vertex into a QVector4D where the last number is a 1 (like e.g. (0.1, 5.4, 13.2, 1.0)) and multiply it with the matrix you can get from the transform: transform->matrix(). I think you have to multiply the matrix from the right which is a bit counter intuitive: vector x matrix.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

57.0k users

...