chipmunk 5.3.4.5 → 6.1.3.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- 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 *
|