{-# LANGUAGE ForeignFunctionInterface #-} {-# LANGUAGE PatternSynonyms #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} -- | Low-level bindings to the enums and configuration structs of -- @box3d/types.h@ needed to create and configure worlds, bodies and shapes. -- -- The @*Def@ structs carry an @internalValue@ magic that Box3D uses to detect -- an initialised definition, so always start from the matching -- @default*@ constructor and tweak the fields you need before use. Every C -- @bool@ maps to 'CBool' (one byte), and opaque callback / @userData@ pointers -- are kept as @'Ptr' ()@ until the callback layer lands. module Box3D.Types ( -- * Enums BodyType (..) , pattern StaticBody , pattern KinematicBody , pattern DynamicBody , ShapeType (..) , pattern CapsuleShape , pattern CompoundShape , pattern HeightShape , pattern HullShape , pattern MeshShape , pattern SphereShape , JointType (..) , pattern ParallelJoint , pattern DistanceJoint , pattern FilterJoint , pattern MotorJoint , pattern PrismaticJoint , pattern RevoluteJoint , pattern SphericalJoint , pattern WeldJoint , pattern WheelJoint -- * Small structs , Capacity (..) , MotionLocks (..) , Filter (..) , SurfaceMaterial (..) , Sphere (..) , Capsule (..) -- * Definitions , WorldDef (..) , EnqueueTaskCallback , FinishTaskCallback , BodyDef (..) , ShapeDef (..) , ExplosionDef (..) , defaultExplosionDef -- * Queries and casts , QueryFilter (..) , defaultQueryFilter , MassData (..) , RayCastInput (..) , CastOutput (..) , WorldCastOutput , RayResult (..) , TreeStats (..) , Sweep (..) , PlaneResult (..) , dynamicTreeByteCount -- * Events , BodyEvents (..) , BodyMoveEvent (..) , SensorEvents (..) , SensorBeginTouchEvent (..) , SensorEndTouchEvent (..) , ContactEvents (..) , ContactBeginTouchEvent (..) , ContactEndTouchEvent (..) , ContactHitEvent (..) , JointEvents (..) , JointEvent (..) -- * Default definitions , defaultWorldDef , defaultBodyDef , defaultShapeDef , defaultFilter , defaultSurfaceMaterial -- * Joint definitions , JointDef (..) , DistanceJointDef (..) , defaultDistanceJointDef , MotorJointDef (..) , defaultMotorJointDef , ParallelJointDef (..) , defaultParallelJointDef , PrismaticJointDef (..) , defaultPrismaticJointDef , RevoluteJointDef (..) , defaultRevoluteJointDef , SphericalJointDef (..) , defaultSphericalJointDef , WeldJointDef (..) , defaultWeldJointDef , WheelJointDef (..) , defaultWheelJointDef , FilterJointDef (..) , defaultFilterJointDef ) where import Foreign import Foreign.C.String (CString) import Foreign.C.Types (CBool, CInt) import Box3D.Id (BodyId, ContactId, JointId, ShapeId) import Box3D.Internal (allocaOut) import Box3D.MathTypes (Matrix3, Plane, Pos, Quat, Transform, Vec3) import Box3D.Tags (CreateDebugShapeCallback, DestroyDebugShapeCallback, FrictionCallback, RestitutionCallback) #include "box3d/box3d.h" -- Enums ------------------------------------------------------------------- -- | The body simulation type. newtype BodyType = BodyType CInt deriving (Eq, Show, Storable) pattern StaticBody :: BodyType pattern KinematicBody :: BodyType pattern DynamicBody :: BodyType pattern StaticBody = BodyType #{const b3_staticBody} pattern KinematicBody = BodyType #{const b3_kinematicBody} pattern DynamicBody = BodyType #{const b3_dynamicBody} {-# COMPLETE StaticBody, KinematicBody, DynamicBody #-} -- | Shape geometry type. newtype ShapeType = ShapeType CInt deriving (Eq, Show, Storable) pattern CapsuleShape :: ShapeType pattern CompoundShape :: ShapeType pattern HeightShape :: ShapeType pattern HullShape :: ShapeType pattern MeshShape :: ShapeType pattern SphereShape :: ShapeType pattern CapsuleShape = ShapeType #{const b3_capsuleShape} pattern CompoundShape = ShapeType #{const b3_compoundShape} pattern HeightShape = ShapeType #{const b3_heightShape} pattern HullShape = ShapeType #{const b3_hullShape} pattern MeshShape = ShapeType #{const b3_meshShape} pattern SphereShape = ShapeType #{const b3_sphereShape} {-# COMPLETE CapsuleShape, CompoundShape, HeightShape, HullShape, MeshShape, SphereShape #-} -- | Joint type. newtype JointType = JointType CInt deriving (Eq, Show, Storable) pattern ParallelJoint :: JointType pattern DistanceJoint :: JointType pattern FilterJoint :: JointType pattern MotorJoint :: JointType pattern PrismaticJoint :: JointType pattern RevoluteJoint :: JointType pattern SphericalJoint :: JointType pattern WeldJoint :: JointType pattern WheelJoint :: JointType pattern ParallelJoint = JointType #{const b3_parallelJoint} pattern DistanceJoint = JointType #{const b3_distanceJoint} pattern FilterJoint = JointType #{const b3_filterJoint} pattern MotorJoint = JointType #{const b3_motorJoint} pattern PrismaticJoint = JointType #{const b3_prismaticJoint} pattern RevoluteJoint = JointType #{const b3_revoluteJoint} pattern SphericalJoint = JointType #{const b3_sphericalJoint} pattern WeldJoint = JointType #{const b3_weldJoint} pattern WheelJoint = JointType #{const b3_wheelJoint} {-# COMPLETE ParallelJoint, DistanceJoint, FilterJoint, MotorJoint, PrismaticJoint, RevoluteJoint, SphericalJoint, WeldJoint, WheelJoint #-} -- Small structs ----------------------------------------------------------- -- | Optional world capacities used to avoid run-time allocations. data Capacity = Capacity { capacityStaticShapeCount :: CInt , capacityDynamicShapeCount :: CInt , capacityStaticBodyCount :: CInt , capacityDynamicBodyCount :: CInt , capacityContactCount :: CInt } deriving (Eq, Show) instance Storable Capacity where sizeOf _ = #{size b3Capacity} alignment _ = #{alignment b3Capacity} peek p = Capacity <$> #{peek b3Capacity, staticShapeCount} p <*> #{peek b3Capacity, dynamicShapeCount} p <*> #{peek b3Capacity, staticBodyCount} p <*> #{peek b3Capacity, dynamicBodyCount} p <*> #{peek b3Capacity, contactCount} p poke p (Capacity ss ds sb db c) = do #{poke b3Capacity, staticShapeCount} p ss #{poke b3Capacity, dynamicShapeCount} p ds #{poke b3Capacity, staticBodyCount} p sb #{poke b3Capacity, dynamicBodyCount} p db #{poke b3Capacity, contactCount} p c -- | Per-axis translation and rotation locks for a body. data MotionLocks = MotionLocks { motionLocksLinearX :: CBool , motionLocksLinearY :: CBool , motionLocksLinearZ :: CBool , motionLocksAngularX :: CBool , motionLocksAngularY :: CBool , motionLocksAngularZ :: CBool } deriving (Eq, Show) instance Storable MotionLocks where sizeOf _ = #{size b3MotionLocks} alignment _ = #{alignment b3MotionLocks} peek p = MotionLocks <$> #{peek b3MotionLocks, linearX} p <*> #{peek b3MotionLocks, linearY} p <*> #{peek b3MotionLocks, linearZ} p <*> #{peek b3MotionLocks, angularX} p <*> #{peek b3MotionLocks, angularY} p <*> #{peek b3MotionLocks, angularZ} p poke p (MotionLocks lx ly lz ax ay az) = do #{poke b3MotionLocks, linearX} p lx #{poke b3MotionLocks, linearY} p ly #{poke b3MotionLocks, linearZ} p lz #{poke b3MotionLocks, angularX} p ax #{poke b3MotionLocks, angularY} p ay #{poke b3MotionLocks, angularZ} p az -- | Collision filtering data. data Filter = Filter { filterCategoryBits :: Word64 , filterMaskBits :: Word64 , filterGroupIndex :: CInt } deriving (Eq, Show) instance Storable Filter where sizeOf _ = #{size b3Filter} alignment _ = #{alignment b3Filter} peek p = Filter <$> #{peek b3Filter, categoryBits} p <*> #{peek b3Filter, maskBits} p <*> #{peek b3Filter, groupIndex} p poke p (Filter c m g) = do #{poke b3Filter, categoryBits} p c #{poke b3Filter, maskBits} p m #{poke b3Filter, groupIndex} p g -- | Per-surface material properties. data SurfaceMaterial = SurfaceMaterial { surfaceMaterialFriction :: Float , surfaceMaterialRestitution :: Float , surfaceMaterialRollingResistance :: Float , surfaceMaterialTangentVelocity :: Vec3 , surfaceMaterialUserMaterialId :: Word64 , surfaceMaterialCustomColor :: Word32 } deriving (Eq, Show) instance Storable SurfaceMaterial where sizeOf _ = #{size b3SurfaceMaterial} alignment _ = #{alignment b3SurfaceMaterial} peek p = SurfaceMaterial <$> #{peek b3SurfaceMaterial, friction} p <*> #{peek b3SurfaceMaterial, restitution} p <*> #{peek b3SurfaceMaterial, rollingResistance} p <*> #{peek b3SurfaceMaterial, tangentVelocity} p <*> #{peek b3SurfaceMaterial, userMaterialId} p <*> #{peek b3SurfaceMaterial, customColor} p poke p (SurfaceMaterial f r rr tv umi cc) = do #{poke b3SurfaceMaterial, friction} p f #{poke b3SurfaceMaterial, restitution} p r #{poke b3SurfaceMaterial, rollingResistance} p rr #{poke b3SurfaceMaterial, tangentVelocity} p tv #{poke b3SurfaceMaterial, userMaterialId} p umi #{poke b3SurfaceMaterial, customColor} p cc -- | A sphere with a local center offset. data Sphere = Sphere { sphereCenter :: Vec3 , sphereRadius :: Float } deriving (Eq, Show) instance Storable Sphere where sizeOf _ = #{size b3Sphere} alignment _ = #{alignment b3Sphere} peek p = Sphere <$> #{peek b3Sphere, center} p <*> #{peek b3Sphere, radius} p poke p (Sphere c r) = do #{poke b3Sphere, center} p c #{poke b3Sphere, radius} p r -- | A capsule: an extruded sphere between two hemisphere centers. data Capsule = Capsule { capsuleCenter1 :: Vec3 , capsuleCenter2 :: Vec3 , capsuleRadius :: Float } deriving (Eq, Show) instance Storable Capsule where sizeOf _ = #{size b3Capsule} alignment _ = #{alignment b3Capsule} peek p = Capsule <$> #{peek b3Capsule, center1} p <*> #{peek b3Capsule, center2} p <*> #{peek b3Capsule, radius} p poke p (Capsule c1 c2 r) = do #{poke b3Capsule, center1} p c1 #{poke b3Capsule, center2} p c2 #{poke b3Capsule, radius} p r -- Definitions ------------------------------------------------------------- -- | Phantom tags for the task-system callbacks stored on 'WorldDef'. These -- typedefs never appear in API signatures, so "Box3D.Tags" carries no tag for -- them; produce values with 'Box3D.Callbacks.withThreadPoolTaskSystem'. data EnqueueTaskCallback data FinishTaskCallback -- | World creation definition. Initialise with 'defaultWorldDef'. data WorldDef = WorldDef { worldDefGravity :: Vec3 , worldDefRestitutionThreshold :: Float , worldDefHitEventThreshold :: Float , worldDefContactHertz :: Float , worldDefContactDampingRatio :: Float , worldDefContactSpeed :: Float , worldDefMaximumLinearSpeed :: Float , worldDefFrictionCallback :: FunPtr FrictionCallback , worldDefRestitutionCallback :: FunPtr RestitutionCallback , worldDefEnableSleep :: CBool , worldDefEnableContinuous :: CBool , worldDefWorkerCount :: Word32 , worldDefEnqueueTask :: FunPtr EnqueueTaskCallback , worldDefFinishTask :: FunPtr FinishTaskCallback , worldDefUserTaskContext :: Ptr () , worldDefUserData :: Ptr () , worldDefCreateDebugShape :: FunPtr CreateDebugShapeCallback , worldDefDestroyDebugShape :: FunPtr DestroyDebugShapeCallback , worldDefUserDebugShapeContext :: Ptr () , worldDefCapacity :: Capacity , worldDefInternalValue :: CInt } deriving (Eq, Show) instance Storable WorldDef where sizeOf _ = #{size b3WorldDef} alignment _ = #{alignment b3WorldDef} peek p = WorldDef <$> #{peek b3WorldDef, gravity} p <*> #{peek b3WorldDef, restitutionThreshold} p <*> #{peek b3WorldDef, hitEventThreshold} p <*> #{peek b3WorldDef, contactHertz} p <*> #{peek b3WorldDef, contactDampingRatio} p <*> #{peek b3WorldDef, contactSpeed} p <*> #{peek b3WorldDef, maximumLinearSpeed} p <*> #{peek b3WorldDef, frictionCallback} p <*> #{peek b3WorldDef, restitutionCallback} p <*> #{peek b3WorldDef, enableSleep} p <*> #{peek b3WorldDef, enableContinuous} p <*> #{peek b3WorldDef, workerCount} p <*> #{peek b3WorldDef, enqueueTask} p <*> #{peek b3WorldDef, finishTask} p <*> #{peek b3WorldDef, userTaskContext} p <*> #{peek b3WorldDef, userData} p <*> #{peek b3WorldDef, createDebugShape} p <*> #{peek b3WorldDef, destroyDebugShape} p <*> #{peek b3WorldDef, userDebugShapeContext} p <*> #{peek b3WorldDef, capacity} p <*> #{peek b3WorldDef, internalValue} p poke p d = do #{poke b3WorldDef, gravity} p (worldDefGravity d) #{poke b3WorldDef, restitutionThreshold} p (worldDefRestitutionThreshold d) #{poke b3WorldDef, hitEventThreshold} p (worldDefHitEventThreshold d) #{poke b3WorldDef, contactHertz} p (worldDefContactHertz d) #{poke b3WorldDef, contactDampingRatio} p (worldDefContactDampingRatio d) #{poke b3WorldDef, contactSpeed} p (worldDefContactSpeed d) #{poke b3WorldDef, maximumLinearSpeed} p (worldDefMaximumLinearSpeed d) #{poke b3WorldDef, frictionCallback} p (worldDefFrictionCallback d) #{poke b3WorldDef, restitutionCallback} p (worldDefRestitutionCallback d) #{poke b3WorldDef, enableSleep} p (worldDefEnableSleep d) #{poke b3WorldDef, enableContinuous} p (worldDefEnableContinuous d) #{poke b3WorldDef, workerCount} p (worldDefWorkerCount d) #{poke b3WorldDef, enqueueTask} p (worldDefEnqueueTask d) #{poke b3WorldDef, finishTask} p (worldDefFinishTask d) #{poke b3WorldDef, userTaskContext} p (worldDefUserTaskContext d) #{poke b3WorldDef, userData} p (worldDefUserData d) #{poke b3WorldDef, createDebugShape} p (worldDefCreateDebugShape d) #{poke b3WorldDef, destroyDebugShape} p (worldDefDestroyDebugShape d) #{poke b3WorldDef, userDebugShapeContext} p (worldDefUserDebugShapeContext d) #{poke b3WorldDef, capacity} p (worldDefCapacity d) #{poke b3WorldDef, internalValue} p (worldDefInternalValue d) -- | Rigid body creation definition. Initialise with 'defaultBodyDef'. data BodyDef = BodyDef { bodyDefType :: BodyType , bodyDefPosition :: Pos , bodyDefRotation :: Quat , bodyDefLinearVelocity :: Vec3 , bodyDefAngularVelocity :: Vec3 , bodyDefLinearDamping :: Float , bodyDefAngularDamping :: Float , bodyDefGravityScale :: Float , bodyDefSleepThreshold :: Float , bodyDefName :: CString , bodyDefUserData :: Ptr () , bodyDefMotionLocks :: MotionLocks , bodyDefEnableSleep :: CBool , bodyDefIsAwake :: CBool , bodyDefIsBullet :: CBool , bodyDefIsEnabled :: CBool , bodyDefAllowFastRotation :: CBool , bodyDefEnableContactRecycling :: CBool , bodyDefInternalValue :: CInt } deriving (Eq, Show) instance Storable BodyDef where sizeOf _ = #{size b3BodyDef} alignment _ = #{alignment b3BodyDef} peek p = BodyDef <$> #{peek b3BodyDef, type} p <*> #{peek b3BodyDef, position} p <*> #{peek b3BodyDef, rotation} p <*> #{peek b3BodyDef, linearVelocity} p <*> #{peek b3BodyDef, angularVelocity} p <*> #{peek b3BodyDef, linearDamping} p <*> #{peek b3BodyDef, angularDamping} p <*> #{peek b3BodyDef, gravityScale} p <*> #{peek b3BodyDef, sleepThreshold} p <*> #{peek b3BodyDef, name} p <*> #{peek b3BodyDef, userData} p <*> #{peek b3BodyDef, motionLocks} p <*> #{peek b3BodyDef, enableSleep} p <*> #{peek b3BodyDef, isAwake} p <*> #{peek b3BodyDef, isBullet} p <*> #{peek b3BodyDef, isEnabled} p <*> #{peek b3BodyDef, allowFastRotation} p <*> #{peek b3BodyDef, enableContactRecycling} p <*> #{peek b3BodyDef, internalValue} p poke p d = do #{poke b3BodyDef, type} p (bodyDefType d) #{poke b3BodyDef, position} p (bodyDefPosition d) #{poke b3BodyDef, rotation} p (bodyDefRotation d) #{poke b3BodyDef, linearVelocity} p (bodyDefLinearVelocity d) #{poke b3BodyDef, angularVelocity} p (bodyDefAngularVelocity d) #{poke b3BodyDef, linearDamping} p (bodyDefLinearDamping d) #{poke b3BodyDef, angularDamping} p (bodyDefAngularDamping d) #{poke b3BodyDef, gravityScale} p (bodyDefGravityScale d) #{poke b3BodyDef, sleepThreshold} p (bodyDefSleepThreshold d) #{poke b3BodyDef, name} p (bodyDefName d) #{poke b3BodyDef, userData} p (bodyDefUserData d) #{poke b3BodyDef, motionLocks} p (bodyDefMotionLocks d) #{poke b3BodyDef, enableSleep} p (bodyDefEnableSleep d) #{poke b3BodyDef, isAwake} p (bodyDefIsAwake d) #{poke b3BodyDef, isBullet} p (bodyDefIsBullet d) #{poke b3BodyDef, isEnabled} p (bodyDefIsEnabled d) #{poke b3BodyDef, allowFastRotation} p (bodyDefAllowFastRotation d) #{poke b3BodyDef, enableContactRecycling} p (bodyDefEnableContactRecycling d) #{poke b3BodyDef, internalValue} p (bodyDefInternalValue d) -- | Shape creation definition. Initialise with 'defaultShapeDef'. data ShapeDef = ShapeDef { shapeDefUserData :: Ptr () , shapeDefMaterials :: Ptr SurfaceMaterial , shapeDefMaterialCount :: CInt , shapeDefBaseMaterial :: SurfaceMaterial , shapeDefDensity :: Float , shapeDefExplosionScale :: Float , shapeDefFilter :: Filter , shapeDefEnableCustomFiltering :: CBool , shapeDefIsSensor :: CBool -- ^ Create-time only: a shape cannot change sensor-ness after creation. , shapeDefEnableSensorEvents :: CBool -- ^ Needed on the sensor /and/ the visiting shape for sensor events. , shapeDefEnableContactEvents :: CBool -- ^ Contact events are opt-in per shape (both shapes of the pair). , shapeDefEnableHitEvents :: CBool -- ^ Hit events additionally require exceeding @worldDefHitEventThreshold@. , shapeDefEnablePreSolveEvents :: CBool , shapeDefInvokeContactCreation :: CBool , shapeDefUpdateBodyMass :: CBool , shapeDefInternalValue :: CInt } deriving (Eq, Show) instance Storable ShapeDef where sizeOf _ = #{size b3ShapeDef} alignment _ = #{alignment b3ShapeDef} peek p = ShapeDef <$> #{peek b3ShapeDef, userData} p <*> #{peek b3ShapeDef, materials} p <*> #{peek b3ShapeDef, materialCount} p <*> #{peek b3ShapeDef, baseMaterial} p <*> #{peek b3ShapeDef, density} p <*> #{peek b3ShapeDef, explosionScale} p <*> #{peek b3ShapeDef, filter} p <*> #{peek b3ShapeDef, enableCustomFiltering} p <*> #{peek b3ShapeDef, isSensor} p <*> #{peek b3ShapeDef, enableSensorEvents} p <*> #{peek b3ShapeDef, enableContactEvents} p <*> #{peek b3ShapeDef, enableHitEvents} p <*> #{peek b3ShapeDef, enablePreSolveEvents} p <*> #{peek b3ShapeDef, invokeContactCreation} p <*> #{peek b3ShapeDef, updateBodyMass} p <*> #{peek b3ShapeDef, internalValue} p poke p d = do #{poke b3ShapeDef, userData} p (shapeDefUserData d) #{poke b3ShapeDef, materials} p (shapeDefMaterials d) #{poke b3ShapeDef, materialCount} p (shapeDefMaterialCount d) #{poke b3ShapeDef, baseMaterial} p (shapeDefBaseMaterial d) #{poke b3ShapeDef, density} p (shapeDefDensity d) #{poke b3ShapeDef, explosionScale} p (shapeDefExplosionScale d) #{poke b3ShapeDef, filter} p (shapeDefFilter d) #{poke b3ShapeDef, enableCustomFiltering} p (shapeDefEnableCustomFiltering d) #{poke b3ShapeDef, isSensor} p (shapeDefIsSensor d) #{poke b3ShapeDef, enableSensorEvents} p (shapeDefEnableSensorEvents d) #{poke b3ShapeDef, enableContactEvents} p (shapeDefEnableContactEvents d) #{poke b3ShapeDef, enableHitEvents} p (shapeDefEnableHitEvents d) #{poke b3ShapeDef, enablePreSolveEvents} p (shapeDefEnablePreSolveEvents d) #{poke b3ShapeDef, invokeContactCreation} p (shapeDefInvokeContactCreation d) #{poke b3ShapeDef, updateBodyMass} p (shapeDefUpdateBodyMass d) #{poke b3ShapeDef, internalValue} p (shapeDefInternalValue d) -- Default definitions ----------------------------------------------------- foreign import ccall unsafe "hs_b3DefaultWorldDef" c_b3DefaultWorldDef :: Ptr WorldDef -> IO () foreign import ccall unsafe "hs_b3DefaultBodyDef" c_b3DefaultBodyDef :: Ptr BodyDef -> IO () foreign import ccall unsafe "hs_b3DefaultShapeDef" c_b3DefaultShapeDef :: Ptr ShapeDef -> IO () foreign import ccall unsafe "hs_b3DefaultFilter" c_b3DefaultFilter :: Ptr Filter -> IO () foreign import ccall unsafe "hs_b3DefaultSurfaceMaterial" c_b3DefaultSurfaceMaterial :: Ptr SurfaceMaterial -> IO () -- | A fully-initialised world definition. defaultWorldDef :: IO WorldDef defaultWorldDef = allocaOut c_b3DefaultWorldDef -- | A fully-initialised body definition. defaultBodyDef :: IO BodyDef defaultBodyDef = allocaOut c_b3DefaultBodyDef -- | A fully-initialised shape definition. defaultShapeDef :: IO ShapeDef defaultShapeDef = allocaOut c_b3DefaultShapeDef -- | A fully-initialised collision filter. defaultFilter :: IO Filter defaultFilter = allocaOut c_b3DefaultFilter -- | A fully-initialised surface material. defaultSurfaceMaterial :: IO SurfaceMaterial defaultSurfaceMaterial = allocaOut c_b3DefaultSurfaceMaterial foreign import ccall unsafe "hs_b3DefaultExplosionDef" c_b3DefaultExplosionDef :: Ptr ExplosionDef -> IO () -- | Explosion parameters for 'Box3D.World.explode'. Initialise with -- 'defaultExplosionDef'. data ExplosionDef = ExplosionDef { explosionDefMaskBits :: Word64 , explosionDefPosition :: Pos , explosionDefRadius :: Float , explosionDefFalloff :: Float , explosionDefImpulsePerArea :: Float } deriving (Eq, Show) instance Storable ExplosionDef where sizeOf _ = #{size b3ExplosionDef} alignment _ = #{alignment b3ExplosionDef} peek p = ExplosionDef <$> #{peek b3ExplosionDef, maskBits} p <*> #{peek b3ExplosionDef, position} p <*> #{peek b3ExplosionDef, radius} p <*> #{peek b3ExplosionDef, falloff} p <*> #{peek b3ExplosionDef, impulsePerArea} p poke p d = do #{poke b3ExplosionDef, maskBits} p (explosionDefMaskBits d) #{poke b3ExplosionDef, position} p (explosionDefPosition d) #{poke b3ExplosionDef, radius} p (explosionDefRadius d) #{poke b3ExplosionDef, falloff} p (explosionDefFalloff d) #{poke b3ExplosionDef, impulsePerArea} p (explosionDefImpulsePerArea d) -- | A fully-initialised explosion definition. defaultExplosionDef :: IO ExplosionDef defaultExplosionDef = allocaOut c_b3DefaultExplosionDef -- Joint definitions ------------------------------------------------------ -- | The shared base of every joint definition. data JointDef = JointDef { jointDefUserData :: Ptr () , jointDefBodyIdA :: BodyId , jointDefBodyIdB :: BodyId , jointDefLocalFrameA :: Transform , jointDefLocalFrameB :: Transform , jointDefForceThreshold :: Float , jointDefTorqueThreshold :: Float , jointDefConstraintHertz :: Float , jointDefConstraintDampingRatio :: Float , jointDefDrawScale :: Float , jointDefCollideConnected :: CBool , jointDefInternalValue :: CInt } deriving (Eq, Show) instance Storable JointDef where sizeOf _ = #{size b3JointDef} alignment _ = #{alignment b3JointDef} peek p = JointDef <$> #{peek b3JointDef, userData} p <*> #{peek b3JointDef, bodyIdA} p <*> #{peek b3JointDef, bodyIdB} p <*> #{peek b3JointDef, localFrameA} p <*> #{peek b3JointDef, localFrameB} p <*> #{peek b3JointDef, forceThreshold} p <*> #{peek b3JointDef, torqueThreshold} p <*> #{peek b3JointDef, constraintHertz} p <*> #{peek b3JointDef, constraintDampingRatio} p <*> #{peek b3JointDef, drawScale} p <*> #{peek b3JointDef, collideConnected} p <*> #{peek b3JointDef, internalValue} p poke p x = do #{poke b3JointDef, userData} p (jointDefUserData x) #{poke b3JointDef, bodyIdA} p (jointDefBodyIdA x) #{poke b3JointDef, bodyIdB} p (jointDefBodyIdB x) #{poke b3JointDef, localFrameA} p (jointDefLocalFrameA x) #{poke b3JointDef, localFrameB} p (jointDefLocalFrameB x) #{poke b3JointDef, forceThreshold} p (jointDefForceThreshold x) #{poke b3JointDef, torqueThreshold} p (jointDefTorqueThreshold x) #{poke b3JointDef, constraintHertz} p (jointDefConstraintHertz x) #{poke b3JointDef, constraintDampingRatio} p (jointDefConstraintDampingRatio x) #{poke b3JointDef, drawScale} p (jointDefDrawScale x) #{poke b3JointDef, collideConnected} p (jointDefCollideConnected x) #{poke b3JointDef, internalValue} p (jointDefInternalValue x) -- | Distance joint definition. Initialise with 'defaultDistanceJointDef'. data DistanceJointDef = DistanceJointDef { distanceJointDefBase :: JointDef , distanceJointDefLength :: Float , distanceJointDefEnableSpring :: CBool , distanceJointDefLowerSpringForce :: Float , distanceJointDefUpperSpringForce :: Float , distanceJointDefHertz :: Float , distanceJointDefDampingRatio :: Float , distanceJointDefEnableLimit :: CBool , distanceJointDefMinLength :: Float , distanceJointDefMaxLength :: Float , distanceJointDefEnableMotor :: CBool , distanceJointDefMaxMotorForce :: Float , distanceJointDefMotorSpeed :: Float } deriving (Eq, Show) instance Storable DistanceJointDef where sizeOf _ = #{size b3DistanceJointDef} alignment _ = #{alignment b3DistanceJointDef} peek p = DistanceJointDef <$> #{peek b3DistanceJointDef, base} p <*> #{peek b3DistanceJointDef, length} p <*> #{peek b3DistanceJointDef, enableSpring} p <*> #{peek b3DistanceJointDef, lowerSpringForce} p <*> #{peek b3DistanceJointDef, upperSpringForce} p <*> #{peek b3DistanceJointDef, hertz} p <*> #{peek b3DistanceJointDef, dampingRatio} p <*> #{peek b3DistanceJointDef, enableLimit} p <*> #{peek b3DistanceJointDef, minLength} p <*> #{peek b3DistanceJointDef, maxLength} p <*> #{peek b3DistanceJointDef, enableMotor} p <*> #{peek b3DistanceJointDef, maxMotorForce} p <*> #{peek b3DistanceJointDef, motorSpeed} p poke p x = do #{poke b3DistanceJointDef, base} p (distanceJointDefBase x) #{poke b3DistanceJointDef, length} p (distanceJointDefLength x) #{poke b3DistanceJointDef, enableSpring} p (distanceJointDefEnableSpring x) #{poke b3DistanceJointDef, lowerSpringForce} p (distanceJointDefLowerSpringForce x) #{poke b3DistanceJointDef, upperSpringForce} p (distanceJointDefUpperSpringForce x) #{poke b3DistanceJointDef, hertz} p (distanceJointDefHertz x) #{poke b3DistanceJointDef, dampingRatio} p (distanceJointDefDampingRatio x) #{poke b3DistanceJointDef, enableLimit} p (distanceJointDefEnableLimit x) #{poke b3DistanceJointDef, minLength} p (distanceJointDefMinLength x) #{poke b3DistanceJointDef, maxLength} p (distanceJointDefMaxLength x) #{poke b3DistanceJointDef, enableMotor} p (distanceJointDefEnableMotor x) #{poke b3DistanceJointDef, maxMotorForce} p (distanceJointDefMaxMotorForce x) #{poke b3DistanceJointDef, motorSpeed} p (distanceJointDefMotorSpeed x) -- | Motor joint definition. Initialise with 'defaultMotorJointDef'. data MotorJointDef = MotorJointDef { motorJointDefBase :: JointDef , motorJointDefLinearVelocity :: Vec3 , motorJointDefMaxVelocityForce :: Float , motorJointDefAngularVelocity :: Vec3 , motorJointDefMaxVelocityTorque :: Float , motorJointDefLinearHertz :: Float , motorJointDefLinearDampingRatio :: Float , motorJointDefMaxSpringForce :: Float , motorJointDefAngularHertz :: Float , motorJointDefAngularDampingRatio :: Float , motorJointDefMaxSpringTorque :: Float } deriving (Eq, Show) instance Storable MotorJointDef where sizeOf _ = #{size b3MotorJointDef} alignment _ = #{alignment b3MotorJointDef} peek p = MotorJointDef <$> #{peek b3MotorJointDef, base} p <*> #{peek b3MotorJointDef, linearVelocity} p <*> #{peek b3MotorJointDef, maxVelocityForce} p <*> #{peek b3MotorJointDef, angularVelocity} p <*> #{peek b3MotorJointDef, maxVelocityTorque} p <*> #{peek b3MotorJointDef, linearHertz} p <*> #{peek b3MotorJointDef, linearDampingRatio} p <*> #{peek b3MotorJointDef, maxSpringForce} p <*> #{peek b3MotorJointDef, angularHertz} p <*> #{peek b3MotorJointDef, angularDampingRatio} p <*> #{peek b3MotorJointDef, maxSpringTorque} p poke p x = do #{poke b3MotorJointDef, base} p (motorJointDefBase x) #{poke b3MotorJointDef, linearVelocity} p (motorJointDefLinearVelocity x) #{poke b3MotorJointDef, maxVelocityForce} p (motorJointDefMaxVelocityForce x) #{poke b3MotorJointDef, angularVelocity} p (motorJointDefAngularVelocity x) #{poke b3MotorJointDef, maxVelocityTorque} p (motorJointDefMaxVelocityTorque x) #{poke b3MotorJointDef, linearHertz} p (motorJointDefLinearHertz x) #{poke b3MotorJointDef, linearDampingRatio} p (motorJointDefLinearDampingRatio x) #{poke b3MotorJointDef, maxSpringForce} p (motorJointDefMaxSpringForce x) #{poke b3MotorJointDef, angularHertz} p (motorJointDefAngularHertz x) #{poke b3MotorJointDef, angularDampingRatio} p (motorJointDefAngularDampingRatio x) #{poke b3MotorJointDef, maxSpringTorque} p (motorJointDefMaxSpringTorque x) -- | Parallel joint definition. Initialise with 'defaultParallelJointDef'. data ParallelJointDef = ParallelJointDef { parallelJointDefBase :: JointDef , parallelJointDefHertz :: Float , parallelJointDefDampingRatio :: Float , parallelJointDefMaxTorque :: Float } deriving (Eq, Show) instance Storable ParallelJointDef where sizeOf _ = #{size b3ParallelJointDef} alignment _ = #{alignment b3ParallelJointDef} peek p = ParallelJointDef <$> #{peek b3ParallelJointDef, base} p <*> #{peek b3ParallelJointDef, hertz} p <*> #{peek b3ParallelJointDef, dampingRatio} p <*> #{peek b3ParallelJointDef, maxTorque} p poke p x = do #{poke b3ParallelJointDef, base} p (parallelJointDefBase x) #{poke b3ParallelJointDef, hertz} p (parallelJointDefHertz x) #{poke b3ParallelJointDef, dampingRatio} p (parallelJointDefDampingRatio x) #{poke b3ParallelJointDef, maxTorque} p (parallelJointDefMaxTorque x) -- | Prismatic joint definition. Initialise with 'defaultPrismaticJointDef'. data PrismaticJointDef = PrismaticJointDef { prismaticJointDefBase :: JointDef , prismaticJointDefEnableSpring :: CBool , prismaticJointDefHertz :: Float , prismaticJointDefDampingRatio :: Float , prismaticJointDefTargetTranslation :: Float , prismaticJointDefEnableLimit :: CBool , prismaticJointDefLowerTranslation :: Float , prismaticJointDefUpperTranslation :: Float , prismaticJointDefEnableMotor :: CBool , prismaticJointDefMaxMotorForce :: Float , prismaticJointDefMotorSpeed :: Float } deriving (Eq, Show) instance Storable PrismaticJointDef where sizeOf _ = #{size b3PrismaticJointDef} alignment _ = #{alignment b3PrismaticJointDef} peek p = PrismaticJointDef <$> #{peek b3PrismaticJointDef, base} p <*> #{peek b3PrismaticJointDef, enableSpring} p <*> #{peek b3PrismaticJointDef, hertz} p <*> #{peek b3PrismaticJointDef, dampingRatio} p <*> #{peek b3PrismaticJointDef, targetTranslation} p <*> #{peek b3PrismaticJointDef, enableLimit} p <*> #{peek b3PrismaticJointDef, lowerTranslation} p <*> #{peek b3PrismaticJointDef, upperTranslation} p <*> #{peek b3PrismaticJointDef, enableMotor} p <*> #{peek b3PrismaticJointDef, maxMotorForce} p <*> #{peek b3PrismaticJointDef, motorSpeed} p poke p x = do #{poke b3PrismaticJointDef, base} p (prismaticJointDefBase x) #{poke b3PrismaticJointDef, enableSpring} p (prismaticJointDefEnableSpring x) #{poke b3PrismaticJointDef, hertz} p (prismaticJointDefHertz x) #{poke b3PrismaticJointDef, dampingRatio} p (prismaticJointDefDampingRatio x) #{poke b3PrismaticJointDef, targetTranslation} p (prismaticJointDefTargetTranslation x) #{poke b3PrismaticJointDef, enableLimit} p (prismaticJointDefEnableLimit x) #{poke b3PrismaticJointDef, lowerTranslation} p (prismaticJointDefLowerTranslation x) #{poke b3PrismaticJointDef, upperTranslation} p (prismaticJointDefUpperTranslation x) #{poke b3PrismaticJointDef, enableMotor} p (prismaticJointDefEnableMotor x) #{poke b3PrismaticJointDef, maxMotorForce} p (prismaticJointDefMaxMotorForce x) #{poke b3PrismaticJointDef, motorSpeed} p (prismaticJointDefMotorSpeed x) -- | Revolute joint definition. Initialise with 'defaultRevoluteJointDef'. data RevoluteJointDef = RevoluteJointDef { revoluteJointDefBase :: JointDef , revoluteJointDefTargetAngle :: Float , revoluteJointDefEnableSpring :: CBool , revoluteJointDefHertz :: Float , revoluteJointDefDampingRatio :: Float , revoluteJointDefEnableLimit :: CBool , revoluteJointDefLowerAngle :: Float , revoluteJointDefUpperAngle :: Float , revoluteJointDefEnableMotor :: CBool , revoluteJointDefMaxMotorTorque :: Float , revoluteJointDefMotorSpeed :: Float } deriving (Eq, Show) instance Storable RevoluteJointDef where sizeOf _ = #{size b3RevoluteJointDef} alignment _ = #{alignment b3RevoluteJointDef} peek p = RevoluteJointDef <$> #{peek b3RevoluteJointDef, base} p <*> #{peek b3RevoluteJointDef, targetAngle} p <*> #{peek b3RevoluteJointDef, enableSpring} p <*> #{peek b3RevoluteJointDef, hertz} p <*> #{peek b3RevoluteJointDef, dampingRatio} p <*> #{peek b3RevoluteJointDef, enableLimit} p <*> #{peek b3RevoluteJointDef, lowerAngle} p <*> #{peek b3RevoluteJointDef, upperAngle} p <*> #{peek b3RevoluteJointDef, enableMotor} p <*> #{peek b3RevoluteJointDef, maxMotorTorque} p <*> #{peek b3RevoluteJointDef, motorSpeed} p poke p x = do #{poke b3RevoluteJointDef, base} p (revoluteJointDefBase x) #{poke b3RevoluteJointDef, targetAngle} p (revoluteJointDefTargetAngle x) #{poke b3RevoluteJointDef, enableSpring} p (revoluteJointDefEnableSpring x) #{poke b3RevoluteJointDef, hertz} p (revoluteJointDefHertz x) #{poke b3RevoluteJointDef, dampingRatio} p (revoluteJointDefDampingRatio x) #{poke b3RevoluteJointDef, enableLimit} p (revoluteJointDefEnableLimit x) #{poke b3RevoluteJointDef, lowerAngle} p (revoluteJointDefLowerAngle x) #{poke b3RevoluteJointDef, upperAngle} p (revoluteJointDefUpperAngle x) #{poke b3RevoluteJointDef, enableMotor} p (revoluteJointDefEnableMotor x) #{poke b3RevoluteJointDef, maxMotorTorque} p (revoluteJointDefMaxMotorTorque x) #{poke b3RevoluteJointDef, motorSpeed} p (revoluteJointDefMotorSpeed x) -- | Spherical joint definition. Initialise with 'defaultSphericalJointDef'. data SphericalJointDef = SphericalJointDef { sphericalJointDefBase :: JointDef , sphericalJointDefEnableSpring :: CBool , sphericalJointDefHertz :: Float , sphericalJointDefDampingRatio :: Float , sphericalJointDefTargetRotation :: Quat , sphericalJointDefEnableConeLimit :: CBool , sphericalJointDefConeAngle :: Float , sphericalJointDefEnableTwistLimit :: CBool , sphericalJointDefLowerTwistAngle :: Float , sphericalJointDefUpperTwistAngle :: Float , sphericalJointDefEnableMotor :: CBool , sphericalJointDefMaxMotorTorque :: Float , sphericalJointDefMotorVelocity :: Vec3 } deriving (Eq, Show) instance Storable SphericalJointDef where sizeOf _ = #{size b3SphericalJointDef} alignment _ = #{alignment b3SphericalJointDef} peek p = SphericalJointDef <$> #{peek b3SphericalJointDef, base} p <*> #{peek b3SphericalJointDef, enableSpring} p <*> #{peek b3SphericalJointDef, hertz} p <*> #{peek b3SphericalJointDef, dampingRatio} p <*> #{peek b3SphericalJointDef, targetRotation} p <*> #{peek b3SphericalJointDef, enableConeLimit} p <*> #{peek b3SphericalJointDef, coneAngle} p <*> #{peek b3SphericalJointDef, enableTwistLimit} p <*> #{peek b3SphericalJointDef, lowerTwistAngle} p <*> #{peek b3SphericalJointDef, upperTwistAngle} p <*> #{peek b3SphericalJointDef, enableMotor} p <*> #{peek b3SphericalJointDef, maxMotorTorque} p <*> #{peek b3SphericalJointDef, motorVelocity} p poke p x = do #{poke b3SphericalJointDef, base} p (sphericalJointDefBase x) #{poke b3SphericalJointDef, enableSpring} p (sphericalJointDefEnableSpring x) #{poke b3SphericalJointDef, hertz} p (sphericalJointDefHertz x) #{poke b3SphericalJointDef, dampingRatio} p (sphericalJointDefDampingRatio x) #{poke b3SphericalJointDef, targetRotation} p (sphericalJointDefTargetRotation x) #{poke b3SphericalJointDef, enableConeLimit} p (sphericalJointDefEnableConeLimit x) #{poke b3SphericalJointDef, coneAngle} p (sphericalJointDefConeAngle x) #{poke b3SphericalJointDef, enableTwistLimit} p (sphericalJointDefEnableTwistLimit x) #{poke b3SphericalJointDef, lowerTwistAngle} p (sphericalJointDefLowerTwistAngle x) #{poke b3SphericalJointDef, upperTwistAngle} p (sphericalJointDefUpperTwistAngle x) #{poke b3SphericalJointDef, enableMotor} p (sphericalJointDefEnableMotor x) #{poke b3SphericalJointDef, maxMotorTorque} p (sphericalJointDefMaxMotorTorque x) #{poke b3SphericalJointDef, motorVelocity} p (sphericalJointDefMotorVelocity x) -- | Weld joint definition. Initialise with 'defaultWeldJointDef'. data WeldJointDef = WeldJointDef { weldJointDefBase :: JointDef , weldJointDefLinearHertz :: Float , weldJointDefAngularHertz :: Float , weldJointDefLinearDampingRatio :: Float , weldJointDefAngularDampingRatio :: Float } deriving (Eq, Show) instance Storable WeldJointDef where sizeOf _ = #{size b3WeldJointDef} alignment _ = #{alignment b3WeldJointDef} peek p = WeldJointDef <$> #{peek b3WeldJointDef, base} p <*> #{peek b3WeldJointDef, linearHertz} p <*> #{peek b3WeldJointDef, angularHertz} p <*> #{peek b3WeldJointDef, linearDampingRatio} p <*> #{peek b3WeldJointDef, angularDampingRatio} p poke p x = do #{poke b3WeldJointDef, base} p (weldJointDefBase x) #{poke b3WeldJointDef, linearHertz} p (weldJointDefLinearHertz x) #{poke b3WeldJointDef, angularHertz} p (weldJointDefAngularHertz x) #{poke b3WeldJointDef, linearDampingRatio} p (weldJointDefLinearDampingRatio x) #{poke b3WeldJointDef, angularDampingRatio} p (weldJointDefAngularDampingRatio x) -- | Wheel joint definition. Initialise with 'defaultWheelJointDef'. data WheelJointDef = WheelJointDef { wheelJointDefBase :: JointDef , wheelJointDefEnableSuspensionSpring :: CBool , wheelJointDefSuspensionHertz :: Float , wheelJointDefSuspensionDampingRatio :: Float , wheelJointDefEnableSuspensionLimit :: CBool , wheelJointDefLowerSuspensionLimit :: Float , wheelJointDefUpperSuspensionLimit :: Float , wheelJointDefEnableSpinMotor :: CBool , wheelJointDefMaxSpinTorque :: Float , wheelJointDefSpinSpeed :: Float , wheelJointDefEnableSteering :: CBool , wheelJointDefSteeringHertz :: Float , wheelJointDefSteeringDampingRatio :: Float , wheelJointDefTargetSteeringAngle :: Float , wheelJointDefMaxSteeringTorque :: Float , wheelJointDefEnableSteeringLimit :: CBool , wheelJointDefLowerSteeringLimit :: Float , wheelJointDefUpperSteeringLimit :: Float } deriving (Eq, Show) instance Storable WheelJointDef where sizeOf _ = #{size b3WheelJointDef} alignment _ = #{alignment b3WheelJointDef} peek p = WheelJointDef <$> #{peek b3WheelJointDef, base} p <*> #{peek b3WheelJointDef, enableSuspensionSpring} p <*> #{peek b3WheelJointDef, suspensionHertz} p <*> #{peek b3WheelJointDef, suspensionDampingRatio} p <*> #{peek b3WheelJointDef, enableSuspensionLimit} p <*> #{peek b3WheelJointDef, lowerSuspensionLimit} p <*> #{peek b3WheelJointDef, upperSuspensionLimit} p <*> #{peek b3WheelJointDef, enableSpinMotor} p <*> #{peek b3WheelJointDef, maxSpinTorque} p <*> #{peek b3WheelJointDef, spinSpeed} p <*> #{peek b3WheelJointDef, enableSteering} p <*> #{peek b3WheelJointDef, steeringHertz} p <*> #{peek b3WheelJointDef, steeringDampingRatio} p <*> #{peek b3WheelJointDef, targetSteeringAngle} p <*> #{peek b3WheelJointDef, maxSteeringTorque} p <*> #{peek b3WheelJointDef, enableSteeringLimit} p <*> #{peek b3WheelJointDef, lowerSteeringLimit} p <*> #{peek b3WheelJointDef, upperSteeringLimit} p poke p x = do #{poke b3WheelJointDef, base} p (wheelJointDefBase x) #{poke b3WheelJointDef, enableSuspensionSpring} p (wheelJointDefEnableSuspensionSpring x) #{poke b3WheelJointDef, suspensionHertz} p (wheelJointDefSuspensionHertz x) #{poke b3WheelJointDef, suspensionDampingRatio} p (wheelJointDefSuspensionDampingRatio x) #{poke b3WheelJointDef, enableSuspensionLimit} p (wheelJointDefEnableSuspensionLimit x) #{poke b3WheelJointDef, lowerSuspensionLimit} p (wheelJointDefLowerSuspensionLimit x) #{poke b3WheelJointDef, upperSuspensionLimit} p (wheelJointDefUpperSuspensionLimit x) #{poke b3WheelJointDef, enableSpinMotor} p (wheelJointDefEnableSpinMotor x) #{poke b3WheelJointDef, maxSpinTorque} p (wheelJointDefMaxSpinTorque x) #{poke b3WheelJointDef, spinSpeed} p (wheelJointDefSpinSpeed x) #{poke b3WheelJointDef, enableSteering} p (wheelJointDefEnableSteering x) #{poke b3WheelJointDef, steeringHertz} p (wheelJointDefSteeringHertz x) #{poke b3WheelJointDef, steeringDampingRatio} p (wheelJointDefSteeringDampingRatio x) #{poke b3WheelJointDef, targetSteeringAngle} p (wheelJointDefTargetSteeringAngle x) #{poke b3WheelJointDef, maxSteeringTorque} p (wheelJointDefMaxSteeringTorque x) #{poke b3WheelJointDef, enableSteeringLimit} p (wheelJointDefEnableSteeringLimit x) #{poke b3WheelJointDef, lowerSteeringLimit} p (wheelJointDefLowerSteeringLimit x) #{poke b3WheelJointDef, upperSteeringLimit} p (wheelJointDefUpperSteeringLimit x) -- | Filter joint definition. Initialise with 'defaultFilterJointDef'. data FilterJointDef = FilterJointDef { filterJointDefBase :: JointDef } deriving (Eq, Show) instance Storable FilterJointDef where sizeOf _ = #{size b3FilterJointDef} alignment _ = #{alignment b3FilterJointDef} peek p = FilterJointDef <$> #{peek b3FilterJointDef, base} p poke p x = do #{poke b3FilterJointDef, base} p (filterJointDefBase x) -- Joint definition defaults ---------------------------------------------- foreign import ccall unsafe "hs_b3DefaultDistanceJointDef" c_b3DefaultDistanceJointDef :: Ptr DistanceJointDef -> IO () foreign import ccall unsafe "hs_b3DefaultMotorJointDef" c_b3DefaultMotorJointDef :: Ptr MotorJointDef -> IO () foreign import ccall unsafe "hs_b3DefaultParallelJointDef" c_b3DefaultParallelJointDef :: Ptr ParallelJointDef -> IO () foreign import ccall unsafe "hs_b3DefaultPrismaticJointDef" c_b3DefaultPrismaticJointDef :: Ptr PrismaticJointDef -> IO () foreign import ccall unsafe "hs_b3DefaultRevoluteJointDef" c_b3DefaultRevoluteJointDef :: Ptr RevoluteJointDef -> IO () foreign import ccall unsafe "hs_b3DefaultSphericalJointDef" c_b3DefaultSphericalJointDef :: Ptr SphericalJointDef -> IO () foreign import ccall unsafe "hs_b3DefaultWeldJointDef" c_b3DefaultWeldJointDef :: Ptr WeldJointDef -> IO () foreign import ccall unsafe "hs_b3DefaultWheelJointDef" c_b3DefaultWheelJointDef :: Ptr WheelJointDef -> IO () foreign import ccall unsafe "hs_b3DefaultFilterJointDef" c_b3DefaultFilterJointDef :: Ptr FilterJointDef -> IO () -- | A fully-initialised DistanceJointDef. defaultDistanceJointDef :: IO DistanceJointDef defaultDistanceJointDef = allocaOut c_b3DefaultDistanceJointDef -- | A fully-initialised MotorJointDef. defaultMotorJointDef :: IO MotorJointDef defaultMotorJointDef = allocaOut c_b3DefaultMotorJointDef -- | A fully-initialised ParallelJointDef. defaultParallelJointDef :: IO ParallelJointDef defaultParallelJointDef = allocaOut c_b3DefaultParallelJointDef -- | A fully-initialised PrismaticJointDef. defaultPrismaticJointDef :: IO PrismaticJointDef defaultPrismaticJointDef = allocaOut c_b3DefaultPrismaticJointDef -- | A fully-initialised RevoluteJointDef. defaultRevoluteJointDef :: IO RevoluteJointDef defaultRevoluteJointDef = allocaOut c_b3DefaultRevoluteJointDef -- | A fully-initialised SphericalJointDef. defaultSphericalJointDef :: IO SphericalJointDef defaultSphericalJointDef = allocaOut c_b3DefaultSphericalJointDef -- | A fully-initialised WeldJointDef. defaultWeldJointDef :: IO WeldJointDef defaultWeldJointDef = allocaOut c_b3DefaultWeldJointDef -- | A fully-initialised WheelJointDef. defaultWheelJointDef :: IO WheelJointDef defaultWheelJointDef = allocaOut c_b3DefaultWheelJointDef -- | A fully-initialised FilterJointDef. defaultFilterJointDef :: IO FilterJointDef defaultFilterJointDef = allocaOut c_b3DefaultFilterJointDef -- Queries and casts -------------------------------------------------------- foreign import ccall unsafe "hs_b3DefaultQueryFilter" c_b3DefaultQueryFilter :: Ptr QueryFilter -> IO () -- | Filter for world queries: which shape categories to accept. The optional -- @id@ / @name@ pair tags the query in a recording; a 'nullPtr' name means -- untagged. data QueryFilter = QueryFilter { queryFilterCategoryBits :: Word64 , queryFilterMaskBits :: Word64 , queryFilterId :: Word64 , queryFilterName :: CString } deriving (Eq, Show) instance Storable QueryFilter where sizeOf _ = #{size b3QueryFilter} alignment _ = #{alignment b3QueryFilter} peek p = QueryFilter <$> #{peek b3QueryFilter, categoryBits} p <*> #{peek b3QueryFilter, maskBits} p <*> #{peek b3QueryFilter, id} p <*> #{peek b3QueryFilter, name} p poke p x = do #{poke b3QueryFilter, categoryBits} p (queryFilterCategoryBits x) #{poke b3QueryFilter, maskBits} p (queryFilterMaskBits x) #{poke b3QueryFilter, id} p (queryFilterId x) #{poke b3QueryFilter, name} p (queryFilterName x) -- | A fully-initialised query filter (accept everything, untagged). defaultQueryFilter :: IO QueryFilter defaultQueryFilter = allocaOut c_b3DefaultQueryFilter -- | The mass, centroid and inertia tensor of a shape or body. data MassData = MassData { massDataMass :: Float , massDataCenter :: Vec3 , massDataInertia :: Matrix3 } deriving (Eq, Show) instance Storable MassData where sizeOf _ = #{size b3MassData} alignment _ = #{alignment b3MassData} peek p = MassData <$> #{peek b3MassData, mass} p <*> #{peek b3MassData, center} p <*> #{peek b3MassData, inertia} p poke p x = do #{poke b3MassData, mass} p (massDataMass x) #{poke b3MassData, center} p (massDataCenter x) #{poke b3MassData, inertia} p (massDataInertia x) -- | Low-level ray-cast input in the local frame of the target shape. data RayCastInput = RayCastInput { rayCastInputOrigin :: Vec3 , rayCastInputTranslation :: Vec3 , rayCastInputMaxFraction :: Float } deriving (Eq, Show) instance Storable RayCastInput where sizeOf _ = #{size b3RayCastInput} alignment _ = #{alignment b3RayCastInput} peek p = RayCastInput <$> #{peek b3RayCastInput, origin} p <*> #{peek b3RayCastInput, translation} p <*> #{peek b3RayCastInput, maxFraction} p poke p x = do #{poke b3RayCastInput, origin} p (rayCastInputOrigin x) #{poke b3RayCastInput, translation} p (rayCastInputTranslation x) #{poke b3RayCastInput, maxFraction} p (rayCastInputMaxFraction x) -- | Low-level ray or shape-cast output, in the frame of the input. A zero -- fraction and normal signal initial overlap. The triangle\/child\/material -- indices are -1 when not applicable. data CastOutput = CastOutput { castOutputNormal :: Vec3 , castOutputPoint :: Vec3 , castOutputFraction :: Float , castOutputIterations :: CInt , castOutputTriangleIndex :: CInt , castOutputChildIndex :: CInt , castOutputMaterialIndex :: CInt , castOutputHit :: CBool } deriving (Eq, Show) instance Storable CastOutput where sizeOf _ = #{size b3CastOutput} alignment _ = #{alignment b3CastOutput} peek p = CastOutput <$> #{peek b3CastOutput, normal} p <*> #{peek b3CastOutput, point} p <*> #{peek b3CastOutput, fraction} p <*> #{peek b3CastOutput, iterations} p <*> #{peek b3CastOutput, triangleIndex} p <*> #{peek b3CastOutput, childIndex} p <*> #{peek b3CastOutput, materialIndex} p <*> #{peek b3CastOutput, hit} p poke p x = do #{poke b3CastOutput, normal} p (castOutputNormal x) #{poke b3CastOutput, point} p (castOutputPoint x) #{poke b3CastOutput, fraction} p (castOutputFraction x) #{poke b3CastOutput, iterations} p (castOutputIterations x) #{poke b3CastOutput, triangleIndex} p (castOutputTriangleIndex x) #{poke b3CastOutput, childIndex} p (castOutputChildIndex x) #{poke b3CastOutput, materialIndex} p (castOutputMaterialIndex x) #{poke b3CastOutput, hit} p (castOutputHit x) -- | World-space cast output. In single-precision builds (the default) this is -- the same struct as 'CastOutput'. type WorldCastOutput = CastOutput -- | The closest hit of a world ray cast ('Box3D.World.castRayClosest'). data RayResult = RayResult { rayResultShapeId :: ShapeId , rayResultPoint :: Pos , rayResultNormal :: Vec3 , rayResultUserMaterialId :: Word64 , rayResultFraction :: Float , rayResultTriangleIndex :: CInt , rayResultChildIndex :: CInt , rayResultNodeVisits :: CInt , rayResultLeafVisits :: CInt , rayResultHit :: CBool } deriving (Eq, Show) instance Storable RayResult where sizeOf _ = #{size b3RayResult} alignment _ = #{alignment b3RayResult} peek p = RayResult <$> #{peek b3RayResult, shapeId} p <*> #{peek b3RayResult, point} p <*> #{peek b3RayResult, normal} p <*> #{peek b3RayResult, userMaterialId} p <*> #{peek b3RayResult, fraction} p <*> #{peek b3RayResult, triangleIndex} p <*> #{peek b3RayResult, childIndex} p <*> #{peek b3RayResult, nodeVisits} p <*> #{peek b3RayResult, leafVisits} p <*> #{peek b3RayResult, hit} p poke p x = do #{poke b3RayResult, shapeId} p (rayResultShapeId x) #{poke b3RayResult, point} p (rayResultPoint x) #{poke b3RayResult, normal} p (rayResultNormal x) #{poke b3RayResult, userMaterialId} p (rayResultUserMaterialId x) #{poke b3RayResult, fraction} p (rayResultFraction x) #{poke b3RayResult, triangleIndex} p (rayResultTriangleIndex x) #{poke b3RayResult, childIndex} p (rayResultChildIndex x) #{poke b3RayResult, nodeVisits} p (rayResultNodeVisits x) #{poke b3RayResult, leafVisits} p (rayResultLeafVisits x) #{poke b3RayResult, hit} p (rayResultHit x) -- | Broad-phase traversal counters for a query. Diagnostic. data TreeStats = TreeStats { treeStatsNodeVisits :: CInt , treeStatsLeafVisits :: CInt } deriving (Eq, Show) instance Storable TreeStats where sizeOf _ = #{size b3TreeStats} alignment _ = #{alignment b3TreeStats} peek p = TreeStats <$> #{peek b3TreeStats, nodeVisits} p <*> #{peek b3TreeStats, leafVisits} p poke p x = do #{poke b3TreeStats, nodeVisits} p (treeStatsNodeVisits x) #{poke b3TreeStats, leafVisits} p (treeStatsLeafVisits x) -- | The motion of a body between two configurations, for TOI computation. data Sweep = Sweep { sweepLocalCenter :: Vec3 , sweepC1 :: Vec3 , sweepC2 :: Vec3 , sweepQ1 :: Quat , sweepQ2 :: Quat } deriving (Eq, Show) instance Storable Sweep where sizeOf _ = #{size b3Sweep} alignment _ = #{alignment b3Sweep} peek p = Sweep <$> #{peek b3Sweep, localCenter} p <*> #{peek b3Sweep, c1} p <*> #{peek b3Sweep, c2} p <*> #{peek b3Sweep, q1} p <*> #{peek b3Sweep, q2} p poke p x = do #{poke b3Sweep, localCenter} p (sweepLocalCenter x) #{poke b3Sweep, c1} p (sweepC1 x) #{poke b3Sweep, c2} p (sweepC2 x) #{poke b3Sweep, q1} p (sweepQ1 x) #{poke b3Sweep, q2} p (sweepQ2 x) -- | One collision plane from 'Box3D.World.collideMover', relative to the -- query origin. data PlaneResult = PlaneResult { planeResultPlane :: Plane , planeResultPoint :: Vec3 } deriving (Eq, Show) instance Storable PlaneResult where sizeOf _ = #{size b3PlaneResult} alignment _ = #{alignment b3PlaneResult} peek p = PlaneResult <$> #{peek b3PlaneResult, plane} p <*> #{peek b3PlaneResult, point} p poke p x = do #{poke b3PlaneResult, plane} p (planeResultPlane x) #{poke b3PlaneResult, point} p (planeResultPoint x) -- | The size of the (opaque) @b3DynamicTree@ struct, for allocating one to -- initialise with 'Box3D.DynamicTree.create'. dynamicTreeByteCount :: Int dynamicTreeByteCount = #{size b3DynamicTree} -- Events ------------------------------------------------------------------ -- | A body move event: the new transform of a body that moved this step. -- Read after 'Box3D.World.step' and before the next step (see "Box3D.Events"). data BodyMoveEvent = BodyMoveEvent { bodyMoveEventUserData :: Ptr () , bodyMoveEventTransform :: Transform , bodyMoveEventBodyId :: BodyId , bodyMoveEventFellAsleep :: CBool } deriving (Eq, Show) instance Storable BodyMoveEvent where sizeOf _ = #{size b3BodyMoveEvent} alignment _ = #{alignment b3BodyMoveEvent} peek p = BodyMoveEvent <$> #{peek b3BodyMoveEvent, userData} p <*> #{peek b3BodyMoveEvent, transform} p <*> #{peek b3BodyMoveEvent, bodyId} p <*> #{peek b3BodyMoveEvent, fellAsleep} p poke p x = do #{poke b3BodyMoveEvent, userData} p (bodyMoveEventUserData x) #{poke b3BodyMoveEvent, transform} p (bodyMoveEventTransform x) #{poke b3BodyMoveEvent, bodyId} p (bodyMoveEventBodyId x) #{poke b3BodyMoveEvent, fellAsleep} p (bodyMoveEventFellAsleep x) -- | Body events buffer: a C-owned array of 'BodyMoveEvent' valid until the -- next 'Box3D.World.step'. Marshalled to a list by "Box3D.Events". data BodyEvents = BodyEvents { bodyEventsMoveEvents :: Ptr BodyMoveEvent , bodyEventsMoveCount :: CInt } deriving (Eq, Show) instance Storable BodyEvents where sizeOf _ = #{size b3BodyEvents} alignment _ = #{alignment b3BodyEvents} peek p = BodyEvents <$> #{peek b3BodyEvents, moveEvents} p <*> #{peek b3BodyEvents, moveCount} p poke p x = do #{poke b3BodyEvents, moveEvents} p (bodyEventsMoveEvents x) #{poke b3BodyEvents, moveCount} p (bodyEventsMoveCount x) -- | A shape started overlapping a sensor shape. data SensorBeginTouchEvent = SensorBeginTouchEvent { sensorBeginTouchEventSensorShapeId :: ShapeId , sensorBeginTouchEventVisitorShapeId :: ShapeId } deriving (Eq, Show) instance Storable SensorBeginTouchEvent where sizeOf _ = #{size b3SensorBeginTouchEvent} alignment _ = #{alignment b3SensorBeginTouchEvent} peek p = SensorBeginTouchEvent <$> #{peek b3SensorBeginTouchEvent, sensorShapeId} p <*> #{peek b3SensorBeginTouchEvent, visitorShapeId} p poke p x = do #{poke b3SensorBeginTouchEvent, sensorShapeId} p (sensorBeginTouchEventSensorShapeId x) #{poke b3SensorBeginTouchEvent, visitorShapeId} p (sensorBeginTouchEventVisitorShapeId x) -- | A shape stopped overlapping a sensor shape. Either shape may already be -- destroyed; check with @Box3D.Shape.isValid@. data SensorEndTouchEvent = SensorEndTouchEvent { sensorEndTouchEventSensorShapeId :: ShapeId , sensorEndTouchEventVisitorShapeId :: ShapeId } deriving (Eq, Show) instance Storable SensorEndTouchEvent where sizeOf _ = #{size b3SensorEndTouchEvent} alignment _ = #{alignment b3SensorEndTouchEvent} peek p = SensorEndTouchEvent <$> #{peek b3SensorEndTouchEvent, sensorShapeId} p <*> #{peek b3SensorEndTouchEvent, visitorShapeId} p poke p x = do #{poke b3SensorEndTouchEvent, sensorShapeId} p (sensorEndTouchEventSensorShapeId x) #{poke b3SensorEndTouchEvent, visitorShapeId} p (sensorEndTouchEventVisitorShapeId x) -- | Sensor events buffer: C-owned begin/end arrays valid until the next -- 'Box3D.World.step'. Marshalled to lists by "Box3D.Events". data SensorEvents = SensorEvents { sensorEventsBeginEvents :: Ptr SensorBeginTouchEvent , sensorEventsEndEvents :: Ptr SensorEndTouchEvent , sensorEventsBeginCount :: CInt , sensorEventsEndCount :: CInt } deriving (Eq, Show) instance Storable SensorEvents where sizeOf _ = #{size b3SensorEvents} alignment _ = #{alignment b3SensorEvents} peek p = SensorEvents <$> #{peek b3SensorEvents, beginEvents} p <*> #{peek b3SensorEvents, endEvents} p <*> #{peek b3SensorEvents, beginCount} p <*> #{peek b3SensorEvents, endCount} p poke p x = do #{poke b3SensorEvents, beginEvents} p (sensorEventsBeginEvents x) #{poke b3SensorEvents, endEvents} p (sensorEventsEndEvents x) #{poke b3SensorEvents, beginCount} p (sensorEventsBeginCount x) #{poke b3SensorEvents, endCount} p (sensorEventsEndCount x) -- | Two shapes began touching. data ContactBeginTouchEvent = ContactBeginTouchEvent { contactBeginTouchEventShapeIdA :: ShapeId , contactBeginTouchEventShapeIdB :: ShapeId , contactBeginTouchEventContactId :: ContactId } deriving (Eq, Show) instance Storable ContactBeginTouchEvent where sizeOf _ = #{size b3ContactBeginTouchEvent} alignment _ = #{alignment b3ContactBeginTouchEvent} peek p = ContactBeginTouchEvent <$> #{peek b3ContactBeginTouchEvent, shapeIdA} p <*> #{peek b3ContactBeginTouchEvent, shapeIdB} p <*> #{peek b3ContactBeginTouchEvent, contactId} p poke p x = do #{poke b3ContactBeginTouchEvent, shapeIdA} p (contactBeginTouchEventShapeIdA x) #{poke b3ContactBeginTouchEvent, shapeIdB} p (contactBeginTouchEventShapeIdB x) #{poke b3ContactBeginTouchEvent, contactId} p (contactBeginTouchEventContactId x) -- | Two shapes stopped touching. The shapes and the contact may already be -- destroyed; check with the respective @isValid@. data ContactEndTouchEvent = ContactEndTouchEvent { contactEndTouchEventShapeIdA :: ShapeId , contactEndTouchEventShapeIdB :: ShapeId , contactEndTouchEventContactId :: ContactId } deriving (Eq, Show) instance Storable ContactEndTouchEvent where sizeOf _ = #{size b3ContactEndTouchEvent} alignment _ = #{alignment b3ContactEndTouchEvent} peek p = ContactEndTouchEvent <$> #{peek b3ContactEndTouchEvent, shapeIdA} p <*> #{peek b3ContactEndTouchEvent, shapeIdB} p <*> #{peek b3ContactEndTouchEvent, contactId} p poke p x = do #{poke b3ContactEndTouchEvent, shapeIdA} p (contactEndTouchEventShapeIdA x) #{poke b3ContactEndTouchEvent, shapeIdB} p (contactEndTouchEventShapeIdB x) #{poke b3ContactEndTouchEvent, contactId} p (contactEndTouchEventContactId x) -- | Two shapes collided faster than the hit speed threshold -- (@worldDefHitEventThreshold@; hit events must be enabled per shape). data ContactHitEvent = ContactHitEvent { contactHitEventShapeIdA :: ShapeId , contactHitEventShapeIdB :: ShapeId , contactHitEventContactId :: ContactId , contactHitEventPoint :: Pos , contactHitEventNormal :: Vec3 , contactHitEventApproachSpeed :: Float , contactHitEventUserMaterialIdA :: Word64 , contactHitEventUserMaterialIdB :: Word64 } deriving (Eq, Show) instance Storable ContactHitEvent where sizeOf _ = #{size b3ContactHitEvent} alignment _ = #{alignment b3ContactHitEvent} peek p = ContactHitEvent <$> #{peek b3ContactHitEvent, shapeIdA} p <*> #{peek b3ContactHitEvent, shapeIdB} p <*> #{peek b3ContactHitEvent, contactId} p <*> #{peek b3ContactHitEvent, point} p <*> #{peek b3ContactHitEvent, normal} p <*> #{peek b3ContactHitEvent, approachSpeed} p <*> #{peek b3ContactHitEvent, userMaterialIdA} p <*> #{peek b3ContactHitEvent, userMaterialIdB} p poke p x = do #{poke b3ContactHitEvent, shapeIdA} p (contactHitEventShapeIdA x) #{poke b3ContactHitEvent, shapeIdB} p (contactHitEventShapeIdB x) #{poke b3ContactHitEvent, contactId} p (contactHitEventContactId x) #{poke b3ContactHitEvent, point} p (contactHitEventPoint x) #{poke b3ContactHitEvent, normal} p (contactHitEventNormal x) #{poke b3ContactHitEvent, approachSpeed} p (contactHitEventApproachSpeed x) #{poke b3ContactHitEvent, userMaterialIdA} p (contactHitEventUserMaterialIdA x) #{poke b3ContactHitEvent, userMaterialIdB} p (contactHitEventUserMaterialIdB x) -- | Contact events buffer: C-owned begin/end/hit arrays valid until the next -- 'Box3D.World.step'. Marshalled to lists by "Box3D.Events". data ContactEvents = ContactEvents { contactEventsBeginEvents :: Ptr ContactBeginTouchEvent , contactEventsEndEvents :: Ptr ContactEndTouchEvent , contactEventsHitEvents :: Ptr ContactHitEvent , contactEventsBeginCount :: CInt , contactEventsEndCount :: CInt , contactEventsHitCount :: CInt } deriving (Eq, Show) instance Storable ContactEvents where sizeOf _ = #{size b3ContactEvents} alignment _ = #{alignment b3ContactEvents} peek p = ContactEvents <$> #{peek b3ContactEvents, beginEvents} p <*> #{peek b3ContactEvents, endEvents} p <*> #{peek b3ContactEvents, hitEvents} p <*> #{peek b3ContactEvents, beginCount} p <*> #{peek b3ContactEvents, endCount} p <*> #{peek b3ContactEvents, hitCount} p poke p x = do #{poke b3ContactEvents, beginEvents} p (contactEventsBeginEvents x) #{poke b3ContactEvents, endEvents} p (contactEventsEndEvents x) #{poke b3ContactEvents, hitEvents} p (contactEventsHitEvents x) #{poke b3ContactEvents, beginCount} p (contactEventsBeginCount x) #{poke b3ContactEvents, endCount} p (contactEventsEndCount x) #{poke b3ContactEvents, hitCount} p (contactEventsHitCount x) -- | A joint exceeded its force/torque event threshold this step. data JointEvent = JointEvent { jointEventJointId :: JointId , jointEventUserData :: Ptr () } deriving (Eq, Show) instance Storable JointEvent where sizeOf _ = #{size b3JointEvent} alignment _ = #{alignment b3JointEvent} peek p = JointEvent <$> #{peek b3JointEvent, jointId} p <*> #{peek b3JointEvent, userData} p poke p x = do #{poke b3JointEvent, jointId} p (jointEventJointId x) #{poke b3JointEvent, userData} p (jointEventUserData x) -- | Joint events buffer: a C-owned array of 'JointEvent' valid until the next -- 'Box3D.World.step'. Marshalled to a list by "Box3D.Events". data JointEvents = JointEvents { jointEventsJointEvents :: Ptr JointEvent , jointEventsCount :: CInt } deriving (Eq, Show) instance Storable JointEvents where sizeOf _ = #{size b3JointEvents} alignment _ = #{alignment b3JointEvents} peek p = JointEvents <$> #{peek b3JointEvents, jointEvents} p <*> #{peek b3JointEvents, count} p poke p x = do #{poke b3JointEvents, jointEvents} p (jointEventsJointEvents x) #{poke b3JointEvents, count} p (jointEventsCount x)