|
Physics.Hipmunk.Space | Portability | portable (needs FFI) | Stability | provisional | Maintainer | felipe.lessa@gmail.com |
|
|
|
|
|
Description |
The space, where the simulation happens and the various entities
interact.
|
|
Synopsis |
|
|
|
|
Callbacks problem
|
|
We have a huge problem for callbacks: we *have* to call
freeHaskellFunPtr to every Haskell function that was
passed via FFI to C code after we don't need them.
However, the ForeignPtr that the Space has can
portably have finalizers only in the FFI, never in the
Haskell land, so we can't run the Haskell function
freeHaskellFunPtr from a ForeignPtr finalizer.
There are two options:
1. Use Foreign.Concurrent to add a Haskell finalizer.
Under GHC this is great and adds no overhead (maybe there's
even less overhead than calling a C function).
However Foreign.Concurrent is not portable and
works only under GHC.
2. Require that users of the library (you) call
a finalizer function when they plan to stop using
the space. This adds some burden to the programmer
and somehow defeats the purpose of the GC, however
it works everywhere.
As this is a library that intends to be as portable as
possible (like Chipmunk itself), of course I chose
to follow the second path. This means that your code will
run unchanged on every Haskell environment supporting
FFI with C99, but also that you have to take care to
avoid memory leaks. You've been warned! :)
|
|
Creating spaces and adding entities
|
|
|
A space is where the simulation really occurs. You add
bodies, shapes and constraints to a space and then step it
to update it as whole.
| Instances | |
|
|
|
Creates a new, empty space.
Some of the memory resources associated with the space
must be manually freed through freeSpace when the
Space is no longer necessary.
|
|
|
freeSpace sp frees some memory resources that can't
be automatically deallocated in a portable way.
The space sp then becomes invalid and should
not be used (passing sp to any other function,
including freeSpace, results in undefined behavior).
|
|
|
Type class implemented by entities that can be
added to a space.
| | Methods | | Add an entity to a Space. Don't add the same
entity twice to a space.
| | | Remove an entity from a Space. Don't remove
an entity that wasn't add.
|
| | Instances | |
|
|
|
A StaticShape is a Shape container that, when added
to a space via spaceAdd, is added to the static
list of shapes.
A static shape is one assumed not to move. If you move
a static shape after adding it, then you need to rehashStatic.
You should not add the same shape as active and static,
nor should you add as active and try to remove as
static or vice versa.
| Constructors | | Instances | |
|
|
Properties
|
|
Iterations
|
|
|
The number of iterations to use when solving constraints.
(default is 10).
|
|
|
|
|
|
Elastic iterations
|
|
|
The number of elastic iterations to use when solving
constraints. (default is 0, meaning old-style elastic code
will be used, which probably isn't what you want).
|
|
|
|
|
|
Gravity
|
|
|
The gravity applied to the system. (default is 0)
|
|
|
|
|
|
Damping
|
|
|
The amount of viscous damping applied to the system.
(default is 1)
|
|
|
|
Time stamp
|
|
|
The time stamp of the simulation, increased in 1
every time step is called.
|
|
|
|
Spatial hashes
|
|
resizeStaticHash sp dim count resizes the static
hash of space sp to have hash cells of size dim
and suggested minimum number of cells count.
resizeActiveHash sp dim count works the same way
but modifying the active hash of the space.
Chipmunk's performance is highly sensitive to both
parameters, which should be hand-tuned to maximize
performance. It is in general recommended to set dim as
the average object size and count around 10 times the
number of objects in the hash. Usually bigger numbers are
better to count, but only to a certain point. By default
dim is 100.0 and count is 1000.
Note that in the case of the static hash you may try
larger numbers as the static hash is only rehashed
when requested by rehashStatic, however that will
use more memory.
|
|
|
|
|
|
|
Rehashes the shapes in the static spatial hash.
You only need to call this if you move one of the
static shapes.
|
|
Point query
|
|
Point querying uses the spatial hashes to find out
in what shapes a point is contained. It is useful,
for example, to know if a shape was clicked by
the user.
|
|
|
spaceQuery sp pos l g cb will call cb for every
shape that
- Contains point pos (in world's coordinates).
- Isn't of the same group as g.
- Shares at least on layer with l.
The order in which the callback is called is unspecified.
However it is guaranteed that it will be called once,
and only once, for each of the shapes described above
(and never for those who aren't).
|
|
|
spaceQueryList sp pos l g acts like spaceQuery but
returns a list of Shapes instead of calling a callback.
This is just a convenience function.
|
|
Stepping
|
|
|
step sp dt will update the space sp for a dt time
step.
It is highly recommended to use a fixed dt to increase
the efficiency of contact persistence. Some tips may be
found in http://www.gaffer.org/game-physics/fix-your-timestep.
|
|
Collision pair functions
|
|
A collision pair function is a callback triggered by step
in response to certain collision events. Its return value
will determine whether or not the collision will be processed.
If False, then the collision will be ignored.
The callbacks themselves may execute arbitrary operations
with a simple exception: callbacks cannot add or remove
entities from the space. You can of course create a queue
of add/remove actions and then process it after step
returns.
As for the events that trigger collision pair functions, the
rule is simple. All shapes have a CollisionType. When
shapes a and b collide, if there was a callback
associated with a's and b's collision types, then it is
called. Otherwise the default callback is called. The
default callback always returns True (i.e. all collisions
are treated).
|
|
|
A Callback function can be of three types:
- A Full callback has access to all parameters passed
by Chipmunk, but it is common not to need all of them.
The two colliding Shapes are passed as arguments with
a Contact array and a normal coefficient (this coefficient
should be multiplied to the contacts' normals as
Chipmunk may have reversed the argument order). See Contact
for more information.
- A Basic callback can't access the Contact information,
but incurs a lower overhead per call.
- A Constant callback always accepts or reject the collision.
For example, a Constant False will never accept any
collision.
Although Basic and Constant can be implemented
in terms of Full, they're optimized to incur less overhead.
So try to use the simplest callback type
(e.g. Constant False instead of Basic (_ _ -> return False)).
| Constructors | |
|
|
|
Defines a new default collision pair function.
This callback is called whenever two shapes a
and b collide such that no other collision
pair function was defined to a's and b's
collision types. The default is Constant True.
|
|
|
addCallback sp (cta,ctb) f defines f as the callback
to be called whenever a collision occurs between
a shape of collision type cta and another of
collision type ctb (and vice versa). Any other callback
already registered to handle (cta,ctb) will be removed.
Note that you should not add callbacks to both
combinations of (cta,ctb) and (ctb,cta). A good rule
of thumb is to always use cta <= ctb, although this
is not necessary.
|
|
|
removeCallback sp (cta,ctb) removes any callbacks that
were registered to handle (cta,ctb) (see addCallback).
Any collisions that would be handled by the removed
callback will be handled by the default one (see
setDefaultCallback).
Note that you should always use the same order that
was passed to addCallback. In other words, after
addCallback sp (cta,ctb) f you should use
removeCallback sp (cta,ctb), and never
removeCallback sp (ctb,cta).
Although pointless, it is harmless to remove a callback
that was not added.
|
|
Contacts
|
|
|
A Contact contains information about a collision.
It is passed to Physics.Hipmunk.Space.Full.
The fields ctJnAcc and ctJtAcc do not have any meaningfull
value until Physics.Hipmunk.Space.step has returned
(i.e. during a call to a callback this information
contains garbage), and by extension you can only know
the impulse sum after step returns as well.
IMPORTANT: You may maintain a reference to an array of
Contacts that was passed to a callback to do any other
processing later. However, a new call to step will
invalidate any of those arrays! Be careful.
| Constructors | Contact | | ctPos :: Position | Position of the collision in world's coordinates.
| ctNormal :: Vector | Normal of the collision.
| ctDist :: CpFloat | Penetration distance of the collision.
| ctJnAcc :: CpFloat | Normal component of final impulse applied.
(Valid only after step finishes.)
| ctJtAcc :: CpFloat | Tangential component of final impulse applied.
(Valid only after step finishes.)
|
|
| Instances | |
|
|
|
Sums the impulses applied to the given contact points.
sumImpulses sums only the normal components.
This function should be called only after step
returns.
|
|
|
Sums the impulses applied to the given contact points.
This function sums both the normal and tangential components
and should be called only after step returns.
|
|
Produced by Haddock version 2.4.2 |