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