InfluenceMap::InfluenceMap(const size_t width, const size_t height, const bool clamp_values_to_0_1, const float initial_influence) : _width(width), _height(height), _clamp_values_to_0_1(clamp_values_to_0_1) { // Of course, if width * height overflows size_t, we're screwed. No sane // person would use values that large of course... _data = new float[num_cells()]; _copy = new float[num_cells()]; const float clamped_influence = clamp_influence(initial_influence); for (size_t i = 0; i < num_cells(); i++) { _data[i] = clamped_influence; _copy[i] = clamped_influence; } }
// Implements a greedy algorithm that split cells using the bisection until a target cell size is // reached std::tuple<std::vector<Partition>, std::vector<std::uint32_t>> bisectionToPartition(const std::vector<BisectionID> &node_to_bisection_id, const std::vector<std::size_t> &max_cell_sizes) { std::vector<std::uint32_t> permutation(node_to_bisection_id.size()); std::iota(permutation.begin(), permutation.end(), 0); std::vector<CellBisection> cells; cells.push_back(CellBisection{ 0, static_cast<std::uint32_t>(node_to_bisection_id.size()), NUM_BISECTION_BITS - 1, false}); std::vector<Partition> partitions(max_cell_sizes.size()); std::vector<std::uint32_t> num_cells(max_cell_sizes.size()); int level_idx = max_cell_sizes.size() - 1; for (auto max_cell_size : boost::adaptors::reverse(max_cell_sizes)) { BOOST_ASSERT(level_idx >= 0); partitionLevel(node_to_bisection_id, max_cell_size, permutation, cells); partitions[level_idx] = cellsToPartition(cells, permutation); num_cells[level_idx] = cells.size(); level_idx--; } return std::make_tuple(std::move(partitions), std::move(num_cells)); }
void InfluenceMap::propagate(const float momentum, const float decay) { float connections_array[InfluenceMap::CONNECTIONS_ARRAY_LENGTH]; size_t x = 0; size_t y = 0; const float edge_distance = 1.0f; const float corner_distance = 1.414f; const float edge = expf(-edge_distance * decay); const float corner = expf(-corner_distance * decay); for (size_t i = 0; i < num_cells(); i++) { connections(x, y, connections_array, 1, 0); // Spread ////////////////////////////////////////////////////// float max_influence = 0; float neighbour_influence; neighbour_influence = connections_array[ConnectionIndex::TopLeft] * corner; if (neighbour_influence > max_influence) max_influence = neighbour_influence; neighbour_influence = connections_array[ConnectionIndex::TopMiddle] * edge; if (neighbour_influence > max_influence) max_influence = neighbour_influence; neighbour_influence = connections_array[ConnectionIndex::TopRight] * corner; if (neighbour_influence > max_influence) max_influence = neighbour_influence; neighbour_influence = connections_array[ConnectionIndex::MiddleRight] * edge; if (neighbour_influence > max_influence) max_influence = neighbour_influence; neighbour_influence = connections_array[ConnectionIndex::BottomRight] * corner; if (neighbour_influence > max_influence) max_influence = neighbour_influence; neighbour_influence = connections_array[ConnectionIndex::BottomMiddle] * edge; if (neighbour_influence > max_influence) max_influence = neighbour_influence; neighbour_influence = connections_array[ConnectionIndex::BottomLeft] * corner; if (neighbour_influence > max_influence) max_influence = neighbour_influence; neighbour_influence = connections_array[ConnectionIndex::MiddleLeft] * edge; if (neighbour_influence > max_influence) max_influence = neighbour_influence; // lerp //////////////////////////////////////////////////////// const float cur_influence = influence(x, y); const float result = (max_influence - cur_influence) * momentum + cur_influence; _copy[i] = clamp_influence(result); // Move on if (++x >= _width) { x = 0; y++; } } // Swap the buffers float * const tmp = _copy; _copy = _data; _data = tmp; }
void IrradianceVolume::write( DataStream& stream ) { stream.write_t(m_width); stream.write_t(m_height); stream.write_t(m_depth); stream.write_t(m_position); stream.write_t(m_dimensions); stream.write_t(m_cell_size); uint32 size = num_cells(); for(uint32 i=0; i<size; ++i ) { stream.write_t(m_cells[i]); } }
Problem::Problem (Input input_param) { /* Retrieve input parameters */ int num_reg = input_param.get_num_reg(); Col<int> num_cells = input_param.get_num_cells(); vec reg_size = input_param.get_reg_size(); string quad_type = input_param.get_quad_type(); Col<int> quad_order = input_param.get_quad_order(); vec abs_xs = input_param.get_abs_xs(); vec scat_xs = input_param.get_scat_xs(); vec ext_source = input_param.get_ext_source(); /* Create vector of pointers to each region */ Regions.resize(num_reg); for (int i=0; i<num_reg; i++){ Regions[i] = new Region(quad_order(i), num_cells(i), reg_size(i), \ abs_xs(i), scat_xs(i), ext_source(i), quad_type); } }
bool IrradianceVolume::read( DataStream& stream ) { delete m_cells; stream.read_t(m_width); stream.read_t(m_height); stream.read_t(m_depth); stream.read_t(m_position); stream.read_t(m_dimensions); stream.read_t(m_cell_size); const uint32 size = num_cells(); m_cells = new SphericalHarmonics3[size]; for(uint32 i=0; i<size; ++i ) { stream.read_t(m_cells[i]); } return true; }