Mercurial > projects > chipmunkd
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 }; |