DirectXで視点の回転がうまくいかない

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

DirectXで視点の回転がうまくいかない

#1

投稿記事 by あうあう » 12年前

FPSゲームを作ろうとしているのですが、視点の回転がうまくいきません。
上のほうを見ようとすると、前にある物体が前に来るのです。
(このようになる→http://kuwasa.net/captingm/vi?key=aiknorCDFGIRTVWYZ3
どうしたらよいのでしょうか?
また、前進,後退をしようとしてもすこしも進みません。
こちらの改善点も教えて頂けると嬉しいです。

コード:

//DirectX.h
#ifndef DEF_DIRECTX_H
#define DEF_DIRECTX_H

HRESULT DxInit(HWND hWnd);
int DxMainloop(HWND hWnd);
int DxEnd(void);
int Draw2Drect(float left,float top,float right,float bottom,DWORD color);
#endif

コード:

//DirectX.cpp
#include <d3d9.h>
#include <d3dx9.h>
#include <tchar.h>
#include <stdio.h>
#include "DirectX.h"
#include "WndKey.h"

#define SCREEN_WIDTH GetSystemMetrics(SM_CXSCREEN)
#define SCREEN_HEIGHT GetSystemMetrics(SM_CYSCREEN)
#define FVF_CUSTOM ( D3DFVF_XYZRHW | D3DFVF_DIFFUSE | D3DFVF_TEX1 )
#define WINDOW_WIDTH (500.0f)
#define WINDOW_HEIGHT  (450.0f)

static LPDIRECT3D9 g_pD3D=NULL;
static LPDIRECT3DDEVICE9 g_pd3dDevice=NULL;
static IDirect3DVertexBuffer9 *pVertex;
static ID3DXBuffer *obj_pMat;
static ID3DXMesh *obj_pMesh;
static D3DLIGHT9 light;
DWORD obj_NumMat;
static float fCamX=12.0f,fCamY=2.0f,fCamZ=19.0f;
typedef struct CUSTOMVERTEX{
	float x,y,z;
	float rhw;
	DWORD dwcolor;
	float u,v;
}CUSTOMVERTEX;

HRESULT DxInit(HWND hWnd)
{
    char               msgbuff[2048];
    BOOL			   WINDED = TRUE;

     // DirectXの初期化
    if( NULL == ( g_pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
    {
		g_pD3D->Release();
        MessageBox(hWnd,"Startup Failed.","DirectX9",MB_OK);
        return E_FAIL;
    }

    // 画面などの設定
    D3DDISPLAYMODE d3ddm;
	D3DFORMAT fmt_mode;

    if( FAILED( g_pD3D->GetAdapterDisplayMode( D3DADAPTER_DEFAULT, &d3ddm ) ) )
		{
			g_pD3D->Release();
			return E_FAIL;
		}
    D3DPRESENT_PARAMETERS d3dpp;
	ZeroMemory( &d3dpp, sizeof(d3dpp) );
    d3dpp.Windowed                    = WINDED;	// WINDEDには、true か false を入れておく
    
	if(WINDED)
    {
		fmt_mode = d3ddm.Format;
    } else {
         d3dpp.FullScreen_RefreshRateInHz = D3DPRESENT_RATE_DEFAULT;    //D3DPRESENT_RATE_UNLIMITED D3DPRESENT_RATE_DEFAULT
    }

    d3dpp.BackBufferFormat           = fmt_mode;
    d3dpp.SwapEffect                 = D3DSWAPEFFECT_DISCARD;  //D3DSWAPEFFECT_FLIP D3DSWAPEFFECT_DISCARD D3DSWAPEFFECT_COPY;//描画フラグ
    d3dpp.EnableAutoDepthStencil     = TRUE;                    // Zバッファを使用する
    d3dpp.AutoDepthStencilFormat     = D3DFMT_D16;
    d3dpp.BackBufferCount            = 1;
    d3dpp.hDeviceWindow              = hWnd;
    d3dpp.BackBufferWidth            = SCREEN_WIDTH;
    d3dpp.BackBufferHeight           = SCREEN_HEIGHT;


    // 設定した画面情報をDirectXに登録する。
    if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,D3DCREATE_HARDWARE_VERTEXPROCESSING,  &d3dpp, &g_pd3dDevice ) ) )
    {
        if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,  &d3dpp, &g_pd3dDevice ) ) )
        {
            if( FAILED( g_pD3D->CreateDevice( D3DADAPTER_DEFAULT, D3DDEVTYPE_REF, hWnd,D3DCREATE_SOFTWARE_VERTEXPROCESSING,  &d3dpp, &g_pd3dDevice ) ) )
            {
                sprintf_s(msgbuff,"CreateDevice Error. \nBackBufferFormat=0x%04X\n",d3dpp.BackBufferFormat);
                MessageBox(hWnd,msgbuff,"Error!",MB_OK);
                g_pD3D->Release();
				return E_FAIL;
            }
        }
    }
	 
    //-----------------------------------------------
    //  画像以外のDirectXの初期化は、ここで行う
    //-----------------------------------------------
	if(FAILED(D3DXLoadMeshFromX(_T("ground.x"),
								D3DXMESH_MANAGED,
								g_pd3dDevice,
								NULL,
								&obj_pMat,
								NULL,
								&obj_NumMat,
								&obj_pMesh)))
											{
											g_pd3dDevice->Release();
											g_pD3D->Release();
											return E_FAIL;
											}
	
	
	ZeroMemory(&light,sizeof(D3DLIGHT9));
	light.Type = D3DLIGHT_DIRECTIONAL;

	light.Diffuse.r= light.Diffuse.g= light.Diffuse.b=0.4f;
	light.Specular.r= light.Specular.g= light.Specular.b=0.1f;
	light.Ambient.r= light.Ambient.g= light.Ambient.b=0.2f;
	
	light.Direction = D3DXVECTOR3(1,-5,-10);	// 平行光源なので向きが必要
	g_pd3dDevice->SetLight(0,&light);
	g_pd3dDevice->LightEnable(0,TRUE);
	   g_pd3dDevice->SetRenderState( D3DRS_LIGHTING, TRUE );
	   g_pd3dDevice->SetRenderState( D3DRS_AMBIENT,0x00808080);




	return S_OK;
}

