chipmunk 4.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,46 @@
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 <math.h>
23
+
24
+ #include "chipmunk.h"
25
+
26
+ cpVect
27
+ cpBBClampVect(const cpBB bb, const cpVect v)
28
+ {
29
+ cpFloat x = cpfmin(cpfmax(bb.l, v.x), bb.r);
30
+ cpFloat y = cpfmin(cpfmax(bb.b, v.y), bb.t);
31
+ return cpv(x, y);
32
+ }
33
+
34
+ cpVect
35
+ cpBBWrapVect(const cpBB bb, const cpVect v)
36
+ {
37
+ cpFloat ix = fabsf(bb.r - bb.l);
38
+ cpFloat modx = fmodf(v.x - bb.l, ix);
39
+ cpFloat x = (modx > 0.0f) ? modx : modx + ix;
40
+
41
+ cpFloat iy = fabsf(bb.t - bb.b);
42
+ cpFloat mody = fmodf(v.y - bb.b, iy);
43
+ cpFloat y = (mody > 0.0f) ? mody : mody + iy;
44
+
45
+ return cpv(x + bb.l, y + bb.b);
46
+ }
@@ -0,0 +1,53 @@
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
+ typedef struct cpBB{
23
+ cpFloat l, b, r ,t;
24
+ } cpBB;
25
+
26
+ static inline cpBB
27
+ cpBBNew(const cpFloat l, const cpFloat b,
28
+ const cpFloat r, const cpFloat t)
29
+ {
30
+ cpBB bb = {l, b, r, t};
31
+ return bb;
32
+ }
33
+
34
+ static inline int
35
+ cpBBintersects(const cpBB a, const cpBB b)
36
+ {
37
+ return (a.l<=b.r && b.l<=a.r && a.b<=b.t && b.b<=a.t);
38
+ }
39
+
40
+ static inline int
41
+ cpBBcontainsBB(const cpBB bb, const cpBB other)
42
+ {
43
+ return (bb.l < other.l && bb.r > other.r && bb.b < other.b && bb.t > other.t);
44
+ }
45
+
46
+ static inline int
47
+ cpBBcontainsVect(const cpBB bb, const cpVect v)
48
+ {
49
+ return (bb.l < v.x && bb.r > v.x && bb.b < v.y && bb.t > v.y);
50
+ }
51
+
52
+ cpVect cpBBClampVect(const cpBB bb, const cpVect v); // clamps the vector to lie within the bbox
53
+ cpVect cpBBWrapVect(const cpBB bb, const cpVect v); // wrap a vector to a bbox
@@ -0,0 +1,180 @@
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
+ #include <float.h>
25
+
26
+ #include "chipmunk.h"
27
+
28
+ cpBody*
29
+ cpBodyAlloc(void)
30
+ {
31
+ return (cpBody *)malloc(sizeof(cpBody));
32
+ }
33
+
34
+ cpBody*
35
+ cpBodyInit(cpBody *body, cpFloat m, cpFloat i)
36
+ {
37
+ body->velocity_func = cpBodyUpdateVelocity;
38
+ body->position_func = cpBodyUpdatePosition;
39
+
40
+ cpBodySetMass(body, m);
41
+ cpBodySetMoment(body, i);
42
+
43
+ body->p = cpvzero;
44
+ body->v = cpvzero;
45
+ body->f = cpvzero;
46
+
47
+ cpBodySetAngle(body, 0.0f);
48
+ body->w = 0.0f;
49
+ body->t = 0.0f;
50
+
51
+ body->v_bias = cpvzero;
52
+ body->w_bias = 0.0f;
53
+
54
+ body->data = NULL;
55
+ // body->active = 1;
56
+
57
+ return body;
58
+ }
59
+
60
+ cpBody*
61
+ cpBodyNew(cpFloat m, cpFloat i)
62
+ {
63
+ return cpBodyInit(cpBodyAlloc(), m, i);
64
+ }
65
+
66
+ void cpBodyDestroy(cpBody *body){}
67
+
68
+ void
69
+ cpBodyFree(cpBody *body)
70
+ {
71
+ if(body) cpBodyDestroy(body);
72
+ free(body);
73
+ }
74
+
75
+ void
76
+ cpBodySetMass(cpBody *body, cpFloat m)
77
+ {
78
+ body->m = m;
79
+ body->m_inv = 1.0f/m;
80
+ }
81
+
82
+ void
83
+ cpBodySetMoment(cpBody *body, cpFloat i)
84
+ {
85
+ body->i = i;
86
+ body->i_inv = 1.0f/i;
87
+ }
88
+
89
+ void
90
+ cpBodySetAngle(cpBody *body, cpFloat a)
91
+ {
92
+ body->a = fmod(a, (cpFloat)M_PI*2.0f);
93
+ body->rot = cpvforangle(a);
94
+ }
95
+
96
+ void
97
+ cpBodySlew(cpBody *body, cpVect pos, cpFloat dt)
98
+ {
99
+ cpVect delta = cpvsub(pos, body->p);
100
+ body->v = cpvmult(delta, 1.0/dt);
101
+ }
102
+
103
+ void
104
+ cpBodyUpdateVelocity(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt)
105
+ {
106
+ body->v = cpvadd(cpvmult(body->v, damping), cpvmult(cpvadd(gravity, cpvmult(body->f, body->m_inv)), dt));
107
+ body->w = body->w*damping + body->t*body->i_inv*dt;
108
+ }
109
+
110
+ void
111
+ cpBodyUpdatePosition(cpBody *body, cpFloat dt)
112
+ {
113
+ body->p = cpvadd(body->p, cpvmult(cpvadd(body->v, body->v_bias), dt));
114
+ cpBodySetAngle(body, body->a + (body->w + body->w_bias)*dt);
115
+
116
+ body->v_bias = cpvzero;
117
+ body->w_bias = 0.0f;
118
+ }
119
+
120
+ void
121
+ cpBodyResetForces(cpBody *body)
122
+ {
123
+ body->f = cpvzero;
124
+ body->t = 0.0f;
125
+ }
126
+
127
+ void
128
+ cpBodyApplyForce(cpBody *body, cpVect f, cpVect r)
129
+ {
130
+ body->f = cpvadd(body->f, f);
131
+ body->t += cpvcross(r, f);
132
+ }
133
+
134
+ void
135
+ cpDampedSpring(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat rlen, cpFloat k, cpFloat dmp, cpFloat dt)
136
+ {
137
+ // Calculate the world space anchor coordinates.
138
+ cpVect r1 = cpvrotate(anchr1, a->rot);
139
+ cpVect r2 = cpvrotate(anchr2, b->rot);
140
+
141
+ cpVect delta = cpvsub(cpvadd(b->p, r2), cpvadd(a->p, r1));
142
+ cpFloat dist = cpvlength(delta);
143
+ cpVect n = dist ? cpvmult(delta, 1.0f/dist) : cpvzero;
144
+
145
+ cpFloat f_spring = (dist - rlen)*k;
146
+
147
+ // Calculate the world relative velocities of the anchor points.
148
+ cpVect v1 = cpvadd(a->v, cpvmult(cpvperp(r1), a->w));
149
+ cpVect v2 = cpvadd(b->v, cpvmult(cpvperp(r2), b->w));
150
+
151
+ // Calculate the damping force.
152
+ // This really should be in the impulse solver and can produce problems when using large damping values.
153
+ cpFloat vrn = cpvdot(cpvsub(v2, v1), n);
154
+ cpFloat f_damp = vrn*cpfmin(dmp, 1.0f/(dt*(a->m_inv + b->m_inv)));
155
+
156
+ // Apply!
157
+ cpVect f = cpvmult(n, f_spring + f_damp);
158
+ cpBodyApplyForce(a, f, r1);
159
+ cpBodyApplyForce(b, cpvneg(f), r2);
160
+ }
161
+
162
+ //int
163
+ //cpBodyMarkLowEnergy(cpBody *body, cpFloat dvsq, int max)
164
+ //{
165
+ // cpFloat ke = body->m*cpvdot(body->v, body->v);
166
+ // cpFloat re = body->i*body->w*body->w;
167
+ //
168
+ // if(ke + re > body->m*dvsq)
169
+ // body->active = 1;
170
+ // else if(body->active)
171
+ // body->active = (body->active + 1)%(max + 1);
172
+ // else {
173
+ // body->v = cpvzero;
174
+ // body->v_bias = cpvzero;
175
+ // body->w = 0.0f;
176
+ // body->w_bias = 0.0f;
177
+ // }
178
+ //
179
+ // return body->active;
180
+ //}
@@ -0,0 +1,132 @@
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
+ struct cpBody;
23
+ typedef void (*cpBodyVelocityFunc)(struct cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt);
24
+ typedef void (*cpBodyPositionFunc)(struct cpBody *body, cpFloat dt);
25
+
26
+
27
+ typedef struct cpBody{
28
+ // *** Integration Functions.
29
+
30
+ // Function that is called to integrate the body's velocity. (Defaults to cpBodyUpdateVelocity)
31
+ cpBodyVelocityFunc velocity_func;
32
+
33
+ // Function that is called to integrate the body's position. (Defaults to cpBodyUpdatePosition)
34
+ cpBodyPositionFunc position_func;
35
+
36
+ // *** Mass Properties
37
+
38
+ // Mass and it's inverse.
39
+ // Always use cpBodySetMass() whenever changing the mass as these values must agree.
40
+ cpFloat m, m_inv;
41
+
42
+ // Moment of inertia and it's inverse.
43
+ // Always use cpBodySetMass() whenever changing the mass as these values must agree.
44
+ cpFloat i, i_inv;
45
+
46
+ // *** Positional Properties
47
+
48
+ // Linear components of motion (position, velocity, and force)
49
+ cpVect p, v, f;
50
+
51
+ // Angular components of motion (angle, angular velocity, and torque)
52
+ // Always use cpBodySetAngle() to set the angle of the body as a and rot must agree.
53
+ cpFloat a, w, t;
54
+
55
+ // Cached unit length vector representing the angle of the body.
56
+ // Used for fast vector rotation using cpvrotate().
57
+ cpVect rot;
58
+
59
+ // *** User Definable Fields
60
+
61
+ // User defined data pointer.
62
+ void *data;
63
+
64
+ // *** Internally Used Fields
65
+
66
+ // Velocity bias values used when solving penetrations and correcting joints.
67
+ cpVect v_bias;
68
+ cpFloat w_bias;
69
+
70
+ // int active;
71
+ } cpBody;
72
+
73
+ // Basic allocation/destruction functions
74
+ cpBody *cpBodyAlloc(void);
75
+ cpBody *cpBodyInit(cpBody *body, cpFloat m, cpFloat i);
76
+ cpBody *cpBodyNew(cpFloat m, cpFloat i);
77
+
78
+ void cpBodyDestroy(cpBody *body);
79
+ void cpBodyFree(cpBody *body);
80
+
81
+ // Setters for some of the special properties (mandatory!)
82
+ void cpBodySetMass(cpBody *body, cpFloat m);
83
+ void cpBodySetMoment(cpBody *body, cpFloat i);
84
+ void cpBodySetAngle(cpBody *body, cpFloat a);
85
+
86
+ // Modify the velocity of the body so that it will move to the specified absolute coordinates in the next timestep.
87
+ // Intended for objects that are moved manually with a custom velocity integration function.
88
+ void cpBodySlew(cpBody *body, cpVect pos, cpFloat dt);
89
+
90
+ // Default Integration functions.
91
+ void cpBodyUpdateVelocity(cpBody *body, cpVect gravity, cpFloat damping, cpFloat dt);
92
+ void cpBodyUpdatePosition(cpBody *body, cpFloat dt);
93
+
94
+ // Convert body local to world coordinates
95
+ static inline cpVect
96
+ cpBodyLocal2World(cpBody *body, cpVect v)
97
+ {
98
+ return cpvadd(body->p, cpvrotate(v, body->rot));
99
+ }
100
+
101
+ // Convert world to body local coordinates
102
+ static inline cpVect
103
+ cpBodyWorld2Local(cpBody *body, cpVect v)
104
+ {
105
+ return cpvunrotate(cpvsub(v, body->p), body->rot);
106
+ }
107
+
108
+ // Apply an impulse (in world coordinates) to the body.
109
+ static inline void
110
+ cpBodyApplyImpulse(cpBody *body, cpVect j, cpVect r)
111
+ {
112
+ body->v = cpvadd(body->v, cpvmult(j, body->m_inv));
113
+ body->w += body->i_inv*cpvcross(r, j);
114
+ }
115
+
116
+ // Not intended for external use. Used by cpArbiter.c and cpJoint.c.
117
+ static inline void
118
+ cpBodyApplyBiasImpulse(cpBody *body, cpVect j, cpVect r)
119
+ {
120
+ body->v_bias = cpvadd(body->v_bias, cpvmult(j, body->m_inv));
121
+ body->w_bias += body->i_inv*cpvcross(r, j);
122
+ }
123
+
124
+ // Zero the forces on a body.
125
+ void cpBodyResetForces(cpBody *body);
126
+ // Apply a force (in world coordinates) to a body.
127
+ void cpBodyApplyForce(cpBody *body, cpVect f, cpVect r);
128
+
129
+ // Apply a damped spring force between two bodies.
130
+ void cpDampedSpring(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat rlen, cpFloat k, cpFloat dmp, cpFloat dt);
131
+
132
+ //int cpBodyMarkLowEnergy(cpBody *body, cpFloat dvsq, int max);