//============================================================
// Program:		GameFrameCamera
// Description:	Class for simplifying camera control
// Author:		Benjamin Gottemoller
// Website:		http://www.particlefield.com
// Date:		4/20/01
// Legal:		Licensed under the gnu GPL (see gpl.txt for details)
//============================================================

/*
static int scan2ascii(DWORD scancode, ushort* result)
{
   static HKL layout=GetKeyboardLayout(0);
   static uchar State[256];

   if (GetKeyboardState(State)==FALSE)
      return 0;
   UINT vk=MapVirtualKeyEx(scancode,1,layout);
   return ToAsciiEx(vk,scancode,State,result,0,layout);
}
*/

#include "GameFrameCamera.h"
#include "GameFrameParticleSystem.h"
#include "GameFrameSolarSystem.h"
#include "GameFrame.h"

CGFCamera::CGFCamera()
{
	GFParent = NULL;
	ActionFlags = 0;
	Reset();
}

CGFCamera::~CGFCamera()
{
	Destroy();
}

void CGFCamera::Initialize(GameFrame *gfparent)
{
	Reset();
	GFParent = gfparent;
	ActionFlags = 0;
	memset(&Bindings, -1, sizeof(CONTROL_BINDINGS));

	Arsenal.Initialize(GFParent, this, 20);
}

void CGFCamera::LoadKeyBindings(char *file)
{
	FILE *fp = NULL;
	fp = fopen(file, "rt");
	if(fp != NULL)
	{
		fscanf(fp, "MouseSensitivity: %f\n",	&(Bindings.MouseSensitivity));
		fscanf(fp, "YawPlus: %d\n",				&(Bindings.YawPlus.Key));
		fscanf(fp, "YawMinus: %d\n",			&(Bindings.YawMinus.Key));
		fscanf(fp, "PitchPlus: %d\n",			&(Bindings.PitchPlus.Key));
		fscanf(fp, "PitchMinus: %d\n",			&(Bindings.PitchMinus.Key));
		fscanf(fp, "RollPlus: %d\n",			&(Bindings.RollPlus.Key));
		fscanf(fp, "RollMinus: %d\n",			&(Bindings.RollMinus.Key));
		fscanf(fp, "Forward: %d, %d\n",			&(Bindings.Forward.Key),			&(Bindings.Forward.Mouse));
		fscanf(fp, "Reverse: %d, %d\n",			&(Bindings.Reverse.Key),			&(Bindings.Reverse.Mouse));
		fscanf(fp, "Left: %d, %d\n",			&(Bindings.Left.Key),				&(Bindings.Left.Mouse));
		fscanf(fp, "Right: %d, %d\n",			&(Bindings.Right.Key),				&(Bindings.Right.Mouse));
		fscanf(fp, "Up: %d, %d\n",				&(Bindings.Up.Key),					&(Bindings.Up.Mouse));
		fscanf(fp, "Down: %d, %d\n",			&(Bindings.Down.Key),				&(Bindings.Down.Mouse));
		fscanf(fp, "Afterburner: %d, %d\n",		&(Bindings.Afterburner.Key),		&(Bindings.Afterburner.Mouse));
		fscanf(fp, "FirePrimary: %d, %d\n",		&(Bindings.FirePrimary.Key),		&(Bindings.FirePrimary.Mouse));
		fscanf(fp, "FireSecondary: %d, %d\n",	&(Bindings.FireSecondary.Key),		&(Bindings.FireSecondary.Mouse));
		fscanf(fp, "WeaponWheel: %d\n",			&(Bindings.WeaponWheel));
		fscanf(fp, "NextWeapon: %d\n",			&(Bindings.NextWeapon.Key));
		fscanf(fp, "PreviousWeapon: %d\n",		&(Bindings.PreviousWeapon.Key));
		fscanf(fp, "ZoomIn: %d, %d\n",			&(Bindings.ZoomIn.Key),				&(Bindings.ZoomIn.Mouse));
		fscanf(fp, "ZoomOut: %d, %d\n",			&(Bindings.ZoomOut.Key),			&(Bindings.ZoomOut.Mouse));
		fscanf(fp, "ToggleWarpDrive: %d, %d\n",	&(Bindings.ToggleWarpDrive.Key),	&(Bindings.ToggleWarpDrive.Mouse));
		fclose(fp);
	}
	else
	{

	}
}

