Removed default values from VoxelDataMap
parent
b0e71e58ab
commit
d2b20f676e
|
@ -106,6 +106,21 @@ inline real_t raw_voxel_to_real(uint64_t value, VoxelBufferInternal::Depth depth
|
|||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
uint64_t g_default_values[VoxelBufferInternal::MAX_CHANNELS] = {
|
||||
0, // TYPE
|
||||
snorm_to_s16(1.f), // SDF
|
||||
encode_indices_to_packed_u16(0, 1, 2, 3), // INDICES
|
||||
encode_weights_to_packed_u16(15, 0, 0, 0), // WEIGHTS
|
||||
0, 0, 0, 0 //
|
||||
};
|
||||
}
|
||||
|
||||
uint64_t VoxelBufferInternal::get_default_value_static(unsigned int channel_index) {
|
||||
ZN_ASSERT(channel_index < MAX_CHANNELS);
|
||||
return g_default_values[channel_index];
|
||||
}
|
||||
|
||||
VoxelBufferInternal::VoxelBufferInternal() {
|
||||
// Minecraft uses way more than 255 block types and there is room for eventual metadata such as rotation
|
||||
_channels[CHANNEL_TYPE].depth = DEFAULT_TYPE_CHANNEL_DEPTH;
|
||||
|
|
|
@ -125,6 +125,8 @@ public:
|
|||
|
||||
void set_default_values(FixedArray<uint64_t, VoxelBufferInternal::MAX_CHANNELS> values);
|
||||
|
||||
static uint64_t get_default_value_static(unsigned int channel_index);
|
||||
|
||||
uint64_t get_voxel(int x, int y, int z, unsigned int channel_index) const;
|
||||
void set_voxel(uint64_t value, int x, int y, int z, unsigned int channel_index);
|
||||
|
||||
|
@ -505,6 +507,7 @@ private:
|
|||
// TODO It may be preferable to actually move away from storing an RWLock in every buffer in the future.
|
||||
// We should be able to find a solution because very few of these locks are actually used at a given time.
|
||||
// It worked so far on PC but other platforms like the PS5 might have a pretty low limit (8K?)
|
||||
// Also it's a heavy data structure, on Windows sizeof(RWLock) is 244.
|
||||
RWLock _rw_lock;
|
||||
};
|
||||
|
||||
|
|
|
@ -10,15 +10,8 @@
|
|||
namespace zylann::voxel {
|
||||
|
||||
VoxelDataMap::VoxelDataMap() {
|
||||
// TODO Make it configurable in editor (with all necessary notifications and updatings!)
|
||||
// This is not planned to change at runtime at the moment.
|
||||
set_block_size_pow2(constants::DEFAULT_BLOCK_SIZE_PO2);
|
||||
|
||||
// Pick same defaults as VoxelBuffer
|
||||
VoxelBufferInternal b;
|
||||
b.create(1, 1, 1);
|
||||
for (unsigned int channel_index = 0; channel_index < VoxelBufferInternal::MAX_CHANNELS; ++channel_index) {
|
||||
_default_voxel[channel_index] = b.get_voxel(0, 0, 0, channel_index);
|
||||
}
|
||||
}
|
||||
|
||||
VoxelDataMap::~VoxelDataMap() {
|
||||
|
@ -55,7 +48,7 @@ int VoxelDataMap::get_voxel(Vector3i pos, unsigned int c) const {
|
|||
Vector3i bpos = voxel_to_block(pos);
|
||||
const VoxelDataBlock *block = get_block(bpos);
|
||||
if (block == nullptr || !block->has_voxels()) {
|
||||
return _default_voxel[c];
|
||||
return VoxelBufferInternal::get_default_value_static(c);
|
||||
}
|
||||
RWLockRead lock(block->get_voxels_const().get_lock());
|
||||
return block->get_voxels_const().get_voxel(to_local(pos), c);
|
||||
|
@ -64,7 +57,7 @@ int VoxelDataMap::get_voxel(Vector3i pos, unsigned int c) const {
|
|||
VoxelDataBlock *VoxelDataMap::create_default_block(Vector3i bpos) {
|
||||
std::shared_ptr<VoxelBufferInternal> buffer = make_shared_instance<VoxelBufferInternal>();
|
||||
buffer->create(_block_size, _block_size, _block_size);
|
||||
buffer->set_default_values(_default_voxel);
|
||||
//buffer->set_default_values(_default_voxel);
|
||||
#ifdef DEBUG_ENABLED
|
||||
ZN_ASSERT_RETURN_V(!has_block(bpos), nullptr);
|
||||
#endif
|
||||
|
@ -99,7 +92,7 @@ float VoxelDataMap::get_voxel_f(Vector3i pos, unsigned int c) const {
|
|||
// TODO The generator needs to be invoked if the block has no voxels
|
||||
if (block == nullptr || !block->has_voxels()) {
|
||||
// TODO Not valid for a float return value
|
||||
return _default_voxel[c];
|
||||
return VoxelBufferInternal::get_default_value_static(c);
|
||||
}
|
||||
Vector3i lpos = to_local(pos);
|
||||
RWLockRead lock(block->get_voxels_const().get_lock());
|
||||
|
@ -116,16 +109,6 @@ void VoxelDataMap::set_voxel_f(real_t value, Vector3i pos, unsigned int c) {
|
|||
voxels.set_voxel_f(value, lpos.x, lpos.y, lpos.z, c);
|
||||
}
|
||||
|
||||
void VoxelDataMap::set_default_voxel(int value, unsigned int channel) {
|
||||
ZN_ASSERT_RETURN(channel >= 0 && channel < VoxelBufferInternal::MAX_CHANNELS);
|
||||
_default_voxel[channel] = value;
|
||||
}
|
||||
|
||||
int VoxelDataMap::get_default_voxel(unsigned int channel) {
|
||||
ZN_ASSERT_RETURN_V(channel >= 0 && channel < VoxelBufferInternal::MAX_CHANNELS, 0);
|
||||
return _default_voxel[channel];
|
||||
}
|
||||
|
||||
VoxelDataBlock *VoxelDataMap::get_block(Vector3i bpos) {
|
||||
auto it = _blocks_map.find(bpos);
|
||||
if (it != _blocks_map.end()) {
|
||||
|
@ -251,8 +234,8 @@ void VoxelDataMap::copy(Vector3i min_pos, VoxelBufferInternal &dst_buffer, unsig
|
|||
const uint8_t channel = channels[ci];
|
||||
// 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.
|
||||
dst_buffer.fill_area(_default_voxel[channel], src_block_origin - min_pos,
|
||||
src_block_origin - min_pos + block_size_v, channel);
|
||||
dst_buffer.fill_area(VoxelBufferInternal::get_default_value_static(channel),
|
||||
src_block_origin - min_pos, src_block_origin - min_pos + block_size_v, channel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,9 +68,6 @@ public:
|
|||
float get_voxel_f(Vector3i pos, unsigned int c = VoxelBufferInternal::CHANNEL_SDF) const;
|
||||
void set_voxel_f(real_t value, Vector3i pos, unsigned int c = VoxelBufferInternal::CHANNEL_SDF);
|
||||
|
||||
void set_default_voxel(int value, unsigned int channel = 0);
|
||||
int get_default_voxel(unsigned int channel = 0);
|
||||
|
||||
inline void copy(Vector3i min_pos, VoxelBufferInternal &dst_buffer, unsigned int channels_mask) const {
|
||||
copy(min_pos, dst_buffer, channels_mask, nullptr, nullptr);
|
||||
}
|
||||
|
@ -186,9 +183,6 @@ private:
|
|||
void set_block_size_pow2(unsigned int p);
|
||||
|
||||
private:
|
||||
// Voxel values that will be returned if access is out of map bounds
|
||||
FixedArray<uint64_t, VoxelBufferInternal::MAX_CHANNELS> _default_voxel;
|
||||
|
||||
// Blocks stored with a spatial hash in all 3D directions.
|
||||
// This is dual storage: map and vector, for fast lookup and also fast iteration.
|
||||
// Before I used Godot's HashMap with RELATIONSHIP = 2 because that delivers better performance compared to
|
||||
|
|
Loading…
Reference in New Issue