キャラを回転させてまっすぐ進ませる事が出来ない

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

キャラを回転させてまっすぐ進ませる事が出来ない

#1

投稿記事 by azio_group » 13年前

こんにちは。
DXライブラリ + VS2010 でとりあえず3Dモデルを表示して、
←,→キーで3Dモデルを回転させ、
↑キーで3Dモデルからみた正面の方向に進ませたいのですが、どうしてもまっすぐ進みません。

0,0,0を基準に回転するようになったり(大きく0,0,0の周りを回るような感じ)
移動してもワールド座標からみたZ軸にしか動かなかったりします。
たぶん行列についてまだ理解していないからだと思うのですが、
出来ればヒントとか教えてくれると幸いです。

以下コード

コード:

//RX = モデルの回転量 0~360
//RADto = #define RADto(x) ((x)*PHI_F/180.0f)
//MH_M4 = 3Dモデル
//V_M4 = 3Dモデル座標を格納しているVECTOR
//m1 , m2 , m3 = Matrix
//モデルデータは0,0,-100.0fを初期位置にしています

	while(ProcessMessage() == 0 && ScreenFlip() == 0 && ClearDrawScreen() == 0 && GetHitKeyStateAll(key) == 0)
		{
		//メインループ開始
		DrawFillBox(0,0,800,600,GetColor(0,150,255));
		//テンキーによる移動
		if (RX>=360) RX=0;
		if (RX<=-360) RX=0;
		if (key[KEY_INPUT_LEFT] == 1) RX-=3.0f;
		if (key[KEY_INPUT_UP] == 1) V_M4.z-=10.0f;
		if (key[KEY_INPUT_RIGHT] == 1) RX+=3.0f;
		if (key[KEY_INPUT_DOWN] == 1) V_M4.z+=10.0f;
		
		m1 = MGetTranslate(VGet(0,0,0));
		m2 = MGetRotY(RADto(RX));
		m3 = MMult(m1,m2);
		MV1SetMatrix(MH_M4,m3);
		MV1DrawModel(MH_M4);
		SetCameraPositionAndTarget_UpVecY(VGet(0,0,-500.0f),VGet(0,0,0));
		}


アバター
h2so5
副管理人
記事: 2212
登録日時: 15年前
住所: 東京
連絡を取る:

Re: キャラを回転させてまっすぐ進ませる事が出来ない

#2

投稿記事 by h2so5 » 13年前

キャラクターが向いている方向のベクトルを座標に加算しないといけません。
今のコードだとキャラクターの向きに関係なくz座標を操作しているだけです。

azio_group

Re: キャラを回転させてまっすぐ進ませる事が出来ない

#3

投稿記事 by azio_group » 13年前

手持ちにVB + DirectXで3Dゲームを作る参考書があったので、DXライブラリに置き換えて以下の通りにしたところ、
理想の動きになりました。しかし、仕組みを詳しく理解したわけではないので、(特にVTransformが要のように感じます)
どういう仕組みで動いてるか少しでいいので教えてもらえないでしょうか?

コード:

        VECTOR vec;
	while(ProcessMessage() == 0 && ScreenFlip() == 0 && ClearDrawScreen() == 0 && GetHitKeyStateAll(key) == 0)
		{
		//メインループ開始
		DrawFillBox(0,0,800,600,GetColor(0,150,255));
		//テンキーによる移動
		vec = VGet(0,0,0);
		if (RX>=360) RX=0;
		if (RX<=-360) RX=0;
		if (key[KEY_INPUT_LEFT] == 1) RX-=3.0f;
		if (key[KEY_INPUT_UP] == 1) vec.z-=10.0f;
		if (key[KEY_INPUT_RIGHT] == 1) RX+=3.0f;
		if (key[KEY_INPUT_DOWN] == 1) vec.z+=10.0f;
		

		MATRIX mroty = MGetRotY(RADto(RX)); //角度計算
		vec = VTransform(vec,mroty);
		V_M4 = VAdd(V_M4,vec);
		m2 = MGetTranslate(V_M4);
		m3 = MMult(mroty,m2);
		MV1SetMatrix(MH_M4,m3);
		MV1DrawModel(MH_M4);
		SetCameraPositionAndTarget_UpVecY(VGet(0,0,-500.0f),VGet(0,0,0));

		}

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

Re: キャラを回転させてまっすぐ進ませる事が出来ない

