Path: blob/master/thirdparty/embree/kernels/bvh/bvh_node_ref.h
9906 views
// Copyright 2009-2021 Intel Corporation1// SPDX-License-Identifier: Apache-2.023#pragma once45#include "../common/default.h"6#include "../common/alloc.h"7#include "../common/accel.h"8#include "../common/device.h"9#include "../common/scene.h"10#include "../geometry/primitive.h"11#include "../common/ray.h"1213namespace embree14{15/* BVH node reference with bounds */16template<typename NodeRef>17struct BVHNodeRecord18{19__forceinline BVHNodeRecord() {}20__forceinline BVHNodeRecord(NodeRef ref, const BBox3fa& bounds) : ref(ref), bounds((BBox3fx)bounds) {}21__forceinline BVHNodeRecord(NodeRef ref, const BBox3fx& bounds) : ref(ref), bounds(bounds) {}2223NodeRef ref;24BBox3fx bounds;25};2627template<typename NodeRef>28struct BVHNodeRecordMB29{30__forceinline BVHNodeRecordMB() {}31__forceinline BVHNodeRecordMB(NodeRef ref, const LBBox3fa& lbounds) : ref(ref), lbounds(lbounds) {}3233NodeRef ref;34LBBox3fa lbounds;35};3637template<typename NodeRef>38struct BVHNodeRecordMB4D39{40__forceinline BVHNodeRecordMB4D() {}41__forceinline BVHNodeRecordMB4D(NodeRef ref, const LBBox3fa& lbounds, const BBox1f& dt) : ref(ref), lbounds(lbounds), dt(dt) {}4243NodeRef ref;44LBBox3fa lbounds;45BBox1f dt;46};4748template<typename NodeRef, int N> struct BaseNode_t;49template<typename NodeRef, int N> struct AABBNode_t;50template<typename NodeRef, int N> struct AABBNodeMB_t;51template<typename NodeRef, int N> struct AABBNodeMB4D_t;52template<typename NodeRef, int N> struct OBBNode_t;53template<typename NodeRef, int N> struct OBBNodeMB_t;54template<typename NodeRef, int N> struct QuantizedNode_t;55template<typename NodeRef, int N> struct QuantizedNodeMB_t;5657/*! Pointer that points to a node or a list of primitives */58template<int N>59struct NodeRefPtr60{61//template<int NN> friend class BVHN;6263/*! Number of bytes the nodes and primitives are minimally aligned to.*/64static const size_t byteAlignment = 16;65static const size_t byteNodeAlignment = 4*N;6667/*! highest address bit is used as barrier for some algorithms */68static const size_t barrier_mask = (1LL << (8*sizeof(size_t)-1));6970/*! Masks the bits that store the number of items per leaf. */71static const size_t align_mask = byteAlignment-1;72static const size_t items_mask = byteAlignment-1;7374/*! different supported node types */75static const size_t tyAABBNode = 0;76static const size_t tyAABBNodeMB = 1;77static const size_t tyAABBNodeMB4D = 6;78static const size_t tyOBBNode = 2;79static const size_t tyOBBNodeMB = 3;80static const size_t tyQuantizedNode = 5;81static const size_t tyLeaf = 8;8283/*! Empty node */84static const size_t emptyNode = tyLeaf;8586/*! Invalid node, used as marker in traversal */87static const size_t invalidNode = (((size_t)-1) & (~items_mask)) | (tyLeaf+0);88static const size_t popRay = (((size_t)-1) & (~items_mask)) | (tyLeaf+1);8990/*! Maximum number of primitive blocks in a leaf. */91static const size_t maxLeafBlocks = items_mask-tyLeaf;9293/*! Default constructor */94__forceinline NodeRefPtr () {}9596/*! Construction from integer */97__forceinline NodeRefPtr (size_t ptr) : ptr(ptr) {}9899/*! Cast to size_t */100__forceinline operator size_t() const { return ptr; }101102/*! Sets the barrier bit. */103__forceinline void setBarrier() {104#if defined(__64BIT__)105assert(!isBarrier());106ptr |= barrier_mask;107#else108assert(false);109#endif110}111112/*! Clears the barrier bit. */113__forceinline void clearBarrier() {114#if defined(__64BIT__)115ptr &= ~barrier_mask;116#else117assert(false);118#endif119}120121/*! Checks if this is an barrier. A barrier tells the top level tree rotations how deep to enter the tree. */122__forceinline bool isBarrier() const { return (ptr & barrier_mask) != 0; }123124/*! checks if this is a leaf */125__forceinline size_t isLeaf() const { return ptr & tyLeaf; }126127/*! returns node type */128__forceinline int type() const { return ptr & (size_t)align_mask; }129130/*! checks if this is a node */131__forceinline int isAABBNode() const { return (ptr & (size_t)align_mask) == tyAABBNode; }132133/*! checks if this is a motion blur node */134__forceinline int isAABBNodeMB() const { return (ptr & (size_t)align_mask) == tyAABBNodeMB; }135136/*! checks if this is a 4D motion blur node */137__forceinline int isAABBNodeMB4D() const { return (ptr & (size_t)align_mask) == tyAABBNodeMB4D; }138139/*! checks if this is a node with unaligned bounding boxes */140__forceinline int isOBBNode() const { return (ptr & (size_t)align_mask) == tyOBBNode; }141142/*! checks if this is a motion blur node with unaligned bounding boxes */143__forceinline int isOBBNodeMB() const { return (ptr & (size_t)align_mask) == tyOBBNodeMB; }144145/*! checks if this is a quantized node */146__forceinline int isQuantizedNode() const { return (ptr & (size_t)align_mask) == tyQuantizedNode; }147148/*! Encodes a node */149static __forceinline NodeRefPtr encodeNode(AABBNode_t<NodeRefPtr,N>* node) {150assert(!((size_t)node & align_mask));151return NodeRefPtr((size_t) node);152}153154static __forceinline NodeRefPtr encodeNode(AABBNodeMB_t<NodeRefPtr,N>* node) {155assert(!((size_t)node & align_mask));156return NodeRefPtr((size_t) node | tyAABBNodeMB);157}158159static __forceinline NodeRefPtr encodeNode(AABBNodeMB4D_t<NodeRefPtr,N>* node) {160assert(!((size_t)node & align_mask));161return NodeRefPtr((size_t) node | tyAABBNodeMB4D);162}163164/*! Encodes an unaligned node */165static __forceinline NodeRefPtr encodeNode(OBBNode_t<NodeRefPtr,N>* node) {166return NodeRefPtr((size_t) node | tyOBBNode);167}168169/*! Encodes an unaligned motion blur node */170static __forceinline NodeRefPtr encodeNode(OBBNodeMB_t<NodeRefPtr,N>* node) {171return NodeRefPtr((size_t) node | tyOBBNodeMB);172}173174/*! Encodes a leaf */175static __forceinline NodeRefPtr encodeLeaf(void* tri, size_t num) {176assert(!((size_t)tri & align_mask));177assert(num <= maxLeafBlocks);178return NodeRefPtr((size_t)tri | (tyLeaf+min(num,(size_t)maxLeafBlocks)));179}180181/*! Encodes a leaf */182static __forceinline NodeRefPtr encodeTypedLeaf(void* ptr, size_t ty) {183assert(!((size_t)ptr & align_mask));184return NodeRefPtr((size_t)ptr | (tyLeaf+ty));185}186187/*! returns base node pointer */188__forceinline BaseNode_t<NodeRefPtr,N>* baseNode()189{190assert(!isLeaf());191return (BaseNode_t<NodeRefPtr,N>*)(ptr & ~(size_t)align_mask);192}193__forceinline const BaseNode_t<NodeRefPtr,N>* baseNode() const194{195assert(!isLeaf());196return (const BaseNode_t<NodeRefPtr,N>*)(ptr & ~(size_t)align_mask);197}198199/*! returns node pointer */200__forceinline AABBNode_t<NodeRefPtr,N>* getAABBNode() { assert(isAABBNode()); return ( AABBNode_t<NodeRefPtr,N>*)ptr; }201__forceinline const AABBNode_t<NodeRefPtr,N>* getAABBNode() const { assert(isAABBNode()); return (const AABBNode_t<NodeRefPtr,N>*)ptr; }202203/*! returns motion blur node pointer */204__forceinline AABBNodeMB_t<NodeRefPtr,N>* getAABBNodeMB() { assert(isAABBNodeMB() || isAABBNodeMB4D()); return ( AABBNodeMB_t<NodeRefPtr,N>*)(ptr & ~(size_t)align_mask); }205__forceinline const AABBNodeMB_t<NodeRefPtr,N>* getAABBNodeMB() const { assert(isAABBNodeMB() || isAABBNodeMB4D()); return (const AABBNodeMB_t<NodeRefPtr,N>*)(ptr & ~(size_t)align_mask); }206207/*! returns 4D motion blur node pointer */208__forceinline AABBNodeMB4D_t<NodeRefPtr,N>* getAABBNodeMB4D() { assert(isAABBNodeMB4D()); return ( AABBNodeMB4D_t<NodeRefPtr,N>*)(ptr & ~(size_t)align_mask); }209__forceinline const AABBNodeMB4D_t<NodeRefPtr,N>* getAABBNodeMB4D() const { assert(isAABBNodeMB4D()); return (const AABBNodeMB4D_t<NodeRefPtr,N>*)(ptr & ~(size_t)align_mask); }210211/*! returns unaligned node pointer */212__forceinline OBBNode_t<NodeRefPtr,N>* ungetAABBNode() { assert(isOBBNode()); return ( OBBNode_t<NodeRefPtr,N>*)(ptr & ~(size_t)align_mask); }213__forceinline const OBBNode_t<NodeRefPtr,N>* ungetAABBNode() const { assert(isOBBNode()); return (const OBBNode_t<NodeRefPtr,N>*)(ptr & ~(size_t)align_mask); }214215/*! returns unaligned motion blur node pointer */216__forceinline OBBNodeMB_t<NodeRefPtr,N>* ungetAABBNodeMB() { assert(isOBBNodeMB()); return ( OBBNodeMB_t<NodeRefPtr,N>*)(ptr & ~(size_t)align_mask); }217__forceinline const OBBNodeMB_t<NodeRefPtr,N>* ungetAABBNodeMB() const { assert(isOBBNodeMB()); return (const OBBNodeMB_t<NodeRefPtr,N>*)(ptr & ~(size_t)align_mask); }218219/*! returns quantized node pointer */220__forceinline QuantizedNode_t<NodeRefPtr,N>* quantizedNode() { assert(isQuantizedNode()); return ( QuantizedNode_t<NodeRefPtr,N>*)(ptr & ~(size_t)align_mask ); }221__forceinline const QuantizedNode_t<NodeRefPtr,N>* quantizedNode() const { assert(isQuantizedNode()); return (const QuantizedNode_t<NodeRefPtr,N>*)(ptr & ~(size_t)align_mask ); }222223/*! returns leaf pointer */224__forceinline char* leaf(size_t& num) const {225assert(isLeaf());226num = (ptr & (size_t)items_mask)-tyLeaf;227return (char*)(ptr & ~(size_t)align_mask);228}229230/*! clear all bit flags */231__forceinline void clearFlags() {232ptr &= ~(size_t)align_mask;233}234235/*! returns the wideness */236__forceinline size_t getN() const { return N; }237238public:239size_t ptr;240};241}242243244