5#include <QtQuick3DUtils/private/qssgassert_p.h>
17 m_vertexBufferData = vb.
data;
18 m_indexBufferData = ib.
data;
28 for (
quint32 entryIdx = 0, entryEnd = vb.
entries.size(); entryIdx < entryEnd; ++entryIdx) {
31 m_hasPositionData =
true;
32 m_vertexPosOffset =
entry.m_firstItemOffset;
35 m_vertexUVOffset =
entry.m_firstItemOffset;
38 m_vertexUVOffset =
entry.m_firstItemOffset;
41 m_vertexStride = vb.
stride;
53 m_vertexBufferData = vertexBuffer;
55 m_hasPositionData =
true;
56 m_vertexPosOffset = posOffset;
58 m_vertexUVOffset = uvOffset;
59 m_hasIndexBuffer = hasIndexBuffer;
60 m_indexBufferData = indexBuffer;
61 m_indexBufferComponentType = indexBufferType;
71 if (m_mesh.
isValid() && m_mesh.
drawMode() != QSSGMesh::Mesh::DrawMode::Triangles)
74 auto meshBvh = std::make_unique<QSSGMeshBVH>();
75 auto &roots = meshBvh->m_roots;
76 auto &triangleBounds = meshBvh->m_triangles;
83 indexCount = m_vertexBufferData.
size() / m_vertexStride;
84 triangleBounds = calculateTriangleBounds(0, indexCount);
88 const QVector<QSSGMesh::Mesh::Subset> subsets = m_mesh.
subsets();
89 roots.reserve(subsets.size());
90 for (
quint32 subsetIdx = 0, subsetEnd = subsets.size(); subsetIdx < subsetEnd; ++subsetIdx) {
97 root->
boundingData = getBounds(*meshBvh, triangleOffset, triangleCount);
99 root = splitNode(*meshBvh, root, triangleOffset, triangleCount);
100 roots.push_back(root);
106 root = splitNode(*meshBvh, root, 0,
quint32(triangleBounds.size()));
107 roots.push_back(root);
114template <QSSGRenderComponentType ComponentType>
122 QSSGDataView<quint16> shortIndex(
reinterpret_cast<const quint16 *
>(indexBufferData.begin()), indexCount);
125 QSSGDataView<quint32> longIndex(
reinterpret_cast<const quint32 *
>(indexBufferData.begin()), indexCount);
148template <QSSGRenderComponentType ComponentType,
bool hasIndexBuffer,
bool hasPositionData,
bool hasUVData>
153 [[maybe_unused]]
const quint32 vertexStride,
154 [[maybe_unused]]
const quint32 vertexUVOffset,
155 [[maybe_unused]]
const quint32 vertexPosOffset,
158 const quint32 triangleCount = indexCount / 3;
159 triangleBounds.reserve(triangleCount);
163 if constexpr (hasIndexBuffer || hasPositionData || hasUVData) {
165 const quint32 triangleIndex =
i * 3 + indexOffset;
167 quint32 index1 = triangleIndex + 0;
168 quint32 index2 = triangleIndex + 1;
169 quint32 index3 = triangleIndex + 2;
171 if constexpr (hasIndexBuffer) {
172 index1 = getIndexBufferValue<ComponentType>(index1, indexCount, indexBufferData);
173 index2 = getIndexBufferValue<ComponentType>(index2, indexCount, indexBufferData);
174 index3 = getIndexBufferValue<ComponentType>(index3, indexCount, indexBufferData);
177 if constexpr (hasPositionData) {
183 if constexpr (hasUVData) {
190 triangle.bounds.include(triangle.vertex1);
191 triangle.bounds.include(triangle.vertex2);
192 triangle.bounds.include(triangle.vertex3);
193 triangleBounds.push_back(triangle);
202 static const CalcTriangleBoundsFn calcTriangleBounds16Fns[] { &calculateTriangleBoundsImpl<QSSGRenderComponentType::UnsignedInt16, false, false, false>,
203 &calculateTriangleBoundsImpl<QSSGRenderComponentType::UnsignedInt16, false, false, true>,
204 &calculateTriangleBoundsImpl<QSSGRenderComponentType::UnsignedInt16, false, true, false>,
205 &calculateTriangleBoundsImpl<QSSGRenderComponentType::UnsignedInt16, false, true, true>,
206 &calculateTriangleBoundsImpl<QSSGRenderComponentType::UnsignedInt16, true, false, false>,
207 &calculateTriangleBoundsImpl<QSSGRenderComponentType::UnsignedInt16, true, false, true>,
208 &calculateTriangleBoundsImpl<QSSGRenderComponentType::UnsignedInt16, true, true, false>,
209 &calculateTriangleBoundsImpl<QSSGRenderComponentType::UnsignedInt16, true, true, true> };
211 static const CalcTriangleBoundsFn calcTriangleBounds32Fns[] { &calculateTriangleBoundsImpl<QSSGRenderComponentType::UnsignedInt32, false, false, false>,
212 &calculateTriangleBoundsImpl<QSSGRenderComponentType::UnsignedInt32, false, false, true>,
213 &calculateTriangleBoundsImpl<QSSGRenderComponentType::UnsignedInt32, false, true, false>,
214 &calculateTriangleBoundsImpl<QSSGRenderComponentType::UnsignedInt32, false, true, true>,
215 &calculateTriangleBoundsImpl<QSSGRenderComponentType::UnsignedInt32, true, false, false>,
216 &calculateTriangleBoundsImpl<QSSGRenderComponentType::UnsignedInt32, true, false, true>,
217 &calculateTriangleBoundsImpl<QSSGRenderComponentType::UnsignedInt32, true, true, false>,
218 &calculateTriangleBoundsImpl<QSSGRenderComponentType::UnsignedInt32, true, true, true> };
221 const size_t idx = (size_t(m_hasIndexBuffer) << 2u) | (
size_t(m_hasPositionData) << 1u) | (
size_t(m_hasUVData));
224 calcTriangleBounds16Fns[idx](indexOffset, indexCount, m_indexBufferData, m_vertexBufferData, m_vertexStride, m_vertexUVOffset, m_vertexPosOffset,
data);
226 calcTriangleBounds32Fns[idx](indexOffset, indexCount, m_indexBufferData, m_vertexBufferData, m_vertexStride, m_vertexUVOffset, m_vertexPosOffset,
data);
247 if (
split.axis == QSSGMeshBVHBuilder::Axis::None) {
286 const auto &triangleBounds = bvh.
triangles();
297 QSSGMeshBVHBuilder::Split
split;
298 split.axis = getLongestDimension(nodeBounds);
301 if (
split.axis != Axis::None)
307QSSGMeshBVHBuilder::Axis QSSGMeshBVHBuilder::getLongestDimension(
const QSSGBounds3 &nodeBounds)
309 QSSGMeshBVHBuilder::Axis axis = Axis::None;
310 float largestDistance = std::numeric_limits<float>::min();
312 if (!nodeBounds.isFinite() || nodeBounds.isEmpty())
315 const QVector3D delta = nodeBounds.maximum - nodeBounds.minimum;
317 if (delta.
x() > largestDistance) {
319 largestDistance = delta.
x();
321 if (delta.
y() > largestDistance) {
323 largestDistance = delta.
y();
325 if (delta.
z() > largestDistance)
339 const auto &triangleBounds = bvh.
triangles();
341 average += triangleBounds[
i +
offset].bounds.center(
int(axis));
343 return average /
count;
351 const int axis = int(
split.axis);
353 auto &triangleBounds = bvh.m_triangles;
363 std::swap(triangleBounds[
left], triangleBounds[
right]);
char * data()
\macro QT_NO_CAST_FROM_BYTEARRAY
qsizetype size() const noexcept
Returns the number of bytes in this byte array.
static size_t getSizeOfType(QSSGRenderComponentType type)
Class representing 3D range or axis aligned bounding box.
void include(const QVector3D &v)
expands the volume to include v
QSSGMeshBVHBuilder(const QSSGMesh::Mesh &mesh)
std::unique_ptr< QSSGMeshBVH > buildTree()
QSSGMeshBVHNode::Handle newHandle()
const QSSGMeshBVHTriangles & triangles() const
VertexBuffer vertexBuffer() const
IndexBuffer indexBuffer() const
QVector< Subset > subsets() const
DrawMode drawMode() const
The QVector2D class represents a vector or vertex in 2D space.
The QVector3D class represents a vector or vertex in 3D space.
constexpr float y() const noexcept
Returns the y coordinate of this point.
constexpr float x() const noexcept
Returns the x coordinate of this point.
constexpr float z() const noexcept
Returns the z coordinate of this point.
Combined button and popup list for selecting options.
#define Q_STATIC_ASSERT(Condition)
DBusConnection const char DBusError DBusBusType DBusError return DBusConnection DBusHandleMessageFunction void DBusFreeFunction return DBusConnection return DBusConnection return const char DBusError return DBusConnection DBusMessage dbus_uint32_t return DBusConnection dbus_bool_t DBusConnection DBusAddWatchFunction DBusRemoveWatchFunction DBusWatchToggledFunction void DBusFreeFunction return DBusConnection DBusDispatchStatusFunction void DBusFreeFunction DBusTimeout return DBusTimeout return DBusWatch return DBusWatch unsigned int return DBusError const DBusError return const DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessage return DBusMessageIter int const void return DBusMessageIter DBusMessageIter return DBusMessageIter void DBusMessageIter void int return DBusMessage DBusMessageIter return DBusMessageIter return DBusMessageIter DBusMessageIter const char const char const char const char return DBusMessage return DBusMessage const char return DBusMessage dbus_bool_t return DBusMessage dbus_uint32_t return DBusMessage void
static const double leftOffset
static const double rightOffset
GLint GLenum GLsizei GLsizei GLsizei depth
GLenum GLenum GLsizei count
GLint GLsizei GLsizei GLenum GLenum GLsizei void * data
const void GLsizei GLsizei stride
GLenum GLuint GLintptr offset
GLsizei GLsizei GLchar * source
static qreal position(const QQuickItem *item, QQuickAnchors::Anchor anchorLine)
static void split(QT_FT_Vector *b)
std::vector< QSSGMeshBVHTriangle > QSSGMeshBVHTriangles
static QVector2D getVertexBufferValueUV(quint32 index, const quint32 vertexStride, const quint32 vertexUVOffset, const QByteArray &vertexBufferData)
static constexpr quint32 QSSG_MAX_LEAF_TRIANGLES
static quint32 getIndexBufferValue(quint32 index, const quint32 indexCount, const QByteArray &indexBufferData)
static void calculateTriangleBoundsImpl(quint32 indexOffset, quint32 indexCount, const QByteArray &indexBufferData, const QByteArray &vertexBufferData, const quint32 vertexStride, const quint32 vertexUVOffset, const quint32 vertexPosOffset, QSSGMeshBVHTriangles &triangleBounds)
static QT_BEGIN_NAMESPACE constexpr quint32 QSSG_MAX_TREE_DEPTH
static QVector3D getVertexBufferValuePosition(quint32 index, const quint32 vertexStride, const quint32 vertexPosOffset, const QByteArray &vertexBufferData)
static const char * getUV1AttrName()
static const char * getPositionAttrName()
static const char * getUV0AttrName()
QVector< VertexBufferEntry > entries