# XMVECTORとXMFLOATどっち？問題

### `<span class="editor-theme-code">XMVECTOR</span>`

`<span class="editor-theme-code">XMVECTOR</span>`は、DirectXMathライブラリの中核をなすデータ型です。その特徴は以下の通りです。

- ****SIMD (Single Instruction, Multiple Data) 最適化****: 複数の浮動小数点数を同時に処理できるCPU命令（SSE/AVXなど）を利用するために設計されています。これにより、ベクトル演算や行列演算が非常に高速に行われます。
- ****アラインメント****: SIMD命令が効率的に動作するために、通常16バイト境界にアラインメントされています。
- ****レジスタでの操作****: 多くの場合、CPUのレジスタ上で直接操作されるため、メモリアクセスによるオーバーヘッドが少ないです。
- ****直接的なアクセスが難しい****<span style="white-space: pre-wrap;">: </span>`<span class="editor-theme-code">XMVECTOR</span>`<span style="white-space: pre-wrap;">の個々の要素に直接アクセス（例: </span>`<span class="editor-theme-code">vec.x</span>`）することは通常できません。要素にアクセスするには、`<span class="editor-theme-code">XMVectorGetX()</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">XMVectorSetX()</span>`などの関数を使用する必要があります。

**`<strong class="editor-theme-bold editor-theme-code">XMVECTOR</strong>` **を使うべき場面****:

- ****ベクトルや行列の計算****: 加算、減算、乗算、内積、外積、変換など、あらゆる数学的な演算を行う場合。
- ****シェーダーへの定数バッファのアップロード****: シェーダーで利用するベクトルや行列データは、通常`<span class="editor-theme-code">XMVECTOR</span>`で計算し、`<span class="editor-theme-code">XMFLOAT4</span>`などで構成された定数バッファに格納してからGPUへ送ります。
- ****一時的な計算結果****: 関数内で中間的な計算を行う場合。

****例****:

C++

```
#include <DirectXMath.h>

// XMVECTOR同士の加算
XMVECTOR v1 = XMVectorSet(1.0f, 2.0f, 3.0f, 0.0f);
XMVECTOR v2 = XMVectorSet(4.0f, 5.0f, 6.0f, 0.0f);
XMVECTOR vResult = XMVectorAdd(v1, v2);

// 行列とベクトルの乗算
XMMATRIX m = XMMatrixRotationY(XM_PIDIV4);
XMVECTOR transformedVec = XMVector3TransformCoord(v1, m);
```

### `<span class="editor-theme-code">XMFLOAT</span>`<span style="white-space: pre-wrap;"> (例: </span>`<span class="editor-theme-code">XMFLOAT3</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">XMFLOAT4</span>`)

`<span class="editor-theme-code">XMFLOAT</span>`シリーズのデータ型（`<span class="editor-theme-code">XMFLOAT2</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">XMFLOAT3</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">XMFLOAT4</span>`など）は、C++の通常の構造体として定義されています。

- ****メモリ上でのデータ格納****: メモリ上にデータをシンプルに格納するために使用されます。
- ****アクセスしやすい****<span style="white-space: pre-wrap;">: </span>`<span class="editor-theme-code">float x, y, z, w;</span>`のようにメンバが直接公開されているため、個々の要素にアクセスしやすいです。
- ****アラインメントの制約が少ない****: 特別なアラインメントを考慮する必要がない場合が多いです（ただし、定数バッファなどGPUに送るデータの場合はアラインメントが重要になります）。
- ****SIMD最適化はされない****<span style="white-space: pre-wrap;">: </span>`<span class="editor-theme-code">XMFLOAT</span>`自体はSIMD最適化の恩恵を受けません。

**`<strong class="editor-theme-bold editor-theme-code">XMFLOAT</strong>` **を使うべき場面****:

- ****構造体やクラスのメンバ変数****: オブジェクトの位置、回転、スケールなど、永続的に保持したいデータ。
- ****頂点バッファのレイアウト****: 頂点データ（位置、法線、UVなど）を定義する場合。
- ****ファイルへの保存や読み込み****: データをファイルに書き込んだり、ファイルから読み込んだりする場合。
- ****GUIでの表示など、個々の要素へのアクセスが必要な場合****。
- **`<strong class="editor-theme-bold editor-theme-code">XMVECTOR</strong>`**での計算結果の格納****<span style="white-space: pre-wrap;">: </span>`<span class="editor-theme-code">XMVECTOR</span>`で計算した結果をメモリに保存する際、`<span class="editor-theme-code">XMStoreFloat3()</span>`や`<span class="editor-theme-code">XMStoreFloat4()</span>`関数を使用して`<span class="editor-theme-code">XMFLOAT</span>`型に変換します。