void CGFCamera::SaveKeyBindings(char *file)
{
	FILE *fp = NULL;
	fp = fopen(file, "wt");
	if(fp != NULL)
	{
		fprintf(fp, "MouseSensitivity: %f\n",		Bindings.MouseSensitivity);
		fprintf(fp, "YawPlus: %d\n",				Bindings.YawPlus.Key);
		fprintf(fp, "YawMinus: %d\n",				Bindings.YawMinus.Key);
		fprintf(fp, "PitchPlus: %d\n",				Bindings.PitchPlus.Key);
		fprintf(fp, "PitchMinus: %d\n",				Bindings.PitchMinus.Key);
		fprintf(fp, "RollPlus: %d\n",				Bindings.RollPlus.Key);
		fprintf(fp, "RollMinus: %d\n",				Bindings.RollMinus.Key);
		fprintf(fp, "Forward: %d, %d\n",			Bindings.Forward.Key,			Bindings.Forward.Mouse);
		fprintf(fp, "Reverse: %d, %d\n",			Bindings.Reverse.Key,			Bindings.Reverse.Mouse);
		fprintf(fp, "Left: %d, %d\n",				Bindings.Left.Key,				Bindings.Left.Mouse);
		fprintf(fp, "Right: %d, %d\n",				Bindings.Right.Key,				Bindings.Right.Mouse);
		fprintf(fp, "Up: %d, %d\n",					Bindings.Up.Key,				Bindings.Up.Mouse);
		fprintf(fp, "Down: %d, %d\n",				Bindings.Down.Key,				Bindings.Down.Mouse);
		fprintf(fp, "Afterburner: %d, %d\n",		Bindings.Afterburner.Key,		Bindings.Afterburner.Mouse);
		fprintf(fp, "FirePrimary: %d, %d\n",		Bindings.FirePrimary.Key,		Bindings.FirePrimary.Mouse);
		fprintf(fp, "FireSecondary: %d, %d\n",		Bindings.FireSecondary.Key,		Bindings.FireSecondary.Mouse);
		fprintf(fp, "WeaponWheel: %d\n",			Bindings.WeaponWheel);
		fprintf(fp, "NextWeapon: %d\n",				Bindings.NextWeapon.Key);
		fprintf(fp, "PreviousWeapon: %d\n",			Bindings.PreviousWeapon.Key);
		fprintf(fp, "ZoomIn: %d, %d\n",				Bindings.ZoomIn.Key,			Bindings.ZoomIn.Mouse);
		fprintf(fp, "ZoomOut: %d, %d\n",			Bindings.ZoomOut.Key,			Bindings.ZoomOut.Mouse);
		fprintf(fp, "ToggleWarpDrive: %d, %d\n",	Bindings.ToggleWarpDrive.Key,	Bindings.ToggleWarpDrive.Mouse);
		fclose(fp);
	}
}

void CGFCamera::EnableGravity(CGFSolarSystem *sys)
{
	SolarSystem = sys;
}

void CGFCamera::Reset(void)
{
	Up_Vector = D3DXVECTOR3(0,1,0);
	Right_Vector = D3DXVECTOR3(1,0,0);
	Look_Vector = D3DXVECTOR3(0,0,1);

	X = Y = Z = 0;
	XVec = YVec = ZVec = 0;

	Yaw = Pitch = Roll = 0;
	YawVel = PitchVel = RollVel = 0; 

	IsWarpDriveOn = 0;
	WarpFactor = 1;
	ZoomFactor = 100.0f;
}

void CGFCamera::Destroy(void)
{
	GFParent = NULL;
	ActionFlags = 0;
	Arsenal.Destroy();
}

void CGFCamera::SetActionFlags(DWORD flags)
{
	ActionFlags = flags;
}

void CGFCamera::Move(DWORD type, DWORD direction, float speed)
{
	if(GFParent->IsGamePaused || GFParent->IsGameLocked) return;

	float scalar = speed * GFParent->GetTimeDiff();

	if(type & CAMERA_MOTION_STEADY)
	{
		if(direction & CAMERA_FORWARD)
		{
			X += scalar * Look_Vector.x;
			Y += scalar * Look_Vector.y;
			Z += scalar * Look_Vector.z;
		}
		else
		if(direction & CAMERA_RIGHT)
		{
			X += scalar * Right_Vector.x;
			Y += scalar * Right_Vector.y;
			Z += scalar * Right_Vector.z;
		}
		else
		if(direction & CAMERA_UP)
		{
			X += scalar * Up_Vector.x;
			Y += scalar * Up_Vector.y;
			Z += scalar * Up_Vector.z;
		}
	}
	else
	if(type & CAMERA_MOTION_ACCELERATE)
	{
		if(direction & CAMERA_FORWARD)
		{
			XVec += scalar * Look_Vector.x;
			YVec += scalar * Look_Vector.y;
			ZVec += scalar * Look_Vector.z;
		}
		else
		if(direction & CAMERA_RIGHT)
		{
			XVec += scalar * Right_Vector.x;
			YVec += scalar * Right_Vector.y;
			ZVec += scalar * Right_Vector.z;
		}
		else
		if(direction & CAMERA_UP)
		{
			XVec += scalar * Up_Vector.x;
			YVec += scalar * Up_Vector.y;
			ZVec += scalar * Up_Vector.z;
		}
	}
}

