View Single Post
Old 2005-12-23, 12:46   Link #94
jfs
Aegisub dev
 
 
Join Date: Sep 2004
Location: Stockholm, Sweden
Age: 39
Quote:
Originally Posted by kooc
hi, how to do this? http://img439.imageshack.us/img439/4153/gsdkar0dw.jpg

in motion, syllables move along path; blur is probably just multiple layers w/ different alpha-- problem is path motion, so smooth
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.)
__________________

Aegisub developer [ Forum | Manual | Feature requests | Bug reports | IRC ]
Don't ask for: More VSFilter changes (I won't), karaoke effects, help in PM's

Last edited by jfs; 2005-12-25 at 11:50.
jfs is offline   Reply With Quote