comparison trunk/tests/ChipmunkDemos/samples/Joints.d @ 16:af2f61a96318

ported chipmunk demos
author Extrawurst
date Sat, 04 Dec 2010 02:02:29 +0100
parents
children
comparison
equal deleted inserted replaced
15:df4ebc8add66 16:af2f61a96318
1
2 // written in the D programming language
3
4 module samples.Joints;
5
6 import chipmunkd.chipmunk;
7
8 import samples.ChipmunkDemo;
9
10 import std.math;
11
12 static cpSpace *space;
13
14 enum M_PI = PI;
15 enum M_PI_2 = PI*0.5f;
16
17 static cpBody *
18 addBall(cpVect pos, cpVect boxOffset)
19 {
20 cpFloat radius = 15.0f;
21 cpFloat mass = 1.0f;
22 cpBody *_body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForCircle(mass, 0.0f, radius, cpvzero)));
23 _body.p = cpvadd(pos, boxOffset);
24
25 cpShape *shape = cpSpaceAddShape(space, cpCircleShapeNew(_body, radius, cpvzero));
26 shape.e = 0.0f; shape.u = 0.7f;
27
28 return _body;
29 }
30
31 static cpBody *
32 addLever(cpVect pos, cpVect boxOffset)
33 {
34 cpFloat mass = 1.0f;
35 cpVect a = cpv(0, 15);
36 cpVect b = cpv(0, -15);
37
38 cpBody *_body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForSegment(mass, a, b)));
39 _body.p = cpvadd(pos, cpvadd(boxOffset, cpv(0, -15)));
40
41 cpShape *shape = cpSpaceAddShape(space, cpSegmentShapeNew(_body, a, b, 5.0f));
42 shape.e = 0.0f; shape.u = 0.7f;
43
44 return _body;
45 }
46
47 static cpBody *
48 addBar(cpVect pos, cpVect boxOffset)
49 {
50 cpFloat mass = 2.0f;
51 cpVect a = cpv(0, 30);
52 cpVect b = cpv(0, -30);
53
54 cpBody *_body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForSegment(mass, a, b)));
55 _body.p = cpvadd(pos, boxOffset);
56
57 cpShape *shape = cpSpaceAddShape(space, cpSegmentShapeNew(_body, a, b, 5.0f));
58 shape.e = 0.0f; shape.u = 0.7f;
59
60 return _body;
61 }
62
63 static cpBody *
64 addWheel(cpVect pos, cpVect boxOffset)
65 {
66 cpFloat radius = 15.0f;
67 cpFloat mass = 1.0f;
68 cpBody *_body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForCircle(mass, 0.0f, radius, cpvzero)));
69 _body.p = cpvadd(pos, boxOffset);
70
71 cpShape *shape = cpSpaceAddShape(space, cpCircleShapeNew(_body, radius, cpvzero));
72 shape.e = 0.0f; shape.u = 0.7f;
73 shape.group = 1; // use a group to keep the car parts from colliding
74
75 return _body;
76 }
77
78 static cpBody *
79 addChassis(cpVect pos, cpVect boxOffset)
80 {
81 int num = 4;
82 cpVect verts[] = [
83 cpv(-40,-15),
84 cpv(-40, 15),
85 cpv( 40, 15),
86 cpv( 40,-15),
87 ];
88
89
90 cpFloat mass = 5.0f;
91 cpBody *_body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForPoly(mass, num, verts.ptr, cpvzero)));
92 _body.p = cpvadd(pos, boxOffset);
93
94 cpShape *shape = cpSpaceAddShape(space, cpPolyShapeNew(_body, num, verts.ptr, cpvzero));
95 shape.e = 0.0f; shape.u = 0.7f;
96 shape.group = 1; // use a group to keep the car parts from colliding
97
98 return _body;
99 }
100
101 static cpSpace *
102 init()
103 {
104 space = cpSpaceNew();
105 space.iterations = 10;
106 space.gravity = cpv(0, -100);
107 space.sleepTimeThreshold = 0.5f;
108
109 cpBody *staticBody = &space.staticBody;
110 cpShape *shape;
111
112 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,240), cpv(320,240), 0.0f));
113 shape.e = 1.0f; shape.u = 1.0f;
114 shape.layers = NOT_GRABABLE_MASK;
115
116 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,120), cpv(320,120), 0.0f));
117 shape.e = 1.0f; shape.u = 1.0f;
118 shape.layers = NOT_GRABABLE_MASK;
119
120 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,0), cpv(320,0), 0.0f));
121 shape.e = 1.0f; shape.u = 1.0f;
122 shape.layers = NOT_GRABABLE_MASK;
123
124 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-120), cpv(320,-120), 0.0f));
125 shape.e = 1.0f; shape.u = 1.0f;
126 shape.layers = NOT_GRABABLE_MASK;
127
128 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(320,-240), 0.0f));
129 shape.e = 1.0f; shape.u = 1.0f;
130 shape.layers = NOT_GRABABLE_MASK;
131
132
133 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-320,-240), cpv(-320,240), 0.0f));
134 shape.e = 1.0f; shape.u = 1.0f;
135 shape.layers = NOT_GRABABLE_MASK;
136
137 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(-160,-240), cpv(-160,240), 0.0f));
138 shape.e = 1.0f; shape.u = 1.0f;
139 shape.layers = NOT_GRABABLE_MASK;
140
141 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(0,-240), cpv(0,240), 0.0f));
142 shape.e = 1.0f; shape.u = 1.0f;
143 shape.layers = NOT_GRABABLE_MASK;
144
145 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(160,-240), cpv(160,240), 0.0f));
146 shape.e = 1.0f; shape.u = 1.0f;
147 shape.layers = NOT_GRABABLE_MASK;
148
149 shape = cpSpaceAddShape(space, cpSegmentShapeNew(staticBody, cpv(320,-240), cpv(320,240), 0.0f));
150 shape.e = 1.0f; shape.u = 1.0f;
151 shape.layers = NOT_GRABABLE_MASK;
152
153 cpVect boxOffset;
154 cpBody *body1;
155 cpBody *body2;
156
157 cpVect posA = cpv( 50, 60);
158 cpVect posB = cpv(110, 60);
159
160 // Pin Joints - Link shapes with a solid bar or pin.
161 // Keeps the anchor points the same distance apart from when the joint was created.
162 boxOffset = cpv(-320, -240);
163 body1 = addBall(posA, boxOffset);
164 body2 = addBall(posB, boxOffset);
165 cpSpaceAddConstraint(space, cpPinJointNew(body1, body2, cpv(15,0), cpv(-15,0)));
166
167 // Slide Joints - Like pin joints but with a min/max distance.
168 // Can be used for a cheap approximation of a rope.
169 boxOffset = cpv(-160, -240);
170 body1 = addBall(posA, boxOffset);
171 body2 = addBall(posB, boxOffset);
172 cpSpaceAddConstraint(space, cpSlideJointNew(body1, body2, cpv(15,0), cpv(-15,0), 20.0f, 40.0f));
173
174 // Pivot Joints - Holds the two anchor points together. Like a swivel.
175 boxOffset = cpv(0, -240);
176 body1 = addBall(posA, boxOffset);
177 body2 = addBall(posB, boxOffset);
178 cpSpaceAddConstraint(space, cpPivotJointNew(body1, body2, cpvadd(boxOffset, cpv(80,60))));
179 // cpPivotJointNew() takes it's anchor parameter in world coordinates. The anchors are calculated from that
180 // cpPivotJointNew2() lets you specify the two anchor points explicitly
181
182 // Groove Joints - Like a pivot joint, but one of the anchors is a line segment that the pivot can slide in
183 boxOffset = cpv(160, -240);
184 body1 = addBall(posA, boxOffset);
185 body2 = addBall(posB, boxOffset);
186 cpSpaceAddConstraint(space, cpGrooveJointNew(body1, body2, cpv(30,30), cpv(30,-30), cpv(-30,0)));
187
188 // Damped Springs
189 boxOffset = cpv(-320, -120);
190 body1 = addBall(posA, boxOffset);
191 body2 = addBall(posB, boxOffset);
192 cpSpaceAddConstraint(space, cpDampedSpringNew(body1, body2, cpv(15,0), cpv(-15,0), 20.0f, 5.0f, 0.3f));
193
194 // Damped Rotary Springs
195 boxOffset = cpv(-160, -120);
196 body1 = addBar(posA, boxOffset);
197 body2 = addBar(posB, boxOffset);
198 // Add some pin joints to hold the circles in place.
199 cpSpaceAddConstraint(space, cpPivotJointNew(body1, staticBody, cpvadd(boxOffset, posA)));
200 cpSpaceAddConstraint(space, cpPivotJointNew(body2, staticBody, cpvadd(boxOffset, posB)));
201 cpSpaceAddConstraint(space, cpDampedRotarySpringNew(body1, body2, 0.0f, 3000.0f, 60.0f));
202
203 // Rotary Limit Joint
204 boxOffset = cpv(0, -120);
205 body1 = addLever(posA, boxOffset);
206 body2 = addLever(posB, boxOffset);
207 // Add some pin joints to hold the circles in place.
208 cpSpaceAddConstraint(space, cpPivotJointNew(body1, staticBody, cpvadd(boxOffset, posA)));
209 cpSpaceAddConstraint(space, cpPivotJointNew(body2, staticBody, cpvadd(boxOffset, posB)));
210 // Hold their rotation within 90 degrees of each other.
211 cpSpaceAddConstraint(space, cpRotaryLimitJointNew(body1, body2, -M_PI_2, M_PI_2));
212
213 // Ratchet Joint - A rotary ratchet, like a socket wrench
214 boxOffset = cpv(160, -120);
215 body1 = addLever(posA, boxOffset);
216 body2 = addLever(posB, boxOffset);
217 // Add some pin joints to hold the circles in place.
218 cpSpaceAddConstraint(space, cpPivotJointNew(body1, staticBody, cpvadd(boxOffset, posA)));
219 cpSpaceAddConstraint(space, cpPivotJointNew(body2, staticBody, cpvadd(boxOffset, posB)));
220 // Ratchet every 90 degrees
221 cpSpaceAddConstraint(space, cpRatchetJointNew(body1, body2, 0.0f, M_PI_2));
222
223 // Gear Joint - Maintain a specific angular velocity ratio
224 boxOffset = cpv(-320, 0);
225 body1 = addBar(posA, boxOffset);
226 body2 = addBar(posB, boxOffset);
227 // Add some pin joints to hold the circles in place.
228 cpSpaceAddConstraint(space, cpPivotJointNew(body1, staticBody, cpvadd(boxOffset, posA)));
229 cpSpaceAddConstraint(space, cpPivotJointNew(body2, staticBody, cpvadd(boxOffset, posB)));
230 // Force one to sping 2x as fast as the other
231 cpSpaceAddConstraint(space, cpGearJointNew(body1, body2, 0.0f, 2.0f));
232
233 // Simple Motor - Maintain a specific angular relative velocity
234 boxOffset = cpv(-160, 0);
235 body1 = addBar(posA, boxOffset);
236 body2 = addBar(posB, boxOffset);
237 // Add some pin joints to hold the circles in place.
238 cpSpaceAddConstraint(space, cpPivotJointNew(body1, staticBody, cpvadd(boxOffset, posA)));
239 cpSpaceAddConstraint(space, cpPivotJointNew(body2, staticBody, cpvadd(boxOffset, posB)));
240 // Make them spin at 1/2 revolution per second in relation to each other.
241 cpSpaceAddConstraint(space, cpSimpleMotorNew(body1, body2, M_PI));
242
243 // Make a car with some nice soft suspension
244 boxOffset = cpv(0, 0);
245 cpBody *wheel1 = addWheel(posA, boxOffset);
246 cpBody *wheel2 = addWheel(posB, boxOffset);
247 cpBody *chassis = addChassis(cpv(80, 100), boxOffset);
248
249 cpSpaceAddConstraint(space, cpGrooveJointNew(chassis, wheel1, cpv(-30, -10), cpv(-30, -40), cpvzero));
250 cpSpaceAddConstraint(space, cpGrooveJointNew(chassis, wheel2, cpv( 30, -10), cpv( 30, -40), cpvzero));
251
252 cpSpaceAddConstraint(space, cpDampedSpringNew(chassis, wheel1, cpv(-30, 0), cpvzero, 50.0f, 20.0f, 1.5f));
253 cpSpaceAddConstraint(space, cpDampedSpringNew(chassis, wheel2, cpv( 30, 0), cpvzero, 50.0f, 20.0f, 1.5f));
254
255 return space;
256 }
257
258 static void
259 update(int ticks)
260 {
261 cpSpaceStep(space, 1.0f/60.0f);
262 }
263
264 static void
265 destroy()
266 {
267 cpSpaceFreeChildren(space);
268 cpSpaceFree(space);
269 }
270
271 chipmunkDemo Joints = {
272 "Joints and Constraints",
273 null,
274 &init,
275 &update,
276 &destroy,
277 };