int DxMainloop(HWND hWnd)
{
	
	D3DXMATRIX World_gr;
	D3DXMATRIX Rot;
	D3DXMATRIX Offset;
	D3DXMATRIX View;
	D3DXMATRIX Persp;
	D3DCOLORVALUE MAmbient = {0.2f, 0.2f, 0.2f, 1.0f};
	int Ground_NumX=10,Ground_NumZ=10;//地面の数
	int x,y;
	//int CurrentKey;

	g_pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET|D3DCLEAR_ZBUFFER,
                         D3DCOLOR_XRGB(40,40,80),
						 1.0f,
						 NULL );
		g_pd3dDevice->BeginScene();
		//ビュー変換+移動について
		if(GetKey()==KEY_W){fCamX+=(float)cos(3.14159/180*GetMoveX());
							fCamZ+=(float)sin(3.14159/180*GetMoveX());}
		if(GetKey()==KEY_A){}
		if(GetKey()==KEY_S){fCamX-=(float)cos(3.14159/180*GetMoveX());
							fCamZ-=(float)sin(3.14159/180*GetMoveX()); }
		if(GetKey()==KEY_D){}

		D3DXMatrixLookAtLH(
                  &View,
                  &D3DXVECTOR3(fCamX, 2.0f, fCamZ),
                  &D3DXVECTOR3((float)fCamX+(float)cos(3.14159/180*GetMoveX()),
							   (float)fCamY+(float)cos(3.14159/180*GetMoveY()/2),
							   (float)fCamZ+(float)sin(3.14159/180*GetMoveX())),
                  &D3DXVECTOR3(0.0f, 1.0f, 0.0f)
                  );
	//射影変換
		D3DXMatrixPerspectiveFovLH(
			&Persp,
			D3DXToRadian(90),
			WINDOW_HEIGHT/WINDOW_WIDTH,
			1.0f,
			10000.0f);

					
			g_pd3dDevice->SetTransform(D3DTS_VIEW, &View);
			g_pd3dDevice->SetTransform(D3DTS_PROJECTION, &Persp);
			
		for(x=0;x<Ground_NumX;x++)
		for(y=0;y<Ground_NumZ;y++)
		{
			
		 //FLOAT PosX = (FLOAT)x-Ground_NumX/220.0f;                                 // 板の制御点の
         //FLOAT PosY = (FLOAT)y-Ground_NumZ/220.0f;                                 // 位置(x,y,0)を決め、
		   FLOAT PosX = (FLOAT)x-Ground_NumX/200.0f;
		   FLOAT PosY = (FLOAT)y-Ground_NumZ/200.0f;

		D3DXMatrixTranslation(&Offset,PosX,0.0f,PosY);
		D3DXMatrixIdentity(&World_gr);
		D3DXMatrixMultiply(&World_gr,&World_gr,&Offset);
		
	
			
			g_pd3dDevice->SetTransform(D3DTS_WORLD, &World_gr);
			
			for(UINT i=0; i<obj_NumMat; i++){      // 描画
						    D3DXMATERIAL *mtrl = ( (D3DXMATERIAL*)(obj_pMat->GetBufferPointer()) + i);
							mtrl->MatD3D.Ambient = MAmbient;
							g_pd3dDevice->SetMaterial( &mtrl->MatD3D );
							obj_pMesh->DrawSubset(i);
			};
		}
			// レンダリングステートの再初期化
			g_pd3dDevice->SetRenderState( D3DRS_ALPHABLENDENABLE, FALSE);
			g_pd3dDevice->SetRenderState( D3DRS_SRCBLEND, D3DBLEND_ONE );
			g_pd3dDevice->SetRenderState( D3DRS_DESTBLEND, D3DBLEND_ZERO );


		Draw2Drect(0.0f,0.0f,0.0f,0.0f,RGB(0,0,0));//エラー回避
		g_pd3dDevice->EndScene();
	g_pd3dDevice->Present(NULL,NULL,NULL,NULL);
	return 0;
}

