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

Contact events and access #82

Merged
merged 11 commits into from
Dec 17, 2023
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: 6 additions & 10 deletions include/box2d/api.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,19 +30,15 @@ typedef void b2FreeFcn(void* mem);
// Return 0 to
typedef int b2AssertFcn(const char* condition, const char* fileName, int lineNumber);

#ifdef __cplusplus
extern "C"
{
#endif

/// Default allocation functions
void b2SetAllocator(b2AllocFcn* allocFcn, b2FreeFcn* freeFcn);
BOX2D_API void b2SetAllocator(b2AllocFcn* allocFcn, b2FreeFcn* freeFcn);

/// Total bytes allocated by Box2D
uint32_t b2GetByteCount(void);

extern b2AssertFcn* Box2DAssertCallback;
BOX2D_API uint32_t b2GetByteCount(void);

#ifdef __cplusplus
}
extern "C" b2AssertFcn* Box2DAssertCallback;
#else
extern b2AssertFcn* Box2DAssertCallback;
#endif

98 changes: 77 additions & 21 deletions include/box2d/box2d.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,19 @@ BOX2D_API b2BodyId b2World_CreateBody(b2WorldId worldId, const b2BodyDef* def);
/// @warning This function is locked during callbacks.
BOX2D_API void b2World_DestroyBody(b2BodyId bodyId);

/// Get sensor events for the current time step. Do not store a reference to this data.
BOX2D_API b2SensorEvents b2World_GetSensorEvents(b2WorldId worldId);
BOX2D_API b2ContactEvents b2World_GetContactEvents(b2WorldId worldId);

BOX2D_API b2BodyType b2Body_GetType(b2BodyId bodyId);
BOX2D_API void b2Body_SetType(b2BodyId bodyId, b2BodyType type);

/// Get the user data stored in a body
BOX2D_API void* b2Body_GetUserData(b2BodyId bodyId);

BOX2D_API b2Vec2 b2Body_GetPosition(b2BodyId bodyId);
BOX2D_API float b2Body_GetAngle(b2BodyId bodyId);
BOX2D_API b2Transform b2Body_GetTransform(b2BodyId bodyId);
BOX2D_API void b2Body_SetTransform(b2BodyId bodyId, b2Vec2 position, float angle);

BOX2D_API b2Vec2 b2Body_GetLocalPoint(b2BodyId bodyId, b2Vec2 globalPoint);
Expand All @@ -57,11 +68,42 @@ BOX2D_API float b2Body_GetAngularVelocity(b2BodyId bodyId);
BOX2D_API void b2Body_SetLinearVelocity(b2BodyId bodyId, b2Vec2 linearVelocity);
BOX2D_API void b2Body_SetAngularVelocity(b2BodyId bodyId, float angularVelocity);

BOX2D_API b2BodyType b2Body_GetType(b2BodyId bodyId);
BOX2D_API void b2Body_SetType(b2BodyId bodyId, b2BodyType type);

/// Get the user data stored in a body
BOX2D_API void* b2Body_GetUserData(b2BodyId bodyId);
/// 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 wakes up the body.
/// @param force the world force vector, usually in Newtons (N).
/// @param point the world position of the point of application.
/// @param wake also wake up the body
BOX2D_API void b2Body_ApplyForce(b2BodyId bodyId, b2Vec2 force, b2Vec2 point, bool wake);

/// Apply a force to the center of mass. This wakes up the body.
/// @param force the world force vector, usually in Newtons (N).
/// @param wake also wake up the body
BOX2D_API void b2Body_ApplyForceToCenter(b2BodyId bodyId, b2Vec2 force, bool wake);

/// Apply a torque. This affects the angular velocity
/// without affecting the linear velocity of the center of mass.
/// @param torque about the z-axis (out of the screen), usually in N-m.
/// @param wake also wake up the body
BOX2D_API void b2Body_ApplyTorque(b2BodyId bodyId, float torque, bool wake);

/// Apply an impulse at a point. This immediately modifies the velocity.
/// It also modifies the angular velocity if the point of application
/// is not at the center of mass. This wakes up the body.
/// @param impulse the world impulse vector, usually in N-seconds or kg-m/s.
/// @param point the world position of the point of application.
/// @param wake also wake up the body
BOX2D_API void b2Body_ApplyLinearImpulse(b2BodyId bodyId, b2Vec2 impulse, b2Vec2 point, bool wake);

