【three.js】Meshに枠線を追加しアニメーションする

作るもの⤵︎
![rotation_sample.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636889/526f12c1-572c-481d-5da1-886eb55b8dae.gif)

# 先に完成物

僕みたいにせっかちな方はこちらからどうぞ！
省略しているので、実際に使うときは関数にまとめるなりしてくださいまし。

```js:js
// 二十面体のgeometryとmaterialを定義
const geometry = new THREE.IcosahedronGeometry(300, 3); // 半径, 面の細かさ
const material = new THREE.MeshBasicMaterial({ color: 0x49ef4 }); // 二十面体の色

// 二十面体を作成
const icosahedron = new THREE.Mesh(geometry, material);

// 枠線を作成
const icosahedronLine = new THREE.LineSegments(
  new THREE.EdgesGeometry(geometry), // 線を生成する元になるgeometry
  new THREE.LineBasicMaterial({ color: 0xffffff }) // 線のmaterial
);

// 二十面体に枠線を追加
icosahedron.add(icosahedronLine);

// sceneに追加
scene.add(icosahedron);

function animate() {
  // 再帰
  requestAnimationFrame(animate);
  // レンダリング
  renderer.render(scene, camera);

  // 二十面体を回転させる
  icosahedron.rotation.y += 0.01;
}

// 関数呼び出し
animation();
```




# 元となるコード

シーンやカメラ、レンダラーは作成済みとする。

```js:js
// 二十面体のgeometryとmaterialを定義
const geometry = new THREE.IcosahedronGeometry(300, 3); // 半径, 面の細かさ
const material = new THREE.MeshBasicMaterial({ color: 0x49ef4 }); // 二十面体の色

// 二十面体を作成
const icosahedron = new THREE.Mesh(geometry, material);

// sceneに追加
scene.add(icosahedron)
```


# 枠線を追加する
LineSegments、EdgesGeometryを用いて作成する。

```js:js
// 二十面体のgeometryとmaterialを定義
const geometry = new THREE.IcosahedronGeometry(300, 3); // 半径, 面の細かさ
const material = new THREE.MeshBasicMaterial({ color: 0x49ef4 }); // 二十面体の色

// 二十面体を作成
const icosahedron = new THREE.Mesh(geometry, material);

+ // 枠線を作成
+ const icosahedronLine = new THREE.LineSegments(
+   new THREE.EdgesGeometry(geometry), // 線を生成する元になるgeometry
+   new THREE.LineBasicMaterial({ color: 0xffffff }) // 線のmaterial
+ );

// sceneに追加
scene.add(icosahedron);
+ scene.add(icosahedronLine);
```

# アニメーション

円が回転するアニメーションを追加してみる。

```js:js
+ function animate() {
+   // 再帰
+   requestAnimationFrame(animate);
+   // レンダリング
+   renderer.render(scene, camera);

+   // 二十面体を回転させる
+   icosahedron.rotation.y += 0.01;
+   icosahedronLine.rotation.y += 0.01;
+ }

+ // 関数呼び出し
+ animation();
```


![rotation_sample.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/636889/526f12c1-572c-481d-5da1-886eb55b8dae.gif)

回った！


# 枠線を立体に結合する

これで完成でも良いが、この十二面体をアニメーションするたびに毎回`icosahedron`と`icosahedronLine`を指定するのは面倒くさい。
ので、**シーンではなく十二面体に枠線を追加する**。~~（これが出来るのに気づかず一晩潰した）~~
アニメーションのターゲットから外すのを忘れずに。

```diff_javascript:js
// 二十面体のgeometryとmaterialを定義
const geometry = new THREE.IcosahedronGeometry(300, 3); // 半径, 面の細かさ
const material = new THREE.MeshBasicMaterial({ color: 0x49ef4 }); // 二十面体の色

// 二十面体を作成
const icosahedron = new THREE.Mesh(geometry, material);

// 枠線を作成
const icosahedronLine = new THREE.LineSegments(
  new THREE.EdgesGeometry(geometry), // 線を生成する元になるgeometry
  new THREE.LineBasicMaterial({ color: 0xffffff }) // 線のmaterial
);

// sceneに十二面体を追加
scene.add(icosahedron);
- // scene.add(icosahedronLine);
// 十二面体に枠線を追加
+ icosahedron.add(icosahedronLine);

function animate() {
  // 再帰
  requestAnimationFrame(animate);
  // レンダリング
  renderer.render(scene, camera);

  // 二十面体を回転させる
  icosahedron.rotation.y += 0.01;
- // icosahedronLine.rotation.y += 0.01;
}

// 関数呼び出し
animation();
```


これで、`icosahedron`を`animate()`やら`AnimationMixer`やらでアニメーションさせれば**枠線も一緒にアニメーションする**ようになった。


# おしまい

意外と検索に引っ掛からなかったので、メモがてら掲載しました。