Releases: routersys/YMM4-LuaScript
v1.4.0
v1.4.0 - Lua スクリプト for YMM4
AviUtl のアニメーション効果スクリプト(.anm 系)に対する部分互換層を追加した
リリースです。座標・拡縮・回転・不透明度の変形と乱数を用いる範囲について、追加の
記述変更なしで AviUtl 向けスクリプトを実行できるようになりました。
新機能
1. AviUtl スクリプトの部分互換
AviUtl のアニメーション効果スクリプトのうち、本プラグインの変形・ピクセルモデルへ
無理なく写像できる範囲を実行できる互換層を追加しました。スクリプトに AviUtl 固有の
記法が含まれない場合、この互換層は一切介入しないため、従来のスクリプトの挙動は
変わりません。
- スクリプトヘッダの解釈: コメント形式のパラメータ宣言を解釈し、スクリプト本体が
参照する変数を実行前に定義します。これまでは単なるコメントとして無視され、参照変数が
nilになり実行できなかったスクリプトが動作するようになります。--dialog:項目名,local 変数=既定値;…… 各項目の宣言部を本体の先頭へ展開します。--color:0xRRGGBB… 変数colorを指定色で定義します。--check0:項目名,既定値…obj.check0(0〜3)を既定値で定義します。--param:任意のLua文… 記述した Lua 文をそのまま本体の先頭へ展開します。--track0:〜--track3:… 値は従来どおりobj.track0〜obj.track3から参照します
(ラベル・範囲・既定値の UI 反映は行いません)。
@による複数セクション: 1 つのスクリプトに@名前で複数の効果が定義されて
いる場合、先頭のセクションのみを実行します。
2. obj.rand の追加
AviUtl 互換の決定論的な整数乱数 obj.rand(st, ed [, seed [, frame]]) を追加しました。
指定範囲 st〜ed の整数を返し、seed と frame が同じであれば常に同じ値を返します。
frame を省略すると現在のフレームを用います。従来エンジン(MoonSharp)と高速ランタイム
(LuaJIT)で同じ値を返すため、エンジンの自動振り分けによらず結果が一致します。
注意事項
- 描画・フィルタ・ファイルアクセス系の関数(
obj.load/obj.draw/obj.drawpoly/
obj.effect/obj.copybuffer/obj.setoption/obj.setfont、require、io等)は
本体の描画パイプラインへの統合を要するため、この互換層では対象外です。これらを呼び出す
スクリプトは意図どおりには動作しません。 --track0:〜--track3:のラベル・範囲・既定値はエフェクトパネルの UI へ反映されません。
トラックバーの値は従来どおり Track0〜Track3 のスライダー値が使用されます。- エンジンに依存しない小数の乱数が必要な場合は、従来どおり
anim.randを使用してください。
内部実装
- スクリプトを実行可能な Lua へ変換する前処理を追加し、MoonSharp・LuaJIT の両実行系へ
一貫して適用しました。変換結果はソース単位でキャッシュし、毎フレームの再解析を避けています。 obj.randの数値コアを C# と LuaJIT で同一アルゴリズムとして実装し、両者がビット単位で
一致することを等価性テストで検証しています。- AviUtl 固有の記法を含まないスクリプトでは前処理がソースをそのまま返すため、既存スクリプト
および既存の実行・キャッシュ経路に対する影響はありません。
v1.3.4
v1.3.4 - Lua スクリプト for YMM4
ネイティブ実行中の obj.getobject を高速化したリリースです。
同じオブジェクトを繰り返し参照するスクリプトで、本体プロセスへの問い合わせ回数を
削減し、大幅に高速化しました。
改善
1. 同一オブジェクト参照のキャッシュによる高速化
ネイティブ実行中の obj.getobject は、解決に必要なシーン情報が本体プロセス側にしか
存在しないため、呼び出しごとに本体プロセスへの問い合わせ(往復)を伴います。この往復は
1 回あたりのコストが大きく、同じオブジェクトをループ内で繰り返し参照すると無視できない
負荷になっていました。
本リリースでは、同じタグ・同じフレームへの連続した問い合わせをフレーム内でキャッシュ
するようにしました。2 回目以降は本体への往復を行わずにキャッシュした結果を返すため、
同一オブジェクトを繰り返し参照するスクリプトでは問い合わせ回数が 1 回に削減されます。
内部計測では、該当パターンが 1000 倍以上高速化することを確認しています。返り値は従来
どおり呼び出しごとに新しいテーブルであり、出力結果は変わりません。
注意事項
- キャッシュが効くのは、同じタグ・同じフレームへの連続した問い合わせです。毎回異なる
オブジェクトやフレームを参照する場合は、その都度本体プロセスへの往復が発生します。
この場合は結果を変数へ保持して呼び出し回数を抑えることを推奨します。
内部実装
- ワーカー側に直前の問い合わせ結果のキャッシュを設け、同一タグ・同一フレームへの連続
呼び出しでは本体への往復を省きます。キャッシュは各フレームの実行開始時に破棄されるため、
フレームをまたいで古い結果が再利用されることはありません。 - 本体側ではタグ文字列の確保を使い回し、問い合わせごとのアロケーションを抑えることで、
長時間の出力における GC 負荷を軽減しました。
v1.3.3
v1.3.3 - Lua スクリプト for YMM4
これまでネイティブ実行では使用できなかった obj.getobject がネイティブ実行でも
利用可能になったリリースです。ピクセル操作と他オブジェクトの参照を 1 つの
スクリプトで併用できるようになりました。
新機能・改善
1. obj.getobject をネイティブ実行でも利用可能に
ピクセル操作を含むスクリプトはネイティブ実行へ振り分けられますが、これまでは
ネイティブ実行中の obj.getobject が常に nil を返していました。本リリースでは、
ネイティブ実行中に obj.getobject を呼び出すと本体プロセスへ同期的に問い合わせて
シーンオブジェクトを解決するようにしました。従来エンジンと同じ描画情報を返すため、
ピクセル操作と他オブジェクトの参照を 1 つのスクリプトで併用できます。
--!moonsharp を明示してエンジンを切り替える必要はなくなりました。
注意事項
- ネイティブ実行中の
obj.getobjectは、呼び出しごとに本体プロセスへの往復が
発生します。1 フレーム内で多数のオブジェクトを参照する場合は、結果を変数へ
保持して呼び出し回数を抑えることを推奨します。 obj.getobjectを含むスクリプトの実行時間も、従来どおり 5 秒のタイムアウトの
対象です。問い合わせを含めた総実行時間が 5 秒を超えると強制終了されます。
内部実装
- ネイティブ実行の共有メモリプロトコルに同期コールバックを追加しました。ワーカーは
obj.getobjectの呼び出し時にタグとフレームを共有メモリへ書き込み、本体側が
シーンオブジェクトを解決して結果を書き戻します。解決したオブジェクトは
描画キャッシュの検証対象に含めるため、フレーム間のキャッシュ整合性は保たれます。 - コールバックを含む実行全体に対して単一の実行期限を適用し、
obj.getobjectを
繰り返し呼び出すスクリプトでもタイムアウトが必ず機能するようにしました。
v1.3.2
v1.3.2 - Lua スクリプト for YMM4
ピクセル操作スクリプトの実行に使う高速ランタイム(LuaJIT)のプロセスが残留する
不具合を解消したリリースです。YMM4 本体が異常終了・強制終了した場合でも、
ネイティブ実行用の luajit.exe が取り残されることはなくなりました。
あわせて、同梱ライブラリのライセンス表記を整備しました。
修正・改善
1. ネイティブ実行プロセスの残留を解消
これまで、ピクセル操作スクリプトを一度でも実行した後に YMM4 本体がクラッシュや
強制終了で落ちると、ネイティブ実行用の luajit.exe がプロセスとして残り続ける
ことがありました。本リリースでは、子プロセスを Windows のジョブオブジェクトへ
割り当て、本体プロセスの終了と同時に luajit.exe も終了するようにしました。
本体が正常終了したかクラッシュしたかにかかわらず、OS がジョブを閉じた時点で
ネイティブワーカーは確実に終了します。タスクマネージャーに luajit.exe が
取り残されることはありません。スクリプトの実行結果や速度に変化はありません。
2. 同梱ライブラリのライセンスを整備
プラグインが同梱する LuaJIT と MoonSharp のライセンス全文を収録しました。
配布パッケージのルートに LICENSE フォルダーを設け、各ライセンスファイルを
配置しています。LuaJIT のライセンスには、LuaJIT 本体が内包する Lua 5.1/5.2 と
dlmalloc の権利表記も含まれます。
内部実装
- 子プロセス起動時に、
JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSEを設定したプロセス
単位のジョブオブジェクトへluajit.exeを割り当てます。本体プロセスの終了で
ジョブハンドルが閉じられると、ジョブ内の全プロセスがカーネルによって終了します。 - 従来の正常終了時のシャットダウン処理はそのまま残しており、ジョブオブジェクトは
異常終了時の安全網として機能します。 - 収録した各ライセンスファイルは、配布元の原本から逐語的に取得しています。
同梱物
LICENSEフォルダーにLuaJIT.txt/Lua.txt/MoonSharp.txtを同梱し、
リリースワークフローで配布パッケージへ自動的に含めます。- 高速ランタイム(
luajit.exe/lua51.dll)と実行スクリプトは従来どおり、
プラグイン本体と同じnativeフォルダーに配置されます。
v1.3.1
v1.3.1 - Lua スクリプト for YMM4
YukkuriMovieMaker4 向けのLua スクリプトプラグインの更新版です。
プラグインの配布元を識別するためのプラグイン情報を追加しました。
変更点
1. プラグイン情報を追加
エフェクトにプラグイン情報(作者名とニコニ・コモンズ ID)を付与しました。YMM4 がプラグインのニコニ・コモンズ IDを識別できるようになります。エフェクトの機能や既定値に変更はありません。
v1.3.0
v1.3.0 - Lua スクリプト for YMM4
ピクセル操作スクリプトを大幅に高速化したリリースです。
obj.getpixel / obj.setpixel / obj.getpixeldata を使うスクリプトは、同梱した高速
ランタイム(LuaJIT)で自動的に実行されるようになり、内部計測では最大で数十倍
(例:1920×1080 のフルフレーム加工で約 41 倍、小さめの画像では 70 倍前後)の
高速化を確認しています。
新機能・改善
1. ピクセル操作スクリプトの自動高速化
ピクセル操作 API(obj.getpixel / obj.setpixel / obj.getpixeldata)を含むスクリプトは、
特別な記述なしで自動的に高速ランタイム(ネイティブ実行)へ振り分けられます。
変形のみ(座標・回転・拡縮・不透明度)のスクリプトは従来どおりの実行系で動作します
(変形のみの処理は元々十分高速なため、速度差はありません)。
ネイティブ実行は専用の別プロセスで行われ、ピクセルバッファは共有メモリ経由で
受け渡されます。スクリプトが無限ループに陥っても、5 秒のタイムアウトで強制終了
され、本体が固まることはありません(終了後は自動的に復帰します)。
2. 実行エンジンを指定するディレクティブ
スクリプトの先頭行に次のディレクティブを書くことで、実行エンジンを明示指定できます。
--!native… 高速ランタイム(LuaJIT)で実行--!moonsharp… 従来エンジン(MoonSharp)で実行- 記述なし … ピクセル操作を含む場合は自動的にネイティブ、それ以外は従来エンジン
3. bit32 の Lua 5.2 準拠化(ネイティブ実行時)
ネイティブ実行時の bit32 ライブラリは、正しい Lua 5.2 の挙動になりました。
実用域(0〜2^31 未満の値、0〜31 のシフト量)では従来と完全に一致するため、
通常のスクリプトの見た目は変わりません。bit32.lshift(1, 32) のような範囲外の
特殊なケースのみ結果が変わります(ネイティブ=正しい 0、従来=1)。
4. 変形処理のアロケーション削減
毎フレームの実行で発生していた一時オブジェクトの確保を削減し、シーンオブジェクトの
解決を遅延化しました。長時間の出力における GC 負荷を軽減します。
注意事項(ネイティブ実行時の制約)
obj.getobjectはネイティブ実行では使用できません(常にnilを返します)。
他オブジェクトの参照を行うスクリプトには--!nativeを付けないでください
(ピクセル操作と併用する場合は--!moonsharpを明示してください)。math.randomは両エンジンとも「フレーム番号でシードし直す決定論的乱数」ですが、
乱数列の実装が異なるため、エンジンをまたぐと同じシードでも値が変わります。
エンジンに依存しない乱数が必要な場合はanim.rand(min, max, seed)を使用してください。- ネイティブ実行は最初のピクセルアクセス前から GPU→CPU の画像転送を行います。
内部実装
- 同梱した LuaJIT を別プロセスで常駐させ、名前付き共有メモリとイベントで往復します。
タイムアウト時はプロセスを強制終了し、自動的に再起動します。 - ネイティブ側に
bit32(正しい 5.2)・rawlen・anim.*(rand/noiseを含む)・
obj.getpixel/setpixel/getpixeldataを実装し、従来エンジンとの出力一致を
自動テストで検証しています(2800 件超のクロスエンジン等価テストを追加)。 - ユーザースクリプトはサンドボックス環境で実行され、
io/os/ffi/require
などは従来どおり利用できません。
同梱物
- 本プラグインには高速ランタイム(
luajit.exe/lua51.dll)と実行スクリプトを同梱して
おり、プラグイン本体と同じnativeフォルダーに配置されます(手動インストールは不要)。
v1.2.0
v1.2.0 - Lua スクリプト for YMM4
他オブジェクトの情報を任意のフレーム時点で取得できるようにしたリリースです。
発射元が動いても弾の発射位置を固定するなど、フレームを指定した参照が可能になりました。
新機能
1. obj.getobject へのフレーム指定引数の追加
obj.getobject(tag, frame) の第2引数 frame を追加しました。指定したタイムライン
フレーム時点での対象オブジェクトの座標・回転・拡大率・不透明度を取得できます。
frame を省略した場合は従来どおり現在フレームの値を返します。
弾の発射フレーム(弾アイテムの開始フレーム)は timelineframe - frame で求まるため、
そのフレームの発射元座標を取得すれば、発射元が動いても弾の原点を発射位置に固定できます。
local fire = timelineframe - frame
local src = obj.getobject("routersys", fire)
if src then
obj.x = src.x
obj.y = src.y
end取得値は対象アイテム自身の座標・回転・拡大率であり、グループ制御・カメラ制御による
変形は含みません。同じタグのアイテムが複数ある場合は、対象フレームで表示中のものを
優先して返します。
内部実装
2. 参照方式の統一(依存クエリの再評価)
他オブジェクトの値を「現在フレームで事前に算出したスナップショット」を比較する方式から、
「参照したオブジェクトを保持し、要求されたフレームで評価する」方式へ統一しました。
- 取得対象のアイテムを保持し、任意のフレームで評価する
SceneObjectResolverを追加 - スクリプト実行中に行われた参照
(タグ, フレーム)を記録し、出力キャッシュの
再利用判定では記録した参照を再評価して一致を確認
これにより、任意フレームの参照に対しても決定論的かつキャッシュ整合性を保った
取得が可能になります。評価はすべて描画スレッド側で行い、スクリプト実行スレッドへは
数値のみを渡します。
ドキュメント
対応する 8 言語のスクリプト説明文に frame 引数の説明と発射位置を固定する例を
追記し、サンプル集ページにも同様の例を追加しました。
v1.1.1
v1.1.1 - Lua スクリプト for YMM4
特定のテーマでスクリプトエディタを開いた際に発生する例外を修正したリリースです。
修正
1. テーマに対応するシンタックス定義の不足による例外
YMM4 のテーマが「Windows」または「Black」のとき、スクリプトエディタの表示時に
System.IO.IOException が発生する不具合を修正しました。
スクリプトエディタ (CodeEditor) は現在のテーマ名から
Lua-{テーマ名}.xshd を解決しますが、本プラグインは Lua-Dark.xshd と
Lua-Light.xshd のみを同梱していたため、テーマ名が Windows や Black の場合に
対応するシンタックス定義が見つからず例外となっていました。
不足していた以下の 2 ファイルを追加しました。
| ファイル | 配色 | 対応テーマ |
|---|---|---|
Lua-Black.xshd |
暗背景向け | Black |
Lua-Windows.xshd |
明背景向け | Windows |
配色は YMM4 のテーマの明暗(Black は暗背景、Windows は明背景)に合わせ、
既存の Lua-Dark.xshd・Lua-Light.xshd と統一しています。これにより
Black・Dark・Light・Windows のいずれのテーマでもシンタックスハイライトが
適用されます。
2. プロジェクトファイルへのリソース登録
追加した 2 ファイルを LuaScript.csproj に Resource として登録しました。
シンタックス定義は pack URI 経由でアセンブリに埋め込まれて参照されるため、
配布パッケージは DLL のみで完結します。
v1.1.0
v1.1.0 - Lua スクリプト for YMM4
他のアイテムの描画情報をスクリプトから取得する関数 obj.getobject を追加したリリースです。
アイテムの備考をタグとして指定することで、別アイテムの座標・拡大率・回転角・不透明度を
参照できます。発射元アイテムの座標を基準に弾を発射するような演出など、複数アイテムを
連動させる用途に利用できます。
新機能
1. オブジェクト参照関数(obj.getobject)
obj.getobject(tag) は、引数 tag(文字列)と一致する備考を持つアイテムの描画情報を
テーブルで返却します。tag が文字列でない場合、または一致するアイテムが存在しない場合は
nil を返却します。
返却テーブルのメンバーは以下のとおりです。
| メンバー | 型 | 説明 |
|---|---|---|
exist |
boolean |
現在のフレームが対象アイテムの表示期間内にあるか |
x・y・z |
double |
描画位置(ピクセル) |
zoom |
double |
拡大率(1.0 で等倍) |
sx・sy |
double |
X・Y 方向の拡大率(zoom と同値) |
rx・ry |
double |
X・Y 軸回転角(度、常に 0) |
rz |
double |
Z 軸回転角(度) |
rxr・ryr |
double |
X・Y 軸回転角(ラジアン、常に 0) |
rzr |
double |
Z 軸回転角(ラジアン) |
alpha |
double |
不透明度(0〜255、フェード適用済み) |
layer |
int |
レイヤー番号 |
各値は obj テーブルと同一の単位系・座標系です。取得できるのはアイテム自身に設定された
アニメーション値であり、グループ制御・カメラ制御・上位エフェクトによる変形は含みません。
同一の tag を持つアイテムが複数ある場合は、現在のフレームで表示期間内にあるものを
優先して返却します。表示期間内のものが存在しない場合は最初に一致したアイテムを返却します。
利用例は以下のとおりです。
local target = obj.getobject("routersys")
if target then
obj.x = anim.lerp(obj.x, target.x, obj.t)
obj.y = anim.lerp(obj.y, target.y, obj.t)
end内部実装
2. シーンオブジェクト情報(SceneObjectInfo)
SceneObjectInfo は 1 つのアイテムの描画情報を保持する不変の readonly record struct です。
Tag・Exist・X・Y・Z・Zoom・Rz・Alpha・Layer を保持し、
値の等価比較によってキャッシュ判定に利用されます。
3. エフェクトプロセッサーの拡張(LuaScriptEffectProcessor)
BuildSceneObjects(EffectDescription desc) は、desc.Scenes から desc.SceneId に一致する
シーンを取得し、そのタイムライン上の VisualItem のうち備考(Remark)が設定されている
ものを列挙します。
各アイテムについて、desc.TimelinePosition.Frame - item.Frame を 0〜item.Length に
クランプしたローカルフレームでアニメーション値を評価します。Exist は現在フレームが
アイテムの表示期間内にあるかを表します。
値は描画パイプラインと同一の式で算出します。Zoom は評価値を 100 で除算した倍率、
Alpha は Opacity の評価値にフェード係数と 255 を乗じた値です。フェード係数は
フェードイン・フェードアウトの経過割合の小さい方です。
評価はすべて描画スレッド上で行い、結果を不変配列としてスクリプト実行スレッドへ渡します。
Update のキャッシュ判定に、このスナップショットの一致比較を RenderKey の比較へ加えて
追加しました。参照先のアイテムが移動した場合に出力が再計算されます。
4. スクリプト実行コンテキストの拡張(AviUtlScriptContext)
SceneObjects プロパティ(IReadOnlyList<SceneObjectInfo>)を追加しました。
TryGetObject(string tag, out SceneObjectInfo info) は、前述の選択規則に従って
アイテムを検索します。
5. Lua 実行エンジンの拡張(LuaScriptEngine)
obj テーブルへのネイティブ関数登録を RegisterObjectCallbacks に統合し、obj.getobject を
追加しました。返却テーブルはコンテキストのスナップショットから構築します。
ドキュメント
対応する 8 言語(ja-jp・en-us・zh-cn・zh-tw・ko-kr・es-es・id-id・ar-sa)のスクリプト
説明文に obj.getobject の項目を追記しました。
v1.0.0
v1.0.0 - Lua スクリプト for YMM4
YukkuriMovieMaker4 向けの Lua スクリプトエフェクトプラグインの初回リリースです。
AviUtl アニメーション効果互換の変数・関数体系を YMM4 映像エフェクトとして提供し、
MoonSharp による Lua 実行エンジン・専用コードエディター・シンタックスハイライト・
折り畳み・オートコンプリート・ファイルインポート/エクスポート・ピクセル直接操作・
独自アニメーションユーティリティライブラリ・8 言語対応 UI を備えた映像エフェクトプラグインです。
新機能
1. エフェクト定義(LuaScriptEffect)
LuaScriptEffect は VideoEffectBase を継承し、IScriptProvider を実装します。
[VideoEffect] 属性は以下のパラメーターで宣言されます。
- 表示名:
Texts.LuaScript(ローカライズキー) - カテゴリー:
VideoEffectCategories.Filtering - 検索タグ:
"lua"・"script"・"スクリプト"・"lua script"・"アニメーション効果"・"animation" IsAviUtlSupported = falseにより AviUtl 向け EXO 出力は非対応です。ResourceType = typeof(Texts)でローカライズリソースを指定します。
Label プロパティは Texts.LuaScript の固定値を返却します。
デフォルトスクリプトは以下のとおりです。
obj.alpha = math.min(time * 255, 255)公開プロパティは以下のとおりです。
-
ToolBar(object?、常にnull):
[LuaScriptToolBar]でインポート・エクスポート・クリアのツールバーを表示します。
Texts.ScriptGroupグループに属します。 -
Script(string、デフォルトDefaultScript):
[CodeEditor]でシンタックスハイライト付きコードエディターとして表示されます。
シンタックス定義はpack://application:,,,/LuaScript;component/Resources/SyntaxDefinitions/Lua-{theme}.xshd
をテーマ別に読み込みます。折り畳みにLuaFoldingStrategy、オートコンプリートに
LuaAutoCompletionStrategyを使用します。PropertyEditorSize.FullWidthで全幅表示されます。
Setによる変更通知を伴うフィールドプロパティとして実装されます。
Texts.ScriptGroupグループに属します。 -
Track0〜Track3(Animation、デフォルト0、内部範囲:YMM4Constants.VerySmallValue〜YMM4Constants.VeryLargeValue):
[AnimationSlider("F2", "", -100, 100)]でスライダー操作範囲 -100〜100 として表示されます。
スクリプト内ではobj.track0〜obj.track3でアクセスします。
AviUtl のtrack0〜track3に対応するスライダー値です。
Texts.ParametersGroupグループに属します。
CreateExoVideoFilters は空の IEnumerable<string> を返却し、EXO 向けフィルター出力は実装されていません。
CreateVideoEffect(IGraphicsDevicesAndContext devices) は
new LuaScriptEffectProcessor(devices, this) を返却します。
GetAnimatables は Track0・Track1・Track2・Track3 を列挙します。
2. スクリプト実行コンテキスト(AviUtlScriptContext)
AviUtlScriptContext はスクリプト実行時の状態を保持する内部クラスです。
読み取り専用プロパティ
| プロパティ | 型 | 説明 |
|---|---|---|
ImageWidth |
int |
画像幅(ピクセル) |
ImageHeight |
int |
画像高さ(ピクセル) |
Track0〜Track3 |
double |
スライダー値 |
Time |
double |
アイテム内の経過時間(秒) |
Frame |
int |
アイテム内の経過フレーム数 |
TotalFrame |
int |
アイテムの総フレーム数 |
TotalTime |
double |
アイテムの総時間(秒) |
Framerate |
int |
フレームレート |
TimelineFrame |
int |
タイムライン上の経過フレーム数 |
TimelineTime |
double |
タイムライン上の経過時間(秒) |
SceneWidth |
int |
シーン幅 |
SceneHeight |
int |
シーン高さ |
Layer |
int |
レイヤー番号 |
Index |
int |
グループ内のインデックス |
Num |
int |
グループ内の総数 |
GroupIndex |
int |
グループインデックス |
GroupCount |
int |
グループ総数 |
TimelineTotalFrame |
int |
タイムライン総フレーム数 |
TimelineTotalTime |
double |
タイムライン総時間(秒) |
IsSaving |
bool |
エクスポート中かどうか |
IsPlaying |
bool |
再生中かどうか |
IsPaused |
bool |
一時停止中かどうか |
TimeRatio |
double |
アイテム内の時間比率(Frame / TotalFrame) |
SceneId |
string |
シーン ID |
書き換え可能プロパティ
| プロパティ | 型 | 説明 |
|---|---|---|
X・Y・Z |
double |
描画位置 |
Ox・Oy・Oz |
double |
回転中心のオフセット |
Sx・Sy |
double |
X・Y 方向の拡大率 |
Zoom |
double |
拡大率((Sx + Sy) / 2) |
Aspect |
double |
アスペクト比((Sx - Sy) / (Sx + Sy)) |
Alpha |
double |
不透明度(0〜255) |
Rx・Ry・Rz |
double |
X・Y・Z 軸回転角(度) |
RxRad・RyRad・RzRad は各 Rx・Ry・Rz をラジアンに換算した計算プロパティです。
ピクセル操作
GetPixel(int x, int y)は(r, g, b, a)のタプルを返却します。各成分は 0〜255 のdoubleで、
プリマルチプライ済み BGRA からストレートアルファの RGB へ復元して返却します。
アルファが 0 以下の場合はすべて 0 を返却します。SetPixel(int x, int y, double r, double g, double b, double a)は
ストレートアルファの RGB をプリマルチプライ済み BGRA に変換してバッファーへ書き込みます。
aのデフォルトは 255 です。書き込み後はIsPixelsDirtyが true になります。EnsurePixelBufferはピクセルローダーを遅延呼び出しして入力画像をバッファーへ読み込みます。GetPixelBufferは内部のbyte[]バッファーを返却します。
3. エフェクトプロセッサー(LuaScriptEffectProcessor)
LuaScriptEffectProcessor は VideoEffectProcessorBase を継承し、
コンストラクターで IGraphicsDevicesAndContext devices と LuaScriptEffect item を受け取ります。
CreateEffect メソッド
GraphicsDevicesAndContext のプライベートコンテキスト _ownCtx を生成して disposer に登録し、
null を返却します。出力画像の生成はスクリプト実行後に動的に決定します。
setInput / ClearEffectChain メソッド
setInput は入力が前回と異なる場合に _isFirst = true としてキャッシュを無効化します。
ClearEffectChain は effectOutput を null に設定します。
Update メソッド
Update(EffectDescription desc) は毎フレーム呼び出されます。
input または _ownCtx が null の場合は desc.DrawDescription をそのまま返却します。
RenderKey レコードでフレーム・時間・長さ・FPS・スライダー値 4 本・スクリプト文字列・
利用用途・シーン ID・タイムライン情報・シーンサイズ・レイヤー・インデックス・グループ情報・
タイムライン総フレーム数・DrawDescription を一括保持し、
前回と同一の場合はキャッシュした結果をそのまま返却します。
スクリプト実行時は BuildContext で AviUtlScriptContext を生成し、
SetPixelLoader でピクセル遅延ローダーを登録してから LuaScriptEngine.Execute を呼び出します。
実行後に ctx.IsPixelsDirty が true の場合のみ出力ビットマップへ書き込み、
AffineTransform2D で入力境界の原点へ平行移動して effectOutput に設定します。
ピクセルが変更されていない場合は effectOutput = null としてパススルーします。
BuildOutputDesc が書き換え後の ctx.X/Y/Z/Ox/Oy/Sx/Sy/Zoom/Aspect/Alpha/Rx/Ry/Rz から
新しい DrawDescription を構築して返却します。Alpha は ctx.Alpha / 255d を
0〜1 にクランプします。
例外は LuaScriptException を捕捉してログに書き込み、エラー時は入力の DrawDescription を
そのまま返却します。タイムアウトは LuaScriptRuntimeException として処理されます。
ビットマップ管理
EnsureBitmaps(int width, int height) でサイズ変化時にビットマップ 3 枚と変換エフェクトを再生成します。
_renderTarget:BitmapOptions.Target、入力を描画する作業バッファー_stagingBitmap:B8G8R8A8_UNorm・Premultiplied・CpuRead | CannotDraw、CPU 読み出し用_outputBitmap:BitmapOptions.Target、ピクセル操作後の書き出し先
LoadInputPixels は _ownCtx の独立デバイスコンテキストで入力を _renderTarget へ描画し、
_stagingBitmap へコピーして Map(MapOptions.Read) で _pixelBuffer へ読み出します。
ピッチが行ストライドと一致する場合は一括コピー、そうでない場合は行ごとにコピーします。
4. Lua 実行エンジン(LuaScriptEngine)
LuaScriptEngine は IDisposable を実装します。
タイムアウトは ExecutionTimeoutMilliseconds = 5000(5 秒)です。
タイムアウト時は実行スレッドを非同期で破棄して新しいスレッドを生成し、
LuaScriptRuntimeException をスローします。
ExecutionThread 内部クラス
Lua スクリプトを専用ワーカースレッドで逐次実行する仕組みです。
キューのバウンド容量は 1 で、実行要求が溢れた場合は即座にエラーを返却します。
CancellationDebugger により、キャンセルトークンを MoonSharp デバッガーフックへ橋渡しし、
タイムアウト時に OperationCanceledException を発生させます。
コンパイル済みチャンクはスクリプト文字列が変化した場合のみ LoadString で再コンパイルします。
再コンパイル時の構文エラーは LuaScriptCompilationException としてラップします。
実行時エラーは LuaScriptRuntimeException としてラップします。
EnsureScriptIntegrity は math グローバルが消失していた場合に Lua VM を完全リセットします。
有効な Lua モジュールは以下のとおりです。
Basic / Math / String / Table / Bit32 / TableIterators / Metatables / ErrorHandling
ファイルアクセスは DisabledFileScriptLoader により無効化されています。
フレームシードによる math.randomseed 呼び出しにより、同一フレームでは math.random が
再現性のある値を返します。
SetupGlobals メソッド
スクリプト実行前にグローバル変数と各テーブルを初期化します。
ユーザーがフレーム間でグローバルに書き込んだキーは次フレームの実行前に除去されます
(_builtinGlobalSnapshot との差分を削除)。
各テーブル(obj・scene・anim・ymm4)も同様にフレーム間でリセットします。
スクリプトから利用可能なグローバル変数は以下のとおりです。
| 変数名 | 型 | 説明 |
|---|---|---|
time |
double |
アイテム内の経過時間(秒) |
frame |
int |
アイテム内の経過フレーム数 |
totalframe |
int |
アイテムの総フレーム数 |
framerate |
int |
フレームレート |
timelineframe |
int |
タイムライン上の経過フレーム数 |
timelinetime |
double |
タイムライン上の経過時間(秒) |
layer |
int |
レイヤー番号 |
ReadBackGlobals メソッド
スクリプト実行後に obj テーブルの変数を AviUtlScriptContext へ書き戻します。
書き戻し対象は x・y・z・ox・oy・oz・alpha・sx・sy・zoom・aspect・
rx・ry・rz・rxr・ryr・rzr です。
zoom・aspect が変化し、かつ sx・sy が変化していない場合は
sx = zoom * (1 + aspect)・sy = zoom * (1 - aspect) で sx・sy を再計算します。
rxr・ryr・rzr が前回値から変化していた場合は、それをラジアンから度に変換して
rx・ry・rz を上書きします。それ以外の場合は rx・ry・rz を直接読み返します。
5. スクリプト API(obj テーブル)
スクリプトから参照・書き換えできる obj テーブルのメンバーは以下のとおりです。
読み取り専用メンバー
| メンバー | 説明 |
|---|---|
obj.w |
画像幅(ピクセル) |
obj.h |
画像高さ(ピクセル) |
obj.hw |
画像幅の半分 |
obj.hh |
画像高さの半分 |
obj.cx |
画像幅の半分(hw の別名) |
obj.cy |
画像高さの半分(hh の別名) |
obj.cz |
常に 0 |
obj.sz |
常に 1 |
obj.diagonal |
画像の対角線長(sqrt(w^2 + h^2)) |
obj.track0〜obj.track3 |
スライダー値 |
obj.time |
アイテム内の経過時間(秒) |
obj.frame |
アイテム内の経過フレーム数 |
obj.totalframe |
アイテムの総フレーム数 |
obj.totaltime |
アイテムの総時間(秒) |
obj.t |
frame / totalframe(0 除算時は 0) |
obj.framerate |
フレームレート |
obj.layer |
レイヤー番号 |
obj.index |
グループ内のインデックス |
obj.num |
グループ内の総数 |
読み書き可能メンバー
| メンバー | 説明 |
|---|---|
obj.x・obj.y・obj.z |
描画位置(ピクセル) |
obj.ox・obj.oy・obj.oz |
回転中心のオフセット(ピクセル) |
obj.sx・obj.sy |
X・Y 方向の拡大率 |
obj.zoom |
拡大率(sx と sy の平均) |
obj.aspect |
アスペクト比 |
obj.alpha |
不透明度(0〜255) |
obj.rx・obj.ry・obj.rz |
X・Y・Z 軸回転角(度) |
obj.rxr・obj.ryr・obj.rzr |
X・Y・Z 軸回転角(ラジアン)。変更すると対応する rx・ry・rz を上書きします。 |
ピクセル操作関数
| 関数 | 戻り値 | 説明 |
|---|---|---|
obj.getpixel(x, y) |
r, g, b, a |
指定座標のピクセルを取得します。各成分は 0〜255 の浮動小数点数です。 |
obj.setpixel(x, y, r, g, b [, a]) |
なし | 指定座標へピクセルを書き込みます。a のデフォルトは 255 です。 |
obj.getpixeldata() |
PixelDataProxy |
ピクセルデータへの直接アクセスオブジェクトを返却します。 |
obj.putpixeldata() |
なし | 互換性のために存在しますが、何もしません。 |
6. スクリプト API(scene テーブル)
| メンバー | 説明 |
|---|---|
scene.width |
シーン幅(ピクセル) |
scene.height |
シーン高さ(ピクセル) |
scene.cx |
シーン幅の半分 |
scene.cy |
シーン高さの半分 |
7. スクリプト API(anim テーブル)
anim テーブルはアニメーション補助関数と数学ユーティリティを提供します。
定数
| 定数名 | 値 | 説明 |
|---|---|---|
anim.tau |
2π |
円周率の 2 倍 |
anim.e |
e |
自然対数の底 |
anim.phi |
(1 + √5) / 2 |
黄金比 |
anim.sqrt2 |
√2 |
2 の平方根 |
補間・マッピング関数
| 関数 | 説明 |
|---|---|
anim.lerp(a, b, t) |
a から b への線形補間 |
anim.smoothstep(edge0, edge1, x) |
Hermite 補間(0〜1 にクランプ) |
anim.smootherstep(edge0, edge1, x) |
5 次 Hermite 補間(0〜1 にクランプ) |
anim.clamp(v, lo, hi) |
v... |