Skip to content

Commit

Permalink
maximum linear velocity in world def
Browse files Browse the repository at this point in the history
allow fast rotation in body def
fix for wasm
  • Loading branch information
erincatto committed Aug 11, 2024
1 parent 2787f00 commit f7b1549
Show file tree
Hide file tree
Showing 11 changed files with 30 additions and 14 deletions.
7 changes: 7 additions & 0 deletions include/box2d/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,9 @@ typedef struct b2WorldDef
/// Joint bounciness. Non-dimensional.
float jointDampingRatio;

/// Maximum linear velocity. Usually meters per second.
float maximumLinearVelocity;

/// Can bodies go to sleep to improve performance
bool enableSleep;

Expand Down Expand Up @@ -202,6 +205,10 @@ typedef struct b2BodyDef
/// Triggers whenever a shape is add/removed/changed. Default is true.
bool automaticMass;

/// This allows this body to bypass rotational speed limits. Should only be used
/// for circular objects, like wheels.
bool allowFastRotation;

/// Used internally to detect a valid definition. DO NOT SET.
int32_t internalValue;
} b2BodyDef;
Expand Down
2 changes: 2 additions & 0 deletions samples/car.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,10 +55,12 @@ void Car::Spawn( b2WorldId worldId, b2Vec2 position, float scale, float hertz, f
shapeDef.friction = 1.5f;

bodyDef.position = b2Add( { -1.0f * scale, 0.35f * scale }, position );
bodyDef.allowFastRotation = true;
m_rearWheelId = b2CreateBody( worldId, &bodyDef );
b2CreateCircleShape( m_rearWheelId, &shapeDef, &circle );

bodyDef.position = b2Add( { 1.0f * scale, 0.4f * scale }, position );
bodyDef.allowFastRotation = true;
m_frontWheelId = b2CreateBody( worldId, &bodyDef );
b2CreateCircleShape( m_frontWheelId, &shapeDef, &circle );

Expand Down
4 changes: 4 additions & 0 deletions samples/sample_continuous.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ class BounceHouse : public Sample
bodyDef.linearVelocity = { 10.0f, 20.0f };
bodyDef.position = { 0.0f, 0.0f };
bodyDef.gravityScale = 0.0f;

// Circle shapes centered on the body can spin fast without risk of tunnelling.
bodyDef.allowFastRotation = m_shapeType == e_circleShape;

m_bodyId = b2CreateBody( m_worldId, &bodyDef );

b2ShapeDef shapeDef = b2DefaultShapeDef();
Expand Down
1 change: 1 addition & 0 deletions src/body.c
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,7 @@ b2BodyId b2CreateBody( b2WorldId worldId, const b2BodyDef* def )
bodySim->gravityScale = def->gravityScale;
bodySim->bodyId = bodyId;
bodySim->isBullet = def->isBullet;
bodySim->allowFastRotation = def->allowFastRotation;
bodySim->enlargeAABB = false;
bodySim->isFast = false;
bodySim->isSpeedCapped = false;
Expand Down
1 change: 1 addition & 0 deletions src/body.h
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,7 @@ typedef struct b2BodySim
bool isFast;
bool isBullet;
bool isSpeedCapped;
bool allowFastRotation;
bool enlargeAABB;
} b2BodySim;

Expand Down
19 changes: 7 additions & 12 deletions src/core.h
Original file line number Diff line number Diff line change
Expand Up @@ -61,18 +61,18 @@

#if defined( B2_COMPILER_MSVC )
#define B2_BREAKPOINT __debugbreak()
#elif defined( B2_COMPILER_GCC ) || defined( B2_COMPILER_CLANG )
#if defined( B2_CPU_X64 )
#define B2_BREAKPOINT __asm volatile( "int $0x3" )
#elif defined( B2_CPU_ARM )
#define B2_BREAKPOINT __builtin_trap()
#endif
#elif defined( B2_PLATFORM_WASM )
#define B2_BREAKPOINT \
do \
{ \
} \
while ( 0 )
#elif defined( B2_COMPILER_GCC ) || defined( B2_COMPILER_CLANG )
#if defined( B2_CPU_X64 )
#define B2_BREAKPOINT __asm volatile( "int $0x3" )
#elif defined( B2_CPU_ARM )
#define B2_BREAKPOINT __builtin_trap()
#endif
#else
#error Unknown platform
#endif
Expand Down Expand Up @@ -128,14 +128,9 @@ extern float b2_lengthUnitsPerMeter;
// Maximum number of simultaneous worlds that can be allocated
#define b2_maxWorlds 128