int DxEnd(void)
{
	g_pd3dDevice->Release();
	g_pD3D->Release();
	pVertex->Release();
	obj_pMesh->Release();
	return 0;
}

int Draw2Drect(float left,float top,float right,float bottom,COLORREF color)
{
	CUSTOMVERTEX v[4]=
	{
		{ right , top , 0.0f , 1.0f , color , left , top },
		{ right , bottom , 0.0f , 1.0f , color , left , bottom },
		{ left , top , 0.0f , 1.0f , color , right , top },
		{ left , bottom , 0.0f , 1.0f , color , right , bottom }
	};
	void *pData;

	if(g_pd3dDevice->CreateVertexBuffer(sizeof(CUSTOMVERTEX)*4,
										D3DUSAGE_WRITEONLY,
										FVF_CUSTOM,D3DPOOL_MANAGED,
										&pVertex,NULL)
										!=D3D_OK)
	{
		MessageBox(NULL,_T("内部エラー\n描画に失敗しました"),_T("Error!"),MB_OK);
		g_pd3dDevice->Release();
		g_pD3D->Release();
		return -1;
	}

	if(pVertex->Lock(0,sizeof(CUSTOMVERTEX)*4,(void**)&pData,0)==D3D_OK)
	{
		memcpy(pData,v,sizeof(CUSTOMVERTEX)*4);
		pVertex->Unlock();

	}else{
		MessageBox(NULL,_T("描画失敗"),_T(""),MB_OK);
		g_pd3dDevice->Release();
		g_pD3D->Release();
		return -1;
	}

	g_pd3dDevice->SetStreamSource(0,pVertex,0,sizeof(CUSTOMVERTEX));
	g_pd3dDevice->SetFVF(FVF_CUSTOM);
	g_pd3dDevice->DrawPrimitive(D3DPT_TRIANGLESTRIP,0,2);
	return 0;
}

コード:

/*WndKey.h*/

#ifndef DEF_WNDKEY_H
#define DEF_WNDKEY_H

