#include "stdafx.h"
#include "CullingProcess.h"
#include "SceneNode.h"

#include "stdafx.h"
#include "cullingprocess.h"
#include "SceneNode.h"

cCullingProcess::cCullingProcess( NiVisibleArray* palphaArray, NiVisibleArray* psolidArray )
: NiCullingProcess( psolidArray, true )
{
	assert( palphaArray && "null alpha node array" );

	mpAlphaArray = palphaArray;
}

cCullingProcess::~cCullingProcess()
{
}

void cCullingProcess::Process( const NiCamera* pcamera, cSceneNode* pnode )
{
	if( pcamera == 0 || pnode == 0 )
	{
		assert( 0 && "null camera or null node" );
		return;
	}

	NiAVObject* pobj = pnode->GetNiObject();
	if( pobj == 0 )
	{
		return;
	}

	NiCullingProcess::Process( pcamera, pobj, NULL );
}

void cCullingProcess::AppendVirtual( NiGeometry& geom )
{
	mpAlphaArray->Add( geom );
}

void cCullingProcess::Process( NiAVObject* pobj )
{
	if( !m_kPlanes.IsAnyPlaneActive() )
	{
		pobj->OnVisible(*this);
	}
	else
	{
		/// Determine if the object is not visible by comparing its world
		/// bound to each culling plane.
		unsigned int saveActive = m_kPlanes.GetActivePlaneState();

		unsigned int i;
		for( i = 0; i<NiFrustumPlanes::MAX_PLANES; i++ )
		{
			if( m_kPlanes.IsPlaneActive( i ) )
			{
				int iSide = pobj->GetWorldBound().WhichSide( m_kPlanes.GetPlane(i) );

				if( iSide == NiPlane::NEGATIVE_SIDE )
				{
					/// The object is not visible since it is on the negative
					/// side of the plane.
					break;
				}

				if( iSide == NiPlane::POSITIVE_SIDE )
				{
					/// The object is fully on the positive side of the plane,
					/// so there is no need to compare child objects to this
					/// plane.
					m_kPlanes.DisablePlane( i );
				}
			}
		}

		if( i == NiFrustumPlanes::MAX_PLANES )
		{
			if( NiIsKindOf(NiNode, pobj) )
			{
				int a = 0;
				a = 1;
			}

			pobj->OnVisible( *this );
		}

		m_kPlanes.SetActivePlaneState( saveActive );
	}
}

void cCullingProcess::Process(const NiCamera* pkCamera, NiAVObject* pkScene, NiVisibleArray* pkVisibleSet)
{
	NiCullingProcess::Process(pkCamera, pkScene, pkVisibleSet);
}
