mirror of https://github.com/axmolengine/axmol.git
251 lines
9.3 KiB
C
251 lines
9.3 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 cpBody cpBody
|
|
/// Chipmunk's rigid body type. Rigid bodies hold the physical properties of an object like
|
|
/// it's mass, and position and velocity of it's center of gravity. They don't have an shape on their own.
|
|
/// They are given a shape by creating collision shapes (cpShape) that point to the body.
|
|
/// @{
|
|
|
|
/// Rigid body velocity update function type.
|
|
typedef void (*cpBodyVelocityFunc)(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt);
|
|
/// Rigid body position update function type.
|
|
typedef void (*cpBodyPositionFunc)(cpBody *body, cpFloat dt);
|
|
|
|
/// Used internally to track information on the collision graph.
|
|
/// @private
|
|
typedef struct cpComponentNode {
|
|
cpBody *root;
|
|
cpBody *next;
|
|
cpFloat idleTime;
|
|
} cpComponentNode;
|
|
|
|
/// Chipmunk's rigid body struct.
|
|
struct cpBody {
|
|
/// Function that is called to integrate the body's velocity. (Defaults to cpBodyUpdateVelocity)
|
|
cpBodyVelocityFunc velocity_func;
|
|
|
|
/// Function that is called to integrate the body's position. (Defaults to cpBodyUpdatePosition)
|
|
cpBodyPositionFunc position_func;
|
|
|
|
/// Mass of the body.
|
|
/// Must agree with cpBody.m_inv! Use cpBodySetMass() when changing the mass for this reason.
|
|
cpFloat m;
|
|
/// Mass inverse.
|
|
cpFloat m_inv;
|
|
|
|
/// Moment of inertia of the body.
|
|
/// Must agree with cpBody.i_inv! Use cpBodySetMoment() when changing the moment for this reason.
|
|
cpFloat i;
|
|
/// Moment of inertia inverse.
|
|
cpFloat i_inv;
|
|
|
|
/// Position of the rigid body's center of gravity.
|
|
cpVect p;
|
|
/// Velocity of the rigid body's center of gravity.
|
|
cpVect v;
|
|
/// Force acting on the rigid body's center of gravity.
|
|
cpVect f;
|
|
|
|
/// Rotation of the body around it's center of gravity in radians.
|
|
/// Must agree with cpBody.rot! Use cpBodySetAngle() when changing the angle for this reason.
|
|
cpFloat a;
|
|
/// Angular velocity of the body around it's center of gravity in radians/second.
|
|
cpFloat w;
|
|
/// Torque applied to the body around it's center of gravity.
|
|
cpFloat t;
|
|
|
|
/// Cached unit length vector representing the angle of the body.
|
|
/// Used for fast rotations using cpvrotate().
|
|
cpVect rot;
|
|
|
|
/// User definable data pointer.
|
|
/// Generally this points to your the game object class so you can access it
|
|
/// when given a cpBody reference in a callback.
|
|
cpDataPointer data;
|
|
|
|
/// Maximum velocity allowed when updating the velocity.
|
|
cpFloat v_limit;
|
|
/// Maximum rotational rate (in radians/second) allowed when updating the angular velocity.
|
|
cpFloat w_limit;
|
|
|
|
CP_PRIVATE(cpVect v_bias);
|
|
CP_PRIVATE(cpFloat w_bias);
|
|
|
|
CP_PRIVATE(cpSpace *space);
|
|
|
|
CP_PRIVATE(cpShape *shapeList);
|
|
CP_PRIVATE(cpArbiter *arbiterList);
|
|
CP_PRIVATE(cpConstraint *constraintList);
|
|
|
|
CP_PRIVATE(cpComponentNode node);
|
|
};
|
|
|
|
/// Allocate a cpBody.
|
|
cpBody* cpBodyAlloc(void);
|
|
/// Initialize a cpBody.
|
|
cpBody* cpBodyInit(cpBody *body, cpFloat m, cpFloat i);
|
|
/// Allocate and initialize a cpBody.
|
|
cpBody* cpBodyNew(cpFloat m, cpFloat i);
|
|
|
|
/// Initialize a static cpBody.
|
|
cpBody* cpBodyInitStatic(cpBody *body);
|
|
/// Allocate and initialize a static cpBody.
|
|
cpBody* cpBodyNewStatic(void);
|
|
|
|
/// Destroy a cpBody.
|
|
void cpBodyDestroy(cpBody *body);
|
|
/// Destroy and free a cpBody.
|
|
void cpBodyFree(cpBody *body);
|
|
|
|
/// Check that the properties of a body is sane. (Only in debug mode)
|
|
#ifdef NDEBUG
|
|
#define cpBodyAssertSane(body)
|
|
#else
|
|
void cpBodySanityCheck(cpBody *body);
|
|
#define cpBodyAssertSane(body) cpBodySanityCheck(body)
|
|
#endif
|
|
|
|
// Defined in cpSpace.c
|
|
/// Wake up a sleeping or idle body.
|
|
void cpBodyActivate(cpBody *body);
|
|
/// Wake up any sleeping or idle bodies touching a static body.
|
|
void cpBodyActivateStatic(cpBody *body, cpShape *filter);
|
|
|
|
/// Force a body to fall asleep immediately.
|
|
void cpBodySleep(cpBody *body);
|
|
/// Force a body to fall asleep immediately along with other bodies in a group.
|
|
void cpBodySleepWithGroup(cpBody *body, cpBody *group);
|
|
|
|
/// Returns true if the body is sleeping.
|
|
static inline cpBool cpBodyIsSleeping(const cpBody *body)
|
|
{
|
|
return (CP_PRIVATE(body->node).root != ((cpBody*)0));
|
|
}
|
|
|
|
/// Returns true if the body is static.
|
|
static inline cpBool cpBodyIsStatic(const cpBody *body)
|
|
{
|
|
return CP_PRIVATE(body->node).idleTime == INFINITY;
|
|
}
|
|
|
|
/// Returns true if the body has not been added to a space.
|
|
static inline cpBool cpBodyIsRogue(const cpBody *body)
|
|
{
|
|
return (body->CP_PRIVATE(space) == ((cpSpace*)0));
|
|
}
|
|
|
|
|
|
#define CP_DefineBodyStructGetter(type, member, name) \
|
|
static inline type cpBodyGet##name(const cpBody *body){return body->member;}
|
|
|
|
#define CP_DefineBodyStructSetter(type, member, name) \
|
|
static inline void cpBodySet##name(cpBody *body, const type value){ \
|
|
cpBodyActivate(body); \
|
|
body->member = value; \
|
|
cpBodyAssertSane(body); \
|
|
}
|
|
|
|
#define CP_DefineBodyStructProperty(type, member, name) \
|
|
CP_DefineBodyStructGetter(type, member, name) \
|
|
CP_DefineBodyStructSetter(type, member, name)
|
|
|
|
// TODO add to docs
|
|
CP_DefineBodyStructGetter(cpSpace*, CP_PRIVATE(space), Space)
|
|
|
|
CP_DefineBodyStructGetter(cpFloat, m, Mass)
|
|
/// Set the mass of a body.
|
|
void cpBodySetMass(cpBody *body, cpFloat m);
|
|
|
|
CP_DefineBodyStructGetter(cpFloat, i, Moment)
|
|
/// Set the moment of a body.
|
|
void cpBodySetMoment(cpBody *body, cpFloat i);
|
|
|
|
CP_DefineBodyStructGetter(cpVect, p, Pos)
|
|
/// Set the position of a body.
|
|
void cpBodySetPos(cpBody *body, cpVect pos);
|
|
CP_DefineBodyStructProperty(cpVect, v, Vel)
|
|
CP_DefineBodyStructProperty(cpVect, f, Force)
|
|
CP_DefineBodyStructGetter(cpFloat, a, Angle)
|
|
/// Set the angle of a body.
|
|
void cpBodySetAngle(cpBody *body, cpFloat a);
|
|
CP_DefineBodyStructProperty(cpFloat, w, AngVel)
|
|
CP_DefineBodyStructProperty(cpFloat, t, Torque)
|
|
CP_DefineBodyStructGetter(cpVect, rot, Rot)
|
|
CP_DefineBodyStructProperty(cpFloat, v_limit, VelLimit)
|
|
CP_DefineBodyStructProperty(cpFloat, w_limit, AngVelLimit)
|
|
CP_DefineBodyStructProperty(cpDataPointer, data, UserData)
|
|
|
|
/// Default Integration functions.
|
|
void cpBodyUpdateVelocity(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt);
|
|
void cpBodyUpdatePosition(cpBody *body, cpFloat dt);
|
|
|
|
/// Convert body relative/local coordinates to absolute/world coordinates.
|
|
static inline cpVect cpBodyLocal2World(const cpBody *body, const cpVect v)
|
|
{
|
|
return cpvadd(body->p, cpvrotate(v, body->rot));
|
|
}
|
|
|
|
/// Convert body absolute/world coordinates to relative/local coordinates.
|
|
static inline cpVect cpBodyWorld2Local(const cpBody *body, const cpVect v)
|
|
{
|
|
return cpvunrotate(cpvsub(v, body->p), body->rot);
|
|
}
|
|
|
|
/// Set the forces and torque or a body to zero.
|
|
void cpBodyResetForces(cpBody *body);
|
|
/// Apply an force (in world coordinates) to the body at a point relative to the center of gravity (also in world coordinates).
|
|
void cpBodyApplyForce(cpBody *body, const cpVect f, const cpVect r);
|
|
/// Apply an impulse (in world coordinates) to the body at a point relative to the center of gravity (also in world coordinates).
|
|
void cpBodyApplyImpulse(cpBody *body, const cpVect j, const cpVect r);
|
|
|
|
/// Get the velocity on a body (in world units) at a point on the body in world coordinates.
|
|
cpVect cpBodyGetVelAtWorldPoint(cpBody *body, cpVect point);
|
|
/// Get the velocity on a body (in world units) at a point on the body in local coordinates.
|
|
cpVect cpBodyGetVelAtLocalPoint(cpBody *body, cpVect point);
|
|
|
|
|
|
/// Get the kinetic energy of a body.
|
|
static inline cpFloat cpBodyKineticEnergy(const cpBody *body)
|
|
{
|
|
// Need to do some fudging to avoid NaNs
|
|
cpFloat vsq = cpvdot(body->v, body->v);
|
|
cpFloat wsq = body->w*body->w;
|
|
return (vsq ? vsq*body->m : 0.0f) + (wsq ? wsq*body->i : 0.0f);
|
|
}
|
|
|
|
/// Body/shape iterator callback function type.
|
|
typedef void (*cpBodyShapeIteratorFunc)(cpBody *body, cpShape *shape, void *data);
|
|
/// Call @c func once for each shape attached to @c body and added to the space.
|
|
void cpBodyEachShape(cpBody *body, cpBodyShapeIteratorFunc func, void *data);
|
|
|
|
/// Body/constraint iterator callback function type.
|
|
typedef void (*cpBodyConstraintIteratorFunc)(cpBody *body, cpConstraint *constraint, void *data);
|
|
/// Call @c func once for each constraint attached to @c body and added to the space.
|
|
void cpBodyEachConstraint(cpBody *body, cpBodyConstraintIteratorFunc func, void *data);
|
|
|
|
/// Body/arbiter iterator callback function type.
|
|
typedef void (*cpBodyArbiterIteratorFunc)(cpBody *body, cpArbiter *arbiter, void *data);
|
|
/// Call @c func once for each arbiter that is currently active on the body.
|
|
void cpBodyEachArbiter(cpBody *body, cpBodyArbiterIteratorFunc func, void *data);
|
|
|
|
///@}
|