1 /* Copyright (c) 2013 Scott Lembcke and Howling Moon Software
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 #ifndef CHIPMUNK_H
23 #define CHIPMUNK_H
24
25 #include <stdlib.h>
26 #include <math.h>
27
28 #ifdef WIN32
29 // For alloca().
30 #include <malloc.h>
31 #define CP_EXPORT __declspec(dllexport)
32 #elif defined(__DragonFly__) || defined(__FreeBSD__) \
33 || defined(__NetBSD__) || defined(__OpenBSD__) \
34 // alloca() is already included in <stdlib.h>
35 #define CP_EXPORT
36 #else
37 #include <alloca.h>
38 #define CP_EXPORT
39 #endif
40
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44
45 // NUKE
46 #ifndef CP_ALLOW_PRIVATE_ACCESS
47 #define CP_ALLOW_PRIVATE_ACCESS 0
48 #endif
49
50 #if CP_ALLOW_PRIVATE_ACCESS == 1
51 #define CP_PRIVATE(__symbol__) __symbol__
52 #else
53 #define CP_PRIVATE(__symbol__) __symbol__##_private
54 #endif
55
56 CP_EXPORT void cpMessage(const char *condition, const char *file, int line, int isError, int isHardError, const char *message, ...);
57 #ifdef NDEBUG
58 #define cpAssertWarn(__condition__, ...)
59 #define cpAssertSoft(__condition__, ...)
60 #else
61 #define cpAssertSoft(__condition__, ...) if(!(__condition__)){cpMessage(#__condition__, __FILE__, __LINE__, 1, 0, __VA_ARGS__); abort();}
62 #define cpAssertWarn(__condition__, ...) if(!(__condition__)) cpMessage(#__condition__, __FILE__, __LINE__, 0, 0, __VA_ARGS__)
63 #endif
64
65 // Hard assertions are used in situations where the program definitely will crash anyway, and the reason is inexpensive to detect.
66 #define cpAssertHard(__condition__, ...) if(!(__condition__)){cpMessage(#__condition__, __FILE__, __LINE__, 1, 1, __VA_ARGS__); abort();}
67
68 #include "chipmunk_types.h"
69
70 /// @defgroup misc Misc
71 /// @{
72
73 /// Allocated size for various Chipmunk buffers
74 #ifndef CP_BUFFER_BYTES
75 #define CP_BUFFER_BYTES (32*1024)
76 #endif
77
78 #ifndef cpcalloc
79 /// Chipmunk calloc() alias.
80 #define cpcalloc calloc
81 #endif
82
83 #ifndef cprealloc
84 /// Chipmunk realloc() alias.
85 #define cprealloc realloc
86 #endif
87
88 #ifndef cpfree
89 /// Chipmunk free() alias.
90 #define cpfree free
91 #endif
92
93 typedef struct cpArray cpArray;
94 typedef struct cpHashSet cpHashSet;
95
96 typedef struct cpBody cpBody;
97
98 typedef struct cpShape cpShape;
99 typedef struct cpCircleShape cpCircleShape;
100 typedef struct cpSegmentShape cpSegmentShape;
101 typedef struct cpPolyShape cpPolyShape;
102
103 typedef struct cpConstraint cpConstraint;
104 typedef struct cpPinJoint cpPinJoint;
105 typedef struct cpSlideJoint cpSlideJoint;
106 typedef struct cpPivotJoint cpPivotJoint;
107 typedef struct cpGrooveJoint cpGrooveJoint;
108 typedef struct cpDampedSpring cpDampedSpring;
109 typedef struct cpDampedRotarySpring cpDampedRotarySpring;
110 typedef struct cpRotaryLimitJoint cpRotaryLimitJoint;
111 typedef struct cpRatchetJoint cpRatchetJoint;
112 typedef struct cpGearJoint cpGearJoint;
113 typedef struct cpSimpleMotorJoint cpSimpleMotorJoint;
114
115 typedef struct cpCollisionHandler cpCollisionHandler;
116 typedef struct cpContactPointSet cpContactPointSet;
117 typedef struct cpArbiter cpArbiter;
118
119 typedef struct cpSpace cpSpace;
120
121 #include "cpVect.h"
122 #include "cpBB.h"
123 #include "cpTransform.h"
124 #include "cpSpatialIndex.h"
125
126 #include "cpArbiter.h"
127
128 #include "cpBody.h"
129 #include "cpShape.h"
130 #include "cpPolyShape.h"
131
132 #include "cpConstraint.h"
133
134 #include "cpSpace.h"
135
136 // Chipmunk 7.0.1
137 #define CP_VERSION_MAJOR 7
138 #define CP_VERSION_MINOR 0
139 #define CP_VERSION_RELEASE 1
140
141 /// Version string.
142 CP_EXPORT extern const char *cpVersionString;
143
144 /// Calculate the moment of inertia for a circle.
145 /// @c r1 and @c r2 are the inner and outer diameters. A solid circle has an inner diameter of 0.
146 CP_EXPORT cpFloat cpMomentForCircle(cpFloat m, cpFloat r1, cpFloat r2, cpVect offset);
147
148 /// Calculate area of a hollow circle.
149 /// @c r1 and @c r2 are the inner and outer diameters. A solid circle has an inner diameter of 0.
150 CP_EXPORT cpFloat cpAreaForCircle(cpFloat r1, cpFloat r2);
151
152 /// Calculate the moment of inertia for a line segment.
153 /// Beveling radius is not supported.
154 CP_EXPORT cpFloat cpMomentForSegment(cpFloat m, cpVect a, cpVect b, cpFloat radius);
155
156 /// Calculate the area of a fattened (capsule shaped) line segment.
157 CP_EXPORT cpFloat cpAreaForSegment(cpVect a, cpVect b, cpFloat radius);
158
159 /// 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.
160 CP_EXPORT cpFloat cpMomentForPoly(cpFloat m, int count, const cpVect *verts, cpVect offset, cpFloat radius);
161
162 /// Calculate the signed area of a polygon. A Clockwise winding gives positive area.
163 /// This is probably backwards from what you expect, but matches Chipmunk's the winding for poly shapes.
164 CP_EXPORT cpFloat cpAreaForPoly(const int count, const cpVect *verts, cpFloat radius);
165
166 /// Calculate the natural centroid of a polygon.
167 CP_EXPORT cpVect cpCentroidForPoly(const int count, const cpVect *verts);
168
169 /// Calculate the moment of inertia for a solid box.
170 CP_EXPORT cpFloat cpMomentForBox(cpFloat m, cpFloat width, cpFloat height);
171
172 /// Calculate the moment of inertia for a solid box.
173 CP_EXPORT cpFloat cpMomentForBox2(cpFloat m, cpBB box);
174
175 /// Calculate the convex hull of a given set of points. Returns the count of points in the hull.
176 /// @c result must be a pointer to a @c cpVect array with at least @c count elements. If @c verts == @c result, then @c verts will be reduced inplace.
177 /// @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])
178 /// @c tol is the allowed amount to shrink the hull when simplifying it. A tolerance of 0.0 creates an exact hull.
179 CP_EXPORT int cpConvexHull(int count, const cpVect *verts, cpVect *result, int *first, cpFloat tol);
180
181 #ifdef _MSC_VER
182 #include "malloc.h"
183 #endif
184
185 /// Convenience macro to work with cpConvexHull.
186 /// @c count and @c verts is the input array passed to cpConvexHull().
187 /// @c count_var and @c verts_var are the names of the variables the macro creates to store the result.
188 /// 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.
189 #define CP_CONVEX_HULL(__count__, __verts__, __count_var__, __verts_var__) \
190 cpVect *__verts_var__ = (cpVect *)alloca(__count__*sizeof(cpVect)); \
191 int __count_var__ = cpConvexHull(__count__, __verts__, __verts_var__, NULL, 0.0); \
192
193 /// Returns the closest point on the line segment ab, to the point p.
194 static inline cpVect
cpClosetPointOnSegment(const cpVect p,const cpVect a,const cpVect b)195 cpClosetPointOnSegment(const cpVect p, const cpVect a, const cpVect b)
196 {
197 cpVect delta = cpvsub(a, b);
198 cpFloat t = cpfclamp01(cpvdot(delta, cpvsub(p, b))/cpvlengthsq(delta));
199 return cpvadd(b, cpvmult(delta, t));
200 }
201
202 #if defined(__has_extension)
203 #if __has_extension(blocks)
204 // Define alternate block based alternatives for a few of the callback heavy functions.
205 // Collision handlers are post-step callbacks are not included to avoid memory management issues.
206 // If you want to use blocks for those and are aware of how to correctly manage the memory, the implementation is trivial.
207
208 void cpSpaceEachBody_b(cpSpace *space, void (^block)(cpBody *body));
209 void cpSpaceEachShape_b(cpSpace *space, void (^block)(cpShape *shape));
210 void cpSpaceEachConstraint_b(cpSpace *space, void (^block)(cpConstraint *constraint));
211
212 void cpBodyEachShape_b(cpBody *body, void (^block)(cpShape *shape));
213 void cpBodyEachConstraint_b(cpBody *body, void (^block)(cpConstraint *constraint));
214 void cpBodyEachArbiter_b(cpBody *body, void (^block)(cpArbiter *arbiter));
215
216 typedef void (^cpSpacePointQueryBlock)(cpShape *shape, cpVect point, cpFloat distance, cpVect gradient);
217 void cpSpacePointQuery_b(cpSpace *space, cpVect point, cpFloat maxDistance, cpShapeFilter filter, cpSpacePointQueryBlock block);
218
219 typedef void (^cpSpaceSegmentQueryBlock)(cpShape *shape, cpVect point, cpVect normal, cpFloat alpha);
220 void cpSpaceSegmentQuery_b(cpSpace *space, cpVect start, cpVect end, cpFloat radius, cpShapeFilter filter, cpSpaceSegmentQueryBlock block);
221
222 typedef void (^cpSpaceBBQueryBlock)(cpShape *shape);
223 void cpSpaceBBQuery_b(cpSpace *space, cpBB bb, cpShapeFilter filter, cpSpaceBBQueryBlock block);
224
225 typedef void (^cpSpaceShapeQueryBlock)(cpShape *shape, cpContactPointSet *points);
226 cpBool cpSpaceShapeQuery_b(cpSpace *space, cpShape *shape, cpSpaceShapeQueryBlock block);
227
228 #endif
229 #endif
230
231
232 //@}
233
234 #ifdef __cplusplus
235 }
236
237 static inline cpVect operator *(const cpVect v, const cpFloat s){return cpvmult(v, s);}
238 static inline cpVect operator +(const cpVect v1, const cpVect v2){return cpvadd(v1, v2);}
239 static inline cpVect operator -(const cpVect v1, const cpVect v2){return cpvsub(v1, v2);}
240 static inline cpBool operator ==(const cpVect v1, const cpVect v2){return cpveql(v1, v2);}
241 static inline cpVect operator -(const cpVect v){return cpvneg(v);}
242
243 #endif
244 #endif
245