#include "Mix/Private/Scene/Common/OctreeNode.h"
#include "Mix/Private/Scene/Common/Octree.h"

#ifdef _DEBUG
	#include "Mix/Private/Scene/Common/Debug.h"
	#include "Mix/Graphics/Utility/IPerspectiveRenderer.h"
#endif //_DEBUG

namespace Mix{ namespace Scene{ namespace Common{

////////////////////////////////////////////////////////////////////////////////////////////////////
// ベース
////////////////////////////////////////////////////////////////////////////////////////////////////

OctreeNode::OctreeNode( Mix::Scene::Common::Octree* pOwner, UInt32 index ) :
m_pOwner( NULL ),
m_Index( index ),
m_Flags( 0 )
{
	MIX_ASSERT( pOwner != NULL );
	m_pOwner = pOwner;
}

OctreeNode::~OctreeNode( void )
{
	MIX_ASSERT( m_LocalLightObjects.count == 0 );
	MIX_ASSERT( m_ActorModelObjects.count == 0 );
}

UInt32 OctreeNode::GetIndex( void ) const
{
	return m_Index;
}

Mix::Scene::Common::LocalLightObject* OctreeNode::GetLocalLightObjects( void ) const
{
	return m_LocalLightObjects.pTop;
}

Mix::Scene::Common::WaterPoolObject* OctreeNode::GetWaterPoolObjects( void ) const
{
	return m_WaterPoolObjects.pTop;
}

Mix::Scene::Common::PlanterObject* OctreeNode::GetPlanterObjects( void ) const
{
	return m_PlanterObjects.pTop;
}

Mix::Scene::Common::LeavingParticleObject* OctreeNode::GetLeavingParticleObjects( void ) const
{
	return m_LeavingParticleObjects.pTop;
}

Mix::Scene::Common::ScatterParticleUnitObject* OctreeNode::GetScatterParticleUnitObjects( void ) const
{
	return m_ScatterParticleUnitObjects.pTop;
}

Mix::Scene::Common::ActorModelObject* OctreeNode::GetActorModelObjects( void ) const
{
	return m_ActorModelObjects.pTop;
}

void OctreeNode::AttachObject( Mix::Scene::Common::LocalLightObject* pObj )
{
	MIX_ASSERT( m_pOwner != NULL );
	MIX_ASSERT( pObj != NULL );
	MIX_ASSERT( pObj->m_pNode == NULL );

	OctreeNode::AddObject( m_LocalLightObjects, pObj );
	pObj->m_pNode = this;

	m_pOwner->RefreshNode( this );
	MIX_SETBIT( m_Flags, OctreeNode::CHANGED_OBJECTS );
	MIX_SETBIT( m_Flags, OctreeNode::REQ_REFRESH_BOUNDS );
}

void OctreeNode::AttachObject( Mix::Scene::Common::WaterPoolObject* pObj )
{
	MIX_ASSERT( m_pOwner != NULL );
	MIX_ASSERT( pObj != NULL );
	MIX_ASSERT( pObj->m_pNode == NULL );

	OctreeNode::AddObject( m_WaterPoolObjects, pObj );
	pObj->m_pNode = this;

	m_pOwner->RefreshNode( this );
	MIX_SETBIT( m_Flags, OctreeNode::CHANGED_OBJECTS );
	MIX_SETBIT( m_Flags, OctreeNode::REQ_REFRESH_BOUNDS );
}

void OctreeNode::AttachObject( Mix::Scene::Common::PlanterObject* pObj )
{
	MIX_ASSERT( m_pOwner != NULL );
	MIX_ASSERT( pObj != NULL );
	MIX_ASSERT( pObj->m_pNode == NULL );

	OctreeNode::AddObject( m_PlanterObjects, pObj );
	pObj->m_pNode = this;

	m_pOwner->RefreshNode( this );
	MIX_SETBIT( m_Flags, OctreeNode::CHANGED_OBJECTS );
	MIX_SETBIT( m_Flags, OctreeNode::REQ_REFRESH_BOUNDS );
}

void OctreeNode::AttachObject( Mix::Scene::Common::LeavingParticleObject* pObj )
{
	MIX_ASSERT( m_pOwner != NULL );
	MIX_ASSERT( pObj != NULL );
	MIX_ASSERT( pObj->m_pNode == NULL );

	OctreeNode::AddObject( m_LeavingParticleObjects, pObj );
	pObj->m_pNode = this;

	m_pOwner->RefreshNode( this );
	MIX_SETBIT( m_Flags, OctreeNode::CHANGED_OBJECTS );
	MIX_SETBIT( m_Flags, OctreeNode::REQ_REFRESH_BOUNDS );
}

void OctreeNode::AttachObject( Mix::Scene::Common::ScatterParticleUnitObject* pObj )
{
	MIX_ASSERT( m_pOwner != NULL );
	MIX_ASSERT( pObj != NULL );
	MIX_ASSERT( pObj->m_pNode == NULL );

	OctreeNode::AddObject( m_ScatterParticleUnitObjects, pObj );
	pObj->m_pNode = this;

	m_pOwner->RefreshNode( this );
	MIX_SETBIT( m_Flags, OctreeNode::CHANGED_OBJECTS );
	MIX_SETBIT( m_Flags, OctreeNode::REQ_REFRESH_BOUNDS );
}

void OctreeNode::AttachObject( Mix::Scene::Common::ActorModelObject* pObj )
{
	MIX_ASSERT( m_pOwner != NULL );
	MIX_ASSERT( pObj != NULL );
	MIX_ASSERT( pObj->m_pNode == NULL );

	OctreeNode::AddObject( m_ActorModelObjects, pObj );
	pObj->m_pNode = this;

	m_pOwner->RefreshNode( this );
	MIX_SETBIT( m_Flags, OctreeNode::CHANGED_OBJECTS );
	MIX_SETBIT( m_Flags, OctreeNode::REQ_REFRESH_BOUNDS );
}

void OctreeNode::DetachObject( Mix::Scene::Common::LocalLightObject* pObj )
{
	MIX_ASSERT( m_pOwner != NULL );
	MIX_ASSERT( pObj != NULL );
	MIX_ASSERT( pObj->m_pNode == this );

	OctreeNode::RemoveObject( m_LocalLightObjects, pObj );
	pObj->m_pNode = NULL;

	m_pOwner->RefreshNode( this );
	MIX_SETBIT( m_Flags, OctreeNode::CHANGED_OBJECTS );
	MIX_SETBIT( m_Flags, OctreeNode::REQ_REFRESH_BOUNDS );
}

void OctreeNode::DetachObject( Mix::Scene::Common::WaterPoolObject* pObj )
{
	MIX_ASSERT( m_pOwner != NULL );
	MIX_ASSERT( pObj != NULL );
	MIX_ASSERT( pObj->m_pNode == this );

	OctreeNode::RemoveObject( m_WaterPoolObjects, pObj );
	pObj->m_pNode = NULL;

	m_pOwner->RefreshNode( this );
	MIX_SETBIT( m_Flags, OctreeNode::CHANGED_OBJECTS );
	MIX_SETBIT( m_Flags, OctreeNode::REQ_REFRESH_BOUNDS );
}

void OctreeNode::DetachObject( Mix::Scene::Common::PlanterObject* pObj )
{
	MIX_ASSERT( m_pOwner != NULL );
	MIX_ASSERT( pObj != NULL );
	MIX_ASSERT( pObj->m_pNode == this );

	OctreeNode::RemoveObject( m_PlanterObjects, pObj );
	pObj->m_pNode = NULL;

	m_pOwner->RefreshNode( this );
	MIX_SETBIT( m_Flags, OctreeNode::CHANGED_OBJECTS );
	MIX_SETBIT( m_Flags, OctreeNode::REQ_REFRESH_BOUNDS );
}

void OctreeNode::DetachObject( Mix::Scene::Common::LeavingParticleObject* pObj )
{
	MIX_ASSERT( m_pOwner != NULL );
	MIX_ASSERT( pObj != NULL );
	MIX_ASSERT( pObj->m_pNode != NULL );

	OctreeNode::RemoveObject( m_LeavingParticleObjects, pObj );
	pObj->m_pNode = NULL;

	m_pOwner->RefreshNode( this );
	MIX_SETBIT( m_Flags, OctreeNode::CHANGED_OBJECTS );
	MIX_SETBIT( m_Flags, OctreeNode::REQ_REFRESH_BOUNDS );
}

void OctreeNode::DetachObject( Mix::Scene::Common::ScatterParticleUnitObject* pObj )
{
	MIX_ASSERT( m_pOwner != NULL );
	MIX_ASSERT( pObj != NULL );
	MIX_ASSERT( pObj->m_pNode != NULL );

	OctreeNode::RemoveObject( m_ScatterParticleUnitObjects, pObj );
	pObj->m_pNode = NULL;

	m_pOwner->RefreshNode( this );
	MIX_SETBIT( m_Flags, OctreeNode::CHANGED_OBJECTS );
	MIX_SETBIT( m_Flags, OctreeNode::REQ_REFRESH_BOUNDS );
}

void OctreeNode::DetachObject( Mix::Scene::Common::ActorModelObject* pObj )
{
	MIX_ASSERT( m_pOwner != NULL );
	MIX_ASSERT( pObj != NULL );
	MIX_ASSERT( pObj->m_pNode != NULL );

	OctreeNode::RemoveObject( m_ActorModelObjects, pObj );
	pObj->m_pNode = NULL;

	m_pOwner->RefreshNode( this );
	MIX_SETBIT( m_Flags, OctreeNode::CHANGED_OBJECTS );
	MIX_SETBIT( m_Flags, OctreeNode::REQ_REFRESH_BOUNDS );
}

void OctreeNode::DestroyObject( Mix::Scene::Common::LocalLightObject* pObj )
{
	MIX_ASSERT( m_pOwner != NULL );
	MIX_ASSERT( pObj != NULL );

	DetachObject( pObj );
	m_pOwner->DetachObject( pObj );
}

void OctreeNode::DestroyObject( Mix::Scene::Common::WaterPoolObject* pObj )
{
	MIX_ASSERT( m_pOwner != NULL );
	MIX_ASSERT( pObj != NULL );

	DetachObject( pObj );
	m_pOwner->DetachObject( pObj );
}

void OctreeNode::DestroyObject( Mix::Scene::Common::PlanterObject* pObj )
{
	MIX_ASSERT( m_pOwner != NULL );
	MIX_ASSERT( pObj != NULL );

	DetachObject( pObj );
	m_pOwner->DetachObject( pObj );
}

void OctreeNode::DestroyObject( Mix::Scene::Common::LeavingParticleObject* pObj )
{
	MIX_ASSERT( m_pOwner != NULL );
	MIX_ASSERT( pObj != NULL );

	DetachObject( pObj );
	m_pOwner->DetachObject( pObj );
}

void OctreeNode::DestroyObject( Mix::Scene::Common::ScatterParticleUnitObject* pObj )
{
	MIX_ASSERT( m_pOwner != NULL );
	MIX_ASSERT( pObj != NULL );

	DetachObject( pObj );
	m_pOwner->DetachObject( pObj );
}

void OctreeNode::DestroyObject( Mix::Scene::Common::ActorModelObject* pObj )
{
	MIX_ASSERT( m_pOwner != NULL );
	MIX_ASSERT( pObj != NULL );

	DetachObject( pObj );
	m_pOwner->DetachObject( pObj );
}

void OctreeNode::RefreshObject( Mix::Scene::Common::LocalLightObject* pObj )
{
	MIX_ASSERT( pObj != NULL );
	MIX_ASSERT( m_pOwner != NULL );

	UInt32 nodeIndex = m_pOwner->GetMortonCode( pObj->GetBounds() );

	if( nodeIndex != m_Index )
	{
		DetachObject( pObj );
		m_pOwner->AttachObject( nodeIndex, pObj );
	}
	else
	{
		m_pOwner->RefreshNode( this );
		MIX_SETBIT( m_Flags, OctreeNode::CHANGED_OBJECTS );
		MIX_SETBIT( m_Flags, OctreeNode::REQ_REFRESH_BOUNDS );
	}
}

void OctreeNode::RefreshObject( Mix::Scene::Common::WaterPoolObject* pObj )
{
	MIX_ASSERT( pObj != NULL );
	MIX_ASSERT( m_pOwner != NULL );

	const Mix::Geometry::AABB& bounds = pObj->GetBounds();
	UInt32 nodeIndex = m_pOwner->GetMortonCode( bounds.min, bounds.max );

	if( nodeIndex != m_Index )
	{
		DetachObject( pObj );
		m_pOwner->AttachObject( nodeIndex, pObj );
	}
	else
	{
		m_pOwner->RefreshNode( this );
		MIX_SETBIT( m_Flags, OctreeNode::CHANGED_OBJECTS );
		MIX_SETBIT( m_Flags, OctreeNode::REQ_REFRESH_BOUNDS );
	}
}

void OctreeNode::RefreshObject( Mix::Scene::Common::PlanterObject* pObj )
{
	MIX_ASSERT( pObj != NULL );
	MIX_ASSERT( m_pOwner != NULL );

	const Mix::Geometry::AABB& bounds = pObj->GetBounds();
	UInt32 nodeIndex = m_pOwner->GetMortonCode( bounds.min, bounds.max );

	if( nodeIndex != m_Index )
	{
		DetachObject( pObj );
		m_pOwner->AttachObject( nodeIndex, pObj );
	}
	else
	{
		m_pOwner->RefreshNode( this );
		MIX_SETBIT( m_Flags, OctreeNode::CHANGED_OBJECTS );
		MIX_SETBIT( m_Flags, OctreeNode::REQ_REFRESH_BOUNDS );
	}
}

void OctreeNode::RefreshObject( Mix::Scene::Common::LeavingParticleObject* pObj )
{
	MIX_ASSERT( pObj != NULL );
	MIX_ASSERT( m_pOwner != NULL );

	const Mix::Geometry::AABB& bounds = pObj->GetBounds();
	UInt32 nodeIndex = m_pOwner->GetMortonCode( bounds.min, bounds.max );

	if( nodeIndex != m_Index )
	{
		DetachObject( pObj );
		m_pOwner->AttachObject( nodeIndex, pObj );
	}
	else
	{
		m_pOwner->RefreshNode( this );
		MIX_SETBIT( m_Flags, OctreeNode::CHANGED_OBJECTS );
		MIX_SETBIT( m_Flags, OctreeNode::REQ_REFRESH_BOUNDS );
	}
}

void OctreeNode::RefreshObject( Mix::Scene::Common::ScatterParticleUnitObject* pObj )
{
	MIX_ASSERT( pObj != NULL );
	MIX_ASSERT( m_pOwner != NULL );

	const Mix::Geometry::Sphere& bounds = pObj->GetBounds();

	UInt32 nodeIndex = m_pOwner->GetMortonCode( bounds );

	if( nodeIndex != m_Index )
	{
		DetachObject( pObj );
		m_pOwner->AttachObject( nodeIndex, pObj );
	}
	else
	{
		m_pOwner->RefreshNode( this );
		MIX_SETBIT( m_Flags, OctreeNode::CHANGED_OBJECTS );
		MIX_SETBIT( m_Flags, OctreeNode::REQ_REFRESH_BOUNDS );
	}
}

void OctreeNode::RefreshObject( Mix::Scene::Common::ActorModelObject* pObj )
{
	MIX_ASSERT( pObj != NULL );
	MIX_ASSERT( m_pOwner != NULL );

	UInt32 nodeIndex = m_pOwner->GetMortonCode( pObj->GetBounds() );

	if( nodeIndex != m_Index )
	{
		DetachObject( pObj );
		m_pOwner->AttachObject( nodeIndex, pObj );
	}
	else
	{
		m_pOwner->RefreshNode( this );
		MIX_SETBIT( m_Flags, OctreeNode::CHANGED_OBJECTS );
		MIX_SETBIT( m_Flags, OctreeNode::REQ_REFRESH_BOUNDS );
	}
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// デフォルト
////////////////////////////////////////////////////////////////////////////////////////////////////

DefaultOctreeNode::DefaultOctreeNode( Mix::Scene::Common::Octree* pOwner, UInt32 index ) : OctreeNode( pOwner, index ),
m_Childs( 0 ),
m_Bounds( Mix::Vector3( +MIX_FLOAT_MAX, +MIX_FLOAT_MAX, +MIX_FLOAT_MAX ),  Mix::Vector3( -MIX_FLOAT_MAX, -MIX_FLOAT_MAX, -MIX_FLOAT_MAX ) )
{
}

DefaultOctreeNode::~DefaultOctreeNode( void )
{
}

UInt8 DefaultOctreeNode::GetChilds( void ) const
{
	return m_Childs;
}

void DefaultOctreeNode::SetChilds( UInt8 childs )
{
	m_Childs = childs;
}

void DefaultOctreeNode::ReqRefreshBounds( void )
{
	MIX_SETBIT( m_Flags, OctreeNode::REQ_REFRESH_BOUNDS );
}

Boolean DefaultOctreeNode::IsReqRefresh( void ) const
{
	return ( m_Flags != 0 );
}

void DefaultOctreeNode::Refresh( void )
{
	MIX_ASSERT( m_Flags != 0 );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 境界をリフレッシュ
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( MIX_TESTBIT( m_Flags, OctreeNode::CHANGED_OBJECTS ) == OctreeNode::CHANGED_OBJECTS )
	{
		MIX_ASSERT( MIX_TESTBIT( m_Flags, OctreeNode::REQ_REFRESH_BOUNDS ) == OctreeNode::REQ_REFRESH_BOUNDS );

		Mix::Scene::Common::LocalLightObject* pLLObj = m_LocalLightObjects.pTop;
		Mix::Scene::Common::WaterPoolObject* pWPObj = m_WaterPoolObjects.pTop;
		Mix::Scene::Common::PlanterObject* pPTObj = m_PlanterObjects.pTop;
		Mix::Scene::Common::LeavingParticleObject* pLPCObj = m_LeavingParticleObjects.pTop;
		Mix::Scene::Common::ScatterParticleUnitObject* pSPCObj = m_ScatterParticleUnitObjects.pTop;
		Mix::Scene::Common::ActorModelObject* pAMObj = m_ActorModelObjects.pTop;

		// リセット
		m_ObjBounds.min.Set( +MIX_FLOAT_MAX, +MIX_FLOAT_MAX, +MIX_FLOAT_MAX );
		m_ObjBounds.max.Set( -MIX_FLOAT_MAX, -MIX_FLOAT_MAX, -MIX_FLOAT_MAX );

		// ローカルライト
		while( pLLObj != NULL )
		{
			m_ObjBounds += pLLObj->GetBounds();
			pLLObj = pLLObj->m_pNext;
		}

		// ウォータープール
		while( pWPObj != NULL )
		{
			m_ObjBounds += pWPObj->GetBounds();
			pWPObj = pWPObj->m_pNext;
		}

		// プランター
		while( pPTObj != NULL )
		{
			m_ObjBounds += pPTObj->GetBounds();
			pPTObj = pPTObj->m_pNext;
		}

		// リービングパーティクル
		while( pLPCObj != NULL )
		{
			m_ObjBounds += pLPCObj->GetBounds();
			pLPCObj = pLPCObj->m_pNext;
		}

		// スキャッターパーティクルユニット
		while( pSPCObj != NULL )
		{
			m_ObjBounds += pSPCObj->GetBounds();
			pSPCObj = pSPCObj->m_pNext;
		}

		// アクターモデル
		while( pAMObj != NULL )
		{
			m_ObjBounds += pAMObj->GetBounds();
			pAMObj = pAMObj->m_pNext;
		}
	}
	else
	{
		if( ( m_LocalLightObjects.count == 0 ) &&
			( m_WaterPoolObjects.count == 0 ) &&
			( m_PlanterObjects.count == 0 ) &&
			( m_LeavingParticleObjects.count == 0 ) &&
			( m_ScatterParticleUnitObjects.count == 0 ) &&
			( m_ActorModelObjects.count == 0 ) )
		{
			// リセット

			m_ObjBounds.min.Set( +MIX_FLOAT_MAX, +MIX_FLOAT_MAX, +MIX_FLOAT_MAX );
			m_ObjBounds.max.Set( -MIX_FLOAT_MAX, -MIX_FLOAT_MAX, -MIX_FLOAT_MAX );
		}
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// 子の境界を結合
	////////////////////////////////////////////////////////////////////////////////////////////////////

	if( MIX_TESTBIT( m_Flags, OctreeNode::REQ_REFRESH_BOUNDS ) == OctreeNode::REQ_REFRESH_BOUNDS )
	{
		Mix::Geometry::AABB childBounds;

		m_Bounds = m_ObjBounds;

		if( m_pOwner->GetChildBounds( this, childBounds ) == True )
		{
			m_Bounds += childBounds;
		}
	}

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ファイナライズ
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_Bounds.ComputePoints();
	m_Flags = 0;
}

const Mix::Geometry::AABB& DefaultOctreeNode::GetBounds( void ) const
{
	return m_Bounds;
}

#ifdef _DEBUG

void DefaultOctreeNode::Debug_Draw( Mix::Graphics::Utility::IPerspectiveRenderer* pPerspectiveRenderer, UInt32 flags )
{
	MIX_ASSERT( pPerspectiveRenderer != NULL );

	if( ( m_Index != 0 ) &&
		( m_LocalLightObjects.count == 0 ) &&
		( m_WaterPoolObjects.count == 0 ) &&
		( m_PlanterObjects.count == 0 ) &&
		( m_LeavingParticleObjects.count == 0 ) &&
		( m_ScatterParticleUnitObjects.count == 0 ) &&
		( m_ActorModelObjects.count == 0 ) )
	{
		return;
	}

	Mix::Matrix4x4 oldMat = pPerspectiveRenderer->GetMatrix();
	Mix::Vector4 oldColor = pPerspectiveRenderer->GetColor();

	pPerspectiveRenderer->SetMatrix( Mix::Matrix4x4::Identity() );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// ノードの境界
	////////////////////////////////////////////////////////////////////////////////////////////////////

	pPerspectiveRenderer->SetColor( Mix::Scene::Common::Debug::GetDrawColor( Mix::Scene::DDC_OCTREE_NODE_BOUNDS ) );
	pPerspectiveRenderer->AddBox( m_Bounds );

	////////////////////////////////////////////////////////////////////////////////////////////////////
	// オブジェクトの境界
	////////////////////////////////////////////////////////////////////////////////////////////////////

	m_ObjBounds.ComputePoints();

	pPerspectiveRenderer->SetColor( Mix::Scene::Common::Debug::GetDrawColor( Mix::Scene::DDC_OCTREE_OBJS_BOUNDS ) );
	pPerspectiveRenderer->AddBox( m_ObjBounds );

	////////////////////////////////////////////////////////////////////////////////////////////////////

	pPerspectiveRenderer->SetMatrix( oldMat );
	pPerspectiveRenderer->SetColor( oldColor );
}

#endif //_DEBUG

////////////////////////////////////////////////////////////////////////////////////////////////////
// イリーガル
////////////////////////////////////////////////////////////////////////////////////////////////////

const wchar_t* IllegalOctreeNode::NOT_IMPL = L"実装されていません";
const Mix::Geometry::AABB IllegalOctreeNode::DUMMY_BOUNDS( Mix::Vector3::Zero(), Mix::Vector3::Zero() );

IllegalOctreeNode::IllegalOctreeNode( Mix::Scene::Common::Octree* pOwner, UInt32 index ) : OctreeNode( pOwner, index )
{
}

IllegalOctreeNode::~IllegalOctreeNode( void )
{
}

void IllegalOctreeNode::AttachObject( Mix::Scene::Common::LocalLightObject* pObj )
{
	OctreeNode::AttachObject( pObj );
	pObj->m_bIllegal = True;
}

void IllegalOctreeNode::AttachObject( Mix::Scene::Common::LeavingParticleObject* pObj )
{
	OctreeNode::AttachObject( pObj );
	pObj->m_bIllegal = True;
}

void IllegalOctreeNode::AttachObject( Mix::Scene::Common::WaterPoolObject* pObj )
{
	OctreeNode::AttachObject( pObj );
	pObj->m_bIllegal = True;
}

void IllegalOctreeNode::AttachObject( Mix::Scene::Common::PlanterObject* pObj )
{
	OctreeNode::AttachObject( pObj );
	pObj->m_bIllegal = True;
}

void IllegalOctreeNode::AttachObject( Mix::Scene::Common::ScatterParticleUnitObject* pObj )
{
	OctreeNode::AttachObject( pObj );
	pObj->m_bIllegal = True;
}

void IllegalOctreeNode::AttachObject( Mix::Scene::Common::ActorModelObject* pObj )
{
	OctreeNode::AttachObject( pObj );
	pObj->m_bIllegal = True;
}

void IllegalOctreeNode::DetachObject( Mix::Scene::Common::LocalLightObject* pObj )
{
	OctreeNode::DetachObject( pObj );
	pObj->m_bIllegal = False;
}

void IllegalOctreeNode::DetachObject( Mix::Scene::Common::WaterPoolObject* pObj )
{
	OctreeNode::DetachObject( pObj );
	pObj->m_bIllegal = False;
}

void IllegalOctreeNode::DetachObject( Mix::Scene::Common::PlanterObject* pObj )
{
	OctreeNode::DetachObject( pObj );
	pObj->m_bIllegal = False;
}

void IllegalOctreeNode::DetachObject( Mix::Scene::Common::LeavingParticleObject* pObj )
{
	OctreeNode::DetachObject( pObj );
	pObj->m_bIllegal = False;
}

void IllegalOctreeNode::DetachObject( Mix::Scene::Common::ScatterParticleUnitObject* pObj )
{
	OctreeNode::DetachObject( pObj );
	pObj->m_bIllegal = False;
}

void IllegalOctreeNode::DetachObject( Mix::Scene::Common::ActorModelObject* pObj )
{
	OctreeNode::DetachObject( pObj );
	pObj->m_bIllegal = False;
}

UInt8 IllegalOctreeNode::GetChilds( void ) const
{
	MIX_ERROR( IllegalOctreeNode::NOT_IMPL );
	return 0;
}

void IllegalOctreeNode::SetChilds( UInt8 childs )
{
	MIX_ERROR( IllegalOctreeNode::NOT_IMPL );
	( void )childs;
}

void IllegalOctreeNode::ReqRefreshBounds( void )
{
	MIX_ERROR( IllegalOctreeNode::NOT_IMPL );
}

Boolean IllegalOctreeNode::IsReqRefresh( void ) const
{
	//リフレッシュは行わないので、常に True を返して、リフレッシュさせない
	return True;
}

void IllegalOctreeNode::Refresh( void )
{
	MIX_ERROR( IllegalOctreeNode::NOT_IMPL );
}

const Mix::Geometry::AABB& IllegalOctreeNode::GetBounds( void ) const
{
	MIX_ERROR( IllegalOctreeNode::NOT_IMPL );
	return IllegalOctreeNode::DUMMY_BOUNDS;
}

#ifdef _DEBUG

UInt32 IllegalOctreeNode::Debug_GetLocalLightNum( void ) const
{
	return m_LocalLightObjects.count;
}

UInt32 IllegalOctreeNode::Debug_GetWaterPoolNum( void ) const
{
	return m_WaterPoolObjects.count;
}

UInt32 IllegalOctreeNode::Debug_GetPlanterNum( void ) const
{
	return m_PlanterObjects.count;
}

UInt32 IllegalOctreeNode::Debug_GetLeavingParticleNum( void ) const
{
	return m_LeavingParticleObjects.count;
}

UInt32 IllegalOctreeNode::Debug_GetScatterParticleUnitNum( void ) const
{
	return m_ScatterParticleUnitObjects.count;
}

UInt32 IllegalOctreeNode::Debug_GetActorModelNum( void ) const
{
	return m_ActorModelObjects.count;
}

void IllegalOctreeNode::Debug_Draw( Mix::Graphics::Utility::IPerspectiveRenderer* pPerspectiveRenderer, UInt32 flags )
{
	MIX_ERROR( IllegalOctreeNode::NOT_IMPL );
}

#endif //_DEBUG

}}}
