跳转至

Compose

视频教程 — 即将推出

Compose 把你 author 的一切 — pose layer 及其 key、control、knob、driver、constraint、visibility group、look-at — 变成 Harmony 场景里一个真正的 Master Controller 节点,以及这个节点需要的文件。

这是 ORC 里唯一会写入你场景的功能。

MC 的名字

MC Name 里输入一个名字。不需要自己加后缀:

你按下 ORC 做的事
Enter,或点到别处 如果还没有后缀就追加 -MCHeadHead-MC
再按一次 Enter 点击 Compose

这个检查不区分大小写,所以你输入的 head-mc 会原样保留。

除此之外没有别的校验 — 不剥离字符,不做唯一性检查。最终的节点名由 Harmony 决定,所以一个冲突的名字可能会带着改动回来,ORC 会报告它实际拿到的名字。

Compose 为什么会被禁用

tooltip 永远就是原因,而且永远是你能处理的东西:

Tooltip 解决办法
Enter a name for the Master Controller first. 输入一个名字。
The "Eyebrows" pose layer has no keys yet. Stamp a snap with F6 or delete the empty layer. 给它打 key,或者删掉它。
3 layers are keyed but have no targets (…). Add what each one should move to its target list. 给它们指定 target。什么都不驱动的 widget 是不能上线的。
Nothing to compose yet. Add poses, drivers, constraints, or look-ats — or set both Front and Back MC to bake a merged runtime. rig 里什么都没有。

当名字已填好、没有半成品 layer,并且以下至少满足一项时,Compose 才会启用:

  • 任意地方至少有一个 pose key,
  • Front 和 Back MC 都已设置(你在合并它们),
  • 零个 pose layer,但至少有一个 driver、constraint 或已启用的 look-at — 一个只有自动化的 rig 也能正常 compose。

那些从不需要 key 的 layer — control 的 face、knob、导入的 grid — 都是例外。

会阻止它的两种情况

Blocker — 直接拒绝

冲突 为什么行不通
Knob 冲突 两个或以上的 extra knob 写同一个节点和 channel。runtime 只为每个节点和 attribute 捕获一份原始 base,所以这些写入无法叠加 — 最后一个会悄悄胜出。
Drawing 冲突 一个 READ 节点被两个或以上的同级(sibling) layer 替换。drawing 的切换是离散的,不能混合,而且没有任何东西给同级排优先级。

你会看到一行红字点名冲突,Compose 也不会开始。出问题的 Outliner 行也会变红。

层级(hierarchy)下方共享的 drawing 切换是没问题的 — 更深的 layer 胜出是有意为之的。

Warning — 确认后继续

如果只是有些可疑,按钮会变成 CONFIRM?,持续五秒,旁边列出清单。让它倒数结束,它就会变回 Compose

  • No pose data loaded
  • No Front or Back face: import an MC or author one — 只有两者都没有时才出现。只有 Front 是正常的。
  • Driver 'Blink' (Eyelids) has no keyed values
  • Constraint 'Arm Follow' has no target nodes
  • Constraint 'Arm Follow' has no channels selected

Compose Settings

Compose Settings

设置 决定的内容
Save states / script to .tbState 文件、runtime 脚本和 ORC 数据文件写入的位置。默认是你场景的 scripts 文件夹。
Connect MC to composite 新 MC 连接到哪个 Composite。ORC 会预选一个最佳猜测,但场景里的完整 composite 列表始终可选。
这个猜测是怎么来的

这个选择是从 rig 本身推导出来的,而不是列表顺序。

首先 ORC 找到 rig 的 main group:target 列表里的每个节点都为它所有的祖先 group 投票,占多数的最深 group 获胜。深度正是防止 deformation group 抢票的关键 — 它永远只包含自己那一小撮成员,所以多数票总会落在它外面的角色 group 上。

在那个 group 内部,按顺序第一个匹配的胜出:

  1. 已经有 MC 连接的 composite — MC 连接数最多的优先。如果它在 main group 内部,直接胜出。
  2. 名字符合 master-controller 命名习惯的 composite — master-controllermasterscontrollersctrl-MC……
  3. 该 group 的 main composite — 也就是喂给它 Multi-Port-Out 的那个。
  4. group 里根本没有 composite → 那就是 group 节点自身在外部喂给的那个。

什么都不匹配 → 场景里的第一个 composite。不管选中什么,这都只是一个预选 — 下拉框始终列出场景里的每一个 composite。

两次 Compose 之间保持同一个输出文件夹

增量缓存就存在那里。复用文件夹正是让 re-compose 变快的原因。

