2017-08-20 15:48:55 +02:00
|
|
|
#include "voxel_block.h"
|
|
|
|
|
|
|
|
// Helper
|
|
|
|
VoxelBlock *VoxelBlock::create(Vector3i bpos, Ref<VoxelBuffer> buffer, unsigned int size) {
|
|
|
|
const int bs = 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);
|
|
|
|
block->pos = bpos;
|
2017-08-20 18:37:08 +02:00
|
|
|
block->_position_in_voxels = bpos * size;
|
2017-08-20 15:48:55 +02:00
|
|
|
|
|
|
|
block->voxels = buffer;
|
|
|
|
//block->map = ↦
|
|
|
|
return block;
|
|
|
|
}
|
|
|
|
|
2019-04-24 02:29:47 +02:00
|
|
|
VoxelBlock::VoxelBlock() :
|
|
|
|
voxels(NULL),
|
|
|
|
_mesh_update_count(0) {
|
2017-08-20 18:37:08 +02:00
|
|
|
|
|
|
|
VisualServer &vs = *VisualServer::get_singleton();
|
|
|
|
|
|
|
|
if (_mesh_instance.is_valid()) {
|
|
|
|
vs.free(_mesh_instance);
|
|
|
|
_mesh_instance = RID();
|
|
|
|
}
|
2017-08-20 15:48:55 +02:00
|
|
|
}
|
|
|
|
|
2017-08-20 18:37:08 +02:00
|
|
|
void VoxelBlock::set_mesh(Ref<Mesh> mesh, Ref<World> world) {
|
|
|
|
|
|
|
|
VisualServer &vs = *VisualServer::get_singleton();
|
|
|
|
|
2019-04-24 02:29:47 +02:00
|
|
|
if (mesh.is_valid()) {
|
2017-08-20 18:37:08 +02:00
|
|
|
|
2019-04-24 02:29:47 +02:00
|
|
|
if (_mesh_instance.is_valid() == false) {
|
2017-08-20 18:37:08 +02:00
|
|
|
// Create instance if it doesn't exist
|
|
|
|
ERR_FAIL_COND(world.is_null());
|
|
|
|
_mesh_instance = vs.instance_create();
|
|
|
|
vs.instance_set_scenario(_mesh_instance, world->get_scenario());
|
|
|
|
}
|
|
|
|
|
|
|
|
vs.instance_set_base(_mesh_instance, mesh.is_valid() ? mesh->get_rid() : RID());
|
|
|
|
|
|
|
|
Transform local_transform(Basis(), _position_in_voxels.to_vec3());
|
|
|
|
vs.instance_set_transform(_mesh_instance, local_transform);
|
|
|
|
// TODO The day VoxelTerrain becomes a Spatial, this transform will need to be updatable separately
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
2019-04-24 02:29:47 +02:00
|
|
|
if (_mesh_instance.is_valid()) {
|
2017-08-20 18:37:08 +02:00
|
|
|
// Delete instance if it exists
|
|
|
|
vs.free(_mesh_instance);
|
|
|
|
_mesh_instance = RID();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
_mesh = mesh;
|
2018-09-29 18:08:05 +02:00
|
|
|
++_mesh_update_count;
|
|
|
|
|
2019-04-24 02:29:47 +02:00
|
|
|
// if(_mesh_update_count > 1) {
|
|
|
|
// print_line(String("Block {0} was updated {1} times").format(varray(pos.to_vec3(), _mesh_update_count)));
|
|
|
|
// }
|
2017-08-20 18:37:08 +02:00
|
|
|
}
|
2017-08-28 02:32:23 +02:00
|
|
|
|
|
|
|
void VoxelBlock::enter_world(World *world) {
|
2019-04-24 02:29:47 +02:00
|
|
|
if (_mesh_instance.is_valid()) {
|
2017-08-28 02:32:23 +02:00
|
|
|
VisualServer &vs = *VisualServer::get_singleton();
|
|
|
|
vs.instance_set_scenario(_mesh_instance, world->get_scenario());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void VoxelBlock::exit_world() {
|
2019-04-24 02:29:47 +02:00
|
|
|
if (_mesh_instance.is_valid()) {
|
2017-08-28 02:32:23 +02:00
|
|
|
VisualServer &vs = *VisualServer::get_singleton();
|
|
|
|
vs.instance_set_scenario(_mesh_instance, RID());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void VoxelBlock::set_visible(bool visible) {
|
2019-04-24 02:29:47 +02:00
|
|
|
if (_mesh_instance.is_valid()) {
|
2017-08-28 02:32:23 +02:00
|
|
|
VisualServer &vs = *VisualServer::get_singleton();
|
|
|
|
vs.instance_set_visible(_mesh_instance, visible);
|
|
|
|
}
|
|
|
|
}
|