//キー関数向けの定数(キーコード)
#define	KEY_1 1
#define KEY_2 2
#define KEY_3 3
#define KEY_4 4
#define KEY_5 5
#define KEY_6 6
#define KEY_7 7
#define KEY_8 8
#define KEY_9 9
#define KEY_0 10
#define KEY_A 11
#define KEY_B 12
#define KEY_C 13
#define KEY_D 14
#define KEY_E 15
#define KEY_F 16
#define KEY_G 17
#define KEY_H 18
#define KEY_I 19
#define KEY_J 20
#define KEY_K 21
#define KEY_L 22
#define KEY_M 22
#define KEY_N 23
#define KEY_O 24
#define KEY_P 25
#define KEY_Q 26
#define KEY_R 27
#define KEY_S 28
#define KEY_T 29
#define KEY_U 30
#define KEY_V 31
#define KEY_W 32
#define KEY_X 33
#define KEY_Y 34
#define KEY_Z 35
#define KEY_BACK 36
#define KEY_TAB 37
#define KEY_CLEAR 38
#define KEY_RETURN 39
#define KEY_SHIFT 40
#define KEY_CONTROL 41//CTRLキー
#define KEY_MENU 42
#define KEY_PAUSE 43
#define KEY_CAPITAL 44//CAPSロックキー
#define KEY_ESCAPE 45//ESCキー
#define KEY_SPACE 46
#define KEY_PRIOR 47//PageUpキー
#define KEY_NEXT 48//PageDownキー
#define KEY_END 49
#define KEY_HOME 50
#define KEY_LEFT 51//カーソルキー始
#define KEY_UP 52
#define KEY_RIGHT 53
#define KEY_DOWN 54//カーソルキー終
#define KEY_PRINT 55//PrintScreenキー
#define KEY_INSERT 56
#define KEY_DELETE 57
#define KEY_LWIN 58//左Windowsキー
#define KEY_RWIN 59//右Windowsキー
#define KEY_NUMPAD0 60//テンキー始
#define KEY_NUMPAD1 61
#define KEY_NUMPAD2 62
#define KEY_NUMPAD3 63
#define KEY_NUMPAD4 64
#define KEY_NUMPAD5 65
#define KEY_NUMPAD6 66
#define KEY_NUMPAD7 67
#define KEY_NUMPAD8 68
#define KEY_NUMPAD9 69
#define KEY_MULTIPLY 70//テンキー*
#define KEY_ADD 71//テンキー+
#define KEY_SEPARATOR 72//テンキーEnter
#define KEY_SUBTRACT 73//テンキー-
#define KEY_DECIMAL 74//テンキー.
#define KEY_DEVIDE 75//テンキー/ テンキー終
#define KEY_F1 76
#define KEY_F2 77
#define KEY_F3 78
#define KEY_F4 79
#define KEY_F5 80
#define KEY_F6 81
#define KEY_F7 82
#define KEY_F8 83
#define KEY_F9 84
#define KEY_F10 85
#define KEY_F11 86
#define KEY_F12 87
#define KEY_F13 88
#define KEY_F14 89
#define KEY_F15 90
#define KEY_F16 91
#define KEY_NUMLOCK 92
#define KEY_SCROLL 93//ScrollLockキー


LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp);//ウィンドウプロシージャ
HWND Create(HINSTANCE hInst);	//ウィンドウクラス等作成
HWND ProcessWindow(HINSTANCE hInst);//ウィンドウ作成と表示
int ProcessMessage(void);//メッセージの処理
int GetKey();//押されているキーの取得
float GetMoveX();//マウスカーソルの動きを取得X
float GetMoveY();//マウスカーソルの動きを取得Y
#endif

コード:

/*WndKey.cpp*/

#include <windows.h>
#include <tchar.h>
#include "WndKey.h"

//定数
#define WINDOW_WIDTH (500)
#define WINDOW_HEIGHT  (450)
#define WINDOW_X ((GetSystemMetrics(SM_CXSCREEN)-WINDOW_WIDTH)/2)
#define WINDOW_Y ((GetSystemMetrics(SM_CYSCREEN)-WINDOW_HEIGHT)/2)

