좌표계¶
세 개의 애플리케이션, 어느 쪽이 위인지와 한 단위가 얼마나 큰지에 대한 세 가지 생각. 이 페이지는 OTS가 그에 대해 무엇을 하는지 — 그리고 그것이 존재하는 이유인 단 하나의 실수를 설명합니다.
OTS를 쓰기 위해 이 문서를 읽어야 할 필요는 없습니다. 무언가가 이상하게 회전된 채로 도착했을 때, 또는 이 도구가 왜 보낸 쪽이 아니라 파일을 신뢰하는지 알고 싶을 때 읽으세요.
정규 공간¶
디스크에 저장되는 모든 것은 하나의 공간에 담깁니다:
| 위쪽 | Y |
| 손 방향(handedness) | 오른손 |
| 단위 | 미터 |
| 회전 (애니메이션) | Euler XYZ, 도(degree) |
| 회전 (rest) | Quaternion, w x y z |
이것은 Harmony의 OGL 관례이며, 그래서 Harmony가 항등(identity) 케이스가 됩니다. 다른 모든 애플리케이션은 자신의 공간을 선언하고 경계에서 변환합니다.
| 애플리케이션 | 네이티브 공간 | 정규 공간으로의 변환 |
|---|---|---|
| Harmony | Y-up 오른손, 미터 (OGL) | 항등, 그리고 런타임 field ↔ OGL 스케일 |
| Blender | Z-up 오른손, 미터 | 스위즐 (x, z, −y) |
| Maya | Y-up 오른손, 센티미터 | ×0.01, 축 교환 없음 (Z-up 씬은 스위즐도 함께) |
헤더¶
모든 파일은 자신이 어떤 공간에서 쓰였는지 설명하는 coordinate_system 블록을 지니고 있습니다. 모든 reader는 그 블록을 보고 그에 맞춰 변환합니다.
이것이 여섯 개의 경로가 경로별 전용 코드 없이 동작하는 이유입니다. reader는 어떤 애플리케이션이 그 파일을 썼는지 알지도, 신경 쓰지도 않습니다 — 오직 그 파일이 어떤 공간을 선언하는지만 봅니다. 애플리케이션을 추가한다는 건 공간을 추가하는 일입니다.
또한 이것이 디스크상의 값이 버전 사이에서 의미가 바뀌지 않는 이유이기도 합니다: 숫자는 항상 정규 공간의 값이고, 그 숫자가 무엇을 기준으로 하는지 말해주는 헤더가 항상 거기 있습니다.
네 개의 채널, 네 개의 변환¶
흥미로운 부분은 네 종류의 데이터가 서로 다르게 변환된다는 점입니다.
부호 있는 축 치환(permutation), 그다음 단위 스케일.
Blender 위치 (x, y, z)는 정규 공간에서 (x, z, −y)가 됩니다. Maya 위치는 0.01을 곱합니다.
w 성분은 그대로 보존되고, 벡터 부분은 위치와 똑같이 치환됩니다.
단위 스케일 없음 — 회전에는 길이가 없습니다.
부호 없는 치환, 그리고 단위 스케일 없음.
스케일은 크기(magnitude)입니다. 부호를 뒤집으면 오브젝트가 미러링되는데, 축 관례 변경이 의미하는 바는 결코 그게 아닙니다.
치환이 아닙니다. 사람들이 걸려 넘어지는 지점이 바로 여기입니다.
아래를 보세요.
Euler 함정¶
이 실수를 있는 그대로 적습니다. OTS가 지금의 형태로 존재하는 이유이기 때문입니다:
회전의 기저 변경은 그 Euler 각의 치환이 아닙니다.
그래야 할 것처럼 보이긴 합니다. 위치가 (x, y, z) → (x, z, −y)로 스위즐된다면, 회전도 당연히 그럴 것 같지 않나요? 게다가 항등 기저에서는 우연히 잘 동작하기 때문에, 이 버그는 테스트를 통과하고 살아남습니다.
하지만 Z-up ↔ Y-up 변경에서 Euler 각을 치환하면 잘못된 축을 중심으로 도는 회전이 나옵니다. 오브젝트가 돌긴 하니까 — 그래서 눈에 띄게 망가져 보이진 않지만 — 잘못 도는 것이고, 그 오차는 chain을 따라 누적됩니다. 이것이 직접 만든 3D 브리지의 전형적인 증상입니다: "회전은 넘어왔는데, 뭔가 맞지 않아요."
올바른 변환은 회전 자체의 켤레(conjugation)입니다:
- Euler 각을 quaternion으로 변환합니다.
- 그 quaternion의 축을 부호 있는 치환으로 회전시킵니다.
- 다시 Euler XYZ로 변환합니다.
OTS는 이것을 어디서나 수행하며, 치환이 항등일 때는 작업을 건너뛰는 빠른 경로를 둡니다 (그래서 Y-up 씬에서 Harmony ↔ Maya는 비용이 0입니다).
가능한 곳에서 회전은 quaternion으로 이동합니다
Euler 각과 나란히, 각 애니메이션 키는 bake된 world matrix에서 계산한 진짜 quaternion도 함께 지니고 다닙니다. 이건 순서 독립적이라서 Euler 순서 모호성을 통째로 피해 갑니다 — 그리고 모든 importer는 그 값이 있으면 그쪽을 선호합니다. Euler 값은 사람이 읽을 수 있는 대비책으로 남아 있습니다.
단위¶
| Harmony | 미터. OTS가 라이브 씬에 직접 물어보는 런타임 field ↔ OGL 스케일을 경유합니다. 상수가 아닙니다 — 해상도, 시야각, 종횡비에 따라 달라집니다 |
| Blender | 미터. 변환 없음 |
| Maya | 센티미터. 내보낼 때 ×0.01, 들여올 때 ×100 |
.pvt의 Scale 옵션은 이상한 작업 크기로 제작된 rig을 위한 별개의 사용자용 배수입니다. 자동으로, 눈에 띄지 않게 일어나는 애플리케이션 간 단위 변환과는 다른 것입니다.
Harmony의 "가짜 quaternion"¶
Harmony에는 QUATERNIONPATH라는 컬럼 타입이 있는데, 이건 quaternion이 아닙니다. 3D-path 컬럼의 서브클래스로, 세 개의 Euler 각 성분과 속도(velocity)를 저장합니다.
그래서 Harmony peg의 회전은 컬럼 이름이 무엇이든, 모든 peg 모드에서 항상 Euler XYZ 도(degree)로 읽고 씁니다. 이걸 (w, x, y, z) quaternion으로 읽으면 쓰레기 값이 나옵니다.
In Harmony를 참조하세요.
카메라 조준¶
카메라는 한 가지 보정을 더 받습니다. "카메라가 어느 쪽을 향하는가"는 애플리케이션마다 다른 관례이기 때문입니다:
| 애플리케이션 | 카메라가 바라보는 방향 | import 시 |
|---|---|---|
| Harmony | 자기 자신의 −Z — 이미 정규 공간의 정면 | roll만 |
| Maya | 자기 자신의 −Z — 이미 정규 공간의 정면 | roll만 |
| Blender | Z-up 월드에서의 −Z | X축 +90°, 그리고 roll |
Blender의 기울기는 export 시 다시 제거되므로, 정면을 보는 카메라는 매번 90°씩 어긋남이 쌓이는 대신 항등 peg으로 왕복합니다.
FOV는 Harmony의 씬 설정에 맞춰 수직 각도로 전달되며, 각 애플리케이션은 수직 센서 fit으로 명시적으로 설정됩니다. Cameras를 참조하세요.
알려진 한계¶
Z-up Maya 씬은 보간 정보만 담은 handle을 내보냅니다. keyframe 값은 올바르게 변환되지만, 키별 bezier tangent는 단순화됩니다. 정확한 tangent 형태가 중요하다면 Maya에서 Y-up으로 작업하세요.