2020-01-31 19:52:37 +01:00
|
|
|
/*
|
|
|
|
Copyright (c) 2019-2020 Péter Magyar
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
|
|
in the Software without restriction, including without limitation the rights
|
|
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in all
|
|
|
|
copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
|
SOFTWARE.
|
|
|
|
*/
|
|
|
|
|
2019-06-07 01:33:41 +02:00
|
|
|
#include "voxel_chunk.h"
|
|
|
|
|
2019-08-12 20:40:05 +02:00
|
|
|
#include "voxel_world.h"
|
|
|
|
|
2020-04-05 22:07:52 +02:00
|
|
|
#include "../thirdparty/lz4/lz4.h"
|
|
|
|
|
2020-04-09 12:34:39 +02:00
|
|
|
#if VERSION_MAJOR < 4
|
|
|
|
#include "servers/visual_server.h"
|
|
|
|
#else
|
|
|
|
#include "servers/rendering_server.h"
|
|
|
|
|
|
|
|
typedef class RenderingServer VisualServer;
|
|
|
|
typedef class RenderingServer VS;
|
|
|
|
|
|
|
|
#define REAL FLOAT
|
|
|
|
|
|
|
|
typedef PackedVector3Array PoolVector3Array;
|
|
|
|
typedef PackedVector2Array PoolVector2Array;
|
|
|
|
typedef PackedColorArray PoolColorArray;
|
|
|
|
typedef PackedInt32Array PoolIntArray;
|
|
|
|
#endif
|
|
|
|
|
2020-04-18 02:15:01 +02:00
|
|
|
_FORCE_INLINE_ bool VoxelChunk::get_is_build_threaded() const {
|
|
|
|
return _is_build_threaded;
|
|
|
|
}
|
|
|
|
_FORCE_INLINE_ void VoxelChunk::set_is_build_threaded(const bool value) {
|
|
|
|
_is_build_threaded = value;
|
|
|
|
}
|
|
|
|
|
2020-04-02 21:28:19 +02:00
|
|
|
_FORCE_INLINE_ bool VoxelChunk::get_process() const {
|
|
|
|
return _is_processing;
|
|
|
|
}
|
|
|
|
_FORCE_INLINE_ void VoxelChunk::set_process(const bool value) {
|
|
|
|
_is_processing = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
_FORCE_INLINE_ bool VoxelChunk::get_physics_process() const {
|
|
|
|
return _is_phisics_processing;
|
|
|
|
}
|
|
|
|
_FORCE_INLINE_ void VoxelChunk::set_physics_process(const bool value) {
|
|
|
|
_is_phisics_processing = value;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool VoxelChunk::get_visible() const {
|
|
|
|
return _is_visible;
|
|
|
|
}
|
|
|
|
void VoxelChunk::set_visible(const bool value) {
|
|
|
|
_is_visible = value;
|
|
|
|
|
|
|
|
visibility_changed(value);
|
|
|
|
}
|
|
|
|
|
2019-11-19 14:42:21 +01:00
|
|
|
_FORCE_INLINE_ bool VoxelChunk::get_is_generating() const {
|
|
|
|
return _is_generating;
|
|
|
|
}
|
2020-04-16 17:10:04 +02:00
|
|
|
_FORCE_INLINE_ void VoxelChunk::set_is_generating(const bool value) {
|
2019-11-19 14:42:21 +01:00
|
|
|
_is_generating = value;
|
|
|
|
}
|
|
|
|
|
2020-04-22 12:33:14 +02:00
|
|
|
bool VoxelChunk::is_in_tree() const {
|
|
|
|
return _is_in_tree;
|
|
|
|
}
|
|
|
|
|
2019-11-18 19:22:11 +01:00
|
|
|
_FORCE_INLINE_ bool VoxelChunk::get_dirty() const {
|
2019-11-10 03:10:42 +01:00
|
|
|
return _dirty;
|
|
|
|
}
|
2020-04-16 17:10:04 +02:00
|
|
|
_FORCE_INLINE_ void VoxelChunk::set_dirty(const bool value) {
|
2019-11-10 03:10:42 +01:00
|
|
|
_dirty = value;
|
|
|
|
}
|
|
|
|
|
2019-11-18 19:22:11 +01:00
|
|
|
_FORCE_INLINE_ int VoxelChunk::get_state() const {
|
2019-11-10 03:10:42 +01:00
|
|
|
return _state;
|
|
|
|
}
|
2020-04-16 17:10:04 +02:00
|
|
|
_FORCE_INLINE_ void VoxelChunk::set_state(const int value) {
|
2019-11-10 03:10:42 +01:00
|
|
|
_state = value;
|
|
|
|
}
|
|
|
|
|
2020-04-16 17:10:04 +02:00
|
|
|
_FORCE_INLINE_ int VoxelChunk::get_position_x() const {
|
2019-11-18 20:16:29 +01:00
|
|
|
return _position_x;
|
2019-06-07 01:33:41 +02:00
|
|
|
}
|
2020-04-16 17:10:04 +02:00
|
|
|
void VoxelChunk::set_position_x(const int value) {
|
2019-11-18 22:22:41 +01:00
|
|
|
_position_x = value;
|
|
|
|
}
|
2020-04-16 17:10:04 +02:00
|
|
|
_FORCE_INLINE_ int VoxelChunk::get_position_y() const {
|
2019-11-18 20:16:29 +01:00
|
|
|
return _position_y;
|
2019-07-17 02:28:16 +02:00
|
|
|
}
|
2020-04-16 17:10:04 +02:00
|
|
|
void VoxelChunk::set_position_y(const int value) {
|
2019-11-18 22:22:41 +01:00
|
|
|
_position_y = value;
|
|
|
|
}
|
2020-04-16 17:10:04 +02:00
|
|
|
_FORCE_INLINE_ int VoxelChunk::get_position_z() const {
|
2019-11-18 20:16:29 +01:00
|
|
|
return _position_z;
|
2019-07-17 02:28:16 +02:00
|
|
|
}
|
2020-04-16 17:10:04 +02:00
|
|
|
void VoxelChunk::set_position_z(const int value) {
|
2019-11-18 22:22:41 +01:00
|
|
|
_position_z = value;
|
|
|
|
}
|
2019-07-17 02:28:16 +02:00
|
|
|
|
2019-11-18 20:16:29 +01:00
|
|
|
_FORCE_INLINE_ Vector3 VoxelChunk::get_position() const {
|
|
|
|
return Vector3(_position_x, _position_y, _position_z);
|
2019-07-17 02:28:16 +02:00
|
|
|
}
|
|
|
|
|
2020-04-16 17:10:04 +02:00
|
|
|
_FORCE_INLINE_ int VoxelChunk::get_size_x() const {
|
2019-11-18 20:16:29 +01:00
|
|
|
return _size_x;
|
2019-07-17 02:28:16 +02:00
|
|
|
}
|
2020-04-16 17:10:04 +02:00
|
|
|
_FORCE_INLINE_ int VoxelChunk::get_size_y() const {
|
2019-11-18 20:16:29 +01:00
|
|
|
return _size_y;
|
2019-07-17 02:28:16 +02:00
|
|
|
}
|
2020-04-16 17:10:04 +02:00
|
|
|
_FORCE_INLINE_ int VoxelChunk::get_size_z() const {
|
2019-11-18 20:16:29 +01:00
|
|
|
return _size_z;
|
2019-07-17 02:28:16 +02:00
|
|
|
}
|
|
|
|
|
2020-04-16 17:10:04 +02:00
|
|
|
_FORCE_INLINE_ void VoxelChunk::set_size_x(const int value) {
|
2020-02-26 01:08:18 +01:00
|
|
|
_size_x = value;
|
|
|
|
}
|
2020-04-16 17:10:04 +02:00
|
|
|
_FORCE_INLINE_ void VoxelChunk::set_size_y(const int value) {
|
2020-02-26 01:08:18 +01:00
|
|
|
_size_y = value;
|
|
|
|
}
|
2020-04-16 17:10:04 +02:00
|
|
|
_FORCE_INLINE_ void VoxelChunk::set_size_z(const int value) {
|
2020-02-26 01:08:18 +01:00
|
|
|
_size_z = value;
|
|
|
|
}
|
|
|
|
|
2019-11-18 20:16:29 +01:00
|
|
|
_FORCE_INLINE_ Vector3 VoxelChunk::get_size() const {
|
|
|
|
return Vector3(_size_x, _size_y, _size_z);
|
2019-07-17 02:28:16 +02:00
|
|
|
}
|
2019-11-18 19:22:11 +01:00
|
|
|
|
2020-04-16 17:10:04 +02:00
|
|
|
_FORCE_INLINE_ int VoxelChunk::get_data_size_x() const {
|
2019-11-18 20:16:29 +01:00
|
|
|
return _data_size_x;
|
2019-11-18 19:22:11 +01:00
|
|
|
}
|
2020-04-16 17:10:04 +02:00
|
|
|
_FORCE_INLINE_ int VoxelChunk::get_data_size_y() const {
|
2019-11-18 20:16:29 +01:00
|
|
|
return _data_size_y;
|
2019-11-18 19:22:11 +01:00
|
|
|
}
|
2020-04-16 17:10:04 +02:00
|
|
|
_FORCE_INLINE_ int VoxelChunk::get_data_size_z() const {
|
2019-11-18 20:16:29 +01:00
|
|
|
return _data_size_z;
|
2019-11-18 19:22:11 +01:00
|
|
|
}
|
|
|
|
|
2020-04-16 17:10:04 +02:00
|
|
|
_FORCE_INLINE_ void VoxelChunk::set_data_size_x(const int value) {
|
2020-02-26 01:08:18 +01:00
|
|
|
_data_size_x = value;
|
|
|
|
}
|
2020-04-16 17:10:04 +02:00
|
|
|
_FORCE_INLINE_ void VoxelChunk::set_data_size_y(const int value) {
|
2020-02-26 01:08:18 +01:00
|
|
|
_data_size_y = value;
|
|
|
|
}
|
2020-04-16 17:10:04 +02:00
|
|
|
_FORCE_INLINE_ void VoxelChunk::set_data_size_z(const int value) {
|
2020-02-26 01:08:18 +01:00
|
|
|
_data_size_z = value;
|
|
|
|
}
|
|
|
|
|
2020-04-16 17:10:04 +02:00
|
|
|
void VoxelChunk::set_position(const int x, const int y, const int z) {
|
2019-11-18 22:22:41 +01:00
|
|
|
_position_x = x;
|
|
|
|
_position_y = y;
|
|
|
|
_position_z = z;
|
|
|
|
}
|
|
|
|
|
2020-01-09 04:29:05 +01:00
|
|
|
_FORCE_INLINE_ int VoxelChunk::get_margin_start() const {
|
|
|
|
return _margin_start;
|
2019-11-18 19:43:15 +01:00
|
|
|
}
|
|
|
|
_FORCE_INLINE_ int VoxelChunk::get_margin_end() const {
|
2020-01-09 04:29:05 +01:00
|
|
|
return _margin_end;
|
2019-07-17 02:28:16 +02:00
|
|
|
}
|
|
|
|
|
2020-04-16 17:10:04 +02:00
|
|
|
_FORCE_INLINE_ void VoxelChunk::set_margin_start(const int value) {
|
2020-02-26 01:08:18 +01:00
|
|
|
_margin_start = value;
|
|
|
|
}
|
2020-04-16 17:10:04 +02:00
|
|
|
_FORCE_INLINE_ void VoxelChunk::set_margin_end(const int value) {
|
2020-02-26 01:08:18 +01:00
|
|
|
_margin_end = value;
|
|
|
|
}
|
|
|
|
|
2019-06-07 01:33:41 +02:00
|
|
|
Ref<VoxelmanLibrary> VoxelChunk::get_library() {
|
|
|
|
return _library;
|
|
|
|
}
|
2020-03-12 23:23:38 +01:00
|
|
|
void VoxelChunk::set_library(const Ref<VoxelmanLibrary> &value) {
|
2019-06-07 01:33:41 +02:00
|
|
|
_library = value;
|
|
|
|
}
|
|
|
|
|
2019-07-17 02:28:16 +02:00
|
|
|
float VoxelChunk::get_voxel_scale() const {
|
2019-06-07 01:33:41 +02:00
|
|
|
return _voxel_scale;
|
|
|
|
}
|
2020-04-16 17:10:04 +02:00
|
|
|
void VoxelChunk::set_voxel_scale(const float value) {
|
2019-06-07 01:33:41 +02:00
|
|
|
_voxel_scale = value;
|
2019-07-17 17:01:12 +02:00
|
|
|
|
2020-01-13 00:39:55 +01:00
|
|
|
for (int i = 0; i < _meshers.size(); ++i) {
|
|
|
|
Ref<VoxelMesher> mesher = _meshers.get(i);
|
|
|
|
|
|
|
|
ERR_CONTINUE(!mesher.is_valid());
|
|
|
|
|
|
|
|
mesher->set_voxel_scale(_voxel_scale);
|
2019-07-17 17:01:12 +02:00
|
|
|
}
|
2019-06-07 01:33:41 +02:00
|
|
|
}
|
|
|
|
|
2020-03-12 23:23:38 +01:00
|
|
|
VoxelWorld *VoxelChunk::get_voxel_world() const {
|
|
|
|
return _voxel_world;
|
2019-10-10 23:51:05 +02:00
|
|
|
}
|
2020-03-12 23:23:38 +01:00
|
|
|
void VoxelChunk::set_voxel_world(VoxelWorld *world) {
|
|
|
|
_voxel_world = world;
|
2019-10-10 23:51:05 +02:00
|
|
|
}
|
2020-03-12 23:23:38 +01:00
|
|
|
void VoxelChunk::set_voxel_world_bind(Node *world) {
|
|
|
|
if (world == NULL) {
|
|
|
|
_voxel_world = NULL;
|
|
|
|
return;
|
|
|
|
}
|
2019-10-10 23:51:05 +02:00
|
|
|
|
2020-03-12 23:23:38 +01:00
|
|
|
_voxel_world = Object::cast_to<VoxelWorld>(world);
|
2020-01-13 00:39:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
Ref<VoxelMesher> VoxelChunk::get_mesher(int index) const {
|
|
|
|
ERR_FAIL_INDEX_V(index, _meshers.size(), Ref<VoxelMesher>());
|
|
|
|
|
|
|
|
return _meshers.get(index);
|
|
|
|
}
|
2020-04-16 17:10:04 +02:00
|
|
|
void VoxelChunk::set_mesher(int index, const Ref<VoxelMesher> &mesher) {
|
2020-01-13 00:39:55 +01:00
|
|
|
ERR_FAIL_INDEX(index, _meshers.size());
|
|
|
|
|
|
|
|
_meshers.set(index, mesher);
|
|
|
|
}
|
2020-04-16 17:10:04 +02:00
|
|
|
void VoxelChunk::remove_mesher(const int index) {
|
2020-01-13 00:39:55 +01:00
|
|
|
ERR_FAIL_INDEX(index, _meshers.size());
|
|
|
|
|
|
|
|
_meshers.remove(index);
|
2019-06-07 01:33:41 +02:00
|
|
|
}
|
2020-04-16 17:10:04 +02:00
|
|
|
void VoxelChunk::add_mesher(const Ref<VoxelMesher> &mesher) {
|
2020-01-13 00:39:55 +01:00
|
|
|
_meshers.push_back(mesher);
|
|
|
|
}
|
2020-04-16 17:10:04 +02:00
|
|
|
int VoxelChunk::get_mesher_count() const {
|
2020-01-13 00:39:55 +01:00
|
|
|
return _meshers.size();
|
2019-06-07 01:33:41 +02:00
|
|
|
}
|
|
|
|
|
2020-04-20 00:31:46 +02:00
|
|
|
Ref<VoxelMesher> VoxelChunk::get_liquid_mesher(int index) const {
|
|
|
|
ERR_FAIL_INDEX_V(index, _liquid_meshers.size(), Ref<VoxelMesher>());
|
|
|
|
|
|
|
|
return _liquid_meshers.get(index);
|
|
|
|
}
|
|
|
|
void VoxelChunk::set_liquid_mesher(int index, const Ref<VoxelMesher> &mesher) {
|
|
|
|
ERR_FAIL_INDEX(index, _liquid_meshers.size());
|
|
|
|
|
|
|
|
_liquid_meshers.set(index, mesher);
|
|
|
|
}
|
|
|
|
void VoxelChunk::remove_liquid_mesher(const int index) {
|
|
|
|
ERR_FAIL_INDEX(index, _liquid_meshers.size());
|
|
|
|
|
|
|
|
_liquid_meshers.remove(index);
|
|
|
|
}
|
|
|
|
void VoxelChunk::add_liquid_mesher(const Ref<VoxelMesher> &mesher) {
|
|
|
|
_liquid_meshers.push_back(mesher);
|
|
|
|
}
|
|
|
|
int VoxelChunk::get_liquid_mesher_count() const {
|
|
|
|
return _liquid_meshers.size();
|
|
|
|
}
|
|
|
|
|
2019-11-18 19:43:15 +01:00
|
|
|
//Voxel Data
|
2019-11-18 23:50:06 +01:00
|
|
|
void VoxelChunk::setup_channels() {
|
2020-03-12 23:23:38 +01:00
|
|
|
ERR_FAIL_COND_MSG(!has_method("_setup_channels"), "VoxelChunk: _setup_channels() is missing! Please implement it!");
|
|
|
|
|
2019-11-18 23:50:06 +01:00
|
|
|
call("_setup_channels");
|
|
|
|
}
|
|
|
|
|
2020-04-16 17:10:04 +02:00
|
|
|
void VoxelChunk::set_size(const int size_x, const int size_y, const int size_z, const int margin_start, const int margin_end) {
|
2019-11-18 23:50:06 +01:00
|
|
|
if (_size_x == size_x && _size_y == size_y && _size_z == size_z && _margin_start == margin_start && _margin_end == margin_end) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < _channels.size(); ++i) {
|
2020-01-09 04:29:05 +01:00
|
|
|
uint8_t *ch = _channels[i];
|
2019-11-18 19:43:15 +01:00
|
|
|
|
2019-11-18 23:50:06 +01:00
|
|
|
if (ch != NULL) {
|
|
|
|
memdelete_arr(ch);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-19 00:54:28 +01:00
|
|
|
setup_channels();
|
|
|
|
|
2019-11-18 23:50:06 +01:00
|
|
|
_size_x = size_x;
|
|
|
|
_size_y = size_y;
|
|
|
|
_size_z = size_z;
|
|
|
|
|
|
|
|
_data_size_x = size_x + margin_start + margin_end;
|
|
|
|
_data_size_y = size_y + margin_start + margin_end;
|
|
|
|
_data_size_z = size_z + margin_start + margin_end;
|
|
|
|
|
|
|
|
_margin_start = margin_start;
|
|
|
|
_margin_end = margin_end;
|
2019-11-18 19:43:15 +01:00
|
|
|
}
|
|
|
|
|
2020-04-16 17:10:04 +02:00
|
|
|
bool VoxelChunk::validate_channel_data_position(const int x, const int y, const int z) const {
|
2019-11-18 23:50:06 +01:00
|
|
|
return x < _data_size_x && y < _data_size_y && z < _data_size_z;
|
2019-11-18 19:43:15 +01:00
|
|
|
}
|
|
|
|
|
2020-04-16 17:10:04 +02:00
|
|
|
uint8_t VoxelChunk::get_voxel(const int p_x, const int p_y, const int p_z, const int p_channel_index) const {
|
2020-02-14 03:19:15 +01:00
|
|
|
int x = p_x + _margin_start;
|
|
|
|
int y = p_y + _margin_start;
|
|
|
|
int z = p_z + _margin_start;
|
2019-11-18 23:50:06 +01:00
|
|
|
|
2020-02-14 03:19:15 +01:00
|
|
|
ERR_FAIL_INDEX_V(p_channel_index, _channels.size(), 0);
|
|
|
|
ERR_FAIL_COND_V_MSG(!validate_channel_data_position(x, y, z), 0, "Error, index out of range! " + String::num(x) + " " + String::num(y) + " " + String::num(z));
|
|
|
|
|
|
|
|
uint8_t *ch = _channels.get(p_channel_index);
|
2019-11-18 23:50:06 +01:00
|
|
|
|
|
|
|
if (!ch)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return ch[get_data_index(x, y, z)];
|
2019-11-18 19:43:15 +01:00
|
|
|
}
|
2020-04-16 17:10:04 +02:00
|
|
|
void VoxelChunk::set_voxel(const uint8_t p_value, const int p_x, const int p_y, const int p_z, const int p_channel_index) {
|
2020-02-14 03:19:15 +01:00
|
|
|
int x = p_x + _margin_start;
|
|
|
|
int y = p_y + _margin_start;
|
|
|
|
int z = p_z + _margin_start;
|
|
|
|
|
|
|
|
ERR_FAIL_INDEX(p_channel_index, _channels.size());
|
|
|
|
ERR_FAIL_COND_MSG(!validate_channel_data_position(x, y, z), "Error, index out of range! " + String::num(x) + " " + String::num(y) + " " + String::num(z));
|
2019-11-18 23:50:06 +01:00
|
|
|
|
2020-02-14 03:19:15 +01:00
|
|
|
uint8_t *ch = get_valid_channel(p_channel_index);
|
2019-11-18 19:43:15 +01:00
|
|
|
|
2020-02-14 03:19:15 +01:00
|
|
|
ch[get_data_index(x, y, z)] = p_value;
|
2019-11-18 19:43:15 +01:00
|
|
|
}
|
|
|
|
|
2020-04-16 17:10:04 +02:00
|
|
|
int VoxelChunk::get_channel_count() const {
|
2020-02-26 01:08:18 +01:00
|
|
|
return _channels.size();
|
|
|
|
}
|
|
|
|
|
2020-04-16 17:10:04 +02:00
|
|
|
void VoxelChunk::set_channel_count(const int count) {
|
2019-11-18 23:50:06 +01:00
|
|
|
if (count == _channels.size())
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (_channels.size() >= count) {
|
|
|
|
for (int i = count; i < _channels.size(); ++i) {
|
2020-01-09 04:29:05 +01:00
|
|
|
uint8_t *ch = _channels[i];
|
2019-11-18 23:50:06 +01:00
|
|
|
|
|
|
|
if (ch != NULL) {
|
|
|
|
memdelete_arr(ch);
|
|
|
|
}
|
|
|
|
}
|
2019-11-18 19:43:15 +01:00
|
|
|
|
2019-11-18 23:50:06 +01:00
|
|
|
_channels.resize(count);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
int s = _channels.size();
|
|
|
|
_channels.resize(count);
|
|
|
|
|
|
|
|
for (int i = s; i < count; ++i) {
|
|
|
|
_channels.set(i, NULL);
|
|
|
|
}
|
2019-11-18 19:43:15 +01:00
|
|
|
}
|
2020-04-16 17:10:04 +02:00
|
|
|
void VoxelChunk::allocate_channel(const int channel_index, const uint8_t default_value) {
|
2019-11-18 23:50:06 +01:00
|
|
|
ERR_FAIL_INDEX(channel_index, _channels.size());
|
2020-01-09 04:29:05 +01:00
|
|
|
|
2019-11-18 23:50:06 +01:00
|
|
|
if (_channels[channel_index] != NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
uint32_t size = _data_size_x * _data_size_y * _data_size_z;
|
2020-01-09 04:29:05 +01:00
|
|
|
|
2019-11-18 23:50:06 +01:00
|
|
|
uint8_t *ch = memnew_arr(uint8_t, size);
|
|
|
|
memset(ch, default_value, size);
|
2019-11-18 19:43:15 +01:00
|
|
|
|
2019-11-18 23:50:06 +01:00
|
|
|
_channels.set(channel_index, ch);
|
2019-11-18 19:43:15 +01:00
|
|
|
}
|
2020-04-16 17:10:04 +02:00
|
|
|
void VoxelChunk::fill_channel(const uint8_t value, const int channel_index) {
|
2019-11-18 23:50:06 +01:00
|
|
|
ERR_FAIL_INDEX(channel_index, _channels.size());
|
2019-11-18 19:43:15 +01:00
|
|
|
|
2019-11-18 23:50:06 +01:00
|
|
|
uint8_t *ch = _channels.get(channel_index);
|
|
|
|
|
|
|
|
if (ch == NULL) {
|
|
|
|
allocate_channel(channel_index, value);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t size = get_data_size();
|
2020-01-09 04:29:05 +01:00
|
|
|
|
2020-02-14 19:02:31 +01:00
|
|
|
for (uint32_t i = 0; i < size; ++i) {
|
2019-11-18 23:50:06 +01:00
|
|
|
ch[i] = value;
|
|
|
|
}
|
2019-11-18 19:43:15 +01:00
|
|
|
}
|
2020-04-16 17:10:04 +02:00
|
|
|
void VoxelChunk::dealloc_channel(const int channel_index) {
|
2019-11-18 23:50:06 +01:00
|
|
|
ERR_FAIL_INDEX(channel_index, _channels.size());
|
|
|
|
|
|
|
|
uint8_t *ch = _channels.get(channel_index);
|
2019-11-18 19:43:15 +01:00
|
|
|
|
2019-11-18 23:50:06 +01:00
|
|
|
if (ch != NULL) {
|
|
|
|
memdelete_arr(ch);
|
2020-01-09 04:29:05 +01:00
|
|
|
|
2019-11-18 23:50:06 +01:00
|
|
|
_channels.set(channel_index, NULL);
|
|
|
|
}
|
2019-11-18 19:43:15 +01:00
|
|
|
}
|
|
|
|
|
2020-04-16 17:10:04 +02:00
|
|
|
uint8_t *VoxelChunk::get_channel(const int channel_index) {
|
2019-11-18 23:50:06 +01:00
|
|
|
ERR_FAIL_INDEX_V(channel_index, _channels.size(), NULL);
|
|
|
|
|
|
|
|
return _channels.get(channel_index);
|
2019-11-18 19:43:15 +01:00
|
|
|
}
|
2020-04-16 17:10:04 +02:00
|
|
|
uint8_t *VoxelChunk::get_valid_channel(const int channel_index, const uint8_t default_value) {
|
2019-11-18 23:50:06 +01:00
|
|
|
ERR_FAIL_INDEX_V(channel_index, _channels.size(), 0);
|
|
|
|
|
|
|
|
uint8_t *ch = _channels.get(channel_index);
|
|
|
|
|
|
|
|
if (ch == NULL) {
|
|
|
|
allocate_channel(channel_index, default_value);
|
|
|
|
|
|
|
|
return _channels.get(channel_index);
|
|
|
|
}
|
|
|
|
|
|
|
|
return ch;
|
|
|
|
}
|
|
|
|
|
2020-04-16 17:10:04 +02:00
|
|
|
PoolByteArray VoxelChunk::get_channel_array(const int channel_index) const {
|
2020-02-26 01:08:18 +01:00
|
|
|
PoolByteArray arr;
|
|
|
|
|
|
|
|
uint32_t size = _data_size_x * _data_size_y * _data_size_z;
|
|
|
|
|
|
|
|
if (channel_index >= _channels.size())
|
|
|
|
return arr;
|
|
|
|
|
|
|
|
uint8_t *ch = _channels.get(channel_index);
|
|
|
|
|
|
|
|
if (ch == NULL)
|
|
|
|
return arr;
|
|
|
|
|
|
|
|
arr.resize(size);
|
|
|
|
|
|
|
|
for (uint32_t i = 0; i < size; ++i) {
|
|
|
|
arr.set(i, ch[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
return arr;
|
|
|
|
}
|
2020-04-16 17:10:04 +02:00
|
|
|
void VoxelChunk::set_channel_array(const int channel_index, const PoolByteArray &array) {
|
2020-02-26 01:08:18 +01:00
|
|
|
if (array.size() == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (_channels.size() <= channel_index)
|
|
|
|
set_channel_count(channel_index + 1);
|
|
|
|
|
|
|
|
uint8_t *ch = _channels.get(channel_index);
|
|
|
|
|
|
|
|
if (ch == NULL) {
|
|
|
|
if (_channels[channel_index] != NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
ch = memnew_arr(uint8_t, array.size());
|
|
|
|
_channels.set(channel_index, ch);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int i = 0; i < array.size(); ++i) {
|
|
|
|
ch[i] = array[i];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-16 17:10:04 +02:00
|
|
|
PoolByteArray VoxelChunk::get_channel_compressed(const int channel_index) const {
|
2020-04-05 22:07:52 +02:00
|
|
|
PoolByteArray arr;
|
|
|
|
|
|
|
|
int size = _data_size_x * _data_size_y * _data_size_z;
|
|
|
|
|
|
|
|
if (channel_index >= _channels.size())
|
|
|
|
return arr;
|
|
|
|
|
|
|
|
uint8_t *ch = _channels.get(channel_index);
|
|
|
|
|
|
|
|
if (ch == NULL)
|
|
|
|
return arr;
|
|
|
|
|
|
|
|
int bound = LZ4_compressBound(size);
|
|
|
|
arr.resize(bound);
|
|
|
|
|
2020-04-10 13:55:27 +02:00
|
|
|
#if VERSION_MAJOR < 4
|
2020-04-05 22:07:52 +02:00
|
|
|
PoolByteArray::Write w = arr.write();
|
|
|
|
|
|
|
|
int ns = LZ4_compress_default(reinterpret_cast<char *>(ch), reinterpret_cast<char *>(w.ptr()), size, bound);
|
2020-04-10 13:55:27 +02:00
|
|
|
|
2020-04-05 22:07:52 +02:00
|
|
|
w.release();
|
2020-04-10 13:55:27 +02:00
|
|
|
#else
|
2020-04-09 12:34:39 +02:00
|
|
|
int ns = LZ4_compress_default(reinterpret_cast<char *>(ch), reinterpret_cast<char *>(arr.ptrw()), size, bound);
|
2020-04-10 13:55:27 +02:00
|
|
|
#endif
|
2020-04-05 22:07:52 +02:00
|
|
|
arr.resize(ns);
|
|
|
|
|
|
|
|
return arr;
|
|
|
|
}
|
2020-04-16 17:10:04 +02:00
|
|
|
void VoxelChunk::set_channel_compressed(const int channel_index, const PoolByteArray &data) {
|
2020-04-05 22:07:52 +02:00
|
|
|
if (data.size() == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
int size = _data_size_x * _data_size_y * _data_size_z;
|
|
|
|
|
|
|
|
if (_channels.size() <= channel_index)
|
|
|
|
set_channel_count(channel_index + 1);
|
|
|
|
|
|
|
|
uint8_t *ch = _channels.get(channel_index);
|
|
|
|
|
|
|
|
if (ch == NULL) {
|
|
|
|
if (_channels[channel_index] != NULL)
|
|
|
|
return;
|
|
|
|
|
|
|
|
ch = memnew_arr(uint8_t, size);
|
|
|
|
_channels.set(channel_index, ch);
|
|
|
|
}
|
|
|
|
|
|
|
|
int ds = data.size();
|
2020-04-05 22:56:40 +02:00
|
|
|
|
2020-04-10 13:55:27 +02:00
|
|
|
#if VERSION_MAJOR < 4
|
2020-04-05 22:07:52 +02:00
|
|
|
PoolByteArray::Read r = data.read();
|
|
|
|
|
|
|
|
//We are not going to write to it
|
|
|
|
uint8_t *data_arr = const_cast<uint8_t *>(r.ptr());
|
|
|
|
|
|
|
|
LZ4_decompress_safe(reinterpret_cast<char *>(data_arr), reinterpret_cast<char *>(ch), ds, size);
|
2020-04-10 13:55:27 +02:00
|
|
|
#else
|
2020-04-09 12:34:39 +02:00
|
|
|
//We are not going to write to it
|
|
|
|
uint8_t *data_arr = const_cast<uint8_t *>(data.ptr());
|
|
|
|
|
|
|
|
LZ4_decompress_safe(reinterpret_cast<char *>(data_arr), reinterpret_cast<char *>(ch), ds, size);
|
2020-04-10 13:55:27 +02:00
|
|
|
#endif
|
2020-04-05 22:07:52 +02:00
|
|
|
}
|
|
|
|
|
2020-04-07 14:40:35 +02:00
|
|
|
_FORCE_INLINE_ int VoxelChunk::get_index(const int x, const int y, const int z) const {
|
|
|
|
return (y + _margin_start) + _data_size_y * ((x + _margin_start) + _data_size_x * (z + _margin_start));
|
|
|
|
}
|
|
|
|
|
2020-04-07 14:23:20 +02:00
|
|
|
_FORCE_INLINE_ int VoxelChunk::get_data_index(const int x, const int y, const int z) const {
|
2019-11-18 23:50:06 +01:00
|
|
|
return y + _data_size_y * (x + _data_size_x * z);
|
|
|
|
}
|
|
|
|
|
2020-04-07 14:23:20 +02:00
|
|
|
_FORCE_INLINE_ int VoxelChunk::get_data_size() const {
|
2019-11-18 23:50:06 +01:00
|
|
|
return _data_size_x * _data_size_y * _data_size_z;
|
2019-11-18 19:43:15 +01:00
|
|
|
}
|
|
|
|
|
2020-01-13 00:39:55 +01:00
|
|
|
void VoxelChunk::create_meshers() {
|
2020-03-12 23:23:38 +01:00
|
|
|
ERR_FAIL_COND_MSG(!has_method("_create_meshers"), "VoxelChunk: _create_meshers() is missing! Please implement it!");
|
2020-03-06 14:22:04 +01:00
|
|
|
|
2020-03-12 23:23:38 +01:00
|
|
|
call("_create_meshers");
|
2020-02-10 23:39:57 +01:00
|
|
|
}
|
|
|
|
|
2020-03-12 23:23:38 +01:00
|
|
|
void VoxelChunk::build(const bool immediate) {
|
2020-04-22 12:33:14 +02:00
|
|
|
ERR_FAIL_COND(!ObjectDB::instance_validate(get_voxel_world()));
|
|
|
|
ERR_FAIL_COND(!get_voxel_world()->is_inside_tree());
|
|
|
|
ERR_FAIL_COND(!is_in_tree());
|
2020-03-12 23:23:38 +01:00
|
|
|
ERR_FAIL_COND_MSG(!has_method("_build"), "VoxelChunk: _build(immediate : bool) is missing! Please implement it!");
|
2019-10-10 23:51:05 +02:00
|
|
|
|
2020-03-12 23:23:38 +01:00
|
|
|
call("_build", immediate);
|
2019-06-07 01:33:41 +02:00
|
|
|
}
|
|
|
|
|
2019-07-19 23:54:56 +02:00
|
|
|
void VoxelChunk::clear() {
|
2020-03-12 23:23:38 +01:00
|
|
|
ERR_FAIL_COND_MSG(!has_method("_clear"), "VoxelChunk: _clear() is missing! Please implement it!");
|
2019-07-18 02:05:50 +02:00
|
|
|
|
2020-03-12 23:23:38 +01:00
|
|
|
call("_clear");
|
2019-06-07 01:33:41 +02:00
|
|
|
}
|
|
|
|
|
2020-03-30 14:36:49 +02:00
|
|
|
Array VoxelChunk::merge_mesh_array(Array arr) const {
|
|
|
|
ERR_FAIL_COND_V(arr.size() != VisualServer::ARRAY_MAX, arr);
|
|
|
|
|
|
|
|
PoolVector3Array verts = arr[VisualServer::ARRAY_VERTEX];
|
|
|
|
PoolVector3Array normals = arr[VisualServer::ARRAY_NORMAL];
|
|
|
|
PoolVector2Array uvs = arr[VisualServer::ARRAY_TEX_UV];
|
|
|
|
PoolColorArray colors = arr[VisualServer::ARRAY_COLOR];
|
|
|
|
PoolIntArray indices = arr[VisualServer::ARRAY_INDEX];
|
|
|
|
|
2020-04-22 12:20:33 +02:00
|
|
|
bool has_normals = normals.size() > 0;
|
|
|
|
bool has_uvs = uvs.size() > 0;
|
|
|
|
bool has_colors = colors.size() > 0;
|
|
|
|
|
2020-03-30 14:36:49 +02:00
|
|
|
int i = 0;
|
|
|
|
while (i < verts.size()) {
|
|
|
|
Vector3 v = verts[i];
|
|
|
|
|
|
|
|
Array equals;
|
|
|
|
for (int j = i + 1; j < verts.size(); ++j) {
|
|
|
|
Vector3 vc = verts[j];
|
|
|
|
|
|
|
|
if (Math::is_equal_approx(v.x, vc.x) && Math::is_equal_approx(v.y, vc.y) && Math::is_equal_approx(v.z, vc.z))
|
|
|
|
equals.push_back(j);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (int k = 0; k < equals.size(); ++k) {
|
|
|
|
int rem = equals[k];
|
|
|
|
int remk = rem - k;
|
|
|
|
|
|
|
|
verts.remove(remk);
|
2020-04-22 12:20:33 +02:00
|
|
|
|
|
|
|
if (has_normals)
|
|
|
|
normals.remove(remk);
|
|
|
|
if (has_uvs)
|
|
|
|
uvs.remove(remk);
|
|
|
|
if (has_colors)
|
|
|
|
colors.remove(remk);
|
2020-03-30 14:36:49 +02:00
|
|
|
|
|
|
|
for (int j = 0; j < indices.size(); ++j) {
|
|
|
|
int indx = indices[j];
|
|
|
|
|
|
|
|
if (indx == remk)
|
|
|
|
indices.set(j, i);
|
|
|
|
else if (indx > remk)
|
|
|
|
indices.set(j, indx - 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
++i;
|
|
|
|
}
|
|
|
|
|
|
|
|
arr[VisualServer::ARRAY_VERTEX] = verts;
|
2020-04-22 12:20:33 +02:00
|
|
|
|
|
|
|
if (has_normals)
|
|
|
|
arr[VisualServer::ARRAY_NORMAL] = normals;
|
|
|
|
if (has_uvs)
|
|
|
|
arr[VisualServer::ARRAY_TEX_UV] = uvs;
|
|
|
|
if (has_colors)
|
|
|
|
arr[VisualServer::ARRAY_COLOR] = colors;
|
|
|
|
|
2020-03-30 14:36:49 +02:00
|
|
|
arr[VisualServer::ARRAY_INDEX] = indices;
|
|
|
|
|
|
|
|
return arr;
|
|
|
|
}
|
2020-04-16 17:10:04 +02:00
|
|
|
Array VoxelChunk::bake_mesh_array_uv(Array arr, Ref<Texture> tex, const float mul_color) const {
|
2020-03-30 14:36:49 +02:00
|
|
|
ERR_FAIL_COND_V(arr.size() != VisualServer::ARRAY_MAX, arr);
|
|
|
|
ERR_FAIL_COND_V(!tex.is_valid(), arr);
|
|
|
|
|
|
|
|
Ref<Image> img = tex->get_data();
|
|
|
|
|
|
|
|
ERR_FAIL_COND_V(!img.is_valid(), arr);
|
|
|
|
|
|
|
|
Vector2 imgsize = img->get_size();
|
|
|
|
|
|
|
|
PoolVector2Array uvs = arr[VisualServer::ARRAY_TEX_UV];
|
|
|
|
PoolColorArray colors = arr[VisualServer::ARRAY_COLOR];
|
|
|
|
|
2020-04-22 12:20:33 +02:00
|
|
|
if (colors.size() < uvs.size())
|
|
|
|
colors.resize(uvs.size());
|
|
|
|
|
2020-04-10 13:55:27 +02:00
|
|
|
#if VERSION_MAJOR < 4
|
2020-03-30 14:36:49 +02:00
|
|
|
img->lock();
|
2020-04-10 13:55:27 +02:00
|
|
|
#endif
|
2020-03-30 14:36:49 +02:00
|
|
|
|
|
|
|
for (int i = 0; i < uvs.size(); ++i) {
|
|
|
|
Vector2 uv = uvs[i];
|
|
|
|
uv *= imgsize;
|
|
|
|
|
|
|
|
Color c = img->get_pixelv(uv);
|
|
|
|
|
2020-03-30 14:57:07 +02:00
|
|
|
colors.set(i, colors[i] * c * mul_color);
|
2020-03-30 14:36:49 +02:00
|
|
|
}
|
|
|
|
|
2020-04-10 13:55:27 +02:00
|
|
|
#if VERSION_MAJOR < 4
|
2020-03-30 14:36:49 +02:00
|
|
|
img->unlock();
|
2020-04-10 13:55:27 +02:00
|
|
|
#endif
|
2020-03-30 14:36:49 +02:00
|
|
|
|
|
|
|
arr[VisualServer::ARRAY_COLOR] = colors;
|
|
|
|
|
|
|
|
return arr;
|
|
|
|
}
|
|
|
|
|
2019-07-17 02:28:16 +02:00
|
|
|
void VoxelChunk::bake_lights() {
|
2020-04-15 12:41:52 +02:00
|
|
|
if (has_method("_bake_lights"))
|
|
|
|
call("_bake_lights");
|
2019-07-17 02:28:16 +02:00
|
|
|
}
|
|
|
|
void VoxelChunk::bake_light(Ref<VoxelLight> light) {
|
2020-04-15 12:41:52 +02:00
|
|
|
if (!light.is_valid())
|
|
|
|
return;
|
2019-06-07 01:33:41 +02:00
|
|
|
|
2020-04-15 12:41:52 +02:00
|
|
|
if (has_method("_bake_lights"))
|
|
|
|
call("_bake_light", light);
|
2019-06-07 01:33:41 +02:00
|
|
|
}
|
2020-03-12 23:23:38 +01:00
|
|
|
void VoxelChunk::clear_baked_lights() {
|
2020-04-15 12:41:52 +02:00
|
|
|
if (has_method("_clear_baked_lights"))
|
|
|
|
call("_clear_baked_lights");
|
2019-11-08 11:52:36 +01:00
|
|
|
}
|
|
|
|
|
2019-10-10 23:51:05 +02:00
|
|
|
void VoxelChunk::add_prop(Ref<VoxelChunkPropData> prop) {
|
2020-04-15 13:06:45 +02:00
|
|
|
ERR_FAIL_COND(!prop.is_valid());
|
|
|
|
ERR_FAIL_COND(prop->get_owner().is_valid());
|
|
|
|
|
|
|
|
prop->set_owner(Ref<VoxelChunk>(this));
|
2019-10-10 23:51:05 +02:00
|
|
|
_props.push_back(prop);
|
2019-10-14 23:59:42 +02:00
|
|
|
|
|
|
|
if (has_method("_prop_added"))
|
|
|
|
call("_prop_added", prop);
|
2019-07-19 20:54:09 +02:00
|
|
|
}
|
2019-10-10 23:51:05 +02:00
|
|
|
Ref<VoxelChunkPropData> VoxelChunk::get_prop(int index) {
|
2020-04-15 13:06:45 +02:00
|
|
|
ERR_FAIL_INDEX_V(index, _props.size(), Ref<VoxelChunkPropData>());
|
|
|
|
|
2019-10-10 23:51:05 +02:00
|
|
|
return _props.get(index);
|
2019-07-19 20:54:09 +02:00
|
|
|
}
|
2020-04-16 17:10:04 +02:00
|
|
|
int VoxelChunk::get_prop_count() const {
|
2019-10-10 23:51:05 +02:00
|
|
|
return _props.size();
|
|
|
|
}
|
2020-04-16 17:10:04 +02:00
|
|
|
void VoxelChunk::remove_prop(const int index) {
|
2020-04-15 13:06:45 +02:00
|
|
|
ERR_FAIL_INDEX(index, _props.size());
|
|
|
|
|
|
|
|
Ref<VoxelChunkPropData> prop = _props.get(index);
|
|
|
|
|
|
|
|
if (prop.is_valid())
|
|
|
|
prop->set_owner(Ref<VoxelChunk>());
|
|
|
|
|
|
|
|
_props.remove(index);
|
2019-07-18 18:56:42 +02:00
|
|
|
}
|
|
|
|
void VoxelChunk::clear_props() {
|
2020-04-15 13:06:45 +02:00
|
|
|
for (int i = 0; i < _props.size(); ++i) {
|
|
|
|
Ref<VoxelChunkPropData> prop = _props.get(i);
|
2019-07-19 23:54:56 +02:00
|
|
|
|
2020-04-15 13:06:45 +02:00
|
|
|
if (prop.is_valid())
|
|
|
|
prop->set_owner(Ref<VoxelChunk>());
|
2019-11-10 13:42:59 +01:00
|
|
|
}
|
|
|
|
|
2020-04-15 13:06:45 +02:00
|
|
|
_props.clear();
|
2019-11-10 13:42:59 +01:00
|
|
|
}
|
|
|
|
|
2020-04-02 21:28:19 +02:00
|
|
|
void VoxelChunk::enter_tree() {
|
2020-04-22 12:33:14 +02:00
|
|
|
_is_in_tree = true;
|
|
|
|
|
2020-04-02 21:28:19 +02:00
|
|
|
if (has_method("_enter_tree"))
|
|
|
|
call("_enter_tree");
|
|
|
|
}
|
|
|
|
void VoxelChunk::exit_tree() {
|
2020-04-22 12:33:14 +02:00
|
|
|
_is_in_tree = false;
|
|
|
|
|
2020-04-02 21:28:19 +02:00
|
|
|
if (has_method("_exit_tree"))
|
|
|
|
call("_exit_tree");
|
|
|
|
}
|
2020-04-16 17:10:04 +02:00
|
|
|
void VoxelChunk::process(const float delta) {
|
2020-04-02 21:28:19 +02:00
|
|
|
if (has_method("_process"))
|
|
|
|
call("_process", delta);
|
|
|
|
}
|
2020-04-16 17:10:04 +02:00
|
|
|
void VoxelChunk::physics_process(const float delta) {
|
2020-04-02 21:28:19 +02:00
|
|
|
if (has_method("_physics_process"))
|
|
|
|
call("_physics_process", delta);
|
|
|
|
}
|
|
|
|
void VoxelChunk::world_transform_changed() {
|
|
|
|
call("_world_transform_changed");
|
|
|
|
}
|
2020-04-16 17:10:04 +02:00
|
|
|
void VoxelChunk::visibility_changed(const bool visible) {
|
2020-04-02 21:28:19 +02:00
|
|
|
if (has_method("_visibility_changed"))
|
|
|
|
call("_visibility_changed", _is_visible);
|
|
|
|
}
|
2020-04-15 12:41:52 +02:00
|
|
|
void VoxelChunk::world_light_added(const Ref<VoxelLight> &light) {
|
|
|
|
if (has_method("_world_light_added"))
|
|
|
|
call("_world_light_added", light);
|
|
|
|
}
|
|
|
|
void VoxelChunk::world_light_removed(const Ref<VoxelLight> &light) {
|
|
|
|
if (has_method("_world_light_removed"))
|
|
|
|
call("_world_light_removed", light);
|
|
|
|
}
|
2020-04-02 21:28:19 +02:00
|
|
|
|
|
|
|
Transform VoxelChunk::get_transform() const {
|
|
|
|
return _transform;
|
|
|
|
}
|
|
|
|
void VoxelChunk::set_transform(const Transform &transform) {
|
|
|
|
_transform = transform;
|
|
|
|
}
|
|
|
|
|
2019-07-18 01:43:58 +02:00
|
|
|
VoxelChunk::VoxelChunk() {
|
2020-04-18 02:15:01 +02:00
|
|
|
_is_build_threaded = false;
|
2020-04-02 21:28:19 +02:00
|
|
|
_is_processing = false;
|
|
|
|
_is_phisics_processing = false;
|
2020-04-22 12:33:14 +02:00
|
|
|
_is_in_tree = false;
|
2020-04-02 21:28:19 +02:00
|
|
|
|
|
|
|
_is_visible = true;
|
|
|
|
|
2019-11-19 14:42:21 +01:00
|
|
|
_is_generating = false;
|
2019-11-10 03:10:42 +01:00
|
|
|
_dirty = false;
|
|
|
|
_state = VOXEL_CHUNK_STATE_OK;
|
|
|
|
|
2019-07-18 01:43:58 +02:00
|
|
|
_voxel_scale = 1;
|
|
|
|
|
2019-07-18 02:05:50 +02:00
|
|
|
_voxel_world = NULL;
|
2019-11-18 19:22:11 +01:00
|
|
|
|
2020-02-26 01:08:18 +01:00
|
|
|
_position_x = 0;
|
|
|
|
_position_y = 0;
|
|
|
|
_position_z = 0;
|
|
|
|
|
|
|
|
_size_x = 0;
|
|
|
|
_size_y = 0;
|
|
|
|
_size_z = 0;
|
|
|
|
|
|
|
|
_data_size_x = 0;
|
|
|
|
_data_size_y = 0;
|
|
|
|
_data_size_z = 0;
|
|
|
|
|
2019-11-18 19:22:11 +01:00
|
|
|
_margin_start = 0;
|
|
|
|
_margin_end = 0;
|
2019-07-18 01:43:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
VoxelChunk::~VoxelChunk() {
|
2020-01-13 00:39:55 +01:00
|
|
|
_meshers.clear();
|
2019-07-18 01:43:58 +02:00
|
|
|
|
|
|
|
if (_library.is_valid()) {
|
|
|
|
_library.unref();
|
|
|
|
}
|
2019-10-10 23:51:05 +02:00
|
|
|
|
2020-04-15 13:06:45 +02:00
|
|
|
clear_props();
|
2019-11-18 23:50:06 +01:00
|
|
|
|
|
|
|
for (int i = 0; i < _channels.size(); ++i) {
|
2020-01-09 04:29:05 +01:00
|
|
|
uint8_t *ch = _channels[i];
|
2019-11-18 23:50:06 +01:00
|
|
|
|
|
|
|
if (ch != NULL) {
|
|
|
|
memdelete_arr(ch);
|
|
|
|
}
|
|
|
|
}
|
2020-02-12 14:16:31 +01:00
|
|
|
}
|
|
|
|
|
2020-04-02 21:28:19 +02:00
|
|
|
void VoxelChunk::_world_transform_changed() {
|
|
|
|
Transform wt;
|
|
|
|
|
|
|
|
if (_voxel_world != NULL) {
|
|
|
|
wt = _voxel_world->get_transform();
|
|
|
|
}
|
|
|
|
|
|
|
|
set_transform(wt * Transform(Basis(), Vector3(_position_x * static_cast<int>(_size_x) * _voxel_scale, _position_y * static_cast<int>(_size_y) * _voxel_scale, _position_z * static_cast<int>(_size_z) * _voxel_scale)));
|
|
|
|
}
|
|
|
|
|
2020-03-31 12:42:22 +02:00
|
|
|
/*
|
2020-02-26 01:08:18 +01:00
|
|
|
bool VoxelChunk::_set(const StringName &p_name, const Variant &p_value) {
|
|
|
|
String name = p_name;
|
|
|
|
|
|
|
|
if (name.begins_with("channels/")) {
|
|
|
|
|
|
|
|
int index = name.get_slicec('/', 1).to_int();
|
|
|
|
|
|
|
|
if (_channels.size() <= index) {
|
|
|
|
set_channel_count(index);
|
|
|
|
}
|
|
|
|
|
|
|
|
PoolByteArray arr = p_value;
|
|
|
|
|
|
|
|
if (arr.size() == 0)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
set_channel_array(index, arr);
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool VoxelChunk::_get(const StringName &p_name, Variant &r_ret) const {
|
|
|
|
String name = p_name;
|
|
|
|
|
|
|
|
if (name.begins_with("channels/")) {
|
|
|
|
|
|
|
|
int index = name.get_slicec('/', 1).to_int();
|
|
|
|
|
|
|
|
r_ret = get_channel_array(index);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void VoxelChunk::_get_property_list(List<PropertyInfo> *p_list) const {
|
|
|
|
for (int i = 0; i < _channels.size(); ++i) {
|
2020-02-26 12:22:46 +01:00
|
|
|
p_list->push_back(PropertyInfo(Variant::POOL_BYTE_ARRAY, "channels/" + String::num(i), PROPERTY_HINT_NONE, "", PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_INTERNAL));
|
2020-02-26 01:08:18 +01:00
|
|
|
}
|
|
|
|
}
|
2020-03-31 12:42:22 +02:00
|
|
|
*/
|
2020-02-26 01:08:18 +01:00
|
|
|
|
2019-06-07 01:33:41 +02:00
|
|
|
void VoxelChunk::_bind_methods() {
|
2019-10-10 23:51:05 +02:00
|
|
|
ADD_SIGNAL(MethodInfo("mesh_generation_finished", PropertyInfo(Variant::OBJECT, "chunk", PROPERTY_HINT_RESOURCE_TYPE, "VoxelChunk")));
|
|
|
|
|
2019-10-14 23:59:42 +02:00
|
|
|
BIND_VMETHOD(MethodInfo("_prop_added", PropertyInfo(Variant::OBJECT, "prop", PROPERTY_HINT_RESOURCE_TYPE, "VoxelChunkPropData")));
|
2020-02-12 14:16:31 +01:00
|
|
|
BIND_VMETHOD(MethodInfo("_create_meshers"));
|
2020-03-12 23:23:38 +01:00
|
|
|
BIND_VMETHOD(MethodInfo("_setup_channels"));
|
2020-04-15 12:41:52 +02:00
|
|
|
|
|
|
|
BIND_VMETHOD(MethodInfo("_bake_lights"));
|
|
|
|
BIND_VMETHOD(MethodInfo("_bake_light", PropertyInfo(Variant::OBJECT, "light", PROPERTY_HINT_RESOURCE_TYPE, "VoxelLight")));
|
|
|
|
BIND_VMETHOD(MethodInfo("_clear_baked_lights"));
|
|
|
|
|
|
|
|
ClassDB::bind_method(D_METHOD("bake_lights"), &VoxelChunk::bake_lights);
|
|
|
|
ClassDB::bind_method(D_METHOD("bake_light", "light"), &VoxelChunk::bake_light);
|
|
|
|
ClassDB::bind_method(D_METHOD("clear_baked_lights"), &VoxelChunk::clear_baked_lights);
|
2019-06-07 01:33:41 +02:00
|
|
|
|
2020-04-02 21:28:19 +02:00
|
|
|
BIND_VMETHOD(MethodInfo("_enter_tree"));
|
|
|
|
BIND_VMETHOD(MethodInfo("_exit_tree"));
|
|
|
|
BIND_VMETHOD(MethodInfo("_process", PropertyInfo(Variant::REAL, "delta")));
|
|
|
|
BIND_VMETHOD(MethodInfo("_physics_process", PropertyInfo(Variant::REAL, "delta")));
|
|
|
|
BIND_VMETHOD(MethodInfo("_world_transform_changed"));
|
|
|
|
BIND_VMETHOD(MethodInfo("_visibility_changed", PropertyInfo(Variant::BOOL, "visible")));
|
2020-04-15 12:41:52 +02:00
|
|
|
BIND_VMETHOD(MethodInfo("_world_light_added", PropertyInfo(Variant::OBJECT, "light", PROPERTY_HINT_RESOURCE_TYPE, "VoxelLight")));
|
|
|
|
BIND_VMETHOD(MethodInfo("_world_light_removed", PropertyInfo(Variant::OBJECT, "light", PROPERTY_HINT_RESOURCE_TYPE, "VoxelLight")));
|
|
|
|
|
|
|
|
ClassDB::bind_method(D_METHOD("enter_tree"), &VoxelChunk::enter_tree);
|
|
|
|
ClassDB::bind_method(D_METHOD("exit_tree"), &VoxelChunk::exit_tree);
|
|
|
|
ClassDB::bind_method(D_METHOD("process", "delta"), &VoxelChunk::process);
|
|
|
|
ClassDB::bind_method(D_METHOD("physics_process", "delta"), &VoxelChunk::physics_process);
|
|
|
|
ClassDB::bind_method(D_METHOD("world_transform_changed"), &VoxelChunk::world_transform_changed);
|
2020-04-02 21:28:19 +02:00
|
|
|
ClassDB::bind_method(D_METHOD("visibility_changed", "visible"), &VoxelChunk::visibility_changed);
|
2020-04-15 12:41:52 +02:00
|
|
|
ClassDB::bind_method(D_METHOD("world_light_added", "light"), &VoxelChunk::world_light_added);
|
|
|
|
ClassDB::bind_method(D_METHOD("world_light_removed", "light"), &VoxelChunk::world_light_removed);
|
2020-04-02 21:28:19 +02:00
|
|
|
|
|
|
|
ClassDB::bind_method(D_METHOD("get_process"), &VoxelChunk::get_process);
|
|
|
|
ClassDB::bind_method(D_METHOD("set_process", "value"), &VoxelChunk::set_process);
|
|
|
|
|
|
|
|
ClassDB::bind_method(D_METHOD("get_physics_process"), &VoxelChunk::get_physics_process);
|
|
|
|
ClassDB::bind_method(D_METHOD("set_physics_process", "value"), &VoxelChunk::set_physics_process);
|
|
|
|
|
2020-04-22 12:33:14 +02:00
|
|
|
ClassDB::bind_method(D_METHOD("is_in_tree"), &VoxelChunk::is_in_tree);
|
|
|
|
|
2020-04-18 02:15:01 +02:00
|
|
|
ClassDB::bind_method(D_METHOD("get_is_build_threaded"), &VoxelChunk::get_is_build_threaded);
|
|
|
|
ClassDB::bind_method(D_METHOD("set_is_build_threaded", "value"), &VoxelChunk::set_is_build_threaded);
|
2020-04-22 12:26:53 +02:00
|
|
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "is_build_threaded", PROPERTY_HINT_NONE, "", 0), "set_is_build_threaded", "get_is_build_threaded");
|
2020-04-18 02:15:01 +02:00
|
|
|
|
2020-04-02 21:28:19 +02:00
|
|
|
ClassDB::bind_method(D_METHOD("get_transform"), &VoxelChunk::get_transform);
|
|
|
|
ClassDB::bind_method(D_METHOD("set_transform", "value"), &VoxelChunk::set_transform);
|
|
|
|
ADD_PROPERTY(PropertyInfo(Variant::TRANSFORM, "transform"), "set_transform", "get_transform");
|
|
|
|
|
|
|
|
ClassDB::bind_method(D_METHOD("get_visible"), &VoxelChunk::get_visible);
|
|
|
|
ClassDB::bind_method(D_METHOD("set_visible", "value"), &VoxelChunk::set_visible);
|
|
|
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "visible"), "set_visible", "get_visible");
|
|
|
|
|
2019-11-19 14:42:21 +01:00
|
|
|
ClassDB::bind_method(D_METHOD("get_is_generating"), &VoxelChunk::get_is_generating);
|
|
|
|
ClassDB::bind_method(D_METHOD("set_is_generating", "value"), &VoxelChunk::set_is_generating);
|
2020-04-22 12:26:53 +02:00
|
|
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "is_generating", PROPERTY_HINT_NONE, "", 0), "set_is_generating", "get_is_generating");
|
2019-11-19 14:42:21 +01:00
|
|
|
|
2019-11-10 03:10:42 +01:00
|
|
|
ClassDB::bind_method(D_METHOD("get_dirty"), &VoxelChunk::get_dirty);
|
|
|
|
ClassDB::bind_method(D_METHOD("set_dirty", "value"), &VoxelChunk::set_dirty);
|
2020-04-22 12:26:53 +02:00
|
|
|
ADD_PROPERTY(PropertyInfo(Variant::BOOL, "dirty", PROPERTY_HINT_NONE, "", 0), "set_dirty", "get_dirty");
|
2019-11-10 03:10:42 +01:00
|
|
|
|
|
|
|
ClassDB::bind_method(D_METHOD("get_state"), &VoxelChunk::get_state);
|
|
|
|
ClassDB::bind_method(D_METHOD("set_state", "value"), &VoxelChunk::set_state);
|
2020-04-22 12:26:53 +02:00
|
|
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "state", PROPERTY_HINT_NONE, "", 0), "set_state", "get_state");
|
2019-11-10 03:10:42 +01:00
|
|
|
|
2019-11-18 20:16:29 +01:00
|
|
|
ClassDB::bind_method(D_METHOD("get_position_x"), &VoxelChunk::get_position_x);
|
2019-11-18 22:22:41 +01:00
|
|
|
ClassDB::bind_method(D_METHOD("set_position_x", "value"), &VoxelChunk::set_position_x);
|
|
|
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "position_x"), "set_position_x", "get_position_x");
|
2019-07-17 02:28:16 +02:00
|
|
|
|
2019-11-18 20:16:29 +01:00
|
|
|
ClassDB::bind_method(D_METHOD("get_position_y"), &VoxelChunk::get_position_y);
|
2019-11-18 22:22:41 +01:00
|
|
|
ClassDB::bind_method(D_METHOD("set_position_y", "value"), &VoxelChunk::set_position_y);
|
|
|
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "position_y"), "set_position_y", "get_position_y");
|
2019-07-17 02:28:16 +02:00
|
|
|
|
2019-11-18 20:16:29 +01:00
|
|
|
ClassDB::bind_method(D_METHOD("get_position_z"), &VoxelChunk::get_position_z);
|
2019-11-18 22:22:41 +01:00
|
|
|
ClassDB::bind_method(D_METHOD("set_position_z", "value"), &VoxelChunk::set_position_z);
|
|
|
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "position_z"), "set_position_z", "get_position_z");
|
2019-07-17 02:28:16 +02:00
|
|
|
|
2019-11-18 20:16:29 +01:00
|
|
|
ClassDB::bind_method(D_METHOD("get_size_x"), &VoxelChunk::get_size_x);
|
2020-02-26 01:08:18 +01:00
|
|
|
ClassDB::bind_method(D_METHOD("set_size_x"), &VoxelChunk::set_size_x);
|
|
|
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "size_x"), "set_size_x", "get_size_x");
|
2019-07-17 02:28:16 +02:00
|
|
|
|
2019-11-18 20:16:29 +01:00
|
|
|
ClassDB::bind_method(D_METHOD("get_size_y"), &VoxelChunk::get_size_y);
|
2020-02-26 01:08:18 +01:00
|
|
|
ClassDB::bind_method(D_METHOD("set_size_y"), &VoxelChunk::set_size_y);
|
|
|
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "size_y"), "set_size_y", "get_size_y");
|
2019-07-17 02:28:16 +02:00
|
|
|
|
2019-11-18 20:16:29 +01:00
|
|
|
ClassDB::bind_method(D_METHOD("get_size_z"), &VoxelChunk::get_size_z);
|
2020-02-26 01:08:18 +01:00
|
|
|
ClassDB::bind_method(D_METHOD("set_size_z"), &VoxelChunk::set_size_z);
|
|
|
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "size_z"), "set_size_z", "get_size_z");
|
2019-07-17 02:28:16 +02:00
|
|
|
|
2019-11-19 00:54:28 +01:00
|
|
|
ClassDB::bind_method(D_METHOD("get_data_size_x"), &VoxelChunk::get_data_size_x);
|
2020-02-26 01:08:18 +01:00
|
|
|
ClassDB::bind_method(D_METHOD("set_data_size_x"), &VoxelChunk::set_data_size_x);
|
|
|
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "data_size_x"), "set_data_size_x", "get_data_size_x");
|
2019-11-19 00:54:28 +01:00
|
|
|
|
|
|
|
ClassDB::bind_method(D_METHOD("get_data_size_y"), &VoxelChunk::get_data_size_y);
|
2020-02-26 01:08:18 +01:00
|
|
|
ClassDB::bind_method(D_METHOD("set_data_size_y"), &VoxelChunk::set_data_size_y);
|
|
|
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "data_size_y"), "set_data_size_y", "get_data_size_y");
|
2019-11-19 00:54:28 +01:00
|
|
|
|
|
|
|
ClassDB::bind_method(D_METHOD("get_data_size_z"), &VoxelChunk::get_data_size_z);
|
2020-02-26 01:08:18 +01:00
|
|
|
ClassDB::bind_method(D_METHOD("set_data_size_z"), &VoxelChunk::set_data_size_z);
|
|
|
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "data_size_z"), "set_data_size_z", "get_data_size_z");
|
2019-11-19 00:54:28 +01:00
|
|
|
|
|
|
|
ClassDB::bind_method(D_METHOD("get_position"), &VoxelChunk::get_position);
|
|
|
|
ClassDB::bind_method(D_METHOD("set_position", "x", "y", "z"), &VoxelChunk::set_position);
|
|
|
|
|
|
|
|
ClassDB::bind_method(D_METHOD("get_margin_start"), &VoxelChunk::get_margin_start);
|
2020-02-26 01:08:18 +01:00
|
|
|
ClassDB::bind_method(D_METHOD("set_margin_start"), &VoxelChunk::set_margin_start);
|
|
|
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "margin_start"), "set_margin_start", "get_margin_start");
|
|
|
|
|
2019-11-19 00:54:28 +01:00
|
|
|
ClassDB::bind_method(D_METHOD("get_margin_end"), &VoxelChunk::get_margin_end);
|
2020-02-26 01:08:18 +01:00
|
|
|
ClassDB::bind_method(D_METHOD("set_margin_end"), &VoxelChunk::set_margin_end);
|
|
|
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "margin_end"), "set_margin_end", "get_margin_end");
|
2019-11-19 00:54:28 +01:00
|
|
|
|
2019-06-07 01:33:41 +02:00
|
|
|
ClassDB::bind_method(D_METHOD("get_library"), &VoxelChunk::get_library);
|
|
|
|
ClassDB::bind_method(D_METHOD("set_library", "value"), &VoxelChunk::set_library);
|
|
|
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "library", PROPERTY_HINT_RESOURCE_TYPE, "VoxelmanLibrary"), "set_library", "get_library");
|
|
|
|
|
|
|
|
ClassDB::bind_method(D_METHOD("get_voxel_scale"), &VoxelChunk::get_voxel_scale);
|
|
|
|
ClassDB::bind_method(D_METHOD("set_voxel_scale", "value"), &VoxelChunk::set_voxel_scale);
|
|
|
|
ADD_PROPERTY(PropertyInfo(Variant::REAL, "voxel_scale"), "set_voxel_scale", "get_voxel_scale");
|
|
|
|
|
2020-01-13 00:39:55 +01:00
|
|
|
ClassDB::bind_method(D_METHOD("get_mesher", "index"), &VoxelChunk::get_mesher);
|
|
|
|
ClassDB::bind_method(D_METHOD("set_mesher", "index", "mesher"), &VoxelChunk::set_mesher);
|
|
|
|
ClassDB::bind_method(D_METHOD("remove_mesher", "index"), &VoxelChunk::remove_mesher);
|
|
|
|
ClassDB::bind_method(D_METHOD("add_mesher", "mesher"), &VoxelChunk::add_mesher);
|
|
|
|
ClassDB::bind_method(D_METHOD("get_mesher_count"), &VoxelChunk::get_mesher_count);
|
2019-06-07 01:33:41 +02:00
|
|
|
|
2019-07-18 02:05:50 +02:00
|
|
|
ClassDB::bind_method(D_METHOD("get_voxel_world"), &VoxelChunk::get_voxel_world);
|
|
|
|
ClassDB::bind_method(D_METHOD("set_voxel_world", "world"), &VoxelChunk::set_voxel_world_bind);
|
2020-04-02 21:38:19 +02:00
|
|
|
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "voxel_world", PROPERTY_HINT_RESOURCE_TYPE, "VoxelWorld", 0), "set_voxel_world", "get_voxel_world");
|
2019-07-18 02:05:50 +02:00
|
|
|
|
2019-11-18 23:50:06 +01:00
|
|
|
//Voxel Data
|
|
|
|
ClassDB::bind_method(D_METHOD("setup_channels"), &VoxelChunk::setup_channels);
|
|
|
|
|
|
|
|
ClassDB::bind_method(D_METHOD("set_size", "size_x", "size_y", "size_z", "margin_start", "margin_end"), &VoxelChunk::set_size, DEFVAL(0), DEFVAL(0));
|
|
|
|
|
|
|
|
ClassDB::bind_method(D_METHOD("validate_channel_data_position", "x", "y", "z"), &VoxelChunk::validate_channel_data_position);
|
|
|
|
|
|
|
|
ClassDB::bind_method(D_METHOD("get_voxel", "x", "y", "z", "channel_index"), &VoxelChunk::get_voxel);
|
|
|
|
ClassDB::bind_method(D_METHOD("set_voxel", "value", "x", "y", "z", "channel_index"), &VoxelChunk::set_voxel);
|
|
|
|
|
2020-02-26 01:08:18 +01:00
|
|
|
ClassDB::bind_method(D_METHOD("get_channel_count"), &VoxelChunk::get_channel_count);
|
2019-11-18 23:50:06 +01:00
|
|
|
ClassDB::bind_method(D_METHOD("set_channel_count", "count"), &VoxelChunk::set_channel_count);
|
2020-02-26 01:08:18 +01:00
|
|
|
ADD_PROPERTY(PropertyInfo(Variant::INT, "channel_count"), "set_channel_count", "get_channel_count");
|
|
|
|
|
2019-11-18 23:50:06 +01:00
|
|
|
ClassDB::bind_method(D_METHOD("allocate_channel", "channel_index", "default_value"), &VoxelChunk::allocate_channel);
|
|
|
|
ClassDB::bind_method(D_METHOD("fill_channel", "value", "channel_index"), &VoxelChunk::fill_channel);
|
|
|
|
ClassDB::bind_method(D_METHOD("dealloc_channel", "channel_index"), &VoxelChunk::dealloc_channel);
|
|
|
|
|
2020-02-26 01:08:18 +01:00
|
|
|
ClassDB::bind_method(D_METHOD("get_channel_array", "channel_index"), &VoxelChunk::get_channel_array);
|
|
|
|
ClassDB::bind_method(D_METHOD("set_channel_array", "channel_index", "array"), &VoxelChunk::set_channel_array);
|
|
|
|
|
2020-04-05 22:07:52 +02:00
|
|
|
ClassDB::bind_method(D_METHOD("get_channel_compressed", "channel_index"), &VoxelChunk::get_channel_compressed);
|
|
|
|
ClassDB::bind_method(D_METHOD("set_channel_compressed", "channel_index", "array"), &VoxelChunk::set_channel_compressed);
|
|
|
|
|
2020-04-07 14:40:35 +02:00
|
|
|
ClassDB::bind_method(D_METHOD("get_index", "x", "y", "z"), &VoxelChunk::get_index);
|
2019-11-18 23:50:06 +01:00
|
|
|
ClassDB::bind_method(D_METHOD("get_data_index", "x", "y", "z"), &VoxelChunk::get_data_index);
|
|
|
|
ClassDB::bind_method(D_METHOD("get_data_size"), &VoxelChunk::get_data_size);
|
|
|
|
|
2020-03-30 14:36:49 +02:00
|
|
|
ClassDB::bind_method(D_METHOD("merge_mesh_array", "arr"), &VoxelChunk::merge_mesh_array);
|
|
|
|
ClassDB::bind_method(D_METHOD("bake_mesh_array_uv", "arr", "tex", "mul_color"), &VoxelChunk::bake_mesh_array_uv, DEFVAL(0.7));
|
|
|
|
|
2019-11-18 23:50:06 +01:00
|
|
|
//Meshes
|
2019-07-17 02:28:16 +02:00
|
|
|
|
2019-10-10 23:51:05 +02:00
|
|
|
ClassDB::bind_method(D_METHOD("add_prop", "prop"), &VoxelChunk::add_prop);
|
|
|
|
ClassDB::bind_method(D_METHOD("get_prop", "index"), &VoxelChunk::get_prop);
|
|
|
|
ClassDB::bind_method(D_METHOD("get_prop_count"), &VoxelChunk::get_prop_count);
|
|
|
|
ClassDB::bind_method(D_METHOD("remove_prop", "index"), &VoxelChunk::remove_prop);
|
2019-07-19 23:54:56 +02:00
|
|
|
ClassDB::bind_method(D_METHOD("clear_props"), &VoxelChunk::clear_props);
|
2019-07-18 18:56:42 +02:00
|
|
|
|
2020-01-13 00:39:55 +01:00
|
|
|
ClassDB::bind_method(D_METHOD("create_meshers"), &VoxelChunk::create_meshers);
|
2020-04-02 21:28:19 +02:00
|
|
|
|
|
|
|
ClassDB::bind_method(D_METHOD("_world_transform_changed"), &VoxelChunk::_world_transform_changed);
|
2019-06-07 01:33:41 +02:00
|
|
|
}
|