Skip to content

Commit

Permalink
PerspectiveMotion, Util: Move line2fbf function to a separate Util mo…
Browse files Browse the repository at this point in the history
…dule
  • Loading branch information
arch1t3cht committed Jan 22, 2024
1 parent 5df7a6f commit adcfce9
Show file tree
Hide file tree
Showing 3 changed files with 264 additions and 182 deletions.
51 changes: 51 additions & 0 deletions DependencyControl.json
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,12 @@
"name": "Perspective",
"url": "https://github.com/TypesettingTools/arch1t3cht-Aegisub-Scripts",
"version": "1.1.0"
},
{
"moduleName": "arch.Util",
"name": "Util",
"url": "https://github.com/TypesettingTools/arch1t3cht-Aegisub-Scripts",
"version": "0.1.0"
}
]
}
Expand All @@ -219,6 +225,9 @@
],
"0.1.4": [
"Various fixes and improvements to the line2fbf logic (more robust transform handling, fixing transforms of colors and rect clips, fixing fades for lines without alpha tags)"
],
"0.1.5": [
"Move line2fbf function to a separate Util module"
]
}
},
Expand Down Expand Up @@ -639,6 +648,48 @@
"Export an_xshift and an_yshift"
]
}
},
"arch.Util": {
"fileBaseUrl": "@{fileBaseUrl}/modules/@{namespacePath}",
"url": "@{baseUrl}#@{namespace}",
"author": "arch1t3cht",
"name": "Util",
"description": "Utility functions used in some of my scripts",
"channels": {
"release": {
"version": "0.1.0",
"released": "2024-01-22",
"default": true,
"files": [
{
"name": ".moon",
"url": "@{fileBaseUrl}@{fileName}",
"sha1": ""
}
],
"requiredModules": [
{
"moduleName": "a-mo.Line",
"version": "1.5.3",
"name": "Aegisub-Motion (Line)",
"url": "https://github.com/TypesettingTools/Aegisub-Motion",
"feed": "@{feed:a-mo}"
},
{
"moduleName": "l0.ASSFoundation",
"name": "ASSFoundation",
"url": "https://github.com/TypesettingTools/ASSFoundation",
"version": "0.5.0",
"feed": "https://raw.githubusercontent.com/TypesettingTools/ASSFoundation/master/DependencyControl.json"
}
]
}
},
"changelog": {
"0.1.0": [
"Initial Release with line2fbf function"
]
}
}
}
}
187 changes: 5 additions & 182 deletions macros/arch.PerspectiveMotion.moon
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@ export script_name = "Aegisub Perspective-Motion"
export script_description = "Apply perspective motion tracking data"
export script_author = "arch1t3cht"
export script_namespace = "arch.PerspectiveMotion"
export script_version = "0.1.4"
export script_version = "0.1.5"