void CGFCamera::Rotate(DWORD type, float speed)
{
	if(GFParent->IsGamePaused || GFParent->IsGameLocked) return;

	float scalar = speed * GFParent->GetTimeDiff();

	if(type & CAMERA_YAW)
	{
		Yaw += scalar;
	}
	else
	if(type & CAMERA_PITCH)
	{
		Pitch += scalar;
		//if(Pitch > PI/2) Pitch = PI/2;
		//if(Pitch < -PI/2) Pitch = -PI/2;
	}
	else
	if(type & CAMERA_ROLL)
	{
		Roll += scalar;
	}
}

void CGFCamera::UpdateCamera(void)
{
	float scalar = GFParent->GetTimeDiff();
	ProcessInput();

	if(GFParent->IsGamePaused || GFParent->IsGameLocked) return;

	if(ActionFlags & CAMERA_ACTION_AUTOLEVEL)
	{
		if(Roll < -.02f) Roll += .01f;
		else
		if(Roll > .02f) Roll -= .01f;
	}

	X += XVec * scalar;
	Y += YVec * scalar;
	Z += ZVec * scalar;
	Yaw += YawVel * scalar;
	Pitch += PitchVel * scalar;
	Roll += RollVel * scalar;

	if(IsWarpDriveOn)
	{
		if(WarpFactor < 20.0f)
		{
			WarpFactor += 6.25f * scalar;
		}
		else
		{
			if(!GFParent->Sound.IsPlaying(1))
			{
				GFParent->Sound.PlaySound(1);
				GFParent->Sound.SetRepeats(1);
			}
		}
	}
	else
	{
		if(WarpFactor > 1.0f)
		{
			WarpFactor -= 6.25f * scalar;
		}

		if(GFParent->Sound.IsPlaying(1))
		{
			GFParent->Sound.StopSound(1);
		}
	}


	if((SolarSystem != NULL) && (!IsWarpDriveOn))
	{
		D3DXVECTOR3 v;
		double distsq = 0;
		double force = 0;
		double accel = 0;
		double limit = 0;

		for(int i=0; i<SolarSystem->NumPlanetsUsed; i++)	
		{
			v.x = SolarSystem->Planets[i].X - X;
			v.y = SolarSystem->Planets[i].Y - Y;
			v.z = SolarSystem->Planets[i].Z - Z;
			distsq = (double) D3DXVec3LengthSq(&v);
		
			limit = SolarSystem->Planets[i].PlanetRadius;
			limit *= limit;

			if(ABS(distsq) > limit)
			{
				force = Gc * SolarSystem->Planets[i].Mass / distsq;
				D3DXVec3Normalize(&v, &v);
									
				accel = scalar * force;
				XVec += v.x * (float)accel;
				YVec += v.y * (float)accel;
				ZVec += v.z * (float)accel;
			}				
		}

		for(int i=0; i<SolarSystem->NumSunsUsed; i++)
		{
			v.x = SolarSystem->Suns[i].X - X;
			v.y = SolarSystem->Suns[i].Y - Y;
			v.z = SolarSystem->Suns[i].Z - Z;
			distsq = (double) D3DXVec3LengthSq(&v);
		
			limit = SolarSystem->Suns[i].SunRadius;
			limit *= limit;

			if(ABS(distsq) > limit)
			{
				force = Gc * SolarSystem->Suns[i].Mass / distsq;
				D3DXVec3Normalize(&v, &v);
				
				accel = scalar * force;
				XVec += v.x * (float)accel;
				YVec += v.y * (float)accel;
				ZVec += v.z * (float)accel;
			}
		}
	}

}

