chipmunk 4.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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);