¡Olé! Make

全体的に備忘録。

AviUtlスクリプトと和解せよ その3 コード解読編1

ライン(移動軌跡)のコードを見る会

前回より、AviUtl拡張編集Pluginで入手出来るスクリプトのコードについては自由に扱ってよいと解釈した。という訳でまずはドン。

コード

--track0:ライン幅,2,200,16
--track1:先端,0,500,48
--track2:固定速度,0,100,0,0.01
--track3:描画間隔,0,400,10
--dialog:色/col,col=0xffffff;先端図形/fig,fig="三角形";先端位置補正(%),f_pos=70;最小間隔(dot),min_step=2;主線描画(%),c_size=100;補助描画(%),l_size=0;
-- ライン部分
base_x = obj.getvalue("x")
base_y = obj.getvalue("y")
obj.load("figure","円",col,obj.track0)
obj.effect()
obj.ox = obj.ox-base_x
obj.oy = obj.oy-base_y
w2 = obj.w/2
h2 = obj.h/2
t = 0;
f = 0;
l = 0;
n = 1;
d = 0
s = w2*obj.track3/50;
if( s < min_step ) then
    s = min_step
end
if( s < 1 ) then
    s = 1
end
ex = obj.getvalue("x",0)
ey = obj.getvalue("y",0)
x0 = ex
y0 = ey
while( t < obj.time ) do
    r = s
    while( r > 0 ) do
        if( l <= 0 ) then
            if( t >= obj.time ) then
                break
            end
            sx = ex
            sy = ey
            f = f+1
            t = f/obj.framerate
            ex = obj.getvalue("x",t)
            ey = obj.getvalue("y",t)
            l = math.sqrt((ex-sx)*(ex-sx)+(ey-sy)*(ey-sy))
            n = l
        end
        if( l > r ) then
            d = d+r
            l = l-r
            r = 0;
            x1 = ex+(sx-ex)*l/n
            y1 = ey+(sy-ey)*l/n
        else
            d = d+l
            r = r-l
            l = 0
            x1 = ex
            y1 = ey
        end
        if( obj.track2 > 0 ) then
            if( t >= obj.totaltime ) then
                break
            end
            t = d/(obj.framerate*obj.track2)
        elseif( l > 0 ) then
            t = (f-l/n)/obj.framerate
        end
    end
    if( c_size > 0 ) then
        lx = w2*c_size/100
        ly = w2*c_size/100
        obj.drawpoly(x0-lx,y0-ly,0,x0+lx,y0-ly,0,x0+lx,y0+ly,0,x0-lx,y0+ly,0, 0,0,obj.w,0,obj.w,obj.h,0,obj.h)
    end
    if( l_size > 0 ) then
        r = math.atan2(y1-y0,x0-x1)
        lx = math.sin(r)*w2*l_size/100
        ly = math.cos(r)*w2*l_size/100
        obj.drawpoly(x0-lx,y0-ly,0,x0+lx,y0+ly,0,x1+lx,y1+ly,0,x1-lx,y1-ly,0, 0,h2,obj.w,h2,obj.w,h2,0,h2)
    end
    x0 = x1
    y0 = y1
end
if( obj.track2 > 0 ) then
    t = (f-l/n)/obj.framerate
else 
    t = obj.time;
    x0 = base_x
    y0 = base_y
end
obj.drawpoly(x0-w2,y0-h2,0,x0+w2,y0-h2,0,x0+w2,y0+h2,0,x0-w2,y0+h2,0, 0,0,obj.w,0,obj.w,obj.h,0,obj.h)
obj.ox = obj.ox+base_x
obj.oy = obj.oy+base_y
-- 先端部分
if( obj.track1 > 0 ) then
    obj.load("figure",fig,col,obj.track1)
    obj.effect()
    obj.ox = obj.ox-base_x
    obj.oy = obj.oy-base_y
    r = 0
    l = 4*4
    s = t
    e = t
    t = 0.5/obj.framerate
    while( s > 0 or e < obj.totaltime ) do
        s = s-t
        e = e+t
        if( s < 0 ) then
            s = 0
        end
        if( e > obj.totaltime ) then
            e = obj.totaltime
        end
        x = obj.getvalue("x",s)-obj.getvalue("x",e)
        y = obj.getvalue("y",s)-obj.getvalue("y",e)
        if( math.sqrt(x*x+y*y) >= l ) then
            r = math.atan2(x,y)
            break
        end
    end
    x0 = x0-math.sin(r)*obj.h*(f_pos-50)/100
    y0 = y0-math.cos(r)*obj.h*(f_pos-50)/100
    sx = math.sin(r)*obj.w/2
    cx = math.cos(r)*obj.w/2
    sy = math.sin(r)*obj.h/2
    cy = math.cos(r)*obj.h/2
    obj.drawpoly(x0-cx-sy,y0+sx-cy,0,x0+cx-sy,y0-sx-cy,0,x0+cx+sy,y0-sx+cy,0,x0-cx+sy,y0+sx+cy,0, 0,0,obj.w,0,obj.w,obj.h,0,obj.h)
    obj.ox = obj.ox+base_x
    obj.oy = obj.oy+base_y
end
obj.setoption("focus_mode","fixed_size")

オアー!(瀕死)

解読

…ひとまず上から見ていくことにする。なお所々に挟んでいる所感は概ね2023/03当時のものである。

