2014年08月30日

Oculus SDK 0.4.1の変換行列について

Oculus SDKのライブラリで計算してくれるのであまり必要ありませんが、ビューイング行列とプロジェクション行列に関するメモです。サンプルプログラムを参考にしていますが、正しいかどうかはわかりません。

普通fov, aspect, near, farを使ってプロジェクション行列を計算しますが、Oculus SDK 0.4.1では、左右で中心位置がずれているため、4つfov情報がeyeRenderDesc.Fovとして提供されています。
oculus_memo_001.png
三角関数のタンジェント的に、この4つのFovとleft, right, top, bottomの関係は下図のようになります。
oculus_memo_003.png
これにより、left, right, top, bottomと、プロジェクション行列が計算できます。(中心から考えるとleftとbottomにマイナスが付きます?)
oculus_memo_004_2.png
ovrMatrix4f_Projectionで計算した行列と、上記で計算した行列は一致しましたので、合っていると思います。
(2014.12.15追記)
よく見たら一致していませんでした。OpenGLの正規化座標系は-1≦z≦1なのに対して、DirectXでは0≦z≦1になるみたいです[2]。


続いて、ビューイング行列です。LookAtRHで行列を計算する場合は、普通のビューイング変換行列の計算と同じようです。左目用、右目用では、とりあえずHMDの位置で計算してから、ViewAdjustだけ平行移動させるやり方のようです。
oculus_memo_005.png
後はOpenGLの一次元配列の順番的に、シェーダ等に渡す場合は転置が必要です。
oculus_memo_006.png

実行結果
板ポリゴン1枚にテクスチャを貼り付けてみました。前回のと組み合わせてセカンダリディスプレイの内容をHMDで表示させたりしようかなと考えていますが、更新周波数的に厳しいかもしれません。一応OpenGLでも75Hzでちゃんと動かせば遅延なくトラッキングしてくれますね。

oculus_memo_002.png

[1] 富士山画像:http://free-photo.gatag.net/2010/05/23/120000.html
[2] http://www.gamedev.net/page/resources/_/technical/graphics-programming-and-theory/perspective-projections-in-lh-and-rh-systems-r3598
web拍手 by FC2
posted by シンドラー at 13:02 | Comment(0) | TrackBack(0) | Oculus Rift | このブログの読者になる | 更新情報をチェックする

2014年08月22日

プライマリディスプレイ表示プログラムの作成

計算機環境やいくつかのプログラムでは、Oculus Riftをプライマリディスプレイにしないと75Hz出なかったりして困ります。かといってOculus Riftをプライマリディスプレイにすると、歪んだデスクトップの操作をしないといけないので、プログラムを起動するだけでも結構大変です。

そこで、プライマリディスプレイのスクリーンをセカンダリディスプレイのスクリーンに表示するプログラムを作成しました。探せばありそうでしたが、探すのが面倒だったので適当に作りました。

実行結果

プログラムを実行すると、2番目のディスプレイに1番目のディスプレイに表示されている内容が表示されます。Oculus Riftをプライマリに設定したら、普通のディスプレイのどれかに下記のような画像が表示されます。ViewPrimaryなのにViewParamになってますね…。

ViewPrimary_001.png

手抜きでマウスカーソルはただの赤い楕円です。一応表示しているので操作はできます。MMEで樽型歪みエフェクト[1]を使う場合などは、Oculus Riftをプライマリにしておいて、セカンダリに表示された画面を見ながら動かして、Oculus Riftで見たいときだけAlt+Enterで全画面にすればいいので楽です。樽型歪みエフェクトはパラメータがDK1用っぽいので、多少修正が必要かと思います。

ViewPrimary_002.png

ソースコードと実行プログラム
ViewPrimary.cpp
ViewPrimary.zip

Windows APIはほとんど使ったことがないので何か問題があるかもしれません。後残念ながらOculus Riftのプログラムをフルスクリーンで実行するとこちらの画面は更新されなくなってしまいました。参考にしたWebサイトはソースコード内のコメントに書いてあります。

[1] 【MMD】Oculus Rift向け樽型歪みエフェクト(前編)【MME】
web拍手 by FC2
posted by シンドラー at 22:13 | Comment(0) | TrackBack(0) | Oculus Rift | このブログの読者になる | 更新情報をチェックする

2014年08月16日

Oculus SDK 0.4.1とGLUTのテスト

SDKが0.4.1になりましたね。というわけでそれに合わせた修正と、前回のサンプルではHMDの位置がちゃんと反映されていなかったのようなので、サンプルソースコードを参考に位置情報を反映させるようにしてみました。適当に参考にしただけなので間違っているかもしれません。あと、FPSの表示もしてみましたが、これもOculus Rift側で表示できるようにするべきだとは思います。

1.目の高さのパラメータの取得
ovrHmd_GetFloatでパラメータの取得ができるのだと思います。
    // 頭の位置の取得
static OVR::Vector3f HeadPos(0.0f, 1.5f, 0.0f);
HeadPos.y = ovrHmd_GetFloat(hmd, OVR_KEY_EYE_HEIGHT, HeadPos.y);

2. HMDの位置姿勢情報の取得
        ovrEyeType eye = hmd->EyeRenderOrder[eyeIndex];
eyeRenderPose[eye] = ovrHmd_GetEyePose(hmd, eye);

3. ビューイング変換行列の計算
HMDの姿勢から、上ベクトルと前ベクトルを計算します。左右の目の位置差がeyeRenderDesc[eye].ViewAdjustになるようなので、LookAtRHで右手系のビューイング変換行列を計算した後で、左右の位置差分の平行移動を行います。たぶん。
        // 姿勢の取得
