// BVHAccel Method Definitions BVHAccel::BVHAccel(const std::vector<std::shared_ptr<Primitive>> &p, int maxPrimsInNode, SplitMethod splitMethod) : maxPrimsInNode(std::min(255, maxPrimsInNode)), primitives(p), splitMethod(splitMethod) { StatTimer buildTime(&constructionTime); if (primitives.size() == 0) return; // Build BVH from _primitives_ // Initialize _primitiveInfo_ array for primitives std::vector<BVHPrimitiveInfo> primitiveInfo(primitives.size()); for (size_t i = 0; i < primitives.size(); ++i) primitiveInfo[i] = {i, primitives[i]->WorldBound()}; // Build BVH tree for primitives using _primitiveInfo_ MemoryArena arena(1024 * 1024); int totalNodes = 0; std::vector<std::shared_ptr<Primitive>> orderedPrims; orderedPrims.reserve(primitives.size()); BVHBuildNode *root; if (splitMethod == SplitMethod::HLBVH) root = HLBVHBuild(arena, primitiveInfo, &totalNodes, orderedPrims); else root = recursiveBuild(arena, primitiveInfo, 0, primitives.size(), &totalNodes, orderedPrims); primitives.swap(orderedPrims); Info("BVH created with %d nodes for %d primitives (%.2f MB)", totalNodes, (int)primitives.size(), float(totalNodes * sizeof(LinearBVHNode)) / (1024.f * 1024.f)); // Compute representation of depth-first traversal of BVH tree treeBytes += totalNodes * sizeof(LinearBVHNode) + sizeof(*this) + primitives.size() * sizeof(primitives[0]); nodes = AllocAligned<LinearBVHNode>(totalNodes); int offset = 0; flattenBVHTree(root, &offset); Assert(offset == totalNodes); }
CBVH_PBRT::CBVH_PBRT( const CGENERICCONTAINER &aObjectContainer, int aMaxPrimsInNode, SPLITMETHOD aSplitMethod ) : m_maxPrimsInNode( std::min( 255, aMaxPrimsInNode ) ), m_splitMethod( aSplitMethod ) { if( aObjectContainer.GetList().empty() ) { m_nodes = NULL; return; } // Initialize the indexes of ray packet for partition traversal for( unsigned int i = 0; i < RAYPACKET_RAYS_PER_PACKET; ++i ) { m_I[i] = i; } // Convert the objects list to vector of objects // ///////////////////////////////////////////////////////////////////////// aObjectContainer.ConvertTo( m_primitives ); wxASSERT( aObjectContainer.GetList().size() == m_primitives.size() ); // Initialize _primitiveInfo_ array for primitives // ///////////////////////////////////////////////////////////////////////// std::vector<BVHPrimitiveInfo> primitiveInfo( m_primitives.size() ); for( size_t i = 0; i < m_primitives.size(); ++i ) { wxASSERT( m_primitives[i]->GetBBox().IsInitialized() ); primitiveInfo[i] = BVHPrimitiveInfo( i, m_primitives[i]->GetBBox() ); } // Build BVH tree for primitives using _primitiveInfo_ int totalNodes = 0; CONST_VECTOR_OBJECT orderedPrims; orderedPrims.clear(); orderedPrims.reserve( m_primitives.size() ); BVHBuildNode *root; if( m_splitMethod == SPLIT_HLBVH ) root = HLBVHBuild( primitiveInfo, &totalNodes, orderedPrims); else root = recursiveBuild( primitiveInfo, 0, m_primitives.size(), &totalNodes, orderedPrims); wxASSERT( m_primitives.size() == orderedPrims.size() ); m_primitives.swap( orderedPrims ); // Compute representation of depth-first traversal of BVH tree m_nodes = static_cast<LinearBVHNode *>( _mm_malloc( sizeof( LinearBVHNode ) * totalNodes, L1_CACHE_LINE_SIZE ) ); m_addresses_pointer_to_mm_free.push_back( m_nodes ); for( int i = 0; i < totalNodes; ++i ) { m_nodes[i].bounds.Reset(); m_nodes[i].primitivesOffset = 0; m_nodes[i].nPrimitives = 0; m_nodes[i].axis = 0; } uint32_t offset = 0; flattenBVHTree( root, &offset ); wxASSERT( offset == (unsigned int)totalNodes ); #ifdef PRINT_STATISTICS_3D_VIEWER uint32_t treeBytes = totalNodes * sizeof( LinearBVHNode ) + sizeof( *this ) + m_primitives.size() * sizeof( m_primitives[0] ) + m_addresses_pointer_to_mm_free.size() * sizeof( void * ); printf( "////////////////////////////////////////////////////////////////////////////////\n" ); printf( "Creating a CBVH_PBRT from %u objects ", (unsigned int)m_primitives.size() ); switch( m_splitMethod ) { case SPLIT_MIDDLE: printf( "using SPLIT_MIDDLE\n" ); break; case SPLIT_EQUALCOUNTS: printf( "using SPLIT_EQUALCOUNTS\n" ); break; case SPLIT_SAH: printf( "using SPLIT_SAH\n" ); break; case SPLIT_HLBVH: printf( "using SPLIT_HLBVH\n" ); break; } printf( " BVH created with %d nodes (%.2f MB)\n", totalNodes, float(treeBytes) / (1024.f * 1024.f) ); printf( "////////////////////////////////////////////////////////////////////////////////\n\n" ); #endif }