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 /// @defgroup cpSpace cpSpace 23 /// @{ 24 25 //MARK: Definitions 26 27 /// Collision begin event function callback type. 28 /// Returning false from a begin callback causes the collision to be ignored until 29 /// the the separate callback is called when the objects stop colliding. 30 typedef cpBool (*cpCollisionBeginFunc)(cpArbiter *arb, cpSpace *space, cpDataPointer userData); 31 /// Collision pre-solve event function callback type. 32 /// Returning false from a pre-step callback causes the collision to be ignored until the next step. 33 typedef cpBool (*cpCollisionPreSolveFunc)(cpArbiter *arb, cpSpace *space, cpDataPointer userData); 34 /// Collision post-solve event function callback type. 35 typedef void (*cpCollisionPostSolveFunc)(cpArbiter *arb, cpSpace *space, cpDataPointer userData); 36 /// Collision separate event function callback type. 37 typedef void (*cpCollisionSeparateFunc)(cpArbiter *arb, cpSpace *space, cpDataPointer userData); 38 39 /// Struct that holds function callback pointers to configure custom collision handling. 40 /// Collision handlers have a pair of types; when a collision occurs between two shapes that have these types, the collision handler functions are triggered. 41 struct cpCollisionHandler { 42 /// Collision type identifier of the first shape that this handler recognizes. 43 /// In the collision handler callback, the shape with this type will be the first argument. Read only. 44 const cpCollisionType typeA; 45 /// Collision type identifier of the second shape that this handler recognizes. 46 /// In the collision handler callback, the shape with this type will be the second argument. Read only. 47 const cpCollisionType typeB; 48 /// This function is called when two shapes with types that match this collision handler begin colliding. 49 cpCollisionBeginFunc beginFunc; 50 /// This function is called each step when two shapes with types that match this collision handler are colliding. 51 /// It's called before the collision solver runs so that you can affect a collision's outcome. 52 cpCollisionPreSolveFunc preSolveFunc; 53 /// This function is called each step when two shapes with types that match this collision handler are colliding. 54 /// It's called after the collision solver runs so that you can read back information about the collision to trigger events in your game. 55 cpCollisionPostSolveFunc postSolveFunc; 56 /// This function is called when two shapes with types that match this collision handler stop colliding. 57 cpCollisionSeparateFunc separateFunc; 58 /// This is a user definable context pointer that is passed to all of the collision handler functions. 59 cpDataPointer userData; 60 }; 61 62 // TODO: Make timestep a parameter? 63 64 65 //MARK: Memory and Initialization 66 67 /// Allocate a cpSpace. 68 CP_EXPORT cpSpace* cpSpaceAlloc(void); 69 /// Initialize a cpSpace. 70 CP_EXPORT cpSpace* cpSpaceInit(cpSpace *space); 71 /// Allocate and initialize a cpSpace. 72 CP_EXPORT cpSpace* cpSpaceNew(void); 73 74 /// Destroy a cpSpace. 75 CP_EXPORT void cpSpaceDestroy(cpSpace *space); 76 /// Destroy and free a cpSpace. 77 CP_EXPORT void cpSpaceFree(cpSpace *space); 78 79 80 //MARK: Properties 81 82 /// Number of iterations to use in the impulse solver to solve contacts and other constraints. 83 CP_EXPORT int cpSpaceGetIterations(const cpSpace *space); 84 CP_EXPORT void cpSpaceSetIterations(cpSpace *space, int iterations); 85 86 /// Gravity to pass to rigid bodies when integrating velocity. 87 CP_EXPORT cpVect cpSpaceGetGravity(const cpSpace *space); 88 CP_EXPORT void cpSpaceSetGravity(cpSpace *space, cpVect gravity); 89 90 /// Damping rate expressed as the fraction of velocity bodies retain each second. 91 /// A value of 0.9 would mean that each body's velocity will drop 10% per second. 92 /// The default value is 1.0, meaning no damping is applied. 93 /// @note This damping value is different than those of cpDampedSpring and cpDampedRotarySpring. 94 CP_EXPORT cpFloat cpSpaceGetDamping(const cpSpace *space); 95 CP_EXPORT void cpSpaceSetDamping(cpSpace *space, cpFloat damping); 96 97 /// Speed threshold for a body to be considered idle. 98 /// The default value of 0 means to let the space guess a good threshold based on gravity. 99 CP_EXPORT cpFloat cpSpaceGetIdleSpeedThreshold(const cpSpace *space); 100 CP_EXPORT void cpSpaceSetIdleSpeedThreshold(cpSpace *space, cpFloat idleSpeedThreshold); 101 102 /// Time a group of bodies must remain idle in order to fall asleep. 103 /// Enabling sleeping also implicitly enables the the contact graph. 104 /// The default value of INFINITY disables the sleeping algorithm. 105 CP_EXPORT cpFloat cpSpaceGetSleepTimeThreshold(const cpSpace *space); 106 CP_EXPORT void cpSpaceSetSleepTimeThreshold(cpSpace *space, cpFloat sleepTimeThreshold); 107 108 /// Amount of encouraged penetration between colliding shapes. 109 /// Used to reduce oscillating contacts and keep the collision cache warm. 110 /// Defaults to 0.1. If you have poor simulation quality, 111 /// increase this number as much as possible without allowing visible amounts of overlap. 112 CP_EXPORT cpFloat cpSpaceGetCollisionSlop(const cpSpace *space); 113 CP_EXPORT void cpSpaceSetCollisionSlop(cpSpace *space, cpFloat collisionSlop); 114 115 /// Determines how fast overlapping shapes are pushed apart. 116 /// Expressed as a fraction of the error remaining after each second. 117 /// Defaults to pow(1.0 - 0.1, 60.0) meaning that Chipmunk fixes 10% of overlap each frame at 60Hz. 118 CP_EXPORT cpFloat cpSpaceGetCollisionBias(const cpSpace *space); 119 CP_EXPORT void cpSpaceSetCollisionBias(cpSpace *space, cpFloat collisionBias); 120 121 /// Number of frames that contact information should persist. 122 /// Defaults to 3. There is probably never a reason to change this value. 123 CP_EXPORT cpTimestamp cpSpaceGetCollisionPersistence(const cpSpace *space); 124 CP_EXPORT void cpSpaceSetCollisionPersistence(cpSpace *space, cpTimestamp collisionPersistence); 125 126 /// User definable data pointer. 127 /// Generally this points to your game's controller or game state 128 /// class so you can access it when given a cpSpace reference in a callback. 129 CP_EXPORT cpDataPointer cpSpaceGetUserData(const cpSpace *space); 130 CP_EXPORT void cpSpaceSetUserData(cpSpace *space, cpDataPointer userData); 131 132 /// The Space provided static body for a given cpSpace. 133 /// This is merely provided for convenience and you are not required to use it. 134 CP_EXPORT cpBody* cpSpaceGetStaticBody(const cpSpace *space); 135 136 /// Returns the current (or most recent) time step used with the given space. 137 /// Useful from callbacks if your time step is not a compile-time global. 138 CP_EXPORT cpFloat cpSpaceGetCurrentTimeStep(const cpSpace *space); 139 140 /// returns true from inside a callback when objects cannot be added/removed. 141 CP_EXPORT cpBool cpSpaceIsLocked(cpSpace *space); 142 143 144 //MARK: Collision Handlers 145 146 /// Create or return the existing collision handler that is called for all collisions that are not handled by a more specific collision handler. 147 CP_EXPORT cpCollisionHandler *cpSpaceAddDefaultCollisionHandler(cpSpace *space); 148 /// Create or return the existing collision handler for the specified pair of collision types. 149 /// If wildcard handlers are used with either of the collision types, it's the responibility of the custom handler to invoke the wildcard handlers. 150 CP_EXPORT cpCollisionHandler *cpSpaceAddCollisionHandler(cpSpace *space, cpCollisionType a, cpCollisionType b); 151 /// Create or return the existing wildcard collision handler for the specified type. 152 CP_EXPORT cpCollisionHandler *cpSpaceAddWildcardHandler(cpSpace *space, cpCollisionType type); 153 154 155 //MARK: Add/Remove objects 156 157 /// Add a collision shape to the simulation. 158 /// If the shape is attached to a static body, it will be added as a static shape. 159 CP_EXPORT cpShape* cpSpaceAddShape(cpSpace *space, cpShape *shape); 160 /// Add a rigid body to the simulation. 161 CP_EXPORT cpBody* cpSpaceAddBody(cpSpace *space, cpBody *body); 162 /// Add a constraint to the simulation. 163 CP_EXPORT cpConstraint* cpSpaceAddConstraint(cpSpace *space, cpConstraint *constraint); 164 165 /// Remove a collision shape from the simulation. 166 CP_EXPORT void cpSpaceRemoveShape(cpSpace *space, cpShape *shape); 167 /// Remove a rigid body from the simulation. 168 CP_EXPORT void cpSpaceRemoveBody(cpSpace *space, cpBody *body); 169 /// Remove a constraint from the simulation. 170 CP_EXPORT void cpSpaceRemoveConstraint(cpSpace *space, cpConstraint *constraint); 171 172 /// Test if a collision shape has been added to the space. 173 CP_EXPORT cpBool cpSpaceContainsShape(cpSpace *space, cpShape *shape); 174 /// Test if a rigid body has been added to the space. 175 CP_EXPORT cpBool cpSpaceContainsBody(cpSpace *space, cpBody *body); 176 /// Test if a constraint has been added to the space. 177 CP_EXPORT cpBool cpSpaceContainsConstraint(cpSpace *space, cpConstraint *constraint); 178 179 //MARK: Post-Step Callbacks 180 181 /// Post Step callback function type. 182 typedef void (*cpPostStepFunc)(cpSpace *space, void *key, void *data); 183 /// Schedule a post-step callback to be called when cpSpaceStep() finishes. 184 /// You can only register one callback per unique value for @c key. 185 /// Returns true only if @c key has never been scheduled before. 186 /// It's possible to pass @c NULL for @c func if you only want to mark @c key as being used. 187 CP_EXPORT cpBool cpSpaceAddPostStepCallback(cpSpace *space, cpPostStepFunc func, void *key, void *data); 188 189 190 //MARK: Queries 191 192 // TODO: Queries and iterators should take a cpSpace parametery. 193 // TODO: They should also be abortable. 194 195 /// Nearest point query callback function type. 196 typedef void (*cpSpacePointQueryFunc)(cpShape *shape, cpVect point, cpFloat distance, cpVect gradient, void *data); 197 /// Query the space at a point and call @c func for each shape found. 198 CP_EXPORT void cpSpacePointQuery(cpSpace *space, cpVect point, cpFloat maxDistance, cpShapeFilter filter, cpSpacePointQueryFunc func, void *data); 199 /// Query the space at a point and return the nearest shape found. Returns NULL if no shapes were found. 200 CP_EXPORT cpShape *cpSpacePointQueryNearest(cpSpace *space, cpVect point, cpFloat maxDistance, cpShapeFilter filter, cpPointQueryInfo *out); 201 202 /// Segment query callback function type. 203 typedef void (*cpSpaceSegmentQueryFunc)(cpShape *shape, cpVect point, cpVect normal, cpFloat alpha, void *data); 204 /// Perform a directed line segment query (like a raycast) against the space calling @c func for each shape intersected. 205 CP_EXPORT void cpSpaceSegmentQuery(cpSpace *space, cpVect start, cpVect end, cpFloat radius, cpShapeFilter filter, cpSpaceSegmentQueryFunc func, void *data); 206 /// Perform a directed line segment query (like a raycast) against the space and return the first shape hit. Returns NULL if no shapes were hit. 207 CP_EXPORT cpShape *cpSpaceSegmentQueryFirst(cpSpace *space, cpVect start, cpVect end, cpFloat radius, cpShapeFilter filter, cpSegmentQueryInfo *out); 208 209 /// Rectangle Query callback function type. 210 typedef void (*cpSpaceBBQueryFunc)(cpShape *shape, void *data); 211 /// Perform a fast rectangle query on the space calling @c func for each shape found. 212 /// Only the shape's bounding boxes are checked for overlap, not their full shape. 213 CP_EXPORT void cpSpaceBBQuery(cpSpace *space, cpBB bb, cpShapeFilter filter, cpSpaceBBQueryFunc func, void *data); 214 215 /// Shape query callback function type. 216 typedef void (*cpSpaceShapeQueryFunc)(cpShape *shape, cpContactPointSet *points, void *data); 217 /// Query a space for any shapes overlapping the given shape and call @c func for each shape found. 218 CP_EXPORT cpBool cpSpaceShapeQuery(cpSpace *space, cpShape *shape, cpSpaceShapeQueryFunc func, void *data); 219 220 221 //MARK: Iteration 222 223 /// Space/body iterator callback function type. 224 typedef void (*cpSpaceBodyIteratorFunc)(cpBody *body, void *data); 225 /// Call @c func for each body in the space. 226 CP_EXPORT void cpSpaceEachBody(cpSpace *space, cpSpaceBodyIteratorFunc func, void *data); 227 228 /// Space/body iterator callback function type. 229 typedef void (*cpSpaceShapeIteratorFunc)(cpShape *shape, void *data); 230 /// Call @c func for each shape in the space. 231 CP_EXPORT void cpSpaceEachShape(cpSpace *space, cpSpaceShapeIteratorFunc func, void *data); 232 233 /// Space/constraint iterator callback function type. 234 typedef void (*cpSpaceConstraintIteratorFunc)(cpConstraint *constraint, void *data); 235 /// Call @c func for each shape in the space. 236 CP_EXPORT void cpSpaceEachConstraint(cpSpace *space, cpSpaceConstraintIteratorFunc func, void *data); 237 238 239 //MARK: Indexing 240 241 /// Update the collision detection info for the static shapes in the space. 242 CP_EXPORT void cpSpaceReindexStatic(cpSpace *space); 243 /// Update the collision detection data for a specific shape in the space. 244 CP_EXPORT void cpSpaceReindexShape(cpSpace *space, cpShape *shape); 245 /// Update the collision detection data for all shapes attached to a body. 246 CP_EXPORT void cpSpaceReindexShapesForBody(cpSpace *space, cpBody *body); 247 248 /// Switch the space to use a spatial has as it's spatial index. 249 CP_EXPORT void cpSpaceUseSpatialHash(cpSpace *space, cpFloat dim, int count); 250 251 252 //MARK: Time Stepping 253 254 /// Step the space forward in time by @c dt. 255 CP_EXPORT void cpSpaceStep(cpSpace *space, cpFloat dt); 256 257 258 //MARK: Debug API 259 260 #ifndef CP_SPACE_DISABLE_DEBUG_API 261 262 /// Color type to use with the space debug drawing API. 263 typedef struct cpSpaceDebugColor { 264 float r, g, b, a; 265 } cpSpaceDebugColor; 266 267 /// Callback type for a function that draws a filled, stroked circle. 268 typedef void (*cpSpaceDebugDrawCircleImpl)(cpVect pos, cpFloat angle, cpFloat radius, cpSpaceDebugColor outlineColor, cpSpaceDebugColor fillColor, cpDataPointer data); 269 /// Callback type for a function that draws a line segment. 270 typedef void (*cpSpaceDebugDrawSegmentImpl)(cpVect a, cpVect b, cpSpaceDebugColor color, cpDataPointer data); 271 /// Callback type for a function that draws a thick line segment. 272 typedef void (*cpSpaceDebugDrawFatSegmentImpl)(cpVect a, cpVect b, cpFloat radius, cpSpaceDebugColor outlineColor, cpSpaceDebugColor fillColor, cpDataPointer data); 273 /// Callback type for a function that draws a convex polygon. 274 typedef void (*cpSpaceDebugDrawPolygonImpl)(int count, const cpVect *verts, cpFloat radius, cpSpaceDebugColor outlineColor, cpSpaceDebugColor fillColor, cpDataPointer data); 275 /// Callback type for a function that draws a dot. 276 typedef void (*cpSpaceDebugDrawDotImpl)(cpFloat size, cpVect pos, cpSpaceDebugColor color, cpDataPointer data); 277 /// Callback type for a function that returns a color for a given shape. This gives you an opportunity to color shapes based on how they are used in your engine. 278 typedef cpSpaceDebugColor (*cpSpaceDebugDrawColorForShapeImpl)(cpShape *shape, cpDataPointer data); 279 280 typedef enum cpSpaceDebugDrawFlags { 281 CP_SPACE_DEBUG_DRAW_SHAPES = 1<<0, 282 CP_SPACE_DEBUG_DRAW_CONSTRAINTS = 1<<1, 283 CP_SPACE_DEBUG_DRAW_COLLISION_POINTS = 1<<2, 284 } cpSpaceDebugDrawFlags; 285 286 /// Struct used with cpSpaceDebugDraw() containing drawing callbacks and other drawing settings. 287 typedef struct cpSpaceDebugDrawOptions { 288 /// Function that will be invoked to draw circles. 289 cpSpaceDebugDrawCircleImpl drawCircle; 290 /// Function that will be invoked to draw line segments. 291 cpSpaceDebugDrawSegmentImpl drawSegment; 292 /// Function that will be invoked to draw thick line segments. 293 cpSpaceDebugDrawFatSegmentImpl drawFatSegment; 294 /// Function that will be invoked to draw convex polygons. 295 cpSpaceDebugDrawPolygonImpl drawPolygon; 296 /// Function that will be invoked to draw dots. 297 cpSpaceDebugDrawDotImpl drawDot; 298 299 /// Flags that request which things to draw (collision shapes, constraints, contact points). 300 cpSpaceDebugDrawFlags flags; 301 /// Outline color passed to the drawing function. 302 cpSpaceDebugColor shapeOutlineColor; 303 /// Function that decides what fill color to draw shapes using. 304 cpSpaceDebugDrawColorForShapeImpl colorForShape; 305 /// Color passed to drawing functions for constraints. 306 cpSpaceDebugColor constraintColor; 307 /// Color passed to drawing functions for collision points. 308 cpSpaceDebugColor collisionPointColor; 309 310 /// User defined context pointer passed to all of the callback functions as the 'data' argument. 311 cpDataPointer data; 312 } cpSpaceDebugDrawOptions; 313 314 /// Debug draw the current state of the space using the supplied drawing options. 315 CP_EXPORT void cpSpaceDebugDraw(cpSpace *space, cpSpaceDebugDrawOptions *options); 316 317 #endif 318 319 /// @} 320