예제 #1
0
    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));
}
예제 #3
0
 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;
 }
예제 #4
0
	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]);
		}
	}
예제 #5
0
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);
    }
    
}
예제 #6
0
	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;
	}