Files
qt-migration-legatus/qt6-after/qt6-migrated-legatus/Lts/Plugins/BuildingViewer/Common/BgViewer/viewerCtrl/buildingmanager.cpp
T
torstenandCopilot b774f4035c Qt6 Migration: DDS-Stubs, Logger-Fixes, Export-Header Korrekturen
- NGL_ADD_LIBRARY2: 87 CMakeLists.txt konvertiert für Export-Header Generierung
- 44 Export-Header Include-Pfade korrigiert (_export.h)
- 81 DDS-Stub-Header generiert (*_dtc.h, *_fts.h, *_dts.h, *_ftc.h)
- INGLLogger: Duplikat gelöscht, m_logger Member entfernt, variadische Makros
- Q_FUNC_INFO Redefinition behoben (Qt6 definiert bereits)
- FATAL_LOG Makro hinzugefügt
- InfrastructureManagement DDS-Stubs (ism.hpp, ism_enums.hpp, ism_ftc.h)
- FilterManagement DDS-Stubs (flt_ftc.h, flt_dts.h)
- AreaEffectSimulation DDS-Stubs (aes.hpp, aes_enums.hpp)
- SymbolAppearance Klasse vollständig definiert mit content() Methode
- BuildingComponentFilter Klasse definiert mit Copy-Konstruktor
- Ftc Factory: nullptr Return (abstract class)
- AesFilter Klasse in aes.hpp hinzugefügt
- Dtc Klasse in ppm.hpp mit participantChanged Signal
- AesType Enum: alle 15 At* Werte definiert
- AesEffectState_def: EsReceived hinzugefügt
- DataModification Enum: eAdded/eModified/eRemoved
- function_reply_object.h → core_types.h Include-Pfad (72 Dateien)
- Enum-Class-Streaming Template-Operator in INGLLogger.h
- ism_mounting_point.h: QImage → QtGui/QImage, QGuiApplication/QScreen
- ism_data_plugin_interface.h: QSet Include, Include-Reihenfolge
- QRegExp → QRegularExpression in tpm_js_parser.cpp
- .underlying() Aufrufe zu direktem Enum-Vergleich korrigiert
- Include-Pfade: aes.hpp in symbol_appearance_settings_impl.h und aes_display_filter_impl.h

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-08-19 06:06:24 +02:00

2748 lines
73 KiB
C++
Executable File

