#! /usr/bin/env python # Simulate the artwork in the hall. # Jack Jansen, Feb 91. from gl import * from GL import * from math import * from DEVICE import * import sys import __main__ main_dict = __main__.__dict__ SPOTDIRECTION = 103 SPOTLIGHT = 104 # # Make a cylinder paralel with the Z axis with center (X,Y,0) # and radius 1 def mkcyl(nslice, nparts, docircle): cyl = [] step = 2.0 / float(nslice) z = -1.0 for i in range(nslice): cyl.append(mkslice(z, z+step, nparts, docircle)) z = z + step return drawcylinder(cyl) # # Make one part of a cylinder # def mkslice(z1, z2, nparts, docircle): if docircle: w1 = z1 w2 = z2 w1 = sqrt(1.0-w1*w1) w2 = sqrt(1.0-w2*w2) normalz = 1.0 else: w1 = 1.0 w2 = 1.0 normalz = 0.0 slice = [] step = (2.0*pi)/float(nparts) angle = 0.0 for i in range(nparts+1): vx = cos(angle) vy = sin(angle) slice.append( ((vx*w1,vy*w1,z1), (vx*w1, vy*w1, z1*normalz)) ) slice.append( ((vx*w2,vy*w2,z2), (vx*w2, vy*w2, z2*normalz)) ) angle = angle + step return slice # # Drawcylinder : draw the cylinder # class struct: pass curobj = struct() curobj.curobj = 1 def drawcylinder(cyl): obj = curobj.curobj curobj.curobj = curobj.curobj+1 makeobj(obj) for slice in cyl: bgntmesh() vnarray(slice) endtmesh() closeobj() return obj # def drawnormals(cyl): for slice in cyl: for triang in slice: bgnline() v3f(triang[0]) v3f(triang[0][0] + triang[1][0], triang[0][1] + triang[1][1], triang[0][2] + triang[1][2]) endline() def drawfloors(): obj = curobj.curobj curobj.curobj = curobj.curobj+1 makeobj(obj) bgnpolygon() v3i(4,6,-6) v3i(-6,6,-6) v3i(-6,-6,-6) v3i(4,-6,-6) endpolygon() for floor in range(3): pos = -1 + 5*floor bgnpolygon() v3i(4,4,pos) v3i(-6,4,pos) v3i(-6,6,pos) v3i(4,6,pos) endpolygon() bgnpolygon() v3i(-4,4,pos) v3i(-4,-4,pos) v3i(-6,-4,pos) v3i(-6,4,pos) endpolygon() bgnpolygon() v3i(-6,-4,pos) v3i(-6,-6,pos) v3i(4,-6,pos) v3i(4,-4,pos) endpolygon() closeobj() return obj def drawdoors(): obj = curobj.curobj curobj.curobj = curobj.curobj+1 makeobj(obj) for floor in range(3): pos = -1+5*floor bgnpolygon() v3i(-2,6,pos) v3i(-2,6,pos+3) v3i(0,6,pos+3) v3i(0,6,pos) endpolygon() closeobj() return obj def drawrailing(): obj = curobj.curobj curobj.curobj = curobj.curobj+1 makeobj(obj) for floor in range(3): pos = -1 + 5*floor bgnpolygon() v3i(4,4,pos) v3i(4,4,pos-1) v3i(-4,4,pos-1) v3i(-4,4,pos) endpolygon() bgnpolygon() v3i(-4,4,pos) v3i(-4,4,pos-1) v3i(-4,-4,pos-1) v3i(-4,-4,pos) endpolygon() bgnpolygon() v3i(-4,-4,pos) v3i(-4,-4,pos-1) v3i(4,-4,pos-1) v3i(4,-4,pos) endpolygon() closeobj() return obj def drawwalls(): obj = curobj.curobj curobj.curobj = curobj.curobj+1 makeobj(obj) bgnpolygon() v3i(4,6,-6) v3i(4,6,18) v3i(-6,6,18) v3i(-6,6,-6) endpolygon() bgnpolygon() v3i(-6,6,-6) v3i(-6,6,18) v3i(-6,-6,18) v3i(-6,-6,-6) endpolygon() bgnpolygon() v3i(-6,-6,-6) v3i(-6,-6,18) v3i(4,-6,18) v3i(4,-6,-6) endpolygon() bgnpolygon() v3i(4,-6,-6) v3i(4,-6,18) v3i(4,4,18) v3i(4,4,-6) endpolygon() closeobj() return obj def axis(): bgnline() cpack(0xff0000) v3i(-1,0,0) v3i(1,0,0) v3f(1.0, 0.1, 0.1) endline() bgnline() cpack(0xff00) v3i(0,-1,0) v3i(0,1,0) v3f(0.1, 1.0, 0.1) endline() bgnline() cpack(0xff) v3i(0,0,-1) v3i(0,0,1) v3f(0.1,0.1,1.0) endline() # green_velvet = [ DIFFUSE, 0.05, 0.4, 0.05, LMNULL] silver = [ DIFFUSE, 0.3, 0.3, 0.3, SPECULAR, 0.9, 0.9, 0.95, \ SHININESS, 40.0, LMNULL] floormat = [ 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] wallmat = [ 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] offwhite = [ 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] doormat = [ 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] toplight = [ LCOLOR, 1.0, 1.0, 0.5, \ POSITION, 0.0, 0.0, 11.0, 1.0, LMNULL] floor1light = [ LCOLOR, 1.0, 1.0, 1.0, POSITION, 3.9, -3.9, 0.0, 1.0, \ SPOTDIRECTION, 1.0, 1.0, 0.0, SPOTLIGHT, 10.0, 90.0, LMNULL] lmodel = [ AMBIENT, 0.92, 0.8, 0.5, LOCALVIEWER, 1.0, LMNULL] # def lighting(): lmdef(DEFMATERIAL, 1, green_velvet) lmdef(DEFMATERIAL, 2, silver) lmdef(DEFMATERIAL, 3, floormat) lmdef(DEFMATERIAL, 4, wallmat) lmdef(DEFMATERIAL, 5, offwhite) lmdef(DEFMATERIAL, 6, doormat) lmdef(DEFLIGHT, 1, toplight) lmdef(DEFLIGHT, 2, floor1light) lmdef(DEFLMODEL, 1, lmodel) lmbind(MATERIAL, 1) lmbind(LIGHT0, 1) lmbind(LIGHT1, 2) lmbind(LMODEL, 1) IdMat=[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] # def defun(axis): done = 0 while not done: print 'F'+axis+'(t) = ', s = sys.stdin.readline(100) print try: s = 'def f'+axis+'(t): return '+s exec(s, main_dict) done = 1 except RuntimeError: print 'Sorry, there is a syntax error in your expression' def getfunctions(): print 'Welcome to the CWI art simulator. You can now enter X, Y and Z' print 'coordinates as a function of t.' print 'Normal trig functions are available. Please use floating point' print 'values only (so 0.0 for 0). Comments to jack@cwi.nl' defun('x') defun('y') defun('z') print 'Ok, here you go. Use mouse+right button to move up/down,' print 'mouse+middle to speed up/slow down time. type ESC to quit simulation' def main(): getfunctions() foreground() prefposition(100,600,100,600) void = winopen('cyl') qdevice(ESCKEY) qdevice(MOUSE1) qdevice(MOUSE2) qdevice(PKEY) RGBmode() doublebuffer() gconfig() zbuffer(1) mmode(MVIEWING) perspective(400, 1.0, 1.0, 20.0) loadmatrix(IdMat) vx = 0.0 vy = -6.0 vz = 0.0 lookat(0.0, -6.0, 0.0, 0.0, 0.0, 0.0, 0) lighting() t = -1.0 step = 1.0 bol = mkcyl(12,24, 1) cable = mkcyl(1, 6, 0) floors = drawfloors() walls = drawwalls() pillar = mkcyl(1,4,0) railing = drawrailing() doors = drawdoors() shademodel(GOURAUD) mousing = -1 pausing = 0 while 1: # # Check for some user input # if qtest(): dev, value = qread() if dev == PKEY and value == 1: pausing = 1 if dev == ESCKEY: break elif (dev==MOUSE1 or dev==MOUSE2) and value == 1: if mousing > 0: vx = 0.0 vy = -6.0 vz = 0.0 mousing = dev oldx = getvaluator(MOUSEX) oldy = getvaluator(MOUSEY) elif (dev==MOUSE1 or dev==MOUSE2): mousing = -1 if mousing >= 0: newx = getvaluator(MOUSEX) newy = getvaluator(MOUSEY) if newy <> oldy and mousing==MOUSE1: vz = vz + float(newy - oldy)/100.0 dist = sqrt(vx*vx + vy*vy + vz*vz) perspective(400, 1.0, 1.0, dist+16.0) loadmatrix(IdMat) if vz < 0.0: lookat(vx, vy, vz, 0.0, 0.0, 0.0, 1800) else: lookat(vx, vy, vz, 0.0, 0.0, 0.0, 0) if newy <> oldy and mousing==MOUSE2: step = step * exp(float(newy-oldy)/400.0) if getbutton(CTRLKEY) == 0: t = t + step else: t = t - step if getbutton(LEFTSHIFTKEY) == 0: shademodel(GOURAUD) else: shademodel(FLAT) # # Draw background and axis cpack(0x105090) clear() zclear() cpack(0x905010) axis() # # Draw object # bolx = fx(t) boly = fy(t) bolz = fz(t) err = '' if bolx < -4.0 or bolx > 4.0: err = 'X('+`bolx`+') out of range [-4,4]' if boly < -4.0 or boly > 4.0: err = 'Y('+`boly`+') out of range [-4,4]' if bolz < -4.0 or bolz > 8.0: err = 'Z('+`bolz`+') out of range [-4,8]' if not err: pushmatrix() translate(bolx, boly, bolz) scale(0.3, 0.3, 0.3) lmbind(MATERIAL, 2) callobj(bol) popmatrix() # # Draw the cables # bolz = bolz + 0.3 pushmatrix() linesmooth(SML_ON) bgnline() v3i(-4,-4,9) v3f(bolx, boly, bolz) endline() bgnline() v3i(-4,4,9) v3f(bolx, boly, bolz) endline() bgnline() v3i(4,-4,9) v3f(bolx, boly, bolz) endline() bgnline() v3i(4,4,9) v3f(bolx, boly, bolz) endline() popmatrix() # # draw the floors # lmbind(MATERIAL, 3) callobj(floors) lmbind(MATERIAL, 4) callobj(walls) lmbind(MATERIAL, 5) pushmatrix() translate(-4.5,4.5,3.0) scale(0.2,0.2,9.0) rotate(450,'z') callobj(pillar) popmatrix() callobj(railing) lmbind(MATERIAL, 6) pushmatrix() translate(0.0, -0.01, 0.0) callobj(doors) popmatrix() if mousing == MOUSE2 or err: cpack(0xff0000) cmov(0.0, 0.0, 0.4) charstr('t='+`t`) if mousing == MOUSE2: cpack(0xff0000) cmov(0.0, 0.0, 0.2) charstr('delta-t='+`step`) if err: cpack(0xff00) cmov(0.0, 0.0, 0.2) print err charstr(err) pausing = 1 if pausing: cpack(0xff00) cmov(0.0, 0.0, 0.0) charstr('Pausing, type P to continue') swapbuffers() if pausing: while 1: dv=qread() if dv==(PKEY,1): break if dv==(ESCKEY,1): sys.exit(0) pausing = 0 # try: main() except KeyboardInterrupt: sys.exit(1)