/** * @RDE_HEADER@ * Building VWM info * $Id$ * $HeadURL$ * $Author$ * Created by Gerlinde Rudolphus, SLSA, 2017-01-15 */ #pragma once #include #include #include #include #include #include "vwm_types.h" #include 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; using ExclusionZoneElement = QVector; // 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 &elements() { return m_elements; } const QVector &elements() const { return m_elements; } private: QVector m_elements; }; // // class OuterWall // class OuterWall : public WallExclusionZoneBase { public: QVector &elements() { return m_elements; } const QVector &elements() const { return m_elements; } QVector &exclusionZones() { return m_exclusionZones; } const QVector &exclusionZones() const { return m_exclusionZones; } bool isDummyWall() const { return m_elements.isEmpty(); } private: QVector m_exclusionZones; QVector 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 &neighbours() { return m_neighbours; } const QMap &neighbours() const { return m_neighbours; } QVector &outerWalls() { return m_outerWalls; } const QVector &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 m_neighbours; QVector 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 &rooms() { return m_rooms; } const QMap &rooms() const { return m_rooms; } // calculated values int damagePercent() const; QVector roomStates() const; DamageState damageState() const; // effects on building void init(); void destroyAllRooms(); void setRoomState(DamageState damageState, const QVector &afffectedRooms); void setFortifyInfo(const QVector &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 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 &points) const; int cleanupDublicatePointsInPolygon(int roomId, int idx, int subIdx, const char *type, QVector &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 &cont); static QString toString(const QMap &cont); static QString toString(const QSet &cont); QMap checkHitNeighbours(const QMap &neighbours, const Charge &charge, QSet ¤tGradeNeighbours, QSet &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 m_rooms; QString m_buildingProperties; QMap 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 &poly); QVector calculate(bool *bMakePlanarDone = nullptr); QVector 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(dim)]; } double ratioOfSmallestAndBiggestDimension(); void makePlanar(); private: QVector m_poly; std::vector ranges; DIMENSION m_smallestDim{DIMENSION::X}; DIMENSION m_biggistDim{DIMENSION::X}; double m_ratio{0.0}; }; // class MakePlanar } // namespace VWM } // namespace BuildingControlUnit