/// Apply an impulse to the center of mass. This immediately modifies the velocity.
/// @param impulse the world impulse vector, usually in N-seconds or kg-m/s.
/// @param wake also wake up the body
BOX2D_API void b2Body_ApplyLinearImpulseToCenter(b2BodyId bodyId, b2Vec2 impulse, bool wake);

/// Apply an angular impulse.
/// @param impulse the angular impulse in units of kg*m*m/s
/// @param wake also wake up the body
BOX2D_API void b2Body_ApplyAngularImpulse(b2BodyId bodyId, float impulse, bool wake);

/// Get the mass of the body (kilograms)
BOX2D_API float b2Body_GetMass(b2BodyId bodyId);
Expand All @@ -78,10 +120,10 @@ BOX2D_API b2Vec2 b2Body_GetWorldCenterOfMass(b2BodyId bodyId);
/// Override the body's mass properties. Normally this is computed automatically using the
/// shape geometry and density. This information is lost if a shape is added or removed or if the
/// body type changes.
BOX2D_API void b2Body_SetMassData(b2MassData massData);
BOX2D_API void b2Body_SetMassData(b2BodyId bodyId, b2MassData massData);

/// Is this body awake?
BOX2D_API void b2Body_IsAwake(b2BodyId bodyId);
BOX2D_API bool b2Body_IsAwake(b2BodyId bodyId);

