Created
December 31, 2013 18:03
-
-
Save vittorioromeo/8200297 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| template<typename T> class AABBImpl | |
| { | |
| public: | |
| using VecT = Vec2<T>; | |
| private: | |
| VecT position, halfSize; | |
| public: | |
| struct TagFromPosition { }; | |
| struct TagFromHalfSize { }; | |
| struct TagFromSize { }; | |
| struct TagFromPositionAndHalfSize { }; | |
| struct TagFromPositionAndSize { }; | |
| struct TagFromMinMax { }; | |
| struct TagFromLeftRightTopBottom { }; | |
| inline AABBImpl() = default; | |
| inline AABBImpl(TagFromPosition, const VecT& mPosition) noexcept : position{mPosition} { } | |
| inline AABBImpl(TagFromHalfSize, const VecT& mHalfSize) noexcept : halfSize{mHalfSize} { } | |
| inline AABBImpl(TagFromSize, const VecT& mSize) noexcept : AABBImpl{TagFromHalfSize{}, mSize / T(2)} { } | |
| inline AABBImpl(TagFromPositionAndHalfSize, const VecT& mPosition, const VecT& mHalfSize) noexcept : position{mPosition}, halfSize{mHalfSize} { } | |
| inline AABBImpl(TagFromPositionAndSize, const VecT& mPosition, const VecT& mSize) noexcept : AABBImpl{TagFromPositionAndHalfSize{}, mPosition, mSize / T(2)} { } | |
| inline AABBImpl(TagFromMinMax, const VecT& mMin, const VecT& mMax) noexcept : AABBImpl{TagFromPositionAndHalfSize{}, ssvs::getCenter(mMin, mMax), ssvs::getHalfSize(mMin, mMax)} { } | |
| inline AABBImpl(TagFromLeftRightTopBottom, T mLeft, T mRight, T mTop, T mBottom) noexcept : AABBImpl{TagFromMinMax{}, VecT{mLeft, mTop}, VecT{mRight, mBottom}} { } | |
| inline void setPosition(const VecT& mPosition) noexcept { position = mPosition; } | |
| inline void setX(T mX) noexcept { position.x = mX; } | |
| inline void setY(T mY) noexcept { position.y = mY; } | |
| inline void setHalfSize(const VecT& mHalfSize) noexcept { halfSize = mHalfSize; } | |
| inline void setSize(const VecT& mSize) noexcept { halfSize = mSize / 2; } | |
| inline void setWidth(T mWidth) noexcept { halfSize.x = mWidth / 2; } | |
| inline void setHeight(T mHeight) noexcept { halfSize.y = mHeight / 2; } | |
| inline const VecT& getPosition() const noexcept { return position; } | |
| inline T getX() const noexcept { return position.x; } | |
| inline T getY() const noexcept { return position.y; } | |
| inline T getLeft() const noexcept { return position.x - halfSize.x; } | |
| inline T getRight() const noexcept { return position.x + halfSize.x; } | |
| inline T getTop() const noexcept { return position.y - halfSize.y; } | |
| inline T getBottom() const noexcept { return position.y + halfSize.y; } | |
| inline const VecT& getHalfSize() const noexcept { return halfSize; } | |
| inline T getHalfWidth() const noexcept { return halfSize.x; } | |
| inline T getHalfHeight() const noexcept { return halfSize.y; } | |
| inline VecT getSize() const noexcept { return halfSize * T(2); } | |
| inline T getWidth() const noexcept { return halfSize.x * T(2); } | |
| inline T getHeight() const noexcept { return halfSize.y * T(2); } | |
| }; | |
| template<typename T = int, template<typename> class TImpl = AABBImpl> struct AABB : public TImpl<T> | |
| { | |
| private: | |
| struct TagFromImpl { }; | |
| template<typename... TArgs> inline AABB(TagFromImpl, TArgs&&... mArgs) noexcept : TImpl<T>{std::forward<TArgs>(mArgs)...} { } | |
| template<typename... TArgs> inline static AABB fromImpl(TArgs&&... mArgs) noexcept { return AABB{TagFromImpl{}, std::forward<TArgs>(mArgs)...}; } | |
| public: | |
| using VecT = typename TImpl<T>::VecT; | |
| inline AABB() = default; | |
| inline static AABB fromPosition(const VecT& mPosition) noexcept { return fromImpl(TImpl<T>::TagFromPosition, mPosition); } | |
| inline static AABB fromHalfSize(const VecT& mHalfSize) noexcept { return fromImpl(TImpl<T>::TagFromHalfSize, mHalfSize); } | |
| inline static AABB fromSize(const VecT& mSize) noexcept { return fromImpl(TImpl<T>::TagFromSize, mSize); } | |
| inline static AABB fromPositionAndHalfSize(const VecT& mPosition, const VecT& mHalfSize) noexcept { return fromImpl(TImpl<T>::TagFromPositionAndHalfSize, mPosition, mHalfSize); } | |
| inline static AABB fromPositionAndSize(const VecT& mPosition, const VecT& mSize) noexcept { return fromImpl(TImpl<T>::TagFromPositionAndSize, mPosition, mSize); } | |
| inline static AABB fromMinMax(const VecT& mMin, const VecT& mMax) noexcept { return fromImpl(TImpl<T>::TagFromMinMax, mMin, mMax); } | |
| inline static AABB fromMinMax(T mLeft, T mRight, T mTop, T mBottom) noexcept { return fromImpl(TImpl<T>::TagFromLeftRightTopBottom, mLeft, mRight, mTop, mBottom); } | |
| inline bool operator==(const AABB& mOther) const noexcept { return this->getPosition() == mOther.getPosition() && this->getHalfSize() == mOther.getHalfSize(); } | |
| inline bool operator!=(const AABB& mOther) const noexcept { return !(*this == mOther); } | |
| inline void move(const Vec2i& mOffset) noexcept { this->setPosition(this->getPosition() + mOffset); } | |
| template<typename TT = T> inline Vec2<TT> getVertexNW() const noexcept { return Vec2<TT>(this->getLeft(), this->getTop()); } | |
| template<typename TT = T> inline Vec2<TT> getVertexNE() const noexcept { return Vec2<TT>(this->getRight(), this->getTop()); } | |
| template<typename TT = T> inline Vec2<TT> getVertexSW() const noexcept { return Vec2<TT>(this->getLeft(), this->getBottom()); } | |
| template<typename TT = T> inline Vec2<TT> getVertexSE() const noexcept { return Vec2<TT>(this->getRight(), this->getBottom()); } | |
| template<typename TT = T> inline Segment<TT> getSegmentLeft() const noexcept { return {getVertexNW<TT>(), getVertexSW<TT>()}; } | |
| template<typename TT = T> inline Segment<TT> getSegmentRight() const noexcept { return {getVertexNE<TT>(), getVertexSE<TT>()}; } | |
| template<typename TT = T> inline Segment<TT> getSegmentTop() const noexcept { return {getVertexNW<TT>(), getVertexNE<TT>()}; } | |
| template<typename TT = T> inline Segment<TT> getSegmentBottom() const noexcept { return {getVertexSW<TT>(), getVertexSE<TT>()}; } | |
| template<typename TShape> inline bool isLeftOf(const TShape& mShape) const noexcept { return this->getRight() <= mShape.getLeft(); } | |
| template<typename TShape> inline bool isRightOf(const TShape& mShape) const noexcept { return this->getLeft() >= mShape.getRight(); } | |
| template<typename TShape> inline bool isAbove(const TShape& mShape) const noexcept { return this->getBottom() <= mShape.getTop(); } | |
| template<typename TShape> inline bool isBelow(const TShape& mShape) const noexcept { return this->getTop() >= mShape.getBottom(); } | |
| template<> inline bool isOverlapping(const VecT& mPoint) const noexcept { return mPoint.x >= this->getLeft() && mPoint.x < this->getRight() && mPoint.y >= this->getTop() && mPoint.y < this->getBottom(); } | |
| inline bool isOverlapping(const Segment<T>& mSegment) const noexcept { return Utils::isSegmentInsersecting(mSegment, getSegmentLeft<T>()) || Utils::isSegmentInsersecting(mSegment, getSegmentRight<T>()) || Utils::isSegmentInsersecting(mSegment, getSegmentTop<T>()) || Utils::isSegmentInsersecting(mSegment, getSegmentBottom<T>()); } | |
| inline bool isOverlapping(const AABB& mAABB) const noexcept { return !isLeftOf(mAABB) && !isRightOf(mAABB) && !isAbove(mAABB) && !isBelow(mAABB); } | |
| inline bool contains(const VecT& mPoint) const noexcept { return isOverlapping(mPoint); } | |
| inline bool contains(const Segment<T>& mSegment) const noexcept { return contains(mSegment.start) && contains(mSegment.end); } | |
| inline bool contains(const AABB& mAABB) const noexcept { return mAABB.getLeft() >= this->getLeft() && mAABB.getRight() < this->getRight() && mAABB.getTop() >= this->getTop() && mAABB.getBottom() < this->getBottom(); } | |
| }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment