packages feed

Hipmunk 5.2.0.2 → 5.2.0.3

raw patch · 117 files changed

+8349/−8284 lines, 117 filesdep ~containersnew-uploaderPVP ok

version bump matches the API change (PVP)

Dependency ranges changed: containers

API changes (from Hackage documentation)

Files

− Chipmunk-5.3.4/LICENSE.txt
@@ -1,19 +0,0 @@-Copyright (c) 2007 Scott Lembcke and Howling Moon Software--Permission is hereby granted, free of charge, to any person obtaining a copy-of this software and associated documentation files (the "Software"), to deal-in the Software without restriction, including without limitation the rights-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell-copies of the Software, and to permit persons to whom the Software is-furnished to do so, subject to the following conditions:--The above copyright notice and this permission notice shall be included in-all copies or substantial portions of the Software.--THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE-SOFTWARE.
− Chipmunk-5.3.4/README.txt
@@ -1,114 +0,0 @@-ABOUT:-Chipmunk is a simple, lightweight, fast and portable 2D rigid body physics library written in C. It's licensed under the unrestrictive, OSI approved MIT license. My aim is to give 2D developers access the same quality of physics you find in newer 3D games. I hope you enjoy using Chipmunk, and please consider donating to help make it worth our time to continue to support Chipmunk with great new features.--CONTRACTING:-Howling Moon Software (my company) is available for contracting if you want to make the physics in your game really stand out. Given our unique experience with the library, we can help you use Chipmunk to it's fullest potential. Feel free to contact us through our webpage: http://howlingmoonsoftware.com/contracting.php--Objective-Chipmunk:-The Objective-Chipmunk directory contains an Objective-C wrapper for the Chipmunk Physics Library as well as some sample code from shipping iPhone Apps. One reason Chipmunk was written in C was to allow easy wrapping for other languages. The primary advantages of a native Objective-C API include integrating with the Cocoa memory management model and the Chipmunk Object protocol. The Chipmunk Object protocol unifies the basic Chipmunk types as well as making it easy to create and manage custom composite collections of the basic types. Additionally, the wrapper adds many convenience methods for doing common setup tasks as well as helper methods that integrate it with the rest of the Cocoa Touch API and basic datatypes used on the iPhone. The wrapper tries to do things the Objective-C way, adding useful method variations where it makes sense to do so. If you are an iPhone developer, Objective-Chipmunk will definitely save you time.--To try Objective-Chipmunk in your own projects see Objective-Chipmunk/Objective-Chipmunk/Readme.rtf.--BUILDING:-Mac OS X: There is an included XCode project file for building the static library and demo application. Alternatively you could use the CMake files. A Mac OS X version of Objective-Chipmunk is available for free upon request. We don't do regular builds as few people seem interested in it.--iPhone: If you want a native Objective-C API, check out the Objective-Chipmunk directory for the Objective-C binding and some sample code from shipping iPhone Apps. It is inexpensive to license and should save you a lot of time. Otherwise, the XCode project can build a static library with all the proper compiler settings. Alternatively, you can just run iphonestatic.command in the macosx/ directory.  It will build you a fat library compiled as release for the device and debug for the simulator. After running it, you can simply drop the Chipmunk-iPhone directory into your iPhone project!--UNIXes: A forum user was kind enough to make a set of CMake files for Chipmunk. This will require you to have CMake installed. To build run 'cmake .' then 'make'. This should build a dynamic library, a static library, and the demo application. A number of people have had build errors on Ubuntu due to not having GLUT or libxmu installed.--Windows: Visual Studio projects are included in the msvc/ directory. I do not maintain these personally, but a number of forum members have assisted with them.--Ruby: I've been using maintaining a Ruby extension for Chipmunk, but at this time is not up to date with all the latest changes. It has been tested and builds under Linux and OS X using CMake however 'cmake -D BUILD_RUBY_EXT=ON .; make'. A forum member has been working on an FFI based extention (http://github.com/erisdiscord/chipmunk-ffi), and that may be a better way to take advantage of Chipmunk from Ruby. Another forum user has offered to maintain the non-FFI version of the extension. Stay tuned.--GETTING STARTED:-First of all, you can find the C API documentation in the doc/ directory.--A good starting point is to take a look at the included Demo application. The demos all just set up a Chipmunk simulation space and the demo app draws the graphics directly out of that. This makes it easy to see how the Chipmunk API works without worrying about the graphics code. You are free to use the demo drawing routines in your own projects, though it is certainly not the recommended way of drawing Chipmunk objects as it pokes around at the undocumented parts of Chipmunk.--If you are looking at Objective-Chipmunk for the iPhone, we have a number of example projects and tutorials in the Objective-Chipmunk directory.--FORUM:-http://www.slembcke.net/forums--CONTACT:-slembcke@gmail.com (also on Google Talk)--CHANGES SINCE 5.3.3:-* FIX: cpBodyActivate() can now be called from collision and query callbacks. This way you can use the setter functions to change properties without indirectly calling cpBodyActivate() and causing an assertion.-* FIX: cpArbiterGetContactPointSet() was returning the collision points for the normals.-* FIX: cpSpaceEachBody() now includes sleeping bodies.-* FIX: Shapes attached to static rogue bodies created with cpBodyNewStatic() are added as static shapes.-* MISC: Applied a user patch to update the MSVC project and add a .def file.--CHANGES SINCE 5.3.2:-* API: Added cpArbiteGetCount() to return the number of contact points.-* API: Added helper functions for calculating areas of Chipmunk shapes as well as calculating polygon centroids and centering polygons on their centroid.-* API: Shape queries. Query a shape to test for collisions if it were to be inserted into a space.-* API: cpBodyInitStatic() and cpBodyNewStatic() for creating additional static (rogue) bodies.-* API: cpBodySleepWithGroup() to allow you to create groups of sleeping objects that are woken up together.-* API: Added overloaded *, +, - and == operators for C++ users.-* API: Added cpSpaceActivateShapesTouchingShape() to query for and activate any shapes touching a given shape. Useful if you ever need to move a static body.-* FIX: Fixed an extremely rare memory bug in the collision cache.-* FIX: Fixed a memory leak in Objective-Chipmunk that could cause ChipmunkSpace objects to be leaked.-* MISC: C struct fields and function that are considered private have been explicitly marked as such. Defining CP_ALLOW_PRIVATE_ACCESS to 0 in Chipmunk.h will let you test which parts of the private API that you are using and give me feedback about how to build proper APIs in Chipmunk 6 for what you are trying to do.-* MISC: Allow CGPoints to be used as cpVect on Mac OS X as well as iOS.---CHANGES SINCE 5.3.1:-* FIX: Collision begin callbacks were being called continuously for sensors or collisions rejected from the pre-solve callback.-* FIX: Plugged a nasty memory leak when adding post-step callbacks.-* FIX: Shapes were being added to the spatial hash using an uninitialized bounding box in some cases.-* FIX: Perfectly aligned circle shapes now push each other apart.-* FIX: cpBody setter functions now call cpBodyActivate().-* FIX: Collision handler targets are released in Objective-Chipmunk when they are no longer needed instead of waiting for the space to be deallocated.-* API: cpSpaceSegmentQuery() no longer returns a boolean. Use cpSpaceSegmentQueryFirst() instead as it's more efficient.-* NEW: cpSpaceRehashShape() Rehash an individual shape, active or static.-* NEW: cpBodySleep() Force a body to fall asleep immediately.-* NEW: cpConstraintGetImpulse() Return the most recent impulse applied by a constraint.-* NEW: Added setter functions for the groove joint endpoints.-* MISC: A number of other minor optimizations and fixes.--CHANGES SINCE 5.3.0:- * NEW: Added a brand new tutorial for Objective-Chipmunk: SimpleObjectiveChipmunk that can be found in the Objective-Chipmunk folder.- * NEW: Proper API docs for Objective-Chipmunk.- * NEW: Updated the included Objective-Chipmunk library.- * FIX: Fixed a rare memory crash in the sensor demo.- * FIX: Fixed some warnings that users submitted.--CHANGES SINCE 5.2.0:- * FIX: Fixed the source so it can compile as C, C++, Objective-C, and Objective-C++.- * FIX: Fixed cp_contact_persistence. It was broken so that it would forget collision solutions after 1 frame instead of respecting the value set.- * OPTIMIZATION: Several minor optimizations have been added. Though performance should only differ by a few percent.- * OPTIMIZATION: Chipmunk now supports putting bodies to sleep when they become inactive.- * API: Elastic iterations are now deprecated as they should no longer be necessary.- * API: Added API elements to support body sleeping.- * API: Added a statically allocated static body to each space for attaching static shapes to.- * API: Static shapes attached to the space's static body can simply be added to the space using cpSpaceAddShape().- * NEW: New MSVC projects.- * NEW: Added boolean and time stamp types for clarity.--CHANGES SINCE 5.1.0:- * OPTIMIZATION: Chipmunk structs used within the solver are now allocated linearly in large blocks. This is much more CPU cache friendly. Programs have seen up to 50% performance improvements though 15-20% should be expected.- * API: Shape references in cpArbiter structs changed to private_a and private_b to discourage accessing the fields directly and getting them out of order. You should be using cpArbiterGetShapes() or CP_ARBITER_GET_SHAPES() to access the shapes in the correct order.- * API: Added assertion error messages as well as warnings and covered many new assertion cases.- * FIX: separate() callbacks are called before shapes are removed from the space to prevent dangling pointers.- * NEW: Added convenience functions for creating box shapes and calculating moments.- --CHANGES SINCE 5.0.0:- * FIX: fixed a NaN issue that was causing raycasts for horizontal or vertical lines to end up in an infinite loop- * FIX: fixed a number of memory leaks- * FIX: fixed warnings for various compiler/OS combinations- * API: Rejecting a collision from a begin() callback permanently rejects the collision until separation- * API: Erroneous collision type parameterns removed from cpSpaceDefaulteCollisionHandler()- * MOVE: FFI declarations of inlined functions into their own header- * MOVE: Rearranged the project structure to separate out the header files into a separate include/ directory.- * NEW: Added a static library target for the iPhone.- * NEW: Type changes when building on the iPhone to make it friendlier to other iPhone APIs- * NEW: Added an AABB query to complement point and segment queries- * NEW: CP_NO_GROUP and CP_ALL_LAYERS constants--CHANGES SINCE 4.x:- * Brand new Joint/Constraint API: New constraints can be added easily and are much more flexible than the old joint system- * Efficient Segment Queries - Like raycasting, but with line segments.- * Brand new collision callback API: Collision begin/separate events, API for removal of objects within callbacks, more programable control over collision handling.
− Chipmunk-5.3.4/include/chipmunk/chipmunk.h
@@ -1,163 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */--#ifndef CHIPMUNK_HEADER-#define CHIPMUNK_HEADER--#ifdef __cplusplus-extern "C" {-#endif--#ifndef CP_ALLOW_PRIVATE_ACCESS-	#define CP_ALLOW_PRIVATE_ACCESS 1-#endif--#if CP_ALLOW_PRIVATE_ACCESS == 1-	#define CP_PRIVATE(symbol) symbol-#else-	#define CP_PRIVATE(symbol) symbol##_private-#endif--void cpMessage(const char *message, const char *condition, const char *file, int line, int isError);-#ifdef NDEBUG-	#define	cpAssertWarn(condition, message)-#else-	#define cpAssertWarn(condition, message) if(!(condition)) cpMessage(message, #condition, __FILE__, __LINE__, 0)-#endif--#ifdef NDEBUG-	#define	cpAssert(condition, message)-#else-	#define cpAssert(condition, message) if(!(condition)) cpMessage(message, #condition, __FILE__, __LINE__, 1)-#endif--#include "chipmunk_types.h"-	-#ifndef INFINITY-	#ifdef _MSC_VER-		union MSVC_EVIL_FLOAT_HACK-		{-			unsigned __int8 Bytes[4];-			float Value;-		};-		static union MSVC_EVIL_FLOAT_HACK INFINITY_HACK = {{0x00, 0x00, 0x80, 0x7F}};-		#define INFINITY (INFINITY_HACK.Value)-	#endif-	-	#ifdef __GNUC__-		#define INFINITY (__builtin_inf())-	#endif-	-	#ifndef INFINITY-		#define INFINITY (1e1000)-	#endif-#endif--// Maximum allocated size for various Chipmunk buffers-#define CP_BUFFER_BYTES (32*1024)--#define cpmalloc malloc-#define cpcalloc calloc-#define cprealloc realloc-#define cpfree free--#include "cpVect.h"-#include "cpBB.h"-#include "cpArray.h"-#include "cpHashSet.h"-#include "cpSpaceHash.h"--#include "cpBody.h"-#include "cpShape.h"-#include "cpPolyShape.h"--#include "cpArbiter.h"-#include "cpCollision.h"-	-#include "constraints/cpConstraint.h"--#include "cpSpace.h"--#define CP_HASH_COEF (3344921057ul)-#define CP_HASH_PAIR(A, B) ((cpHashValue)(A)*CP_HASH_COEF ^ (cpHashValue)(B)*CP_HASH_COEF)--extern const char *cpVersionString;-void cpInitChipmunk(void);--/**-	Calculate the moment of inertia for a circle.-	r1 and r2 are the inner and outer diameters. A solid circle has an inner diameter of 0.-*/-cpFloat cpMomentForCircle(cpFloat m, cpFloat r1, cpFloat r2, cpVect offset);--/**-	Calculate area of a hollow circle.-*/-cpFloat cpAreaForCircle(cpFloat r1, cpFloat r2);--/**-	Calculate the moment of inertia for a line segment.-	Beveling radius is not supported.-*/-cpFloat cpMomentForSegment(cpFloat m, cpVect a, cpVect b);--/**-	Calculate the area of a fattened (capsule shaped) line segment.-*/-cpFloat cpAreaForSegment(cpVect a, cpVect b, cpFloat r);--/**-	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.-*/-cpFloat cpMomentForPoly(cpFloat m, int numVerts, const cpVect *verts, cpVect offset);--/**-	Calculate the signed area of a polygon.-*/-cpFloat cpAreaForPoly(const int numVerts, const cpVect *verts);--/**-	Calculate the natural centroid of a polygon.-*/-cpVect cpCentroidForPoly(const int numVerts, const cpVect *verts);--/**-	Center the polygon on the origin. (Subtracts the centroid of the polygon from each vertex)-*/-void cpRecenterPoly(const int numVerts, cpVect *verts);--/**-	Calculate the moment of inertia for a solid box.-*/-cpFloat cpMomentForBox(cpFloat m, cpFloat width, cpFloat height);--#ifdef __cplusplus-}--static inline cpVect operator *(const cpVect v, const cpFloat s){return cpvmult(v, s);}-static inline cpVect operator +(const cpVect v1, const cpVect v2){return cpvadd(v1, v2);}-static inline cpVect operator -(const cpVect v1, const cpVect v2){return cpvsub(v1, v2);}-static inline cpBool operator ==(const cpVect v1, const cpVect v2){return cpveql(v1, v2);}-static inline cpVect operator -(const cpVect v){return cpvneg(v);}--#endif--#endif
− Chipmunk-5.3.4/include/chipmunk/chipmunk_ffi.h
@@ -1,59 +0,0 @@-// Create non static inlined copies of Chipmunk functions, useful for working with dynamic FFIs-// This file should only be included in chipmunk.c--#ifdef _MSC_VER- #if _MSC_VER >= 1600-  #define MAKE_REF(name) decltype(name) *_##name = name- #else-  #define MAKE_REF(name)- #endif-#else- #define MAKE_REF(name) __typeof__(name) *_##name = name-#endif--MAKE_REF(cpv); // makes a variable named _cpv that contains the function pointer for cpv()-MAKE_REF(cpveql);-MAKE_REF(cpvadd);-MAKE_REF(cpvneg);-MAKE_REF(cpvsub);-MAKE_REF(cpvmult);-MAKE_REF(cpvdot);-MAKE_REF(cpvcross);-MAKE_REF(cpvperp);-MAKE_REF(cpvrperp);-MAKE_REF(cpvproject);-MAKE_REF(cpvrotate);-MAKE_REF(cpvunrotate);-MAKE_REF(cpvlengthsq);-MAKE_REF(cpvlerp);-MAKE_REF(cpvnormalize);-MAKE_REF(cpvnormalize_safe);-MAKE_REF(cpvclamp);-MAKE_REF(cpvlerpconst);-MAKE_REF(cpvdist);-MAKE_REF(cpvdistsq);-MAKE_REF(cpvnear);--MAKE_REF(cpBBNew);-MAKE_REF(cpBBintersects);-MAKE_REF(cpBBcontainsBB);-MAKE_REF(cpBBcontainsVect);-MAKE_REF(cpBBmerge);-MAKE_REF(cpBBexpand);--MAKE_REF(cpBodyWorld2Local);-MAKE_REF(cpBodyLocal2World);-MAKE_REF(cpBodyApplyImpulse);-MAKE_REF(cpBodyIsSleeping);-MAKE_REF(cpBodyIsRogue);-MAKE_REF(cpBodyKineticEnergy);--MAKE_REF(cpArbiterIsFirstContact);-MAKE_REF(cpArbiterGetShapes);-MAKE_REF(cpArbiterGetNormal);-MAKE_REF(cpArbiterGetPoint);--MAKE_REF(cpConstraintGetImpulse);--MAKE_REF(cpSegmentQueryHitPoint);-MAKE_REF(cpSegmentQueryHitDist);
− Chipmunk-5.3.4/include/chipmunk/chipmunk_private.h
@@ -1,49 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */--#define CP_ALLOW_PRIVATE_ACCESS 1-#include "chipmunk.h"--void *cpSpaceGetPostStepData(cpSpace *space, void *obj);--void cpSpaceActivateBody(cpSpace *space, cpBody *body);--static inline void-cpSpaceLock(cpSpace *space)-{-	space->locked++;-}--static inline void-cpSpaceUnlock(cpSpace *space)-{-	space->locked--;-	cpAssert(space->locked >= 0, "Internal error:Space lock underflow.");-	-	if(!space->locked){-		cpArray *waking = space->rousedBodies;-		for(int i=0, count=waking->num; i<count; i++){-			cpSpaceActivateBody(space, (cpBody *)waking->arr[i]);-		}-		-		waking->num = 0;-	}-}
− Chipmunk-5.3.4/include/chipmunk/chipmunk_types.h
@@ -1,151 +0,0 @@-#ifdef __APPLE__-   #import "TargetConditionals.h"-#endif--#if (defined TARGET_OS_IPHONE) && (!defined CP_USE_CGPOINTS)-	#define CP_USE_CGPOINTS-#endif--#ifdef CP_USE_CGPOINTS-	#if TARGET_OS_IPHONE-		#import <CoreGraphics/CGGeometry.h>-	#elif TARGET_OS_MAC-		#import <ApplicationServices/ApplicationServices.h>-	#endif-	-	#if defined(__LP64__) && __LP64__-		#define CP_USE_DOUBLES 1-	#else-		#define CP_USE_DOUBLES 0-	#endif-#endif--#ifndef CP_USE_DOUBLES-	// use doubles by default for higher precision-	#define CP_USE_DOUBLES 1-#endif--#if CP_USE_DOUBLES-	typedef double cpFloat;-	#define cpfsqrt sqrt-	#define cpfsin sin-	#define cpfcos cos-	#define cpfacos acos-	#define cpfatan2 atan2-	#define cpfmod fmod-	#define cpfexp exp-	#define cpfpow pow-	#define cpffloor floor-	#define cpfceil ceil-#else-	typedef float cpFloat;-	#define cpfsqrt sqrtf-	#define cpfsin sinf-	#define cpfcos cosf-	#define cpfacos acosf-	#define cpfatan2 atan2f-	#define cpfmod fmodf-	#define cpfexp expf-	#define cpfpow powf-	#define cpffloor floorf-	#define cpfceil ceilf-#endif--static inline cpFloat-cpfmax(cpFloat a, cpFloat b)-{-	return (a > b) ? a : b;-}--static inline cpFloat-cpfmin(cpFloat a, cpFloat b)-{-	return (a < b) ? a : b;-}--static inline cpFloat-cpfabs(cpFloat n)-{-	return (n < 0) ? -n : n;-}--static inline cpFloat-cpfclamp(cpFloat f, cpFloat min, cpFloat max)-{-	return cpfmin(cpfmax(f, min), max);-}--static inline cpFloat-cpflerp(cpFloat f1, cpFloat f2, cpFloat t)-{-	return f1*(1.0f - t) + f2*t;-}--static inline cpFloat-cpflerpconst(cpFloat f1, cpFloat f2, cpFloat d)-{-	return f1 + cpfclamp(f2 - f1, -d, d);-}--// CGPoints are structurally the same, and allow-// easy interoperability with other Cocoa libraries-#ifdef CP_USE_CGPOINTS-	typedef CGPoint cpVect;-#else-	typedef struct cpVect{cpFloat x,y;} cpVect;-#endif--typedef unsigned int cpHashValue;--// Oh C, how we love to define our own boolean types to get compiler compatibility-#ifdef CP_BOOL_TYPE-	typedef CP_BOOL_TYPE cpBool;-#else-	typedef int cpBool;-#endif--#ifndef cpTrue-	#define cpTrue 1-#endif--#ifndef cpFalse-	#define cpFalse 0-#endif--#ifdef CP_DATA_POINTER_TYPE-	typedef CP_DATA_POINTER_TYPE cpDataPointer;-#else-	typedef void * cpDataPointer;-#endif--#ifdef CP_COLLISION_TYPE_TYPE-	typedef CP_COLLISION_TYPE_TYPE cpCollisionType;-#else-	typedef unsigned int cpCollisionType;-#endif--#ifdef CP_GROUP_TYPE-	typedef CP_GROUP_TYPE cpGroup;-#else-	typedef unsigned int cpGroup;-#endif--#ifdef CP_LAYERS_TYPE-	typedef CP_GROUP_TYPE cpLayers;-#else-	typedef unsigned int cpLayers;-#endif--#ifdef CP_TIMESTAMP_TYPE-	typedef CP_TIMESTAMP_TYPE cpTimestamp;-#else-	typedef unsigned int cpTimestamp;-#endif--#ifndef CP_NO_GROUP-	#define CP_NO_GROUP ((cpGroup)0)-#endif--#ifndef CP_ALL_LAYERS-	#define CP_ALL_LAYERS (~(cpLayers)0)-#endif
− Chipmunk-5.3.4/include/chipmunk/chipmunk_unsafe.h
@@ -1,54 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */----/* This header defines a number of "unsafe" operations on Chipmunk objects.- * In this case "unsafe" is referring to operations which may reduce the- * physical accuracy or numerical stability of the simulation, but will not- * cause crashes.- *- * The prime example is mutating collision shapes. Chipmunk does not support- * this directly. Mutating shapes using this API will caused objects in contact- * to be pushed apart using Chipmunk's overlap solver, but not using real- * persistent velocities. Probably not what you meant, but perhaps close enough.- */--#ifndef CHIPMUNK_UNSAFE_HEADER-#define CHIPMUNK_UNSAFE_HEADER--#ifdef __cplusplus-extern "C" {-#endif--void cpCircleShapeSetRadius(cpShape *shape, cpFloat radius);-void cpCircleShapeSetOffset(cpShape *shape, cpVect offset);--void cpSegmentShapeSetEndpoints(cpShape *shape, cpVect a, cpVect b);-void cpSegmentShapeSetRadius(cpShape *shape, cpFloat radius);--void cpPolyShapeSetVerts(cpShape *shape, int numVerts, cpVect *verts, cpVect offset);--#ifdef __cplusplus-}-#endif--#endif
− Chipmunk-5.3.4/include/chipmunk/constraints/cpConstraint.h
@@ -1,105 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */--// TODO: Comment me!-	-extern cpFloat cp_constraint_bias_coef;--struct cpConstraintClass;-struct cpConstraint;--typedef void (*cpConstraintPreStepFunction)(struct cpConstraint *constraint, cpFloat dt, cpFloat dt_inv);-typedef void (*cpConstraintApplyImpulseFunction)(struct cpConstraint *constraint);-typedef cpFloat (*cpConstraintGetImpulseFunction)(struct cpConstraint *constraint);--typedef struct cpConstraintClass {-	cpConstraintPreStepFunction preStep;-	cpConstraintApplyImpulseFunction applyImpulse;-	cpConstraintGetImpulseFunction getImpulse;-} cpConstraintClass;----typedef struct cpConstraint {-	CP_PRIVATE(const cpConstraintClass *klass);-	-	cpBody *a, *b;-	cpFloat maxForce;-	cpFloat biasCoef;-	cpFloat maxBias;-	-	cpDataPointer data;-} cpConstraint;--#ifdef CP_USE_DEPRECATED_API_4-typedef cpConstraint cpJoint;-#endif--void cpConstraintDestroy(cpConstraint *constraint);-void cpConstraintFree(cpConstraint *constraint);--static inline void-cpConstraintActivateBodies(cpConstraint *constraint)-{-	cpBody *a = constraint->a; if(a) cpBodyActivate(a);-	cpBody *b = constraint->b; if(b) cpBodyActivate(b);-}--static inline cpFloat-cpConstraintGetImpulse(cpConstraint *constraint)-{-	return constraint->CP_PRIVATE(klass)->getImpulse(constraint);-}--#define cpConstraintCheckCast(constraint, struct) \-	cpAssert(constraint->CP_PRIVATE(klass) == struct##GetClass(), "Constraint is not a "#struct);---#define CP_DefineConstraintGetter(struct, type, member, name) \-static inline type \-struct##Get##name(const cpConstraint *constraint){ \-	cpConstraintCheckCast(constraint, struct); \-	return ((struct *)constraint)->member; \-} \--#define CP_DefineConstraintSetter(struct, type, member, name) \-static inline void \-struct##Set##name(cpConstraint *constraint, type value){ \-	cpConstraintCheckCast(constraint, struct); \-	cpConstraintActivateBodies(constraint); \-	((struct *)constraint)->member = value; \-} \--#define CP_DefineConstraintProperty(struct, type, member, name) \-CP_DefineConstraintGetter(struct, type, member, name) \-CP_DefineConstraintSetter(struct, type, member, name)--// Built in Joint types-#include "cpPinJoint.h"-#include "cpSlideJoint.h"-#include "cpPivotJoint.h"-#include "cpGrooveJoint.h"-#include "cpDampedSpring.h"-#include "cpDampedRotarySpring.h"-#include "cpRotaryLimitJoint.h"-#include "cpRatchetJoint.h"-#include "cpGearJoint.h"-#include "cpSimpleMotor.h"
− Chipmunk-5.3.4/include/chipmunk/constraints/cpDampedRotarySpring.h
@@ -1,46 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */--typedef cpFloat (*cpDampedRotarySpringTorqueFunc)(struct cpConstraint *spring, cpFloat relativeAngle);--const cpConstraintClass *cpDampedRotarySpringGetClass();--typedef struct cpDampedRotarySpring {-	cpConstraint constraint;-	cpFloat restAngle;-	cpFloat stiffness;-	cpFloat damping;-	cpDampedRotarySpringTorqueFunc springTorqueFunc;-	-	cpFloat target_wrn;-	cpFloat w_coef;-	-	cpFloat iSum;-} cpDampedRotarySpring;--cpDampedRotarySpring *cpDampedRotarySpringAlloc(void);-cpDampedRotarySpring *cpDampedRotarySpringInit(cpDampedRotarySpring *joint, cpBody *a, cpBody *b, cpFloat restAngle, cpFloat stiffness, cpFloat damping);-cpConstraint *cpDampedRotarySpringNew(cpBody *a, cpBody *b, cpFloat restAngle, cpFloat stiffness, cpFloat damping);--CP_DefineConstraintProperty(cpDampedRotarySpring, cpFloat, restAngle, RestAngle);-CP_DefineConstraintProperty(cpDampedRotarySpring, cpFloat, stiffness, Stiffness);-CP_DefineConstraintProperty(cpDampedRotarySpring, cpFloat, damping, Damping);-CP_DefineConstraintProperty(cpDampedRotarySpring, cpDampedRotarySpringTorqueFunc, springTorqueFunc, SpringTorqueFunc);
− Chipmunk-5.3.4/include/chipmunk/constraints/cpDampedSpring.h
@@ -1,53 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */--struct cpDampedSpring;--typedef cpFloat (*cpDampedSpringForceFunc)(struct cpConstraint *spring, cpFloat dist);--const cpConstraintClass *cpDampedSpringGetClass();--typedef struct cpDampedSpring {-	cpConstraint constraint;-	cpVect anchr1, anchr2;-	cpFloat restLength;-	cpFloat stiffness;-	cpFloat damping;-	cpDampedSpringForceFunc springForceFunc;-	-	cpFloat target_vrn;-	cpFloat v_coef;-	-	cpVect r1, r2;-	cpFloat nMass;-	cpVect n;-} cpDampedSpring;--cpDampedSpring *cpDampedSpringAlloc(void);-cpDampedSpring *cpDampedSpringInit(cpDampedSpring *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat restLength, cpFloat stiffness, cpFloat damping);-cpConstraint *cpDampedSpringNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat restLength, cpFloat stiffness, cpFloat damping);--CP_DefineConstraintProperty(cpDampedSpring, cpVect, anchr1, Anchr1);-CP_DefineConstraintProperty(cpDampedSpring, cpVect, anchr2, Anchr2);-CP_DefineConstraintProperty(cpDampedSpring, cpFloat, restLength, RestLength);-CP_DefineConstraintProperty(cpDampedSpring, cpFloat, stiffness, Stiffness);-CP_DefineConstraintProperty(cpDampedSpring, cpFloat, damping, Damping);-CP_DefineConstraintProperty(cpDampedSpring, cpDampedSpringForceFunc, springForceFunc, SpringForceFunc);
− Chipmunk-5.3.4/include/chipmunk/constraints/cpGearJoint.h
@@ -1,41 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */--const cpConstraintClass *cpGearJointGetClass();--typedef struct cpGearJoint {-	cpConstraint constraint;-	cpFloat phase, ratio;-	cpFloat ratio_inv;-	-	cpFloat iSum;-		-	cpFloat bias;-	cpFloat jAcc, jMax;-} cpGearJoint;--cpGearJoint *cpGearJointAlloc(void);-cpGearJoint *cpGearJointInit(cpGearJoint *joint, cpBody *a, cpBody *b, cpFloat phase, cpFloat ratio);-cpConstraint *cpGearJointNew(cpBody *a, cpBody *b, cpFloat phase, cpFloat ratio);--CP_DefineConstraintProperty(cpGearJoint, cpFloat, phase, Phase);-CP_DefineConstraintGetter(cpGearJoint, cpFloat, ratio, Ratio);-void cpGearJointSetRatio(cpConstraint *constraint, cpFloat value);
− Chipmunk-5.3.4/include/chipmunk/constraints/cpGrooveJoint.h
@@ -1,48 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */--const cpConstraintClass *cpGrooveJointGetClass();--typedef struct cpGrooveJoint {-	cpConstraint constraint;-	cpVect grv_n, grv_a, grv_b;-	cpVect  anchr2;-	-	cpVect grv_tn;-	cpFloat clamp;-	cpVect r1, r2;-	cpVect k1, k2;-	-	cpVect jAcc;-	cpFloat jMaxLen;-	cpVect bias;-} cpGrooveJoint;--cpGrooveJoint *cpGrooveJointAlloc(void);-cpGrooveJoint *cpGrooveJointInit(cpGrooveJoint *joint, cpBody *a, cpBody *b, cpVect groove_a, cpVect groove_b, cpVect anchr2);-cpConstraint *cpGrooveJointNew(cpBody *a, cpBody *b, cpVect groove_a, cpVect groove_b, cpVect anchr2);---CP_DefineConstraintGetter(cpGrooveJoint, cpVect, grv_a, GrooveA);-void cpGrooveJointSetGrooveA(cpConstraint *constraint, cpVect value);-CP_DefineConstraintGetter(cpGrooveJoint, cpVect, grv_b, GrooveB);-void cpGrooveJointSetGrooveB(cpConstraint *constraint, cpVect value);-CP_DefineConstraintProperty(cpGrooveJoint, cpVect, anchr2, Anchr2);
− Chipmunk-5.3.4/include/chipmunk/constraints/cpPinJoint.h
@@ -1,43 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */- -const cpConstraintClass *cpPinJointGetClass();--typedef struct cpPinJoint {-	cpConstraint constraint;-	cpVect anchr1, anchr2;-	cpFloat dist;-	-	cpVect r1, r2;-	cpVect n;-	cpFloat nMass;-	-	cpFloat jnAcc, jnMax;-	cpFloat bias;-} cpPinJoint;--cpPinJoint *cpPinJointAlloc(void);-cpPinJoint *cpPinJointInit(cpPinJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2);-cpConstraint *cpPinJointNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2);--CP_DefineConstraintProperty(cpPinJoint, cpVect, anchr1, Anchr1);-CP_DefineConstraintProperty(cpPinJoint, cpVect, anchr2, Anchr2);-CP_DefineConstraintProperty(cpPinJoint, cpFloat, dist, Dist);
− Chipmunk-5.3.4/include/chipmunk/constraints/cpPivotJoint.h
@@ -1,42 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */--const cpConstraintClass *cpPivotJointGetClass();--typedef struct cpPivotJoint {-	cpConstraint constraint;-	cpVect anchr1, anchr2;-	-	cpVect r1, r2;-	cpVect k1, k2;-	-	cpVect jAcc;-	cpFloat jMaxLen;-	cpVect bias;-} cpPivotJoint;--cpPivotJoint *cpPivotJointAlloc(void);-cpPivotJoint *cpPivotJointInit(cpPivotJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2);-cpConstraint *cpPivotJointNew(cpBody *a, cpBody *b, cpVect pivot);-cpConstraint *cpPivotJointNew2(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2);--CP_DefineConstraintProperty(cpPivotJoint, cpVect, anchr1, Anchr1);-CP_DefineConstraintProperty(cpPivotJoint, cpVect, anchr2, Anchr2);
− Chipmunk-5.3.4/include/chipmunk/constraints/cpRatchetJoint.h
@@ -1,40 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */--const cpConstraintClass *cpRatchetJointGetClass();--typedef struct cpRatchetJoint {-	cpConstraint constraint;-	cpFloat angle, phase, ratchet;-	-	cpFloat iSum;-		-	cpFloat bias;-	cpFloat jAcc, jMax;-} cpRatchetJoint;--cpRatchetJoint *cpRatchetJointAlloc(void);-cpRatchetJoint *cpRatchetJointInit(cpRatchetJoint *joint, cpBody *a, cpBody *b, cpFloat phase, cpFloat ratchet);-cpConstraint *cpRatchetJointNew(cpBody *a, cpBody *b, cpFloat phase, cpFloat ratchet);--CP_DefineConstraintProperty(cpRatchetJoint, cpFloat, angle, Angle);-CP_DefineConstraintProperty(cpRatchetJoint, cpFloat, phase, Phase);-CP_DefineConstraintProperty(cpRatchetJoint, cpFloat, ratchet, Ratchet);
− Chipmunk-5.3.4/include/chipmunk/constraints/cpRotaryLimitJoint.h
@@ -1,39 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */--const cpConstraintClass *cpRotaryLimitJointGetClass();--typedef struct cpRotaryLimitJoint {-	cpConstraint constraint;-	cpFloat min, max;-	-	cpFloat iSum;-		-	cpFloat bias;-	cpFloat jAcc, jMax;-} cpRotaryLimitJoint;--cpRotaryLimitJoint *cpRotaryLimitJointAlloc(void);-cpRotaryLimitJoint *cpRotaryLimitJointInit(cpRotaryLimitJoint *joint, cpBody *a, cpBody *b, cpFloat min, cpFloat max);-cpConstraint *cpRotaryLimitJointNew(cpBody *a, cpBody *b, cpFloat min, cpFloat max);--CP_DefineConstraintProperty(cpRotaryLimitJoint, cpFloat, min, Min);-CP_DefineConstraintProperty(cpRotaryLimitJoint, cpFloat, max, Max);
− Chipmunk-5.3.4/include/chipmunk/constraints/cpSimpleMotor.h
@@ -1,37 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */--const cpConstraintClass *cpSimpleMotorGetClass();--typedef struct cpSimpleMotor {-	cpConstraint constraint;-	cpFloat rate;-	-	cpFloat iSum;-		-	cpFloat jAcc, jMax;-} cpSimpleMotor;--cpSimpleMotor *cpSimpleMotorAlloc(void);-cpSimpleMotor *cpSimpleMotorInit(cpSimpleMotor *joint, cpBody *a, cpBody *b, cpFloat rate);-cpConstraint *cpSimpleMotorNew(cpBody *a, cpBody *b, cpFloat rate);--CP_DefineConstraintProperty(cpSimpleMotor, cpFloat, rate, Rate);
− Chipmunk-5.3.4/include/chipmunk/constraints/cpSlideJoint.h
@@ -1,44 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */--const cpConstraintClass *cpSlideJointGetClass();--typedef struct cpSlideJoint {-	cpConstraint constraint;-	cpVect anchr1, anchr2;-	cpFloat min, max;-	-	cpVect r1, r2;-	cpVect n;-	cpFloat nMass;-	-	cpFloat jnAcc, jnMax;-	cpFloat bias;-} cpSlideJoint;--cpSlideJoint *cpSlideJointAlloc(void);-cpSlideJoint *cpSlideJointInit(cpSlideJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max);-cpConstraint *cpSlideJointNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max);--CP_DefineConstraintProperty(cpSlideJoint, cpVect, anchr1, Anchr1);-CP_DefineConstraintProperty(cpSlideJoint, cpVect, anchr2, Anchr2);-CP_DefineConstraintProperty(cpSlideJoint, cpFloat, min, Min);-CP_DefineConstraintProperty(cpSlideJoint, cpFloat, max, Max);
− Chipmunk-5.3.4/include/chipmunk/constraints/util.h
@@ -1,134 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */--#define CP_DefineClassGetter(t) const cpConstraintClass * t##GetClass(){return (cpConstraintClass *)&klass;}--void cpConstraintInit(cpConstraint *constraint, const cpConstraintClass *klass, cpBody *a, cpBody *b);--#define J_MAX(constraint, dt) (((cpConstraint *)constraint)->maxForce*(dt))--// Get valid body pointers and exit early if the bodies are idle-#define CONSTRAINT_BEGIN(constraint, a_var, b_var) \-cpBody *a_var, *b_var; { \-	a_var = ((cpConstraint *)constraint)->a; \-	b_var = ((cpConstraint *)constraint)->b; \-	if( \-		(cpBodyIsSleeping(a_var) || cpBodyIsStatic(a_var)) && \-		(cpBodyIsSleeping(b_var) || cpBodyIsStatic(b_var)) \-	) return; \-}--static inline cpVect-relative_velocity(cpBody *a, cpBody *b, cpVect r1, cpVect r2){-	cpVect v1_sum = cpvadd(a->v, cpvmult(cpvperp(r1), a->w));-	cpVect v2_sum = cpvadd(b->v, cpvmult(cpvperp(r2), b->w));-	-	return cpvsub(v2_sum, v1_sum);-}--static inline cpFloat-normal_relative_velocity(cpBody *a, cpBody *b, cpVect r1, cpVect r2, cpVect n){-	return cpvdot(relative_velocity(a, b, r1, r2), n);-}--static inline void-apply_impulses(cpBody *a , cpBody *b, cpVect r1, cpVect r2, cpVect j)-{-	cpBodyApplyImpulse(a, cpvneg(j), r1);-	cpBodyApplyImpulse(b, j, r2);-}--static inline void-apply_bias_impulse(cpBody *body, cpVect j, cpVect r)-{-	body->v_bias = cpvadd(body->v_bias, cpvmult(j, body->m_inv));-	body->w_bias += body->i_inv*cpvcross(r, j);-}--static inline void-apply_bias_impulses(cpBody *a , cpBody *b, cpVect r1, cpVect r2, cpVect j)-{-	apply_bias_impulse(a, cpvneg(j), r1);-	apply_bias_impulse(b, j, r2);-}--static inline cpVect-clamp_vect(cpVect v, cpFloat len)-{-	return cpvclamp(v, len);-//	return (cpvdot(v,v) > len*len) ? cpvmult(cpvnormalize(v), len) : v;-}--static inline cpFloat-k_scalar(cpBody *a, cpBody *b, cpVect r1, cpVect r2, cpVect n)-{-	cpFloat mass_sum = a->m_inv + b->m_inv;-	cpFloat r1cn = cpvcross(r1, n);-	cpFloat r2cn = cpvcross(r2, n);-	-	cpFloat value = mass_sum + a->i_inv*r1cn*r1cn + b->i_inv*r2cn*r2cn;-	cpAssert(value != 0.0, "Unsolvable collision or constraint.");-	-	return value;-}--static inline void-k_tensor(cpBody *a, cpBody *b, cpVect r1, cpVect r2, cpVect *k1, cpVect *k2)-{-	// calculate mass matrix-	// If I wasn't lazy and wrote a proper matrix class, this wouldn't be so gross...-	cpFloat k11, k12, k21, k22;-	cpFloat m_sum = a->m_inv + b->m_inv;-	-	// start with I*m_sum-	k11 = m_sum; k12 = 0.0f;-	k21 = 0.0f;  k22 = m_sum;-	-	// add the influence from r1-	cpFloat a_i_inv = a->i_inv;-	cpFloat r1xsq =  r1.x * r1.x * a_i_inv;-	cpFloat r1ysq =  r1.y * r1.y * a_i_inv;-	cpFloat r1nxy = -r1.x * r1.y * a_i_inv;-	k11 += r1ysq; k12 += r1nxy;-	k21 += r1nxy; k22 += r1xsq;-	-	// add the influnce from r2-	cpFloat b_i_inv = b->i_inv;-	cpFloat r2xsq =  r2.x * r2.x * b_i_inv;-	cpFloat r2ysq =  r2.y * r2.y * b_i_inv;-	cpFloat r2nxy = -r2.x * r2.y * b_i_inv;-	k11 += r2ysq; k12 += r2nxy;-	k21 += r2nxy; k22 += r2xsq;-	-	// invert-	cpFloat determinant = k11*k22 - k12*k21;-	cpAssert(determinant != 0.0, "Unsolvable constraint.");-	-	cpFloat det_inv = 1.0f/determinant;-	*k1 = cpv( k22*det_inv, -k12*det_inv);-	*k2 = cpv(-k21*det_inv,  k11*det_inv);-}--static inline cpVect-mult_k(cpVect vr, cpVect k1, cpVect k2)-{-	return cpv(cpvdot(vr, k1), cpvdot(vr, k2));-}
− Chipmunk-5.3.4/include/chipmunk/cpArbiter.h
@@ -1,188 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */- - struct cpArbiter;- struct cpSpace;- struct cpCollisionHandler;--// Determines how fast penetrations resolve themselves.-extern cpFloat cp_bias_coef;-// Amount of allowed penetration. Used to reduce vibrating contacts.-extern cpFloat cp_collision_slop;--// Data structure for contact points.-typedef struct cpContact {-	// Contact point and normal.-	cpVect CP_PRIVATE(p), CP_PRIVATE(n);-	// Penetration distance.-	CP_PRIVATE(cpFloat dist);-	-	// Calculated by cpArbiterPreStep().-	cpVect CP_PRIVATE(r1), CP_PRIVATE(r2);-	cpFloat CP_PRIVATE(nMass), CP_PRIVATE(tMass), CP_PRIVATE(bounce);--	// Persistant contact information.-	cpFloat CP_PRIVATE(jnAcc), CP_PRIVATE(jtAcc), CP_PRIVATE(jBias);-	CP_PRIVATE(cpFloat bias);-	-	// Hash value used to (mostly) uniquely identify a contact.-	CP_PRIVATE(cpHashValue hash);-} cpContact;--// Contacts are always allocated in groups.-cpContact* cpContactInit(cpContact *con, cpVect p, cpVect n, cpFloat dist, cpHashValue hash);--// Sum the contact impulses. (Can be used after cpSpaceStep() returns)-cpVect CP_PRIVATE(cpContactsSumImpulses)(cpContact *contacts, int numContacts);-cpVect CP_PRIVATE(cpContactsSumImpulsesWithFriction)(cpContact *contacts, int numContacts);--#define CP_MAX_CONTACTS_PER_ARBITER 6--typedef enum cpArbiterState {-	cpArbiterStateNormal,-	cpArbiterStateFirstColl,-	cpArbiterStateIgnore,-	cpArbiterStateSleep,-	cpArbiterStateCached,-} cpArbiterState;--// Data structure for tracking collisions between shapes.-typedef struct cpArbiter {-	// Information on the contact points between the objects.-	CP_PRIVATE(int numContacts);-	CP_PRIVATE(cpContact *contacts);-	-	// The two shapes and bodies involved in the collision.-	// These variables are NOT in the order defined by the collision handler.-	// Using CP_ARBITER_GET_SHAPES and CP_ARBITER_GET_BODIES will save you from-	// many headaches-	cpShape CP_PRIVATE(*a), CP_PRIVATE(*b);-	-	// Calculated before calling the pre-solve collision handler-	// Override them with custom values if you want specialized behavior-	CP_PRIVATE(cpFloat e);-	CP_PRIVATE(cpFloat u);-	 // Used for surface_v calculations, implementation may change-	CP_PRIVATE(cpVect surface_vr);-	-	// Time stamp of the arbiter. (from cpSpace)-	CP_PRIVATE(cpTimestamp stamp);-	-	CP_PRIVATE(struct cpCollisionHandler *handler);-	-	// Are the shapes swapped in relation to the collision handler?-	CP_PRIVATE(cpBool swappedColl);-	CP_PRIVATE(cpArbiterState state);-} cpArbiter;--// Arbiters are allocated in large buffers by the space and don't require a destroy function-cpArbiter* CP_PRIVATE(cpArbiterInit)(cpArbiter *arb, cpShape *a, cpShape *b);--// These functions are all intended to be used internally.-// Inject new contact points into the arbiter while preserving contact history.-void CP_PRIVATE(cpArbiterUpdate)(cpArbiter *arb, cpContact *contacts, int numContacts, struct cpCollisionHandler *handler, cpShape *a, cpShape *b);-// Precalculate values used by the solver.-void CP_PRIVATE(cpArbiterPreStep)(cpArbiter *arb, cpFloat dt_inv);-void CP_PRIVATE(cpArbiterApplyCachedImpulse)(cpArbiter *arb);-// Run an iteration of the solver on the arbiter.-void CP_PRIVATE(cpArbiterApplyImpulse)(cpArbiter *arb, cpFloat eCoef);--// Arbiter Helper Functions-cpVect cpArbiterTotalImpulse(cpArbiter *arb);-cpVect cpArbiterTotalImpulseWithFriction(cpArbiter *arb);-void cpArbiterIgnore(cpArbiter *arb);---static inline void-cpArbiterGetShapes(const cpArbiter *arb, cpShape **a, cpShape **b)-{-	if(arb->CP_PRIVATE(swappedColl)){-		(*a) = arb->CP_PRIVATE(b), (*b) = arb->CP_PRIVATE(a);-	} else {-		(*a) = arb->CP_PRIVATE(a), (*b) = arb->CP_PRIVATE(b);-	}-}-#define CP_ARBITER_GET_SHAPES(arb, a, b) cpShape *a, *b; cpArbiterGetShapes(arb, &a, &b);--static inline void-cpArbiterGetBodies(const cpArbiter *arb, cpBody **a, cpBody **b)-{-	CP_ARBITER_GET_SHAPES(arb, shape_a, shape_b);-	(*a) = shape_a->body;-	(*b) = shape_b->body;-}-#define CP_ARBITER_GET_BODIES(arb, a, b) cpBody *a, *b; cpArbiterGetBodies(arb, &a, &b);--static inline cpBool-cpArbiterIsFirstContact(const cpArbiter *arb)-{-	return arb->CP_PRIVATE(state) == cpArbiterStateFirstColl;-}--static inline int-cpArbiterGetCount(const cpArbiter *arb)-{-	return arb->CP_PRIVATE(numContacts);-}--static inline cpVect-cpArbiterGetNormal(const cpArbiter *arb, int i)-{-	cpVect n = arb->CP_PRIVATE(contacts)[i].CP_PRIVATE(n);-	return arb->CP_PRIVATE(swappedColl) ? cpvneg(n) : n;-}--static inline cpVect-cpArbiterGetPoint(const cpArbiter *arb, int i)-{-	return arb->CP_PRIVATE(contacts)[i].CP_PRIVATE(p);-}--static inline cpFloat-cpArbiteGetDepth(const cpArbiter *arb, int i)-{-	return arb->CP_PRIVATE(contacts)[i].CP_PRIVATE(dist);-}--typedef struct cpContactPointSet {-	int count;-	-	struct {-		cpVect point, normal;-		cpFloat dist;-	} points[CP_MAX_CONTACTS_PER_ARBITER];-} cpContactPointSet;--static inline cpContactPointSet-cpArbiterGetContactPointSet(const cpArbiter *arb)-{-	cpContactPointSet set;-	set.count = cpArbiterGetCount(arb);-	-	int i;-	for(i=0; i<set.count; i++){-		set.points[i].point = arb->CP_PRIVATE(contacts)[i].CP_PRIVATE(p);-		set.points[i].normal = arb->CP_PRIVATE(contacts)[i].CP_PRIVATE(n);-		set.points[i].dist = arb->CP_PRIVATE(contacts)[i].CP_PRIVATE(dist);-	}-	-	return set;-}
− Chipmunk-5.3.4/include/chipmunk/cpArray.h
@@ -1,49 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */- -// NOTE: cpArray is rarely used and will probably go away.--typedef struct cpArray{-	CP_PRIVATE(int num);-	CP_PRIVATE(int max);-	CP_PRIVATE(void **arr);-} cpArray;--typedef void (*cpArrayIter)(void *ptr, void *data);--cpArray *cpArrayAlloc(void);-cpArray *cpArrayInit(cpArray *arr, int size);-cpArray *cpArrayNew(int size);--void cpArrayDestroy(cpArray *arr);-void cpArrayFree(cpArray *arr);--void cpArrayClear(cpArray *arr);--void cpArrayPush(cpArray *arr, void *object);-void *cpArrayPop(cpArray *arr);-void cpArrayDeleteIndex(cpArray *arr, int idx);-void cpArrayDeleteObj(cpArray *arr, void *obj);--void cpArrayAppend(cpArray *arr, cpArray *other);--void cpArrayEach(cpArray *arr, cpArrayIter iterFunc, void *data);-cpBool cpArrayContains(cpArray *arr, void *ptr);
− Chipmunk-5.3.4/include/chipmunk/cpBB.h
@@ -1,74 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */- -typedef struct cpBB{-	cpFloat l, b, r ,t;-} cpBB;--static inline cpBB-cpBBNew(const cpFloat l, const cpFloat b,-		const cpFloat r, const cpFloat t)-{-	cpBB bb = {l, b, r, t};-	return bb;-}--static inline cpBool-cpBBintersects(const cpBB a, const cpBB b)-{-	return (a.l<=b.r && b.l<=a.r && a.b<=b.t && b.b<=a.t);-}--static inline cpBool-cpBBcontainsBB(const cpBB bb, const cpBB other)-{-	return (bb.l < other.l && bb.r > other.r && bb.b < other.b && bb.t > other.t);-}--static inline cpBool-cpBBcontainsVect(const cpBB bb, const cpVect v)-{-	return (bb.l < v.x && bb.r > v.x && bb.b < v.y && bb.t > v.y);-}--static inline cpBB-cpBBmerge(const cpBB a, const cpBB b){-	return cpBBNew(-		cpfmin(a.l, b.l),-		cpfmin(a.b, b.b),-		cpfmax(a.r, b.r),-		cpfmax(a.t, b.t)-	);-}--static inline cpBB-cpBBexpand(const cpBB bb, const cpVect v){-	return cpBBNew(-		cpfmin(bb.l, v.x),-		cpfmin(bb.b, v.y),-		cpfmax(bb.r, v.x),-		cpfmax(bb.t, v.y)-	);-}--cpVect cpBBClampVect(const cpBB bb, const cpVect v); // clamps the vector to lie within the bbox-// TODO edge case issue-cpVect cpBBWrapVect(const cpBB bb, const cpVect v); // wrap a vector to a bbox
− Chipmunk-5.3.4/include/chipmunk/cpBody.h
@@ -1,219 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */--struct cpBody;-struct cpShape;-struct cpSpace;--typedef void (*cpBodyVelocityFunc)(struct cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt);-typedef void (*cpBodyPositionFunc)(struct cpBody *body, cpFloat dt);--extern cpBodyVelocityFunc cpBodyUpdateVelocityDefault;-extern cpBodyPositionFunc cpBodyUpdatePositionDefault;--// Structure to hold information about the contact graph components-// when putting groups of objects to sleep.-// No interesting user accessible fields.-typedef struct cpComponentNode {-	struct cpBody *parent;-	struct cpBody *next;-	int rank;-	cpFloat idleTime;-} cpComponentNode;--typedef struct cpBody{-	// *** Integration Functions.--	// Function that is called to integrate the body's velocity. (Defaults to cpBodyUpdateVelocity)-	cpBodyVelocityFunc velocity_func;-	-	// Function that is called to integrate the body's position. (Defaults to cpBodyUpdatePosition)-	cpBodyPositionFunc position_func;-	-	// *** Mass Properties-	-	// Mass and it's inverse.-	// Always use cpBodySetMass() whenever changing the mass as these values must agree.-	cpFloat m, m_inv;-	-	// Moment of inertia and it's inverse.-	// Always use cpBodySetMoment() whenever changing the moment as these values must agree.-	cpFloat i, i_inv;-	-	// *** Positional Properties-	-	// Linear components of motion (position, velocity, and force)-	cpVect p, v, f;-	-	// Angular components of motion (angle, angular velocity, and torque)-	// Always use cpBodySetAngle() to set the angle of the body as a and rot must agree.-	cpFloat a, w, t;-	-	// Cached unit length vector representing the angle of the body.-	// Used for fast vector rotation using cpvrotate().-	cpVect rot;-	-	// *** User Definable Fields-	-	// User defined data pointer.-	cpDataPointer data;-	-	// *** Other Fields-	-	// Maximum velocities this body can move at after integrating velocity-	cpFloat v_limit, w_limit;-	-	// *** Internally Used Fields-	-	// Velocity bias values used when solving penetrations and correcting constraints.-	CP_PRIVATE(cpVect v_bias);-	CP_PRIVATE(cpFloat w_bias);-	-	// Space this body has been added to-	CP_PRIVATE(struct cpSpace *space);-	-	// Pointer to the shape list.-	// Shapes form a linked list using cpShape.next when added to a space.-	CP_PRIVATE(struct cpShape *shapesList);-	-	// Used by cpSpaceStep() to store contact graph information.-	CP_PRIVATE(cpComponentNode node);-} cpBody;--// Basic allocation/destruction functions-cpBody *cpBodyAlloc(void);-cpBody *cpBodyInit(cpBody *body, cpFloat m, cpFloat i);-cpBody *cpBodyNew(cpFloat m, cpFloat i);--cpBody *cpBodyInitStatic(cpBody *body);-cpBody *cpBodyNewStatic();--void cpBodyDestroy(cpBody *body);-void cpBodyFree(cpBody *body);--// Wake up a sleeping or idle body. (defined in cpSpace.c)-void cpBodyActivate(cpBody *body);--// Force a body to sleep;-// defined in cpSpaceComponent.c-void cpBodySleep(cpBody *body);-void cpBodySleepWithGroup(cpBody *body, cpBody *group);--static inline cpBool-cpBodyIsSleeping(const cpBody *body)-{-	return (CP_PRIVATE(body->node).next != ((cpBody*)0));-}--static inline cpBool-cpBodyIsStatic(const cpBody *body)-{-	return CP_PRIVATE(body->node).idleTime == INFINITY;-}--static inline cpBool-cpBodyIsRogue(const cpBody *body)-{-	return (body->CP_PRIVATE(space) == ((struct cpSpace*)0));-}---#define CP_DefineBodyGetter(type, member, name) \-static inline type cpBodyGet##name(const cpBody *body){return body->member;}--#define CP_DefineBodySetter(type, member, name) \-static inline void \-cpBodySet##name(cpBody *body, const type value){ \-	cpBodyActivate(body); \-	body->member = value; \-} \--#define CP_DefineBodyProperty(type, member, name) \-CP_DefineBodyGetter(type, member, name) \-CP_DefineBodySetter(type, member, name)---// Accessors for cpBody struct members-CP_DefineBodyGetter(cpFloat, m, Mass);-void cpBodySetMass(cpBody *body, cpFloat m);--CP_DefineBodyGetter(cpFloat, i, Moment);-void cpBodySetMoment(cpBody *body, cpFloat i);---CP_DefineBodyProperty(cpVect, p, Pos);-CP_DefineBodyProperty(cpVect, v, Vel);-CP_DefineBodyProperty(cpVect, f, Force);-CP_DefineBodyGetter(cpFloat, a, Angle);-void cpBodySetAngle(cpBody *body, cpFloat a);-CP_DefineBodyProperty(cpFloat, w, AngVel);-CP_DefineBodyProperty(cpFloat, t, Torque);-CP_DefineBodyGetter(cpVect, rot, Rot);-CP_DefineBodyProperty(cpFloat, v_limit, VelLimit);-CP_DefineBodyProperty(cpFloat, w_limit, AngVelLimit);--//  Modify the velocity of the body so that it will move to the specified absolute coordinates in the next timestep.-// Intended for objects that are moved manually with a custom velocity integration function.-void cpBodySlew(cpBody *body, cpVect pos, cpFloat dt);--// Default Integration functions.-void cpBodyUpdateVelocity(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt);-void cpBodyUpdatePosition(cpBody *body, cpFloat dt);--// Convert body local to world coordinates-static inline cpVect-cpBodyLocal2World(const cpBody *body, const cpVect v)-{-	return cpvadd(body->p, cpvrotate(v, body->rot));-}--// Convert world to body local coordinates-static inline cpVect-cpBodyWorld2Local(const cpBody *body, const cpVect v)-{-	return cpvunrotate(cpvsub(v, body->p), body->rot);-}--// Apply an impulse (in world coordinates) to the body at a point relative to the center of gravity (also in world coordinates).-static inline void-cpBodyApplyImpulse(cpBody *body, const cpVect j, const cpVect r)-{-	body->v = cpvadd(body->v, cpvmult(j, body->m_inv));-	body->w += body->i_inv*cpvcross(r, j);-}--// Zero the forces on a body.-void cpBodyResetForces(cpBody *body);-// Apply a force (in world coordinates) to a body at a point relative to the center of gravity (also in world coordinates).-void cpBodyApplyForce(cpBody *body, const cpVect f, const cpVect r);--static inline cpFloat-cpBodyKineticEnergy(const cpBody *body)-{-	// Need to do some fudging to avoid NaNs-	cpFloat vsq = cpvdot(body->v, body->v);-	cpFloat wsq = body->w*body->w;-	return (vsq ? vsq*body->m : 0.0f) + (wsq ? wsq*body->i : 0.0f);-}--// Apply a damped spring force between two bodies.-// Warning: Large damping values can be unstable. Use a cpDampedSpring constraint for this instead.-void cpApplyDampedSpring(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat rlen, cpFloat k, cpFloat dmp, cpFloat dt);
− Chipmunk-5.3.4/include/chipmunk/cpCollision.h
@@ -1,28 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */--//TODO delete this header?--// Collides two cpShape structures.-// Returns the number of contact points added to arr-// which should be at least CP_MAX_CONTACTS_PER_ARBITER in length.-// This function is very lonely in this header :(-int cpCollideShapes(const cpShape *a, const cpShape *b, cpContact *arr);
− Chipmunk-5.3.4/include/chipmunk/cpHashSet.h
@@ -1,82 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */- -// cpHashSet uses a chained hashtable implementation.-// Other than the transformation functions, there is nothing fancy going on.--// cpHashSetBin's form the linked lists in the chained hash table.-typedef struct cpHashSetBin {-	// Pointer to the element.-	CP_PRIVATE(void *elt);-	// Hash value of the element.-	CP_PRIVATE(cpHashValue hash);-	// Next element in the chain.-	CP_PRIVATE(struct cpHashSetBin *next);-} cpHashSetBin;--// Equality function. Returns true if ptr is equal to elt.-typedef cpBool (*cpHashSetEqlFunc)(void *ptr, void *elt);-// Used by cpHashSetInsert(). Called to transform the ptr into an element.-typedef void *(*cpHashSetTransFunc)(void *ptr, void *data);--typedef struct cpHashSet {-	// Number of elements stored in the table.-	CP_PRIVATE(int entries);-	// Number of cells in the table.-	CP_PRIVATE(int size);-	-	CP_PRIVATE(cpHashSetEqlFunc eql);-	CP_PRIVATE(cpHashSetTransFunc trans);-	-	// Default value returned by cpHashSetFind() when no element is found.-	// Defaults to NULL.-	CP_PRIVATE(void *default_value);-	-	// The table and recycled bins-	CP_PRIVATE(cpHashSetBin **table);-	CP_PRIVATE(cpHashSetBin *pooledBins);-	-	CP_PRIVATE(cpArray *allocatedBuffers);-} cpHashSet;--// Basic allocation/destruction functions.-void cpHashSetDestroy(cpHashSet *set);-void cpHashSetFree(cpHashSet *set);--cpHashSet *cpHashSetAlloc(void);-cpHashSet *cpHashSetInit(cpHashSet *set, int size, cpHashSetEqlFunc eqlFunc, cpHashSetTransFunc trans);-cpHashSet *cpHashSetNew(int size, cpHashSetEqlFunc eqlFunc, cpHashSetTransFunc trans);--// Insert an element into the set, returns the element.-// If it doesn't already exist, the transformation function is applied.-void *cpHashSetInsert(cpHashSet *set, cpHashValue hash, void *ptr, void *data);-// Remove and return an element from the set.-void *cpHashSetRemove(cpHashSet *set, cpHashValue hash, void *ptr);-// Find an element in the set. Returns the default value if the element isn't found.-void *cpHashSetFind(cpHashSet *set, cpHashValue hash, void *ptr);--// Iterate over a hashset.-typedef void (*cpHashSetIterFunc)(void *elt, void *data);-void cpHashSetEach(cpHashSet *set, cpHashSetIterFunc func, void *data);--// Iterate over a hashset, drop the element if the func returns false.-typedef cpBool (*cpHashSetFilterFunc)(void *elt, void *data);-void cpHashSetFilter(cpHashSet *set, cpHashSetFilterFunc func, void *data);
− Chipmunk-5.3.4/include/chipmunk/cpPolyShape.h
@@ -1,103 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */--// Axis structure used by cpPolyShape.-typedef struct cpPolyShapeAxis{-	// normal-	cpVect n;-	// distance from origin-	cpFloat d;-} cpPolyShapeAxis;--// Convex polygon shape structure.-typedef struct cpPolyShape{-	CP_PRIVATE(cpShape shape);-	-	// Vertex and axis lists.-	CP_PRIVATE(int numVerts);-	CP_PRIVATE(cpVect *verts);-	CP_PRIVATE(cpPolyShapeAxis *axes);--	// Transformed vertex and axis lists.-	CP_PRIVATE(cpVect *tVerts);-	CP_PRIVATE(cpPolyShapeAxis *tAxes);-} cpPolyShape;--// Basic allocation functions.-cpPolyShape *cpPolyShapeAlloc(void);-cpPolyShape *cpPolyShapeInit(cpPolyShape *poly, cpBody *body, int numVerts, cpVect *verts, cpVect offset);-cpShape *cpPolyShapeNew(cpBody *body, int numVerts, cpVect *verts, cpVect offset);--cpPolyShape *cpBoxShapeInit(cpPolyShape *poly, cpBody *body, cpFloat width, cpFloat height);-cpShape *cpBoxShapeNew(cpBody *body, cpFloat width, cpFloat height);--// Check that a set of vertexes has a correct winding and that they are convex-cpBool cpPolyValidate(const cpVect *verts, const int numVerts);--int cpPolyShapeGetNumVerts(cpShape *shape);-cpVect cpPolyShapeGetVert(cpShape *shape, int idx);--// *** inlined utility functions--// Returns the minimum distance of the polygon to the axis.-static inline cpFloat-cpPolyShapeValueOnAxis(const cpPolyShape *poly, const cpVect n, const cpFloat d)-{-	cpVect *verts = poly->CP_PRIVATE(tVerts);-	cpFloat min = cpvdot(n, verts[0]);-	-	int i;-	for(i=1; i<poly->CP_PRIVATE(numVerts); i++)-		min = cpfmin(min, cpvdot(n, verts[i]));-	-	return min - d;-}--// Returns true if the polygon contains the vertex.-static inline cpBool-cpPolyShapeContainsVert(const cpPolyShape *poly, const cpVect v)-{-	cpPolyShapeAxis *axes = poly->CP_PRIVATE(tAxes);-	-	int i;-	for(i=0; i<poly->CP_PRIVATE(numVerts); i++){-		cpFloat dist = cpvdot(axes[i].n, v) - axes[i].d;-		if(dist > 0.0f) return cpFalse;-	}-	-	return cpTrue;-}--// Same as cpPolyShapeContainsVert() but ignores faces pointing away from the normal.-static inline cpBool-cpPolyShapeContainsVertPartial(const cpPolyShape *poly, const cpVect v, const cpVect n)-{-	cpPolyShapeAxis *axes = poly->CP_PRIVATE(tAxes);-	-	int i;-	for(i=0; i<poly->CP_PRIVATE(numVerts); i++){-		if(cpvdot(axes[i].n, n) < 0.0f) continue;-		cpFloat dist = cpvdot(axes[i].n, v) - axes[i].d;-		if(dist > 0.0f) return cpFalse;-	}-	-	return cpTrue;-}
− Chipmunk-5.3.4/include/chipmunk/cpShape.h
@@ -1,177 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */- -// Forward declarations required for defining other structs.-struct cpShape;-struct cpShapeClass;--typedef struct cpSegmentQueryInfo {-	struct cpShape *shape; // shape that was hit, NULL if no collision-	cpFloat t; // Distance along query segment, will always be in the range [0, 1].-	cpVect n; // normal of hit surface-} cpSegmentQueryInfo;--// Enumeration of shape types.-typedef enum cpShapeType{-	CP_CIRCLE_SHAPE,-	CP_SEGMENT_SHAPE,-	CP_POLY_SHAPE,-	CP_NUM_SHAPES-} cpShapeType;--// Shape class. Holds function pointers and type data.-typedef struct cpShapeClass {-	cpShapeType type;-	-	// Called by cpShapeCacheBB().-	cpBB (*cacheData)(struct cpShape *shape, cpVect p, cpVect rot);-	// Called to by cpShapeDestroy().-	void (*destroy)(struct cpShape *shape);-	-	// called by cpShapePointQuery().-	cpBool (*pointQuery)(struct cpShape *shape, cpVect p);-	-	// called by cpShapeSegmentQuery()-	 void (*segmentQuery)(struct cpShape *shape, cpVect a, cpVect b, cpSegmentQueryInfo *info);-} cpShapeClass;--// Basic shape struct that the others inherit from.-typedef struct cpShape{-	// The "class" of a shape as defined above -	CP_PRIVATE(const cpShapeClass *klass);-	-	// cpBody that the shape is attached to.-	cpBody *body;--	// Cached BBox for the shape.-	cpBB bb;-	-	// Sensors invoke callbacks, but do not generate collisions-	cpBool sensor;-	-	// *** Surface properties.-	-	// Coefficient of restitution. (elasticity)-	cpFloat e;-	// Coefficient of friction.-	cpFloat u;-	// Surface velocity used when solving for friction.-	cpVect surface_v;--	// *** User Definable Fields--	// User defined data pointer for the shape.-	cpDataPointer data;-	-	// User defined collision type for the shape.-	cpCollisionType collision_type;-	// User defined collision group for the shape.-	cpGroup group;-	// User defined layer bitmask for the shape.-	cpLayers layers;-	-	// *** Internally Used Fields-	-	// Shapes form a linked list when added to space on a non-NULL body-	CP_PRIVATE(struct cpShape *next);-	-	// Unique id used as the hash value.-	CP_PRIVATE(cpHashValue hashid);-} cpShape;--// Low level shape initialization func.-cpShape* cpShapeInit(cpShape *shape, const struct cpShapeClass *klass, cpBody *body);--// Basic destructor functions. (allocation functions are not shared)-void cpShapeDestroy(cpShape *shape);-void cpShapeFree(cpShape *shape);--// Cache the BBox of the shape.-cpBB cpShapeCacheBB(cpShape *shape);--// Test if a point lies within a shape.-cpBool cpShapePointQuery(cpShape *shape, cpVect p);--#define CP_DeclareShapeGetter(struct, type, name) type struct##Get##name(cpShape *shape)--// Circle shape structure.-typedef struct cpCircleShape{-	CP_PRIVATE(cpShape shape);-	-	// Center in body space coordinates-	CP_PRIVATE(cpVect c);-	// Radius.-	CP_PRIVATE(cpFloat r);-	-	// Transformed center. (world space coordinates)-	CP_PRIVATE(cpVect tc);-} cpCircleShape;--// Basic allocation functions for cpCircleShape.-cpCircleShape *cpCircleShapeAlloc(void);-cpCircleShape *cpCircleShapeInit(cpCircleShape *circle, cpBody *body, cpFloat radius, cpVect offset);-cpShape *cpCircleShapeNew(cpBody *body, cpFloat radius, cpVect offset);--CP_DeclareShapeGetter(cpCircleShape, cpVect, Offset);-CP_DeclareShapeGetter(cpCircleShape, cpFloat, Radius);--// Segment shape structure.-typedef struct cpSegmentShape{-	CP_PRIVATE(cpShape shape);-	-	// Endpoints and normal of the segment. (body space coordinates)-	cpVect CP_PRIVATE(a), CP_PRIVATE(b), CP_PRIVATE(n);-	// Radius of the segment. (Thickness)-	cpFloat CP_PRIVATE(r);--	// Transformed endpoints and normal. (world space coordinates)-	cpVect CP_PRIVATE(ta), CP_PRIVATE(tb), CP_PRIVATE(tn);-} cpSegmentShape;--// Basic allocation functions for cpSegmentShape.-cpSegmentShape* cpSegmentShapeAlloc(void);-cpSegmentShape* cpSegmentShapeInit(cpSegmentShape *seg, cpBody *body, cpVect a, cpVect b, cpFloat radius);-cpShape* cpSegmentShapeNew(cpBody *body, cpVect a, cpVect b, cpFloat radius);--CP_DeclareShapeGetter(cpSegmentShape, cpVect, A);-CP_DeclareShapeGetter(cpSegmentShape, cpVect, B);-CP_DeclareShapeGetter(cpSegmentShape, cpVect, Normal);-CP_DeclareShapeGetter(cpSegmentShape, cpFloat, Radius);--// For determinism, you can reset the shape id counter.-void cpResetShapeIdCounter(void);--// Directed segment queries against individual shapes.-void cpSegmentQueryInfoPrint(cpSegmentQueryInfo *info);--cpBool cpShapeSegmentQuery(cpShape *shape, cpVect a, cpVect b, cpSegmentQueryInfo *info);--static inline cpVect-cpSegmentQueryHitPoint(const cpVect start, const cpVect end, const cpSegmentQueryInfo info)-{-	return cpvlerp(start, end, info.t);-}--static inline cpFloat-cpSegmentQueryHitDist(const cpVect start, const cpVect end, const cpSegmentQueryInfo info)-{-	return cpvdist(start, end)*info.t;-}
− Chipmunk-5.3.4/include/chipmunk/cpSpace.h
@@ -1,206 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */--struct cpSpace;--// Number of frames that contact information should persist.-extern cpTimestamp cp_contact_persistence;--// User collision handler function types.-typedef cpBool (*cpCollisionBeginFunc)(cpArbiter *arb, struct cpSpace *space, void *data);-typedef cpBool (*cpCollisionPreSolveFunc)(cpArbiter *arb, struct cpSpace *space, void *data);-typedef void (*cpCollisionPostSolveFunc)(cpArbiter *arb, struct cpSpace *space, void *data);-typedef void (*cpCollisionSeparateFunc)(cpArbiter *arb, struct cpSpace *space, void *data);--// Structure for holding collision pair function information.-// Used internally.-typedef struct cpCollisionHandler {-	cpCollisionType a;-	cpCollisionType b;-	cpCollisionBeginFunc begin;-	cpCollisionPreSolveFunc preSolve;-	cpCollisionPostSolveFunc postSolve;-	cpCollisionSeparateFunc separate;-	void *data;-} cpCollisionHandler;--typedef struct cpContactBufferHeader {-	cpTimestamp stamp;-	struct cpContactBufferHeader *next;-	unsigned int numContacts;-} cpContactBufferHeader;--typedef struct cpSpace{-	// *** User definable fields-	-	// Number of iterations to use in the impulse solver to solve contacts.-	int iterations;-	-	// Number of iterations to use in the impulse solver to solve elastic collisions.-	int elasticIterations;-	-	// Default gravity to supply when integrating rigid body motions.-	cpVect gravity;-	-	// Default damping to supply when integrating rigid body motions.-	cpFloat damping;-	-	// Speed threshold for a body to be considered idle.-	// The default value of 0 means to let the space guess a good threshold based on gravity.-	cpFloat idleSpeedThreshold;-	-	// Time a group of bodies must remain idle in order to fall asleep-	// The default value of INFINITY disables the sleeping algorithm.-	cpFloat sleepTimeThreshold;-	-	// *** Internally Used Fields-	-	// When the space lock count is non zero you cannot add or remove objects-	CP_PRIVATE(int locked);-	-	// Time stamp. Is incremented on every call to cpSpaceStep().-	CP_PRIVATE(cpTimestamp stamp);--	// The static and active shape spatial hashes.-	CP_PRIVATE(cpSpaceHash *staticShapes);-	CP_PRIVATE(cpSpaceHash *activeShapes);-	-	// List of bodies in the system.-	CP_PRIVATE(cpArray *bodies);-	-	// List of groups of sleeping bodies.-	CP_PRIVATE(cpArray *sleepingComponents);-	-	// List of bodies that have been flagged to be awoken.-	CP_PRIVATE(cpArray *rousedBodies);-	-	// List of active arbiters for the impulse solver.-	CP_PRIVATE(cpArray *arbiters);-	CP_PRIVATE(cpArray *pooledArbiters);-	-	// Linked list ring of contact buffers.-	// Head is the newest buffer, and each buffer points to a newer buffer.-	// Head wraps around and points to the oldest (tail) buffer.-	CP_PRIVATE(cpContactBufferHeader *contactBuffersHead);-	CP_PRIVATE(cpContactBufferHeader *_contactBuffersTail_Deprecated);-	-	// List of buffers to be free()ed when destroying the space.-	CP_PRIVATE(cpArray *allocatedBuffers);-	-	// Persistant contact set.-	CP_PRIVATE(cpHashSet *contactSet);-	-	// List of constraints in the system.-	CP_PRIVATE(cpArray *constraints);-	-	// Set of collisionpair functions.-	CP_PRIVATE(cpHashSet *collFuncSet);-	// Default collision handler.-	CP_PRIVATE(cpCollisionHandler defaultHandler);-	-	CP_PRIVATE(cpHashSet *postStepCallbacks);-	-	cpBody staticBody;-} cpSpace;--// Basic allocation/destruction functions.-cpSpace* cpSpaceAlloc(void);-cpSpace* cpSpaceInit(cpSpace *space);-cpSpace* cpSpaceNew(void);--void cpSpaceDestroy(cpSpace *space);-void cpSpaceFree(cpSpace *space);--// Convenience function. Frees all referenced entities. (bodies, shapes and constraints)-void cpSpaceFreeChildren(cpSpace *space);--// Collision handler management functions.-void cpSpaceSetDefaultCollisionHandler(-	cpSpace *space,-	cpCollisionBeginFunc begin,-	cpCollisionPreSolveFunc preSolve,-	cpCollisionPostSolveFunc postSolve,-	cpCollisionSeparateFunc separate,-	void *data-);-void cpSpaceAddCollisionHandler(-	cpSpace *space,-	cpCollisionType a, cpCollisionType b,-	cpCollisionBeginFunc begin,-	cpCollisionPreSolveFunc preSolve,-	cpCollisionPostSolveFunc postSolve,-	cpCollisionSeparateFunc separate,-	void *data-);-void cpSpaceRemoveCollisionHandler(cpSpace *space, cpCollisionType a, cpCollisionType b);--// Add and remove entities from the system.-cpShape *cpSpaceAddShape(cpSpace *space, cpShape *shape);-cpShape *cpSpaceAddStaticShape(cpSpace *space, cpShape *shape);-cpBody *cpSpaceAddBody(cpSpace *space, cpBody *body);-cpConstraint *cpSpaceAddConstraint(cpSpace *space, cpConstraint *constraint);--void cpSpaceRemoveShape(cpSpace *space, cpShape *shape);-void cpSpaceRemoveStaticShape(cpSpace *space, cpShape *shape);-void cpSpaceRemoveBody(cpSpace *space, cpBody *body);-void cpSpaceRemoveConstraint(cpSpace *space, cpConstraint *constraint);--// Post Step function definition-typedef void (*cpPostStepFunc)(cpSpace *space, void *obj, void *data);-// Register a post step function to be called after cpSpaceStep() has finished.-// obj is used a key, you can only register one callback per unique value for obj-void cpSpaceAddPostStepCallback(cpSpace *space, cpPostStepFunc func, void *obj, void *data);--// Point query callback function-typedef void (*cpSpacePointQueryFunc)(cpShape *shape, void *data);-void cpSpacePointQuery(cpSpace *space, cpVect point, cpLayers layers, cpGroup group, cpSpacePointQueryFunc func, void *data);-cpShape *cpSpacePointQueryFirst(cpSpace *space, cpVect point, cpLayers layers, cpGroup group);--// Segment query callback function-typedef void (*cpSpaceSegmentQueryFunc)(cpShape *shape, cpFloat t, cpVect n, void *data);-void cpSpaceSegmentQuery(cpSpace *space, cpVect start, cpVect end, cpLayers layers, cpGroup group, cpSpaceSegmentQueryFunc func, void *data);-cpShape *cpSpaceSegmentQueryFirst(cpSpace *space, cpVect start, cpVect end, cpLayers layers, cpGroup group, cpSegmentQueryInfo *out);--// BB query callback function-typedef void (*cpSpaceBBQueryFunc)(cpShape *shape, void *data);-void cpSpaceBBQuery(cpSpace *space, cpBB bb, cpLayers layers, cpGroup group, cpSpaceBBQueryFunc func, void *data);--// Shape query callback function-typedef void (*cpSpaceShapeQueryFunc)(cpShape *shape, cpContactPointSet *points, void *data);-cpBool cpSpaceShapeQuery(cpSpace *space, cpShape *shape, cpSpaceShapeQueryFunc func, void *data);---void cpSpaceActivateShapesTouchingShape(cpSpace *space, cpShape *shape);---// Iterator function for iterating the bodies in a space.-typedef void (*cpSpaceBodyIterator)(cpBody *body, void *data);-void cpSpaceEachBody(cpSpace *space, cpSpaceBodyIterator func, void *data);--// Spatial hash management functions.-void cpSpaceResizeStaticHash(cpSpace *space, cpFloat dim, int count);-void cpSpaceResizeActiveHash(cpSpace *space, cpFloat dim, int count);-void cpSpaceRehashStatic(cpSpace *space);--void cpSpaceRehashShape(cpSpace *space, cpShape *shape);--// Update the space.-void cpSpaceStep(cpSpace *space, cpFloat dt);
− Chipmunk-5.3.4/include/chipmunk/cpSpaceHash.h
@@ -1,110 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */--// The spatial hash is Chipmunk's default (and currently only) spatial index type.-// Based on a chained hash table.--// Used internally to track objects added to the hash-typedef struct cpHandle{-	// Pointer to the object-	void *obj;-	// Retain count-	int retain;-	// Query stamp. Used to make sure two objects-	// aren't identified twice in the same query.-	cpTimestamp stamp;-} cpHandle;--// Linked list element for in the chains.-typedef struct cpSpaceHashBin{-	cpHandle *handle;-	struct cpSpaceHashBin *next;-} cpSpaceHashBin;--// BBox callback. Called whenever the hash needs a bounding box from an object.-typedef cpBB (*cpSpaceHashBBFunc)(void *obj);--typedef struct cpSpaceHash{-	// Number of cells in the table.-	CP_PRIVATE(int numcells);-	// Dimentions of the cells.-	CP_PRIVATE(cpFloat celldim);-	-	// BBox callback.-	CP_PRIVATE(cpSpaceHashBBFunc bbfunc);--	// Hashset of the handles and the recycled ones.-	CP_PRIVATE(cpHashSet *handleSet);-	CP_PRIVATE(cpArray *pooledHandles);-	-	// The table and the recycled bins.-	CP_PRIVATE(cpSpaceHashBin **table);-	CP_PRIVATE(cpSpaceHashBin *pooledBins);-	-	// list of buffers to free on destruction.-	CP_PRIVATE(cpArray *allocatedBuffers);-	-	// Incremented on each query. See cpHandle.stamp.-	CP_PRIVATE(cpTimestamp stamp);-} cpSpaceHash;--//Basic allocation/destruction functions.-cpSpaceHash *cpSpaceHashAlloc(void);-cpSpaceHash *cpSpaceHashInit(cpSpaceHash *hash, cpFloat celldim, int cells, cpSpaceHashBBFunc bbfunc);-cpSpaceHash *cpSpaceHashNew(cpFloat celldim, int cells, cpSpaceHashBBFunc bbfunc);--void cpSpaceHashDestroy(cpSpaceHash *hash);-void cpSpaceHashFree(cpSpaceHash *hash);--// Resize the hashtable. (Does not rehash! You must call cpSpaceHashRehash() if needed.)-void cpSpaceHashResize(cpSpaceHash *hash, cpFloat celldim, int numcells);--// Add an object to the hash.-void cpSpaceHashInsert(cpSpaceHash *hash, void *obj, cpHashValue id, cpBB _deprecated_ignored);-// Remove an object from the hash.-void cpSpaceHashRemove(cpSpaceHash *hash, void *obj, cpHashValue id);--// Iterator function-typedef void (*cpSpaceHashIterator)(void *obj, void *data);-// Iterate over the objects in the hash.-void cpSpaceHashEach(cpSpaceHash *hash, cpSpaceHashIterator func, void *data);--// Rehash the contents of the hash.-void cpSpaceHashRehash(cpSpaceHash *hash);-// Rehash only a specific object.-void cpSpaceHashRehashObject(cpSpaceHash *hash, void *obj, cpHashValue id);--// Query callback.-typedef void (*cpSpaceHashQueryFunc)(void *obj1, void *obj2, void *data);-// Point query the hash. A reference to the query point is passed as obj1 to the query callback.-void cpSpaceHashPointQuery(cpSpaceHash *hash, cpVect point, cpSpaceHashQueryFunc func, void *data);-// Query the hash for a given BBox.-void cpSpaceHashQuery(cpSpaceHash *hash, void *obj, cpBB bb, cpSpaceHashQueryFunc func, void *data);-// Run a query for the object, then insert it. (Optimized case)-void cpSpaceHashQueryInsert(cpSpaceHash *hash, void *obj, cpBB bb, cpSpaceHashQueryFunc func, void *data);-// Rehashes while querying for each object. (Optimized case) -void cpSpaceHashQueryRehash(cpSpaceHash *hash, cpSpaceHashQueryFunc func, void *data);--// Segment Query callback.-// Return value is uesd for early exits of the query.-// If while traversing the grid, the raytrace function detects that an entire grid cell is beyond the hit point, it will stop the trace.-typedef cpFloat (*cpSpaceHashSegmentQueryFunc)(void *obj1, void *obj2, void *data);-void cpSpaceHashSegmentQuery(cpSpaceHash *hash, void *obj, cpVect a, cpVect b, cpFloat t_exit, cpSpaceHashSegmentQueryFunc func, void *data);
− Chipmunk-5.3.4/include/chipmunk/cpVect.h
@@ -1,207 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */--/// Constant for the zero vector.-static const cpVect cpvzero = {0.0f,0.0f};--/// Convenience constructor for cpVect structs.-static inline cpVect-cpv(const cpFloat x, const cpFloat y)-{-	cpVect v = {x, y};-	return v;-}--// non-inlined functions--/// Returns the length of v.-cpFloat cpvlength(const cpVect v);--/// Spherical linearly interpolate between v1 and v2.-cpVect cpvslerp(const cpVect v1, const cpVect v2, const cpFloat t);--/// Spherical linearly interpolate between v1 towards v2 by no more than angle a radians-cpVect cpvslerpconst(const cpVect v1, const cpVect v2, const cpFloat a);--/// Returns the unit length vector for the given angle (in radians).-cpVect cpvforangle(const cpFloat a);--/// Returns the angular direction v is pointing in (in radians).-cpFloat cpvtoangle(const cpVect v);--/**-	Returns a string representation of v. Intended mostly for debugging purposes and not production use.-	-	@attention The string points to a static local and is reset every time the function is called.-	If you want to print more than one vector you will have to split up your printing onto separate lines.-*/-char *cpvstr(const cpVect v);--/// Check if two vectors are equal. (Be careful when comparing floating point numbers!)-static inline cpBool-cpveql(const cpVect v1, const cpVect v2)-{-	return (v1.x == v2.x && v1.y == v2.y);-}--/// Add two vectors-static inline cpVect-cpvadd(const cpVect v1, const cpVect v2)-{-	return cpv(v1.x + v2.x, v1.y + v2.y);-}--/// Negate a vector.-static inline cpVect-cpvneg(const cpVect v)-{-	return cpv(-v.x, -v.y);-}--/// Subtract two vectors.-static inline cpVect-cpvsub(const cpVect v1, const cpVect v2)-{-	return cpv(v1.x - v2.x, v1.y - v2.y);-}--/// Scalar multiplication.-static inline cpVect-cpvmult(const cpVect v, const cpFloat s)-{-	return cpv(v.x*s, v.y*s);-}--/// Vector dot product.-static inline cpFloat-cpvdot(const cpVect v1, const cpVect v2)-{-	return v1.x*v2.x + v1.y*v2.y;-}--/**-	2D vector cross product analog.-	The cross product of 2D vectors results in a 3D vector with only a z component.-	This function returns the magnitude of the z value.-*/-static inline cpFloat-cpvcross(const cpVect v1, const cpVect v2)-{-	return v1.x*v2.y - v1.y*v2.x;-}--/// Returns a perpendicular vector. (90 degree rotation)-static inline cpVect-cpvperp(const cpVect v)-{-	return cpv(-v.y, v.x);-}--/// Returns a perpendicular vector. (-90 degree rotation)-static inline cpVect-cpvrperp(const cpVect v)-{-	return cpv(v.y, -v.x);-}--/// Returns the vector projection of v1 onto v2.-static inline cpVect-cpvproject(const cpVect v1, const cpVect v2)-{-	return cpvmult(v2, cpvdot(v1, v2)/cpvdot(v2, v2));-}--/// Uses complex number multiplication to rotate v1 by v2. Scaling will occur if v1 is not a unit vector.-static inline cpVect-cpvrotate(const cpVect v1, const cpVect v2)-{-	return cpv(v1.x*v2.x - v1.y*v2.y, v1.x*v2.y + v1.y*v2.x);-}--/// Inverse of cpvrotate().-static inline cpVect-cpvunrotate(const cpVect v1, const cpVect v2)-{-	return cpv(v1.x*v2.x + v1.y*v2.y, v1.y*v2.x - v1.x*v2.y);-}--/// Returns the squared length of v. Faster than cpvlength() when you only need to compare lengths.-static inline cpFloat-cpvlengthsq(const cpVect v)-{-	return cpvdot(v, v);-}--/// Linearly interpolate between v1 and v2.-static inline cpVect-cpvlerp(const cpVect v1, const cpVect v2, const cpFloat t)-{-	return cpvadd(cpvmult(v1, 1.0f - t), cpvmult(v2, t));-}--/// Returns a normalized copy of v.-static inline cpVect-cpvnormalize(const cpVect v)-{-	return cpvmult(v, 1.0f/cpvlength(v));-}--/// Returns a normalized copy of v or cpvzero if v was already cpvzero. Protects against divide by zero errors.-static inline cpVect-cpvnormalize_safe(const cpVect v)-{-	return (v.x == 0.0f && v.y == 0.0f ? cpvzero : cpvnormalize(v));-}--/// Clamp v to length len.-static inline cpVect-cpvclamp(const cpVect v, const cpFloat len)-{-	return (cpvdot(v,v) > len*len) ? cpvmult(cpvnormalize(v), len) : v;-}--/// Linearly interpolate between v1 towards v2 by distance d.-static inline cpVect-cpvlerpconst(cpVect v1, cpVect v2, cpFloat d)-{-	return cpvadd(v1, cpvclamp(cpvsub(v2, v1), d));-}--/// Returns the distance between v1 and v2.-static inline cpFloat-cpvdist(const cpVect v1, const cpVect v2)-{-	return cpvlength(cpvsub(v1, v2));-}--/// Returns the squared distance between v1 and v2. Faster than cpvdist() when you only need to compare distances.-static inline cpFloat-cpvdistsq(const cpVect v1, const cpVect v2)-{-	return cpvlengthsq(cpvsub(v1, v2));-}--/// Returns true if the distance between v1 and v2 is less than dist.-static inline cpBool-cpvnear(const cpVect v1, const cpVect v2, const cpFloat dist)-{-	return cpvdistsq(v1, v2) < dist*dist;-}
− Chipmunk-5.3.4/src/chipmunk.c
@@ -1,151 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */- -#include <stdlib.h>-#include <stdio.h>-#define _USE_MATH_DEFINES-#include <math.h>--#include "chipmunk.h"--#ifdef __cplusplus-extern "C" {-#endif-	void cpInitCollisionFuncs(void);-#ifdef __cplusplus-}-#endif--void-cpMessage(const char *message, const char *condition, const char *file, int line, int isError)-{-	fprintf(stderr, (isError ? "Aborting due to Chipmunk error: %s\n" : "Chipmunk warning: %s\n"), message);-	fprintf(stderr, "\tFailed condition: %s\n", condition);-	fprintf(stderr, "\tSource:%s:%d\n", file, line);-	-	if(isError) abort();-}---const char *cpVersionString = "5.3.4";--void-cpInitChipmunk(void)-{-#ifndef NDEBUG-	printf("Initializing Chipmunk v%s (Debug Enabled)\n", cpVersionString);-	printf("Compile with -DNDEBUG defined to disable debug mode and runtime assertion checks\n");-#endif-	-	cpInitCollisionFuncs();-}--cpFloat-cpMomentForCircle(cpFloat m, cpFloat r1, cpFloat r2, cpVect offset)-{-	return m*(0.5f*(r1*r1 + r2*r2) + cpvlengthsq(offset));-}--cpFloat-cpAreaForCircle(cpFloat r1, cpFloat r2)-{-	return 2.0f*(cpFloat)M_PI*cpfabs(r1*r1 - r2*r2);-}--cpFloat-cpMomentForSegment(cpFloat m, cpVect a, cpVect b)-{-	cpFloat length = cpvlength(cpvsub(b, a));-	cpVect offset = cpvmult(cpvadd(a, b), 1.0f/2.0f);-	-	return m*(length*length/12.0f + cpvlengthsq(offset));-}--cpFloat-cpAreaForSegment(cpVect a, cpVect b, cpFloat r)-{-	return 2.0f*r*((cpFloat)M_PI*r + cpvdist(a, b));-}--cpFloat-cpMomentForPoly(cpFloat m, const int numVerts, const cpVect *verts, cpVect offset)-{-	cpFloat sum1 = 0.0f;-	cpFloat sum2 = 0.0f;-	for(int i=0; i<numVerts; i++){-		cpVect v1 = cpvadd(verts[i], offset);-		cpVect v2 = cpvadd(verts[(i+1)%numVerts], offset);-		-		cpFloat a = cpvcross(v2, v1);-		cpFloat b = cpvdot(v1, v1) + cpvdot(v1, v2) + cpvdot(v2, v2);-		-		sum1 += a*b;-		sum2 += a;-	}-	-	return (m*sum1)/(6.0f*sum2);-}--cpFloat-cpAreaForPoly(const int numVerts, const cpVect *verts)-{-	cpFloat area = 0.0f;-	for(int i=0; i<numVerts; i++){-		area += cpvcross(verts[i], verts[(i+1)%numVerts]);-	}-	-	return area/2.0f;-}--cpVect-cpCentroidForPoly(const int numVerts, const cpVect *verts)-{-	cpFloat sum = 0.0f;-	cpVect vsum = cpvzero;-	-	for(int i=0; i<numVerts; i++){-		cpVect v1 = verts[i];-		cpVect v2 = verts[(i+1)%numVerts];-		cpFloat cross = cpvcross(v1, v2);-		-		sum += cross;-		vsum = cpvadd(vsum, cpvmult(cpvadd(v1, v2), cross));-	}-	-	return cpvmult(vsum, 1.0f/(3.0f*sum));-}--void-cpRecenterPoly(const int numVerts, cpVect *verts){-	cpVect centroid = cpCentroidForPoly(numVerts, verts);-	-	for(int i=0; i<numVerts; i++){-		verts[i] = cpvsub(verts[i], centroid);-	}-}--cpFloat-cpMomentForBox(cpFloat m, cpFloat width, cpFloat height)-{-	return m*(width*width + height*height)/12.0f;-}--#include "chipmunk_ffi.h"
− Chipmunk-5.3.4/src/constraints/cpConstraint.c
@@ -1,54 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */--#include <stdlib.h>--#include "chipmunk_private.h"-#include "constraints/util.h"--// TODO: Comment me!--cpFloat cp_constraint_bias_coef = 0.1f;--void cpConstraintDestroy(cpConstraint *constraint){}--void-cpConstraintFree(cpConstraint *constraint)-{-	if(constraint){-		cpConstraintDestroy(constraint);-		cpfree(constraint);-	}-}--// *** defined in util.h--void-cpConstraintInit(cpConstraint *constraint, const cpConstraintClass *klass, cpBody *a, cpBody *b)-{-	constraint->klass = klass;-	constraint->a = a;-	constraint->b = b;-	-	constraint->maxForce = (cpFloat)INFINITY;-	constraint->biasCoef = cp_constraint_bias_coef;-	constraint->maxBias = (cpFloat)INFINITY;-}
− Chipmunk-5.3.4/src/constraints/cpDampedRotarySpring.c
@@ -1,105 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */--#include <stdlib.h>-#include <math.h>--#include "chipmunk_private.h"-#include "constraints/util.h"--static cpFloat-defaultSpringTorque(cpDampedRotarySpring *spring, cpFloat relativeAngle){-	return (relativeAngle - spring->restAngle)*spring->stiffness;-}--static void-preStep(cpDampedRotarySpring *spring, cpFloat dt, cpFloat dt_inv)-{-	CONSTRAINT_BEGIN(spring, a, b);-	-	cpFloat moment = a->i_inv + b->i_inv;-	spring->iSum = 1.0f/moment;--	spring->w_coef = 1.0f - cpfexp(-spring->damping*dt*moment);-	spring->target_wrn = 0.0f;--	// apply spring torque-	cpFloat j_spring = spring->springTorqueFunc((cpConstraint *)spring, a->a - b->a)*dt;-	a->w -= j_spring*a->i_inv;-	b->w += j_spring*b->i_inv;-}--static void-applyImpulse(cpDampedRotarySpring *spring)-{-	CONSTRAINT_BEGIN(spring, a, b);-	-	// compute relative velocity-	cpFloat wrn = a->w - b->w;//normal_relative_velocity(a, b, r1, r2, n) - spring->target_vrn;-	-	// compute velocity loss from drag-	// not 100% certain this is derived correctly, though it makes sense-	cpFloat w_damp = wrn*spring->w_coef;-	spring->target_wrn = wrn - w_damp;-	-	//apply_impulses(a, b, spring->r1, spring->r2, cpvmult(spring->n, v_damp*spring->nMass));-	cpFloat j_damp = w_damp*spring->iSum;-	a->w -= j_damp*a->i_inv;-	b->w += j_damp*b->i_inv;-}--static cpFloat-getImpulse(cpConstraint *constraint)-{-	return 0.0f;-}--static const cpConstraintClass klass = {-	(cpConstraintPreStepFunction)preStep,-	(cpConstraintApplyImpulseFunction)applyImpulse,-	(cpConstraintGetImpulseFunction)getImpulse,-};-CP_DefineClassGetter(cpDampedRotarySpring)--cpDampedRotarySpring *-cpDampedRotarySpringAlloc(void)-{-	return (cpDampedRotarySpring *)cpmalloc(sizeof(cpDampedRotarySpring));-}--cpDampedRotarySpring *-cpDampedRotarySpringInit(cpDampedRotarySpring *spring, cpBody *a, cpBody *b, cpFloat restAngle, cpFloat stiffness, cpFloat damping)-{-	cpConstraintInit((cpConstraint *)spring, &klass, a, b);-	-	spring->restAngle = restAngle;-	spring->stiffness = stiffness;-	spring->damping = damping;-	spring->springTorqueFunc = (cpDampedRotarySpringTorqueFunc)defaultSpringTorque;-	-	return spring;-}--cpConstraint *-cpDampedRotarySpringNew(cpBody *a, cpBody *b, cpFloat restAngle, cpFloat stiffness, cpFloat damping)-{-	return (cpConstraint *)cpDampedRotarySpringInit(cpDampedRotarySpringAlloc(), a, b, restAngle, stiffness, damping);-}
− Chipmunk-5.3.4/src/constraints/cpDampedSpring.c
@@ -1,115 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */--#include <stdlib.h>-#include <math.h>--#include "chipmunk_private.h"-#include "constraints/util.h"--static cpFloat-defaultSpringForce(cpDampedSpring *spring, cpFloat dist){-	return (spring->restLength - dist)*spring->stiffness;-}--static void-preStep(cpDampedSpring *spring, cpFloat dt, cpFloat dt_inv)-{-	CONSTRAINT_BEGIN(spring, a, b);-	-	spring->r1 = cpvrotate(spring->anchr1, a->rot);-	spring->r2 = cpvrotate(spring->anchr2, b->rot);-	-	cpVect delta = cpvsub(cpvadd(b->p, spring->r2), cpvadd(a->p, spring->r1));-	cpFloat dist = cpvlength(delta);-	spring->n = cpvmult(delta, 1.0f/(dist ? dist : INFINITY));-	-	cpFloat k = k_scalar(a, b, spring->r1, spring->r2, spring->n);-	spring->nMass = 1.0f/k;-	-	spring->target_vrn = 0.0f;-	spring->v_coef = 1.0f - cpfexp(-spring->damping*dt*k);--	// apply spring force-	cpFloat f_spring = spring->springForceFunc((cpConstraint *)spring, dist);-	apply_impulses(a, b, spring->r1, spring->r2, cpvmult(spring->n, f_spring*dt));-}--static void-applyImpulse(cpDampedSpring *spring)-{-	CONSTRAINT_BEGIN(spring, a, b);-	-	cpVect n = spring->n;-	cpVect r1 = spring->r1;-	cpVect r2 = spring->r2;--	// compute relative velocity-	cpFloat vrn = normal_relative_velocity(a, b, r1, r2, n) - spring->target_vrn;-	-	// compute velocity loss from drag-	// not 100% certain this is derived correctly, though it makes sense-	cpFloat v_damp = -vrn*spring->v_coef;-	spring->target_vrn = vrn + v_damp;-	-	apply_impulses(a, b, spring->r1, spring->r2, cpvmult(spring->n, v_damp*spring->nMass));-}--static cpFloat-getImpulse(cpConstraint *constraint)-{-	return 0.0f;-}--static const cpConstraintClass klass = {-	(cpConstraintPreStepFunction)preStep,-	(cpConstraintApplyImpulseFunction)applyImpulse,-	(cpConstraintGetImpulseFunction)getImpulse,-};-CP_DefineClassGetter(cpDampedSpring)--cpDampedSpring *-cpDampedSpringAlloc(void)-{-	return (cpDampedSpring *)cpmalloc(sizeof(cpDampedSpring));-}--cpDampedSpring *-cpDampedSpringInit(cpDampedSpring *spring, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat restLength, cpFloat stiffness, cpFloat damping)-{-	cpConstraintInit((cpConstraint *)spring, cpDampedSpringGetClass(), a, b);-	-	spring->anchr1 = anchr1;-	spring->anchr2 = anchr2;-	-	spring->restLength = restLength;-	spring->stiffness = stiffness;-	spring->damping = damping;-	spring->springForceFunc = (cpDampedSpringForceFunc)defaultSpringForce;-	-	return spring;-}--cpConstraint *-cpDampedSpringNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat restLength, cpFloat stiffness, cpFloat damping)-{-	return (cpConstraint *)cpDampedSpringInit(cpDampedSpringAlloc(), a, b, anchr1, anchr2, restLength, stiffness, damping);-}
− Chipmunk-5.3.4/src/constraints/cpGearJoint.c
@@ -1,113 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */--#include <stdlib.h>--#include "chipmunk_private.h"-#include "constraints/util.h"--static void-preStep(cpGearJoint *joint, cpFloat dt, cpFloat dt_inv)-{-	CONSTRAINT_BEGIN(joint, a, b);-	-	// calculate moment of inertia coefficient.-	joint->iSum = 1.0f/(a->i_inv*joint->ratio_inv + joint->ratio*b->i_inv);-	-	// calculate bias velocity-	cpFloat maxBias = joint->constraint.maxBias;-	joint->bias = cpfclamp(-joint->constraint.biasCoef*dt_inv*(b->a*joint->ratio - a->a - joint->phase), -maxBias, maxBias);-	-	// compute max impulse-	joint->jMax = J_MAX(joint, dt);--	// apply joint torque-	cpFloat j = joint->jAcc;-	a->w -= j*a->i_inv*joint->ratio_inv;-	b->w += j*b->i_inv;-}--static void-applyImpulse(cpGearJoint *joint)-{-	CONSTRAINT_BEGIN(joint, a, b);-	-	// compute relative rotational velocity-	cpFloat wr = b->w*joint->ratio - a->w;-	-	// compute normal impulse	-	cpFloat j = (joint->bias - wr)*joint->iSum;-	cpFloat jOld = joint->jAcc;-	joint->jAcc = cpfclamp(jOld + j, -joint->jMax, joint->jMax);-	j = joint->jAcc - jOld;-	-	// apply impulse-	a->w -= j*a->i_inv*joint->ratio_inv;-	b->w += j*b->i_inv;-}--static cpFloat-getImpulse(cpGearJoint *joint)-{-	return cpfabs(joint->jAcc);-}--static const cpConstraintClass klass = {-	(cpConstraintPreStepFunction)preStep,-	(cpConstraintApplyImpulseFunction)applyImpulse,-	(cpConstraintGetImpulseFunction)getImpulse,-};-CP_DefineClassGetter(cpGearJoint)--cpGearJoint *-cpGearJointAlloc(void)-{-	return (cpGearJoint *)cpmalloc(sizeof(cpGearJoint));-}--cpGearJoint *-cpGearJointInit(cpGearJoint *joint, cpBody *a, cpBody *b, cpFloat phase, cpFloat ratio)-{-	cpConstraintInit((cpConstraint *)joint, &klass, a, b);-	-	joint->phase = phase;-	joint->ratio = ratio;-	joint->ratio_inv = 1.0f/ratio;-	-	joint->jAcc = 0.0f;-	-	return joint;-}--cpConstraint *-cpGearJointNew(cpBody *a, cpBody *b, cpFloat phase, cpFloat ratio)-{-	return (cpConstraint *)cpGearJointInit(cpGearJointAlloc(), a, b, phase, ratio);-}--void-cpGearJointSetRatio(cpConstraint *constraint, cpFloat value)-{-	cpConstraintCheckCast(constraint, cpGearJoint);-	((cpGearJoint *)constraint)->ratio = value;-	((cpGearJoint *)constraint)->ratio_inv = 1.0f/value;-	cpConstraintActivateBodies(constraint);-}
− Chipmunk-5.3.4/src/constraints/cpGrooveJoint.c
@@ -1,161 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */--#include <stdlib.h>--#include "chipmunk_private.h"-#include "constraints/util.h"--static void-preStep(cpGrooveJoint *joint, cpFloat dt, cpFloat dt_inv)-{-	CONSTRAINT_BEGIN(joint, a, b);-	-	// calculate endpoints in worldspace-	cpVect ta = cpBodyLocal2World(a, joint->grv_a);-	cpVect tb = cpBodyLocal2World(a, joint->grv_b);--	// calculate axis-	cpVect n = cpvrotate(joint->grv_n, a->rot);-	cpFloat d = cpvdot(ta, n);-	-	joint->grv_tn = n;-	joint->r2 = cpvrotate(joint->anchr2, b->rot);-	-	// calculate tangential distance along the axis of r2-	cpFloat td = cpvcross(cpvadd(b->p, joint->r2), n);-	// calculate clamping factor and r2-	if(td <= cpvcross(ta, n)){-		joint->clamp = 1.0f;-		joint->r1 = cpvsub(ta, a->p);-	} else if(td >= cpvcross(tb, n)){-		joint->clamp = -1.0f;-		joint->r1 = cpvsub(tb, a->p);-	} else {-		joint->clamp = 0.0f;-		joint->r1 = cpvsub(cpvadd(cpvmult(cpvperp(n), -td), cpvmult(n, d)), a->p);-	}-	-	// Calculate mass tensor-	k_tensor(a, b, joint->r1, joint->r2, &joint->k1, &joint->k2);	-	-	// compute max impulse-	joint->jMaxLen = J_MAX(joint, dt);-	-	// calculate bias velocity-	cpVect delta = cpvsub(cpvadd(b->p, joint->r2), cpvadd(a->p, joint->r1));-	joint->bias = cpvclamp(cpvmult(delta, -joint->constraint.biasCoef*dt_inv), joint->constraint.maxBias);-	-	// apply accumulated impulse-	apply_impulses(a, b, joint->r1, joint->r2, joint->jAcc);-}--static inline cpVect-grooveConstrain(cpGrooveJoint *joint, cpVect j){-	cpVect n = joint->grv_tn;-	cpVect jClamp = (joint->clamp*cpvcross(j, n) > 0.0f) ? j : cpvproject(j, n);-	return cpvclamp(jClamp, joint->jMaxLen);-}--static void-applyImpulse(cpGrooveJoint *joint)-{-	CONSTRAINT_BEGIN(joint, a, b);-	-	cpVect r1 = joint->r1;-	cpVect r2 = joint->r2;-	-	// compute impulse-	cpVect vr = relative_velocity(a, b, r1, r2);--	cpVect j = mult_k(cpvsub(joint->bias, vr), joint->k1, joint->k2);-	cpVect jOld = joint->jAcc;-	joint->jAcc = grooveConstrain(joint, cpvadd(jOld, j));-	j = cpvsub(joint->jAcc, jOld);-	-	// apply impulse-	apply_impulses(a, b, joint->r1, joint->r2, j);-}--static cpFloat-getImpulse(cpGrooveJoint *joint)-{-	return cpvlength(joint->jAcc);-}--static const cpConstraintClass klass = {-	(cpConstraintPreStepFunction)preStep,-	(cpConstraintApplyImpulseFunction)applyImpulse,-	(cpConstraintGetImpulseFunction)getImpulse,-};-CP_DefineClassGetter(cpGrooveJoint)--cpGrooveJoint *-cpGrooveJointAlloc(void)-{-	return (cpGrooveJoint *)cpmalloc(sizeof(cpGrooveJoint));-}--cpGrooveJoint *-cpGrooveJointInit(cpGrooveJoint *joint, cpBody *a, cpBody *b, cpVect groove_a, cpVect groove_b, cpVect anchr2)-{-	cpConstraintInit((cpConstraint *)joint, &klass, a, b);-	-	joint->grv_a = groove_a;-	joint->grv_b = groove_b;-	joint->grv_n = cpvperp(cpvnormalize(cpvsub(groove_b, groove_a)));-	joint->anchr2 = anchr2;-	-	joint->jAcc = cpvzero;-	-	return joint;-}--cpConstraint *-cpGrooveJointNew(cpBody *a, cpBody *b, cpVect groove_a, cpVect groove_b, cpVect anchr2)-{-	return (cpConstraint *)cpGrooveJointInit(cpGrooveJointAlloc(), a, b, groove_a, groove_b, anchr2);-}--void-cpGrooveJointSetGrooveA(cpConstraint *constraint, cpVect value)-{-	cpGrooveJoint *g = (cpGrooveJoint *)constraint;-	cpConstraintCheckCast(constraint, cpGrooveJoint);-	-	g->grv_a = value;-	g->grv_n = cpvperp(cpvnormalize(cpvsub(g->grv_b, value)));-	-	cpConstraintActivateBodies(constraint);-}--void-cpGrooveJointSetGrooveB(cpConstraint *constraint, cpVect value)-{-	cpGrooveJoint *g = (cpGrooveJoint *)constraint;-	cpConstraintCheckCast(constraint, cpGrooveJoint);-	-	g->grv_b = value;-	g->grv_n = cpvperp(cpvnormalize(cpvsub(value, g->grv_a)));-	-	cpConstraintActivateBodies(constraint);-}-
− Chipmunk-5.3.4/src/constraints/cpPinJoint.c
@@ -1,116 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */--#include <stdlib.h>-//#include <math.h>--#include "chipmunk_private.h"-#include "constraints/util.h"--static void-preStep(cpPinJoint *joint, cpFloat dt, cpFloat dt_inv)-{-	CONSTRAINT_BEGIN(joint, a, b);-	-	joint->r1 = cpvrotate(joint->anchr1, a->rot);-	joint->r2 = cpvrotate(joint->anchr2, b->rot);-	-	cpVect delta = cpvsub(cpvadd(b->p, joint->r2), cpvadd(a->p, joint->r1));-	cpFloat dist = cpvlength(delta);-	joint->n = cpvmult(delta, 1.0f/(dist ? dist : (cpFloat)INFINITY));-	-	// calculate mass normal-	joint->nMass = 1.0f/k_scalar(a, b, joint->r1, joint->r2, joint->n);-	-	// calculate bias velocity-	cpFloat maxBias = joint->constraint.maxBias;-	joint->bias = cpfclamp(-joint->constraint.biasCoef*dt_inv*(dist - joint->dist), -maxBias, maxBias);-	-	// compute max impulse-	joint->jnMax = J_MAX(joint, dt);-	-	// apply accumulated impulse-	cpVect j = cpvmult(joint->n, joint->jnAcc);-	apply_impulses(a, b, joint->r1, joint->r2, j);-}--static void-applyImpulse(cpPinJoint *joint)-{-	CONSTRAINT_BEGIN(joint, a, b);-	cpVect n = joint->n;--	// compute relative velocity-	cpFloat vrn = normal_relative_velocity(a, b, joint->r1, joint->r2, n);-	-	// compute normal impulse-	cpFloat jn = (joint->bias - vrn)*joint->nMass;-	cpFloat jnOld = joint->jnAcc;-	joint->jnAcc = cpfclamp(jnOld + jn, -joint->jnMax, joint->jnMax);-	jn = joint->jnAcc - jnOld;-	-	// apply impulse-	apply_impulses(a, b, joint->r1, joint->r2, cpvmult(n, jn));-}--static cpFloat-getImpulse(cpPinJoint *joint)-{-	return cpfabs(joint->jnAcc);-}--static const cpConstraintClass klass = {-	(cpConstraintPreStepFunction)preStep,-	(cpConstraintApplyImpulseFunction)applyImpulse,-	(cpConstraintGetImpulseFunction)getImpulse,-};-CP_DefineClassGetter(cpPinJoint);---cpPinJoint *-cpPinJointAlloc(void)-{-	return (cpPinJoint *)cpmalloc(sizeof(cpPinJoint));-}--cpPinJoint *-cpPinJointInit(cpPinJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2)-{-	cpConstraintInit((cpConstraint *)joint, &klass, a, b);-	-	joint->anchr1 = anchr1;-	joint->anchr2 = anchr2;-	-	// STATIC_BODY_CHECK-	cpVect p1 = (a ? cpvadd(a->p, cpvrotate(anchr1, a->rot)) : anchr1);-	cpVect p2 = (b ? cpvadd(b->p, cpvrotate(anchr2, b->rot)) : anchr2);-	joint->dist = cpvlength(cpvsub(p2, p1));--	joint->jnAcc = 0.0f;-	-	return joint;-}--cpConstraint *-cpPinJointNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2)-{-	return (cpConstraint *)cpPinJointInit(cpPinJointAlloc(), a, b, anchr1, anchr2);-}
− Chipmunk-5.3.4/src/constraints/cpPivotJoint.c
@@ -1,114 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */--#include <stdlib.h>--#include "chipmunk_private.h"-#include "constraints/util.h"--static void-preStep(cpPivotJoint *joint, cpFloat dt, cpFloat dt_inv)-{-	CONSTRAINT_BEGIN(joint, a, b);-	-	joint->r1 = cpvrotate(joint->anchr1, a->rot);-	joint->r2 = cpvrotate(joint->anchr2, b->rot);-	-	// Calculate mass tensor-	k_tensor(a, b, joint->r1, joint->r2, &joint->k1, &joint->k2);-	-	// compute max impulse-	joint->jMaxLen = J_MAX(joint, dt);-	-	// calculate bias velocity-	cpVect delta = cpvsub(cpvadd(b->p, joint->r2), cpvadd(a->p, joint->r1));-	joint->bias = cpvclamp(cpvmult(delta, -joint->constraint.biasCoef*dt_inv), joint->constraint.maxBias);-	-	// apply accumulated impulse-	apply_impulses(a, b, joint->r1, joint->r2, joint->jAcc);-}--static void-applyImpulse(cpPivotJoint *joint)-{-	CONSTRAINT_BEGIN(joint, a, b);-	-	cpVect r1 = joint->r1;-	cpVect r2 = joint->r2;-		-	// compute relative velocity-	cpVect vr = relative_velocity(a, b, r1, r2);-	-	// compute normal impulse-	cpVect j = mult_k(cpvsub(joint->bias, vr), joint->k1, joint->k2);-	cpVect jOld = joint->jAcc;-	joint->jAcc = cpvclamp(cpvadd(joint->jAcc, j), joint->jMaxLen);-	j = cpvsub(joint->jAcc, jOld);-	-	// apply impulse-	apply_impulses(a, b, joint->r1, joint->r2, j);-}--static cpFloat-getImpulse(cpConstraint *joint)-{-	return cpvlength(((cpPivotJoint *)joint)->jAcc);-}--static const cpConstraintClass klass = {-	(cpConstraintPreStepFunction)preStep,-	(cpConstraintApplyImpulseFunction)applyImpulse,-	(cpConstraintGetImpulseFunction)getImpulse,-};-CP_DefineClassGetter(cpPivotJoint)--cpPivotJoint *-cpPivotJointAlloc(void)-{-	return (cpPivotJoint *)cpmalloc(sizeof(cpPivotJoint));-}--cpPivotJoint *-cpPivotJointInit(cpPivotJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2)-{-	cpConstraintInit((cpConstraint *)joint, &klass, a, b);-	-	joint->anchr1 = anchr1;-	joint->anchr2 = anchr2;-	-	joint->jAcc = cpvzero;-	-	return joint;-}--cpConstraint *-cpPivotJointNew2(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2)-{-	return (cpConstraint *)cpPivotJointInit(cpPivotJointAlloc(), a, b, anchr1, anchr2);-}--cpConstraint *-cpPivotJointNew(cpBody *a, cpBody *b, cpVect pivot)-{-	cpVect anchr1 = (a ? cpBodyWorld2Local(a, pivot) : pivot);-	cpVect anchr2 = (b ? cpBodyWorld2Local(b, pivot) : pivot);-	return cpPivotJointNew2(a, b, anchr1, anchr2);-}
− Chipmunk-5.3.4/src/constraints/cpRatchetJoint.c
@@ -1,126 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */--#include <stdlib.h>-#include <math.h>--#include "chipmunk_private.h"-#include "constraints/util.h"--static void-preStep(cpRatchetJoint *joint, cpFloat dt, cpFloat dt_inv)-{-	CONSTRAINT_BEGIN(joint, a, b);-	-	cpFloat angle = joint->angle;-	cpFloat phase = joint->phase;-	cpFloat ratchet = joint->ratchet;-	-	cpFloat delta = b->a - a->a;-	cpFloat diff = angle - delta;-	cpFloat pdist = 0.0f;-	-	if(diff*ratchet > 0.0f){-		pdist = diff;-	} else {-		joint->angle = cpffloor((delta - phase)/ratchet)*ratchet + phase;-	}-	-	// calculate moment of inertia coefficient.-	joint->iSum = 1.0f/(a->i_inv + b->i_inv);-	-	// calculate bias velocity-	cpFloat maxBias = joint->constraint.maxBias;-	joint->bias = cpfclamp(-joint->constraint.biasCoef*dt_inv*pdist, -maxBias, maxBias);-	-	// compute max impulse-	joint->jMax = J_MAX(joint, dt);--	// If the bias is 0, the joint is not at a limit. Reset the impulse.-	if(!joint->bias)-		joint->jAcc = 0.0f;--	// apply joint torque-	a->w -= joint->jAcc*a->i_inv;-	b->w += joint->jAcc*b->i_inv;-}--static void-applyImpulse(cpRatchetJoint *joint)-{-	if(!joint->bias) return; // early exit--	CONSTRAINT_BEGIN(joint, a, b);-	-	// compute relative rotational velocity-	cpFloat wr = b->w - a->w;-	cpFloat ratchet = joint->ratchet;-	-	// compute normal impulse	-	cpFloat j = -(joint->bias + wr)*joint->iSum;-	cpFloat jOld = joint->jAcc;-	joint->jAcc = cpfclamp((jOld + j)*ratchet, 0.0f, joint->jMax*cpfabs(ratchet))/ratchet;-	j = joint->jAcc - jOld;-	-	// apply impulse-	a->w -= j*a->i_inv;-	b->w += j*b->i_inv;-}--static cpFloat-getImpulse(cpRatchetJoint *joint)-{-	return cpfabs(joint->jAcc);-}--static const cpConstraintClass klass = {-	(cpConstraintPreStepFunction)preStep,-	(cpConstraintApplyImpulseFunction)applyImpulse,-	(cpConstraintGetImpulseFunction)getImpulse,-};-CP_DefineClassGetter(cpRatchetJoint)--cpRatchetJoint *-cpRatchetJointAlloc(void)-{-	return (cpRatchetJoint *)cpmalloc(sizeof(cpRatchetJoint));-}--cpRatchetJoint *-cpRatchetJointInit(cpRatchetJoint *joint, cpBody *a, cpBody *b, cpFloat phase, cpFloat ratchet)-{-	cpConstraintInit((cpConstraint *)joint, &klass, a, b);-	-	joint->angle = 0.0f;-	joint->phase = phase;-	joint->ratchet = ratchet;-	-	// STATIC_BODY_CHECK-	joint->angle = (b ? b->a : 0.0f) - (a ? a->a : 0.0f);-	-	return joint;-}--cpConstraint *-cpRatchetJointNew(cpBody *a, cpBody *b, cpFloat phase, cpFloat ratchet)-{-	return (cpConstraint *)cpRatchetJointInit(cpRatchetJointAlloc(), a, b, phase, ratchet);-}
− Chipmunk-5.3.4/src/constraints/cpRotaryLimitJoint.c
@@ -1,120 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */--#include <stdlib.h>--#include "chipmunk_private.h"-#include "constraints/util.h"--static void-preStep(cpRotaryLimitJoint *joint, cpFloat dt, cpFloat dt_inv)-{-	CONSTRAINT_BEGIN(joint, a, b);-	-	cpFloat dist = b->a - a->a;-	cpFloat pdist = 0.0f;-	if(dist > joint->max) {-		pdist = joint->max - dist;-	} else if(dist < joint->min) {-		pdist = joint->min - dist;-	}-	-	// calculate moment of inertia coefficient.-	joint->iSum = 1.0f/(a->i_inv + b->i_inv);-	-	// calculate bias velocity-	cpFloat maxBias = joint->constraint.maxBias;-	joint->bias = cpfclamp(-joint->constraint.biasCoef*dt_inv*(pdist), -maxBias, maxBias);-	-	// compute max impulse-	joint->jMax = J_MAX(joint, dt);--	// If the bias is 0, the joint is not at a limit. Reset the impulse.-	if(!joint->bias)-		joint->jAcc = 0.0f;--	// apply joint torque-	a->w -= joint->jAcc*a->i_inv;-	b->w += joint->jAcc*b->i_inv;-}--static void-applyImpulse(cpRotaryLimitJoint *joint)-{-	if(!joint->bias) return; // early exit--	CONSTRAINT_BEGIN(joint, a, b);-	-	// compute relative rotational velocity-	cpFloat wr = b->w - a->w;-	-	// compute normal impulse	-	cpFloat j = -(joint->bias + wr)*joint->iSum;-	cpFloat jOld = joint->jAcc;-	if(joint->bias < 0.0f){-		joint->jAcc = cpfclamp(jOld + j, 0.0f, joint->jMax);-	} else {-		joint->jAcc = cpfclamp(jOld + j, -joint->jMax, 0.0f);-	}-	j = joint->jAcc - jOld;-	-	// apply impulse-	a->w -= j*a->i_inv;-	b->w += j*b->i_inv;-}--static cpFloat-getImpulse(cpRotaryLimitJoint *joint)-{-	return cpfabs(joint->jAcc);-}--static const cpConstraintClass klass = {-	(cpConstraintPreStepFunction)preStep,-	(cpConstraintApplyImpulseFunction)applyImpulse,-	(cpConstraintGetImpulseFunction)getImpulse,-};-CP_DefineClassGetter(cpRotaryLimitJoint)--cpRotaryLimitJoint *-cpRotaryLimitJointAlloc(void)-{-	return (cpRotaryLimitJoint *)cpmalloc(sizeof(cpRotaryLimitJoint));-}--cpRotaryLimitJoint *-cpRotaryLimitJointInit(cpRotaryLimitJoint *joint, cpBody *a, cpBody *b, cpFloat min, cpFloat max)-{-	cpConstraintInit((cpConstraint *)joint, &klass, a, b);-	-	joint->min = min;-	joint->max  = max;-	-	joint->jAcc = 0.0f;-	-	return joint;-}--cpConstraint *-cpRotaryLimitJointNew(cpBody *a, cpBody *b, cpFloat min, cpFloat max)-{-	return (cpConstraint *)cpRotaryLimitJointInit(cpRotaryLimitJointAlloc(), a, b, min, max);-}
− Chipmunk-5.3.4/src/constraints/cpSimpleMotor.c
@@ -1,97 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */--#include <stdlib.h>--#include "chipmunk_private.h"-#include "constraints/util.h"--static void-preStep(cpSimpleMotor *joint, cpFloat dt, cpFloat dt_inv)-{-	CONSTRAINT_BEGIN(joint, a, b);-	-	// calculate moment of inertia coefficient.-	joint->iSum = 1.0f/(a->i_inv + b->i_inv);-	-	// compute max impulse-	joint->jMax = J_MAX(joint, dt);--	// apply joint torque-	a->w -= joint->jAcc*a->i_inv;-	b->w += joint->jAcc*b->i_inv;-}--static void-applyImpulse(cpSimpleMotor *joint)-{-	CONSTRAINT_BEGIN(joint, a, b);-	-	// compute relative rotational velocity-	cpFloat wr = b->w - a->w + joint->rate;-	-	// compute normal impulse	-	cpFloat j = -wr*joint->iSum;-	cpFloat jOld = joint->jAcc;-	joint->jAcc = cpfclamp(jOld + j, -joint->jMax, joint->jMax);-	j = joint->jAcc - jOld;-	-	// apply impulse-	a->w -= j*a->i_inv;-	b->w += j*b->i_inv;-}--static cpFloat-getImpulse(cpSimpleMotor *joint)-{-	return cpfabs(joint->jAcc);-}--static const cpConstraintClass klass = {-	(cpConstraintPreStepFunction)preStep,-	(cpConstraintApplyImpulseFunction)applyImpulse,-	(cpConstraintGetImpulseFunction)getImpulse,-};-CP_DefineClassGetter(cpSimpleMotor)--cpSimpleMotor *-cpSimpleMotorAlloc(void)-{-	return (cpSimpleMotor *)cpmalloc(sizeof(cpSimpleMotor));-}--cpSimpleMotor *-cpSimpleMotorInit(cpSimpleMotor *joint, cpBody *a, cpBody *b, cpFloat rate)-{-	cpConstraintInit((cpConstraint *)joint, &klass, a, b);-	-	joint->rate = rate;-	-	joint->jAcc = 0.0f;-	-	return joint;-}--cpConstraint *-cpSimpleMotorNew(cpBody *a, cpBody *b, cpFloat rate)-{-	return (cpConstraint *)cpSimpleMotorInit(cpSimpleMotorAlloc(), a, b, rate);-}
− Chipmunk-5.3.4/src/constraints/cpSlideJoint.c
@@ -1,129 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */--#include <stdlib.h>--#include "chipmunk_private.h"-#include "constraints/util.h"--static void-preStep(cpSlideJoint *joint, cpFloat dt, cpFloat dt_inv)-{-	CONSTRAINT_BEGIN(joint, a, b);-	-	joint->r1 = cpvrotate(joint->anchr1, a->rot);-	joint->r2 = cpvrotate(joint->anchr2, b->rot);-	-	cpVect delta = cpvsub(cpvadd(b->p, joint->r2), cpvadd(a->p, joint->r1));-	cpFloat dist = cpvlength(delta);-	cpFloat pdist = 0.0f;-	if(dist > joint->max) {-		pdist = dist - joint->max;-	} else if(dist < joint->min) {-		pdist = joint->min - dist;-		dist = -dist;-	}-	joint->n = cpvmult(delta, 1.0f/(dist ? dist : (cpFloat)INFINITY));-	-	// calculate mass normal-	joint->nMass = 1.0f/k_scalar(a, b, joint->r1, joint->r2, joint->n);-	-	// calculate bias velocity-	cpFloat maxBias = joint->constraint.maxBias;-	joint->bias = cpfclamp(-joint->constraint.biasCoef*dt_inv*(pdist), -maxBias, maxBias);-	-	// compute max impulse-	joint->jnMax = J_MAX(joint, dt);--	// apply accumulated impulse-	if(!joint->bias) //{-		// if bias is 0, then the joint is not at a limit.-		joint->jnAcc = 0.0f;-//	} else {-		cpVect j = cpvmult(joint->n, joint->jnAcc);-		apply_impulses(a, b, joint->r1, joint->r2, j);-//	}-}--static void-applyImpulse(cpSlideJoint *joint)-{-	if(!joint->bias) return;  // early exit--	CONSTRAINT_BEGIN(joint, a, b);-	-	cpVect n = joint->n;-	cpVect r1 = joint->r1;-	cpVect r2 = joint->r2;-		-	// compute relative velocity-	cpVect vr = relative_velocity(a, b, r1, r2);-	cpFloat vrn = cpvdot(vr, n);-	-	// compute normal impulse-	cpFloat jn = (joint->bias - vrn)*joint->nMass;-	cpFloat jnOld = joint->jnAcc;-	joint->jnAcc = cpfclamp(jnOld + jn, -joint->jnMax, 0.0f);-	jn = joint->jnAcc - jnOld;-	-	// apply impulse-	apply_impulses(a, b, joint->r1, joint->r2, cpvmult(n, jn));-}--static cpFloat-getImpulse(cpConstraint *joint)-{-	return cpfabs(((cpSlideJoint *)joint)->jnAcc);-}--static const cpConstraintClass klass = {-	(cpConstraintPreStepFunction)preStep,-	(cpConstraintApplyImpulseFunction)applyImpulse,-	(cpConstraintGetImpulseFunction)getImpulse,-};-CP_DefineClassGetter(cpSlideJoint)--cpSlideJoint *-cpSlideJointAlloc(void)-{-	return (cpSlideJoint *)cpmalloc(sizeof(cpSlideJoint));-}--cpSlideJoint *-cpSlideJointInit(cpSlideJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max)-{-	cpConstraintInit((cpConstraint *)joint, &klass, a, b);-	-	joint->anchr1 = anchr1;-	joint->anchr2 = anchr2;-	joint->min = min;-	joint->max = max;-	-	joint->jnAcc = 0.0f;-	-	return joint;-}--cpConstraint *-cpSlideJointNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max)-{-	return (cpConstraint *)cpSlideJointInit(cpSlideJointAlloc(), a, b, anchr1, anchr2, min, max);-}
− Chipmunk-5.3.4/src/cpArbiter.c
@@ -1,280 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */- -#include <stdlib.h>--#include "chipmunk_private.h"-#include "constraints/util.h"--cpFloat cp_bias_coef = 0.1f;-cpFloat cp_collision_slop = 0.1f;--cpContact*-cpContactInit(cpContact *con, cpVect p, cpVect n, cpFloat dist, cpHashValue hash)-{-	con->p = p;-	con->n = n;-	con->dist = dist;-	-	con->jnAcc = 0.0f;-	con->jtAcc = 0.0f;-	con->jBias = 0.0f;-	-	con->hash = hash;-		-	return con;-}--cpVect-cpArbiterTotalImpulse(cpArbiter *arb)-{-	cpContact *contacts = arb->contacts;-	cpVect sum = cpvzero;-	-	for(int i=0, count=arb->numContacts; i<count; i++){-		cpContact *con = &contacts[i];-		sum = cpvadd(sum, cpvmult(con->n, con->jnAcc));-	}-		-	return sum;-}--cpVect-cpArbiterTotalImpulseWithFriction(cpArbiter *arb)-{-	cpContact *contacts = arb->contacts;-	cpVect sum = cpvzero;-	-	for(int i=0, count=arb->numContacts; i<count; i++){-		cpContact *con = &contacts[i];-		sum = cpvadd(sum, cpvrotate(con->n, cpv(con->jnAcc, con->jtAcc)));-	}-		-	return sum;-}--cpFloat-cpContactsEstimateCrushingImpulse(cpContact *contacts, int numContacts)-{-	cpFloat fsum = 0.0f;-	cpVect vsum = cpvzero;-	-	for(int i=0; i<numContacts; i++){-		cpContact *con = &contacts[i];-		cpVect j = cpvrotate(con->n, cpv(con->jnAcc, con->jtAcc));-		-		fsum += cpvlength(j);-		vsum = cpvadd(vsum, j);-	}-	-	cpFloat vmag = cpvlength(vsum);-	return (1.0f - vmag/fsum);-}--void-cpArbiterIgnore(cpArbiter *arb)-{-	arb->state = cpArbiterStateIgnore;-}--cpArbiter*-cpArbiterAlloc(void)-{-	return (cpArbiter *)cpcalloc(1, sizeof(cpArbiter));-}--cpArbiter*-cpArbiterInit(cpArbiter *arb, cpShape *a, cpShape *b)-{-	arb->handler = NULL;-	arb->swappedColl = cpFalse;-	-	arb->e = 0.0f;-	arb->u = 0.0f;-	arb->surface_vr = cpvzero;-	-	arb->numContacts = 0;-	arb->contacts = NULL;-	-	arb->a = a;-	arb->b = b;-	-	arb->stamp = 0;-	arb->state = cpArbiterStateFirstColl;-	-	return arb;-}--cpArbiter*-cpArbiterNew(cpShape *a, cpShape *b)-{-	return cpArbiterInit(cpArbiterAlloc(), a, b);-}--void-cpArbiterDestroy(cpArbiter *arb)-{-//	if(arb->contacts) cpfree(arb->contacts);-}--void-cpArbiterFree(cpArbiter *arb)-{-	if(arb){-		cpArbiterDestroy(arb);-		cpfree(arb);-	}-}--void-cpArbiterUpdate(cpArbiter *arb, cpContact *contacts, int numContacts, cpCollisionHandler *handler, cpShape *a, cpShape *b)-{-	// Arbiters without contact data may exist if a collision function rejected the collision.-	if(arb->contacts){-		// Iterate over the possible pairs to look for hash value matches.-		for(int i=0; i<arb->numContacts; i++){-			cpContact *old = &arb->contacts[i];-			-			for(int j=0; j<numContacts; j++){-				cpContact *new_contact = &contacts[j];-				-				// This could trigger false positives, but is fairly unlikely nor serious if it does.-				if(new_contact->hash == old->hash){-					// Copy the persistant contact information.-					new_contact->jnAcc = old->jnAcc;-					new_contact->jtAcc = old->jtAcc;-				}-			}-		}-	}-	-	arb->contacts = contacts;-	arb->numContacts = numContacts;-	-	arb->handler = handler;-	arb->swappedColl = (a->collision_type != handler->a);-	-	arb->e = a->e * b->e;-	arb->u = a->u * b->u;-	arb->surface_vr = cpvsub(a->surface_v, b->surface_v);-	-	// For collisions between two similar primitive types, the order could have been swapped.-	arb->a = a;-	arb->b = b;-	-	// mark it as new if it's been cached-	if(arb->state == cpArbiterStateCached) arb->state = cpArbiterStateFirstColl;-}--void-cpArbiterPreStep(cpArbiter *arb, cpFloat dt_inv)-{-	cpBody *a = arb->a->body;-	cpBody *b = arb->b->body;-	-	for(int i=0; i<arb->numContacts; i++){-		cpContact *con = &arb->contacts[i];-		-		// Calculate the offsets.-		con->r1 = cpvsub(con->p, a->p);-		con->r2 = cpvsub(con->p, b->p);-		-		// Calculate the mass normal and mass tangent.-		con->nMass = 1.0f/k_scalar(a, b, con->r1, con->r2, con->n);-		con->tMass = 1.0f/k_scalar(a, b, con->r1, con->r2, cpvperp(con->n));-				-		// Calculate the target bias velocity.-		con->bias = -cp_bias_coef*dt_inv*cpfmin(0.0f, con->dist + cp_collision_slop);-		con->jBias = 0.0f;-		-		// Calculate the target bounce velocity.-		con->bounce = normal_relative_velocity(a, b, con->r1, con->r2, con->n)*arb->e;//cpvdot(con->n, cpvsub(v2, v1))*e;-	}-}--void-cpArbiterApplyCachedImpulse(cpArbiter *arb)-{-	cpShape *shapea = arb->a;-	cpShape *shapeb = arb->b;-		-	arb->u = shapea->u * shapeb->u;-	arb->surface_vr = cpvsub(shapeb->surface_v, shapea->surface_v);--	cpBody *a = shapea->body;-	cpBody *b = shapeb->body;-	-	for(int i=0; i<arb->numContacts; i++){-		cpContact *con = &arb->contacts[i];-		apply_impulses(a, b, con->r1, con->r2, cpvrotate(con->n, cpv(con->jnAcc, con->jtAcc)));-	}-}--void-cpArbiterApplyImpulse(cpArbiter *arb, cpFloat eCoef)-{-	cpBody *a = arb->a->body;-	cpBody *b = arb->b->body;--	for(int i=0; i<arb->numContacts; i++){-		cpContact *con = &arb->contacts[i];-		cpVect n = con->n;-		cpVect r1 = con->r1;-		cpVect r2 = con->r2;-		-		// Calculate the relative bias velocities.-		cpVect vb1 = cpvadd(a->v_bias, cpvmult(cpvperp(r1), a->w_bias));-		cpVect vb2 = cpvadd(b->v_bias, cpvmult(cpvperp(r2), b->w_bias));-		cpFloat vbn = cpvdot(cpvsub(vb2, vb1), n);-		-		// Calculate and clamp the bias impulse.-		cpFloat jbn = (con->bias - vbn)*con->nMass;-		cpFloat jbnOld = con->jBias;-		con->jBias = cpfmax(jbnOld + jbn, 0.0f);-		jbn = con->jBias - jbnOld;-		-		// Apply the bias impulse.-		apply_bias_impulses(a, b, r1, r2, cpvmult(n, jbn));--		// Calculate the relative velocity.-		cpVect vr = relative_velocity(a, b, r1, r2);-		cpFloat vrn = cpvdot(vr, n);-		-		// Calculate and clamp the normal impulse.-		cpFloat jn = -(con->bounce*eCoef + vrn)*con->nMass;-		cpFloat jnOld = con->jnAcc;-		con->jnAcc = cpfmax(jnOld + jn, 0.0f);-		jn = con->jnAcc - jnOld;-		-		// Calculate the relative tangent velocity.-		cpFloat vrt = cpvdot(cpvadd(vr, arb->surface_vr), cpvperp(n));-		-		// Calculate and clamp the friction impulse.-		cpFloat jtMax = arb->u*con->jnAcc;-		cpFloat jt = -vrt*con->tMass;-		cpFloat jtOld = con->jtAcc;-		con->jtAcc = cpfclamp(jtOld + jt, -jtMax, jtMax);-		jt = con->jtAcc - jtOld;-		-		// Apply the final impulse.-		apply_impulses(a, b, r1, r2, cpvrotate(n, cpv(jn, jt)));-	}-}
− Chipmunk-5.3.4/src/cpArray.c
@@ -1,143 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */- -#include <stdlib.h>-#include <string.h>--#include "chipmunk_private.h"---//#define CP_ARRAY_INCREMENT 10--// NOTE: cpArray is rarely used and will probably go away.--cpArray*-cpArrayAlloc(void)-{-	return (cpArray *)cpcalloc(1, sizeof(cpArray));-}--cpArray*-cpArrayInit(cpArray *arr, int size)-{-	arr->num = 0;-	-	size = (size ? size : 4);-	arr->max = size;-	arr->arr = (void **)cpmalloc(size*sizeof(void**));-	-	return arr;-}--cpArray*-cpArrayNew(int size)-{-	return cpArrayInit(cpArrayAlloc(), size);-}--void-cpArrayDestroy(cpArray *arr)-{-	cpfree(arr->arr);-	arr->arr = NULL;-}--void-cpArrayFree(cpArray *arr)-{-	if(arr){-		cpArrayDestroy(arr);-		cpfree(arr);-	}-}--void-cpArrayPush(cpArray *arr, void *object)-{-	if(arr->num == arr->max){-		arr->max *= 2;-		arr->arr = (void **)cprealloc(arr->arr, arr->max*sizeof(void**));-	}-	-	arr->arr[arr->num] = object;-	arr->num++;-}--void *-cpArrayPop(cpArray *arr)-{-	arr->num--;-	-	void *value = arr->arr[arr->num];-	arr->arr[arr->num] = NULL;-	-	return value;-}--void-cpArrayDeleteIndex(cpArray *arr, int idx)-{-	arr->num--;-	-	arr->arr[idx] = arr->arr[arr->num];-	arr->arr[arr->num] = NULL;-}--void-cpArrayDeleteObj(cpArray *arr, void *obj)-{-	for(int i=0; i<arr->num; i++){-		if(arr->arr[i] == obj){-			cpArrayDeleteIndex(arr, i);-			return;-		}-	}-}--void-cpArrayAppend(cpArray *arr, cpArray *other)-{-	void *tail = &arr->arr[arr->num];-	-	arr->num += other->num;-	if(arr->num >= arr->max){-		arr->max = arr->num;-		arr->arr = (void **)cprealloc(arr->arr, arr->max*sizeof(void**));-	}-	-	memcpy(tail, other->arr, other->num*sizeof(void**));-}--void-cpArrayEach(cpArray *arr, cpArrayIter iterFunc, void *data)-{-	for(int i=0; i<arr->num; i++)-		iterFunc(arr->arr[i], data);-}--cpBool-cpArrayContains(cpArray *arr, void *ptr)-{-	for(int i=0; i<arr->num; i++)-		if(arr->arr[i] == ptr) return cpTrue;-	-	return cpFalse;-}
− Chipmunk-5.3.4/src/cpBB.c
@@ -1,47 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */- -#include <math.h>-#include <stdlib.h>--#include "chipmunk.h"--cpVect-cpBBClampVect(const cpBB bb, const cpVect v)-{-	cpFloat x = cpfmin(cpfmax(bb.l, v.x), bb.r);-	cpFloat y = cpfmin(cpfmax(bb.b, v.y), bb.t);-	return cpv(x, y);-}--cpVect-cpBBWrapVect(const cpBB bb, const cpVect v)-{-	cpFloat ix = cpfabs(bb.r - bb.l);-	cpFloat modx = cpfmod(v.x - bb.l, ix);-	cpFloat x = (modx > 0.0f) ? modx : modx + ix;-	-	cpFloat iy = cpfabs(bb.t - bb.b);-	cpFloat mody = cpfmod(v.y - bb.b, iy);-	cpFloat y = (mody > 0.0f) ? mody : mody + iy;-	-	return cpv(x + bb.l, y + bb.b);-}
− Chipmunk-5.3.4/src/cpBody.c
@@ -1,192 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */- -#include <stdlib.h>-#include <float.h>-#include <stdarg.h>--#include "chipmunk_private.h"--// initialized in cpInitChipmunk()-cpBody cpStaticBodySingleton;--cpBody*-cpBodyAlloc(void)-{-	return (cpBody *)cpmalloc(sizeof(cpBody));-}--cpBodyVelocityFunc cpBodyUpdateVelocityDefault = cpBodyUpdateVelocity;-cpBodyPositionFunc cpBodyUpdatePositionDefault = cpBodyUpdatePosition;--cpBody*-cpBodyInit(cpBody *body, cpFloat m, cpFloat i)-{-	body->velocity_func = cpBodyUpdateVelocityDefault;-	body->position_func = cpBodyUpdatePositionDefault;-	-	cpBodySetMass(body, m);-	cpBodySetMoment(body, i);--	body->p = cpvzero;-	body->v = cpvzero;-	body->f = cpvzero;-	-	cpBodySetAngle(body, 0.0f);-	body->w = 0.0f;-	body->t = 0.0f;-	-	body->v_bias = cpvzero;-	body->w_bias = 0.0f;-	-	body->data = NULL;-	body->v_limit = (cpFloat)INFINITY;-	body->w_limit = (cpFloat)INFINITY;-	-	body->space = NULL;-	body->shapesList = NULL;-	-	cpComponentNode node = {NULL, NULL, 0, 0.0f};-	body->node = node;-	-	return body;-}--cpBody*-cpBodyNew(cpFloat m, cpFloat i)-{-	return cpBodyInit(cpBodyAlloc(), m, i);-}--cpBody *-cpBodyInitStatic(cpBody *body)-{-	cpBodyInit(body, (cpFloat)INFINITY, (cpFloat)INFINITY);-	body->node.idleTime = (cpFloat)INFINITY;-	-	return body;-}--cpBody *-cpBodyNewStatic()-{-	return cpBodyInitStatic(cpBodyAlloc());-}--void cpBodyDestroy(cpBody *body){}--void-cpBodyFree(cpBody *body)-{-	if(body){-		cpBodyDestroy(body);-		cpfree(body);-	}-}--void-cpBodySetMass(cpBody *body, cpFloat mass)-{-	body->m = mass;-	body->m_inv = 1.0f/mass;-}--void-cpBodySetMoment(cpBody *body, cpFloat moment)-{-	body->i = moment;-	body->i_inv = 1.0f/moment;-}--void-cpBodySetAngle(cpBody *body, cpFloat angle)-{-	body->a = angle;//fmod(a, (cpFloat)M_PI*2.0f);-	body->rot = cpvforangle(angle);-}--void-cpBodySlew(cpBody *body, cpVect pos, cpFloat dt)-{-	cpVect delta = cpvsub(pos, body->p);-	body->v = cpvmult(delta, 1.0f/dt);-}--void-cpBodyUpdateVelocity(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt)-{-	body->v = cpvclamp(cpvadd(cpvmult(body->v, damping), cpvmult(cpvadd(gravity, cpvmult(body->f, body->m_inv)), dt)), body->v_limit);-	-	cpFloat w_limit = body->w_limit;-	body->w = cpfclamp(body->w*damping + body->t*body->i_inv*dt, -w_limit, w_limit);-}--void-cpBodyUpdatePosition(cpBody *body, cpFloat dt)-{-	body->p = cpvadd(body->p, cpvmult(cpvadd(body->v, body->v_bias), dt));-	cpBodySetAngle(body, body->a + (body->w + body->w_bias)*dt);-	-	body->v_bias = cpvzero;-	body->w_bias = 0.0f;-}--void-cpBodyResetForces(cpBody *body)-{-	body->f = cpvzero;-	body->t = 0.0f;-}--void-cpBodyApplyForce(cpBody *body, cpVect force, cpVect r)-{-	body->f = cpvadd(body->f, force);-	body->t += cpvcross(r, force);-}--void-cpApplyDampedSpring(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat rlen, cpFloat k, cpFloat dmp, cpFloat dt)-{-	// Calculate the world space anchor coordinates.-	cpVect r1 = cpvrotate(anchr1, a->rot);-	cpVect r2 = cpvrotate(anchr2, b->rot);-	-	cpVect delta = cpvsub(cpvadd(b->p, r2), cpvadd(a->p, r1));-	cpFloat dist = cpvlength(delta);-	cpVect n = dist ? cpvmult(delta, 1.0f/dist) : cpvzero;-	-	cpFloat f_spring = (dist - rlen)*k;--	// Calculate the world relative velocities of the anchor points.-	cpVect v1 = cpvadd(a->v, cpvmult(cpvperp(r1), a->w));-	cpVect v2 = cpvadd(b->v, cpvmult(cpvperp(r2), b->w));-	-	// Calculate the damping force.-	// This really should be in the impulse solver and can produce problems when using large damping values.-	cpFloat vrn = cpvdot(cpvsub(v2, v1), n);-	cpFloat f_damp = vrn*cpfmin(dmp, 1.0f/(dt*(a->m_inv + b->m_inv)));-	-	// Apply!-	cpVect f = cpvmult(n, f_spring + f_damp);-	cpBodyApplyForce(a, f, r1);-	cpBodyApplyForce(b, cpvneg(f), r2);-}
− Chipmunk-5.3.4/src/cpCollision.c
@@ -1,411 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */- -#include <stdlib.h>-#include <math.h>-//#include <stdio.h>--#include "chipmunk_private.h"--typedef int (*collisionFunc)(const cpShape *, const cpShape *, cpContact *);--// Add contact points for circle to circle collisions.-// Used by several collision tests.-static int-circle2circleQuery(const cpVect p1, const cpVect p2, const cpFloat r1, const cpFloat r2, cpContact *con)-{-	cpFloat mindist = r1 + r2;-	cpVect delta = cpvsub(p2, p1);-	cpFloat distsq = cpvlengthsq(delta);-	if(distsq >= mindist*mindist) return 0;-	-	cpFloat dist = cpfsqrt(distsq);--	// Allocate and initialize the contact.-	cpContactInit(-		con,-		cpvadd(p1, cpvmult(delta, 0.5f + (r1 - 0.5f*mindist)/(dist ? dist : INFINITY))),-		(dist ? cpvmult(delta, 1.0f/dist) : cpv(1.0f, 0.0f)),-		dist - mindist,-		0-	);-	-	return 1;-}--// Collide circle shapes.-static int-circle2circle(const cpShape *shape1, const cpShape *shape2, cpContact *arr)-{-	cpCircleShape *circ1 = (cpCircleShape *)shape1;-	cpCircleShape *circ2 = (cpCircleShape *)shape2;-	-	return circle2circleQuery(circ1->tc, circ2->tc, circ1->r, circ2->r, arr);-}--// Collide circles to segment shapes.-static int-circle2segment(const cpShape *circleShape, const cpShape *segmentShape, cpContact *con)-{-	cpCircleShape *circ = (cpCircleShape *)circleShape;-	cpSegmentShape *seg = (cpSegmentShape *)segmentShape;-	-	// Radius sum-	cpFloat rsum = circ->r + seg->r;-	-	// Calculate normal distance from segment.-	cpFloat dn = cpvdot(seg->tn, circ->tc) - cpvdot(seg->ta, seg->tn);-	cpFloat dist = cpfabs(dn) - rsum;-	if(dist > 0.0f) return 0;-	-	// Calculate tangential distance along segment.-	cpFloat dt = -cpvcross(seg->tn, circ->tc);-	cpFloat dtMin = -cpvcross(seg->tn, seg->ta);-	cpFloat dtMax = -cpvcross(seg->tn, seg->tb);-	-	// Decision tree to decide which feature of the segment to collide with.-	if(dt < dtMin){-		if(dt < (dtMin - rsum)){-			return 0;-		} else {-			return circle2circleQuery(circ->tc, seg->ta, circ->r, seg->r, con);-		}-	} else {-		if(dt < dtMax){-			cpVect n = (dn < 0.0f) ? seg->tn : cpvneg(seg->tn);-			cpContactInit(-				con,-				cpvadd(circ->tc, cpvmult(n, circ->r + dist*0.5f)),-				n,-				dist,-				0				 -			);-			return 1;-		} else {-			if(dt < (dtMax + rsum)) {-				return circle2circleQuery(circ->tc, seg->tb, circ->r, seg->r, con);-			} else {-				return 0;-			}-		}-	}-	-	return 1;-}--// Helper function for working with contact buffers-// This used to malloc/realloc memory on the fly but was repurposed.-static cpContact *-nextContactPoint(cpContact *arr, int *numPtr)-{-	int index = *numPtr;-	-	if(index < CP_MAX_CONTACTS_PER_ARBITER){-		(*numPtr) = index + 1;-		return &arr[index];-	} else {-		return &arr[CP_MAX_CONTACTS_PER_ARBITER - 1];-	}-}--// Find the minimum separating axis for the give poly and axis list.-static inline int-findMSA(const cpPolyShape *poly, const cpPolyShapeAxis *axes, const int num, cpFloat *min_out)-{-	int min_index = 0;-	cpFloat min = cpPolyShapeValueOnAxis(poly, axes->n, axes->d);-	if(min > 0.0f) return -1;-	-	for(int i=1; i<num; i++){-		cpFloat dist = cpPolyShapeValueOnAxis(poly, axes[i].n, axes[i].d);-		if(dist > 0.0f) {-			return -1;-		} else if(dist > min){-			min = dist;-			min_index = i;-		}-	}-	-	(*min_out) = min;-	return min_index;-}--// Add contacts for probably penetrating vertexes.-// This handles the degenerate case where an overlap was detected, but no vertexes fall inside-// the opposing polygon. (like a star of david)-static inline int-findVertsFallback(cpContact *arr, const cpPolyShape *poly1, const cpPolyShape *poly2, const cpVect n, const cpFloat dist)-{-	int num = 0;-	-	for(int i=0; i<poly1->numVerts; i++){-		cpVect v = poly1->tVerts[i];-		if(cpPolyShapeContainsVertPartial(poly2, v, cpvneg(n)))-			cpContactInit(nextContactPoint(arr, &num), v, n, dist, CP_HASH_PAIR(poly1->shape.hashid, i));-	}-	-	for(int i=0; i<poly2->numVerts; i++){-		cpVect v = poly2->tVerts[i];-		if(cpPolyShapeContainsVertPartial(poly1, v, n))-			cpContactInit(nextContactPoint(arr, &num), v, n, dist, CP_HASH_PAIR(poly2->shape.hashid, i));-	}-	-	return num;-}--// Add contacts for penetrating vertexes.-static inline int-findVerts(cpContact *arr, const cpPolyShape *poly1, const cpPolyShape *poly2, const cpVect n, const cpFloat dist)-{-	int num = 0;-	-	for(int i=0; i<poly1->numVerts; i++){-		cpVect v = poly1->tVerts[i];-		if(cpPolyShapeContainsVert(poly2, v))-			cpContactInit(nextContactPoint(arr, &num), v, n, dist, CP_HASH_PAIR(poly1->shape.hashid, i));-	}-	-	for(int i=0; i<poly2->numVerts; i++){-		cpVect v = poly2->tVerts[i];-		if(cpPolyShapeContainsVert(poly1, v))-			cpContactInit(nextContactPoint(arr, &num), v, n, dist, CP_HASH_PAIR(poly2->shape.hashid, i));-	}-	-	return (num ? num : findVertsFallback(arr, poly1, poly2, n, dist));-}--// Collide poly shapes together.-static int-poly2poly(const cpShape *shape1, const cpShape *shape2, cpContact *arr)-{-	cpPolyShape *poly1 = (cpPolyShape *)shape1;-	cpPolyShape *poly2 = (cpPolyShape *)shape2;-	-	cpFloat min1;-	int mini1 = findMSA(poly2, poly1->tAxes, poly1->numVerts, &min1);-	if(mini1 == -1) return 0;-	-	cpFloat min2;-	int mini2 = findMSA(poly1, poly2->tAxes, poly2->numVerts, &min2);-	if(mini2 == -1) return 0;-	-	// There is overlap, find the penetrating verts-	if(min1 > min2)-		return findVerts(arr, poly1, poly2, poly1->tAxes[mini1].n, min1);-	else-		return findVerts(arr, poly1, poly2, cpvneg(poly2->tAxes[mini2].n), min2);-}--// Like cpPolyValueOnAxis(), but for segments.-static inline cpFloat-segValueOnAxis(const cpSegmentShape *seg, const cpVect n, const cpFloat d)-{-	cpFloat a = cpvdot(n, seg->ta) - seg->r;-	cpFloat b = cpvdot(n, seg->tb) - seg->r;-	return cpfmin(a, b) - d;-}--// Identify vertexes that have penetrated the segment.-static inline void-findPointsBehindSeg(cpContact *arr, int *num, const cpSegmentShape *seg, const cpPolyShape *poly, const cpFloat pDist, const cpFloat coef) -{-	cpFloat dta = cpvcross(seg->tn, seg->ta);-	cpFloat dtb = cpvcross(seg->tn, seg->tb);-	cpVect n = cpvmult(seg->tn, coef);-	-	for(int i=0; i<poly->numVerts; i++){-		cpVect v = poly->tVerts[i];-		if(cpvdot(v, n) < cpvdot(seg->tn, seg->ta)*coef + seg->r){-			cpFloat dt = cpvcross(seg->tn, v);-			if(dta >= dt && dt >= dtb){-				cpContactInit(nextContactPoint(arr, num), v, n, pDist, CP_HASH_PAIR(poly->shape.hashid, i));-			}-		}-	}-}--// This one is complicated and gross. Just don't go there...-// TODO: Comment me!-static int-seg2poly(const cpShape *shape1, const cpShape *shape2, cpContact *arr)-{-	cpSegmentShape *seg = (cpSegmentShape *)shape1;-	cpPolyShape *poly = (cpPolyShape *)shape2;-	cpPolyShapeAxis *axes = poly->tAxes;-	-	cpFloat segD = cpvdot(seg->tn, seg->ta);-	cpFloat minNorm = cpPolyShapeValueOnAxis(poly, seg->tn, segD) - seg->r;-	cpFloat minNeg = cpPolyShapeValueOnAxis(poly, cpvneg(seg->tn), -segD) - seg->r;-	if(minNeg > 0.0f || minNorm > 0.0f) return 0;-	-	int mini = 0;-	cpFloat poly_min = segValueOnAxis(seg, axes->n, axes->d);-	if(poly_min > 0.0f) return 0;-	for(int i=0; i<poly->numVerts; i++){-		cpFloat dist = segValueOnAxis(seg, axes[i].n, axes[i].d);-		if(dist > 0.0f){-			return 0;-		} else if(dist > poly_min){-			poly_min = dist;-			mini = i;-		}-	}-	-	int num = 0;-	-	cpVect poly_n = cpvneg(axes[mini].n);-	-	cpVect va = cpvadd(seg->ta, cpvmult(poly_n, seg->r));-	cpVect vb = cpvadd(seg->tb, cpvmult(poly_n, seg->r));-	if(cpPolyShapeContainsVert(poly, va))-		cpContactInit(nextContactPoint(arr, &num), va, poly_n, poly_min, CP_HASH_PAIR(seg->shape.hashid, 0));-	if(cpPolyShapeContainsVert(poly, vb))-		cpContactInit(nextContactPoint(arr, &num), vb, poly_n, poly_min, CP_HASH_PAIR(seg->shape.hashid, 1));--	// Floating point precision problems here.-	// This will have to do for now.-	poly_min -= cp_collision_slop;-	if(minNorm >= poly_min || minNeg >= poly_min) {-		if(minNorm > minNeg)-			findPointsBehindSeg(arr, &num, seg, poly, minNorm, 1.0f);-		else-			findPointsBehindSeg(arr, &num, seg, poly, minNeg, -1.0f);-	}-	-	// If no other collision points are found, try colliding endpoints.-	if(num == 0){-		cpVect poly_a = poly->tVerts[mini];-		cpVect poly_b = poly->tVerts[(mini + 1)%poly->numVerts];-		-		if(circle2circleQuery(seg->ta, poly_a, seg->r, 0.0f, arr))-			return 1;-			-		if(circle2circleQuery(seg->tb, poly_a, seg->r, 0.0f, arr))-			return 1;-			-		if(circle2circleQuery(seg->ta, poly_b, seg->r, 0.0f, arr))-			return 1;-			-		if(circle2circleQuery(seg->tb, poly_b, seg->r, 0.0f, arr))-			return 1;-	}--	return num;-}--// This one is less gross, but still gross.-// TODO: Comment me!-static int-circle2poly(const cpShape *shape1, const cpShape *shape2, cpContact *con)-{-	cpCircleShape *circ = (cpCircleShape *)shape1;-	cpPolyShape *poly = (cpPolyShape *)shape2;-	cpPolyShapeAxis *axes = poly->tAxes;-	-	int mini = 0;-	cpFloat min = cpvdot(axes->n, circ->tc) - axes->d - circ->r;-	for(int i=0; i<poly->numVerts; i++){-		cpFloat dist = cpvdot(axes[i].n, circ->tc) - axes[i].d - circ->r;-		if(dist > 0.0f){-			return 0;-		} else if(dist > min) {-			min = dist;-			mini = i;-		}-	}-	-	cpVect n = axes[mini].n;-	cpVect a = poly->tVerts[mini];-	cpVect b = poly->tVerts[(mini + 1)%poly->numVerts];-	cpFloat dta = cpvcross(n, a);-	cpFloat dtb = cpvcross(n, b);-	cpFloat dt = cpvcross(n, circ->tc);-		-	if(dt < dtb){-		return circle2circleQuery(circ->tc, b, circ->r, 0.0f, con);-	} else if(dt < dta) {-		cpContactInit(-			con,-			cpvsub(circ->tc, cpvmult(n, circ->r + min/2.0f)),-			cpvneg(n),-			min,-			0				 -		);-	-		return 1;-	} else {-		return circle2circleQuery(circ->tc, a, circ->r, 0.0f, con);-	}-}--//static const collisionFunc builtinCollisionFuncs[9] = {-//	circle2circle,-//	NULL,-//	NULL,-//	circle2segment,-//	NULL,-//	NULL,-//	circle2poly,-//	seg2poly,-//	poly2poly,-//};-//static const collisionFunc *colfuncs = builtinCollisionFuncs;--static collisionFunc *colfuncs = NULL;--static void-addColFunc(const cpShapeType a, const cpShapeType b, const collisionFunc func)-{-	colfuncs[a + b*CP_NUM_SHAPES] = func;-}--#ifdef __cplusplus-extern "C" {-#endif-	void cpInitCollisionFuncs(void);-	-	// Initializes the array of collision functions.-	// Called by cpInitChipmunk().-	void-	cpInitCollisionFuncs(void)-	{-		if(!colfuncs)-			colfuncs = (collisionFunc *)cpcalloc(CP_NUM_SHAPES*CP_NUM_SHAPES, sizeof(collisionFunc));-		-		addColFunc(CP_CIRCLE_SHAPE,  CP_CIRCLE_SHAPE,  circle2circle);-		addColFunc(CP_CIRCLE_SHAPE,  CP_SEGMENT_SHAPE, circle2segment);-		addColFunc(CP_SEGMENT_SHAPE, CP_POLY_SHAPE,    seg2poly);-		addColFunc(CP_CIRCLE_SHAPE,  CP_POLY_SHAPE,    circle2poly);-		addColFunc(CP_POLY_SHAPE,    CP_POLY_SHAPE,    poly2poly);-	}	-#ifdef __cplusplus-}-#endif--int-cpCollideShapes(const cpShape *a, const cpShape *b, cpContact *arr)-{-	// Their shape types must be in order.-	cpAssert(a->klass->type <= b->klass->type, "Collision shapes passed to cpCollideShapes() are not sorted.");-	-	collisionFunc cfunc = colfuncs[a->klass->type + b->klass->type*CP_NUM_SHAPES];-	return (cfunc) ? cfunc(a, b, arr) : 0;-}
− Chipmunk-5.3.4/src/cpHashSet.c
@@ -1,253 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */- -#include <stdlib.h>-#include <assert.h>--#include "chipmunk_private.h"-#include "prime.h"--static void freeWrap(void *ptr, void *unused){cpfree(ptr);}--void-cpHashSetDestroy(cpHashSet *set)-{-	// Free the table.-	cpfree(set->table);-	-	cpArrayEach(set->allocatedBuffers, freeWrap, NULL);-	cpArrayFree(set->allocatedBuffers);-}--void-cpHashSetFree(cpHashSet *set)-{-	if(set){-		cpHashSetDestroy(set);-		cpfree(set);-	}-}--cpHashSet *-cpHashSetAlloc(void)-{-	return (cpHashSet *)cpcalloc(1, sizeof(cpHashSet));-}--cpHashSet *-cpHashSetInit(cpHashSet *set, int size, cpHashSetEqlFunc eqlFunc, cpHashSetTransFunc trans)-{-	set->size = next_prime(size);-	set->entries = 0;-	-	set->eql = eqlFunc;-	set->trans = trans;-	-	set->default_value = NULL;-	-	set->table = (cpHashSetBin **)cpcalloc(set->size, sizeof(cpHashSetBin *));-	set->pooledBins = NULL;-	-	set->allocatedBuffers = cpArrayNew(0);-	-	return set;-}--cpHashSet *-cpHashSetNew(int size, cpHashSetEqlFunc eqlFunc, cpHashSetTransFunc trans)-{-	return cpHashSetInit(cpHashSetAlloc(), size, eqlFunc, trans);-}--static int-setIsFull(cpHashSet *set)-{-	return (set->entries >= set->size);-}--static void-cpHashSetResize(cpHashSet *set)-{-	// Get the next approximate doubled prime.-	int newSize = next_prime(set->size + 1);-	// Allocate a new table.-	cpHashSetBin **newTable = (cpHashSetBin **)cpcalloc(newSize, sizeof(cpHashSetBin *));-	-	// Iterate over the chains.-	for(int i=0; i<set->size; i++){-		// Rehash the bins into the new table.-		cpHashSetBin *bin = set->table[i];-		while(bin){-			cpHashSetBin *next = bin->next;-			-			int idx = bin->hash%newSize;-			bin->next = newTable[idx];-			newTable[idx] = bin;-			-			bin = next;-		}-	}-	-	cpfree(set->table);-	-	set->table = newTable;-	set->size = newSize;-}--static inline void-recycleBin(cpHashSet *set, cpHashSetBin *bin)-{-	bin->next = set->pooledBins;-	set->pooledBins = bin;-	bin->elt = NULL;-}--static cpHashSetBin *-getUnusedBin(cpHashSet *set)-{-	cpHashSetBin *bin = set->pooledBins;-	-	if(bin){-		set->pooledBins = bin->next;-		return bin;-	} else {-		// Pool is exhausted, make more-		int count = CP_BUFFER_BYTES/sizeof(cpHashSetBin);-		cpAssert(count, "Buffer size is too small.");-		-		cpHashSetBin *buffer = (cpHashSetBin *)cpmalloc(CP_BUFFER_BYTES);-		cpArrayPush(set->allocatedBuffers, buffer);-		-		// push all but the first one, return the first instead-		for(int i=1; i<count; i++) recycleBin(set, buffer + i);-		return buffer;-	}-}--void *-cpHashSetInsert(cpHashSet *set, cpHashValue hash, void *ptr, void *data)-{-	int idx = hash%set->size;-	-	// Find the bin with the matching element.-	cpHashSetBin *bin = set->table[idx];-	while(bin && !set->eql(ptr, bin->elt))-		bin = bin->next;-	-	// Create it necessary.-	if(!bin){-		bin = getUnusedBin(set);-		bin->hash = hash;-		bin->elt = set->trans(ptr, data); // Transform the pointer.-		-		bin->next = set->table[idx];-		set->table[idx] = bin;-		-		set->entries++;-		-		// Resize the set if it's full.-		if(setIsFull(set))-			cpHashSetResize(set);-	}-	-	return bin->elt;-}--void *-cpHashSetRemove(cpHashSet *set, cpHashValue hash, void *ptr)-{-	int idx = hash%set->size;-	-	// Pointer to the previous bin pointer.-	cpHashSetBin **prev_ptr = &set->table[idx];-	// Pointer the the current bin.-	cpHashSetBin *bin = set->table[idx];-	-	// Find the bin-	while(bin && !set->eql(ptr, bin->elt)){-		prev_ptr = &bin->next;-		bin = bin->next;-	}-	-	// Remove it if it exists.-	if(bin){-		// Update the previous bin pointer to point to the next bin.-		(*prev_ptr) = bin->next;-		set->entries--;-		-		void *return_value = bin->elt;-		-		recycleBin(set, bin);-		-		return return_value;-	}-	-	return NULL;-}--void *-cpHashSetFind(cpHashSet *set, cpHashValue hash, void *ptr)-{	-	int idx = hash%set->size;-	cpHashSetBin *bin = set->table[idx];-	while(bin && !set->eql(ptr, bin->elt))-		bin = bin->next;-		-	return (bin ? bin->elt : set->default_value);-}--void-cpHashSetEach(cpHashSet *set, cpHashSetIterFunc func, void *data)-{-	for(int i=0; i<set->size; i++){-		cpHashSetBin *bin = set->table[i];-		while(bin){-			cpHashSetBin *next = bin->next;-			func(bin->elt, data);-			bin = next;-		}-	}-}--void-cpHashSetFilter(cpHashSet *set, cpHashSetFilterFunc func, void *data)-{-	// Iterate over all the chains.-	for(int i=0; i<set->size; i++){-		// The rest works similarly to cpHashSetRemove() above.-		cpHashSetBin **prev_ptr = &set->table[i];-		cpHashSetBin *bin = set->table[i];-		while(bin){-			cpHashSetBin *next = bin->next;-			-			if(func(bin->elt, data)){-				prev_ptr = &bin->next;-			} else {-				(*prev_ptr) = next;--				set->entries--;-				recycleBin(set, bin);-			}-			-			bin = next;-		}-	}-}
− Chipmunk-5.3.4/src/cpPolyShape.c
@@ -1,240 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */- -#include <stdlib.h>--#include "chipmunk_private.h"-#include "chipmunk_unsafe.h"--cpPolyShape *-cpPolyShapeAlloc(void)-{-	return (cpPolyShape *)cpcalloc(1, sizeof(cpPolyShape));-}--static void-cpPolyShapeTransformVerts(cpPolyShape *poly, cpVect p, cpVect rot)-{-	cpVect *src = poly->verts;-	cpVect *dst = poly->tVerts;-	-	for(int i=0; i<poly->numVerts; i++)-		dst[i] = cpvadd(p, cpvrotate(src[i], rot));-}--static void-cpPolyShapeTransformAxes(cpPolyShape *poly, cpVect p, cpVect rot)-{-	cpPolyShapeAxis *src = poly->axes;-	cpPolyShapeAxis *dst = poly->tAxes;-	-	for(int i=0; i<poly->numVerts; i++){-		cpVect n = cpvrotate(src[i].n, rot);-		dst[i].n = n;-		dst[i].d = cpvdot(p, n) + src[i].d;-	}-}--static cpBB-cpPolyShapeCacheData(cpShape *shape, cpVect p, cpVect rot)-{-	cpPolyShape *poly = (cpPolyShape *)shape;-	-	cpFloat l, b, r, t;-	-	cpPolyShapeTransformAxes(poly, p, rot);-	cpPolyShapeTransformVerts(poly, p, rot);-	-	cpVect *verts = poly->tVerts;-	l = r = verts[0].x;-	b = t = verts[0].y;-	-	// TODO do as part of cpPolyShapeTransformVerts?-	for(int i=1; i<poly->numVerts; i++){-		cpVect v = verts[i];-		-		l = cpfmin(l, v.x);-		r = cpfmax(r, v.x);-		-		b = cpfmin(b, v.y);-		t = cpfmax(t, v.y);-	}-	-	return cpBBNew(l, b, r, t);-}--static void-cpPolyShapeDestroy(cpShape *shape)-{-	cpPolyShape *poly = (cpPolyShape *)shape;-	-	cpfree(poly->verts);-	cpfree(poly->tVerts);-	-	cpfree(poly->axes);-	cpfree(poly->tAxes);-}--static cpBool-cpPolyShapePointQuery(cpShape *shape, cpVect p){-	return cpBBcontainsVect(shape->bb, p) && cpPolyShapeContainsVert((cpPolyShape *)shape, p);-}--static void-cpPolyShapeSegmentQuery(cpShape *shape, cpVect a, cpVect b, cpSegmentQueryInfo *info)-{-	cpPolyShape *poly = (cpPolyShape *)shape;-	cpPolyShapeAxis *axes = poly->tAxes;-	cpVect *verts = poly->tVerts;-	int numVerts = poly->numVerts;-	-	for(int i=0; i<numVerts; i++){-		cpVect n = axes[i].n;-		cpFloat an = cpvdot(a, n);-		if(axes[i].d > an) continue;-		-		cpFloat bn = cpvdot(b, n);-		cpFloat t = (axes[i].d - an)/(bn - an);-		if(t < 0.0f || 1.0f < t) continue;-		-		cpVect point = cpvlerp(a, b, t);-		cpFloat dt = -cpvcross(n, point);-		cpFloat dtMin = -cpvcross(n, verts[i]);-		cpFloat dtMax = -cpvcross(n, verts[(i+1)%numVerts]);-		-		if(dtMin <= dt && dt <= dtMax){-			info->shape = shape;-			info->t = t;-			info->n = n;-		}-	}-}--static const cpShapeClass polyClass = {-	CP_POLY_SHAPE,-	cpPolyShapeCacheData,-	cpPolyShapeDestroy,-	cpPolyShapePointQuery,-	cpPolyShapeSegmentQuery,-};--cpBool-cpPolyValidate(const cpVect *verts, const int numVerts)-{-	for(int i=0; i<numVerts; i++){-		cpVect a = verts[i];-		cpVect b = verts[(i+1)%numVerts];-		cpVect c = verts[(i+2)%numVerts];-		-		if(cpvcross(cpvsub(b, a), cpvsub(c, b)) > 0.0f)-			return cpFalse;-	}-	-	return cpTrue;-}--int-cpPolyShapeGetNumVerts(cpShape *shape)-{-	cpAssert(shape->klass == &polyClass, "Shape is not a poly shape.");-	return ((cpPolyShape *)shape)->numVerts;-}--cpVect-cpPolyShapeGetVert(cpShape *shape, int idx)-{-	cpAssert(shape->klass == &polyClass, "Shape is not a poly shape.");-	cpAssert(0 <= idx && idx < cpPolyShapeGetNumVerts(shape), "Index out of range.");-	-	return ((cpPolyShape *)shape)->verts[idx];-}---static void-setUpVerts(cpPolyShape *poly, int numVerts, cpVect *verts, cpVect offset)-{-	poly->numVerts = numVerts;--	poly->verts = (cpVect *)cpcalloc(numVerts, sizeof(cpVect));-	poly->tVerts = (cpVect *)cpcalloc(numVerts, sizeof(cpVect));-	poly->axes = (cpPolyShapeAxis *)cpcalloc(numVerts, sizeof(cpPolyShapeAxis));-	poly->tAxes = (cpPolyShapeAxis *)cpcalloc(numVerts, sizeof(cpPolyShapeAxis));-	-	for(int i=0; i<numVerts; i++){-		cpVect a = cpvadd(offset, verts[i]);-		cpVect b = cpvadd(offset, verts[(i+1)%numVerts]);-		cpVect n = cpvnormalize(cpvperp(cpvsub(b, a)));--		poly->verts[i] = a;-		poly->axes[i].n = n;-		poly->axes[i].d = cpvdot(n, a);-	}-}--cpPolyShape *-cpPolyShapeInit(cpPolyShape *poly, cpBody *body, int numVerts, cpVect *verts, cpVect offset)-{-	// Fail if the user attempts to pass a concave poly, or a bad winding.-	cpAssert(cpPolyValidate(verts, numVerts), "Polygon is concave or has a reversed winding.");-	-	setUpVerts(poly, numVerts, verts, offset);-	cpShapeInit((cpShape *)poly, &polyClass, body);--	return poly;-}--cpShape *-cpPolyShapeNew(cpBody *body, int numVerts, cpVect *verts, cpVect offset)-{-	return (cpShape *)cpPolyShapeInit(cpPolyShapeAlloc(), body, numVerts, verts, offset);-}--cpPolyShape *-cpBoxShapeInit(cpPolyShape *poly, cpBody *body, cpFloat width, cpFloat height)-{-	cpFloat hw = width/2.0f;-	cpFloat hh = height/2.0f;-	-	cpVect verts[] = {-		cpv(-hw,-hh),-		cpv(-hw, hh),-		cpv( hw, hh),-		cpv( hw,-hh),-	};-	-	return cpPolyShapeInit(poly, body, 4, verts, cpvzero);-}--cpShape *-cpBoxShapeNew(cpBody *body, cpFloat width, cpFloat height)-{-	return (cpShape *)cpBoxShapeInit(cpPolyShapeAlloc(), body, width, height);-}--// Unsafe API (chipmunk_unsafe.h)--void-cpPolyShapeSetVerts(cpShape *shape, int numVerts, cpVect *verts, cpVect offset)-{-	cpAssert(shape->klass == &polyClass, "Shape is not a poly shape.");-	cpPolyShapeDestroy(shape);-	setUpVerts((cpPolyShape *)shape, numVerts, verts, offset);-}
− Chipmunk-5.3.4/src/cpShape.c
@@ -1,403 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */- -#include <stdlib.h>-#include <stdio.h>-#include <math.h>--#include "chipmunk_private.h"-#include "chipmunk_unsafe.h"--#define CP_DefineShapeGetter(struct, type, member, name) \-CP_DeclareShapeGetter(struct, type, name){ \-	cpAssert(shape->klass == &struct##Class, "shape is not a "#struct); \-	return ((struct *)shape)->member; \-}-cpHashValue SHAPE_ID_COUNTER = 0;--void-cpResetShapeIdCounter(void)-{-	SHAPE_ID_COUNTER = 0;-}---cpShape*-cpShapeInit(cpShape *shape, const cpShapeClass *klass, cpBody *body)-{-	shape->klass = klass;-	-	shape->hashid = SHAPE_ID_COUNTER;-	SHAPE_ID_COUNTER++;-	-	shape->body = body;-	shape->sensor = 0;-	-	shape->e = 0.0f;-	shape->u = 0.0f;-	shape->surface_v = cpvzero;-	-	shape->collision_type = 0;-	shape->group = CP_NO_GROUP;-	shape->layers = CP_ALL_LAYERS;-	-	shape->data = NULL;-	shape->next = NULL;-	-//	cpShapeCacheBB(shape);-	-	return shape;-}--void-cpShapeDestroy(cpShape *shape)-{-	if(shape->klass->destroy) shape->klass->destroy(shape);-}--void-cpShapeFree(cpShape *shape)-{-	if(shape){-		cpShapeDestroy(shape);-		cpfree(shape);-	}-}--// TODO this function should really take a position and rotation explicitly and be renamed-cpBB-cpShapeCacheBB(cpShape *shape)-{-	cpBody *body = shape->body;-	-	shape->bb = shape->klass->cacheData(shape, body->p, body->rot);-	return shape->bb;-}--cpBool-cpShapePointQuery(cpShape *shape, cpVect p){-	return shape->klass->pointQuery(shape, p);-}--cpBool-cpShapeSegmentQuery(cpShape *shape, cpVect a, cpVect b, cpSegmentQueryInfo *info){-	cpSegmentQueryInfo blank = {NULL, 0.0f, cpvzero};-	(*info) = blank;-	-	shape->klass->segmentQuery(shape, a, b, info);-	return (info->shape != NULL);-}--void-cpSegmentQueryInfoPrint(cpSegmentQueryInfo *info)-{-	printf("Segment Query:\n");-	printf("\tt: %f\n", info->t);-//	printf("\tdist: %f\n", info->dist);-//	printf("\tpoint: %s\n", cpvstr(info->point));-	printf("\tn: %s\n", cpvstr(info->n));-}-----cpCircleShape *-cpCircleShapeAlloc(void)-{-	return (cpCircleShape *)cpcalloc(1, sizeof(cpCircleShape));-}--static inline cpBB-bbFromCircle(const cpVect c, const cpFloat r)-{-	return cpBBNew(c.x-r, c.y-r, c.x+r, c.y+r);-}--static cpBB-cpCircleShapeCacheData(cpShape *shape, cpVect p, cpVect rot)-{-	cpCircleShape *circle = (cpCircleShape *)shape;-	-	circle->tc = cpvadd(p, cpvrotate(circle->c, rot));-	return bbFromCircle(circle->tc, circle->r);-}--static cpBool-cpCircleShapePointQuery(cpShape *shape, cpVect p){-	cpCircleShape *circle = (cpCircleShape *)shape;-	return cpvnear(circle->tc, p, circle->r);-}--static void-circleSegmentQuery(cpShape *shape, cpVect center, cpFloat r, cpVect a, cpVect b, cpSegmentQueryInfo *info)-{-	// offset the line to be relative to the circle-	a = cpvsub(a, center);-	b = cpvsub(b, center);-	-	cpFloat qa = cpvdot(a, a) - 2.0f*cpvdot(a, b) + cpvdot(b, b);-	cpFloat qb = -2.0f*cpvdot(a, a) + 2.0f*cpvdot(a, b);-	cpFloat qc = cpvdot(a, a) - r*r;-	-	cpFloat det = qb*qb - 4.0f*qa*qc;-	-	if(det >= 0.0f){-		cpFloat t = (-qb - cpfsqrt(det))/(2.0f*qa);-		if(0.0f<= t && t <= 1.0f){-			info->shape = shape;-			info->t = t;-			info->n = cpvnormalize(cpvlerp(a, b, t));-		}-	}-}--static void-cpCircleShapeSegmentQuery(cpShape *shape, cpVect a, cpVect b, cpSegmentQueryInfo *info)-{-	cpCircleShape *circle = (cpCircleShape *)shape;-	circleSegmentQuery(shape, circle->tc, circle->r, a, b, info);-}--static const cpShapeClass cpCircleShapeClass = {-	CP_CIRCLE_SHAPE,-	cpCircleShapeCacheData,-	NULL,-	cpCircleShapePointQuery,-	cpCircleShapeSegmentQuery,-};--cpCircleShape *-cpCircleShapeInit(cpCircleShape *circle, cpBody *body, cpFloat radius, cpVect offset)-{-	circle->c = offset;-	circle->r = radius;-	-	cpShapeInit((cpShape *)circle, &cpCircleShapeClass, body);-	-	return circle;-}--cpShape *-cpCircleShapeNew(cpBody *body, cpFloat radius, cpVect offset)-{-	return (cpShape *)cpCircleShapeInit(cpCircleShapeAlloc(), body, radius, offset);-}--CP_DefineShapeGetter(cpCircleShape, cpVect, c, Offset)-CP_DefineShapeGetter(cpCircleShape, cpFloat, r, Radius)--cpSegmentShape *-cpSegmentShapeAlloc(void)-{-	return (cpSegmentShape *)cpcalloc(1, sizeof(cpSegmentShape));-}--static cpBB-cpSegmentShapeCacheData(cpShape *shape, cpVect p, cpVect rot)-{-	cpSegmentShape *seg = (cpSegmentShape *)shape;-	-	seg->ta = cpvadd(p, cpvrotate(seg->a, rot));-	seg->tb = cpvadd(p, cpvrotate(seg->b, rot));-	seg->tn = cpvrotate(seg->n, rot);-	-	cpFloat l,r,s,t;-	-	if(seg->ta.x < seg->tb.x){-		l = seg->ta.x;-		r = seg->tb.x;-	} else {-		l = seg->tb.x;-		r = seg->ta.x;-	}-	-	if(seg->ta.y < seg->tb.y){-		s = seg->ta.y;-		t = seg->tb.y;-	} else {-		s = seg->tb.y;-		t = seg->ta.y;-	}-	-	cpFloat rad = seg->r;-	return cpBBNew(l - rad, s - rad, r + rad, t + rad);-}--static cpBool-cpSegmentShapePointQuery(cpShape *shape, cpVect p){-	if(!cpBBcontainsVect(shape->bb, p)) return cpFalse;-	-	cpSegmentShape *seg = (cpSegmentShape *)shape;-	-	// Calculate normal distance from segment.-	cpFloat dn = cpvdot(seg->tn, p) - cpvdot(seg->ta, seg->tn);-	cpFloat dist = cpfabs(dn) - seg->r;-	if(dist > 0.0f) return cpFalse;-	-	// Calculate tangential distance along segment.-	cpFloat dt = -cpvcross(seg->tn, p);-	cpFloat dtMin = -cpvcross(seg->tn, seg->ta);-	cpFloat dtMax = -cpvcross(seg->tn, seg->tb);-	-	// Decision tree to decide which feature of the segment to collide with.-	if(dt <= dtMin){-		if(dt < (dtMin - seg->r)){-			return cpFalse;-		} else {-			return cpvlengthsq(cpvsub(seg->ta, p)) < (seg->r*seg->r);-		}-	} else {-		if(dt < dtMax){-			return cpTrue;-		} else {-			if(dt < (dtMax + seg->r)) {-				return cpvlengthsq(cpvsub(seg->tb, p)) < (seg->r*seg->r);-			} else {-				return cpFalse;-			}-		}-	}-	-	return cpTrue;	-}--static inline cpBool inUnitRange(cpFloat t){return (0.0f < t && t < 1.0f);}--static void-cpSegmentShapeSegmentQuery(cpShape *shape, cpVect a, cpVect b, cpSegmentQueryInfo *info)-{-	// TODO this function could be optimized better.-	-	cpSegmentShape *seg = (cpSegmentShape *)shape;-	cpVect n = seg->tn;-	// flip n if a is behind the axis-	if(cpvdot(a, n) < cpvdot(seg->ta, n))-		n = cpvneg(n);-	-	cpFloat an = cpvdot(a, n);-	cpFloat bn = cpvdot(b, n);-	-	if(an != bn){-		cpFloat d = cpvdot(seg->ta, n) + seg->r;-		cpFloat t = (d - an)/(bn - an);-		-		if(0.0f < t && t < 1.0f){-			cpVect point = cpvlerp(a, b, t);-			cpFloat dt = -cpvcross(seg->tn, point);-			cpFloat dtMin = -cpvcross(seg->tn, seg->ta);-			cpFloat dtMax = -cpvcross(seg->tn, seg->tb);-			-			if(dtMin < dt && dt < dtMax){-				info->shape = shape;-				info->t = t;-				info->n = n;-				-				return; // don't continue on and check endcaps-			}-		}-	}-	-	if(seg->r) {-		cpSegmentQueryInfo info1 = {NULL, 1.0f, cpvzero};-		cpSegmentQueryInfo info2 = {NULL, 1.0f, cpvzero};-		circleSegmentQuery(shape, seg->ta, seg->r, a, b, &info1);-		circleSegmentQuery(shape, seg->tb, seg->r, a, b, &info2);-		-		if(info1.t < info2.t){-			(*info) = info1;-		} else {-			(*info) = info2;-		}-	}-}--static const cpShapeClass cpSegmentShapeClass = {-	CP_SEGMENT_SHAPE,-	cpSegmentShapeCacheData,-	NULL,-	cpSegmentShapePointQuery,-	cpSegmentShapeSegmentQuery,-};--cpSegmentShape *-cpSegmentShapeInit(cpSegmentShape *seg, cpBody *body, cpVect a, cpVect b, cpFloat r)-{-	seg->a = a;-	seg->b = b;-	seg->n = cpvperp(cpvnormalize(cpvsub(b, a)));-	-	seg->r = r;-	-	cpShapeInit((cpShape *)seg, &cpSegmentShapeClass, body);-	-	return seg;-}--cpShape*-cpSegmentShapeNew(cpBody *body, cpVect a, cpVect b, cpFloat r)-{-	return (cpShape *)cpSegmentShapeInit(cpSegmentShapeAlloc(), body, a, b, r);-}--CP_DefineShapeGetter(cpSegmentShape, cpVect, a, A)-CP_DefineShapeGetter(cpSegmentShape, cpVect, b, B)-CP_DefineShapeGetter(cpSegmentShape, cpVect, n, Normal)-CP_DefineShapeGetter(cpSegmentShape, cpFloat, r, Radius)--// Unsafe API (chipmunk_unsafe.h)--void-cpCircleShapeSetRadius(cpShape *shape, cpFloat radius)-{-	cpAssert(shape->klass == &cpCircleShapeClass, "Shape is not a circle shape.");-	cpCircleShape *circle = (cpCircleShape *)shape;-	-	circle->r = radius;-}--void-cpCircleShapeSetOffset(cpShape *shape, cpVect offset)-{-	cpAssert(shape->klass == &cpCircleShapeClass, "Shape is not a circle shape.");-	cpCircleShape *circle = (cpCircleShape *)shape;-	-	circle->c = offset;-}--void-cpSegmentShapeSetEndpoints(cpShape *shape, cpVect a, cpVect b)-{-	cpAssert(shape->klass == &cpSegmentShapeClass, "Shape is not a segment shape.");-	cpSegmentShape *seg = (cpSegmentShape *)shape;-	-	seg->a = a;-	seg->b = b;-	seg->n = cpvperp(cpvnormalize(cpvsub(b, a)));-}--void-cpSegmentShapeSetRadius(cpShape *shape, cpFloat radius)-{-	cpAssert(shape->klass == &cpSegmentShapeClass, "Shape is not a segment shape.");-	cpSegmentShape *seg = (cpSegmentShape *)shape;-	-	seg->r = radius;-}
− Chipmunk-5.3.4/src/cpSpace.c
@@ -1,499 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */- -#include <stdlib.h>-//#include <stdio.h>-#include <string.h>-#include <math.h>--#include "chipmunk_private.h"--cpTimestamp cp_contact_persistence = 3;--#pragma mark Contact Set Helpers--// Equal function for contactSet.-static cpBool-contactSetEql(cpShape **shapes, cpArbiter *arb)-{-	cpShape *a = shapes[0];-	cpShape *b = shapes[1];-	-	return ((a == arb->a && b == arb->b) || (b == arb->a && a == arb->b));-}--// Transformation function for contactSet.-static void *-contactSetTrans(cpShape **shapes, cpSpace *space)-{-	if(space->pooledArbiters->num == 0){-		// arbiter pool is exhausted, make more-		int count = CP_BUFFER_BYTES/sizeof(cpArbiter);-		cpAssert(count, "Buffer size too small.");-		-		cpArbiter *buffer = (cpArbiter *)cpmalloc(CP_BUFFER_BYTES);-		cpArrayPush(space->allocatedBuffers, buffer);-		-		for(int i=0; i<count; i++) cpArrayPush(space->pooledArbiters, buffer + i);-	}-	-	return cpArbiterInit((cpArbiter *) cpArrayPop(space->pooledArbiters), shapes[0], shapes[1]);-}--#pragma mark Collision Pair Function Helpers--// Equals function for collFuncSet.-static cpBool-collFuncSetEql(cpCollisionHandler *check, cpCollisionHandler *pair)-{-	return ((check->a == pair->a && check->b == pair->b) || (check->b == pair->a && check->a == pair->b));-}--// Transformation function for collFuncSet.-static void *-collFuncSetTrans(cpCollisionHandler *handler, void *unused)-{-	cpCollisionHandler *copy = (cpCollisionHandler *)cpmalloc(sizeof(cpCollisionHandler));-	(*copy) = (*handler);-	-	return copy;-}--#pragma mark Misc Helper Funcs--// Default collision functions.-static cpBool alwaysCollide(cpArbiter *arb, cpSpace *space, void *data){return 1;}-static void nothing(cpArbiter *arb, cpSpace *space, void *data){}--// BBfunc callback for the spatial hash.-static cpBB shapeBBFunc(cpShape *shape){return shape->bb;}--// Iterator functions for destructors.-static void             freeWrap(void         *ptr, void *unused){            cpfree(ptr);}-static void        shapeFreeWrap(cpShape      *ptr, void *unused){     cpShapeFree(ptr);}-static void         bodyFreeWrap(cpBody       *ptr, void *unused){      cpBodyFree(ptr);}-static void   constraintFreeWrap(cpConstraint *ptr, void *unused){cpConstraintFree(ptr);}--#pragma mark Memory Management Functions--cpSpace *-cpSpaceAlloc(void)-{-	return (cpSpace *)cpcalloc(1, sizeof(cpSpace));-}--#define DEFAULT_DIM_SIZE 100.0f-#define DEFAULT_COUNT 1000-#define DEFAULT_ITERATIONS 10-#define DEFAULT_ELASTIC_ITERATIONS 0--cpCollisionHandler defaultHandler = {0, 0, alwaysCollide, alwaysCollide, nothing, nothing, NULL};--cpSpace*-cpSpaceInit(cpSpace *space)-{-	space->iterations = DEFAULT_ITERATIONS;-	space->elasticIterations = DEFAULT_ELASTIC_ITERATIONS;-//	space->sleepTicks = 300;-	-	space->gravity = cpvzero;-	space->damping = 1.0f;-	-	space->locked = 0;-	space->stamp = 0;--	space->staticShapes = cpSpaceHashNew(DEFAULT_DIM_SIZE, DEFAULT_COUNT, (cpSpaceHashBBFunc)shapeBBFunc);-	space->activeShapes = cpSpaceHashNew(DEFAULT_DIM_SIZE, DEFAULT_COUNT, (cpSpaceHashBBFunc)shapeBBFunc);-	-	space->allocatedBuffers = cpArrayNew(0);-	-	space->bodies = cpArrayNew(0);-	space->sleepingComponents = cpArrayNew(0);-	space->rousedBodies = cpArrayNew(0);-	-	space->sleepTimeThreshold = INFINITY;-	space->idleSpeedThreshold = 0.0f;-	-	space->arbiters = cpArrayNew(0);-	space->pooledArbiters = cpArrayNew(0);-	-	space->contactBuffersHead = NULL;-	space->contactSet = cpHashSetNew(0, (cpHashSetEqlFunc)contactSetEql, (cpHashSetTransFunc)contactSetTrans);-	-	space->constraints = cpArrayNew(0);-	-	space->defaultHandler = defaultHandler;-	space->collFuncSet = cpHashSetNew(0, (cpHashSetEqlFunc)collFuncSetEql, (cpHashSetTransFunc)collFuncSetTrans);-	space->collFuncSet->default_value = &space->defaultHandler;-	-	space->postStepCallbacks = NULL;-	-	cpBodyInitStatic(&space->staticBody);-	-	return space;-}--cpSpace*-cpSpaceNew(void)-{-	return cpSpaceInit(cpSpaceAlloc());-}--void-cpSpaceDestroy(cpSpace *space)-{-	cpSpaceHashFree(space->staticShapes);-	cpSpaceHashFree(space->activeShapes);-	-	cpArrayFree(space->bodies);-	cpArrayFree(space->sleepingComponents);-	cpArrayFree(space->rousedBodies);-	-	cpArrayFree(space->constraints);-	-	cpHashSetFree(space->contactSet);-	-	cpArrayFree(space->arbiters);-	cpArrayFree(space->pooledArbiters);-	-	if(space->allocatedBuffers){-		cpArrayEach(space->allocatedBuffers, freeWrap, NULL);-		cpArrayFree(space->allocatedBuffers);-	}-	-	if(space->postStepCallbacks){-		cpHashSetEach(space->postStepCallbacks, freeWrap, NULL);-		cpHashSetFree(space->postStepCallbacks);-	}-	-	if(space->collFuncSet){-		cpHashSetEach(space->collFuncSet, freeWrap, NULL);-		cpHashSetFree(space->collFuncSet);-	}-}--void-cpSpaceFree(cpSpace *space)-{-	if(space){-		cpSpaceDestroy(space);-		cpfree(space);-	}-}--void-cpSpaceFreeChildren(cpSpace *space)-{-	cpArray *components = space->sleepingComponents;-	while(components->num) cpBodyActivate((cpBody *)components->arr[0]);-	-	cpSpaceHashEach(space->staticShapes, (cpSpaceHashIterator)&shapeFreeWrap, NULL);-	cpSpaceHashEach(space->activeShapes, (cpSpaceHashIterator)&shapeFreeWrap, NULL);-	cpArrayEach(space->bodies,           (cpArrayIter)&bodyFreeWrap,          NULL);-	cpArrayEach(space->constraints,      (cpArrayIter)&constraintFreeWrap,    NULL);-}--#pragma mark Collision Handler Function Management--void-cpSpaceAddCollisionHandler(-	cpSpace *space,-	cpCollisionType a, cpCollisionType b,-	cpCollisionBeginFunc begin,-	cpCollisionPreSolveFunc preSolve,-	cpCollisionPostSolveFunc postSolve,-	cpCollisionSeparateFunc separate,-	void *data-){-	// Remove any old function so the new one will get added.-	cpSpaceRemoveCollisionHandler(space, a, b);-	-	cpCollisionHandler handler = {-		a, b,-		begin ? begin : alwaysCollide,-		preSolve ? preSolve : alwaysCollide,-		postSolve ? postSolve : nothing,-		separate ? separate : nothing,-		data-	};-	-	cpHashSetInsert(space->collFuncSet, CP_HASH_PAIR(a, b), &handler, NULL);-}--void-cpSpaceRemoveCollisionHandler(cpSpace *space, cpCollisionType a, cpCollisionType b)-{-	struct{cpCollisionType a, b;} ids = {a, b};-	cpCollisionHandler *old_handler = (cpCollisionHandler *) cpHashSetRemove(space->collFuncSet, CP_HASH_PAIR(a, b), &ids);-	cpfree(old_handler);-}--void-cpSpaceSetDefaultCollisionHandler(-	cpSpace *space,-	cpCollisionBeginFunc begin,-	cpCollisionPreSolveFunc preSolve,-	cpCollisionPostSolveFunc postSolve,-	cpCollisionSeparateFunc separate,-	void *data-){-	cpCollisionHandler handler = {-		0, 0,-		begin ? begin : alwaysCollide,-		preSolve ? preSolve : alwaysCollide,-		postSolve ? postSolve : nothing,-		separate ? separate : nothing,-		data-	};-	-	space->defaultHandler = handler;-}--#pragma mark Body, Shape, and Joint Management--#define cpAssertSpaceUnlocked(space) \-	cpAssert(!space->locked, \-		"This addition/removal cannot be done safely during a call to cpSpaceStep() or during a query. " \-		"Put these calls into a post-step callback." \-	);--static void-cpBodyAddShape(cpBody *body, cpShape *shape)-{-	shape->next = shape->body->shapesList;-	shape->body->shapesList = shape;-}--static void-cpBodyRemoveShape(cpBody *body, cpShape *shape)-{-	cpShape **prev_ptr = &body->shapesList;-	cpShape *node = body->shapesList;-	-	while(node && node != shape){-		prev_ptr = &node->next;-		node = node->next;-	}-	-	cpAssert(node, "Attempted to remove a shape from a body it was never attached to.");-	(*prev_ptr) = node->next;-}--cpShape *-cpSpaceAddShape(cpSpace *space, cpShape *shape)-{-	cpBody *body = shape->body;-	if(!body || cpBodyIsStatic(body)) return cpSpaceAddStaticShape(space, shape);-	-	cpAssert(!cpHashSetFind(space->activeShapes->handleSet, shape->hashid, shape),-		"Cannot add the same shape more than once.");-	cpAssertSpaceUnlocked(space);-	-	cpBodyActivate(body);-	cpBodyAddShape(body, shape);-	-	cpShapeCacheBB(shape);-	cpSpaceHashInsert(space->activeShapes, shape, shape->hashid, shape->bb);-		-	return shape;-}--cpShape *-cpSpaceAddStaticShape(cpSpace *space, cpShape *shape)-{-	cpAssert(!cpHashSetFind(space->staticShapes->handleSet, shape->hashid, shape),-		"Cannot add the same static shape more than once.");-	cpAssertSpaceUnlocked(space);-	-	if(!shape->body) shape->body = &space->staticBody;-	-	cpShapeCacheBB(shape);-	cpSpaceActivateShapesTouchingShape(space, shape);-	cpSpaceHashInsert(space->staticShapes, shape, shape->hashid, shape->bb);-	-	return shape;-}--cpBody *-cpSpaceAddBody(cpSpace *space, cpBody *body)-{-	cpAssertWarn(!cpBodyIsStatic(body), "Static bodies cannot be added to a space as they are not meant to be simulated.");-	cpAssert(!body->space, "Cannot add a body to a more than one space or to the same space twice.");-//	cpAssertSpaceUnlocked(space); This should be safe as long as it's not from an integration callback-	-	cpArrayPush(space->bodies, body);-	body->space = space;-	-	return body;-}--cpConstraint *-cpSpaceAddConstraint(cpSpace *space, cpConstraint *constraint)-{-	cpAssert(!cpArrayContains(space->constraints, constraint), "Cannot add the same constraint more than once.");-//	cpAssertSpaceUnlocked(space); This should be safe as long as its not from a constraint callback.-	-	if(!constraint->a) constraint->a = &space->staticBody;-	if(!constraint->b) constraint->b = &space->staticBody;-	-	cpBodyActivate(constraint->a);-	cpBodyActivate(constraint->b);-	cpArrayPush(space->constraints, constraint);-	-	return constraint;-}--typedef struct removalContext {-	cpSpace *space;-	cpShape *shape;-} removalContext;--// Hashset filter func to throw away old arbiters.-static cpBool-contactSetFilterRemovedShape(cpArbiter *arb, removalContext *context)-{-	if(context->shape == arb->a || context->shape == arb->b){-		if(arb->state != cpArbiterStateCached){-			arb->handler->separate(arb, context->space, arb->handler->data);-		}-		-		cpArrayPush(context->space->pooledArbiters, arb);-		return cpFalse;-	}-	-	return cpTrue;-}--void-cpSpaceRemoveShape(cpSpace *space, cpShape *shape)-{-	cpBody *body = shape->body;-	if(cpBodyIsStatic(body)){-		cpSpaceRemoveStaticShape(space, shape);-		return;-	}--	cpBodyActivate(body);-	-	cpAssertSpaceUnlocked(space);-	cpAssertWarn(cpHashSetFind(space->activeShapes->handleSet, shape->hashid, shape),-		"Cannot remove a shape that was not added to the space. (Removed twice maybe?)");-	-	cpBodyRemoveShape(body, shape);-	-	removalContext context = {space, shape};-	cpHashSetFilter(space->contactSet, (cpHashSetFilterFunc)contactSetFilterRemovedShape, &context);-	cpSpaceHashRemove(space->activeShapes, shape, shape->hashid);-}--void-cpSpaceRemoveStaticShape(cpSpace *space, cpShape *shape)-{-	cpAssertWarn(cpHashSetFind(space->staticShapes->handleSet, shape->hashid, shape),-		"Cannot remove a static or sleeping shape that was not added to the space. (Removed twice maybe?)");-	cpAssertSpaceUnlocked(space);-	-	removalContext context = {space, shape};-	cpHashSetFilter(space->contactSet, (cpHashSetFilterFunc)contactSetFilterRemovedShape, &context);-	cpSpaceHashRemove(space->staticShapes, shape, shape->hashid);-	-	cpSpaceActivateShapesTouchingShape(space, shape);-}--void-cpSpaceRemoveBody(cpSpace *space, cpBody *body)-{-	cpAssertWarn(body->space == space,-		"Cannot remove a body that was not added to the space. (Removed twice maybe?)");-	cpAssertSpaceUnlocked(space);-	-	cpBodyActivate(body);-	cpArrayDeleteObj(space->bodies, body);-	body->space = NULL;-}--void-cpSpaceRemoveConstraint(cpSpace *space, cpConstraint *constraint)-{-	cpAssertWarn(cpArrayContains(space->constraints, constraint),-		"Cannot remove a constraint that was not added to the space. (Removed twice maybe?)");-//	cpAssertSpaceUnlocked(space); Should be safe as long as its not from a constraint callback.-	-	cpBodyActivate(constraint->a);-	cpBodyActivate(constraint->b);-	cpArrayDeleteObj(space->constraints, constraint);-}--#pragma mark Spatial Hash Management--static void updateBBCache(cpShape *shape, void *unused){cpShapeCacheBB(shape);}--void-cpSpaceResizeStaticHash(cpSpace *space, cpFloat dim, int count)-{-	cpSpaceHashResize(space->staticShapes, dim, count);-	cpSpaceHashRehash(space->staticShapes);-}--void-cpSpaceResizeActiveHash(cpSpace *space, cpFloat dim, int count)-{-	cpSpaceHashResize(space->activeShapes, dim, count);-}--void -cpSpaceRehashStatic(cpSpace *space)-{-	cpSpaceHashEach(space->staticShapes, (cpSpaceHashIterator)&updateBBCache, NULL);-	cpSpaceHashRehash(space->staticShapes);-}--void-cpSpaceRehashShape(cpSpace *space, cpShape *shape)-{-	cpShapeCacheBB(shape);-	-	// attempt to rehash the shape in both hashes-	cpSpaceHashRehashObject(space->activeShapes, shape, shape->hashid);-	cpSpaceHashRehashObject(space->staticShapes, shape, shape->hashid);-}--void-cpSpaceEachBody(cpSpace *space, cpSpaceBodyIterator func, void *data)-{-	cpArray *bodies = space->bodies;-	-	for(int i=0; i<bodies->num; i++){-		func((cpBody *)bodies->arr[i], data);-	}-	-	cpArray *components = space->sleepingComponents;-	for(int i=0; i<components->num; i++){-		cpBody *root = (cpBody *)components->arr[i];-		cpBody *body = root, *next;-		do {-			next = body->node.next;-			func(body, data);-		} while((body = next) != root);-	}-}--
− Chipmunk-5.3.4/src/cpSpaceComponent.c
@@ -1,279 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */- -#include <stdlib.h>--#include "chipmunk_private.h"--#pragma mark Sleeping Functions--// Chipmunk uses a data structure called a disjoint set forest.-// My attempts to find a way to splice circularly linked lists in-// constant time failed, and so I found this neat data structure instead.--static inline cpBody *-componentNodeRoot(cpBody *body)-{-	cpBody *parent = body->node.parent;-	-	if(parent){-		// path compression, attaches this node directly to the root-		return (body->node.parent = componentNodeRoot(parent));-	} else {-		return body;-	}-}--static inline void-componentNodeMerge(cpBody *a_root, cpBody *b_root)-{-	if(a_root->node.rank < b_root->node.rank){-		a_root->node.parent = b_root;-	} else if(a_root->node.rank > b_root->node.rank){-		b_root->node.parent = a_root;-	} else if(a_root != b_root){-		b_root->node.parent = a_root;-		a_root->node.rank++;-	}-}--void-cpSpaceActivateBody(cpSpace *space, cpBody *body)-{-	if(space->locked){-		// cpSpaceActivateBody() is called again once the space is unlocked-		cpArrayPush(space->rousedBodies, body);-	} else {-		cpArrayPush(space->bodies, body);-		for(cpShape *shape=body->shapesList; shape; shape=shape->next){-			cpSpaceHashRemove(space->staticShapes, shape, shape->hashid);-			cpSpaceHashInsert(space->activeShapes, shape, shape->hashid, shape->bb);-		}-	}-}--static inline void-componentActivate(cpBody *root)-{-	if(!cpBodyIsSleeping(root)) return;-	-	cpSpace *space = root->space;-	cpAssert(space, "Trying to activate a body that was never added to a space.");-	-	cpBody *body = root, *next;-	do {-		next = body->node.next;-		-		cpComponentNode node = {NULL, NULL, 0, 0.0f};-		body->node = node;-		-		cpSpaceActivateBody(space, body);-	} while((body = next) != root);-	-	cpArrayDeleteObj(space->sleepingComponents, root);-}--void-cpBodyActivate(cpBody *body)-{-	componentActivate(componentNodeRoot(body));-}--static inline void-mergeBodies(cpSpace *space, cpArray *components, cpArray *rogueBodies, cpBody *a, cpBody *b)-{-	// Ignore connections to static bodies-	if(cpBodyIsStatic(a) || cpBodyIsStatic(b)) return;-	-	cpBody *a_root = componentNodeRoot(a);-	cpBody *b_root = componentNodeRoot(b);-	-	cpBool a_sleep = cpBodyIsSleeping(a_root);-	cpBool b_sleep = cpBodyIsSleeping(b_root);-	-	if(a_sleep && b_sleep){-		return;-	} else if(a_sleep || b_sleep){-		componentActivate(a_root);-		componentActivate(b_root);-	} -	-	// Add any rogue bodies found to the list and reset the idle time of anything they touch.-	if(cpBodyIsRogue(a)){ cpArrayPush(rogueBodies, a); b->node.idleTime = 0.0f; }-	if(cpBodyIsRogue(b)){ cpArrayPush(rogueBodies, b); a->node.idleTime = 0.0f; }-	-	componentNodeMerge(a_root, b_root);-}--static inline cpBool-componentActive(cpBody *root, cpFloat threshold)-{-	cpBody *body = root, *next;-	do {-		next = body->node.next;-		if(body->node.idleTime < threshold) return cpTrue;-	} while((body = next) != root);-	-	return cpFalse;-}--static inline void-addToComponent(cpBody *body, cpArray *components)-{-	// Check that the body is not already added to the component list-	if(body->node.next) return;-	cpBody *root = componentNodeRoot(body);-	-	cpBody *next = root->node.next;-	if(!next){-		// If the root isn't part of a list yet, then it hasn't been-		// added to the components list. Do that now.-		cpArrayPush(components, root);-		// Start the list-		body->node.next = root;-		root->node.next = body;-	} else if(root != body) {-		// Splice in body after the root.-		body->node.next = next;-		root->node.next = body;-	}-}--// TODO this function needs more commenting.-void-cpSpaceProcessComponents(cpSpace *space, cpFloat dt)-{-	cpArray *bodies = space->bodies;-	cpArray *newBodies = cpArrayNew(bodies->num);-	cpArray *rogueBodies = cpArrayNew(16);-	cpArray *arbiters = space->arbiters;-	cpArray *constraints = space->constraints;-	cpArray *components = cpArrayNew(space->sleepingComponents->num);-	-	cpFloat dv = space->idleSpeedThreshold;-	cpFloat dvsq = (dv ? dv*dv : cpvdot(space->gravity, space->gravity)*dt*dt);-	-	// update idling-	for(int i=0; i<bodies->num; i++){-		cpBody *body = (cpBody*)bodies->arr[i];-		-		cpFloat thresh = (dvsq ? body->m*dvsq : 0.0f);-		body->node.idleTime = (cpBodyKineticEnergy(body) > thresh ? 0.0f : body->node.idleTime + dt);-	}-	-	// iterate graph edges and build forests-	for(int i=0; i<arbiters->num; i++){-		cpArbiter *arb = (cpArbiter*)arbiters->arr[i];-		mergeBodies(space, components, rogueBodies, arb->a->body, arb->b->body);-	}-	for(int j=0; j<constraints->num; j++){-		cpConstraint *constraint = (cpConstraint *)constraints->arr[j];-		mergeBodies(space, components, rogueBodies, constraint->a, constraint->b);-	}-	-	// iterate bodies and add them to their components-	for(int i=0; i<bodies->num; i++) addToComponent((cpBody*)bodies->arr[i], components);-	for(int i=0; i<rogueBodies->num; i++) addToComponent((cpBody*)rogueBodies->arr[i], components);-	-	// iterate components, copy or deactivate-	for(int i=0; i<components->num; i++){-		cpBody *root = (cpBody*)components->arr[i];-		if(componentActive(root, space->sleepTimeThreshold)){-			cpBody *body = root, *next;-			do {-				next = body->node.next;-				-				if(!cpBodyIsRogue(body)) cpArrayPush(newBodies, body);-				cpComponentNode node = {NULL, NULL, 0, body->node.idleTime};-				body->node = node;-			} while((body = next) != root);-		} else {-			cpBody *body = root, *next;-			do {-				next = body->node.next;-				-				for(cpShape *shape = body->shapesList; shape; shape = shape->next){-					cpSpaceHashRemove(space->activeShapes, shape, shape->hashid);-					cpSpaceHashInsert(space->staticShapes, shape, shape->hashid, shape->bb);-				}-			} while((body = next) != root);-			-			cpArrayPush(space->sleepingComponents, root);-		}-	}-	-	space->bodies = newBodies;-	cpArrayFree(bodies);-	cpArrayFree(rogueBodies);-	cpArrayFree(components);-}--void-cpBodySleep(cpBody *body)-{-	cpBodySleepWithGroup(body, NULL);-}--void-cpBodySleepWithGroup(cpBody *body, cpBody *group){-	cpAssert(!cpBodyIsStatic(body) && !cpBodyIsRogue(body), "Rogue and static bodies cannot be put to sleep.");-	-	cpSpace *space = body->space;-	cpAssert(space, "Cannot put a body to sleep that has not been added to a space.");-	cpAssert(!space->locked, "Bodies can not be put to sleep during a query or a call to cpSpaceSte(). Put these calls into a post-step callback.");-	cpAssert(!group || cpBodyIsSleeping(group), "Cannot use a non-sleeping body as a group identifier.");-	-	if(cpBodyIsSleeping(body)) return;-	-	for(cpShape *shape = body->shapesList; shape; shape = shape->next){-		cpShapeCacheBB(shape);-		cpSpaceHashRemove(space->activeShapes, shape, shape->hashid);-		cpSpaceHashInsert(space->staticShapes, shape, shape->hashid, shape->bb);-	}-	-	if(group){-		cpBody *root = componentNodeRoot(group);-		-		cpComponentNode node = {root, root->node.next, 0, 0.0f};-		body->node = node;-		root->node.next = body;-	} else {-		cpComponentNode node = {NULL, body, 0, 0.0f};-		body->node = node;-		-		cpArrayPush(space->sleepingComponents, body);-	}-	-	cpArrayDeleteObj(space->bodies, body);-}--static void-activateTouchingHelper(cpShape *shape, cpContactPointSet *points, cpArray **bodies){-	cpBodyActivate(shape->body);-}--void-cpSpaceActivateShapesTouchingShape(cpSpace *space, cpShape *shape){-	cpArray *bodies = NULL;-	cpSpaceShapeQuery(space, shape, (cpSpaceShapeQueryFunc)activateTouchingHelper, &bodies);-}--
− Chipmunk-5.3.4/src/cpSpaceHash.c
@@ -1,534 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */--#include <math.h>-#include <stdlib.h>--#include "chipmunk_private.h"-#include "prime.h"--static cpHandle*-cpHandleInit(cpHandle *hand, void *obj)-{-	hand->obj = obj;-	hand->retain = 0;-	hand->stamp = 0;-	-	return hand;-}--static inline void cpHandleRetain(cpHandle *hand){hand->retain++;}--static inline void-cpHandleRelease(cpHandle *hand, cpArray *pooledHandles)-{-	hand->retain--;-	if(hand->retain == 0) cpArrayPush(pooledHandles, hand);-}--cpSpaceHash*-cpSpaceHashAlloc(void)-{-	return (cpSpaceHash *)cpcalloc(1, sizeof(cpSpaceHash));-}--// Frees the old table, and allocate a new one.-static void-cpSpaceHashAllocTable(cpSpaceHash *hash, int numcells)-{-	cpfree(hash->table);-	-	hash->numcells = numcells;-	hash->table = (cpSpaceHashBin **)cpcalloc(numcells, sizeof(cpSpaceHashBin *));-}--// Equality function for the handleset.-static int handleSetEql(void *obj, cpHandle *hand){return (obj == hand->obj);}--// Transformation function for the handleset.-static void *-handleSetTrans(void *obj, cpSpaceHash *hash)-{-	if(hash->pooledHandles->num == 0){-		// handle pool is exhausted, make more-		int count = CP_BUFFER_BYTES/sizeof(cpHandle);-		cpAssert(count, "Buffer size is too small.");-		-		cpHandle *buffer = (cpHandle *)cpmalloc(CP_BUFFER_BYTES);-		cpArrayPush(hash->allocatedBuffers, buffer);-		-		for(int i=0; i<count; i++) cpArrayPush(hash->pooledHandles, buffer + i);-	}-	-	cpHandle *hand = cpHandleInit((cpHandle *) cpArrayPop(hash->pooledHandles), obj);-	cpHandleRetain(hand);-	-	return hand;-}--cpSpaceHash*-cpSpaceHashInit(cpSpaceHash *hash, cpFloat celldim, int numcells, cpSpaceHashBBFunc bbfunc)-{-	cpSpaceHashAllocTable(hash, next_prime(numcells));-	hash->celldim = celldim;-	hash->bbfunc = bbfunc;-	-	hash->handleSet = cpHashSetNew(0, (cpHashSetEqlFunc)handleSetEql, (cpHashSetTransFunc)handleSetTrans);-	hash->pooledHandles = cpArrayNew(0);-	-	hash->pooledBins = NULL;-	hash->allocatedBuffers = cpArrayNew(0);-	-	hash->stamp = 1;-	-	return hash;-}--cpSpaceHash*-cpSpaceHashNew(cpFloat celldim, int cells, cpSpaceHashBBFunc bbfunc)-{-	return cpSpaceHashInit(cpSpaceHashAlloc(), celldim, cells, bbfunc);-}--static inline void-recycleBin(cpSpaceHash *hash, cpSpaceHashBin *bin)-{-	bin->next = hash->pooledBins;-	hash->pooledBins = bin;-}--static inline void-clearHashCell(cpSpaceHash *hash, int idx)-{-	cpSpaceHashBin *bin = hash->table[idx];-	while(bin){-		cpSpaceHashBin *next = bin->next;-		-		cpHandleRelease(bin->handle, hash->pooledHandles);-		recycleBin(hash, bin);-		-		bin = next;-	}-	-	hash->table[idx] = NULL;-}--// Clear all cells in the hashtable.-static void-clearHash(cpSpaceHash *hash)-{-	for(int i=0; i<hash->numcells; i++)-		clearHashCell(hash, i);-}--static void freeWrap(void *ptr, void *unused){cpfree(ptr);}--void-cpSpaceHashDestroy(cpSpaceHash *hash)-{-	clearHash(hash);-	-	cpHashSetFree(hash->handleSet);-	-	cpArrayEach(hash->allocatedBuffers, freeWrap, NULL);-	cpArrayFree(hash->allocatedBuffers);-	cpArrayFree(hash->pooledHandles);-	-	cpfree(hash->table);-}--void-cpSpaceHashFree(cpSpaceHash *hash)-{-	if(hash){-		cpSpaceHashDestroy(hash);-		cpfree(hash);-	}-}--void-cpSpaceHashResize(cpSpaceHash *hash, cpFloat celldim, int numcells)-{-	// Clear the hash to release the old handle locks.-	clearHash(hash);-	-	hash->celldim = celldim;-	cpSpaceHashAllocTable(hash, next_prime(numcells));-}--// Return true if the chain contains the handle.-static inline cpBool-containsHandle(cpSpaceHashBin *bin, cpHandle *hand)-{-	while(bin){-		if(bin->handle == hand) return cpTrue;-		bin = bin->next;-	}-	-	return cpFalse;-}--// Get a recycled or new bin.-static inline cpSpaceHashBin *-getEmptyBin(cpSpaceHash *hash)-{-	cpSpaceHashBin *bin = hash->pooledBins;-	-	if(bin){-		hash->pooledBins = bin->next;-		return bin;-	} else {-		// Pool is exhausted, make more-		int count = CP_BUFFER_BYTES/sizeof(cpSpaceHashBin);-		cpAssert(count, "Buffer size is too small.");-		-		cpSpaceHashBin *buffer = (cpSpaceHashBin *)cpmalloc(CP_BUFFER_BYTES);-		cpArrayPush(hash->allocatedBuffers, buffer);-		-		// push all but the first one, return the first instead-		for(int i=1; i<count; i++) recycleBin(hash, buffer + i);-		return buffer;-	}-}--// The hash function itself.-static inline cpHashValue-hash_func(cpHashValue x, cpHashValue y, cpHashValue n)-{-	return (x*1640531513ul ^ y*2654435789ul) % n;-}--// Much faster than (int)floor(f)-// Profiling showed floor() to be a sizable performance hog-static inline int-floor_int(cpFloat f)-{-	int i = (int)f;-	return (f < 0.0f && f != i ? i - 1 : i);-}--static inline void-hashHandle(cpSpaceHash *hash, cpHandle *hand, cpBB bb)-{-	// Find the dimensions in cell coordinates.-	cpFloat dim = hash->celldim;-	int l = floor_int(bb.l/dim); // Fix by ShiftZ-	int r = floor_int(bb.r/dim);-	int b = floor_int(bb.b/dim);-	int t = floor_int(bb.t/dim);-	-	int n = hash->numcells;-	for(int i=l; i<=r; i++){-		for(int j=b; j<=t; j++){-			int idx = hash_func(i,j,n);-			cpSpaceHashBin *bin = hash->table[idx];-			-			// Don't add an object twice to the same cell.-			if(containsHandle(bin, hand)) continue;--			cpHandleRetain(hand);-			// Insert a new bin for the handle in this cell.-			cpSpaceHashBin *newBin = getEmptyBin(hash);-			newBin->handle = hand;-			newBin->next = bin;-			hash->table[idx] = newBin;-		}-	}-}--void-cpSpaceHashInsert(cpSpaceHash *hash, void *obj, cpHashValue hashid, cpBB _deprecated_unused)-{-	cpHandle *hand = (cpHandle *)cpHashSetInsert(hash->handleSet, hashid, obj, hash);-	hashHandle(hash, hand, hash->bbfunc(obj));-}--void-cpSpaceHashRehashObject(cpSpaceHash *hash, void *obj, cpHashValue hashid)-{-	cpHandle *hand = (cpHandle *)cpHashSetRemove(hash->handleSet, hashid, obj);-	-	if(hand){-		hand->obj = NULL;-		cpHandleRelease(hand, hash->pooledHandles);-		-		cpSpaceHashInsert(hash, obj, hashid, cpBBNew(0.0f, 0.0f, 0.0f, 0.0f));-	}-}--static void handleRehashHelper(cpHandle *hand, cpSpaceHash *hash){hashHandle(hash, hand, hash->bbfunc(hand->obj));}--void-cpSpaceHashRehash(cpSpaceHash *hash)-{-	clearHash(hash);-	cpHashSetEach(hash->handleSet, (cpHashSetIterFunc)handleRehashHelper, hash);-}--void-cpSpaceHashRemove(cpSpaceHash *hash, void *obj, cpHashValue hashid)-{-	cpHandle *hand = (cpHandle *)cpHashSetRemove(hash->handleSet, hashid, obj);-	-	if(hand){-		hand->obj = NULL;-		cpHandleRelease(hand, hash->pooledHandles);-	}-}--typedef struct eachPair {-	cpSpaceHashIterator func;-	void *data;-} eachPair;--static void eachHelper(cpHandle *hand, eachPair *pair){pair->func(hand->obj, pair->data);}--// Iterate over the objects in the spatial hash.-void-cpSpaceHashEach(cpSpaceHash *hash, cpSpaceHashIterator func, void *data)-{-	eachPair pair = {func, data};-	cpHashSetEach(hash->handleSet, (cpHashSetIterFunc)eachHelper, &pair);-}--static inline void-removeOrphanedHandles(cpSpaceHash *hash, cpSpaceHashBin **bin_ptr)-{-	cpSpaceHashBin *bin = *bin_ptr;-	while(bin){-		cpHandle *hand = bin->handle;-		cpSpaceHashBin *next = bin->next;-		-		if(!hand->obj){-			// orphaned handle, unlink and recycle the bin-			(*bin_ptr) = bin->next;-			recycleBin(hash, bin);-			-			cpHandleRelease(hand, hash->pooledHandles);-		} else {-			bin_ptr = &bin->next;-		}-		-		bin = next;-	}-}--// Calls the callback function for the objects in a given chain.-static inline void-query(cpSpaceHash *hash, cpSpaceHashBin **bin_ptr, void *obj, cpSpaceHashQueryFunc func, void *data)-{-	restart:-	for(cpSpaceHashBin *bin = *bin_ptr; bin; bin = bin->next){-		cpHandle *hand = bin->handle;-		void *other = hand->obj;-		-		if(hand->stamp == hash->stamp || obj == other){-			continue;-		} else if(other){-			func(obj, other, data);-			hand->stamp = hash->stamp;-		} else {-			// The object for this handle has been removed-			// cleanup this cell and restart the query-			removeOrphanedHandles(hash, bin_ptr);-			goto restart; // GCC not smart enough/able to tail call an inlined function.-		}-	}-}--void-cpSpaceHashPointQuery(cpSpaceHash *hash, cpVect point, cpSpaceHashQueryFunc func, void *data)-{-	cpFloat dim = hash->celldim;-	int idx = hash_func(floor_int(point.x/dim), floor_int(point.y/dim), hash->numcells);  // Fix by ShiftZ-	-	query(hash, &hash->table[idx], &point, func, data);-	hash->stamp++;-}--void-cpSpaceHashQuery(cpSpaceHash *hash, void *obj, cpBB bb, cpSpaceHashQueryFunc func, void *data)-{-	// Get the dimensions in cell coordinates.-	cpFloat dim = hash->celldim;-	int l = floor_int(bb.l/dim);  // Fix by ShiftZ-	int r = floor_int(bb.r/dim);-	int b = floor_int(bb.b/dim);-	int t = floor_int(bb.t/dim);-	-	int n = hash->numcells;-	cpSpaceHashBin **table = hash->table;-	-	// Iterate over the cells and query them.-	for(int i=l; i<=r; i++){-		for(int j=b; j<=t; j++){-			query(hash, &table[hash_func(i,j,n)], obj, func, data);-		}-	}-	-	hash->stamp++;-}--// Similar to struct eachPair above.-typedef struct queryRehashPair {-	cpSpaceHash *hash;-	cpSpaceHashQueryFunc func;-	void *data;-} queryRehashPair;--// Hashset iterator func used with cpSpaceHashQueryRehash().-static void-handleQueryRehashHelper(void *elt, void *data)-{-	cpHandle *hand = (cpHandle *)elt;-	-	// Unpack the user callback data.-	queryRehashPair *pair = (queryRehashPair *)data;-	cpSpaceHash *hash = pair->hash;-	cpSpaceHashQueryFunc func = pair->func;--	cpFloat dim = hash->celldim;-	int n = hash->numcells;--	void *obj = hand->obj;-	cpBB bb = hash->bbfunc(obj);--	int l = floor_int(bb.l/dim);-	int r = floor_int(bb.r/dim);-	int b = floor_int(bb.b/dim);-	int t = floor_int(bb.t/dim);-	-	cpSpaceHashBin **table = hash->table;--	for(int i=l; i<=r; i++){-		for(int j=b; j<=t; j++){-			int idx = hash_func(i,j,n);-			cpSpaceHashBin *bin = table[idx];-			-			if(containsHandle(bin, hand)) continue;-			-			cpHandleRetain(hand); // this MUST be done first in case the object is removed in func()-			query(hash, &bin, obj, func, pair->data);-			-			cpSpaceHashBin *newBin = getEmptyBin(hash);-			newBin->handle = hand;-			newBin->next = bin;-			table[idx] = newBin;-		}-	}-	-	// Increment the stamp for each object hashed.-	hash->stamp++;-}--void-cpSpaceHashQueryRehash(cpSpaceHash *hash, cpSpaceHashQueryFunc func, void *data)-{-	clearHash(hash);-	-	queryRehashPair pair = {hash, func, data};-	cpHashSetEach(hash->handleSet, &handleQueryRehashHelper, &pair);-}--static inline cpFloat-segmentQuery(cpSpaceHash *hash, cpSpaceHashBin **bin_ptr, void *obj, cpSpaceHashSegmentQueryFunc func, void *data)-{-	cpFloat t = 1.0f;-	 -	restart:-	for(cpSpaceHashBin *bin = *bin_ptr; bin; bin = bin->next){-		cpHandle *hand = bin->handle;-		void *other = hand->obj;-		-		// Skip over certain conditions-		if(hand->stamp == hash->stamp){-			continue;-		} else if(other){-			t = cpfmin(t, func(obj, other, data));-			hand->stamp = hash->stamp;-		} else {-			// The object for this handle has been removed-			// cleanup this cell and restart the query-			removeOrphanedHandles(hash, bin_ptr);-			goto restart; // GCC not smart enough/able to tail call an inlined function.-		}-	}-	-	return t;-}--// modified from http://playtechs.blogspot.com/2007/03/raytracing-on-grid.html-void cpSpaceHashSegmentQuery(cpSpaceHash *hash, void *obj, cpVect a, cpVect b, cpFloat t_exit, cpSpaceHashSegmentQueryFunc func, void *data)-{-	a = cpvmult(a, 1.0f/hash->celldim);-	b = cpvmult(b, 1.0f/hash->celldim);-	-	int cell_x = floor_int(a.x), cell_y = floor_int(a.y);--	cpFloat t = 0;--	int x_inc, y_inc;-	cpFloat temp_v, temp_h;--	if (b.x > a.x){-		x_inc = 1;-		temp_h = (cpffloor(a.x + 1.0f) - a.x);-	} else {-		x_inc = -1;-		temp_h = (a.x - cpffloor(a.x));-	}--	if (b.y > a.y){-		y_inc = 1;-		temp_v = (cpffloor(a.y + 1.0f) - a.y);-	} else {-		y_inc = -1;-		temp_v = (a.y - cpffloor(a.y));-	}-	-	// Division by zero is *very* slow on ARM-	cpFloat dx = cpfabs(b.x - a.x), dy = cpfabs(b.y - a.y);-	cpFloat dt_dx = (dx ? 1.0f/dx : INFINITY), dt_dy = (dy ? 1.0f/dy : INFINITY);-	-	// fix NANs in horizontal directions-	cpFloat next_h = (temp_h ? temp_h*dt_dx : dt_dx);-	cpFloat next_v = (temp_v ? temp_v*dt_dy : dt_dy);-	-	cpSpaceHashBin **table = hash->table;--	int n = hash->numcells;-	while(t < t_exit){-		int idx = hash_func(cell_x, cell_y, n);-		t_exit = cpfmin(t_exit, segmentQuery(hash, &table[idx], obj, func, data));--		if (next_v < next_h){-			cell_y += y_inc;-			t = next_v;-			next_v += dt_dy;-		} else {-			cell_x += x_inc;-			t = next_h;-			next_h += dt_dx;-		}-	}-	-	hash->stamp++;-}
− Chipmunk-5.3.4/src/cpSpaceQuery.c
@@ -1,246 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */- -#include <stdlib.h>--#include "chipmunk_private.h"--#pragma mark Point Query Functions--typedef struct pointQueryContext {-	cpLayers layers;-	cpGroup group;-	cpSpacePointQueryFunc func;-	void *data;-} pointQueryContext;--static void -pointQueryHelper(cpVect *point, cpShape *shape, pointQueryContext *context)-{-	if(-		!(shape->group && context->group == shape->group) && (context->layers&shape->layers) &&-		cpShapePointQuery(shape, *point)-	){-		context->func(shape, context->data);-	}-}--void-cpSpacePointQuery(cpSpace *space, cpVect point, cpLayers layers, cpGroup group, cpSpacePointQueryFunc func, void *data)-{-	pointQueryContext context = {layers, group, func, data};-	-	cpSpaceLock(space); {-		cpSpaceHashPointQuery(space->activeShapes, point, (cpSpaceHashQueryFunc)pointQueryHelper, &context);-		cpSpaceHashPointQuery(space->staticShapes, point, (cpSpaceHashQueryFunc)pointQueryHelper, &context);-	} cpSpaceUnlock(space);-}--static void-rememberLastPointQuery(cpShape *shape, cpShape **outShape)-{-	if(!shape->sensor) *outShape = shape;-}--cpShape *-cpSpacePointQueryFirst(cpSpace *space, cpVect point, cpLayers layers, cpGroup group)-{-	cpShape *shape = NULL;-	cpSpacePointQuery(space, point, layers, group, (cpSpacePointQueryFunc)rememberLastPointQuery, &shape);-	-	return shape;-}---#pragma mark Segment Query Functions--typedef struct segQueryContext {-	cpVect start, end;-	cpLayers layers;-	cpGroup group;-	cpSpaceSegmentQueryFunc func;-} segQueryContext;--static cpFloat-segQueryFunc(segQueryContext *context, cpShape *shape, void *data)-{-	cpSegmentQueryInfo info;-	-	if(-		!(shape->group && context->group == shape->group) && (context->layers&shape->layers) &&-		cpShapeSegmentQuery(shape, context->start, context->end, &info)-	){-		context->func(shape, info.t, info.n, data);-	}-	-	return 1.0f;-}--void-cpSpaceSegmentQuery(cpSpace *space, cpVect start, cpVect end, cpLayers layers, cpGroup group, cpSpaceSegmentQueryFunc func, void *data)-{-	segQueryContext context = {-		start, end,-		layers, group,-		func,-	};-	-	cpSpaceLock(space); {-		cpSpaceHashSegmentQuery(space->staticShapes, &context, start, end, 1.0f, (cpSpaceHashSegmentQueryFunc)segQueryFunc, data);-		cpSpaceHashSegmentQuery(space->activeShapes, &context, start, end, 1.0f, (cpSpaceHashSegmentQueryFunc)segQueryFunc, data);-	} cpSpaceUnlock(space);-}--typedef struct segQueryFirstContext {-	cpVect start, end;-	cpLayers layers;-	cpGroup group;-} segQueryFirstContext;--static cpFloat-segQueryFirst(segQueryFirstContext *context, cpShape *shape, cpSegmentQueryInfo *out)-{-	cpSegmentQueryInfo info;-	-	if(-		!(shape->group && context->group == shape->group) &&-		(context->layers&shape->layers) &&-		!shape->sensor &&-		cpShapeSegmentQuery(shape, context->start, context->end, &info) &&-		info.t < out->t-	){-		*out = info;-	}-	-	return out->t;-}--cpShape *-cpSpaceSegmentQueryFirst(cpSpace *space, cpVect start, cpVect end, cpLayers layers, cpGroup group, cpSegmentQueryInfo *out)-{-	cpSegmentQueryInfo info = {NULL, 1.0f, cpvzero};-	if(out){-		(*out) = info;-  } else {-		out = &info;-	}-	-	segQueryFirstContext context = {-		start, end,-		layers, group-	};-	-	cpSpaceHashSegmentQuery(space->staticShapes, &context, start, end, 1.0f, (cpSpaceHashSegmentQueryFunc)segQueryFirst, out);-	cpSpaceHashSegmentQuery(space->activeShapes, &context, start, end, out->t, (cpSpaceHashSegmentQueryFunc)segQueryFirst, out);-	-	return out->shape;-}--#pragma mark BB Query Functions--typedef struct bbQueryContext {-	cpLayers layers;-	cpGroup group;-	cpSpaceBBQueryFunc func;-	void *data;-} bbQueryContext;--static void -bbQueryHelper(cpBB *bb, cpShape *shape, bbQueryContext *context)-{-	if(-		!(shape->group && context->group == shape->group) && (context->layers&shape->layers) &&-		cpBBintersects(*bb, shape->bb)-	){-		context->func(shape, context->data);-	}-}--void-cpSpaceBBQuery(cpSpace *space, cpBB bb, cpLayers layers, cpGroup group, cpSpaceBBQueryFunc func, void *data)-{-	bbQueryContext context = {layers, group, func, data};-	-	cpSpaceLock(space); {-		cpSpaceHashQuery(space->activeShapes, &bb, bb, (cpSpaceHashQueryFunc)bbQueryHelper, &context);-		cpSpaceHashQuery(space->staticShapes, &bb, bb, (cpSpaceHashQueryFunc)bbQueryHelper, &context);-	} cpSpaceUnlock(space);-}--#pragma mark Shape Query Functions--typedef struct shapeQueryContext {-	cpSpaceShapeQueryFunc func;-	void *data;-	cpBool anyCollision;-} shapeQueryContext;--// Callback from the spatial hash.-static void-shapeQueryHelper(cpShape *a, cpShape *b, shapeQueryContext *context)-{-	// Reject any of the simple cases-	if(-		(a->group && a->group == b->group) ||-		!(a->layers & b->layers) ||-		a->sensor || b->sensor-	) return;-	-	cpContact contacts[CP_MAX_CONTACTS_PER_ARBITER];-	int numContacts = 0;-	-	// Shape 'a' should have the lower shape type. (required by cpCollideShapes() )-	if(a->klass->type <= b->klass->type){-		numContacts = cpCollideShapes(a, b, contacts);-	} else {-		numContacts = cpCollideShapes(b, a, contacts);-		for(int i=0; i<numContacts; i++) contacts[i].n = cpvneg(contacts[i].n);-	}-	-	if(numContacts){-		context->anyCollision = cpTrue;-		-		if(context->func){-			cpContactPointSet set = {numContacts, {}};-			for(int i=0; i<set.count; i++){-				set.points[i].point = contacts[i].p;-				set.points[i].normal = contacts[i].p;-				set.points[i].dist = contacts[i].dist;-			}-			-			context->func(b, &set, context->data);-		}-	}-}--cpBool-cpSpaceShapeQuery(cpSpace *space, cpShape *shape, cpSpaceShapeQueryFunc func, void *data)-{-	cpBB bb = cpShapeCacheBB(shape);-	shapeQueryContext context = {func, data, cpFalse};-	-	cpSpaceLock(space); {-		cpSpaceHashQuery(space->activeShapes, shape, bb, (cpSpaceHashQueryFunc)shapeQueryHelper, &context);-		cpSpaceHashQuery(space->staticShapes, shape, bb, (cpSpaceHashQueryFunc)shapeQueryHelper, &context);-	} cpSpaceUnlock(space);-	-	return context.anyCollision;-}
− Chipmunk-5.3.4/src/cpSpaceStep.c
@@ -1,398 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */- -#include <stdlib.h>-//#include <stdio.h>-#include <math.h>--#include "chipmunk_private.h"--#pragma mark Post Step Callback Functions--typedef struct PostStepCallback {-	cpPostStepFunc func;-	void *obj;-	void *data;-} PostStepCallback;--static cpBool-postStepFuncSetEql(PostStepCallback *a, PostStepCallback *b){-	return a->obj == b->obj;-}--static void *-postStepFuncSetTrans(PostStepCallback *callback, void *ignored)-{-	PostStepCallback *value = (PostStepCallback *)cpmalloc(sizeof(PostStepCallback));-	(*value) = (*callback);-	-	return value;-}--void-cpSpaceAddPostStepCallback(cpSpace *space, cpPostStepFunc func, void *obj, void *data)-{-	if(!space->postStepCallbacks){-		space->postStepCallbacks = cpHashSetNew(0, (cpHashSetEqlFunc)postStepFuncSetEql, (cpHashSetTransFunc)postStepFuncSetTrans);-	}-	-	PostStepCallback callback = {func, obj, data};-	cpHashSetInsert(space->postStepCallbacks, (cpHashValue)(size_t)obj, &callback, NULL);-}--void *-cpSpaceGetPostStepData(cpSpace *space, void *obj)-{-	if(space->postStepCallbacks){-		PostStepCallback query = {NULL, obj, NULL};-		PostStepCallback *callback = (PostStepCallback *)cpHashSetFind(space->postStepCallbacks, (cpHashValue)(size_t)obj, &query);-		return (callback ? callback->data : NULL);-	} else {-		return NULL;-	}-}--#pragma mark Contact Buffer Functions--#define CP_CONTACTS_BUFFER_SIZE ((CP_BUFFER_BYTES - sizeof(cpContactBufferHeader))/sizeof(cpContact))-typedef struct cpContactBuffer {-	cpContactBufferHeader header;-	cpContact contacts[CP_CONTACTS_BUFFER_SIZE];-} cpContactBuffer;--static cpContactBufferHeader *-cpSpaceAllocContactBuffer(cpSpace *space)-{-	cpContactBuffer *buffer = (cpContactBuffer *)cpmalloc(sizeof(cpContactBuffer));-	cpArrayPush(space->allocatedBuffers, buffer);-	return (cpContactBufferHeader *)buffer;-}--static cpContactBufferHeader *-cpContactBufferHeaderInit(cpContactBufferHeader *header, cpTimestamp stamp, cpContactBufferHeader *splice)-{-	header->stamp = stamp;-	header->next = (splice ? splice->next : header);-	header->numContacts = 0;-	-	return header;-}--static void-cpSpacePushFreshContactBuffer(cpSpace *space)-{-	cpTimestamp stamp = space->stamp;-	-	cpContactBufferHeader *head = space->contactBuffersHead;-	-	if(!head){-		// No buffers have been allocated, make one-		space->contactBuffersHead = cpContactBufferHeaderInit(cpSpaceAllocContactBuffer(space), stamp, NULL);-	} else if(stamp - head->next->stamp > cp_contact_persistence){-		// The tail buffer is available, rotate the ring-	cpContactBufferHeader *tail = head->next;-		space->contactBuffersHead = cpContactBufferHeaderInit(tail, stamp, tail);-	} else {-		// Allocate a new buffer and push it into the ring-		cpContactBufferHeader *buffer = cpContactBufferHeaderInit(cpSpaceAllocContactBuffer(space), stamp, head);-		space->contactBuffersHead = head->next = buffer;-	}-}---static cpContact *-cpContactBufferGetArray(cpSpace *space)-{-	if(space->contactBuffersHead->numContacts + CP_MAX_CONTACTS_PER_ARBITER > CP_CONTACTS_BUFFER_SIZE){-		// contact buffer could overflow on the next collision, push a fresh one.-		cpSpacePushFreshContactBuffer(space);-	}-	-	cpContactBufferHeader *head = space->contactBuffersHead;-	return ((cpContactBuffer *)head)->contacts + head->numContacts;-}--static inline void-cpSpacePushContacts(cpSpace *space, int count){-	cpAssert(count <= CP_MAX_CONTACTS_PER_ARBITER, "Internal error, too many contact point overflow!");-	space->contactBuffersHead->numContacts += count;-}--static inline void-cpSpacePopContacts(cpSpace *space, int count){-	space->contactBuffersHead->numContacts -= count;-}--#pragma mark Collision Detection Functions--static inline cpBool-queryReject(cpShape *a, cpShape *b)-{-	return-		// BBoxes must overlap-		!cpBBintersects(a->bb, b->bb)-		// Don't collide shapes attached to the same body.-		|| a->body == b->body-		// Don't collide objects in the same non-zero group-		|| (a->group && a->group == b->group)-		// Don't collide objects that don't share at least on layer.-		|| !(a->layers & b->layers);-}--// Callback from the spatial hash.-static void-queryFunc(cpShape *a, cpShape *b, cpSpace *space)-{-	// Reject any of the simple cases-	if(queryReject(a,b)) return;-	-	// Find the collision pair function for the shapes.-	struct{cpCollisionType a, b;} ids = {a->collision_type, b->collision_type};-	cpHashValue collHashID = CP_HASH_PAIR(a->collision_type, b->collision_type);-	cpCollisionHandler *handler = (cpCollisionHandler *)cpHashSetFind(space->collFuncSet, collHashID, &ids);-	-	cpBool sensor = a->sensor || b->sensor;-	if(sensor && handler == &space->defaultHandler) return;-	-	// Shape 'a' should have the lower shape type. (required by cpCollideShapes() )-	if(a->klass->type > b->klass->type){-		cpShape *temp = a;-		a = b;-		b = temp;-	}-	-	// Narrow-phase collision detection.-	cpContact *contacts = cpContactBufferGetArray(space);-	int numContacts = cpCollideShapes(a, b, contacts);-	if(!numContacts) return; // Shapes are not colliding.-	cpSpacePushContacts(space, numContacts);-	-	// Get an arbiter from space->contactSet for the two shapes.-	// This is where the persistant contact magic comes from.-	cpShape *shape_pair[] = {a, b};-	cpHashValue arbHashID = CP_HASH_PAIR((size_t)a, (size_t)b);-	cpArbiter *arb = (cpArbiter *)cpHashSetInsert(space->contactSet, arbHashID, shape_pair, space);-	cpArbiterUpdate(arb, contacts, numContacts, handler, a, b);-	-	// Call the begin function first if it's the first step-	if(arb->state == cpArbiterStateFirstColl && !handler->begin(arb, space, handler->data)){-		cpArbiterIgnore(arb); // permanently ignore the collision until separation-	}-	-	if(-		// Ignore the arbiter if it has been flagged-		(arb->state != cpArbiterStateIgnore) && -		// Call preSolve-		handler->preSolve(arb, space, handler->data) &&-		// Process, but don't add collisions for sensors.-		!sensor-	){-		cpArrayPush(space->arbiters, arb);-	} else {-		cpSpacePopContacts(space, numContacts);-		-		arb->contacts = NULL;-		arb->numContacts = 0;-		-		// Normally arbiters are set as used after calling the post-step callback.-		// However, post-step callbacks are not called for sensors or arbiters rejected from pre-solve.-		if(arb->state != cpArbiterStateIgnore) arb->state = cpArbiterStateNormal;-	}-	-	// Time stamp the arbiter so we know it was used recently.-	arb->stamp = space->stamp;-}--// Iterator for active/static hash collisions.-static void-active2staticIter(cpShape *shape, cpSpace *space)-{-	cpSpaceHashQuery(space->staticShapes, shape, shape->bb, (cpSpaceHashQueryFunc)queryFunc, space);-}--// Hashset filter func to throw away old arbiters.-static cpBool-contactSetFilter(cpArbiter *arb, cpSpace *space)-{-	if(space->sleepTimeThreshold != INFINITY){-		cpBody *a = arb->a->body;-		cpBody *b = arb->b->body;-		-		// both bodies are either static or sleeping-		cpBool sleepingNow =-			(cpBodyIsStatic(a) || cpBodyIsSleeping(a)) &&-			(cpBodyIsStatic(b) || cpBodyIsSleeping(b));-		-		if(sleepingNow){-			arb->state = cpArbiterStateSleep;-			return cpTrue;-		} else if(arb->state == cpArbiterStateSleep){-			// wake up the arbiter and continue as normal-			arb->state = cpArbiterStateNormal;-			// TODO is it possible that cpArbiterStateIgnore should be set here instead?-		}-	}-	-	cpTimestamp ticks = space->stamp - arb->stamp;-	-	// was used last frame, but not this one-	if(ticks >= 1 && arb->state != cpArbiterStateCached){-		arb->handler->separate(arb, space, arb->handler->data);-		arb->state = cpArbiterStateCached;-	}-	-	if(ticks >= cp_contact_persistence){-		arb->contacts = NULL;-		arb->numContacts = 0;-		-		cpArrayPush(space->pooledArbiters, arb);-		return cpFalse;-	}-	-	return cpTrue;-}--// Hashset filter func to call and throw away post step callbacks.-static void-postStepCallbackSetIter(PostStepCallback *callback, cpSpace *space)-{-	callback->func(space, callback->obj, callback->data);-	cpfree(callback);-}--#pragma mark All Important cpSpaceStep() Function--void cpSpaceProcessComponents(cpSpace *space, cpFloat dt);--static void updateBBCache(cpShape *shape, void *unused){cpShapeCacheBB(shape);}--void-cpSpaceStep(cpSpace *space, cpFloat dt)-{-	if(!dt) return; // don't step if the timestep is 0!-	cpFloat dt_inv = 1.0f/dt;--	cpArray *bodies = space->bodies;-	cpArray *constraints = space->constraints;-	-	// Empty the arbiter list.-	space->arbiters->num = 0;--	// Integrate positions.-	for(int i=0; i<bodies->num; i++){-		cpBody *body = (cpBody *)bodies->arr[i];-		body->position_func(body, dt);-	}-	-	// Pre-cache BBoxes and shape data.-	cpSpaceHashEach(space->activeShapes, (cpSpaceHashIterator)updateBBCache, NULL);-	-	cpSpaceLock(space);-	-	// Collide!-	cpSpacePushFreshContactBuffer(space);-	if(space->staticShapes->handleSet->entries)-		cpSpaceHashEach(space->activeShapes, (cpSpaceHashIterator)active2staticIter, space);-	cpSpaceHashQueryRehash(space->activeShapes, (cpSpaceHashQueryFunc)queryFunc, space);-	-	cpSpaceUnlock(space);-	-	// If body sleeping is enabled, do that now.-	if(space->sleepTimeThreshold != INFINITY){-		cpSpaceProcessComponents(space, dt);-		bodies = space->bodies; // rebuilt by processContactComponents()-	}-	-	// Clear out old cached arbiters and dispatch untouch functions-	cpHashSetFilter(space->contactSet, (cpHashSetFilterFunc)contactSetFilter, space);--	// Prestep the arbiters.-	cpArray *arbiters = space->arbiters;-	for(int i=0; i<arbiters->num; i++)-		cpArbiterPreStep((cpArbiter *)arbiters->arr[i], dt_inv);--	// Prestep the constraints.-	for(int i=0; i<constraints->num; i++){-		cpConstraint *constraint = (cpConstraint *)constraints->arr[i];-		constraint->klass->preStep(constraint, dt, dt_inv);-	}--	for(int i=0; i<space->elasticIterations; i++){-		for(int j=0; j<arbiters->num; j++)-			cpArbiterApplyImpulse((cpArbiter *)arbiters->arr[j], 1.0f);-			-		for(int j=0; j<constraints->num; j++){-			cpConstraint *constraint = (cpConstraint *)constraints->arr[j];-			constraint->klass->applyImpulse(constraint);-		}-	}--	// Integrate velocities.-	cpFloat damping = cpfpow(1.0f/space->damping, -dt);-	for(int i=0; i<bodies->num; i++){-		cpBody *body = (cpBody *)bodies->arr[i];-		body->velocity_func(body, space->gravity, damping, dt);-	}--	for(int i=0; i<arbiters->num; i++)-		cpArbiterApplyCachedImpulse((cpArbiter *)arbiters->arr[i]);-	-	// run the old-style elastic solver if elastic iterations are disabled-	cpFloat elasticCoef = (space->elasticIterations ? 0.0f : 1.0f);-	-	// Run the impulse solver.-	for(int i=0; i<space->iterations; i++){-		for(int j=0; j<arbiters->num; j++)-			cpArbiterApplyImpulse((cpArbiter *)arbiters->arr[j], elasticCoef);-			-		for(int j=0; j<constraints->num; j++){-			cpConstraint *constraint = (cpConstraint *)constraints->arr[j];-			constraint->klass->applyImpulse(constraint);-		}-	}-	-	cpSpaceLock(space);-	-	// run the post solve callbacks-	for(int i=0; i<arbiters->num; i++){-		cpArbiter *arb = (cpArbiter *) arbiters->arr[i];-		-		cpCollisionHandler *handler = arb->handler;-		handler->postSolve(arb, space, handler->data);-		-		arb->state = cpArbiterStateNormal;-	}-	-	cpSpaceUnlock(space);-	-	// Run the post step callbacks-	// Loop because post step callbacks may create more post step callbacks-	while(space->postStepCallbacks){-		cpHashSet *callbacks = space->postStepCallbacks;-		space->postStepCallbacks = NULL;-		-		cpHashSetEach(callbacks, (cpHashSetIterFunc)postStepCallbackSetIter, space);-		cpHashSetFree(callbacks);-	}-	-	// Increment the stamp.-	space->stamp++;-}
− Chipmunk-5.3.4/src/cpVect.c
@@ -1,71 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */- -#include <stdio.h>-#include <math.h>--#include "chipmunk.h"--cpFloat-cpvlength(const cpVect v)-{-	return cpfsqrt( cpvdot(v, v) );-}--inline cpVect-cpvslerp(const cpVect v1, const cpVect v2, const cpFloat t)-{-	cpFloat omega = cpfacos(cpvdot(v1, v2));-	-	if(omega){-		cpFloat denom = 1.0f/cpfsin(omega);-		return cpvadd(cpvmult(v1, cpfsin((1.0f - t)*omega)*denom), cpvmult(v2, cpfsin(t*omega)*denom));-	} else {-		return v1;-	}-}--cpVect-cpvslerpconst(const cpVect v1, const cpVect v2, const cpFloat a)-{-	cpFloat angle = cpfacos(cpvdot(v1, v2));-	return cpvslerp(v1, v2, cpfmin(a, angle)/angle);-}--cpVect-cpvforangle(const cpFloat a)-{-	return cpv(cpfcos(a), cpfsin(a));-}--cpFloat-cpvtoangle(const cpVect v)-{-	return cpfatan2(v.y, v.x);-}--char*-cpvstr(const cpVect v)-{-	static char str[256];-	sprintf(str, "(% .3f, % .3f)", v.x, v.y);-	return str;-}
− Chipmunk-5.3.4/src/prime.h
@@ -1,68 +0,0 @@-/* Copyright (c) 2007 Scott Lembcke- * - * Permission is hereby granted, free of charge, to any person obtaining a copy- * of this software and associated documentation files (the "Software"), to deal- * in the Software without restriction, including without limitation the rights- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell- * copies of the Software, and to permit persons to whom the Software is- * furnished to do so, subject to the following conditions:- * - * The above copyright notice and this permission notice shall be included in- * all copies or substantial portions of the Software.- * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE- * SOFTWARE.- */- -// Used for resizing hash tables.-// Values approximately double.-// http://planetmath.org/encyclopedia/GoodHashTablePrimes.html-static int primes[] = {-	5,-	13,-	23,-	47,-	97,-	193,-	389,-	769,-	1543,-	3079,-	6151,-	12289,-	24593,-	49157,-	98317,-	196613,-	393241,-	786433,-	1572869,-	3145739,-	6291469,-	12582917,-	25165843,-	50331653,-	100663319,-	201326611,-	402653189,-	805306457,-	1610612741,-	0,-};--static inline int-next_prime(int n)-{-	int i = 0;-	while(n > primes[i]){-		i++;-		cpAssert(primes[i], "Tried to resize a hash table to a size greater than 1610612741 O_o"); // realistically this should never happen-	}-	-	return primes[i];-}
+ Chipmunk-5.3.5/LICENSE.txt view
@@ -0,0 +1,19 @@+Copyright (c) 2007 Scott Lembcke and Howling Moon Software++Permission is hereby granted, free of charge, to any person obtaining a copy+of this software and associated documentation files (the "Software"), to deal+in the Software without restriction, including without limitation the rights+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+copies of the Software, and to permit persons to whom the Software is+furnished to do so, subject to the following conditions:++The above copyright notice and this permission notice shall be included in+all copies or substantial portions of the Software.++THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+SOFTWARE.
+ Chipmunk-5.3.5/README.txt view
@@ -0,0 +1,126 @@+ABOUT:+Chipmunk is a simple, lightweight, fast and portable 2D rigid body physics library written in C. It's licensed under the unrestrictive, OSI approved MIT license. My aim is to give 2D developers access the same quality of physics you find in newer 3D games. I hope you enjoy using Chipmunk, and please consider donating to help make it worth our time to continue to support Chipmunk with great new features.++CONTRACTING:+Howling Moon Software (my company) is available for contracting if you want to make the physics in your game really stand out. Given our unique experience with the library, we can help you use Chipmunk to it's fullest potential. Feel free to contact us through our webpage: http://howlingmoonsoftware.com/contracting.php++Objective-Chipmunk:+The Objective-Chipmunk directory contains an Objective-C wrapper for the Chipmunk Physics Library as well as some sample code from shipping iPhone Apps. One reason Chipmunk was written in C was to allow easy wrapping for other languages. The primary advantages of a native Objective-C API include integrating with the Cocoa memory management model and the Chipmunk Object protocol. The Chipmunk Object protocol unifies the basic Chipmunk types as well as making it easy to create and manage custom composite collections of the basic types. Additionally, the wrapper adds many convenience methods for doing common setup tasks as well as helper methods that integrate it with the rest of the Cocoa Touch API and basic datatypes used on the iPhone. The wrapper tries to do things the Objective-C way, adding useful method variations where it makes sense to do so. If you are an iPhone developer, Objective-Chipmunk will definitely save you time.++To try Objective-Chipmunk in your own projects see Objective-Chipmunk/Objective-Chipmunk/Readme.rtf.++BUILDING:+Mac OS X: There is an included XCode project file for building the static library and demo application. Alternatively you could use the CMake files. A Mac OS X version of Objective-Chipmunk is available for free upon request. We don't do regular builds as few people seem interested in it.++iPhone: If you want a native Objective-C API, check out the Objective-Chipmunk directory for the Objective-C binding and some sample code from shipping iPhone Apps. It is inexpensive to license and should save you a lot of time. Otherwise, the XCode project can build a static library with all the proper compiler settings. Alternatively, you can just run iphonestatic.command in the macosx/ directory.  It will build you a fat library compiled as release for the device and debug for the simulator. After running it, you can simply drop the Chipmunk-iPhone directory into your iPhone project!++UNIXes: A forum user was kind enough to make a set of CMake files for Chipmunk. This will require you to have CMake installed. To build run 'cmake .' then 'make'. This should build a dynamic library, a static library, and the demo application. A number of people have had build errors on Ubuntu due to not having GLUT or libxmu installed.++Windows: Visual Studio projects are included in the msvc/ directory. I do not maintain these personally, but a number of forum members have assisted with them.++Ruby: I've been using maintaining a Ruby extension for Chipmunk, but at this time is not up to date with all the latest changes. It has been tested and builds under Linux and OS X using CMake however 'cmake -D BUILD_RUBY_EXT=ON .; make'. A forum member has been working on an FFI based extention (http://github.com/erisdiscord/chipmunk-ffi), and that may be a better way to take advantage of Chipmunk from Ruby. Another forum user has offered to maintain the non-FFI version of the extension. Stay tuned.++GETTING STARTED:+First of all, you can find the C API documentation in the doc/ directory.++A good starting point is to take a look at the included Demo application. The demos all just set up a Chipmunk simulation space and the demo app draws the graphics directly out of that. This makes it easy to see how the Chipmunk API works without worrying about the graphics code. You are free to use the demo drawing routines in your own projects, though it is certainly not the recommended way of drawing Chipmunk objects as it pokes around at the undocumented parts of Chipmunk.++If you are looking at Objective-Chipmunk for the iPhone, we have a number of example projects and tutorials in the Objective-Chipmunk directory.++FORUM:+http://www.slembcke.net/forums++CONTACT:+slembcke@gmail.com (also on Google Talk)++CHANGES SINCE 5.3.4+* FIX: Fixed spelling of cpArbiterGetDepth(). Was cpArbiteGetDepth() before. Apparently nobody ever used this function.+* FIX: Added defines for M_PI and M_E. Apparently these values were never part of the C standard math library. Who knew!?+* FIX: Added a guard to cpBodyActivate() so that it's a noop for rouge bodies.+* FIX: Shape queries now work with (and against) sensor shapes.+* FIX: Fixed an issue where removing a collision handler while a separate() callback was waiting to fire the next step would cause crashes.+* FIX: Fixed an issue where the default callback would not be called for sensor shapes.+* FIX: Resetting or applying forces or impulses on a body causes it to wake up now.+* MISC: Added a check that a space was not locked when adding or removing a callback.+* MISC: Removed cpmalloc from the API and replaced all occurences with cpcalloc+* MISC: Added a benchmarking mode to the demo app. -trial runs it in time trial mode and -bench makes it run some benchmarking demos.++CHANGES SINCE 5.3.3:+* FIX: cpBodyActivate() can now be called from collision and query callbacks. This way you can use the setter functions to change properties without indirectly calling cpBodyActivate() and causing an assertion.+* FIX: cpArbiterGetContactPointSet() was returning the collision points for the normals.+* FIX: cpSpaceEachBody() now includes sleeping bodies.+* FIX: Shapes attached to static rogue bodies created with cpBodyNewStatic() are added as static shapes.+* MISC: Applied a user patch to update the MSVC project and add a .def file.++CHANGES SINCE 5.3.2:+* API: Added cpArbiteGetCount() to return the number of contact points.+* API: Added helper functions for calculating areas of Chipmunk shapes as well as calculating polygon centroids and centering polygons on their centroid.+* API: Shape queries. Query a shape to test for collisions if it were to be inserted into a space.+* API: cpBodyInitStatic() and cpBodyNewStatic() for creating additional static (rogue) bodies.+* API: cpBodySleepWithGroup() to allow you to create groups of sleeping objects that are woken up together.+* API: Added overloaded *, +, - and == operators for C++ users.+* API: Added cpSpaceActivateShapesTouchingShape() to query for and activate any shapes touching a given shape. Useful if you ever need to move a static body.+* FIX: Fixed an extremely rare memory bug in the collision cache.+* FIX: Fixed a memory leak in Objective-Chipmunk that could cause ChipmunkSpace objects to be leaked.+* MISC: C struct fields and function that are considered private have been explicitly marked as such. Defining CP_ALLOW_PRIVATE_ACCESS to 0 in Chipmunk.h will let you test which parts of the private API that you are using and give me feedback about how to build proper APIs in Chipmunk 6 for what you are trying to do.+* MISC: Allow CGPoints to be used as cpVect on Mac OS X as well as iOS.+++CHANGES SINCE 5.3.1:+* FIX: Collision begin callbacks were being called continuously for sensors or collisions rejected from the pre-solve callback.+* FIX: Plugged a nasty memory leak when adding post-step callbacks.+* FIX: Shapes were being added to the spatial hash using an uninitialized bounding box in some cases.+* FIX: Perfectly aligned circle shapes now push each other apart.+* FIX: cpBody setter functions now call cpBodyActivate().+* FIX: Collision handler targets are released in Objective-Chipmunk when they are no longer needed instead of waiting for the space to be deallocated.+* API: cpSpaceSegmentQuery() no longer returns a boolean. Use cpSpaceSegmentQueryFirst() instead as it's more efficient.+* NEW: cpSpaceRehashShape() Rehash an individual shape, active or static.+* NEW: cpBodySleep() Force a body to fall asleep immediately.+* NEW: cpConstraintGetImpulse() Return the most recent impulse applied by a constraint.+* NEW: Added setter functions for the groove joint endpoints.+* MISC: A number of other minor optimizations and fixes.++CHANGES SINCE 5.3.0:+ * NEW: Added a brand new tutorial for Objective-Chipmunk: SimpleObjectiveChipmunk that can be found in the Objective-Chipmunk folder.+ * NEW: Proper API docs for Objective-Chipmunk.+ * NEW: Updated the included Objective-Chipmunk library.+ * FIX: Fixed a rare memory crash in the sensor demo.+ * FIX: Fixed some warnings that users submitted.++CHANGES SINCE 5.2.0:+ * FIX: Fixed the source so it can compile as C, C++, Objective-C, and Objective-C++.+ * FIX: Fixed cp_contact_persistence. It was broken so that it would forget collision solutions after 1 frame instead of respecting the value set.+ * OPTIMIZATION: Several minor optimizations have been added. Though performance should only differ by a few percent.+ * OPTIMIZATION: Chipmunk now supports putting bodies to sleep when they become inactive.+ * API: Elastic iterations are now deprecated as they should no longer be necessary.+ * API: Added API elements to support body sleeping.+ * API: Added a statically allocated static body to each space for attaching static shapes to.+ * API: Static shapes attached to the space's static body can simply be added to the space using cpSpaceAddShape().+ * NEW: New MSVC projects.+ * NEW: Added boolean and time stamp types for clarity.++CHANGES SINCE 5.1.0:+ * OPTIMIZATION: Chipmunk structs used within the solver are now allocated linearly in large blocks. This is much more CPU cache friendly. Programs have seen up to 50% performance improvements though 15-20% should be expected.+ * API: Shape references in cpArbiter structs changed to private_a and private_b to discourage accessing the fields directly and getting them out of order. You should be using cpArbiterGetShapes() or CP_ARBITER_GET_SHAPES() to access the shapes in the correct order.+ * API: Added assertion error messages as well as warnings and covered many new assertion cases.+ * FIX: separate() callbacks are called before shapes are removed from the space to prevent dangling pointers.+ * NEW: Added convenience functions for creating box shapes and calculating moments.+ ++CHANGES SINCE 5.0.0:+ * FIX: fixed a NaN issue that was causing raycasts for horizontal or vertical lines to end up in an infinite loop+ * FIX: fixed a number of memory leaks+ * FIX: fixed warnings for various compiler/OS combinations+ * API: Rejecting a collision from a begin() callback permanently rejects the collision until separation+ * API: Erroneous collision type parameterns removed from cpSpaceDefaulteCollisionHandler()+ * MOVE: FFI declarations of inlined functions into their own header+ * MOVE: Rearranged the project structure to separate out the header files into a separate include/ directory.+ * NEW: Added a static library target for the iPhone.+ * NEW: Type changes when building on the iPhone to make it friendlier to other iPhone APIs+ * NEW: Added an AABB query to complement point and segment queries+ * NEW: CP_NO_GROUP and CP_ALL_LAYERS constants++CHANGES SINCE 4.x:+ * Brand new Joint/Constraint API: New constraints can be added easily and are much more flexible than the old joint system+ * Efficient Segment Queries - Like raycasting, but with line segments.+ * Brand new collision callback API: Collision begin/separate events, API for removal of objects within callbacks, more programable control over collision handling.
+ Chipmunk-5.3.5/include/chipmunk/chipmunk.h view
@@ -0,0 +1,143 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */++#ifndef CHIPMUNK_HEADER+#define CHIPMUNK_HEADER++#ifdef __cplusplus+extern "C" {+#endif++#ifndef CP_ALLOW_PRIVATE_ACCESS+	#define CP_ALLOW_PRIVATE_ACCESS 1+#endif++#if CP_ALLOW_PRIVATE_ACCESS == 1+	#define CP_PRIVATE(symbol) symbol+#else+	#define CP_PRIVATE(symbol) symbol##_private+#endif++void cpMessage(const char *message, const char *condition, const char *file, int line, int isError);+#ifdef NDEBUG+	#define	cpAssertWarn(condition, message)+#else+	#define cpAssertWarn(condition, message) if(!(condition)) cpMessage(message, #condition, __FILE__, __LINE__, 0)+#endif++#ifdef NDEBUG+	#define	cpAssert(condition, message)+#else+	#define cpAssert(condition, message) if(!(condition)) cpMessage(message, #condition, __FILE__, __LINE__, 1)+#endif++#include "chipmunk_types.h"+	+// Maximum allocated size for various Chipmunk buffers+#define CP_BUFFER_BYTES (32*1024)++#define cpmalloc malloc+#define cpcalloc calloc+#define cprealloc realloc+#define cpfree free++#include "cpVect.h"+#include "cpBB.h"+#include "cpArray.h"+#include "cpHashSet.h"+#include "cpSpaceHash.h"++#include "cpBody.h"+#include "cpShape.h"+#include "cpPolyShape.h"++#include "cpArbiter.h"+#include "cpCollision.h"+	+#include "constraints/cpConstraint.h"++#include "cpSpace.h"++#define CP_HASH_COEF (3344921057ul)+#define CP_HASH_PAIR(A, B) ((cpHashValue)(A)*CP_HASH_COEF ^ (cpHashValue)(B)*CP_HASH_COEF)++extern const char *cpVersionString;+void cpInitChipmunk(void);++/**+	Calculate the moment of inertia for a circle.+	r1 and r2 are the inner and outer diameters. A solid circle has an inner diameter of 0.+*/+cpFloat cpMomentForCircle(cpFloat m, cpFloat r1, cpFloat r2, cpVect offset);++/**+	Calculate area of a hollow circle.+*/+cpFloat cpAreaForCircle(cpFloat r1, cpFloat r2);++/**+	Calculate the moment of inertia for a line segment.+	Beveling radius is not supported.+*/+cpFloat cpMomentForSegment(cpFloat m, cpVect a, cpVect b);++/**+	Calculate the area of a fattened (capsule shaped) line segment.+*/+cpFloat cpAreaForSegment(cpVect a, cpVect b, cpFloat r);++/**+	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.+*/+cpFloat cpMomentForPoly(cpFloat m, int numVerts, const cpVect *verts, cpVect offset);++/**+	Calculate the signed area of a polygon.+*/+cpFloat cpAreaForPoly(const int numVerts, const cpVect *verts);++/**+	Calculate the natural centroid of a polygon.+*/+cpVect cpCentroidForPoly(const int numVerts, const cpVect *verts);++/**+	Center the polygon on the origin. (Subtracts the centroid of the polygon from each vertex)+*/+void cpRecenterPoly(const int numVerts, cpVect *verts);++/**+	Calculate the moment of inertia for a solid box.+*/+cpFloat cpMomentForBox(cpFloat m, cpFloat width, cpFloat height);++#ifdef __cplusplus+}++static inline cpVect operator *(const cpVect v, const cpFloat s){return cpvmult(v, s);}+static inline cpVect operator +(const cpVect v1, const cpVect v2){return cpvadd(v1, v2);}+static inline cpVect operator -(const cpVect v1, const cpVect v2){return cpvsub(v1, v2);}+static inline cpBool operator ==(const cpVect v1, const cpVect v2){return cpveql(v1, v2);}+static inline cpVect operator -(const cpVect v){return cpvneg(v);}++#endif++#endif
+ Chipmunk-5.3.5/include/chipmunk/chipmunk_ffi.h view
@@ -0,0 +1,59 @@+// Create non static inlined copies of Chipmunk functions, useful for working with dynamic FFIs+// This file should only be included in chipmunk.c++#ifdef _MSC_VER+ #if _MSC_VER >= 1600+  #define MAKE_REF(name) decltype(name) *_##name = name+ #else+  #define MAKE_REF(name)+ #endif+#else+ #define MAKE_REF(name) __typeof__(name) *_##name = name+#endif++MAKE_REF(cpv); // makes a variable named _cpv that contains the function pointer for cpv()+MAKE_REF(cpveql);+MAKE_REF(cpvadd);+MAKE_REF(cpvneg);+MAKE_REF(cpvsub);+MAKE_REF(cpvmult);+MAKE_REF(cpvdot);+MAKE_REF(cpvcross);+MAKE_REF(cpvperp);+MAKE_REF(cpvrperp);+MAKE_REF(cpvproject);+MAKE_REF(cpvrotate);+MAKE_REF(cpvunrotate);+MAKE_REF(cpvlengthsq);+MAKE_REF(cpvlerp);+MAKE_REF(cpvnormalize);+MAKE_REF(cpvnormalize_safe);+MAKE_REF(cpvclamp);+MAKE_REF(cpvlerpconst);+MAKE_REF(cpvdist);+MAKE_REF(cpvdistsq);+MAKE_REF(cpvnear);++MAKE_REF(cpBBNew);+MAKE_REF(cpBBintersects);+MAKE_REF(cpBBcontainsBB);+MAKE_REF(cpBBcontainsVect);+MAKE_REF(cpBBmerge);+MAKE_REF(cpBBexpand);++MAKE_REF(cpBodyWorld2Local);+MAKE_REF(cpBodyLocal2World);+MAKE_REF(cpBodyApplyImpulse);+MAKE_REF(cpBodyIsSleeping);+MAKE_REF(cpBodyIsRogue);+MAKE_REF(cpBodyKineticEnergy);++MAKE_REF(cpArbiterIsFirstContact);+MAKE_REF(cpArbiterGetShapes);+MAKE_REF(cpArbiterGetNormal);+MAKE_REF(cpArbiterGetPoint);++MAKE_REF(cpConstraintGetImpulse);++MAKE_REF(cpSegmentQueryHitPoint);+MAKE_REF(cpSegmentQueryHitDist);
+ Chipmunk-5.3.5/include/chipmunk/chipmunk_private.h view
@@ -0,0 +1,49 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */++#define CP_ALLOW_PRIVATE_ACCESS 1+#include "chipmunk.h"++void *cpSpaceGetPostStepData(cpSpace *space, void *obj);++void cpSpaceActivateBody(cpSpace *space, cpBody *body);++static inline void+cpSpaceLock(cpSpace *space)+{+	space->locked++;+}++static inline void+cpSpaceUnlock(cpSpace *space)+{+	space->locked--;+	cpAssert(space->locked >= 0, "Internal error:Space lock underflow.");+	+	if(!space->locked){+		cpArray *waking = space->rousedBodies;+		for(int i=0, count=waking->num; i<count; i++){+			cpSpaceActivateBody(space, (cpBody *)waking->arr[i]);+		}+		+		waking->num = 0;+	}+}
+ Chipmunk-5.3.5/include/chipmunk/chipmunk_types.h view
@@ -0,0 +1,180 @@+#ifdef __APPLE__+   #import "TargetConditionals.h"+#endif++#if (defined TARGET_OS_IPHONE) && (!defined CP_USE_CGPOINTS)+	#define CP_USE_CGPOINTS+#endif++#ifdef CP_USE_CGPOINTS+	#if TARGET_OS_IPHONE+		#import <CoreGraphics/CGGeometry.h>+	#elif TARGET_OS_MAC+		#import <ApplicationServices/ApplicationServices.h>+	#endif+	+	#if defined(__LP64__) && __LP64__+		#define CP_USE_DOUBLES 1+	#else+		#define CP_USE_DOUBLES 0+	#endif+#endif++#ifndef CP_USE_DOUBLES+	// use doubles by default for higher precision+	#define CP_USE_DOUBLES 1+#endif++#if CP_USE_DOUBLES+	typedef double cpFloat;+	#define cpfsqrt sqrt+	#define cpfsin sin+	#define cpfcos cos+	#define cpfacos acos+	#define cpfatan2 atan2+	#define cpfmod fmod+	#define cpfexp exp+	#define cpfpow pow+	#define cpffloor floor+	#define cpfceil ceil+#else+	typedef float cpFloat;+	#define cpfsqrt sqrtf+	#define cpfsin sinf+	#define cpfcos cosf+	#define cpfacos acosf+	#define cpfatan2 atan2f+	#define cpfmod fmodf+	#define cpfexp expf+	#define cpfpow powf+	#define cpffloor floorf+	#define cpfceil ceilf+#endif++#ifndef INFINITY+	#ifdef _MSC_VER+		union MSVC_EVIL_FLOAT_HACK+		{+			unsigned __int8 Bytes[4];+			float Value;+		};+		static union MSVC_EVIL_FLOAT_HACK INFINITY_HACK = {{0x00, 0x00, 0x80, 0x7F}};+		#define INFINITY (INFINITY_HACK.Value)+	#endif+	+	#ifdef __GNUC__+		#define INFINITY (__builtin_inf())+	#endif+	+	#ifndef INFINITY+		#define INFINITY (1e1000)+	#endif+#endif++#ifndef M_PI+	#define M_PI 3.14159265358979323846264338327950288+#endif++#ifndef M_E+	#define M_E 2.71828182845904523536028747135266250+#endif+++static inline cpFloat+cpfmax(cpFloat a, cpFloat b)+{+	return (a > b) ? a : b;+}++static inline cpFloat+cpfmin(cpFloat a, cpFloat b)+{+	return (a < b) ? a : b;+}++static inline cpFloat+cpfabs(cpFloat n)+{+	return (n < 0) ? -n : n;+}++static inline cpFloat+cpfclamp(cpFloat f, cpFloat min, cpFloat max)+{+	return cpfmin(cpfmax(f, min), max);+}++static inline cpFloat+cpflerp(cpFloat f1, cpFloat f2, cpFloat t)+{+	return f1*(1.0f - t) + f2*t;+}++static inline cpFloat+cpflerpconst(cpFloat f1, cpFloat f2, cpFloat d)+{+	return f1 + cpfclamp(f2 - f1, -d, d);+}++// CGPoints are structurally the same, and allow+// easy interoperability with other Cocoa libraries+#ifdef CP_USE_CGPOINTS+	typedef CGPoint cpVect;+#else+	typedef struct cpVect{cpFloat x,y;} cpVect;+#endif++typedef unsigned int cpHashValue;++// Oh C, how we love to define our own boolean types to get compiler compatibility+#ifdef CP_BOOL_TYPE+	typedef CP_BOOL_TYPE cpBool;+#else+	typedef int cpBool;+#endif++#ifndef cpTrue+	#define cpTrue 1+#endif++#ifndef cpFalse+	#define cpFalse 0+#endif++#ifdef CP_DATA_POINTER_TYPE+	typedef CP_DATA_POINTER_TYPE cpDataPointer;+#else+	typedef void * cpDataPointer;+#endif++#ifdef CP_COLLISION_TYPE_TYPE+	typedef CP_COLLISION_TYPE_TYPE cpCollisionType;+#else+	typedef unsigned int cpCollisionType;+#endif++#ifdef CP_GROUP_TYPE+	typedef CP_GROUP_TYPE cpGroup;+#else+	typedef unsigned int cpGroup;+#endif++#ifdef CP_LAYERS_TYPE+	typedef CP_LAYERS_TYPE cpLayers;+#else+	typedef unsigned int cpLayers;+#endif++#ifdef CP_TIMESTAMP_TYPE+	typedef CP_TIMESTAMP_TYPE cpTimestamp;+#else+	typedef unsigned int cpTimestamp;+#endif++#ifndef CP_NO_GROUP+	#define CP_NO_GROUP ((cpGroup)0)+#endif++#ifndef CP_ALL_LAYERS+	#define CP_ALL_LAYERS (~(cpLayers)0)+#endif
+ Chipmunk-5.3.5/include/chipmunk/chipmunk_unsafe.h view
@@ -0,0 +1,54 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */++++/* This header defines a number of "unsafe" operations on Chipmunk objects.+ * In this case "unsafe" is referring to operations which may reduce the+ * physical accuracy or numerical stability of the simulation, but will not+ * cause crashes.+ *+ * The prime example is mutating collision shapes. Chipmunk does not support+ * this directly. Mutating shapes using this API will caused objects in contact+ * to be pushed apart using Chipmunk's overlap solver, but not using real+ * persistent velocities. Probably not what you meant, but perhaps close enough.+ */++#ifndef CHIPMUNK_UNSAFE_HEADER+#define CHIPMUNK_UNSAFE_HEADER++#ifdef __cplusplus+extern "C" {+#endif++void cpCircleShapeSetRadius(cpShape *shape, cpFloat radius);+void cpCircleShapeSetOffset(cpShape *shape, cpVect offset);++void cpSegmentShapeSetEndpoints(cpShape *shape, cpVect a, cpVect b);+void cpSegmentShapeSetRadius(cpShape *shape, cpFloat radius);++void cpPolyShapeSetVerts(cpShape *shape, int numVerts, cpVect *verts, cpVect offset);++#ifdef __cplusplus+}+#endif++#endif
+ Chipmunk-5.3.5/include/chipmunk/constraints/cpConstraint.h view
@@ -0,0 +1,105 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */++// TODO: Comment me!+	+extern cpFloat cp_constraint_bias_coef;++struct cpConstraintClass;+struct cpConstraint;++typedef void (*cpConstraintPreStepFunction)(struct cpConstraint *constraint, cpFloat dt, cpFloat dt_inv);+typedef void (*cpConstraintApplyImpulseFunction)(struct cpConstraint *constraint);+typedef cpFloat (*cpConstraintGetImpulseFunction)(struct cpConstraint *constraint);++typedef struct cpConstraintClass {+	cpConstraintPreStepFunction preStep;+	cpConstraintApplyImpulseFunction applyImpulse;+	cpConstraintGetImpulseFunction getImpulse;+} cpConstraintClass;++++typedef struct cpConstraint {+	CP_PRIVATE(const cpConstraintClass *klass);+	+	cpBody *a, *b;+	cpFloat maxForce;+	cpFloat biasCoef;+	cpFloat maxBias;+	+	cpDataPointer data;+} cpConstraint;++#ifdef CP_USE_DEPRECATED_API_4+typedef cpConstraint cpJoint;+#endif++void cpConstraintDestroy(cpConstraint *constraint);+void cpConstraintFree(cpConstraint *constraint);++static inline void+cpConstraintActivateBodies(cpConstraint *constraint)+{+	cpBody *a = constraint->a; if(a) cpBodyActivate(a);+	cpBody *b = constraint->b; if(b) cpBodyActivate(b);+}++static inline cpFloat+cpConstraintGetImpulse(cpConstraint *constraint)+{+	return constraint->CP_PRIVATE(klass)->getImpulse(constraint);+}++#define cpConstraintCheckCast(constraint, struct) \+	cpAssert(constraint->CP_PRIVATE(klass) == struct##GetClass(), "Constraint is not a "#struct);+++#define CP_DefineConstraintGetter(struct, type, member, name) \+static inline type \+struct##Get##name(const cpConstraint *constraint){ \+	cpConstraintCheckCast(constraint, struct); \+	return ((struct *)constraint)->member; \+} \++#define CP_DefineConstraintSetter(struct, type, member, name) \+static inline void \+struct##Set##name(cpConstraint *constraint, type value){ \+	cpConstraintCheckCast(constraint, struct); \+	cpConstraintActivateBodies(constraint); \+	((struct *)constraint)->member = value; \+} \++#define CP_DefineConstraintProperty(struct, type, member, name) \+CP_DefineConstraintGetter(struct, type, member, name) \+CP_DefineConstraintSetter(struct, type, member, name)++// Built in Joint types+#include "cpPinJoint.h"+#include "cpSlideJoint.h"+#include "cpPivotJoint.h"+#include "cpGrooveJoint.h"+#include "cpDampedSpring.h"+#include "cpDampedRotarySpring.h"+#include "cpRotaryLimitJoint.h"+#include "cpRatchetJoint.h"+#include "cpGearJoint.h"+#include "cpSimpleMotor.h"
+ Chipmunk-5.3.5/include/chipmunk/constraints/cpDampedRotarySpring.h view
@@ -0,0 +1,46 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */++typedef cpFloat (*cpDampedRotarySpringTorqueFunc)(struct cpConstraint *spring, cpFloat relativeAngle);++const cpConstraintClass *cpDampedRotarySpringGetClass();++typedef struct cpDampedRotarySpring {+	cpConstraint constraint;+	cpFloat restAngle;+	cpFloat stiffness;+	cpFloat damping;+	cpDampedRotarySpringTorqueFunc springTorqueFunc;+	+	cpFloat target_wrn;+	cpFloat w_coef;+	+	cpFloat iSum;+} cpDampedRotarySpring;++cpDampedRotarySpring *cpDampedRotarySpringAlloc(void);+cpDampedRotarySpring *cpDampedRotarySpringInit(cpDampedRotarySpring *joint, cpBody *a, cpBody *b, cpFloat restAngle, cpFloat stiffness, cpFloat damping);+cpConstraint *cpDampedRotarySpringNew(cpBody *a, cpBody *b, cpFloat restAngle, cpFloat stiffness, cpFloat damping);++CP_DefineConstraintProperty(cpDampedRotarySpring, cpFloat, restAngle, RestAngle);+CP_DefineConstraintProperty(cpDampedRotarySpring, cpFloat, stiffness, Stiffness);+CP_DefineConstraintProperty(cpDampedRotarySpring, cpFloat, damping, Damping);+CP_DefineConstraintProperty(cpDampedRotarySpring, cpDampedRotarySpringTorqueFunc, springTorqueFunc, SpringTorqueFunc);
+ Chipmunk-5.3.5/include/chipmunk/constraints/cpDampedSpring.h view
@@ -0,0 +1,53 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */++struct cpDampedSpring;++typedef cpFloat (*cpDampedSpringForceFunc)(struct cpConstraint *spring, cpFloat dist);++const cpConstraintClass *cpDampedSpringGetClass();++typedef struct cpDampedSpring {+	cpConstraint constraint;+	cpVect anchr1, anchr2;+	cpFloat restLength;+	cpFloat stiffness;+	cpFloat damping;+	cpDampedSpringForceFunc springForceFunc;+	+	cpFloat target_vrn;+	cpFloat v_coef;+	+	cpVect r1, r2;+	cpFloat nMass;+	cpVect n;+} cpDampedSpring;++cpDampedSpring *cpDampedSpringAlloc(void);+cpDampedSpring *cpDampedSpringInit(cpDampedSpring *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat restLength, cpFloat stiffness, cpFloat damping);+cpConstraint *cpDampedSpringNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat restLength, cpFloat stiffness, cpFloat damping);++CP_DefineConstraintProperty(cpDampedSpring, cpVect, anchr1, Anchr1);+CP_DefineConstraintProperty(cpDampedSpring, cpVect, anchr2, Anchr2);+CP_DefineConstraintProperty(cpDampedSpring, cpFloat, restLength, RestLength);+CP_DefineConstraintProperty(cpDampedSpring, cpFloat, stiffness, Stiffness);+CP_DefineConstraintProperty(cpDampedSpring, cpFloat, damping, Damping);+CP_DefineConstraintProperty(cpDampedSpring, cpDampedSpringForceFunc, springForceFunc, SpringForceFunc);
+ Chipmunk-5.3.5/include/chipmunk/constraints/cpGearJoint.h view
@@ -0,0 +1,41 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */++const cpConstraintClass *cpGearJointGetClass();++typedef struct cpGearJoint {+	cpConstraint constraint;+	cpFloat phase, ratio;+	cpFloat ratio_inv;+	+	cpFloat iSum;+		+	cpFloat bias;+	cpFloat jAcc, jMax;+} cpGearJoint;++cpGearJoint *cpGearJointAlloc(void);+cpGearJoint *cpGearJointInit(cpGearJoint *joint, cpBody *a, cpBody *b, cpFloat phase, cpFloat ratio);+cpConstraint *cpGearJointNew(cpBody *a, cpBody *b, cpFloat phase, cpFloat ratio);++CP_DefineConstraintProperty(cpGearJoint, cpFloat, phase, Phase);+CP_DefineConstraintGetter(cpGearJoint, cpFloat, ratio, Ratio);+void cpGearJointSetRatio(cpConstraint *constraint, cpFloat value);
+ Chipmunk-5.3.5/include/chipmunk/constraints/cpGrooveJoint.h view
@@ -0,0 +1,48 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */++const cpConstraintClass *cpGrooveJointGetClass();++typedef struct cpGrooveJoint {+	cpConstraint constraint;+	cpVect grv_n, grv_a, grv_b;+	cpVect  anchr2;+	+	cpVect grv_tn;+	cpFloat clamp;+	cpVect r1, r2;+	cpVect k1, k2;+	+	cpVect jAcc;+	cpFloat jMaxLen;+	cpVect bias;+} cpGrooveJoint;++cpGrooveJoint *cpGrooveJointAlloc(void);+cpGrooveJoint *cpGrooveJointInit(cpGrooveJoint *joint, cpBody *a, cpBody *b, cpVect groove_a, cpVect groove_b, cpVect anchr2);+cpConstraint *cpGrooveJointNew(cpBody *a, cpBody *b, cpVect groove_a, cpVect groove_b, cpVect anchr2);+++CP_DefineConstraintGetter(cpGrooveJoint, cpVect, grv_a, GrooveA);+void cpGrooveJointSetGrooveA(cpConstraint *constraint, cpVect value);+CP_DefineConstraintGetter(cpGrooveJoint, cpVect, grv_b, GrooveB);+void cpGrooveJointSetGrooveB(cpConstraint *constraint, cpVect value);+CP_DefineConstraintProperty(cpGrooveJoint, cpVect, anchr2, Anchr2);
+ Chipmunk-5.3.5/include/chipmunk/constraints/cpPinJoint.h view
@@ -0,0 +1,43 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */+ +const cpConstraintClass *cpPinJointGetClass();++typedef struct cpPinJoint {+	cpConstraint constraint;+	cpVect anchr1, anchr2;+	cpFloat dist;+	+	cpVect r1, r2;+	cpVect n;+	cpFloat nMass;+	+	cpFloat jnAcc, jnMax;+	cpFloat bias;+} cpPinJoint;++cpPinJoint *cpPinJointAlloc(void);+cpPinJoint *cpPinJointInit(cpPinJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2);+cpConstraint *cpPinJointNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2);++CP_DefineConstraintProperty(cpPinJoint, cpVect, anchr1, Anchr1);+CP_DefineConstraintProperty(cpPinJoint, cpVect, anchr2, Anchr2);+CP_DefineConstraintProperty(cpPinJoint, cpFloat, dist, Dist);
+ Chipmunk-5.3.5/include/chipmunk/constraints/cpPivotJoint.h view
@@ -0,0 +1,42 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */++const cpConstraintClass *cpPivotJointGetClass();++typedef struct cpPivotJoint {+	cpConstraint constraint;+	cpVect anchr1, anchr2;+	+	cpVect r1, r2;+	cpVect k1, k2;+	+	cpVect jAcc;+	cpFloat jMaxLen;+	cpVect bias;+} cpPivotJoint;++cpPivotJoint *cpPivotJointAlloc(void);+cpPivotJoint *cpPivotJointInit(cpPivotJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2);+cpConstraint *cpPivotJointNew(cpBody *a, cpBody *b, cpVect pivot);+cpConstraint *cpPivotJointNew2(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2);++CP_DefineConstraintProperty(cpPivotJoint, cpVect, anchr1, Anchr1);+CP_DefineConstraintProperty(cpPivotJoint, cpVect, anchr2, Anchr2);
+ Chipmunk-5.3.5/include/chipmunk/constraints/cpRatchetJoint.h view
@@ -0,0 +1,40 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */++const cpConstraintClass *cpRatchetJointGetClass();++typedef struct cpRatchetJoint {+	cpConstraint constraint;+	cpFloat angle, phase, ratchet;+	+	cpFloat iSum;+		+	cpFloat bias;+	cpFloat jAcc, jMax;+} cpRatchetJoint;++cpRatchetJoint *cpRatchetJointAlloc(void);+cpRatchetJoint *cpRatchetJointInit(cpRatchetJoint *joint, cpBody *a, cpBody *b, cpFloat phase, cpFloat ratchet);+cpConstraint *cpRatchetJointNew(cpBody *a, cpBody *b, cpFloat phase, cpFloat ratchet);++CP_DefineConstraintProperty(cpRatchetJoint, cpFloat, angle, Angle);+CP_DefineConstraintProperty(cpRatchetJoint, cpFloat, phase, Phase);+CP_DefineConstraintProperty(cpRatchetJoint, cpFloat, ratchet, Ratchet);
+ Chipmunk-5.3.5/include/chipmunk/constraints/cpRotaryLimitJoint.h view
@@ -0,0 +1,39 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */++const cpConstraintClass *cpRotaryLimitJointGetClass();++typedef struct cpRotaryLimitJoint {+	cpConstraint constraint;+	cpFloat min, max;+	+	cpFloat iSum;+		+	cpFloat bias;+	cpFloat jAcc, jMax;+} cpRotaryLimitJoint;++cpRotaryLimitJoint *cpRotaryLimitJointAlloc(void);+cpRotaryLimitJoint *cpRotaryLimitJointInit(cpRotaryLimitJoint *joint, cpBody *a, cpBody *b, cpFloat min, cpFloat max);+cpConstraint *cpRotaryLimitJointNew(cpBody *a, cpBody *b, cpFloat min, cpFloat max);++CP_DefineConstraintProperty(cpRotaryLimitJoint, cpFloat, min, Min);+CP_DefineConstraintProperty(cpRotaryLimitJoint, cpFloat, max, Max);
+ Chipmunk-5.3.5/include/chipmunk/constraints/cpSimpleMotor.h view
@@ -0,0 +1,37 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */++const cpConstraintClass *cpSimpleMotorGetClass();++typedef struct cpSimpleMotor {+	cpConstraint constraint;+	cpFloat rate;+	+	cpFloat iSum;+		+	cpFloat jAcc, jMax;+} cpSimpleMotor;++cpSimpleMotor *cpSimpleMotorAlloc(void);+cpSimpleMotor *cpSimpleMotorInit(cpSimpleMotor *joint, cpBody *a, cpBody *b, cpFloat rate);+cpConstraint *cpSimpleMotorNew(cpBody *a, cpBody *b, cpFloat rate);++CP_DefineConstraintProperty(cpSimpleMotor, cpFloat, rate, Rate);
+ Chipmunk-5.3.5/include/chipmunk/constraints/cpSlideJoint.h view
@@ -0,0 +1,44 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */++const cpConstraintClass *cpSlideJointGetClass();++typedef struct cpSlideJoint {+	cpConstraint constraint;+	cpVect anchr1, anchr2;+	cpFloat min, max;+	+	cpVect r1, r2;+	cpVect n;+	cpFloat nMass;+	+	cpFloat jnAcc, jnMax;+	cpFloat bias;+} cpSlideJoint;++cpSlideJoint *cpSlideJointAlloc(void);+cpSlideJoint *cpSlideJointInit(cpSlideJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max);+cpConstraint *cpSlideJointNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max);++CP_DefineConstraintProperty(cpSlideJoint, cpVect, anchr1, Anchr1);+CP_DefineConstraintProperty(cpSlideJoint, cpVect, anchr2, Anchr2);+CP_DefineConstraintProperty(cpSlideJoint, cpFloat, min, Min);+CP_DefineConstraintProperty(cpSlideJoint, cpFloat, max, Max);
+ Chipmunk-5.3.5/include/chipmunk/constraints/util.h view
@@ -0,0 +1,140 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */++#define CP_DefineClassGetter(t) const cpConstraintClass * t##GetClass(){return (cpConstraintClass *)&klass;}++void cpConstraintInit(cpConstraint *constraint, const cpConstraintClass *klass, cpBody *a, cpBody *b);++#define J_MAX(constraint, dt) (((cpConstraint *)constraint)->maxForce*(dt))++// Get valid body pointers and exit early if the bodies are idle+#define CONSTRAINT_BEGIN(constraint, a_var, b_var) \+cpBody *a_var, *b_var; { \+	a_var = ((cpConstraint *)constraint)->a; \+	b_var = ((cpConstraint *)constraint)->b; \+	if( \+		(cpBodyIsSleeping(a_var) || cpBodyIsStatic(a_var)) && \+		(cpBodyIsSleeping(b_var) || cpBodyIsStatic(b_var)) \+	) return; \+}++static inline cpVect+relative_velocity(cpBody *a, cpBody *b, cpVect r1, cpVect r2){+	cpVect v1_sum = cpvadd(a->v, cpvmult(cpvperp(r1), a->w));+	cpVect v2_sum = cpvadd(b->v, cpvmult(cpvperp(r2), b->w));+	+	return cpvsub(v2_sum, v1_sum);+}++static inline cpFloat+normal_relative_velocity(cpBody *a, cpBody *b, cpVect r1, cpVect r2, cpVect n){+	return cpvdot(relative_velocity(a, b, r1, r2), n);+}++static inline void+apply_impulse(cpBody *body, cpVect j, cpVect r){+	body->v = cpvadd(body->v, cpvmult(j, body->m_inv));+	body->w += body->i_inv*cpvcross(r, j);+}++static inline void+apply_impulses(cpBody *a , cpBody *b, cpVect r1, cpVect r2, cpVect j)+{+	apply_impulse(a, cpvneg(j), r1);+	apply_impulse(b, j, r2);+}++static inline void+apply_bias_impulse(cpBody *body, cpVect j, cpVect r)+{+	body->v_bias = cpvadd(body->v_bias, cpvmult(j, body->m_inv));+	body->w_bias += body->i_inv*cpvcross(r, j);+}++static inline void+apply_bias_impulses(cpBody *a , cpBody *b, cpVect r1, cpVect r2, cpVect j)+{+	apply_bias_impulse(a, cpvneg(j), r1);+	apply_bias_impulse(b, j, r2);+}++static inline cpVect+clamp_vect(cpVect v, cpFloat len)+{+	return cpvclamp(v, len);+//	return (cpvdot(v,v) > len*len) ? cpvmult(cpvnormalize(v), len) : v;+}++static inline cpFloat+k_scalar(cpBody *a, cpBody *b, cpVect r1, cpVect r2, cpVect n)+{+	cpFloat mass_sum = a->m_inv + b->m_inv;+	cpFloat r1cn = cpvcross(r1, n);+	cpFloat r2cn = cpvcross(r2, n);+	+	cpFloat value = mass_sum + a->i_inv*r1cn*r1cn + b->i_inv*r2cn*r2cn;+	cpAssert(value != 0.0, "Unsolvable collision or constraint.");+	+	return value;+}++static inline void+k_tensor(cpBody *a, cpBody *b, cpVect r1, cpVect r2, cpVect *k1, cpVect *k2)+{+	// calculate mass matrix+	// If I wasn't lazy and wrote a proper matrix class, this wouldn't be so gross...+	cpFloat k11, k12, k21, k22;+	cpFloat m_sum = a->m_inv + b->m_inv;+	+	// start with I*m_sum+	k11 = m_sum; k12 = 0.0f;+	k21 = 0.0f;  k22 = m_sum;+	+	// add the influence from r1+	cpFloat a_i_inv = a->i_inv;+	cpFloat r1xsq =  r1.x * r1.x * a_i_inv;+	cpFloat r1ysq =  r1.y * r1.y * a_i_inv;+	cpFloat r1nxy = -r1.x * r1.y * a_i_inv;+	k11 += r1ysq; k12 += r1nxy;+	k21 += r1nxy; k22 += r1xsq;+	+	// add the influnce from r2+	cpFloat b_i_inv = b->i_inv;+	cpFloat r2xsq =  r2.x * r2.x * b_i_inv;+	cpFloat r2ysq =  r2.y * r2.y * b_i_inv;+	cpFloat r2nxy = -r2.x * r2.y * b_i_inv;+	k11 += r2ysq; k12 += r2nxy;+	k21 += r2nxy; k22 += r2xsq;+	+	// invert+	cpFloat determinant = k11*k22 - k12*k21;+	cpAssert(determinant != 0.0, "Unsolvable constraint.");+	+	cpFloat det_inv = 1.0f/determinant;+	*k1 = cpv( k22*det_inv, -k12*det_inv);+	*k2 = cpv(-k21*det_inv,  k11*det_inv);+}++static inline cpVect+mult_k(cpVect vr, cpVect k1, cpVect k2)+{+	return cpv(cpvdot(vr, k1), cpvdot(vr, k2));+}
+ Chipmunk-5.3.5/include/chipmunk/cpArbiter.h view
@@ -0,0 +1,188 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */+ + struct cpArbiter;+ struct cpSpace;+ struct cpCollisionHandler;++// Determines how fast penetrations resolve themselves.+extern cpFloat cp_bias_coef;+// Amount of allowed penetration. Used to reduce vibrating contacts.+extern cpFloat cp_collision_slop;++// Data structure for contact points.+typedef struct cpContact {+	// Contact point and normal.+	cpVect CP_PRIVATE(p), CP_PRIVATE(n);+	// Penetration distance.+	CP_PRIVATE(cpFloat dist);+	+	// Calculated by cpArbiterPreStep().+	cpVect CP_PRIVATE(r1), CP_PRIVATE(r2);+	cpFloat CP_PRIVATE(nMass), CP_PRIVATE(tMass), CP_PRIVATE(bounce);++	// Persistant contact information.+	cpFloat CP_PRIVATE(jnAcc), CP_PRIVATE(jtAcc), CP_PRIVATE(jBias);+	CP_PRIVATE(cpFloat bias);+	+	// Hash value used to (mostly) uniquely identify a contact.+	CP_PRIVATE(cpHashValue hash);+} cpContact;++// Contacts are always allocated in groups.+cpContact* cpContactInit(cpContact *con, cpVect p, cpVect n, cpFloat dist, cpHashValue hash);++// Sum the contact impulses. (Can be used after cpSpaceStep() returns)+cpVect CP_PRIVATE(cpContactsSumImpulses)(cpContact *contacts, int numContacts);+cpVect CP_PRIVATE(cpContactsSumImpulsesWithFriction)(cpContact *contacts, int numContacts);++#define CP_MAX_CONTACTS_PER_ARBITER 6++typedef enum cpArbiterState {+	cpArbiterStateNormal,+	cpArbiterStateFirstColl,+	cpArbiterStateIgnore,+	cpArbiterStateSleep,+	cpArbiterStateCached,+} cpArbiterState;++// Data structure for tracking collisions between shapes.+typedef struct cpArbiter {+	// Information on the contact points between the objects.+	CP_PRIVATE(int numContacts);+	CP_PRIVATE(cpContact *contacts);+	+	// The two shapes and bodies involved in the collision.+	// These variables are NOT in the order defined by the collision handler.+	// Using CP_ARBITER_GET_SHAPES and CP_ARBITER_GET_BODIES will save you from+	// many headaches+	cpShape CP_PRIVATE(*a), CP_PRIVATE(*b);+	+	// Calculated before calling the pre-solve collision handler+	// Override them with custom values if you want specialized behavior+	CP_PRIVATE(cpFloat e);+	CP_PRIVATE(cpFloat u);+	 // Used for surface_v calculations, implementation may change+	CP_PRIVATE(cpVect surface_vr);+	+	// Time stamp of the arbiter. (from cpSpace)+	CP_PRIVATE(cpTimestamp stamp);+	+	CP_PRIVATE(struct cpCollisionHandler *handler);+	+	// Are the shapes swapped in relation to the collision handler?+	CP_PRIVATE(cpBool swappedColl);+	CP_PRIVATE(cpArbiterState state);+} cpArbiter;++// Arbiters are allocated in large buffers by the space and don't require a destroy function+cpArbiter* CP_PRIVATE(cpArbiterInit)(cpArbiter *arb, cpShape *a, cpShape *b);++// These functions are all intended to be used internally.+// Inject new contact points into the arbiter while preserving contact history.+void CP_PRIVATE(cpArbiterUpdate)(cpArbiter *arb, cpContact *contacts, int numContacts, struct cpCollisionHandler *handler, cpShape *a, cpShape *b);+// Precalculate values used by the solver.+void CP_PRIVATE(cpArbiterPreStep)(cpArbiter *arb, cpFloat dt_inv);+void CP_PRIVATE(cpArbiterApplyCachedImpulse)(cpArbiter *arb);+// Run an iteration of the solver on the arbiter.+void CP_PRIVATE(cpArbiterApplyImpulse)(cpArbiter *arb, cpFloat eCoef);++// Arbiter Helper Functions+cpVect cpArbiterTotalImpulse(cpArbiter *arb);+cpVect cpArbiterTotalImpulseWithFriction(cpArbiter *arb);+void cpArbiterIgnore(cpArbiter *arb);+++static inline void+cpArbiterGetShapes(const cpArbiter *arb, cpShape **a, cpShape **b)+{+	if(arb->CP_PRIVATE(swappedColl)){+		(*a) = arb->CP_PRIVATE(b), (*b) = arb->CP_PRIVATE(a);+	} else {+		(*a) = arb->CP_PRIVATE(a), (*b) = arb->CP_PRIVATE(b);+	}+}+#define CP_ARBITER_GET_SHAPES(arb, a, b) cpShape *a, *b; cpArbiterGetShapes(arb, &a, &b);++static inline void+cpArbiterGetBodies(const cpArbiter *arb, cpBody **a, cpBody **b)+{+	CP_ARBITER_GET_SHAPES(arb, shape_a, shape_b);+	(*a) = shape_a->body;+	(*b) = shape_b->body;+}+#define CP_ARBITER_GET_BODIES(arb, a, b) cpBody *a, *b; cpArbiterGetBodies(arb, &a, &b);++static inline cpBool+cpArbiterIsFirstContact(const cpArbiter *arb)+{+	return arb->CP_PRIVATE(state) == cpArbiterStateFirstColl;+}++static inline int+cpArbiterGetCount(const cpArbiter *arb)+{+	return arb->CP_PRIVATE(numContacts);+}++static inline cpVect+cpArbiterGetNormal(const cpArbiter *arb, int i)+{+	cpVect n = arb->CP_PRIVATE(contacts)[i].CP_PRIVATE(n);+	return arb->CP_PRIVATE(swappedColl) ? cpvneg(n) : n;+}++static inline cpVect+cpArbiterGetPoint(const cpArbiter *arb, int i)+{+	return arb->CP_PRIVATE(contacts)[i].CP_PRIVATE(p);+}++static inline cpFloat+cpArbiterGetDepth(const cpArbiter *arb, int i)+{+	return arb->CP_PRIVATE(contacts)[i].CP_PRIVATE(dist);+}++typedef struct cpContactPointSet {+	int count;+	+	struct {+		cpVect point, normal;+		cpFloat dist;+	} points[CP_MAX_CONTACTS_PER_ARBITER];+} cpContactPointSet;++static inline cpContactPointSet+cpArbiterGetContactPointSet(const cpArbiter *arb)+{+	cpContactPointSet set;+	set.count = cpArbiterGetCount(arb);+	+	int i;+	for(i=0; i<set.count; i++){+		set.points[i].point = arb->CP_PRIVATE(contacts)[i].CP_PRIVATE(p);+		set.points[i].normal = arb->CP_PRIVATE(contacts)[i].CP_PRIVATE(n);+		set.points[i].dist = arb->CP_PRIVATE(contacts)[i].CP_PRIVATE(dist);+	}+	+	return set;+}
+ Chipmunk-5.3.5/include/chipmunk/cpArray.h view
@@ -0,0 +1,49 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */+ +// NOTE: cpArray is rarely used and will probably go away.++typedef struct cpArray{+	CP_PRIVATE(int num);+	CP_PRIVATE(int max);+	CP_PRIVATE(void **arr);+} cpArray;++typedef void (*cpArrayIter)(void *ptr, void *data);++cpArray *cpArrayAlloc(void);+cpArray *cpArrayInit(cpArray *arr, int size);+cpArray *cpArrayNew(int size);++void cpArrayDestroy(cpArray *arr);+void cpArrayFree(cpArray *arr);++void cpArrayClear(cpArray *arr);++void cpArrayPush(cpArray *arr, void *object);+void *cpArrayPop(cpArray *arr);+void cpArrayDeleteIndex(cpArray *arr, int idx);+void cpArrayDeleteObj(cpArray *arr, void *obj);++void cpArrayAppend(cpArray *arr, cpArray *other);++void cpArrayEach(cpArray *arr, cpArrayIter iterFunc, void *data);+cpBool cpArrayContains(cpArray *arr, void *ptr);
+ Chipmunk-5.3.5/include/chipmunk/cpBB.h view
@@ -0,0 +1,74 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */+ +typedef struct cpBB{+	cpFloat l, b, r ,t;+} cpBB;++static inline cpBB+cpBBNew(const cpFloat l, const cpFloat b,+		const cpFloat r, const cpFloat t)+{+	cpBB bb = {l, b, r, t};+	return bb;+}++static inline cpBool+cpBBintersects(const cpBB a, const cpBB b)+{+	return (a.l<=b.r && b.l<=a.r && a.b<=b.t && b.b<=a.t);+}++static inline cpBool+cpBBcontainsBB(const cpBB bb, const cpBB other)+{+	return (bb.l < other.l && bb.r > other.r && bb.b < other.b && bb.t > other.t);+}++static inline cpBool+cpBBcontainsVect(const cpBB bb, const cpVect v)+{+	return (bb.l < v.x && bb.r > v.x && bb.b < v.y && bb.t > v.y);+}++static inline cpBB+cpBBmerge(const cpBB a, const cpBB b){+	return cpBBNew(+		cpfmin(a.l, b.l),+		cpfmin(a.b, b.b),+		cpfmax(a.r, b.r),+		cpfmax(a.t, b.t)+	);+}++static inline cpBB+cpBBexpand(const cpBB bb, const cpVect v){+	return cpBBNew(+		cpfmin(bb.l, v.x),+		cpfmin(bb.b, v.y),+		cpfmax(bb.r, v.x),+		cpfmax(bb.t, v.y)+	);+}++cpVect cpBBClampVect(const cpBB bb, const cpVect v); // clamps the vector to lie within the bbox+// TODO edge case issue+cpVect cpBBWrapVect(const cpBB bb, const cpVect v); // wrap a vector to a bbox
+ Chipmunk-5.3.5/include/chipmunk/cpBody.h view
@@ -0,0 +1,213 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */++struct cpBody;+struct cpShape;+struct cpSpace;++typedef void (*cpBodyVelocityFunc)(struct cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt);+typedef void (*cpBodyPositionFunc)(struct cpBody *body, cpFloat dt);++extern cpBodyVelocityFunc cpBodyUpdateVelocityDefault;+extern cpBodyPositionFunc cpBodyUpdatePositionDefault;++// Structure to hold information about the contact graph components+// when putting groups of objects to sleep.+// No interesting user accessible fields.+typedef struct cpComponentNode {+	struct cpBody *parent;+	struct cpBody *next;+	int rank;+	cpFloat idleTime;+} cpComponentNode;++typedef struct cpBody{+	// *** Integration Functions.++	// Function that is called to integrate the body's velocity. (Defaults to cpBodyUpdateVelocity)+	cpBodyVelocityFunc velocity_func;+	+	// Function that is called to integrate the body's position. (Defaults to cpBodyUpdatePosition)+	cpBodyPositionFunc position_func;+	+	// *** Mass Properties+	+	// Mass and it's inverse.+	// Always use cpBodySetMass() whenever changing the mass as these values must agree.+	cpFloat m, m_inv;+	+	// Moment of inertia and it's inverse.+	// Always use cpBodySetMoment() whenever changing the moment as these values must agree.+	cpFloat i, i_inv;+	+	// *** Positional Properties+	+	// Linear components of motion (position, velocity, and force)+	cpVect p, v, f;+	+	// Angular components of motion (angle, angular velocity, and torque)+	// Always use cpBodySetAngle() to set the angle of the body as a and rot must agree.+	cpFloat a, w, t;+	+	// Cached unit length vector representing the angle of the body.+	// Used for fast vector rotation using cpvrotate().+	cpVect rot;+	+	// *** User Definable Fields+	+	// User defined data pointer.+	cpDataPointer data;+	+	// *** Other Fields+	+	// Maximum velocities this body can move at after integrating velocity+	cpFloat v_limit, w_limit;+	+	// *** Internally Used Fields+	+	// Velocity bias values used when solving penetrations and correcting constraints.+	CP_PRIVATE(cpVect v_bias);+	CP_PRIVATE(cpFloat w_bias);+	+	// Space this body has been added to+	CP_PRIVATE(struct cpSpace *space);+	+	// Pointer to the shape list.+	// Shapes form a linked list using cpShape.next when added to a space.+	CP_PRIVATE(struct cpShape *shapesList);+	+	// Used by cpSpaceStep() to store contact graph information.+	CP_PRIVATE(cpComponentNode node);+} cpBody;++// Basic allocation/destruction functions+cpBody *cpBodyAlloc(void);+cpBody *cpBodyInit(cpBody *body, cpFloat m, cpFloat i);+cpBody *cpBodyNew(cpFloat m, cpFloat i);++cpBody *cpBodyInitStatic(cpBody *body);+cpBody *cpBodyNewStatic();++void cpBodyDestroy(cpBody *body);+void cpBodyFree(cpBody *body);++// Wake up a sleeping or idle body. (defined in cpSpace.c)+void cpBodyActivate(cpBody *body);++// Force a body to sleep;+// defined in cpSpaceComponent.c+void cpBodySleep(cpBody *body);+void cpBodySleepWithGroup(cpBody *body, cpBody *group);++static inline cpBool+cpBodyIsSleeping(const cpBody *body)+{+	return (CP_PRIVATE(body->node).next != ((cpBody*)0));+}++static inline cpBool+cpBodyIsStatic(const cpBody *body)+{+	return CP_PRIVATE(body->node).idleTime == INFINITY;+}++static inline cpBool+cpBodyIsRogue(const cpBody *body)+{+	return (body->CP_PRIVATE(space) == ((struct cpSpace*)0));+}+++#define CP_DefineBodyGetter(type, member, name) \+static inline type cpBodyGet##name(const cpBody *body){return body->member;}++#define CP_DefineBodySetter(type, member, name) \+static inline void \+cpBodySet##name(cpBody *body, const type value){ \+	cpBodyActivate(body); \+	body->member = value; \+} \++#define CP_DefineBodyProperty(type, member, name) \+CP_DefineBodyGetter(type, member, name) \+CP_DefineBodySetter(type, member, name)+++// Accessors for cpBody struct members+CP_DefineBodyGetter(cpFloat, m, Mass);+void cpBodySetMass(cpBody *body, cpFloat m);++CP_DefineBodyGetter(cpFloat, i, Moment);+void cpBodySetMoment(cpBody *body, cpFloat i);+++CP_DefineBodyProperty(cpVect, p, Pos);+CP_DefineBodyProperty(cpVect, v, Vel);+CP_DefineBodyProperty(cpVect, f, Force);+CP_DefineBodyGetter(cpFloat, a, Angle);+void cpBodySetAngle(cpBody *body, cpFloat a);+CP_DefineBodyProperty(cpFloat, w, AngVel);+CP_DefineBodyProperty(cpFloat, t, Torque);+CP_DefineBodyGetter(cpVect, rot, Rot);+CP_DefineBodyProperty(cpFloat, v_limit, VelLimit);+CP_DefineBodyProperty(cpFloat, w_limit, AngVelLimit);++//  Modify the velocity of the body so that it will move to the specified absolute coordinates in the next timestep.+// Intended for objects that are moved manually with a custom velocity integration function.+void cpBodySlew(cpBody *body, cpVect pos, cpFloat dt);++// Default Integration functions.+void cpBodyUpdateVelocity(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt);+void cpBodyUpdatePosition(cpBody *body, cpFloat dt);++// Convert body local to world coordinates+static inline cpVect+cpBodyLocal2World(const cpBody *body, const cpVect v)+{+	return cpvadd(body->p, cpvrotate(v, body->rot));+}++// Convert world to body local coordinates+static inline cpVect+cpBodyWorld2Local(const cpBody *body, const cpVect v)+{+	return cpvunrotate(cpvsub(v, body->p), body->rot);+}++// Zero the forces on a body.+void cpBodyResetForces(cpBody *body);+// Apply a force (in world coordinates) to a body at a point relative to the center of gravity (also in world coordinates).+void cpBodyApplyForce(cpBody *body, const cpVect f, const cpVect r);+// Apply an impulse (in world coordinates) to the body at a point relative to the center of gravity (also in world coordinates).+void cpBodyApplyImpulse(cpBody *body, const cpVect j, const cpVect r);++static inline cpFloat+cpBodyKineticEnergy(const cpBody *body)+{+	// Need to do some fudging to avoid NaNs+	cpFloat vsq = cpvdot(body->v, body->v);+	cpFloat wsq = body->w*body->w;+	return (vsq ? vsq*body->m : 0.0f) + (wsq ? wsq*body->i : 0.0f);+}++// Apply a damped spring force between two bodies.+// Warning: Large damping values can be unstable. Use a cpDampedSpring constraint for this instead.+void cpApplyDampedSpring(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat rlen, cpFloat k, cpFloat dmp, cpFloat dt);
+ Chipmunk-5.3.5/include/chipmunk/cpCollision.h view
@@ -0,0 +1,28 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */++//TODO delete this header?++// Collides two cpShape structures.+// Returns the number of contact points added to arr+// which should be at least CP_MAX_CONTACTS_PER_ARBITER in length.+// This function is very lonely in this header :(+int cpCollideShapes(const cpShape *a, const cpShape *b, cpContact *arr);
+ Chipmunk-5.3.5/include/chipmunk/cpHashSet.h view
@@ -0,0 +1,82 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */+ +// cpHashSet uses a chained hashtable implementation.+// Other than the transformation functions, there is nothing fancy going on.++// cpHashSetBin's form the linked lists in the chained hash table.+typedef struct cpHashSetBin {+	// Pointer to the element.+	CP_PRIVATE(void *elt);+	// Hash value of the element.+	CP_PRIVATE(cpHashValue hash);+	// Next element in the chain.+	CP_PRIVATE(struct cpHashSetBin *next);+} cpHashSetBin;++// Equality function. Returns true if ptr is equal to elt.+typedef cpBool (*cpHashSetEqlFunc)(void *ptr, void *elt);+// Used by cpHashSetInsert(). Called to transform the ptr into an element.+typedef void *(*cpHashSetTransFunc)(void *ptr, void *data);++typedef struct cpHashSet {+	// Number of elements stored in the table.+	CP_PRIVATE(int entries);+	// Number of cells in the table.+	CP_PRIVATE(int size);+	+	CP_PRIVATE(cpHashSetEqlFunc eql);+	CP_PRIVATE(cpHashSetTransFunc trans);+	+	// Default value returned by cpHashSetFind() when no element is found.+	// Defaults to NULL.+	CP_PRIVATE(void *default_value);+	+	// The table and recycled bins+	CP_PRIVATE(cpHashSetBin **table);+	CP_PRIVATE(cpHashSetBin *pooledBins);+	+	CP_PRIVATE(cpArray *allocatedBuffers);+} cpHashSet;++// Basic allocation/destruction functions.+void cpHashSetDestroy(cpHashSet *set);+void cpHashSetFree(cpHashSet *set);++cpHashSet *cpHashSetAlloc(void);+cpHashSet *cpHashSetInit(cpHashSet *set, int size, cpHashSetEqlFunc eqlFunc, cpHashSetTransFunc trans);+cpHashSet *cpHashSetNew(int size, cpHashSetEqlFunc eqlFunc, cpHashSetTransFunc trans);++// Insert an element into the set, returns the element.+// If it doesn't already exist, the transformation function is applied.+void *cpHashSetInsert(cpHashSet *set, cpHashValue hash, void *ptr, void *data);+// Remove and return an element from the set.+void *cpHashSetRemove(cpHashSet *set, cpHashValue hash, void *ptr);+// Find an element in the set. Returns the default value if the element isn't found.+void *cpHashSetFind(cpHashSet *set, cpHashValue hash, void *ptr);++// Iterate over a hashset.+typedef void (*cpHashSetIterFunc)(void *elt, void *data);+void cpHashSetEach(cpHashSet *set, cpHashSetIterFunc func, void *data);++// Iterate over a hashset, drop the element if the func returns false.+typedef cpBool (*cpHashSetFilterFunc)(void *elt, void *data);+void cpHashSetFilter(cpHashSet *set, cpHashSetFilterFunc func, void *data);
+ Chipmunk-5.3.5/include/chipmunk/cpPolyShape.h view
@@ -0,0 +1,103 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */++// Axis structure used by cpPolyShape.+typedef struct cpPolyShapeAxis{+	// normal+	cpVect n;+	// distance from origin+	cpFloat d;+} cpPolyShapeAxis;++// Convex polygon shape structure.+typedef struct cpPolyShape{+	cpShape shape;+	+	// Vertex and axis lists.+	CP_PRIVATE(int numVerts);+	CP_PRIVATE(cpVect *verts);+	CP_PRIVATE(cpPolyShapeAxis *axes);++	// Transformed vertex and axis lists.+	CP_PRIVATE(cpVect *tVerts);+	CP_PRIVATE(cpPolyShapeAxis *tAxes);+} cpPolyShape;++// Basic allocation functions.+cpPolyShape *cpPolyShapeAlloc(void);+cpPolyShape *cpPolyShapeInit(cpPolyShape *poly, cpBody *body, int numVerts, cpVect *verts, cpVect offset);+cpShape *cpPolyShapeNew(cpBody *body, int numVerts, cpVect *verts, cpVect offset);++cpPolyShape *cpBoxShapeInit(cpPolyShape *poly, cpBody *body, cpFloat width, cpFloat height);+cpShape *cpBoxShapeNew(cpBody *body, cpFloat width, cpFloat height);++// Check that a set of vertexes has a correct winding and that they are convex+cpBool cpPolyValidate(const cpVect *verts, const int numVerts);++int cpPolyShapeGetNumVerts(cpShape *shape);+cpVect cpPolyShapeGetVert(cpShape *shape, int idx);++// *** inlined utility functions++// Returns the minimum distance of the polygon to the axis.+static inline cpFloat+cpPolyShapeValueOnAxis(const cpPolyShape *poly, const cpVect n, const cpFloat d)+{+	cpVect *verts = poly->CP_PRIVATE(tVerts);+	cpFloat min = cpvdot(n, verts[0]);+	+	int i;+	for(i=1; i<poly->CP_PRIVATE(numVerts); i++)+		min = cpfmin(min, cpvdot(n, verts[i]));+	+	return min - d;+}++// Returns true if the polygon contains the vertex.+static inline cpBool+cpPolyShapeContainsVert(const cpPolyShape *poly, const cpVect v)+{+	cpPolyShapeAxis *axes = poly->CP_PRIVATE(tAxes);+	+	int i;+	for(i=0; i<poly->CP_PRIVATE(numVerts); i++){+		cpFloat dist = cpvdot(axes[i].n, v) - axes[i].d;+		if(dist > 0.0f) return cpFalse;+	}+	+	return cpTrue;+}++// Same as cpPolyShapeContainsVert() but ignores faces pointing away from the normal.+static inline cpBool+cpPolyShapeContainsVertPartial(const cpPolyShape *poly, const cpVect v, const cpVect n)+{+	cpPolyShapeAxis *axes = poly->CP_PRIVATE(tAxes);+	+	int i;+	for(i=0; i<poly->CP_PRIVATE(numVerts); i++){+		if(cpvdot(axes[i].n, n) < 0.0f) continue;+		cpFloat dist = cpvdot(axes[i].n, v) - axes[i].d;+		if(dist > 0.0f) return cpFalse;+	}+	+	return cpTrue;+}
+ Chipmunk-5.3.5/include/chipmunk/cpShape.h view
@@ -0,0 +1,177 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */+ +// Forward declarations required for defining other structs.+struct cpShape;+struct cpShapeClass;++typedef struct cpSegmentQueryInfo {+	struct cpShape *shape; // shape that was hit, NULL if no collision+	cpFloat t; // Distance along query segment, will always be in the range [0, 1].+	cpVect n; // normal of hit surface+} cpSegmentQueryInfo;++// Enumeration of shape types.+typedef enum cpShapeType{+	CP_CIRCLE_SHAPE,+	CP_SEGMENT_SHAPE,+	CP_POLY_SHAPE,+	CP_NUM_SHAPES+} cpShapeType;++// Shape class. Holds function pointers and type data.+typedef struct cpShapeClass {+	cpShapeType type;+	+	// Called by cpShapeCacheBB().+	cpBB (*cacheData)(struct cpShape *shape, cpVect p, cpVect rot);+	// Called to by cpShapeDestroy().+	void (*destroy)(struct cpShape *shape);+	+	// called by cpShapePointQuery().+	cpBool (*pointQuery)(struct cpShape *shape, cpVect p);+	+	// called by cpShapeSegmentQuery()+	 void (*segmentQuery)(struct cpShape *shape, cpVect a, cpVect b, cpSegmentQueryInfo *info);+} cpShapeClass;++// Basic shape struct that the others inherit from.+typedef struct cpShape{+	// The "class" of a shape as defined above +	CP_PRIVATE(const cpShapeClass *klass);+	+	// cpBody that the shape is attached to.+	cpBody *body;++	// Cached BBox for the shape.+	cpBB bb;+	+	// Sensors invoke callbacks, but do not generate collisions+	cpBool sensor;+	+	// *** Surface properties.+	+	// Coefficient of restitution. (elasticity)+	cpFloat e;+	// Coefficient of friction.+	cpFloat u;+	// Surface velocity used when solving for friction.+	cpVect surface_v;++	// *** User Definable Fields++	// User defined data pointer for the shape.+	cpDataPointer data;+	+	// User defined collision type for the shape.+	cpCollisionType collision_type;+	// User defined collision group for the shape.+	cpGroup group;+	// User defined layer bitmask for the shape.+	cpLayers layers;+	+	// *** Internally Used Fields+	+	// Shapes form a linked list when added to space on a non-NULL body+	CP_PRIVATE(struct cpShape *next);+	+	// Unique id used as the hash value.+	CP_PRIVATE(cpHashValue hashid);+} cpShape;++// Low level shape initialization func.+cpShape* cpShapeInit(cpShape *shape, const struct cpShapeClass *klass, cpBody *body);++// Basic destructor functions. (allocation functions are not shared)+void cpShapeDestroy(cpShape *shape);+void cpShapeFree(cpShape *shape);++// Cache the BBox of the shape.+cpBB cpShapeCacheBB(cpShape *shape);++// Test if a point lies within a shape.+cpBool cpShapePointQuery(cpShape *shape, cpVect p);++#define CP_DeclareShapeGetter(struct, type, name) type struct##Get##name(cpShape *shape)++// Circle shape structure.+typedef struct cpCircleShape{+	cpShape shape;+	+	// Center in body space coordinates+	CP_PRIVATE(cpVect c);+	// Radius.+	CP_PRIVATE(cpFloat r);+	+	// Transformed center. (world space coordinates)+	CP_PRIVATE(cpVect tc);+} cpCircleShape;++// Basic allocation functions for cpCircleShape.+cpCircleShape *cpCircleShapeAlloc(void);+cpCircleShape *cpCircleShapeInit(cpCircleShape *circle, cpBody *body, cpFloat radius, cpVect offset);+cpShape *cpCircleShapeNew(cpBody *body, cpFloat radius, cpVect offset);++CP_DeclareShapeGetter(cpCircleShape, cpVect, Offset);+CP_DeclareShapeGetter(cpCircleShape, cpFloat, Radius);++// Segment shape structure.+typedef struct cpSegmentShape{+	cpShape shape;+	+	// Endpoints and normal of the segment. (body space coordinates)+	cpVect CP_PRIVATE(a), CP_PRIVATE(b), CP_PRIVATE(n);+	// Radius of the segment. (Thickness)+	cpFloat CP_PRIVATE(r);++	// Transformed endpoints and normal. (world space coordinates)+	cpVect CP_PRIVATE(ta), CP_PRIVATE(tb), CP_PRIVATE(tn);+} cpSegmentShape;++// Basic allocation functions for cpSegmentShape.+cpSegmentShape* cpSegmentShapeAlloc(void);+cpSegmentShape* cpSegmentShapeInit(cpSegmentShape *seg, cpBody *body, cpVect a, cpVect b, cpFloat radius);+cpShape* cpSegmentShapeNew(cpBody *body, cpVect a, cpVect b, cpFloat radius);++CP_DeclareShapeGetter(cpSegmentShape, cpVect, A);+CP_DeclareShapeGetter(cpSegmentShape, cpVect, B);+CP_DeclareShapeGetter(cpSegmentShape, cpVect, Normal);+CP_DeclareShapeGetter(cpSegmentShape, cpFloat, Radius);++// For determinism, you can reset the shape id counter.+void cpResetShapeIdCounter(void);++// Directed segment queries against individual shapes.+void cpSegmentQueryInfoPrint(cpSegmentQueryInfo *info);++cpBool cpShapeSegmentQuery(cpShape *shape, cpVect a, cpVect b, cpSegmentQueryInfo *info);++static inline cpVect+cpSegmentQueryHitPoint(const cpVect start, const cpVect end, const cpSegmentQueryInfo info)+{+	return cpvlerp(start, end, info.t);+}++static inline cpFloat+cpSegmentQueryHitDist(const cpVect start, const cpVect end, const cpSegmentQueryInfo info)+{+	return cpvdist(start, end)*info.t;+}
+ Chipmunk-5.3.5/include/chipmunk/cpSpace.h view
@@ -0,0 +1,208 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */++struct cpSpace;++// Number of frames that contact information should persist.+extern cpTimestamp cp_contact_persistence;++// User collision handler function types.+typedef cpBool (*cpCollisionBeginFunc)(cpArbiter *arb, struct cpSpace *space, void *data);+typedef cpBool (*cpCollisionPreSolveFunc)(cpArbiter *arb, struct cpSpace *space, void *data);+typedef void (*cpCollisionPostSolveFunc)(cpArbiter *arb, struct cpSpace *space, void *data);+typedef void (*cpCollisionSeparateFunc)(cpArbiter *arb, struct cpSpace *space, void *data);++// Structure for holding collision pair function information.+// Used internally.+typedef struct cpCollisionHandler {+	cpCollisionType a;+	cpCollisionType b;+	cpCollisionBeginFunc begin;+	cpCollisionPreSolveFunc preSolve;+	cpCollisionPostSolveFunc postSolve;+	cpCollisionSeparateFunc separate;+	void *data;+} cpCollisionHandler;++extern cpCollisionHandler cpSpaceDefaultHandler;++typedef struct cpContactBufferHeader {+	cpTimestamp stamp;+	struct cpContactBufferHeader *next;+	unsigned int numContacts;+} cpContactBufferHeader;++typedef struct cpSpace{+	// *** User definable fields+	+	// Number of iterations to use in the impulse solver to solve contacts.+	int iterations;+	+	// Number of iterations to use in the impulse solver to solve elastic collisions.+	int elasticIterations;+	+	// Default gravity to supply when integrating rigid body motions.+	cpVect gravity;+	+	// Default damping to supply when integrating rigid body motions.+	cpFloat damping;+	+	// Speed threshold for a body to be considered idle.+	// The default value of 0 means to let the space guess a good threshold based on gravity.+	cpFloat idleSpeedThreshold;+	+	// Time a group of bodies must remain idle in order to fall asleep+	// The default value of INFINITY disables the sleeping algorithm.+	cpFloat sleepTimeThreshold;+	+	// *** Internally Used Fields+	+	// When the space lock count is non zero you cannot add or remove objects+	CP_PRIVATE(int locked);+	+	// Time stamp. Is incremented on every call to cpSpaceStep().+	CP_PRIVATE(cpTimestamp stamp);++	// The static and active shape spatial hashes.+	CP_PRIVATE(cpSpaceHash *staticShapes);+	CP_PRIVATE(cpSpaceHash *activeShapes);+	+	// List of bodies in the system.+	CP_PRIVATE(cpArray *bodies);+	+	// List of groups of sleeping bodies.+	CP_PRIVATE(cpArray *sleepingComponents);+	+	// List of bodies that have been flagged to be awoken.+	CP_PRIVATE(cpArray *rousedBodies);+	+	// List of active arbiters for the impulse solver.+	CP_PRIVATE(cpArray *arbiters);+	CP_PRIVATE(cpArray *pooledArbiters);+	+	// Linked list ring of contact buffers.+	// Head is the newest buffer, and each buffer points to a newer buffer.+	// Head wraps around and points to the oldest (tail) buffer.+	CP_PRIVATE(cpContactBufferHeader *contactBuffersHead);+	CP_PRIVATE(cpContactBufferHeader *_contactBuffersTail_Deprecated);+	+	// List of buffers to be free()ed when destroying the space.+	CP_PRIVATE(cpArray *allocatedBuffers);+	+	// Persistant contact set.+	CP_PRIVATE(cpHashSet *contactSet);+	+	// List of constraints in the system.+	CP_PRIVATE(cpArray *constraints);+	+	// Set of collisionpair functions.+	CP_PRIVATE(cpHashSet *collFuncSet);+	// Default collision handler.+	CP_PRIVATE(cpCollisionHandler defaultHandler);+	+	CP_PRIVATE(cpHashSet *postStepCallbacks);+	+	cpBody staticBody;+} cpSpace;++// Basic allocation/destruction functions.+cpSpace* cpSpaceAlloc(void);+cpSpace* cpSpaceInit(cpSpace *space);+cpSpace* cpSpaceNew(void);++void cpSpaceDestroy(cpSpace *space);+void cpSpaceFree(cpSpace *space);++// Convenience function. Frees all referenced entities. (bodies, shapes and constraints)+void cpSpaceFreeChildren(cpSpace *space);++// Collision handler management functions.+void cpSpaceSetDefaultCollisionHandler(+	cpSpace *space,+	cpCollisionBeginFunc begin,+	cpCollisionPreSolveFunc preSolve,+	cpCollisionPostSolveFunc postSolve,+	cpCollisionSeparateFunc separate,+	void *data+);+void cpSpaceAddCollisionHandler(+	cpSpace *space,+	cpCollisionType a, cpCollisionType b,+	cpCollisionBeginFunc begin,+	cpCollisionPreSolveFunc preSolve,+	cpCollisionPostSolveFunc postSolve,+	cpCollisionSeparateFunc separate,+	void *data+);+void cpSpaceRemoveCollisionHandler(cpSpace *space, cpCollisionType a, cpCollisionType b);++// Add and remove entities from the system.+cpShape *cpSpaceAddShape(cpSpace *space, cpShape *shape);+cpShape *cpSpaceAddStaticShape(cpSpace *space, cpShape *shape);+cpBody *cpSpaceAddBody(cpSpace *space, cpBody *body);+cpConstraint *cpSpaceAddConstraint(cpSpace *space, cpConstraint *constraint);++void cpSpaceRemoveShape(cpSpace *space, cpShape *shape);+void cpSpaceRemoveStaticShape(cpSpace *space, cpShape *shape);+void cpSpaceRemoveBody(cpSpace *space, cpBody *body);+void cpSpaceRemoveConstraint(cpSpace *space, cpConstraint *constraint);++// Post Step function definition+typedef void (*cpPostStepFunc)(cpSpace *space, void *obj, void *data);+// Register a post step function to be called after cpSpaceStep() has finished.+// obj is used a key, you can only register one callback per unique value for obj+void cpSpaceAddPostStepCallback(cpSpace *space, cpPostStepFunc func, void *obj, void *data);++// Point query callback function+typedef void (*cpSpacePointQueryFunc)(cpShape *shape, void *data);+void cpSpacePointQuery(cpSpace *space, cpVect point, cpLayers layers, cpGroup group, cpSpacePointQueryFunc func, void *data);+cpShape *cpSpacePointQueryFirst(cpSpace *space, cpVect point, cpLayers layers, cpGroup group);++// Segment query callback function+typedef void (*cpSpaceSegmentQueryFunc)(cpShape *shape, cpFloat t, cpVect n, void *data);+void cpSpaceSegmentQuery(cpSpace *space, cpVect start, cpVect end, cpLayers layers, cpGroup group, cpSpaceSegmentQueryFunc func, void *data);+cpShape *cpSpaceSegmentQueryFirst(cpSpace *space, cpVect start, cpVect end, cpLayers layers, cpGroup group, cpSegmentQueryInfo *out);++// BB query callback function+typedef void (*cpSpaceBBQueryFunc)(cpShape *shape, void *data);+void cpSpaceBBQuery(cpSpace *space, cpBB bb, cpLayers layers, cpGroup group, cpSpaceBBQueryFunc func, void *data);++// Shape query callback function+typedef void (*cpSpaceShapeQueryFunc)(cpShape *shape, cpContactPointSet *points, void *data);+cpBool cpSpaceShapeQuery(cpSpace *space, cpShape *shape, cpSpaceShapeQueryFunc func, void *data);+++void cpSpaceActivateShapesTouchingShape(cpSpace *space, cpShape *shape);+++// Iterator function for iterating the bodies in a space.+typedef void (*cpSpaceBodyIterator)(cpBody *body, void *data);+void cpSpaceEachBody(cpSpace *space, cpSpaceBodyIterator func, void *data);++// Spatial hash management functions.+void cpSpaceResizeStaticHash(cpSpace *space, cpFloat dim, int count);+void cpSpaceResizeActiveHash(cpSpace *space, cpFloat dim, int count);+void cpSpaceRehashStatic(cpSpace *space);++void cpSpaceRehashShape(cpSpace *space, cpShape *shape);++// Update the space.+void cpSpaceStep(cpSpace *space, cpFloat dt);
+ Chipmunk-5.3.5/include/chipmunk/cpSpaceHash.h view
@@ -0,0 +1,110 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */++// The spatial hash is Chipmunk's default (and currently only) spatial index type.+// Based on a chained hash table.++// Used internally to track objects added to the hash+typedef struct cpHandle{+	// Pointer to the object+	void *obj;+	// Retain count+	int retain;+	// Query stamp. Used to make sure two objects+	// aren't identified twice in the same query.+	cpTimestamp stamp;+} cpHandle;++// Linked list element for in the chains.+typedef struct cpSpaceHashBin{+	cpHandle *handle;+	struct cpSpaceHashBin *next;+} cpSpaceHashBin;++// BBox callback. Called whenever the hash needs a bounding box from an object.+typedef cpBB (*cpSpaceHashBBFunc)(void *obj);++typedef struct cpSpaceHash{+	// Number of cells in the table.+	CP_PRIVATE(int numcells);+	// Dimentions of the cells.+	CP_PRIVATE(cpFloat celldim);+	+	// BBox callback.+	CP_PRIVATE(cpSpaceHashBBFunc bbfunc);++	// Hashset of the handles and the recycled ones.+	CP_PRIVATE(cpHashSet *handleSet);+	CP_PRIVATE(cpArray *pooledHandles);+	+	// The table and the recycled bins.+	CP_PRIVATE(cpSpaceHashBin **table);+	CP_PRIVATE(cpSpaceHashBin *pooledBins);+	+	// list of buffers to free on destruction.+	CP_PRIVATE(cpArray *allocatedBuffers);+	+	// Incremented on each query. See cpHandle.stamp.+	CP_PRIVATE(cpTimestamp stamp);+} cpSpaceHash;++//Basic allocation/destruction functions.+cpSpaceHash *cpSpaceHashAlloc(void);+cpSpaceHash *cpSpaceHashInit(cpSpaceHash *hash, cpFloat celldim, int cells, cpSpaceHashBBFunc bbfunc);+cpSpaceHash *cpSpaceHashNew(cpFloat celldim, int cells, cpSpaceHashBBFunc bbfunc);++void cpSpaceHashDestroy(cpSpaceHash *hash);+void cpSpaceHashFree(cpSpaceHash *hash);++// Resize the hashtable. (Does not rehash! You must call cpSpaceHashRehash() if needed.)+void cpSpaceHashResize(cpSpaceHash *hash, cpFloat celldim, int numcells);++// Add an object to the hash.+void cpSpaceHashInsert(cpSpaceHash *hash, void *obj, cpHashValue id, cpBB _deprecated_ignored);+// Remove an object from the hash.+void cpSpaceHashRemove(cpSpaceHash *hash, void *obj, cpHashValue id);++// Iterator function+typedef void (*cpSpaceHashIterator)(void *obj, void *data);+// Iterate over the objects in the hash.+void cpSpaceHashEach(cpSpaceHash *hash, cpSpaceHashIterator func, void *data);++// Rehash the contents of the hash.+void cpSpaceHashRehash(cpSpaceHash *hash);+// Rehash only a specific object.+void cpSpaceHashRehashObject(cpSpaceHash *hash, void *obj, cpHashValue id);++// Query callback.+typedef void (*cpSpaceHashQueryFunc)(void *obj1, void *obj2, void *data);+// Point query the hash. A reference to the query point is passed as obj1 to the query callback.+void cpSpaceHashPointQuery(cpSpaceHash *hash, cpVect point, cpSpaceHashQueryFunc func, void *data);+// Query the hash for a given BBox.+void cpSpaceHashQuery(cpSpaceHash *hash, void *obj, cpBB bb, cpSpaceHashQueryFunc func, void *data);+// Run a query for the object, then insert it. (Optimized case)+void cpSpaceHashQueryInsert(cpSpaceHash *hash, void *obj, cpBB bb, cpSpaceHashQueryFunc func, void *data);+// Rehashes while querying for each object. (Optimized case) +void cpSpaceHashQueryRehash(cpSpaceHash *hash, cpSpaceHashQueryFunc func, void *data);++// Segment Query callback.+// Return value is uesd for early exits of the query.+// If while traversing the grid, the raytrace function detects that an entire grid cell is beyond the hit point, it will stop the trace.+typedef cpFloat (*cpSpaceHashSegmentQueryFunc)(void *obj1, void *obj2, void *data);+void cpSpaceHashSegmentQuery(cpSpaceHash *hash, void *obj, cpVect a, cpVect b, cpFloat t_exit, cpSpaceHashSegmentQueryFunc func, void *data);
+ Chipmunk-5.3.5/include/chipmunk/cpVect.h view
@@ -0,0 +1,207 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */++/// Constant for the zero vector.+static const cpVect cpvzero = {0.0f,0.0f};++/// Convenience constructor for cpVect structs.+static inline cpVect+cpv(const cpFloat x, const cpFloat y)+{+	cpVect v = {x, y};+	return v;+}++// non-inlined functions++/// Returns the length of v.+cpFloat cpvlength(const cpVect v);++/// Spherical linearly interpolate between v1 and v2.+cpVect cpvslerp(const cpVect v1, const cpVect v2, const cpFloat t);++/// Spherical linearly interpolate between v1 towards v2 by no more than angle a radians+cpVect cpvslerpconst(const cpVect v1, const cpVect v2, const cpFloat a);++/// Returns the unit length vector for the given angle (in radians).+cpVect cpvforangle(const cpFloat a);++/// Returns the angular direction v is pointing in (in radians).+cpFloat cpvtoangle(const cpVect v);++/**+	Returns a string representation of v. Intended mostly for debugging purposes and not production use.+	+	@attention The string points to a static local and is reset every time the function is called.+	If you want to print more than one vector you will have to split up your printing onto separate lines.+*/+char *cpvstr(const cpVect v);++/// Check if two vectors are equal. (Be careful when comparing floating point numbers!)+static inline cpBool+cpveql(const cpVect v1, const cpVect v2)+{+	return (v1.x == v2.x && v1.y == v2.y);+}++/// Add two vectors+static inline cpVect+cpvadd(const cpVect v1, const cpVect v2)+{+	return cpv(v1.x + v2.x, v1.y + v2.y);+}++/// Negate a vector.+static inline cpVect+cpvneg(const cpVect v)+{+	return cpv(-v.x, -v.y);+}++/// Subtract two vectors.+static inline cpVect+cpvsub(const cpVect v1, const cpVect v2)+{+	return cpv(v1.x - v2.x, v1.y - v2.y);+}++/// Scalar multiplication.+static inline cpVect+cpvmult(const cpVect v, const cpFloat s)+{+	return cpv(v.x*s, v.y*s);+}++/// Vector dot product.+static inline cpFloat+cpvdot(const cpVect v1, const cpVect v2)+{+	return v1.x*v2.x + v1.y*v2.y;+}++/**+	2D vector cross product analog.+	The cross product of 2D vectors results in a 3D vector with only a z component.+	This function returns the magnitude of the z value.+*/+static inline cpFloat+cpvcross(const cpVect v1, const cpVect v2)+{+	return v1.x*v2.y - v1.y*v2.x;+}++/// Returns a perpendicular vector. (90 degree rotation)+static inline cpVect+cpvperp(const cpVect v)+{+	return cpv(-v.y, v.x);+}++/// Returns a perpendicular vector. (-90 degree rotation)+static inline cpVect+cpvrperp(const cpVect v)+{+	return cpv(v.y, -v.x);+}++/// Returns the vector projection of v1 onto v2.+static inline cpVect+cpvproject(const cpVect v1, const cpVect v2)+{+	return cpvmult(v2, cpvdot(v1, v2)/cpvdot(v2, v2));+}++/// Uses complex number multiplication to rotate v1 by v2. Scaling will occur if v1 is not a unit vector.+static inline cpVect+cpvrotate(const cpVect v1, const cpVect v2)+{+	return cpv(v1.x*v2.x - v1.y*v2.y, v1.x*v2.y + v1.y*v2.x);+}++/// Inverse of cpvrotate().+static inline cpVect+cpvunrotate(const cpVect v1, const cpVect v2)+{+	return cpv(v1.x*v2.x + v1.y*v2.y, v1.y*v2.x - v1.x*v2.y);+}++/// Returns the squared length of v. Faster than cpvlength() when you only need to compare lengths.+static inline cpFloat+cpvlengthsq(const cpVect v)+{+	return cpvdot(v, v);+}++/// Linearly interpolate between v1 and v2.+static inline cpVect+cpvlerp(const cpVect v1, const cpVect v2, const cpFloat t)+{+	return cpvadd(cpvmult(v1, 1.0f - t), cpvmult(v2, t));+}++/// Returns a normalized copy of v.+static inline cpVect+cpvnormalize(const cpVect v)+{+	return cpvmult(v, 1.0f/cpvlength(v));+}++/// Returns a normalized copy of v or cpvzero if v was already cpvzero. Protects against divide by zero errors.+static inline cpVect+cpvnormalize_safe(const cpVect v)+{+	return (v.x == 0.0f && v.y == 0.0f ? cpvzero : cpvnormalize(v));+}++/// Clamp v to length len.+static inline cpVect+cpvclamp(const cpVect v, const cpFloat len)+{+	return (cpvdot(v,v) > len*len) ? cpvmult(cpvnormalize(v), len) : v;+}++/// Linearly interpolate between v1 towards v2 by distance d.+static inline cpVect+cpvlerpconst(cpVect v1, cpVect v2, cpFloat d)+{+	return cpvadd(v1, cpvclamp(cpvsub(v2, v1), d));+}++/// Returns the distance between v1 and v2.+static inline cpFloat+cpvdist(const cpVect v1, const cpVect v2)+{+	return cpvlength(cpvsub(v1, v2));+}++/// Returns the squared distance between v1 and v2. Faster than cpvdist() when you only need to compare distances.+static inline cpFloat+cpvdistsq(const cpVect v1, const cpVect v2)+{+	return cpvlengthsq(cpvsub(v1, v2));+}++/// Returns true if the distance between v1 and v2 is less than dist.+static inline cpBool+cpvnear(const cpVect v1, const cpVect v2, const cpFloat dist)+{+	return cpvdistsq(v1, v2) < dist*dist;+}
+ Chipmunk-5.3.5/src/chipmunk.c view
@@ -0,0 +1,151 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */+ +#include <stdlib.h>+#include <stdio.h>+#define _USE_MATH_DEFINES+#include <math.h>++#include "chipmunk.h"++#ifdef __cplusplus+extern "C" {+#endif+	void cpInitCollisionFuncs(void);+#ifdef __cplusplus+}+#endif++void+cpMessage(const char *message, const char *condition, const char *file, int line, int isError)+{+	fprintf(stderr, (isError ? "Aborting due to Chipmunk error: %s\n" : "Chipmunk warning: %s\n"), message);+	fprintf(stderr, "\tFailed condition: %s\n", condition);+	fprintf(stderr, "\tSource:%s:%d\n", file, line);+	+	if(isError) abort();+}+++const char *cpVersionString = "5.3.5";++void+cpInitChipmunk(void)+{+#ifndef NDEBUG+	printf("Initializing Chipmunk v%s (Debug Enabled)\n", cpVersionString);+	printf("Compile with -DNDEBUG defined to disable debug mode and runtime assertion checks\n");+#endif+	+	cpInitCollisionFuncs();+}++cpFloat+cpMomentForCircle(cpFloat m, cpFloat r1, cpFloat r2, cpVect offset)+{+	return m*(0.5f*(r1*r1 + r2*r2) + cpvlengthsq(offset));+}++cpFloat+cpAreaForCircle(cpFloat r1, cpFloat r2)+{+	return 2.0f*(cpFloat)M_PI*cpfabs(r1*r1 - r2*r2);+}++cpFloat+cpMomentForSegment(cpFloat m, cpVect a, cpVect b)+{+	cpFloat length = cpvlength(cpvsub(b, a));+	cpVect offset = cpvmult(cpvadd(a, b), 1.0f/2.0f);+	+	return m*(length*length/12.0f + cpvlengthsq(offset));+}++cpFloat+cpAreaForSegment(cpVect a, cpVect b, cpFloat r)+{+	return 2.0f*r*((cpFloat)M_PI*r + cpvdist(a, b));+}++cpFloat+cpMomentForPoly(cpFloat m, const int numVerts, const cpVect *verts, cpVect offset)+{+	cpFloat sum1 = 0.0f;+	cpFloat sum2 = 0.0f;+	for(int i=0; i<numVerts; i++){+		cpVect v1 = cpvadd(verts[i], offset);+		cpVect v2 = cpvadd(verts[(i+1)%numVerts], offset);+		+		cpFloat a = cpvcross(v2, v1);+		cpFloat b = cpvdot(v1, v1) + cpvdot(v1, v2) + cpvdot(v2, v2);+		+		sum1 += a*b;+		sum2 += a;+	}+	+	return (m*sum1)/(6.0f*sum2);+}++cpFloat+cpAreaForPoly(const int numVerts, const cpVect *verts)+{+	cpFloat area = 0.0f;+	for(int i=0; i<numVerts; i++){+		area += cpvcross(verts[i], verts[(i+1)%numVerts]);+	}+	+	return area/2.0f;+}++cpVect+cpCentroidForPoly(const int numVerts, const cpVect *verts)+{+	cpFloat sum = 0.0f;+	cpVect vsum = cpvzero;+	+	for(int i=0; i<numVerts; i++){+		cpVect v1 = verts[i];+		cpVect v2 = verts[(i+1)%numVerts];+		cpFloat cross = cpvcross(v1, v2);+		+		sum += cross;+		vsum = cpvadd(vsum, cpvmult(cpvadd(v1, v2), cross));+	}+	+	return cpvmult(vsum, 1.0f/(3.0f*sum));+}++void+cpRecenterPoly(const int numVerts, cpVect *verts){+	cpVect centroid = cpCentroidForPoly(numVerts, verts);+	+	for(int i=0; i<numVerts; i++){+		verts[i] = cpvsub(verts[i], centroid);+	}+}++cpFloat+cpMomentForBox(cpFloat m, cpFloat width, cpFloat height)+{+	return m*(width*width + height*height)/12.0f;+}++#include "chipmunk_ffi.h"
+ Chipmunk-5.3.5/src/constraints/cpConstraint.c view
@@ -0,0 +1,54 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */++#include <stdlib.h>++#include "chipmunk_private.h"+#include "constraints/util.h"++// TODO: Comment me!++cpFloat cp_constraint_bias_coef = 0.1f;++void cpConstraintDestroy(cpConstraint *constraint){}++void+cpConstraintFree(cpConstraint *constraint)+{+	if(constraint){+		cpConstraintDestroy(constraint);+		cpfree(constraint);+	}+}++// *** defined in util.h++void+cpConstraintInit(cpConstraint *constraint, const cpConstraintClass *klass, cpBody *a, cpBody *b)+{+	constraint->klass = klass;+	constraint->a = a;+	constraint->b = b;+	+	constraint->maxForce = (cpFloat)INFINITY;+	constraint->biasCoef = cp_constraint_bias_coef;+	constraint->maxBias = (cpFloat)INFINITY;+}
+ Chipmunk-5.3.5/src/constraints/cpDampedRotarySpring.c view
@@ -0,0 +1,105 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */++#include <stdlib.h>+#include <math.h>++#include "chipmunk_private.h"+#include "constraints/util.h"++static cpFloat+defaultSpringTorque(cpDampedRotarySpring *spring, cpFloat relativeAngle){+	return (relativeAngle - spring->restAngle)*spring->stiffness;+}++static void+preStep(cpDampedRotarySpring *spring, cpFloat dt, cpFloat dt_inv)+{+	CONSTRAINT_BEGIN(spring, a, b);+	+	cpFloat moment = a->i_inv + b->i_inv;+	spring->iSum = 1.0f/moment;++	spring->w_coef = 1.0f - cpfexp(-spring->damping*dt*moment);+	spring->target_wrn = 0.0f;++	// apply spring torque+	cpFloat j_spring = spring->springTorqueFunc((cpConstraint *)spring, a->a - b->a)*dt;+	a->w -= j_spring*a->i_inv;+	b->w += j_spring*b->i_inv;+}++static void+applyImpulse(cpDampedRotarySpring *spring)+{+	CONSTRAINT_BEGIN(spring, a, b);+	+	// compute relative velocity+	cpFloat wrn = a->w - b->w;//normal_relative_velocity(a, b, r1, r2, n) - spring->target_vrn;+	+	// compute velocity loss from drag+	// not 100% certain this is derived correctly, though it makes sense+	cpFloat w_damp = wrn*spring->w_coef;+	spring->target_wrn = wrn - w_damp;+	+	//apply_impulses(a, b, spring->r1, spring->r2, cpvmult(spring->n, v_damp*spring->nMass));+	cpFloat j_damp = w_damp*spring->iSum;+	a->w -= j_damp*a->i_inv;+	b->w += j_damp*b->i_inv;+}++static cpFloat+getImpulse(cpConstraint *constraint)+{+	return 0.0f;+}++static const cpConstraintClass klass = {+	(cpConstraintPreStepFunction)preStep,+	(cpConstraintApplyImpulseFunction)applyImpulse,+	(cpConstraintGetImpulseFunction)getImpulse,+};+CP_DefineClassGetter(cpDampedRotarySpring)++cpDampedRotarySpring *+cpDampedRotarySpringAlloc(void)+{+	return (cpDampedRotarySpring *)cpcalloc(1, sizeof(cpDampedRotarySpring));+}++cpDampedRotarySpring *+cpDampedRotarySpringInit(cpDampedRotarySpring *spring, cpBody *a, cpBody *b, cpFloat restAngle, cpFloat stiffness, cpFloat damping)+{+	cpConstraintInit((cpConstraint *)spring, &klass, a, b);+	+	spring->restAngle = restAngle;+	spring->stiffness = stiffness;+	spring->damping = damping;+	spring->springTorqueFunc = (cpDampedRotarySpringTorqueFunc)defaultSpringTorque;+	+	return spring;+}++cpConstraint *+cpDampedRotarySpringNew(cpBody *a, cpBody *b, cpFloat restAngle, cpFloat stiffness, cpFloat damping)+{+	return (cpConstraint *)cpDampedRotarySpringInit(cpDampedRotarySpringAlloc(), a, b, restAngle, stiffness, damping);+}
+ Chipmunk-5.3.5/src/constraints/cpDampedSpring.c view
@@ -0,0 +1,115 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */++#include <stdlib.h>+#include <math.h>++#include "chipmunk_private.h"+#include "constraints/util.h"++static cpFloat+defaultSpringForce(cpDampedSpring *spring, cpFloat dist){+	return (spring->restLength - dist)*spring->stiffness;+}++static void+preStep(cpDampedSpring *spring, cpFloat dt, cpFloat dt_inv)+{+	CONSTRAINT_BEGIN(spring, a, b);+	+	spring->r1 = cpvrotate(spring->anchr1, a->rot);+	spring->r2 = cpvrotate(spring->anchr2, b->rot);+	+	cpVect delta = cpvsub(cpvadd(b->p, spring->r2), cpvadd(a->p, spring->r1));+	cpFloat dist = cpvlength(delta);+	spring->n = cpvmult(delta, 1.0f/(dist ? dist : INFINITY));+	+	cpFloat k = k_scalar(a, b, spring->r1, spring->r2, spring->n);+	spring->nMass = 1.0f/k;+	+	spring->target_vrn = 0.0f;+	spring->v_coef = 1.0f - cpfexp(-spring->damping*dt*k);++	// apply spring force+	cpFloat f_spring = spring->springForceFunc((cpConstraint *)spring, dist);+	apply_impulses(a, b, spring->r1, spring->r2, cpvmult(spring->n, f_spring*dt));+}++static void+applyImpulse(cpDampedSpring *spring)+{+	CONSTRAINT_BEGIN(spring, a, b);+	+	cpVect n = spring->n;+	cpVect r1 = spring->r1;+	cpVect r2 = spring->r2;++	// compute relative velocity+	cpFloat vrn = normal_relative_velocity(a, b, r1, r2, n) - spring->target_vrn;+	+	// compute velocity loss from drag+	// not 100% certain this is derived correctly, though it makes sense+	cpFloat v_damp = -vrn*spring->v_coef;+	spring->target_vrn = vrn + v_damp;+	+	apply_impulses(a, b, spring->r1, spring->r2, cpvmult(spring->n, v_damp*spring->nMass));+}++static cpFloat+getImpulse(cpConstraint *constraint)+{+	return 0.0f;+}++static const cpConstraintClass klass = {+	(cpConstraintPreStepFunction)preStep,+	(cpConstraintApplyImpulseFunction)applyImpulse,+	(cpConstraintGetImpulseFunction)getImpulse,+};+CP_DefineClassGetter(cpDampedSpring)++cpDampedSpring *+cpDampedSpringAlloc(void)+{+	return (cpDampedSpring *)cpcalloc(1, sizeof(cpDampedSpring));+}++cpDampedSpring *+cpDampedSpringInit(cpDampedSpring *spring, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat restLength, cpFloat stiffness, cpFloat damping)+{+	cpConstraintInit((cpConstraint *)spring, cpDampedSpringGetClass(), a, b);+	+	spring->anchr1 = anchr1;+	spring->anchr2 = anchr2;+	+	spring->restLength = restLength;+	spring->stiffness = stiffness;+	spring->damping = damping;+	spring->springForceFunc = (cpDampedSpringForceFunc)defaultSpringForce;+	+	return spring;+}++cpConstraint *+cpDampedSpringNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat restLength, cpFloat stiffness, cpFloat damping)+{+	return (cpConstraint *)cpDampedSpringInit(cpDampedSpringAlloc(), a, b, anchr1, anchr2, restLength, stiffness, damping);+}
+ Chipmunk-5.3.5/src/constraints/cpGearJoint.c view
@@ -0,0 +1,113 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */++#include <stdlib.h>++#include "chipmunk_private.h"+#include "constraints/util.h"++static void+preStep(cpGearJoint *joint, cpFloat dt, cpFloat dt_inv)+{+	CONSTRAINT_BEGIN(joint, a, b);+	+	// calculate moment of inertia coefficient.+	joint->iSum = 1.0f/(a->i_inv*joint->ratio_inv + joint->ratio*b->i_inv);+	+	// calculate bias velocity+	cpFloat maxBias = joint->constraint.maxBias;+	joint->bias = cpfclamp(-joint->constraint.biasCoef*dt_inv*(b->a*joint->ratio - a->a - joint->phase), -maxBias, maxBias);+	+	// compute max impulse+	joint->jMax = J_MAX(joint, dt);++	// apply joint torque+	cpFloat j = joint->jAcc;+	a->w -= j*a->i_inv*joint->ratio_inv;+	b->w += j*b->i_inv;+}++static void+applyImpulse(cpGearJoint *joint)+{+	CONSTRAINT_BEGIN(joint, a, b);+	+	// compute relative rotational velocity+	cpFloat wr = b->w*joint->ratio - a->w;+	+	// compute normal impulse	+	cpFloat j = (joint->bias - wr)*joint->iSum;+	cpFloat jOld = joint->jAcc;+	joint->jAcc = cpfclamp(jOld + j, -joint->jMax, joint->jMax);+	j = joint->jAcc - jOld;+	+	// apply impulse+	a->w -= j*a->i_inv*joint->ratio_inv;+	b->w += j*b->i_inv;+}++static cpFloat+getImpulse(cpGearJoint *joint)+{+	return cpfabs(joint->jAcc);+}++static const cpConstraintClass klass = {+	(cpConstraintPreStepFunction)preStep,+	(cpConstraintApplyImpulseFunction)applyImpulse,+	(cpConstraintGetImpulseFunction)getImpulse,+};+CP_DefineClassGetter(cpGearJoint)++cpGearJoint *+cpGearJointAlloc(void)+{+	return (cpGearJoint *)cpcalloc(1, sizeof(cpGearJoint));+}++cpGearJoint *+cpGearJointInit(cpGearJoint *joint, cpBody *a, cpBody *b, cpFloat phase, cpFloat ratio)+{+	cpConstraintInit((cpConstraint *)joint, &klass, a, b);+	+	joint->phase = phase;+	joint->ratio = ratio;+	joint->ratio_inv = 1.0f/ratio;+	+	joint->jAcc = 0.0f;+	+	return joint;+}++cpConstraint *+cpGearJointNew(cpBody *a, cpBody *b, cpFloat phase, cpFloat ratio)+{+	return (cpConstraint *)cpGearJointInit(cpGearJointAlloc(), a, b, phase, ratio);+}++void+cpGearJointSetRatio(cpConstraint *constraint, cpFloat value)+{+	cpConstraintCheckCast(constraint, cpGearJoint);+	((cpGearJoint *)constraint)->ratio = value;+	((cpGearJoint *)constraint)->ratio_inv = 1.0f/value;+	cpConstraintActivateBodies(constraint);+}
+ Chipmunk-5.3.5/src/constraints/cpGrooveJoint.c view
@@ -0,0 +1,161 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */++#include <stdlib.h>++#include "chipmunk_private.h"+#include "constraints/util.h"++static void+preStep(cpGrooveJoint *joint, cpFloat dt, cpFloat dt_inv)+{+	CONSTRAINT_BEGIN(joint, a, b);+	+	// calculate endpoints in worldspace+	cpVect ta = cpBodyLocal2World(a, joint->grv_a);+	cpVect tb = cpBodyLocal2World(a, joint->grv_b);++	// calculate axis+	cpVect n = cpvrotate(joint->grv_n, a->rot);+	cpFloat d = cpvdot(ta, n);+	+	joint->grv_tn = n;+	joint->r2 = cpvrotate(joint->anchr2, b->rot);+	+	// calculate tangential distance along the axis of r2+	cpFloat td = cpvcross(cpvadd(b->p, joint->r2), n);+	// calculate clamping factor and r2+	if(td <= cpvcross(ta, n)){+		joint->clamp = 1.0f;+		joint->r1 = cpvsub(ta, a->p);+	} else if(td >= cpvcross(tb, n)){+		joint->clamp = -1.0f;+		joint->r1 = cpvsub(tb, a->p);+	} else {+		joint->clamp = 0.0f;+		joint->r1 = cpvsub(cpvadd(cpvmult(cpvperp(n), -td), cpvmult(n, d)), a->p);+	}+	+	// Calculate mass tensor+	k_tensor(a, b, joint->r1, joint->r2, &joint->k1, &joint->k2);	+	+	// compute max impulse+	joint->jMaxLen = J_MAX(joint, dt);+	+	// calculate bias velocity+	cpVect delta = cpvsub(cpvadd(b->p, joint->r2), cpvadd(a->p, joint->r1));+	joint->bias = cpvclamp(cpvmult(delta, -joint->constraint.biasCoef*dt_inv), joint->constraint.maxBias);+	+	// apply accumulated impulse+	apply_impulses(a, b, joint->r1, joint->r2, joint->jAcc);+}++static inline cpVect+grooveConstrain(cpGrooveJoint *joint, cpVect j){+	cpVect n = joint->grv_tn;+	cpVect jClamp = (joint->clamp*cpvcross(j, n) > 0.0f) ? j : cpvproject(j, n);+	return cpvclamp(jClamp, joint->jMaxLen);+}++static void+applyImpulse(cpGrooveJoint *joint)+{+	CONSTRAINT_BEGIN(joint, a, b);+	+	cpVect r1 = joint->r1;+	cpVect r2 = joint->r2;+	+	// compute impulse+	cpVect vr = relative_velocity(a, b, r1, r2);++	cpVect j = mult_k(cpvsub(joint->bias, vr), joint->k1, joint->k2);+	cpVect jOld = joint->jAcc;+	joint->jAcc = grooveConstrain(joint, cpvadd(jOld, j));+	j = cpvsub(joint->jAcc, jOld);+	+	// apply impulse+	apply_impulses(a, b, joint->r1, joint->r2, j);+}++static cpFloat+getImpulse(cpGrooveJoint *joint)+{+	return cpvlength(joint->jAcc);+}++static const cpConstraintClass klass = {+	(cpConstraintPreStepFunction)preStep,+	(cpConstraintApplyImpulseFunction)applyImpulse,+	(cpConstraintGetImpulseFunction)getImpulse,+};+CP_DefineClassGetter(cpGrooveJoint)++cpGrooveJoint *+cpGrooveJointAlloc(void)+{+	return (cpGrooveJoint *)cpcalloc(1, sizeof(cpGrooveJoint));+}++cpGrooveJoint *+cpGrooveJointInit(cpGrooveJoint *joint, cpBody *a, cpBody *b, cpVect groove_a, cpVect groove_b, cpVect anchr2)+{+	cpConstraintInit((cpConstraint *)joint, &klass, a, b);+	+	joint->grv_a = groove_a;+	joint->grv_b = groove_b;+	joint->grv_n = cpvperp(cpvnormalize(cpvsub(groove_b, groove_a)));+	joint->anchr2 = anchr2;+	+	joint->jAcc = cpvzero;+	+	return joint;+}++cpConstraint *+cpGrooveJointNew(cpBody *a, cpBody *b, cpVect groove_a, cpVect groove_b, cpVect anchr2)+{+	return (cpConstraint *)cpGrooveJointInit(cpGrooveJointAlloc(), a, b, groove_a, groove_b, anchr2);+}++void+cpGrooveJointSetGrooveA(cpConstraint *constraint, cpVect value)+{+	cpGrooveJoint *g = (cpGrooveJoint *)constraint;+	cpConstraintCheckCast(constraint, cpGrooveJoint);+	+	g->grv_a = value;+	g->grv_n = cpvperp(cpvnormalize(cpvsub(g->grv_b, value)));+	+	cpConstraintActivateBodies(constraint);+}++void+cpGrooveJointSetGrooveB(cpConstraint *constraint, cpVect value)+{+	cpGrooveJoint *g = (cpGrooveJoint *)constraint;+	cpConstraintCheckCast(constraint, cpGrooveJoint);+	+	g->grv_b = value;+	g->grv_n = cpvperp(cpvnormalize(cpvsub(value, g->grv_a)));+	+	cpConstraintActivateBodies(constraint);+}+
+ Chipmunk-5.3.5/src/constraints/cpPinJoint.c view
@@ -0,0 +1,116 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */++#include <stdlib.h>+//#include <math.h>++#include "chipmunk_private.h"+#include "constraints/util.h"++static void+preStep(cpPinJoint *joint, cpFloat dt, cpFloat dt_inv)+{+	CONSTRAINT_BEGIN(joint, a, b);+	+	joint->r1 = cpvrotate(joint->anchr1, a->rot);+	joint->r2 = cpvrotate(joint->anchr2, b->rot);+	+	cpVect delta = cpvsub(cpvadd(b->p, joint->r2), cpvadd(a->p, joint->r1));+	cpFloat dist = cpvlength(delta);+	joint->n = cpvmult(delta, 1.0f/(dist ? dist : (cpFloat)INFINITY));+	+	// calculate mass normal+	joint->nMass = 1.0f/k_scalar(a, b, joint->r1, joint->r2, joint->n);+	+	// calculate bias velocity+	cpFloat maxBias = joint->constraint.maxBias;+	joint->bias = cpfclamp(-joint->constraint.biasCoef*dt_inv*(dist - joint->dist), -maxBias, maxBias);+	+	// compute max impulse+	joint->jnMax = J_MAX(joint, dt);+	+	// apply accumulated impulse+	cpVect j = cpvmult(joint->n, joint->jnAcc);+	apply_impulses(a, b, joint->r1, joint->r2, j);+}++static void+applyImpulse(cpPinJoint *joint)+{+	CONSTRAINT_BEGIN(joint, a, b);+	cpVect n = joint->n;++	// compute relative velocity+	cpFloat vrn = normal_relative_velocity(a, b, joint->r1, joint->r2, n);+	+	// compute normal impulse+	cpFloat jn = (joint->bias - vrn)*joint->nMass;+	cpFloat jnOld = joint->jnAcc;+	joint->jnAcc = cpfclamp(jnOld + jn, -joint->jnMax, joint->jnMax);+	jn = joint->jnAcc - jnOld;+	+	// apply impulse+	apply_impulses(a, b, joint->r1, joint->r2, cpvmult(n, jn));+}++static cpFloat+getImpulse(cpPinJoint *joint)+{+	return cpfabs(joint->jnAcc);+}++static const cpConstraintClass klass = {+	(cpConstraintPreStepFunction)preStep,+	(cpConstraintApplyImpulseFunction)applyImpulse,+	(cpConstraintGetImpulseFunction)getImpulse,+};+CP_DefineClassGetter(cpPinJoint);+++cpPinJoint *+cpPinJointAlloc(void)+{+	return (cpPinJoint *)cpcalloc(1, sizeof(cpPinJoint));+}++cpPinJoint *+cpPinJointInit(cpPinJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2)+{+	cpConstraintInit((cpConstraint *)joint, &klass, a, b);+	+	joint->anchr1 = anchr1;+	joint->anchr2 = anchr2;+	+	// STATIC_BODY_CHECK+	cpVect p1 = (a ? cpvadd(a->p, cpvrotate(anchr1, a->rot)) : anchr1);+	cpVect p2 = (b ? cpvadd(b->p, cpvrotate(anchr2, b->rot)) : anchr2);+	joint->dist = cpvlength(cpvsub(p2, p1));++	joint->jnAcc = 0.0f;+	+	return joint;+}++cpConstraint *+cpPinJointNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2)+{+	return (cpConstraint *)cpPinJointInit(cpPinJointAlloc(), a, b, anchr1, anchr2);+}
+ Chipmunk-5.3.5/src/constraints/cpPivotJoint.c view
@@ -0,0 +1,114 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */++#include <stdlib.h>++#include "chipmunk_private.h"+#include "constraints/util.h"++static void+preStep(cpPivotJoint *joint, cpFloat dt, cpFloat dt_inv)+{+	CONSTRAINT_BEGIN(joint, a, b);+	+	joint->r1 = cpvrotate(joint->anchr1, a->rot);+	joint->r2 = cpvrotate(joint->anchr2, b->rot);+	+	// Calculate mass tensor+	k_tensor(a, b, joint->r1, joint->r2, &joint->k1, &joint->k2);+	+	// compute max impulse+	joint->jMaxLen = J_MAX(joint, dt);+	+	// calculate bias velocity+	cpVect delta = cpvsub(cpvadd(b->p, joint->r2), cpvadd(a->p, joint->r1));+	joint->bias = cpvclamp(cpvmult(delta, -joint->constraint.biasCoef*dt_inv), joint->constraint.maxBias);+	+	// apply accumulated impulse+	apply_impulses(a, b, joint->r1, joint->r2, joint->jAcc);+}++static void+applyImpulse(cpPivotJoint *joint)+{+	CONSTRAINT_BEGIN(joint, a, b);+	+	cpVect r1 = joint->r1;+	cpVect r2 = joint->r2;+		+	// compute relative velocity+	cpVect vr = relative_velocity(a, b, r1, r2);+	+	// compute normal impulse+	cpVect j = mult_k(cpvsub(joint->bias, vr), joint->k1, joint->k2);+	cpVect jOld = joint->jAcc;+	joint->jAcc = cpvclamp(cpvadd(joint->jAcc, j), joint->jMaxLen);+	j = cpvsub(joint->jAcc, jOld);+	+	// apply impulse+	apply_impulses(a, b, joint->r1, joint->r2, j);+}++static cpFloat+getImpulse(cpConstraint *joint)+{+	return cpvlength(((cpPivotJoint *)joint)->jAcc);+}++static const cpConstraintClass klass = {+	(cpConstraintPreStepFunction)preStep,+	(cpConstraintApplyImpulseFunction)applyImpulse,+	(cpConstraintGetImpulseFunction)getImpulse,+};+CP_DefineClassGetter(cpPivotJoint)++cpPivotJoint *+cpPivotJointAlloc(void)+{+	return (cpPivotJoint *)cpcalloc(1, sizeof(cpPivotJoint));+}++cpPivotJoint *+cpPivotJointInit(cpPivotJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2)+{+	cpConstraintInit((cpConstraint *)joint, &klass, a, b);+	+	joint->anchr1 = anchr1;+	joint->anchr2 = anchr2;+	+	joint->jAcc = cpvzero;+	+	return joint;+}++cpConstraint *+cpPivotJointNew2(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2)+{+	return (cpConstraint *)cpPivotJointInit(cpPivotJointAlloc(), a, b, anchr1, anchr2);+}++cpConstraint *+cpPivotJointNew(cpBody *a, cpBody *b, cpVect pivot)+{+	cpVect anchr1 = (a ? cpBodyWorld2Local(a, pivot) : pivot);+	cpVect anchr2 = (b ? cpBodyWorld2Local(b, pivot) : pivot);+	return cpPivotJointNew2(a, b, anchr1, anchr2);+}
+ Chipmunk-5.3.5/src/constraints/cpRatchetJoint.c view
@@ -0,0 +1,126 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */++#include <stdlib.h>+#include <math.h>++#include "chipmunk_private.h"+#include "constraints/util.h"++static void+preStep(cpRatchetJoint *joint, cpFloat dt, cpFloat dt_inv)+{+	CONSTRAINT_BEGIN(joint, a, b);+	+	cpFloat angle = joint->angle;+	cpFloat phase = joint->phase;+	cpFloat ratchet = joint->ratchet;+	+	cpFloat delta = b->a - a->a;+	cpFloat diff = angle - delta;+	cpFloat pdist = 0.0f;+	+	if(diff*ratchet > 0.0f){+		pdist = diff;+	} else {+		joint->angle = cpffloor((delta - phase)/ratchet)*ratchet + phase;+	}+	+	// calculate moment of inertia coefficient.+	joint->iSum = 1.0f/(a->i_inv + b->i_inv);+	+	// calculate bias velocity+	cpFloat maxBias = joint->constraint.maxBias;+	joint->bias = cpfclamp(-joint->constraint.biasCoef*dt_inv*pdist, -maxBias, maxBias);+	+	// compute max impulse+	joint->jMax = J_MAX(joint, dt);++	// If the bias is 0, the joint is not at a limit. Reset the impulse.+	if(!joint->bias)+		joint->jAcc = 0.0f;++	// apply joint torque+	a->w -= joint->jAcc*a->i_inv;+	b->w += joint->jAcc*b->i_inv;+}++static void+applyImpulse(cpRatchetJoint *joint)+{+	if(!joint->bias) return; // early exit++	CONSTRAINT_BEGIN(joint, a, b);+	+	// compute relative rotational velocity+	cpFloat wr = b->w - a->w;+	cpFloat ratchet = joint->ratchet;+	+	// compute normal impulse	+	cpFloat j = -(joint->bias + wr)*joint->iSum;+	cpFloat jOld = joint->jAcc;+	joint->jAcc = cpfclamp((jOld + j)*ratchet, 0.0f, joint->jMax*cpfabs(ratchet))/ratchet;+	j = joint->jAcc - jOld;+	+	// apply impulse+	a->w -= j*a->i_inv;+	b->w += j*b->i_inv;+}++static cpFloat+getImpulse(cpRatchetJoint *joint)+{+	return cpfabs(joint->jAcc);+}++static const cpConstraintClass klass = {+	(cpConstraintPreStepFunction)preStep,+	(cpConstraintApplyImpulseFunction)applyImpulse,+	(cpConstraintGetImpulseFunction)getImpulse,+};+CP_DefineClassGetter(cpRatchetJoint)++cpRatchetJoint *+cpRatchetJointAlloc(void)+{+	return (cpRatchetJoint *)cpcalloc(1, sizeof(cpRatchetJoint));+}++cpRatchetJoint *+cpRatchetJointInit(cpRatchetJoint *joint, cpBody *a, cpBody *b, cpFloat phase, cpFloat ratchet)+{+	cpConstraintInit((cpConstraint *)joint, &klass, a, b);+	+	joint->angle = 0.0f;+	joint->phase = phase;+	joint->ratchet = ratchet;+	+	// STATIC_BODY_CHECK+	joint->angle = (b ? b->a : 0.0f) - (a ? a->a : 0.0f);+	+	return joint;+}++cpConstraint *+cpRatchetJointNew(cpBody *a, cpBody *b, cpFloat phase, cpFloat ratchet)+{+	return (cpConstraint *)cpRatchetJointInit(cpRatchetJointAlloc(), a, b, phase, ratchet);+}
+ Chipmunk-5.3.5/src/constraints/cpRotaryLimitJoint.c view
@@ -0,0 +1,120 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */++#include <stdlib.h>++#include "chipmunk_private.h"+#include "constraints/util.h"++static void+preStep(cpRotaryLimitJoint *joint, cpFloat dt, cpFloat dt_inv)+{+	CONSTRAINT_BEGIN(joint, a, b);+	+	cpFloat dist = b->a - a->a;+	cpFloat pdist = 0.0f;+	if(dist > joint->max) {+		pdist = joint->max - dist;+	} else if(dist < joint->min) {+		pdist = joint->min - dist;+	}+	+	// calculate moment of inertia coefficient.+	joint->iSum = 1.0f/(a->i_inv + b->i_inv);+	+	// calculate bias velocity+	cpFloat maxBias = joint->constraint.maxBias;+	joint->bias = cpfclamp(-joint->constraint.biasCoef*dt_inv*(pdist), -maxBias, maxBias);+	+	// compute max impulse+	joint->jMax = J_MAX(joint, dt);++	// If the bias is 0, the joint is not at a limit. Reset the impulse.+	if(!joint->bias)+		joint->jAcc = 0.0f;++	// apply joint torque+	a->w -= joint->jAcc*a->i_inv;+	b->w += joint->jAcc*b->i_inv;+}++static void+applyImpulse(cpRotaryLimitJoint *joint)+{+	if(!joint->bias) return; // early exit++	CONSTRAINT_BEGIN(joint, a, b);+	+	// compute relative rotational velocity+	cpFloat wr = b->w - a->w;+	+	// compute normal impulse	+	cpFloat j = -(joint->bias + wr)*joint->iSum;+	cpFloat jOld = joint->jAcc;+	if(joint->bias < 0.0f){+		joint->jAcc = cpfclamp(jOld + j, 0.0f, joint->jMax);+	} else {+		joint->jAcc = cpfclamp(jOld + j, -joint->jMax, 0.0f);+	}+	j = joint->jAcc - jOld;+	+	// apply impulse+	a->w -= j*a->i_inv;+	b->w += j*b->i_inv;+}++static cpFloat+getImpulse(cpRotaryLimitJoint *joint)+{+	return cpfabs(joint->jAcc);+}++static const cpConstraintClass klass = {+	(cpConstraintPreStepFunction)preStep,+	(cpConstraintApplyImpulseFunction)applyImpulse,+	(cpConstraintGetImpulseFunction)getImpulse,+};+CP_DefineClassGetter(cpRotaryLimitJoint)++cpRotaryLimitJoint *+cpRotaryLimitJointAlloc(void)+{+	return (cpRotaryLimitJoint *)cpcalloc(1, sizeof(cpRotaryLimitJoint));+}++cpRotaryLimitJoint *+cpRotaryLimitJointInit(cpRotaryLimitJoint *joint, cpBody *a, cpBody *b, cpFloat min, cpFloat max)+{+	cpConstraintInit((cpConstraint *)joint, &klass, a, b);+	+	joint->min = min;+	joint->max  = max;+	+	joint->jAcc = 0.0f;+	+	return joint;+}++cpConstraint *+cpRotaryLimitJointNew(cpBody *a, cpBody *b, cpFloat min, cpFloat max)+{+	return (cpConstraint *)cpRotaryLimitJointInit(cpRotaryLimitJointAlloc(), a, b, min, max);+}
+ Chipmunk-5.3.5/src/constraints/cpSimpleMotor.c view
@@ -0,0 +1,97 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */++#include <stdlib.h>++#include "chipmunk_private.h"+#include "constraints/util.h"++static void+preStep(cpSimpleMotor *joint, cpFloat dt, cpFloat dt_inv)+{+	CONSTRAINT_BEGIN(joint, a, b);+	+	// calculate moment of inertia coefficient.+	joint->iSum = 1.0f/(a->i_inv + b->i_inv);+	+	// compute max impulse+	joint->jMax = J_MAX(joint, dt);++	// apply joint torque+	a->w -= joint->jAcc*a->i_inv;+	b->w += joint->jAcc*b->i_inv;+}++static void+applyImpulse(cpSimpleMotor *joint)+{+	CONSTRAINT_BEGIN(joint, a, b);+	+	// compute relative rotational velocity+	cpFloat wr = b->w - a->w + joint->rate;+	+	// compute normal impulse	+	cpFloat j = -wr*joint->iSum;+	cpFloat jOld = joint->jAcc;+	joint->jAcc = cpfclamp(jOld + j, -joint->jMax, joint->jMax);+	j = joint->jAcc - jOld;+	+	// apply impulse+	a->w -= j*a->i_inv;+	b->w += j*b->i_inv;+}++static cpFloat+getImpulse(cpSimpleMotor *joint)+{+	return cpfabs(joint->jAcc);+}++static const cpConstraintClass klass = {+	(cpConstraintPreStepFunction)preStep,+	(cpConstraintApplyImpulseFunction)applyImpulse,+	(cpConstraintGetImpulseFunction)getImpulse,+};+CP_DefineClassGetter(cpSimpleMotor)++cpSimpleMotor *+cpSimpleMotorAlloc(void)+{+	return (cpSimpleMotor *)cpcalloc(1, sizeof(cpSimpleMotor));+}++cpSimpleMotor *+cpSimpleMotorInit(cpSimpleMotor *joint, cpBody *a, cpBody *b, cpFloat rate)+{+	cpConstraintInit((cpConstraint *)joint, &klass, a, b);+	+	joint->rate = rate;+	+	joint->jAcc = 0.0f;+	+	return joint;+}++cpConstraint *+cpSimpleMotorNew(cpBody *a, cpBody *b, cpFloat rate)+{+	return (cpConstraint *)cpSimpleMotorInit(cpSimpleMotorAlloc(), a, b, rate);+}
+ Chipmunk-5.3.5/src/constraints/cpSlideJoint.c view
@@ -0,0 +1,129 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */++#include <stdlib.h>++#include "chipmunk_private.h"+#include "constraints/util.h"++static void+preStep(cpSlideJoint *joint, cpFloat dt, cpFloat dt_inv)+{+	CONSTRAINT_BEGIN(joint, a, b);+	+	joint->r1 = cpvrotate(joint->anchr1, a->rot);+	joint->r2 = cpvrotate(joint->anchr2, b->rot);+	+	cpVect delta = cpvsub(cpvadd(b->p, joint->r2), cpvadd(a->p, joint->r1));+	cpFloat dist = cpvlength(delta);+	cpFloat pdist = 0.0f;+	if(dist > joint->max) {+		pdist = dist - joint->max;+	} else if(dist < joint->min) {+		pdist = joint->min - dist;+		dist = -dist;+	}+	joint->n = cpvmult(delta, 1.0f/(dist ? dist : (cpFloat)INFINITY));+	+	// calculate mass normal+	joint->nMass = 1.0f/k_scalar(a, b, joint->r1, joint->r2, joint->n);+	+	// calculate bias velocity+	cpFloat maxBias = joint->constraint.maxBias;+	joint->bias = cpfclamp(-joint->constraint.biasCoef*dt_inv*(pdist), -maxBias, maxBias);+	+	// compute max impulse+	joint->jnMax = J_MAX(joint, dt);++	// apply accumulated impulse+	if(!joint->bias) //{+		// if bias is 0, then the joint is not at a limit.+		joint->jnAcc = 0.0f;+//	} else {+		cpVect j = cpvmult(joint->n, joint->jnAcc);+		apply_impulses(a, b, joint->r1, joint->r2, j);+//	}+}++static void+applyImpulse(cpSlideJoint *joint)+{+	if(!joint->bias) return;  // early exit++	CONSTRAINT_BEGIN(joint, a, b);+	+	cpVect n = joint->n;+	cpVect r1 = joint->r1;+	cpVect r2 = joint->r2;+		+	// compute relative velocity+	cpVect vr = relative_velocity(a, b, r1, r2);+	cpFloat vrn = cpvdot(vr, n);+	+	// compute normal impulse+	cpFloat jn = (joint->bias - vrn)*joint->nMass;+	cpFloat jnOld = joint->jnAcc;+	joint->jnAcc = cpfclamp(jnOld + jn, -joint->jnMax, 0.0f);+	jn = joint->jnAcc - jnOld;+	+	// apply impulse+	apply_impulses(a, b, joint->r1, joint->r2, cpvmult(n, jn));+}++static cpFloat+getImpulse(cpConstraint *joint)+{+	return cpfabs(((cpSlideJoint *)joint)->jnAcc);+}++static const cpConstraintClass klass = {+	(cpConstraintPreStepFunction)preStep,+	(cpConstraintApplyImpulseFunction)applyImpulse,+	(cpConstraintGetImpulseFunction)getImpulse,+};+CP_DefineClassGetter(cpSlideJoint)++cpSlideJoint *+cpSlideJointAlloc(void)+{+	return (cpSlideJoint *)cpcalloc(1, sizeof(cpSlideJoint));+}++cpSlideJoint *+cpSlideJointInit(cpSlideJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max)+{+	cpConstraintInit((cpConstraint *)joint, &klass, a, b);+	+	joint->anchr1 = anchr1;+	joint->anchr2 = anchr2;+	joint->min = min;+	joint->max = max;+	+	joint->jnAcc = 0.0f;+	+	return joint;+}++cpConstraint *+cpSlideJointNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max)+{+	return (cpConstraint *)cpSlideJointInit(cpSlideJointAlloc(), a, b, anchr1, anchr2, min, max);+}
+ Chipmunk-5.3.5/src/cpArbiter.c view
@@ -0,0 +1,280 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */+ +#include <stdlib.h>++#include "chipmunk_private.h"+#include "constraints/util.h"++cpFloat cp_bias_coef = 0.1f;+cpFloat cp_collision_slop = 0.1f;++cpContact*+cpContactInit(cpContact *con, cpVect p, cpVect n, cpFloat dist, cpHashValue hash)+{+	con->p = p;+	con->n = n;+	con->dist = dist;+	+	con->jnAcc = 0.0f;+	con->jtAcc = 0.0f;+	con->jBias = 0.0f;+	+	con->hash = hash;+		+	return con;+}++cpVect+cpArbiterTotalImpulse(cpArbiter *arb)+{+	cpContact *contacts = arb->contacts;+	cpVect sum = cpvzero;+	+	for(int i=0, count=arb->numContacts; i<count; i++){+		cpContact *con = &contacts[i];+		sum = cpvadd(sum, cpvmult(con->n, con->jnAcc));+	}+		+	return sum;+}++cpVect+cpArbiterTotalImpulseWithFriction(cpArbiter *arb)+{+	cpContact *contacts = arb->contacts;+	cpVect sum = cpvzero;+	+	for(int i=0, count=arb->numContacts; i<count; i++){+		cpContact *con = &contacts[i];+		sum = cpvadd(sum, cpvrotate(con->n, cpv(con->jnAcc, con->jtAcc)));+	}+		+	return sum;+}++cpFloat+cpContactsEstimateCrushingImpulse(cpContact *contacts, int numContacts)+{+	cpFloat fsum = 0.0f;+	cpVect vsum = cpvzero;+	+	for(int i=0; i<numContacts; i++){+		cpContact *con = &contacts[i];+		cpVect j = cpvrotate(con->n, cpv(con->jnAcc, con->jtAcc));+		+		fsum += cpvlength(j);+		vsum = cpvadd(vsum, j);+	}+	+	cpFloat vmag = cpvlength(vsum);+	return (1.0f - vmag/fsum);+}++void+cpArbiterIgnore(cpArbiter *arb)+{+	arb->state = cpArbiterStateIgnore;+}++cpArbiter*+cpArbiterAlloc(void)+{+	return (cpArbiter *)cpcalloc(1, sizeof(cpArbiter));+}++cpArbiter*+cpArbiterInit(cpArbiter *arb, cpShape *a, cpShape *b)+{+	arb->handler = NULL;+	arb->swappedColl = cpFalse;+	+	arb->e = 0.0f;+	arb->u = 0.0f;+	arb->surface_vr = cpvzero;+	+	arb->numContacts = 0;+	arb->contacts = NULL;+	+	arb->a = a;+	arb->b = b;+	+	arb->stamp = 0;+	arb->state = cpArbiterStateFirstColl;+	+	return arb;+}++cpArbiter*+cpArbiterNew(cpShape *a, cpShape *b)+{+	return cpArbiterInit(cpArbiterAlloc(), a, b);+}++void+cpArbiterDestroy(cpArbiter *arb)+{+//	if(arb->contacts) cpfree(arb->contacts);+}++void+cpArbiterFree(cpArbiter *arb)+{+	if(arb){+		cpArbiterDestroy(arb);+		cpfree(arb);+	}+}++void+cpArbiterUpdate(cpArbiter *arb, cpContact *contacts, int numContacts, cpCollisionHandler *handler, cpShape *a, cpShape *b)+{+	// Arbiters without contact data may exist if a collision function rejected the collision.+	if(arb->contacts){+		// Iterate over the possible pairs to look for hash value matches.+		for(int i=0; i<arb->numContacts; i++){+			cpContact *old = &arb->contacts[i];+			+			for(int j=0; j<numContacts; j++){+				cpContact *new_contact = &contacts[j];+				+				// This could trigger false positives, but is fairly unlikely nor serious if it does.+				if(new_contact->hash == old->hash){+					// Copy the persistant contact information.+					new_contact->jnAcc = old->jnAcc;+					new_contact->jtAcc = old->jtAcc;+				}+			}+		}+	}+	+	arb->contacts = contacts;+	arb->numContacts = numContacts;+	+	arb->handler = handler;+	arb->swappedColl = (a->collision_type != handler->a);+	+	arb->e = a->e * b->e;+	arb->u = a->u * b->u;+	arb->surface_vr = cpvsub(a->surface_v, b->surface_v);+	+	// For collisions between two similar primitive types, the order could have been swapped.+	arb->a = a;+	arb->b = b;+	+	// mark it as new if it's been cached+	if(arb->state == cpArbiterStateCached) arb->state = cpArbiterStateFirstColl;+}++void+cpArbiterPreStep(cpArbiter *arb, cpFloat dt_inv)+{+	cpBody *a = arb->a->body;+	cpBody *b = arb->b->body;+	+	for(int i=0; i<arb->numContacts; i++){+		cpContact *con = &arb->contacts[i];+		+		// Calculate the offsets.+		con->r1 = cpvsub(con->p, a->p);+		con->r2 = cpvsub(con->p, b->p);+		+		// Calculate the mass normal and mass tangent.+		con->nMass = 1.0f/k_scalar(a, b, con->r1, con->r2, con->n);+		con->tMass = 1.0f/k_scalar(a, b, con->r1, con->r2, cpvperp(con->n));+				+		// Calculate the target bias velocity.+		con->bias = -cp_bias_coef*dt_inv*cpfmin(0.0f, con->dist + cp_collision_slop);+		con->jBias = 0.0f;+		+		// Calculate the target bounce velocity.+		con->bounce = normal_relative_velocity(a, b, con->r1, con->r2, con->n)*arb->e;//cpvdot(con->n, cpvsub(v2, v1))*e;+	}+}++void+cpArbiterApplyCachedImpulse(cpArbiter *arb)+{+	cpShape *shapea = arb->a;+	cpShape *shapeb = arb->b;+		+	arb->u = shapea->u * shapeb->u;+	arb->surface_vr = cpvsub(shapeb->surface_v, shapea->surface_v);++	cpBody *a = shapea->body;+	cpBody *b = shapeb->body;+	+	for(int i=0; i<arb->numContacts; i++){+		cpContact *con = &arb->contacts[i];+		apply_impulses(a, b, con->r1, con->r2, cpvrotate(con->n, cpv(con->jnAcc, con->jtAcc)));+	}+}++void+cpArbiterApplyImpulse(cpArbiter *arb, cpFloat eCoef)+{+	cpBody *a = arb->a->body;+	cpBody *b = arb->b->body;++	for(int i=0; i<arb->numContacts; i++){+		cpContact *con = &arb->contacts[i];+		cpVect n = con->n;+		cpVect r1 = con->r1;+		cpVect r2 = con->r2;+		+		// Calculate the relative bias velocities.+		cpVect vb1 = cpvadd(a->v_bias, cpvmult(cpvperp(r1), a->w_bias));+		cpVect vb2 = cpvadd(b->v_bias, cpvmult(cpvperp(r2), b->w_bias));+		cpFloat vbn = cpvdot(cpvsub(vb2, vb1), n);+		+		// Calculate and clamp the bias impulse.+		cpFloat jbn = (con->bias - vbn)*con->nMass;+		cpFloat jbnOld = con->jBias;+		con->jBias = cpfmax(jbnOld + jbn, 0.0f);+		jbn = con->jBias - jbnOld;+		+		// Apply the bias impulse.+		apply_bias_impulses(a, b, r1, r2, cpvmult(n, jbn));++		// Calculate the relative velocity.+		cpVect vr = relative_velocity(a, b, r1, r2);+		cpFloat vrn = cpvdot(vr, n);+		+		// Calculate and clamp the normal impulse.+		cpFloat jn = -(con->bounce*eCoef + vrn)*con->nMass;+		cpFloat jnOld = con->jnAcc;+		con->jnAcc = cpfmax(jnOld + jn, 0.0f);+		jn = con->jnAcc - jnOld;+		+		// Calculate the relative tangent velocity.+		cpFloat vrt = cpvdot(cpvadd(vr, arb->surface_vr), cpvperp(n));+		+		// Calculate and clamp the friction impulse.+		cpFloat jtMax = arb->u*con->jnAcc;+		cpFloat jt = -vrt*con->tMass;+		cpFloat jtOld = con->jtAcc;+		con->jtAcc = cpfclamp(jtOld + jt, -jtMax, jtMax);+		jt = con->jtAcc - jtOld;+		+		// Apply the final impulse.+		apply_impulses(a, b, r1, r2, cpvrotate(n, cpv(jn, jt)));+	}+}
+ Chipmunk-5.3.5/src/cpArray.c view
@@ -0,0 +1,143 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */+ +#include <stdlib.h>+#include <string.h>++#include "chipmunk_private.h"+++//#define CP_ARRAY_INCREMENT 10++// NOTE: cpArray is rarely used and will probably go away.++cpArray*+cpArrayAlloc(void)+{+	return (cpArray *)cpcalloc(1, sizeof(cpArray));+}++cpArray*+cpArrayInit(cpArray *arr, int size)+{+	arr->num = 0;+	+	size = (size ? size : 4);+	arr->max = size;+	arr->arr = (void **)cpcalloc(size, sizeof(void**));+	+	return arr;+}++cpArray*+cpArrayNew(int size)+{+	return cpArrayInit(cpArrayAlloc(), size);+}++void+cpArrayDestroy(cpArray *arr)+{+	cpfree(arr->arr);+	arr->arr = NULL;+}++void+cpArrayFree(cpArray *arr)+{+	if(arr){+		cpArrayDestroy(arr);+		cpfree(arr);+	}+}++void+cpArrayPush(cpArray *arr, void *object)+{+	if(arr->num == arr->max){+		arr->max *= 2;+		arr->arr = (void **)cprealloc(arr->arr, arr->max*sizeof(void**));+	}+	+	arr->arr[arr->num] = object;+	arr->num++;+}++void *+cpArrayPop(cpArray *arr)+{+	arr->num--;+	+	void *value = arr->arr[arr->num];+	arr->arr[arr->num] = NULL;+	+	return value;+}++void+cpArrayDeleteIndex(cpArray *arr, int idx)+{+	arr->num--;+	+	arr->arr[idx] = arr->arr[arr->num];+	arr->arr[arr->num] = NULL;+}++void+cpArrayDeleteObj(cpArray *arr, void *obj)+{+	for(int i=0; i<arr->num; i++){+		if(arr->arr[i] == obj){+			cpArrayDeleteIndex(arr, i);+			return;+		}+	}+}++void+cpArrayAppend(cpArray *arr, cpArray *other)+{+	void *tail = &arr->arr[arr->num];+	+	arr->num += other->num;+	if(arr->num >= arr->max){+		arr->max = arr->num;+		arr->arr = (void **)cprealloc(arr->arr, arr->max*sizeof(void**));+	}+	+	memcpy(tail, other->arr, other->num*sizeof(void**));+}++void+cpArrayEach(cpArray *arr, cpArrayIter iterFunc, void *data)+{+	for(int i=0; i<arr->num; i++)+		iterFunc(arr->arr[i], data);+}++cpBool+cpArrayContains(cpArray *arr, void *ptr)+{+	for(int i=0; i<arr->num; i++)+		if(arr->arr[i] == ptr) return cpTrue;+	+	return cpFalse;+}
+ Chipmunk-5.3.5/src/cpBB.c view
@@ -0,0 +1,47 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */+ +#include <math.h>+#include <stdlib.h>++#include "chipmunk.h"++cpVect+cpBBClampVect(const cpBB bb, const cpVect v)+{+	cpFloat x = cpfmin(cpfmax(bb.l, v.x), bb.r);+	cpFloat y = cpfmin(cpfmax(bb.b, v.y), bb.t);+	return cpv(x, y);+}++cpVect+cpBBWrapVect(const cpBB bb, const cpVect v)+{+	cpFloat ix = cpfabs(bb.r - bb.l);+	cpFloat modx = cpfmod(v.x - bb.l, ix);+	cpFloat x = (modx > 0.0f) ? modx : modx + ix;+	+	cpFloat iy = cpfabs(bb.t - bb.b);+	cpFloat mody = cpfmod(v.y - bb.b, iy);+	cpFloat y = (mody > 0.0f) ? mody : mody + iy;+	+	return cpv(x + bb.l, y + bb.b);+}
+ Chipmunk-5.3.5/src/cpBody.c view
@@ -0,0 +1,204 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */+ +#include <stdlib.h>+#include <float.h>+#include <stdarg.h>++#include "chipmunk_private.h"+#include "constraints/util.h"++// initialized in cpInitChipmunk()+cpBody cpStaticBodySingleton;++cpBody*+cpBodyAlloc(void)+{+	return (cpBody *)cpcalloc(1, sizeof(cpBody));+}++cpBodyVelocityFunc cpBodyUpdateVelocityDefault = cpBodyUpdateVelocity;+cpBodyPositionFunc cpBodyUpdatePositionDefault = cpBodyUpdatePosition;++cpBody *+cpBodyInit(cpBody *body, cpFloat m, cpFloat i)+{+	body->velocity_func = cpBodyUpdateVelocityDefault;+	body->position_func = cpBodyUpdatePositionDefault;+	+	cpBodySetMass(body, m);+	cpBodySetMoment(body, i);++	body->p = cpvzero;+	body->v = cpvzero;+	body->f = cpvzero;+	+	cpBodySetAngle(body, 0.0f);+	body->w = 0.0f;+	body->t = 0.0f;+	+	body->v_bias = cpvzero;+	body->w_bias = 0.0f;+	+	body->data = NULL;+	body->v_limit = (cpFloat)INFINITY;+	body->w_limit = (cpFloat)INFINITY;+	+	body->space = NULL;+	body->shapesList = NULL;+	+	cpComponentNode node = {NULL, NULL, 0, 0.0f};+	body->node = node;+	+	return body;+}++cpBody*+cpBodyNew(cpFloat m, cpFloat i)+{+	return cpBodyInit(cpBodyAlloc(), m, i);+}++cpBody *+cpBodyInitStatic(cpBody *body)+{+	cpBodyInit(body, (cpFloat)INFINITY, (cpFloat)INFINITY);+	body->node.idleTime = (cpFloat)INFINITY;+	+	return body;+}++cpBody *+cpBodyNewStatic()+{+	return cpBodyInitStatic(cpBodyAlloc());+}++void cpBodyDestroy(cpBody *body){}++void+cpBodyFree(cpBody *body)+{+	if(body){+		cpBodyDestroy(body);+		cpfree(body);+	}+}++void+cpBodySetMass(cpBody *body, cpFloat mass)+{+	body->m = mass;+	body->m_inv = 1.0f/mass;+}++void+cpBodySetMoment(cpBody *body, cpFloat moment)+{+	body->i = moment;+	body->i_inv = 1.0f/moment;+}++void+cpBodySetAngle(cpBody *body, cpFloat angle)+{+	body->a = angle;//fmod(a, (cpFloat)M_PI*2.0f);+	body->rot = cpvforangle(angle);+}++void+cpBodySlew(cpBody *body, cpVect pos, cpFloat dt)+{+	cpVect delta = cpvsub(pos, body->p);+	body->v = cpvmult(delta, 1.0f/dt);+}++void+cpBodyUpdateVelocity(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt)+{+	body->v = cpvclamp(cpvadd(cpvmult(body->v, damping), cpvmult(cpvadd(gravity, cpvmult(body->f, body->m_inv)), dt)), body->v_limit);+	+	cpFloat w_limit = body->w_limit;+	body->w = cpfclamp(body->w*damping + body->t*body->i_inv*dt, -w_limit, w_limit);+}++void+cpBodyUpdatePosition(cpBody *body, cpFloat dt)+{+	body->p = cpvadd(body->p, cpvmult(cpvadd(body->v, body->v_bias), dt));+	cpBodySetAngle(body, body->a + (body->w + body->w_bias)*dt);+	+	body->v_bias = cpvzero;+	body->w_bias = 0.0f;+}++void+cpBodyResetForces(cpBody *body)+{+	cpBodyActivate(body);+	body->f = cpvzero;+	body->t = 0.0f;+}++void+cpBodyApplyForce(cpBody *body, const cpVect force, const cpVect r)+{+	cpBodyActivate(body);+	+	body->f = cpvadd(body->f, force);+	body->t += cpvcross(r, force);+}++void+cpBodyApplyImpulse(cpBody *body, const cpVect j, const cpVect r)+{+	cpBodyActivate(body);+	apply_impulse(body, j, r);+}+++void+cpApplyDampedSpring(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat rlen, cpFloat k, cpFloat dmp, cpFloat dt)+{+	// Calculate the world space anchor coordinates.+	cpVect r1 = cpvrotate(anchr1, a->rot);+	cpVect r2 = cpvrotate(anchr2, b->rot);+	+	cpVect delta = cpvsub(cpvadd(b->p, r2), cpvadd(a->p, r1));+	cpFloat dist = cpvlength(delta);+	cpVect n = dist ? cpvmult(delta, 1.0f/dist) : cpvzero;+	+	cpFloat f_spring = (dist - rlen)*k;++	// Calculate the world relative velocities of the anchor points.+	cpVect v1 = cpvadd(a->v, cpvmult(cpvperp(r1), a->w));+	cpVect v2 = cpvadd(b->v, cpvmult(cpvperp(r2), b->w));+	+	// Calculate the damping force.+	// This really should be in the impulse solver and can produce problems when using large damping values.+	cpFloat vrn = cpvdot(cpvsub(v2, v1), n);+	cpFloat f_damp = vrn*cpfmin(dmp, 1.0f/(dt*(a->m_inv + b->m_inv)));+	+	// Apply!+	cpVect f = cpvmult(n, f_spring + f_damp);+	cpBodyApplyForce(a, f, r1);+	cpBodyApplyForce(b, cpvneg(f), r2);+}
+ Chipmunk-5.3.5/src/cpCollision.c view
@@ -0,0 +1,411 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */+ +#include <stdlib.h>+#include <math.h>+//#include <stdio.h>++#include "chipmunk_private.h"++typedef int (*collisionFunc)(const cpShape *, const cpShape *, cpContact *);++// Add contact points for circle to circle collisions.+// Used by several collision tests.+static int+circle2circleQuery(const cpVect p1, const cpVect p2, const cpFloat r1, const cpFloat r2, cpContact *con)+{+	cpFloat mindist = r1 + r2;+	cpVect delta = cpvsub(p2, p1);+	cpFloat distsq = cpvlengthsq(delta);+	if(distsq >= mindist*mindist) return 0;+	+	cpFloat dist = cpfsqrt(distsq);++	// Allocate and initialize the contact.+	cpContactInit(+		con,+		cpvadd(p1, cpvmult(delta, 0.5f + (r1 - 0.5f*mindist)/(dist ? dist : INFINITY))),+		(dist ? cpvmult(delta, 1.0f/dist) : cpv(1.0f, 0.0f)),+		dist - mindist,+		0+	);+	+	return 1;+}++// Collide circle shapes.+static int+circle2circle(const cpShape *shape1, const cpShape *shape2, cpContact *arr)+{+	cpCircleShape *circ1 = (cpCircleShape *)shape1;+	cpCircleShape *circ2 = (cpCircleShape *)shape2;+	+	return circle2circleQuery(circ1->tc, circ2->tc, circ1->r, circ2->r, arr);+}++// Collide circles to segment shapes.+static int+circle2segment(const cpShape *circleShape, const cpShape *segmentShape, cpContact *con)+{+	cpCircleShape *circ = (cpCircleShape *)circleShape;+	cpSegmentShape *seg = (cpSegmentShape *)segmentShape;+	+	// Radius sum+	cpFloat rsum = circ->r + seg->r;+	+	// Calculate normal distance from segment.+	cpFloat dn = cpvdot(seg->tn, circ->tc) - cpvdot(seg->ta, seg->tn);+	cpFloat dist = cpfabs(dn) - rsum;+	if(dist > 0.0f) return 0;+	+	// Calculate tangential distance along segment.+	cpFloat dt = -cpvcross(seg->tn, circ->tc);+	cpFloat dtMin = -cpvcross(seg->tn, seg->ta);+	cpFloat dtMax = -cpvcross(seg->tn, seg->tb);+	+	// Decision tree to decide which feature of the segment to collide with.+	if(dt < dtMin){+		if(dt < (dtMin - rsum)){+			return 0;+		} else {+			return circle2circleQuery(circ->tc, seg->ta, circ->r, seg->r, con);+		}+	} else {+		if(dt < dtMax){+			cpVect n = (dn < 0.0f) ? seg->tn : cpvneg(seg->tn);+			cpContactInit(+				con,+				cpvadd(circ->tc, cpvmult(n, circ->r + dist*0.5f)),+				n,+				dist,+				0				 +			);+			return 1;+		} else {+			if(dt < (dtMax + rsum)) {+				return circle2circleQuery(circ->tc, seg->tb, circ->r, seg->r, con);+			} else {+				return 0;+			}+		}+	}+	+	return 1;+}++// Helper function for working with contact buffers+// This used to malloc/realloc memory on the fly but was repurposed.+static cpContact *+nextContactPoint(cpContact *arr, int *numPtr)+{+	int index = *numPtr;+	+	if(index < CP_MAX_CONTACTS_PER_ARBITER){+		(*numPtr) = index + 1;+		return &arr[index];+	} else {+		return &arr[CP_MAX_CONTACTS_PER_ARBITER - 1];+	}+}++// Find the minimum separating axis for the give poly and axis list.+static inline int+findMSA(const cpPolyShape *poly, const cpPolyShapeAxis *axes, const int num, cpFloat *min_out)+{+	int min_index = 0;+	cpFloat min = cpPolyShapeValueOnAxis(poly, axes->n, axes->d);+	if(min > 0.0f) return -1;+	+	for(int i=1; i<num; i++){+		cpFloat dist = cpPolyShapeValueOnAxis(poly, axes[i].n, axes[i].d);+		if(dist > 0.0f) {+			return -1;+		} else if(dist > min){+			min = dist;+			min_index = i;+		}+	}+	+	(*min_out) = min;+	return min_index;+}++// Add contacts for probably penetrating vertexes.+// This handles the degenerate case where an overlap was detected, but no vertexes fall inside+// the opposing polygon. (like a star of david)+static inline int+findVertsFallback(cpContact *arr, const cpPolyShape *poly1, const cpPolyShape *poly2, const cpVect n, const cpFloat dist)+{+	int num = 0;+	+	for(int i=0; i<poly1->numVerts; i++){+		cpVect v = poly1->tVerts[i];+		if(cpPolyShapeContainsVertPartial(poly2, v, cpvneg(n)))+			cpContactInit(nextContactPoint(arr, &num), v, n, dist, CP_HASH_PAIR(poly1->shape.hashid, i));+	}+	+	for(int i=0; i<poly2->numVerts; i++){+		cpVect v = poly2->tVerts[i];+		if(cpPolyShapeContainsVertPartial(poly1, v, n))+			cpContactInit(nextContactPoint(arr, &num), v, n, dist, CP_HASH_PAIR(poly2->shape.hashid, i));+	}+	+	return num;+}++// Add contacts for penetrating vertexes.+static inline int+findVerts(cpContact *arr, const cpPolyShape *poly1, const cpPolyShape *poly2, const cpVect n, const cpFloat dist)+{+	int num = 0;+	+	for(int i=0; i<poly1->numVerts; i++){+		cpVect v = poly1->tVerts[i];+		if(cpPolyShapeContainsVert(poly2, v))+			cpContactInit(nextContactPoint(arr, &num), v, n, dist, CP_HASH_PAIR(poly1->shape.hashid, i));+	}+	+	for(int i=0; i<poly2->numVerts; i++){+		cpVect v = poly2->tVerts[i];+		if(cpPolyShapeContainsVert(poly1, v))+			cpContactInit(nextContactPoint(arr, &num), v, n, dist, CP_HASH_PAIR(poly2->shape.hashid, i));+	}+	+	return (num ? num : findVertsFallback(arr, poly1, poly2, n, dist));+}++// Collide poly shapes together.+static int+poly2poly(const cpShape *shape1, const cpShape *shape2, cpContact *arr)+{+	cpPolyShape *poly1 = (cpPolyShape *)shape1;+	cpPolyShape *poly2 = (cpPolyShape *)shape2;+	+	cpFloat min1;+	int mini1 = findMSA(poly2, poly1->tAxes, poly1->numVerts, &min1);+	if(mini1 == -1) return 0;+	+	cpFloat min2;+	int mini2 = findMSA(poly1, poly2->tAxes, poly2->numVerts, &min2);+	if(mini2 == -1) return 0;+	+	// There is overlap, find the penetrating verts+	if(min1 > min2)+		return findVerts(arr, poly1, poly2, poly1->tAxes[mini1].n, min1);+	else+		return findVerts(arr, poly1, poly2, cpvneg(poly2->tAxes[mini2].n), min2);+}++// Like cpPolyValueOnAxis(), but for segments.+static inline cpFloat+segValueOnAxis(const cpSegmentShape *seg, const cpVect n, const cpFloat d)+{+	cpFloat a = cpvdot(n, seg->ta) - seg->r;+	cpFloat b = cpvdot(n, seg->tb) - seg->r;+	return cpfmin(a, b) - d;+}++// Identify vertexes that have penetrated the segment.+static inline void+findPointsBehindSeg(cpContact *arr, int *num, const cpSegmentShape *seg, const cpPolyShape *poly, const cpFloat pDist, const cpFloat coef) +{+	cpFloat dta = cpvcross(seg->tn, seg->ta);+	cpFloat dtb = cpvcross(seg->tn, seg->tb);+	cpVect n = cpvmult(seg->tn, coef);+	+	for(int i=0; i<poly->numVerts; i++){+		cpVect v = poly->tVerts[i];+		if(cpvdot(v, n) < cpvdot(seg->tn, seg->ta)*coef + seg->r){+			cpFloat dt = cpvcross(seg->tn, v);+			if(dta >= dt && dt >= dtb){+				cpContactInit(nextContactPoint(arr, num), v, n, pDist, CP_HASH_PAIR(poly->shape.hashid, i));+			}+		}+	}+}++// This one is complicated and gross. Just don't go there...+// TODO: Comment me!+static int+seg2poly(const cpShape *shape1, const cpShape *shape2, cpContact *arr)+{+	cpSegmentShape *seg = (cpSegmentShape *)shape1;+	cpPolyShape *poly = (cpPolyShape *)shape2;+	cpPolyShapeAxis *axes = poly->tAxes;+	+	cpFloat segD = cpvdot(seg->tn, seg->ta);+	cpFloat minNorm = cpPolyShapeValueOnAxis(poly, seg->tn, segD) - seg->r;+	cpFloat minNeg = cpPolyShapeValueOnAxis(poly, cpvneg(seg->tn), -segD) - seg->r;+	if(minNeg > 0.0f || minNorm > 0.0f) return 0;+	+	int mini = 0;+	cpFloat poly_min = segValueOnAxis(seg, axes->n, axes->d);+	if(poly_min > 0.0f) return 0;+	for(int i=0; i<poly->numVerts; i++){+		cpFloat dist = segValueOnAxis(seg, axes[i].n, axes[i].d);+		if(dist > 0.0f){+			return 0;+		} else if(dist > poly_min){+			poly_min = dist;+			mini = i;+		}+	}+	+	int num = 0;+	+	cpVect poly_n = cpvneg(axes[mini].n);+	+	cpVect va = cpvadd(seg->ta, cpvmult(poly_n, seg->r));+	cpVect vb = cpvadd(seg->tb, cpvmult(poly_n, seg->r));+	if(cpPolyShapeContainsVert(poly, va))+		cpContactInit(nextContactPoint(arr, &num), va, poly_n, poly_min, CP_HASH_PAIR(seg->shape.hashid, 0));+	if(cpPolyShapeContainsVert(poly, vb))+		cpContactInit(nextContactPoint(arr, &num), vb, poly_n, poly_min, CP_HASH_PAIR(seg->shape.hashid, 1));++	// Floating point precision problems here.+	// This will have to do for now.+	poly_min -= cp_collision_slop;+	if(minNorm >= poly_min || minNeg >= poly_min) {+		if(minNorm > minNeg)+			findPointsBehindSeg(arr, &num, seg, poly, minNorm, 1.0f);+		else+			findPointsBehindSeg(arr, &num, seg, poly, minNeg, -1.0f);+	}+	+	// If no other collision points are found, try colliding endpoints.+	if(num == 0){+		cpVect poly_a = poly->tVerts[mini];+		cpVect poly_b = poly->tVerts[(mini + 1)%poly->numVerts];+		+		if(circle2circleQuery(seg->ta, poly_a, seg->r, 0.0f, arr))+			return 1;+			+		if(circle2circleQuery(seg->tb, poly_a, seg->r, 0.0f, arr))+			return 1;+			+		if(circle2circleQuery(seg->ta, poly_b, seg->r, 0.0f, arr))+			return 1;+			+		if(circle2circleQuery(seg->tb, poly_b, seg->r, 0.0f, arr))+			return 1;+	}++	return num;+}++// This one is less gross, but still gross.+// TODO: Comment me!+static int+circle2poly(const cpShape *shape1, const cpShape *shape2, cpContact *con)+{+	cpCircleShape *circ = (cpCircleShape *)shape1;+	cpPolyShape *poly = (cpPolyShape *)shape2;+	cpPolyShapeAxis *axes = poly->tAxes;+	+	int mini = 0;+	cpFloat min = cpvdot(axes->n, circ->tc) - axes->d - circ->r;+	for(int i=0; i<poly->numVerts; i++){+		cpFloat dist = cpvdot(axes[i].n, circ->tc) - axes[i].d - circ->r;+		if(dist > 0.0f){+			return 0;+		} else if(dist > min) {+			min = dist;+			mini = i;+		}+	}+	+	cpVect n = axes[mini].n;+	cpVect a = poly->tVerts[mini];+	cpVect b = poly->tVerts[(mini + 1)%poly->numVerts];+	cpFloat dta = cpvcross(n, a);+	cpFloat dtb = cpvcross(n, b);+	cpFloat dt = cpvcross(n, circ->tc);+		+	if(dt < dtb){+		return circle2circleQuery(circ->tc, b, circ->r, 0.0f, con);+	} else if(dt < dta) {+		cpContactInit(+			con,+			cpvsub(circ->tc, cpvmult(n, circ->r + min/2.0f)),+			cpvneg(n),+			min,+			0				 +		);+	+		return 1;+	} else {+		return circle2circleQuery(circ->tc, a, circ->r, 0.0f, con);+	}+}++//static const collisionFunc builtinCollisionFuncs[9] = {+//	circle2circle,+//	NULL,+//	NULL,+//	circle2segment,+//	NULL,+//	NULL,+//	circle2poly,+//	seg2poly,+//	poly2poly,+//};+//static const collisionFunc *colfuncs = builtinCollisionFuncs;++static collisionFunc *colfuncs = NULL;++static void+addColFunc(const cpShapeType a, const cpShapeType b, const collisionFunc func)+{+	colfuncs[a + b*CP_NUM_SHAPES] = func;+}++#ifdef __cplusplus+extern "C" {+#endif+	void cpInitCollisionFuncs(void);+	+	// Initializes the array of collision functions.+	// Called by cpInitChipmunk().+	void+	cpInitCollisionFuncs(void)+	{+		if(!colfuncs)+			colfuncs = (collisionFunc *)cpcalloc(CP_NUM_SHAPES*CP_NUM_SHAPES, sizeof(collisionFunc));+		+		addColFunc(CP_CIRCLE_SHAPE,  CP_CIRCLE_SHAPE,  circle2circle);+		addColFunc(CP_CIRCLE_SHAPE,  CP_SEGMENT_SHAPE, circle2segment);+		addColFunc(CP_SEGMENT_SHAPE, CP_POLY_SHAPE,    seg2poly);+		addColFunc(CP_CIRCLE_SHAPE,  CP_POLY_SHAPE,    circle2poly);+		addColFunc(CP_POLY_SHAPE,    CP_POLY_SHAPE,    poly2poly);+	}	+#ifdef __cplusplus+}+#endif++int+cpCollideShapes(const cpShape *a, const cpShape *b, cpContact *arr)+{+	// Their shape types must be in order.+	cpAssert(a->klass->type <= b->klass->type, "Collision shapes passed to cpCollideShapes() are not sorted.");+	+	collisionFunc cfunc = colfuncs[a->klass->type + b->klass->type*CP_NUM_SHAPES];+	return (cfunc) ? cfunc(a, b, arr) : 0;+}
+ Chipmunk-5.3.5/src/cpHashSet.c view
@@ -0,0 +1,253 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */+ +#include <stdlib.h>+#include <assert.h>++#include "chipmunk_private.h"+#include "prime.h"++static void freeWrap(void *ptr, void *unused){cpfree(ptr);}++void+cpHashSetDestroy(cpHashSet *set)+{+	// Free the table.+	cpfree(set->table);+	+	if(set->allocatedBuffers) cpArrayEach(set->allocatedBuffers, freeWrap, NULL);+	cpArrayFree(set->allocatedBuffers);+}++void+cpHashSetFree(cpHashSet *set)+{+	if(set){+		cpHashSetDestroy(set);+		cpfree(set);+	}+}++cpHashSet *+cpHashSetAlloc(void)+{+	return (cpHashSet *)cpcalloc(1, sizeof(cpHashSet));+}++cpHashSet *+cpHashSetInit(cpHashSet *set, int size, cpHashSetEqlFunc eqlFunc, cpHashSetTransFunc trans)+{+	set->size = next_prime(size);+	set->entries = 0;+	+	set->eql = eqlFunc;+	set->trans = trans;+	+	set->default_value = NULL;+	+	set->table = (cpHashSetBin **)cpcalloc(set->size, sizeof(cpHashSetBin *));+	set->pooledBins = NULL;+	+	set->allocatedBuffers = cpArrayNew(0);+	+	return set;+}++cpHashSet *+cpHashSetNew(int size, cpHashSetEqlFunc eqlFunc, cpHashSetTransFunc trans)+{+	return cpHashSetInit(cpHashSetAlloc(), size, eqlFunc, trans);+}++static int+setIsFull(cpHashSet *set)+{+	return (set->entries >= set->size);+}++static void+cpHashSetResize(cpHashSet *set)+{+	// Get the next approximate doubled prime.+	int newSize = next_prime(set->size + 1);+	// Allocate a new table.+	cpHashSetBin **newTable = (cpHashSetBin **)cpcalloc(newSize, sizeof(cpHashSetBin *));+	+	// Iterate over the chains.+	for(int i=0; i<set->size; i++){+		// Rehash the bins into the new table.+		cpHashSetBin *bin = set->table[i];+		while(bin){+			cpHashSetBin *next = bin->next;+			+			int idx = bin->hash%newSize;+			bin->next = newTable[idx];+			newTable[idx] = bin;+			+			bin = next;+		}+	}+	+	cpfree(set->table);+	+	set->table = newTable;+	set->size = newSize;+}++static inline void+recycleBin(cpHashSet *set, cpHashSetBin *bin)+{+	bin->next = set->pooledBins;+	set->pooledBins = bin;+	bin->elt = NULL;+}++static cpHashSetBin *+getUnusedBin(cpHashSet *set)+{+	cpHashSetBin *bin = set->pooledBins;+	+	if(bin){+		set->pooledBins = bin->next;+		return bin;+	} else {+		// Pool is exhausted, make more+		int count = CP_BUFFER_BYTES/sizeof(cpHashSetBin);+		cpAssert(count, "Buffer size is too small.");+		+		cpHashSetBin *buffer = (cpHashSetBin *)cpcalloc(1, CP_BUFFER_BYTES);+		cpArrayPush(set->allocatedBuffers, buffer);+		+		// push all but the first one, return the first instead+		for(int i=1; i<count; i++) recycleBin(set, buffer + i);+		return buffer;+	}+}++void *+cpHashSetInsert(cpHashSet *set, cpHashValue hash, void *ptr, void *data)+{+	int idx = hash%set->size;+	+	// Find the bin with the matching element.+	cpHashSetBin *bin = set->table[idx];+	while(bin && !set->eql(ptr, bin->elt))+		bin = bin->next;+	+	// Create it necessary.+	if(!bin){+		bin = getUnusedBin(set);+		bin->hash = hash;+		bin->elt = set->trans(ptr, data); // Transform the pointer.+		+		bin->next = set->table[idx];+		set->table[idx] = bin;+		+		set->entries++;+		+		// Resize the set if it's full.+		if(setIsFull(set))+			cpHashSetResize(set);+	}+	+	return bin->elt;+}++void *+cpHashSetRemove(cpHashSet *set, cpHashValue hash, void *ptr)+{+	int idx = hash%set->size;+	+	// Pointer to the previous bin pointer.+	cpHashSetBin **prev_ptr = &set->table[idx];+	// Pointer the the current bin.+	cpHashSetBin *bin = set->table[idx];+	+	// Find the bin+	while(bin && !set->eql(ptr, bin->elt)){+		prev_ptr = &bin->next;+		bin = bin->next;+	}+	+	// Remove it if it exists.+	if(bin){+		// Update the previous bin pointer to point to the next bin.+		(*prev_ptr) = bin->next;+		set->entries--;+		+		void *return_value = bin->elt;+		+		recycleBin(set, bin);+		+		return return_value;+	}+	+	return NULL;+}++void *+cpHashSetFind(cpHashSet *set, cpHashValue hash, void *ptr)+{	+	int idx = hash%set->size;+	cpHashSetBin *bin = set->table[idx];+	while(bin && !set->eql(ptr, bin->elt))+		bin = bin->next;+		+	return (bin ? bin->elt : set->default_value);+}++void+cpHashSetEach(cpHashSet *set, cpHashSetIterFunc func, void *data)+{+	for(int i=0; i<set->size; i++){+		cpHashSetBin *bin = set->table[i];+		while(bin){+			cpHashSetBin *next = bin->next;+			func(bin->elt, data);+			bin = next;+		}+	}+}++void+cpHashSetFilter(cpHashSet *set, cpHashSetFilterFunc func, void *data)+{+	// Iterate over all the chains.+	for(int i=0; i<set->size; i++){+		// The rest works similarly to cpHashSetRemove() above.+		cpHashSetBin **prev_ptr = &set->table[i];+		cpHashSetBin *bin = set->table[i];+		while(bin){+			cpHashSetBin *next = bin->next;+			+			if(func(bin->elt, data)){+				prev_ptr = &bin->next;+			} else {+				(*prev_ptr) = next;++				set->entries--;+				recycleBin(set, bin);+			}+			+			bin = next;+		}+	}+}
+ Chipmunk-5.3.5/src/cpPolyShape.c view
@@ -0,0 +1,240 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */+ +#include <stdlib.h>++#include "chipmunk_private.h"+#include "chipmunk_unsafe.h"++cpPolyShape *+cpPolyShapeAlloc(void)+{+	return (cpPolyShape *)cpcalloc(1, sizeof(cpPolyShape));+}++static void+cpPolyShapeTransformVerts(cpPolyShape *poly, cpVect p, cpVect rot)+{+	cpVect *src = poly->verts;+	cpVect *dst = poly->tVerts;+	+	for(int i=0; i<poly->numVerts; i++)+		dst[i] = cpvadd(p, cpvrotate(src[i], rot));+}++static void+cpPolyShapeTransformAxes(cpPolyShape *poly, cpVect p, cpVect rot)+{+	cpPolyShapeAxis *src = poly->axes;+	cpPolyShapeAxis *dst = poly->tAxes;+	+	for(int i=0; i<poly->numVerts; i++){+		cpVect n = cpvrotate(src[i].n, rot);+		dst[i].n = n;+		dst[i].d = cpvdot(p, n) + src[i].d;+	}+}++static cpBB+cpPolyShapeCacheData(cpShape *shape, cpVect p, cpVect rot)+{+	cpPolyShape *poly = (cpPolyShape *)shape;+	+	cpFloat l, b, r, t;+	+	cpPolyShapeTransformAxes(poly, p, rot);+	cpPolyShapeTransformVerts(poly, p, rot);+	+	cpVect *verts = poly->tVerts;+	l = r = verts[0].x;+	b = t = verts[0].y;+	+	// TODO do as part of cpPolyShapeTransformVerts?+	for(int i=1; i<poly->numVerts; i++){+		cpVect v = verts[i];+		+		l = cpfmin(l, v.x);+		r = cpfmax(r, v.x);+		+		b = cpfmin(b, v.y);+		t = cpfmax(t, v.y);+	}+	+	return cpBBNew(l, b, r, t);+}++static void+cpPolyShapeDestroy(cpShape *shape)+{+	cpPolyShape *poly = (cpPolyShape *)shape;+	+	cpfree(poly->verts);+	cpfree(poly->tVerts);+	+	cpfree(poly->axes);+	cpfree(poly->tAxes);+}++static cpBool+cpPolyShapePointQuery(cpShape *shape, cpVect p){+	return cpBBcontainsVect(shape->bb, p) && cpPolyShapeContainsVert((cpPolyShape *)shape, p);+}++static void+cpPolyShapeSegmentQuery(cpShape *shape, cpVect a, cpVect b, cpSegmentQueryInfo *info)+{+	cpPolyShape *poly = (cpPolyShape *)shape;+	cpPolyShapeAxis *axes = poly->tAxes;+	cpVect *verts = poly->tVerts;+	int numVerts = poly->numVerts;+	+	for(int i=0; i<numVerts; i++){+		cpVect n = axes[i].n;+		cpFloat an = cpvdot(a, n);+		if(axes[i].d > an) continue;+		+		cpFloat bn = cpvdot(b, n);+		cpFloat t = (axes[i].d - an)/(bn - an);+		if(t < 0.0f || 1.0f < t) continue;+		+		cpVect point = cpvlerp(a, b, t);+		cpFloat dt = -cpvcross(n, point);+		cpFloat dtMin = -cpvcross(n, verts[i]);+		cpFloat dtMax = -cpvcross(n, verts[(i+1)%numVerts]);+		+		if(dtMin <= dt && dt <= dtMax){+			info->shape = shape;+			info->t = t;+			info->n = n;+		}+	}+}++static const cpShapeClass polyClass = {+	CP_POLY_SHAPE,+	cpPolyShapeCacheData,+	cpPolyShapeDestroy,+	cpPolyShapePointQuery,+	cpPolyShapeSegmentQuery,+};++cpBool+cpPolyValidate(const cpVect *verts, const int numVerts)+{+	for(int i=0; i<numVerts; i++){+		cpVect a = verts[i];+		cpVect b = verts[(i+1)%numVerts];+		cpVect c = verts[(i+2)%numVerts];+		+		if(cpvcross(cpvsub(b, a), cpvsub(c, b)) > 0.0f)+			return cpFalse;+	}+	+	return cpTrue;+}++int+cpPolyShapeGetNumVerts(cpShape *shape)+{+	cpAssert(shape->klass == &polyClass, "Shape is not a poly shape.");+	return ((cpPolyShape *)shape)->numVerts;+}++cpVect+cpPolyShapeGetVert(cpShape *shape, int idx)+{+	cpAssert(shape->klass == &polyClass, "Shape is not a poly shape.");+	cpAssert(0 <= idx && idx < cpPolyShapeGetNumVerts(shape), "Index out of range.");+	+	return ((cpPolyShape *)shape)->verts[idx];+}+++static void+setUpVerts(cpPolyShape *poly, int numVerts, cpVect *verts, cpVect offset)+{+	poly->numVerts = numVerts;++	poly->verts = (cpVect *)cpcalloc(numVerts, sizeof(cpVect));+	poly->tVerts = (cpVect *)cpcalloc(numVerts, sizeof(cpVect));+	poly->axes = (cpPolyShapeAxis *)cpcalloc(numVerts, sizeof(cpPolyShapeAxis));+	poly->tAxes = (cpPolyShapeAxis *)cpcalloc(numVerts, sizeof(cpPolyShapeAxis));+	+	for(int i=0; i<numVerts; i++){+		cpVect a = cpvadd(offset, verts[i]);+		cpVect b = cpvadd(offset, verts[(i+1)%numVerts]);+		cpVect n = cpvnormalize(cpvperp(cpvsub(b, a)));++		poly->verts[i] = a;+		poly->axes[i].n = n;+		poly->axes[i].d = cpvdot(n, a);+	}+}++cpPolyShape *+cpPolyShapeInit(cpPolyShape *poly, cpBody *body, int numVerts, cpVect *verts, cpVect offset)+{+	// Fail if the user attempts to pass a concave poly, or a bad winding.+	cpAssert(cpPolyValidate(verts, numVerts), "Polygon is concave or has a reversed winding.");+	+	setUpVerts(poly, numVerts, verts, offset);+	cpShapeInit((cpShape *)poly, &polyClass, body);++	return poly;+}++cpShape *+cpPolyShapeNew(cpBody *body, int numVerts, cpVect *verts, cpVect offset)+{+	return (cpShape *)cpPolyShapeInit(cpPolyShapeAlloc(), body, numVerts, verts, offset);+}++cpPolyShape *+cpBoxShapeInit(cpPolyShape *poly, cpBody *body, cpFloat width, cpFloat height)+{+	cpFloat hw = width/2.0f;+	cpFloat hh = height/2.0f;+	+	cpVect verts[] = {+		cpv(-hw,-hh),+		cpv(-hw, hh),+		cpv( hw, hh),+		cpv( hw,-hh),+	};+	+	return cpPolyShapeInit(poly, body, 4, verts, cpvzero);+}++cpShape *+cpBoxShapeNew(cpBody *body, cpFloat width, cpFloat height)+{+	return (cpShape *)cpBoxShapeInit(cpPolyShapeAlloc(), body, width, height);+}++// Unsafe API (chipmunk_unsafe.h)++void+cpPolyShapeSetVerts(cpShape *shape, int numVerts, cpVect *verts, cpVect offset)+{+	cpAssert(shape->klass == &polyClass, "Shape is not a poly shape.");+	cpPolyShapeDestroy(shape);+	setUpVerts((cpPolyShape *)shape, numVerts, verts, offset);+}
+ Chipmunk-5.3.5/src/cpShape.c view
@@ -0,0 +1,403 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */+ +#include <stdlib.h>+#include <stdio.h>+#include <math.h>++#include "chipmunk_private.h"+#include "chipmunk_unsafe.h"++#define CP_DefineShapeGetter(struct, type, member, name) \+CP_DeclareShapeGetter(struct, type, name){ \+	cpAssert(shape->klass == &struct##Class, "shape is not a "#struct); \+	return ((struct *)shape)->member; \+}+cpHashValue SHAPE_ID_COUNTER = 0;++void+cpResetShapeIdCounter(void)+{+	SHAPE_ID_COUNTER = 0;+}+++cpShape*+cpShapeInit(cpShape *shape, const cpShapeClass *klass, cpBody *body)+{+	shape->klass = klass;+	+	shape->hashid = SHAPE_ID_COUNTER;+	SHAPE_ID_COUNTER++;+	+	shape->body = body;+	shape->sensor = 0;+	+	shape->e = 0.0f;+	shape->u = 0.0f;+	shape->surface_v = cpvzero;+	+	shape->collision_type = 0;+	shape->group = CP_NO_GROUP;+	shape->layers = CP_ALL_LAYERS;+	+	shape->data = NULL;+	shape->next = NULL;+	+//	cpShapeCacheBB(shape);+	+	return shape;+}++void+cpShapeDestroy(cpShape *shape)+{+	if(shape->klass && shape->klass->destroy) shape->klass->destroy(shape);+}++void+cpShapeFree(cpShape *shape)+{+	if(shape){+		cpShapeDestroy(shape);+		cpfree(shape);+	}+}++// TODO this function should really take a position and rotation explicitly and be renamed+cpBB+cpShapeCacheBB(cpShape *shape)+{+	cpBody *body = shape->body;+	+	shape->bb = shape->klass->cacheData(shape, body->p, body->rot);+	return shape->bb;+}++cpBool+cpShapePointQuery(cpShape *shape, cpVect p){+	return shape->klass->pointQuery(shape, p);+}++cpBool+cpShapeSegmentQuery(cpShape *shape, cpVect a, cpVect b, cpSegmentQueryInfo *info){+	cpSegmentQueryInfo blank = {NULL, 0.0f, cpvzero};+	(*info) = blank;+	+	shape->klass->segmentQuery(shape, a, b, info);+	return (info->shape != NULL);+}++void+cpSegmentQueryInfoPrint(cpSegmentQueryInfo *info)+{+	printf("Segment Query:\n");+	printf("\tt: %f\n", info->t);+//	printf("\tdist: %f\n", info->dist);+//	printf("\tpoint: %s\n", cpvstr(info->point));+	printf("\tn: %s\n", cpvstr(info->n));+}+++++cpCircleShape *+cpCircleShapeAlloc(void)+{+	return (cpCircleShape *)cpcalloc(1, sizeof(cpCircleShape));+}++static inline cpBB+bbFromCircle(const cpVect c, const cpFloat r)+{+	return cpBBNew(c.x-r, c.y-r, c.x+r, c.y+r);+}++static cpBB+cpCircleShapeCacheData(cpShape *shape, cpVect p, cpVect rot)+{+	cpCircleShape *circle = (cpCircleShape *)shape;+	+	circle->tc = cpvadd(p, cpvrotate(circle->c, rot));+	return bbFromCircle(circle->tc, circle->r);+}++static cpBool+cpCircleShapePointQuery(cpShape *shape, cpVect p){+	cpCircleShape *circle = (cpCircleShape *)shape;+	return cpvnear(circle->tc, p, circle->r);+}++static void+circleSegmentQuery(cpShape *shape, cpVect center, cpFloat r, cpVect a, cpVect b, cpSegmentQueryInfo *info)+{+	// offset the line to be relative to the circle+	a = cpvsub(a, center);+	b = cpvsub(b, center);+	+	cpFloat qa = cpvdot(a, a) - 2.0f*cpvdot(a, b) + cpvdot(b, b);+	cpFloat qb = -2.0f*cpvdot(a, a) + 2.0f*cpvdot(a, b);+	cpFloat qc = cpvdot(a, a) - r*r;+	+	cpFloat det = qb*qb - 4.0f*qa*qc;+	+	if(det >= 0.0f){+		cpFloat t = (-qb - cpfsqrt(det))/(2.0f*qa);+		if(0.0f<= t && t <= 1.0f){+			info->shape = shape;+			info->t = t;+			info->n = cpvnormalize(cpvlerp(a, b, t));+		}+	}+}++static void+cpCircleShapeSegmentQuery(cpShape *shape, cpVect a, cpVect b, cpSegmentQueryInfo *info)+{+	cpCircleShape *circle = (cpCircleShape *)shape;+	circleSegmentQuery(shape, circle->tc, circle->r, a, b, info);+}++static const cpShapeClass cpCircleShapeClass = {+	CP_CIRCLE_SHAPE,+	cpCircleShapeCacheData,+	NULL,+	cpCircleShapePointQuery,+	cpCircleShapeSegmentQuery,+};++cpCircleShape *+cpCircleShapeInit(cpCircleShape *circle, cpBody *body, cpFloat radius, cpVect offset)+{+	circle->c = offset;+	circle->r = radius;+	+	cpShapeInit((cpShape *)circle, &cpCircleShapeClass, body);+	+	return circle;+}++cpShape *+cpCircleShapeNew(cpBody *body, cpFloat radius, cpVect offset)+{+	return (cpShape *)cpCircleShapeInit(cpCircleShapeAlloc(), body, radius, offset);+}++CP_DefineShapeGetter(cpCircleShape, cpVect, c, Offset)+CP_DefineShapeGetter(cpCircleShape, cpFloat, r, Radius)++cpSegmentShape *+cpSegmentShapeAlloc(void)+{+	return (cpSegmentShape *)cpcalloc(1, sizeof(cpSegmentShape));+}++static cpBB+cpSegmentShapeCacheData(cpShape *shape, cpVect p, cpVect rot)+{+	cpSegmentShape *seg = (cpSegmentShape *)shape;+	+	seg->ta = cpvadd(p, cpvrotate(seg->a, rot));+	seg->tb = cpvadd(p, cpvrotate(seg->b, rot));+	seg->tn = cpvrotate(seg->n, rot);+	+	cpFloat l,r,s,t;+	+	if(seg->ta.x < seg->tb.x){+		l = seg->ta.x;+		r = seg->tb.x;+	} else {+		l = seg->tb.x;+		r = seg->ta.x;+	}+	+	if(seg->ta.y < seg->tb.y){+		s = seg->ta.y;+		t = seg->tb.y;+	} else {+		s = seg->tb.y;+		t = seg->ta.y;+	}+	+	cpFloat rad = seg->r;+	return cpBBNew(l - rad, s - rad, r + rad, t + rad);+}++static cpBool+cpSegmentShapePointQuery(cpShape *shape, cpVect p){+	if(!cpBBcontainsVect(shape->bb, p)) return cpFalse;+	+	cpSegmentShape *seg = (cpSegmentShape *)shape;+	+	// Calculate normal distance from segment.+	cpFloat dn = cpvdot(seg->tn, p) - cpvdot(seg->ta, seg->tn);+	cpFloat dist = cpfabs(dn) - seg->r;+	if(dist > 0.0f) return cpFalse;+	+	// Calculate tangential distance along segment.+	cpFloat dt = -cpvcross(seg->tn, p);+	cpFloat dtMin = -cpvcross(seg->tn, seg->ta);+	cpFloat dtMax = -cpvcross(seg->tn, seg->tb);+	+	// Decision tree to decide which feature of the segment to collide with.+	if(dt <= dtMin){+		if(dt < (dtMin - seg->r)){+			return cpFalse;+		} else {+			return cpvlengthsq(cpvsub(seg->ta, p)) < (seg->r*seg->r);+		}+	} else {+		if(dt < dtMax){+			return cpTrue;+		} else {+			if(dt < (dtMax + seg->r)) {+				return cpvlengthsq(cpvsub(seg->tb, p)) < (seg->r*seg->r);+			} else {+				return cpFalse;+			}+		}+	}+	+	return cpTrue;	+}++static inline cpBool inUnitRange(cpFloat t){return (0.0f < t && t < 1.0f);}++static void+cpSegmentShapeSegmentQuery(cpShape *shape, cpVect a, cpVect b, cpSegmentQueryInfo *info)+{+	// TODO this function could be optimized better.+	+	cpSegmentShape *seg = (cpSegmentShape *)shape;+	cpVect n = seg->tn;+	// flip n if a is behind the axis+	if(cpvdot(a, n) < cpvdot(seg->ta, n))+		n = cpvneg(n);+	+	cpFloat an = cpvdot(a, n);+	cpFloat bn = cpvdot(b, n);+	+	if(an != bn){+		cpFloat d = cpvdot(seg->ta, n) + seg->r;+		cpFloat t = (d - an)/(bn - an);+		+		if(0.0f < t && t < 1.0f){+			cpVect point = cpvlerp(a, b, t);+			cpFloat dt = -cpvcross(seg->tn, point);+			cpFloat dtMin = -cpvcross(seg->tn, seg->ta);+			cpFloat dtMax = -cpvcross(seg->tn, seg->tb);+			+			if(dtMin < dt && dt < dtMax){+				info->shape = shape;+				info->t = t;+				info->n = n;+				+				return; // don't continue on and check endcaps+			}+		}+	}+	+	if(seg->r) {+		cpSegmentQueryInfo info1 = {NULL, 1.0f, cpvzero};+		cpSegmentQueryInfo info2 = {NULL, 1.0f, cpvzero};+		circleSegmentQuery(shape, seg->ta, seg->r, a, b, &info1);+		circleSegmentQuery(shape, seg->tb, seg->r, a, b, &info2);+		+		if(info1.t < info2.t){+			(*info) = info1;+		} else {+			(*info) = info2;+		}+	}+}++static const cpShapeClass cpSegmentShapeClass = {+	CP_SEGMENT_SHAPE,+	cpSegmentShapeCacheData,+	NULL,+	cpSegmentShapePointQuery,+	cpSegmentShapeSegmentQuery,+};++cpSegmentShape *+cpSegmentShapeInit(cpSegmentShape *seg, cpBody *body, cpVect a, cpVect b, cpFloat r)+{+	seg->a = a;+	seg->b = b;+	seg->n = cpvperp(cpvnormalize(cpvsub(b, a)));+	+	seg->r = r;+	+	cpShapeInit((cpShape *)seg, &cpSegmentShapeClass, body);+	+	return seg;+}++cpShape*+cpSegmentShapeNew(cpBody *body, cpVect a, cpVect b, cpFloat r)+{+	return (cpShape *)cpSegmentShapeInit(cpSegmentShapeAlloc(), body, a, b, r);+}++CP_DefineShapeGetter(cpSegmentShape, cpVect, a, A)+CP_DefineShapeGetter(cpSegmentShape, cpVect, b, B)+CP_DefineShapeGetter(cpSegmentShape, cpVect, n, Normal)+CP_DefineShapeGetter(cpSegmentShape, cpFloat, r, Radius)++// Unsafe API (chipmunk_unsafe.h)++void+cpCircleShapeSetRadius(cpShape *shape, cpFloat radius)+{+	cpAssert(shape->klass == &cpCircleShapeClass, "Shape is not a circle shape.");+	cpCircleShape *circle = (cpCircleShape *)shape;+	+	circle->r = radius;+}++void+cpCircleShapeSetOffset(cpShape *shape, cpVect offset)+{+	cpAssert(shape->klass == &cpCircleShapeClass, "Shape is not a circle shape.");+	cpCircleShape *circle = (cpCircleShape *)shape;+	+	circle->c = offset;+}++void+cpSegmentShapeSetEndpoints(cpShape *shape, cpVect a, cpVect b)+{+	cpAssert(shape->klass == &cpSegmentShapeClass, "Shape is not a segment shape.");+	cpSegmentShape *seg = (cpSegmentShape *)shape;+	+	seg->a = a;+	seg->b = b;+	seg->n = cpvperp(cpvnormalize(cpvsub(b, a)));+}++void+cpSegmentShapeSetRadius(cpShape *shape, cpFloat radius)+{+	cpAssert(shape->klass == &cpSegmentShapeClass, "Shape is not a segment shape.");+	cpSegmentShape *seg = (cpSegmentShape *)shape;+	+	seg->r = radius;+}
+ Chipmunk-5.3.5/src/cpSpace.c view
@@ -0,0 +1,501 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */+ +#include <stdlib.h>+//#include <stdio.h>+#include <string.h>+#include <math.h>++#include "chipmunk_private.h"++cpTimestamp cp_contact_persistence = 3;++#pragma mark Contact Set Helpers++// Equal function for contactSet.+static cpBool+contactSetEql(cpShape **shapes, cpArbiter *arb)+{+	cpShape *a = shapes[0];+	cpShape *b = shapes[1];+	+	return ((a == arb->a && b == arb->b) || (b == arb->a && a == arb->b));+}++// Transformation function for contactSet.+static void *+contactSetTrans(cpShape **shapes, cpSpace *space)+{+	if(space->pooledArbiters->num == 0){+		// arbiter pool is exhausted, make more+		int count = CP_BUFFER_BYTES/sizeof(cpArbiter);+		cpAssert(count, "Buffer size too small.");+		+		cpArbiter *buffer = (cpArbiter *)cpcalloc(1, CP_BUFFER_BYTES);+		cpArrayPush(space->allocatedBuffers, buffer);+		+		for(int i=0; i<count; i++) cpArrayPush(space->pooledArbiters, buffer + i);+	}+	+	return cpArbiterInit((cpArbiter *) cpArrayPop(space->pooledArbiters), shapes[0], shapes[1]);+}++#pragma mark Collision Pair Function Helpers++// Equals function for collFuncSet.+static cpBool+collFuncSetEql(cpCollisionHandler *check, cpCollisionHandler *pair)+{+	return ((check->a == pair->a && check->b == pair->b) || (check->b == pair->a && check->a == pair->b));+}++// Transformation function for collFuncSet.+static void *+collFuncSetTrans(cpCollisionHandler *handler, void *unused)+{+	cpCollisionHandler *copy = (cpCollisionHandler *)cpcalloc(1, sizeof(cpCollisionHandler));+	(*copy) = (*handler);+	+	return copy;+}++#pragma mark Misc Helper Funcs++// Default collision functions.+static cpBool alwaysCollide(cpArbiter *arb, cpSpace *space, void *data){return 1;}+static void nothing(cpArbiter *arb, cpSpace *space, void *data){}++// BBfunc callback for the spatial hash.+static cpBB shapeBBFunc(cpShape *shape){return shape->bb;}++// Iterator functions for destructors.+static void             freeWrap(void         *ptr, void *unused){            cpfree(ptr);}+static void        shapeFreeWrap(cpShape      *ptr, void *unused){     cpShapeFree(ptr);}+static void         bodyFreeWrap(cpBody       *ptr, void *unused){      cpBodyFree(ptr);}+static void   constraintFreeWrap(cpConstraint *ptr, void *unused){cpConstraintFree(ptr);}++#pragma mark Memory Management Functions++cpSpace *+cpSpaceAlloc(void)+{+	return (cpSpace *)cpcalloc(1, sizeof(cpSpace));+}++#define DEFAULT_DIM_SIZE 100.0f+#define DEFAULT_COUNT 1000+#define DEFAULT_ITERATIONS 10+#define DEFAULT_ELASTIC_ITERATIONS 0++cpCollisionHandler cpSpaceDefaultHandler = {0, 0, alwaysCollide, alwaysCollide, nothing, nothing, NULL};++cpSpace*+cpSpaceInit(cpSpace *space)+{+	space->iterations = DEFAULT_ITERATIONS;+	space->elasticIterations = DEFAULT_ELASTIC_ITERATIONS;+//	space->sleepTicks = 300;+	+	space->gravity = cpvzero;+	space->damping = 1.0f;+	+	space->locked = 0;+	space->stamp = 0;++	space->staticShapes = cpSpaceHashNew(DEFAULT_DIM_SIZE, DEFAULT_COUNT, (cpSpaceHashBBFunc)shapeBBFunc);+	space->activeShapes = cpSpaceHashNew(DEFAULT_DIM_SIZE, DEFAULT_COUNT, (cpSpaceHashBBFunc)shapeBBFunc);+	+	space->allocatedBuffers = cpArrayNew(0);+	+	space->bodies = cpArrayNew(0);+	space->sleepingComponents = cpArrayNew(0);+	space->rousedBodies = cpArrayNew(0);+	+	space->sleepTimeThreshold = INFINITY;+	space->idleSpeedThreshold = 0.0f;+	+	space->arbiters = cpArrayNew(0);+	space->pooledArbiters = cpArrayNew(0);+	+	space->contactBuffersHead = NULL;+	space->contactSet = cpHashSetNew(0, (cpHashSetEqlFunc)contactSetEql, (cpHashSetTransFunc)contactSetTrans);+	+	space->constraints = cpArrayNew(0);+	+	space->defaultHandler = cpSpaceDefaultHandler;+	space->collFuncSet = cpHashSetNew(0, (cpHashSetEqlFunc)collFuncSetEql, (cpHashSetTransFunc)collFuncSetTrans);+	space->collFuncSet->default_value = &cpSpaceDefaultHandler;+	+	space->postStepCallbacks = NULL;+	+	cpBodyInitStatic(&space->staticBody);+	+	return space;+}++cpSpace*+cpSpaceNew(void)+{+	return cpSpaceInit(cpSpaceAlloc());+}++void+cpSpaceDestroy(cpSpace *space)+{+	cpSpaceHashFree(space->staticShapes);+	cpSpaceHashFree(space->activeShapes);+	+	cpArrayFree(space->bodies);+	cpArrayFree(space->sleepingComponents);+	cpArrayFree(space->rousedBodies);+	+	cpArrayFree(space->constraints);+	+	cpHashSetFree(space->contactSet);+	+	cpArrayFree(space->arbiters);+	cpArrayFree(space->pooledArbiters);+	+	if(space->allocatedBuffers) cpArrayEach(space->allocatedBuffers, freeWrap, NULL);+	cpArrayFree(space->allocatedBuffers);+	+	if(space->postStepCallbacks) cpHashSetEach(space->postStepCallbacks, freeWrap, NULL);+	cpHashSetFree(space->postStepCallbacks);+	+	if(space->collFuncSet) cpHashSetEach(space->collFuncSet, freeWrap, NULL);+	cpHashSetFree(space->collFuncSet);+}++void+cpSpaceFree(cpSpace *space)+{+	if(space){+		cpSpaceDestroy(space);+		cpfree(space);+	}+}++void+cpSpaceFreeChildren(cpSpace *space)+{+	cpArray *components = space->sleepingComponents;+	while(components->num) cpBodyActivate((cpBody *)components->arr[0]);+	+	cpSpaceHashEach(space->staticShapes, (cpSpaceHashIterator)&shapeFreeWrap, NULL);+	cpSpaceHashEach(space->activeShapes, (cpSpaceHashIterator)&shapeFreeWrap, NULL);+	cpArrayEach(space->bodies,           (cpArrayIter)&bodyFreeWrap,          NULL);+	cpArrayEach(space->constraints,      (cpArrayIter)&constraintFreeWrap,    NULL);+}++#define cpAssertSpaceUnlocked(space) \+	cpAssert(!space->locked, \+		"This addition/removal cannot be done safely during a call to cpSpaceStep() or during a query. " \+		"Put these calls into a post-step callback." \+	);++#pragma mark Collision Handler Function Management++void+cpSpaceAddCollisionHandler(+	cpSpace *space,+	cpCollisionType a, cpCollisionType b,+	cpCollisionBeginFunc begin,+	cpCollisionPreSolveFunc preSolve,+	cpCollisionPostSolveFunc postSolve,+	cpCollisionSeparateFunc separate,+	void *data+){+	cpAssertSpaceUnlocked(space);+	+	// Remove any old function so the new one will get added.+	cpSpaceRemoveCollisionHandler(space, a, b);+	+	cpCollisionHandler handler = {+		a, b,+		begin ? begin : alwaysCollide,+		preSolve ? preSolve : alwaysCollide,+		postSolve ? postSolve : nothing,+		separate ? separate : nothing,+		data+	};+	+	cpHashSetInsert(space->collFuncSet, CP_HASH_PAIR(a, b), &handler, NULL);+}++void+cpSpaceRemoveCollisionHandler(cpSpace *space, cpCollisionType a, cpCollisionType b)+{+	cpAssertSpaceUnlocked(space);+	+	struct{cpCollisionType a, b;} ids = {a, b};+	cpCollisionHandler *old_handler = (cpCollisionHandler *) cpHashSetRemove(space->collFuncSet, CP_HASH_PAIR(a, b), &ids);+	cpfree(old_handler);+}++void+cpSpaceSetDefaultCollisionHandler(+	cpSpace *space,+	cpCollisionBeginFunc begin,+	cpCollisionPreSolveFunc preSolve,+	cpCollisionPostSolveFunc postSolve,+	cpCollisionSeparateFunc separate,+	void *data+){+	cpAssertSpaceUnlocked(space);+	+	cpCollisionHandler handler = {+		0, 0,+		begin ? begin : alwaysCollide,+		preSolve ? preSolve : alwaysCollide,+		postSolve ? postSolve : nothing,+		separate ? separate : nothing,+		data+	};+	+	space->defaultHandler = handler;+	space->collFuncSet->default_value = &space->defaultHandler;+}++#pragma mark Body, Shape, and Joint Management+static void+cpBodyAddShape(cpBody *body, cpShape *shape)+{+	shape->next = shape->body->shapesList;+	shape->body->shapesList = shape;+}++static void+cpBodyRemoveShape(cpBody *body, cpShape *shape)+{+	cpShape **prev_ptr = &body->shapesList;+	cpShape *node = body->shapesList;+	+	while(node && node != shape){+		prev_ptr = &node->next;+		node = node->next;+	}+	+	cpAssert(node, "Attempted to remove a shape from a body it was never attached to.");+	(*prev_ptr) = node->next;+}++cpShape *+cpSpaceAddShape(cpSpace *space, cpShape *shape)+{+	cpBody *body = shape->body;+	if(!body || cpBodyIsStatic(body)) return cpSpaceAddStaticShape(space, shape);+	+	cpAssert(!cpHashSetFind(space->activeShapes->handleSet, shape->hashid, shape),+		"Cannot add the same shape more than once.");+	cpAssertSpaceUnlocked(space);+	+	cpBodyActivate(body);+	cpBodyAddShape(body, shape);+	+	cpShapeCacheBB(shape);+	cpSpaceHashInsert(space->activeShapes, shape, shape->hashid, shape->bb);+		+	return shape;+}++cpShape *+cpSpaceAddStaticShape(cpSpace *space, cpShape *shape)+{+	cpAssert(!cpHashSetFind(space->staticShapes->handleSet, shape->hashid, shape),+		"Cannot add the same static shape more than once.");+	cpAssertSpaceUnlocked(space);+	+	if(!shape->body) shape->body = &space->staticBody;+	+	cpShapeCacheBB(shape);+	cpSpaceActivateShapesTouchingShape(space, shape);+	cpSpaceHashInsert(space->staticShapes, shape, shape->hashid, shape->bb);+	+	return shape;+}++cpBody *+cpSpaceAddBody(cpSpace *space, cpBody *body)+{+	cpAssertWarn(!cpBodyIsStatic(body), "Static bodies cannot be added to a space as they are not meant to be simulated.");+	cpAssert(!body->space, "Cannot add a body to a more than one space or to the same space twice.");+//	cpAssertSpaceUnlocked(space); This should be safe as long as it's not from an integration callback+	+	cpArrayPush(space->bodies, body);+	body->space = space;+	+	return body;+}++cpConstraint *+cpSpaceAddConstraint(cpSpace *space, cpConstraint *constraint)+{+	cpAssert(!cpArrayContains(space->constraints, constraint), "Cannot add the same constraint more than once.");+//	cpAssertSpaceUnlocked(space); This should be safe as long as its not from a constraint callback.+	+	if(!constraint->a) constraint->a = &space->staticBody;+	if(!constraint->b) constraint->b = &space->staticBody;+	+	cpBodyActivate(constraint->a);+	cpBodyActivate(constraint->b);+	cpArrayPush(space->constraints, constraint);+	+	return constraint;+}++typedef struct removalContext {+	cpSpace *space;+	cpShape *shape;+} removalContext;++// Hashset filter func to throw away old arbiters.+static cpBool+contactSetFilterRemovedShape(cpArbiter *arb, removalContext *context)+{+	if(context->shape == arb->a || context->shape == arb->b){+		if(arb->state != cpArbiterStateCached){+			arb->handler->separate(arb, context->space, arb->handler->data);+		}+		+		cpArrayPush(context->space->pooledArbiters, arb);+		return cpFalse;+	}+	+	return cpTrue;+}++void+cpSpaceRemoveShape(cpSpace *space, cpShape *shape)+{+	cpBody *body = shape->body;+	if(cpBodyIsStatic(body)){+		cpSpaceRemoveStaticShape(space, shape);+		return;+	}++	cpBodyActivate(body);+	+	cpAssertSpaceUnlocked(space);+	cpAssertWarn(cpHashSetFind(space->activeShapes->handleSet, shape->hashid, shape),+		"Cannot remove a shape that was not added to the space. (Removed twice maybe?)");+	+	cpBodyRemoveShape(body, shape);+	+	removalContext context = {space, shape};+	cpHashSetFilter(space->contactSet, (cpHashSetFilterFunc)contactSetFilterRemovedShape, &context);+	cpSpaceHashRemove(space->activeShapes, shape, shape->hashid);+}++void+cpSpaceRemoveStaticShape(cpSpace *space, cpShape *shape)+{+	cpAssertWarn(cpHashSetFind(space->staticShapes->handleSet, shape->hashid, shape),+		"Cannot remove a static or sleeping shape that was not added to the space. (Removed twice maybe?)");+	cpAssertSpaceUnlocked(space);+	+	removalContext context = {space, shape};+	cpHashSetFilter(space->contactSet, (cpHashSetFilterFunc)contactSetFilterRemovedShape, &context);+	cpSpaceHashRemove(space->staticShapes, shape, shape->hashid);+	+	cpSpaceActivateShapesTouchingShape(space, shape);+}++void+cpSpaceRemoveBody(cpSpace *space, cpBody *body)+{+	cpAssertWarn(body->space == space,+		"Cannot remove a body that was not added to the space. (Removed twice maybe?)");+	cpAssertSpaceUnlocked(space);+	+	cpBodyActivate(body);+	cpArrayDeleteObj(space->bodies, body);+	body->space = NULL;+}++void+cpSpaceRemoveConstraint(cpSpace *space, cpConstraint *constraint)+{+	cpAssertWarn(cpArrayContains(space->constraints, constraint),+		"Cannot remove a constraint that was not added to the space. (Removed twice maybe?)");+//	cpAssertSpaceUnlocked(space); Should be safe as long as its not from a constraint callback.+	+	cpBodyActivate(constraint->a);+	cpBodyActivate(constraint->b);+	cpArrayDeleteObj(space->constraints, constraint);+}++#pragma mark Spatial Hash Management++static void updateBBCache(cpShape *shape, void *unused){cpShapeCacheBB(shape);}++void+cpSpaceResizeStaticHash(cpSpace *space, cpFloat dim, int count)+{+	cpSpaceHashResize(space->staticShapes, dim, count);+	cpSpaceHashRehash(space->staticShapes);+}++void+cpSpaceResizeActiveHash(cpSpace *space, cpFloat dim, int count)+{+	cpSpaceHashResize(space->activeShapes, dim, count);+}++void +cpSpaceRehashStatic(cpSpace *space)+{+	cpSpaceHashEach(space->staticShapes, (cpSpaceHashIterator)&updateBBCache, NULL);+	cpSpaceHashRehash(space->staticShapes);+}++void+cpSpaceRehashShape(cpSpace *space, cpShape *shape)+{+	cpShapeCacheBB(shape);+	+	// attempt to rehash the shape in both hashes+	cpSpaceHashRehashObject(space->activeShapes, shape, shape->hashid);+	cpSpaceHashRehashObject(space->staticShapes, shape, shape->hashid);+}++void+cpSpaceEachBody(cpSpace *space, cpSpaceBodyIterator func, void *data)+{+	cpSpaceLock(space); {+		cpArray *bodies = space->bodies;+		+		for(int i=0; i<bodies->num; i++){+			func((cpBody *)bodies->arr[i], data);+		}+		+		cpArray *components = space->sleepingComponents;+		for(int i=0; i<components->num; i++){+			cpBody *root = (cpBody *)components->arr[i];+			cpBody *body = root, *next;+			do {+				next = body->node.next;+				func(body, data);+			} while((body = next) != root);+		}+	} cpSpaceUnlock(space);+}++
+ Chipmunk-5.3.5/src/cpSpaceComponent.c view
@@ -0,0 +1,282 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */+ +#include <stdlib.h>++#include "chipmunk_private.h"++#pragma mark Sleeping Functions++// Chipmunk uses a data structure called a disjoint set forest.+// My attempts to find a way to splice circularly linked lists in+// constant time failed, and so I found this neat data structure instead.++static inline cpBody *+componentNodeRoot(cpBody *body)+{+	cpBody *parent = body->node.parent;+	+	if(parent){+		// path compression, attaches this node directly to the root+		return (body->node.parent = componentNodeRoot(parent));+	} else {+		return body;+	}+}++static inline void+componentNodeMerge(cpBody *a_root, cpBody *b_root)+{+	if(a_root->node.rank < b_root->node.rank){+		a_root->node.parent = b_root;+	} else if(a_root->node.rank > b_root->node.rank){+		b_root->node.parent = a_root;+	} else if(a_root != b_root){+		b_root->node.parent = a_root;+		a_root->node.rank++;+	}+}++void+cpSpaceActivateBody(cpSpace *space, cpBody *body)+{+	if(space->locked){+		// cpSpaceActivateBody() is called again once the space is unlocked+		cpArrayPush(space->rousedBodies, body);+	} else {+		cpArrayPush(space->bodies, body);+		for(cpShape *shape=body->shapesList; shape; shape=shape->next){+			cpSpaceHashRemove(space->staticShapes, shape, shape->hashid);+			cpSpaceHashInsert(space->activeShapes, shape, shape->hashid, shape->bb);+		}+	}+}++static inline void+componentActivate(cpBody *root)+{+	if(!cpBodyIsSleeping(root)) return;+	+	cpSpace *space = root->space;+	cpAssert(space, "Trying to activate a body that was never added to a space.");+	+	cpBody *body = root, *next;+	do {+		next = body->node.next;+		+		cpComponentNode node = {NULL, NULL, 0, 0.0f};+		body->node = node;+		+		cpSpaceActivateBody(space, body);+	} while((body = next) != root);+	+	cpArrayDeleteObj(space->sleepingComponents, root);+}++void+cpBodyActivate(cpBody *body)+{+	if(!cpBodyIsRogue(body)){+		body->node.idleTime = 0.0f;+		componentActivate(componentNodeRoot(body));+	}+}++static inline void+mergeBodies(cpSpace *space, cpArray *components, cpArray *rogueBodies, cpBody *a, cpBody *b)+{+	// Ignore connections to static bodies+	if(cpBodyIsStatic(a) || cpBodyIsStatic(b)) return;+	+	cpBody *a_root = componentNodeRoot(a);+	cpBody *b_root = componentNodeRoot(b);+	+	cpBool a_sleep = cpBodyIsSleeping(a_root);+	cpBool b_sleep = cpBodyIsSleeping(b_root);+	+	if(a_sleep && b_sleep){+		return;+	} else if(a_sleep || b_sleep){+		componentActivate(a_root);+		componentActivate(b_root);+	} +	+	// Add any rogue bodies found to the list and reset the idle time of anything they touch.+	if(cpBodyIsRogue(a)){ cpArrayPush(rogueBodies, a); b->node.idleTime = 0.0f; }+	if(cpBodyIsRogue(b)){ cpArrayPush(rogueBodies, b); a->node.idleTime = 0.0f; }+	+	componentNodeMerge(a_root, b_root);+}++static inline cpBool+componentActive(cpBody *root, cpFloat threshold)+{+	cpBody *body = root, *next;+	do {+		next = body->node.next;+		if(body->node.idleTime < threshold) return cpTrue;+	} while((body = next) != root);+	+	return cpFalse;+}++static inline void+addToComponent(cpBody *body, cpArray *components)+{+	// Check that the body is not already added to the component list+	if(body->node.next) return;+	cpBody *root = componentNodeRoot(body);+	+	cpBody *next = root->node.next;+	if(!next){+		// If the root isn't part of a list yet, then it hasn't been+		// added to the components list. Do that now.+		cpArrayPush(components, root);+		// Start the list+		body->node.next = root;+		root->node.next = body;+	} else if(root != body) {+		// Splice in body after the root.+		body->node.next = next;+		root->node.next = body;+	}+}++// TODO this function needs more commenting.+void+cpSpaceProcessComponents(cpSpace *space, cpFloat dt)+{+	cpArray *bodies = space->bodies;+	cpArray *newBodies = cpArrayNew(bodies->num);+	cpArray *rogueBodies = cpArrayNew(16);+	cpArray *arbiters = space->arbiters;+	cpArray *constraints = space->constraints;+	cpArray *components = cpArrayNew(space->sleepingComponents->num);+	+	cpFloat dv = space->idleSpeedThreshold;+	cpFloat dvsq = (dv ? dv*dv : cpvdot(space->gravity, space->gravity)*dt*dt);+	+	// update idling+	for(int i=0; i<bodies->num; i++){+		cpBody *body = (cpBody*)bodies->arr[i];+		+		cpFloat thresh = (dvsq ? body->m*dvsq : 0.0f);+		body->node.idleTime = (cpBodyKineticEnergy(body) > thresh ? 0.0f : body->node.idleTime + dt);+	}+	+	// iterate graph edges and build forests+	for(int i=0; i<arbiters->num; i++){+		cpArbiter *arb = (cpArbiter*)arbiters->arr[i];+		mergeBodies(space, components, rogueBodies, arb->a->body, arb->b->body);+	}+	for(int j=0; j<constraints->num; j++){+		cpConstraint *constraint = (cpConstraint *)constraints->arr[j];+		mergeBodies(space, components, rogueBodies, constraint->a, constraint->b);+	}+	+	// iterate bodies and add them to their components+	for(int i=0; i<bodies->num; i++) addToComponent((cpBody*)bodies->arr[i], components);+	for(int i=0; i<rogueBodies->num; i++) addToComponent((cpBody*)rogueBodies->arr[i], components);+	+	// iterate components, copy or deactivate+	for(int i=0; i<components->num; i++){+		cpBody *root = (cpBody*)components->arr[i];+		if(componentActive(root, space->sleepTimeThreshold)){+			cpBody *body = root, *next;+			do {+				next = body->node.next;+				+				if(!cpBodyIsRogue(body)) cpArrayPush(newBodies, body);+				cpComponentNode node = {NULL, NULL, 0, body->node.idleTime};+				body->node = node;+			} while((body = next) != root);+		} else {+			cpBody *body = root, *next;+			do {+				next = body->node.next;+				+				for(cpShape *shape = body->shapesList; shape; shape = shape->next){+					cpSpaceHashRemove(space->activeShapes, shape, shape->hashid);+					cpSpaceHashInsert(space->staticShapes, shape, shape->hashid, shape->bb);+				}+			} while((body = next) != root);+			+			cpArrayPush(space->sleepingComponents, root);+		}+	}+	+	space->bodies = newBodies;+	cpArrayFree(bodies);+	cpArrayFree(rogueBodies);+	cpArrayFree(components);+}++void+cpBodySleep(cpBody *body)+{+	cpBodySleepWithGroup(body, NULL);+}++void+cpBodySleepWithGroup(cpBody *body, cpBody *group){+	cpAssert(!cpBodyIsStatic(body) && !cpBodyIsRogue(body), "Rogue and static bodies cannot be put to sleep.");+	+	cpSpace *space = body->space;+	cpAssert(space, "Cannot put a body to sleep that has not been added to a space.");+	cpAssert(!space->locked, "Bodies can not be put to sleep during a query or a call to cpSpaceSte(). Put these calls into a post-step callback.");+	cpAssert(!group || cpBodyIsSleeping(group), "Cannot use a non-sleeping body as a group identifier.");+	+	if(cpBodyIsSleeping(body)) return;+	+	for(cpShape *shape = body->shapesList; shape; shape = shape->next){+		cpShapeCacheBB(shape);+		cpSpaceHashRemove(space->activeShapes, shape, shape->hashid);+		cpSpaceHashInsert(space->staticShapes, shape, shape->hashid, shape->bb);+	}+	+	if(group){+		cpBody *root = componentNodeRoot(group);+		+		cpComponentNode node = {root, root->node.next, 0, 0.0f};+		body->node = node;+		root->node.next = body;+	} else {+		cpComponentNode node = {NULL, body, 0, 0.0f};+		body->node = node;+		+		cpArrayPush(space->sleepingComponents, body);+	}+	+	cpArrayDeleteObj(space->bodies, body);+}++static void+activateTouchingHelper(cpShape *shape, cpContactPointSet *points, cpArray **bodies){+	cpBodyActivate(shape->body);+}++void+cpSpaceActivateShapesTouchingShape(cpSpace *space, cpShape *shape){+	cpArray *bodies = NULL;+	cpSpaceShapeQuery(space, shape, (cpSpaceShapeQueryFunc)activateTouchingHelper, &bodies);+}++
+ Chipmunk-5.3.5/src/cpSpaceHash.c view
@@ -0,0 +1,534 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */++#include <math.h>+#include <stdlib.h>++#include "chipmunk_private.h"+#include "prime.h"++static cpHandle*+cpHandleInit(cpHandle *hand, void *obj)+{+	hand->obj = obj;+	hand->retain = 0;+	hand->stamp = 0;+	+	return hand;+}++static inline void cpHandleRetain(cpHandle *hand){hand->retain++;}++static inline void+cpHandleRelease(cpHandle *hand, cpArray *pooledHandles)+{+	hand->retain--;+	if(hand->retain == 0) cpArrayPush(pooledHandles, hand);+}++cpSpaceHash*+cpSpaceHashAlloc(void)+{+	return (cpSpaceHash *)cpcalloc(1, sizeof(cpSpaceHash));+}++// Frees the old table, and allocate a new one.+static void+cpSpaceHashAllocTable(cpSpaceHash *hash, int numcells)+{+	cpfree(hash->table);+	+	hash->numcells = numcells;+	hash->table = (cpSpaceHashBin **)cpcalloc(numcells, sizeof(cpSpaceHashBin *));+}++// Equality function for the handleset.+static int handleSetEql(void *obj, cpHandle *hand){return (obj == hand->obj);}++// Transformation function for the handleset.+static void *+handleSetTrans(void *obj, cpSpaceHash *hash)+{+	if(hash->pooledHandles->num == 0){+		// handle pool is exhausted, make more+		int count = CP_BUFFER_BYTES/sizeof(cpHandle);+		cpAssert(count, "Buffer size is too small.");+		+		cpHandle *buffer = (cpHandle *)cpcalloc(1, CP_BUFFER_BYTES);+		cpArrayPush(hash->allocatedBuffers, buffer);+		+		for(int i=0; i<count; i++) cpArrayPush(hash->pooledHandles, buffer + i);+	}+	+	cpHandle *hand = cpHandleInit((cpHandle *) cpArrayPop(hash->pooledHandles), obj);+	cpHandleRetain(hand);+	+	return hand;+}++cpSpaceHash*+cpSpaceHashInit(cpSpaceHash *hash, cpFloat celldim, int numcells, cpSpaceHashBBFunc bbfunc)+{+	cpSpaceHashAllocTable(hash, next_prime(numcells));+	hash->celldim = celldim;+	hash->bbfunc = bbfunc;+	+	hash->handleSet = cpHashSetNew(0, (cpHashSetEqlFunc)handleSetEql, (cpHashSetTransFunc)handleSetTrans);+	hash->pooledHandles = cpArrayNew(0);+	+	hash->pooledBins = NULL;+	hash->allocatedBuffers = cpArrayNew(0);+	+	hash->stamp = 1;+	+	return hash;+}++cpSpaceHash*+cpSpaceHashNew(cpFloat celldim, int cells, cpSpaceHashBBFunc bbfunc)+{+	return cpSpaceHashInit(cpSpaceHashAlloc(), celldim, cells, bbfunc);+}++static inline void+recycleBin(cpSpaceHash *hash, cpSpaceHashBin *bin)+{+	bin->next = hash->pooledBins;+	hash->pooledBins = bin;+}++static inline void+clearHashCell(cpSpaceHash *hash, int idx)+{+	cpSpaceHashBin *bin = hash->table[idx];+	while(bin){+		cpSpaceHashBin *next = bin->next;+		+		cpHandleRelease(bin->handle, hash->pooledHandles);+		recycleBin(hash, bin);+		+		bin = next;+	}+	+	hash->table[idx] = NULL;+}++// Clear all cells in the hashtable.+static void+clearHash(cpSpaceHash *hash)+{+	for(int i=0; i<hash->numcells; i++)+		clearHashCell(hash, i);+}++static void freeWrap(void *ptr, void *unused){cpfree(ptr);}++void+cpSpaceHashDestroy(cpSpaceHash *hash)+{+	if(hash->table) clearHash(hash);+	cpfree(hash->table);+	+	cpHashSetFree(hash->handleSet);+	+	if(hash->allocatedBuffers) cpArrayEach(hash->allocatedBuffers, freeWrap, NULL);+	cpArrayFree(hash->allocatedBuffers);+	+	cpArrayFree(hash->pooledHandles);+}++void+cpSpaceHashFree(cpSpaceHash *hash)+{+	if(hash){+		cpSpaceHashDestroy(hash);+		cpfree(hash);+	}+}++void+cpSpaceHashResize(cpSpaceHash *hash, cpFloat celldim, int numcells)+{+	// Clear the hash to release the old handle locks.+	clearHash(hash);+	+	hash->celldim = celldim;+	cpSpaceHashAllocTable(hash, next_prime(numcells));+}++// Return true if the chain contains the handle.+static inline cpBool+containsHandle(cpSpaceHashBin *bin, cpHandle *hand)+{+	while(bin){+		if(bin->handle == hand) return cpTrue;+		bin = bin->next;+	}+	+	return cpFalse;+}++// Get a recycled or new bin.+static inline cpSpaceHashBin *+getEmptyBin(cpSpaceHash *hash)+{+	cpSpaceHashBin *bin = hash->pooledBins;+	+	if(bin){+		hash->pooledBins = bin->next;+		return bin;+	} else {+		// Pool is exhausted, make more+		int count = CP_BUFFER_BYTES/sizeof(cpSpaceHashBin);+		cpAssert(count, "Buffer size is too small.");+		+		cpSpaceHashBin *buffer = (cpSpaceHashBin *)cpcalloc(1, CP_BUFFER_BYTES);+		cpArrayPush(hash->allocatedBuffers, buffer);+		+		// push all but the first one, return the first instead+		for(int i=1; i<count; i++) recycleBin(hash, buffer + i);+		return buffer;+	}+}++// The hash function itself.+static inline cpHashValue+hash_func(cpHashValue x, cpHashValue y, cpHashValue n)+{+	return (x*1640531513ul ^ y*2654435789ul) % n;+}++// Much faster than (int)floor(f)+// Profiling showed floor() to be a sizable performance hog+static inline int+floor_int(cpFloat f)+{+	int i = (int)f;+	return (f < 0.0f && f != i ? i - 1 : i);+}++static inline void+hashHandle(cpSpaceHash *hash, cpHandle *hand, cpBB bb)+{+	// Find the dimensions in cell coordinates.+	cpFloat dim = hash->celldim;+	int l = floor_int(bb.l/dim); // Fix by ShiftZ+	int r = floor_int(bb.r/dim);+	int b = floor_int(bb.b/dim);+	int t = floor_int(bb.t/dim);+	+	int n = hash->numcells;+	for(int i=l; i<=r; i++){+		for(int j=b; j<=t; j++){+			int idx = hash_func(i,j,n);+			cpSpaceHashBin *bin = hash->table[idx];+			+			// Don't add an object twice to the same cell.+			if(containsHandle(bin, hand)) continue;++			cpHandleRetain(hand);+			// Insert a new bin for the handle in this cell.+			cpSpaceHashBin *newBin = getEmptyBin(hash);+			newBin->handle = hand;+			newBin->next = bin;+			hash->table[idx] = newBin;+		}+	}+}++void+cpSpaceHashInsert(cpSpaceHash *hash, void *obj, cpHashValue hashid, cpBB _deprecated_unused)+{+	cpHandle *hand = (cpHandle *)cpHashSetInsert(hash->handleSet, hashid, obj, hash);+	hashHandle(hash, hand, hash->bbfunc(obj));+}++void+cpSpaceHashRehashObject(cpSpaceHash *hash, void *obj, cpHashValue hashid)+{+	cpHandle *hand = (cpHandle *)cpHashSetRemove(hash->handleSet, hashid, obj);+	+	if(hand){+		hand->obj = NULL;+		cpHandleRelease(hand, hash->pooledHandles);+		+		cpSpaceHashInsert(hash, obj, hashid, cpBBNew(0.0f, 0.0f, 0.0f, 0.0f));+	}+}++static void handleRehashHelper(cpHandle *hand, cpSpaceHash *hash){hashHandle(hash, hand, hash->bbfunc(hand->obj));}++void+cpSpaceHashRehash(cpSpaceHash *hash)+{+	clearHash(hash);+	cpHashSetEach(hash->handleSet, (cpHashSetIterFunc)handleRehashHelper, hash);+}++void+cpSpaceHashRemove(cpSpaceHash *hash, void *obj, cpHashValue hashid)+{+	cpHandle *hand = (cpHandle *)cpHashSetRemove(hash->handleSet, hashid, obj);+	+	if(hand){+		hand->obj = NULL;+		cpHandleRelease(hand, hash->pooledHandles);+	}+}++typedef struct eachPair {+	cpSpaceHashIterator func;+	void *data;+} eachPair;++static void eachHelper(cpHandle *hand, eachPair *pair){pair->func(hand->obj, pair->data);}++// Iterate over the objects in the spatial hash.+void+cpSpaceHashEach(cpSpaceHash *hash, cpSpaceHashIterator func, void *data)+{+	eachPair pair = {func, data};+	cpHashSetEach(hash->handleSet, (cpHashSetIterFunc)eachHelper, &pair);+}++static inline void+removeOrphanedHandles(cpSpaceHash *hash, cpSpaceHashBin **bin_ptr)+{+	cpSpaceHashBin *bin = *bin_ptr;+	while(bin){+		cpHandle *hand = bin->handle;+		cpSpaceHashBin *next = bin->next;+		+		if(!hand->obj){+			// orphaned handle, unlink and recycle the bin+			(*bin_ptr) = bin->next;+			recycleBin(hash, bin);+			+			cpHandleRelease(hand, hash->pooledHandles);+		} else {+			bin_ptr = &bin->next;+		}+		+		bin = next;+	}+}++// Calls the callback function for the objects in a given chain.+static inline void+query(cpSpaceHash *hash, cpSpaceHashBin **bin_ptr, void *obj, cpSpaceHashQueryFunc func, void *data)+{+	restart:+	for(cpSpaceHashBin *bin = *bin_ptr; bin; bin = bin->next){+		cpHandle *hand = bin->handle;+		void *other = hand->obj;+		+		if(hand->stamp == hash->stamp || obj == other){+			continue;+		} else if(other){+			func(obj, other, data);+			hand->stamp = hash->stamp;+		} else {+			// The object for this handle has been removed+			// cleanup this cell and restart the query+			removeOrphanedHandles(hash, bin_ptr);+			goto restart; // GCC not smart enough/able to tail call an inlined function.+		}+	}+}++void+cpSpaceHashPointQuery(cpSpaceHash *hash, cpVect point, cpSpaceHashQueryFunc func, void *data)+{+	cpFloat dim = hash->celldim;+	int idx = hash_func(floor_int(point.x/dim), floor_int(point.y/dim), hash->numcells);  // Fix by ShiftZ+	+	query(hash, &hash->table[idx], &point, func, data);+	hash->stamp++;+}++void+cpSpaceHashQuery(cpSpaceHash *hash, void *obj, cpBB bb, cpSpaceHashQueryFunc func, void *data)+{+	// Get the dimensions in cell coordinates.+	cpFloat dim = hash->celldim;+	int l = floor_int(bb.l/dim);  // Fix by ShiftZ+	int r = floor_int(bb.r/dim);+	int b = floor_int(bb.b/dim);+	int t = floor_int(bb.t/dim);+	+	int n = hash->numcells;+	cpSpaceHashBin **table = hash->table;+	+	// Iterate over the cells and query them.+	for(int i=l; i<=r; i++){+		for(int j=b; j<=t; j++){+			query(hash, &table[hash_func(i,j,n)], obj, func, data);+		}+	}+	+	hash->stamp++;+}++// Similar to struct eachPair above.+typedef struct queryRehashPair {+	cpSpaceHash *hash;+	cpSpaceHashQueryFunc func;+	void *data;+} queryRehashPair;++// Hashset iterator func used with cpSpaceHashQueryRehash().+static void+handleQueryRehashHelper(void *elt, void *data)+{+	cpHandle *hand = (cpHandle *)elt;+	+	// Unpack the user callback data.+	queryRehashPair *pair = (queryRehashPair *)data;+	cpSpaceHash *hash = pair->hash;+	cpSpaceHashQueryFunc func = pair->func;++	cpFloat dim = hash->celldim;+	int n = hash->numcells;++	void *obj = hand->obj;+	cpBB bb = hash->bbfunc(obj);++	int l = floor_int(bb.l/dim);+	int r = floor_int(bb.r/dim);+	int b = floor_int(bb.b/dim);+	int t = floor_int(bb.t/dim);+	+	cpSpaceHashBin **table = hash->table;++	for(int i=l; i<=r; i++){+		for(int j=b; j<=t; j++){+			int idx = hash_func(i,j,n);+			cpSpaceHashBin *bin = table[idx];+			+			if(containsHandle(bin, hand)) continue;+			+			cpHandleRetain(hand); // this MUST be done first in case the object is removed in func()+			query(hash, &bin, obj, func, pair->data);+			+			cpSpaceHashBin *newBin = getEmptyBin(hash);+			newBin->handle = hand;+			newBin->next = bin;+			table[idx] = newBin;+		}+	}+	+	// Increment the stamp for each object hashed.+	hash->stamp++;+}++void+cpSpaceHashQueryRehash(cpSpaceHash *hash, cpSpaceHashQueryFunc func, void *data)+{+	clearHash(hash);+	+	queryRehashPair pair = {hash, func, data};+	cpHashSetEach(hash->handleSet, &handleQueryRehashHelper, &pair);+}++static inline cpFloat+segmentQuery(cpSpaceHash *hash, cpSpaceHashBin **bin_ptr, void *obj, cpSpaceHashSegmentQueryFunc func, void *data)+{+	cpFloat t = 1.0f;+	 +	restart:+	for(cpSpaceHashBin *bin = *bin_ptr; bin; bin = bin->next){+		cpHandle *hand = bin->handle;+		void *other = hand->obj;+		+		// Skip over certain conditions+		if(hand->stamp == hash->stamp){+			continue;+		} else if(other){+			t = cpfmin(t, func(obj, other, data));+			hand->stamp = hash->stamp;+		} else {+			// The object for this handle has been removed+			// cleanup this cell and restart the query+			removeOrphanedHandles(hash, bin_ptr);+			goto restart; // GCC not smart enough/able to tail call an inlined function.+		}+	}+	+	return t;+}++// modified from http://playtechs.blogspot.com/2007/03/raytracing-on-grid.html+void cpSpaceHashSegmentQuery(cpSpaceHash *hash, void *obj, cpVect a, cpVect b, cpFloat t_exit, cpSpaceHashSegmentQueryFunc func, void *data)+{+	a = cpvmult(a, 1.0f/hash->celldim);+	b = cpvmult(b, 1.0f/hash->celldim);+	+	int cell_x = floor_int(a.x), cell_y = floor_int(a.y);++	cpFloat t = 0;++	int x_inc, y_inc;+	cpFloat temp_v, temp_h;++	if (b.x > a.x){+		x_inc = 1;+		temp_h = (cpffloor(a.x + 1.0f) - a.x);+	} else {+		x_inc = -1;+		temp_h = (a.x - cpffloor(a.x));+	}++	if (b.y > a.y){+		y_inc = 1;+		temp_v = (cpffloor(a.y + 1.0f) - a.y);+	} else {+		y_inc = -1;+		temp_v = (a.y - cpffloor(a.y));+	}+	+	// Division by zero is *very* slow on ARM+	cpFloat dx = cpfabs(b.x - a.x), dy = cpfabs(b.y - a.y);+	cpFloat dt_dx = (dx ? 1.0f/dx : INFINITY), dt_dy = (dy ? 1.0f/dy : INFINITY);+	+	// fix NANs in horizontal directions+	cpFloat next_h = (temp_h ? temp_h*dt_dx : dt_dx);+	cpFloat next_v = (temp_v ? temp_v*dt_dy : dt_dy);+	+	cpSpaceHashBin **table = hash->table;++	int n = hash->numcells;+	while(t < t_exit){+		int idx = hash_func(cell_x, cell_y, n);+		t_exit = cpfmin(t_exit, segmentQuery(hash, &table[idx], obj, func, data));++		if (next_v < next_h){+			cell_y += y_inc;+			t = next_v;+			next_v += dt_dy;+		} else {+			cell_x += x_inc;+			t = next_h;+			next_h += dt_dx;+		}+	}+	+	hash->stamp++;+}
+ Chipmunk-5.3.5/src/cpSpaceQuery.c view
@@ -0,0 +1,246 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */+ +#include <stdlib.h>++#include "chipmunk_private.h"++#pragma mark Point Query Functions++typedef struct pointQueryContext {+	cpLayers layers;+	cpGroup group;+	cpSpacePointQueryFunc func;+	void *data;+} pointQueryContext;++static void +pointQueryHelper(cpVect *point, cpShape *shape, pointQueryContext *context)+{+	if(+		!(shape->group && context->group == shape->group) && (context->layers&shape->layers) &&+		cpShapePointQuery(shape, *point)+	){+		context->func(shape, context->data);+	}+}++void+cpSpacePointQuery(cpSpace *space, cpVect point, cpLayers layers, cpGroup group, cpSpacePointQueryFunc func, void *data)+{+	pointQueryContext context = {layers, group, func, data};+	+	cpSpaceLock(space); {+		cpSpaceHashPointQuery(space->activeShapes, point, (cpSpaceHashQueryFunc)pointQueryHelper, &context);+		cpSpaceHashPointQuery(space->staticShapes, point, (cpSpaceHashQueryFunc)pointQueryHelper, &context);+	} cpSpaceUnlock(space);+}++static void+rememberLastPointQuery(cpShape *shape, cpShape **outShape)+{+	if(!shape->sensor) *outShape = shape;+}++cpShape *+cpSpacePointQueryFirst(cpSpace *space, cpVect point, cpLayers layers, cpGroup group)+{+	cpShape *shape = NULL;+	cpSpacePointQuery(space, point, layers, group, (cpSpacePointQueryFunc)rememberLastPointQuery, &shape);+	+	return shape;+}+++#pragma mark Segment Query Functions++typedef struct segQueryContext {+	cpVect start, end;+	cpLayers layers;+	cpGroup group;+	cpSpaceSegmentQueryFunc func;+} segQueryContext;++static cpFloat+segQueryFunc(segQueryContext *context, cpShape *shape, void *data)+{+	cpSegmentQueryInfo info;+	+	if(+		!(shape->group && context->group == shape->group) && (context->layers&shape->layers) &&+		cpShapeSegmentQuery(shape, context->start, context->end, &info)+	){+		context->func(shape, info.t, info.n, data);+	}+	+	return 1.0f;+}++void+cpSpaceSegmentQuery(cpSpace *space, cpVect start, cpVect end, cpLayers layers, cpGroup group, cpSpaceSegmentQueryFunc func, void *data)+{+	segQueryContext context = {+		start, end,+		layers, group,+		func,+	};+	+	cpSpaceLock(space); {+		cpSpaceHashSegmentQuery(space->staticShapes, &context, start, end, 1.0f, (cpSpaceHashSegmentQueryFunc)segQueryFunc, data);+		cpSpaceHashSegmentQuery(space->activeShapes, &context, start, end, 1.0f, (cpSpaceHashSegmentQueryFunc)segQueryFunc, data);+	} cpSpaceUnlock(space);+}++typedef struct segQueryFirstContext {+	cpVect start, end;+	cpLayers layers;+	cpGroup group;+} segQueryFirstContext;++static cpFloat+segQueryFirst(segQueryFirstContext *context, cpShape *shape, cpSegmentQueryInfo *out)+{+	cpSegmentQueryInfo info;+	+	if(+		!(shape->group && context->group == shape->group) &&+		(context->layers&shape->layers) &&+		!shape->sensor &&+		cpShapeSegmentQuery(shape, context->start, context->end, &info) &&+		info.t < out->t+	){+		*out = info;+	}+	+	return out->t;+}++cpShape *+cpSpaceSegmentQueryFirst(cpSpace *space, cpVect start, cpVect end, cpLayers layers, cpGroup group, cpSegmentQueryInfo *out)+{+	cpSegmentQueryInfo info = {NULL, 1.0f, cpvzero};+	if(out){+		(*out) = info;+  } else {+		out = &info;+	}+	+	segQueryFirstContext context = {+		start, end,+		layers, group+	};+	+	cpSpaceHashSegmentQuery(space->staticShapes, &context, start, end, 1.0f, (cpSpaceHashSegmentQueryFunc)segQueryFirst, out);+	cpSpaceHashSegmentQuery(space->activeShapes, &context, start, end, out->t, (cpSpaceHashSegmentQueryFunc)segQueryFirst, out);+	+	return out->shape;+}++#pragma mark BB Query Functions++typedef struct bbQueryContext {+	cpLayers layers;+	cpGroup group;+	cpSpaceBBQueryFunc func;+	void *data;+} bbQueryContext;++static void +bbQueryHelper(cpBB *bb, cpShape *shape, bbQueryContext *context)+{+	if(+		!(shape->group && context->group == shape->group) && (context->layers&shape->layers) &&+		cpBBintersects(*bb, shape->bb)+	){+		context->func(shape, context->data);+	}+}++void+cpSpaceBBQuery(cpSpace *space, cpBB bb, cpLayers layers, cpGroup group, cpSpaceBBQueryFunc func, void *data)+{+	bbQueryContext context = {layers, group, func, data};+	+	cpSpaceLock(space); {+		cpSpaceHashQuery(space->activeShapes, &bb, bb, (cpSpaceHashQueryFunc)bbQueryHelper, &context);+		cpSpaceHashQuery(space->staticShapes, &bb, bb, (cpSpaceHashQueryFunc)bbQueryHelper, &context);+	} cpSpaceUnlock(space);+}++#pragma mark Shape Query Functions++typedef struct shapeQueryContext {+	cpSpaceShapeQueryFunc func;+	void *data;+	cpBool anyCollision;+} shapeQueryContext;++// Callback from the spatial hash.+static void+shapeQueryHelper(cpShape *a, cpShape *b, shapeQueryContext *context)+{+	// Reject any of the simple cases+	if(+		(a->group && a->group == b->group) ||+		!(a->layers & b->layers) ||+		a == b+	) return;+	+	cpContact contacts[CP_MAX_CONTACTS_PER_ARBITER];+	int numContacts = 0;+	+	// Shape 'a' should have the lower shape type. (required by cpCollideShapes() )+	if(a->klass->type <= b->klass->type){+		numContacts = cpCollideShapes(a, b, contacts);+	} else {+		numContacts = cpCollideShapes(b, a, contacts);+		for(int i=0; i<numContacts; i++) contacts[i].n = cpvneg(contacts[i].n);+	}+	+	if(numContacts){+		context->anyCollision = !(a->sensor || b->sensor);+		+		if(context->func){+			cpContactPointSet set = {numContacts, {}};+			for(int i=0; i<set.count; i++){+				set.points[i].point = contacts[i].p;+				set.points[i].normal = contacts[i].p;+				set.points[i].dist = contacts[i].dist;+			}+			+			context->func(b, &set, context->data);+		}+	}+}++cpBool+cpSpaceShapeQuery(cpSpace *space, cpShape *shape, cpSpaceShapeQueryFunc func, void *data)+{+	cpBB bb = cpShapeCacheBB(shape);+	shapeQueryContext context = {func, data, cpFalse};+	+	cpSpaceLock(space); {+		cpSpaceHashQuery(space->activeShapes, shape, bb, (cpSpaceHashQueryFunc)shapeQueryHelper, &context);+		cpSpaceHashQuery(space->staticShapes, shape, bb, (cpSpaceHashQueryFunc)shapeQueryHelper, &context);+	} cpSpaceUnlock(space);+	+	return context.anyCollision;+}
+ Chipmunk-5.3.5/src/cpSpaceStep.c view
@@ -0,0 +1,404 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */+ +#include <stdlib.h>+//#include <stdio.h>+#include <math.h>++#include "chipmunk_private.h"++#pragma mark Post Step Callback Functions++typedef struct PostStepCallback {+	cpPostStepFunc func;+	void *obj;+	void *data;+} PostStepCallback;++static cpBool+postStepFuncSetEql(PostStepCallback *a, PostStepCallback *b){+	return a->obj == b->obj;+}++static void *+postStepFuncSetTrans(PostStepCallback *callback, void *ignored)+{+	PostStepCallback *value = (PostStepCallback *)cpcalloc(1, sizeof(PostStepCallback));+	(*value) = (*callback);+	+	return value;+}++void+cpSpaceAddPostStepCallback(cpSpace *space, cpPostStepFunc func, void *obj, void *data)+{+	if(!space->postStepCallbacks){+		space->postStepCallbacks = cpHashSetNew(0, (cpHashSetEqlFunc)postStepFuncSetEql, (cpHashSetTransFunc)postStepFuncSetTrans);+	}+	+	PostStepCallback callback = {func, obj, data};+	cpHashSetInsert(space->postStepCallbacks, (cpHashValue)(size_t)obj, &callback, NULL);+}++void *+cpSpaceGetPostStepData(cpSpace *space, void *obj)+{+	if(space->postStepCallbacks){+		PostStepCallback query = {NULL, obj, NULL};+		PostStepCallback *callback = (PostStepCallback *)cpHashSetFind(space->postStepCallbacks, (cpHashValue)(size_t)obj, &query);+		return (callback ? callback->data : NULL);+	} else {+		return NULL;+	}+}++#pragma mark Contact Buffer Functions++#define CP_CONTACTS_BUFFER_SIZE ((CP_BUFFER_BYTES - sizeof(cpContactBufferHeader))/sizeof(cpContact))+typedef struct cpContactBuffer {+	cpContactBufferHeader header;+	cpContact contacts[CP_CONTACTS_BUFFER_SIZE];+} cpContactBuffer;++static cpContactBufferHeader *+cpSpaceAllocContactBuffer(cpSpace *space)+{+	cpContactBuffer *buffer = (cpContactBuffer *)cpcalloc(1, sizeof(cpContactBuffer));+	cpArrayPush(space->allocatedBuffers, buffer);+	return (cpContactBufferHeader *)buffer;+}++static cpContactBufferHeader *+cpContactBufferHeaderInit(cpContactBufferHeader *header, cpTimestamp stamp, cpContactBufferHeader *splice)+{+	header->stamp = stamp;+	header->next = (splice ? splice->next : header);+	header->numContacts = 0;+	+	return header;+}++static void+cpSpacePushFreshContactBuffer(cpSpace *space)+{+	cpTimestamp stamp = space->stamp;+	+	cpContactBufferHeader *head = space->contactBuffersHead;+	+	if(!head){+		// No buffers have been allocated, make one+		space->contactBuffersHead = cpContactBufferHeaderInit(cpSpaceAllocContactBuffer(space), stamp, NULL);+	} else if(stamp - head->next->stamp > cp_contact_persistence){+		// The tail buffer is available, rotate the ring+	cpContactBufferHeader *tail = head->next;+		space->contactBuffersHead = cpContactBufferHeaderInit(tail, stamp, tail);+	} else {+		// Allocate a new buffer and push it into the ring+		cpContactBufferHeader *buffer = cpContactBufferHeaderInit(cpSpaceAllocContactBuffer(space), stamp, head);+		space->contactBuffersHead = head->next = buffer;+	}+}+++static cpContact *+cpContactBufferGetArray(cpSpace *space)+{+	if(space->contactBuffersHead->numContacts + CP_MAX_CONTACTS_PER_ARBITER > CP_CONTACTS_BUFFER_SIZE){+		// contact buffer could overflow on the next collision, push a fresh one.+		cpSpacePushFreshContactBuffer(space);+	}+	+	cpContactBufferHeader *head = space->contactBuffersHead;+	return ((cpContactBuffer *)head)->contacts + head->numContacts;+}++static inline void+cpSpacePushContacts(cpSpace *space, int count){+	cpAssert(count <= CP_MAX_CONTACTS_PER_ARBITER, "Internal error, too many contact point overflow!");+	space->contactBuffersHead->numContacts += count;+}++static inline void+cpSpacePopContacts(cpSpace *space, int count){+	space->contactBuffersHead->numContacts -= count;+}++#pragma mark Collision Detection Functions++static inline cpCollisionHandler *+lookupCollisionHandler(cpSpace *space, cpCollisionType a, cpCollisionType b)+{+	cpCollisionType types[] = {a, b};+	return (cpCollisionHandler *)cpHashSetFind(space->collFuncSet, CP_HASH_PAIR(a, b), types);+}++static inline cpBool+queryReject(cpShape *a, cpShape *b)+{+	return+		// BBoxes must overlap+		!cpBBintersects(a->bb, b->bb)+		// Don't collide shapes attached to the same body.+		|| a->body == b->body+		// Don't collide objects in the same non-zero group+		|| (a->group && a->group == b->group)+		// Don't collide objects that don't share at least on layer.+		|| !(a->layers & b->layers);+}++// Callback from the spatial hash.+static void+queryFunc(cpShape *a, cpShape *b, cpSpace *space)+{+	// Reject any of the simple cases+	if(queryReject(a,b)) return;+	+	cpCollisionHandler *handler = lookupCollisionHandler(space, a->collision_type, b->collision_type);+	+	cpBool sensor = a->sensor || b->sensor;+	if(sensor && handler == &cpSpaceDefaultHandler) return;+	+	// Shape 'a' should have the lower shape type. (required by cpCollideShapes() )+	if(a->klass->type > b->klass->type){+		cpShape *temp = a;+		a = b;+		b = temp;+	}+	+	// Narrow-phase collision detection.+	cpContact *contacts = cpContactBufferGetArray(space);+	int numContacts = cpCollideShapes(a, b, contacts);+	if(!numContacts) return; // Shapes are not colliding.+	cpSpacePushContacts(space, numContacts);+	+	// Get an arbiter from space->contactSet for the two shapes.+	// This is where the persistant contact magic comes from.+	cpShape *shape_pair[] = {a, b};+	cpHashValue arbHashID = CP_HASH_PAIR((size_t)a, (size_t)b);+	cpArbiter *arb = (cpArbiter *)cpHashSetInsert(space->contactSet, arbHashID, shape_pair, space);+	cpArbiterUpdate(arb, contacts, numContacts, handler, a, b);+	+	// Call the begin function first if it's the first step+	if(arb->state == cpArbiterStateFirstColl && !handler->begin(arb, space, handler->data)){+		cpArbiterIgnore(arb); // permanently ignore the collision until separation+	}+	+	if(+		// Ignore the arbiter if it has been flagged+		(arb->state != cpArbiterStateIgnore) && +		// Call preSolve+		handler->preSolve(arb, space, handler->data) &&+		// Process, but don't add collisions for sensors.+		!sensor+	){+		cpArrayPush(space->arbiters, arb);+	} else {+		cpSpacePopContacts(space, numContacts);+		+		arb->contacts = NULL;+		arb->numContacts = 0;+		+		// Normally arbiters are set as used after calling the post-step callback.+		// However, post-step callbacks are not called for sensors or arbiters rejected from pre-solve.+		if(arb->state != cpArbiterStateIgnore) arb->state = cpArbiterStateNormal;+	}+	+	// Time stamp the arbiter so we know it was used recently.+	arb->stamp = space->stamp;+}++// Iterator for active/static hash collisions.+static void+active2staticIter(cpShape *shape, cpSpace *space)+{+	cpSpaceHashQuery(space->staticShapes, shape, shape->bb, (cpSpaceHashQueryFunc)queryFunc, space);+}++// Hashset filter func to throw away old arbiters.+static cpBool+contactSetFilter(cpArbiter *arb, cpSpace *space)+{+	if(space->sleepTimeThreshold != INFINITY){+		cpBody *a = arb->a->body;+		cpBody *b = arb->b->body;+		+		// both bodies are either static or sleeping+		cpBool sleepingNow =+			(cpBodyIsStatic(a) || cpBodyIsSleeping(a)) &&+			(cpBodyIsStatic(b) || cpBodyIsSleeping(b));+		+		if(sleepingNow){+			arb->state = cpArbiterStateSleep;+			return cpTrue;+		} else if(arb->state == cpArbiterStateSleep){+			// wake up the arbiter and continue as normal+			arb->state = cpArbiterStateNormal;+			// TODO is it possible that cpArbiterStateIgnore should be set here instead?+		}+	}+	+	cpTimestamp ticks = space->stamp - arb->stamp;+	+	// was used last frame, but not this one+	if(ticks >= 1 && arb->state != cpArbiterStateCached){+		// The handler needs to be looked up again as the handler cached on the arbiter may have been deleted since the last step.+		cpCollisionHandler *handler = lookupCollisionHandler(space, arb->a->collision_type, arb->b->collision_type);+		handler->separate(arb, space, handler->data);+		arb->state = cpArbiterStateCached;+	}+	+	if(ticks >= cp_contact_persistence){+		arb->contacts = NULL;+		arb->numContacts = 0;+		+		cpArrayPush(space->pooledArbiters, arb);+		return cpFalse;+	}+	+	return cpTrue;+}++// Hashset filter func to call and throw away post step callbacks.+static void+postStepCallbackSetIter(PostStepCallback *callback, cpSpace *space)+{+	callback->func(space, callback->obj, callback->data);+	cpfree(callback);+}++#pragma mark All Important cpSpaceStep() Function++void cpSpaceProcessComponents(cpSpace *space, cpFloat dt);++static void updateBBCache(cpShape *shape, void *unused){cpShapeCacheBB(shape);}++void+cpSpaceStep(cpSpace *space, cpFloat dt)+{+	if(!dt) return; // don't step if the timestep is 0!+	cpFloat dt_inv = 1.0f/dt;++	cpArray *bodies = space->bodies;+	cpArray *constraints = space->constraints;+	+	// Empty the arbiter list.+	space->arbiters->num = 0;++	// Integrate positions.+	for(int i=0; i<bodies->num; i++){+		cpBody *body = (cpBody *)bodies->arr[i];+		body->position_func(body, dt);+	}+	+	// Pre-cache BBoxes and shape data.+	cpSpaceHashEach(space->activeShapes, (cpSpaceHashIterator)updateBBCache, NULL);+	+	cpSpaceLock(space);+	+	// Collide!+	cpSpacePushFreshContactBuffer(space);+	if(space->staticShapes->handleSet->entries)+		cpSpaceHashEach(space->activeShapes, (cpSpaceHashIterator)active2staticIter, space);+	cpSpaceHashQueryRehash(space->activeShapes, (cpSpaceHashQueryFunc)queryFunc, space);+	+	cpSpaceUnlock(space);+	+	// If body sleeping is enabled, do that now.+	if(space->sleepTimeThreshold != INFINITY){+		cpSpaceProcessComponents(space, dt);+		bodies = space->bodies; // rebuilt by processContactComponents()+	}+	+	// Clear out old cached arbiters and dispatch untouch functions+	cpHashSetFilter(space->contactSet, (cpHashSetFilterFunc)contactSetFilter, space);++	// Prestep the arbiters.+	cpArray *arbiters = space->arbiters;+	for(int i=0; i<arbiters->num; i++)+		cpArbiterPreStep((cpArbiter *)arbiters->arr[i], dt_inv);++	// Prestep the constraints.+	for(int i=0; i<constraints->num; i++){+		cpConstraint *constraint = (cpConstraint *)constraints->arr[i];+		constraint->klass->preStep(constraint, dt, dt_inv);+	}++	for(int i=0; i<space->elasticIterations; i++){+		for(int j=0; j<arbiters->num; j++)+			cpArbiterApplyImpulse((cpArbiter *)arbiters->arr[j], 1.0f);+			+		for(int j=0; j<constraints->num; j++){+			cpConstraint *constraint = (cpConstraint *)constraints->arr[j];+			constraint->klass->applyImpulse(constraint);+		}+	}++	// Integrate velocities.+	cpFloat damping = cpfpow(1.0f/space->damping, -dt);+	for(int i=0; i<bodies->num; i++){+		cpBody *body = (cpBody *)bodies->arr[i];+		body->velocity_func(body, space->gravity, damping, dt);+	}++	for(int i=0; i<arbiters->num; i++)+		cpArbiterApplyCachedImpulse((cpArbiter *)arbiters->arr[i]);+	+	// run the old-style elastic solver if elastic iterations are disabled+	cpFloat elasticCoef = (space->elasticIterations ? 0.0f : 1.0f);+	+	// Run the impulse solver.+	for(int i=0; i<space->iterations; i++){+		for(int j=0; j<arbiters->num; j++)+			cpArbiterApplyImpulse((cpArbiter *)arbiters->arr[j], elasticCoef);+			+		for(int j=0; j<constraints->num; j++){+			cpConstraint *constraint = (cpConstraint *)constraints->arr[j];+			constraint->klass->applyImpulse(constraint);+		}+	}+	+	cpSpaceLock(space);+	+	// run the post solve callbacks+	for(int i=0; i<arbiters->num; i++){+		cpArbiter *arb = (cpArbiter *) arbiters->arr[i];+		+		cpCollisionHandler *handler = arb->handler;+		handler->postSolve(arb, space, handler->data);+		+		arb->state = cpArbiterStateNormal;+	}+	+	cpSpaceUnlock(space);+	+	// Run the post step callbacks+	// Loop because post step callbacks may create more post step callbacks+	while(space->postStepCallbacks){+		cpHashSet *callbacks = space->postStepCallbacks;+		space->postStepCallbacks = NULL;+		+		cpHashSetEach(callbacks, (cpHashSetIterFunc)postStepCallbackSetIter, space);+		cpHashSetFree(callbacks);+	}+	+	// Increment the stamp.+	space->stamp++;+}
+ Chipmunk-5.3.5/src/cpVect.c view
@@ -0,0 +1,71 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */+ +#include <stdio.h>+#include <math.h>++#include "chipmunk.h"++cpFloat+cpvlength(const cpVect v)+{+	return cpfsqrt( cpvdot(v, v) );+}++inline cpVect+cpvslerp(const cpVect v1, const cpVect v2, const cpFloat t)+{+	cpFloat omega = cpfacos(cpvdot(v1, v2));+	+	if(omega){+		cpFloat denom = 1.0f/cpfsin(omega);+		return cpvadd(cpvmult(v1, cpfsin((1.0f - t)*omega)*denom), cpvmult(v2, cpfsin(t*omega)*denom));+	} else {+		return v1;+	}+}++cpVect+cpvslerpconst(const cpVect v1, const cpVect v2, const cpFloat a)+{+	cpFloat angle = cpfacos(cpvdot(v1, v2));+	return cpvslerp(v1, v2, cpfmin(a, angle)/angle);+}++cpVect+cpvforangle(const cpFloat a)+{+	return cpv(cpfcos(a), cpfsin(a));+}++cpFloat+cpvtoangle(const cpVect v)+{+	return cpfatan2(v.y, v.x);+}++char*+cpvstr(const cpVect v)+{+	static char str[256];+	sprintf(str, "(% .3f, % .3f)", v.x, v.y);+	return str;+}
+ Chipmunk-5.3.5/src/prime.h view
@@ -0,0 +1,68 @@+/* Copyright (c) 2007 Scott Lembcke+ * + * Permission is hereby granted, free of charge, to any person obtaining a copy+ * of this software and associated documentation files (the "Software"), to deal+ * in the Software without restriction, including without limitation the rights+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell+ * copies of the Software, and to permit persons to whom the Software is+ * furnished to do so, subject to the following conditions:+ * + * The above copyright notice and this permission notice shall be included in+ * all copies or substantial portions of the Software.+ * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE+ * SOFTWARE.+ */+ +// Used for resizing hash tables.+// Values approximately double.+// http://planetmath.org/encyclopedia/GoodHashTablePrimes.html+static int primes[] = {+	5,+	13,+	23,+	47,+	97,+	193,+	389,+	769,+	1543,+	3079,+	6151,+	12289,+	24593,+	49157,+	98317,+	196613,+	393241,+	786433,+	1572869,+	3145739,+	6291469,+	12582917,+	25165843,+	50331653,+	100663319,+	201326611,+	402653189,+	805306457,+	1610612741,+	0,+};++static inline int+next_prime(int n)+{+	int i = 0;+	while(n > primes[i]){+		i++;+		cpAssert(primes[i], "Tried to resize a hash table to a size greater than 1610612741 O_o"); // realistically this should never happen+	}+	+	return primes[i];+}
Hipmunk.cabal view
@@ -1,27 +1,31 @@-Cabal-Version: >= 1.2+Cabal-Version: >= 1.6 Build-Type:    Simple Tested-With:   GHC Category:      Physics, Game Name:          Hipmunk-Version:       5.2.0.2+Version:       5.2.0.3 Stability:     provisional License:       OtherLicense License-File:  LICENSE-Copyright:     (c) 2008-2010 Felipe A. Lessa+Copyright:     (c) 2008-2011 Felipe A. Lessa Author:        Felipe A. Lessa <felipe.lessa@gmail.com>-Maintainer:    Felipe A. Lessa <felipe.lessa@gmail.com>+Maintainer:    Felipe A. Lessa <felipe.lessa@gmail.com>, Sönke Hahn <shahn@joyridelabs.de> Synopsis:      A Haskell binding for Chipmunk. Homepage:      http://patch-tag.com/r/felipe/hipmunk/home Description:       Chipmunk is a fast, simple, portable, 2D physics engine-      (<http://code.google.com/p/chipmunk-physics/> and-      <http://wiki.slembcke.net/main/published/Chipmunk>).  This-      package contains a prerelease Chipmunk 5.0 source and-      Haskell bindings to all of its functions. It is-      completely self-contained.  Please see-      <http://hackage.haskell.org/package/HipmunkPlayground>+      (<http://code.google.com/p/chipmunk-physics/>).  This+      package the Chipmunk 5.3.4 source and Haskell bindings to+      all of its functions. It is completely self-contained.+      Please see <http://hackage.haskell.org/package/HipmunkPlayground>       for a demonstration of this library.       .+      New in version 5.2.0.3:+      * Update to Chipmunk 5.3.5 and bump dependencies to+        match GHC 7.2.1. (Thanks, Sönke Hahn!)+      .+      * Now Sönke Hahn is also a Hipmunk maintainer.  Awesome!+      .       New in version 5.2.0.2:       .       * Update to Chipmunk 5.3.4.  Note, however, that not all@@ -40,65 +44,70 @@       Licensed under the MIT license (like Chipmunk itself). Extra-Source-Files:       NEWS,-      Chipmunk-5.3.4/include/chipmunk/chipmunk_ffi.h,-      Chipmunk-5.3.4/include/chipmunk/chipmunk.h,-      Chipmunk-5.3.4/include/chipmunk/chipmunk_private.h,-      Chipmunk-5.3.4/include/chipmunk/chipmunk_types.h,-      Chipmunk-5.3.4/include/chipmunk/chipmunk_unsafe.h,-      Chipmunk-5.3.4/include/chipmunk/constraints/cpConstraint.h,-      Chipmunk-5.3.4/include/chipmunk/constraints/cpDampedRotarySpring.h,-      Chipmunk-5.3.4/include/chipmunk/constraints/cpDampedSpring.h,-      Chipmunk-5.3.4/include/chipmunk/constraints/cpGearJoint.h,-      Chipmunk-5.3.4/include/chipmunk/constraints/cpGrooveJoint.h,-      Chipmunk-5.3.4/include/chipmunk/constraints/cpPinJoint.h,-      Chipmunk-5.3.4/include/chipmunk/constraints/cpPivotJoint.h,-      Chipmunk-5.3.4/include/chipmunk/constraints/cpRatchetJoint.h,-      Chipmunk-5.3.4/include/chipmunk/constraints/cpRotaryLimitJoint.h,-      Chipmunk-5.3.4/include/chipmunk/constraints/cpSimpleMotor.h,-      Chipmunk-5.3.4/include/chipmunk/constraints/cpSlideJoint.h,-      Chipmunk-5.3.4/include/chipmunk/constraints/util.h,-      Chipmunk-5.3.4/include/chipmunk/cpArbiter.h,-      Chipmunk-5.3.4/include/chipmunk/cpArray.h,-      Chipmunk-5.3.4/include/chipmunk/cpBB.h,-      Chipmunk-5.3.4/include/chipmunk/cpBody.h,-      Chipmunk-5.3.4/include/chipmunk/cpCollision.h,-      Chipmunk-5.3.4/include/chipmunk/cpHashSet.h,-      Chipmunk-5.3.4/include/chipmunk/cpPolyShape.h,-      Chipmunk-5.3.4/include/chipmunk/cpShape.h,-      Chipmunk-5.3.4/include/chipmunk/cpSpace.h,-      Chipmunk-5.3.4/include/chipmunk/cpSpaceHash.h,-      Chipmunk-5.3.4/include/chipmunk/cpVect.h,-      Chipmunk-5.3.4/LICENSE.txt,-      Chipmunk-5.3.4/README.txt,-      Chipmunk-5.3.4/src/chipmunk.c,-      Chipmunk-5.3.4/src/constraints/cpConstraint.c,-      Chipmunk-5.3.4/src/constraints/cpDampedRotarySpring.c,-      Chipmunk-5.3.4/src/constraints/cpDampedSpring.c,-      Chipmunk-5.3.4/src/constraints/cpGearJoint.c,-      Chipmunk-5.3.4/src/constraints/cpGrooveJoint.c,-      Chipmunk-5.3.4/src/constraints/cpPinJoint.c,-      Chipmunk-5.3.4/src/constraints/cpPivotJoint.c,-      Chipmunk-5.3.4/src/constraints/cpRatchetJoint.c,-      Chipmunk-5.3.4/src/constraints/cpRotaryLimitJoint.c,-      Chipmunk-5.3.4/src/constraints/cpSimpleMotor.c,-      Chipmunk-5.3.4/src/constraints/cpSlideJoint.c,-      Chipmunk-5.3.4/src/cpArbiter.c,-      Chipmunk-5.3.4/src/cpArray.c,-      Chipmunk-5.3.4/src/cpBB.c,-      Chipmunk-5.3.4/src/cpBody.c,-      Chipmunk-5.3.4/src/cpCollision.c,-      Chipmunk-5.3.4/src/cpHashSet.c,-      Chipmunk-5.3.4/src/cpPolyShape.c,-      Chipmunk-5.3.4/src/cpShape.c,-      Chipmunk-5.3.4/src/cpSpace.c,-      Chipmunk-5.3.4/src/cpSpaceComponent.c,-      Chipmunk-5.3.4/src/cpSpaceHash.c,-      Chipmunk-5.3.4/src/cpSpaceQuery.c,-      Chipmunk-5.3.4/src/cpSpaceStep.c,-      Chipmunk-5.3.4/src/cpVect.c,-      Chipmunk-5.3.4/src/prime.h,+      TODO,+      Chipmunk-5.3.5/include/chipmunk/chipmunk_ffi.h,+      Chipmunk-5.3.5/include/chipmunk/chipmunk.h,+      Chipmunk-5.3.5/include/chipmunk/chipmunk_private.h,+      Chipmunk-5.3.5/include/chipmunk/chipmunk_types.h,+      Chipmunk-5.3.5/include/chipmunk/chipmunk_unsafe.h,+      Chipmunk-5.3.5/include/chipmunk/constraints/cpConstraint.h,+      Chipmunk-5.3.5/include/chipmunk/constraints/cpDampedRotarySpring.h,+      Chipmunk-5.3.5/include/chipmunk/constraints/cpDampedSpring.h,+      Chipmunk-5.3.5/include/chipmunk/constraints/cpGearJoint.h,+      Chipmunk-5.3.5/include/chipmunk/constraints/cpGrooveJoint.h,+      Chipmunk-5.3.5/include/chipmunk/constraints/cpPinJoint.h,+      Chipmunk-5.3.5/include/chipmunk/constraints/cpPivotJoint.h,+      Chipmunk-5.3.5/include/chipmunk/constraints/cpRatchetJoint.h,+      Chipmunk-5.3.5/include/chipmunk/constraints/cpRotaryLimitJoint.h,+      Chipmunk-5.3.5/include/chipmunk/constraints/cpSimpleMotor.h,+      Chipmunk-5.3.5/include/chipmunk/constraints/cpSlideJoint.h,+      Chipmunk-5.3.5/include/chipmunk/constraints/util.h,+      Chipmunk-5.3.5/include/chipmunk/cpArbiter.h,+      Chipmunk-5.3.5/include/chipmunk/cpArray.h,+      Chipmunk-5.3.5/include/chipmunk/cpBB.h,+      Chipmunk-5.3.5/include/chipmunk/cpBody.h,+      Chipmunk-5.3.5/include/chipmunk/cpCollision.h,+      Chipmunk-5.3.5/include/chipmunk/cpHashSet.h,+      Chipmunk-5.3.5/include/chipmunk/cpPolyShape.h,+      Chipmunk-5.3.5/include/chipmunk/cpShape.h,+      Chipmunk-5.3.5/include/chipmunk/cpSpace.h,+      Chipmunk-5.3.5/include/chipmunk/cpSpaceHash.h,+      Chipmunk-5.3.5/include/chipmunk/cpVect.h,+      Chipmunk-5.3.5/LICENSE.txt,+      Chipmunk-5.3.5/README.txt,+      Chipmunk-5.3.5/src/chipmunk.c,+      Chipmunk-5.3.5/src/constraints/cpConstraint.c,+      Chipmunk-5.3.5/src/constraints/cpDampedRotarySpring.c,+      Chipmunk-5.3.5/src/constraints/cpDampedSpring.c,+      Chipmunk-5.3.5/src/constraints/cpGearJoint.c,+      Chipmunk-5.3.5/src/constraints/cpGrooveJoint.c,+      Chipmunk-5.3.5/src/constraints/cpPinJoint.c,+      Chipmunk-5.3.5/src/constraints/cpPivotJoint.c,+      Chipmunk-5.3.5/src/constraints/cpRatchetJoint.c,+      Chipmunk-5.3.5/src/constraints/cpRotaryLimitJoint.c,+      Chipmunk-5.3.5/src/constraints/cpSimpleMotor.c,+      Chipmunk-5.3.5/src/constraints/cpSlideJoint.c,+      Chipmunk-5.3.5/src/cpArbiter.c,+      Chipmunk-5.3.5/src/cpArray.c,+      Chipmunk-5.3.5/src/cpBB.c,+      Chipmunk-5.3.5/src/cpBody.c,+      Chipmunk-5.3.5/src/cpCollision.c,+      Chipmunk-5.3.5/src/cpHashSet.c,+      Chipmunk-5.3.5/src/cpPolyShape.c,+      Chipmunk-5.3.5/src/cpShape.c,+      Chipmunk-5.3.5/src/cpSpace.c,+      Chipmunk-5.3.5/src/cpSpaceComponent.c,+      Chipmunk-5.3.5/src/cpSpaceHash.c,+      Chipmunk-5.3.5/src/cpSpaceQuery.c,+      Chipmunk-5.3.5/src/cpSpaceStep.c,+      Chipmunk-5.3.5/src/cpVect.c,+      Chipmunk-5.3.5/src/prime.h,       Physics/Hipmunk/wrapper.h +source-repository head+  type:     darcs+  location: http://patch-tag.com:/r/felipe/hipmunk+ Flag small_base   Description: Choose the new smaller, split-up base package. @@ -121,41 +130,41 @@       Physics.Hipmunk.Internal   Include-Dirs:       Physics/Hipmunk,-      Chipmunk-5.3.4/include/chipmunk+      Chipmunk-5.3.5/include/chipmunk   Includes:       wrapper.h   C-Sources:-      Chipmunk-5.3.4/src/chipmunk.c,-      Chipmunk-5.3.4/src/constraints/cpConstraint.c,-      Chipmunk-5.3.4/src/constraints/cpDampedRotarySpring.c,-      Chipmunk-5.3.4/src/constraints/cpDampedSpring.c,-      Chipmunk-5.3.4/src/constraints/cpGearJoint.c,-      Chipmunk-5.3.4/src/constraints/cpGrooveJoint.c,-      Chipmunk-5.3.4/src/constraints/cpPinJoint.c,-      Chipmunk-5.3.4/src/constraints/cpPivotJoint.c,-      Chipmunk-5.3.4/src/constraints/cpRatchetJoint.c,-      Chipmunk-5.3.4/src/constraints/cpRotaryLimitJoint.c,-      Chipmunk-5.3.4/src/constraints/cpSimpleMotor.c,-      Chipmunk-5.3.4/src/constraints/cpSlideJoint.c,-      Chipmunk-5.3.4/src/cpArbiter.c,-      Chipmunk-5.3.4/src/cpArray.c,-      Chipmunk-5.3.4/src/cpBB.c,-      Chipmunk-5.3.4/src/cpBody.c,-      Chipmunk-5.3.4/src/cpCollision.c,-      Chipmunk-5.3.4/src/cpHashSet.c,-      Chipmunk-5.3.4/src/cpPolyShape.c,-      Chipmunk-5.3.4/src/cpShape.c,-      Chipmunk-5.3.4/src/cpSpace.c,-      Chipmunk-5.3.4/src/cpSpaceComponent.c,-      Chipmunk-5.3.4/src/cpSpaceHash.c,-      Chipmunk-5.3.4/src/cpSpaceQuery.c,-      Chipmunk-5.3.4/src/cpSpaceStep.c,-      Chipmunk-5.3.4/src/cpVect.c,+      Chipmunk-5.3.5/src/chipmunk.c,+      Chipmunk-5.3.5/src/constraints/cpConstraint.c,+      Chipmunk-5.3.5/src/constraints/cpDampedRotarySpring.c,+      Chipmunk-5.3.5/src/constraints/cpDampedSpring.c,+      Chipmunk-5.3.5/src/constraints/cpGearJoint.c,+      Chipmunk-5.3.5/src/constraints/cpGrooveJoint.c,+      Chipmunk-5.3.5/src/constraints/cpPinJoint.c,+      Chipmunk-5.3.5/src/constraints/cpPivotJoint.c,+      Chipmunk-5.3.5/src/constraints/cpRatchetJoint.c,+      Chipmunk-5.3.5/src/constraints/cpRotaryLimitJoint.c,+      Chipmunk-5.3.5/src/constraints/cpSimpleMotor.c,+      Chipmunk-5.3.5/src/constraints/cpSlideJoint.c,+      Chipmunk-5.3.5/src/cpArbiter.c,+      Chipmunk-5.3.5/src/cpArray.c,+      Chipmunk-5.3.5/src/cpBB.c,+      Chipmunk-5.3.5/src/cpBody.c,+      Chipmunk-5.3.5/src/cpCollision.c,+      Chipmunk-5.3.5/src/cpHashSet.c,+      Chipmunk-5.3.5/src/cpPolyShape.c,+      Chipmunk-5.3.5/src/cpShape.c,+      Chipmunk-5.3.5/src/cpSpace.c,+      Chipmunk-5.3.5/src/cpSpaceComponent.c,+      Chipmunk-5.3.5/src/cpSpaceHash.c,+      Chipmunk-5.3.5/src/cpSpaceQuery.c,+      Chipmunk-5.3.5/src/cpSpaceStep.c,+      Chipmunk-5.3.5/src/cpVect.c,       Physics/Hipmunk/wrapper.c   if flag(small_base)     Build-Depends: base >= 3 && < 5,                    array >= 0.1 && < 0.4,-                   containers >= 0.1 && < 0.4,+                   containers >= 0.1 && < 0.5,                    transformers >= 0.2 && < 0.3,                    StateVar >= 1.0 && < 1.1   else
NEWS view
@@ -1,3 +1,9 @@+Version 5.2.0.3+===============+ - Update to Chipmunk 5.3.5 and bump dependencies to+   match GHC 7.2.1. (Thanks, Sönke Hahn!)+ - Now Sönke Hahn is also a Hipmunk maintainer.  Awesome!+ Version 5.2.0.2 ===============  - Update to Chipmunk 5.3.4.  Note, however, that not all
+ TODO view
@@ -0,0 +1,4 @@+- Update to Chipmunk 6+- Provide bindings for all functionality in Chipmunk 5.3.4.+  * Sleeping bodies+  * ...?