babylon.jsチュートリアル２ - Discover Basic Elements

babylon.jsのチュートリアルを学習していきます。

# Discover Basic Elements

https://doc.babylonjs.com/babylon101/discover_basic_elements
いろいろな図形を描いていきます。

# MeshBuilder Method
`BABYLON.MeshBuilder`クラスから、ボックス、球体、平面、地面の描画メソッドとオプションを見ていきます。メッシュビルダーなので、メッシュを作っている。メッシュとは、図形を構成する要素で、三角形または四角形の集まり。CGの基礎知識も理解していく必要がありますね。
[wikipedia ポリゴンメッシュ](https://ja.wikipedia.org/wiki/%E3%83%9D%E3%83%AA%E3%82%B4%E3%83%B3%E3%83%A1%E3%83%83%E3%82%B7%E3%83%A5)

## box
`BABYLON.MeshBuilder.CreateBox`でボックスを生成します。
サンプルでは高さ、幅、深さを指定。

```js
    // box生成
    var box = BABYLON.MeshBuilder.CreateBox("box", {height: 1, width: 0.75, depth: 0.25}, scene);
```

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="js,result" data-user="nobuyuki-ishii" data-slug-hash="oNxByaV" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="babylon101 Discover Basic Elements box">
  <span>See the Pen <a href="https://codepen.io/nobuyuki-ishii/pen/oNxByaV">
  babylon101 Discover Basic Elements box</a> by nobuyuki ishii (<a href="https://codepen.io/nobuyuki-ishii">@nobuyuki-ishii</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## sphere
`BABYLON.MeshBuilder.CreateSphere`で球を生成します。
サンプルでは直径を指定して、直径Xを上書き。たまご型。

```js
var mySphere = BABYLON.MeshBuilder.CreateSphere("mySphere", {diameter: 2, diameterX: 3}, scene);
```

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="js,result" data-user="nobuyuki-ishii" data-slug-hash="QWNdxRg" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="babylon101 Discover Basic Elements box">
  <span>See the Pen <a href="https://codepen.io/nobuyuki-ishii/pen/QWNdxRg">
  babylon101 Discover Basic Elements box</a> by nobuyuki ishii (<a href="https://codepen.io/nobuyuki-ishii">@nobuyuki-ishii</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## plane
`BABYLON.MeshBuilder.CreatePlane`で平面を生成。
サンプルでは幅、高さを指定。

```js
var myPlane = BABYLON.MeshBuilder.CreatePlane("myPlane", {width: 3, height: 2}, scene);
```

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="js,result" data-user="nobuyuki-ishii" data-slug-hash="OJNWwPb" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="babylon101 Discover Basic Elements plane">
  <span>See the Pen <a href="https://codepen.io/nobuyuki-ishii/pen/OJNWwPb">
  babylon101 Discover Basic Elements plane</a> by nobuyuki ishii (<a href="https://codepen.io/nobuyuki-ishii">@nobuyuki-ishii</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## ground
地面を生成。ぱっと見、planeと同じだけれど、`CreateGroundFromHeightMap`で起伏のある地面を作れるとあり、平面も作れるけれど、区別している。

```js
var myGround = BABYLON.MeshBuilder.CreateGround("myGround", {width: 2, height: 1, subdivisions: 4}, scene);
```

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="js,result" data-user="nobuyuki-ishii" data-slug-hash="NWNdBGg" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="babylon101 Discover Basic Elements ground">
  <span>See the Pen <a href="https://codepen.io/nobuyuki-ishii/pen/NWNdBGg">
  babylon101 Discover Basic Elements ground</a> by nobuyuki ishii (<a href="https://codepen.io/nobuyuki-ishii">@nobuyuki-ishii</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## faceColors
ボックスの面に色をつけるオプション。
引数はr, g, b, aをそれぞれ0から1で指定。

```js
  // 色設定
  var faceColors = new Array(6);
  faceColors[0] = new BABYLON.Color4(1,0,0,0);
  faceColors[1] = new BABYLON.Color4(1,1,0,0);
  faceColors[2] = new BABYLON.Color4(1,1,1,0);
  faceColors[3] = new BABYLON.Color4(0,0,0,1);
  faceColors[4] = new BABYLON.Color4(1,0,1,1);
  faceColors[5] = new BABYLON.Color4(0,1,0,1);
  
  // box生成
  var box = BABYLON.MeshBuilder.CreateBox("box", {size: 1, faceColors: faceColors}, scene);
```

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="js,result" data-user="nobuyuki-ishii" data-slug-hash="xxVgJWK" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="babylon101 Discover Basic Elements faceColors">
  <span>See the Pen <a href="https://codepen.io/nobuyuki-ishii/pen/xxVgJWK">
  babylon101 Discover Basic Elements faceColors</a> by nobuyuki ishii (<a href="https://codepen.io/nobuyuki-ishii">@nobuyuki-ishii</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## faceUV
ボックスの面に画像を設定するオプション。

```js
  // 画像設定
  var mat = new BABYLON.StandardMaterial("mat", scene);
  var texture = new BABYLON.Texture("https://drive.google.com/uc?export=view&id=16gDNMIwZDSqaa3M80DiL15rvCNs039x9", scene);
  mat.diffuseTexture = texture;
  
  var columns = 6;  // 6 columns
  var rows = 1;  // 1 rows

  var faceUV = new Array(6);

  for (var i = 0; i < 6; i++) {
    faceUV[i] = new BABYLON.Vector4(i / columns, 0, (i + 1) / columns, 1 / rows);
  }
  
  // box生成
  var box = BABYLON.MeshBuilder.CreateBox("box", {size: 1, faceUV: faceUV}, scene);
  box.material = mat;
```

画像を指定して、その中の表示箇所の左底辺、右頂点を`BABYLON.Vector4(x,y,z,w)`で4点指定する。
1コ目は、こんな感じ。6までズラしている。
![vector4.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45425/b1ae52e2-bed2-2e78-668c-1dae30c43fe5.png)
縦、横はそれぞれ全体で1になるので、横を6等分する。以下のプログラムで`faceUV`は、以下を指定している。

```js
  faceUV[0] = new BABYLON.Vector4(0, 0, 1/6, 1);
  faceUV[1] = new BABYLON.Vector4(1/6, 0, 2/6, 1);
  faceUV[2] = new BABYLON.Vector4(2/6, 0, 3/6, 1);
  faceUV[3] = new BABYLON.Vector4(3/6, 0, 4/6, 1);
  faceUV[4] = new BABYLON.Vector4(4/6, 0, 5/6, 1);
  faceUV[5] = new BABYLON.Vector4(5/6, 0, 1, 1);
```

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="js,result" data-user="nobuyuki-ishii" data-slug-hash="ExKZeoN" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="babylon101 Discover Basic Elements faceUV">
  <span>See the Pen <a href="https://codepen.io/nobuyuki-ishii/pen/ExKZeoN">
  babylon101 Discover Basic Elements faceUV</a> by nobuyuki ishii (<a href="https://codepen.io/nobuyuki-ishii">@nobuyuki-ishii</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

codepenで画像を読み込むとcorsにより、代替画像？になってしまった。。

corsを解決すると、こんな感じになる。
http://141-lab.com/babylon/qiita/faceuv/

## updatable

メッシュの変更を許可するというオプション。デフォルトはfalseで、変更不可となっている。サンプルは下記イメージのように左下の点の位置を変更して、図形を変更。updatable設定がfalseだと何も変化しない。

![updatable.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/45425/75612157-ce03-e689-dbd0-0ce04164601d.png)

```js
  // 平面生成
  var myPlane = BABYLON.MeshBuilder.CreatePlane("myPlane", {width: 3, height: 2, updatable: true}, scene);
  
  var positions = myPlane.getVerticesData(BABYLON.VertexBuffer.PositionKind);
  console.log(positions);

  positions[0] = -3;
  myPlane.updateVerticesData(BABYLON.VertexBuffer.PositionKind, positions);
```

`getVerticesData`で取得したデータは、`[-1.5, -1, 0, 1.5, -1, 0, 1.5, 1, 0, -1.5, 1, 0]`となっていて、`updateVerticesData`で`[-3, -1, 0, 1.5, -1, 0, 1.5, 1, 0, -1.5, 1, 0]`に変更している。

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="js,result" data-user="nobuyuki-ishii" data-slug-hash="eYZvXML" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="babylon101 Discover Basic Elements updatable">
  <span>See the Pen <a href="https://codepen.io/nobuyuki-ishii/pen/eYZvXML">
  babylon101 Discover Basic Elements updatable</a> by nobuyuki ishii (<a href="https://codepen.io/nobuyuki-ishii">@nobuyuki-ishii</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## side orientation
平面のメッシュ設定。デフォルトだと表面しか表示されないのは、この面設定オプションによるもの。
`BABYLON.Mesh.FRONTSIDE`（デフォルト）
`BABYLON.Mesh.BACKSIDE`
`BABYLON.Mesh.DOUBLESIDE`

```js
  // 平面生成
  var myPlane = BABYLON.MeshBuilder.CreatePlane("myPlane", {width: 3, height: 2, sideOrientation: BABYLON.Mesh.DOUBLESIDE}, scene);
```
`BABYLON.Mesh.DOUBLESIDE`にすると、両面が表示される。マウスを左クリックしたまま動かして回転させてみてください。

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="js,result" data-user="nobuyuki-ishii" data-slug-hash="PoNmjez" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="babylon101 Discover Basic Elements plane">
  <span>See the Pen <a href="https://codepen.io/nobuyuki-ishii/pen/PoNmjez">
  babylon101 Discover Basic Elements plane</a> by nobuyuki ishii (<a href="https://codepen.io/nobuyuki-ishii">@nobuyuki-ishii</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

## front and back uv
平面に画像を設定するオプション。`sideOrientation`に`BABYLON.Mesh.DOUBLESIDE`を設定していること。画像の指定の仕方は面のときと同じ。画像の貼り付けたい場所を`BABYLON.Vector4`で指定する。

```js
  // 画像設定
  var mat = new BABYLON.StandardMaterial("mat", scene);
  var texture = new BABYLON.Texture("https://drive.google.com/uc?export=view&id=16gDNMIwZDSqaa3M80DiL15rvCNs039x9", scene);
  mat.diffuseTexture = texture;
  
  var fuv = new BABYLON.Vector4(0, 0, 1/6, 1);
  var buv = new BABYLON.Vector4(1/6, 0, 2/6, 1);
  
  // 平面生成
  var myPlane = BABYLON.MeshBuilder.CreatePlane("myPlane", {width: 3, height: 2, sideOrientation: BABYLON.Mesh.DOUBLESIDE, frontUVs: fuv, backUVs: buv}, scene);
  myPlane.material = mat;
```

codepenはまたcorsにより代替画像。。

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="js,result" data-user="nobuyuki-ishii" data-slug-hash="OJNmgGp" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="babylon101 Discover Basic Elements front and back uv">
  <span>See the Pen <a href="https://codepen.io/nobuyuki-ishii/pen/OJNmgGp">
  babylon101 Discover Basic Elements front and back uv</a> by nobuyuki ishii (<a href="https://codepen.io/nobuyuki-ishii">@nobuyuki-ishii</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>

やりたかったのはこれ。
http://141-lab.com/babylon/qiita/frontuv_backuv/

## position and rotation
オブジェクトの場所、回転、スケールを設定します。
サンプルはボックスを3コ生成し、場所変更して、ボックスを3コ並べ、1コを回転、1コをスケール変更しています。

場所の設定値にはx, y, zがあり、個別に設定するか、BABYLON.Vector3でまとめて設定する。

```js
  // 場所移動
  box1.position.x = 2;
  box3.position.x = -2;
```

回転の設定値にはx, y, zがあり、個別に設定するか、`BABYLON.Vector3`でまとめて設定する。

```js
  // 回転設定
  box1.rotation = new BABYLON.Vector3(1,1,1);
```

スケールの設定値にはx, y, zがあり、個別に設定するか、`BABYLON.Vector3`でまとめて設定する。

```js
  // スケール設定
  box3.scaling = new BABYLON.Vector3(0.5, 2, 1);
```

<p class="codepen" data-height="265" data-theme-id="light" data-default-tab="js,result" data-user="nobuyuki-ishii" data-slug-hash="BaKRdLm" style="height: 265px; box-sizing: border-box; display: flex; align-items: center; justify-content: center; border: 2px solid; margin: 1em 0; padding: 1em;" data-pen-title="babylon101 Discover Basic Elements Position and Rotation">
  <span>See the Pen <a href="https://codepen.io/nobuyuki-ishii/pen/BaKRdLm">
  babylon101 Discover Basic Elements Position and Rotation</a> by nobuyuki ishii (<a href="https://codepen.io/nobuyuki-ishii">@nobuyuki-ishii</a>)
  on <a href="https://codepen.io">CodePen</a>.</span>
</p>
<script async src="https://static.codepen.io/assets/embed/ei.js"></script>