chipmunk 4.1.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.
@@ -0,0 +1,139 @@
1
+ /* Copyright (c) 2007 Scott Lembcke
2
+ *
3
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ * of this software and associated documentation files (the "Software"), to deal
5
+ * in the Software without restriction, including without limitation the rights
6
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ * copies of the Software, and to permit persons to whom the Software is
8
+ * furnished to do so, subject to the following conditions:
9
+ *
10
+ * The above copyright notice and this permission notice shall be included in
11
+ * all copies or substantial portions of the Software.
12
+ *
13
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ * SOFTWARE.
20
+ */
21
+
22
+ #include <stdlib.h>
23
+ #include <stdio.h>
24
+ #include <math.h>
25
+
26
+ #include "chipmunk.h"
27
+
28
+ cpPolyShape *
29
+ cpPolyShapeAlloc(void)
30
+ {
31
+ return (cpPolyShape *)calloc(1, sizeof(cpPolyShape));
32
+ }
33
+
34
+ static void
35
+ cpPolyShapeTransformVerts(cpPolyShape *poly, cpVect p, cpVect rot)
36
+ {
37
+ cpVect *src = poly->verts;
38
+ cpVect *dst = poly->tVerts;
39
+
40
+ for(int i=0; i<poly->numVerts; i++)
41
+ dst[i] = cpvadd(p, cpvrotate(src[i], rot));
42
+ }
43
+
44
+ static void
45
+ cpPolyShapeTransformAxes(cpPolyShape *poly, cpVect p, cpVect rot)
46
+ {
47
+ cpPolyShapeAxis *src = poly->axes;
48
+ cpPolyShapeAxis *dst = poly->tAxes;
49
+
50
+ for(int i=0; i<poly->numVerts; i++){
51
+ cpVect n = cpvrotate(src[i].n, rot);
52
+ dst[i].n = n;
53
+ dst[i].d = cpvdot(p, n) + src[i].d;
54
+ }
55
+ }
56
+
57
+ static cpBB
58
+ cpPolyShapeCacheData(cpShape *shape, cpVect p, cpVect rot)
59
+ {
60
+ cpPolyShape *poly = (cpPolyShape *)shape;
61
+
62
+ cpFloat l, b, r, t;
63
+
64
+ cpPolyShapeTransformAxes(poly, p, rot);
65
+ cpPolyShapeTransformVerts(poly, p, rot);
66
+
67
+ cpVect *verts = poly->tVerts;
68
+ l = r = verts[0].x;
69
+ b = t = verts[0].y;
70
+
71
+ // TODO do as part of cpPolyShapeTransformVerts?
72
+ for(int i=1; i<poly->numVerts; i++){
73
+ cpVect v = verts[i];
74
+
75
+ l = cpfmin(l, v.x);
76
+ r = cpfmax(r, v.x);
77
+
78
+ b = cpfmin(b, v.y);
79
+ t = cpfmax(t, v.y);
80
+ }
81
+
82
+ return cpBBNew(l, b, r, t);
83
+ }
84
+
85
+ static void
86
+ cpPolyShapeDestroy(cpShape *shape)
87
+ {
88
+ cpPolyShape *poly = (cpPolyShape *)shape;
89
+
90
+ free(poly->verts);
91
+ free(poly->tVerts);
92
+
93
+ free(poly->axes);
94
+ free(poly->tAxes);
95
+ }
96
+
97
+ static int
98
+ cpPolyShapePointQuery(cpShape *shape, cpVect p){
99
+ // TODO Check against BB first?
100
+ return cpPolyShapeContainsVert((cpPolyShape *)shape, p);
101
+ }
102
+
103
+ static const cpShapeClass polyClass = {
104
+ CP_POLY_SHAPE,
105
+ cpPolyShapeCacheData,
106
+ cpPolyShapeDestroy,
107
+ cpPolyShapePointQuery,
108
+ };
109
+
110
+ cpPolyShape *
111
+ cpPolyShapeInit(cpPolyShape *poly, cpBody *body, int numVerts, cpVect *verts, cpVect offset)
112
+ {
113
+ poly->numVerts = numVerts;
114
+
115
+ poly->verts = (cpVect *)calloc(numVerts, sizeof(cpVect));
116
+ poly->tVerts = (cpVect *)calloc(numVerts, sizeof(cpVect));
117
+ poly->axes = (cpPolyShapeAxis *)calloc(numVerts, sizeof(cpPolyShapeAxis));
118
+ poly->tAxes = (cpPolyShapeAxis *)calloc(numVerts, sizeof(cpPolyShapeAxis));
119
+
120
+ for(int i=0; i<numVerts; i++){
121
+ cpVect a = cpvadd(offset, verts[i]);
122
+ cpVect b = cpvadd(offset, verts[(i+1)%numVerts]);
123
+ cpVect n = cpvnormalize(cpvperp(cpvsub(b, a)));
124
+
125
+ poly->verts[i] = a;
126
+ poly->axes[i].n = n;
127
+ poly->axes[i].d = cpvdot(n, a);
128
+ }
129
+
130
+ cpShapeInit((cpShape *)poly, &polyClass, body);
131
+
132
+ return poly;
133
+ }
134
+
135
+ cpShape *
136
+ cpPolyShapeNew(cpBody *body, int numVerts, cpVect *verts, cpVect offset)
137
+ {
138
+ return (cpShape *)cpPolyShapeInit(cpPolyShapeAlloc(), body, numVerts, verts, offset);
139
+ }
@@ -0,0 +1,92 @@
1
+ /* Copyright (c) 2007 Scott Lembcke
2
+ *
3
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ * of this software and associated documentation files (the "Software"), to deal
5
+ * in the Software without restriction, including without limitation the rights
6
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ * copies of the Software, and to permit persons to whom the Software is
8
+ * furnished to do so, subject to the following conditions:
9
+ *
10
+ * The above copyright notice and this permission notice shall be included in
11
+ * all copies or substantial portions of the Software.
12
+ *
13
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ * SOFTWARE.
20
+ */
21
+
22
+ // Axis structure used by cpPolyShape.
23
+ typedef struct cpPolyShapeAxis{
24
+ // normal
25
+ cpVect n;
26
+ // distance from origin
27
+ cpFloat d;
28
+ } cpPolyShapeAxis;
29
+
30
+ // Convex polygon shape structure.
31
+ typedef struct cpPolyShape{
32
+ cpShape shape;
33
+
34
+ // Vertex and axis lists.
35
+ int numVerts;
36
+ cpVect *verts;
37
+ cpPolyShapeAxis *axes;
38
+
39
+ // Transformed vertex and axis lists.
40
+ cpVect *tVerts;
41
+ cpPolyShapeAxis *tAxes;
42
+ } cpPolyShape;
43
+
44
+ // Basic allocation functions.
45
+ cpPolyShape *cpPolyShapeAlloc(void);
46
+ cpPolyShape *cpPolyShapeInit(cpPolyShape *poly, cpBody *body, int numVerts, cpVect *verts, cpVect offset);
47
+ cpShape *cpPolyShapeNew(cpBody *body, int numVerts, cpVect *verts, cpVect offset);
48
+
49
+ // Returns the minimum distance of the polygon to the axis.
50
+ static inline cpFloat
51
+ cpPolyShapeValueOnAxis(const cpPolyShape *poly, const cpVect n, const cpFloat d)
52
+ {
53
+ cpVect *verts = poly->tVerts;
54
+ cpFloat min = cpvdot(n, verts[0]);
55
+
56
+ int i;
57
+ for(i=1; i<poly->numVerts; i++)
58
+ min = cpfmin(min, cpvdot(n, verts[i]));
59
+
60
+ return min - d;
61
+ }
62
+
63
+ // Returns true if the polygon contains the vertex.
64
+ static inline int
65
+ cpPolyShapeContainsVert(cpPolyShape *poly, cpVect v)
66
+ {
67
+ cpPolyShapeAxis *axes = poly->tAxes;
68
+
69
+ int i;
70
+ for(i=0; i<poly->numVerts; i++){
71
+ cpFloat dist = cpvdot(axes[i].n, v) - axes[i].d;
72
+ if(dist > 0.0) return 0;
73
+ }
74
+
75
+ return 1;
76
+ }
77
+
78
+ // Same as cpPolyShapeContainsVert() but ignores faces pointing away from the normal.
79
+ static inline int
80
+ cpPolyShapeContainsVertPartial(cpPolyShape *poly, cpVect v, cpVect n)
81
+ {
82
+ cpPolyShapeAxis *axes = poly->tAxes;
83
+
84
+ int i;
85
+ for(i=0; i<poly->numVerts; i++){
86
+ if(cpvdot(axes[i].n, n) < 0.0f) continue;
87
+ cpFloat dist = cpvdot(axes[i].n, v) - axes[i].d;
88
+ if(dist > 0.0) return 0;
89
+ }
90
+
91
+ return 1;
92
+ }
@@ -0,0 +1,244 @@
1
+ /* Copyright (c) 2007 Scott Lembcke
2
+ *
3
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ * of this software and associated documentation files (the "Software"), to deal
5
+ * in the Software without restriction, including without limitation the rights
6
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ * copies of the Software, and to permit persons to whom the Software is
8
+ * furnished to do so, subject to the following conditions:
9
+ *
10
+ * The above copyright notice and this permission notice shall be included in
11
+ * all copies or substantial portions of the Software.
12
+ *
13
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ * SOFTWARE.
20
+ */
21
+
22
+ #include <stdlib.h>
23
+ #include <assert.h>
24
+ #include <stdio.h>
25
+
26
+ #include "chipmunk.h"
27
+ #include "math.h"
28
+
29
+ unsigned int SHAPE_ID_COUNTER = 0;
30
+
31
+ void
32
+ cpResetShapeIdCounter(void)
33
+ {
34
+ SHAPE_ID_COUNTER = 0;
35
+ }
36
+
37
+
38
+ cpShape*
39
+ cpShapeInit(cpShape *shape, const cpShapeClass *klass, cpBody *body)
40
+ {
41
+ shape->klass = klass;
42
+
43
+ shape->id = SHAPE_ID_COUNTER;
44
+ SHAPE_ID_COUNTER++;
45
+
46
+ assert(body != NULL);
47
+ shape->body = body;
48
+
49
+ shape->e = 0.0f;
50
+ shape->u = 0.0f;
51
+ shape->surface_v = cpvzero;
52
+
53
+ shape->collision_type = 0;
54
+ shape->group = 0;
55
+ shape->layers = 0xFFFF;
56
+
57
+ shape->data = NULL;
58
+
59
+ cpShapeCacheBB(shape);
60
+
61
+ return shape;
62
+ }
63
+
64
+ void
65
+ cpShapeDestroy(cpShape *shape)
66
+ {
67
+ if(shape->klass->destroy) shape->klass->destroy(shape);
68
+ }
69
+
70
+ void
71
+ cpShapeFree(cpShape *shape)
72
+ {
73
+ if(shape) cpShapeDestroy(shape);
74
+ free(shape);
75
+ }
76
+
77
+ cpBB
78
+ cpShapeCacheBB(cpShape *shape)
79
+ {
80
+ cpBody *body = shape->body;
81
+
82
+ shape->bb = shape->klass->cacheData(shape, body->p, body->rot);
83
+ return shape->bb;
84
+ }
85
+
86
+ int
87
+ cpShapePointQuery(cpShape *shape, cpVect p){
88
+ return shape->klass->pointQuery(shape, p);
89
+ }
90
+
91
+
92
+
93
+ cpCircleShape *
94
+ cpCircleShapeAlloc(void)
95
+ {
96
+ return (cpCircleShape *)calloc(1, sizeof(cpCircleShape));
97
+ }
98
+
99
+ static inline cpBB
100
+ bbFromCircle(const cpVect c, const cpFloat r)
101
+ {
102
+ return cpBBNew(c.x-r, c.y-r, c.x+r, c.y+r);
103
+ }
104
+
105
+ static cpBB
106
+ cpCircleShapeCacheData(cpShape *shape, cpVect p, cpVect rot)
107
+ {
108
+ cpCircleShape *circle = (cpCircleShape *)shape;
109
+
110
+ circle->tc = cpvadd(p, cpvrotate(circle->c, rot));
111
+ return bbFromCircle(circle->tc, circle->r);
112
+ }
113
+
114
+ static int
115
+ cpCircleShapePointQuery(cpShape *shape, cpVect p){
116
+ cpCircleShape *circle = (cpCircleShape *)shape;
117
+
118
+ cpFloat distSQ = cpvlengthsq(cpvsub(circle->tc, p));
119
+ return distSQ <= (circle->r*circle->r);
120
+ }
121
+
122
+ static const cpShapeClass circleClass = {
123
+ CP_CIRCLE_SHAPE,
124
+ cpCircleShapeCacheData,
125
+ NULL,
126
+ cpCircleShapePointQuery,
127
+ };
128
+
129
+ cpCircleShape *
130
+ cpCircleShapeInit(cpCircleShape *circle, cpBody *body, cpFloat radius, cpVect offset)
131
+ {
132
+ circle->c = offset;
133
+ circle->r = radius;
134
+
135
+ cpShapeInit((cpShape *)circle, &circleClass, body);
136
+
137
+ return circle;
138
+ }
139
+
140
+ cpShape *
141
+ cpCircleShapeNew(cpBody *body, cpFloat radius, cpVect offset)
142
+ {
143
+ return (cpShape *)cpCircleShapeInit(cpCircleShapeAlloc(), body, radius, offset);
144
+ }
145
+
146
+ cpSegmentShape *
147
+ cpSegmentShapeAlloc(void)
148
+ {
149
+ return (cpSegmentShape *)calloc(1, sizeof(cpSegmentShape));
150
+ }
151
+
152
+ static cpBB
153
+ cpSegmentShapeCacheData(cpShape *shape, cpVect p, cpVect rot)
154
+ {
155
+ cpSegmentShape *seg = (cpSegmentShape *)shape;
156
+
157
+ seg->ta = cpvadd(p, cpvrotate(seg->a, rot));
158
+ seg->tb = cpvadd(p, cpvrotate(seg->b, rot));
159
+ seg->tn = cpvrotate(seg->n, rot);
160
+
161
+ cpFloat l,r,s,t;
162
+
163
+ if(seg->ta.x < seg->tb.x){
164
+ l = seg->ta.x;
165
+ r = seg->tb.x;
166
+ } else {
167
+ l = seg->tb.x;
168
+ r = seg->ta.x;
169
+ }
170
+
171
+ if(seg->ta.y < seg->tb.y){
172
+ s = seg->ta.y;
173
+ t = seg->tb.y;
174
+ } else {
175
+ s = seg->tb.y;
176
+ t = seg->ta.y;
177
+ }
178
+
179
+ cpFloat rad = seg->r;
180
+ return cpBBNew(l - rad, s - rad, r + rad, t + rad);
181
+ }
182
+
183
+ static int
184
+ cpSegmentShapePointQuery(cpShape *shape, cpVect p){
185
+ cpSegmentShape *seg = (cpSegmentShape *)shape;
186
+
187
+ // Calculate normal distance from segment.
188
+ cpFloat dn = cpvdot(seg->tn, p) - cpvdot(seg->ta, seg->tn);
189
+ cpFloat dist = fabs(dn) - seg->r;
190
+ if(dist > 0.0f) return 0;
191
+
192
+ // Calculate tangential distance along segment.
193
+ cpFloat dt = -cpvcross(seg->tn, p);
194
+ cpFloat dtMin = -cpvcross(seg->tn, seg->ta);
195
+ cpFloat dtMax = -cpvcross(seg->tn, seg->tb);
196
+
197
+ // Decision tree to decide which feature of the segment to collide with.
198
+ if(dt <= dtMin){
199
+ if(dt < (dtMin - seg->r)){
200
+ return 0;
201
+ } else {
202
+ return cpvlengthsq(cpvsub(seg->ta, p)) < (seg->r*seg->r);
203
+ }
204
+ } else {
205
+ if(dt < dtMax){
206
+ return 1;
207
+ } else {
208
+ if(dt < (dtMax + seg->r)) {
209
+ return cpvlengthsq(cpvsub(seg->tb, p)) < (seg->r*seg->r);
210
+ } else {
211
+ return 0;
212
+ }
213
+ }
214
+ }
215
+
216
+ return 1;
217
+ }
218
+
219
+ static const cpShapeClass segmentClass = {
220
+ CP_SEGMENT_SHAPE,
221
+ cpSegmentShapeCacheData,
222
+ NULL,
223
+ cpSegmentShapePointQuery,
224
+ };
225
+
226
+ cpSegmentShape *
227
+ cpSegmentShapeInit(cpSegmentShape *seg, cpBody *body, cpVect a, cpVect b, cpFloat r)
228
+ {
229
+ seg->a = a;
230
+ seg->b = b;
231
+ seg->n = cpvperp(cpvnormalize(cpvsub(b, a)));
232
+
233
+ seg->r = r;
234
+
235
+ cpShapeInit((cpShape *)seg, &segmentClass, body);
236
+
237
+ return seg;
238
+ }
239
+
240
+ cpShape*
241
+ cpSegmentShapeNew(cpBody *body, cpVect a, cpVect b, cpFloat r)
242
+ {
243
+ return (cpShape *)cpSegmentShapeInit(cpSegmentShapeAlloc(), body, a, b, r);
244
+ }
@@ -0,0 +1,141 @@
1
+ /* Copyright (c) 2007 Scott Lembcke
2
+ *
3
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ * of this software and associated documentation files (the "Software"), to deal
5
+ * in the Software without restriction, including without limitation the rights
6
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ * copies of the Software, and to permit persons to whom the Software is
8
+ * furnished to do so, subject to the following conditions:
9
+ *
10
+ * The above copyright notice and this permission notice shall be included in
11
+ * all copies or substantial portions of the Software.
12
+ *
13
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ * SOFTWARE.
20
+ */
21
+
22
+ // For determinism, you can reset the shape id counter.
23
+ void cpResetShapeIdCounter(void);
24
+
25
+ // Enumeration of shape types.
26
+ typedef enum cpShapeType{
27
+ CP_CIRCLE_SHAPE,
28
+ CP_SEGMENT_SHAPE,
29
+ CP_POLY_SHAPE,
30
+ CP_NUM_SHAPES
31
+ } cpShapeType;
32
+
33
+ // Forward declarations required for defining the cpShape and cpShapeClass structs.
34
+ struct cpShape;
35
+ struct cpShapeClass;
36
+
37
+ // Shape class. Holds function pointers and type data.
38
+ typedef struct cpShapeClass {
39
+ cpShapeType type;
40
+
41
+ // Called by cpShapeCacheBB().
42
+ cpBB (*cacheData)(struct cpShape *shape, cpVect p, cpVect rot);
43
+ // Called to by cpShapeDestroy().
44
+ void (*destroy)(struct cpShape *shape);
45
+
46
+ // called by cpShapeQueryPointQuery().
47
+ int (*pointQuery)(struct cpShape *shape, cpVect p);
48
+ } cpShapeClass;
49
+
50
+ // Basic shape struct that the others inherit from.
51
+ typedef struct cpShape{
52
+ // The "class" of a shape as defined above
53
+ const cpShapeClass *klass;
54
+
55
+ // cpBody that the shape is attached to.
56
+ cpBody *body;
57
+
58
+ // Cached BBox for the shape.
59
+ cpBB bb;
60
+
61
+ // *** Surface properties.
62
+
63
+ // Coefficient of restitution. (elasticity)
64
+ cpFloat e;
65
+ // Coefficient of friction.
66
+ cpFloat u;
67
+ // Surface velocity used when solving for friction.
68
+ cpVect surface_v;
69
+
70
+ // *** User Definable Fields
71
+
72
+ // User defined data pointer for the shape.
73
+ void *data;
74
+
75
+ // User defined collision type for the shape.
76
+ unsigned int collision_type;
77
+ // User defined collision group for the shape.
78
+ unsigned int group;
79
+ // User defined layer bitmask for the shape.
80
+ unsigned int layers;
81
+
82
+ // *** Internally Used Fields
83
+
84
+ // Unique id used as the hash value.
85
+ unsigned int id;
86
+ } cpShape;
87
+
88
+ // Low level shape initialization func.
89
+ cpShape* cpShapeInit(cpShape *shape, const struct cpShapeClass *klass, cpBody *body);
90
+
91
+ // Basic destructor functions. (allocation functions are not shared)
92
+ void cpShapeDestroy(cpShape *shape);
93
+ void cpShapeFree(cpShape *shape);
94
+
95
+ // Cache the BBox of the shape.
96
+ cpBB cpShapeCacheBB(cpShape *shape);
97
+
98
+ // Test if a point lies within a shape.
99
+ int cpShapePointQuery(cpShape *shape, cpVect p);
100
+
101
+ // Test if a segment collides with a shape.
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
+
106
+
107
+ // Circle shape structure.
108
+ typedef struct cpCircleShape{
109
+ cpShape shape;
110
+
111
+ // Center. (body space coordinates)
112
+ cpVect c;
113
+ // Radius.
114
+ cpFloat r;
115
+
116
+ // Transformed center. (world space coordinates)
117
+ cpVect tc;
118
+ } cpCircleShape;
119
+
120
+ // Basic allocation functions for cpCircleShape.
121
+ cpCircleShape *cpCircleShapeAlloc(void);
122
+ cpCircleShape *cpCircleShapeInit(cpCircleShape *circle, cpBody *body, cpFloat radius, cpVect offset);
123
+ cpShape *cpCircleShapeNew(cpBody *body, cpFloat radius, cpVect offset);
124
+
125
+ // Segment shape structure.
126
+ typedef struct cpSegmentShape{
127
+ cpShape shape;
128
+
129
+ // Endpoints and normal of the segment. (body space coordinates)
130
+ cpVect a, b, n;
131
+ // Radius of the segment. (Thickness)
132
+ cpFloat r;
133
+
134
+ // Transformed endpoints and normal. (world space coordinates)
135
+ cpVect ta, tb, tn;
136
+ } cpSegmentShape;
137
+
138
+ // Basic allocation functions for cpSegmentShape.
139
+ cpSegmentShape* cpSegmentShapeAlloc(void);
140
+ cpSegmentShape* cpSegmentShapeInit(cpSegmentShape *seg, cpBody *body, cpVect a, cpVect b, cpFloat radius);
141
+ cpShape* cpSegmentShapeNew(cpBody *body, cpVect a, cpVect b, cpFloat radius);