chipmunk 5.3.4.5 → 6.1.3.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. data/ext/chipmunk/chipmunk.c +199 -28
  2. data/ext/chipmunk/chipmunk.h +123 -68
  3. data/ext/chipmunk/chipmunk_ffi.h +129 -11
  4. data/ext/chipmunk/chipmunk_private.h +232 -16
  5. data/ext/chipmunk/chipmunk_types.h +94 -30
  6. data/ext/chipmunk/chipmunk_unsafe.h +12 -3
  7. data/ext/chipmunk/constraints/cpConstraint.h +90 -34
  8. data/ext/chipmunk/{cpDampedRotarySpring.h → constraints/cpDampedRotarySpring.h} +18 -8
  9. data/ext/chipmunk/{cpDampedSpring.h → constraints/cpDampedSpring.h} +27 -16
  10. data/ext/chipmunk/constraints/cpGearJoint.h +17 -7
  11. data/ext/chipmunk/constraints/cpGrooveJoint.h +19 -10
  12. data/ext/chipmunk/constraints/cpPinJoint.h +17 -8
  13. data/ext/chipmunk/constraints/cpPivotJoint.h +18 -9
  14. data/ext/chipmunk/constraints/cpRatchetJoint.h +17 -8
  15. data/ext/chipmunk/constraints/cpRotaryLimitJoint.h +16 -7
  16. data/ext/chipmunk/{cpSimpleMotor.h → constraints/cpSimpleMotor.h} +15 -6
  17. data/ext/chipmunk/constraints/cpSlideJoint.h +18 -9
  18. data/ext/chipmunk/constraints/util.h +36 -44
  19. data/ext/chipmunk/cpArbiter.c +159 -94
  20. data/ext/chipmunk/cpArbiter.h +135 -129
  21. data/ext/chipmunk/cpArray.c +37 -56
  22. data/ext/chipmunk/cpBB.c +1 -12
  23. data/ext/chipmunk/cpBB.h +80 -18
  24. data/ext/chipmunk/cpBBTree.c +891 -0
  25. data/ext/chipmunk/cpBody.c +185 -47
  26. data/ext/chipmunk/cpBody.h +156 -124
  27. data/ext/chipmunk/cpCollision.c +126 -115
  28. data/ext/chipmunk/cpConstraint.c +10 -6
  29. data/ext/chipmunk/cpDampedRotarySpring.c +26 -17
  30. data/ext/chipmunk/cpDampedSpring.c +25 -18
  31. data/ext/chipmunk/cpGearJoint.c +23 -17
  32. data/ext/chipmunk/cpGrooveJoint.c +26 -22
  33. data/ext/chipmunk/cpHashSet.c +51 -51
  34. data/ext/chipmunk/cpPinJoint.c +26 -19
  35. data/ext/chipmunk/cpPivotJoint.c +23 -19
  36. data/ext/chipmunk/cpPolyShape.c +93 -69
  37. data/ext/chipmunk/cpPolyShape.h +33 -69
  38. data/ext/chipmunk/cpRatchetJoint.c +26 -21
  39. data/ext/chipmunk/cpRotaryLimitJoint.c +28 -22
  40. data/ext/chipmunk/cpShape.c +122 -133
  41. data/ext/chipmunk/cpShape.h +146 -95
  42. data/ext/chipmunk/cpSimpleMotor.c +24 -17
  43. data/ext/chipmunk/cpSlideJoint.c +28 -26
  44. data/ext/chipmunk/cpSpace.c +251 -196
  45. data/ext/chipmunk/cpSpace.h +173 -103
  46. data/ext/chipmunk/cpSpaceComponent.c +236 -159
  47. data/ext/chipmunk/cpSpaceHash.c +259 -159
  48. data/ext/chipmunk/cpSpaceQuery.c +127 -59
  49. data/ext/chipmunk/cpSpaceStep.c +235 -197
  50. data/ext/chipmunk/cpSpatialIndex.c +69 -0
  51. data/ext/chipmunk/cpSpatialIndex.h +227 -0
  52. data/ext/chipmunk/cpSweep1D.c +254 -0
  53. data/ext/chipmunk/cpVect.c +11 -26
  54. data/ext/chipmunk/cpVect.h +76 -71
  55. data/ext/chipmunk/extconf.rb +4 -31
  56. data/ext/chipmunk/prime.h +1 -1
  57. data/ext/chipmunk/rb_chipmunk.c +36 -45
  58. data/ext/chipmunk/rb_chipmunk.h +6 -3
  59. data/ext/chipmunk/rb_cpArbiter.c +2 -2
  60. data/ext/chipmunk/rb_cpBB.c +116 -35
  61. data/ext/chipmunk/rb_cpBody.c +5 -12
  62. data/ext/chipmunk/rb_cpConstraint.c +144 -9
  63. data/ext/chipmunk/rb_cpShape.c +69 -78
  64. data/ext/chipmunk/rb_cpSpace.c +81 -76
  65. metadata +61 -61
  66. data/LICENSE +0 -22
  67. data/README +0 -110
  68. data/Rakefile +0 -102
  69. data/ext/chipmunk/cpArray.h +0 -49
  70. data/ext/chipmunk/cpCollision.h +0 -28
  71. data/ext/chipmunk/cpHashSet.h +0 -82
  72. data/ext/chipmunk/cpSpaceHash.h +0 -110
  73. data/lib/chipmunk.rb +0 -194
