/*************************************************************************
Crytek Source File.
Copyright (C), Crytek Studios, 2001-2005.
-------------------------------------------------------------------------
$Id$
$DateTime$
Description: Implements a parachute vehicle movement

-------------------------------------------------------------------------
History:
- 14:07:2005: Created by Julien Darre

*************************************************************************/
#include "StdAfx.h"
#include "VehicleMovementParachute.h"
//#include "IRenderAuxGeom.h"

//-----------------------------------------------------------------------------------------------------

CVehicleMovementParachute::CVehicleMovementParachute()
{ 
	ReadFile("Game\\Scripts\\Entities\\Vehicles\\FlightDynamics\\ParachuteLift.txt",&m_LiftPointsMap);
	ReadFile("Game\\Scripts\\Entities\\Vehicles\\FlightDynamics\\ParachuteDrag.txt",&m_DragPointsMap);
}

//-----------------------------------------------------------------------------------------------------

CVehicleMovementParachute::~CVehicleMovementParachute()
{
}

//-----------------------------------------------------------------------------------------------------

void CVehicleMovementParachute::AddCel(int _iID,SWing *_pCel)
{
	IPhysicalWorld *pPhysicalWorld = GetISystem()->GetIPhysicalWorld();

	primitives::box geomBox;
	geomBox.Basis = Matrix33::CreateRotationXYZ(Ang3(DEG2RAD(_pCel->fAngleX),DEG2RAD(_pCel->fAngleY),0.0f));
	geomBox.bOriented = 1;
	geomBox.center.Set(0.0f,0.0f,0.0f);
	geomBox.size = _pCel->vSize;
	IGeometry *pGeom = pPhysicalWorld->GetGeomManager()->CreatePrimitive(primitives::box::type,&geomBox);
	phys_geometry *physGeom = pPhysicalWorld->GetGeomManager()->RegisterGeometry(pGeom);
	pGeom->Release();

	pe_geomparams partpos;
	partpos.pos		= _pCel->vPos;
	partpos.mass	= _pCel->fMass;
	m_pPhysics->AddGeometry(physGeom,&partpos,_iID);

	pPhysicalWorld->GetGeomManager()->UnregisterGeometry(physGeom);
}

//-----------------------------------------------------------------------------------------------------

