diff --git a/src/noggit/MapChunk.cpp b/src/noggit/MapChunk.cpp index 88dc14b47..9a543a472 100644 --- a/src/noggit/MapChunk.cpp +++ b/src/noggit/MapChunk.cpp @@ -1079,12 +1079,19 @@ void MapChunk::eraseTextures() texture_set_changed(); texture_set->eraseTextures(); } + void MapChunk::remove_texture_duplicates() { texture_set_changed(); texture_set->removeDuplicate(); } +void MapChunk::remove_unused_textures(float threshold) +{ + texture_set_changed(); + texture_set->eraseUnusedTextures(threshold); +} + void MapChunk::change_texture_flag(scoped_blp_texture_reference const& tex, std::size_t flag, bool add) { texture_set_changed(); diff --git a/src/noggit/MapChunk.h b/src/noggit/MapChunk.h index 2afcde736..386535e9b 100644 --- a/src/noggit/MapChunk.h +++ b/src/noggit/MapChunk.h @@ -217,6 +217,7 @@ class MapChunk void switchTexture(scoped_blp_texture_reference const& oldTexture, scoped_blp_texture_reference newTexture); void eraseTextures(); void remove_texture_duplicates(); + void remove_unused_textures(float threshold); void change_texture_flag(scoped_blp_texture_reference const& tex, std::size_t flag, bool add); void clear_texture_flags(); diff --git a/src/noggit/World.cpp b/src/noggit/World.cpp index d841da3a7..e2b907d36 100644 --- a/src/noggit/World.cpp +++ b/src/noggit/World.cpp @@ -2036,15 +2036,16 @@ bool World::replaceTexture(math::vector_3d const& pos, float radius, scoped_blp_ } void World::clear_on_chunks ( math::vector_3d const& pos, float radius, bool height, bool textures, bool duplicate_textures - , bool texture_flags, bool liquids, bool m2s, bool wmos, bool shadows, bool mccv, bool impassible_flag, bool holes + , bool textures_below_threshold, float alpha_threshold, bool texture_flags, bool liquids + , bool m2s, bool wmos, bool shadows, bool mccv, bool impassible_flag, bool holes ) { for_all_chunks_in_range ( pos, radius , [&](MapChunk* chunk) { - clear_on_chunk ( chunk, height, textures, duplicate_textures, texture_flags - , liquids, shadows, mccv, impassible_flag, holes + clear_on_chunk ( chunk, height, textures, duplicate_textures, textures_below_threshold, alpha_threshold + , texture_flags, liquids, shadows, mccv, impassible_flag, holes ); return true; } @@ -2059,7 +2060,8 @@ void World::clear_on_chunks ( math::vector_3d const& pos, float radius, bool hei } } void World::clear_on_tiles ( math::vector_3d const& pos, float radius, bool height, bool textures, bool duplicate_textures - , bool texture_flags, bool liquids, bool m2s, bool wmos, bool shadows, bool mccv, bool impassible_flag, bool holes + , bool textures_below_threshold, float alpha_threshold, bool texture_flags, bool liquids + , bool m2s, bool wmos, bool shadows, bool mccv, bool impassible_flag, bool holes ) { for_all_tiles_in_range @@ -2075,8 +2077,8 @@ void World::clear_on_tiles ( math::vector_3d const& pos, float radius, bool heig for_all_chunks_on_tile({ tile->xbase + CHUNKSIZE, 0.f, tile->zbase + CHUNKSIZE }, [&](MapChunk* chunk) { - clear_on_chunk ( chunk, height, textures, duplicate_textures, texture_flags - , liquids, shadows, mccv, impassible_flag, holes + clear_on_chunk ( chunk, height, textures, duplicate_textures, textures_below_threshold, alpha_threshold + , texture_flags, liquids, shadows, mccv, impassible_flag, holes ); return true; } @@ -2088,7 +2090,8 @@ void World::clear_on_tiles ( math::vector_3d const& pos, float radius, bool heig } void World::clear_on_chunk( MapChunk* chunk, bool height, bool textures, bool duplicate_textures - , bool texture_flags, bool liquids, bool shadows, bool mccv, bool impassible_flag, bool holes + , bool textures_below_threshold, float alpha_threshold, bool texture_flags + , bool liquids, bool shadows, bool mccv, bool impassible_flag, bool holes ) { if (height) @@ -2103,6 +2106,10 @@ void World::clear_on_chunk( MapChunk* chunk, bool height, bool textures, bool du { chunk->remove_texture_duplicates(); } + if (textures_below_threshold) + { + chunk->remove_unused_textures(alpha_threshold); + } if (texture_flags) { chunk->clear_texture_flags(); diff --git a/src/noggit/World.h b/src/noggit/World.h index 0cc84c9f1..5bd4aabe1 100644 --- a/src/noggit/World.h +++ b/src/noggit/World.h @@ -259,11 +259,13 @@ class World bool sprayTexture(math::vector_3d const& pos, Brush *brush, float strength, float pressure, float spraySize, float sprayPressure, scoped_blp_texture_reference texture); bool replaceTexture(math::vector_3d const& pos, float radius, scoped_blp_texture_reference const& old_texture, scoped_blp_texture_reference new_texture); - void clear_on_chunks ( math::vector_3d const& pos, float radius, bool height, bool textures, bool duplicate_textures, bool texture_flags - , bool liquids, bool m2s, bool wmos, bool shadows, bool mccv, bool impassible_flag, bool holes + void clear_on_chunks ( math::vector_3d const& pos, float radius, bool height, bool textures, bool duplicate_textures + , bool textures_below_threshold, float alpha_threshold, bool texture_flags, bool liquids + , bool m2s, bool wmos, bool shadows, bool mccv, bool impassible_flag, bool holes ); - void clear_on_tiles ( math::vector_3d const& pos, float radius, bool height, bool textures, bool duplicate_textures, bool texture_flags - , bool liquids, bool m2s, bool wmos, bool shadows, bool mccv, bool impassible_flag, bool holes + void clear_on_tiles ( math::vector_3d const& pos, float radius, bool height, bool textures, bool duplicate_textures + , bool textures_below_threshold, float alpha_threshold, bool texture_flags, bool liquids + , bool m2s, bool wmos, bool shadows, bool mccv, bool impassible_flag, bool holes ); void eraseTextures(math::vector_3d const& pos); @@ -386,9 +388,11 @@ class World private: void clear_on_chunk( MapChunk* chunk, bool height, bool textures, bool duplicate_textures - , bool texture_flags, bool liquids, bool shadows, bool mccv, bool impassible_flag, bool holes + , bool textures_below_threshold, float alpha_threshold, bool texture_flags, bool liquids + , bool shadows, bool mccv, bool impassible_flag, bool holes ); + void update_models_by_filename(); bool _need_wmo_liquid_update = true; diff --git a/src/noggit/texture_set.cpp b/src/noggit/texture_set.cpp index 8f4195abe..5c7b6db21 100644 --- a/src/noggit/texture_set.cpp +++ b/src/noggit/texture_set.cpp @@ -306,13 +306,20 @@ math::vector_3d TextureSet::anim_param(int layer) const return { -anim_dir_x[dir_index], anim_dir_y[dir_index], speed }; } -bool TextureSet::eraseUnusedTextures() +bool TextureSet::eraseUnusedTextures(float threshold) { + if (threshold >= 255.f) + { + eraseTextures(); + } + if (nTextures < 2) { return false; } + int i_threshold = static_cast(threshold); + std::set visible_tex; if (tmp_edit_values) @@ -325,7 +332,7 @@ bool TextureSet::eraseUnusedTextures() { // use 0.01 to account for floating point imprecision // while not preventing very low pressure brush from painting correctly - if (amaps[layer][i] > 0.01f) + if (amaps[layer][i] >= threshold) { visible_tex.emplace(layer); break; // texture visible, go to the next layer @@ -342,7 +349,7 @@ bool TextureSet::eraseUnusedTextures() { uint8_t a = alphamaps[n]->getAlpha(i); sum += a; - if (a > 0) + if (a > i_threshold) { visible_tex.emplace(n + 1); } diff --git a/src/noggit/texture_set.hpp b/src/noggit/texture_set.hpp index 717e21455..2c1acf6ed 100644 --- a/src/noggit/texture_set.hpp +++ b/src/noggit/texture_set.hpp @@ -45,7 +45,7 @@ class TextureSet void eraseTexture(size_t id); void eraseTextures(); // return true if at least 1 texture has been erased - bool eraseUnusedTextures(); + bool eraseUnusedTextures(float threshold = 0.01f); void swap_layers(int layer_1, int layer_2); void replace_texture(scoped_blp_texture_reference const& texture_to_replace, scoped_blp_texture_reference replacement_texture); bool paintTexture(float xbase, float zbase, float x, float z, Brush* brush, float strength, float pressure, scoped_blp_texture_reference texture); diff --git a/src/noggit/ui/clearing_tool.cpp b/src/noggit/ui/clearing_tool.cpp index 6b4de1535..304fb4050 100644 --- a/src/noggit/ui/clearing_tool.cpp +++ b/src/noggit/ui/clearing_tool.cpp @@ -25,9 +25,11 @@ namespace noggit clearing_tool::clearing_tool(QWidget* parent) : QWidget(parent) , _radius(15.0f) + , _texture_threshold(1.0f) , _clear_height(false) , _clear_textures(false) , _clear_duplicate_textures(false) + , _clear_textures_under_threshold(false) , _clear_texture_flags(false) , _clear_liquids(false) , _clear_m2s(false) @@ -46,6 +48,7 @@ namespace noggit clearing_option_layout->addWidget(new checkbox("Height", &_clear_height, clearing_option_group)); clearing_option_layout->addWidget(new checkbox("Textures", &_clear_textures, clearing_option_group)); clearing_option_layout->addWidget(new checkbox("Texture Duplicates", &_clear_duplicate_textures, clearing_option_group)); + clearing_option_layout->addWidget(new checkbox("Textures below Threshold", &_clear_textures_under_threshold, clearing_option_group)); clearing_option_layout->addWidget(new checkbox("Liquids", &_clear_liquids, clearing_option_group)); clearing_option_layout->addWidget(new checkbox("M2s", &_clear_m2s, clearing_option_group)); clearing_option_layout->addWidget(new checkbox("WMOs", &_clear_wmos, clearing_option_group)); @@ -79,18 +82,36 @@ namespace noggit layout->addRow(mode_option_group); - _radius_spin = new QDoubleSpinBox (this); + auto parameters_group(new QGroupBox("Parameters", this)); + auto parameters_layout(new QFormLayout(parameters_group)); + + _radius_spin = new QDoubleSpinBox (parameters_group); _radius_spin->setRange (0.0f, 1000.0f); - _radius_spin->setDecimals (2); + _radius_spin->setDecimals(2); _radius_spin->setValue (_radius); - layout->addRow ("Radius:", _radius_spin); + parameters_layout->addRow("Radius:", _radius_spin); - _radius_slider = new QSlider (Qt::Orientation::Horizontal, this); + _radius_slider = new QSlider (Qt::Orientation::Horizontal, parameters_group); _radius_slider->setRange (0, 1000); _radius_slider->setSliderPosition (_radius); - layout->addRow (_radius_slider); + parameters_layout->addRow(_radius_slider); + + _texture_threshold_spin = new QDoubleSpinBox(parameters_group); + _texture_threshold_spin->setRange(0., 255.); + _texture_threshold_spin->setValue(_texture_threshold); + + parameters_layout->addRow("Texture Alpha Threshold:", _texture_threshold_spin); + + _texture_threshold_slider = new QSlider(Qt::Orientation::Horizontal, parameters_group); + _texture_threshold_slider->setRange(0, 255); + _texture_threshold_slider->setSliderPosition(_texture_threshold); + + parameters_layout->addRow(_texture_threshold_slider); + + + layout->addRow(parameters_group); @@ -112,6 +133,22 @@ namespace noggit } ); + connect ( _texture_threshold_spin, qOverload (&QDoubleSpinBox::valueChanged) + , [&] (double v) + { + _texture_threshold = v; + QSignalBlocker const blocker(_texture_threshold_slider); + _texture_threshold_slider->setSliderPosition((int)std::round(v)); + } + ); + connect ( _texture_threshold_slider, &QSlider::valueChanged + , [&] (int v) + { + _texture_threshold = v; + QSignalBlocker const blocker(_texture_threshold_spin); + _texture_threshold_spin->setValue(v); + } + ); setMinimumWidth(sizeHint().width()); } @@ -125,6 +162,8 @@ namespace noggit , _clear_height.get() , _clear_textures.get() , _clear_duplicate_textures.get() + , _clear_textures_under_threshold.get() + , _texture_threshold , _clear_texture_flags.get() , _clear_liquids.get() , _clear_m2s.get() @@ -142,6 +181,8 @@ namespace noggit , _clear_height.get() , _clear_textures.get() , _clear_duplicate_textures.get() + , _clear_textures_under_threshold.get() + , _texture_threshold , _clear_texture_flags.get() , _clear_liquids.get() , _clear_m2s.get() diff --git a/src/noggit/ui/clearing_tool.hpp b/src/noggit/ui/clearing_tool.hpp index 9e285ae72..5af2d6a1d 100644 --- a/src/noggit/ui/clearing_tool.hpp +++ b/src/noggit/ui/clearing_tool.hpp @@ -30,11 +30,13 @@ namespace noggit private: float _radius; + float _texture_threshold; int _mode = 0; bool_toggle_property _clear_height; bool_toggle_property _clear_textures; bool_toggle_property _clear_duplicate_textures; + bool_toggle_property _clear_textures_under_threshold; bool_toggle_property _clear_texture_flags; bool_toggle_property _clear_liquids; bool_toggle_property _clear_m2s; @@ -46,6 +48,8 @@ namespace noggit QSlider* _radius_slider; QDoubleSpinBox* _radius_spin; + QSlider* _texture_threshold_slider; + QDoubleSpinBox* _texture_threshold_spin; }; }