Index: Box2D/Box2D/Box2D.h
===================================================================
--- Box2D/Box2D/Box2D.h	(revision 70)
+++ Box2D/Box2D/Box2D.h	(working copy)
@@ -35,6 +35,7 @@
 
 #include <Box2D/Collision/Shapes/b2CircleShape.h>
 #include <Box2D/Collision/Shapes/b2PolygonShape.h>
+#include <Box2D/Collision/Shapes/b2CapsuleShape.h>
 
 #include <Box2D/Collision/b2BroadPhase.h>
 #include <Box2D/Collision/b2Distance.h>
Index: Box2D/Box2D/CMakeLists.txt
===================================================================
--- Box2D/Box2D/CMakeLists.txt	(revision 70)
+++ Box2D/Box2D/CMakeLists.txt	(working copy)
@@ -15,10 +15,12 @@
 	Collision/b2TimeOfImpact.h
 )
 set(BOX2D_Shapes_SRCS
+	Collision/Shapes/b2CapsuleShape.cpp
 	Collision/Shapes/b2CircleShape.cpp
 	Collision/Shapes/b2PolygonShape.cpp
 )
 set(BOX2D_Shapes_HDRS
+	Collision/Shapes/b2CapsuleShape.h
 	Collision/Shapes/b2CircleShape.h
 	Collision/Shapes/b2PolygonShape.h
 	Collision/Shapes/b2Shape.h
@@ -53,18 +55,24 @@
 	Dynamics/b2WorldCallbacks.h
 )
 set(BOX2D_Contacts_SRCS
+	Dynamics/Contacts/b2CapsuleAndCircleContact.cpp
+	Dynamics/Contacts/b2CapsuleContact.cpp
 	Dynamics/Contacts/b2CircleContact.cpp
 	Dynamics/Contacts/b2Contact.cpp
 	Dynamics/Contacts/b2ContactSolver.cpp
+	Dynamics/Contacts/b2PolygonAndCapsuleContact.cpp
 	Dynamics/Contacts/b2PolygonAndCircleContact.cpp
 	Dynamics/Contacts/b2PolygonContact.cpp
 	Dynamics/Contacts/b2TOISolver.cpp
 )
 set(BOX2D_Contacts_HDRS
+	Dynamics/Contacts/b2CapsuleAndCircleContact.h
+	Dynamics/Contacts/b2CapsuleContact.h
 	Dynamics/Contacts/b2CircleContact.h
 	Dynamics/Contacts/b2Contact.h
 	Dynamics/Contacts/b2ContactSolver.h
 	Dynamics/Contacts/b2NullContact.h
+	Dynamics/Contacts/b2PolygonAndCapsuleContact.h
 	Dynamics/Contacts/b2PolygonAndCircleContact.h
 	Dynamics/Contacts/b2PolygonContact.h
 	Dynamics/Contacts/b2TOISolver.h
Index: Box2D/Box2D/Collision/b2Collision.cpp
===================================================================
--- Box2D/Box2D/Collision/b2Collision.cpp	(revision 70)
+++ Box2D/Box2D/Collision/b2Collision.cpp	(working copy)
@@ -248,3 +248,220 @@
 
 	return output.distance < 10.0f * b2_epsilon;
 }
