Merge branch 'master' into smooth_texturing

This commit is contained in:
Marc Gilleron 2021-05-07 21:48:11 +01:00
commit d5bd6c794b
6 changed files with 49 additions and 17 deletions

View File

@ -94,7 +94,6 @@ void VoxelToolTerrain::copy(Vector3i pos, Ref<VoxelBuffer> dst, uint8_t channels
void VoxelToolTerrain::paste(Vector3i pos, Ref<VoxelBuffer> p_voxels, uint8_t channels_mask, uint64_t mask_value) {
ERR_FAIL_COND(_terrain == nullptr);
ERR_FAIL_COND(p_voxels.is_null());
ERR_PRINT("Not implemented");
if (channels_mask == 0) {
channels_mask = (1 << _channel);
}

View File

@ -852,12 +852,11 @@ static void copy_block_and_neighbors(ArraySlice<Ref<VoxelBuffer> > blocks, Voxel
const Vector3i src_min = min_pos - offset;
const Vector3i src_max = max_pos - offset;
const Vector3i dst_min = offset - min_pos;
{
RWLockRead read(src->get_lock());
for (unsigned int ci = 0; ci < channels_count; ++ci) {
dst.copy_from(**src, src_min, src_max, dst_min, channels[ci]);
dst.copy_from(**src, src_min, src_max, Vector3(), channels[ci]);
}
}
}

View File

@ -512,6 +512,36 @@ void VoxelBuffer::copy_from(const VoxelBuffer &other, unsigned int channel_index
channel.depth = other_channel.depth;
}
inline void clip_copy_region_coord(int &src_min, int &src_max, const int src_size, int &dst_min, const int dst_size) {
// Clamp source and shrink destination for moved borders
if (src_min < 0) {
dst_min += -src_min;
src_min = 0;
}
if (src_max > src_size) {
src_max = src_size;
}
// Clamp destination and shrink source for moved borders
if (dst_min < 0) {
src_min += -dst_min;
dst_min = 0;
}
const int dst_w = src_max - src_min;
const int dst_max = dst_min + dst_w;
if (dst_max > dst_size) {
src_max -= dst_max - dst_size;
}
// It is possible the source has negative size at this point, which means there is nothing to copy.
// This must be checked by the caller.
}
inline void clip_copy_region(
Vector3i &src_min, Vector3i &src_max, const Vector3i &src_size, Vector3i &dst_min, const Vector3i &dst_size) {
clip_copy_region_coord(src_min.x, src_max.x, src_size.x, dst_min.x, dst_size.x);
clip_copy_region_coord(src_min.y, src_max.y, src_size.y, dst_min.y, dst_size.y);
clip_copy_region_coord(src_min.z, src_max.z, src_size.z, dst_min.z, dst_size.z);
}
void VoxelBuffer::copy_from(const VoxelBuffer &other, Vector3i src_min, Vector3i src_max, Vector3i dst_min,
unsigned int channel_index) {
@ -529,19 +559,21 @@ void VoxelBuffer::copy_from(const VoxelBuffer &other, Vector3i src_min, Vector3i
Vector3i::sort_min_max(src_min, src_max);
src_min.clamp_to(Vector3i(0, 0, 0), other._size);
src_max.clamp_to(Vector3i(0, 0, 0), other._size + Vector3i(1, 1, 1));
clip_copy_region(src_min, src_max, other._size, dst_min, _size);
dst_min.clamp_to(Vector3i(0, 0, 0), _size);
const Vector3i area_size = src_max - src_min;
//Vector3i dst_max = dst_min + area_size;
if (area_size.x <= 0 || area_size.y <= 0 || area_size.z <= 0) {
// Degenerate area, we'll not copy anything.
return;
}
if (area_size == _size && area_size == other._size) {
// Equivalent of full copy between two blocks of same size
copy_from(other, channel_index);
} else {
if (other_channel.data) {
if (other_channel.data != nullptr) {
if (channel.data == nullptr) {
create_channel(channel_index, _size, channel.defval);
@ -656,6 +688,7 @@ void VoxelBuffer::downscale_to(VoxelBuffer &dst, Vector3i src_min, Vector3i src_
Vector3i dst_max = dst_min + ((src_max - src_min) >> 1);
// TODO This will be wrong if it overlaps the border?
dst_min.clamp_to(Vector3i(), dst._size);
dst_max.clamp_to(Vector3i(), dst._size + Vector3i(1));

View File

@ -278,15 +278,16 @@ void VoxelDataMap::paste(Vector3i min_pos, VoxelBuffer &src_buffer, unsigned int
}
}
const Vector3i offset = block_to_voxel(bpos);
const Vector3i dst_block_origin = block_to_voxel(bpos);
VoxelBuffer &dst_buffer = **block->voxels;
RWLockWrite lock(dst_buffer.get_lock());
if (mask_value != std::numeric_limits<uint64_t>::max()) {
dst_buffer.read_write_action(Rect3i(offset - min_pos, src_buffer.get_size()), channel,
[&src_buffer, mask_value, offset, channel](const Vector3i pos, uint64_t dst_v) {
const uint64_t src_v = src_buffer.get_voxel(pos + offset, channel);
const Vector3i src_offset = min_pos - dst_block_origin;
dst_buffer.read_write_action(Rect3i(min_pos - dst_block_origin, src_buffer.get_size()), channel,
[&src_buffer, mask_value, src_offset, channel](const Vector3i pos, uint64_t dst_v) {
const uint64_t src_v = src_buffer.get_voxel(pos + src_offset, channel);
if (src_v == mask_value) {
return dst_v;
}
@ -294,9 +295,9 @@ void VoxelDataMap::paste(Vector3i min_pos, VoxelBuffer &src_buffer, unsigned int
});
} else {
dst_buffer.copy_from(src_buffer,
offset - min_pos,
offset - max_pos,
min_pos - offset,
Vector3i(),
src_buffer.get_size(),
min_pos - dst_block_origin,
channel);
}
}

View File

@ -19,7 +19,7 @@ public:
Rect3i(int ox, int oy, int oz, int sx, int sy, int sz) :
pos(ox, oy, oz),
size(sz, sy, sz) {}
size(sx, sy, sz) {}
Rect3i(const Rect3i &other) :
pos(other.pos),

View File

@ -186,7 +186,7 @@ struct Vector3i {
}
};
_FORCE_INLINE_ Vector3i operator+(const Vector3i a, const Vector3i &b) {
_FORCE_INLINE_ Vector3i operator+(const Vector3i &a, const Vector3i &b) {
return Vector3i(a.x + b.x, a.y + b.y, a.z + b.z);
}