Removed all code that uses OpenGL from Image.
[io/quag.git] / addons / ODE / samples / tutorial3.io
blobdcab70f728263c6ebba98ac1519ccd959fb1b483
1 #!/usr/bin/env io
3 # Port of http://pyode.sourceforge.net/tutorials/tutorial3.html
5 appendProto(OpenGL)
7 scalp := method(vec, scal,
8 vec *= scal
11 length := method(vec,
12 vec rootMeanSquare
15 drawBody := method(body,
16 pos := body position
17 r := body rotation
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)
19 glPushMatrix()
20 glMultMatrixd(rot)
21 if(body shape == "box",
22 body size glScale
23 glColor4d(0,0,1, 1)
24 glutSolidCube(1)
25 glEnable(GL_BLEND)
27 glDisable(GL_LIGHTING)
28 glColor4d(.4,.4,.4, 1)
29 glutWireCube(1.002)
30 glEnable(GL_LIGHTING)
32 glPopMatrix
35 geoms := list # work around for bug which means geoms were gc'ed too early
36 createBox := method(world, space, density, lx, ly, lz,
37 # Create body
38 body := world Body clone
39 body setMass(ODEMass clone setBoxDensity(density, lx, ly, lz))
41 # Set parameters for drawing the body
42 body shape := "box"
43 body size := vector(lx, ly, lz)
45 # Create a box geom for collision detection
46 geom := space box(lx, ly, lz) setBody(body)
47 geoms append(geom)
49 body
52 dropObject := method(
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
57 ct := theta cos
58 st := theta sin
59 body setRotation(ct, 0, -st, 0, 1, 0, st, 0, ct)
61 bodies append(body)
62 counter = 0
63 objCount = objCount + 1
66 origin := vector(0,0,0)
68 explosion := method(
69 bodies foreach(b,
70 l := b position
71 l setY(1)
72 d := l distanceTo(origin)
73 force := 300000 / (1 + d)
74 l normalize *= force
75 b addForce(l x, l y, l z)
79 bump := method(
80 bodies foreach(b,
81 b addForce(0,20000,0)
85 implode := method(
86 bodies foreach(b,
87 l := b position clone
88 d := l distanceTo(origin)
89 force := -45000 * d sqrt
90 l normalize *= force
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)
108 world setErp(0.8)
109 world setCfm(1E-5)
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
118 bodies := list
120 # A joint group for the contact joints that are generated whenever
121 # two bodies collide
122 contactgroup := world JointGroup clone
124 # Some variables used inside the simulation loop
126 # Glut events object
127 Screen := Object clone do(
128 newSlot("width", 640)
129 newSlot("height", 480)
131 newSlot("state", 0)
132 newSlot("counter", 0)
133 newSlot("objCount", 0)
135 reshape := method( w, h,
136 setWidth(w) setHeight(h)
137 glMatrixMode(GL_PROJECTION)
138 glLoadIdentity
139 gluPerspective(45, w / h, 1.0, 20.0)
140 glMatrixMode(GL_MODELVIEW)
141 glViewport(0, 0, w, h)
144 display := method(
145 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
146 glLoadIdentity
147 gluLookAt (2.4, 3.6, 4.8, 0.5, 0.5, 0, 0, 1, 0)
148 glPushMatrix
149 glScaled(1,0,1)
150 //glutSolidCube(10)
151 glDisable(GL_LIGHTING)
152 glLineWidth(1)
153 glColor4d(1,1,1,.4)
154 for(x, -10, 10,
155 for(z, -10, 10,
156 glPushMatrix
157 glTranslated(x,0,z)
158 glutWireCube(1)
159 glPopMatrix
161 glEnable(GL_LIGHTING)
162 glPopMatrix
163 bodies foreach(b, drawBody(b))
164 glFlush
165 glutSwapBuffers
168 timer := method(arg,
169 counter = counter + 1
171 if(state == 0,
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)
180 glutPostRedisplay
182 n := 2
184 # Simulate
185 n repeat(
186 # Detect collisions and create contact joints
187 space collide(Lobby, message(nearCallback))
189 # Simulation step
190 world step(arg / 1200 / n)
192 # Remove all contact joints
193 contactgroup empty
196 glutTimerFunc( arg, arg )
200 glutInitDisplayMode( GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH)
201 glutInitWindowSize( Screen width, Screen height )
202 glutInit
203 glutCreateWindow("ODE Example")
204 glutEventTarget( Screen )
205 glutReshapeFunc
206 glutDisplayFunc
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)
220 glEnable(GL_BLEND)
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))
227 glEnable(GL_LIGHT0)
229 # View transformation
230 Coroutine setStackSize(1024*1024)
231 e := try(
232 glutMainLoop
234 if(e, e showStack)