+
+
+// Collision Detection in Interactive 3D Environments by Gino van den Bergen
+// From Section 3.4.1
+// x = mu1 * p1 + mu2 * p2
+// mu1 + mu2 = 1 && mu1 >= 0 && mu2 >= 0
+// mu1 = 1 - mu2;
+// x = (1 - mu2) * p1 + mu2 * p2
+//   = p1 + mu2 * (p2 - p1)
+// x = s + a * r (s := start, r := end - start)
+// s + a * r = p1 + mu2 * d (d := p2 - p1)
+// -a * r + mu2 * d = b (b := s - p1)
+// [-r d] * [a; mu2] = b
+// Cramer's rule:
+// denom = det[-r d]
+// a = det[b d] / denom
+// mu2 = det[-r b] / denom
+bool b2RaycastSegment(b2RayCastOutput* output, const b2RayCastInput& input, const b2Vec2& p1, const b2Vec2& p2)
+{
+	b2Vec2 s = input.p1;
+	b2Vec2 r = input.p2 - s;
+	b2Vec2 d = p2 - p1;
+	b2Vec2 n = b2Cross(d, 1.0f);
+
+	const float32 k_slop = 100.0f * b2_epsilon;
+	float32 denom = -b2Dot(r, n);
+
+	// Cull back facing collision and ignore parallel segments.
+	if (denom > k_slop)
+	{
+		// Does the segment intersect the infinite line associated with this segment?
+		b2Vec2 b = s - p1;
+		float32 a = b2Dot(b, n);
+
+		if (0.0f <= a && a <= input.maxFraction * denom)
+		{
+			float32 mu2 = -r.x * b.y + r.y * b.x;
+
+			// Does the segment intersect this segment?
+			if (-k_slop * denom <= mu2 && mu2 <= denom * (1.0f + k_slop))
+			{
+				a /= denom;
+				n.Normalize();
+				output->normal = n;
+				output->fraction = a;
+				return true;
+			}
+		}
+	}
+
+	return false;
+}	
+
+
+static void FindNearestPointOnLineSegment(	b2Vec2* nearest, float32* parameter,
+											const b2Vec2& A1, const b2Vec2& L, const b2Vec2& B,
+											bool infinite_line )
+{
+	float32 D = L.LengthSquared();
+	if (D < b2_epsilon * b2_epsilon)
+	{
+		*nearest = A1;
+		return;
+	}
+	
+	b2Vec2 AB = B - A1;
+	*parameter = b2Dot(L, AB) / D;
+	if (!infinite_line)
+	{
+		*parameter = b2Clamp(*parameter, 0.0f, 1.0f);
+	}
+	*nearest = A1 + *parameter * L;
+}
+
+// Based on Game Programming Gems 2
+// Fast, Robust Intersection of 3D Line Segments
+// Graham Rhodes, Applied Research Associates
+b2Vec2 b2NearestPointOnLine(const b2Vec2& point, const b2Vec2& p1, const b2Vec2& p2)
+{
+	b2Vec2 result;
+	float32 unused;
+	FindNearestPointOnLineSegment(&result, &unused, p1, p2 - p1, point, false);
+	return result;
+}
+
+static void FindNearestPointOfParallelLineSegments(	b2Vec2* x1, b2Vec2* x2,
+													const b2Vec2& A1, const b2Vec2& A2, const b2Vec2& La,
+													const b2Vec2& B1, const b2Vec2& B2, const b2Vec2& Lb)
+{
+	float32 s, t;
+	FindNearestPointOnLineSegment(x1, &s, A1, La, B1, true);
+	FindNearestPointOnLineSegment(x2, &t, A1, La, B2, true);
+	
+	if (s < 0.0f && t < 0.0f)
+	{
+		*x1 = A1;
+		if (s < t)
+			*x2 = B2;
+		else
+			*x2 = B1;
+		return;
+	}
+	
+	if (s > 1.0f && t > 1.0f)
+	{
+		*x1 = A2;
+		if (s < t)
+			*x2 = B1;
+		else
+			*x2 = B2;
+		return;
+	}
+	
+	float32 temp = 0.5f * (b2Clamp(s, 0.0f, 1.0f) + b2Clamp(t, 0.0f, 1.0f));
+	*x1 = A1 + temp * La;
+	
+	float32 unused;
+	FindNearestPointOnLineSegment(x2, &unused, B1, Lb, *x1, true);
+}
+
+static void AdjustNearestPoints(b2Vec2* x1, b2Vec2* x2,
+								const b2Vec2& A1, const b2Vec2& A2, const b2Vec2& La,
+								const b2Vec2& B1, const b2Vec2& B2, const b2Vec2& Lb,
+								float32 s, float32 t)
+{
+	if ((s < 0.0f || s > 1.0f) && (t < 0.0f || t > 1.0f))
+	{
+		s = b2Clamp(s, 0.0f, 1.0f);
+		*x1 = A1 + s * La;
+		FindNearestPointOnLineSegment(x2, &t, B1, Lb, *x1, true);
+		if (t < 0.0f || t > 1.0f)
+		{
+			t = b2Clamp(t, 0.0f, 1.0f);
+			*x2 = B1 + t * Lb;
+			FindNearestPointOnLineSegment(x1, &s, A1, La, *x2, false);
+			FindNearestPointOnLineSegment(x2, &t, B1, Lb, *x1, false);
+		}
+		return;
+	}
+	if (s < 0.0f || s > 1.0f)
+	{
+		s = b2Clamp(s, 0.0f, 1.0f);
+		*x1 = A1 + s * La;
+		FindNearestPointOnLineSegment(x2, &t, B1, Lb, *x1, false);
+		return;
+	}
+	b2Assert(t < 0.0f || t > 1.0f);
+	t = b2Clamp(t, 0.0f, 1.0f);
+	*x2 = B1 + t * Lb;
+	FindNearestPointOnLineSegment(x1, &s, A1, La, *x2, false);
+}
+
+static void IntersectLineSegments(	b2Vec2* x1, b2Vec2* x2,
+									const b2Vec2& A1, const b2Vec2& A2,
+									const b2Vec2& B1, const b2Vec2& B2)
+{
+	float32 unused;
+	
+	b2Vec2 La = A2 - A1;
+	b2Vec2 Lb = B2 - B1;
+	float32 L11 = La.LengthSquared();
+	float32 L22 = Lb.LengthSquared();
+	
+	// Check for degenerate parameters
+	if (L11 < b2_epsilon * b2_epsilon)
+	{
+		*x1 = A1;
+		FindNearestPointOnLineSegment(x2, &unused, B1, Lb, A1, false);
+		return;
+	}
+	if (L22 < b2_epsilon * b2_epsilon)
+	{
+		*x2 = B1;
+		FindNearestPointOnLineSegment(x1, &unused, A1, La, B1, false);
+		return;
+	}
+	
+	b2Vec2 AB = B1 - A1;
+	float32 L12 = -b2Dot(La, Lb);
+	float32 DetL = L11 * L22 - L12 * L12;
+	
+	// parallel segments
+	if (b2Abs(DetL) < b2_epsilon)
+	{
+		FindNearestPointOfParallelLineSegments(x1, x2, A1, A2, La, B1, B2, Lb);
+		return;
+	}
+	
+	float32 ra = b2Dot(La, AB);
+	float32 rb = -b2Dot(Lb, AB);
+	
+	float32 t = (L11 * rb - ra * L12) / DetL;
+	float32 s = (ra - L12 * t) / L11;
+	
+	// These tests can't quite stay within B2_FLT_EPSILON
+	//b2Assert(b2Abs(s * L11 + t * L12 - ra) < .0001f);
+	//b2Assert(b2Abs(s * L12 + t * L22 - rb) < .0001f);
+	
+	*x1 = A1 + s * La;
+	*x2 = B1 + t * Lb;
+	
+	if (s < 0.0f || s > 1.0f || t < 0.0f || t > 1.0f)
+	{
+		AdjustNearestPoints(x1, x2, A1, A2, La, B1, B2, Lb, s, t);
+	}
+}
+
+// Based on Game Programming Gems 2
+// Fast, Robust Intersection of 3D Line Segments
+// Graham Rhodes, Applied Research Associates
+float32 b2DistanceBetweenLines(	b2Vec2* x1, b2Vec2* x2,
+								const b2Vec2& A1, const b2Vec2& A2,
+								const b2Vec2& B1, const b2Vec2& B2)
+{
+	IntersectLineSegments(x1, x2, A1, A2, B1, B2);
+	return (*x2 - *x1).Length();
+}
\ No newline at end of file
Index: Box2D/Box2D/Collision/b2Collision.h
===================================================================
--- Box2D/Box2D/Collision/b2Collision.h	(revision 70)
+++ Box2D/Box2D/Collision/b2Collision.h	(working copy)
@@ -27,6 +27,7 @@
 /// queries, and TOI queries.
 
 class b2Shape;
+class b2CapsuleShape;
 class b2CircleShape;
 class b2PolygonShape;
 
@@ -212,6 +213,18 @@
 bool b2TestOverlap(const b2Shape* shapeA, const b2Shape* shapeB,
 				   const b2Transform& xfA, const b2Transform& xfB);
 
+/// Perform a raycast against a given line segment.
+bool b2RaycastSegment(b2RayCastOutput* output, const b2RayCastInput& input, const b2Vec2& p1, const b2Vec2& p2);
+
+/// Find the nearest point on a line.
+b2Vec2 b2NearestPointOnLine(const b2Vec2& point, const b2Vec2& p1, const b2Vec2& p2);
+
+/// Find the nearest points on between two different lines.
+float32 b2DistanceBetweenLines(	b2Vec2* x1, b2Vec2* x2,
+								const b2Vec2& A1, const b2Vec2& A2,
+								const b2Vec2& B1, const b2Vec2& B2);
+
+
 // ---------------- Inline Functions ------------------------------------------
 
 inline bool b2AABB::IsValid() const
