Implemented nearest neighbor downscaling (to be tested)

master
Marc Gilleron 2019-09-02 21:14:30 +01:00
parent a24e6d1b5a
commit 2e1467edd7
3 changed files with 51 additions and 1 deletions

View File

@ -90,12 +90,12 @@ struct Vector3i {
return coords[i];
}
// Clamps between min and max, where max is excluded
void clamp_to(const Vector3i min, const Vector3i max) {
if (x < min.x) x = min.x;
if (y < min.y) y = min.y;
if (z < min.z) z = min.z;
// TODO Not sure it should clamp like that...
if (x >= max.x) x = max.x - 1;
if (y >= max.y) y = max.y - 1;
if (z >= max.z) z = max.z - 1;

View File

@ -328,6 +328,54 @@ void VoxelBuffer::delete_channel(int i) {
channel.data = NULL;
}
void VoxelBuffer::downscale_to(VoxelBuffer &dst, Vector3i src_min, Vector3i src_max, Vector3i dst_min) const {
// TODO Align input to multiple of two
src_min.clamp_to(Vector3i(), _size);
src_max.clamp_to(Vector3i(), _size);
Vector3i dst_max = dst_min + (src_max - src_min) >> 2;
dst_min.clamp_to(Vector3i(), dst._size);
dst_max.clamp_to(Vector3i(), dst._size);
for (int channel_index = 0; channel_index < MAX_CHANNELS; ++channel_index) {
const Channel &src_channel = _channels[channel_index];
const Channel &dst_channel = _channels[channel_index];
if (src_channel.data == nullptr && dst_channel.data == nullptr && src_channel.defval == dst_channel.defval) {
// No action needed
continue;
}
// Nearest-neighbor downscaling
Vector3i pos;
for (pos.z = dst_min.z; pos.z < dst_max.z; ++pos.z) {
for (pos.x = dst_min.x; pos.x < dst_max.x; ++pos.x) {
for (pos.y = dst_min.y; pos.y < dst_max.y; ++pos.y) {
Vector3i src_pos = src_min + (pos - dst_min) << 2;
// TODO Remove check once it works
CRASH_COND(!validate_pos(src_pos.x, src_pos.y, src_pos.z));
int v;
if (src_channel.data) {
v = src_channel.data[index(src_pos.x, src_pos.y, src_pos.z)];
} else {
v = src_channel.defval;
}
dst.set_voxel(v, pos, channel_index);
}
}
}
}
}
void VoxelBuffer::_bind_methods() {
ClassDB::bind_method(D_METHOD("create", "sx", "sy", "sz"), &VoxelBuffer::create);

View File

@ -118,6 +118,8 @@ public:
uint8_t *get_channel_raw(unsigned int channel_index) const;
void downscale_to(VoxelBuffer &dst, Vector3i src_min, Vector3i src_max, Vector3i dst_min) const;
private:
void create_channel_noinit(int i, Vector3i size);
void create_channel(int i, Vector3i size, uint8_t defval);