DependencyControl = require "l0.DependencyControl"
dep = DependencyControl{
feed: "https://raw.githubusercontent.com/TypesettingTools/arch1t3cht-Aegisub-Scripts/main/DependencyControl.json",
{
{"a-mo.Line", version: "1.5.3", url: "https://github.com/TypesettingTools/Aegisub-Motion",
feed: "https://raw.githubusercontent.com/TypesettingTools/Aegisub-Motion/DepCtrl/DependencyControl.json"},
{"a-mo.LineCollection", version: "1.3.0", url: "https://github.com/TypesettingTools/Aegisub-Motion",
feed: "https://raw.githubusercontent.com/TypesettingTools/Aegisub-Motion/DepCtrl/DependencyControl.json"},
{"l0.ASSFoundation", version: "0.5.0", url: "https://github.com/TypesettingTools/ASSFoundation",
Expand All @@ -18,10 +16,12 @@ dep = DependencyControl{
feed: "https://raw.githubusercontent.com/TypesettingTools/arch1t3cht-Aegisub-Scripts/main/DependencyControl.json"},
{"arch.Perspective", version: "1.1.0", url: "https://github.com/TypesettingTools/arch1t3cht-Aegisub-Scripts",
feed: "https://raw.githubusercontent.com/TypesettingTools/arch1t3cht-Aegisub-Scripts/main/DependencyControl.json"},
{"arch.Util", version: "0.1.0", url: "https://github.com/TypesettingTools/arch1t3cht-Aegisub-Scripts",
feed: "https://raw.githubusercontent.com/TypesettingTools/arch1t3cht-Aegisub-Scripts/main/DependencyControl.json"},
"aegisub.clipboard",
}
}
Line, LineCollection, ASS, AMath, APersp, clipboard = dep\requireModules!
LineCollection, ASS, AMath, APersp, Util, clipboard = dep\requireModules!
{:Point, :Matrix} = AMath
{:Quad, :an_xshift, :an_yshift, :relevantTags, :usedTags, :transformPoints, :tagsFromQuad, :prepareForPerspective} = APersp

Expand All @@ -31,183 +31,6 @@ die = (errmsg) ->
aegisub.log(errmsg .. "\n")
aegisub.cancel!

-- rounds a ms timestamp to cs just like Aegisub does
round_to_cs = (time) ->
(time + 5) - (time + 5) % 10

-- gets the exact starting timestamp of a given frame,
-- unlike aegisub.frame_from_ms, which returns a timestamp in the
-- middle of the frame suitable for a line's start time.
exact_ms_from_frame = (frame) ->
frame += 1

ms = aegisub.ms_from_frame(frame)
while true
new_ms = ms - 1
if new_ms < 0 or aegisub.frame_from_ms(new_ms) != frame
break

ms = new_ms

return ms - 1

-- line2fbf function, modified from a function by PhosCity
line2fbf = (sourceData, cleanLevel = 3) ->
line, effTags = sourceData.line, (sourceData\getEffectiveTags -1, true, true, false).tags
-- Aegisub will never give us timestamps that aren't rounded to centiseconds, but lua code might.
-- Explicitly round to centiseconds just to be sure.
startTime = round_to_cs line.start_time
startFrame = line.startFrame
endFrame = line.endFrame

-- Tag Collection
local fade
-- Fade
for tag in *{"fade_simple", "fade"}
fade = sourceData\getTags(tag, 1)[1]
break if fade

-- Transform
transforms = sourceData\getTags "transform"
tagSections = {}
sectionEffTags = {}
sourceData\callback ((section, _, i, j) ->
tagSections[i] = j
sectionEffTags[i] = (section\getEffectiveTags true).tags
), ASS.Section.Tag

-- Fbfing
fbfLines = {}
for frame = startFrame, endFrame-1
newLine = Line sourceData.line, sourceData.line.parentCollection
newLine.start_time = aegisub.ms_from_frame(frame)
newLine.end_time = aegisub.ms_from_frame(frame + 1)
data = ASS\parse newLine
now = exact_ms_from_frame(frame) - startTime

-- Move
move = effTags.move
if move and not move.startPos\equal move.endPos
t1, t2 = move.startTime.value, move.endTime.value

-- Does assf handle this for us already? Who knows, certainly not me!
t1 or= 0
t2 or= 0

t1, t2 = t2, t1 if t1 > t2

if t1 <= 0 and t2 <= 0
t1 = 0
t2 = line.duration

local k
if now <= t1
k = 0
elseif now >= t2
k = 1
else
k = (now - t1) / (t2 - t1)

finalPos = move.startPos\lerp(move.endPos, k)
data\removeTags "move"
data\replaceTags {ASS\createTag "position", finalPos}

-- Transform
if #transforms > 0
currValue = {}
data\removeTags "transform"
for tr in *transforms
sectionIndex = tr.parent.index
tagIndex = tagSections[sectionIndex]

t1 = tr.startTime\get!
t2 = tr.endTime\get!

t2 = line.duration if t2 == 0

accel = tr.accel\get! or 1

local k
if now < t1
k = 0
elseif now >= t2
k = 1
else
k = ((now - t1) / (t2 - t1))^accel

for tag in *tr.tags\getTags!
-- FIXME this still breaks in a case like \t(\frx10)\frx20\t(\frx30)
-- but that's extremely niche so I'm not fixing it now
tagname = tag.__tag.name
currValue[tagIndex] or= {}
currValue[tagIndex][tagname] or= sectionEffTags[sectionIndex][tagname]
local finalValue

if tag.class == ASS.Tag.Color
finalValue = currValue[tagIndex][tagname]\copy!
for channel in *{"r", "g", "b"}
finalValue[channel] = finalValue[channel]\lerp tag[channel], k
elseif tag.class == ASS.Tag.ClipRect
-- ClipRect\lerp exists but does not return the resulting clip. If and when this gets fixed, this can be removed
finalValue = currValue[tagIndex][tagname]\copy!
for pt in *{"topLeft", "bottomRight"}
finalValue[pt] = finalValue[pt]\lerp tag[pt], k
else
finalValue = currValue[tagIndex][tagname]\lerp tag, k

data\replaceTags finalValue, tagIndex, tagIndex, true
currValue[tagIndex][tagname] = finalValue

-- Fade
if fade
local a1, a2, a3, t1, t2, t3, t4
if fade.__tag.name == "fade_simple"
a1, a2, a3 = 255, 0, 255
t1, t4 = -1, -1
t2, t3 = fade.inDuration\getTagParams!, fade.outDuration\getTagParams!
else
a1, a2, a3, t1, t2, t3, t4 = fade\getTagParams!

if t1 == -1 and t4 == -1
t1 = 0
t4 = line.duration
t3 = t4 - t3

local fadeVal
if now < t1
fadeVal = a1
elseif now < t2
k = (now - t1)/(t2 - t1)
fadeVal = a1 * (1 - k) + a2 * k
elseif now < t3
fadeVal = a2
elseif now < t4
k = (now - t3)/(t4 - t3)
fadeVal = a2 * (1 - k) + a3 * k
else
fadeVal = a3

data\removeTags {"fade", "fade_simple"}

-- Insert all alpha tags so we can modify them later
-- Don't bother with checking if they exist already, cleanTags will do that for us later
alphaTags = data\getDefaultTags!\filterTags [ "alpha#{k}" for k=1,4 ]
if alphaTags.tags.alpha1.value == alphaTags.tags.alpha2.value and alphaTags.tags.alpha1.value == alphaTags.tags.alpha3.value and alphaTags.tags.alpha1.value == alphaTags.tags.alpha4.value
alphaTags = {ASS\createTag "alpha", alphaTags.tags.alpha1.value}

data\insertTags alphaTags, 1, 1

data\modTags {"alpha", "alpha1", "alpha2", "alpha3", "alpha4"}, ((tag) ->
tag.value = tag.value - (tag.value * fadeVal - 0x7F) / 0xFF + fadeVal
tag.value = math.max(0, math.min(255, tag.value))
) if fadeVal > 0

data\cleanTags cleanLevel
data\commit!
table.insert fbfLines, newLine

return fbfLines


track = (quads, options, subs, sel, active) ->
lines = LineCollection subs, sel, () -> true
Expand All @@ -221,7 +44,7 @@ track = (quads, options, subs, sel, active) ->

table.insert to_delete, line

fbf = line2fbf data
fbf = Util.line2fbf data
for fbfline in *fbf
lines\addLine fbfline
), true
Expand Down
Loading

0 comments on commit adcfce9

Please sign in to comment.