Three.js

Three.js 객체의 이동, 리사이즈, 회전 | position, scale, rotation

FACET 2023. 12. 22. 20:00

선행학습

이번 글에서는 객체의 변형을 구현하기 위한 핵심 코드 라인만 기재되어 있다. 객체 자체를 만들고 화면에 띄우는 과정은 아래 글을 통해 확인 가능하다.

 

CONTENTS

 

이번 글에서 다룰 내용은 다음과 같다.

  • AxesHelper 켜기
  • Three.js 객체의 이동 position
  • Three.js 객체의 크기 변형 scale
  • Three.js 객체 회전 rotation

AxesHelper 켜기

 

객체의 이동과 변형을 시작하기 전, 변화를 좀더 뚜렷하게 확인할 수 있도록 '축'선을 켜준다.

 

// 축선 켜기
const axesHelper = new THREE.AxesHelper(3) // 괄호 안 숫자 = 선 길이

// 이것도 scene에 추가해줘야 나온다.(scene 이미 만드셨죠?)
scene.add(axesHelper)

 

 


Three.js 객체의 이동 position

 

Three.js에서 객체의 이동은 position 프로퍼티를 이용해서 하며, position 을 활용하는 방법은 다음과 같이 여러개로 나뉜다.

 

1) 축별 이동 좌표 지정(.x, .y, .z)

- 사용자가 만들어둔 Mesh 객체의 x, y, z 좌표값을 지정해서 객체의 위치를 바꾸는(=이동시키는) 방법은 다음과 같다.

myMesh.position.x = 1.2;
myMesh.position.y = 2.5;
myMesh.position.z = -1.0;

 

2) 이동 좌표 한번에 지정(.set)

- x, y, z를 모두 바꿀 경우 set이라는 함수를 이용해서 압축적으로 표현할 수 있다.

- 좌표값 대신 다른 객체의 position값을 통째로 넣어도 되지 않을까?

// 정석
myMesh.position.set(1.2, 2.5, -1.0); // x, y, z

// 꼼수. 안될 수도 있음
myMesh.position.set( otherMesh.position );

 

3) 거리값이 1이 되게 옮기기(.normalize)

- position.normalize를 사용하면 원점 기준으로 현재 객체의 각도를 유지하면서 거리만 1이 되게 이동시킨다.

 

myMesh.position.normalize()

 

※ TIP 객체간 거리 측정 툴

// 두 객체 사이의 거리 측정하기
// mesh.position.distanceTo()를 쓰면 두 mesh 객체 사이의 거리값을 확인할 수 있다.
// 이때 거리는 객체의 중심점인 position 정보를 기준으로 한다.

console.log( myMesh.position.distanceTo( yourMesh.position ) )

Three.js 객체의 크기 변형 scale

 

Three.js에서 객체의 크기 변형은 scale 프로퍼티를 이용해서 하며, scale 을 활용하는 방법은 다음과 같이 여러개로 나뉜다.

 

1) 축별 scale 변형(.x, .y, .z)

myMesh.scale.x = 0.8;
myMesh.scale.y = 2.5;
myMesh.scale.z = 0.2;

 

2) scale 한번에 변형(.set)

myMesh.scale.set(0.8, 2.5, 0.2); // x, y, z

 


Three.js 객체 회전 rotation

 

Three.js에서 객체의 이동은 rotation 프로퍼티를 이용해서 하며, rotation 을 활용하는 방법은 다음과 같이 여러개로 나뉜다. 단, 객체의 회전시에는 주의할 점이 3개 있다.

 

1) 첫 번째, 회전값은 라디안

- 즉 π = 180°를 염두에 두고 회전값을 입력해야 한다.

 

2) 두 번째, 돌리기 전 축 방향 확인

- Three.js에서는 높이가 y축이다. 다른 3D 소프트웨어와 기본 축방향이 다를 수 있다.(아래 그림 참고)

- 아래 그림에서  X축은 빨강,  Y축은 초록,  Z축은 파란색으로 표현되었다. 높이가 y축이고, z는 물체가 가까이 오냐 멀리 가냐에 영향을 미친다(이건 카메라 위치에 따라 다름)는 점을 기억해두는 편이 도움이 된다.

 

Three.js 축방향 참고 - 빨강(X축), 초록(Y축), 파랑(Z축)  ⓒthreejs.org (출처: https://threejs.org/examples/#webgl_geometry_convex)

 

3) 세 번째, 여러 축 회전시 때 순서는 YXZ

- 여러 축에 대해 회전을 연달아할 때 그 적용 순서에 따라서 예상치 못한 결과물이 나올 수 있다.
- 따라서 어느 축으로 먼저 회전시킬 건지 순서를 지정해야 하는데, 가장 직관적인 순서는 Y축 > X축 > Z축 순서이다. 이 순서를 회전 실행 이전에 reorder프로퍼티를 사용해서 지정해주어야 한다.

//  Y축 회전 > X축 회전 > Z축 회전 순으로 실행
myMesh.rotation.reorder('YXZ'); // 축이름은 대문자로 써야함

myMesh.rotation.x = Math.PI * 0.25; // X축을 중심으로 45도 회전
myMesh.rotation.y = Math.PI * 0.25; // y축을 중심으로 45도 회전

 

 [ 참고자료 : Quaternion ]

- 이러한 순서 문제를 해결하고 한층 발전된 회전 프로퍼티로 'Quaternion'이 있다. 이를 rotation 대신 사용할 수 있다. 아직 한글화된 문서는 없는 것 같으며, 영어로 된 샘플코드 및 변수 설명은 여기에서 확인할 수 있다.