@@ -19,45 +19,42 @@
19
19
  * SOFTWARE.
20
20
  */
21
21
 
22
- #include <stdlib.h>
23
22
  #include <stdio.h>
24
- #define _USE_MATH_DEFINES
25
- #include <math.h>
23
+ #include <string.h>
24
+ #include <stdarg.h>
26
25
 
27
- #include "chipmunk.h"
28
-
29
- #ifdef __cplusplus
30
- extern "C" {
31
- #endif
32
- void cpInitCollisionFuncs(void);
33
- #ifdef __cplusplus
34
- }
35
- #endif
26
+ #include "chipmunk_private.h"
36
27
 
37
28
  void
38
- cpMessage(const char *message, const char *condition, const char *file, int line, int isError)
29
+ cpMessage(const char *condition, const char *file, int line, cpBool isError, cpBool isHardError, const char *message, ...)
39
30
  {
40
- fprintf(stderr, (isError ? "Aborting due to Chipmunk error: %s\n" : "Chipmunk warning: %s\n"), message);
31
+ fprintf(stderr, (isError ? "Aborting due to Chipmunk error: " : "Chipmunk warning: "));
32
+
33
+ va_list vargs;
34
+ va_start(vargs, message); {
35
+ vfprintf(stderr, message, vargs);
36
+ fprintf(stderr, "\n");
37
+ } va_end(vargs);
38
+
41
39
  fprintf(stderr, "\tFailed condition: %s\n", condition);
42
40
  fprintf(stderr, "\tSource:%s:%d\n", file, line);
43
41
 
44
42
  if(isError) abort();
45
43
  }
46
44
 
45
+ #define STR(s) #s
46
+ #define XSTR(s) STR(s)
47
47
 
48
- const char *cpVersionString = "5.3.4";
48
+ const char *cpVersionString = XSTR(CP_VERSION_MAJOR)"."XSTR(CP_VERSION_MINOR)"."XSTR(CP_VERSION_RELEASE);
49
49
 
50
50
  void
51
51
  cpInitChipmunk(void)
52
52
  {
53
- #ifndef NDEBUG
54
- printf("Initializing Chipmunk v%s (Debug Enabled)\n", cpVersionString);
55
- printf("Compile with -DNDEBUG defined to disable debug mode and runtime assertion checks\n");
56
- #endif
57
-
58
- cpInitCollisionFuncs();
53
+ cpAssertWarn(cpFalse, "cpInitChipmunk is deprecated and no longer required. It will be removed in the future.");
59
54
  }
60
55
 
