집계와 sibling aggregator¶
하나의 트리가 두 개의 그래프를 설명해야 한다. 이 페이지는 그 두 번째 그래프에 대한 것이며, 모든 컴포지트가 무엇을 모을지 결정하는 단 하나의 규칙에 대한 것이다.
왜 계층이 두 개인가¶
Harmony의 Node View는 두 개의 연결 그래프를 동시에 담는다:
| 계층 | 색 | 연결 | 의미 |
|---|---|---|---|
| Input / Transform | 🟢 초록 | peg → 그 자식들 | "이것이 저것을 움직인다" |
| Output / Composite | 🔵 파랑 | comp ← 그것에 들어오는 것 | "이것이 저것을 합성한다" |
이 둘은 같은 트리가 아니다. 하나의 peg가 서로 다른 여러 합성을 구동할 수 있고, 하나의 컴포지트가 어떤 peg도 움직이지 않는 것들을 모을 수 있다.
스테이징 트리는 트리다 — 부모 관계가 정확히 한 종류뿐이다. 그래서 OSA는 그것을 초록 그래프에 쓴다. 거기서는 들여쓰기가 이미 당신이 원하는 의미를 갖는다: 자식 행은 자식 노드다.
그러면 파란 그래프에는 살아갈 들여쓰기가 남지 않는다. 그 답이 형제들 사이의 위치다.
sibling aggregator¶
그린 컨테이너가 없는 컴포지트는 자기 아래의 형제들을 집계한다.
그것이 sibling aggregator다. 안을 들여다볼 자기 스코프가 없으므로 목록 아래쪽을 본다.
Comp-1 ← starts block 1
Peg-1 ← feeds Comp-1 … but see below: what enters is Comp-2's output
Comp-2 ← starts an inner block; its output IS Peg-1's output
Drawing-1 ← feeds Comp-2
Drawing-2 ← feeds Comp-2
Drawing-3 ← feeds Comp-1
Comp-3 ← ENDS block 1, starts block 2
Drawing-4 ← feeds Comp-3
Drawing-5 ← feeds Comp-3
소리 내어 읽으면 이렇다: 컴프가 블록을 열고, 그 뒤의 모든 것이 그 안으로 흘러들며, 같은 레벨의 다음 컴프가 블록을 닫고 새 블록을 연다.
peg는 comp에 들어가지 않는다 — 그 계층의 출력이 들어간다
Peg-1은 이미지가 아니라 트랜스폼이다. Comp-1에 도착하는 것은 Peg-1 아래 모든 것의 결과이며, 그 결과는 Comp-2에서 나온다 — Peg-1의 스코프 안에 있는 컴프로, 이미 Drawing-1과 Drawing-2를 모아둔 상태다.
그래서 배선은 Comp-2 → Comp-1이다. Peg-1은 초록 그래프에 있고, 파란 그래프에는 절대 나타나지 않는다.
Comp-2를 없애면 Peg-1을 대변할 컴프가 없어진다 — 그러면 Drawing-1과 Drawing-2가 위로 올라와(bubble up) Comp-1에 개별적으로 배선되어, 하나가 아니라 두 개의 입력이 된다. 그것이 컴프가 있는 peg와 없는 peg의 차이 전부이며, 컨테이너가 출력하는 것에서 다룬다.
그리고 Peg-1 안에 두 번째 컴프가 있다면 Comp-1에 도달하는 출력이 두 개가 된다 — 블록당 하나씩:
Comp-1
Peg-1 ← now hands Comp-1 TWO outputs
Comp-2 ← block A → its output goes to Comp-1
Drawing-1 → feeds Comp-2
Comp-2b ← block B: closes A, opens its own
Drawing-2 → feeds Comp-2b
← Comp-2b's output ALSO goes to Comp-1
컨테이너 안에서 끝나는 각 블록은 트리 순서대로 자기 자신의 출력으로 위로 올라간다. 그래서 Peg-1에서 Comp-1로 도착하는 배선의 수는 Peg-1이 닫은 블록의 수와 정확히 같다 — 컴프 하나면 배선 하나, 컴프 둘이면 배선 둘, 컴프가 전혀 없으면 드로잉당 배선 하나.
무엇이 사슬을 끊는가¶
같은 레벨의 또 다른 컴포지트. 그것이 유일하다.
순회가 같은 형제들 사이에서 두 번째 컴프를 만나면 현재 블록을 flush하고 새 블록을 시작한다. 설정할 표식도, 체크할 옵션도 없다: 두 번째 컴프의 존재 자체가 경계다.
그래서 장면을 형제들의 평평한 목록으로 배치하고도 거기서 여러 개의 분리된 합성을 얻을 수 있다 — 각 그룹이 끝나야 할 자리에 컴프를 하나 두어 나누면 된다.
자식이냐 형제냐를 결정하는 규칙¶
스코프를 만드는 것은 그린 컨테이너뿐이고, 그것은 정확히 둘이다: Peg와 Group.
| 슬롯 | 컴프가 집계하는 것 | 이유 |
|---|---|---|
C 단독 |
아래 형제들 | 집계 지점 외에는 아무것도 아님 |
D-C |
아래 형제들 | 그린 컨테이너가 없으니 스코프도 없음 |
BD-C |
아래 형제들 | 백드롭은 시각적이다 — 노드를 소유하지 않는다 |
BD-D-C |
아래 형제들 | 마찬가지: 백드롭은 배선에 대해 아무것도 바꾸지 않는다 |
P-C, G-C |
자식들 | 그린 컨테이너가 내부 스코프를 만든다 |
P-D-C, G-D-C |
자식들 | 동일 |
BD-P-C, BD-P-G-D-C |
자식들 | 그렇게 만드는 건 peg다. 백드롭은 상자를 그릴 뿐 |
백드롭은 누가 집계하는지를 절대 바꾸지 않는다
사람들이 틀리는 지점이고, 대놓고 말할 가치가 있다: BD는 시각적이다. BG=BD-C는 맨 C와 똑같이 형제들을 집계한다. 백드롭과 컴프 사이에는 컴프가 자식을 모아올 초록 연결이 없기 때문이다. 컴프를 자식-집계자로 바꾸는 것은 P나 G뿐이다.
Peg(또는 Group) + Comp 슈퍼 노드¶
이제 당신이 매일 만드는 경우다.
그린 컨테이너 와 컴프를 함께 가진 슬롯 — hero=P-C, hero=BD-P-G-C — 은 컴프가 자신의 직계 자식들을 트리 순서대로 집계하게 만든다…
…자기 자신이 컴프인 첫 번째 자식까지만. 그 자식이 새로운 sibling-aggregator 블록을 시작하고, 그 뒤의 모든 것은 그 블록에 속한다.
hero=P-C ← green scope; its comp collects the children below
├── arm=D → feeds hero-C
├── leg=D → feeds hero-C
├── fx=C ← a comp among the children: block boundary
├── glow=D → feeds fx-C
└── dust=D → feeds fx-C
hero-C는 arm과 leg를 받는다. fx-C는 glow와 dust를 받고, 위로 이어지는 것은 fx-C 자신의 출력이다.
이것이 합성 언어의 전부다: 그린 컨테이너가 스코프를 열고, 그 안의 컴프가 다음 컴프가 멈추라고 할 때까지 모은다.
컨테이너가 출력하는 것¶
| 컨테이너가 | 그 출력 |
|---|---|
| 내부 컴프를 가짐 | 단일 출력 — 그 컴프, 또는 그 뒤의 마지막 이펙트 |
| 내부 컴프가 없음 | 다중 출력: 안의 모든 드로잉이 위로 올라간다 |
컴프가 없는 peg는 아무것도 병합하지 않는다. 부모에게 목록을 건네고, 각 항목은 부모의 컴프에 개별적으로 배선된다.
SuperNode=P-D-C
├── Peg-1 (P only, no Comp)
│ ├── Drawing-A
│ └── Drawing-B
└── Drawing-C
Peg-1은 [Drawing-A, Drawing-B]를 반환하므로 SuperNode-C는 네 개의 입력을 받는다:
| 포트 | 입력 |
|---|---|
| 3 | SuperNode 자신의 드로잉 |
| 2 | Drawing-A (Peg-1에서 올라옴) |
| 1 | Drawing-B (Peg-1에서 올라옴) |
| 0 | Drawing-C |
peg 안에 컴프를 넣으면 그 둘이 하나의 입력으로 합쳐진다. 그것이 Peg-1=P와 Peg-1=P-C의 실질적 차이이며, 보통 그래프에 예상보다 배선이 많은 이유다.
포트 순서¶
파란 그래프에는 방향이 있고, 그것은 고정되어 있다:
| 포트 | 렌더 위치 | 자리 |
|---|---|---|
| Port N (최상) | 앞 | Node View의 왼쪽 |
| Port 0 (최하) | 뒤 | Node View의 오른쪽 |
그러니 Node View에서 가장 왼쪽 요소가 렌더의 맨 위에 있고, 가장 오른쪽이 맨 뒤에 있다. 슈퍼 노드 안에서는 슬롯의 자기 드로잉이 앞쪽 포트를 차지하고, 자식들이 그 아래 포트들을 왼쪽에서 오른쪽으로 차지한다.
Wide Bus가 트리의 꼭대기를 왼쪽에 두는 이유도 그것이다: 트리 순서, 포트 순서, 렌더 순서는 같은 순서이고, 같은 방식으로 읽힌다.
트리에서 읽기¶
이걸 머릿속으로 시뮬레이션할 필요는 없다 — Details 열이 이미 각 행이 무엇을 만드는지 알려주고, 위의 규칙이 그 컴프가 무엇을 모을지 알려준다:
BACKGROUND (Backdrop > Peg > Comp) ← green scope: collects its children
sky (Read) → feeds BACKGROUND-C
clouds (Read) → feeds BACKGROUND-C
EFFECTS (Backdrop > Peg > Comp > Effects)
컴프가 엉뚱한 것을 모으고 있다면 던질 질문은 둘뿐이다: 그 슬롯에 그린 컨테이너가 있는가? 그리고 같은 형제들 중에 그 위에 다른 컴프가 있는가?