c++ - Qt3D 我可以列出来自 Qt3DRender::QGeometryRenderer 的所有顶点吗?
问题描述
例如
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, 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, 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)
我改造它:
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)
我认为它太小了。我如何解决它?
解决方案
关于你的第一个问题:
QSphereMesh
是 的一个实例QGeometryRenderer
。QGeometryRenderer 有一个函数geometry()
,它返回相应的QGeometry
. QGeometry
反过来有一个函数attributes()
,它返回存储的属性(顶点、法线、索引等)的向量。您可以遍历此属性向量并检查name()
属性的 ,即它是否等于QAttribute::defaultPositionAttributeName()
。这(至少我认为)返回 Qt3D 现成网格使用的顶点属性的默认名称。然后,您可以使用QAttribute
like byteStride()
、count()
等的其他函数来重建实际顶点(查找类似“QByteArray to array of X”的内容,其中 X 是属性缓冲区的数据类型)。
关于你的第二个问题:
不,顶点不会被转换。Qt3DmodelView
为您构造一个矩阵并将其添加到着色器中——这意味着您可以modelView
在自定义着色器中使用,而无需手动添加它。查看 Qt3D自动添加的变量和制服列表。您可以将每个顶点的值放入QVector4D
最后一个数字为 a 的位置1
(例如 eg (0.1, 5.4, 13.2, 1.0)
),然后将其与从变换中获得的矩阵相乘:transform->matrix()
。我认为你必须从右边乘以矩阵,这有点违反直觉:vector x matrix
.
推荐阅读
- mysql - 独特的组合,没有重复的单个值
- android - Android EditText点击事件第二次触发
- c++ - 是否有获取 *.exe 文件产品名称的功能?
- apache - htaccess 重定向子域
- python - 我在多大程度上可以依赖 django 的 inspectdb 命令来使用大型遗留 MySQL 数据库?
- c# - 如何对不同的数据集发出单个 get 请求?
- jquery - 如何停止页脚上的固定侧边栏?
- c# - 使用文件上传控件如何在asp.net c#中上传空文件夹?
- c# - 动态创建的单选按钮列表未触发 onselected
- python - 根据python3.x中另一个列表中的子字符串列表删除列表中的项目