ground effect editor progress
support detail doodads exclusion painting implement actions
This commit is contained in:
@@ -74,7 +74,7 @@ void Noggit::Action::undo(bool redo)
|
||||
auto texture_set = pair.first->getTextureSet();
|
||||
*texture_set->getAlphamaps() = pair.second.alphamaps;
|
||||
*texture_set->getTempAlphamaps() = pair.second.tmp_edit_values;
|
||||
std::memcpy(texture_set->getMCLYEntries(), &pair.second.layers_info, sizeof(ENTRY_MCLY) * 4);
|
||||
std::memcpy(texture_set->getMCLYEntries(), &pair.second.layers_info, sizeof(layer_info) * 4);
|
||||
texture_set->setNTextures(pair.second.n_textures);
|
||||
|
||||
auto textures = texture_set->getTextures();
|
||||
@@ -88,6 +88,7 @@ void Noggit::Action::undo(bool redo)
|
||||
|
||||
texture_set->markDirty();
|
||||
texture_set->apply_alpha_changes();
|
||||
pair.first->registerChunkUpdate(ChunkUpdateFlags::FLAGS); // for texture anim flags
|
||||
}
|
||||
}
|
||||
if (_flags & ActionFlags::eCHUNKS_VERTEX_COLOR)
|
||||
@@ -200,6 +201,28 @@ void Noggit::Action::undo(bool redo)
|
||||
pair.first->update_shadows();
|
||||
}
|
||||
}
|
||||
if (_flags & ActionFlags::eCHUNK_DOODADS_EXCLUSION)
|
||||
{
|
||||
for (auto& pair : redo ? _chunk_detaildoodad_exclusion_post : _chunk_detaildoodad_exclusion_pre)
|
||||
{
|
||||
std::memcpy(&pair.first->texture_set->_doodadStencil, pair.second.data(), 8 * sizeof(std::uint8_t));
|
||||
|
||||
pair.first->registerChunkUpdate(ChunkUpdateFlags::DETAILDOODADS_EXCLUSION);
|
||||
}
|
||||
}
|
||||
if (_flags & ActionFlags::eCHUNKS_LAYERINFO)
|
||||
{
|
||||
for (auto& pair : redo ? _chunk_layerinfos_post : _chunk_layerinfos_pre)
|
||||
{
|
||||
auto texture_set = pair.first->getTextureSet();
|
||||
std::memcpy(texture_set->getMCLYEntries(), &pair.second, sizeof(layer_info) * 4);
|
||||
|
||||
// TODO, enable this if texture flags get moved to this action flag.
|
||||
// pair.first->registerChunkUpdate(ChunkUpdateFlags::FLAGS); // for texture anim flags.
|
||||
|
||||
pair.first->registerChunkUpdate(ChunkUpdateFlags::GROUND_EFFECT);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -386,7 +409,7 @@ void Noggit::Action::finish()
|
||||
cache.n_textures = texture_set->num();
|
||||
cache.alphamaps = *texture_set->getAlphamaps();
|
||||
cache.tmp_edit_values = *texture_set->getTempAlphamaps();
|
||||
std::memcpy(&cache.layers_info, texture_set->getMCLYEntries(), sizeof(ENTRY_MCLY) * 4);
|
||||
std::memcpy(&cache.layers_info, texture_set->getMCLYEntries(), sizeof(layer_info) * 4);
|
||||
|
||||
for (int j = 0; j < cache.n_textures; ++j)
|
||||
{
|
||||
@@ -578,14 +601,16 @@ void Noggit::Action::registerChunkTextureChange(MapChunk* chunk)
|
||||
cache.n_textures = texture_set->num();
|
||||
cache.alphamaps = *texture_set->getAlphamaps();
|
||||
cache.tmp_edit_values = *texture_set->getTempAlphamaps();
|
||||
std::memcpy(&cache.layers_info, texture_set->getMCLYEntries(), sizeof(ENTRY_MCLY) * 4);
|
||||
std::memcpy(&cache.layers_info, texture_set->getMCLYEntries(), sizeof(layer_info) * 4);
|
||||
|
||||
for (int i = 0; i < cache.n_textures; ++i)
|
||||
{
|
||||
cache.textures.push_back(texture_set->filename(i));
|
||||
}
|
||||
// _chunk_texture_pre.emplace_back(std::make_pair(chunk, std::move( cache)));
|
||||
|
||||
_chunk_texture_pre.emplace_back(std::make_pair(chunk, std::move(cache)));
|
||||
auto cache_pair = std::make_pair(chunk, std::move(cache));
|
||||
_chunk_texture_pre.emplace_back(std::move(cache_pair));
|
||||
}
|
||||
|
||||
void Noggit::Action::registerChunkVertexColorChange(MapChunk* chunk)
|
||||
@@ -742,6 +767,36 @@ void Noggit::Action::registerChunkShadowChange(MapChunk *chunk)
|
||||
_chunk_shadow_map_pre.emplace_back(std::make_pair(chunk, std::move(data)));
|
||||
}
|
||||
|
||||
void Noggit::Action::registerChunkLayerInfoChange(MapChunk* chunk)
|
||||
{
|
||||
_flags |= ActionFlags::eCHUNKS_LAYERINFO;
|
||||
|
||||
for (auto& pair : _chunk_layerinfos_pre)
|
||||
{
|
||||
if (pair.first == chunk)
|
||||
return;
|
||||
}
|
||||
std::array<layer_info, 4> layer_infos{};
|
||||
std::memcpy(&layer_infos, chunk->texture_set->getMCLYEntries(), sizeof(layer_info) * 4);
|
||||
|
||||
_chunk_layerinfos_pre.emplace_back(chunk, std::move(layer_infos));
|
||||
}
|
||||
|
||||
void Noggit::Action::registerChunkDetailDoodadExclusionChange(MapChunk* chunk)
|
||||
{
|
||||
_flags |= ActionFlags::eCHUNK_DOODADS_EXCLUSION;
|
||||
|
||||
for (auto& pair : _chunk_detaildoodad_exclusion_pre)
|
||||
{
|
||||
if (pair.first == chunk)
|
||||
return;
|
||||
}
|
||||
std::array<std::uint8_t, 8> data{};
|
||||
std::memcpy(&data, chunk->texture_set->getDoodadStencilBase(), sizeof(std::uint8_t) * 8);
|
||||
|
||||
_chunk_detaildoodad_exclusion_pre.emplace_back(std::make_pair(chunk, data));
|
||||
}
|
||||
|
||||
void Noggit::Action::registerAllChunkChanges(MapChunk* chunk)
|
||||
{
|
||||
registerChunkTerrainChange(chunk);
|
||||
@@ -753,6 +808,8 @@ void Noggit::Action::registerAllChunkChanges(MapChunk* chunk)
|
||||
registerChunkLiquidChange(chunk);
|
||||
registerVertexSelectionChange();
|
||||
registerChunkShadowChange(chunk);
|
||||
registerChunkLayerInfoChange(chunk);
|
||||
registerChunkDetailDoodadExclusionChange(chunk);
|
||||
}
|
||||
|
||||
Noggit::Action::~Action()
|
||||
|
||||
@@ -39,7 +39,9 @@ namespace Noggit
|
||||
eCHUNKS_FLAGS = 0x200,
|
||||
eVERTEX_SELECTION = 0x400,
|
||||
eCHUNK_SHADOWS = 0x800,
|
||||
eDO_NOT_WRITE_HISTORY= 0x1000
|
||||
eDO_NOT_WRITE_HISTORY= 0x1000,
|
||||
eCHUNK_DOODADS_EXCLUSION = 0x2000, // ground effects exclusion mapping
|
||||
eCHUNKS_LAYERINFO = 0x4000 // ground effect id and texture flags
|
||||
};
|
||||
|
||||
enum ActionModalityControllers
|
||||
@@ -71,7 +73,7 @@ namespace Noggit
|
||||
std::vector<std::string> textures;
|
||||
std::array<std::optional<Alphamap>, 3> alphamaps;
|
||||
std::optional<tmp_edit_alpha_values> tmp_edit_values;
|
||||
ENTRY_MCLY layers_info[4];
|
||||
layer_info layers_info[4];
|
||||
};
|
||||
|
||||
struct ObjectInstanceCache
|
||||
@@ -135,6 +137,8 @@ namespace Noggit
|
||||
void registerChunkLiquidChange(MapChunk* chunk);
|
||||
void registerVertexSelectionChange();
|
||||
void registerChunkShadowChange(MapChunk* chunk);
|
||||
void registerChunkLayerInfoChange(MapChunk* chunk);
|
||||
void registerChunkDetailDoodadExclusionChange(MapChunk* chunk);
|
||||
void registerAllChunkChanges(MapChunk* chunk);
|
||||
|
||||
|
||||
@@ -161,6 +165,10 @@ namespace Noggit
|
||||
std::vector<std::pair<MapChunk*, int>> _chunk_holes_post;
|
||||
std::vector<std::pair<MapChunk*, int>> _chunk_area_id_pre;
|
||||
std::vector<std::pair<MapChunk*, int>> _chunk_area_id_post;
|
||||
std::vector<std::pair<MapChunk*, std::array<layer_info, 4>>> _chunk_layerinfos_pre;
|
||||
std::vector<std::pair<MapChunk*, std::array<layer_info, 4>>> _chunk_layerinfos_post;
|
||||
std::vector<std::pair<MapChunk*, std::array<std::uint8_t, 8>>> _chunk_detaildoodad_exclusion_pre;
|
||||
std::vector<std::pair<MapChunk*, std::array<std::uint8_t, 8>>> _chunk_detaildoodad_exclusion_post;
|
||||
std::vector<std::pair<MapChunk*, mcnk_flags>> _chunk_flags_pre;
|
||||
std::vector<std::pair<MapChunk*, mcnk_flags>> _chunk_flags_post;
|
||||
std::vector<std::pair<MapChunk*, std::vector<liquid_layer>>> _chunk_liquid_pre;
|
||||
|
||||
@@ -36,7 +36,7 @@ MapChunk::MapChunk(MapTile* maintile, BlizzardArchive::ClientFile* f, bool bigAl
|
||||
| ChunkUpdateFlags::SHADOW | ChunkUpdateFlags::MCCV
|
||||
| ChunkUpdateFlags::NORMALS| ChunkUpdateFlags::HOLES
|
||||
| ChunkUpdateFlags::AREA_ID| ChunkUpdateFlags::FLAGS
|
||||
| ChunkUpdateFlags::GROUND_EFFECT)
|
||||
| ChunkUpdateFlags::GROUND_EFFECT | ChunkUpdateFlags::DETAILDOODADS_EXCLUSION)
|
||||
{
|
||||
|
||||
|
||||
@@ -1352,6 +1352,11 @@ void MapChunk::clear_shadows()
|
||||
registerChunkUpdate(ChunkUpdateFlags::SHADOW);
|
||||
}
|
||||
|
||||
void MapChunk::paintDetailDoodadsExclusion(glm::vec3 const& pos, float radius, bool exclusion)
|
||||
{
|
||||
texture_set->setDetailDoodadsExclusion(xbase, zbase, pos, radius, false, exclusion);
|
||||
}
|
||||
|
||||
bool MapChunk::isHole(int i, int j)
|
||||
{
|
||||
return (holes & ((1 << ((j * 4) + i)))) != 0;
|
||||
@@ -1956,7 +1961,7 @@ void MapChunk::unload()
|
||||
| ChunkUpdateFlags::SHADOW | ChunkUpdateFlags::MCCV
|
||||
| ChunkUpdateFlags::NORMALS| ChunkUpdateFlags::HOLES
|
||||
| ChunkUpdateFlags::AREA_ID| ChunkUpdateFlags::FLAGS
|
||||
| ChunkUpdateFlags::GROUND_EFFECT;
|
||||
| ChunkUpdateFlags::GROUND_EFFECT | ChunkUpdateFlags::DETAILDOODADS_EXCLUSION;
|
||||
}
|
||||
|
||||
void MapChunk::setAlphamapImage(const QImage &image, unsigned int layer)
|
||||
|
||||
@@ -46,8 +46,9 @@ enum ChunkUpdateFlags
|
||||
NORMALS = 0x10,
|
||||
HOLES = 0x20,
|
||||
AREA_ID = 0x40,
|
||||
FLAGS = 0x80,
|
||||
GROUND_EFFECT = 0x100
|
||||
FLAGS = 0x80, // both chunk and texture layers flags
|
||||
GROUND_EFFECT = 0x100,
|
||||
DETAILDOODADS_EXCLUSION = 0x200
|
||||
};
|
||||
|
||||
class MapChunk
|
||||
@@ -110,7 +111,7 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
TextureSet* getTextureSet() { return texture_set.get(); };
|
||||
TextureSet* getTextureSet() const { return texture_set.get(); };
|
||||
|
||||
void draw ( math::frustum const& frustum
|
||||
, OpenGL::Scoped::use_program& mcnk_shader
|
||||
@@ -173,6 +174,8 @@ public:
|
||||
|
||||
void clear_shadows();
|
||||
|
||||
void paintDetailDoodadsExclusion(glm::vec3 const& pos, float radius, bool exclusion);
|
||||
|
||||
bool isHole(int i, int j);
|
||||
void setHole(glm::vec3 const& pos, float radius, bool big, bool add);
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ MapTile::MapTile( int pX
|
||||
| ChunkUpdateFlags::SHADOW | ChunkUpdateFlags::MCCV
|
||||
| ChunkUpdateFlags::NORMALS| ChunkUpdateFlags::HOLES
|
||||
| ChunkUpdateFlags::AREA_ID| ChunkUpdateFlags::FLAGS
|
||||
| ChunkUpdateFlags::GROUND_EFFECT)
|
||||
| ChunkUpdateFlags::GROUND_EFFECT | ChunkUpdateFlags::DETAILDOODADS_EXCLUSION)
|
||||
, _extents{glm::vec3{pX * TILESIZE, std::numeric_limits<float>::max(), pZ * TILESIZE},
|
||||
glm::vec3{pX * TILESIZE + TILESIZE, std::numeric_limits<float>::lowest(), pZ * TILESIZE + TILESIZE}}
|
||||
, _combined_extents{glm::vec3{pX * TILESIZE, std::numeric_limits<float>::max(), pZ * TILESIZE},
|
||||
|
||||
@@ -49,6 +49,7 @@
|
||||
#include <limits>
|
||||
#include <variant>
|
||||
#include <noggit/Selection.h>
|
||||
#include <noggit/ui/FontAwesome.hpp>
|
||||
|
||||
#ifdef USE_MYSQL_UID_STORAGE
|
||||
#include <mysql/mysql.h>
|
||||
@@ -106,7 +107,7 @@ NOGGIT_ACTION_MGR->purge();
|
||||
ACTION_CODE \
|
||||
} \
|
||||
|
||||
|
||||
// add action no shortcut
|
||||
#define ADD_ACTION_NS(menu, name, on_action) \
|
||||
{ \
|
||||
auto action (menu->addAction (name)); \
|
||||
@@ -258,7 +259,12 @@ void MapView::set_editing_mode(editing_mode mode)
|
||||
_world->renderer()->getTerrainParamsUniformBlock()->draw_noeffectdoodad_overlay = false;
|
||||
_minimap->use_selection(nullptr);
|
||||
|
||||
bool use_classic_ui = _settings->value("classicUI", true).toBool();
|
||||
bool use_classic_ui = _settings->value("classicUI", false).toBool();
|
||||
|
||||
if (mode != editing_mode::paint)
|
||||
{
|
||||
getGroundEffectsTool()->hide();
|
||||
}
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
@@ -276,12 +282,8 @@ void MapView::set_editing_mode(editing_mode mode)
|
||||
else if (texturingTool->getTexturingMode() == Noggit::Ui::texturing_mode::ground_effect)
|
||||
{
|
||||
getGroundEffectsTool()->updateTerrainUniformParams();
|
||||
// _world->renderer()->getTerrainParamsUniformBlock()->draw_groundeffectid_overlay = getGroundEffectsTool()->show_active_sets_overlay();
|
||||
// _world->renderer()->getTerrainParamsUniformBlock()->draw_groundeffect_layerid_overlay = getGroundEffectsTool()->show_placement_map_overlay();
|
||||
// _world->renderer()->getTerrainParamsUniformBlock()->draw_noeffectdoodad_overlay = getGroundEffectsTool()->show_exclusion_map_overlay();
|
||||
}
|
||||
|
||||
|
||||
if (use_classic_ui)
|
||||
{
|
||||
if (texturingTool->show_unpaintable_chunks())
|
||||
@@ -2854,6 +2856,75 @@ void MapView::createGUI()
|
||||
setupHelpMenu();
|
||||
setupHotkeys();
|
||||
|
||||
|
||||
// temp test, move to a function later
|
||||
auto separator(_main_window->_menuBar->addSeparator());
|
||||
|
||||
#if defined(_WIN32) || defined(WIN32)
|
||||
QAction* start_wow_action(_main_window->_menuBar->addAction("Launch WoW"));
|
||||
start_wow_action->setIconVisibleInMenu(true);
|
||||
start_wow_action->setIcon(Noggit::Ui::FontAwesomeIcon(Noggit::Ui::FontAwesome::playcircle));
|
||||
start_wow_action->setIconText("test icon text");
|
||||
|
||||
connect(start_wow_action, &QAction::triggered,
|
||||
[&]
|
||||
{
|
||||
std::filesystem::path WoW_path = std::filesystem::path(Noggit::Project::CurrentProject::get()->ClientPath) / "Wow.exe";
|
||||
|
||||
QString program_path = WoW_path.string().c_str();
|
||||
QFileInfo checkFile(program_path);
|
||||
|
||||
QStringList arguments;
|
||||
// arguments << "-console"; // deosn't seem to work
|
||||
|
||||
if (checkFile.exists() && checkFile.isFile())
|
||||
{
|
||||
QProcess* process = new QProcess(); // this parent?
|
||||
process->start(program_path, arguments);
|
||||
|
||||
if (!process->waitForStarted()) {
|
||||
qWarning("Failed to start process");
|
||||
QMessageBox::information(this, "Error", "Failed to start process");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Handle file not existing
|
||||
qWarning("File does not exist");
|
||||
QMessageBox::critical(this, "Error", "The specified file does not exist");
|
||||
}
|
||||
|
||||
// ShellExecute(nullptr
|
||||
// , "open"
|
||||
// , WoW_path.string().c_str()
|
||||
// , nullptr
|
||||
// , nullptr
|
||||
// , SW_SHOWNORMAL
|
||||
// );
|
||||
});
|
||||
|
||||
|
||||
QAction* build_data_action(_main_window->_menuBar->addAction("Build Game Data"));
|
||||
build_data_action->setToolTip("Save content of project folder as MPQ patch in the client.");
|
||||
build_data_action->setIcon(Noggit::Ui::FontAwesomeIcon(Noggit::Ui::FontAwesome::filearchive));
|
||||
|
||||
QAction* start_server_action(_main_window->_menuBar->addAction("Start Server"));
|
||||
start_server_action->setToolTip("Start World and Auth servers.");
|
||||
start_server_action->setIcon(Noggit::Ui::FontAwesomeIcon(Noggit::Ui::FontAwesome::server));
|
||||
|
||||
QAction* extract_server_map_action(_main_window->_menuBar->addAction("Extract Server Map"));
|
||||
extract_server_map_action->setToolTip("Start server extractors for this map.");
|
||||
// TODO idea : detect modified tiles and only extract those.
|
||||
extract_server_map_action->setIcon(Noggit::Ui::FontAwesomeIcon(Noggit::Ui::FontAwesome::map));
|
||||
|
||||
// TODO : restart button while WoW is running?
|
||||
|
||||
#endif
|
||||
|
||||
// IDEAs : various client utils like synchronize client view with noggit, reload, patch WoW.exe with community patches like unlock md5 check, set WoW client version
|
||||
|
||||
/////////////////////////////////////////////////////////////////
|
||||
|
||||
connect(_main_window, &Noggit::Ui::Windows::NoggitWindow::exitPromptOpened, this, &MapView::on_exit_prompt);
|
||||
|
||||
set_editing_mode (editing_mode::ground);
|
||||
@@ -3598,7 +3669,10 @@ MapView::~MapView()
|
||||
{
|
||||
delete TexturePicker; // explicitly delete this here to avoid opengl context related crash
|
||||
delete objectEditor;
|
||||
delete texturingTool;
|
||||
|
||||
// since the ground effect tool preview renderer got added, this causes crashing on exit to menu.
|
||||
// Now it crashes in application exit.
|
||||
// delete texturingTool;
|
||||
}
|
||||
|
||||
if (_force_uid_check)
|
||||
@@ -4033,54 +4107,86 @@ void MapView::tick (float dt)
|
||||
}
|
||||
break;
|
||||
case editing_mode::paint:
|
||||
if (_mod_shift_down && _mod_ctrl_down && _mod_alt_down)
|
||||
{
|
||||
// clear chunk texture
|
||||
if (!underMap)
|
||||
|
||||
if (texturingTool->getTexturingMode() == Noggit::Ui::texturing_mode::ground_effect)
|
||||
{
|
||||
NOGGIT_ACTION_MGR->beginAction(this, Noggit::ActionFlags::eCHUNKS_TEXTURE,
|
||||
Noggit::ActionModalityControllers::eSHIFT
|
||||
| Noggit::ActionModalityControllers::eCTRL
|
||||
| Noggit::ActionModalityControllers::eALT
|
||||
| Noggit::ActionModalityControllers::eLMB);
|
||||
if (_mod_shift_down)
|
||||
{
|
||||
if (texturingTool->getGroundEffectsTool()->brush_mode() == Noggit::Ui::ground_effect_brush_mode::exclusion)
|
||||
{
|
||||
NOGGIT_ACTION_MGR->beginAction(this, Noggit::ActionFlags::eCHUNK_DOODADS_EXCLUSION,
|
||||
Noggit::ActionModalityControllers::eSHIFT
|
||||
| Noggit::ActionModalityControllers::eLMB);
|
||||
_world->paintGroundEffectExclusion(_cursor_pos, texturingTool->getGroundEffectsTool()->radius(), true);
|
||||
// _world->setHole(_cursor_pos, holeTool->brushRadius(), _mod_alt_down, false);
|
||||
}
|
||||
else if (texturingTool->getGroundEffectsTool()->brush_mode() == Noggit::Ui::ground_effect_brush_mode::effect)
|
||||
{
|
||||
|
||||
_world->eraseTextures(_cursor_pos);
|
||||
}
|
||||
|
||||
}
|
||||
else if (_mod_ctrl_down && !underMap)
|
||||
{
|
||||
NOGGIT_ACTION_MGR->beginAction(this, Noggit::ActionFlags::eCHUNK_DOODADS_EXCLUSION,
|
||||
Noggit::ActionModalityControllers::eCTRL
|
||||
| Noggit::ActionModalityControllers::eLMB);
|
||||
_world->paintGroundEffectExclusion(_cursor_pos, texturingTool->getGroundEffectsTool()->radius(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (_mod_ctrl_down && !ui_hidden)
|
||||
{
|
||||
_texture_picker_need_update = true;
|
||||
// Pick texture
|
||||
// _texture_picker_dock->setVisible(true);
|
||||
// TexturePicker->setMainTexture(texturingTool->_current_texture);
|
||||
// TexturePicker->getTextures(selection);
|
||||
}
|
||||
else if (_mod_shift_down && !!Noggit::Ui::selected_texture::get())
|
||||
{
|
||||
if ((_display_mode == display_mode::in_3D && !underMap) || _display_mode == display_mode::in_2D)
|
||||
else
|
||||
{
|
||||
auto image_mask_selector = texturingTool->getImageMaskSelector();
|
||||
if (_mod_shift_down && _mod_ctrl_down && _mod_alt_down)
|
||||
{
|
||||
// clear chunk texture
|
||||
if (!underMap)
|
||||
{
|
||||
NOGGIT_ACTION_MGR->beginAction(this, Noggit::ActionFlags::eCHUNKS_TEXTURE,
|
||||
Noggit::ActionModalityControllers::eSHIFT
|
||||
| Noggit::ActionModalityControllers::eCTRL
|
||||
| Noggit::ActionModalityControllers::eALT
|
||||
| Noggit::ActionModalityControllers::eLMB);
|
||||
|
||||
if (NOGGIT_CUR_ACTION
|
||||
&& texturingTool->getTexturingMode() == Noggit::Ui::texturing_mode::paint
|
||||
&& image_mask_selector->isEnabled()
|
||||
&& !image_mask_selector->getBrushMode())
|
||||
break;
|
||||
_world->eraseTextures(_cursor_pos);
|
||||
}
|
||||
}
|
||||
else if (_mod_ctrl_down && !ui_hidden)
|
||||
{
|
||||
_texture_picker_need_update = true;
|
||||
// Pick texture
|
||||
// _texture_picker_dock->setVisible(true);
|
||||
// TexturePicker->setMainTexture(texturingTool->_current_texture);
|
||||
// TexturePicker->getTextures(selection);
|
||||
}
|
||||
else if (_mod_shift_down && !!Noggit::Ui::selected_texture::get())
|
||||
{
|
||||
if ((_display_mode == display_mode::in_3D && !underMap) || _display_mode == display_mode::in_2D)
|
||||
{
|
||||
auto image_mask_selector = texturingTool->getImageMaskSelector();
|
||||
|
||||
auto action = NOGGIT_ACTION_MGR->beginAction(this, Noggit::ActionFlags::eCHUNKS_TEXTURE,
|
||||
Noggit::ActionModalityControllers::eSHIFT
|
||||
| Noggit::ActionModalityControllers::eLMB);
|
||||
if (NOGGIT_CUR_ACTION
|
||||
&& texturingTool->getTexturingMode() == Noggit::Ui::texturing_mode::paint
|
||||
&& image_mask_selector->isEnabled()
|
||||
&& !image_mask_selector->getBrushMode())
|
||||
break;
|
||||
|
||||
action->setPostCallback(&MapView::randomizeTexturingRotation);
|
||||
auto action = NOGGIT_ACTION_MGR->beginAction(this, Noggit::ActionFlags::eCHUNKS_TEXTURE,
|
||||
Noggit::ActionModalityControllers::eSHIFT
|
||||
| Noggit::ActionModalityControllers::eLMB);
|
||||
|
||||
if (texturingTool->getTexturingMode() == Noggit::Ui::texturing_mode::paint
|
||||
&& image_mask_selector->isEnabled()
|
||||
&& !image_mask_selector->getBrushMode())
|
||||
action->setBlockCursor(true);
|
||||
action->setPostCallback(&MapView::randomizeTexturingRotation);
|
||||
|
||||
texturingTool->paint(_world.get(), _cursor_pos, dt, *Noggit::Ui::selected_texture::get());
|
||||
if (texturingTool->getTexturingMode() == Noggit::Ui::texturing_mode::paint
|
||||
&& image_mask_selector->isEnabled()
|
||||
&& !image_mask_selector->getBrushMode())
|
||||
action->setBlockCursor(true);
|
||||
|
||||
texturingTool->paint(_world.get(), _cursor_pos, dt, *Noggit::Ui::selected_texture::get());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
break;
|
||||
|
||||
case editing_mode::holes:
|
||||
@@ -4804,7 +4910,7 @@ void MapView::draw_map()
|
||||
_minimap->update();
|
||||
}
|
||||
|
||||
bool classic_ui = _settings->value("classicUI", true).toBool();
|
||||
bool classic_ui = _settings->value("classicUI", false).toBool();
|
||||
bool show_unpaintable = classic_ui ? texturingTool->show_unpaintable_chunks() : _left_sec_toolbar->showUnpaintableChunk();
|
||||
_world->renderer()->draw (
|
||||
model_view()
|
||||
@@ -5880,7 +5986,7 @@ void MapView::onSettingsSave()
|
||||
void MapView::ShowContextMenu(QPoint pos)
|
||||
{
|
||||
// QApplication::startDragDistance() is 10
|
||||
auto mouse_moved = QApplication::startDragDistance() < (_right_click_pos - pos).manhattanLength();;
|
||||
auto mouse_moved = QApplication::startDragDistance() / 3 < (_right_click_pos - pos).manhattanLength();
|
||||
|
||||
// don't show context menu if dragging mouse
|
||||
if (mouse_moved || ImGuizmo::IsUsing())
|
||||
|
||||
@@ -1677,6 +1677,23 @@ void World::overwriteTextureAtCurrentChunk(glm::vec3 const& pos, scoped_blp_text
|
||||
});
|
||||
}
|
||||
|
||||
void World::paintGroundEffectExclusion(glm::vec3 const& pos, float radius, bool exclusion)
|
||||
{
|
||||
ZoneScoped;
|
||||
for_all_chunks_in_range
|
||||
(pos, radius
|
||||
, [&](MapChunk* chunk)
|
||||
{
|
||||
// TODO action
|
||||
NOGGIT_CUR_ACTION->registerChunkDetailDoodadExclusionChange(chunk);
|
||||
|
||||
// chunk->setHole(pos, radius, exclusion);
|
||||
chunk->paintDetailDoodadsExclusion(pos, radius, exclusion);
|
||||
return true;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void World::setHole(glm::vec3 const& pos, float radius, bool big, bool hole)
|
||||
{
|
||||
ZoneScoped;
|
||||
|
||||
@@ -241,6 +241,7 @@ public:
|
||||
|
||||
void eraseTextures(glm::vec3 const& pos);
|
||||
void overwriteTextureAtCurrentChunk(glm::vec3 const& pos, scoped_blp_texture_reference const& oldTexture, scoped_blp_texture_reference newTexture);
|
||||
void paintGroundEffectExclusion(glm::vec3 const& pos, float radius, bool exclusion);
|
||||
void setBaseTexture(glm::vec3 const& pos);
|
||||
void clear_shadows(glm::vec3 const& pos);
|
||||
void clearTextures(glm::vec3 const& pos);
|
||||
|
||||
@@ -51,7 +51,7 @@ void TileRender::unload()
|
||||
| ChunkUpdateFlags::SHADOW | ChunkUpdateFlags::MCCV
|
||||
| ChunkUpdateFlags::NORMALS| ChunkUpdateFlags::HOLES
|
||||
| ChunkUpdateFlags::AREA_ID| ChunkUpdateFlags::FLAGS
|
||||
| ChunkUpdateFlags::GROUND_EFFECT;
|
||||
| ChunkUpdateFlags::GROUND_EFFECT | ChunkUpdateFlags::DETAILDOODADS_EXCLUSION;
|
||||
}
|
||||
|
||||
|
||||
@@ -218,7 +218,15 @@ void TileRender::draw (OpenGL::Scoped::use_program& mcnk_shader
|
||||
|
||||
if (flags & ChunkUpdateFlags::GROUND_EFFECT)
|
||||
{
|
||||
setChunkGroundEffectData(chunk.get());
|
||||
// TODO.
|
||||
// currently directly handled in functions
|
||||
// setChunkGroundEffectColor()
|
||||
// setChunkGroundEffectActiveData()
|
||||
}
|
||||
|
||||
if (flags & ChunkUpdateFlags::DETAILDOODADS_EXCLUSION)
|
||||
{
|
||||
setChunkDetaildoodadsExclusionData(chunk.get());
|
||||
}
|
||||
|
||||
|
||||
@@ -572,14 +580,14 @@ void TileRender::initChunkData(MapChunk* chunk)
|
||||
chunk_render_instance.ChunkGroundEffectColor[2] = 0.0f;
|
||||
chunk_render_instance.ChunkGroundEffectColor[3] = 0.0f;
|
||||
|
||||
// setChunkGroundEffectData(chunk);
|
||||
// setChunkDetaildoodadsExclusionData(chunk);
|
||||
chunk_render_instance.ChunkDoodadsEnabled2_ChunksLayerEnabled2[0] = 0;
|
||||
chunk_render_instance.ChunkDoodadsEnabled2_ChunksLayerEnabled2[1] = 0;
|
||||
chunk_render_instance.ChunkDoodadsEnabled2_ChunksLayerEnabled2[2] = 0;
|
||||
chunk_render_instance.ChunkDoodadsEnabled2_ChunksLayerEnabled2[3] = 0;
|
||||
}
|
||||
|
||||
void TileRender::setChunkGroundEffectData(MapChunk* chunk)
|
||||
void TileRender::setChunkDetaildoodadsExclusionData(MapChunk* chunk)
|
||||
{
|
||||
auto doodadExclusionMap = chunk->texture_set->getDoodadStencilBase();
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace Noggit::Rendering
|
||||
|
||||
void initChunkData(MapChunk* chunk);
|
||||
|
||||
void setChunkGroundEffectData(MapChunk* chunk);
|
||||
void setChunkDetaildoodadsExclusionData(MapChunk* chunk);
|
||||
void setChunkGroundEffectActiveData(MapChunk* chunk, std::string active_texture);
|
||||
|
||||
[[nodiscard]]
|
||||
|
||||
@@ -423,6 +423,36 @@ bool const TextureSet::getDoodadDisabledAt(int x, int y)
|
||||
return is_enabled;
|
||||
}
|
||||
|
||||
void TextureSet::setDetailDoodadsExclusion(float xbase, float zbase, glm::vec3 const& pos, float radius, bool big, bool add)
|
||||
{
|
||||
// big = fill chunk
|
||||
if (big)
|
||||
{
|
||||
std::fill(_doodadStencil.begin(), _doodadStencil.end(), add ? 0xFF : 0x0);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int x = 0; x < 8; ++x)
|
||||
{
|
||||
for (int y = 0; y < 8; ++y)
|
||||
{
|
||||
if (misc::getShortestDist(pos.x, pos.z, xbase + (UNITSIZE * x),
|
||||
zbase + (UNITSIZE * y), UNITSIZE) <= radius)
|
||||
{
|
||||
int v = (1 << (x));
|
||||
|
||||
if (add)
|
||||
_doodadStencil[y] |= v;
|
||||
else
|
||||
_doodadStencil[y] &= ~v;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
_chunk->registerChunkUpdate(ChunkUpdateFlags::DETAILDOODADS_EXCLUSION);
|
||||
}
|
||||
|
||||
bool TextureSet::stampTexture(float xbase, float zbase, float x, float z, Brush* brush, float strength, float pressure, scoped_blp_texture_reference texture, QImage* image, bool paint)
|
||||
{
|
||||
|
||||
|
||||
@@ -103,12 +103,19 @@ public:
|
||||
std::optional<tmp_edit_alpha_values>* getTempAlphamaps() { return &tmp_edit_values; };
|
||||
|
||||
int get_texture_index_or_add (scoped_blp_texture_reference texture, float target);
|
||||
|
||||
auto getDoodadMappingBase(void) -> std::uint16_t* { return _doodadMapping.data(); }
|
||||
std::array<std::uint16_t, 8> const& getDoodadMapping() { return _doodadMapping; }
|
||||
std::array<std::array<std::uint8_t, 8>, 8> const getDoodadMappingReadable(); // get array of readable values
|
||||
auto getDoodadStencilBase(void) -> std::uint8_t* { return _doodadStencil.data(); }
|
||||
uint8_t const getDoodadActiveLayerIdAt(unsigned int x, unsigned int y); // max is 8
|
||||
|
||||
// TODO x and Y are swapped
|
||||
std::array<std::uint8_t, 8> _doodadStencil; // doodads disabled if 1; WoD: may be an explicit MCDD chunk
|
||||
// this is actually uint1_t[8][8] (8*8 -> 1 bit each)
|
||||
auto getDoodadStencilBase(void) -> std::uint8_t* { return _doodadStencil.data(); }
|
||||
bool const getDoodadDisabledAt(int x, int y); // max is 8
|
||||
void setDetailDoodadsExclusion(float xbase, float zbase, glm::vec3 const& pos, float radius, bool big, bool add);
|
||||
|
||||
auto getEffectForLayer(std::size_t idx) const -> unsigned { return _layers_info[idx].effectID; }
|
||||
layer_info* getMCLYEntries() { return &_layers_info[0]; };
|
||||
void setNTextures(size_t n) { nTextures = n; };
|
||||
@@ -138,9 +145,7 @@ private:
|
||||
// this is actually uint2_t[8][8] (8*8 -> 2 bit each)
|
||||
// getting the layer id from the two bits : MCLY textureLayer entry ID (can be only one of: 00 | 01 | 10 | 11)
|
||||
// bool[8][8]
|
||||
// TODO x and Y are swapped
|
||||
std::array<std::uint8_t, 8> _doodadStencil; // doodads disabled if 1; WoD: may be an explicit MCDD chunk
|
||||
// this is actually uint1_t[8][8] (8*8 -> 1 bit each)
|
||||
|
||||
bool _need_lod_texture_map_update = false;
|
||||
|
||||
// ENTRY_MCLY _layers_info[4]; // TODO rework this, don't need to store textureid and offset
|
||||
|
||||
@@ -112,8 +112,13 @@ namespace Noggit
|
||||
_brush_level_spin->setSingleStep(5);
|
||||
slider_layout_right->addWidget(_brush_level_spin);
|
||||
|
||||
QSettings settings;
|
||||
bool use_classic_ui = settings.value("classicUI", false).toBool();
|
||||
|
||||
_show_unpaintable_chunks_cb = new QCheckBox("Show unpaintable chunks", tool_widget);
|
||||
_show_unpaintable_chunks_cb->setChecked(false);
|
||||
if (!use_classic_ui)
|
||||
_show_unpaintable_chunks_cb->hide();
|
||||
tool_layout->addWidget(_show_unpaintable_chunks_cb);
|
||||
|
||||
connect(_show_unpaintable_chunks_cb, &QCheckBox::toggled, [=](bool checked)
|
||||
@@ -326,7 +331,6 @@ namespace Noggit
|
||||
connect(geffect_tools_btn, &QPushButton::clicked
|
||||
, [=]()
|
||||
{
|
||||
_texturing_mode = texturing_mode::ground_effect;
|
||||
_ground_effect_tool->show();
|
||||
}
|
||||
);
|
||||
@@ -362,6 +366,12 @@ namespace Noggit
|
||||
setMaximumWidth(250);
|
||||
}
|
||||
|
||||
texturing_tool::~texturing_tool()
|
||||
{
|
||||
// _ground_effect_tool->delete_renderer();
|
||||
// delete _ground_effect_tool;
|
||||
}
|
||||
|
||||
void texturing_tool::updateMaskImage()
|
||||
{
|
||||
QPixmap* pixmap = _image_mask_group->getPixmap();
|
||||
@@ -415,6 +425,7 @@ namespace Noggit
|
||||
{
|
||||
_radius_slider->setValue(radius);
|
||||
_texture_switcher->change_radius(radius - _texture_switcher->radius());
|
||||
_ground_effect_tool->change_radius(radius);
|
||||
}
|
||||
|
||||
void texturing_tool::setHardness(float hardness)
|
||||
@@ -432,6 +443,10 @@ namespace Noggit
|
||||
{
|
||||
_texture_switcher->change_radius(change);
|
||||
}
|
||||
else if (_texturing_mode == texturing_mode::ground_effect)
|
||||
{
|
||||
_ground_effect_tool->change_radius(change);
|
||||
}
|
||||
}
|
||||
|
||||
void texturing_tool::change_hardness(float change)
|
||||
@@ -500,17 +515,18 @@ namespace Noggit
|
||||
float texturing_tool::brush_radius() const
|
||||
{
|
||||
// show only a dot when using the anim / swap mode
|
||||
switch (_texturing_mode)
|
||||
switch (getTexturingMode())
|
||||
{
|
||||
case texturing_mode::paint: return static_cast<float>(_radius_slider->value());
|
||||
case texturing_mode::swap: return (_texture_switcher->brush_mode() ? _texture_switcher->radius() : 0.f);
|
||||
case texturing_mode::ground_effect: return (_ground_effect_tool->brush_mode() != ground_effect_brush_mode::none ? _ground_effect_tool->radius() : 0.f);
|
||||
default: return 0.f;
|
||||
}
|
||||
}
|
||||
|
||||
float texturing_tool::hardness() const
|
||||
{
|
||||
switch (_texturing_mode)
|
||||
switch (getTexturingMode())
|
||||
{
|
||||
case texturing_mode::paint: return static_cast<float>(_hardness_slider->value());
|
||||
default: return 0.f;
|
||||
@@ -519,7 +535,7 @@ namespace Noggit
|
||||
|
||||
bool texturing_tool::show_unpaintable_chunks() const
|
||||
{
|
||||
return _show_unpaintable_chunks && _texturing_mode == texturing_mode::paint;
|
||||
return _show_unpaintable_chunks && getTexturingMode() == texturing_mode::paint;
|
||||
}
|
||||
|
||||
void texturing_tool::paint (World* world, glm::vec3 const& pos, float dt, scoped_blp_texture_reference texture)
|
||||
@@ -530,59 +546,80 @@ namespace Noggit
|
||||
update_brush_hardness();
|
||||
}
|
||||
|
||||
float strength = 1.0f - pow(1.0f - _pressure_slider->value(), dt * 10.0f);
|
||||
|
||||
if (_texturing_mode == texturing_mode::swap)
|
||||
switch(getTexturingMode())
|
||||
{
|
||||
auto to_swap (_texture_switcher->texture_to_swap());
|
||||
if (to_swap)
|
||||
{
|
||||
if (_texture_switcher->brush_mode())
|
||||
case (texturing_mode::swap):
|
||||
{
|
||||
std::cout << _texture_switcher->radius() << std::endl;
|
||||
world->replaceTexture(pos, _texture_switcher->radius(), to_swap.value(), texture, _texture_switcher->entireChunk(), _texture_switcher->entireTile());
|
||||
auto to_swap(_texture_switcher->texture_to_swap());
|
||||
if (to_swap)
|
||||
{
|
||||
if (_texture_switcher->brush_mode())
|
||||
{
|
||||
std::cout << _texture_switcher->radius() << std::endl;
|
||||
world->replaceTexture(pos, _texture_switcher->radius(), to_swap.value(), texture, _texture_switcher->entireChunk(), _texture_switcher->entireTile());
|
||||
}
|
||||
else
|
||||
{
|
||||
world->overwriteTextureAtCurrentChunk(pos, to_swap.value(), texture);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
case (texturing_mode::paint):
|
||||
{
|
||||
world->overwriteTextureAtCurrentChunk(pos, to_swap.value(), texture);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (_texturing_mode == texturing_mode::paint)
|
||||
{
|
||||
if (_spray_mode_group->isChecked())
|
||||
{
|
||||
world->sprayTexture(pos, &_spray_brush, alpha_target(), strength, static_cast<float>(_radius_slider->value()), _spray_pressure, texture);
|
||||
float strength = 1.0f - pow(1.0f - _pressure_slider->value(), dt * 10.0f);
|
||||
if (_spray_mode_group->isChecked())
|
||||
{
|
||||
world->sprayTexture(pos, &_spray_brush, alpha_target(), strength, static_cast<float>(_radius_slider->value()), _spray_pressure, texture);
|
||||
|
||||
if (_inner_radius_cb->isChecked())
|
||||
{
|
||||
if (!_image_mask_group->isEnabled())
|
||||
{
|
||||
world->paintTexture(pos, &_inner_brush, alpha_target(), strength, texture);
|
||||
}
|
||||
else
|
||||
{
|
||||
world->stampTexture(pos, &_inner_brush, alpha_target(), strength, texture, &_mask_image, _image_mask_group->getBrushMode());
|
||||
}
|
||||
if (_inner_radius_cb->isChecked())
|
||||
{
|
||||
if (!_image_mask_group->isEnabled())
|
||||
{
|
||||
world->paintTexture(pos, &_inner_brush, alpha_target(), strength, texture);
|
||||
}
|
||||
else
|
||||
{
|
||||
world->stampTexture(pos, &_inner_brush, alpha_target(), strength, texture, &_mask_image, _image_mask_group->getBrushMode());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!_image_mask_group->isEnabled())
|
||||
{
|
||||
world->paintTexture(pos, &_texture_brush, alpha_target(), strength, texture);
|
||||
}
|
||||
else
|
||||
{
|
||||
world->stampTexture(pos, &_texture_brush, alpha_target(), strength, texture, &_mask_image, _image_mask_group->getBrushMode());
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
case (texturing_mode::anim):
|
||||
{
|
||||
change_tex_flag(world, pos, _anim_prop.get(), texture);
|
||||
break;
|
||||
}
|
||||
case (texturing_mode::ground_effect):
|
||||
{
|
||||
// handled directly in MapView::tick()
|
||||
|
||||
// if (_ground_effect_tool->brush_mode() == ground_effect_brush_mode::exclusion)
|
||||
// {
|
||||
// world->paintGroundEffectExclusion(pos, _ground_effect_tool->radius(), );
|
||||
// }
|
||||
// else if (_ground_effect_tool->brush_mode() == ground_effect_brush_mode::effect)
|
||||
// {
|
||||
//
|
||||
// }
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (!_image_mask_group->isEnabled())
|
||||
{
|
||||
world->paintTexture(pos, &_texture_brush, alpha_target(), strength, texture);
|
||||
}
|
||||
else
|
||||
{
|
||||
world->stampTexture(pos, &_texture_brush, alpha_target(), strength, texture, &_mask_image, _image_mask_group->getBrushMode());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else if (_texturing_mode == texturing_mode::anim)
|
||||
{
|
||||
change_tex_flag(world, pos, _anim_prop.get(), texture);
|
||||
}
|
||||
}
|
||||
|
||||
void texturing_tool::change_tex_flag(World* world, glm::vec3 const& pos, bool add, scoped_blp_texture_reference texture)
|
||||
@@ -721,7 +758,7 @@ namespace Noggit
|
||||
_render_group_box->setChecked(true);
|
||||
left_side_layout->addWidget(_render_group_box);
|
||||
|
||||
auto render_layout(new QHBoxLayout(_render_group_box));
|
||||
auto render_layout(new QGridLayout(_render_group_box));
|
||||
_render_group_box->setLayout(render_layout);
|
||||
|
||||
_render_type_group = new QButtonGroup(_render_group_box);
|
||||
@@ -729,17 +766,17 @@ namespace Noggit
|
||||
_render_active_sets = new QRadioButton("Effect Id/Set", this);
|
||||
_render_active_sets->setToolTip("Render all the loaded effect sets for this texture in matching colors");
|
||||
_render_type_group->addButton(_render_active_sets);
|
||||
render_layout->addWidget(_render_active_sets);
|
||||
render_layout->addWidget(_render_active_sets, 0, 0);
|
||||
|
||||
_render_exclusion_map = new QRadioButton("Doodads Disabled", this);
|
||||
_render_exclusion_map->setToolTip("Render chunk units where effect doodads are disabled as white, rest as black");
|
||||
_render_type_group->addButton(_render_exclusion_map);
|
||||
render_layout->addWidget(_render_exclusion_map);
|
||||
render_layout->addWidget(_render_exclusion_map, 0, 1);
|
||||
|
||||
_render_placement_map = new QRadioButton("Selected Texture state", this); // if chunk contains texture/Effect : render as green or red if the effect layer is active or not
|
||||
_render_placement_map->setToolTip("Render chunk unit as red if texture is present in the chunk and NOT the current active layer, render as green if it's active. \nThis defines which of the 4 textures' set is currently active, this is determined by which has the highest opacity.");
|
||||
_render_type_group->addButton(_render_placement_map);
|
||||
render_layout->addWidget(_render_placement_map);
|
||||
render_layout->addWidget(_render_placement_map, 1, 0);
|
||||
|
||||
_render_active_sets->setChecked(true);
|
||||
// _render_type_group->setAutoExclusive(true);
|
||||
@@ -945,21 +982,30 @@ namespace Noggit
|
||||
_brush_grup_box->setChecked(false);
|
||||
left_side_layout->addWidget(_brush_grup_box);
|
||||
|
||||
QHBoxLayout* brush_layout = new QHBoxLayout(_brush_grup_box);
|
||||
QVBoxLayout* brush_layout = new QVBoxLayout(_brush_grup_box);
|
||||
_brush_grup_box->setLayout(brush_layout);
|
||||
|
||||
QHBoxLayout* brush_buttons_layout = new QHBoxLayout(_brush_grup_box);
|
||||
brush_layout->addLayout(brush_buttons_layout);
|
||||
_brush_type_group = new QButtonGroup(_brush_grup_box);
|
||||
|
||||
_paint_effect = new QRadioButton("Paint Effect", this);
|
||||
_brush_type_group->addButton(_paint_effect);
|
||||
brush_layout->addWidget(_paint_effect);
|
||||
|
||||
brush_buttons_layout->addWidget(_paint_effect);
|
||||
_paint_exclusion = new QRadioButton("Paint Exclusion", this);
|
||||
_brush_type_group->addButton(_paint_exclusion);
|
||||
brush_layout->addWidget(_paint_exclusion);
|
||||
brush_buttons_layout->addWidget(_paint_exclusion);
|
||||
|
||||
_paint_effect->setChecked(true);
|
||||
_paint_effect->setAutoExclusive(true);
|
||||
|
||||
brush_layout->addWidget(new QLabel("Radius:", _brush_grup_box));
|
||||
_effect_radius_slider = new Noggit::Ui::Tools::UiCommon::ExtendedSlider(_brush_grup_box);
|
||||
_effect_radius_slider->setPrefix("");
|
||||
_effect_radius_slider->setRange(0, 1000);
|
||||
_effect_radius_slider->setDecimals(2);
|
||||
_effect_radius_slider->setValue(_texturing_tool->texture_brush().getRadius());
|
||||
brush_layout->addWidget(_effect_radius_slider);
|
||||
}
|
||||
left_side_layout->addSpacerItem(new QSpacerItem(20, 40, QSizePolicy::Minimum, QSizePolicy::Expanding));
|
||||
// adjustSize();
|
||||
@@ -1081,20 +1127,19 @@ namespace Noggit
|
||||
|
||||
void ground_effect_tool::updateTerrainUniformParams()
|
||||
{
|
||||
if (_map_view->getWorld()->renderer()->getTerrainParamsUniformBlock()->draw_groundeffectid_overlay != show_active_sets_overlay())
|
||||
if (_map_view->getWorld()->renderer()->getTerrainParamsUniformBlock()->draw_groundeffectid_overlay != render_active_sets_overlay())
|
||||
{
|
||||
_map_view->getWorld()->renderer()->getTerrainParamsUniformBlock()->draw_groundeffectid_overlay = show_active_sets_overlay();
|
||||
_map_view->getWorld()->renderer()->getTerrainParamsUniformBlock()->draw_groundeffectid_overlay = render_active_sets_overlay();
|
||||
_map_view->getWorld()->renderer()->markTerrainParamsUniformBlockDirty();
|
||||
}
|
||||
|
||||
if (_map_view->getWorld()->renderer()->getTerrainParamsUniformBlock()->draw_groundeffect_layerid_overlay != show_placement_map_overlay())
|
||||
if (_map_view->getWorld()->renderer()->getTerrainParamsUniformBlock()->draw_groundeffect_layerid_overlay != render_placement_map_overlay())
|
||||
{
|
||||
_map_view->getWorld()->renderer()->getTerrainParamsUniformBlock()->draw_groundeffect_layerid_overlay = show_placement_map_overlay();
|
||||
_map_view->getWorld()->renderer()->getTerrainParamsUniformBlock()->draw_groundeffect_layerid_overlay = render_placement_map_overlay();
|
||||
_map_view->getWorld()->renderer()->markTerrainParamsUniformBlockDirty();
|
||||
}
|
||||
if (_map_view->getWorld()->renderer()->getTerrainParamsUniformBlock()->draw_noeffectdoodad_overlay != show_exclusion_map_overlay())
|
||||
if (_map_view->getWorld()->renderer()->getTerrainParamsUniformBlock()->draw_noeffectdoodad_overlay != render_exclusion_map_overlay())
|
||||
{
|
||||
_map_view->getWorld()->renderer()->getTerrainParamsUniformBlock()->draw_noeffectdoodad_overlay = show_exclusion_map_overlay();
|
||||
_map_view->getWorld()->renderer()->getTerrainParamsUniformBlock()->draw_noeffectdoodad_overlay = render_exclusion_map_overlay();
|
||||
_map_view->getWorld()->renderer()->markTerrainParamsUniformBlockDirty();
|
||||
}
|
||||
}
|
||||
@@ -1396,6 +1441,20 @@ namespace Noggit
|
||||
// _preview_renderer->deleteLater();
|
||||
}
|
||||
|
||||
ground_effect_brush_mode ground_effect_tool::brush_mode() const
|
||||
{
|
||||
if (!_brush_grup_box->isChecked())
|
||||
{
|
||||
return ground_effect_brush_mode::none;
|
||||
}
|
||||
else if (_paint_effect->isChecked())
|
||||
return ground_effect_brush_mode::effect;
|
||||
else if (_paint_exclusion->isChecked())
|
||||
return ground_effect_brush_mode::exclusion;
|
||||
|
||||
return ground_effect_brush_mode::none;
|
||||
}
|
||||
|
||||
std::optional<ground_effect_set> ground_effect_tool::getSelectedGroundEffect()
|
||||
{
|
||||
//_effect_sets_list->currentItem
|
||||
|
||||
@@ -87,6 +87,12 @@ namespace Noggit
|
||||
unsigned int TerrainType = 0;
|
||||
};
|
||||
|
||||
enum class ground_effect_brush_mode
|
||||
{
|
||||
none,
|
||||
exclusion,
|
||||
effect
|
||||
};
|
||||
|
||||
class ground_effect_tool : public QWidget
|
||||
{
|
||||
@@ -99,37 +105,50 @@ namespace Noggit
|
||||
|
||||
~ground_effect_tool(); // delete renderer
|
||||
|
||||
float radius() const{ return _effect_radius_slider->value();}
|
||||
ground_effect_brush_mode brush_mode() const; // { return _brush_grup_box->isChecked(); }
|
||||
bool render_mode() const { return _render_group_box->isChecked(); }
|
||||
|
||||
void delete_renderer() { delete _preview_renderer; } // test to fix opengl crashes on exit
|
||||
|
||||
protected:
|
||||
void showEvent(QShowEvent* event) {
|
||||
void showEvent(QShowEvent* event) override {
|
||||
QWidget::showEvent(event);
|
||||
|
||||
updateTerrainUniformParams();
|
||||
}
|
||||
|
||||
void hideEvent(QHideEvent* event) {
|
||||
void hideEvent(QHideEvent* event) override {
|
||||
_map_view->getWorld()->renderer()->getTerrainParamsUniformBlock()->draw_groundeffectid_overlay = false;
|
||||
_map_view->getWorld()->renderer()->getTerrainParamsUniformBlock()->draw_groundeffect_layerid_overlay = false;
|
||||
_map_view->getWorld()->renderer()->getTerrainParamsUniformBlock()->draw_noeffectdoodad_overlay = false;
|
||||
_map_view->getWorld()->renderer()->markTerrainParamsUniformBlockDirty();
|
||||
|
||||
QWidget::hideEvent(event);
|
||||
// event->accept();
|
||||
};
|
||||
|
||||
void closeEvent(QCloseEvent* event) override {
|
||||
_map_view->getWorld()->renderer()->getTerrainParamsUniformBlock()->draw_groundeffectid_overlay = false;
|
||||
_map_view->getWorld()->renderer()->getTerrainParamsUniformBlock()->draw_groundeffect_layerid_overlay = false;
|
||||
_map_view->getWorld()->renderer()->getTerrainParamsUniformBlock()->draw_noeffectdoodad_overlay = false;
|
||||
QWidget::closeEvent(event);
|
||||
// event->accept();
|
||||
};
|
||||
// close event triggers hide event.
|
||||
|
||||
public:
|
||||
void setDoodadSlotFromBrowser(QString doodad_path);
|
||||
|
||||
void TextureChanged(); // textureChanged
|
||||
void TextureChanged(); // selected texture was changed
|
||||
|
||||
bool show_active_sets_overlay() const { return _render_active_sets->isChecked() && _render_group_box->isChecked(); };
|
||||
bool show_placement_map_overlay() const { return _render_placement_map->isChecked() && _render_group_box->isChecked(); };
|
||||
bool show_exclusion_map_overlay() const { return _render_exclusion_map->isChecked() && _render_group_box->isChecked(); };
|
||||
private:
|
||||
inline bool render_active_sets_overlay() const
|
||||
{
|
||||
return isVisible() && _render_active_sets->isChecked() && render_mode(); // _texturing_tool->getTexturingMode() == texturing_mode::ground_effect
|
||||
};
|
||||
inline bool render_placement_map_overlay() const
|
||||
{
|
||||
return isVisible() && _render_placement_map->isChecked() && render_mode();
|
||||
};
|
||||
inline bool render_exclusion_map_overlay() const
|
||||
{
|
||||
return isVisible() && _render_exclusion_map->isChecked() && render_mode();
|
||||
};
|
||||
|
||||
void change_radius(float change) { _effect_radius_slider->setValue(static_cast<float>(_effect_radius_slider->value()) + change); };
|
||||
private:
|
||||
|
||||
std::optional<ground_effect_set> getSelectedGroundEffect();
|
||||
std::optional<glm::vec3> getSelectedEffectColor();
|
||||
@@ -158,21 +177,17 @@ namespace Noggit
|
||||
|
||||
QGroupBox* _render_group_box;
|
||||
QButtonGroup* _render_type_group;
|
||||
|
||||
// render all the loaded effect sets for this texture in various colors
|
||||
QRadioButton* _render_active_sets;
|
||||
|
||||
// only for the active/selected set of the current texture :
|
||||
// - render as red if set is present in the chunk and NOT the current active layer
|
||||
// - render as green if set is present in the chunk and is the current active layer
|
||||
// - render as black is set is not present
|
||||
QRadioButton* _render_placement_map;
|
||||
|
||||
// render chunk units where effect doodads are disabled as white, rest as black
|
||||
QRadioButton* _render_exclusion_map;
|
||||
|
||||
QCheckBox* _chkbox_merge_duplicates;
|
||||
|
||||
// QComboBox* _cbbox_effect_sets;
|
||||
QListWidget* _effect_sets_list;
|
||||
|
||||
@@ -180,7 +195,6 @@ namespace Noggit
|
||||
QListWidget* _object_list; // for render previews
|
||||
QListWidget* _weight_list; // weight and percentage customization
|
||||
// QPushButton* _button_effect_doodad[4];
|
||||
|
||||
QSpinBox* _spinbox_doodads_amount;
|
||||
QComboBox* _cbbox_terrain_type;
|
||||
|
||||
@@ -190,10 +204,17 @@ namespace Noggit
|
||||
QButtonGroup* _brush_type_group;
|
||||
QRadioButton* _paint_effect;
|
||||
QRadioButton* _paint_exclusion;
|
||||
|
||||
|
||||
Noggit::Ui::Tools::UiCommon::ExtendedSlider* _effect_radius_slider;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// ///////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/// </summary>
|
||||
///
|
||||
///
|
||||
///
|
||||
///
|
||||
|
||||
class texturing_tool : public QWidget
|
||||
{
|
||||
public:
|
||||
@@ -203,7 +224,7 @@ namespace Noggit
|
||||
, QWidget* parent = nullptr
|
||||
);
|
||||
|
||||
// ~texturing_tool() { _ground_effect_tool->deleteLater(); }; // { delete _ground_effect_tool; };
|
||||
~texturing_tool(); // { _ground_effect_tool->deleteLater(); }; // { delete _ground_effect_tool; };
|
||||
|
||||
float brush_radius() const;
|
||||
float hardness() const;
|
||||
@@ -251,7 +272,7 @@ namespace Noggit
|
||||
|
||||
Noggit::Ui::Tools::ImageMaskSelector* getImageMaskSelector() { return _image_mask_group; };
|
||||
QImage* getMaskImage() { return &_mask_image; }
|
||||
texturing_mode getTexturingMode()
|
||||
inline texturing_mode getTexturingMode() const
|
||||
{
|
||||
if (_ground_effect_tool->isVisible())
|
||||
return texturing_mode::ground_effect;
|
||||
@@ -286,7 +307,7 @@ namespace Noggit
|
||||
unsigned_int_property _anim_rotation_prop;
|
||||
BoolToggleProperty _overbright_prop;
|
||||
|
||||
texturing_mode _texturing_mode;
|
||||
texturing_mode _texturing_mode; // use getTexturingMode() to check for ground effect mode
|
||||
|
||||
private:
|
||||
QSlider* _brush_level_slider;
|
||||
|
||||
@@ -167,7 +167,7 @@ void ChunkClipboard::copySelected(glm::vec3 const& pos, ChunkCopyFlags flags)
|
||||
cache.n_textures = texture_set->num();
|
||||
cache.alphamaps = *texture_set->getAlphamaps();
|
||||
cache.tmp_edit_values = *texture_set->getTempAlphamaps();
|
||||
std::memcpy(&cache.layers_info, texture_set->getMCLYEntries(), sizeof(ENTRY_MCLY) * 4);
|
||||
std::memcpy(&cache.layers_info, texture_set->getMCLYEntries(), sizeof(layer_info) * 4);
|
||||
|
||||
for (int i = 0; i < cache.n_textures; ++i)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user