324 lines
10 KiB
C++
Executable File
324 lines
10 KiB
C++
Executable File
/**
|
|
* @RDE_HEADER@
|
|
* Building VWM info
|
|
* $Id$
|
|
* $HeadURL$
|
|
* $Author$
|
|
* Created by Gerlinde Rudolphus, SLSA, 2017-01-15
|
|
*/
|
|
|
|
#pragma once
|
|
|
|
#include <QString>
|
|
#include <QMap>
|
|
#include <QVector>
|
|
#include <LtsUtilsCore/qpoint3d.h>
|
|
#include <logger.h>
|
|
#include "vwm_types.h"
|
|
#include <VWM/buildingcontrolvwm_export.h>
|
|
|
|
namespace BuildingControlUnit
|
|
{
|
|
namespace VWM
|
|
{
|
|
//
|
|
// class NeighbourRoom
|
|
//
|
|
class NeighbourRoom
|
|
{
|
|
public:
|
|
void setId(int id) { m_id = id; }
|
|
int id() const { return m_id; }
|
|
|
|
void setTransitionFactor(double transitionFactor) { m_transitionFactor = transitionFactor; }
|
|
double transitionFactor() const { return m_transitionFactor; }
|
|
|
|
private:
|
|
// static data from config
|
|
int m_id = 0;
|
|
double m_transitionFactor = 0;
|
|
};
|
|
|
|
using WallElement = QVector<LtsUtils::QPoint3D>;
|
|
using ExclusionZoneElement = QVector<LtsUtils::QPoint3D>;
|
|
|
|
// some helper functions
|
|
void wallElementToBottomLeftTopRight3D(const WallElement &wallElement,
|
|
LtsUtils::QPoint3D &bottomLeftOut,
|
|
LtsUtils::QPoint3D &topRightOut);
|
|
LtsUtils::QPoint3D centerOfWallElement3D(const WallElement &wallElement);
|
|
|
|
//
|
|
// class WallExclusionZoneBase
|
|
//
|
|
class WallExclusionZoneBase
|
|
{
|
|
public:
|
|
// from config
|
|
void setProtectiveFactor(double protectiveFactor) { m_protectiveFactor = protectiveFactor; }
|
|
double protectiveFactor() const { return m_protectiveFactor; }
|
|
|
|
// calculated from config
|
|
void setInitalProtection(double initialProtection, bool bResetProtection);
|
|
double initialProtection() const { return m_initialProtection; }
|
|
double protectionPercent() const {
|
|
if (m_initialProtection<=0.0)
|
|
return 0.0; // avoid nan (not-a-number)
|
|
return m_protection / m_initialProtection * 100;
|
|
} // for debug purposes
|
|
|
|
// calculated on hit
|
|
void updateProtection(const double RW, const double ZF, const double TF);
|
|
void setProtection(double protection) { m_protection = protection; }
|
|
double protection() const { return m_protection; }
|
|
|
|
protected:
|
|
WallExclusionZoneBase() = default;
|
|
|
|
// static data from config
|
|
double m_protectiveFactor = 0;
|
|
// initial data (Wall: BGPL * OWPL * OWPF, ExclusionZone: BGPL * EZPL * EZPF)
|
|
double m_initialProtection = 0;
|
|
|
|
// calculated data
|
|
double m_protection = 0;
|
|
};
|
|
|
|
//
|
|
// class ExclusionZone
|
|
//
|
|
class ExclusionZone : public WallExclusionZoneBase
|
|
{
|
|
public:
|
|
QVector<ExclusionZoneElement> &elements() { return m_elements; }
|
|
const QVector<ExclusionZoneElement> &elements() const { return m_elements; }
|
|
|
|
private:
|
|
QVector<ExclusionZoneElement> m_elements;
|
|
};
|
|
|
|
//
|
|
// class OuterWall
|
|
//
|
|
class OuterWall : public WallExclusionZoneBase
|
|
{
|
|
public:
|
|
QVector<WallElement> &elements() { return m_elements; }
|
|
const QVector<WallElement> &elements() const { return m_elements; }
|
|
|
|
QVector<ExclusionZone> &exclusionZones() { return m_exclusionZones; }
|
|
const QVector<ExclusionZone> &exclusionZones() const { return m_exclusionZones; }
|
|
|
|
bool isDummyWall() const { return m_elements.isEmpty(); }
|
|
private:
|
|
QVector<ExclusionZone> m_exclusionZones;
|
|
QVector<WallElement> m_elements;
|
|
};
|
|
|
|
//
|
|
// class Room
|
|
//
|
|
class Room
|
|
{
|
|
public:
|
|
void setId(int id) { m_id = id; }
|
|
int id() const { return m_id; }
|
|
bool isValid() const { return m_id != 0; }
|
|
bool isDirectHit() const { return m_directHit; }
|
|
void setDirectHit(bool directHit) { m_directHit = directHit; }
|
|
|
|
QMap<int, NeighbourRoom> &neighbours() { return m_neighbours; }
|
|
const QMap<int, NeighbourRoom> &neighbours() const { return m_neighbours; }
|
|
|
|
QVector<OuterWall> &outerWalls() { return m_outerWalls; }
|
|
const QVector<OuterWall> &outerWalls() const { return m_outerWalls; }
|
|
|
|
// Verstärkte Räume
|
|
void setFortifyFactor(double factorNew, bool bRecalcValues = true);
|
|
double fortifyFactor() const { return m_fortifyFactor; }
|
|
|
|
// calculated values
|
|
double damagePercent() const; // TODO: cache calculated value?
|
|
void setRemainingEffect(double remainingEffect) { m_remainingEffect = remainingEffect; }
|
|
double remainingEffect() const { return m_remainingEffect; }
|
|
// effect calculation
|
|
double calcRemainingEffect(const HitPosition &hitPos, const Charge &ammu) const;
|
|
void updateProtectionDirectHit(const HitPosition &hitPos, const Charge &ammu);
|
|
void updateProtectionIndirectHit(const HitPosition &hitPos, const Charge &ammu, double remainingEffect);
|
|
// returns false when the calculated effect is too low for a real change
|
|
bool updateProtectionNeighbourHit(const HitPosition &hitPos, const Charge &ammu, double remainingEffect, double transitionFactor);
|
|
|
|
// effects on Room
|
|
void init();
|
|
void destroy();
|
|
|
|
private:
|
|
// static data from config
|
|
int m_id = 0;
|
|
double m_remainingEffect = 0;
|
|
QMap<int, NeighbourRoom> m_neighbours;
|
|
QVector<OuterWall> m_outerWalls;
|
|
// dynamic data from excon
|
|
double m_fortifyFactor = 1.0;
|
|
bool m_directHit = false;
|
|
|
|
double protectionForHitPosition(const HitPosition &hitPos) const;
|
|
void setProtectionForHitPosition(const HitPosition &hitPos, double SG_neu);
|
|
static double calcRemainingEffect(double SG_alt, double ZF, double WF);
|
|
};
|
|
|
|
// exported for test xml reader
|
|
class BUILDINGCONTROLVWM_EXPORT Building
|
|
{
|
|
public:
|
|
Building();
|
|
|
|
int cleanupPolygons();
|
|
// used for xml file testing
|
|
int checkPolygons();
|
|
|
|
QString name() const { return m_name; }
|
|
void setName(const QString &name) { m_name = name; }
|
|
|
|
int modelId() const { return m_modelId; }
|
|
void setModelId(int modelId) { m_modelId = modelId; }
|
|
|
|
double buildingProtectionLevel() const { return m_buildingProtectionLevel; }
|
|
void setBuildingProtectionLevel(double buildingProtectionLevel) { m_buildingProtectionLevel = buildingProtectionLevel; }
|
|
|
|
int exclusionZoneProtectionLevel() const { return m_exclusionZoneProtectionLevel; }
|
|
void setExclusionZoneProtectionLevel(int exclusionZoneProtectionLevel) { m_exclusionZoneProtectionLevel = exclusionZoneProtectionLevel; }
|
|
|
|
int outerWallProtectionLevel() const { return m_outerWallProtectionLevel; }
|
|
void setOuterWallProtectionLevel(int outerWallProtectionLevel) { m_outerWallProtectionLevel = outerWallProtectionLevel; }
|
|
|
|
Room room(int roomId);
|
|
QMap<int, Room> &rooms() { return m_rooms; }
|
|
const QMap<int, Room> &rooms() const { return m_rooms; }
|
|
|
|
// calculated values
|
|
int damagePercent() const;
|
|
QVector<HitRoom> roomStates() const;
|
|
DamageState damageState() const;
|
|
|
|
// effects on building
|
|
void init();
|
|
void destroyAllRooms();
|
|
void setRoomState(DamageState damageState, const QVector<int> &afffectedRooms);
|
|
void setFortifyInfo(const QVector<FortifyInfo> &foritfyInfos);
|
|
bool hit(const LtsUtils::QPoint3D &pos, const LtsUtils::QPoint3D &dir, Charge charge, HitPosition *preCalculatedHitPosition = nullptr);
|
|
const HitPosition &lastHitPosition() const { return m_lastHitPosition; }
|
|
bool isLastHitPositionBelowGroundHack() const;
|
|
|
|
QString segmentProperties(const QString &hostname) const;
|
|
void setSegmentProperties(const QString &hostname, const QString &properties);
|
|
const QMap<QString, QString> segmentPropertyMap() const { return m_segmentProperties; }
|
|
void clearSegmentProperties() { m_segmentProperties.clear(); }
|
|
|
|
QString buildingProperties() const;
|
|
void setBuildingProperties(const QString &buildingProperties);
|
|
|
|
private:
|
|
void initRoom(Room &room) const;
|
|
static void destroyRoom(Room &room);
|
|
int checkDublicatePointsInPolygon(int roomId, int idx, int subIdx, const char *type,
|
|
const QVector<LtsUtils::QPoint3D> &points) const;
|
|
int cleanupDublicatePointsInPolygon(int roomId, int idx, int subIdx, const char *type,
|
|
QVector<LtsUtils::QPoint3D> &points) const;
|
|
struct NeighboursToCheck
|
|
{
|
|
NeighbourRoom room;
|
|
double remainEffect = 0;
|
|
NeighboursToCheck() = default;
|
|
NeighboursToCheck(const NeighbourRoom &r, double re)
|
|
: room(r), remainEffect(re)
|
|
{}
|
|
};
|
|
|
|
// for debugging purpose
|
|
static QString toString(const QVector<Building::NeighboursToCheck> &cont);
|
|
static QString toString(const QMap<int, Building::NeighboursToCheck> &cont);
|
|
static QString toString(const QSet<int> &cont);
|
|
|
|
QMap<int, NeighboursToCheck> checkHitNeighbours(const QMap<int, NeighboursToCheck> &neighbours,
|
|
const Charge &charge,
|
|
QSet<int> ¤tGradeNeighbours,
|
|
QSet<int> &lowerGradeNeighbours);
|
|
private:
|
|
// static data from config
|
|
QString m_name;
|
|
int m_modelId{0};
|
|
double m_buildingProtectionLevel{0.0};
|
|
int m_exclusionZoneProtectionLevel{0};
|
|
int m_outerWallProtectionLevel{0};
|
|
QMap<int, Room> m_rooms;
|
|
|
|
QString m_buildingProperties;
|
|
QMap<QString, QString> m_segmentProperties; // By Hostname;
|
|
|
|
HitPosition m_lastHitPosition; // for debug purposes
|
|
NGL::INGLLogger &m_logger;
|
|
|
|
};
|
|
|
|
//
|
|
// class MakePlanar
|
|
//
|
|
|
|
/*!
|
|
* \brief The MakePlanar class takes points and makes them planar
|
|
* "Polylines" of VWM (like bldg_1101.flt.VWM_Building.xml) are sometimes not planar.
|
|
* That is difficult/impossible for the further steps
|
|
* So here (or at getCoordsForPlane) we try to make (most) walls planar
|
|
*/
|
|
class BUILDINGCONTROLVWM_EXPORT MakePlanar
|
|
{
|
|
public:
|
|
|
|
// helper #1
|
|
enum class DIMENSION
|
|
{
|
|
Undefined = -1,
|
|
X = 0,
|
|
Y = 1,
|
|
Z = 2
|
|
};
|
|
|
|
// helper #2
|
|
struct MyRange
|
|
{
|
|
double min{0.0};
|
|
double max{0.0};
|
|
double range() const { return fabs(max - min); } // keep neg values in mind
|
|
};
|
|
|
|
|
|
// ctor
|
|
explicit MakePlanar(const QVector<LtsUtils::QPoint3D> &poly);
|
|
|
|
QVector<LtsUtils::QPoint3D> calculate(bool *bMakePlanarDone = nullptr);
|
|
|
|
QVector<LtsUtils::QPoint3D> getPoly() const { return m_poly; }
|
|
double getRatio() const { return m_ratio; }
|
|
double getSmallestRange() const { return getRange(m_smallestDim).range(); }
|
|
DIMENSION getSmallestDim() const { return m_smallestDim; }
|
|
|
|
protected:
|
|
const MyRange &getRange(DIMENSION dim) const { return ranges[static_cast<int>(dim)]; }
|
|
|
|
double ratioOfSmallestAndBiggestDimension();
|
|
void makePlanar();
|
|
|
|
private:
|
|
QVector<LtsUtils::QPoint3D> m_poly;
|
|
std::vector<MyRange> ranges;
|
|
DIMENSION m_smallestDim{DIMENSION::X};
|
|
DIMENSION m_biggistDim{DIMENSION::X};
|
|
double m_ratio{0.0};
|
|
}; // class MakePlanar
|
|
|
|
|
|
} // namespace VWM
|
|
} // namespace BuildingControlUnit
|
|
|