#pragma once
#include "container.h"
#include "core.h"
#include "box3d/math_functions.h"
#include <stdint.h>
typedef struct b3BodySim b3BodySim;
typedef struct b3BodyState b3BodyState;
typedef struct b3ContactConstraint b3ContactConstraint;
typedef struct b3ContactConstraintWide b3ContactConstraintWide;
typedef struct b3ContactSpec b3ContactSpec;
typedef struct b3JointSim b3JointSim;
typedef struct b3Manifold b3Manifold;
typedef struct b3ManifoldConstraint b3ManifoldConstraint;
typedef struct b3World b3World;
typedef enum b3SolverStageType
{
b3_stagePrepareJoints,
b3_stagePrepareWideContacts,
b3_stagePrepareContacts,
b3_stageIntegrateVelocities,
b3_stageWarmStart,
b3_stageSolve,
b3_stageIntegratePositions,
b3_stageRelax,
b3_stageRestitution,
b3_stageStoreWideImpulses,
b3_stageStoreImpulses,
} b3SolverStageType;
typedef enum b3SolverBlockType
{
b3_bodyBlock,
b3_jointBlock,
b3_wideContactBlock,
b3_contactBlock,
b3_graphJointBlock,
b3_graphWideContactBlock,
b3_graphContactBlock,
b3_overflowBlock,
} b3SolverBlockType;
typedef struct b3SolverBlock
{
int startIndex;
uint16_t count;
uint8_t blockType;
uint8_t colorIndex;
} b3SolverBlock;
typedef struct b3SyncBlock
{
b3SolverBlock block;
b3AtomicInt syncIndex;
} b3SyncBlock;
typedef struct b3SolverStage
{
b3SyncBlock* blocks;
b3SolverStageType type;
int blockCount;
uint8_t colorIndex;
b3AtomicInt completionCount;
} b3SolverStage;
typedef struct b3Softness
{
float biasRate;
float massScale;
float impulseScale;
} b3Softness;
typedef struct b3WidePrepareSpan
{
int start;
int count;
int* contacts;
} b3WidePrepareSpan;
typedef struct b3ContactPrepareSpan
{
int start;
int count;
b3ContactSpec* contacts;
} b3ContactPrepareSpan;
typedef struct b3JointPrepareSpan
{
int start;
int count;
b3JointSim* joints;
} b3JointPrepareSpan;
typedef struct b3StepContext
{
float dt;
float inv_dt;
float h;
float inv_h;
int subStepCount;
b3Softness contactSoftness;
b3Softness staticSoftness;
float restitutionThreshold;
float maxLinearVelocity;
struct b3World* world;
struct b3ConstraintGraph* graph;
b3BodyState* states;
b3BodySim* sims;
int* enlargedShapes;
int enlargedShapeCount;
int* bulletBodies;
b3AtomicInt bulletBodyCount;
int* awakeContactIndices;
struct b3ContactConstraintWide* wideConstraints;
b3WidePrepareSpan* widePrepareSpans;
int wideContactCount;
struct b3ManifoldConstraint* manifoldConstraints;
struct b3ContactConstraint* contactConstraints;
b3ContactPrepareSpan* contactPrepareSpans;
b3ContactPrepareSpan* overflowSpans;
b3JointPrepareSpan* jointPrepareSpans;
int activeColorCount;
int workerCount;
b3SolverStage* stages;
int stageCount;
bool enableWarmStarting;
char padding1[64];
b3AtomicU32 atomicSyncBits;
char padding2[64];
b3AtomicInt mainClaimed;
char padding3[64];
} b3StepContext;
void b3Solve( b3World* world, b3StepContext* stepContext );
static inline b3Softness b3MakeSoft( float hertz, float zeta, float h )
{
if ( hertz == 0.0f )
{
return B3_LITERAL( b3Softness ){
.biasRate = 0.0f,
.massScale = 0.0f,
.impulseScale = 0.0f,
};
}
float omega = 2.0f * B3_PI * hertz;
float a1 = 2.0f * zeta + h * omega;
float a2 = h * omega * a1;
float a3 = 1.0f / ( 1.0f + a2 );
return ( b3Softness ){
.biasRate = omega / a1,
.massScale = a2 * a3,
.impulseScale = a3,
};
}