Storing position on VoxelDataBlock isn't necessary

master
Marc Gilleron 2022-06-04 02:44:00 +01:00
parent f34d87d305
commit abdcb4c7d5
10 changed files with 41 additions and 46 deletions

View File

@ -7,7 +7,7 @@ namespace zylann::voxel {
void VoxelDataBlock::set_modified(bool modified) {
#ifdef TOOLS_ENABLED
if (_modified == false && modified) {
ZN_PRINT_VERBOSE(format("Marking block {} as modified", _position));
ZN_PRINT_VERBOSE(format("Marking block {} as modified", size_t(this)));
}
#endif
_modified = modified;

View File

@ -15,12 +15,11 @@ public:
VoxelDataBlock() {}
VoxelDataBlock(Vector3i bpos, std::shared_ptr<VoxelBufferInternal> &buffer, unsigned int p_lod_index) :
_position(bpos), _lod_index(p_lod_index), _voxels(buffer) {}
VoxelDataBlock(std::shared_ptr<VoxelBufferInternal> &buffer, unsigned int p_lod_index) :
_lod_index(p_lod_index), _voxels(buffer) {}
VoxelDataBlock(VoxelDataBlock &&src) :
viewers(src.viewers),
_position(src._position),
_lod_index(src._lod_index),
_voxels(std::move(src._voxels)),
_needs_lodding(src._needs_lodding),
@ -29,7 +28,6 @@ public:
VoxelDataBlock &operator=(VoxelDataBlock &&src) {
viewers = src.viewers;
_position = src._position;
_lod_index = src._lod_index;
_voxels = std::move(src._voxels);
_needs_lodding = src._needs_lodding;
@ -38,10 +36,6 @@ public:
return *this;
}
inline const Vector3i &get_position() const {
return _position;
}
inline unsigned int get_lod_index() const {
return _lod_index;
}
@ -95,8 +89,6 @@ public:
}
private:
Vector3i _position;
std::shared_ptr<VoxelBufferInternal> _voxels;
uint8_t _lod_index = 0;

View File

@ -69,7 +69,7 @@ VoxelDataBlock *VoxelDataMap::create_default_block(Vector3i bpos) {
ZN_ASSERT_RETURN_V(!has_block(bpos), nullptr);
#endif
VoxelDataBlock &map_block = _blocks_map[bpos];
map_block = std::move(VoxelDataBlock(bpos, buffer, _lod_index));
map_block = std::move(VoxelDataBlock(buffer, _lod_index));
return &map_block;
}
@ -144,7 +144,7 @@ VoxelDataBlock *VoxelDataMap::set_block_buffer(
if (block == nullptr) {
VoxelDataBlock &map_block = _blocks_map[bpos];
map_block = std::move(VoxelDataBlock(bpos, buffer, _lod_index));
map_block = std::move(VoxelDataBlock(buffer, _lod_index));
block = &map_block;
} else if (overwrite) {

View File

@ -102,14 +102,14 @@ public:
template <typename Op_T>
inline void for_each_block(Op_T op) {
for (auto it = _blocks_map.begin(); it != _blocks_map.end(); ++it) {
op(it->second);
op(it->first, it->second);
}
}
template <typename Op_T>
inline void for_each_block(Op_T op) const {
for (auto it = _blocks_map.begin(); it != _blocks_map.end(); ++it) {
op(it->second);
op(it->first, it->second);
}
}

View File

@ -459,7 +459,7 @@ void VoxelTerrain::view_data_block(Vector3i bpos, uint32_t viewer_id, bool requi
block->viewers.add();
if (require_notification) {
notify_data_block_enter(*block, viewer_id);
notify_data_block_enter(*block, bpos, viewer_id);
}
// TODO viewers with varying flags during the game is not supported at the moment.
@ -570,7 +570,7 @@ struct ScheduleSaveAction {
std::vector<VoxelTerrain::BlockToSave> &blocks_to_save;
bool with_copy;
void operator()(VoxelDataBlock &block) {
void operator()(const Vector3i &bpos, VoxelDataBlock &block) {
// TODO Don't ask for save if the stream doesn't support it!
if (block.is_modified()) {
//print_line(String("Scheduling save for block {0}").format(varray(block->position.to_vec3())));
@ -582,7 +582,7 @@ struct ScheduleSaveAction {
} else {
b.voxels = block.get_voxels_shared();
}
b.position = block.get_position();
b.position = bpos;
blocks_to_save.push_back(b);
block.set_modified(false);
}
@ -593,11 +593,11 @@ struct ScheduleSaveAction {
void VoxelTerrain::unload_data_block(Vector3i bpos) {
const bool save = _stream.is_valid() && (!Engine::get_singleton()->is_editor_hint() || _run_stream_in_editor);
_data_map.remove_block(bpos, [this, save](VoxelDataBlock &block) {
emit_data_block_unloaded(block);
_data_map.remove_block(bpos, [this, save, bpos](VoxelDataBlock &block) {
emit_data_block_unloaded(block, bpos);
if (save) {
// Note: no need to copy the block because it gets removed from the map anyways
ScheduleSaveAction{ _blocks_to_save, false }(block);
ScheduleSaveAction{ _blocks_to_save, false }(bpos, block);
}
});
@ -780,8 +780,8 @@ void VoxelTerrain::stop_streamer() {
void VoxelTerrain::reset_map() {
// Discard everything, to reload it all
_data_map.for_each_block([this](VoxelDataBlock &block) { //
emit_data_block_unloaded(block);
_data_map.for_each_block([this](const Vector3i &bpos, VoxelDataBlock &block) { //
emit_data_block_unloaded(block, bpos);
});
_data_map.create(get_data_block_size_pow2(), 0);
@ -1008,7 +1008,7 @@ void VoxelTerrain::send_block_data_requests() {
_blocks_to_save.clear();
}
void VoxelTerrain::emit_data_block_loaded(const VoxelDataBlock &block) {
void VoxelTerrain::emit_data_block_loaded(const VoxelDataBlock &block, Vector3i bpos) {
// Not sure about exposing buffers directly... some stuff on them is useful to obtain directly,
// but also it allows scripters to mess with voxels in a way they should not.
// Example: modifying voxels without locking them first, while another thread may be reading them at the same
@ -1018,13 +1018,13 @@ void VoxelTerrain::emit_data_block_loaded(const VoxelDataBlock &block) {
// absolutely necessary, buffers aren't exposed. Workaround: use VoxelTool
//const Variant vbuffer = block->voxels;
//const Variant *args[2] = { &vpos, &vbuffer };
emit_signal(VoxelStringNames::get_singleton().block_loaded, block.get_position());
emit_signal(VoxelStringNames::get_singleton().block_loaded, bpos);
}
void VoxelTerrain::emit_data_block_unloaded(const VoxelDataBlock &block) {
void VoxelTerrain::emit_data_block_unloaded(const VoxelDataBlock &block, Vector3i bpos) {
// const Variant vbuffer = block->voxels;
// const Variant *args[2] = { &vpos, &vbuffer };
emit_signal(VoxelStringNames::get_singleton().block_unloaded, block.get_position());
emit_signal(VoxelStringNames::get_singleton().block_unloaded, bpos);
}
bool VoxelTerrain::try_get_paired_viewer_index(uint32_t id, size_t &out_i) const {
@ -1039,7 +1039,7 @@ bool VoxelTerrain::try_get_paired_viewer_index(uint32_t id, size_t &out_i) const
}
// TODO It is unclear yet if this API will stay. I have a feeling it might consume a lot of CPU
void VoxelTerrain::notify_data_block_enter(VoxelDataBlock &block, uint32_t viewer_id) {
void VoxelTerrain::notify_data_block_enter(VoxelDataBlock &block, Vector3i bpos, uint32_t viewer_id) {
if (!VoxelServer::get_singleton().viewer_exists(viewer_id)) {
// The viewer might have been removed between the moment we requested the block and the moment we finished
// loading it
@ -1050,6 +1050,7 @@ void VoxelTerrain::notify_data_block_enter(VoxelDataBlock &block, uint32_t viewe
}
_data_block_enter_info_obj->network_peer_id = VoxelServer::get_singleton().get_viewer_network_peer_id(viewer_id);
_data_block_enter_info_obj->voxel_block = &block;
_data_block_enter_info_obj->block_position = bpos;
if (!GDVIRTUAL_CALL(_on_data_block_entered, _data_block_enter_info_obj.get())) {
WARN_PRINT_ONCE("VoxelTerrain::_on_data_block_entered is unimplemented!");
@ -1355,11 +1356,11 @@ void VoxelTerrain::apply_data_block_response(VoxelServer::BlockDataOutput &ob) {
block->viewers = loading_block.viewers;
}
emit_data_block_loaded(*block);
emit_data_block_loaded(*block, block_pos);
for (unsigned int i = 0; i < loading_block.viewers_to_notify.size(); ++i) {
const uint32_t viewer_id = loading_block.viewers_to_notify[i];
notify_data_block_enter(*block, viewer_id);
notify_data_block_enter(*block, block_pos, viewer_id);
}
// The block itself might not be suitable for meshing yet, but blocks surrounding it might be now
@ -1698,7 +1699,7 @@ void VoxelTerrain::_b_save_block(Vector3i p_block_pos) {
return;
}
ScheduleSaveAction{ _blocks_to_save, true }(*block);
ScheduleSaveAction{ _blocks_to_save, true }(p_block_pos, *block);
}
void VoxelTerrain::_b_set_bounds(AABB aabb) {

View File

@ -177,12 +177,12 @@ private:
void get_viewer_pos_and_direction(Vector3 &out_pos, Vector3 &out_direction) const;
void send_block_data_requests();
void emit_data_block_loaded(const VoxelDataBlock &block);
void emit_data_block_unloaded(const VoxelDataBlock &block);
void emit_data_block_loaded(const VoxelDataBlock &block, Vector3i bpos);
void emit_data_block_unloaded(const VoxelDataBlock &block, Vector3i bpos);
bool try_get_paired_viewer_index(uint32_t id, size_t &out_i) const;
void notify_data_block_enter(VoxelDataBlock &block, uint32_t viewer_id);
void notify_data_block_enter(VoxelDataBlock &block, Vector3i bpos, uint32_t viewer_id);
void get_viewers_in_area(std::vector<int> &out_viewer_ids, Box3i voxel_box) const;

View File

@ -98,7 +98,7 @@ struct BeforeUnloadMeshAction {
struct ScheduleSaveAction {
std::vector<VoxelLodTerrainUpdateData::BlockToSave> &blocks_to_save;
void operator()(VoxelDataBlock &block) {
void operator()(const Vector3i &bpos, VoxelDataBlock &block) {
// Save if modified
// TODO Don't ask for save if the stream doesn't support it!
if (block.is_modified()) {
@ -111,7 +111,7 @@ struct ScheduleSaveAction {
block.get_voxels_const().duplicate_to(*b.voxels, true);
}
b.position = block.get_position();
b.position = bpos;
b.lod = block.get_lod_index();
blocks_to_save.push_back(b);
block.set_modified(false);
@ -2085,12 +2085,13 @@ void VoxelLodTerrain::update_gizmos() {
const Basis basis(Basis().scaled(Vector3(data_block_size, data_block_size, data_block_size)));
RWLockRead rlock(data_lod.map_lock);
data_lod.map.for_each_block([&dr, parent_transform, data_block_size, basis](const VoxelDataBlock &block) {
const Transform3D local_transform(basis, block.get_position() * data_block_size);
const Transform3D t = parent_transform * local_transform;
const Color8 c = Color8(block.is_modified() ? 255 : 0, 255, 0, 255);
dr.draw_box_mm(t, c);
});
data_lod.map.for_each_block(
[&dr, parent_transform, data_block_size, basis](const Vector3i &bpos, const VoxelDataBlock &block) {
const Transform3D local_transform(basis, bpos * data_block_size);
const Transform3D t = parent_transform * local_transform;
const Color8 c = Color8(block.is_modified() ? 255 : 0, 255, 0, 255);
dr.draw_box_mm(t, c);
});
}
dr.end();

View File

@ -166,6 +166,7 @@ void VoxelLodTerrainUpdateTask::flush_pending_lod_edits(VoxelLodTerrainUpdateDat
struct BeforeUnloadDataAction {
std::vector<VoxelLodTerrainUpdateData::BlockToSave> &blocks_to_save;
const Vector3i bpos;
bool save;
void operator()(VoxelDataBlock &block) {
@ -176,7 +177,7 @@ struct BeforeUnloadDataAction {
VoxelLodTerrainUpdateData::BlockToSave b;
// We don't copy since the block will be unloaded anyways
b.voxels = block.get_voxels_shared();
b.position = block.get_position();
b.position = bpos;
b.lod = block.get_lod_index();
blocks_to_save.push_back(b);
}
@ -187,7 +188,7 @@ static void unload_data_block_no_lock(VoxelLodTerrainUpdateData::Lod &lod, Voxel
Vector3i block_pos, std::vector<VoxelLodTerrainUpdateData::BlockToSave> &blocks_to_save, bool can_save) {
ZN_PROFILE_SCOPE();
data_lod.map.remove_block(block_pos, BeforeUnloadDataAction{ blocks_to_save, can_save });
data_lod.map.remove_block(block_pos, BeforeUnloadDataAction{ blocks_to_save, block_pos, can_save });
//print_line(String("Unloading data block {0} lod {1}").format(varray(block_pos.to_vec3(), lod_index)));
MutexLock lock(lod.loading_blocks_mutex);

View File

@ -16,8 +16,7 @@ Ref<gd::VoxelBuffer> VoxelDataBlockEnterInfo::_b_get_voxels() const {
}
Vector3i VoxelDataBlockEnterInfo::_b_get_position() const {
ERR_FAIL_COND_V(voxel_block == nullptr, Vector3i());
return voxel_block->get_position();
return block_position;
}
int VoxelDataBlockEnterInfo::_b_get_lod_index() const {

View File

@ -18,6 +18,7 @@ class VoxelDataBlockEnterInfo : public Object {
GDCLASS(VoxelDataBlockEnterInfo, Object)
public:
int network_peer_id = -1;
Vector3i block_position;
VoxelDataBlock *voxel_block = nullptr;
private: