context menu update

This commit is contained in:
T1ti
2023-12-23 00:59:26 +01:00
parent 2ae5de2608
commit efc53a25e6
12 changed files with 437 additions and 53 deletions

View File

@@ -398,7 +398,7 @@ void MapView::snap_selected_models_to_the_ground()
} }
void MapView::DeleteSelectedObject() void MapView::DeleteSelectedObjects()
{ {
if (terrainMode != editing_mode::object) if (terrainMode != editing_mode::object)
{ {
@@ -1218,7 +1218,7 @@ void MapView::setupEditMenu()
ADD_ACTION (edit_menu, "Delete", Qt::Key_Delete, [this] ADD_ACTION (edit_menu, "Delete", Qt::Key_Delete, [this]
{ {
NOGGIT_ACTION_MGR->beginAction(this, Noggit::ActionFlags::eOBJECTS_REMOVED); NOGGIT_ACTION_MGR->beginAction(this, Noggit::ActionFlags::eOBJECTS_REMOVED);
DeleteSelectedObject(); DeleteSelectedObjects();
NOGGIT_ACTION_MGR->endAction(); NOGGIT_ACTION_MGR->endAction();
}); });
@@ -2201,6 +2201,7 @@ void MapView::setupHotkeys()
} }
, [this] { return terrainMode == editing_mode::object && !NOGGIT_CUR_ACTION; } , [this] { return terrainMode == editing_mode::object && !NOGGIT_CUR_ACTION; }
); );
/*
addHotkey ( Qt::Key_C addHotkey ( Qt::Key_C
, MOD_none , MOD_none
, [this] , [this]
@@ -2208,7 +2209,7 @@ void MapView::setupHotkeys()
objectEditor->copy_current_selection(_world.get()); objectEditor->copy_current_selection(_world.get());
} }
, [this] { return terrainMode == editing_mode::object && !NOGGIT_CUR_ACTION; } , [this] { return terrainMode == editing_mode::object && !NOGGIT_CUR_ACTION; }
); );*/
addHotkey ( Qt::Key_V addHotkey ( Qt::Key_V
, MOD_ctrl , MOD_ctrl
@@ -2221,6 +2222,7 @@ void MapView::setupHotkeys()
} }
, [this] { return terrainMode == editing_mode::object && !NOGGIT_CUR_ACTION; } , [this] { return terrainMode == editing_mode::object && !NOGGIT_CUR_ACTION; }
); );
/*
addHotkey ( Qt::Key_V addHotkey ( Qt::Key_V
, MOD_none , MOD_none
, [this] , [this]
@@ -2230,7 +2232,7 @@ void MapView::setupHotkeys()
NOGGIT_ACTION_MGR->endAction(); NOGGIT_ACTION_MGR->endAction();
} }
, [this] { return terrainMode == editing_mode::object && !NOGGIT_CUR_ACTION; } , [this] { return terrainMode == editing_mode::object && !NOGGIT_CUR_ACTION; }
); );*/
addHotkey ( Qt::Key_V addHotkey ( Qt::Key_V
, MOD_shift , MOD_shift
, [this] { objectEditor->import_last_model_from_wmv(eMODEL); } , [this] { objectEditor->import_last_model_from_wmv(eMODEL); }
@@ -2768,6 +2770,11 @@ MapView::MapView( math::degrees camera_yaw0
, [=] { _main_window->statusBar()->removeWidget(_status_database); } , [=] { _main_window->statusBar()->removeWidget(_status_database); }
); );
setContextMenuPolicy(Qt::CustomContextMenu);
connect(this, SIGNAL(customContextMenuRequested(const QPoint&)),
this, SLOT(ShowContextMenu(const QPoint&)));
moving = strafing = updown = lookat = turn = 0.0f; moving = strafing = updown = lookat = turn = 0.0f;
freelook = false; freelook = false;
@@ -4337,8 +4344,7 @@ void MapView::doSelection (bool selectTerrainOnly, bool mouseMove)
} }
_rotation_editor_need_update = true; _rotation_editor_need_update = true;
objectEditor->update_selection(_world.get()); objectEditor->update_selection_ui(_world.get());
} }
void MapView::update_cursor_pos() void MapView::update_cursor_pos()
@@ -5229,6 +5235,7 @@ void MapView::mousePressEvent(QMouseEvent* event)
if (rightMouse) if (rightMouse)
{ {
_right_click_pos = event->pos();
look = true; look = true;
} }
} }
@@ -5353,6 +5360,13 @@ void MapView::mouseReleaseEvent (QMouseEvent* event)
if (_display_mode == display_mode::in_2D) if (_display_mode == display_mode::in_2D)
updown = 0; updown = 0;
// // may need to be done in constructor of widget
// this->setContextMenuPolicy(Qt::CustomContextMenu);
// connect(this, SIGNAL(customContextMenuRequested(const QPoint&)),
// this, SLOT(ShowContextMenu(const QPoint&)));
break; break;
case Qt::MiddleButton: case Qt::MiddleButton:
@@ -5581,3 +5595,331 @@ void MapView::onSettingsSave()
_world->renderer()->markTerrainParamsUniformBlockDirty(); _world->renderer()->markTerrainParamsUniformBlockDirty();
} }
void MapView::ShowContextMenu(QPoint pos)
{
// QApplication::startDragDistance() is 10
auto mouse_moved = QApplication::startDragDistance() < (_right_click_pos - pos).manhattanLength();;
// don't show context menu if dragging mouse
if (mouse_moved || ImGuizmo::IsUsing())
return;
// TODO : build the menu only once, store it and instead use setVisible ?
QMenu* menu = new QMenu(this);
// Undo
QAction action_undo("Undo", this);
menu->addAction(&action_undo);
action_undo.setShortcut(QKeySequence::Undo);
QObject::connect(&action_undo, &QAction::triggered, [=]()
{
NOGGIT_ACTION_MGR->undo();
});
// Redo
QAction action_redo("Redo", this);
menu->addAction(&action_redo);
action_redo.setShortcut(QKeySequence(Qt::CTRL | Qt::SHIFT | Qt::Key_Z));
QObject::connect(&action_redo, &QAction::triggered, [=]()
{
NOGGIT_ACTION_MGR->redo();
});
menu->addSeparator();
if (terrainMode == editing_mode::object)
{
bool has_selected_objects = _world->get_selected_model_count();
bool has_copied_objects = objectEditor->clipboardSize();
// Copy
QAction action_8("Copy Object(s)", this);
menu->addAction(&action_8);
action_8.setEnabled(has_selected_objects);
action_8.setShortcut(QKeySequence::Copy);
QObject::connect(&action_8, &QAction::triggered, [=]()
{
if (terrainMode == editing_mode::object && !NOGGIT_CUR_ACTION)
objectEditor->copy_current_selection(_world.get());
});
// Paste
QAction action_9("Paste Object(s)", this);
menu->addAction(&action_9);
action_9.setEnabled(has_copied_objects);
action_9.setShortcut(QKeySequence::Paste); // (Qt::CTRL | Qt::Key_P)
QObject::connect(&action_9, &QAction::triggered, [=]()
{
if (terrainMode == editing_mode::object && !NOGGIT_CUR_ACTION)
{
NOGGIT_ACTION_MGR->beginAction(this, Noggit::ActionFlags::eOBJECTS_ADDED);
objectEditor->pasteObject(_cursor_pos, _camera.position, _world.get(), &_object_paste_params);
NOGGIT_ACTION_MGR->endAction();
}
});
// Delete
QAction action_10("Delete Object(s)", this);
menu->addAction(&action_10);
action_10.setEnabled(has_selected_objects);
action_10.setShortcut(QKeySequence::Delete); // (Qt::CTRL | Qt::Key_P)
QObject::connect(&action_10, &QAction::triggered, [=]()
{
if (terrainMode == editing_mode::object && !NOGGIT_CUR_ACTION)
{
NOGGIT_ACTION_MGR->beginAction(this, Noggit::ActionFlags::eOBJECTS_REMOVED);
DeleteSelectedObjects();
NOGGIT_ACTION_MGR->endAction();
}
});
// Duplicate
QAction action_11("Duplicate Object(s)", this);
menu->addAction(&action_11);
action_11.setEnabled(has_copied_objects);
action_11.setShortcut(QKeySequence(Qt::CTRL | Qt::Key_B)); // (Qt::CTRL | Qt::Key_P)
QObject::connect(&action_11, &QAction::triggered, [=]()
{
if (terrainMode == editing_mode::object && !NOGGIT_CUR_ACTION)
{
NOGGIT_ACTION_MGR->beginAction(this, Noggit::ActionFlags::eOBJECTS_ADDED);
objectEditor->copy_current_selection(_world.get());
objectEditor->pasteObject(_cursor_pos, _camera.position, _world.get(), &_object_paste_params);
NOGGIT_ACTION_MGR->endAction();
}
});
menu->addSeparator();
// selection stuff
QAction action_1("Select all Like Selected", this); // select all objects with the same model
action_1.setToolTip("Warning : Doing actions on models overlapping unloaded tiles can cause crash");
menu->addAction(&action_1);
action_1.setEnabled(_world->get_selected_model_count() == 1);
QObject::connect(&action_1, &QAction::triggered, [=]()
{
auto last_entry = _world->get_last_selected_model();
if (last_entry)
{
if (!last_entry.value().index() == eEntry_Object)
return;
// Only works with m2 doodads
auto obj = std::get<selected_object_type>(last_entry.value());
auto model_name = obj->instance_model()->file_key().filepath();
// auto models = _world->get_models_by_filename()[model_name];
// std::vector< uint32_t> objects_to_select;
//makeCurrent();
//OpenGL::context::scoped_setter const _(::gl, context());
_world->reset_selection();
if (obj->which() == eMODEL)
{
_world->getModelInstanceStorage().for_each_m2_instance([&](ModelInstance& model_instance)
{
if (model_instance.instance_model()->file_key().filepath() == model_name)
{
// objects_to_select.push_back(model_instance.uid);
_world->add_to_selection(&model_instance);
}
});
}
else if (obj->which() == eWMO)
_world->getModelInstanceStorage().for_each_wmo_instance([&](WMOInstance& wmo_instance)
{
if (wmo_instance.instance_model()->file_key().filepath() == model_name)
{
// objects_to_select.push_back(wmo_instance.uid);
_world->add_to_selection(&wmo_instance);
}
});
// for (auto uid_it = objects_to_select.begin(); uid_it != objects_to_select.end(); uid_it++)
// {
// auto instance = _world->getObjectInstance(*uid_it);
// // if (!_world->is_selected(instance))
// _world->add_to_selection(instance);
// }
}
});
QAction action_2("Hide Selected Objects", this);
menu->addAction(&action_2);
action_2.setEnabled(has_selected_objects);
action_2.setShortcut(Qt::Key_H);
QObject::connect(&action_2, &QAction::triggered, [=]()
{
if (_world->has_selection())
{
for (auto& selection : _world->current_selection())
{
if (selection.index() != eEntry_Object)
continue;
auto obj = std::get<selected_object_type>(selection);
if (obj->which() == eMODEL)
{
static_cast<ModelInstance*>(obj)->model->hide();
}
else if (obj->which() == eWMO)
{
static_cast<WMOInstance*>(obj)->wmo->hide();
}
}
}
});
QAction action_3("Hide Unselected Objects", this);
// QAction action_2("Show Hidden", this);
QAction action_palette_add("Add Object To Palette", this);
menu->addAction(&action_palette_add);
action_palette_add.setEnabled(_world->get_selected_model_count() == 1);
QObject::connect(&action_palette_add, &QAction::triggered, [=]()
{
auto last_entry = _world->get_last_selected_model();
if (last_entry)
{
if (!last_entry.value().index() == eEntry_Object)
return;
getObjectPalette()->setVisible(true);
auto obj = std::get<selected_object_type>(last_entry.value());
auto model_name = obj->instance_model()->file_key().filepath();
_object_palette->addObjectByFilename(model_name.c_str());
}
});
menu->addSeparator();
// allow replacing all selected?
QAction action_replace("Replace Models (By Clipboard)", this);
menu->addAction(&action_replace);
// auto model_path = objectEditor->getFilename();
action_replace.setEnabled(has_selected_objects && objectEditor->clipboardSize() == 1);
action_replace.setToolTip("Replace the currently selected objects by the object in the clipboard (There must only be one!). M2s can only be replaced by m2s");
QObject::connect(&action_replace, &QAction::triggered, [=]()
{
if (terrainMode != editing_mode::object && NOGGIT_CUR_ACTION)
return;
// verify this
NOGGIT_ACTION_MGR->beginAction(this, Noggit::ActionFlags::eOBJECTS_ADDED | Noggit::ActionFlags::eOBJECTS_REMOVED); // Noggit::ActionFlags::eOBJECTS_TRANSFORMED
// NOGGIT_ACTION_MGR->beginAction(this, Noggit::ActionFlags::eOBJECTS_TRANSFORMED);
// get the model to replace by
auto replace_select = objectEditor->getClipboard().front();
auto replace_obj = std::get<selected_object_type>(replace_select);
// bool replace_is_wmo = replace_obj->which() == eWMO;
auto replace_path = replace_obj->instance_model()->file_key();
// iterate selection (objects to replace)
for (auto& entry : _world->current_selection())
{
if (entry.index() == eEntry_Object)
{
auto source_obj = std::get<selected_object_type>(entry);
//SceneObject* source_scene_obj = source_obj;
math::degrees::vec3 source_rot(math::degrees(0)._, math::degrees(0)._, math::degrees(0)._);
source_rot = source_obj->dir;
float source_scale = source_obj->scale;
auto source_pos = source_obj->pos;
if (source_obj->instance_model()->file_key().filepath() == replace_path)
continue;
// TODO : Test if this breaks if clipboard is empty
if (replace_obj->which() == eWMO)
{
// if (!replace_is_wmo)
// continue;
// auto replace_wmo = static_cast<WMOInstance*>(replace_obj);
// auto source_wmo = static_cast<WMOInstance*>(source_obj);
auto new_obj = _world->addWMOAndGetInstance(replace_path, source_pos, source_rot);
new_obj->wmo->wait_until_loaded();
new_obj->wmo->waitForChildrenLoaded();
new_obj->recalcExtents();
}
else if (replace_obj->which() == eMODEL)
{
// if (replace_is_wmo)
// continue;
// auto replace_m2 = static_cast<ModelInstance*>(replace_obj);
// auto source_m2 = static_cast<ModelInstance*>(source_obj);
// Just swapping model
// Issue : doesn't work with actions
// _world->updateTilesEntry(entry, model_update::remove);
// source_m2->model = scoped_model_reference(replace_path, _context);
// source_m2->recalcExtents();
// _world->updateTilesEntry(entry, model_update::add);
auto new_obj = _world->addM2AndGetInstance(replace_path
, source_pos
, source_scale
, source_rot
, &_object_paste_params
, true
);
new_obj->model->wait_until_loaded();
new_obj->model->waitForChildrenLoaded();
new_obj->recalcExtents();
}
}
}
// can cause the usual crash of deleting models overlapping unloaded tiles.
DeleteSelectedObjects();
// NOGGIT_ACTION_MGR->beginAction(this, Noggit::ActionFlags::eOBJECTS_REMOVED);
NOGGIT_ACTION_MGR->endAction();
});
QAction action_snap("Snap Selected To Ground", this);
menu->addAction(&action_snap);
action_snap.setEnabled(has_selected_objects);
action_snap.setShortcut(Qt::Key_PageDown); // (Qt::CTRL | Qt::Key_P)
QObject::connect(&action_snap, &QAction::triggered, [=]()
{
if (terrainMode == editing_mode::object && !NOGGIT_CUR_ACTION)
{
NOGGIT_ACTION_MGR->beginAction(this, Noggit::ActionFlags::eOBJECTS_TRANSFORMED);
snap_selected_models_to_the_ground();
NOGGIT_ACTION_MGR->endAction();
}
});
menu->addSeparator();
// TODO
QAction action_6("Group Selected Objects TODO", this);
menu->addAction(&action_6);
action_6.setEnabled(_world->has_multiple_model_selected() && false); // TODO, some "notgrouped" condition
QAction action_7("Ungroup Selected Objects TODO", this);
menu->addSeparator();
menu->exec(mapToGlobal(pos)); // synch
// menu->popup(mapToGlobal(pos)); // asynch
};
}