如果没有选中任何 composite,MC 会创建在 Top 下,不连接任何东西。否则它会创建在那个 composite 的父 group 里,并放在 Node View 中紧邻其上方的位置,方便你找到它。

会发生什么

Composing

四个阶段,全部实时报告:

阶段 产出
Slicing state files… .tbState pose 堆栈,每个 layer/side/page 一份,外加清单。详细行会准确点名当前位置:"Layer 'Eyebrows-L' — Pose 3 of 25 · Knob 2 of 13"
Constraint pre-wiring… 记录每个 constraint 原来的列,以便它的开关能恢复它们。
Generating MC script… MC 将要执行的 runtime 脚本。
Assembling MC node in Harmony… 节点本身、它的 attribute、UI 脚本和数据,以及 ORC 自己的数据块。

下方的 Recent activity 日志会保留带时间戳的记录,包括任何 warning。

一次 Ctrl+Z 就能撤销一次 Compose

整个组装过程都在一个名为 ORC Compose 的单一 Harmony undo 步骤内运行。

slicing 阶段确实会写列 — 这是它读取你的 pose 的方式 — 但那些写入是临时的、会被丢弃的,而且不管 Compose 成功、失败还是被取消,你的 pose 之后都会被恢复

取消

Cancel 是两次点击确认:第一次点击让它武装四秒(CONFIRM? (4s)),第二次点击才真正取消。窗口的 行为相同 — 正在运行的 Compose 不会直接关闭。Enter 永远不会触发 Cancel,所以一次无意识的按键不会中断一个半成品的 MC。

取消是协作式的:它会在下一个安全边界停下,而不是在调用中途,所以你会看到 "Will stop after the current Harmony call returns…"

取消会留下什么:

  • slicing 期间取消:已经写入的 .tbState 文件会保留,缓存也会保存,让这些工作计入下一次运行。不会创建 MC 节点。
  • 组装已经开始后取消:节点已经存在。整个 compose 没有事务性可言,ORC Compose 这一步的 Ctrl+Z 就是回退的办法。
  • 不管哪种情况,你的 pose 都会被恢复

结束的方式

结果 意味着什么
Compose complete — Top/robin-head-MC | 12 state stack(s), 2 constraint(s) 完成了。Node View 会平移到新节点并选中它。
Compose finished with 3 warning(s) — see the log MC 已经存在并能工作,但某个非致命的步骤出了问题。去读日志。
Compose failed — no state files produced 没有任何东西可切片。
Compose failed — script generation error
Compose failed — MC assembly error: …

落到磁盘上的文件

在你选择的输出文件夹里:

文件 是什么
<Stack>.tbState,或 <Stack>/0.tbState1.tbState…… pose 堆栈。带 knob 的 layer 会得到一个文件夹,每个 knob 位置一个文件 — 这是 Toon Boom 自己的原生布局。
<folder>_compose_state.json runtime 清单。
<name>_orc.js 生成的 runtime 脚本。
orc_pose_data.json 你整个 rig 的配置 — re-edit 和独立版 Widget Editor 的数据源。
orc_session_state.json authoring UI 的状态,重新打开时用来恢复你的工作区。
.orc_cache/snaps.json 增量 compose 缓存。不属于 rig 的一部分,删掉也安全。

堆栈名字派生自你的 layer 名字 — EyebrowsEyebrow 都会变成 Eyebrow,side 会追加 L/R,back 堆栈追加 Back,page 追加它的编号。

落到节点上的东西

除了 runtime 脚本及其数据外,ORC 还会向 MC 节点写入三块自己的数据:你的 pose 数据、会话状态和清单。它们只有在足够小的时候才会内嵌;更大的会留在磁盘上,因为把几兆的文本内嵌进 Harmony attribute,读取时会让它的脚本引擎崩溃。

一个小小的指针 attribute 记录着输出文件夹的场景相对路径,re-edit 和 unroll 正是靠它找到其余文件的。

把输出文件夹和场景放在一起

MC 在运行时会从磁盘读取状态文件。移动场景却不带上它们,rig 就没有 pose 可以加载了。路径是以场景相对方式存储的,所以把两者一起移动是安全的。

重新 Compose

对同一个 rig 再次 Compose 是正常且预期的行为 — 这就是你迭代的方式。

因为 ORC 存储的是帧引用而不是烘焙好的 pose,你可以回到第 861 帧,修好那道眉毛,再重新 compose:改动会被采纳。不需要重新打 key。

增量缓存意味着 re-compose 只会重新切片真正变化的部分,这也是保持同一个输出文件夹很重要的原因。

相关