Path: blob/master/thirdparty/embree/kernels/bvh/bvh_node_aabb_mb4d.h
9913 views
// Copyright 2009-2021 Intel Corporation1// SPDX-License-Identifier: Apache-2.023#pragma once45#include "bvh_node_aabb_mb.h"67namespace embree8{9/*! Aligned 4D Motion Blur Node */10template<typename NodeRef, int N>11struct AABBNodeMB4D_t : public AABBNodeMB_t<NodeRef, N>12{13using BaseNode_t<NodeRef,N>::children;14using AABBNodeMB_t<NodeRef,N>::set;1516typedef BVHNodeRecord<NodeRef> NodeRecord;17typedef BVHNodeRecordMB<NodeRef> NodeRecordMB;18typedef BVHNodeRecordMB4D<NodeRef> NodeRecordMB4D;1920struct Create21{22template<typename BuildRecord>23__forceinline NodeRef operator() (BuildRecord*, const size_t, const FastAllocator::CachedAllocator& alloc, bool hasTimeSplits = true) const24{25if (hasTimeSplits)26{27AABBNodeMB4D_t* node = (AABBNodeMB4D_t*) alloc.malloc0(sizeof(AABBNodeMB4D_t),NodeRef::byteNodeAlignment); node->clear();28return NodeRef::encodeNode(node);29}30else31{32AABBNodeMB_t<NodeRef,N>* node = (AABBNodeMB_t<NodeRef,N>*) alloc.malloc0(sizeof(AABBNodeMB_t<NodeRef,N>),NodeRef::byteNodeAlignment); node->clear();33return NodeRef::encodeNode(node);34}35}36};3738struct Set39{40template<typename BuildRecord>41__forceinline void operator() (const BuildRecord&, const BuildRecord*, NodeRef ref, NodeRecordMB4D* children, const size_t num) const42{43#if defined(DEBUG)44// check that empty children are only at the end of the child list45bool emptyChild = false;46for (size_t i=0; i<num; i++) {47emptyChild |= (children[i].ref == NodeRef::emptyNode);48assert(emptyChild == (children[i].ref == NodeRef::emptyNode));49}50#endif51if (likely(ref.isAABBNodeMB())) {52for (size_t i=0; i<num; i++)53ref.getAABBNodeMB()->set(i, children[i]);54} else {55for (size_t i=0; i<num; i++)56ref.getAABBNodeMB4D()->set(i, children[i]);57}58}59};6061/*! Clears the node. */62__forceinline void clear() {63lower_t = vfloat<N>(pos_inf);64upper_t = vfloat<N>(neg_inf);65AABBNodeMB_t<NodeRef,N>::clear();66}6768/*! Sets bounding box of child. */69__forceinline void setBounds(size_t i, const LBBox3fa& bounds, const BBox1f& tbounds)70{71AABBNodeMB_t<NodeRef,N>::setBounds(i, bounds.global(tbounds));72lower_t[i] = tbounds.lower;73upper_t[i] = tbounds.upper == 1.0f ? 1.0f+float(ulp) : tbounds.upper;74}7576/*! Sets bounding box and ID of child. */77__forceinline void set(size_t i, const NodeRecordMB4D& child) {78AABBNodeMB_t<NodeRef,N>::setRef(i,child.ref);79setBounds(i, child.lbounds, child.dt);80}8182/*! Returns the expected surface area when randomly sampling the time. */83__forceinline float expectedHalfArea(size_t i) const {84return AABBNodeMB_t<NodeRef,N>::lbounds(i).expectedHalfArea(timeRange(i));85}8687/*! returns time range for specified child */88__forceinline BBox1f timeRange(size_t i) const {89return BBox1f(lower_t[i],upper_t[i]);90}9192/*! stream output operator */93friend embree_ostream operator<<(embree_ostream cout, const AABBNodeMB4D_t& n)94{95cout << "AABBNodeMB4D {" << embree_endl;96for (size_t i=0; i<N; i++)97{98const BBox3fa b0 = n.bounds0(i);99const BBox3fa b1 = n.bounds1(i);100cout << " child" << i << " { " << embree_endl;101cout << " bounds0 = " << lerp(b0,b1,n.lower_t[i]) << ", " << embree_endl;102cout << " bounds1 = " << lerp(b0,b1,n.upper_t[i]) << ", " << embree_endl;103cout << " time_bounds = " << n.lower_t[i] << ", " << n.upper_t[i] << embree_endl;104cout << " }";105}106cout << "}";107return cout;108}109110public:111vfloat<N> lower_t; //!< time dimension of lower bounds of all N children112vfloat<N> upper_t; //!< time dimension of upper bounds of all N children113};114}115116117