View File

@@ -127,6 +127,7 @@ private:
CursorType _cursorType; CursorType _cursorType;
glm::vec3 _cursor_pos; glm::vec3 _cursor_pos;
QPoint _drag_start_pos; QPoint _drag_start_pos;
QPoint _right_click_pos;
float _cursorRotation; float _cursorRotation;
bool look, freelook; bool look, freelook;
bool ui_hidden = false; bool ui_hidden = false;
@@ -188,7 +189,7 @@ private:
void ResetSelectedObjectRotation(); void ResetSelectedObjectRotation();
void snap_selected_models_to_the_ground(); void snap_selected_models_to_the_ground();
void DeleteSelectedObject(); void DeleteSelectedObjects();
void changeZoneIDValue (int set); void changeZoneIDValue (int set);
QPointF _last_mouse_pos; QPointF _last_mouse_pos;
@@ -252,6 +253,7 @@ signals:
void updateProgress(int value); void updateProgress(int value);
public slots: public slots:
void on_exit_prompt(); void on_exit_prompt();
void ShowContextMenu(QPoint pos);
public: public:
glm::vec4 cursor_color; glm::vec4 cursor_color;

View File

@@ -151,6 +151,7 @@ public:
void toggle_visibility() { _hidden = !_hidden; } void toggle_visibility() { _hidden = !_hidden; }
void show() { _hidden = false ; } void show() { _hidden = false ; }
void hide() { _hidden = true; }
[[nodiscard]] [[nodiscard]]
bool use_fake_geometry() const { return !!_fake_geometry; } bool use_fake_geometry() const { return !!_fake_geometry; }

