이번 시간에는 three.js에서 물리엔진을 사용해본다. 물리엔진은 어렵다. 따라서 잘만들어둔 라이브러리를 사용함. 이번 시간에는 가장 사용이 쉬운 cannon.js로 만들어본다.

Mesh(three.js) + Body(cannon.js)의 조합으로 물리엔진을 구현한다. Body는 눈에 보이지 않은 상태로 적용되어 구현된다. Mesh 자체는 중력이나 떨어지는 등의 액션을 구현할 수 없다. 이런 것들은 cannon.js가 구현해 줌. 이걸 구현하기 위해서는 Body의 위치를 Mesh가 따라가도록 해줘야 한다. 한 쌍이 되어 움직인다고 보면 됨

물리엔진 월드 생성

cannon.js 문서는 여기를 참조. 일단 설치를 해준다.

> npm i cannon-es

그러면 아래와 같이 접근할 수 있음

physics/src/ex01.js

import * as CANNON from "cannon-es";

먼저 중력을 적용해주기 위해 Controls에 아래와 같은 코드를 추가해본다.

import * as THREE from "three";
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
import * as CANNON from "cannon-es";

// ----- 주제: cannon.js 기본 세팅

export default function example() {
  // Renderer, Scene, Camera, Light ..

  // Controls
  const constols = new OrbitControls(camera, renderer.domElement);

  const connonWorld = new CANNON.World();
  connonWorld.gravity.set(0, -10, 0); // 중력을 세팅(x, y, z축 설정) - 아직 아무런 변화가 없다.

  // Mesh, etc...
}

위와 같이 중력을 grayity.set으로 구현함. 물론 화면상 변화는 없다. 중력이 세팅되었을 뿐 아무런 이벤트가 없기 때문. 다음으로는 중력에 의해 부딪힐 바닥을 만들어보겠다.

먼저 바닥으로 사용할 Mesh를 아래에 추가해준다.

export default function example() {
  // Renderer, Scene, Camera, Light ..

	// ..
  connonWorld.gravity.set(0, -10, 0);

  // Mesh
  const floorMesh = new THREE.Mesh(
    new THREE.PlaneGeometry(10, 10),
    new THREE.MeshStandardMaterial({ color: "slategray" })
  );

  scene.add(floorMesh);

	// ..
}

스크린샷 2023-04-21 오후 11.36.03.png

그럼 요래 노출.. 바닥이니까 아래로 가게 조정해준다.

export default function example() {
  // Renderer, Scene, Camera, Light ..
	// ..
  connonWorld.gravity.set(0, -10, 0);

  // Mesh
  const floorMesh = new THREE.Mesh(
    new THREE.PlaneGeometry(10, 10),
    new THREE.MeshStandardMaterial({ color: "slategray" })
  );

  floorMesh.rotation.x = -Math.PI * 0.5; // 앞면이 위로 향하기 위해 음수 처리
  scene.add(floorMesh);

  const boxGeometry = new THREE.BoxGeometry(1, 1, 1);
  const boxMaterial = new THREE.MeshStandardMaterial({ color: "seagreen" });
  const boxMesh = new THREE.Mesh(boxGeometry, boxMaterial);

  boxMesh.position.y = 0.5; // boxMesh 위치를 0.5만큼 올려주면 모두 보임
  scene.add(boxMesh);

	// ..
}

위와 같이 floorMesh와 boxMesh 모두 값을 수정해주면 아래와 같이 노출됨

스크린샷 2023-04-21 오후 11.40.13.png

이제 cannon 바닥도 설정해줘야한다.

물리가 적용되는 객체 만들기