OrthographicCamera로 2D editor 좌표계 만들기
2D editor에는 원근감이 필요하지 않습니다. 도형이 카메라에서 멀어졌다고 작아지면 안 됩니다. 그래서 Three.js에서는 OrthographicCamera를 기본 카메라로 둡니다.
viewport 크기로 frustum을 만든다
const halfW = canvasCssWidth / 2 / zoom;
const halfH = canvasCssHeight / 2 / zoom;
camera.left = -halfW;
camera.right = halfW;
camera.top = halfH;
camera.bottom = -halfH;
camera.position.set(panX, panY, 1000);
camera.lookAt(panX, panY, 0);
camera.updateProjectionMatrix();
CSS pixel 크기, zoom, pan이 바뀌면 camera frustum을 갱신합니다.
editor camera 값을 Three.js camera로 옮긴다
raw WebGL 파트에서 썼던 camera는 보통 screen = (world - camera.xy) * zoom 형태였습니다. Three.js에서는 이 관계를 OrthographicCamera의 frustum과 position으로 나눠 표현합니다.
function syncOrthographicCamera(camera, editorCamera, viewport) {
const halfW = viewport.width / editorCamera.zoom / 2;
const halfH = viewport.height / editorCamera.zoom / 2;
camera.left = -halfW;
camera.right = halfW;
camera.top = halfH;
camera.bottom = -halfH;
camera.position.set(editorCamera.x + halfW, -(editorCamera.y + halfH), 1000);
camera.lookAt(editorCamera.x + halfW, -(editorCamera.y + halfH), 0);
camera.updateProjectionMatrix();
}
여기서 editorCamera.x/y를 viewport의 왼쪽 위 world 좌표로 둘지, camera center로 둘지는 프로젝트 정책입니다. 중요한 것은 한 번 정한 정책을 pointer 변환, grid, hit test에도 같은 방식으로 쓰는 것입니다.
Y축 방향을 명시한다
Canvas 2D와 CSS는 보통 아래로 갈수록 y가 증가합니다. Three.js world는 관례적으로 위쪽이 양수 y입니다. 어느 쪽을 editor world로 삼을지 먼저 정해야 합니다.
option A: editor y down, adapter에서 Three.js 좌표 변환
option B: editor y up, UI 좌표 변환에서 보정
editor world를 y-down으로 유지한다면 adapter에서만 y를 뒤집는 편이 CSS/Canvas 경험과 이어집니다.
function editorPointToThree(point) {
return new THREE.Vector3(point.x, -point.y, 0);
}
function syncMeshTransform(mesh, node) {
mesh.position.set(node.x + node.width / 2, -(node.y + node.height / 2), 0);
mesh.rotation.z = -node.rotation;
mesh.scale.set(node.width, node.height, 1);
}
회전 부호까지 같이 뒤집어야 화면에서 보이는 방향이 editor 모델과 맞습니다.
오늘의 핵심
OrthographicCamera는 2D editor의 viewport입니다. zoom/pan은 도형을 직접 움직이는 것이 아니라 camera가 world를 보는 방식을 바꾸는 값입니다.