Index: Box2D/Box2D/Collision/b2Distance.cpp
===================================================================
--- Box2D/Box2D/Collision/b2Distance.cpp	(revision 70)
+++ Box2D/Box2D/Collision/b2Distance.cpp	(working copy)
@@ -17,6 +17,7 @@
 */
 
 #include <Box2D/Collision/b2Distance.h>
+#include <Box2D/Collision/Shapes/b2CapsuleShape.h>
 #include <Box2D/Collision/Shapes/b2CircleShape.h>
 #include <Box2D/Collision/Shapes/b2PolygonShape.h>
 
@@ -44,6 +45,15 @@
 			m_radius = polygon->m_radius;
 		}
 		break;
+	
+	case b2Shape::e_capsule:
+	    {
+			const b2CapsuleShape* capsule = (b2CapsuleShape*)shape;
+			m_vertices = capsule->m_vertices;
+			m_count = 2;
+			m_radius = capsule->m_radius;
+	    }
+	    break;
 
 	default:
 		b2Assert(false);
Index: Box2D/Box2D/Collision/Shapes/b2CapsuleShape.cpp
===================================================================
--- Box2D/Box2D/Collision/Shapes/b2CapsuleShape.cpp	(revision 0)
+++ Box2D/Box2D/Collision/Shapes/b2CapsuleShape.cpp	(revision 0)
@@ -0,0 +1,194 @@
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com
+*
+* 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.
+*/
+
+#include <Box2D/Collision/Shapes/b2CapsuleShape.h>
+#include <new>
+
+void b2CapsuleShape::SetByExtentsX(float32 radius, float32 length)
+{
+	m_radius = radius;
+	float32 half = length * 0.5f;
+	m_vertices[0] = b2Vec2(-half, 0.0f);
+	m_vertices[1] = b2Vec2(half, 0.0f);
+}
+
+void b2CapsuleShape::SetByExtentsX(float32 radius, float32 length,
+									  const b2Vec2& center, float32 angle)
+{
+	SetByExtentsX(radius, length);
+	b2Transform xf;
+	xf.position = center;
+	xf.R.Set(angle);
+	
+	m_vertices[0] = b2Mul(xf, m_vertices[0]);
+	m_vertices[1] = b2Mul(xf, m_vertices[1]);
+}
+
+
+void b2CapsuleShape::SetByExtentsY(float32 radius, float32 height)
+{
+	m_radius = radius;
+	float32 half = height * 0.5f;
+	m_vertices[0] = b2Vec2(0.0f, -half);
+	m_vertices[1] = b2Vec2(0.0f, half);
+}
+
+void b2CapsuleShape::SetByExtentsY(float32 radius, float32 height,
+									  const b2Vec2& center, float32 angle)
+{
+	SetByExtentsY(radius, height);
+	b2Transform xf;
+	xf.position = center;
+	xf.R.Set(angle);
+	
+	m_vertices[0] = b2Mul(xf, m_vertices[0]);
+	m_vertices[1] = b2Mul(xf, m_vertices[1]);
+}
+
+b2Shape* b2CapsuleShape::Clone(b2BlockAllocator* allocator) const
+{
+	void* mem = allocator->Allocate(sizeof(b2CapsuleShape));
+	b2CapsuleShape* clone = new (mem) b2CapsuleShape;
+	*clone = *this;
+	return clone;
+}
+
+bool b2CapsuleShape::TestPoint(const b2Transform& transform, const b2Vec2& p) const
+{
+	b2Vec2 local = b2MulT(transform, p);
+	b2Vec2 d = b2NearestPointOnLine(local, m_vertices[0], m_vertices[1]) - local;
+	return (d.LengthSquared() <= m_radius * m_radius);
+}
+
+bool b2CapsuleShape::RayCast(b2RayCastOutput* output, const b2RayCastInput& input, const b2Transform& transform) const
+{
+	// Test for starting inside first significantly reduces complexity
+	if (TestPoint(transform, input.p1)) {
+	    return false;
+	}
+	
+	// Project capsule to world
+	b2Vec2 capsule[2];
+	capsule[0] = b2Mul(transform, m_vertices[0]);
+	capsule[1] = b2Mul(transform, m_vertices[1]);
+	b2Vec2 d = capsule[1] - capsule[0];
+	
+	// Consider "cylinder"
+	
+	// Figure out signed distance from p1 to infinite capsule line
+	float32 ld = b2Cross(d, capsule[0] - input.p1);
+	
+	// Only bother if we don't start inside the infinite "cylinder"
+	if (!(ld * ld <= m_radius * m_radius * d.LengthSquared())) {
+		
+		// Find a perpendicular vector to the intersect, with length equal to radius
+		b2Vec2 perp = b2Cross(d, m_radius / d.Length());
+		
+		// Push the capsule segment by that vector
+		// Must swap if coming from the other side
+		b2Vec2 boundary[2];
+		if (ld < 0) {
+			boundary[0] = capsule[1] - perp;
+			boundary[1] = capsule[0] - perp;
+		}
+		else {
+			boundary[0] = capsule[0] + perp;
+			boundary[1] = capsule[1] + perp;
+		}
+		
+		// Check intersection against the adjusted segments.
+		if (b2RaycastSegment(output, input, boundary[0], boundary[1]))
+			return true;
+	}
+	
+	// Consider circular caps
+	
+	// Precompute some circle values
+	b2Vec2 r = input.p2 - input.p1;
+	float32 rr = r.LengthSquared();
+	
+	// Check for short segment
+	if (rr < b2_epsilon)
+	{
+		return false;
+	}
+	
+	// Check the circle caps, starting with closer
+	int startingIndex = 0;
+	if ((capsule[1] - input.p1).LengthSquared() < (capsule[0] - input.p1).LengthSquared()) {
+		startingIndex = 1;
+	}
+	b2Vec2 center = capsule[startingIndex];
+	for (int i = 0; i < 2; ++i)
+	{
+		b2Vec2 s = input.p1 - center;
+		float32 b = b2Dot(s, s) - m_radius * m_radius;
+		
+		// Should not start inside
+		b2Assert(!(b < 0.0f));
+		
+		// Solve quadratic equation.
+		float32 c =  b2Dot(s, r);
+		float32 sigma = c * c - rr * b;
+		
+		// Check for negative discriminant.
+		if (!(sigma < 0.0f))
+		{
+			// Find the point of intersection of the line with the circle.
+			float32 a = -(c + b2Sqrt(sigma));
+			
+			// Is the intersection point on the segment?
+			if (0.0f <= a && a <= input.maxFraction * rr)
+			{
+				a /= rr;
+				output->fraction = a;
+				output->normal = s + a * r;
+				output->normal.Normalize();
+				return true;
+			}
+		}
+		center = capsule[!startingIndex];
+	}
+	
+	return false;
+}
+
+void b2CapsuleShape::ComputeAABB(b2AABB* aabb, const b2Transform& transform) const
+{
+	b2Vec2 p1 = transform.position + b2Mul(transform.R, m_vertices[0]);
+	b2Vec2 p2 = transform.position + b2Mul(transform.R, m_vertices[1]);
+	b2Vec2 min = b2Min(p1, p2);
+	b2Vec2 max = b2Max(p1, p2);
+	aabb->lowerBound.Set(min.x - m_radius, min.y - m_radius);
+	aabb->upperBound.Set(max.x + m_radius, max.y + m_radius);
+}
+
+void b2CapsuleShape::ComputeMass(b2MassData* massData, float32 density) const
+{
+ 	// Area of rectangle + 2 half circles
+	float32 rectHeight = (m_vertices[1] - m_vertices[0]).Length();
+	float32 rectMass = density * rectHeight * m_radius;
+	float32 circleMass = density * b2_pi * m_radius * m_radius;
+	massData->mass = rectMass + circleMass;
+	massData->center = 0.5f * (m_vertices[0] + m_vertices[1]);
+
+	// inertia about the local origin
+	float32 rectInertia = rectMass * (rectHeight * rectHeight + m_radius * m_radius) / 12.0f;
+	float32 circleInertia = circleMass * (0.5f * m_radius * m_radius + rectHeight * rectHeight * .25f);
+	massData->I = rectInertia + circleInertia + massData->mass * massData->center.LengthSquared();
+}
Index: Box2D/Box2D/Collision/Shapes/b2CapsuleShape.h
===================================================================
--- Box2D/Box2D/Collision/Shapes/b2CapsuleShape.h	(revision 0)
+++ Box2D/Box2D/Collision/Shapes/b2CapsuleShape.h	(revision 0)
@@ -0,0 +1,103 @@
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com
+*
+* 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_CAPSULE_SHAPE_H
+#define B2_CAPSULE_SHAPE_H
+
+#include <Box2D/Collision/Shapes/b2Shape.h>
+
+/// A circle shape.
+class b2CapsuleShape : public b2Shape
+{
+public:
+	b2CapsuleShape();
+	
+	/// Set to a capsule across the X axis, with given width between focii.
+	void SetByExtentsX(float32 radius, float32 width);
+	/// Set to a capsule across the X axis, rotated and transposed.
+	void SetByExtentsX(float32 radius, float32 width,
+					    const b2Vec2& center, float32 angle);
+    
+	/// Set to a capsule across the Y axis, with given height between focii.
+	void SetByExtentsY(float32 radius, float32 height);
+	/// Set to a capsule across the Y axis, rotated and transposed.
+	void SetByExtentsY(float32 radius, float32 height,
+					    const b2Vec2& center, float32 angle);
+
+	/// Implement b2Shape.
+	b2Shape* Clone(b2BlockAllocator* allocator) const;
+
+	/// Implement b2Shape.
+	bool TestPoint(const b2Transform& transform, const b2Vec2& p) const;
+
+	/// Implement b2Shape.
+	bool RayCast(b2RayCastOutput* output, const b2RayCastInput& input, const b2Transform& transform) const;
+
+	/// @see b2Shape::ComputeAABB
+	void ComputeAABB(b2AABB* aabb, const b2Transform& transform) const;
+
+	/// @see b2Shape::ComputeMass
+	void ComputeMass(b2MassData* massData, float32 density) const;
+
+	/// Get the supporting vertex index in the given direction.
+	int32 GetSupport(const b2Vec2& d) const;
+
+	/// Get the supporting vertex in the given direction.
+	const b2Vec2& GetSupportVertex(const b2Vec2& d) const;
+
+	/// Get the vertex count.
+	int32 GetVertexCount() const { return 2; }
+
+	/// Get a vertex by index. Used by b2Distance.
+	const b2Vec2& GetVertex(int32 index) const;
+
+	/// Position of circle centers
+	b2Vec2 m_vertices[2];
+};
+
+inline b2CapsuleShape::b2CapsuleShape()
+{
+	m_type = e_capsule;
+	m_radius = 0.0f;
+	m_vertices[0].SetZero();
+	m_vertices[1].SetZero();
+}
+
+
+inline int32 b2CapsuleShape::GetSupport(const b2Vec2 &d) const
+{
+    if ((m_vertices[0] - d).LengthSquared() <= (m_vertices[1] - d).LengthSquared()) {
+        return 0;
+    }
+	return 1;
+}
+
+inline const b2Vec2& b2CapsuleShape::GetSupportVertex(const b2Vec2 &d) const
+{
+    return GetVertex(GetSupport(d));
+}
+
+inline const b2Vec2& b2CapsuleShape::GetVertex(int32 index) const
+{
+	b2Assert(index == 0 || index == 1);
+	return m_vertices[index];
+}
+
+
+
+#endif
Index: Box2D/Box2D/Collision/Shapes/b2Shape.h
===================================================================
--- Box2D/Box2D/Collision/Shapes/b2Shape.h	(revision 70)
+++ Box2D/Box2D/Collision/Shapes/b2Shape.h	(working copy)
@@ -48,7 +48,8 @@
 		e_unknown= -1,
 		e_circle = 0,
 		e_polygon = 1,
