mirror of
https://github.com/Relintai/godot_voxel.git
synced 2024-11-11 20:35:08 +01:00
Fixed set_voxel() and block force_update_blocks()
This commit is contained in:
parent
d3ab015c67
commit
06a399f932
@ -23,7 +23,7 @@ void VoxelBuffer::create(int sx, int sy, int sz) {
|
|||||||
Channel & channel = _channels[i];
|
Channel & channel = _channels[i];
|
||||||
if (channel.data) {
|
if (channel.data) {
|
||||||
// TODO Optimize with realloc
|
// TODO Optimize with realloc
|
||||||
delete_channel(i, _size);
|
delete_channel(i);
|
||||||
create_channel(i, new_size);
|
create_channel(i, new_size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -35,19 +35,26 @@ void VoxelBuffer::clear() {
|
|||||||
for (unsigned int i = 0; i < MAX_CHANNELS; ++i) {
|
for (unsigned int i = 0; i < MAX_CHANNELS; ++i) {
|
||||||
Channel & channel = _channels[i];
|
Channel & channel = _channels[i];
|
||||||
if (channel.data) {
|
if (channel.data) {
|
||||||
delete_channel(i, _size);
|
delete_channel(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelBuffer::clear_channel(unsigned int channel_index, int clear_value) {
|
void VoxelBuffer::clear_channel(unsigned int channel_index, int clear_value) {
|
||||||
ERR_FAIL_INDEX(channel_index, MAX_CHANNELS);
|
ERR_FAIL_INDEX(channel_index, MAX_CHANNELS);
|
||||||
delete_channel(channel_index, _size);
|
if(_channels[channel_index].data)
|
||||||
|
delete_channel(channel_index);
|
||||||
_channels[channel_index].defval = clear_value;
|
_channels[channel_index].defval = clear_value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void VoxelBuffer::set_default_values(uint8_t values[VoxelBuffer::MAX_CHANNELS]) {
|
||||||
|
for(unsigned int i = 0; i < MAX_CHANNELS; ++i) {
|
||||||
|
_channels[i].defval = values[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
int VoxelBuffer::get_voxel(int x, int y, int z, unsigned int channel_index) const {
|
int VoxelBuffer::get_voxel(int x, int y, int z, unsigned int channel_index) const {
|
||||||
ERR_FAIL_INDEX_V(channel_index, MAX_CHANNELS, 0);
|
ERR_FAIL_INDEX_V(channel_index, MAX_CHANNELS, 0);
|
||||||
|
|
||||||
const Channel & channel = _channels[channel_index];
|
const Channel & channel = _channels[channel_index];
|
||||||
|
|
||||||
@ -156,7 +163,7 @@ void VoxelBuffer::copy_from(const VoxelBuffer & other, unsigned int channel_inde
|
|||||||
memcpy(channel.data, other_channel.data, get_volume() * sizeof(uint8_t));
|
memcpy(channel.data, other_channel.data, get_volume() * sizeof(uint8_t));
|
||||||
}
|
}
|
||||||
else if(channel.data) {
|
else if(channel.data) {
|
||||||
delete_channel(channel_index, _size);
|
delete_channel(channel_index);
|
||||||
}
|
}
|
||||||
|
|
||||||
channel.defval = other_channel.defval;
|
channel.defval = other_channel.defval;
|
||||||
@ -223,8 +230,9 @@ void VoxelBuffer::create_channel_noinit(int i, Vector3i size) {
|
|||||||
channel.data = (uint8_t*)memalloc(volume * sizeof(uint8_t));
|
channel.data = (uint8_t*)memalloc(volume * sizeof(uint8_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
void VoxelBuffer::delete_channel(int i, Vector3i size) {
|
void VoxelBuffer::delete_channel(int i) {
|
||||||
Channel & channel = _channels[i];
|
Channel & channel = _channels[i];
|
||||||
|
ERR_FAIL_COND(channel.data == NULL);
|
||||||
memfree(channel.data);
|
memfree(channel.data);
|
||||||
channel.data = NULL;
|
channel.data = NULL;
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,8 @@ public:
|
|||||||
|
|
||||||
_FORCE_INLINE_ Vector3i get_size() const { return _size; }
|
_FORCE_INLINE_ Vector3i get_size() const { return _size; }
|
||||||
|
|
||||||
|
void set_default_values(uint8_t values[MAX_CHANNELS]);
|
||||||
|
|
||||||
int get_voxel(int x, int y, int z, unsigned int channel_index=0) const;
|
int get_voxel(int x, int y, int z, unsigned int channel_index=0) const;
|
||||||
void set_voxel(int value, int x, int y, int z, unsigned int channel_index=0);
|
void set_voxel(int value, int x, int y, int z, unsigned int channel_index=0);
|
||||||
void set_voxel_v(int value, Vector3 pos, unsigned int channel_index = 0);
|
void set_voxel_v(int value, Vector3 pos, unsigned int channel_index = 0);
|
||||||
@ -62,7 +64,7 @@ public:
|
|||||||
private:
|
private:
|
||||||
void create_channel_noinit(int i, Vector3i size);
|
void create_channel_noinit(int i, Vector3i size);
|
||||||
void create_channel(int i, Vector3i size, uint8_t defval=0);
|
void create_channel(int i, Vector3i size, uint8_t defval=0);
|
||||||
void delete_channel(int i, Vector3i size);
|
void delete_channel(int i);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
static void _bind_methods();
|
static void _bind_methods();
|
||||||
|
@ -15,18 +15,15 @@ MeshInstance * VoxelBlock::get_mesh_instance(const Node & root) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Helper
|
// Helper
|
||||||
VoxelBlock * VoxelBlock::create(Vector3i bpos, VoxelBuffer * buffer) {
|
VoxelBlock * VoxelBlock::create(Vector3i bpos, Ref<VoxelBuffer> buffer) {
|
||||||
|
const int bs = VoxelBlock::SIZE;
|
||||||
|
ERR_FAIL_COND_V(buffer.is_null(), NULL);
|
||||||
|
ERR_FAIL_COND_V(buffer->get_size() != Vector3i(bs, bs, bs), NULL);
|
||||||
|
|
||||||
VoxelBlock * block = memnew(VoxelBlock);
|
VoxelBlock * block = memnew(VoxelBlock);
|
||||||
block->pos = bpos;
|
block->pos = bpos;
|
||||||
if (buffer) {
|
|
||||||
const int bs = VoxelBlock::SIZE;
|
block->voxels = buffer;
|
||||||
ERR_FAIL_COND_V(buffer->get_size() != Vector3i(bs, bs, bs), NULL);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
buffer = memnew(VoxelBuffer);
|
|
||||||
}
|
|
||||||
ERR_FAIL_COND_V(buffer == NULL, NULL);
|
|
||||||
block->voxels = Ref<VoxelBuffer>(buffer);
|
|
||||||
//block->map = ↦
|
//block->map = ↦
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
@ -58,12 +55,21 @@ int VoxelMap::get_voxel(Vector3i pos, unsigned int c) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void VoxelMap::set_voxel(int value, Vector3i pos, unsigned int c) {
|
void VoxelMap::set_voxel(int value, Vector3i pos, unsigned int c) {
|
||||||
|
|
||||||
Vector3i bpos = voxel_to_block(pos);
|
Vector3i bpos = voxel_to_block(pos);
|
||||||
VoxelBlock * block = get_block(bpos);
|
VoxelBlock * block = get_block(bpos);
|
||||||
|
|
||||||
if (block == NULL) {
|
if (block == NULL) {
|
||||||
block = VoxelBlock::create(bpos);
|
|
||||||
|
Ref<VoxelBuffer> buffer(memnew(VoxelBuffer));
|
||||||
|
buffer->create(VoxelBlock::SIZE, VoxelBlock::SIZE, VoxelBlock::SIZE);
|
||||||
|
buffer->set_default_values(_default_voxel);
|
||||||
|
|
||||||
|
block = VoxelBlock::create(bpos, buffer);
|
||||||
|
|
||||||
set_block(bpos, block);
|
set_block(bpos, block);
|
||||||
}
|
}
|
||||||
|
|
||||||
block->voxels->set_voxel(value, pos - block_to_voxel(bpos), c);
|
block->voxels->set_voxel(value, pos - block_to_voxel(bpos), c);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -90,6 +96,7 @@ VoxelBlock * VoxelMap::get_block(Vector3i bpos) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void VoxelMap::set_block(Vector3i bpos, VoxelBlock * block) {
|
void VoxelMap::set_block(Vector3i bpos, VoxelBlock * block) {
|
||||||
|
ERR_FAIL_COND(block == NULL);
|
||||||
if (_last_accessed_block == NULL || _last_accessed_block->pos == bpos) {
|
if (_last_accessed_block == NULL || _last_accessed_block->pos == bpos) {
|
||||||
_last_accessed_block = block;
|
_last_accessed_block = block;
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ public:
|
|||||||
Vector3i pos;
|
Vector3i pos;
|
||||||
NodePath mesh_instance_path;
|
NodePath mesh_instance_path;
|
||||||
|
|
||||||
static VoxelBlock * create(Vector3i bpos, VoxelBuffer * buffer = 0);
|
static VoxelBlock * create(Vector3i bpos, Ref<VoxelBuffer> buffer);
|
||||||
|
|
||||||
MeshInstance * get_mesh_instance(const Node & root);
|
MeshInstance * get_mesh_instance(const Node & root);
|
||||||
|
|
||||||
|
@ -79,6 +79,7 @@ void VoxelTerrain::update_blocks() {
|
|||||||
uint32_t max_time = 1000 / 60;
|
uint32_t max_time = 1000 / 60;
|
||||||
|
|
||||||
while (!_block_update_queue.empty() && (os.get_ticks_msec() - time_before) < max_time) {
|
while (!_block_update_queue.empty() && (os.get_ticks_msec() - time_before) < max_time) {
|
||||||
|
//printf("Remaining: %i\n", _block_update_queue.size());
|
||||||
|
|
||||||
// TODO Move this to a thread
|
// TODO Move this to a thread
|
||||||
// TODO Have VoxelTerrainGenerator in C++
|
// TODO Have VoxelTerrainGenerator in C++
|
||||||
@ -88,37 +89,37 @@ void VoxelTerrain::update_blocks() {
|
|||||||
Vector3i block_pos = _block_update_queue[_block_update_queue.size() - 1];
|
Vector3i block_pos = _block_update_queue[_block_update_queue.size() - 1];
|
||||||
|
|
||||||
if (!_map->has_block(block_pos)) {
|
if (!_map->has_block(block_pos)) {
|
||||||
|
|
||||||
// Create buffer
|
// Create buffer
|
||||||
Ref<VoxelBuffer> buffer_ref = Ref<VoxelBuffer>(memnew(VoxelBuffer));
|
|
||||||
const Vector3i block_size(VoxelBlock::SIZE, VoxelBlock::SIZE, VoxelBlock::SIZE);
|
|
||||||
buffer_ref->create(block_size.x, block_size.y, block_size.z);
|
|
||||||
|
|
||||||
// Query voxel provider
|
|
||||||
if(!_provider.is_null()) {
|
if(!_provider.is_null()) {
|
||||||
|
Ref<VoxelBuffer> buffer_ref = Ref<VoxelBuffer>(memnew(VoxelBuffer));
|
||||||
|
const Vector3i block_size(VoxelBlock::SIZE, VoxelBlock::SIZE, VoxelBlock::SIZE);
|
||||||
|
buffer_ref->create(block_size.x, block_size.y, block_size.z);
|
||||||
|
|
||||||
|
// Query voxel provider
|
||||||
_provider->emerge_block(buffer_ref, block_pos);
|
_provider->emerge_block(buffer_ref, block_pos);
|
||||||
|
|
||||||
|
// Check script return
|
||||||
|
ERR_FAIL_COND(buffer_ref->get_size() != block_size);
|
||||||
|
|
||||||
|
// Store buffer
|
||||||
|
_map->set_block_buffer(block_pos, buffer_ref);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Check script return
|
// Update meshes
|
||||||
ERR_FAIL_COND(buffer_ref->get_size() != block_size);
|
Vector3i ndir;
|
||||||
|
for (ndir.z = -1; ndir.z < 2; ++ndir.z) {
|
||||||
// Store buffer
|
for (ndir.x = -1; ndir.x < 2; ++ndir.x) {
|
||||||
_map->set_block_buffer(block_pos, buffer_ref);
|
for (ndir.y = -1; ndir.y < 2; ++ndir.y) {
|
||||||
|
Vector3i npos = block_pos + ndir;
|
||||||
// Update meshes
|
// TODO What if the map is really composed of empty blocks?
|
||||||
Vector3i ndir;
|
if (_map->is_block_surrounded(npos)) {
|
||||||
for (ndir.z = -1; ndir.z < 2; ++ndir.z) {
|
update_block_mesh(npos);
|
||||||
for (ndir.x = -1; ndir.x < 2; ++ndir.x) {
|
|
||||||
for (ndir.y = -1; ndir.y < 2; ++ndir.y) {
|
|
||||||
Vector3i npos = block_pos + ndir;
|
|
||||||
if (_map->is_block_surrounded(npos)) {
|
|
||||||
update_block_mesh(npos);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//update_block_mesh(block_pos);
|
|
||||||
}
|
}
|
||||||
|
//update_block_mesh(block_pos);
|
||||||
|
|
||||||
// Pop request
|
// Pop request
|
||||||
_block_update_queue.resize(_block_update_queue.size() - 1);
|
_block_update_queue.resize(_block_update_queue.size() - 1);
|
||||||
@ -191,6 +192,8 @@ void VoxelTerrain::_bind_methods() {
|
|||||||
ObjectTypeDB::bind_method(_MD("get_block_update_count"), &VoxelTerrain::get_block_update_count);
|
ObjectTypeDB::bind_method(_MD("get_block_update_count"), &VoxelTerrain::get_block_update_count);
|
||||||
ObjectTypeDB::bind_method(_MD("get_mesher:VoxelMesher"), &VoxelTerrain::get_mesher);
|
ObjectTypeDB::bind_method(_MD("get_mesher:VoxelMesher"), &VoxelTerrain::get_mesher);
|
||||||
|
|
||||||
|
ObjectTypeDB::bind_method(_MD("get_map:VoxelMap"), &VoxelTerrain::get_map);
|
||||||
|
|
||||||
// TODO Make those two static in VoxelMap?
|
// TODO Make those two static in VoxelMap?
|
||||||
ObjectTypeDB::bind_method(_MD("voxel_to_block", "voxel_pos"), &VoxelTerrain::_voxel_to_block_binding);
|
ObjectTypeDB::bind_method(_MD("voxel_to_block", "voxel_pos"), &VoxelTerrain::_voxel_to_block_binding);
|
||||||
ObjectTypeDB::bind_method(_MD("block_to_voxel", "block_pos"), &VoxelTerrain::_block_to_voxel_binding);
|
ObjectTypeDB::bind_method(_MD("block_to_voxel", "block_pos"), &VoxelTerrain::_block_to_voxel_binding);
|
||||||
|
@ -20,6 +20,7 @@ public:
|
|||||||
int get_block_update_count();
|
int get_block_update_count();
|
||||||
|
|
||||||
Ref<VoxelMesher> get_mesher() { return _mesher; }
|
Ref<VoxelMesher> get_mesher() { return _mesher; }
|
||||||
|
Ref<VoxelMap> get_map() { return _map; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void _notification(int p_what);
|
void _notification(int p_what);
|
||||||
|
Loading…
Reference in New Issue
Block a user