//ウィンドウハンドル
static HWND hWnd;
//メッセージ変数
static MSG msg;
//キー情報格納
static int keywp;
//マウスの位置を格納
static POINT CursorPos;
//カーソルの動いた距離を格納
static int mouseposX,mouseposY;
static int addX=0,addY=0;
//ウィンドウプロシージャ
LRESULT CALLBACK WndProc(HWND hWnd, UINT msg, WPARAM wp, LPARAM lp)
{


	switch( msg )
	{
	case WM_MOUSEMOVE:

		GetCursorPos(&CursorPos);

		if (CursorPos.x!=(WINDOW_WIDTH/2)&&CursorPos.y!=(WINDOW_HEIGHT/2))
		{
		mouseposX=(addX*((WINDOW_WIDTH/2)-100))+CursorPos.x-(WINDOW_WIDTH/2);
		mouseposY=(addY*((WINDOW_HEIGHT/2)-100))+CursorPos.y-(WINDOW_HEIGHT/2);
		}
	if	(CursorPos.x>400)
			{
				addX++;
				mouseposX=(addX*((WINDOW_WIDTH/2)-100))+CursorPos.x-(WINDOW_WIDTH/2);
				mouseposY=(addY*((WINDOW_HEIGHT/2)-100))+CursorPos.y-(WINDOW_HEIGHT/2);
				SetCursorPos(WINDOW_WIDTH/2,WINDOW_HEIGHT/2);
			}

	if  (CursorPos.y>350)
			{
				addY++;
				mouseposX=(addX*((WINDOW_WIDTH/2)-100))+CursorPos.x-(WINDOW_WIDTH/2);
				mouseposY=(addY*((WINDOW_HEIGHT/2)-100))+CursorPos.y-(WINDOW_HEIGHT/2);
				SetCursorPos(WINDOW_WIDTH/2,WINDOW_HEIGHT/2);
			}
	if	(CursorPos.x<100)
			{
				addX--;
				mouseposX=(addX*((WINDOW_WIDTH/2)-100))+CursorPos.x-(WINDOW_WIDTH/2);
				mouseposY=(addY*((WINDOW_HEIGHT/2)-100))+CursorPos.y-(WINDOW_HEIGHT/2);
				SetCursorPos(WINDOW_WIDTH/2,WINDOW_HEIGHT/2);
			}
	if  (CursorPos.y<100)
			{
				addY--;
				mouseposX=(addX*((WINDOW_WIDTH/2)-100))+CursorPos.x-(WINDOW_WIDTH/2);
				mouseposY=(addY*((WINDOW_HEIGHT/2)-100))+CursorPos.y-(WINDOW_HEIGHT/2);
				SetCursorPos(WINDOW_WIDTH/2,WINDOW_HEIGHT/2);
			}

		return 0;
	case WM_KEYDOWN:
		keywp=wp;//グローバル変数に押されたキーの情報を渡す
		return 0;

	case WM_DESTROY:  // ウィンドウを破棄するとき
		PostQuitMessage( 0 );
		return 0;
	}
	// 他のメッセージは、デフォルトの処理を行う
	return DefWindowProc( hWnd, msg, wp, lp );
}

