1 
2 // written in the D programming language
3 
4 module samples.Springies;
5 
6 import dchip.all;
7 
8 import samples.ChipmunkDemo;
9 
10 static cpSpace *space;
11 
12 static cpFloat
13 springForce(cpConstraint *spring, cpFloat dist)
14 {
15     cpFloat clamp = 20.0f;
16     return cpfclamp(cpDampedSpringGetRestLength(spring) - dist, -clamp, clamp)*cpDampedSpringGetStiffness(spring);
17 }
18 
19 static cpConstraint *
20 new_spring(cpBody *a, cpBody *b, cpVect anchr1, cpVect anchr2, cpFloat restLength, cpFloat stiff, cpFloat damp)
21 {
22     cpConstraint *spring = cpDampedSpringNew(a, b, anchr1, anchr2, restLength, stiff, damp);
23     cpDampedSpringSetSpringForceFunc(spring, &springForce);
24 
25     return spring;
26 }
27 
28 static void
29 update(int ticks)
30 {
31     enum int steps = 1;
32     enum cpFloat dt = 1.0f/60.0f/cast(cpFloat)steps;
33 
34     for(int i=0; i<steps; i++){
35         cpSpaceStep(space, dt);
36     }
37 }
38 
39 static cpBody *
40 add_bar(cpVect a, cpVect b, int group)
41 {
42     cpVect center = cpvmult(cpvadd(a, b), 1.0f/2.0f);
43     cpFloat length = cpvlength(cpvsub(b, a));
44     cpFloat mass = length/160.0f;
45 
46     cpBody *_body = cpSpaceAddBody(space, cpBodyNew(mass, mass*length*length/12.0f));
47     _body.p = center;
48 
49     cpShape *shape = cpSpaceAddShape(space, cpSegmentShapeNew(_body, cpvsub(a, center), cpvsub(b, center), 10.0f));
50     shape.group = group;
51 
52     return _body;
53 }
54 
55 static cpSpace *
56 init()
57 {
58     space = cpSpaceNew();
59     cpBody *staticBody = space.staticBody;
60 
61     cpBody *body1  = add_bar(cpv(-240,  160), cpv(-160,   80), 1);
62     cpBody *body2  = add_bar(cpv(-160,   80), cpv( -80,  160), 1);
63     cpBody *body3  = add_bar(cpv(   0,  160), cpv(  80,    0), 0);
64     cpBody *body4  = add_bar(cpv( 160,  160), cpv( 240,  160), 0);
65     cpBody *body5  = add_bar(cpv(-240,    0), cpv(-160,  -80), 2);
66     cpBody *body6  = add_bar(cpv(-160,  -80), cpv( -80,    0), 2);
67     cpBody *body7  = add_bar(cpv( -80,    0), cpv(   0,    0), 2);
68     cpBody *body8  = add_bar(cpv(   0,  -80), cpv(  80,  -80), 0);
69     cpBody *body9  = add_bar(cpv( 240,   80), cpv( 160,    0), 3);
70     cpBody *body10 = add_bar(cpv( 160,    0), cpv( 240,  -80), 3);
71     cpBody *body11 = add_bar(cpv(-240,  -80), cpv(-160, -160), 4);
72     cpBody *body12 = add_bar(cpv(-160, -160), cpv( -80, -160), 0);
73     cpBody *body13 = add_bar(cpv(   0, -160), cpv(  80, -160), 0);
74     cpBody *body14 = add_bar(cpv( 160, -160), cpv( 240, -160), 0);
75 
76     cpSpaceAddConstraint(space, cpPivotJointNew2( body1,  body2, cpv( 40,-40), cpv(-40,-40)));
77     cpSpaceAddConstraint(space, cpPivotJointNew2( body5,  body6, cpv( 40,-40), cpv(-40,-40)));
78     cpSpaceAddConstraint(space, cpPivotJointNew2( body6,  body7, cpv( 40, 40), cpv(-40,  0)));
79     cpSpaceAddConstraint(space, cpPivotJointNew2( body9, body10, cpv(-40,-40), cpv(-40, 40)));
80     cpSpaceAddConstraint(space, cpPivotJointNew2(body11, body12, cpv( 40,-40), cpv(-40,  0)));
81 
82     cpFloat stiff = 100.0f;
83     cpFloat damp = 0.5f;
84     cpSpaceAddConstraint(space, new_spring(staticBody,  body1, cpv(-320,  240), cpv(-40, 40), 0.0f, stiff, damp));
85     cpSpaceAddConstraint(space, new_spring(staticBody,  body1, cpv(-320,   80), cpv(-40, 40), 0.0f, stiff, damp));
86     cpSpaceAddConstraint(space, new_spring(staticBody,  body1, cpv(-160,  240), cpv(-40, 40), 0.0f, stiff, damp));
87 
88     cpSpaceAddConstraint(space, new_spring(staticBody,  body2, cpv(-160,  240), cpv( 40, 40), 0.0f, stiff, damp));
89     cpSpaceAddConstraint(space, new_spring(staticBody,  body2, cpv(   0,  240), cpv( 40, 40), 0.0f, stiff, damp));
90 
91     cpSpaceAddConstraint(space, new_spring(staticBody,  body3, cpv(  80,  240), cpv(-40, 80), 0.0f, stiff, damp));
92 
93     cpSpaceAddConstraint(space, new_spring(staticBody,  body4, cpv(  80,  240), cpv(-40,  0), 0.0f, stiff, damp));
94     cpSpaceAddConstraint(space, new_spring(staticBody,  body4, cpv( 320,  240), cpv( 40,  0), 0.0f, stiff, damp));
95 
96     cpSpaceAddConstraint(space, new_spring(staticBody,  body5, cpv(-320,   80), cpv(-40, 40), 0.0f, stiff, damp));
97 
98     cpSpaceAddConstraint(space, new_spring(staticBody,  body9, cpv( 320,  80), cpv( 40, 40), 0.0f, stiff, damp));
99 
100     cpSpaceAddConstraint(space, new_spring(staticBody, body10, cpv( 320,   0), cpv( 40,-40), 0.0f, stiff, damp));
101     cpSpaceAddConstraint(space, new_spring(staticBody, body10, cpv( 320,-160), cpv( 40,-40), 0.0f, stiff, damp));
102 
103     cpSpaceAddConstraint(space, new_spring(staticBody, body11, cpv(-320,-160), cpv(-40, 40), 0.0f, stiff, damp));
104 
105     cpSpaceAddConstraint(space, new_spring(staticBody, body12, cpv(-240,-240), cpv(-40,  0), 0.0f, stiff, damp));
106     cpSpaceAddConstraint(space, new_spring(staticBody, body12, cpv(   0,-240), cpv( 40,  0), 0.0f, stiff, damp));
107 
108     cpSpaceAddConstraint(space, new_spring(staticBody, body13, cpv(   0,-240), cpv(-40,  0), 0.0f, stiff, damp));
109     cpSpaceAddConstraint(space, new_spring(staticBody, body13, cpv(  80,-240), cpv( 40,  0), 0.0f, stiff, damp));
110 
111     cpSpaceAddConstraint(space, new_spring(staticBody, body14, cpv(  80,-240), cpv(-40,  0), 0.0f, stiff, damp));
112     cpSpaceAddConstraint(space, new_spring(staticBody, body14, cpv( 240,-240), cpv( 40,  0), 0.0f, stiff, damp));
113     cpSpaceAddConstraint(space, new_spring(staticBody, body14, cpv( 320,-160), cpv( 40,  0), 0.0f, stiff, damp));
114 
115     cpSpaceAddConstraint(space, new_spring( body1,  body5, cpv( 40,-40), cpv(-40, 40), 0.0f, stiff, damp));
116     cpSpaceAddConstraint(space, new_spring( body1,  body6, cpv( 40,-40), cpv( 40, 40), 0.0f, stiff, damp));
117     cpSpaceAddConstraint(space, new_spring( body2,  body3, cpv( 40, 40), cpv(-40, 80), 0.0f, stiff, damp));
118     cpSpaceAddConstraint(space, new_spring( body3,  body4, cpv(-40, 80), cpv(-40,  0), 0.0f, stiff, damp));
119     cpSpaceAddConstraint(space, new_spring( body3,  body4, cpv( 40,-80), cpv(-40,  0), 0.0f, stiff, damp));
120     cpSpaceAddConstraint(space, new_spring( body3,  body7, cpv( 40,-80), cpv( 40,  0), 0.0f, stiff, damp));
121     cpSpaceAddConstraint(space, new_spring( body3,  body7, cpv(-40, 80), cpv(-40,  0), 0.0f, stiff, damp));
122     cpSpaceAddConstraint(space, new_spring( body3,  body8, cpv( 40,-80), cpv( 40,  0), 0.0f, stiff, damp));
123     cpSpaceAddConstraint(space, new_spring( body3,  body9, cpv( 40,-80), cpv(-40,-40), 0.0f, stiff, damp));
124     cpSpaceAddConstraint(space, new_spring( body4,  body9, cpv( 40,  0), cpv( 40, 40), 0.0f, stiff, damp));
125     cpSpaceAddConstraint(space, new_spring( body5, body11, cpv(-40, 40), cpv(-40, 40), 0.0f, stiff, damp));
126     cpSpaceAddConstraint(space, new_spring( body5, body11, cpv( 40,-40), cpv( 40,-40), 0.0f, stiff, damp));
127     cpSpaceAddConstraint(space, new_spring( body7,  body8, cpv( 40,  0), cpv(-40,  0), 0.0f, stiff, damp));
128     cpSpaceAddConstraint(space, new_spring( body8, body12, cpv(-40,  0), cpv( 40,  0), 0.0f, stiff, damp));
129     cpSpaceAddConstraint(space, new_spring( body8, body13, cpv(-40,  0), cpv(-40,  0), 0.0f, stiff, damp));
130     cpSpaceAddConstraint(space, new_spring( body8, body13, cpv( 40,  0), cpv( 40,  0), 0.0f, stiff, damp));
131     cpSpaceAddConstraint(space, new_spring( body8, body14, cpv( 40,  0), cpv(-40,  0), 0.0f, stiff, damp));
132     cpSpaceAddConstraint(space, new_spring(body10, body14, cpv( 40,-40), cpv(-40,  0), 0.0f, stiff, damp));
133     cpSpaceAddConstraint(space, new_spring(body10, body14, cpv( 40,-40), cpv(-40,  0), 0.0f, stiff, damp));
134 
135     return space;
136 }
137 
138 static void
139 destroy()
140 {
141     ChipmunkDemoFreeSpaceChildren(space);
142     cpSpaceFree(space);
143 }
144 
145 chipmunkDemo Springies = {
146     "Springies",
147     null,
148     &init,
149     &update,
150     &destroy,
151 };