contact-dots 是做什麼的?
將定位點放置於每個角色的手、四肢、腳與骨盆(以及您指定的任何其他部位),
然後在無頭 Blender 中逐幀測量每個定位點到表面的間距、
定位點之間的距離以及方向之間的角度。輸出 dots.json,列印簡短摘要,
並渲染 dots-sheet.png(每個檢查與最嚴重穿透各一張特寫圖)。
它絕不會修改原始檔案,只會寫入您指定的輸出資料夾。
使用時機
- 「她的右手掌在第 40 幀真的有碰到他的左大腿嗎?」(身體接觸,
touch) - 「有任何手指插入杯子裡嗎?」(穿透總是被檢查)
- 「彈匣在第 40 幀已卡入定位」、「盒子平放」、「槍枝保持在手中」、
「踩地的腳沒有滑動」(結構檢查:
seat、rest、hold、distance) - 「手肘從未向後彎曲」、「蓋子開啟 0-110 度」、「手掌面向桌子」
(角度檢查:
range、align)
不適用於:修正姿勢、物理或平衡、嘴部或布料接觸、網格對網格重疊。
需求
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 ...(退出碼 0)、dots: FAIL ...(退出碼 1)或
dots: skipped (<原因>)(退出碼 2:找不到 Blender、超時、Blender 錯誤或無效設定;
原因會說明是哪一項)。跳過的執行不算結果:修正原因後重新執行。
從一句話到設定檔
- 如果您不確定骨架對應是否正確,請對每個角色檔案執行
dots.py bones <file>(Mixamo 與 Unity 人形骨架名稱會自動對應;否則請撰寫一個boneMap)。 - 為每個角色指定一個簡短的
role(her、him、a、b):定位點會是<role>.<dot>。 - 將每個待檢查項目轉換為
checks中的一個條目,並指定應維持的幀數。 - 指定一個
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>(單一身體部位,
例如 him.LeftUpLeg、him.Spine1、him.Head)、self、self.<bone>、prop:<物件名稱>、
floor、nearest。
結構與角度檢查使用自訂定位點(位於骨骼、物件或網格區域上)與方向(骨骼或物件軸向、
定位點之間的連線、表面法線、手掌法線、世界軸向)。完整設定請參閱:references/config.md。
每種檢查類型的範例:references/checks.md。
包含 touch、hold、align、range 與 rest 的完整場景(人體模型手持並舉起一根槓鈴):ContactDots 儲存庫中的 examples/grab/
(config.json;預期結果為 PASS 10/10,0 次穿透)。
限制:預設 finger(預設:接觸在指定幀數最多偏差 3 毫米,任何幀數最多穿透 2 毫米)
或 limb(10 毫米 / 10 毫米),或您自訂的數值。
讀取結果
摘要會列出每個檢查的編號、最差幀數、限制與 PASS/FAIL,然後列出超過限制的穿透。
間距為皮膚到表面的毫米數:正值表示分開,負值表示穿透。dots.json 的詳細說明:references/results.md。
- touch 失敗且最差間距為正值 = 未接觸(浮空);最差穿透為較大的負值 = 陷入。
dots.json中的skinMm是每個定位點自身的皮膚半徑;異常的半徑表示蒙皮權重不佳 或身體網格錯誤,該定位點的間距會不準確。- 未宣告任何檢查:摘要會改為列出觀測到的接觸(小於 30 毫米內的定位點)。
世界座標系警告
兩個 FBX 檔案不一定共享同一個世界座標系(不同的匯出根節點或偏移)。 當有兩個或更多角色時,摘要會列印每個角色在第一幀的根節點位置。 在相信任何成對的數值之前,請確認它們的相對位置是正確的。 如果不正確,數值就毫無意義:請修正匯出方式,不要對數值進行偏移。
查看圖表
單看數字是不夠的。在回報之前請打開 dots-sheet.png(位於 out 資料夾):
每個角色或道具的網格以一種純色顯示在深色背景上,每個角色有小的定位點,
測量的配對用一條線連接(黃色 = 通過,洋紅色 = 失敗;接近零間距處有一個環),
被觸碰的表面上有一個半透明圓盤(互補色,附有輪廓線與法線箭頭),
特寫視圖中手掌、手腕、頭部與骨盆處有 XYZ 三軸(X 紅色、Y 綠色、Z 淺藍色),
角度檢查有箭頭,每個圖塊有標題(id、數值、限制、PASS/FAIL)。
測量的配對、箭頭、圓盤輪廓線與三軸會繪製在網格前方;小的定位點可能藏在網格後面。
請檢查每個圖塊是否顯示了您想要的部分(右手、右大腿、正確的幀數)。
在錯誤的定位點上通過,就是錯誤的答案。
回報
第一行摘要、每個檢查的編號及其限制與幀數、超過限制的穿透、 若有兩個角色則加上根節點位置,以及圖表顯示的內容。請說明它僅進行測量。