View File

@@ -50,3 +50,20 @@ enum eSelectionEntryTypes
using selection_entry = std::pair<float, selection_type>; using selection_entry = std::pair<float, selection_type>;
using selection_result = std::vector<selection_entry>; using selection_result = std::vector<selection_entry>;
struct selection_group
{
selection_group()
{
};
void add_member(selected_object_type);
void set_selected_as_group(std::vector<selection_type> selection);
void copy_group(); // create and save a new selection group from copied objects
std::vector<unsigned int> object_members; // uids
std::array<glm::vec3, 2> extents;
};

View File

@@ -347,6 +347,8 @@ public:
void toggle_visibility() { _hidden = !_hidden; } void toggle_visibility() { _hidden = !_hidden; }
void show() { _hidden = false ; } void show() { _hidden = false ; }
void hide() { _hidden = true; }
[[nodiscard]] [[nodiscard]]
bool is_required_when_saving() const override bool is_required_when_saving() const override

View File

@@ -1012,7 +1012,7 @@ void World::clearAllModelsOnADT(TileIndex const& tile)
{ {
ZoneScoped; ZoneScoped;
_model_instance_storage.delete_instances_from_tile(tile); _model_instance_storage.delete_instances_from_tile(tile);
update_models_by_filename(); // update_models_by_filename();
} }
void World::CropWaterADT(const TileIndex& pos) void World::CropWaterADT(const TileIndex& pos)
@@ -1638,7 +1638,7 @@ void World::unload_every_model_and_wmo_instance()
_model_instance_storage.clear(); _model_instance_storage.clear();
_models_by_filename.clear(); // _models_by_filename.clear();
} }
void World::addM2 ( BlizzardArchive::Listfile::FileKey const& file_key void World::addM2 ( BlizzardArchive::Listfile::FileKey const& file_key
@@ -1687,7 +1687,7 @@ void World::addM2 ( BlizzardArchive::Listfile::FileKey const& file_key
std::uint32_t uid = _model_instance_storage.add_model_instance(std::move(model_instance), true); std::uint32_t uid = _model_instance_storage.add_model_instance(std::move(model_instance), true);
_models_by_filename[file_key.filepath()].push_back(_model_instance_storage.get_model_instance(uid).value()); // _models_by_filename[file_key.filepath()].push_back(_model_instance_storage.get_model_instance(uid).value());
} }
ModelInstance* World::addM2AndGetInstance ( BlizzardArchive::Listfile::FileKey const& file_key ModelInstance* World::addM2AndGetInstance ( BlizzardArchive::Listfile::FileKey const& file_key
@@ -1695,6 +1695,7 @@ ModelInstance* World::addM2AndGetInstance ( BlizzardArchive::Listfile::FileKey c
, float scale , float scale
, math::degrees::vec3 rotation , math::degrees::vec3 rotation
, Noggit::object_paste_params* paste_params , Noggit::object_paste_params* paste_params
, bool ignore_params
) )
{ {
ZoneScoped; ZoneScoped;
@@ -1705,7 +1706,7 @@ ModelInstance* World::addM2AndGetInstance ( BlizzardArchive::Listfile::FileKey c
model_instance.scale = scale; model_instance.scale = scale;
model_instance.dir = rotation; model_instance.dir = rotation;
if (paste_params) if (paste_params && !ignore_params)
{ {
if (_settings->value("model/random_rotation", false).toBool()) if (_settings->value("model/random_rotation", false).toBool())
{ {
@@ -1737,7 +1738,7 @@ ModelInstance* World::addM2AndGetInstance ( BlizzardArchive::Listfile::FileKey c
std::uint32_t uid = _model_instance_storage.add_model_instance(std::move(model_instance), true); std::uint32_t uid = _model_instance_storage.add_model_instance(std::move(model_instance), true);
auto instance = _model_instance_storage.get_model_instance(uid).value(); auto instance = _model_instance_storage.get_model_instance(uid).value();
_models_by_filename[file_key.filepath()].push_back(instance); // _models_by_filename[file_key.filepath()].push_back(instance);
return instance; return instance;
} }
@@ -1823,11 +1824,11 @@ void World::remove_models_if_needed(std::vector<uint32_t> const& uids)
{ {
reset_selection(); reset_selection();
} }
/*
if (uids.size()) if (uids.size())
{ {
update_models_by_filename(); update_models_by_filename();
} }*/
} }
void World::reload_tile(TileIndex const& tile) void World::reload_tile(TileIndex const& tile)
@@ -2715,7 +2716,7 @@ std::unordered_set<MapChunk*>& World::vertexBorderChunks()
} }
return _vertex_border_chunks; return _vertex_border_chunks;
} }
/*
void World::update_models_by_filename() void World::update_models_by_filename()
{ {
ZoneScoped; ZoneScoped;
@@ -2730,7 +2731,7 @@ void World::update_models_by_filename()
need_model_updates = false; need_model_updates = false;
} }
*/
void World::range_add_to_selection(glm::vec3 const& pos, float radius, bool remove) void World::range_add_to_selection(glm::vec3 const& pos, float radius, bool remove)
{ {
ZoneScoped; ZoneScoped;

View File

@@ -58,9 +58,10 @@ class World
protected: protected:
std::vector<selection_type> _current_selection; std::vector<selection_type> _current_selection;
std::unordered_map<std::string, std::vector<ModelInstance*>> _models_by_filename; // std::unordered_map<std::string, std::vector<ModelInstance*>> _models_by_filename;
Noggit::world_model_instances_storage _model_instance_storage; Noggit::world_model_instances_storage _model_instance_storage;
Noggit::world_tile_update_queue _tile_update_queue; Noggit::world_tile_update_queue _tile_update_queue;
std::vector< selection_group> _selection_groups;
public: public:
MapIndex mapIndex; MapIndex mapIndex;
@@ -126,6 +127,8 @@ public:
bool has_selection() const { return !_current_selection.empty(); } bool has_selection() const { return !_current_selection.empty(); }
bool has_multiple_model_selected() const { return _selected_model_count > 1; } bool has_multiple_model_selected() const { return _selected_model_count > 1; }
int get_selected_model_count() const { return _selected_model_count; } int get_selected_model_count() const { return _selected_model_count; }
// Unused in Red, models are now iterated by adt because of the occlusion check
// std::unordered_map<std::string, std::vector<ModelInstance*>> get_models_by_filename() const& { return _models_by_filename; }
void set_current_selection(selection_type entry); void set_current_selection(selection_type entry);
void add_to_selection(selection_type entry); void add_to_selection(selection_type entry);
void remove_from_selection(selection_type entry); void remove_from_selection(selection_type entry);
@@ -279,6 +282,7 @@ public:
, glm::vec3 newPos , glm::vec3 newPos
, float scale, math::degrees::vec3 rotation , float scale, math::degrees::vec3 rotation
, Noggit::object_paste_params* , Noggit::object_paste_params*
, bool ignore_params = false
); );
WMOInstance* addWMOAndGetInstance ( BlizzardArchive::Listfile::FileKey const& file_key WMOInstance* addWMOAndGetInstance ( BlizzardArchive::Listfile::FileKey const& file_key
@@ -386,7 +390,7 @@ public:
); );
protected: protected:
void update_models_by_filename(); // void update_models_by_filename();
std::unordered_set<MapChunk*>& vertexBorderChunks(); std::unordered_set<MapChunk*>& vertexBorderChunks();

View File

@@ -613,11 +613,11 @@ void WorldRender::draw (glm::mat4x4 const& model_view
{ {
ModelManager::resetAnim(); ModelManager::resetAnim();
} }
/*
if (_world->need_model_updates) if (_world->need_model_updates)
{ {
_world->update_models_by_filename(); _world->update_models_by_filename();
} }*/
std::unordered_map<Model*, std::size_t> model_boxes_to_draw; std::unordered_map<Model*, std::size_t> model_boxes_to_draw;

View File

@@ -55,7 +55,7 @@ namespace Noggit
, helper_models_widget(new helper_models(this)) , helper_models_widget(new helper_models(this))
, _settings (new QSettings (this)) , _settings (new QSettings (this))
, _copy_model_stats (true) , _copy_model_stats (true)
, selected() , _model_instance_created()
, pasteMode(PASTE_ON_TERRAIN) , pasteMode(PASTE_ON_TERRAIN)
, _map_view(mapView) , _map_view(mapView)
{ {
@@ -104,7 +104,7 @@ namespace Noggit
QPushButton* object_palette_btn = new QPushButton("Object palette", this); QPushButton* object_palette_btn = new QPushButton("Object palette", this);
layout->addWidget(object_palette_btn); layout->addWidget(object_palette_btn);
_wmo_group = new QGroupBox("WMO Options"); _wmo_group = new QGroupBox("Selected WMO Options");
auto wmo_layout = new QFormLayout(_wmo_group); auto wmo_layout = new QFormLayout(_wmo_group);
_doodadSetSelector = new QComboBox(this); _doodadSetSelector = new QComboBox(this);
@@ -114,6 +114,16 @@ namespace Noggit
wmo_layout->addRow("Doodad Set:", _doodadSetSelector); wmo_layout->addRow("Doodad Set:", _doodadSetSelector);
wmo_layout->addRow("Name Set:", _nameSetSelector); wmo_layout->addRow("Name Set:", _nameSetSelector);
auto clipboard_box = new QGroupBox("Clipboard");
auto clipboard_layout = new QVBoxLayout(clipboard_box);
_filename = new QLabel(this);
_filename->setWordWrap(true);
_filename->setText("Empty (0 objects copied)");
layout->addWidget(clipboard_box);
clipboard_layout->addWidget(_filename);
auto *copyBox = new ExpanderWidget( this); auto *copyBox = new ExpanderWidget( this);
copyBox->setExpanderTitle("Copy options"); copyBox->setExpanderTitle("Copy options");
copyBox->setExpanded(_settings->value ("object_editor/copy_options", false).toBool()); copyBox->setExpanded(_settings->value ("object_editor/copy_options", false).toBool());
@@ -146,9 +156,6 @@ namespace Noggit
QDoubleSpinBox *scaleRangeStart = new QDoubleSpinBox(this); QDoubleSpinBox *scaleRangeStart = new QDoubleSpinBox(this);
QDoubleSpinBox *scaleRangeEnd = new QDoubleSpinBox(this); QDoubleSpinBox *scaleRangeEnd = new QDoubleSpinBox(this);
_filename = new QLabel (this);
_filename->setWordWrap (true);
rotRangeStart->setMaximumWidth(85); rotRangeStart->setMaximumWidth(85);
rotRangeEnd->setMaximumWidth(85); rotRangeEnd->setMaximumWidth(85);
tiltRangeStart->setMaximumWidth(85); tiltRangeStart->setMaximumWidth(85);
@@ -281,7 +288,8 @@ namespace Noggit
selectionOptions_layout->addWidget(multi_select_movement_box); selectionOptions_layout->addWidget(multi_select_movement_box);
QPushButton *rotEditorButton = new QPushButton("Pos/Rotation Editor", this); QPushButton *rotEditorButton = new QPushButton("Pos/Rotation Editor", this);
QPushButton *visToggleButton = new QPushButton("Toggle Hidden Models Visibility", this); // replaced by a button
// QPushButton *visToggleButton = new QPushButton("Toggle Hidden Models Visibility", this);
QPushButton *clearListButton = new QPushButton("Clear Hidden Models List", this); QPushButton *clearListButton = new QPushButton("Clear Hidden Models List", this);
auto importBox = new ExpanderWidget(this); auto importBox = new ExpanderWidget(this);
@@ -309,10 +317,10 @@ namespace Noggit
layout->addWidget(pasteBox); layout->addWidget(pasteBox);
layout->addWidget(selectionOptionsBox); layout->addWidget(selectionOptionsBox);
layout->addWidget(rotEditorButton); layout->addWidget(rotEditorButton);
layout->addWidget(visToggleButton); // layout->addWidget(visToggleButton);
layout->addWidget(clearListButton); layout->addWidget(clearListButton);
layout->addWidget(importBox); layout->addWidget(importBox);
layout->addWidget(_filename); // layout->addWidget(_filename);
rotationEditor->use_median_pivot_point = &_use_median_pivot_point; rotationEditor->use_median_pivot_point = &_use_median_pivot_point;
@@ -469,11 +477,12 @@ namespace Noggit
connect(rotEditorButton, &QPushButton::clicked, [=]() { connect(rotEditorButton, &QPushButton::clicked, [=]() {
rotationEditor->show(); rotationEditor->show();
}); });
/*
connect(visToggleButton, &QPushButton::clicked, [=]() { connect(visToggleButton, &QPushButton::clicked, [=]() {
mapView->_draw_hidden_models.set mapView->_draw_hidden_models.set
(!mapView->_draw_hidden_models.get()); (!mapView->_draw_hidden_models.get());
}); });
*/
connect(clearListButton, &QPushButton::clicked, [=]() { connect(clearListButton, &QPushButton::clicked, [=]() {
ModelManager::clear_hidden_models(); ModelManager::clear_hidden_models();
@@ -574,7 +583,7 @@ namespace Noggit
{ {
auto last_entry = world->get_last_selected_model(); auto last_entry = world->get_last_selected_model();
for (auto& selection : selected) for (auto& selection : _model_instance_created)
{ {
glm::vec3 pos; glm::vec3 pos;
@@ -676,23 +685,23 @@ namespace Noggit
pasteModeGroup->button ((pasteMode + 1) % PASTE_MODE_COUNT)->setChecked (true); pasteModeGroup->button ((pasteMode + 1) % PASTE_MODE_COUNT)->setChecked (true);
} }
void object_editor::replace_selection(std::vector<selection_type> new_selection) void object_editor::update_clipboard()
{ {
selected = new_selection; // _model_instance_created = new_selection;
std::stringstream ss; std::stringstream ss;
if (selected.empty()) if (_model_instance_created.empty())
{ {
_filename->setText(""); _filename->setText("Empty (0 objects copied)");
return; return;
} }
if (selected.size() == 1) if (_model_instance_created.size() == 1)
{ {
ss << "Model: "; ss << "Model: ";
auto selectedObject = new_selection.front(); auto selectedObject = _model_instance_created.front();
if (selectedObject.index() == eEntry_Object) if (selectedObject.index() == eEntry_Object)
{ {
ss << std::get<selected_object_type>(selectedObject)->instance_model()->file_key().filepath(); ss << std::get<selected_object_type>(selectedObject)->instance_model()->file_key().filepath();
@@ -705,7 +714,7 @@ namespace Noggit
} }
else else
{ {
ss << "Multiple objects selected"; ss << _model_instance_created.size() << " objects selected";
} }
_filename->setText(ss.str().c_str()); _filename->setText(ss.str().c_str());
@@ -724,7 +733,8 @@ namespace Noggit
return; return;
} }
std::vector<selection_type> selected_model; // std::vector<selection_type> selected_model;
_model_instance_created.clear();
if (filename.ends_with(".m2")) if (filename.ends_with(".m2"))
{ {
@@ -732,8 +742,8 @@ namespace Noggit
_model_instance_created.push_back(mi); _model_instance_created.push_back(mi);
selected_model.push_back(mi); // selected_model.push_back(mi);
replace_selection(selected_model); update_clipboard();
} }
else if (filename.ends_with(".wmo")) else if (filename.ends_with(".wmo"))
{ {
@@ -741,8 +751,8 @@ namespace Noggit
_model_instance_created.push_back(wi); _model_instance_created.push_back(wi);
selected_model.push_back(wi); // selected_model.push_back(wi);
replace_selection(selected_model); update_clipboard();
} }
} }
@@ -756,7 +766,8 @@ namespace Noggit
return; return;
} }
std::vector<selection_type> selected_model; // std::vector<selection_type> selected_model;
_model_instance_created.clear();
for (auto& selection : current_selection) for (auto& selection : current_selection)
{ {
@@ -776,7 +787,7 @@ namespace Noggit
clone->dir = original->dir; clone->dir = original->dir;
clone->pos = pivot ? original->pos - pivot.value() : glm::vec3(); clone->pos = pivot ? original->pos - pivot.value() : glm::vec3();
selected_model.push_back(clone); // selected_model.push_back(clone);
_model_instance_created.push_back(clone); _model_instance_created.push_back(clone);
} }
else if (obj->which() == eWMO) else if (obj->which() == eWMO)
@@ -786,11 +797,11 @@ namespace Noggit
clone->dir = original->dir; clone->dir = original->dir;
clone->pos = pivot ? original->pos - pivot.value() : glm::vec3(); clone->pos = pivot ? original->pos - pivot.value() : glm::vec3();
selected_model.push_back(clone); // selected_model.push_back(clone);
_model_instance_created.push_back(clone); _model_instance_created.push_back(clone);
} }
} }
replace_selection(selected_model); update_clipboard();
} }
void object_editor::SaveObjecttoTXT (World* world) void object_editor::SaveObjecttoTXT (World* world)
@@ -875,7 +886,7 @@ namespace Noggit
return QSize(215, height()); return QSize(215, height());
} }
void object_editor::update_selection(World* world) void object_editor::update_selection_ui(World* world)
{ {
_wmo_group->setDisabled(true); _wmo_group->setDisabled(true);
_wmo_group->hide(); _wmo_group->hide();

View File

@@ -82,12 +82,16 @@ namespace Noggit
float drag_selection_depth() const { return _drag_selection_depth; } float drag_selection_depth() const { return _drag_selection_depth; }
int clipboardSize() const { return _model_instance_created.size(); }
std::vector<selection_type> getClipboard() const& { return _model_instance_created; }
model_import *modelImport; model_import *modelImport;
rotation_editor* rotationEditor; rotation_editor* rotationEditor;
helper_models* helper_models_widget; helper_models* helper_models_widget;
QSize sizeHint() const override; QSize sizeHint() const override;
void update_selection(World* world); void update_selection_ui(World* world);
private: private:
float _radius = 0.01f; float _radius = 0.01f;
@@ -112,10 +116,10 @@ namespace Noggit
bool _copy_model_stats; bool _copy_model_stats;
bool _use_median_pivot_point; bool _use_median_pivot_point;
std::vector<selection_type> selected; // std::vector<selection_type> selected;
std::vector<selection_type> _model_instance_created; std::vector<selection_type> _model_instance_created;
void replace_selection(std::vector<selection_type> new_selection); void update_clipboard();
void showImportModels(); void showImportModels();
void SaveObjecttoTXT (World*); void SaveObjecttoTXT (World*);

View File

@@ -111,7 +111,7 @@ namespace Noggit
_add_button = new QPushButton(this); _add_button = new QPushButton(this);
_add_button->setIcon(FontAwesomeIcon(FontAwesome::plus)); _add_button->setIcon(FontAwesomeIcon(FontAwesome::plus));
button_layout->addWidget(_add_button); button_layout->addWidget(_add_button);
connect(_add_button, &QAbstractButton::clicked, this, &ObjectPalette::addObject); connect(_add_button, &QAbstractButton::clicked, this, &ObjectPalette::addObjectFromAssetBrowser);
_remove_button = new QPushButton(this); _remove_button = new QPushButton(this);
_remove_button->setIcon(FontAwesomeIcon(FontAwesome::times)); _remove_button->setIcon(FontAwesomeIcon(FontAwesome::times));
@@ -125,7 +125,7 @@ namespace Noggit
} }
void ObjectPalette::addObject() void ObjectPalette::addObjectFromAssetBrowser()
{ {
std::string const& display_name = reinterpret_cast<Noggit::Ui::Tools::AssetBrowser::Ui::AssetBrowserWidget*>( std::string const& display_name = reinterpret_cast<Noggit::Ui::Tools::AssetBrowser::Ui::AssetBrowserWidget*>(

View File

@@ -48,7 +48,7 @@ namespace Noggit
ObjectPalette(MapView* map_view, QWidget* parent); ObjectPalette(MapView* map_view, QWidget* parent);
~ObjectPalette(); ~ObjectPalette();
void addObject(); void addObjectFromAssetBrowser();
void addObjectByFilename(QString const& filename); void addObjectByFilename(QString const& filename);
void removeObject(QString filename); void removeObject(QString filename);