a1c7389f8af95fe33b24e95999812140de178078
[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 automates the process of creating simple fly-by animations.
10 -- The rasters are saved in the `frames' directory, and if ffmpeg is
11 -- installed, the frames will also be combined into a video file. This script
12 -- must be called from the same directory where the rasterize program is.
13
14 -- Set the width and height of the viewport.
15 local size = {w = 640, h = 480}
16
17 -- Set the number of frames to be rendered for the animation.
18 local frames = 360
19
20 -- Define the code to calculate where the camera is, in world coordinates.
21 local eye = function(frame)
22 -- just rotate around the center of the scene on the XZ plane
23 local center = vec_new(0, 1, 0)
24 local distance = 4
25 local start = math.pi
26 local t = start + 2 * math.pi * frame / frames
27 local v = vec_new(math.cos(t), 0, math.sin(t))
28 return vec_add(vec_scale(v, distance), center)
29 end
30
31 -- Define the code to calculate where the focal point of the scene is.
32 local look = function(frame)
33 -- keep the camera focused on the buddha
34 return vec_new(2, 1, 2)
35 end
36
37 -- Define the actual objects of the scene that will be rendered, in the
38 -- extended u3d format.
39 local scene = [[
40 L 0 1000000 0 1 1 1 1 1 1
41 L 0 0 1000000 1 1 1 1 1 1
42 g ak47.obj
43 c 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1 0.1
44 M 0.9 0.9 0.9 128
45 g dragon.raw
46 M 0.3 0.3 0.3 5
47 c 0.7 0.3 0.2 0.8 0.2 0.1 0.9 0.2 0.2
48 t -2 -1 -2
49 s 2 2 2
50 g budda.raw
51 c 0.1 0.2 0.7 0.1 0.3 0.9 0.2 0.1 0.8
52 t 2 -1.5 2
53 s 10 10 10
54 g bunny.raw
55 M 0.2 0.2 0.2 1
56 c 0.9 0.8 0.9 0.8 0.7 0.9 0.9 0.8 0.7
57 t -2 -1 2
58 s 10 10 10
59 ]]
60
61 -- Set the number of concurrent renderings (for multi-core machines).
62 local jobs = 6
63
64
65 -- end of configuration
66 ---------------------------------------------------------------------------
67
68 local fmt = string.format
69 local write = function(...) io.write(fmt(...)) end
70
71 function vec_new(x, y, z)
72 return {x = x, y = y, z = z}
73 end
74
75 function vec_add(a, b)
76 return vec_new(a.x + b.x, a.y + b.y, a.z + b.z)
77 end
78
79 function vec_scale(v, s)
80 return vec_new(v.x * s, v.y * s, v.z * s)
81 end
82
83 function render(i)
84 while i do
85 local filename = fmt("frames/anim%04d.bmp", i)
86 local command = fmt("./rasterize -o %s >/dev/null", filename)
87 local out = io.popen(command, "w")
88 local e = eye(i)
89 local l = look(i)
90 write("\27[80D\27[2Kframe\t %4d / %d", i + 1, frames)
91 out:write(fmt([[
92 U3
93 %d %d
94 %f %f %f
95 %f %f %f
96 0 1 0
97 1.57 %f 0.1 1000
98 %s
99 X
100 ]], size.w, size.h, e.x, e.y, e.z, l.x, l.y, l.z, size.w/size.h, scene))
101 i = coroutine.yield()
102 out:close()
103 end
104 end
105
106 print("Animating scene...")
107
108 local threads = {}
109 for i = 1,jobs do
110 table.insert(threads, coroutine.wrap(render))
111 end
112
113 os.execute("rm -rf frames && mkdir frames >/dev/null 2>&1")
114 for i = 0,(frames-1) do
115 threads[1 + (i % jobs)](i)
116 end
117 for _,thread in ipairs(threads) do thread(null) end
118 print()
119
120 if os.execute("ffmpeg -i frames/anim%04d.bmp -b 1024k -y -an scene.avi") == 0 then
121 print("Animation written to scene.avi.")
122 end
123
This page took 0.043423 seconds and 3 git commands to generate.