Oystermath updated

Needs to be tested though.
removed OysterMath.cpp because it was not needed anymore
This commit is contained in:
Dander7BD 2013-11-09 01:23:30 +01:00
parent 426a45a47c
commit 60f448e97a
6 changed files with 1513 additions and 1330 deletions

View File

@ -3,7 +3,6 @@
// © Dan Andersson 2013 // © Dan Andersson 2013
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
#pragma once
#ifndef LINEARMATH_H #ifndef LINEARMATH_H
#define LINEARMATH_H #define LINEARMATH_H
@ -12,257 +11,439 @@
#include "Quaternion.h" #include "Quaternion.h"
#include <math.h> #include <math.h>
namespace LinearAlgebra
{
// x2 // x2
template<typename ElementType>
Matrix2x2<ElementType> operator * ( const Matrix2x2<ElementType> &left, const Matrix2x2<ElementType> &right )
{ return Matrix2x2<ElementType>( (left.m11 * right.m11) + (left.m21 * right.m12), (left.m11 * right.m21) + (left.m21 * right.m22), (left.m12 * right.m11) + (left.m22 * right.m12), (left.m12 * right.m21) + (left.m22 * right.m22) ); }
template<typename ElementType> template<typename ScalarType>
Vector2<ElementType> operator * ( const Matrix2x2<ElementType> &matrix, const Vector2<ElementType> &vector ) ::LinearAlgebra::Matrix2x2<ScalarType> operator * ( const ::LinearAlgebra::Matrix2x2<ScalarType> &left, const ::LinearAlgebra::Matrix2x2<ScalarType> &right )
{ return Vector2<ElementType>( (matrix.m11 * vector.x) + (matrix.m21 * vector.y), (matrix.m12 * vector.x) + (matrix.m22 * vector.y) ); } {
return ::LinearAlgebra::Matrix2x2<ScalarType>( (left.m11 * right.m11) + (left.m12 * right.m21),
(left.m11 * right.m12) + (left.m12 * right.m22),
(left.m21 * right.m11) + (left.m22 * right.m21),
(left.m21 * right.m12) + (left.m22 * right.m22) );
}
template<typename ElementType> template<typename ScalarType>
Vector2<ElementType> operator * ( const Vector2<ElementType> &vector, const Matrix2x2<ElementType> &left ) ::LinearAlgebra::Vector2<ScalarType> operator * ( const ::LinearAlgebra::Matrix2x2<ScalarType> &matrix, const ::LinearAlgebra::Vector2<ScalarType> &vector )
{ return Vector2<ElementType>( (vector.x * matrix.m11) + (vector.y * matrix.m12), (vector.x * matrix.m21) + (vector.y * matrix.m22) ); } {
return ::LinearAlgebra::Vector2<ScalarType>( (matrix.m11 * vector.x) + (matrix.m12 * vector.y),
(matrix.m21 * vector.x) + (matrix.m22 * vector.y) );
}
template<typename ScalarType>
::LinearAlgebra::Vector2<ScalarType> operator * ( const ::LinearAlgebra::Vector2<ScalarType> &vector, const ::LinearAlgebra::Matrix2x2<ScalarType> &left )
{
return ::LinearAlgebra::Vector2<ScalarType>( (vector.x * matrix.m11) + (vector.y * matrix.m21),
(vector.x * matrix.m12) + (vector.y * matrix.m22) );
}
// x3 // x3
template<typename ElementType>
Matrix3x3<ElementType> operator * ( const Matrix3x3<ElementType> &left, const Matrix3x3<ElementType> &right ) template<typename ScalarType>
::LinearAlgebra::Matrix3x3<ScalarType> operator * ( const ::LinearAlgebra::Matrix3x3<ScalarType> &left, const ::LinearAlgebra::Matrix3x3<ScalarType> &right )
{ {
Matrix3x3<ElementType> product, leftT = left.getTranspose(); return ::LinearAlgebra::Matrix3x3<ScalarType>( (left.m11 * right.m11) + (left.m12 * right.m21) + (left.m13 * right.m31), (left.m11 * right.m12) + (left.m12 * right.m22) + (left.m13 * right.m32), (left.m11 * right.m13) + (left.m12 * right.m23) + (left.m13 * right.m33),
for( int i = 0; i < 3; ++i ) for( int j = 0; j < 3; ++j ) (left.m21 * right.m11) + (left.m22 * right.m21) + (left.m23 * right.m31), (left.m21 * right.m12) + (left.m22 * right.m22) + (left.m23 * right.m32), (left.m21 * right.m13) + (left.m22 * right.m23) + (left.m23 * right.m33),
product.m[i][j] = leftT.v[i].dot(right.v[j]); (left.m31 * right.m11) + (left.m32 * right.m21) + (left.m33 * right.m31), (left.m31 * right.m12) + (left.m32 * right.m22) + (left.m33 * right.m32), (left.m31 * right.m13) + (left.m32 * right.m23) + (left.m33 * right.m33) );
return product;
} }
template<typename ElementType> template<typename ScalarType>
Vector3<ElementType> operator * ( const Matrix3x3<ElementType> &matrix, const Vector3<ElementType> &vector ) ::LinearAlgebra::Vector3<ScalarType> operator * ( const ::LinearAlgebra::Matrix3x3<ScalarType> &matrix, const ::LinearAlgebra::Vector3<ScalarType> &vector )
{ return Vector3<ElementType>( (matrix.m11 * vector.x) + (matrix.m21 * vector.y) + (matrix.m31 * vector.z), (matrix.m12 * vector.x) + (matrix.m22 * vector.y) + (matrix.m32 * vector.z), (matrix.m13 * vector.x) + (matrix.m23 * vector.y) + (matrix.m33 * vector.z) ); } {
return ::LinearAlgebra::Vector3<ScalarType>( (matrix.m11 * vector.x) + (matrix.m12 * vector.y) + (matrix.m13 * vector.z),
(matrix.m21 * vector.x) + (matrix.m22 * vector.y) + (matrix.m23 * vector.z),
(matrix.m31 * vector.x) + (matrix.m32 * vector.y) + (matrix.m33 * vector.z) );
}
template<typename ElementType> template<typename ScalarType>
Vector3<ElementType> operator * ( const Vector3<ElementType> &vector, const Matrix3x3<ElementType> &left ) ::LinearAlgebra::Vector3<ScalarType> operator * ( const ::LinearAlgebra::Vector3<ScalarType> &vector, const ::LinearAlgebra::Matrix3x3<ScalarType> &left )
{ return Vector3<ElementType>( (vector.x * matrix.m11) + (vector.y * matrix.m12) + (vector.z * matrix.m13), (vector.x * matrix.m21) + (vector.y * matrix.m22) + (vector.z * matrix.m23), (vector.x * matrix.m31) + (vector.y * matrix.m32) + (vector.z * matrix.m33) ); } {
return ::LinearAlgebra::Vector3<ScalarType>( (vector.x * matrix.m11) + (vector.y * matrix.m21) + (vector.z * matrix.m31),
(vector.x * matrix.m12) + (vector.y * matrix.m22) + (vector.z * matrix.m32),
(vector.x * matrix.m13) + (vector.y * matrix.m23) + (vector.z * matrix.m33) );
}
// x4 // x4
template<typename ElementType>
Matrix4x4<ElementType> operator * ( const Matrix4x4<ElementType> &left, const Matrix4x4<ElementType> &right ) template<typename ScalarType>
::LinearAlgebra::Matrix4x4<ScalarType> operator * ( const ::LinearAlgebra::Matrix4x4<ScalarType> &left, const ::LinearAlgebra::Matrix4x4<ScalarType> &right )
{ {
Matrix4x4<ElementType> product, rightT = right.getTranspose(); return ::LinearAlgebra::Matrix4x4<ScalarType>( (left.m11 * right.m11) + (left.m12 * right.m21) + (left.m13 * right.m31) + (left.m14 * right.m41), (left.m11 * right.m12) + (left.m12 * right.m22) + (left.m13 * right.m32) + (left.m14 * right.m42), (left.m11 * right.m13) + (left.m12 * right.m23) + (left.m13 * right.m33) + (left.m14 * right.m43), (left.m11 * right.m14) + (left.m12 * right.m24) + (left.m13 * right.m34) + (left.m14 * right.m44),
for( int i = 0; i < 4; ++i ) (left.m21 * right.m11) + (left.m22 * right.m21) + (left.m23 * right.m31) + (left.m24 * right.m41), (left.m21 * right.m12) + (left.m22 * right.m22) + (left.m23 * right.m32) + (left.m24 * right.m42), (left.m21 * right.m13) + (left.m22 * right.m23) + (left.m23 * right.m33) + (left.m24 * right.m43), (left.m21 * right.m14) + (left.m22 * right.m24) + (left.m23 * right.m34) + (left.m24 * right.m44),
{ (left.m31 * right.m11) + (left.m32 * right.m21) + (left.m33 * right.m31) + (left.m34 * right.m41), (left.m31 * right.m12) + (left.m32 * right.m22) + (left.m33 * right.m32) + (left.m34 * right.m42), (left.m31 * right.m13) + (left.m32 * right.m23) + (left.m33 * right.m33) + (left.m34 * right.m43), (left.m31 * right.m14) + (left.m32 * right.m24) + (left.m33 * right.m34) + (left.m34 * right.m44),
product.m[i][0] = left.v[i].dot(rightT.v[0]); (left.m41 * right.m11) + (left.m42 * right.m21) + (left.m43 * right.m31) + (left.m44 * right.m41), (left.m41 * right.m12) + (left.m42 * right.m22) + (left.m43 * right.m32) + (left.m44 * right.m42), (left.m41 * right.m13) + (left.m42 * right.m23) + (left.m43 * right.m33) + (left.m44 * right.m43), (left.m41 * right.m14) + (left.m42 * right.m24) + (left.m43 * right.m34) + (left.m44 * right.m44) );
product.m[i][1] = left.v[i].dot(rightT.v[1]);
product.m[i][2] = left.v[i].dot(rightT.v[2]);
product.m[i][3] = left.v[i].dot(rightT.v[3]);
}
return product;
} }
template<typename ElementType> template<typename ScalarType>
Vector4<ElementType> operator * ( const Matrix4x4<ElementType> &matrix, const Vector4<ElementType> &vector ) ::LinearAlgebra::Vector4<ScalarType> operator * ( const ::LinearAlgebra::Matrix4x4<ScalarType> &matrix, const ::LinearAlgebra::Vector4<ScalarType> &vector )
{ return Vector4<ElementType>( (matrix.m11 * vector.x) + (matrix.m21 * vector.y) + (matrix.m31 * vector.z) + (matrix.m41 * vector.w), (matrix.m12 * vector.x) + (matrix.m22 * vector.y) + (matrix.m32 * vector.z) + (matrix.m42 * vector.w), (matrix.m13 * vector.x) + (matrix.m23 * vector.y) + (matrix.m33 * vector.z) + (matrix.m43 * vector.w), (matrix.m14 * vector.x) + (matrix.m24 * vector.y) + (matrix.m34 * vector.z) + (matrix.m44 * vector.w) ); }
template<typename ElementType> // works for column weighted matrixes
Vector4<ElementType> operator * ( const Vector4<ElementType> &vector, const Matrix4x4<ElementType> &matrix )
{ return Vector4<ElementType>( (vector.x * matrix.m11) + (vector.y * matrix.m12) + (vector.z * matrix.m13) + (vector.w * matrix.m14), (vector.x * matrix.m21) + (vector.y * matrix.m22) + (vector.z * matrix.m23) + (vector.w * matrix.m24), (vector.x * matrix.m31) + (vector.y * matrix.m32) + (vector.z * matrix.m33) + (vector.w * matrix.m34), (vector.x * matrix.m41) + (vector.y * matrix.m42) + (vector.z * matrix.m43) + (vector.w * matrix.m44) ); }
namespace _2D
{ {
template<typename ElementType> return ::LinearAlgebra::Vector4<ScalarType>( (matrix.m11 * vector.x) + (matrix.m12 * vector.y) + (matrix.m13 * vector.z) + (matrix.m14 * vector.w),
inline void translationMatrix( Matrix3x3<ElementType> &output, const Vector2<ElementType> &position ) (matrix.m21 * vector.x) + (matrix.m22 * vector.y) + (matrix.m23 * vector.z) + (matrix.m24 * vector.w),
// { output = Matrix3x3<ElementType>( 1, 0, position.x, 0, 1, position.y, 0, 0, 1 ); } (matrix.m23 * vector.x) + (matrix.m32 * vector.y) + (matrix.m33 * vector.z) + (matrix.m34 * vector.w),
{ output = Matrix3x3<ElementType>( 1, 0, 0, 0, 1, 0, position.x, position.y, 1 ); } (matrix.m41 * vector.x) + (matrix.m42 * vector.y) + (matrix.m43 * vector.z) + (matrix.m44 * vector.w) );
}
template<typename ElementType> template<typename ScalarType>
void rotationMatrix( Matrix2x2<ElementType> &output, const ElementType &radian ) ::LinearAlgebra::Vector4<ScalarType> operator * ( const ::LinearAlgebra::Vector4<ScalarType> &vector, const ::LinearAlgebra::Matrix4x4<ScalarType> &matrix )
{ {
ElementType s = std::sin( radian ), return ::LinearAlgebra::Vector4<ScalarType>( (vector.x * matrix.m11) + (vector.y * matrix.m21) + (vector.z * matrix.m31) + (vector.w * matrix.m41),
(vector.x * matrix.m12) + (vector.y * matrix.m22) + (vector.z * matrix.m32) + (vector.w * matrix.m42),
(vector.x * matrix.m13) + (vector.y * matrix.m23) + (vector.z * matrix.m33) + (vector.w * matrix.m43),
(vector.x * matrix.m14) + (vector.y * matrix.m24) + (vector.z * matrix.m34) + (vector.w * matrix.m44) );
}
namespace LinearAlgebra
{
// Creates a solution matrix for 'out´= 'targetMem' * 'in'.
// Returns false if there is no explicit solution.
template<typename ScalarType>
bool SuperpositionMatrix( const Matrix2x2<ScalarType> &in, const Matrix2x2<ScalarType> &out, Matrix2x2<ScalarType> &targetMem )
{
ScalarType d = in.GetDeterminant();
if( d == 0 ) return false;
targetMem = out * (in.GetAdjoint() /= d);
return true;
}
// Creates a solution matrix for 'out´= 'targetMem' * 'in'.
// Returns false if there is no explicit solution.
template<typename ScalarType>
bool SuperpositionMatrix( const Matrix3x3<ScalarType> &in, const Matrix3x3<ScalarType> &out, Matrix3x3<ScalarType> &targetMem )
{
ScalarType d = in.GetDeterminant();
if( d == 0 ) return false;
targetMem = out * (in.GetAdjoint() /= d);
return true;
}
// Creates a solution matrix for 'out´= 'targetMem' * 'in'.
// Returns false if there is no explicit solution.
template<typename ScalarType>
bool SuperpositionMatrix( const Matrix4x4<ScalarType> &in, const Matrix4x4<ScalarType> &out, Matrix4x4<ScalarType> &targetMem )
{
ScalarType d = in.GetDeterminant();
if( d == 0 ) return false;
targetMem = out * (in.GetAdjoint() /= d);
return true;
}
}
namespace LinearAlgebra2D
{
template<typename ScalarType>
inline ::LinearAlgebra::Vector2<ScalarType> X_AxisTo( const ::LinearAlgebra::Vector2<ScalarType> &yAxis )
{ return ::LinearAlgebra::Vector2<ScalarType>( yAxis.y, -yAxis.x ); }
template<typename ScalarType>
inline ::LinearAlgebra::Vector2<ScalarType> Y_AxisTo( const ::LinearAlgebra::Vector2<ScalarType> &xAxis )
{ return ::LinearAlgebra::Vector2<ScalarType>( -xAxis.y, xAxis.x ); }
template<typename ScalarType>
inline ::LinearAlgebra::Matrix3x3<ScalarType> & TranslationMatrix( const ::LinearAlgebra::Vector2<ScalarType> &position, ::LinearAlgebra::Matrix3x3<ScalarType> &targetMem = ::LinearAlgebra::Matrix3x3<ScalarType>() )
{
return targetMem = ::LinearAlgebra::Matrix3x3<ScalarType>( 1, 0, position.x,
0, 1, position.y,
0, 0, 1 );
}
template<typename ScalarType>
inline ::LinearAlgebra::Matrix2x2<ScalarType> & RotationMatrix( const ScalarType &radian, ::LinearAlgebra::Matrix2x2<ScalarType> &targetMem = ::LinearAlgebra::Matrix2x2<ScalarType>() )
{
ScalarType s = ::std::sin( radian ),
c = ::std::cos( radian );
return targetMem = ::LinearAlgebra::Matrix2x2<ScalarType>( c, -s, s, c );
}
template<typename ScalarType>
inline ::LinearAlgebra::Matrix3x3<ScalarType> & RotationMatrix( const ScalarType &radian, ::LinearAlgebra::Matrix3x3<ScalarType> &targetMem = ::LinearAlgebra::Matrix3x3<ScalarType>() )
{
ScalarType s = ::std::sin( radian ),
c = ::std::cos( radian );
return targetMem = ::LinearAlgebra::Matrix3x3<ScalarType>( c,-s, 0, s, c, 0, 0, 0, 1 );
}
template<typename ScalarType>
inline ::LinearAlgebra::Matrix3x3<ScalarType> & OrientationMatrix( const ScalarType &radian, const ::LinearAlgebra::Vector2<ScalarType> &position, ::LinearAlgebra::Matrix3x3<ScalarType> &targetMem = ::LinearAlgebra::Matrix3x3<ScalarType>() )
{
ScalarType s = ::std::sin( radian ),
c = ::std::cos( radian );
return targetMem = ::LinearAlgebra::Matrix3x3<ScalarType>( c,-s, position.x,
s, c, position.y,
0, 0, 1 );
}
template<typename ScalarType>
inline ::LinearAlgebra::Matrix3x3<ScalarType> & OrientationMatrix( const ::LinearAlgebra::Vector2<ScalarType> &lookAt, const ::LinearAlgebra::Vector2<ScalarType> &position, ::LinearAlgebra::Matrix3x3<ScalarType> &targetMem = ::LinearAlgebra::Matrix3x3<ScalarType>() )
{
::LinearAlgebra::Vector2<ScalarType> direction = ( lookAt - position ).GetNormalized();
return targetMem = ::LinearAlgebra::Matrix3x3<ScalarType>( ::LinearAlgebra::Vector3<ScalarType>( X_AxisTo(direction), 0.0f ),
::LinearAlgebra::Vector3<ScalarType>( direction, 0.0f ),
::LinearAlgebra::Vector3<ScalarType>( position, 1.0f ) );
}
template<typename ScalarType>
inline ::LinearAlgebra::Matrix3x3<ScalarType> & OrientationMatrix( const ScalarType &radian, const ::LinearAlgebra::Vector2<ScalarType> &position, const ::LinearAlgebra::Vector2<ScalarType> &centerOfRotation, ::LinearAlgebra::Matrix3x3<ScalarType> &targetMem = ::LinearAlgebra::Matrix3x3<ScalarType>() )
{ // TODO: not tested
RotationMatrix( radian, targetMem );
targetMem.v[2].xy = position + centerOfRotation;
targetMem.v[2].x -= ::LinearAlgebra::Vector2<ScalarType>( targetMem.v[0].x, targetMem.v[1].x ).Dot( centerOfRotation );
targetMem.v[2].y -= ::LinearAlgebra::Vector2<ScalarType>( targetMem.v[0].y, targetMem.v[1].y ).Dot( centerOfRotation );
return targetMem;
}
template<typename ScalarType>
inline ::LinearAlgebra::Matrix3x3<ScalarType> & InverseOrientationMatrix( const ::LinearAlgebra::Matrix3x3<ScalarType> &orientationMatrix, ::LinearAlgebra::Matrix3x3<ScalarType> &targetMem = ::LinearAlgebra::Matrix3x3<ScalarType>() )
{
return targetMem = ::LinearAlgebra::Matrix3x3<ScalarType>( orientationMatrix.m11, orientationMatrix.m21, -orientationMatrix.v[0].xy.Dot(orientationMatrix.v[2].xy),
orientationMatrix.m12, orientationMatrix.m22, -orientationMatrix.v[1].xy.Dot(orientationMatrix.v[2].xy),
0, 0, 1 );
}
}
namespace LinearAlgebra3D
{
template<typename ScalarType>
inline ::LinearAlgebra::Matrix4x4<ScalarType> & TranslationMatrix( const ::LinearAlgebra::Vector3<ScalarType> &position, ::LinearAlgebra::Matrix4x4<ScalarType> &targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>() )
{
return targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>( 1, 0, 0, position.x,
0, 1, 0, position.y,
0, 0, 1, position.z,
0, 0, 0, 1 );
}
template<typename ScalarType>
inline ::LinearAlgebra::Matrix3x3<ScalarType> & RotationMatrix_AxisX( const ScalarType &radian, ::LinearAlgebra::Matrix3x3<ScalarType> &targetMem = ::LinearAlgebra::Matrix3x3<ScalarType>() )
{
ScalarType s = std::sin( radian ),
c = std::cos( radian ); c = std::cos( radian );
// output = Matrix2x2<ElementType>( c, -s, s, c ); return targetMem = ::LinearAlgebra::Matrix3x3<ScalarType>( 1, 0, 0,
output = Matrix2x2<ElementType>( c, s, -s, c ); 0, c,-s,
0, s, c );
} }
template<typename ElementType> template<typename ScalarType>
void rotationMatrix( Matrix3x3<ElementType> &output, const ElementType &radian ) inline ::LinearAlgebra::Matrix4x4<ScalarType> & RotationMatrix_AxisX( const ScalarType &radian, ::LinearAlgebra::Matrix4x4<ScalarType> &targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>() )
{ {
ElementType s = std::sin( radian ), ScalarType s = std::sin( radian ),
c = std::cos( radian ); c = std::cos( radian );
// output = Matrix3x3<ElementType>( c, -s, 0, s, c, 0, 0, 0, 1 ); return targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>( 1, 0, 0, 0,
output = Matrix3x3<ElementType>( c, s, 0, -s, c, 0, 0, 0, 1 ); 0, c,-s, 0,
0, s, c, 0,
0, 0, 0, 1 );
} }
template<typename ElementType> template<typename ScalarType>
void rigidBodyMatrix( Matrix3x3<ElementType> &output, const ElementType &radian, const Vector2<ElementType> &position ) inline ::LinearAlgebra::Matrix3x3<ScalarType> & RotationMatrix_AxisY( const ScalarType &radian, ::LinearAlgebra::Matrix3x3<ScalarType> &targetMem = ::LinearAlgebra::Matrix3x3<ScalarType>() )
{ {
ElementType s = std::sin( radian ), ScalarType s = std::sin( radian ),
c = std::cos( radian ); c = std::cos( radian );
// output = Matrix3x3<ElementType>( c, -s, position.x, s, c, position.y, 0, 0, 1 ); return targetMem = ::LinearAlgebra::Matrix3x3<ScalarType>( c, 0, s,
output = Matrix3x3<ElementType>( c, s, 0, -s, c, 0, position.x, position.y, 1 ); 0, 1, 0,
} -s, 0, c );
} }
namespace _3D template<typename ScalarType>
inline ::LinearAlgebra::Matrix4x4<ScalarType> & RotationMatrix_AxisY( const ScalarType &radian, ::LinearAlgebra::Matrix4x4<ScalarType> &targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>() )
{ {
template<typename ElementType> ScalarType s = std::sin( radian ),
inline void translationMatrix( Matrix4x4<ElementType> &output, const Vector3<ElementType> &position )
// { output = Matrix4x4<ElementType>( 1, 0, 0, position.x, 0, 1, 0, position.y, 0, 0, 1, position.z, 0, 0, 0, 1 ); }
{ output = Matrix4x4<ElementType>( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, position.x, position.y, position.z, 1 ); }
template<typename ElementType>
void inverseRigidBody( Matrix4x4<ElementType> &output, const Matrix4x4<ElementType> &rigidBody )
{
output = Matrix4x4<ElementType>( rigidBody.m11, rigidBody.m21, rigidBody.m31, 0,
rigidBody.m12, rigidBody.m22, rigidBody.m32, 0,
rigidBody.m13, rigidBody.m23, rigidBody.m33, 0,
-rigidBody.v[3].xyz.dot(rigidBody.v[0].xyz),
-rigidBody.v[3].xyz.dot(rigidBody.v[1].xyz),
-rigidBody.v[3].xyz.dot(rigidBody.v[2].xyz), 1 );
}
template<typename ElementType>
void rotationMatrix_AxisX( Matrix3x3<ElementType> &output, const ElementType &radian )
{
ElementType s = std::sin( radian ),
c = std::cos( radian ); c = std::cos( radian );
// output = Matrix3x3<ElementType>( 1, 0, 0, 0, c, -s, 0, s, c ); return targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>( c, 0, s, 0,
output = Matrix3x3<ElementType>( 1, 0, 0, 0, c, s, 0, -s, c ); 0, 1, 0, 0,
-s, 0, c, 0,
0, 0, 0, 1 );
} }
template<typename ElementType> template<typename ScalarType>
void rotationMatrix_AxisX( Matrix4x4<ElementType> &output, const ElementType &radian ) inline ::LinearAlgebra::Matrix3x3<ScalarType> & RotationMatrix_AxisZ( const ScalarType &radian, ::LinearAlgebra::Matrix3x3<ScalarType> &targetMem = ::LinearAlgebra::Matrix3x3<ScalarType>() )
{ return ::LinearAlgebra2D::RotationMatrix( radian, targetMem ); }
template<typename ScalarType>
inline ::LinearAlgebra::Matrix4x4<ScalarType> & RotationMatrix_AxisZ( const ScalarType &radian, ::LinearAlgebra::Matrix4x4<ScalarType> &targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>() )
{ {
ElementType s = std::sin( radian ), ScalarType s = std::sin( radian ),
c = std::cos( radian ); c = std::cos( radian );
// output = Matrix4x4<ElementType>( 1, 0, 0, 0, 0, c, -s, 0, 0, s, c, 0, 0, 0, 0, 1 ); return targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>( c,-s, 0, 0,
output = Matrix4x4<ElementType>( 1, 0, 0, 0, 0, c, s, 0, 0, -s, c, 0, 0, 0, 0, 1 ); s, c, 0, 0,
0, 0, 1, 0,
0, 0, 0, 1 );
} }
template<typename ElementType> template<typename ScalarType>
void rotationMatrix_AxisY( Matrix3x3<ElementType> &output, const ElementType &radian ) ::LinearAlgebra::Matrix4x4<ScalarType> & RotationMatrix( const ::LinearAlgebra::Vector3<ScalarType> &normalizedAxis, const ScalarType &radian, ::LinearAlgebra::Matrix4x4<ScalarType> &targetMem )
{ { /// TODO: not verified
ElementType s = std::sin( radian ), ScalarType r = radian * 0.5f,
c = std::cos( radian );
// output = Matrix3x3<ElementType>( c, 0, s, 0, 1, 0, -s, 0, c );
output = Matrix3x3<ElementType>( c, 0, -s, 0, 1, 0, s, 0, c );
}
template<typename ElementType>
void rotationMatrix_AxisY( Matrix4x4<ElementType> &output, const ElementType &radian )
{
ElementType s = std::sin( radian ),
c = std::cos( radian );
// output = Matrix4x4<ElementType>( c, 0, s, 0, 0, 1, 0, 0, -s, 0, c, 0, 0, 0, 0, 1 );
output = Matrix4x4<ElementType>( c, 0, -s, 0, 0, 1, 0, 0, s, 0, c, 0, 0, 0, 0, 1 );
}
template<typename ElementType>
inline void rotationMatrix_AxisZ( Matrix3x3<ElementType> &output, const ElementType &radian )
{ ::LinearAlgebra::_2D::rotationMatrix( output, radian ); }
template<typename ElementType>
void rotationMatrix_AxisZ( Matrix4x4<ElementType> &output, const ElementType &radian )
{
ElementType s = std::sin( radian ),
c = std::cos( radian );
// output = Matrix4x4<ElementType>( c, -s, 0, 0, s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 );
output = Matrix4x4<ElementType>( c, s, 0, 0, -s, c, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 );
}
template<typename ElementType>
void rotationMatrix( Matrix4x4<ElementType> &output, const Vector3<ElementType> &normalizedAxis, const ElementType &radian )
{ // TODO : Optimize
ElementType r = radian * 0.5f,
s = std::sin( r ), s = std::sin( r ),
c = std::cos( r ); c = std::cos( r );
Quaternion<ElementType> q( normalizedAxis * s, c ), ::LinearAlgebra::Quaternion<ScalarType> q( normalizedAxis * s, c ),
qConj = q.getConjugate(); qConj = q.GetConjugate();
output.v[0] = Vector4<ElementType>( (q*Vector3<ElementType>(1,0,0)*qConj).imaginary, 0 ); targetMem.v[0] = ::LinearAlgebra::Vector4<ScalarType>( (q*::LinearAlgebra::Vector3<ScalarType>(1,0,0)*qConj).imaginary, 0 );
output.v[1] = Vector4<ElementType>( (q*Vector3<ElementType>(0,1,0)*qConj).imaginary, 0 ); targetMem.v[1] = ::LinearAlgebra::Vector4<ScalarType>( (q*::LinearAlgebra::Vector3<ScalarType>(0,1,0)*qConj).imaginary, 0 );
output.v[2] = Vector4<ElementType>( (q*Vector3<ElementType>(0,0,1)*qConj).imaginary, 0 ); targetMem.v[2] = ::LinearAlgebra::Vector4<ScalarType>( (q*::LinearAlgebra::Vector3<ScalarType>(0,0,1)*qConj).imaginary, 0 );
output.v[3] = Vector4<ElementType>( 0, 0, 0, 1 ); targetMem.v[3] = ::LinearAlgebra::Vector4<ScalarType>::standard_unit_W;
return targetMem;
} }
/* template<typename ScalarType>
returns a deltaAngularAxis which is a vectorProduct of the movementVector and leverVector. ::LinearAlgebra::Matrix4x4<ScalarType> & OrientationMatrix( const ::LinearAlgebra::Vector3<ScalarType> &sumDeltaAngularAxis, const ::LinearAlgebra::Vector3<ScalarType> &sumTranslation, ::LinearAlgebra::Matrix4x4<ScalarType> &targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>() )
angular: (1/I) * L, there I is known as the "moment of inertia", L as the "angular momentum vector". { /// TODO: not tested
lever: Displacement vector relative to the rotation pivot. ScalarType radian = sumDeltaAngularAxis.Dot( sumDeltaAngularAxis );
Recommended reading: http://en.wikipedia.org/wiki/Torque if( radian > 0 )
*/
template<typename ElementType>
inline Vector3<ElementType> deltaAngularAxis( const Vector3<ElementType> &movement, const Vector3<ElementType> &lever )
{ return movement.cross( lever ); }
template<typename ElementType>
inline Vector3<ElementType> particleRotationMovement( const Vector3<ElementType> &deltaRadian, const Vector3<ElementType> &lever )
{ return lever.cross(deltaRadian) /= lever.dot(lever); }
template<typename ElementType>
inline Vector3<ElementType> vectorProjection( const Vector3<ElementType> &vector, const Vector3<ElementType> &axis )
{ return axis * ( vector.dot(axis) / axis.dot(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
*/
template<typename ElementType>
void rigidBodyMatrix( Matrix4x4<ElementType> &output, const Vector3<ElementType> &sumDeltaAngularAxis, const Vector3<ElementType> &sumTranslation, const Vector3<ElementType> &centerOfMass = Vector3<ElementType>::null )
{ {
ElementType deltaRadian = sumDeltaAngularAxis.length(); radian = ::std::sqrt( radian );
if( deltaRadian != 0 ) ::LinearAlgebra::Vector3<ScalarType> axis = sumDeltaAngularAxis / radian;
RotationMatrix( axis, radian, targetMem );
}
else targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>::identity;
targetMem.v[3].xyz = sumTranslation;
return targetMem;
}
template<typename ScalarType>
::LinearAlgebra::Matrix4x4<ScalarType> & OrientationMatrix( const ::LinearAlgebra::Vector3<ScalarType> &sumDeltaAngularAxis, const ::LinearAlgebra::Vector3<ScalarType> &sumTranslation, const ::LinearAlgebra::Vector3<ScalarType> &centerOfRotation, ::LinearAlgebra::Matrix4x4<ScalarType> &targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>() )
{ /// TODO: not tested
ScalarType radian = sumDeltaAngularAxis.Dot( sumDeltaAngularAxis );
if( radian > 0 )
{ {
Vector3<ElementType> axis = sumDeltaAngularAxis / deltaRadian; radian = ::std::sqrt( radian );
rotationMatrix( output, axis, deltaRadian ); ::LinearAlgebra::Vector3<ScalarType> axis = sumDeltaAngularAxis / radian;
RotationMatrix( axis, radian, targetMem );
output.v[3].xyz = centerOfMass;
output.v[3].x -= centerOfMass.dot( output.v[0].xyz );
output.v[3].y -= centerOfMass.dot( output.v[1].xyz );
output.v[3].z -= centerOfMass.dot( output.v[2].xyz );
} }
else output = Matrix4x4<ElementType>::identity; else targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>::identity;
output.v[3].xyz += sumTranslation; targetMem.v[3].xyz = sumTranslation + centerOfRotation;
targetMem.v[3].x -= ::LinearAlgebra::Vector3<ScalarType>( targetMem.v[0].x, targetMem.v[1].x, targetMem.v[2].x ).Dot( centerOfRotation );
targetMem.v[3].y -= ::LinearAlgebra::Vector3<ScalarType>( targetMem.v[0].y, targetMem.v[1].y, targetMem.v[2].y ).Dot( centerOfRotation );
targetMem.v[3].z -= ::LinearAlgebra::Vector3<ScalarType>( targetMem.v[0].z, targetMem.v[1].z, targetMem.v[2].z ).Dot( centerOfRotation );
return targetMem;
} }
/* template<typename ScalarType>
output; is set to an orthographic projection matrix. inline ::LinearAlgebra::Matrix4x4<ScalarType> & InverseOrientationMatrix( const ::LinearAlgebra::Matrix4x4<ScalarType> &orientationMatrix, ::LinearAlgebra::Matrix4x4<ScalarType> &targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>() )
{
return targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>( orientationMatrix.m11, orientationMatrix.m21, orientationMatrix.m31, -orientationMatrix.v[0].xyz.Dot(orientationMatrix.v[3].xyz),
orientationMatrix.m12, orientationMatrix.m22, orientationMatrix.m32, -orientationMatrix.v[1].xyz.Dot(orientationMatrix.v[3].xyz),
orientationMatrix.m13, orientationMatrix.m23, orientationMatrix.m33, -orientationMatrix.v[2].xyz.Dot(orientationMatrix.v[3].xyz),
0, 0, 0, 1 );
}
/* Creates an orthographic projection matrix designed for DirectX enviroment.
width; of the projection sample volume. width; of the projection sample volume.
height; of the projection sample volume. height; of the projection sample volume.
nearClip: Distance to the nearClippingPlane. nearClip: Distance to the nearClippingPlane.
farClip: Distance to the farClippingPlane farClip: Distance to the farClippingPlane
targetMem; is set to an orthographic projection matrix and then returned.
*/ */
template<typename ElementType> template<typename ScalarType>
void projectionMatrix_Orthographic( Matrix4x4<ElementType> &output, const ElementType &width, const ElementType &height, const ElementType &nearClip, const ElementType &farClip ) ::LinearAlgebra::Matrix4x4<ScalarType> & ProjectionMatrix_Orthographic( const ScalarType &width, const ScalarType &height, const ScalarType &nearClip, const ScalarType &farClip, ::LinearAlgebra::Matrix4x4<ScalarType> &targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>() )
{ { /// TODO: not tested
ElementType c = 1; ScalarType c = 1 / (nearClip - farClip);
c /= nearClip - farClip; return targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>( 2/width, 0, 0, 0,
output = Matrix4x4<ElementType>( 2/width, 0, 0, 0,
0, 2/height, 0, 0, 0, 2/height, 0, 0,
0, 0, -c, 0, 0, 0, 0, -c, 0, 0,
0, nearClip*c, 1 ); 0, nearClip*c, 1 );
} }
/* /* Creates a perspective projection matrix designed for DirectX enviroment.
output; is set to a perspective transform matrix. vertFoV; is the vertical field of vision in radians. (lookup FoV Hor+ )
vertFoV; is the vertical field of vision in radians. (se FoV Hor+ )
aspect; is the screenratio width/height (example 16/9 or 16/10 ) aspect; is the screenratio width/height (example 16/9 or 16/10 )
nearClip: Distance to the nearClippingPlane nearClip: Distance to the nearClippingPlane
farClip: Distance to the farClippingPlane farClip: Distance to the farClippingPlane
targetMem; is set to a perspective transform matrix and then returned.
*/ */
template<typename ElementType> template<typename ScalarType>
void projectionMatrix_Perspective( Matrix4x4<ElementType> &output, const ElementType &vertFoV, const ElementType &aspect, const ElementType &nearClip, const ElementType &farClip ) ::LinearAlgebra::Matrix4x4<ScalarType> & ProjectionMatrix_Perspective( const ScalarType &vertFoV, const ScalarType &aspect, const ScalarType &nearClip, const ScalarType &farClip, ::LinearAlgebra::Matrix4x4<ScalarType> &targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>() )
{ { /// TODO: not tested
ElementType fov = 1 / ::std::tan( vertFoV * 0.5f ), ScalarType fov = 1 / ::std::tan( vertFoV * 0.5f ),
dDepth = farClip; dDepth = farClip / (farClip - nearClip);
dDepth /= farClip - nearClip; return targetMem = ::LinearAlgebra::Matrix4x4<ScalarType>( fov / aspect, 0, 0, 0,
output = Matrix4x4<ElementType>( fov / aspect, 0, 0, 0, 0, fov, 0, 0, 0, 0, dDepth, 1, 0, 0, -(dDepth * nearClip), 0 ); 0, fov, 0, 0,
} 0, 0, dDepth, -(dDepth * nearClip),
} 0, 0, 1, 0 );
} }
template<typename ScalarType>
inline ::LinearAlgebra::Vector3<ScalarType> VectorProjection( const ::LinearAlgebra::Vector3<ScalarType> &vector, const ::LinearAlgebra::Vector3<ScalarType> &axis )
{ return axis * ( vector.Dot(axis) / axis.Dot(axis) ); }
}
#include "Utilities.h"
namespace Utility { namespace Value
{ // Utility Value Specializations
template<typename ScalarType>
inline ::LinearAlgebra::Vector2<ScalarType> Abs( const ::LinearAlgebra::Vector2<ScalarType> &vector )
{ return ::LinearAlgebra::Vector2<ScalarType>( Abs(vector.x), Abs(vector.y) ); }
template<typename ScalarType>
inline ::LinearAlgebra::Vector3<ScalarType> Abs( const ::LinearAlgebra::Vector3<ScalarType> &vector )
{ return ::LinearAlgebra::Vector3<ScalarType>( Abs(vector.xy), Abs(vector.z) ); }
template<typename ScalarType>
inline ::LinearAlgebra::Vector4<ScalarType> Abs( const ::LinearAlgebra::Vector4<ScalarType> &vector )
{ return ::LinearAlgebra::Vector4<ScalarType>( Abs(vector.xyz), Abs(vector.w) ); }
template<typename ScalarType>
inline ::LinearAlgebra::Matrix2x2<ScalarType> Abs( const ::LinearAlgebra::Matrix2x2<ScalarType> &matrix )
{ return ::LinearAlgebra::Matrix2x2<ScalarType>( Abs(matrix.v[0]), Abs(matrix.v[1]) ); }
template<typename ScalarType>
inline ::LinearAlgebra::Matrix3x3<ScalarType> Abs( const ::LinearAlgebra::Matrix3x3<ScalarType> &matrix )
{ return ::LinearAlgebra::Matrix3x3<ScalarType>( Abs(matrix.v[0]), Abs(matrix.v[1]), Abs(matrix.v[2]) ); }
template<typename ScalarType>
inline ::LinearAlgebra::Matrix4x4<ScalarType> Abs( const ::LinearAlgebra::Matrix4x4<ScalarType> &matrix )
{ return ::LinearAlgebra::Matrix4x4<ScalarType>( Abs(matrix.v[0]), Abs(matrix.v[1]), Abs(matrix.v[2]), Abs(matrix.v[3]) ); }
template<typename ScalarType>
inline ::LinearAlgebra::Vector2<ScalarType> Max( const ::LinearAlgebra::Vector2<ScalarType> &vectorA, const ::LinearAlgebra::Vector2<ScalarType> &vectorB )
{ return ::LinearAlgebra::Vector2<ScalarType>( Max(vectorA.x, vectorB.x), Max(vectorA.y, vectorB.y) ); }
template<typename ScalarType>
inline ::LinearAlgebra::Vector3<ScalarType> Max( const ::LinearAlgebra::Vector3<ScalarType> &vectorA, const ::LinearAlgebra::Vector3<ScalarType> &vectorB )
{ return ::LinearAlgebra::Vector3<ScalarType>( Max(vectorA.xy, vectorB.xy), Max(vectorA.z, vectorB.z) ); }
template<typename ScalarType>
inline ::LinearAlgebra::Vector4<ScalarType> Max( const ::LinearAlgebra::Vector4<ScalarType> &vectorA, const ::LinearAlgebra::Vector4<ScalarType> &vectorB )
{ return ::LinearAlgebra::Vector4<ScalarType>( Max(vectorA.xyz, vectorB.xyz), Max(vectorA.w, vectorB.w) ); }
template<typename ScalarType>
inline ::LinearAlgebra::Matrix2x2<ScalarType> Max( const ::LinearAlgebra::Matrix2x2<ScalarType> &matrixA, const ::LinearAlgebra::Matrix2x2<ScalarType> &matrixB )
{ return ::LinearAlgebra::Matrix2x2<ScalarType>( Max(matrixA.v[0], matrixB.v[0]), Max(matrixA.v[1], matrixB.v[1]) ); }
template<typename ScalarType>
inline ::LinearAlgebra::Matrix3x3<ScalarType> Max( const ::LinearAlgebra::Matrix3x3<ScalarType> &matrixA, const ::LinearAlgebra::Matrix3x3<ScalarType> &matrixB )
{ return ::LinearAlgebra::Matrix3x3<ScalarType>( Max(matrixA.v[0], matrixB.v[0]), Max(matrixA.v[1], matrixB.v[1]), Max(matrixA.v[2], matrixB.v[2]) ); }
template<typename ScalarType>
inline ::LinearAlgebra::Matrix4x4<ScalarType> Max( const ::LinearAlgebra::Matrix4x4<ScalarType> &matrixA, const ::LinearAlgebra::Matrix4x4<ScalarType> &matrixB )
{ return ::LinearAlgebra::Matrix4x4<ScalarType>( Max(matrixA.v[0], matrixB.v[0]), Max(matrixA.v[1], matrixB.v[1]), Max(matrixA.v[2], matrixB.v[2]), Max(matrixA.v[3], matrixB.v[3]) ); }
template<typename ScalarType>
inline ::LinearAlgebra::Vector2<ScalarType> Min( const ::LinearAlgebra::Vector2<ScalarType> &vectorA, const ::LinearAlgebra::Vector2<ScalarType> &vectorB )
{ return ::LinearAlgebra::Vector2<ScalarType>( Min(vectorA.x, vectorB.x), Min(vectorA.y, vectorB.y) ); }
template<typename ScalarType>
inline ::LinearAlgebra::Vector3<ScalarType> Min( const ::LinearAlgebra::Vector3<ScalarType> &vectorA, const ::LinearAlgebra::Vector3<ScalarType> &vectorB )
{ return ::LinearAlgebra::Vector3<ScalarType>( Min(vectorA.xy, vectorB.xy), Min(vectorA.z, vectorB.z) ); }
template<typename ScalarType>
inline ::LinearAlgebra::Vector4<ScalarType> Min( const ::LinearAlgebra::Vector4<ScalarType> &vectorA, const ::LinearAlgebra::Vector4<ScalarType> &vectorB )
{ return ::LinearAlgebra::Vector4<ScalarType>( Min(vectorA.xyz, vectorB.xyz), Min(vectorA.w, vectorB.w) ); }
template<typename ScalarType>
inline ::LinearAlgebra::Matrix2x2<ScalarType> Min( const ::LinearAlgebra::Matrix2x2<ScalarType> &matrixA, const ::LinearAlgebra::Matrix2x2<ScalarType> &matrixB )
{ return ::LinearAlgebra::Matrix2x2<ScalarType>( Min(matrixA.v[0], matrixB.v[0]), Min(matrixA.v[1], matrixB.v[1]) ); }
template<typename ScalarType>
inline ::LinearAlgebra::Matrix3x3<ScalarType> Min( const ::LinearAlgebra::Matrix3x3<ScalarType> &matrixA, const ::LinearAlgebra::Matrix3x3<ScalarType> &matrixB )
{ return ::LinearAlgebra::Matrix3x3<ScalarType>( Min(matrixA.v[0], matrixB.v[0]), Min(matrixA.v[1], matrixB.v[1]), Min(matrixA.v[2], matrixB.v[2]) ); }
template<typename ScalarType>
inline ::LinearAlgebra::Matrix4x4<ScalarType> Min( const ::LinearAlgebra::Matrix4x4<ScalarType> &matrixA, const ::LinearAlgebra::Matrix4x4<ScalarType> &matrixB )
{ return ::LinearAlgebra::Matrix4x4<ScalarType>( Min(matrixA.v[0], matrixB.v[0]), Min(matrixA.v[1], matrixB.v[1]), Min(matrixA.v[2], matrixB.v[2]), Min(matrixA.v[3], matrixB.v[3]) ); }
} }
#endif #endif

