chipmunk 5.3.4.5 → 6.1.3.0.rc1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (73) hide show
  1. data/ext/chipmunk/chipmunk.c +199 -28
  2. data/ext/chipmunk/chipmunk.h +123 -68
  3. data/ext/chipmunk/chipmunk_ffi.h +129 -11
  4. data/ext/chipmunk/chipmunk_private.h +232 -16
  5. data/ext/chipmunk/chipmunk_types.h +94 -30
  6. data/ext/chipmunk/chipmunk_unsafe.h +12 -3
  7. data/ext/chipmunk/constraints/cpConstraint.h +90 -34
  8. data/ext/chipmunk/{cpDampedRotarySpring.h → constraints/cpDampedRotarySpring.h} +18 -8
  9. data/ext/chipmunk/{cpDampedSpring.h → constraints/cpDampedSpring.h} +27 -16
  10. data/ext/chipmunk/constraints/cpGearJoint.h +17 -7
  11. data/ext/chipmunk/constraints/cpGrooveJoint.h +19 -10
  12. data/ext/chipmunk/constraints/cpPinJoint.h +17 -8
  13. data/ext/chipmunk/constraints/cpPivotJoint.h +18 -9
  14. data/ext/chipmunk/constraints/cpRatchetJoint.h +17 -8
  15. data/ext/chipmunk/constraints/cpRotaryLimitJoint.h +16 -7
  16. data/ext/chipmunk/{cpSimpleMotor.h → constraints/cpSimpleMotor.h} +15 -6
  17. data/ext/chipmunk/constraints/cpSlideJoint.h +18 -9
  18. data/ext/chipmunk/constraints/util.h +36 -44
  19. data/ext/chipmunk/cpArbiter.c +159 -94
  20. data/ext/chipmunk/cpArbiter.h +135 -129
  21. data/ext/chipmunk/cpArray.c +37 -56
  22. data/ext/chipmunk/cpBB.c +1 -12
  23. data/ext/chipmunk/cpBB.h +80 -18
  24. data/ext/chipmunk/cpBBTree.c +891 -0
  25. data/ext/chipmunk/cpBody.c +185 -47
  26. data/ext/chipmunk/cpBody.h +156 -124
  27. data/ext/chipmunk/cpCollision.c +126 -115
  28. data/ext/chipmunk/cpConstraint.c +10 -6
  29. data/ext/chipmunk/cpDampedRotarySpring.c +26 -17
  30. data/ext/chipmunk/cpDampedSpring.c +25 -18
  31. data/ext/chipmunk/cpGearJoint.c +23 -17
  32. data/ext/chipmunk/cpGrooveJoint.c +26 -22
  33. data/ext/chipmunk/cpHashSet.c +51 -51
  34. data/ext/chipmunk/cpPinJoint.c +26 -19
  35. data/ext/chipmunk/cpPivotJoint.c +23 -19
  36. data/ext/chipmunk/cpPolyShape.c +93 -69
  37. data/ext/chipmunk/cpPolyShape.h +33 -69
  38. data/ext/chipmunk/cpRatchetJoint.c +26 -21
  39. data/ext/chipmunk/cpRotaryLimitJoint.c +28 -22
  40. data/ext/chipmunk/cpShape.c +122 -133
  41. data/ext/chipmunk/cpShape.h +146 -95
  42. data/ext/chipmunk/cpSimpleMotor.c +24 -17
  43. data/ext/chipmunk/cpSlideJoint.c +28 -26
  44. data/ext/chipmunk/cpSpace.c +251 -196
  45. data/ext/chipmunk/cpSpace.h +173 -103
  46. data/ext/chipmunk/cpSpaceComponent.c +236 -159
  47. data/ext/chipmunk/cpSpaceHash.c +259 -159
  48. data/ext/chipmunk/cpSpaceQuery.c +127 -59
  49. data/ext/chipmunk/cpSpaceStep.c +235 -197
  50. data/ext/chipmunk/cpSpatialIndex.c +69 -0
  51. data/ext/chipmunk/cpSpatialIndex.h +227 -0
  52. data/ext/chipmunk/cpSweep1D.c +254 -0
  53. data/ext/chipmunk/cpVect.c +11 -26
  54. data/ext/chipmunk/cpVect.h +76 -71
  55. data/ext/chipmunk/extconf.rb +4 -31
  56. data/ext/chipmunk/prime.h +1 -1
  57. data/ext/chipmunk/rb_chipmunk.c +36 -45
  58. data/ext/chipmunk/rb_chipmunk.h +6 -3
  59. data/ext/chipmunk/rb_cpArbiter.c +2 -2
  60. data/ext/chipmunk/rb_cpBB.c +116 -35
  61. data/ext/chipmunk/rb_cpBody.c +5 -12
  62. data/ext/chipmunk/rb_cpConstraint.c +144 -9
  63. data/ext/chipmunk/rb_cpShape.c +69 -78
  64. data/ext/chipmunk/rb_cpSpace.c +81 -76
  65. metadata +61 -61
  66. data/LICENSE +0 -22
  67. data/README +0 -110
  68. data/Rakefile +0 -102
  69. data/ext/chipmunk/cpArray.h +0 -49
  70. data/ext/chipmunk/cpCollision.h +0 -28
  71. data/ext/chipmunk/cpHashSet.h +0 -82
  72. data/ext/chipmunk/cpSpaceHash.h +0 -110
  73. data/lib/chipmunk.rb +0 -194