56
+ //MARK: Misc Functions
57
+
61
58
  cpFloat
62
59
  cpMomentForCircle(cpFloat m, cpFloat r1, cpFloat r2, cpVect offset)
63
60
  {
@@ -67,22 +64,20 @@ cpMomentForCircle(cpFloat m, cpFloat r1, cpFloat r2, cpVect offset)
67
64
  cpFloat
68
65
  cpAreaForCircle(cpFloat r1, cpFloat r2)
69
66
  {
70
- return 2.0f*(cpFloat)M_PI*cpfabs(r1*r1 - r2*r2);
67
+ return (cpFloat)M_PI*cpfabs(r1*r1 - r2*r2);
71
68
  }
72
69
 
73
70
  cpFloat
74
71
  cpMomentForSegment(cpFloat m, cpVect a, cpVect b)
75
72
  {
76
- cpFloat length = cpvlength(cpvsub(b, a));
77
- cpVect offset = cpvmult(cpvadd(a, b), 1.0f/2.0f);
78
-
79
- return m*(length*length/12.0f + cpvlengthsq(offset));
73
+ cpVect offset = cpvmult(cpvadd(a, b), 0.5f);
74
+ return m*(cpvdistsq(b, a)/12.0f + cpvlengthsq(offset));
80
75
  }
81
76
 
82
77
  cpFloat
83
78
  cpAreaForSegment(cpVect a, cpVect b, cpFloat r)
84
79
  {
85
- return 2.0f*r*((cpFloat)M_PI*r + cpvdist(a, b));
80
+ return r*((cpFloat)M_PI*r + 2.0f*cpvdist(a, b));
86
81
  }
87
82
 
88
83
  cpFloat
@@ -112,7 +107,7 @@ cpAreaForPoly(const int numVerts, const cpVect *verts)
112
107
  area += cpvcross(verts[i], verts[(i+1)%numVerts]);
113
108
  }
114
109
 
115
- return area/2.0f;
110
+ return -area/2.0f;
116
111
  }
117
112
 
118
113
  cpVect
@@ -148,4 +143,180 @@ cpMomentForBox(cpFloat m, cpFloat width, cpFloat height)
148
143
  return m*(width*width + height*height)/12.0f;
149
144
  }
150
145
 
