chiphunk-0.1.0.0: src/Chiphunk/Low.hs
-- | Description: Low-level Haskell bindings to Chipmunk2D physics library
-- Chiphunk is a __low-level__ Haskell bindings for the <https://chipmunk-physics.net/ Chipmunk2D physics engine>.
-- It includes most (almost all) of the functions mentioned in the main documentation for Chipmunk2D,
-- except for some (relatively) exotic ones, which may be added later per request.
module Chiphunk.Low
( -- * Disclaymer
-- | This bindings are so low-level so that they even require you to free the memory the Chipmunk2D has allocated
-- for your objects. Module with more high-level api can be built around this low-level bingings at some point,
-- in the meantime, however, you're advised to provide wrapper layer for your games so that you do not have to
-- keep track of such things in the core of your game's logic.
--
-- See below for an adoptation of the original Chipmunk documentation available
-- <https://chipmunk-physics.net/release/ChipmunkLatest-Docs/ here>. I've skipped some sections not related
-- to the bindings, like the reason author chose C language in the first place and limitations of the C api.
-- Obviously, it's thanks to that choice that I was able to write bindings around the library in Haskell.
--
-- __Howling Moon Software is not affiliated with this bindings.__
-- __In all of the following \"I\" refers to the original documentation author for Chipmunk2D.__
-- * Chipmunk2D 7.0.2
-- | Chipmunk2D is a 2D rigid body physics library distributed under the MIT license.
-- It is blazingly fast, portable, numerically stable, and easy to use.
-- For this reason it has been used in hundreds of games across just about every system you can name.
-- This includes top quality titles such as Night Sky for the Wii and many #1 sellers on the iPhone App Store!
-- I’ve put thousands of hours of work over many years to make Chipmunk2D what it is today.
-- If you find Chipmunk2D has saved you a lot of time, please consider
-- <https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_id=6666552 donating>.
-- You’ll make an indie game developer very happy!
-- | First of all, I would like to give a Erin Catto a big thank you, as Chipmunk2D’s impulse solver
-- was directly inspired by his example code way back in 2006.
-- (Now a full fledged physics engine all its own: <http://www.box2d.org/ Box2D.org>).
-- His contact persistence idea allows for stable stacks of objects with very few iterations of the solver.
-- My previous solver produced mushy piles of objects or required a large amount of CPU to operate stably.
-- ** Support
-- | The best way to get support is to visit the <http://www.slembcke.net/forums/viewforum.php?f=1 Chipmunk Forums>.
-- There are plenty of people around using Chipmunk on the just about every platform
-- I’ve ever heard of. If you are working on a commercial project, Howling Moon Software
-- (my company) is <http://howlingmoonsoftware.com/contracting.php available for contracting>.
-- We can help with implementing custom Chipmunk behaviors,
-- as well as priority bug fixes and performance tuning.
-- ** Contact
-- | If you find any bugs in Chipmunk, errors or broken links in this document,
-- or have a question or comment about Chipmunk you can contact me at
-- slembcke(at)gmail(dot)com. (email or GTalk)
-- ** License
-- | Chipmunk is licensed under the MIT license.
--
-- @
-- Copyright (c) 2007-2015 Scott Lembcke and Howling Moon Software
--
-- Permission is hereby granted, free of charge, to any person obtaining a copy
-- of this software and associated documentation files (the "Software"), to deal
-- in the Software without restriction, including without limitation the rights
-- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-- copies of the Software, and to permit persons to whom the Software is
-- furnished to do so, subject to the following conditions:
--
-- The above copyright notice and this permission notice shall be included in
-- all copies or substantial portions of the Software.
--
-- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-- SOFTWARE.
-- @
--
-- This means that you do not have to buy a license or pay to use Chipmunk in commercial projects. (Though we really appreciate donations)
-- ** Links
-- |
-- * <http://chipmunk2d.net/forum Chipmunk Forums> – The official forum Chipmunk2D forum.
--
-- * <http://howlingmoonsoftware.com/ Howling Moon Software> – The software company I co-founded.
-- (We are available for contract work!)
--
-- * <http://chipmunk2d.net/games.php Games> – A small list of games we know that use Chipmunk.
-- * Hello Chipmunk (World)
-- | Hello world Chipmunk style. Create a simple simulation where a ball falls onto a static line segment,
-- then rolls off. Print out the coordinates of the ball.
--
-- @
-- main :: IO ()
-- main = do
-- let gravity = 'Vect' 0 (-100)
--
-- -- Create an empty space.
-- space <- 'spaceNew'
-- 'spaceGravity' space $= gravity
--
-- -- Add a static line segment shape for the ground.
-- -- We'll make it slightly tilted so the ball will roll off.
-- -- We attach it to a static body to tell Chipmunk it shouldn't be movable.
-- static <- get $ 'spaceStaticBody' space
-- ground <- 'segmentShapeNew' static (Vect (-20) 5) (Vect 20 (-5)) 0
-- 'shapeFriction' ground $= 1
-- 'spaceAddShape' space ground
--
-- -- Now let's make a ball that falls onto the line and rolls off.
-- -- First we need to make a cpBody to hold the physical properties of the object.
-- -- These include the mass, position, velocity, angle, etc. of the object.
-- -- Then we attach collision shapes to the 'Body' to give it a size and shape.
--
-- let radius = 5
-- let mass = 1
--
-- -- The moment of inertia is like mass for rotation
-- -- Use the momentFor* functions to help you approximate it.
-- let moment = 'momentForCircle' mass 0 radius (Vect 0 0)
--
-- -- The spaceAdd* functions return the thing that you are adding.
-- ballBody <- 'bodyNew' mass moment
-- 'spaceAddBody' space ballBody
-- 'bodyPosition' ballBody $= Vect 0 15
--
-- -- Now we create the collision shape for the ball.
-- -- You can create multiple collision shapes that point to the same body.
-- -- They will all be attached to the body and move around to follow it.
-- ballShape <- 'circleShapeNew' ballBody radius (Vect 0 0)
-- 'spaceAddShape' space ballShape
-- 'shapeFriction' ballShape $= 0.7
--
-- -- Now that it's all set up, we simulate all the objects in the space by
-- -- stepping forward through time in small increments called steps.
-- -- It is *highly* recommended to use a fixed size time step.
-- let timeStep = 1/60
-- runFor 2 timeStep $ \time -> do
-- pos <- get $ 'bodyPosition' ballBody
-- vel <- get $ 'bodyVelocity' ballBody
-- printf "Time is %4.2f. ballBody is at (%6.2f, %6.2f), it's velocity is (%6.2f, %6.2f).\n"
-- time (vX pos) (vY pos) (vX vel) (vY vel)
--
-- 'spaceStep' space timeStep
--
-- 'shapeFree' ballShape
-- 'bodyFree' ballBody
-- 'shapeFree' ground
-- 'spaceFree' space
-- where
-- runFor time step inner = go time
-- where
-- go time'
-- | time' <= 0 = pure ()
-- | otherwise = inner (time - time') *> go (time' - step)
-- @
-- * Chipmunk2D Basics
-- ** Overview
-- | There are 4 basic object types you will use in Chipmunk.
-- |
-- * __Rigid Bodies__ ('Body'): A rigid body holds the physical properties of an object.
-- (mass, position, rotation, velocity, etc.) It does not have a shape until you attach one or more collision shapes
-- to it. If you’ve done physics with particles before, rigid bodies differ in that they are able to rotate.
-- Rigid bodies generally tend to have a 1:1 correlation to sprites in a game.
-- You should structure your game so that you use the position and rotation of the rigid body
-- for drawing your sprite.
--
-- * __Collision Shapes__ ('Shape'): By attaching shapes to bodies, you can define the a body’s shape.
-- You can attach as many shapes to a single body as you need to in order to define a complex shape.
-- Shapes contain the surface properties of an object such as how much friction or elasticity it has.
--
-- * __Constraints/Joints__ ('Constraint'): Constraints and joints describe how bodies are attached to each other.
--
-- * __Spaces__ ('Space'): Spaces are containers for simulating objects in Chipmunk.
-- You add bodies, shapes and joints to a space and then update the space as a whole.
-- They control how all the rigid bodies, shapes, and constraints interact together.
--
-- There is often confusion between rigid bodies and their collision shapes in Chipmunk
-- and how they relate to sprites. A sprite would be a visual representation of an object,
-- while a collision shape is an invisible property that defines how objects should collide.
-- Both the sprite’s and the collision shape’s position and rotation are controlled by the motion of a rigid body.
-- Generally you want to create a game object type that ties these things all together.
-- ** Memory Management the Chipmunk way
-- | For most of the structures you will use, Chipmunk uses a more or less standard and straightforward set
-- of memory management functions. Take the 'Space' struct for example:
--
-- * 'spaceNew' — Allocates and initializes a 'Space' struct.
--
-- * 'spaceFree' — Destroys and frees the 'Space' struct.
--
-- You are responsible for freeing any structs that you allocate. Chipmunk does not do reference counting or garbage collection. If you call a new function, you must call the matching free function or you will leak memory.
-- ** Math the Chipmunk way
-- | First of all, Chipmunk uses double precision floating point numbers throughout its calculations by default.
-- This is likely to be faster on most modern desktop processors,
-- and means you don’t have to worry as much about floating point accuracy.
--
-- However, there are a few unique functions you will probably find very useful:
fClamp
, fLerp
, fLerpConst
-- * Chipmunk Vectors
-- ** Struct Definition, Constants and Constructors
, Vect (..)
, vZero
, cpv
-- ** Operations
-- | (__Note for bindings__: Most of these are Chipmunk2D-style aliases for 'Vect' typeclasses methods:
-- 'Eq', 'Data.VectorSpace.AdditiveGroup', 'Data.VectorSpace.VectorSpace', 'Data.VectorSpace.InnerSpace',
-- 'Data.Cross.HasCross2')
, vEql
, vAdd
, vSub
, vNeg
, vMult
, vDot
, vCross
, vPerp
, vRPerp
, vProject
, vRotate
, vUnRotate
, vLength
, vLengthSq
, vLerp
, vLerpConst
, vSLerp
, vSLerpConst
, vNormalize
, vClamp
, vDist
, vDistSq
, vNear
, vForAngle
, vToAngle
-- * Chipmunk Axis Aligned Bounding Boxes
-- ** Struct Definition and Constructors
, BB (..)
, bbNew
, bbNewForExtents
, bbNewForCircle
-- ** Operations
, bbIntersects
, bbContainsBB
, bbContainsVect
, bbMerge
, bbExpand
, bbCenter
, bbArea
, bbMergedArea
, bbSegmentQuery
, bbIntersectsSegment
, bbClampVect
, bbWrapVect
-- * Chipmunk Rigid Bodies
, Body
-- ** Dynamic, Kinematic, and Static Bodies
, BodyType (..)
-- ** Movement, Teleportation, and Velocity
-- | A graphics engine only needs to know the position of an object for each frame that its drawn.
-- For a physics engine, this isn’t enough information to calculate a collision response.
-- When you set the position of a body, you are effectively asking it to teleport itself.
-- This means that it will instantly move to its new position instead of moving through space and time
-- like a normal object. If you teleport an object so that it overlaps another one,
-- the best the physics engine can do is to attempt to push the objects apart again
-- since there is no information about their movement. This generally results in very mushy looking collisions.
-- So instead of setting the position of an object, it’s better to set its velocity and allow the physics engine
-- to update the position. That way it can resolve any resulting colisions natuarally since it knows
-- how the objects were moving. This is why kinematic bodies work the way they do.
-- You set the velocity, and the physics updates their position so the two are never out of sync.
--
-- For dynamic bodies, setting the velocity explicitly every frame can cause problems.
-- For example, a problem occurs when a light dynamic body (like a person) is pressed against a heavy dynamic body
-- (like a car), and you set velocity of the small object so that it’s pushing it into the big body.
-- To the physics engine, the change in velocity is the same as applying a large impulse
-- (a very short, very large force). Even if the velocity is low, the large force can allow the small body
-- to push the big body, even when it normally wouldn’t be able to. For example, a person walking into a car
-- can overpower the car’s friction and cause it to creep along the ground slowly.
-- Additionally, when you set the velocity of an object that is already in contact,
-- it can cause the two objects to overlap by a small amount. The easiest way to avoid both of these problems
-- is to make smaller changes to the body’s velocity, accelerating it over a fraction of a second
-- instead of a single frame. An even better solution, which is covered more thoroughly later,
-- is to use constraints to move the object.
-- ** Memory Management Functions
-- | Standard set of Chipmunk memory management functions.
, bodyNew
, bodyNewKinematic
, bodyNewStatic
, bodyFree
-- ** Creating Dynamic Bodies
-- | There are two ways to set up a dynamic body. The easiest option is to create a body
-- with a mass and moment of 0, and set the mass or density of each collision shape added to the body.
-- Chipmunk will automatically calculate the mass, moment of inertia, and center of gravity for you.
-- This is probably preferred in most cases.
--
-- The other option is to set the mass of the body when it’s created, and leave the mass of the shapes
-- added to it as 0.0. This approach is more flexible, but is not as easy to use.
-- __Don’t__ set the mass of both the body and the shapes. If you do so,
-- it will recalculate and overwite your custom mass value when the shapes are added to the body.
-- ** Properties
-- | Chipmunk provides getter/setter functions for a number of properties on rigid bodies.
-- Setting most properties automatically wakes the rigid bodies up if they were sleeping.
, bodyType
, bodyMass
, bodyMoment
, bodyPosition
, bodyCenterOfGravity
, bodyVelocity
, bodyForce
, bodyAngle
, bodyAngularVelocity
, bodyTorque
, bodyRotation
, bodySpace
, bodyUserData
-- ** Moment of Inertia and Area Helper Functions
-- | Use the following functions to approximate the moment of inertia for your body,
-- adding the results together if you want to use more than one.
, momentForCircle
, momentForSegment
, momentForPoly
, momentForBox
-- | Use the following functions to get the area for common Chipmunk shapes if you want to approximate masses
-- or density or whatnot.
, areaForCircle
, areaForSegment
, areaForPoly
-- ** Coordinate Conversion Functions
-- | Many things are defined in coordinates local to a body meaning that the (0,0) is at the center of gravity
-- of the body and the axis rotate along with the body.
, bodyLocalToWorld
, bodyWorldToLocal
-- ** Velocity Conversion Functions
-- | It’s often useful to know the absolute velocity of a point on the surface of a body
-- since the angular velocity affects everything except the center of gravity.
, bodyVelocityAtWorldPoint
-- ** Applying Forces and Torques
-- | People are sometimes confused by the difference between a force and an impulse.
-- An impulse is a very large force applied over a very short period of time.
-- Some examples are a ball hitting a wall or cannon firing. Chipmunk treats impulses as if they occur
-- instantaneously by adding directly to the velocity of an object.
-- Both impulses and forces are affected the mass of an object.
-- Doubling the mass of the object will halve the effect.
, bodyApplyForceAtWorldPoint
, bodyApplyForceAtLocalPoint
, bodyApplyImpulseAtWorldPoint
, bodyApplyImpulseAtLocalPoint
-- ** Sleeping Functions
-- | Chipmunk supports a sleeping feature which improves performance by not simulating groups of objects
-- that aren’t moving. Read more about it in the 'Space' section.
, bodyIsSleeping
, bodyActivate
, bodySleep
, bodyActivateStatic
, bodySleepWithGroup
-- ** Iterators
, BodyShapeIteratorFunc
, bodyEachShape
, BodyConstraintIteratorFunc
, bodyEachConstraint
, BodyArbiterIteratorFunc
, bodyEachArbiter
-- * Chipmunk Collision Shapes
, Shape
-- ** Properties
-- | Chipmunk provides getter/setter functions for a number of properties on collision shapes.
-- Setting most properties will automatically wake the attached rigid body, if it’s sleeping.
, shapeBody
, shapeBB
, shapeSensor
, shapeElasticity
, shapeFriction
, shapeSurfaceVelocity
, shapeCollisionType
, ShapeFilter (..)
, shapeFilter
, shapeSpace
, shapeUserData
-- ** Fast Collision Filtering using ShapeFilter
-- | Chipmunk has two primary means of ignoring collisions: groups and category masks.
--
-- __Groups__ are used to ignore collisions between parts on a complex object.
-- A ragdoll is a good example. When jointing an arm onto the torso, you’ll want them to allow them to overlap.
-- Groups allow you to do exactly that. Shapes that have the same group don’t generate collisions.
-- So by placing all of the shapes in a ragdoll in the same group, you’ll prevent it from colliding
-- against other parts of itself.
-- __Category__ masks allow you to mark which categories an object belongs to
-- and which categories it collidies with.
--
-- For example, a game has four collision categories: player (0), enemy (1), player bullet (2),
-- and enemy bullet (3). Neither players nor enemies should not collide with their own bullets,
-- and bullets should not collide with other bullets.
-- However, players collide with enemy bullets, and enemies collide with player bullets.
--
-- +-----------------+-----------------+---------------+
-- | Object | Object Category | Category Mask |
-- +=================+=================+===============+
-- | \"Player\" | 1 | 4, 5 |
-- +-----------------+-----------------+---------------+
-- | \"Enemy\" | 2 | 2, 3, 5 |
-- +-----------------+-----------------+---------------+
-- | "Player Bullet" | 3 | 1, 5 |
-- +-----------------+-----------------+---------------+
-- | "Enemy Bullet" | 4 | 2, 5 |
-- +-----------------+-----------------+---------------+
-- | \"Walls\" | 5 | 1, 2, 3, 4 |
-- +-----------------+-----------------+---------------+
--
-- Note that everything in this example collides with walls. Additionally, the enemies collide with eachother.
--
-- By default, objects exist in every category and collide with every category.
--
-- Objects can fall into multiple categories. For instance, you might have a category for a red team,
-- and have a red player bullet. In the above example, each object only has one category.
--
-- There is one last way of filtering collisions using collision handlers. See the section on callbacks
-- for more information. Collision handlers can be more flexible, but can be slower.
-- Fast collision filtering rejects collisions before running the expensive collision detection code,
-- so using groups or category masks is preferred.
-- ** Memory Management Functions
, shapeFree
-- ** Misc functions
, shapeCacheBB
, shapeUpdate
-- ** Working With Circle Shapes
, circleShapeNew
-- ** Working With Segment Shapes
, segmentShapeNew
, segmentShapeNeighbors
-- ** Working With Polygon Shapes
, polyShapeNew
, polyShapeNewRaw
-- *** Boxes
-- | Because boxes are so common in physics games, Chipmunk provides shortcuts to create box shaped polygons.
-- The boxes will always be centered at the center of gravity of the body you are attaching them to.
-- Adding a small radius will bevel the corners and can significantly reduce problems
-- where the box gets stuck on seams in your geometry. If you want to create an off-center box,
-- you will need to use 'polyShapeNew'.
, boxShapeNew
, boxShapeNew2
-- *** Poly Shape Helper Functions
, centroidForPoly
-- *** Convex Hull Helper Functions
, convexHull
-- ** Modifying 'Shape's
-- | The short answer is that you can’t because the changes would be only picked up as a change to the position
-- of the shape’s surface, but not its velocity.
-- ** Notes
-- |
-- * You can attach multiple collision shapes to a rigid body. This should allow you to create almost any shape
-- you could possibly need.
--
-- * Shapes attached to the same rigid body will never generate collisions. You don’t have to worry
-- about overlap when attaching multiple shapes to a rigid body.
--
-- * Make sure you add both the body and its collision shapes to a space.
-- * Chipmunk Spaces
, Space
-- ** What Are Iterations, and Why Should I Care?
-- | Chipmunk uses an iterative solver to figure out the forces between objects in the space.
-- What this means is that it builds a big list of all of the collisions, joints, and other constraints
-- between the bodies and makes several passes over the list considering each one individually.
-- The number of passes it makes is the iteration count, and each iteration makes the solution more accurate.
-- If you use too many iterations, the physics should look nice and solid, but may use up too much CPU time.
-- If you use too few iterations, the simulation may seem mushy or bouncy when the objects should be solid.
-- Setting the number of iterations lets you balance between CPU usage and the accuracy of the physics.
-- Chipmunk’s default of 10 iterations is sufficient for most simple games.
-- ** Sleeping
-- | Spaces can disable entire groups of objects that have stopped moving to save CPU time and battery life.
-- In order to use this feature you must do two things. You must enable sleeping explicitly
-- by choosing a time threshold value with 'spaceSetSleepTimeThreshold'. This threshold is the amount of time
-- something must be idle before it falls asleep. 'spaceSetIdleSpeedThreshold' defines what is considered idle.
-- If you do not set idle speed threshold explicitly, a value will be chosen automatically
-- based on the current amount of gravity. Be mindful that objects cannot fall asleep if they are touching
-- or jointed to a kinematic body.
-- ** Properties
, spaceIterations
, spaceGravity
, spaceDamping
, spaceIdleSpeedThreshold
, spaceSleepTimeThreshold
, spaceCollisionSlop
, spaceCollisionBias
, spaceCollisionPersistence
, spaceCurrentTimeStep
, spaceIsLocked
, spaceUserData
, spaceStaticBody
-- ** Memory Management Functions
-- | More standard Chipmunk memory functions.
, spaceNew
, spaceFree
-- ** Operations
-- | These functions add and remove shapes, bodies and constraints from space. The add/remove functions
-- cannot be called from within a callback other than a 'postStep' callback (which is different than a 'postSolve'
-- callback!). Attempting to add or remove objects from the space while 'spaceStep' is still executing
-- will throw an assertion. See the callbacks section for more information. Be careful not to free bodies
-- before removing shapes and constraints attached to them or you will cause crashes..
-- The contains functions allow you to check if an object has been added to the space or not.
, spaceAddShape
, spaceAddBody
, spaceAddConstraint
, spaceRemoveShape
, spaceRemoveBody
, spaceRemoveConstraint
, spaceContainsShape
, spaceContainsBody
, spaceContainsConstraint
-- ** Spatial Indexing
-- | Occasionally, you might want to update the collision detection data for a shape.
-- If you move a static shape or a static body you must do this to let Chipmunk know
-- it needs to have its collision detection data updated. You may also want to manually update the collision data
-- for normal shapes if you move them and still want to perform queries against them
-- before the next call to 'spaceStep'.
, spaceReindexShape
, spaceReindexShapesForBody
, spaceReindexStatic
-- ** Iterators
, SpaceBodyIteratorFunc
, spaceEachBody
, SpaceShapeIteratorFunc
, spaceEachShape
, SpaceConstraintIteratorFunc
, spaceEachConstraint
-- ** Simulating the Space
, spaceStep
-- * Notes
-- |
-- * When removing objects from the space, make sure you remove any other objects that reference it.
-- For instance, when you remove a body, remove the joints and shapes attached to it.
--
-- * Using more iterations or smaller time steps will increase the physics quality, but also increase the CPU usage.
-- * Chipmunk Constraints
, Constraint
-- ** What constraints are and what they are not
-- | Constraints in Chipmunk are all velocity based constraints.
-- This means that they act primarily by synchronizing the velocity of two bodies.
-- A pivot joint holds two anchor points on two separate bodies together by defining equations that say
-- that the velocity of the anchor points must be the same and calculating impulses to apply to the bodies
-- to try and keep it that way. A constraint takes a velocity as it’s primary input and produces a velocity change
-- as its output. Some constraints, (joints in particular) apply velocity changes to correct differences
-- in positions. More about this in the next section.
--
-- A spring connected between two bodies is not a constraint. It’s very constraint-like as it creates forces
-- that affect the velocities of the two bodies, but a spring takes distances as input and produces forces
-- as its output. If a spring is not a constraint, then why do I have two varieties of spring constraints you ask?
-- The reason is because they are damped springs. The damping associated with the spring is a true constraint
-- that creates velocity changes based on the relative velocities of the two bodies it links.
-- As it is convenient to put a damper and a spring together most of the time, I figured I might as well just apply
-- the spring force as part of the constraint instead of having a damper constraint and having the user
-- calculate and apply their own spring forces separately.
-- ** Properties
, constraintBodyA
, constraintBodyB
, constraintMaxForce
, constraintErrorBias
, constraintMaxBias
, constraintSpace
, constraintCollideBodies
, constraintUserData
, constraintImpulse
-- ** Error correction by Feedback
-- | Joints in Chipmunk are not perfect. A pin joint can’t maintain the exact correct distance between its anchor
-- points, nor can a pivot joint hold its anchor points completely together. Instead, they are designed
-- to deal with this by correcting themselves over time. Since Chipmunk 5, you have a fair amount of extra control
-- over how joints correct themselves and can even use this ability to create physical effects
-- that allow you to use joints in unique ways:
--
-- * Servo motors – Ex: open/close doors or rotate things without going over a maximum force.
--
-- * Winches – Pull one object towards another at a constant speed without going over a maximum force.
--
-- * Mouse manipulation – Interact with objects smoothly given coarse/shaky mouse input.
--
-- There are three properties of 'Constraint' structs that control the error correction,
-- maxForce, maxBias, and biasCoef. maxForce is pretty self explanatory, a joint or constraint
-- will not be able to use more than this amount of force in order to function. If it needs more force
-- to be able to hold itself together, it will fall apart. maxBias is the maximum speed at which error correction
-- can be applied. If you change a property on a joint so that the joint will have to correct itself,
-- it normally does so very quickly. By setting a maxSpeed you can make the joint work like a servo,
-- correcting itself at a constant rate over a longer period of time. Lastly, biasCoef is the percentage
-- of error corrected every step before clamping to a maximum speed. You can use this
-- to make joints correct themselves smoothly instead of at a constant speed, but is probably the least useful
-- of the three properties by far.
-- ** Constraints and Collision Shapes
-- | Neither constraints or collision shapes have any knowledge of the other.
-- When connecting joints to a body the anchor points don’t need to be inside of any shapes attached to the body
-- and it often makes sense that they shouldn’t. Also, adding a constraint between two bodies
-- doesn’t prevent their collision shapes from colliding. In fact, this is the primary reason
-- that the collision group property exists.
-- ** Video Tour of Current Joint Types
-- | http://www.youtube.com/watch?v=ZgJJZTS0aMM
-- ** Shared Memory Management Functions
, constraintFree
-- ** Constraint Types
-- *** Pin Joints
, pinJointNew
-- **** Properties
, pinJointAnchorA
, pinJointAnchorB
, pinJointDist
-- *** Slide Joints
, slideJointNew
-- **** Properties
, slideJointAnchorA
, slideJointAnchorB
, slideJointMin
, slideJointMax
-- *** Pivot Joints
-- | (__Note for bindings__: So each instance of pivot joint can be replaced with pin joint with dist of 0?)
, pivotJointNew
, pivotJointNew2
-- **** Properties
, pivotJointAnchorA
, pivotJointAnchorB
-- *** Groove Joint
, grooveJointNew
-- **** Properties
, grooveJointGrooveA
, grooveJointGrooveB
, grooveJointAnchorB
-- *** Damped Spring
, dampedSpringNew
-- **** Properties
, dampedSpringAnchorA
, dampedSpringAnchorB
, dampedSpringRestLength
, dampedSpringStiffness
, dampedSpringDamping
-- *** Damped Rotary Spring
-- | Like a damped spring, but works in an angular fashion.
, dampedRotarySpringNew
-- **** Properties
, dampedRotarySpringRestAngle
, dampedRotarySpringStiffness
, dampedRotarySpringDamping
-- *** Rotary Limit Joint
-- | Constrains the relative rotations of two bodies.
-- It is implemented so that it’s possible to for the range to be greater than a full revolution.
, rotaryLimitJointNew
-- **** Properties
, rotaryLimitJointMin
, rotaryLimitJointMax
-- *** Ratchet Joint
-- | Works like a socket wrench.
, ratchetJointNew
-- **** Properties
, ratchetJointAngle
, ratchetJointPhase
, ratchetJointRatchet
-- *** Gear Joint
-- | Keeps the angular velocity ratio of a pair of bodies constant.
, gearJointNew
-- **** Properties
, gearJointPhase
, gearJointRatio
-- *** Simple Motor
-- | Keeps the relative angular velocity of a pair of bodies constant.
-- You will usually want to set an force (torque) maximum for motors as otherwise
-- they will be able to apply a nearly infinite torque to keep the bodies moving.
, simpleMotorNew
-- **** Properties
, simpleMotorRate
-- ** Notes
-- | * You can add multiple joints between two bodies, but make sure that they don’t fight.
-- Doing so can cause the bodies jitter or spin violently.
-- * Overview of Collision Detection in Chipmunk
-- | In order to make collision detection in Chipmunk as fast as possible, the process is broken down
-- into several stages. While I’ve tried to keep it conceptually simple, the implementation can be a bit daunting.
-- Fortunately as a user of the library, you don’t need to understand everything about how it works.
-- Though if you are trying to squeeze every bit of performance out of Chipmunk, understanding this section
-- can be helpful.
-- ** Spatial Indexing
-- | A for loop that checks every object against every other object in the scene would be very slow.
-- So the first stage of the collision detection, commonly called the broadphase, uses a high level
-- spatial algorithm to decide which pairs of objects to check for collisions.
-- Currently Chipmunk supports two spatial indexes, an axis-aligned bounding box tree and a spatial hash.
-- These spatial indexes are able to quickly identify which pairs of shapes are near each other
-- and should be checked for a collision.
-- ** Fast Collision Filtering
-- | After the spatial index figures out which pairs of shapes are likely to be near each other,
-- it passes each pair back to the space using a callback to perform some additional filtering on the pairs.
-- Before doing anything else, Chipmunk performs a few quick tests to check if shapes should collide.
--
-- * __Bounding Box Test__: The shapes are not colliding if their bounding boxes are not overlapping.
-- Objects like diagonal line segments can trigger a lot of false positives here,
-- but it’s unlikely to be something you should worry about.
--
-- * __Category Mask Test__: The categories of each shape are bitwise ANDed against the category mask
-- of the other shape. If either result is 0, the shapes do not collide.
--
-- * __Group Test__: Shapes shouldn’t collide with other shapes in the same non-zero group.
-- ** Constraint Based Filtering
-- | After fast collision filtering, Chipmunk checks the list of joints on one of the bodies
-- to see if it has a constraint that attaches it to the other body. If that constraint’s collideBodies
-- property is false, the collision will be ignored. This check is often very fast
-- since most scenes don’t contain a lot of constraints.
-- ** Primitive Shape to Shape Collision Detection
-- | The most expensive test is to actually check for overlap based on their geometry.
-- Circle to circle and circle to line collisions are very fast. Segment to segment and poly to poly collisions
-- are handled using the GJK/EPA algorithms, and get more expensive as the number of vertexes increases.
-- Simpler shapes make for faster collisions, and often more important, fewer collision points
-- for the solver to run. Chipmunk uses a small dispatch table to figure out which function to use to check
-- if the shapes overlap.
--
-- Without going into too much detail, the GJK algorithm checks the distance between two objects,
-- and the EPA algorithm checks how much they are overlapping. If you give you segment and poly shapes
-- a small radius when creating them, the EPA algorithm can usually be skipped, speeding up the collision detection
-- considerably. The radius should be at least as big as the amount of allowed collision slop.
-- ** Collision Handler Filtering
-- | After checking if two shapes overlap Chipmunk will look to see if you have defined a collision handler
-- for the collision types of the shapes. This is vital to process collisions events for the gameplay,
-- but also gives you a very flexible way to filter out collisions. The return value of the begin and preSolve
-- callbacks determines whether or not the colliding pair of shapes is discarded or not.
-- Returning true will keep the pair, false will discard it. Rejecting a collision from a begin callback
-- is permanent, rejecting it from the preSolve only applies to the step it occured in. If you don’t define
-- a handler for the given collision types, Chipmunk will call the space’s default handler, which by default
-- is defined to simply accept all collisions.
--
-- Wildcard collisions can also return a value, but they are handled in a more complicated way.
-- When you create a collision handler between two specific collision types, it’s your responsibility
-- to decide when to call the wildcard handlers and what to do with their return values.
-- Otherwise, the default is to call the wildcard handler for the first type, then the second type,
-- and use a logical AND of their return values as filtering value. See DefaultBegin() in cpSpace.c
-- for more information.
--
-- While using callbacks to filter collisions is the most flexible way, keep in mind that by the time your callback
-- is called all of the most expensive collision detection has already been done. For simulations
-- with a lot of colliding objects each frame, the time spent finding collisions is small compared to the time
-- spent solving the physics for them so it may not be a big deal. Fast collision filtering should be preferred
-- if possible.
-- * Collision Callbacks
-- | A physics library without any events or feedback would not be very useful for games.
-- How would you know when the player bumped into an enemy so that you could take some health points away?
-- How would you know how hard the car hit something so you don’t play a loud crash noise when a pebble hits it?
-- What if you need to decide if a collision should be ignored based on specific conditions,
-- like implementing one way platforms? Chipmunk has a number of powerful callback systems
-- that you can use to solve these problems.
-- ** Collision Handlers
-- | Collision handler function types. While all of them take an arbiter, space, and a user data pointer,
-- only the begin and preSolve callbacks return a value. See above for more information.
, CollisionCallback
-- Collision callbacks are closely associated with 'Arbiter' structs.
-- You should familiarize yourself with those as well.
--
-- __Note__: Shapes tagged as sensors (cpShape.sensor == true) never generate collisions that get processed,
-- so collisions between sensors shapes and other shapes will never call the postSolve callback.
-- They still generate begin, and separate callbacks, and the preSolve callback is also called
-- every frame even though there is no collision response.
--
-- __Note #2__: preSolve callbacks are called before the sleeping algorithm runs.
-- If an object falls asleep, its postSolve callback won’t be called until it’s reawoken.
, CollisionType
, CollisionHandler (..)
, CollisionHandlerPtr
, spaceAddCollisionHandler
, spaceAddWildcardHandler
, spaceAddDefaultCollisionHandler
, modifyCollisionHandler
, mkCallback
, mkCallbackB
-- ** Post-Step Callbacks
-- | Post-step callbacks are the one place where you can break the rules about adding or removing objects
-- from within a callback. In fact, their primary function is to help you safely remove objects from the space
-- that you wanted to disable or destroy in a collision or query callback.
--
-- Post step callbacks are registered as a function and a pointer that is used as a key.
-- You can only register one postStep callback per key. This prevents you from accidentally removing
-- an object more than once. For instance, say that you get a collision callback between a bullet and object A.
-- You want to destroy both the bullet and object A, so you register a postStep callback
-- to safely remove them from your game. Then you get a second collision callback between the bullet and object B.
-- You register a postStep callback to remove object B, and a second postStep callback to remove the bullet.
-- Because you can only register one callback per key, the postStep callback for the bullet
-- will only be called once and you can’t accidentally try to remove it twice.
, PostStepFunc
, spaceAddPostStepCallback
-- ** Examples
-- | See
-- <https://chipmunk-physics.net/release/ChipmunkLatest-Docs/examples.html#CollisionCallbacks the callback examples>
-- for more information.
-- * Chipmunk Collision Pairs
, Arbiter
-- ** Memory Management
-- | You will never need to create or free an arbiter. More importantly,
-- because they are entirely managed by the space you should never store a reference to an arbiter
-- as you don’t know when they will be freed or reused. Use them within the callback where they are given to you
-- and then forget about them or copy out the information you need.
-- ** Properties
, arbiterRestitution
, arbiterFriction
, arbiterSurfaceVelocity
, arbiterUserData
-- *** Collision Point(s)
, arbiterCount
, arbiterNormal
, arbiterPointA
, arbiterPointB
, arbiterDepth
-- *** Other
, arbiterIsFirstContact
, arbiterIsRemoval
-- *** Bodies and shapes
, arbiterShapes
, arbiterBodies
-- *** Running wildcard handlers
-- | These functions invoke the wildcard handlers for a given collision. For custom collision handlers
-- between specific types or overriding the default handler, you must decide how to invoke the wildcard handlers
-- since it may be important to call the wildcards first, last, or possibly skip them entirely.
-- For the begin and preSolve callbacks, you also need to decide what to do with their return values
-- since they may not agree with each other or the specific handler they were called from.
-- Every collision handler is defined for two types, the “A” variants of these functions call the wildcard handler
-- for the first type, and the “B” variants call the handler for the second type.
, arbiterCallWildcardBeginA
, arbiterCallWildcardBeginB
, arbiterCallWildcardPreSolveA
, arbiterCallWildcardPreSolveB
, arbiterCallWildcardPostSolveA
, arbiterCallWildcardPostSolveB
, arbiterCallWildcardSeparateA
, arbiterCallWildcardSeparateB
-- * Misc
, DataPtr
, Transform (..)
-- * Re-exports
, nullPtr
, HasGetter (..)
, HasSetter (..)
) where
import Foreign
import Data.StateVar
import Chiphunk.Low.Types
import Chiphunk.Low.Math
import Chiphunk.Low.Helper
import Chiphunk.Low.Vect
import Chiphunk.Low.BB
import Chiphunk.Low.Body
import Chiphunk.Low.Shape
import Chiphunk.Low.Space
import Chiphunk.Low.Constraint
import Chiphunk.Low.Callback
import Chiphunk.Low.Arbiter