トラックバーと値入力ダイアログ

--track0:ライン幅,2,200,16
--track1:先端,0,500,48
--track2:固定速度,0,100,0,0.01
--track3:描画間隔,0,400,10
--dialog:色/col,col=0xffffff;先端図形/fig,fig="三角形";先端位置補正(%),f_pos=70;最小間隔(dot),min_step=2;主線描画(%),c_size=100;補助描画(%),l_size=0;

これらはスクリプト用インターフェースを設定するための記述である。詳細は以下を参照。

aviutlscript.wiki.fc2.com

trackは以下画像の右側部分の内、「回転」より下の4項目(トラックバー)を好きな様に変更できる。都度変更するパラメーターがある場合はここを使用すればよいであろう。

dialogは上記画像の「設定」内の項目(値入力ダイアログ)を変更できる。要はコンフィグである。

先頭に--と記載されているが、これはLuaのコメント記法にあたる。なぜコメントアウトする必要があるのかと一瞬思ったが、そういうものだと思いなおすことにした。

トラックバーに設定した項目は、obj.track*という変数として使用できる。*には0~3の数字が対応する。値入力ダイアログに設定した項目はその後に続くcolfigを変数として使用できる。なお、これらは仕様上すべてグローバル変数として宣言されることになる。

続いて「ライン部分」とコメントされた部分以降を見ていく。

obj.getvalue

base_x = obj.getvalue("x")
base_y = obj.getvalue("y")

objと付くものはAviUtl専用に定義された変数や関数である。逐一WiKiを見るべし。

aviutlscript.wiki.fc2.com

「指定した時間のトラックバーの値を取得します」とな。なんのこっちゃと思ったが、上記をざっくりいくと、base_xは「ナウのx座標」、base_yは「ナウのy座標」を取得したことになる様だ。なぜは一旦置いておく。

obj.load

obj.load("figure","円",col,obj.track0)

aviutlscript.wiki.fc2.com

様々読み込みができるようだが、ここでは図形を読み込むモードが使われている。その後の引数はname、color、sizeと続いているので「col色の円をobj.track0サイズで読み込む」という操作をしている。で、後でobj.drawpolyで実際に描画をするのであろう。ちなみにライン(移動軌跡)は、実際は線ではなく円の集合体でラインを表現している。はえーあたまいい。

obj.effect()

obj.effect()

aviutlscript.wiki.fc2.com

フィルタ効果、要はエフェクトをかけるために必要なのだと思われる。随分中途半端な位置にあるなと思ったがそういうもんだと(以下略)。

obj.ox,obj.oy

obj.ox = obj.ox-base_x
obj.oy = obj.oy-base_y

aviutlscript.wiki.fc2.com

基準座標からの相対座標である。オーン。で、基準座標とはobj.xobj.yである。つまりトラックバーのxやyである。オーン。とまあ当時(2023/03)は仕様をよく理解していなかった。そのため現相対座標から現基準座標を引く理由が分からぬ。このツケの結果は後日紹介する

obj.w,obj.h

w2 = obj.w/2
h2 = obj.h/2

aviutlscript.wiki.fc2.com

名前の通り、オブジェクトの幅と高さである。ここでは上でロードした円の情報を取得し、その半分の値をw2h2に代入している。何に使うかは後で分かるであろう。

変数群その1

t = 0;
f = 0;
l = 0;
n = 1;
d = 0
s = w2*obj.track3/50;

ン゙ン゙ン゙ン゙

謎の変数初期化祭りにたどり着いた。唯一sについては「円の幅に描画間隔を掛け50で割る」計算をしていることは分かった。意味が分かったとは言っていない。ひとまず後のコードを見てから考えることにする。

制御文その1

if( s < min_step ) then
    s = min_step
end
if( s < 1 ) then
    s = 1
end

aviutlscript.wiki.fc2.com

これを見た時の感情は外国で道に迷ったときに日本語の看板を見つけた時の安心感に似ていた(?)。こういうのでいいんだよ。ただし意味が分かったとは(以下略)。変数smin_step(初期値2)より小さければ強制的にmin_stepにする。さらにそれが2より小さければ強制的に1にする。

コーヒーブレイク

大分頭も厳しくなってきたので、ここで改めて動作確認を行う。特にトラックバー、ダイアログ、sあたりは何かつかめるかもしれない。

ライン幅

track0。文字通り線幅が変わる。

先端

track1。先端サイズが変わる。

固定速度

track2。分かりにくいがフレーム毎の移動距離が変わる。

描画間隔

track3。円の設置間隔が変わる。

dialogcol。カラーパレットがガビガビなのはご愛敬。

先端図形

dialogfig。未紹介。矢印はこの三角形で表現していた。

先端位置補正

dialogf_pos。未紹介。図形の中心が描画の中心という訳では無い様子。

最小間隔

dialogmin_step1 < min_stepの時に円同士の最小間隔に指定される。

主線描画

dialogc_size。未紹介。これも結局の所線の幅が変わる。

補助描画

dialogl_size。未紹介。新しく線が生えてくる。半点線の様なものが描画出来る。

一旦まとめ

26/130にしてこの文量となってしまったため、キリも良いので残りは次回に回す。ともあれトラックバーとダイアログが何者か、記すことはできたのでよし。以上。