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.
- data/ext/chipmunk/chipmunk.c +199 -28
- data/ext/chipmunk/chipmunk.h +123 -68
- data/ext/chipmunk/chipmunk_ffi.h +129 -11
- data/ext/chipmunk/chipmunk_private.h +232 -16
- data/ext/chipmunk/chipmunk_types.h +94 -30
- data/ext/chipmunk/chipmunk_unsafe.h +12 -3
- data/ext/chipmunk/constraints/cpConstraint.h +90 -34
- data/ext/chipmunk/{cpDampedRotarySpring.h → constraints/cpDampedRotarySpring.h} +18 -8
- data/ext/chipmunk/{cpDampedSpring.h → constraints/cpDampedSpring.h} +27 -16
- data/ext/chipmunk/constraints/cpGearJoint.h +17 -7
- data/ext/chipmunk/constraints/cpGrooveJoint.h +19 -10
- data/ext/chipmunk/constraints/cpPinJoint.h +17 -8
- data/ext/chipmunk/constraints/cpPivotJoint.h +18 -9
- data/ext/chipmunk/constraints/cpRatchetJoint.h +17 -8
- data/ext/chipmunk/constraints/cpRotaryLimitJoint.h +16 -7
- data/ext/chipmunk/{cpSimpleMotor.h → constraints/cpSimpleMotor.h} +15 -6
- data/ext/chipmunk/constraints/cpSlideJoint.h +18 -9
- data/ext/chipmunk/constraints/util.h +36 -44
- data/ext/chipmunk/cpArbiter.c +159 -94
- data/ext/chipmunk/cpArbiter.h +135 -129
- data/ext/chipmunk/cpArray.c +37 -56
- data/ext/chipmunk/cpBB.c +1 -12
- data/ext/chipmunk/cpBB.h +80 -18
- data/ext/chipmunk/cpBBTree.c +891 -0
- data/ext/chipmunk/cpBody.c +185 -47
- data/ext/chipmunk/cpBody.h +156 -124
- data/ext/chipmunk/cpCollision.c +126 -115
- data/ext/chipmunk/cpConstraint.c +10 -6
- data/ext/chipmunk/cpDampedRotarySpring.c +26 -17
- data/ext/chipmunk/cpDampedSpring.c +25 -18
- data/ext/chipmunk/cpGearJoint.c +23 -17
- data/ext/chipmunk/cpGrooveJoint.c +26 -22
- data/ext/chipmunk/cpHashSet.c +51 -51
- data/ext/chipmunk/cpPinJoint.c +26 -19
- data/ext/chipmunk/cpPivotJoint.c +23 -19
- data/ext/chipmunk/cpPolyShape.c +93 -69
- data/ext/chipmunk/cpPolyShape.h +33 -69
- data/ext/chipmunk/cpRatchetJoint.c +26 -21
- data/ext/chipmunk/cpRotaryLimitJoint.c +28 -22
- data/ext/chipmunk/cpShape.c +122 -133
- data/ext/chipmunk/cpShape.h +146 -95
- data/ext/chipmunk/cpSimpleMotor.c +24 -17
- data/ext/chipmunk/cpSlideJoint.c +28 -26
- data/ext/chipmunk/cpSpace.c +251 -196
- data/ext/chipmunk/cpSpace.h +173 -103
- data/ext/chipmunk/cpSpaceComponent.c +236 -159
- data/ext/chipmunk/cpSpaceHash.c +259 -159
- data/ext/chipmunk/cpSpaceQuery.c +127 -59
- data/ext/chipmunk/cpSpaceStep.c +235 -197
- data/ext/chipmunk/cpSpatialIndex.c +69 -0
- data/ext/chipmunk/cpSpatialIndex.h +227 -0
- data/ext/chipmunk/cpSweep1D.c +254 -0
- data/ext/chipmunk/cpVect.c +11 -26
- data/ext/chipmunk/cpVect.h +76 -71
- data/ext/chipmunk/extconf.rb +4 -31
- data/ext/chipmunk/prime.h +1 -1
- data/ext/chipmunk/rb_chipmunk.c +36 -45
- data/ext/chipmunk/rb_chipmunk.h +6 -3
- data/ext/chipmunk/rb_cpArbiter.c +2 -2
- data/ext/chipmunk/rb_cpBB.c +116 -35
- data/ext/chipmunk/rb_cpBody.c +5 -12
- data/ext/chipmunk/rb_cpConstraint.c +144 -9
- data/ext/chipmunk/rb_cpShape.c +69 -78
- data/ext/chipmunk/rb_cpSpace.c +81 -76
- metadata +61 -61
- data/LICENSE +0 -22
- data/README +0 -110
- data/Rakefile +0 -102
- data/ext/chipmunk/cpArray.h +0 -49
- data/ext/chipmunk/cpCollision.h +0 -28
- data/ext/chipmunk/cpHashSet.h +0 -82
- data/ext/chipmunk/cpSpaceHash.h +0 -110
- data/lib/chipmunk.rb +0 -194
data/ext/chipmunk/cpShape.h
CHANGED
@@ -19,17 +19,33 @@
|
|
19
19
|
* SOFTWARE.
|
20
20
|
*/
|
21
21
|
|
22
|
-
|
23
|
-
struct
|
24
|
-
|
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
|
-
|
28
|
-
|
29
|
-
|
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
|
-
|
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
|
-
|
41
|
-
typedef
|
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
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
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
|
-
|
75
|
+
/// The rigid body this collision shape is attached to.
|
62
76
|
cpBody *body;
|
63
77
|
|
64
|
-
|
78
|
+
/// The current bounding box of the shape.
|
65
79
|
cpBB bb;
|
66
80
|
|
67
|
-
|
81
|
+
/// Sensor flag.
|
82
|
+
/// Sensor shapes call collision callbacks but don't produce collisions.
|
68
83
|
cpBool sensor;
|
69
84
|
|
70
|
-
|
71
|
-
|
72
|
-
// Coefficient of restitution. (elasticity)
|
85
|
+
/// Coefficient of restitution. (elasticity)
|
73
86
|
cpFloat e;
|
74
|
-
|
87
|
+
/// Coefficient of friction.
|
75
88
|
cpFloat u;
|
76
|
-
|
89
|
+
/// Surface velocity used when solving for friction.
|
77
90
|
cpVect surface_v;
|
78
91
|
|
79
|
-
|
80
|
-
|
81
|
-
|
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
|
-
|
97
|
+
/// Collision type of this shape used when picking collision handlers.
|
85
98
|
cpCollisionType collision_type;
|
86
|
-
|
99
|
+
/// Group of this shape. Shapes in the same group don't collide.
|
87
100
|
cpGroup group;
|
88
|
-
//
|
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
|
-
|
104
|
+
CP_PRIVATE(cpSpace *space);
|
92
105
|
|
93
|
-
|
94
|
-
CP_PRIVATE(
|
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
|
-
}
|
99
|
-
|
100
|
-
// Low level shape initialization func.
|
101
|
-
cpShape* cpShapeInit(cpShape *shape, const struct cpShapeClass *klass, cpBody *body);
|
110
|
+
};
|
102
111
|
|
103
|
-
|
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
|
-
|
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
|
-
|
122
|
+
/// Test if a point lies within a shape.
|
111
123
|
cpBool cpShapePointQuery(cpShape *shape, cpVect p);
|
112
124
|
|
113
|
-
|
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
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
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
|
-
|
125
|
-
|
186
|
+
cpVect c, tc;
|
187
|
+
cpFloat r;
|
126
188
|
} cpCircleShape;
|
127
189
|
|
128
|
-
|
129
|
-
cpCircleShape
|
130
|
-
|
131
|
-
|
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
|
-
|
137
|
-
|
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
|
-
|
146
|
-
|
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
|
-
|
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
|
-
|
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
|
26
|
+
preStep(cpSimpleMotor *joint, cpFloat dt)
|
29
27
|
{
|
30
|
-
|
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
|
-
|
39
|
-
|
40
|
-
|
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
|
-
|
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, -
|
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
|
-
(
|
70
|
-
(
|
71
|
-
(
|
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 *)
|
85
|
+
return (cpSimpleMotor *)cpcalloc(1, sizeof(cpSimpleMotor));
|
79
86
|
}
|
80
87
|
|
81
88
|
cpSimpleMotor *
|
data/ext/chipmunk/cpSlideJoint.c
CHANGED
@@ -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
|
26
|
+
preStep(cpSlideJoint *joint, cpFloat dt)
|
29
27
|
{
|
30
|
-
|
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
|
-
|
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.
|
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
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
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(
|
69
|
+
if(cpveql(joint->n, cpvzero)) return; // early exit
|
70
70
|
|
71
|
-
|
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->
|
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
|
-
(
|
99
|
-
(
|
100
|
-
(
|
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 *)
|
109
|
+
return (cpSlideJoint *)cpcalloc(1, sizeof(cpSlideJoint));
|
108
110
|
}
|
109
111
|
|
110
112
|
cpSlideJoint *
|