#include "voxel_library.h" VoxelLibrary::VoxelLibrary() : Resource(), _atlas_size(1) { _voxel_editor_count = 0; _voxel_editor_page = 0; _atlas_rows = 8; _atlas_columns = 8; _is_textured = true; _uvs = memnew(Vector >()); //rebuild_uvs(); } VoxelLibrary::~VoxelLibrary() { // Handled with a WeakRef // for (unsigned int i = 0; i < MAX_VOXEL_TYPES; ++i) { // if (_voxel_types[i].is_valid()) { // _voxel_types[i]->set_library(NULL); // } // } _uvs->clear(); memdelete(_uvs); } int VoxelLibrary::get_voxel_count() const { int count = 0; for (int i = 0; i < MAX_VOXEL_TYPES; ++i) { if (_voxel_types[i].is_valid()) ++count; } return count; } void VoxelLibrary::load_default() { create_voxel(0, "air")->set_transparent(true); create_voxel(1, "solid") ->set_transparent(false) ->set_geometry_type(Voxel::GEOMETRY_CUBE); } int VoxelLibrary::get_voxel_editor_count() { return _voxel_editor_count; } void VoxelLibrary::set_voxel_editor_count(int value) { _voxel_editor_count = value; } 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; } 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; } 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::rebuild_uvs() { float material_width = (float)1 / (float)(get_atlas_columns()); float material_height = (float)1 / (float)(get_atlas_rows()); _uvs->clear(); for (float num2 = (float)0; num2 < (float)1; num2 += material_height) { for (float num3 = (float)0; num3 < (float)1; num3 += material_width) { _uvs->push_back(get_uvs_test(num3, num2, material_width, material_height)); } } } Vector VoxelLibrary::get_material_uv(int ID) { if (_is_textured) { return (*_uvs)[ID]; } return get_uvs_test((float)0, (float)0, (float)1, (float)1); } Vector VoxelLibrary::get_uvs_test(float x, float y, float w, float h) { Vector v; v.push_back(Vector2(x + w, y)); v.push_back(Vector2(x + w, y + h)); v.push_back(Vector2(x, y + h)); v.push_back(Vector2(x, y)); return v; } void VoxelLibrary::set_atlas_columns(int s) { ERR_FAIL_COND(s <= 0); _atlas_columns = s; } void VoxelLibrary::set_atlas_rows(int s) { ERR_FAIL_COND(s <= 0); _atlas_rows = s; } bool VoxelLibrary::get_is_textured() const { return _is_textured; } void VoxelLibrary::set_is_textured(bool value) { _is_textured = value; } 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("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_atlas_columns"), &VoxelLibrary::get_atlas_columns); ClassDB::bind_method(D_METHOD("set_atlas_columns", "value"), &VoxelLibrary::set_atlas_columns); ADD_PROPERTY(PropertyInfo(Variant::INT, "atlas_columns"), "set_atlas_columns", "get_atlas_columns"); ClassDB::bind_method(D_METHOD("get_atlas_rows"), &VoxelLibrary::get_atlas_rows); ClassDB::bind_method(D_METHOD("set_atlas_rows", "value"), &VoxelLibrary::set_atlas_rows); ADD_PROPERTY(PropertyInfo(Variant::INT, "atlas_rows"), "set_atlas_rows", "get_atlas_rows"); ClassDB::bind_method(D_METHOD("get_is_textured"), &VoxelLibrary::get_is_textured); ClassDB::bind_method(D_METHOD("set_is_textured", "value"), &VoxelLibrary::set_is_textured); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "is_textured"), "set_is_textured", "get_is_textured"); ClassDB::bind_method(D_METHOD("get_material"), &VoxelLibrary::get_material); ClassDB::bind_method(D_METHOD("set_material", "value"), &VoxelLibrary::set_material); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "Material"), "set_material", "get_material"); 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); }