# Meshes（メッシュ） — ufbx ドキュメント日本語訳

## 概要

****Meshes（メッシュ）****（`<span class="editor-theme-code">ufbx_mesh</span>`）は、****ポリゴンジオメトリデータ****<span style="white-space: pre-wrap;"> を保持する要素です。</span>

ufbx では次の用語を使用します：

<table id="bkmrk-%E7%94%A8%E8%AA%9E%E8%AA%AC%E6%98%8Evertex%EF%BC%88%E9%A0%82%E7%82%B9%EF%BC%89%E4%BD%8D%E7%BD%AE%E6%83%85%E5%A0%B1%E3%82%92%E6%8C%81"><colgroup><col></col><col></col></colgroup><tbody><tr><th>用語

</th><th>説明

</th></tr><tr><td>****Vertex（頂点）****

</td><td>位置情報を持つ頂点。3Dモデリングソフトで選択可能な頂点に相当。

</td></tr><tr><td>****Index（インデックス）****

</td><td>頂点にUV・法線・カラーなどの属性を組み合わせたもの。

</td></tr><tr><td>****Face（面）****

</td><td>1枚の平面（三角形・四角形・N-gon）を構成するインデックスの範囲。

</td></tr></tbody></table>

同じ頂点が複数の面から参照されることがあります。  
<span style="white-space: pre-wrap;">各参照では異なるインデックスを持ち、これにより </span>****同一頂点に異なるUVや法線を設定****<span style="white-space: pre-wrap;"> できます。</span>

---

## メッシュのデータ構造

メッシュデータは各種属性として格納されます：

- `<span class="editor-theme-code">ufbx_mesh.vertex_position</span>`<span style="white-space: pre-wrap;"> — 頂点座標</span>
- `<span class="editor-theme-code">ufbx_mesh.vertex_normal</span>`<span style="white-space: pre-wrap;"> — 頂点法線</span>
- `<span class="editor-theme-code">ufbx_mesh.vertex_uv</span>`<span style="white-space: pre-wrap;"> — 頂点UV座標</span>

<span style="white-space: pre-wrap;">各属性には独自の </span>****インデックス配列****（`<span class="editor-theme-code">ufbx_vertex_attrib.indices[]</span>`<span style="white-space: pre-wrap;">）と </span>****値配列****（`<span class="editor-theme-code">ufbx_vertex_attrib.values[]</span>`）があり、  
インデックス指定で値を取得できます：

```c
data[indices[index]]
```

<span style="white-space: pre-wrap;">あるいはヘルパー関数 </span>`<span class="editor-theme-code">ufbx_get_vertex_vec3()</span>`<span style="white-space: pre-wrap;"> や、</span>  
<span style="white-space: pre-wrap;">C++／Rust の </span>`<span class="editor-theme-code">attrib[index]</span>`<span style="white-space: pre-wrap;"> 構文でもアクセス可能です。</span>

---

## 描画例

以下は仮想的な即時モードポリゴンAPIを使ってメッシュを描画する例です。

```c
void draw_polygons(ufbx_mesh *mesh)
{
    for (ufbx_face face : mesh->faces) {
        begin_polygon();

        // ポリゴンの各コーナーをループ
        for (uint32_t corner = 0; corner < face.num_indices; corner++) {

            // 各コーナーに対応するインデックス
            uint32_t index = face.index_begin + corner;

            // 頂点属性を取得
            ufbx_vec3 position = mesh->vertex_position[index];
            ufbx_vec3 normal   = mesh->vertex_normal[index];
            ufbx_vec2 uv       = mesh->vertex_uv[index];

            polygon_corner(position, normal, uv);
        }

        end_polygon();
    }
}
```

---

## Materials（マテリアル）

