3 # Port of http
://pyode
.sourceforge
.net
/tutorials
/tutorial3
.html
7 scalp
:= method(vec
, scal
,
15 drawBody
:= method(body
,
18 rot
:= list(r
at(0), r
at(3), r
at(6), 0, r
at(1), r
at(4), r
at(7), 0, r
at(2), r
at(5), r
at(8), 0, pos x
, pos y
, pos z
, 1)
21 if(body shape
== "box",
27 glDisable(GL_LIGHTING
)
28 glColor4d(.4,.4,.4, 1)
35 geoms
:= list # work around
for bug which means geoms were gc
'ed too early
36 createBox := method(world, space, density, lx, ly, lz,
38 body := world Body clone
39 body setMass(ODEMass clone setBoxDensity(density, lx, ly, lz))
41 # Set parameters for drawing the body
43 body size := vector(lx, ly, lz)
45 # Create a box geom for collision detection
46 geom := space box(lx, ly, lz) setBody(body)
53 body := createBox(world, space, 2000, 9/9, 1/9, 4/9)
54 body setPosition(Random gaussian(0, 0.5), 3.0, Random gaussian(0, 0.5))
56 theta := Random value * 2 * Number constants pi * 2
59 body setRotation(ct, 0, -st, 0, 1, 0, st, 0, ct)
63 objCount = objCount + 1
66 origin := vector(0,0,0)
72 d := l distanceTo(origin)
73 force := 300000 / (1 + d)
75 b addForce(l x, l y, l z)
88 d := l distanceTo(origin)
89 force := -45000 * d sqrt
91 b addForce(l x, l y, l z)
95 nearCallback := method(geom1, geom2,
96 contacts := geom1 collide(geom2, 8) # find a max of 8 contacts
97 contacts foreach(contact,
98 contact setBounce(0.2) setMu(5000)
99 contactgroup createContact(contact) attach(geom1 body, geom2 body)
104 ######################################################################
106 # Create a world object
107 world := ODEWorld clone setGravity(0, -9.81, 0)
111 # Create a space object
112 space := ODESimpleSpace clone
114 # Create a plane geom which prevent the objects from falling forever
115 floor := space plane(0, 1, 0, 0)
117 # A list with ODE bodies
120 # A joint group for the contact joints that are generated whenever
122 contactgroup := world JointGroup clone
124 # Some variables used inside the simulation loop
127 Screen := Object clone do(
128 newSlot("width", 640)
129 newSlot("height", 480)
132 newSlot("counter", 0)
133 newSlot("objCount", 0)
135 reshape := method( w, h,
136 setWidth(w) setHeight(h)
137 glMatrixMode(GL_PROJECTION)
139 gluPerspective(45, w / h, 1.0, 20.0)
140 glMatrixMode(GL_MODELVIEW)
141 glViewport(0, 0, w, h)
145 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
147 gluLookAt (2.4, 3.6, 4.8, 0.5, 0.5, 0, 0, 1, 0)
151 glDisable(GL_LIGHTING)
161 glEnable(GL_LIGHTING)
163 bodies foreach(b, drawBody(b))
169 counter = counter + 1
172 if(counter == 50, dropObject)
173 if(objCount == 20, state = 1; counter = 0)
175 if(counter == 100, explosion)
176 if(counter > 400, if(counter % 20 == 0, bump; implode))
177 if(counter == 600, counter = 0)
186 # Detect collisions and create contact joints
187 space collide(Lobby, message(nearCallback))
190 world step(arg / 1200 / n)
192 # Remove all contact joints
196 glutTimerFunc( arg, arg )
200 glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)
201 glutInitWindowSize( Screen width, Screen height )
203 glutCreateWindow("ODE Example")
204 glutEventTarget( Screen )
207 glutTimerFunc( 0, 10 )
209 glClearColor(1,1,1, 1 )
210 glClearColor(0,0,0, 1 )
211 glEnable( GL_DEPTH_TEST )
212 glEnable( GL_LIGHTING )
213 glEnable( GL_LIGHT0 )
214 glEnable(GL_DEPTH_TEST)
215 glEnable(GL_NORMALIZE)
216 glShadeModel(GL_SMOOTH)
217 glDisable(GL_CULL_FACE)
219 glEnable(GL_LINE_SMOOTH)
221 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
222 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST)
224 glLightfv(GL_LIGHT0,GL_POSITION, list(0,0,1,0))
225 glLightfv(GL_LIGHT0,GL_DIFFUSE, list(1,1,1,1))
226 glLightfv(GL_LIGHT0,GL_SPECULAR, list(1,1,1,1))
229 # View transformation
230 Coroutine setStackSize(1024*1024)