146
+ cpFloat
147
+ cpMomentForBox2(cpFloat m, cpBB box)
148
+ {
149
+ cpFloat width = box.r - box.l;
150
+ cpFloat height = box.t - box.b;
151
+ cpVect offset = cpvmult(cpv(box.l + box.r, box.b + box.t), 0.5f);
152
+
153
+ // TODO NaN when offset is 0 and m is INFINITY
154
+ return cpMomentForBox(m, width, height) + m*cpvlengthsq(offset);
155
+ }
156
+
157
+ //MARK: Quick Hull
158
+
159
+ void
160
+ cpLoopIndexes(cpVect *verts, int count, int *start, int *end)
161
+ {
162
+ (*start) = (*end) = 0;
163
+ cpVect min = verts[0];
164
+ cpVect max = min;
165
+
166
+ for(int i=1; i<count; i++){
167
+ cpVect v = verts[i];
168
+
169
+ if(v.x < min.x || (v.x == min.x && v.y < min.y)){
170
+ min = v;
171
+ (*start) = i;
172
+ } else if(v.x > max.x || (v.x == max.x && v.y > max.y)){
173
+ max = v;
174
+ (*end) = i;
175
+ }
176
+ }
177
+ }
178
+
179
+ #define SWAP(__A__, __B__) {cpVect __TMP__ = __A__; __A__ = __B__; __B__ = __TMP__;}
180
+
181
+ static int
182
+ QHullPartition(cpVect *verts, int count, cpVect a, cpVect b, cpFloat tol)
183
+ {
184
+ if(count == 0) return 0;
185
+
186
+ cpFloat max = 0;
187
+ int pivot = 0;
188
+
189
+ cpVect delta = cpvsub(b, a);
190
+ cpFloat valueTol = tol*cpvlength(delta);
191
+
192
+ int head = 0;
193
+ for(int tail = count-1; head <= tail;){
194
+ cpFloat value = cpvcross(delta, cpvsub(verts[head], a));
195
+ if(value > valueTol){
196
+ if(value > max){
197
+ max = value;
198
+ pivot = head;
199
+ }
200
+
201
+ head++;
202
+ } else {
203
+ SWAP(verts[head], verts[tail]);
204
+ tail--;
205
+ }
206
+ }
207
+
208
+ // move the new pivot to the front if it's not already there.
209
+ if(pivot != 0) SWAP(verts[0], verts[pivot]);
210
+ return head;
211
+ }
212
+
213
+ static int
214
+ QHullReduce(cpFloat tol, cpVect *verts, int count, cpVect a, cpVect pivot, cpVect b, cpVect *result)
215
+ {
216
+ if(count < 0){
217
+ return 0;
218
+ } else if(count == 0) {
219
+ result[0] = pivot;
220
+ return 1;
221
+ } else {
222
+ int left_count = QHullPartition(verts, count, a, pivot, tol);
223
+ int index = QHullReduce(tol, verts + 1, left_count - 1, a, verts[0], pivot, result);
224
+
225
+ result[index++] = pivot;
226
+
227
+ int right_count = QHullPartition(verts + left_count, count - left_count, pivot, b, tol);
228
+ return index + QHullReduce(tol, verts + left_count + 1, right_count - 1, pivot, verts[left_count], b, result + index);
229
+ }
230
+ }
231
+
232
+ // QuickHull seemed like a neat algorithm, and efficient-ish for large input sets.
233
+ // My implementation performs an in place reduction using the result array as scratch space.
234
+ int
235
+ cpConvexHull(int count, cpVect *verts, cpVect *result, int *first, cpFloat tol)
236
+ {
237
+ if(result){
238
+ // Copy the line vertexes into the empty part of the result polyline to use as a scratch buffer.
239
+ memcpy(result, verts, count*sizeof(cpVect));
240
+ } else {
241
+ // If a result array was not specified, reduce the input instead.
242
+ result = verts;
243
+ }
244
+
245
+ // Degenerate case, all poins are the same.
246
+ int start, end;
247
+ cpLoopIndexes(verts, count, &start, &end);
248
+ if(start == end){
249
+ if(first) (*first) = 0;
250
+ return 1;
251
+ }
252
+
253
+ SWAP(result[0], result[start]);
254
+ SWAP(result[1], result[end == 0 ? start : end]);
255
+
256
+ cpVect a = result[0];
257
+ cpVect b = result[1];
258
+
259
+ if(first) (*first) = start;
260
+ int resultCount = QHullReduce(tol, result + 2, count - 2, a, b, a, result + 1) + 1;
261
+ cpAssertSoft(cpPolyValidate(result, resultCount),
262
+ "Internal error: cpConvexHull() and cpPolyValidate() did not agree."
263
+ "Please report this error with as much info as you can.");
264
+ return resultCount;
265
+ }
266
+
267
+ //MARK: Alternate Block Iterators
268
+
269
+ #if defined(__has_extension)
270
+ #if __has_extension(blocks)
271
+
272
+ static void IteratorFunc(void *ptr, void (^block)(void *ptr)){block(ptr);}
273
+
274
+ void cpSpaceEachBody_b(cpSpace *space, void (^block)(cpBody *body)){
275
+ cpSpaceEachBody(space, (cpSpaceBodyIteratorFunc)IteratorFunc, block);
276
+ }
277
+
278
+ void cpSpaceEachShape_b(cpSpace *space, void (^block)(cpShape *shape)){
279
+ cpSpaceEachShape(space, (cpSpaceShapeIteratorFunc)IteratorFunc, block);
280
+ }
281
+
282
+ void cpSpaceEachConstraint_b(cpSpace *space, void (^block)(cpConstraint *constraint)){
283
+ cpSpaceEachConstraint(space, (cpSpaceConstraintIteratorFunc)IteratorFunc, block);
284
+ }
285
+
286
+ static void BodyIteratorFunc(cpBody *body, void *ptr, void (^block)(void *ptr)){block(ptr);}
287
+
288
+ void cpBodyEachShape_b(cpBody *body, void (^block)(cpShape *shape)){
289
+ cpBodyEachShape(body, (cpBodyShapeIteratorFunc)BodyIteratorFunc, block);
290
+ }
291
+
292
+ void cpBodyEachConstraint_b(cpBody *body, void (^block)(cpConstraint *constraint)){
293
+ cpBodyEachConstraint(body, (cpBodyConstraintIteratorFunc)BodyIteratorFunc, block);
294
+ }
295
+
296
+ void cpBodyEachArbiter_b(cpBody *body, void (^block)(cpArbiter *arbiter)){
297
+ cpBodyEachArbiter(body, (cpBodyArbiterIteratorFunc)BodyIteratorFunc, block);
298
+ }
299
+
300
+ static void NearestPointQueryIteratorFunc(cpShape *shape, cpFloat distance, cpVect point, cpSpaceNearestPointQueryBlock block){block(shape, distance, point);}
301
+ void cpSpaceNearestPointQuery_b(cpSpace *space, cpVect point, cpFloat maxDistance, cpLayers layers, cpGroup group, cpSpaceNearestPointQueryBlock block){
302
+ cpSpaceNearestPointQuery(space, point, maxDistance, layers, group, (cpSpaceNearestPointQueryFunc)NearestPointQueryIteratorFunc, block);
303
+ }
304
+
305
+ static void SegmentQueryIteratorFunc(cpShape *shape, cpFloat t, cpVect n, cpSpaceSegmentQueryBlock block){block(shape, t, n);}
306
+ void cpSpaceSegmentQuery_b(cpSpace *space, cpVect start, cpVect end, cpLayers layers, cpGroup group, cpSpaceSegmentQueryBlock block){
307
+ cpSpaceSegmentQuery(space, start, end, layers, group, (cpSpaceSegmentQueryFunc)SegmentQueryIteratorFunc, block);
308
+ }
309
+
310
+ void cpSpaceBBQuery_b(cpSpace *space, cpBB bb, cpLayers layers, cpGroup group, cpSpaceBBQueryBlock block){
311
+ cpSpaceBBQuery(space, bb, layers, group, (cpSpaceBBQueryFunc)IteratorFunc, block);
312
+ }
313
+
314
+ static void ShapeQueryIteratorFunc(cpShape *shape, cpContactPointSet *points, cpSpaceShapeQueryBlock block){block(shape, points);}
315
+ cpBool cpSpaceShapeQuery_b(cpSpace *space, cpShape *shape, cpSpaceShapeQueryBlock block){
316
+ return cpSpaceShapeQuery(space, shape, (cpSpaceShapeQueryFunc)ShapeQueryIteratorFunc, block);
317
+ }
318
+
319
+ #endif
320
+ #endif
321
+
151
322
  #include "chipmunk_ffi.h"