#4

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

何処が分かっていないのが分かりませんので、ここの部分に1行毎に自分なりにコメントを書いてみて下さい。
なぜ、この順番で処理するかも言及してもうらうと更に良いです。

コード:

        MATRIX mroty = MGetRotY(RADto(RX)); //角度計算
        vec = VTransform(vec,mroty);
        V_M4 = VAdd(V_M4,vec);
        m2 = MGetTranslate(V_M4);
        m3 = MMult(mroty,m2);
        MV1SetMatrix(MH_M4,m3);
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

azio_group

Re: キャラを回転させてまっすぐ進ませる事が出来ない

#5

投稿記事 by azio_group » 13年前

返信ありがとうございます。
何処がわからないのかも分からない状態です。
3Dモデルから見たX,Y,Zで操作する方法が分かりません。
3Dモデルのローカル座標からZ軸に加算すれば前に進むと思うのですが、その方法が分からず、
ワールド座標からみたZ軸に加算することしかできませんでした。どうやったらローカル座標での計算ができるのでしょうか?

下のコメントは多分かなり間違ってる解釈ばかりだと思います。間違ってる場所の指摘をお願いいたしますm

コード:

        MATRIX mroty = MGetRotY(RADto(RX)); //RX度回転させる
        vec = VTransform(vec,mroty); //←これは一体何をしているのかわからなかったです。実際のモデルへの回転処理はMMult()でしてると思ったのですが…
        V_M4 = VAdd(V_M4,vec); //たぶんモデルから見た状態にvecを加算。今の場合↑を押したらZ方向に進む
        m2 = MGetTranslate(V_M4); //「モデルをV_M4の位置に配置する」を格納
        m3 = MMult(mroty,m2); //「回転処理を加えて、V_M4の位置にモデルを配置する」を格納
        MV1SetMatrix(MH_M4,m3); //↑を実際のモデルに適用

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

Re: キャラを回転させてまっすぐ進ませる事が出来ない

#6

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

まず、移動とモデルへの座標・回転角の反映は別だと考えてください。
ですので、

コード:

        MATRIX mroty = MGetRotY(RADto(RX)); //RX度回転させる
        vec = VTransform(vec,mroty); //←これは一体何をしているのかわからなかったです。実際のモデルへの回転処理はMMult()でしてると思ったのですが…
        V_M4 = VAdd(V_M4,vec); //たぶんモデルから見た状態にvecを加算。今の場合↑を押したらZ方向に進む

コード:

        m2 = MGetTranslate(V_M4); //「モデルをV_M4の位置に配置する」を格納
        m3 = MMult(mroty,m2); //「回転処理を加えて、V_M4の位置にモデルを配置する」を格納
        MV1SetMatrix(MH_M4,m3); //↑を実際のモデルに適用
は、別の処理です。※ mroty は兼用してますが。

上の処理は移動処理です。
z軸を前後移動する移動ベクトルをY軸周りの回転マトリクスで回転させてオブジェクトローカルの回転・移動ベクトルに変換して、V_M4(自機座標?)に加算しています。
やっていることはマトリクスが出てくるだけで2Dと差があるわけでありません。
※ Y軸周りの回転でRXと言う変数名は良くないと思います。

下の処理は現在の座標とモデルの回転状態をモデルに反映します。
ベクトル移動後の座標を使ってワールド平行移動マトリクスを作成しローカル回転マトリクスに掛けて回転・移動マトリクスを求めて、これをモデルに設定しています。
このMMultで掛ける順番が違うとワールド回転になったり、ローカル回転になってくるので気をつけてください。
ローカル回転 * 平行移動 * ワールド回転 の順番です。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

azio_group

Re: キャラを回転させてまっすぐ進ませる事が出来ない

#7

投稿記事 by azio_group » 13年前

返信が大変遅れてすいませんでした。
あの後回答してくださった方を元に色々調べたり人から聞いたりして、動かせるようになりました。

ありがとうございました。

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

Re: キャラを回転させてまっすぐ進ませる事が出来ない

#8

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

azio_group さんが書きました:返信が大変遅れてすいませんでした。
あの後回答してくださった方を元に色々調べたり人から聞いたりして、動かせるようになりました。

ありがとうございました。
動いてよかったですね。
ここのルールなのですが最終的に動いたコードを投稿して頂けますでしょうか。
よろしくおねがいします。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

閉鎖

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