Smooth VoxelProviderImage a little in isolevel mode, also properly repeat the heightmap if it's not power of two

This commit is contained in:
Marc Gilleron 2019-04-27 02:08:12 +01:00
parent 6d872160ab
commit a67ea390d5

View File

@ -20,6 +20,27 @@ int VoxelProviderImage::get_channel() const {
return _channel; return _channel;
} }
namespace {
inline int umod(int a, int b) {
return ((unsigned int)a - (a < 0)) % (unsigned int)b;
}
inline float get_height_repeat(Image &im, int x, int y) {
return im.get_pixel(umod(x, im.get_width()), umod(y, im.get_height())).r;
}
inline float get_height_blurred(Image &im, int x, int y) {
float h = get_height_repeat(im, x, y);
h += get_height_repeat(im, x + 1, y);
h += get_height_repeat(im, x - 1, y);
h += get_height_repeat(im, x, y + 1);
h += get_height_repeat(im, x, y - 1);
return h * 0.2f;
}
} // namespace
void VoxelProviderImage::emerge_block(Ref<VoxelBuffer> p_out_buffer, Vector3i origin_in_voxels) { void VoxelProviderImage::emerge_block(Ref<VoxelBuffer> p_out_buffer, Vector3i origin_in_voxels) {
int ox = origin_in_voxels.x; int ox = origin_in_voxels.x;
@ -31,11 +52,6 @@ void VoxelProviderImage::emerge_block(Ref<VoxelBuffer> p_out_buffer, Vector3i or
image.lock(); image.lock();
int im_w = image.get_width();
int im_h = image.get_height();
int im_wm = im_w - 1;
int im_hm = im_h - 1;
int x = 0; int x = 0;
int z = 0; int z = 0;
@ -46,16 +62,16 @@ void VoxelProviderImage::emerge_block(Ref<VoxelBuffer> p_out_buffer, Vector3i or
while (z < bs) { while (z < bs) {
while (x < bs) { while (x < bs) {
Color c = image.get_pixel((ox + x) & im_wm, (oz + z) & im_hm);
float h = c.r * 200.0 - 50;
if (_channel == VoxelBuffer::CHANNEL_ISOLEVEL) { if (_channel == VoxelBuffer::CHANNEL_ISOLEVEL) {
float h = get_height_blurred(image, ox + x, oz + z) * 200.0 - 50;
for (int y = 0; y < bs; ++y) { for (int y = 0; y < bs; ++y) {
out_buffer.set_voxel_iso((oy + y) - h, x, y, z, _channel); out_buffer.set_voxel_iso((oy + y) - h, x, y, z, _channel);
} }
} else { } else {
float h = get_height_repeat(image, ox + x, oz + z) * 200.0 - 50;
h -= oy; h -= oy;
int ih = int(h); int ih = int(h);
if (ih > 0) { if (ih > 0) {