Box2D-0.1.0.0: upstream/include/box2d/types.h
// SPDX-FileCopyrightText: 2023 Erin Catto
// SPDX-License-Identifier: MIT
#pragma once
#include "base.h"
#include "collision.h"
#include "id.h"
#include "math_types.h"
#include <stdbool.h>
#include <stdint.h>
/// Default filter category bits.
/// @ingroup shape
#define B2_DEFAULT_CATEGORY_BITS 1
/// Default filter mask bits.
/// @ingroup shape
#define B2_DEFAULT_MASK_BITS UINT64_MAX
/// Task interface This is the prototype for a Box2D task. Your task system is expected to run this
/// callback on a worker thread, exactly once per enqueue, passing back the same taskContext pointer
/// supplied to b2EnqueueTaskCallbackFcn.
/// @ingroup world
typedef void b2TaskCallbackFcn( void* taskContext );
/// These functions can be provided to Box2D to invoke a task system. Returns a pointer to the
/// user's task object. May be nullptr. A nullptr indicates to Box2D that the work was executed
/// serially within the callback and there is no need to call b2FinishTaskCallbackFcn.
/// @ingroup world
typedef void* b2EnqueueTaskCallbackFcn( b2TaskCallbackFcn* task, void* taskContext,
void* userContext );
/// Finishes a user task object that wraps a Box2D task.
/// @ingroup world
typedef void b2FinishTaskCallbackFcn( void* userTask, void* userContext );
/// Optional friction mixing callback. This intentionally provides no context objects because this
/// is called from a worker thread.
/// @warning This function should not attempt to modify Box2D state or user application state.
/// @ingroup world
typedef float b2FrictionCallbackFcn( float frictionA, uint64_t userMaterialIdA, float frictionB,
uint64_t userMaterialIdB );
/// Optional restitution mixing callback. This intentionally provides no context objects because
/// this is called from a worker thread.
/// @warning This function should not attempt to modify Box2D state or user application state.
/// @ingroup world
typedef float b2RestitutionCallbackFcn( float restitutionA, uint64_t userMaterialIdA,
float restitutionB, uint64_t userMaterialIdB );
/// Result from b2World_CastRayClosest If there is initial overlap the fraction and normal will be
/// zero while the point is an arbitrary point in the overlap region.
/// @ingroup world
typedef struct b2RayResult
{
/// The shape hit.
b2ShapeId shapeId;
/// The point of contact, on the surface of the hit shape.
b2Pos point;
/// The unit normal vector at the point of contact.
b2Vec2 normal;
/// The fraction of the input ray.
float fraction;
/// The number of BVH nodes visited. Diagnostic.
int nodeVisits;
/// The number of BVH leaves visited. Diagnostic.
int leafVisits;
/// Did the ray hit? If false, all other data is invalid.
bool hit;
} b2RayResult;
/// Optional world capacities that can be used to avoid run-time allocations.
/// @see b2World_GetMaxCapacity
/// @ingroup world
typedef struct b2Capacity
{
/// Number of expected static shapes.
int staticShapeCount;
/// Number of expected dynamic and kinematic shapes.
int dynamicShapeCount;
/// Number of expected static bodies.
int staticBodyCount;
/// Number of expected dynamic and kinematic bodies.
int dynamicBodyCount;
/// Number of expected contacts.
int contactCount;
/// Reserve arena allocator space, used for temporary allocations.
int arenaByteCount;
} b2Capacity;
/// World definition used to create a simulation world. Must be initialized using
/// b2DefaultWorldDef().
/// @ingroup world
typedef struct b2WorldDef
{
/// Gravity vector. Box2D has no up-vector defined.
b2Vec2 gravity;
/// Restitution speed threshold, usually in m/s. Collisions above this speed have restitution
/// applied (will bounce).
float restitutionThreshold;
/// Number of iterations of the restitution solver. More iterations can lead to less box
/// spinning.
/// @see B2_MAX_RESTITUTION_ITERATIONS
int restitutionIterations;
/// Enable full contact propagation in the restitution solver. Expensive. (Experimental)
bool enableRestitutionPropagation;
/// Threshold speed for hit events. Usually meters per second.
float hitEventThreshold;
/// Contact stiffness. Cycles per second. Increasing this increases the speed of overlap
/// recovery, but can introduce jitter.
float contactHertz;
/// Contact bounciness. Non-dimensional. You can speed up overlap recovery by decreasing this
/// with the trade-off that overlap resolution becomes more energetic.
float contactDampingRatio;
/// This parameter controls how fast overlap is resolved and usually has units of meters per
/// second. This only puts a cap on the resolution speed. The resolution speed is increased by
/// increasing the hertz and/or decreasing the damping ratio.
float contactSpeed;
/// Maximum linear speed. Usually meters per second.
float maximumLinearSpeed;
/// Optional mixing callback for friction. The default uses sqrt(frictionA * frictionB).
b2FrictionCallbackFcn* frictionCallback;
/// Optional mixing callback for restitution. The default uses max(restitutionA, restitutionB).
b2RestitutionCallbackFcn* restitutionCallback;
/// Can bodies go to sleep to improve performance
bool enableSleep;
/// Enable continuous collision
bool enableContinuous;
/// Number of workers for multithreading. Box2D performs best when using performance cores and
/// accessing a single L3 cache (uniform memory). Efficiency cores and SMT provide little
/// benefit and may even harm performance. This is clamped to the range [1, B2_MAX_WORKERS]. If
/// task callbacks are provided then Box2D will use the user provided task system. If no task
/// callbacks are installed then Box2D will run single-threaded with a worker count of 1, or use
/// the internal scheduler with a worker count greater than 1.
int workerCount;
/// Function to spawn tasks
b2EnqueueTaskCallbackFcn* enqueueTask;
/// Function to finish a task
b2FinishTaskCallbackFcn* finishTask;
/// User context that is provided to enqueueTask and finishTask
void* userTaskContext;
/// User data
void* userData;
/// Optional initial capacities
b2Capacity capacity;
/// Used internally to detect a valid definition. DO NOT SET.
int internalValue;
} b2WorldDef;
/// Use this to initialize your world definition
/// @ingroup world
B2_API b2WorldDef b2DefaultWorldDef( void );
/// The body simulation type. Each body is one of these three types. The type determines how the
/// body behaves in the simulation.
/// @ingroup body
typedef enum b2BodyType
{
/// zero mass, zero velocity, may be manually moved
b2_staticBody = 0,
/// zero mass, velocity set by user, moved by solver
b2_kinematicBody = 1,
/// positive mass, velocity determined by forces, moved by solver
b2_dynamicBody = 2,
/// number of body types
b2_bodyTypeCount,
} b2BodyType;
/// Motion locks to restrict the body movement
/// @ingroup body
typedef struct b2MotionLocks
{
/// Prevent translation along the x-axis
bool linearX;
/// Prevent translation along the y-axis
bool linearY;
/// Prevent rotation around the z-axis
bool angularZ;
} b2MotionLocks;
/// A body definition holds all the data needed to construct a rigid body. You can safely re-use
/// body definitions. Shapes are added to a body after construction. Body definitions are temporary
/// objects used to bundle creation parameters. Must be initialized using b2DefaultBodyDef().
/// @ingroup body
typedef struct b2BodyDef
{
/// The body type: static, kinematic, or dynamic.
b2BodyType type;
/// The initial world position of the body. Bodies should be created with the desired position.
/// @note Creating bodies at the origin and then moving them nearly doubles the cost of body
/// creation, especially if the body is moved after shapes have been added.
b2Pos position;
/// The initial world rotation of the body. Use b2MakeRot() if you have an angle.
b2Rot rotation;
/// The initial linear velocity of the body's origin. Usually in meters per second.
b2Vec2 linearVelocity;
/// The initial angular velocity of the body. Radians per second.
float angularVelocity;
/// Linear damping is used to reduce the linear velocity. The damping parameter can be larger
/// than 1 but the damping effect becomes sensitive to the time step when the damping parameter
/// is large. Generally linear damping is undesirable because it makes objects move slowly as if
/// they are floating.
float linearDamping;
/// Angular damping is used to reduce the angular velocity. The damping parameter can be larger
/// than 1.0f but the damping effect becomes sensitive to the time step when the damping
/// parameter is large. Angular damping can be used to slow down rotating bodies.
float angularDamping;
/// Scale the gravity applied to this body. Non-dimensional.
float gravityScale;
/// Sleep speed threshold, default is 0.05 meters per second
float sleepThreshold;
/// Continuous collision safety factor. The solver only uses continuous collision if there is a
/// risk of tunneling. If the body is moving fast enough to risk tunneling then it is considered
/// a "fast body". This improves performance and prevents movement hitches. If a body moving N
/// meters risks tunneling, then the body will be considered fast if it moves more than a
/// safetyFactor times N meters over one full time step. Non-dimensional. Recommended range
/// [0.01, 0.5]. Default is 0.5 for high performance with low tunneling risk.
float safetyFactor;
/// Optional body name for debugging. Up to B2_NAME_LENGTH characters
const char* name;
/// Use this to store application specific body data.
void* userData;
/// Motion locks to restrict linear and angular movement. Caution: may lead to softer
/// constraints along the locked direction
b2MotionLocks motionLocks;
/// Set this flag to false if this body should never fall asleep.
bool enableSleep;
/// Is this body initially awake or sleeping?
bool isAwake;
/// Treat this dynamic body as a high speed object that performs continuous collision detection
/// against dynamic and kinematic bodies, but not other bullet bodies.
/// @warning Bullets should be used sparingly. They are not a solution for general
/// dynamic-versus-dynamic continuous collision. They do not guarantee accurate collision if
/// both bodies are fast moving because the bullet does a continuous check after all non-bullet
/// bodies have moved. You could get unlucky and have the bullet body end a time step very close
/// to a non-bullet body and the non-bullet body then moves over the bullet body. In continuous
/// collision, initial overlap is ignored to avoid freezing bodies in place. I do not recommend
/// using them for game projectiles if precise collision timing is needed. Instead consider
/// using a ray or shape cast. You can use a marching ray or shape cast for a projectile that
/// moves over time. If you want a fast moving projectile to collide with a fast moving target,
/// you need to consider the relative movement in your ray or shape cast. This is out of the
/// scope of Box2D. So what are good use cases for bullets? Pinball games or games with dynamic
/// containers that hold other objects. It should be a use case where it doesn't break the game
/// if there is a collision missed, but having them captured improves the quality of the game.
bool isBullet;
/// Used to disable a body. A disabled body does not move or collide.
bool isEnabled;
/// This allows this body to bypass rotational speed limits. Should only be used for circular
/// objects, like wheels.
bool allowFastRotation;
/// Enable contact recycling. True by default. Leaving this enabled improves performance but may
/// lead to ghost collisions that should be avoided on characters.
bool enableContactRecycling;
/// Used internally to detect a valid definition. DO NOT SET.
int internalValue;
} b2BodyDef;
/// Use this to initialize your body definition
/// @ingroup body
B2_API b2BodyDef b2DefaultBodyDef( void );
/// This is used to filter collision on shapes. It affects shape-vs-shape collision and
/// shape-versus-query collision (such as b2World_CastRay).
/// @ingroup shape
typedef struct b2Filter
{
/// The collision category bits. Normally you would just set one bit. The category bits should
/// represent your application object types. For example:
/// @code{.cpp}
/// enum MyCategories
/// {
/// Static = 0x00000001,
/// Dynamic = 0x00000002,
/// Debris = 0x00000004,
/// Player = 0x00000008,
/// // etc
/// };
/// @endcode
uint64_t categoryBits;
/// The collision mask bits. This states the categories that this shape would accept for
/// collision. For example, you may want your player to only collide with static objects and
/// other players.
/// @code{.c}
/// maskBits = Static | Player;
/// @endcode
uint64_t maskBits;
/// Collision groups allow a certain group of objects to never collide (negative) or always
/// collide (positive). A group index of zero has no effect. Non-zero group filtering always
/// wins against the mask bits. For example, you may want ragdolls to collide with other
/// ragdolls but you don't want ragdoll self-collision. In this case you would give each ragdoll
/// a unique negative group index and apply that group index to all shapes on the ragdoll.
int groupIndex;
} b2Filter;
/// Use this to initialize your filter
/// @ingroup shape
B2_API b2Filter b2DefaultFilter( void );
/// The query filter is used to filter collisions between queries and shapes. For example, you may
/// want a ray-cast representing a projectile to hit players and the static environment but not
/// debris.
/// @ingroup shape
typedef struct b2QueryFilter
{
/// The collision category bits of this query. Normally you would just set one bit.
uint64_t categoryBits;
/// The collision mask bits. This states the shape categories that this query would accept for
/// collision.
uint64_t maskBits;
} b2QueryFilter;
/// Use this to initialize your query filter
/// @ingroup shape
B2_API b2QueryFilter b2DefaultQueryFilter( void );
/// Shape type
/// @ingroup shape
typedef enum b2ShapeType
{
/// A circle with an offset
b2_circleShape,
/// A capsule is an extruded circle
b2_capsuleShape,
/// A line segment
b2_segmentShape,
/// A convex polygon
b2_polygonShape,
/// A line segment owned by a chain shape
b2_chainSegmentShape,
/// The number of shape types
b2_shapeTypeCount
} b2ShapeType;
/// The surface material groups together parameters related to the shape surface, which is the 2D
/// boundary. Surface materials allow chain shapes to have per segment properties.
/// @ingroup shape
typedef struct b2SurfaceMaterial
{
/// The Coulomb (dry) friction coefficient, usually in the range [0,1].
float friction;
/// The coefficient of restitution (bounce) usually in the range [0,1].
/// https://en.wikipedia.org/wiki/Coefficient_of_restitution
float restitution;
/// The rolling resistance usually in the range [0,1].
float rollingResistance;
/// The tangent speed for conveyor belts
float tangentSpeed;
/// User material identifier. This is passed with query results and to friction and restitution
/// combining functions. It is not used internally.
uint64_t userMaterialId;
/// Custom debug draw color.
uint32_t customColor;
} b2SurfaceMaterial;
/// Use this to initialize your surface material
/// @ingroup shape
B2_API b2SurfaceMaterial b2DefaultSurfaceMaterial( void );
/// Used to create a shape. This is a temporary object used to bundle shape creation parameters. You
/// may use the same shape definition to create multiple shapes. Must be initialized using
/// b2DefaultShapeDef().
/// @ingroup shape
typedef struct b2ShapeDef
{
/// Use this to store application specific shape data.
void* userData;
/// The surface material for this shape.
b2SurfaceMaterial material;
/// The density, usually in kg/m^2. This is not part of the surface material because this is for
/// the interior, which may have other considerations, such as being hollow. For example a wood
/// barrel may be hollow or full of water.
float density;
/// Collision filtering data.
b2Filter filter;
/// Enable custom filtering. Only one of the two shapes needs to enable custom filtering. See
/// b2World_SetCustomFilterCallback.
bool enableCustomFiltering;
/// A sensor shape generates overlap events but never generates a collision response. Fast
/// moving sensors may miss overlaps. Instead, use a ray or shape cast for those scenarios.
/// Sensors still contribute to the body mass if they have non-zero density.
/// @note Sensor events are disabled by default.
/// @see enableSensorEvents
bool isSensor;
/// Enable sensor events for this shape. This applies to sensors and non-sensors. Both shapes
/// involved must have this flag set to true. False by default, even for sensors.
bool enableSensorEvents;
/// Enable contact events for this shape. Only applies to kinematic and dynamic bodies. Only one
/// shape involved needs this flag set to true. Ignored for sensors. False by default.
bool enableContactEvents;
/// Enable hit events for this shape. Only applies to kinematic and dynamic bodies. Only one
/// shape involved needs this flag set to true. Ignored for sensors. False by default.
bool enableHitEvents;
/// Enable pre-solve contact events for this shape. Only applies to dynamic bodies. These are
/// expensive and must be carefully handled due to multithreading. Ignored for sensors.
bool enablePreSolveEvents;
/// When shapes are created they will scan the environment for collision the next time step.
/// This can significantly slow down static body creation when there are many static shapes.
/// This flag is ignored for dynamic and kinematic shapes which always invoke contact creation.
bool invokeContactCreation;
/// Should the body update the mass properties when this shape is created. Default is true.
/// Warning: if this is false, you MUST call b2Body_UpdateMassFromShapes or b2Body_SetMassData
/// before simulating the world.
bool updateBodyMass;
/// Used internally to detect a valid definition. DO NOT SET.
int internalValue;
} b2ShapeDef;
/// Use this to initialize your shape definition
/// @ingroup shape
B2_API b2ShapeDef b2DefaultShapeDef( void );
/// Used to create a chain of line segments. This is designed to eliminate ghost collisions with
/// some limitations.
/// - chains are one-sided
/// - chains have no mass and should be used on static bodies
/// - chains have a counter-clockwise winding order (normal points right of segment direction)
/// - chains are either a loop or open
/// - the distance between any two points must be greater than B2_LINEAR_SLOP
/// - a chain shape should not self intersect (this is not validated)
/// - an open chain shape needs a leading and trailing ghost point.
/// - you may overlap two open chains using the ghost points to get smooth collision.
/// - a chain shape creates multiple line segment shapes on the body
/// https://en.wikipedia.org/wiki/Polygonal_chain
/// Must be initialized using b2DefaultChainDef().
/// @warning Do not use chain shapes unless you understand the limitations. This is an advanced
/// feature.
/// @ingroup chain
typedef struct b2ChainDef
{
/// Use this to store application specific shape data.
void* userData;
/// Array of chain points. Each consecutive pair forms a segment. For a loop the last and first
/// point form a segment. Cloned.
const b2Vec2* points;
/// The point count. At least 2 for an open chain and at least 3 for a loop.
/// segmentCount = isLoop ? pointCount : pointCount - 1
int pointCount;
/// Leading ghost point for an open chain. Distance from first point must be greater than
/// B2_LINEAR_SLOP. Ignored for loops.
b2Vec2 ghost1;
/// Ending ghost point for an open chain. Distance from last point must be greater than
/// B2_LINEAR_SLOP. Ignored for loops.
b2Vec2 ghost2;
/// One material for the whole chain or one for each segment. Cloned.
const b2SurfaceMaterial* materials;
/// The material count. Must be 1 or the segment count.
int materialCount;
/// Contact filtering data.
b2Filter filter;
/// Indicates a closed chain formed by connecting the first and last point.
bool isLoop;
/// Enable sensors to detect this chain. False by default.
bool enableSensorEvents;
/// Used internally to detect a valid definition. DO NOT SET.
int internalValue;
} b2ChainDef;
/// Use this to initialize your chain definition
/// @ingroup chain
B2_API b2ChainDef b2DefaultChainDef( void );
/// Profiling data. Times are in milliseconds.
/// @ingroup world
typedef struct b2Profile
{
float step; ///<
float pairs; ///<
float collide; ///<
float solve; ///<
float solverSetup; ///<
float constraints; ///<
float prepareConstraints; ///<
float integrateVelocities; ///<
float warmStart; ///<
float solveImpulses; ///<
float integratePositions; ///<
float relaxImpulses; ///<
float restitution; ///<
float storeImpulses; ///<
float splitIslands; ///<
float transforms; ///<
float sensorHits; ///<
float jointEvents; ///<
float hitEvents; ///<
float refit; ///<
float bullets; ///<
float sleepIslands; ///<
float sensors; ///<
} b2Profile;
/// Counters that give details of the simulation size.
/// @ingroup world
typedef struct b2Counters
{
size_t byteCount; ///<
int bodyCount; ///<
int shapeCount; ///<
int contactCount; ///<
int jointCount; ///<
int islandCount; ///<
int stackUsed; ///<
int staticTreeHeight; ///<
int treeHeight; ///<
int taskCount; ///<
int colorCounts[24]; ///<
/// Number of contacts touched by the collide pass (graph contacts + awake-set non-touching).
int awakeContactCount;
/// Number of contacts recycled in the most recent step.
int recycledContactCount;
} b2Counters;
/// Joint type enumeration
///
/// This is useful because all joint types use b2JointId and sometimes you want to get the type of a
/// joint.
/// @ingroup joint
typedef enum b2JointType
{
b2_distanceJoint, ///< constrain the distance between two points
b2_filterJoint, ///< filter collision between two bodies
b2_motorJoint, ///< fully control the movement of a body
b2_moverJoint, ///< control the movement of the dynamic character mover
b2_pogoJoint, ///< ground interaction for the dynamic character mover
b2_prismaticJoint, ///< slide along an axis
b2_revoluteJoint, ///< rotate around a pivot
b2_weldJoint, ///< bring two bodies together with some flex
b2_wheelJoint, ///< wheel spins with shock absorber
} b2JointType;
/// Base joint definition used by all joint types. The local frames are measured from the body's
/// origin rather than the center of mass because:
/// 1. you might not know where the center of mass will be.
/// 2. if you add/remove shapes from a body and recompute the mass, the joints will be broken.
/// @ingroup joint
typedef struct b2JointDef
{
/// User data pointer
void* userData;
/// The first attached body
b2BodyId bodyIdA;
/// The second attached body
b2BodyId bodyIdB;
/// The first local joint frame
b2Transform localFrameA;
/// The second local joint frame
b2Transform localFrameB;
/// Force threshold for joint events
float forceThreshold;
/// Torque threshold for joint events
float torqueThreshold;
/// Constraint hertz (advanced feature)
float constraintHertz;
/// Constraint damping ratio (advanced feature)
float constraintDampingRatio;
/// Debug draw scale
float drawScale;
/// Set this flag to true if the attached bodies should collide
bool collideConnected;
} b2JointDef;
/// Distance joint definition Connects a point on body A with a point on body B by a segment. Useful
/// for ropes and springs.
/// @ingroup distance_joint
typedef struct b2DistanceJointDef
{
/// Base joint definition
b2JointDef base;
/// The rest length of this joint. Clamped to a stable minimum value.
float length;
/// Enable the distance constraint to behave like a spring. If false then the distance joint
/// will be rigid, overriding the limit and motor.
bool enableSpring;
/// The lower spring force controls how much tension it can sustain.
float lowerSpringForce;
/// The upper spring force controls how much compression it can sustain.
float upperSpringForce;
/// The spring linear stiffness Hertz, cycles per second.
float hertz;
/// The spring linear damping ratio, non-dimensional
float dampingRatio;
/// Enable/disable the joint limit
bool enableLimit;
/// Minimum length for limit. Clamped to a stable minimum value.
float minLength;
/// Maximum length for limit. Must be greater than or equal to the minimum length.
float maxLength;
/// Enable/disable the joint motor
bool enableMotor;
/// The maximum motor force, usually in newtons
float maxMotorForce;
/// The desired motor speed, usually in meters per second
float motorSpeed;
/// Used internally to detect a valid definition. DO NOT SET.
int internalValue;
} b2DistanceJointDef;
/// Use this to initialize your joint definition
/// @ingroup distance_joint
B2_API b2DistanceJointDef b2DefaultDistanceJointDef( void );
/// A filter joint is used to disable collision between two specific bodies.
///
/// @ingroup filter_joint
typedef struct b2FilterJointDef
{
/// Base joint definition
b2JointDef base;
/// Used internally to detect a valid definition. DO NOT SET.
int internalValue;
} b2FilterJointDef;
/// Use this to initialize your joint definition
/// @ingroup filter_joint
B2_API b2FilterJointDef b2DefaultFilterJointDef( void );
/// A motor joint is used to control the relative velocity and/or transform between two bodies. With
/// a velocity of zero this acts like top-down friction.
/// @ingroup motor_joint
typedef struct b2MotorJointDef
{
/// Base joint definition
b2JointDef base;
/// The desired linear velocity
b2Vec2 linearVelocity;
/// The maximum motor force in newtons
float maxVelocityForce;
/// The desired angular velocity
float angularVelocity;
/// The maximum motor torque in newton-meters
float maxVelocityTorque;
/// Linear spring hertz for position control
float linearHertz;
/// Linear spring damping ratio
float linearDampingRatio;
/// Maximum spring force in newtons
float maxSpringForce;
/// Angular spring hertz for position control
float angularHertz;
/// Angular spring damping ratio
float angularDampingRatio;
/// Maximum spring torque in newton-meters
float maxSpringTorque;
/// Used internally to detect a valid definition. DO NOT SET.
int internalValue;
} b2MotorJointDef;
/// Use this to initialize your joint definition
/// @ingroup motor_joint
B2_API b2MotorJointDef b2DefaultMotorJointDef( void );
/// A mover joint is used to move a dynamic character mover through velocity commands. The x and y
/// directions are handled separately. Does not affect rotation.
/// @ingroup mover_joint
typedef struct b2MoverJointDef
{
/// Base joint definition
b2JointDef base;
/// The desired linear velocity
b2Vec2 linearVelocity;
/// The maximum motor force in newtons.
b2Vec2 maxVelocityForce;
/// Used internally to detect a valid definition. DO NOT SET.
int internalValue;
} b2MoverJointDef;
/// Use this to initialize your joint definition
/// @ingroup mover_joint
B2_API b2MoverJointDef b2DefaultMoverJointDef( void );
/// Pogo joint definition
/// @ingroup pogo_joint
typedef struct b2PogoJointDef
{
/// Base joint definition
b2JointDef base;
/// Normal vector at the contact
b2Vec2 normal;
/// The spring stiffness Hertz, cycles per second
float hertz;
/// The spring damping ratio, non-dimensional
float dampingRatio;
/// Spring length.
float restLength;
/// Maximum tension force. Controls how sticky the mover is to ground.
float maxTensionForce;
/// Maximum compression force. How hard the pogo pushes the mover up from the ground.
float maxCompressionForce;
/// The initial pogo internal impulse. The pogo is typically recreated every frame. This gives a
/// way to move the internal state forward for smoother spring behavior.
float impulse;
/// The initial pogo internal velocity. The pogo is typically recreated every frame. This gives
/// a way to move the internal state forward for smoother spring behavior.
float velocity;
/// Used internally to detect a valid definition. DO NOT SET.
int internalValue;
} b2PogoJointDef;
/// Use this to initialize your joint definition
/// @ingroup pogo_joint
B2_API b2PogoJointDef b2DefaultPogoJointDef( void );
/// Prismatic joint definition Body B may slide along the x-axis in local frame A. Body B cannot
/// rotate relative to body A. The joint translation is zero when the local frame origins coincide
/// in world space.
/// @ingroup prismatic_joint
typedef struct b2PrismaticJointDef
{
/// Base joint definition
b2JointDef base;
/// Enable a linear spring along the prismatic joint axis
bool enableSpring;
/// The spring stiffness Hertz, cycles per second
float hertz;
/// The spring damping ratio, non-dimensional
float dampingRatio;
/// The target translation for the joint in meters. The spring-damper will drive to this
/// translation.
float targetTranslation;
/// Enable/disable the joint limit
bool enableLimit;
/// The lower translation limit
float lowerTranslation;
/// The upper translation limit
float upperTranslation;
/// Enable/disable the joint motor
bool enableMotor;
/// The maximum motor force, typically in newtons
float maxMotorForce;
/// The desired motor speed, typically in meters per second
float motorSpeed;
/// Used internally to detect a valid definition. DO NOT SET.
int internalValue;
} b2PrismaticJointDef;
/// Use this to initialize your joint definition
/// @ingroup prismatic_joint
B2_API b2PrismaticJointDef b2DefaultPrismaticJointDef( void );
/// Revolute joint definition A point on body B is fixed to a point on body A. Allows relative
/// rotation.
/// @ingroup revolute_joint
typedef struct b2RevoluteJointDef
{
/// Base joint definition
b2JointDef base;
/// The target angle for the joint in radians. The spring-damper will drive to this angle.
float targetAngle;
/// Enable a rotational spring on the revolute hinge axis
bool enableSpring;
/// The spring stiffness Hertz, cycles per second
float hertz;
/// The spring damping ratio, non-dimensional
float dampingRatio;
/// A flag to enable joint limits
bool enableLimit;
/// The lower angle for the joint limit in radians. Minimum of -0.99*pi radians.
float lowerAngle;
/// The upper angle for the joint limit in radians. Maximum of 0.99*pi radians.
float upperAngle;
/// A flag to enable the joint motor
bool enableMotor;
/// The maximum motor torque, typically in newton-meters
float maxMotorTorque;
/// The desired motor speed in radians per second
float motorSpeed;
/// Used internally to detect a valid definition. DO NOT SET.
int internalValue;
} b2RevoluteJointDef;
/// Use this to initialize your joint definition.
/// @ingroup revolute_joint
B2_API b2RevoluteJointDef b2DefaultRevoluteJointDef( void );
/// Weld joint definition Connects two bodies together rigidly. This constraint provides springs to
/// mimic soft-body simulation.
/// @note The approximate solver in Box2D cannot hold many bodies together rigidly
/// @ingroup weld_joint
typedef struct b2WeldJointDef
{
/// Base joint definition
b2JointDef base;
/// Linear stiffness expressed as Hertz (cycles per second). Use zero for maximum stiffness.
float linearHertz;
/// Angular stiffness as Hertz (cycles per second). Use zero for maximum stiffness.
float angularHertz;
/// Linear damping ratio, non-dimensional. Use 1 for critical damping.
float linearDampingRatio;
/// Angular damping ratio, non-dimensional. Use 1 for critical damping.
float angularDampingRatio;
/// Used internally to detect a valid definition. DO NOT SET.
int internalValue;
} b2WeldJointDef;
/// Use this to initialize your joint definition
/// @ingroup weld_joint
B2_API b2WeldJointDef b2DefaultWeldJointDef( void );
/// Wheel joint definition Body B is a wheel that may rotate freely and slide along the local x-axis
/// in frame A. The joint translation is zero when the local frame origins coincide in world space.
/// @ingroup wheel_joint
typedef struct b2WheelJointDef
{
/// Base joint definition
b2JointDef base;
/// Enable a linear spring along the local axis
bool enableSpring;
/// Spring stiffness in Hertz
float hertz;
/// Spring damping ratio, non-dimensional
float dampingRatio;
/// Enable/disable the joint linear limit
bool enableLimit;
/// The lower translation limit
float lowerTranslation;
/// The upper translation limit
float upperTranslation;
/// Enable/disable the joint rotational motor
bool enableMotor;
/// The maximum motor torque, typically in newton-meters
float maxMotorTorque;
/// The desired motor speed in radians per second
float motorSpeed;
/// Used internally to detect a valid definition. DO NOT SET.
int internalValue;
} b2WheelJointDef;
/// Use this to initialize your joint definition
/// @ingroup wheel_joint
B2_API b2WheelJointDef b2DefaultWheelJointDef( void );
/// The explosion definition is used to configure options for explosions. Explosions consider shape
/// geometry when computing the impulse.
/// @ingroup world
typedef struct b2ExplosionDef
{
/// Mask bits to filter shapes
uint64_t maskBits;
/// The center of the explosion in world space
b2Pos position;
/// The radius of the explosion
float radius;
/// The falloff distance beyond the radius. Impulse is reduced to zero at this distance.
float falloff;
/// Impulse per unit length. This applies an impulse according to the shape perimeter that is
/// facing the explosion. Explosions only apply to circles, capsules, and polygons. This may be
/// negative for implosions.
float impulsePerLength;
} b2ExplosionDef;
/// Use this to initialize your explosion definition
/// @ingroup world
B2_API b2ExplosionDef b2DefaultExplosionDef( void );
/**
* @defgroup events Events
* World event types.
*
* Events are used to collect events that occur during the world time step. These events are then
* available to query after the time step is complete. This is preferable to callbacks because Box2D
* uses multithreaded simulation.
*
* Also when events occur in the simulation step it may be problematic to modify the world, which is
* often what applications want to do when events occur.
*
* With event arrays, you can scan the events in a loop and modify the world. However, you need to
* be careful that some event data may become invalid. There are several samples that show how to do
* this safely.
*
* @{
*/
/// A begin touch event is generated when a shape starts to overlap a sensor shape.
typedef struct b2SensorBeginTouchEvent
{
/// The id of the sensor shape
b2ShapeId sensorShapeId;
/// The id of the shape that began touching the sensor shape
b2ShapeId visitorShapeId;
} b2SensorBeginTouchEvent;
/// An end touch event is generated when a shape stops overlapping a sensor shape. Normally this
/// event is generated from simulation movement. However, this event can also be generated from API
/// interactions: setting the body transform, destroying a body or shape, or changing a filter. You
/// will also get an end event if the sensor is destroyed. Therefore you should always confirm the
/// shape id is valid using b2Shape_IsValid.
typedef struct b2SensorEndTouchEvent
{
/// The id of the sensor shape
/// @warning this shape may have been destroyed
/// @see b2Shape_IsValid
b2ShapeId sensorShapeId;
/// The id of the shape that stopped touching the sensor shape
/// @warning this shape may have been destroyed
/// @see b2Shape_IsValid
b2ShapeId visitorShapeId;
} b2SensorEndTouchEvent;
/// Sensor events are buffered in the 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
{
/// Array of sensor begin touch events
b2SensorBeginTouchEvent* beginEvents;
/// Array of sensor end touch events
b2SensorEndTouchEvent* endEvents;
/// The number of begin touch events
int beginCount;
/// The number of end touch events
int endCount;
} b2SensorEvents;
/// A begin touch event is generated when two shapes begin touching.
typedef struct b2ContactBeginTouchEvent
{
/// Id of the first shape
b2ShapeId shapeIdA;
/// Id of the second shape
b2ShapeId shapeIdB;
/// The transient contact id. This contact may be destroyed automatically when the world is
/// modified or simulated. Use b2Contact_IsValid before using this id.
b2ContactId contactId;
} b2ContactBeginTouchEvent;
/// An end touch event is generated when two shapes stop touching. You will get an end event if you
/// do anything that destroys contacts previous to the last world step. These include things like
/// setting the transform, destroying a body or shape, or changing a filter or body type.
typedef struct b2ContactEndTouchEvent
{
/// Id of the first shape
/// @warning this shape may have been destroyed
/// @see b2Shape_IsValid
b2ShapeId shapeIdA;
/// Id of the second shape
/// @warning this shape may have been destroyed
/// @see b2Shape_IsValid
b2ShapeId shapeIdB;
/// Id of the contact.
/// @warning this contact may have been destroyed
/// @see b2Contact_IsValid
b2ContactId contactId;
} b2ContactEndTouchEvent;
/// A hit event is generated when two shapes collide with a speed faster than the hit event
/// threshold. This may be reported for speculative contacts that have a confirmed impulse.
typedef struct b2ContactHitEvent
{
/// Id of the first shape
b2ShapeId shapeIdA;
/// Id of the second shape
b2ShapeId shapeIdB;
/// Id of the contact.
/// @warning this contact may have been destroyed
/// @see b2Contact_IsValid
b2ContactId contactId;
/// Point where the shapes hit. This is a mid-point between the two surfaces. It could be a
/// speculative point where the shapes were not touching at the beginning of the time step. The
/// point is reconstructed after the step, so when both bodies are moving it may trail the
/// impact by up to one step of motion.
b2Pos point;
/// Normal vector pointing from shape A to shape B
b2Vec2 normal;
/// The speed the shapes are approaching. Always positive. Typically in meters per second.
float approachSpeed;
} b2ContactHitEvent;
/// 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
{
/// Array of begin touch events
b2ContactBeginTouchEvent* beginEvents;
/// Array of end touch events
b2ContactEndTouchEvent* endEvents;
/// Array of hit events
b2ContactHitEvent* hitEvents;
/// Number of begin touch events
int beginCount;
/// Number of end touch events
int endCount;
/// Number of hit events
int hitCount;
} b2ContactEvents;
/// Body move events triggered when a body moves. Triggered when a body moves due to simulation. Not
/// reported for bodies moved by the user. This also has a flag to indicate that the body went to
/// sleep so the application can also sleep that actor/entity/object associated with the body. On
/// the other hand if the flag does not indicate the body went to sleep then the application can
/// treat the actor/entity/object associated with the body as awake. This is an efficient way for an
/// application to update game object transforms rather than calling functions such as
/// b2Body_GetTransform() because this data is delivered as a contiguous array and it is only
/// populated with bodies that have moved.
/// @note If sleeping is disabled all dynamic and kinematic bodies will trigger move events.
typedef struct b2BodyMoveEvent
{
/// The body user data.
void* userData;
/// The world transform of the body.
b2WorldTransform transform;
/// The id of the body that moved.
b2BodyId bodyId;
/// Did the body fall asleep this time step?
bool fellAsleep;
} b2BodyMoveEvent;
/// Body events are buffered in the Box2D world and are available as event arrays after the time
/// step is complete. Note: this data becomes invalid if bodies are destroyed
typedef struct b2BodyEvents
{
/// Array of move events
b2BodyMoveEvent* moveEvents;
/// Number of move events
int moveCount;
} b2BodyEvents;
/// Joint events report joints that are awake and have a force and/or torque exceeding the
/// threshold. The observed forces and torques are not returned for efficiency reasons.
typedef struct b2JointEvent
{
/// The joint id
b2JointId jointId;
/// The user data from the joint for convenience
void* userData;
} b2JointEvent;
/// Joint events are buffered in the world and are available as event arrays after the time step is
/// complete. Note: this data becomes invalid if joints are destroyed
typedef struct b2JointEvents
{
/// Array of events
b2JointEvent* jointEvents;
/// Number of events
int count;
} b2JointEvents;
/**@}*/
/// The contact data for two shapes. By convention the manifold normal points from shape A to shape
/// B.
/// @see b2Shape_GetContactData() and b2Body_GetContactData()
/// @ingroup contact
typedef struct b2ContactData
{
/// The contact id. You may hold onto this to track a contact across time steps. This id may
/// become orphaned. Use b2Contact_IsValid before using it for other functions.
b2ContactId contactId;
/// The first shape id.
b2ShapeId shapeIdA;
/// The second shape id.
b2ShapeId shapeIdB;
/// The manifold copied from the contact.
b2Manifold manifold;
} b2ContactData;
/// Prototype for a contact filter callback. This is called when a contact pair is considered for
/// collision. This allows you to perform custom logic to prevent collision between shapes. This is
/// only called if one of the two shapes has custom filtering enabled. Notes:
/// - this function must be thread-safe
/// - this is only called if one of the two shapes has enabled custom filtering
/// - this may be called for awake dynamic bodies and sensors Return false if you want to disable
/// the collision
/// @see b2ShapeDef
/// @warning Do not attempt to modify the world inside this callback
/// @ingroup world
typedef bool b2CustomFilterCallbackFcn( b2ShapeId shapeIdA, b2ShapeId shapeIdB, void* context );
/// Prototype for a pre-solve callback. This is called after a contact manifold is updated. This
/// allows you to inspect a manifold before it goes to the solver. If you are careful, you can
/// modify the manifold (e.g. modify the normal). You can set the manifold point count to zero to
/// disable collision. Notes:
/// - this function must be thread-safe
/// - this is only called if the shape has enabled pre-solve events
/// - this is called only for awake dynamic bodies
/// - this is not called for sensors
/// - the supplied manifold impulses are not reliable
/// @warning Do not attempt to modify the world inside this callback
/// @ingroup world
typedef void b2PreSolveCallbackFcn( b2ShapeId shapeIdA, b2ShapeId shapeIdB, b2Manifold* manifold,
void* context );
/// Prototype for a pre-continuous callback. This is called when a time of impact event is computed
/// in continuous collision. This function can be used to skip the event. Unlike the pre-solve
/// callback, this only supplies the point and normal. At this stage of the solver the manifold may
/// not exist or may be stale. Notes:
/// - this function must be thread-safe
/// - this is only called if the shape has enabled pre-solve events
/// - this is called only for awake dynamic bodies
/// - this is not called for sensors Return false if you want to disable the time of impact event.
/// @warning Do not attempt to modify the world inside this callback
/// @ingroup world
typedef bool b2PreContinuousCallbackFcn( b2ShapeId shapeIdA, b2ShapeId shapeIdB, b2Pos point,
b2Vec2 normal, void* context );
/// Prototype callback for overlap queries. Called for each shape found in the query.
/// @see b2World_OverlapAABB
/// @return false to terminate the query.
/// @ingroup world
typedef bool b2OverlapResultCallbackFcn( b2ShapeId shapeId, void* context );
/// Prototype callback for ray and shape casts. Called for each shape found in the query. You
/// control how the ray cast proceeds by returning a float:
/// - return -1: ignore this shape and continue
/// - return 0: terminate the ray cast
/// - return fraction: clip the ray to this point
/// - return 1: don't clip the ray and continue A cast with initial overlap will return a zero
/// fraction and a zero normal.
/// @param shapeId the shape hit by the ray
/// @param point the point of initial intersection
/// @param normal the normal vector at the point of intersection, zero for a shape cast with initial
/// overlap
/// @param fraction the fraction along the ray at the point of intersection, zero for a shape cast
/// with initial overlap
/// @param context the user context
/// @return -1 to filter, 0 to terminate, fraction to clip the ray for closest hit, 1 to continue
/// @see b2World_CastRay
/// @ingroup world
typedef float b2CastResultCallbackFcn( b2ShapeId shapeId, b2Pos point, b2Vec2 normal,
float fraction, void* context );
/// Used to collect collision planes for character movers. Return true to continue gathering planes.
/// @ingroup character
typedef bool b2PlaneResultCallbackFcn( b2ShapeId shapeId, const b2PlaneResult* plane,
void* context );
/**
* @defgroup debug Debug Draw
*/
/// These colors are used for debug draw and mostly match the named SVG colors.
/// See https://www.rapidtables.com/web/color/index.html
/// https://johndecember.com/html/spec/colorsvg.html
/// https://upload.wikimedia.org/wikipedia/commons/2/2b/SVG_Recognized_color_keyword_names.svg
/// @ingroup debug
typedef enum b2HexColor
{
b2_colorAliceBlue = 0xF0F8FF,
b2_colorAntiqueWhite = 0xFAEBD7,
b2_colorAqua = 0x00FFFF,
b2_colorAquamarine = 0x7FFFD4,
b2_colorAzure = 0xF0FFFF,
b2_colorBeige = 0xF5F5DC,
b2_colorBisque = 0xFFE4C4,
b2_colorBlack = 0x000000,
b2_colorBlanchedAlmond = 0xFFEBCD,
b2_colorBlue = 0x0000FF,
b2_colorBlueViolet = 0x8A2BE2,
b2_colorBrown = 0xA52A2A,
b2_colorBurlywood = 0xDEB887,
b2_colorCadetBlue = 0x5F9EA0,
b2_colorChartreuse = 0x7FFF00,
b2_colorChocolate = 0xD2691E,
b2_colorCoral = 0xFF7F50,
b2_colorCornflowerBlue = 0x6495ED,
b2_colorCornsilk = 0xFFF8DC,
b2_colorCrimson = 0xDC143C,
b2_colorCyan = 0x00FFFF,
b2_colorDarkBlue = 0x00008B,
b2_colorDarkCyan = 0x008B8B,
b2_colorDarkGoldenRod = 0xB8860B,
b2_colorDarkGray = 0xA9A9A9,
b2_colorDarkGreen = 0x006400,
b2_colorDarkKhaki = 0xBDB76B,
b2_colorDarkMagenta = 0x8B008B,
b2_colorDarkOliveGreen = 0x556B2F,
b2_colorDarkOrange = 0xFF8C00,
b2_colorDarkOrchid = 0x9932CC,
b2_colorDarkRed = 0x8B0000,
b2_colorDarkSalmon = 0xE9967A,
b2_colorDarkSeaGreen = 0x8FBC8F,
b2_colorDarkSlateBlue = 0x483D8B,
b2_colorDarkSlateGray = 0x2F4F4F,
b2_colorDarkTurquoise = 0x00CED1,
b2_colorDarkViolet = 0x9400D3,
b2_colorDeepPink = 0xFF1493,
b2_colorDeepSkyBlue = 0x00BFFF,
b2_colorDimGray = 0x696969,
b2_colorDodgerBlue = 0x1E90FF,
b2_colorFireBrick = 0xB22222,
b2_colorFloralWhite = 0xFFFAF0,
b2_colorForestGreen = 0x228B22,
b2_colorFuchsia = 0xFF00FF,
b2_colorGainsboro = 0xDCDCDC,
b2_colorGhostWhite = 0xF8F8FF,
b2_colorGold = 0xFFD700,
b2_colorGoldenRod = 0xDAA520,
b2_colorGray = 0x808080,
b2_colorGreen = 0x008000,
b2_colorGreenYellow = 0xADFF2F,
b2_colorHoneyDew = 0xF0FFF0,
b2_colorHotPink = 0xFF69B4,
b2_colorIndianRed = 0xCD5C5C,
b2_colorIndigo = 0x4B0082,
b2_colorIvory = 0xFFFFF0,
b2_colorKhaki = 0xF0E68C,
b2_colorLavender = 0xE6E6FA,
b2_colorLavenderBlush = 0xFFF0F5,
b2_colorLawnGreen = 0x7CFC00,
b2_colorLemonChiffon = 0xFFFACD,
b2_colorLightBlue = 0xADD8E6,
b2_colorLightCoral = 0xF08080,
b2_colorLightCyan = 0xE0FFFF,
b2_colorLightGoldenRodYellow = 0xFAFAD2,
b2_colorLightGray = 0xD3D3D3,
b2_colorLightGreen = 0x90EE90,
b2_colorLightPink = 0xFFB6C1,
b2_colorLightSalmon = 0xFFA07A,
b2_colorLightSeaGreen = 0x20B2AA,
b2_colorLightSkyBlue = 0x87CEFA,
b2_colorLightSlateGray = 0x778899,
b2_colorLightSteelBlue = 0xB0C4DE,
b2_colorLightYellow = 0xFFFFE0,
b2_colorLime = 0x00FF00,
b2_colorLimeGreen = 0x32CD32,
b2_colorLinen = 0xFAF0E6,
b2_colorMagenta = 0xFF00FF,
b2_colorMaroon = 0x800000,
b2_colorMediumAquaMarine = 0x66CDAA,
b2_colorMediumBlue = 0x0000CD,
b2_colorMediumOrchid = 0xBA55D3,
b2_colorMediumPurple = 0x9370DB,
b2_colorMediumSeaGreen = 0x3CB371,
b2_colorMediumSlateBlue = 0x7B68EE,
b2_colorMediumSpringGreen = 0x00FA9A,
b2_colorMediumTurquoise = 0x48D1CC,
b2_colorMediumVioletRed = 0xC71585,
b2_colorMidnightBlue = 0x191970,
b2_colorMintCream = 0xF5FFFA,
b2_colorMistyRose = 0xFFE4E1,
b2_colorMoccasin = 0xFFE4B5,
b2_colorNavajoWhite = 0xFFDEAD,
b2_colorNavy = 0x000080,
b2_colorOldLace = 0xFDF5E6,
b2_colorOlive = 0x808000,
b2_colorOliveDrab = 0x6B8E23,
b2_colorOrange = 0xFFA500,
b2_colorOrangeRed = 0xFF4500,
b2_colorOrchid = 0xDA70D6,
b2_colorPaleGoldenRod = 0xEEE8AA,
b2_colorPaleGreen = 0x98FB98,
b2_colorPaleTurquoise = 0xAFEEEE,
b2_colorPaleVioletRed = 0xDB7093,
b2_colorPapayaWhip = 0xFFEFD5,
b2_colorPeachPuff = 0xFFDAB9,
b2_colorPeru = 0xCD853F,
b2_colorPink = 0xFFC0CB,
b2_colorPlum = 0xDDA0DD,
b2_colorPowderBlue = 0xB0E0E6,
b2_colorPurple = 0x800080,
b2_colorRebeccaPurple = 0x663399,
b2_colorRed = 0xFF0000,
b2_colorRosyBrown = 0xBC8F8F,
b2_colorRoyalBlue = 0x4169E1,
b2_colorSaddleBrown = 0x8B4513,
b2_colorSalmon = 0xFA8072,
b2_colorSandyBrown = 0xF4A460,
b2_colorSeaGreen = 0x2E8B57,
b2_colorSeaShell = 0xFFF5EE,
b2_colorSienna = 0xA0522D,
b2_colorSilver = 0xC0C0C0,
b2_colorSkyBlue = 0x87CEEB,
b2_colorSlateBlue = 0x6A5ACD,
b2_colorSlateGray = 0x708090,
b2_colorSnow = 0xFFFAFA,
b2_colorSpringGreen = 0x00FF7F,
b2_colorSteelBlue = 0x4682B4,
b2_colorTan = 0xD2B48C,
b2_colorTeal = 0x008080,
b2_colorThistle = 0xD8BFD8,
b2_colorTomato = 0xFF6347,
b2_colorTurquoise = 0x40E0D0,
b2_colorViolet = 0xEE82EE,
b2_colorWheat = 0xF5DEB3,
b2_colorWhite = 0xFFFFFF,
b2_colorWhiteSmoke = 0xF5F5F5,
b2_colorYellow = 0xFFFF00,
b2_colorYellowGreen = 0x9ACD32,
b2_colorBox2DRed = 0xDC3132,
b2_colorBox2DBlue = 0x30AEBF,
b2_colorBox2DGreen = 0x8CC924,
b2_colorBox2DYellow = 0xFFEE8C
} b2HexColor;
/// Get the visualization color assigned to a constraint graph color slot. The last index
/// (B2_GRAPH_COLOR_COUNT - 1) is the overflow color.
/// @ingroup debug
B2_API b2HexColor b2GetGraphColor( int index );
/// This struct holds callbacks you can implement to draw a Box2D world. Callbacks receive world
/// coordinates. In large world mode the translation is double precision so it stays accurate far
/// from the origin. Shift into your own camera frame inside the callbacks. Initialize with
/// b2DefaultDebugDraw.
/// @ingroup debug
typedef struct b2DebugDraw
{
/// Draw a closed polygon provided in CCW order.
void ( *DrawPolygonFcn )( b2WorldTransform transform, const b2Vec2* vertices, int vertexCount,
b2HexColor color, void* context );
/// Draw a solid closed polygon provided in CCW order.
void ( *DrawSolidPolygonFcn )( b2WorldTransform transform, const b2Vec2* vertices,
int vertexCount, float radius, b2HexColor color, void* context );
/// Draw a circle.
void ( *DrawCircleFcn )( b2Pos center, float radius, b2HexColor color, void* context );
/// Draw a solid circle.
void ( *DrawSolidCircleFcn )( b2WorldTransform transform, b2Vec2 center, float radius,
b2HexColor color, void* context );
/// Draw a solid capsule.
void ( *DrawSolidCapsuleFcn )( b2Pos p1, b2Pos p2, float radius, b2HexColor color,
void* context );
/// Draw a line segment.
void ( *DrawLineFcn )( b2Pos p1, b2Pos p2, b2HexColor color, void* context );
/// Draw a transform. Choose your own length scale.
void ( *DrawTransformFcn )( b2WorldTransform transform, void* context );
/// Draw a point.
void ( *DrawPointFcn )( b2Pos p, float size, b2HexColor color, void* context );
/// Draw a string in world space
void ( *DrawStringFcn )( b2Pos p, const char* s, b2HexColor color, void* context );
/// Draw a bounding box. With double precision enabled, the single precision bounding box gets
/// increasing padding when moving far from the origin.
void ( *DrawBoundsFcn )( b2AABB aabb, b2HexColor color, void* context );
/// World bounds used for debug draw. An empty box draws nothing.
b2AABB drawingBounds;
/// Scale to use when drawing forces
float forceScale;
/// Global scaling for joint drawing
float jointScale;
/// Option to draw contact points
bool drawContacts;
/// Draw anchor A for contact points (instead of anchorB)
bool drawAnchorA;
/// Option to draw shapes
bool drawShapes;
/// Option to draw chain shape normals
bool drawChainNormals;
/// Option to draw joints
bool drawJoints;
/// Option to draw additional information for joints
bool drawJointExtras;
/// Option to draw the bounding boxes for shapes
bool drawBounds;
/// Option to draw the mass and center of mass of dynamic bodies
bool drawMass;
/// Option to draw body names
bool drawBodyNames;
/// Option to visualize the graph coloring used for contacts and joints
bool drawGraphColors;
/// Option to draw contact feature ids
bool drawContactFeatures;
/// Option to draw contact normals
bool drawContactNormals;
/// Option to draw contact normal forces
bool drawContactForces;
/// Option to draw contact friction forces
bool drawFrictionForces;
/// Option to draw islands as bounding boxes
bool drawIslands;
/// User context that is passed as an argument to drawing callback functions
void* context;
} b2DebugDraw;
/// Use this to initialize your drawing interface. This allows you to implement a subset of the
/// drawing functions.
/// @ingroup debug
B2_API b2DebugDraw b2DefaultDebugDraw( void );
/// Opaque handle for incremental playback of a recording.
/// @ingroup replay
typedef struct b2Replay b2Replay;
/// Static metadata describing a recording, resolved once when the player opens the file.
/// @ingroup replay
typedef struct b2ReplayInfo
{
int frameCount; ///< total recorded steps
int workerCount; ///< worker count used for the replay world
float timeStep; ///< dt of the recorded steps
int subStepCount; ///< recorded sub-steps
float lengthScale; ///< length units per meter in effect when recorded
b2AABB bounds; ///< accumulated world bounds over the recording, zero-extent if unavailable
} b2ReplayInfo;
/// The kind of a recorded spatial query, matching the public query and cast functions.
/// @ingroup replay
typedef enum b2ReplayQueryType
{
b2_replayQueryOverlapAABB,
b2_replayQueryOverlapShape,
b2_replayQueryCastRay,
b2_replayQueryCastShape,
b2_replayQueryCollideMover,
b2_replayQueryCastRayClosest,
b2_replayQueryCastMover,
} b2ReplayQueryType;
/// A spatial query recorded during a replayed frame, exposed for inspection.
/// @ingroup replay
typedef struct b2ReplayQueryInfo
{
b2ReplayQueryType type; ///< the query type
b2QueryFilter filter; ///< the query filter
b2AABB aabb; ///< overlap AABB, relative to origin
b2Pos origin; ///< query origin
b2Vec2 translation; ///< ray and cast translation
int hitCount; ///< number of recorded results
} b2ReplayQueryInfo;
/// One result of a recorded spatial query.
/// @ingroup replay
typedef struct b2ReplayQueryHit
{
b2ShapeId shapeId; ///< the shape hit
b2Pos point; ///< the hit point on the shape surface
b2Vec2 normal; ///< the unit normal vector at the hit point
float fraction; ///< the query translation fraction
} b2ReplayQueryHit;