3次元空間上の任意の回転について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
Masao

3次元空間上の任意の回転について

#1

投稿記事 by Masao » 13年前

カメラが任意に位置と向きを変える条件下で、画面に対して固定の位置と角度に3Dオブジェクトを表示したいと思っています。
つまり、画面に対して(UIのように)2次元に描画しているように見せたいのです。
(OpenGL ESで、min3Dというライブラリを使用してます。)

表示位置を、画面に対して固定することはベクトルで簡単に出来たのですが・・。
(カメラの位置と回転は、upAxis(カメラ鉛直軸)、target(見る先)、position(場所)で一意に決まるので、targetとpositionの間の位置を指定した。)、

具体的に言うと、XZ平面上の四角形のオブジェクトを、カメラに対して角度を固定、すなわち、2次元で描画しているように見せたいのです。
ちょっと、検索キーワードが分からないので、どう調べたらいいのか享受出来たら嬉しいです。

回転行列、あるいはクオータニオンを使うのではと思っているのですが。。。
(最終的には、XZ平面にある四角形オブジェクトを、X,Y,Z軸に対してどれだけ回転したら、カメラに対して垂直になるか求めたいのです。)

beatle
記事: 1281
登録日時: 14年前
住所: 埼玉
連絡を取る:

Re: 3次元空間上の任意の回転について

#2

投稿記事 by beatle » 13年前

2次元で描画しているように見せたいとなると、ただ物体をカメラと同じように回転させるだけでいいのでしょうか。
たしかに向きはカメラと同じになりますが、光の向きが変わって影の様子が変わります。

向きをカメラと同じにするだけでいいなら、カメラを移動する度にカメラの回転行列を取り出して物体の回転行列として設定する、みたいな考え方で行けませんか?

Masao

Re: 3次元空間上の任意の回転について

#3

投稿記事 by Masao » 13年前

助言ありがとうございます。

光に関しては気にしてません。
なるほど、カメラと同じ回転行列ですか。
日中は用事があるので、今晩やってみることにします。
ありがとうございます。

Masao

Re: 3次元空間上の任意の回転について

#4

投稿記事 by Masao » 13年前

ちょっと方針が合っているか不安なので、進捗報告させてください。


カメラの行列の取得には、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次元空間上の任意の回転について

#5

投稿記事 by Masao » 13年前

追記:
gluLookAt関数を自分で実装後、その関数で得られた変換行列の結果から、X,Y,Z軸周りの回転成分だけをそれぞれ抽出する方法を探してます。

Masao

Re: 3次元空間上の任意の回転について

#6

投稿記事 by Masao » 13年前

次のコードで、カメラの行列を得る事が出来、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);
                //この先描画
としているんですが、どうも、カメラと垂直を向いてくれません。回転はしているのですが・・・。

何かアドバイスなど頂ければ幸いです。

Masao
記事: 2
登録日時: 13年前
連絡を取る:

Re: 3次元空間上の任意の回転について

#7

投稿記事 by Masao » 13年前

別トピックで、質問を改めていましたところ、解決に至ったので、こちらも解決にします。

(質問を改めていたトピック)
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);

閉鎖

“C言語何でも質問掲示板” へ戻る