UdemyのThree.js入門コースをやってみてわかったこと メモ （コース：3D Programming with JavaScript and the Three.js 3D Library）

Udemyのこちらのコースをやっていて学んだことのメモです。
最初は少し英語が聞き取りにくいかな？と思ったのですが、かなり体系的に学べていい感じです。

[3D Programming with JavaScript and the Three.js 3D Library](https://www.udemy.com/course/3d-programming-with-javascript-and-the-threejs-3d-library/)

# Three.jsでWEBブラウザに描画するために必要な3つの要素
① scene（舞台）を作る：キャンバス
② camera（視点）をつくる：カメラ
③ renderer （レンダラー）をつくる：カメラでsceneを撮ってHTMLに表示する

# 立方体をつくる

`let geometry = new THREE.BoxGeometry(1,1,1)`
height, widhth, depthの順番で指定

```code:JavaScript
 let cube;
 let createCube = function(){
   let geometry = new THREE.BoxGeometry(1,1,1) // サイズ指定
   let material = new THREE.MeshBasicMaterial({color: 0x00a1cb}); // テクスチャ指定
   
   cube = new THREE.Mesh(geometry, material);　// 立方体をつくる
   scene.add(cube); // 立方体をキャンバスに置く
 }; 
```

MeshBasicMaterialでなんのテクスチャもないフツーの立方体ができる

positionに対してADDを使うことで、ぬるぬる立方体を動かすこともできる

```code:JavaScript
 let ADD = 0.01;
 
  // main animation loop - calls 50-60 in a second.
  let mainLoop = function(){
  	cube.position.x += ADD;
     // -3もしくは3以上になったら反対側へ動かす
     if(cube.position.x <= -3 || cube.position.x >= 3)
        ADD *= -1;
        renderer.render(scene,camera);
        requestAnimationFrame(mainLoop);
   };
```

# Lotating the Cube
x軸、y軸、z軸に沿って回転させたりできる
`cube.rotation.z -= ADD;`
rotationを使うと回転させられる

axes helperを使うと画面に回転軸の線を表示できる
code:AxesHelper
 let axes = new THREE.AxesHelper(5);
 scene.add(axes);
ADDの値をあげると早く回転する

# Unit System
heightの指定の単位は決まってない
cmでもinchでもpxでもない

# 球を取る
第1引数：The radius 半径
第2, 3引数：Number of horizontal and vertical segments
→何個頂点をつくるか、多いほどなめらか、少ないと球体ではなく多角形に見える

```
code:Sphere
  let scene, camera, renderer, sphere;
  let ADD = 0.01;
  
  let createSphere = function() {
      let geometry = new THREE.SphereGeometry(5, 30, 30);
      let material = new THREE.MeshBasicMaterial({color: 0xffffff});
      cube = new THREE.Mesh( geometry, material );
      scene.add(sphere);
  };
  
  createSphere();

```

球はシンプルなテクスチャを使っちゃうとどの角度から見ても同じになって動きがわからない
→wireframeプロパティを追加
`let material = new THREE.MeshBasicMaterial({color: 0xffffff,wireframe: true});`

# Horizontal Sweep
半径の分x軸にベクトルを描いてからそれを360°回転させて球をつくっている
HorizontalSweepが描かれる範囲をPhi - 径と呼ぶ
`let geometry = new THREE.SphereGeometry(5, 30, 30, 0, Math.PI);`
第1引数：Horizontal Sweepの開始点（例：0）
第2引数：角度、この例ではMath.PI（180°）分だけ回転させている

# Vertical Sweep
y軸の描画
y軸のベクトルからx軸の半径までの範囲をTheta（シータ）と呼ぶ

# Torus 輪っか
`let geometry = new THREE.TorusGeometry(5,1,20,20,2 * Math.PI)`
5つのパラメーター
1つ目：半径
2つ目：輪っかの横方向の太さ（Tube Diametor）
3つ目：輪っかの縦方向の太さ：大きいほどまるくなる、小さいとCDぽくなる
4つ目：輪っかの内側、Tubulor Segment
5つ目：Arc、2 * Math.PIで完全な輪っかになる

`Math.random();`
1以外の整数を返す

# Custom Geometry
Vertices / vertex  頂点
頂点を3つ作ると面(face)ができる
頂点の配列をつくる

```
 let geometry = new THREE.Geometry();
 geometry.vertices.push(new THREE.Vector3(3,0,0)); // vertices[0]
 geometry.vertices.push(new THREE.Vector3(3,0,0)); // vertices[1]
 geometry.vertices.push(new THREE.Vector3(0,0,2)); // vertices[2]
 
 geometry.faces.push(new THREE.Face3(0,1,2));
 
 let material = new THREE.MeshBasicMaterial({color: 0Xffffff, side: THREE.DoubleSide });
 // 表と裏があるので、DoubleSideプロパティをつけることで両面にテクスチャを入れられる
 let shape = new THREE.Mesh(geometry, material)
 scene.add(shape);
```

動的に頂点を変化させるには
`geometry.verticesNeedUpdate = true`