text: /*
  * Copyright (c) 2006-2009 Erin Catto http://www.box2d.org
  *
  * This software is provided 'as-is', without any express or implied
  * warranty.  In no event will the authors be held liable for any damages
  * arising from the use of this software.
  * Permission is granted to anyone to use this software for any purpose,
  * including commercial applications, and to alter it and redistribute it
  * freely, subject to the following restrictions:
  * 1. The origin of this software must not be misrepresented; you must not
  * claim that you wrote the original software. If you use this software
  * in a product, an acknowledgment in the product documentation would be
  * appreciated but is not required.
  * 2. Altered source versions must be plainly marked as such, and must not be
  * misrepresented as being the original software.
  * 3. This notice may not be removed or altered from any source distribution.
  */
  
  #ifndef B2_COLLISION_H
  #define B2_COLLISION_H
  
  #include "b2Math.h"
  #include <climits>
  
  /// Ray-cast input data. The ray extends from p1 to p1 + maxFraction * (p2 - p1).
  struct b2RayCastInput
  {
  	b2Vec2 p1, p2;
  	float32 maxFraction;
  };
  
  /// Ray-cast output data. The ray hits at p1 + fraction * (p2 - p1), where p1 and p2
  /// come from b2RayCastInput.
  struct b2RayCastOutput
  {
  	b2Vec2 normal;
  	float32 fraction;
  };
  
  /// An axis aligned bounding box.
  struct b2AABB
  {
  	/// Verify that the bounds are sorted.
  	bool IsValid() const;
  
  	/// Get the center of the AABB.
  	b2Vec2 GetCenter() const
  	{
  		return 0.5f * (lowerBound + upperBound);
  	}
  
  	/// Get the extents of the AABB (half-widths).
  	b2Vec2 GetExtents() const
  	{
  		return 0.5f * (upperBound - lowerBound);
  	}
  
  	/// Get the perimeter length
  	float32 GetPerimeter() const
  	{
  		float32 wx = upperBound.x - lowerBound.x;
  		float32 wy = upperBound.y - lowerBound.y;
  		return 2.0f * (wx + wy);
  	}
  
  	/// Combine an AABB into this one.
  	void Combine(const b2AABB& aabb)
  	{
  		lowerBound = b2Min(lowerBound, aabb.lowerBound);
  		upperBound = b2Max(upperBound, aabb.upperBound);
  	}
  
  	/// Combine two AABBs into this one.
  	void Combine(const b2AABB& aabb1, const b2AABB& aabb2)
  	{
  		lowerBound = b2Min(aabb1.lowerBound, aabb2.lowerBound);
  		upperBound = b2Max(aabb1.upperBound, aabb2.upperBound);
  	}
  
  	/// Does this aabb contain the provided AABB.
  	bool Contains(const b2AABB& aabb) const
  	{
  		bool result = true;
  		result = result && lowerBound.x <= aabb.lowerBound.x;
  		result = result && lowerBound.y <= aabb.lowerBound.y;
  		result = result && aabb.upperBound.x <= upperBound.x;
  		result = result && aabb.upperBound.y <= upperBound.y;
  		return result;
  	}
  
  	bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input) const;
  
  	b2Vec2 lowerBound;	///< the lower vertex
  	b2Vec2 upperBound;	///< the upper vertex
  };
  
  // ---------------- Inline Functions ------------------------------------------
  
  inline bool b2AABB::IsValid() const
  {
  	b2Vec2 d = upperBound - lowerBound;
  	bool valid = d.x >= 0.0f && d.y >= 0.0f;
  	valid = valid && lowerBound.IsValid() && upperBound.IsValid();
  	return valid;
  }
  
  inline bool b2TestOverlap(const b2AABB& a, const b2AABB& b)
  {
  	b2Vec2 d1, d2;
  	d1 = b.lowerBound - a.upperBound;
  	d2 = a.lowerBound - b.upperBound;
  
  	if (d1.x > 0.0f || d1.y > 0.0f)
  		return false;
  
  	if (d2.x > 0.0f || d2.y > 0.0f)
  		return false;
  
  	return true;
  }
  
  #endif
  