///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// ZCamera Class
///
///		- Camera class
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////




#include	"..\Scene Graph\ZooCamera.h"

///////////////////////////////////////////////////////////////////////////
/// Constructor	& Destructor		      								///
///////////////////////////////////////////////////////////////////////////
ZCamera::ZCamera(int s3d) : ZNodeGraph(s3d)
{
	type = CAM_TYPE_ID;
}

ZCamera::~ZCamera()
{
	ZNodeGraph::~ZNodeGraph();
}





///////////////////////////////////////////////////////////////////////////
/// Compute the matrix of camera space    								///
///////////////////////////////////////////////////////////////////////////
void ZCamera::ComputeMatrix()
{
	///////////////////////////////////////
	///	Vision matrix computing			///
	///////////////////////////////////////

	// SCOL integration
	float	newfov	  = (atan2((double)(height/2),(double)dy)*180.0) / 3.1415926535;
	fov = newfov;

	if(userACCEL)
	{
		// Recuperation de la matrice de projective, via OpenGL
		int ModeActuel;
		glGetIntegerv(GL_MATRIX_MODE, &ModeActuel);

		glMatrixMode(GL_PROJECTION);

		glPushMatrix();
		glLoadIdentity();
		gluPerspective(newfov*2, ((float)width)/((float)height), Znear, Zfar);
		glGetFloatv(GL_PROJECTION_MATRIX, visionMatx.matxArray);
		glPopMatrix();

		glMatrixMode(ModeActuel);
	}
	else
	{
		float	top		= Znear * ((float)(height/2)) / ((float)dy);
		float	right	= top * ((float)width/(float)height);

		visionMatx.IdentityMatrix();
		visionMatx._11 = Znear/right;
		visionMatx._22 = Znear/top;
		visionMatx._33 = -(Zfar+Znear) / (Zfar-Znear);
		visionMatx._43 = -1;
		visionMatx._34 = -2.0f*Zfar*Znear / (Zfar-Znear);
	}


	///////////////////////////////////////
	///	Camera matrix computing			///
	///////////////////////////////////////

	// Sauvegarde de la VRAI matrice de la camera dans le world Space
	RealWorldMat = worldMat;

	ZMatrix		matx;
	matx = worldMat * (1.0f/worldScale);
	matx._14 = matx._24 = matx._34 = 0.0f;

	RealWorldAngles = matx.GetAnglesYXZ();		// YXZ car provient de la matrice de rotation calculée par :  Ry.Rx.Rz
	RealWorldPos	= worldPos;

	cameraMatx.RotateYXZMatrix(0.0174532925f * RealWorldAngles);
	cameraMatx.Transpose();
	cameraMatx *= TranslateMatrix(-RealWorldPos.x, -RealWorldPos.y, -RealWorldPos.z);
}



///////////////////////////////////////////////////////////////////////////
/// Compute the matrix of camera space    								///
///////////////////////////////////////////////////////////////////////////
void ZCamera::ComputeMatrixOrtho()
{
	///////////////////////////////////////
	///	Vision matrix computing			///
	///////////////////////////////////////

	visionMatx.IdentityMatrix();
	visionMatx._11 = ((float)dx) / 5.0f / ((float)width);
	visionMatx._22 = ((float)dy) / 5.0f / ((float)height);
	visionMatx._33 = 0;	visionMatx._34 = 1;

	///////////////////////////////////////
	///	Camera matrix computing			///
	///////////////////////////////////////

	ZMatrix		matx;
	matx = worldMat * (1.0f/worldScale);
	matx._14 = matx._24 = matx._34 = 0.0f;

	RealWorldAngles = matx.GetAnglesYXZ();		// YXZ car provient de la matrice de rotation calculée par :  Ry.Rx.Rz
	RealWorldPos	= worldPos;

	cameraMatx.RotateYXZMatrix(0.0174532925f * RealWorldAngles);
	cameraMatx.Transpose();
	cameraMatx *= TranslateMatrix(-RealWorldPos.x, -RealWorldPos.y, -RealWorldPos.z);
}