/// Wake a body from sleep. This wakes the entire island the body is touching.
BOX2D_API void b2Body_Wake(b2BodyId bodyId);
Expand All @@ -103,17 +145,43 @@ BOX2D_API b2ShapeId b2Body_CreateCapsule(b2BodyId bodyId, const b2ShapeDef* def,
BOX2D_API b2ShapeId b2Body_CreatePolygon(b2BodyId bodyId, const b2ShapeDef* def, const b2Polygon* polygon);
BOX2D_API void b2Body_DestroyShape(b2ShapeId shapeId);

BOX2D_API b2ChainId b2Body_CreateChain(b2BodyId bodyId, const b2ChainDef* def);
BOX2D_API void b2Body_DestroyChain(b2ChainId chainId);

/// Iterate over shapes on a body
BOX2D_API b2ShapeId b2Body_GetFirstShape(b2BodyId bodyId);
BOX2D_API b2ShapeId b2Body_GetNextShape(b2ShapeId shapeId);

BOX2D_API b2BodyId b2Shape_GetBody(b2ShapeId shapeId);
BOX2D_API void* b2Shape_GetUserData(b2ShapeId shapeId);
BOX2D_API bool b2Shape_TestPoint(b2ShapeId shapeId, b2Vec2 point);
BOX2D_API void b2Shape_SetFriction(b2ShapeId shapeId, float friction);
BOX2D_API void b2Shape_SetRestitution(b2ShapeId shapeId, float restitution);

BOX2D_API b2ChainId b2Body_CreateChain(b2BodyId bodyId, const b2ChainDef* def);
BOX2D_API void b2Body_DestroyChain(b2ChainId chainId);
BOX2D_API b2ShapeType b2Shape_GetType(b2ShapeId shapeId);
BOX2D_API const b2Circle* b2Shape_GetCircle(b2ShapeId shapeId);
BOX2D_API const b2Segment* b2Shape_GetSegment(b2ShapeId shapeId);
BOX2D_API const b2Polygon* b2Shape_GetSmoothSegment(b2ShapeId shapeId);
BOX2D_API const b2Capsule* b2Shape_GetCapsule(b2ShapeId shapeId);
BOX2D_API const b2Polygon* b2Shape_GetPolygon(b2ShapeId shapeId);

BOX2D_API void b2Chain_SetFriction(b2ChainId chainId, float friction);
BOX2D_API void b2Chain_SetRestitution(b2ChainId chainId, float restitution);

/// Contacts

/// Get the number of touching contacts on a body
BOX2D_API int32_t b2Body_GetContactCount(b2BodyId bodyId);

/// Get the touching contact data for a body
BOX2D_API int32_t b2Body_GetContactData(b2BodyId bodyId, b2ContactData* contactData, int32_t capacity);

/// Get the number of touching contacts on a shape. For efficiency, this may be larger than the actual number.
BOX2D_API int32_t b2Shape_GetContactCount(b2ShapeId shapeId);

/// Get the touching contact data for a shape. The provided shapeId will be either shapeIdA or shapeIdB on the contact data.
BOX2D_API int32_t b2Shape_GetContactData(b2ShapeId shapeId, b2ContactData* contactData, int32_t capacity);

/// Create a joint
BOX2D_API b2JointId b2World_CreateDistanceJoint(b2WorldId worldId, const b2DistanceJointDef* def);
BOX2D_API b2JointId b2World_CreateMouseJoint(b2WorldId worldId, const b2MouseJointDef* def);
Expand Down Expand Up @@ -180,18 +248,6 @@ BOX2D_API void b2World_CapsuleCast(b2WorldId worldId, const b2Capsule* capsule,
BOX2D_API void b2World_PolygonCast(b2WorldId worldId, const b2Polygon* polygon, b2Transform originTransform, b2Vec2 translation,
b2QueryFilter filter, b2RayResultFcn* fcn, void* context);

/// World events

/// Get sensor events for the current time step. Do not store a reference to this data.
BOX2D_API b2SensorEvents b2World_GetSensorEvents(b2WorldId worldId);

/// Id validation. These allow validation for up 64K allocations.
BOX2D_API bool b2World_IsValid(b2WorldId id);
BOX2D_API bool b2Body_IsValid(b2BodyId id);
BOX2D_API bool b2Shape_IsValid(b2ShapeId id);
BOX2D_API bool b2Chain_IsValid(b2ChainId id);
BOX2D_API bool b2Joint_IsValid(b2JointId id);

/// Advanced API for testing and special cases

/// Enable/disable sleep.
Expand Down
4 changes: 4 additions & 0 deletions include/box2d/debug_draw.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ typedef struct b2DebugDraw
bool drawJoints;
bool drawAABBs;
bool drawMass;
bool drawContacts;
bool drawGraphColors;
bool drawContactNormals;
bool drawContactImpulses;
bool drawFrictionImpulses;
void* context;
} b2DebugDraw;
36 changes: 36 additions & 0 deletions include/box2d/event_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#pragma once

#include "box2d/id.h"
#include "box2d/manifold.h"

#include <stdbool.h>
#include <stddef.h>
Expand All @@ -25,10 +26,45 @@ typedef struct b2SensorEndTouchEvent

/// Sensor events are buffered in the Box2D world and are available
/// as begin/end overlap event arrays after the time step is complete.
/// Note: these may become invalid if bodies and/or shapes are destroyed
typedef struct b2SensorEvents
{
b2SensorBeginTouchEvent* beginEvents;
b2SensorEndTouchEvent* endEvents;
int beginCount;
int endCount;
} b2SensorEvents;

/// A begin touch event is generated when two shapes begin touching.
typedef struct b2ContactBeginTouchEvent
{
b2ShapeId shapeIdA;
b2ShapeId shapeIdB;
b2Manifold manifold;
} b2ContactBeginTouchEvent;

/// An end touch event is generated when two shapes stop touching.
typedef struct b2ContactEndTouchEvent
{
b2ShapeId shapeIdA;
b2ShapeId shapeIdB;
} b2ContactEndTouchEvent;

/// Contact events are buffered in the Box2D world and are available
/// as event arrays after the time step is complete.
/// Note: these may become invalid if bodies and/or shapes are destroyed
typedef struct b2ContactEvents
{
b2ContactBeginTouchEvent* beginEvents;
b2ContactEndTouchEvent* endEvents;
int beginCount;
int endCount;
} b2ContactEvents;

/// This is the data you can access using a b2ContactId.
typedef struct b2ContactData
{
b2ShapeId shapeIdA;
b2ShapeId shapeIdB;
b2Manifold manifold;
} b2ContactData;
2 changes: 2 additions & 0 deletions include/box2d/geometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ BOX2D_API b2Polygon b2MakeRoundedBox(float hx, float hy, float radius);
BOX2D_API b2Polygon b2MakeOffsetBox(float hx, float hy, b2Vec2 center, float angle);
BOX2D_API b2Polygon b2MakeCapsule(b2Vec2 p1, b2Vec2 p2, float radius);

BOX2D_API b2Polygon b2TransformPolygon(b2Transform transform, const b2Polygon* polygon);

/// Compute mass properties
BOX2D_API b2MassData b2ComputeCircleMass(const b2Circle* shape, float density);
BOX2D_API b2MassData b2ComputeCapsuleMass(const b2Capsule* shape, float density);
Expand Down
27 changes: 25 additions & 2 deletions include/box2d/id.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@

#pragma once

#include "api.h"

#include <stdbool.h>
#include <stdint.h>

/// These ids serve as handles to internal Box2D objects. These should be considered opaque data and passed by value.
Expand Down Expand Up @@ -31,6 +34,14 @@ typedef struct b2ShapeId
uint16_t revision;
} b2ShapeId;

