#ifndef _GAME_CAM_CONTROLLER_H_
#define _GAME_CAM_CONTROLLER_H_
#include "Camera/InteractiveCameraController.h"
#include "Utils/CasualCoreCandidates.h"
namespace bne
{
BEGIN_CUSTOMOBJECT(GameCameraController, ::InteractiveCameraController)
public:
struct Parameters
{
float minimumZoom = 20.f;
float maximumZoom = 35.f;
float zoomExtension = 10.f;
float panDeceleration = 0.3f;
float panMaxInertialSpeed = 0.8f;
float panExtension = 5.f;
bool enableCameraExtents = true;
bool bOverrideViewportCentre = false;
RKVector viewportCentreOverride = RKVector::Zero;
float viewportExtentsPositiveX = 17.f;
float viewportExtentsPositiveZ = 11.f;
float viewportExtentsNegativeX = 9.f;
float viewportExtentsNegativeZ = 17.f;
bool adjustCameraAngleWithZoom = false;
float cameraYawAtMinZoom = 75.f;
float cameraYawAtMaxZoom = 85.f;
bool adjustCameraFOVWithZoom = false;
float cameraFOVAtMinZoom = 25.f;
float cameraFOVAtMaxZoom = 15.f;
float rubberBandRestoreTime = 1.f;
bool disableInput = false;
};
public:
GameCameraController();
~GameCameraController();
inline const Parameters& GetParameters() const { return m_pars; }
inline void SetParameters(const Parameters& pars) { m_pars = pars; }
void MoveCameraTowardDesiredTarget(const RKVector& target);
/// \brief Get the bounded position of a camera.
/// \param a_camera The camera to bound.
/// \param a_retPos The bounded position.
/// \returns true if the camera was bounded; otherwise, false.
bool GetBoundedPosition(const RKCamera& a_camera, RKVector& a_retPos);
/// \brief Calculate the field of view for the current device
/// \param a_srcFOV The source vertical FOV (degrees)
/// \param a_srcAspectRatio The source aspect ratio
/// \return The new vertical FOV for the current device is returned (degrees)
static float CalculateDeviceFOV(float a_srcFOV, float a_srcAspectRatio = (16.0f /9.0f));
//+ overrides
virtual bool PostInit() override;
virtual void Reset() override;
virtual void SetCameraControl(RKCamera* camera) override;
virtual void UpdateFromCamera(RKCamera* camera) override;
virtual void LockCameraInput(bool locked) override;
virtual void EnableCameraExtents(bool enabled) override;
virtual void CopySettingFromCameraCtrl(CasualCore::CameraController* ctrl) override;
virtual void PinchStarted(float x, float y) override;
virtual void PinchChanged(float scale, float velocity) override;
virtual void PinchEnded(float x, float y) override;
virtual void Pinch(float x, float y) override;
virtual void PanStarted(float x, float y) override;
virtual void PanChanged(float x, float y) override;
virtual void PanEnded(float x, float y) override;
virtual void OnTap(float x, float y) override;
virtual void OnPinchGesture(int gestureId, float x, float y) override;
virtual void OnPanGesture(int gestureId, float x, float y) override;
virtual void Update(float time) override;
//- overrides
private:
//+ serialized data
Parameters m_pars;
//- serialized data
float m_defaultZoom = 25.f;
float m_ZoomMultiplier = 1.f;
RKVector m_vBoundaryCenter = RKVector::Zero;
RKVector m_vBoundaryXAxis = RKVector::Zero;
RKVector m_vBoundaryZAxis = RKVector::Zero;
RKVector m_CameraDesiredTarget{ 0, 0, 0, 1 };
float m_fPanSpeed = 0;
RKVector2 m_panCurrentScreenPoint{ 0, 0 };
RKVector2 m_panPreviousScreenPoint{ 0, 0 };
RKVector2 m_panDirection{ 0, 0 };
float m_panRestoreTime = 0.f;
RKVector m_panRestoreStartPoint = RKVector::Zero;
RKVector m_panRestoreEndPoint = RKVector::Zero;
float m_zoomRestoreTime = 0;
float m_zoomRestoreStart = 0;
float m_zoomRestoreDelta = 0;
RKVector m_RefPos = RKVector::Zero;
RKVector m_StartPos = RKVector::Zero;
RKQuaternion m_RefQuat = RKQuaternion::Identity;
bool m_bRestoreAfterZoomin = false;
bool m_bRestoreAfterPan = false;
bool m_bUserInput = false;
bool m_bPanApplyInertia = false;
bool m_bInPan = false;
bool m_bInPinch = false;
/// \brief Initialise the restoration from a pan extension.
void InitPanRestore();
void RestoreFromZoomExtension(float a_fTime);
void RestoreFromPanExtension(float a_fTime);
struct ViewportExtentData
{
float topExcess;
float rightExcess;
float bottomExcess;
float leftExcess;
};
void GetViewportWorldExtents(const RKCamera& a_camera, ViewportExtentData& a_extentData);
/// \brief Apply the extents to the camera.
/// \returns true if the camera was moved into bounds; otherwise, false.
bool ApplyExtents();
void ZoomBy(float zoom_delta);
float ApplyZoomLimits(float zoom) const;
void SetZoomCam();
void StopInertialMovement();
void UpdateCameraInertia(float time);
RKVector ScreenToWorld(const RKVector2& position);
RKVector GetLookAtPoint(RKTransformObject* camera);
inline void SetUserInput(bool a_userInput) { m_bUserInput = a_userInput; }
END_CUSTOMOBJECT(GameCameraController)
} // namespace bne
#endif //_GAME_CAM_CONTROLLER_H_