#include "Mix/Tool/Win32/Core/Graphics/Camera.h"
#include "Mix/Tool/Win32/Core/Graphics/Manager.h"
#include "Mix/Tool/Win32/Core/Graphics/Scene.h"
#include "Mix/Tool/Win32/Core/Graphics/DrawObject.h"
#include "Mix/Tool/Win32/Core/Graphics/TargetTexture.h"
#include "Mix/Tool/Win32/Core/Graphics/SwapChain.h"

namespace Mix{ namespace Tool{ namespace Win32{ namespace Graphics{

const float Camera::DEF_DISTANCE = 10.0f;
const float Camera::DEF_ROTATION_H = 20.0f;
const float Camera::DEF_ROTATION_V = 30.0f;

Camera::Camera( void ) :
m_pSelectMapTex( NULL ),
m_pSwapChain( NULL ),
m_DefDistance( DEF_DISTANCE ),
m_Distance( DEF_DISTANCE ),
m_Position( 0.0f, 0.0f, 0.0f ),
m_Target( 0.0f, 0.0f, 0.0f ),
m_FillMode( D3DFILL_SOLID ),
m_bInvisibleSelection( false ),
m_DrawFlags( Camera::DRAW_DEF )
{
/*	m_DrawObjectScaling = D3DXVECTOR3( 1.0f, 1.0f, 1.0f );
	m_DrawObjectScalingBasePos = D3DXVECTOR2( 0.0f, 0.0f );
	m_InvDrawObjectScalingLength = 0.0f;
*/
	ResetRotation();
}

Camera::~Camera( void )
{
	Mix::Tool::Win32::Graphics::Scene* pScene = GetScenePtr();

	if( pScene != NULL )
	{
		pScene->RemoveCamera( this );
	}

	MIX_RELEASE( m_pSelectMapTex );
	MIX_RELEASE( m_pSwapChain );
}

bool Camera::Initialize( HWND hWnd )
{
	Mix::Tool::Win32::Graphics::Manager* pManager = Manager::GetInstance();
	if( pManager == NULL )
	{
		return false;
	}

	m_pSelectMapTex = pManager->CreateLockableTargetTexture();
	if( m_pSelectMapTex == NULL )
	{
		return false;
	}

	m_pSwapChain = pManager->CreateSwapChain( hWnd );
	if( m_pSwapChain == NULL )
	{
		return false;
	}

	return true;
}

void Camera::SetParam( const D3DXVECTOR3& localPos, const D3DXVECTOR3& target, const D3DXQUATERNION& pose )
{
	m_Distance = ::D3DXVec3Length( &localPos );
	m_LocalPosition = localPos;
	m_Target = target;
	m_PoseQuat = pose;

	::D3DXMatrixIdentity( &m_PoseMatrix );
	::D3DXMatrixRotationQuaternion( &m_PoseMatrix, &m_PoseQuat );
}

void Camera::SetDefDistance( float d )
{
	m_DefDistance = d;
	m_Distance = d;

	DistationLocalPosition();
}

float Camera::GetDefDistance( void ) const
{
	return m_DefDistance;
}

void Camera::SetDistance( float d )
{
	m_Distance = ( m_Distance > FLT_EPSILON )? d : 0.0f;

	DistationLocalPosition();
}

float Camera::GetDistance( void ) const
{
	return m_Distance;
}

void Camera::SetPose( const D3DXQUATERNION& quat )
{
	m_PoseQuat = quat;

	::D3DXMatrixIdentity( &m_PoseMatrix );
	::D3DXMatrixRotationQuaternion( &m_PoseMatrix, &m_PoseQuat );
}


const D3DXQUATERNION& Camera::GetPose( void ) const
{
	return m_PoseQuat;
}

void Camera::SetTarget( const D3DXVECTOR3& target )
{
	m_Target = target;
}

const D3DXVECTOR3& Camera::GetTarget( void ) const
{
	return m_Target;
}

void Camera::ResetDistation( void )
{
	SetDistance( m_DefDistance );
}

void Camera::Distation( int d )
{
	Mix::Tool::Win32::Graphics::Manager* pManager = Manager::GetInstance();
	if( pManager == NULL )
	{
		return;
	}

	float nextDistance = m_Distance + pManager->GetDistation( d );

	if( nextDistance > FLT_EPSILON )
	{
		m_Distance = nextDistance;
	}

	DistationLocalPosition();
}

void Camera::ResetRotation( void )
{
	m_LocalPosition = D3DXVECTOR3( 0.0f, 0.0f, m_Distance );
	::D3DXMatrixIdentity( &m_PoseMatrix );

	RotationDirect( D3DXVECTOR3( 0.0f, 3.14159f, 0.0f ) );
}

void Camera::Rotation( int h, int v )
{
	Mix::Tool::Win32::Graphics::Manager* pManager = Manager::GetInstance();
	if( pManager == NULL )
	{
		return;
	}

	D3DXVECTOR3 rot = pManager->GetRotation( -h, v );

	//ラジアン単位へ変換
	rot.x = D3DXToRadian( rot.x );
	rot.y = D3DXToRadian( rot.y );
	rot.z = D3DXToRadian( rot.z );

	RotationDirect( rot );
}

void Camera::ResetTranslation( void )
{
	//注視点を原点に設定
	m_Target = D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
}

void Camera::Translation( int h, int v )
{
	Mix::Tool::Win32::Graphics::Manager* pManager = Manager::GetInstance();
	if( pManager == NULL )
	{
		return;
	}

	D3DXVECTOR3 diff = pManager->GetTranslation( -h, v );

	//現在の姿勢での移動を求める
	::D3DXVec3TransformCoord( &diff, &diff, &m_PoseMatrix );

	//注視点を移動
	m_Target += diff;
}

void Camera::SetFillMode( D3DFILLMODE fill )
{
	m_FillMode = fill;
}

D3DFILLMODE Camera::GetFillMode( void ) const
{
	return m_FillMode;
}

void Camera::SetInvisibleSelection( bool state )
{
	m_bInvisibleSelection = state;
}

bool Camera::GetInvisibleSelection( void ) const
{
	return m_bInvisibleSelection;
}

void Camera::SetDrawFlags( unsigned int flags )
{
	m_DrawFlags = flags;
}

unsigned int Camera::GetDrawFlags( void ) const
{
	return m_DrawFlags;
}

void Camera::RotationLight( int h, int v )
{
	Mix::Tool::Win32::Graphics::Scene* pScene = GetScenePtr();

	if( pScene != NULL )
	{
		pScene->SetLightPoseMatrix( RotationMatrix( pScene->GetLightPoseMatrix(), -v, -h ) );
	}
}
/*
bool Camera::SetupScalingDrawObject( const POINT& pos )
{
	if( m_pSwapChain == NULL )
	{
		return false;
	}

	Mix::Tool::Win32::Graphics::Manager* pManager = Manager::GetInstance();
	if( pManager == NULL )
	{
		return false;
	}

	Mix::Tool::Win32::Graphics::Scene* pScene = GetScene();
	if( pScene == NULL )
	{
		return false;
	}

	Mix::Tool::Win32::Graphics::DrawObject* pDrawObject = pScene->GetDrawObject();
	if( pDrawObject == NULL )
	{
		return false;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 描画オブジェクトの座標をスクリーン座標へ変換
	////////////////////////////////////////////////////////////////////////////////////////////////////

	const RECT& bounds = m_pSwapChain->GetBounds();
	const D3DVIEWPORT9& viewport = m_pSwapChain->GetViewport();
	const D3DXMATRIX& worldMat = pDrawObject->GetWorldMatrix();

	D3DXMATRIX identityMat;
	D3DXVECTOR3 translation;
	D3DXVECTOR3 screenPos;
	D3DXVECTOR2 diff;

	::D3DXMatrixIdentity( &identityMat );

	translation.x = worldMat.m[3][0];
	translation.y = worldMat.m[3][1];
	translation.z = worldMat.m[3][2];

	::D3DXVec3Project( &screenPos, &translation, &viewport, &( pManager->GetProjectionMatrix() ), &m_ViewMatrix, &identityMat );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// スケーリングに必要なパラメータを求める
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_DrawObjectScaling = pDrawObject->GetScaling();

	m_DrawObjectScalingBasePos.x = screenPos.x - static_cast<float>( bounds.left );
	m_DrawObjectScalingBasePos.y = screenPos.y - static_cast<float>( bounds.top );

	::D3DXVec2Subtract( &diff, &MIX_POINT_TO_VEC2( pos ), &m_DrawObjectScalingBasePos );
	m_InvDrawObjectScalingLength = MIX_FLOAT_DIV( 1.0f, ::D3DXVec2Length( &diff ) );

	return true;
}

void Camera::ScalingDrawObject( const POINT& pos )
{
	Mix::Tool::Win32::Graphics::Manager* pManager = Manager::GetInstance();
	if( pManager == NULL )
	{
		return;
	}

	Mix::Tool::Win32::Graphics::Scene* pScene = GetScene();
	if( pScene == NULL )
	{
		return;
	}

	Mix::Tool::Win32::Graphics::DrawObject* pDrawObject = pScene->GetDrawObject();
	if( pDrawObject == NULL )
	{
		return;
	}

	D3DXVECTOR3 scaling = m_DrawObjectScaling * ( pManager->GetScaling( m_DrawObjectScalingBasePos, MIX_POINT_TO_VEC2( pos ) ) * m_InvDrawObjectScalingLength );

	pDrawObject->SetScaling( scaling );
}

void Camera::RotationDrawObject( int h, int v )
{
	Mix::Tool::Win32::Graphics::Scene* pScene = GetScene();
	if( pScene == NULL )
	{
		return;
	}

	Mix::Tool::Win32::Graphics::DrawObject* pDrawObject = pScene->GetDrawObject();
	if( pDrawObject == NULL )
	{
		return;
	}

//	pDrawObject->SetRotationMatrix( RotationMatrix( pDrawObject->GetRotationMatrix(), -v, -h ) );
}

void Camera::TranslationDrawObject( int h, int v )
{
	Mix::Tool::Win32::Graphics::Manager* pManager = Manager::GetInstance();
	if( pManager == NULL )
	{
		return;
	}

	Mix::Tool::Win32::Graphics::Scene* pScene = GetScene();
	if( pScene == NULL )
	{
		return;
	}

	Mix::Tool::Win32::Graphics::DrawObject* pDrawObject = pScene->GetDrawObject();
	if( pDrawObject == NULL )
	{
		return;
	}

	D3DXVECTOR3 diff = pManager->GetTranslation( h, -v );
	D3DXVECTOR3 translation = pDrawObject->GetTranslation();

	::D3DXVec3TransformCoord( &diff, &diff, &m_PoseMatrix );

	translation += diff;

	pDrawObject->SetTranslation( translation );
}
*/
unsigned int Camera::SelectMesh( const POINT& pos )
{
	const RECT& bounds = m_pSwapChain->GetBounds();

	RECT rect;
	D3DLOCKED_RECT info;
	unsigned int ret = 0;

	rect.left = bounds.left + pos.x;
	rect.top = bounds.top + pos.y;
	rect.right = rect.left + 1;
	rect.bottom = rect.top + 1;

	if( m_pSelectMapTex->Lock( rect, info ) == true )
	{
		unsigned int temp = *( ( unsigned int* )info.pBits );

		ret |= ( temp & 0x00FF0000 ) >> 16;
		ret |= ( temp & 0x0000FF00 ) >> 8;
		ret |= ( temp & 0x000000FF );

		m_pSelectMapTex->Unlock();
	}

	return ret;
}

D3DXVECTOR3 Camera::Unproject( const D3DXVECTOR3& pos )
{
	Mix::Tool::Win32::Graphics::Manager* pManager = Manager::GetInstance();
	if( ( pManager == NULL ) ||
		( m_pSwapChain == NULL ) )
	{
		return D3DXVECTOR3( 0.0f, 0.0f, 0.0f );
	}

	const RECT& bounds = m_pSwapChain->GetBounds();
	Mix::Tool::Win32::Graphics::Texture* pBackBuffer = m_pSwapChain->GetBackBufferPtr();

	float ox = static_cast<float>( bounds.left );
	float oy = static_cast<float>( bounds.top );
	float width = static_cast<float>( pBackBuffer->GetWidth() );
	float height = static_cast<float>( pBackBuffer->GetHeight() );

	D3DXVECTOR3 screenPos( pos.x + ox, pos.y + oy, pos.z );

	D3DXMATRIX invViewMat;
	D3DXMATRIX invProjMat;
	D3DXMATRIX unViewport;
	D3DXMATRIX temp;
	D3DXVECTOR3 worldPos;

	D3DXMatrixInverse( &invViewMat, NULL, &m_ViewMatrix );
	D3DXMatrixInverse( &invProjMat, NULL, &( pManager->GetProjectionMatrix() ) );

	D3DXMatrixIdentity( &unViewport );

	unViewport._11 = ( width * 0.5f );
	unViewport._22 = -( height * 0.5f );
	unViewport._41 = unViewport._11;
	unViewport._42 = ( height * 0.5f );

	D3DXMatrixInverse( &unViewport, NULL, &unViewport );

	temp = unViewport;
	temp *= invProjMat;
	temp *= invViewMat;

	D3DXVec3TransformCoord( &worldPos, &screenPos, &temp );

	return worldPos;
}

const D3DXVECTOR3& Camera::GetLocalPosition( void ) const
{
	return m_LocalPosition;
}

const D3DXVECTOR3& Camera::GetPosition( void ) const
{
	return m_Position;
}

const D3DXVECTOR3& Camera::GetDirection( void ) const
{
	return m_Direction;
}

bool Camera::Contains( const Mix::Tool::Win32::Geometry::SPHERE& sphere ) const
{
	D3DXVECTOR4 pos( sphere.pos, 1.0f );
	float mr = -sphere.radius;

	for( int i = 0; i < Camera::FP_TYPE_MAX; i++ )
	{
		if( mr > ::D3DXPlaneDot( &( m_Frustum[i] ), &pos ) )
		{
			return false;
		}
	}

	return true;
}

bool Camera::Contains( const Mix::Tool::Win32::Geometry::AABB& aabb ) const
{
	D3DXVECTOR4 points[8] =
	{
		D3DXVECTOR4( aabb.min.x, aabb.max.y, aabb.max.z, 1.0f ),
		D3DXVECTOR4( aabb.max.x, aabb.max.y, aabb.max.z, 1.0f ),
		D3DXVECTOR4( aabb.max.x, aabb.max.y, aabb.min.z, 1.0f ),
		D3DXVECTOR4( aabb.min.x, aabb.max.y, aabb.min.z, 1.0f ),
		D3DXVECTOR4( aabb.min.x, aabb.min.y, aabb.max.z, 1.0f ),
		D3DXVECTOR4( aabb.max.x, aabb.min.y, aabb.max.z, 1.0f ),
		D3DXVECTOR4( aabb.max.x, aabb.min.y, aabb.min.z, 1.0f ),
		D3DXVECTOR4( aabb.min.x, aabb.min.y, aabb.min.z, 1.0f ),
	};

	for( int i = 0; i < Camera::FP_TYPE_MAX; i++ )
	{
		int inCount = 8;

		for( int j = 0; j < 8; j++ )
		{
			if( 0.0f > ::D3DXPlaneDot( &( m_Frustum[i] ), &( points[j] ) ) )
			{
				inCount--;
			}
		}

		if( inCount == 0 )
		{
			return false;
		}
	}

	return true;
}

Mix::Tool::Win32::Object::TYPE Camera::GetType( void ) const
{
	return Mix::Tool::Win32::Object::GRAPHICS__CAMERA;
}

bool Camera::QueryType( Mix::Tool::Win32::Object::TYPE type ) const
{
	if( type == Mix::Tool::Win32::Object::GRAPHICS__CAMERA )
	{
		return true;
	}

	return SceneObject::QueryType( type );
}

void Camera::RotationDirect( const D3DXVECTOR3& rot )
{
	D3DXVECTOR3 diff;
	D3DXVECTOR3 xAxis;
	D3DXVECTOR3 yAxis;
	D3DXVECTOR3 zAxis;

	//現在の姿勢での回転量を求める
	::D3DXVec3TransformCoord( &diff, &rot, &m_PoseMatrix );

	//回転軸を取得
	::CopyMemory( &xAxis, m_PoseMatrix.m[0], sizeof( D3DXVECTOR3 ) );
	::CopyMemory( &yAxis, m_PoseMatrix.m[1], sizeof( D3DXVECTOR3 ) );
	::CopyMemory( &zAxis, m_PoseMatrix.m[2], sizeof( D3DXVECTOR3 ) );

	//Z軸回転
	RotationLocalPosition( xAxis, diff );

	//Y軸回転
	RotationLocalPosition( yAxis, diff );

	//Z軸回転
	RotationLocalPosition( zAxis, diff );

	//Z軸
	zAxis = -m_LocalPosition;
	::D3DXVec3Normalize( &zAxis, &zAxis );

	//Z軸
	::CopyMemory( &yAxis, m_PoseMatrix.m[1], sizeof( D3DXVECTOR3 ) );
	::D3DXVec3Cross( &xAxis, &yAxis, &zAxis );
	::D3DXVec3Normalize( &xAxis, &xAxis );

	//Y軸
	::D3DXVec3Cross( &yAxis, &zAxis, &xAxis );
	::D3DXVec3Normalize( &yAxis, &yAxis );

	//姿勢行列を求める
	::D3DXMatrixIdentity( &m_PoseMatrix );
	::CopyMemory( m_PoseMatrix.m[0], &( xAxis ), sizeof( D3DXVECTOR3 ) );
	::CopyMemory( m_PoseMatrix.m[1], &( yAxis ), sizeof( D3DXVECTOR3 ) );
	::CopyMemory( m_PoseMatrix.m[2], &( zAxis ), sizeof( D3DXVECTOR3 ) );

	//クォータニオンを作成
	::D3DXQuaternionRotationMatrix( &m_PoseQuat, &m_PoseMatrix );
}

D3DXMATRIX Camera::RotationMatrix( const D3DXMATRIX& mat, int h, int v )
{
	D3DXMATRIX rotMat;

	::D3DXMatrixIdentity( &rotMat );

	Mix::Tool::Win32::Graphics::Manager* pManager = Manager::GetInstance();
	if( pManager == NULL )
	{
		return rotMat;
	}

	D3DXVECTOR3 diff = pManager->GetRotation( h, v );

	float rad;
	D3DXQUATERNION quat;
	D3DXVECTOR4 temp;

	//ラジアンへ変換
	diff.x = D3DXToRadian( diff.x );
	diff.y = D3DXToRadian( diff.y );
	diff.z = D3DXToRadian( diff.z );

	//現在の姿勢での回転量を求める
	::D3DXVec3TransformCoord( &diff, &diff, &m_PoseMatrix );

	//回転角度を求める
	rad = ::D3DXVec3Length( &diff );

	//回転行列を求める
	::D3DXVec3Normalize( &diff, &diff );
	::D3DXQuaternionRotationAxis( &quat, &diff, rad );
	::D3DXMatrixRotationQuaternion( &rotMat, &quat );

	return mat * rotMat;
}

void Camera::DistationLocalPosition( void )
{
	::D3DXVec3Normalize( &m_LocalPosition, &m_LocalPosition );
	m_LocalPosition *= m_Distance;
}

void Camera::RotationLocalPosition( const D3DXVECTOR3& axis, const D3DXVECTOR3& diff )
{
	D3DXQUATERNION quat;
	D3DXVECTOR3 rotAxis;
	D3DXMATRIX mat;
	float dot;

	::D3DXVec3Cross( &rotAxis, &diff, &axis );

	dot = ::D3DXVec3Length( &rotAxis );

	::D3DXVec3Normalize( &rotAxis, &rotAxis );
	::D3DXQuaternionRotationAxis( &quat, &rotAxis, dot );

	::D3DXMatrixRotationQuaternion( &mat, &quat );
	::D3DXVec3TransformCoord( &m_LocalPosition, &m_LocalPosition, &mat );
}

void Camera::SetPoseMatrix( const D3DXVECTOR3& rot )
{
	D3DXVECTOR3 xAxis;
	D3DXVECTOR3 yAxis;
	D3DXVECTOR3 zAxis;

	//回転軸を取得
	::CopyMemory( &xAxis, m_PoseMatrix.m[0], sizeof( D3DXVECTOR3 ) );
	::CopyMemory( &yAxis, m_PoseMatrix.m[1], sizeof( D3DXVECTOR3 ) );
	::CopyMemory( &zAxis, m_PoseMatrix.m[2], sizeof( D3DXVECTOR3 ) );

	//Z軸回転
	RotationLocalPosition( xAxis, rot );

	//Y軸回転
	RotationLocalPosition( yAxis, rot );

	//Z軸回転
	RotationLocalPosition( zAxis, rot );

	//Z軸
	zAxis = -m_LocalPosition;
	::D3DXVec3Normalize( &zAxis, &zAxis );

	//Z軸
	::CopyMemory( &yAxis, m_PoseMatrix.m[1], sizeof( D3DXVECTOR3 ) );
	::D3DXVec3Cross( &xAxis, &yAxis, &zAxis );
	::D3DXVec3Normalize( &xAxis, &xAxis );

	//Y軸
	::D3DXVec3Cross( &yAxis, &zAxis, &xAxis );
	::D3DXVec3Normalize( &yAxis, &yAxis );

	//姿勢行列を求める
	::D3DXMatrixIdentity( &m_PoseMatrix );
	::CopyMemory( m_PoseMatrix.m[0], &( xAxis ), sizeof( D3DXVECTOR3 ) );
	::CopyMemory( m_PoseMatrix.m[1], &( yAxis ), sizeof( D3DXVECTOR3 ) );
	::CopyMemory( m_PoseMatrix.m[2], &( zAxis ), sizeof( D3DXVECTOR3 ) );
}

const D3DXMATRIX& Camera::GetViewMatrix( void ) const
{
	return m_ViewMatrix;
}

const D3DXMATRIX& Camera::GetViewProjMatrix( void ) const
{
	return m_ViewProjMatrix;
}

bool Camera::IsActive( void )
{
	if( m_pSwapChain == NULL )
	{
		return false;
	}

	return m_pSwapChain->IsActive();
}

void Camera::Update( void )
{
	////////////////////////////////////////////////////////////////////////////////////////////////////
	// マネージャを取得
	////////////////////////////////////////////////////////////////////////////////////////////////////

	Mix::Tool::Win32::Graphics::Manager* pManager = Manager::GetInstance();
	if( pManager == NULL )
	{
		return;
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ワールド空間での視点を求める
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_Position = m_Target + m_LocalPosition;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ワールド空間で方向を求める
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_Direction = ( m_Target - m_Position );
	::D3DXVec3Normalize( &m_Direction, &m_Direction );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ビュー行列を求める
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_ViewMatrix = m_PoseMatrix;

	::CopyMemory( m_ViewMatrix.m[3], &m_Position, sizeof( D3DXVECTOR3 ) );
	m_ViewMatrix.m[3][3] = 1.0f;

	::D3DXMatrixInverse( &m_ViewMatrix, 0, &m_ViewMatrix );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ビュー * 射影 行列を求める
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_ViewProjMatrix = m_ViewMatrix * pManager->GetProjectionMatrix();

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// フラスタムを更新
	////////////////////////////////////////////////////////////////////////////////////////////////////

	//Near
	m_Frustum[Camera::FP_NEAR].a = m_ViewProjMatrix.m[0][3] + m_ViewProjMatrix.m[0][2];
	m_Frustum[Camera::FP_NEAR].b = m_ViewProjMatrix.m[1][3] + m_ViewProjMatrix.m[1][2];
	m_Frustum[Camera::FP_NEAR].c = m_ViewProjMatrix.m[2][3] + m_ViewProjMatrix.m[2][2];
	m_Frustum[Camera::FP_NEAR].d = m_ViewProjMatrix.m[3][3] + m_ViewProjMatrix.m[3][2];

	//Far
	m_Frustum[Camera::FP_FAR].a = m_ViewProjMatrix.m[0][3] - m_ViewProjMatrix.m[0][2];
	m_Frustum[Camera::FP_FAR].b = m_ViewProjMatrix.m[1][3] - m_ViewProjMatrix.m[1][2];
	m_Frustum[Camera::FP_FAR].c = m_ViewProjMatrix.m[2][3] - m_ViewProjMatrix.m[2][2];
	m_Frustum[Camera::FP_FAR].d = m_ViewProjMatrix.m[3][3] - m_ViewProjMatrix.m[3][2];

	//Left
	m_Frustum[Camera::FP_LEFT].a = m_ViewProjMatrix.m[0][3] + m_ViewProjMatrix.m[0][0];
	m_Frustum[Camera::FP_LEFT].b = m_ViewProjMatrix.m[1][3] + m_ViewProjMatrix.m[1][0];
	m_Frustum[Camera::FP_LEFT].c = m_ViewProjMatrix.m[2][3] + m_ViewProjMatrix.m[2][0];
	m_Frustum[Camera::FP_LEFT].d = m_ViewProjMatrix.m[3][3] + m_ViewProjMatrix.m[3][0];

	//Right
	m_Frustum[Camera::FP_RIGHT].a = m_ViewProjMatrix.m[0][3] - m_ViewProjMatrix.m[0][0];
	m_Frustum[Camera::FP_RIGHT].b = m_ViewProjMatrix.m[1][3] - m_ViewProjMatrix.m[1][0];
	m_Frustum[Camera::FP_RIGHT].c = m_ViewProjMatrix.m[2][3] - m_ViewProjMatrix.m[2][0];
	m_Frustum[Camera::FP_RIGHT].d = m_ViewProjMatrix.m[3][3] - m_ViewProjMatrix.m[3][0];

	//Top
	m_Frustum[Camera::FP_TOP].a = m_ViewProjMatrix.m[0][3] - m_ViewProjMatrix.m[0][1];
	m_Frustum[Camera::FP_TOP].b = m_ViewProjMatrix.m[1][3] - m_ViewProjMatrix.m[1][1];
	m_Frustum[Camera::FP_TOP].c = m_ViewProjMatrix.m[2][3] - m_ViewProjMatrix.m[2][1];
	m_Frustum[Camera::FP_TOP].d = m_ViewProjMatrix.m[3][3] - m_ViewProjMatrix.m[3][1];

	//Bottom
	m_Frustum[Camera::FP_BOTTOM].a = m_ViewProjMatrix.m[0][3] + m_ViewProjMatrix.m[0][1];
	m_Frustum[Camera::FP_BOTTOM].b = m_ViewProjMatrix.m[1][3] + m_ViewProjMatrix.m[1][1];
	m_Frustum[Camera::FP_BOTTOM].c = m_ViewProjMatrix.m[2][3] + m_ViewProjMatrix.m[2][1];
	m_Frustum[Camera::FP_BOTTOM].d = m_ViewProjMatrix.m[3][3] + m_ViewProjMatrix.m[3][1];

	//フラスタムの平面を正規化
	for( int i = 0; i < Camera::FP_TYPE_MAX; i++ )
	{
		::D3DXPlaneNormalize( &( m_Frustum[i] ), &( m_Frustum[i] ) );
	}
}

Mix::Tool::Win32::Graphics::TargetTexture* Camera::GetSelectMapTexPtr( void )
{
	return m_pSelectMapTex;
}

Mix::Tool::Win32::Graphics::SwapChain* Camera::GetSwapChainPtr( void )
{
	return m_pSwapChain;
}

}}}}
