chipmunk 5.3.4.5 → 6.1.3.0.rc1

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.
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