Rust やっつけフェーズ(10) 球面束縛カメラ (wio-terminal, nalgebra, MVP)

前回はナビエストークスSOR法で流体のシミュレーションを行うPythonプログラムをRustで写経した。
配列計算はnalgebraを使用。 nalgebra繋がりで今回は球面束縛カメラで描画対象を3D表示することを行う。
本来はクォータニオンを習得しようとして始めたのだが、何故かこういう着地になってしまった。

やっつけフェーズとは

Rustと組込みを始めて約1年半だが、心はいつまでも初心者。
通勤中にスマホの単機能なエディタでえいやで作り、動けばオッケーなフェーズ。

球面束縛カメラ

出来上がり

デザイン

以前に作成した以下の描画を3D化する。

WioSBEye(カメラ位置情報)、WioSBButton(ボタン操作)
  • 左、右、上、下旋回
    5wayボタン操作により球面旋回し、位置情報を更新する。
  • ズーム、アウト
    TopLeft、TopMidボタン操作により、原点からの距離と位置情報を更新する。
WioSBCamera(3D変換)
  • モデル・ビュー・プロジェクション行列を生成し、受取った頂点情報を変換する。
  • 変換方法はnalgebra本家の以下ドキュメント「Build a MVP matrix」を基本的に踏襲。
  • モデル変換は、元画像が左上原点で作られているため、中央原点に対応。具体的にはX軸を中心に180度回転した後xとyをシフトする。(この回転時にクォータニオンが使われているようだ)
  • 遠近感を出すためwで割るのだが、割る前にwがマイナスにならないようかつ、wが小さくなりすぎないよう調整する。
  • 最後に左上原点表示に戻すためスクリーン行列を掛ける。

コード

wio_sbcamera
オブジェクトを斜めにして近づきすぎると破綻するバグあり。 何らかの限界があるのだろうがスキル不足で対処不可能。
wio_sbeye
wio_sbbutton
wio_elldiski(修正)
wio-polywave(修正)
main(流用)

今回はこんな感じで。