context menu update
This commit is contained in:
@@ -398,7 +398,7 @@ void MapView::snap_selected_models_to_the_ground()
|
||||
}
|
||||
|
||||
|
||||
void MapView::DeleteSelectedObject()
|
||||
void MapView::DeleteSelectedObjects()
|
||||
{
|
||||
if (terrainMode != editing_mode::object)
|
||||
{
|
||||
@@ -1218,7 +1218,7 @@ void MapView::setupEditMenu()
|
||||
ADD_ACTION (edit_menu, "Delete", Qt::Key_Delete, [this]
|
||||
{
|
||||
NOGGIT_ACTION_MGR->beginAction(this, Noggit::ActionFlags::eOBJECTS_REMOVED);
|
||||
DeleteSelectedObject();
|
||||
DeleteSelectedObjects();
|
||||
NOGGIT_ACTION_MGR->endAction();
|
||||
});
|
||||
|
||||
@@ -2201,6 +2201,7 @@ void MapView::setupHotkeys()
|
||||
}
|
||||
, [this] { return terrainMode == editing_mode::object && !NOGGIT_CUR_ACTION; }
|
||||
);
|
||||
/*
|
||||
addHotkey ( Qt::Key_C
|
||||
, MOD_none
|
||||
, [this]
|
||||
@@ -2208,7 +2209,7 @@ void MapView::setupHotkeys()
|
||||
objectEditor->copy_current_selection(_world.get());
|
||||
}
|
||||
, [this] { return terrainMode == editing_mode::object && !NOGGIT_CUR_ACTION; }
|
||||
);
|
||||
);*/
|
||||
|
||||
addHotkey ( Qt::Key_V
|
||||
, MOD_ctrl
|
||||
@@ -2221,6 +2222,7 @@ void MapView::setupHotkeys()
|
||||
}
|
||||
, [this] { return terrainMode == editing_mode::object && !NOGGIT_CUR_ACTION; }
|
||||
);
|
||||
/*
|
||||
addHotkey ( Qt::Key_V
|
||||
, MOD_none
|
||||
, [this]
|
||||
@@ -2230,7 +2232,7 @@ void MapView::setupHotkeys()
|
||||
NOGGIT_ACTION_MGR->endAction();
|
||||
}
|
||||
, [this] { return terrainMode == editing_mode::object && !NOGGIT_CUR_ACTION; }
|
||||
);
|
||||
);*/
|
||||
addHotkey ( Qt::Key_V
|
||||
, MOD_shift
|
||||
, [this] { objectEditor->import_last_model_from_wmv(eMODEL); }
|
||||
@@ -2768,6 +2770,11 @@ MapView::MapView( math::degrees camera_yaw0
|
||||
, [=] { _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;
|
||||
|
||||
freelook = false;
|
||||
@@ -4337,8 +4344,7 @@ void MapView::doSelection (bool selectTerrainOnly, bool mouseMove)
|
||||
}
|
||||
|
||||
_rotation_editor_need_update = true;
|
||||
objectEditor->update_selection(_world.get());
|
||||
|
||||
objectEditor->update_selection_ui(_world.get());
|
||||
}
|
||||
|
||||
void MapView::update_cursor_pos()
|
||||
@@ -5229,6 +5235,7 @@ void MapView::mousePressEvent(QMouseEvent* event)
|
||||
|
||||
if (rightMouse)
|
||||
{
|
||||
_right_click_pos = event->pos();
|
||||
look = true;
|
||||
}
|
||||
}
|
||||
@@ -5353,6 +5360,13 @@ void MapView::mouseReleaseEvent (QMouseEvent* event)
|
||||
if (_display_mode == display_mode::in_2D)
|
||||
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;
|
||||
|
||||
case Qt::MiddleButton:
|
||||
@@ -5581,3 +5595,331 @@ void MapView::onSettingsSave()
|
||||
|
||||
_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
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -127,6 +127,7 @@ private:
|
||||
CursorType _cursorType;
|
||||
glm::vec3 _cursor_pos;
|
||||
QPoint _drag_start_pos;
|
||||
QPoint _right_click_pos;
|
||||
float _cursorRotation;
|
||||
bool look, freelook;
|
||||
bool ui_hidden = false;
|
||||
@@ -188,7 +189,7 @@ private:
|
||||
|
||||
void ResetSelectedObjectRotation();
|
||||
void snap_selected_models_to_the_ground();
|
||||
void DeleteSelectedObject();
|
||||
void DeleteSelectedObjects();
|
||||
void changeZoneIDValue (int set);
|
||||
|
||||
QPointF _last_mouse_pos;
|
||||
@@ -252,6 +253,7 @@ signals:
|
||||
void updateProgress(int value);
|
||||
public slots:
|
||||
void on_exit_prompt();
|
||||
void ShowContextMenu(QPoint pos);
|
||||
|
||||
public:
|
||||
glm::vec4 cursor_color;
|
||||
|
||||
@@ -151,6 +151,7 @@ public:
|
||||
|
||||
void toggle_visibility() { _hidden = !_hidden; }
|
||||
void show() { _hidden = false ; }
|
||||
void hide() { _hidden = true; }
|
||||
|
||||
[[nodiscard]]
|
||||
bool use_fake_geometry() const { return !!_fake_geometry; }
|
||||
|
||||
@@ -50,3 +50,20 @@ enum eSelectionEntryTypes
|
||||
|
||||
using selection_entry = std::pair<float, selection_type>;
|
||||
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;
|
||||
};
|
||||
@@ -347,6 +347,8 @@ public:
|
||||
|
||||
void toggle_visibility() { _hidden = !_hidden; }
|
||||
void show() { _hidden = false ; }
|
||||
void hide() { _hidden = true; }
|
||||
|
||||
|
||||
[[nodiscard]]
|
||||
bool is_required_when_saving() const override
|
||||
|
||||
@@ -1012,7 +1012,7 @@ void World::clearAllModelsOnADT(TileIndex const& tile)
|
||||
{
|
||||
ZoneScoped;
|
||||
_model_instance_storage.delete_instances_from_tile(tile);
|
||||
update_models_by_filename();
|
||||
// update_models_by_filename();
|
||||
}
|
||||
|
||||
void World::CropWaterADT(const TileIndex& pos)
|
||||
@@ -1638,7 +1638,7 @@ void World::unload_every_model_and_wmo_instance()
|
||||
|
||||
_model_instance_storage.clear();
|
||||
|
||||
_models_by_filename.clear();
|
||||
// _models_by_filename.clear();
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
_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
|
||||
@@ -1695,6 +1695,7 @@ ModelInstance* World::addM2AndGetInstance ( BlizzardArchive::Listfile::FileKey c
|
||||
, float scale
|
||||
, math::degrees::vec3 rotation
|
||||
, Noggit::object_paste_params* paste_params
|
||||
, bool ignore_params
|
||||
)
|
||||
{
|
||||
ZoneScoped;
|
||||
@@ -1705,7 +1706,7 @@ ModelInstance* World::addM2AndGetInstance ( BlizzardArchive::Listfile::FileKey c
|
||||
model_instance.scale = scale;
|
||||
model_instance.dir = rotation;
|
||||
|
||||
if (paste_params)
|
||||
if (paste_params && !ignore_params)
|
||||
{
|
||||
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);
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -1823,11 +1824,11 @@ void World::remove_models_if_needed(std::vector<uint32_t> const& uids)
|
||||
{
|
||||
reset_selection();
|
||||
}
|
||||
|
||||
/*
|
||||
if (uids.size())
|
||||
{
|
||||
update_models_by_filename();
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
void World::reload_tile(TileIndex const& tile)
|
||||
@@ -2715,7 +2716,7 @@ std::unordered_set<MapChunk*>& World::vertexBorderChunks()
|
||||
}
|
||||
return _vertex_border_chunks;
|
||||
}
|
||||
|
||||
/*
|
||||
void World::update_models_by_filename()
|
||||
{
|
||||
ZoneScoped;
|
||||
@@ -2730,7 +2731,7 @@ void World::update_models_by_filename()
|
||||
|
||||
need_model_updates = false;
|
||||
}
|
||||
|
||||
*/
|
||||
void World::range_add_to_selection(glm::vec3 const& pos, float radius, bool remove)
|
||||
{
|
||||
ZoneScoped;
|
||||
|
||||
@@ -58,9 +58,10 @@ class World
|
||||
|
||||
protected:
|
||||
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_tile_update_queue _tile_update_queue;
|
||||
std::vector< selection_group> _selection_groups;
|
||||
|
||||
public:
|
||||
MapIndex mapIndex;
|
||||
@@ -126,6 +127,8 @@ public:
|
||||
bool has_selection() const { return !_current_selection.empty(); }
|
||||
bool has_multiple_model_selected() const { return _selected_model_count > 1; }
|
||||
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 add_to_selection(selection_type entry);
|
||||
void remove_from_selection(selection_type entry);
|
||||
@@ -279,6 +282,7 @@ public:
|
||||
, glm::vec3 newPos
|
||||
, float scale, math::degrees::vec3 rotation
|
||||
, Noggit::object_paste_params*
|
||||
, bool ignore_params = false
|
||||
);
|
||||
|
||||
WMOInstance* addWMOAndGetInstance ( BlizzardArchive::Listfile::FileKey const& file_key
|
||||
@@ -386,7 +390,7 @@ public:
|
||||
);
|
||||
|
||||
protected:
|
||||
void update_models_by_filename();
|
||||
// void update_models_by_filename();
|
||||
|
||||
std::unordered_set<MapChunk*>& vertexBorderChunks();
|
||||
|
||||
|
||||
@@ -613,11 +613,11 @@ void WorldRender::draw (glm::mat4x4 const& model_view
|
||||
{
|
||||
ModelManager::resetAnim();
|
||||
}
|
||||
|
||||
/*
|
||||
if (_world->need_model_updates)
|
||||
{
|
||||
_world->update_models_by_filename();
|
||||
}
|
||||
}*/
|
||||
|
||||
std::unordered_map<Model*, std::size_t> model_boxes_to_draw;
|
||||
|
||||
|
||||
@@ -55,7 +55,7 @@ namespace Noggit
|
||||
, helper_models_widget(new helper_models(this))
|
||||
, _settings (new QSettings (this))
|
||||
, _copy_model_stats (true)
|
||||
, selected()
|
||||
, _model_instance_created()
|
||||
, pasteMode(PASTE_ON_TERRAIN)
|
||||
, _map_view(mapView)
|
||||
{
|
||||
@@ -104,7 +104,7 @@ namespace Noggit
|
||||
QPushButton* object_palette_btn = new QPushButton("Object palette", this);
|
||||
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);
|
||||
|
||||
_doodadSetSelector = new QComboBox(this);
|
||||
@@ -114,6 +114,16 @@ namespace Noggit
|
||||
wmo_layout->addRow("Doodad Set:", _doodadSetSelector);
|
||||
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);
|
||||
copyBox->setExpanderTitle("Copy options");
|
||||
copyBox->setExpanded(_settings->value ("object_editor/copy_options", false).toBool());
|
||||
@@ -146,9 +156,6 @@ namespace Noggit
|
||||
QDoubleSpinBox *scaleRangeStart = new QDoubleSpinBox(this);
|
||||
QDoubleSpinBox *scaleRangeEnd = new QDoubleSpinBox(this);
|
||||
|
||||
_filename = new QLabel (this);
|
||||
_filename->setWordWrap (true);
|
||||
|
||||
rotRangeStart->setMaximumWidth(85);
|
||||
rotRangeEnd->setMaximumWidth(85);
|
||||
tiltRangeStart->setMaximumWidth(85);
|
||||
@@ -281,7 +288,8 @@ namespace Noggit
|
||||
selectionOptions_layout->addWidget(multi_select_movement_box);
|
||||
|
||||
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);
|
||||
|
||||
auto importBox = new ExpanderWidget(this);
|
||||
@@ -309,10 +317,10 @@ namespace Noggit
|
||||
layout->addWidget(pasteBox);
|
||||
layout->addWidget(selectionOptionsBox);
|
||||
layout->addWidget(rotEditorButton);
|
||||
layout->addWidget(visToggleButton);
|
||||
// layout->addWidget(visToggleButton);
|
||||
layout->addWidget(clearListButton);
|
||||
layout->addWidget(importBox);
|
||||
layout->addWidget(_filename);
|
||||
// layout->addWidget(_filename);
|
||||
|
||||
rotationEditor->use_median_pivot_point = &_use_median_pivot_point;
|
||||
|
||||
@@ -469,11 +477,12 @@ namespace Noggit
|
||||
connect(rotEditorButton, &QPushButton::clicked, [=]() {
|
||||
rotationEditor->show();
|
||||
});
|
||||
|
||||
/*
|
||||
connect(visToggleButton, &QPushButton::clicked, [=]() {
|
||||
mapView->_draw_hidden_models.set
|
||||
(!mapView->_draw_hidden_models.get());
|
||||
});
|
||||
*/
|
||||
|
||||
connect(clearListButton, &QPushButton::clicked, [=]() {
|
||||
ModelManager::clear_hidden_models();
|
||||
@@ -574,7 +583,7 @@ namespace Noggit
|
||||
{
|
||||
auto last_entry = world->get_last_selected_model();
|
||||
|
||||
for (auto& selection : selected)
|
||||
for (auto& selection : _model_instance_created)
|
||||
{
|
||||
glm::vec3 pos;
|
||||
|
||||
@@ -676,23 +685,23 @@ namespace Noggit
|
||||
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;
|
||||
|
||||
if (selected.empty())
|
||||
if (_model_instance_created.empty())
|
||||
{
|
||||
_filename->setText("");
|
||||
_filename->setText("Empty (0 objects copied)");
|
||||
return;
|
||||
}
|
||||
|
||||
if (selected.size() == 1)
|
||||
if (_model_instance_created.size() == 1)
|
||||
{
|
||||
ss << "Model: ";
|
||||
|
||||
auto selectedObject = new_selection.front();
|
||||
auto selectedObject = _model_instance_created.front();
|
||||
if (selectedObject.index() == eEntry_Object)
|
||||
{
|
||||
ss << std::get<selected_object_type>(selectedObject)->instance_model()->file_key().filepath();
|
||||
@@ -705,7 +714,7 @@ namespace Noggit
|
||||
}
|
||||
else
|
||||
{
|
||||
ss << "Multiple objects selected";
|
||||
ss << _model_instance_created.size() << " objects selected";
|
||||
}
|
||||
|
||||
_filename->setText(ss.str().c_str());
|
||||
@@ -724,7 +733,8 @@ namespace Noggit
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<selection_type> selected_model;
|
||||
// std::vector<selection_type> selected_model;
|
||||
_model_instance_created.clear();
|
||||
|
||||
if (filename.ends_with(".m2"))
|
||||
{
|
||||
@@ -732,8 +742,8 @@ namespace Noggit
|
||||
|
||||
_model_instance_created.push_back(mi);
|
||||
|
||||
selected_model.push_back(mi);
|
||||
replace_selection(selected_model);
|
||||
// selected_model.push_back(mi);
|
||||
update_clipboard();
|
||||
}
|
||||
else if (filename.ends_with(".wmo"))
|
||||
{
|
||||
@@ -741,8 +751,8 @@ namespace Noggit
|
||||
|
||||
_model_instance_created.push_back(wi);
|
||||
|
||||
selected_model.push_back(wi);
|
||||
replace_selection(selected_model);
|
||||
// selected_model.push_back(wi);
|
||||
update_clipboard();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -756,7 +766,8 @@ namespace Noggit
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<selection_type> selected_model;
|
||||
// std::vector<selection_type> selected_model;
|
||||
_model_instance_created.clear();
|
||||
|
||||
for (auto& selection : current_selection)
|
||||
{
|
||||
@@ -776,7 +787,7 @@ namespace Noggit
|
||||
clone->dir = original->dir;
|
||||
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);
|
||||
}
|
||||
else if (obj->which() == eWMO)
|
||||
@@ -786,11 +797,11 @@ namespace Noggit
|
||||
clone->dir = original->dir;
|
||||
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);
|
||||
}
|
||||
}
|
||||
replace_selection(selected_model);
|
||||
update_clipboard();
|
||||
}
|
||||
|
||||
void object_editor::SaveObjecttoTXT (World* world)
|
||||
@@ -875,7 +886,7 @@ namespace Noggit
|
||||
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->hide();
|
||||
|
||||
@@ -82,12 +82,16 @@ namespace Noggit
|
||||
|
||||
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;
|
||||
rotation_editor* rotationEditor;
|
||||
helper_models* helper_models_widget;
|
||||
QSize sizeHint() const override;
|
||||
|
||||
void update_selection(World* world);
|
||||
void update_selection_ui(World* world);
|
||||
|
||||
private:
|
||||
float _radius = 0.01f;
|
||||
@@ -112,10 +116,10 @@ namespace Noggit
|
||||
bool _copy_model_stats;
|
||||
bool _use_median_pivot_point;
|
||||
|
||||
std::vector<selection_type> selected;
|
||||
// std::vector<selection_type> selected;
|
||||
std::vector<selection_type> _model_instance_created;
|
||||
|
||||
void replace_selection(std::vector<selection_type> new_selection);
|
||||
void update_clipboard();
|
||||
|
||||
void showImportModels();
|
||||
void SaveObjecttoTXT (World*);
|
||||
|
||||
@@ -111,7 +111,7 @@ namespace Noggit
|
||||
_add_button = new QPushButton(this);
|
||||
_add_button->setIcon(FontAwesomeIcon(FontAwesome::plus));
|
||||
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->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*>(
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace Noggit
|
||||
ObjectPalette(MapView* map_view, QWidget* parent);
|
||||
~ObjectPalette();
|
||||
|
||||
void addObject();
|
||||
void addObjectFromAssetBrowser();
|
||||
void addObjectByFilename(QString const& filename);
|
||||
|
||||
void removeObject(QString filename);
|
||||
|
||||
Reference in New Issue
Block a user