1つのFBXメッシュには、****異なる部位に複数のマテリアル****<span style="white-space: pre-wrap;"> が割り当てられる場合があります。</span>  
`<span class="editor-theme-code">ufbx_mesh.face_material[]</span>`<span style="white-space: pre-wrap;"> には、面ごとのマテリアルインデックスが格納されており、</span>  
<span style="white-space: pre-wrap;">これを使って </span>`<span class="editor-theme-code">ufbx_mesh.materials[]</span>`<span style="white-space: pre-wrap;"> にアクセスできます。</span>

ただし、****正確な結果を得るには** `<strong class="editor-theme-bold editor-theme-code">ufbx_node.materials[]</strong>` **を使うのが推奨****です。  
理由は、同じメッシュが異なるマテリアルでインスタンス化されることがあるためです。

ゲームエンジンでは、マテリアル境界ごとにメッシュを分割する必要がある場合があります。  
<span style="white-space: pre-wrap;">ufbx ではこれを容易にするために </span>`<span class="editor-theme-code">ufbx_mesh.material_parts[]</span>`<span style="white-space: pre-wrap;"> を提供しています。</span>  
これには、各マテリアルごとの****面数・三角形数・面リスト****が含まれます。  
マテリアルが存在しない場合でも、便宜上1つのマテリアルパートが存在します。

---

## 例：GPU用フォーマットへの変換

<span style="white-space: pre-wrap;">以下は、メッシュデータを </span>****GPU向けインデックス付きフォーマット****<span style="white-space: pre-wrap;"> に変換する例です。</span>  
使用しているヘルパー関数：

- `<span class="editor-theme-code">ufbx_triangulate_face()</span>`：面を三角形化してインデックス配列を生成
- `<span class="editor-theme-code">ufbx_generate_indices()</span>`：頂点配列を重複排除し、インデックスバッファを生成

```cpp
// GPU向け頂点構造体
// 実際にはよりコンパクトな型を使うべきです。
// `ufbx_real` はデフォルトで64bitです。
struct Vertex {
    ufbx_vec3 position;
    ufbx_vec3 normal;
    ufbx_vec2 uv;
};

void convert_mesh_part(ufbx_mesh *mesh, ufbx_mesh_part *part)
{
    std::vector<Vertex> vertices;
    std::vector<uint32_t> tri_indices;
    tri_indices.resize(mesh->max_face_triangles * 3);

    // このマテリアルを使用している各面を処理
    for (uint32_t face_index : part->face_indices) {
        ufbx_face face = mesh->faces[face_index];

        // 面を三角形化
        uint32_t num_tris = ufbx_triangulate_face(
            tri_indices.data(), tri_indices.size(), mesh, face);

        // 各三角形の頂点を取得
        for (size_t i = 0; i < num_tris * 3; i++) {
            uint32_t index = tri_indices[i];

            Vertex v;
            v.position = mesh->vertex_position[index];
            v.normal   = mesh->vertex_normal[index];
            v.uv       = mesh->vertex_uv[index];
            vertices.push_back(v);
        }
    }

    assert(vertices.size() == part->num_triangles * 3);

    // 頂点ストリームを生成
    ufbx_vertex_stream streams[1] = {
        { vertices.data(), vertices.size(), sizeof(Vertex) },
    };
    std::vector<uint32_t> indices;
    indices.resize(part->num_triangles * 3);

    // 頂点重複を削除し、インデックスバッファを生成
    size_t num_vertices = ufbx_generate_indices(
        streams, 1, indices.data(), indices.size(), nullptr, nullptr);

    vertices.resize(num_vertices);

    create_vertex_buffer(vertices.data(), vertices.size());
    create_index_buffer(indices.data(), indices.size());
}
```

---

## Attributes（属性）

上記の属性に加えて、FBXメッシュには他の属性も存在します。  
<span style="white-space: pre-wrap;">多くの属性は </span>****頂点ごと（またはインデックスごと）****<span style="white-space: pre-wrap;"> に定義されていますが、</span>  
<span style="white-space: pre-wrap;">一部は </span>****面単位・エッジ単位****<span style="white-space: pre-wrap;"> のデータも含まれます。</span>

