diff --git a/project/addons/terrain_3d/editor.gd b/project/addons/terrain_3d/editor.gd index ec32da2e..f34c8f04 100644 --- a/project/addons/terrain_3d/editor.gd +++ b/project/addons/terrain_3d/editor.gd @@ -180,9 +180,8 @@ func _forward_3d_gui_input(p_viewport_camera: Camera3D, p_event: InputEvent) -> ui.update_decal() ## Update region highlight - var region_size = terrain.get_storage().get_region_size() var region_position: Vector2 = ( Vector2(mouse_global_position.x, mouse_global_position.z) \ - / (region_size * terrain.get_mesh_vertex_spacing()) ).floor() + / (terrain.get_region_size() * terrain.get_mesh_vertex_spacing()) ).floor() if current_region_position != region_position: current_region_position = region_position update_region_grid() @@ -246,7 +245,7 @@ func update_region_grid() -> void: region_gizmo.show_rect = editor.get_tool() == Terrain3DEditor.REGION region_gizmo.use_secondary_color = editor.get_operation() == Terrain3DEditor.SUBTRACT region_gizmo.region_position = current_region_position - region_gizmo.region_size = terrain.get_storage().get_region_size() * terrain.get_mesh_vertex_spacing() + region_gizmo.region_size = terrain.get_region_size() * terrain.get_mesh_vertex_spacing() region_gizmo.grid = terrain.get_storage().get_region_locations() terrain.update_gizmos() diff --git a/src/terrain_3d.cpp b/src/terrain_3d.cpp index 35091416..90e74b37 100644 --- a/src/terrain_3d.cpp +++ b/src/terrain_3d.cpp @@ -51,11 +51,6 @@ void Terrain3D::_initialize() { } // Connect signals - // Region size changed, update material - if (!_storage->is_connected("region_size_changed", callable_mp(_material.ptr(), &Terrain3DMaterial::_update_maps))) { - LOG(DEBUG, "Connecting region_size_changed signal to _material->_update_regions()"); - _storage->connect("region_size_changed", callable_mp(_material.ptr(), &Terrain3DMaterial::_update_maps)); - } // Any region was changed, update region labels if (!_storage->is_connected("region_map_changed", callable_mp(this, &Terrain3D::update_region_labels))) { LOG(DEBUG, "Connecting _storage::region_map_changed signal to set_show_region_locations()"); @@ -420,8 +415,7 @@ void Terrain3D::_update_collision() { } int time = Time::get_singleton()->get_ticks_msec(); - int region_size = _storage->get_region_size(); - int shape_size = region_size + 1; + int shape_size = _region_size + 1; float hole_const = NAN; // DEPRECATED - Jolt v0.12 supports NAN. Remove check when it's old. if (ProjectSettings::get_singleton()->get_setting("physics/3d/physics_engine") == "JoltPhysics3D") { @@ -433,7 +427,7 @@ void Terrain3D::_update_collision() { map_data.resize(shape_size * shape_size); Vector2i region_loc = _storage->get_region_locations()[i]; - Vector2i global_loc = region_loc * region_size; + Vector2i global_loc = region_loc * _region_size; Vector3 global_pos = Vector3(global_loc.x, 0.f, global_loc.y); Ref map, map_x, map_z, map_xz; @@ -446,17 +440,17 @@ void Terrain3D::_update_collision() { map = region->get_map(TYPE_HEIGHT); cmap = region->get_map(TYPE_CONTROL); - region = _storage->get_regionp(Vector3(global_pos.x + region_size, 0.f, global_pos.z) * _mesh_vertex_spacing); + region = _storage->get_regionp(Vector3(global_pos.x + _region_size, 0.f, global_pos.z) * _mesh_vertex_spacing); if (region.is_valid()) { map_x = region->get_map(TYPE_HEIGHT); cmap_x = region->get_map(TYPE_CONTROL); } - region = _storage->get_regionp(Vector3(global_pos.x, 0.f, global_pos.z + region_size) * _mesh_vertex_spacing); + region = _storage->get_regionp(Vector3(global_pos.x, 0.f, global_pos.z + _region_size) * _mesh_vertex_spacing); if (region.is_valid()) { map_z = region->get_map(TYPE_HEIGHT); cmap_z = region->get_map(TYPE_CONTROL); } - region = _storage->get_regionp(Vector3(global_pos.x + region_size, 0.f, global_pos.z + region_size) * _mesh_vertex_spacing); + region = _storage->get_regionp(Vector3(global_pos.x + _region_size, 0.f, global_pos.z + _region_size) * _mesh_vertex_spacing); if (region.is_valid()) { map_xz = region->get_map(TYPE_HEIGHT); cmap_xz = region->get_map(TYPE_CONTROL); @@ -472,21 +466,21 @@ void Terrain3D::_update_collision() { int index = shape_size - 1 - z + x * shape_size; // Set heights on local map, or adjacent maps if on the last row/col - if (x < region_size && z < region_size) { + if (x < _region_size && z < _region_size) { map_data[index] = (is_hole(cmap->get_pixel(x, z).r)) ? hole_const : map->get_pixel(x, z).r; - } else if (x == region_size && z < region_size) { + } else if (x == _region_size && z < _region_size) { if (map_x.is_valid()) { map_data[index] = (is_hole(cmap_x->get_pixel(0, z).r)) ? hole_const : map_x->get_pixel(0, z).r; } else { map_data[index] = 0.0f; } - } else if (z == region_size && x < region_size) { + } else if (z == _region_size && x < _region_size) { if (map_z.is_valid()) { map_data[index] = (is_hole(cmap_z->get_pixel(x, 0).r)) ? hole_const : map_z->get_pixel(x, 0).r; } else { map_data[index] = 0.0f; } - } else if (x == region_size && z == region_size) { + } else if (x == _region_size && z == _region_size) { if (map_xz.is_valid()) { map_data[index] = (is_hole(cmap_xz->get_pixel(0, 0).r)) ? hole_const : map_xz->get_pixel(0, 0).r; } else { @@ -500,7 +494,7 @@ void Terrain3D::_update_collision() { //Transform3D xform = Transform3D(Basis(), global_pos); // Rotated shape Y=90 for -90 rotated array index Transform3D xform = Transform3D(Basis(Vector3(0.f, 1.f, 0.f), Math_PI * .5f), - global_pos + Vector3(region_size, 0.f, region_size) * .5f); + global_pos + Vector3(_region_size, 0.f, _region_size) * .5f); xform.scale(Vector3(_mesh_vertex_spacing, 1.f, _mesh_vertex_spacing)); if (!_show_debug_collision) { @@ -575,7 +569,7 @@ void Terrain3D::_generate_triangles(PackedVector3Array &p_vertices, PackedVector int32_t step = 1 << CLAMP(p_lod, 0, 8); if (!p_global_aabb.has_volume()) { - int32_t region_size = (int)_storage->get_region_size(); + int32_t region_size = (int32_t)_region_size; TypedArray region_locations = _storage->get_region_locations(); for (int r = 0; r < region_locations.size(); ++r) { @@ -684,6 +678,22 @@ void Terrain3D::set_debug_level(const int p_level) { debug_level = CLAMP(p_level, 0, DEBUG_MAX); } +void Terrain3D::set_region_size(const RegionSize p_size) { + LOG(INFO, p_size); + //ERR_FAIL_COND(p_size < SIZE_64); + //ERR_FAIL_COND(p_size > SIZE_2048); + ERR_FAIL_COND(p_size != SIZE_1024); + _region_size = p_size; + // Region size changed, update downstream + if (_storage) { + _storage->_region_size = _region_size; + _storage->_region_sizev = Vector2i(_region_size, _region_size); + } + if (_material.is_valid()) { + _material->_update_maps(); + } +} + void Terrain3D::set_mesh_lods(const int p_count) { if (_mesh_lods != p_count) { _clear_meshes(); @@ -1117,8 +1127,7 @@ void Terrain3D::update_region_labels() { label->set_visibility_range_fade_mode(GeometryInstance3D::VISIBILITY_RANGE_FADE_SELF); _label_nodes->add_child(label, true); Vector2i loc = region_locations[i]; - int region_size = _storage->get_region_size(); - Vector3 pos = Vector3(real_t(loc.x) + .5f, 0.f, real_t(loc.y) + .5f) * region_size * _mesh_vertex_spacing; + Vector3 pos = Vector3(real_t(loc.x) + .5f, 0.f, real_t(loc.y) + .5f) * _region_size * _mesh_vertex_spacing; label->set_position(pos); } } @@ -1345,6 +1354,13 @@ void Terrain3D::_notification(const int p_what) { } void Terrain3D::_bind_methods() { + //BIND_ENUM_CONSTANT(SIZE_64); + //BIND_ENUM_CONSTANT(SIZE_128); + //BIND_ENUM_CONSTANT(SIZE_256); + //BIND_ENUM_CONSTANT(SIZE_512); + BIND_ENUM_CONSTANT(SIZE_1024); + //BIND_ENUM_CONSTANT(SIZE_2048); + ClassDB::bind_method(D_METHOD("get_version"), &Terrain3D::get_version); ClassDB::bind_method(D_METHOD("set_debug_level", "level"), &Terrain3D::set_debug_level); ClassDB::bind_method(D_METHOD("get_debug_level"), &Terrain3D::get_debug_level); @@ -1357,6 +1373,9 @@ void Terrain3D::_bind_methods() { ClassDB::bind_method(D_METHOD("set_save_16_bit", "enabled"), &Terrain3D::set_save_16_bit); ClassDB::bind_method(D_METHOD("get_save_16_bit"), &Terrain3D::get_save_16_bit); + ClassDB::bind_method(D_METHOD("set_region_size", "size"), &Terrain3D::set_region_size); + ClassDB::bind_method(D_METHOD("get_region_size"), &Terrain3D::get_region_size); + ClassDB::bind_method(D_METHOD("set_mesh_lods", "count"), &Terrain3D::set_mesh_lods); ClassDB::bind_method(D_METHOD("get_mesh_lods"), &Terrain3D::get_mesh_lods); ClassDB::bind_method(D_METHOD("set_mesh_size", "size"), &Terrain3D::set_mesh_size); @@ -1402,8 +1421,12 @@ void Terrain3D::_bind_methods() { ClassDB::bind_method(D_METHOD("bake_mesh", "lod", "filter"), &Terrain3D::bake_mesh); ClassDB::bind_method(D_METHOD("generate_nav_mesh_source_geometry", "global_aabb", "require_nav"), &Terrain3D::generate_nav_mesh_source_geometry, DEFVAL(true)); + int ro_flags = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_READ_ONLY; + ADD_PROPERTY(PropertyInfo(Variant::STRING, "version", PROPERTY_HINT_NONE, "", PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_READ_ONLY), "", "get_version"); ADD_PROPERTY(PropertyInfo(Variant::STRING, "storage_directory", PROPERTY_HINT_DIR), "set_storage_directory", "get_storage_directory"); + //ADD_PROPERTY(PropertyInfo(Variant::INT, "region_size", PROPERTY_HINT_ENUM, "64:64, 128:128, 256:256, 512:512, 1024:1024, 2048:2048"), "set_region_size", "get_region_size"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "region_size", PROPERTY_HINT_ENUM, "1024:1024"), "set_region_size", "get_region_size"); ADD_PROPERTY(PropertyInfo(Variant::BOOL, "save_16_bit", PROPERTY_HINT_NONE), "set_save_16_bit", "get_save_16_bit"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "material", PROPERTY_HINT_RESOURCE_TYPE, "Terrain3DMaterial"), "set_material", "get_material"); ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "assets", PROPERTY_HINT_RESOURCE_TYPE, "Terrain3DAssets"), "set_assets", "get_assets"); diff --git a/src/terrain_3d.h b/src/terrain_3d.h index cfdf1d95..5db4c47b 100644 --- a/src/terrain_3d.h +++ b/src/terrain_3d.h @@ -24,12 +24,24 @@ class Terrain3D : public Node3D { GDCLASS(Terrain3D, Node3D); CLASS_NAME(); +public: // Constants + enum RegionSize { + //SIZE_64 = 64, + //SIZE_128 = 128, + //SIZE_256 = 256, + //SIZE_512 = 512, + SIZE_1024 = 1024, + //SIZE_2048 = 2048, + }; + +private: // Terrain state String _version = "0.9.3-dev"; bool _is_inside_world = false; bool _initialized = false; // Terrain settings + RegionSize _region_size = SIZE_1024; int _mesh_size = 48; int _mesh_lods = 7; real_t _mesh_vertex_spacing = 1.0f; @@ -122,6 +134,8 @@ class Terrain3D : public Node3D { String get_version() const { return _version; } void set_debug_level(const int p_level); int get_debug_level() const { return debug_level; } + void set_region_size(const RegionSize p_size); + RegionSize get_region_size() const { return _region_size; } void set_mesh_lods(const int p_count); int get_mesh_lods() const { return _mesh_lods; } void set_mesh_size(const int p_size); @@ -200,4 +214,6 @@ class Terrain3D : public Node3D { static void _bind_methods(); }; +VARIANT_ENUM_CAST(Terrain3D::RegionSize); + #endif // TERRAIN3D_CLASS_H diff --git a/src/terrain_3d_editor.cpp b/src/terrain_3d_editor.cpp index e9d2f8fe..a86f2f2c 100644 --- a/src/terrain_3d_editor.cpp +++ b/src/terrain_3d_editor.cpp @@ -14,7 +14,7 @@ // Sends the whole region aabb to edited_area void Terrain3DEditor::_send_region_aabb(const Vector2i &p_region_loc, const Vector2 &p_height_range) { - Terrain3DStorage::RegionSize region_size = _terrain->get_storage()->get_region_size(); + Terrain3D::RegionSize region_size = _terrain->get_region_size(); AABB edited_area; edited_area.position = Vector3(p_region_loc.x * region_size, p_height_range.x, p_region_loc.y * region_size); edited_area.size = Vector3(region_size, p_height_range.y - p_height_range.x, region_size); @@ -94,11 +94,11 @@ void Terrain3DEditor::_operate_map(const Vector3 &p_global_position, const real_ return; } - Terrain3DStorage *storage = _terrain->get_storage(); - int region_size = storage->get_region_size(); + int region_size = _terrain->get_region_size(); Vector2i region_vsize = Vector2i(region_size, region_size); // If no region and can't add one, skip whole function. Checked again later + Terrain3DStorage *storage = _terrain->get_storage(); if (!storage->has_regionp(p_global_position) && (!_brush_data["auto_regions"] || _tool != HEIGHT)) { return; } diff --git a/src/terrain_3d_instancer.cpp b/src/terrain_3d_instancer.cpp index aa835cb0..7b44e5ca 100644 --- a/src/terrain_3d_instancer.cpp +++ b/src/terrain_3d_instancer.cpp @@ -482,7 +482,7 @@ void Terrain3DInstancer::update_transforms(const AABB &p_aabb) { LOG(WARN, "No region found at: ", region_loc); continue; } - int region_size = _terrain->get_storage()->get_region_size(); + int region_size = _terrain->get_region_size(); Rect2 region_rect; region_rect.set_position(region_loc * region_size); region_rect.set_size(Vector2(region_size, region_size)); diff --git a/src/terrain_3d_material.cpp b/src/terrain_3d_material.cpp index f6b104c8..1f64bb91 100644 --- a/src/terrain_3d_material.cpp +++ b/src/terrain_3d_material.cpp @@ -320,7 +320,7 @@ void Terrain3DMaterial::_update_maps() { LOG(DEBUG_CONT, "Region_locations size: ", region_locations.size(), " ", region_locations); RS->material_set_param(_material, "_region_locations", region_locations); - real_t region_size = real_t(storage->get_region_size()); + real_t region_size = real_t(_terrain->get_region_size()); LOG(DEBUG_CONT, "Setting region size in material: ", region_size); RS->material_set_param(_material, "_region_size", region_size); RS->material_set_param(_material, "_region_texel_size", 1.0f / region_size); diff --git a/src/terrain_3d_storage.cpp b/src/terrain_3d_storage.cpp index 670aa46a..57a5eb47 100644 --- a/src/terrain_3d_storage.cpp +++ b/src/terrain_3d_storage.cpp @@ -40,6 +40,9 @@ void Terrain3DStorage::initialize(Terrain3D *p_terrain) { _terrain = p_terrain; _region_map.resize(REGION_MAP_SIZE * REGION_MAP_SIZE); _mesh_vertex_spacing = _terrain->get_mesh_vertex_spacing(); + _region_size = _terrain->get_region_size(); + _region_sizev = Vector2i(_region_size, _region_size); + if (!initialized && !_terrain->get_storage_directory().is_empty()) { load_directory(_terrain->get_storage_directory()); } @@ -126,16 +129,6 @@ bool Terrain3DStorage::is_region_deleted(const Vector2i &p_region_loc) const { return region->is_deleted(); } -void Terrain3DStorage::set_region_size(const RegionSize p_size) { - LOG(INFO, p_size); - //ERR_FAIL_COND(p_size < SIZE_64); - //ERR_FAIL_COND(p_size > SIZE_2048); - ERR_FAIL_COND(p_size != SIZE_1024); - _region_size = p_size; - _region_sizev = Vector2i(_region_size, _region_size); - emit_signal("region_size_changed", _region_size); -} - void Terrain3DStorage::set_region_locations(const TypedArray &p_locations) { LOG(INFO, "Setting _region_locations with array sized: ", p_locations.size()); _region_locations = p_locations; @@ -959,13 +952,6 @@ void Terrain3DStorage::print_audit_data() const { /////////////////////////// void Terrain3DStorage::_bind_methods() { - //BIND_ENUM_CONSTANT(SIZE_64); - //BIND_ENUM_CONSTANT(SIZE_128); - //BIND_ENUM_CONSTANT(SIZE_256); - //BIND_ENUM_CONSTANT(SIZE_512); - BIND_ENUM_CONSTANT(SIZE_1024); - //BIND_ENUM_CONSTANT(SIZE_2048); - BIND_ENUM_CONSTANT(HEIGHT_FILTER_NEAREST); BIND_ENUM_CONSTANT(HEIGHT_FILTER_MINIMUM); @@ -994,10 +980,6 @@ void Terrain3DStorage::_bind_methods() { ClassDB::bind_method(D_METHOD("get_region_id", "region_location"), &Terrain3DStorage::get_region_id); ClassDB::bind_method(D_METHOD("get_region_idp", "global_position"), &Terrain3DStorage::get_region_idp); - ClassDB::bind_method(D_METHOD("set_region_size", "size"), &Terrain3DStorage::set_region_size); - ClassDB::bind_method(D_METHOD("get_region_size"), &Terrain3DStorage::get_region_size); - ClassDB::bind_method(D_METHOD("get_region_sizev"), &Terrain3DStorage::get_region_sizev); - ClassDB::bind_method(D_METHOD("add_region", "region", "update"), &Terrain3DStorage::add_region, DEFVAL(true)); ClassDB::bind_method(D_METHOD("add_regionl", "region_location", "update"), &Terrain3DStorage::add_regionl, DEFVAL(true)); ClassDB::bind_method(D_METHOD("add_regionp", "global_position", "update"), &Terrain3DStorage::add_regionp, DEFVAL(true)); @@ -1048,15 +1030,10 @@ void Terrain3DStorage::_bind_methods() { ClassDB::bind_method(D_METHOD("export_image", "file_name", "map_type"), &Terrain3DStorage::export_image); ClassDB::bind_method(D_METHOD("layered_to_image", "map_type"), &Terrain3DStorage::layered_to_image); - int ro_flags = PROPERTY_USAGE_STORAGE | PROPERTY_USAGE_EDITOR | PROPERTY_USAGE_READ_ONLY; - //ADD_PROPERTY(PropertyInfo(Variant::INT, "region_size", PROPERTY_HINT_ENUM, "64:64, 128:128, 256:256, 512:512, 1024:1024, 2048:2048"), "set_region_size", "get_region_size"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "region_size", PROPERTY_HINT_ENUM, "1024:1024"), "set_region_size", "get_region_size"); - ADD_SIGNAL(MethodInfo("maps_changed")); ADD_SIGNAL(MethodInfo("region_map_changed")); ADD_SIGNAL(MethodInfo("height_maps_changed")); ADD_SIGNAL(MethodInfo("control_maps_changed")); ADD_SIGNAL(MethodInfo("color_maps_changed")); - ADD_SIGNAL(MethodInfo("region_size_changed")); ADD_SIGNAL(MethodInfo("maps_edited", PropertyInfo(Variant::AABB, "edited_area"))); } diff --git a/src/terrain_3d_storage.h b/src/terrain_3d_storage.h index 75a7982b..d675d8fd 100644 --- a/src/terrain_3d_storage.h +++ b/src/terrain_3d_storage.h @@ -21,15 +21,6 @@ class Terrain3DStorage : public Object { static inline const int REGION_MAP_SIZE = 16; static inline const Vector2i REGION_MAP_VSIZE = Vector2i(REGION_MAP_SIZE, REGION_MAP_SIZE); - enum RegionSize { - //SIZE_64 = 64, - //SIZE_128 = 128, - //SIZE_256 = 256, - //SIZE_512 = 512, - SIZE_1024 = 1024, - //SIZE_2048 = 2048, - }; - enum HeightFilter { HEIGHT_FILTER_NEAREST, HEIGHT_FILTER_MINIMUM @@ -39,6 +30,8 @@ class Terrain3DStorage : public Object { Terrain3D *_terrain = nullptr; // Storage Settings & flags + int _region_size = 0; + Vector2i _region_sizev = Vector2i(_region_size, _region_size); real_t _mesh_vertex_spacing = 1.f; // Set by Terrain3D::set_mesh_vertex_spacing AABB _edited_area; @@ -79,10 +72,6 @@ class Terrain3DStorage : public Object { GeneratedTexture _generated_control_maps; GeneratedTexture _generated_color_maps; - /// Move to Region? - RegionSize _region_size = SIZE_1024; - Vector2i _region_sizev = Vector2i(_region_size, _region_size); - // Functions void _clear(); @@ -121,10 +110,6 @@ class Terrain3DStorage : public Object { int get_region_id(const Vector2i &p_region_loc) const; int get_region_idp(const Vector3 &p_global_position) const; - void set_region_size(const RegionSize p_size); - RegionSize get_region_size() const { return _region_size; } - Vector2i get_region_sizev() const { return _region_sizev; } - Error add_region(const Ref &p_region, const bool p_update = true); Error add_regionl(const Vector2i &p_region_loc, const Ref &p_region, const bool p_update = true); Error add_regionp(const Vector3 &p_global_position, const Ref &p_region, const bool p_update = true); @@ -192,7 +177,6 @@ class Terrain3DStorage : public Object { static void _bind_methods(); }; -VARIANT_ENUM_CAST(Terrain3DStorage::RegionSize); VARIANT_ENUM_CAST(Terrain3DStorage::HeightFilter); /// Inline Region Functions