scene graph와 nested transform
이번에는 scene graph입니다.
이름은 거창하지만 핵심은 “부모와 자식의 transform을 어떻게 이어 붙일까?”입니다. 그룹 안에 사각형이 있고, 그 그룹을 움직이면 사각형도 같이 움직입니다. 그런데 사각형 자신의 local 위치는 그대로일 수 있습니다.
이 관계를 제대로 표현하는 구조가 scene graph입니다.
world matrix는 부모와 자식의 곱이다
worldMatrix(node) = worldMatrix(parent) * localMatrix(node)
부모가 움직이면 자식의 world matrix도 바뀝니다. 하지만 자식의 local matrix는 그대로입니다. 이게 그룹 편집의 핵심입니다.
group moves -> child world changes
child local stays same
그래서 그룹을 이동할 때 자식 DOM을 하나씩 직접 수정하지 않습니다. 그룹의 local matrix를 바꾸고, 자식은 그 결과를 따라옵니다.
reparent는 좌표 변환 문제다
오브젝트를 다른 그룹으로 옮길 때 화면 위치를 유지하려면 새 local matrix를 계산해야 합니다.
newLocal = inverse(newParentWorld) * oldWorld
이 공식이 없으면 오브젝트가 그룹을 옮기는 순간 화면에서 튀어버립니다. 사용자는 “내가 옮긴 건 레이어인데 왜 위치까지 바뀌죠?”라고 묻습니다. 맞는 질문입니다. reparent는 항상 world 보존을 생각해야 합니다.
group bounds
그룹의 bounds는 자식 world bounds의 합집합으로 만들 수 있습니다.
group bounds = union(child world bounds)
모델 트리와 DOM 트리는 1:1일 수도 있고 아닐 수도 있습니다. 렌더링 최적화를 위해 DOM 구조를 다르게 만들 수 있지만, 편집 모델의 scene graph는 명확해야 합니다.
데모에서 볼 것
데모에서는 부모 frame 안에 자식 object가 실제 DOM 자식으로 들어 있습니다. 부모 transform을 바꾸면 자식의 childLocal 값은 그대로인데 childWorld가 같이 바뀝니다. 자식 transform 슬라이더를 바꾸면 부모 좌표계 안에서 자식만 움직입니다.
canvas 안의 회색 선은 parent origin에서 child origin으로 이어지는 관계를 보여줍니다. 점선 box는 child의 world AABB입니다. 그러니까 “자식은 부모 안에 산다”와 “화면 위치는 world matrix로 계산된다”가 동시에 보이는 장면입니다. scene graph가 폴더 정리가 아니라 수학 장부라는 뜻이죠.
오늘의 핵심은 계층 구조가 단순한 폴더 정리가 아니라 transform 누적 규칙이라는 점입니다. 그룹, 프레임, 컴포넌트 인스턴스가 모두 이 위에 올라갑니다.