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 (<reason>)(退出码 2:没有 Blender、超时、Blender 错误或错误的配置;
原因会说明)。跳过的运行不是结果:修正原因后重新运行。
从句子到配置文件
- 如果您不确定骨骼映射,请对每个角色文件运行
dots.py bones <file>(Mixamo 和 Unity humanoid 名称会自动映射;否则请编写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。
触表面(接触检查的 b):<role>(整个身体)、<role>.<canonical bone>(一个身体部位,如 him.LeftUpLeg、him.Spine1、him.Head)、self、self.<bone>、prop:<object name>、floor、nearest。
结构性和旋转性检查使用自定义点(在骨骼、物体或网格区域上)和方向(骨骼或物体轴线、两点之间的连线、表面法线、手掌法线、世界轴线)。完整配置:references/config.md。每种检查类型有一个工作示例:references/checks.md。
包含接触、把持、对齐、范围和放置的完整场景(人体模型手持并举起一根杆):ContactDots 仓库中的 examples/grab/
(config.json;预期结果为 PASS 10/10,0 穿透)。
限制:预设 finger(默认:接触在其指定帧上的偏差最多为 3 毫米,在任何帧上的穿透最多为 2 毫米)或 limb(10 毫米 / 10 毫米),或您自己的数值。
读取结果
摘要列出每个检查项及其编号、最差帧、限制和 PASS/FAIL,然后列出超过限制的穿透。间隙以毫米为单位(皮肤到表面):正值 = 分开,负值 = 内部。dots.json 的详细信息:references/results.md。
- 接触 FAIL 且最差间隙为正值 = 未接触(漂浮);最深层间隙为大的负值 = 陷入。
dots.json中的skinMm是每个点自身的皮肤半径;异常的半径表示皮肤权重差或错误的体网格,该点的间隙是粗略的。- 未声明检查项:摘要将改为列出观察到的接触(30 毫米以内的点)。
世界帧警告
两个 FBX 文件并不总是共享一个世界帧(不同的导出原点或偏移)。当有两个或更多角色时,摘要会打印每个角色在第一帧时的根位置。在信任任何成对数值之前,确认它们相对于彼此的位置是否正确。如果不正确,数字就毫无意义:请修正导出,不要调整数字。
请查看图片
仅靠数字是不够的。在报告之前,打开 dots-sheet.png(在 out 文件夹中):每个网格使用一种纯色(每个角色或道具使用不同颜色),背景为深色,每个角色有较小的点,测量的配对用一条线连接(黄色 = 通过,洋红色 = 失败;接近零间隙的点有一个环),在接触表面上有一个半透明圆盘(互补色、轮廓线和法线箭头),X 轴红色、Y 轴绿色、Z 轴浅蓝色的三元组位于手掌、手腕、头部和骨盆的特写视图中,角度检查有箭头,每个图块有标题(id、值、限制、PASS/FAIL)。测量的配对、箭头、圆盘轮廓和三元组绘制在网格前面;较小的点可能隐藏在它们后面。检查每个图块是否显示了您想要的部分(右手、右大腿、正确的帧)。在错误的点上通过测试意味着错误的答案。
报告反馈
第一行摘要、每个检查项的编号及其限制和帧、超过限制的穿透、两个角色时的根位置,以及图片显示的内容。请说明它仅进行了测量。