Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New capsule collider #804

Merged
merged 3 commits into from
Sep 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions include/box2d/box2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -467,6 +467,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 @@ -600,6 +603,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 @@ -634,6 +647,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 @@ -744,6 +744,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 @@ -763,6 +768,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 @@ -789,6 +789,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