// SPDX-License-Identifier: BSD-3-Clause // // See box3d_shim.h for the rationale behind this file. #include "box3d_shim.h" // The Haskell bindings pass ids by value as Word32/Word64; that pun is only // sound while the ids stay register-sized integer structs. _Static_assert(sizeof(b3WorldId) == 4, "b3WorldId is passed as Word32"); _Static_assert(sizeof(b3BodyId) == 8, "b3BodyId is passed as Word64"); _Static_assert(sizeof(b3ShapeId) == 8, "b3ShapeId is passed as Word64"); _Static_assert(sizeof(b3JointId) == 8, "b3JointId is passed as Word64"); // base.h ----------------------------------------------------------------- void hs_b3GetVersion(b3Version* out) { *out = b3GetVersion(); } // math_functions.h ------------------------------------------------------- bool hs_b3IsValidVec3(const b3Vec3* a) { return b3IsValidVec3(*a); } bool hs_b3IsValidQuat(const b3Quat* q) { return b3IsValidQuat(*q); } bool hs_b3IsValidTransform(const b3Transform* a) { return b3IsValidTransform(*a); } bool hs_b3IsValidMatrix3(const b3Matrix3* a) { return b3IsValidMatrix3(*a); } bool hs_b3IsValidAABB(const b3AABB* a) { return b3IsValidAABB(*a); } bool hs_b3IsValidPlane(const b3Plane* a) { return b3IsValidPlane(*a); } void hs_b3ComputeCosSin(float radians, b3CosSin* out) { *out = b3ComputeCosSin(radians); } void hs_b3ComputeQuatBetweenUnitVectors(const b3Vec3* v1, const b3Vec3* v2, b3Quat* out) { *out = b3ComputeQuatBetweenUnitVectors(*v1, *v2); } // types.h: default definition constructors -------------------------------- void hs_b3DefaultWorldDef(b3WorldDef* out) { *out = b3DefaultWorldDef(); } void hs_b3DefaultBodyDef(b3BodyDef* out) { *out = b3DefaultBodyDef(); } void hs_b3DefaultShapeDef(b3ShapeDef* out) { *out = b3DefaultShapeDef(); } void hs_b3DefaultFilter(b3Filter* out) { *out = b3DefaultFilter(); } void hs_b3DefaultSurfaceMaterial(b3SurfaceMaterial* out) { *out = b3DefaultSurfaceMaterial(); } void hs_b3DefaultQueryFilter(b3QueryFilter* out) { *out = b3DefaultQueryFilter(); } void hs_b3DefaultExplosionDef(b3ExplosionDef* out) { *out = b3DefaultExplosionDef(); } // types.h: joint definition defaults --------------------------------------- void hs_b3DefaultDistanceJointDef(b3DistanceJointDef* out) { *out = b3DefaultDistanceJointDef(); } void hs_b3DefaultMotorJointDef(b3MotorJointDef* out) { *out = b3DefaultMotorJointDef(); } void hs_b3DefaultParallelJointDef(b3ParallelJointDef* out) { *out = b3DefaultParallelJointDef(); } void hs_b3DefaultPrismaticJointDef(b3PrismaticJointDef* out) { *out = b3DefaultPrismaticJointDef(); } void hs_b3DefaultRevoluteJointDef(b3RevoluteJointDef* out) { *out = b3DefaultRevoluteJointDef(); } void hs_b3DefaultSphericalJointDef(b3SphericalJointDef* out) { *out = b3DefaultSphericalJointDef(); } void hs_b3DefaultWeldJointDef(b3WeldJointDef* out) { *out = b3DefaultWeldJointDef(); } void hs_b3DefaultWheelJointDef(b3WheelJointDef* out) { *out = b3DefaultWheelJointDef(); } void hs_b3DefaultFilterJointDef(b3FilterJointDef* out) { *out = b3DefaultFilterJointDef(); } // Callback trampolines ------------------------------------------------------ // GHC callbacks cannot receive structs by value, so these fixed C functions // take the by-value b3Pos/b3Vec3 arguments and forward pointers to a // Haskell-wrapped function carried in the context slot. typedef float (*hs_b3CastResultHsFcn)(b3ShapeId shapeId, const b3Pos* point, const b3Vec3* normal, float fraction, uint64_t userMaterialId, int triangleIndex, int childIndex, void* context); typedef bool (*hs_b3PreSolveHsFcn)(b3ShapeId shapeIdA, b3ShapeId shapeIdB, const b3Pos* point, const b3Vec3* normal, void* context); float hs_b3CastResultTrampoline(b3ShapeId shapeId, b3Pos point, b3Vec3 normal, float fraction, uint64_t userMaterialId, int triangleIndex, int childIndex, void* context) { hs_b3Closure* c = context; return ((hs_b3CastResultHsFcn)c->fn)(shapeId, &point, &normal, fraction, userMaterialId, triangleIndex, childIndex, c->context); } bool hs_b3PreSolveTrampoline(b3ShapeId shapeIdA, b3ShapeId shapeIdB, b3Pos point, b3Vec3 normal, void* context) { hs_b3Closure* c = context; return ((hs_b3PreSolveHsFcn)c->fn)(shapeIdA, shapeIdB, &point, &normal, c->context); } typedef bool (*hs_b3MeshQueryHsFcn)(const b3Vec3* a, const b3Vec3* b, const b3Vec3* c, int triangleIndex, void* context); bool hs_b3MeshQueryTrampoline(b3Vec3 a, b3Vec3 b, b3Vec3 c, int triangleIndex, void* context) { hs_b3Closure* cl = context; return ((hs_b3MeshQueryHsFcn)cl->fn)(&a, &b, &c, triangleIndex, cl->context); }