bool CVehicleMovementParachute::Init(IVehicle *_pVehicle,const SmartScriptTable &_rSmartScriptTable)
{
	if(!CVehicleMovementBase::Init(_pVehicle,_rSmartScriptTable))
	{
		return false;
	}

  m_maxSpeed = 100.f;

	float fSizeY = 1.9f;
	float fPosY = 0.25f;

	m_aCels[0].vSize = Vec3(0.6f,fSizeY,0.2f);
	m_aCels[1].vSize = Vec3(0.6f,fSizeY,0.2f);
	m_aCels[2].vSize = Vec3(0.6f,fSizeY,0.2f);
	m_aCels[3].vSize = Vec3(1.1f,fSizeY,0.2f);
	m_aCels[4].vSize = Vec3(0.6f,fSizeY,0.2f);
	m_aCels[5].vSize = Vec3(0.6f,fSizeY,0.2f);
	m_aCels[6].vSize = Vec3(0.6f,fSizeY,0.2f);

	m_aCels[0].vPos = Vec3(-3.7f,fPosY,5.2f);
	m_aCels[1].vPos = Vec3(-2.7f,fPosY,5.7f);
	m_aCels[2].vPos = Vec3(-1.6f,fPosY,6.0f);
	m_aCels[3].vPos = Vec3(+0.0f,fPosY,6.1f);
	m_aCels[4].vPos = Vec3(+1.6f,fPosY,6.0f);
	m_aCels[5].vPos = Vec3(+2.7f,fPosY,5.7f);
	m_aCels[6].vPos = Vec3(+3.7f,fPosY,5.2f);

	m_aCels[0].fAngleX = 7.0f;
	m_aCels[1].fAngleX = 7.0f;
	m_aCels[2].fAngleX = 7.0f;
	m_aCels[3].fAngleX = 7.0f;
	m_aCels[4].fAngleX = 7.0f;
	m_aCels[5].fAngleX = 7.0f;
	m_aCels[6].fAngleX = 7.0f;

	m_aCels[0].fAngleY = +29.0f;
	m_aCels[1].fAngleY = +23.0f;
	m_aCels[2].fAngleY = +10.0f;
	m_aCels[3].fAngleY = 0.0f;
	m_aCels[4].fAngleY = -10.0f;
	m_aCels[5].fAngleY = -23.0f;
	m_aCels[6].fAngleY = -29.0f;

	m_aCels[0].fAngleZ = 0.0f;
	m_aCels[1].fAngleZ = 0.0f;
	m_aCels[2].fAngleZ = 0.0f;
	m_aCels[3].fAngleZ = 0.0f;
	m_aCels[4].fAngleZ = 0.0f;
	m_aCels[5].fAngleZ = 0.0f;
	m_aCels[6].fAngleZ = 0.0f;

	m_aCels[0].fMass = 1.0f;
	m_aCels[1].fMass = 1.0f;
	m_aCels[2].fMass = 2.0f;
	m_aCels[3].fMass = 2.0f;
	m_aCels[4].fMass = 2.0f;
	m_aCels[5].fMass = 1.0f;
	m_aCels[6].fMass = 1.0f;

	for(int iCel=0; iCel<7; iCel++)
	{
		SWing *pCel = &m_aCels[iCel];

		AddCel(iCel+1,pCel);

		pCel->fSurface = pCel->vSize.x * pCel->vSize.y;

		pCel->pLiftPointsMap = &m_LiftPointsMap;
		pCel->pDragPointsMap = &m_DragPointsMap;
	}
	Vec3 minExt(0.0f,0.0f,-0.5f), maxExt(0.5f,0.3f,1.9f);
	AddBox(&minExt, &maxExt, 90.0f, 8);

	return true;
}


//------------------------------------------------------------------------
void CVehicleMovementParachute::Release()
{
  CVehicleMovementBase::Release();
  delete this;
}

//-----------------------------------------------------------------------------------------------------

bool CVehicleMovementParachute::SetParams(const SmartScriptTable &_rSmartScriptTable)
{
	return true;
}

//-----------------------------------------------------------------------------------------------------

