chipmunk 4.1.0-x86-mswin32

Sign up to get free protection for your applications and to get access to all the features.
data/Rakefile ADDED
@@ -0,0 +1,38 @@
1
+ # Rakefile added by John Mair (banisterfiend)
2
+
3
+ require 'rake/clean'
4
+ require 'rake/extensiontask'
5
+ require 'rake/gempackagetask'
6
+
7
+ CHIPMUNK_VERSION = "4.1.0"
8
+
9
+ CLEAN.include("ext/**/*.#{$dlext}", "ext/**/.log", "ext/**/.o", "ext/**/*~", "ext/**/*#*", "ext/**/.obj", "ext/**/.def", "ext/**/.pdb")
10
+ CLOBBER.include("**/*.#{$dlext}", "**/*~", "**/*#*", "**/*.log", "**/*.o", "doc/**")
11
+
12
+ Rake::ExtensionTask.new('chipmunk')
13
+
14
+ spec = Gem::Specification.new do |s|
15
+ s.name = "chipmunk"
16
+ s.summary = "ruby bindings for the chipmunk physics engine"
17
+ s.description = s.summary
18
+ s.version = CHIPMUNK_VERSION
19
+ s.author = "Scott Lembcke, Beoran, John Mair (banisterfiend)"
20
+ s.email = 'jrmair@gmail.com'
21
+ s.date = Time.now.strftime '%Y-%m-%d'
22
+ s.require_path = 'lib'
23
+ s.homepage = "http://code.google.com/p/chipmunk-physics/"
24
+ s.platform = Gem::Platform::RUBY
25
+ s.extensions = FileList["ext/**/extconf.rb"]
26
+ s.files = ["Rakefile", "lib/chipmunk.rb"] + FileList["ext/**/extconf.rb", "ext/**/*.h",
27
+ "ext/**/*.c"].to_a
28
+ end
29
+
30
+ Rake::GemPackageTask.new(spec) do |pkg|
31
+ pkg.need_zip = false
32
+ pkg.need_tar = false
33
+ end
34
+
35
+ Rake::ExtensionTask.new('chipmunk', spec) do |ext|
36
+ ext.cross_compile = true
37
+ ext.cross_platform = 'i386-mswin32'
38
+ end
@@ -0,0 +1,69 @@
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
+
26
+ #ifdef __cplusplus
27
+ extern "C" {
28
+ #endif
29
+ void cpInitCollisionFuncs(void);
30
+ #ifdef __cplusplus
31
+ }
32
+ #endif
33
+
34
+
35
+ void
36
+ cpInitChipmunk(void)
37
+ {
38
+ cpInitCollisionFuncs();
39
+ }
40
+
41
+ cpFloat
42
+ cpMomentForCircle(cpFloat m, cpFloat r1, cpFloat r2, cpVect offset)
43
+ {
44
+ return (1.0f/2.0f)*m*(r1*r1 + r2*r2) + m*cpvdot(offset, offset);
45
+ }
46
+
47
+ cpFloat
48
+ cpMomentForPoly(cpFloat m, const int numVerts, cpVect *verts, cpVect offset)
49
+ {
50
+ cpVect *tVerts = (cpVect *)calloc(numVerts, sizeof(cpVect));
51
+ for(int i=0; i<numVerts; i++)
52
+ tVerts[i] = cpvadd(verts[i], offset);
53
+
54
+ cpFloat sum1 = 0.0f;
55
+ cpFloat sum2 = 0.0f;
56
+ for(int i=0; i<numVerts; i++){
57
+ cpVect v1 = tVerts[i];
58
+ cpVect v2 = tVerts[(i+1)%numVerts];
59
+
60
+ cpFloat a = cpvcross(v2, v1);
61
+ cpFloat b = cpvdot(v1, v1) + cpvdot(v1, v2) + cpvdot(v2, v2);
62
+
63
+ sum1 += a*b;
64
+ sum2 += a;
65
+ }
66
+
67
+ free(tVerts);
68
+ return (m*sum1)/(6.0f*sum2);
69
+ }
@@ -0,0 +1,91 @@
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
+ #ifndef CHIPMUNK_HEADER
23
+ #define CHIPMUNK_HEADER
24
+
25
+ #ifdef __cplusplus
26
+ extern "C" {
27
+ #endif
28
+
29
+ typedef double cpFloat;
30
+
31
+ static inline cpFloat
32
+ cpfmax(cpFloat a, cpFloat b)
33
+ {
34
+ return (a > b) ? a : b;
35
+ }
36
+
37
+ static inline cpFloat
38
+ cpfmin(cpFloat a, cpFloat b)
39
+ {
40
+ return (a < b) ? a : b;
41
+ }
42
+
43
+ static inline cpFloat
44
+ cpfclamp(cpFloat f, cpFloat min, cpFloat max){
45
+ return cpfmin(cpfmax(f, min), max);
46
+ }
47
+
48
+ #ifndef INFINITY
49
+ #ifdef _MSC_VER
50
+ union MSVC_EVIL_FLOAT_HACK
51
+ {
52
+ unsigned __int8 Bytes[4];
53
+ float Value;
54
+ };
55
+ static union MSVC_EVIL_FLOAT_HACK INFINITY_HACK = {{0x00, 0x00, 0x80, 0x7F}};
56
+ #define INFINITY (INFINITY_HACK.Value)
57
+ #else
58
+ #define INFINITY (1e1000)
59
+ #endif
60
+ #endif
61
+
62
+ #include "cpVect.h"
63
+ #include "cpBB.h"
64
+ #include "cpBody.h"
65
+ #include "cpArray.h"
66
+ #include "cpHashSet.h"
67
+ #include "cpSpaceHash.h"
68
+
69
+ #include "cpShape.h"
70
+ #include "cpPolyShape.h"
71
+
72
+ #include "cpArbiter.h"
73
+ #include "cpCollision.h"
74
+
75
+ #include "cpJoint.h"
76
+
77
+ #include "cpSpace.h"
78
+
79
+ #define CP_HASH_COEF (3344921057ul)
80
+ #define CP_HASH_PAIR(A, B) ((unsigned int)(A)*CP_HASH_COEF ^ (unsigned int)(B)*CP_HASH_COEF)
81
+
82
+ void cpInitChipmunk(void);
83
+
84
+ cpFloat cpMomentForCircle(cpFloat m, cpFloat r1, cpFloat r2, cpVect offset);
85
+ cpFloat cpMomentForPoly(cpFloat m, int numVerts, cpVect *verts, cpVect offset);
86
+
87
+ #ifdef __cplusplus
88
+ }
89
+ #endif
90
+
91
+ #endif
@@ -0,0 +1,263 @@
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
+ cpFloat cp_bias_coef = 0.1f;
28
+ cpFloat cp_collision_slop = 0.1f;
29
+
30
+ cpContact*
31
+ cpContactInit(cpContact *con, cpVect p, cpVect n, cpFloat dist, unsigned int hash)
32
+ {
33
+ con->p = p;
34
+ con->n = n;
35
+ con->dist = dist;
36
+
37
+ con->jnAcc = 0.0f;
38
+ con->jtAcc = 0.0f;
39
+ con->jBias = 0.0f;
40
+
41
+ con->hash = hash;
42
+
43
+ return con;
44
+ }
45
+
46
+ cpVect
47
+ cpContactsSumImpulses(cpContact *contacts, int numContacts)
48
+ {
49
+ cpVect sum = cpvzero;
50
+
51
+ for(int i=0; i<numContacts; i++){
52
+ cpContact *con = &contacts[i];
53
+ cpVect j = cpvmult(con->n, con->jnAcc);
54
+ sum = cpvadd(sum, j);
55
+ }
56
+
57
+ return sum;
58
+ }
59
+
60
+ cpVect
61
+ cpContactsSumImpulsesWithFriction(cpContact *contacts, int numContacts)
62
+ {
63
+ cpVect sum = cpvzero;
64
+
65
+ for(int i=0; i<numContacts; i++){
66
+ cpContact *con = &contacts[i];
67
+ cpVect t = cpvperp(con->n);
68
+ cpVect j = cpvadd(cpvmult(con->n, con->jnAcc), cpvmult(t, con->jtAcc));
69
+ sum = cpvadd(sum, j);
70
+ }
71
+
72
+ return sum;
73
+ }
74
+
75
+ cpArbiter*
76
+ cpArbiterAlloc(void)
77
+ {
78
+ return (cpArbiter *)calloc(1, sizeof(cpArbiter));
79
+ }
80
+
81
+ cpArbiter*
82
+ cpArbiterInit(cpArbiter *arb, cpShape *a, cpShape *b, int stamp)
83
+ {
84
+ arb->numContacts = 0;
85
+ arb->contacts = NULL;
86
+
87
+ arb->a = a;
88
+ arb->b = b;
89
+
90
+ arb->stamp = stamp;
91
+
92
+ return arb;
93
+ }
94
+
95
+ cpArbiter*
96
+ cpArbiterNew(cpShape *a, cpShape *b, int stamp)
97
+ {
98
+ return cpArbiterInit(cpArbiterAlloc(), a, b, stamp);
99
+ }
100
+
101
+ void
102
+ cpArbiterDestroy(cpArbiter *arb)
103
+ {
104
+ free(arb->contacts);
105
+ }
106
+
107
+ void
108
+ cpArbiterFree(cpArbiter *arb)
109
+ {
110
+ if(arb) cpArbiterDestroy(arb);
111
+ free(arb);
112
+ }
113
+
114
+ void
115
+ cpArbiterInject(cpArbiter *arb, cpContact *contacts, int numContacts)
116
+ {
117
+ // Iterate over the possible pairs to look for hash value matches.
118
+ for(int i=0; i<arb->numContacts; i++){
119
+ cpContact *old = &arb->contacts[i];
120
+
121
+ for(int j=0; j<numContacts; j++){
122
+ cpContact *new_contact = &contacts[j];
123
+
124
+ // This could trigger false possitives.
125
+ if(new_contact->hash == old->hash){
126
+ // Copy the persistant contact information.
127
+ new_contact->jnAcc = old->jnAcc;
128
+ new_contact->jtAcc = old->jtAcc;
129
+ }
130
+ }
131
+ }
132
+
133
+ free(arb->contacts);
134
+
135
+ arb->contacts = contacts;
136
+ arb->numContacts = numContacts;
137
+ }
138
+
139
+ void
140
+ cpArbiterPreStep(cpArbiter *arb, cpFloat dt_inv)
141
+ {
142
+ cpShape *shapea = arb->a;
143
+ cpShape *shapeb = arb->b;
144
+
145
+ cpFloat e = shapea->e * shapeb->e;
146
+ arb->u = shapea->u * shapeb->u;
147
+ arb->target_v = cpvsub(shapeb->surface_v, shapea->surface_v);
148
+
149
+ cpBody *a = shapea->body;
150
+ cpBody *b = shapeb->body;
151
+
152
+ for(int i=0; i<arb->numContacts; i++){
153
+ cpContact *con = &arb->contacts[i];
154
+
155
+ // Calculate the offsets.
156
+ con->r1 = cpvsub(con->p, a->p);
157
+ con->r2 = cpvsub(con->p, b->p);
158
+
159
+ // Calculate the mass normal.
160
+ cpFloat mass_sum = a->m_inv + b->m_inv;
161
+
162
+ cpFloat r1cn = cpvcross(con->r1, con->n);
163
+ cpFloat r2cn = cpvcross(con->r2, con->n);
164
+ cpFloat kn = mass_sum + a->i_inv*r1cn*r1cn + b->i_inv*r2cn*r2cn;
165
+ con->nMass = 1.0f/kn;
166
+
167
+ // Calculate the mass tangent.
168
+ cpVect t = cpvperp(con->n);
169
+ cpFloat r1ct = cpvcross(con->r1, t);
170
+ cpFloat r2ct = cpvcross(con->r2, t);
171
+ cpFloat kt = mass_sum + a->i_inv*r1ct*r1ct + b->i_inv*r2ct*r2ct;
172
+ con->tMass = 1.0f/kt;
173
+
174
+ // Calculate the target bias velocity.
175
+ con->bias = -cp_bias_coef*dt_inv*cpfmin(0.0f, con->dist + cp_collision_slop);
176
+ con->jBias = 0.0f;
177
+
178
+ // Calculate the target bounce velocity.
179
+ cpVect v1 = cpvadd(a->v, cpvmult(cpvperp(con->r1), a->w));
180
+ cpVect v2 = cpvadd(b->v, cpvmult(cpvperp(con->r2), b->w));
181
+ con->bounce = cpvdot(con->n, cpvsub(v2, v1))*e;
182
+ }
183
+ }
184
+
185
+ void
186
+ cpArbiterApplyCachedImpulse(cpArbiter *arb)
187
+ {
188
+ cpShape *shapea = arb->a;
189
+ cpShape *shapeb = arb->b;
190
+
191
+ arb->u = shapea->u * shapeb->u;
192
+ arb->target_v = cpvsub(shapeb->surface_v, shapea->surface_v);
193
+
194
+ cpBody *a = shapea->body;
195
+ cpBody *b = shapeb->body;
196
+
197
+ for(int i=0; i<arb->numContacts; i++){
198
+ cpContact *con = &arb->contacts[i];
199
+
200
+ cpVect t = cpvperp(con->n);
201
+ cpVect j = cpvadd(cpvmult(con->n, con->jnAcc), cpvmult(t, con->jtAcc));
202
+ cpBodyApplyImpulse(a, cpvneg(j), con->r1);
203
+ cpBodyApplyImpulse(b, j, con->r2);
204
+ }
205
+ }
206
+
207
+ void
208
+ cpArbiterApplyImpulse(cpArbiter *arb, cpFloat eCoef)
209
+ {
210
+ cpBody *a = arb->a->body;
211
+ cpBody *b = arb->b->body;
212
+
213
+ for(int i=0; i<arb->numContacts; i++){
214
+ cpContact *con = &arb->contacts[i];
215
+ cpVect n = con->n;
216
+ cpVect r1 = con->r1;
217
+ cpVect r2 = con->r2;
218
+
219
+ // Calculate the relative bias velocities.
220
+ cpVect vb1 = cpvadd(a->v_bias, cpvmult(cpvperp(r1), a->w_bias));
221
+ cpVect vb2 = cpvadd(b->v_bias, cpvmult(cpvperp(r2), b->w_bias));
222
+ cpFloat vbn = cpvdot(cpvsub(vb2, vb1), n);
223
+
224
+ // Calculate and clamp the bias impulse.
225
+ cpFloat jbn = (con->bias - vbn)*con->nMass;
226
+ cpFloat jbnOld = con->jBias;
227
+ con->jBias = cpfmax(jbnOld + jbn, 0.0f);
228
+ jbn = con->jBias - jbnOld;
229
+
230
+ // Apply the bias impulse.
231
+ cpVect jb = cpvmult(n, jbn);
232
+ cpBodyApplyBiasImpulse(a, cpvneg(jb), r1);
233
+ cpBodyApplyBiasImpulse(b, jb, r2);
234
+
235
+ // Calculate the relative velocity.
236
+ cpVect v1 = cpvadd(a->v, cpvmult(cpvperp(r1), a->w));
237
+ cpVect v2 = cpvadd(b->v, cpvmult(cpvperp(r2), b->w));
238
+ cpVect vr = cpvsub(v2, v1);
239
+ cpFloat vrn = cpvdot(vr, n);
240
+
241
+ // Calculate and clamp the normal impulse.
242
+ cpFloat jn = -(con->bounce*eCoef + vrn)*con->nMass;
243
+ cpFloat jnOld = con->jnAcc;
244
+ con->jnAcc = cpfmax(jnOld + jn, 0.0f);
245
+ jn = con->jnAcc - jnOld;
246
+
247
+ // Calculate the relative tangent velocity.
248
+ cpVect t = cpvperp(n);
249
+ cpFloat vrt = cpvdot(cpvadd(vr, arb->target_v), t);
250
+
251
+ // Calculate and clamp the friction impulse.
252
+ cpFloat jtMax = arb->u*con->jnAcc;
253
+ cpFloat jt = -vrt*con->tMass;
254
+ cpFloat jtOld = con->jtAcc;
255
+ con->jtAcc = cpfclamp(jtOld + jt, -jtMax, jtMax);
256
+ jt = con->jtAcc - jtOld;
257
+
258
+ // Apply the final impulse.
259
+ cpVect j = cpvadd(cpvmult(n, jn), cpvmult(t, jt));
260
+ cpBodyApplyImpulse(a, cpvneg(j), r1);
261
+ cpBodyApplyImpulse(b, j, r2);
262
+ }
263
+ }