#include "stdafx.h"
#include "depthplaneobject.h"

#include "CameraManager.h"

cDepthPlaneObject::cDepthPlaneObject( cDepthPlaneData* pdata )
: NiTriShape(pdata)
{
}

cDepthPlaneObject::~cDepthPlaneObject()
{
}

void cDepthPlaneObject::Draw( NiRenderer* pRenderer )
{
	RenderImmediate( pRenderer );
}

void cDepthPlaneObject::OnUpdate( NiCamera* pcamera )
{
	RotateToCamera( pcamera );
	UpdateWorldBound();
}

void cDepthPlaneObject::UpdateWorldBound()
{
	Data()->UpdateBound();

	NiTriShape::UpdateWorldBound();
}

void cDepthPlaneObject::SetColor( const NiColorA& color )
{
	Data()->SetColor( color );
}

void cDepthPlaneObject::SetAlpha( float alpha )
{
	Data()->SetAlpha( alpha );
}

void cDepthPlaneObject::ReSize( unsigned int width, unsigned int height )
{
	Data()->ReSize( width, height );
}

void cDepthPlaneObject::ReScale( float scaleX, float scaleY )
{
	Data()->ReScale( scaleX, scaleY );
}

void cDepthPlaneObject::SetTextureRect( float left, float top, float right, float bottom )
{
	Data()->SetTextureRect( left, top, right, bottom );
}

void cDepthPlaneObject::RotateToCamera( const NiCamera* pCamera )
{
	// get parent world transforms
//	NiNode* pkParent = GetParent();
	NiTransform kParentXform;

//	if (pkParent)
//	{
//		kParentXform = pkParent->GetWorldTransform();
//	}
//	else
//	{
	kParentXform.MakeIdentity();
//	}

	// compute billboard's world transforms
	m_kWorld = kParentXform * m_kLocal;

	// additional orienting of billboard based on selected mode
	NiMatrix3 kFaceMat = NiMatrix3::IDENTITY;

	// billboard coordinates for world axes of camera
	NiPoint3 kCamD, kCamU, kCamR;
	kCamD = -pCamera->GetWorldDirection(); 
	kCamU = pCamera->GetWorldUpVector();
	kCamR = pCamera->GetWorldRightVector();

	kCamD = kCamD * m_kWorld.m_Rotate;
	kCamU = kCamU * m_kWorld.m_Rotate;
	kCamR = kCamR * m_kWorld.m_Rotate;

	// Rotated model up vector is that vector in the plane
	// orthogonal to the camera direction which minimizes the angle
	// between it and the original model up (0,1,0).
	float fRoot = NiSqrt(kCamR.z*kCamR.z+kCamU.z*kCamU.z);
	if (fRoot > 1e-06f)
	{
		float fInvRoot = 1.0f/fRoot;
		float fCos = kCamU.z*fInvRoot;
		float fSin = -kCamR.z*fInvRoot;
		kFaceMat.SetCol(0, fCos*kCamR.x+fSin*kCamU.x, fCos*kCamR.y+fSin*kCamU.y, fCos*kCamR.z+fSin*kCamU.z);
		kFaceMat.SetCol(1, -kCamD );
		kFaceMat.SetCol(2, fSin*kCamR.x+fCos*kCamU.x, fSin*kCamR.y+fCos*kCamU.y, fSin*kCamR.z+fCos*kCamU.z);
	}
	else
	{
		kFaceMat.SetCol(0, -kCamR);
		kFaceMat.SetCol(1, -kCamD);
		kFaceMat.SetCol(2, kCamU);
	}

	// adjust the billboard before applying its world transform
	m_kWorld.m_Rotate = m_kWorld.m_Rotate * kFaceMat;
}