220 lines
10 KiB
C
220 lines
10 KiB
C
|
/////////////////////////////////////////////////////////////////////
|
||
|
// by Dan Andersson 2013
|
||
|
/////////////////////////////////////////////////////////////////////
|
||
|
|
||
|
#pragma once
|
||
|
#ifndef OYSTER_MATH_H
|
||
|
#define OYSTER_MATH_H
|
||
|
|
||
|
#include "Utilities.h"
|
||
|
#include "LinearMath.h"
|
||
|
#include <limits>
|
||
|
|
||
|
namespace Oyster { namespace Math
|
||
|
{
|
||
|
typedef float Float;
|
||
|
|
||
|
typedef ::LinearAlgebra::Vector2<Float> Float2;
|
||
|
typedef ::LinearAlgebra::Vector3<Float> Float3;
|
||
|
typedef ::LinearAlgebra::Vector4<Float> Float4;
|
||
|
|
||
|
typedef ::LinearAlgebra::Matrix2x2<Float> Float2x2;
|
||
|
typedef ::LinearAlgebra::Matrix3x3<Float> Float3x3;
|
||
|
typedef ::LinearAlgebra::Matrix4x4<Float> Float4x4;
|
||
|
|
||
|
typedef Float4x4 Matrix;
|
||
|
typedef Float2 Vector2;
|
||
|
typedef Float3 Vector3;
|
||
|
typedef Float4 Vector4;
|
||
|
|
||
|
|
||
|
|
||
|
Float2 & operator *= ( Float2 &left, const Float2 &right );
|
||
|
|
||
|
inline Float2 operator * ( const Float2 &left, const Float2 &right )
|
||
|
{ return Float2(left) *= right; }
|
||
|
|
||
|
inline Float2 operator * ( const Float &left, const Float2 &right )
|
||
|
{ return Float2(right) *= left; }
|
||
|
|
||
|
Float3 & operator *= ( Float3 &left, const Float3 &right );
|
||
|
|
||
|
inline Float3 operator * ( const Float3 &left, const Float3 &right )
|
||
|
{ return Float3(left) *= right; }
|
||
|
|
||
|
inline Float3 operator * ( const Float &left, const Float3 &right )
|
||
|
{ return Float3(right) *= left; }
|
||
|
|
||
|
Float4 & operator *= ( Float4 &left, const Float4 &right );
|
||
|
|
||
|
inline Float4 operator * ( const Float4 &left, const Float4 &right )
|
||
|
{ return Float4(left) *= right; }
|
||
|
|
||
|
inline Float4 operator * ( const Float &left, const Float4 &right )
|
||
|
{ return Float4(right) *= left; }
|
||
|
|
||
|
inline Float2x2 operator * ( const Float &left, const Float2x2 &right )
|
||
|
{ return Float2x2(right) *= left; }
|
||
|
|
||
|
inline Float3x3 operator * ( const Float &left, const Float3x3 &right )
|
||
|
{ return Float3x3(right) *= left; }
|
||
|
|
||
|
inline Float4x4 operator * ( const Float &left, const Float4x4 &right )
|
||
|
{ return Float4x4(right) *= left; }
|
||
|
|
||
|
// Deprecated function! Use the static const member identity instead.
|
||
|
inline void identityMatrix( Float2x2 &output )
|
||
|
{ output = Float2x2::identity; }
|
||
|
|
||
|
// Deprecated function! Use the static const member identity instead.
|
||
|
inline void identityMatrix( Float3x3 &output )
|
||
|
{ output = Float3x3::identity; }
|
||
|
|
||
|
// Deprecated function! Use the static const member identity instead.
|
||
|
inline void identityMatrix( Float4x4 &output )
|
||
|
{ output = Float4x4::identity; }
|
||
|
|
||
|
// If rigidBody is assumed to be by all definitions a rigid body matrix. Then this is a faster inverse method.
|
||
|
inline void inverseRigidBodyMatrix( Float4x4 &output, const Float4x4 &rigidBody )
|
||
|
{ ::LinearAlgebra::_3D::inverseRigidBody( output, rigidBody ); }
|
||
|
|
||
|
inline void translationMatrix( Float4x4 &output, const Float3 &position )
|
||
|
{ ::LinearAlgebra::_3D::translationMatrix( output, position ); }
|
||
|
|
||
|
// counterclockwise rotation around X axis
|
||
|
inline void rotationMatrix_AxisX( Float4x4 &output, const Float &radian )
|
||
|
{ ::LinearAlgebra::_3D::rotationMatrix_AxisX( output, radian ); }
|
||
|
|
||
|
// counterclockwise rotation around Y axis
|
||
|
inline void rotationMatrix_AxisY( Float4x4 &output, const Float &radian )
|
||
|
{ ::LinearAlgebra::_3D::rotationMatrix_AxisY( output, radian ); }
|
||
|
|
||
|
// counterclockwise rotation around Z axis
|
||
|
inline void rotationMatrix_AxisZ( Float4x4 &output, const Float &radian )
|
||
|
{ ::LinearAlgebra::_3D::rotationMatrix_AxisZ( output, radian ); }
|
||
|
|
||
|
// counterclockwise rotation around any given Float3 vector (normalizedAxis). Please make sure it is normalized.
|
||
|
inline void rotationMatrix( Float4x4 &output, const Float &radian, const Float3 &normalizedAxis )
|
||
|
{ ::LinearAlgebra::_3D::rotationMatrix( output, normalizedAxis, radian ); }
|
||
|
|
||
|
/*
|
||
|
returns a deltaAngularAxis which is a vectorProduct of the particleMovementVector and leverVector.
|
||
|
angular: (1/I) * L, there I is known as the "moment of inertia", L as the "angular momentum vector".
|
||
|
lever: Displacement vector relative to the center of mass.
|
||
|
Recommended reading: http://en.wikipedia.org/wiki/Torque
|
||
|
*/
|
||
|
inline Float3 deltaAngularAxis( const Float3 &movement, const Float3 &lever )
|
||
|
{ return ::LinearAlgebra::_3D::deltaAngularAxis( movement, lever ); }
|
||
|
|
||
|
inline Float3 particleRotationMovement( const Float3 &deltaRadian, const Float3 &lever )
|
||
|
{ return ::LinearAlgebra::_3D::particleRotationMovement( deltaRadian, lever ); }
|
||
|
|
||
|
inline Float3 vectorProjection( const Float3 &vector, const Float3 &axis )
|
||
|
{ return ::LinearAlgebra::_3D::vectorProjection( vector, axis ); }
|
||
|
|
||
|
/*
|
||
|
output: is set to a rigibody matrix that revolve/rotate around centerOfMass and then translates.
|
||
|
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".
|
||
|
sumTranslation: sum of all the translation vectors.
|
||
|
centerOfMass: the point the particles is to revolve around, prior to translation. Default set to null vector aka origo.
|
||
|
Recommended reading: http://en.wikipedia.org/wiki/Torque
|
||
|
*/
|
||
|
inline void rigidBodyMatrix( Float4x4 &output, const Float3 &sumDeltaAngularAxis, const Float3 &sumTranslation, const Float3 ¢erOfMass = Float3::null )
|
||
|
{ ::LinearAlgebra::_3D::rigidBodyMatrix( output, sumDeltaAngularAxis, sumTranslation, centerOfMass ); }
|
||
|
|
||
|
/*
|
||
|
output; is set to an orthographic projection matrix.
|
||
|
width; of the projection sample volume.
|
||
|
height; of the projection sample volume.
|
||
|
near: Distance to the nearPlane.
|
||
|
far: Distance to the farPlane
|
||
|
*/
|
||
|
inline void projectionMatrix_Orthographic( Float4x4 &output, const Float &width, const Float &height, const Float &nearClip = ::std::numeric_limits<Float>::epsilon(), const Float &farClip = ::std::numeric_limits<Float>::max() )
|
||
|
{ ::LinearAlgebra::_3D::projectionMatrix_Orthographic( output, width, height, nearClip, farClip ); }
|
||
|
|
||
|
/*
|
||
|
output; is set to a perspective transform matrix.
|
||
|
vertFoV; is the vertical field of vision in radians. (se FoV Hor+ )
|
||
|
aspect; is the screenratio width/height (example 16/9 or 16/10 )
|
||
|
near: Distance to the nearPlane
|
||
|
far: Distance to the farPlane
|
||
|
*/
|
||
|
inline void projectionMatrix_Perspective( Float4x4 &output, const Float &verticalFoV, const Float &aspectRatio, const Float &nearClip = ::std::numeric_limits<Float>::epsilon(), const Float &farClip = ::std::numeric_limits<Float>::max() )
|
||
|
{ ::LinearAlgebra::_3D::projectionMatrix_Perspective( output, verticalFoV, aspectRatio, nearClip, farClip ); }
|
||
|
|
||
|
inline Float4x4 & viewProjectionMatrix( Float4x4 &output, const Float4x4 &view, const Float4x4 &projection )
|
||
|
{ return output = (view * projection).getTranspose(); }
|
||
|
|
||
|
inline Float4x4 & transformMatrix( Float4x4 &output, const Float4x4 &transformee, const Float4x4 &transformer )
|
||
|
{ return output = transformee * transformer; }
|
||
|
|
||
|
inline Float4x4 transformMatrix( const Float4x4 &transformee, const Float4x4 &transformer )
|
||
|
{ return transformee * transformer; }
|
||
|
|
||
|
inline Float4 & transformVector( Float4 &output, const Float4 &transformee, const Float4x4 &transformer )
|
||
|
{ return output = transformer * transformee; }
|
||
|
|
||
|
inline Float4 transformVector( const Float4 &transformee, const Float4x4 &transformer )
|
||
|
{ return transformee * transformer; }
|
||
|
} }
|
||
|
|
||
|
namespace Utility { namespace Value
|
||
|
{ // Utility Value Specializations
|
||
|
using namespace ::Oyster::Math;
|
||
|
|
||
|
template< > inline Float2 abs<Float2>( const Float2 &value )
|
||
|
{ return Float2( abs(value.x), abs(value.y) ); }
|
||
|
|
||
|
template< > inline Float2 max<Float2>( const Float2 &valueA, const Float2 &valueB )
|
||
|
{ return Float2( max(valueA.x, valueB.x), max(valueA.y, valueB.y) ); }
|
||
|
|
||
|
template< > inline Float2 min<Float2>( const Float2 &valueA, const Float2 &valueB )
|
||
|
{ return Float2( min(valueA.x, valueB.x), min(valueA.y, valueB.y) ); }
|
||
|
|
||
|
template< > inline Float3 abs<Float3>( const Float3 &value )
|
||
|
{ return Float3( abs(value.xy), abs(value.z) ); }
|
||
|
|
||
|
template< > inline Float3 max<Float3>( const Float3 &valueA, const Float3 &valueB )
|
||
|
{ return Float3( max(valueA.xy, valueB.xy), max(valueA.z, valueB.z) ); }
|
||
|
|
||
|
template< > inline Float3 min<Float3>( const Float3 &valueA, const Float3 &valueB )
|
||
|
{ return Float3( min(valueA.xy, valueB.xy), min(valueA.z, valueB.z) ); }
|
||
|
|
||
|
template< > inline Float4 abs<Float4>( const Float4 &value )
|
||
|
{ return Float4( abs(value.xyz), abs(value.w) ); }
|
||
|
|
||
|
template< > inline Float4 max<Float4>( const Float4 &valueA, const Float4 &valueB )
|
||
|
{ return Float4( max(valueA.xyz, valueB.xyz), max(valueA.w, valueB.w) ); }
|
||
|
|
||
|
template< > inline Float4 min<Float4>( const Float4 &valueA, const Float4 &valueB )
|
||
|
{ return Float4( min(valueA.xyz, valueB.xyz), min(valueA.w, valueB.w) ); }
|
||
|
|
||
|
template< > inline Float2x2 abs<Float2x2>( const Float2x2 &value )
|
||
|
{ return Float2x2( abs(value.v[0]), abs(value.v[1]) ); }
|
||
|
|
||
|
template< > inline Float2x2 max<Float2x2>( const Float2x2 &valueA, const Float2x2 &valueB )
|
||
|
{ return Float2x2( max(valueA.v[0], valueB.v[0]), max(valueA.v[1], valueB.v[1]) ); }
|
||
|
|
||
|
template< > inline Float2x2 min<Float2x2>( const Float2x2 &valueA, const Float2x2 &valueB )
|
||
|
{ return Float2x2( min(valueA.v[0], valueB.v[0]), min(valueA.v[1], valueB.v[1]) ); }
|
||
|
|
||
|
template< > inline Float3x3 abs<Float3x3>( const Float3x3 &value )
|
||
|
{ return Float3x3( abs(value.v[0]), abs(value.v[1]), abs(value[2]) ); }
|
||
|
|
||
|
template< > inline Float3x3 max<Float3x3>( const Float3x3 &valueA, const Float3x3 &valueB )
|
||
|
{ return Float3x3( max(valueA.v[0], valueB.v[0]), max(valueA.v[1], valueB.v[1]), max(valueA.v[2], valueB.v[2]) ); }
|
||
|
|
||
|
template< > inline Float3x3 min<Float3x3>( const Float3x3 &valueA, const Float3x3 &valueB )
|
||
|
{ return Float3x3( min(valueA.v[0], valueB.v[0]), min(valueA.v[1], valueB.v[1]), min(valueA.v[2], valueB.v[2]) ); }
|
||
|
|
||
|
template< > inline Float4x4 abs<Float4x4>( const Float4x4 &value )
|
||
|
{ return Float4x4( abs(value.v[0]), abs(value.v[1]), abs(value[2]), abs(value[3]) ); }
|
||
|
|
||
|
template< > inline Float4x4 max<Float4x4>( const Float4x4 &valueA, const Float4x4 &valueB )
|
||
|
{ return Float4x4( max(valueA.v[0], valueB.v[0]), max(valueA.v[1], valueB.v[1]), max(valueA.v[2], valueB.v[2]), max(valueA.v[3], valueB.v[3]) ); }
|
||
|
|
||
|
template< > inline Float4x4 min<Float4x4>( const Float4x4 &valueA, const Float4x4 &valueB )
|
||
|
{ return Float4x4( min(valueA.v[0], valueB.v[0]), min(valueA.v[1], valueB.v[1]), min(valueA.v[2], valueB.v[2]), min(valueA.v[3], valueB.v[3]) ); }
|
||
|
} }
|
||
|
|
||
|
#endif
|