chipmunk 4.1.0 → 5.2.0

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 (71) hide show
  1. data/LICENSE +20 -0
  2. data/README +60 -0
  3. data/Rakefile +47 -40
  4. data/ext/chipmunk/chipmunk.c +39 -3
  5. data/ext/chipmunk/cpArbiter.c +91 -80
  6. data/ext/chipmunk/cpArray.c +24 -10
  7. data/ext/chipmunk/cpBB.c +5 -4
  8. data/ext/chipmunk/cpBody.c +30 -22
  9. data/ext/chipmunk/cpCollision.c +54 -53
  10. data/ext/chipmunk/cpConstraint.c +54 -0
  11. data/ext/chipmunk/cpDampedRotarySpring.c +106 -0
  12. data/ext/chipmunk/cpDampedSpring.c +117 -0
  13. data/ext/chipmunk/cpGearJoint.c +114 -0
  14. data/ext/chipmunk/cpGrooveJoint.c +138 -0
  15. data/ext/chipmunk/cpHashSet.c +74 -40
  16. data/ext/chipmunk/cpPinJoint.c +117 -0
  17. data/ext/chipmunk/cpPivotJoint.c +114 -0
  18. data/ext/chipmunk/cpPolyShape.c +117 -15
  19. data/ext/chipmunk/cpRatchetJoint.c +128 -0
  20. data/ext/chipmunk/cpRotaryLimitJoint.c +122 -0
  21. data/ext/chipmunk/cpShape.c +174 -18
  22. data/ext/chipmunk/cpSimpleMotor.c +99 -0
  23. data/ext/chipmunk/cpSlideJoint.c +131 -0
  24. data/ext/chipmunk/cpSpace.c +584 -215
  25. data/ext/chipmunk/cpSpaceHash.c +191 -105
  26. data/ext/chipmunk/cpVect.c +18 -10
  27. data/ext/chipmunk/extconf.rb +34 -4
  28. data/ext/chipmunk/{chipmunk.h → include/chipmunk/chipmunk.h} +63 -6
  29. data/ext/chipmunk/include/chipmunk/chipmunk_ffi.h +42 -0
  30. data/ext/chipmunk/include/chipmunk/chipmunk_types.h +80 -0
  31. data/ext/chipmunk/include/chipmunk/chipmunk_unsafe.h +54 -0
  32. data/ext/chipmunk/include/chipmunk/constraints/cpConstraint.h +92 -0
  33. data/ext/chipmunk/include/chipmunk/constraints/cpDampedRotarySpring.h +46 -0
  34. data/ext/chipmunk/include/chipmunk/constraints/cpDampedSpring.h +53 -0
  35. data/ext/chipmunk/include/chipmunk/constraints/cpGearJoint.h +41 -0
  36. data/ext/chipmunk/include/chipmunk/constraints/cpGrooveJoint.h +44 -0
  37. data/ext/chipmunk/include/chipmunk/constraints/cpPinJoint.h +43 -0
  38. data/ext/chipmunk/include/chipmunk/constraints/cpPivotJoint.h +42 -0
  39. data/ext/chipmunk/include/chipmunk/constraints/cpRatchetJoint.h +40 -0
  40. data/ext/chipmunk/include/chipmunk/constraints/cpRotaryLimitJoint.h +39 -0
  41. data/ext/chipmunk/include/chipmunk/constraints/cpSimpleMotor.h +37 -0
  42. data/ext/chipmunk/include/chipmunk/constraints/cpSlideJoint.h +44 -0
  43. data/ext/chipmunk/include/chipmunk/constraints/util.h +116 -0
  44. data/ext/chipmunk/{cpArbiter.h → include/chipmunk/cpArbiter.h} +66 -15
  45. data/ext/chipmunk/{cpArray.h → include/chipmunk/cpArray.h} +2 -1
  46. data/ext/chipmunk/{cpBB.h → include/chipmunk/cpBB.h} +21 -0
  47. data/ext/chipmunk/{cpBody.h → include/chipmunk/cpBody.h} +37 -9
  48. data/ext/chipmunk/{cpCollision.h → include/chipmunk/cpCollision.h} +1 -1
  49. data/ext/chipmunk/{cpHashSet.h → include/chipmunk/cpHashSet.h} +12 -9
  50. data/ext/chipmunk/{cpPolyShape.h → include/chipmunk/cpPolyShape.h} +13 -2
  51. data/ext/chipmunk/{cpShape.h → include/chipmunk/cpShape.h} +51 -18
  52. data/ext/chipmunk/include/chipmunk/cpSpace.h +180 -0
  53. data/ext/chipmunk/{cpSpaceHash.h → include/chipmunk/cpSpaceHash.h} +18 -9
  54. data/ext/chipmunk/{cpVect.h → include/chipmunk/cpVect.h} +61 -10
  55. data/ext/chipmunk/prime.h +32 -32
  56. data/ext/chipmunk/rb_chipmunk.c +125 -109
  57. data/ext/chipmunk/rb_chipmunk.h +96 -77
  58. data/ext/chipmunk/rb_cpArbiter.c +225 -0
  59. data/ext/chipmunk/rb_cpBB.c +174 -154
  60. data/ext/chipmunk/rb_cpBody.c +347 -239
  61. data/ext/chipmunk/rb_cpConstraint.c +346 -0
  62. data/ext/chipmunk/rb_cpShape.c +455 -292
  63. data/ext/chipmunk/rb_cpSpace.c +544 -330
  64. data/ext/chipmunk/rb_cpVect.c +321 -250
  65. data/lib/chipmunk.rb +28 -15
  66. data/lib/chipmunk/version.rb +3 -0
  67. metadata +74 -34
  68. data/ext/chipmunk/cpJoint.c +0 -553
  69. data/ext/chipmunk/cpJoint.h +0 -122
  70. data/ext/chipmunk/cpSpace.h +0 -120
  71. data/ext/chipmunk/rb_cpJoint.c +0 -136
