blob: f37f979ef8be64e67dc86e86813925304ffa2ae1 [file] [log] [blame]
Guido van Rossumf06ee5f1996-11-27 19:52:01 +00001#! /usr/bin/env python
Guido van Rossum453bd401992-03-30 13:18:37 +00002# Simulate the artwork in the hall.
3# Jack Jansen, Feb 91.
Guido van Rossum24263311992-12-14 13:01:06 +00004
Guido van Rossum453bd401992-03-30 13:18:37 +00005from gl import *
6from GL import *
7from math import *
8from DEVICE import *
9import sys
10import __main__
11main_dict = __main__.__dict__
12
13SPOTDIRECTION = 103
14SPOTLIGHT = 104
15
16#
17# Make a cylinder paralel with the Z axis with center (X,Y,0)
18# and radius 1
19def mkcyl(nslice, nparts, docircle):
Guido van Rossum4117e541998-09-14 16:44:15 +000020 cyl = []
21 step = 2.0 / float(nslice)
22 z = -1.0
23 for i in range(nslice):
24 cyl.append(mkslice(z, z+step, nparts, docircle))
25 z = z + step
26 return drawcylinder(cyl)
Guido van Rossum453bd401992-03-30 13:18:37 +000027#
28# Make one part of a cylinder
29#
30def mkslice(z1, z2, nparts, docircle):
Guido van Rossum4117e541998-09-14 16:44:15 +000031 if docircle:
32 w1 = z1
33 w2 = z2
34 w1 = sqrt(1.0-w1*w1)
35 w2 = sqrt(1.0-w2*w2)
36 normalz = 1.0
37 else:
38 w1 = 1.0
39 w2 = 1.0
40 normalz = 0.0
41 slice = []
42 step = (2.0*pi)/float(nparts)
43 angle = 0.0
44 for i in range(nparts+1):
45 vx = cos(angle)
46 vy = sin(angle)
47 slice.append( ((vx*w1,vy*w1,z1), (vx*w1, vy*w1, z1*normalz)) )
48 slice.append( ((vx*w2,vy*w2,z2), (vx*w2, vy*w2, z2*normalz)) )
49 angle = angle + step
50 return slice
Guido van Rossum453bd401992-03-30 13:18:37 +000051#
52# Drawcylinder : draw the cylinder
53#
Guido van Rossum96b608c1993-12-17 14:57:24 +000054class struct: pass
Guido van Rossum453bd401992-03-30 13:18:37 +000055curobj = struct()
56curobj.curobj = 1
57def drawcylinder(cyl):
Guido van Rossum4117e541998-09-14 16:44:15 +000058 obj = curobj.curobj
59 curobj.curobj = curobj.curobj+1
60 makeobj(obj)
61 for slice in cyl:
62 bgntmesh()
63 vnarray(slice)
64 endtmesh()
65 closeobj()
66 return obj
Guido van Rossum453bd401992-03-30 13:18:37 +000067#
68def drawnormals(cyl):
Guido van Rossum4117e541998-09-14 16:44:15 +000069 for slice in cyl:
70 for triang in slice:
71 bgnline()
72 v3f(triang[0])
73 v3f(triang[0][0] + triang[1][0], triang[0][1] + triang[1][1], triang[0][2] + triang[1][2])
74 endline()
Guido van Rossum453bd401992-03-30 13:18:37 +000075def drawfloors():
Guido van Rossum4117e541998-09-14 16:44:15 +000076 obj = curobj.curobj
77 curobj.curobj = curobj.curobj+1
78 makeobj(obj)
79 bgnpolygon()
80 v3i(4,6,-6)
81 v3i(-6,6,-6)
82 v3i(-6,-6,-6)
83 v3i(4,-6,-6)
84 endpolygon()
85 for floor in range(3):
86 pos = -1 + 5*floor
87 bgnpolygon()
88 v3i(4,4,pos)
89 v3i(-6,4,pos)
90 v3i(-6,6,pos)
91 v3i(4,6,pos)
92 endpolygon()
93 bgnpolygon()
94 v3i(-4,4,pos)
95 v3i(-4,-4,pos)
96 v3i(-6,-4,pos)
97 v3i(-6,4,pos)
98 endpolygon()
99 bgnpolygon()
100 v3i(-6,-4,pos)
101 v3i(-6,-6,pos)
102 v3i(4,-6,pos)
103 v3i(4,-4,pos)
104 endpolygon()
105 closeobj()
106 return obj
Guido van Rossum453bd401992-03-30 13:18:37 +0000107def drawdoors():
Guido van Rossum4117e541998-09-14 16:44:15 +0000108 obj = curobj.curobj
109 curobj.curobj = curobj.curobj+1
110 makeobj(obj)
111 for floor in range(3):
112 pos = -1+5*floor
113 bgnpolygon()
114 v3i(-2,6,pos)
115 v3i(-2,6,pos+3)
116 v3i(0,6,pos+3)
117 v3i(0,6,pos)
118 endpolygon()
119 closeobj()
120 return obj
Guido van Rossum453bd401992-03-30 13:18:37 +0000121def drawrailing():
Guido van Rossum4117e541998-09-14 16:44:15 +0000122 obj = curobj.curobj
123 curobj.curobj = curobj.curobj+1
124 makeobj(obj)
125 for floor in range(3):
126 pos = -1 + 5*floor
127 bgnpolygon()
128 v3i(4,4,pos)
129 v3i(4,4,pos-1)
130 v3i(-4,4,pos-1)
131 v3i(-4,4,pos)
132 endpolygon()
133 bgnpolygon()
134 v3i(-4,4,pos)
135 v3i(-4,4,pos-1)
136 v3i(-4,-4,pos-1)
137 v3i(-4,-4,pos)
138 endpolygon()
139 bgnpolygon()
140 v3i(-4,-4,pos)
141 v3i(-4,-4,pos-1)
142 v3i(4,-4,pos-1)
143 v3i(4,-4,pos)
144 endpolygon()
145 closeobj()
146 return obj
Guido van Rossum453bd401992-03-30 13:18:37 +0000147def drawwalls():
Guido van Rossum4117e541998-09-14 16:44:15 +0000148 obj = curobj.curobj
149 curobj.curobj = curobj.curobj+1
150 makeobj(obj)
151 bgnpolygon()
152 v3i(4,6,-6)
153 v3i(4,6,18)
154 v3i(-6,6,18)
155 v3i(-6,6,-6)
156 endpolygon()
157 bgnpolygon()
158 v3i(-6,6,-6)
159 v3i(-6,6,18)
160 v3i(-6,-6,18)
161 v3i(-6,-6,-6)
162 endpolygon()
163 bgnpolygon()
164 v3i(-6,-6,-6)
165 v3i(-6,-6,18)
166 v3i(4,-6,18)
167 v3i(4,-6,-6)
168 endpolygon()
169 bgnpolygon()
170 v3i(4,-6,-6)
171 v3i(4,-6,18)
172 v3i(4,4,18)
173 v3i(4,4,-6)
174 endpolygon()
175 closeobj()
176 return obj
Guido van Rossum453bd401992-03-30 13:18:37 +0000177def axis():
Guido van Rossum4117e541998-09-14 16:44:15 +0000178 bgnline()
179 cpack(0xff0000)
180 v3i(-1,0,0)
181 v3i(1,0,0)
182 v3f(1.0, 0.1, 0.1)
183 endline()
184 bgnline()
185 cpack(0xff00)
186 v3i(0,-1,0)
187 v3i(0,1,0)
188 v3f(0.1, 1.0, 0.1)
189 endline()
190 bgnline()
191 cpack(0xff)
192 v3i(0,0,-1)
193 v3i(0,0,1)
194 v3f(0.1,0.1,1.0)
195 endline()
Guido van Rossum453bd401992-03-30 13:18:37 +0000196#
Guido van Rossum24263311992-12-14 13:01:06 +0000197green_velvet = [ DIFFUSE, 0.05, 0.4, 0.05, LMNULL]
Guido van Rossum453bd401992-03-30 13:18:37 +0000198silver = [ DIFFUSE, 0.3, 0.3, 0.3, SPECULAR, 0.9, 0.9, 0.95, \
Guido van Rossum4117e541998-09-14 16:44:15 +0000199 SHININESS, 40.0, LMNULL]
Guido van Rossum453bd401992-03-30 13:18:37 +0000200floormat = [ 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]
201wallmat = [ 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]
202offwhite = [ 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]
203doormat = [ 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]
204
205toplight = [ LCOLOR, 1.0, 1.0, 0.5, \
Guido van Rossum4117e541998-09-14 16:44:15 +0000206 POSITION, 0.0, 0.0, 11.0, 1.0, LMNULL]
Guido van Rossum453bd401992-03-30 13:18:37 +0000207floor1light = [ LCOLOR, 1.0, 1.0, 1.0, POSITION, 3.9, -3.9, 0.0, 1.0, \
Guido van Rossum4117e541998-09-14 16:44:15 +0000208 SPOTDIRECTION, 1.0, 1.0, 0.0, SPOTLIGHT, 10.0, 90.0, LMNULL]
Guido van Rossum453bd401992-03-30 13:18:37 +0000209
210lmodel = [ AMBIENT, 0.92, 0.8, 0.5, LOCALVIEWER, 1.0, LMNULL]
211#
212def lighting():
Guido van Rossum4117e541998-09-14 16:44:15 +0000213 lmdef(DEFMATERIAL, 1, green_velvet)
214 lmdef(DEFMATERIAL, 2, silver)
215 lmdef(DEFMATERIAL, 3, floormat)
216 lmdef(DEFMATERIAL, 4, wallmat)
217 lmdef(DEFMATERIAL, 5, offwhite)
218 lmdef(DEFMATERIAL, 6, doormat)
219 lmdef(DEFLIGHT, 1, toplight)
220 lmdef(DEFLIGHT, 2, floor1light)
221 lmdef(DEFLMODEL, 1, lmodel)
222 lmbind(MATERIAL, 1)
223 lmbind(LIGHT0, 1)
224 lmbind(LIGHT1, 2)
225 lmbind(LMODEL, 1)
Guido van Rossum453bd401992-03-30 13:18:37 +0000226IdMat=[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]
227#
Guido van Rossum453bd401992-03-30 13:18:37 +0000228def defun(axis):
Guido van Rossum4117e541998-09-14 16:44:15 +0000229 done = 0
230 while not done:
231 print 'F'+axis+'(t) = ',
232 s = sys.stdin.readline(100)
233 print
234 try:
235 s = 'def f'+axis+'(t): return '+s
236 exec(s, main_dict)
237 done = 1
238 except RuntimeError:
239 print 'Sorry, there is a syntax error in your expression'
Guido van Rossum453bd401992-03-30 13:18:37 +0000240def getfunctions():
Guido van Rossum4117e541998-09-14 16:44:15 +0000241 print 'Welcome to the CWI art simulator. You can now enter X, Y and Z'
242 print 'coordinates as a function of t.'
243 print 'Normal trig functions are available. Please use floating point'
244 print 'values only (so 0.0 for 0). Comments to jack@cwi.nl'
245 defun('x')
246 defun('y')
247 defun('z')
248 print 'Ok, here you go. Use mouse+right button to move up/down,'
249 print 'mouse+middle to speed up/slow down time. type ESC to quit simulation'
Guido van Rossum453bd401992-03-30 13:18:37 +0000250def main():
Guido van Rossum4117e541998-09-14 16:44:15 +0000251 getfunctions()
252 foreground()
253 prefposition(100,600,100,600)
254 void = winopen('cyl')
255 qdevice(ESCKEY)
256 qdevice(MOUSE1)
257 qdevice(MOUSE2)
258 qdevice(PKEY)
259 RGBmode()
260 doublebuffer()
261 gconfig()
262 zbuffer(1)
263 mmode(MVIEWING)
264 perspective(400, 1.0, 1.0, 20.0)
265 loadmatrix(IdMat)
266 vx = 0.0
267 vy = -6.0
268 vz = 0.0
269 lookat(0.0, -6.0, 0.0, 0.0, 0.0, 0.0, 0)
270 lighting()
271 t = -1.0
272 step = 1.0
273 bol = mkcyl(12,24, 1)
274 cable = mkcyl(1, 6, 0)
275 floors = drawfloors()
276 walls = drawwalls()
277 pillar = mkcyl(1,4,0)
278 railing = drawrailing()
279 doors = drawdoors()
280 shademodel(GOURAUD)
281 mousing = -1
282 pausing = 0
283 while 1:
284 #
285 # Check for some user input
286 #
287 if qtest():
288 dev, value = qread()
289 if dev == PKEY and value == 1:
290 pausing = 1
291 if dev == ESCKEY:
292 break
293 elif (dev==MOUSE1 or dev==MOUSE2) and value == 1:
294 if mousing > 0:
295 vx = 0.0
296 vy = -6.0
297 vz = 0.0
298 mousing = dev
299 oldx = getvaluator(MOUSEX)
300 oldy = getvaluator(MOUSEY)
301 elif (dev==MOUSE1 or dev==MOUSE2):
302 mousing = -1
303 if mousing >= 0:
304 newx = getvaluator(MOUSEX)
305 newy = getvaluator(MOUSEY)
306 if newy <> oldy and mousing==MOUSE1:
307 vz = vz + float(newy - oldy)/100.0
308 dist = sqrt(vx*vx + vy*vy + vz*vz)
309 perspective(400, 1.0, 1.0, dist+16.0)
310 loadmatrix(IdMat)
311 if vz < 0.0:
312 lookat(vx, vy, vz, 0.0, 0.0, 0.0, 1800)
313 else:
314 lookat(vx, vy, vz, 0.0, 0.0, 0.0, 0)
315 if newy <> oldy and mousing==MOUSE2:
316 step = step * exp(float(newy-oldy)/400.0)
317 if getbutton(CTRLKEY) == 0:
318 t = t + step
319 else:
320 t = t - step
321 if getbutton(LEFTSHIFTKEY) == 0:
322 shademodel(GOURAUD)
323 else:
324 shademodel(FLAT)
325 #
326 # Draw background and axis
327 cpack(0x105090)
328 clear()
329 zclear()
330 cpack(0x905010)
331 axis()
332 #
333 # Draw object
334 #
335 bolx = fx(t)
336 boly = fy(t)
337 bolz = fz(t)
338 err = ''
339 if bolx < -4.0 or bolx > 4.0:
340 err = 'X('+`bolx`+') out of range [-4,4]'
341 if boly < -4.0 or boly > 4.0:
342 err = 'Y('+`boly`+') out of range [-4,4]'
343 if bolz < -4.0 or bolz > 8.0:
344 err = 'Z('+`bolz`+') out of range [-4,8]'
345 if not err:
346 pushmatrix()
347 translate(bolx, boly, bolz)
348 scale(0.3, 0.3, 0.3)
349 lmbind(MATERIAL, 2)
350 callobj(bol)
351 popmatrix()
352 #
353 # Draw the cables
354 #
355 bolz = bolz + 0.3
356 pushmatrix()
357 linesmooth(SML_ON)
358 bgnline()
359 v3i(-4,-4,9)
360 v3f(bolx, boly, bolz)
361 endline()
362 bgnline()
363 v3i(-4,4,9)
364 v3f(bolx, boly, bolz)
365 endline()
366 bgnline()
367 v3i(4,-4,9)
368 v3f(bolx, boly, bolz)
369 endline()
370 bgnline()
371 v3i(4,4,9)
372 v3f(bolx, boly, bolz)
373 endline()
374 popmatrix()
375 #
376 # draw the floors
377 #
378 lmbind(MATERIAL, 3)
379 callobj(floors)
380 lmbind(MATERIAL, 4)
381 callobj(walls)
382 lmbind(MATERIAL, 5)
383 pushmatrix()
384 translate(-4.5,4.5,3.0)
385 scale(0.2,0.2,9.0)
386 rotate(450,'z')
387 callobj(pillar)
388 popmatrix()
389 callobj(railing)
390 lmbind(MATERIAL, 6)
391 pushmatrix()
392 translate(0.0, -0.01, 0.0)
393 callobj(doors)
394 popmatrix()
395 if mousing == MOUSE2 or err:
396 cpack(0xff0000)
397 cmov(0.0, 0.0, 0.4)
398 charstr('t='+`t`)
399 if mousing == MOUSE2:
400 cpack(0xff0000)
401 cmov(0.0, 0.0, 0.2)
402 charstr('delta-t='+`step`)
403 if err:
404 cpack(0xff00)
405 cmov(0.0, 0.0, 0.2)
406 print err
407 charstr(err)
408 pausing = 1
409 if pausing:
410 cpack(0xff00)
411 cmov(0.0, 0.0, 0.0)
412 charstr('Pausing, type P to continue')
413 swapbuffers()
414 if pausing:
415 while 1:
416 dv=qread()
417 if dv==(PKEY,1):
418 break
419 if dv==(ESCKEY,1):
420 sys.exit(0)
421 pausing = 0
Guido van Rossum453bd401992-03-30 13:18:37 +0000422#
423try:
424 main()
425except KeyboardInterrupt:
426 sys.exit(1)