@ -30,8 +30,11 @@ namespace AzFramework
AZ : : Vector3 EulerAngles ( const AZ : : Matrix3x3 & orientation ) ;
//! A simple camera representation using spherical coordinates as input (pitch, yaw, pivot and offset).
//! The camera s transform and view can be obtained through accessor functions that use the internal
//! The camera ' s transform and view can be obtained through accessor functions that use the internal
//! spherical coordinates to calculate the position and orientation.
//! @note Modifying m_pivot directly and leaving m_offset as zero will produce a free look camera effect, giving
//! m_offset a value (e.g. in negative Y only) will produce an orbit camera effect, modifying X and Z of m_offset
//! will further alter the camera translation in relation to m_pivot so it appears off center.
struct Camera
{
AZ : : Vector3 m_pivot = AZ : : Vector3 : : CreateZero ( ) ; //!< Pivot point to rotate about (modified in world space).
@ -291,7 +294,7 @@ namespace AzFramework
Cameras m_cameras ; //!< Represents a collection of camera inputs that together provide a camera controller.
private :
ScreenVector m_motionDelta ; //!< The delta used for look/ piv ot/pan (rotation + translation) - two dimensional.
ScreenVector m_motionDelta ; //!< The delta used for look/ orbi t/pan (rotation + translation) - two dimensional.
CursorState m_cursorState ; //!< The current and previous position of the cursor (used to calculate movement delta).
float m_scrollDelta = 0.0f ; //!< The delta used for dolly/movement (translation) - one dimensional.
bool m_handlingEvents = false ; //!< Is the camera system currently handling events (events are consumed and not propagated).
@ -316,7 +319,7 @@ namespace AzFramework
return AZStd : : fmod ( yaw + AZ : : Constants : : TwoPi , AZ : : Constants : : TwoPi ) ;
}
//! A camera input to handle motion deltas that can rotate or pivot the camera .
//! A camera input to handle motion deltas that can change the orientation of the camera (update pitch and yaw) .
class RotateCameraInput : public CameraInput
{
public :
@ -348,15 +351,16 @@ namespace AzFramework
//! PanAxes build function that will return a pair of pan axes depending on the camera orientation.
using PanAxesFn = AZStd : : function < PanAxes ( const Camera & camera ) > ;
//! PanAxes to use while in 'look' camera behavior (free look) .
//! PanAxes to use while in 'look' or 'orbit' camera behavior.
inline PanAxes LookPan ( const Camera & camera )
{
const AZ : : Matrix3x3 orientation = camera . Rotation ( ) ;
return { orientation . GetBasisX ( ) , orientation . GetBasisZ ( ) } ;
}
//! PanAxes to use while in 'pivot' camera behavior.
inline PanAxes PivotPan ( const Camera & camera )
//! Optional PanAxes to use while in 'orbit' camera behavior.
//! @note This will move the camera in the local X/Y plane instead of usual X/Z plane.
inline PanAxes OrbitPan ( const Camera & camera )
{
const AZ : : Matrix3x3 orientation = camera . Rotation ( ) ;
@ -370,14 +374,23 @@ namespace AzFramework
return { basisX , basisY } ;
}
//! TranslationDeltaFn is used by PanCameraInput and TranslateCameraInput
//! @note Choose the appropriate function if the behavior should be operating as a free look camera (TranslatePivotLook)
//! or an orbit camera (TranslateOffsetOrbit).
using TranslationDeltaFn = AZStd : : function < void ( Camera & camera , const AZ : : Vector3 & delta ) > ;
inline void TranslatePivot ( Camera & camera , const AZ : : Vector3 & delta )
//! Update the pivot camera position.
//! @note delta will need to have been transformed to world space, e.g. To move the camera right, (1, 0, 0) must
//! first be transformed by the orientation of the camera before being applied to m_pivot.
inline void TranslatePivotLook ( Camera & camera , const AZ : : Vector3 & delta )
{
camera . m_pivot + = delta ;
}
inline void TranslateOffset ( Camera & camera , const AZ : : Vector3 & delta )
//! Update the offset camera position.
//! @note delta still needs to be transformed to world space (as with TranslatePivotLook) but internally this is undone
//! to be performed in local space when being applied to m_offset.
inline void TranslateOffsetOrbit ( Camera & camera , const AZ : : Vector3 & delta )
{
camera . m_offset + = camera . View ( ) . TransformVector ( delta ) ;
}
@ -409,7 +422,7 @@ namespace AzFramework
//! Axes to use while translating the camera.
using TranslationAxesFn = AZStd : : function < AZ : : Matrix3x3 ( const Camera & camera ) > ;
//! TranslationAxes to use while in 'look' camera behavior (free look) .
//! TranslationAxes to use while in 'look' or 'orbit' camera behavior.
inline AZ : : Matrix3x3 LookTranslation ( const Camera & camera )
{
const AZ : : Matrix3x3 orientation = camera . Rotation ( ) ;
@ -421,8 +434,8 @@ namespace AzFramework
return AZ : : Matrix3x3 : : CreateFromColumns ( basisX , basisY , basisZ ) ;
}
//! TranslationAxes to use while in 'piv ot' camera behavior.
inline AZ : : Matrix3x3 Pivo tTranslation( const Camera & camera )
//! Optional TranslationAxes to use while in 'orbi t' camera behavior.
inline AZ : : Matrix3x3 Orbi tTranslation( const Camera & camera )
{
const AZ : : Matrix3x3 orientation = camera . Rotation ( ) ;
@ -535,11 +548,11 @@ namespace AzFramework
bool m_boost = false ; //!< Is the translation speed currently being multiplied/scaled upwards.
} ;
//! A camera input to handle discrete scroll events that can modify the camera pivot distance .
class Pivo tDollyScrollCameraInput : public CameraInput
//! A camera input to handle discrete scroll events that can modify the camera offset .
class Orbi tDollyScrollCameraInput : public CameraInput
{
public :
Pivo tDollyScrollCameraInput( ) ;
Orbi tDollyScrollCameraInput( ) ;
// CameraInput overrides ...
bool HandleEvents ( const InputEvent & event , const ScreenVector & cursorDelta , float scrollDelta ) override ;
@ -548,11 +561,11 @@ namespace AzFramework
AZStd : : function < float ( ) > m_scrollSpeedFn ;
} ;
//! A camera input to handle motion deltas that can modify the camera pivot distance .
class Pivo tDollyMotionCameraInput : public CameraInput
//! A camera input to handle motion deltas that can modify the camera offset .
class Orbi tDollyMotionCameraInput : public CameraInput
{
public :
explicit Pivo tDollyMotionCameraInput( const InputChannelId & dollyChannelId ) ;
explicit Orbi tDollyMotionCameraInput( const InputChannelId & dollyChannelId ) ;
// CameraInput overrides ...
bool HandleEvents ( const InputEvent & event , const ScreenVector & cursorDelta , float scrollDelta ) override ;
@ -569,10 +582,10 @@ namespace AzFramework
} ;
//! A camera input to handle discrete scroll events that can scroll (translate) the camera along its forward axis.
class ScrollTranslationCameraInput : public CameraInput
class Look ScrollTranslationCameraInput : public CameraInput
{
public :
ScrollTranslationCameraInput( ) ;
Look ScrollTranslationCameraInput( ) ;
// CameraInput overrides ...
bool HandleEvents ( const InputEvent & event , const ScreenVector & cursorDelta , float scrollDelta ) override ;
@ -583,36 +596,36 @@ namespace AzFramework
//! A camera input that doubles as its own set of camera inputs.
//! It is 'exclusive', so does not overlap with other sibling camera inputs - it runs its own set of camera inputs as 'children'.
class Pivo tCameraInput : public CameraInput
class Orbi tCameraInput : public CameraInput
{
public :
using PivotFn = AZStd : : function < AZ : : Vector3 ( const AZ : : Vector3 & position , const AZ : : Vector3 & direction ) > ;
explicit Pivo tCameraInput( const InputChannelId & piv otChannelId) ;
explicit Orbi tCameraInput( const InputChannelId & orbi tChannelId) ;
// CameraInput overrides ...
bool HandleEvents ( const InputEvent & event , const ScreenVector & cursorDelta , float scrollDelta ) override ;
Camera StepCamera ( const Camera & targetCamera , const ScreenVector & cursorDelta , float scrollDelta , float deltaTime ) override ;
bool Exclusive ( ) const override ;
void Set Pivo tInputChannelId( const InputChannelId & piv otChanneId) ;
void Set Orbi tInputChannelId( const InputChannelId & orbi tChanneId) ;
Cameras m_ piv otCameras; //!< The camera inputs to run when this camera input is active (only these will run as it is exclusive).
Cameras m_ orbi tCameras; //!< The camera inputs to run when this camera input is active (only these will run as it is exclusive).
//! Override the default behavior for how a pivot point is calculated.
void SetPivotFn ( PivotFn pivotFn ) ;
private :
InputChannelId m_ piv otChannelId; //!< Input channel to begin the piv ot camera input.
PivotFn m_pivotFn ; //!< The pivot position to use for this piv ot camera (how is the pivot point calculated/retrieved).
InputChannelId m_ orbi tChannelId; //!< Input channel to begin the orbi t camera input.
PivotFn m_pivotFn ; //!< The pivot position to use for this orbi t camera (how is the pivot point calculated/retrieved).
} ;
inline void Pivo tCameraInput: : SetPivotFn ( PivotFn pivotFn )
inline void Orbi tCameraInput: : SetPivotFn ( PivotFn pivotFn )
{
m_pivotFn = AZStd : : move ( pivotFn ) ;
}
inline bool Pivo tCameraInput: : Exclusive ( ) const
inline bool Orbi tCameraInput: : Exclusive ( ) const
{
return true ;
}
@ -624,9 +637,9 @@ namespace AzFramework
return AZ : : Vector3 : : CreateZero ( ) ;
}
//! Callback to use for FocusCameraInput when a piv ot camera is being used.
//! Callback to use for FocusCameraInput when a orbi t camera is being used.
//! @note This is when offset is non zero.
inline AZ : : Vector3 Focus Pivo t( const float length )
inline AZ : : Vector3 Focus Orbi t( const float length )
{
return AZ : : Vector3 : : CreateAxisY ( - length ) ;
}
@ -667,7 +680,9 @@ namespace AzFramework
bool HandleEvents ( const InputEvent & event , const ScreenVector & cursorDelta , float scrollDelta ) override ;
Camera StepCamera ( const Camera & targetCamera , const ScreenVector & cursorDelta , float scrollDelta , float deltaTime ) override ;
//! HandleEvents delegates directly to m_handleEventsFn.
AZStd : : function < bool ( CameraInput & , const InputEvent & , const ScreenVector & , float ) > m_handleEventsFn ;
//! StepCamera delegates directly to m_stepCameraFn.
AZStd : : function < Camera ( CameraInput & , const Camera & , const ScreenVector & , float , float ) > m_stepCameraFn ;
} ;