livre::MemoryUnitPtr sample( const livre::LODNode& node, const livre::VolumeInformation& info ) const { // called from multiple render threads, only have one update running lunchbox::ScopedWrite mutex( _lock ); EventSourcePtr loader = source->getEventSource(); const uint32_t timeStep = node.getNodeId().getTimeStep(); loader->setTime( timeStep ); const vmml::Vector3i& voxels = info.maximumBlockSize; ByteVolume::SizeType vSize; vSize[0] = voxels[0]; vSize[1] = voxels[1]; vSize[2] = voxels[2]; ByteVolume::RegionType region; region.SetSize( vSize ); // Real-world coordinate setup const AABBf& bbox = source->getBoundingBox(); const Vector3f& baseSpacing = ( bbox.getSize() + _borders ) / info.voxels; const int32_t levelFromBottom = info.rootNode.getDepth() - 1 - node.getRefLevel(); const float spacingFactor = 1 << levelFromBottom; ByteVolume::SpacingType spacing; spacing[0] = baseSpacing.find_max() * spacingFactor; spacing[1] = spacing[0]; spacing[2] = spacing[0]; const Vector3f& offset = ( bbox.getMin() - _borders / 2.0f ) + node.getRelativePosition() * Vector3f( bbox.getSize() + _borders ); ByteVolume::PointType origin; origin[0] = offset[0]; origin[1] = offset[1]; origin[2] = offset[2]; auto volume = source->GetOutput(); volume->SetRegions( region ); volume->SetSpacing( spacing ); volume->SetOrigin( origin ); source->Modified(); scaler.Update(); const size_t size = voxels[0] * voxels[1] * voxels[2] * info.compCount * info.getBytesPerVoxel(); return livre::MemoryUnitPtr( new livre::AllocMemoryUnit( scaler.GetOutput()->GetBufferPointer(), size )); }
livre::MemoryUnitPtr sample( const livre::LODNode& node, const livre::VolumeInformation& info ) const { ::fivox::EventSourcePtr loader = source->getFunctor()->getSource(); const uint32_t frame = node.getNodeId().getFrame(); if( !loader->load( frame )) return livre::MemoryUnitPtr(); // Alloc voxels const vmml::Vector3i& voxels = info.maximumBlockSize; ByteVolume::SizeType vSize; vSize[0] = voxels[0]; vSize[1] = voxels[1]; vSize[2] = voxels[2]; ByteVolume::RegionType region; region.SetSize( vSize ); // Real-world coordinate setup const ::fivox::AABBf& bbox = loader->getBoundingBox(); const Vector3f& baseSpacing = ( bbox.getSize() + _borders ) / info.voxels; const int32_t levelFromBottom = info.rootNode.getDepth() - 1 - node.getRefLevel(); const float spacingFactor = 1 << levelFromBottom; ByteVolume::SpacingType spacing; spacing[0] = baseSpacing.find_max() * spacingFactor; spacing[1] = spacing[0]; spacing[2] = spacing[0]; const Vector3f& offset = ( bbox.getMin() - _borders / 2.0f ) + node.getRelativePosition() * Vector3f( bbox.getSize() + _borders ); ByteVolume::PointType origin; origin[0] = offset[0]; origin[1] = offset[1]; origin[2] = offset[2]; // called from multiple render threads, only have one update running lunchbox::ScopedWrite mutex( _lock ); VolumePtr output = source->GetOutput(); output->SetRegions( region ); output->SetSpacing( spacing ); output->SetOrigin( origin ); #ifdef LIVRE_DEBUG_RENDERING std::cout << "Sample " << node.getRefLevel() << ' ' << node.getRelativePosition() << " (" << spacing << " @ " << origin << 'x' << baseSpacing * spacingFactor * voxels << ")" << std::endl; #endif source->Modified(); source->Update(); livre::AllocMemoryUnitPtr memoryUnit( new livre::AllocMemoryUnit ); const size_t size = voxels[0] * voxels[1] * voxels[2] * info.compCount * info.getBytesPerVoxel(); memoryUnit->allocAndSetData( output->GetBufferPointer(), size ); return memoryUnit; }