载入中...
搜索中...
未找到
BrushKernel.cpp
浏览该文件的文档.
2
3#include "common/Exception.h"
4
5#include <algorithm>
6#include <cmath>
7
8namespace eve::editor {
9namespace {
10ConstantBrushFalloff defaultFalloff;
11float weightAt(const IBrushFalloff *falloff, float distance) {
12 return std::clamp((falloff ? falloff : &defaultFalloff)->evaluate(distance), 0.f, 1.f);
13}
14EditRegion squareBounds(const BrushSample &sample) {
15 const float radius = std::max(0.f, sample.radius);
16 EditRegion region;
17 region.minX = static_cast<int>(std::floor(sample.centerX - radius));
18 region.minY = static_cast<int>(std::floor(sample.centerY - radius));
19 region.maxX = static_cast<int>(std::ceil(sample.centerX + radius));
20 region.maxY = static_cast<int>(std::ceil(sample.centerY + radius));
21 return region;
22}
23} // namespace
24
25float ConstantBrushFalloff::evaluate(float normalizedDistance) const {
26 return normalizedDistance <= 1.f ? 1.f : 0.f;
27}
28float LinearBrushFalloff::evaluate(float normalizedDistance) const {
29 return std::clamp(1.f - normalizedDistance, 0.f, 1.f);
30}
31float SmoothBrushFalloff::evaluate(float normalizedDistance) const {
32 const float t = std::clamp(1.f - normalizedDistance, 0.f, 1.f);
33 return t * t * (3.f - 2.f * t);
34}
35
36CircleBrushKernel::CircleBrushKernel(const IBrushFalloff *falloff) : falloff_(falloff) {}
37EditRegion CircleBrushKernel::bounds(const BrushSample &sample) const { return squareBounds(sample); }
38void CircleBrushKernel::sample(const BrushSample &sample, IBrushSampleSink &sink) const {
39 const float radius = std::max(0.f, sample.radius);
40 const EditRegion region = bounds(sample);
41 for (int y = region.minY; y <= region.maxY; ++y) {
42 for (int x = region.minX; x <= region.maxX; ++x) {
43 const float dx = static_cast<float>(x) - sample.centerX;
44 const float dy = static_cast<float>(y) - sample.centerY;
45 const float distance = std::sqrt(dx * dx + dy * dy);
46 if (distance > radius) continue;
47 sink.emit(x, y, weightAt(falloff_, radius > 0.f ? distance / radius : 0.f));
48 }
49 }
50}
51
52BoxBrushKernel::BoxBrushKernel(const IBrushFalloff *falloff) : falloff_(falloff) {}
53EditRegion BoxBrushKernel::bounds(const BrushSample &sample) const { return squareBounds(sample); }
54void BoxBrushKernel::sample(const BrushSample &sample, IBrushSampleSink &sink) const {
55 const float radius = std::max(0.f, sample.radius);
56 const float c = std::cos(-sample.rotation);
57 const float s = std::sin(-sample.rotation);
58 const EditRegion region = bounds(sample);
59 for (int y = region.minY; y <= region.maxY; ++y) {
60 for (int x = region.minX; x <= region.maxX; ++x) {
61 const float dx = static_cast<float>(x) - sample.centerX;
62 const float dy = static_cast<float>(y) - sample.centerY;
63 const float localX = c * dx - s * dy;
64 const float localY = s * dx + c * dy;
65 const float distance = std::max(std::abs(localX), std::abs(localY));
66 if (distance > radius) continue;
67 sink.emit(x, y, weightAt(falloff_, radius > 0.f ? distance / radius : 0.f));
68 }
69 }
70}
71
72void BrushSampleBuffer::emit(int x, int y, float weight) { points_.push_back({x, y, weight}); }
74 if (index < 0 || index >= size()) throw Exception("BrushSampleBuffer::point: bad index");
75 return points_[static_cast<size_t>(index)];
76}
77
78} // namespace eve::editor
float y
Definition AnimClip.cpp:738
float x
Definition AnimClip.cpp:738
const std::string & s
std::int32_t c
float distance
float radius
float t
float dy
float dx
uint32_t index
EVENGINE_API_FOUNDATION public API.
Definition Exception.h:13
EditRegion bounds(const BrushSample &sample) const override
Bounds.
void sample(const BrushSample &sample, IBrushSampleSink &sink) const override
Sample.
BoxBrushKernel(const IBrushFalloff *falloff=nullptr)
Box brush kernel.
int size() const
Returns the size of .
const BrushPoint & point(int index) const
Point.
void emit(int x, int y, float weight) override
Emit.
CircleBrushKernel(const IBrushFalloff *falloff=nullptr)
Circle brush kernel.
EditRegion bounds(const BrushSample &sample) const override
Bounds.
void sample(const BrushSample &sample, IBrushSampleSink &sink) const override
Sample.
float evaluate(float normalizedDistance) const override
Evaluate.
Replaceable mapping from normalized distance to brush strength.
Definition BrushKernel.h:36
Receives weighted points without constraining their storage.
Definition BrushKernel.h:27
virtual void emit(int x, int y, float weight)=0
Emit.
float evaluate(float normalizedDistance) const override
Evaluate.
float evaluate(float normalizedDistance) const override
Evaluate.
eve::editing::EditRegion EditRegion
Definition EditorTarget.h:5
double sample(const Heightmap &map, double u, double v)
Sample.
std::vector< OnnxNamedTensor > evaluate(const ModelData &, std::span< const OnnxNamedTensor >, const std::vector< std::string > &, OnnxCompute *, OnnxRunOptions options)
Evaluate.
EditRegion public API.
One weighted grid coordinate emitted by a brush kernel.
Definition BrushKernel.h:20
Location and size passed to an interchangeable brush kernel.
Definition BrushKernel.h:12
glm::vec4 bounds