Path: blob/master/thirdparty/embree/kernels/builders/priminfo_mb.h
9913 views
// Copyright 2009-2021 Intel Corporation1// SPDX-License-Identifier: Apache-2.023#pragma once45#include "primref_mb.h"67namespace embree8{9/*! stores bounding information for a set of primitives */10template<typename BBox>11class PrimInfoMBT : public CentGeom<BBox>12{13public:14using CentGeom<BBox>::geomBounds;15using CentGeom<BBox>::centBounds;1617__forceinline PrimInfoMBT () {18}1920__forceinline PrimInfoMBT (EmptyTy)21: CentGeom<BBox>(empty), object_range(0,0), num_time_segments(0), max_num_time_segments(0), max_time_range(0.0f,1.0f), time_range(1.0f,0.0f) {}2223__forceinline PrimInfoMBT (size_t begin, size_t end)24: CentGeom<BBox>(empty), object_range(begin,end), num_time_segments(0), max_num_time_segments(0), max_time_range(0.0f,1.0f), time_range(1.0f,0.0f) {}2526template<typename PrimRef>27__forceinline void add_primref(const PrimRef& prim)28{29CentGeom<BBox>::extend_primref(prim);30time_range.extend(prim.time_range);31object_range._end++;32num_time_segments += prim.size();33if (max_num_time_segments < prim.totalTimeSegments()) {34max_num_time_segments = prim.totalTimeSegments();35max_time_range = prim.time_range;36}37}3839__forceinline void merge(const PrimInfoMBT& other)40{41CentGeom<BBox>::merge(other);42time_range.extend(other.time_range);43object_range._begin += other.object_range.begin();44object_range._end += other.object_range.end();45num_time_segments += other.num_time_segments;46if (max_num_time_segments < other.max_num_time_segments) {47max_num_time_segments = other.max_num_time_segments;48max_time_range = other.max_time_range;49}50}5152static __forceinline const PrimInfoMBT merge2(const PrimInfoMBT& a, const PrimInfoMBT& b) {53PrimInfoMBT r = a; r.merge(b); return r;54}5556__forceinline size_t begin() const {57return object_range.begin();58}5960__forceinline size_t end() const {61return object_range.end();62}6364/*! returns the number of primitives */65__forceinline size_t size() const {66return object_range.size();67}6869__forceinline float halfArea() const {70return time_range.size()*expectedApproxHalfArea(geomBounds);71}7273__forceinline float leafSAH() const {74return time_range.size()*expectedApproxHalfArea(geomBounds)*float(num_time_segments);75}7677__forceinline float leafSAH(size_t block_shift) const {78return time_range.size()*expectedApproxHalfArea(geomBounds)*float((num_time_segments+(size_t(1)<<block_shift)-1) >> block_shift);79}8081__forceinline float align_time(float ct) const82{83//return roundf(ct * float(numTimeSegments)) / float(numTimeSegments);84float t0 = (ct-max_time_range.lower)/max_time_range.size();85float t1 = roundf(t0 * float(max_num_time_segments)) / float(max_num_time_segments);86return t1*max_time_range.size()+max_time_range.lower;87}8889/*! stream output */90friend embree_ostream operator<<(embree_ostream cout, const PrimInfoMBT& pinfo)91{92return cout << "PrimInfo { " <<93"object_range = " << pinfo.object_range <<94", time_range = " << pinfo.time_range <<95", time_segments = " << pinfo.num_time_segments <<96", geomBounds = " << pinfo.geomBounds <<97", centBounds = " << pinfo.centBounds <<98"}";99}100101public:102range<size_t> object_range; //!< primitive range103size_t num_time_segments; //!< total number of time segments of all added primrefs104size_t max_num_time_segments; //!< maximum number of time segments of a primitive105BBox1f max_time_range; //!< time range of primitive with max_num_time_segments106BBox1f time_range; //!< merged time range of primitives when merging prims, or additionally clipped with build time range when used in SetMB107};108109typedef PrimInfoMBT<typename PrimRefMB::BBox> PrimInfoMB;110111struct SetMB : public PrimInfoMB112{113static const size_t PARALLEL_THRESHOLD = 3 * 1024;114static const size_t PARALLEL_FIND_BLOCK_SIZE = 1024;115static const size_t PARALLEL_PARTITION_BLOCK_SIZE = 128;116117typedef mvector<PrimRefMB>* PrimRefVector;118119__forceinline SetMB() {}120121__forceinline SetMB(const PrimInfoMB& pinfo_i, PrimRefVector prims)122: PrimInfoMB(pinfo_i), prims(prims) {}123124__forceinline SetMB(const PrimInfoMB& pinfo_i, PrimRefVector prims, range<size_t> object_range_in, BBox1f time_range_in)125: PrimInfoMB(pinfo_i), prims(prims)126{127object_range = object_range_in;128time_range = intersect(time_range,time_range_in);129}130131__forceinline SetMB(const PrimInfoMB& pinfo_i, PrimRefVector prims, BBox1f time_range_in)132: PrimInfoMB(pinfo_i), prims(prims)133{134time_range = intersect(time_range,time_range_in);135}136137void deterministic_order() const138{139/* required as parallel partition destroys original primitive order */140PrimRefMB* prim = prims->data();141std::sort(&prim[object_range.begin()],&prim[object_range.end()]);142}143144template<typename RecalculatePrimRef>145__forceinline LBBox3fa linearBounds(const RecalculatePrimRef& recalculatePrimRef) const146{147auto reduce = [&](const range<size_t>& r) -> LBBox3fa148{149LBBox3fa cbounds(empty);150for (size_t j = r.begin(); j < r.end(); j++)151{152PrimRefMB& ref = (*prims)[j];153const LBBox3fa bn = recalculatePrimRef.linearBounds(ref, time_range);154cbounds.extend(bn);155};156return cbounds;157};158159return parallel_reduce(object_range.begin(), object_range.end(), PARALLEL_FIND_BLOCK_SIZE, PARALLEL_THRESHOLD, LBBox3fa(empty),160reduce,161[&](const LBBox3fa& b0, const LBBox3fa& b1) -> LBBox3fa { return embree::merge(b0, b1); });162}163164template<typename RecalculatePrimRef>165__forceinline LBBox3fa linearBounds(const RecalculatePrimRef& recalculatePrimRef, const LinearSpace3fa& space) const166{167auto reduce = [&](const range<size_t>& r) -> LBBox3fa168{169LBBox3fa cbounds(empty);170for (size_t j = r.begin(); j < r.end(); j++)171{172PrimRefMB& ref = (*prims)[j];173const LBBox3fa bn = recalculatePrimRef.linearBounds(ref, time_range, space);174cbounds.extend(bn);175};176return cbounds;177};178179return parallel_reduce(object_range.begin(), object_range.end(), PARALLEL_FIND_BLOCK_SIZE, PARALLEL_THRESHOLD, LBBox3fa(empty),180reduce,181[&](const LBBox3fa& b0, const LBBox3fa& b1) -> LBBox3fa { return embree::merge(b0, b1); });182}183184template<typename RecalculatePrimRef>185const SetMB primInfo(const RecalculatePrimRef& recalculatePrimRef, const LinearSpace3fa& space) const186{187auto computePrimInfo = [&](const range<size_t>& r) -> PrimInfoMB188{189PrimInfoMB pinfo(empty);190for (size_t j=r.begin(); j<r.end(); j++)191{192PrimRefMB& ref = (*prims)[j];193PrimRefMB ref1 = recalculatePrimRef(ref,time_range,space);194pinfo.add_primref(ref1);195};196return pinfo;197};198199const PrimInfoMB pinfo = parallel_reduce(object_range.begin(), object_range.end(), PARALLEL_FIND_BLOCK_SIZE, PARALLEL_THRESHOLD,200PrimInfoMB(empty), computePrimInfo, PrimInfoMB::merge2);201202return SetMB(pinfo,prims,object_range,time_range);203}204205public:206PrimRefVector prims;207};208//}209}210211212