Skip to content

Commit

Permalink
Merge offical pull request erincatto#804 (New capsule collider).
Browse files Browse the repository at this point in the history
  • Loading branch information
zero-meta committed Sep 26, 2024
2 parents adbfee6 + df7373c commit f041ac5
Show file tree
Hide file tree
Showing 17 changed files with 460 additions and 33 deletions.
16 changes: 16 additions & 0 deletions include/box2d/box2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,9 @@ B2_API b2ShapeType b2Shape_GetType( b2ShapeId shapeId );
/// Get the id of the body that a shape is attached to
B2_API b2BodyId b2Shape_GetBody( b2ShapeId shapeId );

/// Get the world that owns this shape
B2_API b2WorldId b2Shape_GetWorld( b2ShapeId shapeId );

/// Returns true If the shape is a sensor
B2_API bool b2Shape_IsSensor( b2ShapeId shapeId );

Expand Down Expand Up @@ -616,6 +619,16 @@ B2_API b2ChainId b2CreateChain( b2BodyId bodyId, const b2ChainDef* def );
/// Destroy a chain shape
B2_API void b2DestroyChain( b2ChainId chainId );

/// Get the world that owns this chain shape
B2_API b2WorldId b2Chain_GetWorld( b2ChainId chainId );

/// Get the number of segments on this chain
B2_API int b2Chain_GetSegmentCount( b2ChainId chainId );

/// Fill a user array with chain segment shape ids up to the specified capacity. Returns
/// the actual number of segments returned.
B2_API int b2Chain_GetSegments( b2ChainId chainId, b2ShapeId* segmentArray, int capacity );

/// Set the chain friction
/// @see b2ChainDef::friction
B2_API void b2Chain_SetFriction( b2ChainId chainId, float friction );
Expand Down Expand Up @@ -650,6 +663,9 @@ B2_API b2BodyId b2Joint_GetBodyA( b2JointId jointId );
/// Get body B id on a joint
B2_API b2BodyId b2Joint_GetBodyB( b2JointId jointId );

/// Get the world that owns this joint
B2_API b2WorldId b2Joint_GetWorld( b2JointId jointId );

/// Get the local anchor on bodyA
B2_API b2Vec2 b2Joint_GetLocalAnchorA( b2JointId jointId );

Expand Down
10 changes: 10 additions & 0 deletions include/box2d/collision.h
Original file line number Diff line number Diff line change
Expand Up @@ -183,15 +183,25 @@ B2_API b2Polygon b2MakePolygon( const b2Hull* hull, float radius );
B2_API b2Polygon b2MakeOffsetPolygon( const b2Hull* hull, float radius, b2Transform transform );

/// Make a square polygon, bypassing the need for a convex hull.
/// @param h the half-width
B2_API b2Polygon b2MakeSquare( float h );

/// Make a box (rectangle) polygon, bypassing the need for a convex hull.
/// @param hx the half-width
/// @param hy the half-height
B2_API b2Polygon b2MakeBox( float hx, float hy );

/// Make a rounded box, bypassing the need for a convex hull.
/// @param hx the half-width
/// @param hy the half-height
/// @param radius the radius of the rounded extension
B2_API b2Polygon b2MakeRoundedBox( float hx, float hy, float radius );

/// Make an offset box, bypassing the need for a convex hull.
/// @param hx the half-width
/// @param hy the half-height
/// @param center the local position of the center of the box
/// @param rotation the local rotation of the box
B2_API b2Polygon b2MakeOffsetBox( float hx, float hy, b2Vec2 center, b2Rot rotation );

/// Transform a polygon. This is useful for transferring a shape from one body to another.
Expand Down
2 changes: 1 addition & 1 deletion samples/sample_bodies.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -785,7 +785,7 @@ class BadBody : public Sample
b2BodyDef bodyDef = b2DefaultBodyDef();
bodyDef.type = b2_dynamicBody;
bodyDef.position = { 0.0f, 3.0f };
bodyDef.angularVelocity = 0.2f;
bodyDef.angularVelocity = 0.5f;
bodyDef.rotation = b2MakeRot( 0.25f * b2_pi );

m_badBodyId = b2CreateBody( m_worldId, &bodyDef );
Expand Down
22 changes: 13 additions & 9 deletions samples/sample_collision.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2232,6 +2232,9 @@ class Manifold : public Sample
m_smgcapCache2 = b2_emptyDistanceCache;

m_transform = b2Transform_identity;
m_transform.p.x = 1.0f;
m_transform.p.y = 0.0f;
//m_transform.q = b2MakeRot( 0.5f * b2_pi );
m_angle = 0.0f;
m_round = 0.1f;

