尝试为 QtQuick3D 实现自定义几何图形:
mycustomgeometry.h:
#ifndef MYCUSTOMGEOMETRY_H
#define MYCUSTOMGEOMETRY_H
#include <QQuick3DGeometry>
class MyCustomGeometry : public QQuick3DGeometry
{
Q_OBJECT
public:
MyCustomGeometry();
virtual ~MyCustomGeometry();
signals:
public slots:
void setData(QByteArray vertexData, QByteArray indexData);
};
#endif // MYCUSTOMGEOMETRY_H
mycustomgeometry.cpp:
#include "mycustomgeometry.h"
#include <QVector3D>
// simulate data coming from my application (should look like a cut cuboid)
static unsigned char vertexData[] = {
0x00, 0x00, 0xe0, 0xb3, 0x8c, 0xca, 0x4c, 0xbd, 0x1c, 0x63, 0x89, 0x3d,
0x00, 0x00, 0x60, 0x35, 0x0c, 0xcf, 0x4c, 0x3d, 0xa4, 0x61, 0x89, 0x3d,
0x64, 0x2e, 0x37, 0xbd, 0xb8, 0xcc, 0x4c, 0xbd, 0x00, 0x2a, 0xb7, 0xbc,
0x68, 0x2d, 0x37, 0xbd, 0xe4, 0xcc, 0x4c, 0x3d, 0xe0, 0x2f, 0xb7, 0xbc,
0x80, 0x2d, 0x37, 0x3d, 0xa4, 0xcb, 0x4c, 0xbd, 0x18, 0x2f, 0x37, 0x3d,
0x80, 0x2e, 0x37, 0x3d, 0xf0, 0xcd, 0x4c, 0x3d, 0x28, 0x2c, 0x37, 0x3d,
0xd8, 0x2c, 0x37, 0x3d, 0xf8, 0xce, 0x4c, 0xbd, 0xa0, 0x61, 0x89, 0xbd,
0xd8, 0x2d, 0x37, 0x3d, 0xa4, 0xca, 0x4c, 0x3d, 0x20, 0x63, 0x89, 0xbd
};
static unsigned char indexData[] = {
0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x06, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
0x04, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00,
0x07, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00
};
MyCustomGeometry::MyCustomGeometry()
{
QByteArray v(reinterpret_cast<char*>(::vertexData), sizeof(::vertexData));
QByteArray i(reinterpret_cast<char*>(::indexData), sizeof(::indexData));
setData(v, i);
}
MyCustomGeometry::~MyCustomGeometry()
{
}
void MyCustomGeometry::setData(QByteArray vertexData, QByteArray indexData)
{
clear();
setPrimitiveType(PrimitiveType::Triangles);
addAttribute(Attribute::PositionSemantic, 0, Attribute::F32Type);
addAttribute(Attribute::IndexSemantic, 0, Attribute::U32Type);
addAttribute(Attribute::NormalSemantic, 0, Attribute::F32Type);
setVertexData(vertexData);
setIndexData(indexData);
setStride(sizeof(float) * 3);
QVector3D boundsMin, boundsMax;
auto vertices = reinterpret_cast<const float*>(vertexData.constData());
for(size_t i = 0; i < vertexData.length() / sizeof(float); i += 3)
{
for(size_t j = 0; j < 3; j++)
{
boundsMin[j] = (std::min(vertices[i + j], i == 0 ? vertices[i + j] : boundsMin[j]));
boundsMax[j] = (std::max(vertices[i + j], i == 0 ? vertices[i + j] : boundsMax[j]));
}
}
setBounds(boundsMin, boundsMax);
}
main.qml:
import QtQuick 2.15
import QtQuick.Window 2.15
import QtQuick3D 1.15
import QtQuick3D.Helpers 1.15
import QtQuick.Controls 2.15
import MyCustomGeometry 1.0
Window {
id: mainWindow
width: 400
height: 300
visible: true
flags: Qt.Tool
title: qsTr("3D demo")
View3D {
id: view
anchors.fill: parent
camera: camera
renderMode: View3D.Overlay
PerspectiveCamera {
id: camera
position: Qt.vector3d(0, 200, 300)
eulerRotation.x: -30
}
WasdController {
controlledObject: camera
mouseEnabled: true
}
DirectionalLight {
eulerRotation.x: -30
}
Model {
id: cube
objectName: "cube"
visible: true
position: Qt.vector3d(-100, 0, 0)
scale: Qt.vector3d(slider.k, slider.k, slider.k)
source: "#Cube"
materials: [DefaultMaterial {diffuseColor: "red"}]
eulerRotation.y: 90
}
Model {
id: sphere
objectName: "sphere"
visible: true
position: Qt.vector3d(100, 0, 0)
scale: Qt.vector3d(slider.k, slider.k, slider.k)
//source: "#Sphere"
geometry: MyCustomGeometry {}
materials: [DefaultMaterial {diffuseColor: "blue"}]
eulerRotation.y: 90
}
}
Slider {
id: slider
property real k: Math.pow(10, slider.value)
from: -3; to: 6; value: 3
}
}
立方体和球体(在评论geometry:
和取消评论时source:
)正确显示。
但是具有自定义几何形状的模型没有。
我也尝试使用 16 位整数作为索引,但得到了相同的结果。
编辑:在 Qt 6.0.0 上测试并且可以工作,所以这是一个仅限于 Qt 5.15.2 的问题