-		e_typeCount = 2,
+		e_capsule = 2,
+		e_typeCount = 3,
 	};
 
 	b2Shape() { m_type = e_unknown; }
Index: Box2D/Box2D/Dynamics/b2Fixture.cpp
===================================================================
--- Box2D/Box2D/Dynamics/b2Fixture.cpp	(revision 70)
+++ Box2D/Box2D/Dynamics/b2Fixture.cpp	(working copy)
@@ -18,6 +18,7 @@
 
 #include <Box2D/Dynamics/b2Fixture.h>
 #include <Box2D/Dynamics/Contacts/b2Contact.h>
+#include <Box2D/Collision/Shapes/b2CapsuleShape.h>
 #include <Box2D/Collision/Shapes/b2CircleShape.h>
 #include <Box2D/Collision/Shapes/b2PolygonShape.h>
 #include <Box2D/Collision/b2BroadPhase.h>
@@ -82,6 +83,14 @@
 			allocator->Free(s, sizeof(b2PolygonShape));
 		}
 		break;
+	
+	case b2Shape::e_capsule:
+	    {
+			b2CapsuleShape* s = (b2CapsuleShape*)m_shape;
+			s->~b2CapsuleShape();
+			allocator->Free(s, sizeof(b2CapsuleShape));
+	    }
+	    break;
 
 	default:
 		b2Assert(false);