エッジはオプションで、`<span class="editor-theme-code">ufbx_mesh.edges[]</span>`<span style="white-space: pre-wrap;"> で2つのインデックス間を定義します。</span>

---

### <span style="white-space: pre-wrap;">頂点（インデックス単位、最大 </span>`<span class="editor-theme-code">ufbx_mesh.num_indices</span>`）

<table id="bkmrk-%E3%83%95%E3%82%A3%E3%83%BC%E3%83%AB%E3%83%89%E5%86%85%E5%AE%B9ufbx_mesh.ver"><colgroup><col></col><col></col></colgroup><tbody><tr><th>フィールド

</th><th>内容

</th></tr><tr><td>`<span class="editor-theme-code">ufbx_mesh.vertex_position</span>`

</td><td>頂点座標

</td></tr><tr><td>`<span class="editor-theme-code">ufbx_mesh.vertex_normal</span>`

</td><td>法線ベクトル

</td></tr><tr><td>`<span class="editor-theme-code">ufbx_mesh.vertex_tangent</span>`

</td><td>接線方向（Tangent）UV.x

</td></tr><tr><td>`<span class="editor-theme-code">ufbx_mesh.vertex_bitangent</span>`

</td><td>接線空間UV.y

</td></tr><tr><td>`<span class="editor-theme-code">ufbx_mesh.vertex_uv</span>`

</td><td>UV座標（第1セット）

</td></tr><tr><td>`<span class="editor-theme-code">ufbx_mesh.vertex_color</span>`

</td><td>頂点カラー（第1セット）

</td></tr><tr><td>`<span class="editor-theme-code">ufbx_mesh.vertex_crease</span>`

</td><td>サブディビジョン用クリース値

</td></tr></tbody></table>

---

### <span style="white-space: pre-wrap;">面（最大 </span>`<span class="editor-theme-code">ufbx_mesh.num_faces</span>`）

<table id="bkmrk-%E3%83%95%E3%82%A3%E3%83%BC%E3%83%AB%E3%83%89%E5%86%85%E5%AE%B9ufbx_mesh.fac"><colgroup><col></col><col></col></colgroup><tbody><tr><th>フィールド

</th><th>内容

</th></tr><tr><td>`<span class="editor-theme-code">ufbx_mesh.face_material</span>`

</td><td>面ごとのマテリアル

</td></tr><tr><td>`<span class="editor-theme-code">ufbx_mesh.face_group</span>`

</td><td>ポリゴングループ

</td></tr><tr><td>`<span class="editor-theme-code">ufbx_mesh.face_smoothing</span>`

</td><td>スムーズシェーディングフラグ

</td></tr><tr><td>`<span class="editor-theme-code">ufbx_mesh.face_hole</span>`

</td><td>穴として扱うかどうか

</td></tr></tbody></table>

---

### <span style="white-space: pre-wrap;">エッジ（最大 </span>`<span class="editor-theme-code">ufbx_mesh.num_edges</span>`）

<table id="bkmrk-%E3%83%95%E3%82%A3%E3%83%BC%E3%83%AB%E3%83%89%E5%86%85%E5%AE%B9ufbx_mesh.edg"><colgroup><col></col><col></col></colgroup><tbody><tr><th>フィールド

</th><th>内容

</th></tr><tr><td>`<span class="editor-theme-code">ufbx_mesh.edge_smoothing</span>`

</td><td>法線生成用スムーズフラグ

</td></tr><tr><td>`<span class="editor-theme-code">ufbx_mesh.edge_visibility</span>`

</td><td>編集用のエッジ表示フラグ

</td></tr><tr><td>`<span class="editor-theme-code">ufbx_mesh.edge_crease</span>`

</td><td>サブディビジョン用エッジクリース

</td></tr></tbody></table>

---