X-Git-Url: https://git.dogcows.com/gitweb?p=chaz%2Frasterize;a=blobdiff_plain;f=animate.lua;fp=animate.lua;h=d04f5df539a98bd00bbad77de0ee65c495d5bee3;hp=0000000000000000000000000000000000000000;hb=e16cf0578f4baaf879e4ab9d3528a765bfd29be0;hpb=db44364a1fabda81d3f6c842c4e4778eac6495a5 diff --git a/animate.lua b/animate.lua new file mode 100755 index 0000000..d04f5df --- /dev/null +++ b/animate.lua @@ -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 +