2013-11-06 22:52:00 +01:00
/////////////////////////////////////////////////////////////////////
2013-11-09 14:59:10 +01:00
// Created by Dan Andersson 2013
2013-11-06 22:52:00 +01:00
/////////////////////////////////////////////////////////////////////
# ifndef OYSTER_MATH_H
# define OYSTER_MATH_H
# include "Utilities.h"
# include "LinearMath.h"
# include <limits>
2013-11-09 01:23:30 +01:00
namespace Oyster { namespace Math /// Oyster's native math library
2013-11-06 22:52:00 +01:00
{
2013-11-09 01:23:30 +01:00
typedef float Float ; /// Oyster's native scalar is float
typedef : : LinearAlgebra : : Vector2 < Float > Float2 ; /// 2D Linear Vector for Oyster
typedef : : LinearAlgebra : : Vector3 < Float > Float3 ; /// 3D Linear Vector for Oyster
typedef : : LinearAlgebra : : Vector4 < Float > Float4 ; /// 4D Linear Vector for Oyster
typedef : : LinearAlgebra : : Matrix2x2 < Float > Float2x2 ; /// 2x2 Linear Matrix for Oyster
typedef : : LinearAlgebra : : Matrix3x3 < Float > Float3x3 ; /// 3x3 Linear Matrix for Oyster
typedef : : LinearAlgebra : : Matrix4x4 < Float > Float4x4 ; /// 4x4 Linear Matrix for Oyster
typedef Float4x4 Matrix ; // by popular demand
typedef Float2 Vector2 ; // by popular demand
typedef Float3 Vector3 ; // by popular demand
typedef Float4 Vector4 ; // by popular demand
2013-11-12 00:10:48 +01:00
const Float pi = 3.1415926535897932384626433832795f ;
2013-11-09 01:23:30 +01:00
/// Function Highly recommended to check at start, just in case current version is using a feature that might be available.
/// @todo TODO: create a template UniquePointer to use here
2013-11-09 14:59:10 +01:00
bool IsSupported ( ) ;
2013-11-09 01:23:30 +01:00
/// Creates a solution matrix for 'out<75> = 'targetMem' * 'in'.
/// Returns false if there is no explicit solution.
2013-11-09 14:59:10 +01:00
bool SuperpositionMatrix ( const Float2x2 & in , const Float2x2 & out , Float2x2 & targetMem ) ;
2013-11-09 01:23:30 +01:00
/// Creates a solution matrix for 'out<75> = 'targetMem' * 'in'.
/// Returns false if there is no explicit solution.
2013-11-09 14:59:10 +01:00
bool SuperpositionMatrix ( const Float3x3 & in , const Float3x3 & out , Float3x3 & targetMem ) ;
2013-11-09 01:23:30 +01:00
/// Creates a solution matrix for 'out<75> = 'targetMem' * 'in'.
/// Returns false if there is no explicit solution.
2013-11-09 14:59:10 +01:00
bool SuperpositionMatrix ( const Float4x4 & in , const Float4x4 & out , Float4x4 & targetMem ) ;
2013-11-09 01:23:30 +01:00
} }
2013-11-06 22:52:00 +01:00
2013-11-09 01:23:30 +01:00
inline : : Oyster : : Math : : Float2 & operator * = ( : : Oyster : : Math : : Float2 & left , const : : Oyster : : Math : : Float2 & right )
{
left . x * = right . x ;
left . y * = right . y ;
return left ;
}
2013-11-06 22:52:00 +01:00
2013-11-09 01:23:30 +01:00
inline : : Oyster : : Math : : Float2 operator * ( const : : Oyster : : Math : : Float2 & left , const : : Oyster : : Math : : Float2 & right )
{ return : : Oyster : : Math : : Float2 ( left ) * = right ; }
2013-11-06 22:52:00 +01:00
2013-11-09 01:23:30 +01:00
inline : : Oyster : : Math : : Float2 operator * ( const : : Oyster : : Math : : Float & left , const : : Oyster : : Math : : Float2 & right )
{ return : : Oyster : : Math : : Float2 ( right ) * = left ; }
2013-11-06 22:52:00 +01:00
2013-11-09 01:23:30 +01:00
inline : : Oyster : : Math : : Float3 & operator * = ( : : Oyster : : Math : : Float3 & left , const : : Oyster : : Math : : Float3 & right )
{
left . x * = right . x ;
left . y * = right . y ;
left . z * = right . z ;
return left ;
}
2013-11-06 22:52:00 +01:00
2013-11-09 01:23:30 +01:00
inline : : Oyster : : Math : : Float3 operator * ( const : : Oyster : : Math : : Float3 & left , const : : Oyster : : Math : : Float3 & right )
{ return : : Oyster : : Math : : Float3 ( left ) * = right ; }
2013-11-06 22:52:00 +01:00
2013-11-09 01:23:30 +01:00
inline : : Oyster : : Math : : Float3 operator * ( const : : Oyster : : Math : : Float & left , const : : Oyster : : Math : : Float3 & right )
{ return : : Oyster : : Math : : Float3 ( right ) * = left ; }
2013-11-06 22:52:00 +01:00
2013-11-09 01:23:30 +01:00
inline : : Oyster : : Math : : Float4 & operator * = ( : : Oyster : : Math : : Float4 & left , const : : Oyster : : Math : : Float4 & right )
{
left . x * = right . x ;
left . y * = right . y ;
left . z * = right . z ;
left . w * = right . w ;
return left ;
}
2013-11-06 22:52:00 +01:00
2013-11-09 01:23:30 +01:00
inline : : Oyster : : Math : : Float4 operator * ( const : : Oyster : : Math : : Float4 & left , const : : Oyster : : Math : : Float4 & right )
{ return : : Oyster : : Math : : Float4 ( left ) * = right ; }
2013-11-06 22:52:00 +01:00
2013-11-09 01:23:30 +01:00
inline : : Oyster : : Math : : Float4 operator * ( const : : Oyster : : Math : : Float & left , const : : Oyster : : Math : : Float4 & right )
{ return : : Oyster : : Math : : Float4 ( right ) * = left ; }
2013-11-06 22:52:00 +01:00
2013-11-09 01:23:30 +01:00
inline : : Oyster : : Math : : Float2x2 operator * ( const : : Oyster : : Math : : Float & left , const : : Oyster : : Math : : Float2x2 & right )
{ return : : Oyster : : Math : : Float2x2 ( right ) * = left ; }
2013-11-06 22:52:00 +01:00
2013-11-09 01:23:30 +01:00
inline : : Oyster : : Math : : Float3x3 operator * ( const : : Oyster : : Math : : Float & left , const : : Oyster : : Math : : Float3x3 & right )
{ return : : Oyster : : Math : : Float3x3 ( right ) * = left ; }
2013-11-06 22:52:00 +01:00
2013-11-09 01:23:30 +01:00
inline : : Oyster : : Math : : Float4x4 operator * ( const : : Oyster : : Math : : Float & left , const : : Oyster : : Math : : Float4x4 & right )
{ return : : Oyster : : Math : : Float4x4 ( right ) * = left ; }
2013-11-06 22:52:00 +01:00
2013-11-09 01:23:30 +01:00
namespace Oyster { namespace Math2D /// Oyster's native math library specialized for 2D
{
using namespace : : Oyster : : Math ; // deliberate inheritance from ::Oyster::Math namespace
/// If there is an Y-axis on a 2D plane, then there is an explicit X-axis on and that is what is returned.
/// Recommended too make sure that yAxis is normalized.
2013-11-09 14:59:10 +01:00
Float2 X_AxisTo ( const Float2 & yAxis ) ;
2013-11-09 01:23:30 +01:00
/// If there is an X-axis on a 2D plane, then there is an explicit Y-axis and that is what is returned.
/// Recommended too make sure that yAxis is normalized.
2013-11-09 14:59:10 +01:00
Float2 Y_AxisTo ( const Float2 & xAxis ) ;
2013-11-09 01:23:30 +01:00
/// Sets and returns targetMem to a translationMatrix with position as translation.
2013-11-09 14:59:10 +01:00
Float3x3 & TranslationMatrix ( const Float2 & position , Float3x3 & targetMem = Float3x3 ( ) ) ;
2013-11-09 01:23:30 +01:00
/// Sets and returns targetMem as a counterclockwise rotationMatrix
2013-11-09 14:59:10 +01:00
Float3x3 & RotationMatrix ( const Float & radian , Float3x3 & targetMem = Float3x3 ( ) ) ;
2013-11-09 01:23:30 +01:00
2013-11-20 16:58:56 +01:00
/// If rotation is assumed to be by all definitions a rotation matrix. Then this is a much faster inverse method.
Float2x2 & InverseRotationMatrix ( const Float2x2 & rotation , Float2x2 & targetMem = Float2x2 ( ) ) ;
/// If rotation is assumed to be by all definitions a rotation matrix. Then this is a much faster inverse method.
Float3x3 & InverseRotationMatrix ( const Float3x3 & rotation , Float3x3 & targetMem = Float3x3 ( ) ) ;
/// Sets and returns targetMem as an orientation Matrix composed by the rotation matrix and translation vector
Float3x3 & OrientationMatrix ( const Float2x2 & rotation , const Float2 & translation , Float3x3 & targetMem = Float3x3 ( ) ) ;
/// Sets and returns targetMem as an orientation Matrix composed by the rotation matrix and translation vector
Float3x3 & OrientationMatrix ( const Float3x3 & rotation , const Float2 & translation , Float3x3 & targetMem = Float3x3 ( ) ) ;
2013-11-09 01:23:30 +01:00
/// Sets and returns targetMem as an orientation Matrix with position as translation and radian rotation
2013-11-09 14:59:10 +01:00
Float3x3 & OrientationMatrix ( const Float2 & position , const Float & radian , Float3x3 & targetMem = Float3x3 ( ) ) ;
2013-11-09 01:23:30 +01:00
/// Sets and returns targetMem as an orientation Matrix with position as translation and local y-axis directed at lookAt
2013-11-09 14:59:10 +01:00
Float3x3 & OrientationMatrix ( const Float2 & position , const Float2 & lookAt , Float3x3 & targetMem = Float3x3 ( ) ) ;
2013-11-09 01:23:30 +01:00
/// Sets and returns targetMem as an orientation Matrix that is rotated around localCenterOfRotation and then translated with position.
/// TODO: not tested
2013-11-09 14:59:10 +01:00
Float3x3 & OrientationMatrix ( const Float2 & position , Float radian , const Float2 & localCenterOfRotation , Float3x3 & targetMem = Float3x3 ( ) ) ;
2013-11-09 01:23:30 +01:00
/// If orientationMatrix is assumed to be by all definitions a rigid orientation matrix aka rigid body matrix. Then this is a much faster inverse method.
2013-11-09 14:59:10 +01:00
Float3x3 & InverseOrientationMatrix ( const Float3x3 & orientationMatrix , Float3x3 & targetMem = Float3x3 ( ) ) ;
2013-11-20 16:58:56 +01:00
/// Returns targetmem after writing the rotation data from orientation, into it.
Float3x3 & ExtractRotationMatrix ( const Float3x3 & orientation , Float3x3 & targetMem = Float3x3 ( ) ) ;
2013-11-09 01:23:30 +01:00
} }
2013-11-06 22:52:00 +01:00
2013-11-09 01:23:30 +01:00
namespace Oyster { namespace Math3D /// Oyster's native math library specialized for 3D
{
using namespace : : Oyster : : Math ; // deliberate inheritance from ::Oyster::Math namespace
/// Sets and returns targetMem to a translationMatrix with position as translation.
2013-11-09 14:59:10 +01:00
Float4x4 & TranslationMatrix ( const Float3 & position , Float4x4 & targetMem = Float4x4 ( ) ) ;
2013-11-09 01:23:30 +01:00
/// Sets and returns targetMem as an counterclockwise rotation matrix around the global X-axis
2013-11-09 14:59:10 +01:00
Float4x4 & RotationMatrix_AxisX ( const Float & radian , Float4x4 & targetMem = Float4x4 ( ) ) ;
2013-11-09 01:23:30 +01:00
/// Sets and returns targetMem as an counterclockwise rotation matrix around the global Y-axis
2013-11-09 14:59:10 +01:00
Float4x4 & RotationMatrix_AxisY ( const Float & radian , Float4x4 & targetMem = Float4x4 ( ) ) ;
2013-11-09 01:23:30 +01:00
/// Sets and returns targetMem as an counterclockwise rotation matrix around the global Z-axis
2013-11-09 14:59:10 +01:00
Float4x4 & RotationMatrix_AxisZ ( const Float & radian , Float4x4 & targetMem = Float4x4 ( ) ) ;
2013-11-09 01:23:30 +01:00
/// Sets and returns targetMem as an counterclockwise rotation matrix around the normalizedAxis.
/// Please make sure normalizedAxis is normalized.
2013-11-09 14:59:10 +01:00
Float4x4 & RotationMatrix ( const Float & radian , const Float3 & normalizedAxis , Float4x4 & targetMem = Float4x4 ( ) ) ;
2013-11-09 01:23:30 +01:00
2013-11-20 16:58:56 +01:00
/// If rotation is assumed to be by all definitions a rotation matrix. Then this is a much faster inverse method.
Float3x3 & InverseRotationMatrix ( const Float3x3 & rotation , Float3x3 & targetMem = Float3x3 ( ) ) ;
/// If rotation is assumed to be by all definitions a rotation matrix. Then this is a much faster inverse method.
Float4x4 & InverseRotationMatrix ( const Float4x4 & rotation , Float4x4 & targetMem = Float4x4 ( ) ) ;
/// Sets and returns targetMem as an orientation Matrix composed by the rotation matrix and translation vector
Float4x4 & OrientationMatrix ( const Float3x3 & rotation , const Float3 & translation , Float4x4 & targetMem = Float4x4 ( ) ) ;
/// Sets and returns targetMem as an orientation Matrix composed by the rotation matrix and translation vector
Float4x4 & OrientationMatrix ( const Float4x4 & rotation , const Float3 & translation , Float4x4 & targetMem = Float4x4 ( ) ) ;
2013-11-12 00:10:48 +01:00
/*******************************************************************
* Sets and returns targetMem as an orientation Matrix
* @ param normalizedAxis : The normalized vector parallell with the rotationAxis .
* @ param deltaRadian : The rotation angle .
* @ param sumTranslation : sum of all the translation vectors .
* @ param targetMem : is set to a rigibody matrix that rotate counterclockwise and then translates .
* @ return targetMem
* @ todo TODO : not tested
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
Float4x4 & OrientationMatrix ( const Float3 & normalizedAxis , const Float & deltaRadian , const Float3 & sumTranslation , Float4x4 & targetMem = Float4x4 ( ) ) ;
/*******************************************************************
* Sets and returns targetMem as an orientation Matrix
2013-11-09 01:23:30 +01:00
* @ param sumDeltaAngularAxis : sum of all ( ( 1 / I ) * ( L x D ) ) - vectorproducts . There I is known as " moment of inertia " , L as " angular momentum vector " and D the " lever vector " .
* @ param sumTranslation : sum of all the translation vectors .
2013-11-12 00:10:48 +01:00
* @ param targetMem : is set to a rigibody matrix that rotate counterclockwise and then translates .
2013-11-09 01:23:30 +01:00
* @ return targetMem
2013-11-12 00:10:48 +01:00
* @ todo TODO : not tested
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2013-11-09 14:59:10 +01:00
Float4x4 & OrientationMatrix ( const Float3 & sumDeltaAngularAxis , const Float3 & sumTranslation , Float4x4 & targetMem = Float4x4 ( ) ) ;
2013-11-09 01:23:30 +01:00
2013-11-12 00:10:48 +01:00
/*******************************************************************
* Sets and returns targetMem as an orientation Matrix
2013-11-09 01:23:30 +01:00
* @ param sumDeltaAngularAxis : sum of all ( ( 1 / I ) * ( L x D ) ) - vectorproducts . There I is known as " moment of inertia " , L as " angular momentum vector " and D the " lever vector " .
* @ param sumTranslation : sum of all the translation vectors .
* @ param centerOfMass : the point the particles is to revolve around , prior to translation . Default set to null vector aka origo .
2013-11-12 00:10:48 +01:00
* @ param targetMem : is set to a rigibody matrix that revolve / rotate counterclockwise around centerOfMass and then translates .
2013-11-09 01:23:30 +01:00
* @ return targetMem
2013-11-12 00:10:48 +01:00
* @ todo TODO : not tested
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2013-11-09 14:59:10 +01:00
Float4x4 & OrientationMatrix ( const Float3 & sumDeltaAngularAxis , const Float3 & sumTranslation , const Float3 & centerOfMass , Float4x4 & targetMem = Float4x4 ( ) ) ;
2013-11-21 15:19:32 +01:00
//! @todo TODO: Add documentation and not tested
Float4x4 & OrientationMatrix_LookAtDirection ( const Float3 & normalizedDirection , const Float3 & normalizedUpVector , const Float3 & worldPos , Float4x4 & targetMem = Float4x4 ( ) ) ;
//! @todo TODO: Add documentation and not tested
Float4x4 & OrientationMatrix_LookAtPos ( const Float3 & worldLookAt , const Float3 & normalizedUpVector , const Float3 & worldPos , Float4x4 & targetMem = Float4x4 ( ) ) ;
2013-11-22 10:49:07 +01:00
//! @todo TODO: Add documentation and not tested
Float4x4 & ViewMatrix_LookAtDirection ( const Float3 & normalizedDirection , const Float3 & normalizedUpVector , const Float3 & worldPos , Float4x4 & targetMem = Float4x4 ( ) ) ;
//! @todo TODO: Add documentation and not tested
Float4x4 & ViewMatrix_LookAtPos ( const Float3 & worldLookAt , const Float3 & normalizedUpVector , const Float3 & worldPos , Float4x4 & targetMem = Float4x4 ( ) ) ;
2013-11-09 14:59:10 +01:00
/// If orientationMatrix is assumed to be by all definitions a rigid orientation matrix aka rigid body matrix. Then this is a much faster inverse method.
Float4x4 & InverseOrientationMatrix ( const Float4x4 & orientationMatrix , Float4x4 & targetMem = Float4x4 ( ) ) ;
2013-11-09 01:23:30 +01:00
2013-11-18 14:01:23 +01:00
// O0 = T0 * R0
// O1 = T1 * T0 * R1 * R0
Float4x4 & UpdateOrientationMatrix ( const Float3 & deltaPosition , const Float4x4 & deltaRotationMatrix , Float4x4 & orientationMatrix ) ;
2013-11-20 16:58:56 +01:00
/// Returns targetmem after writing the rotation data from orientation, into it.
Float4x4 & ExtractRotationMatrix ( const Float4x4 & orientation , Float4x4 & targetMem = Float4x4 ( ) ) ;
2013-11-12 00:10:48 +01:00
/*******************************************************************
* Creates an orthographic projection matrix designed for DirectX enviroment .
2013-11-09 01:23:30 +01:00
* @ param width ; of the projection sample volume .
* @ param height ; of the projection sample volume .
* @ param nearClip : Distance to the nearPlane .
* @ param farClip : Distance to the farPlane .
2013-11-12 00:10:48 +01:00
* @ param targetMem ; is set to an orthographic projection matrix .
2013-11-09 01:23:30 +01:00
* @ return targetMem
2013-11-12 00:10:48 +01:00
* @ todo TODO : not tested
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2013-11-09 14:59:10 +01:00
Float4x4 & ProjectionMatrix_Orthographic ( const Float & width , const Float & height , const Float & nearClip = : : std : : numeric_limits < Float > : : epsilon ( ) , const Float & farClip = : : std : : numeric_limits < Float > : : max ( ) , Float4x4 & targetMem = Float4x4 ( ) ) ;
2013-11-09 01:23:30 +01:00
2013-11-12 00:10:48 +01:00
/*******************************************************************
* Creates a perspective projection matrix designed for DirectX enviroment .
2013-11-09 01:23:30 +01:00
* @ param vertFoV ; is the vertical field of vision in radians . ( lookup FoV Hor + )
* @ param aspect ; is the screenratio width / height ( example 16 / 9 or 16 / 10 )
* @ param nearClip : Distance to the nearPlane
* @ param farClip : Distance to the farPlane
2013-11-12 00:10:48 +01:00
* @ param targetMem ; is set to a perspective transform matrix .
2013-11-09 01:23:30 +01:00
* @ return targetMem
2013-11-12 00:10:48 +01:00
* @ todo TODO : not tested
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2013-11-09 14:59:10 +01:00
Float4x4 & ProjectionMatrix_Perspective ( const Float & verticalFoV , const Float & aspectRatio , const Float & nearClip = : : std : : numeric_limits < Float > : : epsilon ( ) , const Float & farClip = : : std : : numeric_limits < Float > : : max ( ) , Float4x4 & targetMem = Float4x4 ( ) ) ;
2013-11-06 22:52:00 +01:00
2013-11-09 01:23:30 +01:00
/// returns the component vector of vector that is parallell with axis
2013-11-09 14:59:10 +01:00
Float3 VectorProjection ( const Float3 & vector , const Float3 & axis ) ;
2013-11-06 22:52:00 +01:00
2013-11-21 11:39:11 +01:00
/// returns the component vector of vector that is parallell with axis. Faster than VectorProjection.
Float3 NormalProjection ( const Float3 & vector , const Float3 & normalizedAxis ) ;
2013-11-09 01:23:30 +01:00
/// Helper inline function that sets and then returns targetMem = projection * view
inline Float4x4 & ViewProjectionMatrix ( const Float4x4 & view , const Float4x4 & projection , Float4x4 & targetMem = Float4x4 ( ) )
{ return targetMem = projection * view ; }
2013-11-06 22:52:00 +01:00
2013-11-20 11:09:27 +01:00
/** Helper inline function that sets and then returns targetMem = transformer * transformee */
inline Float4x4 & TransformMatrix ( const Float4x4 & transformer , const Float4x4 & transformee , Float4x4 & targetMem )
2013-11-09 01:23:30 +01:00
{ return targetMem = transformer * transformee ; }
2013-11-06 22:52:00 +01:00
2013-11-20 11:09:27 +01:00
/** Helper inline function that sets and then returns transformer * transformee */
inline Float4x4 TransformMatrix ( const Float4x4 & transformer , const Float4x4 & transformee )
{ return transformer * transformee ; }
2013-11-09 01:23:30 +01:00
/// Helper inline function that sets and then returns targetMem = transformer * transformee
inline Float4 & TransformVector ( const Float4x4 & transformer , const Float4 & transformee , Float4 & targetMem = Float4 ( ) )
{ return targetMem = transformer * transformee ; }
2013-11-06 22:52:00 +01:00
} }
# endif