@@ -25,35 +25,31 @@
25
25
  #include "chipmunk.h"
26
26
  #include "prime.h"
27
27
 
28
+ static void freeWrap(void *ptr, void *unused){cpfree(ptr);}
29
+
28
30
  void
29
31
  cpHashSetDestroy(cpHashSet *set)
30
32
  {
31
- // Free the chains.
32
- for(int i=0; i<set->size; i++){
33
- // Free the bins in the chain.
34
- cpHashSetBin *bin = set->table[i];
35
- while(bin){
36
- cpHashSetBin *next = bin->next;
37
- free(bin);
38
- bin = next;
39
- }
40
- }
41
-
42
33
  // Free the table.
43
- free(set->table);
34
+ cpfree(set->table);
35
+
36
+ cpArrayEach(set->allocatedBuffers, freeWrap, NULL);
37
+ cpArrayFree(set->allocatedBuffers);
44
38
  }
45
39
 
46
40
  void
47
41
  cpHashSetFree(cpHashSet *set)
48
42
  {
49
- if(set) cpHashSetDestroy(set);
50
- free(set);
43
+ if(set){
44
+ cpHashSetDestroy(set);
45
+ cpfree(set);
46
+ }
51
47
  }
52
48
 
53
49
  cpHashSet *
54
50
  cpHashSetAlloc(void)
55
51
  {
56
- return (cpHashSet *)calloc(1, sizeof(cpHashSet));
52
+ return (cpHashSet *)cpcalloc(1, sizeof(cpHashSet));
57
53
  }
58
54
 
59
55
  cpHashSet *
