Aegisub dev
Join Date: Sep 2004
Location: Stockholm, Sweden
Age: 39
|
Quote:
Originally Posted by kooc
|
Here's a snippet of Lua code for Aegisub Automation, that moves something along a path, drawing a trail after it.
I wrote it for a remake of the KAA Full Moon o Sagashite OP effect. (Which will be used fom ep 8 on.)
It's basically about first defining the path, then simulating movement along it.
Code:
stars = {
-- most of the "stars" have been left out here
["circle-y"] = {
shape = "m 0 0 s 100 0 100 100 0 100 c",
starstyle = "\\1c&HC0FFFF&\\3c&H449337&",
textstyle = "\\bord1\\1c&HEDE6D1&\\3c&H996600&",
hlstyle = "\\1c&HEDE6D1&"
}
}
function do_star(meta, styles, config, line)
if line.karaoke.n < 3 then
return {n=0}
end
-- prepare the syllable data
local syls = {n=0}
for i = 1, line.karaoke.n-1 do
local syl = line.karaoke[i]
if syl.duration > 0 and del_spaces(syl.text_stripped) ~= "" then
table.insert(syls, syl)
end
end
local style = stars[(string.gsub(line.karaoke[0].text, "{\\%-(.-)}", "%1"))]
-- calculate the path to take
local movement = {n=2, [1]={x=0, y=0, t=0, r=0, s=0}, [2]={x=0, y=0, t=0, r=120, s=75}}
local dir, rot = 1, 120
for i = 1, syls.n do
local syl = syls[i]
if del_spaces(syl.text_stripped) ~= "" and syl.duration > 0 then
local timing = {}
timing.x = line.centerleft + syl.center
timing.y = line.styleref.margin_v+line.height
local dist = math.sqrt((timing.x-movement[movement.n].x)^2 + (timing.y-movement[movement.n].y)^2)
timing.r = rot + math.floor(dist/3)
rot = timing.r
timing.t = line.start_time*10 + syl.start_time - 10
timing.s = utf_len(syl.text_stripped)*300 - math.log(utf_len(syl.text_stripped))*200 + math.log(syl.duration)*15
table.insert(movement, timing)
timing = {x=timing.x, y=timing.y, s=timing.s, r=timing.r}
if (i < syls.n and syl.end_time ~= syls[i+1].start_time) or i == syls.n then
timing.t = line.start_time*10 + syl.end_time
else
timing.t = line.start_time*10 + syl.start_time + syl.duration*5
end
table.insert(movement, timing)
if i < syls.n and (syl.duration > 5 or syl.end_time ~= syls[i+1].start_time) then
timing = {}
timing.x = line.centerleft + syls[i+1].center/2 + syl.center/2
timing.y = line.styleref.margin_v + line.height + line.height*dir/3
dist = math.sqrt((timing.x-movement[movement.n].x)^2 + (timing.y-movement[movement.n].y)^2)
timing.r = rot + math.floor(dist/3)
timing.s = movement[movement.n].s
rot = timing.r
if syl.end_time ~= syls[i+1].start_time then
timing.t = line.start_time*10 + syl.end_time/2 + syls[i+1].start_time/2
else
timing.t = line.start_time*10 + syl.end_time - 25
end
table.insert(movement, timing)
end
dir = dir * -1
end
end
table.insert(movement, {
x=movement[movement.n].x+syls[syls.n].width*2,
y=movement[movement.n].y,
r=rot+360,
s=125,
t=movement[movement.n].t + config.starleavetime*5
})
table.insert(movement, {
x=meta.res_x,
y=0,
r=rot+720,
s=0,
t=movement[movement.n].t + config.starleavetime*5
})
-- fix entry stuff
movement[2].x = movement[3].x/2
movement[2].y = movement[3].y - line.height/3
movement[2].t = movement[3].t - config.starentrytime*5
movement[1].t = movement[2].t - config.starentrytime*5
-- generate star
local result, last = {n=0}, movement[1]
for i = 2, movement.n do
-- make a moving star between the points
local star, move = copy_line(line), movement[i]
star.layer = 50
star.start_time = last.t/10
star.end_time = move.t/10
star.text = string.format("{\\an5\\be1\\move(%d,%d,%d,%d)\\frz%.1f\\fscx%d\\fscy%d\\t(\\frz%.1f\\fscx%d\\fscy%d)}{%s}{\\p3}%s", last.x, last.y, move.x, move.y, last.r, last.s, last.s, move.r, move.s, move.s, style.starstyle, style.shape)
table.insert(result, star)
-- make some static fading out ghosts between points
local dist, dur = math.sqrt((move.x-last.x)^2 + (move.y-last.y)^2), (move.t-last.t)/10
local vel = dist / dur -- pixels per centisecond
local numghosts = math.ceil(dist / config.ghostdist)
local vect = {x=(move.x-last.x)/dur, y=(move.y-last.y)/dur} -- direction vector for the movement
for j = 1, numghosts do
local totaldist = j * config.ghostdist
local ctime = totaldist / vel
local x, y = vect.x*ctime+last.x, vect.y*ctime+last.y
local ghost = copy_line(star)
local rot = (move.r - last.r) * j / numghosts + last.r
local size = (move.s - last.s) * j / numghosts + last.s
ghost.text = string.format("{\\an5\\be1\\bord0\\pos(%d,%d)\\1a&HE0&\\3a&HE0&\\t(\\1a&HFF&\\3a&HFF&)\\frz%.2f\\fscx%d\\fscy%d}{%s}{\\p3}%s", x, y, rot, size, size, style.starstyle, style.shape)
ghost.start_time = last.t/10 + ctime
ghost.end_time = ghost.start_time + config.ghosttime
ghost.layer = 25
table.insert(result, ghost)
end
last = move
star.text = "{\\bord1}" .. star.text
end
return result
end
(Note that the code IIRC depends on changes in the yet-unreleased 1.07 of Aegisub.)
Last edited by jfs; 2005-12-25 at 11:50.
|