capsule88.patch
上传用户:gb3593
上传日期:2022-01-07
资源大小:3028k
文件大小:46k
- 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;
-