blob: 8fb982ee8680e47740a5e6596b568c593c68da2f [file] [log] [blame]
Guido van Rossum453bd401992-03-30 13:18:37 +00001#!/ufs/guido/bin/sgi/python
2# Simulate the artwork in the hall.
3# Jack Jansen, Feb 91.
4#
5# Please please please don't try to read this code.
6# It is the first GL program I ever wrote, and used to do
7# very different things before it's current function:-)
8from gl import *
9from GL import *
10from math import *
11from DEVICE import *
12import sys
13import __main__
14main_dict = __main__.__dict__
15
16SPOTDIRECTION = 103
17SPOTLIGHT = 104
18
19#
20# Make a cylinder paralel with the Z axis with center (X,Y,0)
21# and radius 1
22def mkcyl(nslice, nparts, docircle):
23 cyl = []
24 step = 2.0 / float(nslice)
25 z = -1.0
26 for i in range(nslice):
27 cyl.append(mkslice(z, z+step, nparts, docircle))
28 z = z + step
29 return drawcylinder(cyl)
30#
31# Make one part of a cylinder
32#
33def mkslice(z1, z2, nparts, docircle):
34 if docircle:
35 w1 = z1
36 w2 = z2
37 w1 = sqrt(1.0-w1*w1)
38 w2 = sqrt(1.0-w2*w2)
39 normalz = 1.0
40 else:
41 w1 = 1.0
42 w2 = 1.0
43 normalz = 0.0
44 slice = []
45 step = (2.0*pi)/float(nparts)
46 angle = 0.0
47 for i in range(nparts+1):
48 vx = cos(angle)
49 vy = sin(angle)
50 slice.append( ((vx*w1,vy*w1,z1), (vx*w1, vy*w1, z1*normalz)) )
51 slice.append( ((vx*w2,vy*w2,z2), (vx*w2, vy*w2, z2*normalz)) )
52 angle = angle + step
53 return slice
54#
55# Drawcylinder : draw the cylinder
56#
57class struct(): pass
58curobj = struct()
59curobj.curobj = 1
60def drawcylinder(cyl):
61 obj = curobj.curobj
62 curobj.curobj = curobj.curobj+1
63 makeobj(obj)
64 for slice in cyl:
65 bgntmesh()
66 vnarray(slice)
67 endtmesh()
68 closeobj()
69 return obj
70#
71def drawnormals(cyl):
72 for slice in cyl:
73 for triang in slice:
74 bgnline()
75 v3f(triang[0])
76 v3f(triang[0][0] + triang[1][0], triang[0][1] + triang[1][1], triang[0][2] + triang[1][2])
77 endline()
78def drawfloors():
79 obj = curobj.curobj
80 curobj.curobj = curobj.curobj+1
81 makeobj(obj)
82 bgnpolygon()
83 v3i(4,6,-6)
84 v3i(-6,6,-6)
85 v3i(-6,-6,-6)
86 v3i(4,-6,-6)
87 endpolygon()
88 for floor in range(3):
89 pos = -1 + 5*floor
90 bgnpolygon()
91 v3i(4,4,pos)
92 v3i(-6,4,pos)
93 v3i(-6,6,pos)
94 v3i(4,6,pos)
95 endpolygon()
96 bgnpolygon()
97 v3i(-4,4,pos)
98 v3i(-4,-4,pos)
99 v3i(-6,-4,pos)
100 v3i(-6,4,pos)
101 endpolygon()
102 bgnpolygon()
103 v3i(-6,-4,pos)
104 v3i(-6,-6,pos)
105 v3i(4,-6,pos)
106 v3i(4,-4,pos)
107 endpolygon()
108 closeobj()
109 return obj
110def drawdoors():
111 obj = curobj.curobj
112 curobj.curobj = curobj.curobj+1
113 makeobj(obj)
114 for floor in range(3):
115 pos = -1+5*floor
116 bgnpolygon()
117 v3i(-2,6,pos)
118 v3i(-2,6,pos+3)
119 v3i(0,6,pos+3)
120 v3i(0,6,pos)
121 endpolygon()
122 closeobj()
123 return obj
124def drawrailing():
125 obj = curobj.curobj
126 curobj.curobj = curobj.curobj+1
127 makeobj(obj)
128 for floor in range(3):
129 pos = -1 + 5*floor
130 bgnpolygon()
131 v3i(4,4,pos)
132 v3i(4,4,pos-1)
133 v3i(-4,4,pos-1)
134 v3i(-4,4,pos)
135 endpolygon()
136 bgnpolygon()
137 v3i(-4,4,pos)
138 v3i(-4,4,pos-1)
139 v3i(-4,-4,pos-1)
140 v3i(-4,-4,pos)
141 endpolygon()
142 bgnpolygon()
143 v3i(-4,-4,pos)
144 v3i(-4,-4,pos-1)
145 v3i(4,-4,pos-1)
146 v3i(4,-4,pos)
147 endpolygon()
148 closeobj()
149 return obj
150def drawwalls():
151 obj = curobj.curobj
152 curobj.curobj = curobj.curobj+1
153 makeobj(obj)
154 bgnpolygon()
155 v3i(4,6,-6)
156 v3i(4,6,18)
157 v3i(-6,6,18)
158 v3i(-6,6,-6)
159 endpolygon()
160 bgnpolygon()
161 v3i(-6,6,-6)
162 v3i(-6,6,18)
163 v3i(-6,-6,18)
164 v3i(-6,-6,-6)
165 endpolygon()
166 bgnpolygon()
167 v3i(-6,-6,-6)
168 v3i(-6,-6,18)
169 v3i(4,-6,18)
170 v3i(4,-6,-6)
171 endpolygon()
172 bgnpolygon()
173 v3i(4,-6,-6)
174 v3i(4,-6,18)
175 v3i(4,4,18)
176 v3i(4,4,-6)
177 endpolygon()
178 closeobj()
179 return obj
180def axis():
181 bgnline()
182 cpack(0xff0000)
183 v3i(-1,0,0)
184 v3i(1,0,0)
185 v3f(1.0, 0.1, 0.1)
186 endline()
187 bgnline()
188 cpack(0xff00)
189 v3i(0,-1,0)
190 v3i(0,1,0)
191 v3f(0.1, 1.0, 0.1)
192 endline()
193 bgnline()
194 cpack(0xff)
195 v3i(0,0,-1)
196 v3i(0,0,1)
197 v3f(0.1,0.1,1.0)
198 endline()
199#
200silver = [ DIFFUSE, 0.3, 0.3, 0.3, SPECULAR, 0.9, 0.9, 0.95, \
201 SHININESS, 40.0, LMNULL]
202floormat = [ AMBIENT, 0.5, 0.25, 0.15, DIFFUSE, 0.5, 0.25, 0.15, SPECULAR, 0.6, 0.3, 0.2, SHININESS, 20.0, LMNULL]
203wallmat = [ DIFFUSE, 0.4, 0.2, 0.1, AMBIENT, 0.4, 0.20, 0.10, SPECULAR, 0.0, 0.0, 0.0, SHININESS, 20.0, LMNULL]
204offwhite = [ DIFFUSE, 0.8, 0.8, 0.6, AMBIENT, 0.8, 0.8, 0.6, SPECULAR, 0.9, 0.9, 0.9, SHININESS, 30.0, LMNULL]
205doormat = [ DIFFUSE, 0.1, 0.2, 0.5, AMBIENT, 0.2, 0.4, 1.0, SPECULAR, 0.2, 0.4, 1.0, SHININESS, 60.0, LMNULL]
206
207toplight = [ LCOLOR, 1.0, 1.0, 0.5, \
208 POSITION, 0.0, 0.0, 11.0, 1.0, LMNULL]
209floor1light = [ LCOLOR, 1.0, 1.0, 1.0, POSITION, 3.9, -3.9, 0.0, 1.0, \
210 SPOTDIRECTION, 1.0, 1.0, 0.0, SPOTLIGHT, 10.0, 90.0, LMNULL]
211
212lmodel = [ AMBIENT, 0.92, 0.8, 0.5, LOCALVIEWER, 1.0, LMNULL]
213#
214def lighting():
215 INDIGO=1 # XXXX Seems indigo only has one light.
216 lmdef(DEFMATERIAL, 2, silver)
217 lmdef(DEFMATERIAL, 3, floormat)
218 lmdef(DEFMATERIAL, 4, wallmat)
219 lmdef(DEFMATERIAL, 5, offwhite)
220 lmdef(DEFMATERIAL, 6, doormat)
221 lmdef(DEFLIGHT, 1, toplight)
222 if not INDIGO:
223 lmdef(DEFLIGHT, 2, floor1light)
224 lmdef(DEFLMODEL, 1, lmodel)
225 lmbind(LIGHT0, 1)
226 if not INDIGO:
227 lmbind(LIGHT1, 2)
228 lmbind(LMODEL, 1)
229IdMat=[1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,0.0,1.0]
230#
231wrongrange='Wrong Range'
232def defun(axis):
233 done = 0
234 res = 0.0 # Hack around exec(...)
235 while not done:
236 print 'F'+axis+'(t) = ',
237 s = sys.stdin.readline(100)
238 print
239 try:
240 s = 'def f'+axis+'(t): return '+s
241 exec(s, main_dict)
242 exec('res = f'+axis+'(0.0)\n')
243 if res < -10.0 or res > 10.0:
244 raise wrongrange
245 exec('res = f'+axis+'(100.0)\n')
246 if res < -10.0 or res > 10.0:
247 raise wrongrange
248 done = 1
249 except RuntimeError:
250 print 'Sorry, there is a syntax error in your expression'
251 except TypeError:
252 print 'Please remember to use floating point numbers'
253 except wrongrange:
254 print 'Sorry, function values out of range (non-periodic function?)'
255def getfunctions():
256 print 'Welcome to the CWI art simulator. You can now enter X, Y and Z'
257 print 'coordinates as a function of t.'
258 print 'Alternatively, you can specify the name of a python module'
259 print 'defining functions fx(t), fy(t) and fz(t) on the command line'
260 print 'Normal trig functions are available. Please use floating point'
261 print 'values only (so 0.0 for 0). Comments to jack@cwi.nl'
262 defun('x')
263 defun('y')
264 defun('z')
265 print 'Ok, here you go. Use mouse+right button to move up/down,'
266 print 'mouse+middle to speed up/slow down time. type ESC to quit simulation'
267def main():
268 if len(sys.argv) > 1:
269 exec('from '+sys.argv[1]+' import *\n')
270 else:
271 getfunctions()
272 foreground()
273 prefposition(100,600,100,600)
274 void = winopen('cyl')
275 qdevice(ESCKEY)
276 qdevice(MOUSE1)
277 qdevice(MOUSE2)
278 qdevice(PKEY)
279 RGBmode()
280 doublebuffer()
281 gconfig()
282 zbuffer(1)
283 mmode(MVIEWING)
284 perspective(600, 1.0, 0.01, 20.0)
285 loadmatrix(IdMat)
286 vx = 0.0
287 vy = -3.9
288 vz = 0.0
289 lookat(0.0, -3.9, 0.0, 0.0, 0.0, 0.0, 0)
290 lighting()
291 t = -1.0
292 step = 0.2
293 bol = mkcyl(12,24, 1)
294 cable = mkcyl(1, 6, 0)
295 floors = drawfloors()
296 walls = drawwalls()
297 pillar = mkcyl(1,4,0)
298 railing = drawrailing()
299 doors = drawdoors()
300 shademodel(GOURAUD)
301 mousing = -1
302 pausing = 0
303 while 1:
304 #
305 # Check for some user input
306 #
307 if qtest():
308 dev, value = qread()
309 if dev == PKEY and value == 1:
310 pausing = 1
311 if dev == ESCKEY:
312 break
313 elif (dev==MOUSE1 or dev==MOUSE2) and value == 1:
314 if mousing > 0:
315 vx = 0.0
316 vy = -3.9
317 vz = 0.0
318 mousing = dev
319 oldx = getvaluator(MOUSEX)
320 oldy = getvaluator(MOUSEY)
321 elif (dev==MOUSE1 or dev==MOUSE2):
322 mousing = -1
323 if mousing >= 0:
324 newx = getvaluator(MOUSEX)
325 newy = getvaluator(MOUSEY)
326 if newy <> oldy and mousing==MOUSE1:
327 vz = vz + float(newy - oldy)/100.0
328 if vz < -5.99:
329 vz = -5.99
330 dist = sqrt(vx*vx + vy*vy + vz*vz)
331 perspective(600, 1.0, 0.01, dist+16.0)
332 loadmatrix(IdMat)
333 if vz < 0.0:
334 lookat(vx, vy, vz, 0.0, 0.0, 0.0, 1800)
335 else:
336 lookat(vx, vy, vz, 0.0, 0.0, 0.0, 0)
337 if newy <> oldy and mousing==MOUSE2:
338 step = step * exp(float(newy-oldy)/400.0)
339 if getbutton(CTRLKEY) == 0:
340 t = t + step
341 else:
342 t = t - step
343 if getbutton(LEFTSHIFTKEY) == 0:
344 shademodel(GOURAUD)
345 else:
346 shademodel(FLAT)
347 #
348 # Draw background and axis
349 czclear(0x802020,getgdesc(GD_ZMAX))
350 #axis()
351 #
352 # draw the floors
353 #
354 lmbind(MATERIAL, 3)
355 callobj(floors)
356 lmbind(MATERIAL, 4)
357 callobj(walls)
358 lmbind(MATERIAL, 5)
359 pushmatrix()
360 translate(-4.5,4.5,3.0)
361 scale(0.2,0.2,9.0)
362 rotate(450,'z')
363 callobj(pillar)
364 popmatrix()
365 callobj(railing)
366 lmbind(MATERIAL, 6)
367 pushmatrix()
368 translate(0.0, -0.01, 0.0)
369 callobj(doors)
370 popmatrix()
371 #
372 # Draw object
373 #
374 bolx = fx(t)
375 boly = fy(t)
376 bolz = fz(t)
377 err = ''
378 if bolx < -4.0 or bolx > 4.0:
379 err = 'X('+`bolx`+') out of range [-4,4]'
380 if boly < -4.0 or boly > 4.0:
381 err = 'Y('+`boly`+') out of range [-4,4]'
382 if bolz < -4.0 or bolz > 8.0:
383 err = 'Z('+`bolz`+') out of range [-4,8]'
384 if not err:
385 pushmatrix()
386 translate(bolx, boly, bolz)
387 scale(0.3, 0.3, 0.3)
388 lmbind(MATERIAL, 2)
389 blendfunction(BF_ONE, BF_ONE)
390 callobj(bol)
391 blendfunction(BF_ONE, BF_ZERO)
392 popmatrix()
393 #
394 # Draw the cables
395 #
396 bolz = bolz + 0.3
397 pushmatrix()
398 #linesmooth(SML_ON)
399 bgnline()
400 v3i(-4,-4,9)
401 v3f(bolx, boly, bolz)
402 endline()
403 bgnline()
404 v3i(-4,4,9)
405 v3f(bolx, boly, bolz)
406 endline()
407 bgnline()
408 v3i(4,-4,9)
409 v3f(bolx, boly, bolz)
410 endline()
411 bgnline()
412 v3i(4,4,9)
413 v3f(bolx, boly, bolz)
414 endline()
415 popmatrix()
416 if mousing == MOUSE2 or err:
417 cpack(0xff0000)
418 cmov(0.0, 0.0, 0.4)
419 charstr('t='+`t`)
420 if mousing == MOUSE2:
421 cpack(0xff0000)
422 cmov(0.0, 0.0, 0.2)
423 charstr('delta-t='+`step`)
424 if err:
425 cpack(0xff00)
426 cmov(0.0, 0.0, 0.2)
427 charstr(err)
428 pausing = 1
429 if pausing:
430 cpack(0xff00)
431 cmov(0.0, 0.0, 0.0)
432 charstr('Pausing, type P to continue')
433 swapbuffers()
434 if pausing:
435 while 1:
436 dv=qread()
437 if dv==(PKEY,1):
438 break
439 if dv==(ESCKEY,1):
440 sys.exit(0)
441 pausing = 0
442#
443try:
444 main()
445except KeyboardInterrupt:
446 sys.exit(1)