]> Dogcows Code - chaz/rasterize/blob - animate.lua
fixes for compiling with mingw32
[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 -- The CACHE_GEOMETRY option is also recommended to improve performance.
14
15 -- Set the number of frames to be rendered for the animation.
16 local frames = 360
17
18 -- Define the code to calculate where the camera is, in world coordinates.
19 local eye = function(frame)
20 -- just rotate around the center of the scene on the XZ plane
21 local center = vec_new(0, 0.4, 0)
22 local distance = 0.7
23 local start = math.pi
24 local t = start + 2 * math.pi * frame / frames
25 local v = vec_new(math.cos(t), 0, math.sin(t))
26 return vec_add(vec_scale(v, distance), center)
27 end
28
29 -- Define the code to calculate where the focal point of the scene is.
30 local look = function(frame)
31 -- keep the camera focused at the center
32 return vec_new(0, 0, 0)
33 end
34
35 -- Define the actual objects of the scene that will be rendered, in the
36 -- extended u3d format.
37 local scene = [[
38 l -14687.0 7986.0 8976.0 1.0 1.0 1.0
39 g checker.obj
40 c 1.0 0.6 0.6 0.6
41 m checker.ppm
42 r -1.57 1.0 0.0 0.0
43 p 1.0 1.0 1.0 100.0
44 g teapot.raw
45 c 0.9 0.7 0.1 0.2
46 p 1.0 1.0 1.0 60.0
47 t 0.0 0.1 0.0
48 s 0.004 0.004 0.004
49 ]]
50
51 -- Set the number of samples for supersampling. If this is set to a value
52 -- of two or greater, each frame will be rendered larger by the factor
53 -- specified. ImageMagick is used to scale the frames back down to size;
54 -- if ImageMagick is not installed, this script will exit with error 1.
55 local supersample = 2
56
57 -- Set the width and height of the viewport.
58 local size = {w = 640, h = 480}
59
60 -- Set the number of concurrent renderings (for multi-core machines).
61 local jobs = 6
62
63 -- Set the options to be passed directly to ffmpeg.
64 local ffmpeg_opts = "-b 1024k"
65
66 -- end of configuration
67 ---------------------------------------------------------------------------
68
69 function vec_new(x, y, z)
70 return {x = x, y = y, z = z}
71 end
72
73 function vec_add(a, b)
74 return vec_new(a.x + b.x, a.y + b.y, a.z + b.z)
75 end
76
77 function vec_scale(v, s)
78 return vec_new(v.x * s, v.y * s, v.z * s)
79 end
80
81 local fmt = string.format
82 local write = function(...) io.write(fmt(...)) io.flush() end
83 local run = function(...) return os.execute(fmt(...)) end
84
85 function render(i)
86 while i do
87 local w, h = size.w, size.h
88 if 1 < supersample then
89 w = w * supersample
90 h = h * supersample
91 end
92 local filename = fmt("frames/anim%04d.bmp", i)
93 local command = fmt("./rasterize -o %s >/dev/null", filename)
94 local out = io.popen(command, "w")
95 local e = eye(i)
96 local l = look(i)
97 write("\27[80D\27[2Kframe\t %4d / %d", i, frames)
98 out:write(fmt([[
99 U4
100 %d %d
101 %f %f %f
102 %f %f %f
103 0 1 0
104 1.57 %f 0.1 1000
105 1.0 1.0 1.0
106 %s
107 X
108 ]], w, h, e.x, e.y, e.z, l.x, l.y, l.z, size.w/size.h, scene))
109 i = coroutine.yield()
110 out:close()
111 if 1 < supersample and
112 run("convert %s -scale %dx%d %s", filename, size.w, size.h, filename) ~= 0 then
113 print()
114 os.exit(1)
115 end
116 end
117 end
118
119 function renderings()
120 local t = {}
121 for i = 1,jobs do
122 table.insert(t, coroutine.wrap(render))
123 end
124 local iterations = frames + jobs
125 local frame = 0
126 return function()
127 frame = frame + 1
128 if frame <= iterations then
129 local i = frame
130 if frames < i then i = null end
131 return t[1 + frame % jobs], i
132 end
133 end
134 end
135
136 print("Animating scene...")
137
138 run("rm -rf frames && mkdir frames >/dev/null 2>&1")
139 for render,frame in renderings() do render(frame) end
140
141 print()
142
143 if run("ffmpeg -i frames/anim%%04d.bmp %s -y -an scene.avi", ffmpeg_opts) == 0 then
144 print("Animation written to scene.avi.")
145 else
146 print("The animation could not be created. Is ffmpeg installed?")
147 os.exit(2)
148 end
149
This page took 0.033487 seconds and 4 git commands to generate.