@@ -22,12 +22,15 @@
22
22
  #ifndef CHIPMUNK_HEADER
23
23
  #define CHIPMUNK_HEADER
24
24
 
25
+ #include <stdlib.h>
26
+ #include <math.h>
27
+
25
28
  #ifdef __cplusplus
26
29
  extern "C" {
27
30
  #endif
28
31
 
29
32
  #ifndef CP_ALLOW_PRIVATE_ACCESS
30
- #define CP_ALLOW_PRIVATE_ACCESS 1
33
+ #define CP_ALLOW_PRIVATE_ACCESS 0
31
34
  #endif
32
35
 
33
36
  #if CP_ALLOW_PRIVATE_ACCESS == 1
@@ -36,119 +39,172 @@ extern "C" {
36
39
  #define CP_PRIVATE(symbol) symbol##_private
37
40
  #endif
38
41
 
39
- void cpMessage(const char *message, const char *condition, const char *file, int line, int isError);
42
+ void cpMessage(const char *condition, const char *file, int line, int isError, int isHardError, const char *message, ...);
40
43
  #ifdef NDEBUG
41
- #define cpAssertWarn(condition, message)
44
+ #define cpAssertWarn(condition, ...)
42
45
  #else
43
- #define cpAssertWarn(condition, message) if(!(condition)) cpMessage(message, #condition, __FILE__, __LINE__, 0)
46
+ #define cpAssertWarn(condition, ...) if(!(condition)) cpMessage(#condition, __FILE__, __LINE__, 0, 0, __VA_ARGS__)
44
47
  #endif
45
48
 
46
49
  #ifdef NDEBUG
47
- #define cpAssert(condition, message)
50
+ #define cpAssertSoft(condition, ...)
48
51
  #else
49
- #define cpAssert(condition, message) if(!(condition)) cpMessage(message, #condition, __FILE__, __LINE__, 1)
52
+ #define cpAssertSoft(condition, ...) if(!(condition)) cpMessage(#condition, __FILE__, __LINE__, 1, 0, __VA_ARGS__)
50
53
  #endif
51
54
 
55
+ // Hard assertions are important and cheap to execute. They are not disabled by compiling as debug.
56
+ #define cpAssertHard(condition, ...) if(!(condition)) cpMessage(#condition, __FILE__, __LINE__, 1, 1, __VA_ARGS__)
57
+
58
+
52
59
  #include "chipmunk_types.h"
53
60
 
54
- #ifndef INFINITY
55
- #ifdef _MSC_VER
56
- union MSVC_EVIL_FLOAT_HACK
57
- {
58
- unsigned __int8 Bytes[4];
59
- float Value;
60
- };
61
- static union MSVC_EVIL_FLOAT_HACK INFINITY_HACK = {{0x00, 0x00, 0x80, 0x7F}};
62
- #define INFINITY (INFINITY_HACK.Value)
63
- #endif
64
-
65
- #ifdef __GNUC__
66
- #define INFINITY (__builtin_inf())
67
- #endif
68
-
69
- #ifndef INFINITY
70
- #define INFINITY (1e1000)
71
- #endif
61
+ /// @defgroup misc Misc
62
+ /// @{
63
+
64
+ /// Allocated size for various Chipmunk buffers
65
+ #ifndef CP_BUFFER_BYTES
66
+ #define CP_BUFFER_BYTES (32*1024)
67
+ #endif
68
+
69
+ #ifndef cpcalloc
70
+ /// Chipmunk calloc() alias.
71
+ #define cpcalloc calloc
72
+ #endif
73
+
74
+ #ifndef cprealloc
75
+ /// Chipmunk realloc() alias.
76
+ #define cprealloc realloc
77
+ #endif
78
+
79
+ #ifndef cpfree
80
+ /// Chipmunk free() alias.
81
+ #define cpfree free
72
82
  #endif
73
83
 
74
- // Maximum allocated size for various Chipmunk buffers
75
- #define CP_BUFFER_BYTES (32*1024)
84
+ typedef struct cpArray cpArray;
85
+ typedef struct cpHashSet cpHashSet;
86
+
87
+ typedef struct cpBody cpBody;
88
+ typedef struct cpShape cpShape;
89
+ typedef struct cpConstraint cpConstraint;
90
+
91
+ typedef struct cpCollisionHandler cpCollisionHandler;
92
+ typedef struct cpArbiter cpArbiter;
76
93
 
77
- #define cpmalloc malloc
78
- #define cpcalloc calloc
79
- #define cprealloc realloc
80
- #define cpfree free
94
+ typedef struct cpSpace cpSpace;
81
95
 
82
96
  #include "cpVect.h"
83
97
  #include "cpBB.h"
84
- #include "cpArray.h"
85
- #include "cpHashSet.h"
86
- #include "cpSpaceHash.h"
98
+ #include "cpSpatialIndex.h"
87
99
 
88
100
  #include "cpBody.h"
89
101
  #include "cpShape.h"
90
102
  #include "cpPolyShape.h"
91
103
 
92
- #include "cpArbiter.h"
93
- #include "cpCollision.h"
94
-
104
+ #include "cpArbiter.h"
95
105
  #include "constraints/cpConstraint.h"
96
106
 
97
107
  #include "cpSpace.h"
98
108
 
99
- #define CP_HASH_COEF (3344921057ul)
100
- #define CP_HASH_PAIR(A, B) ((cpHashValue)(A)*CP_HASH_COEF ^ (cpHashValue)(B)*CP_HASH_COEF)
109
+ // Chipmunk 6.1.3
110
+ #define CP_VERSION_MAJOR 6
111
+ #define CP_VERSION_MINOR 1
112
+ #define CP_VERSION_RELEASE 3
101
113
 
114
+ /// Version string.
102
115
  extern const char *cpVersionString;
116
+
117
+ /// @deprecated
103
118
  void cpInitChipmunk(void);
104
119
 
105
- /**
106
- Calculate the moment of inertia for a circle.
107
- r1 and r2 are the inner and outer diameters. A solid circle has an inner diameter of 0.
108
- */
120
+ /// Enables segment to segment shape collisions.
121
+ void cpEnableSegmentToSegmentCollisions(void);
122
+
123
+
124
+ /// Calculate the moment of inertia for a circle.
125
+ /// @c r1 and @c r2 are the inner and outer diameters. A solid circle has an inner diameter of 0.
109
126
  cpFloat cpMomentForCircle(cpFloat m, cpFloat r1, cpFloat r2, cpVect offset);
110
127
 
111
- /**
112
- Calculate area of a hollow circle.
113
- */
128
+ /// Calculate area of a hollow circle.
129
+ /// @c r1 and @c r2 are the inner and outer diameters. A solid circle has an inner diameter of 0.
114
130
  cpFloat cpAreaForCircle(cpFloat r1, cpFloat r2);
115
131
 
116
- /**
117
- Calculate the moment of inertia for a line segment.
118
- Beveling radius is not supported.
119
- */
132
+ /// Calculate the moment of inertia for a line segment.
133
+ /// Beveling radius is not supported.
120
134
  cpFloat cpMomentForSegment(cpFloat m, cpVect a, cpVect b);
121
135
 
122
- /**
123
- Calculate the area of a fattened (capsule shaped) line segment.
124
- */
136
+ /// Calculate the area of a fattened (capsule shaped) line segment.
125
137
  cpFloat cpAreaForSegment(cpVect a, cpVect b, cpFloat r);
126
138
 
127
- /**
128
- 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.
129
- */
139
+ /// 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.
130
140
  cpFloat cpMomentForPoly(cpFloat m, int numVerts, const cpVect *verts, cpVect offset);
131
141
 
132
- /**
133
- Calculate the signed area of a polygon.
134
- */
142
+ /// Calculate the signed area of a polygon. A Clockwise winding gives positive area.
143
+ /// This is probably backwards from what you expect, but matches Chipmunk's the winding for poly shapes.
135
144
  cpFloat cpAreaForPoly(const int numVerts, const cpVect *verts);
136
145
 
137
- /**
138
- Calculate the natural centroid of a polygon.
139
- */
146
+ /// Calculate the natural centroid of a polygon.
140
147
  cpVect cpCentroidForPoly(const int numVerts, const cpVect *verts);
141
148
 
142
- /**
143
- Center the polygon on the origin. (Subtracts the centroid of the polygon from each vertex)
144
- */
149
+ /// Center the polygon on the origin. (Subtracts the centroid of the polygon from each vertex)
145
150
  void cpRecenterPoly(const int numVerts, cpVect *verts);
146
151
 
147
- /**
148
- Calculate the moment of inertia for a solid box.
149
- */
152
+ /// Calculate the moment of inertia for a solid box.
150
153
  cpFloat cpMomentForBox(cpFloat m, cpFloat width, cpFloat height);
151
154
 
155
+ /// Calculate the moment of inertia for a solid box.
156
+ cpFloat cpMomentForBox2(cpFloat m, cpBB box);
157
+
158
+ /// Calculate the convex hull of a given set of points. Returns the count of points in the hull.
159
+ /// @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.
160
+ /// @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])
161
+ /// @c tol is the allowed amount to shrink the hull when simplifying it. A tolerance of 0.0 creates an exact hull.
162
+ int cpConvexHull(int count, cpVect *verts, cpVect *result, int *first, cpFloat tol);
163
+
164
+ #ifdef _MSC_VER
165
+ #include "malloc.h"
166
+ #endif
167
+
168
+ /// Convenience macro to work with cpConvexHull.
169
+ /// @c count and @c verts is the input array passed to cpConvexHull().
170
+ /// @c count_var and @c verts_var are the names of the variables the macro creates to store the result.
171
+ /// 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.
172
+ #define CP_CONVEX_HULL(__count__, __verts__, __count_var__, __verts_var__) \
173
+ cpVect *__verts_var__ = (cpVect *)alloca(__count__*sizeof(cpVect)); \
174
+ int __count_var__ = cpConvexHull(__count__, __verts__, __verts_var__, NULL, 0.0); \
175
+
176
+ #if defined(__has_extension)
177
+ #if __has_extension(blocks)
178
+ // Define alternate block based alternatives for a few of the callback heavy functions.
179
+ // Collision handlers are post-step callbacks are not included to avoid memory management issues.
180
+ // If you want to use blocks for those and are aware of how to correctly manage the memory, the implementation is trivial.
181
+
182
+ void cpSpaceEachBody_b(cpSpace *space, void (^block)(cpBody *body));
183
+ void cpSpaceEachShape_b(cpSpace *space, void (^block)(cpShape *shape));
184
+ void cpSpaceEachConstraint_b(cpSpace *space, void (^block)(cpConstraint *constraint));
185
+
186
+ void cpBodyEachShape_b(cpBody *body, void (^block)(cpShape *shape));
187
+ void cpBodyEachConstraint_b(cpBody *body, void (^block)(cpConstraint *constraint));
188
+ void cpBodyEachArbiter_b(cpBody *body, void (^block)(cpArbiter *arbiter));
189
+
190
+ typedef void (^cpSpaceNearestPointQueryBlock)(cpShape *shape, cpFloat distance, cpVect point);
191
+ void cpSpaceNearestPointQuery_b(cpSpace *space, cpVect point, cpFloat maxDistance, cpLayers layers, cpGroup group, cpSpaceNearestPointQueryBlock block);
192
+
193
+ typedef void (^cpSpaceSegmentQueryBlock)(cpShape *shape, cpFloat t, cpVect n);
194
+ void cpSpaceSegmentQuery_b(cpSpace *space, cpVect start, cpVect end, cpLayers layers, cpGroup group, cpSpaceSegmentQueryBlock block);
195
+
196
+ typedef void (^cpSpaceBBQueryBlock)(cpShape *shape);
197
+ void cpSpaceBBQuery_b(cpSpace *space, cpBB bb, cpLayers layers, cpGroup group, cpSpaceBBQueryBlock block);
198
+
199
+ typedef void (^cpSpaceShapeQueryBlock)(cpShape *shape, cpContactPointSet *points);
200
+ cpBool cpSpaceShapeQuery_b(cpSpace *space, cpShape *shape, cpSpaceShapeQueryBlock block);
201
+
202
+ #endif
203
+ #endif
204
+
205
+
206
+ //@}
207
+
152
208
  #ifdef __cplusplus
153
209
  }
154
210
 
@@ -159,5 +215,4 @@ static inline cpBool operator ==(const cpVect v1, const cpVect v2){return cpveql
159
215
  static inline cpVect operator -(const cpVect v){return cpvneg(v);}
160
216
 
161
217
  #endif
162
-
163
218
  #endif