/** * @RDE_HEADER@ * Calculate line of sight * $Id$ * $HeadURL$ * $Author$ * Created by gr, SLSE, 2024-11-03 */ #include "line_of_sight.h" #include #include #include #include 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 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 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 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