ページ 11

3Dモデルの描画位置の座標について

Posted: 2013年6月23日(日) 18:13
by chalaza
3D関数にまだ慣れていなく、少し聞きたいことがあります。

プレイヤーのモデルをVGet( 320.0f, 240.0f, 0.0f );の位置に描画して、
カメラの座標をVGet(320.0f, 240.0f, -300.0f) ; の位置にしました。プレイヤーをZ軸300f離れた位置から見るようにするためです。
そして、もうひとつただの箱をVGet( 320.0f, 240.0f, 0.0f);の位置に描画したのですが、
その箱がプレイヤーと同じ位置ではなく、すこしずれた位置に描画されます。
何故なのでしょうか?

Re: 3Dモデルの描画位置の座標について

Posted: 2013年6月23日(日) 18:15
by chalaza
すみません。注視点はプレイヤーの座標です。

Re: 3Dモデルの描画位置の座標について

Posted: 2013年6月23日(日) 18:34
by h2so5
プレイヤーのモデルか箱のモデルの中心座標がずれているからではないでしょうか。

Re: 3Dモデルの描画位置の座標について

Posted: 2013年6月23日(日) 18:40
by softya(ソフト屋)
ローカル座標系の中心がズレているのではないでしょうか?
つまり、モデリングの時の中心位置が違うのではないかと。

Re: 3Dモデルの描画位置の座標について

Posted: 2013年6月23日(日) 18:46
by chalaza
試しにPMDエディタでプレイヤーと箱のモデルを同時に読み込んだら、しっかり重なっていました。
Z軸だけが200ほどずれているようなのですが(箱がプレイヤーより200ほど奥にある)
カメラの設定が特にあやしいのですが、なにか間違っていませんか?

Player.cppです

コード:

#include "DxLib.h"
#include "Keyboard.h"
#include "Player.h"
#include "Map.h"

int PixelShaderHandle ;		//ピクセルシェーダ用1
int PixelShaderHandle2 ;	//ピクセルシェーダ用2

int ScreenHandle1;		//ベタ塗り用スクリーン
int ScreenHandle2;		//縁取り用スクリーン
int Beta1Image;			//ベタ塗用画像
VERTEX2DSHADER Vert[6];	//頂点データ

//プレイヤーの初期化
void Player_Initialize( Player_t *Player, Camera_t *Camera  ){

	// カメラを初期化
	Camera->pos = VGet(320, 240, -300.0f) ;
	Camera->r = 0;
	SetCameraNearFar(100, 2000);  

	//縁取りのために二画面用意
	// フルシーンアンチエイリアスを設定して作成
    SetFullSceneAntiAliasingMode( 4, 2 ) ;
	ScreenHandle1 = MakeScreen( 640, 480, TRUE ) ;
	// フルシーンアンチエイリアスを設定して作成
    SetFullSceneAntiAliasingMode( 4, 2 ) ;
	ScreenHandle2 = MakeScreen( 640, 480, TRUE);

	// 画像の読み込み
	Beta1Image = LoadGraph( "Image/Beta1.bmp" );

	// ピクセルシェーダーを読み込む
	PixelShaderHandle = LoadPixelShader( "BetaPS.pso" ) ;
	PixelShaderHandle2 = LoadPixelShader( "Beta2PS.pso" ) ;

	// 3Dモデルの読み込み  
	Player->Model = MV1LoadModel( "Model/Player.pmx" ) ;  
	//大きくする(モデルはMMDサイズから変えたくないので)
	MV1SetScale(Player->Model, VGet(8, 8, 8) ); 

	int MaterialNum = MV1GetMaterialNum( Player->Model ) ;
	for( int i = 0 ; i < MaterialNum ; i ++ )  
	{  
		// マテリアルの輪郭線をなくす
		MV1SetMaterialOutLineDotWidth( Player->Model, i, 0.0f ) ;
		MV1SetMaterialOutLineWidth( Player->Model, i, 0.0f ) ;
	}
	// プレイヤーの座標を初期化
	Player->Modelpos = VGet( 320.0f, 240.0f, 0.0f ); 
	//プレイヤーの回転
	Player->r = 0;
}

//プレイヤーの動き
void Player_Move( Player_t *Player , Camera_t *Camera , Input_t *Input){

	// 方向キーで移動
	if( Input->UP > 0 )
    {
        Player->Modelpos.z += 2.0f ;
    }
    if( Input->DOWN > 0 )
    {
        Player->Modelpos.z -= 2.0f ;
    }
    if( Input->LEFT > 0 )
    {
        Player->Modelpos.x -= 2.0f ;
	}
    if( Input->RIGHT > 0 )
    {
		Player->Modelpos.x += 2.0f ;
    }
	//Zキー(PADボタン1)で回転
	if(Input->A > 0)
		Player->r+= 0.1f;
	MV1SetRotationXYZ(Player->Model, VGet(0, Player->r, 0) );  

	//モデルの位置を設定
	MV1SetPosition(Player->Model, Player->Modelpos ) ;

	//カメラの設定 
	Camera->pos = VGet(320, 240, -300.0f) ; 
	// カメラの位置と注視点をセット、注視点はプレイヤー
	SetCameraPositionAndTargetAndUpVec(Camera->pos,  
		Player->Modelpos , 
		VGet(0, 1, 0)); 

	//テスト用
	//SetupCamera_Perspective( PHI_F / 3 );  
	//SetupCamera_Ortho(150); 

}

