Pentanium Reactor Blog

ゲーム、アニメ、CG、プログラミング

GLKitでオブジェクトの選択

2013年03月16日 18時49分06秒 | プログラミング
PS4の情報が出てきたものの詳しいことも発売もまだまだ先だからなぁ感の漂う昨今、いかがお過ごしでしょうか。
とりあえず時代はまだまだ3Dらしいので、GLKitでも使おうかということで作ってみたよ。
なんて実はBlenderがそろそろGL_SELECTやめたいとか言ってるのを見て、そういえばGLKitにもunprojectあったなと思ったのが本当のきっかけだったりする。
というわけでやってみたのがこちら
マウスでクリックするかタップするとそこにあるオブジェクトが選択されて色が変わる、みたいなもの。
GLKitならOSXとiOSで同じソースが使えて良いねッ!
ただOSXは10.8以降になっちゃうけど。
ちなみにOSXでGLKitのGLKBaseEffectなどを使うにはOpenGL 3.0 Core Profileで初期化しないといけないので注意。
あとGLKViewに相当するものは無いので適当に作りましょう。
そして肝心な部分は、
GLKVector3 screenVec = GLKVector3Make(px, py, 1.0f); // 左下を原点とした時の画面上の座標
int vp[] = {0, 0, _viewportWidth, _viewportHeight}; // ビューポートの矩形
GLKVector3 upv = GLKMathUnproject(screenVec, cameraMatrix, projectionMatrix, vp, &isSuccess);// 変換

というだけなので特に難しいことは無し。
罠があるとすれば、上のisSuccessになっている変数はBOOLじゃなくてboolだということくらいで大した問題ではないかと。
なお座標系の原点がどこかなどというのは、この文章を読もうと思った時点でわざわざ言わなくても大丈夫な人だろうと想定しています(笑
で、まあこれだけじゃ面白くないよなということで、上げてあるコードではこのUnprojectの中で何をやってるのかというのを適当に。

/*
GLKVector4 screenVec = GLKVector4Make((px / _viewportWidth) * 2.0f - 1.0f, (py / _viewportHeight) * 2.0f - 1.0f, 1.0f, 1.0f);
GLKMatrix4 ivm = GLKMatrix4Invert(GLKMatrix4Multiply(projectionMatrix, cameraMatrix), &isSuccess);
GLKVector4 upv4 = GLKMatrix4MultiplyVector4(ivm, screenVec);
GLKVector3 upv = GLKVector3MultiplyScalar(GLKVector3MakeWithArray(upv4.v), 1.0f / upv4.w);
*/

GLKVector3 screenVec = GLKVector3Make((px / _viewportWidth) * 2.0f - 1.0f, (py / _viewportHeight) * 2.0f - 1.0f, 1.0f);
GLKMatrix4 ivm = GLKMatrix4Invert(GLKMatrix4Multiply(projectionMatrix, cameraMatrix), &isSuccess); // 全体の変換の逆行列
GLKVector3 upv = GLKMatrix4MultiplyAndProjectVector3(ivm, screenVec); // Projectが付くのはwを考慮して計算してくれるものだったらしい

こっちも見たまま。
わざわざwで割らなくてもGLKMatrix4MultiplyAndProjectVector3で良かったということに後で気がついた。
あと人によっては馴染みがなさそうなのは、オブジェクト毎の移動や回転などの変換があるものは、逆変換を求めてレイの方を回す→求まった交差点を変換、みたいなパターンくらい?
それから今回のは何も考えずにポリゴン総当たりになっているけれど、思ったよりも負荷は少なそう。
ポリゴンモデラーとか普通にいけるかもしれないよッ!

しかしやっぱり少なくとも月一くらいは更新できるといね。