****例****:

C++

```
#include <DirectXMath.h>

// 構造体のメンバとして位置を保持
struct GameObject {
    XMFLOAT3 position;
    XMFLOAT4 color;
    // ...
};

GameObject player;
player.position = XMFLOAT3(0.0f, 1.0f, 0.0f);
player.color = XMFLOAT4(1.0f, 0.0f, 0.0f, 1.0f);

// XMVECTORの計算結果をXMFLOAT3に格納
XMVECTOR vec = XMVectorSet(10.0f, 20.0f, 30.0f, 0.0f);
XMFLOAT3 resultFloat3;
XMStoreFloat3(&resultFloat3, vec); // ここで変換
```

### 変換について

`<span class="editor-theme-code">XMVECTOR</span>`と`<span class="editor-theme-code">XMFLOAT</span>`の間は、以下の関数を使って相互に変換できます。

- **`<strong class="editor-theme-bold editor-theme-code">XMFLOAT</strong>` **→** `<strong class="editor-theme-bold editor-theme-code">XMVECTOR</strong>`**:
    - `<span class="editor-theme-code">XMLoadFloat2()</span>`
    - `<span class="editor-theme-code">XMLoadFloat3()</span>`
    - `<span class="editor-theme-code">XMLoadFloat4()</span>`
    - `<span class="editor-theme-code">XMLoadFloat3x3()</span>`<span style="white-space: pre-wrap;"> (行列用)</span>
    - `<span class="editor-theme-code">XMLoadFloat4x4()</span>`<span style="white-space: pre-wrap;"> (行列用) これらの関数は、</span>`<span class="editor-theme-code">XMFLOAT</span>`型のデータを`<span class="editor-theme-code">XMVECTOR</span>`型（または`<span class="editor-theme-code">XMMATRIX</span>`型）にロードし、SIMD演算の準備をします。
- **`<strong class="editor-theme-bold editor-theme-code">XMVECTOR</strong>` **→** `<strong class="editor-theme-bold editor-theme-code">XMFLOAT</strong>`**:
    - `<span class="editor-theme-code">XMStoreFloat2()</span>`
    - `<span class="editor-theme-code">XMStoreFloat3()</span>`
    - `<span class="editor-theme-code">XMStoreFloat4()</span>`
    - `<span class="editor-theme-code">XMStoreFloat3x3()</span>`
    - `<span class="editor-theme-code">XMStoreFloat4x4()</span>`<span style="white-space: pre-wrap;"> これらの関数は、</span>`<span class="editor-theme-code">XMVECTOR</span>`型の計算結果を`<span class="editor-theme-code">XMFLOAT</span>`型のメモリ領域にストアします。

### まとめと推奨されるフロー

DirectXプログラミングにおける理想的なデータフローは以下のようになります。

1. ****データ格納****: オブジェクトの状態（位置、回転、色など）は、クラスや構造体のメンバとして\*\*`<span class="editor-theme-code">XMFLOAT</span>`\*\*型で保持します。
2. ****計算開始****: 計算が必要になったら、\*\*`<span class="editor-theme-code">XMLoadFloat</span>`****関数を使用して****`<span class="editor-theme-code">XMFLOAT</span>`****型のデータを****`<span class="editor-theme-code">XMVECTOR</span>`\*\*型にロードします。
3. ****計算実行****: \*\*`<span class="editor-theme-code">XMVECTOR</span>`\*\*型を使って、DirectXMathの関数（`<span class="editor-theme-code">XMVectorAdd</span>`<span style="white-space: pre-wrap;">, </span>`<span class="editor-theme-code">XMMatrixMultiply</span>`など）で高速なSIMD演算を行います。
4. ****計算結果の格納****: 計算が終わったら、\*\*`<span class="editor-theme-code">XMStoreFloat</span>`****関数を使用して****`<span class="editor-theme-code">XMVECTOR</span>`****型の結果を再び****`<span class="editor-theme-code">XMFLOAT</span>`\*\*型にストアし、永続化します。