Communitygithub.com

contact-dots

在無頭 Blender 中測量動畫(FBX 或 .blend)裡應接觸、貼合、停留或對齊的物體,是否真的在真實網格上達成。以毫米為單位檢查身體接觸(手放腿上、手指碰道具、腳踩地板)、結構檢查(零件卡入插槽、盒子平放、手持物體不滑動、固定間距)以及角度檢查(零件對齊、鉸鏈或關節在範圍內),同時測量所有穿透,並輸出特寫圖表。僅測量,不修正任何事物。

contact-dots 是什麼?

contact-dots 是一個基於 Blender 的測量工具,專為動畫師與技術美術設計,用於精確驗證動畫或姿態中的接觸、穿透、貼合、滑動與角度。它支援 FBX 與 .blend 格式,可在無頭 Blender 中批次處理,並輸出詳細的 JSON 數據(dots.json)與視覺化圖表(dots-sheet.png)。此工具包含身體各部位(手指、手掌、腳、骨盆等)的自動定位點、自訂定位點、表面距離與方向角度測量,以及預設或自訂容差限制。它不修改原始檔案,僅提供客觀數值與視覺證據,適合用於 QA 流程、動畫驗證或技術審查。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/FullCircle-0/ContactDots/tree/HEAD/skill/contact-dots

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

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 錯誤或無效設定; 原因會說明是哪一項)。跳過的執行不算結果:修正原因後重新執行。

從一句話到設定檔

  1. 如果您不確定骨架對應是否正確,請對每個角色檔案執行 dots.py bones <file>(Mixamo 與 Unity 人形骨架名稱會自動對應;否則請撰寫一個 boneMap)。
  2. 為每個角色指定一個簡短的 role(her、him、a、b):定位點會是 <role>.<dot>。
  3. 將每個待檢查項目轉換為 checks 中的一個條目,並指定應維持的幀數。
  4. 指定一個 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)。 測量的配對、箭頭、圓盤輪廓線與三軸會繪製在網格前方;小的定位點可能藏在網格後面。 請檢查每個圖塊是否顯示了您想要的部分(右手、右大腿、正確的幀數)。 在錯誤的定位點上通過,就是錯誤的答案。

回報

第一行摘要、每個檢查的編號及其限制與幀數、超過限制的穿透、 若有兩個角色則加上根節點位置,以及圖表顯示的內容。請說明它僅進行測量。

相關技能