File diff suppressed because it is too large Load Diff

View File

@ -1,32 +0,0 @@
/////////////////////////////////////////////////////////////////////
// by Dan Andersson 2013
/////////////////////////////////////////////////////////////////////
#include "OysterMath.h"
namespace Oyster { namespace Math
{
Float2 & operator *= ( Float2 &left, const Float2 &right )
{
left.x *= right.x;
left.y *= right.y;
return left;
}
Float3 & operator *= ( Float3 &left, const Float3 &right )
{
left.x *= right.x;
left.y *= right.y;
left.z *= right.z;
return left;
}
Float4 & operator *= ( Float4 &left, const Float4 &right )
{
left.x *= right.x;
left.y *= right.y;
left.z *= right.z;
left.w *= right.w;
return left;
}
} }

View File

@ -2,7 +2,6 @@
// by Dan Andersson 2013 // by Dan Andersson 2013
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
#pragma once
#ifndef OYSTER_MATH_H #ifndef OYSTER_MATH_H
#define OYSTER_MATH_H #define OYSTER_MATH_H
@ -10,211 +9,224 @@
#include "LinearMath.h" #include "LinearMath.h"
#include <limits> #include <limits>
namespace Oyster { namespace Math namespace Oyster { namespace Math /// Oyster's native math library
{ {
typedef float Float; typedef float Float; /// Oyster's native scalar is float
typedef ::LinearAlgebra::Vector2<Float> Float2; typedef ::LinearAlgebra::Vector2<Float> Float2; /// 2D Linear Vector for Oyster
typedef ::LinearAlgebra::Vector3<Float> Float3; typedef ::LinearAlgebra::Vector3<Float> Float3; /// 3D Linear Vector for Oyster
typedef ::LinearAlgebra::Vector4<Float> Float4; typedef ::LinearAlgebra::Vector4<Float> Float4; /// 4D Linear Vector for Oyster
typedef ::LinearAlgebra::Matrix2x2<Float> Float2x2; typedef ::LinearAlgebra::Matrix2x2<Float> Float2x2; /// 2x2 Linear Matrix for Oyster
typedef ::LinearAlgebra::Matrix3x3<Float> Float3x3; typedef ::LinearAlgebra::Matrix3x3<Float> Float3x3; /// 3x3 Linear Matrix for Oyster
typedef ::LinearAlgebra::Matrix4x4<Float> Float4x4; typedef ::LinearAlgebra::Matrix4x4<Float> Float4x4; /// 4x4 Linear Matrix for Oyster
typedef Float4x4 Matrix; typedef Float4x4 Matrix; // by popular demand
typedef Float2 Vector2; typedef Float2 Vector2; // by popular demand
typedef Float3 Vector3; typedef Float3 Vector3; // by popular demand
typedef Float4 Vector4; typedef Float4 Vector4; // by popular demand
/// 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
inline bool IsSupported()
{ return true; }
/// Creates a solution matrix for 'out´= 'targetMem' * 'in'.
/// Returns false if there is no explicit solution.
inline bool SuperpositionMatrix( const Float2x2 &in, const Float2x2 &out, Float2x2 &targetMem )
{ return ::LinearAlgebra::SuperpositionMatrix( in, out, targetMem ); }
Float2 & operator *= ( Float2 &left, const Float2 &right ); /// Creates a solution matrix for 'out´= 'targetMem' * 'in'.
/// Returns false if there is no explicit solution.
inline bool SuperpositionMatrix( const Float3x3 &in, const Float3x3 &out, Float3x3 &targetMem )
{ return ::LinearAlgebra::SuperpositionMatrix( in, out, targetMem ); }
inline Float2 operator * ( const Float2 &left, const Float2 &right ) /// Creates a solution matrix for 'out´= 'targetMem' * 'in'.
{ return Float2(left) *= right; } /// Returns false if there is no explicit solution.
inline bool SuperpositionMatrix( const Float4x4 &in, const Float4x4 &out, Float4x4 &targetMem )
inline Float2 operator * ( const Float &left, const Float2 &right ) { return ::LinearAlgebra::SuperpositionMatrix( in, out, targetMem ); }
{ 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 &centerOfMass = 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 inline ::Oyster::Math::Float2 & operator *= ( ::Oyster::Math::Float2 &left, const ::Oyster::Math::Float2 &right )
{ // Utility Value Specializations {
using namespace ::Oyster::Math; left.x *= right.x;
left.y *= right.y;
return left;
}
template< > inline Float2 abs<Float2>( const Float2 &value ) inline ::Oyster::Math::Float2 operator * ( const ::Oyster::Math::Float2 &left, const ::Oyster::Math::Float2 &right )
{ return Float2( abs(value.x), abs(value.y) ); } { return ::Oyster::Math::Float2(left) *= right; }
template< > inline Float2 max<Float2>( const Float2 &valueA, const Float2 &valueB ) inline ::Oyster::Math::Float2 operator * ( const ::Oyster::Math::Float &left, const ::Oyster::Math::Float2 &right )
{ return Float2( max(valueA.x, valueB.x), max(valueA.y, valueB.y) ); } { return ::Oyster::Math::Float2(right) *= left; }
template< > inline Float2 min<Float2>( const Float2 &valueA, const Float2 &valueB ) inline ::Oyster::Math::Float3 & operator *= ( ::Oyster::Math::Float3 &left, const ::Oyster::Math::Float3 &right )
{ return Float2( min(valueA.x, valueB.x), min(valueA.y, valueB.y) ); } {
left.x *= right.x;
left.y *= right.y;
left.z *= right.z;
return left;
}
template< > inline Float3 abs<Float3>( const Float3 &value ) inline ::Oyster::Math::Float3 operator * ( const ::Oyster::Math::Float3 &left, const ::Oyster::Math::Float3 &right )
{ return Float3( abs(value.xy), abs(value.z) ); } { return ::Oyster::Math::Float3(left) *= right; }
template< > inline Float3 max<Float3>( const Float3 &valueA, const Float3 &valueB ) inline ::Oyster::Math::Float3 operator * ( const ::Oyster::Math::Float &left, const ::Oyster::Math::Float3 &right )
{ return Float3( max(valueA.xy, valueB.xy), max(valueA.z, valueB.z) ); } { return ::Oyster::Math::Float3(right) *= left; }
template< > inline Float3 min<Float3>( const Float3 &valueA, const Float3 &valueB ) inline ::Oyster::Math::Float4 & operator *= ( ::Oyster::Math::Float4 &left, const ::Oyster::Math::Float4 &right )
{ return Float3( min(valueA.xy, valueB.xy), min(valueA.z, valueB.z) ); } {
left.x *= right.x;
left.y *= right.y;
left.z *= right.z;
left.w *= right.w;
return left;
}
template< > inline Float4 abs<Float4>( const Float4 &value ) inline ::Oyster::Math::Float4 operator * ( const ::Oyster::Math::Float4 &left, const ::Oyster::Math::Float4 &right )
{ return Float4( abs(value.xyz), abs(value.w) ); } { return ::Oyster::Math::Float4(left) *= right; }
template< > inline Float4 max<Float4>( const Float4 &valueA, const Float4 &valueB ) inline ::Oyster::Math::Float4 operator * ( const ::Oyster::Math::Float &left, const ::Oyster::Math::Float4 &right )
{ return Float4( max(valueA.xyz, valueB.xyz), max(valueA.w, valueB.w) ); } { return ::Oyster::Math::Float4(right) *= left; }
template< > inline Float4 min<Float4>( const Float4 &valueA, const Float4 &valueB ) inline ::Oyster::Math::Float2x2 operator * ( const ::Oyster::Math::Float &left, const ::Oyster::Math::Float2x2 &right )
{ return Float4( min(valueA.xyz, valueB.xyz), min(valueA.w, valueB.w) ); } { return ::Oyster::Math::Float2x2(right) *= left; }
template< > inline Float2x2 abs<Float2x2>( const Float2x2 &value ) inline ::Oyster::Math::Float3x3 operator * ( const ::Oyster::Math::Float &left, const ::Oyster::Math::Float3x3 &right )
{ return Float2x2( abs(value.v[0]), abs(value.v[1]) ); } { return ::Oyster::Math::Float3x3(right) *= left; }
template< > inline Float2x2 max<Float2x2>( const Float2x2 &valueA, const Float2x2 &valueB ) inline ::Oyster::Math::Float4x4 operator * ( const ::Oyster::Math::Float &left, const ::Oyster::Math::Float4x4 &right )
{ return Float2x2( max(valueA.v[0], valueB.v[0]), max(valueA.v[1], valueB.v[1]) ); } { return ::Oyster::Math::Float4x4(right) *= left; }
template< > inline Float2x2 min<Float2x2>( const Float2x2 &valueA, const Float2x2 &valueB ) namespace Oyster { namespace Math2D /// Oyster's native math library specialized for 2D
{ return Float2x2( min(valueA.v[0], valueB.v[0]), min(valueA.v[1], valueB.v[1]) ); } {
using namespace ::Oyster::Math; // deliberate inheritance from ::Oyster::Math namespace
template< > inline Float3x3 abs<Float3x3>( const Float3x3 &value ) /// If there is an Y-axis on a 2D plane, then there is an explicit X-axis on and that is what is returned.
{ return Float3x3( abs(value.v[0]), abs(value.v[1]), abs(value[2]) ); } /// Recommended too make sure that yAxis is normalized.
inline Float2 X_AxisTo( const Float2 &yAxis )
{ return ::LinearAlgebra2D::X_AxisTo(yAxis); }
template< > inline Float3x3 max<Float3x3>( const Float3x3 &valueA, const Float3x3 &valueB ) /// If there is an X-axis on a 2D plane, then there is an explicit Y-axis and that is what is returned.
{ return Float3x3( max(valueA.v[0], valueB.v[0]), max(valueA.v[1], valueB.v[1]), max(valueA.v[2], valueB.v[2]) ); } /// Recommended too make sure that yAxis is normalized.
inline Float2 Y_AxisTo( const Float2 &xAxis )
{ return ::LinearAlgebra2D::Y_AxisTo(xAxis); }
template< > inline Float3x3 min<Float3x3>( const Float3x3 &valueA, const Float3x3 &valueB ) /// Sets and returns targetMem to a translationMatrix with position as translation.
{ return Float3x3( min(valueA.v[0], valueB.v[0]), min(valueA.v[1], valueB.v[1]), min(valueA.v[2], valueB.v[2]) ); } inline Float3x3 & TranslationMatrix( const Float2 &position, Float3x3 &targetMem = Float3x3() )
{ return ::LinearAlgebra2D::TranslationMatrix( position, targetMem ); }
template< > inline Float4x4 abs<Float4x4>( const Float4x4 &value ) /// Sets and returns targetMem as a counterclockwise rotationMatrix
{ return Float4x4( abs(value.v[0]), abs(value.v[1]), abs(value[2]), abs(value[3]) ); } inline Float3x3 & RotationMatrix( const Float &radian, Float3x3 &targetMem = Float3x3() )
{ return ::LinearAlgebra2D::RotationMatrix( radian, targetMem ); }
template< > inline Float4x4 max<Float4x4>( const Float4x4 &valueA, const Float4x4 &valueB ) /// Sets and returns targetMem as an orientation Matrix with position as translation and radian rotation
{ 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]) ); } inline Float3x3 & OrientationMatrix( const Float2 &position, const Float &radian, Float3x3 &targetMem = Float3x3() )
{ return ::LinearAlgebra2D::OrientationMatrix( radian, position, targetMem ); }
template< > inline Float4x4 min<Float4x4>( const Float4x4 &valueA, const Float4x4 &valueB ) /// Sets and returns targetMem as an orientation Matrix with position as translation and local y-axis directed at lookAt
{ 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]) ); } inline Float3x3 & OrientationMatrix( const Float2 &position, const Float2 &lookAt, Float3x3 &targetMem = Float3x3() )
{ return ::LinearAlgebra2D::OrientationMatrix( lookAt, position, targetMem ); }
/// Sets and returns targetMem as an orientation Matrix that is rotated around localCenterOfRotation and then translated with position.
/// TODO: not tested
inline Float3x3 & OrientationMatrix( const Float2 &position, Float radian, const Float2 &localCenterOfRotation, Float3x3 &targetMem = Float3x3() )
{ return ::LinearAlgebra2D::OrientationMatrix( radian, position, localCenterOfRotation, targetMem ); }
/// 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.
inline Float3x3 & InverseOrientationMatrix( const Float3x3 &orientationMatrix, Float3x3 &targetMem = Float3x3() )
{ return ::LinearAlgebra2D::InverseOrientationMatrix( orientationMatrix, targetMem ); }
} }
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.
inline Float4x4 & TranslationMatrix( const Float3 &position, Float4x4 &targetMem = Float4x4() )
{ return ::LinearAlgebra3D::TranslationMatrix( position, targetMem ); }
/// Sets and returns targetMem as an counterclockwise rotation matrix around the global X-axis
inline Float4x4 & RotationMatrix_AxisX( const Float &radian, Float4x4 &targetMem = Float4x4() )
{ return ::LinearAlgebra3D::RotationMatrix_AxisX( radian, targetMem ); }
/// Sets and returns targetMem as an counterclockwise rotation matrix around the global Y-axis
inline Float4x4 & RotationMatrix_AxisY( const Float &radian, Float4x4 &targetMem = Float4x4() )
{ return ::LinearAlgebra3D::RotationMatrix_AxisY( radian, targetMem ); }
/// Sets and returns targetMem as an counterclockwise rotation matrix around the global Z-axis
inline Float4x4 & RotationMatrix_AxisZ( const Float &radian, Float4x4 &targetMem = Float4x4() )
{ return ::LinearAlgebra3D::RotationMatrix_AxisZ( radian, targetMem ); }
/// Sets and returns targetMem as an counterclockwise rotation matrix around the normalizedAxis.
/// Please make sure normalizedAxis is normalized.
inline Float4x4 & RotationMatrix( const Float &radian, const Float3 &normalizedAxis, Float4x4 &targetMem = Float4x4() )
{ return ::LinearAlgebra3D::RotationMatrix( normalizedAxis, radian, targetMem ); }
/// 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.
inline Float4x4 & InverseOrientationMatrix( const Float4x4 &orientationMatrix, Float4x4 &targetMem = Float4x4() )
{ return ::LinearAlgebra3D::InverseOrientationMatrix( orientationMatrix, targetMem ); }
/** Sets and returns targetMem as an orientation Matrix
* @param targetMem: is set to a rigibody matrix that rotate counterclockwise and then translates.
* @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.
* @return targetMem
@todo TODO: not tested
*/
inline Float4x4 & OrientationMatrix( const Float3 &sumDeltaAngularAxis, const Float3 &sumTranslation, Float4x4 &targetMem = Float4x4() )
{ return ::LinearAlgebra3D::OrientationMatrix( sumDeltaAngularAxis, sumTranslation, targetMem ); }
/** Sets and returns targetMem as an orientation Matrix
* @param targetMem: is set to a rigibody matrix that revolve/rotate counterclockwise around centerOfMass and then translates.
* @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.
* @return targetMem
@todo TODO: not tested
*/
inline Float4x4 & OrientationMatrix( const Float3 &sumDeltaAngularAxis, const Float3 &sumTranslation, const Float3 &centerOfMass, Float4x4 &targetMem = Float4x4() )
{ return ::LinearAlgebra3D::OrientationMatrix( sumDeltaAngularAxis, sumTranslation, centerOfMass, targetMem ); }
/** Creates an orthographic projection matrix designed for DirectX enviroment.
* @param targetMem; is set to an orthographic projection matrix.
* @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.
* @return targetMem
@todo TODO: not tested
*/
inline 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() )
{ return ::LinearAlgebra3D::ProjectionMatrix_Orthographic( width, height, nearClip, farClip, targetMem ); }
/** Creates a perspective projection matrix designed for DirectX enviroment.
* @param targetMem; is set to a perspective transform matrix.
* @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
* @return targetMem
@todo TODO: not tested
*/
inline 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() )
{ return ::LinearAlgebra3D::ProjectionMatrix_Perspective( verticalFoV, aspectRatio, nearClip, farClip, targetMem ); }
/// returns the component vector of vector that is parallell with axis
inline Float3 VectorProjection( const Float3 &vector, const Float3 &axis )
{ return ::LinearAlgebra3D::VectorProjection( vector, axis ); }
/// 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; }
/// Helper inline function that sets and then returns targetMem = transformer * transformee
inline Float4x4 & TransformMatrix( const Float4x4 &transformer, const Float4x4 &transformee, Float4x4 &targetMem = Float4x4() )
{ return targetMem = transformer * transformee; }
/// 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; }
} } } }
#endif #endif

