Qt3D 从 QGeometry 读取原始顶点数据

Cin*_*its 5 c++ opengl qt5 qt3d

我正在使用 Qt3D 开发一个应用程序,需要通过 C++ 访问原始顶点数据。我正在使用QObjectPickerraypointing,但由于数据是专门的(我开发了一个导入器,为每个包含温度读数的顶点添加一个额外的属性),我无法QObjectPicker方便地从该点读取数据。

3D 对象是通过加载的,QMesh所以我相信访问原始数据的最佳方式是通过QMeshQGeometry成员。如果我错了纠正我。QGeometry有一个QAttribute保存顶点属性的向量。(同样,如果我错了,请纠正我。)从这一点来看,我不确定如何从特定顶点索引读取数据。我的猜测是我需要QAttribute::buffer通过知道每个顶点数据有多大并从它的偏移量中读取来从某个位置读取数据,但是我在这里怎么做呢?

这是我到目前为止想出的:

void ES3DScene::handlePickerClicked(QPickEvent *pick)
{
    QPickTriangleEvent *trianglePick = qobject_cast<QPickTriangleEvent*>(pick);
    // I'd like to get the vertex data from vertex1Index's position.
    qDebug() << "Clicked " << trianglePick->vertex1Index();
    QGeometry *geometry = m_mesh->geometry();
    auto attributes = geometry->attributes();
    for (auto i = 0; i < attributes.count(); ++i)
    {
        if (attributes.at(i)->name() == QAttribute::defaultPositionAttributeName())
        {
            QAttribute *attribute = attributes.at(i);
            qDebug() << "Attrib " << attribute;

            //This is where I'm stuck. I need to read the vertex attributes for the
            //vertex at trianglePick->vertex1Index();

            break;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

dra*_*gly 4

我认为您必须访问QBuffer您感兴趣的属性的 。这可能不是带有 的属性defaultPositionAttributeName(),而是您在导入器中为其指定的名称。获取实际数据需要您将其从 QByteArray 转换为正确的数据类型,并使用 和 中包含的信息获取数据中的QAttribute正确byteStride位置byteOffset。您可能还想使用vertexSizevertexBaseType,具体取决于您编写导入程序的方式。

沿着这些思路的东西应该有效(未经测试):

void ES3DScene::handlePickerClicked(QPickEvent *pick)
{
    QPickTriangleEvent *trianglePick = qobject_cast<QPickTriangleEvent*>(pick);
    QGeometry *geometry = m_mesh->geometry();
    auto attributes = geometry->attributes();
    int vertexIndex = trianglePick->vertex1Index();
    for (auto i = 0; i < attributes.count(); ++i)
    {
        if (attributes.at(i)->name() == "yourattributename")
        {
            QAttribute *attribute = attributes.at(i);
            QBuffer *buffer = attribute->buffer();
            const QByteArray &data = buffer->data();

            int vertexOffset = vertexIndex * attribute->byteStride();
            int offset = vertexOffset + attribute.byteOffset();

            const char *rawData = &(data.constData()[offset]);

            // replace float with your data type
            float *value = reinterpret_cast<float*>(rawData);

            break;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)