Path: blob/master/thirdparty/embree/kernels/bvh/bvh_node_aabb_mb.h
9906 views
// Copyright 2009-2021 Intel Corporation1// SPDX-License-Identifier: Apache-2.023#pragma once45#include "bvh_node_base.h"67namespace embree8{9/*! Motion Blur AABBNode */10template<typename NodeRef, int N>11struct AABBNodeMB_t : public BaseNode_t<NodeRef, N>12{13using BaseNode_t<NodeRef,N>::children;14typedef BVHNodeRecord<NodeRef> NodeRecord;15typedef BVHNodeRecordMB<NodeRef> NodeRecordMB;16typedef BVHNodeRecordMB4D<NodeRef> NodeRecordMB4D;1718struct Create19{20template<typename BuildRecord>21__forceinline NodeRef operator() (BuildRecord* children, const size_t num, const FastAllocator::CachedAllocator& alloc) const22{23AABBNodeMB_t* node = (AABBNodeMB_t*) alloc.malloc0(sizeof(AABBNodeMB_t),NodeRef::byteNodeAlignment); node->clear();24return NodeRef::encodeNode(node);25}26};2728struct Set29{30template<typename BuildRecord>31__forceinline NodeRecordMB operator() (const BuildRecord& precord, const BuildRecord* crecords, NodeRef ref, NodeRecordMB* children, const size_t num) const32{33#if defined(DEBUG)34// check that empty children are only at the end of the child list35bool emptyChild = false;36for (size_t i=0; i<num; i++) {37emptyChild |= (children[i].ref == NodeRef::emptyNode);38assert(emptyChild == (children[i].ref == NodeRef::emptyNode));39}40#endif41AABBNodeMB_t* node = ref.getAABBNodeMB();4243LBBox3fa bounds = empty;44for (size_t i=0; i<num; i++) {45node->setRef(i,children[i].ref);46node->setBounds(i,children[i].lbounds);47bounds.extend(children[i].lbounds);48}49return NodeRecordMB(ref,bounds);50}51};5253struct SetTimeRange54{55__forceinline SetTimeRange(BBox1f tbounds) : tbounds(tbounds) {}5657template<typename BuildRecord>58__forceinline NodeRecordMB operator() (const BuildRecord& precord, const BuildRecord* crecords, NodeRef ref, NodeRecordMB* children, const size_t num) const59{60AABBNodeMB_t* node = ref.getAABBNodeMB();6162LBBox3fa bounds = empty;63for (size_t i=0; i<num; i++) {64node->setRef(i, children[i].ref);65node->setBounds(i, children[i].lbounds, tbounds);66bounds.extend(children[i].lbounds);67}68return NodeRecordMB(ref,bounds);69}7071BBox1f tbounds;72};7374/*! Clears the node. */75__forceinline void clear() {76lower_x = lower_y = lower_z = vfloat<N>(pos_inf);77upper_x = upper_y = upper_z = vfloat<N>(neg_inf);78lower_dx = lower_dy = lower_dz = vfloat<N>(0.0f);79upper_dx = upper_dy = upper_dz = vfloat<N>(0.0f);80BaseNode_t<NodeRef,N>::clear();81}8283/*! Sets ID of child. */84__forceinline void setRef(size_t i, NodeRef ref) {85children[i] = ref;86}8788/*! Sets bounding box of child. */89__forceinline void setBounds(size_t i, const BBox3fa& bounds0_i, const BBox3fa& bounds1_i)90{91/*! for empty bounds we have to avoid inf-inf=nan */92BBox3fa bounds0(min(bounds0_i.lower,Vec3fa(+FLT_MAX)),max(bounds0_i.upper,Vec3fa(-FLT_MAX)));93BBox3fa bounds1(min(bounds1_i.lower,Vec3fa(+FLT_MAX)),max(bounds1_i.upper,Vec3fa(-FLT_MAX)));94bounds0 = bounds0.enlarge_by(4.0f*float(ulp));95bounds1 = bounds1.enlarge_by(4.0f*float(ulp));96Vec3fa dlower = bounds1.lower-bounds0.lower;97Vec3fa dupper = bounds1.upper-bounds0.upper;9899lower_x[i] = bounds0.lower.x; lower_y[i] = bounds0.lower.y; lower_z[i] = bounds0.lower.z;100upper_x[i] = bounds0.upper.x; upper_y[i] = bounds0.upper.y; upper_z[i] = bounds0.upper.z;101102lower_dx[i] = dlower.x; lower_dy[i] = dlower.y; lower_dz[i] = dlower.z;103upper_dx[i] = dupper.x; upper_dy[i] = dupper.y; upper_dz[i] = dupper.z;104}105106/*! Sets bounding box of child. */107__forceinline void setBounds(size_t i, const LBBox3fa& bounds) {108setBounds(i, bounds.bounds0, bounds.bounds1);109}110111/*! Sets bounding box of child. */112__forceinline void setBounds(size_t i, const LBBox3fa& bounds, const BBox1f& tbounds) {113setBounds(i, bounds.global(tbounds));114}115116/*! Sets bounding box and ID of child. */117__forceinline void set(size_t i, NodeRef ref, const BBox3fa& bounds) {118lower_x[i] = bounds.lower.x; lower_y[i] = bounds.lower.y; lower_z[i] = bounds.lower.z;119upper_x[i] = bounds.upper.x; upper_y[i] = bounds.upper.y; upper_z[i] = bounds.upper.z;120children[i] = ref;121}122123/*! Sets bounding box and ID of child. */124__forceinline void set(size_t i, const NodeRecordMB4D& child)125{126setRef(i, child.ref);127setBounds(i, child.lbounds, child.dt);128}129130/*! Return bounding box for time 0 */131__forceinline BBox3fa bounds0(size_t i) const {132return BBox3fa(Vec3fa(lower_x[i],lower_y[i],lower_z[i]),133Vec3fa(upper_x[i],upper_y[i],upper_z[i]));134}135136/*! Return bounding box for time 1 */137__forceinline BBox3fa bounds1(size_t i) const {138return BBox3fa(Vec3fa(lower_x[i]+lower_dx[i],lower_y[i]+lower_dy[i],lower_z[i]+lower_dz[i]),139Vec3fa(upper_x[i]+upper_dx[i],upper_y[i]+upper_dy[i],upper_z[i]+upper_dz[i]));140}141142/*! Returns bounds of node. */143__forceinline BBox3fa bounds() const {144return BBox3fa(Vec3fa(reduce_min(min(lower_x,lower_x+lower_dx)),145reduce_min(min(lower_y,lower_y+lower_dy)),146reduce_min(min(lower_z,lower_z+lower_dz))),147Vec3fa(reduce_max(max(upper_x,upper_x+upper_dx)),148reduce_max(max(upper_y,upper_y+upper_dy)),149reduce_max(max(upper_z,upper_z+upper_dz))));150}151152/*! Return bounding box of child i */153__forceinline BBox3fa bounds(size_t i) const {154return merge(bounds0(i),bounds1(i));155}156157/*! Return linear bounding box of child i */158__forceinline LBBox3fa lbounds(size_t i) const {159return LBBox3fa(bounds0(i),bounds1(i));160}161162/*! Return bounding box of child i at specified time */163__forceinline BBox3fa bounds(size_t i, float time) const {164return lerp(bounds0(i),bounds1(i),time);165}166167/*! Returns the expected surface area when randomly sampling the time. */168__forceinline float expectedHalfArea(size_t i) const {169return lbounds(i).expectedHalfArea();170}171172/*! Returns the expected surface area when randomly sampling the time. */173__forceinline float expectedHalfArea(size_t i, const BBox1f& t0t1) const {174return lbounds(i).expectedHalfArea(t0t1);175}176177/*! swap two children of the node */178__forceinline void swap(size_t i, size_t j)179{180assert(i<N && j<N);181std::swap(children[i],children[j]);182183std::swap(lower_x[i],lower_x[j]);184std::swap(upper_x[i],upper_x[j]);185std::swap(lower_y[i],lower_y[j]);186std::swap(upper_y[i],upper_y[j]);187std::swap(lower_z[i],lower_z[j]);188std::swap(upper_z[i],upper_z[j]);189190std::swap(lower_dx[i],lower_dx[j]);191std::swap(upper_dx[i],upper_dx[j]);192std::swap(lower_dy[i],lower_dy[j]);193std::swap(upper_dy[i],upper_dy[j]);194std::swap(lower_dz[i],lower_dz[j]);195std::swap(upper_dz[i],upper_dz[j]);196}197198/*! compacts a node (moves empty children to the end) */199__forceinline static void compact(AABBNodeMB_t* a)200{201/* find right most filled node */202ssize_t j=N;203for (j=j-1; j>=0; j--)204if (a->child(j) != NodeRef::emptyNode)205break;206207/* replace empty nodes with filled nodes */208for (ssize_t i=0; i<j; i++) {209if (a->child(i) == NodeRef::emptyNode) {210a->swap(i,j);211for (j=j-1; j>i; j--)212if (a->child(j) != NodeRef::emptyNode)213break;214}215}216}217218/*! Returns reference to specified child */219__forceinline NodeRef& child(size_t i) { assert(i<N); return children[i]; }220__forceinline const NodeRef& child(size_t i) const { assert(i<N); return children[i]; }221222/*! stream output operator */223friend embree_ostream operator<<(embree_ostream cout, const AABBNodeMB_t& n)224{225cout << "AABBNodeMB {" << embree_endl;226for (size_t i=0; i<N; i++)227{228const BBox3fa b0 = n.bounds0(i);229const BBox3fa b1 = n.bounds1(i);230cout << " child" << i << " { " << embree_endl;231cout << " bounds0 = " << b0 << ", " << embree_endl;232cout << " bounds1 = " << b1 << ", " << embree_endl;233cout << " }";234}235cout << "}";236return cout;237}238239public:240vfloat<N> lower_x; //!< X dimension of lower bounds of all N children.241vfloat<N> upper_x; //!< X dimension of upper bounds of all N children.242vfloat<N> lower_y; //!< Y dimension of lower bounds of all N children.243vfloat<N> upper_y; //!< Y dimension of upper bounds of all N children.244vfloat<N> lower_z; //!< Z dimension of lower bounds of all N children.245vfloat<N> upper_z; //!< Z dimension of upper bounds of all N children.246247vfloat<N> lower_dx; //!< X dimension of lower bounds of all N children.248vfloat<N> upper_dx; //!< X dimension of upper bounds of all N children.249vfloat<N> lower_dy; //!< Y dimension of lower bounds of all N children.250vfloat<N> upper_dy; //!< Y dimension of upper bounds of all N children.251vfloat<N> lower_dz; //!< Z dimension of lower bounds of all N children.252vfloat<N> upper_dz; //!< Z dimension of upper bounds of all N children.253};254}255256257