跳转至

在 Harmony 中

Harmony 是 OTS 说母语的地方。交换格式的规范空间 就是 Harmony 的 OGL 惯例 — Y-up、右手系、米 — 所以进出时什么都不需要调换。其他每一个应用都要转换 Harmony 已经在用的这套。

启动

从 Scripts 工具栏运行 OctoTransformSync 脚本。窗口会浮在 Harmony 上方并保持在那里;在它已经打开时再次运行脚本,只会把它提到最前。

窗口里的词汇是 Harmony 的:列表里说 PEGPEGs,导入按钮说 Apply to PEGs

四个页面

顶部两种格式,其下两个方向 — 这就是你在 Harmony 中能到达的所有页面:

Harmony — .pvt 导入

一副即将被构建的静置骨架。Build Skeleton 创建那些 peg;Create Cameras 亮了起来,因为这个文件携带了一台摄像机。

Harmony — .pvt 导出

你扫描进来的 peg,带 Rig 列和 Scale 选项。没有帧范围 — .pvt 里没有动画。

Harmony — .anm 导入

匹配树,每行一个复选框,以及三个动作:Apply to PEGsCreate RigCreate Cameras

Harmony — .anm 导出

.pvt 导出相同的列表 — 一个场景,一套分组 — 再加上 Start / EndScene range


OTS 从一个 peg 读什么

对每个被导出的 peg,OTS 会记录:

  • 它在 node graph 中的 路径,以及最近的那个 被导出的 祖先作为它的 parent。
  • 它的 pivot,以规范的米为单位。
  • 它的 变换,在每个打了关键帧的帧上作为 world matrix 求值,并换算成相对于那个祖先。
  • 它的 创作模式 — 分离位置、quaternion-path 旋转、分离缩放、3D 是否启用 — 记录为一条提示。
  • 如果有一个 CAMERA 节点挂在它上面,还有那份 摄像机配置

Keyframe 从这个 peg 实际的控制点收集,再加上导出范围的首帧和末帧。在 column 类型允许的地方,bezier handle 会被原生读取;在不允许的地方,则通过对曲线采样来重建。

Field ↔ OGL 缩放

Harmony 工作在 field 而不是米之下,而两者之间的换算并不是一个常数 — 它取决于场景的分辨率、视野和宽高比。OTS 会在导出和导入时向活动场景询问这个值,而不是把一个数字硬编码进去,这也正是 Harmony 适配器需要一个打开的场景才能干活的原因。

Harmony 的摄像机 clip plane 同样是以 field 为单位的。它们原本的 field 值会与转换后的距离一起保留在文件里,所以一次 Harmony → 任意 → Harmony 的往返会返回你一开始的那些确切数字。


"假 quaternion"

Harmony 有一个叫 QUATERNIONPATH 的 column 类型,而它并不是 quaternion。

它是 3D-path column 的一个子类,存的是一条由 三个 Euler 角分量 加上一个速度构成的路径 — 而不是一个 (w, x, y, z) quaternion。把它当作 quaternion 来读会得到一堆胡话。

所以 OTS 在所有 peg 模式下,永远把一个 peg 的旋转当作 Euler XYZ 度数 来读写。在内部,交换格式还会为旋转携带一个真正的 quaternion,由烘焙出的 world matrix 计算而来;那一个是与顺序无关的,彻底绕开了 Euler 顺序的歧义,而且它也是其他应用在导入时更偏爱的形式。

这件事你不需要做任何处理。写在这里,是因为它解释了为什么一个 peg 的旋转要这样处理,以及为什么对一个 Harmony 场景做朴素的 quaternion 读取会出错。


导入到已有的 peg 上

Apply to PEGs 会把动画写到已匹配且被勾选的行上。

Apply 会改写 peg 的创作模式

在写入之前,OTS 会 解除 目标 peg 上任何 3D-path 或 quaternion-path column 的链接,强制启用分离的位置 / 旋转 / 缩放通道并开启 3D,然后写入全新的 bezier 曲线。

得到的数值是正确的,曲线也是完全可编辑的。但一个原本基于 3D path 创作的 peg 之后就不在 3D path 上了,而且这一点不会因为重新导入而被撤销。

这是一个刻意的取舍:不这么做,就无法在 Harmony 的 path column 中表示任意传入的曲线。如果这个 peg 是你亲手打磨、希望原样保留的东西,那就改为应用到一个 Create Rig 的结果上,然后手动合并。

文件中记录的 source_modes 只是一条提示 — 它们描述的是这个 peg 在导出时是怎么创作的,在导入时从不改变任何数值。


Create Rig 构建出什么

Create Rig 组装出一个完整、整洁的子图,而不是一堆零散的 peg:

  • 一个以文件命名的 wrapper group,带 Multi-Port-In。
  • 一个面向整个 group 的外部 peg,让你可以把结果当作一个对象来移动。
  • 每一项一个 peg,静置 pivot 被写进它的 pivot 属性。
  • 按文件层级建立的父子 连线
  • 一个由叶子节点馈入的 composite,以及一个 Multi-Port-Out。
  • 这个 group 会被 接进 父 group 的主 composite。

整个构建过程是单独一步 undo。

Create Cameras 为每台摄像机添加一个 peg 加一个 CAMERA 节点,把摄像机挂到它的 peg 之下,并按文件给这个 peg 打关键帧。


说明与限制

后缀在匹配时会被剥离。 一个叫 hip-P 的 Harmony peg 和一个叫 hip 的 Maya joint 会被当作同一项,所以常见的 -P / -G / -C 惯例不会破坏一次往返。

Harmony 读文件时略微宽松一些。 Harmony 适配器的读取器不像 Maya 和 Blender 的读取器那样执行同样严格的版本检查,所以一个版本不对的文件在那里会以不同的错误形式暴露出来。从源应用重新导出一次就没事了。

场景必须是打开的。 Harmony 适配器所做的一切 — field 缩放、matrix bake、node graph 写入 — 都是针对活动场景运行的。


参见

  • 坐标系 — 为什么 Harmony 是那个恒等情形
  • 摄像机 — field ↔ 距离的 clip plane 问题
  • 匹配树 — 在你按下 Apply 之前,琥珀色意味着什么