Optimize vecr::renderer by using primitive's bbox
This commit is contained in:
parent
2e2df09790
commit
f70cdf9d8e
22 changed files with 245 additions and 16 deletions
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <psemek/vecr/invert.hpp>
|
#include <psemek/vecr/invert.hpp>
|
||||||
#include <psemek/vecr/intersect.hpp>
|
#include <psemek/vecr/intersect.hpp>
|
||||||
|
#include <psemek/geom/box.hpp>
|
||||||
|
|
||||||
namespace psemek::vecr
|
namespace psemek::vecr
|
||||||
{
|
{
|
||||||
|
|
@ -14,4 +15,6 @@ namespace psemek::vecr
|
||||||
|
|
||||||
sdf_sample sdf(add const & s, geom::point<float, 2> const & p);
|
sdf_sample sdf(add const & s, geom::point<float, 2> const & p);
|
||||||
|
|
||||||
|
geom::box<float, 2> bbox(add const & s);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,12 +2,52 @@
|
||||||
|
|
||||||
#include <psemek/vecr/sdf.hpp>
|
#include <psemek/vecr/sdf.hpp>
|
||||||
#include <psemek/geom/point.hpp>
|
#include <psemek/geom/point.hpp>
|
||||||
|
#include <psemek/geom/box.hpp>
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
namespace psemek::vecr
|
namespace psemek::vecr
|
||||||
{
|
{
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
struct any_base
|
||||||
|
{
|
||||||
|
virtual sdf_sample sdf_func(geom::point<float, 2> const & p) const = 0;
|
||||||
|
virtual geom::box<float, 2> bbox_func() const = 0;
|
||||||
|
|
||||||
|
virtual ~any_base() {}
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename Shape>
|
||||||
|
struct any_impl
|
||||||
|
: any_base
|
||||||
|
{
|
||||||
|
any_impl(Shape && shape)
|
||||||
|
: shape(std::move(shape))
|
||||||
|
{}
|
||||||
|
|
||||||
|
any_impl(Shape const & shape)
|
||||||
|
: shape(shape)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Shape shape;
|
||||||
|
|
||||||
|
sdf_sample sdf_func(geom::point<float, 2> const & p) const override
|
||||||
|
{
|
||||||
|
return sdf(shape, p);
|
||||||
|
}
|
||||||
|
|
||||||
|
geom::box<float, 2> bbox_func() const override
|
||||||
|
{
|
||||||
|
return bbox(shape);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
struct any
|
struct any
|
||||||
{
|
{
|
||||||
any() = default;
|
any() = default;
|
||||||
|
|
@ -26,26 +66,30 @@ namespace psemek::vecr
|
||||||
template <typename Shape>
|
template <typename Shape>
|
||||||
any & operator = (Shape && shape)
|
any & operator = (Shape && shape)
|
||||||
{
|
{
|
||||||
sdf_ = [shape = std::forward<Shape>(shape)](geom::point<float, 2> const & p){
|
impl_ = std::make_shared<detail::any_impl<std::decay_t<Shape>>>(std::move(shape));
|
||||||
return sdf(shape, p);
|
|
||||||
};
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
explicit operator bool() const
|
explicit operator bool() const
|
||||||
{
|
{
|
||||||
return static_cast<bool>(sdf_);
|
return static_cast<bool>(impl_);
|
||||||
}
|
}
|
||||||
|
|
||||||
friend sdf_sample sdf(any const & s, geom::point<float, 2> const & p);
|
friend sdf_sample sdf(any const & s, geom::point<float, 2> const & p);
|
||||||
|
friend geom::box<float, 2> bbox(any const & s);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::function<sdf_sample(geom::point<float, 2> const &)> sdf_;
|
std::shared_ptr<detail::any_base> impl_;
|
||||||
};
|
};
|
||||||
|
|
||||||
inline sdf_sample sdf(any const & s, geom::point<float, 2> const & p)
|
inline sdf_sample sdf(any const & s, geom::point<float, 2> const & p)
|
||||||
{
|
{
|
||||||
return s.sdf_ ? s.sdf_(p) : sdf_sample{};
|
return s.impl_ ? s.impl_->sdf_func(p) : sdf_sample{};
|
||||||
|
}
|
||||||
|
|
||||||
|
inline geom::box<float, 2> bbox(any const & s)
|
||||||
|
{
|
||||||
|
return s.impl_ ? s.impl_->bbox_func() : geom::box<float, 2>{};
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <psemek/vecr/sdf.hpp>
|
#include <psemek/vecr/sdf.hpp>
|
||||||
#include <psemek/geom/point.hpp>
|
#include <psemek/geom/point.hpp>
|
||||||
|
#include <psemek/geom/box.hpp>
|
||||||
|
|
||||||
namespace psemek::vecr
|
namespace psemek::vecr
|
||||||
{
|
{
|
||||||
|
|
@ -24,4 +25,10 @@ namespace psemek::vecr
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Shape>
|
||||||
|
geom::box<float, 2> bbox(border<Shape> const & s)
|
||||||
|
{
|
||||||
|
return bbox(s.shape);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <psemek/vecr/sdf.hpp>
|
#include <psemek/vecr/sdf.hpp>
|
||||||
#include <psemek/geom/point.hpp>
|
#include <psemek/geom/point.hpp>
|
||||||
|
#include <psemek/geom/box.hpp>
|
||||||
|
|
||||||
namespace psemek::vecr
|
namespace psemek::vecr
|
||||||
{
|
{
|
||||||
|
|
@ -14,4 +15,6 @@ namespace psemek::vecr
|
||||||
|
|
||||||
sdf_sample sdf(circle const & s, geom::point<float, 2> const & p);
|
sdf_sample sdf(circle const & s, geom::point<float, 2> const & p);
|
||||||
|
|
||||||
|
geom::box<float, 2> bbox(circle const & s);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <psemek/vecr/sdf.hpp>
|
#include <psemek/vecr/sdf.hpp>
|
||||||
#include <psemek/geom/point.hpp>
|
#include <psemek/geom/point.hpp>
|
||||||
|
#include <psemek/geom/box.hpp>
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
|
||||||
|
|
@ -55,4 +56,10 @@ namespace psemek::vecr
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Shape>
|
||||||
|
geom::box<float, 2> bbox(exact<Shape> const & s)
|
||||||
|
{
|
||||||
|
return bbox(s.shape);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <psemek/vecr/path.hpp>
|
#include <psemek/vecr/path.hpp>
|
||||||
|
#include <psemek/geom/box.hpp>
|
||||||
|
|
||||||
namespace psemek::vecr
|
namespace psemek::vecr
|
||||||
{
|
{
|
||||||
|
|
@ -12,4 +13,6 @@ namespace psemek::vecr
|
||||||
|
|
||||||
sdf_sample sdf(fill const & s, geom::point<float, 2> const & p);
|
sdf_sample sdf(fill const & s, geom::point<float, 2> const & p);
|
||||||
|
|
||||||
|
geom::box<float, 2> bbox(fill const & s);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <psemek/vecr/sdf.hpp>
|
#include <psemek/vecr/sdf.hpp>
|
||||||
#include <psemek/geom/point.hpp>
|
#include <psemek/geom/point.hpp>
|
||||||
|
#include <psemek/geom/box.hpp>
|
||||||
|
|
||||||
namespace psemek::vecr
|
namespace psemek::vecr
|
||||||
{
|
{
|
||||||
|
|
@ -21,4 +22,10 @@ namespace psemek::vecr
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Shape>
|
||||||
|
geom::box<float, 2> bbox(grow<Shape> const & s)
|
||||||
|
{
|
||||||
|
return geom::expand(bbox(s.shape), s.distance);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <psemek/vecr/sdf.hpp>
|
#include <psemek/vecr/sdf.hpp>
|
||||||
#include <psemek/geom/point.hpp>
|
#include <psemek/geom/point.hpp>
|
||||||
|
#include <psemek/geom/box.hpp>
|
||||||
|
|
||||||
namespace psemek::vecr
|
namespace psemek::vecr
|
||||||
{
|
{
|
||||||
|
|
@ -17,4 +18,10 @@ namespace psemek::vecr
|
||||||
return {geom::dot(p - s.origin, s.normal), s.normal};
|
return {geom::dot(p - s.origin, s.normal), s.normal};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline geom::box<float, 2> bbox(halfspace const &)
|
||||||
|
{
|
||||||
|
return geom::box<float, 2>::full();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#include <psemek/vecr/any.hpp>
|
#include <psemek/vecr/any.hpp>
|
||||||
#include <psemek/geom/point.hpp>
|
#include <psemek/geom/point.hpp>
|
||||||
#include <psemek/geom/math.hpp>
|
#include <psemek/geom/math.hpp>
|
||||||
|
#include <psemek/geom/box.hpp>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
@ -18,4 +19,6 @@ namespace psemek::vecr
|
||||||
|
|
||||||
sdf_sample sdf(intersect const & s, geom::point<float, 2> const & p);
|
sdf_sample sdf(intersect const & s, geom::point<float, 2> const & p);
|
||||||
|
|
||||||
|
geom::box<float, 2> bbox(intersect const & s);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <psemek/vecr/sdf.hpp>
|
#include <psemek/vecr/sdf.hpp>
|
||||||
#include <psemek/geom/point.hpp>
|
#include <psemek/geom/point.hpp>
|
||||||
|
#include <psemek/geom/box.hpp>
|
||||||
|
|
||||||
namespace psemek::vecr
|
namespace psemek::vecr
|
||||||
{
|
{
|
||||||
|
|
@ -21,4 +22,10 @@ namespace psemek::vecr
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Shape>
|
||||||
|
geom::box<float, 2> bbox(invert<Shape> const &)
|
||||||
|
{
|
||||||
|
return geom::box<float, 2>::full();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <psemek/vecr/sdf.hpp>
|
#include <psemek/vecr/sdf.hpp>
|
||||||
#include <psemek/geom/point.hpp>
|
#include <psemek/geom/point.hpp>
|
||||||
|
#include <psemek/geom/box.hpp>
|
||||||
|
|
||||||
namespace psemek::vecr
|
namespace psemek::vecr
|
||||||
{
|
{
|
||||||
|
|
@ -34,4 +35,24 @@ namespace psemek::vecr
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Shape>
|
||||||
|
geom::box<float, 2> bbox(mirror<Shape> const & s)
|
||||||
|
{
|
||||||
|
geom::box<float, 2> result;
|
||||||
|
|
||||||
|
auto sbox = bbox(s.shape);
|
||||||
|
|
||||||
|
for (int x = 0; x <= 1; ++x)
|
||||||
|
{
|
||||||
|
for (int y = 0; y <= 1; ++y)
|
||||||
|
{
|
||||||
|
auto p = sbox.corner(x, y);
|
||||||
|
p = p - (2.f * geom::dot(s.axis, p - s.origin)) * s.axis;
|
||||||
|
result |= p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
#include <psemek/vecr/sdf.hpp>
|
#include <psemek/vecr/sdf.hpp>
|
||||||
#include <psemek/geom/point.hpp>
|
#include <psemek/geom/point.hpp>
|
||||||
|
#include <psemek/geom/box.hpp>
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
@ -15,4 +16,6 @@ namespace psemek::vecr
|
||||||
|
|
||||||
sdf_sample sdf(path const & s, geom::point<float, 2> const & p, bool closed = false);
|
sdf_sample sdf(path const & s, geom::point<float, 2> const & p, bool closed = false);
|
||||||
|
|
||||||
|
geom::box<float, 2> bbox(path const & s);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,7 @@ namespace psemek::vecr
|
||||||
geom::vector<std::size_t, 2> size() const;
|
geom::vector<std::size_t, 2> size() const;
|
||||||
std::size_t samples() const;
|
std::size_t samples() const;
|
||||||
gfx::pixmap_rgba const & result() const;
|
gfx::pixmap_rgba const & result() const;
|
||||||
|
gfx::pixmap_rgba release();
|
||||||
|
|
||||||
void clear(gfx::color_rgba const & color = {0, 0, 0, 0});
|
void clear(gfx::color_rgba const & color = {0, 0, 0, 0});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,4 +20,10 @@ namespace psemek::vecr
|
||||||
return sdf(intersect{{s.shape1, invert{s.shape2}}, s.smooth}, p);
|
return sdf(intersect{{s.shape1, invert{s.shape2}}, s.smooth}, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Shape1, typename Shape2>
|
||||||
|
geom::box<float, 2> bbox(subtract<Shape1, Shape2> const & s)
|
||||||
|
{
|
||||||
|
return bbox(s.shape1);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -25,4 +25,10 @@ namespace psemek::vecr
|
||||||
return sdf(s.shape, q);
|
return sdf(s.shape, q);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Shape>
|
||||||
|
geom::box<float, 2> bbox(tile<Shape> const &)
|
||||||
|
{
|
||||||
|
return geom::box<float, 2>::full();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include <psemek/geom/matrix.hpp>
|
#include <psemek/geom/matrix.hpp>
|
||||||
#include <psemek/geom/homogeneous.hpp>
|
#include <psemek/geom/homogeneous.hpp>
|
||||||
#include <psemek/geom/gauss.hpp>
|
#include <psemek/geom/gauss.hpp>
|
||||||
|
#include <psemek/geom/box.hpp>
|
||||||
|
|
||||||
namespace psemek::vecr
|
namespace psemek::vecr
|
||||||
{
|
{
|
||||||
|
|
@ -45,6 +46,12 @@ namespace psemek::vecr
|
||||||
return sdf(s.shape, p - s.delta);
|
return sdf(s.shape, p - s.delta);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Shape>
|
||||||
|
geom::box<float, 2> bbox(translate<Shape> const & s)
|
||||||
|
{
|
||||||
|
return bbox(s.shape) + s.delta;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Shape>
|
template <typename Shape>
|
||||||
sdf_sample sdf(rotate<Shape> const & s, geom::point<float, 2> const & p)
|
sdf_sample sdf(rotate<Shape> const & s, geom::point<float, 2> const & p)
|
||||||
{
|
{
|
||||||
|
|
@ -53,6 +60,20 @@ namespace psemek::vecr
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Shape>
|
||||||
|
geom::box<float, 2> bbox(rotate<Shape> const & s)
|
||||||
|
{
|
||||||
|
auto sbox = bbox(s.shape);
|
||||||
|
|
||||||
|
geom::box<float, 2> result;
|
||||||
|
|
||||||
|
for (int y = 0; y <= 1; ++y)
|
||||||
|
for (int x = 0; x <= 1; ++x)
|
||||||
|
result |= s.origin + geom::rotate(sbox.corner(x, y) - s.origin, s.angle);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Shape>
|
template <typename Shape>
|
||||||
sdf_sample sdf(scale<Shape> const & s, geom::point<float, 2> const & p)
|
sdf_sample sdf(scale<Shape> const & s, geom::point<float, 2> const & p)
|
||||||
{
|
{
|
||||||
|
|
@ -65,6 +86,20 @@ namespace psemek::vecr
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Shape>
|
||||||
|
geom::box<float, 2> bbox(scale<Shape> const & s)
|
||||||
|
{
|
||||||
|
auto sbox = bbox(s.shape);
|
||||||
|
|
||||||
|
geom::box<float, 2> result;
|
||||||
|
|
||||||
|
for (int y = 0; y <= 1; ++y)
|
||||||
|
for (int x = 0; x <= 1; ++x)
|
||||||
|
result |= s.origin + (sbox.corner(x, y) - s.origin) * s.factor;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename Shape>
|
template <typename Shape>
|
||||||
sdf_sample sdf(transform<Shape> const & s, geom::point<float, 2> const & p)
|
sdf_sample sdf(transform<Shape> const & s, geom::point<float, 2> const & p)
|
||||||
{
|
{
|
||||||
|
|
@ -89,5 +124,18 @@ namespace psemek::vecr
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Shape>
|
||||||
|
geom::box<float, 2> bbox(transform<Shape> const & s)
|
||||||
|
{
|
||||||
|
auto sbox = bbox(s.shape);
|
||||||
|
|
||||||
|
geom::box<float, 2> result;
|
||||||
|
|
||||||
|
for (int y = 0; y <= 1; ++y)
|
||||||
|
for (int x = 0; x <= 1; ++x)
|
||||||
|
result |= geom::as_point(s.matrix * geom::homogeneous(sbox.corner(x, y)));
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -38,4 +38,12 @@ namespace psemek::vecr
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
geom::box<float, 2> bbox(add const & s)
|
||||||
|
{
|
||||||
|
geom::box<float, 2> result;
|
||||||
|
for (auto const & ss : s.shapes)
|
||||||
|
result |= bbox(ss);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,4 +12,9 @@ namespace psemek::vecr
|
||||||
return {l - s.radius, {0.f, 0.f}};
|
return {l - s.radius, {0.f, 0.f}};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
geom::box<float, 2> bbox(circle const & s)
|
||||||
|
{
|
||||||
|
return geom::expand(geom::box<float, 2>::singleton(s.center), s.radius);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -29,4 +29,9 @@ namespace psemek::vecr
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
geom::box<float, 2> bbox(fill const & s)
|
||||||
|
{
|
||||||
|
return bbox(s.border);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -39,4 +39,12 @@ namespace psemek::vecr
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
geom::box<float, 2> bbox(intersect const & s)
|
||||||
|
{
|
||||||
|
auto result = geom::box<float, 2>::full();
|
||||||
|
for (auto const & ss : s.shapes)
|
||||||
|
result &= bbox(ss);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -27,4 +27,14 @@ namespace psemek::vecr
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
geom::box<float, 2> bbox(path const & s)
|
||||||
|
{
|
||||||
|
geom::box<float, 2> result;
|
||||||
|
|
||||||
|
for (auto const & p : s.points)
|
||||||
|
result |= p;
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,13 @@ namespace psemek::vecr
|
||||||
return result_;
|
return result_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
gfx::pixmap_rgba renderer::release()
|
||||||
|
{
|
||||||
|
resolve();
|
||||||
|
canvas_.clear();
|
||||||
|
return std::move(result_);
|
||||||
|
}
|
||||||
|
|
||||||
void renderer::clear(gfx::color_rgba const & color)
|
void renderer::clear(gfx::color_rgba const & color)
|
||||||
{
|
{
|
||||||
canvas_.fill(color);
|
canvas_.fill(color);
|
||||||
|
|
@ -39,22 +46,32 @@ namespace psemek::vecr
|
||||||
{
|
{
|
||||||
float const aa = primitive.blur / 2.f;
|
float const aa = primitive.blur / 2.f;
|
||||||
|
|
||||||
for (auto const & idx : canvas_.indices())
|
auto const box = geom::expand(bbox(primitive.mask), aa);
|
||||||
|
|
||||||
|
int xmin = std::max<int>(0, std::floor(box[0].min) * samples_);
|
||||||
|
int xmax = std::min<int>(canvas_.width() - 1, std::ceil(box[0].max) * samples_);
|
||||||
|
int ymin = std::max<int>(0, std::floor(box[1].min) * samples_);
|
||||||
|
int ymax = std::min<int>(canvas_.height() - 1, std::ceil(box[1].max) * samples_);
|
||||||
|
|
||||||
|
for (int y = ymin; y < ymax; ++y)
|
||||||
{
|
{
|
||||||
geom::point const center{(idx[0] + 0.5f) / samples_, (idx[1] + 0.5f) / samples_};
|
for (int x = xmin; x < xmax; ++x)
|
||||||
|
{
|
||||||
|
geom::point const center{(x + 0.5f) / samples_, (y + 0.5f) / samples_};
|
||||||
|
|
||||||
auto const sample = sdf(primitive.mask, center);
|
auto const sample = sdf(primitive.mask, center);
|
||||||
|
|
||||||
if (sample.value > aa) continue;
|
if (sample.value > aa) continue;
|
||||||
|
|
||||||
float blur = 1.f;
|
float blur = 1.f;
|
||||||
if (sample.value > - aa)
|
if (sample.value > - aa)
|
||||||
blur = (aa - sample.value) / (2.f * aa);
|
blur = (aa - sample.value) / (2.f * aa);
|
||||||
|
|
||||||
auto color = colorize(primitive.colorizer, center, sample);
|
auto color = colorize(primitive.colorizer, center, sample);
|
||||||
color[3] *= blur;
|
color[3] *= blur;
|
||||||
|
|
||||||
canvas_(idx) = gfx::to_coloru8(primitive.blend(gfx::to_colorf(canvas_(idx)), color));
|
canvas_(x, y) = gfx::to_coloru8(primitive.blend(gfx::to_colorf(canvas_(x, y)), color));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
need_resolve_ = true;
|
need_resolve_ = true;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue