// Copyright (C) 2020 The Qt Company Ltd. // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only #ifndef QSSGMESHBVH_H #define QSSGMESHBVH_H // // W A R N I N G // ------------- // // This file is not part of the Qt API. It exists purely as an // implementation detail. This header file may change from version to // version without notice, or even be removed. // // We mean it. // #include #include #include #include #include QT_BEGIN_NAMESPACE class QSSGMeshBVH; class Q_QUICK3DUTILS_EXPORT QSSGMeshBVHNode { public: class Handle { public: Handle() = default; bool isNull() const { return !m_owner || m_idx < size_t(FallbackIndex::Count); } inline explicit operator const QSSGMeshBVHNode *() const; inline QSSGMeshBVHNode *operator->() const; private: friend class QSSGMeshBVH; Handle(QSSGMeshBVH *owner, size_t idx) : m_owner(owner) , m_idx(idx) {} QSSGMeshBVH *m_owner = nullptr; size_t m_idx = 0; }; // Internal Handle left; Handle right; QSSGBounds3 boundingData; //splitAxis // Leaf int offset = 0; int count = 0; private: friend class QSSGMeshBVH; friend class QSSGMeshBVHBuilder; enum class FallbackIndex : quint8 { InvalidRead = 0, InvalidWrite = 1, Count }; }; struct Q_QUICK3DUTILS_EXPORT QSSGMeshBVHTriangle { QSSGBounds3 bounds; QVector3D vertex1; QVector3D vertex2; QVector3D vertex3; QVector2D uvCoord1; QVector2D uvCoord2; QVector2D uvCoord3; }; using QSSGMeshBVHTriangles = std::vector; using QSSGMeshBVHRoots = std::vector; using QSSGMeshBVHNodes = std::vector; class Q_QUICK3DUTILS_EXPORT QSSGMeshBVH { public: QSSGMeshBVH() = default; ~QSSGMeshBVH(); [[nodiscard]] QSSGMeshBVHNode::Handle newHandle() { m_nodes.emplace_back(); return { this, m_nodes.size() - 1 }; } [[nodiscard]] const QSSGMeshBVHTriangles &triangles() const { return m_triangles; } [[nodiscard]] const QSSGMeshBVHRoots &roots() const { return m_roots; } [[nodiscard]] const QSSGMeshBVHNodes &nodes() const { return m_nodes; } private: friend class QSSGMeshBVHNode::Handle; friend class QSSGMeshBVHBuilder; using FallbackIndex = QSSGMeshBVHNode::FallbackIndex; size_t getNodeIndex(size_t idx, FallbackIndex op) const { const bool valid = (idx >= size_t(FallbackIndex::Count) && idx < m_nodes.size()); return (valid * idx) + (!valid * size_t(op)); } QSSGMeshBVHNode &mutableValue(qsizetype idx) { return m_nodes[getNodeIndex(idx, FallbackIndex::InvalidWrite)]; } const QSSGMeshBVHNode &value(qsizetype idx) const { return m_nodes[getNodeIndex(idx, FallbackIndex::InvalidRead)]; } QSSGMeshBVHRoots m_roots; QSSGMeshBVHNodes m_nodes { { /* 0 - reserved for invalid reads */ }, { /* 1 - reserved for invalid writes */ } }; QSSGMeshBVHTriangles m_triangles; }; QSSGMeshBVHNode::Handle::operator const QSSGMeshBVHNode *() const { return &m_owner->value(m_idx); } QSSGMeshBVHNode *QSSGMeshBVHNode::Handle::operator->() const { return &m_owner->mutableValue(m_idx); } QT_END_NAMESPACE #endif // QSSGMESHBVH_H