Skip to content

Commit

Permalink
api cleanup and documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
erincatto committed Dec 27, 2023
1 parent 4edf0a5 commit 7c001c6
Show file tree
Hide file tree
Showing 50 changed files with 1,027 additions and 1,189 deletions.
7 changes: 6 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
cmake_minimum_required(VERSION 3.23)
include(FetchContent)

project(box2d VERSION 3.0.0 LANGUAGES C CXX)
project(box2d
VERSION 3.0.0
DESCRIPTION "A 2D physics engine for games"
HOMEPAGE_URL "box2d.org"
LANGUAGES C CXX
)

# stuff to help debug cmake
# message(STATUS "cmake source dir: ${CMAKE_SOURCE_DIR}")
Expand Down
2 changes: 2 additions & 0 deletions docs/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ set(DOXYGEN_FULL_SIDEBAR NO)
# this tells doxygen to label structs as structs intead of classes
set(DOXYGEN_OPTIMIZE_OUTPUT_FOR_C YES)

set(DOXYGEN_WARN_IF_INCOMPLETE_DOC NO)

doxygen_add_docs(doc
"${CMAKE_SOURCE_DIR}/include/box2d"
"overview.md"
Expand Down
2 changes: 2 additions & 0 deletions docs/dynamics.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ Bodies have position and velocity. You can apply forces, torques, and
impulses to bodies. Bodies can be static, kinematic, or dynamic. Here
are the body type definitions:

### Body types

#### b2_staticBody
A static body does not move under simulation and behaves as if it has
infinite mass. Internally, Box2D stores zero for the mass and the
Expand Down
240 changes: 195 additions & 45 deletions include/box2d/box2d.h

Large diffs are not rendered by default.

26 changes: 11 additions & 15 deletions include/box2d/callbacks.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,33 +9,29 @@

typedef struct b2Manifold b2Manifold;

/// Implement this class to provide collision filtering. In other words, you can implement
/// this class if you want finer control over contact creation.
/// Return true if contact calculations should be performed between these two shapes.
/// @warning for performance reasons this is only called when the AABBs begin to overlap.
typedef bool b2ShouldCollideFcn(b2ShapeId shapeIdA, b2ShapeId shapeIdB, void* context);

/// Prototype for a pre-solve callback.
/// This is called after a contact is updated. This allows you to inspect a
/// contact before it goes to the solver. If you are careful, you can modify the
/// contact manifold (e.g. disable contact).
/// Notes:
/// - this is called only for awake bodies.
/// - this is called even when the number of contact points is zero.
/// - this is not called for sensors.
/// - if you set the number of contact points to zero, you will not
/// get an EndContact callback. However, you may get a BeginContact callback
/// the next step.
/// - the supplied manifold has impulse values from the previous frame
/// - this function must be thread-safe
/// - this is only called if the shape has enabled presolve events
/// - this is called only for awake dynamic bodies
/// - this is not called for sensors
/// - the supplied manifold has impulse values from the previous step
/// Return false if you want to disable the contact this step
typedef bool b2PreSolveFcn(b2ShapeId shapeIdA, b2ShapeId shapeIdB, b2Manifold* manifold, int32_t color, void* context);

/// Register the pre-solve callback. This is optional.
BOX2D_API void b2World_SetPreSolveCallback(b2WorldId worldId, b2PreSolveFcn* fcn, void* context);

/// Callback class for AABB queries.
/// Prototype callback for AABB queries.
/// See b2World_Query
/// Called for each shape found in the query AABB.
/// @return false to terminate the query.
typedef bool b2QueryResultFcn(b2ShapeId shapeId, void* context);

/// Callback class for ray casts.
/// Prototype callback for ray casts.
/// See b2World::RayCast
/// Called for each shape found in the query. You control how the ray cast
/// proceeds by returning a float:
Expand Down
11 changes: 2 additions & 9 deletions include/box2d/color.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ typedef struct b2Color
float r, g, b, a;
} b2Color;

/// All the colors! Credit to wherever I got this from, I forget.
typedef enum b2HexColor
{
b2_colorAliceBlue = 0xf0f8ff,
Expand Down Expand Up @@ -579,11 +580,7 @@ typedef enum b2HexColor
b2_colorYellowGreen = 0x9acd32,
} b2HexColor;

