218 lines
7.7 KiB
C++
Executable File
218 lines
7.7 KiB
C++
Executable File
/**
|
|
* @RDE_HEADER@
|
|
* Calculate line of sight
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
* Created by gr, SLSE, 2024-11-03
|
|
*/
|
|
|
|
#include "line_of_sight.h"
|
|
|
|
#include <CentralEffectSimulation/logger.h>
|
|
#include <LtsCoordTrans/lts_coord_trans.h>
|
|
#include <LtsElevation/lts_elevation_manager.h>
|
|
|
|
#include <QElapsedTimer>
|
|
|
|
|
|
namespace CesExplosions
|
|
{
|
|
|
|
CentralEffectSimulation::LOGGER_T getLocalLogger()
|
|
{
|
|
return CentralEffectSimulation::getLogger("Plugin.Explosions.LineOfSight");
|
|
}
|
|
|
|
|
|
bool lineOfSightBuilding(const LtsCoordTrans::LtsCoordinate &impactLtsCoord_absZ,
|
|
const LtsCoordTrans::LtsCoordinate &participantLtsCoord_absZ,
|
|
bool &bLosOut,
|
|
std::shared_ptr<CentralEffectSimulation::ProxyBuilding> proxyBuilding)
|
|
{
|
|
static CentralEffectSimulation::LOGGER_T logger = getLocalLogger();
|
|
|
|
TRACE_LOG(logger) << LOGFUNCTION << " START";
|
|
DEBUG_LOG(logger) << LOGFUNCTION << " impactCoord = " << impactLtsCoord_absZ.toString(true);
|
|
DEBUG_LOG(logger) << LOGFUNCTION << " participant = " << participantLtsCoord_absZ.toString(true);
|
|
|
|
if (!proxyBuilding || !proxyBuilding->isSet_handlerBuildingModel())
|
|
{
|
|
INFO_LOG(logger) << LOGFUNCTION << " proxyBuilding not working...";
|
|
return false;
|
|
}
|
|
|
|
// sp should be checked by isSet above:
|
|
std::shared_ptr<CesBuildings::HandlerBuildingModelInterface> sp = proxyBuilding->handlerBuildingModelInterface();
|
|
|
|
const CesBuildings::HandlerBuildingModelInterface::LineBuildingIntersectsResult &result =
|
|
sp->getLineBuildingIntersects({impactLtsCoord_absZ.geoPosition(), participantLtsCoord_absZ.geoPosition()});
|
|
|
|
bool success = false;
|
|
|
|
if (result.errorString.empty())
|
|
{
|
|
if (result.intersects)
|
|
DEBUG_LOG(logger) << "lineOfSightBuilding, res.intersect = " << "YES";
|
|
else
|
|
DEBUG_LOG(logger) << "lineOfSightBuilding, res.intersect = " << "NO";
|
|
|
|
bLosOut = !result.intersects;
|
|
success = true;
|
|
}
|
|
else
|
|
{
|
|
ERROR_LOG(logger) << LOGFUNCTION
|
|
<< " getLineBuildingIntersects failed"
|
|
<< ", impactCoord = " << impactLtsCoord_absZ.toString(true)
|
|
<< ", participantCoord = " << participantLtsCoord_absZ.toString(true)
|
|
<< ", res.errorString = '" << result.errorString << "'";
|
|
}
|
|
|
|
DEBUG_LOG(logger) << LOGFUNCTION
|
|
<< ", success = " << success
|
|
<< ", bLosOut = " << bLosOut;
|
|
|
|
TRACE_LOG(logger) << LOGFUNCTION << " END, success = " << success;
|
|
return success;
|
|
}
|
|
|
|
bool lineOfSightElevation(const LtsCoordTrans::LtsCoordinate &impactLtsCoord_absZ,
|
|
const LtsCoordTrans::LtsCoordinate &participantLtsCoord_absZ,
|
|
bool &bLosOut,
|
|
const int exerciseId)
|
|
{
|
|
static CentralEffectSimulation::LOGGER_T logger = getLocalLogger();
|
|
|
|
TRACE_LOG(logger) << LOGFUNCTION << " START";
|
|
|
|
DEBUG_LOG(logger) << LOGFUNCTION << " getExerciseId=" << exerciseId
|
|
<< ", impactCoord = " << impactLtsCoord_absZ.toString(true)
|
|
<< ", participantCoord = " << participantLtsCoord_absZ.toString(true);
|
|
|
|
//
|
|
// The very first instanciation should be done by the MainHandler:
|
|
//
|
|
static LtsElevation::LTS_ELEVATION_MANAGER_TYPE s_ltsElevationManager = nullptr;
|
|
if (!s_ltsElevationManager)
|
|
s_ltsElevationManager = LtsElevation::LtsElevationManager::getInstance(exerciseId);
|
|
|
|
if (!s_ltsElevationManager)
|
|
{
|
|
WARNING_LOG(logger) << LOGFUNCTION << " no LtsElevationManager could be create for exerciseId " << exerciseId;
|
|
return false;
|
|
}
|
|
if (s_ltsElevationManager->isValid())
|
|
DEBUG_LOG(logger) << LOGFUNCTION << " LtsElevationManager is valid for exerciseId = " << exerciseId;
|
|
else
|
|
{
|
|
WARNING_LOG(logger) << LOGFUNCTION << " LtsElevationManager is INVALID for exerciseId = " << exerciseId;
|
|
return false;
|
|
}
|
|
|
|
const LtsUtils::QPoint3D &start = impactLtsCoord_absZ.toGeoPoint3D();
|
|
const LtsUtils::QPoint3D &end = participantLtsCoord_absZ.toGeoPoint3D();
|
|
|
|
const LtsElevation::LineOfSight losEle = s_ltsElevationManager->lineOfSightCalculation(start, end);
|
|
|
|
bool success = false;
|
|
|
|
switch (losEle)
|
|
{
|
|
case LtsElevation::LineOfSight::LOS_UNDEFINED:
|
|
case LtsElevation::LineOfSight::LOS_ERROR:
|
|
case LtsElevation::LineOfSight::LOS_INVISIBLE:
|
|
success = true;
|
|
bLosOut = false;
|
|
break;
|
|
case LtsElevation::LineOfSight::LOS_VISIBLE:
|
|
success = true;
|
|
bLosOut = true;
|
|
break;
|
|
} // switch
|
|
|
|
DEBUG_LOG(logger) << LOGFUNCTION
|
|
<< ", success = " << success
|
|
<< ", losEle = " << losEle
|
|
<< ", bLosOut = " << bLosOut;
|
|
|
|
TRACE_LOG(logger) << LOGFUNCTION << " END, success = " << success << ", losEle = " << losEle;
|
|
return success;
|
|
}
|
|
|
|
|
|
bool lineOfSight_elevationAndBuilding(const int exerciseId,
|
|
const LtsCoordTrans::LtsCoordinate &impactLtsCoord_absZ,
|
|
const LtsCoordTrans::LtsCoordinate &participantLtsCoord_absZ,
|
|
Options lineOfSightOptions,
|
|
bool &bLosOut,
|
|
std::shared_ptr<CentralEffectSimulation::ProxyBuilding> proxyBuilding)
|
|
{
|
|
static CentralEffectSimulation::LOGGER_T logger = getLocalLogger();
|
|
|
|
// What shall happen, if exeBldgLos is SKIP or proxyBuilding is not availble?
|
|
bool success = true; // (BLDG_LOS_SKIP || no buildings) -> bLOS given :-)
|
|
bLosOut = true;
|
|
|
|
DEBUG_LOG(logger) << LOGFUNCTION << " impactCoord = " << impactLtsCoord_absZ.toString(true);
|
|
DEBUG_LOG(logger) << LOGFUNCTION << " participant = " << participantLtsCoord_absZ.toString(true);
|
|
|
|
//
|
|
// execute different LineOfSight operations:
|
|
// try to start with the cheapest. But which is cheap and which expensive?
|
|
// assume lineOfSightBuilding is expensive due to several buildings, rooms, walls...
|
|
//
|
|
DEBUG_LOG(logger) << LOGFUNCTION << " vor lineOfSightOptions.testFlag EXECUTE_ELEVATION_LOS_CALC"
|
|
<< " lineOfSightOptions.testFlag(Option::EXECUTE_ELEVATION_LOS_CALC)=" << lineOfSightOptions.testFlag(Option::EXECUTE_ELEVATION_LOS_CALC);
|
|
if (lineOfSightOptions.testFlag(Option::EXECUTE_ELEVATION_LOS_CALC) /*&& bLOS*/)
|
|
{
|
|
DEBUG_LOG(logger) << LOGFUNCTION << " lineOfSightOptions EXECUTE_ELEVATION_LOS_CALC";
|
|
QElapsedTimer timer;
|
|
DEBUG_LOG(logger) << LOGFUNCTION << " vor lineOfSightOptions start";
|
|
if (logger.isInfoEnabled())
|
|
timer.start();
|
|
|
|
|
|
if (lineOfSightElevation(impactLtsCoord_absZ,
|
|
participantLtsCoord_absZ,
|
|
bLosOut, exerciseId))
|
|
{
|
|
DEBUG_LOG(logger) << "---------------- lineOfSightElevation bLosOut=" << bLosOut;
|
|
if (!bLosOut)
|
|
{
|
|
DEBUG_LOG(logger) << "---------------- lineOfSightElevation return success";
|
|
return success;
|
|
}
|
|
DEBUG_LOG(logger) << "---------------- lineOfSightElevation continue with buildings";
|
|
}
|
|
else
|
|
return false;
|
|
|
|
INFO_LOG(logger) << " lineOfSightElevation took [ms] " << timer.elapsed();
|
|
|
|
}
|
|
else
|
|
DEBUG_LOG(logger) << "skip lineOfSightElevation due to option EXECUTE_ELEVATION_LOS_CALC";
|
|
DEBUG_LOG(logger) << LOGFUNCTION << " vor lineOfSightOptions.testFlag EXECUTE_BLDG_LOS_CALC";
|
|
if (lineOfSightOptions.testFlag(Option::EXECUTE_BLDG_LOS_CALC))
|
|
{
|
|
QElapsedTimer timer;
|
|
if (logger.isInfoEnabled())
|
|
timer.start();
|
|
|
|
if (lineOfSightBuilding(impactLtsCoord_absZ, participantLtsCoord_absZ,
|
|
bLosOut, proxyBuilding))
|
|
return success;
|
|
else
|
|
return false;
|
|
|
|
INFO_LOG(logger) << " lineOfSightBuilding took [ms] " << timer.elapsed();
|
|
}
|
|
else
|
|
DEBUG_LOG(logger) << "skip lineOfSightBuilding due to option EXECUTE_BLDG_LOS_CALC or previous non-LineOfSight";
|
|
|
|
return true;
|
|
}
|
|
|
|
} // namespace
|