implement radius based selection for object mode

This commit is contained in:
Skarn
2020-10-14 00:23:22 +03:00
parent 234aa4cbae
commit 1987cd8703
6 changed files with 139 additions and 1 deletions

View File

@@ -123,6 +123,8 @@ public:
bool tile_is_being_reloaded() const { return _tile_is_being_reloaded; }
std::vector<uint32_t>* get_uids() { return &uids; }
private:
tile_mode _mode;
bool _tile_is_being_reloaded;

View File

@@ -2262,6 +2262,18 @@ void MapView::doSelection (bool selectTerrainOnly)
_world->remove_from_selection(hit);
}
}
else if (hit.which() == eEntry_MapChunk)
{
_world->range_add_to_selection(_cursor_pos, objectEditor->brushRadius(), false);
}
}
else if (QGuiApplication::queryKeyboardModifiers().testFlag(Qt::ControlModifier))
{
if (hit.which() == eEntry_MapChunk)
{
_world->range_add_to_selection(_cursor_pos, objectEditor->brushRadius(), true);
}
}
else
{
@@ -2365,6 +2377,9 @@ void MapView::draw_map()
case editing_mode::holes:
radius = holeTool->brushRadius();
break;
case editing_mode::object:
radius = objectEditor->brushRadius();
break;
}
//! \note Select terrain below mouse, if no item selected or the item is map.
@@ -2696,6 +2711,7 @@ void MapView::mouseMoveEvent (QMouseEvent* event)
{
terrainTool->moveVertices (_world.get(), -relative_movement.dy() / YSENS);
}
}
@@ -2729,7 +2745,9 @@ void MapView::mouseMoveEvent (QMouseEvent* event)
case editing_mode::holes:
holeTool->changeRadius(relative_movement.dx() / XSENS);
break;
case editing_mode::object:
objectEditor->changeRadius(relative_movement.dx() / XSENS);
break;
}
}
@@ -2752,6 +2770,14 @@ void MapView::mouseMoveEvent (QMouseEvent* event)
}
}
if (leftMouse && (_mod_shift_down || _mod_ctrl_down))
{
if (terrainMode == editing_mode::object)
{
doSelection(false); // Required for radius selection in Object mode
}
}
if (_display_mode == display_mode::in_2D && leftMouse && _mod_alt_down && _mod_shift_down)
{
strafing = ((relative_movement.dx() / XSENS) / -1) * 5.0f;

View File

@@ -2282,3 +2282,65 @@ void World::update_models_by_filename()
need_model_updates = false;
}
void World::range_add_to_selection(math::vector_3d const& pos, float radius, bool remove)
{
for_tile_at(pos, [this, pos, radius, remove](MapTile* tile)
{
std::vector<uint32_t>* uids = tile->get_uids();
if (remove)
{
for (uint32_t uid : *uids)
{
auto instance = _model_instance_storage.get_instance(uid);
if (instance.get().which() == eEntry_WMO)
{
auto wmo = boost::get<selected_wmo_type>(instance.get());
if ((wmo->pos - pos).length() <= radius && is_selected(wmo))
{
remove_from_selection(wmo);
}
} else
{
auto model = boost::get<selected_model_type>(instance.get());
if ((model->pos - pos).length() <= radius && is_selected(model))
{
remove_from_selection(model);
}
}
}
}
else
{
for (uint32_t uid : *uids)
{
auto instance = _model_instance_storage.get_instance(uid);
if (instance.get().which() == eEntry_WMO)
{
auto wmo = boost::get<selected_wmo_type>(instance.get());
if ((wmo->pos - pos).length() <= radius && !is_selected(wmo))
{
add_to_selection(wmo);
}
} else
{
auto model = boost::get<selected_model_type>(instance.get());
if ((model->pos - pos).length() <= radius && !is_selected(model))
{
add_to_selection(model);
}
}
}
}
});
}

View File

@@ -163,6 +163,7 @@ public:
void remove_from_selection(std::uint32_t uid);
void reset_selection();
void delete_selected_models();
void range_add_to_selection(math::vector_3d const& pos, float radius, bool remove);
enum class m2_scaling_type
{

View File

@@ -53,6 +53,19 @@ namespace noggit
{
auto layout = new QFormLayout (this);
_radius_spin = new QDoubleSpinBox (this);
_radius_spin->setRange (0.0f, 100.0f);
_radius_spin->setDecimals (2);
_radius_spin->setValue (_radius);
layout->addRow ("Radius:", _radius_spin);
_radius_slider = new QSlider (Qt::Orientation::Horizontal, this);
_radius_slider->setRange (0, 100);
_radius_slider->setSliderPosition (_radius);
layout->addRow (_radius_slider);
QGroupBox *copyBox = new QGroupBox("Copy options", this);
auto copy_layout = new QFormLayout (copyBox);
@@ -222,6 +235,24 @@ namespace noggit
scaleRangeStart->setValue(paste_params->minScale);
scaleRangeEnd->setValue(paste_params->maxScale);
connect ( _radius_spin, qOverload<double> (&QDoubleSpinBox::valueChanged)
, [&] (double v)
{
_radius = v;
QSignalBlocker const blocker(_radius_slider);
_radius_slider->setSliderPosition ((int)std::round (v));
}
);
connect ( _radius_slider, &QSlider::valueChanged
, [&] (int v)
{
_radius = v;
QSignalBlocker const blocker(_radius_spin);
_radius_spin->setValue(v);
}
);
connect ( rotRangeStart, qOverload<double> (&QDoubleSpinBox::valueChanged)
, [=] (double v)
{
@@ -347,6 +378,11 @@ namespace noggit
}
}
void object_editor::changeRadius(float change)
{
_radius_spin->setValue (_radius + change);
}
void object_editor::showImportModels()
{
modelImport->show();

View File

@@ -9,6 +9,8 @@
#include <QLabel>
#include <QWidget>
#include <QSettings>
#include <QtWidgets/QDoubleSpinBox>
#include <QtWidgets/QSlider>
#include <boost/optional.hpp>
@@ -72,12 +74,21 @@ namespace noggit
);
void togglePasteMode();
void changeRadius(float change);
float brushRadius() const { return _radius; }
model_import *modelImport;
rotation_editor* rotationEditor;
helper_models* helper_models_widget;
QSize sizeHint() const override;
private:
float _radius = 15.0f;
QSlider* _radius_slider;
QDoubleSpinBox* _radius_spin;
QSettings* _settings;
QButtonGroup* pasteModeGroup;