| #! /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) |