chipmunk 4.1.0 → 5.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README +60 -0
- data/Rakefile +47 -40
- data/ext/chipmunk/chipmunk.c +39 -3
- data/ext/chipmunk/cpArbiter.c +91 -80
- data/ext/chipmunk/cpArray.c +24 -10
- data/ext/chipmunk/cpBB.c +5 -4
- data/ext/chipmunk/cpBody.c +30 -22
- data/ext/chipmunk/cpCollision.c +54 -53
- data/ext/chipmunk/cpConstraint.c +54 -0
- data/ext/chipmunk/cpDampedRotarySpring.c +106 -0
- data/ext/chipmunk/cpDampedSpring.c +117 -0
- data/ext/chipmunk/cpGearJoint.c +114 -0
- data/ext/chipmunk/cpGrooveJoint.c +138 -0
- data/ext/chipmunk/cpHashSet.c +74 -40
- data/ext/chipmunk/cpPinJoint.c +117 -0
- data/ext/chipmunk/cpPivotJoint.c +114 -0
- data/ext/chipmunk/cpPolyShape.c +117 -15
- data/ext/chipmunk/cpRatchetJoint.c +128 -0
- data/ext/chipmunk/cpRotaryLimitJoint.c +122 -0
- data/ext/chipmunk/cpShape.c +174 -18
- data/ext/chipmunk/cpSimpleMotor.c +99 -0
- data/ext/chipmunk/cpSlideJoint.c +131 -0
- data/ext/chipmunk/cpSpace.c +584 -215
- data/ext/chipmunk/cpSpaceHash.c +191 -105
- data/ext/chipmunk/cpVect.c +18 -10
- data/ext/chipmunk/extconf.rb +34 -4
- data/ext/chipmunk/{chipmunk.h → include/chipmunk/chipmunk.h} +63 -6
- data/ext/chipmunk/include/chipmunk/chipmunk_ffi.h +42 -0
- data/ext/chipmunk/include/chipmunk/chipmunk_types.h +80 -0
- data/ext/chipmunk/include/chipmunk/chipmunk_unsafe.h +54 -0
- data/ext/chipmunk/include/chipmunk/constraints/cpConstraint.h +92 -0
- data/ext/chipmunk/include/chipmunk/constraints/cpDampedRotarySpring.h +46 -0
- data/ext/chipmunk/include/chipmunk/constraints/cpDampedSpring.h +53 -0
- data/ext/chipmunk/include/chipmunk/constraints/cpGearJoint.h +41 -0
- data/ext/chipmunk/include/chipmunk/constraints/cpGrooveJoint.h +44 -0
- data/ext/chipmunk/include/chipmunk/constraints/cpPinJoint.h +43 -0
- data/ext/chipmunk/include/chipmunk/constraints/cpPivotJoint.h +42 -0
- data/ext/chipmunk/include/chipmunk/constraints/cpRatchetJoint.h +40 -0
- data/ext/chipmunk/include/chipmunk/constraints/cpRotaryLimitJoint.h +39 -0
- data/ext/chipmunk/include/chipmunk/constraints/cpSimpleMotor.h +37 -0
- data/ext/chipmunk/include/chipmunk/constraints/cpSlideJoint.h +44 -0
- data/ext/chipmunk/include/chipmunk/constraints/util.h +116 -0
- data/ext/chipmunk/{cpArbiter.h → include/chipmunk/cpArbiter.h} +66 -15
- data/ext/chipmunk/{cpArray.h → include/chipmunk/cpArray.h} +2 -1
- data/ext/chipmunk/{cpBB.h → include/chipmunk/cpBB.h} +21 -0
- data/ext/chipmunk/{cpBody.h → include/chipmunk/cpBody.h} +37 -9
- data/ext/chipmunk/{cpCollision.h → include/chipmunk/cpCollision.h} +1 -1
- data/ext/chipmunk/{cpHashSet.h → include/chipmunk/cpHashSet.h} +12 -9
- data/ext/chipmunk/{cpPolyShape.h → include/chipmunk/cpPolyShape.h} +13 -2
- data/ext/chipmunk/{cpShape.h → include/chipmunk/cpShape.h} +51 -18
- data/ext/chipmunk/include/chipmunk/cpSpace.h +180 -0
- data/ext/chipmunk/{cpSpaceHash.h → include/chipmunk/cpSpaceHash.h} +18 -9
- data/ext/chipmunk/{cpVect.h → include/chipmunk/cpVect.h} +61 -10
- data/ext/chipmunk/prime.h +32 -32
- data/ext/chipmunk/rb_chipmunk.c +125 -109
- data/ext/chipmunk/rb_chipmunk.h +96 -77
- data/ext/chipmunk/rb_cpArbiter.c +225 -0
- data/ext/chipmunk/rb_cpBB.c +174 -154
- data/ext/chipmunk/rb_cpBody.c +347 -239
- data/ext/chipmunk/rb_cpConstraint.c +346 -0
- data/ext/chipmunk/rb_cpShape.c +455 -292
- data/ext/chipmunk/rb_cpSpace.c +544 -330
- data/ext/chipmunk/rb_cpVect.c +321 -250
- data/lib/chipmunk.rb +28 -15
- data/lib/chipmunk/version.rb +3 -0
- metadata +74 -34
- data/ext/chipmunk/cpJoint.c +0 -553
- data/ext/chipmunk/cpJoint.h +0 -122
- data/ext/chipmunk/cpSpace.h +0 -120
- data/ext/chipmunk/rb_cpJoint.c +0 -136
@@ -18,6 +18,10 @@
|
|
18
18
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
19
|
* SOFTWARE.
|
20
20
|
*/
|
21
|
+
|
22
|
+
struct cpArbiter;
|
23
|
+
struct cpSpace;
|
24
|
+
struct cpCollisionHandler;
|
21
25
|
|
22
26
|
// Determines how fast penetrations resolve themselves.
|
23
27
|
extern cpFloat cp_bias_coef;
|
@@ -25,7 +29,7 @@ extern cpFloat cp_bias_coef;
|
|
25
29
|
extern cpFloat cp_collision_slop;
|
26
30
|
|
27
31
|
// Data structure for contact points.
|
28
|
-
typedef struct cpContact{
|
32
|
+
typedef struct cpContact {
|
29
33
|
// Contact point and normal.
|
30
34
|
cpVect p, n;
|
31
35
|
// Penetration distance.
|
@@ -40,46 +44,93 @@ typedef struct cpContact{
|
|
40
44
|
cpFloat bias;
|
41
45
|
|
42
46
|
// Hash value used to (mostly) uniquely identify a contact.
|
43
|
-
|
47
|
+
cpHashValue hash;
|
44
48
|
} cpContact;
|
45
49
|
|
46
50
|
// Contacts are always allocated in groups.
|
47
|
-
cpContact* cpContactInit(cpContact *con, cpVect p, cpVect n, cpFloat dist,
|
51
|
+
cpContact* cpContactInit(cpContact *con, cpVect p, cpVect n, cpFloat dist, cpHashValue hash);
|
48
52
|
|
49
53
|
// Sum the contact impulses. (Can be used after cpSpaceStep() returns)
|
50
54
|
cpVect cpContactsSumImpulses(cpContact *contacts, int numContacts);
|
51
55
|
cpVect cpContactsSumImpulsesWithFriction(cpContact *contacts, int numContacts);
|
52
56
|
|
57
|
+
typedef enum cpArbiterState {
|
58
|
+
cpArbiterStateNormal,
|
59
|
+
cpArbiterStateFirstColl,
|
60
|
+
cpArbiterStateIgnore,
|
61
|
+
} cpArbiterState;
|
62
|
+
|
53
63
|
// Data structure for tracking collisions between shapes.
|
54
|
-
typedef struct cpArbiter{
|
64
|
+
typedef struct cpArbiter {
|
55
65
|
// Information on the contact points between the objects.
|
56
66
|
int numContacts;
|
57
67
|
cpContact *contacts;
|
58
68
|
|
59
69
|
// The two shapes involved in the collision.
|
60
|
-
|
70
|
+
// These variables are NOT in the order defined by the collision handler.
|
71
|
+
cpShape *private_a, *private_b;
|
61
72
|
|
62
|
-
// Calculated
|
73
|
+
// Calculated before calling the pre-solve collision handler
|
74
|
+
// Override them with custom values if you want specialized behavior
|
75
|
+
cpFloat e;
|
63
76
|
cpFloat u;
|
64
|
-
|
77
|
+
// Used for surface_v calculations, implementation may change
|
78
|
+
cpVect surface_vr;
|
65
79
|
|
66
80
|
// Time stamp of the arbiter. (from cpSpace)
|
67
81
|
int stamp;
|
82
|
+
|
83
|
+
struct cpCollisionHandler *handler;
|
84
|
+
|
85
|
+
// Are the shapes swapped in relation to the collision handler?
|
86
|
+
char swappedColl;
|
87
|
+
char state;
|
68
88
|
} cpArbiter;
|
69
89
|
|
70
|
-
//
|
71
|
-
cpArbiter*
|
72
|
-
cpArbiter* cpArbiterInit(cpArbiter *arb, cpShape *a, cpShape *b, int stamp);
|
73
|
-
cpArbiter* cpArbiterNew(cpShape *a, cpShape *b, int stamp);
|
74
|
-
|
75
|
-
void cpArbiterDestroy(cpArbiter *arb);
|
76
|
-
void cpArbiterFree(cpArbiter *arb);
|
90
|
+
// Arbiters are allocated in large buffers by the space and don't require a destroy function
|
91
|
+
cpArbiter* cpArbiterInit(cpArbiter *arb, cpShape *a, cpShape *b);
|
77
92
|
|
78
93
|
// These functions are all intended to be used internally.
|
79
94
|
// Inject new contact points into the arbiter while preserving contact history.
|
80
|
-
void
|
95
|
+
void cpArbiterUpdate(cpArbiter *arb, cpContact *contacts, int numContacts, struct cpCollisionHandler *handler, cpShape *a, cpShape *b);
|
81
96
|
// Precalculate values used by the solver.
|
82
97
|
void cpArbiterPreStep(cpArbiter *arb, cpFloat dt_inv);
|
83
98
|
void cpArbiterApplyCachedImpulse(cpArbiter *arb);
|
84
99
|
// Run an iteration of the solver on the arbiter.
|
85
100
|
void cpArbiterApplyImpulse(cpArbiter *arb, cpFloat eCoef);
|
101
|
+
|
102
|
+
// Arbiter Helper Functions
|
103
|
+
cpVect cpArbiterTotalImpulse(cpArbiter *arb);
|
104
|
+
cpVect cpArbiterTotalImpulseWithFriction(cpArbiter *arb);
|
105
|
+
void cpArbiterIgnore(cpArbiter *arb);
|
106
|
+
|
107
|
+
|
108
|
+
static inline void
|
109
|
+
cpArbiterGetShapes(cpArbiter *arb, cpShape **a, cpShape **b)
|
110
|
+
{
|
111
|
+
if(arb->swappedColl){
|
112
|
+
(*a) = arb->private_b, (*b) = arb->private_a;
|
113
|
+
} else {
|
114
|
+
(*a) = arb->private_a, (*b) = arb->private_b;
|
115
|
+
}
|
116
|
+
}
|
117
|
+
#define CP_ARBITER_GET_SHAPES(arb, a, b) cpShape *a, *b; cpArbiterGetShapes(arb, &a, &b);
|
118
|
+
|
119
|
+
static inline int
|
120
|
+
cpArbiterIsFirstContact(cpArbiter *arb)
|
121
|
+
{
|
122
|
+
return arb->state == cpArbiterStateFirstColl;
|
123
|
+
}
|
124
|
+
|
125
|
+
static inline cpVect
|
126
|
+
cpArbiterGetNormal(cpArbiter *arb, int i)
|
127
|
+
{
|
128
|
+
cpVect n = arb->contacts[i].n;
|
129
|
+
return arb->swappedColl ? cpvneg(n) : n;
|
130
|
+
}
|
131
|
+
|
132
|
+
static inline cpVect
|
133
|
+
cpArbiterGetPoint(cpArbiter *arb, int i)
|
134
|
+
{
|
135
|
+
return arb->contacts[i].p;
|
136
|
+
}
|
@@ -38,7 +38,8 @@ void cpArrayFree(cpArray *arr);
|
|
38
38
|
void cpArrayClear(cpArray *arr);
|
39
39
|
|
40
40
|
void cpArrayPush(cpArray *arr, void *object);
|
41
|
-
void
|
41
|
+
void *cpArrayPop(cpArray *arr);
|
42
|
+
void cpArrayDeleteIndex(cpArray *arr, int idx);
|
42
43
|
void cpArrayDeleteObj(cpArray *arr, void *obj);
|
43
44
|
|
44
45
|
void cpArrayEach(cpArray *arr, cpArrayIter iterFunc, void *data);
|
@@ -49,5 +49,26 @@ cpBBcontainsVect(const cpBB bb, const cpVect v)
|
|
49
49
|
return (bb.l < v.x && bb.r > v.x && bb.b < v.y && bb.t > v.y);
|
50
50
|
}
|
51
51
|
|
52
|
+
static inline cpBB
|
53
|
+
cpBBmerge(const cpBB a, const cpBB b){
|
54
|
+
return cpBBNew(
|
55
|
+
cpfmin(a.l, b.l),
|
56
|
+
cpfmin(a.b, b.b),
|
57
|
+
cpfmax(a.r, b.r),
|
58
|
+
cpfmax(a.t, b.t)
|
59
|
+
);
|
60
|
+
}
|
61
|
+
|
62
|
+
static inline cpBB
|
63
|
+
cpBBexpand(const cpBB bb, const cpVect v){
|
64
|
+
return cpBBNew(
|
65
|
+
cpfmin(bb.l, v.x),
|
66
|
+
cpfmin(bb.b, v.y),
|
67
|
+
cpfmax(bb.r, v.x),
|
68
|
+
cpfmax(bb.t, v.y)
|
69
|
+
);
|
70
|
+
}
|
71
|
+
|
52
72
|
cpVect cpBBClampVect(const cpBB bb, const cpVect v); // clamps the vector to lie within the bbox
|
73
|
+
// TODO edge case issue
|
53
74
|
cpVect cpBBWrapVect(const cpBB bb, const cpVect v); // wrap a vector to a bbox
|
@@ -23,9 +23,11 @@ struct cpBody;
|
|
23
23
|
typedef void (*cpBodyVelocityFunc)(struct cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt);
|
24
24
|
typedef void (*cpBodyPositionFunc)(struct cpBody *body, cpFloat dt);
|
25
25
|
|
26
|
+
extern cpBodyVelocityFunc cpBodyUpdateVelocityDefault;
|
27
|
+
extern cpBodyPositionFunc cpBodyUpdatePositionDefault;
|
26
28
|
|
27
29
|
typedef struct cpBody{
|
28
|
-
// *** Integration Functions.
|
30
|
+
// *** Integration Functions.ntoehu
|
29
31
|
|
30
32
|
// Function that is called to integrate the body's velocity. (Defaults to cpBodyUpdateVelocity)
|
31
33
|
cpBodyVelocityFunc velocity_func;
|
@@ -40,7 +42,7 @@ typedef struct cpBody{
|
|
40
42
|
cpFloat m, m_inv;
|
41
43
|
|
42
44
|
// Moment of inertia and it's inverse.
|
43
|
-
// Always use
|
45
|
+
// Always use cpBodySetMoment() whenever changing the moment as these values must agree.
|
44
46
|
cpFloat i, i_inv;
|
45
47
|
|
46
48
|
// *** Positional Properties
|
@@ -59,11 +61,14 @@ typedef struct cpBody{
|
|
59
61
|
// *** User Definable Fields
|
60
62
|
|
61
63
|
// User defined data pointer.
|
62
|
-
|
64
|
+
cpDataPointer data;
|
65
|
+
|
66
|
+
// Maximum velocities this body can move at after integrating velocity
|
67
|
+
cpFloat v_limit, w_limit;
|
63
68
|
|
64
69
|
// *** Internally Used Fields
|
65
70
|
|
66
|
-
// Velocity bias values used when solving penetrations and correcting
|
71
|
+
// Velocity bias values used when solving penetrations and correcting constraints.
|
67
72
|
cpVect v_bias;
|
68
73
|
cpFloat w_bias;
|
69
74
|
|
@@ -78,10 +83,32 @@ cpBody *cpBodyNew(cpFloat m, cpFloat i);
|
|
78
83
|
void cpBodyDestroy(cpBody *body);
|
79
84
|
void cpBodyFree(cpBody *body);
|
80
85
|
|
81
|
-
|
86
|
+
#define CP_DefineBodyGetter(type, member, name) static inline type cpBodyGet##name(cpBody *body){return body->member;}
|
87
|
+
#define CP_DefineBodySetter(type, member, name) static inline void cpBodySet##name(cpBody *body, type value){body->member = value;}
|
88
|
+
|
89
|
+
#define CP_DefineBodyProperty(type, member, name) \
|
90
|
+
CP_DefineBodyGetter(type, member, name) \
|
91
|
+
CP_DefineBodySetter(type, member, name)
|
92
|
+
|
93
|
+
|
94
|
+
// Accessors for cpBody struct members
|
95
|
+
CP_DefineBodyGetter(cpFloat, m, Mass);
|
82
96
|
void cpBodySetMass(cpBody *body, cpFloat m);
|
97
|
+
|
98
|
+
CP_DefineBodyGetter(cpFloat, i, Moment);
|
83
99
|
void cpBodySetMoment(cpBody *body, cpFloat i);
|
100
|
+
|
101
|
+
|
102
|
+
CP_DefineBodyProperty(cpVect, p, Pos);
|
103
|
+
CP_DefineBodyProperty(cpVect, v, Vel);
|
104
|
+
CP_DefineBodyProperty(cpVect, f, Force);
|
105
|
+
CP_DefineBodyGetter(cpFloat, a, Angle);
|
84
106
|
void cpBodySetAngle(cpBody *body, cpFloat a);
|
107
|
+
CP_DefineBodyProperty(cpFloat, w, AngVel);
|
108
|
+
CP_DefineBodyProperty(cpFloat, t, Torque);
|
109
|
+
CP_DefineBodyGetter(cpVect, rot, Rot);
|
110
|
+
CP_DefineBodyProperty(cpFloat, v_limit, VelLimit);
|
111
|
+
CP_DefineBodyProperty(cpFloat, w_limit, AngVelLimit);
|
85
112
|
|
86
113
|
// Modify the velocity of the body so that it will move to the specified absolute coordinates in the next timestep.
|
87
114
|
// Intended for objects that are moved manually with a custom velocity integration function.
|
@@ -105,7 +132,7 @@ cpBodyWorld2Local(cpBody *body, cpVect v)
|
|
105
132
|
return cpvunrotate(cpvsub(v, body->p), body->rot);
|
106
133
|
}
|
107
134
|
|
108
|
-
// Apply an impulse (in world coordinates) to the body.
|
135
|
+
// Apply an impulse (in world coordinates) to the body at a point relative to the center of gravity (also in world coordinates).
|
109
136
|
static inline void
|
110
137
|
cpBodyApplyImpulse(cpBody *body, cpVect j, cpVect r)
|
111
138
|
{
|
@@ -113,7 +140,7 @@ cpBodyApplyImpulse(cpBody *body, cpVect j, cpVect r)
|
|
113
140
|
body->w += body->i_inv*cpvcross(r, j);
|
114
141
|
}
|
115
142
|
|
116
|
-
// Not intended for external use. Used by cpArbiter.c and
|
143
|
+
// Not intended for external use. Used by cpArbiter.c and cpConstraint.c.
|
117
144
|
static inline void
|
118
145
|
cpBodyApplyBiasImpulse(cpBody *body, cpVect j, cpVect r)
|
119
146
|
{
|
@@ -123,10 +150,11 @@ cpBodyApplyBiasImpulse(cpBody *body, cpVect j, cpVect r)
|
|
123
150
|
|
124
151
|
// Zero the forces on a body.
|
125
152
|
void cpBodyResetForces(cpBody *body);
|
126
|
-
// Apply a force (in world coordinates) to a body.
|
153
|
+
// Apply a force (in world coordinates) to a body at a point relative to the center of gravity (also in world coordinates).
|
127
154
|
void cpBodyApplyForce(cpBody *body, cpVect f, cpVect r);
|
128
155
|
|
129
156
|
// Apply a damped spring force between two bodies.
|
130
|
-
|
157
|
+
// Warning: Large damping values can be unstable. Use a cpDampedSpring constraint for this instead.
|
158
|
+
void cpApplyDampedSpring(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat rlen, cpFloat k, cpFloat dmp, cpFloat dt);
|
131
159
|
|
132
160
|
//int cpBodyMarkLowEnergy(cpBody *body, cpFloat dvsq, int max);
|
@@ -27,7 +27,7 @@ typedef struct cpHashSetBin {
|
|
27
27
|
// Pointer to the element.
|
28
28
|
void *elt;
|
29
29
|
// Hash value of the element.
|
30
|
-
|
30
|
+
cpHashValue hash;
|
31
31
|
// Next element in the chain.
|
32
32
|
struct cpHashSetBin *next;
|
33
33
|
} cpHashSetBin;
|
@@ -38,8 +38,8 @@ typedef int (*cpHashSetEqlFunc)(void *ptr, void *elt);
|
|
38
38
|
typedef void *(*cpHashSetTransFunc)(void *ptr, void *data);
|
39
39
|
// Iterator function for a hashset.
|
40
40
|
typedef void (*cpHashSetIterFunc)(void *elt, void *data);
|
41
|
-
//
|
42
|
-
typedef int (*
|
41
|
+
// Filter function. Returns false if elt should be dropped.
|
42
|
+
typedef int (*cpHashSetFilterFunc)(void *elt, void *data);
|
43
43
|
|
44
44
|
typedef struct cpHashSet {
|
45
45
|
// Number of elements stored in the table.
|
@@ -54,7 +54,10 @@ typedef struct cpHashSet {
|
|
54
54
|
// Defaults to NULL.
|
55
55
|
void *default_value;
|
56
56
|
|
57
|
-
|
57
|
+
// The table and recycled bins
|
58
|
+
cpHashSetBin **table, *pooledBins;
|
59
|
+
|
60
|
+
cpArray *allocatedBuffers;
|
58
61
|
} cpHashSet;
|
59
62
|
|
60
63
|
// Basic allocation/destruction functions.
|
@@ -67,13 +70,13 @@ cpHashSet *cpHashSetNew(int size, cpHashSetEqlFunc eqlFunc, cpHashSetTransFunc t
|
|
67
70
|
|
68
71
|
// Insert an element into the set, returns the element.
|
69
72
|
// If it doesn't already exist, the transformation function is applied.
|
70
|
-
void *cpHashSetInsert(cpHashSet *set,
|
73
|
+
void *cpHashSetInsert(cpHashSet *set, cpHashValue hash, void *ptr, void *data);
|
71
74
|
// Remove and return an element from the set.
|
72
|
-
void *cpHashSetRemove(cpHashSet *set,
|
75
|
+
void *cpHashSetRemove(cpHashSet *set, cpHashValue hash, void *ptr);
|
73
76
|
// Find an element in the set. Returns the default value if the element isn't found.
|
74
|
-
void *cpHashSetFind(cpHashSet *set,
|
77
|
+
void *cpHashSetFind(cpHashSet *set, cpHashValue hash, void *ptr);
|
75
78
|
|
76
79
|
// Iterate over a hashset.
|
77
80
|
void cpHashSetEach(cpHashSet *set, cpHashSetIterFunc func, void *data);
|
78
|
-
// Iterate over a hashset
|
79
|
-
void
|
81
|
+
// Iterate over a hashset, retain .
|
82
|
+
void cpHashSetFilter(cpHashSet *set, cpHashSetFilterFunc func, void *data);
|
@@ -46,6 +46,17 @@ cpPolyShape *cpPolyShapeAlloc(void);
|
|
46
46
|
cpPolyShape *cpPolyShapeInit(cpPolyShape *poly, cpBody *body, int numVerts, cpVect *verts, cpVect offset);
|
47
47
|
cpShape *cpPolyShapeNew(cpBody *body, int numVerts, cpVect *verts, cpVect offset);
|
48
48
|
|
49
|
+
cpPolyShape *cpBoxShapeInit(cpPolyShape *poly, cpBody *body, cpFloat width, cpFloat height);
|
50
|
+
cpShape *cpBoxShapeNew(cpBody *body, cpFloat width, cpFloat height);
|
51
|
+
|
52
|
+
// Check that a set of vertexes has a correct winding and that they are convex
|
53
|
+
int cpPolyValidate(cpVect *verts, int numVerts);
|
54
|
+
|
55
|
+
int cpPolyShapeGetNumVerts(cpShape *shape);
|
56
|
+
cpVect cpPolyShapeGetVert(cpShape *shape, int idx);
|
57
|
+
|
58
|
+
// *** inlined utility functions
|
59
|
+
|
49
60
|
// Returns the minimum distance of the polygon to the axis.
|
50
61
|
static inline cpFloat
|
51
62
|
cpPolyShapeValueOnAxis(const cpPolyShape *poly, const cpVect n, const cpFloat d)
|
@@ -69,7 +80,7 @@ cpPolyShapeContainsVert(cpPolyShape *poly, cpVect v)
|
|
69
80
|
int i;
|
70
81
|
for(i=0; i<poly->numVerts; i++){
|
71
82
|
cpFloat dist = cpvdot(axes[i].n, v) - axes[i].d;
|
72
|
-
if(dist > 0.
|
83
|
+
if(dist > 0.0f) return 0;
|
73
84
|
}
|
74
85
|
|
75
86
|
return 1;
|
@@ -85,7 +96,7 @@ cpPolyShapeContainsVertPartial(cpPolyShape *poly, cpVect v, cpVect n)
|
|
85
96
|
for(i=0; i<poly->numVerts; i++){
|
86
97
|
if(cpvdot(axes[i].n, n) < 0.0f) continue;
|
87
98
|
cpFloat dist = cpvdot(axes[i].n, v) - axes[i].d;
|
88
|
-
if(dist > 0.
|
99
|
+
if(dist > 0.0f) return 0;
|
89
100
|
}
|
90
101
|
|
91
102
|
return 1;
|
@@ -18,9 +18,16 @@
|
|
18
18
|
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
19
19
|
* SOFTWARE.
|
20
20
|
*/
|
21
|
+
|
22
|
+
// Forward declarations required for defining other structs.
|
23
|
+
struct cpShape;
|
24
|
+
struct cpShapeClass;
|
21
25
|
|
22
|
-
|
23
|
-
|
26
|
+
typedef struct cpSegmentQueryInfo {
|
27
|
+
struct cpShape *shape; // shape that was hit, NULL if no collision
|
28
|
+
cpFloat t; // Distance along query segment, will always be in the range [0, 1].
|
29
|
+
cpVect n; // normal of hit surface
|
30
|
+
} cpSegmentQueryInfo;
|
24
31
|
|
25
32
|
// Enumeration of shape types.
|
26
33
|
typedef enum cpShapeType{
|
@@ -30,10 +37,6 @@ typedef enum cpShapeType{
|
|
30
37
|
CP_NUM_SHAPES
|
31
38
|
} cpShapeType;
|
32
39
|
|
33
|
-
// Forward declarations required for defining the cpShape and cpShapeClass structs.
|
34
|
-
struct cpShape;
|
35
|
-
struct cpShapeClass;
|
36
|
-
|
37
40
|
// Shape class. Holds function pointers and type data.
|
38
41
|
typedef struct cpShapeClass {
|
39
42
|
cpShapeType type;
|
@@ -43,8 +46,11 @@ typedef struct cpShapeClass {
|
|
43
46
|
// Called to by cpShapeDestroy().
|
44
47
|
void (*destroy)(struct cpShape *shape);
|
45
48
|
|
46
|
-
// called by
|
49
|
+
// called by cpShapePointQuery().
|
47
50
|
int (*pointQuery)(struct cpShape *shape, cpVect p);
|
51
|
+
|
52
|
+
// called by cpShapeSegmentQuery()
|
53
|
+
void (*segmentQuery)(struct cpShape *shape, cpVect a, cpVect b, cpSegmentQueryInfo *info);
|
48
54
|
} cpShapeClass;
|
49
55
|
|
50
56
|
// Basic shape struct that the others inherit from.
|
@@ -58,6 +64,9 @@ typedef struct cpShape{
|
|
58
64
|
// Cached BBox for the shape.
|
59
65
|
cpBB bb;
|
60
66
|
|
67
|
+
// Sensors invoke callbacks, but do not generate collisions
|
68
|
+
int sensor;
|
69
|
+
|
61
70
|
// *** Surface properties.
|
62
71
|
|
63
72
|
// Coefficient of restitution. (elasticity)
|
@@ -70,19 +79,19 @@ typedef struct cpShape{
|
|
70
79
|
// *** User Definable Fields
|
71
80
|
|
72
81
|
// User defined data pointer for the shape.
|
73
|
-
|
82
|
+
cpDataPointer data;
|
74
83
|
|
75
84
|
// User defined collision type for the shape.
|
76
|
-
|
85
|
+
cpCollisionType collision_type;
|
77
86
|
// User defined collision group for the shape.
|
78
|
-
|
87
|
+
cpGroup group;
|
79
88
|
// User defined layer bitmask for the shape.
|
80
|
-
|
89
|
+
cpLayers layers;
|
81
90
|
|
82
91
|
// *** Internally Used Fields
|
83
92
|
|
84
93
|
// Unique id used as the hash value.
|
85
|
-
|
94
|
+
cpHashValue hashid;
|
86
95
|
} cpShape;
|
87
96
|
|
88
97
|
// Low level shape initialization func.
|
@@ -98,17 +107,13 @@ cpBB cpShapeCacheBB(cpShape *shape);
|
|
98
107
|
// Test if a point lies within a shape.
|
99
108
|
int cpShapePointQuery(cpShape *shape, cpVect p);
|
100
109
|
|
101
|
-
|
102
|
-
// Returns [0-1] if the segment collides and -1 otherwise.
|
103
|
-
// 0 would be a collision at point a, 1 would be a collision at point b.
|
104
|
-
//cpFloat cpShapeSegmentQuery(cpShape *shape, cpVect a, cpVect b);
|
105
|
-
|
110
|
+
#define CP_DeclareShapeGetter(struct, type, name) type struct##Get##name(cpShape *shape)
|
106
111
|
|
107
112
|
// Circle shape structure.
|
108
113
|
typedef struct cpCircleShape{
|
109
114
|
cpShape shape;
|
110
115
|
|
111
|
-
// Center
|
116
|
+
// Center in body space coordinates
|
112
117
|
cpVect c;
|
113
118
|
// Radius.
|
114
119
|
cpFloat r;
|
@@ -122,6 +127,9 @@ cpCircleShape *cpCircleShapeAlloc(void);
|
|
122
127
|
cpCircleShape *cpCircleShapeInit(cpCircleShape *circle, cpBody *body, cpFloat radius, cpVect offset);
|
123
128
|
cpShape *cpCircleShapeNew(cpBody *body, cpFloat radius, cpVect offset);
|
124
129
|
|
130
|
+
CP_DeclareShapeGetter(cpCircleShape, cpVect, Offset);
|
131
|
+
CP_DeclareShapeGetter(cpCircleShape, cpFloat, Radius);
|
132
|
+
|
125
133
|
// Segment shape structure.
|
126
134
|
typedef struct cpSegmentShape{
|
127
135
|
cpShape shape;
|
@@ -139,3 +147,28 @@ typedef struct cpSegmentShape{
|
|
139
147
|
cpSegmentShape* cpSegmentShapeAlloc(void);
|
140
148
|
cpSegmentShape* cpSegmentShapeInit(cpSegmentShape *seg, cpBody *body, cpVect a, cpVect b, cpFloat radius);
|
141
149
|
cpShape* cpSegmentShapeNew(cpBody *body, cpVect a, cpVect b, cpFloat radius);
|
150
|
+
|
151
|
+
CP_DeclareShapeGetter(cpSegmentShape, cpVect, A);
|
152
|
+
CP_DeclareShapeGetter(cpSegmentShape, cpVect, B);
|
153
|
+
CP_DeclareShapeGetter(cpSegmentShape, cpVect, Normal);
|
154
|
+
CP_DeclareShapeGetter(cpSegmentShape, cpFloat, Radius);
|
155
|
+
|
156
|
+
// For determinism, you can reset the shape id counter.
|
157
|
+
void cpResetShapeIdCounter(void);
|
158
|
+
|
159
|
+
// Directed segment queries against individual shapes.
|
160
|
+
void cpSegmentQueryInfoPrint(cpSegmentQueryInfo *info);
|
161
|
+
|
162
|
+
int cpShapeSegmentQuery(cpShape *shape, cpVect a, cpVect b, cpSegmentQueryInfo *info);
|
163
|
+
|
164
|
+
static inline cpVect
|
165
|
+
cpSegmentQueryHitPoint(cpVect start, cpVect end, cpSegmentQueryInfo info)
|
166
|
+
{
|
167
|
+
return cpvlerp(start, end, info.t);
|
168
|
+
}
|
169
|
+
|
170
|
+
static inline cpFloat
|
171
|
+
cpSegmentQueryHitDist(cpVect start, cpVect end, cpSegmentQueryInfo info)
|
172
|
+
{
|
173
|
+
return cpvdist(start, end)*info.t;
|
174
|
+
}
|