void Histogram::add(const Histogram& hist) { assert(hist.getBins() == m_bins); assert(hist.getBinSize() == -1); // assume log histogram assert(m_binsize == -1); for (int j = 0; j < hist.getData(0); j++) { add(0); } for (int i = 1; i < m_bins; i++) { for (int j = 0; j < hist.getData(i); j++) { add(1<<(i-1)); // account for the + 1 index } } }
void execute(const FutureMap& input, PromiseMap& output) const { const auto& frustums = input.get<Frustum>("Frustum"); const auto& viewports = input.get<Viewport>("RelativeViewport"); auto dataSourceRange = input.get<Vector2f>("DataSourceRange").front(); const auto& frustum = frustums.front(); const auto& viewport = viewports.front(); Histogram histogramAccumulated; for (const auto& cacheObjects : input.getFutures("CacheObjects")) for (const auto& cacheObject : cacheObjects.get<ConstCacheObjects>()) { const CacheId& cacheId = cacheObject->getId(); // Hist cache object expands the data source range if data has // larger values ConstHistogramObjectPtr histCacheObject = _histogramCache.load<HistogramObject>(cacheId, _dataCache, _dataSource, dataSourceRange); if (!histCacheObject) continue; const Vector2f& currentRange = histCacheObject->getHistogram().getRange(); if (currentRange[0] < dataSourceRange[0]) dataSourceRange[0] = currentRange[0]; histogramAccumulated.setMin(dataSourceRange[0]); if (currentRange[1] > dataSourceRange[1]) dataSourceRange[1] = currentRange[1]; histogramAccumulated.setMax(dataSourceRange[1]); const size_t currentBinCount = histCacheObject->getHistogram().getBins().size(); if (histogramAccumulated.getBins().empty()) histogramAccumulated.resize(currentBinCount); // When a frame is rendered in multi-channel, multi-node, etc // config, some nodes are rendered twice in sort-first // renderings // To avoid counting nodes twice, we check if the center of the // node is in // this frustum (because it can only be in one tile at a time). // For viewports // on the border of the absolute viewport, the frustum is // virtually extended // to infinity on the boundary. try { const LODNode& lodNode = _dataSource.getNode(NodeId(cacheId)); if (isCenterInViewport(frustum, lodNode.getWorldBox(), viewport)) histogramAccumulated += histCacheObject->getHistogram(); } catch (const std::runtime_error&) { // Only compatible histograms can be added.( i.e same data // range and number of // bins.) Until data range converges to the full data range // combined from other // rendering clients, the cache objects are purged from the // cache. _histogramCache.purge(cacheId); } } output.set("Histogram", histogramAccumulated); }