View File

@ -3,7 +3,6 @@
// © Dan Andersson 2013 // © Dan Andersson 2013
///////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////
#pragma once
#ifndef LINEARALGEBRA_QUATERNION_H #ifndef LINEARALGEBRA_QUATERNION_H
#define LINEARALGEBRA_QUATERNION_H #define LINEARALGEBRA_QUATERNION_H
@ -12,172 +11,170 @@
namespace LinearAlgebra namespace LinearAlgebra
{ {
template<typename ElementType> template<typename ScalarType>
class Quaternion struct Quaternion
{ {
public: public:
union union
{ {
struct{ Vector3<ElementType> imaginary; ElementType real; }; struct{ Vector3<ScalarType> imaginary; ScalarType real; };
ElementType element[4]; ScalarType element[4];
char byte[sizeof(ElementType[2])]; char byte[sizeof(ScalarType[2])];
}; };
Quaternion( ); Quaternion( );
Quaternion( const Quaternion &quaternion ); Quaternion( const Quaternion &quaternion );
Quaternion( const Vector3<ElementType> &imaginary, const ElementType &real ); Quaternion( const Vector3<ScalarType> &imaginary, const ScalarType &real );
~Quaternion( );
operator ElementType* ( ); operator ScalarType* ( );
operator const ElementType* ( ) const; operator const ScalarType* ( ) const;
operator char* ( ); operator char* ( );
operator const char* ( ) const; operator const char* ( ) const;
ElementType & operator [] ( int i ); ScalarType & operator [] ( int i );
const ElementType & operator [] ( int i ) const; const ScalarType & operator [] ( int i ) const;
Quaternion<ElementType> & operator = ( const Quaternion<ElementType> &quaternion ); Quaternion<ScalarType> & operator = ( const Quaternion<ScalarType> &quaternion );
Quaternion<ElementType> & operator *= ( const ElementType &scalar ); Quaternion<ScalarType> & operator *= ( const ScalarType &scalar );
Quaternion<ElementType> & operator /= ( const ElementType &scalar ); Quaternion<ScalarType> & operator /= ( const ScalarType &scalar );
Quaternion<ElementType> & operator += ( const Quaternion<ElementType> &quaternion ); Quaternion<ScalarType> & operator += ( const Quaternion<ScalarType> &quaternion );
Quaternion<ElementType> & operator -= ( const Quaternion<ElementType> &quaternion ); Quaternion<ScalarType> & operator -= ( const Quaternion<ScalarType> &quaternion );
Quaternion<ElementType> operator * ( const Quaternion<ElementType> &quaternion ) const; Quaternion<ScalarType> operator * ( const Quaternion<ScalarType> &quaternion ) const;
Quaternion<ElementType> operator * ( const Vector3<ElementType> &vector ) const; Quaternion<ScalarType> operator * ( const Vector3<ScalarType> &vector ) const;
Quaternion<ElementType> operator * ( const ElementType &scalar ) const; Quaternion<ScalarType> operator * ( const ScalarType &scalar ) const;
Quaternion<ElementType> operator / ( const ElementType &scalar ) const; Quaternion<ScalarType> operator / ( const ScalarType &scalar ) const;
Quaternion<ElementType> operator + ( const Quaternion<ElementType> &quaternion ) const; Quaternion<ScalarType> operator + ( const Quaternion<ScalarType> &quaternion ) const;
Quaternion<ElementType> operator - ( const Quaternion<ElementType> &quaternion ) const; Quaternion<ScalarType> operator - ( const Quaternion<ScalarType> &quaternion ) const;
Quaternion<ElementType> operator - ( ) const; Quaternion<ScalarType> operator - ( ) const;
Quaternion<ElementType> getConjugate( ) const; Quaternion<ScalarType> GetConjugate( ) const;
}; };
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
// Body // Body
/////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////
template<typename ElementType> template<typename ScalarType>
Quaternion<ElementType>::Quaternion( ) : imaginary(0,0,0), real(0) {} Quaternion<ScalarType>::Quaternion( ) : imaginary(), real() {}
template<typename ElementType> template<typename ScalarType>
Quaternion<ElementType>::Quaternion( const Quaternion &quaternion ) : imaginary(quaternion.imaginary), real(quaternion.real) {} Quaternion<ScalarType>::Quaternion( const Quaternion &quaternion )
{ this->imaginary = quaternion.imaginary; this->real = quaternion.real; }
template<typename ElementType> template<typename ScalarType>
Quaternion<ElementType>::Quaternion( const Vector3<ElementType> &_imaginary, const ElementType &_real ) : imaginary(_imaginary), real(_real) {} Quaternion<ScalarType>::Quaternion( const Vector3<ScalarType> &_imaginary, const ScalarType &_real )
{ this->imaginary = _imaginary; this->real = _real; }
template<typename ElementType> template<typename ScalarType>
Quaternion<ElementType>::~Quaternion( ) { /* Nothing that needs to be done */ } inline Quaternion<ScalarType>::operator ScalarType* ( )
template<typename ElementType>
inline Quaternion<ElementType>::operator ElementType* ( )
{ return this->element; } { return this->element; }
template<typename ElementType> template<typename ScalarType>
inline Quaternion<ElementType>::operator const ElementType* ( ) const inline Quaternion<ScalarType>::operator const ScalarType* ( ) const
{ return this->element; } { return this->element; }
template<typename ElementType> template<typename ScalarType>
inline Quaternion<ElementType>::operator char* ( ) inline Quaternion<ScalarType>::operator char* ( )
{ return this->byte; } { return this->byte; }
template<typename ElementType> template<typename ScalarType>
inline Quaternion<ElementType>::operator const char* ( ) const inline Quaternion<ScalarType>::operator const char* ( ) const
{ return this->byte; } { return this->byte; }
template<typename ElementType> template<typename ScalarType>
inline ElementType & Quaternion<ElementType>::operator [] ( int i ) inline ScalarType & Quaternion<ScalarType>::operator [] ( int i )
{ return this->element[i]; } { return this->element[i]; }
template<typename ElementType> template<typename ScalarType>
inline const ElementType & Quaternion<ElementType>::operator [] ( int i ) const inline const ScalarType & Quaternion<ScalarType>::operator [] ( int i ) const
{ return this->element[i]; } { return this->element[i]; }
template<typename ElementType> template<typename ScalarType>
Quaternion<ElementType> & Quaternion<ElementType>::operator = ( const Quaternion<ElementType> &quaternion ) Quaternion<ScalarType> & Quaternion<ScalarType>::operator = ( const Quaternion<ScalarType> &quaternion )
{ {
this->imaginary = quaternion.imaginary; this->imaginary = quaternion.imaginary;
this->real = quaternion.real; this->real = quaternion.real;
return *this; return *this;
} }
template<typename ElementType> template<typename ScalarType>
Quaternion<ElementType> & Quaternion<ElementType>::operator *= ( const ElementType &scalar ) Quaternion<ScalarType> & Quaternion<ScalarType>::operator *= ( const ScalarType &scalar )
{ {
this->imaginary *= scalar; this->imaginary *= scalar;
this->real *= scalar; this->real *= scalar;
return *this; return *this;
} }
template<typename ElementType> template<typename ScalarType>
Quaternion<ElementType> & Quaternion<ElementType>::operator /= ( const ElementType &scalar ) Quaternion<ScalarType> & Quaternion<ScalarType>::operator /= ( const ScalarType &scalar )
{ {
this->imaginary /= scalar; this->imaginary /= scalar;
this->real /= scalar; this->real /= scalar;
return *this; return *this;
} }
template<typename ElementType> template<typename ScalarType>
Quaternion<ElementType> & Quaternion<ElementType>::operator += ( const Quaternion<ElementType> &quaternion ) Quaternion<ScalarType> & Quaternion<ScalarType>::operator += ( const Quaternion<ScalarType> &quaternion )
{ {
this->imaginary += quaternion.imaginary; this->imaginary += quaternion.imaginary;
this->real += quaternion.real; this->real += quaternion.real;
return *this; return *this;
} }
template<typename ElementType> template<typename ScalarType>
Quaternion<ElementType> & Quaternion<ElementType>::operator -= ( const Quaternion<ElementType> &quaternion ) Quaternion<ScalarType> & Quaternion<ScalarType>::operator -= ( const Quaternion<ScalarType> &quaternion )
{ {
this->imaginary -= quaternion.imaginary; this->imaginary -= quaternion.imaginary;
this->real -= quaternion.real; this->real -= quaternion.real;
return *this; return *this;
} }
template<typename ElementType> template<typename ScalarType>
Quaternion<ElementType> Quaternion<ElementType>::operator * ( const Quaternion<ElementType> &quaternion ) const Quaternion<ScalarType> Quaternion<ScalarType>::operator * ( const Quaternion<ScalarType> &quaternion ) const
{ {
Vector3<ElementType> im = this->imaginary.cross( quaternion.imaginary ); Vector3<ScalarType> im = this->imaginary.Cross( quaternion.imaginary );
im += (quaternion.imaginary * this->real); im += (quaternion.imaginary * this->real);
im += (this->imaginary * quaternion.real); im += (this->imaginary * quaternion.real);
ElementType re = this->real * quaternion.real; ScalarType re = this->real * quaternion.real;
re -= this->imaginary.dot( quaternion.imaginary ); re -= this->imaginary.Dot( quaternion.imaginary );
return Quaternion<ElementType>( im, re ); return Quaternion<ScalarType>( im, re );
} }
template<typename ElementType> template<typename ScalarType>
Quaternion<ElementType> Quaternion<ElementType>::operator * ( const Vector3<ElementType> &vector ) const Quaternion<ScalarType> Quaternion<ScalarType>::operator * ( const Vector3<ScalarType> &vector ) const
{ {
Vector3<ElementType> im = this->imaginary.cross( vector ); Vector3<ScalarType> im = this->imaginary.Cross( vector );
im += (vector * this->real); im += (vector * this->real);
ElementType re = this->imaginary.dot( vector ) * -1; ScalarType re = this->imaginary.Dot( vector ) * -1;
return Quaternion<ElementType>( im, re ); return Quaternion<ScalarType>( im, re );
} }
template<typename ElementType> template<typename ScalarType>
inline Quaternion<ElementType> Quaternion<ElementType>::operator * ( const ElementType &scalar ) const inline Quaternion<ScalarType> Quaternion<ScalarType>::operator * ( const ScalarType &scalar ) const
{ return Quaternion<ElementType>(*this) *= scalar; } { return Quaternion<ScalarType>(*this) *= scalar; }
template<typename ElementType> template<typename ScalarType>
inline Quaternion<ElementType> Quaternion<ElementType>::operator / ( const ElementType &scalar ) const inline Quaternion<ScalarType> Quaternion<ScalarType>::operator / ( const ScalarType &scalar ) const
{ return Quaternion<ElementType>(*this) /= scalar; } { return Quaternion<ScalarType>(*this) /= scalar; }
template<typename ElementType> template<typename ScalarType>
inline Quaternion<ElementType> Quaternion<ElementType>::operator + ( const Quaternion<ElementType> &quaternion ) const inline Quaternion<ScalarType> Quaternion<ScalarType>::operator + ( const Quaternion<ScalarType> &quaternion ) const
{ return Quaternion<ElementType>(*this) += quaternion; } { return Quaternion<ScalarType>(*this) += quaternion; }
template<typename ElementType> template<typename ScalarType>
inline Quaternion<ElementType> Quaternion<ElementType>::operator - ( const Quaternion<ElementType> &quaternion ) const inline Quaternion<ScalarType> Quaternion<ScalarType>::operator - ( const Quaternion<ScalarType> &quaternion ) const
{ return Quaternion<ElementType>(*this) -= quaternion; } { return Quaternion<ScalarType>(*this) -= quaternion; }
template<typename ElementType> template<typename ScalarType>
inline Quaternion<ElementType> Quaternion<ElementType>::operator - ( ) const inline Quaternion<ScalarType> Quaternion<ScalarType>::operator - ( ) const
{ return Quaternion<ElementType>(-this->imaginary, -this->real); } { return Quaternion<ScalarType>(-this->imaginary, -this->real); }
template<typename ElementType> template<typename ScalarType>
inline Quaternion<ElementType> Quaternion<ElementType>::getConjugate( ) const inline Quaternion<ScalarType> Quaternion<ScalarType>::GetConjugate( ) const
{ return Quaternion<ElementType>(this->imaginary * -1, this->real ); } { return Quaternion<ScalarType>(-this->imaginary, this->real ); }
} }
#endif #endif

File diff suppressed because it is too large Load Diff