Support generating pcg::lazy_perlin subview

This commit is contained in:
Nikita Lisitsa 2022-06-30 23:09:28 +03:00
parent 079157f201
commit 06313a0234

View file

@ -59,6 +59,28 @@ namespace psemek::pcg
}
template <typename T, std::size_t N>
struct lazy_perlin_view
{
using value_type = T;
static constexpr auto dimension = N;
lazy_perlin_view() = default;
lazy_perlin_view(std::size_t grid_size, geom::vector<int, N> const & view_origin, util::array<geom::vector<T, N>, N> subgrid)
: grid_size_(grid_size)
, origin_(view_origin)
, subgrid_(std::move(subgrid))
{}
T operator()(geom::vector<T, N> p) const;
private:
int grid_size_;
geom::vector<int, N> origin_;
util::array<geom::vector<T, N>, N> subgrid_;
};
template <typename T, std::size_t N>
struct lazy_perlin
{
@ -74,6 +96,8 @@ namespace psemek::pcg
T operator()(geom::vector<T, N> p) const;
auto subview(geom::box<T, N> const & box) const;
private:
int const grid_size_;
mutable std::unordered_map<geom::vector<int, N>, geom::vector<T, N>> grid_;
@ -133,12 +157,51 @@ namespace psemek::pcg
}
};
template <typename T, std::size_t N>
T lazy_perlin_view<T, N>::operator()(geom::vector<T, N> p) const
{
return detail::perlin_impl(p, grid_size_, [this](auto const & c){
return subgrid_(c - origin_);
}, [this](auto p){
for (std::size_t i = 0; i < N; ++i)
{
p[i] = std::max<int>(p[i], origin_[i]);
p[i] = std::min<int>(p[i], origin_[i] + subgrid_.dim(i));
}
return p;
});
}
template <typename T, std::size_t N>
T lazy_perlin<T, N>::operator()(geom::vector<T, N> p) const
{
return detail::perlin_impl(p, grid_size_, [this](auto const & c){ return grid_at(c); }, [](auto const & p){ return p; });
}
template <typename T, std::size_t N>
auto lazy_perlin<T, N>::subview(geom::box<T, N> const & box) const
{
geom::vector<int, N> subgrid_origin;
std::array<std::size_t, N> subgrid_dimensions;
for (std::size_t i = 0; i < N; ++i)
{
subgrid_origin[i] = std::floor(box[i].min / grid_size_);
int subgrid_max = std::ceil(box[i].max / grid_size_);
subgrid_dimensions[i] = subgrid_max - subgrid_origin[i] + 1;
}
util::array<geom::vector<T, N>, N> subgrid(subgrid_dimensions);
for (auto const idx : subgrid.indices())
{
geom::vector<int, N> id;
for (std::size_t i = 0; i < N; ++i)
id[i] = subgrid_origin[i] + idx[i];
subgrid(idx) = grid_at(id);
}
return lazy_perlin_view<T, N>(grid_size_, subgrid_origin, std::move(subgrid));
}
template <typename T, std::size_t N>
T bounded_lazy_perlin<T, N>::operator()(geom::vector<T, N> p) const
{