2022/7/14(木)

今日解いた競プロの問題。

ABC259-F: 木なので分割統治したいなという気持ちになる。

あるノード$i$を根とするサブツリーに着目した場合、そこから出ている辺は(wが正なら)全部採用したいなという気分になる。しかし制限として$d_i$以下の数の辺しか採用することはできない。なので、一番採用して得なものから採用していく。

採用時の得を評価するとき、単にwでソートするのでは不十分になる。なぜかというとある辺を採用した場合、その辺を介した子ノードから採用できる辺の数も1つ減ってしまうからである。これをうまく勘案するには、「子を$d_i$個採用した場合の最大の得p」「子を$d_i-1$個採用した場合の最大の得q」をすべての子ノードについて計算しておいた上で$w-p+q$などとすればよい。全ての子についてこの情報があれば現在のノードについても$d_i$個採用した場合の得、$d_i-1$個採用した場合の得を算出できる。こういう感じで再帰的にやっていけばよい。

なんか青diff上位にしてはそこまで歯ごたえがなかった感じがする。


OpenXRの勉強と実装を進めた。今日はコントローラの座標を取得するところまで行けた。Action周りはかなりややこしい。いろいろなベンダのいろいろなコントローラを抽象化して扱うために面倒なことになってる感じがする。

まず、各コントローラの各入出力には「パス」というものが振ってある。一意の文字列で識別されている。この辺の対応付けはここを見ると一応網羅的に書いてある。

識別子として文字列を渡せばデータをもらえるといった単純なものではない。まずxrStringToPathで、"/user/hand/left"といった文字列からXrPathというオブジェクトに変換する必要がある。

それから次にActionSetなるものを作成する。今一つ思想がよく分かっていないのだがおそらく、アプリ上で使われるコントローラによる様々な入出力(=アクション)のまとまりを表すオブジェクトである。

ActionSetオブジェクトを作成したらそこにActionを適宜作成していく。Actionは例えば「決定」だとか「移動」といった、文字通りアプリ上の「アクション」を抽象化するオブジェクトで、これ自体は「コントローラのAボタンに対応する」といった情報を持たない。

それからxrSuggestInteractionProfileBindingsで「このコントローラの場合はこのボタンをこのアクションに割り振る」といったことを指定する。アプリ開発者側は一体どんなコントローラで遊ばれるか分かったものではないので、様々なコントローラに対応して適宜指定することになる。つらそう。これに指定したそれぞれのアクションの対応付けが実際に採用されるかどうかはプレイ時まで分からない、というあたりの気持ちが「Suggest」という命名に込められているのだと思う。

最後にxrAttachSessionActionSetsでSessionにActionSetを紐づけて有効化する。これでセットアップが完了する。

各フレームでActionSetを利用するための処理はそこまで面倒ではない。まずxrSyncActionsを呼ぶ。そして各ActionについてxrGetActionState****といった関数を呼んで値を取得する。xrGetActionStateFloat, xrGetActionStateBoolean, xrGetActionStatePoseなどがある。このうちコントローラの姿勢を取得するxrGetActionStatePoseはやや面倒で、あらかじめxrGetActionStatePoseを呼んだ上でそれとは別にxrLocateSpaceで取得する。

とりあえず手の位置をリアルタイムに表示させることに成功した。ようやくVRアプリらしい感じになってきた。次の目標はhapticsの利用、ReferenceSpace周りの研究あたりで、その辺が終わったらOpenXRのチュートリアルとしては終了かな。あとは3DCGとVulkanの勉強になる気がする。偉そうにVulkan入門とか書いておきながらいまだにモデルの読み込み表示とかすらしたことがない(そもそも筆者が勉強しながら書くという趣旨のシリーズではあるのだが)。

最終的には簡易VRChatみたいなのが作りたい。

Categories: