chipmunk 4.1.0 → 5.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
}
|