NodeIds NodeId::getParents() const { NodeIds nodeIds; NodeId parent = getParent(); while (parent.isValid()) { nodeIds.push_back(parent); parent = parent.getParent(); } return nodeIds; }
NodeIds NodeId::getChildren( ) const { NodeIds nodeIds; if( _level == INVALID_LEVEL ) return nodeIds; const Vector3ui childPos = getPosition() * 2; for( uint32_t x = 0; x < 2; ++x ) for( uint32_t y = 0; y < 2; ++y ) for( uint32_t z = 0; z < 2; ++z ) { const Vector3ui pos( childPos[ 0 ] + x, childPos[ 1 ] + y, childPos[ 2 ] + z ); nodeIds.push_back( NodeId( _level + 1, pos, _frame ) ); } return nodeIds; }
NodeIds NodeId::getChildrenAtLevel( const uint32_t level ) const { NodeIds nodeIds; if( _level == INVALID_LEVEL || _level >= level ) return nodeIds; const uint32_t childCount = 1u << ( level - _level ); const Vector3f& startPosInLevel = getPosition() * childCount; for( uint32_t x = 0; x < childCount; ++x ) for( uint32_t y = 0; y < childCount; ++y ) for( uint32_t z = 0; z < childCount; ++z ) { const Vector3ui pos( startPosInLevel[ 0 ] + x, startPosInLevel[ 1 ] + y, startPosInLevel[ 2 ] + z ); nodeIds.push_back( NodeId( level, pos, _frame ) ); } return nodeIds; }
NodeIds NodeId::getChildren() const { if (_level == INVALID_LEVEL) return NodeIds(); NodeIds nodeIds; nodeIds.reserve(8); const Vector3ui childPos = getPosition() * 2; for (uint32_t x = 0; x < 2; ++x) { for (uint32_t y = 0; y < 2; ++y) { for (uint32_t z = 0; z < 2; ++z) { const Vector3ui pos(childPos[0] + x, childPos[1] + y, childPos[2] + z); nodeIds.emplace_back(NodeId(_level + 1, pos, _timeStep)); } } } return nodeIds; }
void visitPost() { // Sort-last range selection: #ifndef LIVRE_STATIC_DECOMPOSITION const size_t startIndex = _range[0] * _visibles.size(); const size_t endIndex = _range[1] * _visibles.size(); #endif NodeIds selected; for (size_t i = 0; i < _visibles.size(); ++i) { #ifdef LIVRE_STATIC_DECOMPOSITION const Range& nodeRange = _visibles[i].getRange(); const bool isInRange = nodeRange[1] > _range[0] && nodeRange[1] <= _range[1]; #else const bool isInRange = i >= startIndex && i < endIndex; #endif if (isInRange) selected.push_back(_visibles[i]); } _visibles.swap(selected); }
ConstCacheObjects generateRenderingSet( const NodeIds& visibles, size_t& nAvailable, size_t& nNotAvailable ) const { ConstCacheMap cacheMap; for( const NodeId& nodeId : visibles ) { collectLoadedTextures( nodeId, cacheMap ); cacheMap.count( nodeId.getId( )) > 0 ? ++nAvailable : ++nNotAvailable; } if( visibles.size() != cacheMap.size( )) { ConstCacheMap::const_iterator it = cacheMap.begin(); size_t previousSize = 0; do { previousSize = cacheMap.size(); while( it != cacheMap.end( )) { if( hasParentInMap( NodeId( it->first ), cacheMap )) it = cacheMap.erase( it ); else ++it; } } while( previousSize != cacheMap.size( )); } ConstCacheObjects cacheObjects; cacheObjects.reserve( cacheMap.size( )); for( ConstCacheMap::const_iterator it = cacheMap.begin(); it != cacheMap.end(); ++it ) { cacheObjects.push_back( it->second ); } return cacheObjects; }
void renderSync( RenderStatistics& statistics, Renderer& renderer, const RenderInputs& renderInputs ) { tuyau::PipeFilter sendHistogramFilter = renderInputs.filters.find( "SendHistogramFilter" )->second; tuyau::PipeFilter preRenderFilter = renderInputs.filters.find( "PreRenderFilter" )->second; tuyau::PipeFilterT< VisibleSetGeneratorFilter > visibleSetGenerator( "VisibleSetGenerator", renderInputs.dataSource ); setupVisibleGeneratorFilter( visibleSetGenerator, renderInputs ); visibleSetGenerator.connect( "VisibleNodes", preRenderFilter, "VisibleNodes" ); preRenderFilter.getPromise( "Frustum" ).set( renderInputs.frameInfo.frustum ); visibleSetGenerator.execute(); preRenderFilter.execute(); const tuyau::UniqueFutureMap portFutures( visibleSetGenerator.getPostconditions( )); NodeIds nodeIdsCopy = portFutures.get< NodeIds >( "VisibleNodes" ); DistanceOperator distanceOp( renderInputs.dataSource, renderInputs.frameInfo.frustum ); std::sort( nodeIdsCopy.begin(), nodeIdsCopy.end(), distanceOp ); const uint32_t maxNodesPerPass = texturePool->getTextureMem() / texturePool->getSlotMemSize(); const uint32_t numberOfPasses = std::ceil( (float)nodeIdsCopy.size() / (float)maxNodesPerPass ); std::unique_ptr< boost::progress_display > showProgress; if( numberOfPasses > 1 ) { LBINFO << "Multipass rendering. Number of passes: " << numberOfPasses << std::endl; showProgress.reset( new boost::progress_display( numberOfPasses )); } for( uint32_t i = 0; i < numberOfPasses; ++i ) { uint32_t renderStages = RENDER_FRAME; if( i == 0 ) renderStages |= RENDER_BEGIN; if( i == numberOfPasses - 1u ) renderStages |= RENDER_END; const uint32_t startIndex = i * maxNodesPerPass; const uint32_t endIndex = ( i + 1 ) * maxNodesPerPass; const NodeIds nodesPerPass( nodeIdsCopy.begin() + startIndex, endIndex > nodeIdsCopy.size() ? nodeIdsCopy.end() : nodeIdsCopy.begin() + endIndex ); createAndExecuteSyncPass( nodesPerPass, renderInputs, renderer, renderStages ); if( numberOfPasses > 1 ) ++(*showProgress); } tuyau::PipeFilterT< HistogramFilter > histogramFilter( "HistogramFilter", *histogramCache, *dataCache, renderInputs.dataSource ); histogramFilter.getPromise( "NodeIds" ).set( nodeIdsCopy ); sendHistogramFilter.getPromise( "RelativeViewport" ).set( renderInputs.viewport ); sendHistogramFilter.getPromise( "Id" ).set( renderInputs.frameInfo.frameId ); histogramFilter.getPromise( "Frustum" ).set( renderInputs.frameInfo.frustum ); histogramFilter.connect( "Histogram", sendHistogramFilter, "Histogram" ); histogramFilter.getPromise( "RelativeViewport" ).set( renderInputs.viewport ); histogramFilter.getPromise( "DataSourceRange" ).set( renderInputs.dataSourceRange ); histogramFilter.schedule( _computeExecutor ); sendHistogramFilter.schedule( _computeExecutor ); const tuyau::UniqueFutureMap futures( visibleSetGenerator.getPostconditions( )); statistics.nAvailable = futures.get< NodeIds >( "VisibleNodes" ).size(); statistics.nNotAvailable = 0; statistics.nRenderAvailable = statistics.nAvailable; }