Index: Box2D/Box2D/Dynamics/b2World.cpp
===================================================================
--- Box2D/Box2D/Dynamics/b2World.cpp	(revision 70)
+++ Box2D/Box2D/Dynamics/b2World.cpp	(working copy)
@@ -26,6 +26,7 @@
 #include <Box2D/Dynamics/Contacts/b2TOISolver.h>
 #include <Box2D/Collision/b2Collision.h>
 #include <Box2D/Collision/b2BroadPhase.h>
+#include <Box2D/Collision/Shapes/b2CapsuleShape.h>
 #include <Box2D/Collision/Shapes/b2CircleShape.h>
 #include <Box2D/Collision/Shapes/b2PolygonShape.h>
 #include <Box2D/Collision/b2TimeOfImpact.h>
@@ -907,6 +908,18 @@
 			m_debugDraw->DrawSolidPolygon(vertices, vertexCount, color);
 		}
 		break;
+	
+	case b2Shape::e_capsule:
+		{
+			b2CapsuleShape* capsule = (b2CapsuleShape*)fixture->GetShape();
+			
+			b2Vec2 p1 = b2Mul(xf, capsule->m_vertices[0]);
+			b2Vec2 p2 = b2Mul(xf, capsule->m_vertices[1]);
+			float32 radius = capsule->m_radius;
+
+			m_debugDraw->DrawSolidCapsule(p1, p2, radius, color);
+		}
+		break;
 	}
 }
 
Index: Box2D/Box2D/Dynamics/b2WorldCallbacks.h
===================================================================
--- Box2D/Box2D/Dynamics/b2WorldCallbacks.h	(revision 70)
+++ Box2D/Box2D/Dynamics/b2WorldCallbacks.h	(working copy)
@@ -206,6 +206,12 @@
 	/// Draw a solid circle.
 	virtual void DrawSolidCircle(const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color) = 0;
 	
+	/// Draw a capsule.
+	virtual void DrawCapsule(const b2Vec2& p1, const b2Vec2& p2, float32 radius, const b2Color& color) = 0;
+	
+	/// Draw a solid capsule.
+	virtual void DrawSolidCapsule(const b2Vec2& p1, const b2Vec2& p2, float32 radius, const b2Color& color) = 0;
+	
 	/// Draw a line segment.
 	virtual void DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color) = 0;
 
Index: Box2D/Box2D/Dynamics/Contacts/b2CapsuleAndCircleContact.cpp
===================================================================
--- Box2D/Box2D/Dynamics/Contacts/b2CapsuleAndCircleContact.cpp	(revision 0)
+++ Box2D/Box2D/Dynamics/Contacts/b2CapsuleAndCircleContact.cpp	(revision 0)
@@ -0,0 +1,63 @@
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com
+*
+* 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.
+*/
+
+#include <Box2D/Dynamics/Contacts/b2CapsuleAndCircleContact.h>
+#include <Box2D/Dynamics/b2Body.h>
+#include <Box2D/Dynamics/b2Fixture.h>
+#include <Box2D/Dynamics/b2WorldCallbacks.h>
+#include <Box2D/Common/b2BlockAllocator.h>
+#include <Box2D/Collision/b2TimeOfImpact.h>
+#include <Box2D/Collision/Shapes/b2CapsuleShape.h>
+#include <Box2D/Collision/Shapes/b2PolygonShape.h>
+
+#include <new>
+
+b2Contact* b2CapsuleAndCircleContact::Create(b2Fixture* fixtureA, b2Fixture* fixtureB, b2BlockAllocator* allocator)
+{
+	void* mem = allocator->Allocate(sizeof(b2CapsuleAndCircleContact));
+	return new (mem) b2CapsuleAndCircleContact(fixtureA, fixtureB);
+}
+
+void b2CapsuleAndCircleContact::Destroy(b2Contact* contact, b2BlockAllocator* allocator)
+{
+	((b2CapsuleAndCircleContact*)contact)->~b2CapsuleAndCircleContact();
+	allocator->Free(contact, sizeof(b2CapsuleAndCircleContact));
+}
+
+b2CapsuleAndCircleContact::b2CapsuleAndCircleContact(b2Fixture* fixtureA, b2Fixture* fixtureB)
+	: b2Contact(fixtureA, fixtureB)
+{
+	b2Assert(m_fixtureA->GetType() == b2Shape::e_capsule);
+	b2Assert(m_fixtureB->GetType() == b2Shape::e_circle);
+}
+
+void b2CapsuleAndCircleContact::Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB)
+{
+	b2Body* bodyA = m_fixtureA->GetBody();
+	b2Body* bodyB = m_fixtureB->GetBody();
+	
+	b2CapsuleShape* capsule = (b2CapsuleShape*)m_fixtureA->GetShape();
+	
+	b2PolygonShape polygon;
+	polygon.SetAsEdge(capsule->m_vertices[0], capsule->m_vertices[1]);
+	polygon.m_radius = capsule->m_radius;
+
+	b2CollidePolygonAndCircle(	manifold,
+						&polygon, xfA,
+						(b2CircleShape*)m_fixtureB->GetShape(), xfB);
+}
Index: Box2D/Box2D/Dynamics/Contacts/b2CapsuleAndCircleContact.h
===================================================================
--- Box2D/Box2D/Dynamics/Contacts/b2CapsuleAndCircleContact.h	(revision 0)
+++ Box2D/Box2D/Dynamics/Contacts/b2CapsuleAndCircleContact.h	(revision 0)
@@ -0,0 +1,38 @@
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com
+*
+* 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_CAPSULE_AND_CIRCLE_CONTACT_H
+#define B2_CAPSULE_AND_CIRCLE_CONTACT_H
+
+#include <Box2D/Dynamics/Contacts/b2Contact.h>
+
+class b2BlockAllocator;
+
+class b2CapsuleAndCircleContact : public b2Contact
+{
+public:
+	static b2Contact* Create(b2Fixture* fixtureA, b2Fixture* fixtureB, b2BlockAllocator* allocator);
+	static void Destroy(b2Contact* contact, b2BlockAllocator* allocator);
+
+	b2CapsuleAndCircleContact(b2Fixture* fixtureA, b2Fixture* fixtureB);
+	~b2CapsuleAndCircleContact() {}
+
+	void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB);
+};
+
+#endif
Index: Box2D/Box2D/Dynamics/Contacts/b2CapsuleContact.cpp
===================================================================
--- Box2D/Box2D/Dynamics/Contacts/b2CapsuleContact.cpp	(revision 0)
+++ Box2D/Box2D/Dynamics/Contacts/b2CapsuleContact.cpp	(revision 0)
@@ -0,0 +1,66 @@
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com
+*
+* 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.
+*/
+
+#include <Box2D/Dynamics/Contacts/b2CapsuleContact.h>
+#include <Box2D/Dynamics/b2Body.h>
+#include <Box2D/Dynamics/b2Fixture.h>
+#include <Box2D/Dynamics/b2WorldCallbacks.h>
+#include <Box2D/Common/b2BlockAllocator.h>
+#include <Box2D/Collision/b2TimeOfImpact.h>
+#include <Box2D/Collision/Shapes/b2CapsuleShape.h>
+#include <Box2D/Collision/Shapes/b2PolygonShape.h>
+
+#include <new>
+
+b2Contact* b2CapsuleContact::Create(b2Fixture* fixtureA, b2Fixture* fixtureB, b2BlockAllocator* allocator)
+{
+	void* mem = allocator->Allocate(sizeof(b2CapsuleContact));
+	return new (mem) b2CapsuleContact(fixtureA, fixtureB);
+}
+
+void b2CapsuleContact::Destroy(b2Contact* contact, b2BlockAllocator* allocator)
+{
+	((b2CapsuleContact*)contact)->~b2CapsuleContact();
+	allocator->Free(contact, sizeof(b2CapsuleContact));
+}
+
+b2CapsuleContact::b2CapsuleContact(b2Fixture* fixtureA, b2Fixture* fixtureB)
+	: b2Contact(fixtureA, fixtureB)
+{
+	b2Assert(m_fixtureA->GetType() == b2Shape::e_capsule);
+	b2Assert(m_fixtureB->GetType() == b2Shape::e_capsule);
+}
+
+void b2CapsuleContact::Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB)
+{
+	b2Body* bodyA = m_fixtureA->GetBody();
+	b2Body* bodyB = m_fixtureB->GetBody();
+
+	b2CapsuleShape* capsule1 = (b2CapsuleShape*)m_fixtureA->GetShape();
+	b2CapsuleShape* capsule2 = (b2CapsuleShape*)m_fixtureB->GetShape();
+	
+	b2PolygonShape polygon1, polygon2;
+	polygon1.SetAsEdge(capsule1->m_vertices[0], capsule1->m_vertices[1]);
+	polygon2.SetAsEdge(capsule2->m_vertices[0], capsule2->m_vertices[1]);
+	polygon1.m_radius = capsule1->m_radius;
+	polygon2.m_radius = capsule2->m_radius;
+
+	b2CollidePolygons(	manifold,
+						&polygon1, xfA,
+						&polygon2, xfB);
+}
Index: Box2D/Box2D/Dynamics/Contacts/b2CapsuleContact.h
===================================================================
--- Box2D/Box2D/Dynamics/Contacts/b2CapsuleContact.h	(revision 0)
+++ Box2D/Box2D/Dynamics/Contacts/b2CapsuleContact.h	(revision 0)
@@ -0,0 +1,38 @@
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com
+*
+* 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_CAPSULE_CONTACT_H
+#define B2_CAPSULE_CONTACT_H
+
+#include <Box2D/Dynamics/Contacts/b2Contact.h>
+
+class b2BlockAllocator;
+
+class b2CapsuleContact : public b2Contact
+{
+public:
+	static b2Contact* Create(b2Fixture* fixtureA, b2Fixture* fixtureB, b2BlockAllocator* allocator);
+	static void Destroy(b2Contact* contact, b2BlockAllocator* allocator);
+
+	b2CapsuleContact(b2Fixture* fixtureA, b2Fixture* fixtureB);
+	~b2CapsuleContact() {}
+
+	void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB);
+};
+
+#endif
Index: Box2D/Box2D/Dynamics/Contacts/b2Contact.cpp
===================================================================
--- Box2D/Box2D/Dynamics/Contacts/b2Contact.cpp	(revision 70)
+++ Box2D/Box2D/Dynamics/Contacts/b2Contact.cpp	(working copy)
@@ -17,7 +17,10 @@
 */
 
 #include <Box2D/Dynamics/Contacts/b2Contact.h>
