カメラが任意に位置と向きを変える条件下で、画面に対して固定の位置と角度に3Dオブジェクトを表示したいと思っています。
つまり、画面に対して(UIのように)2次元に描画しているように見せたいのです。
(OpenGL ESで、min3Dというライブラリを使用してます。)
表示位置を、画面に対して固定することはベクトルで簡単に出来たのですが・・。
(カメラの位置と回転は、upAxis(カメラ鉛直軸)、target(見る先)、position(場所)で一意に決まるので、targetとpositionの間の位置を指定した。)、
具体的に言うと、XZ平面上の四角形のオブジェクトを、カメラに対して角度を固定、すなわち、2次元で描画しているように見せたいのです。
ちょっと、検索キーワードが分からないので、どう調べたらいいのか享受出来たら嬉しいです。
回転行列、あるいはクオータニオンを使うのではと思っているのですが。。。
(最終的には、XZ平面にある四角形オブジェクトを、X,Y,Z軸に対してどれだけ回転したら、カメラに対して垂直になるか求めたいのです。)
3次元空間上の任意の回転について
Re: 3次元空間上の任意の回転について
2次元で描画しているように見せたいとなると、ただ物体をカメラと同じように回転させるだけでいいのでしょうか。
たしかに向きはカメラと同じになりますが、光の向きが変わって影の様子が変わります。
向きをカメラと同じにするだけでいいなら、カメラを移動する度にカメラの回転行列を取り出して物体の回転行列として設定する、みたいな考え方で行けませんか?
たしかに向きはカメラと同じになりますが、光の向きが変わって影の様子が変わります。
向きをカメラと同じにするだけでいいなら、カメラを移動する度にカメラの回転行列を取り出して物体の回転行列として設定する、みたいな考え方で行けませんか?
-
Masao
Re: 3次元空間上の任意の回転について
助言ありがとうございます。
光に関しては気にしてません。
なるほど、カメラと同じ回転行列ですか。
日中は用事があるので、今晩やってみることにします。
ありがとうございます。
光に関しては気にしてません。
なるほど、カメラと同じ回転行列ですか。
日中は用事があるので、今晩やってみることにします。
ありがとうございます。
-
Masao
Re: 3次元空間上の任意の回転について
ちょっと方針が合っているか不安なので、進捗報告させてください。
カメラの行列の取得には、glGetFloatv関数を使えばよい。(これはGL10では使えない。)
FloatBuffer fb = FloatBuffer.allocate(16);
((GL11)Shared.renderer().gl()).glGetFloatv(GL11.GL_MODELVIEW_MATRIX,fb);
こんな感じでコンパイルは通る。が、ネットで調べるとこの関数、「アンドロイドでは使わない方がいい」らしいのです。
http://www.rbgrn.net/content/438-androi ... gselecting
抜粋
"you can't trust the call to glGetFloatv(MODELVIEW_MATRIX) because most android GL implementations return a bunch of 0s. The easiest way to do this is to do your own matrix math and store the matrix yourself, using it for your unproject."
つまりglGetFloatvは信用ならんので、gluLookAt()関数を自分で実装して、変換行列も自分で計算しなさい。ということ。
実際に、上のコードを自分のHTC Desireで試したところ、実際に全部0になってしまったので、どうやらダメみたいです。
そこで、現在、次のような記事を読みながら、これをjavaで実装すればいいのだろう! と、これらの記事とコードを読み始めたところです。
(gluLookAtを置き換える)
http://www21.atwiki.jp/opengl/pages/133.html
(gluLookAtをglLoadMatrixで置き換えてみる)
http://d.hatena.ne.jp/ousttrue/20070514/1179147922
何か、方針が間違ってましたら、ご助言頂けると幸いです。
カメラの行列の取得には、glGetFloatv関数を使えばよい。(これはGL10では使えない。)
FloatBuffer fb = FloatBuffer.allocate(16);
((GL11)Shared.renderer().gl()).glGetFloatv(GL11.GL_MODELVIEW_MATRIX,fb);
こんな感じでコンパイルは通る。が、ネットで調べるとこの関数、「アンドロイドでは使わない方がいい」らしいのです。
http://www.rbgrn.net/content/438-androi ... gselecting
抜粋
"you can't trust the call to glGetFloatv(MODELVIEW_MATRIX) because most android GL implementations return a bunch of 0s. The easiest way to do this is to do your own matrix math and store the matrix yourself, using it for your unproject."
つまりglGetFloatvは信用ならんので、gluLookAt()関数を自分で実装して、変換行列も自分で計算しなさい。ということ。
実際に、上のコードを自分のHTC Desireで試したところ、実際に全部0になってしまったので、どうやらダメみたいです。
そこで、現在、次のような記事を読みながら、これをjavaで実装すればいいのだろう! と、これらの記事とコードを読み始めたところです。
(gluLookAtを置き換える)
http://www21.atwiki.jp/opengl/pages/133.html
(gluLookAtをglLoadMatrixで置き換えてみる)
http://d.hatena.ne.jp/ousttrue/20070514/1179147922
何か、方針が間違ってましたら、ご助言頂けると幸いです。
-
Masao
Re: 3次元空間上の任意の回転について
追記:
gluLookAt関数を自分で実装後、その関数で得られた変換行列の結果から、X,Y,Z軸周りの回転成分だけをそれぞれ抽出する方法を探してます。
gluLookAt関数を自分で実装後、その関数で得られた変換行列の結果から、X,Y,Z軸周りの回転成分だけをそれぞれ抽出する方法を探してます。
-
Masao
Re: 3次元空間上の任意の回転について
次のコードで、カメラの行列を得る事が出来、gluLookAtを置き換える事が出来ました。
そして、オブジェクトを描画するときに
としているんですが、どうも、カメラと垂直を向いてくれません。回転はしているのですが・・・。
何かアドバイスなど頂ければ幸いです。
void LookAt(float eyex, float eyey, float eyez, float centerx,
float centery, float centerz, float upx, float upy, float upz){
Number3d forward = new Number3d(centerx-eyex,centery-eyey,centerz-eyez);
Number3d up = new Number3d(upx,upy,upz);
forward.normalize();
Number3d side = Number3d.cross(up, forward);
side.normalize();
up.setAllFrom(Number3d.cross(forward,side));
float m[]={
side.x,up.x,-forward.x,0,
side.y,up.y,-forward.y,0,
side.z,up.z,-forward.z,0,
0,0,0,1
};
float mov[]={
1,0,0,0,
0,1,0,0,
0,0,1,0,
-eyex,-eyey,-eyez,1
};
Matrix.multiplyMM(camera_matrix, 0, m, 0, mov, 0);
Shared.renderer().gl().glLoadMatrixf(camera_matrix,0);
for(int i = 0;i<16;i++){
camera_matrix[i] = m[i];
}
}
_gl.glPushMatrix();
_gl.glTranslatef($o.position().x, $o.position().y, $o.position().z);
_gl.glRotatef($o.rotation().x, 1,0,0);
_gl.glRotatef($o.rotation().y, 0,1,0);
_gl.glRotatef($o.rotation().z, 0,0,1);
_gl.glMultMatrixf(camera_matrix, 0);
_gl.glScalef($o.scale().x, $o.scale().y, $o.scale().z);
//この先描画
何かアドバイスなど頂ければ幸いです。
Re: 3次元空間上の任意の回転について
別トピックで、質問を改めていましたところ、解決に至ったので、こちらも解決にします。
(質問を改めていたトピック)
http://dixq.net/forum/viewtopic.php?f=3&t=11286
======以下、同様の解決報告をさせて頂きます。=======
すみません。自己解決しました。
http://www.sousakuba.com/Programming/d3d_camera.html
「カメラ座標変換の逆行列がビュー変換行列になります。」
先の行列の逆行列をかけたら出来ました!!
お騒がせいたしました。
コードはこんな感じです。
(質問を改めていたトピック)
http://dixq.net/forum/viewtopic.php?f=3&t=11286
======以下、同様の解決報告をさせて頂きます。=======
すみません。自己解決しました。
http://www.sousakuba.com/Programming/d3d_camera.html
「カメラ座標変換の逆行列がビュー変換行列になります。」
先の行列の逆行列をかけたら出来ました!!
お騒がせいたしました。
コードはこんな感じです。
Number3d forward = new Number3d(centerx-eyex,centery-eyey,centerz-eyez);
Number3d up = new Number3d(upx,upy,upz);
forward.normalize();
Number3d side = Number3d.cross(up, forward);
side.normalize();
up.setAllFrom(Number3d.cross(forward,side));
float m2[]={
side.x,-forward.x,-up.x,0,
side.y,-forward.y,-up.y,0,
side.z,-forward.z,-up.z,0,
0,0,0,1
};
Matrix.invertM(camera_matrix, 0, m2, 0);