技術ノート2025年4月20日
Konva.js + Three.js で2D→3D図面変換を実装する
執筆: Hiramise チーム
Hiramise では、2D 図面と 3D ビューアが同一の JSON データを共有しています。2D で機器を移動すると 3D に即座に反映されます。本記事ではその実装の核心をご紹介します。
座標系の設計原則
2D と 3D では座標系が異なります。Konva.js は左上原点(Y軸下向き)、Three.js は中央原点(Y軸上向き)です。2つのシステムをつなぐ変換関数が核心です。
- 内部保存単位:mm整数(浮動小数点誤差累積防止)
- 2Dレンダリング時:mm→ピクセル(DPR・ズーム倍率反映)
- 3Dレンダリング時:mm→Three.js単位(1 unit = 100mm採用)
- Y軸反転:floorY = roomHeight_mm − konvaY
共有JSONスキーマ
図面データは単一JSONで保存されます。boundary(壁)、equipment(機器リスト)、metadata(業種・国)の3セクションで構成されます。
- boundary:外壁+内壁のポリライン、mm座標
- equipment:id、archetype、x_mm、y_mm、width_mm、depth_mm、rotation_deg
- metadata:country、category、specialty、format
3Dレンダリングパイプライン
各equipmentエントリはarchetype IDでGLBモデルをマッピングします。width_mmとdepth_mmに応じてモデルを自動スケーリングして実寸と一致させます。
- Tier 1(55%):Three.js parametricコード生成 — GLBファイルなし
- Tier 2–4:R2にアップロードされたGLB → useGLTFで読み込み
- スケーリング:scale.x = targetWidth / modelNativeWidth
- 回転:rotation.y = −(rotation_deg × π / 180)(Y軸反転補正)
この構造のおかげで、新しい機器カタログ追加時にGLBファイルとarchetypeマッピング1行を追加するだけで済みます。コアレンダラーを修正せずにカタログを拡張できます。