Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【wip】ポリゴンの頂点をタイル境界にスナップする #678

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
3 changes: 2 additions & 1 deletion demo/cesium/3dtiles.html
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@
viewer.scene.globe.depthTestAgainstTerrain = true;

const tileset = await Cesium.Cesium3DTileset.fromUrl(
"/examples/3dtiles/tileset.json"
"/examples/3dtiles_textured",
{ enableDebugWireframe: true }
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codebase verification

タイルセットのパスが無効です - 修正が必要

検証の結果、以下の問題が確認されました:

  • /examples/3dtiles_textured ディレクトリが存在しません
  • 現在利用可能な3DTilesのサンプルは以下のみです:
    • /examples/ext_mesh_features
    • /examples/ext_structural_metadata

タイルセットのパスを既存のディレクトリのいずれかに変更するか、新しいタイルセットを適切に配置する必要があります。

🔗 Analysis chain

3Dタイルセットの読み込み設定の変更について確認が必要です

タイルセットのURLが変更され、デバッグオプションが追加されました。以下の点について確認をお願いします:

  1. 新しいパス /examples/3dtiles_textured が正しく設定されているか
  2. テクスチャ付きタイルセットへの移行による影響
  3. デバッグワイヤーフレーム表示がタイル境界へのスナップ機能の開発に有用か
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# 新しいタイルセットのパスが存在するか確認
fd -t d "3dtiles_textured$" examples/

# タイルセット関連の設定ファイルを検索
fd -e json "tileset.json$" examples/3dtiles_textured

Length of output: 304


Script:

#!/bin/bash
# リポジトリ内の全ての3DTilesに関連するディレクトリを検索
fd -t d "3dtiles"

# リポジトリ内のtileset.jsonファイルを検索
fd -e json "tileset.json$"

# HTMLファイル内のタイルセットパスの参照を検索
rg -g "*.html" "3dtiles_textured"

# デモディレクトリの構造を確認
ls -la demo/cesium/

Length of output: 788

);
viewer.scene.primitives.add(tileset);
viewer.zoomTo(tileset);
Expand Down
47 changes: 46 additions & 1 deletion nusamai/src/sink/cesiumtiles/slice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@

use super::{material::Material, tiling};
use crate::sink::cesiumtiles::{material::Texture, tiling::zxy_from_lng_lat};

struct TileBounds {
min_x: f64,
max_x: f64,
min_y: f64,
max_y: f64,
}
#[derive(Serialize, Deserialize)]
pub struct SlicedFeature {
// polygons [x, y, z, u, v]
Expand Down Expand Up @@ -398,6 +403,27 @@

poly_buf.add_ring(ring_buffer.drain(..))
}
let tile_bounds = TileBounds {
min_x: 0.0,
max_x: 1.0,
min_y: 0.0,
max_y: 1.0,
};

let rings: Vec<_> = poly_buf.rings().collect();

for ring in rings {
if ring.raw_coords().is_empty() {
continue;

Check warning on line 417 in nusamai/src/sink/cesiumtiles/slice.rs

View check run for this annotation

Codecov / codecov/patch

nusamai/src/sink/cesiumtiles/slice.rs#L417

Added line #L417 was not covered by tests
}

ring_buffer.clear();

for vertex in &ring {
let snapped_vertex = snap_to_tile_boundary(vertex, &tile_bounds);
ring_buffer.push(snapped_vertex);
}
}
yud0uhu marked this conversation as resolved.
Show resolved Hide resolved

send_polygon(key, &poly_buf);
}
Expand Down Expand Up @@ -433,3 +459,22 @@
entry_lod == selected_lod
}
}