#ifdef __cplusplus
extern "C"
{
#endif

/// Make a color from a hex code
static inline b2Color b2MakeColor(enum b2HexColor hexCode, float alpha)
{
b2Color color;
Expand All @@ -593,7 +590,3 @@ static inline b2Color b2MakeColor(enum b2HexColor hexCode, float alpha)
color.a = alpha;
return color;
}

#ifdef __cplusplus
}
#endif
4 changes: 4 additions & 0 deletions include/box2d/constants.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
/// degrees are indicated.
/// Some values can be overridden by using a compiler definition.
/// Other values cannot be modified without causing stability and/or performance problems.
/// Although most of these are not user configurable, it can be interesting for a user to see
/// these to understand the tuning values Box2D uses.

// todo move constraint hertz/damping here

#include "user_constants.h"

Expand Down
1 change: 1 addition & 0 deletions include/box2d/distance.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ typedef struct b2TOIInput
float tMax;
} b2TOIInput;

/// Describes the TOI output
typedef enum b2TOIState
{
b2_toiStateUnknown,
Expand Down
14 changes: 5 additions & 9 deletions include/box2d/dynamic_tree.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#define b2_defaultCategoryBits (0x00000001)
#define b2_defaultMaskBits (0xFFFFFFFF)

/// A node in the dynamic tree. The client does not interact with this directly.
/// A node in the dynamic tree. The user does not interact with this directly.
/// 16 + 16 + 8 + pad(8)
typedef struct b2TreeNode
{
Expand All @@ -28,7 +28,7 @@ typedef struct b2TreeNode
int32_t child1; // 4
int32_t child2; // 4

// TODO_ERIN could be union with child index
// todo could be union with child index
int32_t userData; // 4

// leaf = 0, free node = -1
Expand Down Expand Up @@ -158,19 +158,15 @@ BOX2D_API int32_t b2DynamicTree_Rebuild(b2DynamicTree* tree, bool fullBuild);
/// @param newOrigin the new origin with respect to the old origin
BOX2D_API void b2DynamicTree_ShiftOrigin(b2DynamicTree* tree, b2Vec2 newOrigin);

/// Get proxy user data.
/// @return the proxy user data or 0 if the id is invalid.
/// Get proxy user data
/// @return the proxy user data or 0 if the id is invalid
static inline int32_t b2DynamicTree_GetUserData(const b2DynamicTree* tree, int32_t proxyId)
{
return tree->nodes[proxyId].userData;
}

/// Get the AABB of a proxy
static inline b2AABB b2DynamicTree_GetAABB(const b2DynamicTree* tree, int32_t proxyId)
{
return tree->nodes[proxyId].aabb;
}

static inline uint32_t b2DynamicTree_GetCategoryBits(const b2DynamicTree* tree, int32_t proxyId)
{
return tree->nodes[proxyId].categoryBits;
}
61 changes: 51 additions & 10 deletions include/box2d/geometry.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ typedef struct b2Capsule
/// the left of each edge.
/// Polygons have a maximum number of vertices equal to b2_maxPolygonVertices.
/// In most cases you should not need many vertices for a convex polygon.
/// @warning DO NOT fill this out manually, instead use a helper function like
/// b2MakePolygon or b2MakeBox.
typedef struct b2Polygon
{
b2Vec2 vertices[b2_maxPolygonVertices];
Expand Down Expand Up @@ -80,42 +82,81 @@ typedef struct b2SmoothSegment
b2Vec2 ghost2;
} b2SmoothSegment;

/// Validate ray cast input data (NaN, etc)
BOX2D_API bool b2IsValidRay(const b2RayCastInput* input);

/// Helper functions to make convex polygons
/// Make a convex polygon from a convex hull. This will assert if the hull is not valid.
BOX2D_API b2Polygon b2MakePolygon(const b2Hull* hull, float radius);

/// Make an offset convex polygon from a convex hull. This will assert if the hull is not valid.
BOX2D_API b2Polygon b2MakeOffsetPolygon(const b2Hull* hull, float radius, b2Transform transform);

/// Make a square polygon, bypassing the need for a convex hull.
BOX2D_API b2Polygon b2MakeSquare(float h);

/// Make a box (rectangle) polygon, bypassing the need for a convex hull.
BOX2D_API b2Polygon b2MakeBox(float hx, float hy);

/// Make a rounded box, bypassing the need for a convex hull.
BOX2D_API b2Polygon b2MakeRoundedBox(float hx, float hy, float radius);

/// Make an offset box, bypassing the need for a convex hull.
BOX2D_API b2Polygon b2MakeOffsetBox(float hx, float hy, b2Vec2 center, float angle);
BOX2D_API b2Polygon b2MakeCapsule(b2Vec2 p1, b2Vec2 p2, float radius);

/// Transform a polygon. This is useful for transfering a shape from one body to another.
BOX2D_API b2Polygon b2TransformPolygon(b2Transform transform, const b2Polygon* polygon);

/// Compute mass properties
/// Compute mass properties of a circle
BOX2D_API b2MassData b2ComputeCircleMass(const b2Circle* shape, float density);

/// Compute mass properties of a capsule
BOX2D_API b2MassData b2ComputeCapsuleMass(const b2Capsule* shape, float density);

/// Compute mass properties of a polygon
BOX2D_API b2MassData b2ComputePolygonMass(const b2Polygon* shape, float density);

/// These compute the bounding box in world space
BOX2D_API b2AABB b2ComputeCircleAABB(const b2Circle* shape, b2Transform xf);
BOX2D_API b2AABB b2ComputeCapsuleAABB(const b2Capsule* shape, b2Transform xf);
BOX2D_API b2AABB b2ComputePolygonAABB(const b2Polygon* shape, b2Transform xf);
BOX2D_API b2AABB b2ComputeSegmentAABB(const b2Segment* shape, b2Transform xf);
/// Compute the bounding box of a transformed circle
BOX2D_API b2AABB b2ComputeCircleAABB(const b2Circle* shape, b2Transform transform);

/// Compute the bounding box of a transformed capsule
BOX2D_API b2AABB b2ComputeCapsuleAABB(const b2Capsule* shape, b2Transform transform);

/// Compute the bounding box of a transformed polygon
BOX2D_API b2AABB b2ComputePolygonAABB(const b2Polygon* shape, b2Transform transform);

/// Test a point in local space
/// Compute the bounding box of a transformed line segment
BOX2D_API b2AABB b2ComputeSegmentAABB(const b2Segment* shape, b2Transform transform);

/// Test a point for overlap with a circle in local space
BOX2D_API bool b2PointInCircle(b2Vec2 point, const b2Circle* shape);

/// Test a point for overlap with a capsule in local space
BOX2D_API bool b2PointInCapsule(b2Vec2 point, const b2Capsule* shape);

/// Test a point for overlap with a convex polygon in local space
BOX2D_API bool b2PointInPolygon(b2Vec2 point, const b2Polygon* shape);

// Ray cast versus shape in shape local space. Initial overlap is treated as a miss.
/// Ray cast versus circle in shape local space. Initial overlap is treated as a miss.
BOX2D_API b2RayCastOutput b2RayCastCircle(const b2RayCastInput* input, const b2Circle* shape);

/// Ray cast versus capsule in shape local space. Initial overlap is treated as a miss.
BOX2D_API b2RayCastOutput b2RayCastCapsule(const b2RayCastInput* input, const b2Capsule* shape);

/// Ray cast versus segment in shape local space. Optionally treat the segment as one-sided with hits from
/// the left side being treated as a miss.
BOX2D_API b2RayCastOutput b2RayCastSegment(const b2RayCastInput* input, const b2Segment* shape, bool oneSided);

/// Ray cast versus polygon in shape local space. Initial overlap is treated as a miss.
BOX2D_API b2RayCastOutput b2RayCastPolygon(const b2RayCastInput* input, const b2Polygon* shape);

/// Shape cast versus a circle. Initial overlap is treated as a miss.
BOX2D_API b2RayCastOutput b2ShapeCastCircle(const b2ShapeCastInput* input, const b2Circle* shape);

/// Shape cast versus a capsule. Initial overlap is treated as a miss.
BOX2D_API b2RayCastOutput b2ShapeCastCapsule(const b2ShapeCastInput* input, const b2Capsule* shape);

/// Shape cast versus a line segment. Initial overlap is treated as a miss.
BOX2D_API b2RayCastOutput b2ShapeCastSegment(const b2ShapeCastInput* input, const b2Segment* shape);

/// Shape cast versus a convex polygon. Initial overlap is treated as a miss.
BOX2D_API b2RayCastOutput b2ShapeCastPolygon(const b2ShapeCastInput* input, const b2Polygon* shape);
16 changes: 4 additions & 12 deletions include/box2d/hull.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,11 @@

#pragma once

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

#ifdef __cplusplus
extern "C"
{
#endif

/// Convex hull used for polygon collision
/// A convex hull. Used to create convex polygons.
typedef struct b2Hull
{
b2Vec2 points[b2_maxPolygonVertices];
Expand All @@ -25,14 +21,10 @@ typedef struct b2Hull
/// - less than 3 points
/// - more than b2_maxPolygonVertices points
/// This welds close points and removes collinear points.
b2Hull b2ComputeHull(const b2Vec2* points, int32_t count);
BOX2D_API b2Hull b2ComputeHull(const b2Vec2* points, int32_t count);

/// This determines if a hull is valid. Checks for:
/// - convexity
/// - collinear points
/// This is expensive and should not be called at runtime.
bool b2ValidateHull(const b2Hull* hull);

#ifdef __cplusplus
}
#endif
BOX2D_API bool b2ValidateHull(const b2Hull* hull);
15 changes: 13 additions & 2 deletions include/box2d/id.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,15 +56,26 @@ static const b2ShapeId b2_nullShapeId = {-1, -1, 0};
static const b2JointId b2_nullJointId = {-1, -1, 0};
static const b2ChainId b2_nullChainId = {-1, -1, 0};

/// Macro to determine if any id is null
#define B2_IS_NULL(id) (id.index == -1)

/// Macro to determine if any id is non-null
#define B2_NON_NULL(id) (id.index != -1)

// Compare two ids for equality. Doesn't work for b2WorldId./
// 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.
/// World identifier validation. Provides validation for up to 64K allocations.
BOX2D_API bool b2World_IsValid(b2WorldId id);

/// Body identifier validation. Provides validation for up to 64K allocations.
BOX2D_API bool b2Body_IsValid(b2BodyId id);

/// Shape identifier validation. Provides validation for up to 64K allocations.
BOX2D_API bool b2Shape_IsValid(b2ShapeId id);

/// Chain identifier validation. Provides validation for up to 64K allocations.
BOX2D_API bool b2Chain_IsValid(b2ChainId id);

/// Joint identifier validation. Provides validation for up to 64K allocations.
BOX2D_API bool b2Joint_IsValid(b2JointId id);
15 changes: 12 additions & 3 deletions include/box2d/joint_types.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ typedef struct b2DistanceJointDef

} b2DistanceJointDef;

/// Use this to initialize your joint definition
static inline b2DistanceJointDef b2DefaultDistanceJointDef(void)
{
b2DistanceJointDef def = B2_ZERO_INIT;
Expand Down Expand Up @@ -86,6 +87,7 @@ typedef struct b2MotorJointDef
float correctionFactor;
} b2MotorJointDef;

/// Use this to initialize your joint definition
static inline b2MotorJointDef b2DefaultMotorJointDef(void)
{
b2MotorJointDef def = B2_ZERO_INIT;
Expand Down Expand Up @@ -126,6 +128,7 @@ typedef struct b2MouseJointDef
float damping;
} b2MouseJointDef;

/// Use this to initialize your joint definition
static inline b2MouseJointDef b2DefaultMouseJointDef(void)
{
b2MouseJointDef def = B2_ZERO_INIT;
Expand Down Expand Up @@ -279,6 +282,9 @@ static inline b2RevoluteJointDef b2DefaultRevoluteJointDef(void)
return def;
}

/// A weld joint connect to bodies together rigidly. This constraint can be made soft to mimic
/// soft-body simulation.
/// @warning the approximate solver in Box2D cannot hold many bodies together rigidly
typedef struct b2WeldJointDef
{
/// The first attached body.
Expand All @@ -294,15 +300,18 @@ typedef struct b2WeldJointDef
b2Vec2 localAnchorB;

/// The bodyB angle minus bodyA angle in the reference state (radians).
/// This defines the zero angle for the joint limit.
float referenceAngle;

/// Stiffness expressed as hertz (oscillations per second). Use zero for maximum stiffness.
/// Linear stiffness expressed as hertz (oscillations per second). Use zero for maximum stiffness.
float linearHertz;

/// Angular stiffness as hertz (oscillations per second). Use zero for maximum stiffness.
float angularHertz;

/// Damping ratio, non-dimensional. Use 1 for critical damping.
/// Linear damping ratio, non-dimensional. Use 1 for critical damping.
float linearDampingRatio;

/// Linear damping ratio, non-dimensional. Use 1 for critical damping.
float angularDampingRatio;

/// Set this flag to true if the attached bodies should collide.
Expand Down
2 changes: 1 addition & 1 deletion include/box2d/joint_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@
BOX2D_API void b2LinearStiffness(float* stiffness, float* damping, float frequencyHertz, float dampingRatio, b2BodyId bodyA,
b2BodyId bodyB);

/// Utility to compute rotational stiffness values frequency and damping ratio
/// Utility to compute angular stiffness values from frequency and damping ratio
BOX2D_API void b2AngularStiffness(float* stiffness, float* damping, float frequencyHertz, float dampingRatio, b2BodyId bodyA,
b2BodyId bodyB);
Loading

0 comments on commit 7c001c6

Please sign in to comment.