Merge pull request #873 from aidandavey/Update-Transforms-isn't-working-#856
Fix #856 - Update Transforms isn't working
This commit is contained in:
commit
cad4e5d8d6
|
|
@ -12,7 +12,7 @@ config_version=5
|
|||
|
||||
config/name="Terrain3D"
|
||||
run/main_scene="res://demo/Demo.tscn"
|
||||
config/features=PackedStringArray("4.4", "C#")
|
||||
config/features=PackedStringArray("4.4")
|
||||
config/icon="res://icon.png"
|
||||
|
||||
[display]
|
||||
|
|
|
|||
|
|
@ -154,8 +154,8 @@ void Terrain3D::_destroy_containers() {
|
|||
void Terrain3D::_destroy_labels() {
|
||||
Array labels = _label_parent->get_children();
|
||||
LOG(DEBUG, "Destroying ", labels.size(), " region labels");
|
||||
for (int i = 0; i < labels.size(); i++) {
|
||||
Node *label = cast_to<Node>(labels[i]);
|
||||
for (const Variant &var : labels) {
|
||||
Node *label = cast_to<Node>(var);
|
||||
memdelete_safely(label);
|
||||
}
|
||||
}
|
||||
|
|
@ -267,11 +267,10 @@ void Terrain3D::_generate_triangles(PackedVector3Array &p_vertices, PackedVector
|
|||
int32_t region_size = (int32_t)_region_size;
|
||||
|
||||
TypedArray<Vector2i> region_locations = _data->get_region_locations();
|
||||
for (int r = 0; r < region_locations.size(); ++r) {
|
||||
Vector2i region_loc = (Vector2i)region_locations[r] * region_size;
|
||||
|
||||
for (int32_t z = region_loc.y; z < region_loc.y + region_size; z += step) {
|
||||
for (int32_t x = region_loc.x; x < region_loc.x + region_size; x += step) {
|
||||
for (const Vector2i ®ion_loc : region_locations) {
|
||||
Vector2i region_pos = region_loc * region_size;
|
||||
for (int32_t z = region_pos.y; z < region_pos.y + region_size; z += step) {
|
||||
for (int32_t x = region_pos.x; x < region_pos.x + region_size; x += step) {
|
||||
_generate_triangle_pair(p_vertices, p_uvs, p_lod, p_filter, p_require_nav, x, z);
|
||||
}
|
||||
}
|
||||
|
|
@ -549,8 +548,7 @@ void Terrain3D::set_save_16_bit(const bool p_enabled) {
|
|||
SET_IF_DIFF(_save_16_bit, p_enabled);
|
||||
LOG(INFO, "Save heightmaps as 16-bit: ", _save_16_bit);
|
||||
TypedArray<Terrain3DRegion> regions = _data->get_regions_active();
|
||||
for (int i = 0; i < regions.size(); i++) {
|
||||
Ref<Terrain3DRegion> region = regions[i];
|
||||
for (Ref<Terrain3DRegion> region : regions) {
|
||||
region->set_modified(true);
|
||||
}
|
||||
}
|
||||
|
|
@ -572,9 +570,9 @@ void Terrain3D::update_region_labels() {
|
|||
if (_label_distance > 0.f && _data) {
|
||||
TypedArray<Vector2i> region_locations = _data->get_region_locations();
|
||||
LOG(DEBUG, "Creating ", region_locations.size(), " region labels");
|
||||
for (int i = 0; i < region_locations.size(); i++) {
|
||||
for (const Vector2i ®ion_loc : region_locations) {
|
||||
Label3D *label = memnew(Label3D);
|
||||
String text = region_locations[i];
|
||||
String text = region_loc;
|
||||
label->set_name("Label3D" + text.replace(" ", ""));
|
||||
label->set_pixel_size(.001f);
|
||||
label->set_billboard_mode(BaseMaterial3D::BILLBOARD_ENABLED);
|
||||
|
|
@ -590,8 +588,7 @@ void Terrain3D::update_region_labels() {
|
|||
label->set_visibility_range_end_margin(_label_distance / 10.f);
|
||||
label->set_visibility_range_fade_mode(GeometryInstance3D::VISIBILITY_RANGE_FADE_SELF);
|
||||
_label_parent->add_child(label, true);
|
||||
Vector2i loc = region_locations[i];
|
||||
Vector3 pos = Vector3(real_t(loc.x) + .5f, 0.f, real_t(loc.y) + .5f) * _region_size * _vertex_spacing;
|
||||
Vector3 pos = Vector3(real_t(region_loc.x) + .5f, 0.f, real_t(region_loc.y) + .5f) * _region_size * _vertex_spacing;
|
||||
real_t height = _data->get_height(pos);
|
||||
pos.y = (std::isnan(height)) ? 0 : height;
|
||||
label->set_position(pos);
|
||||
|
|
|
|||
|
|
@ -201,13 +201,12 @@ void Terrain3DAssets::_update_texture_files() {
|
|||
bool normal_mipmaps = true;
|
||||
_terrain->set_warning(WARN_ALL, false);
|
||||
|
||||
for (int i = 0; i < _texture_list.size(); i++) {
|
||||
Ref<Terrain3DTextureAsset> texture_set = _texture_list[i];
|
||||
if (texture_set.is_null()) {
|
||||
for (const Ref<Terrain3DTextureAsset> &ta : _texture_list) {
|
||||
if (ta.is_null()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Ref<Texture2D> albedo_tex = texture_set->_albedo_texture;
|
||||
Ref<Texture2D> albedo_tex = ta->_albedo_texture;
|
||||
if (albedo_tex.is_valid()) {
|
||||
Vector2i tex_size = albedo_tex->get_size();
|
||||
Ref<Image> img = albedo_tex->get_image();
|
||||
|
|
@ -222,20 +221,20 @@ void Terrain3DAssets::_update_texture_files() {
|
|||
} else { // else validate against first texture
|
||||
if (tex_size != albedo_size) {
|
||||
_terrain->set_warning(WARN_MISMATCHED_SIZE, true);
|
||||
LOG(ERROR, "Texture ID ", i, " albedo size: ", tex_size, " doesn't match size of first texture: ", albedo_size, ". They must be identical. Read Texture Prep in docs.");
|
||||
LOG(ERROR, "Texture ID ", ta->get_id(), " albedo size: ", tex_size, " doesn't match size of first texture: ", albedo_size, ". They must be identical. Read Texture Prep in docs.");
|
||||
}
|
||||
if (format != albedo_format) {
|
||||
_terrain->set_warning(WARN_MISMATCHED_FORMAT, true);
|
||||
LOG(ERROR, "Texture ID ", i, " albedo format: ", format, " doesn't match format of first texture: ", albedo_format, ". They must be identical. Read Texture Prep in docs.");
|
||||
LOG(ERROR, "Texture ID ", ta->get_id(), " albedo format: ", format, " doesn't match format of first texture: ", albedo_format, ". They must be identical. Read Texture Prep in docs.");
|
||||
}
|
||||
if (mipmaps != albedo_mipmaps) {
|
||||
_terrain->set_warning(WARN_MISMATCHED_MIPMAPS, true);
|
||||
LOG(ERROR, "Texture ID ", i, " albedo mipmap setting (", mipmaps, ") doesn't match first texture (", albedo_mipmaps, "). They must be identical. Read Texture Prep in docs.");
|
||||
LOG(ERROR, "Texture ID ", ta->get_id(), " albedo mipmap setting (", mipmaps, ") doesn't match first texture (", albedo_mipmaps, "). They must be identical. Read Texture Prep in docs.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ref<Texture2D> normal_tex = texture_set->_normal_texture;
|
||||
Ref<Texture2D> normal_tex = ta->_normal_texture;
|
||||
if (normal_tex.is_valid()) {
|
||||
Vector2i tex_size = normal_tex->get_size();
|
||||
Ref<Image> img = normal_tex->get_image();
|
||||
|
|
@ -250,15 +249,15 @@ void Terrain3DAssets::_update_texture_files() {
|
|||
} else { // else validate against first texture
|
||||
if (tex_size != normal_size) {
|
||||
_terrain->set_warning(WARN_MISMATCHED_SIZE, true);
|
||||
LOG(ERROR, "Texture ID ", i, " normal size: ", tex_size, " doesn't match size of first texture: ", normal_size, ". They must be identical. Read Texture Prep in docs.");
|
||||
LOG(ERROR, "Texture ID ", ta->get_id(), " normal size: ", tex_size, " doesn't match size of first texture: ", normal_size, ". They must be identical. Read Texture Prep in docs.");
|
||||
}
|
||||
if (format != normal_format) {
|
||||
_terrain->set_warning(WARN_MISMATCHED_FORMAT, true);
|
||||
LOG(ERROR, "Texture ID ", i, " normal format: ", format, " doesn't match format of first texture: ", normal_format, ". They must be identical. Read Texture Prep in docs.");
|
||||
LOG(ERROR, "Texture ID ", ta->get_id(), " normal format: ", format, " doesn't match format of first texture: ", normal_format, ". They must be identical. Read Texture Prep in docs.");
|
||||
}
|
||||
if (mipmaps != normal_mipmaps) {
|
||||
_terrain->set_warning(WARN_MISMATCHED_MIPMAPS, true);
|
||||
LOG(ERROR, "Texture ID ", i, " normal mipmap setting (", mipmaps, ") doesn't match first texture (", albedo_mipmaps, "). They must be identical. Read Texture Prep in docs.");
|
||||
LOG(ERROR, "Texture ID ", ta->get_id(), " normal mipmap setting (", mipmaps, ") doesn't match first texture (", albedo_mipmaps, "). They must be identical. Read Texture Prep in docs.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -283,23 +282,22 @@ void Terrain3DAssets::_update_texture_files() {
|
|||
if (_generated_albedo_textures.is_dirty() && albedo_size != V2I_ZERO) {
|
||||
LOG(INFO, "Regenerating albedo texture array");
|
||||
Array albedo_texture_array;
|
||||
for (int i = 0; i < _texture_list.size(); i++) {
|
||||
Ref<Terrain3DTextureAsset> texture_set = _texture_list[i];
|
||||
if (texture_set.is_null()) {
|
||||
for (const Ref<Terrain3DTextureAsset> &ta : _texture_list) {
|
||||
if (ta.is_null()) {
|
||||
continue;
|
||||
}
|
||||
Ref<Texture2D> tex = texture_set->_albedo_texture;
|
||||
Ref<Texture2D> tex = ta->_albedo_texture;
|
||||
Ref<Image> img;
|
||||
|
||||
if (tex.is_null()) {
|
||||
img = Util::get_filled_image(albedo_size, COLOR_CHECKED, albedo_mipmaps, albedo_format);
|
||||
LOG(DEBUG, "Texture ID ", i, " albedo is null. Creating a new one. Format: ", img->get_format());
|
||||
texture_set->set_albedo_texture(ImageTexture::create_from_image(img));
|
||||
LOG(DEBUG, "Texture ID ", ta->get_id(), " albedo is null. Creating a new one. Format: ", img->get_format());
|
||||
ta->set_albedo_texture(ImageTexture::create_from_image(img));
|
||||
} else {
|
||||
img = tex->get_image();
|
||||
LOG(EXTREME, "Texture ID ", i, " albedo is valid. Format: ", img->get_format());
|
||||
LOG(EXTREME, "Texture ID ", ta->get_id(), " albedo is valid. Format: ", img->get_format());
|
||||
if (!IS_EDITOR && tex->get_path().contains("ImageTexture")) {
|
||||
LOG(WARN, "Texture ID ", i, " albedo is saved in the scene. Save it as a file and link it.");
|
||||
LOG(WARN, "Texture ID ", ta->get_id(), " albedo is saved in the scene. Save it as a file and link it.");
|
||||
}
|
||||
}
|
||||
albedo_texture_array.push_back(img);
|
||||
|
|
@ -314,23 +312,22 @@ void Terrain3DAssets::_update_texture_files() {
|
|||
|
||||
Array normal_texture_array;
|
||||
|
||||
for (int i = 0; i < _texture_list.size(); i++) {
|
||||
Ref<Terrain3DTextureAsset> texture_set = _texture_list[i];
|
||||
if (texture_set.is_null()) {
|
||||
for (const Ref<Terrain3DTextureAsset> &ta : _texture_list) {
|
||||
if (ta.is_null()) {
|
||||
continue;
|
||||
}
|
||||
Ref<Texture2D> tex = texture_set->_normal_texture;
|
||||
Ref<Texture2D> tex = ta->_normal_texture;
|
||||
Ref<Image> img;
|
||||
|
||||
if (tex.is_null()) {
|
||||
img = Util::get_filled_image(normal_size, COLOR_NORMAL, normal_mipmaps, normal_format);
|
||||
LOG(DEBUG, "Texture ID ", i, " normal is null. Creating a new one. Format: ", img->get_format());
|
||||
texture_set->_normal_texture = ImageTexture::create_from_image(img);
|
||||
LOG(DEBUG, "Texture ID ", ta->get_id(), " normal is null. Creating a new one. Format: ", img->get_format());
|
||||
ta->_normal_texture = ImageTexture::create_from_image(img);
|
||||
} else {
|
||||
img = tex->get_image();
|
||||
LOG(EXTREME, "Texture ID ", i, " normal is valid. Format: ", img->get_format());
|
||||
LOG(EXTREME, "Texture ID ", ta->get_id(), " normal is valid. Format: ", img->get_format());
|
||||
if (!IS_EDITOR && tex->get_path().contains("ImageTexture")) {
|
||||
LOG(WARN, "Texture ID ", i, " normal is saved in the scene. Save it as a file and link it.");
|
||||
LOG(WARN, "Texture ID ", ta->get_id(), " normal is saved in the scene. Save it as a file and link it.");
|
||||
}
|
||||
}
|
||||
normal_texture_array.push_back(img);
|
||||
|
|
@ -355,22 +352,21 @@ void Terrain3DAssets::_update_texture_settings() {
|
|||
_texture_vertical_projections = 0u;
|
||||
_texture_detiles.clear();
|
||||
|
||||
for (int i = 0; i < _texture_list.size(); i++) {
|
||||
Ref<Terrain3DTextureAsset> texture_set = _texture_list[i];
|
||||
if (texture_set.is_null()) {
|
||||
for (const Ref<Terrain3DTextureAsset> &ta : _texture_list) {
|
||||
if (ta.is_null()) {
|
||||
continue;
|
||||
}
|
||||
if (texture_set->is_highlighted()) {
|
||||
_texture_colors.push_back(texture_set->get_highlight_color());
|
||||
if (ta->is_highlighted()) {
|
||||
_texture_colors.push_back(ta->get_highlight_color());
|
||||
} else {
|
||||
_texture_colors.push_back(texture_set->get_albedo_color());
|
||||
_texture_colors.push_back(ta->get_albedo_color());
|
||||
}
|
||||
_texture_normal_depths.push_back(texture_set->get_normal_depth());
|
||||
_texture_ao_strengths.push_back(texture_set->get_ao_strength());
|
||||
_texture_roughness_mods.push_back(texture_set->get_roughness());
|
||||
_texture_uv_scales.push_back(texture_set->get_uv_scale());
|
||||
_texture_vertical_projections |= (texture_set->get_vertical_projection() ? (uint32_t(1u) << uint32_t(i)) : uint32_t(0u));
|
||||
_texture_detiles.push_back(Vector2(texture_set->get_detiling_rotation(), texture_set->get_detiling_shift()));
|
||||
_texture_normal_depths.push_back(ta->get_normal_depth());
|
||||
_texture_ao_strengths.push_back(ta->get_ao_strength());
|
||||
_texture_roughness_mods.push_back(ta->get_roughness());
|
||||
_texture_uv_scales.push_back(ta->get_uv_scale());
|
||||
_texture_vertical_projections |= (ta->get_vertical_projection() ? (uint32_t(1u) << uint32_t(ta->get_id())) : uint32_t(0u));
|
||||
_texture_detiles.push_back(Vector2(ta->get_detiling_rotation(), ta->get_detiling_shift()));
|
||||
}
|
||||
}
|
||||
LOG(DEBUG, "Emitting textures_changed");
|
||||
|
|
@ -516,19 +512,18 @@ void Terrain3DAssets::clear_textures(const bool p_update) {
|
|||
|
||||
void Terrain3DAssets::update_texture_list() {
|
||||
LOG(INFO, "Reconnecting texture signals");
|
||||
for (int i = 0; i < _texture_list.size(); i++) {
|
||||
Ref<Terrain3DTextureAsset> texture_set = _texture_list[i];
|
||||
if (texture_set.is_null()) {
|
||||
LOG(ERROR, "TextureAsset ID ", i, " is null, but shouldn't be.");
|
||||
for (const Ref<Terrain3DTextureAsset> &ta : _texture_list) {
|
||||
if (ta.is_null()) {
|
||||
LOG(ERROR, "Null TextureAsset found at index: ", _texture_list.find(ta));
|
||||
continue;
|
||||
}
|
||||
if (!texture_set->is_connected("file_changed", callable_mp(this, &Terrain3DAssets::_update_texture_files))) {
|
||||
if (!ta->is_connected("file_changed", callable_mp(this, &Terrain3DAssets::_update_texture_files))) {
|
||||
LOG(DEBUG, "Connecting file_changed signal");
|
||||
texture_set->connect("file_changed", callable_mp(this, &Terrain3DAssets::_update_texture_files));
|
||||
ta->connect("file_changed", callable_mp(this, &Terrain3DAssets::_update_texture_files));
|
||||
}
|
||||
if (!texture_set->is_connected("setting_changed", callable_mp(this, &Terrain3DAssets::_update_texture_settings))) {
|
||||
if (!ta->is_connected("setting_changed", callable_mp(this, &Terrain3DAssets::_update_texture_settings))) {
|
||||
LOG(DEBUG, "Connecting setting_changed signal");
|
||||
texture_set->connect("setting_changed", callable_mp(this, &Terrain3DAssets::_update_texture_settings));
|
||||
ta->connect("setting_changed", callable_mp(this, &Terrain3DAssets::_update_texture_settings));
|
||||
}
|
||||
}
|
||||
_update_texture_files();
|
||||
|
|
@ -662,16 +657,15 @@ void Terrain3DAssets::update_mesh_list() {
|
|||
set_mesh_asset(0, new_mesh);
|
||||
}
|
||||
LOG(DEBUG, "Reconnecting mesh instance signals");
|
||||
for (int i = 0; i < _mesh_list.size(); i++) {
|
||||
Ref<Terrain3DMeshAsset> mesh_asset = _mesh_list[i];
|
||||
if (mesh_asset.is_null()) {
|
||||
LOG(ERROR, "Terrain3DMeshAsset ID ", i, " is null, but shouldn't be");
|
||||
for (Ref<Terrain3DMeshAsset> ma : _mesh_list) {
|
||||
if (ma.is_null()) {
|
||||
LOG(ERROR, "Null Terrain3DMeshAsset found at index ", _mesh_list.find(ma));
|
||||
continue;
|
||||
}
|
||||
mesh_asset->check_mesh(true);
|
||||
if (!mesh_asset->is_connected("instancer_setting_changed", callable_mp(this, &Terrain3DAssets::_update_mesh))) {
|
||||
ma->check_mesh(true);
|
||||
if (!ma->is_connected("instancer_setting_changed", callable_mp(this, &Terrain3DAssets::_update_mesh))) {
|
||||
LOG(DEBUG, "Connecting instancer_setting_changed signal to _update_mesh");
|
||||
mesh_asset->connect("instancer_setting_changed", callable_mp(this, &Terrain3DAssets::_update_mesh));
|
||||
ma->connect("instancer_setting_changed", callable_mp(this, &Terrain3DAssets::_update_mesh));
|
||||
}
|
||||
}
|
||||
LOG(DEBUG, "Emitting meshes_changed");
|
||||
|
|
|
|||
|
|
@ -74,8 +74,7 @@ void Terrain3DData::set_region_locations(const TypedArray<Vector2i> &p_locations
|
|||
// Returns an array of active regions, optionally a shallow or deep copy
|
||||
TypedArray<Terrain3DRegion> Terrain3DData::get_regions_active(const bool p_copy, const bool p_deep) const {
|
||||
TypedArray<Terrain3DRegion> region_arr;
|
||||
for (int i = 0; i < _region_locations.size(); i++) {
|
||||
Vector2i region_loc = _region_locations[i];
|
||||
for (const Vector2i ®ion_loc : _region_locations) {
|
||||
Ref<Terrain3DRegion> region = get_region(region_loc);
|
||||
if (region.is_valid()) {
|
||||
region_arr.push_back(p_copy ? region->duplicate(p_deep) : region);
|
||||
|
|
@ -122,16 +121,16 @@ void Terrain3DData::change_region_size(int p_new_size) {
|
|||
}
|
||||
|
||||
// Get current region corners expressed in new region_size coordinates
|
||||
Dictionary new_region_points;
|
||||
Array locs = _regions.keys();
|
||||
for (int i = 0; i < locs.size(); i++) {
|
||||
const Terrain3DRegion *region = get_region_ptr((Vector2i)locs[i]);
|
||||
Dictionary new_region_locations;
|
||||
Array region_locations = _regions.keys();
|
||||
for (const Vector2i ®ion_loc : region_locations) {
|
||||
const Terrain3DRegion *region = get_region_ptr(region_loc);
|
||||
if (region && !region->is_deleted()) {
|
||||
Point2i region_position = region->get_location() * _region_size;
|
||||
Vector2i region_position = region->get_location() * _region_size;
|
||||
Rect2i location_bounds(V2I_DIVIDE_FLOOR(region_position, p_new_size), V2I_DIVIDE_CEIL(_region_sizev, p_new_size));
|
||||
for (int y = location_bounds.position.y; y < location_bounds.get_end().y; y++) {
|
||||
for (int x = location_bounds.position.x; x < location_bounds.get_end().x; x++) {
|
||||
new_region_points[Point2i(x, y)] = 1;
|
||||
new_region_locations[Vector2i(x, y)] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -139,12 +138,11 @@ void Terrain3DData::change_region_size(int p_new_size) {
|
|||
|
||||
// Make new regions to receive copied data
|
||||
TypedArray<Terrain3DRegion> new_regions;
|
||||
Array keys = new_region_points.keys();
|
||||
for (int i = 0; i < keys.size(); i++) {
|
||||
Point2i loc = keys[i];
|
||||
Array new_locations = new_region_locations.keys();
|
||||
for (const Vector2i ®ion_loc : new_locations) {
|
||||
Ref<Terrain3DRegion> new_region;
|
||||
new_region.instantiate();
|
||||
new_region->set_location(loc);
|
||||
new_region->set_location(region_loc);
|
||||
new_region->set_region_size(p_new_size);
|
||||
new_region->set_vertex_spacing(_vertex_spacing);
|
||||
new_region->set_modified(true);
|
||||
|
|
@ -152,7 +150,7 @@ void Terrain3DData::change_region_size(int p_new_size) {
|
|||
|
||||
// Copy current data from current into new region, up to new region size
|
||||
Rect2i area;
|
||||
area.position = loc * p_new_size;
|
||||
area.position = region_loc * p_new_size;
|
||||
area.size = V2I(p_new_size);
|
||||
do_for_regions(area, callable_mp(this, &Terrain3DData::_copy_paste_dfr).bind(new_region.ptr()));
|
||||
new_regions.push_back(new_region);
|
||||
|
|
@ -161,16 +159,16 @@ void Terrain3DData::change_region_size(int p_new_size) {
|
|||
// Remove old data
|
||||
_terrain->get_instancer()->destroy();
|
||||
TypedArray<Terrain3DRegion> old_regions = get_regions_active();
|
||||
for (int i = 0; i < old_regions.size(); i++) {
|
||||
remove_region(old_regions[i], false);
|
||||
for (const Ref<Terrain3DRegion> ®ion : old_regions) {
|
||||
remove_region(region, false);
|
||||
}
|
||||
|
||||
// Change region size
|
||||
_terrain->set_region_size((Terrain3D::RegionSize)p_new_size);
|
||||
|
||||
// Add new regions and rebuild
|
||||
for (int i = 0; i < new_regions.size(); i++) {
|
||||
add_region(new_regions[i], false);
|
||||
for (const Ref<Terrain3DRegion> ®ion : new_regions) {
|
||||
add_region(region, false);
|
||||
}
|
||||
|
||||
calc_height_range(true);
|
||||
|
|
@ -305,8 +303,8 @@ void Terrain3DData::remove_region(const Ref<Terrain3DRegion> &p_region, const bo
|
|||
void Terrain3DData::save_directory(const String &p_dir) {
|
||||
LOG(INFO, "Saving data files to ", p_dir);
|
||||
Array locations = _regions.keys();
|
||||
for (int i = 0; i < locations.size(); i++) {
|
||||
save_region(locations[i], p_dir, _terrain->get_save_16_bit());
|
||||
for (const Vector2i ®ion_loc : locations) {
|
||||
save_region(region_loc, p_dir, _terrain->get_save_16_bit());
|
||||
}
|
||||
if (IS_EDITOR && !EditorInterface::get_singleton()->get_resource_filesystem()->is_scanning()) {
|
||||
EditorInterface::get_singleton()->get_resource_filesystem()->scan();
|
||||
|
|
@ -363,8 +361,7 @@ void Terrain3DData::load_directory(const String &p_dir) {
|
|||
}
|
||||
|
||||
_clear();
|
||||
for (int i = 0; i < files.size(); i++) {
|
||||
String fname = files[i];
|
||||
for (const String &fname : files) {
|
||||
String path = p_dir + String("/") + fname;
|
||||
LOG(DEBUG, "Loading region from ", path);
|
||||
Vector2i loc = Util::filename_to_location(fname);
|
||||
|
|
@ -448,8 +445,7 @@ void Terrain3DData::update_maps(const MapType p_map_type, const bool p_all_regio
|
|||
// Generate region color mipmaps
|
||||
if (p_generate_mipmaps && (p_map_type == TYPE_COLOR || p_map_type == TYPE_MAX)) {
|
||||
LOG(EXTREME, "Regenerating color mipmaps");
|
||||
for (int i = 0; i < _region_locations.size(); i++) {
|
||||
Vector2i region_loc = _region_locations[i];
|
||||
for (const Vector2i ®ion_loc : _region_locations) {
|
||||
Terrain3DRegion *region = get_region_ptr(region_loc);
|
||||
// Generate all or only those marked edited
|
||||
if (region && (p_all_regions || region->is_edited())) {
|
||||
|
|
@ -491,8 +487,7 @@ void Terrain3DData::update_maps(const MapType p_map_type, const bool p_all_regio
|
|||
_region_locations = TypedArray<Vector2i>(); // enforce new pointer
|
||||
Array locs = _regions.keys();
|
||||
int region_id = 0;
|
||||
for (int i = 0; i < locs.size(); i++) {
|
||||
Vector2i region_loc = locs[i];
|
||||
for (const Vector2i ®ion_loc : locs) {
|
||||
const Terrain3DRegion *region = get_region_ptr(region_loc);
|
||||
if (region && !region->is_deleted()) {
|
||||
region_id += 1; // Begin at 1 since 0 = no region
|
||||
|
|
@ -512,8 +507,7 @@ void Terrain3DData::update_maps(const MapType p_map_type, const bool p_all_regio
|
|||
if (_generated_height_maps.is_dirty()) {
|
||||
LOG(EXTREME, "Regenerating height texture array from regions");
|
||||
_height_maps.clear();
|
||||
for (int i = 0; i < _region_locations.size(); i++) {
|
||||
Vector2i region_loc = _region_locations[i];
|
||||
for (const Vector2i ®ion_loc : _region_locations) {
|
||||
const Terrain3DRegion *region = get_region_ptr(region_loc);
|
||||
if (region) {
|
||||
_height_maps.push_back(region->get_height_map());
|
||||
|
|
@ -534,8 +528,7 @@ void Terrain3DData::update_maps(const MapType p_map_type, const bool p_all_regio
|
|||
if (_generated_control_maps.is_dirty()) {
|
||||
LOG(EXTREME, "Regenerating control texture array from regions");
|
||||
_control_maps.clear();
|
||||
for (int i = 0; i < _region_locations.size(); i++) {
|
||||
Vector2i region_loc = _region_locations[i];
|
||||
for (const Vector2i ®ion_loc : _region_locations) {
|
||||
const Terrain3DRegion *region = get_region_ptr(region_loc);
|
||||
if (region) {
|
||||
_control_maps.push_back(region->get_control_map());
|
||||
|
|
@ -551,8 +544,7 @@ void Terrain3DData::update_maps(const MapType p_map_type, const bool p_all_regio
|
|||
if (_generated_color_maps.is_dirty()) {
|
||||
LOG(EXTREME, "Regenerating color texture array from regions");
|
||||
_color_maps.clear();
|
||||
for (int i = 0; i < _region_locations.size(); i++) {
|
||||
Vector2i region_loc = _region_locations[i];
|
||||
for (const Vector2i ®ion_loc : _region_locations) {
|
||||
const Terrain3DRegion *region = get_region_ptr(region_loc);
|
||||
if (region) {
|
||||
_color_maps.push_back(region->get_color_map());
|
||||
|
|
@ -567,8 +559,7 @@ void Terrain3DData::update_maps(const MapType p_map_type, const bool p_all_regio
|
|||
// If no maps have been rebuilt, update only individual regions in the array.
|
||||
// Regions marked Edited have been changed by Terrain3DEditor::_operate_map or undo / redo processing.
|
||||
if (!any_changed) {
|
||||
for (int i = 0; i < _region_locations.size(); i++) {
|
||||
Vector2i region_loc = _region_locations[i];
|
||||
for (const Vector2i ®ion_loc : _region_locations) {
|
||||
const Terrain3DRegion *region = get_region_ptr(region_loc);
|
||||
if (region && region->is_edited()) {
|
||||
int region_id = get_region_id(region_loc);
|
||||
|
|
@ -844,8 +835,7 @@ void Terrain3DData::add_edited_area(const AABB &p_area) {
|
|||
// Recursive mode has all regions to recalculate from each heightmap pixel
|
||||
void Terrain3DData::calc_height_range(const bool p_recursive) {
|
||||
_master_height_range = V2_ZERO;
|
||||
for (int i = 0; i < _region_locations.size(); i++) {
|
||||
Vector2i region_loc = _region_locations[i];
|
||||
for (const Vector2i ®ion_loc : _region_locations) {
|
||||
Terrain3DRegion *region = get_region_ptr(region_loc);
|
||||
if (!region) {
|
||||
continue;
|
||||
|
|
@ -1092,9 +1082,8 @@ Ref<Image> Terrain3DData::layered_to_image(const MapType p_map_type) const {
|
|||
}
|
||||
Vector2i top_left = V2I_ZERO;
|
||||
Vector2i bottom_right = V2I_ZERO;
|
||||
for (int i = 0; i < _region_locations.size(); i++) {
|
||||
LOG(DEBUG, "Region locations[", i, "]: ", _region_locations[i]);
|
||||
Vector2i region_loc = _region_locations[i];
|
||||
for (const Vector2i ®ion_loc : _region_locations) {
|
||||
LOG(DEBUG, "Region location: ", region_loc);
|
||||
if (region_loc.x < top_left.x) {
|
||||
top_left.x = region_loc.x;
|
||||
} else if (region_loc.x > bottom_right.x) {
|
||||
|
|
@ -1112,8 +1101,7 @@ Ref<Image> Terrain3DData::layered_to_image(const MapType p_map_type) const {
|
|||
LOG(DEBUG, "Image size: ", img_size);
|
||||
Ref<Image> img = Util::get_filled_image(img_size, COLOR[map_type], false, FORMAT[map_type]);
|
||||
|
||||
for (int i = 0; i < _region_locations.size(); i++) {
|
||||
Vector2i region_loc = _region_locations[i];
|
||||
for (const Vector2i ®ion_loc : _region_locations) {
|
||||
Vector2i img_location = (region_loc - top_left) * _region_size;
|
||||
LOG(DEBUG, "Region to blit: ", region_loc, " Export image coords: ", img_location);
|
||||
const Terrain3DRegion *region = get_region_ptr(region_loc);
|
||||
|
|
@ -1128,8 +1116,7 @@ void Terrain3DData::dump(const bool verbose) const {
|
|||
LOG(MESG, "_region_locations (", _region_locations.size(), "): ", _region_locations);
|
||||
Array keys = _regions.keys();
|
||||
LOG(MESG, "_regions (", keys.size(), "):");
|
||||
for (int i = 0; i < keys.size(); i++) {
|
||||
Vector2i region_loc = keys[i];
|
||||
for (const Vector2i ®ion_loc : keys) {
|
||||
const Terrain3DRegion *region = get_region_ptr(region_loc);
|
||||
if (!region) {
|
||||
LOG(WARN, "No region found at: ", region_loc);
|
||||
|
|
|
|||
|
|
@ -558,8 +558,7 @@ void Terrain3DEditor::_operate_map(const Vector3 &p_global_position, const real_
|
|||
}
|
||||
// Regenerate color mipmaps for edited regions
|
||||
if (map_type == TYPE_COLOR) {
|
||||
for (int i = 0; i < _edited_regions.size(); i++) {
|
||||
Ref<Terrain3DRegion> region = _edited_regions[i];
|
||||
for (Ref<Terrain3DRegion> region : _edited_regions) {
|
||||
if (region.is_valid()) {
|
||||
region->get_map(map_type)->generate_mipmaps();
|
||||
}
|
||||
|
|
@ -598,15 +597,13 @@ void Terrain3DEditor::_store_undo() {
|
|||
|
||||
if (Terrain3D::debug_level >= DEBUG) {
|
||||
LOG(DEBUG, "Storing Original Regions:");
|
||||
for (int i = 0; i < _original_regions.size(); i++) {
|
||||
Ref<Terrain3DRegion> region = _original_regions[i];
|
||||
for (const Ref<Terrain3DRegion> ®ion : _original_regions) {
|
||||
if (region.is_valid()) {
|
||||
region->dump();
|
||||
}
|
||||
}
|
||||
LOG(DEBUG, "Storing Edited Regions:");
|
||||
for (int i = 0; i < _edited_regions.size(); i++) {
|
||||
Ref<Terrain3DRegion> region = _edited_regions[i];
|
||||
for (const Ref<Terrain3DRegion> ®ion : _edited_regions) {
|
||||
if (region.is_valid()) {
|
||||
region->dump();
|
||||
}
|
||||
|
|
@ -662,8 +659,7 @@ void Terrain3DEditor::_apply_undo(const Dictionary &p_data) {
|
|||
Util::print_arr("Edited regions", p_data["edited_regions"]);
|
||||
TypedArray<Terrain3DRegion> undo_regions = p_data["edited_regions"];
|
||||
LOG(DEBUG, "Backup has ", undo_regions.size(), " edited regions");
|
||||
for (int i = 0; i < undo_regions.size(); i++) {
|
||||
Ref<Terrain3DRegion> region = undo_regions[i];
|
||||
for (Ref<Terrain3DRegion> region : undo_regions) {
|
||||
if (region.is_null()) {
|
||||
LOG(ERROR, "Null region saved in undo data. Please report this error.");
|
||||
continue;
|
||||
|
|
@ -689,10 +685,10 @@ void Terrain3DEditor::_apply_undo(const Dictionary &p_data) {
|
|||
if (p_data.has("added_regions")) {
|
||||
LOG(DEBUG, "Added regions: ", p_data["added_regions"]);
|
||||
TypedArray<Vector2i> region_locs = p_data["added_regions"];
|
||||
for (int i = 0; i < region_locs.size(); i++) {
|
||||
Ref<Terrain3DRegion> region = data->get_region(region_locs[i]);
|
||||
for (const Vector2i region_loc : region_locs) {
|
||||
Ref<Terrain3DRegion> region = data->get_region(region_loc);
|
||||
if (region.is_valid()) {
|
||||
LOG(DEBUG, "Marking region: ", region_locs[i], " +deleted, +modified, ", ptr_to_str(*region));
|
||||
LOG(DEBUG, "Marking region: ", region_loc, " +deleted, +modified, ", ptr_to_str(*region));
|
||||
region->set_deleted(true);
|
||||
region->set_modified(true);
|
||||
}
|
||||
|
|
@ -701,13 +697,13 @@ void Terrain3DEditor::_apply_undo(const Dictionary &p_data) {
|
|||
if (p_data.has("removed_regions")) {
|
||||
LOG(DEBUG, "Removed regions: ", p_data["removed_regions"]);
|
||||
TypedArray<Vector2i> region_locs = p_data["removed_regions"];
|
||||
for (int i = 0; i < region_locs.size(); i++) {
|
||||
Ref<Terrain3DRegion> region = data->get_region(region_locs[i]);
|
||||
for (const Vector2i region_loc : region_locs) {
|
||||
Ref<Terrain3DRegion> region = data->get_region(region_loc);
|
||||
if (region.is_valid()) {
|
||||
LOG(DEBUG, "Marking region: ", region_locs[i], " -deleted, +modified, ", ptr_to_str(*region));
|
||||
LOG(DEBUG, "Marking region: ", region_loc, " -deleted, +modified, ", ptr_to_str(*region));
|
||||
region->set_deleted(false);
|
||||
region->set_modified(true);
|
||||
_send_region_aabb(region_locs[i], region->get_height_range());
|
||||
_send_region_aabb(region_loc, region->get_height_range());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -728,8 +724,7 @@ void Terrain3DEditor::_apply_undo(const Dictionary &p_data) {
|
|||
// After TextureArray updates clear edited regions flag.
|
||||
if (p_data.has("edited_regions")) {
|
||||
TypedArray<Terrain3DRegion> undo_regions = p_data["edited_regions"];
|
||||
for (int i = 0; i < undo_regions.size(); i++) {
|
||||
Ref<Terrain3DRegion> region = undo_regions[i];
|
||||
for (Ref<Terrain3DRegion> region : undo_regions) {
|
||||
if (region.is_valid()) {
|
||||
region->set_edited(false);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -392,10 +392,10 @@ void Terrain3DInstancer::_update_vertex_spacing(const real_t p_vertex_spacing) {
|
|||
void Terrain3DInstancer::_destroy_mmi_by_mesh(const int p_mesh_id) {
|
||||
LOG(DEBUG, "Deleting all MMIs in all regions with mesh_id: ", p_mesh_id);
|
||||
TypedArray<Vector2i> region_locations = _terrain->get_data()->get_region_locations();
|
||||
for (int i = 0; i < region_locations.size(); i++) {
|
||||
for (const Vector2i ®ion_loc : region_locations) {
|
||||
Ref<Terrain3DMeshAsset> ma = _terrain->get_assets()->get_mesh_asset(p_mesh_id);
|
||||
ma.is_valid() ? ma->set_instance_count(0) : void(); // Reset count for this mesh
|
||||
_destroy_mmi_by_location(region_locations[i], p_mesh_id);
|
||||
_destroy_mmi_by_location(region_loc, p_mesh_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -416,7 +416,7 @@ void Terrain3DInstancer::_destroy_mmi_by_location(const Vector2i &p_region_loc,
|
|||
}
|
||||
}
|
||||
// Iterate over unique cells; each _destroy_mmi_by_cell will handle all LODs
|
||||
for (const auto &cell : cells) {
|
||||
for (const Vector2i &cell : cells) {
|
||||
_destroy_mmi_by_cell(p_region_loc, p_mesh_id, cell);
|
||||
}
|
||||
}
|
||||
|
|
@ -591,8 +591,8 @@ void Terrain3DInstancer::destroy() {
|
|||
void Terrain3DInstancer::clear_by_mesh(const int p_mesh_id) {
|
||||
LOG(INFO, "Deleting Multimeshes in all regions with mesh_id: ", p_mesh_id);
|
||||
TypedArray<Vector2i> region_locations = _terrain->get_data()->get_region_locations();
|
||||
for (int i = 0; i < region_locations.size(); i++) {
|
||||
clear_by_location(region_locations[i], p_mesh_id);
|
||||
for (const Vector2i ®ion_loc : region_locations) {
|
||||
clear_by_location(region_loc, p_mesh_id);
|
||||
}
|
||||
Ref<Terrain3DMeshAsset> ma = _terrain->get_assets()->get_mesh_asset(p_mesh_id);
|
||||
ma.is_valid() ? ma->set_instance_count(0) : void(); // Reset count for this mesh
|
||||
|
|
@ -774,8 +774,7 @@ void Terrain3DInstancer::remove_instances(const Vector3 &p_global_position, cons
|
|||
return;
|
||||
}
|
||||
|
||||
for (int r = 0; r < region_queue.size(); r++) {
|
||||
Vector2i region_loc = region_queue[r];
|
||||
for (const Vector2i ®ion_loc : region_queue) {
|
||||
Ref<Terrain3DRegion> region = data->get_region(region_loc);
|
||||
if (region.is_null()) {
|
||||
LOG(WARN, "Errant null region found at: ", region_loc);
|
||||
|
|
@ -928,8 +927,7 @@ void Terrain3DInstancer::add_transforms(const int p_mesh_id, const TypedArray<Tr
|
|||
|
||||
// Merge incoming transforms with existing transforms
|
||||
Array region_locations = xforms_dict.keys();
|
||||
for (int i = 0; i < region_locations.size(); i++) {
|
||||
Vector2i region_loc = region_locations[i];
|
||||
for (const Vector2i ®ion_loc : region_locations) {
|
||||
TypedArray<Transform3D> xforms = xforms_dict[region_loc];
|
||||
PackedColorArray colors = colors_dict[region_loc];
|
||||
//LOG(MESG, "Appending ", xforms.size(), " xforms, ", colors, " colors to region location: ", region_loc);
|
||||
|
|
@ -949,8 +947,7 @@ void Terrain3DInstancer::append_location(const Vector2i &p_region_loc, const int
|
|||
real_t vertex_spacing = _terrain->get_vertex_spacing();
|
||||
Vector2 global_local_offset = Vector2(p_region_loc.x * region_size * vertex_spacing, p_region_loc.y * region_size * vertex_spacing);
|
||||
TypedArray<Transform3D> localised_xforms;
|
||||
for (int i = 0; i < p_xforms.size(); i++) {
|
||||
Transform3D t = p_xforms[i];
|
||||
for (Transform3D t : p_xforms) {
|
||||
// Localise the transform to "region space"
|
||||
t.origin.x -= global_local_offset.x;
|
||||
t.origin.z -= global_local_offset.y;
|
||||
|
|
@ -1048,8 +1045,7 @@ void Terrain3DInstancer::update_transforms(const AABB &p_aabb) {
|
|||
return;
|
||||
}
|
||||
|
||||
for (int r = 0; r < region_queue.size(); r++) {
|
||||
Vector2i region_loc = region_queue[r];
|
||||
for (const Vector2i ®ion_loc : region_queue) {
|
||||
Ref<Terrain3DRegion> region = data->get_region(region_loc);
|
||||
_backup_region(region);
|
||||
|
||||
|
|
@ -1060,12 +1056,11 @@ void Terrain3DInstancer::update_transforms(const AABB &p_aabb) {
|
|||
}
|
||||
Vector3 global_local_offset = Vector3(region_loc.x * region_size * vertex_spacing, 0.f, region_loc.y * region_size * vertex_spacing);
|
||||
|
||||
// For this mesh id, or all mesh ids
|
||||
for (int m = 0; m < mesh_types.size(); m++) {
|
||||
// For each mesh type in this region
|
||||
for (const int ®ion_mesh_id : mesh_types) {
|
||||
// Check potential cells rather than searching the entire region, whilst marginally
|
||||
// slower if there are very few cells for the given mesh present it is significantly
|
||||
// faster when a very large number of cells are present.
|
||||
int region_mesh_id = mesh_types[m];
|
||||
Dictionary cell_inst_dict = mesh_inst_dict[region_mesh_id];
|
||||
Array cell_locations = cell_inst_dict.keys();
|
||||
if (cell_locations.size() == 0) {
|
||||
|
|
@ -1090,10 +1085,9 @@ void Terrain3DInstancer::update_transforms(const AABB &p_aabb) {
|
|||
if (cell_queue.size() == 0) {
|
||||
continue;
|
||||
}
|
||||
Ref<Terrain3DMeshAsset> mesh_asset = _terrain->get_assets()->get_mesh_asset(mesh_types[m]);
|
||||
Ref<Terrain3DMeshAsset> mesh_asset = _terrain->get_assets()->get_mesh_asset(region_mesh_id);
|
||||
real_t mesh_height_offset = mesh_asset->get_height_offset();
|
||||
for (int c = 0; c < cell_queue.size(); c++) {
|
||||
Vector2i cell = cell_queue[c];
|
||||
for (const Vector2i &cell : cell_queue) {
|
||||
Array triple = cell_inst_dict[cell];
|
||||
TypedArray<Transform3D> xforms = triple[0];
|
||||
PackedColorArray colors = triple[1];
|
||||
|
|
@ -1123,13 +1117,13 @@ void Terrain3DInstancer::update_transforms(const AABB &p_aabb) {
|
|||
} else {
|
||||
// Removed if a hole erased everything
|
||||
cell_inst_dict.erase(cell);
|
||||
_destroy_mmi_by_cell(region_loc, m, cell);
|
||||
_destroy_mmi_by_cell(region_loc, region_mesh_id, cell);
|
||||
}
|
||||
if (cell_inst_dict.is_empty()) {
|
||||
mesh_inst_dict.erase(region_mesh_id);
|
||||
}
|
||||
}
|
||||
update_mmis(m, region_loc);
|
||||
update_mmis(region_mesh_id, region_loc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1157,8 +1151,7 @@ int Terrain3DInstancer::get_closest_mesh_id(const Vector3 &p_global_position) co
|
|||
int closest_id = -1;
|
||||
real_t closest_distance = FLT_MAX;
|
||||
Array mesh_instance_keys = mesh_inst_dict.keys();
|
||||
for (int i = 0; i < mesh_instance_keys.size(); i++) {
|
||||
int mesh_id = mesh_instance_keys[i];
|
||||
for (const int &mesh_id : mesh_instance_keys) {
|
||||
Dictionary cell_inst_dict = mesh_inst_dict[mesh_id];
|
||||
if (!cell_inst_dict.has(cell)) {
|
||||
continue; // No instances in this cell
|
||||
|
|
@ -1171,8 +1164,7 @@ int Terrain3DInstancer::get_closest_mesh_id(const Vector3 &p_global_position) co
|
|||
if (xforms.is_empty()) {
|
||||
continue; // No transforms in this cell
|
||||
}
|
||||
for (int i = 0; i < xforms.size(); i++) {
|
||||
const Transform3D &instance_transform = xforms[i];
|
||||
for (const Transform3D &instance_transform : xforms) {
|
||||
Vector3 instance_origin = instance_transform.origin + region_global_pos; // Convert to global position
|
||||
real_t distance = instance_origin.distance_squared_to(p_global_position);
|
||||
if (distance < closest_distance) {
|
||||
|
|
@ -1218,14 +1210,14 @@ void Terrain3DInstancer::copy_paste_dfr(const Terrain3DRegion *p_src_region, con
|
|||
// For each mesh, for each cell, if in rect, convert xforms to target region space, append to target region.
|
||||
Dictionary mesh_inst_dict = p_src_region->get_instances();
|
||||
Array mesh_types = mesh_inst_dict.keys();
|
||||
for (int m = 0; m < mesh_types.size(); m++) {
|
||||
for (const int &mesh_id : mesh_types) {
|
||||
TypedArray<Transform3D> xforms;
|
||||
PackedColorArray colors;
|
||||
Dictionary cell_inst_dict = p_src_region->get_instances()[m];
|
||||
Dictionary cell_inst_dict = p_src_region->get_instances()[mesh_id];
|
||||
Array cell_locs = cell_inst_dict.keys();
|
||||
for (int c = 0; c < cell_locs.size(); c++) {
|
||||
if (cells_to_copy.has(cell_locs[c])) {
|
||||
Array triple = cell_inst_dict[cell_locs[c]];
|
||||
for (const Vector2i &cell : cell_locs) {
|
||||
if (cells_to_copy.has(cell)) {
|
||||
Array triple = cell_inst_dict[cell];
|
||||
TypedArray<Transform3D> cell_xforms = triple[0];
|
||||
PackedColorArray cell_colors = triple[1];
|
||||
for (int i = 0; i < cell_xforms.size(); i++) {
|
||||
|
|
@ -1239,7 +1231,7 @@ void Terrain3DInstancer::copy_paste_dfr(const Terrain3DRegion *p_src_region, con
|
|||
if (xforms.size() == 0) {
|
||||
continue;
|
||||
}
|
||||
append_region(Ref<Terrain3DRegion>(p_dst_region), m, xforms, colors, false);
|
||||
append_region(Ref<Terrain3DRegion>(p_dst_region), mesh_id, xforms, colors, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1252,8 +1244,7 @@ void Terrain3DInstancer::swap_ids(const int p_src_id, const int p_dst_id) {
|
|||
LOG(INFO, "Swapping IDs of multimeshes: ", p_src_id, " and ", p_dst_id);
|
||||
if (p_src_id >= 0 && p_src_id < mesh_count && p_dst_id >= 0 && p_dst_id < mesh_count) {
|
||||
TypedArray<Vector2i> region_locations = _terrain->get_data()->get_region_locations();
|
||||
for (int i = 0; i < region_locations.size(); i++) {
|
||||
Vector2i region_loc = region_locations[i];
|
||||
for (const Vector2i ®ion_loc : region_locations) {
|
||||
Ref<Terrain3DRegion> region = _terrain->get_data()->get_region(region_loc);
|
||||
if (region.is_null()) {
|
||||
LOG(WARN, "No region found at: ", region_loc);
|
||||
|
|
@ -1339,17 +1330,17 @@ void Terrain3DInstancer::update_mmis(const int p_mesh_id, const Vector2i &p_regi
|
|||
void Terrain3DInstancer::dump_mmis() {
|
||||
LOG(WARN, "Dumping MMI tree and node containers");
|
||||
LOG(MESG, "_mmi_containers size: ", int(_mmi_containers.size()));
|
||||
for (auto &it : _mmi_containers) {
|
||||
for (const auto &it : _mmi_containers) {
|
||||
LOG(MESG, "_mmi_containers region: ", it.first, ", node ptr: ", ptr_to_str(it.second));
|
||||
}
|
||||
LOG(MESG, "_mmi tree: ");
|
||||
_terrain->get_mmi_parent()->print_tree();
|
||||
LOG(MESG, "_mmi_nodes size: ", int(_mmi_nodes.size()));
|
||||
for (auto &i : _mmi_nodes) {
|
||||
for (const auto &i : _mmi_nodes) {
|
||||
LOG(MESG, "_mmi_nodes region: ", i.first, ", dict ptr: ", ptr_to_str(&i.second));
|
||||
for (auto &j : i.second) {
|
||||
for (const auto &j : i.second) {
|
||||
LOG(MESG, "mesh_mmi_dict mesh: ", j.first, ", dict ptr: ", ptr_to_str(&j.second));
|
||||
for (auto &k : j.second) {
|
||||
for (const auto &k : j.second) {
|
||||
LOG(MESG, "cell_mmi_dict cell: ", k.first, ", mmi ptr: ", ptr_to_str(k.second));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -49,8 +49,8 @@ void Terrain3DMaterial::_preload_shaders() {
|
|||
|
||||
if (Terrain3D::debug_level >= DEBUG) {
|
||||
Array keys = _shader_code.keys();
|
||||
for (int i = 0; i < keys.size(); i++) {
|
||||
LOG(DEBUG, "Loaded shader insert: ", keys[i]);
|
||||
for (const StringName &key : keys) {
|
||||
LOG(DEBUG, "Loaded shader insert: ", key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -285,8 +285,8 @@ String Terrain3DMaterial::_inject_editor_code(const String &p_shader) const {
|
|||
insert_names.push_back("OVERLAY_CONTOURS_SETUP");
|
||||
}
|
||||
// Apply pending inserts
|
||||
for (int i = 0; i < insert_names.size(); i++) {
|
||||
String insert = _shader_code[insert_names[i]];
|
||||
for (const String &name : insert_names) {
|
||||
String insert = _shader_code[name];
|
||||
shader = shader.insert(idx, "\n" + insert);
|
||||
idx += insert.length();
|
||||
}
|
||||
|
|
@ -381,8 +381,8 @@ String Terrain3DMaterial::_inject_editor_code(const String &p_shader) const {
|
|||
insert_names.push_back("EDITOR_DECAL_RENDER");
|
||||
}
|
||||
// Apply pending inserts
|
||||
for (int i = 0; i < insert_names.size(); i++) {
|
||||
String insert = _shader_code[insert_names[i]];
|
||||
for (const String &name : insert_names) {
|
||||
String insert = _shader_code[name];
|
||||
shader = shader.insert(idx, "\n" + insert);
|
||||
idx += insert.length();
|
||||
}
|
||||
|
|
@ -422,8 +422,7 @@ void Terrain3DMaterial::_update_shader() {
|
|||
}
|
||||
|
||||
// Fetch saved shader parameters, converting textures to RIDs
|
||||
for (int i = 0; i < _active_params.size(); i++) {
|
||||
StringName param = _active_params[i];
|
||||
for (const StringName ¶m : _active_params) {
|
||||
Variant value = _shader_params[param];
|
||||
if (value.get_type() == Variant::OBJECT) {
|
||||
Ref<Texture> tex = value;
|
||||
|
|
@ -796,19 +795,13 @@ Error Terrain3DMaterial::save(const String &p_path) {
|
|||
|
||||
// Remove saved shader params that don't exist in either shader
|
||||
Array keys = _shader_params.keys();
|
||||
for (int i = 0; i < keys.size(); i++) {
|
||||
for (const StringName &name : keys) {
|
||||
bool has = false;
|
||||
StringName name = keys[i];
|
||||
for (int j = 0; j < param_list.size(); j++) {
|
||||
Dictionary dict;
|
||||
StringName dname;
|
||||
if (j < param_list.size()) {
|
||||
dict = param_list[j];
|
||||
dname = dict["name"];
|
||||
if (name == dname) {
|
||||
has = true;
|
||||
break;
|
||||
}
|
||||
for (const Dictionary &dict : param_list) {
|
||||
StringName dname = dict["name"];
|
||||
if (name == dname) {
|
||||
has = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!has) {
|
||||
|
|
@ -850,8 +843,7 @@ void Terrain3DMaterial::_get_property_list(List<PropertyInfo> *p_list) const {
|
|||
}
|
||||
|
||||
_active_params.clear();
|
||||
for (int i = 0; i < param_list.size(); i++) {
|
||||
Dictionary dict = param_list[i];
|
||||
for (const Dictionary &dict : param_list) {
|
||||
StringName name = dict["name"];
|
||||
|
||||
// Filter out private uniforms that start with _
|
||||
|
|
|
|||
|
|
@ -253,12 +253,10 @@ void Terrain3DMesher::_generate_offset_data(const int p_size) {
|
|||
// Frees all clipmap instance RIDs. Mesh rids must be freed seperatley.
|
||||
void Terrain3DMesher::_clear_clipmap() {
|
||||
LOG(INFO, "Freeing all clipmap instances");
|
||||
for (int lod = 0; lod < _clipmap_rids.size(); lod++) {
|
||||
Array lod_array = _clipmap_rids[lod];
|
||||
for (int mesh = 0; mesh < lod_array.size(); mesh++) {
|
||||
Array mesh_array = lod_array[mesh];
|
||||
for (int instance = 0; instance < mesh_array.size(); instance++) {
|
||||
RS->free_rid(mesh_array[instance]);
|
||||
for (Array lod_array : _clipmap_rids) {
|
||||
for (Array mesh_array : lod_array) {
|
||||
for (const RID &rid : mesh_array) {
|
||||
RS->free_rid(rid);
|
||||
}
|
||||
mesh_array.clear();
|
||||
}
|
||||
|
|
@ -271,8 +269,8 @@ void Terrain3DMesher::_clear_clipmap() {
|
|||
// Frees all Mesh RIDs use for clipmap instances.
|
||||
void Terrain3DMesher::_clear_mesh_types() {
|
||||
LOG(INFO, "Freeing all clipmap meshes");
|
||||
for (int m = 0; m < _mesh_rids.size(); m++) {
|
||||
RS->free_rid(_mesh_rids[m]);
|
||||
for (const RID &rid : _mesh_rids) {
|
||||
RS->free_rid(rid);
|
||||
}
|
||||
_mesh_rids.clear();
|
||||
return;
|
||||
|
|
@ -432,17 +430,15 @@ void Terrain3DMesher::update() {
|
|||
bool visible = _terrain->is_visible_in_tree();
|
||||
|
||||
LOG(INFO, "Updating all mesh instances for ", _clipmap_rids.size(), " LODs");
|
||||
for (int lod = 0; lod < _clipmap_rids.size(); ++lod) {
|
||||
Array lod_array = _clipmap_rids[lod];
|
||||
for (int mesh = 0; mesh < lod_array.size(); ++mesh) {
|
||||
Array mesh_array = lod_array[mesh];
|
||||
for (int instance = 0; instance < mesh_array.size(); ++instance) {
|
||||
RS->instance_set_visible(mesh_array[instance], visible);
|
||||
RS->instance_set_scenario(mesh_array[instance], scenario);
|
||||
RS->instance_set_layer_mask(mesh_array[instance], render_layers);
|
||||
RS->instance_geometry_set_cast_shadows_setting(mesh_array[instance], cast_shadows);
|
||||
RS->instance_geometry_set_flag(mesh_array[instance], RenderingServer::INSTANCE_FLAG_USE_BAKED_LIGHT, baked_light);
|
||||
RS->instance_geometry_set_flag(mesh_array[instance], RenderingServer::INSTANCE_FLAG_USE_DYNAMIC_GI, dynamic_gi);
|
||||
for (Array lod_array : _clipmap_rids) {
|
||||
for (Array mesh_array : lod_array) {
|
||||
for (const RID &rid : mesh_array) {
|
||||
RS->instance_set_visible(rid, visible);
|
||||
RS->instance_set_scenario(rid, scenario);
|
||||
RS->instance_set_layer_mask(rid, render_layers);
|
||||
RS->instance_geometry_set_cast_shadows_setting(rid, cast_shadows);
|
||||
RS->instance_geometry_set_flag(rid, RenderingServer::INSTANCE_FLAG_USE_BAKED_LIGHT, baked_light);
|
||||
RS->instance_geometry_set_flag(rid, RenderingServer::INSTANCE_FLAG_USE_DYNAMIC_GI, dynamic_gi);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -458,12 +454,11 @@ void Terrain3DMesher::update_aabbs() {
|
|||
height_range.y += abs(height_range.x);
|
||||
|
||||
LOG(INFO, "Updating ", _mesh_rids.size(), " meshes AABBs")
|
||||
for (int m = 0; m < _mesh_rids.size(); m++) {
|
||||
RID mesh = _mesh_rids[m];
|
||||
AABB aabb = RS->mesh_get_custom_aabb(mesh);
|
||||
for (const RID &rid : _mesh_rids) {
|
||||
AABB aabb = RS->mesh_get_custom_aabb(rid);
|
||||
aabb.position.y = height_range.x - cull_margin;
|
||||
aabb.size.y = height_range.y + cull_margin * 2.f;
|
||||
RS->mesh_set_custom_aabb(mesh, aabb);
|
||||
RS->mesh_set_custom_aabb(rid, aabb);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -389,13 +389,11 @@ void Terrain3DRegion::dump(const bool verbose) const {
|
|||
", Color map: ", ptr_to_str(*_color_map));
|
||||
LOG(MESG, "Instances: Mesh IDs: ", _instances.size(), ", ", ptr_to_str(_instances._native_ptr()));
|
||||
Array mesh_ids = _instances.keys();
|
||||
for (int m = 0; m < mesh_ids.size(); m++) {
|
||||
int mesh_id = mesh_ids[m];
|
||||
for (const int &mesh_id : mesh_ids) {
|
||||
int counter = 0;
|
||||
Dictionary cell_inst_dict = _instances[mesh_id];
|
||||
Array cells = cell_inst_dict.keys();
|
||||
for (int c = 0; c < cells.size(); c++) {
|
||||
Vector2i cell = cells[c];
|
||||
for (const Vector2i &cell : cells) {
|
||||
Array triple = cell_inst_dict[cell];
|
||||
if (triple.size() == 3) {
|
||||
counter += Array(triple[0]).size();
|
||||
|
|
|
|||
|
|
@ -42,25 +42,25 @@ void Terrain3DUtil::print_arr(const String &p_name, const Array &p_arr, const in
|
|||
void Terrain3DUtil::print_dict(const String &p_name, const Dictionary &p_dict, const int p_level) {
|
||||
LOG(p_level, "Dictionary: ", p_name);
|
||||
Array keys = p_dict.keys();
|
||||
for (int i = 0; i < keys.size(); i++) {
|
||||
Variant var = p_dict[keys[i]];
|
||||
for (const StringName &key : keys) {
|
||||
Variant var = p_dict[key];
|
||||
switch (var.get_type()) {
|
||||
case Variant::ARRAY: {
|
||||
print_arr(String(keys[i]), var, p_level);
|
||||
print_arr(String(key), var, p_level);
|
||||
break;
|
||||
}
|
||||
case Variant::DICTIONARY: {
|
||||
print_dict(String(keys[i]), var, p_level);
|
||||
print_dict(String(key), var, p_level);
|
||||
break;
|
||||
}
|
||||
case Variant::OBJECT: {
|
||||
Object *obj = cast_to<Object>(var);
|
||||
String str = "Object#" + String::num_uint64(obj->get_instance_id()) + ", " + ptr_to_str(obj);
|
||||
LOG(p_level, "\"", keys[i], "\": ", str);
|
||||
LOG(p_level, "\"", key, "\": ", str);
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
LOG(p_level, "\"", keys[i], "\": Value: ", var);
|
||||
LOG(p_level, "\"", key, "\": Value: ", var);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -74,9 +74,8 @@ void Terrain3DUtil::dump_gentex(const GeneratedTexture &p_gen, const String &p_n
|
|||
|
||||
void Terrain3DUtil::dump_maps(const TypedArray<Image> &p_maps, const String &p_name) {
|
||||
LOG(MESG, "Dumping ", p_name, " array. Size: ", p_maps.size());
|
||||
for (int i = 0; i < p_maps.size(); i++) {
|
||||
Ref<Image> img = p_maps[i];
|
||||
LOG(MESG, "[", i, "]: Map size: ", img->get_size(), ", format: ", img->get_format(),
|
||||
for (const Ref<Image> &img : p_maps) {
|
||||
LOG(MESG, "Map size: ", img->get_size(), ", format: ", img->get_format(),
|
||||
", ", ptr_to_str(*img));
|
||||
}
|
||||
}
|
||||
|
|
@ -121,8 +120,8 @@ PackedStringArray Terrain3DUtil::get_files(const String &p_dir, const String &p_
|
|||
return files;
|
||||
}
|
||||
PackedStringArray dir_files = da->get_files();
|
||||
for (int i = 0; i < dir_files.size(); i++) {
|
||||
String fname = dir_files[i].trim_suffix(".remap");
|
||||
for (const String &file_name : dir_files) {
|
||||
String fname = file_name.trim_suffix(".remap");
|
||||
if (!fname.matchn(p_glob)) {
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue