mirror of https://github.com/axmolengine/axmol.git
195 lines
8.0 KiB
C
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);
|
|
|
|
/// @}
|