#!/ufs/guido/bin/sgi/python # Simulate the artwork in the hall. # Jack Jansen, Feb 91. # # Please please please don't try to read this code. # It is the first GL program I ever wrote, and used to do # very different things before it's current function:-) 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() # 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(): INDIGO=1 # XXXX Seems indigo only has one light. lmdef(DEFMATERIAL, 2, silver) lmdef(DEFMATERIAL, 3, floormat) lmdef(DEFMATERIAL, 4, wallmat) lmdef(DEFMATERIAL, 5, offwhite) lmdef(DEFMATERIAL, 6, doormat) lmdef(DEFLIGHT, 1, toplight) if not INDIGO: lmdef(DEFLIGHT, 2, floor1light) lmdef(DEFLMODEL, 1, lmodel) lmbind(LIGHT0, 1) if not INDIGO: 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] # wrongrange='Wrong Range' def defun(axis): done = 0 res = 0.0 # Hack around exec(...) 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) exec('res = f'+axis+'(0.0)\n') if res < -10.0 or res > 10.0: raise wrongrange exec('res = f'+axis+'(100.0)\n') if res < -10.0 or res > 10.0: raise wrongrange done = 1 except RuntimeError: print 'Sorry, there is a syntax error in your expression' except TypeError: print 'Please remember to use floating point numbers' except wrongrange: print 'Sorry, function values out of range (non-periodic function?)' 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 'Alternatively, you can specify the name of a python module' print 'defining functions fx(t), fy(t) and fz(t) on the command line' 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(): if len(sys.argv) > 1: exec('from '+sys.argv[1]+' import *\n') else: 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(600, 1.0, 0.01, 20.0) loadmatrix(IdMat) vx = 0.0 vy = -3.9 vz = 0.0 lookat(0.0, -3.9, 0.0, 0.0, 0.0, 0.0, 0) lighting() t = -1.0 step = 0.2 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 = -3.9 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 if vz < -5.99: vz = -5.99 dist = sqrt(vx*vx + vy*vy + vz*vz) perspective(600, 1.0, 0.01, 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 czclear(0x802020,getgdesc(GD_ZMAX)) #axis() # # 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() # # 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) blendfunction(BF_ONE, BF_ONE) callobj(bol) blendfunction(BF_ONE, BF_ZERO) 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() 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) 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)