Fix copy
This commit is contained in:
parent
dd82fc91c8
commit
9b3263d68b
@ -88,7 +88,7 @@ void VoxelToolTerrain::copy(Vector3i pos, Ref<VoxelBuffer> dst, uint8_t channels
|
|||||||
if (channels_mask == 0) {
|
if (channels_mask == 0) {
|
||||||
channels_mask = (1 << _channel);
|
channels_mask = (1 << _channel);
|
||||||
}
|
}
|
||||||
_terrain->get_storage().get_buffer_copy(pos, **dst, channels_mask);
|
_terrain->get_storage().copy(pos, **dst, channels_mask);
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelToolTerrain::paste(Vector3i pos, Ref<VoxelBuffer> p_voxels, uint8_t channels_mask, uint64_t mask_value) {
|
void VoxelToolTerrain::paste(Vector3i pos, Ref<VoxelBuffer> p_voxels, uint8_t channels_mask, uint64_t mask_value) {
|
||||||
|
@ -726,16 +726,14 @@ Ref<VoxelTool> VoxelBuffer::get_voxel_tool() {
|
|||||||
return Ref<VoxelTool>(memnew(VoxelToolBuffer(vb)));
|
return Ref<VoxelTool>(memnew(VoxelToolBuffer(vb)));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VoxelBuffer::equals(const VoxelBuffer *p_other) const {
|
bool VoxelBuffer::equals(const VoxelBuffer &p_other) const {
|
||||||
CRASH_COND(p_other == nullptr);
|
if (p_other._size != _size) {
|
||||||
|
|
||||||
if (p_other->_size != _size) {
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int channel_index = 0; channel_index < MAX_CHANNELS; ++channel_index) {
|
for (int channel_index = 0; channel_index < MAX_CHANNELS; ++channel_index) {
|
||||||
const Channel &channel = _channels[channel_index];
|
const Channel &channel = _channels[channel_index];
|
||||||
const Channel &other_channel = p_other->_channels[channel_index];
|
const Channel &other_channel = p_other._channels[channel_index];
|
||||||
|
|
||||||
if ((channel.data == nullptr) != (other_channel.data == nullptr)) {
|
if ((channel.data == nullptr) != (other_channel.data == nullptr)) {
|
||||||
// Note: they could still logically be equal if one channel contains uniform voxel memory
|
// Note: they could still logically be equal if one channel contains uniform voxel memory
|
||||||
@ -752,7 +750,7 @@ bool VoxelBuffer::equals(const VoxelBuffer *p_other) const {
|
|||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
CRASH_COND(channel.size_in_bytes != other_channel.size_in_bytes);
|
ERR_FAIL_COND_V(channel.size_in_bytes != other_channel.size_in_bytes, false);
|
||||||
for (unsigned int i = 0; i < channel.size_in_bytes; ++i) {
|
for (unsigned int i = 0; i < channel.size_in_bytes; ++i) {
|
||||||
if (channel.data[i] != other_channel.data[i]) {
|
if (channel.data[i] != other_channel.data[i]) {
|
||||||
return false;
|
return false;
|
||||||
|
@ -187,7 +187,7 @@ public:
|
|||||||
void downscale_to(VoxelBuffer &dst, Vector3i src_min, Vector3i src_max, Vector3i dst_min) const;
|
void downscale_to(VoxelBuffer &dst, Vector3i src_min, Vector3i src_max, Vector3i dst_min) const;
|
||||||
Ref<VoxelTool> get_voxel_tool();
|
Ref<VoxelTool> get_voxel_tool();
|
||||||
|
|
||||||
bool equals(const VoxelBuffer *p_other) const;
|
bool equals(const VoxelBuffer &p_other) const;
|
||||||
|
|
||||||
void set_channel_depth(unsigned int channel_index, Depth new_depth);
|
void set_channel_depth(unsigned int channel_index, Depth new_depth);
|
||||||
Depth get_channel_depth(unsigned int channel_index) const;
|
Depth get_channel_depth(unsigned int channel_index) const;
|
||||||
|
@ -202,7 +202,7 @@ bool VoxelDataMap::is_block_surrounded(Vector3i pos) const {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelDataMap::get_buffer_copy(Vector3i min_pos, VoxelBuffer &dst_buffer, unsigned int channels_mask) {
|
void VoxelDataMap::copy(Vector3i min_pos, VoxelBuffer &dst_buffer, unsigned int channels_mask) {
|
||||||
const Vector3i max_pos = min_pos + dst_buffer.get_size();
|
const Vector3i max_pos = min_pos + dst_buffer.get_size();
|
||||||
|
|
||||||
const Vector3i min_block_pos = voxel_to_block(min_pos);
|
const Vector3i min_block_pos = voxel_to_block(min_pos);
|
||||||
@ -219,31 +219,29 @@ void VoxelDataMap::get_buffer_copy(Vector3i min_pos, VoxelBuffer &dst_buffer, un
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const VoxelDataBlock *block = get_block(bpos);
|
const VoxelDataBlock *block = get_block(bpos);
|
||||||
|
const Vector3i src_block_origin = block_to_voxel(bpos);
|
||||||
|
|
||||||
if (block != nullptr) {
|
if (block != nullptr) {
|
||||||
const VoxelBuffer &src_buffer = **block->voxels;
|
const VoxelBuffer &src_buffer = **block->voxels;
|
||||||
|
|
||||||
dst_buffer.set_channel_depth(channel, src_buffer.get_channel_depth(channel));
|
dst_buffer.set_channel_depth(channel, src_buffer.get_channel_depth(channel));
|
||||||
|
|
||||||
const Vector3i offset = block_to_voxel(bpos);
|
|
||||||
|
|
||||||
RWLockRead lock(src_buffer.get_lock());
|
RWLockRead lock(src_buffer.get_lock());
|
||||||
|
|
||||||
// Note: copy_from takes care of clamping the area if it's on an edge
|
// Note: copy_from takes care of clamping the area if it's on an edge
|
||||||
dst_buffer.copy_from(src_buffer,
|
dst_buffer.copy_from(src_buffer,
|
||||||
min_pos - offset,
|
min_pos - src_block_origin,
|
||||||
max_pos - offset,
|
src_buffer.get_size(),
|
||||||
offset - min_pos,
|
Vector3i(),
|
||||||
channel);
|
channel);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
// For now, inexistent blocks default to hardcoded defaults, corresponding to "empty space".
|
// For now, inexistent blocks default to hardcoded defaults, corresponding to "empty space".
|
||||||
// If we want to change this, we may have to add an API for that.
|
// If we want to change this, we may have to add an API for that.
|
||||||
const Vector3i offset = block_to_voxel(bpos);
|
|
||||||
dst_buffer.fill_area(
|
dst_buffer.fill_area(
|
||||||
_default_voxel[channel],
|
_default_voxel[channel],
|
||||||
offset - min_pos,
|
src_block_origin - min_pos,
|
||||||
offset - min_pos + block_size_v,
|
src_block_origin - min_pos + block_size_v,
|
||||||
channel);
|
channel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,7 +56,7 @@ public:
|
|||||||
int get_default_voxel(unsigned int channel = 0);
|
int get_default_voxel(unsigned int channel = 0);
|
||||||
|
|
||||||
// Gets a copy of all voxels in the area starting at min_pos having the same size as dst_buffer.
|
// Gets a copy of all voxels in the area starting at min_pos having the same size as dst_buffer.
|
||||||
void get_buffer_copy(Vector3i min_pos, VoxelBuffer &dst_buffer, unsigned int channels_mask);
|
void copy(Vector3i min_pos, VoxelBuffer &dst_buffer, unsigned int channels_mask);
|
||||||
|
|
||||||
void paste(Vector3i min_pos, VoxelBuffer &src_buffer, unsigned int channels_mask, uint64_t mask_value,
|
void paste(Vector3i min_pos, VoxelBuffer &src_buffer, unsigned int channels_mask, uint64_t mask_value,
|
||||||
bool create_new_blocks);
|
bool create_new_blocks);
|
||||||
|
@ -146,6 +146,55 @@ void test_voxel_data_map_paste_mask() {
|
|||||||
ERR_FAIL_COND(!outside_is_ok);
|
ERR_FAIL_COND(!outside_is_ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_voxel_data_map_copy() {
|
||||||
|
static const int voxel_value = 1;
|
||||||
|
static const int default_value = 0;
|
||||||
|
static const int channel = VoxelBuffer::CHANNEL_TYPE;
|
||||||
|
|
||||||
|
VoxelDataMap map;
|
||||||
|
map.create(4, 0);
|
||||||
|
|
||||||
|
Rect3i box(10, 10, 10, 32, 16, 32);
|
||||||
|
Ref<VoxelBuffer> buffer;
|
||||||
|
buffer.instance();
|
||||||
|
buffer->create(box.size);
|
||||||
|
|
||||||
|
// Fill the inside of the buffer with a value, and leave outline to zero,
|
||||||
|
// so our buffer isn't just uniform
|
||||||
|
for (int z = 1; z < buffer->get_size().z - 1; ++z) {
|
||||||
|
for (int x = 1; x < buffer->get_size().x - 1; ++x) {
|
||||||
|
for (int y = 1; y < buffer->get_size().y - 1; ++y) {
|
||||||
|
buffer->set_voxel(voxel_value, x, y, z, channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
map.paste(box.pos, **buffer, (1 << channel), default_value, true);
|
||||||
|
|
||||||
|
Ref<VoxelBuffer> buffer2;
|
||||||
|
buffer2.instance();
|
||||||
|
buffer2->create(box.size);
|
||||||
|
|
||||||
|
map.copy(box.pos, **buffer2, (1 << channel));
|
||||||
|
|
||||||
|
// for (int y = 0; y < buffer2->get_size().y; ++y) {
|
||||||
|
// String line = String("y={0} | ").format(varray(y));
|
||||||
|
// for (int x = 0; x < buffer2->get_size().x; ++x) {
|
||||||
|
// const int v = buffer2->get_voxel(Vector3i(x, y, 5), channel);
|
||||||
|
// if (v == default_value) {
|
||||||
|
// line += "- ";
|
||||||
|
// } else if (v == voxel_value) {
|
||||||
|
// line += "O ";
|
||||||
|
// } else {
|
||||||
|
// line += "X ";
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// print_line(line);
|
||||||
|
// }
|
||||||
|
|
||||||
|
ERR_FAIL_COND(!buffer->equals(**buffer2));
|
||||||
|
}
|
||||||
|
|
||||||
#define VOXEL_TEST(fname) \
|
#define VOXEL_TEST(fname) \
|
||||||
print_line(String("Running {0}").format(varray(#fname))); \
|
print_line(String("Running {0}").format(varray(#fname))); \
|
||||||
fname()
|
fname()
|
||||||
@ -156,6 +205,7 @@ void run_voxel_tests() {
|
|||||||
VOXEL_TEST(test_rect3i_for_inner_outline);
|
VOXEL_TEST(test_rect3i_for_inner_outline);
|
||||||
VOXEL_TEST(test_voxel_data_map_paste_fill);
|
VOXEL_TEST(test_voxel_data_map_paste_fill);
|
||||||
VOXEL_TEST(test_voxel_data_map_paste_mask);
|
VOXEL_TEST(test_voxel_data_map_paste_mask);
|
||||||
|
VOXEL_TEST(test_voxel_data_map_copy);
|
||||||
|
|
||||||
print_line("------------ Voxel tests end -------------");
|
print_line("------------ Voxel tests end -------------");
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user