Files
qt5-legatus-legacy/Lts/Plugins/BuildingViewer/Common/bdv_communication_interface_internal.cpp
T
2026-08-13 18:33:10 +02:00

656 lines
21 KiB
C++
Executable File

/**
* @RDE_HEADER@
* HMI Plugin for MeteoDataManagement - Meteo Data Overview Dialog
* $Id$
* $HeadURL$
* $Author$
* Created by Philipp Last, SLSY, 2017-08-15
*/
#include "bdv_communication_interface_internal.h"
#include <QTimer>
#include <cassert>
#include <ParticipantManagement/ppm_translation.h>
namespace BuildingViewer
{
static const char PLAYER_PREFIX[] = "player_";
static const char ROOM_PREFIX[] = "";
static const char BUILDING_PREFIX[] = "House_";
//static const char CAMERA_PREFIX[] = "Camera_";
static inline std::string createPlayerIdString(int playerId)
{
return PLAYER_PREFIX + std::to_string(playerId);
}
static inline std::string createBuildingIdString(int buildingId)
{
return BUILDING_PREFIX + std::to_string(buildingId);
}
static inline std::string createRoomNumberString(int roomNumber)
{
return ROOM_PREFIX + std::to_string(roomNumber);
}
CommunicationInterfaceInternal::CommunicationInterfaceInternal(VCtrl::ViewerInterface* pviewerInterface)
: m_pviewerInterface(pviewerInterface)
, m_logger(getLogger("CommunicationInterface"))
{
assert(m_pviewerInterface);
}
void CommunicationInterfaceInternal::playerCreate(int playerID, int partyID, const QString &strPathToSymbolFile,
const LtsUtils::QPoint3D &pos, int buildingID, int roomNumber, Core::PositionReportingSource reportingSource)
{
std::string playerIdStr = createPlayerIdString(playerID);
VCtrl::Color partyColor = m_teamMap.value(partyID).color;
m_pviewerInterface->CreatePlayer(playerIdStr, strPathToSymbolFile.toStdString(), partyColor);
std::string buildingIdStr, roomNumberStr;
if (buildingID > 0)
{
buildingIdStr = createBuildingIdString(buildingID);
}
if (roomNumber > 0)
{
roomNumberStr = createRoomNumberString(roomNumber);
}
const VCtrl::Vec3d tgt(pos.x(), pos.y(), pos.z());
m_pviewerInterface->Teleport(playerIdStr, 0, tgt, buildingIdStr, roomNumber, roomNumberStr,
(reportingSource == Core::PositionReportingSource::Wls
? VCtrl::ZValue::AboveMsl
: VCtrl::ZValue::RelativeBuildings));
m_pviewerInterface->SetPlayerShown(playerIdStr, true, 0);
m_playerId2String[playerID] = playerIdStr;
m_string2PlayerId[playerIdStr] = playerID;
m_player2TeamMap[playerID] = partyID;
}
void CommunicationInterfaceInternal::playerPlace(int playerID, const LtsUtils::QPoint3D &pos,
int buildingID, int roomNumber, Core::PositionReportingSource reportingSource)
{
auto it = m_playerId2String.find(playerID);
if (it == m_playerId2String.end())
{
WARNING_LOG(m_logger) << "Trying to set player position for unknown (=not created) player with id " << playerID;
return;
}
const std::string &playerIdStr = it.value();
std::string buildingIdStr, roomNumberStr;
if (buildingID > 0 )
{
buildingIdStr = createBuildingIdString(buildingID);
}
if ( roomNumber > 0)
{
roomNumberStr = createRoomNumberString(roomNumber);
}
const VCtrl::Vec3d tgt(pos.x(), pos.y(), pos.z());
m_pviewerInterface->Teleport(playerIdStr, 0, tgt, buildingIdStr, roomNumber, roomNumberStr,
(reportingSource == Core::PositionReportingSource::Wls
? VCtrl::ZValue::AboveMsl
: VCtrl::ZValue::RelativeBuildings));
}
void CommunicationInterfaceInternal::playerDelete(int playerID)
{
if (playerID <= 0)
return;
std::string playerIdStr = createPlayerIdString(playerID);
m_pviewerInterface->DeletePlayer(playerIdStr);
m_playerId2String.remove(playerID);
m_string2PlayerId.remove(playerIdStr);
m_player2TeamMap.remove(playerID);
}
void CommunicationInterfaceInternal::setPlayerVisible(int playerID, bool bVisible)
{
if (playerID <= 0)
return;
std::string playerIdStr = createPlayerIdString(playerID);
m_pviewerInterface->SetPlayerShown(playerIdStr, bVisible);
}
void CommunicationInterfaceInternal::playerClear()
{
const auto string2PlayerId_Copy = m_string2PlayerId;
for (const int playerId : string2PlayerId_Copy)
playerDelete(playerId);
m_player2TeamMap.clear();
m_playerId2String.clear();
m_string2PlayerId.clear();
}
void CommunicationInterfaceInternal::playerUpdateSymbols()
{
m_pviewerInterface->reloadPlayerIcons();
}
void CommunicationInterfaceInternal::playerUpdatePlayerSymbol(int playerID, const QString &strPathToSymbolFile)
{
std::string playerIdStr = createPlayerIdString(playerID);
m_pviewerInterface->SetPlayerIcon(playerIdStr, strPathToSymbolFile.toStdString());
}
/*
* Also causes the reload the symbol file for playerIdDst.
* Hence, the new symbol file needs to be created before calling this function.
*/
void CommunicationInterfaceInternal::playerHit(const int32_t id, int playerIdSrc, int playerIdDst,
const LtsUtils::QPoint3D &posSrc, const LtsUtils::QPoint3D &posDst,
int buildingIdSrc, int roomNumberSrc, int buildingIdDst, int roomNumberDst,
int lineType, int64_t time)
{
DEBUG_LOG(m_logger) << "playerHit id= " << id;
const std::string playerIdStrDst = m_playerId2String.value(playerIdDst);
const std::string playerIdStrSrc = m_playerId2String.value(playerIdSrc);
const VCtrl::Vec3d src(posSrc.x(), posSrc.y(), posSrc.z());
const VCtrl::Vec3d dst(posDst.x(), posDst.y(), posDst.z());
m_pviewerInterface->Shoot(id, playerIdStrSrc, playerIdStrDst,
src, dst,
buildingIdSrc, roomNumberSrc, buildingIdDst, roomNumberDst,
lineType, time / 1000.);
}
void CommunicationInterfaceInternal::buildingHit(const int32_t id, int buildingId, int damagePercent, const QMap<int,int>& mapRoomDestructions)
{
DEBUG_LOG(m_logger) << "buildingHit for building " << buildingId
<< " id=" << id
<< " damagePercent " << damagePercent
<< " roomlist size: " << mapRoomDestructions.size();
const std::string buildingIdStr = createBuildingIdString(buildingId);
// Nur bei ganz zersört oder gar nicht zerstört auch die buildingDestruction setzen da diese alle Räume beeinflusst
if (damagePercent <= 0 || damagePercent >= 80)
{
if (damagePercent >= 80)
damagePercent = 100;
m_pviewerInterface->SetBuildingDestructionValue(buildingIdStr, damagePercent / 100.f);
}
else
{
for (auto it = mapRoomDestructions.begin(); it != mapRoomDestructions.end(); ++it)
{
const int roomNumber = it.key();
DEBUG_LOG(m_logger) << "BuildingId " << buildingId
<< ", room: "<< roomNumber
<< ", destruction: " << it.value();
std::string roomNumberStr = createRoomNumberString(roomNumber);
if (!m_pviewerInterface->SetRoomDestructionValue(buildingIdStr, roomNumberStr,it.value() / 100.f))
ERROR_LOG(m_logger) << "SetRoomDestructionValue failed for room "<< roomNumber;
}
}
}
void CommunicationInterfaceInternal::roomHit(const int32_t id, int playerIdSrc, int buildingId, int roomNumber, const LtsUtils::QPoint3D &posSrc, int lineType, int64_t time)
{
// ERROR_LOG(m_logger) << "HOTLINE roomHit for building " << buildingId
//<< " id=" << id;
const std::string playerIdStrSrc = m_playerId2String.value(playerIdSrc);
const std::string buildingIdStrDst = createBuildingIdString(buildingId);
const std::string roomNumberStrDst = createRoomNumberString(roomNumber);
const VCtrl::Vec3d src(posSrc.x(), posSrc.y(), posSrc.z());
DEBUG_LOG(m_logger) << "roomHit for building palyer " << playerIdStrSrc
<< " building " << buildingIdStrDst
<< " room " << roomNumberStrDst
<< " id=" << id;
m_pviewerInterface->Shoot(id, playerIdStrSrc, buildingIdStrDst, roomNumberStrDst, src, lineType, time / 1000.);
}
void CommunicationInterfaceInternal::removeRoomHit(const int32_t id)
{
DEBUG_LOG(m_logger) << "removeRoomHit id=" << id;
m_pviewerInterface->removeShoot(id);
}
void CommunicationInterfaceInternal::setTeamConfiguration(const QMap<qint32, ParticipantManagement::Party> &parties)
{
for (const ParticipantManagement::Party &party : parties)
{
BdvParty bdvParty;
bdvParty.id = party.id();
bdvParty.name = ParticipantManagement::trPartyName(party.name());
const uint32_t argb = party.color();
bdvParty.color.w = ( ( ( argb >> 24 ) & 0xff ) / 255.);
bdvParty.color.x = ( ( ( argb >> 16 ) & 0xff ) / 255.);
bdvParty.color.y = ( ( ( argb >> 8 ) & 0xff ) / 255.);
bdvParty.color.z = ( ( ( argb >> 0 ) & 0xff ) / 255.);
m_teamMap[bdvParty.id] = bdvParty;
}
std::map<std::string, VCtrl::Color> mapPlayerColors;
for (auto it = m_player2TeamMap.cbegin(); it != m_player2TeamMap.cend(); ++it)
{
const auto itParty = m_teamMap.constFind(it.value());
if (itParty == m_teamMap.cend())
continue;
mapPlayerColors.emplace(std::make_pair(createPlayerIdString(it.key()),
itParty.value().color));
}
m_pviewerInterface->UpdatePlayerPartyColors(mapPlayerColors);
}
void CommunicationInterfaceInternal::systemSetSimulationTime(qint64 time)
{
double tSimTime = time / 1000;
double tCurSimTime = m_pviewerInterface->GetSimulationTime();
if(fabs(tCurSimTime - tSimTime) < 0.5)
return;
m_pviewerInterface->SetSimulationTime(tSimTime);
}
void CommunicationInterfaceInternal::setSimuationPace(double pace)
{
m_pviewerInterface->SetTimeScale(pace);
}
void CommunicationInterfaceInternal::systemDisconnect()
{
playerClear();
clearCameras();
systemSetPaused(true);
}
void CommunicationInterfaceInternal::systemSetPaused(bool bPaused)
{
m_pviewerInterface->SetPaused(bPaused);
}
void CommunicationInterfaceInternal::systemSetMountingPoint(const InfrastructureManagement::MountingPoint &data, const QString &filename, bool show)
{
int buildingId = data.buildingId();
const QString &mountingPointName = filename;
double x = data.relPosition().offsetX();
double y = data.relPosition().offsetY();
double z = data.relPosition().offsetZ();
const std::string buildingIdStr = createBuildingIdString(buildingId);
if(!show)
{
DEBUG_LOG(m_logger) << "Hiding mounting point \"" << mountingPointName<< "\"";
m_pviewerInterface->HideDeviceIcon(mountingPointName.toStdString());
return;
}
if(m_deviceMap.contains(mountingPointName))
{
WARNING_LOG(m_logger) << "Trying to add a mounting point which was already added - trying to re-add";
//remove first and then reAdd
m_pviewerInterface->HideDeviceIcon(mountingPointName.toStdString());
}
const VCtrl::Vec3d position(x,y,z);
if(m_pviewerInterface->ShowDeviceIcon(mountingPointName.toStdString(), buildingIdStr, position, filename.toStdString())) {
DEBUG_LOG(m_logger) << "Added mounting point to scene: " << mountingPointName;
m_deviceMap[mountingPointName] = DeviceInfo(buildingId, mountingPointName);
}
}
void CommunicationInterfaceInternal::excStartRecording(const QString& strPathOutputFolder, const QString &buildingId, int w, int h, int framerate, int quality)
{
m_pviewerInterface->StartVideoRecording(buildingId.toStdString(), strPathOutputFolder.toStdString(), w, h, framerate, quality);
}
void CommunicationInterfaceInternal::excStopRecording(const QString &buildingId)
{
m_pviewerInterface->StopVideoRecording(buildingId.toStdString());
}
void CommunicationInterfaceInternal::excConnect(const std::vector<std::string> &paths, const QString &strXMLFile)
{
m_pviewerInterface->SetProjectDataPaths(paths);
m_pviewerInterface->LoadBuildingPositionMap(strXMLFile.toStdString(), (strXMLFile.size() ? false : true));
emit signalBgViewerInitFinished();
}
void CommunicationInterfaceInternal::excDeleteBuildingList()
{
m_pviewerInterface->LoadBuildingPositionMap(std::string(), false);
}
void CommunicationInterfaceInternal::excSetHitlineDuration(uint32_t duration_s)
{
DEBUG_LOG(m_logger) << "excSetHitlineDuration=" << duration_s;
m_pviewerInterface->setHitLineDuration(duration_s);
}
void CommunicationInterfaceInternal::excUseExactPositioning(bool useExactPositioning)
{
m_useExactPositioning = useExactPositioning;
m_pviewerInterface->UseExactPositioning(useExactPositioning);
}
void CommunicationInterfaceInternal::excOpenView(const std::vector<std::string> &bldIds)
{
m_pviewerInterface->openViews(bldIds, m_useExactPositioning);
}
void CommunicationInterfaceInternal::excCloseView(const std::vector<std::string> &bldIds)
{
m_pviewerInterface->closeViews(bldIds);
}
void CommunicationInterfaceInternal::excCloseAllViews()
{
m_pviewerInterface->closeViews({"all"});
}
void CommunicationInterfaceInternal::excHighlightView(const QString &buildingId)
{
m_pviewerInterface->highlightView(buildingId.toStdString());
}
void CommunicationInterfaceInternal::excGetBuildingList()
{
const auto states = m_pviewerInterface->getBuildingState();
QVector<BuildingTuple> tplStates;
BuildingTuple tpl;
tplStates.reserve(states.size());
for (const auto &state : states)
{
tpl.buildingId = QString::fromStdString(state.buildingId);
tpl.description = QString::fromStdString(state.description);
tpl.entityId = state.entityId;
tpl.isShown = state.isShown;
tplStates += tpl;
}
emit signalReceivedBuildingList(tplStates);
}
void CommunicationInterfaceInternal::excSetGlobalTransparency(double transparency)
{
m_pviewerInterface->setTransparency(transparency / 100.0);
}
void CommunicationInterfaceInternal::excSetGlobalViewMode(bool useOrtho)
{
m_pviewerInterface->setViewMode(useOrtho ? VCtrl::ViewMode::ORTHOGRAPHIC : VCtrl::ViewMode::ISOMETRIC);
}
void CommunicationInterfaceInternal::excSetGlobalDotsMode(bool useDots)
{
m_pviewerInterface->setDisplayMode(useDots ? VCtrl::PlayerDisplayMode::Dots : VCtrl::PlayerDisplayMode::Icons);
}
void CommunicationInterfaceInternal::excRestoreViewState(const QJsonValue &val)
{
m_pviewerInterface->setViewState(val);
}
void CommunicationInterfaceInternal::excGetViewState()
{
const auto state = m_pviewerInterface->getViewState();
emit signalReceivedViewState(state);
}
void CommunicationInterfaceInternal::excSetBuildingDisplayName(const QString &buildingId, const QString &strBuildingDisplayName)
{
m_pviewerInterface->setBuildingDisplayName(buildingId.toStdString(), strBuildingDisplayName.toStdString());
}
void CommunicationInterfaceInternal::excSetRoomDisplayName(const QString &strFeatureID, const QString &strRoomName, const QString &strRoomDisplayName)
{
m_pviewerInterface->SetDisplayName(strFeatureID.toStdString(), strRoomName.toStdString(), strRoomDisplayName.toStdString());
}
void CommunicationInterfaceInternal::extSetMountingPointAsset(const QString &strFeatureID, const QString &strMountingPointId,
const QVector3D& position, BuildingViewer::AssetTypes assetType)
{
m_pviewerInterface->setMountingPointAsset({strFeatureID.toStdString(),
strMountingPointId.toStdString(),
{position.x(), position.y(), position.z()},
assetType});
}
void CommunicationInterfaceInternal::extHideMountingPointAsset(const QString &strMountingPointId)
{
m_pviewerInterface->HideDeviceIcon(strMountingPointId.toStdString());
}
void CommunicationInterfaceInternal::clearCameras()
{
for (const DeviceInfo &di : qAsConst(m_deviceMap))
{
if (!di.deviceName.startsWith(QLatin1String("Camera")))
continue;
if (!m_pviewerInterface->HideDeviceIcon(di.deviceName.toStdString()))
ERROR_LOG(m_logger) << "Could not remove camera with id " << di.deviceName;
}
m_deviceMap.clear();
}
// VCtrl::ViewerCallback interface
void CommunicationInterfaceInternal::SystemReady()
{
}
void CommunicationInterfaceInternal::TransformChanged(const std::string &id, const VCtrl::Vec3d &pos, const VCtrl::Quat &attitude)
{
Q_UNUSED(id);
Q_UNUSED(pos);
Q_UNUSED(attitude);
}
void CommunicationInterfaceInternal::NavMeshGroupChanged(const std::string &id, const std::string &grpname)
{
Q_UNUSED(id);
Q_UNUSED(grpname);
}
static inline bool isPlayerId(const std::string &playerIdString, int *playerId)
{
const QString playerIdQString(QString::fromStdString(playerIdString));
bool bOk = false;
if (playerIdQString.startsWith(QLatin1String(PLAYER_PREFIX)))
*playerId = playerIdQString.midRef(QLatin1String(PLAYER_PREFIX).size()).toInt(&bOk);
return bOk;
}
void CommunicationInterfaceInternal::PlayerPicked(const std::string &strId)
{
int playerId = 0;
if (isPlayerId(strId, &playerId)) {
emit signalPlayerPicked(playerId);
} else {
// asset string may be, e.g., "House_56_MountingPoint_37"
QString str = QString::fromStdString(strId);
int structureElementId = str.remove(0, str.lastIndexOf(QStringLiteral("_")) + 1).toInt();
INFO_LOG(m_logger) << "Picked mounting point with id " << strId
<< " mountingPointId=" << structureElementId;
if(structureElementId < 0) {
WARNING_LOG(m_logger) << "Picked mounting point with id " << strId;
return;
}
emit signalAssetPicked(structureElementId);
}
}
void CommunicationInterfaceInternal::DisplayNamePicked(const std::string &buildingid, const std::string &roomname)
{
// HandleViewerEvent (see below) handles this...
Q_UNUSED(buildingid);
Q_UNUSED(roomname);
}
void CommunicationInterfaceInternal::ViewCreated(unsigned int contextId, VCtrl::ViewMode viewmode)
{
Q_UNUSED(contextId);
Q_UNUSED(viewmode);
}
void CommunicationInterfaceInternal::ViewModeChanged(unsigned int contextId, VCtrl::ViewMode viewmode)
{
Q_UNUSED(contextId);
Q_UNUSED(viewmode);
emit signalViewerEventButton();
}
void CommunicationInterfaceInternal::ViewLineModeChanged(unsigned int contextId, bool line)
{
Q_UNUSED(contextId);
Q_UNUSED(line);
emit signalViewerEventButton();
}
void CommunicationInterfaceInternal::ViewNameModeChanged(unsigned int contextId, bool name)
{
Q_UNUSED(contextId);
Q_UNUSED(name);
emit signalViewerEventButton();
}
void CommunicationInterfaceInternal::ViewLockRotationChanged(unsigned int contextId, bool lock)
{
Q_UNUSED(contextId);
Q_UNUSED(lock);
emit signalViewerEventButton();
}
void CommunicationInterfaceInternal::ViewTransparencyChanged()
{
emit signalViewerEventButton();
}
void CommunicationInterfaceInternal::PlayerDisplayModeChanged(unsigned int contextId, VCtrl::PlayerDisplayMode mode)
{
Q_UNUSED(contextId);
Q_UNUSED(mode);
emit signalViewerEventButton();
}
void CommunicationInterfaceInternal::ViewClosed(unsigned int contextId)
{
Q_UNUSED(contextId);
}
void CommunicationInterfaceInternal::HandleViewerEvent(BgViewerEvents event, const std::vector<std::string> &args)
{
if (args.size() < 1)
{
Q_ASSERT(false);
return;
}
const QString featureID = QString::fromStdString(args[0]);
switch (event)
{
case BuildingViewer::BgViewerEvents::WidgetClosed:
emit signalViewerEventWidgetClosed(featureID);
break;
case BuildingViewer::BgViewerEvents::WidgetMaximized:
emit signalViewerEventWidgetMaximized(featureID);
break;
case BuildingViewer::BgViewerEvents::WidgetMinimized:
emit signalViewerEventWidgetMinimized(featureID);
break;
case BuildingViewer::BgViewerEvents::WidgetGotFocus:
emit signalViewerEventWidgetFocused(featureID);
break;
case BuildingViewer::BgViewerEvents::RoomNameClicked:
{
if (args.size() >= 2)
{
const QString roomID = QString::fromStdString(args[1]);
emit signalViewerEventRoomNameClicked(featureID, roomID);
}
break;
}
}
}
void CommunicationInterfaceInternal::ViewZoomChanged(const std::string &buildingId, double top, double left, double bottom, double right)
{
emit signalViewerZoomChanged(QString::fromStdString(buildingId), top, left, bottom, right);
}
void CommunicationInterfaceInternal::LogMessage(Severity &severity, const std::string &filename, const std::string &methodname, int linenumber, const std::string &msg)
{
auto logLevel = NGL::LogLevel::Info;
bool logAlways = false;
switch (severity)
{
case Severity::Always:
logAlways = true;
logLevel = NGL::LogLevel::Info;
break;
case Severity::Debug:
logLevel = NGL::LogLevel::Debug;
break;
case Severity::Info:
logLevel = NGL::LogLevel::Info;
break;
case Severity::Warning:
logLevel = NGL::LogLevel::Warning;
break;
case Severity::Error:
logLevel = NGL::LogLevel::Error;
break;
case Severity::Fatal:
logLevel = NGL::LogLevel::Fatal;
break;
}
if (logAlways || m_logger.isLevelEnabled(logLevel))
NGL::LogStreamHelper(m_logger, logLevel, filename.c_str(), linenumber, methodname.c_str()) << msg;
}
} // namesapce BuildingViewer