[ #2 ] Object의 Transform 변경

2024. 5. 21. 03:04ThreeJS 공부 뿌셔

★☆ 이 글은 Three.js journey 강의를 통해 작성하게 되었습니다 ☆★ 

 

 

ThreeJS의 다양한 오브젝트들의 Transform 속성들을 변경해보자!

 

Transform 속성이 뭐냐!?

  • Position (오브젝트의 위치)
  • Scale (오브젝트의 크기)
  • Rotation (오브젝트의 회전)
  • Quaternion (오브젝트의 회전)

 

🍀 Position

Position은 Vector3의 타입을 가진다!

Vector3는 Three.js의 3D 공간에서의 위치, 이동 벡터 등을 표현하기 위해 사용되는 클래스

 

Position 설정 방법을 미리 말하자면, 두가지 방법이 있다,

  1.  x, y, z 하나씩 설정해주기
  2.  x, y, z 한번에 설정해주기
// 하나씩 설정
mesh.position.x = 1;
mesh.position.y = 2;
mesh.position.z = 0.7;

// 한번에 설정
camera.position.set(2, 0, 0.2);

 

Position 속성의 유용 메서드도 몇가지 소개할게요우!

// 원점([0,0,0])에서의 거리
mesh.position.length();

// 특정 지점 및 오브젝트와의 거리
mesh.position.distanceTo(camera.position);

//거리가 1이 될때까지 position xyz 비율을 유지하며 줄어듦
mesh.position.normalize();

 

 

🍀 Scale

Position과 같이 Vector3를 타입으로 가지며,

설정 방법도 Position과 마찬가지로,

// 하나씩 설정
mesh.scale.x = 1.5;
mesh.scale.y = 2;
mesh.scale.z = 2.1;

// 한번에 설정
mesh.scale.set(2, 0.5, 0.5);

※ 음수 값을 넣을 순 있지만 오류가 발생할 이유가 될 수 있으므로, 음수 값은 사용하지 말기!

 

 

🍀 Rotation

Rotation은 Vector3가 아닌 Euler를 타입으로 갖는다! 헉!

(찾아보니, 축을 통해 회전시키는 특징 때문에, Vector3 대신 Euler를 사용한다고 한다..!)

 

또한, x y z의 회전값의 변경 순서에 따라서도 결과 모습이 다르게 보인다! ('gimbal lock'의 이슈)

Rotation 이녀석 알고보니 더욱 까다로운 놈이다

mesh.rotation.reorder('YXZ');
// 위와 같이 rotation 실행 순서를 정해 줌
// 대문자로 표기
// rotation 값 설정 코드의 상단에서 실행해줘야 함 (하단에 있을 경우 적용X)

// ex) FPS게임에서 사용자가 마우스를 통해,
//     1. 왼쪽으로 비틀고, 하늘을 올려다 본 모습과
//     2. 하늘을 올려다 본 후, 왼쪽으로 비튼 모습이
//     서로 다르게 보이기 때문에 꼭 'reorder'의 설정이 필요!

reorder('XYZ')의 경우
reorder('YXZ')의 경우

 

Rotation의 유용한 메서드 소개할게요우!

// 특정 지점 및 오브젝트를 바라보는 카메라
camera.lookAt(mesh.position);

 

 

🍀 Quaternion

네? Rotation 짜증난다구요? 그렇담 마라맛 Rotation이 여기 있습니다

const quaternion = new THREE.Quaternion();

const axis = new THREE.Vector3(1, 0, 0); // x축을 기준으로
const angle = Math.PI / 4; // 45도 회전

quaternion.setFromAxisAngle(axis, angle);
cube.quaternion.copy(quaternion);

네? 너무 맵다구요?? 저두요

 

Quaternion은 Vector3 타입인 axisangle을 필요로 합니다.

확실히 Quaternion은 'gimbal lock'과 같은 이슈는 해결해 주지만, 사용하기 복잡하다는 단점이 있죠.!

저는 그냥 Rotation 쓰겠습니ㅏ..

 

 

🍀 Axes Helper

Axes Helper는 x, y, z 축을 화면에 제공함으로써,

더욱 쉽고 편안하게 Transform을 설정할 수 있도록 도와주는 착한 친구입니다..

특히 카메라가 움직이는 순간, 마니마니 어지럽습니다요

const axesHelper = new THREE.AxesHelper(20); // 축의 길이를 인자로 삽입 
scene.add(axesHelper);

어때요 좋죠?

 

 

🍀 Group

프로젝트가 커질 수록, 그룹으로 묶어 오브젝트들을 관리하는 것이 유리합니다!

ex. 여러 빌딩 오브젝트들

 

그룹으로 묶인 오브젝트들은, 한 번에 Transform의 변경이 가능합니다!

 

  • 그룹화하기
const group = new THREE.Group();
scene.add(group);
// 만든 group 객체도 꼭 scene에 넣어주기

const cube1 = new THREE.Mesh(
  new THREE.BoxGeometry(1, 1, 1),
  new THREE.MeshBasicMaterial({ color: "pink" })
);

const cube2 = new THREE.Mesh(
  new THREE.BoxGeometry(1, 1, 1),
  new THREE.MeshBasicMaterial({ color: "green" })
);

const cube3 = new THREE.Mesh(
  new THREE.BoxGeometry(1, 1, 1),
  new THREE.MeshBasicMaterial({ color: "blue" })
);

cube2.position.set(2, 1, 0);
cube3.position.set(-1.5, 0.5, 0);
group.add(cube1, cube2, cube3);
// group 객체에 오브젝트들 넣어주기
  • 그룹의 Transform
group.position.y = 1.5;
group.rotation.y = Math.PI / 4;
group.scale.set(2, 0.5, 1);

Before
After