#ifndef RAYTRYCPP_KDNODE_H #define RAYTRYCPP_KDNODE_H #include "KDAxis.h" #include #include #include namespace raytry::KD { static constexpr const unsigned int farIdxMask = 0b00111111111111111111111111111111; struct Node { static constexpr const size_t shifty{(sizeof(unsigned int) * 8) - 2}; unsigned int farIdxAndAxis = 0; float value = 0.0f; Node(Axis axis, unsigned int farIdx, float value) : farIdxAndAxis{(static_cast(axis) << shifty) | (farIdx & farIdxMask)}, value{value} { if (farIdx > farIdxMask) { qFatal("Far index too large"); } } [[nodiscard]] Axis getAxis() const { return static_cast(farIdxAndAxis >> shifty); } [[nodiscard]] bool isLeaf() const { return getAxis() == Axis::None; } [[nodiscard]] unsigned int farIdx() const { return farIdxAndAxis & farIdxMask; } [[nodiscard]] float val() const { return value; } void setFarIdx(unsigned int farIdx) { if (farIdx > farIdxMask) { qFatal("Far index too large"); } farIdxAndAxis = (farIdxAndAxis & ~farIdxMask) | farIdx; } #ifndef QT_NO_DEBUG_STREAM QDebug operator<<(QDebug dbg) const { if (isLeaf()) { return dbg << "KD::Node(leaf,idx=" << farIdx() << ")"; } else { return dbg << "KD::Node(axis=" << getAxis() << ",far=" << farIdx() << ",t=" << val() << ")"; } } friend QDebug operator<<(QDebug dbg, const Node &node) { return node.operator<<(std::move(dbg)); } #endif }; }// namespace raytry::KD #endif//RAYTRYCPP_KDNODE_H