#include "buildingmanager.h"
#include <utility>
#include "iconcomponent.h"
#include "modelsplittercomponent.h"
#include "motionmodel.h"
#include "orthomotionmodel.h"
#include "playercomponent.h"
#include "roomdestructioncomponent.h"
#include "textcomponent.h"
#include "visitors.h"
#include <dtEntity/entitymanager.h>
#include <dtEntity/commandmessages.h>
#include <dtEntity/core.h>
#include <dtEntity/mapcomponent.h>
#include <dtEntity/systemmessages.h>
#include <dtEntity/windowinterface.h>
#include <dtEntityOSG/cameracomponent.h>
#include <dtEntityOSG/layercomponent.h>
#include <dtEntityOSG/layerattachpointcomponent.h>
#include <dtEntityOSG/lightcomponent.h>
#include <dtEntityOSG/osginputinterface.h>
#include <dtEntityOSG/osgsysteminterface.h>
#include <dtEntityOSG/positionattitudetransformcomponent.h>
#include <dtEntityOSG/staticmeshcomponent.h>
#include <osg/BlendFunc>
#include <osg/Camera>
#include <osg/ComputeBoundsVisitor>
#include <osg/GraphicsContext>
#include <osg/io_utils>
#include <osg/LineWidth>
#include <osg/LineStipple>
#include <osg/Point>
#include <osg/Vec3>
#include <osgDB/FileNameUtils>
#include <osgDB/FileUtils>
#include <osgViewer/CompositeViewer>
#include <vector>
#include "rapidxml.hpp"
#include "rapidxml_utils.hpp"
#define ROOM_OBB_Z_MIN_SUBTRACT 0.1f
#define ROOM_OBB_Z_MAX_SUBTRACT 0.5f
namespace VCtrl
{
BuildingManager::BuildingManager(dtEntity::EntityManager &em)
: mEntityManager(&em)
, mShotOverview(false)
, mExactPos(true)
, mMapRotation(0)
, mTickFunctor(this, &BuildingManager::Tick)
, m_logger(BuildingViewer::getLogger("BuildingManager"))
{
em.RegisterForMessages(dtEntity::TickMessage::TYPE, mTickFunctor);
}
BuildingManager::~BuildingManager()
{
deleteAllBuildings();
}
void BuildingManager::deleteAllBuildings()
{
for (auto building : mBuildings)
{
qDeleteAll(building->mShots);
qDeleteAll(building->mDevices);
qDeleteAll(building->mNames);
delete building;
}
mBuildings.clear();
}
osg::Vec2d BuildingManager::AddRoomUsages(const std::string& bldgname, const std::string& roomname, VCtrl::PlayerPosition& playPos)
{
const std::string key = bldgname + " " + roomname;
auto i = mUsedRooms.find(key);
if (i == mUsedRooms.end())
{
RoomPlayers mroomPlayers;
mroomPlayers.push_back(playPos);
mUsedRooms[key] = mroomPlayers;
}
else
{
RoomPlayers &mroomPlayers = i->second;
bool knownPlayer = false;
for (auto it = mroomPlayers.begin(); it != mroomPlayers.end(); ++it)
{
if (it->mWorldPlayerId == playPos.mWorldPlayerId)
{
it = mroomPlayers.erase(it);
break;
}
}
if (knownPlayer == false)
{
VCtrl::OBB roomObb;
getRoomBounds(bldgname, roomname, roomObb);
double shiftVal = 0.6;
for (const PlayerPosition &pp : mroomPlayers)
{
if (qFuzzyCompare(pp.mPosition[0], playPos.mPosition[0]) &&
qFuzzyCompare(pp.mPosition[1], playPos.mPosition[1]))
{
playPos.mPosition = shiftPosition(roomObb, playPos.mPosition, shiftVal);
}
}
mroomPlayers.push_back(playPos);
}
}
return playPos.mPosition;
}
void BuildingManager::deleteRoomUsagePlayer(const std::string& bldgname, const std::string& roomname, dtEntity::EntityId playerId)
{
const std::string key = bldgname + " " + roomname;
auto i = mUsedRooms.find(key);
if (i != mUsedRooms.end())
{
RoomPlayers &mroomPlayers = i->second;
for (auto it = mroomPlayers.begin(); it != mroomPlayers.end(); ++it)
{
if (mroomPlayers.size() == 0)
break;
const PlayerPosition &pp = *it;
if (pp.mWorldPlayerId == playerId)
{
if (mroomPlayers.size() > 0 )
{
it = mroomPlayers.erase(it);
}
break;
}
}
}
if (mUsedRooms[key].empty())
mUsedRooms.erase(key);
}
osg::Vec2d BuildingManager::shiftPosition(const VCtrl::OBB& obb, const osg::Vec2d& pos, double& shiftValue)
{
osg::Vec2d position;
const double wall = 0.4;
osg::Vec3d v(pos[0], pos[1], 0);
v = v * obb.mMatrixInverse;
v.x() = v.x() + shiftValue;
if ( v.x() > (obb.mBB.xMax() - wall) )
{
v.x() = obb.mBB.xMin() + wall;
v.y() = v.y() + shiftValue;
}
if ( v.y() > obb.mBB.yMax() - wall)
{
v.y() = obb.mBB.yMin() + wall;
shiftValue = shiftValue / 2.0;
}
v = v * obb.mMatrix;
position.x() = v.x();
position.y() = v.y();
return position;
}
void BuildingManager::Tick(const dtEntity::Message &message)
{
QMutexLocker locker(&m_mutexShots);
const dtEntity::TickMessage &msg = static_cast<const dtEntity::TickMessage &>(message);
double simtime = msg.GetSimulationTime();
for (Building *building : mBuildings)
{
Building &bldg = *building;
for (BuildingDisplay &dspl : bldg.mDisplays)
{
std::vector<ShotDisplay>::iterator itShotDisplay = dspl.mShotDisplays.begin();
while (itShotDisplay != dspl.mShotDisplays.end())
{
ShotDisplay &shotdspl = *itShotDisplay;
Shot *shot =shotdspl.mShot;
bool lifeTimeOver = (shot->lifeTime() <= simtime);
bool displayTimeOver = (shot->displayTime() <= simtime);
if (displayTimeOver)
{
dtEntityOSG::LayerAttachPointComponent *lac;
if (!mEntityManager->GetComponent(dspl.mAttachPointId, lac))
{
WARNING_LOG() << "NO sLayerAttachPointComponent";
return;
}
if( shotdspl.mGeode.valid())
{
DEBUG_LOG() << "displayTimeOver OVER KILL IT drawables: !" << shotdspl.mGeode->getNumDrawables();
while (shotdspl.mGeode->getNumDrawables() > 0)
shotdspl.mGeode->removeDrawables(0, shotdspl.mGeode->getNumDrawables());
bool ret = lac->GetNode()->asGroup()->removeChild(shotdspl.mGeode);
DEBUG_LOG() << "displayTimeOver OVER KILL IT! result: " << ret;
dtEntity::GetWindowInterface()->RequestRedraw(dspl.mContextId);
}
}
if (lifeTimeOver)
{
DEBUG_LOG() << "lifeTimeOver OVER ERASE IT!";
itShotDisplay = dspl.mShotDisplays.erase(itShotDisplay);
}
else
++itShotDisplay;
}
}
}
}
bool BuildingManager::getFloorOfRoom(const std::string &bdlgFeatureId, int roomNumber, int &floorOut) const
{
floorOut = -999;
auto it = mRoomToFloorPerBldg.find(bdlgFeatureId);
if (it == mRoomToFloorPerBldg.end())
return false;
const std::map<int, int> &roomToFloor = it->second;
{
auto itR = roomToFloor.find(roomNumber);
if (itR == roomToFloor.end())
return false;
floorOut = itR->second;
}
return true;
}
void BuildingManager::updateShotDuration(unsigned int newDuration_s)
{
DEBUG_LOG() << Q_FUNC_INFO << " newDuration_s= " << newDuration_s;
QMutexLocker locker(&m_mutexShots);
for (Building *building : std::as_const(mBuildings))
{
for (Shot *pShot : building->mShots)
pShot->setDisplayTime(newDuration_s);
if (!building->mDisplays.empty())
{
BuildingDisplay buildingDisplay = building->mDisplays.front();
DEBUG_LOG() << Q_FUNC_INFO << " buildingDisplay.mContextId " << buildingDisplay.mContextId;
updateShots(*building, buildingDisplay);
dtEntity::GetWindowInterface()->RequestRedraw(buildingDisplay.mContextId);
}
}
}
void BuildingManager::setCallbackCamPosChanged(const CallbackCamPosChanged &cb)
{
mCbCamPosChanged = cb;
for (auto building : mBuildings)
{
for (auto &bd : building->mDisplays)
{
if (bd.pMotion)
bd.pMotion->m_callbackCamPosChanged = mCbCamPosChanged;
}
}
}
bool BuildingManager::setCameraPosition(unsigned int contextid, const BuildingViewer::CameraViewPosition& pos)
{
BuildingDisplay* pBuildingDisplay = getBuildingDisplay(contextid);
if (!pBuildingDisplay)
return false;
dtEntityOSG::CameraComponent *pCamComp = nullptr;
bool success = mEntityManager->GetComponent(pBuildingDisplay->mCameraId, pCamComp);
if (!success || !pCamComp)
return false;
pCamComp->SetOrthoLeft(pos.m_left);
pCamComp->SetOrthoRight(pos.m_right);
pCamComp->SetOrthoBottom(pos.m_bottom);
pCamComp->SetOrthoTop(pos.m_top);
pCamComp->UpdateProjectionMatrix();
pCamComp->UpdateViewMatrix();
dtEntity::GetWindowInterface()->RequestRedraw(contextid);
return true;
}
bool BuildingManager::getCameraPosition(unsigned int contextid, BuildingViewer::CameraViewPosition& pos)
{
BuildingDisplay* pBuildingDisplay = getBuildingDisplay(contextid);
if (!pBuildingDisplay)
return false;
dtEntityOSG::CameraComponent *pCamComp = nullptr;
bool success = mEntityManager->GetComponent(pBuildingDisplay->mCameraId, pCamComp);
if (!success || !pCamComp)
return false;
double znear, zfar;
pCamComp->GetCamera()->getProjectionMatrixAsOrtho(pos.m_left, pos.m_right, pos.m_bottom, pos.m_top, znear, zfar);
return true;
}
bool BuildingManager::setDefaultCameraPosition(unsigned int contextid)
{
BuildingDisplay *pBuildingDisplay = getBuildingDisplay(contextid);
if (!pBuildingDisplay)
return false;
Building *building = nullptr;
for (Building *b : mBuildings)
{
for (const auto &dspl : b->mDisplays)
{
if (&dspl == pBuildingDisplay)
{
building = b;
break;
}
}
}
if (!building)
return false;
repositionCamera(*building, *pBuildingDisplay);
return true;
}
bool BuildingManager::displayBuilding(const std::string& featureId, unsigned int contextid, dtEntity::EntityId buildingid, const osg::Vec4 &bgcolor, ViewMode viewmode, bool exactPos)
{
if (!displayBuilding(contextid, buildingid, bgcolor, viewmode, exactPos))
return false;
Building *building = nullptr;
for (Building *b : mBuildings)
{
if (b->mWorldBuildingId == buildingid)
{
building = b;
break;
}
}
assert(building);
auto it = m_mapBuildingRoomNames.find(featureId);
if(it == m_mapBuildingRoomNames.end())
return false;
const std::map<std::string, std::string>& mapRoomNames = it->second;
for(const auto& e : mapRoomNames)
setRoomDisplayName(building, e.first, e.second);
return true;
}
bool BuildingManager::displayBuilding(unsigned int contextid, dtEntity::EntityId buildingid, const osg::Vec4& bgcolor, ViewMode viewmode, bool exactPos)
{
DEBUG_LOG() << "BuildingManager::displayBuilding";
mExactPos = exactPos;
dtEntity::EntityManager &em = *mEntityManager;
Building *building = nullptr;
for (Building *b : mBuildings)
{
if (b->mWorldBuildingId == buildingid)
{
building = b;
break;
}
}
assert(building);
if (!building)
return false;
building->mDisplays.emplace_back(BuildingDisplay(contextid, viewmode));
BuildingDisplay &buildingDisplay = building->mDisplays.back();
dtEntity::WindowCreatedMessage msg;
msg.SetName("Building " + std::to_string(buildingid));
msg.SetContextId(contextid);
em.EmitMessage(msg);
std::string viewname = "Context_" + std::to_string(buildingDisplay.mContextId);
dtEntity::MapSystem *mapsys;
if (!em.GetES(mapsys))
return false;
{
dtEntity::Entity *e;
if (!em.CreateEntity(e))
return false;
buildingDisplay.mAttachPointId = e->GetId();
dtEntity::MapComponent *map;
if (!e->CreateComponent(map))
return false;
map->SetEntityName(viewname);
map->SetMapName("attach");
map->SetUniqueId(viewname);
dtEntityOSG::LayerAttachPointComponent *attach;
if (!e->CreateComponent(attach))
return false;
attach->SetName(dtEntity::SID(viewname));
mapsys->AddToScene(e->GetId());
}
{
ModelSplitterComponent *msc;
bool success = em.GetComponent(buildingid, msc);
assert(success);
if (!success)
return false;
std::vector<dtEntity::EntityId> ids;
std::vector<float> heights;
std::vector<int> floors;
msc->Split(ids, heights, floors, dtEntity::SID(viewname));
for (unsigned int i = 0; i < ids.size(); ++i)
{
dtEntity::EntityId id = ids[i];
int floorId = floors[i];
float height = heights[i];
mapsys->AddToScene(id);
dtEntityOSG::StaticMeshComponent *smc;
success = em.GetComponent(id, smc);
assert(success);
if (!success)
continue;
osg::ComputeBoundsVisitor v;
smc->GetNode()->accept(v);
buildingDisplay.mWorldBounds.expandBy(v.getBoundingBox());
buildingDisplay.mLevels.emplace_back(BuildingLevel(id, floorId, height, v.getBoundingBox()));
RoomDestructionComponent *btc;
if (em.CreateComponent(id, btc))
btc->OnEnteredWorld();
ClearVertexColorsVisitor vcv;
smc->GetNode()->accept(vcv);
}
}
{
dtEntity::Entity *cam;
if (!em.CreateEntity(cam))
return false;
buildingDisplay.mCameraId = cam->GetId();
dtEntityOSG::CameraComponent *camcomp;
if (!cam->CreateComponent(camcomp))
return false;
camcomp->SetContextId(contextid);
camcomp->SetLayerAttachPoint(dtEntity::SID(viewname));
camcomp->SetClearColor(bgcolor);
camcomp->SetProjectionMode(dtEntityOSG::CameraComponent::ModeOrthoId);
camcomp->Finished();
OrthoMotionModelComponent *motion;
if (!cam->CreateComponent(motion))
return false;
motion->SetContextId(contextid);
motion->Finished();
buildingDisplay.pMotion = motion;
buildingDisplay.pMotion->m_callbackCamPosChanged = mCbCamPosChanged;
dtEntity::MapComponent *mapcomp;
if (!cam->CreateComponent(mapcomp))
return false;
std::string name = "cam_" + std::to_string(contextid);
mapcomp->SetEntityName(name);
mapcomp->SetUniqueId(name);
mapcomp->SetMapName("cams");
mapcomp->Finished();
mapsys->AddToScene(cam->GetId());
}
{
dtEntity::Entity *light;
if (!em.CreateEntity(light))
return false;
buildingDisplay.mLightId = light->GetId();
dtEntityOSG::LightComponent *lightcomp;
if (!light->CreateComponent(lightcomp))
return false;
lightcomp->SetVec4(dtEntityOSG::LightComponent::PositionId, osg::Vec4(0.8f, 0.2f, 1, 0));
lightcomp->SetVec4(dtEntityOSG::LightComponent::DiffuseId, osg::Vec4(1, 1, 1, 1));
lightcomp->SetVec4(dtEntityOSG::LightComponent::AmbientId, osg::Vec4(0.5f, 0.5f, 0.5f, 1.0f));
dtEntity::MapComponent *mapc;
if (!light->CreateComponent(mapc))
return false;
std::string name = "light_" + std::to_string(contextid);
mapc->SetEntityName(name);
mapc->SetUniqueId(name);
mapc->SetMapName("lights");
dtEntityOSG::LayerComponent *layer;
if (!light->CreateComponent(layer))
return false;
layer->SetAttachedComponent(dtEntityOSG::LightComponent::TYPE);
layer->SetLayer(dtEntity::SID(viewname));
layer->Finished();
mapsys->AddToScene(light->GetId());
}
applyViewModeToBuildingParts(*building, buildingDisplay);
repositionCamera(*building, buildingDisplay);
{
PlayerSystem *ps;
if (mEntityManager->GetES(ps))
{
for (const auto &i : *ps)
{
PlayerComponent *pc = i.second;
if (dtEntity::GetStringFromSID(pc->GetCurrentCellGroup()) == building->mNavMeshGrpName)
{
IconComponent *ic;
if (mEntityManager->GetComponent(i.first, ic))
addPlayerToBuilding(*building, buildingDisplay, i.first, pc->GetColor(), ic->GetPath(), ic->GetTranslation(), ic->GetVisible());
}
}
}
}
{
QMutexLocker locker(&m_mutexShots);
if (!building->mShots.empty())
{
for (Shot *s : building->mShots)
{
ShotDisplay sd;
sd.mShot = s;
buildingDisplay.mShotDisplays.push_back(std::move(sd));
}
updateShots(*building, buildingDisplay);
}
}
{
DEBUG_LOG() << "mDevices.size = " << building->mDevices.size();
if (!building->mDevices.empty())
{
for (Device *d : building->mDevices)
{
DeviceDisplay sd;
sd.mDevice = d;
sd.mWorldPlayerId = d->mWorldPlayerId;
buildingDisplay.mDeviceDisplays.push_back(std::move(sd));
}
updateDevices(*building, buildingDisplay);
}
}
{
RoomDestructionComponent *btc1;
if (em.GetComponent(buildingid, btc1))
{
const RoomDestructionComponent::RoomDestructions &rd = btc1->GetRoomDestructions();
for (const BuildingLevel &level : buildingDisplay.mLevels)
{
RoomDestructionComponent *btc2;
if (mEntityManager->GetComponent(level.mEntityId, btc2))
{
if (!btc2)
continue;
for (const auto &destr : rd)
btc2->SetRoomDestructionValue(destr.first, destr.second);
}
}
}
}
if(building->mNames.empty())
{
createRoomNames(buildingid, *building);
}
{
if(!building->mNames.empty())
{
for (Name *n : building->mNames)
{
NameDisplay nd;
nd.mName = n;
nd.mWorldPlayerId = n->mWorldPlayerId;
nd.visible = false;
buildingDisplay.mNameDisplays.push_back(std::move(nd));
}
updateNames(*building, buildingDisplay);
}
}
return true;
}
void BuildingManager::closeBuildingDisplay(unsigned int contextid)
{
dtEntity::MapSystem* mapsys;
if (!mEntityManager->GetES(mapsys))
return;
for (Building *building : mBuildings)
{
for (auto it = building->mDisplays.begin(); it != building->mDisplays.end(); ++it)
{
const BuildingDisplay &bd = (*it);
if (bd.mContextId == contextid)
{
osgViewer::CompositeViewer* cv = static_cast<osgViewer::CompositeViewer*>(dtEntityOSG::GetOSGSystemInterface()->GetViewer());
cv->stopThreading();
osgViewer::ViewerBase::Cameras cams;
cv->getCameras(cams);
for (osg::Camera *c : cams)
{
if (c->getGraphicsContext()->getState()->getContextID() == contextid)
{
cv->removeView(dynamic_cast<osgViewer::View*>(c->getView()));
}
}
cv->startThreading();
for (const BuildingLevel &level : bd.mLevels)
{
dtEntity::EntityId eid = level.mEntityId;
mapsys->RemoveFromScene(eid);
mEntityManager->KillEntity(eid);
}
mapsys->RemoveFromScene(bd.mLightId);
mEntityManager->KillEntity(bd.mLightId);
mapsys->RemoveFromScene(bd.mCameraId);
mEntityManager->KillEntity(bd.mCameraId);
mapsys->RemoveFromScene(bd.mAttachPointId);
mEntityManager->KillEntity(bd.mAttachPointId);
for (const PlayerDisplay &pd : bd.mPlayers)
{
mapsys->RemoveFromScene(pd.mLocalPlayerId);
mEntityManager->KillEntity(pd.mLocalPlayerId);
}
for (const DeviceDisplay &pd : bd.mDeviceDisplays)
{
mapsys->RemoveFromScene(pd.mLocalPlayerId);
mEntityManager->KillEntity(pd.mLocalPlayerId);
}
for (const NameDisplay &nd : bd.mNameDisplays)
{
mapsys->RemoveFromScene(nd.mLocalPlayerId);
mEntityManager->KillEntity(nd.mLocalPlayerId);
}
building->mDisplays.erase(it);
return;
}
}
}
}
void BuildingManager::addBuilding(dtEntity::EntityId buildingid, const std::string &featureId)
{
Building *b = new Building;
b->mWorldBuildingId = buildingid;
b->mFeatureId = featureId;
mBuildings.push_back(b);
dtEntityOSG::PositionAttitudeTransformComponent *pat;
mEntityManager->GetComponent(buildingid, pat);
if (!pat)
return;
b->mLocalToWorld.setRotate(pat->GetAttitude());
b->mLocalToWorld.setTrans(pat->GetTranslation());
b->mWorldToLocal = osg::Matrix::inverse(b->mLocalToWorld);
VCtrl::ModelSplitterComponent *msc;
mEntityManager->GetComponent(buildingid, msc);
if (!msc)
return;
b->mNavMeshGrpName = dtEntity::GetStringFromSID(msc->GetBuildingId());
}
BuildingDisplay *BuildingManager::getBuildingDisplay(unsigned int contextid)
{
for (Building *b : mBuildings)
{
for (BuildingDisplay &bd : b->mDisplays)
{
if (bd.mContextId == contextid)
return &bd;
}
}
return nullptr;
}
osg::Vec3 getIsoEyeDir(const Building &bd, const BuildingDisplay &d, float maprotation)
{
if (d.mLockRotation)
{
osg::Vec3 eyedir(0, 1, -0.7f);
eyedir = bd.mWorldToLocal.getRotate() * eyedir;
eyedir.normalize();
eyedir = osg::Quat(-osg::DegreesToRadians(maprotation), osg::Vec3(0, 0, 1)) * eyedir;
return eyedir;
}
else
{
osg::Vec3 eye = osg::Vec3(-1, 1, -1);
eye.normalize();
return eye;
}
}
void BuildingManager::applyViewModeToBuildingParts(const Building &bldg, BuildingDisplay &dspl) const
{
dtEntity::EntityManager &em = *mEntityManager;
dspl.mLocalBounds = osg::BoundingBox();
float maprotation = dspl.mLockRotation ? mMapRotation : 0;
switch (dspl.mViewMode)
{
case ViewMode::ISOMETRIC:
{
float h = dspl.mWorldBounds.radius() * osg::PI_2;
int count = 0;
for (BuildingLevel &lvl : dspl.mLevels)
{
dtEntityOSG::PositionAttitudeTransformComponent *pat;
if (!em.GetComponent(lvl.mEntityId, pat))
{
assert(false);
continue;
}
float height = h * count++;
lvl.mLocalToLevel.makeTranslate(osg::Vec3d(0, 0, height - lvl.mHeightAboveGround));
pat->SetPosition(osg::Vec3d(0, 0, height - lvl.mHeightAboveGround));
osg::ComputeBoundsVisitor v;
pat->GetNode()->accept(v);
dspl.mLocalBounds.expandBy(v.getBoundingBox());
}
break;
}
case ViewMode::ORTHOGRAPHIC:
{
float h = 0;
for (BuildingLevel &lvl : dspl.mLevels)
{
dtEntityOSG::PositionAttitudeTransformComponent *pat;
if (!em.GetComponent(lvl.mEntityId, pat))
{
assert(false);
continue;
}
pat->SetPosition(osg::Vec3d());
osg::ComputeBoundsVisitor v;
pat->GetNode()->accept(v);
float w = v.getBoundingBox().yMax() - v.getBoundingBox().yMin();
h += w * 0.6f;
osg::Vec3d pos(0, h - v.getBoundingBox().center()[1], -lvl.mHeightAboveGround);
pat->SetPosition(pos);
lvl.mLocalToLevel.makeTranslate(osg::Vec3d(0, h - v.getBoundingBox().center()[1], 0));
h += w * 0.6f;
osg::Quat q(0, 0, 0, 1);
if (dspl.mLockRotation)
{
q = bldg.mLocalToWorld.getRotate();
q *= osg::Quat(osg::DegreesToRadians(maprotation), osg::Vec3(0, 0, 1));
lvl.mLocalToLevel.setRotate(q);
}
pat->SetAttitude(q);
osg::ComputeBoundsVisitor v2;
pat->GetNode()->accept(v2);
dspl.mLocalBounds.expandBy(v2.getBoundingBox());
}
break;
}
default:
LOG_ERROR("Unknown view mode set!");
return;
}
dtEntity::GetWindowInterface()->RequestRedraw(dspl.mContextId);
}
void BuildingManager::repositionCamera(const Building &bd, const BuildingDisplay &dspl, bool useOriginViewPos)
{
float maprotation = (dspl.mLockRotation) ? mMapRotation : 0;
osg::Vec3d eyedir;
osg::Vec3d up;
switch (dspl.mViewMode)
{
case ViewMode::ISOMETRIC:
eyedir = getIsoEyeDir(bd, dspl, maprotation);
up.set(0, 0, 1);
break;
case ViewMode::ORTHOGRAPHIC:
eyedir.set(0, 0, -1);
up.set(0, 1, 0);
break;
}
osg::Vec3 pxa(eyedir ^ up);
osg::Vec3 pya(pxa ^ eyedir);
pya.normalize();
osg::Plane py(pya, dspl.mLocalBounds.center());
float ydist = 0;
for (unsigned int i = 0; i < 8; ++i)
{
osg::Vec3 corner = dspl.mLocalBounds.corner(i);
float dist = fabs(py.distance(corner));
ydist = std::max(ydist, dist);
}
ydist *= 1.1f;
dtEntityOSG::CameraComponent *camcomp;
if (!mEntityManager->GetComponent(dspl.mCameraId, camcomp))
return;
bool initialCameraPosWasSet = (m_setInitialCameraPositionSet.find(dspl.mContextId) != m_setInitialCameraPositionSet.end());
double left, right, bottom, top, znear, zfar;
camcomp->GetCamera()->getProjectionMatrixAsOrtho(left, right, bottom, top, znear, zfar);
int x, y, w, h;
dtEntity::GetWindowInterface()->GetWindowGeometry(dspl.mContextId, x, y, w, h);
camcomp->SetOrthoLeft(-ydist * w / h);
camcomp->SetOrthoRight(ydist * w / h);
camcomp->SetOrthoBottom(-ydist);
camcomp->SetOrthoTop(ydist);
camcomp->SetOrthoZNear(-1000);
camcomp->SetOrthoZFar(1000);
m_setInitialCameraPositionSet.insert(dspl.mContextId);
camcomp->SetPosition(dspl.mLocalBounds.center());
camcomp->SetEyeDirection(eyedir);
camcomp->SetUp(up);
camcomp->UpdateProjectionMatrix();
camcomp->UpdateViewMatrix();
if(!useOriginViewPos && initialCameraPosWasSet) {
camcomp->SetOrthoLeft(left);
camcomp->SetOrthoRight(right);
camcomp->SetOrthoBottom(bottom);
camcomp->SetOrthoTop(top);
camcomp->UpdateViewMatrix();
}
dtEntityOSG::LightComponent *light;
if (!mEntityManager->GetComponent(dspl.mLightId, light))
return;
osg::Vec3 dir(0, 0, -1);
if (dspl.mViewMode == ViewMode::ISOMETRIC)
dir = pxa;
light->SetVec3(dtEntityOSG::LightComponent::DirectionId, dir);
}
void BuildingManager::updatePlayerPositions(const Building &bd, BuildingDisplay &dspl)
{
LOG_DEBUG("BuildingManager::updatePlayerPositions: " << " mBuildingDisplayName" << bd.mBuildingDisplayName);
for (PlayerDisplay &pd : dspl.mPlayers)
{
IconComponent *ic;
mEntityManager->GetComponent(pd.mWorldPlayerId, ic);
if (!ic)
continue;
int roomNumber = pd.mIcon->GetRoomNumber();
LOG_DEBUG("BuildingManager::updatePlayerPositions: "
<< ", pd.mWorldPlayerId" << pd.mWorldPlayerId
<< ", roomNumber" << roomNumber);
pd.mIcon->SetTranslation(remapPosition(bd, dspl, ic->GetTranslation(), roomNumber));
pd.mIcon->SetOriginAtBottom(dspl.mViewMode == ViewMode::ISOMETRIC);
}
}
void BuildingManager::changeViewMode(unsigned int contextId, ViewMode viewmode, bool useOriginViewPos)
{
for (Building *bldg : mBuildings)
{
for (BuildingDisplay &dspl : bldg->mDisplays)
{
if (dspl.mContextId == contextId)
{
if (dspl.mViewMode != viewmode)
{
dspl.mViewMode = viewmode;
applyViewModeToBuildingParts(*bldg, dspl);
updateShots(*bldg, dspl);
updatePlayerPositions(*bldg, dspl);
updateDevices(*bldg, dspl);
updateNames(*bldg, dspl);
applyMapRotation(*bldg, dspl);
}
repositionCamera(*bldg, dspl, useOriginViewPos);
dtEntity::GetWindowInterface()->RequestRedraw(contextId);
}
}
}
}
void BuildingManager::applyMapRotation(const Building &bd, BuildingDisplay &dspl)
{
dtEntityOSG::CameraComponent *camcomp;
if (!mEntityManager->GetComponent(dspl.mCameraId, camcomp))
return;
if (dspl.mViewMode == VCtrl::ViewMode::ISOMETRIC)
{
camcomp->SetEyeDirection(getIsoEyeDir(bd, dspl, mMapRotation));
camcomp->UpdateViewMatrix();
dtEntity::GetWindowInterface()->RequestRedraw(dspl.mContextId);
}
else
{
applyViewModeToBuildingParts(bd, dspl);
updatePlayerPositions(bd, dspl);
updateDevices(bd, dspl);
updateNames(bd, dspl);
camcomp->UpdateViewMatrix();
}
updateShots(bd, dspl);
}
void BuildingManager::lockViewRotationToMapRotation(unsigned int contextId, bool lock)
{
for (Building *bldg : mBuildings)
{
for (BuildingDisplay &dspl : bldg->mDisplays)
{
if (dspl.mContextId == contextId && dspl.mLockRotation != lock)
{
dspl.mLockRotation = lock;
repositionCamera(*bldg, dspl, false);
applyViewModeToBuildingParts(*bldg, dspl);
applyMapRotation(*bldg, dspl);
repositionCamera(*bldg, dspl, false);
break;
}
}
}
}
void BuildingManager::setPlayerDisplayMode(unsigned int contextId, PlayerDisplayMode mode)
{
BuildingDisplay *bd = getBuildingDisplay(contextId);
if (!bd)
{
LOG_ERROR("Could not lock view rotation, view with this context id does not exist!");
return;
}
if (bd->mPlayerDisplayMode == mode)
return;
bd->mPlayerDisplayMode = mode;
for (PlayerDisplay &pd : bd->mPlayers)
pd.mIcon->SetShowDot(mode == PlayerDisplayMode::Dots);
dtEntity::GetWindowInterface()->RequestRedraw(bd->mContextId);
}
void BuildingManager::setWallTransparency(unsigned int contextId, float value)
{
BuildingDisplay *bd = getBuildingDisplay(contextId);
if (!bd)
{
LOG_ERROR("Could not lock view rotation, view with this context id does not exist!");
return;
}
SetWallsTransparentVisitor v(value);
for (const BuildingLevel &lvl : bd->mLevels)
{
dtEntityOSG::StaticMeshComponent *smc;
if (!mEntityManager->GetComponent(lvl.mEntityId, smc))
{
assert(false);
continue;
}
smc->GetNode()->accept(v);
}
dtEntity::GetWindowInterface()->RequestRedraw(bd->mContextId);
}
float BuildingManager::getMapRotation() const
{
return mMapRotation;
}
void BuildingManager::setMapRotation(float angle)
{
if (qFuzzyCompare(mMapRotation, angle))
return;
mMapRotation = angle;
for (Building *building : mBuildings)
{
for (BuildingDisplay &bd : building->mDisplays)
{
if (bd.mLockRotation)
applyMapRotation(*building, bd);
}
}
}
void BuildingManager::openOverview(unsigned int contextid)
{
dtEntity::GetDebugDrawInterface()->SetEnabled(true);
dtEntity::WindowCreatedMessage msg;
msg.SetName("Overview");
msg.SetContextId(contextid);
mEntityManager->EmitMessage(msg);
dtEntity::Entity *camera;
if (!mEntityManager->CreateEntity(camera))
return;
dtEntityOSG::CameraComponent *camcomp;
if (!camera->CreateComponent(camcomp))
return;
camcomp->SetClearColor(osg::Vec4(0.2f, 0.2f, 0.2f, 1));
camcomp->SetContextId(contextid);
camcomp->SetEyeDirection(osg::Vec3(0, -1, 0));
camcomp->SetLayerAttachPoint(dtEntity::SID("root"));
camcomp->SetAspectRatio(1.3);
camcomp->Finished();
dtEntity::MapComponent *cammap;
if (!camera->CreateComponent(cammap))
return;
cammap->SetEntityName("cam_overview");
cammap->SetUniqueId("cam_overview");
cammap->SetMapName("cams");
MotionModelComponent *motion;
if (!camera->CreateComponent(motion))
return;
motion->Finished();
dtEntity::MapSystem *ms;
if (mEntityManager->GetES(ms))
ms->AddToScene(camera->GetId());
}
void BuildingManager::addPlayerToBuilding(const Building &bd, BuildingDisplay &dspl, dtEntity::EntityId eid,
const osg::Vec4 &color, const std::string &symbol, const osg::Vec3d &pos, bool visible)
{
PlayerDisplay pd;
pd.mWorldPlayerId = eid;
dtEntity::Entity *e;
if (!mEntityManager->CreateEntity(e))
return;
pd.mLocalPlayerId = e->GetId();
dtEntity::MapComponent *mc;
if (!e->CreateComponent(mc))
return;
std::string en = "ctx_" + std::to_string(dspl.mContextId) + "_plr_" + std::to_string(pd.mWorldPlayerId);
mc->SetEntityName(en);
mc->SetUniqueId(en);
mc->SetMapName("proxies");
if (!e->CreateComponent(pd.mIcon))
return;
pd.mIcon->SetVisible(visible);
pd.mIcon->SetPath(symbol);
pd.mIcon->SetColor(color);
pd.mIcon->SetVOffset(0.0f);
int roomNumber = pd.mIcon->GetRoomNumber();
pd.mIcon->SetTranslation(remapPosition(bd, dspl, pos, roomNumber));
pd.mIcon->SetOriginAtBottom(dspl.mViewMode == ViewMode::ISOMETRIC);
pd.mIcon->SetShowDot(dspl.mPlayerDisplayMode == PlayerDisplayMode::Dots);
pd.mIcon->Finished();
std::string viewname = "Context_" + std::to_string(dspl.mContextId);
dtEntityOSG::LayerComponent *lc;
if (!e->CreateComponent(lc))
return;
lc->SetAttachedComponent(IconComponent::TYPE);
lc->SetLayer(dtEntity::SID(viewname));
dtEntity::MapSystem *ms;
if (!mEntityManager->GetES(ms))
return;
ms->AddToScene(e->GetId());
dspl.mPlayers.push_back(std::move(pd));
dtEntity::GetWindowInterface()->RequestRedraw(dspl.mContextId);
}
void BuildingManager::addPlayerToBuildings(const std::string &navmeshgrpname, dtEntity::EntityId eid,
const osg::Vec4 &color, const std::string &symbol, const osg::Vec3d &pos,
bool visible)
{
for (Building *building : mBuildings)
{
if (building->mNavMeshGrpName != navmeshgrpname)
continue;
for (BuildingDisplay &bd : building->mDisplays)
addPlayerToBuilding(*building, bd, eid, color, symbol, pos, visible);
}
}
void BuildingManager::removePlayerFromBuilding(const std::string &navmeshgrpname, dtEntity::EntityId eid, const std::string& roomname)
{
if (mExactPos == false)
deleteRoomUsagePlayer(navmeshgrpname, roomname, eid);
for (Building *building : mBuildings)
{
if (building->mNavMeshGrpName != navmeshgrpname)
continue;
for (BuildingDisplay &bd : building->mDisplays)
{
for (auto it = bd.mPlayers.begin(); it != bd.mPlayers.end(); ++it)
{
const PlayerDisplay &pd = *it;
if (pd.mWorldPlayerId == eid)
{
dtEntity::MapSystem *ms;
if (mEntityManager->GetES(ms))
ms->RemoveFromScene(pd.mLocalPlayerId);
mEntityManager->KillEntity(pd.mLocalPlayerId);
bd.mPlayers.erase(it);
dtEntity::GetWindowInterface()->RequestRedraw(bd.mContextId);
break;
}
}
}
}
}
void BuildingManager::updatePlayerPosition(const std::string &navmeshgrpname, dtEntity::EntityId eid, const osg::Vec3d &pos, int roomNumber)
{
LOG_DEBUG("BuildingManager::updatePlayerPosition: " << "navmeshgrpname='"<< navmeshgrpname << "'"
<< ", eid/WorldPlayerId="<< eid
<< ", pos: x=" << pos.x() << " y=" << pos.y() << " z=" << pos.z()
<< ", roomNumber="<< roomNumber);
for (Building *building : mBuildings)
{
if (building->mNavMeshGrpName != navmeshgrpname)
continue;
for (BuildingDisplay &bd : building->mDisplays)
{
for (PlayerDisplay &pd : bd.mPlayers)
{
if (pd.mWorldPlayerId == eid)
{
pd.mIcon->SetTranslation(remapPosition(*building, bd, pos, roomNumber));
pd.mIcon->SetRoomNumber(roomNumber);
dtEntity::GetWindowInterface()->RequestRedraw(bd.mContextId);
break;
}
}
}
}
}
osg::Vec3d BuildingManager::remapPosition(const Building &bd, const BuildingDisplay &dspl, const osg::Vec3d &world, int roomNumber)
{
DEBUG_LOG() << Q_FUNC_INFO << " mFeatureId = " << bd.mFeatureId.c_str()
<< ", roomNumber= " << roomNumber;
if (roomNumber > 0)
{
int floorOut;
if (getFloorOfRoom(bd.mFeatureId, roomNumber, floorOut))
{
for (const auto &level : dspl.mLevels)
{
if (level.mFloorId == floorOut)
{
const osg::Vec3d &l = world * bd.mWorldToLocal;
DEBUG_LOG() << Q_FUNC_INFO << " mFeatureId = " << bd.mFeatureId.c_str()
<< ", roomNumber= " << roomNumber
<< ", floorOut= " << floorOut
<< ", world.z()= " << world.z()
<< ", RET value is =" << (l * level.mLocalToLevel).z();
return l * level.mLocalToLevel;
}
}
}
}
const osg::Vec3d l = world * bd.mWorldToLocal;
const size_t numlevels = dspl.mLevels.size();
for (unsigned int i = 0; i < numlevels; ++i)
{
if (i == (numlevels - 1) || (dspl.mLevels[i + 1].mHeightAboveGround - 0.1f) > l[2])
{
const BuildingLevel &level = dspl.mLevels[i];
DEBUG_LOG() << Q_FUNC_INFO
<< " remapXPosition"
<< ", l.z=" << l.z()
<< ", i=" << i
<< ", numlevels=" << numlevels
<< ", (dspl.mLevels[i + 1].mHeightAboveGround - 0.1f)="
<< (dspl.mLevels[i + 1].mHeightAboveGround - 0.1f)
<< ", l[2]=" << l[2]
<< ", ret=" << (l * level.mLocalToLevel).z();
return l * level.mLocalToLevel;
}
}
LOG_ERROR("Could not remap position!");
return world;
}
void BuildingManager::setPlayerColor(dtEntity::EntityId eid, const osg::Vec4 &color)
{
for (Building *building : mBuildings)
{
for (BuildingDisplay &bd : building->mDisplays)
{
for (PlayerDisplay &pd : bd.mPlayers)
{
if (pd.mWorldPlayerId == eid)
{
pd.mIcon->SetColor(color);
dtEntity::GetWindowInterface()->RequestRedraw(bd.mContextId);
break;
}
}
}
}
}
void BuildingManager::setPlayerIcon(dtEntity::EntityId eid, const std::string &path)
{
for (Building *building : mBuildings)
{
for (BuildingDisplay &bd : building->mDisplays)
{
for (PlayerDisplay &pd : bd.mPlayers)
{
if (pd.mWorldPlayerId == eid)
{
pd.mIcon->SetPath(path);
dtEntity::GetWindowInterface()->RequestRedraw(bd.mContextId);
break;
}
}
}
}
}
void BuildingManager::reloadPlayerIcons()
{
for (Building *building : mBuildings)
{
for (BuildingDisplay &bd : building->mDisplays)
{
for (PlayerDisplay &pd : bd.mPlayers)
pd.mIcon->Reload();
if (bd.mPlayers.size())
dtEntity::GetWindowInterface()->RequestRedraw(bd.mContextId);
}
}
}
void BuildingManager::updatePlayerPartyColor(dtEntity::EntityId eid, const VCtrl::Color& col)
{
for (Building *building : mBuildings)
{
for (BuildingDisplay &bd : building->mDisplays)
{
for (PlayerDisplay &pd : bd.mPlayers)
{
if (pd.mWorldPlayerId == eid)
{
pd.mIcon->SetColor(osg::Vec4(col.x,col.y,col.z,col.w));
dtEntity::GetWindowInterface()->RequestRedraw(bd.mContextId);
break;
}
}
}
}
}
void BuildingManager::setShowPlayerSelection(dtEntity::EntityId eid, bool show)
{
for (Building *building : mBuildings)
{
for (BuildingDisplay &bd : building->mDisplays)
{
for (PlayerDisplay &pd : bd.mPlayers)
{
if (pd.mWorldPlayerId == eid)
{
pd.mIcon->SetShowSelection(show);
dtEntity::GetWindowInterface()->RequestRedraw(bd.mContextId);
break;
}
}
}
}
}
void BuildingManager::setShowHidePlayer(dtEntity::EntityId eid, bool show)
{
for (Building *building : mBuildings)
{
for (BuildingDisplay &bd : building->mDisplays)
{
for (PlayerDisplay &pd : bd.mPlayers)
{
if (pd.mWorldPlayerId == eid)
{
if (pd.mIcon->GetVisible() != show)
{
pd.mIcon->SetVisible(show);
dtEntity::GetWindowInterface()->RequestRedraw(bd.mContextId);
}
break;
}
}
}
}
}
void BuildingManager::setRoomDestructionValue(dtEntity::EntityId eid, const std::string &roomname, float value)
{
for (const Building *building : mBuildings)
{
if (building->mWorldBuildingId != eid)
continue;
for (const BuildingDisplay &bd : building->mDisplays)
{
bool bRequestRedraw = false;
for (const BuildingLevel &level : bd.mLevels)
{
RoomDestructionComponent *btc;
if (mEntityManager->GetComponent(level.mEntityId, btc))
{
btc->SetRoomDestructionValue(roomname, value);
bRequestRedraw = true;
}
}
if (bRequestRedraw)
dtEntity::GetWindowInterface()->RequestRedraw(bd.mContextId);
}
break;
}
}
void BuildingManager::setBuildingDestructionValue(dtEntity::EntityId eid, float value)
{
for (const Building *building : mBuildings)
{
if (building->mWorldBuildingId != eid)
continue;
for (const BuildingDisplay &bd : building->mDisplays)
{
bool bRequestRedraw = false;
for (const BuildingLevel &level : bd.mLevels)
{
RoomDestructionComponent *btc;
if (mEntityManager->GetComponent(level.mEntityId, btc))
{
btc->SetBuildingDestructionValue(value);
bRequestRedraw = true;
}
}
if (bRequestRedraw)
dtEntity::GetWindowInterface()->RequestRedraw(bd.mContextId);
}
break;
}
}
dtEntity::EntityId BuildingManager::getWorldPlayerIdFromLocalPlayer(dtEntity::EntityId local) const
{
for (const Building *building : mBuildings)
{
for (const BuildingDisplay &bd : building->mDisplays)
{
for (const PlayerDisplay &pd : bd.mPlayers)
{
if (pd.mLocalPlayerId == local)
return pd.mWorldPlayerId;
}
for (const DeviceDisplay &pd : bd.mDeviceDisplays)
{
if (pd.mLocalPlayerId == local)
return pd.mWorldPlayerId;
}
}
}
return 0;
}
void BuildingManager::removeShoot(int32_t id)
{
DEBUG_LOG() << "removeShoot id=" << id;
QMutexLocker locker(&m_mutexShots);
for (Building *bldg : mBuildings)
{
DEBUG_LOG() << "Vorher: bldg->mShots.size()=" << bldg->mShots.size();
auto it = std::remove_if(bldg->mShots.begin(), bldg->mShots.end(),
[id]( Shot *shot)
{
if (shot->getId() == id)
{
const unsigned int duration = 0;
shot->setDisplayTime(duration);
return true;
}
return false;
});
bool wasRemoved = (it != bldg->mShots.end());
bldg->mShots.erase(it, bldg->mShots.end());
DEBUG_LOG() << "Nachher: bldg->mShots.size()=" << bldg->mShots.size();
if (wasRemoved)
for (BuildingDisplay &dspl : bldg->mDisplays)
{
DEBUG_LOG() << "wasRemoved id=" << id;
updateShots(*bldg, dspl);
dtEntity::GetWindowInterface()->RequestRedraw(dspl.mContextId);
}
}
}
void BuildingManager::showShoot(int32_t id, dtEntity::EntityId shooter, dtEntity::EntityId target,
const dtEntity::Vec3d &shooterPos, const dtEntity::Vec3d &targetPos,
int buildingIdSrc, int roomNumberSrc, int buildingIdDst, int roomNumberDst,
int lineType, float duration, double simTimeCreated)
{
PlayerComponent *shooterpc, *targetpc;
mEntityManager->GetComponent(shooter, shooterpc);
mEntityManager->GetComponent(target, targetpc);
if (!shooterpc)
{
assert(false);
return;
}
if (mShotOverview == false && targetpc)
{
if (shooterpc->GetCurrentCellGroup() != targetpc->GetCurrentCellGroup())
return;
}
std::string navmeshname = dtEntity::GetStringFromSID(shooterpc->GetCurrentCellGroup());
std::string targetnavmeshname;
if (mShotOverview == true && targetpc)
targetnavmeshname = dtEntity::GetStringFromSID(targetpc->GetCurrentCellGroup());
QMutexLocker locker(&m_mutexShots);
for (Building *bldg : mBuildings)
{
if ((targetpc == nullptr && target == bldg->mWorldBuildingId) ||
(bldg->mNavMeshGrpName == navmeshname) ||
(bldg->mNavMeshGrpName == targetnavmeshname))
{
double _simTimeCreated = simTimeCreated != 0 ? simTimeCreated : dtEntity::GetSystemInterface()->GetSimulationTime() ;
Shot* shot = new Shot(id,
shooterPos,
targetPos,
buildingIdSrc, roomNumberSrc,
buildingIdDst, roomNumberDst,
lineType,
shooterpc->GetColor(),
static_cast<unsigned int>(duration),
120,
_simTimeCreated);
for(const auto it : bldg->mShots)
{
if (it->getId() == shot->getId())
{
delete shot;
return;
}
}
bldg->mShots.push_back(shot);
DEBUG_LOG() << "XXXX SIM TIME CREATED = " << QString::number(_simTimeCreated, 'f', 5) << " and SIM TIME IS " <<QString::number(dtEntity::GetSystemInterface()->GetSimulationTime(), 'f', 5);
for (BuildingDisplay &bldgDispl : bldg->mDisplays)
{
ShotDisplay shotDispl;
shotDispl.mShot = shot;
DEBUG_LOG() << "mShotDisplays.push_back id=" << shot->getId();
bldgDispl.mShotDisplays.push_back(std::move(shotDispl));
updateShots(*bldg, bldgDispl);
dtEntity::GetWindowInterface()->RequestRedraw(bldgDispl.mContextId);
}
if (targetpc == nullptr && target == bldg->mWorldBuildingId)
break;
}
}
}
void BuildingManager::updateShots(const Building &bd, BuildingDisplay &dspl)
{
DEBUG_LOG() << Q_FUNC_INFO << " Building= " << bd.mWorldBuildingId;
dtEntityOSG::CameraComponent *camcomp;
if (!mEntityManager->GetComponent(dspl.mCameraId, camcomp))
return;
osg::Vec3 eyedir(camcomp->GetEyeDirection());
dtEntityOSG::LayerAttachPointComponent *lac;
if (!mEntityManager->GetComponent(dspl.mAttachPointId, lac))
return;
const double simTime = dtEntity::GetSystemInterface()->GetSimulationTime();
DEBUG_LOG() << Q_FUNC_INFO << " dspl.mShotDisplays.size()= " << dspl.mShotDisplays.size()
<< ", simTime=" << (int)simTime;
for (ShotDisplay &shotdspl : dspl.mShotDisplays)
{
if (!shotdspl.mShot)
continue;
const bool bDisplay = (shotdspl.mShot->displayTime() > simTime) && (shotdspl.mShot->simTimeCreated() <= simTime);
while (shotdspl.mGeode.valid() && shotdspl.mGeode->getNumParents() > 0)
shotdspl.mGeode->getParent(0)->removeChild(shotdspl.mGeode);
shotdspl.mGeode = osg::ref_ptr<osg::Geode>();
int numParents = -1;
if (shotdspl.mGeode)
numParents = shotdspl.mGeode->getNumParents();
DEBUG_LOG() << Q_FUNC_INFO << " BB shotdspl.mShot->getId()= " << shotdspl.mShot->getId()
<< ", shotdspl.mGeode=" << shotdspl.mGeode
<< ", shotdspl.mGeode->getNumParents=" << numParents
<< ", bDisplay=" << bDisplay;
if ((!shotdspl.mGeode || shotdspl.mGeode->getNumParents() == 0) && bDisplay)
{
DEBUG_LOG() << "NEW mGeode! id " << shotdspl.mShot->getId();
if (!shotdspl.mGeode)
shotdspl.mGeode = new osg::Geode();
osg::StateSet *ss = shotdspl.mGeode->getOrCreateStateSet();
ss->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
ss->setRenderBinDetails(240001, "RenderBin");
osg::ref_ptr<osg::LineWidth> lw = new osg::LineWidth();
DEBUG_LOG() << "NEW LINE " << shotdspl.mShot->getLineType();
if (shotdspl.mShot->getLineType() < 2 )
{
int stippleSize = 5;
if (shotdspl.mShot->getLineType() == 1)
stippleSize = 2;
osg::ref_ptr<osg::LineStipple> ls = new osg::LineStipple(stippleSize, 0xAAAA);
ss->setAttributeAndModes(ls, osg::StateAttribute::ON | osg::StateAttribute::OVERRIDE);
}
lw->setWidth(2);
ss->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
osg::Geometry *gmtr = new osg::Geometry();
shotdspl.mGeode->addDrawable(gmtr);
osg::Vec4Array *col = new osg::Vec4Array(1);
(*col)[0] = shotdspl.mShot->getColor();
gmtr->setColorArray(col);
gmtr->setColorBinding(osg::Geometry::BIND_OVERALL);
osg::Vec3d shooterpos = remapPosition(bd, dspl, shotdspl.mShot->getShooterPos(), shotdspl.mShot->getRoomNumberSrc());
osg::Vec3d targetpos = remapPosition(bd, dspl, shotdspl.mShot->getTargetPos(), shotdspl.mShot->getRoomNumberDst());
shooterpos[2] += 1;
targetpos[2] += 1;
DEBUG_LOG() << Q_FUNC_INFO << " shotdspl.mShot->getId()= " << shotdspl.mShot->getId()
<< ", getShooterPos.z()=" << shotdspl.mShot->getShooterPos().z()
<< ", BuildingIdSrc=" << shotdspl.mShot->getBuildingIdSrc() << ", RoomNumberSrc=" << shotdspl.mShot->getRoomNumberSrc()
<< ", shooterpos=" << shooterpos
<< ", getTargetPos.z()=" << shotdspl.mShot->getTargetPos().z()
<< ", BuildingIdDst=" << shotdspl.mShot->getBuildingIdDst() << ", RoomNumberDst=" << shotdspl.mShot->getRoomNumberDst()
<< ", targetpos=" << targetpos;
osg::Vec3Array *coords = new osg::Vec3Array(6);
(*coords)[0] = shooterpos;
(*coords)[1] = targetpos;
osg::Vec3d edge = targetpos - shooterpos;
edge.normalize();
edge *= 0.8;
osg::Vec3d p1 = eyedir ^ edge;
p1.normalize();
p1 *= 0.8;
(*coords)[2] = p1 - edge * 1.5 + targetpos;
(*coords)[3] = targetpos;
(*coords)[4] = -p1 - edge * 1.5 + targetpos;
(*coords)[5] = targetpos;
gmtr->setVertexArray(coords);
gmtr->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINES, 0, 6));
}
if (bDisplay)
lac->GetNode()->asGroup()->addChild(shotdspl.mGeode);
}
}
void BuildingManager::updateDevices(const Building &bd, BuildingDisplay &dspl)
{
for (DeviceDisplay &ddspl : dspl.mDeviceDisplays)
{
IconComponent *icon;
if (ddspl.mLocalPlayerId == 0)
{
dtEntity::Entity *e;
if (!mEntityManager->CreateEntity(e))
continue;
ddspl.mLocalPlayerId = e->GetId();
dtEntity::MapComponent *mc;
if (!e->CreateComponent(mc))
continue;
std::string en = "ctx_" + std::to_string(dspl.mContextId) + "_plr_" + std::to_string(ddspl.mDevice->mWorldPlayerId);
mc->SetEntityName(en);
mc->SetUniqueId(en);
mc->SetMapName("deviceproxies");
if (!e->CreateComponent(icon))
continue;
icon->SetPath(ddspl.mDevice->mPath);
icon->SetOriginAtBottom(false);
dtEntityOSG::LayerComponent *lc;
if (!e->CreateComponent(lc))
continue;
std::string viewname = "Context_" + std::to_string(dspl.mContextId);
lc->SetAttachedComponent(IconComponent::TYPE);
lc->SetLayer(dtEntity::SID(viewname));
dtEntity::MapSystem *ms;
if (mEntityManager->GetES(ms))
ms->AddToScene(e->GetId());
}
else
{
if (!mEntityManager->GetComponent(ddspl.mLocalPlayerId, icon))
{
assert(false);
continue;
}
}
int roomNumber = icon->GetRoomNumber();
icon->SetTranslation(remapPosition(bd, dspl, ddspl.mDevice->mPosition, roomNumber));
icon->Finished();
icon->SetVisible(true);
}
}
void BuildingManager::addDeviceToBuilding(dtEntity::EntityId iconmainid, dtEntity::EntityId buildingid,
const osg::Vec3d &pos, const std::string &iconpath)
{
DEBUG_LOG() << "addDeviceToBuilding";
for (Building *building : mBuildings)
{
DEBUG_LOG() << "mWorldBuildingId=" << building->mWorldBuildingId
<< " buildingid=" << buildingid;
if (building->mWorldBuildingId != buildingid)
continue;
DEBUG_LOG() << "addDeviceToBuilding 1";
Device *device = new Device();
device->mWorldPlayerId = iconmainid;
device->mPath = iconpath;
device->mPosition = pos;
building->mDevices.push_back(device);
DEBUG_LOG() << "building->mDisplays.size=" << building->mDisplays.size();
for (BuildingDisplay &dspl : building->mDisplays)
{
DEBUG_LOG() << "addDeviceToBuilding 2";
DeviceDisplay dd;
dd.mDevice = device;
dd.mWorldPlayerId = iconmainid;
dspl.mDeviceDisplays.push_back(std::move(dd));
updateDevices(*building, dspl);
dtEntity::GetWindowInterface()->RequestRedraw(dspl.mContextId);
}
break;
}
}
void BuildingManager::removeDeviceFromBuilding(dtEntity::EntityId iconmainid)
{
for (Building *building : mBuildings)
{
std::vector<Device *>::iterator j = building->mDevices.begin();
while (j != building->mDevices.end())
{
Device *device = *j;
if (device->mWorldPlayerId == iconmainid)
{
for (BuildingDisplay &bd : building->mDisplays)
{
std::vector<DeviceDisplay>::iterator l = bd.mDeviceDisplays.begin();
while (l != bd.mDeviceDisplays.end())
{
DeviceDisplay &pd = *l;
if (pd.mDevice->mWorldPlayerId == iconmainid)
{
dtEntity::MapSystem *ms;
mEntityManager->GetES(ms);
if (ms)
ms->RemoveFromScene(pd.mLocalPlayerId);
mEntityManager->KillEntity(pd.mLocalPlayerId);
dtEntity::GetWindowInterface()->RequestRedraw(bd.mContextId);
l = bd.mDeviceDisplays.erase(l);
}
else
++l;
}
}
j = building->mDevices.erase(j);
delete device;
}
else
++j;
}
}
}
template <class T>
bool fetchAttr(T &t, const rapidxml::xml_node<> *node, const char *name)
{
using namespace rapidxml;
for (xml_attribute<> *attr = node->first_attribute(); attr; attr = attr->next_attribute())
{
if (strcmp(attr->name(), name) == 0)
{
std::istringstream iss(attr->value());
return !(iss >> std::dec >> t).fail();
}
}
return false;
}
static bool HasTagName(const rapidxml::xml_node<> *node, const char *name)
{
return (node->type() == rapidxml::node_element && strcmp(name, node->name()) == 0);
}
bool BuildingManager::getRoomBounds(const std::string &bldgname, const std::string &roomname, VCtrl::OBB &obb) const
{
const std::string key = bldgname + " " + roomname;
auto i = mRooms.find(key);
if (i == mRooms.end() || !i->second.mBB.valid())
{
for (const auto &room : mRooms)
{
const osg::BoundingBox &bb = room.second.mBB;
QByteArray ba("id: ");
ba += room.first.c_str();
ba += ", min: " +
QByteArray::number(bb.xMin()) + ", " +
QByteArray::number(bb.yMin()) + ", " +
QByteArray::number(bb.zMin());
ba += ", max: " +
QByteArray::number(bb.xMax()) + ", " +
QByteArray::number(bb.yMax()) + ", " +
QByteArray::number(bb.zMax());
#ifdef LTS_DEBUG
LOG_ERROR(ba.data());
#endif
}
LOG_ERROR("Could not find room " << bldgname << "-" << roomname << ", #mRooms: " << mRooms.size());
return false;
}
obb = i->second;
if (!obb.mBB.valid())
{
LOG_ERROR("Room" << bldgname << "-" << roomname << " has invalid bounds");
return false;
}
return true;
}
static void readBBoxMin(const rapidxml::xml_node<> *roomnode, VCtrl::OBB &room)
{
if (HasTagName(roomnode, "BBox_Min"))
{
fetchAttr(room.mBB._min[0], roomnode, "X");
fetchAttr(room.mBB._min[1], roomnode, "Y");
fetchAttr(room.mBB._min[2], roomnode, "Z");
}
}
static void readBBoxMax(const rapidxml::xml_node<> *roomnode, VCtrl::OBB &room)
{
if (HasTagName(roomnode, "BBox_Max"))
{
fetchAttr(room.mBB._max[0], roomnode, "X");
fetchAttr(room.mBB._max[1], roomnode, "Y");
fetchAttr(room.mBB._max[2], roomnode, "Z");
}
}
static void readPolygon(const rapidxml::xml_node<> *roomnode, VCtrl::OBB &room)
{
if (HasTagName(roomnode, "Group"))
{
for (auto grp0node(roomnode->first_node()); grp0node != nullptr; grp0node = grp0node->next_sibling())
{
if (HasTagName(grp0node, "Polygon"))
{
for (auto grp1node(grp0node->first_node()); grp1node != nullptr; grp1node = grp1node->next_sibling())
{
if (HasTagName(grp1node, "Vertex"))
{
for (auto grp2node(grp1node->first_node()); grp2node != nullptr; grp2node = grp2node->next_sibling())
{
if (HasTagName(grp2node, "Coord"))
{
double x,y;
fetchAttr(x, grp2node, "X");
fetchAttr(y, grp2node, "Y");
room.mPoly.append(QPointF(x,y));
}
}
}
}
}
}
}
}
bool BuildingManager::AddRoomOBBs(const BuildingData &b)
{
LOG_DEBUG("AddRoomOBBs: " + b.mFileName);
if (b.mBuildingXMLPath.empty())
{
LOG_WARNING("Buildings xml is not set: " + b.mFileName);
return false;
}
const std::string xmlpath = b.mBuildingXMLPath;
using namespace rapidxml;
const std::string absPath = dtEntity::GetSystemInterface()->FindDataFile(xmlpath);
if (absPath.empty())
{
LOG_ERROR("Map not found: " + absPath);
return false;
}
file<> file(absPath.c_str());
try
{
xml_document<> doc;
doc.parse<0>(file.data());
xml_node<> *rootnode = doc.first_node("STREIF");
if (rootnode == nullptr)
{
LOG_ERROR("Could not parse building xml!");
return false;
}
int floorNumber = -999;
std::map<int, int> roomToFloor;
for (xml_node<> *hdrNode(rootnode->first_node()); hdrNode != nullptr; hdrNode = hdrNode->next_sibling())
{
if (HasTagName(hdrNode, "Header"))
{
for (xml_node<> *grp1Node(hdrNode->first_node()); grp1Node != nullptr; grp1Node = grp1Node->next_sibling())
{
if (HasTagName(grp1Node, "Group"))
{
for (xml_node<> *grp2Node(grp1Node->first_node()); grp2Node != nullptr; grp2Node = grp2Node->next_sibling())
{
if (HasTagName(grp2Node, "Group"))
{
for (xml_node<> *swtchNode(grp2Node->first_node()); swtchNode != nullptr; swtchNode = swtchNode->next_sibling())
{
std::string temp;
if (HasTagName(swtchNode, "Name"))
{
temp = swtchNode->value();
if (temp.substr(0,6).compare("floor_") == 0)
{
bool bOk = false;
floorNumber = QString::fromStdString(temp.substr(6)).toInt(&bOk);
if (!bOk)
floorNumber = -999;
}
}
if (HasTagName(swtchNode, "Switch"))
{
VCtrl::OBB room;
room.mMatrix.setTrans(b.mX, b.mY, b.mZ);
osg::Quat q;
q.makeRotate(-b.mOrientation / 180.0 * osg::PI, osg::Vec3(0, 0, 1));
room.mMatrix.setRotate(q);
room.mMatrixInverse.invert(room.mMatrix);
std::string name;
for (xml_node<> *roomnode(swtchNode->first_node()); roomnode != nullptr; roomnode = roomnode->next_sibling())
{
int roomNumber = -999;
if (HasTagName(roomnode, "Name"))
{
temp = roomnode->value();
if (temp.substr(0,8).compare("SW_room_") == 0)
{
bool bOk = false;
roomNumber = QString::fromStdString(temp.substr(8)).toInt(&bOk);
if (!bOk)
roomNumber = -999;
if (roomNumber>=0)
roomToFloor[roomNumber+2000]=floorNumber;
}
}
if (HasTagName(roomnode, "SubId"))
{
for (xml_attribute<> *attr = roomnode->first_attribute(); attr; attr = attr->next_attribute())
{
if (strcmp(attr->name(), "ID") == 0)
name = attr->value();
}
}
if (name.empty())
continue;
readBBoxMin(roomnode, room);
readBBoxMax(roomnode, room);
}
if (!room.mBB.valid())
{
for (auto roomnode(swtchNode->first_node()); roomnode != nullptr; roomnode = roomnode->next_sibling())
{
if (HasTagName(roomnode, "Group"))
{
for (auto grp3node(roomnode->first_node()); grp3node != nullptr; grp3node = grp3node->next_sibling())
{
readBBoxMin(grp3node, room);
readBBoxMax(grp3node, room);
readPolygon(grp3node, room);
}
if (room.mBB.valid() && !room.mPoly.empty())
{
break;
}
}
}
}
if (!room.mBB.valid())
LOG_ERROR("Could not parse room bounding boxes for room" << name << " in xml " << xmlpath);
room.mBB._min[2] -= ROOM_OBB_Z_MIN_SUBTRACT;
room.mBB._max[2] -= ROOM_OBB_Z_MAX_SUBTRACT;
if (!room.mBB.valid())
{
LOG_ERROR("Subtract from room OBB height fails, revert... room=" << name);
room.mBB._min[2] += ROOM_OBB_Z_MIN_SUBTRACT;
room.mBB._max[2] += ROOM_OBB_Z_MAX_SUBTRACT;
}
if (!room.mBB.valid())
LOG_ERROR("Could not parse room bounding boxes for room " << name << " in xml " << xmlpath);
const std::string key = b.mFeatureId + " " + name;
room.mBuilding = dtEntity::SID(b.mFeatureId);
mRooms[key] = room;
dtEntity::GetDebugDrawInterface()->AddOBB(room.mMatrix, room.mBB._min, room.mBB._max, osg::Vec4(1, 0, 1, 1), 1, FLT_MAX, false);
osg::Vec3 pos = room.mBB.center() * room.mMatrix;
dtEntity::GetDebugDrawInterface()->AddString(pos, key, osg::Vec4(0, 1, 0, 1), FLT_MAX, false);
}
}
}
}
}
}
}
}
mRoomToFloorPerBldg[b.mFeatureId] = roomToFloor;
}
catch (const std::exception &ex)
{
LOG_ERROR("XML Parsing error: " + std::string(ex.what()));
return false;
}
return true;
}
bool BuildingManager::LoadBuildings(const std::string &path, std::vector<BuildingData> &buildings)
{
using namespace rapidxml;
const std::string absPath = dtEntity::GetSystemInterface()->FindDataFile(path);
if (absPath.empty())
{
LOG_ERROR("Map not found: " + absPath);
return false;
}
file<> file(absPath.c_str());
try
{
xml_document<> doc;
doc.parse<0>(file.data());
xml_node<> *rootnode = doc.first_node("MetaData");
if (rootnode == nullptr)
{
LOG_ERROR("Could not parse map xml!");
return false;
}
for (xml_node<> *tagNode(rootnode->first_node()); tagNode != nullptr; tagNode = tagNode->next_sibling())
{
if (HasTagName(tagNode, "Tag"))
{
int topmesh = -1;
for (xml_node<> *groupNode(tagNode->first_node()); groupNode != nullptr; groupNode = groupNode->next_sibling())
{
if (HasTagName(groupNode, "Group"))
{
++topmesh;
for (xml_node<> *modelNode(groupNode->first_node()); modelNode != nullptr; modelNode = modelNode->next_sibling())
{
if (HasTagName(modelNode, "Model"))
{
BuildingData b;
for (xml_node<> *dataNode(modelNode->first_node()); dataNode != nullptr; dataNode = dataNode->next_sibling())
{
if (HasTagName(dataNode, "Orientation"))
fetchAttr(b.mOrientation, dataNode, "Angle");
else if (HasTagName(dataNode, "Position"))
{
fetchAttr(b.mX, dataNode, "X");
fetchAttr(b.mY, dataNode, "Y");
fetchAttr(b.mZ, dataNode, "Z");
}
else if (HasTagName(dataNode, "Description"))
fetchAttr(b.mDescription, dataNode, "Name");
else if (HasTagName(dataNode, "Feature"))
fetchAttr(b.mFeatureId, dataNode, "Id");
else if (HasTagName(dataNode, "File"))
fetchAttr(b.mFileName, dataNode, "Name");
else if (HasTagName(dataNode, "STREIF"))
fetchAttr(b.mBuildingXMLPath, dataNode, "Name");
}
b.mBuildingGroup = topmesh;
LOG_INFO("add building " + b.mFeatureId + " - " + b.mFileName);
buildings.push_back(std::move(b));
}
}
}
}
}
}
}
catch (const std::exception &ex)
{
LOG_ERROR("XML Parsing error: " + std::string(ex.what()));
return false;
}
return true;
}
size_t BuildingManager::getNumBuildings() const
{
return mBuildings.size();
}
void BuildingManager::getBuildingIds(std::vector<dtEntity::EntityId> &toFill) const
{
toFill.reserve(mBuildings.size());
for (const Building *building : mBuildings)
toFill.push_back(building->mWorldBuildingId);
}
dtEntity::EntityId BuildingManager::getNextBuilding(const osg::Vec3d &pos, float &distance, std::string &featureId) const
{
const osg::Vec2d pos2d(pos[0], pos[1]);
float minDist = 1000000.0f;
dtEntity::EntityId eid = -1;
for (const Building *building : mBuildings)
{
const osg::Vec3d currentPos = osg::Vec3d(0, 0, 0) * building->mLocalToWorld;
const osg::Vec2d currentPos2d(currentPos[0], currentPos[1]);
float dist = (currentPos2d - pos2d).length();
if (dist < minDist)
{
minDist = dist;
eid = building->mWorldBuildingId;
featureId = building->mFeatureId;
}
}
distance = minDist;
return eid;
}
Building BuildingManager::getBuildingFromFeatureId(const std::string &bldname) const
{
Building bld;
bld.mWorldBuildingId = 0;
for (const Building *building : mBuildings)
{
if (building->mFeatureId == bldname)
{
bld.mBuildingDisplayName = building->mBuildingDisplayName;
bld.mFeatureId = building->mFeatureId;
bld.mWorldBuildingId = building->mWorldBuildingId;
}
}
return bld;
}
void BuildingManager::updateNames(const Building& bd, BuildingDisplay& dspl)
{
for (NameDisplay& ddspl : dspl.mNameDisplays)
{
TextComponent *name;
if (ddspl.mLocalPlayerId == 0)
{
dtEntity::Entity* e;
if (!mEntityManager->CreateEntity(e))
continue;
ddspl.mLocalPlayerId = e->GetId();
dtEntity::MapComponent* mc;
if (!e->CreateComponent(mc))
continue;
std::string en = "ctx_" + std::to_string(dspl.mContextId) +
"_nam_" + std::to_string(ddspl.mName->mWorldPlayerId);
mc->SetEntityName(en);
mc->SetUniqueId(en);
mc->SetMapName("nameproxies");
if (!e->CreateComponent(name))
continue;
name->SetText(ddspl.mName->mtext);
name->SetDisText(ddspl.mName->mdistext);
dtEntityOSG::LayerComponent* lc;
if (!e->CreateComponent(lc))
continue;
std::string viewname = "Context_" + std::to_string(dspl.mContextId);
lc->SetAttachedComponent(TextComponent::TYPE);
lc->SetLayer(dtEntity::SID(viewname));
dtEntity::MapSystem* ms;
if (mEntityManager->GetES(ms))
ms->AddToScene(e->GetId());
}
else
{
if (!mEntityManager->GetComponent(ddspl.mLocalPlayerId, name))
{
assert(false);
continue;
}
}
int roomNumber = -1;
{
bool bOk = false;
roomNumber = QString::fromStdString(ddspl.mName->mtext).toInt(&bOk);;
if (!bOk)
roomNumber = -1;
}
name->SetTranslation(remapPosition(bd, dspl, ddspl.mName->mPosition, roomNumber));
name->SetVisible(dspl.mNameMode);
name->SetDisText(ddspl.mName->mdistext);
name->Finished();
}
}
dtEntity::EntityId BuildingManager::getWorldNameIdFromLocalName(dtEntity::EntityId local, std::string &buildingName, std::string &room) const
{
for (const Building *building : mBuildings)
{
for (const BuildingDisplay &bd : building->mDisplays)
{
for (const NameDisplay &nd : bd.mNameDisplays)
{
if (nd.mLocalPlayerId == local)
{
buildingName = nd.mName->mbuilding;
room = nd.mName->mtext;
return nd.mWorldPlayerId;
}
}
}
}
return 0;
}
void BuildingManager::changeLineMode(unsigned int contextId, bool line)
{
mShotOverview = line;
bool bRequestRedraw = false;
for (Building *building : mBuildings)
{
for (BuildingDisplay &bd : building->mDisplays)
{
if (bd.mContextId == contextId)
{
if (bd.mLineMode != line)
{
bd.mLineMode = line;
bRequestRedraw = true;
}
}
}
}
if (bRequestRedraw)
dtEntity::GetWindowInterface()->RequestRedraw(contextId);
}
void BuildingManager::changeNameMode(unsigned int contextId, bool name)
{
bool bRequestRedraw = false;
for (Building *building : mBuildings)
{
for (BuildingDisplay &bd : building->mDisplays)
{
if (bd.mContextId == contextId)
{
if (bd.mNameMode != name)
{
bd.mNameMode = name;
setShowHideDisplayNames(building->mWorldBuildingId, contextId, name);
bRequestRedraw = true;
}
}
}
}
if (bRequestRedraw)
dtEntity::GetWindowInterface()->RequestRedraw(contextId);
}
void BuildingManager::setBuildingDisplayName(const std::string& featureId, dtEntity::EntityId eid, const std::string& strDisplayName)
{
m_mapBuildingDisplayNames[featureId] = strDisplayName;
if(eid > 0)
{
setBuildingDisplayName(eid, strDisplayName);
}
}
void BuildingManager::setBuildingDisplayName(dtEntity::EntityId eid, const std::string& strDisplayName)
{
for (Building *building : mBuildings)
{
if (building->mWorldBuildingId != eid)
continue;
building->mBuildingDisplayName = strDisplayName;
break;
}
}
void BuildingManager::setRoomDisplayName(const std::string& featureId, dtEntity::EntityId eid, const std::string& roomname, const std::string& strDisplayName)
{
m_mapBuildingRoomNames[featureId][roomname] = strDisplayName;
if (eid > 0)
{
for (Building *building : mBuildings)
{
if (building->mWorldBuildingId != eid)
continue;
setRoomDisplayName(building, roomname, strDisplayName);
return;
}
}
}
void BuildingManager::setRoomDisplayName(Building *building, const std::string& roomname, const std::string& strDisplayName)
{
for (BuildingDisplay &bd : building->mDisplays)
{
for (NameDisplay &nd : bd.mNameDisplays)
{
if (nd.mName->mtext == roomname)
{
nd.mName->mdistext = strDisplayName;
TextComponent* tc;
if (mEntityManager->GetComponent(nd.mLocalPlayerId, tc))
{
tc->SetDisText(strDisplayName);
tc->Finished();
}
dtEntity::GetWindowInterface()->RequestRedraw(bd.mContextId);
return;
}
}
}
}
void BuildingManager::setShowHideDisplayNames(dtEntity::EntityId eid, unsigned int contextId, bool show)
{
for (Building *building : mBuildings)
{
if (building->mWorldBuildingId != eid)
continue;
for (BuildingDisplay &bd : building->mDisplays)
{
bool bRequestRedraw = false;
if ( (bd.mContextId == contextId) || (contextId == 9999) )
{
for (NameDisplay &nd : bd.mNameDisplays)
{
nd.visible = show;
TextComponent* tc;
if (mEntityManager->GetComponent(nd.mLocalPlayerId, tc))
{
tc->SetVisible(show);
bRequestRedraw = true;
}
}
}
if (bRequestRedraw)
dtEntity::GetWindowInterface()->RequestRedraw(bd.mContextId);
}
break;
}
}
void BuildingManager::setShowDisplayNamesSelection(dtEntity::EntityId eid, bool show)
{
for (Building *building : mBuildings)
{
for (const BuildingDisplay &bd : building->mDisplays)
{
bool bRequestRedraw = false;
for (const NameDisplay &nd : bd.mNameDisplays)
{
if (nd.mWorldPlayerId == eid)
{
TextComponent* tc;
if (mEntityManager->GetComponent(nd.mLocalPlayerId, tc))
{
tc->SetShowSelection(show);
bRequestRedraw = true;
}
}
}
if (bRequestRedraw)
dtEntity::GetWindowInterface()->RequestRedraw(bd.mContextId);
}
}
}
void BuildingManager::createRoomNames(dtEntity::EntityId buildingid, Building& building)
{
RoomDestructionComponent* btc;
if (mEntityManager->GetComponent(buildingid, btc))
{
const RoomDestructionComponent::RoomDestructions& rc = btc->GetRoomDestructions();
for (const auto &i : rc)
{
const std::string &roomName = i.first;
VCtrl::OBB roomObb;
getRoomBounds(building.mNavMeshGrpName, roomName, roomObb);
osg::Vec3 posX = roomObb.mBB.center();
if (!roomObb.mPoly.isEmpty() && !roomObb.mPoly.containsPoint(QPointF(posX.x(), posX.y()), Qt::OddEvenFill))
{
const QPointF qpfCenter(posX.x(), posX.y());
QPointF nearestVertex;
qreal distance = 999999999;
for (const QPointF &vertex : std::as_const(roomObb.mPoly))
{
qreal dis = (vertex-qpfCenter).manhattanLength();
if (dis<distance)
{
distance = dis;
nearestVertex = vertex;
}
}
if (nearestVertex.isNull())
{
posX.x() = roomObb.mPoly.at(0).x();
posX.y() = roomObb.mPoly.at(0).y();
} else {
posX.x() = nearestVertex.x();
posX.y() = nearestVertex.y();
}
}
const osg::Vec3 pos = posX * roomObb.mMatrix;
dtEntity::Entity* e;
if (!mEntityManager->CreateEntity(e))
continue;
dtEntity::MapComponent* mc;
if (!e->CreateComponent(mc))
{
mEntityManager->KillEntity(e->GetId());
continue;
}
const std::string en = "bd_" + building.mNavMeshGrpName + "_rm_" + roomName;
mc->SetEntityName(en);
mc->SetUniqueId(en);
mc->SetMapName("roomlabel");
dtEntity::EntityId nameMainId = e->GetId();
Name* name = new Name();
name->mWorldPlayerId = nameMainId;
name->mtext = roomName;
name->mdistext = "";
name->mPosition = pos;
name->mbuilding = building.mNavMeshGrpName;
building.mNames.push_back(name);
}
}
}
}