#include "Mix/Private/Scene/Common/ViewCamera.h"

namespace Mix{ namespace Scene{ namespace Common{

////////////////////////////////////////////////////////////////////////////////////////////////////
// Mix::Scene::Common::ViewCamera
////////////////////////////////////////////////////////////////////////////////////////////////////

const wchar_t* ViewCamera::FAILED_CREATE = L"ビューカメラの作成に失敗";

ViewCamera* ViewCamera::CreateInstance(	const Mix::Scene::CAMERA_CONFIG& config )
{
	return MIX_LIB_NEW_T( Mix::Memory::SECTION_SCENE, ViewCamera, config );
}

ViewCamera::ViewCamera( const Mix::Scene::CAMERA_CONFIG& config ) : Mix::Scene::Common::Camera( config ),
m_Distance( 10.0f ),
m_LocalEye( 0.0f, 0.0f, m_Distance )
{
	UpdateViewMat();
}

ViewCamera::~ViewCamera( void )
{
}

void ViewCamera::UpdateViewMat( void )
{
	Mix::Vector3 xAxis;
	Mix::Vector3 yAxis;
	Mix::Vector3 zAxis;

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ビュー行列
	////////////////////////////////////////////////////////////////////////////////////////////////////

	//ローカル視点
	m_LocalEye = Mix::Vector4( 0.0f, 0.0f, 1.0f );
	m_LocalEye *= m_Distance;
	m_LocalEye = m_RotMat * m_LocalEye;

	//ビューベクトル
//	m_ViewVec = -m_LocalEye;

	//ワールド視点
	m_Eye = m_At + m_LocalEye;

	//Z軸
	zAxis = -m_LocalEye;
	zAxis.Normalize();

	//X軸
	yAxis.x = m_RotMat.m10;
	yAxis.y = m_RotMat.m11;
	yAxis.z = m_RotMat.m12;
	xAxis = Mix::Vector3::Cross( yAxis, zAxis );
	xAxis.Normalize();

	//Y軸
	yAxis = Mix::Vector3::Cross( zAxis, xAxis );
	yAxis.Normalize();

	m_ViewMat.m00 = xAxis.x;
	m_ViewMat.m01 = xAxis.y;
	m_ViewMat.m02 = xAxis.z;
	m_ViewMat.m03 = 0.0f;

	m_ViewMat.m10 = yAxis.x;
	m_ViewMat.m11 = yAxis.y;
	m_ViewMat.m12 = yAxis.z;
	m_ViewMat.m13 = 0.0f;

	m_ViewMat.m20 = zAxis.x;
	m_ViewMat.m21 = zAxis.y;
	m_ViewMat.m22 = zAxis.z;
	m_ViewMat.m23 = 0.0f;

	m_ViewMat.m30 = m_Eye.x;
	m_ViewMat.m31 = m_Eye.y;
	m_ViewMat.m32 = m_Eye.z;
	m_ViewMat.m33 = 1.0f;

	m_ViewMat.Inverse();
}

void ViewCamera::SetView( const Mix::Vector3& at, const Mix::Quaternion& rotation, Float32 distance )
{
	m_At = at;
	m_Rot = rotation;
	m_RotMat.SetRotation( m_Rot );
	m_Distance = distance;

	UpdateViewMat();
}

void ViewCamera::SetAt( const Mix::Vector3& at )
{
	m_At = at;

	UpdateViewMat();
}

const Mix::Quaternion& ViewCamera::GetRotation( void ) const
{
	return m_Rot;
}

const Mix::Matrix4x4& ViewCamera::GetRotationMatrix( void ) const
{
	return m_RotMat;
}

void ViewCamera::SetRotation( const Mix::Quaternion& rotation )
{
	m_Rot = rotation;
	m_RotMat.SetRotation( m_Rot );

	UpdateViewMat();
}

Float32 ViewCamera::GetDistance( void ) const
{
	return m_Distance;
}

void ViewCamera::SetDistance( Float32 distance )
{
	m_Distance = max( GetNearZ(), distance );

	UpdateViewMat();
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Mix::Scene::ICamera
////////////////////////////////////////////////////////////////////////////////////////////////////

UInt32 ViewCamera::GetID( void ) const
{
	return Camera::GetID();
}

const Mix::Scene::CAMERA_CONFIG& ViewCamera::GetConfig( void ) const
{
	return Camera::GetConfig();
}

Boolean ViewCamera::SetConfig( const Mix::Scene::CAMERA_CONFIG& config )
{
	return Camera::SetConfig( config );
}

const Mix::Vector4& ViewCamera::GetBackgroundColor( void ) const
{
	return Camera::GetBackgroundColor();
}

void ViewCamera::SetBackgroundColor( const Mix::Vector4& color )
{
	Camera::SetBackgroundColor( color );
}

Mix::Graphics::TEXTURE_FILTER_TYPE ViewCamera::GetFilterType( void ) const
{
	return Camera::GetFilterType();
}

void ViewCamera::SetFilterType( Mix::Graphics::TEXTURE_FILTER_TYPE type )
{
	Camera::SetFilterType( type );
}

const Mix::Matrix4x4& ViewCamera::GetProjectionMatrix( void ) const
{
	return Camera::GetProjectionMatrix();
}

void ViewCamera::SetProjection( Float32 fovY, Float32 nearZ, Float32 farZ )
{
	Camera::SetProjection( fovY, nearZ, farZ );
}

void ViewCamera::SetProjection( Float32 fovY, Float32 aspect, Float32 nearZ, Float32 farZ )
{
	Camera::SetProjection( fovY, aspect, nearZ, farZ );
}

void ViewCamera::SetProjection( Float32 fovY, UInt32 width, UInt32 height, Float32 nearZ, Float32 farZ )
{
	Camera::SetProjection( fovY, width, height, nearZ, farZ );
}

Float32 ViewCamera::GetFovY( void ) const
{
	return Camera::GetFovY();
}

Float32 ViewCamera::GetDefaultAspect( void ) const
{
	return Camera::GetDefaultAspect();
}

Float32 ViewCamera::GetAspect( void ) const
{
	return Camera::GetAspect();
}

Float32 ViewCamera::GetNearZ( void ) const
{
	return Camera::GetNearZ();
}

Float32 ViewCamera::GetFarZ( void ) const
{
	return Camera::GetFarZ();
}

const Mix::Vector3& ViewCamera::GetEye( void ) const
{
	return m_Eye;
}

const Mix::Vector3& ViewCamera::GetAt( void ) const
{
	return m_At;
}

const Mix::Vector3& ViewCamera::GetViewVector( void ) const
{
	return Camera::GetViewVector();
}

const Mix::Vector3& ViewCamera::GetViewForward( void ) const
{
	return Camera::GetViewForward();
}

const Mix::Vector3& ViewCamera::GetViewUpward( void ) const
{
	return Camera::GetViewUpward();
}

const Mix::Vector3& ViewCamera::GetViewCrossDirection( void ) const
{
	return Camera::GetViewCrossDirection();
}

const Mix::Matrix4x4& ViewCamera::GetViewMatrix( void ) const
{
	return m_ViewMat;
}

const Mix::Geometry::Frustum& ViewCamera::GetFrustum( void ) const
{
	return Camera::GetFrustum();
}

const Mix::Matrix4x4& ViewCamera::GetViewProjectionMatrix( void ) const
{
	return Camera::GetViewProjectionMatrix();
}

const Mix::Matrix4x4& ViewCamera::GetInvViewProjectionMatrix( void ) const
{
	return Camera::GetInvViewProjectionMatrix();
}

const Mix::Matrix4x4& ViewCamera::GetBillboardMatrix( void ) const
{
	return Camera::GetBillboardMatrix();
}

const Mix::Matrix4x4& ViewCamera::GetBillboardMatrixY( void ) const
{
	return Camera::GetBillboardMatrixY();
}

const Mix::Scene::ICamera::VISIBILITY_SETTINGS& ViewCamera::GetVisiblitySettings( void ) const
{
	return Camera::GetVisiblitySettings();
}

void ViewCamera::SetVisiblitySettings( const Mix::Scene::ICamera::VISIBILITY_SETTINGS& settings )
{
	Camera::SetVisiblitySettings( settings );
}

Boolean ViewCamera::IsAmbientOcclusionEnabled( void ) const
{
	return Camera::IsAmbientOcclusionEnabled();
}

void ViewCamera::SetAmbientOcclusionEnabled( Boolean state )
{
	Camera::SetAmbientOcclusionEnabled( state );
}

const Mix::Scene::ICamera::AMBIENT_OCCLUSION_SETTINGS& ViewCamera::GetAmbientOcclusionSettings( void ) const
{
	return Camera::GetAmbientOcclusionSettings();
}

void ViewCamera::SetAmbientOcclusionSettings( const Mix::Scene::ICamera::AMBIENT_OCCLUSION_SETTINGS& settings )
{
	Camera::SetAmbientOcclusionSettings( settings );
}

Boolean ViewCamera::GetAmbientOcclusionTexture( Mix::Graphics::ITexture** ppTex )
{
	return Camera::GetAmbientOcclusionTexture( ppTex );
}

void ViewCamera::SetAmbientOcclusionTexture( Mix::Graphics::ITexture* pTex )
{
	Camera::SetAmbientOcclusionTexture( pTex );
}

Boolean ViewCamera::IsShadowMappingEnabled( void ) const
{
	return Camera::IsShadowMappingEnabled();
}

void ViewCamera::SetShadowMappingEnabled( Boolean state )
{
	Camera::SetShadowMappingEnabled( state );
}

const Mix::Scene::ICamera::SHADOW_MAPPING_SETTINGS& ViewCamera::GetShadowMappingSettings( void ) const
{
	return Camera::GetShadowMappingSettings();
}

void ViewCamera::SetShadowMappingSettings( const Mix::Scene::ICamera::SHADOW_MAPPING_SETTINGS& settings )
{
	Camera::SetShadowMappingSettings( settings );
}

const Mix::Scene::ICamera::LUMINOSITY_SETTINGS& ViewCamera::GetLuminositySettings( void ) const
{
	return Camera::GetLuminositySettings();
}

void ViewCamera::SetLuminositySettings( const Mix::Scene::ICamera::LUMINOSITY_SETTINGS& settings )
{
	Camera::SetLuminositySettings( settings );
}

UInt32 ViewCamera::ResumeLuminosityAdaptation( void )
{
	return Camera::ResumeLuminosityAdaptation();
}

UInt32 ViewCamera::SusupendLuminosityAdaptation( void )
{
	return Camera::SusupendLuminosityAdaptation();
}

UInt32 ViewCamera::GetLuminosityAdaptationSuspendCount( void ) const
{
	return Camera::GetLuminosityAdaptationSuspendCount();
}

void ViewCamera::ForceLuminosityAdaptation( void )
{
	Camera::ForceLuminosityAdaptation();
}

void ViewCamera::SetLuminosityAdaptation( Float32 lum )
{
	Camera::SetLuminosityAdaptation( lum );
}

Boolean ViewCamera::IsBloomEnabled( void ) const
{
	return Camera::IsBloomEnabled();
}

void ViewCamera::SetBloomEnabled( Boolean state )
{
	Camera::SetBloomEnabled( state );
}

UInt32 ViewCamera::GetBloomOverflowNum( void ) const
{
	return Camera::GetBloomOverflowNum();
}

const Mix::Scene::ICamera::BLOOM_OVERFLOW& ViewCamera::GetBloomOverflow( UInt32 index ) const
{
	return Camera::GetBloomOverflow( index );
}

void ViewCamera::SetBloomOverflow( UInt32 index, const Mix::Scene::ICamera::BLOOM_OVERFLOW& overflow )
{
	Camera::SetBloomOverflow( index, overflow );
}

const Mix::Scene::ICamera::BLOOM_SETTINGS& ViewCamera::GetBloomSettings( void ) const
{
	return Camera::GetBloomSettings();
}

void ViewCamera::SetBloomSettings( const Mix::Scene::ICamera::BLOOM_SETTINGS& settings )
{
	Camera::SetBloomSettings( settings );
}

Boolean ViewCamera::IsLightShaftsEnabled( void ) const
{
	return Camera::IsLightShaftsEnabled();
}

void ViewCamera::SetLightShaftsEnabled( Boolean state )
{
	Camera::SetLightShaftsEnabled( state );
}

const Mix::Scene::ICamera::LIGHT_SHAFTS_SETTINGS& ViewCamera::GetLightShaftsSettings( void ) const
{
	return Camera::GetLightShaftsSettings();
}

void ViewCamera::SetLightShaftsSettings( const Mix::Scene::ICamera::LIGHT_SHAFTS_SETTINGS& settings )
{
	Camera::SetLightShaftsSettings( settings );
}

Boolean ViewCamera::GetLightShaftsTexture( Mix::Graphics::ITexture** ppTex )
{
	return Camera::GetLightShaftsTexture( ppTex );
}

void ViewCamera::SetLightShaftsTexture( Mix::Graphics::ITexture* pTex )
{
	Camera::SetLightShaftsTexture( pTex );
}

Boolean ViewCamera::IsLensFlareEnabled( void ) const
{
	return Camera::IsLensFlareEnabled();
}

void ViewCamera::SetLensFlareEnabled( Boolean state )
{
	Camera::SetLensFlareEnabled( state );
}

const Mix::Scene::ICamera::LENS_FLARE_SETTINGS& ViewCamera::GetLensFlareSettings( void ) const
{
	return Camera::GetLensFlareSettings();
}

void ViewCamera::SetLensFlareSettings( const Mix::Scene::ICamera::LENS_FLARE_SETTINGS& settings )
{
	Camera::SetLensFlareSettings( settings );
}

Boolean ViewCamera::GetLensFlareTexture( Mix::Scene::ICamera::LENS_FLARE_TEXTURE_TYPE type, Mix::Graphics::ITexture** ppTexture )
{
	return Camera::GetLensFlareTexture( type, ppTexture );
}

void ViewCamera::SetLensFlareTexture( Mix::Scene::ICamera::LENS_FLARE_TEXTURE_TYPE type, Mix::Graphics::ITexture* pTexture )
{
	Camera::SetLensFlareTexture( type, pTexture );
}

Boolean ViewCamera::IsFilmicEnabled( void ) const
{
	return Camera::IsFilmicEnabled();
}

void ViewCamera::SetFilmicEnabled( Boolean state )
{
	Camera::SetFilmicEnabled( state );
}

Mix::Scene::ICamera::FILMIC_TYPE ViewCamera::GetFilmicType( void ) const
{
	return Camera::GetFilmicType();
}

Boolean ViewCamera::GetFilmicSettings( void* pSettings, UInt32 settingsSize ) const
{
	return Camera::GetFilmicSettings( pSettings, settingsSize );
}

Boolean ViewCamera::SetFilmicType( Mix::Scene::ICamera::FILMIC_TYPE type, const void* pSettings, UInt32 settingsSize )
{
	return Camera::SetFilmicType( type, pSettings, settingsSize );
}

Boolean ViewCamera::IsGammaEnabled( void ) const
{
	return Camera::IsGammaEnabled();
}

void ViewCamera::SetGammaEnabled( Boolean state )
{
	Camera::SetGammaEnabled( state );
}

const Mix::Vector3& ViewCamera::GetGammaValue( void ) const
{
	return Camera::GetGammaValue();
}

void ViewCamera::SetGammaValue( const Mix::Vector3& value )
{
	Camera::SetGammaValue( value );
}

void ViewCamera::SetGammaValue( Float32 value )
{
	Camera::SetGammaValue( value );
}

Boolean ViewCamera::IsMotionBlurEnabled( void ) const
{
	return Camera::IsMotionBlurEnabled();
}

void ViewCamera::SetMotionBlurEnabled( Boolean state )
{
	Camera::SetMotionBlurEnabled( state );
}

const Mix::Scene::ICamera::MOTION_BLUR_SETTINGS& ViewCamera::GetMotionBlurSettings( void ) const
{
	return Camera::GetMotionBlurSettings();
}

void ViewCamera::SetMotionBlurSettings( const Mix::Scene::ICamera::MOTION_BLUR_SETTINGS& settings )
{
	Camera::SetMotionBlurSettings( settings );
}

Boolean ViewCamera::IsMotionBlurActivated( void ) const
{
	return Camera::IsMotionBlurActivated();
}

UInt32 ViewCamera::GetMotionBlurCurrentAmount( void ) const
{
	return Camera::GetMotionBlurCurrentAmount();
}

Boolean ViewCamera::IsChromatismEnabled( void ) const
{
	return Camera::IsChromatismEnabled();
}

void ViewCamera::SetChromatismEnabled( Boolean state )
{
	Camera::SetChromatismEnabled( state );
}

const Mix::Scene::ICamera::CHROMATISM_SETTINGS& ViewCamera::GetChromatismSettings( void ) const
{
	return Camera::GetChromatismSettings();
}

void ViewCamera::SetChromatismSettings( const Mix::Scene::ICamera::CHROMATISM_SETTINGS& settings )
{
	Camera::SetChromatismSettings( settings );
}

Boolean ViewCamera::IsDofEnabled( void ) const
{
	return Camera::IsDofEnabled();
}

void ViewCamera::SetDofEnabled( Boolean state )
{
	Camera::SetDofEnabled( state );
}

const Mix::Scene::ICamera::DOF_SETTINGS& ViewCamera::GetDofSettings( void ) const
{
	return Camera::GetDofSettings();
}

void ViewCamera::SetDofSettings( const Mix::Scene::ICamera::DOF_SETTINGS& settings )
{
	Camera::SetDofSettings( settings );
}

Boolean ViewCamera::IsLensDistortionEnabled( void ) const
{
	return Camera::IsLensDistortionEnabled();
}

void ViewCamera::SetLensDistortionEnabled( Boolean state )
{
	Camera::SetLensDistortionEnabled( state );
}

const Mix::Scene::ICamera::DISTORTION_SETTINGS& ViewCamera::GetLendDistortionSettings( void ) const
{
	return Camera::GetLendDistortionSettings();
}

void ViewCamera::SetLendDistortionSettings( const Mix::Scene::ICamera::DISTORTION_SETTINGS& settings )
{
	Camera::SetLendDistortionSettings( settings );
}

Boolean ViewCamera::IsVignetteEnabled( void ) const
{
	return Camera::IsVignetteEnabled();
}

void ViewCamera::SetVignetteEnabled( Boolean state )
{
	Camera::SetVignetteEnabled( state );
}

const Mix::Scene::ICamera::VIGNETTE_SETTINGS& ViewCamera::GetVignetteSettings( void ) const
{
	return Camera::GetVignetteSettings();
}

void ViewCamera::SetVignetteSettings( const Mix::Scene::ICamera::VIGNETTE_SETTINGS& settings )
{
	Camera::SetVignetteSettings( settings );
}

Mix::Scene::ICamera::ANTIALIASING_TYPE ViewCamera::GetAntiAliasingType( void ) const
{
	return Camera::GetAntiAliasingType();
}

void ViewCamera::SetAntiAliasingType( Mix::Scene::ICamera::ANTIALIASING_TYPE type )
{
	Camera::SetAntiAliasingType( type );
}

Boolean ViewCamera::IsUnderWater( void ) const
{
	return Camera::IsUnderWater();
}

Mix::Point ViewCamera::Project( const Mix::Vector3& pos ) const
{
	return Camera::Project( pos );
}

Mix::Point ViewCamera::Project( const Mix::Point& screenPos, const Mix::Vector3& pos ) const
{
	return Camera::Project( screenPos, pos );
}

Mix::Point ViewCamera::Project( const Mix::Rectangle& screenRect, const Mix::Vector3& pos ) const
{
	return Camera::Project( screenRect, pos );
}

Mix::Vector3 ViewCamera::Unproject( const Mix::Point& pos, Float32 z ) const
{
	return Camera::Unproject( pos, z );
}

Mix::Vector3 ViewCamera::Unproject( const Mix::Point& screenPos, const Mix::Point& pos, Float32 z ) const
{
	return Camera::Unproject( screenPos, pos, z );
}

Mix::Vector3 ViewCamera::Unproject( const Mix::Rectangle& screenRect, const Mix::Point& pos, Float32 z ) const
{
	return Camera::Unproject( screenRect, pos, z );
}

Boolean ViewCamera::DragObject( const Mix::Point& pos )
{
	return Camera::DragObject( pos );
}

Boolean ViewCamera::DragObject( const Mix::Point& screenPos, const Mix::Point& pos )
{
	return Camera::DragObject( screenPos, pos );
}

Boolean ViewCamera::DragObject( const Mix::Rectangle& screenRect, const Mix::Point& pos )
{
	return Camera::DragObject( screenRect, pos );
}

void ViewCamera::Update( Float32 dt )
{
	Camera::Update( dt );
}

Boolean ViewCamera::Draw( void )
{
	return Camera::Draw();
}

void ViewCamera::Debug_SetFillType( Mix::Graphics::FILL_TYPE type )
{
	Camera::Debug_SetFillType( type );
}

Mix::Graphics::FILL_TYPE ViewCamera::Debug_GetFillType( void ) const
{
	return Camera::Debug_GetFillType();
}

void ViewCamera::Debug_SetDrawMethod( Mix::Scene::DEBUG_DRAW_METHOD method )
{
	Camera::Debug_SetDrawMethod( method );
}

Mix::Scene::DEBUG_DRAW_METHOD ViewCamera::Debug_GetDrawMethod( void ) const
{
	return Camera::Debug_GetDrawMethod();
}

void ViewCamera::Debug_SetDrawFlags( UInt32 flags )
{
	Camera::Debug_SetDrawFlags( flags );
}

UInt32 ViewCamera::Debug_GetDrawFlags( void ) const
{
	return Camera::Debug_GetDrawFlags();
}

const Mix::Scene::ICamera::DEBUG_DRAW_FILIMIC_SETTINGS& ViewCamera::Debug_GetDrawFilmicSettings( void ) const
{
	return Camera::Debug_GetDrawFilmicSettings();
}

void ViewCamera::Debug_SetDrawFilmicSettings( const Mix::Scene::ICamera::DEBUG_DRAW_FILIMIC_SETTINGS& settings )
{
	Camera::Debug_SetDrawFilmicSettings( settings );
}

UInt32 ViewCamera::Debug_GetProfile( UInt32 type, void* pProf, UInt32 size ) const
{
	return Camera::Debug_GetProfile( type, pProf, size );
}

UInt32 ViewCamera::Debug_GetImageNum( UInt32 type ) const
{
	return Camera::Debug_GetImageNum( type );
}

Boolean ViewCamera::Debug_GetImage( UInt32 type, UInt32 index, Mix::Graphics::ITexture** ppTexture )
{
	return Camera::Debug_GetImage( type, index, ppTexture );
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Mix::Scene::IRendererObject
////////////////////////////////////////////////////////////////////////////////////////////////////

Mix::Scene::IRendererObject::TYPE ViewCamera::GetType( void ) const
{
	return Mix::Scene::IRendererObject::VIEW_CAMERA;
}

Boolean ViewCamera::IsRendering( void ) const
{
	return Camera::IsRendering();
}

}}}
