问题描述
例如
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);
我可以获取所有 sphereMesh 的顶点吗?
它的顶点是否由 sphereTransform 转换?
或者我怎样才能得到转换后的顶点?
我想我可以使用 QAttribute,但我需要一些示例。
更新:
我试过了:
// 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),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
它的输出:
QVector4D(0,1)
QVector4D(1.57402e-38,1.34525e-43,1)
QVector4D(0,7.00649e-45,1.52015e-23,1)
QVector4D(1.52015e-23,1)
然后我转换它:
qDebug() << (list[0] * planeform->matrix());
qDebug() << (list[1] * planeform->matrix());
qDebug() << (list[2] * planeform->matrix());
qDebug() << (list[3] * planeform->matrix());
// ---- output --------
QVector4D(0,1)
QVector4D(1.57402e-37,-1.34525e-42,1)
QVector4D(0,1.52015e-22,9.06081e-30,1)
QVector4D(1.52015e-22,1)
我觉得它太小了。我该如何解决?
解决方法
关于你的第一个问题:
QSphereMesh
是 QGeometryRenderer
的一个实例。 QGeometryRenderer 有一个函数 geometry()
,它返回相应的 QGeometry
。 QGeometry
反过来有一个函数 attributes()
,它返回存储属性(顶点、法线、索引等)的向量。您可以迭代这个属性向量并检查属性的 name()
,即它是否等于 QAttribute::defaultPositionAttributeName()
。这(我认为至少)返回 Qt3D 现成网格使用的顶点属性的默认名称。然后,您可以使用 QAttribute
的其他函数(如 byteStride()
、count()
等)来重建实际顶点(查找类似“QByteArray to array of X”的内容,其中 X 是数据属性缓冲区的类型)。
关于你的第二个问题:
不,顶点不会被变换。 Qt3D 为您构造一个 modelView
矩阵并将其添加到着色器 - 这意味着您可以使用例如modelView
在您的自定义着色器中,而无需手动添加它。检查 Qt3D 自动添加的变量和制服的 this list。您可以将每个顶点的值放入 QVector4D
中,其中最后一个数字是 1
(例如 (0.1,5.4,13.2,1.0)
)并将其与您可以从变换中获得的矩阵相乘:{{ 1}}。我认为您必须从右侧乘以矩阵,这有点违反直觉:transform->matrix()
。