ページ 11

カメラ関連のコード

Posted: 2011年9月20日(火) 18:46
by Kzone
ネットで公開されているソースコードを見ながらプログラミングの学習をしている者ですが
カメラ関係のソースコードがイマイチ分かりません

以下、ソースコード

コード:


// カメラの情報を格納する構造体
struct CAMERA
{
	VECTOR Position ;  // 座標
	float RotateV;  // 垂直角度
	float RotateH;  // 水平角度
	float RotateT;  // 捻り角度
	float EndRotateV; // 最終角度 - 垂直
	float EndRotateH; // 最終角度 - 水平
	int TurnFlagV;  // 周回フラグ - 垂直
	int TurnFlagH;  // 周回フラグ - 水平
	int FallCameraFlag; // 落下カメラフラグ
} ;



//カメラ
#define CAMERA_X (0.0f)
#define CAMERA_Y (100.0f)
#define CAMERA_Z (0.0f)
#define CAMERA_RADIUS (200.0f)    // 周回の半径
#define CAMERA_TURN_SPEED (18.0f) // 周回の速度
#define CAMERA_DECELERATE (4.0f)  // 周回の減速
#define HALF_PHI_F (1.5707963267948966192313216915f)


// カメラ初期化
void CameraInitialize( void )
{
	Camera.Position.x = Pc.Position.x;
	Camera.Position.y = CAMERA_Y;
	Camera.Position.z = Pc.Position.z;

	Camera.RotateV = 0.0f;
	Camera.RotateH = 0.0f;
	Camera.RotateT = 0.0f;

	Camera.TurnFlagV = 0;
	Camera.TurnFlagH = 0;

	Camera.FallCameraFlag = 0;
}

// カメラ移動
void CameraMove( void )
{
	static float PlusRadius = 0.0f;

	// カメラ右
	if( GameData.NowInput & PAD_INPUT_Z )
	{
		Camera.EndRotateH = Camera.RotateH + (PHI_F / CAMERA_TURN_SPEED);
		Camera.TurnFlagH = 1;
	}
	// カメラ左
	if( GameData.NowInput & PAD_INPUT_X )
	{
		Camera.EndRotateH = Camera.RotateH - (PHI_F / CAMERA_TURN_SPEED);
		Camera.TurnFlagH = 2;
	}
	// カメラ上(落下カメラキャンセル)
	if( GameData.NowInput & PAD_INPUT_Y )
	{
		Camera.EndRotateV = Camera.RotateV + (PHI_F / CAMERA_TURN_SPEED);
		Camera.TurnFlagV = 3;
		Camera.FallCameraFlag = 0;

	}
	// カメラ下
	if( GameData.NowInput & PAD_INPUT_R )
	{
		Camera.EndRotateV = Camera.RotateV - (PHI_F / CAMERA_TURN_SPEED);
		Camera.TurnFlagV = 4;
	}
	// 落下カメラ
	if( Pc.FallFlag == 1 && Camera.FallCameraFlag == 0 )
	{
		Camera.EndRotateV = PHI_F / 3.2f;
		Camera.FallCameraFlag = 1;
	}
	// 落下カメラ終了
	if( Pc.FallFlag == 0 && Camera.FallCameraFlag == 1 )
	{
		Camera.EndRotateV = 0.0f;
		Camera.FallCameraFlag = 0;
		Camera.TurnFlagV = 4;
	}
	// カメラ周回半径初期化
	if(PlusRadius > 0.0f && Camera.FallCameraFlag == 0){
		PlusRadius = 0.0f;
	}

	//カメラ向き調整
	if(Camera.TurnFlagH == 1 && Camera.RotateH < (Camera.EndRotateH + 0.05f)){
		Camera.RotateH += (Camera.EndRotateH - Camera.RotateH) / CAMERA_DECELERATE;
	}
	else if(Camera.TurnFlagH == 2 && Camera.RotateH > (Camera.EndRotateH - 0.05f)){
		Camera.RotateH -= (Camera.RotateH - Camera.EndRotateH) / CAMERA_DECELERATE;
	}
	if(Camera.TurnFlagV == 3 && Camera.RotateV < (Camera.EndRotateV + 0.05f)){
		Camera.RotateV += (Camera.EndRotateV - Camera.RotateV) / CAMERA_DECELERATE;
	}
	else if(Camera.TurnFlagV == 4 && Camera.RotateV > (Camera.EndRotateV - 0.05f)){
		Camera.RotateV -= (Camera.RotateV - Camera.EndRotateV) / CAMERA_DECELERATE;
	}
	if(Camera.FallCameraFlag == 1 && Camera.RotateV < (Camera.EndRotateV + 0.05f)){
		Camera.RotateV += (Camera.EndRotateV - Camera.RotateV) / (CAMERA_DECELERATE * 4.2f);
	}

	// カメラ角度制限
	if(Camera.EndRotateH > PHI_F * 2 && Camera.RotateH > PHI_F * 2){
		Camera.EndRotateH -= PHI_F * 2;
		Camera.RotateH   -= PHI_F * 2;
	}
	else if(Camera.EndRotateH < PHI_F * -2 && Camera.RotateH < PHI_F * -2){
		Camera.EndRotateH += PHI_F * 2;
		Camera.RotateH   += PHI_F * 2;
	}
	if(Camera.EndRotateV < 0.25f && Camera.EndRotateV > -0.25f){
		Camera.EndRotateV = 0.00f;
	}
	else if(Camera.EndRotateV > PHI_F / 4 && Camera.RotateV > PHI_F / 4){
		if(Camera.FallCameraFlag == 0){
			Camera.EndRotateV = Camera.RotateV = PHI_F / 4;
		}else{
			// 落下カメラ 半径拡大
			PlusRadius += 0.5f;
		}
	}
	else if(Camera.EndRotateV < PHI_F / -4 && Camera.RotateV < PHI_F / -4){
		Camera.EndRotateV = Camera.RotateV = PHI_F / -4;
	}

	// カメラ位置調整
	Camera.Position.x = Pc.Position.x - ((CAMERA_RADIUS - PlusRadius) * sin(Camera.RotateV + HALF_PHI_F) * cos(HALF_PHI_F - Camera.RotateH));
	Camera.Position.z = Pc.Position.z - ((CAMERA_RADIUS - PlusRadius) * sin(Camera.RotateV + HALF_PHI_F) * sin(HALF_PHI_F - Camera.RotateH));
	Camera.Position.y = (Pc.Position.y + CAMERA_Y) - ((CAMERA_RADIUS + PlusRadius) * cos(Camera.RotateV + HALF_PHI_F));

	// カメラセット
	SetCameraPositionAndAngle( VGet( Camera.Position.x, Camera.Position.y, Camera.Position.z ),
		Camera.RotateV, Camera.RotateH, Camera.RotateT ) ;
}

