【3D】カメラを原点に向ける

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
アバター
みけCAT
記事: 6734
登録日時: 15年前
住所: 千葉県
連絡を取る:

【3D】カメラを原点に向ける

#1

投稿記事 by みけCAT » 13年前

Dev-C++5.2.0.3(gcc4.7.0)、Windows Vista SP2 32ビットです。
3Dの描画の実験をしています。
カメラに、原点を中心とした球上を移動し、常に原点を見る、ということをさせたいです。
適当に書いてみたのですが、うまくいきませんでした。
softyaさんに作っていただいたライブラリを改造したライブラリを使用しています。
カメラの定義はこうなっています。

コード:

/*
x,y,z:座標
cx:縦の首振り(正=上)
cy:横の首振り(正=右) 
cz:回転(正=時計回り) 
genkai:視野(ピクセル)
genkaiangle:視野(角度) 
centerx,centery:中心の座標(二次元) 
*/
typedef struct {
	double x,y,z;
	double cx,cy,cz;
	double genkai,genkaiangle;
	double centerx,centery;
	double matrix[4][4];
} camera_t;
位置と方向の計算部分は、このようになっています。

コード:

camera.cy=-dec2rad(xangle);
camera.cx=-dec2rad(yangle);
camera.z=-500*cos(-camera.cx);
camera.y=-500*sin(-camera.cx);
camera.x=-camera.z*sin(-camera.cy);
camera.z=camera.z*cos(-camera.cy);
カメラを球上で動かすことには(多分)成功しているので、
あとはカメラの角度を適切に計算できればいいと思います。

このページを見つけましたが、
知らない関数と難しい用語があって理解できませんでした。
http://marupeke296.com/DXG_No56_CameraBaseTrans.html

どのように計算すればいいのでしょうか?
教えていただければ幸いです。
よろしくお願いします。

現段階のプロジェクト一式を添付します。
添付ファイル
3dtest_7.zip
プロジェクトです。
(22.1 KiB) ダウンロード数: 117 回
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 【3D】カメラを原点に向ける

#2

投稿記事 by softya(ソフト屋) » 13年前

いまだに行列を使ってはいけないのでしょうか?
使わないにしても、行列を展開した形にならざる負えないと思いますが。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
みけCAT
記事: 6734
登録日時: 15年前
住所: 千葉県
連絡を取る:

Re: 【3D】カメラを原点に向ける

#3

投稿記事 by みけCAT » 13年前

行列を使っても構いません。
よろしくお願いします。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 【3D】カメラを原点に向ける

#4

投稿記事 by softya(ソフト屋) » 13年前

みけCAT さんが書きました:行列を使っても構いません。
よろしくお願いします。
ちょっと待って下さいね。

【補足】 とりあえず分りやすいのが見つからないので参考1です。
「(1) gluLookAt はどんな matrix を生成するのか?|Chandler@Berlin」
http://ameblo.jp/renderrender/entry-10760743329.html
これで勉強してみてください。

ちなみにDXライブラリの関数は、下記のようになっています。

コード:

// ビュー行列を作成する
extern int CreateLookAtMatrix( MATRIX *Out, VECTOR *Eye, VECTOR *At, VECTOR *Up )
{
	VECTOR va, vu, vx, vy, vz ;

	// 視点→注視点のベクトルを得る
	va = VectorSa( *At, *Eye ) ;

	// 視点に垂直なベクトルを得る
	vu = *Up ;

	// 新X軸のベクトルを算出
	vx = VectorGaiseki( vu, va ) ;

	// 新Y軸のベクトルを算出
	vy = VectorGaiseki( va, vx ) ;

	// 新Z軸のベクトルをセット
	vz = va ;

	// 各ベクトルの正規化
	VectorNormalize( &vx, &vx ) ;
	VectorNormalize( &vy, &vy ) ;
	VectorNormalize( &vz, &vz ) ;

	// ビュー行列の作成
	Out->m[0][0] = vx.x ; Out->m[0][1] = vy.x ; Out->m[0][2] = vz.x ; Out->m[0][3] = 0.0f ;
	Out->m[1][0] = vx.y ; Out->m[1][1] = vy.y ; Out->m[1][2] = vz.y ; Out->m[1][3] = 0.0f ;
	Out->m[2][0] = vx.z ; Out->m[2][1] = vy.z ; Out->m[2][2] = vz.z ; Out->m[2][3] = 0.0f ;
	Out->m[3][3] = 1.0f ;

	Out->m[3][0] = - ( Eye->x * vx.x + Eye->y * vx.y + Eye->z * vx.z ) ;
	Out->m[3][1] = - ( Eye->x * vy.x + Eye->y * vy.y + Eye->z * vy.z ) ;
	Out->m[3][2] = - ( Eye->x * vz.x + Eye->y * vz.y + Eye->z * vz.z ) ;
	return 0;
}
実装できそうになかったらまた聞いてください。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
みけCAT
記事: 6734
登録日時: 15年前
住所: 千葉県
連絡を取る:

