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