PMD材質リストファイルをPMD出力時に自動作成しようという話です。メタセコイア+ExportPMD使用が前提です。
PMXエディタでは材質リストファイルの読み込みが廃止されてしまいましたが、MMEではサブセット展開が材質リストファイルに対応しました。依然としてPMDエディタを使っている人もいるでしょうし、PMDでモデル制作するなら材質リストファイルはあったほうが便利なのではないでしょうか。
しかしながら、これを手作業で作成するのは面倒ですし、ミスが発生する可能性が大きくなります。またモデル更新時にリストファイルのほうの更新を忘れるということもあります。
ということで、ExportPMDでのPMD出力時に材質リストファイルの作成/更新を自動化する方法を考えてみました。
ExportPMD設定ファイルのGlobalチャンクには「shell」と「app」という設定項目があります。これで起動するアプリケーションを設定できます。実はWindowsの実行形式ならなんでもいいので、バッチファイルを設定することもできます。「shell」を「1」に設定して引数に出力ファイル名を渡すようにし、「app」にバッチファイルの絶対パスを設定します。
Global {
・・・
shell 1
app "バッチファイルのパス名"
}
で、あとはこのバッチファイルに材質リストファイルを出力するコードを書けばいいのです。
方法はいろいろあるでしょうが、ここではWSH(JScript)を使うことにします。
@if (1==0) /*ユーザー設定で各自の環境変数を設定します。PMDLISTにはExportPMD用の設定ファイルがあるフォルダのパスを指定します。CONFTXTには設定ファイルの名前を指定します。
@echo off
setlocal enableextensions enabledelayedexpansion
rem -------------------- ユーザー設定 --------------------
set PMDLIST=C:\Metaseq\Plugins\Export\pmdlist
set CONFTXT=default.txt
rem ------------------------------------------------------
cd %~dp0
cls
if {%~x1}=={.pmd} cscript //Nologo //E:JScript %~f0 export_materiallist "%PMDLIST%\%CONFTXT%" %1 & goto :EOF
rem */
@end
/** ========================================================
* JavaScript 処理
* ========================================================
**/
function export_materiallist() {
var fs = new ActiveXObject("Scripting.FileSystemObject");
var ts = fs.OpenTextFile(WScript.Arguments(1), 1, false);
var m = new Array();
var reg1 = new RegExp();
reg1.compile('^Material "([^"]+)" {');
while (!ts.AtEndOfStream) {
if (reg1.test(ts.ReadLine())) {
var t1 = RegExp.$1;
m.push(t1);
}
}
ts.Close();
ts = fs.OpenTextFile(fs.GetBaseName(WScript.Arguments(2)) + ".txt", 2, true);
for (var i in m) { ts.WriteLine(m[i]); }
ts.Close();
m = null;
}
command = WScript.Arguments(0);
eval(command + "();");
ここで注意点が2つ。
ExportPMDは実際のモデルデータにない材質をMaterialチャンクに設定しても出力時に無視してくれる仕様のようですが、上記のバッチファイルは全Materialチャンクをリスト化します。なので無効なMaterialチャンクは削除してください。
また、出力されるPMDの材質の順番はモデルデータの材質の順番となります。なので設定ファイルのMaterialチャンクの順番もこれに合わせてください。『メタセコイアの材質をExportPMD用にリストするスクリプト』を使えば、モデルデータの材質の順番でMaterialチャンクのリストを出力してくれます。
このバッチを実行すると、バッチファイルのあるフォルダに材質リストファイルが出力されます。すでに同名の材質リストファイルがある場合は、内容が更新されます。なお、引数にPMXファイルが渡されると、このバッチは材質リストファイルを作成しません。
ところでKeynoteではボーンとアンカー用の材質が必要なため、これとモデル本来の材質とを識別しやすくするため、モデル本来の材質名には記号などを加える工夫をしている場合があります。また、日本語の材質名はFBXエクスポーターとの相性が悪いため英数字を使用していることもあるでしょう。
もし材質名の変換をしたいなら、JScriptのDictionaryを使って実現できます。変換する材質名と変換後の名前のペアを登録するDictionaryオブジェクトを用意します。例えばこんな感じで
var dic = new ActiveXObject("Scripting.Dictionary");ここでの登録の順番は問題ないです。ただし、材質名全てのペアを用意しないといけません。あとはwhile文中のm.push関数の引数に変換を実行するコードを加えてやります。
dic.Add("mat:body_skin", "肌");
dic.Add("mat:face_skin", "顔");
dic.Add("mat:hair", "髪");
while (!ts.AtEndOfStream) {この部分は正規表現などを使えばもっと複雑な変換が可能です。
if (reg1.test(ts.ReadLine())) {
var t1 = RegExp.$1;
m.push(dic.Item(t1));
}
}