Proper brush configuration
This commit is contained in:
@@ -45,11 +45,240 @@ namespace
|
||||
|
||||
} // namespace
|
||||
|
||||
std::map<int, struct EditBrush *> EditBrushList::brushes;
|
||||
std::map<int, String> EditBrushList::brush_names;
|
||||
struct Brush0 : EditBrush
|
||||
{
|
||||
Brush0(Ref<Image> &image) : EditBrush(0, image, "Brush0")
|
||||
{
|
||||
}
|
||||
void draw(const Vector3 &v, float r, float s)
|
||||
{
|
||||
int i, j;
|
||||
int xs = 3 * r;
|
||||
float c = 0.5f;
|
||||
for (i = -xs; i < xs + 1; i++)
|
||||
for (j = -xs; j < xs + 1; j++)
|
||||
{
|
||||
float xr = Vector2(i, j).length();
|
||||
if (xr < r)
|
||||
{
|
||||
Vector3 pos(v.x + i, v.y, v.z + j);
|
||||
Vector2 pt = Vector2(pos.x * 0.1f + draw_image->get_width() / 2,
|
||||
pos.z * 0.1f + draw_image->get_height() / 2);
|
||||
pt.x = CLAMP(pt.x, 1, draw_image->get_width() - 1);
|
||||
pt.y = CLAMP(pt.y, 1, draw_image->get_height() - 1);
|
||||
draw_image->fill_rect(Rect2(pt - Vector2(1, 1), Vector2(2, 2)), Color(c, 0, 0, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct Brush1 : EditBrush
|
||||
{
|
||||
Brush1(Ref<Image> &image) : EditBrush(1, image, "Brush1")
|
||||
{
|
||||
}
|
||||
void draw(const Vector3 &v, float r, float s)
|
||||
{
|
||||
int i, j;
|
||||
int xs = 3 * r;
|
||||
float c = 0.5f;
|
||||
/* erase stuff */
|
||||
for (i = -xs; i < xs + 1; i++)
|
||||
for (j = -xs; j < xs + 1; j++)
|
||||
{
|
||||
float xr = Vector2(i, j).length();
|
||||
if (xr < r)
|
||||
{
|
||||
Vector3 pos(v.x + i, v.y, v.z + j);
|
||||
Vector2 pt = Vector2(pos.x * 0.1f + draw_image->get_width() / 2,
|
||||
pos.z * 0.1f + draw_image->get_height() / 2);
|
||||
pt.x = CLAMP(pt.x, 1, draw_image->get_width() - 1);
|
||||
pt.y = CLAMP(pt.y, 1, draw_image->get_height() - 1);
|
||||
draw_image->fill_rect(Rect2(pt - Vector2(1, 1), Vector2(2, 2)), Color(c, 0, 0, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct Brush2 : EditBrush
|
||||
{
|
||||
Ref<Curve> curve;
|
||||
Brush2(Ref<Image> &image, Ref<Curve> &curve)
|
||||
: EditBrush(2, image, "Brush2"), curve(curve)
|
||||
{
|
||||
}
|
||||
void draw(const Vector3 &v, float r, float s)
|
||||
{
|
||||
int i, j;
|
||||
int xs = 3 * r;
|
||||
float c = 0.5f;
|
||||
float scale = s / 100.0f;
|
||||
ERR_FAIL_COND(!curve.is_valid());
|
||||
for (i = -xs; i < xs + 1; i++)
|
||||
for (j = -xs; j < xs + 1; j++)
|
||||
{
|
||||
float xr = Vector2(i, j).length();
|
||||
if (xr < r)
|
||||
{
|
||||
float h = curve->interpolate_baked(xr / r) * scale;
|
||||
h = CLAMP(h, -100.0, 100.0f);
|
||||
c = (h + 100.0f) / 200.0;
|
||||
|
||||
Vector3 pos(v.x + i, v.y, v.z + j);
|
||||
Vector2 pt = Vector2(pos.x * 0.1f + draw_image->get_width() / 2,
|
||||
pos.z * 0.1f + draw_image->get_height() / 2);
|
||||
pt.x = CLAMP(pt.x, 1, draw_image->get_width() - 1);
|
||||
pt.y = CLAMP(pt.y, 1, draw_image->get_height() - 1);
|
||||
draw_image->fill_rect(Rect2(pt - Vector2(1, 1), Vector2(2, 2)), Color(c, 0, 0, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct Brush3 : EditBrush
|
||||
{
|
||||
Ref<Curve> curve;
|
||||
VoxelGeneratorImgMapper *imgmap;
|
||||
Brush3(Ref<Image> &image, Ref<Curve> &curve,
|
||||
VoxelGeneratorImgMapper *imgmap)
|
||||
: EditBrush(3, image, "Brush3"), curve(curve), imgmap(imgmap)
|
||||
{
|
||||
}
|
||||
void draw(const Vector3 &v, float r, float s)
|
||||
{
|
||||
int i, j;
|
||||
int xs = 3 * r;
|
||||
float c = 0.5f;
|
||||
float scale = s / 100.0f;
|
||||
/* rel draw curve1 */
|
||||
ERR_FAIL_COND(!curve.is_valid());
|
||||
for (i = -xs; i < xs + 1; i++)
|
||||
for (j = -xs; j < xs + 1; j++)
|
||||
{
|
||||
float xr = Vector2(i, j).length();
|
||||
if (xr < r)
|
||||
{
|
||||
float h = curve->interpolate_baked(xr / r) * scale;
|
||||
if (h < -2.0f || h > 2.0f)
|
||||
{
|
||||
h += imgmap->get_height_full(v + Vector3(i, 0.0f, j));
|
||||
h = CLAMP(h, -100.0, 100.0f);
|
||||
c = (h + 100.0f) / 200.0;
|
||||
|
||||
Vector3 pos(v.x + i, v.y, v.z + j);
|
||||
Vector2 pt = Vector2(pos.x * 0.1f + draw_image->get_width() / 2,
|
||||
pos.z * 0.1f + draw_image->get_height() / 2);
|
||||
pt.x = CLAMP(pt.x, 1, draw_image->get_width() - 1);
|
||||
pt.y = CLAMP(pt.y, 1, draw_image->get_height() - 1);
|
||||
draw_image->fill_rect(Rect2(pt - Vector2(1, 1), Vector2(2, 2)), Color(c, 0, 0, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct Brush4 : EditBrush
|
||||
{
|
||||
Ref<Curve> curve;
|
||||
VoxelGeneratorImgMapper *imgmap;
|
||||
Brush4(Ref<Image> &image, Ref<Curve> &curve,
|
||||
VoxelGeneratorImgMapper *imgmap)
|
||||
: EditBrush(4, image, "Brush4"), curve(curve), imgmap(imgmap)
|
||||
{
|
||||
}
|
||||
void draw(const Vector3 &v, float r, float s)
|
||||
{
|
||||
int i, j;
|
||||
int xs = 3 * r;
|
||||
float c = 0.5f;
|
||||
float scale = s / 100.0f;
|
||||
/* rel draw curve2 */
|
||||
ERR_FAIL_COND(!curve.is_valid());
|
||||
for (i = -xs; i < xs + 1; i++)
|
||||
for (j = -xs; j < xs + 1; j++)
|
||||
{
|
||||
float xr = Vector2(i, j).length();
|
||||
if (xr < r)
|
||||
{
|
||||
float h = curve->interpolate_baked(xr / r) * scale;
|
||||
if (h < -2.0f || h > 2.0f)
|
||||
{
|
||||
h += imgmap->get_height_full(v + Vector3(i, 0.0f, j));
|
||||
h = CLAMP(h, -100.0, 100.0f);
|
||||
c = (h + 100.0f) / 200.0;
|
||||
|
||||
Vector3 pos(v.x + i, v.y, v.z + j);
|
||||
Vector2 pt = Vector2(pos.x * 0.1f + draw_image->get_width() / 2,
|
||||
pos.z * 0.1f + draw_image->get_height() / 2);
|
||||
pt.x = CLAMP(pt.x, 1, draw_image->get_width() - 1);
|
||||
pt.y = CLAMP(pt.y, 1, draw_image->get_height() - 1);
|
||||
draw_image->fill_rect(Rect2(pt - Vector2(1, 1), Vector2(2, 2)), Color(c, 0, 0, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct Brush5 : EditBrush
|
||||
{
|
||||
VoxelGeneratorImgMapper *imgmap;
|
||||
Brush5(Ref<Image> &image,
|
||||
VoxelGeneratorImgMapper *imgmap)
|
||||
: EditBrush(5, image, "Brush5"), imgmap(imgmap)
|
||||
{
|
||||
}
|
||||
void draw(const Vector3 &v, float r, float s)
|
||||
{
|
||||
int i, j;
|
||||
int xs = 3 * r;
|
||||
float c = 0.5f;
|
||||
float scale = s / 100.0f;
|
||||
float h = imgmap->get_height_full(v) + 2.0f;
|
||||
h = CLAMP(h, -100.0, 100.0f);
|
||||
for (i = -8; i < 8 + 1; i++)
|
||||
for (j = -8; j < 8 + 1; j++)
|
||||
{
|
||||
Vector3 pos(v.x + i, v.y, v.z + j);
|
||||
h = MAX(h, imgmap->get_height_full(pos) + 2.0f);
|
||||
}
|
||||
c = (h + 100.0f) / 200.0;
|
||||
for (i = -xs; i < xs + 1; i++)
|
||||
for (j = -xs; j < xs + 1; j++)
|
||||
{
|
||||
float xr = Vector2(i, j).length();
|
||||
if (xr < r)
|
||||
{
|
||||
Vector3 pos(v.x + i, v.y, v.z + j);
|
||||
Vector2 pt = Vector2(pos.x * 0.1f + draw_image->get_width() / 2,
|
||||
pos.z * 0.1f + draw_image->get_height() / 2);
|
||||
pt.x = CLAMP(pt.x, 1, draw_image->get_width() - 1);
|
||||
pt.y = CLAMP(pt.y, 1, draw_image->get_height() - 1);
|
||||
draw_image->fill_rect(Rect2(pt - Vector2(1, 1), Vector2(2, 2)), Color(c, 0, 0, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
template <typename T, class... Args>
|
||||
T *RegBrush(Args &&...args)
|
||||
{
|
||||
static T data(std::forward<Args>(args)...);
|
||||
EditBrushList::register_brush(&data);
|
||||
return &data;
|
||||
}
|
||||
|
||||
VoxelGeneratorImgMapper::VoxelGeneratorImgMapper()
|
||||
: VoxelGeneratorHeightmap(),
|
||||
world_size(10240),
|
||||
grid_size(0)
|
||||
{
|
||||
RegBrush<Brush0>(_image_draw);
|
||||
RegBrush<Brush1>(_image_draw);
|
||||
RegBrush<Brush2>(_image_draw, curve1);
|
||||
RegBrush<Brush3>(_image_draw, curve1, this);
|
||||
RegBrush<Brush4>(_image_draw, curve2, this);
|
||||
RegBrush<Brush5>(_image_draw, this);
|
||||
}
|
||||
|
||||
VoxelGeneratorImgMapper::~VoxelGeneratorImgMapper()
|
||||
@@ -215,232 +444,11 @@ float VoxelGeneratorImgMapper::get_height_full(const Vector3 &v)
|
||||
return get_height(v) * 200.0f - 100.0f;
|
||||
}
|
||||
|
||||
std::map<int, struct EditBrush *> EditBrush::brushes;
|
||||
struct Brush0 : EditBrush
|
||||
{
|
||||
Brush0(Ref<Image> &image) : EditBrush(0, image)
|
||||
{
|
||||
}
|
||||
void draw(const Vector3 &v, float r, float s)
|
||||
{
|
||||
int i, j;
|
||||
int xs = 3 * r;
|
||||
float c = 0.5f;
|
||||
for (i = -xs; i < xs + 1; i++)
|
||||
for (j = -xs; j < xs + 1; j++)
|
||||
{
|
||||
float xr = Vector2(i, j).length();
|
||||
if (xr < r)
|
||||
{
|
||||
Vector3 pos(v.x + i, v.y, v.z + j);
|
||||
Vector2 pt = Vector2(pos.x * 0.1f + draw_image->get_width() / 2,
|
||||
pos.z * 0.1f + draw_image->get_height() / 2);
|
||||
pt.x = CLAMP(pt.x, 1, draw_image->get_width() - 1);
|
||||
pt.y = CLAMP(pt.y, 1, draw_image->get_height() - 1);
|
||||
draw_image->fill_rect(Rect2(pt - Vector2(1, 1), Vector2(2, 2)), Color(c, 0, 0, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct Brush1 : EditBrush
|
||||
{
|
||||
Brush1(Ref<Image> &image) : EditBrush(1, image)
|
||||
{
|
||||
}
|
||||
void draw(const Vector3 &v, float r, float s)
|
||||
{
|
||||
int i, j;
|
||||
int xs = 3 * r;
|
||||
float c = 0.5f;
|
||||
/* erase stuff */
|
||||
for (i = -xs; i < xs + 1; i++)
|
||||
for (j = -xs; j < xs + 1; j++)
|
||||
{
|
||||
float xr = Vector2(i, j).length();
|
||||
if (xr < r)
|
||||
{
|
||||
Vector3 pos(v.x + i, v.y, v.z + j);
|
||||
Vector2 pt = Vector2(pos.x * 0.1f + draw_image->get_width() / 2,
|
||||
pos.z * 0.1f + draw_image->get_height() / 2);
|
||||
pt.x = CLAMP(pt.x, 1, draw_image->get_width() - 1);
|
||||
pt.y = CLAMP(pt.y, 1, draw_image->get_height() - 1);
|
||||
draw_image->fill_rect(Rect2(pt - Vector2(1, 1), Vector2(2, 2)), Color(c, 0, 0, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct Brush2 : EditBrush
|
||||
{
|
||||
Ref<Curve> curve;
|
||||
Brush2(Ref<Image> &image, Ref<Curve> &curve)
|
||||
: EditBrush(2, image), curve(curve)
|
||||
{
|
||||
}
|
||||
void draw(const Vector3 &v, float r, float s)
|
||||
{
|
||||
int i, j;
|
||||
int xs = 3 * r;
|
||||
float c = 0.5f;
|
||||
float scale = s / 100.0f;
|
||||
ERR_FAIL_COND(!curve.is_valid());
|
||||
for (i = -xs; i < xs + 1; i++)
|
||||
for (j = -xs; j < xs + 1; j++)
|
||||
{
|
||||
float xr = Vector2(i, j).length();
|
||||
if (xr < r)
|
||||
{
|
||||
float h = curve->interpolate_baked(xr / r) * scale;
|
||||
h = CLAMP(h, -100.0, 100.0f);
|
||||
c = (h + 100.0f) / 200.0;
|
||||
|
||||
Vector3 pos(v.x + i, v.y, v.z + j);
|
||||
Vector2 pt = Vector2(pos.x * 0.1f + draw_image->get_width() / 2,
|
||||
pos.z * 0.1f + draw_image->get_height() / 2);
|
||||
pt.x = CLAMP(pt.x, 1, draw_image->get_width() - 1);
|
||||
pt.y = CLAMP(pt.y, 1, draw_image->get_height() - 1);
|
||||
draw_image->fill_rect(Rect2(pt - Vector2(1, 1), Vector2(2, 2)), Color(c, 0, 0, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct Brush3 : EditBrush
|
||||
{
|
||||
Ref<Curve> curve;
|
||||
VoxelGeneratorImgMapper *imgmap;
|
||||
Brush3(Ref<Image> &image, Ref<Curve> &curve,
|
||||
VoxelGeneratorImgMapper *imgmap)
|
||||
: EditBrush(3, image), curve(curve), imgmap(imgmap)
|
||||
{
|
||||
}
|
||||
void draw(const Vector3 &v, float r, float s)
|
||||
{
|
||||
int i, j;
|
||||
int xs = 3 * r;
|
||||
float c = 0.5f;
|
||||
float scale = s / 100.0f;
|
||||
/* rel draw curve1 */
|
||||
ERR_FAIL_COND(!curve.is_valid());
|
||||
for (i = -xs; i < xs + 1; i++)
|
||||
for (j = -xs; j < xs + 1; j++)
|
||||
{
|
||||
float xr = Vector2(i, j).length();
|
||||
if (xr < r)
|
||||
{
|
||||
float h = curve->interpolate_baked(xr / r) * scale;
|
||||
if (h < -2.0f || h > 2.0f)
|
||||
{
|
||||
h += imgmap->get_height_full(v + Vector3(i, 0.0f, j));
|
||||
h = CLAMP(h, -100.0, 100.0f);
|
||||
c = (h + 100.0f) / 200.0;
|
||||
|
||||
Vector3 pos(v.x + i, v.y, v.z + j);
|
||||
Vector2 pt = Vector2(pos.x * 0.1f + draw_image->get_width() / 2,
|
||||
pos.z * 0.1f + draw_image->get_height() / 2);
|
||||
pt.x = CLAMP(pt.x, 1, draw_image->get_width() - 1);
|
||||
pt.y = CLAMP(pt.y, 1, draw_image->get_height() - 1);
|
||||
draw_image->fill_rect(Rect2(pt - Vector2(1, 1), Vector2(2, 2)), Color(c, 0, 0, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct Brush4 : EditBrush
|
||||
{
|
||||
Ref<Curve> curve;
|
||||
VoxelGeneratorImgMapper *imgmap;
|
||||
Brush4(Ref<Image> &image, Ref<Curve> &curve,
|
||||
VoxelGeneratorImgMapper *imgmap)
|
||||
: EditBrush(4, image), curve(curve), imgmap(imgmap)
|
||||
{
|
||||
}
|
||||
void draw(const Vector3 &v, float r, float s)
|
||||
{
|
||||
int i, j;
|
||||
int xs = 3 * r;
|
||||
float c = 0.5f;
|
||||
float scale = s / 100.0f;
|
||||
/* rel draw curve2 */
|
||||
ERR_FAIL_COND(!curve.is_valid());
|
||||
for (i = -xs; i < xs + 1; i++)
|
||||
for (j = -xs; j < xs + 1; j++)
|
||||
{
|
||||
float xr = Vector2(i, j).length();
|
||||
if (xr < r)
|
||||
{
|
||||
float h = curve->interpolate_baked(xr / r) * scale;
|
||||
if (h < -2.0f || h > 2.0f)
|
||||
{
|
||||
h += imgmap->get_height_full(v + Vector3(i, 0.0f, j));
|
||||
h = CLAMP(h, -100.0, 100.0f);
|
||||
c = (h + 100.0f) / 200.0;
|
||||
|
||||
Vector3 pos(v.x + i, v.y, v.z + j);
|
||||
Vector2 pt = Vector2(pos.x * 0.1f + draw_image->get_width() / 2,
|
||||
pos.z * 0.1f + draw_image->get_height() / 2);
|
||||
pt.x = CLAMP(pt.x, 1, draw_image->get_width() - 1);
|
||||
pt.y = CLAMP(pt.y, 1, draw_image->get_height() - 1);
|
||||
draw_image->fill_rect(Rect2(pt - Vector2(1, 1), Vector2(2, 2)), Color(c, 0, 0, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct Brush5 : EditBrush
|
||||
{
|
||||
VoxelGeneratorImgMapper *imgmap;
|
||||
Brush5(Ref<Image> &image,
|
||||
VoxelGeneratorImgMapper *imgmap)
|
||||
: EditBrush(5, image), imgmap(imgmap)
|
||||
{
|
||||
}
|
||||
void draw(const Vector3 &v, float r, float s)
|
||||
{
|
||||
int i, j;
|
||||
int xs = 3 * r;
|
||||
float c = 0.5f;
|
||||
float scale = s / 100.0f;
|
||||
float h = imgmap->get_height_full(v) + 2.0f;
|
||||
h = CLAMP(h, -100.0, 100.0f);
|
||||
for (i = -8; i < 8 + 1; i++)
|
||||
for (j = -8; j < 8 + 1; j++)
|
||||
{
|
||||
Vector3 pos(v.x + i, v.y, v.z + j);
|
||||
h = MAX(h, imgmap->get_height_full(pos) + 2.0f);
|
||||
}
|
||||
c = (h + 100.0f) / 200.0;
|
||||
for (i = -xs; i < xs + 1; i++)
|
||||
for (j = -xs; j < xs + 1; j++)
|
||||
{
|
||||
float xr = Vector2(i, j).length();
|
||||
if (xr < r)
|
||||
{
|
||||
Vector3 pos(v.x + i, v.y, v.z + j);
|
||||
Vector2 pt = Vector2(pos.x * 0.1f + draw_image->get_width() / 2,
|
||||
pos.z * 0.1f + draw_image->get_height() / 2);
|
||||
pt.x = CLAMP(pt.x, 1, draw_image->get_width() - 1);
|
||||
pt.y = CLAMP(pt.y, 1, draw_image->get_height() - 1);
|
||||
draw_image->fill_rect(Rect2(pt - Vector2(1, 1), Vector2(2, 2)), Color(c, 0, 0, 1));
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
void VoxelGeneratorImgMapper::draw_brush(const Vector3 &v, float r, float s, int id)
|
||||
{
|
||||
ERR_FAIL_COND(!_image_draw.is_valid());
|
||||
ERR_FAIL_COND(!curve1.is_valid());
|
||||
ERR_FAIL_COND(!curve2.is_valid());
|
||||
static struct Brush0 b0(_image_draw);
|
||||
static struct Brush1 b1(_image_draw);
|
||||
static struct Brush2 b2(_image_draw, curve1);
|
||||
static struct Brush3 b3(_image_draw, curve1, this);
|
||||
static struct Brush4 b4(_image_draw, curve2, this);
|
||||
static struct Brush5 b5(_image_draw, this);
|
||||
|
||||
int i, j;
|
||||
if (r < 1.0f)
|
||||
r = 1.0f;
|
||||
@@ -448,7 +456,7 @@ void VoxelGeneratorImgMapper::draw_brush(const Vector3 &v, float r, float s, int
|
||||
int xs = 3 * r;
|
||||
float base_h = get_height_full(v);
|
||||
float scale = s / 100.0f;
|
||||
EditBrush::draw_brush(v, r, s, id);
|
||||
EditBrushList::draw_brush(v, r, s, id);
|
||||
#if 0
|
||||
switch (id)
|
||||
{
|
||||
@@ -747,6 +755,11 @@ int VoxelGeneratorImgMapper::get_world_size() const
|
||||
return world_size;
|
||||
}
|
||||
|
||||
std::map<int, String> VoxelGeneratorImgMapper::get_brush_names() const
|
||||
{
|
||||
return EditBrushList::get_brush_names();
|
||||
}
|
||||
|
||||
void VoxelGeneratorImgMapper::_bind_methods()
|
||||
{
|
||||
ClassDB::bind_method(D_METHOD("set_image_bg", "image"), &VoxelGeneratorImgMapper::set_image_bg);
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#ifndef HEADER_VOXEL_GENERATOR_IMGMAPPER
|
||||
#define HEADER_VOXEL_GENERATOR_IMGMAPPER
|
||||
#undef NDEBUG
|
||||
#include <cassert>
|
||||
#include <map>
|
||||
#include <modules/voxel/generators/simple/voxel_generator_heightmap.h>
|
||||
#include <core/image.h>
|
||||
@@ -7,23 +9,42 @@
|
||||
|
||||
struct EditBrush
|
||||
{
|
||||
static std::map<int, struct EditBrush *> brushes;
|
||||
int id;
|
||||
String name;
|
||||
Ref<Image> &draw_image;
|
||||
virtual void draw(const Vector3 &v, float r, float s) = 0;
|
||||
EditBrush(int id, Ref<Image> &im) : id(id), draw_image(im)
|
||||
EditBrush(int id, Ref<Image> &im, const String &name) : id(id), name(name), draw_image(im)
|
||||
{
|
||||
brushes[id] = this;
|
||||
}
|
||||
virtual ~EditBrush()
|
||||
{
|
||||
brushes.erase(id);
|
||||
}
|
||||
};
|
||||
|
||||
struct EditBrushList
|
||||
{
|
||||
static std::map<int, struct EditBrush *> brushes;
|
||||
static std::map<int, String> brush_names;
|
||||
|
||||
public:
|
||||
template <typename T>
|
||||
static void register_brush(T *brush)
|
||||
{
|
||||
int id = brush->id;
|
||||
brushes[id] = brush;
|
||||
brush_names[id] = brush->name;
|
||||
}
|
||||
static void draw_brush(const Vector3 &v, float r, float s, int id)
|
||||
{
|
||||
if (brushes.find(id) != brushes.end())
|
||||
brushes.at(id)->draw(v, r, s);
|
||||
}
|
||||
static const std::map<int, String> &get_brush_names()
|
||||
{
|
||||
assert(brushes.size() > 0);
|
||||
assert(brush_names.size() > 0);
|
||||
return brush_names;
|
||||
}
|
||||
};
|
||||
|
||||
// Provides infinite tiling heightmap based on an image
|
||||
@@ -75,6 +96,7 @@ public:
|
||||
|
||||
void set_world_size(int value);
|
||||
int get_world_size() const;
|
||||
std::map<int, String> get_brush_names() const;
|
||||
|
||||
private:
|
||||
static void _bind_methods();
|
||||
|
||||
@@ -385,6 +385,11 @@ void StreamWorld::_notification(int which)
|
||||
ERR_FAIL_COND_MSG(!current_scene, "No current scene");
|
||||
RoadProcessing::road_setup(this, 0);
|
||||
set_process(true);
|
||||
if (Engine::get_singleton()->is_editor_hint())
|
||||
break;
|
||||
update_view();
|
||||
assert(terrain);
|
||||
assert(viewer);
|
||||
}
|
||||
break;
|
||||
case NOTIFICATION_EXIT_TREE:
|
||||
|
||||
@@ -60,6 +60,21 @@ void TerrainEditor::activate()
|
||||
EditorEvent::get_singleton()->event.add_listener(
|
||||
this, &TerrainEditor::event_handler);
|
||||
|
||||
assert(editor->is_inside_tree());
|
||||
imgmapper = editor->get_heightmap();
|
||||
assert(imgmapper.is_valid());
|
||||
const std::map<int, String> &brush_names = imgmapper->get_brush_names();
|
||||
assert(brush_names.size() > 0);
|
||||
Dictionary brushes;
|
||||
std::map<int, String>::const_iterator ib = brush_names.begin();
|
||||
while (ib != brush_names.end()) {
|
||||
std::pair<int, String> ibp = *ib;
|
||||
brushes[ibp.first] = ibp.second;
|
||||
ib++;
|
||||
}
|
||||
assert(brushes.size() > 0);
|
||||
EditorEvent::get_singleton()->event.emit("terrain_update_brushes",
|
||||
varray(brushes));
|
||||
active = true;
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#ifndef TERRAIN_EDITOR_H_
|
||||
#define TERRAIN_EDITOR_H_
|
||||
class WorldEditor;
|
||||
class VoxelGeneratorImgMapper;
|
||||
class TerrainEditor {
|
||||
WorldEditor *editor;
|
||||
bool active;
|
||||
@@ -9,6 +10,7 @@ class TerrainEditor {
|
||||
String cursor_name;
|
||||
bool camera_moved;
|
||||
Vector3 camera_motion;
|
||||
Ref<VoxelGeneratorImgMapper> imgmapper;
|
||||
|
||||
public:
|
||||
void exit();
|
||||
|
||||
@@ -71,6 +71,22 @@ void MainTabs::handle_event(const String &event, const Vector<Variant> &args)
|
||||
if (ok)
|
||||
EditorEvent::get_singleton()->event.emit(
|
||||
"buildings_building_selected", varray());
|
||||
} else if (event == "terrain_update_brushes") {
|
||||
OptionButton *brushes = Object::cast_to<OptionButton>(
|
||||
get_node(NodePath("%terrain_select_brush")));
|
||||
assert(brushes);
|
||||
assert(args.size() == 1);
|
||||
const Dictionary &brush_data = args[0];
|
||||
assert(brush_data.size() > 0);
|
||||
List<Variant> brush_keys;
|
||||
List<Variant>::Element *be;
|
||||
brush_data.get_key_list(&brush_keys);
|
||||
be = brush_keys.front();
|
||||
while (be) {
|
||||
int id = be->get();
|
||||
brushes->add_item(brush_data[id], id);
|
||||
be = be->next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,13 +193,22 @@ void MainTabs::_notification(int which)
|
||||
add_child(tab);
|
||||
switch (i) {
|
||||
case 0: {
|
||||
/* clang-format off */
|
||||
std::vector<Variant> args_data = {
|
||||
items[i].header
|
||||
items[i].header,
|
||||
/* 0 */
|
||||
"Brush",
|
||||
/* 1 */
|
||||
"Brush", 0, "terrain_select_brush",
|
||||
};
|
||||
HashMap<String, Object *> save_data;
|
||||
/* clang-format on */
|
||||
ui_field::ui_field_builder(this, tab,
|
||||
"l_p{v{}}",
|
||||
"l_p{v{lo#!$}}",
|
||||
args_data.data(),
|
||||
args_data.size());
|
||||
args_data.size(),
|
||||
&save_data);
|
||||
assert(save_data.has("terrain_select_brush"));
|
||||
} break;
|
||||
case 1: {
|
||||
// VBoxContainer *v = memnew(VBoxContainer);
|
||||
|
||||
@@ -420,6 +420,7 @@ void WorldEditor::event_signal_handler(const String &event,
|
||||
Ref<VoxelGeneratorImgMapper> WorldEditor::get_heightmap()
|
||||
{
|
||||
StreamWorld *world = get_stream_world();
|
||||
assert(world);
|
||||
VoxelLodTerrain *terrain = world->get_terrain();
|
||||
assert(terrain);
|
||||
return terrain->get_generator();
|
||||
|
||||
Reference in New Issue
Block a user