Files
noggit-red/src/noggit/Selection.cpp

234 lines
7.1 KiB
C++
Executable File

#include <noggit/Selection.h>
#include <noggit/MapChunk.h>
#include <noggit/DBC.h>
#include <noggit/World.h>
#include <sstream>
void selected_chunk_type::updateDetails(Noggit::Ui::detail_infos* detail_widget)
{
std::stringstream select_info;
mcnk_flags const& flags = chunk->header_flags;
select_info << "<b>Chunk</b> (" << chunk->px << ", " << chunk->py << ") flat index: (" << chunk->py * 16 + chunk->px
<< ") of <b>tile</b> (" << chunk->mt->index.x << " , " << chunk->mt->index.z << ")"
<< "<br><b>area ID:</b> " << chunk->getAreaID() << " (\"" << gAreaDB.getAreaName(chunk->getAreaID()) << "\")"
<< "<br><b>flags</b>: "
<< (flags.flags.has_mcsh ? "<br>shadows " : "")
<< (flags.flags.impass ? "<br>impassable " : "")
<< (flags.flags.lq_river ? "<br>river " : "")
<< (flags.flags.lq_ocean ? "<br>ocean " : "")
<< (flags.flags.lq_magma ? "<br>lava" : "")
<< (flags.flags.lq_slime ? "<br>slime" : "")
<< "<br><b>textures used:</b> " << chunk->texture_set->num()
<< "<br><b>textures:</b><span>";
// liquid details if the chunk has liquid data
if (chunk->mt->Water.hasData(0))
{
ChunkWater* waterchunk = chunk->liquid_chunk();
MH2O_Render liquid_render = waterchunk->Render.value_or(MH2O_Render{ 0xffffffffffffffff,0xffffffffffffffff });
if (waterchunk->hasData(0))
{
liquid_layer liquid = waterchunk->getLayers()->at(0); // only getting data from layer 0, maybe loop them ?
int liquid_flags = liquid.getSubchunks();
select_info << "\nliquid type: " << liquid.liquidID() << " (\"" << gLiquidTypeDB.getLiquidName(liquid.liquidID()) << "\")"
<< "\nliquid flags: "
// getting flags from the center tile
<< ((liquid_render.fishable >> (4 * 8 + 4)) & 1 ? "fishable " : "")
<< ((liquid_render.fatigue >> (4 * 8 + 4)) & 1 ? "fatigue" : "");
}
}
else
{
select_info << "\nno liquid data";
}
unsigned counter = 0;
for (auto& tex : *(chunk->texture_set->getTextures()))
{
bool stuck = !tex->finishedLoading();
bool error = tex->finishedLoading() && !tex->is_uploaded();
select_info << "<br> ";
if (stuck)
select_info << "<font color=\"Orange\">";
if (error)
select_info << "<font color=\"Red\">";
select_info << "<b>" << (counter + 1) << ":</b> " << tex->file_key().stringRepr();
if (stuck || error)
select_info << "</font>";
}
//! \todo get a list of textures and their flags as well as detail doodads.
select_info << "</span><br>";
detail_widget->setText(select_info.str());
}
selection_group::selection_group(std::vector<SceneObject*> selected_objects, World* world)
: _world(world)
{
// _object_count = selected_objects.size();
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)
_group_extents[0].x = selected_obj->extents[0].x;
if (selected_obj->getExtents()[0].y < _group_extents[0].y)
_group_extents[0].y = selected_obj->extents[0].y;
if (selected_obj->getExtents()[0].z < _group_extents[0].z)
_group_extents[0].z = selected_obj->extents[0].z;
if (selected_obj->getExtents()[1].x > _group_extents[1].x)
_group_extents[1].x = selected_obj->extents[1].x;
if (selected_obj->getExtents()[1].y > _group_extents[1].y)
_group_extents[1].y = selected_obj->extents[1].y;
if (selected_obj->getExtents()[1].z > _group_extents[1].z)
_group_extents[1].z = selected_obj->extents[1].z;
}
}
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)
{
if (object->uid == member_uid)
return true;
}
return false;
}
void selection_group::select_group()
{
for (unsigned int obj_uid : _members_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))
continue;
_world->add_to_selection(obj.value(), true);
}
_is_selected = true;
}
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, true);
}
_is_selected = false;
}
// only remove the group, not used to delete objects in it
void selection_group::remove_group()
{
// TODO remove group from storage and json
_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);
if (!obj)
continue;
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;
if (instance->getExtents()[0].y < _group_extents[0].y)
_group_extents[0].y = instance->extents[0].y;
if (instance->getExtents()[0].z < _group_extents[0].z)
_group_extents[0].z = instance->extents[0].z;
if (instance->getExtents()[1].x > _group_extents[1].x)
_group_extents[1].x = instance->extents[1].x;
if (instance->getExtents()[1].y > _group_extents[1].y)
_group_extents[1].y = instance->extents[1].y;
if (instance->getExtents()[1].z > _group_extents[1].z)
_group_extents[1].z = instance->extents[1].z;
}
}