//プレイヤー描画
void Player_Draw(Player_t Player){

	// Player->Modelpos の内容を画面に表示
    DrawFormatString( 0, 0, GetColor( 255,255,255 ), "Player->Modelpos  x=%f y=%f z=%f", Player.Modelpos.x, Player.Modelpos.y, Player.Modelpos.z ) ;

	// 頂点データ
	Vert[ 0 ].pos = VGet(    0.0f,   0.0f, 0.0f ) ;
	Vert[ 1 ].pos = VGet( 640.0f,   0.0f, 0.0f ) ;
	Vert[ 2 ].pos = VGet(    0.0f, 480.0f, 0.0f ) ;
	Vert[ 3 ].pos = VGet( 640.0f, 480.0f, 0.0f ) ;
	Vert[ 0 ].dif = GetColorU8( 255,255,255,255 ) ;
	Vert[ 0 ].spc = GetColorU8( 0,0,0,0 ) ;
	Vert[ 0 ].u = 0.0f ; Vert[ 0 ].v = 0.0f ;
	Vert[ 1 ].u = 1.0f ; Vert[ 1 ].v = 0.0f ;	
	Vert[ 2 ].u = 0.0f ; Vert[ 2 ].v = 1.0f;
	Vert[ 3 ].u = 1.0f ; Vert[ 3 ].v = 1.0f;
	Vert[ 0 ].su = 0.0f ; Vert[ 0 ].sv = 0.0f ;
	Vert[ 1 ].su = 1.0f ; Vert[ 1 ].sv = 0.0f ;
	Vert[ 2 ].su = 0.0f ; Vert[ 2 ].sv = 1.0f;
	Vert[ 3 ].su = 1.0f ; Vert[ 3 ].sv = 1.0f;
	Vert[ 0 ].rhw = Vert[ 1 ].rhw = Vert[ 2 ].rhw = Vert[ 3 ].rhw = 1.0f ;
	Vert[ 4 ] = Vert[ 2 ] ;		Vert[ 5 ] = Vert[ 1 ] ;

	//描画先を描画用画面1にセット
	SetDrawScreen( ScreenHandle1) ;
	ClearDrawScreen() ;  //画面クリア

	// モデルの描画にオリジナルシェーダーを使用する設定をONにする
	MV1SetUseOrigShader( TRUE ) ;
	// 使用するピクセルシェーダーをセット
	SetUsePixelShader( PixelShaderHandle ) ;

	// 3Dモデルをベタ塗りで描画
	MV1DrawModel(Player.Model) ;

	//描画先を描画用画面2にセット
	SetDrawScreen( ScreenHandle2) ;
	ClearDrawScreen() ;  //画面クリア

	// 使用するピクセルシェーダーをセット
	SetUsePixelShader( PixelShaderHandle2 ) ;
	// 使用するテクスチャをセット
	SetUseTextureToShader( 0, ScreenHandle1 ) ;
	SetUseTextureToShader( 2, Beta1Image ) ;
	// モデルの縁取りを描画
	DrawPrimitive2DToShader( Vert, 6, DX_PRIMTYPE_TRIANGLELIST ) ;

	// 描画先を裏画面に変更
	SetDrawScreen( DX_SCREEN_BACK ) ;

	// モデルの描画にオリジナルシェーダーを使用する設定をOFFにする
	MV1SetUseOrigShader( FALSE ) ;

	// 縁取り輪郭のグラフィックハンドルを描画
	DrawGraph( 0, 0, ScreenHandle2, TRUE ) ;

	//モデルを描画
	MV1DrawModel(Player.Model) ;


}
Map.cppです。箱を描画します。

コード:

#include "DxLib.h"
#include "Keyboard.h"
#include "Map.h"
#include "Player.h"

int Box1;	//箱のモデル

void Map_Initialize(){	//マップ初期化

	// 3Dモデルの読み込み  
	Box1 = MV1LoadModel( "Model/Box1.pmx" ) ; 
	//大きくする
	MV1SetScale(Box1, VGet(8, 8, 8) ); 
}

//マップの動き
void Map_Move( Player_t *Player, Input_t *Input ){


}

void Map_Draw(Player_t Player)//マップ描画
{
	//背景
	DrawBox(0,0,640,480, 0xBBBBFF, TRUE); 

	//箱の位置を指定して描画
	MV1SetPosition(Box1, VGet( 320.0f, 240.0f, 300.0f)) ; 
	MV1DrawModel(Box1) ;

}

Re: 3Dモデルの描画位置の座標について

Posted: 2013年6月23日(日) 18:53
by chalaza
すみません。最後の//箱の位置を指定して描画は
MV1SetPosition(Box1, VGet( 320.0f, 240.0f, 300.0f)) ;となっていますが、この指定でやっとモデルと重なるということで、
実際はZ軸を0にしたいわけです。