void CVehicleMovementParachute::ProcessMovement(const float _fDeltaTime)
{
#define MetersPerSecondToKilometersPerHour(fValue) (fValue*3.6f)
#define SquareFeetToSquareMeters(fValue) (fValue*0.0929f)

	float fDeltaTime = min(_fDeltaTime,0.1f);

	pe_status_dynamics statusDynamics;
	m_pPhysics->GetStatus(&statusDynamics);

	ResetTextPos();

	DumpVector("Velocity",			&statusDynamics.v);
	DumpVector("AVelocity",			&statusDynamics.w);
	DumpVector("Acceleration",	&statusDynamics.a);
	DumpVector("WAcceleration",	&statusDynamics.wa);

	DumpText("DeltaTime=%f",fDeltaTime);
	DumpText("Velocity=%f m/s",statusDynamics.v.len());
	DumpText("Velocity=%f km/h",MetersPerSecondToKilometersPerHour(statusDynamics.v.len()));
	DumpText("Yaw=%f",	m_movementAction.rotateYaw);
	DumpText("Pitch=%f",m_movementAction.rotatePitch);
	DumpText("Roll=%f",	m_movementAction.rotateRoll);

/*	Vec3 p1 = GetEntity()->GetWorldTM().GetColumn(3);
	Vec3 p2 = p1 + statusDynamics.v * 10.0f;
	GetISystem()->GetIRenderer()->GetIRenderAuxGeom()->DrawLine(p1,ColorF(1,1,0,1),p2,ColorF(1,1,0,1));
	GetISystem()->GetIRenderer()->GetIRenderAuxGeom()->DrawSphere(p1,0.6f,ColorF(0,0,1,1));*/

	if(m_movementAction.rotatePitch > 0.0f)
	{
		pe_action_impulse actionImpulse;
		actionImpulse.impulse = Vec3(0,0,5000*fDeltaTime);
		m_pPhysics->Action(&actionImpulse);
	}
	else if(statusDynamics.v.z < 0.0f)
	{
		for(int iCel=0; iCel<7; iCel++)
		{
			SWing *pCel = &m_aCels[iCel];

			pCel->fCl = 1.0f;
			pCel->fCd = 1.0f;

			float fPosY = 0.25f;

			m_aCels[0].vPos = Vec3(-3.7f,fPosY,5.2f);
			m_aCels[1].vPos = Vec3(-2.7f,fPosY,5.7f);
			m_aCels[2].vPos = Vec3(-1.6f,fPosY,6.0f);
			m_aCels[3].vPos = Vec3(+0.0f,fPosY,6.1f);
			m_aCels[4].vPos = Vec3(+1.6f,fPosY,6.0f);
			m_aCels[5].vPos = Vec3(+2.7f,fPosY,5.7f);
			m_aCels[6].vPos = Vec3(+3.7f,fPosY,5.2f);

			m_aCels[0].fAngleX = 7.0f;
			m_aCels[1].fAngleX = 7.0f;
			m_aCels[2].fAngleX = 7.0f;
			m_aCels[3].fAngleX = 7.0f;
			m_aCels[4].fAngleX = 7.0f;
			m_aCels[5].fAngleX = 7.0f;
			m_aCels[6].fAngleX = 7.0f;

			if(m_movementAction.rotateYaw < 0.0f)
			{
				m_aCels[0].fCl = 1.3f;
//				m_aCels[1].fCl = 1.3f;
//				m_aCels[2].fCl = 1.2f;

				m_aCels[0].fCd = 2.9f;
//				m_aCels[1].fCd = 2.2f;
//				m_aCels[2].fCd = 2.1f;
			}
			else if(m_movementAction.rotateYaw > 0.0f)
			{
//				m_aCels[4].fCl = 1.2f;
//				m_aCels[5].fCl = 1.3f;
				m_aCels[6].fCl = 1.3f;

//				m_aCels[4].fCd = 2.1f;
//				m_aCels[5].fCd = 2.2f;
				m_aCels[6].fCd = 2.9f;
			}
			else if(m_movementAction.rotatePitch < 0.0f)
			{
/*				m_aCels[0].vPos = Vec3(-3.6f,fPosY,4.6f);
				m_aCels[1].vPos = Vec3(-2.6f,fPosY,5.3f);
				m_aCels[2].vPos = Vec3(-1.6f,fPosY,5.9f);

				m_aCels[0].fAngleX = -15.0f;
				m_aCels[1].fAngleX = -8.0f;
				m_aCels[2].fAngleX = 0.0f;

				m_aCels[4].vPos = Vec3(+1.6f,fPosY,5.9f);
				m_aCels[5].vPos = Vec3(+2.6f,fPosY,5.3f);
				m_aCels[6].vPos = Vec3(+3.6f,fPosY,4.6f);

				m_aCels[4].fAngleX = 0.0f;
				m_aCels[5].fAngleX = -8.0f;
				m_aCels[6].fAngleX = -15.0f;*/

				m_aCels[0].fCl = 1.1f;
				m_aCels[1].fCl = 1.2f;
				m_aCels[2].fCl = 1.3f;

				m_aCels[0].fCd = 2.1f;
				m_aCels[1].fCd = 2.2f;
				m_aCels[2].fCd = 2.3f;

				m_aCels[4].fCl = 1.3f;
				m_aCels[5].fCl = 1.2f;
				m_aCels[6].fCl = 1.1f;

				m_aCels[4].fCd = 2.3f;
				m_aCels[5].fCd = 2.2f;
				m_aCels[6].fCd = 2.1f;
			}

			UpdateWing(pCel,0,fDeltaTime);
		}
	}
}

//-----------------------------------------------------------------------------------------------------