Re: 【3D】カメラを原点に向ける

#5

投稿記事 by みけCAT » 13年前

適当に書いてみたのですが、
・upベクトルを上向きの(0,-1,0)ではなく下向きの(0,1,0)にしないと今までの画面の向きにならないのですが、正常ですか?
・見た目では正しそうに見えますが、本当に正しいですか?

コード:

static void vectorGaiseki(double out[4],double a[4],double b[4]) {
	double temp[4];
	temp[0]=a[1]*b[2]-b[1]*a[2];
	temp[1]=a[2]*b[0]-b[2]*a[0];
	temp[2]=a[0]*b[1]-b[0]*a[1];
	temp[3]=1;
	out[0]=temp[0];
	out[1]=temp[1];
	out[2]=temp[2];
	out[3]=temp[3];
}

static void vectorNormalize(double vec[4]) {
	double zettaiti;
	zettaiti=sqrt(vec[0]*vec[0]+vec[1]*vec[1]+vec[2]*vec[2]);
	vec[0]/=zettaiti;
	vec[1]/=zettaiti;
	vec[2]/=zettaiti;
}

void updateCameraLookAt(camera_t* camera,
		double x,double y,double z,
		double upx,double upy,double upz) {
	double Vmatrix[4][4];  // ビュー行列
	double MVmatrix[4][4]; // 平行移動行列
	double RZmatrix[4][4]; // z回転行列
    double Pmatrix[4][4]; //射影変換行列
	double rot;
	double vz[4];
	double vy[4];
	double vx[4];
	vz[0]=x-camera->x;
	vz[1]=y-camera->y;
	vz[2]=z-camera->z;
	vz[3]=1;
	vy[0]=upx;
	vy[1]=upy;
	vy[2]=upz;
	vy[3]=1;
	vectorGaiseki(vx,vy,vz);
	vectorGaiseki(vy,vz,vx);
	vectorNormalize(vx);
	vectorNormalize(vy);
	vectorNormalize(vz);

	// ビュー行列
	setMatrix( Vmatrix,
	            vx[0],      vy[0],      vz[0],     0,
	            vx[1],      vy[1],      vz[1],     0,
	            vx[2],      vy[2],      vz[2],     0,
	            0,          0,          0,         1    );
	Vmatrix[3][0]=-(camera->x*vx[0]+camera->y*vx[1]+camera->z*vx[2]);
	Vmatrix[3][1]=-(camera->x*vy[0]+camera->y*vy[1]+camera->z*vy[2]);
	Vmatrix[3][2]=-(camera->x*vz[0]+camera->y*vz[1]+camera->z*vz[2]);
    //  Z回転マトリックス
    rot = -camera->cz;
    setMatrix( RZmatrix,
                cos(rot),   sin(rot),   0,          0,
                -sin(rot),  cos(rot),   0,          0,
                0,          0,          1,          0,
                0,          0,          0,          1   );

    //  マトリックスの合成
    calcMatrix(Vmatrix,RZmatrix);

    //  射影変換行列を設定する。
    {
        double depth,ctan;
        double cnear,cfar,width,height;
        
        cnear = 0.1;
        cfar = 1000.0;
        ctan = tan(camera->genkaiangle*0.5);
        width = 1.0 / ctan;
        height = 1.0 / ctan;
        depth = cfar / (cfar - cnear);
        setMatrix( Pmatrix,
                        width,  0,    0,              0,
                        0,    height, 0,              0,
                        0,    0,      depth,          1,
                        0,    0,      -depth * cnear, 0 );
    }
    //  行列の演算。
    calcMatrix(Vmatrix,Pmatrix);
    copyMatrix(camera->matrix,Vmatrix);
}
よろしくお願いします。
UIも少し変更したので、プロジェクトを上げ直します。
オフトピック
このライブラリ、DXライブラリと比べるとy軸の方向が180度逆なのですね。
仕様ということで、悪くはないですけど。
添付ファイル
3dtest_7.zip
プロジェクトです。
(24.33 KiB) ダウンロード数: 109 回
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 15年前
住所: 東海地方
連絡を取る:

Re: 【3D】カメラを原点に向ける

#6

投稿記事 by softya(ソフト屋) » 13年前

Y軸の上下が違うのはかの有名な右手系・左手系の違いだと思います。
http://www.arakin.dyndns.org/gl_coord.php

あとは多分大丈夫じゃないでしょうか。

【補足】
私が無意識に右手系座標で作ってしまったみたいですね。
OpenGL系とおなじはずですので、データはOpenGLの物が使えます。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

アバター
みけCAT
記事: 6734
登録日時: 15年前
住所: 千葉県
連絡を取る:

Re: 【3D】カメラを原点に向ける

#7

投稿記事 by みけCAT » 13年前

ありがとうございました。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

閉鎖

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