+#include <Box2D/Dynamics/Contacts/b2CapsuleContact.h>
+#include <Box2D/Dynamics/Contacts/b2CapsuleAndCircleContact.h>
 #include <Box2D/Dynamics/Contacts/b2CircleContact.h>
+#include <Box2D/Dynamics/Contacts/b2PolygonAndCapsuleContact.h>
 #include <Box2D/Dynamics/Contacts/b2PolygonAndCircleContact.h>
 #include <Box2D/Dynamics/Contacts/b2PolygonContact.h>
 #include <Box2D/Dynamics/Contacts/b2ContactSolver.h>
@@ -38,6 +41,10 @@
 	AddType(b2CircleContact::Create, b2CircleContact::Destroy, b2Shape::e_circle, b2Shape::e_circle);
 	AddType(b2PolygonAndCircleContact::Create, b2PolygonAndCircleContact::Destroy, b2Shape::e_polygon, b2Shape::e_circle);
 	AddType(b2PolygonContact::Create, b2PolygonContact::Destroy, b2Shape::e_polygon, b2Shape::e_polygon);
+	
+	AddType(b2CapsuleContact::Create, b2CapsuleContact::Destroy, b2Shape::e_capsule, b2Shape::e_capsule);
+	AddType(b2CapsuleAndCircleContact::Create, b2CapsuleAndCircleContact::Destroy, b2Shape::e_capsule, b2Shape::e_circle);
+	AddType(b2PolygonAndCapsuleContact::Create, b2PolygonAndCapsuleContact::Destroy, b2Shape::e_polygon, b2Shape::e_capsule);
 }
 
 void b2Contact::AddType(b2ContactCreateFcn* createFcn, b2ContactDestroyFcn* destoryFcn,
Index: Box2D/Box2D/Dynamics/Contacts/b2PolygonAndCapsuleContact.cpp
===================================================================
--- Box2D/Box2D/Dynamics/Contacts/b2PolygonAndCapsuleContact.cpp	(revision 0)
+++ Box2D/Box2D/Dynamics/Contacts/b2PolygonAndCapsuleContact.cpp	(revision 0)
@@ -0,0 +1,63 @@
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com
+*
+* 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.
+*/
+
+#include <Box2D/Dynamics/Contacts/b2PolygonAndCapsuleContact.h>
+#include <Box2D/Dynamics/b2Body.h>
+#include <Box2D/Dynamics/b2Fixture.h>
+#include <Box2D/Dynamics/b2WorldCallbacks.h>
+#include <Box2D/Common/b2BlockAllocator.h>
+#include <Box2D/Collision/b2TimeOfImpact.h>
+#include <Box2D/Collision/Shapes/b2CapsuleShape.h>
+#include <Box2D/Collision/Shapes/b2PolygonShape.h>
+
+#include <new>
+
+b2Contact* b2PolygonAndCapsuleContact::Create(b2Fixture* fixtureA, b2Fixture* fixtureB, b2BlockAllocator* allocator)
+{
+	void* mem = allocator->Allocate(sizeof(b2PolygonAndCapsuleContact));
+	return new (mem) b2PolygonAndCapsuleContact(fixtureA, fixtureB);
+}
+
+void b2PolygonAndCapsuleContact::Destroy(b2Contact* contact, b2BlockAllocator* allocator)
+{
+	((b2PolygonAndCapsuleContact*)contact)->~b2PolygonAndCapsuleContact();
+	allocator->Free(contact, sizeof(b2PolygonAndCapsuleContact));
+}
+
+b2PolygonAndCapsuleContact::b2PolygonAndCapsuleContact(b2Fixture* fixtureA, b2Fixture* fixtureB)
+	: b2Contact(fixtureA, fixtureB)
+{
+	b2Assert(m_fixtureA->GetType() == b2Shape::e_polygon);
+	b2Assert(m_fixtureB->GetType() == b2Shape::e_capsule);
+}
+
+void b2PolygonAndCapsuleContact::Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB)
+{
+	b2Body* bodyA = m_fixtureA->GetBody();
+	b2Body* bodyB = m_fixtureB->GetBody();
+
+	b2CapsuleShape* capsule = (b2CapsuleShape*)m_fixtureB->GetShape();
+	
+	b2PolygonShape polygon;
+	polygon.SetAsEdge(capsule->m_vertices[0], capsule->m_vertices[1]);
+	polygon.m_radius = capsule->m_radius;
+
+	b2CollidePolygons(	manifold,
+						(b2PolygonShape*)m_fixtureA->GetShape(), xfA,
+						&polygon, xfB);
+}
Index: Box2D/Box2D/Dynamics/Contacts/b2PolygonAndCapsuleContact.h
===================================================================
--- Box2D/Box2D/Dynamics/Contacts/b2PolygonAndCapsuleContact.h	(revision 0)
+++ Box2D/Box2D/Dynamics/Contacts/b2PolygonAndCapsuleContact.h	(revision 0)
@@ -0,0 +1,38 @@
+/*
+* Copyright (c) 2006-2009 Erin Catto http://www.gphysics.com
+*
+* 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_POLYGON_AND_CAPSULE_CONTACT_H
+#define B2_POLYGON_AND_CAPSULE_CONTACT_H
+
+#include <Box2D/Dynamics/Contacts/b2Contact.h>
+
+class b2BlockAllocator;
+
+class b2PolygonAndCapsuleContact : public b2Contact
+{
+public:
+	static b2Contact* Create(b2Fixture* fixtureA, b2Fixture* fixtureB, b2BlockAllocator* allocator);
+	static void Destroy(b2Contact* contact, b2BlockAllocator* allocator);
+
+	b2PolygonAndCapsuleContact(b2Fixture* fixtureA, b2Fixture* fixtureB);
+	~b2PolygonAndCapsuleContact() {}
+
+	void Evaluate(b2Manifold* manifold, const b2Transform& xfA, const b2Transform& xfB);
+};
+
+#endif
Index: Box2D/Testbed/Framework/Render.cpp
===================================================================
--- Box2D/Testbed/Framework/Render.cpp	(revision 70)
+++ Box2D/Testbed/Framework/Render.cpp	(working copy)
@@ -110,6 +110,83 @@
 	glEnd();
 }
 
+void DebugDraw::DrawCapsule(const b2Vec2& p1, const b2Vec2& p2, float32 radius, const b2Color& color)
+{
+    b2Vec2 displacement = p2 - p1;
+    displacement.Normalize();
+    float32 startingAngle = atan2f(displacement.y, displacement.x) + b2_pi / 2;
+    
+	const float32 k_segments = 8.0f;
+	const float32 k_increment = b2_pi / k_segments;
+	float32 theta = startingAngle;
+	glColor3f(color.r, color.g, color.b);
+	glBegin(GL_LINE_LOOP);
+	for (int32 i = 0; i < k_segments; ++i)
+	{
+		b2Vec2 v = p1 + radius * b2Vec2(cosf(theta), sinf(theta));
+		glVertex2f(v.x, v.y);
+		theta += k_increment;
+	}
+	for (int32 i = 0; i < k_segments; ++i)
+	{
+		b2Vec2 v = p2 + radius * b2Vec2(cosf(theta), sinf(theta));
+		glVertex2f(v.x, v.y);
+		theta += k_increment;
+	}
+	glEnd();
+}
+
+void DebugDraw::DrawSolidCapsule(const b2Vec2& p1, const b2Vec2& p2, float32 radius, const b2Color& color)
+{
+    b2Vec2 displacement = p2 - p1;
+    displacement.Normalize();
+    float32 startingAngle = atan2f(displacement.y, displacement.x) + b2_pi / 2;
+    
+	const float32 k_segments = 8.0f;
+	const float32 k_increment = b2_pi / k_segments;
+	float32 theta = startingAngle;
+	glEnable(GL_BLEND);
+	glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+	glColor4f(0.5f * color.r, 0.5f * color.g, 0.5f * color.b, 0.5f);
+	glBegin(GL_TRIANGLE_FAN);
+	for (int32 i = 0; i < k_segments; ++i)
+	{
+		b2Vec2 v = p1 + radius * b2Vec2(cosf(theta), sinf(theta));
+		glVertex2f(v.x, v.y);
+		theta += k_increment;
+	}
+	for (int32 i = 0; i < k_segments; ++i)
+	{
+		b2Vec2 v = p2 + radius * b2Vec2(cosf(theta), sinf(theta));
+		glVertex2f(v.x, v.y);
+		theta += k_increment;
+	}
+	glEnd();
+	glDisable(GL_BLEND);
+	
+	theta = startingAngle;
+	glColor4f(color.r, color.g, color.b, 1.0f);
+	glBegin(GL_LINE_LOOP);
+	for (int32 i = 0; i < k_segments; ++i)
+	{
+		b2Vec2 v = p1 + radius * b2Vec2(cosf(theta), sinf(theta));
+		glVertex2f(v.x, v.y);
+		theta += k_increment;
+	}
+	for (int32 i = 0; i < k_segments; ++i)
+	{
+		b2Vec2 v = p2 + radius * b2Vec2(cosf(theta), sinf(theta));
+		glVertex2f(v.x, v.y);
+		theta += k_increment;
+	}
+	glEnd();
+    
+	glBegin(GL_LINES);
+	glVertex2f(p1.x, p1.y);
+	glVertex2f(p2.x, p2.y);
+	glEnd();
+}
+
 void DebugDraw::DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color)
 {
 	glColor3f(color.r, color.g, color.b);
Index: Box2D/Testbed/Framework/Render.h
===================================================================
--- Box2D/Testbed/Framework/Render.h	(revision 70)
+++ Box2D/Testbed/Framework/Render.h	(working copy)
@@ -36,6 +36,10 @@
 
 	void DrawSolidCircle(const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color);
 
+	void DrawCapsule(const b2Vec2& p1, const b2Vec2& p2, float32 radius, const b2Color& color);
+
+	void DrawSolidCapsule(const b2Vec2& p1, const b2Vec2& p2, float32 radius, const b2Color& color);
+	
 	void DrawSegment(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color);
 
 	void DrawTransform(const b2Transform& xf);
Index: Box2D/Testbed/Tests/PolyShapes.h
===================================================================
--- Box2D/Testbed/Tests/PolyShapes.h	(revision 70)
+++ Box2D/Testbed/Tests/PolyShapes.h	(working copy)
@@ -74,6 +74,19 @@
 				m_debugDraw->DrawPolygon(vertices, vertexCount, color);
 			}
 			break;
+
+		case b2Shape::e_capsule:
+			{
+				b2CapsuleShape* capsule = (b2CapsuleShape*)fixture->GetShape();
+
+				b2Vec2 p1 = b2Mul(xf, capsule->m_vertices[0]);
+				b2Vec2 p2 = b2Mul(xf, capsule->m_vertices[1]);
+				float32 radius = capsule->m_radius;
+
+				m_debugDraw->DrawCapsule(p1, p2, radius, color);
+			}
+			break;
+
 		}
 	}
 
@@ -163,6 +176,14 @@
 			m_circle.m_radius = 0.5f;
 		}
 
+		{
+		    m_capsules[0].SetByExtentsX(0.5f, 0.5f);
+		}
+
+		{
+		    m_capsules[1].SetByExtentsY(0.1f, 1.8f, b2Vec2(0.0f, 1.0f), 0.0f);
+		}
+		
 		m_bodyIndex = 0;
 		memset(m_bodies, 0, sizeof(m_bodies));
 	}
@@ -197,7 +218,7 @@
 			fd.friction = 0.3f;
 			m_bodies[m_bodyIndex]->CreateFixture(&fd);
 		}
-		else
+		else if (index == 4)
 		{
 			b2FixtureDef fd;
 			fd.shape = &m_circle;
@@ -206,6 +227,15 @@
 
 			m_bodies[m_bodyIndex]->CreateFixture(&fd);
 		}
+		else
+		{
+			b2FixtureDef fd;
+			fd.shape = m_capsules + (index - 5);
+			fd.density = 1.0f;
+			fd.friction = 0.3f;
+ 
+			m_bodies[m_bodyIndex]->CreateFixture(&fd);
+		}
 
 		m_bodyIndex = (m_bodyIndex + 1) % k_maxBodies;
 	}
@@ -232,6 +262,8 @@
 		case '3':
 		case '4':
 		case '5':
+		case '6':
+		case '7':
 			Create(key - '1');
 			break;
 
@@ -270,7 +302,7 @@
 		b2Color color(0.4f, 0.7f, 0.8f);
 		m_debugDraw.DrawCircle(callback.m_circle.m_p, callback.m_circle.m_radius, color);
 
-		m_debugDraw.DrawString(5, m_textLine, "Press 1-5 to drop stuff");
+		m_debugDraw.DrawString(5, m_textLine, "Press 1-7 to drop stuff");
 		m_textLine += 15;
 		m_debugDraw.DrawString(5, m_textLine, "Press 'a' to (de)activate some bodies");
 		m_textLine += 15;
@@ -287,6 +319,7 @@
 	b2Body* m_bodies[k_maxBodies];
 	b2PolygonShape m_polygons[4];
 	b2CircleShape m_circle;
+	b2CapsuleShape m_capsules[2];
 };
 
 #endif
Index: Box2D/Testbed/Tests/RayCast.h
===================================================================
--- Box2D/Testbed/Tests/RayCast.h	(revision 70)
+++ Box2D/Testbed/Tests/RayCast.h	(working copy)
@@ -211,6 +211,14 @@
 			m_circle.m_radius = 0.5f;
 		}
 
+		{
+		    m_capsules[0].SetByExtentsX(0.5f, 0.5f);
+		}
+ 
+		{
+		    m_capsules[1].SetByExtentsY(0.1f, 1.8f, b2Vec2(0.0f, 1.0f), 0.0f);
+		}
+
 		m_bodyIndex = 0;
 		memset(m_bodies, 0, sizeof(m_bodies));
 
@@ -251,7 +259,7 @@
 			fd.friction = 0.3f;
 			m_bodies[m_bodyIndex]->CreateFixture(&fd);
 		}
-		else
+		else if (index == 4)
 		{
 			b2FixtureDef fd;
 			fd.shape = &m_circle;
@@ -259,6 +267,14 @@
 
 			m_bodies[m_bodyIndex]->CreateFixture(&fd);
 		}
+		else
+		{
+			b2FixtureDef fd;
+			fd.shape = m_capsules + (index - 5);
+			fd.friction = 0.3f;
+ 
+			m_bodies[m_bodyIndex]->CreateFixture(&fd);
+		}
 
 		m_bodyIndex = (m_bodyIndex + 1) % e_maxBodies;
 	}
@@ -285,6 +301,8 @@
 		case '3':
 		case '4':
 		case '5':
+		case '6':
+		case '7':
 			Create(key - '1');
 			break;
 
@@ -311,7 +329,7 @@
 	void Step(Settings* settings)
 	{
 		Test::Step(settings);
-		m_debugDraw.DrawString(5, m_textLine, "Press 1-5 to drop stuff, m to change the mode");
+		m_debugDraw.DrawString(5, m_textLine, "Press 1-7 to drop stuff, m to change the mode");
 		m_textLine += 15;
 		m_debugDraw.DrawString(5, m_textLine, "Mode = %d", m_mode);
 		m_textLine += 15;
@@ -385,6 +403,7 @@
 	int32 m_userData[e_maxBodies];
 	b2PolygonShape m_polygons[4];
 	b2CircleShape m_circle;
+	b2CapsuleShape m_capsules[2];
 
 	float32 m_angle;
 
