diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml new file mode 100644 index 00000000..2b3a297e --- /dev/null +++ b/.github/workflows/build.yml @@ -0,0 +1,82 @@ +# This starter workflow is for a CMake project running on multiple platforms. There is a different starter workflow if you just want a single platform. +# See: https://github.com/actions/starter-workflows/blob/main/ci/cmake-single-platform.yml +name: CMake on multiple platforms + +on: + push: + branches: master + pull_request: + branches: master + +jobs: + build: + runs-on: ${{ matrix.os }} + + strategy: + # Set fail-fast to false to ensure that feedback is delivered for all matrix combinations. Consider changing this to true when your workflow is stable. + fail-fast: false + + # Set up a matrix to run the following 3 configurations: + # 1. + # 2. + # 3. + # + # To add more build types (Release, Debug, RelWithDebInfo, etc.) customize the build_type list. + matrix: + os: [ubuntu-latest, windows-latest] + build_type: [Release] + c_compiler: [gcc, clang, cl] + include: + - os: windows-latest + c_compiler: cl + cpp_compiler: cl + - os: ubuntu-latest + c_compiler: gcc + cpp_compiler: g++ + - os: ubuntu-latest + c_compiler: clang + cpp_compiler: clang++ + exclude: + - os: windows-latest + c_compiler: gcc + - os: windows-latest + c_compiler: clang + - os: ubuntu-latest + c_compiler: cl + + steps: + - uses: actions/checkout@v4 + + - name: Set reusable strings + # Turn repeated input strings (such as the build output directory) into step outputs. These step outputs can be used throughout the workflow file. + id: strings + shell: bash + run: | + echo "build-output-dir=${{ github.workspace }}/build" >> "$GITHUB_OUTPUT" + + - name: Update packages + run: sudo apt-get update + + - name: Install packages + run: sudo apt-get install --fix-missing libgl1-mesa-dev + + - name: Configure CMake + # Configure CMake in a 'build' subdirectory. `CMAKE_BUILD_TYPE` is only required if you are using a single-configuration generator such as make. + # See https://cmake.org/cmake/help/latest/variable/CMAKE_BUILD_TYPE.html?highlight=cmake_build_type + run: > + cmake -B ${{ steps.strings.outputs.build-output-dir }} + -DCMAKE_CXX_COMPILER=${{ matrix.cpp_compiler }} -DCMAKE_C_COMPILER=${{ + matrix.c_compiler }} -DCMAKE_BUILD_TYPE=${{ matrix.build_type }} -S + ${{ github.workspace }} + + - name: Build + # Build your program with the given configuration. Note that --config is needed because the default Windows generator is a multi-config generator (Visual Studio generator). + run: + cmake --build ${{ steps.strings.outputs.build-output-dir }} --config + ${{ matrix.build_type }} + + #- name: Test + # working-directory: ${{ steps.strings.outputs.build-output-dir }} + # Execute tests defined by the CMake configuration. Note that --build-config is needed because the default Windows generator is a multi-config generator (Visual Studio generator). + # See https://cmake.org/cmake/help/latest/manual/ctest.1.html for more detail + # run: ctest --build-config ${{ matrix.build_type }} diff --git a/CMakeLists.txt b/CMakeLists.txt index b1372b44..faa3492f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.7) +cmake_minimum_required(VERSION 3.10) project(chipmunk) diff --git a/README.textile b/README.textile index 301b502a..a7655a01 100644 --- a/README.textile +++ b/README.textile @@ -1,5 +1,24 @@ !http://files.slembcke.net/chipmunk/logo/logo1_med.png! +h2. FORK INFO - START HERE + +This is a fork of the original "Chipmunk2D":https://github.com/slembcke/Chipmunk2D + +The main purpose of this fork is to be a compainion for the Python 2D physics library "Pymunk":https://www.pymunk.org which is built on Chipmunk2D. Given the slow pace of development of Chipmunk2D, and some unique requirements and oppurtunitites of Pymunk this is something that have grown over a long time. What really made me consider to make it more formal was the discussion "here":https://github.com/slembcke/Chipmunk2D/issues/237 with Slembcke, the creator of Chipmunk2D. + +I do not forsee that I have the time, motivation or skills to really revive Chipmunk2D. However, I hope to incorporate minor new features, and a bunch of fixes. Any changes are driven by what make sense from the Pymunk use case. However, I do think many of these changes are useful also to users outside of Pymunk, and you are of course free to use the fork for other projects / languages as well. + +At the moment I dont have any formal release of this fork, but I plan to make some kind of rename and a release if/when enough changes are accumulated. + +h3. Differeces: + +* This fork will have ABI breaking changes. For Pymunk it does not matter, a Pymunk verison is always compiled against a specific Chipmunk2D version. +* This fork might have API breaking changes. Since Pymunk wraps Chipmunk2D in a Python friendly API, end users of Pymunk wont be affected. +* Some additional minor features, useful from Pymunk +* Fixes to various issues, mainly those affecting Pymunk + +--- + h2. NEW IN CHIPMUNK 7 Chipmunk 7 is complete and now includes the ARM NEON optimizations, the autogeometry code, and the mulithreaded solver. diff --git a/VERSION.txt b/VERSION.txt index d822ba08..abc6c1e2 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1,3 +1,24 @@ +What's new in NEXT: +* API: Now possible to to override cpMessage by defining CP_OVERRIDE_MESSAGE +* API: The maxForce property now have effect on DampedSpring and DampedRotarySpring +* API: Reset velocity and constraint jAcc when body type changes to DYNAMIC +* API: Add transform property to cpSpaceDebugDrawOptions +* API: Use CGFloat as the float type if CP_USE_CGTYPES is set. +* BUG: Fixed total impulse calculation of DampedRotarySpring +* BUG: Fix for compiling cpPolyline with MSVC +* BUG: Fix FFI symbols not exported on windows under mingw +* BUG: Fix a potential divide by zero in ClosestT +* BUG: Fix division by zero in cpPolyShapeSegmentQuery() function. +* BUG: Fix planetmath url (by ccgargantua) +* BUG: Optimized memory allocation of cpPolylineSet (by richardgroves) +* BUG: Fix cast between incompatible function type to reduce warnings (by aganm) +* BUG: Rename body local variable to fix shadow warning (by aganm) +* BUG: Fixes bug in cpSpaceShapeQuery to not miss collisions (by alanmillard) +* BUG: Fix for cpSpaceShapeQuery using cpSegmentShape with null body (by maniek2332) +* MISC: Fix spelling of positive (by skitt) + + + What's new in 7.0.3: * MISC: Replacing GLFW with Sokol in the demo application. No need to push GLFW binaries and has a nice x-platform renderer to build on. * MISC: Fixed some 'const' warnings for MSCV. diff --git a/demo/ChipmunkDemo.c b/demo/ChipmunkDemo.c index 7f144e50..7f2d2df9 100644 --- a/demo/ChipmunkDemo.c +++ b/demo/ChipmunkDemo.c @@ -189,6 +189,7 @@ ChipmunkDemoDefaultDrawImpl(cpSpace *space) ColorForShape, {0.0f, 0.75f, 0.0f, 1.0f}, // Constraint color {1.0f, 0.0f, 0.0f, 1.0f}, // Collision point color + cpTransformIdentity, NULL, }; diff --git a/include/chipmunk/chipmunk_structs.h b/include/chipmunk/chipmunk_structs.h index 1485795d..20c9c001 100644 --- a/include/chipmunk/chipmunk_structs.h +++ b/include/chipmunk/chipmunk_structs.h @@ -239,12 +239,14 @@ typedef void (*cpConstraintPreStepImpl)(cpConstraint *constraint, cpFloat dt); typedef void (*cpConstraintApplyCachedImpulseImpl)(cpConstraint *constraint, cpFloat dt_coef); typedef void (*cpConstraintApplyImpulseImpl)(cpConstraint *constraint, cpFloat dt); typedef cpFloat (*cpConstraintGetImpulseImpl)(cpConstraint *constraint); +typedef void (*cpConstraintResetAccImpl)(cpConstraint *constraint); typedef struct cpConstraintClass { cpConstraintPreStepImpl preStep; cpConstraintApplyCachedImpulseImpl applyCachedImpulse; cpConstraintApplyImpulseImpl applyImpulse; cpConstraintGetImpulseImpl getImpulse; + cpConstraintResetAccImpl resetAcc; } cpConstraintClass; struct cpConstraint { diff --git a/include/chipmunk/cpMarch.h b/include/chipmunk/cpMarch.h index cc1f5c06..53474a51 100644 --- a/include/chipmunk/cpMarch.h +++ b/include/chipmunk/cpMarch.h @@ -1,6 +1,10 @@ // Copyright 2013 Howling Moon Software. All rights reserved. // See http://chipmunk2d.net/legal.php for more information. +#ifdef __cplusplus +extern "C" { +#endif + /// Function type used as a callback from the marching squares algorithm to sample an image function. /// It passes you the point to sample and your context pointer, and you return the density. typedef cpFloat (*cpMarchSampleFunc)(cpVect point, void *data); @@ -26,3 +30,7 @@ CP_EXPORT void cpMarchHard( cpMarchSegmentFunc segment, void *segment_data, cpMarchSampleFunc sample, void *sample_data ); + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/include/chipmunk/cpPolyline.h b/include/chipmunk/cpPolyline.h index 9a6ebed3..4dc286be 100644 --- a/include/chipmunk/cpPolyline.h +++ b/include/chipmunk/cpPolyline.h @@ -1,6 +1,10 @@ // Copyright 2013 Howling Moon Software. All rights reserved. // See http://chipmunk2d.net/legal.php for more information. +#ifdef __cplusplus +extern "C" { +#endif + // Polylines are just arrays of vertexes. // They are looped if the first vertex is equal to the last. // cpPolyline structs are intended to be passed by value and destroyed when you are done with them. @@ -68,3 +72,7 @@ CP_EXPORT void cpPolylineSetCollectSegment(cpVect v0, cpVect v1, cpPolylineSet * CP_EXPORT cpPolylineSet *cpPolylineConvexDecomposition(cpPolyline *line, cpFloat tol); #define cpPolylineConvexDecomposition_BETA cpPolylineConvexDecomposition + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/src/chipmunk.c b/src/chipmunk.c index a6cc9d6d..cf2807eb 100644 --- a/src/chipmunk.c +++ b/src/chipmunk.c @@ -17,7 +17,7 @@ * 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 #include @@ -28,6 +28,7 @@ #include "chipmunk/chipmunk_private.h" +#ifndef CP_OVERRIDE_MESSAGE void cpMessage(const char *condition, const char *file, int line, int isError, int isHardError, const char *message, ...) { @@ -52,6 +53,8 @@ cpMessage(const char *condition, const char *file, int line, int isError, int is fprintf(stderr, "\tSource:%s:%d\n", file, line); #endif } +#endif + #define STR(s) #s #define XSTR(s) STR(s) diff --git a/src/cpBBTree.c b/src/cpBBTree.c index 2cef7bc7..c822c75a 100644 --- a/src/cpBBTree.c +++ b/src/cpBBTree.c @@ -544,7 +544,7 @@ cpBBTreeAlloc(void) return (cpBBTree *)cpcalloc(1, sizeof(cpBBTree)); } -static int +static cpBool leafSetEql(void *obj, Node *node) { return (obj == node->obj); diff --git a/src/cpBody.c b/src/cpBody.c index 8ad2bc99..d4cd89a6 100644 --- a/src/cpBody.c +++ b/src/cpBody.c @@ -103,9 +103,9 @@ cpBodyFree(cpBody *body) #ifdef NDEBUG #define cpAssertSaneBody(body) #else - static void cpv_assert_nan(cpVect v, char *message){cpAssertHard(v.x == v.x && v.y == v.y, message);} - static void cpv_assert_infinite(cpVect v, char *message){cpAssertHard(cpfabs(v.x) != INFINITY && cpfabs(v.y) != INFINITY, message);} - static void cpv_assert_sane(cpVect v, char *message){cpv_assert_nan(v, message); cpv_assert_infinite(v, message);} + static void cpv_assert_nan(cpVect v, const char *message){cpAssertHard(v.x == v.x && v.y == v.y, message);} + static void cpv_assert_infinite(cpVect v, const char *message){cpAssertHard(cpfabs(v.x) != INFINITY && cpfabs(v.y) != INFINITY, message);} + static void cpv_assert_sane(cpVect v, const char *message){cpv_assert_nan(v, message); cpv_assert_infinite(v, message);} static void cpBodySanityCheck(const cpBody *body) @@ -160,6 +160,23 @@ cpBodySetType(cpBody *body, cpBodyType type) body->m_inv = body->i_inv = INFINITY; cpBodyAccumulateMassFromShapes(body); + + // Check any constraints, and if there are + // constraints with another non-DYNAMIC body: + // Reset any accumulated force in constraints attached to the body. + // Reset velocity of the body. These will be NaN or Inf otherwise. + cpConstraint* constraint = body->constraintList; + while (constraint) { + constraint->klass->resetAcc(constraint); + cpBody* a = cpConstraintGetBodyA(constraint); + a->v = cpvzero; + a->w = 0.0f; + cpBody* b = cpConstraintGetBodyB(constraint); + b->v = cpvzero; + b->w = 0.0f; + + constraint = cpConstraintNext(constraint, body); + } } else { body->m = body->i = INFINITY; body->m_inv = body->i_inv = 0.0f; diff --git a/src/cpCollision.c b/src/cpCollision.c index f315bdf9..429667e4 100644 --- a/src/cpCollision.c +++ b/src/cpCollision.c @@ -559,7 +559,7 @@ CircleToSegment(const cpCircleShape *circle, const cpSegmentShape *segment, stru cpVect n = info->n = (dist ? cpvmult(delta, 1.0f/dist) : segment->tn); // Reject endcap collisions if tangents are provided. - cpVect rot = cpBodyGetRotation(segment->shape.body); + cpVect rot = segment->shape.body ? cpBodyGetRotation(segment->shape.body) : cpv(1.0f, 0.0f); if( (closest_t != 0.0f || cpvdot(n, cpvrotate(segment->a_tangent, rot)) >= 0.0) && (closest_t != 1.0f || cpvdot(n, cpvrotate(segment->b_tangent, rot)) >= 0.0) @@ -587,8 +587,8 @@ SegmentToSegment(const cpSegmentShape *seg1, const cpSegmentShape *seg2, struct #endif cpVect n = points.n; - cpVect rot1 = cpBodyGetRotation(seg1->shape.body); - cpVect rot2 = cpBodyGetRotation(seg2->shape.body); + cpVect rot1 = seg1->shape.body ? cpBodyGetRotation(seg1->shape.body) : cpv(1.0f, 0.0f); + cpVect rot2 = seg2->shape.body ? cpBodyGetRotation(seg2->shape.body) : cpv(1.0f, 0.0f); // If the closest points are nearer than the sum of the radii... if( @@ -645,7 +645,7 @@ SegmentToPoly(const cpSegmentShape *seg, const cpPolyShape *poly, struct cpColli #endif cpVect n = points.n; - cpVect rot = cpBodyGetRotation(seg->shape.body); + cpVect rot = seg->shape.body ? cpBodyGetRotation(seg->shape.body) : cpv(1.0f, 0.0f); if( // If the closest points are nearer than the sum of the radii... diff --git a/src/cpDampedRotarySpring.c b/src/cpDampedRotarySpring.c index 8d38a545..d5737a93 100644 --- a/src/cpDampedRotarySpring.c +++ b/src/cpDampedRotarySpring.c @@ -20,7 +20,7 @@ */ #include "chipmunk/chipmunk_private.h" - +#include static cpFloat defaultSpringTorque(cpDampedRotarySpring *spring, cpFloat relativeAngle){ return (relativeAngle - spring->restAngle)*spring->stiffness; @@ -40,7 +40,10 @@ preStep(cpDampedRotarySpring *spring, cpFloat dt) spring->target_wrn = 0.0f; // apply spring torque - cpFloat j_spring = spring->springTorqueFunc((cpConstraint *)spring, a->a - b->a)*dt; + cpFloat t_spring = spring->springTorqueFunc((cpConstraint *)spring, a->a - b->a); + t_spring = cpfclamp(t_spring, -spring->constraint.maxForce, spring->constraint.maxForce); + + cpFloat j_spring = t_spring*dt; spring->jAcc = j_spring; a->w -= j_spring*a->i_inv; @@ -65,8 +68,12 @@ applyImpulse(cpDampedRotarySpring *spring, cpFloat dt) //apply_impulses(a, b, spring->r1, spring->r2, cpvmult(spring->n, v_damp*spring->nMass)); cpFloat j_damp = w_damp*spring->iSum; - spring->jAcc += j_damp; + cpFloat maxImpulse = spring->constraint.maxForce*dt; + cpFloat jAccClamped = cpfclamp(spring->jAcc-j_damp, -maxImpulse, maxImpulse); + j_damp = spring->jAcc - jAccClamped; + + spring->jAcc -= j_damp; a->w += j_damp*a->i_inv; b->w -= j_damp*b->i_inv; } @@ -77,11 +84,18 @@ getImpulse(cpDampedRotarySpring *spring) return spring->jAcc; } +static void +resetAcc(cpDampedRotarySpring *spring) +{ + spring->jAcc = 0.0f; +} + static const cpConstraintClass klass = { (cpConstraintPreStepImpl)preStep, (cpConstraintApplyCachedImpulseImpl)applyCachedImpulse, (cpConstraintApplyImpulseImpl)applyImpulse, (cpConstraintGetImpulseImpl)getImpulse, + (cpConstraintResetAccImpl)resetAcc, }; cpDampedRotarySpring * diff --git a/src/cpDampedSpring.c b/src/cpDampedSpring.c index e4d019e9..8e284e19 100644 --- a/src/cpDampedSpring.c +++ b/src/cpDampedSpring.c @@ -48,7 +48,9 @@ preStep(cpDampedSpring *spring, cpFloat dt) // apply spring force cpFloat f_spring = spring->springForceFunc((cpConstraint *)spring, dist); + f_spring = cpfclamp(f_spring, -spring->constraint.maxForce, spring->constraint.maxForce); cpFloat j_spring = spring->jAcc = f_spring*dt; + apply_impulses(a, b, spring->r1, spring->r2, cpvmult(spring->n, j_spring)); } @@ -70,9 +72,15 @@ applyImpulse(cpDampedSpring *spring, cpFloat dt) // compute velocity loss from drag cpFloat v_damp = (spring->target_vrn - vrn)*spring->v_coef; spring->target_vrn = vrn + v_damp; - + cpFloat j_damp = v_damp*spring->nMass; + cpFloat maxImpulse = spring->constraint.maxForce*dt; + + cpFloat jAccClamped = cpfclamp(spring->jAcc+j_damp, -maxImpulse, maxImpulse); + j_damp = jAccClamped - spring->jAcc; + spring->jAcc += j_damp; + apply_impulses(a, b, spring->r1, spring->r2, cpvmult(spring->n, j_damp)); } @@ -82,11 +90,18 @@ getImpulse(cpDampedSpring *spring) return spring->jAcc; } +static void +resetAcc(cpDampedSpring *spring) +{ + spring->jAcc = 0.0f; +} + static const cpConstraintClass klass = { (cpConstraintPreStepImpl)preStep, (cpConstraintApplyCachedImpulseImpl)applyCachedImpulse, (cpConstraintApplyImpulseImpl)applyImpulse, (cpConstraintGetImpulseImpl)getImpulse, + (cpConstraintResetAccImpl)resetAcc, }; cpDampedSpring * diff --git a/src/cpGearJoint.c b/src/cpGearJoint.c index 3670173b..57e91282 100644 --- a/src/cpGearJoint.c +++ b/src/cpGearJoint.c @@ -74,11 +74,18 @@ getImpulse(cpGearJoint *joint) return cpfabs(joint->jAcc); } +static void +resetAcc(cpGearJoint *joint) +{ + joint->jAcc = 0.0f; +} + static const cpConstraintClass klass = { (cpConstraintPreStepImpl)preStep, (cpConstraintApplyCachedImpulseImpl)applyCachedImpulse, (cpConstraintApplyImpulseImpl)applyImpulse, (cpConstraintGetImpulseImpl)getImpulse, + (cpConstraintResetAccImpl)resetAcc, }; cpGearJoint * diff --git a/src/cpGrooveJoint.c b/src/cpGrooveJoint.c index 50d1857d..56cecf2e 100644 --- a/src/cpGrooveJoint.c +++ b/src/cpGrooveJoint.c @@ -103,11 +103,18 @@ getImpulse(cpGrooveJoint *joint) return cpvlength(joint->jAcc); } +static void +resetAcc(cpGrooveJoint *joint) +{ + joint->jAcc = cpvzero; +} + static const cpConstraintClass klass = { (cpConstraintPreStepImpl)preStep, (cpConstraintApplyCachedImpulseImpl)applyCachedImpulse, (cpConstraintApplyImpulseImpl)applyImpulse, (cpConstraintGetImpulseImpl)getImpulse, + (cpConstraintResetAccImpl)resetAcc, }; cpGrooveJoint * diff --git a/src/cpPinJoint.c b/src/cpPinJoint.c index 545e78bf..d4f7b111 100644 --- a/src/cpPinJoint.c +++ b/src/cpPinJoint.c @@ -80,14 +80,20 @@ getImpulse(cpPinJoint *joint) return cpfabs(joint->jnAcc); } +static void +resetAcc(cpPinJoint *joint) +{ + joint->jnAcc = 0.0f; +} + static const cpConstraintClass klass = { (cpConstraintPreStepImpl)preStep, (cpConstraintApplyCachedImpulseImpl)applyCachedImpulse, (cpConstraintApplyImpulseImpl)applyImpulse, (cpConstraintGetImpulseImpl)getImpulse, + (cpConstraintResetAccImpl)resetAcc, }; - cpPinJoint * cpPinJointAlloc(void) { diff --git a/src/cpPivotJoint.c b/src/cpPivotJoint.c index e45ba072..44f215df 100644 --- a/src/cpPivotJoint.c +++ b/src/cpPivotJoint.c @@ -70,9 +70,15 @@ applyImpulse(cpPivotJoint *joint, cpFloat dt) } static cpFloat -getImpulse(cpConstraint *joint) +getImpulse(cpPivotJoint *joint) { - return cpvlength(((cpPivotJoint *)joint)->jAcc); + return cpvlength(joint->jAcc); +} + +static void +resetAcc(cpPivotJoint *joint) +{ + joint->jAcc = cpvzero; } static const cpConstraintClass klass = { @@ -80,6 +86,7 @@ static const cpConstraintClass klass = { (cpConstraintApplyCachedImpulseImpl)applyCachedImpulse, (cpConstraintApplyImpulseImpl)applyImpulse, (cpConstraintGetImpulseImpl)getImpulse, + (cpConstraintResetAccImpl)resetAcc, }; cpPivotJoint * diff --git a/src/cpPolyline.c b/src/cpPolyline.c index 47b8be97..ed971f76 100644 --- a/src/cpPolyline.c +++ b/src/cpPolyline.c @@ -244,7 +244,7 @@ cpPolylineSetInit(cpPolylineSet *set) { set->count = 0; set->capacity = 8; - set->lines = (cpPolyline**) cpcalloc(set->capacity, sizeof(cpPolyline)); + set->lines = (cpPolyline**) cpcalloc(set->capacity, sizeof(cpPolyline*)); return set; } @@ -313,7 +313,7 @@ cpPolylineSetPush(cpPolylineSet *set, cpPolyline *line) set->count++; if(set->count > set->capacity){ set->capacity *= 2; - set->lines = (cpPolyline**) cprealloc(set->lines, set->capacity*sizeof(cpPolyline)); + set->lines = (cpPolyline**) cprealloc(set->lines, set->capacity*sizeof(cpPolyline*)); } set->lines[set->count - 1] = line; diff --git a/src/cpRatchetJoint.c b/src/cpRatchetJoint.c index b3c9687e..0344f4f6 100644 --- a/src/cpRatchetJoint.c +++ b/src/cpRatchetJoint.c @@ -94,11 +94,18 @@ getImpulse(cpRatchetJoint *joint) return cpfabs(joint->jAcc); } +static void +resetAcc(cpRatchetJoint *joint) +{ + joint->jAcc = 0.0f; +} + static const cpConstraintClass klass = { (cpConstraintPreStepImpl)preStep, (cpConstraintApplyCachedImpulseImpl)applyCachedImpulse, (cpConstraintApplyImpulseImpl)applyImpulse, (cpConstraintGetImpulseImpl)getImpulse, + (cpConstraintResetAccImpl)resetAcc, }; cpRatchetJoint * diff --git a/src/cpRotaryLimitJoint.c b/src/cpRotaryLimitJoint.c index 548adbeb..2710b827 100644 --- a/src/cpRotaryLimitJoint.c +++ b/src/cpRotaryLimitJoint.c @@ -91,11 +91,18 @@ getImpulse(cpRotaryLimitJoint *joint) return cpfabs(joint->jAcc); } +static void +resetAcc(cpRotaryLimitJoint *joint) +{ + joint->jAcc = 0.0f; +} + static const cpConstraintClass klass = { (cpConstraintPreStepImpl)preStep, (cpConstraintApplyCachedImpulseImpl)applyCachedImpulse, (cpConstraintApplyImpulseImpl)applyImpulse, (cpConstraintGetImpulseImpl)getImpulse, + (cpConstraintResetAccImpl)resetAcc, }; cpRotaryLimitJoint * diff --git a/src/cpShape.c b/src/cpShape.c index 513b5353..e34b7b50 100644 --- a/src/cpShape.c +++ b/src/cpShape.c @@ -151,7 +151,7 @@ cpShapeGetFriction(const cpShape *shape) void cpShapeSetFriction(cpShape *shape, cpFloat friction) { - cpAssertHard(friction >= 0.0f, "Friction must be postive."); + cpAssertHard(friction >= 0.0f, "Friction must be positive."); cpBodyActivate(shape->body); shape->u = friction; } diff --git a/src/cpSimpleMotor.c b/src/cpSimpleMotor.c index 2bea74a5..cda6a602 100644 --- a/src/cpSimpleMotor.c +++ b/src/cpSimpleMotor.c @@ -70,11 +70,18 @@ getImpulse(cpSimpleMotor *joint) return cpfabs(joint->jAcc); } +static void +resetAcc(cpSimpleMotor *joint) +{ + joint->jAcc = 0.0f; +} + static const cpConstraintClass klass = { (cpConstraintPreStepImpl)preStep, (cpConstraintApplyCachedImpulseImpl)applyCachedImpulse, (cpConstraintApplyImpulseImpl)applyImpulse, (cpConstraintGetImpulseImpl)getImpulse, + (cpConstraintResetAccImpl)resetAcc, }; cpSimpleMotor * diff --git a/src/cpSlideJoint.c b/src/cpSlideJoint.c index 61afe33e..b7a97f4d 100644 --- a/src/cpSlideJoint.c +++ b/src/cpSlideJoint.c @@ -89,9 +89,15 @@ applyImpulse(cpSlideJoint *joint, cpFloat dt) } static cpFloat -getImpulse(cpConstraint *joint) +getImpulse(cpSlideJoint *joint) { - return cpfabs(((cpSlideJoint *)joint)->jnAcc); + return cpfabs(joint->jnAcc); +} + +static void +resetAcc(cpSlideJoint *joint) +{ + joint->jnAcc = 0.0f; } static const cpConstraintClass klass = { @@ -99,6 +105,7 @@ static const cpConstraintClass klass = { (cpConstraintApplyCachedImpulseImpl)applyCachedImpulse, (cpConstraintApplyImpulseImpl)applyImpulse, (cpConstraintGetImpulseImpl)getImpulse, + (cpConstraintResetAccImpl)resetAcc, }; cpSlideJoint * diff --git a/src/cpSpaceComponent.c b/src/cpSpaceComponent.c index 7b2d6069..d4955f72 100644 --- a/src/cpSpaceComponent.c +++ b/src/cpSpaceComponent.c @@ -128,16 +128,16 @@ cpBodyActivate(cpBody *body) cpAssertSoft(cpBodyGetType(root) == CP_BODY_TYPE_DYNAMIC, "Internal Error: Non-dynamic body component root detected."); cpSpace *space = root->space; - cpBody *body = root; - while(body){ - cpBody *next = body->sleeping.next; + cpBody *bodyA = root; + while(bodyA){ + cpBody *next = bodyA->sleeping.next; - body->sleeping.idleTime = 0.0f; - body->sleeping.root = NULL; - body->sleeping.next = NULL; - cpSpaceActivateBody(space, body); + bodyA->sleeping.idleTime = 0.0f; + bodyA->sleeping.root = NULL; + bodyA->sleeping.next = NULL; + cpSpaceActivateBody(space, bodyA); - body = next; + bodyA = next; } cpArrayDeleteObj(space->sleepingComponents, root); diff --git a/src/cpSpaceHash.c b/src/cpSpaceHash.c index 556c8d38..b5369739 100644 --- a/src/cpSpaceHash.c +++ b/src/cpSpaceHash.c @@ -69,7 +69,7 @@ cpHandleRelease(cpHandle *hand, cpArray *pooledHandles) if(hand->retain == 0) cpArrayPush(pooledHandles, hand); } -static int handleSetEql(void *obj, cpHandle *hand){return (obj == hand->obj);} +static cpBool handleSetEql(void *obj, cpHandle *hand){return (obj == hand->obj);} static void * handleSetTrans(void *obj, cpSpaceHash *hash) @@ -564,7 +564,7 @@ cpSpaceHashCount(cpSpaceHash *hash) return cpHashSetCount(hash->handleSet); } -static int +static cpBool cpSpaceHashContains(cpSpaceHash *hash, void *obj, cpHashValue hashid) { return cpHashSetFind(hash->handleSet, hashid, obj) != NULL; diff --git a/src/cpSpaceQuery.c b/src/cpSpaceQuery.c index 1ce4a10c..c6011a25 100644 --- a/src/cpSpaceQuery.c +++ b/src/cpSpaceQuery.c @@ -224,7 +224,7 @@ ShapeQuery(cpShape *a, cpShape *b, cpCollisionID id, struct ShapeQueryContext *c cpContactPointSet set = cpShapesCollide(a, b); if(set.count){ if(context->func) context->func(b, &set, context->data); - context->anyCollision = !(a->sensor || b->sensor); + context->anyCollision |= !(a->sensor || b->sensor); } return id; diff --git a/src/cpSweep1D.c b/src/cpSweep1D.c index 94c4e225..42bffbcc 100644 --- a/src/cpSweep1D.c +++ b/src/cpSweep1D.c @@ -117,7 +117,7 @@ cpSweep1DEach(cpSweep1D *sweep, cpSpatialIndexIteratorFunc func, void *data) for(int i=0, count=sweep->num; itable; diff --git a/src/prime.h b/src/prime.h index d470c2cd..5e830883 100644 --- a/src/prime.h +++ b/src/prime.h @@ -21,7 +21,7 @@ // Used for resizing hash tables. // Values approximately double. -// http://planetmath.org/encyclopedia/GoodHashTablePrimes.html +// https://planetmath.org/goodhashtableprimes static int primes[] = { 5, 13,