axmol/external/chipmunk/include/chipmunk/cpArbiter.h

195 lines
8.0 KiB
C

/* Copyright (c) 2007 Scott Lembcke
*
* 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.
*/
/// @defgroup cpArbiter cpArbiter
/// The cpArbiter struct controls pairs of colliding shapes.
/// They are also used in conjuction with collision handler callbacks
/// allowing you to retrieve information on the collision and control it.
/// @{
/// Collision begin event function callback type.
/// Returning false from a begin callback causes the collision to be ignored until
/// the the separate callback is called when the objects stop colliding.
typedef cpBool (*cpCollisionBeginFunc)(cpArbiter *arb, cpSpace *space, void *data);
/// Collision pre-solve event function callback type.
/// Returning false from a pre-step callback causes the collision to be ignored until the next step.
typedef cpBool (*cpCollisionPreSolveFunc)(cpArbiter *arb, cpSpace *space, void *data);
/// Collision post-solve event function callback type.
typedef void (*cpCollisionPostSolveFunc)(cpArbiter *arb, cpSpace *space, void *data);
/// Collision separate event function callback type.
typedef void (*cpCollisionSeparateFunc)(cpArbiter *arb, cpSpace *space, void *data);
/// @private
struct cpCollisionHandler {
cpCollisionType a;
cpCollisionType b;
cpCollisionBeginFunc begin;
cpCollisionPreSolveFunc preSolve;
cpCollisionPostSolveFunc postSolve;
cpCollisionSeparateFunc separate;
void *data;
};
typedef struct cpContact cpContact;
#define CP_MAX_CONTACTS_PER_ARBITER 4
/// @private
typedef enum cpArbiterState {
// Arbiter is active and its the first collision.
cpArbiterStateFirstColl,
// Arbiter is active and its not the first collision.
cpArbiterStateNormal,
// Collision has been explicitly ignored.
// Either by returning false from a begin collision handler or calling cpArbiterIgnore().
cpArbiterStateIgnore,
// Collison is no longer active. A space will cache an arbiter for up to cpSpace.collisionPersistence more steps.
cpArbiterStateCached,
} cpArbiterState;
/// @private
struct cpArbiterThread {
// Links to next and previous arbiters in the contact graph.
struct cpArbiter *next, *prev;
};
/// A colliding pair of shapes.
struct cpArbiter {
/// Calculated value to use for the elasticity coefficient.
/// Override in a pre-solve collision handler for custom behavior.
cpFloat e;
/// Calculated value to use for the friction coefficient.
/// Override in a pre-solve collision handler for custom behavior.
cpFloat u;
/// Calculated value to use for applying surface velocities.
/// Override in a pre-solve collision handler for custom behavior.
cpVect surface_vr;
/// User definable data pointer.
/// The value will persist for the pair of shapes until the separate() callback is called.
/// NOTE: If you need to clean up this pointer, you should implement the separate() callback to do it.
cpDataPointer data;
CP_PRIVATE(cpShape *a);
CP_PRIVATE(cpShape *b);
CP_PRIVATE(cpBody *body_a);
CP_PRIVATE(cpBody *body_b);
CP_PRIVATE(struct cpArbiterThread thread_a);
CP_PRIVATE(struct cpArbiterThread thread_b);
CP_PRIVATE(int numContacts);
CP_PRIVATE(cpContact *contacts);
CP_PRIVATE(cpTimestamp stamp);
CP_PRIVATE(cpCollisionHandler *handler);
CP_PRIVATE(cpBool swappedColl);
CP_PRIVATE(cpArbiterState state);
};
#define CP_DefineArbiterStructGetter(type, member, name) \
static inline type cpArbiterGet##name(const cpArbiter *arb){return arb->member;}
#define CP_DefineArbiterStructSetter(type, member, name) \
static inline void cpArbiterSet##name(cpArbiter *arb, type value){arb->member = value;}
#define CP_DefineArbiterStructProperty(type, member, name) \
CP_DefineArbiterStructGetter(type, member, name) \
CP_DefineArbiterStructSetter(type, member, name)
CP_DefineArbiterStructProperty(cpFloat, e, Elasticity)
CP_DefineArbiterStructProperty(cpFloat, u, Friction)
CP_DefineArbiterStructProperty(cpVect, surface_vr, SurfaceVelocity)
CP_DefineArbiterStructProperty(cpDataPointer, data, UserData)
/// Calculate the total impulse that was applied by this arbiter.
/// This function should only be called from a post-solve, post-step or cpBodyEachArbiter callback.
cpVect cpArbiterTotalImpulse(const cpArbiter *arb);
/// Calculate the total impulse including the friction that was applied by this arbiter.
/// This function should only be called from a post-solve, post-step or cpBodyEachArbiter callback.
cpVect cpArbiterTotalImpulseWithFriction(const cpArbiter *arb);
/// Calculate the amount of energy lost in a collision including static, but not dynamic friction.
/// This function should only be called from a post-solve, post-step or cpBodyEachArbiter callback.
cpFloat cpArbiterTotalKE(const cpArbiter *arb);
/// Causes a collision pair to be ignored as if you returned false from a begin callback.
/// If called from a pre-step callback, you will still need to return false
/// if you want it to be ignored in the current step.
void cpArbiterIgnore(cpArbiter *arb);
/// Return the colliding shapes involved for this arbiter.
/// The order of their cpSpace.collision_type values will match
/// the order set when the collision handler was registered.
static inline void cpArbiterGetShapes(const cpArbiter *arb, cpShape **a, cpShape **b)
{
if(arb->CP_PRIVATE(swappedColl)){
(*a) = arb->CP_PRIVATE(b), (*b) = arb->CP_PRIVATE(a);
} else {
(*a) = arb->CP_PRIVATE(a), (*b) = arb->CP_PRIVATE(b);
}
}
/// A macro shortcut for defining and retrieving the shapes from an arbiter.
#define CP_ARBITER_GET_SHAPES(arb, a, b) cpShape *a, *b; cpArbiterGetShapes(arb, &a, &b);
/// Return the colliding bodies involved for this arbiter.
/// The order of the cpSpace.collision_type the bodies are associated with values will match
/// the order set when the collision handler was registered.
static inline void cpArbiterGetBodies(const cpArbiter *arb, cpBody **a, cpBody **b)
{
CP_ARBITER_GET_SHAPES(arb, shape_a, shape_b);
(*a) = shape_a->body;
(*b) = shape_b->body;
}
/// A macro shortcut for defining and retrieving the bodies from an arbiter.
#define CP_ARBITER_GET_BODIES(arb, a, b) cpBody *a, *b; cpArbiterGetBodies(arb, &a, &b);
/// A struct that wraps up the important collision data for an arbiter.
typedef struct cpContactPointSet {
/// The number of contact points in the set.
int count;
/// The array of contact points.
struct {
/// The position of the contact point.
cpVect point;
/// The normal of the contact point.
cpVect normal;
/// The depth of the contact point.
cpFloat dist;
} points[CP_MAX_CONTACTS_PER_ARBITER];
} cpContactPointSet;
/// Return a contact set from an arbiter.
cpContactPointSet cpArbiterGetContactPointSet(const cpArbiter *arb);
/// Returns true if this is the first step a pair of objects started colliding.
cpBool cpArbiterIsFirstContact(const cpArbiter *arb);
/// Get the number of contact points for this arbiter.
int cpArbiterGetCount(const cpArbiter *arb);
/// Get the normal of the @c ith contact point.
cpVect cpArbiterGetNormal(const cpArbiter *arb, int i);
/// Get the position of the @c ith contact point.
cpVect cpArbiterGetPoint(const cpArbiter *arb, int i);
/// Get the depth of the @c ith contact point.
cpFloat cpArbiterGetDepth(const cpArbiter *arb, int i);
/// @}