Skip to content

textured_max_lod でテクスチャの無い建物のジオメトリが消える不具合の修正 - #1

Open
kurouna wants to merge 1 commit into
Project-PLATEAU:mainfrom
kurouna:fix/textured-max-lod-untextured-geometry
Open

textured_max_lod でテクスチャの無い建物のジオメトリが消える不具合の修正#1
kurouna wants to merge 1 commit into
Project-PLATEAU:mainfrom
kurouna:fix/textured-max-lod-untextured-geometry

Conversation

@kurouna

@kurouna kurouna commented Jun 21, 2026

Copy link
Copy Markdown

概要

--sink gltf -t use_lod=textured_max_lod で変換すると、テクスチャを持たない建物(住宅地に多いです)のジオメトリが出力から丸ごと消えてしまいます。テクスチャ付きの建物は問題なく出ます。

さいたま市(大宮周辺)のデータを変換していて、住宅街がごっそり抜け落ちることで気づきました。あるメッシュ(53396479)だと、修正前は約 1,900 頂点しか残らないのに、修正後は約 62,000 頂点になります。衝突判定用に別途 GeoJSON で出しているフットプリント側には建物があるのに、glTF 側だけ消えている、という状態でした。

原因

nusamai/src/transformer/transform/lods.rsLodFilterMode::TexturedHighest です。

for lod in (0..=highest_available_lod).rev() {
    if available_lods.0 & (1 << lod) != 0 {
        edit_tree(&mut entity.root, lod);                   // ①
        let has_textures = !appearance.textures.is_empty(); // ②
        if has_textures { highest_textured_lod = Some(lod); break; }
    }
}
  • edit_treegeometries.retain(|g| g.lod == target_lod) で対象以外の LOD のジオメトリを破棄します。これを探索ループの中で毎回呼んでいるので、LOD を降りながら順にジオメトリを壊してしまい、あとから戻せません。
  • ② テクスチャの有無を appearance_store(エンティティ全体が持つテクスチャ画像の有無)で見ていますが、これは edit_tree では刈られないため、LOD ごとの判定になっていません(実質「このエンティティにテクスチャが 1 枚でもあるか」という、LOD によらない定数になっています)。

この結果、テクスチャ付きのエンティティは最初の反復(最上位 LOD)で break するのでたまたま正しく動きますが、テクスチャの無いエンティティはループが最後まで回ってジオメトリが空になり、消えてしまいます(本来は「最上位 LOD にフォールバック」したいはずの分岐です)。

修正

polygon_textures(ポリゴン単位のテクスチャ割り当て。ApplyAppearanceTransformFilterLodTransform より前に解決します)を使って、各 LOD にテクスチャ付きのポリゴンがあるかを 非破壊で 判定するようにしました。テクスチャを持つ最上位 LOD を選び、無ければ最上位 LOD にフォールバックして、edit_tree は対象 LOD を決めてから一度だけ呼びます。これでテクスチャの無い建物もジオメトリを保ったまま出力されます。

textured_max_lodset_appearance(true) で appearance を有効化するため、本変換の時点で polygon_textures は解決済みです。万一空(appearance 未解決)の場合は最上位 LOD にフォールバックするので、ジオメトリが失われることはありません。

テスト

lods.rs にユニットテストを追加しました。

  • テクスチャの無いフィーチャがジオメトリを失わない(最上位 LOD にフォールバックする)
  • 最上位 LOD が無テクスチャでも、テクスチャを持つ下位 LOD があればそちらを選ぶ/最上位 LOD がテクスチャ付きならそれを選ぶ
cargo test -p nusamai --lib transformer::transform::lods

動作確認

実データで再変換して確認しました。

  • さいたま市(大宮・住宅メッシュ): 抜け落ちていた住宅が復活しました。
  • 東京(千代田・商業メッシュ 53394611): 頂点数は変化なし(元からテクスチャ付きなので影響を受けません)。

TexturedHighest のLOD選択が、探索ループの中で破壊的な edit_tree を呼び、かつテクスチャ判定を
エンティティ全体の appearance_store で行っていた(LOD非依存)。このためテクスチャを持たない
フィーチャはループの過程でジオメトリが空になり、出力から消えていた。

polygon_textures(ApplyAppearanceTransform が本変換の前に解決する、ポリゴン単位のテクスチャ
割り当て)でLODごとに非破壊で判定し、テクスチャを持つ最上位LOD(無ければ最上位LOD)を選んで
edit_tree は一度だけ呼ぶように修正。ユニットテストを追加。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant