diff --git a/voxel_library.cpp b/voxel_library.cpp index 5703bd7..a3f9694 100644 --- a/voxel_library.cpp +++ b/voxel_library.cpp @@ -3,6 +3,9 @@ VoxelLibrary::VoxelLibrary() : Resource(), _atlas_size(1) { + + _voxel_editor_count = 0; + _voxel_editor_page = 0; } VoxelLibrary::~VoxelLibrary() { @@ -30,69 +33,27 @@ void VoxelLibrary::load_default() { ->set_geometry_type(Voxel::GEOMETRY_CUBE); } -// TODO Add a way to add voxels - -bool VoxelLibrary::_set(const StringName &p_name, const Variant &p_value) { - - // if(p_name == "voxels/max") { - - // int v = p_value; - // _max_count = CLAMP(v, 0, MAX_VOXEL_TYPES); - // for(int i = _max_count; i < MAX_VOXEL_TYPES; ++i) { - // _voxel_types[i] = Ref(); - // return true; - // } - - // } else - if (p_name.operator String().begins_with("voxels/")) { - - int idx = p_name.operator String().get_slicec('/', 1).to_int(); - if (idx >= 0 && idx < MAX_VOXEL_TYPES) { - Ref voxel = p_value; - _voxel_types[idx] = voxel; - if (voxel.is_valid()) { - voxel->set_library(Ref(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; - } - } - - return false; +int VoxelLibrary::get_voxel_editor_count() { + return _voxel_editor_count; } -bool VoxelLibrary::_get(const StringName &p_name, Variant &r_ret) const { - - // if(p_name == "voxels/max") { - - // r_ret = _max_count; - // return true; - - // } else - if (p_name.operator String().begins_with("voxels/")) { - - int idx = p_name.operator String().get_slicec('/', 1).to_int(); - if (idx >= 0 && idx < MAX_VOXEL_TYPES) { - r_ret = _voxel_types[idx]; - return true; - } - } - - return false; +void VoxelLibrary::set_voxel_editor_count(int value) { + _voxel_editor_count = value; } -void VoxelLibrary::_get_property_list(List *p_list) const { - - //p_list->push_back(PropertyInfo(Variant::INT, "voxels/max")); - - //for(int i = 0; i < _max_count; ++i) { - for (int i = 0; i < MAX_VOXEL_TYPES; ++i) { - p_list->push_back(PropertyInfo(Variant::OBJECT, "voxels/" + itos(i), PROPERTY_HINT_RESOURCE_TYPE, "Voxel")); - } +int VoxelLibrary::get_voxel_editor_page() { + return _voxel_editor_page; } +void VoxelLibrary::set_voxel_editor_page(int value) { + if (value < 0 || value > (int)(_voxel_editor_count / ITEMS_PER_PAGE)) { + return; + } + + _voxel_editor_page = value; +} + + void VoxelLibrary::set_atlas_size(int s) { ERR_FAIL_COND(s <= 0); _atlas_size = s; @@ -100,26 +61,85 @@ void VoxelLibrary::set_atlas_size(int s) { Ref VoxelLibrary::create_voxel(int id, String name) { ERR_FAIL_COND_V(id < 0 || id >= MAX_VOXEL_TYPES, Ref()); + Ref voxel(memnew(Voxel)); + voxel->set_library(Ref(this)); voxel->set_id(id); voxel->set_voxel_name(name); _voxel_types[id] = voxel; + return voxel; } -Ref VoxelLibrary::_get_voxel_bind(int id) { +void VoxelLibrary::add_voxel(Ref voxel) { + int index = get_voxel_count(); + + ERR_FAIL_COND(index >= MAX_VOXEL_TYPES); + + voxel->set_id(index); +} + +void VoxelLibrary::set_voxel(int id, Ref voxel) { + ERR_FAIL_COND(id < 0 || id >= MAX_VOXEL_TYPES); + + voxel->set_id(id); + + _voxel_types[id] = voxel; +} + +Ref VoxelLibrary::get_voxel(int id) { ERR_FAIL_COND_V(id < 0 || id >= MAX_VOXEL_TYPES, Ref()); + return _voxel_types[id]; } +void VoxelLibrary::remove_voxel(int id) { + ERR_FAIL_COND(id < 0 || id >= MAX_VOXEL_TYPES); + + _voxel_types[id] = Ref(NULL); +} + +void VoxelLibrary::_validate_property(PropertyInfo &property) const { + String prop = property.name; + if (prop.begins_with("Voxel_")) { + int frame = prop.get_slicec('/', 0).get_slicec('_', 1).to_int(); + if (frame >= _voxel_editor_count || frame < ITEMS_PER_PAGE * _voxel_editor_page || frame > ITEMS_PER_PAGE * (_voxel_editor_page + 1)) { + property.usage = 0; + } + } +} + 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("set_atlas_size", "square_size"), &VoxelLibrary::set_atlas_size); ClassDB::bind_method(D_METHOD("get_atlas_size"), &VoxelLibrary::get_atlas_size); ADD_PROPERTY(PropertyInfo(Variant::INT, "atlas_size"), "set_atlas_size", "get_atlas_size"); + + + ClassDB::bind_method(D_METHOD("get_voxel_editor_count"), &VoxelLibrary::get_voxel_editor_count); + ClassDB::bind_method(D_METHOD("set_voxel_editor_count", "value"), &VoxelLibrary::set_voxel_editor_count); + ADD_PROPERTY(PropertyInfo(Variant::INT, "voxel_editor_count", PROPERTY_HINT_RANGE, "0," + itos(MAX_VOXEL_TYPES), PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_voxel_editor_count", "get_voxel_editor_count"); + + ClassDB::bind_method(D_METHOD("get_voxel_editor_page"), &VoxelLibrary::get_voxel_editor_page); + ClassDB::bind_method(D_METHOD("set_voxel_editor_page", "value"), &VoxelLibrary::set_voxel_editor_page); + ADD_PROPERTY(PropertyInfo(Variant::INT, "voxel_editor_page", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED), "set_voxel_editor_page", "get_voxel_editor_page"); + + ClassDB::bind_method(D_METHOD("has_voxel", "id"), &VoxelLibrary::has_voxel); + ClassDB::bind_method(D_METHOD("add_voxel", "voxel"), &VoxelLibrary::add_voxel); + ClassDB::bind_method(D_METHOD("remove_voxel", "id"), &VoxelLibrary::set_voxel); + ClassDB::bind_method(D_METHOD("get_voxel_count"), &VoxelLibrary::get_voxel_count); + + ClassDB::bind_method(D_METHOD("get_voxel", "id"), &VoxelLibrary::get_voxel); + ClassDB::bind_method(D_METHOD("set_voxel", "id", "voxel"), &VoxelLibrary::set_voxel); + + ADD_GROUP("Voxel", "Voxel"); + for (int i = 0; i < MAX_VOXEL_TYPES; ++i) { + ADD_PROPERTYI(PropertyInfo(Variant::OBJECT, "Voxel_" + itos(i), PROPERTY_HINT_RESOURCE_TYPE, "Voxel", PROPERTY_USAGE_DEFAULT | PROPERTY_USAGE_INTERNAL), "set_voxel", "get_voxel", i); + } + + BIND_CONSTANT(MAX_VOXEL_TYPES); } diff --git a/voxel_library.h b/voxel_library.h index 4bd62cf..2c7590f 100644 --- a/voxel_library.h +++ b/voxel_library.h @@ -9,6 +9,7 @@ class VoxelLibrary : public Resource { public: static const unsigned int MAX_VOXEL_TYPES = 256; // Required limit because voxel types are stored in 8 bits + static const unsigned int ITEMS_PER_PAGE = 256; //TODO fix saving items that are not on the currently active page VoxelLibrary(); ~VoxelLibrary(); @@ -16,28 +17,34 @@ public: int get_atlas_size() const { return _atlas_size; } void set_atlas_size(int s); - // Use this factory rather than creating voxels from scratch Ref create_voxel(int id, String name); + void add_voxel(Ref voxel); + void set_voxel(int id, Ref voxel); + Ref get_voxel(int id); + void remove_voxel(int id); + int get_voxel_count() const; void load_default(); - // Internal getters + int get_voxel_editor_count(); + void set_voxel_editor_count(int value); + + int get_voxel_editor_page(); + void set_voxel_editor_page(int value); _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]; } protected: + void _validate_property(PropertyInfo &property) const; static void _bind_methods(); - bool _set(const StringName &p_name, const Variant &p_value); - bool _get(const StringName &p_name, Variant &r_ret) const; - void _get_property_list(List *p_list) const; - - Ref _get_voxel_bind(int id); - private: + int _voxel_editor_count; + int _voxel_editor_page; + Ref _voxel_types[MAX_VOXEL_TYPES]; int _atlas_size; };