Skip to content

Commit

Permalink
added b2Body_GetLocalPointVelocity and b2Body_GetWorldPointVelocity
Browse files Browse the repository at this point in the history
  • Loading branch information
erincatto committed Jan 20, 2025
1 parent 4ff15c5 commit 61bb03d
Show file tree
Hide file tree
Showing 3 changed files with 53 additions and 0 deletions.
6 changes: 6 additions & 0 deletions include/box2d/box2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,12 @@ B2_API void b2Body_SetLinearVelocity( b2BodyId bodyId, b2Vec2 linearVelocity );
/// Set the angular velocity of a body in radians per second
B2_API void b2Body_SetAngularVelocity( b2BodyId bodyId, float angularVelocity );

/// Get the linear velocity of a local point attached to a body. Usually in meters per second.
B2_API b2Vec2 b2Body_GetLocalPointVelocity( b2BodyId bodyId, b2Vec2 localPoint );

/// Get the linear velocity of a world point attached to a body. Usually in meters per second.
B2_API b2Vec2 b2Body_GetWorldPointVelocity( b2BodyId bodyId, b2Vec2 worldPoint );

/// Apply a force at a world point. If the force is not applied at the center of mass,
/// it will generate a torque and affect the angular velocity. This optionally wakes up the body.
/// The force is ignored if the body is not awake.
Expand Down
11 changes: 11 additions & 0 deletions samples/sample_bodies.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -553,6 +553,17 @@ class Weeble : public Sample
Sample::Step( settings );

g_draw.DrawCircle( m_explosionPosition, m_explosionRadius, b2_colorAzure );

// This shows how to get the velocity of a point on a body
b2Vec2 localPoint = { 0.0f, 2.0f };
b2Vec2 worldPoint = b2Body_GetWorldPoint( m_weebleId, localPoint );

b2Vec2 v1 = b2Body_GetLocalPointVelocity( m_weebleId, localPoint );
b2Vec2 v2 = b2Body_GetWorldPointVelocity( m_weebleId, worldPoint );

b2Vec2 offset = { 0.05f, 0.0f };
g_draw.DrawSegment( worldPoint, worldPoint + v1, b2_colorRed );
g_draw.DrawSegment( worldPoint + offset, worldPoint + v2 + offset, b2_colorGreen );
}

static Sample* Create( Settings& settings )
Expand Down
36 changes: 36 additions & 0 deletions src/body.c
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,42 @@ void b2Body_SetAngularVelocity( b2BodyId bodyId, float angularVelocity )
state->angularVelocity = angularVelocity;
}

b2Vec2 b2Body_GetLocalPointVelocity(b2BodyId bodyId, b2Vec2 localPoint)
{
b2World* world = b2GetWorld( bodyId.world0 );
b2Body* body = b2GetBodyFullId( world, bodyId );
b2BodyState* state = b2GetBodyState( world, body );
if ( state == NULL )
{
return b2Vec2_zero;
}

b2SolverSet* set = b2SolverSetArray_Get( &world->solverSets, body->setIndex );
b2BodySim* bodySim = b2BodySimArray_Get( &set->bodySims, body->localIndex );

b2Vec2 r = b2RotateVector( bodySim->transform.q, b2Sub(localPoint, bodySim->localCenter) );
b2Vec2 v = b2Add(state->linearVelocity, b2CrossSV( state->angularVelocity, r ));
return v;
}

b2Vec2 b2Body_GetWorldPointVelocity(b2BodyId bodyId, b2Vec2 worldPoint)
{
b2World* world = b2GetWorld( bodyId.world0 );
b2Body* body = b2GetBodyFullId( world, bodyId );
b2BodyState* state = b2GetBodyState( world, body );
if ( state == NULL )
{
return b2Vec2_zero;
}

b2SolverSet* set = b2SolverSetArray_Get( &world->solverSets, body->setIndex );
b2BodySim* bodySim = b2BodySimArray_Get( &set->bodySims, body->localIndex );

b2Vec2 r = b2Sub( worldPoint, bodySim->center );
b2Vec2 v = b2Add( state->linearVelocity, b2CrossSV( state->angularVelocity, r ) );
return v;
}

void b2Body_ApplyForce( b2BodyId bodyId, b2Vec2 force, b2Vec2 point, bool wake )
{
b2World* world = b2GetWorld( bodyId.world0 );
Expand Down

0 comments on commit 61bb03d

Please sign in to comment.