@@ -19,17 +19,33 @@
19
19
  * SOFTWARE.
20
20
  */
21
21
 
22
- // Forward declarations required for defining other structs.
23
- struct cpShape;
24
- struct cpShapeClass;
25
-
22
+ /// @defgroup cpShape cpShape
23
+ /// The cpShape struct defines the shape of a rigid body.
24
+ /// @{
25
+
26
+ typedef struct cpShapeClass cpShapeClass;
27
+
28
+ /// Nearest point query info struct.
29
+ typedef struct cpNearestPointQueryInfo {
30
+ /// The nearest shape, NULL if no shape was within range.
31
+ cpShape *shape;
32
+ /// The closest point on the shape's surface. (in world space coordinates)
33
+ cpVect p;
34
+ /// The distance to the point. The distance is negative if the point is inside the shape.
35
+ cpFloat d;
36
+ } cpNearestPointQueryInfo;
37
+
38
+ /// Segment query info struct.
26
39
  typedef struct cpSegmentQueryInfo {
27
- struct cpShape *shape; // shape that was hit, NULL if no collision
28
- cpFloat t; // Distance along query segment, will always be in the range [0, 1].
29
- cpVect n; // normal of hit surface
40
+ /// The shape that was hit, NULL if no collision occured.
41
+ cpShape *shape;
42
+ /// The normalized distance along the query segment in the range [0, 1].
43
+ cpFloat t;
44
+ /// The normal of the surface hit.
45
+ cpVect n;
30
46
  } cpSegmentQueryInfo;
31
47
 