void CGFCamera::ProcessInput(void)
{
	int play_index = 0;

	float data = 0;
	float default_rot_speed = 0.84f;
//	float default_forward_accel = 1.0f;
//	float default_reverse_accel = -0.5f;
//	float default_horizontal_accel = 0.5f;
//	float default_vertical_accel = 0.5f;
	float default_forward_accel = 3.0f;
	float default_reverse_accel = -2.5f;
	float default_horizontal_accel = 2.0f;
	float default_vertical_accel = 2.0f;

	static float afterburner_boost = 0;
	float default_warp_speed = 4000.0f;

	if(GFParent->KEYDOWN(DIK_P))
	{
		static float PauseLastTime = 0;
		if((GFParent->GetTime() - PauseLastTime) > 0.450f)
		{
			if(GFParent->IsGamePaused == 0)
			{
				GFParent->IsGamePaused = 1;
			}
			else
			{
				GFParent->IsGamePaused = 0;
			}

			PauseLastTime = GFParent->GetTime();
		}
	}

	if(GFParent->KEYDOWN(DIK_F12))
	{
		static float LastTime = 0;
		char msg[256];
		char tm[100];
		if((GFParent->GetTime() - LastTime) > 1.000f)
		{
			GetTimeFormat(LOCALE_SYSTEM_DEFAULT, 0, NULL, "hh'_'mm'_'ss tt", tm, 100);
			sprintf(msg, "ScreenShot[%s].bmp", tm);
			GFParent->TakeScreenShot(msg);
			LastTime = GFParent->GetTime();
		}
	}

	/***************Yaw, Pitch, and Roll************************************************/
	Rotate(CAMERA_YAW, Bindings.MouseSensitivity * GFParent->MOUSEMESSAGE(MOUSE_X));
	Rotate(CAMERA_PITCH, Bindings.MouseSensitivity * GFParent->MOUSEMESSAGE(MOUSE_Y));

	if(GFParent->KEYDOWN(Bindings.YawPlus.Key))
	{
		Rotate(CAMERA_YAW, +default_rot_speed);
	}
	if(GFParent->KEYDOWN(Bindings.YawMinus.Key))
	{
		Rotate(CAMERA_YAW, -default_rot_speed);
	}

	if(GFParent->KEYDOWN(Bindings.PitchPlus.Key))
	{
		Rotate(CAMERA_PITCH, -default_rot_speed);
	}
	if(GFParent->KEYDOWN(Bindings.PitchMinus.Key))
	{
		Rotate(CAMERA_PITCH, +default_rot_speed);
	}

	if(GFParent->KEYDOWN(Bindings.RollPlus.Key))
	{
		Rotate(CAMERA_ROLL, +default_rot_speed);
	}
	if(GFParent->KEYDOWN(Bindings.RollMinus.Key))
	{
		Rotate(CAMERA_ROLL, -default_rot_speed);
	}
	
	/***********************************************************************************/

	/***************X,Y,Z Motion********************************************************/
	play_index = 0;
	if(GFParent->KEYDOWN(Bindings.Forward.Key) || (GFParent->MOUSEMESSAGE(Bindings.Forward.Mouse) == 1))
	{
		if(IsWarpDriveOn)
		{
			Move(CAMERA_MOTION_STEADY, CAMERA_FORWARD, +default_warp_speed);
		}
		else
		{
			if(!GFParent->Sound.IsPlaying(3))
			{
				GFParent->Sound.PlaySound(3);
			}
			GFParent->Sound.SetRepeats(3);

			Move(CAMERA_MOTION_ACCELERATE, CAMERA_FORWARD, +default_forward_accel + afterburner_boost);
		}
	}
	else
	{
		GFParent->Sound.StopSound(3);
	}

	if(GFParent->KEYDOWN(Bindings.Reverse.Key) || (GFParent->MOUSEMESSAGE(Bindings.Reverse.Mouse) == 1))
	{
		if(IsWarpDriveOn)
		{
			Move(CAMERA_MOTION_STEADY, CAMERA_FORWARD, -default_warp_speed);
		}
		else
		{
			play_index = 4;
			Move(CAMERA_MOTION_ACCELERATE, CAMERA_FORWARD, +default_reverse_accel);
		}		
	}

	if(GFParent->KEYDOWN(Bindings.Left.Key) || (GFParent->MOUSEMESSAGE(Bindings.Left.Mouse) == 1))
	{
		if(IsWarpDriveOn)
		{
			Move(CAMERA_MOTION_STEADY, CAMERA_RIGHT, -default_warp_speed);
		}
		else
		{
			play_index = 4;
			Move(CAMERA_MOTION_ACCELERATE, CAMERA_RIGHT, -default_horizontal_accel);
		}		
	}

	if(GFParent->KEYDOWN(Bindings.Right.Key) || (GFParent->MOUSEMESSAGE(Bindings.Right.Mouse) == 1))
	{
		if(IsWarpDriveOn)
		{
			Move(CAMERA_MOTION_STEADY, CAMERA_RIGHT, +default_warp_speed);
		}
		else
		{
			play_index = 4;
			Move(CAMERA_MOTION_ACCELERATE, CAMERA_RIGHT, +default_horizontal_accel);
		}		
	}

	if(GFParent->KEYDOWN(Bindings.Up.Key) || (GFParent->MOUSEMESSAGE(Bindings.Up.Mouse) == 1))
	{
		if(IsWarpDriveOn)
		{
			Move(CAMERA_MOTION_STEADY, CAMERA_UP, +default_warp_speed);
		}
		else
		{
			play_index = 4;
			Move(CAMERA_MOTION_ACCELERATE, CAMERA_UP, +default_vertical_accel);
		}
	}
	if(GFParent->KEYDOWN(Bindings.Down.Key) || (GFParent->MOUSEMESSAGE(Bindings.Down.Mouse) == 1))
	{
		if(IsWarpDriveOn)
		{
			Move(CAMERA_MOTION_STEADY, CAMERA_UP, -default_warp_speed);
		}
		else
		{
			play_index = 4;
			Move(CAMERA_MOTION_ACCELERATE, CAMERA_UP, -default_vertical_accel);
		}		
	}
	
	if(play_index == 4)
	{
		if(!GFParent->Sound.IsPlaying(4))
		{
			GFParent->Sound.PlaySound(4);
		}
		GFParent->Sound.SetRepeats(4);
	}
	else
	{
		GFParent->Sound.StopSound(4);
	}
	/***********************************************************************************/

	/***************Afterburner*********************************************************/
	if(GFParent->KEYDOWN(Bindings.Afterburner.Key) || (GFParent->MOUSEMESSAGE(Bindings.Afterburner.Mouse) == 1))
	{
		if(!IsWarpDriveOn)
		{
			afterburner_boost = 30.0f;
		}
	}
	else
	{
		afterburner_boost = 0;
	}
	/***********************************************************************************/

	/***************Fire Weapons********************************************************/
	if(GFParent->KEYDOWN(Bindings.FirePrimary.Key) || (GFParent->MOUSEMESSAGE(Bindings.FirePrimary.Mouse) == 1))
	{
		if(!IsWarpDriveOn)
		{
			Arsenal.FirePrimary();
		}
	}

	if(GFParent->KEYDOWN(Bindings.FireSecondary.Key) || (GFParent->MOUSEMESSAGE(Bindings.FireSecondary.Mouse) == 1))
	{
		if(!IsWarpDriveOn)
		{
			Arsenal.FireSecondary();
		}
	}
	/***********************************************************************************/

	/***************Change Weapons******************************************************/
	static float WeaponChangeLastTime = 0;
	if((GFParent->GetTime() - WeaponChangeLastTime) > 0.150f)
	{
		if(Bindings.WeaponWheel && (!GFParent->IsGamePaused))
		{
			data = GFParent->MOUSEMESSAGE(MOUSE_Z);
			if((int)data == 1)
			{
				Arsenal.PreviousPrimary();
				Arsenal.PreviousSecondary();
				WeaponChangeLastTime = GFParent->GetTime();
			}
			else
			if((int)data == -1)
			{
				Arsenal.NextPrimary();
				Arsenal.NextSecondary();
				WeaponChangeLastTime = GFParent->GetTime();
			}
		}

		if(GFParent->KEYDOWN(Bindings.NextWeapon.Key) && (!GFParent->IsGamePaused))
		{
			Arsenal.NextPrimary();
			Arsenal.NextSecondary();
			WeaponChangeLastTime = GFParent->GetTime();
		}
		else
		if(GFParent->KEYDOWN(Bindings.PreviousWeapon.Key) && (!GFParent->IsGamePaused))
		{
			Arsenal.PreviousPrimary();
			Arsenal.PreviousSecondary();
			WeaponChangeLastTime = GFParent->GetTime();
		}	
	}
	/***********************************************************************************/

	/***************Zoom In/Out*********************************************************/
	if(GFParent->KEYDOWN(Bindings.ZoomIn.Key) || (GFParent->MOUSEMESSAGE(Bindings.ZoomIn.Mouse) == 1))
	{
		if((ZoomFactor < 10000.0f) && (!GFParent->IsGamePaused))
		{
			ZoomFactor += 1.0f;
		}
	}

	if(GFParent->KEYDOWN(Bindings.ZoomOut.Key) || (GFParent->MOUSEMESSAGE(Bindings.ZoomOut.Mouse) == 1))
	{
		if((ZoomFactor > 1.0f) && (!GFParent->IsGamePaused))
		{
			ZoomFactor -= 1.0f;
		}
	}
	/***********************************************************************************/

	/***************Toggle Warp Drive***************************************************/
	static float WarpToggleLastTime = 0;
	static float last_xvec = 0, last_yvec = 0, last_zvec = 0;
	if(((GFParent->GetTime() - WarpToggleLastTime) > 4) && (!GFParent->IsGamePaused))
	{
		if(GFParent->KEYDOWN(Bindings.ToggleWarpDrive.Key) || (GFParent->MOUSEMESSAGE(Bindings.ToggleWarpDrive.Mouse) == 1))
		{
			if(IsWarpDriveOn == 0) 
			{
				GFParent->Sound.PlaySound(0);
				
				last_xvec = XVec;
				last_yvec = YVec;
				last_zvec = ZVec;
				XVec = YVec = ZVec = 0;
				IsWarpDriveOn = 1;
			}
			else
			{
				GFParent->Sound.PlaySound(2);

				XVec = last_xvec;
				YVec = last_yvec;
				ZVec = last_zvec;
				last_xvec = last_yvec = last_zvec = 0;
				IsWarpDriveOn = 0;
			}
			WarpToggleLastTime = GFParent->GetTime();
		}
	}
	/***********************************************************************************/
}

