accelerated-raytracer/src/KDNode.h

64 lines
1.8 KiB
C++

#ifndef RAYTRYCPP_KDNODE_H
#define RAYTRYCPP_KDNODE_H
#include "KDAxis.h"
#include <QDebug>
#include <QVector3D>
#include <array>
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<unsigned int>(axis) << shifty) | (farIdx & farIdxMask)}, value{value} {
if (farIdx > farIdxMask) {
qFatal("Far index too large");
}
}
[[nodiscard]] Axis getAxis() const {
return static_cast<Axis>(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