]> Dogcows Code - chaz/rasterize/blobdiff - animate.lua
refactor the animation script a bit
[chaz/rasterize] / animate.lua
index a1c7389f8af95fe33b24e95999812140de178078..ad16db9363d29c9a93cd56b95457c83c16bbfe6c 100755 (executable)
@@ -11,9 +11,6 @@
 -- installed, the frames will also be combined into a video file.  This script
 -- must be called from the same directory where the rasterize program is.
 
--- Set the width and height of the viewport.
-local size = {w = 640, h = 480}
-
 -- Set the number of frames to be rendered for the animation.
 local frames = 360
 
@@ -58,16 +55,25 @@ t -2 -1 2
 s 10 10 10
 ]]
 
+-- Set the number of samples for supersampling.  If this is set to a value of
+-- two or greater, each frame will be rendered larger by the factor specified.
+-- ImageMagick is used to scale the frames back down to size; if ImageMagick
+-- is not installed, the resulting frames will end up bigger than they should
+-- be and the aliasing problem will not be fixed.
+local supersample = 2
+
+-- Set the width and height of the viewport.
+local size = {w = 640, h = 480}
+
 -- Set the number of concurrent renderings (for multi-core machines).
 local jobs = 6
 
+-- Set the options to be passed directly to ffmpeg.
+local ffmpeg_opts = "-b 1024k"
 
 -- end of configuration
 ---------------------------------------------------------------------------
 
-local fmt   = string.format
-local write = function(...) io.write(fmt(...)) end
-
 function vec_new(x, y, z)
     return {x = x, y = y, z = z}
 end
@@ -80,14 +86,23 @@ function vec_scale(v, s)
     return vec_new(v.x * s, v.y * s, v.z * s)
 end
 
+local fmt   = string.format
+local write = function(...) io.write(fmt(...)) io.flush() end
+local run   = function(...) return os.execute(fmt(...)) end
+
 function render(i)
     while i do
+        local w, h = size.w, size.h
+        if 1 < supersample then
+            w = w * supersample
+            h = h * supersample
+        end
         local filename  = fmt("frames/anim%04d.bmp", i)
         local command   = fmt("./rasterize -o %s >/dev/null", filename)
         local out = io.popen(command, "w")
         local e = eye(i)
         local l = look(i)
-        write("\27[80D\27[2Kframe\t %4d / %d", i + 1, frames)
+        write("\27[80D\27[2Kframe\t %4d / %d", i, frames)
         out:write(fmt([[
 U3
 %d %d
@@ -97,27 +112,40 @@ U3
 1.57 %f 0.1 1000
 %s
 X
-]], size.w, size.h, e.x, e.y, e.z, l.x, l.y, l.z, size.w/size.h, scene))
+]], w, h, e.x, e.y, e.z, l.x, l.y, l.z, size.w/size.h, scene))
         i = coroutine.yield()
         out:close()
+        if 1 < supersample then
+            run("convert %s -scale %dx%d %s", filename, size.w, size.h, filename)
+        end
+    end
+end
+
+function renderings()
+    local t = {}
+    for i = 1,jobs do
+        table.insert(t, coroutine.wrap(render))
+    end
+    local iterations = frames + jobs
+    local frame = 0
+    return function()
+        frame = frame + 1
+        if frame <= iterations then
+            local i = frame
+            if frames < i then i = null end
+            return t[1 + frame % jobs], i
+        end
     end
 end
 
 print("Animating scene...")
 
-local threads = {}
-for i = 1,jobs do
-    table.insert(threads, coroutine.wrap(render))
-end
+run("rm -rf frames && mkdir frames >/dev/null 2>&1")
+for render,frame in renderings() do render(frame) end
 
-os.execute("rm -rf frames && mkdir frames >/dev/null 2>&1")
-for i = 0,(frames-1) do
-    threads[1 + (i % jobs)](i)
-end
-for _,thread in ipairs(threads) do thread(null) end
 print()
 
-if os.execute("ffmpeg -i frames/anim%04d.bmp -b 1024k -y -an scene.avi") == 0 then
+if run("ffmpeg -i frames/anim%%04d.bmp %s -y -an scene.avi", ffmpeg_opts) == 0 then
     print("Animation written to scene.avi.")
 end
 
This page took 0.018627 seconds and 4 git commands to generate.