// The maximum translation of a body per time step. This limit is very large and is used
// to prevent numerical problems. You shouldn't need to adjust this. Meters.
// @warning modifying this can have a significant impact on stability
#define b2_maxTranslation ( 4.0f * b2_lengthUnitsPerMeter )

// The maximum rotation of a body per time step. This limit is very large and is used
// to prevent numerical problems. You shouldn't need to adjust this.
// @warning modifying this can have a significant impact on stability
// @warning increasing this to 0.5f * b2_pi or greater will break continuous collision.
#define b2_maxRotation ( 0.25f * b2_pi )

// @warning modifying this can have a significant impact on performance and stability
Expand Down
4 changes: 2 additions & 2 deletions src/solver.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ static void b2IntegrateVelocitiesTask( int startIndex, int endIndex, b2StepConte

b2Vec2 gravity = context->world->gravity;
float h = context->h;
float maxLinearSpeed = b2_maxTranslation * context->inv_dt;
float maxLinearSpeed = context->maxLinearVelocity;
float maxAngularSpeed = b2_maxRotation * context->inv_dt;
float maxLinearSpeedSquared = maxLinearSpeed * maxLinearSpeed;
float maxAngularSpeedSquared = maxAngularSpeed * maxAngularSpeed;
Expand Down Expand Up @@ -78,7 +78,7 @@ static void b2IntegrateVelocitiesTask( int startIndex, int endIndex, b2StepConte
}

// Clamp to max angular speed
if ( w * w > maxAngularSpeedSquared )
if ( w * w > maxAngularSpeedSquared && sim->allowFastRotation == false )
{
float ratio = maxAngularSpeed / b2AbsFloat( w );
w *= ratio;
Expand Down
1 change: 1 addition & 0 deletions src/solver.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,7 @@ typedef struct b2StepContext
b2Softness staticSoftness;

float restitutionThreshold;
float maxLinearVelocity;

struct b2World* world;
struct b2ConstraintGraph* graph;
Expand Down
2 changes: 2 additions & 0 deletions src/types.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ b2WorldDef b2DefaultWorldDef( void )
def.contactDampingRatio = 10.0f;
def.jointHertz = 60.0;
def.jointDampingRatio = 2.0f;
// 400 meters per second, faster than the speed of sound
def.maximumLinearVelocity = 400.0f * b2_lengthUnitsPerMeter;
def.enableSleep = true;
def.enableContinous = true;
def.internalValue = B2_SECRET_COOKIE;
Expand Down
2 changes: 2 additions & 0 deletions src/world.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ b2WorldId b2CreateWorld( const b2WorldDef* def )
world->gravity = def->gravity;
world->hitEventThreshold = def->hitEventThreshold;
world->restitutionThreshold = def->restitutionThreshold;
world->maxLinearVelocity = def->maximumLinearVelocity;
world->contactPushoutVelocity = def->contactPushoutVelocity;
world->contactHertz = def->contactHertz;
world->contactDampingRatio = def->contactDampingRatio;
Expand Down Expand Up @@ -743,6 +744,7 @@ void b2World_Step( b2WorldId worldId, float timeStep, int subStepCount )
context.jointSoftness = b2MakeSoft( jointHertz, world->jointDampingRatio, context.h );

context.restitutionThreshold = world->restitutionThreshold;
context.maxLinearVelocity = world->maxLinearVelocity;
context.enableWarmStarting = world->enableWarmStarting;

// Update contacts
Expand Down
1 change: 1 addition & 0 deletions src/world.h
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ typedef struct b2World
b2Vec2 gravity;
float hitEventThreshold;
float restitutionThreshold;
float maxLinearVelocity;
float contactPushoutVelocity;
float contactHertz;
float contactDampingRatio;
Expand Down

0 comments on commit f7b1549

Please sign in to comment.