Domestiqueはもともとルートをつらくする方法を知っていた。ルートを指定すればトレーナーが勾配をシミュレートするので、藤沢の部屋にいながら脚はしまなみ海道を感じる。でも画面に並ぶ数字を眺めているだけだった。実際に3Dで、しかも本物の地形の上でルートを走りたかった。見えている景色が脚の感覚と一致するように。
そこでこの数日、ほとんどをSparraの敵対的ループ(Codexが成果を採点する構成)で作った。中心になるのは新しいpure-Swiftの地形パッケージだ。GPSをローカルな平面座標に投影し、ルートがどの標高タイルにかかるかを求め、terrariumエンコードの標高タイルをAWSのオープンなデータセットから取得し、ハイトマップにデコードして、ディスクにキャッシュする。一度走ったルートならオフラインで準備できる。もう一段のパイプラインがルートと地形をジオメトリに変える。地形メッシュ、ルートに沿って掃引したロードリボン、そして道が斜面に埋まるように道の下の地形を平らにならす処理だ。RealityKitがそれをレンダリングし、手続き的に生成したライダーがトレーナーの報告する距離に沿って進み、追従カメラが後ろから追いかける。いちばんこだわった不変条件はこれだ。道の標高は地形データではなくルートプロファイルから取る。だから見えている勾配は、脚で感じる勾配とぴったり一致する。
正直なところ、その多くは目に見えないバグを追いかける作業だった。3Dで道が見えない状態が、認めたくないくらい長く続いた。三角形のワインディングが時計回りなのに法線は上を向いていると主張していたので、RealityKitがロードリボン全体をバックフェースカリングで静かに消していた。次に、実際のルートでは地形が粗すぎて、フラット化の処理が届く頂点がゼロになり、何もせず素通りしていた。結果として道は地面から浮くか、地中にもぐった。さらに、たった一つの悪い標高サンプル(サイコンの気圧計が走り出しの数秒で落ち着くまでの値で、周囲が+5.7m前後なのに-7.2mを指していた)が、ライダーがスポーンするまさにその位置に壁を作った。どれも一行で直りそうに見えて、自信ありげなシーンの裏に隠れていた。
これがどれだけ初期段階かは、はっきり書いておきたい。まだブランチ上の粗いプロトタイプでmainには入れていないし、どうすれば走っていて気持ちよくなるかを模索している最中だ。本物のテクスチャやモデルはまだ使っていない。地形はフラットシェーディングで、道はテクスチャなしのただのリボン、ライダーはルートに沿って滑るだけのプレースホルダーだ。今の時点で本物なのは地面そのものだ。ハイトマップは実際の標高データから来ているので、登る地形の形は本物の丘の形になっている。その形の上に乗っているものは、まだどれもスケッチにすぎない。
サイドバーでPROTOとタグ付けされたRide 3Dプロトタイプ。しまなみ海道の車輪の下にあるのは本物の標高で、その上に乗っているものはまだすべて仮のものだ。