packages feed

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;