/// References a contact instance
typedef struct b2ContactId
{
int32_t index;
int16_t world;
uint16_t revision;
} b2ContactId;

/// References a joint instance
typedef struct b2JointId
{
Expand All @@ -39,6 +50,7 @@ typedef struct b2JointId
uint16_t revision;
} b2JointId;

/// References a chain instances
typedef struct b2ChainId
{
int32_t index;
Expand All @@ -49,8 +61,19 @@ typedef struct b2ChainId
static const b2WorldId b2_nullWorldId = {-1, 0};
static const b2BodyId b2_nullBodyId = {-1, -1, 0};
static const b2ShapeId b2_nullShapeId = {-1, -1, 0};
static const b2ContactId b2_nullContactId = {-1, -1, 0};
static const b2JointId b2_nullJointId = {-1, -1, 0};
static const b2ChainId b2_nullChainId = {-1, -1, 0};

#define B2_IS_NULL(ID) (ID.index == -1)
#define B2_NON_NULL(ID) (ID.index != -1)
#define B2_IS_NULL(id) (id.index == -1)
#define B2_NON_NULL(id) (id.index != -1)

// Compare two ids for equality. Doesn't work for b2WorldId./
#define B2_ID_EQUALS(id1, id2) (id1.index == id2.index && id1.world == id2.world && id1.revision == id2.revision)

/// Id validation. These allow validation for up 64K allocations.
BOX2D_API bool b2World_IsValid(b2WorldId id);
BOX2D_API bool b2Body_IsValid(b2BodyId id);
BOX2D_API bool b2Shape_IsValid(b2ShapeId id);
BOX2D_API bool b2Chain_IsValid(b2ChainId id);
BOX2D_API bool b2Joint_IsValid(b2JointId id);
4 changes: 1 addition & 3 deletions include/box2d/manifold.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ typedef struct b2Polygon b2Polygon;
typedef struct b2Segment b2Segment;
typedef struct b2SmoothSegment b2SmoothSegment;

#define B2_MAKE_ID(A, B) ((uint8_t)(A) << 8 | (uint8_t)(B))

/// A manifold point is a contact point belonging to a contact
/// manifold. It holds details related to the geometry and dynamics
/// of the contact points.
Expand All @@ -24,7 +22,7 @@ typedef struct b2ManifoldPoint
/// world coordinates of contact point
b2Vec2 point;

/// Body anchors used by solver
/// body anchors used by solver internally
b2Vec2 anchorA, anchorB;

/// the separation of the contact point, negative if penetrating
Expand Down
23 changes: 12 additions & 11 deletions include/box2d/math.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#pragma once

#include "api.h"
#include "types.h"

#include <math.h>
Expand All @@ -24,9 +25,6 @@ static const b2Transform b2Transform_identity = {{0.0f, 0.0f}, {0.0f, 1.0f}};
static const b2Mat22 b2Mat22_zero = {{0.0f, 0.0f}, {0.0f, 0.0f}};
static const b2Mat33 b2Mat33_zero = {{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, 0.0f}};

bool b2IsValid(float a);
bool b2IsValidVec2(b2Vec2 v);

/// Make a vector
static inline b2Vec2 b2MakeVec2(float x, float y)
{
Expand Down Expand Up @@ -167,14 +165,6 @@ static inline b2Vec2 b2Clamp(b2Vec2 v, b2Vec2 a, b2Vec2 b)
return c;
}

/// Convert this vector into a unit vector
b2Vec2 b2Normalize(b2Vec2 v);

/// This asserts of the vector is too short
b2Vec2 b2NormalizeChecked(b2Vec2 v);

b2Vec2 b2GetLengthAndNormalize(float* length, b2Vec2 v);

/// Get the length of this vector (the norm).
static inline float b2Length(b2Vec2 v)
{
Expand Down Expand Up @@ -417,3 +407,14 @@ static inline b2Vec3 b2Solve33(b2Mat33 A, b2Vec3 b)
#ifdef __cplusplus
}
#endif

BOX2D_API bool b2IsValid(float a);
BOX2D_API bool b2IsValidVec2(b2Vec2 v);

/// Convert this vector into a unit vector
BOX2D_API b2Vec2 b2Normalize(b2Vec2 v);

/// This asserts of the vector is too short
BOX2D_API b2Vec2 b2NormalizeChecked(b2Vec2 v);

BOX2D_API b2Vec2 b2GetLengthAndNormalize(float* length, b2Vec2 v);
Loading