void CGFCamera::DoCamera(D3DXMATRIX *modifier)
{
	if(GFParent == NULL) return;
	if(GFParent->IsGameLocked) return;

	D3DXMATRIX YawMat, PitchMat, RollMat;
	D3DXMATRIX ViewMat, WarpMat;

	Up_Vector = D3DXVECTOR3(0,1,0);
	Right_Vector = D3DXVECTOR3(1,0,0);
	Look_Vector = D3DXVECTOR3(0,0,1);

	D3DXMatrixRotationAxis(&YawMat, &Up_Vector, Yaw);
	D3DXVec3TransformCoord(&Look_Vector, &Look_Vector, &YawMat);
	D3DXVec3TransformCoord(&Right_Vector, &Right_Vector, &YawMat);

	D3DXMatrixRotationAxis(&PitchMat, &Right_Vector, Pitch);
	D3DXVec3TransformCoord(&Look_Vector, &Look_Vector, &PitchMat);
	D3DXVec3TransformCoord(&Up_Vector, &Up_Vector, &PitchMat);

	D3DXMatrixRotationAxis(&RollMat, &Look_Vector, Roll);
	D3DXVec3TransformCoord(&Up_Vector, &Up_Vector, &RollMat);
	D3DXVec3TransformCoord(&Right_Vector, &Right_Vector, &RollMat);

	D3DXMatrixIdentity(&ViewMat);

	ViewMat._11 = Right_Vector.x;	ViewMat._12 = Up_Vector.x;	ViewMat._13 = Look_Vector.x;
	ViewMat._21 = Right_Vector.y;	ViewMat._22 = Up_Vector.y;	ViewMat._23 = Look_Vector.y;
	ViewMat._31 = Right_Vector.z;	ViewMat._32 = Up_Vector.z;	ViewMat._33 = Look_Vector.z;
	ViewMat._41 = - ((X * Right_Vector.x) + (Y * Right_Vector.y) + (Z * Right_Vector.z));	
	ViewMat._42 = - ((X * Up_Vector.x)    + (Y * Up_Vector.y)    + (Z * Up_Vector.z));
	ViewMat._43 = - ((X * Look_Vector.x)  + (Y * Look_Vector.y)  + (Z * Look_Vector.z));

	if(modifier == NULL)
	{
		D3DXMatrixScaling(&WarpMat, 1.0f, 1.0f, WarpFactor);
		ViewMat = ViewMat * WarpMat;
	}

	if(modifier != NULL) ViewMat = ViewMat * (*modifier);

	GFParent->D3DDevice->SetTransform(D3DTS_VIEW, &ViewMat);
}
