commit
051853a542
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2007 Scott Lembcke
|
||||
/* Copyright (c) 2013 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
|
||||
|
|
@ -19,20 +19,26 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef CHIPMUNK_HEADER
|
||||
#define CHIPMUNK_HEADER
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define _USE_MATH_DEFINES
|
||||
#endif
|
||||
#ifndef CHIPMUNK_H
|
||||
#define CHIPMUNK_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#ifdef WIN32
|
||||
// For alloca().
|
||||
#include <malloc.h>
|
||||
#define CP_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#include <alloca.h>
|
||||
#define CP_EXPORT
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// NUKE
|
||||
#ifndef CP_ALLOW_PRIVATE_ACCESS
|
||||
#define CP_ALLOW_PRIVATE_ACCESS 0
|
||||
#endif
|
||||
|
|
@ -43,22 +49,17 @@ extern "C" {
|
|||
#define CP_PRIVATE(__symbol__) __symbol__##_private
|
||||
#endif
|
||||
|
||||
void cpMessage(const char *condition, const char *file, int line, int isError, int isHardError, const char *message, ...);
|
||||
CP_EXPORT void cpMessage(const char *condition, const char *file, int line, int isError, int isHardError, const char *message, ...);
|
||||
#ifdef NDEBUG
|
||||
#define cpAssertWarn(__condition__, ...)
|
||||
#define cpAssertSoft(__condition__, ...)
|
||||
#else
|
||||
#define cpAssertSoft(__condition__, ...) if(!(__condition__)){cpMessage(#__condition__, __FILE__, __LINE__, 1, 0, __VA_ARGS__); abort();}
|
||||
#define cpAssertWarn(__condition__, ...) if(!(__condition__)) cpMessage(#__condition__, __FILE__, __LINE__, 0, 0, __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define cpAssertSoft(__condition__, ...)
|
||||
#else
|
||||
#define cpAssertSoft(__condition__, ...) if(!(__condition__)) cpMessage(#__condition__, __FILE__, __LINE__, 1, 0, __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
// Hard assertions are important and cheap to execute. They are not disabled by compiling as debug.
|
||||
#define cpAssertHard(__condition__, ...) if(!(__condition__)) cpMessage(#__condition__, __FILE__, __LINE__, 1, 1, __VA_ARGS__)
|
||||
|
||||
// Hard assertions are used in situations where the program definitely will crash anyway, and the reason is inexpensive to detect.
|
||||
#define cpAssertHard(__condition__, ...) if(!(__condition__)){cpMessage(#__condition__, __FILE__, __LINE__, 1, 1, __VA_ARGS__); abort();}
|
||||
|
||||
#include "chipmunk_types.h"
|
||||
|
||||
|
|
@ -89,81 +90,90 @@ typedef struct cpArray cpArray;
|
|||
typedef struct cpHashSet cpHashSet;
|
||||
|
||||
typedef struct cpBody cpBody;
|
||||
|
||||
typedef struct cpShape cpShape;
|
||||
typedef struct cpCircleShape cpCircleShape;
|
||||
typedef struct cpSegmentShape cpSegmentShape;
|
||||
typedef struct cpPolyShape cpPolyShape;
|
||||
|
||||
typedef struct cpConstraint cpConstraint;
|
||||
typedef struct cpPinJoint cpPinJoint;
|
||||
typedef struct cpSlideJoint cpSlideJoint;
|
||||
typedef struct cpPivotJoint cpPivotJoint;
|
||||
typedef struct cpGrooveJoint cpGrooveJoint;
|
||||
typedef struct cpDampedSpring cpDampedSpring;
|
||||
typedef struct cpDampedRotarySpring cpDampedRotarySpring;
|
||||
typedef struct cpRotaryLimitJoint cpRotaryLimitJoint;
|
||||
typedef struct cpRatchetJoint cpRatchetJoint;
|
||||
typedef struct cpGearJoint cpGearJoint;
|
||||
typedef struct cpSimpleMotorJoint cpSimpleMotorJoint;
|
||||
|
||||
typedef struct cpCollisionHandler cpCollisionHandler;
|
||||
typedef struct cpContactPointSet cpContactPointSet;
|
||||
typedef struct cpArbiter cpArbiter;
|
||||
|
||||
typedef struct cpSpace cpSpace;
|
||||
|
||||
#include "cpVect.h"
|
||||
#include "cpBB.h"
|
||||
#include "cpTransform.h"
|
||||
#include "cpSpatialIndex.h"
|
||||
|
||||
#include "cpArbiter.h"
|
||||
|
||||
#include "cpBody.h"
|
||||
#include "cpShape.h"
|
||||
#include "cpPolyShape.h"
|
||||
|
||||
#include "cpArbiter.h"
|
||||
#include "constraints/cpConstraint.h"
|
||||
#include "cpConstraint.h"
|
||||
|
||||
#include "cpSpace.h"
|
||||
#include "cpHastySpace.h"
|
||||
|
||||
// Chipmunk 6.2.1
|
||||
#define CP_VERSION_MAJOR 6
|
||||
#define CP_VERSION_MINOR 2
|
||||
// Chipmunk 7.0.1
|
||||
#define CP_VERSION_MAJOR 7
|
||||
#define CP_VERSION_MINOR 0
|
||||
#define CP_VERSION_RELEASE 1
|
||||
|
||||
/// Version string.
|
||||
extern const char *cpVersionString;
|
||||
|
||||
/// @deprecated
|
||||
void cpInitChipmunk(void);
|
||||
|
||||
/// Enables segment to segment shape collisions.
|
||||
void cpEnableSegmentToSegmentCollisions(void);
|
||||
|
||||
CP_EXPORT extern const char *cpVersionString;
|
||||
|
||||
/// Calculate the moment of inertia for a circle.
|
||||
/// @c r1 and @c r2 are the inner and outer diameters. A solid circle has an inner diameter of 0.
|
||||
cpFloat cpMomentForCircle(cpFloat m, cpFloat r1, cpFloat r2, cpVect offset);
|
||||
CP_EXPORT cpFloat cpMomentForCircle(cpFloat m, cpFloat r1, cpFloat r2, cpVect offset);
|
||||
|
||||
/// Calculate area of a hollow circle.
|
||||
/// @c r1 and @c r2 are the inner and outer diameters. A solid circle has an inner diameter of 0.
|
||||
cpFloat cpAreaForCircle(cpFloat r1, cpFloat r2);
|
||||
CP_EXPORT cpFloat cpAreaForCircle(cpFloat r1, cpFloat r2);
|
||||
|
||||
/// Calculate the moment of inertia for a line segment.
|
||||
/// Beveling radius is not supported.
|
||||
cpFloat cpMomentForSegment(cpFloat m, cpVect a, cpVect b);
|
||||
CP_EXPORT cpFloat cpMomentForSegment(cpFloat m, cpVect a, cpVect b, cpFloat radius);
|
||||
|
||||
/// Calculate the area of a fattened (capsule shaped) line segment.
|
||||
cpFloat cpAreaForSegment(cpVect a, cpVect b, cpFloat r);
|
||||
CP_EXPORT cpFloat cpAreaForSegment(cpVect a, cpVect b, cpFloat radius);
|
||||
|
||||
/// Calculate the moment of inertia for a solid polygon shape assuming it's center of gravity is at it's centroid. The offset is added to each vertex.
|
||||
cpFloat cpMomentForPoly(cpFloat m, int numVerts, const cpVect *verts, cpVect offset);
|
||||
CP_EXPORT cpFloat cpMomentForPoly(cpFloat m, int count, const cpVect *verts, cpVect offset, cpFloat radius);
|
||||
|
||||
/// Calculate the signed area of a polygon. A Clockwise winding gives positive area.
|
||||
/// This is probably backwards from what you expect, but matches Chipmunk's the winding for poly shapes.
|
||||
cpFloat cpAreaForPoly(const int numVerts, const cpVect *verts);
|
||||
CP_EXPORT cpFloat cpAreaForPoly(const int count, const cpVect *verts, cpFloat radius);
|
||||
|
||||
/// Calculate the natural centroid of a polygon.
|
||||
cpVect cpCentroidForPoly(const int numVerts, const cpVect *verts);
|
||||
|
||||
/// Center the polygon on the origin. (Subtracts the centroid of the polygon from each vertex)
|
||||
void cpRecenterPoly(const int numVerts, cpVect *verts);
|
||||
CP_EXPORT cpVect cpCentroidForPoly(const int count, const cpVect *verts);
|
||||
|
||||
/// Calculate the moment of inertia for a solid box.
|
||||
cpFloat cpMomentForBox(cpFloat m, cpFloat width, cpFloat height);
|
||||
CP_EXPORT cpFloat cpMomentForBox(cpFloat m, cpFloat width, cpFloat height);
|
||||
|
||||
/// Calculate the moment of inertia for a solid box.
|
||||
cpFloat cpMomentForBox2(cpFloat m, cpBB box);
|
||||
CP_EXPORT cpFloat cpMomentForBox2(cpFloat m, cpBB box);
|
||||
|
||||
/// Calculate the convex hull of a given set of points. Returns the count of points in the hull.
|
||||
/// @c result must be a pointer to a @c cpVect array with at least @c count elements. If @c result is @c NULL, then @c verts will be reduced instead.
|
||||
/// @c result must be a pointer to a @c cpVect array with at least @c count elements. If @c verts == @c result, then @c verts will be reduced inplace.
|
||||
/// @c first is an optional pointer to an integer to store where the first vertex in the hull came from (i.e. verts[first] == result[0])
|
||||
/// @c tol is the allowed amount to shrink the hull when simplifying it. A tolerance of 0.0 creates an exact hull.
|
||||
int cpConvexHull(int count, cpVect *verts, cpVect *result, int *first, cpFloat tol);
|
||||
CP_EXPORT int cpConvexHull(int count, const cpVect *verts, cpVect *result, int *first, cpFloat tol);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include "malloc.h"
|
||||
|
|
@ -177,6 +187,15 @@ int cpConvexHull(int count, cpVect *verts, cpVect *result, int *first, cpFloat t
|
|||
cpVect *__verts_var__ = (cpVect *)alloca(__count__*sizeof(cpVect)); \
|
||||
int __count_var__ = cpConvexHull(__count__, __verts__, __verts_var__, NULL, 0.0); \
|
||||
|
||||
/// Returns the closest point on the line segment ab, to the point p.
|
||||
static inline cpVect
|
||||
cpClosetPointOnSegment(const cpVect p, const cpVect a, const cpVect b)
|
||||
{
|
||||
cpVect delta = cpvsub(a, b);
|
||||
cpFloat t = cpfclamp01(cpvdot(delta, cpvsub(p, b))/cpvlengthsq(delta));
|
||||
return cpvadd(b, cpvmult(delta, t));
|
||||
}
|
||||
|
||||
#if defined(__has_extension)
|
||||
#if __has_extension(blocks)
|
||||
// Define alternate block based alternatives for a few of the callback heavy functions.
|
||||
|
|
@ -191,14 +210,14 @@ void cpBodyEachShape_b(cpBody *body, void (^block)(cpShape *shape));
|
|||
void cpBodyEachConstraint_b(cpBody *body, void (^block)(cpConstraint *constraint));
|
||||
void cpBodyEachArbiter_b(cpBody *body, void (^block)(cpArbiter *arbiter));
|
||||
|
||||
typedef void (^cpSpaceNearestPointQueryBlock)(cpShape *shape, cpFloat distance, cpVect point);
|
||||
void cpSpaceNearestPointQuery_b(cpSpace *space, cpVect point, cpFloat maxDistance, cpLayers layers, cpGroup group, cpSpaceNearestPointQueryBlock block);
|
||||
typedef void (^cpSpacePointQueryBlock)(cpShape *shape, cpVect point, cpFloat distance, cpVect gradient);
|
||||
void cpSpacePointQuery_b(cpSpace *space, cpVect point, cpFloat maxDistance, cpShapeFilter filter, cpSpacePointQueryBlock block);
|
||||
|
||||
typedef void (^cpSpaceSegmentQueryBlock)(cpShape *shape, cpFloat t, cpVect n);
|
||||
void cpSpaceSegmentQuery_b(cpSpace *space, cpVect start, cpVect end, cpLayers layers, cpGroup group, cpSpaceSegmentQueryBlock block);
|
||||
typedef void (^cpSpaceSegmentQueryBlock)(cpShape *shape, cpVect point, cpVect normal, cpFloat alpha);
|
||||
void cpSpaceSegmentQuery_b(cpSpace *space, cpVect start, cpVect end, cpFloat radius, cpShapeFilter filter, cpSpaceSegmentQueryBlock block);
|
||||
|
||||
typedef void (^cpSpaceBBQueryBlock)(cpShape *shape);
|
||||
void cpSpaceBBQuery_b(cpSpace *space, cpBB bb, cpLayers layers, cpGroup group, cpSpaceBBQueryBlock block);
|
||||
void cpSpaceBBQuery_b(cpSpace *space, cpBB bb, cpShapeFilter filter, cpSpaceBBQueryBlock block);
|
||||
|
||||
typedef void (^cpSpaceShapeQueryBlock)(cpShape *shape, cpContactPointSet *points);
|
||||
cpBool cpSpaceShapeQuery_b(cpSpace *space, cpShape *shape, cpSpaceShapeQueryBlock block);
|
||||
|
|
|
|||
|
|
@ -1,11 +1,35 @@
|
|||
/* Copyright (c) 2013 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.
|
||||
*/
|
||||
|
||||
#ifdef CHIPMUNK_FFI
|
||||
|
||||
// Create non static inlined copies of Chipmunk functions, useful for working with dynamic FFIs
|
||||
// This file should only be included in chipmunk.c
|
||||
|
||||
// TODO: get rid of the reliance on static inlines.
|
||||
// They make a mess for FFIs.
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if _MSC_VER >= 1600
|
||||
#define MAKE_REF(name) decltype(name) *_##name = name
|
||||
#define MAKE_REF(name) CP_EXPORT decltype(name) *_##name = name
|
||||
#else
|
||||
#define MAKE_REF(name)
|
||||
#endif
|
||||
|
|
@ -13,8 +37,9 @@
|
|||
#define MAKE_REF(name) __typeof__(name) *_##name = name
|
||||
#endif
|
||||
|
||||
#define MAKE_PROPERTIES_REF(struct, property) \
|
||||
MAKE_REF(struct##Get##property); MAKE_REF(struct##Set##property)
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
MAKE_REF(cpv); // makes a variable named _cpv that contains the function pointer for cpv()
|
||||
MAKE_REF(cpveql);
|
||||
|
|
@ -35,7 +60,6 @@ MAKE_REF(cpvlengthsq);
|
|||
MAKE_REF(cpvlength);
|
||||
MAKE_REF(cpvlerp);
|
||||
MAKE_REF(cpvnormalize);
|
||||
MAKE_REF(cpvnormalize_safe);
|
||||
MAKE_REF(cpvclamp);
|
||||
MAKE_REF(cpvlerpconst);
|
||||
MAKE_REF(cpvdist);
|
||||
|
|
@ -50,104 +74,20 @@ MAKE_REF(cpflerp);
|
|||
MAKE_REF(cpflerpconst);
|
||||
|
||||
MAKE_REF(cpBBNew);
|
||||
MAKE_REF(cpBBNewForExtents);
|
||||
MAKE_REF(cpBBNewForCircle);
|
||||
MAKE_REF(cpBBIntersects);
|
||||
MAKE_REF(cpBBContainsBB);
|
||||
MAKE_REF(cpBBContainsVect);
|
||||
MAKE_REF(cpBBMerge);
|
||||
MAKE_REF(cpBBExpand);
|
||||
MAKE_REF(cpBBCenter);
|
||||
MAKE_REF(cpBBArea);
|
||||
MAKE_REF(cpBBMergedArea);
|
||||
MAKE_REF(cpBBSegmentQuery);
|
||||
MAKE_REF(cpBBIntersectsSegment);
|
||||
MAKE_REF(cpBBClampVect);
|
||||
|
||||
MAKE_REF(cpBodyGetMass);
|
||||
MAKE_REF(cpBodyGetMoment);
|
||||
MAKE_REF(cpBodyGetPos);
|
||||
MAKE_REF(cpBodyGetAngle);
|
||||
MAKE_REF(cpBodyGetRot);
|
||||
MAKE_PROPERTIES_REF(cpBody, Vel);
|
||||
MAKE_PROPERTIES_REF(cpBody, Force);
|
||||
MAKE_PROPERTIES_REF(cpBody, AngVel);
|
||||
MAKE_PROPERTIES_REF(cpBody, Torque);
|
||||
MAKE_PROPERTIES_REF(cpBody, VelLimit);
|
||||
MAKE_PROPERTIES_REF(cpBody, AngVelLimit);
|
||||
MAKE_PROPERTIES_REF(cpBody, UserData);
|
||||
MAKE_REF(cpBodyIsSleeping);
|
||||
MAKE_REF(cpBodyIsStatic);
|
||||
MAKE_REF(cpBodyIsRogue);
|
||||
MAKE_REF(cpBodyLocal2World);
|
||||
MAKE_REF(cpBodyWorld2Local);
|
||||
MAKE_REF(cpBodyKineticEnergy);
|
||||
|
||||
MAKE_REF(cpShapeGetBB);
|
||||
MAKE_PROPERTIES_REF(cpShape, Body);
|
||||
MAKE_PROPERTIES_REF(cpShape, Sensor);
|
||||
MAKE_PROPERTIES_REF(cpShape, Elasticity);
|
||||
MAKE_PROPERTIES_REF(cpShape, Friction);
|
||||
MAKE_PROPERTIES_REF(cpShape, SurfaceVelocity);
|
||||
MAKE_PROPERTIES_REF(cpShape, UserData);
|
||||
MAKE_PROPERTIES_REF(cpShape, CollisionType);
|
||||
MAKE_PROPERTIES_REF(cpShape, Group);
|
||||
MAKE_PROPERTIES_REF(cpShape, Layers);
|
||||
|
||||
MAKE_REF(cpArbiterGetShapes);
|
||||
MAKE_REF(cpArbiterGetBodies);
|
||||
MAKE_REF(cpArbiterIsFirstContact);
|
||||
MAKE_REF(cpArbiterGetCount);
|
||||
|
||||
MAKE_REF(cpConstraintGetA);
|
||||
MAKE_REF(cpConstraintGetB);
|
||||
MAKE_PROPERTIES_REF(cpConstraint, MaxForce);
|
||||
MAKE_PROPERTIES_REF(cpConstraint, ErrorBias);
|
||||
MAKE_PROPERTIES_REF(cpConstraint, MaxBias);
|
||||
MAKE_PROPERTIES_REF(cpConstraint, UserData);
|
||||
MAKE_REF(cpConstraintGetImpulse);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpDampedRotarySpring, RestAngle);
|
||||
MAKE_PROPERTIES_REF(cpDampedRotarySpring, Stiffness);
|
||||
MAKE_PROPERTIES_REF(cpDampedRotarySpring, Damping);
|
||||
//MAKE_PROPERTIES_REF(cpDampedRotarySpring, SpringTorqueFunc);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpDampedSpring, Anchr1);
|
||||
MAKE_PROPERTIES_REF(cpDampedSpring, Anchr2);
|
||||
MAKE_PROPERTIES_REF(cpDampedSpring, RestLength);
|
||||
MAKE_PROPERTIES_REF(cpDampedSpring, Stiffness);
|
||||
MAKE_PROPERTIES_REF(cpDampedSpring, Damping);
|
||||
//MAKE_PROPERTIES_REF(cpDampedSpring, SpringForceFunc);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpGearJoint, Phase);
|
||||
MAKE_REF(cpGearJointGetRatio);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpGrooveJoint, Anchr2);
|
||||
MAKE_REF(cpGrooveJointGetGrooveA);
|
||||
MAKE_REF(cpGrooveJointGetGrooveB);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpPinJoint, Anchr1);
|
||||
MAKE_PROPERTIES_REF(cpPinJoint, Anchr2);
|
||||
MAKE_PROPERTIES_REF(cpPinJoint, Dist);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpPivotJoint, Anchr1);
|
||||
MAKE_PROPERTIES_REF(cpPivotJoint, Anchr2);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpRatchetJoint, Angle);
|
||||
MAKE_PROPERTIES_REF(cpRatchetJoint, Phase);
|
||||
MAKE_PROPERTIES_REF(cpRatchetJoint, Ratchet);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpRotaryLimitJoint, Min);
|
||||
MAKE_PROPERTIES_REF(cpRotaryLimitJoint, Max);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpSimpleMotor, Rate);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpSlideJoint, Anchr1);
|
||||
MAKE_PROPERTIES_REF(cpSlideJoint, Anchr2);
|
||||
MAKE_PROPERTIES_REF(cpSlideJoint, Min);
|
||||
MAKE_PROPERTIES_REF(cpSlideJoint, Max);
|
||||
|
||||
MAKE_REF(cpSegmentQueryHitPoint);
|
||||
MAKE_REF(cpSegmentQueryHitDist);
|
||||
|
||||
MAKE_REF(cpSpatialIndexDestroy);
|
||||
MAKE_REF(cpSpatialIndexCount);
|
||||
MAKE_REF(cpSpatialIndexEach);
|
||||
|
|
@ -160,18 +100,8 @@ MAKE_REF(cpSpatialIndexSegmentQuery);
|
|||
MAKE_REF(cpSpatialIndexQuery);
|
||||
MAKE_REF(cpSpatialIndexReindexQuery);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpSpace, Iterations);
|
||||
MAKE_PROPERTIES_REF(cpSpace, Gravity);
|
||||
MAKE_PROPERTIES_REF(cpSpace, Damping);
|
||||
MAKE_PROPERTIES_REF(cpSpace, IdleSpeedThreshold);
|
||||
MAKE_PROPERTIES_REF(cpSpace, SleepTimeThreshold);
|
||||
MAKE_PROPERTIES_REF(cpSpace, CollisionSlop);
|
||||
MAKE_PROPERTIES_REF(cpSpace, CollisionBias);
|
||||
MAKE_PROPERTIES_REF(cpSpace, CollisionPersistence);
|
||||
MAKE_PROPERTIES_REF(cpSpace, EnableContactGraph);
|
||||
MAKE_PROPERTIES_REF(cpSpace, UserData);
|
||||
MAKE_REF(cpSpaceGetStaticBody);
|
||||
MAKE_REF(cpSpaceGetCurrentTimeStep);
|
||||
MAKE_REF(cpSpaceIsLocked);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2007 Scott Lembcke
|
||||
/* Copyright (c) 2013 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
|
||||
|
|
@ -18,9 +18,14 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#ifndef CHIPMUNK_PRIVATE_H
|
||||
#define CHIPMUNK_PRIVATE_H
|
||||
#ifdef CHIPMUNK_H
|
||||
#error Cannot include chipmunk_private.h after chipmunk.h.
|
||||
#endif
|
||||
|
||||
#define CP_ALLOW_PRIVATE_ACCESS 1
|
||||
#include "chipmunk.h"
|
||||
#include "chipmunk/chipmunk.h"
|
||||
|
||||
#define CP_HASH_COEF (3344921057ul)
|
||||
#define CP_HASH_PAIR(A, B) ((cpHashValue)(A)*CP_HASH_COEF ^ (cpHashValue)(B)*CP_HASH_COEF)
|
||||
|
|
@ -28,6 +33,7 @@
|
|||
// TODO: Eww. Magic numbers.
|
||||
#define MAGIC_EPSILON 1e-5
|
||||
|
||||
|
||||
//MARK: cpArray
|
||||
|
||||
struct cpArray {
|
||||
|
|
@ -47,6 +53,690 @@ cpBool cpArrayContains(cpArray *arr, void *ptr);
|
|||
void cpArrayFreeEach(cpArray *arr, void (freeFunc)(void*));
|
||||
|
||||
|
||||
//MARK: cpHashSet
|
||||
|
||||
typedef cpBool (*cpHashSetEqlFunc)(void *ptr, void *elt);
|
||||
typedef void *(*cpHashSetTransFunc)(void *ptr, void *data);
|
||||
|
||||
cpHashSet *cpHashSetNew(int size, cpHashSetEqlFunc eqlFunc);
|
||||
void cpHashSetSetDefaultValue(cpHashSet *set, void *default_value);
|
||||
|
||||
void cpHashSetFree(cpHashSet *set);
|
||||
|
||||
int cpHashSetCount(cpHashSet *set);
|
||||
void *cpHashSetInsert(cpHashSet *set, cpHashValue hash, void *ptr, cpHashSetTransFunc trans, void *data);
|
||||
void *cpHashSetRemove(cpHashSet *set, cpHashValue hash, void *ptr);
|
||||
void *cpHashSetFind(cpHashSet *set, cpHashValue hash, void *ptr);
|
||||
|
||||
typedef void (*cpHashSetIteratorFunc)(void *elt, void *data);
|
||||
void cpHashSetEach(cpHashSet *set, cpHashSetIteratorFunc func, void *data);
|
||||
|
||||
typedef cpBool (*cpHashSetFilterFunc)(void *elt, void *data);
|
||||
void cpHashSetFilter(cpHashSet *set, cpHashSetFilterFunc func, void *data);
|
||||
|
||||
|
||||
//MARK: Bodies
|
||||
|
||||
struct cpBody {
|
||||
// Integration functions
|
||||
cpBodyVelocityFunc velocity_func;
|
||||
cpBodyPositionFunc position_func;
|
||||
|
||||
// mass and it's inverse
|
||||
cpFloat m;
|
||||
cpFloat m_inv;
|
||||
|
||||
// moment of inertia and it's inverse
|
||||
cpFloat i;
|
||||
cpFloat i_inv;
|
||||
|
||||
// center of gravity
|
||||
cpVect cog;
|
||||
|
||||
// position, velocity, force
|
||||
cpVect p;
|
||||
cpVect v;
|
||||
cpVect f;
|
||||
|
||||
// Angle, angular velocity, torque (radians)
|
||||
cpFloat a;
|
||||
cpFloat w;
|
||||
cpFloat t;
|
||||
|
||||
cpTransform transform;
|
||||
|
||||
cpDataPointer userData;
|
||||
|
||||
// "pseudo-velocities" used for eliminating overlap.
|
||||
// Erin Catto has some papers that talk about what these are.
|
||||
cpVect v_bias;
|
||||
cpFloat w_bias;
|
||||
|
||||
cpSpace *space;
|
||||
|
||||
cpShape *shapeList;
|
||||
cpArbiter *arbiterList;
|
||||
cpConstraint *constraintList;
|
||||
|
||||
struct {
|
||||
cpBody *root;
|
||||
cpBody *next;
|
||||
cpFloat idleTime;
|
||||
} sleeping;
|
||||
};
|
||||
|
||||
void cpBodyAddShape(cpBody *body, cpShape *shape);
|
||||
void cpBodyRemoveShape(cpBody *body, cpShape *shape);
|
||||
|
||||
//void cpBodyAccumulateMassForShape(cpBody *body, cpShape *shape);
|
||||
void cpBodyAccumulateMassFromShapes(cpBody *body);
|
||||
|
||||
void cpBodyRemoveConstraint(cpBody *body, cpConstraint *constraint);
|
||||
|
||||
|
||||
//MARK: Spatial Index Functions
|
||||
|
||||
cpSpatialIndex *cpSpatialIndexInit(cpSpatialIndex *index, cpSpatialIndexClass *klass, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
|
||||
|
||||
//MARK: Arbiters
|
||||
|
||||
enum cpArbiterState {
|
||||
// Arbiter is active and its the first collision.
|
||||
CP_ARBITER_STATE_FIRST_COLLISION,
|
||||
// Arbiter is active and its not the first collision.
|
||||
CP_ARBITER_STATE_NORMAL,
|
||||
// Collision has been explicitly ignored.
|
||||
// Either by returning false from a begin collision handler or calling cpArbiterIgnore().
|
||||
CP_ARBITER_STATE_IGNORE,
|
||||
// Collison is no longer active. A space will cache an arbiter for up to cpSpace.collisionPersistence more steps.
|
||||
CP_ARBITER_STATE_CACHED,
|
||||
// Collison arbiter is invalid because one of the shapes was removed.
|
||||
CP_ARBITER_STATE_INVALIDATED,
|
||||
};
|
||||
|
||||
struct cpArbiterThread {
|
||||
struct cpArbiter *next, *prev;
|
||||
};
|
||||
|
||||
struct cpContact {
|
||||
cpVect r1, r2;
|
||||
|
||||
cpFloat nMass, tMass;
|
||||
cpFloat bounce; // TODO: look for an alternate bounce solution.
|
||||
|
||||
cpFloat jnAcc, jtAcc, jBias;
|
||||
cpFloat bias;
|
||||
|
||||
cpHashValue hash;
|
||||
};
|
||||
|
||||
struct cpCollisionInfo {
|
||||
const cpShape *a, *b;
|
||||
cpCollisionID id;
|
||||
|
||||
cpVect n;
|
||||
|
||||
int count;
|
||||
// TODO Should this be a unique struct type?
|
||||
struct cpContact *arr;
|
||||
};
|
||||
|
||||
struct cpArbiter {
|
||||
cpFloat e;
|
||||
cpFloat u;
|
||||
cpVect surface_vr;
|
||||
|
||||
cpDataPointer data;
|
||||
|
||||
const cpShape *a, *b;
|
||||
cpBody *body_a, *body_b;
|
||||
struct cpArbiterThread thread_a, thread_b;
|
||||
|
||||
int count;
|
||||
struct cpContact *contacts;
|
||||
cpVect n;
|
||||
|
||||
// Regular, wildcard A and wildcard B collision handlers.
|
||||
cpCollisionHandler *handler, *handlerA, *handlerB;
|
||||
cpBool swapped;
|
||||
|
||||
cpTimestamp stamp;
|
||||
enum cpArbiterState state;
|
||||
};
|
||||
|
||||
cpArbiter* cpArbiterInit(cpArbiter *arb, cpShape *a, cpShape *b);
|
||||
|
||||
static inline struct cpArbiterThread *
|
||||
cpArbiterThreadForBody(cpArbiter *arb, cpBody *body)
|
||||
{
|
||||
return (arb->body_a == body ? &arb->thread_a : &arb->thread_b);
|
||||
}
|
||||
|
||||
void cpArbiterUnthread(cpArbiter *arb);
|
||||
|
||||
void cpArbiterUpdate(cpArbiter *arb, struct cpCollisionInfo *info, cpSpace *space);
|
||||
void cpArbiterPreStep(cpArbiter *arb, cpFloat dt, cpFloat bias, cpFloat slop);
|
||||
void cpArbiterApplyCachedImpulse(cpArbiter *arb, cpFloat dt_coef);
|
||||
void cpArbiterApplyImpulse(cpArbiter *arb);
|
||||
|
||||
|
||||
//MARK: Shapes/Collisions
|
||||
|
||||
struct cpShapeMassInfo {
|
||||
cpFloat m;
|
||||
cpFloat i;
|
||||
cpVect cog;
|
||||
cpFloat area;
|
||||
};
|
||||
|
||||
typedef enum cpShapeType{
|
||||
CP_CIRCLE_SHAPE,
|
||||
CP_SEGMENT_SHAPE,
|
||||
CP_POLY_SHAPE,
|
||||
CP_NUM_SHAPES
|
||||
} cpShapeType;
|
||||
|
||||
typedef cpBB (*cpShapeCacheDataImpl)(cpShape *shape, cpTransform transform);
|
||||
typedef void (*cpShapeDestroyImpl)(cpShape *shape);
|
||||
typedef void (*cpShapePointQueryImpl)(const cpShape *shape, cpVect p, cpPointQueryInfo *info);
|
||||
typedef void (*cpShapeSegmentQueryImpl)(const cpShape *shape, cpVect a, cpVect b, cpFloat radius, cpSegmentQueryInfo *info);
|
||||
|
||||
typedef struct cpShapeClass cpShapeClass;
|
||||
|
||||
struct cpShapeClass {
|
||||
cpShapeType type;
|
||||
|
||||
cpShapeCacheDataImpl cacheData;
|
||||
cpShapeDestroyImpl destroy;
|
||||
cpShapePointQueryImpl pointQuery;
|
||||
cpShapeSegmentQueryImpl segmentQuery;
|
||||
};
|
||||
|
||||
struct cpShape {
|
||||
const cpShapeClass *klass;
|
||||
|
||||
cpSpace *space;
|
||||
cpBody *body;
|
||||
struct cpShapeMassInfo massInfo;
|
||||
cpBB bb;
|
||||
|
||||
cpBool sensor;
|
||||
|
||||
cpFloat e;
|
||||
cpFloat u;
|
||||
cpVect surfaceV;
|
||||
|
||||
cpDataPointer userData;
|
||||
|
||||
cpCollisionType type;
|
||||
cpShapeFilter filter;
|
||||
|
||||
cpShape *next;
|
||||
cpShape *prev;
|
||||
|
||||
cpHashValue hashid;
|
||||
};
|
||||
|
||||
struct cpCircleShape {
|
||||
cpShape shape;
|
||||
|
||||
cpVect c, tc;
|
||||
cpFloat r;
|
||||
};
|
||||
|
||||
struct cpSegmentShape {
|
||||
cpShape shape;
|
||||
|
||||
cpVect a, b, n;
|
||||
cpVect ta, tb, tn;
|
||||
cpFloat r;
|
||||
|
||||
cpVect a_tangent, b_tangent;
|
||||
};
|
||||
|
||||
struct cpSplittingPlane {
|
||||
cpVect v0, n;
|
||||
};
|
||||
|
||||
#define CP_POLY_SHAPE_INLINE_ALLOC 6
|
||||
|
||||
struct cpPolyShape {
|
||||
cpShape shape;
|
||||
|
||||
cpFloat r;
|
||||
|
||||
int count;
|
||||
// The untransformed planes are appended at the end of the transformed planes.
|
||||
struct cpSplittingPlane *planes;
|
||||
|
||||
// Allocate a small number of splitting planes internally for simple poly.
|
||||
struct cpSplittingPlane _planes[2*CP_POLY_SHAPE_INLINE_ALLOC];
|
||||
};
|
||||
|
||||
cpShape *cpShapeInit(cpShape *shape, const cpShapeClass *klass, cpBody *body, struct cpShapeMassInfo massInfo);
|
||||
|
||||
static inline cpBool
|
||||
cpShapeActive(cpShape *shape)
|
||||
{
|
||||
// checks if the shape is added to a shape list.
|
||||
// TODO could this just check the space now?
|
||||
return (shape->prev || (shape->body && shape->body->shapeList == shape));
|
||||
}
|
||||
|
||||
// Note: This function returns contact points with r1/r2 in absolute coordinates, not body relative.
|
||||
struct cpCollisionInfo cpCollide(const cpShape *a, const cpShape *b, cpCollisionID id, struct cpContact *contacts);
|
||||
|
||||
static inline void
|
||||
CircleSegmentQuery(cpShape *shape, cpVect center, cpFloat r1, cpVect a, cpVect b, cpFloat r2, cpSegmentQueryInfo *info)
|
||||
{
|
||||
cpVect da = cpvsub(a, center);
|
||||
cpVect db = cpvsub(b, center);
|
||||
cpFloat rsum = r1 + r2;
|
||||
|
||||
cpFloat qa = cpvdot(da, da) - 2.0f*cpvdot(da, db) + cpvdot(db, db);
|
||||
cpFloat qb = cpvdot(da, db) - cpvdot(da, da);
|
||||
cpFloat det = qb*qb - qa*(cpvdot(da, da) - rsum*rsum);
|
||||
|
||||
if(det >= 0.0f){
|
||||
cpFloat t = (-qb - cpfsqrt(det))/(qa);
|
||||
if(0.0f<= t && t <= 1.0f){
|
||||
cpVect n = cpvnormalize(cpvlerp(da, db, t));
|
||||
|
||||
info->shape = shape;
|
||||
info->point = cpvsub(cpvlerp(a, b, t), cpvmult(n, r2));
|
||||
info->normal = n;
|
||||
info->alpha = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline cpBool
|
||||
cpShapeFilterReject(cpShapeFilter a, cpShapeFilter b)
|
||||
{
|
||||
// Reject the collision if:
|
||||
return (
|
||||
// They are in the same non-zero group.
|
||||
(a.group != 0 && a.group == b.group) ||
|
||||
// One of the category/mask combinations fails.
|
||||
(a.categories & b.mask) == 0 ||
|
||||
(b.categories & a.mask) == 0
|
||||
);
|
||||
}
|
||||
|
||||
void cpLoopIndexes(const cpVect *verts, int count, int *start, int *end);
|
||||
|
||||
|
||||
//MARK: Constraints
|
||||
// TODO naming conventions here
|
||||
|
||||
typedef void (*cpConstraintPreStepImpl)(cpConstraint *constraint, cpFloat dt);
|
||||
typedef void (*cpConstraintApplyCachedImpulseImpl)(cpConstraint *constraint, cpFloat dt_coef);
|
||||
typedef void (*cpConstraintApplyImpulseImpl)(cpConstraint *constraint, cpFloat dt);
|
||||
typedef cpFloat (*cpConstraintGetImpulseImpl)(cpConstraint *constraint);
|
||||
|
||||
typedef struct cpConstraintClass {
|
||||
cpConstraintPreStepImpl preStep;
|
||||
cpConstraintApplyCachedImpulseImpl applyCachedImpulse;
|
||||
cpConstraintApplyImpulseImpl applyImpulse;
|
||||
cpConstraintGetImpulseImpl getImpulse;
|
||||
} cpConstraintClass;
|
||||
|
||||
struct cpConstraint {
|
||||
const cpConstraintClass *klass;
|
||||
|
||||
cpSpace *space;
|
||||
|
||||
cpBody *a, *b;
|
||||
cpConstraint *next_a, *next_b;
|
||||
|
||||
cpFloat maxForce;
|
||||
cpFloat errorBias;
|
||||
cpFloat maxBias;
|
||||
|
||||
cpBool collideBodies;
|
||||
|
||||
cpConstraintPreSolveFunc preSolve;
|
||||
cpConstraintPostSolveFunc postSolve;
|
||||
|
||||
cpDataPointer userData;
|
||||
};
|
||||
|
||||
struct cpPinJoint {
|
||||
cpConstraint constraint;
|
||||
cpVect anchorA, anchorB;
|
||||
cpFloat dist;
|
||||
|
||||
cpVect r1, r2;
|
||||
cpVect n;
|
||||
cpFloat nMass;
|
||||
|
||||
cpFloat jnAcc;
|
||||
cpFloat bias;
|
||||
};
|
||||
|
||||
struct cpSlideJoint {
|
||||
cpConstraint constraint;
|
||||
cpVect anchorA, anchorB;
|
||||
cpFloat min, max;
|
||||
|
||||
cpVect r1, r2;
|
||||
cpVect n;
|
||||
cpFloat nMass;
|
||||
|
||||
cpFloat jnAcc;
|
||||
cpFloat bias;
|
||||
};
|
||||
|
||||
struct cpPivotJoint {
|
||||
cpConstraint constraint;
|
||||
cpVect anchorA, anchorB;
|
||||
|
||||
cpVect r1, r2;
|
||||
cpMat2x2 k;
|
||||
|
||||
cpVect jAcc;
|
||||
cpVect bias;
|
||||
};
|
||||
|
||||
struct cpGrooveJoint {
|
||||
cpConstraint constraint;
|
||||
cpVect grv_n, grv_a, grv_b;
|
||||
cpVect anchorB;
|
||||
|
||||
cpVect grv_tn;
|
||||
cpFloat clamp;
|
||||
cpVect r1, r2;
|
||||
cpMat2x2 k;
|
||||
|
||||
cpVect jAcc;
|
||||
cpVect bias;
|
||||
};
|
||||
|
||||
struct cpDampedSpring {
|
||||
cpConstraint constraint;
|
||||
cpVect anchorA, anchorB;
|
||||
cpFloat restLength;
|
||||
cpFloat stiffness;
|
||||
cpFloat damping;
|
||||
cpDampedSpringForceFunc springForceFunc;
|
||||
|
||||
cpFloat target_vrn;
|
||||
cpFloat v_coef;
|
||||
|
||||
cpVect r1, r2;
|
||||
cpFloat nMass;
|
||||
cpVect n;
|
||||
|
||||
cpFloat jAcc;
|
||||
};
|
||||
|
||||
struct cpDampedRotarySpring {
|
||||
cpConstraint constraint;
|
||||
cpFloat restAngle;
|
||||
cpFloat stiffness;
|
||||
cpFloat damping;
|
||||
cpDampedRotarySpringTorqueFunc springTorqueFunc;
|
||||
|
||||
cpFloat target_wrn;
|
||||
cpFloat w_coef;
|
||||
|
||||
cpFloat iSum;
|
||||
cpFloat jAcc;
|
||||
};
|
||||
|
||||
struct cpRotaryLimitJoint {
|
||||
cpConstraint constraint;
|
||||
cpFloat min, max;
|
||||
|
||||
cpFloat iSum;
|
||||
|
||||
cpFloat bias;
|
||||
cpFloat jAcc;
|
||||
};
|
||||
|
||||
struct cpRatchetJoint {
|
||||
cpConstraint constraint;
|
||||
cpFloat angle, phase, ratchet;
|
||||
|
||||
cpFloat iSum;
|
||||
|
||||
cpFloat bias;
|
||||
cpFloat jAcc;
|
||||
};
|
||||
|
||||
struct cpGearJoint {
|
||||
cpConstraint constraint;
|
||||
cpFloat phase, ratio;
|
||||
cpFloat ratio_inv;
|
||||
|
||||
cpFloat iSum;
|
||||
|
||||
cpFloat bias;
|
||||
cpFloat jAcc;
|
||||
};
|
||||
|
||||
struct cpSimpleMotor {
|
||||
cpConstraint constraint;
|
||||
cpFloat rate;
|
||||
|
||||
cpFloat iSum;
|
||||
|
||||
cpFloat jAcc;
|
||||
};
|
||||
|
||||
void cpConstraintInit(cpConstraint *constraint, const struct cpConstraintClass *klass, cpBody *a, cpBody *b);
|
||||
|
||||
static inline void
|
||||
cpConstraintActivateBodies(cpConstraint *constraint)
|
||||
{
|
||||
cpBody *a = constraint->a; cpBodyActivate(a);
|
||||
cpBody *b = constraint->b; cpBodyActivate(b);
|
||||
}
|
||||
|
||||
static inline cpVect
|
||||
relative_velocity(cpBody *a, cpBody *b, cpVect r1, cpVect r2){
|
||||
cpVect v1_sum = cpvadd(a->CP_PRIVATE(v), cpvmult(cpvperp(r1), a->CP_PRIVATE(w)));
|
||||
cpVect v2_sum = cpvadd(b->CP_PRIVATE(v), cpvmult(cpvperp(r2), b->CP_PRIVATE(w)));
|
||||
|
||||
return cpvsub(v2_sum, v1_sum);
|
||||
}
|
||||
|
||||
static inline cpFloat
|
||||
normal_relative_velocity(cpBody *a, cpBody *b, cpVect r1, cpVect r2, cpVect n){
|
||||
return cpvdot(relative_velocity(a, b, r1, r2), n);
|
||||
}
|
||||
|
||||
static inline void
|
||||
apply_impulse(cpBody *body, cpVect j, cpVect r){
|
||||
body->CP_PRIVATE(v) = cpvadd(body->CP_PRIVATE(v), cpvmult(j, body->CP_PRIVATE(m_inv)));
|
||||
body->CP_PRIVATE(w) += body->CP_PRIVATE(i_inv)*cpvcross(r, j);
|
||||
}
|
||||
|
||||
static inline void
|
||||
apply_impulses(cpBody *a , cpBody *b, cpVect r1, cpVect r2, cpVect j)
|
||||
{
|
||||
apply_impulse(a, cpvneg(j), r1);
|
||||
apply_impulse(b, j, r2);
|
||||
}
|
||||
|
||||
static inline void
|
||||
apply_bias_impulse(cpBody *body, cpVect j, cpVect r)
|
||||
{
|
||||
body->CP_PRIVATE(v_bias) = cpvadd(body->CP_PRIVATE(v_bias), cpvmult(j, body->CP_PRIVATE(m_inv)));
|
||||
body->CP_PRIVATE(w_bias) += body->CP_PRIVATE(i_inv)*cpvcross(r, j);
|
||||
}
|
||||
|
||||
static inline void
|
||||
apply_bias_impulses(cpBody *a , cpBody *b, cpVect r1, cpVect r2, cpVect j)
|
||||
{
|
||||
apply_bias_impulse(a, cpvneg(j), r1);
|
||||
apply_bias_impulse(b, j, r2);
|
||||
}
|
||||
|
||||
static inline cpFloat
|
||||
k_scalar_body(cpBody *body, cpVect r, cpVect n)
|
||||
{
|
||||
cpFloat rcn = cpvcross(r, n);
|
||||
return body->CP_PRIVATE(m_inv) + body->CP_PRIVATE(i_inv)*rcn*rcn;
|
||||
}
|
||||
|
||||
static inline cpFloat
|
||||
k_scalar(cpBody *a, cpBody *b, cpVect r1, cpVect r2, cpVect n)
|
||||
{
|
||||
cpFloat value = k_scalar_body(a, r1, n) + k_scalar_body(b, r2, n);
|
||||
cpAssertSoft(value != 0.0, "Unsolvable collision or constraint.");
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static inline cpMat2x2
|
||||
k_tensor(cpBody *a, cpBody *b, cpVect r1, cpVect r2)
|
||||
{
|
||||
cpFloat m_sum = a->CP_PRIVATE(m_inv) + b->CP_PRIVATE(m_inv);
|
||||
|
||||
// start with Identity*m_sum
|
||||
cpFloat k11 = m_sum, k12 = 0.0f;
|
||||
cpFloat k21 = 0.0f, k22 = m_sum;
|
||||
|
||||
// add the influence from r1
|
||||
cpFloat a_i_inv = a->CP_PRIVATE(i_inv);
|
||||
cpFloat r1xsq = r1.x * r1.x * a_i_inv;
|
||||
cpFloat r1ysq = r1.y * r1.y * a_i_inv;
|
||||
cpFloat r1nxy = -r1.x * r1.y * a_i_inv;
|
||||
k11 += r1ysq; k12 += r1nxy;
|
||||
k21 += r1nxy; k22 += r1xsq;
|
||||
|
||||
// add the influnce from r2
|
||||
cpFloat b_i_inv = b->CP_PRIVATE(i_inv);
|
||||
cpFloat r2xsq = r2.x * r2.x * b_i_inv;
|
||||
cpFloat r2ysq = r2.y * r2.y * b_i_inv;
|
||||
cpFloat r2nxy = -r2.x * r2.y * b_i_inv;
|
||||
k11 += r2ysq; k12 += r2nxy;
|
||||
k21 += r2nxy; k22 += r2xsq;
|
||||
|
||||
// invert
|
||||
cpFloat det = k11*k22 - k12*k21;
|
||||
cpAssertSoft(det != 0.0, "Unsolvable constraint.");
|
||||
|
||||
cpFloat det_inv = 1.0f/det;
|
||||
return cpMat2x2New(
|
||||
k22*det_inv, -k12*det_inv,
|
||||
-k21*det_inv, k11*det_inv
|
||||
);
|
||||
}
|
||||
|
||||
static inline cpFloat
|
||||
bias_coef(cpFloat errorBias, cpFloat dt)
|
||||
{
|
||||
return 1.0f - cpfpow(errorBias, dt);
|
||||
}
|
||||
|
||||
|
||||
//MARK: Spaces
|
||||
|
||||
typedef struct cpContactBufferHeader cpContactBufferHeader;
|
||||
typedef void (*cpSpaceArbiterApplyImpulseFunc)(cpArbiter *arb);
|
||||
|
||||
struct cpSpace {
|
||||
int iterations;
|
||||
|
||||
cpVect gravity;
|
||||
cpFloat damping;
|
||||
|
||||
cpFloat idleSpeedThreshold;
|
||||
cpFloat sleepTimeThreshold;
|
||||
|
||||
cpFloat collisionSlop;
|
||||
cpFloat collisionBias;
|
||||
cpTimestamp collisionPersistence;
|
||||
|
||||
cpDataPointer userData;
|
||||
|
||||
cpTimestamp stamp;
|
||||
cpFloat curr_dt;
|
||||
|
||||
cpArray *dynamicBodies;
|
||||
cpArray *staticBodies;
|
||||
cpArray *rousedBodies;
|
||||
cpArray *sleepingComponents;
|
||||
|
||||
cpHashValue shapeIDCounter;
|
||||
cpSpatialIndex *staticShapes;
|
||||
cpSpatialIndex *dynamicShapes;
|
||||
|
||||
cpArray *constraints;
|
||||
|
||||
cpArray *arbiters;
|
||||
cpContactBufferHeader *contactBuffersHead;
|
||||
cpHashSet *cachedArbiters;
|
||||
cpArray *pooledArbiters;
|
||||
|
||||
cpArray *allocatedBuffers;
|
||||
unsigned int locked;
|
||||
|
||||
cpBool usesWildcards;
|
||||
cpHashSet *collisionHandlers;
|
||||
cpCollisionHandler defaultHandler;
|
||||
|
||||
cpBool skipPostStep;
|
||||
cpArray *postStepCallbacks;
|
||||
|
||||
cpBody *staticBody;
|
||||
cpBody _staticBody;
|
||||
};
|
||||
|
||||
#define cpAssertSpaceUnlocked(space) \
|
||||
cpAssertHard(!space->locked, \
|
||||
"This operation cannot be done safely during a call to cpSpaceStep() or during a query. " \
|
||||
"Put these calls into a post-step callback." \
|
||||
);
|
||||
|
||||
void cpSpaceSetStaticBody(cpSpace *space, cpBody *body);
|
||||
|
||||
extern cpCollisionHandler cpCollisionHandlerDoNothing;
|
||||
|
||||
void cpSpaceProcessComponents(cpSpace *space, cpFloat dt);
|
||||
|
||||
void cpSpacePushFreshContactBuffer(cpSpace *space);
|
||||
struct cpContact *cpContactBufferGetArray(cpSpace *space);
|
||||
void cpSpacePushContacts(cpSpace *space, int count);
|
||||
|
||||
typedef struct cpPostStepCallback {
|
||||
cpPostStepFunc func;
|
||||
void *key;
|
||||
void *data;
|
||||
} cpPostStepCallback;
|
||||
|
||||
cpPostStepCallback *cpSpaceGetPostStepCallback(cpSpace *space, void *key);
|
||||
|
||||
cpBool cpSpaceArbiterSetFilter(cpArbiter *arb, cpSpace *space);
|
||||
void cpSpaceFilterArbiters(cpSpace *space, cpBody *body, cpShape *filter);
|
||||
|
||||
void cpSpaceActivateBody(cpSpace *space, cpBody *body);
|
||||
void cpSpaceLock(cpSpace *space);
|
||||
void cpSpaceUnlock(cpSpace *space, cpBool runPostStep);
|
||||
|
||||
static inline void
|
||||
cpSpaceUncacheArbiter(cpSpace *space, cpArbiter *arb)
|
||||
{
|
||||
const cpShape *a = arb->a, *b = arb->b;
|
||||
const cpShape *shape_pair[] = {a, b};
|
||||
cpHashValue arbHashID = CP_HASH_PAIR((cpHashValue)a, (cpHashValue)b);
|
||||
cpHashSetRemove(space->cachedArbiters, arbHashID, shape_pair);
|
||||
cpArrayDeleteObj(space->arbiters, arb);
|
||||
}
|
||||
|
||||
static inline cpArray *
|
||||
cpSpaceArrayForBodyType(cpSpace *space, cpBodyType type)
|
||||
{
|
||||
return (type == CP_BODY_TYPE_STATIC ? space->staticBodies : space->dynamicBodies);
|
||||
}
|
||||
|
||||
void cpShapeUpdateFunc(cpShape *shape, void *unused);
|
||||
cpCollisionID cpSpaceCollideShapes(cpShape *a, cpShape *b, cpCollisionID id, cpSpace *space);
|
||||
|
||||
|
||||
//MARK: Foreach loops
|
||||
|
||||
static inline cpConstraint *
|
||||
|
|
@ -71,184 +761,6 @@ cpArbiterNext(cpArbiter *node, cpBody *body)
|
|||
for(cpShape *var = body->shapeList; var; var = var->next)
|
||||
|
||||
#define CP_BODY_FOREACH_COMPONENT(root, var)\
|
||||
for(cpBody *var = root; var; var = var->node.next)
|
||||
for(cpBody *var = root; var; var = var->sleeping.next)
|
||||
|
||||
|
||||
//MARK: cpHashSet
|
||||
|
||||
typedef cpBool (*cpHashSetEqlFunc)(void *ptr, void *elt);
|
||||
typedef void *(*cpHashSetTransFunc)(void *ptr, void *data);
|
||||
|
||||
cpHashSet *cpHashSetNew(int size, cpHashSetEqlFunc eqlFunc);
|
||||
void cpHashSetSetDefaultValue(cpHashSet *set, void *default_value);
|
||||
|
||||
void cpHashSetFree(cpHashSet *set);
|
||||
|
||||
int cpHashSetCount(cpHashSet *set);
|
||||
void *cpHashSetInsert(cpHashSet *set, cpHashValue hash, void *ptr, void *data, cpHashSetTransFunc trans);
|
||||
void *cpHashSetRemove(cpHashSet *set, cpHashValue hash, void *ptr);
|
||||
void *cpHashSetFind(cpHashSet *set, cpHashValue hash, void *ptr);
|
||||
|
||||
typedef void (*cpHashSetIteratorFunc)(void *elt, void *data);
|
||||
void cpHashSetEach(cpHashSet *set, cpHashSetIteratorFunc func, void *data);
|
||||
|
||||
typedef cpBool (*cpHashSetFilterFunc)(void *elt, void *data);
|
||||
void cpHashSetFilter(cpHashSet *set, cpHashSetFilterFunc func, void *data);
|
||||
|
||||
|
||||
//MARK: Body Functions
|
||||
|
||||
void cpBodyAddShape(cpBody *body, cpShape *shape);
|
||||
void cpBodyRemoveShape(cpBody *body, cpShape *shape);
|
||||
void cpBodyRemoveConstraint(cpBody *body, cpConstraint *constraint);
|
||||
|
||||
|
||||
//MARK: Shape/Collision Functions
|
||||
|
||||
// TODO should move this to the cpVect API. It's pretty useful.
|
||||
static inline cpVect
|
||||
cpClosetPointOnSegment(const cpVect p, const cpVect a, const cpVect b)
|
||||
{
|
||||
cpVect delta = cpvsub(a, b);
|
||||
cpFloat t = cpfclamp01(cpvdot(delta, cpvsub(p, b))/cpvlengthsq(delta));
|
||||
return cpvadd(b, cpvmult(delta, t));
|
||||
}
|
||||
|
||||
cpShape* cpShapeInit(cpShape *shape, const cpShapeClass *klass, cpBody *body);
|
||||
|
||||
static inline cpBool
|
||||
cpShapeActive(cpShape *shape)
|
||||
{
|
||||
return shape->prev || (shape->body && shape->body->shapeList == shape);
|
||||
}
|
||||
|
||||
int cpCollideShapes(const cpShape *a, const cpShape *b, cpCollisionID *id, cpContact *arr);
|
||||
|
||||
static inline void
|
||||
CircleSegmentQuery(cpShape *shape, cpVect center, cpFloat r, cpVect a, cpVect b, cpSegmentQueryInfo *info)
|
||||
{
|
||||
cpVect da = cpvsub(a, center);
|
||||
cpVect db = cpvsub(b, center);
|
||||
|
||||
cpFloat qa = cpvdot(da, da) - 2.0f*cpvdot(da, db) + cpvdot(db, db);
|
||||
cpFloat qb = -2.0f*cpvdot(da, da) + 2.0f*cpvdot(da, db);
|
||||
cpFloat qc = cpvdot(da, da) - r*r;
|
||||
|
||||
cpFloat det = qb*qb - 4.0f*qa*qc;
|
||||
|
||||
if(det >= 0.0f){
|
||||
cpFloat t = (-qb - cpfsqrt(det))/(2.0f*qa);
|
||||
if(0.0f<= t && t <= 1.0f){
|
||||
info->shape = shape;
|
||||
info->t = t;
|
||||
info->n = cpvnormalize(cpvlerp(da, db, t));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO doesn't really need to be inline, but need a better place to put this function
|
||||
static inline cpSplittingPlane
|
||||
cpSplittingPlaneNew(cpVect a, cpVect b)
|
||||
{
|
||||
cpVect n = cpvnormalize(cpvperp(cpvsub(b, a)));
|
||||
cpSplittingPlane plane = {n, cpvdot(n, a)};
|
||||
return plane;
|
||||
}
|
||||
|
||||
static inline cpFloat
|
||||
cpSplittingPlaneCompare(cpSplittingPlane plane, cpVect v)
|
||||
{
|
||||
return cpvdot(plane.n, v) - plane.d;
|
||||
}
|
||||
|
||||
void cpLoopIndexes(cpVect *verts, int count, int *start, int *end);
|
||||
|
||||
|
||||
//MARK: Spatial Index Functions
|
||||
|
||||
cpSpatialIndex *cpSpatialIndexInit(cpSpatialIndex *index, cpSpatialIndexClass *klass, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
|
||||
|
||||
//MARK: Space Functions
|
||||
|
||||
extern cpCollisionHandler cpDefaultCollisionHandler;
|
||||
void cpSpaceProcessComponents(cpSpace *space, cpFloat dt);
|
||||
|
||||
void cpSpacePushFreshContactBuffer(cpSpace *space);
|
||||
cpContact *cpContactBufferGetArray(cpSpace *space);
|
||||
void cpSpacePushContacts(cpSpace *space, int count);
|
||||
|
||||
typedef struct cpPostStepCallback {
|
||||
cpPostStepFunc func;
|
||||
void *key;
|
||||
void *data;
|
||||
} cpPostStepCallback;
|
||||
|
||||
cpPostStepCallback *cpSpaceGetPostStepCallback(cpSpace *space, void *key);
|
||||
|
||||
cpBool cpSpaceArbiterSetFilter(cpArbiter *arb, cpSpace *space);
|
||||
void cpSpaceFilterArbiters(cpSpace *space, cpBody *body, cpShape *filter);
|
||||
|
||||
void cpSpaceActivateBody(cpSpace *space, cpBody *body);
|
||||
void cpSpaceLock(cpSpace *space);
|
||||
void cpSpaceUnlock(cpSpace *space, cpBool runPostStep);
|
||||
|
||||
static inline cpCollisionHandler *
|
||||
cpSpaceLookupHandler(cpSpace *space, cpCollisionType a, cpCollisionType b)
|
||||
{
|
||||
cpCollisionType types[] = {a, b};
|
||||
return (cpCollisionHandler *)cpHashSetFind(space->collisionHandlers, CP_HASH_PAIR(a, b), types);
|
||||
}
|
||||
|
||||
static inline void
|
||||
cpSpaceUncacheArbiter(cpSpace *space, cpArbiter *arb)
|
||||
{
|
||||
cpShape *a = arb->a, *b = arb->b;
|
||||
cpShape *shape_pair[] = {a, b};
|
||||
cpHashValue arbHashID = CP_HASH_PAIR((cpHashValue)a, (cpHashValue)b);
|
||||
cpHashSetRemove(space->cachedArbiters, arbHashID, shape_pair);
|
||||
cpArrayDeleteObj(space->arbiters, arb);
|
||||
}
|
||||
|
||||
void cpShapeUpdateFunc(cpShape *shape, void *unused);
|
||||
cpCollisionID cpSpaceCollideShapes(cpShape *a, cpShape *b, cpCollisionID id, cpSpace *space);
|
||||
|
||||
|
||||
//MARK: Arbiters
|
||||
|
||||
struct cpContact {
|
||||
cpVect p, n;
|
||||
cpFloat dist;
|
||||
|
||||
cpVect r1, r2;
|
||||
cpFloat nMass, tMass, bounce;
|
||||
|
||||
cpFloat jnAcc, jtAcc, jBias;
|
||||
cpFloat bias;
|
||||
|
||||
cpHashValue hash;
|
||||
};
|
||||
|
||||
cpContact* cpContactInit(cpContact *con, cpVect p, cpVect n, cpFloat dist, cpHashValue hash);
|
||||
cpArbiter* cpArbiterInit(cpArbiter *arb, cpShape *a, cpShape *b);
|
||||
|
||||
static inline void
|
||||
cpArbiterCallSeparate(cpArbiter *arb, cpSpace *space)
|
||||
{
|
||||
// The handler needs to be looked up again as the handler cached on the arbiter may have been deleted since the last step.
|
||||
cpCollisionHandler *handler = cpSpaceLookupHandler(space, arb->a->collision_type, arb->b->collision_type);
|
||||
handler->separate(arb, space, handler->data);
|
||||
}
|
||||
|
||||
static inline struct cpArbiterThread *
|
||||
cpArbiterThreadForBody(cpArbiter *arb, cpBody *body)
|
||||
{
|
||||
return (arb->body_a == body ? &arb->thread_a : &arb->thread_b);
|
||||
}
|
||||
|
||||
void cpArbiterUnthread(cpArbiter *arb);
|
||||
|
||||
void cpArbiterUpdate(cpArbiter *arb, cpContact *contacts, int numContacts, struct cpCollisionHandler *handler, cpShape *a, cpShape *b);
|
||||
void cpArbiterPreStep(cpArbiter *arb, cpFloat dt, cpFloat bias, cpFloat slop);
|
||||
void cpArbiterApplyCachedImpulse(cpArbiter *arb, cpFloat dt_coef);
|
||||
void cpArbiterApplyImpulse(cpArbiter *arb);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,31 +1,34 @@
|
|||
/* Copyright (c) 2013 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.
|
||||
*/
|
||||
|
||||
#ifndef CHIPMUNK_TYPES_H
|
||||
#define CHIPMUNK_TYPES_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <float.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include "TargetConditionals.h"
|
||||
#endif
|
||||
|
||||
#if ((TARGET_OS_IPHONE == 1) || (TARGET_OS_MAC == 1)) && (!defined CP_USE_CGPOINTS)
|
||||
#define CP_USE_CGPOINTS 1
|
||||
#endif
|
||||
|
||||
#if CP_USE_CGPOINTS == 1
|
||||
#if TARGET_OS_IPHONE
|
||||
#import <CoreGraphics/CGGeometry.h>
|
||||
#elif TARGET_OS_MAC
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#endif
|
||||
|
||||
#if defined(__LP64__) && __LP64__
|
||||
#define CP_USE_DOUBLES 1
|
||||
#else
|
||||
#define CP_USE_DOUBLES 0
|
||||
#endif
|
||||
#endif
|
||||
#include <math.h>
|
||||
|
||||
#ifndef CP_USE_DOUBLES
|
||||
// use doubles by default for higher precision
|
||||
#define CP_USE_DOUBLES 1
|
||||
// Use doubles by default for higher precision.
|
||||
#define CP_USE_DOUBLES 0
|
||||
#endif
|
||||
|
||||
/// @defgroup basicTypes Basic Types
|
||||
|
|
@ -82,13 +85,8 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846264338327950288
|
||||
#endif
|
||||
|
||||
#ifndef M_E
|
||||
#define M_E 2.71828182845904523536028747135266250
|
||||
#endif
|
||||
#define CP_PI ((cpFloat)3.14159265358979323846264338327950288)
|
||||
|
||||
|
||||
/// Return the max of two cpFloats.
|
||||
|
|
@ -136,7 +134,11 @@ static inline cpFloat cpflerpconst(cpFloat f1, cpFloat f2, cpFloat d)
|
|||
}
|
||||
|
||||
/// Hash value type.
|
||||
typedef uintptr_t cpHashValue;
|
||||
#ifdef CP_HASH_VALUE_TYPE
|
||||
typedef CP_HASH_VALUE_TYPE cpHashValue;
|
||||
#else
|
||||
typedef uintptr_t cpHashValue;
|
||||
#endif
|
||||
|
||||
/// Type used internally to cache colliding object info for cpCollideShapes().
|
||||
/// Should be at least 32 bits.
|
||||
|
|
@ -147,7 +149,7 @@ typedef uint32_t cpCollisionID;
|
|||
#ifdef CP_BOOL_TYPE
|
||||
typedef CP_BOOL_TYPE cpBool;
|
||||
#else
|
||||
typedef int cpBool;
|
||||
typedef unsigned char cpBool;
|
||||
#endif
|
||||
|
||||
#ifndef cpTrue
|
||||
|
|
@ -181,11 +183,11 @@ typedef uint32_t cpCollisionID;
|
|||
typedef uintptr_t cpGroup;
|
||||
#endif
|
||||
|
||||
#ifdef CP_LAYERS_TYPE
|
||||
typedef CP_LAYERS_TYPE cpLayers;
|
||||
#ifdef CP_BITMASK_TYPE
|
||||
typedef CP_BITMASK_TYPE cpBitmask;
|
||||
#else
|
||||
/// Type used for cpShape.layers.
|
||||
typedef unsigned int cpLayers;
|
||||
/// Type used for cpShapeFilter category and mask.
|
||||
typedef unsigned int cpBitmask;
|
||||
#endif
|
||||
|
||||
#ifdef CP_TIMESTAMP_TYPE
|
||||
|
|
@ -200,15 +202,21 @@ typedef uint32_t cpCollisionID;
|
|||
#define CP_NO_GROUP ((cpGroup)0)
|
||||
#endif
|
||||
|
||||
#ifndef CP_ALL_LAYERS
|
||||
#ifndef CP_ALL_CATEGORIES
|
||||
/// Value for cpShape.layers signifying that a shape is in every layer.
|
||||
#define CP_ALL_LAYERS (~(cpLayers)0)
|
||||
#define CP_ALL_CATEGORIES (~(cpBitmask)0)
|
||||
#endif
|
||||
|
||||
#ifndef CP_WILDCARD_COLLISION_TYPE
|
||||
/// cpCollisionType value internally reserved for hashing wildcard handlers.
|
||||
#define CP_WILDCARD_COLLISION_TYPE (~(cpCollisionType)0)
|
||||
#endif
|
||||
|
||||
/// @}
|
||||
|
||||
// CGPoints are structurally the same, and allow
|
||||
// easy interoperability with other Cocoa libraries
|
||||
#if CP_USE_CGPOINTS
|
||||
#if CP_USE_CGTYPES
|
||||
typedef CGPoint cpVect;
|
||||
#else
|
||||
/// Chipmunk's 2D vector type.
|
||||
|
|
@ -216,7 +224,19 @@ typedef uint32_t cpCollisionID;
|
|||
typedef struct cpVect{cpFloat x,y;} cpVect;
|
||||
#endif
|
||||
|
||||
#if CP_USE_CGTYPES
|
||||
typedef CGAffineTransform cpTransform;
|
||||
#else
|
||||
/// Column major affine transform.
|
||||
typedef struct cpTransform {
|
||||
cpFloat a, b, c, d, tx, ty;
|
||||
} cpTransform;
|
||||
#endif
|
||||
|
||||
// NUKE
|
||||
typedef struct cpMat2x2 {
|
||||
// Row major [[a, b][c d]]
|
||||
cpFloat a, b, c, d;
|
||||
} cpMat2x2;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2007 Scott Lembcke
|
||||
/* Copyright (c) 2013 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
|
||||
|
|
@ -36,27 +36,28 @@
|
|||
/// so the results will be unrealistic. You must explicity include the chipmunk_unsafe.h header to use them.
|
||||
/// @{
|
||||
|
||||
#ifndef CHIPMUNK_UNSAFE_HEADER
|
||||
#define CHIPMUNK_UNSAFE_HEADER
|
||||
#ifndef CHIPMUNK_UNSAFE_H
|
||||
#define CHIPMUNK_UNSAFE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// Set the radius of a circle shape.
|
||||
void cpCircleShapeSetRadius(cpShape *shape, cpFloat radius);
|
||||
CP_EXPORT void cpCircleShapeSetRadius(cpShape *shape, cpFloat radius);
|
||||
/// Set the offset of a circle shape.
|
||||
void cpCircleShapeSetOffset(cpShape *shape, cpVect offset);
|
||||
CP_EXPORT void cpCircleShapeSetOffset(cpShape *shape, cpVect offset);
|
||||
|
||||
/// Set the endpoints of a segment shape.
|
||||
void cpSegmentShapeSetEndpoints(cpShape *shape, cpVect a, cpVect b);
|
||||
CP_EXPORT void cpSegmentShapeSetEndpoints(cpShape *shape, cpVect a, cpVect b);
|
||||
/// Set the radius of a segment shape.
|
||||
void cpSegmentShapeSetRadius(cpShape *shape, cpFloat radius);
|
||||
CP_EXPORT void cpSegmentShapeSetRadius(cpShape *shape, cpFloat radius);
|
||||
|
||||
/// Set the vertexes of a poly shape.
|
||||
void cpPolyShapeSetVerts(cpShape *shape, int numVerts, cpVect *verts, cpVect offset);
|
||||
CP_EXPORT void cpPolyShapeSetVerts(cpShape *shape, int count, cpVect *verts, cpTransform transform);
|
||||
CP_EXPORT void cpPolyShapeSetVertsRaw(cpShape *shape, int count, cpVect *verts);
|
||||
/// Set the radius of a poly shape.
|
||||
void cpPolyShapeSetRadius(cpShape *shape, cpFloat radius);
|
||||
CP_EXPORT void cpPolyShapeSetRadius(cpShape *shape, cpFloat radius);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,161 +0,0 @@
|
|||
/* 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 cpConstraint cpConstraint
|
||||
/// @{
|
||||
|
||||
typedef struct cpConstraintClass cpConstraintClass;
|
||||
|
||||
typedef void (*cpConstraintPreStepImpl)(cpConstraint *constraint, cpFloat dt);
|
||||
typedef void (*cpConstraintApplyCachedImpulseImpl)(cpConstraint *constraint, cpFloat dt_coef);
|
||||
typedef void (*cpConstraintApplyImpulseImpl)(cpConstraint *constraint, cpFloat dt);
|
||||
typedef cpFloat (*cpConstraintGetImpulseImpl)(cpConstraint *constraint);
|
||||
|
||||
/// @private
|
||||
struct cpConstraintClass {
|
||||
cpConstraintPreStepImpl preStep;
|
||||
cpConstraintApplyCachedImpulseImpl applyCachedImpulse;
|
||||
cpConstraintApplyImpulseImpl applyImpulse;
|
||||
cpConstraintGetImpulseImpl getImpulse;
|
||||
};
|
||||
|
||||
/// Callback function type that gets called before solving a joint.
|
||||
typedef void (*cpConstraintPreSolveFunc)(cpConstraint *constraint, cpSpace *space);
|
||||
/// Callback function type that gets called after solving a joint.
|
||||
typedef void (*cpConstraintPostSolveFunc)(cpConstraint *constraint, cpSpace *space);
|
||||
|
||||
|
||||
/// Opaque cpConstraint struct.
|
||||
struct cpConstraint {
|
||||
CP_PRIVATE(const cpConstraintClass *klass);
|
||||
|
||||
/// The first body connected to this constraint.
|
||||
cpBody *a;
|
||||
/// The second body connected to this constraint.
|
||||
cpBody *b;
|
||||
|
||||
CP_PRIVATE(cpSpace *space);
|
||||
|
||||
CP_PRIVATE(cpConstraint *next_a);
|
||||
CP_PRIVATE(cpConstraint *next_b);
|
||||
|
||||
/// The maximum force that this constraint is allowed to use.
|
||||
/// Defaults to infinity.
|
||||
cpFloat maxForce;
|
||||
/// The rate at which joint error is corrected.
|
||||
/// Defaults to pow(1.0 - 0.1, 60.0) meaning that it will
|
||||
/// correct 10% of the error every 1/60th of a second.
|
||||
cpFloat errorBias;
|
||||
/// The maximum rate at which joint error is corrected.
|
||||
/// Defaults to infinity.
|
||||
cpFloat maxBias;
|
||||
|
||||
/// Function called before the solver runs.
|
||||
/// Animate your joint anchors, update your motor torque, etc.
|
||||
cpConstraintPreSolveFunc preSolve;
|
||||
|
||||
/// Function called after the solver runs.
|
||||
/// Use the applied impulse to perform effects like breakable joints.
|
||||
cpConstraintPostSolveFunc postSolve;
|
||||
|
||||
/// User definable data pointer.
|
||||
/// Generally this points to your the game object class so you can access it
|
||||
/// when given a cpConstraint reference in a callback.
|
||||
cpDataPointer data;
|
||||
};
|
||||
|
||||
/// Destroy a constraint.
|
||||
void cpConstraintDestroy(cpConstraint *constraint);
|
||||
/// Destroy and free a constraint.
|
||||
void cpConstraintFree(cpConstraint *constraint);
|
||||
|
||||
/// @private
|
||||
static inline void cpConstraintActivateBodies(cpConstraint *constraint)
|
||||
{
|
||||
cpBody *a = constraint->a; if(a) cpBodyActivate(a);
|
||||
cpBody *b = constraint->b; if(b) cpBodyActivate(b);
|
||||
}
|
||||
|
||||
/// @private
|
||||
#define CP_DefineConstraintStructGetter(type, member, name) \
|
||||
static inline type cpConstraint##Get##name(const cpConstraint *constraint){return constraint->member;}
|
||||
|
||||
/// @private
|
||||
#define CP_DefineConstraintStructSetter(type, member, name) \
|
||||
static inline void cpConstraint##Set##name(cpConstraint *constraint, type value){ \
|
||||
cpConstraintActivateBodies(constraint); \
|
||||
constraint->member = value; \
|
||||
}
|
||||
|
||||
/// @private
|
||||
#define CP_DefineConstraintStructProperty(type, member, name) \
|
||||
CP_DefineConstraintStructGetter(type, member, name) \
|
||||
CP_DefineConstraintStructSetter(type, member, name)
|
||||
|
||||
CP_DefineConstraintStructGetter(cpSpace*, CP_PRIVATE(space), Space)
|
||||
|
||||
CP_DefineConstraintStructGetter(cpBody*, a, A)
|
||||
CP_DefineConstraintStructGetter(cpBody*, b, B)
|
||||
CP_DefineConstraintStructProperty(cpFloat, maxForce, MaxForce)
|
||||
CP_DefineConstraintStructProperty(cpFloat, errorBias, ErrorBias)
|
||||
CP_DefineConstraintStructProperty(cpFloat, maxBias, MaxBias)
|
||||
CP_DefineConstraintStructProperty(cpConstraintPreSolveFunc, preSolve, PreSolveFunc)
|
||||
CP_DefineConstraintStructProperty(cpConstraintPostSolveFunc, postSolve, PostSolveFunc)
|
||||
CP_DefineConstraintStructProperty(cpDataPointer, data, UserData)
|
||||
|
||||
// Get the last impulse applied by this constraint.
|
||||
static inline cpFloat cpConstraintGetImpulse(cpConstraint *constraint)
|
||||
{
|
||||
return constraint->CP_PRIVATE(klass)->getImpulse(constraint);
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
#define cpConstraintCheckCast(constraint, struct) \
|
||||
cpAssertHard(constraint->CP_PRIVATE(klass) == struct##GetClass(), "Constraint is not a "#struct)
|
||||
|
||||
#define CP_DefineConstraintGetter(struct, type, member, name) \
|
||||
static inline type struct##Get##name(const cpConstraint *constraint){ \
|
||||
cpConstraintCheckCast(constraint, struct); \
|
||||
return ((struct *)constraint)->member; \
|
||||
}
|
||||
|
||||
#define CP_DefineConstraintSetter(struct, type, member, name) \
|
||||
static inline void struct##Set##name(cpConstraint *constraint, type value){ \
|
||||
cpConstraintCheckCast(constraint, struct); \
|
||||
cpConstraintActivateBodies(constraint); \
|
||||
((struct *)constraint)->member = value; \
|
||||
}
|
||||
|
||||
#define CP_DefineConstraintProperty(struct, type, member, name) \
|
||||
CP_DefineConstraintGetter(struct, type, member, name) \
|
||||
CP_DefineConstraintSetter(struct, type, member, name)
|
||||
|
||||
#include "cpPinJoint.h"
|
||||
#include "cpSlideJoint.h"
|
||||
#include "cpPivotJoint.h"
|
||||
#include "cpGrooveJoint.h"
|
||||
#include "cpDampedSpring.h"
|
||||
#include "cpDampedRotarySpring.h"
|
||||
#include "cpRotaryLimitJoint.h"
|
||||
#include "cpRatchetJoint.h"
|
||||
#include "cpGearJoint.h"
|
||||
#include "cpSimpleMotor.h"
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
/* 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 cpDampedRotarySpring cpDampedRotarySpring
|
||||
/// @{
|
||||
|
||||
typedef cpFloat (*cpDampedRotarySpringTorqueFunc)(struct cpConstraint *spring, cpFloat relativeAngle);
|
||||
|
||||
const cpConstraintClass *cpDampedRotarySpringGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpDampedRotarySpring {
|
||||
cpConstraint constraint;
|
||||
cpFloat restAngle;
|
||||
cpFloat stiffness;
|
||||
cpFloat damping;
|
||||
cpDampedRotarySpringTorqueFunc springTorqueFunc;
|
||||
|
||||
cpFloat target_wrn;
|
||||
cpFloat w_coef;
|
||||
|
||||
cpFloat iSum;
|
||||
cpFloat jAcc;
|
||||
} cpDampedRotarySpring;
|
||||
|
||||
/// Allocate a damped rotary spring.
|
||||
cpDampedRotarySpring* cpDampedRotarySpringAlloc(void);
|
||||
/// Initialize a damped rotary spring.
|
||||
cpDampedRotarySpring* cpDampedRotarySpringInit(cpDampedRotarySpring *joint, cpBody *a, cpBody *b, cpFloat restAngle, cpFloat stiffness, cpFloat damping);
|
||||
/// Allocate and initialize a damped rotary spring.
|
||||
cpConstraint* cpDampedRotarySpringNew(cpBody *a, cpBody *b, cpFloat restAngle, cpFloat stiffness, cpFloat damping);
|
||||
|
||||
CP_DefineConstraintProperty(cpDampedRotarySpring, cpFloat, restAngle, RestAngle)
|
||||
CP_DefineConstraintProperty(cpDampedRotarySpring, cpFloat, stiffness, Stiffness)
|
||||
CP_DefineConstraintProperty(cpDampedRotarySpring, cpFloat, damping, Damping)
|
||||
CP_DefineConstraintProperty(cpDampedRotarySpring, cpDampedRotarySpringTorqueFunc, springTorqueFunc, SpringTorqueFunc)
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
/* 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 cpDampedSpring cpDampedSpring
|
||||
/// @{
|
||||
|
||||
typedef struct cpDampedSpring cpDampedSpring;
|
||||
|
||||
typedef cpFloat (*cpDampedSpringForceFunc)(cpConstraint *spring, cpFloat dist);
|
||||
|
||||
const cpConstraintClass *cpDampedSpringGetClass(void);
|
||||
|
||||
/// @private
|
||||
struct cpDampedSpring {
|
||||
cpConstraint constraint;
|
||||
cpVect anchr1, anchr2;
|
||||
cpFloat restLength;
|
||||
cpFloat stiffness;
|
||||
cpFloat damping;
|
||||
cpDampedSpringForceFunc springForceFunc;
|
||||
|
||||
cpFloat target_vrn;
|
||||
cpFloat v_coef;
|
||||
|
||||
cpVect r1, r2;
|
||||
cpFloat nMass;
|
||||
cpVect n;
|
||||
|
||||
cpFloat jAcc;
|
||||
};
|
||||
|
||||
/// Allocate a damped spring.
|
||||
cpDampedSpring* cpDampedSpringAlloc(void);
|
||||
/// Initialize a damped spring.
|
||||
cpDampedSpring* cpDampedSpringInit(cpDampedSpring *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat restLength, cpFloat stiffness, cpFloat damping);
|
||||
/// Allocate and initialize a damped spring.
|
||||
cpConstraint* cpDampedSpringNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat restLength, cpFloat stiffness, cpFloat damping);
|
||||
|
||||
CP_DefineConstraintProperty(cpDampedSpring, cpVect, anchr1, Anchr1)
|
||||
CP_DefineConstraintProperty(cpDampedSpring, cpVect, anchr2, Anchr2)
|
||||
CP_DefineConstraintProperty(cpDampedSpring, cpFloat, restLength, RestLength)
|
||||
CP_DefineConstraintProperty(cpDampedSpring, cpFloat, stiffness, Stiffness)
|
||||
CP_DefineConstraintProperty(cpDampedSpring, cpFloat, damping, Damping)
|
||||
CP_DefineConstraintProperty(cpDampedSpring, cpDampedSpringForceFunc, springForceFunc, SpringForceFunc)
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
/* 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 cpGearJoint cpGearJoint
|
||||
/// @{
|
||||
|
||||
const cpConstraintClass *cpGearJointGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpGearJoint {
|
||||
cpConstraint constraint;
|
||||
cpFloat phase, ratio;
|
||||
cpFloat ratio_inv;
|
||||
|
||||
cpFloat iSum;
|
||||
|
||||
cpFloat bias;
|
||||
cpFloat jAcc;
|
||||
} cpGearJoint;
|
||||
|
||||
/// Allocate a gear joint.
|
||||
cpGearJoint* cpGearJointAlloc(void);
|
||||
/// Initialize a gear joint.
|
||||
cpGearJoint* cpGearJointInit(cpGearJoint *joint, cpBody *a, cpBody *b, cpFloat phase, cpFloat ratio);
|
||||
/// Allocate and initialize a gear joint.
|
||||
cpConstraint* cpGearJointNew(cpBody *a, cpBody *b, cpFloat phase, cpFloat ratio);
|
||||
|
||||
CP_DefineConstraintProperty(cpGearJoint, cpFloat, phase, Phase)
|
||||
CP_DefineConstraintGetter(cpGearJoint, cpFloat, ratio, Ratio)
|
||||
/// Set the ratio of a gear joint.
|
||||
void cpGearJointSetRatio(cpConstraint *constraint, cpFloat value);
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
/* 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 cpGrooveJoint cpGrooveJoint
|
||||
/// @{
|
||||
|
||||
const cpConstraintClass *cpGrooveJointGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpGrooveJoint {
|
||||
cpConstraint constraint;
|
||||
cpVect grv_n, grv_a, grv_b;
|
||||
cpVect anchr2;
|
||||
|
||||
cpVect grv_tn;
|
||||
cpFloat clamp;
|
||||
cpVect r1, r2;
|
||||
cpMat2x2 k;
|
||||
|
||||
cpVect jAcc;
|
||||
cpVect bias;
|
||||
} cpGrooveJoint;
|
||||
|
||||
/// Allocate a groove joint.
|
||||
cpGrooveJoint* cpGrooveJointAlloc(void);
|
||||
/// Initialize a groove joint.
|
||||
cpGrooveJoint* cpGrooveJointInit(cpGrooveJoint *joint, cpBody *a, cpBody *b, cpVect groove_a, cpVect groove_b, cpVect anchr2);
|
||||
/// Allocate and initialize a groove joint.
|
||||
cpConstraint* cpGrooveJointNew(cpBody *a, cpBody *b, cpVect groove_a, cpVect groove_b, cpVect anchr2);
|
||||
|
||||
CP_DefineConstraintGetter(cpGrooveJoint, cpVect, grv_a, GrooveA)
|
||||
/// Set endpoint a of a groove joint's groove
|
||||
void cpGrooveJointSetGrooveA(cpConstraint *constraint, cpVect value);
|
||||
CP_DefineConstraintGetter(cpGrooveJoint, cpVect, grv_b, GrooveB)
|
||||
/// Set endpoint b of a groove joint's groove
|
||||
void cpGrooveJointSetGrooveB(cpConstraint *constraint, cpVect value);
|
||||
CP_DefineConstraintProperty(cpGrooveJoint, cpVect, anchr2, Anchr2)
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
/* 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 cpPinJoint cpPinJoint
|
||||
/// @{
|
||||
|
||||
const cpConstraintClass *cpPinJointGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpPinJoint {
|
||||
cpConstraint constraint;
|
||||
cpVect anchr1, anchr2;
|
||||
cpFloat dist;
|
||||
|
||||
cpVect r1, r2;
|
||||
cpVect n;
|
||||
cpFloat nMass;
|
||||
|
||||
cpFloat jnAcc;
|
||||
cpFloat bias;
|
||||
} cpPinJoint;
|
||||
|
||||
/// Allocate a pin joint.
|
||||
cpPinJoint* cpPinJointAlloc(void);
|
||||
/// Initialize a pin joint.
|
||||
cpPinJoint* cpPinJointInit(cpPinJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2);
|
||||
/// Allocate and initialize a pin joint.
|
||||
cpConstraint* cpPinJointNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2);
|
||||
|
||||
CP_DefineConstraintProperty(cpPinJoint, cpVect, anchr1, Anchr1)
|
||||
CP_DefineConstraintProperty(cpPinJoint, cpVect, anchr2, Anchr2)
|
||||
CP_DefineConstraintProperty(cpPinJoint, cpFloat, dist, Dist)
|
||||
|
||||
///@}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
/* 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 cpPivotJoint cpPivotJoint
|
||||
/// @{
|
||||
|
||||
const cpConstraintClass *cpPivotJointGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpPivotJoint {
|
||||
cpConstraint constraint;
|
||||
cpVect anchr1, anchr2;
|
||||
|
||||
cpVect r1, r2;
|
||||
cpMat2x2 k;
|
||||
|
||||
cpVect jAcc;
|
||||
cpVect bias;
|
||||
} cpPivotJoint;
|
||||
|
||||
/// Allocate a pivot joint
|
||||
cpPivotJoint* cpPivotJointAlloc(void);
|
||||
/// Initialize a pivot joint.
|
||||
cpPivotJoint* cpPivotJointInit(cpPivotJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2);
|
||||
/// Allocate and initialize a pivot joint.
|
||||
cpConstraint* cpPivotJointNew(cpBody *a, cpBody *b, cpVect pivot);
|
||||
/// Allocate and initialize a pivot joint with specific anchors.
|
||||
cpConstraint* cpPivotJointNew2(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2);
|
||||
|
||||
CP_DefineConstraintProperty(cpPivotJoint, cpVect, anchr1, Anchr1)
|
||||
CP_DefineConstraintProperty(cpPivotJoint, cpVect, anchr2, Anchr2)
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
/* 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 cpRatchetJoint cpRatchetJoint
|
||||
/// @{
|
||||
|
||||
const cpConstraintClass *cpRatchetJointGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpRatchetJoint {
|
||||
cpConstraint constraint;
|
||||
cpFloat angle, phase, ratchet;
|
||||
|
||||
cpFloat iSum;
|
||||
|
||||
cpFloat bias;
|
||||
cpFloat jAcc;
|
||||
} cpRatchetJoint;
|
||||
|
||||
/// Allocate a ratchet joint.
|
||||
cpRatchetJoint* cpRatchetJointAlloc(void);
|
||||
/// Initialize a ratched joint.
|
||||
cpRatchetJoint* cpRatchetJointInit(cpRatchetJoint *joint, cpBody *a, cpBody *b, cpFloat phase, cpFloat ratchet);
|
||||
/// Allocate and initialize a ratchet joint.
|
||||
cpConstraint* cpRatchetJointNew(cpBody *a, cpBody *b, cpFloat phase, cpFloat ratchet);
|
||||
|
||||
CP_DefineConstraintProperty(cpRatchetJoint, cpFloat, angle, Angle)
|
||||
CP_DefineConstraintProperty(cpRatchetJoint, cpFloat, phase, Phase)
|
||||
CP_DefineConstraintProperty(cpRatchetJoint, cpFloat, ratchet, Ratchet)
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
/* 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 cpRotaryLimitJoint cpRotaryLimitJoint
|
||||
/// @{
|
||||
|
||||
const cpConstraintClass *cpRotaryLimitJointGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpRotaryLimitJoint {
|
||||
cpConstraint constraint;
|
||||
cpFloat min, max;
|
||||
|
||||
cpFloat iSum;
|
||||
|
||||
cpFloat bias;
|
||||
cpFloat jAcc;
|
||||
} cpRotaryLimitJoint;
|
||||
|
||||
/// Allocate a damped rotary limit joint.
|
||||
cpRotaryLimitJoint* cpRotaryLimitJointAlloc(void);
|
||||
/// Initialize a damped rotary limit joint.
|
||||
cpRotaryLimitJoint* cpRotaryLimitJointInit(cpRotaryLimitJoint *joint, cpBody *a, cpBody *b, cpFloat min, cpFloat max);
|
||||
/// Allocate and initialize a damped rotary limit joint.
|
||||
cpConstraint* cpRotaryLimitJointNew(cpBody *a, cpBody *b, cpFloat min, cpFloat max);
|
||||
|
||||
CP_DefineConstraintProperty(cpRotaryLimitJoint, cpFloat, min, Min)
|
||||
CP_DefineConstraintProperty(cpRotaryLimitJoint, cpFloat, max, Max)
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
/* 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 cpSimpleMotor cpSimpleMotor
|
||||
/// @{
|
||||
|
||||
const cpConstraintClass *cpSimpleMotorGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpSimpleMotor {
|
||||
cpConstraint constraint;
|
||||
cpFloat rate;
|
||||
|
||||
cpFloat iSum;
|
||||
|
||||
cpFloat jAcc;
|
||||
} cpSimpleMotor;
|
||||
|
||||
/// Allocate a simple motor.
|
||||
cpSimpleMotor* cpSimpleMotorAlloc(void);
|
||||
/// initialize a simple motor.
|
||||
cpSimpleMotor* cpSimpleMotorInit(cpSimpleMotor *joint, cpBody *a, cpBody *b, cpFloat rate);
|
||||
/// Allocate and initialize a simple motor.
|
||||
cpConstraint* cpSimpleMotorNew(cpBody *a, cpBody *b, cpFloat rate);
|
||||
|
||||
CP_DefineConstraintProperty(cpSimpleMotor, cpFloat, rate, Rate)
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
/* 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 cpSlideJoint cpSlideJoint
|
||||
/// @{
|
||||
|
||||
const cpConstraintClass *cpSlideJointGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpSlideJoint {
|
||||
cpConstraint constraint;
|
||||
cpVect anchr1, anchr2;
|
||||
cpFloat min, max;
|
||||
|
||||
cpVect r1, r2;
|
||||
cpVect n;
|
||||
cpFloat nMass;
|
||||
|
||||
cpFloat jnAcc;
|
||||
cpFloat bias;
|
||||
} cpSlideJoint;
|
||||
|
||||
/// Allocate a slide joint.
|
||||
cpSlideJoint* cpSlideJointAlloc(void);
|
||||
/// Initialize a slide joint.
|
||||
cpSlideJoint* cpSlideJointInit(cpSlideJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max);
|
||||
/// Allocate and initialize a slide joint.
|
||||
cpConstraint* cpSlideJointNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max);
|
||||
|
||||
CP_DefineConstraintProperty(cpSlideJoint, cpVect, anchr1, Anchr1)
|
||||
CP_DefineConstraintProperty(cpSlideJoint, cpVect, anchr2, Anchr2)
|
||||
CP_DefineConstraintProperty(cpSlideJoint, cpFloat, min, Min)
|
||||
CP_DefineConstraintProperty(cpSlideJoint, cpFloat, max, Max)
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,126 +0,0 @@
|
|||
/* 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.
|
||||
*/
|
||||
|
||||
// These are utility routines to use when creating custom constraints.
|
||||
// I'm not sure if this should be part of the private API or not.
|
||||
// I should probably clean up the naming conventions if it is...
|
||||
|
||||
#define CP_DefineClassGetter(t) const cpConstraintClass * t##GetClass(void){return (cpConstraintClass *)&klass;}
|
||||
|
||||
void cpConstraintInit(cpConstraint *constraint, const cpConstraintClass *klass, cpBody *a, cpBody *b);
|
||||
|
||||
static inline cpVect
|
||||
relative_velocity(cpBody *a, cpBody *b, cpVect r1, cpVect r2){
|
||||
cpVect v1_sum = cpvadd(a->v, cpvmult(cpvperp(r1), a->w));
|
||||
cpVect v2_sum = cpvadd(b->v, cpvmult(cpvperp(r2), b->w));
|
||||
|
||||
return cpvsub(v2_sum, v1_sum);
|
||||
}
|
||||
|
||||
static inline cpFloat
|
||||
normal_relative_velocity(cpBody *a, cpBody *b, cpVect r1, cpVect r2, cpVect n){
|
||||
return cpvdot(relative_velocity(a, b, r1, r2), n);
|
||||
}
|
||||
|
||||
static inline void
|
||||
apply_impulse(cpBody *body, cpVect j, cpVect r){
|
||||
body->v = cpvadd(body->v, cpvmult(j, body->m_inv));
|
||||
body->w += body->i_inv*cpvcross(r, j);
|
||||
}
|
||||
|
||||
static inline void
|
||||
apply_impulses(cpBody *a , cpBody *b, cpVect r1, cpVect r2, cpVect j)
|
||||
{
|
||||
apply_impulse(a, cpvneg(j), r1);
|
||||
apply_impulse(b, j, r2);
|
||||
}
|
||||
|
||||
static inline void
|
||||
apply_bias_impulse(cpBody *body, cpVect j, cpVect r)
|
||||
{
|
||||
body->CP_PRIVATE(v_bias) = cpvadd(body->CP_PRIVATE(v_bias), cpvmult(j, body->m_inv));
|
||||
body->CP_PRIVATE(w_bias) += body->i_inv*cpvcross(r, j);
|
||||
}
|
||||
|
||||
static inline void
|
||||
apply_bias_impulses(cpBody *a , cpBody *b, cpVect r1, cpVect r2, cpVect j)
|
||||
{
|
||||
apply_bias_impulse(a, cpvneg(j), r1);
|
||||
apply_bias_impulse(b, j, r2);
|
||||
}
|
||||
|
||||
static inline cpFloat
|
||||
k_scalar_body(cpBody *body, cpVect r, cpVect n)
|
||||
{
|
||||
cpFloat rcn = cpvcross(r, n);
|
||||
return body->m_inv + body->i_inv*rcn*rcn;
|
||||
}
|
||||
|
||||
static inline cpFloat
|
||||
k_scalar(cpBody *a, cpBody *b, cpVect r1, cpVect r2, cpVect n)
|
||||
{
|
||||
cpFloat value = k_scalar_body(a, r1, n) + k_scalar_body(b, r2, n);
|
||||
cpAssertSoft(value != 0.0, "Unsolvable collision or constraint.");
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static inline cpMat2x2
|
||||
k_tensor(cpBody *a, cpBody *b, cpVect r1, cpVect r2)
|
||||
{
|
||||
cpFloat m_sum = a->m_inv + b->m_inv;
|
||||
|
||||
// start with Identity*m_sum
|
||||
cpFloat k11 = m_sum, k12 = 0.0f;
|
||||
cpFloat k21 = 0.0f, k22 = m_sum;
|
||||
|
||||
// add the influence from r1
|
||||
cpFloat a_i_inv = a->i_inv;
|
||||
cpFloat r1xsq = r1.x * r1.x * a_i_inv;
|
||||
cpFloat r1ysq = r1.y * r1.y * a_i_inv;
|
||||
cpFloat r1nxy = -r1.x * r1.y * a_i_inv;
|
||||
k11 += r1ysq; k12 += r1nxy;
|
||||
k21 += r1nxy; k22 += r1xsq;
|
||||
|
||||
// add the influnce from r2
|
||||
cpFloat b_i_inv = b->i_inv;
|
||||
cpFloat r2xsq = r2.x * r2.x * b_i_inv;
|
||||
cpFloat r2ysq = r2.y * r2.y * b_i_inv;
|
||||
cpFloat r2nxy = -r2.x * r2.y * b_i_inv;
|
||||
k11 += r2ysq; k12 += r2nxy;
|
||||
k21 += r2nxy; k22 += r2xsq;
|
||||
|
||||
// invert
|
||||
cpFloat det = k11*k22 - k12*k21;
|
||||
cpAssertSoft(det != 0.0, "Unsolvable constraint.");
|
||||
|
||||
cpFloat det_inv = 1.0f/det;
|
||||
return cpMat2x2New(
|
||||
k22*det_inv, -k12*det_inv,
|
||||
-k21*det_inv, k11*det_inv
|
||||
);
|
||||
}
|
||||
|
||||
static inline cpFloat
|
||||
bias_coef(cpFloat errorBias, cpFloat dt)
|
||||
{
|
||||
return 1.0f - cpfpow(errorBias, dt);
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2007 Scott Lembcke
|
||||
/* Copyright (c) 2013 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
|
||||
|
|
@ -20,188 +20,126 @@
|
|||
*/
|
||||
|
||||
/// @defgroup cpArbiter cpArbiter
|
||||
/// The cpArbiter struct controls pairs of colliding shapes.
|
||||
/// The cpArbiter struct tracks 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.
|
||||
/// allowing you to retrieve information on the collision or change it.
|
||||
/// A unique arbiter value is used for each pair of colliding objects. It persists until the shapes separate.
|
||||
/// @{
|
||||
|
||||
/// 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 2
|
||||
|
||||
/// @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)
|
||||
/// Get the restitution (elasticity) that will be applied to the pair of colliding objects.
|
||||
CP_EXPORT cpFloat cpArbiterGetRestitution(const cpArbiter *arb);
|
||||
/// Override the restitution (elasticity) that will be applied to the pair of colliding objects.
|
||||
CP_EXPORT void cpArbiterSetRestitution(cpArbiter *arb, cpFloat restitution);
|
||||
/// Get the friction coefficient that will be applied to the pair of colliding objects.
|
||||
CP_EXPORT cpFloat cpArbiterGetFriction(const cpArbiter *arb);
|
||||
/// Override the friction coefficient that will be applied to the pair of colliding objects.
|
||||
CP_EXPORT void cpArbiterSetFriction(cpArbiter *arb, cpFloat friction);
|
||||
|
||||
// Get the relative surface velocity of the two shapes in contact.
|
||||
cpVect cpArbiterGetSurfaceVelocity(cpArbiter *arb);
|
||||
CP_EXPORT cpVect cpArbiterGetSurfaceVelocity(cpArbiter *arb);
|
||||
|
||||
// Override the relative surface velocity of the two shapes in contact.
|
||||
// By default this is calculated to be the difference of the two
|
||||
// surface velocities clamped to the tangent plane.
|
||||
void cpArbiterSetSurfaceVelocity(cpArbiter *arb, cpVect vr);
|
||||
// By default this is calculated to be the difference of the two surface velocities clamped to the tangent plane.
|
||||
CP_EXPORT void cpArbiterSetSurfaceVelocity(cpArbiter *arb, cpVect vr);
|
||||
|
||||
CP_DefineArbiterStructProperty(cpDataPointer, data, UserData)
|
||||
/// Get the user data pointer associated with this pair of colliding objects.
|
||||
CP_EXPORT cpDataPointer cpArbiterGetUserData(const cpArbiter *arb);
|
||||
/// Set a user data point associated with this pair of colliding objects.
|
||||
/// If you need to perform any cleanup for this pointer, you must do it yourself, in the separate callback for instance.
|
||||
CP_EXPORT void cpArbiterSetUserData(cpArbiter *arb, cpDataPointer 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);
|
||||
CP_EXPORT cpVect cpArbiterTotalImpulse(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);
|
||||
CP_EXPORT 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);
|
||||
/// Mark a collision pair to be ignored until the two objects separate.
|
||||
/// Pre-solve and post-solve callbacks will not be called, but the separate callback will be called.
|
||||
CP_EXPORT cpBool 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);
|
||||
}
|
||||
}
|
||||
CP_EXPORT void cpArbiterGetShapes(const cpArbiter *arb, cpShape **a, cpShape **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;
|
||||
}
|
||||
CP_EXPORT void cpArbiterGetBodies(const cpArbiter *arb, cpBody **a, cpBody **b);
|
||||
|
||||
/// 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 {
|
||||
struct cpContactPointSet {
|
||||
/// The number of contact points in the set.
|
||||
int count;
|
||||
|
||||
/// The normal of the collision.
|
||||
cpVect normal;
|
||||
|
||||
/// 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;
|
||||
/// The position of the contact on the surface of each shape.
|
||||
cpVect pointA, pointB;
|
||||
/// Penetration distance of the two shapes. Overlapping means it will be negative.
|
||||
/// This value is calculated as cpvdot(cpvsub(point2, point1), normal) and is ignored by cpArbiterSetContactPointSet().
|
||||
cpFloat distance;
|
||||
} points[CP_MAX_CONTACTS_PER_ARBITER];
|
||||
} cpContactPointSet;
|
||||
};
|
||||
|
||||
/// Return a contact set from an arbiter.
|
||||
cpContactPointSet cpArbiterGetContactPointSet(const cpArbiter *arb);
|
||||
CP_EXPORT cpContactPointSet cpArbiterGetContactPointSet(const cpArbiter *arb);
|
||||
|
||||
/// Replace the contact point set for an arbiter.
|
||||
/// This can be a very powerful feature, but use it with caution!
|
||||
void cpArbiterSetContactPointSet(cpArbiter *arb, cpContactPointSet *set);
|
||||
CP_EXPORT void cpArbiterSetContactPointSet(cpArbiter *arb, cpContactPointSet *set);
|
||||
|
||||
/// Returns true if this is the first step a pair of objects started colliding.
|
||||
cpBool cpArbiterIsFirstContact(const cpArbiter *arb);
|
||||
CP_EXPORT cpBool cpArbiterIsFirstContact(const cpArbiter *arb);
|
||||
/// Returns true if the separate callback is due to a shape being removed from the space.
|
||||
CP_EXPORT cpBool cpArbiterIsRemoval(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);
|
||||
CP_EXPORT int cpArbiterGetCount(const cpArbiter *arb);
|
||||
/// Get the normal of the collision.
|
||||
CP_EXPORT cpVect cpArbiterGetNormal(const cpArbiter *arb);
|
||||
/// Get the position of the @c ith contact point on the surface of the first shape.
|
||||
CP_EXPORT cpVect cpArbiterGetPointA(const cpArbiter *arb, int i);
|
||||
/// Get the position of the @c ith contact point on the surface of the second shape.
|
||||
CP_EXPORT cpVect cpArbiterGetPointB(const cpArbiter *arb, int i);
|
||||
/// Get the depth of the @c ith contact point.
|
||||
cpFloat cpArbiterGetDepth(const cpArbiter *arb, int i);
|
||||
CP_EXPORT cpFloat cpArbiterGetDepth(const cpArbiter *arb, int i);
|
||||
|
||||
/// If you want a custom callback to invoke the wildcard callback for the first collision type, you must call this function explicitly.
|
||||
/// You must decide how to handle the wildcard's return value since it may disagree with the other wildcard handler's return value or your own.
|
||||
CP_EXPORT cpBool cpArbiterCallWildcardBeginA(cpArbiter *arb, cpSpace *space);
|
||||
/// If you want a custom callback to invoke the wildcard callback for the second collision type, you must call this function explicitly.
|
||||
/// You must decide how to handle the wildcard's return value since it may disagree with the other wildcard handler's return value or your own.
|
||||
CP_EXPORT cpBool cpArbiterCallWildcardBeginB(cpArbiter *arb, cpSpace *space);
|
||||
|
||||
/// If you want a custom callback to invoke the wildcard callback for the first collision type, you must call this function explicitly.
|
||||
/// You must decide how to handle the wildcard's return value since it may disagree with the other wildcard handler's return value or your own.
|
||||
CP_EXPORT cpBool cpArbiterCallWildcardPreSolveA(cpArbiter *arb, cpSpace *space);
|
||||
/// If you want a custom callback to invoke the wildcard callback for the second collision type, you must call this function explicitly.
|
||||
/// You must decide how to handle the wildcard's return value since it may disagree with the other wildcard handler's return value or your own.
|
||||
CP_EXPORT cpBool cpArbiterCallWildcardPreSolveB(cpArbiter *arb, cpSpace *space);
|
||||
|
||||
/// If you want a custom callback to invoke the wildcard callback for the first collision type, you must call this function explicitly.
|
||||
CP_EXPORT void cpArbiterCallWildcardPostSolveA(cpArbiter *arb, cpSpace *space);
|
||||
/// If you want a custom callback to invoke the wildcard callback for the second collision type, you must call this function explicitly.
|
||||
CP_EXPORT void cpArbiterCallWildcardPostSolveB(cpArbiter *arb, cpSpace *space);
|
||||
|
||||
/// If you want a custom callback to invoke the wildcard callback for the first collision type, you must call this function explicitly.
|
||||
CP_EXPORT void cpArbiterCallWildcardSeparateA(cpArbiter *arb, cpSpace *space);
|
||||
/// If you want a custom callback to invoke the wildcard callback for the second collision type, you must call this function explicitly.
|
||||
CP_EXPORT void cpArbiterCallWildcardSeparateB(cpArbiter *arb, cpSpace *space);
|
||||
|
||||
/// @}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2007 Scott Lembcke
|
||||
/* Copyright (c) 2013 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
|
||||
|
|
@ -19,6 +19,12 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef CHIPMUNK_BB_H
|
||||
#define CHIPMUNK_BB_H
|
||||
|
||||
#include "chipmunk_types.h"
|
||||
#include "cpVect.h"
|
||||
|
||||
/// @defgroup cpBBB cpBB
|
||||
/// Chipmunk's axis-aligned 2D bounding box type along with a few handy routines.
|
||||
/// @{
|
||||
|
|
@ -35,10 +41,17 @@ static inline cpBB cpBBNew(const cpFloat l, const cpFloat b, const cpFloat r, co
|
|||
return bb;
|
||||
}
|
||||
|
||||
/// Constructs a cpBB centered on a point with the given extents (half sizes).
|
||||
static inline cpBB
|
||||
cpBBNewForExtents(const cpVect c, const cpFloat hw, const cpFloat hh)
|
||||
{
|
||||
return cpBBNew(c.x - hw, c.y - hh, c.x + hw, c.y + hh);
|
||||
}
|
||||
|
||||
/// Constructs a cpBB for a circle with the given position and radius.
|
||||
static inline cpBB cpBBNewForCircle(const cpVect p, const cpFloat r)
|
||||
{
|
||||
return cpBBNew(p.x - r, p.y - r, p.x + r, p.y + r);
|
||||
return cpBBNewForExtents(p, r, r);
|
||||
}
|
||||
|
||||
/// Returns true if @c a and @c b intersect.
|
||||
|
|
@ -102,6 +115,9 @@ static inline cpFloat cpBBMergedArea(cpBB a, cpBB b)
|
|||
static inline cpFloat cpBBSegmentQuery(cpBB bb, cpVect a, cpVect b)
|
||||
{
|
||||
cpFloat idx = 1.0f/(b.x - a.x);
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable: 4056)
|
||||
#endif
|
||||
cpFloat tx1 = (bb.l == a.x ? -INFINITY : (bb.l - a.x)*idx);
|
||||
cpFloat tx2 = (bb.r == a.x ? INFINITY : (bb.r - a.x)*idx);
|
||||
cpFloat txmin = cpfmin(tx1, tx2);
|
||||
|
|
@ -110,6 +126,9 @@ static inline cpFloat cpBBSegmentQuery(cpBB bb, cpVect a, cpVect b)
|
|||
cpFloat idy = 1.0f/(b.y - a.y);
|
||||
cpFloat ty1 = (bb.b == a.y ? -INFINITY : (bb.b - a.y)*idy);
|
||||
cpFloat ty2 = (bb.t == a.y ? INFINITY : (bb.t - a.y)*idy);
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(default: 4056)
|
||||
#endif
|
||||
cpFloat tymin = cpfmin(ty1, ty2);
|
||||
cpFloat tymax = cpfmax(ty1, ty2);
|
||||
|
||||
|
|
@ -136,8 +155,33 @@ cpBBClampVect(const cpBB bb, const cpVect v)
|
|||
return cpv(cpfclamp(v.x, bb.l, bb.r), cpfclamp(v.y, bb.b, bb.t));
|
||||
}
|
||||
|
||||
// TODO edge case issue
|
||||
/// Wrap a vector to a bounding box.
|
||||
cpVect cpBBWrapVect(const cpBB bb, const cpVect v); // wrap a vector to a bbox
|
||||
static inline cpVect
|
||||
cpBBWrapVect(const cpBB bb, const cpVect v)
|
||||
{
|
||||
cpFloat dx = cpfabs(bb.r - bb.l);
|
||||
cpFloat modx = cpfmod(v.x - bb.l, dx);
|
||||
cpFloat x = (modx > 0.0f) ? modx : modx + dx;
|
||||
|
||||
cpFloat dy = cpfabs(bb.t - bb.b);
|
||||
cpFloat mody = cpfmod(v.y - bb.b, dy);
|
||||
cpFloat y = (mody > 0.0f) ? mody : mody + dy;
|
||||
|
||||
return cpv(x + bb.l, y + bb.b);
|
||||
}
|
||||
|
||||
/// Returns a bounding box offseted by @c v.
|
||||
static inline cpBB
|
||||
cpBBOffset(const cpBB bb, const cpVect v)
|
||||
{
|
||||
return cpBBNew(
|
||||
bb.l + v.x,
|
||||
bb.b + v.y,
|
||||
bb.r + v.x,
|
||||
bb.t + v.y
|
||||
);
|
||||
}
|
||||
|
||||
///@}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2007 Scott Lembcke
|
||||
/* Copyright (c) 2013 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
|
||||
|
|
@ -25,227 +25,165 @@
|
|||
/// They are given a shape by creating collision shapes (cpShape) that point to the body.
|
||||
/// @{
|
||||
|
||||
typedef enum cpBodyType {
|
||||
/// A dynamic body is one that is affected by gravity, forces, and collisions.
|
||||
/// This is the default body type.
|
||||
CP_BODY_TYPE_DYNAMIC,
|
||||
/// A kinematic body is an infinite mass, user controlled body that is not affected by gravity, forces or collisions.
|
||||
/// Instead the body only moves based on it's velocity.
|
||||
/// Dynamic bodies collide normally with kinematic bodies, though the kinematic body will be unaffected.
|
||||
/// Collisions between two kinematic bodies, or a kinematic body and a static body produce collision callbacks, but no collision response.
|
||||
CP_BODY_TYPE_KINEMATIC,
|
||||
/// A static body is a body that never (or rarely) moves. If you move a static body, you must call one of the cpSpaceReindex*() functions.
|
||||
/// Chipmunk uses this information to optimize the collision detection.
|
||||
/// Static bodies do not produce collision callbacks when colliding with other static bodies.
|
||||
CP_BODY_TYPE_STATIC,
|
||||
} cpBodyType;
|
||||
|
||||
/// 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);
|
||||
CP_EXPORT cpBody* cpBodyAlloc(void);
|
||||
/// Initialize a cpBody.
|
||||
cpBody* cpBodyInit(cpBody *body, cpFloat m, cpFloat i);
|
||||
CP_EXPORT cpBody* cpBodyInit(cpBody *body, cpFloat mass, cpFloat moment);
|
||||
/// Allocate and initialize a cpBody.
|
||||
cpBody* cpBodyNew(cpFloat m, cpFloat i);
|
||||
CP_EXPORT cpBody* cpBodyNew(cpFloat mass, cpFloat moment);
|
||||
|
||||
/// Initialize a static cpBody.
|
||||
cpBody* cpBodyInitStatic(cpBody *body);
|
||||
/// Allocate and initialize a static cpBody.
|
||||
cpBody* cpBodyNewStatic(void);
|
||||
/// Allocate and initialize a cpBody, and set it as a kinematic body.
|
||||
CP_EXPORT cpBody* cpBodyNewKinematic(void);
|
||||
/// Allocate and initialize a cpBody, and set it as a static body.
|
||||
CP_EXPORT cpBody* cpBodyNewStatic(void);
|
||||
|
||||
/// Destroy a cpBody.
|
||||
void cpBodyDestroy(cpBody *body);
|
||||
CP_EXPORT 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
|
||||
CP_EXPORT void cpBodyFree(cpBody *body);
|
||||
|
||||
// Defined in cpSpace.c
|
||||
/// Wake up a sleeping or idle body.
|
||||
void cpBodyActivate(cpBody *body);
|
||||
CP_EXPORT void cpBodyActivate(cpBody *body);
|
||||
/// Wake up any sleeping or idle bodies touching a static body.
|
||||
void cpBodyActivateStatic(cpBody *body, cpShape *filter);
|
||||
CP_EXPORT void cpBodyActivateStatic(cpBody *body, cpShape *filter);
|
||||
|
||||
/// Force a body to fall asleep immediately.
|
||||
void cpBodySleep(cpBody *body);
|
||||
CP_EXPORT void cpBodySleep(cpBody *body);
|
||||
/// Force a body to fall asleep immediately along with other bodies in a group.
|
||||
void cpBodySleepWithGroup(cpBody *body, cpBody *group);
|
||||
CP_EXPORT 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));
|
||||
}
|
||||
CP_EXPORT cpBool cpBodyIsSleeping(const cpBody *body);
|
||||
|
||||
/// Returns true if the body is static.
|
||||
static inline cpBool cpBodyIsStatic(const cpBody *body)
|
||||
{
|
||||
return CP_PRIVATE(body->node).idleTime == INFINITY;
|
||||
}
|
||||
/// Get the type of the body.
|
||||
CP_EXPORT cpBodyType cpBodyGetType(cpBody *body);
|
||||
/// Set the type of the body.
|
||||
CP_EXPORT void cpBodySetType(cpBody *body, cpBodyType type);
|
||||
|
||||
/// Returns true if the body has not been added to a space.
|
||||
/// Note: Static bodies are a subtype of rogue bodies.
|
||||
static inline cpBool cpBodyIsRogue(const cpBody *body)
|
||||
{
|
||||
return (body->CP_PRIVATE(space) == ((cpSpace*)0));
|
||||
}
|
||||
/// Get the space this body is added to.
|
||||
CP_EXPORT cpSpace* cpBodyGetSpace(const cpBody *body);
|
||||
|
||||
/// Get the mass of the body.
|
||||
CP_EXPORT cpFloat cpBodyGetMass(const cpBody *body);
|
||||
/// Set the mass of the body.
|
||||
CP_EXPORT void cpBodySetMass(cpBody *body, cpFloat m);
|
||||
|
||||
#define CP_DefineBodyStructGetter(type, member, name) \
|
||||
static inline type cpBodyGet##name(const cpBody *body){return body->member;}
|
||||
/// Get the moment of inertia of the body.
|
||||
CP_EXPORT cpFloat cpBodyGetMoment(const cpBody *body);
|
||||
/// Set the moment of inertia of the body.
|
||||
CP_EXPORT void cpBodySetMoment(cpBody *body, cpFloat i);
|
||||
|
||||
#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)
|
||||
CP_EXPORT cpVect cpBodyGetPosition(const cpBody *body);
|
||||
/// Set the position of the body.
|
||||
CP_EXPORT void cpBodySetPosition(cpBody *body, cpVect pos);
|
||||
|
||||
/// Default Integration functions.
|
||||
void cpBodyUpdateVelocity(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt);
|
||||
void cpBodyUpdatePosition(cpBody *body, cpFloat dt);
|
||||
/// Get the offset of the center of gravity in body local coordinates.
|
||||
CP_EXPORT cpVect cpBodyGetCenterOfGravity(const cpBody *body);
|
||||
/// Set the offset of the center of gravity in body local coordinates.
|
||||
CP_EXPORT void cpBodySetCenterOfGravity(cpBody *body, cpVect cog);
|
||||
|
||||
/// Get the velocity of the body.
|
||||
CP_EXPORT cpVect cpBodyGetVelocity(const cpBody *body);
|
||||
/// Set the velocity of the body.
|
||||
CP_EXPORT void cpBodySetVelocity(cpBody *body, cpVect velocity);
|
||||
|
||||
/// Get the force applied to the body for the next time step.
|
||||
CP_EXPORT cpVect cpBodyGetForce(const cpBody *body);
|
||||
/// Set the force applied to the body for the next time step.
|
||||
CP_EXPORT void cpBodySetForce(cpBody *body, cpVect force);
|
||||
|
||||
/// Get the angle of the body.
|
||||
CP_EXPORT cpFloat cpBodyGetAngle(const cpBody *body);
|
||||
/// Set the angle of a body.
|
||||
CP_EXPORT void cpBodySetAngle(cpBody *body, cpFloat a);
|
||||
|
||||
/// Get the angular velocity of the body.
|
||||
CP_EXPORT cpFloat cpBodyGetAngularVelocity(const cpBody *body);
|
||||
/// Set the angular velocity of the body.
|
||||
CP_EXPORT void cpBodySetAngularVelocity(cpBody *body, cpFloat angularVelocity);
|
||||
|
||||
/// Get the torque applied to the body for the next time step.
|
||||
CP_EXPORT cpFloat cpBodyGetTorque(const cpBody *body);
|
||||
/// Set the torque applied to the body for the next time step.
|
||||
CP_EXPORT void cpBodySetTorque(cpBody *body, cpFloat torque);
|
||||
|
||||
/// Get the rotation vector of the body. (The x basis vector of it's transform.)
|
||||
CP_EXPORT cpVect cpBodyGetRotation(const cpBody *body);
|
||||
|
||||
/// Get the user data pointer assigned to the body.
|
||||
CP_EXPORT cpDataPointer cpBodyGetUserData(const cpBody *body);
|
||||
/// Set the user data pointer assigned to the body.
|
||||
CP_EXPORT void cpBodySetUserData(cpBody *body, cpDataPointer userData);
|
||||
|
||||
/// Set the callback used to update a body's velocity.
|
||||
CP_EXPORT void cpBodySetVelocityUpdateFunc(cpBody *body, cpBodyVelocityFunc velocityFunc);
|
||||
/// Set the callback used to update a body's position.
|
||||
/// NOTE: It's not generally recommended to override this unless you call the default position update function.
|
||||
CP_EXPORT void cpBodySetPositionUpdateFunc(cpBody *body, cpBodyPositionFunc positionFunc);
|
||||
|
||||
/// Default velocity integration function..
|
||||
CP_EXPORT void cpBodyUpdateVelocity(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt);
|
||||
/// Default position integration function.
|
||||
CP_EXPORT 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));
|
||||
}
|
||||
|
||||
CP_EXPORT cpVect cpBodyLocalToWorld(const cpBody *body, const cpVect point);
|
||||
/// 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);
|
||||
}
|
||||
CP_EXPORT cpVect cpBodyWorldToLocal(const cpBody *body, const cpVect point);
|
||||
|
||||
/// 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);
|
||||
/// Apply a force to a body. Both the force and point are expressed in world coordinates.
|
||||
CP_EXPORT void cpBodyApplyForceAtWorldPoint(cpBody *body, cpVect force, cpVect point);
|
||||
/// Apply a force to a body. Both the force and point are expressed in body local coordinates.
|
||||
CP_EXPORT void cpBodyApplyForceAtLocalPoint(cpBody *body, cpVect force, cpVect point);
|
||||
|
||||
/// Apply an impulse to a body. Both the impulse and point are expressed in world coordinates.
|
||||
CP_EXPORT void cpBodyApplyImpulseAtWorldPoint(cpBody *body, cpVect impulse, cpVect point);
|
||||
/// Apply an impulse to a body. Both the impulse and point are expressed in body local coordinates.
|
||||
CP_EXPORT void cpBodyApplyImpulseAtLocalPoint(cpBody *body, cpVect impulse, cpVect point);
|
||||
|
||||
/// Get the velocity on a body (in world units) at a point on the body in world coordinates.
|
||||
cpVect cpBodyGetVelAtWorldPoint(cpBody *body, cpVect point);
|
||||
CP_EXPORT cpVect cpBodyGetVelocityAtWorldPoint(const 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);
|
||||
CP_EXPORT cpVect cpBodyGetVelocityAtLocalPoint(const 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);
|
||||
}
|
||||
/// Get the amount of kinetic energy contained by the body.
|
||||
CP_EXPORT cpFloat cpBodyKineticEnergy(const cpBody *body);
|
||||
|
||||
/// 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);
|
||||
CP_EXPORT 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);
|
||||
CP_EXPORT 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);
|
||||
CP_EXPORT void cpBodyEachArbiter(cpBody *body, cpBodyArbiterIteratorFunc func, void *data);
|
||||
|
||||
///@}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2007 Scott Lembcke
|
||||
/* Copyright (c) 2013 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
|
||||
|
|
@ -22,60 +22,35 @@
|
|||
/// @defgroup cpPolyShape cpPolyShape
|
||||
/// @{
|
||||
|
||||
/// @private
|
||||
typedef struct cpSplittingPlane {
|
||||
cpVect n;
|
||||
cpFloat d;
|
||||
} cpSplittingPlane;
|
||||
|
||||
/// @private
|
||||
typedef struct cpPolyShape {
|
||||
cpShape shape;
|
||||
|
||||
int numVerts;
|
||||
cpVect *verts, *tVerts;
|
||||
cpSplittingPlane *planes, *tPlanes;
|
||||
|
||||
cpFloat r;
|
||||
} cpPolyShape;
|
||||
|
||||
/// Allocate a polygon shape.
|
||||
cpPolyShape* cpPolyShapeAlloc(void);
|
||||
/// Initialize a polygon shape.
|
||||
CP_EXPORT cpPolyShape* cpPolyShapeAlloc(void);
|
||||
/// Initialize a polygon shape with rounded corners.
|
||||
/// A convex hull will be created from the vertexes.
|
||||
cpPolyShape* cpPolyShapeInit(cpPolyShape *poly, cpBody *body, int numVerts, const cpVect *verts, cpVect offset);
|
||||
/// Initialize a polygon shape.
|
||||
CP_EXPORT cpPolyShape* cpPolyShapeInit(cpPolyShape *poly, cpBody *body, int count, const cpVect *verts, cpTransform transform, cpFloat radius);
|
||||
/// Initialize a polygon shape with rounded corners.
|
||||
/// The vertexes must be convex with a counter-clockwise winding.
|
||||
CP_EXPORT cpPolyShape* cpPolyShapeInitRaw(cpPolyShape *poly, cpBody *body, int count, const cpVect *verts, cpFloat radius);
|
||||
/// Allocate and initialize a polygon shape with rounded corners.
|
||||
/// A convex hull will be created from the vertexes.
|
||||
cpPolyShape* cpPolyShapeInit2(cpPolyShape *poly, cpBody *body, int numVerts, const cpVect *verts, cpVect offset, cpFloat radius);
|
||||
/// Allocate and initialize a polygon shape.
|
||||
/// A convex hull will be created from the vertexes.
|
||||
cpShape* cpPolyShapeNew(cpBody *body, int numVerts, const cpVect *verts, cpVect offset);
|
||||
/// Allocate and initialize a polygon shape.
|
||||
/// A convex hull will be created from the vertexes.
|
||||
cpShape* cpPolyShapeNew2(cpBody *body, int numVerts, const cpVect *verts, cpVect offset, cpFloat radius);
|
||||
CP_EXPORT cpShape* cpPolyShapeNew(cpBody *body, int count, const cpVect *verts, cpTransform transform, cpFloat radius);
|
||||
/// Allocate and initialize a polygon shape with rounded corners.
|
||||
/// The vertexes must be convex with a counter-clockwise winding.
|
||||
CP_EXPORT cpShape* cpPolyShapeNewRaw(cpBody *body, int count, const cpVect *verts, cpFloat radius);
|
||||
|
||||
/// Initialize a box shaped polygon shape.
|
||||
cpPolyShape* cpBoxShapeInit(cpPolyShape *poly, cpBody *body, cpFloat width, cpFloat height);
|
||||
/// Initialize an offset box shaped polygon shape.
|
||||
cpPolyShape* cpBoxShapeInit2(cpPolyShape *poly, cpBody *body, cpBB box);
|
||||
/// Initialize an offset box shaped polygon shape.
|
||||
cpPolyShape* cpBoxShapeInit3(cpPolyShape *poly, cpBody *body, cpBB box, cpFloat radius);
|
||||
/// Initialize a box shaped polygon shape with rounded corners.
|
||||
CP_EXPORT cpPolyShape* cpBoxShapeInit(cpPolyShape *poly, cpBody *body, cpFloat width, cpFloat height, cpFloat radius);
|
||||
/// Initialize an offset box shaped polygon shape with rounded corners.
|
||||
CP_EXPORT cpPolyShape* cpBoxShapeInit2(cpPolyShape *poly, cpBody *body, cpBB box, cpFloat radius);
|
||||
/// Allocate and initialize a box shaped polygon shape.
|
||||
cpShape* cpBoxShapeNew(cpBody *body, cpFloat width, cpFloat height);
|
||||
CP_EXPORT cpShape* cpBoxShapeNew(cpBody *body, cpFloat width, cpFloat height, cpFloat radius);
|
||||
/// Allocate and initialize an offset box shaped polygon shape.
|
||||
cpShape* cpBoxShapeNew2(cpBody *body, cpBB box);
|
||||
/// Allocate and initialize an offset box shaped polygon shape.
|
||||
cpShape* cpBoxShapeNew3(cpBody *body, cpBB box, cpFloat radius);
|
||||
|
||||
/// Check that a set of vertexes is convex and has a clockwise winding.
|
||||
/// NOTE: Due to floating point precision issues, hulls created with cpQuickHull() are not guaranteed to validate!
|
||||
cpBool cpPolyValidate(const cpVect *verts, const int numVerts);
|
||||
CP_EXPORT cpShape* cpBoxShapeNew2(cpBody *body, cpBB box, cpFloat radius);
|
||||
|
||||
/// Get the number of verts in a polygon shape.
|
||||
int cpPolyShapeGetNumVerts(const cpShape *shape);
|
||||
CP_EXPORT int cpPolyShapeGetCount(const cpShape *shape);
|
||||
/// Get the @c ith vertex of a polygon shape.
|
||||
cpVect cpPolyShapeGetVert(const cpShape *shape, int idx);
|
||||
CP_EXPORT cpVect cpPolyShapeGetVert(const cpShape *shape, int index);
|
||||
/// Get the radius of a polygon shape.
|
||||
cpFloat cpPolyShapeGetRadius(const cpShape *shape);
|
||||
CP_EXPORT cpFloat cpPolyShapeGetRadius(const cpShape *shape);
|
||||
|
||||
/// @}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2007 Scott Lembcke
|
||||
/* Copyright (c) 2013 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
|
||||
|
|
@ -23,210 +23,177 @@
|
|||
/// The cpShape struct defines the shape of a rigid body.
|
||||
/// @{
|
||||
|
||||
typedef struct cpShapeClass cpShapeClass;
|
||||
|
||||
/// Nearest point query info struct.
|
||||
typedef struct cpNearestPointQueryInfo {
|
||||
/// Point query info struct.
|
||||
typedef struct cpPointQueryInfo {
|
||||
/// The nearest shape, NULL if no shape was within range.
|
||||
cpShape *shape;
|
||||
const cpShape *shape;
|
||||
/// The closest point on the shape's surface. (in world space coordinates)
|
||||
cpVect p;
|
||||
cpVect point;
|
||||
/// The distance to the point. The distance is negative if the point is inside the shape.
|
||||
cpFloat d;
|
||||
cpFloat distance;
|
||||
/// The gradient of the signed distance function.
|
||||
/// The same as info.p/info.d, but accurate even for very small values of info.d.
|
||||
cpVect g;
|
||||
} cpNearestPointQueryInfo;
|
||||
/// The value should be similar to info.p/info.d, but accurate even for very small values of info.d.
|
||||
cpVect gradient;
|
||||
} cpPointQueryInfo;
|
||||
|
||||
/// Segment query info struct.
|
||||
typedef struct cpSegmentQueryInfo {
|
||||
/// The shape that was hit, NULL if no collision occured.
|
||||
cpShape *shape;
|
||||
/// The normalized distance along the query segment in the range [0, 1].
|
||||
cpFloat t;
|
||||
/// The shape that was hit, or NULL if no collision occured.
|
||||
const cpShape *shape;
|
||||
/// The point of impact.
|
||||
cpVect point;
|
||||
/// The normal of the surface hit.
|
||||
cpVect n;
|
||||
cpVect normal;
|
||||
/// The normalized distance along the query segment in the range [0, 1].
|
||||
cpFloat alpha;
|
||||
} cpSegmentQueryInfo;
|
||||
|
||||
/// @private
|
||||
typedef enum cpShapeType{
|
||||
CP_CIRCLE_SHAPE,
|
||||
CP_SEGMENT_SHAPE,
|
||||
CP_POLY_SHAPE,
|
||||
CP_NUM_SHAPES
|
||||
} cpShapeType;
|
||||
|
||||
typedef cpBB (*cpShapeCacheDataImpl)(cpShape *shape, cpVect p, cpVect rot);
|
||||
typedef void (*cpShapeDestroyImpl)(cpShape *shape);
|
||||
typedef void (*cpShapeNearestPointQueryImpl)(cpShape *shape, cpVect p, cpNearestPointQueryInfo *info);
|
||||
typedef void (*cpShapeSegmentQueryImpl)(cpShape *shape, cpVect a, cpVect b, cpSegmentQueryInfo *info);
|
||||
|
||||
/// @private
|
||||
struct cpShapeClass {
|
||||
cpShapeType type;
|
||||
|
||||
cpShapeCacheDataImpl cacheData;
|
||||
cpShapeDestroyImpl destroy;
|
||||
cpShapeNearestPointQueryImpl nearestPointQuery;
|
||||
cpShapeSegmentQueryImpl segmentQuery;
|
||||
};
|
||||
|
||||
/// Opaque collision shape struct.
|
||||
struct cpShape {
|
||||
CP_PRIVATE(const cpShapeClass *klass);
|
||||
|
||||
/// The rigid body this collision shape is attached to.
|
||||
cpBody *body;
|
||||
|
||||
/// The current bounding box of the shape.
|
||||
cpBB bb;
|
||||
|
||||
/// Sensor flag.
|
||||
/// Sensor shapes call collision callbacks but don't produce collisions.
|
||||
cpBool sensor;
|
||||
|
||||
/// Coefficient of restitution. (elasticity)
|
||||
cpFloat e;
|
||||
/// Coefficient of friction.
|
||||
cpFloat u;
|
||||
/// Surface velocity used when solving for friction.
|
||||
cpVect surface_v;
|
||||
|
||||
/// User definable data pointer.
|
||||
/// Generally this points to your the game object class so you can access it
|
||||
/// when given a cpShape reference in a callback.
|
||||
cpDataPointer data;
|
||||
|
||||
/// Collision type of this shape used when picking collision handlers.
|
||||
cpCollisionType collision_type;
|
||||
/// Group of this shape. Shapes in the same group don't collide.
|
||||
/// Fast collision filtering type that is used to determine if two objects collide before calling collision or query callbacks.
|
||||
typedef struct cpShapeFilter {
|
||||
/// Two objects with the same non-zero group value do not collide.
|
||||
/// This is generally used to group objects in a composite object together to disable self collisions.
|
||||
cpGroup group;
|
||||
// Layer bitmask for this shape. Shapes only collide if the bitwise and of their layers is non-zero.
|
||||
cpLayers layers;
|
||||
/// A bitmask of user definable categories that this object belongs to.
|
||||
/// The category/mask combinations of both objects in a collision must agree for a collision to occur.
|
||||
cpBitmask categories;
|
||||
/// A bitmask of user definable category types that this object object collides with.
|
||||
/// The category/mask combinations of both objects in a collision must agree for a collision to occur.
|
||||
cpBitmask mask;
|
||||
} cpShapeFilter;
|
||||
|
||||
CP_PRIVATE(cpSpace *space);
|
||||
/// Collision filter value for a shape that will collide with anything except CP_SHAPE_FILTER_NONE.
|
||||
static const cpShapeFilter CP_SHAPE_FILTER_ALL = {CP_NO_GROUP, CP_ALL_CATEGORIES, CP_ALL_CATEGORIES};
|
||||
/// Collision filter value for a shape that does not collide with anything.
|
||||
static const cpShapeFilter CP_SHAPE_FILTER_NONE = {CP_NO_GROUP, ~CP_ALL_CATEGORIES, ~CP_ALL_CATEGORIES};
|
||||
|
||||
CP_PRIVATE(cpShape *next);
|
||||
CP_PRIVATE(cpShape *prev);
|
||||
|
||||
CP_PRIVATE(cpHashValue hashid);
|
||||
};
|
||||
/// Create a new collision filter.
|
||||
static inline cpShapeFilter
|
||||
cpShapeFilterNew(cpGroup group, cpBitmask categories, cpBitmask mask)
|
||||
{
|
||||
cpShapeFilter filter = {group, categories, mask};
|
||||
return filter;
|
||||
}
|
||||
|
||||
/// Destroy a shape.
|
||||
void cpShapeDestroy(cpShape *shape);
|
||||
CP_EXPORT void cpShapeDestroy(cpShape *shape);
|
||||
/// Destroy and Free a shape.
|
||||
void cpShapeFree(cpShape *shape);
|
||||
CP_EXPORT void cpShapeFree(cpShape *shape);
|
||||
|
||||
/// Update, cache and return the bounding box of a shape based on the body it's attached to.
|
||||
cpBB cpShapeCacheBB(cpShape *shape);
|
||||
CP_EXPORT cpBB cpShapeCacheBB(cpShape *shape);
|
||||
/// Update, cache and return the bounding box of a shape with an explicit transformation.
|
||||
cpBB cpShapeUpdate(cpShape *shape, cpVect pos, cpVect rot);
|
||||
|
||||
/// Test if a point lies within a shape.
|
||||
cpBool cpShapePointQuery(cpShape *shape, cpVect p);
|
||||
CP_EXPORT cpBB cpShapeUpdate(cpShape *shape, cpTransform transform);
|
||||
|
||||
/// Perform a nearest point query. It finds the closest point on the surface of shape to a specific point.
|
||||
/// The value returned is the distance between the points. A negative distance means the point is inside the shape.
|
||||
cpFloat cpShapeNearestPointQuery(cpShape *shape, cpVect p, cpNearestPointQueryInfo *out);
|
||||
CP_EXPORT cpFloat cpShapePointQuery(const cpShape *shape, cpVect p, cpPointQueryInfo *out);
|
||||
|
||||
/// Perform a segment query against a shape. @c info must be a pointer to a valid cpSegmentQueryInfo structure.
|
||||
cpBool cpShapeSegmentQuery(cpShape *shape, cpVect a, cpVect b, cpSegmentQueryInfo *info);
|
||||
CP_EXPORT cpBool cpShapeSegmentQuery(const cpShape *shape, cpVect a, cpVect b, cpFloat radius, cpSegmentQueryInfo *info);
|
||||
|
||||
/// Get the hit point for a segment query.
|
||||
static inline cpVect cpSegmentQueryHitPoint(const cpVect start, const cpVect end, const cpSegmentQueryInfo info)
|
||||
{
|
||||
return cpvlerp(start, end, info.t);
|
||||
}
|
||||
/// Return contact information about two shapes.
|
||||
CP_EXPORT cpContactPointSet cpShapesCollide(const cpShape *a, const cpShape *b);
|
||||
|
||||
/// Get the hit distance for a segment query.
|
||||
static inline cpFloat cpSegmentQueryHitDist(const cpVect start, const cpVect end, const cpSegmentQueryInfo info)
|
||||
{
|
||||
return cpvdist(start, end)*info.t;
|
||||
}
|
||||
/// The cpSpace this body is added to.
|
||||
CP_EXPORT cpSpace* cpShapeGetSpace(const cpShape *shape);
|
||||
|
||||
#define CP_DefineShapeStructGetter(type, member, name) \
|
||||
static inline type cpShapeGet##name(const cpShape *shape){return shape->member;}
|
||||
/// The cpBody this shape is connected to.
|
||||
CP_EXPORT cpBody* cpShapeGetBody(const cpShape *shape);
|
||||
/// Set the cpBody this shape is connected to.
|
||||
/// Can only be used if the shape is not currently added to a space.
|
||||
CP_EXPORT void cpShapeSetBody(cpShape *shape, cpBody *body);
|
||||
|
||||
#define CP_DefineShapeStructSetter(type, member, name, activates) \
|
||||
static inline void cpShapeSet##name(cpShape *shape, type value){ \
|
||||
if(activates && shape->body) cpBodyActivate(shape->body); \
|
||||
shape->member = value; \
|
||||
}
|
||||
/// Get the mass of the shape if you are having Chipmunk calculate mass properties for you.
|
||||
cpFloat cpShapeGetMass(cpShape *shape);
|
||||
/// Set the mass of this shape to have Chipmunk calculate mass properties for you.
|
||||
CP_EXPORT void cpShapeSetMass(cpShape *shape, cpFloat mass);
|
||||
|
||||
#define CP_DefineShapeStructProperty(type, member, name, activates) \
|
||||
CP_DefineShapeStructGetter(type, member, name) \
|
||||
CP_DefineShapeStructSetter(type, member, name, activates)
|
||||
/// Get the density of the shape if you are having Chipmunk calculate mass properties for you.
|
||||
CP_EXPORT cpFloat cpShapeGetDensity(cpShape *shape);
|
||||
/// Set the density of this shape to have Chipmunk calculate mass properties for you.
|
||||
CP_EXPORT void cpShapeSetDensity(cpShape *shape, cpFloat density);
|
||||
|
||||
CP_DefineShapeStructGetter(cpSpace*, CP_PRIVATE(space), Space)
|
||||
/// Get the calculated moment of inertia for this shape.
|
||||
CP_EXPORT cpFloat cpShapeGetMoment(cpShape *shape);
|
||||
/// Get the calculated area of this shape.
|
||||
CP_EXPORT cpFloat cpShapeGetArea(cpShape *shape);
|
||||
/// Get the centroid of this shape.
|
||||
CP_EXPORT cpVect cpShapeGetCenterOfGravity(cpShape *shape);
|
||||
|
||||
CP_DefineShapeStructGetter(cpBody*, body, Body)
|
||||
void cpShapeSetBody(cpShape *shape, cpBody *body);
|
||||
/// Get the bounding box that contains the shape given it's current position and angle.
|
||||
CP_EXPORT cpBB cpShapeGetBB(const cpShape *shape);
|
||||
|
||||
CP_DefineShapeStructGetter(cpBB, bb, BB)
|
||||
CP_DefineShapeStructProperty(cpBool, sensor, Sensor, cpTrue)
|
||||
CP_DefineShapeStructProperty(cpFloat, e, Elasticity, cpFalse)
|
||||
CP_DefineShapeStructProperty(cpFloat, u, Friction, cpTrue)
|
||||
CP_DefineShapeStructProperty(cpVect, surface_v, SurfaceVelocity, cpTrue)
|
||||
CP_DefineShapeStructProperty(cpDataPointer, data, UserData, cpFalse)
|
||||
CP_DefineShapeStructProperty(cpCollisionType, collision_type, CollisionType, cpTrue)
|
||||
CP_DefineShapeStructProperty(cpGroup, group, Group, cpTrue)
|
||||
CP_DefineShapeStructProperty(cpLayers, layers, Layers, cpTrue)
|
||||
/// Get if the shape is set to be a sensor or not.
|
||||
CP_EXPORT cpBool cpShapeGetSensor(const cpShape *shape);
|
||||
/// Set if the shape is a sensor or not.
|
||||
CP_EXPORT void cpShapeSetSensor(cpShape *shape, cpBool sensor);
|
||||
|
||||
/// When initializing a shape, it's hash value comes from a counter.
|
||||
/// Because the hash value may affect iteration order, you can reset the shape ID counter
|
||||
/// when recreating a space. This will make the simulation be deterministic.
|
||||
void cpResetShapeIdCounter(void);
|
||||
/// Get the elasticity of this shape.
|
||||
CP_EXPORT cpFloat cpShapeGetElasticity(const cpShape *shape);
|
||||
/// Set the elasticity of this shape.
|
||||
CP_EXPORT void cpShapeSetElasticity(cpShape *shape, cpFloat elasticity);
|
||||
|
||||
/// Get the friction of this shape.
|
||||
CP_EXPORT cpFloat cpShapeGetFriction(const cpShape *shape);
|
||||
/// Set the friction of this shape.
|
||||
CP_EXPORT void cpShapeSetFriction(cpShape *shape, cpFloat friction);
|
||||
|
||||
/// Get the surface velocity of this shape.
|
||||
CP_EXPORT cpVect cpShapeGetSurfaceVelocity(const cpShape *shape);
|
||||
/// Set the surface velocity of this shape.
|
||||
CP_EXPORT void cpShapeSetSurfaceVelocity(cpShape *shape, cpVect surfaceVelocity);
|
||||
|
||||
/// Get the user definable data pointer of this shape.
|
||||
CP_EXPORT cpDataPointer cpShapeGetUserData(const cpShape *shape);
|
||||
/// Set the user definable data pointer of this shape.
|
||||
CP_EXPORT void cpShapeSetUserData(cpShape *shape, cpDataPointer userData);
|
||||
|
||||
/// Set the collision type of this shape.
|
||||
CP_EXPORT cpCollisionType cpShapeGetCollisionType(const cpShape *shape);
|
||||
/// Get the collision type of this shape.
|
||||
CP_EXPORT void cpShapeSetCollisionType(cpShape *shape, cpCollisionType collisionType);
|
||||
|
||||
/// Get the collision filtering parameters of this shape.
|
||||
CP_EXPORT cpShapeFilter cpShapeGetFilter(const cpShape *shape);
|
||||
/// Set the collision filtering parameters of this shape.
|
||||
CP_EXPORT void cpShapeSetFilter(cpShape *shape, cpShapeFilter filter);
|
||||
|
||||
#define CP_DeclareShapeGetter(struct, type, name) type struct##Get##name(const cpShape *shape)
|
||||
|
||||
/// @}
|
||||
/// @defgroup cpCircleShape cpCircleShape
|
||||
|
||||
/// @private
|
||||
typedef struct cpCircleShape {
|
||||
cpShape shape;
|
||||
|
||||
cpVect c, tc;
|
||||
cpFloat r;
|
||||
} cpCircleShape;
|
||||
|
||||
/// Allocate a circle shape.
|
||||
cpCircleShape* cpCircleShapeAlloc(void);
|
||||
CP_EXPORT cpCircleShape* cpCircleShapeAlloc(void);
|
||||
/// Initialize a circle shape.
|
||||
cpCircleShape* cpCircleShapeInit(cpCircleShape *circle, cpBody *body, cpFloat radius, cpVect offset);
|
||||
CP_EXPORT cpCircleShape* cpCircleShapeInit(cpCircleShape *circle, cpBody *body, cpFloat radius, cpVect offset);
|
||||
/// Allocate and initialize a circle shape.
|
||||
cpShape* cpCircleShapeNew(cpBody *body, cpFloat radius, cpVect offset);
|
||||
CP_EXPORT cpShape* cpCircleShapeNew(cpBody *body, cpFloat radius, cpVect offset);
|
||||
|
||||
CP_DeclareShapeGetter(cpCircleShape, cpVect, Offset);
|
||||
CP_DeclareShapeGetter(cpCircleShape, cpFloat, Radius);
|
||||
/// Get the offset of a circle shape.
|
||||
CP_EXPORT cpVect cpCircleShapeGetOffset(const cpShape *shape);
|
||||
/// Get the radius of a circle shape.
|
||||
CP_EXPORT cpFloat cpCircleShapeGetRadius(const cpShape *shape);
|
||||
|
||||
/// @}
|
||||
/// @defgroup cpSegmentShape cpSegmentShape
|
||||
|
||||
/// @private
|
||||
typedef struct cpSegmentShape {
|
||||
cpShape shape;
|
||||
|
||||
cpVect a, b, n;
|
||||
cpVect ta, tb, tn;
|
||||
cpFloat r;
|
||||
|
||||
cpVect a_tangent, b_tangent;
|
||||
} cpSegmentShape;
|
||||
|
||||
/// Allocate a segment shape.
|
||||
cpSegmentShape* cpSegmentShapeAlloc(void);
|
||||
CP_EXPORT cpSegmentShape* cpSegmentShapeAlloc(void);
|
||||
/// Initialize a segment shape.
|
||||
cpSegmentShape* cpSegmentShapeInit(cpSegmentShape *seg, cpBody *body, cpVect a, cpVect b, cpFloat radius);
|
||||
CP_EXPORT cpSegmentShape* cpSegmentShapeInit(cpSegmentShape *seg, cpBody *body, cpVect a, cpVect b, cpFloat radius);
|
||||
/// Allocate and initialize a segment shape.
|
||||
cpShape* cpSegmentShapeNew(cpBody *body, cpVect a, cpVect b, cpFloat radius);
|
||||
CP_EXPORT cpShape* cpSegmentShapeNew(cpBody *body, cpVect a, cpVect b, cpFloat radius);
|
||||
|
||||
/// Let Chipmunk know about the geometry of adjacent segments to avoid colliding with endcaps.
|
||||
void cpSegmentShapeSetNeighbors(cpShape *shape, cpVect prev, cpVect next);
|
||||
CP_EXPORT void cpSegmentShapeSetNeighbors(cpShape *shape, cpVect prev, cpVect next);
|
||||
|
||||
CP_DeclareShapeGetter(cpSegmentShape, cpVect, A);
|
||||
CP_DeclareShapeGetter(cpSegmentShape, cpVect, B);
|
||||
CP_DeclareShapeGetter(cpSegmentShape, cpVect, Normal);
|
||||
CP_DeclareShapeGetter(cpSegmentShape, cpFloat, Radius);
|
||||
/// Get the first endpoint of a segment shape.
|
||||
CP_EXPORT cpVect cpSegmentShapeGetA(const cpShape *shape);
|
||||
/// Get the second endpoint of a segment shape.
|
||||
CP_EXPORT cpVect cpSegmentShapeGetB(const cpShape *shape);
|
||||
/// Get the normal of a segment shape.
|
||||
CP_EXPORT cpVect cpSegmentShapeGetNormal(const cpShape *shape);
|
||||
/// Get the first endpoint of a segment shape.
|
||||
CP_EXPORT cpFloat cpSegmentShapeGetRadius(const cpShape *shape);
|
||||
|
||||
/// @}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2007 Scott Lembcke
|
||||
/* Copyright (c) 2013 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
|
||||
|
|
@ -22,191 +22,161 @@
|
|||
/// @defgroup cpSpace cpSpace
|
||||
/// @{
|
||||
|
||||
typedef struct cpContactBufferHeader cpContactBufferHeader;
|
||||
typedef void (*cpSpaceArbiterApplyImpulseFunc)(cpArbiter *arb);
|
||||
//MARK: Definitions
|
||||
|
||||
/// Basic Unit of Simulation in Chipmunk
|
||||
struct cpSpace {
|
||||
/// Number of iterations to use in the impulse solver to solve contacts.
|
||||
int iterations;
|
||||
/// 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, cpDataPointer userData);
|
||||
/// 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, cpDataPointer userData);
|
||||
/// Collision post-solve event function callback type.
|
||||
typedef void (*cpCollisionPostSolveFunc)(cpArbiter *arb, cpSpace *space, cpDataPointer userData);
|
||||
/// Collision separate event function callback type.
|
||||
typedef void (*cpCollisionSeparateFunc)(cpArbiter *arb, cpSpace *space, cpDataPointer userData);
|
||||
|
||||
/// Gravity to pass to rigid bodies when integrating velocity.
|
||||
cpVect gravity;
|
||||
|
||||
/// Damping rate expressed as the fraction of velocity bodies retain each second.
|
||||
/// A value of 0.9 would mean that each body's velocity will drop 10% per second.
|
||||
/// The default value is 1.0, meaning no damping is applied.
|
||||
/// @note This damping value is different than those of cpDampedSpring and cpDampedRotarySpring.
|
||||
cpFloat damping;
|
||||
|
||||
/// Speed threshold for a body to be considered idle.
|
||||
/// The default value of 0 means to let the space guess a good threshold based on gravity.
|
||||
cpFloat idleSpeedThreshold;
|
||||
|
||||
/// Time a group of bodies must remain idle in order to fall asleep.
|
||||
/// Enabling sleeping also implicitly enables the the contact graph.
|
||||
/// The default value of INFINITY disables the sleeping algorithm.
|
||||
cpFloat sleepTimeThreshold;
|
||||
|
||||
/// Amount of encouraged penetration between colliding shapes.
|
||||
/// Used to reduce oscillating contacts and keep the collision cache warm.
|
||||
/// Defaults to 0.1. If you have poor simulation quality,
|
||||
/// increase this number as much as possible without allowing visible amounts of overlap.
|
||||
cpFloat collisionSlop;
|
||||
|
||||
/// Determines how fast overlapping shapes are pushed apart.
|
||||
/// Expressed as a fraction of the error remaining after each second.
|
||||
/// Defaults to pow(1.0 - 0.1, 60.0) meaning that Chipmunk fixes 10% of overlap each frame at 60Hz.
|
||||
cpFloat collisionBias;
|
||||
|
||||
/// Number of frames that contact information should persist.
|
||||
/// Defaults to 3. There is probably never a reason to change this value.
|
||||
cpTimestamp collisionPersistence;
|
||||
|
||||
/// Rebuild the contact graph during each step. Must be enabled to use the cpBodyEachArbiter() function.
|
||||
/// Disabled by default for a small performance boost. Enabled implicitly when the sleeping feature is enabled.
|
||||
cpBool enableContactGraph;
|
||||
|
||||
/// User definable data pointer.
|
||||
/// Generally this points to your game's controller or game state
|
||||
/// class so you can access it when given a cpSpace reference in a callback.
|
||||
cpDataPointer data;
|
||||
|
||||
/// The designated static body for this space.
|
||||
/// You can modify this body, or replace it with your own static body.
|
||||
/// By default it points to a statically allocated cpBody in the cpSpace struct.
|
||||
cpBody *staticBody;
|
||||
|
||||
CP_PRIVATE(cpTimestamp stamp);
|
||||
CP_PRIVATE(cpFloat curr_dt);
|
||||
|
||||
CP_PRIVATE(cpArray *bodies);
|
||||
CP_PRIVATE(cpArray *rousedBodies);
|
||||
CP_PRIVATE(cpArray *sleepingComponents);
|
||||
|
||||
CP_PRIVATE(cpSpatialIndex *staticShapes);
|
||||
CP_PRIVATE(cpSpatialIndex *activeShapes);
|
||||
|
||||
CP_PRIVATE(cpArray *arbiters);
|
||||
CP_PRIVATE(cpContactBufferHeader *contactBuffersHead);
|
||||
CP_PRIVATE(cpHashSet *cachedArbiters);
|
||||
CP_PRIVATE(cpArray *pooledArbiters);
|
||||
CP_PRIVATE(cpArray *constraints);
|
||||
|
||||
CP_PRIVATE(cpArray *allocatedBuffers);
|
||||
CP_PRIVATE(int locked);
|
||||
|
||||
CP_PRIVATE(cpHashSet *collisionHandlers);
|
||||
CP_PRIVATE(cpCollisionHandler defaultHandler);
|
||||
|
||||
CP_PRIVATE(cpBool skipPostStep);
|
||||
CP_PRIVATE(cpArray *postStepCallbacks);
|
||||
|
||||
CP_PRIVATE(cpBody _staticBody);
|
||||
/// Struct that holds function callback pointers to configure custom collision handling.
|
||||
/// Collision handlers have a pair of types; when a collision occurs between two shapes that have these types, the collision handler functions are triggered.
|
||||
struct cpCollisionHandler {
|
||||
/// Collision type identifier of the first shape that this handler recognizes.
|
||||
/// In the collision handler callback, the shape with this type will be the first argument. Read only.
|
||||
const cpCollisionType typeA;
|
||||
/// Collision type identifier of the second shape that this handler recognizes.
|
||||
/// In the collision handler callback, the shape with this type will be the second argument. Read only.
|
||||
const cpCollisionType typeB;
|
||||
/// This function is called when two shapes with types that match this collision handler begin colliding.
|
||||
cpCollisionBeginFunc beginFunc;
|
||||
/// This function is called each step when two shapes with types that match this collision handler are colliding.
|
||||
/// It's called before the collision solver runs so that you can affect a collision's outcome.
|
||||
cpCollisionPreSolveFunc preSolveFunc;
|
||||
/// This function is called each step when two shapes with types that match this collision handler are colliding.
|
||||
/// It's called after the collision solver runs so that you can read back information about the collision to trigger events in your game.
|
||||
cpCollisionPostSolveFunc postSolveFunc;
|
||||
/// This function is called when two shapes with types that match this collision handler stop colliding.
|
||||
cpCollisionSeparateFunc separateFunc;
|
||||
/// This is a user definable context pointer that is passed to all of the collision handler functions.
|
||||
cpDataPointer userData;
|
||||
};
|
||||
|
||||
// TODO: Make timestep a parameter?
|
||||
|
||||
|
||||
//MARK: Memory and Initialization
|
||||
|
||||
/// Allocate a cpSpace.
|
||||
cpSpace* cpSpaceAlloc(void);
|
||||
CP_EXPORT cpSpace* cpSpaceAlloc(void);
|
||||
/// Initialize a cpSpace.
|
||||
cpSpace* cpSpaceInit(cpSpace *space);
|
||||
CP_EXPORT cpSpace* cpSpaceInit(cpSpace *space);
|
||||
/// Allocate and initialize a cpSpace.
|
||||
cpSpace* cpSpaceNew(void);
|
||||
CP_EXPORT cpSpace* cpSpaceNew(void);
|
||||
|
||||
/// Destroy a cpSpace.
|
||||
void cpSpaceDestroy(cpSpace *space);
|
||||
CP_EXPORT void cpSpaceDestroy(cpSpace *space);
|
||||
/// Destroy and free a cpSpace.
|
||||
void cpSpaceFree(cpSpace *space);
|
||||
CP_EXPORT void cpSpaceFree(cpSpace *space);
|
||||
|
||||
#define CP_DefineSpaceStructGetter(type, member, name) \
|
||||
static inline type cpSpaceGet##name(const cpSpace *space){return space->member;}
|
||||
|
||||
#define CP_DefineSpaceStructSetter(type, member, name) \
|
||||
static inline void cpSpaceSet##name(cpSpace *space, type value){space->member = value;}
|
||||
//MARK: Properties
|
||||
|
||||
#define CP_DefineSpaceStructProperty(type, member, name) \
|
||||
CP_DefineSpaceStructGetter(type, member, name) \
|
||||
CP_DefineSpaceStructSetter(type, member, name)
|
||||
/// Number of iterations to use in the impulse solver to solve contacts and other constraints.
|
||||
CP_EXPORT int cpSpaceGetIterations(const cpSpace *space);
|
||||
CP_EXPORT void cpSpaceSetIterations(cpSpace *space, int iterations);
|
||||
|
||||
CP_DefineSpaceStructProperty(int, iterations, Iterations)
|
||||
CP_DefineSpaceStructProperty(cpVect, gravity, Gravity)
|
||||
CP_DefineSpaceStructProperty(cpFloat, damping, Damping)
|
||||
CP_DefineSpaceStructProperty(cpFloat, idleSpeedThreshold, IdleSpeedThreshold)
|
||||
CP_DefineSpaceStructProperty(cpFloat, sleepTimeThreshold, SleepTimeThreshold)
|
||||
CP_DefineSpaceStructProperty(cpFloat, collisionSlop, CollisionSlop)
|
||||
CP_DefineSpaceStructProperty(cpFloat, collisionBias, CollisionBias)
|
||||
CP_DefineSpaceStructProperty(cpTimestamp, collisionPersistence, CollisionPersistence)
|
||||
CP_DefineSpaceStructProperty(cpBool, enableContactGraph, EnableContactGraph)
|
||||
CP_DefineSpaceStructProperty(cpDataPointer, data, UserData)
|
||||
CP_DefineSpaceStructGetter(cpBody*, staticBody, StaticBody)
|
||||
CP_DefineSpaceStructGetter(cpFloat, CP_PRIVATE(curr_dt), CurrentTimeStep)
|
||||
/// Gravity to pass to rigid bodies when integrating velocity.
|
||||
CP_EXPORT cpVect cpSpaceGetGravity(const cpSpace *space);
|
||||
CP_EXPORT void cpSpaceSetGravity(cpSpace *space, cpVect gravity);
|
||||
|
||||
/// returns true from inside a callback and objects cannot be added/removed.
|
||||
static inline cpBool
|
||||
cpSpaceIsLocked(cpSpace *space)
|
||||
{
|
||||
return space->CP_PRIVATE(locked);
|
||||
}
|
||||
/// Damping rate expressed as the fraction of velocity bodies retain each second.
|
||||
/// A value of 0.9 would mean that each body's velocity will drop 10% per second.
|
||||
/// The default value is 1.0, meaning no damping is applied.
|
||||
/// @note This damping value is different than those of cpDampedSpring and cpDampedRotarySpring.
|
||||
CP_EXPORT cpFloat cpSpaceGetDamping(const cpSpace *space);
|
||||
CP_EXPORT void cpSpaceSetDamping(cpSpace *space, cpFloat damping);
|
||||
|
||||
/// Set a default collision handler for this space.
|
||||
/// The default collision handler is invoked for each colliding pair of shapes
|
||||
/// that isn't explicitly handled by a specific collision handler.
|
||||
/// You can pass NULL for any function you don't want to implement.
|
||||
void cpSpaceSetDefaultCollisionHandler(
|
||||
cpSpace *space,
|
||||
cpCollisionBeginFunc begin,
|
||||
cpCollisionPreSolveFunc preSolve,
|
||||
cpCollisionPostSolveFunc postSolve,
|
||||
cpCollisionSeparateFunc separate,
|
||||
void *data
|
||||
);
|
||||
/// Speed threshold for a body to be considered idle.
|
||||
/// The default value of 0 means to let the space guess a good threshold based on gravity.
|
||||
CP_EXPORT cpFloat cpSpaceGetIdleSpeedThreshold(const cpSpace *space);
|
||||
CP_EXPORT void cpSpaceSetIdleSpeedThreshold(cpSpace *space, cpFloat idleSpeedThreshold);
|
||||
|
||||
/// Set a collision handler to be used whenever the two shapes with the given collision types collide.
|
||||
/// You can pass NULL for any function you don't want to implement.
|
||||
void cpSpaceAddCollisionHandler(
|
||||
cpSpace *space,
|
||||
cpCollisionType a, cpCollisionType b,
|
||||
cpCollisionBeginFunc begin,
|
||||
cpCollisionPreSolveFunc preSolve,
|
||||
cpCollisionPostSolveFunc postSolve,
|
||||
cpCollisionSeparateFunc separate,
|
||||
void *data
|
||||
);
|
||||
/// Time a group of bodies must remain idle in order to fall asleep.
|
||||
/// Enabling sleeping also implicitly enables the the contact graph.
|
||||
/// The default value of INFINITY disables the sleeping algorithm.
|
||||
CP_EXPORT cpFloat cpSpaceGetSleepTimeThreshold(const cpSpace *space);
|
||||
CP_EXPORT void cpSpaceSetSleepTimeThreshold(cpSpace *space, cpFloat sleepTimeThreshold);
|
||||
|
||||
/// Unset a collision handler.
|
||||
void cpSpaceRemoveCollisionHandler(cpSpace *space, cpCollisionType a, cpCollisionType b);
|
||||
/// Amount of encouraged penetration between colliding shapes.
|
||||
/// Used to reduce oscillating contacts and keep the collision cache warm.
|
||||
/// Defaults to 0.1. If you have poor simulation quality,
|
||||
/// increase this number as much as possible without allowing visible amounts of overlap.
|
||||
CP_EXPORT cpFloat cpSpaceGetCollisionSlop(const cpSpace *space);
|
||||
CP_EXPORT void cpSpaceSetCollisionSlop(cpSpace *space, cpFloat collisionSlop);
|
||||
|
||||
/// Determines how fast overlapping shapes are pushed apart.
|
||||
/// Expressed as a fraction of the error remaining after each second.
|
||||
/// Defaults to pow(1.0 - 0.1, 60.0) meaning that Chipmunk fixes 10% of overlap each frame at 60Hz.
|
||||
CP_EXPORT cpFloat cpSpaceGetCollisionBias(const cpSpace *space);
|
||||
CP_EXPORT void cpSpaceSetCollisionBias(cpSpace *space, cpFloat collisionBias);
|
||||
|
||||
/// Number of frames that contact information should persist.
|
||||
/// Defaults to 3. There is probably never a reason to change this value.
|
||||
CP_EXPORT cpTimestamp cpSpaceGetCollisionPersistence(const cpSpace *space);
|
||||
CP_EXPORT void cpSpaceSetCollisionPersistence(cpSpace *space, cpTimestamp collisionPersistence);
|
||||
|
||||
/// User definable data pointer.
|
||||
/// Generally this points to your game's controller or game state
|
||||
/// class so you can access it when given a cpSpace reference in a callback.
|
||||
CP_EXPORT cpDataPointer cpSpaceGetUserData(const cpSpace *space);
|
||||
CP_EXPORT void cpSpaceSetUserData(cpSpace *space, cpDataPointer userData);
|
||||
|
||||
/// The Space provided static body for a given cpSpace.
|
||||
/// This is merely provided for convenience and you are not required to use it.
|
||||
CP_EXPORT cpBody* cpSpaceGetStaticBody(const cpSpace *space);
|
||||
|
||||
/// Returns the current (or most recent) time step used with the given space.
|
||||
/// Useful from callbacks if your time step is not a compile-time global.
|
||||
CP_EXPORT cpFloat cpSpaceGetCurrentTimeStep(const cpSpace *space);
|
||||
|
||||
/// returns true from inside a callback when objects cannot be added/removed.
|
||||
CP_EXPORT cpBool cpSpaceIsLocked(cpSpace *space);
|
||||
|
||||
|
||||
//MARK: Collision Handlers
|
||||
|
||||
/// Create or return the existing collision handler that is called for all collisions that are not handled by a more specific collision handler.
|
||||
CP_EXPORT cpCollisionHandler *cpSpaceAddDefaultCollisionHandler(cpSpace *space);
|
||||
/// Create or return the existing collision handler for the specified pair of collision types.
|
||||
/// If wildcard handlers are used with either of the collision types, it's the responibility of the custom handler to invoke the wildcard handlers.
|
||||
CP_EXPORT cpCollisionHandler *cpSpaceAddCollisionHandler(cpSpace *space, cpCollisionType a, cpCollisionType b);
|
||||
/// Create or return the existing wildcard collision handler for the specified type.
|
||||
CP_EXPORT cpCollisionHandler *cpSpaceAddWildcardHandler(cpSpace *space, cpCollisionType type);
|
||||
|
||||
|
||||
//MARK: Add/Remove objects
|
||||
|
||||
/// Add a collision shape to the simulation.
|
||||
/// If the shape is attached to a static body, it will be added as a static shape.
|
||||
cpShape* cpSpaceAddShape(cpSpace *space, cpShape *shape);
|
||||
/// Explicity add a shape as a static shape to the simulation.
|
||||
cpShape* cpSpaceAddStaticShape(cpSpace *space, cpShape *shape);
|
||||
CP_EXPORT cpShape* cpSpaceAddShape(cpSpace *space, cpShape *shape);
|
||||
/// Add a rigid body to the simulation.
|
||||
cpBody* cpSpaceAddBody(cpSpace *space, cpBody *body);
|
||||
CP_EXPORT cpBody* cpSpaceAddBody(cpSpace *space, cpBody *body);
|
||||
/// Add a constraint to the simulation.
|
||||
cpConstraint* cpSpaceAddConstraint(cpSpace *space, cpConstraint *constraint);
|
||||
CP_EXPORT cpConstraint* cpSpaceAddConstraint(cpSpace *space, cpConstraint *constraint);
|
||||
|
||||
/// Remove a collision shape from the simulation.
|
||||
void cpSpaceRemoveShape(cpSpace *space, cpShape *shape);
|
||||
/// Remove a collision shape added using cpSpaceAddStaticShape() from the simulation.
|
||||
void cpSpaceRemoveStaticShape(cpSpace *space, cpShape *shape);
|
||||
CP_EXPORT void cpSpaceRemoveShape(cpSpace *space, cpShape *shape);
|
||||
/// Remove a rigid body from the simulation.
|
||||
void cpSpaceRemoveBody(cpSpace *space, cpBody *body);
|
||||
CP_EXPORT void cpSpaceRemoveBody(cpSpace *space, cpBody *body);
|
||||
/// Remove a constraint from the simulation.
|
||||
void cpSpaceRemoveConstraint(cpSpace *space, cpConstraint *constraint);
|
||||
CP_EXPORT void cpSpaceRemoveConstraint(cpSpace *space, cpConstraint *constraint);
|
||||
|
||||
/// Test if a collision shape has been added to the space.
|
||||
cpBool cpSpaceContainsShape(cpSpace *space, cpShape *shape);
|
||||
CP_EXPORT cpBool cpSpaceContainsShape(cpSpace *space, cpShape *shape);
|
||||
/// Test if a rigid body has been added to the space.
|
||||
cpBool cpSpaceContainsBody(cpSpace *space, cpBody *body);
|
||||
CP_EXPORT cpBool cpSpaceContainsBody(cpSpace *space, cpBody *body);
|
||||
/// Test if a constraint has been added to the space.
|
||||
cpBool cpSpaceContainsConstraint(cpSpace *space, cpConstraint *constraint);
|
||||
CP_EXPORT cpBool cpSpaceContainsConstraint(cpSpace *space, cpConstraint *constraint);
|
||||
|
||||
/// Convert a dynamic rogue body to a static one.
|
||||
/// If the body is active, you must remove it from the space first.
|
||||
void cpSpaceConvertBodyToStatic(cpSpace *space, cpBody *body);
|
||||
/// Convert a body to a dynamic rogue body.
|
||||
/// If you want the body to be active after the transition, you must add it to the space also.
|
||||
void cpSpaceConvertBodyToDynamic(cpSpace *space, cpBody *body, cpFloat mass, cpFloat moment);
|
||||
//MARK: Post-Step Callbacks
|
||||
|
||||
/// Post Step callback function type.
|
||||
typedef void (*cpPostStepFunc)(cpSpace *space, void *key, void *data);
|
||||
|
|
@ -214,70 +184,136 @@ typedef void (*cpPostStepFunc)(cpSpace *space, void *key, void *data);
|
|||
/// You can only register one callback per unique value for @c key.
|
||||
/// Returns true only if @c key has never been scheduled before.
|
||||
/// It's possible to pass @c NULL for @c func if you only want to mark @c key as being used.
|
||||
cpBool cpSpaceAddPostStepCallback(cpSpace *space, cpPostStepFunc func, void *key, void *data);
|
||||
CP_EXPORT cpBool cpSpaceAddPostStepCallback(cpSpace *space, cpPostStepFunc func, void *key, void *data);
|
||||
|
||||
/// Point query callback function type.
|
||||
typedef void (*cpSpacePointQueryFunc)(cpShape *shape, void *data);
|
||||
/// Query the space at a point and call @c func for each shape found.
|
||||
void cpSpacePointQuery(cpSpace *space, cpVect point, cpLayers layers, cpGroup group, cpSpacePointQueryFunc func, void *data);
|
||||
/// Query the space at a point and return the first shape found. Returns NULL if no shapes were found.
|
||||
cpShape *cpSpacePointQueryFirst(cpSpace *space, cpVect point, cpLayers layers, cpGroup group);
|
||||
|
||||
//MARK: Queries
|
||||
|
||||
// TODO: Queries and iterators should take a cpSpace parametery.
|
||||
// TODO: They should also be abortable.
|
||||
|
||||
/// Nearest point query callback function type.
|
||||
typedef void (*cpSpaceNearestPointQueryFunc)(cpShape *shape, cpFloat distance, cpVect point, void *data);
|
||||
typedef void (*cpSpacePointQueryFunc)(cpShape *shape, cpVect point, cpFloat distance, cpVect gradient, void *data);
|
||||
/// Query the space at a point and call @c func for each shape found.
|
||||
void cpSpaceNearestPointQuery(cpSpace *space, cpVect point, cpFloat maxDistance, cpLayers layers, cpGroup group, cpSpaceNearestPointQueryFunc func, void *data);
|
||||
CP_EXPORT void cpSpacePointQuery(cpSpace *space, cpVect point, cpFloat maxDistance, cpShapeFilter filter, cpSpacePointQueryFunc func, void *data);
|
||||
/// Query the space at a point and return the nearest shape found. Returns NULL if no shapes were found.
|
||||
cpShape *cpSpaceNearestPointQueryNearest(cpSpace *space, cpVect point, cpFloat maxDistance, cpLayers layers, cpGroup group, cpNearestPointQueryInfo *out);
|
||||
CP_EXPORT cpShape *cpSpacePointQueryNearest(cpSpace *space, cpVect point, cpFloat maxDistance, cpShapeFilter filter, cpPointQueryInfo *out);
|
||||
|
||||
/// Segment query callback function type.
|
||||
typedef void (*cpSpaceSegmentQueryFunc)(cpShape *shape, cpFloat t, cpVect n, void *data);
|
||||
typedef void (*cpSpaceSegmentQueryFunc)(cpShape *shape, cpVect point, cpVect normal, cpFloat alpha, void *data);
|
||||
/// Perform a directed line segment query (like a raycast) against the space calling @c func for each shape intersected.
|
||||
void cpSpaceSegmentQuery(cpSpace *space, cpVect start, cpVect end, cpLayers layers, cpGroup group, cpSpaceSegmentQueryFunc func, void *data);
|
||||
CP_EXPORT void cpSpaceSegmentQuery(cpSpace *space, cpVect start, cpVect end, cpFloat radius, cpShapeFilter filter, cpSpaceSegmentQueryFunc func, void *data);
|
||||
/// Perform a directed line segment query (like a raycast) against the space and return the first shape hit. Returns NULL if no shapes were hit.
|
||||
cpShape *cpSpaceSegmentQueryFirst(cpSpace *space, cpVect start, cpVect end, cpLayers layers, cpGroup group, cpSegmentQueryInfo *out);
|
||||
CP_EXPORT cpShape *cpSpaceSegmentQueryFirst(cpSpace *space, cpVect start, cpVect end, cpFloat radius, cpShapeFilter filter, cpSegmentQueryInfo *out);
|
||||
|
||||
/// Rectangle Query callback function type.
|
||||
typedef void (*cpSpaceBBQueryFunc)(cpShape *shape, void *data);
|
||||
/// Perform a fast rectangle query on the space calling @c func for each shape found.
|
||||
/// Only the shape's bounding boxes are checked for overlap, not their full shape.
|
||||
void cpSpaceBBQuery(cpSpace *space, cpBB bb, cpLayers layers, cpGroup group, cpSpaceBBQueryFunc func, void *data);
|
||||
CP_EXPORT void cpSpaceBBQuery(cpSpace *space, cpBB bb, cpShapeFilter filter, cpSpaceBBQueryFunc func, void *data);
|
||||
|
||||
/// Shape query callback function type.
|
||||
typedef void (*cpSpaceShapeQueryFunc)(cpShape *shape, cpContactPointSet *points, void *data);
|
||||
/// Query a space for any shapes overlapping the given shape and call @c func for each shape found.
|
||||
cpBool cpSpaceShapeQuery(cpSpace *space, cpShape *shape, cpSpaceShapeQueryFunc func, void *data);
|
||||
CP_EXPORT cpBool cpSpaceShapeQuery(cpSpace *space, cpShape *shape, cpSpaceShapeQueryFunc func, void *data);
|
||||
|
||||
/// Call cpBodyActivate() for any shape that is overlaps the given shape.
|
||||
void cpSpaceActivateShapesTouchingShape(cpSpace *space, cpShape *shape);
|
||||
|
||||
//MARK: Iteration
|
||||
|
||||
/// Space/body iterator callback function type.
|
||||
typedef void (*cpSpaceBodyIteratorFunc)(cpBody *body, void *data);
|
||||
/// Call @c func for each body in the space.
|
||||
void cpSpaceEachBody(cpSpace *space, cpSpaceBodyIteratorFunc func, void *data);
|
||||
CP_EXPORT void cpSpaceEachBody(cpSpace *space, cpSpaceBodyIteratorFunc func, void *data);
|
||||
|
||||
/// Space/body iterator callback function type.
|
||||
typedef void (*cpSpaceShapeIteratorFunc)(cpShape *shape, void *data);
|
||||
/// Call @c func for each shape in the space.
|
||||
void cpSpaceEachShape(cpSpace *space, cpSpaceShapeIteratorFunc func, void *data);
|
||||
CP_EXPORT void cpSpaceEachShape(cpSpace *space, cpSpaceShapeIteratorFunc func, void *data);
|
||||
|
||||
/// Space/constraint iterator callback function type.
|
||||
typedef void (*cpSpaceConstraintIteratorFunc)(cpConstraint *constraint, void *data);
|
||||
/// Call @c func for each shape in the space.
|
||||
void cpSpaceEachConstraint(cpSpace *space, cpSpaceConstraintIteratorFunc func, void *data);
|
||||
CP_EXPORT void cpSpaceEachConstraint(cpSpace *space, cpSpaceConstraintIteratorFunc func, void *data);
|
||||
|
||||
|
||||
//MARK: Indexing
|
||||
|
||||
/// Update the collision detection info for the static shapes in the space.
|
||||
void cpSpaceReindexStatic(cpSpace *space);
|
||||
CP_EXPORT void cpSpaceReindexStatic(cpSpace *space);
|
||||
/// Update the collision detection data for a specific shape in the space.
|
||||
void cpSpaceReindexShape(cpSpace *space, cpShape *shape);
|
||||
CP_EXPORT void cpSpaceReindexShape(cpSpace *space, cpShape *shape);
|
||||
/// Update the collision detection data for all shapes attached to a body.
|
||||
void cpSpaceReindexShapesForBody(cpSpace *space, cpBody *body);
|
||||
CP_EXPORT void cpSpaceReindexShapesForBody(cpSpace *space, cpBody *body);
|
||||
|
||||
/// Switch the space to use a spatial has as it's spatial index.
|
||||
void cpSpaceUseSpatialHash(cpSpace *space, cpFloat dim, int count);
|
||||
CP_EXPORT void cpSpaceUseSpatialHash(cpSpace *space, cpFloat dim, int count);
|
||||
|
||||
|
||||
//MARK: Time Stepping
|
||||
|
||||
/// Step the space forward in time by @c dt.
|
||||
void cpSpaceStep(cpSpace *space, cpFloat dt);
|
||||
CP_EXPORT void cpSpaceStep(cpSpace *space, cpFloat dt);
|
||||
|
||||
|
||||
//MARK: Debug API
|
||||
|
||||
#ifndef CP_SPACE_DISABLE_DEBUG_API
|
||||
|
||||
/// Color type to use with the space debug drawing API.
|
||||
typedef struct cpSpaceDebugColor {
|
||||
float r, g, b, a;
|
||||
} cpSpaceDebugColor;
|
||||
|
||||
/// Callback type for a function that draws a filled, stroked circle.
|
||||
typedef void (*cpSpaceDebugDrawCircleImpl)(cpVect pos, cpFloat angle, cpFloat radius, cpSpaceDebugColor outlineColor, cpSpaceDebugColor fillColor, cpDataPointer data);
|
||||
/// Callback type for a function that draws a line segment.
|
||||
typedef void (*cpSpaceDebugDrawSegmentImpl)(cpVect a, cpVect b, cpSpaceDebugColor color, cpDataPointer data);
|
||||
/// Callback type for a function that draws a thick line segment.
|
||||
typedef void (*cpSpaceDebugDrawFatSegmentImpl)(cpVect a, cpVect b, cpFloat radius, cpSpaceDebugColor outlineColor, cpSpaceDebugColor fillColor, cpDataPointer data);
|
||||
/// Callback type for a function that draws a convex polygon.
|
||||
typedef void (*cpSpaceDebugDrawPolygonImpl)(int count, const cpVect *verts, cpFloat radius, cpSpaceDebugColor outlineColor, cpSpaceDebugColor fillColor, cpDataPointer data);
|
||||
/// Callback type for a function that draws a dot.
|
||||
typedef void (*cpSpaceDebugDrawDotImpl)(cpFloat size, cpVect pos, cpSpaceDebugColor color, cpDataPointer data);
|
||||
/// Callback type for a function that returns a color for a given shape. This gives you an opportunity to color shapes based on how they are used in your engine.
|
||||
typedef cpSpaceDebugColor (*cpSpaceDebugDrawColorForShapeImpl)(cpShape *shape, cpDataPointer data);
|
||||
|
||||
typedef enum cpSpaceDebugDrawFlags {
|
||||
CP_SPACE_DEBUG_DRAW_SHAPES = 1<<0,
|
||||
CP_SPACE_DEBUG_DRAW_CONSTRAINTS = 1<<1,
|
||||
CP_SPACE_DEBUG_DRAW_COLLISION_POINTS = 1<<2,
|
||||
} cpSpaceDebugDrawFlags;
|
||||
|
||||
/// Struct used with cpSpaceDebugDraw() containing drawing callbacks and other drawing settings.
|
||||
typedef struct cpSpaceDebugDrawOptions {
|
||||
/// Function that will be invoked to draw circles.
|
||||
cpSpaceDebugDrawCircleImpl drawCircle;
|
||||
/// Function that will be invoked to draw line segments.
|
||||
cpSpaceDebugDrawSegmentImpl drawSegment;
|
||||
/// Function that will be invoked to draw thick line segments.
|
||||
cpSpaceDebugDrawFatSegmentImpl drawFatSegment;
|
||||
/// Function that will be invoked to draw convex polygons.
|
||||
cpSpaceDebugDrawPolygonImpl drawPolygon;
|
||||
/// Function that will be invoked to draw dots.
|
||||
cpSpaceDebugDrawDotImpl drawDot;
|
||||
|
||||
/// Flags that request which things to draw (collision shapes, constraints, contact points).
|
||||
cpSpaceDebugDrawFlags flags;
|
||||
/// Outline color passed to the drawing function.
|
||||
cpSpaceDebugColor shapeOutlineColor;
|
||||
/// Function that decides what fill color to draw shapes using.
|
||||
cpSpaceDebugDrawColorForShapeImpl colorForShape;
|
||||
/// Color passed to drawing functions for constraints.
|
||||
cpSpaceDebugColor constraintColor;
|
||||
/// Color passed to drawing functions for collision points.
|
||||
cpSpaceDebugColor collisionPointColor;
|
||||
|
||||
/// User defined context pointer passed to all of the callback functions as the 'data' argument.
|
||||
cpDataPointer data;
|
||||
} cpSpaceDebugDrawOptions;
|
||||
|
||||
/// Debug draw the current state of the space using the supplied drawing options.
|
||||
CP_EXPORT void cpSpaceDebugDraw(cpSpace *space, cpSpaceDebugDrawOptions *options);
|
||||
|
||||
#endif
|
||||
|
||||
/// @}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2010 Scott Lembcke
|
||||
/* Copyright (c) 2013 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
|
||||
|
|
@ -69,48 +69,48 @@ struct cpSpatialIndex {
|
|||
typedef struct cpSpaceHash cpSpaceHash;
|
||||
|
||||
/// Allocate a spatial hash.
|
||||
cpSpaceHash* cpSpaceHashAlloc(void);
|
||||
CP_EXPORT cpSpaceHash* cpSpaceHashAlloc(void);
|
||||
/// Initialize a spatial hash.
|
||||
cpSpatialIndex* cpSpaceHashInit(cpSpaceHash *hash, cpFloat celldim, int numcells, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
CP_EXPORT cpSpatialIndex* cpSpaceHashInit(cpSpaceHash *hash, cpFloat celldim, int numcells, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
/// Allocate and initialize a spatial hash.
|
||||
cpSpatialIndex* cpSpaceHashNew(cpFloat celldim, int cells, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
CP_EXPORT cpSpatialIndex* cpSpaceHashNew(cpFloat celldim, int cells, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
|
||||
/// Change the cell dimensions and table size of the spatial hash to tune it.
|
||||
/// The cell dimensions should roughly match the average size of your objects
|
||||
/// and the table size should be ~10 larger than the number of objects inserted.
|
||||
/// Some trial and error is required to find the optimum numbers for efficiency.
|
||||
void cpSpaceHashResize(cpSpaceHash *hash, cpFloat celldim, int numcells);
|
||||
CP_EXPORT void cpSpaceHashResize(cpSpaceHash *hash, cpFloat celldim, int numcells);
|
||||
|
||||
//MARK: AABB Tree
|
||||
|
||||
typedef struct cpBBTree cpBBTree;
|
||||
|
||||
/// Allocate a bounding box tree.
|
||||
cpBBTree* cpBBTreeAlloc(void);
|
||||
CP_EXPORT cpBBTree* cpBBTreeAlloc(void);
|
||||
/// Initialize a bounding box tree.
|
||||
cpSpatialIndex* cpBBTreeInit(cpBBTree *tree, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
CP_EXPORT cpSpatialIndex* cpBBTreeInit(cpBBTree *tree, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
/// Allocate and initialize a bounding box tree.
|
||||
cpSpatialIndex* cpBBTreeNew(cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
CP_EXPORT cpSpatialIndex* cpBBTreeNew(cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
|
||||
/// Perform a static top down optimization of the tree.
|
||||
void cpBBTreeOptimize(cpSpatialIndex *index);
|
||||
CP_EXPORT void cpBBTreeOptimize(cpSpatialIndex *index);
|
||||
|
||||
/// Bounding box tree velocity callback function.
|
||||
/// This function should return an estimate for the object's velocity.
|
||||
typedef cpVect (*cpBBTreeVelocityFunc)(void *obj);
|
||||
/// Set the velocity function for the bounding box tree to enable temporal coherence.
|
||||
void cpBBTreeSetVelocityFunc(cpSpatialIndex *index, cpBBTreeVelocityFunc func);
|
||||
CP_EXPORT void cpBBTreeSetVelocityFunc(cpSpatialIndex *index, cpBBTreeVelocityFunc func);
|
||||
|
||||
//MARK: Single Axis Sweep
|
||||
|
||||
typedef struct cpSweep1D cpSweep1D;
|
||||
|
||||
/// Allocate a 1D sort and sweep broadphase.
|
||||
cpSweep1D* cpSweep1DAlloc(void);
|
||||
CP_EXPORT cpSweep1D* cpSweep1DAlloc(void);
|
||||
/// Initialize a 1D sort and sweep broadphase.
|
||||
cpSpatialIndex* cpSweep1DInit(cpSweep1D *sweep, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
CP_EXPORT cpSpatialIndex* cpSweep1DInit(cpSweep1D *sweep, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
/// Allocate and initialize a 1D sort and sweep broadphase.
|
||||
cpSpatialIndex* cpSweep1DNew(cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
CP_EXPORT cpSpatialIndex* cpSweep1DNew(cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
|
||||
//MARK: Spatial Index Implementation
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2007 Scott Lembcke
|
||||
/* Copyright (c) 2013 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
|
||||
|
|
@ -19,6 +19,11 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef CHIPMUNK_VECT_H
|
||||
#define CHIPMUNK_VECT_H
|
||||
|
||||
#include "chipmunk_types.h"
|
||||
|
||||
/// @defgroup cpVect cpVect
|
||||
/// Chipmunk's 2D vector type along with a handy 2D vector math lib.
|
||||
/// @{
|
||||
|
|
@ -33,17 +38,6 @@ static inline cpVect cpv(const cpFloat x, const cpFloat y)
|
|||
return v;
|
||||
}
|
||||
|
||||
/// Spherical linearly interpolate between v1 and v2.
|
||||
cpVect cpvslerp(const cpVect v1, const cpVect v2, const cpFloat t);
|
||||
|
||||
/// Spherical linearly interpolate between v1 towards v2 by no more than angle a radians
|
||||
cpVect cpvslerpconst(const cpVect v1, const cpVect v2, const cpFloat a);
|
||||
|
||||
/// Returns a string representation of v. Intended mostly for debugging purposes and not production use.
|
||||
/// @attention The string points to a static local and is reset every time the function is called.
|
||||
/// If you want to print more than one vector you will have to split up your printing onto separate lines.
|
||||
char* cpvstr(const cpVect v);
|
||||
|
||||
/// Check if two vectors are equal. (Be careful when comparing floating point numbers!)
|
||||
static inline cpBool cpveql(const cpVect v1, const cpVect v2)
|
||||
{
|
||||
|
|
@ -155,10 +149,30 @@ static inline cpVect cpvnormalize(const cpVect v)
|
|||
return cpvmult(v, 1.0f/(cpvlength(v) + CPFLOAT_MIN));
|
||||
}
|
||||
|
||||
/// @deprecated Just an alias for cpvnormalize() now.
|
||||
static inline cpVect cpvnormalize_safe(const cpVect v)
|
||||
/// Spherical linearly interpolate between v1 and v2.
|
||||
static inline cpVect
|
||||
cpvslerp(const cpVect v1, const cpVect v2, const cpFloat t)
|
||||
{
|
||||
return cpvnormalize(v);
|
||||
cpFloat dot = cpvdot(cpvnormalize(v1), cpvnormalize(v2));
|
||||
cpFloat omega = cpfacos(cpfclamp(dot, -1.0f, 1.0f));
|
||||
|
||||
if(omega < 1e-3){
|
||||
// If the angle between two vectors is very small, lerp instead to avoid precision issues.
|
||||
return cpvlerp(v1, v2, t);
|
||||
} else {
|
||||
cpFloat denom = 1.0f/cpfsin(omega);
|
||||
return cpvadd(cpvmult(v1, cpfsin((1.0f - t)*omega)*denom), cpvmult(v2, cpfsin(t*omega)*denom));
|
||||
}
|
||||
}
|
||||
|
||||
/// Spherical linearly interpolate between v1 towards v2 by no more than angle a radians
|
||||
static inline cpVect
|
||||
cpvslerpconst(const cpVect v1, const cpVect v2, const cpFloat a)
|
||||
{
|
||||
cpFloat dot = cpvdot(cpvnormalize(v1), cpvnormalize(v2));
|
||||
cpFloat omega = cpfacos(cpfclamp(dot, -1.0f, 1.0f));
|
||||
|
||||
return cpvslerp(v1, v2, cpfmin(a, omega)/omega);
|
||||
}
|
||||
|
||||
/// Clamp v to length len.
|
||||
|
|
@ -197,6 +211,7 @@ static inline cpBool cpvnear(const cpVect v1, const cpVect v2, const cpFloat dis
|
|||
/// 2x2 matrix type used for tensors and such.
|
||||
/// @{
|
||||
|
||||
// NUKE
|
||||
static inline cpMat2x2
|
||||
cpMat2x2New(cpFloat a, cpFloat b, cpFloat c, cpFloat d)
|
||||
{
|
||||
|
|
@ -211,3 +226,5 @@ cpMat2x2Transform(cpMat2x2 m, cpVect v)
|
|||
}
|
||||
|
||||
///@}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2007 Scott Lembcke
|
||||
/* Copyright (c) 2013 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
|
||||
|
|
@ -19,20 +19,26 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef CHIPMUNK_HEADER
|
||||
#define CHIPMUNK_HEADER
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define _USE_MATH_DEFINES
|
||||
#endif
|
||||
#ifndef CHIPMUNK_H
|
||||
#define CHIPMUNK_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#ifdef WIN32
|
||||
// For alloca().
|
||||
#include <malloc.h>
|
||||
#define CP_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#include <alloca.h>
|
||||
#define CP_EXPORT
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// NUKE
|
||||
#ifndef CP_ALLOW_PRIVATE_ACCESS
|
||||
#define CP_ALLOW_PRIVATE_ACCESS 0
|
||||
#endif
|
||||
|
|
@ -43,22 +49,17 @@ extern "C" {
|
|||
#define CP_PRIVATE(__symbol__) __symbol__##_private
|
||||
#endif
|
||||
|
||||
void cpMessage(const char *condition, const char *file, int line, int isError, int isHardError, const char *message, ...);
|
||||
CP_EXPORT void cpMessage(const char *condition, const char *file, int line, int isError, int isHardError, const char *message, ...);
|
||||
#ifdef NDEBUG
|
||||
#define cpAssertWarn(__condition__, ...)
|
||||
#define cpAssertSoft(__condition__, ...)
|
||||
#else
|
||||
#define cpAssertSoft(__condition__, ...) if(!(__condition__)){cpMessage(#__condition__, __FILE__, __LINE__, 1, 0, __VA_ARGS__); abort();}
|
||||
#define cpAssertWarn(__condition__, ...) if(!(__condition__)) cpMessage(#__condition__, __FILE__, __LINE__, 0, 0, __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define cpAssertSoft(__condition__, ...)
|
||||
#else
|
||||
#define cpAssertSoft(__condition__, ...) if(!(__condition__)) cpMessage(#__condition__, __FILE__, __LINE__, 1, 0, __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
// Hard assertions are important and cheap to execute. They are not disabled by compiling as debug.
|
||||
#define cpAssertHard(__condition__, ...) if(!(__condition__)) cpMessage(#__condition__, __FILE__, __LINE__, 1, 1, __VA_ARGS__)
|
||||
|
||||
// Hard assertions are used in situations where the program definitely will crash anyway, and the reason is inexpensive to detect.
|
||||
#define cpAssertHard(__condition__, ...) if(!(__condition__)){cpMessage(#__condition__, __FILE__, __LINE__, 1, 1, __VA_ARGS__); abort();}
|
||||
|
||||
#include "chipmunk_types.h"
|
||||
|
||||
|
|
@ -89,81 +90,90 @@ typedef struct cpArray cpArray;
|
|||
typedef struct cpHashSet cpHashSet;
|
||||
|
||||
typedef struct cpBody cpBody;
|
||||
|
||||
typedef struct cpShape cpShape;
|
||||
typedef struct cpCircleShape cpCircleShape;
|
||||
typedef struct cpSegmentShape cpSegmentShape;
|
||||
typedef struct cpPolyShape cpPolyShape;
|
||||
|
||||
typedef struct cpConstraint cpConstraint;
|
||||
typedef struct cpPinJoint cpPinJoint;
|
||||
typedef struct cpSlideJoint cpSlideJoint;
|
||||
typedef struct cpPivotJoint cpPivotJoint;
|
||||
typedef struct cpGrooveJoint cpGrooveJoint;
|
||||
typedef struct cpDampedSpring cpDampedSpring;
|
||||
typedef struct cpDampedRotarySpring cpDampedRotarySpring;
|
||||
typedef struct cpRotaryLimitJoint cpRotaryLimitJoint;
|
||||
typedef struct cpRatchetJoint cpRatchetJoint;
|
||||
typedef struct cpGearJoint cpGearJoint;
|
||||
typedef struct cpSimpleMotorJoint cpSimpleMotorJoint;
|
||||
|
||||
typedef struct cpCollisionHandler cpCollisionHandler;
|
||||
typedef struct cpContactPointSet cpContactPointSet;
|
||||
typedef struct cpArbiter cpArbiter;
|
||||
|
||||
typedef struct cpSpace cpSpace;
|
||||
|
||||
#include "cpVect.h"
|
||||
#include "cpBB.h"
|
||||
#include "cpTransform.h"
|
||||
#include "cpSpatialIndex.h"
|
||||
|
||||
#include "cpArbiter.h"
|
||||
|
||||
#include "cpBody.h"
|
||||
#include "cpShape.h"
|
||||
#include "cpPolyShape.h"
|
||||
|
||||
#include "cpArbiter.h"
|
||||
#include "constraints/cpConstraint.h"
|
||||
#include "cpConstraint.h"
|
||||
|
||||
#include "cpSpace.h"
|
||||
#include "cpHastySpace.h"
|
||||
|
||||
// Chipmunk 6.2.1
|
||||
#define CP_VERSION_MAJOR 6
|
||||
#define CP_VERSION_MINOR 2
|
||||
// Chipmunk 7.0.1
|
||||
#define CP_VERSION_MAJOR 7
|
||||
#define CP_VERSION_MINOR 0
|
||||
#define CP_VERSION_RELEASE 1
|
||||
|
||||
/// Version string.
|
||||
extern const char *cpVersionString;
|
||||
|
||||
/// @deprecated
|
||||
void cpInitChipmunk(void);
|
||||
|
||||
/// Enables segment to segment shape collisions.
|
||||
void cpEnableSegmentToSegmentCollisions(void);
|
||||
|
||||
CP_EXPORT extern const char *cpVersionString;
|
||||
|
||||
/// Calculate the moment of inertia for a circle.
|
||||
/// @c r1 and @c r2 are the inner and outer diameters. A solid circle has an inner diameter of 0.
|
||||
cpFloat cpMomentForCircle(cpFloat m, cpFloat r1, cpFloat r2, cpVect offset);
|
||||
CP_EXPORT cpFloat cpMomentForCircle(cpFloat m, cpFloat r1, cpFloat r2, cpVect offset);
|
||||
|
||||
/// Calculate area of a hollow circle.
|
||||
/// @c r1 and @c r2 are the inner and outer diameters. A solid circle has an inner diameter of 0.
|
||||
cpFloat cpAreaForCircle(cpFloat r1, cpFloat r2);
|
||||
CP_EXPORT cpFloat cpAreaForCircle(cpFloat r1, cpFloat r2);
|
||||
|
||||
/// Calculate the moment of inertia for a line segment.
|
||||
/// Beveling radius is not supported.
|
||||
cpFloat cpMomentForSegment(cpFloat m, cpVect a, cpVect b);
|
||||
CP_EXPORT cpFloat cpMomentForSegment(cpFloat m, cpVect a, cpVect b, cpFloat radius);
|
||||
|
||||
/// Calculate the area of a fattened (capsule shaped) line segment.
|
||||
cpFloat cpAreaForSegment(cpVect a, cpVect b, cpFloat r);
|
||||
CP_EXPORT cpFloat cpAreaForSegment(cpVect a, cpVect b, cpFloat radius);
|
||||
|
||||
/// Calculate the moment of inertia for a solid polygon shape assuming it's center of gravity is at it's centroid. The offset is added to each vertex.
|
||||
cpFloat cpMomentForPoly(cpFloat m, int numVerts, const cpVect *verts, cpVect offset);
|
||||
CP_EXPORT cpFloat cpMomentForPoly(cpFloat m, int count, const cpVect *verts, cpVect offset, cpFloat radius);
|
||||
|
||||
/// Calculate the signed area of a polygon. A Clockwise winding gives positive area.
|
||||
/// This is probably backwards from what you expect, but matches Chipmunk's the winding for poly shapes.
|
||||
cpFloat cpAreaForPoly(const int numVerts, const cpVect *verts);
|
||||
CP_EXPORT cpFloat cpAreaForPoly(const int count, const cpVect *verts, cpFloat radius);
|
||||
|
||||
/// Calculate the natural centroid of a polygon.
|
||||
cpVect cpCentroidForPoly(const int numVerts, const cpVect *verts);
|
||||
|
||||
/// Center the polygon on the origin. (Subtracts the centroid of the polygon from each vertex)
|
||||
void cpRecenterPoly(const int numVerts, cpVect *verts);
|
||||
CP_EXPORT cpVect cpCentroidForPoly(const int count, const cpVect *verts);
|
||||
|
||||
/// Calculate the moment of inertia for a solid box.
|
||||
cpFloat cpMomentForBox(cpFloat m, cpFloat width, cpFloat height);
|
||||
CP_EXPORT cpFloat cpMomentForBox(cpFloat m, cpFloat width, cpFloat height);
|
||||
|
||||
/// Calculate the moment of inertia for a solid box.
|
||||
cpFloat cpMomentForBox2(cpFloat m, cpBB box);
|
||||
CP_EXPORT cpFloat cpMomentForBox2(cpFloat m, cpBB box);
|
||||
|
||||
/// Calculate the convex hull of a given set of points. Returns the count of points in the hull.
|
||||
/// @c result must be a pointer to a @c cpVect array with at least @c count elements. If @c result is @c NULL, then @c verts will be reduced instead.
|
||||
/// @c result must be a pointer to a @c cpVect array with at least @c count elements. If @c verts == @c result, then @c verts will be reduced inplace.
|
||||
/// @c first is an optional pointer to an integer to store where the first vertex in the hull came from (i.e. verts[first] == result[0])
|
||||
/// @c tol is the allowed amount to shrink the hull when simplifying it. A tolerance of 0.0 creates an exact hull.
|
||||
int cpConvexHull(int count, cpVect *verts, cpVect *result, int *first, cpFloat tol);
|
||||
CP_EXPORT int cpConvexHull(int count, const cpVect *verts, cpVect *result, int *first, cpFloat tol);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include "malloc.h"
|
||||
|
|
@ -177,6 +187,15 @@ int cpConvexHull(int count, cpVect *verts, cpVect *result, int *first, cpFloat t
|
|||
cpVect *__verts_var__ = (cpVect *)alloca(__count__*sizeof(cpVect)); \
|
||||
int __count_var__ = cpConvexHull(__count__, __verts__, __verts_var__, NULL, 0.0); \
|
||||
|
||||
/// Returns the closest point on the line segment ab, to the point p.
|
||||
static inline cpVect
|
||||
cpClosetPointOnSegment(const cpVect p, const cpVect a, const cpVect b)
|
||||
{
|
||||
cpVect delta = cpvsub(a, b);
|
||||
cpFloat t = cpfclamp01(cpvdot(delta, cpvsub(p, b))/cpvlengthsq(delta));
|
||||
return cpvadd(b, cpvmult(delta, t));
|
||||
}
|
||||
|
||||
#if defined(__has_extension)
|
||||
#if __has_extension(blocks)
|
||||
// Define alternate block based alternatives for a few of the callback heavy functions.
|
||||
|
|
@ -191,14 +210,14 @@ void cpBodyEachShape_b(cpBody *body, void (^block)(cpShape *shape));
|
|||
void cpBodyEachConstraint_b(cpBody *body, void (^block)(cpConstraint *constraint));
|
||||
void cpBodyEachArbiter_b(cpBody *body, void (^block)(cpArbiter *arbiter));
|
||||
|
||||
typedef void (^cpSpaceNearestPointQueryBlock)(cpShape *shape, cpFloat distance, cpVect point);
|
||||
void cpSpaceNearestPointQuery_b(cpSpace *space, cpVect point, cpFloat maxDistance, cpLayers layers, cpGroup group, cpSpaceNearestPointQueryBlock block);
|
||||
typedef void (^cpSpacePointQueryBlock)(cpShape *shape, cpVect point, cpFloat distance, cpVect gradient);
|
||||
void cpSpacePointQuery_b(cpSpace *space, cpVect point, cpFloat maxDistance, cpShapeFilter filter, cpSpacePointQueryBlock block);
|
||||
|
||||
typedef void (^cpSpaceSegmentQueryBlock)(cpShape *shape, cpFloat t, cpVect n);
|
||||
void cpSpaceSegmentQuery_b(cpSpace *space, cpVect start, cpVect end, cpLayers layers, cpGroup group, cpSpaceSegmentQueryBlock block);
|
||||
typedef void (^cpSpaceSegmentQueryBlock)(cpShape *shape, cpVect point, cpVect normal, cpFloat alpha);
|
||||
void cpSpaceSegmentQuery_b(cpSpace *space, cpVect start, cpVect end, cpFloat radius, cpShapeFilter filter, cpSpaceSegmentQueryBlock block);
|
||||
|
||||
typedef void (^cpSpaceBBQueryBlock)(cpShape *shape);
|
||||
void cpSpaceBBQuery_b(cpSpace *space, cpBB bb, cpLayers layers, cpGroup group, cpSpaceBBQueryBlock block);
|
||||
void cpSpaceBBQuery_b(cpSpace *space, cpBB bb, cpShapeFilter filter, cpSpaceBBQueryBlock block);
|
||||
|
||||
typedef void (^cpSpaceShapeQueryBlock)(cpShape *shape, cpContactPointSet *points);
|
||||
cpBool cpSpaceShapeQuery_b(cpSpace *space, cpShape *shape, cpSpaceShapeQueryBlock block);
|
||||
|
|
|
|||
|
|
@ -1,222 +0,0 @@
|
|||
/* 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.
|
||||
*/
|
||||
|
||||
#ifndef CHIPMUNK_HEADER
|
||||
#define CHIPMUNK_HEADER
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define _USE_MATH_DEFINES
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef CP_ALLOW_PRIVATE_ACCESS
|
||||
#define CP_ALLOW_PRIVATE_ACCESS 0
|
||||
#endif
|
||||
|
||||
#if CP_ALLOW_PRIVATE_ACCESS == 1
|
||||
#define CP_PRIVATE(__symbol__) __symbol__
|
||||
#else
|
||||
#define CP_PRIVATE(__symbol__) __symbol__##_private
|
||||
#endif
|
||||
|
||||
void cpMessage(const char *condition, const char *file, int line, int isError, int isHardError, const char *message, ...);
|
||||
#ifdef NDEBUG
|
||||
#define cpAssertWarn(__condition__, ...)
|
||||
#else
|
||||
#define cpAssertWarn(__condition__, ...) if(!(__condition__)) cpMessage(#__condition__, __FILE__, __LINE__, 0, 0, __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define cpAssertSoft(__condition__, ...)
|
||||
#else
|
||||
#define cpAssertSoft(__condition__, ...) if(!(__condition__)) cpMessage(#__condition__, __FILE__, __LINE__, 1, 0, __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
// Hard assertions are important and cheap to execute. They are not disabled by compiling as debug.
|
||||
#define cpAssertHard(__condition__, ...) if(!(__condition__)) cpMessage(#__condition__, __FILE__, __LINE__, 1, 1, __VA_ARGS__)
|
||||
|
||||
|
||||
#include "chipmunk_types.h"
|
||||
|
||||
/// @defgroup misc Misc
|
||||
/// @{
|
||||
|
||||
/// Allocated size for various Chipmunk buffers
|
||||
#ifndef CP_BUFFER_BYTES
|
||||
#define CP_BUFFER_BYTES (32*1024)
|
||||
#endif
|
||||
|
||||
#ifndef cpcalloc
|
||||
/// Chipmunk calloc() alias.
|
||||
#define cpcalloc calloc
|
||||
#endif
|
||||
|
||||
#ifndef cprealloc
|
||||
/// Chipmunk realloc() alias.
|
||||
#define cprealloc realloc
|
||||
#endif
|
||||
|
||||
#ifndef cpfree
|
||||
/// Chipmunk free() alias.
|
||||
#define cpfree free
|
||||
#endif
|
||||
|
||||
typedef struct cpArray cpArray;
|
||||
typedef struct cpHashSet cpHashSet;
|
||||
|
||||
typedef struct cpBody cpBody;
|
||||
typedef struct cpShape cpShape;
|
||||
typedef struct cpConstraint cpConstraint;
|
||||
|
||||
typedef struct cpCollisionHandler cpCollisionHandler;
|
||||
typedef struct cpArbiter cpArbiter;
|
||||
|
||||
typedef struct cpSpace cpSpace;
|
||||
|
||||
#include "cpVect.h"
|
||||
#include "cpBB.h"
|
||||
#include "cpSpatialIndex.h"
|
||||
|
||||
#include "cpBody.h"
|
||||
#include "cpShape.h"
|
||||
#include "cpPolyShape.h"
|
||||
|
||||
#include "cpArbiter.h"
|
||||
#include "constraints/cpConstraint.h"
|
||||
|
||||
#include "cpSpace.h"
|
||||
|
||||
// Chipmunk 6.2.1
|
||||
#define CP_VERSION_MAJOR 6
|
||||
#define CP_VERSION_MINOR 2
|
||||
#define CP_VERSION_RELEASE 1
|
||||
|
||||
/// Version string.
|
||||
extern const char *cpVersionString;
|
||||
|
||||
/// @deprecated
|
||||
void cpInitChipmunk(void);
|
||||
|
||||
/// Enables segment to segment shape collisions.
|
||||
void cpEnableSegmentToSegmentCollisions(void);
|
||||
|
||||
|
||||
/// Calculate the moment of inertia for a circle.
|
||||
/// @c r1 and @c r2 are the inner and outer diameters. A solid circle has an inner diameter of 0.
|
||||
cpFloat cpMomentForCircle(cpFloat m, cpFloat r1, cpFloat r2, cpVect offset);
|
||||
|
||||
/// Calculate area of a hollow circle.
|
||||
/// @c r1 and @c r2 are the inner and outer diameters. A solid circle has an inner diameter of 0.
|
||||
cpFloat cpAreaForCircle(cpFloat r1, cpFloat r2);
|
||||
|
||||
/// Calculate the moment of inertia for a line segment.
|
||||
/// Beveling radius is not supported.
|
||||
cpFloat cpMomentForSegment(cpFloat m, cpVect a, cpVect b);
|
||||
|
||||
/// Calculate the area of a fattened (capsule shaped) line segment.
|
||||
cpFloat cpAreaForSegment(cpVect a, cpVect b, cpFloat r);
|
||||
|
||||
/// Calculate the moment of inertia for a solid polygon shape assuming it's center of gravity is at it's centroid. The offset is added to each vertex.
|
||||
cpFloat cpMomentForPoly(cpFloat m, int numVerts, const cpVect *verts, cpVect offset);
|
||||
|
||||
/// Calculate the signed area of a polygon. A Clockwise winding gives positive area.
|
||||
/// This is probably backwards from what you expect, but matches Chipmunk's the winding for poly shapes.
|
||||
cpFloat cpAreaForPoly(const int numVerts, const cpVect *verts);
|
||||
|
||||
/// Calculate the natural centroid of a polygon.
|
||||
cpVect cpCentroidForPoly(const int numVerts, const cpVect *verts);
|
||||
|
||||
/// Center the polygon on the origin. (Subtracts the centroid of the polygon from each vertex)
|
||||
void cpRecenterPoly(const int numVerts, cpVect *verts);
|
||||
|
||||
/// Calculate the moment of inertia for a solid box.
|
||||
cpFloat cpMomentForBox(cpFloat m, cpFloat width, cpFloat height);
|
||||
|
||||
/// Calculate the moment of inertia for a solid box.
|
||||
cpFloat cpMomentForBox2(cpFloat m, cpBB box);
|
||||
|
||||
/// Calculate the convex hull of a given set of points. Returns the count of points in the hull.
|
||||
/// @c result must be a pointer to a @c cpVect array with at least @c count elements. If @c result is @c NULL, then @c verts will be reduced instead.
|
||||
/// @c first is an optional pointer to an integer to store where the first vertex in the hull came from (i.e. verts[first] == result[0])
|
||||
/// @c tol is the allowed amount to shrink the hull when simplifying it. A tolerance of 0.0 creates an exact hull.
|
||||
int cpConvexHull(int count, cpVect *verts, cpVect *result, int *first, cpFloat tol);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include "malloc.h"
|
||||
#endif
|
||||
|
||||
/// Convenience macro to work with cpConvexHull.
|
||||
/// @c count and @c verts is the input array passed to cpConvexHull().
|
||||
/// @c count_var and @c verts_var are the names of the variables the macro creates to store the result.
|
||||
/// The output vertex array is allocated on the stack using alloca() so it will be freed automatically, but cannot be returned from the current scope.
|
||||
#define CP_CONVEX_HULL(__count__, __verts__, __count_var__, __verts_var__) \
|
||||
cpVect *__verts_var__ = (cpVect *)alloca(__count__*sizeof(cpVect)); \
|
||||
int __count_var__ = cpConvexHull(__count__, __verts__, __verts_var__, NULL, 0.0); \
|
||||
|
||||
#if defined(__has_extension)
|
||||
#if __has_extension(blocks)
|
||||
// Define alternate block based alternatives for a few of the callback heavy functions.
|
||||
// Collision handlers are post-step callbacks are not included to avoid memory management issues.
|
||||
// If you want to use blocks for those and are aware of how to correctly manage the memory, the implementation is trivial.
|
||||
|
||||
void cpSpaceEachBody_b(cpSpace *space, void (^block)(cpBody *body));
|
||||
void cpSpaceEachShape_b(cpSpace *space, void (^block)(cpShape *shape));
|
||||
void cpSpaceEachConstraint_b(cpSpace *space, void (^block)(cpConstraint *constraint));
|
||||
|
||||
void cpBodyEachShape_b(cpBody *body, void (^block)(cpShape *shape));
|
||||
void cpBodyEachConstraint_b(cpBody *body, void (^block)(cpConstraint *constraint));
|
||||
void cpBodyEachArbiter_b(cpBody *body, void (^block)(cpArbiter *arbiter));
|
||||
|
||||
typedef void (^cpSpaceNearestPointQueryBlock)(cpShape *shape, cpFloat distance, cpVect point);
|
||||
void cpSpaceNearestPointQuery_b(cpSpace *space, cpVect point, cpFloat maxDistance, cpLayers layers, cpGroup group, cpSpaceNearestPointQueryBlock block);
|
||||
|
||||
typedef void (^cpSpaceSegmentQueryBlock)(cpShape *shape, cpFloat t, cpVect n);
|
||||
void cpSpaceSegmentQuery_b(cpSpace *space, cpVect start, cpVect end, cpLayers layers, cpGroup group, cpSpaceSegmentQueryBlock block);
|
||||
|
||||
typedef void (^cpSpaceBBQueryBlock)(cpShape *shape);
|
||||
void cpSpaceBBQuery_b(cpSpace *space, cpBB bb, cpLayers layers, cpGroup group, cpSpaceBBQueryBlock block);
|
||||
|
||||
typedef void (^cpSpaceShapeQueryBlock)(cpShape *shape, cpContactPointSet *points);
|
||||
cpBool cpSpaceShapeQuery_b(cpSpace *space, cpShape *shape, cpSpaceShapeQueryBlock block);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
//@}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
static inline cpVect operator *(const cpVect v, const cpFloat s){return cpvmult(v, s);}
|
||||
static inline cpVect operator +(const cpVect v1, const cpVect v2){return cpvadd(v1, v2);}
|
||||
static inline cpVect operator -(const cpVect v1, const cpVect v2){return cpvsub(v1, v2);}
|
||||
static inline cpBool operator ==(const cpVect v1, const cpVect v2){return cpveql(v1, v2);}
|
||||
static inline cpVect operator -(const cpVect v){return cpvneg(v);}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
@ -1,177 +0,0 @@
|
|||
#ifdef CHIPMUNK_FFI
|
||||
|
||||
// Create non static inlined copies of Chipmunk functions, useful for working with dynamic FFIs
|
||||
// This file should only be included in chipmunk.c
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if _MSC_VER >= 1600
|
||||
#define MAKE_REF(name) decltype(name) *_##name = name
|
||||
#else
|
||||
#define MAKE_REF(name)
|
||||
#endif
|
||||
#else
|
||||
#define MAKE_REF(name) __typeof__(name) *_##name = name
|
||||
#endif
|
||||
|
||||
#define MAKE_PROPERTIES_REF(struct, property) \
|
||||
MAKE_REF(struct##Get##property); MAKE_REF(struct##Set##property)
|
||||
|
||||
MAKE_REF(cpv); // makes a variable named _cpv that contains the function pointer for cpv()
|
||||
MAKE_REF(cpveql);
|
||||
MAKE_REF(cpvadd);
|
||||
MAKE_REF(cpvneg);
|
||||
MAKE_REF(cpvsub);
|
||||
MAKE_REF(cpvmult);
|
||||
MAKE_REF(cpvdot);
|
||||
MAKE_REF(cpvcross);
|
||||
MAKE_REF(cpvperp);
|
||||
MAKE_REF(cpvrperp);
|
||||
MAKE_REF(cpvproject);
|
||||
MAKE_REF(cpvforangle);
|
||||
MAKE_REF(cpvtoangle);
|
||||
MAKE_REF(cpvrotate);
|
||||
MAKE_REF(cpvunrotate);
|
||||
MAKE_REF(cpvlengthsq);
|
||||
MAKE_REF(cpvlength);
|
||||
MAKE_REF(cpvlerp);
|
||||
MAKE_REF(cpvnormalize);
|
||||
MAKE_REF(cpvnormalize_safe);
|
||||
MAKE_REF(cpvclamp);
|
||||
MAKE_REF(cpvlerpconst);
|
||||
MAKE_REF(cpvdist);
|
||||
MAKE_REF(cpvdistsq);
|
||||
MAKE_REF(cpvnear);
|
||||
|
||||
MAKE_REF(cpfmax);
|
||||
MAKE_REF(cpfmin);
|
||||
MAKE_REF(cpfabs);
|
||||
MAKE_REF(cpfclamp);
|
||||
MAKE_REF(cpflerp);
|
||||
MAKE_REF(cpflerpconst);
|
||||
|
||||
MAKE_REF(cpBBNew);
|
||||
MAKE_REF(cpBBNewForCircle);
|
||||
MAKE_REF(cpBBIntersects);
|
||||
MAKE_REF(cpBBContainsBB);
|
||||
MAKE_REF(cpBBContainsVect);
|
||||
MAKE_REF(cpBBMerge);
|
||||
MAKE_REF(cpBBExpand);
|
||||
MAKE_REF(cpBBArea);
|
||||
MAKE_REF(cpBBMergedArea);
|
||||
MAKE_REF(cpBBSegmentQuery);
|
||||
MAKE_REF(cpBBIntersectsSegment);
|
||||
MAKE_REF(cpBBClampVect);
|
||||
|
||||
MAKE_REF(cpBodyGetMass);
|
||||
MAKE_REF(cpBodyGetMoment);
|
||||
MAKE_REF(cpBodyGetPos);
|
||||
MAKE_REF(cpBodyGetAngle);
|
||||
MAKE_REF(cpBodyGetRot);
|
||||
MAKE_PROPERTIES_REF(cpBody, Vel);
|
||||
MAKE_PROPERTIES_REF(cpBody, Force);
|
||||
MAKE_PROPERTIES_REF(cpBody, AngVel);
|
||||
MAKE_PROPERTIES_REF(cpBody, Torque);
|
||||
MAKE_PROPERTIES_REF(cpBody, VelLimit);
|
||||
MAKE_PROPERTIES_REF(cpBody, AngVelLimit);
|
||||
MAKE_PROPERTIES_REF(cpBody, UserData);
|
||||
MAKE_REF(cpBodyIsSleeping);
|
||||
MAKE_REF(cpBodyIsStatic);
|
||||
MAKE_REF(cpBodyIsRogue);
|
||||
MAKE_REF(cpBodyLocal2World);
|
||||
MAKE_REF(cpBodyWorld2Local);
|
||||
MAKE_REF(cpBodyKineticEnergy);
|
||||
|
||||
MAKE_REF(cpShapeGetBB);
|
||||
MAKE_PROPERTIES_REF(cpShape, Body);
|
||||
MAKE_PROPERTIES_REF(cpShape, Sensor);
|
||||
MAKE_PROPERTIES_REF(cpShape, Elasticity);
|
||||
MAKE_PROPERTIES_REF(cpShape, Friction);
|
||||
MAKE_PROPERTIES_REF(cpShape, SurfaceVelocity);
|
||||
MAKE_PROPERTIES_REF(cpShape, UserData);
|
||||
MAKE_PROPERTIES_REF(cpShape, CollisionType);
|
||||
MAKE_PROPERTIES_REF(cpShape, Group);
|
||||
MAKE_PROPERTIES_REF(cpShape, Layers);
|
||||
|
||||
MAKE_REF(cpArbiterGetShapes);
|
||||
MAKE_REF(cpArbiterGetBodies);
|
||||
MAKE_REF(cpArbiterIsFirstContact);
|
||||
MAKE_REF(cpArbiterGetCount);
|
||||
|
||||
MAKE_REF(cpConstraintGetA);
|
||||
MAKE_REF(cpConstraintGetB);
|
||||
MAKE_PROPERTIES_REF(cpConstraint, MaxForce);
|
||||
MAKE_PROPERTIES_REF(cpConstraint, ErrorBias);
|
||||
MAKE_PROPERTIES_REF(cpConstraint, MaxBias);
|
||||
MAKE_PROPERTIES_REF(cpConstraint, UserData);
|
||||
MAKE_REF(cpConstraintGetImpulse);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpDampedRotarySpring, RestAngle);
|
||||
MAKE_PROPERTIES_REF(cpDampedRotarySpring, Stiffness);
|
||||
MAKE_PROPERTIES_REF(cpDampedRotarySpring, Damping);
|
||||
//MAKE_PROPERTIES_REF(cpDampedRotarySpring, SpringTorqueFunc);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpDampedSpring, Anchr1);
|
||||
MAKE_PROPERTIES_REF(cpDampedSpring, Anchr2);
|
||||
MAKE_PROPERTIES_REF(cpDampedSpring, RestLength);
|
||||
MAKE_PROPERTIES_REF(cpDampedSpring, Stiffness);
|
||||
MAKE_PROPERTIES_REF(cpDampedSpring, Damping);
|
||||
//MAKE_PROPERTIES_REF(cpDampedSpring, SpringForceFunc);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpGearJoint, Phase);
|
||||
MAKE_REF(cpGearJointGetRatio);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpGrooveJoint, Anchr2);
|
||||
MAKE_REF(cpGrooveJointGetGrooveA);
|
||||
MAKE_REF(cpGrooveJointGetGrooveB);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpPinJoint, Anchr1);
|
||||
MAKE_PROPERTIES_REF(cpPinJoint, Anchr2);
|
||||
MAKE_PROPERTIES_REF(cpPinJoint, Dist);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpPivotJoint, Anchr1);
|
||||
MAKE_PROPERTIES_REF(cpPivotJoint, Anchr2);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpRatchetJoint, Angle);
|
||||
MAKE_PROPERTIES_REF(cpRatchetJoint, Phase);
|
||||
MAKE_PROPERTIES_REF(cpRatchetJoint, Ratchet);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpRotaryLimitJoint, Min);
|
||||
MAKE_PROPERTIES_REF(cpRotaryLimitJoint, Max);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpSimpleMotor, Rate);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpSlideJoint, Anchr1);
|
||||
MAKE_PROPERTIES_REF(cpSlideJoint, Anchr2);
|
||||
MAKE_PROPERTIES_REF(cpSlideJoint, Min);
|
||||
MAKE_PROPERTIES_REF(cpSlideJoint, Max);
|
||||
|
||||
MAKE_REF(cpSegmentQueryHitPoint);
|
||||
MAKE_REF(cpSegmentQueryHitDist);
|
||||
|
||||
MAKE_REF(cpSpatialIndexDestroy);
|
||||
MAKE_REF(cpSpatialIndexCount);
|
||||
MAKE_REF(cpSpatialIndexEach);
|
||||
MAKE_REF(cpSpatialIndexContains);
|
||||
MAKE_REF(cpSpatialIndexInsert);
|
||||
MAKE_REF(cpSpatialIndexRemove);
|
||||
MAKE_REF(cpSpatialIndexReindex);
|
||||
MAKE_REF(cpSpatialIndexReindexObject);
|
||||
MAKE_REF(cpSpatialIndexSegmentQuery);
|
||||
MAKE_REF(cpSpatialIndexQuery);
|
||||
MAKE_REF(cpSpatialIndexReindexQuery);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpSpace, Iterations);
|
||||
MAKE_PROPERTIES_REF(cpSpace, Gravity);
|
||||
MAKE_PROPERTIES_REF(cpSpace, Damping);
|
||||
MAKE_PROPERTIES_REF(cpSpace, IdleSpeedThreshold);
|
||||
MAKE_PROPERTIES_REF(cpSpace, SleepTimeThreshold);
|
||||
MAKE_PROPERTIES_REF(cpSpace, CollisionSlop);
|
||||
MAKE_PROPERTIES_REF(cpSpace, CollisionBias);
|
||||
MAKE_PROPERTIES_REF(cpSpace, CollisionPersistence);
|
||||
MAKE_PROPERTIES_REF(cpSpace, EnableContactGraph);
|
||||
MAKE_PROPERTIES_REF(cpSpace, UserData);
|
||||
MAKE_REF(cpSpaceGetStaticBody);
|
||||
MAKE_REF(cpSpaceGetCurrentTimeStep);
|
||||
MAKE_REF(cpSpaceIsLocked);
|
||||
|
||||
#endif
|
||||
|
|
@ -1,254 +0,0 @@
|
|||
/* 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.
|
||||
*/
|
||||
|
||||
#define CP_ALLOW_PRIVATE_ACCESS 1
|
||||
#include "chipmunk.h"
|
||||
|
||||
#define CP_HASH_COEF (3344921057ul)
|
||||
#define CP_HASH_PAIR(A, B) ((cpHashValue)(A)*CP_HASH_COEF ^ (cpHashValue)(B)*CP_HASH_COEF)
|
||||
|
||||
// TODO: Eww. Magic numbers.
|
||||
#define MAGIC_EPSILON 1e-5
|
||||
|
||||
//MARK: cpArray
|
||||
|
||||
struct cpArray {
|
||||
int num, max;
|
||||
void **arr;
|
||||
};
|
||||
|
||||
cpArray *cpArrayNew(int size);
|
||||
|
||||
void cpArrayFree(cpArray *arr);
|
||||
|
||||
void cpArrayPush(cpArray *arr, void *object);
|
||||
void *cpArrayPop(cpArray *arr);
|
||||
void cpArrayDeleteObj(cpArray *arr, void *obj);
|
||||
cpBool cpArrayContains(cpArray *arr, void *ptr);
|
||||
|
||||
void cpArrayFreeEach(cpArray *arr, void (freeFunc)(void*));
|
||||
|
||||
|
||||
//MARK: Foreach loops
|
||||
|
||||
static inline cpConstraint *
|
||||
cpConstraintNext(cpConstraint *node, cpBody *body)
|
||||
{
|
||||
return (node->a == body ? node->next_a : node->next_b);
|
||||
}
|
||||
|
||||
#define CP_BODY_FOREACH_CONSTRAINT(bdy, var)\
|
||||
for(cpConstraint *var = bdy->constraintList; var; var = cpConstraintNext(var, bdy))
|
||||
|
||||
static inline cpArbiter *
|
||||
cpArbiterNext(cpArbiter *node, cpBody *body)
|
||||
{
|
||||
return (node->body_a == body ? node->thread_a.next : node->thread_b.next);
|
||||
}
|
||||
|
||||
#define CP_BODY_FOREACH_ARBITER(bdy, var)\
|
||||
for(cpArbiter *var = bdy->arbiterList; var; var = cpArbiterNext(var, bdy))
|
||||
|
||||
#define CP_BODY_FOREACH_SHAPE(body, var)\
|
||||
for(cpShape *var = body->shapeList; var; var = var->next)
|
||||
|
||||
#define CP_BODY_FOREACH_COMPONENT(root, var)\
|
||||
for(cpBody *var = root; var; var = var->node.next)
|
||||
|
||||
|
||||
//MARK: cpHashSet
|
||||
|
||||
typedef cpBool (*cpHashSetEqlFunc)(void *ptr, void *elt);
|
||||
typedef void *(*cpHashSetTransFunc)(void *ptr, void *data);
|
||||
|
||||
cpHashSet *cpHashSetNew(int size, cpHashSetEqlFunc eqlFunc);
|
||||
void cpHashSetSetDefaultValue(cpHashSet *set, void *default_value);
|
||||
|
||||
void cpHashSetFree(cpHashSet *set);
|
||||
|
||||
int cpHashSetCount(cpHashSet *set);
|
||||
void *cpHashSetInsert(cpHashSet *set, cpHashValue hash, void *ptr, void *data, cpHashSetTransFunc trans);
|
||||
void *cpHashSetRemove(cpHashSet *set, cpHashValue hash, void *ptr);
|
||||
void *cpHashSetFind(cpHashSet *set, cpHashValue hash, void *ptr);
|
||||
|
||||
typedef void (*cpHashSetIteratorFunc)(void *elt, void *data);
|
||||
void cpHashSetEach(cpHashSet *set, cpHashSetIteratorFunc func, void *data);
|
||||
|
||||
typedef cpBool (*cpHashSetFilterFunc)(void *elt, void *data);
|
||||
void cpHashSetFilter(cpHashSet *set, cpHashSetFilterFunc func, void *data);
|
||||
|
||||
|
||||
//MARK: Body Functions
|
||||
|
||||
void cpBodyAddShape(cpBody *body, cpShape *shape);
|
||||
void cpBodyRemoveShape(cpBody *body, cpShape *shape);
|
||||
void cpBodyRemoveConstraint(cpBody *body, cpConstraint *constraint);
|
||||
|
||||
|
||||
//MARK: Shape/Collision Functions
|
||||
|
||||
// TODO should move this to the cpVect API. It's pretty useful.
|
||||
static inline cpVect
|
||||
cpClosetPointOnSegment(const cpVect p, const cpVect a, const cpVect b)
|
||||
{
|
||||
cpVect delta = cpvsub(a, b);
|
||||
cpFloat t = cpfclamp01(cpvdot(delta, cpvsub(p, b))/cpvlengthsq(delta));
|
||||
return cpvadd(b, cpvmult(delta, t));
|
||||
}
|
||||
|
||||
cpShape* cpShapeInit(cpShape *shape, const cpShapeClass *klass, cpBody *body);
|
||||
|
||||
static inline cpBool
|
||||
cpShapeActive(cpShape *shape)
|
||||
{
|
||||
return shape->prev || (shape->body && shape->body->shapeList == shape);
|
||||
}
|
||||
|
||||
int cpCollideShapes(const cpShape *a, const cpShape *b, cpCollisionID *id, cpContact *arr);
|
||||
|
||||
static inline void
|
||||
CircleSegmentQuery(cpShape *shape, cpVect center, cpFloat r, cpVect a, cpVect b, cpSegmentQueryInfo *info)
|
||||
{
|
||||
cpVect da = cpvsub(a, center);
|
||||
cpVect db = cpvsub(b, center);
|
||||
|
||||
cpFloat qa = cpvdot(da, da) - 2.0f*cpvdot(da, db) + cpvdot(db, db);
|
||||
cpFloat qb = -2.0f*cpvdot(da, da) + 2.0f*cpvdot(da, db);
|
||||
cpFloat qc = cpvdot(da, da) - r*r;
|
||||
|
||||
cpFloat det = qb*qb - 4.0f*qa*qc;
|
||||
|
||||
if(det >= 0.0f){
|
||||
cpFloat t = (-qb - cpfsqrt(det))/(2.0f*qa);
|
||||
if(0.0f<= t && t <= 1.0f){
|
||||
info->shape = shape;
|
||||
info->t = t;
|
||||
info->n = cpvnormalize(cpvlerp(da, db, t));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO doesn't really need to be inline, but need a better place to put this function
|
||||
static inline cpSplittingPlane
|
||||
cpSplittingPlaneNew(cpVect a, cpVect b)
|
||||
{
|
||||
cpVect n = cpvnormalize(cpvperp(cpvsub(b, a)));
|
||||
cpSplittingPlane plane = {n, cpvdot(n, a)};
|
||||
return plane;
|
||||
}
|
||||
|
||||
static inline cpFloat
|
||||
cpSplittingPlaneCompare(cpSplittingPlane plane, cpVect v)
|
||||
{
|
||||
return cpvdot(plane.n, v) - plane.d;
|
||||
}
|
||||
|
||||
void cpLoopIndexes(cpVect *verts, int count, int *start, int *end);
|
||||
|
||||
|
||||
//MARK: Spatial Index Functions
|
||||
|
||||
cpSpatialIndex *cpSpatialIndexInit(cpSpatialIndex *index, cpSpatialIndexClass *klass, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
|
||||
|
||||
//MARK: Space Functions
|
||||
|
||||
extern cpCollisionHandler cpDefaultCollisionHandler;
|
||||
void cpSpaceProcessComponents(cpSpace *space, cpFloat dt);
|
||||
|
||||
void cpSpacePushFreshContactBuffer(cpSpace *space);
|
||||
cpContact *cpContactBufferGetArray(cpSpace *space);
|
||||
void cpSpacePushContacts(cpSpace *space, int count);
|
||||
|
||||
typedef struct cpPostStepCallback {
|
||||
cpPostStepFunc func;
|
||||
void *key;
|
||||
void *data;
|
||||
} cpPostStepCallback;
|
||||
|
||||
cpPostStepCallback *cpSpaceGetPostStepCallback(cpSpace *space, void *key);
|
||||
|
||||
cpBool cpSpaceArbiterSetFilter(cpArbiter *arb, cpSpace *space);
|
||||
void cpSpaceFilterArbiters(cpSpace *space, cpBody *body, cpShape *filter);
|
||||
|
||||
void cpSpaceActivateBody(cpSpace *space, cpBody *body);
|
||||
void cpSpaceLock(cpSpace *space);
|
||||
void cpSpaceUnlock(cpSpace *space, cpBool runPostStep);
|
||||
|
||||
static inline cpCollisionHandler *
|
||||
cpSpaceLookupHandler(cpSpace *space, cpCollisionType a, cpCollisionType b)
|
||||
{
|
||||
cpCollisionType types[] = {a, b};
|
||||
return (cpCollisionHandler *)cpHashSetFind(space->collisionHandlers, CP_HASH_PAIR(a, b), types);
|
||||
}
|
||||
|
||||
static inline void
|
||||
cpSpaceUncacheArbiter(cpSpace *space, cpArbiter *arb)
|
||||
{
|
||||
cpShape *a = arb->a, *b = arb->b;
|
||||
cpShape *shape_pair[] = {a, b};
|
||||
cpHashValue arbHashID = CP_HASH_PAIR((cpHashValue)a, (cpHashValue)b);
|
||||
cpHashSetRemove(space->cachedArbiters, arbHashID, shape_pair);
|
||||
cpArrayDeleteObj(space->arbiters, arb);
|
||||
}
|
||||
|
||||
void cpShapeUpdateFunc(cpShape *shape, void *unused);
|
||||
cpCollisionID cpSpaceCollideShapes(cpShape *a, cpShape *b, cpCollisionID id, cpSpace *space);
|
||||
|
||||
|
||||
//MARK: Arbiters
|
||||
|
||||
struct cpContact {
|
||||
cpVect p, n;
|
||||
cpFloat dist;
|
||||
|
||||
cpVect r1, r2;
|
||||
cpFloat nMass, tMass, bounce;
|
||||
|
||||
cpFloat jnAcc, jtAcc, jBias;
|
||||
cpFloat bias;
|
||||
|
||||
cpHashValue hash;
|
||||
};
|
||||
|
||||
cpContact* cpContactInit(cpContact *con, cpVect p, cpVect n, cpFloat dist, cpHashValue hash);
|
||||
cpArbiter* cpArbiterInit(cpArbiter *arb, cpShape *a, cpShape *b);
|
||||
|
||||
static inline void
|
||||
cpArbiterCallSeparate(cpArbiter *arb, cpSpace *space)
|
||||
{
|
||||
// The handler needs to be looked up again as the handler cached on the arbiter may have been deleted since the last step.
|
||||
cpCollisionHandler *handler = cpSpaceLookupHandler(space, arb->a->collision_type, arb->b->collision_type);
|
||||
handler->separate(arb, space, handler->data);
|
||||
}
|
||||
|
||||
static inline struct cpArbiterThread *
|
||||
cpArbiterThreadForBody(cpArbiter *arb, cpBody *body)
|
||||
{
|
||||
return (arb->body_a == body ? &arb->thread_a : &arb->thread_b);
|
||||
}
|
||||
|
||||
void cpArbiterUnthread(cpArbiter *arb);
|
||||
|
||||
void cpArbiterUpdate(cpArbiter *arb, cpContact *contacts, int numContacts, struct cpCollisionHandler *handler, cpShape *a, cpShape *b);
|
||||
void cpArbiterPreStep(cpArbiter *arb, cpFloat dt, cpFloat bias, cpFloat slop);
|
||||
void cpArbiterApplyCachedImpulse(cpArbiter *arb, cpFloat dt_coef);
|
||||
void cpArbiterApplyImpulse(cpArbiter *arb);
|
||||
|
|
@ -1,222 +0,0 @@
|
|||
#include <stdint.h>
|
||||
#include <float.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include "TargetConditionals.h"
|
||||
#endif
|
||||
|
||||
#if ((TARGET_OS_IPHONE == 1) || (TARGET_OS_MAC == 1)) && (!defined CP_USE_CGPOINTS)
|
||||
#define CP_USE_CGPOINTS 1
|
||||
#endif
|
||||
|
||||
#if CP_USE_CGPOINTS == 1
|
||||
#if TARGET_OS_IPHONE
|
||||
#import <CoreGraphics/CGGeometry.h>
|
||||
#elif TARGET_OS_MAC
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#endif
|
||||
|
||||
#if defined(__LP64__) && __LP64__
|
||||
#define CP_USE_DOUBLES 1
|
||||
#else
|
||||
#define CP_USE_DOUBLES 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef CP_USE_DOUBLES
|
||||
// use doubles by default for higher precision
|
||||
#define CP_USE_DOUBLES 1
|
||||
#endif
|
||||
|
||||
/// @defgroup basicTypes Basic Types
|
||||
/// Most of these types can be configured at compile time.
|
||||
/// @{
|
||||
|
||||
#if CP_USE_DOUBLES
|
||||
/// Chipmunk's floating point type.
|
||||
/// Can be reconfigured at compile time.
|
||||
typedef double cpFloat;
|
||||
#define cpfsqrt sqrt
|
||||
#define cpfsin sin
|
||||
#define cpfcos cos
|
||||
#define cpfacos acos
|
||||
#define cpfatan2 atan2
|
||||
#define cpfmod fmod
|
||||
#define cpfexp exp
|
||||
#define cpfpow pow
|
||||
#define cpffloor floor
|
||||
#define cpfceil ceil
|
||||
#define CPFLOAT_MIN DBL_MIN
|
||||
#else
|
||||
typedef float cpFloat;
|
||||
#define cpfsqrt sqrtf
|
||||
#define cpfsin sinf
|
||||
#define cpfcos cosf
|
||||
#define cpfacos acosf
|
||||
#define cpfatan2 atan2f
|
||||
#define cpfmod fmodf
|
||||
#define cpfexp expf
|
||||
#define cpfpow powf
|
||||
#define cpffloor floorf
|
||||
#define cpfceil ceilf
|
||||
#define CPFLOAT_MIN FLT_MIN
|
||||
#endif
|
||||
|
||||
#ifndef INFINITY
|
||||
#ifdef _MSC_VER
|
||||
union MSVC_EVIL_FLOAT_HACK
|
||||
{
|
||||
unsigned __int8 Bytes[4];
|
||||
float Value;
|
||||
};
|
||||
static union MSVC_EVIL_FLOAT_HACK INFINITY_HACK = {{0x00, 0x00, 0x80, 0x7F}};
|
||||
#define INFINITY (INFINITY_HACK.Value)
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define INFINITY (__builtin_inf())
|
||||
#endif
|
||||
|
||||
#ifndef INFINITY
|
||||
#define INFINITY (1e1000)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846264338327950288
|
||||
#endif
|
||||
|
||||
#ifndef M_E
|
||||
#define M_E 2.71828182845904523536028747135266250
|
||||
#endif
|
||||
|
||||
|
||||
/// Return the max of two cpFloats.
|
||||
static inline cpFloat cpfmax(cpFloat a, cpFloat b)
|
||||
{
|
||||
return (a > b) ? a : b;
|
||||
}
|
||||
|
||||
/// Return the min of two cpFloats.
|
||||
static inline cpFloat cpfmin(cpFloat a, cpFloat b)
|
||||
{
|
||||
return (a < b) ? a : b;
|
||||
}
|
||||
|
||||
/// Return the absolute value of a cpFloat.
|
||||
static inline cpFloat cpfabs(cpFloat f)
|
||||
{
|
||||
return (f < 0) ? -f : f;
|
||||
}
|
||||
|
||||
/// Clamp @c f to be between @c min and @c max.
|
||||
static inline cpFloat cpfclamp(cpFloat f, cpFloat min, cpFloat max)
|
||||
{
|
||||
return cpfmin(cpfmax(f, min), max);
|
||||
}
|
||||
|
||||
/// Clamp @c f to be between 0 and 1.
|
||||
static inline cpFloat cpfclamp01(cpFloat f)
|
||||
{
|
||||
return cpfmax(0.0f, cpfmin(f, 1.0f));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Linearly interpolate (or extrapolate) between @c f1 and @c f2 by @c t percent.
|
||||
static inline cpFloat cpflerp(cpFloat f1, cpFloat f2, cpFloat t)
|
||||
{
|
||||
return f1*(1.0f - t) + f2*t;
|
||||
}
|
||||
|
||||
/// Linearly interpolate from @c f1 to @c f2 by no more than @c d.
|
||||
static inline cpFloat cpflerpconst(cpFloat f1, cpFloat f2, cpFloat d)
|
||||
{
|
||||
return f1 + cpfclamp(f2 - f1, -d, d);
|
||||
}
|
||||
|
||||
/// Hash value type.
|
||||
typedef uintptr_t cpHashValue;
|
||||
|
||||
/// Type used internally to cache colliding object info for cpCollideShapes().
|
||||
/// Should be at least 32 bits.
|
||||
typedef uint32_t cpCollisionID;
|
||||
|
||||
// Oh C, how we love to define our own boolean types to get compiler compatibility
|
||||
/// Chipmunk's boolean type.
|
||||
#ifdef CP_BOOL_TYPE
|
||||
typedef CP_BOOL_TYPE cpBool;
|
||||
#else
|
||||
typedef int cpBool;
|
||||
#endif
|
||||
|
||||
#ifndef cpTrue
|
||||
/// true value.
|
||||
#define cpTrue 1
|
||||
#endif
|
||||
|
||||
#ifndef cpFalse
|
||||
/// false value.
|
||||
#define cpFalse 0
|
||||
#endif
|
||||
|
||||
#ifdef CP_DATA_POINTER_TYPE
|
||||
typedef CP_DATA_POINTER_TYPE cpDataPointer;
|
||||
#else
|
||||
/// Type used for user data pointers.
|
||||
typedef void * cpDataPointer;
|
||||
#endif
|
||||
|
||||
#ifdef CP_COLLISION_TYPE_TYPE
|
||||
typedef CP_COLLISION_TYPE_TYPE cpCollisionType;
|
||||
#else
|
||||
/// Type used for cpSpace.collision_type.
|
||||
typedef uintptr_t cpCollisionType;
|
||||
#endif
|
||||
|
||||
#ifdef CP_GROUP_TYPE
|
||||
typedef CP_GROUP_TYPE cpGroup;
|
||||
#else
|
||||
/// Type used for cpShape.group.
|
||||
typedef uintptr_t cpGroup;
|
||||
#endif
|
||||
|
||||
#ifdef CP_LAYERS_TYPE
|
||||
typedef CP_LAYERS_TYPE cpLayers;
|
||||
#else
|
||||
/// Type used for cpShape.layers.
|
||||
typedef unsigned int cpLayers;
|
||||
#endif
|
||||
|
||||
#ifdef CP_TIMESTAMP_TYPE
|
||||
typedef CP_TIMESTAMP_TYPE cpTimestamp;
|
||||
#else
|
||||
/// Type used for various timestamps in Chipmunk.
|
||||
typedef unsigned int cpTimestamp;
|
||||
#endif
|
||||
|
||||
#ifndef CP_NO_GROUP
|
||||
/// Value for cpShape.group signifying that a shape is in no group.
|
||||
#define CP_NO_GROUP ((cpGroup)0)
|
||||
#endif
|
||||
|
||||
#ifndef CP_ALL_LAYERS
|
||||
/// Value for cpShape.layers signifying that a shape is in every layer.
|
||||
#define CP_ALL_LAYERS (~(cpLayers)0)
|
||||
#endif
|
||||
/// @}
|
||||
|
||||
// CGPoints are structurally the same, and allow
|
||||
// easy interoperability with other Cocoa libraries
|
||||
#if CP_USE_CGPOINTS
|
||||
typedef CGPoint cpVect;
|
||||
#else
|
||||
/// Chipmunk's 2D vector type.
|
||||
/// @addtogroup cpVect
|
||||
typedef struct cpVect{cpFloat x,y;} cpVect;
|
||||
#endif
|
||||
|
||||
typedef struct cpMat2x2 {
|
||||
// Row major [[a, b][c d]]
|
||||
cpFloat a, b, c, d;
|
||||
} cpMat2x2;
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
/* 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.
|
||||
*/
|
||||
|
||||
/* This header defines a number of "unsafe" operations on Chipmunk objects.
|
||||
* In this case "unsafe" is referring to operations which may reduce the
|
||||
* physical accuracy or numerical stability of the simulation, but will not
|
||||
* cause crashes.
|
||||
*
|
||||
* The prime example is mutating collision shapes. Chipmunk does not support
|
||||
* this directly. Mutating shapes using this API will caused objects in contact
|
||||
* to be pushed apart using Chipmunk's overlap solver, but not using real
|
||||
* persistent velocities. Probably not what you meant, but perhaps close enough.
|
||||
*/
|
||||
|
||||
/// @defgroup unsafe Chipmunk Unsafe Shape Operations
|
||||
/// These functions are used for mutating collision shapes.
|
||||
/// Chipmunk does not have any way to get velocity information on changing shapes,
|
||||
/// so the results will be unrealistic. You must explicity include the chipmunk_unsafe.h header to use them.
|
||||
/// @{
|
||||
|
||||
#ifndef CHIPMUNK_UNSAFE_HEADER
|
||||
#define CHIPMUNK_UNSAFE_HEADER
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// Set the radius of a circle shape.
|
||||
void cpCircleShapeSetRadius(cpShape *shape, cpFloat radius);
|
||||
/// Set the offset of a circle shape.
|
||||
void cpCircleShapeSetOffset(cpShape *shape, cpVect offset);
|
||||
|
||||
/// Set the endpoints of a segment shape.
|
||||
void cpSegmentShapeSetEndpoints(cpShape *shape, cpVect a, cpVect b);
|
||||
/// Set the radius of a segment shape.
|
||||
void cpSegmentShapeSetRadius(cpShape *shape, cpFloat radius);
|
||||
|
||||
/// Set the vertexes of a poly shape.
|
||||
void cpPolyShapeSetVerts(cpShape *shape, int numVerts, cpVect *verts, cpVect offset);
|
||||
/// Set the radius of a poly shape.
|
||||
void cpPolyShapeSetRadius(cpShape *shape, cpFloat radius);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
/// @}
|
||||
|
|
@ -1,161 +0,0 @@
|
|||
/* 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 cpConstraint cpConstraint
|
||||
/// @{
|
||||
|
||||
typedef struct cpConstraintClass cpConstraintClass;
|
||||
|
||||
typedef void (*cpConstraintPreStepImpl)(cpConstraint *constraint, cpFloat dt);
|
||||
typedef void (*cpConstraintApplyCachedImpulseImpl)(cpConstraint *constraint, cpFloat dt_coef);
|
||||
typedef void (*cpConstraintApplyImpulseImpl)(cpConstraint *constraint, cpFloat dt);
|
||||
typedef cpFloat (*cpConstraintGetImpulseImpl)(cpConstraint *constraint);
|
||||
|
||||
/// @private
|
||||
struct cpConstraintClass {
|
||||
cpConstraintPreStepImpl preStep;
|
||||
cpConstraintApplyCachedImpulseImpl applyCachedImpulse;
|
||||
cpConstraintApplyImpulseImpl applyImpulse;
|
||||
cpConstraintGetImpulseImpl getImpulse;
|
||||
};
|
||||
|
||||
/// Callback function type that gets called before solving a joint.
|
||||
typedef void (*cpConstraintPreSolveFunc)(cpConstraint *constraint, cpSpace *space);
|
||||
/// Callback function type that gets called after solving a joint.
|
||||
typedef void (*cpConstraintPostSolveFunc)(cpConstraint *constraint, cpSpace *space);
|
||||
|
||||
|
||||
/// Opaque cpConstraint struct.
|
||||
struct cpConstraint {
|
||||
CP_PRIVATE(const cpConstraintClass *klass);
|
||||
|
||||
/// The first body connected to this constraint.
|
||||
cpBody *a;
|
||||
/// The second body connected to this constraint.
|
||||
cpBody *b;
|
||||
|
||||
CP_PRIVATE(cpSpace *space);
|
||||
|
||||
CP_PRIVATE(cpConstraint *next_a);
|
||||
CP_PRIVATE(cpConstraint *next_b);
|
||||
|
||||
/// The maximum force that this constraint is allowed to use.
|
||||
/// Defaults to infinity.
|
||||
cpFloat maxForce;
|
||||
/// The rate at which joint error is corrected.
|
||||
/// Defaults to pow(1.0 - 0.1, 60.0) meaning that it will
|
||||
/// correct 10% of the error every 1/60th of a second.
|
||||
cpFloat errorBias;
|
||||
/// The maximum rate at which joint error is corrected.
|
||||
/// Defaults to infinity.
|
||||
cpFloat maxBias;
|
||||
|
||||
/// Function called before the solver runs.
|
||||
/// Animate your joint anchors, update your motor torque, etc.
|
||||
cpConstraintPreSolveFunc preSolve;
|
||||
|
||||
/// Function called after the solver runs.
|
||||
/// Use the applied impulse to perform effects like breakable joints.
|
||||
cpConstraintPostSolveFunc postSolve;
|
||||
|
||||
/// User definable data pointer.
|
||||
/// Generally this points to your the game object class so you can access it
|
||||
/// when given a cpConstraint reference in a callback.
|
||||
cpDataPointer data;
|
||||
};
|
||||
|
||||
/// Destroy a constraint.
|
||||
void cpConstraintDestroy(cpConstraint *constraint);
|
||||
/// Destroy and free a constraint.
|
||||
void cpConstraintFree(cpConstraint *constraint);
|
||||
|
||||
/// @private
|
||||
static inline void cpConstraintActivateBodies(cpConstraint *constraint)
|
||||
{
|
||||
cpBody *a = constraint->a; if(a) cpBodyActivate(a);
|
||||
cpBody *b = constraint->b; if(b) cpBodyActivate(b);
|
||||
}
|
||||
|
||||
/// @private
|
||||
#define CP_DefineConstraintStructGetter(type, member, name) \
|
||||
static inline type cpConstraint##Get##name(const cpConstraint *constraint){return constraint->member;}
|
||||
|
||||
/// @private
|
||||
#define CP_DefineConstraintStructSetter(type, member, name) \
|
||||
static inline void cpConstraint##Set##name(cpConstraint *constraint, type value){ \
|
||||
cpConstraintActivateBodies(constraint); \
|
||||
constraint->member = value; \
|
||||
}
|
||||
|
||||
/// @private
|
||||
#define CP_DefineConstraintStructProperty(type, member, name) \
|
||||
CP_DefineConstraintStructGetter(type, member, name) \
|
||||
CP_DefineConstraintStructSetter(type, member, name)
|
||||
|
||||
CP_DefineConstraintStructGetter(cpSpace*, CP_PRIVATE(space), Space)
|
||||
|
||||
CP_DefineConstraintStructGetter(cpBody*, a, A)
|
||||
CP_DefineConstraintStructGetter(cpBody*, b, B)
|
||||
CP_DefineConstraintStructProperty(cpFloat, maxForce, MaxForce)
|
||||
CP_DefineConstraintStructProperty(cpFloat, errorBias, ErrorBias)
|
||||
CP_DefineConstraintStructProperty(cpFloat, maxBias, MaxBias)
|
||||
CP_DefineConstraintStructProperty(cpConstraintPreSolveFunc, preSolve, PreSolveFunc)
|
||||
CP_DefineConstraintStructProperty(cpConstraintPostSolveFunc, postSolve, PostSolveFunc)
|
||||
CP_DefineConstraintStructProperty(cpDataPointer, data, UserData)
|
||||
|
||||
// Get the last impulse applied by this constraint.
|
||||
static inline cpFloat cpConstraintGetImpulse(cpConstraint *constraint)
|
||||
{
|
||||
return constraint->CP_PRIVATE(klass)->getImpulse(constraint);
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
#define cpConstraintCheckCast(constraint, struct) \
|
||||
cpAssertHard(constraint->CP_PRIVATE(klass) == struct##GetClass(), "Constraint is not a "#struct)
|
||||
|
||||
#define CP_DefineConstraintGetter(struct, type, member, name) \
|
||||
static inline type struct##Get##name(const cpConstraint *constraint){ \
|
||||
cpConstraintCheckCast(constraint, struct); \
|
||||
return ((struct *)constraint)->member; \
|
||||
}
|
||||
|
||||
#define CP_DefineConstraintSetter(struct, type, member, name) \
|
||||
static inline void struct##Set##name(cpConstraint *constraint, type value){ \
|
||||
cpConstraintCheckCast(constraint, struct); \
|
||||
cpConstraintActivateBodies(constraint); \
|
||||
((struct *)constraint)->member = value; \
|
||||
}
|
||||
|
||||
#define CP_DefineConstraintProperty(struct, type, member, name) \
|
||||
CP_DefineConstraintGetter(struct, type, member, name) \
|
||||
CP_DefineConstraintSetter(struct, type, member, name)
|
||||
|
||||
#include "cpPinJoint.h"
|
||||
#include "cpSlideJoint.h"
|
||||
#include "cpPivotJoint.h"
|
||||
#include "cpGrooveJoint.h"
|
||||
#include "cpDampedSpring.h"
|
||||
#include "cpDampedRotarySpring.h"
|
||||
#include "cpRotaryLimitJoint.h"
|
||||
#include "cpRatchetJoint.h"
|
||||
#include "cpGearJoint.h"
|
||||
#include "cpSimpleMotor.h"
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
/* 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 cpDampedRotarySpring cpDampedRotarySpring
|
||||
/// @{
|
||||
|
||||
typedef cpFloat (*cpDampedRotarySpringTorqueFunc)(struct cpConstraint *spring, cpFloat relativeAngle);
|
||||
|
||||
const cpConstraintClass *cpDampedRotarySpringGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpDampedRotarySpring {
|
||||
cpConstraint constraint;
|
||||
cpFloat restAngle;
|
||||
cpFloat stiffness;
|
||||
cpFloat damping;
|
||||
cpDampedRotarySpringTorqueFunc springTorqueFunc;
|
||||
|
||||
cpFloat target_wrn;
|
||||
cpFloat w_coef;
|
||||
|
||||
cpFloat iSum;
|
||||
cpFloat jAcc;
|
||||
} cpDampedRotarySpring;
|
||||
|
||||
/// Allocate a damped rotary spring.
|
||||
cpDampedRotarySpring* cpDampedRotarySpringAlloc(void);
|
||||
/// Initialize a damped rotary spring.
|
||||
cpDampedRotarySpring* cpDampedRotarySpringInit(cpDampedRotarySpring *joint, cpBody *a, cpBody *b, cpFloat restAngle, cpFloat stiffness, cpFloat damping);
|
||||
/// Allocate and initialize a damped rotary spring.
|
||||
cpConstraint* cpDampedRotarySpringNew(cpBody *a, cpBody *b, cpFloat restAngle, cpFloat stiffness, cpFloat damping);
|
||||
|
||||
CP_DefineConstraintProperty(cpDampedRotarySpring, cpFloat, restAngle, RestAngle)
|
||||
CP_DefineConstraintProperty(cpDampedRotarySpring, cpFloat, stiffness, Stiffness)
|
||||
CP_DefineConstraintProperty(cpDampedRotarySpring, cpFloat, damping, Damping)
|
||||
CP_DefineConstraintProperty(cpDampedRotarySpring, cpDampedRotarySpringTorqueFunc, springTorqueFunc, SpringTorqueFunc)
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
/* 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 cpDampedSpring cpDampedSpring
|
||||
/// @{
|
||||
|
||||
typedef struct cpDampedSpring cpDampedSpring;
|
||||
|
||||
typedef cpFloat (*cpDampedSpringForceFunc)(cpConstraint *spring, cpFloat dist);
|
||||
|
||||
const cpConstraintClass *cpDampedSpringGetClass(void);
|
||||
|
||||
/// @private
|
||||
struct cpDampedSpring {
|
||||
cpConstraint constraint;
|
||||
cpVect anchr1, anchr2;
|
||||
cpFloat restLength;
|
||||
cpFloat stiffness;
|
||||
cpFloat damping;
|
||||
cpDampedSpringForceFunc springForceFunc;
|
||||
|
||||
cpFloat target_vrn;
|
||||
cpFloat v_coef;
|
||||
|
||||
cpVect r1, r2;
|
||||
cpFloat nMass;
|
||||
cpVect n;
|
||||
|
||||
cpFloat jAcc;
|
||||
};
|
||||
|
||||
/// Allocate a damped spring.
|
||||
cpDampedSpring* cpDampedSpringAlloc(void);
|
||||
/// Initialize a damped spring.
|
||||
cpDampedSpring* cpDampedSpringInit(cpDampedSpring *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat restLength, cpFloat stiffness, cpFloat damping);
|
||||
/// Allocate and initialize a damped spring.
|
||||
cpConstraint* cpDampedSpringNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat restLength, cpFloat stiffness, cpFloat damping);
|
||||
|
||||
CP_DefineConstraintProperty(cpDampedSpring, cpVect, anchr1, Anchr1)
|
||||
CP_DefineConstraintProperty(cpDampedSpring, cpVect, anchr2, Anchr2)
|
||||
CP_DefineConstraintProperty(cpDampedSpring, cpFloat, restLength, RestLength)
|
||||
CP_DefineConstraintProperty(cpDampedSpring, cpFloat, stiffness, Stiffness)
|
||||
CP_DefineConstraintProperty(cpDampedSpring, cpFloat, damping, Damping)
|
||||
CP_DefineConstraintProperty(cpDampedSpring, cpDampedSpringForceFunc, springForceFunc, SpringForceFunc)
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
/* 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 cpGearJoint cpGearJoint
|
||||
/// @{
|
||||
|
||||
const cpConstraintClass *cpGearJointGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpGearJoint {
|
||||
cpConstraint constraint;
|
||||
cpFloat phase, ratio;
|
||||
cpFloat ratio_inv;
|
||||
|
||||
cpFloat iSum;
|
||||
|
||||
cpFloat bias;
|
||||
cpFloat jAcc;
|
||||
} cpGearJoint;
|
||||
|
||||
/// Allocate a gear joint.
|
||||
cpGearJoint* cpGearJointAlloc(void);
|
||||
/// Initialize a gear joint.
|
||||
cpGearJoint* cpGearJointInit(cpGearJoint *joint, cpBody *a, cpBody *b, cpFloat phase, cpFloat ratio);
|
||||
/// Allocate and initialize a gear joint.
|
||||
cpConstraint* cpGearJointNew(cpBody *a, cpBody *b, cpFloat phase, cpFloat ratio);
|
||||
|
||||
CP_DefineConstraintProperty(cpGearJoint, cpFloat, phase, Phase)
|
||||
CP_DefineConstraintGetter(cpGearJoint, cpFloat, ratio, Ratio)
|
||||
/// Set the ratio of a gear joint.
|
||||
void cpGearJointSetRatio(cpConstraint *constraint, cpFloat value);
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
/* 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 cpGrooveJoint cpGrooveJoint
|
||||
/// @{
|
||||
|
||||
const cpConstraintClass *cpGrooveJointGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpGrooveJoint {
|
||||
cpConstraint constraint;
|
||||
cpVect grv_n, grv_a, grv_b;
|
||||
cpVect anchr2;
|
||||
|
||||
cpVect grv_tn;
|
||||
cpFloat clamp;
|
||||
cpVect r1, r2;
|
||||
cpMat2x2 k;
|
||||
|
||||
cpVect jAcc;
|
||||
cpVect bias;
|
||||
} cpGrooveJoint;
|
||||
|
||||
/// Allocate a groove joint.
|
||||
cpGrooveJoint* cpGrooveJointAlloc(void);
|
||||
/// Initialize a groove joint.
|
||||
cpGrooveJoint* cpGrooveJointInit(cpGrooveJoint *joint, cpBody *a, cpBody *b, cpVect groove_a, cpVect groove_b, cpVect anchr2);
|
||||
/// Allocate and initialize a groove joint.
|
||||
cpConstraint* cpGrooveJointNew(cpBody *a, cpBody *b, cpVect groove_a, cpVect groove_b, cpVect anchr2);
|
||||
|
||||
CP_DefineConstraintGetter(cpGrooveJoint, cpVect, grv_a, GrooveA)
|
||||
/// Set endpoint a of a groove joint's groove
|
||||
void cpGrooveJointSetGrooveA(cpConstraint *constraint, cpVect value);
|
||||
CP_DefineConstraintGetter(cpGrooveJoint, cpVect, grv_b, GrooveB)
|
||||
/// Set endpoint b of a groove joint's groove
|
||||
void cpGrooveJointSetGrooveB(cpConstraint *constraint, cpVect value);
|
||||
CP_DefineConstraintProperty(cpGrooveJoint, cpVect, anchr2, Anchr2)
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
/* 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 cpPinJoint cpPinJoint
|
||||
/// @{
|
||||
|
||||
const cpConstraintClass *cpPinJointGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpPinJoint {
|
||||
cpConstraint constraint;
|
||||
cpVect anchr1, anchr2;
|
||||
cpFloat dist;
|
||||
|
||||
cpVect r1, r2;
|
||||
cpVect n;
|
||||
cpFloat nMass;
|
||||
|
||||
cpFloat jnAcc;
|
||||
cpFloat bias;
|
||||
} cpPinJoint;
|
||||
|
||||
/// Allocate a pin joint.
|
||||
cpPinJoint* cpPinJointAlloc(void);
|
||||
/// Initialize a pin joint.
|
||||
cpPinJoint* cpPinJointInit(cpPinJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2);
|
||||
/// Allocate and initialize a pin joint.
|
||||
cpConstraint* cpPinJointNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2);
|
||||
|
||||
CP_DefineConstraintProperty(cpPinJoint, cpVect, anchr1, Anchr1)
|
||||
CP_DefineConstraintProperty(cpPinJoint, cpVect, anchr2, Anchr2)
|
||||
CP_DefineConstraintProperty(cpPinJoint, cpFloat, dist, Dist)
|
||||
|
||||
///@}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
/* 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 cpPivotJoint cpPivotJoint
|
||||
/// @{
|
||||
|
||||
const cpConstraintClass *cpPivotJointGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpPivotJoint {
|
||||
cpConstraint constraint;
|
||||
cpVect anchr1, anchr2;
|
||||
|
||||
cpVect r1, r2;
|
||||
cpMat2x2 k;
|
||||
|
||||
cpVect jAcc;
|
||||
cpVect bias;
|
||||
} cpPivotJoint;
|
||||
|
||||
/// Allocate a pivot joint
|
||||
cpPivotJoint* cpPivotJointAlloc(void);
|
||||
/// Initialize a pivot joint.
|
||||
cpPivotJoint* cpPivotJointInit(cpPivotJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2);
|
||||
/// Allocate and initialize a pivot joint.
|
||||
cpConstraint* cpPivotJointNew(cpBody *a, cpBody *b, cpVect pivot);
|
||||
/// Allocate and initialize a pivot joint with specific anchors.
|
||||
cpConstraint* cpPivotJointNew2(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2);
|
||||
|
||||
CP_DefineConstraintProperty(cpPivotJoint, cpVect, anchr1, Anchr1)
|
||||
CP_DefineConstraintProperty(cpPivotJoint, cpVect, anchr2, Anchr2)
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
/* 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 cpRatchetJoint cpRatchetJoint
|
||||
/// @{
|
||||
|
||||
const cpConstraintClass *cpRatchetJointGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpRatchetJoint {
|
||||
cpConstraint constraint;
|
||||
cpFloat angle, phase, ratchet;
|
||||
|
||||
cpFloat iSum;
|
||||
|
||||
cpFloat bias;
|
||||
cpFloat jAcc;
|
||||
} cpRatchetJoint;
|
||||
|
||||
/// Allocate a ratchet joint.
|
||||
cpRatchetJoint* cpRatchetJointAlloc(void);
|
||||
/// Initialize a ratched joint.
|
||||
cpRatchetJoint* cpRatchetJointInit(cpRatchetJoint *joint, cpBody *a, cpBody *b, cpFloat phase, cpFloat ratchet);
|
||||
/// Allocate and initialize a ratchet joint.
|
||||
cpConstraint* cpRatchetJointNew(cpBody *a, cpBody *b, cpFloat phase, cpFloat ratchet);
|
||||
|
||||
CP_DefineConstraintProperty(cpRatchetJoint, cpFloat, angle, Angle)
|
||||
CP_DefineConstraintProperty(cpRatchetJoint, cpFloat, phase, Phase)
|
||||
CP_DefineConstraintProperty(cpRatchetJoint, cpFloat, ratchet, Ratchet)
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
/* 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 cpRotaryLimitJoint cpRotaryLimitJoint
|
||||
/// @{
|
||||
|
||||
const cpConstraintClass *cpRotaryLimitJointGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpRotaryLimitJoint {
|
||||
cpConstraint constraint;
|
||||
cpFloat min, max;
|
||||
|
||||
cpFloat iSum;
|
||||
|
||||
cpFloat bias;
|
||||
cpFloat jAcc;
|
||||
} cpRotaryLimitJoint;
|
||||
|
||||
/// Allocate a damped rotary limit joint.
|
||||
cpRotaryLimitJoint* cpRotaryLimitJointAlloc(void);
|
||||
/// Initialize a damped rotary limit joint.
|
||||
cpRotaryLimitJoint* cpRotaryLimitJointInit(cpRotaryLimitJoint *joint, cpBody *a, cpBody *b, cpFloat min, cpFloat max);
|
||||
/// Allocate and initialize a damped rotary limit joint.
|
||||
cpConstraint* cpRotaryLimitJointNew(cpBody *a, cpBody *b, cpFloat min, cpFloat max);
|
||||
|
||||
CP_DefineConstraintProperty(cpRotaryLimitJoint, cpFloat, min, Min)
|
||||
CP_DefineConstraintProperty(cpRotaryLimitJoint, cpFloat, max, Max)
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
/* 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 cpSimpleMotor cpSimpleMotor
|
||||
/// @{
|
||||
|
||||
const cpConstraintClass *cpSimpleMotorGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpSimpleMotor {
|
||||
cpConstraint constraint;
|
||||
cpFloat rate;
|
||||
|
||||
cpFloat iSum;
|
||||
|
||||
cpFloat jAcc;
|
||||
} cpSimpleMotor;
|
||||
|
||||
/// Allocate a simple motor.
|
||||
cpSimpleMotor* cpSimpleMotorAlloc(void);
|
||||
/// initialize a simple motor.
|
||||
cpSimpleMotor* cpSimpleMotorInit(cpSimpleMotor *joint, cpBody *a, cpBody *b, cpFloat rate);
|
||||
/// Allocate and initialize a simple motor.
|
||||
cpConstraint* cpSimpleMotorNew(cpBody *a, cpBody *b, cpFloat rate);
|
||||
|
||||
CP_DefineConstraintProperty(cpSimpleMotor, cpFloat, rate, Rate)
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
/* 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 cpSlideJoint cpSlideJoint
|
||||
/// @{
|
||||
|
||||
const cpConstraintClass *cpSlideJointGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpSlideJoint {
|
||||
cpConstraint constraint;
|
||||
cpVect anchr1, anchr2;
|
||||
cpFloat min, max;
|
||||
|
||||
cpVect r1, r2;
|
||||
cpVect n;
|
||||
cpFloat nMass;
|
||||
|
||||
cpFloat jnAcc;
|
||||
cpFloat bias;
|
||||
} cpSlideJoint;
|
||||
|
||||
/// Allocate a slide joint.
|
||||
cpSlideJoint* cpSlideJointAlloc(void);
|
||||
/// Initialize a slide joint.
|
||||
cpSlideJoint* cpSlideJointInit(cpSlideJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max);
|
||||
/// Allocate and initialize a slide joint.
|
||||
cpConstraint* cpSlideJointNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max);
|
||||
|
||||
CP_DefineConstraintProperty(cpSlideJoint, cpVect, anchr1, Anchr1)
|
||||
CP_DefineConstraintProperty(cpSlideJoint, cpVect, anchr2, Anchr2)
|
||||
CP_DefineConstraintProperty(cpSlideJoint, cpFloat, min, Min)
|
||||
CP_DefineConstraintProperty(cpSlideJoint, cpFloat, max, Max)
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,126 +0,0 @@
|
|||
/* 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.
|
||||
*/
|
||||
|
||||
// These are utility routines to use when creating custom constraints.
|
||||
// I'm not sure if this should be part of the private API or not.
|
||||
// I should probably clean up the naming conventions if it is...
|
||||
|
||||
#define CP_DefineClassGetter(t) const cpConstraintClass * t##GetClass(void){return (cpConstraintClass *)&klass;}
|
||||
|
||||
void cpConstraintInit(cpConstraint *constraint, const cpConstraintClass *klass, cpBody *a, cpBody *b);
|
||||
|
||||
static inline cpVect
|
||||
relative_velocity(cpBody *a, cpBody *b, cpVect r1, cpVect r2){
|
||||
cpVect v1_sum = cpvadd(a->v, cpvmult(cpvperp(r1), a->w));
|
||||
cpVect v2_sum = cpvadd(b->v, cpvmult(cpvperp(r2), b->w));
|
||||
|
||||
return cpvsub(v2_sum, v1_sum);
|
||||
}
|
||||
|
||||
static inline cpFloat
|
||||
normal_relative_velocity(cpBody *a, cpBody *b, cpVect r1, cpVect r2, cpVect n){
|
||||
return cpvdot(relative_velocity(a, b, r1, r2), n);
|
||||
}
|
||||
|
||||
static inline void
|
||||
apply_impulse(cpBody *body, cpVect j, cpVect r){
|
||||
body->v = cpvadd(body->v, cpvmult(j, body->m_inv));
|
||||
body->w += body->i_inv*cpvcross(r, j);
|
||||
}
|
||||
|
||||
static inline void
|
||||
apply_impulses(cpBody *a , cpBody *b, cpVect r1, cpVect r2, cpVect j)
|
||||
{
|
||||
apply_impulse(a, cpvneg(j), r1);
|
||||
apply_impulse(b, j, r2);
|
||||
}
|
||||
|
||||
static inline void
|
||||
apply_bias_impulse(cpBody *body, cpVect j, cpVect r)
|
||||
{
|
||||
body->CP_PRIVATE(v_bias) = cpvadd(body->CP_PRIVATE(v_bias), cpvmult(j, body->m_inv));
|
||||
body->CP_PRIVATE(w_bias) += body->i_inv*cpvcross(r, j);
|
||||
}
|
||||
|
||||
static inline void
|
||||
apply_bias_impulses(cpBody *a , cpBody *b, cpVect r1, cpVect r2, cpVect j)
|
||||
{
|
||||
apply_bias_impulse(a, cpvneg(j), r1);
|
||||
apply_bias_impulse(b, j, r2);
|
||||
}
|
||||
|
||||
static inline cpFloat
|
||||
k_scalar_body(cpBody *body, cpVect r, cpVect n)
|
||||
{
|
||||
cpFloat rcn = cpvcross(r, n);
|
||||
return body->m_inv + body->i_inv*rcn*rcn;
|
||||
}
|
||||
|
||||
static inline cpFloat
|
||||
k_scalar(cpBody *a, cpBody *b, cpVect r1, cpVect r2, cpVect n)
|
||||
{
|
||||
cpFloat value = k_scalar_body(a, r1, n) + k_scalar_body(b, r2, n);
|
||||
cpAssertSoft(value != 0.0, "Unsolvable collision or constraint.");
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static inline cpMat2x2
|
||||
k_tensor(cpBody *a, cpBody *b, cpVect r1, cpVect r2)
|
||||
{
|
||||
cpFloat m_sum = a->m_inv + b->m_inv;
|
||||
|
||||
// start with Identity*m_sum
|
||||
cpFloat k11 = m_sum, k12 = 0.0f;
|
||||
cpFloat k21 = 0.0f, k22 = m_sum;
|
||||
|
||||
// add the influence from r1
|
||||
cpFloat a_i_inv = a->i_inv;
|
||||
cpFloat r1xsq = r1.x * r1.x * a_i_inv;
|
||||
cpFloat r1ysq = r1.y * r1.y * a_i_inv;
|
||||
cpFloat r1nxy = -r1.x * r1.y * a_i_inv;
|
||||
k11 += r1ysq; k12 += r1nxy;
|
||||
k21 += r1nxy; k22 += r1xsq;
|
||||
|
||||
// add the influnce from r2
|
||||
cpFloat b_i_inv = b->i_inv;
|
||||
cpFloat r2xsq = r2.x * r2.x * b_i_inv;
|
||||
cpFloat r2ysq = r2.y * r2.y * b_i_inv;
|
||||
cpFloat r2nxy = -r2.x * r2.y * b_i_inv;
|
||||
k11 += r2ysq; k12 += r2nxy;
|
||||
k21 += r2nxy; k22 += r2xsq;
|
||||
|
||||
// invert
|
||||
cpFloat det = k11*k22 - k12*k21;
|
||||
cpAssertSoft(det != 0.0, "Unsolvable constraint.");
|
||||
|
||||
cpFloat det_inv = 1.0f/det;
|
||||
return cpMat2x2New(
|
||||
k22*det_inv, -k12*det_inv,
|
||||
-k21*det_inv, k11*det_inv
|
||||
);
|
||||
}
|
||||
|
||||
static inline cpFloat
|
||||
bias_coef(cpFloat errorBias, cpFloat dt)
|
||||
{
|
||||
return 1.0f - cpfpow(errorBias, dt);
|
||||
}
|
||||
|
|
@ -1,207 +0,0 @@
|
|||
/* 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 2
|
||||
|
||||
/// @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)
|
||||
|
||||
// Get the relative surface velocity of the two shapes in contact.
|
||||
cpVect cpArbiterGetSurfaceVelocity(cpArbiter *arb);
|
||||
|
||||
// Override the relative surface velocity of the two shapes in contact.
|
||||
// By default this is calculated to be the difference of the two
|
||||
// surface velocities clamped to the tangent plane.
|
||||
void cpArbiterSetSurfaceVelocity(cpArbiter *arb, cpVect vr);
|
||||
|
||||
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);
|
||||
|
||||
/// Replace the contact point set for an arbiter.
|
||||
/// This can be a very powerful feature, but use it with caution!
|
||||
void cpArbiterSetContactPointSet(cpArbiter *arb, cpContactPointSet *set);
|
||||
|
||||
/// 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);
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,143 +0,0 @@
|
|||
/* 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 cpBBB cpBB
|
||||
/// Chipmunk's axis-aligned 2D bounding box type along with a few handy routines.
|
||||
/// @{
|
||||
|
||||
/// Chipmunk's axis-aligned 2D bounding box type. (left, bottom, right, top)
|
||||
typedef struct cpBB{
|
||||
cpFloat l, b, r ,t;
|
||||
} cpBB;
|
||||
|
||||
/// Convenience constructor for cpBB structs.
|
||||
static inline cpBB cpBBNew(const cpFloat l, const cpFloat b, const cpFloat r, const cpFloat t)
|
||||
{
|
||||
cpBB bb = {l, b, r, t};
|
||||
return bb;
|
||||
}
|
||||
|
||||
/// Constructs a cpBB for a circle with the given position and radius.
|
||||
static inline cpBB cpBBNewForCircle(const cpVect p, const cpFloat r)
|
||||
{
|
||||
return cpBBNew(p.x - r, p.y - r, p.x + r, p.y + r);
|
||||
}
|
||||
|
||||
/// Returns true if @c a and @c b intersect.
|
||||
static inline cpBool cpBBIntersects(const cpBB a, const cpBB b)
|
||||
{
|
||||
return (a.l <= b.r && b.l <= a.r && a.b <= b.t && b.b <= a.t);
|
||||
}
|
||||
|
||||
/// Returns true if @c other lies completely within @c bb.
|
||||
static inline cpBool cpBBContainsBB(const cpBB bb, const cpBB other)
|
||||
{
|
||||
return (bb.l <= other.l && bb.r >= other.r && bb.b <= other.b && bb.t >= other.t);
|
||||
}
|
||||
|
||||
/// Returns true if @c bb contains @c v.
|
||||
static inline cpBool cpBBContainsVect(const cpBB bb, const cpVect v)
|
||||
{
|
||||
return (bb.l <= v.x && bb.r >= v.x && bb.b <= v.y && bb.t >= v.y);
|
||||
}
|
||||
|
||||
/// Returns a bounding box that holds both bounding boxes.
|
||||
static inline cpBB cpBBMerge(const cpBB a, const cpBB b){
|
||||
return cpBBNew(
|
||||
cpfmin(a.l, b.l),
|
||||
cpfmin(a.b, b.b),
|
||||
cpfmax(a.r, b.r),
|
||||
cpfmax(a.t, b.t)
|
||||
);
|
||||
}
|
||||
|
||||
/// Returns a bounding box that holds both @c bb and @c v.
|
||||
static inline cpBB cpBBExpand(const cpBB bb, const cpVect v){
|
||||
return cpBBNew(
|
||||
cpfmin(bb.l, v.x),
|
||||
cpfmin(bb.b, v.y),
|
||||
cpfmax(bb.r, v.x),
|
||||
cpfmax(bb.t, v.y)
|
||||
);
|
||||
}
|
||||
|
||||
/// Returns the center of a bounding box.
|
||||
static inline cpVect
|
||||
cpBBCenter(cpBB bb)
|
||||
{
|
||||
return cpvlerp(cpv(bb.l, bb.b), cpv(bb.r, bb.t), 0.5f);
|
||||
}
|
||||
|
||||
/// Returns the area of the bounding box.
|
||||
static inline cpFloat cpBBArea(cpBB bb)
|
||||
{
|
||||
return (bb.r - bb.l)*(bb.t - bb.b);
|
||||
}
|
||||
|
||||
/// Merges @c a and @c b and returns the area of the merged bounding box.
|
||||
static inline cpFloat cpBBMergedArea(cpBB a, cpBB b)
|
||||
{
|
||||
return (cpfmax(a.r, b.r) - cpfmin(a.l, b.l))*(cpfmax(a.t, b.t) - cpfmin(a.b, b.b));
|
||||
}
|
||||
|
||||
/// Returns the fraction along the segment query the cpBB is hit. Returns INFINITY if it doesn't hit.
|
||||
static inline cpFloat cpBBSegmentQuery(cpBB bb, cpVect a, cpVect b)
|
||||
{
|
||||
cpFloat idx = 1.0f/(b.x - a.x);
|
||||
cpFloat tx1 = (bb.l == a.x ? -INFINITY : (bb.l - a.x)*idx);
|
||||
cpFloat tx2 = (bb.r == a.x ? INFINITY : (bb.r - a.x)*idx);
|
||||
cpFloat txmin = cpfmin(tx1, tx2);
|
||||
cpFloat txmax = cpfmax(tx1, tx2);
|
||||
|
||||
cpFloat idy = 1.0f/(b.y - a.y);
|
||||
cpFloat ty1 = (bb.b == a.y ? -INFINITY : (bb.b - a.y)*idy);
|
||||
cpFloat ty2 = (bb.t == a.y ? INFINITY : (bb.t - a.y)*idy);
|
||||
cpFloat tymin = cpfmin(ty1, ty2);
|
||||
cpFloat tymax = cpfmax(ty1, ty2);
|
||||
|
||||
if(tymin <= txmax && txmin <= tymax){
|
||||
cpFloat min = cpfmax(txmin, tymin);
|
||||
cpFloat max = cpfmin(txmax, tymax);
|
||||
|
||||
if(0.0 <= max && min <= 1.0) return cpfmax(min, 0.0);
|
||||
}
|
||||
|
||||
return INFINITY;
|
||||
}
|
||||
|
||||
/// Return true if the bounding box intersects the line segment with ends @c a and @c b.
|
||||
static inline cpBool cpBBIntersectsSegment(cpBB bb, cpVect a, cpVect b)
|
||||
{
|
||||
return (cpBBSegmentQuery(bb, a, b) != INFINITY);
|
||||
}
|
||||
|
||||
/// Clamp a vector to a bounding box.
|
||||
static inline cpVect
|
||||
cpBBClampVect(const cpBB bb, const cpVect v)
|
||||
{
|
||||
return cpv(cpfclamp(v.x, bb.l, bb.r), cpfclamp(v.y, bb.b, bb.t));
|
||||
}
|
||||
|
||||
// TODO edge case issue
|
||||
/// Wrap a vector to a bounding box.
|
||||
cpVect cpBBWrapVect(const cpBB bb, const cpVect v); // wrap a vector to a bbox
|
||||
|
||||
///@}
|
||||
|
|
@ -1,251 +0,0 @@
|
|||
/* 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.
|
||||
/// Note: Static bodies are a subtype of rogue bodies.
|
||||
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);
|
||||
|
||||
///@}
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
/* 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 cpPolyShape cpPolyShape
|
||||
/// @{
|
||||
|
||||
/// @private
|
||||
typedef struct cpSplittingPlane {
|
||||
cpVect n;
|
||||
cpFloat d;
|
||||
} cpSplittingPlane;
|
||||
|
||||
/// @private
|
||||
typedef struct cpPolyShape {
|
||||
cpShape shape;
|
||||
|
||||
int numVerts;
|
||||
cpVect *verts, *tVerts;
|
||||
cpSplittingPlane *planes, *tPlanes;
|
||||
|
||||
cpFloat r;
|
||||
} cpPolyShape;
|
||||
|
||||
/// Allocate a polygon shape.
|
||||
cpPolyShape* cpPolyShapeAlloc(void);
|
||||
/// Initialize a polygon shape.
|
||||
/// A convex hull will be created from the vertexes.
|
||||
cpPolyShape* cpPolyShapeInit(cpPolyShape *poly, cpBody *body, int numVerts, const cpVect *verts, cpVect offset);
|
||||
/// Initialize a polygon shape.
|
||||
/// A convex hull will be created from the vertexes.
|
||||
cpPolyShape* cpPolyShapeInit2(cpPolyShape *poly, cpBody *body, int numVerts, const cpVect *verts, cpVect offset, cpFloat radius);
|
||||
/// Allocate and initialize a polygon shape.
|
||||
/// A convex hull will be created from the vertexes.
|
||||
cpShape* cpPolyShapeNew(cpBody *body, int numVerts, const cpVect *verts, cpVect offset);
|
||||
/// Allocate and initialize a polygon shape.
|
||||
/// A convex hull will be created from the vertexes.
|
||||
cpShape* cpPolyShapeNew2(cpBody *body, int numVerts, const cpVect *verts, cpVect offset, cpFloat radius);
|
||||
|
||||
/// Initialize a box shaped polygon shape.
|
||||
cpPolyShape* cpBoxShapeInit(cpPolyShape *poly, cpBody *body, cpFloat width, cpFloat height);
|
||||
/// Initialize an offset box shaped polygon shape.
|
||||
cpPolyShape* cpBoxShapeInit2(cpPolyShape *poly, cpBody *body, cpBB box);
|
||||
/// Initialize an offset box shaped polygon shape.
|
||||
cpPolyShape* cpBoxShapeInit3(cpPolyShape *poly, cpBody *body, cpBB box, cpFloat radius);
|
||||
/// Allocate and initialize a box shaped polygon shape.
|
||||
cpShape* cpBoxShapeNew(cpBody *body, cpFloat width, cpFloat height);
|
||||
/// Allocate and initialize an offset box shaped polygon shape.
|
||||
cpShape* cpBoxShapeNew2(cpBody *body, cpBB box);
|
||||
/// Allocate and initialize an offset box shaped polygon shape.
|
||||
cpShape* cpBoxShapeNew3(cpBody *body, cpBB box, cpFloat radius);
|
||||
|
||||
/// Check that a set of vertexes is convex and has a clockwise winding.
|
||||
/// NOTE: Due to floating point precision issues, hulls created with cpQuickHull() are not guaranteed to validate!
|
||||
cpBool cpPolyValidate(const cpVect *verts, const int numVerts);
|
||||
|
||||
/// Get the number of verts in a polygon shape.
|
||||
int cpPolyShapeGetNumVerts(const cpShape *shape);
|
||||
/// Get the @c ith vertex of a polygon shape.
|
||||
cpVect cpPolyShapeGetVert(const cpShape *shape, int idx);
|
||||
/// Get the radius of a polygon shape.
|
||||
cpFloat cpPolyShapeGetRadius(const cpShape *shape);
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,232 +0,0 @@
|
|||
/* 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 cpShape cpShape
|
||||
/// The cpShape struct defines the shape of a rigid body.
|
||||
/// @{
|
||||
|
||||
typedef struct cpShapeClass cpShapeClass;
|
||||
|
||||
/// Nearest point query info struct.
|
||||
typedef struct cpNearestPointQueryInfo {
|
||||
/// The nearest shape, NULL if no shape was within range.
|
||||
cpShape *shape;
|
||||
/// The closest point on the shape's surface. (in world space coordinates)
|
||||
cpVect p;
|
||||
/// The distance to the point. The distance is negative if the point is inside the shape.
|
||||
cpFloat d;
|
||||
/// The gradient of the signed distance function.
|
||||
/// The same as info.p/info.d, but accurate even for very small values of info.d.
|
||||
cpVect g;
|
||||
} cpNearestPointQueryInfo;
|
||||
|
||||
/// Segment query info struct.
|
||||
typedef struct cpSegmentQueryInfo {
|
||||
/// The shape that was hit, NULL if no collision occured.
|
||||
cpShape *shape;
|
||||
/// The normalized distance along the query segment in the range [0, 1].
|
||||
cpFloat t;
|
||||
/// The normal of the surface hit.
|
||||
cpVect n;
|
||||
} cpSegmentQueryInfo;
|
||||
|
||||
/// @private
|
||||
typedef enum cpShapeType{
|
||||
CP_CIRCLE_SHAPE,
|
||||
CP_SEGMENT_SHAPE,
|
||||
CP_POLY_SHAPE,
|
||||
CP_NUM_SHAPES
|
||||
} cpShapeType;
|
||||
|
||||
typedef cpBB (*cpShapeCacheDataImpl)(cpShape *shape, cpVect p, cpVect rot);
|
||||
typedef void (*cpShapeDestroyImpl)(cpShape *shape);
|
||||
typedef void (*cpShapeNearestPointQueryImpl)(cpShape *shape, cpVect p, cpNearestPointQueryInfo *info);
|
||||
typedef void (*cpShapeSegmentQueryImpl)(cpShape *shape, cpVect a, cpVect b, cpSegmentQueryInfo *info);
|
||||
|
||||
/// @private
|
||||
struct cpShapeClass {
|
||||
cpShapeType type;
|
||||
|
||||
cpShapeCacheDataImpl cacheData;
|
||||
cpShapeDestroyImpl destroy;
|
||||
cpShapeNearestPointQueryImpl nearestPointQuery;
|
||||
cpShapeSegmentQueryImpl segmentQuery;
|
||||
};
|
||||
|
||||
/// Opaque collision shape struct.
|
||||
struct cpShape {
|
||||
CP_PRIVATE(const cpShapeClass *klass);
|
||||
|
||||
/// The rigid body this collision shape is attached to.
|
||||
cpBody *body;
|
||||
|
||||
/// The current bounding box of the shape.
|
||||
cpBB bb;
|
||||
|
||||
/// Sensor flag.
|
||||
/// Sensor shapes call collision callbacks but don't produce collisions.
|
||||
cpBool sensor;
|
||||
|
||||
/// Coefficient of restitution. (elasticity)
|
||||
cpFloat e;
|
||||
/// Coefficient of friction.
|
||||
cpFloat u;
|
||||
/// Surface velocity used when solving for friction.
|
||||
cpVect surface_v;
|
||||
|
||||
/// User definable data pointer.
|
||||
/// Generally this points to your the game object class so you can access it
|
||||
/// when given a cpShape reference in a callback.
|
||||
cpDataPointer data;
|
||||
|
||||
/// Collision type of this shape used when picking collision handlers.
|
||||
cpCollisionType collision_type;
|
||||
/// Group of this shape. Shapes in the same group don't collide.
|
||||
cpGroup group;
|
||||
// Layer bitmask for this shape. Shapes only collide if the bitwise and of their layers is non-zero.
|
||||
cpLayers layers;
|
||||
|
||||
CP_PRIVATE(cpSpace *space);
|
||||
|
||||
CP_PRIVATE(cpShape *next);
|
||||
CP_PRIVATE(cpShape *prev);
|
||||
|
||||
CP_PRIVATE(cpHashValue hashid);
|
||||
};
|
||||
|
||||
/// Destroy a shape.
|
||||
void cpShapeDestroy(cpShape *shape);
|
||||
/// Destroy and Free a shape.
|
||||
void cpShapeFree(cpShape *shape);
|
||||
|
||||
/// Update, cache and return the bounding box of a shape based on the body it's attached to.
|
||||
cpBB cpShapeCacheBB(cpShape *shape);
|
||||
/// Update, cache and return the bounding box of a shape with an explicit transformation.
|
||||
cpBB cpShapeUpdate(cpShape *shape, cpVect pos, cpVect rot);
|
||||
|
||||
/// Test if a point lies within a shape.
|
||||
cpBool cpShapePointQuery(cpShape *shape, cpVect p);
|
||||
|
||||
/// Perform a nearest point query. It finds the closest point on the surface of shape to a specific point.
|
||||
/// The value returned is the distance between the points. A negative distance means the point is inside the shape.
|
||||
cpFloat cpShapeNearestPointQuery(cpShape *shape, cpVect p, cpNearestPointQueryInfo *out);
|
||||
|
||||
/// Perform a segment query against a shape. @c info must be a pointer to a valid cpSegmentQueryInfo structure.
|
||||
cpBool cpShapeSegmentQuery(cpShape *shape, cpVect a, cpVect b, cpSegmentQueryInfo *info);
|
||||
|
||||
/// Get the hit point for a segment query.
|
||||
static inline cpVect cpSegmentQueryHitPoint(const cpVect start, const cpVect end, const cpSegmentQueryInfo info)
|
||||
{
|
||||
return cpvlerp(start, end, info.t);
|
||||
}
|
||||
|
||||
/// Get the hit distance for a segment query.
|
||||
static inline cpFloat cpSegmentQueryHitDist(const cpVect start, const cpVect end, const cpSegmentQueryInfo info)
|
||||
{
|
||||
return cpvdist(start, end)*info.t;
|
||||
}
|
||||
|
||||
#define CP_DefineShapeStructGetter(type, member, name) \
|
||||
static inline type cpShapeGet##name(const cpShape *shape){return shape->member;}
|
||||
|
||||
#define CP_DefineShapeStructSetter(type, member, name, activates) \
|
||||
static inline void cpShapeSet##name(cpShape *shape, type value){ \
|
||||
if(activates && shape->body) cpBodyActivate(shape->body); \
|
||||
shape->member = value; \
|
||||
}
|
||||
|
||||
#define CP_DefineShapeStructProperty(type, member, name, activates) \
|
||||
CP_DefineShapeStructGetter(type, member, name) \
|
||||
CP_DefineShapeStructSetter(type, member, name, activates)
|
||||
|
||||
CP_DefineShapeStructGetter(cpSpace*, CP_PRIVATE(space), Space)
|
||||
|
||||
CP_DefineShapeStructGetter(cpBody*, body, Body)
|
||||
void cpShapeSetBody(cpShape *shape, cpBody *body);
|
||||
|
||||
CP_DefineShapeStructGetter(cpBB, bb, BB)
|
||||
CP_DefineShapeStructProperty(cpBool, sensor, Sensor, cpTrue)
|
||||
CP_DefineShapeStructProperty(cpFloat, e, Elasticity, cpFalse)
|
||||
CP_DefineShapeStructProperty(cpFloat, u, Friction, cpTrue)
|
||||
CP_DefineShapeStructProperty(cpVect, surface_v, SurfaceVelocity, cpTrue)
|
||||
CP_DefineShapeStructProperty(cpDataPointer, data, UserData, cpFalse)
|
||||
CP_DefineShapeStructProperty(cpCollisionType, collision_type, CollisionType, cpTrue)
|
||||
CP_DefineShapeStructProperty(cpGroup, group, Group, cpTrue)
|
||||
CP_DefineShapeStructProperty(cpLayers, layers, Layers, cpTrue)
|
||||
|
||||
/// When initializing a shape, it's hash value comes from a counter.
|
||||
/// Because the hash value may affect iteration order, you can reset the shape ID counter
|
||||
/// when recreating a space. This will make the simulation be deterministic.
|
||||
void cpResetShapeIdCounter(void);
|
||||
|
||||
#define CP_DeclareShapeGetter(struct, type, name) type struct##Get##name(const cpShape *shape)
|
||||
|
||||
/// @}
|
||||
/// @defgroup cpCircleShape cpCircleShape
|
||||
|
||||
/// @private
|
||||
typedef struct cpCircleShape {
|
||||
cpShape shape;
|
||||
|
||||
cpVect c, tc;
|
||||
cpFloat r;
|
||||
} cpCircleShape;
|
||||
|
||||
/// Allocate a circle shape.
|
||||
cpCircleShape* cpCircleShapeAlloc(void);
|
||||
/// Initialize a circle shape.
|
||||
cpCircleShape* cpCircleShapeInit(cpCircleShape *circle, cpBody *body, cpFloat radius, cpVect offset);
|
||||
/// Allocate and initialize a circle shape.
|
||||
cpShape* cpCircleShapeNew(cpBody *body, cpFloat radius, cpVect offset);
|
||||
|
||||
CP_DeclareShapeGetter(cpCircleShape, cpVect, Offset);
|
||||
CP_DeclareShapeGetter(cpCircleShape, cpFloat, Radius);
|
||||
|
||||
/// @}
|
||||
/// @defgroup cpSegmentShape cpSegmentShape
|
||||
|
||||
/// @private
|
||||
typedef struct cpSegmentShape {
|
||||
cpShape shape;
|
||||
|
||||
cpVect a, b, n;
|
||||
cpVect ta, tb, tn;
|
||||
cpFloat r;
|
||||
|
||||
cpVect a_tangent, b_tangent;
|
||||
} cpSegmentShape;
|
||||
|
||||
/// Allocate a segment shape.
|
||||
cpSegmentShape* cpSegmentShapeAlloc(void);
|
||||
/// Initialize a segment shape.
|
||||
cpSegmentShape* cpSegmentShapeInit(cpSegmentShape *seg, cpBody *body, cpVect a, cpVect b, cpFloat radius);
|
||||
/// Allocate and initialize a segment shape.
|
||||
cpShape* cpSegmentShapeNew(cpBody *body, cpVect a, cpVect b, cpFloat radius);
|
||||
|
||||
/// Let Chipmunk know about the geometry of adjacent segments to avoid colliding with endcaps.
|
||||
void cpSegmentShapeSetNeighbors(cpShape *shape, cpVect prev, cpVect next);
|
||||
|
||||
CP_DeclareShapeGetter(cpSegmentShape, cpVect, A);
|
||||
CP_DeclareShapeGetter(cpSegmentShape, cpVect, B);
|
||||
CP_DeclareShapeGetter(cpSegmentShape, cpVect, Normal);
|
||||
CP_DeclareShapeGetter(cpSegmentShape, cpFloat, Radius);
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,283 +0,0 @@
|
|||
/* 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 cpSpace cpSpace
|
||||
/// @{
|
||||
|
||||
typedef struct cpContactBufferHeader cpContactBufferHeader;
|
||||
typedef void (*cpSpaceArbiterApplyImpulseFunc)(cpArbiter *arb);
|
||||
|
||||
/// Basic Unit of Simulation in Chipmunk
|
||||
struct cpSpace {
|
||||
/// Number of iterations to use in the impulse solver to solve contacts.
|
||||
int iterations;
|
||||
|
||||
/// Gravity to pass to rigid bodies when integrating velocity.
|
||||
cpVect gravity;
|
||||
|
||||
/// Damping rate expressed as the fraction of velocity bodies retain each second.
|
||||
/// A value of 0.9 would mean that each body's velocity will drop 10% per second.
|
||||
/// The default value is 1.0, meaning no damping is applied.
|
||||
/// @note This damping value is different than those of cpDampedSpring and cpDampedRotarySpring.
|
||||
cpFloat damping;
|
||||
|
||||
/// Speed threshold for a body to be considered idle.
|
||||
/// The default value of 0 means to let the space guess a good threshold based on gravity.
|
||||
cpFloat idleSpeedThreshold;
|
||||
|
||||
/// Time a group of bodies must remain idle in order to fall asleep.
|
||||
/// Enabling sleeping also implicitly enables the the contact graph.
|
||||
/// The default value of INFINITY disables the sleeping algorithm.
|
||||
cpFloat sleepTimeThreshold;
|
||||
|
||||
/// Amount of encouraged penetration between colliding shapes.
|
||||
/// Used to reduce oscillating contacts and keep the collision cache warm.
|
||||
/// Defaults to 0.1. If you have poor simulation quality,
|
||||
/// increase this number as much as possible without allowing visible amounts of overlap.
|
||||
cpFloat collisionSlop;
|
||||
|
||||
/// Determines how fast overlapping shapes are pushed apart.
|
||||
/// Expressed as a fraction of the error remaining after each second.
|
||||
/// Defaults to pow(1.0 - 0.1, 60.0) meaning that Chipmunk fixes 10% of overlap each frame at 60Hz.
|
||||
cpFloat collisionBias;
|
||||
|
||||
/// Number of frames that contact information should persist.
|
||||
/// Defaults to 3. There is probably never a reason to change this value.
|
||||
cpTimestamp collisionPersistence;
|
||||
|
||||
/// Rebuild the contact graph during each step. Must be enabled to use the cpBodyEachArbiter() function.
|
||||
/// Disabled by default for a small performance boost. Enabled implicitly when the sleeping feature is enabled.
|
||||
cpBool enableContactGraph;
|
||||
|
||||
/// User definable data pointer.
|
||||
/// Generally this points to your game's controller or game state
|
||||
/// class so you can access it when given a cpSpace reference in a callback.
|
||||
cpDataPointer data;
|
||||
|
||||
/// The designated static body for this space.
|
||||
/// You can modify this body, or replace it with your own static body.
|
||||
/// By default it points to a statically allocated cpBody in the cpSpace struct.
|
||||
cpBody *staticBody;
|
||||
|
||||
CP_PRIVATE(cpTimestamp stamp);
|
||||
CP_PRIVATE(cpFloat curr_dt);
|
||||
|
||||
CP_PRIVATE(cpArray *bodies);
|
||||
CP_PRIVATE(cpArray *rousedBodies);
|
||||
CP_PRIVATE(cpArray *sleepingComponents);
|
||||
|
||||
CP_PRIVATE(cpSpatialIndex *staticShapes);
|
||||
CP_PRIVATE(cpSpatialIndex *activeShapes);
|
||||
|
||||
CP_PRIVATE(cpArray *arbiters);
|
||||
CP_PRIVATE(cpContactBufferHeader *contactBuffersHead);
|
||||
CP_PRIVATE(cpHashSet *cachedArbiters);
|
||||
CP_PRIVATE(cpArray *pooledArbiters);
|
||||
CP_PRIVATE(cpArray *constraints);
|
||||
|
||||
CP_PRIVATE(cpArray *allocatedBuffers);
|
||||
CP_PRIVATE(int locked);
|
||||
|
||||
CP_PRIVATE(cpHashSet *collisionHandlers);
|
||||
CP_PRIVATE(cpCollisionHandler defaultHandler);
|
||||
|
||||
CP_PRIVATE(cpBool skipPostStep);
|
||||
CP_PRIVATE(cpArray *postStepCallbacks);
|
||||
|
||||
CP_PRIVATE(cpBody _staticBody);
|
||||
};
|
||||
|
||||
/// Allocate a cpSpace.
|
||||
cpSpace* cpSpaceAlloc(void);
|
||||
/// Initialize a cpSpace.
|
||||
cpSpace* cpSpaceInit(cpSpace *space);
|
||||
/// Allocate and initialize a cpSpace.
|
||||
cpSpace* cpSpaceNew(void);
|
||||
|
||||
/// Destroy a cpSpace.
|
||||
void cpSpaceDestroy(cpSpace *space);
|
||||
/// Destroy and free a cpSpace.
|
||||
void cpSpaceFree(cpSpace *space);
|
||||
|
||||
#define CP_DefineSpaceStructGetter(type, member, name) \
|
||||
static inline type cpSpaceGet##name(const cpSpace *space){return space->member;}
|
||||
|
||||
#define CP_DefineSpaceStructSetter(type, member, name) \
|
||||
static inline void cpSpaceSet##name(cpSpace *space, type value){space->member = value;}
|
||||
|
||||
#define CP_DefineSpaceStructProperty(type, member, name) \
|
||||
CP_DefineSpaceStructGetter(type, member, name) \
|
||||
CP_DefineSpaceStructSetter(type, member, name)
|
||||
|
||||
CP_DefineSpaceStructProperty(int, iterations, Iterations)
|
||||
CP_DefineSpaceStructProperty(cpVect, gravity, Gravity)
|
||||
CP_DefineSpaceStructProperty(cpFloat, damping, Damping)
|
||||
CP_DefineSpaceStructProperty(cpFloat, idleSpeedThreshold, IdleSpeedThreshold)
|
||||
CP_DefineSpaceStructProperty(cpFloat, sleepTimeThreshold, SleepTimeThreshold)
|
||||
CP_DefineSpaceStructProperty(cpFloat, collisionSlop, CollisionSlop)
|
||||
CP_DefineSpaceStructProperty(cpFloat, collisionBias, CollisionBias)
|
||||
CP_DefineSpaceStructProperty(cpTimestamp, collisionPersistence, CollisionPersistence)
|
||||
CP_DefineSpaceStructProperty(cpBool, enableContactGraph, EnableContactGraph)
|
||||
CP_DefineSpaceStructProperty(cpDataPointer, data, UserData)
|
||||
CP_DefineSpaceStructGetter(cpBody*, staticBody, StaticBody)
|
||||
CP_DefineSpaceStructGetter(cpFloat, CP_PRIVATE(curr_dt), CurrentTimeStep)
|
||||
|
||||
/// returns true from inside a callback and objects cannot be added/removed.
|
||||
static inline cpBool
|
||||
cpSpaceIsLocked(cpSpace *space)
|
||||
{
|
||||
return space->CP_PRIVATE(locked);
|
||||
}
|
||||
|
||||
/// Set a default collision handler for this space.
|
||||
/// The default collision handler is invoked for each colliding pair of shapes
|
||||
/// that isn't explicitly handled by a specific collision handler.
|
||||
/// You can pass NULL for any function you don't want to implement.
|
||||
void cpSpaceSetDefaultCollisionHandler(
|
||||
cpSpace *space,
|
||||
cpCollisionBeginFunc begin,
|
||||
cpCollisionPreSolveFunc preSolve,
|
||||
cpCollisionPostSolveFunc postSolve,
|
||||
cpCollisionSeparateFunc separate,
|
||||
void *data
|
||||
);
|
||||
|
||||
/// Set a collision handler to be used whenever the two shapes with the given collision types collide.
|
||||
/// You can pass NULL for any function you don't want to implement.
|
||||
void cpSpaceAddCollisionHandler(
|
||||
cpSpace *space,
|
||||
cpCollisionType a, cpCollisionType b,
|
||||
cpCollisionBeginFunc begin,
|
||||
cpCollisionPreSolveFunc preSolve,
|
||||
cpCollisionPostSolveFunc postSolve,
|
||||
cpCollisionSeparateFunc separate,
|
||||
void *data
|
||||
);
|
||||
|
||||
/// Unset a collision handler.
|
||||
void cpSpaceRemoveCollisionHandler(cpSpace *space, cpCollisionType a, cpCollisionType b);
|
||||
|
||||
/// Add a collision shape to the simulation.
|
||||
/// If the shape is attached to a static body, it will be added as a static shape.
|
||||
cpShape* cpSpaceAddShape(cpSpace *space, cpShape *shape);
|
||||
/// Explicity add a shape as a static shape to the simulation.
|
||||
cpShape* cpSpaceAddStaticShape(cpSpace *space, cpShape *shape);
|
||||
/// Add a rigid body to the simulation.
|
||||
cpBody* cpSpaceAddBody(cpSpace *space, cpBody *body);
|
||||
/// Add a constraint to the simulation.
|
||||
cpConstraint* cpSpaceAddConstraint(cpSpace *space, cpConstraint *constraint);
|
||||
|
||||
/// Remove a collision shape from the simulation.
|
||||
void cpSpaceRemoveShape(cpSpace *space, cpShape *shape);
|
||||
/// Remove a collision shape added using cpSpaceAddStaticShape() from the simulation.
|
||||
void cpSpaceRemoveStaticShape(cpSpace *space, cpShape *shape);
|
||||
/// Remove a rigid body from the simulation.
|
||||
void cpSpaceRemoveBody(cpSpace *space, cpBody *body);
|
||||
/// Remove a constraint from the simulation.
|
||||
void cpSpaceRemoveConstraint(cpSpace *space, cpConstraint *constraint);
|
||||
|
||||
/// Test if a collision shape has been added to the space.
|
||||
cpBool cpSpaceContainsShape(cpSpace *space, cpShape *shape);
|
||||
/// Test if a rigid body has been added to the space.
|
||||
cpBool cpSpaceContainsBody(cpSpace *space, cpBody *body);
|
||||
/// Test if a constraint has been added to the space.
|
||||
cpBool cpSpaceContainsConstraint(cpSpace *space, cpConstraint *constraint);
|
||||
|
||||
/// Convert a dynamic rogue body to a static one.
|
||||
/// If the body is active, you must remove it from the space first.
|
||||
void cpSpaceConvertBodyToStatic(cpSpace *space, cpBody *body);
|
||||
/// Convert a body to a dynamic rogue body.
|
||||
/// If you want the body to be active after the transition, you must add it to the space also.
|
||||
void cpSpaceConvertBodyToDynamic(cpSpace *space, cpBody *body, cpFloat mass, cpFloat moment);
|
||||
|
||||
/// Post Step callback function type.
|
||||
typedef void (*cpPostStepFunc)(cpSpace *space, void *key, void *data);
|
||||
/// Schedule a post-step callback to be called when cpSpaceStep() finishes.
|
||||
/// You can only register one callback per unique value for @c key.
|
||||
/// Returns true only if @c key has never been scheduled before.
|
||||
/// It's possible to pass @c NULL for @c func if you only want to mark @c key as being used.
|
||||
cpBool cpSpaceAddPostStepCallback(cpSpace *space, cpPostStepFunc func, void *key, void *data);
|
||||
|
||||
/// Point query callback function type.
|
||||
typedef void (*cpSpacePointQueryFunc)(cpShape *shape, void *data);
|
||||
/// Query the space at a point and call @c func for each shape found.
|
||||
void cpSpacePointQuery(cpSpace *space, cpVect point, cpLayers layers, cpGroup group, cpSpacePointQueryFunc func, void *data);
|
||||
/// Query the space at a point and return the first shape found. Returns NULL if no shapes were found.
|
||||
cpShape *cpSpacePointQueryFirst(cpSpace *space, cpVect point, cpLayers layers, cpGroup group);
|
||||
|
||||
/// Nearest point query callback function type.
|
||||
typedef void (*cpSpaceNearestPointQueryFunc)(cpShape *shape, cpFloat distance, cpVect point, void *data);
|
||||
/// Query the space at a point and call @c func for each shape found.
|
||||
void cpSpaceNearestPointQuery(cpSpace *space, cpVect point, cpFloat maxDistance, cpLayers layers, cpGroup group, cpSpaceNearestPointQueryFunc func, void *data);
|
||||
/// Query the space at a point and return the nearest shape found. Returns NULL if no shapes were found.
|
||||
cpShape *cpSpaceNearestPointQueryNearest(cpSpace *space, cpVect point, cpFloat maxDistance, cpLayers layers, cpGroup group, cpNearestPointQueryInfo *out);
|
||||
|
||||
/// Segment query callback function type.
|
||||
typedef void (*cpSpaceSegmentQueryFunc)(cpShape *shape, cpFloat t, cpVect n, void *data);
|
||||
/// Perform a directed line segment query (like a raycast) against the space calling @c func for each shape intersected.
|
||||
void cpSpaceSegmentQuery(cpSpace *space, cpVect start, cpVect end, cpLayers layers, cpGroup group, cpSpaceSegmentQueryFunc func, void *data);
|
||||
/// Perform a directed line segment query (like a raycast) against the space and return the first shape hit. Returns NULL if no shapes were hit.
|
||||
cpShape *cpSpaceSegmentQueryFirst(cpSpace *space, cpVect start, cpVect end, cpLayers layers, cpGroup group, cpSegmentQueryInfo *out);
|
||||
|
||||
/// Rectangle Query callback function type.
|
||||
typedef void (*cpSpaceBBQueryFunc)(cpShape *shape, void *data);
|
||||
/// Perform a fast rectangle query on the space calling @c func for each shape found.
|
||||
/// Only the shape's bounding boxes are checked for overlap, not their full shape.
|
||||
void cpSpaceBBQuery(cpSpace *space, cpBB bb, cpLayers layers, cpGroup group, cpSpaceBBQueryFunc func, void *data);
|
||||
|
||||
/// Shape query callback function type.
|
||||
typedef void (*cpSpaceShapeQueryFunc)(cpShape *shape, cpContactPointSet *points, void *data);
|
||||
/// Query a space for any shapes overlapping the given shape and call @c func for each shape found.
|
||||
cpBool cpSpaceShapeQuery(cpSpace *space, cpShape *shape, cpSpaceShapeQueryFunc func, void *data);
|
||||
|
||||
/// Call cpBodyActivate() for any shape that is overlaps the given shape.
|
||||
void cpSpaceActivateShapesTouchingShape(cpSpace *space, cpShape *shape);
|
||||
|
||||
|
||||
/// Space/body iterator callback function type.
|
||||
typedef void (*cpSpaceBodyIteratorFunc)(cpBody *body, void *data);
|
||||
/// Call @c func for each body in the space.
|
||||
void cpSpaceEachBody(cpSpace *space, cpSpaceBodyIteratorFunc func, void *data);
|
||||
|
||||
/// Space/body iterator callback function type.
|
||||
typedef void (*cpSpaceShapeIteratorFunc)(cpShape *shape, void *data);
|
||||
/// Call @c func for each shape in the space.
|
||||
void cpSpaceEachShape(cpSpace *space, cpSpaceShapeIteratorFunc func, void *data);
|
||||
|
||||
/// Space/constraint iterator callback function type.
|
||||
typedef void (*cpSpaceConstraintIteratorFunc)(cpConstraint *constraint, void *data);
|
||||
/// Call @c func for each shape in the space.
|
||||
void cpSpaceEachConstraint(cpSpace *space, cpSpaceConstraintIteratorFunc func, void *data);
|
||||
|
||||
/// Update the collision detection info for the static shapes in the space.
|
||||
void cpSpaceReindexStatic(cpSpace *space);
|
||||
/// Update the collision detection data for a specific shape in the space.
|
||||
void cpSpaceReindexShape(cpSpace *space, cpShape *shape);
|
||||
/// Update the collision detection data for all shapes attached to a body.
|
||||
void cpSpaceReindexShapesForBody(cpSpace *space, cpBody *body);
|
||||
|
||||
/// Switch the space to use a spatial has as it's spatial index.
|
||||
void cpSpaceUseSpatialHash(cpSpace *space, cpFloat dim, int count);
|
||||
|
||||
/// Step the space forward in time by @c dt.
|
||||
void cpSpaceStep(cpSpace *space, cpFloat dt);
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,227 +0,0 @@
|
|||
/* Copyright (c) 2010 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 cpSpatialIndex cpSpatialIndex
|
||||
|
||||
Spatial indexes are data structures that are used to accelerate collision detection
|
||||
and spatial queries. Chipmunk provides a number of spatial index algorithms to pick from
|
||||
and they are programmed in a generic way so that you can use them for holding more than
|
||||
just cpShape structs.
|
||||
|
||||
It works by using @c void pointers to the objects you add and using a callback to ask your code
|
||||
for bounding boxes when it needs them. Several types of queries can be performed an index as well
|
||||
as reindexing and full collision information. All communication to the spatial indexes is performed
|
||||
through callback functions.
|
||||
|
||||
Spatial indexes should be treated as opaque structs.
|
||||
This meanns you shouldn't be reading any of the struct fields.
|
||||
@{
|
||||
*/
|
||||
|
||||
//MARK: Spatial Index
|
||||
|
||||
/// Spatial index bounding box callback function type.
|
||||
/// The spatial index calls this function and passes you a pointer to an object you added
|
||||
/// when it needs to get the bounding box associated with that object.
|
||||
typedef cpBB (*cpSpatialIndexBBFunc)(void *obj);
|
||||
/// Spatial index/object iterator callback function type.
|
||||
typedef void (*cpSpatialIndexIteratorFunc)(void *obj, void *data);
|
||||
/// Spatial query callback function type.
|
||||
typedef cpCollisionID (*cpSpatialIndexQueryFunc)(void *obj1, void *obj2, cpCollisionID id, void *data);
|
||||
/// Spatial segment query callback function type.
|
||||
typedef cpFloat (*cpSpatialIndexSegmentQueryFunc)(void *obj1, void *obj2, void *data);
|
||||
|
||||
|
||||
typedef struct cpSpatialIndexClass cpSpatialIndexClass;
|
||||
typedef struct cpSpatialIndex cpSpatialIndex;
|
||||
|
||||
/// @private
|
||||
struct cpSpatialIndex {
|
||||
cpSpatialIndexClass *klass;
|
||||
|
||||
cpSpatialIndexBBFunc bbfunc;
|
||||
|
||||
cpSpatialIndex *staticIndex, *dynamicIndex;
|
||||
};
|
||||
|
||||
|
||||
//MARK: Spatial Hash
|
||||
|
||||
typedef struct cpSpaceHash cpSpaceHash;
|
||||
|
||||
/// Allocate a spatial hash.
|
||||
cpSpaceHash* cpSpaceHashAlloc(void);
|
||||
/// Initialize a spatial hash.
|
||||
cpSpatialIndex* cpSpaceHashInit(cpSpaceHash *hash, cpFloat celldim, int numcells, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
/// Allocate and initialize a spatial hash.
|
||||
cpSpatialIndex* cpSpaceHashNew(cpFloat celldim, int cells, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
|
||||
/// Change the cell dimensions and table size of the spatial hash to tune it.
|
||||
/// The cell dimensions should roughly match the average size of your objects
|
||||
/// and the table size should be ~10 larger than the number of objects inserted.
|
||||
/// Some trial and error is required to find the optimum numbers for efficiency.
|
||||
void cpSpaceHashResize(cpSpaceHash *hash, cpFloat celldim, int numcells);
|
||||
|
||||
//MARK: AABB Tree
|
||||
|
||||
typedef struct cpBBTree cpBBTree;
|
||||
|
||||
/// Allocate a bounding box tree.
|
||||
cpBBTree* cpBBTreeAlloc(void);
|
||||
/// Initialize a bounding box tree.
|
||||
cpSpatialIndex* cpBBTreeInit(cpBBTree *tree, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
/// Allocate and initialize a bounding box tree.
|
||||
cpSpatialIndex* cpBBTreeNew(cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
|
||||
/// Perform a static top down optimization of the tree.
|
||||
void cpBBTreeOptimize(cpSpatialIndex *index);
|
||||
|
||||
/// Bounding box tree velocity callback function.
|
||||
/// This function should return an estimate for the object's velocity.
|
||||
typedef cpVect (*cpBBTreeVelocityFunc)(void *obj);
|
||||
/// Set the velocity function for the bounding box tree to enable temporal coherence.
|
||||
void cpBBTreeSetVelocityFunc(cpSpatialIndex *index, cpBBTreeVelocityFunc func);
|
||||
|
||||
//MARK: Single Axis Sweep
|
||||
|
||||
typedef struct cpSweep1D cpSweep1D;
|
||||
|
||||
/// Allocate a 1D sort and sweep broadphase.
|
||||
cpSweep1D* cpSweep1DAlloc(void);
|
||||
/// Initialize a 1D sort and sweep broadphase.
|
||||
cpSpatialIndex* cpSweep1DInit(cpSweep1D *sweep, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
/// Allocate and initialize a 1D sort and sweep broadphase.
|
||||
cpSpatialIndex* cpSweep1DNew(cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
|
||||
//MARK: Spatial Index Implementation
|
||||
|
||||
typedef void (*cpSpatialIndexDestroyImpl)(cpSpatialIndex *index);
|
||||
|
||||
typedef int (*cpSpatialIndexCountImpl)(cpSpatialIndex *index);
|
||||
typedef void (*cpSpatialIndexEachImpl)(cpSpatialIndex *index, cpSpatialIndexIteratorFunc func, void *data);
|
||||
|
||||
typedef cpBool (*cpSpatialIndexContainsImpl)(cpSpatialIndex *index, void *obj, cpHashValue hashid);
|
||||
typedef void (*cpSpatialIndexInsertImpl)(cpSpatialIndex *index, void *obj, cpHashValue hashid);
|
||||
typedef void (*cpSpatialIndexRemoveImpl)(cpSpatialIndex *index, void *obj, cpHashValue hashid);
|
||||
|
||||
typedef void (*cpSpatialIndexReindexImpl)(cpSpatialIndex *index);
|
||||
typedef void (*cpSpatialIndexReindexObjectImpl)(cpSpatialIndex *index, void *obj, cpHashValue hashid);
|
||||
typedef void (*cpSpatialIndexReindexQueryImpl)(cpSpatialIndex *index, cpSpatialIndexQueryFunc func, void *data);
|
||||
|
||||
typedef void (*cpSpatialIndexQueryImpl)(cpSpatialIndex *index, void *obj, cpBB bb, cpSpatialIndexQueryFunc func, void *data);
|
||||
typedef void (*cpSpatialIndexSegmentQueryImpl)(cpSpatialIndex *index, void *obj, cpVect a, cpVect b, cpFloat t_exit, cpSpatialIndexSegmentQueryFunc func, void *data);
|
||||
|
||||
struct cpSpatialIndexClass {
|
||||
cpSpatialIndexDestroyImpl destroy;
|
||||
|
||||
cpSpatialIndexCountImpl count;
|
||||
cpSpatialIndexEachImpl each;
|
||||
|
||||
cpSpatialIndexContainsImpl contains;
|
||||
cpSpatialIndexInsertImpl insert;
|
||||
cpSpatialIndexRemoveImpl remove;
|
||||
|
||||
cpSpatialIndexReindexImpl reindex;
|
||||
cpSpatialIndexReindexObjectImpl reindexObject;
|
||||
cpSpatialIndexReindexQueryImpl reindexQuery;
|
||||
|
||||
cpSpatialIndexQueryImpl query;
|
||||
cpSpatialIndexSegmentQueryImpl segmentQuery;
|
||||
};
|
||||
|
||||
/// Destroy and free a spatial index.
|
||||
void cpSpatialIndexFree(cpSpatialIndex *index);
|
||||
/// Collide the objects in @c dynamicIndex against the objects in @c staticIndex using the query callback function.
|
||||
void cpSpatialIndexCollideStatic(cpSpatialIndex *dynamicIndex, cpSpatialIndex *staticIndex, cpSpatialIndexQueryFunc func, void *data);
|
||||
|
||||
/// Destroy a spatial index.
|
||||
static inline void cpSpatialIndexDestroy(cpSpatialIndex *index)
|
||||
{
|
||||
if(index->klass) index->klass->destroy(index);
|
||||
}
|
||||
|
||||
/// Get the number of objects in the spatial index.
|
||||
static inline int cpSpatialIndexCount(cpSpatialIndex *index)
|
||||
{
|
||||
return index->klass->count(index);
|
||||
}
|
||||
|
||||
/// Iterate the objects in the spatial index. @c func will be called once for each object.
|
||||
static inline void cpSpatialIndexEach(cpSpatialIndex *index, cpSpatialIndexIteratorFunc func, void *data)
|
||||
{
|
||||
index->klass->each(index, func, data);
|
||||
}
|
||||
|
||||
/// Returns true if the spatial index contains the given object.
|
||||
/// Most spatial indexes use hashed storage, so you must provide a hash value too.
|
||||
static inline cpBool cpSpatialIndexContains(cpSpatialIndex *index, void *obj, cpHashValue hashid)
|
||||
{
|
||||
return index->klass->contains(index, obj, hashid);
|
||||
}
|
||||
|
||||
/// Add an object to a spatial index.
|
||||
/// Most spatial indexes use hashed storage, so you must provide a hash value too.
|
||||
static inline void cpSpatialIndexInsert(cpSpatialIndex *index, void *obj, cpHashValue hashid)
|
||||
{
|
||||
index->klass->insert(index, obj, hashid);
|
||||
}
|
||||
|
||||
/// Remove an object from a spatial index.
|
||||
/// Most spatial indexes use hashed storage, so you must provide a hash value too.
|
||||
static inline void cpSpatialIndexRemove(cpSpatialIndex *index, void *obj, cpHashValue hashid)
|
||||
{
|
||||
index->klass->remove(index, obj, hashid);
|
||||
}
|
||||
|
||||
/// Perform a full reindex of a spatial index.
|
||||
static inline void cpSpatialIndexReindex(cpSpatialIndex *index)
|
||||
{
|
||||
index->klass->reindex(index);
|
||||
}
|
||||
|
||||
/// Reindex a single object in the spatial index.
|
||||
static inline void cpSpatialIndexReindexObject(cpSpatialIndex *index, void *obj, cpHashValue hashid)
|
||||
{
|
||||
index->klass->reindexObject(index, obj, hashid);
|
||||
}
|
||||
|
||||
/// Perform a rectangle query against the spatial index, calling @c func for each potential match.
|
||||
static inline void cpSpatialIndexQuery(cpSpatialIndex *index, void *obj, cpBB bb, cpSpatialIndexQueryFunc func, void *data)
|
||||
{
|
||||
index->klass->query(index, obj, bb, func, data);
|
||||
}
|
||||
|
||||
/// Perform a segment query against the spatial index, calling @c func for each potential match.
|
||||
static inline void cpSpatialIndexSegmentQuery(cpSpatialIndex *index, void *obj, cpVect a, cpVect b, cpFloat t_exit, cpSpatialIndexSegmentQueryFunc func, void *data)
|
||||
{
|
||||
index->klass->segmentQuery(index, obj, a, b, t_exit, func, data);
|
||||
}
|
||||
|
||||
/// Simultaneously reindex and find all colliding objects.
|
||||
/// @c func will be called once for each potentially overlapping pair of objects found.
|
||||
/// If the spatial index was initialized with a static index, it will collide it's objects against that as well.
|
||||
static inline void cpSpatialIndexReindexQuery(cpSpatialIndex *index, cpSpatialIndexQueryFunc func, void *data)
|
||||
{
|
||||
index->klass->reindexQuery(index, func, data);
|
||||
}
|
||||
|
||||
///@}
|
||||
|
|
@ -1,213 +0,0 @@
|
|||
/* 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 cpVect cpVect
|
||||
/// Chipmunk's 2D vector type along with a handy 2D vector math lib.
|
||||
/// @{
|
||||
|
||||
/// Constant for the zero vector.
|
||||
static const cpVect cpvzero = {0.0f,0.0f};
|
||||
|
||||
/// Convenience constructor for cpVect structs.
|
||||
static inline cpVect cpv(const cpFloat x, const cpFloat y)
|
||||
{
|
||||
cpVect v = {x, y};
|
||||
return v;
|
||||
}
|
||||
|
||||
/// Spherical linearly interpolate between v1 and v2.
|
||||
cpVect cpvslerp(const cpVect v1, const cpVect v2, const cpFloat t);
|
||||
|
||||
/// Spherical linearly interpolate between v1 towards v2 by no more than angle a radians
|
||||
cpVect cpvslerpconst(const cpVect v1, const cpVect v2, const cpFloat a);
|
||||
|
||||
/// Returns a string representation of v. Intended mostly for debugging purposes and not production use.
|
||||
/// @attention The string points to a static local and is reset every time the function is called.
|
||||
/// If you want to print more than one vector you will have to split up your printing onto separate lines.
|
||||
char* cpvstr(const cpVect v);
|
||||
|
||||
/// Check if two vectors are equal. (Be careful when comparing floating point numbers!)
|
||||
static inline cpBool cpveql(const cpVect v1, const cpVect v2)
|
||||
{
|
||||
return (v1.x == v2.x && v1.y == v2.y);
|
||||
}
|
||||
|
||||
/// Add two vectors
|
||||
static inline cpVect cpvadd(const cpVect v1, const cpVect v2)
|
||||
{
|
||||
return cpv(v1.x + v2.x, v1.y + v2.y);
|
||||
}
|
||||
|
||||
/// Subtract two vectors.
|
||||
static inline cpVect cpvsub(const cpVect v1, const cpVect v2)
|
||||
{
|
||||
return cpv(v1.x - v2.x, v1.y - v2.y);
|
||||
}
|
||||
|
||||
/// Negate a vector.
|
||||
static inline cpVect cpvneg(const cpVect v)
|
||||
{
|
||||
return cpv(-v.x, -v.y);
|
||||
}
|
||||
|
||||
/// Scalar multiplication.
|
||||
static inline cpVect cpvmult(const cpVect v, const cpFloat s)
|
||||
{
|
||||
return cpv(v.x*s, v.y*s);
|
||||
}
|
||||
|
||||
/// Vector dot product.
|
||||
static inline cpFloat cpvdot(const cpVect v1, const cpVect v2)
|
||||
{
|
||||
return v1.x*v2.x + v1.y*v2.y;
|
||||
}
|
||||
|
||||
/// 2D vector cross product analog.
|
||||
/// The cross product of 2D vectors results in a 3D vector with only a z component.
|
||||
/// This function returns the magnitude of the z value.
|
||||
static inline cpFloat cpvcross(const cpVect v1, const cpVect v2)
|
||||
{
|
||||
return v1.x*v2.y - v1.y*v2.x;
|
||||
}
|
||||
|
||||
/// Returns a perpendicular vector. (90 degree rotation)
|
||||
static inline cpVect cpvperp(const cpVect v)
|
||||
{
|
||||
return cpv(-v.y, v.x);
|
||||
}
|
||||
|
||||
/// Returns a perpendicular vector. (-90 degree rotation)
|
||||
static inline cpVect cpvrperp(const cpVect v)
|
||||
{
|
||||
return cpv(v.y, -v.x);
|
||||
}
|
||||
|
||||
/// Returns the vector projection of v1 onto v2.
|
||||
static inline cpVect cpvproject(const cpVect v1, const cpVect v2)
|
||||
{
|
||||
return cpvmult(v2, cpvdot(v1, v2)/cpvdot(v2, v2));
|
||||
}
|
||||
|
||||
/// Returns the unit length vector for the given angle (in radians).
|
||||
static inline cpVect cpvforangle(const cpFloat a)
|
||||
{
|
||||
return cpv(cpfcos(a), cpfsin(a));
|
||||
}
|
||||
|
||||
/// Returns the angular direction v is pointing in (in radians).
|
||||
static inline cpFloat cpvtoangle(const cpVect v)
|
||||
{
|
||||
return cpfatan2(v.y, v.x);
|
||||
}
|
||||
|
||||
/// Uses complex number multiplication to rotate v1 by v2. Scaling will occur if v1 is not a unit vector.
|
||||
static inline cpVect cpvrotate(const cpVect v1, const cpVect v2)
|
||||
{
|
||||
return cpv(v1.x*v2.x - v1.y*v2.y, v1.x*v2.y + v1.y*v2.x);
|
||||
}
|
||||
|
||||
/// Inverse of cpvrotate().
|
||||
static inline cpVect cpvunrotate(const cpVect v1, const cpVect v2)
|
||||
{
|
||||
return cpv(v1.x*v2.x + v1.y*v2.y, v1.y*v2.x - v1.x*v2.y);
|
||||
}
|
||||
|
||||
/// Returns the squared length of v. Faster than cpvlength() when you only need to compare lengths.
|
||||
static inline cpFloat cpvlengthsq(const cpVect v)
|
||||
{
|
||||
return cpvdot(v, v);
|
||||
}
|
||||
|
||||
/// Returns the length of v.
|
||||
static inline cpFloat cpvlength(const cpVect v)
|
||||
{
|
||||
return cpfsqrt(cpvdot(v, v));
|
||||
}
|
||||
|
||||
/// Linearly interpolate between v1 and v2.
|
||||
static inline cpVect cpvlerp(const cpVect v1, const cpVect v2, const cpFloat t)
|
||||
{
|
||||
return cpvadd(cpvmult(v1, 1.0f - t), cpvmult(v2, t));
|
||||
}
|
||||
|
||||
/// Returns a normalized copy of v.
|
||||
static inline cpVect cpvnormalize(const cpVect v)
|
||||
{
|
||||
// Neat trick I saw somewhere to avoid div/0.
|
||||
return cpvmult(v, 1.0f/(cpvlength(v) + CPFLOAT_MIN));
|
||||
}
|
||||
|
||||
/// @deprecated Just an alias for cpvnormalize() now.
|
||||
static inline cpVect cpvnormalize_safe(const cpVect v)
|
||||
{
|
||||
return cpvnormalize(v);
|
||||
}
|
||||
|
||||
/// Clamp v to length len.
|
||||
static inline cpVect cpvclamp(const cpVect v, const cpFloat len)
|
||||
{
|
||||
return (cpvdot(v,v) > len*len) ? cpvmult(cpvnormalize(v), len) : v;
|
||||
}
|
||||
|
||||
/// Linearly interpolate between v1 towards v2 by distance d.
|
||||
static inline cpVect cpvlerpconst(cpVect v1, cpVect v2, cpFloat d)
|
||||
{
|
||||
return cpvadd(v1, cpvclamp(cpvsub(v2, v1), d));
|
||||
}
|
||||
|
||||
/// Returns the distance between v1 and v2.
|
||||
static inline cpFloat cpvdist(const cpVect v1, const cpVect v2)
|
||||
{
|
||||
return cpvlength(cpvsub(v1, v2));
|
||||
}
|
||||
|
||||
/// Returns the squared distance between v1 and v2. Faster than cpvdist() when you only need to compare distances.
|
||||
static inline cpFloat cpvdistsq(const cpVect v1, const cpVect v2)
|
||||
{
|
||||
return cpvlengthsq(cpvsub(v1, v2));
|
||||
}
|
||||
|
||||
/// Returns true if the distance between v1 and v2 is less than dist.
|
||||
static inline cpBool cpvnear(const cpVect v1, const cpVect v2, const cpFloat dist)
|
||||
{
|
||||
return cpvdistsq(v1, v2) < dist*dist;
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
/// @defgroup cpMat2x2 cpMat2x2
|
||||
/// 2x2 matrix type used for tensors and such.
|
||||
/// @{
|
||||
|
||||
static inline cpMat2x2
|
||||
cpMat2x2New(cpFloat a, cpFloat b, cpFloat c, cpFloat d)
|
||||
{
|
||||
cpMat2x2 m = {a, b, c, d};
|
||||
return m;
|
||||
}
|
||||
|
||||
static inline cpVect
|
||||
cpMat2x2Transform(cpMat2x2 m, cpVect v)
|
||||
{
|
||||
return cpv(v.x*m.a + v.y*m.b, v.x*m.c + v.y*m.d);
|
||||
}
|
||||
|
||||
///@}
|
||||
|
|
@ -1,11 +1,35 @@
|
|||
/* Copyright (c) 2013 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.
|
||||
*/
|
||||
|
||||
#ifdef CHIPMUNK_FFI
|
||||
|
||||
// Create non static inlined copies of Chipmunk functions, useful for working with dynamic FFIs
|
||||
// This file should only be included in chipmunk.c
|
||||
|
||||
// TODO: get rid of the reliance on static inlines.
|
||||
// They make a mess for FFIs.
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if _MSC_VER >= 1600
|
||||
#define MAKE_REF(name) decltype(name) *_##name = name
|
||||
#define MAKE_REF(name) CP_EXPORT decltype(name) *_##name = name
|
||||
#else
|
||||
#define MAKE_REF(name)
|
||||
#endif
|
||||
|
|
@ -13,8 +37,9 @@
|
|||
#define MAKE_REF(name) __typeof__(name) *_##name = name
|
||||
#endif
|
||||
|
||||
#define MAKE_PROPERTIES_REF(struct, property) \
|
||||
MAKE_REF(struct##Get##property); MAKE_REF(struct##Set##property)
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
MAKE_REF(cpv); // makes a variable named _cpv that contains the function pointer for cpv()
|
||||
MAKE_REF(cpveql);
|
||||
|
|
@ -35,7 +60,6 @@ MAKE_REF(cpvlengthsq);
|
|||
MAKE_REF(cpvlength);
|
||||
MAKE_REF(cpvlerp);
|
||||
MAKE_REF(cpvnormalize);
|
||||
MAKE_REF(cpvnormalize_safe);
|
||||
MAKE_REF(cpvclamp);
|
||||
MAKE_REF(cpvlerpconst);
|
||||
MAKE_REF(cpvdist);
|
||||
|
|
@ -50,104 +74,20 @@ MAKE_REF(cpflerp);
|
|||
MAKE_REF(cpflerpconst);
|
||||
|
||||
MAKE_REF(cpBBNew);
|
||||
MAKE_REF(cpBBNewForExtents);
|
||||
MAKE_REF(cpBBNewForCircle);
|
||||
MAKE_REF(cpBBIntersects);
|
||||
MAKE_REF(cpBBContainsBB);
|
||||
MAKE_REF(cpBBContainsVect);
|
||||
MAKE_REF(cpBBMerge);
|
||||
MAKE_REF(cpBBExpand);
|
||||
MAKE_REF(cpBBCenter);
|
||||
MAKE_REF(cpBBArea);
|
||||
MAKE_REF(cpBBMergedArea);
|
||||
MAKE_REF(cpBBSegmentQuery);
|
||||
MAKE_REF(cpBBIntersectsSegment);
|
||||
MAKE_REF(cpBBClampVect);
|
||||
|
||||
MAKE_REF(cpBodyGetMass);
|
||||
MAKE_REF(cpBodyGetMoment);
|
||||
MAKE_REF(cpBodyGetPos);
|
||||
MAKE_REF(cpBodyGetAngle);
|
||||
MAKE_REF(cpBodyGetRot);
|
||||
MAKE_PROPERTIES_REF(cpBody, Vel);
|
||||
MAKE_PROPERTIES_REF(cpBody, Force);
|
||||
MAKE_PROPERTIES_REF(cpBody, AngVel);
|
||||
MAKE_PROPERTIES_REF(cpBody, Torque);
|
||||
MAKE_PROPERTIES_REF(cpBody, VelLimit);
|
||||
MAKE_PROPERTIES_REF(cpBody, AngVelLimit);
|
||||
MAKE_PROPERTIES_REF(cpBody, UserData);
|
||||
MAKE_REF(cpBodyIsSleeping);
|
||||
MAKE_REF(cpBodyIsStatic);
|
||||
MAKE_REF(cpBodyIsRogue);
|
||||
MAKE_REF(cpBodyLocal2World);
|
||||
MAKE_REF(cpBodyWorld2Local);
|
||||
MAKE_REF(cpBodyKineticEnergy);
|
||||
|
||||
MAKE_REF(cpShapeGetBB);
|
||||
MAKE_PROPERTIES_REF(cpShape, Body);
|
||||
MAKE_PROPERTIES_REF(cpShape, Sensor);
|
||||
MAKE_PROPERTIES_REF(cpShape, Elasticity);
|
||||
MAKE_PROPERTIES_REF(cpShape, Friction);
|
||||
MAKE_PROPERTIES_REF(cpShape, SurfaceVelocity);
|
||||
MAKE_PROPERTIES_REF(cpShape, UserData);
|
||||
MAKE_PROPERTIES_REF(cpShape, CollisionType);
|
||||
MAKE_PROPERTIES_REF(cpShape, Group);
|
||||
MAKE_PROPERTIES_REF(cpShape, Layers);
|
||||
|
||||
MAKE_REF(cpArbiterGetShapes);
|
||||
MAKE_REF(cpArbiterGetBodies);
|
||||
MAKE_REF(cpArbiterIsFirstContact);
|
||||
MAKE_REF(cpArbiterGetCount);
|
||||
|
||||
MAKE_REF(cpConstraintGetA);
|
||||
MAKE_REF(cpConstraintGetB);
|
||||
MAKE_PROPERTIES_REF(cpConstraint, MaxForce);
|
||||
MAKE_PROPERTIES_REF(cpConstraint, ErrorBias);
|
||||
MAKE_PROPERTIES_REF(cpConstraint, MaxBias);
|
||||
MAKE_PROPERTIES_REF(cpConstraint, UserData);
|
||||
MAKE_REF(cpConstraintGetImpulse);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpDampedRotarySpring, RestAngle);
|
||||
MAKE_PROPERTIES_REF(cpDampedRotarySpring, Stiffness);
|
||||
MAKE_PROPERTIES_REF(cpDampedRotarySpring, Damping);
|
||||
//MAKE_PROPERTIES_REF(cpDampedRotarySpring, SpringTorqueFunc);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpDampedSpring, Anchr1);
|
||||
MAKE_PROPERTIES_REF(cpDampedSpring, Anchr2);
|
||||
MAKE_PROPERTIES_REF(cpDampedSpring, RestLength);
|
||||
MAKE_PROPERTIES_REF(cpDampedSpring, Stiffness);
|
||||
MAKE_PROPERTIES_REF(cpDampedSpring, Damping);
|
||||
//MAKE_PROPERTIES_REF(cpDampedSpring, SpringForceFunc);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpGearJoint, Phase);
|
||||
MAKE_REF(cpGearJointGetRatio);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpGrooveJoint, Anchr2);
|
||||
MAKE_REF(cpGrooveJointGetGrooveA);
|
||||
MAKE_REF(cpGrooveJointGetGrooveB);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpPinJoint, Anchr1);
|
||||
MAKE_PROPERTIES_REF(cpPinJoint, Anchr2);
|
||||
MAKE_PROPERTIES_REF(cpPinJoint, Dist);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpPivotJoint, Anchr1);
|
||||
MAKE_PROPERTIES_REF(cpPivotJoint, Anchr2);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpRatchetJoint, Angle);
|
||||
MAKE_PROPERTIES_REF(cpRatchetJoint, Phase);
|
||||
MAKE_PROPERTIES_REF(cpRatchetJoint, Ratchet);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpRotaryLimitJoint, Min);
|
||||
MAKE_PROPERTIES_REF(cpRotaryLimitJoint, Max);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpSimpleMotor, Rate);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpSlideJoint, Anchr1);
|
||||
MAKE_PROPERTIES_REF(cpSlideJoint, Anchr2);
|
||||
MAKE_PROPERTIES_REF(cpSlideJoint, Min);
|
||||
MAKE_PROPERTIES_REF(cpSlideJoint, Max);
|
||||
|
||||
MAKE_REF(cpSegmentQueryHitPoint);
|
||||
MAKE_REF(cpSegmentQueryHitDist);
|
||||
|
||||
MAKE_REF(cpSpatialIndexDestroy);
|
||||
MAKE_REF(cpSpatialIndexCount);
|
||||
MAKE_REF(cpSpatialIndexEach);
|
||||
|
|
@ -160,18 +100,8 @@ MAKE_REF(cpSpatialIndexSegmentQuery);
|
|||
MAKE_REF(cpSpatialIndexQuery);
|
||||
MAKE_REF(cpSpatialIndexReindexQuery);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpSpace, Iterations);
|
||||
MAKE_PROPERTIES_REF(cpSpace, Gravity);
|
||||
MAKE_PROPERTIES_REF(cpSpace, Damping);
|
||||
MAKE_PROPERTIES_REF(cpSpace, IdleSpeedThreshold);
|
||||
MAKE_PROPERTIES_REF(cpSpace, SleepTimeThreshold);
|
||||
MAKE_PROPERTIES_REF(cpSpace, CollisionSlop);
|
||||
MAKE_PROPERTIES_REF(cpSpace, CollisionBias);
|
||||
MAKE_PROPERTIES_REF(cpSpace, CollisionPersistence);
|
||||
MAKE_PROPERTIES_REF(cpSpace, EnableContactGraph);
|
||||
MAKE_PROPERTIES_REF(cpSpace, UserData);
|
||||
MAKE_REF(cpSpaceGetStaticBody);
|
||||
MAKE_REF(cpSpaceGetCurrentTimeStep);
|
||||
MAKE_REF(cpSpaceIsLocked);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2007 Scott Lembcke
|
||||
/* Copyright (c) 2013 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
|
||||
|
|
@ -18,9 +18,14 @@
|
|||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*/
|
||||
#ifndef CHIPMUNK_PRIVATE_H
|
||||
#define CHIPMUNK_PRIVATE_H
|
||||
#ifdef CHIPMUNK_H
|
||||
#error Cannot include chipmunk_private.h after chipmunk.h.
|
||||
#endif
|
||||
|
||||
#define CP_ALLOW_PRIVATE_ACCESS 1
|
||||
#include "chipmunk.h"
|
||||
#include "chipmunk/chipmunk.h"
|
||||
|
||||
#define CP_HASH_COEF (3344921057ul)
|
||||
#define CP_HASH_PAIR(A, B) ((cpHashValue)(A)*CP_HASH_COEF ^ (cpHashValue)(B)*CP_HASH_COEF)
|
||||
|
|
@ -28,6 +33,7 @@
|
|||
// TODO: Eww. Magic numbers.
|
||||
#define MAGIC_EPSILON 1e-5
|
||||
|
||||
|
||||
//MARK: cpArray
|
||||
|
||||
struct cpArray {
|
||||
|
|
@ -47,6 +53,690 @@ cpBool cpArrayContains(cpArray *arr, void *ptr);
|
|||
void cpArrayFreeEach(cpArray *arr, void (freeFunc)(void*));
|
||||
|
||||
|
||||
//MARK: cpHashSet
|
||||
|
||||
typedef cpBool (*cpHashSetEqlFunc)(void *ptr, void *elt);
|
||||
typedef void *(*cpHashSetTransFunc)(void *ptr, void *data);
|
||||
|
||||
cpHashSet *cpHashSetNew(int size, cpHashSetEqlFunc eqlFunc);
|
||||
void cpHashSetSetDefaultValue(cpHashSet *set, void *default_value);
|
||||
|
||||
void cpHashSetFree(cpHashSet *set);
|
||||
|
||||
int cpHashSetCount(cpHashSet *set);
|
||||
void *cpHashSetInsert(cpHashSet *set, cpHashValue hash, void *ptr, cpHashSetTransFunc trans, void *data);
|
||||
void *cpHashSetRemove(cpHashSet *set, cpHashValue hash, void *ptr);
|
||||
void *cpHashSetFind(cpHashSet *set, cpHashValue hash, void *ptr);
|
||||
|
||||
typedef void (*cpHashSetIteratorFunc)(void *elt, void *data);
|
||||
void cpHashSetEach(cpHashSet *set, cpHashSetIteratorFunc func, void *data);
|
||||
|
||||
typedef cpBool (*cpHashSetFilterFunc)(void *elt, void *data);
|
||||
void cpHashSetFilter(cpHashSet *set, cpHashSetFilterFunc func, void *data);
|
||||
|
||||
|
||||
//MARK: Bodies
|
||||
|
||||
struct cpBody {
|
||||
// Integration functions
|
||||
cpBodyVelocityFunc velocity_func;
|
||||
cpBodyPositionFunc position_func;
|
||||
|
||||
// mass and it's inverse
|
||||
cpFloat m;
|
||||
cpFloat m_inv;
|
||||
|
||||
// moment of inertia and it's inverse
|
||||
cpFloat i;
|
||||
cpFloat i_inv;
|
||||
|
||||
// center of gravity
|
||||
cpVect cog;
|
||||
|
||||
// position, velocity, force
|
||||
cpVect p;
|
||||
cpVect v;
|
||||
cpVect f;
|
||||
|
||||
// Angle, angular velocity, torque (radians)
|
||||
cpFloat a;
|
||||
cpFloat w;
|
||||
cpFloat t;
|
||||
|
||||
cpTransform transform;
|
||||
|
||||
cpDataPointer userData;
|
||||
|
||||
// "pseudo-velocities" used for eliminating overlap.
|
||||
// Erin Catto has some papers that talk about what these are.
|
||||
cpVect v_bias;
|
||||
cpFloat w_bias;
|
||||
|
||||
cpSpace *space;
|
||||
|
||||
cpShape *shapeList;
|
||||
cpArbiter *arbiterList;
|
||||
cpConstraint *constraintList;
|
||||
|
||||
struct {
|
||||
cpBody *root;
|
||||
cpBody *next;
|
||||
cpFloat idleTime;
|
||||
} sleeping;
|
||||
};
|
||||
|
||||
void cpBodyAddShape(cpBody *body, cpShape *shape);
|
||||
void cpBodyRemoveShape(cpBody *body, cpShape *shape);
|
||||
|
||||
//void cpBodyAccumulateMassForShape(cpBody *body, cpShape *shape);
|
||||
void cpBodyAccumulateMassFromShapes(cpBody *body);
|
||||
|
||||
void cpBodyRemoveConstraint(cpBody *body, cpConstraint *constraint);
|
||||
|
||||
|
||||
//MARK: Spatial Index Functions
|
||||
|
||||
cpSpatialIndex *cpSpatialIndexInit(cpSpatialIndex *index, cpSpatialIndexClass *klass, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
|
||||
|
||||
//MARK: Arbiters
|
||||
|
||||
enum cpArbiterState {
|
||||
// Arbiter is active and its the first collision.
|
||||
CP_ARBITER_STATE_FIRST_COLLISION,
|
||||
// Arbiter is active and its not the first collision.
|
||||
CP_ARBITER_STATE_NORMAL,
|
||||
// Collision has been explicitly ignored.
|
||||
// Either by returning false from a begin collision handler or calling cpArbiterIgnore().
|
||||
CP_ARBITER_STATE_IGNORE,
|
||||
// Collison is no longer active. A space will cache an arbiter for up to cpSpace.collisionPersistence more steps.
|
||||
CP_ARBITER_STATE_CACHED,
|
||||
// Collison arbiter is invalid because one of the shapes was removed.
|
||||
CP_ARBITER_STATE_INVALIDATED,
|
||||
};
|
||||
|
||||
struct cpArbiterThread {
|
||||
struct cpArbiter *next, *prev;
|
||||
};
|
||||
|
||||
struct cpContact {
|
||||
cpVect r1, r2;
|
||||
|
||||
cpFloat nMass, tMass;
|
||||
cpFloat bounce; // TODO: look for an alternate bounce solution.
|
||||
|
||||
cpFloat jnAcc, jtAcc, jBias;
|
||||
cpFloat bias;
|
||||
|
||||
cpHashValue hash;
|
||||
};
|
||||
|
||||
struct cpCollisionInfo {
|
||||
const cpShape *a, *b;
|
||||
cpCollisionID id;
|
||||
|
||||
cpVect n;
|
||||
|
||||
int count;
|
||||
// TODO Should this be a unique struct type?
|
||||
struct cpContact *arr;
|
||||
};
|
||||
|
||||
struct cpArbiter {
|
||||
cpFloat e;
|
||||
cpFloat u;
|
||||
cpVect surface_vr;
|
||||
|
||||
cpDataPointer data;
|
||||
|
||||
const cpShape *a, *b;
|
||||
cpBody *body_a, *body_b;
|
||||
struct cpArbiterThread thread_a, thread_b;
|
||||
|
||||
int count;
|
||||
struct cpContact *contacts;
|
||||
cpVect n;
|
||||
|
||||
// Regular, wildcard A and wildcard B collision handlers.
|
||||
cpCollisionHandler *handler, *handlerA, *handlerB;
|
||||
cpBool swapped;
|
||||
|
||||
cpTimestamp stamp;
|
||||
enum cpArbiterState state;
|
||||
};
|
||||
|
||||
cpArbiter* cpArbiterInit(cpArbiter *arb, cpShape *a, cpShape *b);
|
||||
|
||||
static inline struct cpArbiterThread *
|
||||
cpArbiterThreadForBody(cpArbiter *arb, cpBody *body)
|
||||
{
|
||||
return (arb->body_a == body ? &arb->thread_a : &arb->thread_b);
|
||||
}
|
||||
|
||||
void cpArbiterUnthread(cpArbiter *arb);
|
||||
|
||||
void cpArbiterUpdate(cpArbiter *arb, struct cpCollisionInfo *info, cpSpace *space);
|
||||
void cpArbiterPreStep(cpArbiter *arb, cpFloat dt, cpFloat bias, cpFloat slop);
|
||||
void cpArbiterApplyCachedImpulse(cpArbiter *arb, cpFloat dt_coef);
|
||||
void cpArbiterApplyImpulse(cpArbiter *arb);
|
||||
|
||||
|
||||
//MARK: Shapes/Collisions
|
||||
|
||||
struct cpShapeMassInfo {
|
||||
cpFloat m;
|
||||
cpFloat i;
|
||||
cpVect cog;
|
||||
cpFloat area;
|
||||
};
|
||||
|
||||
typedef enum cpShapeType{
|
||||
CP_CIRCLE_SHAPE,
|
||||
CP_SEGMENT_SHAPE,
|
||||
CP_POLY_SHAPE,
|
||||
CP_NUM_SHAPES
|
||||
} cpShapeType;
|
||||
|
||||
typedef cpBB (*cpShapeCacheDataImpl)(cpShape *shape, cpTransform transform);
|
||||
typedef void (*cpShapeDestroyImpl)(cpShape *shape);
|
||||
typedef void (*cpShapePointQueryImpl)(const cpShape *shape, cpVect p, cpPointQueryInfo *info);
|
||||
typedef void (*cpShapeSegmentQueryImpl)(const cpShape *shape, cpVect a, cpVect b, cpFloat radius, cpSegmentQueryInfo *info);
|
||||
|
||||
typedef struct cpShapeClass cpShapeClass;
|
||||
|
||||
struct cpShapeClass {
|
||||
cpShapeType type;
|
||||
|
||||
cpShapeCacheDataImpl cacheData;
|
||||
cpShapeDestroyImpl destroy;
|
||||
cpShapePointQueryImpl pointQuery;
|
||||
cpShapeSegmentQueryImpl segmentQuery;
|
||||
};
|
||||
|
||||
struct cpShape {
|
||||
const cpShapeClass *klass;
|
||||
|
||||
cpSpace *space;
|
||||
cpBody *body;
|
||||
struct cpShapeMassInfo massInfo;
|
||||
cpBB bb;
|
||||
|
||||
cpBool sensor;
|
||||
|
||||
cpFloat e;
|
||||
cpFloat u;
|
||||
cpVect surfaceV;
|
||||
|
||||
cpDataPointer userData;
|
||||
|
||||
cpCollisionType type;
|
||||
cpShapeFilter filter;
|
||||
|
||||
cpShape *next;
|
||||
cpShape *prev;
|
||||
|
||||
cpHashValue hashid;
|
||||
};
|
||||
|
||||
struct cpCircleShape {
|
||||
cpShape shape;
|
||||
|
||||
cpVect c, tc;
|
||||
cpFloat r;
|
||||
};
|
||||
|
||||
struct cpSegmentShape {
|
||||
cpShape shape;
|
||||
|
||||
cpVect a, b, n;
|
||||
cpVect ta, tb, tn;
|
||||
cpFloat r;
|
||||
|
||||
cpVect a_tangent, b_tangent;
|
||||
};
|
||||
|
||||
struct cpSplittingPlane {
|
||||
cpVect v0, n;
|
||||
};
|
||||
|
||||
#define CP_POLY_SHAPE_INLINE_ALLOC 6
|
||||
|
||||
struct cpPolyShape {
|
||||
cpShape shape;
|
||||
|
||||
cpFloat r;
|
||||
|
||||
int count;
|
||||
// The untransformed planes are appended at the end of the transformed planes.
|
||||
struct cpSplittingPlane *planes;
|
||||
|
||||
// Allocate a small number of splitting planes internally for simple poly.
|
||||
struct cpSplittingPlane _planes[2*CP_POLY_SHAPE_INLINE_ALLOC];
|
||||
};
|
||||
|
||||
cpShape *cpShapeInit(cpShape *shape, const cpShapeClass *klass, cpBody *body, struct cpShapeMassInfo massInfo);
|
||||
|
||||
static inline cpBool
|
||||
cpShapeActive(cpShape *shape)
|
||||
{
|
||||
// checks if the shape is added to a shape list.
|
||||
// TODO could this just check the space now?
|
||||
return (shape->prev || (shape->body && shape->body->shapeList == shape));
|
||||
}
|
||||
|
||||
// Note: This function returns contact points with r1/r2 in absolute coordinates, not body relative.
|
||||
struct cpCollisionInfo cpCollide(const cpShape *a, const cpShape *b, cpCollisionID id, struct cpContact *contacts);
|
||||
|
||||
static inline void
|
||||
CircleSegmentQuery(cpShape *shape, cpVect center, cpFloat r1, cpVect a, cpVect b, cpFloat r2, cpSegmentQueryInfo *info)
|
||||
{
|
||||
cpVect da = cpvsub(a, center);
|
||||
cpVect db = cpvsub(b, center);
|
||||
cpFloat rsum = r1 + r2;
|
||||
|
||||
cpFloat qa = cpvdot(da, da) - 2.0f*cpvdot(da, db) + cpvdot(db, db);
|
||||
cpFloat qb = cpvdot(da, db) - cpvdot(da, da);
|
||||
cpFloat det = qb*qb - qa*(cpvdot(da, da) - rsum*rsum);
|
||||
|
||||
if(det >= 0.0f){
|
||||
cpFloat t = (-qb - cpfsqrt(det))/(qa);
|
||||
if(0.0f<= t && t <= 1.0f){
|
||||
cpVect n = cpvnormalize(cpvlerp(da, db, t));
|
||||
|
||||
info->shape = shape;
|
||||
info->point = cpvsub(cpvlerp(a, b, t), cpvmult(n, r2));
|
||||
info->normal = n;
|
||||
info->alpha = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static inline cpBool
|
||||
cpShapeFilterReject(cpShapeFilter a, cpShapeFilter b)
|
||||
{
|
||||
// Reject the collision if:
|
||||
return (
|
||||
// They are in the same non-zero group.
|
||||
(a.group != 0 && a.group == b.group) ||
|
||||
// One of the category/mask combinations fails.
|
||||
(a.categories & b.mask) == 0 ||
|
||||
(b.categories & a.mask) == 0
|
||||
);
|
||||
}
|
||||
|
||||
void cpLoopIndexes(const cpVect *verts, int count, int *start, int *end);
|
||||
|
||||
|
||||
//MARK: Constraints
|
||||
// TODO naming conventions here
|
||||
|
||||
typedef void (*cpConstraintPreStepImpl)(cpConstraint *constraint, cpFloat dt);
|
||||
typedef void (*cpConstraintApplyCachedImpulseImpl)(cpConstraint *constraint, cpFloat dt_coef);
|
||||
typedef void (*cpConstraintApplyImpulseImpl)(cpConstraint *constraint, cpFloat dt);
|
||||
typedef cpFloat (*cpConstraintGetImpulseImpl)(cpConstraint *constraint);
|
||||
|
||||
typedef struct cpConstraintClass {
|
||||
cpConstraintPreStepImpl preStep;
|
||||
cpConstraintApplyCachedImpulseImpl applyCachedImpulse;
|
||||
cpConstraintApplyImpulseImpl applyImpulse;
|
||||
cpConstraintGetImpulseImpl getImpulse;
|
||||
} cpConstraintClass;
|
||||
|
||||
struct cpConstraint {
|
||||
const cpConstraintClass *klass;
|
||||
|
||||
cpSpace *space;
|
||||
|
||||
cpBody *a, *b;
|
||||
cpConstraint *next_a, *next_b;
|
||||
|
||||
cpFloat maxForce;
|
||||
cpFloat errorBias;
|
||||
cpFloat maxBias;
|
||||
|
||||
cpBool collideBodies;
|
||||
|
||||
cpConstraintPreSolveFunc preSolve;
|
||||
cpConstraintPostSolveFunc postSolve;
|
||||
|
||||
cpDataPointer userData;
|
||||
};
|
||||
|
||||
struct cpPinJoint {
|
||||
cpConstraint constraint;
|
||||
cpVect anchorA, anchorB;
|
||||
cpFloat dist;
|
||||
|
||||
cpVect r1, r2;
|
||||
cpVect n;
|
||||
cpFloat nMass;
|
||||
|
||||
cpFloat jnAcc;
|
||||
cpFloat bias;
|
||||
};
|
||||
|
||||
struct cpSlideJoint {
|
||||
cpConstraint constraint;
|
||||
cpVect anchorA, anchorB;
|
||||
cpFloat min, max;
|
||||
|
||||
cpVect r1, r2;
|
||||
cpVect n;
|
||||
cpFloat nMass;
|
||||
|
||||
cpFloat jnAcc;
|
||||
cpFloat bias;
|
||||
};
|
||||
|
||||
struct cpPivotJoint {
|
||||
cpConstraint constraint;
|
||||
cpVect anchorA, anchorB;
|
||||
|
||||
cpVect r1, r2;
|
||||
cpMat2x2 k;
|
||||
|
||||
cpVect jAcc;
|
||||
cpVect bias;
|
||||
};
|
||||
|
||||
struct cpGrooveJoint {
|
||||
cpConstraint constraint;
|
||||
cpVect grv_n, grv_a, grv_b;
|
||||
cpVect anchorB;
|
||||
|
||||
cpVect grv_tn;
|
||||
cpFloat clamp;
|
||||
cpVect r1, r2;
|
||||
cpMat2x2 k;
|
||||
|
||||
cpVect jAcc;
|
||||
cpVect bias;
|
||||
};
|
||||
|
||||
struct cpDampedSpring {
|
||||
cpConstraint constraint;
|
||||
cpVect anchorA, anchorB;
|
||||
cpFloat restLength;
|
||||
cpFloat stiffness;
|
||||
cpFloat damping;
|
||||
cpDampedSpringForceFunc springForceFunc;
|
||||
|
||||
cpFloat target_vrn;
|
||||
cpFloat v_coef;
|
||||
|
||||
cpVect r1, r2;
|
||||
cpFloat nMass;
|
||||
cpVect n;
|
||||
|
||||
cpFloat jAcc;
|
||||
};
|
||||
|
||||
struct cpDampedRotarySpring {
|
||||
cpConstraint constraint;
|
||||
cpFloat restAngle;
|
||||
cpFloat stiffness;
|
||||
cpFloat damping;
|
||||
cpDampedRotarySpringTorqueFunc springTorqueFunc;
|
||||
|
||||
cpFloat target_wrn;
|
||||
cpFloat w_coef;
|
||||
|
||||
cpFloat iSum;
|
||||
cpFloat jAcc;
|
||||
};
|
||||
|
||||
struct cpRotaryLimitJoint {
|
||||
cpConstraint constraint;
|
||||
cpFloat min, max;
|
||||
|
||||
cpFloat iSum;
|
||||
|
||||
cpFloat bias;
|
||||
cpFloat jAcc;
|
||||
};
|
||||
|
||||
struct cpRatchetJoint {
|
||||
cpConstraint constraint;
|
||||
cpFloat angle, phase, ratchet;
|
||||
|
||||
cpFloat iSum;
|
||||
|
||||
cpFloat bias;
|
||||
cpFloat jAcc;
|
||||
};
|
||||
|
||||
struct cpGearJoint {
|
||||
cpConstraint constraint;
|
||||
cpFloat phase, ratio;
|
||||
cpFloat ratio_inv;
|
||||
|
||||
cpFloat iSum;
|
||||
|
||||
cpFloat bias;
|
||||
cpFloat jAcc;
|
||||
};
|
||||
|
||||
struct cpSimpleMotor {
|
||||
cpConstraint constraint;
|
||||
cpFloat rate;
|
||||
|
||||
cpFloat iSum;
|
||||
|
||||
cpFloat jAcc;
|
||||
};
|
||||
|
||||
void cpConstraintInit(cpConstraint *constraint, const struct cpConstraintClass *klass, cpBody *a, cpBody *b);
|
||||
|
||||
static inline void
|
||||
cpConstraintActivateBodies(cpConstraint *constraint)
|
||||
{
|
||||
cpBody *a = constraint->a; cpBodyActivate(a);
|
||||
cpBody *b = constraint->b; cpBodyActivate(b);
|
||||
}
|
||||
|
||||
static inline cpVect
|
||||
relative_velocity(cpBody *a, cpBody *b, cpVect r1, cpVect r2){
|
||||
cpVect v1_sum = cpvadd(a->CP_PRIVATE(v), cpvmult(cpvperp(r1), a->CP_PRIVATE(w)));
|
||||
cpVect v2_sum = cpvadd(b->CP_PRIVATE(v), cpvmult(cpvperp(r2), b->CP_PRIVATE(w)));
|
||||
|
||||
return cpvsub(v2_sum, v1_sum);
|
||||
}
|
||||
|
||||
static inline cpFloat
|
||||
normal_relative_velocity(cpBody *a, cpBody *b, cpVect r1, cpVect r2, cpVect n){
|
||||
return cpvdot(relative_velocity(a, b, r1, r2), n);
|
||||
}
|
||||
|
||||
static inline void
|
||||
apply_impulse(cpBody *body, cpVect j, cpVect r){
|
||||
body->CP_PRIVATE(v) = cpvadd(body->CP_PRIVATE(v), cpvmult(j, body->CP_PRIVATE(m_inv)));
|
||||
body->CP_PRIVATE(w) += body->CP_PRIVATE(i_inv)*cpvcross(r, j);
|
||||
}
|
||||
|
||||
static inline void
|
||||
apply_impulses(cpBody *a , cpBody *b, cpVect r1, cpVect r2, cpVect j)
|
||||
{
|
||||
apply_impulse(a, cpvneg(j), r1);
|
||||
apply_impulse(b, j, r2);
|
||||
}
|
||||
|
||||
static inline void
|
||||
apply_bias_impulse(cpBody *body, cpVect j, cpVect r)
|
||||
{
|
||||
body->CP_PRIVATE(v_bias) = cpvadd(body->CP_PRIVATE(v_bias), cpvmult(j, body->CP_PRIVATE(m_inv)));
|
||||
body->CP_PRIVATE(w_bias) += body->CP_PRIVATE(i_inv)*cpvcross(r, j);
|
||||
}
|
||||
|
||||
static inline void
|
||||
apply_bias_impulses(cpBody *a , cpBody *b, cpVect r1, cpVect r2, cpVect j)
|
||||
{
|
||||
apply_bias_impulse(a, cpvneg(j), r1);
|
||||
apply_bias_impulse(b, j, r2);
|
||||
}
|
||||
|
||||
static inline cpFloat
|
||||
k_scalar_body(cpBody *body, cpVect r, cpVect n)
|
||||
{
|
||||
cpFloat rcn = cpvcross(r, n);
|
||||
return body->CP_PRIVATE(m_inv) + body->CP_PRIVATE(i_inv)*rcn*rcn;
|
||||
}
|
||||
|
||||
static inline cpFloat
|
||||
k_scalar(cpBody *a, cpBody *b, cpVect r1, cpVect r2, cpVect n)
|
||||
{
|
||||
cpFloat value = k_scalar_body(a, r1, n) + k_scalar_body(b, r2, n);
|
||||
cpAssertSoft(value != 0.0, "Unsolvable collision or constraint.");
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static inline cpMat2x2
|
||||
k_tensor(cpBody *a, cpBody *b, cpVect r1, cpVect r2)
|
||||
{
|
||||
cpFloat m_sum = a->CP_PRIVATE(m_inv) + b->CP_PRIVATE(m_inv);
|
||||
|
||||
// start with Identity*m_sum
|
||||
cpFloat k11 = m_sum, k12 = 0.0f;
|
||||
cpFloat k21 = 0.0f, k22 = m_sum;
|
||||
|
||||
// add the influence from r1
|
||||
cpFloat a_i_inv = a->CP_PRIVATE(i_inv);
|
||||
cpFloat r1xsq = r1.x * r1.x * a_i_inv;
|
||||
cpFloat r1ysq = r1.y * r1.y * a_i_inv;
|
||||
cpFloat r1nxy = -r1.x * r1.y * a_i_inv;
|
||||
k11 += r1ysq; k12 += r1nxy;
|
||||
k21 += r1nxy; k22 += r1xsq;
|
||||
|
||||
// add the influnce from r2
|
||||
cpFloat b_i_inv = b->CP_PRIVATE(i_inv);
|
||||
cpFloat r2xsq = r2.x * r2.x * b_i_inv;
|
||||
cpFloat r2ysq = r2.y * r2.y * b_i_inv;
|
||||
cpFloat r2nxy = -r2.x * r2.y * b_i_inv;
|
||||
k11 += r2ysq; k12 += r2nxy;
|
||||
k21 += r2nxy; k22 += r2xsq;
|
||||
|
||||
// invert
|
||||
cpFloat det = k11*k22 - k12*k21;
|
||||
cpAssertSoft(det != 0.0, "Unsolvable constraint.");
|
||||
|
||||
cpFloat det_inv = 1.0f/det;
|
||||
return cpMat2x2New(
|
||||
k22*det_inv, -k12*det_inv,
|
||||
-k21*det_inv, k11*det_inv
|
||||
);
|
||||
}
|
||||
|
||||
static inline cpFloat
|
||||
bias_coef(cpFloat errorBias, cpFloat dt)
|
||||
{
|
||||
return 1.0f - cpfpow(errorBias, dt);
|
||||
}
|
||||
|
||||
|
||||
//MARK: Spaces
|
||||
|
||||
typedef struct cpContactBufferHeader cpContactBufferHeader;
|
||||
typedef void (*cpSpaceArbiterApplyImpulseFunc)(cpArbiter *arb);
|
||||
|
||||
struct cpSpace {
|
||||
int iterations;
|
||||
|
||||
cpVect gravity;
|
||||
cpFloat damping;
|
||||
|
||||
cpFloat idleSpeedThreshold;
|
||||
cpFloat sleepTimeThreshold;
|
||||
|
||||
cpFloat collisionSlop;
|
||||
cpFloat collisionBias;
|
||||
cpTimestamp collisionPersistence;
|
||||
|
||||
cpDataPointer userData;
|
||||
|
||||
cpTimestamp stamp;
|
||||
cpFloat curr_dt;
|
||||
|
||||
cpArray *dynamicBodies;
|
||||
cpArray *staticBodies;
|
||||
cpArray *rousedBodies;
|
||||
cpArray *sleepingComponents;
|
||||
|
||||
cpHashValue shapeIDCounter;
|
||||
cpSpatialIndex *staticShapes;
|
||||
cpSpatialIndex *dynamicShapes;
|
||||
|
||||
cpArray *constraints;
|
||||
|
||||
cpArray *arbiters;
|
||||
cpContactBufferHeader *contactBuffersHead;
|
||||
cpHashSet *cachedArbiters;
|
||||
cpArray *pooledArbiters;
|
||||
|
||||
cpArray *allocatedBuffers;
|
||||
unsigned int locked;
|
||||
|
||||
cpBool usesWildcards;
|
||||
cpHashSet *collisionHandlers;
|
||||
cpCollisionHandler defaultHandler;
|
||||
|
||||
cpBool skipPostStep;
|
||||
cpArray *postStepCallbacks;
|
||||
|
||||
cpBody *staticBody;
|
||||
cpBody _staticBody;
|
||||
};
|
||||
|
||||
#define cpAssertSpaceUnlocked(space) \
|
||||
cpAssertHard(!space->locked, \
|
||||
"This operation cannot be done safely during a call to cpSpaceStep() or during a query. " \
|
||||
"Put these calls into a post-step callback." \
|
||||
);
|
||||
|
||||
void cpSpaceSetStaticBody(cpSpace *space, cpBody *body);
|
||||
|
||||
extern cpCollisionHandler cpCollisionHandlerDoNothing;
|
||||
|
||||
void cpSpaceProcessComponents(cpSpace *space, cpFloat dt);
|
||||
|
||||
void cpSpacePushFreshContactBuffer(cpSpace *space);
|
||||
struct cpContact *cpContactBufferGetArray(cpSpace *space);
|
||||
void cpSpacePushContacts(cpSpace *space, int count);
|
||||
|
||||
typedef struct cpPostStepCallback {
|
||||
cpPostStepFunc func;
|
||||
void *key;
|
||||
void *data;
|
||||
} cpPostStepCallback;
|
||||
|
||||
cpPostStepCallback *cpSpaceGetPostStepCallback(cpSpace *space, void *key);
|
||||
|
||||
cpBool cpSpaceArbiterSetFilter(cpArbiter *arb, cpSpace *space);
|
||||
void cpSpaceFilterArbiters(cpSpace *space, cpBody *body, cpShape *filter);
|
||||
|
||||
void cpSpaceActivateBody(cpSpace *space, cpBody *body);
|
||||
void cpSpaceLock(cpSpace *space);
|
||||
void cpSpaceUnlock(cpSpace *space, cpBool runPostStep);
|
||||
|
||||
static inline void
|
||||
cpSpaceUncacheArbiter(cpSpace *space, cpArbiter *arb)
|
||||
{
|
||||
const cpShape *a = arb->a, *b = arb->b;
|
||||
const cpShape *shape_pair[] = {a, b};
|
||||
cpHashValue arbHashID = CP_HASH_PAIR((cpHashValue)a, (cpHashValue)b);
|
||||
cpHashSetRemove(space->cachedArbiters, arbHashID, shape_pair);
|
||||
cpArrayDeleteObj(space->arbiters, arb);
|
||||
}
|
||||
|
||||
static inline cpArray *
|
||||
cpSpaceArrayForBodyType(cpSpace *space, cpBodyType type)
|
||||
{
|
||||
return (type == CP_BODY_TYPE_STATIC ? space->staticBodies : space->dynamicBodies);
|
||||
}
|
||||
|
||||
void cpShapeUpdateFunc(cpShape *shape, void *unused);
|
||||
cpCollisionID cpSpaceCollideShapes(cpShape *a, cpShape *b, cpCollisionID id, cpSpace *space);
|
||||
|
||||
|
||||
//MARK: Foreach loops
|
||||
|
||||
static inline cpConstraint *
|
||||
|
|
@ -71,184 +761,6 @@ cpArbiterNext(cpArbiter *node, cpBody *body)
|
|||
for(cpShape *var = body->shapeList; var; var = var->next)
|
||||
|
||||
#define CP_BODY_FOREACH_COMPONENT(root, var)\
|
||||
for(cpBody *var = root; var; var = var->node.next)
|
||||
for(cpBody *var = root; var; var = var->sleeping.next)
|
||||
|
||||
|
||||
//MARK: cpHashSet
|
||||
|
||||
typedef cpBool (*cpHashSetEqlFunc)(void *ptr, void *elt);
|
||||
typedef void *(*cpHashSetTransFunc)(void *ptr, void *data);
|
||||
|
||||
cpHashSet *cpHashSetNew(int size, cpHashSetEqlFunc eqlFunc);
|
||||
void cpHashSetSetDefaultValue(cpHashSet *set, void *default_value);
|
||||
|
||||
void cpHashSetFree(cpHashSet *set);
|
||||
|
||||
int cpHashSetCount(cpHashSet *set);
|
||||
void *cpHashSetInsert(cpHashSet *set, cpHashValue hash, void *ptr, void *data, cpHashSetTransFunc trans);
|
||||
void *cpHashSetRemove(cpHashSet *set, cpHashValue hash, void *ptr);
|
||||
void *cpHashSetFind(cpHashSet *set, cpHashValue hash, void *ptr);
|
||||
|
||||
typedef void (*cpHashSetIteratorFunc)(void *elt, void *data);
|
||||
void cpHashSetEach(cpHashSet *set, cpHashSetIteratorFunc func, void *data);
|
||||
|
||||
typedef cpBool (*cpHashSetFilterFunc)(void *elt, void *data);
|
||||
void cpHashSetFilter(cpHashSet *set, cpHashSetFilterFunc func, void *data);
|
||||
|
||||
|
||||
//MARK: Body Functions
|
||||
|
||||
void cpBodyAddShape(cpBody *body, cpShape *shape);
|
||||
void cpBodyRemoveShape(cpBody *body, cpShape *shape);
|
||||
void cpBodyRemoveConstraint(cpBody *body, cpConstraint *constraint);
|
||||
|
||||
|
||||
//MARK: Shape/Collision Functions
|
||||
|
||||
// TODO should move this to the cpVect API. It's pretty useful.
|
||||
static inline cpVect
|
||||
cpClosetPointOnSegment(const cpVect p, const cpVect a, const cpVect b)
|
||||
{
|
||||
cpVect delta = cpvsub(a, b);
|
||||
cpFloat t = cpfclamp01(cpvdot(delta, cpvsub(p, b))/cpvlengthsq(delta));
|
||||
return cpvadd(b, cpvmult(delta, t));
|
||||
}
|
||||
|
||||
cpShape* cpShapeInit(cpShape *shape, const cpShapeClass *klass, cpBody *body);
|
||||
|
||||
static inline cpBool
|
||||
cpShapeActive(cpShape *shape)
|
||||
{
|
||||
return shape->prev || (shape->body && shape->body->shapeList == shape);
|
||||
}
|
||||
|
||||
int cpCollideShapes(const cpShape *a, const cpShape *b, cpCollisionID *id, cpContact *arr);
|
||||
|
||||
static inline void
|
||||
CircleSegmentQuery(cpShape *shape, cpVect center, cpFloat r, cpVect a, cpVect b, cpSegmentQueryInfo *info)
|
||||
{
|
||||
cpVect da = cpvsub(a, center);
|
||||
cpVect db = cpvsub(b, center);
|
||||
|
||||
cpFloat qa = cpvdot(da, da) - 2.0f*cpvdot(da, db) + cpvdot(db, db);
|
||||
cpFloat qb = -2.0f*cpvdot(da, da) + 2.0f*cpvdot(da, db);
|
||||
cpFloat qc = cpvdot(da, da) - r*r;
|
||||
|
||||
cpFloat det = qb*qb - 4.0f*qa*qc;
|
||||
|
||||
if(det >= 0.0f){
|
||||
cpFloat t = (-qb - cpfsqrt(det))/(2.0f*qa);
|
||||
if(0.0f<= t && t <= 1.0f){
|
||||
info->shape = shape;
|
||||
info->t = t;
|
||||
info->n = cpvnormalize(cpvlerp(da, db, t));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO doesn't really need to be inline, but need a better place to put this function
|
||||
static inline cpSplittingPlane
|
||||
cpSplittingPlaneNew(cpVect a, cpVect b)
|
||||
{
|
||||
cpVect n = cpvnormalize(cpvperp(cpvsub(b, a)));
|
||||
cpSplittingPlane plane = {n, cpvdot(n, a)};
|
||||
return plane;
|
||||
}
|
||||
|
||||
static inline cpFloat
|
||||
cpSplittingPlaneCompare(cpSplittingPlane plane, cpVect v)
|
||||
{
|
||||
return cpvdot(plane.n, v) - plane.d;
|
||||
}
|
||||
|
||||
void cpLoopIndexes(cpVect *verts, int count, int *start, int *end);
|
||||
|
||||
|
||||
//MARK: Spatial Index Functions
|
||||
|
||||
cpSpatialIndex *cpSpatialIndexInit(cpSpatialIndex *index, cpSpatialIndexClass *klass, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
|
||||
|
||||
//MARK: Space Functions
|
||||
|
||||
extern cpCollisionHandler cpDefaultCollisionHandler;
|
||||
void cpSpaceProcessComponents(cpSpace *space, cpFloat dt);
|
||||
|
||||
void cpSpacePushFreshContactBuffer(cpSpace *space);
|
||||
cpContact *cpContactBufferGetArray(cpSpace *space);
|
||||
void cpSpacePushContacts(cpSpace *space, int count);
|
||||
|
||||
typedef struct cpPostStepCallback {
|
||||
cpPostStepFunc func;
|
||||
void *key;
|
||||
void *data;
|
||||
} cpPostStepCallback;
|
||||
|
||||
cpPostStepCallback *cpSpaceGetPostStepCallback(cpSpace *space, void *key);
|
||||
|
||||
cpBool cpSpaceArbiterSetFilter(cpArbiter *arb, cpSpace *space);
|
||||
void cpSpaceFilterArbiters(cpSpace *space, cpBody *body, cpShape *filter);
|
||||
|
||||
void cpSpaceActivateBody(cpSpace *space, cpBody *body);
|
||||
void cpSpaceLock(cpSpace *space);
|
||||
void cpSpaceUnlock(cpSpace *space, cpBool runPostStep);
|
||||
|
||||
static inline cpCollisionHandler *
|
||||
cpSpaceLookupHandler(cpSpace *space, cpCollisionType a, cpCollisionType b)
|
||||
{
|
||||
cpCollisionType types[] = {a, b};
|
||||
return (cpCollisionHandler *)cpHashSetFind(space->collisionHandlers, CP_HASH_PAIR(a, b), types);
|
||||
}
|
||||
|
||||
static inline void
|
||||
cpSpaceUncacheArbiter(cpSpace *space, cpArbiter *arb)
|
||||
{
|
||||
cpShape *a = arb->a, *b = arb->b;
|
||||
cpShape *shape_pair[] = {a, b};
|
||||
cpHashValue arbHashID = CP_HASH_PAIR((cpHashValue)a, (cpHashValue)b);
|
||||
cpHashSetRemove(space->cachedArbiters, arbHashID, shape_pair);
|
||||
cpArrayDeleteObj(space->arbiters, arb);
|
||||
}
|
||||
|
||||
void cpShapeUpdateFunc(cpShape *shape, void *unused);
|
||||
cpCollisionID cpSpaceCollideShapes(cpShape *a, cpShape *b, cpCollisionID id, cpSpace *space);
|
||||
|
||||
|
||||
//MARK: Arbiters
|
||||
|
||||
struct cpContact {
|
||||
cpVect p, n;
|
||||
cpFloat dist;
|
||||
|
||||
cpVect r1, r2;
|
||||
cpFloat nMass, tMass, bounce;
|
||||
|
||||
cpFloat jnAcc, jtAcc, jBias;
|
||||
cpFloat bias;
|
||||
|
||||
cpHashValue hash;
|
||||
};
|
||||
|
||||
cpContact* cpContactInit(cpContact *con, cpVect p, cpVect n, cpFloat dist, cpHashValue hash);
|
||||
cpArbiter* cpArbiterInit(cpArbiter *arb, cpShape *a, cpShape *b);
|
||||
|
||||
static inline void
|
||||
cpArbiterCallSeparate(cpArbiter *arb, cpSpace *space)
|
||||
{
|
||||
// The handler needs to be looked up again as the handler cached on the arbiter may have been deleted since the last step.
|
||||
cpCollisionHandler *handler = cpSpaceLookupHandler(space, arb->a->collision_type, arb->b->collision_type);
|
||||
handler->separate(arb, space, handler->data);
|
||||
}
|
||||
|
||||
static inline struct cpArbiterThread *
|
||||
cpArbiterThreadForBody(cpArbiter *arb, cpBody *body)
|
||||
{
|
||||
return (arb->body_a == body ? &arb->thread_a : &arb->thread_b);
|
||||
}
|
||||
|
||||
void cpArbiterUnthread(cpArbiter *arb);
|
||||
|
||||
void cpArbiterUpdate(cpArbiter *arb, cpContact *contacts, int numContacts, struct cpCollisionHandler *handler, cpShape *a, cpShape *b);
|
||||
void cpArbiterPreStep(cpArbiter *arb, cpFloat dt, cpFloat bias, cpFloat slop);
|
||||
void cpArbiterApplyCachedImpulse(cpArbiter *arb, cpFloat dt_coef);
|
||||
void cpArbiterApplyImpulse(cpArbiter *arb);
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,31 +1,34 @@
|
|||
/* Copyright (c) 2013 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.
|
||||
*/
|
||||
|
||||
#ifndef CHIPMUNK_TYPES_H
|
||||
#define CHIPMUNK_TYPES_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <float.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include "TargetConditionals.h"
|
||||
#endif
|
||||
|
||||
#if ((TARGET_OS_IPHONE == 1) || (TARGET_OS_MAC == 1)) && (!defined CP_USE_CGPOINTS)
|
||||
#define CP_USE_CGPOINTS 1
|
||||
#endif
|
||||
|
||||
#if CP_USE_CGPOINTS == 1
|
||||
#if TARGET_OS_IPHONE
|
||||
#import <CoreGraphics/CGGeometry.h>
|
||||
#elif TARGET_OS_MAC
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#endif
|
||||
|
||||
#if defined(__LP64__) && __LP64__
|
||||
#define CP_USE_DOUBLES 1
|
||||
#else
|
||||
#define CP_USE_DOUBLES 0
|
||||
#endif
|
||||
#endif
|
||||
#include <math.h>
|
||||
|
||||
#ifndef CP_USE_DOUBLES
|
||||
// use doubles by default for higher precision
|
||||
#define CP_USE_DOUBLES 1
|
||||
// Use doubles by default for higher precision.
|
||||
#define CP_USE_DOUBLES 0
|
||||
#endif
|
||||
|
||||
/// @defgroup basicTypes Basic Types
|
||||
|
|
@ -82,13 +85,8 @@
|
|||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846264338327950288
|
||||
#endif
|
||||
|
||||
#ifndef M_E
|
||||
#define M_E 2.71828182845904523536028747135266250
|
||||
#endif
|
||||
#define CP_PI ((cpFloat)3.14159265358979323846264338327950288)
|
||||
|
||||
|
||||
/// Return the max of two cpFloats.
|
||||
|
|
@ -136,7 +134,11 @@ static inline cpFloat cpflerpconst(cpFloat f1, cpFloat f2, cpFloat d)
|
|||
}
|
||||
|
||||
/// Hash value type.
|
||||
typedef uintptr_t cpHashValue;
|
||||
#ifdef CP_HASH_VALUE_TYPE
|
||||
typedef CP_HASH_VALUE_TYPE cpHashValue;
|
||||
#else
|
||||
typedef uintptr_t cpHashValue;
|
||||
#endif
|
||||
|
||||
/// Type used internally to cache colliding object info for cpCollideShapes().
|
||||
/// Should be at least 32 bits.
|
||||
|
|
@ -147,7 +149,7 @@ typedef uint32_t cpCollisionID;
|
|||
#ifdef CP_BOOL_TYPE
|
||||
typedef CP_BOOL_TYPE cpBool;
|
||||
#else
|
||||
typedef int cpBool;
|
||||
typedef unsigned char cpBool;
|
||||
#endif
|
||||
|
||||
#ifndef cpTrue
|
||||
|
|
@ -181,11 +183,11 @@ typedef uint32_t cpCollisionID;
|
|||
typedef uintptr_t cpGroup;
|
||||
#endif
|
||||
|
||||
#ifdef CP_LAYERS_TYPE
|
||||
typedef CP_LAYERS_TYPE cpLayers;
|
||||
#ifdef CP_BITMASK_TYPE
|
||||
typedef CP_BITMASK_TYPE cpBitmask;
|
||||
#else
|
||||
/// Type used for cpShape.layers.
|
||||
typedef unsigned int cpLayers;
|
||||
/// Type used for cpShapeFilter category and mask.
|
||||
typedef unsigned int cpBitmask;
|
||||
#endif
|
||||
|
||||
#ifdef CP_TIMESTAMP_TYPE
|
||||
|
|
@ -200,15 +202,21 @@ typedef uint32_t cpCollisionID;
|
|||
#define CP_NO_GROUP ((cpGroup)0)
|
||||
#endif
|
||||
|
||||
#ifndef CP_ALL_LAYERS
|
||||
#ifndef CP_ALL_CATEGORIES
|
||||
/// Value for cpShape.layers signifying that a shape is in every layer.
|
||||
#define CP_ALL_LAYERS (~(cpLayers)0)
|
||||
#define CP_ALL_CATEGORIES (~(cpBitmask)0)
|
||||
#endif
|
||||
|
||||
#ifndef CP_WILDCARD_COLLISION_TYPE
|
||||
/// cpCollisionType value internally reserved for hashing wildcard handlers.
|
||||
#define CP_WILDCARD_COLLISION_TYPE (~(cpCollisionType)0)
|
||||
#endif
|
||||
|
||||
/// @}
|
||||
|
||||
// CGPoints are structurally the same, and allow
|
||||
// easy interoperability with other Cocoa libraries
|
||||
#if CP_USE_CGPOINTS
|
||||
#if CP_USE_CGTYPES
|
||||
typedef CGPoint cpVect;
|
||||
#else
|
||||
/// Chipmunk's 2D vector type.
|
||||
|
|
@ -216,7 +224,19 @@ typedef uint32_t cpCollisionID;
|
|||
typedef struct cpVect{cpFloat x,y;} cpVect;
|
||||
#endif
|
||||
|
||||
#if CP_USE_CGTYPES
|
||||
typedef CGAffineTransform cpTransform;
|
||||
#else
|
||||
/// Column major affine transform.
|
||||
typedef struct cpTransform {
|
||||
cpFloat a, b, c, d, tx, ty;
|
||||
} cpTransform;
|
||||
#endif
|
||||
|
||||
// NUKE
|
||||
typedef struct cpMat2x2 {
|
||||
// Row major [[a, b][c d]]
|
||||
cpFloat a, b, c, d;
|
||||
} cpMat2x2;
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2007 Scott Lembcke
|
||||
/* Copyright (c) 2013 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
|
||||
|
|
@ -36,27 +36,28 @@
|
|||
/// so the results will be unrealistic. You must explicity include the chipmunk_unsafe.h header to use them.
|
||||
/// @{
|
||||
|
||||
#ifndef CHIPMUNK_UNSAFE_HEADER
|
||||
#define CHIPMUNK_UNSAFE_HEADER
|
||||
#ifndef CHIPMUNK_UNSAFE_H
|
||||
#define CHIPMUNK_UNSAFE_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// Set the radius of a circle shape.
|
||||
void cpCircleShapeSetRadius(cpShape *shape, cpFloat radius);
|
||||
CP_EXPORT void cpCircleShapeSetRadius(cpShape *shape, cpFloat radius);
|
||||
/// Set the offset of a circle shape.
|
||||
void cpCircleShapeSetOffset(cpShape *shape, cpVect offset);
|
||||
CP_EXPORT void cpCircleShapeSetOffset(cpShape *shape, cpVect offset);
|
||||
|
||||
/// Set the endpoints of a segment shape.
|
||||
void cpSegmentShapeSetEndpoints(cpShape *shape, cpVect a, cpVect b);
|
||||
CP_EXPORT void cpSegmentShapeSetEndpoints(cpShape *shape, cpVect a, cpVect b);
|
||||
/// Set the radius of a segment shape.
|
||||
void cpSegmentShapeSetRadius(cpShape *shape, cpFloat radius);
|
||||
CP_EXPORT void cpSegmentShapeSetRadius(cpShape *shape, cpFloat radius);
|
||||
|
||||
/// Set the vertexes of a poly shape.
|
||||
void cpPolyShapeSetVerts(cpShape *shape, int numVerts, cpVect *verts, cpVect offset);
|
||||
CP_EXPORT void cpPolyShapeSetVerts(cpShape *shape, int count, cpVect *verts, cpTransform transform);
|
||||
CP_EXPORT void cpPolyShapeSetVertsRaw(cpShape *shape, int count, cpVect *verts);
|
||||
/// Set the radius of a poly shape.
|
||||
void cpPolyShapeSetRadius(cpShape *shape, cpFloat radius);
|
||||
CP_EXPORT void cpPolyShapeSetRadius(cpShape *shape, cpFloat radius);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,161 +0,0 @@
|
|||
/* 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 cpConstraint cpConstraint
|
||||
/// @{
|
||||
|
||||
typedef struct cpConstraintClass cpConstraintClass;
|
||||
|
||||
typedef void (*cpConstraintPreStepImpl)(cpConstraint *constraint, cpFloat dt);
|
||||
typedef void (*cpConstraintApplyCachedImpulseImpl)(cpConstraint *constraint, cpFloat dt_coef);
|
||||
typedef void (*cpConstraintApplyImpulseImpl)(cpConstraint *constraint, cpFloat dt);
|
||||
typedef cpFloat (*cpConstraintGetImpulseImpl)(cpConstraint *constraint);
|
||||
|
||||
/// @private
|
||||
struct cpConstraintClass {
|
||||
cpConstraintPreStepImpl preStep;
|
||||
cpConstraintApplyCachedImpulseImpl applyCachedImpulse;
|
||||
cpConstraintApplyImpulseImpl applyImpulse;
|
||||
cpConstraintGetImpulseImpl getImpulse;
|
||||
};
|
||||
|
||||
/// Callback function type that gets called before solving a joint.
|
||||
typedef void (*cpConstraintPreSolveFunc)(cpConstraint *constraint, cpSpace *space);
|
||||
/// Callback function type that gets called after solving a joint.
|
||||
typedef void (*cpConstraintPostSolveFunc)(cpConstraint *constraint, cpSpace *space);
|
||||
|
||||
|
||||
/// Opaque cpConstraint struct.
|
||||
struct cpConstraint {
|
||||
CP_PRIVATE(const cpConstraintClass *klass);
|
||||
|
||||
/// The first body connected to this constraint.
|
||||
cpBody *a;
|
||||
/// The second body connected to this constraint.
|
||||
cpBody *b;
|
||||
|
||||
CP_PRIVATE(cpSpace *space);
|
||||
|
||||
CP_PRIVATE(cpConstraint *next_a);
|
||||
CP_PRIVATE(cpConstraint *next_b);
|
||||
|
||||
/// The maximum force that this constraint is allowed to use.
|
||||
/// Defaults to infinity.
|
||||
cpFloat maxForce;
|
||||
/// The rate at which joint error is corrected.
|
||||
/// Defaults to pow(1.0 - 0.1, 60.0) meaning that it will
|
||||
/// correct 10% of the error every 1/60th of a second.
|
||||
cpFloat errorBias;
|
||||
/// The maximum rate at which joint error is corrected.
|
||||
/// Defaults to infinity.
|
||||
cpFloat maxBias;
|
||||
|
||||
/// Function called before the solver runs.
|
||||
/// Animate your joint anchors, update your motor torque, etc.
|
||||
cpConstraintPreSolveFunc preSolve;
|
||||
|
||||
/// Function called after the solver runs.
|
||||
/// Use the applied impulse to perform effects like breakable joints.
|
||||
cpConstraintPostSolveFunc postSolve;
|
||||
|
||||
/// User definable data pointer.
|
||||
/// Generally this points to your the game object class so you can access it
|
||||
/// when given a cpConstraint reference in a callback.
|
||||
cpDataPointer data;
|
||||
};
|
||||
|
||||
/// Destroy a constraint.
|
||||
void cpConstraintDestroy(cpConstraint *constraint);
|
||||
/// Destroy and free a constraint.
|
||||
void cpConstraintFree(cpConstraint *constraint);
|
||||
|
||||
/// @private
|
||||
static inline void cpConstraintActivateBodies(cpConstraint *constraint)
|
||||
{
|
||||
cpBody *a = constraint->a; if(a) cpBodyActivate(a);
|
||||
cpBody *b = constraint->b; if(b) cpBodyActivate(b);
|
||||
}
|
||||
|
||||
/// @private
|
||||
#define CP_DefineConstraintStructGetter(type, member, name) \
|
||||
static inline type cpConstraint##Get##name(const cpConstraint *constraint){return constraint->member;}
|
||||
|
||||
/// @private
|
||||
#define CP_DefineConstraintStructSetter(type, member, name) \
|
||||
static inline void cpConstraint##Set##name(cpConstraint *constraint, type value){ \
|
||||
cpConstraintActivateBodies(constraint); \
|
||||
constraint->member = value; \
|
||||
}
|
||||
|
||||
/// @private
|
||||
#define CP_DefineConstraintStructProperty(type, member, name) \
|
||||
CP_DefineConstraintStructGetter(type, member, name) \
|
||||
CP_DefineConstraintStructSetter(type, member, name)
|
||||
|
||||
CP_DefineConstraintStructGetter(cpSpace*, CP_PRIVATE(space), Space)
|
||||
|
||||
CP_DefineConstraintStructGetter(cpBody*, a, A)
|
||||
CP_DefineConstraintStructGetter(cpBody*, b, B)
|
||||
CP_DefineConstraintStructProperty(cpFloat, maxForce, MaxForce)
|
||||
CP_DefineConstraintStructProperty(cpFloat, errorBias, ErrorBias)
|
||||
CP_DefineConstraintStructProperty(cpFloat, maxBias, MaxBias)
|
||||
CP_DefineConstraintStructProperty(cpConstraintPreSolveFunc, preSolve, PreSolveFunc)
|
||||
CP_DefineConstraintStructProperty(cpConstraintPostSolveFunc, postSolve, PostSolveFunc)
|
||||
CP_DefineConstraintStructProperty(cpDataPointer, data, UserData)
|
||||
|
||||
// Get the last impulse applied by this constraint.
|
||||
static inline cpFloat cpConstraintGetImpulse(cpConstraint *constraint)
|
||||
{
|
||||
return constraint->CP_PRIVATE(klass)->getImpulse(constraint);
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
#define cpConstraintCheckCast(constraint, struct) \
|
||||
cpAssertHard(constraint->CP_PRIVATE(klass) == struct##GetClass(), "Constraint is not a "#struct)
|
||||
|
||||
#define CP_DefineConstraintGetter(struct, type, member, name) \
|
||||
static inline type struct##Get##name(const cpConstraint *constraint){ \
|
||||
cpConstraintCheckCast(constraint, struct); \
|
||||
return ((struct *)constraint)->member; \
|
||||
}
|
||||
|
||||
#define CP_DefineConstraintSetter(struct, type, member, name) \
|
||||
static inline void struct##Set##name(cpConstraint *constraint, type value){ \
|
||||
cpConstraintCheckCast(constraint, struct); \
|
||||
cpConstraintActivateBodies(constraint); \
|
||||
((struct *)constraint)->member = value; \
|
||||
}
|
||||
|
||||
#define CP_DefineConstraintProperty(struct, type, member, name) \
|
||||
CP_DefineConstraintGetter(struct, type, member, name) \
|
||||
CP_DefineConstraintSetter(struct, type, member, name)
|
||||
|
||||
#include "cpPinJoint.h"
|
||||
#include "cpSlideJoint.h"
|
||||
#include "cpPivotJoint.h"
|
||||
#include "cpGrooveJoint.h"
|
||||
#include "cpDampedSpring.h"
|
||||
#include "cpDampedRotarySpring.h"
|
||||
#include "cpRotaryLimitJoint.h"
|
||||
#include "cpRatchetJoint.h"
|
||||
#include "cpGearJoint.h"
|
||||
#include "cpSimpleMotor.h"
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
/* 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 cpDampedRotarySpring cpDampedRotarySpring
|
||||
/// @{
|
||||
|
||||
typedef cpFloat (*cpDampedRotarySpringTorqueFunc)(struct cpConstraint *spring, cpFloat relativeAngle);
|
||||
|
||||
const cpConstraintClass *cpDampedRotarySpringGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpDampedRotarySpring {
|
||||
cpConstraint constraint;
|
||||
cpFloat restAngle;
|
||||
cpFloat stiffness;
|
||||
cpFloat damping;
|
||||
cpDampedRotarySpringTorqueFunc springTorqueFunc;
|
||||
|
||||
cpFloat target_wrn;
|
||||
cpFloat w_coef;
|
||||
|
||||
cpFloat iSum;
|
||||
cpFloat jAcc;
|
||||
} cpDampedRotarySpring;
|
||||
|
||||
/// Allocate a damped rotary spring.
|
||||
cpDampedRotarySpring* cpDampedRotarySpringAlloc(void);
|
||||
/// Initialize a damped rotary spring.
|
||||
cpDampedRotarySpring* cpDampedRotarySpringInit(cpDampedRotarySpring *joint, cpBody *a, cpBody *b, cpFloat restAngle, cpFloat stiffness, cpFloat damping);
|
||||
/// Allocate and initialize a damped rotary spring.
|
||||
cpConstraint* cpDampedRotarySpringNew(cpBody *a, cpBody *b, cpFloat restAngle, cpFloat stiffness, cpFloat damping);
|
||||
|
||||
CP_DefineConstraintProperty(cpDampedRotarySpring, cpFloat, restAngle, RestAngle)
|
||||
CP_DefineConstraintProperty(cpDampedRotarySpring, cpFloat, stiffness, Stiffness)
|
||||
CP_DefineConstraintProperty(cpDampedRotarySpring, cpFloat, damping, Damping)
|
||||
CP_DefineConstraintProperty(cpDampedRotarySpring, cpDampedRotarySpringTorqueFunc, springTorqueFunc, SpringTorqueFunc)
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
/* 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 cpDampedSpring cpDampedSpring
|
||||
/// @{
|
||||
|
||||
typedef struct cpDampedSpring cpDampedSpring;
|
||||
|
||||
typedef cpFloat (*cpDampedSpringForceFunc)(cpConstraint *spring, cpFloat dist);
|
||||
|
||||
const cpConstraintClass *cpDampedSpringGetClass(void);
|
||||
|
||||
/// @private
|
||||
struct cpDampedSpring {
|
||||
cpConstraint constraint;
|
||||
cpVect anchr1, anchr2;
|
||||
cpFloat restLength;
|
||||
cpFloat stiffness;
|
||||
cpFloat damping;
|
||||
cpDampedSpringForceFunc springForceFunc;
|
||||
|
||||
cpFloat target_vrn;
|
||||
cpFloat v_coef;
|
||||
|
||||
cpVect r1, r2;
|
||||
cpFloat nMass;
|
||||
cpVect n;
|
||||
|
||||
cpFloat jAcc;
|
||||
};
|
||||
|
||||
/// Allocate a damped spring.
|
||||
cpDampedSpring* cpDampedSpringAlloc(void);
|
||||
/// Initialize a damped spring.
|
||||
cpDampedSpring* cpDampedSpringInit(cpDampedSpring *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat restLength, cpFloat stiffness, cpFloat damping);
|
||||
/// Allocate and initialize a damped spring.
|
||||
cpConstraint* cpDampedSpringNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat restLength, cpFloat stiffness, cpFloat damping);
|
||||
|
||||
CP_DefineConstraintProperty(cpDampedSpring, cpVect, anchr1, Anchr1)
|
||||
CP_DefineConstraintProperty(cpDampedSpring, cpVect, anchr2, Anchr2)
|
||||
CP_DefineConstraintProperty(cpDampedSpring, cpFloat, restLength, RestLength)
|
||||
CP_DefineConstraintProperty(cpDampedSpring, cpFloat, stiffness, Stiffness)
|
||||
CP_DefineConstraintProperty(cpDampedSpring, cpFloat, damping, Damping)
|
||||
CP_DefineConstraintProperty(cpDampedSpring, cpDampedSpringForceFunc, springForceFunc, SpringForceFunc)
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
/* 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 cpGearJoint cpGearJoint
|
||||
/// @{
|
||||
|
||||
const cpConstraintClass *cpGearJointGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpGearJoint {
|
||||
cpConstraint constraint;
|
||||
cpFloat phase, ratio;
|
||||
cpFloat ratio_inv;
|
||||
|
||||
cpFloat iSum;
|
||||
|
||||
cpFloat bias;
|
||||
cpFloat jAcc;
|
||||
} cpGearJoint;
|
||||
|
||||
/// Allocate a gear joint.
|
||||
cpGearJoint* cpGearJointAlloc(void);
|
||||
/// Initialize a gear joint.
|
||||
cpGearJoint* cpGearJointInit(cpGearJoint *joint, cpBody *a, cpBody *b, cpFloat phase, cpFloat ratio);
|
||||
/// Allocate and initialize a gear joint.
|
||||
cpConstraint* cpGearJointNew(cpBody *a, cpBody *b, cpFloat phase, cpFloat ratio);
|
||||
|
||||
CP_DefineConstraintProperty(cpGearJoint, cpFloat, phase, Phase)
|
||||
CP_DefineConstraintGetter(cpGearJoint, cpFloat, ratio, Ratio)
|
||||
/// Set the ratio of a gear joint.
|
||||
void cpGearJointSetRatio(cpConstraint *constraint, cpFloat value);
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
/* 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 cpGrooveJoint cpGrooveJoint
|
||||
/// @{
|
||||
|
||||
const cpConstraintClass *cpGrooveJointGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpGrooveJoint {
|
||||
cpConstraint constraint;
|
||||
cpVect grv_n, grv_a, grv_b;
|
||||
cpVect anchr2;
|
||||
|
||||
cpVect grv_tn;
|
||||
cpFloat clamp;
|
||||
cpVect r1, r2;
|
||||
cpMat2x2 k;
|
||||
|
||||
cpVect jAcc;
|
||||
cpVect bias;
|
||||
} cpGrooveJoint;
|
||||
|
||||
/// Allocate a groove joint.
|
||||
cpGrooveJoint* cpGrooveJointAlloc(void);
|
||||
/// Initialize a groove joint.
|
||||
cpGrooveJoint* cpGrooveJointInit(cpGrooveJoint *joint, cpBody *a, cpBody *b, cpVect groove_a, cpVect groove_b, cpVect anchr2);
|
||||
/// Allocate and initialize a groove joint.
|
||||
cpConstraint* cpGrooveJointNew(cpBody *a, cpBody *b, cpVect groove_a, cpVect groove_b, cpVect anchr2);
|
||||
|
||||
CP_DefineConstraintGetter(cpGrooveJoint, cpVect, grv_a, GrooveA)
|
||||
/// Set endpoint a of a groove joint's groove
|
||||
void cpGrooveJointSetGrooveA(cpConstraint *constraint, cpVect value);
|
||||
CP_DefineConstraintGetter(cpGrooveJoint, cpVect, grv_b, GrooveB)
|
||||
/// Set endpoint b of a groove joint's groove
|
||||
void cpGrooveJointSetGrooveB(cpConstraint *constraint, cpVect value);
|
||||
CP_DefineConstraintProperty(cpGrooveJoint, cpVect, anchr2, Anchr2)
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
/* 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 cpPinJoint cpPinJoint
|
||||
/// @{
|
||||
|
||||
const cpConstraintClass *cpPinJointGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpPinJoint {
|
||||
cpConstraint constraint;
|
||||
cpVect anchr1, anchr2;
|
||||
cpFloat dist;
|
||||
|
||||
cpVect r1, r2;
|
||||
cpVect n;
|
||||
cpFloat nMass;
|
||||
|
||||
cpFloat jnAcc;
|
||||
cpFloat bias;
|
||||
} cpPinJoint;
|
||||
|
||||
/// Allocate a pin joint.
|
||||
cpPinJoint* cpPinJointAlloc(void);
|
||||
/// Initialize a pin joint.
|
||||
cpPinJoint* cpPinJointInit(cpPinJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2);
|
||||
/// Allocate and initialize a pin joint.
|
||||
cpConstraint* cpPinJointNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2);
|
||||
|
||||
CP_DefineConstraintProperty(cpPinJoint, cpVect, anchr1, Anchr1)
|
||||
CP_DefineConstraintProperty(cpPinJoint, cpVect, anchr2, Anchr2)
|
||||
CP_DefineConstraintProperty(cpPinJoint, cpFloat, dist, Dist)
|
||||
|
||||
///@}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
/* 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 cpPivotJoint cpPivotJoint
|
||||
/// @{
|
||||
|
||||
const cpConstraintClass *cpPivotJointGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpPivotJoint {
|
||||
cpConstraint constraint;
|
||||
cpVect anchr1, anchr2;
|
||||
|
||||
cpVect r1, r2;
|
||||
cpMat2x2 k;
|
||||
|
||||
cpVect jAcc;
|
||||
cpVect bias;
|
||||
} cpPivotJoint;
|
||||
|
||||
/// Allocate a pivot joint
|
||||
cpPivotJoint* cpPivotJointAlloc(void);
|
||||
/// Initialize a pivot joint.
|
||||
cpPivotJoint* cpPivotJointInit(cpPivotJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2);
|
||||
/// Allocate and initialize a pivot joint.
|
||||
cpConstraint* cpPivotJointNew(cpBody *a, cpBody *b, cpVect pivot);
|
||||
/// Allocate and initialize a pivot joint with specific anchors.
|
||||
cpConstraint* cpPivotJointNew2(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2);
|
||||
|
||||
CP_DefineConstraintProperty(cpPivotJoint, cpVect, anchr1, Anchr1)
|
||||
CP_DefineConstraintProperty(cpPivotJoint, cpVect, anchr2, Anchr2)
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
/* 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 cpRatchetJoint cpRatchetJoint
|
||||
/// @{
|
||||
|
||||
const cpConstraintClass *cpRatchetJointGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpRatchetJoint {
|
||||
cpConstraint constraint;
|
||||
cpFloat angle, phase, ratchet;
|
||||
|
||||
cpFloat iSum;
|
||||
|
||||
cpFloat bias;
|
||||
cpFloat jAcc;
|
||||
} cpRatchetJoint;
|
||||
|
||||
/// Allocate a ratchet joint.
|
||||
cpRatchetJoint* cpRatchetJointAlloc(void);
|
||||
/// Initialize a ratched joint.
|
||||
cpRatchetJoint* cpRatchetJointInit(cpRatchetJoint *joint, cpBody *a, cpBody *b, cpFloat phase, cpFloat ratchet);
|
||||
/// Allocate and initialize a ratchet joint.
|
||||
cpConstraint* cpRatchetJointNew(cpBody *a, cpBody *b, cpFloat phase, cpFloat ratchet);
|
||||
|
||||
CP_DefineConstraintProperty(cpRatchetJoint, cpFloat, angle, Angle)
|
||||
CP_DefineConstraintProperty(cpRatchetJoint, cpFloat, phase, Phase)
|
||||
CP_DefineConstraintProperty(cpRatchetJoint, cpFloat, ratchet, Ratchet)
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
/* 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 cpRotaryLimitJoint cpRotaryLimitJoint
|
||||
/// @{
|
||||
|
||||
const cpConstraintClass *cpRotaryLimitJointGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpRotaryLimitJoint {
|
||||
cpConstraint constraint;
|
||||
cpFloat min, max;
|
||||
|
||||
cpFloat iSum;
|
||||
|
||||
cpFloat bias;
|
||||
cpFloat jAcc;
|
||||
} cpRotaryLimitJoint;
|
||||
|
||||
/// Allocate a damped rotary limit joint.
|
||||
cpRotaryLimitJoint* cpRotaryLimitJointAlloc(void);
|
||||
/// Initialize a damped rotary limit joint.
|
||||
cpRotaryLimitJoint* cpRotaryLimitJointInit(cpRotaryLimitJoint *joint, cpBody *a, cpBody *b, cpFloat min, cpFloat max);
|
||||
/// Allocate and initialize a damped rotary limit joint.
|
||||
cpConstraint* cpRotaryLimitJointNew(cpBody *a, cpBody *b, cpFloat min, cpFloat max);
|
||||
|
||||
CP_DefineConstraintProperty(cpRotaryLimitJoint, cpFloat, min, Min)
|
||||
CP_DefineConstraintProperty(cpRotaryLimitJoint, cpFloat, max, Max)
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
/* 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 cpSimpleMotor cpSimpleMotor
|
||||
/// @{
|
||||
|
||||
const cpConstraintClass *cpSimpleMotorGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpSimpleMotor {
|
||||
cpConstraint constraint;
|
||||
cpFloat rate;
|
||||
|
||||
cpFloat iSum;
|
||||
|
||||
cpFloat jAcc;
|
||||
} cpSimpleMotor;
|
||||
|
||||
/// Allocate a simple motor.
|
||||
cpSimpleMotor* cpSimpleMotorAlloc(void);
|
||||
/// initialize a simple motor.
|
||||
cpSimpleMotor* cpSimpleMotorInit(cpSimpleMotor *joint, cpBody *a, cpBody *b, cpFloat rate);
|
||||
/// Allocate and initialize a simple motor.
|
||||
cpConstraint* cpSimpleMotorNew(cpBody *a, cpBody *b, cpFloat rate);
|
||||
|
||||
CP_DefineConstraintProperty(cpSimpleMotor, cpFloat, rate, Rate)
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
/* 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 cpSlideJoint cpSlideJoint
|
||||
/// @{
|
||||
|
||||
const cpConstraintClass *cpSlideJointGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpSlideJoint {
|
||||
cpConstraint constraint;
|
||||
cpVect anchr1, anchr2;
|
||||
cpFloat min, max;
|
||||
|
||||
cpVect r1, r2;
|
||||
cpVect n;
|
||||
cpFloat nMass;
|
||||
|
||||
cpFloat jnAcc;
|
||||
cpFloat bias;
|
||||
} cpSlideJoint;
|
||||
|
||||
/// Allocate a slide joint.
|
||||
cpSlideJoint* cpSlideJointAlloc(void);
|
||||
/// Initialize a slide joint.
|
||||
cpSlideJoint* cpSlideJointInit(cpSlideJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max);
|
||||
/// Allocate and initialize a slide joint.
|
||||
cpConstraint* cpSlideJointNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max);
|
||||
|
||||
CP_DefineConstraintProperty(cpSlideJoint, cpVect, anchr1, Anchr1)
|
||||
CP_DefineConstraintProperty(cpSlideJoint, cpVect, anchr2, Anchr2)
|
||||
CP_DefineConstraintProperty(cpSlideJoint, cpFloat, min, Min)
|
||||
CP_DefineConstraintProperty(cpSlideJoint, cpFloat, max, Max)
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,126 +0,0 @@
|
|||
/* 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.
|
||||
*/
|
||||
|
||||
// These are utility routines to use when creating custom constraints.
|
||||
// I'm not sure if this should be part of the private API or not.
|
||||
// I should probably clean up the naming conventions if it is...
|
||||
|
||||
#define CP_DefineClassGetter(t) const cpConstraintClass * t##GetClass(void){return (cpConstraintClass *)&klass;}
|
||||
|
||||
void cpConstraintInit(cpConstraint *constraint, const cpConstraintClass *klass, cpBody *a, cpBody *b);
|
||||
|
||||
static inline cpVect
|
||||
relative_velocity(cpBody *a, cpBody *b, cpVect r1, cpVect r2){
|
||||
cpVect v1_sum = cpvadd(a->v, cpvmult(cpvperp(r1), a->w));
|
||||
cpVect v2_sum = cpvadd(b->v, cpvmult(cpvperp(r2), b->w));
|
||||
|
||||
return cpvsub(v2_sum, v1_sum);
|
||||
}
|
||||
|
||||
static inline cpFloat
|
||||
normal_relative_velocity(cpBody *a, cpBody *b, cpVect r1, cpVect r2, cpVect n){
|
||||
return cpvdot(relative_velocity(a, b, r1, r2), n);
|
||||
}
|
||||
|
||||
static inline void
|
||||
apply_impulse(cpBody *body, cpVect j, cpVect r){
|
||||
body->v = cpvadd(body->v, cpvmult(j, body->m_inv));
|
||||
body->w += body->i_inv*cpvcross(r, j);
|
||||
}
|
||||
|
||||
static inline void
|
||||
apply_impulses(cpBody *a , cpBody *b, cpVect r1, cpVect r2, cpVect j)
|
||||
{
|
||||
apply_impulse(a, cpvneg(j), r1);
|
||||
apply_impulse(b, j, r2);
|
||||
}
|
||||
|
||||
static inline void
|
||||
apply_bias_impulse(cpBody *body, cpVect j, cpVect r)
|
||||
{
|
||||
body->CP_PRIVATE(v_bias) = cpvadd(body->CP_PRIVATE(v_bias), cpvmult(j, body->m_inv));
|
||||
body->CP_PRIVATE(w_bias) += body->i_inv*cpvcross(r, j);
|
||||
}
|
||||
|
||||
static inline void
|
||||
apply_bias_impulses(cpBody *a , cpBody *b, cpVect r1, cpVect r2, cpVect j)
|
||||
{
|
||||
apply_bias_impulse(a, cpvneg(j), r1);
|
||||
apply_bias_impulse(b, j, r2);
|
||||
}
|
||||
|
||||
static inline cpFloat
|
||||
k_scalar_body(cpBody *body, cpVect r, cpVect n)
|
||||
{
|
||||
cpFloat rcn = cpvcross(r, n);
|
||||
return body->m_inv + body->i_inv*rcn*rcn;
|
||||
}
|
||||
|
||||
static inline cpFloat
|
||||
k_scalar(cpBody *a, cpBody *b, cpVect r1, cpVect r2, cpVect n)
|
||||
{
|
||||
cpFloat value = k_scalar_body(a, r1, n) + k_scalar_body(b, r2, n);
|
||||
cpAssertSoft(value != 0.0, "Unsolvable collision or constraint.");
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static inline cpMat2x2
|
||||
k_tensor(cpBody *a, cpBody *b, cpVect r1, cpVect r2)
|
||||
{
|
||||
cpFloat m_sum = a->m_inv + b->m_inv;
|
||||
|
||||
// start with Identity*m_sum
|
||||
cpFloat k11 = m_sum, k12 = 0.0f;
|
||||
cpFloat k21 = 0.0f, k22 = m_sum;
|
||||
|
||||
// add the influence from r1
|
||||
cpFloat a_i_inv = a->i_inv;
|
||||
cpFloat r1xsq = r1.x * r1.x * a_i_inv;
|
||||
cpFloat r1ysq = r1.y * r1.y * a_i_inv;
|
||||
cpFloat r1nxy = -r1.x * r1.y * a_i_inv;
|
||||
k11 += r1ysq; k12 += r1nxy;
|
||||
k21 += r1nxy; k22 += r1xsq;
|
||||
|
||||
// add the influnce from r2
|
||||
cpFloat b_i_inv = b->i_inv;
|
||||
cpFloat r2xsq = r2.x * r2.x * b_i_inv;
|
||||
cpFloat r2ysq = r2.y * r2.y * b_i_inv;
|
||||
cpFloat r2nxy = -r2.x * r2.y * b_i_inv;
|
||||
k11 += r2ysq; k12 += r2nxy;
|
||||
k21 += r2nxy; k22 += r2xsq;
|
||||
|
||||
// invert
|
||||
cpFloat det = k11*k22 - k12*k21;
|
||||
cpAssertSoft(det != 0.0, "Unsolvable constraint.");
|
||||
|
||||
cpFloat det_inv = 1.0f/det;
|
||||
return cpMat2x2New(
|
||||
k22*det_inv, -k12*det_inv,
|
||||
-k21*det_inv, k11*det_inv
|
||||
);
|
||||
}
|
||||
|
||||
static inline cpFloat
|
||||
bias_coef(cpFloat errorBias, cpFloat dt)
|
||||
{
|
||||
return 1.0f - cpfpow(errorBias, dt);
|
||||
}
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2007 Scott Lembcke
|
||||
/* Copyright (c) 2013 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
|
||||
|
|
@ -20,188 +20,126 @@
|
|||
*/
|
||||
|
||||
/// @defgroup cpArbiter cpArbiter
|
||||
/// The cpArbiter struct controls pairs of colliding shapes.
|
||||
/// The cpArbiter struct tracks 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.
|
||||
/// allowing you to retrieve information on the collision or change it.
|
||||
/// A unique arbiter value is used for each pair of colliding objects. It persists until the shapes separate.
|
||||
/// @{
|
||||
|
||||
/// 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 2
|
||||
|
||||
/// @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)
|
||||
/// Get the restitution (elasticity) that will be applied to the pair of colliding objects.
|
||||
CP_EXPORT cpFloat cpArbiterGetRestitution(const cpArbiter *arb);
|
||||
/// Override the restitution (elasticity) that will be applied to the pair of colliding objects.
|
||||
CP_EXPORT void cpArbiterSetRestitution(cpArbiter *arb, cpFloat restitution);
|
||||
/// Get the friction coefficient that will be applied to the pair of colliding objects.
|
||||
CP_EXPORT cpFloat cpArbiterGetFriction(const cpArbiter *arb);
|
||||
/// Override the friction coefficient that will be applied to the pair of colliding objects.
|
||||
CP_EXPORT void cpArbiterSetFriction(cpArbiter *arb, cpFloat friction);
|
||||
|
||||
// Get the relative surface velocity of the two shapes in contact.
|
||||
cpVect cpArbiterGetSurfaceVelocity(cpArbiter *arb);
|
||||
CP_EXPORT cpVect cpArbiterGetSurfaceVelocity(cpArbiter *arb);
|
||||
|
||||
// Override the relative surface velocity of the two shapes in contact.
|
||||
// By default this is calculated to be the difference of the two
|
||||
// surface velocities clamped to the tangent plane.
|
||||
void cpArbiterSetSurfaceVelocity(cpArbiter *arb, cpVect vr);
|
||||
// By default this is calculated to be the difference of the two surface velocities clamped to the tangent plane.
|
||||
CP_EXPORT void cpArbiterSetSurfaceVelocity(cpArbiter *arb, cpVect vr);
|
||||
|
||||
CP_DefineArbiterStructProperty(cpDataPointer, data, UserData)
|
||||
/// Get the user data pointer associated with this pair of colliding objects.
|
||||
CP_EXPORT cpDataPointer cpArbiterGetUserData(const cpArbiter *arb);
|
||||
/// Set a user data point associated with this pair of colliding objects.
|
||||
/// If you need to perform any cleanup for this pointer, you must do it yourself, in the separate callback for instance.
|
||||
CP_EXPORT void cpArbiterSetUserData(cpArbiter *arb, cpDataPointer 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);
|
||||
CP_EXPORT cpVect cpArbiterTotalImpulse(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);
|
||||
CP_EXPORT 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);
|
||||
/// Mark a collision pair to be ignored until the two objects separate.
|
||||
/// Pre-solve and post-solve callbacks will not be called, but the separate callback will be called.
|
||||
CP_EXPORT cpBool 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);
|
||||
}
|
||||
}
|
||||
CP_EXPORT void cpArbiterGetShapes(const cpArbiter *arb, cpShape **a, cpShape **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;
|
||||
}
|
||||
CP_EXPORT void cpArbiterGetBodies(const cpArbiter *arb, cpBody **a, cpBody **b);
|
||||
|
||||
/// 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 {
|
||||
struct cpContactPointSet {
|
||||
/// The number of contact points in the set.
|
||||
int count;
|
||||
|
||||
/// The normal of the collision.
|
||||
cpVect normal;
|
||||
|
||||
/// 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;
|
||||
/// The position of the contact on the surface of each shape.
|
||||
cpVect pointA, pointB;
|
||||
/// Penetration distance of the two shapes. Overlapping means it will be negative.
|
||||
/// This value is calculated as cpvdot(cpvsub(point2, point1), normal) and is ignored by cpArbiterSetContactPointSet().
|
||||
cpFloat distance;
|
||||
} points[CP_MAX_CONTACTS_PER_ARBITER];
|
||||
} cpContactPointSet;
|
||||
};
|
||||
|
||||
/// Return a contact set from an arbiter.
|
||||
cpContactPointSet cpArbiterGetContactPointSet(const cpArbiter *arb);
|
||||
CP_EXPORT cpContactPointSet cpArbiterGetContactPointSet(const cpArbiter *arb);
|
||||
|
||||
/// Replace the contact point set for an arbiter.
|
||||
/// This can be a very powerful feature, but use it with caution!
|
||||
void cpArbiterSetContactPointSet(cpArbiter *arb, cpContactPointSet *set);
|
||||
CP_EXPORT void cpArbiterSetContactPointSet(cpArbiter *arb, cpContactPointSet *set);
|
||||
|
||||
/// Returns true if this is the first step a pair of objects started colliding.
|
||||
cpBool cpArbiterIsFirstContact(const cpArbiter *arb);
|
||||
CP_EXPORT cpBool cpArbiterIsFirstContact(const cpArbiter *arb);
|
||||
/// Returns true if the separate callback is due to a shape being removed from the space.
|
||||
CP_EXPORT cpBool cpArbiterIsRemoval(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);
|
||||
CP_EXPORT int cpArbiterGetCount(const cpArbiter *arb);
|
||||
/// Get the normal of the collision.
|
||||
CP_EXPORT cpVect cpArbiterGetNormal(const cpArbiter *arb);
|
||||
/// Get the position of the @c ith contact point on the surface of the first shape.
|
||||
CP_EXPORT cpVect cpArbiterGetPointA(const cpArbiter *arb, int i);
|
||||
/// Get the position of the @c ith contact point on the surface of the second shape.
|
||||
CP_EXPORT cpVect cpArbiterGetPointB(const cpArbiter *arb, int i);
|
||||
/// Get the depth of the @c ith contact point.
|
||||
cpFloat cpArbiterGetDepth(const cpArbiter *arb, int i);
|
||||
CP_EXPORT cpFloat cpArbiterGetDepth(const cpArbiter *arb, int i);
|
||||
|
||||
/// If you want a custom callback to invoke the wildcard callback for the first collision type, you must call this function explicitly.
|
||||
/// You must decide how to handle the wildcard's return value since it may disagree with the other wildcard handler's return value or your own.
|
||||
CP_EXPORT cpBool cpArbiterCallWildcardBeginA(cpArbiter *arb, cpSpace *space);
|
||||
/// If you want a custom callback to invoke the wildcard callback for the second collision type, you must call this function explicitly.
|
||||
/// You must decide how to handle the wildcard's return value since it may disagree with the other wildcard handler's return value or your own.
|
||||
CP_EXPORT cpBool cpArbiterCallWildcardBeginB(cpArbiter *arb, cpSpace *space);
|
||||
|
||||
/// If you want a custom callback to invoke the wildcard callback for the first collision type, you must call this function explicitly.
|
||||
/// You must decide how to handle the wildcard's return value since it may disagree with the other wildcard handler's return value or your own.
|
||||
CP_EXPORT cpBool cpArbiterCallWildcardPreSolveA(cpArbiter *arb, cpSpace *space);
|
||||
/// If you want a custom callback to invoke the wildcard callback for the second collision type, you must call this function explicitly.
|
||||
/// You must decide how to handle the wildcard's return value since it may disagree with the other wildcard handler's return value or your own.
|
||||
CP_EXPORT cpBool cpArbiterCallWildcardPreSolveB(cpArbiter *arb, cpSpace *space);
|
||||
|
||||
/// If you want a custom callback to invoke the wildcard callback for the first collision type, you must call this function explicitly.
|
||||
CP_EXPORT void cpArbiterCallWildcardPostSolveA(cpArbiter *arb, cpSpace *space);
|
||||
/// If you want a custom callback to invoke the wildcard callback for the second collision type, you must call this function explicitly.
|
||||
CP_EXPORT void cpArbiterCallWildcardPostSolveB(cpArbiter *arb, cpSpace *space);
|
||||
|
||||
/// If you want a custom callback to invoke the wildcard callback for the first collision type, you must call this function explicitly.
|
||||
CP_EXPORT void cpArbiterCallWildcardSeparateA(cpArbiter *arb, cpSpace *space);
|
||||
/// If you want a custom callback to invoke the wildcard callback for the second collision type, you must call this function explicitly.
|
||||
CP_EXPORT void cpArbiterCallWildcardSeparateB(cpArbiter *arb, cpSpace *space);
|
||||
|
||||
/// @}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2007 Scott Lembcke
|
||||
/* Copyright (c) 2013 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
|
||||
|
|
@ -19,6 +19,12 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef CHIPMUNK_BB_H
|
||||
#define CHIPMUNK_BB_H
|
||||
|
||||
#include "chipmunk_types.h"
|
||||
#include "cpVect.h"
|
||||
|
||||
/// @defgroup cpBBB cpBB
|
||||
/// Chipmunk's axis-aligned 2D bounding box type along with a few handy routines.
|
||||
/// @{
|
||||
|
|
@ -35,10 +41,17 @@ static inline cpBB cpBBNew(const cpFloat l, const cpFloat b, const cpFloat r, co
|
|||
return bb;
|
||||
}
|
||||
|
||||
/// Constructs a cpBB centered on a point with the given extents (half sizes).
|
||||
static inline cpBB
|
||||
cpBBNewForExtents(const cpVect c, const cpFloat hw, const cpFloat hh)
|
||||
{
|
||||
return cpBBNew(c.x - hw, c.y - hh, c.x + hw, c.y + hh);
|
||||
}
|
||||
|
||||
/// Constructs a cpBB for a circle with the given position and radius.
|
||||
static inline cpBB cpBBNewForCircle(const cpVect p, const cpFloat r)
|
||||
{
|
||||
return cpBBNew(p.x - r, p.y - r, p.x + r, p.y + r);
|
||||
return cpBBNewForExtents(p, r, r);
|
||||
}
|
||||
|
||||
/// Returns true if @c a and @c b intersect.
|
||||
|
|
@ -102,6 +115,9 @@ static inline cpFloat cpBBMergedArea(cpBB a, cpBB b)
|
|||
static inline cpFloat cpBBSegmentQuery(cpBB bb, cpVect a, cpVect b)
|
||||
{
|
||||
cpFloat idx = 1.0f/(b.x - a.x);
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable: 4056)
|
||||
#endif
|
||||
cpFloat tx1 = (bb.l == a.x ? -INFINITY : (bb.l - a.x)*idx);
|
||||
cpFloat tx2 = (bb.r == a.x ? INFINITY : (bb.r - a.x)*idx);
|
||||
cpFloat txmin = cpfmin(tx1, tx2);
|
||||
|
|
@ -110,6 +126,9 @@ static inline cpFloat cpBBSegmentQuery(cpBB bb, cpVect a, cpVect b)
|
|||
cpFloat idy = 1.0f/(b.y - a.y);
|
||||
cpFloat ty1 = (bb.b == a.y ? -INFINITY : (bb.b - a.y)*idy);
|
||||
cpFloat ty2 = (bb.t == a.y ? INFINITY : (bb.t - a.y)*idy);
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(default: 4056)
|
||||
#endif
|
||||
cpFloat tymin = cpfmin(ty1, ty2);
|
||||
cpFloat tymax = cpfmax(ty1, ty2);
|
||||
|
||||
|
|
@ -136,8 +155,33 @@ cpBBClampVect(const cpBB bb, const cpVect v)
|
|||
return cpv(cpfclamp(v.x, bb.l, bb.r), cpfclamp(v.y, bb.b, bb.t));
|
||||
}
|
||||
|
||||
// TODO edge case issue
|
||||
/// Wrap a vector to a bounding box.
|
||||
cpVect cpBBWrapVect(const cpBB bb, const cpVect v); // wrap a vector to a bbox
|
||||
static inline cpVect
|
||||
cpBBWrapVect(const cpBB bb, const cpVect v)
|
||||
{
|
||||
cpFloat dx = cpfabs(bb.r - bb.l);
|
||||
cpFloat modx = cpfmod(v.x - bb.l, dx);
|
||||
cpFloat x = (modx > 0.0f) ? modx : modx + dx;
|
||||
|
||||
cpFloat dy = cpfabs(bb.t - bb.b);
|
||||
cpFloat mody = cpfmod(v.y - bb.b, dy);
|
||||
cpFloat y = (mody > 0.0f) ? mody : mody + dy;
|
||||
|
||||
return cpv(x + bb.l, y + bb.b);
|
||||
}
|
||||
|
||||
/// Returns a bounding box offseted by @c v.
|
||||
static inline cpBB
|
||||
cpBBOffset(const cpBB bb, const cpVect v)
|
||||
{
|
||||
return cpBBNew(
|
||||
bb.l + v.x,
|
||||
bb.b + v.y,
|
||||
bb.r + v.x,
|
||||
bb.t + v.y
|
||||
);
|
||||
}
|
||||
|
||||
///@}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2007 Scott Lembcke
|
||||
/* Copyright (c) 2013 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
|
||||
|
|
@ -25,227 +25,165 @@
|
|||
/// They are given a shape by creating collision shapes (cpShape) that point to the body.
|
||||
/// @{
|
||||
|
||||
typedef enum cpBodyType {
|
||||
/// A dynamic body is one that is affected by gravity, forces, and collisions.
|
||||
/// This is the default body type.
|
||||
CP_BODY_TYPE_DYNAMIC,
|
||||
/// A kinematic body is an infinite mass, user controlled body that is not affected by gravity, forces or collisions.
|
||||
/// Instead the body only moves based on it's velocity.
|
||||
/// Dynamic bodies collide normally with kinematic bodies, though the kinematic body will be unaffected.
|
||||
/// Collisions between two kinematic bodies, or a kinematic body and a static body produce collision callbacks, but no collision response.
|
||||
CP_BODY_TYPE_KINEMATIC,
|
||||
/// A static body is a body that never (or rarely) moves. If you move a static body, you must call one of the cpSpaceReindex*() functions.
|
||||
/// Chipmunk uses this information to optimize the collision detection.
|
||||
/// Static bodies do not produce collision callbacks when colliding with other static bodies.
|
||||
CP_BODY_TYPE_STATIC,
|
||||
} cpBodyType;
|
||||
|
||||
/// 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);
|
||||
CP_EXPORT cpBody* cpBodyAlloc(void);
|
||||
/// Initialize a cpBody.
|
||||
cpBody* cpBodyInit(cpBody *body, cpFloat m, cpFloat i);
|
||||
CP_EXPORT cpBody* cpBodyInit(cpBody *body, cpFloat mass, cpFloat moment);
|
||||
/// Allocate and initialize a cpBody.
|
||||
cpBody* cpBodyNew(cpFloat m, cpFloat i);
|
||||
CP_EXPORT cpBody* cpBodyNew(cpFloat mass, cpFloat moment);
|
||||
|
||||
/// Initialize a static cpBody.
|
||||
cpBody* cpBodyInitStatic(cpBody *body);
|
||||
/// Allocate and initialize a static cpBody.
|
||||
cpBody* cpBodyNewStatic(void);
|
||||
/// Allocate and initialize a cpBody, and set it as a kinematic body.
|
||||
CP_EXPORT cpBody* cpBodyNewKinematic(void);
|
||||
/// Allocate and initialize a cpBody, and set it as a static body.
|
||||
CP_EXPORT cpBody* cpBodyNewStatic(void);
|
||||
|
||||
/// Destroy a cpBody.
|
||||
void cpBodyDestroy(cpBody *body);
|
||||
CP_EXPORT 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
|
||||
CP_EXPORT void cpBodyFree(cpBody *body);
|
||||
|
||||
// Defined in cpSpace.c
|
||||
/// Wake up a sleeping or idle body.
|
||||
void cpBodyActivate(cpBody *body);
|
||||
CP_EXPORT void cpBodyActivate(cpBody *body);
|
||||
/// Wake up any sleeping or idle bodies touching a static body.
|
||||
void cpBodyActivateStatic(cpBody *body, cpShape *filter);
|
||||
CP_EXPORT void cpBodyActivateStatic(cpBody *body, cpShape *filter);
|
||||
|
||||
/// Force a body to fall asleep immediately.
|
||||
void cpBodySleep(cpBody *body);
|
||||
CP_EXPORT void cpBodySleep(cpBody *body);
|
||||
/// Force a body to fall asleep immediately along with other bodies in a group.
|
||||
void cpBodySleepWithGroup(cpBody *body, cpBody *group);
|
||||
CP_EXPORT 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));
|
||||
}
|
||||
CP_EXPORT cpBool cpBodyIsSleeping(const cpBody *body);
|
||||
|
||||
/// Returns true if the body is static.
|
||||
static inline cpBool cpBodyIsStatic(const cpBody *body)
|
||||
{
|
||||
return CP_PRIVATE(body->node).idleTime == INFINITY;
|
||||
}
|
||||
/// Get the type of the body.
|
||||
CP_EXPORT cpBodyType cpBodyGetType(cpBody *body);
|
||||
/// Set the type of the body.
|
||||
CP_EXPORT void cpBodySetType(cpBody *body, cpBodyType type);
|
||||
|
||||
/// Returns true if the body has not been added to a space.
|
||||
/// Note: Static bodies are a subtype of rogue bodies.
|
||||
static inline cpBool cpBodyIsRogue(const cpBody *body)
|
||||
{
|
||||
return (body->CP_PRIVATE(space) == ((cpSpace*)0));
|
||||
}
|
||||
/// Get the space this body is added to.
|
||||
CP_EXPORT cpSpace* cpBodyGetSpace(const cpBody *body);
|
||||
|
||||
/// Get the mass of the body.
|
||||
CP_EXPORT cpFloat cpBodyGetMass(const cpBody *body);
|
||||
/// Set the mass of the body.
|
||||
CP_EXPORT void cpBodySetMass(cpBody *body, cpFloat m);
|
||||
|
||||
#define CP_DefineBodyStructGetter(type, member, name) \
|
||||
static inline type cpBodyGet##name(const cpBody *body){return body->member;}
|
||||
/// Get the moment of inertia of the body.
|
||||
CP_EXPORT cpFloat cpBodyGetMoment(const cpBody *body);
|
||||
/// Set the moment of inertia of the body.
|
||||
CP_EXPORT void cpBodySetMoment(cpBody *body, cpFloat i);
|
||||
|
||||
#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)
|
||||
CP_EXPORT cpVect cpBodyGetPosition(const cpBody *body);
|
||||
/// Set the position of the body.
|
||||
CP_EXPORT void cpBodySetPosition(cpBody *body, cpVect pos);
|
||||
|
||||
/// Default Integration functions.
|
||||
void cpBodyUpdateVelocity(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt);
|
||||
void cpBodyUpdatePosition(cpBody *body, cpFloat dt);
|
||||
/// Get the offset of the center of gravity in body local coordinates.
|
||||
CP_EXPORT cpVect cpBodyGetCenterOfGravity(const cpBody *body);
|
||||
/// Set the offset of the center of gravity in body local coordinates.
|
||||
CP_EXPORT void cpBodySetCenterOfGravity(cpBody *body, cpVect cog);
|
||||
|
||||
/// Get the velocity of the body.
|
||||
CP_EXPORT cpVect cpBodyGetVelocity(const cpBody *body);
|
||||
/// Set the velocity of the body.
|
||||
CP_EXPORT void cpBodySetVelocity(cpBody *body, cpVect velocity);
|
||||
|
||||
/// Get the force applied to the body for the next time step.
|
||||
CP_EXPORT cpVect cpBodyGetForce(const cpBody *body);
|
||||
/// Set the force applied to the body for the next time step.
|
||||
CP_EXPORT void cpBodySetForce(cpBody *body, cpVect force);
|
||||
|
||||
/// Get the angle of the body.
|
||||
CP_EXPORT cpFloat cpBodyGetAngle(const cpBody *body);
|
||||
/// Set the angle of a body.
|
||||
CP_EXPORT void cpBodySetAngle(cpBody *body, cpFloat a);
|
||||
|
||||
/// Get the angular velocity of the body.
|
||||
CP_EXPORT cpFloat cpBodyGetAngularVelocity(const cpBody *body);
|
||||
/// Set the angular velocity of the body.
|
||||
CP_EXPORT void cpBodySetAngularVelocity(cpBody *body, cpFloat angularVelocity);
|
||||
|
||||
/// Get the torque applied to the body for the next time step.
|
||||
CP_EXPORT cpFloat cpBodyGetTorque(const cpBody *body);
|
||||
/// Set the torque applied to the body for the next time step.
|
||||
CP_EXPORT void cpBodySetTorque(cpBody *body, cpFloat torque);
|
||||
|
||||
/// Get the rotation vector of the body. (The x basis vector of it's transform.)
|
||||
CP_EXPORT cpVect cpBodyGetRotation(const cpBody *body);
|
||||
|
||||
/// Get the user data pointer assigned to the body.
|
||||
CP_EXPORT cpDataPointer cpBodyGetUserData(const cpBody *body);
|
||||
/// Set the user data pointer assigned to the body.
|
||||
CP_EXPORT void cpBodySetUserData(cpBody *body, cpDataPointer userData);
|
||||
|
||||
/// Set the callback used to update a body's velocity.
|
||||
CP_EXPORT void cpBodySetVelocityUpdateFunc(cpBody *body, cpBodyVelocityFunc velocityFunc);
|
||||
/// Set the callback used to update a body's position.
|
||||
/// NOTE: It's not generally recommended to override this unless you call the default position update function.
|
||||
CP_EXPORT void cpBodySetPositionUpdateFunc(cpBody *body, cpBodyPositionFunc positionFunc);
|
||||
|
||||
/// Default velocity integration function..
|
||||
CP_EXPORT void cpBodyUpdateVelocity(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt);
|
||||
/// Default position integration function.
|
||||
CP_EXPORT 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));
|
||||
}
|
||||
|
||||
CP_EXPORT cpVect cpBodyLocalToWorld(const cpBody *body, const cpVect point);
|
||||
/// 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);
|
||||
}
|
||||
CP_EXPORT cpVect cpBodyWorldToLocal(const cpBody *body, const cpVect point);
|
||||
|
||||
/// 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);
|
||||
/// Apply a force to a body. Both the force and point are expressed in world coordinates.
|
||||
CP_EXPORT void cpBodyApplyForceAtWorldPoint(cpBody *body, cpVect force, cpVect point);
|
||||
/// Apply a force to a body. Both the force and point are expressed in body local coordinates.
|
||||
CP_EXPORT void cpBodyApplyForceAtLocalPoint(cpBody *body, cpVect force, cpVect point);
|
||||
|
||||
/// Apply an impulse to a body. Both the impulse and point are expressed in world coordinates.
|
||||
CP_EXPORT void cpBodyApplyImpulseAtWorldPoint(cpBody *body, cpVect impulse, cpVect point);
|
||||
/// Apply an impulse to a body. Both the impulse and point are expressed in body local coordinates.
|
||||
CP_EXPORT void cpBodyApplyImpulseAtLocalPoint(cpBody *body, cpVect impulse, cpVect point);
|
||||
|
||||
/// Get the velocity on a body (in world units) at a point on the body in world coordinates.
|
||||
cpVect cpBodyGetVelAtWorldPoint(cpBody *body, cpVect point);
|
||||
CP_EXPORT cpVect cpBodyGetVelocityAtWorldPoint(const 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);
|
||||
CP_EXPORT cpVect cpBodyGetVelocityAtLocalPoint(const 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);
|
||||
}
|
||||
/// Get the amount of kinetic energy contained by the body.
|
||||
CP_EXPORT cpFloat cpBodyKineticEnergy(const cpBody *body);
|
||||
|
||||
/// 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);
|
||||
CP_EXPORT 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);
|
||||
CP_EXPORT 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);
|
||||
CP_EXPORT void cpBodyEachArbiter(cpBody *body, cpBodyArbiterIteratorFunc func, void *data);
|
||||
|
||||
///@}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2007 Scott Lembcke
|
||||
/* Copyright (c) 2013 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
|
||||
|
|
@ -22,60 +22,35 @@
|
|||
/// @defgroup cpPolyShape cpPolyShape
|
||||
/// @{
|
||||
|
||||
/// @private
|
||||
typedef struct cpSplittingPlane {
|
||||
cpVect n;
|
||||
cpFloat d;
|
||||
} cpSplittingPlane;
|
||||
|
||||
/// @private
|
||||
typedef struct cpPolyShape {
|
||||
cpShape shape;
|
||||
|
||||
int numVerts;
|
||||
cpVect *verts, *tVerts;
|
||||
cpSplittingPlane *planes, *tPlanes;
|
||||
|
||||
cpFloat r;
|
||||
} cpPolyShape;
|
||||
|
||||
/// Allocate a polygon shape.
|
||||
cpPolyShape* cpPolyShapeAlloc(void);
|
||||
/// Initialize a polygon shape.
|
||||
CP_EXPORT cpPolyShape* cpPolyShapeAlloc(void);
|
||||
/// Initialize a polygon shape with rounded corners.
|
||||
/// A convex hull will be created from the vertexes.
|
||||
cpPolyShape* cpPolyShapeInit(cpPolyShape *poly, cpBody *body, int numVerts, const cpVect *verts, cpVect offset);
|
||||
/// Initialize a polygon shape.
|
||||
CP_EXPORT cpPolyShape* cpPolyShapeInit(cpPolyShape *poly, cpBody *body, int count, const cpVect *verts, cpTransform transform, cpFloat radius);
|
||||
/// Initialize a polygon shape with rounded corners.
|
||||
/// The vertexes must be convex with a counter-clockwise winding.
|
||||
CP_EXPORT cpPolyShape* cpPolyShapeInitRaw(cpPolyShape *poly, cpBody *body, int count, const cpVect *verts, cpFloat radius);
|
||||
/// Allocate and initialize a polygon shape with rounded corners.
|
||||
/// A convex hull will be created from the vertexes.
|
||||
cpPolyShape* cpPolyShapeInit2(cpPolyShape *poly, cpBody *body, int numVerts, const cpVect *verts, cpVect offset, cpFloat radius);
|
||||
/// Allocate and initialize a polygon shape.
|
||||
/// A convex hull will be created from the vertexes.
|
||||
cpShape* cpPolyShapeNew(cpBody *body, int numVerts, const cpVect *verts, cpVect offset);
|
||||
/// Allocate and initialize a polygon shape.
|
||||
/// A convex hull will be created from the vertexes.
|
||||
cpShape* cpPolyShapeNew2(cpBody *body, int numVerts, const cpVect *verts, cpVect offset, cpFloat radius);
|
||||
CP_EXPORT cpShape* cpPolyShapeNew(cpBody *body, int count, const cpVect *verts, cpTransform transform, cpFloat radius);
|
||||
/// Allocate and initialize a polygon shape with rounded corners.
|
||||
/// The vertexes must be convex with a counter-clockwise winding.
|
||||
CP_EXPORT cpShape* cpPolyShapeNewRaw(cpBody *body, int count, const cpVect *verts, cpFloat radius);
|
||||
|
||||
/// Initialize a box shaped polygon shape.
|
||||
cpPolyShape* cpBoxShapeInit(cpPolyShape *poly, cpBody *body, cpFloat width, cpFloat height);
|
||||
/// Initialize an offset box shaped polygon shape.
|
||||
cpPolyShape* cpBoxShapeInit2(cpPolyShape *poly, cpBody *body, cpBB box);
|
||||
/// Initialize an offset box shaped polygon shape.
|
||||
cpPolyShape* cpBoxShapeInit3(cpPolyShape *poly, cpBody *body, cpBB box, cpFloat radius);
|
||||
/// Initialize a box shaped polygon shape with rounded corners.
|
||||
CP_EXPORT cpPolyShape* cpBoxShapeInit(cpPolyShape *poly, cpBody *body, cpFloat width, cpFloat height, cpFloat radius);
|
||||
/// Initialize an offset box shaped polygon shape with rounded corners.
|
||||
CP_EXPORT cpPolyShape* cpBoxShapeInit2(cpPolyShape *poly, cpBody *body, cpBB box, cpFloat radius);
|
||||
/// Allocate and initialize a box shaped polygon shape.
|
||||
cpShape* cpBoxShapeNew(cpBody *body, cpFloat width, cpFloat height);
|
||||
CP_EXPORT cpShape* cpBoxShapeNew(cpBody *body, cpFloat width, cpFloat height, cpFloat radius);
|
||||
/// Allocate and initialize an offset box shaped polygon shape.
|
||||
cpShape* cpBoxShapeNew2(cpBody *body, cpBB box);
|
||||
/// Allocate and initialize an offset box shaped polygon shape.
|
||||
cpShape* cpBoxShapeNew3(cpBody *body, cpBB box, cpFloat radius);
|
||||
|
||||
/// Check that a set of vertexes is convex and has a clockwise winding.
|
||||
/// NOTE: Due to floating point precision issues, hulls created with cpQuickHull() are not guaranteed to validate!
|
||||
cpBool cpPolyValidate(const cpVect *verts, const int numVerts);
|
||||
CP_EXPORT cpShape* cpBoxShapeNew2(cpBody *body, cpBB box, cpFloat radius);
|
||||
|
||||
/// Get the number of verts in a polygon shape.
|
||||
int cpPolyShapeGetNumVerts(const cpShape *shape);
|
||||
CP_EXPORT int cpPolyShapeGetCount(const cpShape *shape);
|
||||
/// Get the @c ith vertex of a polygon shape.
|
||||
cpVect cpPolyShapeGetVert(const cpShape *shape, int idx);
|
||||
CP_EXPORT cpVect cpPolyShapeGetVert(const cpShape *shape, int index);
|
||||
/// Get the radius of a polygon shape.
|
||||
cpFloat cpPolyShapeGetRadius(const cpShape *shape);
|
||||
CP_EXPORT cpFloat cpPolyShapeGetRadius(const cpShape *shape);
|
||||
|
||||
/// @}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2007 Scott Lembcke
|
||||
/* Copyright (c) 2013 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
|
||||
|
|
@ -23,210 +23,177 @@
|
|||
/// The cpShape struct defines the shape of a rigid body.
|
||||
/// @{
|
||||
|
||||
typedef struct cpShapeClass cpShapeClass;
|
||||
|
||||
/// Nearest point query info struct.
|
||||
typedef struct cpNearestPointQueryInfo {
|
||||
/// Point query info struct.
|
||||
typedef struct cpPointQueryInfo {
|
||||
/// The nearest shape, NULL if no shape was within range.
|
||||
cpShape *shape;
|
||||
const cpShape *shape;
|
||||
/// The closest point on the shape's surface. (in world space coordinates)
|
||||
cpVect p;
|
||||
cpVect point;
|
||||
/// The distance to the point. The distance is negative if the point is inside the shape.
|
||||
cpFloat d;
|
||||
cpFloat distance;
|
||||
/// The gradient of the signed distance function.
|
||||
/// The same as info.p/info.d, but accurate even for very small values of info.d.
|
||||
cpVect g;
|
||||
} cpNearestPointQueryInfo;
|
||||
/// The value should be similar to info.p/info.d, but accurate even for very small values of info.d.
|
||||
cpVect gradient;
|
||||
} cpPointQueryInfo;
|
||||
|
||||
/// Segment query info struct.
|
||||
typedef struct cpSegmentQueryInfo {
|
||||
/// The shape that was hit, NULL if no collision occured.
|
||||
cpShape *shape;
|
||||
/// The normalized distance along the query segment in the range [0, 1].
|
||||
cpFloat t;
|
||||
/// The shape that was hit, or NULL if no collision occured.
|
||||
const cpShape *shape;
|
||||
/// The point of impact.
|
||||
cpVect point;
|
||||
/// The normal of the surface hit.
|
||||
cpVect n;
|
||||
cpVect normal;
|
||||
/// The normalized distance along the query segment in the range [0, 1].
|
||||
cpFloat alpha;
|
||||
} cpSegmentQueryInfo;
|
||||
|
||||
/// @private
|
||||
typedef enum cpShapeType{
|
||||
CP_CIRCLE_SHAPE,
|
||||
CP_SEGMENT_SHAPE,
|
||||
CP_POLY_SHAPE,
|
||||
CP_NUM_SHAPES
|
||||
} cpShapeType;
|
||||
|
||||
typedef cpBB (*cpShapeCacheDataImpl)(cpShape *shape, cpVect p, cpVect rot);
|
||||
typedef void (*cpShapeDestroyImpl)(cpShape *shape);
|
||||
typedef void (*cpShapeNearestPointQueryImpl)(cpShape *shape, cpVect p, cpNearestPointQueryInfo *info);
|
||||
typedef void (*cpShapeSegmentQueryImpl)(cpShape *shape, cpVect a, cpVect b, cpSegmentQueryInfo *info);
|
||||
|
||||
/// @private
|
||||
struct cpShapeClass {
|
||||
cpShapeType type;
|
||||
|
||||
cpShapeCacheDataImpl cacheData;
|
||||
cpShapeDestroyImpl destroy;
|
||||
cpShapeNearestPointQueryImpl nearestPointQuery;
|
||||
cpShapeSegmentQueryImpl segmentQuery;
|
||||
};
|
||||
|
||||
/// Opaque collision shape struct.
|
||||
struct cpShape {
|
||||
CP_PRIVATE(const cpShapeClass *klass);
|
||||
|
||||
/// The rigid body this collision shape is attached to.
|
||||
cpBody *body;
|
||||
|
||||
/// The current bounding box of the shape.
|
||||
cpBB bb;
|
||||
|
||||
/// Sensor flag.
|
||||
/// Sensor shapes call collision callbacks but don't produce collisions.
|
||||
cpBool sensor;
|
||||
|
||||
/// Coefficient of restitution. (elasticity)
|
||||
cpFloat e;
|
||||
/// Coefficient of friction.
|
||||
cpFloat u;
|
||||
/// Surface velocity used when solving for friction.
|
||||
cpVect surface_v;
|
||||
|
||||
/// User definable data pointer.
|
||||
/// Generally this points to your the game object class so you can access it
|
||||
/// when given a cpShape reference in a callback.
|
||||
cpDataPointer data;
|
||||
|
||||
/// Collision type of this shape used when picking collision handlers.
|
||||
cpCollisionType collision_type;
|
||||
/// Group of this shape. Shapes in the same group don't collide.
|
||||
/// Fast collision filtering type that is used to determine if two objects collide before calling collision or query callbacks.
|
||||
typedef struct cpShapeFilter {
|
||||
/// Two objects with the same non-zero group value do not collide.
|
||||
/// This is generally used to group objects in a composite object together to disable self collisions.
|
||||
cpGroup group;
|
||||
// Layer bitmask for this shape. Shapes only collide if the bitwise and of their layers is non-zero.
|
||||
cpLayers layers;
|
||||
/// A bitmask of user definable categories that this object belongs to.
|
||||
/// The category/mask combinations of both objects in a collision must agree for a collision to occur.
|
||||
cpBitmask categories;
|
||||
/// A bitmask of user definable category types that this object object collides with.
|
||||
/// The category/mask combinations of both objects in a collision must agree for a collision to occur.
|
||||
cpBitmask mask;
|
||||
} cpShapeFilter;
|
||||
|
||||
CP_PRIVATE(cpSpace *space);
|
||||
/// Collision filter value for a shape that will collide with anything except CP_SHAPE_FILTER_NONE.
|
||||
static const cpShapeFilter CP_SHAPE_FILTER_ALL = {CP_NO_GROUP, CP_ALL_CATEGORIES, CP_ALL_CATEGORIES};
|
||||
/// Collision filter value for a shape that does not collide with anything.
|
||||
static const cpShapeFilter CP_SHAPE_FILTER_NONE = {CP_NO_GROUP, ~CP_ALL_CATEGORIES, ~CP_ALL_CATEGORIES};
|
||||
|
||||
CP_PRIVATE(cpShape *next);
|
||||
CP_PRIVATE(cpShape *prev);
|
||||
|
||||
CP_PRIVATE(cpHashValue hashid);
|
||||
};
|
||||
/// Create a new collision filter.
|
||||
static inline cpShapeFilter
|
||||
cpShapeFilterNew(cpGroup group, cpBitmask categories, cpBitmask mask)
|
||||
{
|
||||
cpShapeFilter filter = {group, categories, mask};
|
||||
return filter;
|
||||
}
|
||||
|
||||
/// Destroy a shape.
|
||||
void cpShapeDestroy(cpShape *shape);
|
||||
CP_EXPORT void cpShapeDestroy(cpShape *shape);
|
||||
/// Destroy and Free a shape.
|
||||
void cpShapeFree(cpShape *shape);
|
||||
CP_EXPORT void cpShapeFree(cpShape *shape);
|
||||
|
||||
/// Update, cache and return the bounding box of a shape based on the body it's attached to.
|
||||
cpBB cpShapeCacheBB(cpShape *shape);
|
||||
CP_EXPORT cpBB cpShapeCacheBB(cpShape *shape);
|
||||
/// Update, cache and return the bounding box of a shape with an explicit transformation.
|
||||
cpBB cpShapeUpdate(cpShape *shape, cpVect pos, cpVect rot);
|
||||
|
||||
/// Test if a point lies within a shape.
|
||||
cpBool cpShapePointQuery(cpShape *shape, cpVect p);
|
||||
CP_EXPORT cpBB cpShapeUpdate(cpShape *shape, cpTransform transform);
|
||||
|
||||
/// Perform a nearest point query. It finds the closest point on the surface of shape to a specific point.
|
||||
/// The value returned is the distance between the points. A negative distance means the point is inside the shape.
|
||||
cpFloat cpShapeNearestPointQuery(cpShape *shape, cpVect p, cpNearestPointQueryInfo *out);
|
||||
CP_EXPORT cpFloat cpShapePointQuery(const cpShape *shape, cpVect p, cpPointQueryInfo *out);
|
||||
|
||||
/// Perform a segment query against a shape. @c info must be a pointer to a valid cpSegmentQueryInfo structure.
|
||||
cpBool cpShapeSegmentQuery(cpShape *shape, cpVect a, cpVect b, cpSegmentQueryInfo *info);
|
||||
CP_EXPORT cpBool cpShapeSegmentQuery(const cpShape *shape, cpVect a, cpVect b, cpFloat radius, cpSegmentQueryInfo *info);
|
||||
|
||||
/// Get the hit point for a segment query.
|
||||
static inline cpVect cpSegmentQueryHitPoint(const cpVect start, const cpVect end, const cpSegmentQueryInfo info)
|
||||
{
|
||||
return cpvlerp(start, end, info.t);
|
||||
}
|
||||
/// Return contact information about two shapes.
|
||||
CP_EXPORT cpContactPointSet cpShapesCollide(const cpShape *a, const cpShape *b);
|
||||
|
||||
/// Get the hit distance for a segment query.
|
||||
static inline cpFloat cpSegmentQueryHitDist(const cpVect start, const cpVect end, const cpSegmentQueryInfo info)
|
||||
{
|
||||
return cpvdist(start, end)*info.t;
|
||||
}
|
||||
/// The cpSpace this body is added to.
|
||||
CP_EXPORT cpSpace* cpShapeGetSpace(const cpShape *shape);
|
||||
|
||||
#define CP_DefineShapeStructGetter(type, member, name) \
|
||||
static inline type cpShapeGet##name(const cpShape *shape){return shape->member;}
|
||||
/// The cpBody this shape is connected to.
|
||||
CP_EXPORT cpBody* cpShapeGetBody(const cpShape *shape);
|
||||
/// Set the cpBody this shape is connected to.
|
||||
/// Can only be used if the shape is not currently added to a space.
|
||||
CP_EXPORT void cpShapeSetBody(cpShape *shape, cpBody *body);
|
||||
|
||||
#define CP_DefineShapeStructSetter(type, member, name, activates) \
|
||||
static inline void cpShapeSet##name(cpShape *shape, type value){ \
|
||||
if(activates && shape->body) cpBodyActivate(shape->body); \
|
||||
shape->member = value; \
|
||||
}
|
||||
/// Get the mass of the shape if you are having Chipmunk calculate mass properties for you.
|
||||
cpFloat cpShapeGetMass(cpShape *shape);
|
||||
/// Set the mass of this shape to have Chipmunk calculate mass properties for you.
|
||||
CP_EXPORT void cpShapeSetMass(cpShape *shape, cpFloat mass);
|
||||
|
||||
#define CP_DefineShapeStructProperty(type, member, name, activates) \
|
||||
CP_DefineShapeStructGetter(type, member, name) \
|
||||
CP_DefineShapeStructSetter(type, member, name, activates)
|
||||
/// Get the density of the shape if you are having Chipmunk calculate mass properties for you.
|
||||
CP_EXPORT cpFloat cpShapeGetDensity(cpShape *shape);
|
||||
/// Set the density of this shape to have Chipmunk calculate mass properties for you.
|
||||
CP_EXPORT void cpShapeSetDensity(cpShape *shape, cpFloat density);
|
||||
|
||||
CP_DefineShapeStructGetter(cpSpace*, CP_PRIVATE(space), Space)
|
||||
/// Get the calculated moment of inertia for this shape.
|
||||
CP_EXPORT cpFloat cpShapeGetMoment(cpShape *shape);
|
||||
/// Get the calculated area of this shape.
|
||||
CP_EXPORT cpFloat cpShapeGetArea(cpShape *shape);
|
||||
/// Get the centroid of this shape.
|
||||
CP_EXPORT cpVect cpShapeGetCenterOfGravity(cpShape *shape);
|
||||
|
||||
CP_DefineShapeStructGetter(cpBody*, body, Body)
|
||||
void cpShapeSetBody(cpShape *shape, cpBody *body);
|
||||
/// Get the bounding box that contains the shape given it's current position and angle.
|
||||
CP_EXPORT cpBB cpShapeGetBB(const cpShape *shape);
|
||||
|
||||
CP_DefineShapeStructGetter(cpBB, bb, BB)
|
||||
CP_DefineShapeStructProperty(cpBool, sensor, Sensor, cpTrue)
|
||||
CP_DefineShapeStructProperty(cpFloat, e, Elasticity, cpFalse)
|
||||
CP_DefineShapeStructProperty(cpFloat, u, Friction, cpTrue)
|
||||
CP_DefineShapeStructProperty(cpVect, surface_v, SurfaceVelocity, cpTrue)
|
||||
CP_DefineShapeStructProperty(cpDataPointer, data, UserData, cpFalse)
|
||||
CP_DefineShapeStructProperty(cpCollisionType, collision_type, CollisionType, cpTrue)
|
||||
CP_DefineShapeStructProperty(cpGroup, group, Group, cpTrue)
|
||||
CP_DefineShapeStructProperty(cpLayers, layers, Layers, cpTrue)
|
||||
/// Get if the shape is set to be a sensor or not.
|
||||
CP_EXPORT cpBool cpShapeGetSensor(const cpShape *shape);
|
||||
/// Set if the shape is a sensor or not.
|
||||
CP_EXPORT void cpShapeSetSensor(cpShape *shape, cpBool sensor);
|
||||
|
||||
/// When initializing a shape, it's hash value comes from a counter.
|
||||
/// Because the hash value may affect iteration order, you can reset the shape ID counter
|
||||
/// when recreating a space. This will make the simulation be deterministic.
|
||||
void cpResetShapeIdCounter(void);
|
||||
/// Get the elasticity of this shape.
|
||||
CP_EXPORT cpFloat cpShapeGetElasticity(const cpShape *shape);
|
||||
/// Set the elasticity of this shape.
|
||||
CP_EXPORT void cpShapeSetElasticity(cpShape *shape, cpFloat elasticity);
|
||||
|
||||
/// Get the friction of this shape.
|
||||
CP_EXPORT cpFloat cpShapeGetFriction(const cpShape *shape);
|
||||
/// Set the friction of this shape.
|
||||
CP_EXPORT void cpShapeSetFriction(cpShape *shape, cpFloat friction);
|
||||
|
||||
/// Get the surface velocity of this shape.
|
||||
CP_EXPORT cpVect cpShapeGetSurfaceVelocity(const cpShape *shape);
|
||||
/// Set the surface velocity of this shape.
|
||||
CP_EXPORT void cpShapeSetSurfaceVelocity(cpShape *shape, cpVect surfaceVelocity);
|
||||
|
||||
/// Get the user definable data pointer of this shape.
|
||||
CP_EXPORT cpDataPointer cpShapeGetUserData(const cpShape *shape);
|
||||
/// Set the user definable data pointer of this shape.
|
||||
CP_EXPORT void cpShapeSetUserData(cpShape *shape, cpDataPointer userData);
|
||||
|
||||
/// Set the collision type of this shape.
|
||||
CP_EXPORT cpCollisionType cpShapeGetCollisionType(const cpShape *shape);
|
||||
/// Get the collision type of this shape.
|
||||
CP_EXPORT void cpShapeSetCollisionType(cpShape *shape, cpCollisionType collisionType);
|
||||
|
||||
/// Get the collision filtering parameters of this shape.
|
||||
CP_EXPORT cpShapeFilter cpShapeGetFilter(const cpShape *shape);
|
||||
/// Set the collision filtering parameters of this shape.
|
||||
CP_EXPORT void cpShapeSetFilter(cpShape *shape, cpShapeFilter filter);
|
||||
|
||||
#define CP_DeclareShapeGetter(struct, type, name) type struct##Get##name(const cpShape *shape)
|
||||
|
||||
/// @}
|
||||
/// @defgroup cpCircleShape cpCircleShape
|
||||
|
||||
/// @private
|
||||
typedef struct cpCircleShape {
|
||||
cpShape shape;
|
||||
|
||||
cpVect c, tc;
|
||||
cpFloat r;
|
||||
} cpCircleShape;
|
||||
|
||||
/// Allocate a circle shape.
|
||||
cpCircleShape* cpCircleShapeAlloc(void);
|
||||
CP_EXPORT cpCircleShape* cpCircleShapeAlloc(void);
|
||||
/// Initialize a circle shape.
|
||||
cpCircleShape* cpCircleShapeInit(cpCircleShape *circle, cpBody *body, cpFloat radius, cpVect offset);
|
||||
CP_EXPORT cpCircleShape* cpCircleShapeInit(cpCircleShape *circle, cpBody *body, cpFloat radius, cpVect offset);
|
||||
/// Allocate and initialize a circle shape.
|
||||
cpShape* cpCircleShapeNew(cpBody *body, cpFloat radius, cpVect offset);
|
||||
CP_EXPORT cpShape* cpCircleShapeNew(cpBody *body, cpFloat radius, cpVect offset);
|
||||
|
||||
CP_DeclareShapeGetter(cpCircleShape, cpVect, Offset);
|
||||
CP_DeclareShapeGetter(cpCircleShape, cpFloat, Radius);
|
||||
/// Get the offset of a circle shape.
|
||||
CP_EXPORT cpVect cpCircleShapeGetOffset(const cpShape *shape);
|
||||
/// Get the radius of a circle shape.
|
||||
CP_EXPORT cpFloat cpCircleShapeGetRadius(const cpShape *shape);
|
||||
|
||||
/// @}
|
||||
/// @defgroup cpSegmentShape cpSegmentShape
|
||||
|
||||
/// @private
|
||||
typedef struct cpSegmentShape {
|
||||
cpShape shape;
|
||||
|
||||
cpVect a, b, n;
|
||||
cpVect ta, tb, tn;
|
||||
cpFloat r;
|
||||
|
||||
cpVect a_tangent, b_tangent;
|
||||
} cpSegmentShape;
|
||||
|
||||
/// Allocate a segment shape.
|
||||
cpSegmentShape* cpSegmentShapeAlloc(void);
|
||||
CP_EXPORT cpSegmentShape* cpSegmentShapeAlloc(void);
|
||||
/// Initialize a segment shape.
|
||||
cpSegmentShape* cpSegmentShapeInit(cpSegmentShape *seg, cpBody *body, cpVect a, cpVect b, cpFloat radius);
|
||||
CP_EXPORT cpSegmentShape* cpSegmentShapeInit(cpSegmentShape *seg, cpBody *body, cpVect a, cpVect b, cpFloat radius);
|
||||
/// Allocate and initialize a segment shape.
|
||||
cpShape* cpSegmentShapeNew(cpBody *body, cpVect a, cpVect b, cpFloat radius);
|
||||
CP_EXPORT cpShape* cpSegmentShapeNew(cpBody *body, cpVect a, cpVect b, cpFloat radius);
|
||||
|
||||
/// Let Chipmunk know about the geometry of adjacent segments to avoid colliding with endcaps.
|
||||
void cpSegmentShapeSetNeighbors(cpShape *shape, cpVect prev, cpVect next);
|
||||
CP_EXPORT void cpSegmentShapeSetNeighbors(cpShape *shape, cpVect prev, cpVect next);
|
||||
|
||||
CP_DeclareShapeGetter(cpSegmentShape, cpVect, A);
|
||||
CP_DeclareShapeGetter(cpSegmentShape, cpVect, B);
|
||||
CP_DeclareShapeGetter(cpSegmentShape, cpVect, Normal);
|
||||
CP_DeclareShapeGetter(cpSegmentShape, cpFloat, Radius);
|
||||
/// Get the first endpoint of a segment shape.
|
||||
CP_EXPORT cpVect cpSegmentShapeGetA(const cpShape *shape);
|
||||
/// Get the second endpoint of a segment shape.
|
||||
CP_EXPORT cpVect cpSegmentShapeGetB(const cpShape *shape);
|
||||
/// Get the normal of a segment shape.
|
||||
CP_EXPORT cpVect cpSegmentShapeGetNormal(const cpShape *shape);
|
||||
/// Get the first endpoint of a segment shape.
|
||||
CP_EXPORT cpFloat cpSegmentShapeGetRadius(const cpShape *shape);
|
||||
|
||||
/// @}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2007 Scott Lembcke
|
||||
/* Copyright (c) 2013 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
|
||||
|
|
@ -22,191 +22,161 @@
|
|||
/// @defgroup cpSpace cpSpace
|
||||
/// @{
|
||||
|
||||
typedef struct cpContactBufferHeader cpContactBufferHeader;
|
||||
typedef void (*cpSpaceArbiterApplyImpulseFunc)(cpArbiter *arb);
|
||||
//MARK: Definitions
|
||||
|
||||
/// Basic Unit of Simulation in Chipmunk
|
||||
struct cpSpace {
|
||||
/// Number of iterations to use in the impulse solver to solve contacts.
|
||||
int iterations;
|
||||
/// 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, cpDataPointer userData);
|
||||
/// 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, cpDataPointer userData);
|
||||
/// Collision post-solve event function callback type.
|
||||
typedef void (*cpCollisionPostSolveFunc)(cpArbiter *arb, cpSpace *space, cpDataPointer userData);
|
||||
/// Collision separate event function callback type.
|
||||
typedef void (*cpCollisionSeparateFunc)(cpArbiter *arb, cpSpace *space, cpDataPointer userData);
|
||||
|
||||
/// Gravity to pass to rigid bodies when integrating velocity.
|
||||
cpVect gravity;
|
||||
|
||||
/// Damping rate expressed as the fraction of velocity bodies retain each second.
|
||||
/// A value of 0.9 would mean that each body's velocity will drop 10% per second.
|
||||
/// The default value is 1.0, meaning no damping is applied.
|
||||
/// @note This damping value is different than those of cpDampedSpring and cpDampedRotarySpring.
|
||||
cpFloat damping;
|
||||
|
||||
/// Speed threshold for a body to be considered idle.
|
||||
/// The default value of 0 means to let the space guess a good threshold based on gravity.
|
||||
cpFloat idleSpeedThreshold;
|
||||
|
||||
/// Time a group of bodies must remain idle in order to fall asleep.
|
||||
/// Enabling sleeping also implicitly enables the the contact graph.
|
||||
/// The default value of INFINITY disables the sleeping algorithm.
|
||||
cpFloat sleepTimeThreshold;
|
||||
|
||||
/// Amount of encouraged penetration between colliding shapes.
|
||||
/// Used to reduce oscillating contacts and keep the collision cache warm.
|
||||
/// Defaults to 0.1. If you have poor simulation quality,
|
||||
/// increase this number as much as possible without allowing visible amounts of overlap.
|
||||
cpFloat collisionSlop;
|
||||
|
||||
/// Determines how fast overlapping shapes are pushed apart.
|
||||
/// Expressed as a fraction of the error remaining after each second.
|
||||
/// Defaults to pow(1.0 - 0.1, 60.0) meaning that Chipmunk fixes 10% of overlap each frame at 60Hz.
|
||||
cpFloat collisionBias;
|
||||
|
||||
/// Number of frames that contact information should persist.
|
||||
/// Defaults to 3. There is probably never a reason to change this value.
|
||||
cpTimestamp collisionPersistence;
|
||||
|
||||
/// Rebuild the contact graph during each step. Must be enabled to use the cpBodyEachArbiter() function.
|
||||
/// Disabled by default for a small performance boost. Enabled implicitly when the sleeping feature is enabled.
|
||||
cpBool enableContactGraph;
|
||||
|
||||
/// User definable data pointer.
|
||||
/// Generally this points to your game's controller or game state
|
||||
/// class so you can access it when given a cpSpace reference in a callback.
|
||||
cpDataPointer data;
|
||||
|
||||
/// The designated static body for this space.
|
||||
/// You can modify this body, or replace it with your own static body.
|
||||
/// By default it points to a statically allocated cpBody in the cpSpace struct.
|
||||
cpBody *staticBody;
|
||||
|
||||
CP_PRIVATE(cpTimestamp stamp);
|
||||
CP_PRIVATE(cpFloat curr_dt);
|
||||
|
||||
CP_PRIVATE(cpArray *bodies);
|
||||
CP_PRIVATE(cpArray *rousedBodies);
|
||||
CP_PRIVATE(cpArray *sleepingComponents);
|
||||
|
||||
CP_PRIVATE(cpSpatialIndex *staticShapes);
|
||||
CP_PRIVATE(cpSpatialIndex *activeShapes);
|
||||
|
||||
CP_PRIVATE(cpArray *arbiters);
|
||||
CP_PRIVATE(cpContactBufferHeader *contactBuffersHead);
|
||||
CP_PRIVATE(cpHashSet *cachedArbiters);
|
||||
CP_PRIVATE(cpArray *pooledArbiters);
|
||||
CP_PRIVATE(cpArray *constraints);
|
||||
|
||||
CP_PRIVATE(cpArray *allocatedBuffers);
|
||||
CP_PRIVATE(int locked);
|
||||
|
||||
CP_PRIVATE(cpHashSet *collisionHandlers);
|
||||
CP_PRIVATE(cpCollisionHandler defaultHandler);
|
||||
|
||||
CP_PRIVATE(cpBool skipPostStep);
|
||||
CP_PRIVATE(cpArray *postStepCallbacks);
|
||||
|
||||
CP_PRIVATE(cpBody _staticBody);
|
||||
/// Struct that holds function callback pointers to configure custom collision handling.
|
||||
/// Collision handlers have a pair of types; when a collision occurs between two shapes that have these types, the collision handler functions are triggered.
|
||||
struct cpCollisionHandler {
|
||||
/// Collision type identifier of the first shape that this handler recognizes.
|
||||
/// In the collision handler callback, the shape with this type will be the first argument. Read only.
|
||||
const cpCollisionType typeA;
|
||||
/// Collision type identifier of the second shape that this handler recognizes.
|
||||
/// In the collision handler callback, the shape with this type will be the second argument. Read only.
|
||||
const cpCollisionType typeB;
|
||||
/// This function is called when two shapes with types that match this collision handler begin colliding.
|
||||
cpCollisionBeginFunc beginFunc;
|
||||
/// This function is called each step when two shapes with types that match this collision handler are colliding.
|
||||
/// It's called before the collision solver runs so that you can affect a collision's outcome.
|
||||
cpCollisionPreSolveFunc preSolveFunc;
|
||||
/// This function is called each step when two shapes with types that match this collision handler are colliding.
|
||||
/// It's called after the collision solver runs so that you can read back information about the collision to trigger events in your game.
|
||||
cpCollisionPostSolveFunc postSolveFunc;
|
||||
/// This function is called when two shapes with types that match this collision handler stop colliding.
|
||||
cpCollisionSeparateFunc separateFunc;
|
||||
/// This is a user definable context pointer that is passed to all of the collision handler functions.
|
||||
cpDataPointer userData;
|
||||
};
|
||||
|
||||
// TODO: Make timestep a parameter?
|
||||
|
||||
|
||||
//MARK: Memory and Initialization
|
||||
|
||||
/// Allocate a cpSpace.
|
||||
cpSpace* cpSpaceAlloc(void);
|
||||
CP_EXPORT cpSpace* cpSpaceAlloc(void);
|
||||
/// Initialize a cpSpace.
|
||||
cpSpace* cpSpaceInit(cpSpace *space);
|
||||
CP_EXPORT cpSpace* cpSpaceInit(cpSpace *space);
|
||||
/// Allocate and initialize a cpSpace.
|
||||
cpSpace* cpSpaceNew(void);
|
||||
CP_EXPORT cpSpace* cpSpaceNew(void);
|
||||
|
||||
/// Destroy a cpSpace.
|
||||
void cpSpaceDestroy(cpSpace *space);
|
||||
CP_EXPORT void cpSpaceDestroy(cpSpace *space);
|
||||
/// Destroy and free a cpSpace.
|
||||
void cpSpaceFree(cpSpace *space);
|
||||
CP_EXPORT void cpSpaceFree(cpSpace *space);
|
||||
|
||||
#define CP_DefineSpaceStructGetter(type, member, name) \
|
||||
static inline type cpSpaceGet##name(const cpSpace *space){return space->member;}
|
||||
|
||||
#define CP_DefineSpaceStructSetter(type, member, name) \
|
||||
static inline void cpSpaceSet##name(cpSpace *space, type value){space->member = value;}
|
||||
//MARK: Properties
|
||||
|
||||
#define CP_DefineSpaceStructProperty(type, member, name) \
|
||||
CP_DefineSpaceStructGetter(type, member, name) \
|
||||
CP_DefineSpaceStructSetter(type, member, name)
|
||||
/// Number of iterations to use in the impulse solver to solve contacts and other constraints.
|
||||
CP_EXPORT int cpSpaceGetIterations(const cpSpace *space);
|
||||
CP_EXPORT void cpSpaceSetIterations(cpSpace *space, int iterations);
|
||||
|
||||
CP_DefineSpaceStructProperty(int, iterations, Iterations)
|
||||
CP_DefineSpaceStructProperty(cpVect, gravity, Gravity)
|
||||
CP_DefineSpaceStructProperty(cpFloat, damping, Damping)
|
||||
CP_DefineSpaceStructProperty(cpFloat, idleSpeedThreshold, IdleSpeedThreshold)
|
||||
CP_DefineSpaceStructProperty(cpFloat, sleepTimeThreshold, SleepTimeThreshold)
|
||||
CP_DefineSpaceStructProperty(cpFloat, collisionSlop, CollisionSlop)
|
||||
CP_DefineSpaceStructProperty(cpFloat, collisionBias, CollisionBias)
|
||||
CP_DefineSpaceStructProperty(cpTimestamp, collisionPersistence, CollisionPersistence)
|
||||
CP_DefineSpaceStructProperty(cpBool, enableContactGraph, EnableContactGraph)
|
||||
CP_DefineSpaceStructProperty(cpDataPointer, data, UserData)
|
||||
CP_DefineSpaceStructGetter(cpBody*, staticBody, StaticBody)
|
||||
CP_DefineSpaceStructGetter(cpFloat, CP_PRIVATE(curr_dt), CurrentTimeStep)
|
||||
/// Gravity to pass to rigid bodies when integrating velocity.
|
||||
CP_EXPORT cpVect cpSpaceGetGravity(const cpSpace *space);
|
||||
CP_EXPORT void cpSpaceSetGravity(cpSpace *space, cpVect gravity);
|
||||
|
||||
/// returns true from inside a callback and objects cannot be added/removed.
|
||||
static inline cpBool
|
||||
cpSpaceIsLocked(cpSpace *space)
|
||||
{
|
||||
return space->CP_PRIVATE(locked);
|
||||
}
|
||||
/// Damping rate expressed as the fraction of velocity bodies retain each second.
|
||||
/// A value of 0.9 would mean that each body's velocity will drop 10% per second.
|
||||
/// The default value is 1.0, meaning no damping is applied.
|
||||
/// @note This damping value is different than those of cpDampedSpring and cpDampedRotarySpring.
|
||||
CP_EXPORT cpFloat cpSpaceGetDamping(const cpSpace *space);
|
||||
CP_EXPORT void cpSpaceSetDamping(cpSpace *space, cpFloat damping);
|
||||
|
||||
/// Set a default collision handler for this space.
|
||||
/// The default collision handler is invoked for each colliding pair of shapes
|
||||
/// that isn't explicitly handled by a specific collision handler.
|
||||
/// You can pass NULL for any function you don't want to implement.
|
||||
void cpSpaceSetDefaultCollisionHandler(
|
||||
cpSpace *space,
|
||||
cpCollisionBeginFunc begin,
|
||||
cpCollisionPreSolveFunc preSolve,
|
||||
cpCollisionPostSolveFunc postSolve,
|
||||
cpCollisionSeparateFunc separate,
|
||||
void *data
|
||||
);
|
||||
/// Speed threshold for a body to be considered idle.
|
||||
/// The default value of 0 means to let the space guess a good threshold based on gravity.
|
||||
CP_EXPORT cpFloat cpSpaceGetIdleSpeedThreshold(const cpSpace *space);
|
||||
CP_EXPORT void cpSpaceSetIdleSpeedThreshold(cpSpace *space, cpFloat idleSpeedThreshold);
|
||||
|
||||
/// Set a collision handler to be used whenever the two shapes with the given collision types collide.
|
||||
/// You can pass NULL for any function you don't want to implement.
|
||||
void cpSpaceAddCollisionHandler(
|
||||
cpSpace *space,
|
||||
cpCollisionType a, cpCollisionType b,
|
||||
cpCollisionBeginFunc begin,
|
||||
cpCollisionPreSolveFunc preSolve,
|
||||
cpCollisionPostSolveFunc postSolve,
|
||||
cpCollisionSeparateFunc separate,
|
||||
void *data
|
||||
);
|
||||
/// Time a group of bodies must remain idle in order to fall asleep.
|
||||
/// Enabling sleeping also implicitly enables the the contact graph.
|
||||
/// The default value of INFINITY disables the sleeping algorithm.
|
||||
CP_EXPORT cpFloat cpSpaceGetSleepTimeThreshold(const cpSpace *space);
|
||||
CP_EXPORT void cpSpaceSetSleepTimeThreshold(cpSpace *space, cpFloat sleepTimeThreshold);
|
||||
|
||||
/// Unset a collision handler.
|
||||
void cpSpaceRemoveCollisionHandler(cpSpace *space, cpCollisionType a, cpCollisionType b);
|
||||
/// Amount of encouraged penetration between colliding shapes.
|
||||
/// Used to reduce oscillating contacts and keep the collision cache warm.
|
||||
/// Defaults to 0.1. If you have poor simulation quality,
|
||||
/// increase this number as much as possible without allowing visible amounts of overlap.
|
||||
CP_EXPORT cpFloat cpSpaceGetCollisionSlop(const cpSpace *space);
|
||||
CP_EXPORT void cpSpaceSetCollisionSlop(cpSpace *space, cpFloat collisionSlop);
|
||||
|
||||
/// Determines how fast overlapping shapes are pushed apart.
|
||||
/// Expressed as a fraction of the error remaining after each second.
|
||||
/// Defaults to pow(1.0 - 0.1, 60.0) meaning that Chipmunk fixes 10% of overlap each frame at 60Hz.
|
||||
CP_EXPORT cpFloat cpSpaceGetCollisionBias(const cpSpace *space);
|
||||
CP_EXPORT void cpSpaceSetCollisionBias(cpSpace *space, cpFloat collisionBias);
|
||||
|
||||
/// Number of frames that contact information should persist.
|
||||
/// Defaults to 3. There is probably never a reason to change this value.
|
||||
CP_EXPORT cpTimestamp cpSpaceGetCollisionPersistence(const cpSpace *space);
|
||||
CP_EXPORT void cpSpaceSetCollisionPersistence(cpSpace *space, cpTimestamp collisionPersistence);
|
||||
|
||||
/// User definable data pointer.
|
||||
/// Generally this points to your game's controller or game state
|
||||
/// class so you can access it when given a cpSpace reference in a callback.
|
||||
CP_EXPORT cpDataPointer cpSpaceGetUserData(const cpSpace *space);
|
||||
CP_EXPORT void cpSpaceSetUserData(cpSpace *space, cpDataPointer userData);
|
||||
|
||||
/// The Space provided static body for a given cpSpace.
|
||||
/// This is merely provided for convenience and you are not required to use it.
|
||||
CP_EXPORT cpBody* cpSpaceGetStaticBody(const cpSpace *space);
|
||||
|
||||
/// Returns the current (or most recent) time step used with the given space.
|
||||
/// Useful from callbacks if your time step is not a compile-time global.
|
||||
CP_EXPORT cpFloat cpSpaceGetCurrentTimeStep(const cpSpace *space);
|
||||
|
||||
/// returns true from inside a callback when objects cannot be added/removed.
|
||||
CP_EXPORT cpBool cpSpaceIsLocked(cpSpace *space);
|
||||
|
||||
|
||||
//MARK: Collision Handlers
|
||||
|
||||
/// Create or return the existing collision handler that is called for all collisions that are not handled by a more specific collision handler.
|
||||
CP_EXPORT cpCollisionHandler *cpSpaceAddDefaultCollisionHandler(cpSpace *space);
|
||||
/// Create or return the existing collision handler for the specified pair of collision types.
|
||||
/// If wildcard handlers are used with either of the collision types, it's the responibility of the custom handler to invoke the wildcard handlers.
|
||||
CP_EXPORT cpCollisionHandler *cpSpaceAddCollisionHandler(cpSpace *space, cpCollisionType a, cpCollisionType b);
|
||||
/// Create or return the existing wildcard collision handler for the specified type.
|
||||
CP_EXPORT cpCollisionHandler *cpSpaceAddWildcardHandler(cpSpace *space, cpCollisionType type);
|
||||
|
||||
|
||||
//MARK: Add/Remove objects
|
||||
|
||||
/// Add a collision shape to the simulation.
|
||||
/// If the shape is attached to a static body, it will be added as a static shape.
|
||||
cpShape* cpSpaceAddShape(cpSpace *space, cpShape *shape);
|
||||
/// Explicity add a shape as a static shape to the simulation.
|
||||
cpShape* cpSpaceAddStaticShape(cpSpace *space, cpShape *shape);
|
||||
CP_EXPORT cpShape* cpSpaceAddShape(cpSpace *space, cpShape *shape);
|
||||
/// Add a rigid body to the simulation.
|
||||
cpBody* cpSpaceAddBody(cpSpace *space, cpBody *body);
|
||||
CP_EXPORT cpBody* cpSpaceAddBody(cpSpace *space, cpBody *body);
|
||||
/// Add a constraint to the simulation.
|
||||
cpConstraint* cpSpaceAddConstraint(cpSpace *space, cpConstraint *constraint);
|
||||
CP_EXPORT cpConstraint* cpSpaceAddConstraint(cpSpace *space, cpConstraint *constraint);
|
||||
|
||||
/// Remove a collision shape from the simulation.
|
||||
void cpSpaceRemoveShape(cpSpace *space, cpShape *shape);
|
||||
/// Remove a collision shape added using cpSpaceAddStaticShape() from the simulation.
|
||||
void cpSpaceRemoveStaticShape(cpSpace *space, cpShape *shape);
|
||||
CP_EXPORT void cpSpaceRemoveShape(cpSpace *space, cpShape *shape);
|
||||
/// Remove a rigid body from the simulation.
|
||||
void cpSpaceRemoveBody(cpSpace *space, cpBody *body);
|
||||
CP_EXPORT void cpSpaceRemoveBody(cpSpace *space, cpBody *body);
|
||||
/// Remove a constraint from the simulation.
|
||||
void cpSpaceRemoveConstraint(cpSpace *space, cpConstraint *constraint);
|
||||
CP_EXPORT void cpSpaceRemoveConstraint(cpSpace *space, cpConstraint *constraint);
|
||||
|
||||
/// Test if a collision shape has been added to the space.
|
||||
cpBool cpSpaceContainsShape(cpSpace *space, cpShape *shape);
|
||||
CP_EXPORT cpBool cpSpaceContainsShape(cpSpace *space, cpShape *shape);
|
||||
/// Test if a rigid body has been added to the space.
|
||||
cpBool cpSpaceContainsBody(cpSpace *space, cpBody *body);
|
||||
CP_EXPORT cpBool cpSpaceContainsBody(cpSpace *space, cpBody *body);
|
||||
/// Test if a constraint has been added to the space.
|
||||
cpBool cpSpaceContainsConstraint(cpSpace *space, cpConstraint *constraint);
|
||||
CP_EXPORT cpBool cpSpaceContainsConstraint(cpSpace *space, cpConstraint *constraint);
|
||||
|
||||
/// Convert a dynamic rogue body to a static one.
|
||||
/// If the body is active, you must remove it from the space first.
|
||||
void cpSpaceConvertBodyToStatic(cpSpace *space, cpBody *body);
|
||||
/// Convert a body to a dynamic rogue body.
|
||||
/// If you want the body to be active after the transition, you must add it to the space also.
|
||||
void cpSpaceConvertBodyToDynamic(cpSpace *space, cpBody *body, cpFloat mass, cpFloat moment);
|
||||
//MARK: Post-Step Callbacks
|
||||
|
||||
/// Post Step callback function type.
|
||||
typedef void (*cpPostStepFunc)(cpSpace *space, void *key, void *data);
|
||||
|
|
@ -214,70 +184,136 @@ typedef void (*cpPostStepFunc)(cpSpace *space, void *key, void *data);
|
|||
/// You can only register one callback per unique value for @c key.
|
||||
/// Returns true only if @c key has never been scheduled before.
|
||||
/// It's possible to pass @c NULL for @c func if you only want to mark @c key as being used.
|
||||
cpBool cpSpaceAddPostStepCallback(cpSpace *space, cpPostStepFunc func, void *key, void *data);
|
||||
CP_EXPORT cpBool cpSpaceAddPostStepCallback(cpSpace *space, cpPostStepFunc func, void *key, void *data);
|
||||
|
||||
/// Point query callback function type.
|
||||
typedef void (*cpSpacePointQueryFunc)(cpShape *shape, void *data);
|
||||
/// Query the space at a point and call @c func for each shape found.
|
||||
void cpSpacePointQuery(cpSpace *space, cpVect point, cpLayers layers, cpGroup group, cpSpacePointQueryFunc func, void *data);
|
||||
/// Query the space at a point and return the first shape found. Returns NULL if no shapes were found.
|
||||
cpShape *cpSpacePointQueryFirst(cpSpace *space, cpVect point, cpLayers layers, cpGroup group);
|
||||
|
||||
//MARK: Queries
|
||||
|
||||
// TODO: Queries and iterators should take a cpSpace parametery.
|
||||
// TODO: They should also be abortable.
|
||||
|
||||
/// Nearest point query callback function type.
|
||||
typedef void (*cpSpaceNearestPointQueryFunc)(cpShape *shape, cpFloat distance, cpVect point, void *data);
|
||||
typedef void (*cpSpacePointQueryFunc)(cpShape *shape, cpVect point, cpFloat distance, cpVect gradient, void *data);
|
||||
/// Query the space at a point and call @c func for each shape found.
|
||||
void cpSpaceNearestPointQuery(cpSpace *space, cpVect point, cpFloat maxDistance, cpLayers layers, cpGroup group, cpSpaceNearestPointQueryFunc func, void *data);
|
||||
CP_EXPORT void cpSpacePointQuery(cpSpace *space, cpVect point, cpFloat maxDistance, cpShapeFilter filter, cpSpacePointQueryFunc func, void *data);
|
||||
/// Query the space at a point and return the nearest shape found. Returns NULL if no shapes were found.
|
||||
cpShape *cpSpaceNearestPointQueryNearest(cpSpace *space, cpVect point, cpFloat maxDistance, cpLayers layers, cpGroup group, cpNearestPointQueryInfo *out);
|
||||
CP_EXPORT cpShape *cpSpacePointQueryNearest(cpSpace *space, cpVect point, cpFloat maxDistance, cpShapeFilter filter, cpPointQueryInfo *out);
|
||||
|
||||
/// Segment query callback function type.
|
||||
typedef void (*cpSpaceSegmentQueryFunc)(cpShape *shape, cpFloat t, cpVect n, void *data);
|
||||
typedef void (*cpSpaceSegmentQueryFunc)(cpShape *shape, cpVect point, cpVect normal, cpFloat alpha, void *data);
|
||||
/// Perform a directed line segment query (like a raycast) against the space calling @c func for each shape intersected.
|
||||
void cpSpaceSegmentQuery(cpSpace *space, cpVect start, cpVect end, cpLayers layers, cpGroup group, cpSpaceSegmentQueryFunc func, void *data);
|
||||
CP_EXPORT void cpSpaceSegmentQuery(cpSpace *space, cpVect start, cpVect end, cpFloat radius, cpShapeFilter filter, cpSpaceSegmentQueryFunc func, void *data);
|
||||
/// Perform a directed line segment query (like a raycast) against the space and return the first shape hit. Returns NULL if no shapes were hit.
|
||||
cpShape *cpSpaceSegmentQueryFirst(cpSpace *space, cpVect start, cpVect end, cpLayers layers, cpGroup group, cpSegmentQueryInfo *out);
|
||||
CP_EXPORT cpShape *cpSpaceSegmentQueryFirst(cpSpace *space, cpVect start, cpVect end, cpFloat radius, cpShapeFilter filter, cpSegmentQueryInfo *out);
|
||||
|
||||
/// Rectangle Query callback function type.
|
||||
typedef void (*cpSpaceBBQueryFunc)(cpShape *shape, void *data);
|
||||
/// Perform a fast rectangle query on the space calling @c func for each shape found.
|
||||
/// Only the shape's bounding boxes are checked for overlap, not their full shape.
|
||||
void cpSpaceBBQuery(cpSpace *space, cpBB bb, cpLayers layers, cpGroup group, cpSpaceBBQueryFunc func, void *data);
|
||||
CP_EXPORT void cpSpaceBBQuery(cpSpace *space, cpBB bb, cpShapeFilter filter, cpSpaceBBQueryFunc func, void *data);
|
||||
|
||||
/// Shape query callback function type.
|
||||
typedef void (*cpSpaceShapeQueryFunc)(cpShape *shape, cpContactPointSet *points, void *data);
|
||||
/// Query a space for any shapes overlapping the given shape and call @c func for each shape found.
|
||||
cpBool cpSpaceShapeQuery(cpSpace *space, cpShape *shape, cpSpaceShapeQueryFunc func, void *data);
|
||||
CP_EXPORT cpBool cpSpaceShapeQuery(cpSpace *space, cpShape *shape, cpSpaceShapeQueryFunc func, void *data);
|
||||
|
||||
/// Call cpBodyActivate() for any shape that is overlaps the given shape.
|
||||
void cpSpaceActivateShapesTouchingShape(cpSpace *space, cpShape *shape);
|
||||
|
||||
//MARK: Iteration
|
||||
|
||||
/// Space/body iterator callback function type.
|
||||
typedef void (*cpSpaceBodyIteratorFunc)(cpBody *body, void *data);
|
||||
/// Call @c func for each body in the space.
|
||||
void cpSpaceEachBody(cpSpace *space, cpSpaceBodyIteratorFunc func, void *data);
|
||||
CP_EXPORT void cpSpaceEachBody(cpSpace *space, cpSpaceBodyIteratorFunc func, void *data);
|
||||
|
||||
/// Space/body iterator callback function type.
|
||||
typedef void (*cpSpaceShapeIteratorFunc)(cpShape *shape, void *data);
|
||||
/// Call @c func for each shape in the space.
|
||||
void cpSpaceEachShape(cpSpace *space, cpSpaceShapeIteratorFunc func, void *data);
|
||||
CP_EXPORT void cpSpaceEachShape(cpSpace *space, cpSpaceShapeIteratorFunc func, void *data);
|
||||
|
||||
/// Space/constraint iterator callback function type.
|
||||
typedef void (*cpSpaceConstraintIteratorFunc)(cpConstraint *constraint, void *data);
|
||||
/// Call @c func for each shape in the space.
|
||||
void cpSpaceEachConstraint(cpSpace *space, cpSpaceConstraintIteratorFunc func, void *data);
|
||||
CP_EXPORT void cpSpaceEachConstraint(cpSpace *space, cpSpaceConstraintIteratorFunc func, void *data);
|
||||
|
||||
|
||||
//MARK: Indexing
|
||||
|
||||
/// Update the collision detection info for the static shapes in the space.
|
||||
void cpSpaceReindexStatic(cpSpace *space);
|
||||
CP_EXPORT void cpSpaceReindexStatic(cpSpace *space);
|
||||
/// Update the collision detection data for a specific shape in the space.
|
||||
void cpSpaceReindexShape(cpSpace *space, cpShape *shape);
|
||||
CP_EXPORT void cpSpaceReindexShape(cpSpace *space, cpShape *shape);
|
||||
/// Update the collision detection data for all shapes attached to a body.
|
||||
void cpSpaceReindexShapesForBody(cpSpace *space, cpBody *body);
|
||||
CP_EXPORT void cpSpaceReindexShapesForBody(cpSpace *space, cpBody *body);
|
||||
|
||||
/// Switch the space to use a spatial has as it's spatial index.
|
||||
void cpSpaceUseSpatialHash(cpSpace *space, cpFloat dim, int count);
|
||||
CP_EXPORT void cpSpaceUseSpatialHash(cpSpace *space, cpFloat dim, int count);
|
||||
|
||||
|
||||
//MARK: Time Stepping
|
||||
|
||||
/// Step the space forward in time by @c dt.
|
||||
void cpSpaceStep(cpSpace *space, cpFloat dt);
|
||||
CP_EXPORT void cpSpaceStep(cpSpace *space, cpFloat dt);
|
||||
|
||||
|
||||
//MARK: Debug API
|
||||
|
||||
#ifndef CP_SPACE_DISABLE_DEBUG_API
|
||||
|
||||
/// Color type to use with the space debug drawing API.
|
||||
typedef struct cpSpaceDebugColor {
|
||||
float r, g, b, a;
|
||||
} cpSpaceDebugColor;
|
||||
|
||||
/// Callback type for a function that draws a filled, stroked circle.
|
||||
typedef void (*cpSpaceDebugDrawCircleImpl)(cpVect pos, cpFloat angle, cpFloat radius, cpSpaceDebugColor outlineColor, cpSpaceDebugColor fillColor, cpDataPointer data);
|
||||
/// Callback type for a function that draws a line segment.
|
||||
typedef void (*cpSpaceDebugDrawSegmentImpl)(cpVect a, cpVect b, cpSpaceDebugColor color, cpDataPointer data);
|
||||
/// Callback type for a function that draws a thick line segment.
|
||||
typedef void (*cpSpaceDebugDrawFatSegmentImpl)(cpVect a, cpVect b, cpFloat radius, cpSpaceDebugColor outlineColor, cpSpaceDebugColor fillColor, cpDataPointer data);
|
||||
/// Callback type for a function that draws a convex polygon.
|
||||
typedef void (*cpSpaceDebugDrawPolygonImpl)(int count, const cpVect *verts, cpFloat radius, cpSpaceDebugColor outlineColor, cpSpaceDebugColor fillColor, cpDataPointer data);
|
||||
/// Callback type for a function that draws a dot.
|
||||
typedef void (*cpSpaceDebugDrawDotImpl)(cpFloat size, cpVect pos, cpSpaceDebugColor color, cpDataPointer data);
|
||||
/// Callback type for a function that returns a color for a given shape. This gives you an opportunity to color shapes based on how they are used in your engine.
|
||||
typedef cpSpaceDebugColor (*cpSpaceDebugDrawColorForShapeImpl)(cpShape *shape, cpDataPointer data);
|
||||
|
||||
typedef enum cpSpaceDebugDrawFlags {
|
||||
CP_SPACE_DEBUG_DRAW_SHAPES = 1<<0,
|
||||
CP_SPACE_DEBUG_DRAW_CONSTRAINTS = 1<<1,
|
||||
CP_SPACE_DEBUG_DRAW_COLLISION_POINTS = 1<<2,
|
||||
} cpSpaceDebugDrawFlags;
|
||||
|
||||
/// Struct used with cpSpaceDebugDraw() containing drawing callbacks and other drawing settings.
|
||||
typedef struct cpSpaceDebugDrawOptions {
|
||||
/// Function that will be invoked to draw circles.
|
||||
cpSpaceDebugDrawCircleImpl drawCircle;
|
||||
/// Function that will be invoked to draw line segments.
|
||||
cpSpaceDebugDrawSegmentImpl drawSegment;
|
||||
/// Function that will be invoked to draw thick line segments.
|
||||
cpSpaceDebugDrawFatSegmentImpl drawFatSegment;
|
||||
/// Function that will be invoked to draw convex polygons.
|
||||
cpSpaceDebugDrawPolygonImpl drawPolygon;
|
||||
/// Function that will be invoked to draw dots.
|
||||
cpSpaceDebugDrawDotImpl drawDot;
|
||||
|
||||
/// Flags that request which things to draw (collision shapes, constraints, contact points).
|
||||
cpSpaceDebugDrawFlags flags;
|
||||
/// Outline color passed to the drawing function.
|
||||
cpSpaceDebugColor shapeOutlineColor;
|
||||
/// Function that decides what fill color to draw shapes using.
|
||||
cpSpaceDebugDrawColorForShapeImpl colorForShape;
|
||||
/// Color passed to drawing functions for constraints.
|
||||
cpSpaceDebugColor constraintColor;
|
||||
/// Color passed to drawing functions for collision points.
|
||||
cpSpaceDebugColor collisionPointColor;
|
||||
|
||||
/// User defined context pointer passed to all of the callback functions as the 'data' argument.
|
||||
cpDataPointer data;
|
||||
} cpSpaceDebugDrawOptions;
|
||||
|
||||
/// Debug draw the current state of the space using the supplied drawing options.
|
||||
CP_EXPORT void cpSpaceDebugDraw(cpSpace *space, cpSpaceDebugDrawOptions *options);
|
||||
|
||||
#endif
|
||||
|
||||
/// @}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2010 Scott Lembcke
|
||||
/* Copyright (c) 2013 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
|
||||
|
|
@ -69,48 +69,48 @@ struct cpSpatialIndex {
|
|||
typedef struct cpSpaceHash cpSpaceHash;
|
||||
|
||||
/// Allocate a spatial hash.
|
||||
cpSpaceHash* cpSpaceHashAlloc(void);
|
||||
CP_EXPORT cpSpaceHash* cpSpaceHashAlloc(void);
|
||||
/// Initialize a spatial hash.
|
||||
cpSpatialIndex* cpSpaceHashInit(cpSpaceHash *hash, cpFloat celldim, int numcells, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
CP_EXPORT cpSpatialIndex* cpSpaceHashInit(cpSpaceHash *hash, cpFloat celldim, int numcells, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
/// Allocate and initialize a spatial hash.
|
||||
cpSpatialIndex* cpSpaceHashNew(cpFloat celldim, int cells, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
CP_EXPORT cpSpatialIndex* cpSpaceHashNew(cpFloat celldim, int cells, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
|
||||
/// Change the cell dimensions and table size of the spatial hash to tune it.
|
||||
/// The cell dimensions should roughly match the average size of your objects
|
||||
/// and the table size should be ~10 larger than the number of objects inserted.
|
||||
/// Some trial and error is required to find the optimum numbers for efficiency.
|
||||
void cpSpaceHashResize(cpSpaceHash *hash, cpFloat celldim, int numcells);
|
||||
CP_EXPORT void cpSpaceHashResize(cpSpaceHash *hash, cpFloat celldim, int numcells);
|
||||
|
||||
//MARK: AABB Tree
|
||||
|
||||
typedef struct cpBBTree cpBBTree;
|
||||
|
||||
/// Allocate a bounding box tree.
|
||||
cpBBTree* cpBBTreeAlloc(void);
|
||||
CP_EXPORT cpBBTree* cpBBTreeAlloc(void);
|
||||
/// Initialize a bounding box tree.
|
||||
cpSpatialIndex* cpBBTreeInit(cpBBTree *tree, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
CP_EXPORT cpSpatialIndex* cpBBTreeInit(cpBBTree *tree, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
/// Allocate and initialize a bounding box tree.
|
||||
cpSpatialIndex* cpBBTreeNew(cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
CP_EXPORT cpSpatialIndex* cpBBTreeNew(cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
|
||||
/// Perform a static top down optimization of the tree.
|
||||
void cpBBTreeOptimize(cpSpatialIndex *index);
|
||||
CP_EXPORT void cpBBTreeOptimize(cpSpatialIndex *index);
|
||||
|
||||
/// Bounding box tree velocity callback function.
|
||||
/// This function should return an estimate for the object's velocity.
|
||||
typedef cpVect (*cpBBTreeVelocityFunc)(void *obj);
|
||||
/// Set the velocity function for the bounding box tree to enable temporal coherence.
|
||||
void cpBBTreeSetVelocityFunc(cpSpatialIndex *index, cpBBTreeVelocityFunc func);
|
||||
CP_EXPORT void cpBBTreeSetVelocityFunc(cpSpatialIndex *index, cpBBTreeVelocityFunc func);
|
||||
|
||||
//MARK: Single Axis Sweep
|
||||
|
||||
typedef struct cpSweep1D cpSweep1D;
|
||||
|
||||
/// Allocate a 1D sort and sweep broadphase.
|
||||
cpSweep1D* cpSweep1DAlloc(void);
|
||||
CP_EXPORT cpSweep1D* cpSweep1DAlloc(void);
|
||||
/// Initialize a 1D sort and sweep broadphase.
|
||||
cpSpatialIndex* cpSweep1DInit(cpSweep1D *sweep, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
CP_EXPORT cpSpatialIndex* cpSweep1DInit(cpSweep1D *sweep, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
/// Allocate and initialize a 1D sort and sweep broadphase.
|
||||
cpSpatialIndex* cpSweep1DNew(cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
CP_EXPORT cpSpatialIndex* cpSweep1DNew(cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
|
||||
//MARK: Spatial Index Implementation
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2007 Scott Lembcke
|
||||
/* Copyright (c) 2013 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
|
||||
|
|
@ -19,6 +19,11 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef CHIPMUNK_VECT_H
|
||||
#define CHIPMUNK_VECT_H
|
||||
|
||||
#include "chipmunk_types.h"
|
||||
|
||||
/// @defgroup cpVect cpVect
|
||||
/// Chipmunk's 2D vector type along with a handy 2D vector math lib.
|
||||
/// @{
|
||||
|
|
@ -33,17 +38,6 @@ static inline cpVect cpv(const cpFloat x, const cpFloat y)
|
|||
return v;
|
||||
}
|
||||
|
||||
/// Spherical linearly interpolate between v1 and v2.
|
||||
cpVect cpvslerp(const cpVect v1, const cpVect v2, const cpFloat t);
|
||||
|
||||
/// Spherical linearly interpolate between v1 towards v2 by no more than angle a radians
|
||||
cpVect cpvslerpconst(const cpVect v1, const cpVect v2, const cpFloat a);
|
||||
|
||||
/// Returns a string representation of v. Intended mostly for debugging purposes and not production use.
|
||||
/// @attention The string points to a static local and is reset every time the function is called.
|
||||
/// If you want to print more than one vector you will have to split up your printing onto separate lines.
|
||||
char* cpvstr(const cpVect v);
|
||||
|
||||
/// Check if two vectors are equal. (Be careful when comparing floating point numbers!)
|
||||
static inline cpBool cpveql(const cpVect v1, const cpVect v2)
|
||||
{
|
||||
|
|
@ -155,10 +149,30 @@ static inline cpVect cpvnormalize(const cpVect v)
|
|||
return cpvmult(v, 1.0f/(cpvlength(v) + CPFLOAT_MIN));
|
||||
}
|
||||
|
||||
/// @deprecated Just an alias for cpvnormalize() now.
|
||||
static inline cpVect cpvnormalize_safe(const cpVect v)
|
||||
/// Spherical linearly interpolate between v1 and v2.
|
||||
static inline cpVect
|
||||
cpvslerp(const cpVect v1, const cpVect v2, const cpFloat t)
|
||||
{
|
||||
return cpvnormalize(v);
|
||||
cpFloat dot = cpvdot(cpvnormalize(v1), cpvnormalize(v2));
|
||||
cpFloat omega = cpfacos(cpfclamp(dot, -1.0f, 1.0f));
|
||||
|
||||
if(omega < 1e-3){
|
||||
// If the angle between two vectors is very small, lerp instead to avoid precision issues.
|
||||
return cpvlerp(v1, v2, t);
|
||||
} else {
|
||||
cpFloat denom = 1.0f/cpfsin(omega);
|
||||
return cpvadd(cpvmult(v1, cpfsin((1.0f - t)*omega)*denom), cpvmult(v2, cpfsin(t*omega)*denom));
|
||||
}
|
||||
}
|
||||
|
||||
/// Spherical linearly interpolate between v1 towards v2 by no more than angle a radians
|
||||
static inline cpVect
|
||||
cpvslerpconst(const cpVect v1, const cpVect v2, const cpFloat a)
|
||||
{
|
||||
cpFloat dot = cpvdot(cpvnormalize(v1), cpvnormalize(v2));
|
||||
cpFloat omega = cpfacos(cpfclamp(dot, -1.0f, 1.0f));
|
||||
|
||||
return cpvslerp(v1, v2, cpfmin(a, omega)/omega);
|
||||
}
|
||||
|
||||
/// Clamp v to length len.
|
||||
|
|
@ -197,6 +211,7 @@ static inline cpBool cpvnear(const cpVect v1, const cpVect v2, const cpFloat dis
|
|||
/// 2x2 matrix type used for tensors and such.
|
||||
/// @{
|
||||
|
||||
// NUKE
|
||||
static inline cpMat2x2
|
||||
cpMat2x2New(cpFloat a, cpFloat b, cpFloat c, cpFloat d)
|
||||
{
|
||||
|
|
@ -211,3 +226,5 @@ cpMat2x2Transform(cpMat2x2 m, cpVect v)
|
|||
}
|
||||
|
||||
///@}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -1,4 +1,4 @@
|
|||
/* Copyright (c) 2007 Scott Lembcke
|
||||
/* Copyright (c) 2013 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
|
||||
|
|
@ -19,20 +19,26 @@
|
|||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef CHIPMUNK_HEADER
|
||||
#define CHIPMUNK_HEADER
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define _USE_MATH_DEFINES
|
||||
#endif
|
||||
#ifndef CHIPMUNK_H
|
||||
#define CHIPMUNK_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#ifdef WIN32
|
||||
// For alloca().
|
||||
#include <malloc.h>
|
||||
#define CP_EXPORT __declspec(dllexport)
|
||||
#else
|
||||
#include <alloca.h>
|
||||
#define CP_EXPORT
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// NUKE
|
||||
#ifndef CP_ALLOW_PRIVATE_ACCESS
|
||||
#define CP_ALLOW_PRIVATE_ACCESS 0
|
||||
#endif
|
||||
|
|
@ -43,22 +49,17 @@ extern "C" {
|
|||
#define CP_PRIVATE(__symbol__) __symbol__##_private
|
||||
#endif
|
||||
|
||||
void cpMessage(const char *condition, const char *file, int line, int isError, int isHardError, const char *message, ...);
|
||||
CP_EXPORT void cpMessage(const char *condition, const char *file, int line, int isError, int isHardError, const char *message, ...);
|
||||
#ifdef NDEBUG
|
||||
#define cpAssertWarn(__condition__, ...)
|
||||
#define cpAssertSoft(__condition__, ...)
|
||||
#else
|
||||
#define cpAssertSoft(__condition__, ...) if(!(__condition__)){cpMessage(#__condition__, __FILE__, __LINE__, 1, 0, __VA_ARGS__); abort();}
|
||||
#define cpAssertWarn(__condition__, ...) if(!(__condition__)) cpMessage(#__condition__, __FILE__, __LINE__, 0, 0, __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define cpAssertSoft(__condition__, ...)
|
||||
#else
|
||||
#define cpAssertSoft(__condition__, ...) if(!(__condition__)) cpMessage(#__condition__, __FILE__, __LINE__, 1, 0, __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
// Hard assertions are important and cheap to execute. They are not disabled by compiling as debug.
|
||||
#define cpAssertHard(__condition__, ...) if(!(__condition__)) cpMessage(#__condition__, __FILE__, __LINE__, 1, 1, __VA_ARGS__)
|
||||
|
||||
// Hard assertions are used in situations where the program definitely will crash anyway, and the reason is inexpensive to detect.
|
||||
#define cpAssertHard(__condition__, ...) if(!(__condition__)){cpMessage(#__condition__, __FILE__, __LINE__, 1, 1, __VA_ARGS__); abort();}
|
||||
|
||||
#include "chipmunk_types.h"
|
||||
|
||||
|
|
@ -89,81 +90,90 @@ typedef struct cpArray cpArray;
|
|||
typedef struct cpHashSet cpHashSet;
|
||||
|
||||
typedef struct cpBody cpBody;
|
||||
|
||||
typedef struct cpShape cpShape;
|
||||
typedef struct cpCircleShape cpCircleShape;
|
||||
typedef struct cpSegmentShape cpSegmentShape;
|
||||
typedef struct cpPolyShape cpPolyShape;
|
||||
|
||||
typedef struct cpConstraint cpConstraint;
|
||||
typedef struct cpPinJoint cpPinJoint;
|
||||
typedef struct cpSlideJoint cpSlideJoint;
|
||||
typedef struct cpPivotJoint cpPivotJoint;
|
||||
typedef struct cpGrooveJoint cpGrooveJoint;
|
||||
typedef struct cpDampedSpring cpDampedSpring;
|
||||
typedef struct cpDampedRotarySpring cpDampedRotarySpring;
|
||||
typedef struct cpRotaryLimitJoint cpRotaryLimitJoint;
|
||||
typedef struct cpRatchetJoint cpRatchetJoint;
|
||||
typedef struct cpGearJoint cpGearJoint;
|
||||
typedef struct cpSimpleMotorJoint cpSimpleMotorJoint;
|
||||
|
||||
typedef struct cpCollisionHandler cpCollisionHandler;
|
||||
typedef struct cpContactPointSet cpContactPointSet;
|
||||
typedef struct cpArbiter cpArbiter;
|
||||
|
||||
typedef struct cpSpace cpSpace;
|
||||
|
||||
#include "cpVect.h"
|
||||
#include "cpBB.h"
|
||||
#include "cpTransform.h"
|
||||
#include "cpSpatialIndex.h"
|
||||
|
||||
#include "cpArbiter.h"
|
||||
|
||||
#include "cpBody.h"
|
||||
#include "cpShape.h"
|
||||
#include "cpPolyShape.h"
|
||||
|
||||
#include "cpArbiter.h"
|
||||
#include "constraints/cpConstraint.h"
|
||||
#include "cpConstraint.h"
|
||||
|
||||
#include "cpSpace.h"
|
||||
#include "cpHastySpace.h"
|
||||
|
||||
// Chipmunk 6.2.1
|
||||
#define CP_VERSION_MAJOR 6
|
||||
#define CP_VERSION_MINOR 2
|
||||
// Chipmunk 7.0.1
|
||||
#define CP_VERSION_MAJOR 7
|
||||
#define CP_VERSION_MINOR 0
|
||||
#define CP_VERSION_RELEASE 1
|
||||
|
||||
/// Version string.
|
||||
extern const char *cpVersionString;
|
||||
|
||||
/// @deprecated
|
||||
void cpInitChipmunk(void);
|
||||
|
||||
/// Enables segment to segment shape collisions.
|
||||
void cpEnableSegmentToSegmentCollisions(void);
|
||||
|
||||
CP_EXPORT extern const char *cpVersionString;
|
||||
|
||||
/// Calculate the moment of inertia for a circle.
|
||||
/// @c r1 and @c r2 are the inner and outer diameters. A solid circle has an inner diameter of 0.
|
||||
cpFloat cpMomentForCircle(cpFloat m, cpFloat r1, cpFloat r2, cpVect offset);
|
||||
CP_EXPORT cpFloat cpMomentForCircle(cpFloat m, cpFloat r1, cpFloat r2, cpVect offset);
|
||||
|
||||
/// Calculate area of a hollow circle.
|
||||
/// @c r1 and @c r2 are the inner and outer diameters. A solid circle has an inner diameter of 0.
|
||||
cpFloat cpAreaForCircle(cpFloat r1, cpFloat r2);
|
||||
CP_EXPORT cpFloat cpAreaForCircle(cpFloat r1, cpFloat r2);
|
||||
|
||||
/// Calculate the moment of inertia for a line segment.
|
||||
/// Beveling radius is not supported.
|
||||
cpFloat cpMomentForSegment(cpFloat m, cpVect a, cpVect b);
|
||||
CP_EXPORT cpFloat cpMomentForSegment(cpFloat m, cpVect a, cpVect b, cpFloat radius);
|
||||
|
||||
/// Calculate the area of a fattened (capsule shaped) line segment.
|
||||
cpFloat cpAreaForSegment(cpVect a, cpVect b, cpFloat r);
|
||||
CP_EXPORT cpFloat cpAreaForSegment(cpVect a, cpVect b, cpFloat radius);
|
||||
|
||||
/// Calculate the moment of inertia for a solid polygon shape assuming it's center of gravity is at it's centroid. The offset is added to each vertex.
|
||||
cpFloat cpMomentForPoly(cpFloat m, int numVerts, const cpVect *verts, cpVect offset);
|
||||
CP_EXPORT cpFloat cpMomentForPoly(cpFloat m, int count, const cpVect *verts, cpVect offset, cpFloat radius);
|
||||
|
||||
/// Calculate the signed area of a polygon. A Clockwise winding gives positive area.
|
||||
/// This is probably backwards from what you expect, but matches Chipmunk's the winding for poly shapes.
|
||||
cpFloat cpAreaForPoly(const int numVerts, const cpVect *verts);
|
||||
CP_EXPORT cpFloat cpAreaForPoly(const int count, const cpVect *verts, cpFloat radius);
|
||||
|
||||
/// Calculate the natural centroid of a polygon.
|
||||
cpVect cpCentroidForPoly(const int numVerts, const cpVect *verts);
|
||||
|
||||
/// Center the polygon on the origin. (Subtracts the centroid of the polygon from each vertex)
|
||||
void cpRecenterPoly(const int numVerts, cpVect *verts);
|
||||
CP_EXPORT cpVect cpCentroidForPoly(const int count, const cpVect *verts);
|
||||
|
||||
/// Calculate the moment of inertia for a solid box.
|
||||
cpFloat cpMomentForBox(cpFloat m, cpFloat width, cpFloat height);
|
||||
CP_EXPORT cpFloat cpMomentForBox(cpFloat m, cpFloat width, cpFloat height);
|
||||
|
||||
/// Calculate the moment of inertia for a solid box.
|
||||
cpFloat cpMomentForBox2(cpFloat m, cpBB box);
|
||||
CP_EXPORT cpFloat cpMomentForBox2(cpFloat m, cpBB box);
|
||||
|
||||
/// Calculate the convex hull of a given set of points. Returns the count of points in the hull.
|
||||
/// @c result must be a pointer to a @c cpVect array with at least @c count elements. If @c result is @c NULL, then @c verts will be reduced instead.
|
||||
/// @c result must be a pointer to a @c cpVect array with at least @c count elements. If @c verts == @c result, then @c verts will be reduced inplace.
|
||||
/// @c first is an optional pointer to an integer to store where the first vertex in the hull came from (i.e. verts[first] == result[0])
|
||||
/// @c tol is the allowed amount to shrink the hull when simplifying it. A tolerance of 0.0 creates an exact hull.
|
||||
int cpConvexHull(int count, cpVect *verts, cpVect *result, int *first, cpFloat tol);
|
||||
CP_EXPORT int cpConvexHull(int count, const cpVect *verts, cpVect *result, int *first, cpFloat tol);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include "malloc.h"
|
||||
|
|
@ -177,6 +187,15 @@ int cpConvexHull(int count, cpVect *verts, cpVect *result, int *first, cpFloat t
|
|||
cpVect *__verts_var__ = (cpVect *)alloca(__count__*sizeof(cpVect)); \
|
||||
int __count_var__ = cpConvexHull(__count__, __verts__, __verts_var__, NULL, 0.0); \
|
||||
|
||||
/// Returns the closest point on the line segment ab, to the point p.
|
||||
static inline cpVect
|
||||
cpClosetPointOnSegment(const cpVect p, const cpVect a, const cpVect b)
|
||||
{
|
||||
cpVect delta = cpvsub(a, b);
|
||||
cpFloat t = cpfclamp01(cpvdot(delta, cpvsub(p, b))/cpvlengthsq(delta));
|
||||
return cpvadd(b, cpvmult(delta, t));
|
||||
}
|
||||
|
||||
#if defined(__has_extension)
|
||||
#if __has_extension(blocks)
|
||||
// Define alternate block based alternatives for a few of the callback heavy functions.
|
||||
|
|
@ -191,14 +210,14 @@ void cpBodyEachShape_b(cpBody *body, void (^block)(cpShape *shape));
|
|||
void cpBodyEachConstraint_b(cpBody *body, void (^block)(cpConstraint *constraint));
|
||||
void cpBodyEachArbiter_b(cpBody *body, void (^block)(cpArbiter *arbiter));
|
||||
|
||||
typedef void (^cpSpaceNearestPointQueryBlock)(cpShape *shape, cpFloat distance, cpVect point);
|
||||
void cpSpaceNearestPointQuery_b(cpSpace *space, cpVect point, cpFloat maxDistance, cpLayers layers, cpGroup group, cpSpaceNearestPointQueryBlock block);
|
||||
typedef void (^cpSpacePointQueryBlock)(cpShape *shape, cpVect point, cpFloat distance, cpVect gradient);
|
||||
void cpSpacePointQuery_b(cpSpace *space, cpVect point, cpFloat maxDistance, cpShapeFilter filter, cpSpacePointQueryBlock block);
|
||||
|
||||
typedef void (^cpSpaceSegmentQueryBlock)(cpShape *shape, cpFloat t, cpVect n);
|
||||
void cpSpaceSegmentQuery_b(cpSpace *space, cpVect start, cpVect end, cpLayers layers, cpGroup group, cpSpaceSegmentQueryBlock block);
|
||||
typedef void (^cpSpaceSegmentQueryBlock)(cpShape *shape, cpVect point, cpVect normal, cpFloat alpha);
|
||||
void cpSpaceSegmentQuery_b(cpSpace *space, cpVect start, cpVect end, cpFloat radius, cpShapeFilter filter, cpSpaceSegmentQueryBlock block);
|
||||
|
||||
typedef void (^cpSpaceBBQueryBlock)(cpShape *shape);
|
||||
void cpSpaceBBQuery_b(cpSpace *space, cpBB bb, cpLayers layers, cpGroup group, cpSpaceBBQueryBlock block);
|
||||
void cpSpaceBBQuery_b(cpSpace *space, cpBB bb, cpShapeFilter filter, cpSpaceBBQueryBlock block);
|
||||
|
||||
typedef void (^cpSpaceShapeQueryBlock)(cpShape *shape, cpContactPointSet *points);
|
||||
cpBool cpSpaceShapeQuery_b(cpSpace *space, cpShape *shape, cpSpaceShapeQueryBlock block);
|
||||
|
|
|
|||
|
|
@ -1,222 +0,0 @@
|
|||
/* 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.
|
||||
*/
|
||||
|
||||
#ifndef CHIPMUNK_HEADER
|
||||
#define CHIPMUNK_HEADER
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#define _USE_MATH_DEFINES
|
||||
#endif
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef CP_ALLOW_PRIVATE_ACCESS
|
||||
#define CP_ALLOW_PRIVATE_ACCESS 0
|
||||
#endif
|
||||
|
||||
#if CP_ALLOW_PRIVATE_ACCESS == 1
|
||||
#define CP_PRIVATE(__symbol__) __symbol__
|
||||
#else
|
||||
#define CP_PRIVATE(__symbol__) __symbol__##_private
|
||||
#endif
|
||||
|
||||
void cpMessage(const char *condition, const char *file, int line, int isError, int isHardError, const char *message, ...);
|
||||
#ifdef NDEBUG
|
||||
#define cpAssertWarn(__condition__, ...)
|
||||
#else
|
||||
#define cpAssertWarn(__condition__, ...) if(!(__condition__)) cpMessage(#__condition__, __FILE__, __LINE__, 0, 0, __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
#ifdef NDEBUG
|
||||
#define cpAssertSoft(__condition__, ...)
|
||||
#else
|
||||
#define cpAssertSoft(__condition__, ...) if(!(__condition__)) cpMessage(#__condition__, __FILE__, __LINE__, 1, 0, __VA_ARGS__)
|
||||
#endif
|
||||
|
||||
// Hard assertions are important and cheap to execute. They are not disabled by compiling as debug.
|
||||
#define cpAssertHard(__condition__, ...) if(!(__condition__)) cpMessage(#__condition__, __FILE__, __LINE__, 1, 1, __VA_ARGS__)
|
||||
|
||||
|
||||
#include "chipmunk_types.h"
|
||||
|
||||
/// @defgroup misc Misc
|
||||
/// @{
|
||||
|
||||
/// Allocated size for various Chipmunk buffers
|
||||
#ifndef CP_BUFFER_BYTES
|
||||
#define CP_BUFFER_BYTES (32*1024)
|
||||
#endif
|
||||
|
||||
#ifndef cpcalloc
|
||||
/// Chipmunk calloc() alias.
|
||||
#define cpcalloc calloc
|
||||
#endif
|
||||
|
||||
#ifndef cprealloc
|
||||
/// Chipmunk realloc() alias.
|
||||
#define cprealloc realloc
|
||||
#endif
|
||||
|
||||
#ifndef cpfree
|
||||
/// Chipmunk free() alias.
|
||||
#define cpfree free
|
||||
#endif
|
||||
|
||||
typedef struct cpArray cpArray;
|
||||
typedef struct cpHashSet cpHashSet;
|
||||
|
||||
typedef struct cpBody cpBody;
|
||||
typedef struct cpShape cpShape;
|
||||
typedef struct cpConstraint cpConstraint;
|
||||
|
||||
typedef struct cpCollisionHandler cpCollisionHandler;
|
||||
typedef struct cpArbiter cpArbiter;
|
||||
|
||||
typedef struct cpSpace cpSpace;
|
||||
|
||||
#include "cpVect.h"
|
||||
#include "cpBB.h"
|
||||
#include "cpSpatialIndex.h"
|
||||
|
||||
#include "cpBody.h"
|
||||
#include "cpShape.h"
|
||||
#include "cpPolyShape.h"
|
||||
|
||||
#include "cpArbiter.h"
|
||||
#include "constraints/cpConstraint.h"
|
||||
|
||||
#include "cpSpace.h"
|
||||
|
||||
// Chipmunk 6.2.1
|
||||
#define CP_VERSION_MAJOR 6
|
||||
#define CP_VERSION_MINOR 2
|
||||
#define CP_VERSION_RELEASE 1
|
||||
|
||||
/// Version string.
|
||||
extern const char *cpVersionString;
|
||||
|
||||
/// @deprecated
|
||||
void cpInitChipmunk(void);
|
||||
|
||||
/// Enables segment to segment shape collisions.
|
||||
void cpEnableSegmentToSegmentCollisions(void);
|
||||
|
||||
|
||||
/// Calculate the moment of inertia for a circle.
|
||||
/// @c r1 and @c r2 are the inner and outer diameters. A solid circle has an inner diameter of 0.
|
||||
cpFloat cpMomentForCircle(cpFloat m, cpFloat r1, cpFloat r2, cpVect offset);
|
||||
|
||||
/// Calculate area of a hollow circle.
|
||||
/// @c r1 and @c r2 are the inner and outer diameters. A solid circle has an inner diameter of 0.
|
||||
cpFloat cpAreaForCircle(cpFloat r1, cpFloat r2);
|
||||
|
||||
/// Calculate the moment of inertia for a line segment.
|
||||
/// Beveling radius is not supported.
|
||||
cpFloat cpMomentForSegment(cpFloat m, cpVect a, cpVect b);
|
||||
|
||||
/// Calculate the area of a fattened (capsule shaped) line segment.
|
||||
cpFloat cpAreaForSegment(cpVect a, cpVect b, cpFloat r);
|
||||
|
||||
/// Calculate the moment of inertia for a solid polygon shape assuming it's center of gravity is at it's centroid. The offset is added to each vertex.
|
||||
cpFloat cpMomentForPoly(cpFloat m, int numVerts, const cpVect *verts, cpVect offset);
|
||||
|
||||
/// Calculate the signed area of a polygon. A Clockwise winding gives positive area.
|
||||
/// This is probably backwards from what you expect, but matches Chipmunk's the winding for poly shapes.
|
||||
cpFloat cpAreaForPoly(const int numVerts, const cpVect *verts);
|
||||
|
||||
/// Calculate the natural centroid of a polygon.
|
||||
cpVect cpCentroidForPoly(const int numVerts, const cpVect *verts);
|
||||
|
||||
/// Center the polygon on the origin. (Subtracts the centroid of the polygon from each vertex)
|
||||
void cpRecenterPoly(const int numVerts, cpVect *verts);
|
||||
|
||||
/// Calculate the moment of inertia for a solid box.
|
||||
cpFloat cpMomentForBox(cpFloat m, cpFloat width, cpFloat height);
|
||||
|
||||
/// Calculate the moment of inertia for a solid box.
|
||||
cpFloat cpMomentForBox2(cpFloat m, cpBB box);
|
||||
|
||||
/// Calculate the convex hull of a given set of points. Returns the count of points in the hull.
|
||||
/// @c result must be a pointer to a @c cpVect array with at least @c count elements. If @c result is @c NULL, then @c verts will be reduced instead.
|
||||
/// @c first is an optional pointer to an integer to store where the first vertex in the hull came from (i.e. verts[first] == result[0])
|
||||
/// @c tol is the allowed amount to shrink the hull when simplifying it. A tolerance of 0.0 creates an exact hull.
|
||||
int cpConvexHull(int count, cpVect *verts, cpVect *result, int *first, cpFloat tol);
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#include "malloc.h"
|
||||
#endif
|
||||
|
||||
/// Convenience macro to work with cpConvexHull.
|
||||
/// @c count and @c verts is the input array passed to cpConvexHull().
|
||||
/// @c count_var and @c verts_var are the names of the variables the macro creates to store the result.
|
||||
/// The output vertex array is allocated on the stack using alloca() so it will be freed automatically, but cannot be returned from the current scope.
|
||||
#define CP_CONVEX_HULL(__count__, __verts__, __count_var__, __verts_var__) \
|
||||
cpVect *__verts_var__ = (cpVect *)alloca(__count__*sizeof(cpVect)); \
|
||||
int __count_var__ = cpConvexHull(__count__, __verts__, __verts_var__, NULL, 0.0); \
|
||||
|
||||
#if defined(__has_extension)
|
||||
#if __has_extension(blocks)
|
||||
// Define alternate block based alternatives for a few of the callback heavy functions.
|
||||
// Collision handlers are post-step callbacks are not included to avoid memory management issues.
|
||||
// If you want to use blocks for those and are aware of how to correctly manage the memory, the implementation is trivial.
|
||||
|
||||
void cpSpaceEachBody_b(cpSpace *space, void (^block)(cpBody *body));
|
||||
void cpSpaceEachShape_b(cpSpace *space, void (^block)(cpShape *shape));
|
||||
void cpSpaceEachConstraint_b(cpSpace *space, void (^block)(cpConstraint *constraint));
|
||||
|
||||
void cpBodyEachShape_b(cpBody *body, void (^block)(cpShape *shape));
|
||||
void cpBodyEachConstraint_b(cpBody *body, void (^block)(cpConstraint *constraint));
|
||||
void cpBodyEachArbiter_b(cpBody *body, void (^block)(cpArbiter *arbiter));
|
||||
|
||||
typedef void (^cpSpaceNearestPointQueryBlock)(cpShape *shape, cpFloat distance, cpVect point);
|
||||
void cpSpaceNearestPointQuery_b(cpSpace *space, cpVect point, cpFloat maxDistance, cpLayers layers, cpGroup group, cpSpaceNearestPointQueryBlock block);
|
||||
|
||||
typedef void (^cpSpaceSegmentQueryBlock)(cpShape *shape, cpFloat t, cpVect n);
|
||||
void cpSpaceSegmentQuery_b(cpSpace *space, cpVect start, cpVect end, cpLayers layers, cpGroup group, cpSpaceSegmentQueryBlock block);
|
||||
|
||||
typedef void (^cpSpaceBBQueryBlock)(cpShape *shape);
|
||||
void cpSpaceBBQuery_b(cpSpace *space, cpBB bb, cpLayers layers, cpGroup group, cpSpaceBBQueryBlock block);
|
||||
|
||||
typedef void (^cpSpaceShapeQueryBlock)(cpShape *shape, cpContactPointSet *points);
|
||||
cpBool cpSpaceShapeQuery_b(cpSpace *space, cpShape *shape, cpSpaceShapeQueryBlock block);
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
//@}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
||||
static inline cpVect operator *(const cpVect v, const cpFloat s){return cpvmult(v, s);}
|
||||
static inline cpVect operator +(const cpVect v1, const cpVect v2){return cpvadd(v1, v2);}
|
||||
static inline cpVect operator -(const cpVect v1, const cpVect v2){return cpvsub(v1, v2);}
|
||||
static inline cpBool operator ==(const cpVect v1, const cpVect v2){return cpveql(v1, v2);}
|
||||
static inline cpVect operator -(const cpVect v){return cpvneg(v);}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
|
@ -1,177 +0,0 @@
|
|||
#ifdef CHIPMUNK_FFI
|
||||
|
||||
// Create non static inlined copies of Chipmunk functions, useful for working with dynamic FFIs
|
||||
// This file should only be included in chipmunk.c
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#if _MSC_VER >= 1600
|
||||
#define MAKE_REF(name) decltype(name) *_##name = name
|
||||
#else
|
||||
#define MAKE_REF(name)
|
||||
#endif
|
||||
#else
|
||||
#define MAKE_REF(name) __typeof__(name) *_##name = name
|
||||
#endif
|
||||
|
||||
#define MAKE_PROPERTIES_REF(struct, property) \
|
||||
MAKE_REF(struct##Get##property); MAKE_REF(struct##Set##property)
|
||||
|
||||
MAKE_REF(cpv); // makes a variable named _cpv that contains the function pointer for cpv()
|
||||
MAKE_REF(cpveql);
|
||||
MAKE_REF(cpvadd);
|
||||
MAKE_REF(cpvneg);
|
||||
MAKE_REF(cpvsub);
|
||||
MAKE_REF(cpvmult);
|
||||
MAKE_REF(cpvdot);
|
||||
MAKE_REF(cpvcross);
|
||||
MAKE_REF(cpvperp);
|
||||
MAKE_REF(cpvrperp);
|
||||
MAKE_REF(cpvproject);
|
||||
MAKE_REF(cpvforangle);
|
||||
MAKE_REF(cpvtoangle);
|
||||
MAKE_REF(cpvrotate);
|
||||
MAKE_REF(cpvunrotate);
|
||||
MAKE_REF(cpvlengthsq);
|
||||
MAKE_REF(cpvlength);
|
||||
MAKE_REF(cpvlerp);
|
||||
MAKE_REF(cpvnormalize);
|
||||
MAKE_REF(cpvnormalize_safe);
|
||||
MAKE_REF(cpvclamp);
|
||||
MAKE_REF(cpvlerpconst);
|
||||
MAKE_REF(cpvdist);
|
||||
MAKE_REF(cpvdistsq);
|
||||
MAKE_REF(cpvnear);
|
||||
|
||||
MAKE_REF(cpfmax);
|
||||
MAKE_REF(cpfmin);
|
||||
MAKE_REF(cpfabs);
|
||||
MAKE_REF(cpfclamp);
|
||||
MAKE_REF(cpflerp);
|
||||
MAKE_REF(cpflerpconst);
|
||||
|
||||
MAKE_REF(cpBBNew);
|
||||
MAKE_REF(cpBBNewForCircle);
|
||||
MAKE_REF(cpBBIntersects);
|
||||
MAKE_REF(cpBBContainsBB);
|
||||
MAKE_REF(cpBBContainsVect);
|
||||
MAKE_REF(cpBBMerge);
|
||||
MAKE_REF(cpBBExpand);
|
||||
MAKE_REF(cpBBArea);
|
||||
MAKE_REF(cpBBMergedArea);
|
||||
MAKE_REF(cpBBSegmentQuery);
|
||||
MAKE_REF(cpBBIntersectsSegment);
|
||||
MAKE_REF(cpBBClampVect);
|
||||
|
||||
MAKE_REF(cpBodyGetMass);
|
||||
MAKE_REF(cpBodyGetMoment);
|
||||
MAKE_REF(cpBodyGetPos);
|
||||
MAKE_REF(cpBodyGetAngle);
|
||||
MAKE_REF(cpBodyGetRot);
|
||||
MAKE_PROPERTIES_REF(cpBody, Vel);
|
||||
MAKE_PROPERTIES_REF(cpBody, Force);
|
||||
MAKE_PROPERTIES_REF(cpBody, AngVel);
|
||||
MAKE_PROPERTIES_REF(cpBody, Torque);
|
||||
MAKE_PROPERTIES_REF(cpBody, VelLimit);
|
||||
MAKE_PROPERTIES_REF(cpBody, AngVelLimit);
|
||||
MAKE_PROPERTIES_REF(cpBody, UserData);
|
||||
MAKE_REF(cpBodyIsSleeping);
|
||||
MAKE_REF(cpBodyIsStatic);
|
||||
MAKE_REF(cpBodyIsRogue);
|
||||
MAKE_REF(cpBodyLocal2World);
|
||||
MAKE_REF(cpBodyWorld2Local);
|
||||
MAKE_REF(cpBodyKineticEnergy);
|
||||
|
||||
MAKE_REF(cpShapeGetBB);
|
||||
MAKE_PROPERTIES_REF(cpShape, Body);
|
||||
MAKE_PROPERTIES_REF(cpShape, Sensor);
|
||||
MAKE_PROPERTIES_REF(cpShape, Elasticity);
|
||||
MAKE_PROPERTIES_REF(cpShape, Friction);
|
||||
MAKE_PROPERTIES_REF(cpShape, SurfaceVelocity);
|
||||
MAKE_PROPERTIES_REF(cpShape, UserData);
|
||||
MAKE_PROPERTIES_REF(cpShape, CollisionType);
|
||||
MAKE_PROPERTIES_REF(cpShape, Group);
|
||||
MAKE_PROPERTIES_REF(cpShape, Layers);
|
||||
|
||||
MAKE_REF(cpArbiterGetShapes);
|
||||
MAKE_REF(cpArbiterGetBodies);
|
||||
MAKE_REF(cpArbiterIsFirstContact);
|
||||
MAKE_REF(cpArbiterGetCount);
|
||||
|
||||
MAKE_REF(cpConstraintGetA);
|
||||
MAKE_REF(cpConstraintGetB);
|
||||
MAKE_PROPERTIES_REF(cpConstraint, MaxForce);
|
||||
MAKE_PROPERTIES_REF(cpConstraint, ErrorBias);
|
||||
MAKE_PROPERTIES_REF(cpConstraint, MaxBias);
|
||||
MAKE_PROPERTIES_REF(cpConstraint, UserData);
|
||||
MAKE_REF(cpConstraintGetImpulse);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpDampedRotarySpring, RestAngle);
|
||||
MAKE_PROPERTIES_REF(cpDampedRotarySpring, Stiffness);
|
||||
MAKE_PROPERTIES_REF(cpDampedRotarySpring, Damping);
|
||||
//MAKE_PROPERTIES_REF(cpDampedRotarySpring, SpringTorqueFunc);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpDampedSpring, Anchr1);
|
||||
MAKE_PROPERTIES_REF(cpDampedSpring, Anchr2);
|
||||
MAKE_PROPERTIES_REF(cpDampedSpring, RestLength);
|
||||
MAKE_PROPERTIES_REF(cpDampedSpring, Stiffness);
|
||||
MAKE_PROPERTIES_REF(cpDampedSpring, Damping);
|
||||
//MAKE_PROPERTIES_REF(cpDampedSpring, SpringForceFunc);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpGearJoint, Phase);
|
||||
MAKE_REF(cpGearJointGetRatio);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpGrooveJoint, Anchr2);
|
||||
MAKE_REF(cpGrooveJointGetGrooveA);
|
||||
MAKE_REF(cpGrooveJointGetGrooveB);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpPinJoint, Anchr1);
|
||||
MAKE_PROPERTIES_REF(cpPinJoint, Anchr2);
|
||||
MAKE_PROPERTIES_REF(cpPinJoint, Dist);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpPivotJoint, Anchr1);
|
||||
MAKE_PROPERTIES_REF(cpPivotJoint, Anchr2);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpRatchetJoint, Angle);
|
||||
MAKE_PROPERTIES_REF(cpRatchetJoint, Phase);
|
||||
MAKE_PROPERTIES_REF(cpRatchetJoint, Ratchet);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpRotaryLimitJoint, Min);
|
||||
MAKE_PROPERTIES_REF(cpRotaryLimitJoint, Max);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpSimpleMotor, Rate);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpSlideJoint, Anchr1);
|
||||
MAKE_PROPERTIES_REF(cpSlideJoint, Anchr2);
|
||||
MAKE_PROPERTIES_REF(cpSlideJoint, Min);
|
||||
MAKE_PROPERTIES_REF(cpSlideJoint, Max);
|
||||
|
||||
MAKE_REF(cpSegmentQueryHitPoint);
|
||||
MAKE_REF(cpSegmentQueryHitDist);
|
||||
|
||||
MAKE_REF(cpSpatialIndexDestroy);
|
||||
MAKE_REF(cpSpatialIndexCount);
|
||||
MAKE_REF(cpSpatialIndexEach);
|
||||
MAKE_REF(cpSpatialIndexContains);
|
||||
MAKE_REF(cpSpatialIndexInsert);
|
||||
MAKE_REF(cpSpatialIndexRemove);
|
||||
MAKE_REF(cpSpatialIndexReindex);
|
||||
MAKE_REF(cpSpatialIndexReindexObject);
|
||||
MAKE_REF(cpSpatialIndexSegmentQuery);
|
||||
MAKE_REF(cpSpatialIndexQuery);
|
||||
MAKE_REF(cpSpatialIndexReindexQuery);
|
||||
|
||||
MAKE_PROPERTIES_REF(cpSpace, Iterations);
|
||||
MAKE_PROPERTIES_REF(cpSpace, Gravity);
|
||||
MAKE_PROPERTIES_REF(cpSpace, Damping);
|
||||
MAKE_PROPERTIES_REF(cpSpace, IdleSpeedThreshold);
|
||||
MAKE_PROPERTIES_REF(cpSpace, SleepTimeThreshold);
|
||||
MAKE_PROPERTIES_REF(cpSpace, CollisionSlop);
|
||||
MAKE_PROPERTIES_REF(cpSpace, CollisionBias);
|
||||
MAKE_PROPERTIES_REF(cpSpace, CollisionPersistence);
|
||||
MAKE_PROPERTIES_REF(cpSpace, EnableContactGraph);
|
||||
MAKE_PROPERTIES_REF(cpSpace, UserData);
|
||||
MAKE_REF(cpSpaceGetStaticBody);
|
||||
MAKE_REF(cpSpaceGetCurrentTimeStep);
|
||||
MAKE_REF(cpSpaceIsLocked);
|
||||
|
||||
#endif
|
||||
|
|
@ -1,254 +0,0 @@
|
|||
/* 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.
|
||||
*/
|
||||
|
||||
#define CP_ALLOW_PRIVATE_ACCESS 1
|
||||
#include "chipmunk.h"
|
||||
|
||||
#define CP_HASH_COEF (3344921057ul)
|
||||
#define CP_HASH_PAIR(A, B) ((cpHashValue)(A)*CP_HASH_COEF ^ (cpHashValue)(B)*CP_HASH_COEF)
|
||||
|
||||
// TODO: Eww. Magic numbers.
|
||||
#define MAGIC_EPSILON 1e-5
|
||||
|
||||
//MARK: cpArray
|
||||
|
||||
struct cpArray {
|
||||
int num, max;
|
||||
void **arr;
|
||||
};
|
||||
|
||||
cpArray *cpArrayNew(int size);
|
||||
|
||||
void cpArrayFree(cpArray *arr);
|
||||
|
||||
void cpArrayPush(cpArray *arr, void *object);
|
||||
void *cpArrayPop(cpArray *arr);
|
||||
void cpArrayDeleteObj(cpArray *arr, void *obj);
|
||||
cpBool cpArrayContains(cpArray *arr, void *ptr);
|
||||
|
||||
void cpArrayFreeEach(cpArray *arr, void (freeFunc)(void*));
|
||||
|
||||
|
||||
//MARK: Foreach loops
|
||||
|
||||
static inline cpConstraint *
|
||||
cpConstraintNext(cpConstraint *node, cpBody *body)
|
||||
{
|
||||
return (node->a == body ? node->next_a : node->next_b);
|
||||
}
|
||||
|
||||
#define CP_BODY_FOREACH_CONSTRAINT(bdy, var)\
|
||||
for(cpConstraint *var = bdy->constraintList; var; var = cpConstraintNext(var, bdy))
|
||||
|
||||
static inline cpArbiter *
|
||||
cpArbiterNext(cpArbiter *node, cpBody *body)
|
||||
{
|
||||
return (node->body_a == body ? node->thread_a.next : node->thread_b.next);
|
||||
}
|
||||
|
||||
#define CP_BODY_FOREACH_ARBITER(bdy, var)\
|
||||
for(cpArbiter *var = bdy->arbiterList; var; var = cpArbiterNext(var, bdy))
|
||||
|
||||
#define CP_BODY_FOREACH_SHAPE(body, var)\
|
||||
for(cpShape *var = body->shapeList; var; var = var->next)
|
||||
|
||||
#define CP_BODY_FOREACH_COMPONENT(root, var)\
|
||||
for(cpBody *var = root; var; var = var->node.next)
|
||||
|
||||
|
||||
//MARK: cpHashSet
|
||||
|
||||
typedef cpBool (*cpHashSetEqlFunc)(void *ptr, void *elt);
|
||||
typedef void *(*cpHashSetTransFunc)(void *ptr, void *data);
|
||||
|
||||
cpHashSet *cpHashSetNew(int size, cpHashSetEqlFunc eqlFunc);
|
||||
void cpHashSetSetDefaultValue(cpHashSet *set, void *default_value);
|
||||
|
||||
void cpHashSetFree(cpHashSet *set);
|
||||
|
||||
int cpHashSetCount(cpHashSet *set);
|
||||
void *cpHashSetInsert(cpHashSet *set, cpHashValue hash, void *ptr, void *data, cpHashSetTransFunc trans);
|
||||
void *cpHashSetRemove(cpHashSet *set, cpHashValue hash, void *ptr);
|
||||
void *cpHashSetFind(cpHashSet *set, cpHashValue hash, void *ptr);
|
||||
|
||||
typedef void (*cpHashSetIteratorFunc)(void *elt, void *data);
|
||||
void cpHashSetEach(cpHashSet *set, cpHashSetIteratorFunc func, void *data);
|
||||
|
||||
typedef cpBool (*cpHashSetFilterFunc)(void *elt, void *data);
|
||||
void cpHashSetFilter(cpHashSet *set, cpHashSetFilterFunc func, void *data);
|
||||
|
||||
|
||||
//MARK: Body Functions
|
||||
|
||||
void cpBodyAddShape(cpBody *body, cpShape *shape);
|
||||
void cpBodyRemoveShape(cpBody *body, cpShape *shape);
|
||||
void cpBodyRemoveConstraint(cpBody *body, cpConstraint *constraint);
|
||||
|
||||
|
||||
//MARK: Shape/Collision Functions
|
||||
|
||||
// TODO should move this to the cpVect API. It's pretty useful.
|
||||
static inline cpVect
|
||||
cpClosetPointOnSegment(const cpVect p, const cpVect a, const cpVect b)
|
||||
{
|
||||
cpVect delta = cpvsub(a, b);
|
||||
cpFloat t = cpfclamp01(cpvdot(delta, cpvsub(p, b))/cpvlengthsq(delta));
|
||||
return cpvadd(b, cpvmult(delta, t));
|
||||
}
|
||||
|
||||
cpShape* cpShapeInit(cpShape *shape, const cpShapeClass *klass, cpBody *body);
|
||||
|
||||
static inline cpBool
|
||||
cpShapeActive(cpShape *shape)
|
||||
{
|
||||
return shape->prev || (shape->body && shape->body->shapeList == shape);
|
||||
}
|
||||
|
||||
int cpCollideShapes(const cpShape *a, const cpShape *b, cpCollisionID *id, cpContact *arr);
|
||||
|
||||
static inline void
|
||||
CircleSegmentQuery(cpShape *shape, cpVect center, cpFloat r, cpVect a, cpVect b, cpSegmentQueryInfo *info)
|
||||
{
|
||||
cpVect da = cpvsub(a, center);
|
||||
cpVect db = cpvsub(b, center);
|
||||
|
||||
cpFloat qa = cpvdot(da, da) - 2.0f*cpvdot(da, db) + cpvdot(db, db);
|
||||
cpFloat qb = -2.0f*cpvdot(da, da) + 2.0f*cpvdot(da, db);
|
||||
cpFloat qc = cpvdot(da, da) - r*r;
|
||||
|
||||
cpFloat det = qb*qb - 4.0f*qa*qc;
|
||||
|
||||
if(det >= 0.0f){
|
||||
cpFloat t = (-qb - cpfsqrt(det))/(2.0f*qa);
|
||||
if(0.0f<= t && t <= 1.0f){
|
||||
info->shape = shape;
|
||||
info->t = t;
|
||||
info->n = cpvnormalize(cpvlerp(da, db, t));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO doesn't really need to be inline, but need a better place to put this function
|
||||
static inline cpSplittingPlane
|
||||
cpSplittingPlaneNew(cpVect a, cpVect b)
|
||||
{
|
||||
cpVect n = cpvnormalize(cpvperp(cpvsub(b, a)));
|
||||
cpSplittingPlane plane = {n, cpvdot(n, a)};
|
||||
return plane;
|
||||
}
|
||||
|
||||
static inline cpFloat
|
||||
cpSplittingPlaneCompare(cpSplittingPlane plane, cpVect v)
|
||||
{
|
||||
return cpvdot(plane.n, v) - plane.d;
|
||||
}
|
||||
|
||||
void cpLoopIndexes(cpVect *verts, int count, int *start, int *end);
|
||||
|
||||
|
||||
//MARK: Spatial Index Functions
|
||||
|
||||
cpSpatialIndex *cpSpatialIndexInit(cpSpatialIndex *index, cpSpatialIndexClass *klass, cpSpatialIndexBBFunc bbfunc, cpSpatialIndex *staticIndex);
|
||||
|
||||
|
||||
//MARK: Space Functions
|
||||
|
||||
extern cpCollisionHandler cpDefaultCollisionHandler;
|
||||
void cpSpaceProcessComponents(cpSpace *space, cpFloat dt);
|
||||
|
||||
void cpSpacePushFreshContactBuffer(cpSpace *space);
|
||||
cpContact *cpContactBufferGetArray(cpSpace *space);
|
||||
void cpSpacePushContacts(cpSpace *space, int count);
|
||||
|
||||
typedef struct cpPostStepCallback {
|
||||
cpPostStepFunc func;
|
||||
void *key;
|
||||
void *data;
|
||||
} cpPostStepCallback;
|
||||
|
||||
cpPostStepCallback *cpSpaceGetPostStepCallback(cpSpace *space, void *key);
|
||||
|
||||
cpBool cpSpaceArbiterSetFilter(cpArbiter *arb, cpSpace *space);
|
||||
void cpSpaceFilterArbiters(cpSpace *space, cpBody *body, cpShape *filter);
|
||||
|
||||
void cpSpaceActivateBody(cpSpace *space, cpBody *body);
|
||||
void cpSpaceLock(cpSpace *space);
|
||||
void cpSpaceUnlock(cpSpace *space, cpBool runPostStep);
|
||||
|
||||
static inline cpCollisionHandler *
|
||||
cpSpaceLookupHandler(cpSpace *space, cpCollisionType a, cpCollisionType b)
|
||||
{
|
||||
cpCollisionType types[] = {a, b};
|
||||
return (cpCollisionHandler *)cpHashSetFind(space->collisionHandlers, CP_HASH_PAIR(a, b), types);
|
||||
}
|
||||
|
||||
static inline void
|
||||
cpSpaceUncacheArbiter(cpSpace *space, cpArbiter *arb)
|
||||
{
|
||||
cpShape *a = arb->a, *b = arb->b;
|
||||
cpShape *shape_pair[] = {a, b};
|
||||
cpHashValue arbHashID = CP_HASH_PAIR((cpHashValue)a, (cpHashValue)b);
|
||||
cpHashSetRemove(space->cachedArbiters, arbHashID, shape_pair);
|
||||
cpArrayDeleteObj(space->arbiters, arb);
|
||||
}
|
||||
|
||||
void cpShapeUpdateFunc(cpShape *shape, void *unused);
|
||||
cpCollisionID cpSpaceCollideShapes(cpShape *a, cpShape *b, cpCollisionID id, cpSpace *space);
|
||||
|
||||
|
||||
//MARK: Arbiters
|
||||
|
||||
struct cpContact {
|
||||
cpVect p, n;
|
||||
cpFloat dist;
|
||||
|
||||
cpVect r1, r2;
|
||||
cpFloat nMass, tMass, bounce;
|
||||
|
||||
cpFloat jnAcc, jtAcc, jBias;
|
||||
cpFloat bias;
|
||||
|
||||
cpHashValue hash;
|
||||
};
|
||||
|
||||
cpContact* cpContactInit(cpContact *con, cpVect p, cpVect n, cpFloat dist, cpHashValue hash);
|
||||
cpArbiter* cpArbiterInit(cpArbiter *arb, cpShape *a, cpShape *b);
|
||||
|
||||
static inline void
|
||||
cpArbiterCallSeparate(cpArbiter *arb, cpSpace *space)
|
||||
{
|
||||
// The handler needs to be looked up again as the handler cached on the arbiter may have been deleted since the last step.
|
||||
cpCollisionHandler *handler = cpSpaceLookupHandler(space, arb->a->collision_type, arb->b->collision_type);
|
||||
handler->separate(arb, space, handler->data);
|
||||
}
|
||||
|
||||
static inline struct cpArbiterThread *
|
||||
cpArbiterThreadForBody(cpArbiter *arb, cpBody *body)
|
||||
{
|
||||
return (arb->body_a == body ? &arb->thread_a : &arb->thread_b);
|
||||
}
|
||||
|
||||
void cpArbiterUnthread(cpArbiter *arb);
|
||||
|
||||
void cpArbiterUpdate(cpArbiter *arb, cpContact *contacts, int numContacts, struct cpCollisionHandler *handler, cpShape *a, cpShape *b);
|
||||
void cpArbiterPreStep(cpArbiter *arb, cpFloat dt, cpFloat bias, cpFloat slop);
|
||||
void cpArbiterApplyCachedImpulse(cpArbiter *arb, cpFloat dt_coef);
|
||||
void cpArbiterApplyImpulse(cpArbiter *arb);
|
||||
|
|
@ -1,222 +0,0 @@
|
|||
#include <stdint.h>
|
||||
#include <float.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include "TargetConditionals.h"
|
||||
#endif
|
||||
|
||||
#if ((TARGET_OS_IPHONE == 1) || (TARGET_OS_MAC == 1)) && (!defined CP_USE_CGPOINTS)
|
||||
#define CP_USE_CGPOINTS 1
|
||||
#endif
|
||||
|
||||
#if CP_USE_CGPOINTS == 1
|
||||
#if TARGET_OS_IPHONE
|
||||
#import <CoreGraphics/CGGeometry.h>
|
||||
#elif TARGET_OS_MAC
|
||||
#include <ApplicationServices/ApplicationServices.h>
|
||||
#endif
|
||||
|
||||
#if defined(__LP64__) && __LP64__
|
||||
#define CP_USE_DOUBLES 1
|
||||
#else
|
||||
#define CP_USE_DOUBLES 0
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef CP_USE_DOUBLES
|
||||
// use doubles by default for higher precision
|
||||
#define CP_USE_DOUBLES 1
|
||||
#endif
|
||||
|
||||
/// @defgroup basicTypes Basic Types
|
||||
/// Most of these types can be configured at compile time.
|
||||
/// @{
|
||||
|
||||
#if CP_USE_DOUBLES
|
||||
/// Chipmunk's floating point type.
|
||||
/// Can be reconfigured at compile time.
|
||||
typedef double cpFloat;
|
||||
#define cpfsqrt sqrt
|
||||
#define cpfsin sin
|
||||
#define cpfcos cos
|
||||
#define cpfacos acos
|
||||
#define cpfatan2 atan2
|
||||
#define cpfmod fmod
|
||||
#define cpfexp exp
|
||||
#define cpfpow pow
|
||||
#define cpffloor floor
|
||||
#define cpfceil ceil
|
||||
#define CPFLOAT_MIN DBL_MIN
|
||||
#else
|
||||
typedef float cpFloat;
|
||||
#define cpfsqrt sqrtf
|
||||
#define cpfsin sinf
|
||||
#define cpfcos cosf
|
||||
#define cpfacos acosf
|
||||
#define cpfatan2 atan2f
|
||||
#define cpfmod fmodf
|
||||
#define cpfexp expf
|
||||
#define cpfpow powf
|
||||
#define cpffloor floorf
|
||||
#define cpfceil ceilf
|
||||
#define CPFLOAT_MIN FLT_MIN
|
||||
#endif
|
||||
|
||||
#ifndef INFINITY
|
||||
#ifdef _MSC_VER
|
||||
union MSVC_EVIL_FLOAT_HACK
|
||||
{
|
||||
unsigned __int8 Bytes[4];
|
||||
float Value;
|
||||
};
|
||||
static union MSVC_EVIL_FLOAT_HACK INFINITY_HACK = {{0x00, 0x00, 0x80, 0x7F}};
|
||||
#define INFINITY (INFINITY_HACK.Value)
|
||||
#endif
|
||||
|
||||
#ifdef __GNUC__
|
||||
#define INFINITY (__builtin_inf())
|
||||
#endif
|
||||
|
||||
#ifndef INFINITY
|
||||
#define INFINITY (1e1000)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef M_PI
|
||||
#define M_PI 3.14159265358979323846264338327950288
|
||||
#endif
|
||||
|
||||
#ifndef M_E
|
||||
#define M_E 2.71828182845904523536028747135266250
|
||||
#endif
|
||||
|
||||
|
||||
/// Return the max of two cpFloats.
|
||||
static inline cpFloat cpfmax(cpFloat a, cpFloat b)
|
||||
{
|
||||
return (a > b) ? a : b;
|
||||
}
|
||||
|
||||
/// Return the min of two cpFloats.
|
||||
static inline cpFloat cpfmin(cpFloat a, cpFloat b)
|
||||
{
|
||||
return (a < b) ? a : b;
|
||||
}
|
||||
|
||||
/// Return the absolute value of a cpFloat.
|
||||
static inline cpFloat cpfabs(cpFloat f)
|
||||
{
|
||||
return (f < 0) ? -f : f;
|
||||
}
|
||||
|
||||
/// Clamp @c f to be between @c min and @c max.
|
||||
static inline cpFloat cpfclamp(cpFloat f, cpFloat min, cpFloat max)
|
||||
{
|
||||
return cpfmin(cpfmax(f, min), max);
|
||||
}
|
||||
|
||||
/// Clamp @c f to be between 0 and 1.
|
||||
static inline cpFloat cpfclamp01(cpFloat f)
|
||||
{
|
||||
return cpfmax(0.0f, cpfmin(f, 1.0f));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// Linearly interpolate (or extrapolate) between @c f1 and @c f2 by @c t percent.
|
||||
static inline cpFloat cpflerp(cpFloat f1, cpFloat f2, cpFloat t)
|
||||
{
|
||||
return f1*(1.0f - t) + f2*t;
|
||||
}
|
||||
|
||||
/// Linearly interpolate from @c f1 to @c f2 by no more than @c d.
|
||||
static inline cpFloat cpflerpconst(cpFloat f1, cpFloat f2, cpFloat d)
|
||||
{
|
||||
return f1 + cpfclamp(f2 - f1, -d, d);
|
||||
}
|
||||
|
||||
/// Hash value type.
|
||||
typedef uintptr_t cpHashValue;
|
||||
|
||||
/// Type used internally to cache colliding object info for cpCollideShapes().
|
||||
/// Should be at least 32 bits.
|
||||
typedef uint32_t cpCollisionID;
|
||||
|
||||
// Oh C, how we love to define our own boolean types to get compiler compatibility
|
||||
/// Chipmunk's boolean type.
|
||||
#ifdef CP_BOOL_TYPE
|
||||
typedef CP_BOOL_TYPE cpBool;
|
||||
#else
|
||||
typedef int cpBool;
|
||||
#endif
|
||||
|
||||
#ifndef cpTrue
|
||||
/// true value.
|
||||
#define cpTrue 1
|
||||
#endif
|
||||
|
||||
#ifndef cpFalse
|
||||
/// false value.
|
||||
#define cpFalse 0
|
||||
#endif
|
||||
|
||||
#ifdef CP_DATA_POINTER_TYPE
|
||||
typedef CP_DATA_POINTER_TYPE cpDataPointer;
|
||||
#else
|
||||
/// Type used for user data pointers.
|
||||
typedef void * cpDataPointer;
|
||||
#endif
|
||||
|
||||
#ifdef CP_COLLISION_TYPE_TYPE
|
||||
typedef CP_COLLISION_TYPE_TYPE cpCollisionType;
|
||||
#else
|
||||
/// Type used for cpSpace.collision_type.
|
||||
typedef uintptr_t cpCollisionType;
|
||||
#endif
|
||||
|
||||
#ifdef CP_GROUP_TYPE
|
||||
typedef CP_GROUP_TYPE cpGroup;
|
||||
#else
|
||||
/// Type used for cpShape.group.
|
||||
typedef uintptr_t cpGroup;
|
||||
#endif
|
||||
|
||||
#ifdef CP_LAYERS_TYPE
|
||||
typedef CP_LAYERS_TYPE cpLayers;
|
||||
#else
|
||||
/// Type used for cpShape.layers.
|
||||
typedef unsigned int cpLayers;
|
||||
#endif
|
||||
|
||||
#ifdef CP_TIMESTAMP_TYPE
|
||||
typedef CP_TIMESTAMP_TYPE cpTimestamp;
|
||||
#else
|
||||
/// Type used for various timestamps in Chipmunk.
|
||||
typedef unsigned int cpTimestamp;
|
||||
#endif
|
||||
|
||||
#ifndef CP_NO_GROUP
|
||||
/// Value for cpShape.group signifying that a shape is in no group.
|
||||
#define CP_NO_GROUP ((cpGroup)0)
|
||||
#endif
|
||||
|
||||
#ifndef CP_ALL_LAYERS
|
||||
/// Value for cpShape.layers signifying that a shape is in every layer.
|
||||
#define CP_ALL_LAYERS (~(cpLayers)0)
|
||||
#endif
|
||||
/// @}
|
||||
|
||||
// CGPoints are structurally the same, and allow
|
||||
// easy interoperability with other Cocoa libraries
|
||||
#if CP_USE_CGPOINTS
|
||||
typedef CGPoint cpVect;
|
||||
#else
|
||||
/// Chipmunk's 2D vector type.
|
||||
/// @addtogroup cpVect
|
||||
typedef struct cpVect{cpFloat x,y;} cpVect;
|
||||
#endif
|
||||
|
||||
typedef struct cpMat2x2 {
|
||||
// Row major [[a, b][c d]]
|
||||
cpFloat a, b, c, d;
|
||||
} cpMat2x2;
|
||||
|
|
@ -1,65 +0,0 @@
|
|||
/* 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.
|
||||
*/
|
||||
|
||||
/* This header defines a number of "unsafe" operations on Chipmunk objects.
|
||||
* In this case "unsafe" is referring to operations which may reduce the
|
||||
* physical accuracy or numerical stability of the simulation, but will not
|
||||
* cause crashes.
|
||||
*
|
||||
* The prime example is mutating collision shapes. Chipmunk does not support
|
||||
* this directly. Mutating shapes using this API will caused objects in contact
|
||||
* to be pushed apart using Chipmunk's overlap solver, but not using real
|
||||
* persistent velocities. Probably not what you meant, but perhaps close enough.
|
||||
*/
|
||||
|
||||
/// @defgroup unsafe Chipmunk Unsafe Shape Operations
|
||||
/// These functions are used for mutating collision shapes.
|
||||
/// Chipmunk does not have any way to get velocity information on changing shapes,
|
||||
/// so the results will be unrealistic. You must explicity include the chipmunk_unsafe.h header to use them.
|
||||
/// @{
|
||||
|
||||
#ifndef CHIPMUNK_UNSAFE_HEADER
|
||||
#define CHIPMUNK_UNSAFE_HEADER
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// Set the radius of a circle shape.
|
||||
void cpCircleShapeSetRadius(cpShape *shape, cpFloat radius);
|
||||
/// Set the offset of a circle shape.
|
||||
void cpCircleShapeSetOffset(cpShape *shape, cpVect offset);
|
||||
|
||||
/// Set the endpoints of a segment shape.
|
||||
void cpSegmentShapeSetEndpoints(cpShape *shape, cpVect a, cpVect b);
|
||||
/// Set the radius of a segment shape.
|
||||
void cpSegmentShapeSetRadius(cpShape *shape, cpFloat radius);
|
||||
|
||||
/// Set the vertexes of a poly shape.
|
||||
void cpPolyShapeSetVerts(cpShape *shape, int numVerts, cpVect *verts, cpVect offset);
|
||||
/// Set the radius of a poly shape.
|
||||
void cpPolyShapeSetRadius(cpShape *shape, cpFloat radius);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
/// @}
|
||||
|
|
@ -1,161 +0,0 @@
|
|||
/* 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 cpConstraint cpConstraint
|
||||
/// @{
|
||||
|
||||
typedef struct cpConstraintClass cpConstraintClass;
|
||||
|
||||
typedef void (*cpConstraintPreStepImpl)(cpConstraint *constraint, cpFloat dt);
|
||||
typedef void (*cpConstraintApplyCachedImpulseImpl)(cpConstraint *constraint, cpFloat dt_coef);
|
||||
typedef void (*cpConstraintApplyImpulseImpl)(cpConstraint *constraint, cpFloat dt);
|
||||
typedef cpFloat (*cpConstraintGetImpulseImpl)(cpConstraint *constraint);
|
||||
|
||||
/// @private
|
||||
struct cpConstraintClass {
|
||||
cpConstraintPreStepImpl preStep;
|
||||
cpConstraintApplyCachedImpulseImpl applyCachedImpulse;
|
||||
cpConstraintApplyImpulseImpl applyImpulse;
|
||||
cpConstraintGetImpulseImpl getImpulse;
|
||||
};
|
||||
|
||||
/// Callback function type that gets called before solving a joint.
|
||||
typedef void (*cpConstraintPreSolveFunc)(cpConstraint *constraint, cpSpace *space);
|
||||
/// Callback function type that gets called after solving a joint.
|
||||
typedef void (*cpConstraintPostSolveFunc)(cpConstraint *constraint, cpSpace *space);
|
||||
|
||||
|
||||
/// Opaque cpConstraint struct.
|
||||
struct cpConstraint {
|
||||
CP_PRIVATE(const cpConstraintClass *klass);
|
||||
|
||||
/// The first body connected to this constraint.
|
||||
cpBody *a;
|
||||
/// The second body connected to this constraint.
|
||||
cpBody *b;
|
||||
|
||||
CP_PRIVATE(cpSpace *space);
|
||||
|
||||
CP_PRIVATE(cpConstraint *next_a);
|
||||
CP_PRIVATE(cpConstraint *next_b);
|
||||
|
||||
/// The maximum force that this constraint is allowed to use.
|
||||
/// Defaults to infinity.
|
||||
cpFloat maxForce;
|
||||
/// The rate at which joint error is corrected.
|
||||
/// Defaults to pow(1.0 - 0.1, 60.0) meaning that it will
|
||||
/// correct 10% of the error every 1/60th of a second.
|
||||
cpFloat errorBias;
|
||||
/// The maximum rate at which joint error is corrected.
|
||||
/// Defaults to infinity.
|
||||
cpFloat maxBias;
|
||||
|
||||
/// Function called before the solver runs.
|
||||
/// Animate your joint anchors, update your motor torque, etc.
|
||||
cpConstraintPreSolveFunc preSolve;
|
||||
|
||||
/// Function called after the solver runs.
|
||||
/// Use the applied impulse to perform effects like breakable joints.
|
||||
cpConstraintPostSolveFunc postSolve;
|
||||
|
||||
/// User definable data pointer.
|
||||
/// Generally this points to your the game object class so you can access it
|
||||
/// when given a cpConstraint reference in a callback.
|
||||
cpDataPointer data;
|
||||
};
|
||||
|
||||
/// Destroy a constraint.
|
||||
void cpConstraintDestroy(cpConstraint *constraint);
|
||||
/// Destroy and free a constraint.
|
||||
void cpConstraintFree(cpConstraint *constraint);
|
||||
|
||||
/// @private
|
||||
static inline void cpConstraintActivateBodies(cpConstraint *constraint)
|
||||
{
|
||||
cpBody *a = constraint->a; if(a) cpBodyActivate(a);
|
||||
cpBody *b = constraint->b; if(b) cpBodyActivate(b);
|
||||
}
|
||||
|
||||
/// @private
|
||||
#define CP_DefineConstraintStructGetter(type, member, name) \
|
||||
static inline type cpConstraint##Get##name(const cpConstraint *constraint){return constraint->member;}
|
||||
|
||||
/// @private
|
||||
#define CP_DefineConstraintStructSetter(type, member, name) \
|
||||
static inline void cpConstraint##Set##name(cpConstraint *constraint, type value){ \
|
||||
cpConstraintActivateBodies(constraint); \
|
||||
constraint->member = value; \
|
||||
}
|
||||
|
||||
/// @private
|
||||
#define CP_DefineConstraintStructProperty(type, member, name) \
|
||||
CP_DefineConstraintStructGetter(type, member, name) \
|
||||
CP_DefineConstraintStructSetter(type, member, name)
|
||||
|
||||
CP_DefineConstraintStructGetter(cpSpace*, CP_PRIVATE(space), Space)
|
||||
|
||||
CP_DefineConstraintStructGetter(cpBody*, a, A)
|
||||
CP_DefineConstraintStructGetter(cpBody*, b, B)
|
||||
CP_DefineConstraintStructProperty(cpFloat, maxForce, MaxForce)
|
||||
CP_DefineConstraintStructProperty(cpFloat, errorBias, ErrorBias)
|
||||
CP_DefineConstraintStructProperty(cpFloat, maxBias, MaxBias)
|
||||
CP_DefineConstraintStructProperty(cpConstraintPreSolveFunc, preSolve, PreSolveFunc)
|
||||
CP_DefineConstraintStructProperty(cpConstraintPostSolveFunc, postSolve, PostSolveFunc)
|
||||
CP_DefineConstraintStructProperty(cpDataPointer, data, UserData)
|
||||
|
||||
// Get the last impulse applied by this constraint.
|
||||
static inline cpFloat cpConstraintGetImpulse(cpConstraint *constraint)
|
||||
{
|
||||
return constraint->CP_PRIVATE(klass)->getImpulse(constraint);
|
||||
}
|
||||
|
||||
/// @}
|
||||
|
||||
#define cpConstraintCheckCast(constraint, struct) \
|
||||
cpAssertHard(constraint->CP_PRIVATE(klass) == struct##GetClass(), "Constraint is not a "#struct)
|
||||
|
||||
#define CP_DefineConstraintGetter(struct, type, member, name) \
|
||||
static inline type struct##Get##name(const cpConstraint *constraint){ \
|
||||
cpConstraintCheckCast(constraint, struct); \
|
||||
return ((struct *)constraint)->member; \
|
||||
}
|
||||
|
||||
#define CP_DefineConstraintSetter(struct, type, member, name) \
|
||||
static inline void struct##Set##name(cpConstraint *constraint, type value){ \
|
||||
cpConstraintCheckCast(constraint, struct); \
|
||||
cpConstraintActivateBodies(constraint); \
|
||||
((struct *)constraint)->member = value; \
|
||||
}
|
||||
|
||||
#define CP_DefineConstraintProperty(struct, type, member, name) \
|
||||
CP_DefineConstraintGetter(struct, type, member, name) \
|
||||
CP_DefineConstraintSetter(struct, type, member, name)
|
||||
|
||||
#include "cpPinJoint.h"
|
||||
#include "cpSlideJoint.h"
|
||||
#include "cpPivotJoint.h"
|
||||
#include "cpGrooveJoint.h"
|
||||
#include "cpDampedSpring.h"
|
||||
#include "cpDampedRotarySpring.h"
|
||||
#include "cpRotaryLimitJoint.h"
|
||||
#include "cpRatchetJoint.h"
|
||||
#include "cpGearJoint.h"
|
||||
#include "cpSimpleMotor.h"
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
/* 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 cpDampedRotarySpring cpDampedRotarySpring
|
||||
/// @{
|
||||
|
||||
typedef cpFloat (*cpDampedRotarySpringTorqueFunc)(struct cpConstraint *spring, cpFloat relativeAngle);
|
||||
|
||||
const cpConstraintClass *cpDampedRotarySpringGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpDampedRotarySpring {
|
||||
cpConstraint constraint;
|
||||
cpFloat restAngle;
|
||||
cpFloat stiffness;
|
||||
cpFloat damping;
|
||||
cpDampedRotarySpringTorqueFunc springTorqueFunc;
|
||||
|
||||
cpFloat target_wrn;
|
||||
cpFloat w_coef;
|
||||
|
||||
cpFloat iSum;
|
||||
cpFloat jAcc;
|
||||
} cpDampedRotarySpring;
|
||||
|
||||
/// Allocate a damped rotary spring.
|
||||
cpDampedRotarySpring* cpDampedRotarySpringAlloc(void);
|
||||
/// Initialize a damped rotary spring.
|
||||
cpDampedRotarySpring* cpDampedRotarySpringInit(cpDampedRotarySpring *joint, cpBody *a, cpBody *b, cpFloat restAngle, cpFloat stiffness, cpFloat damping);
|
||||
/// Allocate and initialize a damped rotary spring.
|
||||
cpConstraint* cpDampedRotarySpringNew(cpBody *a, cpBody *b, cpFloat restAngle, cpFloat stiffness, cpFloat damping);
|
||||
|
||||
CP_DefineConstraintProperty(cpDampedRotarySpring, cpFloat, restAngle, RestAngle)
|
||||
CP_DefineConstraintProperty(cpDampedRotarySpring, cpFloat, stiffness, Stiffness)
|
||||
CP_DefineConstraintProperty(cpDampedRotarySpring, cpFloat, damping, Damping)
|
||||
CP_DefineConstraintProperty(cpDampedRotarySpring, cpDampedRotarySpringTorqueFunc, springTorqueFunc, SpringTorqueFunc)
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,64 +0,0 @@
|
|||
/* 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 cpDampedSpring cpDampedSpring
|
||||
/// @{
|
||||
|
||||
typedef struct cpDampedSpring cpDampedSpring;
|
||||
|
||||
typedef cpFloat (*cpDampedSpringForceFunc)(cpConstraint *spring, cpFloat dist);
|
||||
|
||||
const cpConstraintClass *cpDampedSpringGetClass(void);
|
||||
|
||||
/// @private
|
||||
struct cpDampedSpring {
|
||||
cpConstraint constraint;
|
||||
cpVect anchr1, anchr2;
|
||||
cpFloat restLength;
|
||||
cpFloat stiffness;
|
||||
cpFloat damping;
|
||||
cpDampedSpringForceFunc springForceFunc;
|
||||
|
||||
cpFloat target_vrn;
|
||||
cpFloat v_coef;
|
||||
|
||||
cpVect r1, r2;
|
||||
cpFloat nMass;
|
||||
cpVect n;
|
||||
|
||||
cpFloat jAcc;
|
||||
};
|
||||
|
||||
/// Allocate a damped spring.
|
||||
cpDampedSpring* cpDampedSpringAlloc(void);
|
||||
/// Initialize a damped spring.
|
||||
cpDampedSpring* cpDampedSpringInit(cpDampedSpring *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat restLength, cpFloat stiffness, cpFloat damping);
|
||||
/// Allocate and initialize a damped spring.
|
||||
cpConstraint* cpDampedSpringNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat restLength, cpFloat stiffness, cpFloat damping);
|
||||
|
||||
CP_DefineConstraintProperty(cpDampedSpring, cpVect, anchr1, Anchr1)
|
||||
CP_DefineConstraintProperty(cpDampedSpring, cpVect, anchr2, Anchr2)
|
||||
CP_DefineConstraintProperty(cpDampedSpring, cpFloat, restLength, RestLength)
|
||||
CP_DefineConstraintProperty(cpDampedSpring, cpFloat, stiffness, Stiffness)
|
||||
CP_DefineConstraintProperty(cpDampedSpring, cpFloat, damping, Damping)
|
||||
CP_DefineConstraintProperty(cpDampedSpring, cpDampedSpringForceFunc, springForceFunc, SpringForceFunc)
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
/* 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 cpGearJoint cpGearJoint
|
||||
/// @{
|
||||
|
||||
const cpConstraintClass *cpGearJointGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpGearJoint {
|
||||
cpConstraint constraint;
|
||||
cpFloat phase, ratio;
|
||||
cpFloat ratio_inv;
|
||||
|
||||
cpFloat iSum;
|
||||
|
||||
cpFloat bias;
|
||||
cpFloat jAcc;
|
||||
} cpGearJoint;
|
||||
|
||||
/// Allocate a gear joint.
|
||||
cpGearJoint* cpGearJointAlloc(void);
|
||||
/// Initialize a gear joint.
|
||||
cpGearJoint* cpGearJointInit(cpGearJoint *joint, cpBody *a, cpBody *b, cpFloat phase, cpFloat ratio);
|
||||
/// Allocate and initialize a gear joint.
|
||||
cpConstraint* cpGearJointNew(cpBody *a, cpBody *b, cpFloat phase, cpFloat ratio);
|
||||
|
||||
CP_DefineConstraintProperty(cpGearJoint, cpFloat, phase, Phase)
|
||||
CP_DefineConstraintGetter(cpGearJoint, cpFloat, ratio, Ratio)
|
||||
/// Set the ratio of a gear joint.
|
||||
void cpGearJointSetRatio(cpConstraint *constraint, cpFloat value);
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,57 +0,0 @@
|
|||
/* 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 cpGrooveJoint cpGrooveJoint
|
||||
/// @{
|
||||
|
||||
const cpConstraintClass *cpGrooveJointGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpGrooveJoint {
|
||||
cpConstraint constraint;
|
||||
cpVect grv_n, grv_a, grv_b;
|
||||
cpVect anchr2;
|
||||
|
||||
cpVect grv_tn;
|
||||
cpFloat clamp;
|
||||
cpVect r1, r2;
|
||||
cpMat2x2 k;
|
||||
|
||||
cpVect jAcc;
|
||||
cpVect bias;
|
||||
} cpGrooveJoint;
|
||||
|
||||
/// Allocate a groove joint.
|
||||
cpGrooveJoint* cpGrooveJointAlloc(void);
|
||||
/// Initialize a groove joint.
|
||||
cpGrooveJoint* cpGrooveJointInit(cpGrooveJoint *joint, cpBody *a, cpBody *b, cpVect groove_a, cpVect groove_b, cpVect anchr2);
|
||||
/// Allocate and initialize a groove joint.
|
||||
cpConstraint* cpGrooveJointNew(cpBody *a, cpBody *b, cpVect groove_a, cpVect groove_b, cpVect anchr2);
|
||||
|
||||
CP_DefineConstraintGetter(cpGrooveJoint, cpVect, grv_a, GrooveA)
|
||||
/// Set endpoint a of a groove joint's groove
|
||||
void cpGrooveJointSetGrooveA(cpConstraint *constraint, cpVect value);
|
||||
CP_DefineConstraintGetter(cpGrooveJoint, cpVect, grv_b, GrooveB)
|
||||
/// Set endpoint b of a groove joint's groove
|
||||
void cpGrooveJointSetGrooveB(cpConstraint *constraint, cpVect value);
|
||||
CP_DefineConstraintProperty(cpGrooveJoint, cpVect, anchr2, Anchr2)
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,52 +0,0 @@
|
|||
/* 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 cpPinJoint cpPinJoint
|
||||
/// @{
|
||||
|
||||
const cpConstraintClass *cpPinJointGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpPinJoint {
|
||||
cpConstraint constraint;
|
||||
cpVect anchr1, anchr2;
|
||||
cpFloat dist;
|
||||
|
||||
cpVect r1, r2;
|
||||
cpVect n;
|
||||
cpFloat nMass;
|
||||
|
||||
cpFloat jnAcc;
|
||||
cpFloat bias;
|
||||
} cpPinJoint;
|
||||
|
||||
/// Allocate a pin joint.
|
||||
cpPinJoint* cpPinJointAlloc(void);
|
||||
/// Initialize a pin joint.
|
||||
cpPinJoint* cpPinJointInit(cpPinJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2);
|
||||
/// Allocate and initialize a pin joint.
|
||||
cpConstraint* cpPinJointNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2);
|
||||
|
||||
CP_DefineConstraintProperty(cpPinJoint, cpVect, anchr1, Anchr1)
|
||||
CP_DefineConstraintProperty(cpPinJoint, cpVect, anchr2, Anchr2)
|
||||
CP_DefineConstraintProperty(cpPinJoint, cpFloat, dist, Dist)
|
||||
|
||||
///@}
|
||||
|
|
@ -1,51 +0,0 @@
|
|||
/* 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 cpPivotJoint cpPivotJoint
|
||||
/// @{
|
||||
|
||||
const cpConstraintClass *cpPivotJointGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpPivotJoint {
|
||||
cpConstraint constraint;
|
||||
cpVect anchr1, anchr2;
|
||||
|
||||
cpVect r1, r2;
|
||||
cpMat2x2 k;
|
||||
|
||||
cpVect jAcc;
|
||||
cpVect bias;
|
||||
} cpPivotJoint;
|
||||
|
||||
/// Allocate a pivot joint
|
||||
cpPivotJoint* cpPivotJointAlloc(void);
|
||||
/// Initialize a pivot joint.
|
||||
cpPivotJoint* cpPivotJointInit(cpPivotJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2);
|
||||
/// Allocate and initialize a pivot joint.
|
||||
cpConstraint* cpPivotJointNew(cpBody *a, cpBody *b, cpVect pivot);
|
||||
/// Allocate and initialize a pivot joint with specific anchors.
|
||||
cpConstraint* cpPivotJointNew2(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2);
|
||||
|
||||
CP_DefineConstraintProperty(cpPivotJoint, cpVect, anchr1, Anchr1)
|
||||
CP_DefineConstraintProperty(cpPivotJoint, cpVect, anchr2, Anchr2)
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
/* 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 cpRatchetJoint cpRatchetJoint
|
||||
/// @{
|
||||
|
||||
const cpConstraintClass *cpRatchetJointGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpRatchetJoint {
|
||||
cpConstraint constraint;
|
||||
cpFloat angle, phase, ratchet;
|
||||
|
||||
cpFloat iSum;
|
||||
|
||||
cpFloat bias;
|
||||
cpFloat jAcc;
|
||||
} cpRatchetJoint;
|
||||
|
||||
/// Allocate a ratchet joint.
|
||||
cpRatchetJoint* cpRatchetJointAlloc(void);
|
||||
/// Initialize a ratched joint.
|
||||
cpRatchetJoint* cpRatchetJointInit(cpRatchetJoint *joint, cpBody *a, cpBody *b, cpFloat phase, cpFloat ratchet);
|
||||
/// Allocate and initialize a ratchet joint.
|
||||
cpConstraint* cpRatchetJointNew(cpBody *a, cpBody *b, cpFloat phase, cpFloat ratchet);
|
||||
|
||||
CP_DefineConstraintProperty(cpRatchetJoint, cpFloat, angle, Angle)
|
||||
CP_DefineConstraintProperty(cpRatchetJoint, cpFloat, phase, Phase)
|
||||
CP_DefineConstraintProperty(cpRatchetJoint, cpFloat, ratchet, Ratchet)
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
/* 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 cpRotaryLimitJoint cpRotaryLimitJoint
|
||||
/// @{
|
||||
|
||||
const cpConstraintClass *cpRotaryLimitJointGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpRotaryLimitJoint {
|
||||
cpConstraint constraint;
|
||||
cpFloat min, max;
|
||||
|
||||
cpFloat iSum;
|
||||
|
||||
cpFloat bias;
|
||||
cpFloat jAcc;
|
||||
} cpRotaryLimitJoint;
|
||||
|
||||
/// Allocate a damped rotary limit joint.
|
||||
cpRotaryLimitJoint* cpRotaryLimitJointAlloc(void);
|
||||
/// Initialize a damped rotary limit joint.
|
||||
cpRotaryLimitJoint* cpRotaryLimitJointInit(cpRotaryLimitJoint *joint, cpBody *a, cpBody *b, cpFloat min, cpFloat max);
|
||||
/// Allocate and initialize a damped rotary limit joint.
|
||||
cpConstraint* cpRotaryLimitJointNew(cpBody *a, cpBody *b, cpFloat min, cpFloat max);
|
||||
|
||||
CP_DefineConstraintProperty(cpRotaryLimitJoint, cpFloat, min, Min)
|
||||
CP_DefineConstraintProperty(cpRotaryLimitJoint, cpFloat, max, Max)
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,46 +0,0 @@
|
|||
/* 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 cpSimpleMotor cpSimpleMotor
|
||||
/// @{
|
||||
|
||||
const cpConstraintClass *cpSimpleMotorGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpSimpleMotor {
|
||||
cpConstraint constraint;
|
||||
cpFloat rate;
|
||||
|
||||
cpFloat iSum;
|
||||
|
||||
cpFloat jAcc;
|
||||
} cpSimpleMotor;
|
||||
|
||||
/// Allocate a simple motor.
|
||||
cpSimpleMotor* cpSimpleMotorAlloc(void);
|
||||
/// initialize a simple motor.
|
||||
cpSimpleMotor* cpSimpleMotorInit(cpSimpleMotor *joint, cpBody *a, cpBody *b, cpFloat rate);
|
||||
/// Allocate and initialize a simple motor.
|
||||
cpConstraint* cpSimpleMotorNew(cpBody *a, cpBody *b, cpFloat rate);
|
||||
|
||||
CP_DefineConstraintProperty(cpSimpleMotor, cpFloat, rate, Rate)
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,53 +0,0 @@
|
|||
/* 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 cpSlideJoint cpSlideJoint
|
||||
/// @{
|
||||
|
||||
const cpConstraintClass *cpSlideJointGetClass(void);
|
||||
|
||||
/// @private
|
||||
typedef struct cpSlideJoint {
|
||||
cpConstraint constraint;
|
||||
cpVect anchr1, anchr2;
|
||||
cpFloat min, max;
|
||||
|
||||
cpVect r1, r2;
|
||||
cpVect n;
|
||||
cpFloat nMass;
|
||||
|
||||
cpFloat jnAcc;
|
||||
cpFloat bias;
|
||||
} cpSlideJoint;
|
||||
|
||||
/// Allocate a slide joint.
|
||||
cpSlideJoint* cpSlideJointAlloc(void);
|
||||
/// Initialize a slide joint.
|
||||
cpSlideJoint* cpSlideJointInit(cpSlideJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max);
|
||||
/// Allocate and initialize a slide joint.
|
||||
cpConstraint* cpSlideJointNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max);
|
||||
|
||||
CP_DefineConstraintProperty(cpSlideJoint, cpVect, anchr1, Anchr1)
|
||||
CP_DefineConstraintProperty(cpSlideJoint, cpVect, anchr2, Anchr2)
|
||||
CP_DefineConstraintProperty(cpSlideJoint, cpFloat, min, Min)
|
||||
CP_DefineConstraintProperty(cpSlideJoint, cpFloat, max, Max)
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,126 +0,0 @@
|
|||
/* 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.
|
||||
*/
|
||||
|
||||
// These are utility routines to use when creating custom constraints.
|
||||
// I'm not sure if this should be part of the private API or not.
|
||||
// I should probably clean up the naming conventions if it is...
|
||||
|
||||
#define CP_DefineClassGetter(t) const cpConstraintClass * t##GetClass(void){return (cpConstraintClass *)&klass;}
|
||||
|
||||
void cpConstraintInit(cpConstraint *constraint, const cpConstraintClass *klass, cpBody *a, cpBody *b);
|
||||
|
||||
static inline cpVect
|
||||
relative_velocity(cpBody *a, cpBody *b, cpVect r1, cpVect r2){
|
||||
cpVect v1_sum = cpvadd(a->v, cpvmult(cpvperp(r1), a->w));
|
||||
cpVect v2_sum = cpvadd(b->v, cpvmult(cpvperp(r2), b->w));
|
||||
|
||||
return cpvsub(v2_sum, v1_sum);
|
||||
}
|
||||
|
||||
static inline cpFloat
|
||||
normal_relative_velocity(cpBody *a, cpBody *b, cpVect r1, cpVect r2, cpVect n){
|
||||
return cpvdot(relative_velocity(a, b, r1, r2), n);
|
||||
}
|
||||
|
||||
static inline void
|
||||
apply_impulse(cpBody *body, cpVect j, cpVect r){
|
||||
body->v = cpvadd(body->v, cpvmult(j, body->m_inv));
|
||||
body->w += body->i_inv*cpvcross(r, j);
|
||||
}
|
||||
|
||||
static inline void
|
||||
apply_impulses(cpBody *a , cpBody *b, cpVect r1, cpVect r2, cpVect j)
|
||||
{
|
||||
apply_impulse(a, cpvneg(j), r1);
|
||||
apply_impulse(b, j, r2);
|
||||
}
|
||||
|
||||
static inline void
|
||||
apply_bias_impulse(cpBody *body, cpVect j, cpVect r)
|
||||
{
|
||||
body->CP_PRIVATE(v_bias) = cpvadd(body->CP_PRIVATE(v_bias), cpvmult(j, body->m_inv));
|
||||
body->CP_PRIVATE(w_bias) += body->i_inv*cpvcross(r, j);
|
||||
}
|
||||
|
||||
static inline void
|
||||
apply_bias_impulses(cpBody *a , cpBody *b, cpVect r1, cpVect r2, cpVect j)
|
||||
{
|
||||
apply_bias_impulse(a, cpvneg(j), r1);
|
||||
apply_bias_impulse(b, j, r2);
|
||||
}
|
||||
|
||||
static inline cpFloat
|
||||
k_scalar_body(cpBody *body, cpVect r, cpVect n)
|
||||
{
|
||||
cpFloat rcn = cpvcross(r, n);
|
||||
return body->m_inv + body->i_inv*rcn*rcn;
|
||||
}
|
||||
|
||||
static inline cpFloat
|
||||
k_scalar(cpBody *a, cpBody *b, cpVect r1, cpVect r2, cpVect n)
|
||||
{
|
||||
cpFloat value = k_scalar_body(a, r1, n) + k_scalar_body(b, r2, n);
|
||||
cpAssertSoft(value != 0.0, "Unsolvable collision or constraint.");
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static inline cpMat2x2
|
||||
k_tensor(cpBody *a, cpBody *b, cpVect r1, cpVect r2)
|
||||
{
|
||||
cpFloat m_sum = a->m_inv + b->m_inv;
|
||||
|
||||
// start with Identity*m_sum
|
||||
cpFloat k11 = m_sum, k12 = 0.0f;
|
||||
cpFloat k21 = 0.0f, k22 = m_sum;
|
||||
|
||||
// add the influence from r1
|
||||
cpFloat a_i_inv = a->i_inv;
|
||||
cpFloat r1xsq = r1.x * r1.x * a_i_inv;
|
||||
cpFloat r1ysq = r1.y * r1.y * a_i_inv;
|
||||
cpFloat r1nxy = -r1.x * r1.y * a_i_inv;
|
||||
k11 += r1ysq; k12 += r1nxy;
|
||||
k21 += r1nxy; k22 += r1xsq;
|
||||
|
||||
// add the influnce from r2
|
||||
cpFloat b_i_inv = b->i_inv;
|
||||
cpFloat r2xsq = r2.x * r2.x * b_i_inv;
|
||||
cpFloat r2ysq = r2.y * r2.y * b_i_inv;
|
||||
cpFloat r2nxy = -r2.x * r2.y * b_i_inv;
|
||||
k11 += r2ysq; k12 += r2nxy;
|
||||
k21 += r2nxy; k22 += r2xsq;
|
||||
|
||||
// invert
|
||||
cpFloat det = k11*k22 - k12*k21;
|
||||
cpAssertSoft(det != 0.0, "Unsolvable constraint.");
|
||||
|
||||
cpFloat det_inv = 1.0f/det;
|
||||
return cpMat2x2New(
|
||||
k22*det_inv, -k12*det_inv,
|
||||
-k21*det_inv, k11*det_inv
|
||||
);
|
||||
}
|
||||
|
||||
static inline cpFloat
|
||||
bias_coef(cpFloat errorBias, cpFloat dt)
|
||||
{
|
||||
return 1.0f - cpfpow(errorBias, dt);
|
||||
}
|
||||
|
|
@ -1,207 +0,0 @@
|
|||
/* 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 2
|
||||
|
||||
/// @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)
|
||||
|
||||
// Get the relative surface velocity of the two shapes in contact.
|
||||
cpVect cpArbiterGetSurfaceVelocity(cpArbiter *arb);
|
||||
|
||||
// Override the relative surface velocity of the two shapes in contact.
|
||||
// By default this is calculated to be the difference of the two
|
||||
// surface velocities clamped to the tangent plane.
|
||||
void cpArbiterSetSurfaceVelocity(cpArbiter *arb, cpVect vr);
|
||||
|
||||
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);
|
||||
|
||||
/// Replace the contact point set for an arbiter.
|
||||
/// This can be a very powerful feature, but use it with caution!
|
||||
void cpArbiterSetContactPointSet(cpArbiter *arb, cpContactPointSet *set);
|
||||
|
||||
/// 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);
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,143 +0,0 @@
|
|||
/* 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 cpBBB cpBB
|
||||
/// Chipmunk's axis-aligned 2D bounding box type along with a few handy routines.
|
||||
/// @{
|
||||
|
||||
/// Chipmunk's axis-aligned 2D bounding box type. (left, bottom, right, top)
|
||||
typedef struct cpBB{
|
||||
cpFloat l, b, r ,t;
|
||||
} cpBB;
|
||||
|
||||
/// Convenience constructor for cpBB structs.
|
||||
static inline cpBB cpBBNew(const cpFloat l, const cpFloat b, const cpFloat r, const cpFloat t)
|
||||
{
|
||||
cpBB bb = {l, b, r, t};
|
||||
return bb;
|
||||
}
|
||||
|
||||
/// Constructs a cpBB for a circle with the given position and radius.
|
||||
static inline cpBB cpBBNewForCircle(const cpVect p, const cpFloat r)
|
||||
{
|
||||
return cpBBNew(p.x - r, p.y - r, p.x + r, p.y + r);
|
||||
}
|
||||
|
||||
/// Returns true if @c a and @c b intersect.
|
||||
static inline cpBool cpBBIntersects(const cpBB a, const cpBB b)
|
||||
{
|
||||
return (a.l <= b.r && b.l <= a.r && a.b <= b.t && b.b <= a.t);
|
||||
}
|
||||
|
||||
/// Returns true if @c other lies completely within @c bb.
|
||||
static inline cpBool cpBBContainsBB(const cpBB bb, const cpBB other)
|
||||
{
|
||||
return (bb.l <= other.l && bb.r >= other.r && bb.b <= other.b && bb.t >= other.t);
|
||||
}
|
||||
|
||||
/// Returns true if @c bb contains @c v.
|
||||
static inline cpBool cpBBContainsVect(const cpBB bb, const cpVect v)
|
||||
{
|
||||
return (bb.l <= v.x && bb.r >= v.x && bb.b <= v.y && bb.t >= v.y);
|
||||
}
|
||||
|
||||
/// Returns a bounding box that holds both bounding boxes.
|
||||
static inline cpBB cpBBMerge(const cpBB a, const cpBB b){
|
||||
return cpBBNew(
|
||||
cpfmin(a.l, b.l),
|
||||
cpfmin(a.b, b.b),
|
||||
cpfmax(a.r, b.r),
|
||||
cpfmax(a.t, b.t)
|
||||
);
|
||||
}
|
||||
|
||||
/// Returns a bounding box that holds both @c bb and @c v.
|
||||
static inline cpBB cpBBExpand(const cpBB bb, const cpVect v){
|
||||
return cpBBNew(
|
||||
cpfmin(bb.l, v.x),
|
||||
cpfmin(bb.b, v.y),
|
||||
cpfmax(bb.r, v.x),
|
||||
cpfmax(bb.t, v.y)
|
||||
);
|
||||
}
|
||||
|
||||
/// Returns the center of a bounding box.
|
||||
static inline cpVect
|
||||
cpBBCenter(cpBB bb)
|
||||
{
|
||||
return cpvlerp(cpv(bb.l, bb.b), cpv(bb.r, bb.t), 0.5f);
|
||||
}
|
||||
|
||||
/// Returns the area of the bounding box.
|
||||
static inline cpFloat cpBBArea(cpBB bb)
|
||||
{
|
||||
return (bb.r - bb.l)*(bb.t - bb.b);
|
||||
}
|
||||
|
||||
/// Merges @c a and @c b and returns the area of the merged bounding box.
|
||||
static inline cpFloat cpBBMergedArea(cpBB a, cpBB b)
|
||||
{
|
||||
return (cpfmax(a.r, b.r) - cpfmin(a.l, b.l))*(cpfmax(a.t, b.t) - cpfmin(a.b, b.b));
|
||||
}
|
||||
|
||||
/// Returns the fraction along the segment query the cpBB is hit. Returns INFINITY if it doesn't hit.
|
||||
static inline cpFloat cpBBSegmentQuery(cpBB bb, cpVect a, cpVect b)
|
||||
{
|
||||
cpFloat idx = 1.0f/(b.x - a.x);
|
||||
cpFloat tx1 = (bb.l == a.x ? -INFINITY : (bb.l - a.x)*idx);
|
||||
cpFloat tx2 = (bb.r == a.x ? INFINITY : (bb.r - a.x)*idx);
|
||||
cpFloat txmin = cpfmin(tx1, tx2);
|
||||
cpFloat txmax = cpfmax(tx1, tx2);
|
||||
|
||||
cpFloat idy = 1.0f/(b.y - a.y);
|
||||
cpFloat ty1 = (bb.b == a.y ? -INFINITY : (bb.b - a.y)*idy);
|
||||
cpFloat ty2 = (bb.t == a.y ? INFINITY : (bb.t - a.y)*idy);
|
||||
cpFloat tymin = cpfmin(ty1, ty2);
|
||||
cpFloat tymax = cpfmax(ty1, ty2);
|
||||
|
||||
if(tymin <= txmax && txmin <= tymax){
|
||||
cpFloat min = cpfmax(txmin, tymin);
|
||||
cpFloat max = cpfmin(txmax, tymax);
|
||||
|
||||
if(0.0 <= max && min <= 1.0) return cpfmax(min, 0.0);
|
||||
}
|
||||
|
||||
return INFINITY;
|
||||
}
|
||||
|
||||
/// Return true if the bounding box intersects the line segment with ends @c a and @c b.
|
||||
static inline cpBool cpBBIntersectsSegment(cpBB bb, cpVect a, cpVect b)
|
||||
{
|
||||
return (cpBBSegmentQuery(bb, a, b) != INFINITY);
|
||||
}
|
||||
|
||||
/// Clamp a vector to a bounding box.
|
||||
static inline cpVect
|
||||
cpBBClampVect(const cpBB bb, const cpVect v)
|
||||
{
|
||||
return cpv(cpfclamp(v.x, bb.l, bb.r), cpfclamp(v.y, bb.b, bb.t));
|
||||
}
|
||||
|
||||
// TODO edge case issue
|
||||
/// Wrap a vector to a bounding box.
|
||||
cpVect cpBBWrapVect(const cpBB bb, const cpVect v); // wrap a vector to a bbox
|
||||
|
||||
///@}
|
||||
|
|
@ -1,251 +0,0 @@
|
|||
/* 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.
|
||||
/// Note: Static bodies are a subtype of rogue bodies.
|
||||
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);
|
||||
|
||||
///@}
|
||||
|
|
@ -1,81 +0,0 @@
|
|||
/* 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 cpPolyShape cpPolyShape
|
||||
/// @{
|
||||
|
||||
/// @private
|
||||
typedef struct cpSplittingPlane {
|
||||
cpVect n;
|
||||
cpFloat d;
|
||||
} cpSplittingPlane;
|
||||
|
||||
/// @private
|
||||
typedef struct cpPolyShape {
|
||||
cpShape shape;
|
||||
|
||||
int numVerts;
|
||||
cpVect *verts, *tVerts;
|
||||
cpSplittingPlane *planes, *tPlanes;
|
||||
|
||||
cpFloat r;
|
||||
} cpPolyShape;
|
||||
|
||||
/// Allocate a polygon shape.
|
||||
cpPolyShape* cpPolyShapeAlloc(void);
|
||||
/// Initialize a polygon shape.
|
||||
/// A convex hull will be created from the vertexes.
|
||||
cpPolyShape* cpPolyShapeInit(cpPolyShape *poly, cpBody *body, int numVerts, const cpVect *verts, cpVect offset);
|
||||
/// Initialize a polygon shape.
|
||||
/// A convex hull will be created from the vertexes.
|
||||
cpPolyShape* cpPolyShapeInit2(cpPolyShape *poly, cpBody *body, int numVerts, const cpVect *verts, cpVect offset, cpFloat radius);
|
||||
/// Allocate and initialize a polygon shape.
|
||||
/// A convex hull will be created from the vertexes.
|
||||
cpShape* cpPolyShapeNew(cpBody *body, int numVerts, const cpVect *verts, cpVect offset);
|
||||
/// Allocate and initialize a polygon shape.
|
||||
/// A convex hull will be created from the vertexes.
|
||||
cpShape* cpPolyShapeNew2(cpBody *body, int numVerts, const cpVect *verts, cpVect offset, cpFloat radius);
|
||||
|
||||
/// Initialize a box shaped polygon shape.
|
||||
cpPolyShape* cpBoxShapeInit(cpPolyShape *poly, cpBody *body, cpFloat width, cpFloat height);
|
||||
/// Initialize an offset box shaped polygon shape.
|
||||
cpPolyShape* cpBoxShapeInit2(cpPolyShape *poly, cpBody *body, cpBB box);
|
||||
/// Initialize an offset box shaped polygon shape.
|
||||
cpPolyShape* cpBoxShapeInit3(cpPolyShape *poly, cpBody *body, cpBB box, cpFloat radius);
|
||||
/// Allocate and initialize a box shaped polygon shape.
|
||||
cpShape* cpBoxShapeNew(cpBody *body, cpFloat width, cpFloat height);
|
||||
/// Allocate and initialize an offset box shaped polygon shape.
|
||||
cpShape* cpBoxShapeNew2(cpBody *body, cpBB box);
|
||||
/// Allocate and initialize an offset box shaped polygon shape.
|
||||
cpShape* cpBoxShapeNew3(cpBody *body, cpBB box, cpFloat radius);
|
||||
|
||||
/// Check that a set of vertexes is convex and has a clockwise winding.
|
||||
/// NOTE: Due to floating point precision issues, hulls created with cpQuickHull() are not guaranteed to validate!
|
||||
cpBool cpPolyValidate(const cpVect *verts, const int numVerts);
|
||||
|
||||
/// Get the number of verts in a polygon shape.
|
||||
int cpPolyShapeGetNumVerts(const cpShape *shape);
|
||||
/// Get the @c ith vertex of a polygon shape.
|
||||
cpVect cpPolyShapeGetVert(const cpShape *shape, int idx);
|
||||
/// Get the radius of a polygon shape.
|
||||
cpFloat cpPolyShapeGetRadius(const cpShape *shape);
|
||||
|
||||
/// @}
|
||||
|
|
@ -1,232 +0,0 @@
|
|||
/* 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 cpShape cpShape
|
||||
/// The cpShape struct defines the shape of a rigid body.
|
||||
/// @{
|
||||
|
||||
typedef struct cpShapeClass cpShapeClass;
|
||||
|
||||
/// Nearest point query info struct.
|
||||
typedef struct cpNearestPointQueryInfo {
|
||||
/// The nearest shape, NULL if no shape was within range.
|
||||
cpShape *shape;
|
||||
/// The closest point on the shape's surface. (in world space coordinates)
|
||||
cpVect p;
|
||||
/// The distance to the point. The distance is negative if the point is inside the shape.
|
||||
cpFloat d;
|
||||
/// The gradient of the signed distance function.
|
||||
/// The same as info.p/info.d, but accurate even for very small values of info.d.
|
||||
cpVect g;
|
||||
} cpNearestPointQueryInfo;
|
||||
|
||||
/// Segment query info struct.
|
||||
typedef struct cpSegmentQueryInfo {
|
||||
/// The shape that was hit, NULL if no collision occured.
|
||||
cpShape *shape;
|
||||
/// The normalized distance along the query segment in the range [0, 1].
|
||||
cpFloat t;
|
||||
/// The normal of the surface hit.
|
||||
cpVect n;
|
||||
} cpSegmentQueryInfo;
|
||||
|
||||
/// @private
|
||||
typedef enum cpShapeType{
|
||||
CP_CIRCLE_SHAPE,
|
||||
CP_SEGMENT_SHAPE,
|
||||
CP_POLY_SHAPE,
|
||||
CP_NUM_SHAPES
|
||||
} cpShapeType;
|
||||
|
||||
typedef cpBB (*cpShapeCacheDataImpl)(cpShape *shape, cpVect p, cpVect rot);
|
||||
typedef void (*cpShapeDestroyImpl)(cpShape *shape);
|
||||
typedef void (*cpShapeNearestPointQueryImpl)(cpShape *shape, cpVect p, cpNearestPointQueryInfo *info);
|
||||
typedef void (*cpShapeSegmentQueryImpl)(cpShape *shape, cpVect a, cpVect b, cpSegmentQueryInfo *info);
|
||||
|
||||
/// @private
|
||||
struct cpShapeClass {
|
||||
cpShapeType type;
|
||||
|
||||
cpShapeCacheDataImpl cacheData;
|
||||
cpShapeDestroyImpl destroy;
|
||||
cpShapeNearestPointQueryImpl nearestPointQuery;
|
||||
cpShapeSegmentQueryImpl segmentQuery;
|
||||
};
|
||||
|
||||
/// Opaque collision shape struct.
|
||||
struct cpShape {
|
||||
CP_PRIVATE(const cpShapeClass *klass);
|
||||
|
||||
/// The rigid body this collision shape is attached to.
|
||||
cpBody *body;
|
||||
|
||||
/// The current bounding box of the shape.
|
||||
cpBB bb;
|
||||
|
||||
/// Sensor flag.
|
||||
/// Sensor shapes call collision callbacks but don't produce collisions.
|
||||
cpBool sensor;
|
||||
|
||||
/// Coefficient of restitution. (elasticity)
|
||||
cpFloat e;
|
||||
/// Coefficient of friction.
|
||||
cpFloat u;
|
||||
/// Surface velocity used when solving for friction.
|
||||
cpVect surface_v;
|
||||
|
||||
/// User definable data pointer.
|
||||
/// Generally this points to your the game object class so you can access it
|
||||
/// when given a cpShape reference in a callback.
|
||||
cpDataPointer data;
|
||||
|
||||
/// Collision type of this shape used when picking collision handlers.
|
||||
cpCollisionType collision_type;
|
||||
/// Group of this shape. Shapes in the same group don't collide.
|
||||
cpGroup group;
|
||||
// Layer bitmask for this shape. Shapes only collide if the bitwise and of their layers is non-zero.
|
||||
cpLayers layers;
|
||||
|
||||
CP_PRIVATE(cpSpace *space);
|
||||
|
||||
CP_PRIVATE(cpShape *next);
|
||||
CP_PRIVATE(cpShape *prev);
|
||||
|
||||
CP_PRIVATE(cpHashValue hashid);
|
||||
};
|
||||
|
||||
/// Destroy a shape.
|
||||
void cpShapeDestroy(cpShape *shape);
|
||||
/// Destroy and Free a shape.
|
||||
void cpShapeFree(cpShape *shape);
|
||||
|
||||
/// Update, cache and return the bounding box of a shape based on the body it's attached to.
|
||||
cpBB cpShapeCacheBB(cpShape *shape);
|
||||
/// Update, cache and return the bounding box of a shape with an explicit transformation.
|
||||
cpBB cpShapeUpdate(cpShape *shape, cpVect pos, cpVect rot);
|
||||
|
||||
/// Test if a point lies within a shape.
|
||||
cpBool cpShapePointQuery(cpShape *shape, cpVect p);
|
||||
|
||||
/// Perform a nearest point query. It finds the closest point on the surface of shape to a specific point.
|
||||
/// The value returned is the distance between the points. A negative distance means the point is inside the shape.
|
||||
cpFloat cpShapeNearestPointQuery(cpShape *shape, cpVect p, cpNearestPointQueryInfo *out);
|
||||
|
||||
/// Perform a segment query against a shape. @c info must be a pointer to a valid cpSegmentQueryInfo structure.
|
||||
cpBool cpShapeSegmentQuery(cpShape *shape, cpVect a, cpVect b, cpSegmentQueryInfo *info);
|
||||
|
||||
/// Get the hit point for a segment query.
|
||||
static inline cpVect cpSegmentQueryHitPoint(const cpVect start, const cpVect end, const cpSegmentQueryInfo info)
|
||||
{
|
||||
return cpvlerp(start, end, info.t);
|
||||
}
|
||||
|
||||
/// Get the hit distance for a segment query.
|
||||
static inline cpFloat cpSegmentQueryHitDist(const cpVect start, const cpVect end, const cpSegmentQueryInfo info)
|
||||
{
|
||||
return cpvdist(start, end)*info.t;
|
||||
}
|
||||
|
||||
#define CP_DefineShapeStructGetter(type, member, name) \
|
||||
static inline type cpShapeGet##name(const cpShape *shape){return shape->member;}
|
||||
|
||||
#define CP_DefineShapeStructSetter(type, member, name, activates) \
|
||||
static inline void cpShapeSet##name(cpShape *shape, type value){ \
|
||||
if(activates && shape->body) cpBodyActivate(shape->body); \
|
||||
shape->member = value; \
|
||||
}
|
||||
|
||||
#define CP_DefineShapeStructProperty(type, member, name, activates) \
|
||||
CP_DefineShapeStructGetter(type, member, name) \
|
||||
CP_DefineShapeStructSetter(type, member, name, activates)
|
||||
|
||||
CP_DefineShapeStructGetter(cpSpace*, CP_PRIVATE(space), Space)
|
||||
|
||||
CP_DefineShapeStructGetter(cpBody*, body, Body)
|
||||
void cpShapeSetBody(cpShape *shape, cpBody *body);
|
||||
|
||||
CP_DefineShapeStructGetter(cpBB, bb, BB)
|
||||
CP_DefineShapeStructProperty(cpBool, sensor, Sensor, cpTrue)
|
||||
CP_DefineShapeStructProperty(cpFloat, e, Elasticity, cpFalse)
|
||||
CP_DefineShapeStructProperty(cpFloat, u, Friction, cpTrue)
|
||||
CP_DefineShapeStructProperty(cpVect, surface_v, SurfaceVelocity, cpTrue)
|
||||
CP_DefineShapeStructProperty(cpDataPointer, data, UserData, cpFalse)
|
||||
CP_DefineShapeStructProperty(cpCollisionType, collision_type, CollisionType, cpTrue)
|
||||
CP_DefineShapeStructProperty(cpGroup, group, Group, cpTrue)
|
||||
CP_DefineShapeStructProperty(cpLayers, layers, Layers, cpTrue)
|
||||
|
||||
/// When initializing a shape, it's hash value comes from a counter.
|
||||
/// Because the hash value may affect iteration order, you can reset the shape ID counter
|
||||
/// when recreating a space. This will make the simulation be deterministic.
|
||||
void cpResetShapeIdCounter(void);
|
||||
|
||||
#define CP_DeclareShapeGetter(struct, type, name) type struct##Get##name(const cpShape *shape)
|
||||
|
||||
/// @}
|
||||
/// @defgroup cpCircleShape cpCircleShape
|
||||
|
||||
/// @private
|
||||
typedef struct cpCircleShape {
|
||||
cpShape shape;
|
||||
|
||||
cpVect c, tc;
|
||||
cpFloat r;
|
||||
} cpCircleShape;
|
||||
|
||||
/// Allocate a circle shape.
|
||||
cpCircleShape* cpCircleShapeAlloc(void);
|
||||
/// Initialize a circle shape.
|
||||
cpCircleShape* cpCircleShapeInit(cpCircleShape *circle, cpBody *body, cpFloat radius, cpVect offset);
|
||||
/// Allocate and initialize a circle shape.
|
||||
cpShape* cpCircleShapeNew(cpBody *body, cpFloat radius, cpVect offset);
|
||||
|
||||
CP_DeclareShapeGetter(cpCircleShape, cpVect, Offset);
|
||||
CP_DeclareShapeGetter(cpCircleShape, cpFloat, Radius);
|
||||
|
||||
/// @}
|
||||
/// @defgroup cpSegmentShape cpSegmentShape
|
||||
|
||||
/// @private
|
||||
typedef struct cpSegmentShape {
|
||||
cpShape shape;
|
||||
|
||||
cpVect a, b, n;
|
||||
cpVect ta, tb, tn;
|
||||
cpFloat r;
|
||||
|
||||
cpVect a_tangent, b_tangent;
|
||||
} cpSegmentShape;
|
||||
|
||||
/// Allocate a segment shape.
|
||||
cpSegmentShape* cpSegmentShapeAlloc(void);
|
||||
/// Initialize a segment shape.
|
||||
cpSegmentShape* cpSegmentShapeInit(cpSegmentShape *seg, cpBody *body, cpVect a, cpVect b, cpFloat radius);
|
||||
/// Allocate and initialize a segment shape.
|
||||
cpShape* cpSegmentShapeNew(cpBody *body, cpVect a, cpVect b, cpFloat radius);
|
||||
|
||||
/// Let Chipmunk know about the geometry of adjacent segments to avoid colliding with endcaps.
|
||||
void cpSegmentShapeSetNeighbors(cpShape *shape, cpVect prev, cpVect next);
|
||||
|
||||
CP_DeclareShapeGetter(cpSegmentShape, cpVect, A);
|
||||
CP_DeclareShapeGetter(cpSegmentShape, cpVect, B);
|
||||
CP_DeclareShapeGetter(cpSegmentShape, cpVect, Normal);
|
||||
CP_DeclareShapeGetter(cpSegmentShape, cpFloat, Radius);
|
||||
|
||||
/// @}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue