chipmunk 4.1.0-x86-mswin32 → 5.3.4.0-x86-mswin32

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. data/{ext/chipmunk/cpCollision.h → LICENSE} +4 -5
  2. data/README +67 -0
  3. data/Rakefile +76 -29
  4. data/ext/chipmunk/extconf.rb +38 -0
  5. data/ext/chipmunk/rb_chipmunk.c +162 -21
  6. data/ext/chipmunk/rb_chipmunk.h +39 -11
  7. data/ext/chipmunk/rb_cpArbiter.c +253 -0
  8. data/ext/chipmunk/rb_cpBB.c +60 -4
  9. data/ext/chipmunk/rb_cpBody.c +282 -17
  10. data/ext/chipmunk/rb_cpConstraint.c +336 -0
  11. data/ext/chipmunk/rb_cpShape.c +145 -4
  12. data/ext/chipmunk/rb_cpSpace.c +438 -57
  13. data/ext/chipmunk/rb_cpVect.c +98 -2
  14. data/lib/1.8/chipmunk.so +0 -0
  15. data/lib/1.9/chipmunk.so +0 -0
  16. data/lib/chipmunk.rb +168 -0
  17. metadata +29 -41
  18. data/ext/chipmunk/chipmunk.c +0 -69
  19. data/ext/chipmunk/chipmunk.h +0 -91
  20. data/ext/chipmunk/cpArbiter.c +0 -263
  21. data/ext/chipmunk/cpArbiter.h +0 -85
  22. data/ext/chipmunk/cpArray.c +0 -114
  23. data/ext/chipmunk/cpArray.h +0 -45
  24. data/ext/chipmunk/cpBB.c +0 -46
  25. data/ext/chipmunk/cpBB.h +0 -53
  26. data/ext/chipmunk/cpBody.c +0 -180
  27. data/ext/chipmunk/cpBody.h +0 -132
  28. data/ext/chipmunk/cpCollision.c +0 -390
  29. data/ext/chipmunk/cpHashSet.c +0 -219
  30. data/ext/chipmunk/cpHashSet.h +0 -79
  31. data/ext/chipmunk/cpJoint.c +0 -553
  32. data/ext/chipmunk/cpJoint.h +0 -122
  33. data/ext/chipmunk/cpPolyShape.c +0 -139
  34. data/ext/chipmunk/cpPolyShape.h +0 -92
  35. data/ext/chipmunk/cpShape.c +0 -244
  36. data/ext/chipmunk/cpShape.h +0 -141
  37. data/ext/chipmunk/cpSpace.c +0 -530
  38. data/ext/chipmunk/cpSpace.h +0 -120
  39. data/ext/chipmunk/cpSpaceHash.c +0 -455
  40. data/ext/chipmunk/cpSpaceHash.h +0 -100
  41. data/ext/chipmunk/cpVect.c +0 -63
  42. data/ext/chipmunk/cpVect.h +0 -106
  43. data/ext/chipmunk/prime.h +0 -68
  44. data/ext/chipmunk/rb_cpJoint.c +0 -136
