diff options
Diffstat (limited to 'dep/include/g3dlite/G3D/Box2D.h')
| -rw-r--r-- | dep/include/g3dlite/G3D/Box2D.h | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/dep/include/g3dlite/G3D/Box2D.h b/dep/include/g3dlite/G3D/Box2D.h new file mode 100644 index 00000000000..80accad89dd --- /dev/null +++ b/dep/include/g3dlite/G3D/Box2D.h @@ -0,0 +1,121 @@ +/** + @file Box2D.h + + @maintainer Morgan McGuire, http://graphics.cs.williams.edu + + @created 2001-06-02 + @edited 2008-12-27 + + Copyright 2000-2009, Morgan McGuire. + All rights reserved. + */ + +#ifndef G3D_Box2D_h +#define G3D_Box2D_h + +#include "G3D/platform.h" +#include "G3D/Vector2.h" + +namespace G3D { + +class CoordinateFrame; +typedef class CoordinateFrame CFrame; +class Rect2D; +typedef class Rect2D AABox2D; + +/** + 2D oriented box + @cite http://www.flipcode.com/archives/2D_OBB_Intersection.shtml + */ +class Box2D { +private: + /** Corners of the box, where 0 is the lower left. */ + Vector2 m_corner[4]; + + /** Two edges of the box extended away from corner[0], with length + = 1 / extentSquared */ + Vector2 m_axisin[2]; + + /** Two edges of the box extended away from corner[0], with unit length */ + Vector2 m_axis[2]; + + /** Centroid of the box */ + Vector2 m_center; + + /** origin[a] = m_corner[0].dot(m_axisin[a]); */ + float origin[2]; + + /** Surface area */ + float m_area; + + Vector2 m_extent; + + /** Returns true if other overlaps one dimension of this. */ + bool overlaps1Way(const Box2D& other) const; + + + /** Updates the axes after the m_corners move. Assumes the + m_corners actually form a rectangle. */ + void computeAxes(); + +public: + + /** + @param center World-space center + @param w Width along object-space x-axis + @param h Height along object-space y-axis + @param angle Counter-clockwise angle from object-space x-axis in radians + */ + Box2D(const Vector2& center = Vector2(0, 0), float w = 0, float h = 0, float angle = 0); + + Box2D(const AABox2D& b); + + Box2D(const Vector2& min, const Vector2& max); + + /** Transform @a b by @a frame, discarding the Z components, and + compute the new box.*/ + Box2D(const CFrame& frame, Box2D& b); + + inline bool contains(const Vector2& v) const { + // Take to object space: + const Vector2& p = v - m_center; + float x = p.dot(m_axisin[0]); + float y = p.dot(m_axisin[1]); + + // Must be within extent/2 on both axes in object space + return (abs(x) <= 0.5f) && (abs(y) <= 0.5f); + } + + /** @brief Distance from corner(0) to the next corner along the box's local axis a. */ + inline const Vector2& extent() const { + return m_extent; + } + + /** @brief Unit length vector along axis @a a */ + inline const Vector2& axis(int a) const { + debugAssert(a == 0 || a == 1); + return m_axis[a]; + } + + /** @brief Surface area */ + inline float area() const { + return m_area; + } + + inline const Vector2& corner(int i) const { + debugAssert(i >=0 && i <= 3); + return m_corner[i]; + } + + inline const Vector2& center() const { + return m_center; + } + + /** Returns true if the intersection of the boxes is non-empty. */ + inline bool overlaps(const Box2D& other) const { + return overlaps1Way(other) && other.overlaps1Way(*this); + } +}; + +} // G3D +#endif |