カメラの仕様はキーで上下左右移動

キャラクターが高所から落下するとカメラがキャラの頭上に移動し
キャラを上から見下ろす形になります

どなたか詳しいソースコードの解説をお願いします

Re: カメラ関連のコード

Posted: 2011年9月24日(土) 11:39
by 史上最悪のデスペナ
詳しい解説とのことですが、そもそもソースの文の直訳(?)が出来ないということでしょうか?
それとも直訳は出来たけど何故こんなことするのかがわからないということでしょうか?

とりあえず日本語っぽく訳してみました
CameraInitialize関数→
    カメラの視点を(キャラのx座標, 100.0f, キャラのz座標)にセット
    カメラの垂直回転角度、水平回転角度、捻り回転角度を0にする
    キャラを中心に垂直方向・水平方向に回転してるかどうかのフラグを0にする(0=してない)
    落下カメラかどうかのフラグを0にする(0=違う)

CameraMove関数→
    カメラ右回転→
        もし、GameData.NowInput かつ PAD_INPUT_Zなら
            (EndRotateH)を(現在の水平角度)に(π/周回速度)を足した値にする
            カメラ水平回転フラグを1にセット
    カメラ左回転→
        もし、GameData.NowInput かつ PAD_INPUT_Xなら
            (EndRotateH)を(現在の水平角度)から(π/周回速度)を引いた値にする
            カメラ水平回転フラグを2にセット
    カメラ上回転→
        もし、GameData.NowInput かつ PAD_INPUT_Yなら
            (EndRotateV)を(現在の垂直角度)に(π/周回速度)を足した値にする
            カメラ垂直回転フラグを3にセット
            カメラ落下フラグを0にセット
    カメラ下回転→
        もし、GameData.NowInput かつ PAD_INPUT_Rなら
            (EndRotateV)を(現在の垂直角度)から(π/周回速度)引いた値にする
            カメラ垂直回転フラグを4にセット
    落下カメラ→
        もし、キャラが落ちてて、落下カメラフラグが0なら
            EndRotateVをπ/3.2fという値にする
            落下カメラフラグを1にセット
    落下カメラ終了→
        もし、キャラが落ちてなくて、落下カメラフラグが1なら
            EndRotateVを0.0fという値にする
            落下カメラフラグを0にセット
            カメラ垂直回転フラグを4にセット
    カメラ周回半径初期化→
        もし、PlusRadius>0かつ落下カメラフラグが0なら
            PlusRadiusを0.0fという値にする
    カメラ向き調整→
        もし、カメラ水平回転フラグが1で、カメラの現在水平角度が水平角度+0.05fより小さかったら
            カメラの現在水平角度に(Camera.EndRotateH - Camera.RotateH) / CAMERA_DECELERATEを足す

・・・・・・・・・・・・・・・・・・・・長すぎて疲れた・・・・・・・以下略
途中で放棄してすみません・・・・・・・・・・
プログラム見て二つほど。EndRotateVやEndRotateHは使わなくても別の方法でやれる(と思います)。
それと、TurnFlagVとTurnFlagHは一つにまとめてTurnFlagで十分です。