Path: blob/master/thirdparty/embree/kernels/bvh/bvh_node_aabb.h
9906 views
// Copyright 2009-2021 Intel Corporation1// SPDX-License-Identifier: Apache-2.023#pragma once45#include "bvh_node_base.h"67namespace embree8{9/*! BVHN AABBNode */10template<typename NodeRef, int N>11struct AABBNode_t : public BaseNode_t<NodeRef, N>12{13using BaseNode_t<NodeRef,N>::children;1415struct Create16{17__forceinline NodeRef operator() (const FastAllocator::CachedAllocator& alloc, size_t numChildren = 0) const18{19AABBNode_t* node = (AABBNode_t*) alloc.malloc0(sizeof(AABBNode_t),NodeRef::byteNodeAlignment); node->clear();20return NodeRef::encodeNode(node);21}22};2324struct Set25{26__forceinline void operator() (NodeRef node, size_t i, NodeRef child, const BBox3fa& bounds) const {27node.getAABBNode()->setRef(i,child);28node.getAABBNode()->setBounds(i,bounds);29}30};3132struct Create233{34template<typename BuildRecord>35__forceinline NodeRef operator() (BuildRecord* children, const size_t num, const FastAllocator::CachedAllocator& alloc) const36{37AABBNode_t* node = (AABBNode_t*) alloc.malloc0(sizeof(AABBNode_t), NodeRef::byteNodeAlignment); node->clear();38for (size_t i=0; i<num; i++) node->setBounds(i,children[i].bounds());39return NodeRef::encodeNode(node);40}41};4243struct Set244{45template<typename BuildRecord>46__forceinline NodeRef operator() (const BuildRecord& precord, const BuildRecord* crecords, NodeRef ref, NodeRef* children, const size_t num) const47{48#if defined(DEBUG)49// check that empty children are only at the end of the child list50bool emptyChild = false;51for (size_t i=0; i<num; i++) {52emptyChild |= (children[i] == NodeRef::emptyNode);53assert(emptyChild == (children[i] == NodeRef::emptyNode));54}55#endif56AABBNode_t* node = ref.getAABBNode();57for (size_t i=0; i<num; i++) node->setRef(i,children[i]);58return ref;59}60};6162struct Set363{64Set3 (FastAllocator* allocator, PrimRef* prims)65: allocator(allocator), prims(prims) {}6667template<typename BuildRecord>68__forceinline NodeRef operator() (const BuildRecord& precord, const BuildRecord* crecords, NodeRef ref, NodeRef* children, const size_t num) const69{70#if defined(DEBUG)71// check that empty children are only at the end of the child list72bool emptyChild = false;73for (size_t i=0; i<num; i++) {74emptyChild |= (children[i] == NodeRef::emptyNode);75assert(emptyChild == (children[i] == NodeRef::emptyNode));76}77#endif78AABBNode_t* node = ref.getAABBNode();79for (size_t i=0; i<num; i++) node->setRef(i,children[i]);8081if (unlikely(precord.alloc_barrier))82{83PrimRef* begin = &prims[precord.prims.begin()];84PrimRef* end = &prims[precord.prims.end()]; // FIXME: extended end for spatial split builder!!!!!85size_t bytes = (size_t)end - (size_t)begin;86allocator->addBlock(begin,bytes);87}8889return ref;90}9192FastAllocator* const allocator;93PrimRef* const prims;94};9596/*! Clears the node. */97__forceinline void clear() {98lower_x = lower_y = lower_z = pos_inf;99upper_x = upper_y = upper_z = neg_inf;100BaseNode_t<NodeRef,N>::clear();101}102103/*! Sets bounding box and ID of child. */104__forceinline void setRef(size_t i, const NodeRef& ref) {105assert(i < N);106children[i] = ref;107}108109/*! Sets bounding box of child. */110__forceinline void setBounds(size_t i, const BBox3fa& bounds)111{112assert(i < N);113lower_x[i] = bounds.lower.x; lower_y[i] = bounds.lower.y; lower_z[i] = bounds.lower.z;114upper_x[i] = bounds.upper.x; upper_y[i] = bounds.upper.y; upper_z[i] = bounds.upper.z;115}116117/*! Sets bounding box and ID of child. */118__forceinline void set(size_t i, const NodeRef& ref, const BBox3fa& bounds) {119setBounds(i,bounds);120children[i] = ref;121}122123/*! Returns bounds of node. */124__forceinline BBox3fa bounds() const {125const Vec3fa lower(reduce_min(lower_x),reduce_min(lower_y),reduce_min(lower_z));126const Vec3fa upper(reduce_max(upper_x),reduce_max(upper_y),reduce_max(upper_z));127return BBox3fa(lower,upper);128}129130/*! Returns bounds of specified child. */131__forceinline BBox3fa bounds(size_t i) const132{133assert(i < N);134const Vec3fa lower(lower_x[i],lower_y[i],lower_z[i]);135const Vec3fa upper(upper_x[i],upper_y[i],upper_z[i]);136return BBox3fa(lower,upper);137}138139/*! Returns extent of bounds of specified child. */140__forceinline Vec3fa extend(size_t i) const {141return bounds(i).size();142}143144/*! Returns bounds of all children (implemented later as specializations) */145__forceinline void bounds(BBox<vfloat4>& bounds0, BBox<vfloat4>& bounds1, BBox<vfloat4>& bounds2, BBox<vfloat4>& bounds3) const;146147/*! swap two children of the node */148__forceinline void swap(size_t i, size_t j)149{150assert(i<N && j<N);151std::swap(children[i],children[j]);152std::swap(lower_x[i],lower_x[j]);153std::swap(lower_y[i],lower_y[j]);154std::swap(lower_z[i],lower_z[j]);155std::swap(upper_x[i],upper_x[j]);156std::swap(upper_y[i],upper_y[j]);157std::swap(upper_z[i],upper_z[j]);158}159160/*! swap the children of two nodes */161__forceinline static void swap(AABBNode_t* a, size_t i, AABBNode_t* b, size_t j)162{163assert(i<N && j<N);164std::swap(a->children[i],b->children[j]);165std::swap(a->lower_x[i],b->lower_x[j]);166std::swap(a->lower_y[i],b->lower_y[j]);167std::swap(a->lower_z[i],b->lower_z[j]);168std::swap(a->upper_x[i],b->upper_x[j]);169std::swap(a->upper_y[i],b->upper_y[j]);170std::swap(a->upper_z[i],b->upper_z[j]);171}172173/*! compacts a node (moves empty children to the end) */174__forceinline static void compact(AABBNode_t* a)175{176/* find right most filled node */177ssize_t j=N;178for (j=j-1; j>=0; j--)179if (a->child(j) != NodeRef::emptyNode)180break;181182/* replace empty nodes with filled nodes */183for (ssize_t i=0; i<j; i++) {184if (a->child(i) == NodeRef::emptyNode) {185a->swap(i,j);186for (j=j-1; j>i; j--)187if (a->child(j) != NodeRef::emptyNode)188break;189}190}191}192193/*! Returns reference to specified child */194__forceinline NodeRef& child(size_t i) { assert(i<N); return children[i]; }195__forceinline const NodeRef& child(size_t i) const { assert(i<N); return children[i]; }196197/*! output operator */198friend embree_ostream operator<<(embree_ostream o, const AABBNode_t& n)199{200o << "AABBNode { " << embree_endl;201o << " lower_x " << n.lower_x << embree_endl;202o << " upper_x " << n.upper_x << embree_endl;203o << " lower_y " << n.lower_y << embree_endl;204o << " upper_y " << n.upper_y << embree_endl;205o << " lower_z " << n.lower_z << embree_endl;206o << " upper_z " << n.upper_z << embree_endl;207o << " children = ";208for (size_t i=0; i<N; i++) o << n.children[i] << " ";209o << embree_endl;210o << "}" << embree_endl;211return o;212}213214public:215vfloat<N> lower_x; //!< X dimension of lower bounds of all N children.216vfloat<N> upper_x; //!< X dimension of upper bounds of all N children.217vfloat<N> lower_y; //!< Y dimension of lower bounds of all N children.218vfloat<N> upper_y; //!< Y dimension of upper bounds of all N children.219vfloat<N> lower_z; //!< Z dimension of lower bounds of all N children.220vfloat<N> upper_z; //!< Z dimension of upper bounds of all N children.221};222223template<>224__forceinline void AABBNode_t<NodeRefPtr<4>,4>::bounds(BBox<vfloat4>& bounds0, BBox<vfloat4>& bounds1, BBox<vfloat4>& bounds2, BBox<vfloat4>& bounds3) const {225transpose(lower_x,lower_y,lower_z,vfloat4(zero),bounds0.lower,bounds1.lower,bounds2.lower,bounds3.lower);226transpose(upper_x,upper_y,upper_z,vfloat4(zero),bounds0.upper,bounds1.upper,bounds2.upper,bounds3.upper);227}228}229230231