HWND Create(HINSTANCE hInst)
{
	WNDCLASSEX wc;
		// ウィンドウクラスの情報を設定
	wc.cbSize = sizeof(wc);               // 構造体サイズ
	wc.style = CS_HREDRAW | CS_VREDRAW;   // スタイル
	wc.lpfnWndProc = WndProc;             // ウィンドウプロシージャ
	wc.cbClsExtra = 0;                    // 拡張情報1
	wc.cbWndExtra = 0;                    // 拡張情報2
	wc.hInstance = hInst;                 // インスタンスハンドル
	wc.hIcon = (HICON)LoadImage(          // アイコン
		NULL, MAKEINTRESOURCE(IDI_APPLICATION), IMAGE_ICON,
		0, 0, LR_DEFAULTSIZE | LR_SHARED
	);
	wc.hIconSm = wc.hIcon;                // 子アイコン
	wc.hCursor = (HCURSOR)LoadImage(      // マウスカーソル
		NULL, MAKEINTRESOURCE(IDC_ARROW), IMAGE_CURSOR,
		0, 0, LR_DEFAULTSIZE | LR_SHARED
	);
	wc.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); // ウィンドウ背景
	wc.lpszMenuName = NULL;                     // メニュー名
	wc.lpszClassName = _T("Default Class Name");// ウィンドウクラス名
	
	// ウィンドウクラスを登録する
	if( RegisterClassEx( &wc ) == 0 ){ return NULL; }

	// ウィンドウを作成する
	return CreateWindow(
		wc.lpszClassName,      // ウィンドウクラス名
		_T("Main Window"),  // タイトルバーに表示する文字列
		WS_OVERLAPPEDWINDOW&~WS_THICKFRAME&~WS_MAXIMIZEBOX,   // ウィンドウの種類
		WINDOW_X,				   // ウィンドウを表示する位置(X座標)
		WINDOW_Y,		           // ウィンドウを表示する位置(Y座標)
		WINDOW_WIDTH,				   // ウィンドウの幅
		WINDOW_HEIGHT,				   // ウィンドウの高さ
		NULL,                  // 親ウィンドウのウィンドウハンドル
		NULL,                  // メニューハンドル
		hInst,                 // インスタンスハンドル
		NULL                   // その他の作成データ
	);
	
}

HWND ProcessWindow(HINSTANCE hInst)//ウィンドウを作成・表示
{
	hWnd = Create(hInst);//ウィンドウの作成
	if( hWnd == NULL )
	{ 
		MessageBox(NULL, _T("Startup Failed."),_T("errid_1"),MB_OK);
		return 0; 
	}

	// ウィンドウを表示する
	ShowWindow( hWnd, SW_SHOW );
	UpdateWindow( hWnd );
	return hWnd;
}

int ProcessMessage(void)
{
		BOOL ret = GetMessage( &msg, NULL, 0, 0 );  // メッセージを取得する
		if( ret == 0 || ret == -1 )
		{
			// アプリケーションを終了させるメッセージが来ていたら、
			// あるいは GetMessage() が失敗したら( -1 が返されたら )、-1を返す
			return -1;
		}
		else
		{
			// メッセージを処理する
			TranslateMessage( &msg );
			DispatchMessage( &msg );
			
		}
	return 0;
}


int GetKey()//グローバル変数に渡されたキーの情報を処理する
{
	
	switch(keywp)//作りかけ・・
	{
		case '0':
			keywp=NULL;
			return KEY_0;
		case '1':
			keywp=NULL;
			return KEY_1;
		case '2':
			keywp=NULL;
			return KEY_2;
		case 'A':
			keywp=NULL;
			return KEY_A; 
		case VK_LEFT:
			keywp=NULL;
			return KEY_LEFT;
		case VK_UP:
			keywp=NULL;
			return KEY_UP;
		case VK_RIGHT:
			keywp=NULL;
			return KEY_RIGHT;
		case VK_DOWN:
			keywp=NULL;
			return KEY_DOWN;
		default:
			break;
	}

	return 0;
}

float GetMoveX()
{

	return (float)mouseposX;
}

float GetMoveY()
{

	return (float)mouseposY;
}
分かりにくいコードで申し訳ない;;

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

Re: DirectXで視点の回転がうまくいかない

#2

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

なにか不思議な事をしているように見えますが、それぞれキーを押した時に何の変数値を変化させて視点を移動させようとしているか説明してもらえますか?
D3DXMatrixLookAtLHでやっていることの意図を特に説明をお願いします。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

あうあう

Re: DirectXで視点の回転がうまくいかない

#3

投稿記事 by あうあう » 12年前

視点の回転はマウスが動いたときにされます。
WかSキーを押したとき、fCamX(カメラのX座標)とfCamZ(カメラのZ座標)を変化させて、前進/後退させようとしている・・・のですが、どうもうまくいかないのです。

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

Re: DirectXで視点の回転がうまくいかない

#4

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