Re: 3Dモデルの描画位置の座標について

Posted: 2013年6月23日(日) 18:56
by chalaza
すみませんそうでもなかったみたいです。もう一度いろいろやってみます。

Re: 3Dモデルの描画位置の座標について

Posted: 2013年6月23日(日) 19:02
by chalaza
どうやらやっぱり箱のZ座標の位置だけずれているようでした。
何かわかりませんか?

Re: 3Dモデルの描画位置の座標について

Posted: 2013年6月23日(日) 19:59
by softya(ソフト屋)
PMDエディタが補正している可能性はありませんか?
生のデータを見てみないとなんとも言えないです。
※ 一番疑うべきものを最初に除外してはいけません。

Re: 3Dモデルの描画位置の座標について

Posted: 2013年6月23日(日) 21:45
by chalaza
試しにプレイヤーと箱のXYZ座標を画面に文字で表示させてみたら完全に同じ座標なのにずれていました・・・。
仰る通りPMDエディタのせいっぽいです。
そこでなんですが、ここでPMDエディタの事を聞くのもおかしいかもしれませんが、
PMDエディタでの補正はどうやって確認するのでしょうか?
一応PMXエディタもあります。

Re: 3Dモデルの描画位置の座標について

Posted: 2013年6月23日(日) 21:51
by softya(ソフト屋)
PMDエディタの補正を確認しても意味が無いのでは?
ごめんなさい。何がやりたいのか見えて来ません。
PMDで何を確認しているのでしょうか?

PMDの出力ファイルをバイナリで見る方法もあるようですが。
「DirectX11プログラミング -単純なPMDファイルを見てみる-」
http://yun.cup.com/directx11018.html

Re: 3Dモデルの描画位置の座標について

Posted: 2013年6月24日(月) 00:06
by chalaza
要するに、PMDエディタに移す前のXファイルの時点でずれていて、PMDエディタは勝手に中心に補正して表示してくれてたけど
実際は位置が原点でなかった。という事でしょうか?
Xファイルに書きだすときの設定はUVマッピングと拡大率くらいしか設定できないようですが…

Re: 3Dモデルの描画位置の座標について

Posted: 2013年6月24日(月) 00:11
by softya(ソフト屋)
いくつか確認してください。
1.まず、モデリングした位置が問題となります。
2.Xファイルはテキストなので座標確認が比較的簡単です。
3.PMDエディタでの座標を確認してください。これも出来ないのでしょうか?
4.できればPMDファイルをバイナリレベルで確認してください。
5.箱のモデルの中心座標が合っていることを確認して、私に示してください。

私にはchalazaさん のフィルタを通した情報ばかりなので確認しようがないのです。
なので生のデータを見たいと言っているわけです。

【補足】 公開に支障があるなら支障のない簡単なデータを用意してください。問題点の追試にもなります。

Re: 3Dモデルの描画位置の座標について

Posted: 2013年6月24日(月) 13:44
by chalaza
メタセコでの表示もPMDエディタでの表示も、モデルは軸の中心に表示されていて、
Xファイルのテキストでもモデルも箱も(箱なら頂点が-6から6だけで表示されている)問題なさそうなのです。
PMDエディタのセンターボーンの位置も中心座標の位置も0,0,0になっているようなのですが、他に確認すべきところはあるでしょうか?

それと、問題に関係あるかどうかは分からないのですが、カメラの位置と注視点をセットするときに、ためしに

コード:

SetCameraPositionAndTargetAndUpVec(VGet(320, 400, -450),  
		Player->Modelpos,  
		VGet(0, 1, 0));  
というような、モデルの上から見下ろすような位置にカメラを移動させたのですが、プレイヤーを上から見た感じ(頭の上が見える)ではなく、
真横から見た感じに表示されてしまいます。
そしてなぜか箱のモデルはしっかり上面が見えているのです。
何がおかしいのでしょうか?

Re: 3Dモデルの描画位置の座標について

Posted: 2013年6月24日(月) 14:03
by chalaza
もしここでファイルを公開する場合は、アップローダなどを使うのでしょうか?

Re: 3Dモデルの描画位置の座標について

Posted: 2013年6月24日(月) 14:15
by chalaza
本当にすみません。解決しました!
モデルには異常が無くて、私はモデルを縁取りつきで描画するためにスクリーンハンドルを切り替えて描画していたのですが、
描画するスクリーンハンドルを切り替えるとカメラの設定が初期化されてしまうという仕様のため、
プレイヤーを描画するときだけカメラが初期化されていたようです。
スクリーンハンドルを切り替えた後にもう一度カメラ設定をしたら正常な位置に描画されました。
迷惑かけてすみません。ありがとうございました。

Re: 3Dモデルの描画位置の座標について

Posted: 2013年6月24日(月) 18:35
by softya(ソフト屋)
すいません。それを見逃してました。
やはり、データがないと検証が難しいですね。

このmixc++の会員になって頂くとファイル貼付可能です。
あるいは、どこかのアップローダを使用してください。