Cesiumで標高計算処理を他言語に移植するために関連コードを調べた時のメモ書きその2です。
その2はこちら:
本記事ではquantized-mesh形式の地形データを使ったときの標高計算について調べました。
quantized-meshデータを使う場合QuantizedMeshTerrainData#interpolateHeightで標高の計算が行われます。
ざっくりとした処理の流れは以下の通りです。
- 引数のlongitude, latitudeをrectangle内の座標としてクランプして0~32767の範囲の値として正規化する(u, v)
2. meshデータ(TerrainMesh型)の有無で処理分岐する。
- meshデータが生成されていない場合はinterpolateHeightが呼ばれる(※1)
- meshデータが生成されている場合はinterpolateMeshHeightが呼ばれる(※2)
※1)QuantizedMeshTerrainDataのprototypeメソッドのinterpolateHeightと関数名が同じですが、こちらは上記とは別に定義されているファイル内スコープのinterpolateHeight関数です。
紛らわしいので、本記事では以後こちらの関数をinterpolateHeight(mesh不要版)と呼ぶことにします。
※2)明示的にcreateMeshを呼び出さない限りmeshデータは生成されないので、初回呼び出し時はinterpolateHeight(mesh不要版)が呼び出されることになると思います。
interpolateHeight(mesh不要版)がundefinedの結果を返したときに、呼び出し側コード(sampleTerrain.js)がTerrainData#createMeshを呼び出し、meshデータ作成後に再びinterpolateHeightを呼び出します。
ちなみにinterpolateHeight(mesh不要版)がundefinedを返すのは、(u, v)で表される点がどの三角形内にも含まれていない場合です。
これがcesium-tile-builder等で普通に作ったデータでも普通に起こりうることなのかはよくわかりませんでした。(タイルの境界付近とか?)
interpolateHeight(mesh不要版)の処理
処理内容は以下の通りです。
点を含む三角形の検索
terrainDataに含まれる各三角形を順次処理し、与えられた点がその三角形内にあるかどうかを判定する。
重心座標による高さの補間
1で三角形が見つかった場合、以下の処理を行い結果を返す。
barycentric coordinates(重心座標)を計算する。
三角形の頂点の高さと点の重心座標を用いて、点の高さを補間する。
1の処理で点がどの三角形内にも含まれていない場合、undefinedが返却される。
重心座標はシェーダーとかで使ってるやつですね。
interpolateMeshHeightの処理
createMeshで生成したメッシュデータを使ってinterpolateHeight(mesh不要版)と同様の処理を行います。
quantized-meshデータのデコード
quantized-meshのデータのデコード処理はquantized-mesh-1.0の仕様とCesiumTerrainProvider.jsのcreateQuantizedMeshTerrainData関数の処理が参考になりそう。
createMeshの処理
createMeshの呼び出し側と呼び出される側の処理。
こちらはあまり深追いしていません。とりあえずソースコードのリンクだけ。
呼び出し側:
呼び出されるタスク: