3Dプログラミング基本 1-5

キャラクターの向いている方向への移動(これ以降ラジコン移動と呼ぶ)

1-5-1.今までの移動処理

ラジコン移動では、今までと違った考え方が求められるので、

まずは今までの移動について復習してみよう。


今までの移動は画面のグローバル軸を用いた移動を行っていた。

DirectXでは画面に対して、横軸をX、縦軸をY、奥行きをZとしている。

(※1-1-2 下部の「■基礎知識」を参照)


例えば、右に移動したければ座標Xを示す変数に値を加算すれば良いし、

奥に行きたければ座標Zを示す変数に値を加算すれば良い。


↓確認

//  キーボード入力							
if(DXUTIsKeyDown(VK_UP))    //  上キー入力		
{							
	g_pos.z += 0.2f;        //  Z方向に0.2f分加算		
}							
if(DXUTIsKeyDown(VK_DOWN))  //  下キー入力		
{							
	g_pos.z -= 0.2f;        //  Z方向に0.2f分減算		
}							
if(DXUTIsKeyDown(VK_RIGHT)) //  右キー入力		
{							
	g_pos.x += 0.2f;        //  X方向に0.2f分加算		
}							
if(DXUTIsKeyDown(VK_LEFT))  //  左キー入力		
{							
	g_pos.x -= 0.2f;        //  X方向に0.2f分減算		
}							
        

▲TOP

1-5-2.ラジコン移動

次にラジコン移動について確認してみよう。

考え方としては、


①移動開始点の決定

②キャラクターの向き(回転)情報の変更

③キャラクターの向いている方向への移動

④移動後の座標取得


以上の4つ処理が出来れば完成である。

下図で例を挙げて確認してみよう。


D3DXMATRIX t_matrix,s_matrix;                           //  作業用行列変数															
D3DXMatrixTranslation( &s_matrix , 0 , 0 , 0.0f );      //  移動マトリクスの初期化					
												
//  キーボード入力												
if(DXUTIsKeyDown(VK_UP))    //  上キー入力							
{												
	D3DXMatrixTranslation( &s_matrix , 0 , 0 , 0.2f );  //  移動マトリクスの作成		
}												
if(DXUTIsKeyDown(VK_DOWN))  //  下キー入力							
{												
	D3DXMatrixTranslation( &s_matrix , 0 , 0 , -0.2f ); //  移動マトリクスの作成		
}												
if(DXUTIsKeyDown(VK_RIGHT)) //  右キー入力							
{												
	g_rot.y += 0.2f;        //  Y軸方向に0.2f分加算回転						
}												
if(DXUTIsKeyDown(VK_LEFT))  //  左キー入力							
{												
	g_rot.y -= 0.2f;        //  Y軸方向に0.2f分減算回転						
}
        
//  モデルを表示するためのマトリクス作成											
D3DXMatrixTranslation(&g_matrix , g_pos.x , g_pos.y ,g_pos.z);              //  移動マトリクスの作成		
D3DXMatrixRotationYawPitchRoll(&t_matrix , g_rot.y , g_rot.x , g_rot.z);    //  回転マトリクスの作成
	
//  ここで移動マトリクスと回転マトリクス、移動開始点マトリクスを合成する ※順番に注意										
g_matrix = s_matrix * t_matrix * g_matrix;																								
D3DXMatrixScaling(&t_matrix , g_scal.x , g_scal.y ,g_scal.z);               //  拡大縮小マトリクスの作成	

//  ここで移動&拡大縮小マトリクスと回転マトリクスを合成する										
g_matrix = t_matrix * g_matrix;												
												
//  座標の更新												
g_pos.x = g_matrix._41;												
g_pos.y = g_matrix._42;												
g_pos.z = g_matrix._43;	
        
  

▲TOP

1-5-3.プログラミング

※追加箇所はマーカーで表記

※変更箇所は下部にて別途補足説明をする

//--------------------------------------------------------------------------------------													
// File: EmptyProject.cpp													
//													
// Empty starting point for new Direct3D applications													
//													
// Copyright (c) Microsoft Corporation. All rights reserved.													
//--------------------------------------------------------------------------------------													
#include "dxstdafx.h"													
#include "resource.h"												
													
//  フォント変数												
LPD3DXFONT pFont;													
																										
//  変数宣言													
CDXUTMesh       *g_mesh;                        //  モデルを扱うポインタ変数						
D3DXVECTOR3     g_pos = D3DXVECTOR3(0,0,0);     //  座標						
D3DXVECTOR3     g_rot = D3DXVECTOR3(0,0,0);     //  回転						
D3DXVECTOR3     g_scal = D3DXVECTOR3(1,1,1);    //  拡大縮小						
D3DXMATRIX      g_matrix;                       //  上記の3変数をまとめて管理する行列変数						
													
#define CHILD_DISTANCE 4.0f                     //  モデル間の距離。今回は定数を使用						
CDXUTMesh       *h_mesh;			//  モデルを扱うポインタ変数						
D3DXMATRIX      h_matrix;                       //  別モデルのマトリクス						
D3DXVECTOR3     h_rot = D3DXVECTOR3(0,0,0);     //  回転						
//--------------------------------------------------------------------------------------													
// Rejects any devices that aren't acceptable by returning false													
//--------------------------------------------------------------------------------------													
bool CALLBACK IsDeviceAcceptable( D3DCAPS9* pCaps, D3DFORMAT AdapterFormat, 													
                                  D3DFORMAT BackBufferFormat, bool bWindowed, void* pUserContext )													
{													
    //  Typically want to skip backbuffer formats that don't support alpha blending													
    IDirect3D9* pD3D = DXUTGetD3DObject(); 													
    if( FAILED( pD3D->CheckDeviceFormat( pCaps->AdapterOrdinal, pCaps->DeviceType,													
                    AdapterFormat, D3DUSAGE_QUERY_POSTPIXELSHADER_BLENDING, 													
                    D3DRTYPE_TEXTURE, BackBufferFormat ) ) )													
        return false;													
													
    return true;													
}													
													
//--------------------------------------------------------------------------------------													
// Before a device is created, modify the device settings as needed													
//--------------------------------------------------------------------------------------													
bool CALLBACK ModifyDeviceSettings( DXUTDeviceSettings* pDeviceSettings, const D3DCAPS9* pCaps, void* pUserContext )													
{													
    return true;													
}													
													
//--------------------------------------------------------------------------------------													
// Create any D3DPOOL_MANAGED resources here 													
//--------------------------------------------------------------------------------------													
HRESULT CALLBACK OnCreateDevice( IDirect3DDevice9* pd3dDevice, const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )													
{													
    return S_OK;													
}													
													
//--------------------------------------------------------------------------------------													
// Create any D3DPOOL_DEFAULT resources here 													
//--------------------------------------------------------------------------------------													
HRESULT CALLBACK OnResetDevice( IDirect3DDevice9* pd3dDevice, 													
                                const D3DSURFACE_DESC* pBackBufferSurfaceDesc, void* pUserContext )													
{													
    return S_OK;													
}													
													
//--------------------------------------------------------------------------------------													
// Handle updates to the scene													
//--------------------------------------------------------------------------------------													
void CALLBACK OnFrameMove( IDirect3DDevice9* pd3dDevice, double fTime, float fElapsedTime, void* pUserContext )													
{													
	D3DXMATRIX t_matrix,s_matrix;                         //  作業用行列変数																			
	D3DXMatrixTranslation( &s_matrix , 0 , 0 , 0.0f );    //  移動マトリクスの初期化					
													
	//  キーボード入力												
	if(DXUTIsKeyDown(VK_UP))                              //  上キー入力							
	{												
		D3DXMatrixTranslation( &s_matrix , 0 , 0 , 0.2f );  //  移動マトリクスの作成			
	}												
	if(DXUTIsKeyDown(VK_DOWN))                            //  下キー入力							
	{												
		D3DXMatrixTranslation( &s_matrix , 0 , 0 , -0.2f ); //  移動マトリクスの作成			
	}												
	if(DXUTIsKeyDown(VK_RIGHT))                           //  右キー入力							
	{												
		g_rot.y += 0.2f;                                    //  Y軸方向に0.2f分加算回転						
	}												
	if(DXUTIsKeyDown(VK_LEFT))                            //  左キー入力							
	{												
		g_rot.y -= 0.2f;                                    //  Y軸方向に0.2f分減算回転						
	}												
													
	if(DXUTIsKeyDown(VK_SHIFT))                           //  SHIFTキー入力							
	{												
		//  ピッチ(X軸回転)											
		if(DXUTIsKeyDown('Q'))      //  Qキー入力						
		{											
			g_rot.x += 0.2f;          //  X軸方向に0.2f分加算回転					
		}											
		if(DXUTIsKeyDown('W'))      //  Wキー入力						
		{											
			g_rot.x -= 0.2f           //  X軸方向に0.2f分減算回転					
		}											
		//  ヨー(Y軸回転)											
		if(DXUTIsKeyDown('A'))      //  Aキー入力						
		{											
			g_rot.y += 0.2f;          //  Y軸方向に0.2f分加算回転					
		}											
		if(DXUTIsKeyDown('S')       //  Sキー入力						
		{											
			g_rot.y -= 0.2f;          //  Y軸方向に0.2f分減算回転					
		}											
		//  ロール(Z軸回転)											
		if(DXUTIsKeyDown('Z'))      //  Zキー入力						
		{											
			g_rot.z += 0.2f;          //  Z軸方向に0.2f分加算回転					
		}											
		if(DXUTIsKeyDown('X'))      //  Xキー入力						
		{											
			g_rot.z -= 0.2f;          //  Z軸方向に0.2f分減算回転					
		}											
	}												
	else												
	{												
		//  X軸拡縮											
		if(DXUTIsKeyDown('Q'))      //  Qキー入力						
		{											
			g_scal.x += 0.2f;         //  X方向に0.2f分拡大					
		}											
		if(DXUTIsKeyDown('W'))      //  Wキー入力						
		{											
			g_scal.x -= 0.2f;         //  X方向に0.2f分縮小					
		}											
		//  Y軸拡縮											
		if(DXUTIsKeyDown('A'))      //  Aキー入力						
		{											
			g_scal.y += 0.2f;         //  Y方向に0.2f分拡大					
		}											
		if(DXUTIsKeyDown('S'))      //  Sキー入力						
		{											
			g_scal.y -= 0.2f;         //  Y方向に0.2f分縮小					
		}											
		//  Z軸拡縮											
		if(DXUTIsKeyDown('Z'))      //  Zキー入力						
		{											
			g_scal.z += 0.2f;         //  Z方向に0.2f分拡大					
		}											
		if(DXUTIsKeyDown('X'))      //  Xキー入力						
		{											
			g_scal.z -= 0.2f;         //  Z方向に0.2f分縮小					
		}											
	}												
													
	//  別モデルの回転量を加算												
	h_rot.y += 0.02f;												
													
	//  モデルを表示するためのマトリクス作成											
	D3DXMatrixTranslation(&g_matrix , g_pos.x , g_pos.y ,g_pos.z);              //  移動マトリクスの作成			
	D3DXMatrixRotationYawPitchRoll(&t_matrix , g_rot.y , g_rot.x , g_rot.z);    //  回転マトリクスの作成
		
	//  ここで移動マトリクス、回転マトリクス、移動開始点マトリクスを合成する ※順番に注意											
	g_matrix = s_matrix * t_matrix * g_matrix;												
													
	D3DXMatrixScaling(&t_matrix , g_scal.x , g_scal.y ,g_scal.z);               //  拡大縮小マトリクスの作成	
		
	//  ここで移動&拡大縮小マトリクスと回転マトリクスを合成する											
	g_matrix = t_matrix * g_matrix;												
													
	//  座標の更新												
	g_pos.x = g_matrix._41;												
	g_pos.y = g_matrix._42;												
	g_pos.z = g_matrix._43;												
													
	//  別モデルのマトリクス作成												
	D3DXMatrixTranslation( &h_matrix , CHILD_DISTANCE , 0 ,0 );                 //  別モデルの移動マトリクスの作成				
	D3DXMatrixRotationY(&t_matrix,h_rot.y);                                     //  別モデルの回転マトリクスの作成
												
	//  ここで移動マトリクスと回転マトリクスを合成する											
	//  合成の手順のイメージとしては「移動してから回転」するのか「回転してから移動」するのかでよく考えること											
													
	h_matrix = h_matrix * t_matrix * g_matrix;												
	//  h_matrix = t_matrix * h_matrix * g_matrix;													
}
        

↓以降の処理は前回1-4の「 Render the scene 」と同じ。


※補足説明※

●71行めの[ D3DXMATRIX t_matrix,s_matrix; // 作業用行列変数 ]

●77行めの[ D3DXMatrixTranslation( &s_matrix , 0 , 0 , 0.2f ); // 移動マトリクスの作成 ]

●81行めの[ D3DXMatrixTranslation( &s_matrix , 0 , 0 , -0.2f ); // 移動マトリクスの作成 ]

●85行めの[ g_rot.y += 0.2f; // Y軸方向に0.2f分加算回転 ]

●89行めの[ g_rot.y -= 0.2f; // Y軸方向に0.2f分減算回転 ]


および、


●158行めの[ D3DXMatrixRotationYawPitchRoll(&t_matrix , g_rot.y , g_rot.x , g_rot.z); // 回転マトリクスの作成 ]

●161行めの[ g_matrix = s_matrix * t_matrix * g_matrix; (※移動&拡大縮小&回転マトリクスの合成) ]

●163行めの[ D3DXMatrixScaling(&t_matrix , g_scal.x , g_scal.y ,g_scal.z); // 拡大縮小マトリクスの作成 ]

●166行めの[ g_matrix = t_matrix * g_matrix; (※移動&拡大縮小&回転マトリクスの合成) ]


は処理を変更した箇所である。

1-1-5.動作確認

左右キーで回転、上下キー前後に移動すれば完了です。


1-1-5 動作確認

↓参考動画


▲TOP