245 lines
10 KiB
C++
Executable File
245 lines
10 KiB
C++
Executable File
/**
|
|
* Handler for the HMI language
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
*/
|
|
|
|
#include "effect_show_explosion_area.h"
|
|
|
|
namespace EffectShowManagement
|
|
{
|
|
EffectShowExplosionArea::EffectShowExplosionArea(const AreaEffectSimulation::ExplosionArea &explosionArea,
|
|
const std::shared_ptr<HandlerPdmData> &handlerPdmData)
|
|
: m_explosionArea(explosionArea)
|
|
, m_handlerPdmData(handlerPdmData)
|
|
, m_numOfEffectShows(0)
|
|
, m_logger(getLogger("EffectShowExplosionArea"))
|
|
{
|
|
}
|
|
|
|
//=============================================================================
|
|
int EffectShowExplosionArea::getNumOfEffectShows()
|
|
{
|
|
if (m_numOfEffectShows == 0)
|
|
calculateSquare();
|
|
|
|
return m_numOfEffectShows;
|
|
}
|
|
//=============================================================================
|
|
Database::EsmEffectShow EffectShowExplosionArea::getEffectShow(int idx)
|
|
{
|
|
if (m_numOfEffectShows == 0)
|
|
calculateSquare();
|
|
|
|
|
|
Database::EsmEffectShow esmEffectShow;
|
|
|
|
if (!m_handlerPdmData->isSmoke(m_explosionArea.chargeStruct()))
|
|
{
|
|
int indX = idx % m_areasWidth.numOfAreas;
|
|
int indY = idx / m_areasWidth.numOfAreas;
|
|
|
|
// calculate lower left position
|
|
double x_off = 0.0;
|
|
for (int i = 0; i < indX; ++i)
|
|
x_off += m_areasWidth.side(i);
|
|
|
|
double y_off = 0.0;
|
|
for (int i = 0; i < indY; ++i)
|
|
y_off += m_areasDepth.side(i);
|
|
|
|
LtsCoordTrans::UtmCoordinate lowerLeftPos = m_lowerLeftPos;
|
|
lowerLeftPos.x = lowerLeftPos.x + x_off;
|
|
lowerLeftPos.y = lowerLeftPos.y + y_off;
|
|
LtsCoordTrans::UtmCoordinate lowerLeftPosRotated = rotate(lowerLeftPos, m_lowerLeftPos, rotationRad());
|
|
|
|
// calculate center position
|
|
LtsCoordTrans::UtmCoordinate centerPos = lowerLeftPos;
|
|
centerPos.x = centerPos.x + m_areasWidth.side(indX) / 2.;
|
|
centerPos.y = centerPos.y + m_areasDepth.side(indY) / 2.;
|
|
LtsCoordTrans::UtmCoordinate centerPosRotated = rotate(centerPos, m_lowerLeftPos, rotationRad());
|
|
|
|
esmEffectShow.id = 0;
|
|
esmEffectShow.name = QStringLiteral("EXP");
|
|
esmEffectShow.startTime = m_explosionArea.effectStart().is_set() ? m_explosionArea.effectStart().get() : 0;
|
|
esmEffectShow.duration = m_explosionArea.effectDuration();
|
|
esmEffectShow.centerPosition = centerPosRotated.geographic();
|
|
esmEffectShow.idAreaEffectSimulation = m_explosionArea.id();
|
|
esmEffectShow.esmParticipantId = -1;
|
|
esmEffectShow.nameAreaEfffectSimulation = QString::fromStdString(m_explosionArea.name());
|
|
esmEffectShow.numOfVolley = getNumberOfVolley();
|
|
esmEffectShow.shotsPerVolley = getShotsPerArea() / esmEffectShow.numOfVolley;
|
|
esmEffectShow.typeOfAmmunition = m_explosionArea.chargeStruct().chargeTypeId();
|
|
// can there be more then 48 shoots?
|
|
|
|
if (esmEffectShow.shotsPerVolley > 48)
|
|
esmEffectShow.shotsPerVolley = 48;// (48 / esmEffectShow.numOfVolley);
|
|
if (esmEffectShow.shotsPerVolley <= 0)
|
|
esmEffectShow.shotsPerVolley = 1;
|
|
esmEffectShow.lowerLeftPosition = lowerLeftPosRotated.geographic();
|
|
esmEffectShow.areaWidth = m_areasWidth.side(indX);
|
|
esmEffectShow.areaDepth = m_areasDepth.side(indY);
|
|
esmEffectShow.areaRotation = m_explosionArea.area().rotation() + 90;
|
|
|
|
|
|
DEBUG_LOG(m_logger) << "\nWidth: " << m_explosionArea.area().width() << " Height: " << m_explosionArea.area().height()
|
|
<< "\nRotated LL Pos: " << lowerLeftPosRotated.mgrs()
|
|
<< "\nRotated Center Pos: " << centerPosRotated.mgrs()
|
|
<< "\nOffset x,y: " << x_off << " , " << y_off
|
|
<< "\nSide x,y: " << m_areasWidth.side(indX) << " , " << m_areasDepth.side(indY)
|
|
<< "\nindX: " << indX << " grid " << m_areasWidth.numSideLength1 << ' ' << m_areasWidth.sideLength1 << ' ' << m_areasWidth.numSideLength2 << ' ' << m_areasWidth.sideLength2
|
|
<< "\nindY: " << indY << " grid " << m_areasDepth.numSideLength1 << ' ' << m_areasDepth.sideLength1 << ' ' << m_areasDepth.numSideLength2 << ' ' << m_areasDepth.sideLength2;
|
|
|
|
}
|
|
else
|
|
{
|
|
|
|
LtsCoordTrans::UtmCoordinate lowerLeftPos = m_lowerLeftPos; //unnötig?
|
|
LtsCoordTrans::UtmCoordinate lowerLeftPosRotated = rotate(lowerLeftPos, m_lowerLeftPos, rotationRad());
|
|
|
|
// calculate center position
|
|
LtsCoordTrans::UtmCoordinate centerPos = lowerLeftPosRotated;
|
|
centerPos.x = centerPos.x + m_explosionArea.area().width() / 2.;
|
|
centerPos.y = centerPos.y + m_explosionArea.area().height() / 2.;
|
|
LtsCoordTrans::UtmCoordinate centerPosRotated = rotate(centerPos, m_lowerLeftPos, rotationRad());
|
|
|
|
esmEffectShow.id = 0;
|
|
esmEffectShow.name = QStringLiteral("EXP");
|
|
esmEffectShow.startTime = m_explosionArea.effectStart().is_set() ? m_explosionArea.effectStart().get() : 0;
|
|
esmEffectShow.duration = m_explosionArea.effectDuration();
|
|
esmEffectShow.centerPosition = centerPosRotated.geographic();
|
|
esmEffectShow.idAreaEffectSimulation = m_explosionArea.id();
|
|
esmEffectShow.esmParticipantId = -1;
|
|
esmEffectShow.nameAreaEfffectSimulation = QString::fromStdString(m_explosionArea.name());
|
|
esmEffectShow.typeOfAmmunition = m_explosionArea.chargeStruct().chargeTypeId();
|
|
esmEffectShow.numOfVolley = 1;
|
|
esmEffectShow.shotsPerVolley = 1;
|
|
esmEffectShow.lowerLeftPosition = lowerLeftPosRotated.geographic();
|
|
esmEffectShow.areaWidth = m_explosionArea.area().width();
|
|
esmEffectShow.areaDepth = m_explosionArea.area().height();
|
|
esmEffectShow.areaRotation = m_explosionArea.area().rotation() + 90;
|
|
|
|
DEBUG_LOG(m_logger) << "\nWidth: " << m_explosionArea.area().width() << " Height: " << m_explosionArea.area().height()
|
|
<< "\nRotated LL Pos: " << lowerLeftPosRotated.mgrs()
|
|
<< "\nRotated Center Pos: " << centerPosRotated.mgrs()
|
|
<< "\nSide x,y: " << m_explosionArea.area().width() << " , " << m_explosionArea.area().height();
|
|
}
|
|
|
|
return esmEffectShow;
|
|
}
|
|
//=============================================================================
|
|
void EffectShowExplosionArea::updateEffectShow(Database::EsmEffectShow &data)
|
|
{
|
|
data.nameAreaEfffectSimulation = QString::fromStdString(m_explosionArea.name());
|
|
data.startTime = m_explosionArea.effectStart().is_set() ? m_explosionArea.effectStart().get() : 0;
|
|
data.duration = m_explosionArea.effectDuration();
|
|
|
|
if (data.shotsPerVolley > 48)
|
|
data.shotsPerVolley = 48;//(48 / data.numOfVolley);
|
|
if (data.shotsPerVolley <= 0)
|
|
data.shotsPerVolley = 1;
|
|
|
|
data.typeOfAmmunition = m_explosionArea.chargeStruct().chargeTypeId();
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
void EffectShowExplosionArea::calculateSquare()
|
|
{
|
|
// start position of the area
|
|
Core::GeoPosition2D geoPos = m_explosionArea.area().cornerBottomLeft();
|
|
m_lowerLeftPos = LtsCoordTrans::UtmCoordinate::fromGeographic(geoPos.lon(), geoPos.lat());
|
|
|
|
// Calculate squares.
|
|
m_areasWidth = getAreasSideLength(m_explosionArea.area().width()); // Squares in x-direction
|
|
m_areasDepth = getAreasSideLength(m_explosionArea.area().height()); // Squares in y-direction
|
|
// Calculate number of squares
|
|
if (m_handlerPdmData->isSmoke(m_explosionArea.chargeStruct()))
|
|
m_numOfEffectShows = 1;
|
|
else
|
|
m_numOfEffectShows = m_areasWidth.numOfAreas * m_areasDepth.numOfAreas;
|
|
|
|
DEBUG_LOG(m_logger) << "Calc Square poslef " << m_lowerLeftPos.x << " " << m_lowerLeftPos.y << " witdh" << m_areasWidth.sideLength1 << " depth " << m_areasDepth.sideLength1 << " num of Effect Shows " << m_numOfEffectShows;
|
|
}
|
|
//static ----------------------------------------------------------------------
|
|
LtsCoordTrans::UtmCoordinate EffectShowExplosionArea::rotate(const LtsCoordTrans::UtmCoordinate &p, const LtsCoordTrans::UtmCoordinate &c, double angle)
|
|
{
|
|
LtsCoordTrans::UtmCoordinate res = p; // copy zone, northp
|
|
res.x = ((p.x - c.x) * cos(angle)) - ((p.y - c.y) * sin(angle)) + c.x;
|
|
res.y = ((p.x - c.x) * sin(angle)) + ((p.y - c.y) * cos(angle)) + c.y;
|
|
|
|
return res;
|
|
}
|
|
|
|
//static ----------------------------------------------------------------------
|
|
EffectShowExplosionArea::areas_t EffectShowExplosionArea::getAreasSideLength(double sideLength)
|
|
{
|
|
areas_t res;
|
|
|
|
int sl = qRound(sideLength + 0.5);
|
|
int n50 = (sl < 25) ? 1 : (sl + 25) / 50; // number of 50m squares
|
|
int n300 = n50 / 6; // number of 300m squares
|
|
int len = n50 * 50; // length to be diveded into squares
|
|
|
|
res.numOfAreas = ((n300 * 6) == n50) ? n300 : n300 + 1; // number of areas at all
|
|
|
|
res.sideLength1 = (len / (res.numOfAreas * 50)) * 50;
|
|
res.numSideLength2 = (len - (res.numOfAreas * res.sideLength1)) / 50;
|
|
res.sideLength2 = res.sideLength1 + 50;
|
|
res.numSideLength1 = res.numOfAreas - res.numSideLength2;
|
|
//qCritical() << "sl = " << sl << " n50= " << n50 << " n300 = " << n300 << " len = "
|
|
// << len << " numOfAreas = " << res.numOfAreas << " sideLength1 = " << res.sideLength1;
|
|
return res;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
int EffectShowExplosionArea::getNumberOfVolley() const
|
|
{
|
|
const int v = getShotsPerArea();
|
|
return getNumberOfVolley(v);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
int EffectShowExplosionArea::getShotsPerArea() const
|
|
{
|
|
if (!m_numOfEffectShows)
|
|
return 0;
|
|
int v = m_explosionArea.cannonCount() * m_explosionArea.cannonRounds();
|
|
return v / m_numOfEffectShows; //split even across all effect shows
|
|
}
|
|
|
|
int EffectShowExplosionArea::getShotsPerArea(int areas) const
|
|
{
|
|
if (areas == 0)
|
|
return 0;
|
|
int v = m_explosionArea.cannonCount() * m_explosionArea.cannonRounds();
|
|
|
|
return v / areas;
|
|
}
|
|
|
|
int EffectShowExplosionArea::getNumberOfVolley(int v)
|
|
{
|
|
if (v < 3) // <= 0 should not happen but did...
|
|
return qMax(1, v);
|
|
if (v <= 25)
|
|
return 3;
|
|
if (v <= 50)
|
|
return 6;
|
|
if (v <= 100)
|
|
return 9;
|
|
if (v <= 150)
|
|
return 12;
|
|
if (v <= 200)
|
|
return 15;
|
|
return 18;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
double EffectShowExplosionArea::rotationRad() const
|
|
{
|
|
return -m_explosionArea.area().rotation() * LtsCoordTrans::deg2rad();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
} // Namespace EffectShowManagement
|