@@ -1,79 +0,0 @@
1
- /* Copyright (c) 2007 Scott Lembcke
2
- *
3
- * Permission is hereby granted, free of charge, to any person obtaining a copy
4
- * of this software and associated documentation files (the "Software"), to deal
5
- * in the Software without restriction, including without limitation the rights
6
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- * copies of the Software, and to permit persons to whom the Software is
8
- * furnished to do so, subject to the following conditions:
9
- *
10
- * The above copyright notice and this permission notice shall be included in
11
- * all copies or substantial portions of the Software.
12
- *
13
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
- * SOFTWARE.
20
- */
21
-
22
- // cpHashSet uses a chained hashtable implementation.
23
- // Other than the transformation functions, there is nothing fancy going on.
24
-
25
- // cpHashSetBin's form the linked lists in the chained hash table.
26
- typedef struct cpHashSetBin {
27
- // Pointer to the element.
28
- void *elt;
29
- // Hash value of the element.
30
- unsigned int hash;
31
- // Next element in the chain.
32
- struct cpHashSetBin *next;
33
- } cpHashSetBin;
34
-
35
- // Equality function. Returns true if ptr is equal to elt.
36
- typedef int (*cpHashSetEqlFunc)(void *ptr, void *elt);
37
- // Used by cpHashSetInsert(). Called to transform the ptr into an element.
38
- typedef void *(*cpHashSetTransFunc)(void *ptr, void *data);
39
- // Iterator function for a hashset.
40
- typedef void (*cpHashSetIterFunc)(void *elt, void *data);
41
- // Reject function. Returns true if elt should be dropped.
42
- typedef int (*cpHashSetRejectFunc)(void *elt, void *data);
43
-
44
- typedef struct cpHashSet {
45
- // Number of elements stored in the table.
46
- int entries;
47
- // Number of cells in the table.
48
- int size;
49
-
50
- cpHashSetEqlFunc eql;
51
- cpHashSetTransFunc trans;
52
-
53
- // Default value returned by cpHashSetFind() when no element is found.
54
- // Defaults to NULL.
55
- void *default_value;
56
-
57
- cpHashSetBin **table;
58
- } cpHashSet;
59
-
60
- // Basic allocation/destruction functions.
61
- void cpHashSetDestroy(cpHashSet *set);
62
- void cpHashSetFree(cpHashSet *set);
63
-
64
- cpHashSet *cpHashSetAlloc(void);
65
- cpHashSet *cpHashSetInit(cpHashSet *set, int size, cpHashSetEqlFunc eqlFunc, cpHashSetTransFunc trans);
66
- cpHashSet *cpHashSetNew(int size, cpHashSetEqlFunc eqlFunc, cpHashSetTransFunc trans);
67
-
68
- // Insert an element into the set, returns the element.
69
- // If it doesn't already exist, the transformation function is applied.
70
- void *cpHashSetInsert(cpHashSet *set, unsigned int hash, void *ptr, void *data);
71
- // Remove and return an element from the set.
72
- void *cpHashSetRemove(cpHashSet *set, unsigned int hash, void *ptr);
73
- // Find an element in the set. Returns the default value if the element isn't found.
74
- void *cpHashSetFind(cpHashSet *set, unsigned int hash, void *ptr);
75
-
76
- // Iterate over a hashset.
77
- void cpHashSetEach(cpHashSet *set, cpHashSetIterFunc func, void *data);
78
- // Iterate over a hashset while rejecting certain elements.
79
- void cpHashSetReject(cpHashSet *set, cpHashSetRejectFunc func, void *data);
@@ -1,553 +0,0 @@
1
- /* Copyright (c) 2007 Scott Lembcke
2
- *
3
- * Permission is hereby granted, free of charge, to any person obtaining a copy
4
- * of this software and associated documentation files (the "Software"), to deal
5
- * in the Software without restriction, including without limitation the rights
6
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
- * copies of the Software, and to permit persons to whom the Software is
8
- * furnished to do so, subject to the following conditions:
9
- *
10
- * The above copyright notice and this permission notice shall be included in
11
- * all copies or substantial portions of the Software.
12
- *
13
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
- * SOFTWARE.
20
- */
21
-
22
- #include <stdlib.h>
23
- #include <math.h>
24
-
25
- #include "chipmunk.h"
26
-
27
- // TODO: Comment me!
28
-
29
- cpFloat cp_joint_bias_coef = 0.1f;
30
-
31
- void cpJointDestroy(cpJoint *joint){}
32
-
33
- void
34
- cpJointFree(cpJoint *joint)
35
- {
36
- if(joint) cpJointDestroy(joint);
37
- free(joint);
38
- }
39
-
40
- static void
41
- cpJointInit(cpJoint *joint, const cpJointClass *klass, cpBody *a, cpBody *b)
42
- {
43
- joint->klass = klass;
44
- joint->a = a;
45
- joint->b = b;
46
- }
47
-
48
-
49
- static inline cpVect
50
- relative_velocity(cpVect r1, cpVect v1, cpFloat w1, cpVect r2, cpVect v2, cpFloat w2){
51
- cpVect v1_sum = cpvadd(v1, cpvmult(cpvperp(r1), w1));
52
- cpVect v2_sum = cpvadd(v2, cpvmult(cpvperp(r2), w2));
53
-
54
- return cpvsub(v2_sum, v1_sum);
55
- }
56
-
57
- static inline cpFloat
58
- scalar_k(cpBody *a, cpBody *b, cpVect r1, cpVect r2, cpVect n)
59
- {
60
- cpFloat mass_sum = a->m_inv + b->m_inv;
61
- cpFloat r1cn = cpvcross(r1, n);
62
- cpFloat r2cn = cpvcross(r2, n);
63
-
64
- return mass_sum + a->i_inv*r1cn*r1cn + b->i_inv*r2cn*r2cn;
65
- }
66
-
67
- static inline void
68
- apply_impulses(cpBody *a , cpBody *b, cpVect r1, cpVect r2, cpVect j)
69
- {
70
- cpBodyApplyImpulse(a, cpvneg(j), r1);
71
- cpBodyApplyImpulse(b, j, r2);
72
- }
73
-
74
- static inline void
75
- apply_bias_impulses(cpBody *a , cpBody *b, cpVect r1, cpVect r2, cpVect j)
76
- {
77
- cpBodyApplyBiasImpulse(a, cpvneg(j), r1);
78
- cpBodyApplyBiasImpulse(b, j, r2);
79
- }
80
-
81
-
82
- static void
83
- pinJointPreStep(cpJoint *joint, cpFloat dt_inv)
84
- {
85
- cpBody *a = joint->a;
86
- cpBody *b = joint->b;
87
- cpPinJoint *jnt = (cpPinJoint *)joint;
88
-
89
- jnt->r1 = cpvrotate(jnt->anchr1, a->rot);
90
- jnt->r2 = cpvrotate(jnt->anchr2, b->rot);
91
-
92
- cpVect delta = cpvsub(cpvadd(b->p, jnt->r2), cpvadd(a->p, jnt->r1));
93
- cpFloat dist = cpvlength(delta);
94
- jnt->n = cpvmult(delta, 1.0f/(dist ? dist : INFINITY));
95
-
96
- // calculate mass normal
97
- jnt->nMass = 1.0f/scalar_k(a, b, jnt->r1, jnt->r2, jnt->n);
98
-
99
- // calculate bias velocity
100
- jnt->bias = -cp_joint_bias_coef*dt_inv*(dist - jnt->dist);
101
- jnt->jBias = 0.0f;
102
-
103
- // apply accumulated impulse
104
- cpVect j = cpvmult(jnt->n, jnt->jnAcc);
105
- apply_impulses(a, b, jnt->r1, jnt->r2, j);
106
- }
107
-
108
- static void
109
- pinJointApplyImpulse(cpJoint *joint)
110
- {
111
- cpBody *a = joint->a;
112
- cpBody *b = joint->b;
113
-
114
- cpPinJoint *jnt = (cpPinJoint *)joint;
115
- cpVect n = jnt->n;
116
- cpVect r1 = jnt->r1;
117
- cpVect r2 = jnt->r2;
118
-
119
- //calculate bias impulse
120
- cpVect vbr = relative_velocity(r1, a->v_bias, a->w_bias, r2, b->v_bias, b->w_bias);
121
- cpFloat vbn = cpvdot(vbr, n);
122
-
123
- cpFloat jbn = (jnt->bias - vbn)*jnt->nMass;
124
- jnt->jBias += jbn;
125
-
126
- cpVect jb = cpvmult(n, jbn);
127
- apply_bias_impulses(a, b, jnt->r1, jnt->r2, jb);
128
-
129
- // compute relative velocity
130
- cpVect vr = relative_velocity(r1, a->v, a->w, r2, b->v, b->w);
131
- cpFloat vrn = cpvdot(vr, n);
132
-
133
- // compute normal impulse
134
- cpFloat jn = -vrn*jnt->nMass;
135
- jnt->jnAcc =+ jn;
136
-
137
- // apply impulse
138
- cpVect j = cpvmult(n, jn);
139
- apply_impulses(a, b, jnt->r1, jnt->r2, j);
140
- }
141
-
142
- static const cpJointClass pinJointClass = {
143
- CP_PIN_JOINT,
144
- pinJointPreStep,
145
- pinJointApplyImpulse,
146
- };
147
-
148
- cpPinJoint *
149
- cpPinJointAlloc(void)
150
- {
151
- return (cpPinJoint *)malloc(sizeof(cpPinJoint));
152
- }
153
-
154
- cpPinJoint *
155
- cpPinJointInit(cpPinJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2)
156
- {
157
- cpJointInit((cpJoint *)joint, &pinJointClass, a, b);
158
-
159
- joint->anchr1 = anchr1;
160
- joint->anchr2 = anchr2;
161
-
162
- cpVect p1 = cpvadd(a->p, cpvrotate(anchr1, a->rot));
163
- cpVect p2 = cpvadd(b->p, cpvrotate(anchr2, b->rot));
164
- joint->dist = cpvlength(cpvsub(p2, p1));
165
-
166
- joint->jnAcc = 0.0;
167
-
168
- return joint;
169
- }
170
-
171
- cpJoint *
172
- cpPinJointNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2)
173
- {
174
- return (cpJoint *)cpPinJointInit(cpPinJointAlloc(), a, b, anchr1, anchr2);
175
- }
176
-
177
-
178
-
179
-
180
- static void
181
- slideJointPreStep(cpJoint *joint, cpFloat dt_inv)
182
- {
183
- cpBody *a = joint->a;
184
- cpBody *b = joint->b;
185
- cpSlideJoint *jnt = (cpSlideJoint *)joint;
186
-
187
- jnt->r1 = cpvrotate(jnt->anchr1, a->rot);
188
- jnt->r2 = cpvrotate(jnt->anchr2, b->rot);
189
-
190
- cpVect delta = cpvsub(cpvadd(b->p, jnt->r2), cpvadd(a->p, jnt->r1));
191
- cpFloat dist = cpvlength(delta);
192
- cpFloat pdist = 0.0;
193
- if(dist > jnt->max) {
194
- pdist = dist - jnt->max;
195
- } else if(dist < jnt->min) {
196
- pdist = jnt->min - dist;
197
- dist = -dist;
198
- }
199
- jnt->n = cpvmult(delta, 1.0f/(dist ? dist : INFINITY));
200
-
201
- // calculate mass normal
202
- jnt->nMass = 1.0f/scalar_k(a, b, jnt->r1, jnt->r2, jnt->n);
203
-
204
- // calculate bias velocity
205
- jnt->bias = -cp_joint_bias_coef*dt_inv*(pdist);
206
- jnt->jBias = 0.0f;
207
-
208
- // apply accumulated impulse
209
- if(!jnt->bias) //{
210
- // if bias is 0, then the joint is not at a limit.
211
- jnt->jnAcc = 0.0f;
212
- // } else {
213
- cpVect j = cpvmult(jnt->n, jnt->jnAcc);
214
- apply_impulses(a, b, jnt->r1, jnt->r2, j);
215
- // }
216
- }
217
-
218
- static void
219
- slideJointApplyImpulse(cpJoint *joint)
220
- {
221
- cpSlideJoint *jnt = (cpSlideJoint *)joint;
222
- if(!jnt->bias) return; // early exit
223
-
224
- cpBody *a = joint->a;
225
- cpBody *b = joint->b;
226
-
227
- cpVect n = jnt->n;
228
- cpVect r1 = jnt->r1;
229
- cpVect r2 = jnt->r2;
230
-
231
- //calculate bias impulse
232
- cpVect vbr = relative_velocity(r1, a->v_bias, a->w_bias, r2, b->v_bias, b->w_bias);
233
- cpFloat vbn = cpvdot(vbr, n);
234
-
235
- cpFloat jbn = (jnt->bias - vbn)*jnt->nMass;
236
- cpFloat jbnOld = jnt->jBias;
237
- jnt->jBias = cpfmin(jbnOld + jbn, 0.0f);
238
- jbn = jnt->jBias - jbnOld;
239
-
240
- cpVect jb = cpvmult(n, jbn);
241
- apply_bias_impulses(a, b, jnt->r1, jnt->r2, jb);
242
-
243
- // compute relative velocity
244
- cpVect vr = relative_velocity(r1, a->v, a->w, r2, b->v, b->w);
245
- cpFloat vrn = cpvdot(vr, n);
246
-
247
- // compute normal impulse
248
- cpFloat jn = -vrn*jnt->nMass;
249
- cpFloat jnOld = jnt->jnAcc;
250
- jnt->jnAcc = cpfmin(jnOld + jn, 0.0f);
251
- jn = jnt->jnAcc - jnOld;
252
-
253
- // apply impulse
254
- cpVect j = cpvmult(n, jn);
255
- apply_impulses(a, b, jnt->r1, jnt->r2, j);
256
- }
257
-
258
- static const cpJointClass slideJointClass = {
259
- CP_SLIDE_JOINT,
260
- slideJointPreStep,
261
- slideJointApplyImpulse,
262
- };
263
-
264
- cpSlideJoint *
265
- cpSlideJointAlloc(void)
266
- {
267
- return (cpSlideJoint *)malloc(sizeof(cpSlideJoint));
268
- }
269
-
270
- cpSlideJoint *
271
- cpSlideJointInit(cpSlideJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max)
272
- {
273
- cpJointInit((cpJoint *)joint, &slideJointClass, a, b);
274
-
275
- joint->anchr1 = anchr1;
276
- joint->anchr2 = anchr2;
277
- joint->min = min;
278
- joint->max = max;
279
-
280
- joint->jnAcc = 0.0;
281
-
282
- return joint;
283
- }
284
-
285
- cpJoint *
286
- cpSlideJointNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat min, cpFloat max)
287
- {
288
- return (cpJoint *)cpSlideJointInit(cpSlideJointAlloc(), a, b, anchr1, anchr2, min, max);
289
- }
290
-
291
-
292
-
293
-
294
- static void
295
- pivotJointPreStep(cpJoint *joint, cpFloat dt_inv)
296
- {
297
- cpBody *a = joint->a;
298
- cpBody *b = joint->b;
299
- cpPivotJoint *jnt = (cpPivotJoint *)joint;
300
-
301
- jnt->r1 = cpvrotate(jnt->anchr1, a->rot);
302
- jnt->r2 = cpvrotate(jnt->anchr2, b->rot);
303
-
304
- // calculate mass matrix
305
- // If I wasn't lazy, this wouldn't be so gross...
306
- cpFloat k11, k12, k21, k22;
307
-
308
- cpFloat m_sum = a->m_inv + b->m_inv;
309
- k11 = m_sum; k12 = 0.0f;
310
- k21 = 0.0f; k22 = m_sum;
311
-
312
- cpFloat r1xsq = jnt->r1.x * jnt->r1.x * a->i_inv;
313
- cpFloat r1ysq = jnt->r1.y * jnt->r1.y * a->i_inv;
314
- cpFloat r1nxy = -jnt->r1.x * jnt->r1.y * a->i_inv;
315
- k11 += r1ysq; k12 += r1nxy;
316
- k21 += r1nxy; k22 += r1xsq;
317
-
318
- cpFloat r2xsq = jnt->r2.x * jnt->r2.x * b->i_inv;
319
- cpFloat r2ysq = jnt->r2.y * jnt->r2.y * b->i_inv;
320
- cpFloat r2nxy = -jnt->r2.x * jnt->r2.y * b->i_inv;
321
- k11 += r2ysq; k12 += r2nxy;
322
- k21 += r2nxy; k22 += r2xsq;
323
-
324
- cpFloat det_inv = 1.0f/(k11*k22 - k12*k21);
325
- jnt->k1 = cpv( k22*det_inv, -k12*det_inv);
326
- jnt->k2 = cpv(-k21*det_inv, k11*det_inv);
327
-
328
-
329
- // calculate bias velocity
330
- cpVect delta = cpvsub(cpvadd(b->p, jnt->r2), cpvadd(a->p, jnt->r1));
331
- jnt->bias = cpvmult(delta, -cp_joint_bias_coef*dt_inv);
332
- jnt->jBias = cpvzero;
333
-
334
- // apply accumulated impulse
335
- apply_impulses(a, b, jnt->r1, jnt->r2, jnt->jAcc);
336
- }
337
-
338
- static void
339
- pivotJointApplyImpulse(cpJoint *joint)
340
- {
341
- cpBody *a = joint->a;
342
- cpBody *b = joint->b;
343
-
344
- cpPivotJoint *jnt = (cpPivotJoint *)joint;
345
- cpVect r1 = jnt->r1;
346
- cpVect r2 = jnt->r2;
347
- cpVect k1 = jnt->k1;
348
- cpVect k2 = jnt->k2;
349
-
350
- //calculate bias impulse
351
- cpVect vbr = relative_velocity(r1, a->v_bias, a->w_bias, r2, b->v_bias, b->w_bias);
352
- vbr = cpvsub(jnt->bias, vbr);
353
-
354
- cpVect jb = cpv(cpvdot(vbr, k1), cpvdot(vbr, k2));
355
- jnt->jBias = cpvadd(jnt->jBias, jb);
356
-
357
- apply_bias_impulses(a, b, jnt->r1, jnt->r2, jb);
358
-
359
- // compute relative velocity
360
- cpVect vr = relative_velocity(r1, a->v, a->w, r2, b->v, b->w);
361
-
362
- // compute normal impulse
363
- cpVect j = cpv(-cpvdot(vr, k1), -cpvdot(vr, k2));
364
- jnt->jAcc = cpvadd(jnt->jAcc, j);
365
-
366
- // apply impulse
367
- apply_impulses(a, b, jnt->r1, jnt->r2, j);
368
- }
369
-
370
- static const cpJointClass pivotJointClass = {
371
- CP_PIVOT_JOINT,
372
- pivotJointPreStep,
373
- pivotJointApplyImpulse,
374
- };
375
-
376
- cpPivotJoint *
377
- cpPivotJointAlloc(void)
378
- {
379
- return (cpPivotJoint *)malloc(sizeof(cpPivotJoint));
380
- }
381
-
382
- cpPivotJoint *
383
- cpPivotJointInit(cpPivotJoint *joint, cpBody *a, cpBody *b, cpVect pivot)
384
- {
385
- cpJointInit((cpJoint *)joint, &pivotJointClass, a, b);
386
-
387
- joint->anchr1 = cpvunrotate(cpvsub(pivot, a->p), a->rot);
388
- joint->anchr2 = cpvunrotate(cpvsub(pivot, b->p), b->rot);
389
-
390
- joint->jAcc = cpvzero;
391
-
392
- return joint;
393
- }
394
-
395
- cpJoint *
396
- cpPivotJointNew(cpBody *a, cpBody *b, cpVect pivot)
397
- {
398
- return (cpJoint *)cpPivotJointInit(cpPivotJointAlloc(), a, b, pivot);
399
- }
400
-
401
-
402
-
403
-
404
- static void
405
- grooveJointPreStep(cpJoint *joint, cpFloat dt_inv)
406
- {
407
- cpBody *a = joint->a;
408
- cpBody *b = joint->b;
409
- cpGrooveJoint *jnt = (cpGrooveJoint *)joint;
410
-
411
- // calculate endpoints in worldspace
412
- cpVect ta = cpBodyLocal2World(a, jnt->grv_a);
413
- cpVect tb = cpBodyLocal2World(a, jnt->grv_b);
414
-
415
- // calculate axis
416
- cpVect n = cpvrotate(jnt->grv_n, a->rot);
417
- cpFloat d = cpvdot(ta, n);
418
-
419
- jnt->grv_tn = n;
420
- jnt->r2 = cpvrotate(jnt->anchr2, b->rot);
421
-
422
- // calculate tangential distance along the axis of r2
423
- cpFloat td = cpvcross(cpvadd(b->p, jnt->r2), n);
424
- // calculate clamping factor and r2
425
- if(td <= cpvcross(ta, n)){
426
- jnt->clamp = 1.0f;
427
- jnt->r1 = cpvsub(ta, a->p);
428
- } else if(td >= cpvcross(tb, n)){
429
- jnt->clamp = -1.0f;
430
- jnt->r1 = cpvsub(tb, a->p);
431
- } else {
432
- jnt->clamp = 0.0f;
433
- jnt->r1 = cpvsub(cpvadd(cpvmult(cpvperp(n), -td), cpvmult(n, d)), a->p);
434
- }
435
-
436
- // calculate mass matrix
437
- // If I wasn't lazy and wrote a proper matrix class, this wouldn't be so gross...
438
- cpFloat k11, k12, k21, k22;
439
- cpFloat m_sum = a->m_inv + b->m_inv;
440
-
441
- // start with I*m_sum
442
- k11 = m_sum; k12 = 0.0f;
443
- k21 = 0.0f; k22 = m_sum;
444
-
445
- // add the influence from r1
446
- cpFloat r1xsq = jnt->r1.x * jnt->r1.x * a->i_inv;
447
- cpFloat r1ysq = jnt->r1.y * jnt->r1.y * a->i_inv;
448
- cpFloat r1nxy = -jnt->r1.x * jnt->r1.y * a->i_inv;
449
- k11 += r1ysq; k12 += r1nxy;
450
- k21 += r1nxy; k22 += r1xsq;
451
-
452
- // add the influnce from r2
453
- cpFloat r2xsq = jnt->r2.x * jnt->r2.x * b->i_inv;
454
- cpFloat r2ysq = jnt->r2.y * jnt->r2.y * b->i_inv;
455
- cpFloat r2nxy = -jnt->r2.x * jnt->r2.y * b->i_inv;
456
- k11 += r2ysq; k12 += r2nxy;
457
- k21 += r2nxy; k22 += r2xsq;
458
-
459
- // invert
460
- cpFloat det_inv = 1.0f/(k11*k22 - k12*k21);
461
- jnt->k1 = cpv( k22*det_inv, -k12*det_inv);
462
- jnt->k2 = cpv(-k21*det_inv, k11*det_inv);
463
-
464
-
465
- // calculate bias velocity
466
- cpVect delta = cpvsub(cpvadd(b->p, jnt->r2), cpvadd(a->p, jnt->r1));
467
- jnt->bias = cpvmult(delta, -cp_joint_bias_coef*dt_inv);
468
- jnt->jBias = cpvzero;
469
-
470
- // apply accumulated impulse
471
- apply_impulses(a, b, jnt->r1, jnt->r2, jnt->jAcc);
472
- }
473
-
474
- static inline cpVect
475
- grooveConstrain(cpGrooveJoint *jnt, cpVect j){
476
- cpVect n = jnt->grv_tn;
477
- cpVect jn = cpvmult(n, cpvdot(j, n));
478
-
479
- cpVect t = cpvperp(n);
480
- cpFloat coef = (jnt->clamp*cpvcross(j, n) > 0.0f) ? 1.0f : 0.0f;
481
- cpVect jt = cpvmult(t, cpvdot(j, t)*coef);
482
-
483
- return cpvadd(jn, jt);
484
- }
485
-
486
- static void
487
- grooveJointApplyImpulse(cpJoint *joint)
488
- {
489
- cpBody *a = joint->a;
490
- cpBody *b = joint->b;
491
-
492
- cpGrooveJoint *jnt = (cpGrooveJoint *)joint;
493
- cpVect r1 = jnt->r1;
494
- cpVect r2 = jnt->r2;
495
- cpVect k1 = jnt->k1;
496
- cpVect k2 = jnt->k2;
497
-
498
- //calculate bias impulse
499
- cpVect vbr = relative_velocity(r1, a->v_bias, a->w_bias, r2, b->v_bias, b->w_bias);
500
- vbr = cpvsub(jnt->bias, vbr);
501
-
502
- cpVect jb = cpv(cpvdot(vbr, k1), cpvdot(vbr, k2));
503
- cpVect jbOld = jnt->jBias;
504
- jnt->jBias = grooveConstrain(jnt, cpvadd(jbOld, jb));
505
- jb = cpvsub(jnt->jBias, jbOld);
506
-
507
- apply_bias_impulses(a, b, jnt->r1, jnt->r2, jb);
508
-
509
- // compute impulse
510
- cpVect vr = relative_velocity(r1, a->v, a->w, r2, b->v, b->w);
511
-
512
- cpVect j = cpv(-cpvdot(vr, k1), -cpvdot(vr, k2));
513
- cpVect jOld = jnt->jAcc;
514
- jnt->jAcc = grooveConstrain(jnt, cpvadd(jOld, j));
515
- j = cpvsub(jnt->jAcc, jOld);
516
-
517
- // apply impulse
518
- apply_impulses(a, b, jnt->r1, jnt->r2, j);
519
- }
520
-
521
- static const cpJointClass grooveJointClass = {
522
- CP_GROOVE_JOINT,
523
- grooveJointPreStep,
524
- grooveJointApplyImpulse,
525
- };
526
-
527
- cpGrooveJoint *
528
- cpGrooveJointAlloc(void)
529
- {
530
- return (cpGrooveJoint *)malloc(sizeof(cpGrooveJoint));
531
- }
532
-
533
- cpGrooveJoint *
534
- cpGrooveJointInit(cpGrooveJoint *joint, cpBody *a, cpBody *b, cpVect groove_a, cpVect groove_b, cpVect anchr2)
535
- {
536
- cpJointInit((cpJoint *)joint, &grooveJointClass, a, b);
537
-
538
- joint->grv_a = groove_a;
539
- joint->grv_b = groove_b;
540
- joint->grv_n = cpvperp(cpvnormalize(cpvsub(groove_b, groove_a)));
541
- joint->anchr2 = anchr2;
542
-
543
- joint->jAcc = cpvzero;
544
-
545
- return joint;
546
- }
547
-
548
- cpJoint *
549
- cpGrooveJointNew(cpBody *a, cpBody *b, cpVect groove_a, cpVect groove_b, cpVect anchr2)
550
- {
551
- return (cpJoint *)cpGrooveJointInit(cpGrooveJointAlloc(), a, b, groove_a, groove_b, anchr2);
552
- }
553
-