OVR::Matrix4f rollPitchYaw = OVR::Matrix4f(eyeRenderPose[eye].Orientation);
// 視点の上ベクトル、前ベクトルを計算
OVR::Vector3f finalUp = rollPitchYaw.Transform(OVR::Vector3f(0,1,0));
OVR::Vector3f finalForward = rollPitchYaw.Transform(OVR::Vector3f(0,0,-1));
// 視点のワールド座標を取得
OVR::Vector3f eyePos = HeadPos + eyeRenderPose[eye].Position;
// ビューイング変換行列の計算
OVR::Matrix4f view = OVR::Matrix4f::LookAtRH(eyePos,
eyePos + finalForward, finalUp);
// 左右の目の位置の違い分を平行移動
view = OVR::Matrix4f::Translation(eyeRenderDesc[eye].ViewAdjust) * view;

4. プロジェクション変換行列の計算
これもLibOVRに関数があるようなので、それを使用します。
        // プロジェクション変換行列の計算
OVR::Matrix4f proj = ovrMatrix4f_Projection(eyeRenderDesc[eye].Fov,
0.01f, 10000.0f, true);

5. ビューポート変換行列の計算
これは初期化時に事前計算したものを使用します。
        // ビューポートの設定
glViewport(eyeRenderViewport[eye].Pos.x, eyeRenderViewport[eye].Pos.y,
eyeRenderViewport[eye].Size.w, eyeRenderViewport[eye].Size.h);

以下ソースコード
main_glut4.cpp
simple.vert
simple.frag

おまけ
オレオレライブラリに組み込んであぴミクさんを表示するところまではできました。今はテクスチャ表示しかしていないので75Hzでてますが、色々加えたらどうなりますかね。
oculus_opengl_002.png

web拍手 by FC2
posted by シンドラー at 03:49 | Comment(0) | TrackBack(0) | Oculus Rift | このブログの読者になる | 更新情報をチェックする

2014年08月12日

Oculus SDK 0.4.0とGLUTのテスト

夏休みですね。油断するとだらだら過ごしてしまうのでOculus Riftで遊びたいと思います。

時代的にはGLFWの方が良いのかもしれませんが、過去の遺産を使いたいのでとりあえずfreeglut版に変更してみました。

ソースコード((2014.8.12 三角形の頂点が右回りになっていたので修正))
(視点の位置によって見えなくなるかもしれないのでglDisable(GL_CULL_FACE);にした方が良いかも)
main_glut2.cpp

GLUTではモニタを指定してフルスクリーンみたいなことができないようなので、ウィンドウをOculus Riftの方に持っていってからキーボードでフルスクリーンに切り替えることにしました。また、ウィンドウハンドルの取得ももうちょっとうまくできるはずですがとりあえず適当です。

FBOの内容を取得して保存してみましたが、樽状の変換はLibOVR側でやってくれるようで、普通に視点を変えて左右にレンダリングしたのでいいみたいですね。

oculus_fbo_001.png

次はオレオレライブラリにOculus SDKを組み込んでみたいと思います。

web拍手 by FC2
posted by シンドラー at 12:38 | Comment(0) | TrackBack(0) | Oculus Rift | このブログの読者になる | 更新情報をチェックする

2014年08月09日

Oculus SDK 0.4.0とGLFWのテスト

Oculus Rift DK2はいい感じですね。残念ながら?OpenGL派ですので、DK2でOculus SDK 0.4.0でGLFWを使う方法についてメモっておきます。

1. Visual Studio 2010 Express Editionでのコンパイル

[1]を参考にさせていただきました。ATLが必要なんですね。後はkernel32.libが見つからない等はWindows SDKで、タイマ系の関数がリンクできないと出たらwinmm.libを追加して、ソケットっぽい関数がリンクできないとでたらws2_32.libを追加したらコンパイルできました。

2. GLFWの使い方などOpenGL回りについて

[2]〜[4]を参考にさせていただきました。

3. Oculus Rift + OpenGLの使い方について

[5][6]を参考にさせていただきました。SDL2を使う場合は[6]そのままで良さそうです。

実行結果

三角形1枚描画しているだけです。

oculus_opengl_001.png

何かちょっとポジショントラッキングのブレが大きいような気もします。OpenGLのせいなのかどこか間違えているのかはわかりませんが。

以下ソースコード(2014.8.12 三角形の頂点が右回りになっていたので修正)
(視点の位置によって見えなくなるかもしれないのでglDisable(GL_CULL_FACE);にした方が良いかも)
main_glfw2.cpp
simple.vert
simple.frag

[1] http://d.hatena.ne.jp/toburau/20140802/1406993965
[2] http://marina.sys.wakayama-u.ac.jp/~tokoi/GLFW.pdf
[3] http://www.glfw.org/docs/latest/monitor.html
[4] OpenGL 4 Shading Language Cookbook Second Edition
[5] Simple OpenGL example with GLFW, GLEW and OculusSDK 0.3.1
[6] Oculus Rift SDL2 OpenGL Demo
web拍手 by FC2
posted by シンドラー at 19:07 | Comment(0) | TrackBack(0) | Oculus Rift | このブログの読者になる | 更新情報をチェックする

広告


この広告は60日以上更新がないブログに表示がされております。

以下のいずれかの方法で非表示にすることが可能です。

・記事の投稿、編集をおこなう
・マイブログの【設定】 > 【広告設定】 より、「60日間更新が無い場合」 の 「広告を表示しない」にチェックを入れて保存する。