@@ -67,7 +63,10 @@ cpHashSetInit(cpHashSet *set, int size, cpHashSetEqlFunc eqlFunc, cpHashSetTrans
67
63
 
68
64
  set->default_value = NULL;
69
65
 
70
- set->table = (cpHashSetBin **)calloc(set->size, sizeof(cpHashSetBin *));
66
+ set->table = (cpHashSetBin **)cpcalloc(set->size, sizeof(cpHashSetBin *));
67
+ set->pooledBins = NULL;
68
+
69
+ set->allocatedBuffers = cpArrayNew(0);
71
70
 
72
71
  return set;
73
72
  }
@@ -90,7 +89,7 @@ cpHashSetResize(cpHashSet *set)
90
89
  // Get the next approximate doubled prime.
91
90
  int newSize = next_prime(set->size + 1);
92
91
  // Allocate a new table.
93
- cpHashSetBin **newTable = (cpHashSetBin **)calloc(newSize, sizeof(cpHashSetBin *));
92
+ cpHashSetBin **newTable = (cpHashSetBin **)cpcalloc(newSize, sizeof(cpHashSetBin *));
94
93
 
95
94
  // Iterate over the chains.
96
95
  for(int i=0; i<set->size; i++){
@@ -99,38 +98,68 @@ cpHashSetResize(cpHashSet *set)
99
98
  while(bin){
100
99
  cpHashSetBin *next = bin->next;
101
100
 
102
- int index = bin->hash%newSize;
103
- bin->next = newTable[index];
104
- newTable[index] = bin;
101
+ int idx = bin->hash%newSize;
102
+ bin->next = newTable[idx];
103
+ newTable[idx] = bin;
105
104
 
106
105
  bin = next;
107
106
  }
108
107
  }
109
108
 
110
- free(set->table);
109
+ cpfree(set->table);
111
110
 
112
111
  set->table = newTable;
113
112
  set->size = newSize;
114
113
  }
115
114
 
115
+ static inline void
116
+ recycleBin(cpHashSet *set, cpHashSetBin *bin)
117
+ {
118
+ bin->next = set->pooledBins;
119
+ set->pooledBins = bin;
120
+ bin->elt = NULL;
121
+ }
122
+
123
+ static cpHashSetBin *
124
+ getUnusedBin(cpHashSet *set)
125
+ {
126
+ cpHashSetBin *bin = set->pooledBins;
127
+
128
+ if(bin){
129
+ set->pooledBins = bin->next;
130
+ return bin;
131
+ } else {
132
+ // Pool is exhausted, make more
133
+ int count = CP_BUFFER_BYTES/sizeof(cpHashSetBin);
134
+ cpAssert(count, "Buffer size is too small.");
135
+
136
+ cpHashSetBin *buffer = (cpHashSetBin *)cpmalloc(CP_BUFFER_BYTES);
137
+ cpArrayPush(set->allocatedBuffers, buffer);
138
+
139
+ // push all but the first one, return the first instead
140
+ for(int i=1; i<count; i++) recycleBin(set, buffer + i);
141
+ return buffer;
142
+ }
143
+ }
144
+
116
145
  void *
117
- cpHashSetInsert(cpHashSet *set, unsigned int hash, void *ptr, void *data)
146
+ cpHashSetInsert(cpHashSet *set, cpHashValue hash, void *ptr, void *data)
118
147
  {
119
- int index = hash%set->size;
148
+ int idx = hash%set->size;
120
149
 
121
150
  // Find the bin with the matching element.
122
- cpHashSetBin *bin = set->table[index];
151
+ cpHashSetBin *bin = set->table[idx];
123
152
  while(bin && !set->eql(ptr, bin->elt))
124
153
  bin = bin->next;
125
154
 
126
155
  // Create it necessary.
127
156
  if(!bin){
128
- bin = (cpHashSetBin *)malloc(sizeof(cpHashSetBin));
157
+ bin = getUnusedBin(set);
129
158
  bin->hash = hash;
130
159
  bin->elt = set->trans(ptr, data); // Transform the pointer.
131
160
 
132
- bin->next = set->table[index];
133
- set->table[index] = bin;
161
+ bin->next = set->table[idx];
162
+ set->table[idx] = bin;
134
163
 
135
164
  set->entries++;
136
165
 
@@ -143,14 +172,14 @@ cpHashSetInsert(cpHashSet *set, unsigned int hash, void *ptr, void *data)
143
172
  }
144
173
 
145
174
  void *
146
- cpHashSetRemove(cpHashSet *set, unsigned int hash, void *ptr)
175
+ cpHashSetRemove(cpHashSet *set, cpHashValue hash, void *ptr)
147
176
  {
148
- int index = hash%set->size;
177
+ int idx = hash%set->size;
149
178
 
150
179
  // Pointer to the previous bin pointer.
151
- cpHashSetBin **prev_ptr = &set->table[index];
180
+ cpHashSetBin **prev_ptr = &set->table[idx];
152
181
  // Pointer the the current bin.
153
- cpHashSetBin *bin = set->table[index];
182
+ cpHashSetBin *bin = set->table[idx];
154
183
 
155
184
  // Find the bin
156
185
  while(bin && !set->eql(ptr, bin->elt)){
@@ -160,12 +189,14 @@ cpHashSetRemove(cpHashSet *set, unsigned int hash, void *ptr)
160
189
 
161
190
  // Remove it if it exists.
162
191
  if(bin){
163
- // Update the previos bin pointer to point to the next bin.
192
+ // Update the previous bin pointer to point to the next bin.
164
193
  (*prev_ptr) = bin->next;
165
194
  set->entries--;
166
195
 
167
196
  void *return_value = bin->elt;
168
- free(bin);
197
+
198
+ recycleBin(set, bin);
199
+
169
200
  return return_value;
170
201
  }
171
202
 
@@ -173,10 +204,10 @@ cpHashSetRemove(cpHashSet *set, unsigned int hash, void *ptr)
173
204
  }
174
205
 
175
206
  void *
176
- cpHashSetFind(cpHashSet *set, unsigned int hash, void *ptr)
207
+ cpHashSetFind(cpHashSet *set, cpHashValue hash, void *ptr)
177
208
  {
178
- int index = hash%set->size;
179
- cpHashSetBin *bin = set->table[index];
209
+ int idx = hash%set->size;
210
+ cpHashSetBin *bin = set->table[idx];
180
211
  while(bin && !set->eql(ptr, bin->elt))
181
212
  bin = bin->next;
182
213
 
@@ -187,14 +218,17 @@ void
187
218
  cpHashSetEach(cpHashSet *set, cpHashSetIterFunc func, void *data)
188
219
  {
189
220
  for(int i=0; i<set->size; i++){
190
- cpHashSetBin *bin;
191
- for(bin = set->table[i]; bin; bin = bin->next)
221
+ cpHashSetBin *bin = set->table[i];
222
+ while(bin){
223
+ cpHashSetBin *next = bin->next;
192
224
  func(bin->elt, data);
225
+ bin = next;
226
+ }
193
227
  }
194
228
  }
195
229
 
196
230
  void
197
- cpHashSetReject(cpHashSet *set, cpHashSetRejectFunc func, void *data)
231
+ cpHashSetFilter(cpHashSet *set, cpHashSetFilterFunc func, void *data)
198
232
  {
199
233
  // Iterate over all the chains.
200
234
  for(int i=0; i<set->size; i++){
@@ -210,7 +244,7 @@ cpHashSetReject(cpHashSet *set, cpHashSetRejectFunc func, void *data)
210
244
  (*prev_ptr) = next;
211
245
 
212
246
  set->entries--;
213
- free(bin);
247
+ recycleBin(set, bin);
214
248
  }
215
249
 
216
250
  bin = next;
@@ -0,0 +1,117 @@
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
+ #include "constraints/util.h"
27
+
28
+ static void
29
+ preStep(cpPinJoint *joint, cpFloat dt, cpFloat dt_inv)
30
+ {
31
+ cpBody *a = joint->constraint.a;
32
+ cpBody *b = joint->constraint.b;
33
+
34
+ joint->r1 = cpvrotate(joint->anchr1, a->rot);
35
+ joint->r2 = cpvrotate(joint->anchr2, b->rot);
36
+
37
+ cpVect delta = cpvsub(cpvadd(b->p, joint->r2), cpvadd(a->p, joint->r1));
38
+ cpFloat dist = cpvlength(delta);
39
+ joint->n = cpvmult(delta, 1.0f/(dist ? dist : (cpFloat)INFINITY));
40
+
41
+ // calculate mass normal
42
+ joint->nMass = 1.0f/k_scalar(a, b, joint->r1, joint->r2, joint->n);
43
+
44
+ // calculate bias velocity
45
+ cpFloat maxBias = joint->constraint.maxBias;
46
+ joint->bias = cpfclamp(-joint->constraint.biasCoef*dt_inv*(dist - joint->dist), -maxBias, maxBias);
47
+
48
+ // compute max impulse
49
+ joint->jnMax = J_MAX(joint, dt);
50
+
51
+ // apply accumulated impulse
52
+ cpVect j = cpvmult(joint->n, joint->jnAcc);
53
+ apply_impulses(a, b, joint->r1, joint->r2, j);
54
+ }
55
+
56
+ static void
57
+ applyImpulse(cpPinJoint *joint)
58
+ {
59
+ cpBody *a = joint->constraint.a;
60
+ cpBody *b = joint->constraint.b;
61
+ cpVect n = joint->n;
62
+
63
+ // compute relative velocity
64
+ cpFloat vrn = normal_relative_velocity(a, b, joint->r1, joint->r2, n);
65
+
66
+ // compute normal impulse
67
+ cpFloat jn = (joint->bias - vrn)*joint->nMass;
68
+ cpFloat jnOld = joint->jnAcc;
69
+ joint->jnAcc = cpfclamp(jnOld + jn, -joint->jnMax, joint->jnMax);
70
+ jn = joint->jnAcc - jnOld;
71
+
72
+ // apply impulse
73
+ apply_impulses(a, b, joint->r1, joint->r2, cpvmult(n, jn));
74
+ }
75
+
76
+ static cpFloat
77
+ getImpulse(cpPinJoint *joint)
78
+ {
79
+ return cpfabs(joint->jnAcc);
80
+ }
81
+
82
+ static const cpConstraintClass klass = {
83
+ (cpConstraintPreStepFunction)preStep,
84
+ (cpConstraintApplyImpulseFunction)applyImpulse,
85
+ (cpConstraintGetImpulseFunction)getImpulse,
86
+ };
87
+ CP_DefineClassGetter(cpPinJoint);
88
+
89
+
90
+ cpPinJoint *
91
+ cpPinJointAlloc(void)
92
+ {
93
+ return (cpPinJoint *)cpmalloc(sizeof(cpPinJoint));
94
+ }
95
+
96
+ cpPinJoint *
97
+ cpPinJointInit(cpPinJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2)
98
+ {
99
+ cpConstraintInit((cpConstraint *)joint, &klass, a, b);
100
+
101
+ joint->anchr1 = anchr1;
102
+ joint->anchr2 = anchr2;
103
+
104
+ cpVect p1 = cpvadd(a->p, cpvrotate(anchr1, a->rot));
105
+ cpVect p2 = cpvadd(b->p, cpvrotate(anchr2, b->rot));
106
+ joint->dist = cpvlength(cpvsub(p2, p1));
107
+
108
+ joint->jnAcc = 0.0f;
109
+
110
+ return joint;
111
+ }
112
+
113
+ cpConstraint *
114
+ cpPinJointNew(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2)
115
+ {
116
+ return (cpConstraint *)cpPinJointInit(cpPinJointAlloc(), a, b, anchr1, anchr2);
117
+ }
@@ -0,0 +1,114 @@
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
+
24
+ #include "chipmunk.h"
25
+ #include "constraints/util.h"
26
+
27
+ static void
28
+ preStep(cpPivotJoint *joint, cpFloat dt, cpFloat dt_inv)
29
+ {
30
+ cpBody *a = joint->constraint.a;
31
+ cpBody *b = joint->constraint.b;
32
+
33
+ joint->r1 = cpvrotate(joint->anchr1, a->rot);
34
+ joint->r2 = cpvrotate(joint->anchr2, b->rot);
35
+
36
+ // Calculate mass tensor
37
+ k_tensor(a, b, joint->r1, joint->r2, &joint->k1, &joint->k2);
38
+
39
+ // compute max impulse
40
+ joint->jMaxLen = J_MAX(joint, dt);
41
+
42
+ // calculate bias velocity
43
+ cpVect delta = cpvsub(cpvadd(b->p, joint->r2), cpvadd(a->p, joint->r1));
44
+ joint->bias = cpvclamp(cpvmult(delta, -joint->constraint.biasCoef*dt_inv), joint->constraint.maxBias);
45
+
46
+ // apply accumulated impulse
47
+ apply_impulses(a, b, joint->r1, joint->r2, joint->jAcc);
48
+ }
49
+
50
+ static void
51
+ applyImpulse(cpPivotJoint *joint)
52
+ {
53
+ cpBody *a = joint->constraint.a;
54
+ cpBody *b = joint->constraint.b;
55
+
56
+ cpVect r1 = joint->r1;
57
+ cpVect r2 = joint->r2;
58
+
59
+ // compute relative velocity
60
+ cpVect vr = relative_velocity(a, b, r1, r2);
61
+
62
+ // compute normal impulse
63
+ cpVect j = mult_k(cpvsub(joint->bias, vr), joint->k1, joint->k2);
64
+ cpVect jOld = joint->jAcc;
65
+ joint->jAcc = cpvclamp(cpvadd(joint->jAcc, j), joint->jMaxLen);
66
+ j = cpvsub(joint->jAcc, jOld);
67
+
68
+ // apply impulse
69
+ apply_impulses(a, b, joint->r1, joint->r2, j);
70
+ }
71
+
72
+ static cpFloat
73
+ getImpulse(cpConstraint *joint)
74
+ {
75
+ return cpvlength(((cpPivotJoint *)joint)->jAcc);
76
+ }
77
+
78
+ static const cpConstraintClass klass = {
79
+ (cpConstraintPreStepFunction)preStep,
80
+ (cpConstraintApplyImpulseFunction)applyImpulse,
81
+ (cpConstraintGetImpulseFunction)getImpulse,
82
+ };
83
+ CP_DefineClassGetter(cpPivotJoint)
84
+
85
+ cpPivotJoint *
86
+ cpPivotJointAlloc(void)
87
+ {
88
+ return (cpPivotJoint *)cpmalloc(sizeof(cpPivotJoint));
89
+ }
90
+
91
+ cpPivotJoint *
92
+ cpPivotJointInit(cpPivotJoint *joint, cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2)
93
+ {
94
+ cpConstraintInit((cpConstraint *)joint, &klass, a, b);
95
+
96
+ joint->anchr1 = anchr1;
97
+ joint->anchr2 = anchr2;
98
+
99
+ joint->jAcc = cpvzero;
100
+
101
+ return joint;
102
+ }
103
+
104
+ cpConstraint *
105
+ cpPivotJointNew2(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2)
106
+ {
107
+ return (cpConstraint *)cpPivotJointInit(cpPivotJointAlloc(), a, b, anchr1, anchr2);
108
+ }
109
+
110
+ cpConstraint *
111
+ cpPivotJointNew(cpBody *a, cpBody *b, cpVect pivot)
112
+ {
113
+ return cpPivotJointNew2(a, b, cpBodyWorld2Local(a, pivot), cpBodyWorld2Local(b, pivot));
114
+ }