VoxelLibrary can contain up to 65536 voxel types

master
Marc Gilleron 2020-01-18 20:43:34 +00:00
parent 1e1385c86c
commit 45a34676b3
2 changed files with 53 additions and 33 deletions

View File

@ -14,16 +14,22 @@ VoxelLibrary::~VoxelLibrary() {
// }
}
int VoxelLibrary::get_voxel_count() const {
int count = 0;
for (unsigned int i = 0; i < MAX_VOXEL_TYPES; ++i) {
if (_voxel_types[i].is_valid())
++count;
unsigned int VoxelLibrary::get_voxel_count() const {
return _voxel_types.size();
}
void VoxelLibrary::set_voxel_count(unsigned int type_count) {
ERR_FAIL_COND(type_count > MAX_VOXEL_TYPES);
if (type_count == _voxel_types.size()) {
return;
}
return count;
// Note: a smaller size may cause a loss of data
_voxel_types.resize(type_count);
_change_notify();
}
void VoxelLibrary::load_default() {
set_voxel_count(2);
create_voxel(0, "air")->set_transparent(true);
create_voxel(1, "solid")
->set_transparent(false)
@ -47,17 +53,23 @@ bool VoxelLibrary::_set(const StringName &p_name, const Variant &p_value) {
if (p_name.operator String().begins_with("voxels/")) {
unsigned int idx = p_name.operator String().get_slicec('/', 1).to_int();
if (idx >= 0 && idx < MAX_VOXEL_TYPES) {
Ref<Voxel> voxel = p_value;
_voxel_types[idx] = voxel;
if (voxel.is_valid()) {
voxel->set_library(Ref<VoxelLibrary>(this));
voxel->set_id(idx);
}
// Note: if the voxel is set to null, we could set the previous one's library reference to null.
// however it Voxels use a weak reference, so it's not really needed
return true;
ERR_FAIL_INDEX_V(idx, MAX_VOXEL_TYPES, false);
if (idx >= _voxel_types.size()) {
_voxel_types.resize(idx + 1);
}
Ref<Voxel> voxel = p_value;
_voxel_types[idx] = voxel;
if (voxel.is_valid()) {
voxel->set_library(Ref<VoxelLibrary>(this));
voxel->set_id(idx);
}
// Note: if the voxel is set to null, we could set the previous one's library reference to null.
// however Voxels use a weak reference, so it's not really needed
return true;
}
return false;
@ -74,7 +86,7 @@ bool VoxelLibrary::_get(const StringName &p_name, Variant &r_ret) const {
if (p_name.operator String().begins_with("voxels/")) {
unsigned int idx = p_name.operator String().get_slicec('/', 1).to_int();
if (idx >= 0 && idx < MAX_VOXEL_TYPES) {
if (idx < _voxel_types.size()) {
r_ret = _voxel_types[idx];
return true;
}
@ -84,11 +96,7 @@ bool VoxelLibrary::_get(const StringName &p_name, Variant &r_ret) const {
}
void VoxelLibrary::_get_property_list(List<PropertyInfo> *p_list) const {
//p_list->push_back(PropertyInfo(Variant::INT, "voxels/max"));
//for(int i = 0; i < _max_count; ++i) {
for (unsigned int i = 0; i < MAX_VOXEL_TYPES; ++i) {
for (unsigned int i = 0; i < _voxel_types.size(); ++i) {
p_list->push_back(PropertyInfo(Variant::OBJECT, "voxels/" + itos(i), PROPERTY_HINT_RESOURCE_TYPE, "Voxel"));
}
}
@ -99,7 +107,7 @@ void VoxelLibrary::set_atlas_size(int s) {
}
Ref<Voxel> VoxelLibrary::create_voxel(unsigned int id, String name) {
ERR_FAIL_COND_V(id < 0 || id >= MAX_VOXEL_TYPES, Ref<Voxel>());
ERR_FAIL_COND_V(id >= _voxel_types.size(), Ref<Voxel>());
Ref<Voxel> voxel(memnew(Voxel));
voxel->set_library(Ref<VoxelLibrary>(this));
voxel->set_id(id);
@ -108,18 +116,24 @@ Ref<Voxel> VoxelLibrary::create_voxel(unsigned int id, String name) {
return voxel;
}
Ref<Voxel> VoxelLibrary::_get_voxel_bind(unsigned int id) {
ERR_FAIL_COND_V(id < 0 || id >= MAX_VOXEL_TYPES, Ref<Voxel>());
Ref<Voxel> VoxelLibrary::_b_get_voxel(unsigned int id) {
ERR_FAIL_COND_V(id >= _voxel_types.size(), Ref<Voxel>());
return _voxel_types[id];
}
void VoxelLibrary::_bind_methods() {
ClassDB::bind_method(D_METHOD("create_voxel", "id", "name"), &VoxelLibrary::create_voxel);
ClassDB::bind_method(D_METHOD("get_voxel", "id"), &VoxelLibrary::_get_voxel_bind);
ClassDB::bind_method(D_METHOD("get_voxel", "id"), &VoxelLibrary::_b_get_voxel);
ClassDB::bind_method(D_METHOD("set_atlas_size", "square_size"), &VoxelLibrary::set_atlas_size);
ClassDB::bind_method(D_METHOD("get_atlas_size"), &VoxelLibrary::get_atlas_size);
ClassDB::bind_method(D_METHOD("set_voxel_count", "count"), &VoxelLibrary::set_voxel_count);
ClassDB::bind_method(D_METHOD("get_voxel_count"), &VoxelLibrary::get_voxel_count);
ADD_PROPERTY(PropertyInfo(Variant::INT, "atlas_size"), "set_atlas_size", "get_atlas_size");
ADD_PROPERTY(PropertyInfo(Variant::INT, "voxel_count", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR), "set_voxel_count", "get_voxel_count");
BIND_CONSTANT(MAX_VOXEL_TYPES);
}

View File

@ -8,8 +8,8 @@ class VoxelLibrary : public Resource {
GDCLASS(VoxelLibrary, Resource)
public:
// TODO Lift that limit to 65536 and use a vector to store them
static const unsigned int MAX_VOXEL_TYPES = 256; // Required limit because voxel types are stored in 8 bits
// Limit based on maximum supported by VoxelMesherBlocky
static const unsigned int MAX_VOXEL_TYPES = 65536;
VoxelLibrary();
~VoxelLibrary();
@ -20,14 +20,20 @@ public:
// Use this factory rather than creating voxels from scratch
Ref<Voxel> create_voxel(unsigned int id, String name);
int get_voxel_count() const;
unsigned int get_voxel_count() const;
void set_voxel_count(unsigned int type_count);
void load_default();
// Internal getters
_FORCE_INLINE_ bool has_voxel(int id) const { return _voxel_types[id].is_valid(); }
_FORCE_INLINE_ const Voxel &get_voxel_const(int id) const { return **_voxel_types[id]; }
_FORCE_INLINE_ bool has_voxel(unsigned int id) const {
return id < _voxel_types.size() && _voxel_types[id].is_valid();
}
_FORCE_INLINE_ const Voxel &get_voxel_const(unsigned int id) const {
return **_voxel_types[id];
}
protected:
static void _bind_methods();
@ -36,10 +42,10 @@ protected:
bool _get(const StringName &p_name, Variant &r_ret) const;
void _get_property_list(List<PropertyInfo> *p_list) const;
Ref<Voxel> _get_voxel_bind(unsigned int id);
Ref<Voxel> _b_get_voxel(unsigned int id);
private:
Ref<Voxel> _voxel_types[MAX_VOXEL_TYPES];
std::vector<Ref<Voxel> > _voxel_types;
int _atlas_size;
};