示例#1
0
//3次元回転描画
void DrawImpl::rot3D(const Vector2& pos, const Vector2& exRate, float zRot, float xRot, float yRot, int gHandle, int turnFlag){
	MATRIX m;
	int w, h;
	GetGraphSize(gHandle, &w, &h);
	w = (int)(w*exRate.x);
	h = (int)(h*exRate.y);
	if (turnFlag == TRUE)
		w *= -1;
	VECTOR v[4] = { VGet(-(float)w / 2, -(float)h / 2, 0), VGet((float)w / 2, -(float)h / 2, 0)
		, VGet(-(float)w / 2, (float)h / 2, 0), VGet((float)w / 2, (float)h / 2, 0) };

	m = MGetRotZ(zRot);
	for (int i = 0; i < 4; i++)
		v[i] = VTransform(v[i], m);
	if (xRot != 0.0f)
	{
		m = MGetRotX(xRot);
		for (int i = 0; i < 4; i++)
			v[i] = VTransform(v[i], m);
	}
	if (yRot != 0.0f)
	{
		m = MGetRotY(yRot);
		for (int i = 0; i < 4; i++)
			v[i] = VTransform(v[i], m);
	}

	DrawModiGraphF(pos.x + v[0].x, pos.y + v[0].y, pos.x + v[1].x, pos.y + v[1].y, pos.x + v[3].x, pos.y + v[3].y, pos.x + v[2].x, pos.y + v[2].y, gHandle, TRUE);
}
示例#2
0
void MODEL :: display(){
	/*DrawCapsule3D(	VGet(x+600*sinf(rotateY), y+y0+200.0f-500*sinf(rotateX), z+600*cosf(rotateY)),
					VGet(x-200*sinf(rotateY), y+y0+200.0f+500*sinf(rotateX), z-200*cosf(rotateY)),
					210.0f, 2, GetColor(255,255,255), GetColor(255,255,255), FALSE);*/
	playTime += 200.0f;
	if(playTime >= animTime)
		playTime = 0.0f;
	mS->move();
	mS->display();
	MV1RefreshCollInfo(ModelHandle, 39);
	MATRIX rot = MMult(MMult(MGetRotX(rotateX), MGetRotZ(rotateZ)),MGetRotY(rotateY));
	MATRIX trans = MGetTranslate(VGet(x+x0, y+y0, z+z0));
	MV1SetMatrix(ModelHandle, MMult(rot, trans));
	MV1SetAttachAnimTime(ModelHandle, attachIndex, playTime);
	MV1DrawModel(ModelHandle);
}
// カメラの処理
void Camera_Process( void )
{
	// パッドの3ボタンか、シフトキーが押されている場合のみ角度変更操作を行う
	if( CheckHitKey( KEY_INPUT_LSHIFT ) || ( inp.NowInput & PAD_INPUT_C ) )
	{
		// 「←」ボタンが押されていたら水平角度をマイナスする
		if( inp.NowInput & PAD_INPUT_LEFT )
		{
			cam.AngleH -= CAMERA_ANGLE_SPEED ;

			// −180度以下になったら角度値が大きくなりすぎないように360度を足す
			if( cam.AngleH < -DX_PI_F )
			{
				cam.AngleH += DX_TWO_PI_F ;
			}
		}

		// 「→」ボタンが押されていたら水平角度をプラスする
		if( inp.NowInput & PAD_INPUT_RIGHT )
		{
			cam.AngleH += CAMERA_ANGLE_SPEED ;

			// 180度以上になったら角度値が大きくなりすぎないように360度を引く
			if( cam.AngleH > DX_PI_F )
			{
				cam.AngleH -= DX_TWO_PI_F ;
			}
		}

		// 「↑」ボタンが押されていたら垂直角度をマイナスする
		if( inp.NowInput & PAD_INPUT_UP )
		{
			cam.AngleV -= CAMERA_ANGLE_SPEED ;

			// ある一定角度以下にはならないようにする
			if( cam.AngleV < -DX_PI_F / 2.0f + 0.6f )
			{
				cam.AngleV = -DX_PI_F / 2.0f + 0.6f ;
			}
		}

		// 「↓」ボタンが押されていたら垂直角度をプラスする
		if( inp.NowInput & PAD_INPUT_DOWN )
		{
			cam.AngleV += CAMERA_ANGLE_SPEED ;

			// ある一定角度以上にはならないようにする
			if( cam.AngleV > DX_PI_F / 2.0f - 0.6f )
			{
				cam.AngleV = DX_PI_F / 2.0f - 0.6f ;
			}
		}
	}

	// カメラの注視点はプレイヤー座標から規定値分高い座標
	cam.Target = VAdd( pl.CharaInfo.Position, VGet( 0.0f, CAMERA_PLAYER_TARGET_HEIGHT, 0.0f ) ) ;

	// カメラの座標を決定する
	{
		MATRIX RotZ, RotY ;
		float Camera_Player_Length ;
		MV1_COLL_RESULT_POLY_DIM HRes ;
		int HitNum ;

		// 水平方向の回転はY軸回転
		RotY = MGetRotY( cam.AngleH ) ;

		// 垂直方向の回転はZ軸回転 )
		RotZ = MGetRotZ( cam.AngleV ) ;

		// カメラからプレイヤーまでの初期距離をセット
		Camera_Player_Length = CAMERA_PLAYER_LENGTH ;

		// カメラの座標を算出
		// X軸にカメラとプレイヤーとの距離分だけ伸びたベクトルを
		// 垂直方向回転( Z軸回転 )させたあと水平方向回転( Y軸回転 )して更に
		// 注視点の座標を足したものがカメラの座標
		cam.Eye = VAdd( VTransform( VTransform( VGet( -Camera_Player_Length, 0.0f, 0.0f ), RotZ ), RotY ), cam.Target ) ;

		// 注視点からカメラの座標までの間にステージのポリゴンがあるか調べる
		HRes = MV1CollCheck_Capsule( stg.ModelHandle, -1, cam.Target, cam.Eye, CAMERA_COLLISION_SIZE );
		HitNum = HRes.HitNum ;
		MV1CollResultPolyDimTerminate( HRes ) ;
		if( HitNum != 0 )
		{
			float NotHitLength ;
			float HitLength ;
			float TestLength ;
			VECTOR TestPosition ;

			// あったら無い位置までプレイヤーに近づく

			// ポリゴンに当たらない距離をセット
			NotHitLength = 0.0f ;

			// ポリゴンに当たる距離をセット
			HitLength = Camera_Player_Length ;
			do
			{
				// 当たるかどうかテストする距離をセット( 当たらない距離と当たる距離の中間 )
				TestLength = NotHitLength + ( HitLength - NotHitLength ) / 2.0f ;

				// テスト用のカメラ座標を算出
				TestPosition = VAdd( VTransform( VTransform( VGet( -TestLength, 0.0f, 0.0f ), RotZ ), RotY ), cam.Target ) ;

				// 新しい座標で壁に当たるかテスト
				HRes = MV1CollCheck_Capsule( stg.ModelHandle, -1, cam.Target, TestPosition, CAMERA_COLLISION_SIZE );
				HitNum = HRes.HitNum ;
				MV1CollResultPolyDimTerminate( HRes ) ;
				if( HitNum != 0 )
				{
					// 当たったら当たる距離を TestLength に変更する
					HitLength = TestLength ;
				}
				else
				{
					// 当たらなかったら当たらない距離を TestLength に変更する
					NotHitLength = TestLength ;
				}

				// HitLength と NoHitLength が十分に近づいていなかったらループ
			}while( HitLength - NotHitLength > 0.1f ) ;

			// カメラの座標をセット
			cam.Eye = TestPosition ;
		}
	}
}
void CameraWorkManager::Update_RotateCamOnGazePoint( double timeslice )
{
	static const double DrugMoveScale=0.005; // ドラッグ量に対する視点の移動量のパラメータ

	static Vector2D ScreenDrugStartPoint;  // マウスでドラッグを開始したスクリーン上の座標を格納
	static Vector2D SavedCamDist;          // マウスでドラッグを開始したときの、m_dTilt、m_dHead を保持
	static bool     nowDruging=false;      // 今ドラッグ中か?

	// キー入力から、m_dTilt と m_dHead を更新
	//getKeyInput();

	// スクロール操作から、カメラと注視点の距離を更新
	getMouseWheelInput(timeslice);

	// マウスによるドラッグ操作により、m_dTilt と m_dHead を更新
	if( nowDruging )
	{ // 今ドラッグ中
		// ドラッグ終了したかを判定
		if( ( GetMouseInput() & MOUSE_INPUT_LEFT ) == 0 )
		{ // ドラッグ終了
			nowDruging = false; 
		}
		else
		{
			// 今のマウス位置を取得
			Point2D pos;
			GetMousePoint( &(pos.x) , &(pos.y) );
			Vector2D CurMousePos( (double)pos.x, (double)pos.y);
			
			// m_dTilt と m_dHead を更新
			Vector2D NewCamDist = -DrugMoveScale*(CurMousePos-ScreenDrugStartPoint)+SavedCamDist;
			m_dTilt = NewCamDist.y;
			m_dHead = NewCamDist.x;

		}
	}
	else
	{ // ドラッグ中でない
		// ドラッグ開始したかを判定
		int button;
		Point2D pos;
		if( GetMouseInputLog( &button, &pos.x, &pos.y, TRUE )==0
			&& ( button & MOUSE_INPUT_LEFT ) != 0 )
		{ // ドラッグが開始された
			// ドラッグ開始時の マウス座標を ScreenDrugStartPoint に保持
			ScreenDrugStartPoint = pos.toRealVector();

			// ドラッグ開始時の m_dTilt、m_dHead の値を SavedCamDist に保持
			SavedCamDist.y = m_dTilt;
			SavedCamDist.x = m_dHead;

			// ドラッグフラグを立てる
			nowDruging = true;
		}
	}
	

	// m_dHead と m_dTilt から、(GazingPointを原点とした)カメラの位置を計算する
	Vector3D Hedding3D( 1.0, 0, 0 );
	Hedding3D = VTransform( Hedding3D.toVECTOR(), MGetRotZ( (float)m_dTilt ) ); // もしかしたら、マイナスにしないと駄目かも
	Hedding3D = VTransform( Hedding3D.toVECTOR(), MGetRotY( -1*(float)m_dHead ) );
	Vector3D toCamPos3D = m_dCamDistFrmFP * Hedding3D ;

	// ### ビュー行列を生成を確認

	// カメラの座標変換行列のz軸向き(=カメラの向き)
	Vector3D vViewBaseZ = -1 * Hedding3D; 

	// カメラの座標変換行列のy軸向きを仮置き
	Vector3D vViewBaseY( 0.0, 1.0, 0.0 );

	// カメラの座標変換行列のx軸向き(= y × z )
	Vector3D vViewBaseX = VCross( vViewBaseY.toVECTOR(), vViewBaseZ.toVECTOR() );
	vViewBaseX = vViewBaseX.normalize();

	// カメラの座標変換行列のy軸向きを再調整
	vViewBaseY = VCross( vViewBaseZ.toVECTOR(), vViewBaseX.toVECTOR() );

	// 基底を組み合わせてカメラ座標変換行列(Entityローカル座標)を生成
	MATRIX MCamTransMatLocal = 
		MGetAxis1(
		//MakeMatrixFromBaseVec( 
			vViewBaseX.toVECTOR(),
			vViewBaseY.toVECTOR(),
			vViewBaseZ.toVECTOR(),
			toCamPos3D.toVECTOR() );
	MCamTransMatLocal.m[3][1] += m_TrgtHight;

	// Entity位置だけシフトしたものがワールド座標でのカメラ座標変換行列
	MATRIX MCamTransMatWorld = MCamTransMatLocal;
	MCamTransMatWorld.m[3][0] += m_TargetPos.x;
	//MCamTransMatWorld.m[3][1] += m_TrgtHight; <- MCamTransMatLocal の段階でシフト
	MCamTransMatWorld.m[3][2] += m_TargetPos.z;

	// 逆行列がビュー行列
	m_MViewLocal = MInverse( MCamTransMatLocal );
	m_MViewWorld = MInverse( MCamTransMatWorld );
	
	// 背景パノラマ球の描画に使用しているため m_vFinalCamPos を参照している
	m_vFinalCamPos = VTransform( Vector3D( 0,0,0 ).toVECTOR(), MCamTransMatWorld );
};