contact-dots は何をしますか?
各キャラクターの手、手足、足、骨盤(および指定したその他の部位)にドットを配置し、
ヘッドレスBlenderでフレームごとに、各ドットから表面までのギャップ、ドット間の距離、
方向間の角度を計測します。dots.jsonを書き出し、短いサマリーを表示し、
dots-sheet.png(各チェックと最悪の貫通ごとに1つのクローズアップ)をレンダリングします。
ソースファイルは決して変更せず、指定した出力フォルダにのみ書き込みます。
使用する場面
- 「彼女の右手のひらは本当にフレーム40で彼の左太ももに触れているのか?」(ボディコンタクト、
touch) - 「指がカップの中に入っていないか?」(貫通は常にチェックされます)
- 「マガジンがフレーム40で装着されている」「箱が平らに置かれている」「銃が手の中に収まっている」「接地した足が滑っていない」(構造的:
seat,rest,hold,distance) - 「肘が後ろに反っていない」「蓋が0〜110度開く」「手のひらがテーブルを向いている」(回転:
range,align)
対象外: ポーズ、物理、バランスの修正、口や布の接触、メッシュ同士の重なり。
必要なもの
Blender(最新バージョンであればどれでも可;内部でBlender自身のPythonを使用)、ホストスクリプト用のPython 3標準ライブラリ。
Blenderは--blender PATH、次に$BLENDER、次にPATH、最後に通常のインストールフォルダから検索されます。
コマンド
すべてこのスキルフォルダ内の scripts/dots.py を通じて実行します:
python scripts/dots.py selftest [--out DIR] # 既知の答えを確認;新しいマシンで最初に実行
python scripts/dots.py bones <file.fbx|.blend> # リグのボーンと提案されるボーンマップ
python scripts/dots.py measure <config.json> # 計測、判定、dots.json + dots-sheet.png を書き出す
python scripts/dots.py sheet <dots.json> # シートのみを再レンダリング
オプション: --blender PATH, --timeout S(デフォルト600), --limits finger|limb(計測)、
--no-sheet(計測、数値のみ)。
結果行(警告やセルフテスト行の後): dots: PASS ...(exit 0)、dots: FAIL ...(exit 1)、または
dots: skipped (<reason>)(exit 2: Blenderなし、タイムアウト、Blenderエラー、または不正な設定;
理由が示されます)。スキップされた実行は結果ではありません: 理由を修正して再実行してください。
文章から設定へ
- 各キャラクターファイルに対して
dots.py bones <file>を実行し、リグマッピングが不明な場合は確認します(Mixamo およびUnityヒューマノイド名は自動的にマッピングされます;それ以外の場合はboneMapを記述します)。 - 各キャラクターに短い
role(her,him,a,b)を割り当てます:ドットは<role>.<dot>になります。 - チェックする各項目を
checksの1エントリにし、それが成立すべきフレームを指定します。 outフォルダを指定します(相対パスは設定ファイルからの相対パスになります)。
「彼女の右手のひらが彼の左太ももにフレーム40で触れている」:
{"out": "dots_out",
"characters": [{"role": "her", "file": "her.fbx"}, {"role": "him", "file": "him.fbx"}],
"frames": [40],
"checks": [{"id": "palm-on-thigh", "kind": "touch", "a": "her.R.palm", "b": "him.LeftUpLeg", "frames": [40]}]}
「彼女の右手が彼の左太ももに触れている」(手の任意の部位): "a": "her.R.hand"(グループ内の最も近いドットがカウントされます)。
ボディドット(S = R または L): S.<finger>.tip, S.<finger>.mid(thumb, index, middle, ring,
pinky)、S.palm, S.forearm.1-3, S.upperarm.1-3, S.thigh.1-3, S.shin.1-3, S.knee,
S.heel, S.ball, S.toe, pelvis.front, pelvis.back。グループ: S.hand, S.foot,
S.forearm, S.upperarm, S.thigh, S.shin, pelvis。
表面(touchのb): <role>(全身)、<role>.<canonical bone>(1つの体の部位、例:him.LeftUpLeg、him.Spine1、him.Head)、self、self.<bone>、prop:<オブジェクト名>、floor、nearest。
構造的および回転チェックでは、カスタムドット(ボーン、オブジェクト、またはメッシュ領域上)と
方向(ボーンまたはオブジェクトの軸、ドット間の線、表面法線、手のひら法線、ワールド軸)を使用します。
完全な設定: references/config.md。チェックの種類ごとに1つの実例: references/checks.md。
タッチ、ホールド、アライン、レンジ、レストを含むシーン全体(マネキンの手がバーを握って持ち上げる):
examples/grab/(ContactDotsリポジトリ内、config.json;期待される結果はPASS 10/10、貫通0)。
制限値: プリセット finger(デフォルト: 接触はそのフレームで最大3 mmまで許容、どのフレームでも内部に最大2 mmまで許容)、
または limb(10 mm / 10 mm)、または独自の数値。
結果の読み方
サマリーには、各チェックの番号、最悪のフレーム、制限値、PASS/FAIL、および制限値を超える貫通がリストされます。
ギャップは皮膚から表面までのmm単位: 正 = 離れている、負 = 内部に入り込んでいる。dots.jsonの詳細: references/results.md。
- worst gapが正のtouch FAIL = 接触していない(浮いている);大きな負の最深ギャップ = 沈み込んでいる。
dots.jsonのskinMmは各ドットの独自の皮膚半径です。異常な半径はスキンウェイトの不良または間違ったボディメッシュを示し、そのドットのギャップは大まかです。- チェックが宣言されていない場合: サマリーは観測された接触(30 mm以内のドット)を代わりにリストします。
ワールドフレームの警告
2つのFBXファイルは常に同じワールドフレームを共有するとは限りません(エクスポートルートやオフセットが異なる)。 2人以上のキャラクターがいる場合、サマリーは最初のフレームでの各キャラクターのルート位置を表示します。 ペアの数値を信頼する前に、それらが互いに対して適切な位置に立っていることを確認してください。 そうでない場合、数値は無意味です: 数値をずらすのではなく、エクスポートを修正してください。
シートを見てください
数値だけでは十分ではありません。報告する前に dots-sheet.png(outフォルダ内)を開いてください:
各メッシュはキャラクターまたはプロップごとに1つのフラットカラーで、暗い背景上に表示されます。
キャラクターごとに小さなドット、計測されたペアは線で結ばれます(黄色 = 合格、マゼンタ = 不合格;ほぼゼロのギャップの周りにリング)。
触れている表面上に半透明のディスク(補色、アウトライン、法線矢印)。
クローズアップビューの手のひら、手首、頭、骨盤にXYZトライアド(X赤、Y緑、Z水色)。
角度チェック用の矢印、タイルごとのキャプション(id、値、制限値、PASS/FAIL)。
計測されたペア、矢印、ディスクのアウトライン、トライアドはメッシュの前面に描画されます;
小さなドットはそれらの後ろに隠れる可能性があります。各タイルが意図した部位(右手、右太もも、
正しいフレーム)を示していることを確認してください。間違ったドットでの合格は間違った答えです。
報告内容
最初のサマリー行、各チェックの番号とその制限値およびフレーム、制限値を超える貫通、 2人のキャラクターがいる場合はルート位置、そしてシートに表示されている内容。計測のみを行ったことを伝えてください。