add scene lighting constructs; real stdin support
[chaz/rasterize] / animate.lua
1 #!/usr/bin/env lua
2
3 --
4 -- CS5600 University of Utah
5 -- Charles McGarvey
6 -- mcgarvey@eng.utah.edu
7 --
8
9 -- This program that draws a scene multiple times from different camera angles
10 -- and positions. The rasters are saved in the `frames' directory, and if
11 -- ffmpeg is installed, they will also be combined into a video file. The
12 -- camera will make a full rotation along the X and Z axes, around a specified
13 -- point (center), all the while looking at some other point (look).
14 -- This must be called from the same directory where the rasterize program is.
15
16 local size = {w = 640, h = 480} -- width and height of the viewport
17 local frames = 512 -- number of animation frames
18
19 local look = {x = 2, y = 1, z = 2} -- the point to look at
20 local center = {x = 0, y = 1, z = 0} -- center of rotation
21 local distance = 4 -- the distance from the center
22 local start = math.pi -- where is the first frame
23
24 local jobs = 6 -- number of concurrent renderings
25
26 -- the actual objects of the scene that will be drawn:
27 local scene = [[
28 L 0 1000000 0 1 1 1 1 1 1
29 L 0 0 1000000 1 1 1 1 1 1
30 g triangle.raw
31 c 0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2 0.1
32 t 2 0 -2
33 s 1 1 1
34 g dragon.raw
35 c 0.7 0.3 0.2 0.8 0.2 0.1 0.9 0.2 0.2
36 t -2 -1 -2
37 s 2 2 2
38 g budda.raw
39 c 0.1 0.2 0.7 0.1 0.3 0.9 0.2 0.1 0.8
40 t 2 -1.5 2
41 s 10 10 10
42 g bunny.raw
43 c 0.9 0.8 0.9 0.8 0.7 0.9 0.9 0.8 0.7
44 t -2 -1 2
45 s 10 10 10
46 g teapot2.raw
47 c 0 1 0 0 1 0 0 1 0
48 t 0 -1 0
49 s 0.6 0.6 0.6
50 ]]
51
52
53 function vec_add(a, b)
54 return {x = a.x + b.x, y = a.y + b.y, z = a.z + b.z}
55 end
56
57 function vec_scale(v, s)
58 return {x = v.x * s, y = v.y * s, z = v.z * s}
59 end
60
61 local fmt = string.format
62 local write = function(...) io.write(fmt(...)) end
63
64 function render(i, v)
65 while i and v do
66 local filename = fmt("frames/anim%04d.bmp", i)
67 local command = fmt("./rasterize -o %s >/dev/null", filename)
68 local out = io.popen(command, "w")
69 write("\27[80D\27[2Kframe\t %4d / %d", i + 1, frames)
70 out:write(fmt([[
71 U3
72 %d %d
73 %f %f %f
74 %f %f %f
75 0 1 0
76 1.57 %f 0.1 1000
77 %s
78 X
79 ]], size.w, size.h, v.x, v.y, v.z, look.x, look.y, look.z, size.w/size.h, scene))
80 i, v = coroutine.yield()
81 out:close()
82 end
83 end
84
85
86 print("Animating scene...")
87
88 local threads = {}
89 for i = 1,jobs do
90 table.insert(threads, coroutine.wrap(render))
91 end
92
93 os.execute("rm -rf frames && mkdir frames >/dev/null 2>&1")
94 for i = 0,(frames-1) do
95 local t = start + 2 * math.pi * i / frames
96 local v = {
97 x = math.cos(t),
98 y = 0,
99 z = math.sin(t),
100 }
101 v = vec_add(vec_scale(v, distance), center)
102 threads[1 + (i % jobs)](i, v)
103 end
104 for _,thread in ipairs(threads) do thread(null) end
105 print()
106
107 if os.execute("ffmpeg -i frames/anim%04d.bmp -b 1024k -y -an scene.avi") == 0 then
108 print("Animation written to scene.avi.")
109 end
110
This page took 0.045504 seconds and 4 git commands to generate.