콘텐츠로 이동

집계와 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-1Drawing-2를 모아둔 상태다.

그래서 배선은 Comp-2 → Comp-1이다. Peg-1은 초록 그래프에 있고, 파란 그래프에는 절대 나타나지 않는다.

Comp-2를 없애면 Peg-1을 대변할 컴프가 없어진다 — 그러면 Drawing-1Drawing-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하고 새 블록을 시작한다. 설정할 표식도, 체크할 옵션도 없다: 두 번째 컴프의 존재 자체가 경계다.

그래서 장면을 형제들의 평평한 목록으로 배치하고도 거기서 여러 개의 분리된 합성을 얻을 수 있다 — 각 그룹이 끝나야 할 자리에 컴프를 하나 두어 나누면 된다.

자식이냐 형제냐를 결정하는 규칙

스코프를 만드는 것은 그린 컨테이너뿐이고, 그것은 정확히 둘이다: PegGroup.

슬롯 컴프가 집계하는 것 이유
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와 똑같이 형제들을 집계한다. 백드롭과 컴프 사이에는 컴프가 자식을 모아올 초록 연결이 없기 때문이다. 컴프를 자식-집계자로 바꾸는 것은 PG뿐이다.

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-Carmleg를 받는다. fx-Cglowdust를 받고, 위로 이어지는 것은 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=PPeg-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)

컴프가 엉뚱한 것을 모으고 있다면 던질 질문은 둘뿐이다: 그 슬롯에 그린 컨테이너가 있는가? 그리고 같은 형제들 중에 그 위에 다른 컴프가 있는가?