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