Guido van Rossum | f06ee5f | 1996-11-27 19:52:01 +0000 | [diff] [blame] | 1 | #! /usr/bin/env python |
Guido van Rossum | 453bd40 | 1992-03-30 13:18:37 +0000 | [diff] [blame] | 2 | # Simulate the artwork in the hall. |
| 3 | # Jack Jansen, Feb 91. |
Guido van Rossum | 2426331 | 1992-12-14 13:01:06 +0000 | [diff] [blame] | 4 | |
Guido van Rossum | 453bd40 | 1992-03-30 13:18:37 +0000 | [diff] [blame] | 5 | from gl import * |
| 6 | from GL import * |
| 7 | from math import * |
| 8 | from DEVICE import * |
| 9 | import sys |
| 10 | import __main__ |
| 11 | main_dict = __main__.__dict__ |
| 12 | |
| 13 | SPOTDIRECTION = 103 |
| 14 | SPOTLIGHT = 104 |
| 15 | |
| 16 | # |
| 17 | # Make a cylinder paralel with the Z axis with center (X,Y,0) |
| 18 | # and radius 1 |
| 19 | def mkcyl(nslice, nparts, docircle): |
Guido van Rossum | 4117e54 | 1998-09-14 16:44:15 +0000 | [diff] [blame^] | 20 | 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 Rossum | 453bd40 | 1992-03-30 13:18:37 +0000 | [diff] [blame] | 27 | # |
| 28 | # Make one part of a cylinder |
| 29 | # |
| 30 | def mkslice(z1, z2, nparts, docircle): |
Guido van Rossum | 4117e54 | 1998-09-14 16:44:15 +0000 | [diff] [blame^] | 31 | 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 Rossum | 453bd40 | 1992-03-30 13:18:37 +0000 | [diff] [blame] | 51 | # |
| 52 | # Drawcylinder : draw the cylinder |
| 53 | # |
Guido van Rossum | 96b608c | 1993-12-17 14:57:24 +0000 | [diff] [blame] | 54 | class struct: pass |
Guido van Rossum | 453bd40 | 1992-03-30 13:18:37 +0000 | [diff] [blame] | 55 | curobj = struct() |
| 56 | curobj.curobj = 1 |
| 57 | def drawcylinder(cyl): |
Guido van Rossum | 4117e54 | 1998-09-14 16:44:15 +0000 | [diff] [blame^] | 58 | 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 Rossum | 453bd40 | 1992-03-30 13:18:37 +0000 | [diff] [blame] | 67 | # |
| 68 | def drawnormals(cyl): |
Guido van Rossum | 4117e54 | 1998-09-14 16:44:15 +0000 | [diff] [blame^] | 69 | 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 Rossum | 453bd40 | 1992-03-30 13:18:37 +0000 | [diff] [blame] | 75 | def drawfloors(): |
Guido van Rossum | 4117e54 | 1998-09-14 16:44:15 +0000 | [diff] [blame^] | 76 | 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 Rossum | 453bd40 | 1992-03-30 13:18:37 +0000 | [diff] [blame] | 107 | def drawdoors(): |
Guido van Rossum | 4117e54 | 1998-09-14 16:44:15 +0000 | [diff] [blame^] | 108 | 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 Rossum | 453bd40 | 1992-03-30 13:18:37 +0000 | [diff] [blame] | 121 | def drawrailing(): |
Guido van Rossum | 4117e54 | 1998-09-14 16:44:15 +0000 | [diff] [blame^] | 122 | 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 Rossum | 453bd40 | 1992-03-30 13:18:37 +0000 | [diff] [blame] | 147 | def drawwalls(): |
Guido van Rossum | 4117e54 | 1998-09-14 16:44:15 +0000 | [diff] [blame^] | 148 | 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 Rossum | 453bd40 | 1992-03-30 13:18:37 +0000 | [diff] [blame] | 177 | def axis(): |
Guido van Rossum | 4117e54 | 1998-09-14 16:44:15 +0000 | [diff] [blame^] | 178 | 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 Rossum | 453bd40 | 1992-03-30 13:18:37 +0000 | [diff] [blame] | 196 | # |
Guido van Rossum | 2426331 | 1992-12-14 13:01:06 +0000 | [diff] [blame] | 197 | green_velvet = [ DIFFUSE, 0.05, 0.4, 0.05, LMNULL] |
Guido van Rossum | 453bd40 | 1992-03-30 13:18:37 +0000 | [diff] [blame] | 198 | silver = [ DIFFUSE, 0.3, 0.3, 0.3, SPECULAR, 0.9, 0.9, 0.95, \ |
Guido van Rossum | 4117e54 | 1998-09-14 16:44:15 +0000 | [diff] [blame^] | 199 | SHININESS, 40.0, LMNULL] |
Guido van Rossum | 453bd40 | 1992-03-30 13:18:37 +0000 | [diff] [blame] | 200 | 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] |
| 201 | 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] |
| 202 | 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] |
| 203 | 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] |
| 204 | |
| 205 | toplight = [ LCOLOR, 1.0, 1.0, 0.5, \ |
Guido van Rossum | 4117e54 | 1998-09-14 16:44:15 +0000 | [diff] [blame^] | 206 | POSITION, 0.0, 0.0, 11.0, 1.0, LMNULL] |
Guido van Rossum | 453bd40 | 1992-03-30 13:18:37 +0000 | [diff] [blame] | 207 | floor1light = [ LCOLOR, 1.0, 1.0, 1.0, POSITION, 3.9, -3.9, 0.0, 1.0, \ |
Guido van Rossum | 4117e54 | 1998-09-14 16:44:15 +0000 | [diff] [blame^] | 208 | SPOTDIRECTION, 1.0, 1.0, 0.0, SPOTLIGHT, 10.0, 90.0, LMNULL] |
Guido van Rossum | 453bd40 | 1992-03-30 13:18:37 +0000 | [diff] [blame] | 209 | |
| 210 | lmodel = [ AMBIENT, 0.92, 0.8, 0.5, LOCALVIEWER, 1.0, LMNULL] |
| 211 | # |
| 212 | def lighting(): |
Guido van Rossum | 4117e54 | 1998-09-14 16:44:15 +0000 | [diff] [blame^] | 213 | 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 Rossum | 453bd40 | 1992-03-30 13:18:37 +0000 | [diff] [blame] | 226 | 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] |
| 227 | # |
Guido van Rossum | 453bd40 | 1992-03-30 13:18:37 +0000 | [diff] [blame] | 228 | def defun(axis): |
Guido van Rossum | 4117e54 | 1998-09-14 16:44:15 +0000 | [diff] [blame^] | 229 | 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 Rossum | 453bd40 | 1992-03-30 13:18:37 +0000 | [diff] [blame] | 240 | def getfunctions(): |
Guido van Rossum | 4117e54 | 1998-09-14 16:44:15 +0000 | [diff] [blame^] | 241 | 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 Rossum | 453bd40 | 1992-03-30 13:18:37 +0000 | [diff] [blame] | 250 | def main(): |
Guido van Rossum | 4117e54 | 1998-09-14 16:44:15 +0000 | [diff] [blame^] | 251 | 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 Rossum | 453bd40 | 1992-03-30 13:18:37 +0000 | [diff] [blame] | 422 | # |
| 423 | try: |
| 424 | main() |
| 425 | except KeyboardInterrupt: |
| 426 | sys.exit(1) |