diff options
Diffstat (limited to 'src/common')
-rw-r--r-- | src/common/Collision/DynamicTree.cpp | 22 | ||||
-rw-r--r-- | src/common/Collision/DynamicTree.h | 10 | ||||
-rw-r--r-- | src/common/Collision/Models/GameObjectModel.cpp | 4 | ||||
-rw-r--r-- | src/common/Collision/Models/GameObjectModel.h | 6 | ||||
-rw-r--r-- | src/common/Utilities/Containers.h | 37 | ||||
-rw-r--r-- | src/common/Utilities/EnumClassFlag.h | 82 |
6 files changed, 137 insertions, 24 deletions
diff --git a/src/common/Collision/DynamicTree.cpp b/src/common/Collision/DynamicTree.cpp index 0e6c80d15ca..2fa66ab3adb 100644 --- a/src/common/Collision/DynamicTree.cpp +++ b/src/common/Collision/DynamicTree.cpp @@ -146,11 +146,11 @@ void DynamicMapTree::update(uint32 t_diff) struct DynamicTreeIntersectionCallback { - DynamicTreeIntersectionCallback(std::set<uint32> const& phases) : _didHit(false), _phases(phases) { } + DynamicTreeIntersectionCallback(PhaseShift const& phaseShift) : _didHit(false), _phaseShift(phaseShift) { } bool operator()(G3D::Ray const& r, GameObjectModel const& obj, float& distance) { - _didHit = obj.intersectRay(r, distance, true, _phases); + _didHit = obj.intersectRay(r, distance, true, _phaseShift); return _didHit; } @@ -158,20 +158,20 @@ struct DynamicTreeIntersectionCallback private: bool _didHit; - std::set<uint32> _phases; + PhaseShift const& _phaseShift; }; -bool DynamicMapTree::getIntersectionTime(std::set<uint32> const& phases, G3D::Ray const& ray, G3D::Vector3 const& endPos, float& maxDist) const +bool DynamicMapTree::getIntersectionTime(G3D::Ray const& ray, G3D::Vector3 const& endPos, PhaseShift const& phaseShift, float& maxDist) const { float distance = maxDist; - DynamicTreeIntersectionCallback callback(phases); + DynamicTreeIntersectionCallback callback(phaseShift); impl->intersectRay(ray, callback, distance, endPos); if (callback.didHit()) maxDist = distance; return callback.didHit(); } -bool DynamicMapTree::getObjectHitPos(std::set<uint32> const& phases, G3D::Vector3 const& startPos, G3D::Vector3 const& endPos, G3D::Vector3& resultHitPos, float modifyDist) const +bool DynamicMapTree::getObjectHitPos(G3D::Vector3 const& startPos, G3D::Vector3 const& endPos, G3D::Vector3& resultHitPos, float modifyDist, PhaseShift const& phaseShift) const { bool result = false; float maxDist = (endPos - startPos).magnitude(); @@ -186,7 +186,7 @@ bool DynamicMapTree::getObjectHitPos(std::set<uint32> const& phases, G3D::Vector G3D::Vector3 dir = (endPos - startPos)/maxDist; // direction with length of 1 G3D::Ray ray(startPos, dir); float dist = maxDist; - if (getIntersectionTime(phases, ray, endPos, dist)) + if (getIntersectionTime(ray, endPos, phaseShift, dist)) { resultHitPos = startPos + dir * dist; if (modifyDist < 0) @@ -209,7 +209,7 @@ bool DynamicMapTree::getObjectHitPos(std::set<uint32> const& phases, G3D::Vector return result; } -bool DynamicMapTree::isInLineOfSight(G3D::Vector3 const& startPos, G3D::Vector3 const& endPos, std::set<uint32> const& phases) const +bool DynamicMapTree::isInLineOfSight(G3D::Vector3 const& startPos, G3D::Vector3 const& endPos, PhaseShift const& phaseShift) const { float maxDist = (endPos - startPos).magnitude(); @@ -217,17 +217,17 @@ bool DynamicMapTree::isInLineOfSight(G3D::Vector3 const& startPos, G3D::Vector3 return true; G3D::Ray r(startPos, (endPos - startPos) / maxDist); - DynamicTreeIntersectionCallback callback(phases); + DynamicTreeIntersectionCallback callback(phaseShift); impl->intersectRay(r, callback, maxDist, endPos); return !callback.didHit(); } -float DynamicMapTree::getHeight(float x, float y, float z, float maxSearchDist, std::set<uint32> const& phases) const +float DynamicMapTree::getHeight(float x, float y, float z, float maxSearchDist, PhaseShift const& phaseShift) const { G3D::Vector3 v(x, y, z + 0.5f); G3D::Ray r(v, G3D::Vector3(0, 0, -1)); - DynamicTreeIntersectionCallback callback(phases); + DynamicTreeIntersectionCallback callback(phaseShift); impl->intersectZAllignedRay(r, callback, maxSearchDist); if (callback.didHit()) diff --git a/src/common/Collision/DynamicTree.h b/src/common/Collision/DynamicTree.h index e26ffebdc33..b2a198a1846 100644 --- a/src/common/Collision/DynamicTree.h +++ b/src/common/Collision/DynamicTree.h @@ -21,7 +21,6 @@ #define _DYNTREE_H #include "Define.h" -#include <set> namespace G3D { @@ -30,6 +29,7 @@ namespace G3D } class GameObjectModel; +class PhaseShift; struct DynTreeImpl; class TC_COMMON_API DynamicMapTree @@ -41,11 +41,11 @@ public: DynamicMapTree(); ~DynamicMapTree(); - bool isInLineOfSight(G3D::Vector3 const& startPos, G3D::Vector3 const& endPos, std::set<uint32> const& phases) const; - bool getIntersectionTime(std::set<uint32> const& phases, G3D::Ray const& ray, G3D::Vector3 const& endPos, float& maxDist) const; - bool getObjectHitPos(std::set<uint32> const& phases, G3D::Vector3 const& startPos, G3D::Vector3 const& endPos, G3D::Vector3& resultHitPos, float modifyDist) const; + bool isInLineOfSight(G3D::Vector3 const& startPos, G3D::Vector3 const& endPos, PhaseShift const& phaseShift) const; + bool getIntersectionTime(G3D::Ray const& ray, G3D::Vector3 const& endPos, PhaseShift const& phaseShift, float& maxDist) const; + bool getObjectHitPos(G3D::Vector3 const& startPos, G3D::Vector3 const& endPos, G3D::Vector3& resultHitPos, float modifyDist, PhaseShift const& phaseShift) const; - float getHeight(float x, float y, float z, float maxSearchDist, std::set<uint32> const& phases) const; + float getHeight(float x, float y, float z, float maxSearchDist, PhaseShift const& phaseShift) const; void insert(const GameObjectModel&); void remove(const GameObjectModel&); diff --git a/src/common/Collision/Models/GameObjectModel.cpp b/src/common/Collision/Models/GameObjectModel.cpp index 538086f2ea3..350c52bfde0 100644 --- a/src/common/Collision/Models/GameObjectModel.cpp +++ b/src/common/Collision/Models/GameObjectModel.cpp @@ -152,12 +152,12 @@ GameObjectModel* GameObjectModel::Create(std::unique_ptr<GameObjectModelOwnerBas return mdl; } -bool GameObjectModel::intersectRay(G3D::Ray const& ray, float& maxDist, bool stopAtFirstHit, std::set<uint32> const& phases) const +bool GameObjectModel::intersectRay(G3D::Ray const& ray, float& maxDist, bool stopAtFirstHit, PhaseShift const& phaseShift) const { if (!isCollisionEnabled() || !owner->IsSpawned()) return false; - if (!owner->IsInPhase(phases)) + if (!owner->IsInPhase(phaseShift)) return false; float time = ray.intersectionTime(iBound); diff --git a/src/common/Collision/Models/GameObjectModel.h b/src/common/Collision/Models/GameObjectModel.h index 1e42da90d85..53d1d1ca149 100644 --- a/src/common/Collision/Models/GameObjectModel.h +++ b/src/common/Collision/Models/GameObjectModel.h @@ -26,7 +26,6 @@ #include "Define.h" #include <memory> -#include <set> namespace VMAP { @@ -34,6 +33,7 @@ namespace VMAP } class GameObject; +class PhaseShift; struct GameObjectDisplayInfoEntry; class TC_COMMON_API GameObjectModelOwnerBase @@ -43,7 +43,7 @@ public: virtual bool IsSpawned() const { return false; } virtual uint32 GetDisplayId() const { return 0; } - virtual bool IsInPhase(std::set<uint32> const& /*phases*/) const { return false; } + virtual bool IsInPhase(PhaseShift const& /*phaseShift*/) const { return false; } virtual G3D::Vector3 GetPosition() const { return G3D::Vector3::zero(); } virtual float GetOrientation() const { return 0.0f; } virtual float GetScale() const { return 1.0f; } @@ -66,7 +66,7 @@ public: void enableCollision(bool enable) { _collisionEnabled = enable; } bool isCollisionEnabled() const { return _collisionEnabled; } - bool intersectRay(G3D::Ray const& ray, float& maxDist, bool stopAtFirstHit, std::set<uint32> const& phases) const; + bool intersectRay(G3D::Ray const& ray, float& maxDist, bool stopAtFirstHit, PhaseShift const& phaseShift) const; static GameObjectModel* Create(std::unique_ptr<GameObjectModelOwnerBase> modelOwner, std::string const& dataPath); diff --git a/src/common/Utilities/Containers.h b/src/common/Utilities/Containers.h index cf23949c10a..581fbfabe6b 100644 --- a/src/common/Utilities/Containers.h +++ b/src/common/Utilities/Containers.h @@ -118,7 +118,7 @@ namespace Trinity * Note: container cannot be empty */ template<class C, class Fn> - auto SelectRandomWeightedContainerElement(C const& container, Fn weightExtractor) -> decltype(std::begin(container)) + inline auto SelectRandomWeightedContainerElement(C const& container, Fn weightExtractor) -> decltype(std::begin(container)) { std::vector<double> weights; weights.reserve(Size(container)); @@ -161,7 +161,7 @@ namespace Trinity * @return true if containers have a common element, false otherwise. */ template<class Iterator1, class Iterator2> - bool Intersects(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) + inline bool Intersects(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2) { while (first1 != last1 && first2 != last2) { @@ -177,6 +177,37 @@ namespace Trinity } /** + * @fn bool Trinity::Containers::Intersects(Iterator first1, Iterator last1, Iterator first2, Iterator last2, Predicate&& equalPred) + * + * @brief Checks if two SORTED containers have a common element + * + * @param first1 Iterator pointing to start of the first container + * @param last1 Iterator pointing to end of the first container + * @param first2 Iterator pointing to start of the second container + * @param last2 Iterator pointing to end of the second container + * @param equalPred Additional predicate to exclude elements + * + * @return true if containers have a common element, false otherwise. + */ + template<class Iterator1, class Iterator2, class Predicate> + inline bool Intersects(Iterator1 first1, Iterator1 last1, Iterator2 first2, Iterator2 last2, Predicate&& equalPred) + { + while (first1 != last1 && first2 != last2) + { + if (*first1 < *first2) + ++first1; + else if (*first2 < *first1) + ++first2; + else if (!equalPred(*first1, *first2)) + ++first1, ++first2; + else + return true; + } + + return false; + } + + /** * Returns a pointer to mapped value (or the value itself if map stores pointers) */ template<class M> @@ -187,7 +218,7 @@ namespace Trinity } template<class K, class V, template<class, class, class...> class M, class... Rest> - void MultimapErasePair(M<K, V, Rest...>& multimap, K const& key, V const& value) + inline void MultimapErasePair(M<K, V, Rest...>& multimap, K const& key, V const& value) { auto range = multimap.equal_range(key); for (auto itr = range.first; itr != range.second;) diff --git a/src/common/Utilities/EnumClassFlag.h b/src/common/Utilities/EnumClassFlag.h new file mode 100644 index 00000000000..68ee56edb07 --- /dev/null +++ b/src/common/Utilities/EnumClassFlag.h @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2008-2018 TrinityCore <https://www.trinitycore.org/> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see <http://www.gnu.org/licenses/>. + */ + +#ifndef EnumClassFlag_h__ +#define EnumClassFlag_h__ + +#include <type_traits> + +template<typename T> +class EnumClassFlag +{ + static_assert(std::is_enum<T>::value, "EnumClassFlag must be used only with enums"); + +public: + /*implicit*/ EnumClassFlag(T value) : _value(value) { } + + EnumClassFlag& operator&=(EnumClassFlag right) + { + _value = static_cast<T>(static_cast<std::underlying_type_t<T>>(_value) & static_cast<std::underlying_type_t<T>>(right._value)); + return *this; + } + + friend EnumClassFlag operator&(EnumClassFlag left, EnumClassFlag right) + { + return left &= right; + } + + EnumClassFlag operator|=(EnumClassFlag right) + { + _value = static_cast<T>(static_cast<std::underlying_type_t<T>>(_value) | static_cast<std::underlying_type_t<T>>(right._value)); + return *this; + } + + friend EnumClassFlag operator|(EnumClassFlag left, EnumClassFlag right) + { + return left |= right; + } + + EnumClassFlag operator~() const + { + return static_cast<T>(~static_cast<std::underlying_type_t<T>>(_value)); + } + + void RemoveFlag(EnumClassFlag flag) + { + _value = static_cast<T>(static_cast<std::underlying_type_t<T>>(_value) & ~static_cast<std::underlying_type_t<T>>(flag._value)); + } + + bool HasFlag(T flag) const + { + return (static_cast<std::underlying_type_t<T>>(_value) & static_cast<std::underlying_type_t<T>>(flag)) != 0; + } + + operator T() const + { + return _value; + } + + std::underlying_type_t<T> AsUnderlyingType() const + { + return static_cast<std::underlying_type_t<T>>(_value); + } + +private: + T _value; +}; + +#endif // EnumClassFlag_h__ |