Proper brush configuration
This commit is contained in:
@@ -45,11 +45,240 @@ namespace
|
|||||||
|
|
||||||
} // 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()
|
VoxelGeneratorImgMapper::VoxelGeneratorImgMapper()
|
||||||
: VoxelGeneratorHeightmap(),
|
: VoxelGeneratorHeightmap(),
|
||||||
world_size(10240),
|
world_size(10240),
|
||||||
grid_size(0)
|
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()
|
VoxelGeneratorImgMapper::~VoxelGeneratorImgMapper()
|
||||||
@@ -215,232 +444,11 @@ float VoxelGeneratorImgMapper::get_height_full(const Vector3 &v)
|
|||||||
return get_height(v) * 200.0f - 100.0f;
|
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)
|
void VoxelGeneratorImgMapper::draw_brush(const Vector3 &v, float r, float s, int id)
|
||||||
{
|
{
|
||||||
ERR_FAIL_COND(!_image_draw.is_valid());
|
ERR_FAIL_COND(!_image_draw.is_valid());
|
||||||
ERR_FAIL_COND(!curve1.is_valid());
|
ERR_FAIL_COND(!curve1.is_valid());
|
||||||
ERR_FAIL_COND(!curve2.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;
|
int i, j;
|
||||||
if (r < 1.0f)
|
if (r < 1.0f)
|
||||||
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;
|
int xs = 3 * r;
|
||||||
float base_h = get_height_full(v);
|
float base_h = get_height_full(v);
|
||||||
float scale = s / 100.0f;
|
float scale = s / 100.0f;
|
||||||
EditBrush::draw_brush(v, r, s, id);
|
EditBrushList::draw_brush(v, r, s, id);
|
||||||
#if 0
|
#if 0
|
||||||
switch (id)
|
switch (id)
|
||||||
{
|
{
|
||||||
@@ -747,6 +755,11 @@ int VoxelGeneratorImgMapper::get_world_size() const
|
|||||||
return world_size;
|
return world_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::map<int, String> VoxelGeneratorImgMapper::get_brush_names() const
|
||||||
|
{
|
||||||
|
return EditBrushList::get_brush_names();
|
||||||
|
}
|
||||||
|
|
||||||
void VoxelGeneratorImgMapper::_bind_methods()
|
void VoxelGeneratorImgMapper::_bind_methods()
|
||||||
{
|
{
|
||||||
ClassDB::bind_method(D_METHOD("set_image_bg", "image"), &VoxelGeneratorImgMapper::set_image_bg);
|
ClassDB::bind_method(D_METHOD("set_image_bg", "image"), &VoxelGeneratorImgMapper::set_image_bg);
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
#ifndef HEADER_VOXEL_GENERATOR_IMGMAPPER
|
#ifndef HEADER_VOXEL_GENERATOR_IMGMAPPER
|
||||||
#define HEADER_VOXEL_GENERATOR_IMGMAPPER
|
#define HEADER_VOXEL_GENERATOR_IMGMAPPER
|
||||||
|
#undef NDEBUG
|
||||||
|
#include <cassert>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <modules/voxel/generators/simple/voxel_generator_heightmap.h>
|
#include <modules/voxel/generators/simple/voxel_generator_heightmap.h>
|
||||||
#include <core/image.h>
|
#include <core/image.h>
|
||||||
@@ -7,23 +9,42 @@
|
|||||||
|
|
||||||
struct EditBrush
|
struct EditBrush
|
||||||
{
|
{
|
||||||
static std::map<int, struct EditBrush *> brushes;
|
|
||||||
int id;
|
int id;
|
||||||
|
String name;
|
||||||
Ref<Image> &draw_image;
|
Ref<Image> &draw_image;
|
||||||
virtual void draw(const Vector3 &v, float r, float s) = 0;
|
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()
|
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)
|
static void draw_brush(const Vector3 &v, float r, float s, int id)
|
||||||
{
|
{
|
||||||
if (brushes.find(id) != brushes.end())
|
if (brushes.find(id) != brushes.end())
|
||||||
brushes.at(id)->draw(v, r, s);
|
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
|
// Provides infinite tiling heightmap based on an image
|
||||||
@@ -75,6 +96,7 @@ public:
|
|||||||
|
|
||||||
void set_world_size(int value);
|
void set_world_size(int value);
|
||||||
int get_world_size() const;
|
int get_world_size() const;
|
||||||
|
std::map<int, String> get_brush_names() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
|||||||
@@ -385,6 +385,11 @@ void StreamWorld::_notification(int which)
|
|||||||
ERR_FAIL_COND_MSG(!current_scene, "No current scene");
|
ERR_FAIL_COND_MSG(!current_scene, "No current scene");
|
||||||
RoadProcessing::road_setup(this, 0);
|
RoadProcessing::road_setup(this, 0);
|
||||||
set_process(true);
|
set_process(true);
|
||||||
|
if (Engine::get_singleton()->is_editor_hint())
|
||||||
|
break;
|
||||||
|
update_view();
|
||||||
|
assert(terrain);
|
||||||
|
assert(viewer);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case NOTIFICATION_EXIT_TREE:
|
case NOTIFICATION_EXIT_TREE:
|
||||||
|
|||||||
@@ -60,6 +60,21 @@ void TerrainEditor::activate()
|
|||||||
EditorEvent::get_singleton()->event.add_listener(
|
EditorEvent::get_singleton()->event.add_listener(
|
||||||
this, &TerrainEditor::event_handler);
|
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;
|
active = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#ifndef TERRAIN_EDITOR_H_
|
#ifndef TERRAIN_EDITOR_H_
|
||||||
#define TERRAIN_EDITOR_H_
|
#define TERRAIN_EDITOR_H_
|
||||||
class WorldEditor;
|
class WorldEditor;
|
||||||
|
class VoxelGeneratorImgMapper;
|
||||||
class TerrainEditor {
|
class TerrainEditor {
|
||||||
WorldEditor *editor;
|
WorldEditor *editor;
|
||||||
bool active;
|
bool active;
|
||||||
@@ -9,6 +10,7 @@ class TerrainEditor {
|
|||||||
String cursor_name;
|
String cursor_name;
|
||||||
bool camera_moved;
|
bool camera_moved;
|
||||||
Vector3 camera_motion;
|
Vector3 camera_motion;
|
||||||
|
Ref<VoxelGeneratorImgMapper> imgmapper;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void exit();
|
void exit();
|
||||||
|
|||||||
@@ -71,6 +71,22 @@ void MainTabs::handle_event(const String &event, const Vector<Variant> &args)
|
|||||||
if (ok)
|
if (ok)
|
||||||
EditorEvent::get_singleton()->event.emit(
|
EditorEvent::get_singleton()->event.emit(
|
||||||
"buildings_building_selected", varray());
|
"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);
|
add_child(tab);
|
||||||
switch (i) {
|
switch (i) {
|
||||||
case 0: {
|
case 0: {
|
||||||
|
/* clang-format off */
|
||||||
std::vector<Variant> args_data = {
|
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,
|
ui_field::ui_field_builder(this, tab,
|
||||||
"l_p{v{}}",
|
"l_p{v{lo#!$}}",
|
||||||
args_data.data(),
|
args_data.data(),
|
||||||
args_data.size());
|
args_data.size(),
|
||||||
|
&save_data);
|
||||||
|
assert(save_data.has("terrain_select_brush"));
|
||||||
} break;
|
} break;
|
||||||
case 1: {
|
case 1: {
|
||||||
// VBoxContainer *v = memnew(VBoxContainer);
|
// VBoxContainer *v = memnew(VBoxContainer);
|
||||||
|
|||||||
@@ -420,6 +420,7 @@ void WorldEditor::event_signal_handler(const String &event,
|
|||||||
Ref<VoxelGeneratorImgMapper> WorldEditor::get_heightmap()
|
Ref<VoxelGeneratorImgMapper> WorldEditor::get_heightmap()
|
||||||
{
|
{
|
||||||
StreamWorld *world = get_stream_world();
|
StreamWorld *world = get_stream_world();
|
||||||
|
assert(world);
|
||||||
VoxelLodTerrain *terrain = world->get_terrain();
|
VoxelLodTerrain *terrain = world->get_terrain();
|
||||||
assert(terrain);
|
assert(terrain);
|
||||||
return terrain->get_generator();
|
return terrain->get_generator();
|
||||||
|
|||||||
Reference in New Issue
Block a user