void CarHandlingDemo::addWheels(
	btVector3* halfExtents,
	btRaycastVehicle* vehicle,
	btRaycastVehicle::btVehicleTuning tuning)
{
	//The direction of the raycast, the btRaycastVehicle uses raycasts instead of simiulating the wheels with rigid bodies
	btVector3 wheelDirectionCS0(0, -1, 0);

	//The axis which the wheel rotates arround
	btVector3 wheelAxleCS(-1, 0, 0);

	btScalar suspensionRestLength(0.7);

	btScalar wheelWidth(0.4);

	btScalar wheelRadius(0.5);

	//The height where the wheels are connected to the chassis
	btScalar connectionHeight(1.2);

	//All the wheel configuration assumes the vehicle is centered at the origin and a right handed coordinate system is used
	btVector3 wheelConnectionPoint(halfExtents->x() - wheelRadius, connectionHeight, halfExtents->z() - wheelWidth);

	//Adds the front wheels
	vehicle->addWheel(wheelConnectionPoint, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, tuning, true);

	vehicle->addWheel(wheelConnectionPoint * btVector3(-1, 1, 1), wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, tuning, true);

	//Adds the rear wheels
	vehicle->addWheel(wheelConnectionPoint* btVector3(1, 1, -1), wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, tuning, false);

	vehicle->addWheel(wheelConnectionPoint * btVector3(-1, 1, -1), wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, tuning, false);

	//Configures each wheel of our vehicle, setting its friction, damping compression, etc.
	//For more details on what each parameter does, refer to the docs
	for (int i = 0; i < vehicle->getNumWheels(); i++)
	{
		btWheelInfo& wheel = vehicle->getWheelInfo(i);
		wheel.m_suspensionStiffness = 50;
		wheel.m_wheelsDampingCompression = btScalar(0.3) * 2 * btSqrt(wheel.m_suspensionStiffness);//btScalar(0.8);
		wheel.m_wheelsDampingRelaxation = btScalar(0.5) * 2 * btSqrt(wheel.m_suspensionStiffness);//1;
		//Larger friction slips will result in better handling
		wheel.m_frictionSlip = btScalar(1.2);
		wheel.m_rollInfluence = 1;
	}
}
bool Vehicle::LoadContent(DxGraphics* dx, ResourceManager& resources)
{
	m_dynamicsWorld = resources.GetPhysicsManager()->GetWorld();

	//Loads the content of all the modules
	if (!m_body->LoadContent(dx, m_body->GetPosition(), resources, m_body->GetYaw(), m_body->GetPitch(),
		m_body->GetRoll(), m_scale + m_body->GetScale()))
	{
		return false;
	}
	for (unsigned int i = 0; i < 4; i++)
	{
		if (i == 0 || i == 1)
		{
			if (!m_retros[i]->LoadContent(dx, m_retros[i]->GetPosition(), resources, m_retros[i]->GetYaw(),
				m_retros[i]->GetPitch(), m_retros[i]->GetRoll(), m_scale + m_retros[i]->GetScale()))
			{
				return false;
			}
		}

		if (!m_wheels[i]->LoadContent(dx, m_wheels[i]->GetPosition(), resources, m_wheels[i]->GetYaw(),
			m_wheels[i]->GetPitch(), m_wheels[i]->GetRoll(), m_scale + m_wheels[i]->GetScale()))
		{
			return false;
		}
	}

	if (!m_spoiler->LoadContent(dx, m_spoiler->GetPosition(), resources, m_spoiler->GetYaw(),
		m_spoiler->GetPitch(), m_spoiler->GetRoll(), m_scale + m_spoiler->GetScale()))
	{
		return false;
	}


	//ASSIGN CAR INFORMATION
	m_vehicleInfo.m_engineForce = m_retros[0]->engineForce;
	m_vehicleInfo.m_defaultEngineForce = m_retros[0]->engineForce;
	m_vehicleInfo.m_frictionSlip = BT_LARGE_FLOAT;
	m_vehicleInfo.m_rollInfluence = 0.0001f;
	m_vehicleInfo.m_suspensionRestLength1 = 0.2f;
	m_vehicleInfo.m_suspensionStiffness = 40.0f;
	m_vehicleInfo.m_wheelsDampingCompression = 4.4f; //4.4
	m_vehicleInfo.m_wheelsDampingRelaxation = 10.2f; //20
	m_vehicleInfo.m_steeringForce = 0.05f;
	m_vehicleInfo.m_breakingForce = 100;
	m_vehicleInfo.m_maxSteeringAngle = 0.10f;

	//Calcualte mass of the car, based on components.
	m_mass = m_body->GetWeight() + m_spoiler->GetWeight() + (m_wheels[0]->GetWeight() * 4) + (m_retros[0]->GetWeight() * 2);

	//initialize the compound, start adding all the aprts together
	m_vehicleCompound = new btCompoundShape();

	//CREATE VEHICLE PARTS

	//BODY
	m_vehicleCompound->addChildShape(m_body->GetLocalTranslation(), m_body->CreateCollisionShape());

	//RETROS
	for (int x = 0; x < 2; x++)
	{
		m_vehicleCompound->addChildShape(m_retros[x]->GetLocalTranslation(), m_retros[x]->CreateCollisionShape());
	}
	//SPOILER
	m_vehicleCompound->addChildShape(m_spoiler->GetLocalTranslation(), m_spoiler->CreateCollisionShape());


	//set the car Transform 
	btTransform tr;
	tr.setIdentity();
	tr.setOrigin(btVector3(m_position.x, m_position.y, m_position.z));
	//Combine all the parts into a rigid body object.
	m_rigidBody = localCreateRigidBody(m_mass, tr, m_vehicleCompound);


	/// Create raycasting for the vechicle and attach it to the car
	{
		m_vehicleRayCaster = new btDefaultVehicleRaycaster(m_dynamicsWorld);
		m_vehicle = new btRaycastVehicle(m_tuning, m_rigidBody, m_vehicleRayCaster);
		///never deactivate the vehicle
		m_rigidBody->setActivationState(DISABLE_DEACTIVATION);
		//add the vehicle to the simualtion.
		m_dynamicsWorld->addVehicle(m_vehicle);

		//Set up coordiante system , Y-up, Z-forward
		int rightIndex = 0;
		int upIndex = 1;
		int forwardIndex = 2;
		m_vehicle->setCoordinateSystem(rightIndex, upIndex, forwardIndex);

		bool isFrontWheel = true;
		btVector3 wheelDirectionCS0(0.0f, -1.0f, 0.0f);
		btVector3 wheelAxleCS(-1.0f, 0.0f, 0.0f);
		btScalar suspensionRestLength(0.2f);

		//initialize wheels
		for (int x = 0; x < 4; x++)
		{
			XMFLOAT3 colExt = m_wheels[x]->GetCollisionExtents();
			float	wheelRadius = colExt.y;
			float	wheelWidth = colExt.z;
			//determine which wheels are at the back
			if (x > 2) isFrontWheel = false;

			XMFLOAT3 offset = m_wheels[x]->GetOffset();
			btVector3 connectionPointCS0 = btVector3(offset.x, offset.y, offset.z);
			m_vehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, m_tuning, isFrontWheel);
		}
		//Rotate the wheel for the other side.
		m_wheels[1]->SetYaw(m_wheels[2]->GetYaw() + XM_PI);
		m_wheels[3]->SetYaw(m_wheels[3]->GetYaw() + XM_PI);

		//Wheel parameters.
		for (int i = 0; i < m_vehicle->getNumWheels(); i++)
		{
			btWheelInfo& wheel = m_vehicle->getWheelInfo(i);
			wheel.m_suspensionStiffness = m_vehicleInfo.m_suspensionStiffness;
			wheel.m_wheelsDampingRelaxation = m_vehicleInfo.m_wheelsDampingRelaxation;
			wheel.m_wheelsDampingCompression = m_vehicleInfo.m_wheelsDampingCompression;
			wheel.m_frictionSlip = m_vehicleInfo.m_frictionSlip;
			wheel.m_rollInfluence = m_vehicleInfo.m_rollInfluence;
			wheel.m_suspensionRestLength1 = m_vehicleInfo.m_suspensionRestLength1;
		}
	}

	m_loaded = true;
	return true;
}