32
- // Enumeration of shape types.
48
+ /// @private
33
49
  typedef enum cpShapeType{
34
50
  CP_CIRCLE_SHAPE,
35
51
  CP_SEGMENT_SHAPE,
@@ -37,141 +53,176 @@ typedef enum cpShapeType{
37
53
  CP_NUM_SHAPES
38
54
  } cpShapeType;
39
55
 
40
- // Shape class. Holds function pointers and type data.
41
- typedef struct cpShapeClass {
56
+ typedef cpBB (*cpShapeCacheDataImpl)(cpShape *shape, cpVect p, cpVect rot);
57
+ typedef void (*cpShapeDestroyImpl)(cpShape *shape);
58
+ typedef void (*cpShapeNearestPointQueryImpl)(cpShape *shape, cpVect p, cpNearestPointQueryInfo *info);
59
+ typedef void (*cpShapeSegmentQueryImpl)(cpShape *shape, cpVect a, cpVect b, cpSegmentQueryInfo *info);
60
+
61
+ /// @private
62
+ struct cpShapeClass {
42
63
  cpShapeType type;
43
64
 
44
- // Called by cpShapeCacheBB().
45
- cpBB (*cacheData)(struct cpShape *shape, cpVect p, cpVect rot);
46
- // Called to by cpShapeDestroy().
47
- void (*destroy)(struct cpShape *shape);
48
-
49
- // called by cpShapePointQuery().
50
- cpBool (*pointQuery)(struct cpShape *shape, cpVect p);
51
-
52
- // called by cpShapeSegmentQuery()
53
- void (*segmentQuery)(struct cpShape *shape, cpVect a, cpVect b, cpSegmentQueryInfo *info);
54
- } cpShapeClass;
55
-
56
- // Basic shape struct that the others inherit from.
57
- typedef struct cpShape{
58
- // The "class" of a shape as defined above
65
+ cpShapeCacheDataImpl cacheData;
66
+ cpShapeDestroyImpl destroy;
67
+ cpShapeNearestPointQueryImpl nearestPointQuery;
68
+ cpShapeSegmentQueryImpl segmentQuery;
69
+ };
70
+
71
+ /// Opaque collision shape struct.
72
+ struct cpShape {
59
73
  CP_PRIVATE(const cpShapeClass *klass);
60
74
 
61
- // cpBody that the shape is attached to.
75
+ /// The rigid body this collision shape is attached to.
62
76
  cpBody *body;
63
77
 
64
- // Cached BBox for the shape.
78
+ /// The current bounding box of the shape.
65
79
  cpBB bb;
66
80
 
67
- // Sensors invoke callbacks, but do not generate collisions
81
+ /// Sensor flag.
82
+ /// Sensor shapes call collision callbacks but don't produce collisions.
68
83
  cpBool sensor;
69
84
 
70
- // *** Surface properties.
71
-
72
- // Coefficient of restitution. (elasticity)
85
+ /// Coefficient of restitution. (elasticity)
73
86
  cpFloat e;
74
- // Coefficient of friction.
87
+ /// Coefficient of friction.
75
88
  cpFloat u;
76
- // Surface velocity used when solving for friction.
89
+ /// Surface velocity used when solving for friction.
77
90
  cpVect surface_v;
78
91
 
79
- // *** User Definable Fields
80
-
81
- // User defined data pointer for the shape.
92
+ /// User definable data pointer.
93
+ /// Generally this points to your the game object class so you can access it
94
+ /// when given a cpShape reference in a callback.
82
95
  cpDataPointer data;
83
96
 
84
- // User defined collision type for the shape.
97
+ /// Collision type of this shape used when picking collision handlers.
85
98
  cpCollisionType collision_type;
86
- // User defined collision group for the shape.
99
+ /// Group of this shape. Shapes in the same group don't collide.
87
100
  cpGroup group;
88
- // User defined layer bitmask for the shape.
101
+ // Layer bitmask for this shape. Shapes only collide if the bitwise and of their layers is non-zero.
89
102
  cpLayers layers;
90
103
 
91
- // *** Internally Used Fields
104
+ CP_PRIVATE(cpSpace *space);
92
105
 
93
- // Shapes form a linked list when added to space on a non-NULL body
94
- CP_PRIVATE(struct cpShape *next);
106
+ CP_PRIVATE(cpShape *next);
107
+ CP_PRIVATE(cpShape *prev);
95
108
 
96
- // Unique id used as the hash value.
97
109
  CP_PRIVATE(cpHashValue hashid);
98
- } cpShape;
99
-
100
- // Low level shape initialization func.
101
- cpShape* cpShapeInit(cpShape *shape, const struct cpShapeClass *klass, cpBody *body);
110
+ };
102
111
 
103
- // Basic destructor functions. (allocation functions are not shared)
112
+ /// Destroy a shape.
104
113
  void cpShapeDestroy(cpShape *shape);
114
+ /// Destroy and Free a shape.
105
115
  void cpShapeFree(cpShape *shape);
106
116
 
107
- // Cache the BBox of the shape.
117
+ /// Update, cache and return the bounding box of a shape based on the body it's attached to.
108
118
  cpBB cpShapeCacheBB(cpShape *shape);
119
+ /// Update, cache and return the bounding box of a shape with an explicit transformation.
120
+ cpBB cpShapeUpdate(cpShape *shape, cpVect pos, cpVect rot);
109
121
 
110
- // Test if a point lies within a shape.
122
+ /// Test if a point lies within a shape.
111
123
  cpBool cpShapePointQuery(cpShape *shape, cpVect p);
112
124
 
113
- #define CP_DeclareShapeGetter(struct, type, name) type struct##Get##name(cpShape *shape)
125
+ /// Perform a nearest point query. It finds the closest point on the surface of shape to a specific point.
126
+ /// The value returned is the distance between the points. A negative distance means the point is inside the shape.
127
+ cpFloat cpShapeNearestPointQuery(cpShape *shape, cpVect p, cpNearestPointQueryInfo *out);
114
128
 
115
- // Circle shape structure.
116
- typedef struct cpCircleShape{
117
- CP_PRIVATE(cpShape shape);
118
-
119
- // Center in body space coordinates
120
- CP_PRIVATE(cpVect c);
121
- // Radius.
122
- CP_PRIVATE(cpFloat r);
129
+ /// Perform a segment query against a shape. @c info must be a pointer to a valid cpSegmentQueryInfo structure.
130
+ cpBool cpShapeSegmentQuery(cpShape *shape, cpVect a, cpVect b, cpSegmentQueryInfo *info);
131
+
132
+ /// Get the hit point for a segment query.
133
+ static inline cpVect cpSegmentQueryHitPoint(const cpVect start, const cpVect end, const cpSegmentQueryInfo info)
134
+ {
135
+ return cpvlerp(start, end, info.t);
136
+ }
137
+
138
+ /// Get the hit distance for a segment query.
139
+ static inline cpFloat cpSegmentQueryHitDist(const cpVect start, const cpVect end, const cpSegmentQueryInfo info)
140
+ {
141
+ return cpvdist(start, end)*info.t;
142
+ }
143
+
144
+ #define CP_DefineShapeStructGetter(type, member, name) \
145
+ static inline type cpShapeGet##name(const cpShape *shape){return shape->member;}
146
+
147
+ #define CP_DefineShapeStructSetter(type, member, name, activates) \
148
+ static inline void cpShapeSet##name(cpShape *shape, type value){ \
149
+ if(activates && shape->body) cpBodyActivate(shape->body); \
150
+ shape->member = value; \
151
+ }
152
+
153
+ #define CP_DefineShapeStructProperty(type, member, name, activates) \
154
+ CP_DefineShapeStructGetter(type, member, name) \
155
+ CP_DefineShapeStructSetter(type, member, name, activates)
156
+
157
+ CP_DefineShapeStructGetter(cpSpace*, CP_PRIVATE(space), Space)
158
+
159
+ CP_DefineShapeStructGetter(cpBody*, body, Body)
160
+ void cpShapeSetBody(cpShape *shape, cpBody *body);
161
+
162
+ CP_DefineShapeStructGetter(cpBB, bb, BB)
163
+ CP_DefineShapeStructProperty(cpBool, sensor, Sensor, cpTrue)
164
+ CP_DefineShapeStructProperty(cpFloat, e, Elasticity, cpFalse)
165
+ CP_DefineShapeStructProperty(cpFloat, u, Friction, cpTrue)
166
+ CP_DefineShapeStructProperty(cpVect, surface_v, SurfaceVelocity, cpTrue)
167
+ CP_DefineShapeStructProperty(cpDataPointer, data, UserData, cpFalse)
168
+ CP_DefineShapeStructProperty(cpCollisionType, collision_type, CollisionType, cpTrue)
169
+ CP_DefineShapeStructProperty(cpGroup, group, Group, cpTrue)
170
+ CP_DefineShapeStructProperty(cpLayers, layers, Layers, cpTrue)
171
+
172
+ /// When initializing a shape, it's hash value comes from a counter.
173
+ /// Because the hash value may affect iteration order, you can reset the shape ID counter
174
+ /// when recreating a space. This will make the simulation be deterministic.
175
+ void cpResetShapeIdCounter(void);
176
+
177
+ #define CP_DeclareShapeGetter(struct, type, name) type struct##Get##name(const cpShape *shape)
178
+
179
+ /// @}
180
+ /// @defgroup cpCircleShape cpCircleShape
181
+
182
+ /// @private
183
+ typedef struct cpCircleShape {
184
+ cpShape shape;
123
185
 
124
- // Transformed center. (world space coordinates)
125
- CP_PRIVATE(cpVect tc);
186
+ cpVect c, tc;
187
+ cpFloat r;
126
188
  } cpCircleShape;
127
189
 
128
- // Basic allocation functions for cpCircleShape.
129
- cpCircleShape *cpCircleShapeAlloc(void);
130
- cpCircleShape *cpCircleShapeInit(cpCircleShape *circle, cpBody *body, cpFloat radius, cpVect offset);
131
- cpShape *cpCircleShapeNew(cpBody *body, cpFloat radius, cpVect offset);
190
+ /// Allocate a circle shape.
191
+ cpCircleShape* cpCircleShapeAlloc(void);
192
+ /// Initialize a circle shape.
193
+ cpCircleShape* cpCircleShapeInit(cpCircleShape *circle, cpBody *body, cpFloat radius, cpVect offset);
194
+ /// Allocate and initialize a circle shape.
195
+ cpShape* cpCircleShapeNew(cpBody *body, cpFloat radius, cpVect offset);
132
196
 
133
197
  CP_DeclareShapeGetter(cpCircleShape, cpVect, Offset);
134
198
  CP_DeclareShapeGetter(cpCircleShape, cpFloat, Radius);
135
199
 
136
- // Segment shape structure.
137
- typedef struct cpSegmentShape{
138
- CP_PRIVATE(cpShape shape);
139
-
140
- // Endpoints and normal of the segment. (body space coordinates)
141
- cpVect CP_PRIVATE(a), CP_PRIVATE(b), CP_PRIVATE(n);
142
- // Radius of the segment. (Thickness)
143
- cpFloat CP_PRIVATE(r);
200
+ /// @}
201
+ /// @defgroup cpSegmentShape cpSegmentShape
144
202
 
145
- // Transformed endpoints and normal. (world space coordinates)
146
- cpVect CP_PRIVATE(ta), CP_PRIVATE(tb), CP_PRIVATE(tn);
203
+ /// @private
204
+ typedef struct cpSegmentShape {
205
+ cpShape shape;
206
+
207
+ cpVect a, b, n;
208
+ cpVect ta, tb, tn;
209
+ cpFloat r;
210
+
211
+ cpVect a_tangent, b_tangent;
147
212
  } cpSegmentShape;
148
213
 
149
- // Basic allocation functions for cpSegmentShape.
214
+ /// Allocate a segment shape.
150
215
  cpSegmentShape* cpSegmentShapeAlloc(void);
216
+ /// Initialize a segment shape.
151
217
  cpSegmentShape* cpSegmentShapeInit(cpSegmentShape *seg, cpBody *body, cpVect a, cpVect b, cpFloat radius);
218
+ /// Allocate and initialize a segment shape.
152
219
  cpShape* cpSegmentShapeNew(cpBody *body, cpVect a, cpVect b, cpFloat radius);
153
220
 
221
+ void cpSegmentShapeSetNeighbors(cpShape *shape, cpVect prev, cpVect next);
222
+
154
223
  CP_DeclareShapeGetter(cpSegmentShape, cpVect, A);
155
224
  CP_DeclareShapeGetter(cpSegmentShape, cpVect, B);
156
225
  CP_DeclareShapeGetter(cpSegmentShape, cpVect, Normal);
157
226
  CP_DeclareShapeGetter(cpSegmentShape, cpFloat, Radius);
158
227
 
159
- // For determinism, you can reset the shape id counter.
160
- void cpResetShapeIdCounter(void);
161
-
162
- // Directed segment queries against individual shapes.
163
- void cpSegmentQueryInfoPrint(cpSegmentQueryInfo *info);
164
-
165
- cpBool cpShapeSegmentQuery(cpShape *shape, cpVect a, cpVect b, cpSegmentQueryInfo *info);
166
-
167
- static inline cpVect
168
- cpSegmentQueryHitPoint(const cpVect start, const cpVect end, const cpSegmentQueryInfo info)
169
- {
170
- return cpvlerp(start, end, info.t);
171
- }
172
-
173
- static inline cpFloat
174
- cpSegmentQueryHitDist(const cpVect start, const cpVect end, const cpSegmentQueryInfo info)
175
- {
176
- return cpvdist(start, end)*info.t;
177
- }
228
+ /// @}
@@ -19,39 +19,45 @@
19
19
  * SOFTWARE.
20
20
  */
21
21
 
22
- #include <stdlib.h>
23
-
24
22
  #include "chipmunk_private.h"
25
23
  #include "constraints/util.h"
26
24
 
27
25
  static void
28
- preStep(cpSimpleMotor *joint, cpFloat dt, cpFloat dt_inv)
26
+ preStep(cpSimpleMotor *joint, cpFloat dt)
29
27
  {
30
- CONSTRAINT_BEGIN(joint, a, b);
28
+ cpBody *a = joint->constraint.a;
29
+ cpBody *b = joint->constraint.b;
31
30
 
32
31
  // calculate moment of inertia coefficient.
33
32
  joint->iSum = 1.0f/(a->i_inv + b->i_inv);
34
-
35
- // compute max impulse
36
- joint->jMax = J_MAX(joint, dt);
33
+ }
37
34
 
38
- // apply joint torque
39
- a->w -= joint->jAcc*a->i_inv;
40
- b->w += joint->jAcc*b->i_inv;
35
+ static void
36
+ applyCachedImpulse(cpSimpleMotor *joint, cpFloat dt_coef)
37
+ {
38
+ cpBody *a = joint->constraint.a;
39
+ cpBody *b = joint->constraint.b;
40
+
41
+ cpFloat j = joint->jAcc*dt_coef;
42
+ a->w -= j*a->i_inv;
43
+ b->w += j*b->i_inv;
41
44
  }
42
45
 
43
46
  static void
44
- applyImpulse(cpSimpleMotor *joint)
47
+ applyImpulse(cpSimpleMotor *joint, cpFloat dt)
45
48
  {
46
- CONSTRAINT_BEGIN(joint, a, b);
49
+ cpBody *a = joint->constraint.a;
50
+ cpBody *b = joint->constraint.b;
47
51
 
48
52
  // compute relative rotational velocity
49
53
  cpFloat wr = b->w - a->w + joint->rate;
50
54
 
55
+ cpFloat jMax = joint->constraint.maxForce*dt;
56
+
51
57
  // compute normal impulse
52
58
  cpFloat j = -wr*joint->iSum;
53
59
  cpFloat jOld = joint->jAcc;
54
- joint->jAcc = cpfclamp(jOld + j, -joint->jMax, joint->jMax);
60
+ joint->jAcc = cpfclamp(jOld + j, -jMax, jMax);
55
61
  j = joint->jAcc - jOld;
56
62
 
57
63
  // apply impulse
@@ -66,16 +72,17 @@ getImpulse(cpSimpleMotor *joint)
66
72
  }
67
73
 
68
74
  static const cpConstraintClass klass = {
69
- (cpConstraintPreStepFunction)preStep,
70
- (cpConstraintApplyImpulseFunction)applyImpulse,
71
- (cpConstraintGetImpulseFunction)getImpulse,
75
+ (cpConstraintPreStepImpl)preStep,
76
+ (cpConstraintApplyCachedImpulseImpl)applyCachedImpulse,
77
+ (cpConstraintApplyImpulseImpl)applyImpulse,
78
+ (cpConstraintGetImpulseImpl)getImpulse,
72
79
  };
73
80
  CP_DefineClassGetter(cpSimpleMotor)
74
81
 
75
82
  cpSimpleMotor *
76
83
  cpSimpleMotorAlloc(void)
77
84
  {
78
- return (cpSimpleMotor *)cpmalloc(sizeof(cpSimpleMotor));
85
+ return (cpSimpleMotor *)cpcalloc(1, sizeof(cpSimpleMotor));
79
86
  }
80
87
 
81
88
  cpSimpleMotor *
@@ -19,15 +19,14 @@
19
19
  * SOFTWARE.
20
20
  */
21
21
 
22
- #include <stdlib.h>
23
-
24
22
  #include "chipmunk_private.h"
25
23
  #include "constraints/util.h"
26
24
 
27
25
  static void
28
- preStep(cpSlideJoint *joint, cpFloat dt, cpFloat dt_inv)
26
+ preStep(cpSlideJoint *joint, cpFloat dt)
29
27
  {
30
- CONSTRAINT_BEGIN(joint, a, b);
28
+ cpBody *a = joint->constraint.a;
29
+ cpBody *b = joint->constraint.b;
31
30
 
32
31
  joint->r1 = cpvrotate(joint->anchr1, a->rot);
33
32
  joint->r2 = cpvrotate(joint->anchr2, b->rot);
@@ -37,38 +36,40 @@ preStep(cpSlideJoint *joint, cpFloat dt, cpFloat dt_inv)
37
36
  cpFloat pdist = 0.0f;
38
37
  if(dist > joint->max) {
39
38
  pdist = dist - joint->max;
39
+ joint->n = cpvnormalize_safe(delta);
40
40
  } else if(dist < joint->min) {
41
41
  pdist = joint->min - dist;
42
- dist = -dist;
42
+ joint->n = cpvneg(cpvnormalize_safe(delta));
43
+ } else {
44
+ joint->n = cpvzero;
45
+ joint->jnAcc = 0.0f;
43
46
  }
44
- joint->n = cpvmult(delta, 1.0f/(dist ? dist : (cpFloat)INFINITY));
45
47
 
46
48
  // calculate mass normal
47
49
  joint->nMass = 1.0f/k_scalar(a, b, joint->r1, joint->r2, joint->n);
48
50
 
49
51
  // calculate bias velocity
50
52
  cpFloat maxBias = joint->constraint.maxBias;
51
- joint->bias = cpfclamp(-joint->constraint.biasCoef*dt_inv*(pdist), -maxBias, maxBias);
52
-
53
- // compute max impulse
54
- joint->jnMax = J_MAX(joint, dt);
53
+ joint->bias = cpfclamp(-bias_coef(joint->constraint.errorBias, dt)*pdist/dt, -maxBias, maxBias);
54
+ }
55
55
 
56
- // apply accumulated impulse
57
- if(!joint->bias) //{
58
- // if bias is 0, then the joint is not at a limit.
59
- joint->jnAcc = 0.0f;
60
- // } else {
61
- cpVect j = cpvmult(joint->n, joint->jnAcc);
62
- apply_impulses(a, b, joint->r1, joint->r2, j);
63
- // }
56
+ static void
57
+ applyCachedImpulse(cpSlideJoint *joint, cpFloat dt_coef)
58
+ {
59
+ cpBody *a = joint->constraint.a;
60
+ cpBody *b = joint->constraint.b;
61
+
62
+ cpVect j = cpvmult(joint->n, joint->jnAcc*dt_coef);
63
+ apply_impulses(a, b, joint->r1, joint->r2, j);
64
64
  }
65
65
 
66
66
  static void
67
- applyImpulse(cpSlideJoint *joint)
67
+ applyImpulse(cpSlideJoint *joint, cpFloat dt)
68
68
  {
69
- if(!joint->bias) return; // early exit
69
+ if(cpveql(joint->n, cpvzero)) return; // early exit
70
70
 
71
- CONSTRAINT_BEGIN(joint, a, b);
71
+ cpBody *a = joint->constraint.a;
72
+ cpBody *b = joint->constraint.b;
72
73
 
73
74
  cpVect n = joint->n;
74
75
  cpVect r1 = joint->r1;
@@ -81,7 +82,7 @@ applyImpulse(cpSlideJoint *joint)
81
82
  // compute normal impulse
82
83
  cpFloat jn = (joint->bias - vrn)*joint->nMass;
83
84
  cpFloat jnOld = joint->jnAcc;
84
- joint->jnAcc = cpfclamp(jnOld + jn, -joint->jnMax, 0.0f);
85
+ joint->jnAcc = cpfclamp(jnOld + jn, -joint->constraint.maxForce*dt, 0.0f);
85
86
  jn = joint->jnAcc - jnOld;
86
87
 
87
88
  // apply impulse
@@ -95,16 +96,17 @@ getImpulse(cpConstraint *joint)
95
96
  }
96
97
 
97
98
  static const cpConstraintClass klass = {
98
- (cpConstraintPreStepFunction)preStep,
99
- (cpConstraintApplyImpulseFunction)applyImpulse,
100
- (cpConstraintGetImpulseFunction)getImpulse,
99
+ (cpConstraintPreStepImpl)preStep,
100
+ (cpConstraintApplyCachedImpulseImpl)applyCachedImpulse,
101
+ (cpConstraintApplyImpulseImpl)applyImpulse,
102
+ (cpConstraintGetImpulseImpl)getImpulse,
101
103
  };
102
104
  CP_DefineClassGetter(cpSlideJoint)
103
105
 
104
106
  cpSlideJoint *
105
107
  cpSlideJointAlloc(void)
106
108
  {
107
- return (cpSlideJoint *)cpmalloc(sizeof(cpSlideJoint));
109
+ return (cpSlideJoint *)cpcalloc(1, sizeof(cpSlideJoint));
108
110
  }
109
111
 
110
112
  cpSlideJoint *