[3D Animation] DirectX8の時代にゼロから創ったMeshのロードから3Dアニメーションエンジンのエンジン開発した際のノウハウやTips まとめ Part3

今回からは、3Dの世界に突入するので、まず基本から説明を入ろうと思います。
いきなりオブジェクトを3D空間にマップするイメージは出来ないと思うので、基本からイメージを固めましょう。

まずは、簡単に人体的な観点から話します。
人の目が一定間隔離れているのは意味があります。
一直線だけだと平面にしか見えませんか、2直線で視る事で遠近が判断できるようになるので
立体的に見るには最適な位置にあります。

目から見た視野と3D上の概念のイメージを合わせてみました。
人間の視野角は、30°とのことなので視線を中心に2等分線を引くイメージになる。
**※VRの場合は、目の位置がカメラの位置になるイメージです。**

![視野角.png](https://qiita-image-store.s3.amazonaws.com/0/107688/861fce87-a2f8-c348-3491-36e2478b1ae1.png)

#2D空間に3D世界を表現するための基本原理
2D上で3Dを表現するには、3つの座標系が必要です。
・2D座標系の『Screen座標』
・3D座標系の『World座標』
・視点と光源・マテリアルから質感を表現した座標系を『View座標』(座標というより画像のような物)
があります。

それぞれの座標系についてイメージを共有します。

#World座標について
World座標とは、3D空間上の座標のことです。
たとえば、ある向きで(任意のXYZだけ)離れた位置に配置する場合の位置を3次元行列で表した座標を言います。

順番は、以下の組み合わせになります。
*(オブジェクト自身の向き) X (3D空間上の位置) X (移動量を中心に回転する行列)*
※オブジェクトの拡大/縮小は、行列全体に対する倍率設定をする

- **オブジェクト自身の向き**

![回転の図.png](https://qiita-image-store.s3.amazonaws.com/0/107688/75154d5b-4d1d-ce91-da86-a08b0bd6ad44.png)

最初、3Dオブジェクトは3D空間上の原点に配置されます。
この行列は、原点を中心(半径r = 0)に回転させることで、向きを変える意図があります。
角度の単位は、ラジアン(rad)で表現し、-π < θ ≦ π (-180° < θ ≦ 180°) の範囲で設定します。
通常、Rotation Matrix(回転行列)と言ってます。

式は、下記の通りです。

```math
R_Roll (\theta )=\begin{bmatrix}
1 &0 &0 \\
0 &\cos \theta &-\sin \theta \\
0 &\sin \theta &\cos \theta \\
\end{bmatrix}
\begin{bmatrix}
x \\
y \\
z
\end{bmatrix}
```

```math
R_Pitch (\theta )=\begin{bmatrix}
\cos \theta &0 &\sin \theta \\
0 & 1 & 0 \\
-\sin \theta &0 &\cos \theta \\
\end{bmatrix}
\begin{bmatrix}
x \\
y \\
z
\end{bmatrix}
```

```math
R_Yaw (\theta )=\begin{bmatrix}
\cos \theta &-\sin \theta &0 \\
\sin \theta &\cos \theta &0 \\
0 &0 &1
\end{bmatrix}
\begin{bmatrix}
x \\
y \\
z
\end{bmatrix}
```

ただ、式を出すだけだと中身が無いので、この式になった過程を説明します。

Yaw軸(X-Y平面)を中心にした回転をイメージしましょう。
![2次元平面上のベクトル.png](https://qiita-image-store.s3.amazonaws.com/0/107688/a0dc4466-3f79-c6bd-db2f-50eeb68e8dc1.png)

|a|は、点Aのまでの長さを表していますが、これは、**『3D空間上の位置』(平行移動行列)**で設定するので考慮しません。(単位円上の座標[ベクトルとしては、正規化のこと。]で考えて頂ければと思います。)

すなわち、|a| = 1となる円周上の点Aを回転させた後の座標を考えましょう。
|a|を正規化して1と考えた場合、x,yはそれぞれ以下の通りになります。

```math
x = \begin{align}
\cos \theta_A
\end{align}
```

```math
y = \begin{align}
\sin \theta_A
\end{align}
```

軸ごとθ radだけ左周りに回転させた場合、以下の図になります。
この時の点A'が回転後の座標になります。
![回転後のイメージ.png](https://qiita-image-store.s3.amazonaws.com/0/107688/a9c61958-c83f-5e8d-7fbc-39babfc1d9c2.png)

回転後のX,Yを求めるには、sin, cosの加法定理を利用します。
Z軸は、回転軸なのでそのままになります。

```math
X = \begin{align}
\cos (\theta_A + \theta)
\end{align}
```

```math
Y = \begin{align}
\sin (\theta_A + \theta)
\end{align}
```

```math
Z = \begin{align}
z
\end{align}
```

展開すると、

```math
X = \begin{align}
\cos \theta_A \cos \theta - \sin \theta_A \sin \theta
\end{align}
```

```math
Y = \begin{align}
\sin \theta_A \cos \theta + \cos \theta_A \sin \theta
\end{align}
```

```math
Z = \begin{align}
z
\end{align}
```

回転前の図より、

```math
x = \begin{align}
\cos \theta_A
\end{align}
```

```math
y = \begin{align}
\sin \theta_A
\end{align}
```

から、それぞれを代入して


```math
X = \begin{align}
x \cos \theta - y \sin \theta + z * 0
\end{align}
```

```math
Y = \begin{align}
x \sin \theta + y \cos \theta + z * 0
\end{align}
```

```math
Z = \begin{align}
x * 0 + y * 0 + z * 1
\end{align}
```
となります。
これを、3次元行列に入れることで回転行列ができます。
**※↑の式と↓の式を比較すれば、行列の正体が分かると思うので行列の説明はあえてしていません。**

```math
R_Yaw (\theta )=
\begin{bmatrix}
X \\
Y \\
Z \\
\end{bmatrix}
=
\begin{bmatrix}
\cos \theta &-\sin \theta &0 \\
\sin \theta &\cos \theta &0 \\
0 &0 &1
\end{bmatrix}
\begin{bmatrix}
x \\
y \\
z
\end{bmatrix}
```

Pitch, Rollも同じ方法で算出できますので、説明は省きます。
回転の行列を掛ける順番は、**Yaw*Pitch*Roll**の順番で掛けてください。

長くなったので、今回はここまでとします。
次回は、平行移動行列について解説します。