fn snap_to_tile_boundary(vertex: [f64; 5], tile_bounds: &TileBounds) -> [f64; 5] {
let mut snapped_vertex = vertex;

if vertex[0] < tile_bounds.min_x {
snapped_vertex[0] = tile_bounds.min_x;

Check warning on line 467 in nusamai/src/sink/cesiumtiles/slice.rs

View check run for this annotation

Codecov / codecov/patch

nusamai/src/sink/cesiumtiles/slice.rs#L467

Added line #L467 was not covered by tests
} else if vertex[0] > tile_bounds.max_x {
snapped_vertex[0] = tile_bounds.max_x;
}

// Snap y coordinate
if vertex[1] < tile_bounds.min_y {
snapped_vertex[1] = tile_bounds.min_y;

Check warning on line 474 in nusamai/src/sink/cesiumtiles/slice.rs

View check run for this annotation

Codecov / codecov/patch

nusamai/src/sink/cesiumtiles/slice.rs#L474

Added line #L474 was not covered by tests
} else if vertex[1] > tile_bounds.max_y {
snapped_vertex[1] = tile_bounds.max_y;
}

snapped_vertex
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

スナッピング関数の改善が必要

以下の改善を推奨します:

  1. 浮動小数点の精度問題に対処するためのイプシロン値の追加
  2. 関数のドキュメント追加
  3. テストケースの追加
+/// 頂点をタイル境界にスナップする
+///
+/// # 引数
+/// * `vertex` - スナップ対象の頂点 [x, y, z, u, v]
+/// * `tile_bounds` - タイル境界
+///
+/// # 戻り値
+/// スナップされた頂点
 fn snap_to_tile_boundary(vertex: [f64; 5], tile_bounds: &TileBounds) -> [f64; 5] {
+    const EPSILON: f64 = 1e-10;
     let mut snapped_vertex = vertex;

-    if vertex[0] < tile_bounds.min_x {
+    if vertex[0] < tile_bounds.min_x + EPSILON {
         snapped_vertex[0] = tile_bounds.min_x;
-    } else if vertex[0] > tile_bounds.max_x {
+    } else if vertex[0] > tile_bounds.max_x - EPSILON {
         snapped_vertex[0] = tile_bounds.max_x;
     }

     // Snap y coordinate
-    if vertex[1] < tile_bounds.min_y {
+    if vertex[1] < tile_bounds.min_y + EPSILON {
         snapped_vertex[1] = tile_bounds.min_y;
-    } else if vertex[1] > tile_bounds.max_y {
+    } else if vertex[1] > tile_bounds.max_y - EPSILON {
         snapped_vertex[1] = tile_bounds.max_y;
     }

     snapped_vertex
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
fn snap_to_tile_boundary(vertex: [f64; 5], tile_bounds: &TileBounds) -> [f64; 5] {
let mut snapped_vertex = vertex;
if vertex[0] < tile_bounds.min_x {
snapped_vertex[0] = tile_bounds.min_x;
} else if vertex[0] > tile_bounds.max_x {
snapped_vertex[0] = tile_bounds.max_x;
}
// Snap y coordinate
if vertex[1] < tile_bounds.min_y {
snapped_vertex[1] = tile_bounds.min_y;
} else if vertex[1] > tile_bounds.max_y {
snapped_vertex[1] = tile_bounds.max_y;
}
snapped_vertex
}
/// 頂点をタイル境界にスナップする
///
/// # 引数
/// * `vertex` - スナップ対象の頂点 [x, y, z, u, v]
/// * `tile_bounds` - タイル境界
///
/// # 戻り値
/// スナップされた頂点
fn snap_to_tile_boundary(vertex: [f64; 5], tile_bounds: &TileBounds) -> [f64; 5] {
const EPSILON: f64 = 1e-10;
let mut snapped_vertex = vertex;
if vertex[0] < tile_bounds.min_x + EPSILON {
snapped_vertex[0] = tile_bounds.min_x;
} else if vertex[0] > tile_bounds.max_x - EPSILON {
snapped_vertex[0] = tile_bounds.max_x;
}
// Snap y coordinate
if vertex[1] < tile_bounds.min_y + EPSILON {
snapped_vertex[1] = tile_bounds.min_y;
} else if vertex[1] > tile_bounds.max_y - EPSILON {
snapped_vertex[1] = tile_bounds.max_y;
}
snapped_vertex
}