grouping is complete, only missing json saving
This commit is contained in:
@@ -5931,29 +5931,85 @@ void MapView::ShowContextMenu(QPoint pos)
|
||||
// TODO
|
||||
QAction action_group("Group Selected Objects TODO", this);
|
||||
menu->addAction(&action_group);
|
||||
action_group.setEnabled(_world->has_multiple_model_selected() && true); // TODO, some "notgrouped" condition
|
||||
QObject::connect(&action_snap, &QAction::triggered, [=]()
|
||||
// check if all selected objects are already grouped
|
||||
bool groupable = false;
|
||||
if ( _world->has_multiple_model_selected())
|
||||
{
|
||||
// if there's no existing groups, that means it's always groupable
|
||||
if (!_world->_selection_groups.size())
|
||||
groupable = true;
|
||||
|
||||
if (!groupable)
|
||||
{
|
||||
_world->add_object_group();
|
||||
|
||||
//auto selected_objects = _world->get_selected_objects();
|
||||
//for (auto selected_obj : selected_objects)
|
||||
//{
|
||||
//
|
||||
//}
|
||||
// check if there's any ungrouped object
|
||||
for (auto obj : _world->get_selected_objects())
|
||||
{
|
||||
bool obj_ungrouped = true;
|
||||
for (auto& group : _world->_selection_groups)
|
||||
{
|
||||
if (group.contains_object(obj))
|
||||
obj_ungrouped = false;
|
||||
}
|
||||
if (obj_ungrouped)
|
||||
{
|
||||
groupable = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
action_group.setEnabled(groupable);
|
||||
QObject::connect(&action_group, &QAction::triggered, [=]()
|
||||
{
|
||||
// remove all groups the objects are already in and create a new one
|
||||
// for (auto obj : _world->get_selected_objects())
|
||||
// {
|
||||
// for (auto& group : _world->_selection_groups)
|
||||
// {
|
||||
// if (group.contains_object(obj))
|
||||
// {
|
||||
// group.remove_group();
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
for (auto& group : _world->_selection_groups)
|
||||
{
|
||||
if (group.isSelected())
|
||||
{
|
||||
group.remove_group();
|
||||
}
|
||||
}
|
||||
|
||||
_world->add_object_group_from_selection();
|
||||
});
|
||||
|
||||
|
||||
QAction action_ungroup("Ungroup Selected Objects TODO", this);
|
||||
|
||||
|
||||
menu->addAction(&action_ungroup);
|
||||
bool group_selected = false;
|
||||
for (auto& group : _world->_selection_groups)
|
||||
{
|
||||
if (group.isSelected())
|
||||
{
|
||||
group_selected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
action_ungroup.setEnabled(group_selected);
|
||||
QObject::connect(&action_ungroup, &QAction::triggered, [=]()
|
||||
{
|
||||
for (auto& group : _world->_selection_groups)
|
||||
{
|
||||
if (group.isSelected())
|
||||
{
|
||||
group.remove_group();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
menu->exec(mapToGlobal(pos)); // synch
|
||||
// menu->popup(mapToGlobal(pos)); // asynch
|
||||
// menu->popup(mapToGlobal(pos)); // asynch, needs to be preloaded to work
|
||||
};
|
||||
|
||||
|
||||
|
||||
}
|
||||
@@ -73,10 +73,11 @@ void ModelInstance::draw_box (glm::mat4x4 const& model_view
|
||||
}
|
||||
else
|
||||
{
|
||||
const glm::vec4 color = _grouped ? glm::vec4(0.5f, 0.5f, 1.0f, 0.5f) : glm::vec4(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
Noggit::Rendering::Primitives::WireBox::getInstance(_context).draw ( model_view
|
||||
, projection
|
||||
, transformMatrix()
|
||||
, {0.5f, 0.5f, 0.5f, 1.0f}
|
||||
, color
|
||||
, misc::transform_model_box_coords(model->header.bounding_box_min)
|
||||
, misc::transform_model_box_coords(model->header.bounding_box_max)
|
||||
);
|
||||
|
||||
@@ -72,6 +72,8 @@ public:
|
||||
|
||||
glm::vec3 const getServerPos() { return glm::vec3(ZEROPOINT - pos.z, ZEROPOINT - pos.x, pos.y); }
|
||||
|
||||
bool _grouped = false;
|
||||
|
||||
public:
|
||||
glm::vec3 pos;
|
||||
std::array<glm::vec3, 2> extents;
|
||||
|
||||
@@ -77,20 +77,22 @@ void selected_chunk_type::updateDetails(Noggit::Ui::detail_infos* detail_widget)
|
||||
detail_widget->setText(select_info.str());
|
||||
}
|
||||
|
||||
selection_group::selection_group(std::vector<selected_object_type> selected_objects, World* world)
|
||||
selection_group::selection_group(std::vector<SceneObject*> selected_objects, World* world)
|
||||
: _world(world)
|
||||
{
|
||||
_object_count = selected_objects.size();
|
||||
// _object_count = selected_objects.size();
|
||||
|
||||
if (!_object_count)
|
||||
if (!selected_objects.size())
|
||||
return;
|
||||
|
||||
_is_selected = true;
|
||||
// default group extents to first obj
|
||||
_group_extents = selected_objects.front()->getExtents();
|
||||
|
||||
_members_uid.reserve(selected_objects.size());
|
||||
for (auto& selected_obj : selected_objects)
|
||||
{
|
||||
selected_obj->_grouped = true;
|
||||
_members_uid.push_back(selected_obj->uid);
|
||||
|
||||
if (selected_obj->getExtents()[0].x < _group_extents[0].x)
|
||||
@@ -109,7 +111,32 @@ selection_group::selection_group(std::vector<selected_object_type> selected_obje
|
||||
}
|
||||
}
|
||||
|
||||
bool selection_group::group_contains_object(selected_object_type object)
|
||||
void selection_group::remove_member(unsigned int object_uid)
|
||||
{
|
||||
if (_members_uid.size() == 1)
|
||||
{
|
||||
remove_group();
|
||||
return;
|
||||
}
|
||||
|
||||
for (auto it = _members_uid.begin(); it != _members_uid.end(); ++it)
|
||||
{
|
||||
auto member_uid = *it;
|
||||
std::optional<selection_type> obj = _world->get_model(member_uid);
|
||||
if (!obj)
|
||||
continue;
|
||||
SceneObject* instance = std::get<SceneObject*>(obj.value());
|
||||
|
||||
if (instance->uid == object_uid)
|
||||
{
|
||||
_members_uid.erase(it);
|
||||
instance->_grouped = false;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool selection_group::contains_object(SceneObject* object)
|
||||
{
|
||||
for (unsigned int member_uid : _members_uid)
|
||||
{
|
||||
@@ -134,8 +161,9 @@ void selection_group::select_group()
|
||||
continue;
|
||||
|
||||
_world->add_to_selection(obj.value(), true);
|
||||
|
||||
}
|
||||
|
||||
_is_selected = true;
|
||||
}
|
||||
|
||||
void selection_group::unselect_group()
|
||||
@@ -143,29 +171,35 @@ void selection_group::unselect_group()
|
||||
for (unsigned int obj_uid : _members_uid)
|
||||
{
|
||||
// don't need to check if it's not selected
|
||||
_world->remove_from_selection(obj_uid);
|
||||
|
||||
/*
|
||||
std::optional<selection_type> obj = _world->get_model(obj_uid);
|
||||
if (!obj)
|
||||
continue;
|
||||
|
||||
SceneObject* instance = std::get<SceneObject*>(obj.value());
|
||||
|
||||
if (_world->is_selected(instance))
|
||||
_world->remove_from_selection(obj.value());
|
||||
*/
|
||||
_world->remove_from_selection(obj_uid, true);
|
||||
}
|
||||
|
||||
_is_selected = false;
|
||||
}
|
||||
|
||||
void selection_group::move_group()
|
||||
// only remove the group, not used to delete objects in it
|
||||
void selection_group::remove_group()
|
||||
{
|
||||
// TODO remove group from storage and json
|
||||
|
||||
// _world->select_objects_in_area
|
||||
_world->remove_selection_group(this);
|
||||
|
||||
// remvoe grouped attribute
|
||||
for (auto it = _members_uid.begin(); it != _members_uid.end(); ++it)
|
||||
{
|
||||
auto member_uid = *it;
|
||||
std::optional<selection_type> obj = _world->get_model(member_uid);
|
||||
if (!obj)
|
||||
continue;
|
||||
SceneObject* instance = std::get<SceneObject*>(obj.value());
|
||||
|
||||
instance->_grouped = false;
|
||||
}
|
||||
}
|
||||
|
||||
void selection_group::recalcExtents()
|
||||
{
|
||||
bool first_obj = true;
|
||||
for (unsigned int obj_uid : _members_uid)
|
||||
{
|
||||
std::optional<selection_type> obj = _world->get_model(obj_uid);
|
||||
@@ -174,6 +208,13 @@ void selection_group::recalcExtents()
|
||||
|
||||
SceneObject* instance = std::get<SceneObject*>(obj.value());
|
||||
|
||||
if (first_obj)
|
||||
{
|
||||
_group_extents = instance->getExtents();
|
||||
first_obj = false;
|
||||
continue;
|
||||
}
|
||||
|
||||
// min = glm::min(min, point);
|
||||
if (instance->getExtents()[0].x < _group_extents[0].x)
|
||||
_group_extents[0].x = instance->extents[0].x;
|
||||
|
||||
@@ -57,40 +57,51 @@ enum eSelectionEntryTypes
|
||||
class selection_group
|
||||
{
|
||||
public:
|
||||
selection_group(std::vector<selected_object_type> selected_objects, World* world);
|
||||
selection_group(std::vector<SceneObject*> selected_objects, World* world);
|
||||
// selection_group(std::vector<unsigned int> objects_uids, World* world);
|
||||
// void set_selected_as_group(std::vector<selected_object_type> selection);
|
||||
|
||||
void remove_group();
|
||||
|
||||
void add_member(SceneObject* object);
|
||||
void remove_member(unsigned int object_uid);
|
||||
|
||||
bool contains_object(SceneObject* object);
|
||||
|
||||
void add_member(selected_object_type object);
|
||||
|
||||
bool group_contains_object(selected_object_type object);
|
||||
|
||||
void select_group();
|
||||
void unselect_group();
|
||||
|
||||
// void set_selected_as_group(std::vector<selected_object_type> selection);
|
||||
void recalcExtents();
|
||||
// void copy_group(); // create and save a new selection group from copied objects
|
||||
|
||||
void copy_group(); // create and save a new selection group from copied objects
|
||||
|
||||
void move_group();
|
||||
void scale_group();
|
||||
void rotate_group();
|
||||
// void move_group();
|
||||
// void scale_group();
|
||||
// void rotate_group();
|
||||
|
||||
std::vector<unsigned int> const& getObjects() const { return _members_uid; }
|
||||
|
||||
[[nodiscard]]
|
||||
std::array<glm::vec3, 2> const& getExtents() { return _group_extents; } // ensureExtents();
|
||||
|
||||
private:
|
||||
void recalcExtents();
|
||||
bool isSelected() const { return _is_selected; }
|
||||
void setUnselected() { _is_selected = false; }
|
||||
|
||||
private:
|
||||
std::vector<unsigned int> _members_uid; // uids
|
||||
|
||||
bool _is_selected = false;
|
||||
|
||||
// std::vector<SceneObject*> _object_members;
|
||||
|
||||
std::array<glm::vec3, 2> _group_extents;
|
||||
|
||||
unsigned int _object_count = 0;
|
||||
// unsigned int _object_count = 0;
|
||||
|
||||
World* _world;
|
||||
|
||||
// bool _need_recalc_extents = false;
|
||||
};
|
||||
|
||||
using selection_entry = std::pair<float, selection_type>;
|
||||
|
||||
@@ -110,7 +110,7 @@ void WMOInstance::draw ( OpenGL::Scoped::use_program& wmo_shader
|
||||
, model_view
|
||||
, projection
|
||||
, _transform_mat
|
||||
, is_selected
|
||||
, is_selected && !_grouped
|
||||
, frustum
|
||||
, cull_distance
|
||||
, camera
|
||||
@@ -125,10 +125,10 @@ void WMOInstance::draw ( OpenGL::Scoped::use_program& wmo_shader
|
||||
|
||||
if (force_box || is_selected)
|
||||
{
|
||||
//gl.enable(GL_BLEND);
|
||||
//gl.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
gl.enable(GL_BLEND);
|
||||
gl.blendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glm::vec4 color = force_box ? glm::vec4(0.0f, 0.0f, 1.0f, 1.0f)
|
||||
glm::vec4 color = force_box || _grouped ? glm::vec4(0.5f, 0.5f, 1.0f, 0.5f)
|
||||
: glm::vec4(0.0f, 1.0f, 0.0f, 1.0f);
|
||||
|
||||
Noggit::Rendering::Primitives::WireBox::getInstance(_context).draw(model_view
|
||||
|
||||
@@ -363,6 +363,8 @@ void World::rotate_selected_models_randomly(float minX, float maxX, float minY,
|
||||
void World::rotate_selected_models_to_ground_normal(bool smoothNormals)
|
||||
{
|
||||
ZoneScoped;
|
||||
if (!_selected_model_count)
|
||||
return;
|
||||
for (auto& entry : _current_selection)
|
||||
{
|
||||
auto type = entry.index();
|
||||
@@ -500,16 +502,14 @@ void World::rotate_selected_models_to_ground_normal(bool smoothNormals)
|
||||
double cosy_cosp = 1 - 2 * (q.y * q.y + q.z * q.z);
|
||||
updateTilesEntry(entry, model_update::add);
|
||||
}
|
||||
update_selected_model_groups();
|
||||
}
|
||||
|
||||
void World::set_current_selection(selection_type entry)
|
||||
{
|
||||
ZoneScoped;
|
||||
_current_selection.clear();
|
||||
_current_selection.push_back(entry);
|
||||
_multi_select_pivot = std::nullopt;
|
||||
|
||||
_selected_model_count = entry.index() != eEntry_Object ? 0 : 1;
|
||||
reset_selection();
|
||||
add_to_selection(entry);
|
||||
}
|
||||
|
||||
void World::add_to_selection(selection_type entry, bool skip_group)
|
||||
@@ -525,7 +525,7 @@ void World::add_to_selection(selection_type entry, bool skip_group)
|
||||
auto obj = std::get<selected_object_type>(entry);
|
||||
for (auto& group : _selection_groups)
|
||||
{
|
||||
if (group.group_contains_object(obj))
|
||||
if (group.contains_object(obj))
|
||||
{
|
||||
// this then calls add_to_selection() with skip_group = true to avoid repetition
|
||||
group.select_group();
|
||||
@@ -538,7 +538,16 @@ void World::add_to_selection(selection_type entry, bool skip_group)
|
||||
update_selection_pivot();
|
||||
}
|
||||
|
||||
void World::remove_from_selection(selection_type entry)
|
||||
void World::remove_selection_group(selection_group* group)
|
||||
{
|
||||
for (auto it = _selection_groups.begin(); it != _selection_groups.end(); ++it)
|
||||
{
|
||||
_selection_groups.erase(it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void World::remove_from_selection(selection_type entry, bool skip_group)
|
||||
{
|
||||
ZoneScoped;
|
||||
std::vector<selection_type>::iterator position = std::find(_current_selection.begin(), _current_selection.end(), entry);
|
||||
@@ -547,6 +556,21 @@ void World::remove_from_selection(selection_type entry)
|
||||
if (entry.index() == eEntry_Object)
|
||||
{
|
||||
_selected_model_count--;
|
||||
|
||||
// check if it is in a group
|
||||
if (!skip_group)
|
||||
{
|
||||
auto obj = std::get<selected_object_type>(entry);
|
||||
for (auto& group : _selection_groups)
|
||||
{
|
||||
if (group.contains_object(obj))
|
||||
{
|
||||
// this then calls remove_from_selection() with skip_group = true to avoid repetition
|
||||
group.unselect_group();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
_current_selection.erase(position);
|
||||
@@ -554,7 +578,7 @@ void World::remove_from_selection(selection_type entry)
|
||||
}
|
||||
}
|
||||
|
||||
void World::remove_from_selection(std::uint32_t uid)
|
||||
void World::remove_from_selection(std::uint32_t uid, bool skip_group)
|
||||
{
|
||||
ZoneScoped;
|
||||
for (auto it = _current_selection.begin(); it != _current_selection.end(); ++it)
|
||||
@@ -564,18 +588,30 @@ void World::remove_from_selection(std::uint32_t uid)
|
||||
|
||||
auto obj = std::get<selected_object_type>(*it);
|
||||
|
||||
if (obj->which() == eMODEL && static_cast<ModelInstance*>(obj)->uid == uid)
|
||||
if (obj->uid == uid)
|
||||
{
|
||||
_current_selection.erase(it);
|
||||
update_selection_pivot();
|
||||
return;
|
||||
}
|
||||
else if (obj->which() == eWMO && static_cast<WMOInstance*>(obj)->uid == uid)
|
||||
{
|
||||
_current_selection.erase(it);
|
||||
update_selection_pivot();
|
||||
return;
|
||||
_selected_model_count--;
|
||||
_current_selection.erase(it);
|
||||
|
||||
// check if it is in a group
|
||||
if (!skip_group)
|
||||
{
|
||||
for (auto& group : _selection_groups)
|
||||
{
|
||||
if (group.contains_object(obj))
|
||||
{
|
||||
// this then calls remove_from_selection() with skip_group = true to avoid repetition
|
||||
group.unselect_group();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
update_selection_pivot();
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -585,11 +621,28 @@ void World::reset_selection()
|
||||
_current_selection.clear();
|
||||
_multi_select_pivot = std::nullopt;
|
||||
_selected_model_count = 0;
|
||||
|
||||
for (auto& selection_group : _selection_groups)
|
||||
{
|
||||
selection_group.setUnselected();
|
||||
}
|
||||
}
|
||||
|
||||
void World::delete_selected_models()
|
||||
{
|
||||
ZoneScoped;
|
||||
if (!_selected_model_count)
|
||||
return;
|
||||
|
||||
// erase selected groups as well
|
||||
for (auto& group : _selection_groups)
|
||||
{
|
||||
if (group.isSelected())
|
||||
{
|
||||
group.remove_group();
|
||||
}
|
||||
}
|
||||
|
||||
_model_instance_storage.delete_instances(_current_selection);
|
||||
need_model_updates = true;
|
||||
reset_selection();
|
||||
@@ -626,6 +679,8 @@ glm::vec3 World::get_ground_height(glm::vec3 pos)
|
||||
void World::snap_selected_models_to_the_ground()
|
||||
{
|
||||
ZoneScoped;
|
||||
if (!_selected_model_count)
|
||||
return;
|
||||
for (auto& entry : _current_selection)
|
||||
{
|
||||
auto type = entry.index();
|
||||
@@ -647,11 +702,14 @@ void World::snap_selected_models_to_the_ground()
|
||||
}
|
||||
|
||||
update_selection_pivot();
|
||||
update_selected_model_groups();
|
||||
}
|
||||
|
||||
void World::scale_selected_models(float v, m2_scaling_type type)
|
||||
{
|
||||
ZoneScoped;
|
||||
if (!_selected_model_count)
|
||||
return;
|
||||
for (auto& entry : _current_selection)
|
||||
{
|
||||
if (entry.index() == eEntry_Object)
|
||||
@@ -692,11 +750,14 @@ void World::scale_selected_models(float v, m2_scaling_type type)
|
||||
updateTilesModel(mi, model_update::add);
|
||||
}
|
||||
}
|
||||
update_selected_model_groups();
|
||||
}
|
||||
|
||||
void World::move_selected_models(float dx, float dy, float dz)
|
||||
{
|
||||
ZoneScoped;
|
||||
if (!_selected_model_count)
|
||||
return;
|
||||
for (auto& entry : _current_selection)
|
||||
{
|
||||
auto type = entry.index();
|
||||
@@ -721,6 +782,7 @@ void World::move_selected_models(float dx, float dy, float dz)
|
||||
}
|
||||
|
||||
update_selection_pivot();
|
||||
update_selected_model_groups();
|
||||
}
|
||||
|
||||
void World::move_model(selection_type entry, float dx, float dy, float dz)
|
||||
@@ -751,6 +813,8 @@ void World::move_model(selection_type entry, float dx, float dy, float dz)
|
||||
void World::set_selected_models_pos(glm::vec3 const& pos, bool change_height)
|
||||
{
|
||||
ZoneScoped;
|
||||
if (!_selected_model_count)
|
||||
return;
|
||||
// move models relative to the pivot when several are selected
|
||||
if (has_multiple_model_selected())
|
||||
{
|
||||
@@ -787,6 +851,7 @@ void World::set_selected_models_pos(glm::vec3 const& pos, bool change_height)
|
||||
}
|
||||
|
||||
update_selection_pivot();
|
||||
update_selected_model_groups();
|
||||
}
|
||||
|
||||
void World::set_model_pos(selection_type entry, glm::vec3 const& pos, bool change_height)
|
||||
@@ -811,6 +876,9 @@ void World::set_model_pos(selection_type entry, glm::vec3 const& pos, bool chang
|
||||
void World::rotate_selected_models(math::degrees rx, math::degrees ry, math::degrees rz, bool use_pivot)
|
||||
{
|
||||
ZoneScoped;
|
||||
if (!_selected_model_count)
|
||||
return;
|
||||
|
||||
math::degrees::vec3 dir_change(rx._, ry._, rz._);
|
||||
bool has_multi_select = has_multiple_model_selected();
|
||||
|
||||
@@ -848,17 +916,21 @@ void World::rotate_selected_models(math::degrees rx, math::degrees ry, math::deg
|
||||
|
||||
updateTilesEntry(entry, model_update::add);
|
||||
}
|
||||
update_selected_model_groups();
|
||||
}
|
||||
|
||||
void World::set_selected_models_rotation(math::degrees rx, math::degrees ry, math::degrees rz)
|
||||
{
|
||||
ZoneScoped;
|
||||
if (!_selected_model_count)
|
||||
return;
|
||||
|
||||
math::degrees::vec3 new_dir(rx._, ry._, rz._);
|
||||
|
||||
for (auto& entry : _current_selection)
|
||||
{
|
||||
auto type = entry.index();
|
||||
if (type == eEntry_MapChunk)
|
||||
if (type != eEntry_Object)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@@ -876,8 +948,17 @@ void World::set_selected_models_rotation(math::degrees rx, math::degrees ry, mat
|
||||
|
||||
updateTilesEntry(entry, model_update::add);
|
||||
}
|
||||
update_selected_model_groups();
|
||||
}
|
||||
|
||||
void World::update_selected_model_groups()
|
||||
{
|
||||
for (auto& selection_group : _selection_groups)
|
||||
{
|
||||
if (selection_group.isSelected())
|
||||
selection_group.recalcExtents();
|
||||
}
|
||||
}
|
||||
|
||||
MapChunk* World::getChunkAt(glm::vec3 const& pos)
|
||||
{
|
||||
@@ -3390,9 +3471,9 @@ void World::select_objects_in_area(
|
||||
}
|
||||
}
|
||||
|
||||
void World::add_object_group()
|
||||
void World::add_object_group_from_selection()
|
||||
{
|
||||
// auto selected_objects = get_selected_objects();
|
||||
// create group from selecetd objects
|
||||
selection_group selection_group(get_selected_objects(), this);
|
||||
|
||||
_selection_groups.push_back(selection_group);
|
||||
|
||||
@@ -61,9 +61,9 @@ protected:
|
||||
// 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;
|
||||
public:
|
||||
std::vector<selection_group> _selection_groups;
|
||||
|
||||
public:
|
||||
MapIndex mapIndex;
|
||||
Noggit::map_horizon horizon;
|
||||
|
||||
@@ -132,8 +132,8 @@ public:
|
||||
// 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, bool skip_group = false);
|
||||
void remove_from_selection(selection_type entry);
|
||||
void remove_from_selection(std::uint32_t uid);
|
||||
void remove_from_selection(selection_type entry, bool skip_group = false);
|
||||
void remove_from_selection(std::uint32_t uid, bool skip_group = false);
|
||||
void reset_selection();
|
||||
void delete_selected_models();
|
||||
glm::vec3 get_ground_height(glm::vec3 pos);
|
||||
@@ -165,6 +165,8 @@ public:
|
||||
void rotate_selected_models_randomly(float minX, float maxX, float minY, float maxY, float minZ, float maxZ);
|
||||
void set_selected_models_rotation(math::degrees rx, math::degrees ry, math::degrees rz);
|
||||
|
||||
void update_selected_model_groups();
|
||||
|
||||
// Checks the normal of the terrain on model origin and rotates to that spot.
|
||||
void rotate_selected_models_to_ground_normal(bool smoothNormals);
|
||||
|
||||
@@ -390,8 +392,8 @@ public:
|
||||
glm::vec3 camera_position
|
||||
);
|
||||
|
||||
void add_object_group();
|
||||
void delete_object_group();
|
||||
void add_object_group_from_selection();
|
||||
void remove_selection_group(selection_group* group);
|
||||
|
||||
protected:
|
||||
// void update_models_by_filename();
|
||||
|
||||
@@ -766,14 +766,46 @@ void WorldRender::draw (glm::mat4x4 const& model_view
|
||||
continue;
|
||||
|
||||
auto model = static_cast<ModelInstance*>(obj);
|
||||
|
||||
|
||||
|
||||
if (model->isInFrustum(frustum) && model->isInRenderDist(_cull_distance, camera_pos, display))
|
||||
{
|
||||
model->draw_box(model_view, projection, false); // make optional!
|
||||
bool is_selected = false;
|
||||
/*
|
||||
auto id = model->uid;
|
||||
bool const is_selected = _world->current_selection().size() > 0 &&
|
||||
std::find_if(_world->current_selection().begin(), _world->current_selection().end(),
|
||||
[id](selection_type type)
|
||||
{
|
||||
return var_type(type) == typeid(selected_object_type)
|
||||
&& std::get<selected_object_type>(type)->which() == SceneObjectTypes::eMODEL
|
||||
&& static_cast<ModelInstance*>(std::get<selected_object_type>(type))->uid == id;
|
||||
}) != _world->current_selection().end();*/
|
||||
|
||||
model->draw_box(model_view, projection, is_selected); // make optional!
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// render selection group boxes
|
||||
for (auto& selection_group : _world->_selection_groups)
|
||||
{
|
||||
if (!selection_group.isSelected())
|
||||
continue;
|
||||
|
||||
glm::mat4x4 identity_mtx = glm::mat4x4{ 1 };
|
||||
auto& extents = selection_group.getExtents();
|
||||
Noggit::Rendering::Primitives::WireBox::getInstance(_world->_context).draw(model_view
|
||||
, projection
|
||||
, identity_mtx
|
||||
, { 0.0f, 0.0f, 1.0f, 1.0f } // blue
|
||||
, extents[0]
|
||||
, extents[1]
|
||||
);
|
||||
}
|
||||
|
||||
// set anim time only once per frame
|
||||
{
|
||||
OpenGL::Scoped::use_program water_shader {*_liquid_program.get()};
|
||||
|
||||
@@ -315,5 +315,7 @@ void ViewportGizmo::handleTransformGizmo(MapView* map_view
|
||||
_world->updateTilesEntry(selected, model_update::add);
|
||||
}
|
||||
}
|
||||
|
||||
_world->update_selected_model_groups();
|
||||
}
|
||||
|
||||
|
||||
@@ -189,6 +189,14 @@ namespace Noggit
|
||||
_world->updateTilesEntry(instance.value(), model_update::remove);
|
||||
auto obj = std::get<selected_object_type>(instance.value());
|
||||
|
||||
for (auto& selection_group : _world->_selection_groups)
|
||||
{
|
||||
if (selection_group.contains_object(obj))
|
||||
{
|
||||
selection_group.remove_member(obj->uid);
|
||||
}
|
||||
}
|
||||
|
||||
if (NOGGIT_CUR_ACTION)
|
||||
{
|
||||
NOGGIT_CUR_ACTION->registerObjectRemoved(obj);
|
||||
|
||||
Reference in New Issue
Block a user