そうですね。
デバッガを使ってみると分かると思うのですがGetMoveX()とGetMoveY()の値は意図通りに変化していますか?
それと、D3DXMatrixLookAtLHで注視点の相対位置を固定してカメラ側を動かしているようですが、これは意図した事でしょうか?
これは注視点を動かしていているの間違いでした。すいません。
ただ、どこを中心に回転しているかがかなり疑問です。

それと移動している間は+(float)cos(3.14159/180*GetMoveX()が2回計算されるのも気になります。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

あうあう

Re: DirectXで視点の回転がうまくいかない

#5

投稿記事 by あうあう » 12年前

自身の座標を中心に回転をしています。
また、2回計算をしないと見ている方向に進まないのでこうしています。

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

Re: DirectXで視点の回転がうまくいかない

#6

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

カメラと注視点をあのような形でうまく回せれば、想定した動きになると思います。一定の区間をグルグル回るだけだと思います。【訂正】少し勘違いしていましたので訂正します。
ただ、それ以前にそれが出来ていないと思います。そういう意味でデバッガで確かめてくださいと書いたのですが。
下にサンプルを書きましたが、rにあたる部分がちゃんと出来ていない思います。

[補足] 少し条件が限定なプログラムなので補足します。下のプログラムは横を見て前進し続けた時の動作を真上から見た時の動きです。
回転.png
回転.png (35.97 KiB) 閲覧数: 4045 回
DXライブラリのサンプルプログラム(exe)です。
DXtest.zip
(945.08 KiB) ダウンロード数: 150 回

コード:

#include "DxLib.h"
#include <math.h>

int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
{
	ChangeWindowMode( TRUE ), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); //ウィンドウモード変更と初期化と裏画面設定

	float baseX=200,baseY=200;
	float x=baseX,y=baseY;
	float r=90;
	float lx,ly;

	// while( 裏画面を表画面に反映, メッセージ処理, 画面クリア )
	while( ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0 )
	{
		x += (float)cos(3.14159/180* r );
		y += (float)sin(3.14159/180* r );
		lx = x + (float)cos(3.14159/180* r );
		ly = y + (float)sin(3.14159/180* r );
		DrawLine( (int)baseX,(int)baseY, (int)lx,(int)ly, GetColor(0,255,255) );
		DrawCircle( (int)lx, (int)ly, 10, GetColor(255,255,255), FALSE );
		r += 1.0;
		//	視線ベクトル
		float vx = lx - x;
		float vy = ly - y;
		vx *= 30;
		vy *= 30;
		DrawLine( (int)x,(int)y, (int)(x+vx),(int)(y+vy), GetColor(255,0,0) );
		
		//	情報の表示
		DrawFormatString( (int)lx + 10,(int)ly - 8, GetColor(255,255,255), "← 注視点" );
		DrawFormatString( (int)x - 8,(int)y - 24, GetColor(255,255,255), "↓ カメラの位置" );
		DrawFormatString( (int)baseX + 10,(int)baseY-8, GetColor(255,255,255), "← スタートのポイント" );
		DrawFormatString( 0, 0, GetColor(255,255,255), "カメラ現在位置(%6.3f,%6.3f)",x,y );
		DrawFormatString( 0, 16, GetColor(255,255,255), "注視点位置(%6.3f,%6.3f)",lx,ly );
		DrawFormatString( 0, 32, GetColor(255,255,255), "赤い線は視線ベクトル" );
		
	}

	DxLib_End(); // DXライブラリ終了処理
	return 0;
}
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

あうあう

Re: DirectXで視点の回転がうまくいかない

#7

投稿記事 by あうあう » 12年前

GetMoveX,GetMoveYはうまく動いてるようなのですが・・
試行錯誤してみたのですがどうしても改善されません。
サンプルのrの部分が問題ということは、GetMoveYがおかしいのだろうとは思いますが、
真下/真上を見れずぐるっとなってしまいます。
そもそもYのところに三角関数を使うことが間違っているのでしょうか?

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

Re: DirectXで視点の回転がうまくいかない

#8

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

私の書いたプログラムではrは前の値に対して加算して累積していくのですが、GetMoveX,GetMoveYの値は累積していく気配がありません。
なので一時的な角度変化から動かないのでは無いでしょうか?
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

閉鎖

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