#pragma once
#include "math_internal.h"
#include "box3d/types.h"
#include <stdbool.h>
typedef struct b3BroadPhase b3BroadPhase;
typedef struct b3World b3World;
typedef struct b3Shape
{
int id;
int bodyId;
int prevShapeId;
int nextShapeId;
int sensorIndex;
int proxyKey;
b3ShapeType type;
float density;
float explosionScale;
float aabbMargin;
b3AABB aabb;
b3AABB fatAABB;
b3Vec3 localCentroid;
b3SurfaceMaterial material;
int materialCount;
b3SurfaceMaterial* materials;
b3Filter filter;
void* userData;
void* userShape;
uint16_t generation;
bool enableSensorEvents;
bool enableContactEvents;
bool enableCustomFiltering;
bool enableHitEvents;
bool enablePreSolveEvents;
bool enlargedAABB;
union
{
b3Capsule capsule;
b3Sphere sphere;
const b3HullData* hull;
b3Mesh mesh;
const b3HeightFieldData* heightField;
const b3CompoundData* compound;
};
} b3Shape;
static inline b3SurfaceMaterial* b3GetShapeMaterials( const b3Shape* shape )
{
return shape->materials != NULL ? shape->materials : (b3SurfaceMaterial*)&shape->material;
}
void b3CreateShapeProxy( b3Shape* shape, b3BroadPhase* bp, b3BodyType type, b3WorldTransform transform, bool forcePairCreation );
void b3DestroyShapeProxy( b3Shape* shape, b3BroadPhase* bp );
void b3DestroyShapeAllocations( b3World* world, b3Shape* shape );
b3MassData b3ComputeShapeMass( const b3Shape* shape );
b3ShapeExtent b3ComputeShapeExtent( const b3Shape* shape, b3Vec3 localCenter );
b3AABB b3ComputeSweptSphereAABB( const b3Sphere* shape, b3Transform xf1, b3Transform xf2 );
b3AABB b3ComputeSweptCapsuleAABB( const b3Capsule* shape, b3Transform xf1, b3Transform xf2 );
b3AABB b3ComputeShapeAABB( const b3Shape* shape, b3Transform transform );
b3AABB b3ComputeFatShapeAABB( const b3Shape* shape, b3WorldTransform transform, float extra );
b3AABB b3ComputeSweptShapeAABB( const b3Shape* shape, const b3Sweep* sweep, float time );
b3Vec3 b3GetShapeCentroid( const b3Shape* shape );
float b3GetShapeArea( const b3Shape* shape );
float b3GetShapeProjectedArea( const b3Shape* shape, b3Vec3 planeNormal );
uint64_t b3GetShapeUserMaterialId( const b3Shape* shape, int childIndex, int triangleIndex );
b3ShapeProxy b3MakeShapeProxy( const b3Shape* shape );
b3ShapeProxy b3MakeLocalProxy( const b3ShapeProxy* proxy, b3Transform transform, b3Vec3* buffer );
b3AABB b3ComputeProxyAABB( const b3ShapeProxy* proxy );
b3CastOutput b3RayCastShape( const b3Shape* shape, b3Transform transform, const b3RayCastInput* input );
b3CastOutput b3ShapeCastShape( const b3Shape* shape, b3Transform transform, const b3ShapeCastInput* input );
bool b3OverlapShape( const b3Shape* shape, b3Transform transform, const b3ShapeProxy* proxy );
float b3GetShapeArea( const b3Shape* shape );
float b3GetShapeProjectedArea( const b3Shape* shape, b3Vec3 planeNormal );
b3TOIOutput b3ShapeTimeOfImpact( b3Shape* shapeA, b3Shape* shapeB, b3Sweep* sweepA, b3Sweep* sweepB, float maxFraction );
int b3CollideMoverAndSphere( b3PlaneResult* result, const b3Sphere* shape, const b3Capsule* mover );
int b3CollideMoverAndCapsule( b3PlaneResult* result, const b3Capsule* shape, const b3Capsule* mover );
int b3CollideMoverAndHull( b3PlaneResult* result, const b3HullData* shape, const b3Capsule* mover );
int b3CollideMoverAndMesh( b3PlaneResult* planes, int capacity, const b3Mesh* shape, const b3Capsule* mover );
int b3CollideMoverAndHeightField( b3PlaneResult* results, int capacity, const b3HeightFieldData* shape, const b3Capsule* mover );
int b3CollideMover( b3PlaneResult* planes, int planeCapacity, const b3Shape* shape, b3Transform transform,
const b3Capsule* mover );
int b3FindHullSupportVertex( const b3HullData* hull, b3Vec3 direction );
int b3FindHullSupportFace( const b3HullData* hull, b3Vec3 direction );
bool b3IsValidHull( const b3HullData* hull );
b3AABB b3ComputeSweptHullAABB( const b3HullData* shape, b3Transform xf1, b3Transform xf2 );
b3ShapeExtent b3ComputeHullExtent( const b3HullData* hull, b3Vec3 origin );
float b3ComputeHullProjectedArea( const b3HullData* hull, b3Vec3 direction );
b3Triangle b3GetHeightFieldTriangle( const b3HeightFieldData* heightField, int triangleIndex );
int b3GetHeightFieldMaterial( const b3HeightFieldData* heightField, int triangleIndex );
static inline int b3GetHeightFieldTriangleCount( const b3HeightFieldData* heightField )
{
int cellCount = ( heightField->rowCount - 1 ) * ( heightField->columnCount - 1 );
return 2 * cellCount;
}
b3Triangle b3GetMeshTriangle( const b3Mesh* mesh, int triangleIndex );
bool b3IsValidMesh( const b3MeshData* meshData );
void b3DumpShape( b3World* world, int shapeIndex );
static inline bool b3ShouldShapesCollide( b3Filter filterA, b3Filter filterB )
{
if ( filterA.groupIndex == filterB.groupIndex && filterA.groupIndex != 0 )
{
return filterA.groupIndex > 0;
}
return ( filterA.maskBits & filterB.categoryBits ) != 0 && ( filterA.categoryBits & filterB.maskBits ) != 0;
}
static inline bool b3ShouldQueryCollide( const b3Filter* shapeFilter, const b3QueryFilter* queryFilter )
{
return ( shapeFilter->categoryBits & queryFilter->maskBits ) != 0 &&
( shapeFilter->maskBits & queryFilter->categoryBits ) != 0;
}