comparison trunk/tests/ChipmunkDemos/samples/Planet.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.Planet;
5
6 import chipmunkd.chipmunk;
7
8 import samples.ChipmunkDemo;
9
10 static cpSpace *space;
11 static cpBody *planetBody;
12
13 static cpFloat gravityStrength = 5.0e6f;
14
15 static void
16 update(int ticks)
17 {
18 int steps = 1;
19 cpFloat dt = 1.0f/60.0f/cast(cpFloat)steps;
20
21 for(int i=0; i<steps; i++){
22 cpSpaceStep(space, dt);
23
24 // Update the static body spin so that it looks like it's rotating.
25 cpBodyUpdatePosition(planetBody, dt);
26 }
27 }
28
29 static void
30 planetGravityVelocityFunc(cpBody *_body, cpVect gravity, cpFloat damping, cpFloat dt)
31 {
32 // Gravitational acceleration is proportional to the inverse square of
33 // distance, and directed toward the origin. The central planet is assumed
34 // to be massive enough that it affects the satellites but not vice versa.
35 cpVect p = _body.p;
36 cpFloat sqdist = cpvlengthsq(p);
37 cpVect g = cpvmult(p, -gravityStrength / (sqdist * cpfsqrt(sqdist)));
38
39 cpBodyUpdateVelocity(_body, g, damping, dt);
40 }
41
42 static cpVect
43 rand_pos(cpFloat radius)
44 {
45 cpVect v;
46 do {
47 v = cpv(frand()*(640 - 2*radius) - (320 - radius), frand()*(480 - 2*radius) - (240 - radius));
48 } while(cpvlength(v) < 85.0f);
49
50 return v;
51 }
52
53 static void
54 add_box()
55 {
56 const cpFloat size = 10.0f;
57 const cpFloat mass = 1.0f;
58
59 cpVect verts[] = [
60 cpv(-size,-size),
61 cpv(-size, size),
62 cpv( size, size),
63 cpv( size,-size),
64 ];
65
66 cpFloat radius = cpvlength(cpv(size, size));
67
68 cpBody *_body = cpSpaceAddBody(space, cpBodyNew(mass, cpMomentForPoly(mass, 4, verts.ptr, cpvzero)));
69 _body.velocity_func = &planetGravityVelocityFunc;
70 _body.p = rand_pos(radius);
71
72 // Set the box's velocity to put it into a circular orbit from its
73 // starting position.
74 cpFloat r = cpvlength(_body.p);
75 cpFloat v = cpfsqrt(gravityStrength / r) / r;
76 _body.v = cpvmult(cpvperp(_body.p), v);
77
78 // Set the box's angular velocity to match its orbital period and
79 // align its initial angle with its position.
80 _body.w = v;
81 cpBodySetAngle(_body, cpfatan2(_body.p.y, _body.p.x));
82
83 cpShape *shape = cpSpaceAddShape(space, cpPolyShapeNew(_body, 4, verts.ptr, cpvzero));
84 shape.e = 0.0f; shape.u = 0.7f;
85 }
86
87 static cpSpace *
88 init()
89 {
90 planetBody = cpBodyNew(INFINITY, INFINITY);
91 planetBody.w = 0.2f;
92
93 cpResetShapeIdCounter();
94
95 space = cpSpaceNew();
96 cpSpaceResizeActiveHash(space, 30.0f, 10000);
97 space.iterations = 20;
98
99 for(int i=0; i<30; i++)
100 add_box();
101
102 cpShape *shape = cpSpaceAddShape(space, cpCircleShapeNew(planetBody, 70.0f, cpvzero));
103 shape.e = 1.0f; shape.u = 1.0f;
104 shape.layers = NOT_GRABABLE_MASK;
105
106 return space;
107 }
108
109 static void
110 destroy()
111 {
112 cpBodyFree(planetBody);
113 cpSpaceFreeChildren(space);
114 cpSpaceFree(space);
115 }
116
117 chipmunkDemo Planet = {
118 "Planet",
119 null,
120 &init,
121 &update,
122 &destroy,
123 };