#pragma once
#include "arena_allocator.h"
#include "container.h"
#include "box3d/collision.h"
#include "box3d/types.h"
#define B3_FORCE_GHOST_COLLISIONS 0
typedef struct b3Shape b3Shape;
typedef struct b3World b3World;
typedef union b3ContactCache
{
b3SATCache satCache;
b3SimplexCache simplexCache;
} b3ContactCache;
typedef struct b3TriangleCache
{
int triangleIndex;
b3ContactCache cache;
} b3TriangleCache;
b3DeclareArray( b3TriangleCache );
enum b3ContactFlags
{
b3_contactTouchingFlag = 0x00000001,
b3_contactHitEventFlag = 0x00000002,
b3_contactEnableContactEvents = 0x00000004,
b3_contactStaticFlag = 0x00000008,
b3_contactRecycleFlag = 0x00000010,
b3_simTouchingFlag = 0x00010000,
b3_simDisjoint = 0x00020000,
b3_simStartedTouching = 0x00040000,
b3_simStoppedTouching = 0x00080000,
b3_simEnableHitEvent = 0x00100000,
b3_simEnablePreSolveEvents = 0x00200000,
b3_simMeshContact = 0x00400000,
b3_relativeTransformValid = 0x00800000,
};
typedef struct b3ContactEdge
{
int bodyId;
int prevKey;
int nextKey;
} b3ContactEdge;
typedef struct b3MeshContact
{
b3Array( b3TriangleCache ) triangleCache;
b3AABB queryBounds;
} b3MeshContact;
typedef struct b3ConvexContact
{
b3ContactCache cache;
} b3ConvexContact;
typedef struct b3Contact
{
int setIndex;
int colorIndex;
int localIndex;
b3ContactEdge edges[2];
int shapeIdA;
int shapeIdB;
int childIndex;
int islandId;
int islandIndex;
int contactId;
int bodySimIndexA;
int bodySimIndexB;
uint32_t flags;
b3Manifold* manifolds;
int manifoldCount;
b3Quat cachedRotationA;
b3Quat cachedRotationB;
b3Transform cachedRelativePose;
float friction;
union
{
b3ConvexContact convexContact;
b3MeshContact meshContact;
};
float restitution;
float rollingResistance;
b3Vec3 tangentVelocity;
uint32_t generation;
} b3Contact;
typedef struct b3ContactSpec
{
int contactId;
int manifoldStart;
uint16_t manifoldCount;
} b3ContactSpec;
b3DeclareArray( b3ContactSpec );
void b3InitializeContactRegisters( void );
void b3CreateContact( b3World* world, b3Shape* shapeA, b3Shape* shapeB, int childIndex );
void b3DestroyContact( b3World* world, b3Contact* contact, bool wakeBodies );
bool b3UpdateContact( b3World* world, int workerIndex, b3Contact* contact, b3Shape* shapeA, b3Vec3 localCenterA, b3WorldTransform xfA,
b3Shape* shapeB, b3Vec3 localCenterB, b3WorldTransform xfB, bool isFast, b3Arena arena );
bool b3ComputeMeshManifolds( b3World* world, int workerIndex, b3Contact* contact, const b3Shape* shapeA, const int* materialMap,
b3WorldTransform xfA, const b3Shape* shapeB, b3WorldTransform xfB, bool isFast, b3Arena arena );