]> Dogcows Code - chaz/rasterize/blobdiff - animate.lua
add scene lighting constructs; real stdin support
[chaz/rasterize] / animate.lua
diff --git a/animate.lua b/animate.lua
new file mode 100755 (executable)
index 0000000..d04f5df
--- /dev/null
@@ -0,0 +1,110 @@
+#!/usr/bin/env lua
+
+--
+-- CS5600 University of Utah
+-- Charles McGarvey
+-- mcgarvey@eng.utah.edu
+--
+
+-- This program that draws a scene multiple times from different camera angles
+-- and positions.  The rasters are saved in the `frames' directory, and if
+-- ffmpeg is installed, they will also be combined into a video file.  The
+-- camera will make a full rotation along the X and Z axes, around a specified
+-- point (center), all the while looking at some other point (look).
+-- This must be called from the same directory where the rasterize program is.
+
+local size      = {w = 640, h = 480}    -- width and height of the viewport
+local frames    = 512                   -- number of animation frames
+
+local look      = {x = 2, y = 1, z = 2} -- the point to look at
+local center    = {x = 0, y = 1, z = 0} -- center of rotation
+local distance  = 4                     -- the distance from the center
+local start     = math.pi               -- where is the first frame
+
+local jobs      = 6                     -- number of concurrent renderings
+
+-- the actual objects of the scene that will be drawn:
+local scene = [[
+L 0 1000000 0 1 1 1 1 1 1
+L 0 0 1000000 1 1 1 1 1 1
+g triangle.raw
+c 0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2 0.1
+t 2 0 -2
+s 1 1 1
+g dragon.raw
+c 0.7 0.3 0.2 0.8 0.2 0.1 0.9 0.2 0.2
+t -2 -1 -2
+s 2 2 2
+g budda.raw
+c 0.1 0.2 0.7 0.1 0.3 0.9 0.2 0.1 0.8
+t 2 -1.5 2
+s 10 10 10
+g bunny.raw
+c 0.9 0.8 0.9 0.8 0.7 0.9 0.9 0.8 0.7
+t -2 -1 2
+s 10 10 10
+g teapot2.raw
+c 0 1 0 0 1 0 0 1 0
+t 0 -1 0
+s 0.6 0.6 0.6
+]]
+
+
+function vec_add(a, b)
+    return {x = a.x + b.x, y = a.y + b.y, z = a.z + b.z}
+end
+
+function vec_scale(v, s)
+    return {x = v.x * s, y = v.y * s, z = v.z * s}
+end
+
+local fmt   = string.format
+local write = function(...) io.write(fmt(...)) end
+
+function render(i, v)
+    while i and v do
+        local filename  = fmt("frames/anim%04d.bmp", i)
+        local command   = fmt("./rasterize -o %s >/dev/null", filename)
+        local out = io.popen(command, "w")
+        write("\27[80D\27[2Kframe\t %4d / %d", i + 1, frames)
+        out:write(fmt([[
+U3
+%d %d
+%f %f %f
+%f %f %f
+0 1 0
+1.57 %f 0.1 1000
+%s
+X
+]], size.w, size.h, v.x, v.y, v.z, look.x, look.y, look.z, size.w/size.h, scene))
+        i, v = coroutine.yield()
+        out:close()
+    end
+end
+
+
+print("Animating scene...")
+
+local threads = {}
+for i = 1,jobs do
+    table.insert(threads, coroutine.wrap(render))
+end
+
+os.execute("rm -rf frames && mkdir frames >/dev/null 2>&1")
+for i = 0,(frames-1) do
+    local t = start + 2 * math.pi * i / frames
+    local v = {
+        x = math.cos(t),
+        y = 0,
+        z = math.sin(t),
+    }
+    v = vec_add(vec_scale(v, distance), center)
+    threads[1 + (i % jobs)](i, v)
+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
+    print("Animation written to scene.avi.")
+end
+
This page took 0.019817 seconds and 4 git commands to generate.