mirror of https://github.com/python/cpython
447 lines
9.9 KiB
Python
447 lines
9.9 KiB
Python
|
#!/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)
|