Skip to main content

Elements(要素) — ufbx ドキュメント日本語訳


概要

ufbx のほぼすべては、struct ufbx_element のような「基底クラス」風の表現を持つ 要素(element) で構成されます。要素は name(名前)や、FBX のキー/値プロパティのための props(プロパティ集合)といった共通プロパティを含みます。

ufbx_nodeufbx_meshufbx_material といった「派生」型は、無名 union として ufbx_element ヘッダを埋め込んでおり、ufbx_element へキャストしたり、ufbx_element の共通プロパティへ直接アクセスできます。


例(C)

void list_nodes(ufbx_scene *scene)
{
    for (size_t i = 0; i < scene->nodes.count; i++) {
        ufbx_node *node = scene->nodes.data[i];

        printf("Node: '%s'\n", node->element.name.data);

        // 同等の省略形:
        printf("Node: '%s'\n", node->name.data);
    }
}

Element IDs(要素ID)

ufbx_scene は利便性のためにネストしたポインタ構造をとりますが、識別子(ID)を使えると便利なことがよくあります:

  • ufbx_element.element_id:シーン全体で一意な連番インデックス(scene.elements 内)
  • ufbx_element.typed_id:同一種別内での連番インデックス(例:scene.nodes 内)

これらのインデックスを使えば、ufbx_scene 内の配列をインデックス指定で取り出せます。

C

assert(node == scene->nodes.data[node->typed_id]);
assert(node == (ufbx_node*)scene->elements.data[node->element_id]);

assert(mesh == scene->meshes.data[mesh->typed_id]);
assert(mesh == (ufbx_mesh*)scene->elements.data[mesh->element_id]);

C++

assert(node == scene->nodes[node->typed_id]);
assert(node == (ufbx_node*)scene->elements[node->element_id]);
assert(mesh == scene->meshes[mesh->typed_id]);
assert(mesh == (ufbx_mesh*)scene->elements[mesh->element_id]);

Rust

use std::ptr;

assert!(ptr::eq(node, scene.nodes[node.element.typed_id]));
assert!(ptr::eq(&node.element, scene.elements[node.element.element_id]));

assert!(ptr::eq(mesh, scene.meshes[mesh.element.typed_id]));
assert!(ptr::eq(&mesh.element, scene.elements[mesh.element.element_id]));

これらのインデックスは、同じファイルを複数回読み込む範囲では安定していますが、ファイルを再エクスポートしただけでも必ずしも安定とは限りません。


Properties(プロパティ)

FBX は各要素に対して汎用的なキー/値のプロパティを持っており、ufbx はそれを ufbx_element.props 経由で公開します。多くの場合 ufbx はこれらを内部でフィールドへ解釈します(例:ufbx_node.local_transformufbx_light.intensity)。ただし、以下のようなケースでは ufbx_props を直接使うとよいでしょう:

  • ufbx_anim_curve を用いたアニメーションカーブの手動解釈
  • ユーザー定義のカスタムプロパティ
  • 非標準なマテリアル定義の取り扱い

ufbx は FBX の値を直感的に見えるよう多くの補正を行いますが、ufbx_props を直接読む場合には FBX 固有のクセ に注意してください。例えばライトには "Intensity"(強度)というプロパティがあり、FBX はしばしば DCC ツールで入力した値の 100 倍 を格納します。ufbx はこのクセを緩和するため 値を 100 で割る 補正を試みますが、FBX プロパティを直接読むと期待と異なる結果になることがあります。

C 例(Intensity を比較表示)

void print_intensity(ufbx_light *light)
{
    // `light->props` は `light->element.props` の省略形
    ufbx_prop *prop = ufbx_find_prop(&light->props, "Intensity");
    assert(prop);

    printf("ufbx_light.intensity: %.2f\n", light->intensity);
    printf("ufbx_props.Intensity: %.2f\n", prop->value_real);
}

C++ 例

void print_intensity(ufbx_light *light)
{
    // `light->props` は `light->element.props` の省略形
    ufbx_prop *prop = ufbx_find_prop(&light->props, "Intensity");
    assert(prop);

    printf("ufbx_light.intensity: %.2f\n", light->intensity);
    printf("ufbx_props.Intensity: %.2f\n", prop->value_real);
}

Rust 例

fn print_intensity(light: &ufbx::Light) {
    let prop = light.element.props
        .find_prop("Intensity")
        .expect("expected to find 'Intensity'");

    println!("ufbx_light.intensity: {:.2}", light.intensity);
    // 注意:Rust バインディングの表現は実装に依存する場合があります
    println!("ufbx_props.Intensity: {:.2}", prop.value_vec4.x);
}

例(Blender で強度 2.0 のライトを持つシーン)

ufbx_light.intensity: 2.00
ufbx_props.Intensity: 200.00

脚注

  1. FBX のファイルフォーマットではこれらを Objects と呼びますが、3D モデルの文脈では “object” という語が多義的すぎるため、ufbx では elements と呼んでいます。

クレジット / ライセンス

本文・コード例は ufbx の公開ライセンス(MIT / Unlicense)に基づき翻訳・再構成しています。必要に応じてクレジット表記を併記してください:
© 2020 Samuli Raivio — Original docs under Unlicense/MIT. Japanese translation by <YzLearning>.

  • 原文: ufbx docs “Elements” ページ
  • ライセンス: MIT / Unlicense(二重ライセンス)
  • 推奨クレジット: © 2020 Samuli Raivio — Original docs under Unlicense/MIT.
  • 訳者:[YzLearnig](必要に応じて記入)