Expand Down Expand Up @@ -2371,7 +2374,7 @@ class Manifold : public Sample
b2Vec2 increment = { 4.0f, 0.0f };

b2HexColor color1 = b2_colorAquamarine;
b2HexColor color2 = b2_colorMagenta;
b2HexColor color2 = b2_colorPaleGoldenrod;

if ( m_enableCaching == false )
{
Expand Down Expand Up @@ -2462,20 +2465,21 @@ class Manifold : public Sample

// capsule-capsule
{
b2Capsule capsule = { { -0.5f, 0.0f }, { 0.5f, 0.0 }, 0.25f };
b2Capsule capsule1 = { { -0.5f, 0.0f }, { 0.5f, 0.0 }, 0.25f };
b2Capsule capsule2 = { { 0.25f, 0.0f }, { 1.0f, 0.0 }, 0.1f };

b2Transform transform1 = { offset, b2Rot_identity };
b2Transform transform2 = { b2Add( m_transform.p, offset ), m_transform.q };

b2Manifold m = b2CollideCapsules( &capsule, transform1, &capsule, transform2 );
b2Manifold m = b2CollideCapsules( &capsule1, transform1, &capsule2, transform2 );

b2Vec2 v1 = b2TransformPoint( transform1, capsule.center1 );
b2Vec2 v2 = b2TransformPoint( transform1, capsule.center2 );
g_draw.DrawSolidCapsule( v1, v2, capsule.radius, color1 );
b2Vec2 v1 = b2TransformPoint( transform1, capsule1.center1 );
b2Vec2 v2 = b2TransformPoint( transform1, capsule1.center2 );
g_draw.DrawSolidCapsule( v1, v2, capsule1.radius, color1 );

v1 = b2TransformPoint( transform2, capsule.center1 );
v2 = b2TransformPoint( transform2, capsule.center2 );
g_draw.DrawSolidCapsule( v1, v2, capsule.radius, color2 );
v1 = b2TransformPoint( transform2, capsule2.center1 );
v2 = b2TransformPoint( transform2, capsule2.center2 );
g_draw.DrawSolidCapsule( v1, v2, capsule2.radius, color2 );

DrawManifold( &m, transform1.p, transform2.p );

Expand Down
56 changes: 56 additions & 0 deletions samples/sample_continuous.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,62 @@ class SkinnyBox : public Sample

static int sampleSkinnyBox = RegisterSample( "Continuous", "Skinny Box", SkinnyBox::Create );

class SpeculativeBug : public Sample
{
public:
explicit SpeculativeBug( Settings& settings )
: Sample( settings )
{
if ( settings.restart == false )
{
g_camera.m_center = { 1.0f, 5.0f };
g_camera.m_zoom = 25.0f * 0.25f;
}

{
b2BodyDef bodyDef = b2DefaultBodyDef();
b2BodyId groundId = b2CreateBody( m_worldId, &bodyDef );

b2Segment segment = { { -10.0f, 0.0f }, { 10.0f, 0.0f } };
b2ShapeDef shapeDef = b2DefaultShapeDef();
b2CreateSegmentShape( groundId, &shapeDef, &segment );

shapeDef.friction = 0.0f;
b2Polygon box = b2MakeOffsetBox( 0.05f, 1.0f, { 0.0f, 1.0f }, b2Rot_identity );
b2CreatePolygonShape( groundId, &shapeDef, &box );
}

b2BodyDef bodyDef = b2DefaultBodyDef();
bodyDef.type = b2_dynamicBody;
for (int i = 0; i < 2; ++i)
{
if (i == 0)
{
bodyDef.position = { -0.8f, 0.25f };
bodyDef.isAwake = false;
}
else
{
bodyDef.position = { 0.8f, 2.0f };
bodyDef.isAwake = true;
}

b2BodyId bodyId = b2CreateBody( m_worldId, &bodyDef );

b2ShapeDef shapeDef = b2DefaultShapeDef();
b2Capsule capsule = { { -0.5f, 0.0f }, { 0.5f, 0.0f }, 0.25f };
b2CreateCapsuleShape( bodyId, &shapeDef, &capsule );
}
}

static Sample* Create( Settings& settings )
{
return new SpeculativeBug( settings );
}
};

static int sampleSpeculativeBug = RegisterSample( "Continuous", "Speculative Bug", SpeculativeBug::Create );

// This sample shows ghost collisions
class GhostCollision : public Sample
{
Expand Down
16 changes: 9 additions & 7 deletions src/array.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

#include "core.h"

// Macro based dynamic arrays
// Macro generated functions for dynamic arrays
// Pros
// - type safe
// - array data debuggable (visible count and capacity)
Expand Down Expand Up @@ -46,10 +46,10 @@
// Inline array functions that need the type T to be defined
#define B2_ARRAY_INLINE( T, PREFIX ) \
/* Resize */ \
static inline void PREFIX##Array_Resize( PREFIX##Array* a, int count ) \
static inline void PREFIX##Array_Resize( PREFIX##Array* a, int count ) \
{ \
PREFIX##Array_Reserve( a, count ); \
a->count = count; \
a->count = count; \
} \
/* Get */ \
static inline T* PREFIX##Array_Get( PREFIX##Array* a, int index ) \
Expand Down Expand Up @@ -122,10 +122,12 @@
/* Create */ \
PREFIX##Array PREFIX##Array_Create( int capacity ) \
{ \
PREFIX##Array a; \
a.data = b2Alloc( capacity * sizeof( T ) ); \
a.count = 0; \
a.capacity = capacity; \
PREFIX##Array a = { 0 }; \
if ( capacity > 0 ) \
{ \
a.data = b2Alloc( capacity * sizeof( T ) ); \
a.capacity = capacity; \
} \
return a; \
} \
/* Reserve */ \
Expand Down
10 changes: 10 additions & 0 deletions src/body.c
Original file line number Diff line number Diff line change
Expand Up @@ -762,6 +762,11 @@ void b2Body_SetLinearVelocity( b2BodyId bodyId, b2Vec2 linearVelocity )
b2World* world = b2GetWorld( bodyId.world0 );
b2Body* body = b2GetBodyFullId( world, bodyId );

if ( body->type == b2_staticBody )
{
return;
}

if ( b2LengthSquared( linearVelocity ) > 0.0f )
{
b2WakeBody( world, body );
Expand All @@ -781,6 +786,11 @@ void b2Body_SetAngularVelocity( b2BodyId bodyId, float angularVelocity )
b2World* world = b2GetWorld( bodyId.world0 );
b2Body* body = b2GetBodyFullId( world, bodyId );

if (body->type == b2_staticBody || body->fixedRotation)
{
return;
}

if ( angularVelocity != 0.0f )
{
b2WakeBody( world, body );
Expand Down
2 changes: 2 additions & 0 deletions src/broad_phase.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// SPDX-FileCopyrightText: 2023 Erin Catto
// SPDX-License-Identifier: MIT

#if defined( _MSC_VER ) && !defined( _CRT_SECURE_NO_WARNINGS )
#define _CRT_SECURE_NO_WARNINGS
#endif

#include "broad_phase.h"

Expand Down
5 changes: 5 additions & 0 deletions src/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,11 @@ void b2SetAllocator( b2AllocFcn* allocFcn, b2FreeFcn* freeFcn )

void* b2Alloc( int size )
{
if (size == 0)
{
return NULL;
}

// This could cause some sharing issues, however Box2D rarely calls b2Alloc.
atomic_fetch_add_explicit( &b2_byteCount, size, memory_order_relaxed );

Expand Down
2 changes: 1 addition & 1 deletion src/distance.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ b2SegmentDistanceResult b2SegmentDistance( b2Vec2 p1, b2Vec2 q1, b2Vec2 p2, b2Ve
b2Vec2 r = b2Sub( p1, p2 );
float dd1 = b2Dot( d1, d1 );
float dd2 = b2Dot( d2, d2 );
float rd2 = b2Dot( r, d2 );
float rd1 = b2Dot( r, d1 );
float rd2 = b2Dot( r, d2 );

const float epsSqr = FLT_EPSILON * FLT_EPSILON;

Expand Down
2 changes: 2 additions & 0 deletions src/distance_joint.c
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
// SPDX-FileCopyrightText: 2023 Erin Catto
// SPDX-License-Identifier: MIT

#if defined( _MSC_VER ) && !defined( _CRT_SECURE_NO_WARNINGS )
#define _CRT_SECURE_NO_WARNINGS
#endif

#include "body.h"
#include "core.h"
Expand Down
6 changes: 6 additions & 0 deletions src/joint.c
Original file line number Diff line number Diff line change
Expand Up @@ -832,6 +832,12 @@ b2BodyId b2Joint_GetBodyB( b2JointId jointId )
return b2MakeBodyId( world, joint->edges[1].bodyId );
}

b2WorldId b2Joint_GetWorld( b2JointId jointId )
{
b2World* world = b2GetWorld( jointId.world0 );
return ( b2WorldId ){ jointId.world0 + 1, world->revision };
}

b2Vec2 b2Joint_GetLocalAnchorA( b2JointId jointId )
{
b2World* world = b2GetWorld( jointId.world0 );
Expand Down
Loading

0 comments on commit f041ac5

Please sign in to comment.