218 lines
13 KiB
C++
218 lines
13 KiB
C++
#pragma once
|
|
|
|
#include <uf/config.h>
|
|
#include <uf/utils/math/vector.h>
|
|
|
|
#include "math.h"
|
|
namespace pod {
|
|
template<typename T = pod::Math::num_t, size_t R = 4, size_t C = R>
|
|
#if UF_MATRIX_ALIGNED
|
|
struct /*UF_API*/ alignas(16) Matrix {
|
|
#else
|
|
struct /*UF_API*/ Matrix {
|
|
#endif
|
|
// n-dimensional/unspecialized matrix access
|
|
T components[R*C] = {};
|
|
// T components[R][C] = {};
|
|
// T* array = (T*) this;
|
|
// POD information
|
|
typedef T type_t;
|
|
typedef T* container_t;
|
|
static const uint_fast8_t rows = R;
|
|
static const uint_fast8_t columns = C;
|
|
// Overload access
|
|
// Accessing via subscripts
|
|
inline T& operator[](uint_fast8_t i);
|
|
inline const T& operator[](uint_fast8_t i) const;
|
|
|
|
inline T& operator()(uint_fast8_t r, uint_fast8_t c);
|
|
inline const T& operator()(uint_fast8_t r, uint_fast8_t c) const;
|
|
|
|
// Arithmetic
|
|
Matrix<T,R,C> operator()() const; // Creation
|
|
Matrix<T,R,C> operator-() const; // Negation
|
|
Matrix<T,R,C> operator*( const Matrix<T,R,C>& matrix ) const; // Multiplication between two matrices
|
|
Matrix<T,R,C> operator*( T scalar ) const; // Multiplication between two matrices
|
|
Matrix<T,R,C> operator+( const Matrix<T,R,C>& matrix ) const; // Multiplication between two matrices
|
|
Matrix<T,R,C>& operator *=( const Matrix<T,R,C>& matrix ); // Multiplication set between two matrices
|
|
bool operator==( const Matrix<T,R,C>& matrix ) const; // Equality check between two matrices (equals)
|
|
bool operator!=( const Matrix<T,R,C>& matrix ) const; // Equality check between two matrices (not equals)
|
|
};
|
|
|
|
template<typename T = pod::Math::num_t> using Matrix2t = Matrix<T,2>;
|
|
typedef Matrix2t<> Matrix2;
|
|
typedef Matrix2t<float> Matrix2f;
|
|
|
|
template<typename T = pod::Math::num_t> using Matrix3t = Matrix<T,3>;
|
|
typedef Matrix3t<> Matrix3;
|
|
typedef Matrix3t<float> Matrix3f;
|
|
|
|
template<typename T = pod::Math::num_t> using Matrix4t = Matrix<T,4>;
|
|
typedef Matrix4t<> Matrix4;
|
|
typedef Matrix4t<float> Matrix4f;
|
|
}
|
|
|
|
namespace uf {
|
|
namespace matrix {
|
|
extern bool UF_API reverseInfiniteProjection;
|
|
|
|
template<typename T=pod::Math::num_t> pod::Matrix4t<T> /*UF_API*/ identity();
|
|
|
|
template<typename T=pod::Math::num_t> pod::Matrix4t<T> /*UF_API*/ initialize( const T* );
|
|
template<typename T=pod::Math::num_t> pod::Matrix4t<T> /*UF_API*/ initialize( const uf::stl::vector<T>& );
|
|
template<typename T> pod::Matrix<typename T::type_t, T::columns, T::columns> /*UF_API*/ identityi();
|
|
|
|
// Equality checking
|
|
template<typename T=pod::Matrix4> int /*UF_API*/ compareTo( const T& left, const T& right ); // Equality check between two matrices (less than)
|
|
template<typename T=pod::Matrix4> bool /*UF_API*/ equals( const T& left, const T& right ); // Equality check between two matrices (equals)
|
|
template<typename T=pod::Matrix4> bool /*UF_API*/ equals( const T& left, const T& right, float eps ); // Equality check between two matrices (equals)
|
|
// Basic arithmetic
|
|
// template<typename T=pod::Matrix4> pod::Matrix<typename T::type_t, C, C> /*UF_API*/ multiply( const T& left, const T& right ); // Multiplies two matrices of same type and size together
|
|
template<typename T, typename U> pod::Matrix<typename T::type_t, T::columns, T::columns> multiply( const T& left, const U& right ); // Multiplies two matrices of same type and size together
|
|
template<typename T> pod::Matrix4t<T> multiply( const pod::Matrix4t<T>& left, const pod::Matrix4t<T>& right ); // Multiplies two matrices of same type and size together
|
|
template<typename T=pod::Matrix4> T /*UF_API*/ transpose( const T& matrix );
|
|
|
|
template<typename T=pod::Math::num_t> pod::Matrix2t<T> inverse(const pod::Matrix2t<T>& mat );
|
|
template<typename T=pod::Math::num_t> pod::Matrix3t<T> inverse(const pod::Matrix3t<T>& mat );
|
|
template<typename T=pod::Math::num_t> pod::Matrix4t<T> inverse(const pod::Matrix4t<T>& mat );
|
|
|
|
template<typename T=pod::Math::num_t> pod::Vector2t<T> multiply(const pod::Matrix2t<T>& mat, const pod::Vector2t<T>& v );
|
|
template<typename T=pod::Math::num_t> pod::Vector3t<T> multiply(const pod::Matrix3t<T>& mat, const pod::Vector3t<T>& v );
|
|
template<typename T=pod::Math::num_t> pod::Vector3t<T> multiply( const pod::Matrix4t<T>& mat, const pod::Vector3t<T>& vector, T w = 1, bool = false );
|
|
template<typename T=pod::Math::num_t> pod::Vector4t<T> multiply( const pod::Matrix4t<T>& mat, const pod::Vector4t<T>& vector, bool = false );
|
|
|
|
template<typename T=pod::Matrix4> T /*UF_API*/ multiplyAll( const T& matrix, typename T::type_t scalar );
|
|
template<typename T=pod::Matrix4> T /*UF_API*/ add( const T& lhs, const T& rhs );
|
|
// Writes to first value
|
|
template<typename T=pod::Matrix4> T& /*UF_API*/ invert( T& matrix ); // Flip sign of all components
|
|
// template<typename T=pod::Matrix4> pod::Matrix<typename T::type_t, C, C>& /*UF_API*/ multiply_( T& left, const T& right ); // Multiplies two matrices of same type and size together
|
|
template<typename T, typename U> pod::Matrix<typename T::type_t, T::columns, T::columns> multiply_( T& left, const U& right ); // Multiplies two matrices of same type and size together
|
|
template<typename T> pod::Matrix<typename T::type_t, T::columns, T::columns> multiply_( T& left, const T& right );
|
|
template<typename T=pod::Matrix4> T& /*UF_API*/ translate_( T& matrix, const pod::Vector3t<typename T::type_t>& vector );
|
|
template<typename T=pod::Matrix4> T& /*UF_API*/ rotate_( T& matrix, const pod::Vector3t<typename T::type_t>& vector );
|
|
template<typename T=pod::Matrix4> T& /*UF_API*/ scale_( T& matrix, const pod::Vector3t<typename T::type_t>& vector );
|
|
// Complex arithmetic
|
|
template<typename T=pod::Matrix4> T /*UF_API*/ translate( const T& matrix, const pod::Vector3t<typename T::type_t>& vector );
|
|
template<typename T=pod::Matrix4> T /*UF_API*/ rotate( const T& matrix, const pod::Vector3t<typename T::type_t>& vector );
|
|
template<typename T=pod::Matrix4> T /*UF_API*/ scale( const T& matrix, const pod::Vector3t<typename T::type_t>& vector );
|
|
template<typename T=pod::Matrix4> pod::Vector3t<typename T::type_t> /*UF_API*/ eulerAngles( const T& matrix );
|
|
|
|
template<typename T=pod::Math::num_t> pod::Matrix4t<T> /*UF_API*/ orthographic( T, T, T, T, T, T );
|
|
template<typename T=pod::Math::num_t> pod::Matrix4t<T> /*UF_API*/ orthographic( T, T, T, T );
|
|
template<typename T=pod::Math::num_t> pod::Matrix4t<T> inline /*UF_API*/ orthographic( const pod::Vector2t<T>& lr, const pod::Vector2t<T>& bt, const pod::Vector2t<T>& nf ) {
|
|
return orthographic<T>( lr.x, lr.y, bt.x, bt.y, nf.x, nf.y );
|
|
}
|
|
template<typename T=pod::Math::num_t> pod::Matrix4t<T> inline /*UF_API*/ orthographic( const pod::Vector2t<T>& lr, const pod::Vector2t<T>& bt ) {
|
|
return orthographic<T>( lr.x, lr.y, bt.x, bt.y );
|
|
}
|
|
|
|
template<typename T=pod::Math::num_t> pod::Matrix4t<T> /*UF_API*/ perspective( T, T, T, T );
|
|
template<typename T=pod::Math::num_t> pod::Matrix4t<T> inline /*UF_API*/ perspective( T fov, T raidou, const pod::Vector2f& range ) {
|
|
return perspective( fov, raidou, range.x, range.y );
|
|
}
|
|
template<typename T=pod::Math::num_t> pod::Matrix4t<T> inline /*UF_API*/ perspective( T fov, const pod::Vector2ui& size, const pod::Vector2f& range ) {
|
|
return perspective( fov, (T) size.x / (T) size.y, range.x, range.y );
|
|
}
|
|
// Setting
|
|
template<typename T=pod::Matrix4> T& /*UF_API*/ copy( T& destination, const T& source );
|
|
template<typename T=pod::Matrix4> T& /*UF_API*/ copy( T& destination, typename T::type_t* const source );
|
|
|
|
template<typename T, size_t R, size_t C = R> uf::stl::string /*UF_API*/ toString( const pod::Matrix<T,R,C>& v );
|
|
template<typename T, size_t R, size_t C> ext::json::Value /*UF_API*/ encode( const pod::Matrix<T,R,C>& v, const ext::json::EncodingSettings& = {} );
|
|
template<typename T, size_t R, size_t C> pod::Matrix<T,R,C>& /*UF_API*/ decode( const ext::json::Value& v, pod::Matrix<T,R,C>& );
|
|
template<typename T, size_t R, size_t C> pod::Matrix<T,R,C> /*UF_API*/ decode( const ext::json::Value& v, const pod::Matrix<T,R,C>& = uf::matrix::identity() );
|
|
}
|
|
}
|
|
|
|
#if UF_USE_CLASS_OF_PODS
|
|
namespace uf {
|
|
template<typename T = pod::Math::num_t, std::size_t R = 4, std::size_t C = R>
|
|
class /*UF_API*/ Matrix {
|
|
public:
|
|
// Easily access POD's type
|
|
typedef pod::Matrix<T,R,C> pod_t;
|
|
// Replicate POD information
|
|
typedef T type_t;
|
|
typedef T* container_t;
|
|
static const uint_fast8_t rows = R;
|
|
static const uint_fast8_t columns = C;
|
|
protected:
|
|
// POD storage
|
|
Matrix<T,R,C>::pod_t m_pod;
|
|
public:
|
|
// C-tor
|
|
Matrix(); // initializes POD to 'def'
|
|
Matrix(const Matrix<T,R,C>::pod_t& pod); // copies POD altogether
|
|
Matrix(const T components[R][C]); // copies data into POD from 'components' (typed as C array)
|
|
Matrix(const T components[R*C]); // copies data into POD from 'components' (typed as C array)
|
|
Matrix(const uf::stl::vector<T>& components); // copies data into POD from 'components' (typed as std::matrix<T>)
|
|
// D-tor
|
|
// Unneccesary
|
|
// POD access
|
|
Matrix<T,R,C>::pod_t& data(); // Returns a reference of POD
|
|
const Matrix<T,R,C>::pod_t& data() const; // Returns a const-reference of POD
|
|
|
|
template<typename Q> typename Matrix<Q,R,C>::pod_t convert() const; // Returns a POD converted
|
|
// Alternative POD access
|
|
T* get(); // Returns a pointer to the entire array
|
|
const T* get() const; // Returns a const-pointer to the entire array
|
|
T& getComponent( uint_fast8_t i ); // Returns a reference to a single element
|
|
const T& getComponent( uint_fast8_t i ) const; // Returns a const-reference to a single element
|
|
// POD manipulation
|
|
T* set(const T components[R][C]); // Sets the entire array
|
|
T* set(const T components[R*C]); // Sets the entire array
|
|
T& setComponent( uint_fast8_t i, const T& value ); // Sets a single element
|
|
// Validation
|
|
bool isValid() const; // Checks if all components are valid (non NaN, inf, etc.)
|
|
// Basic arithmetic
|
|
inline uf::Matrix<T,C,C> multiply( const Matrix<T,R,C>& matrix ) const; // Multiplies two matrices of same type and size together
|
|
inline uf::Matrix<T,C,C> multiply( const Matrix<T,R,C>& matrix ); // Multiplies two matrices of same type and size together
|
|
inline pod::Vector3t<T> multiply( const pod::Vector3t<T>& vector ) const;
|
|
inline pod::Vector4t<T> multiply( const pod::Vector4t<T>& vector ) const;
|
|
inline uf::Matrix<T,R,C>& negate(); // Flip sign of all components
|
|
inline uf::Matrix<T,R,C>& translate( const pod::Vector3t<T>& vector );
|
|
inline uf::Matrix<T,R,C>& rotate( const pod::Vector3t<T>& vector );
|
|
inline uf::Matrix<T,R,C>& scale( const pod::Vector3t<T>& vector );
|
|
inline uf::Matrix<T,R,C>& invert();
|
|
inline uf::Matrix<T,R,C> inverse() const;
|
|
template<typename U>
|
|
inline uf::Matrix<T,C,C> multiply( const U& matrix ) const; // Multiplies two matrices of same type and size together
|
|
template<typename U>
|
|
inline uf::Matrix<T,C,C> multiply( const U& matrix ); // Multiplies two matrices of same type and size together
|
|
// Overloaded ops
|
|
// Accessing via subscripts
|
|
T& operator[](uint_fast8_t i);
|
|
const T& operator[](uint_fast8_t i) const;
|
|
// Arithmetic
|
|
inline Matrix<T,R,C> operator-() const; // Negation
|
|
inline Matrix<T,C,C> operator*( const Matrix<T,R,C>& matrix ) const; // Multiplication between two matrices
|
|
inline Matrix<T,C,C>& operator *=( const Matrix<T,R,C>& matrix ); // Multiplication set between two matrices
|
|
template<typename U> inline Matrix<T,C,C> operator*( const U& matrix ) const; // Multiplication between two matrices
|
|
inline bool operator==( const Matrix<T,R,C>& matrix ) const; // Equality check between two matrices (equals)
|
|
inline bool operator!=( const Matrix<T,R,C>& matrix ) const; // Equality check between two matrices (not equals)
|
|
|
|
inline operator pod_t&() { return this->m_pod; }
|
|
inline operator const pod_t&() const { return this->m_pod; }
|
|
};
|
|
template<typename T = pod::Math::num_t> using Matrix4t = Matrix<T,4>;
|
|
typedef Matrix4t<> Matrix4;
|
|
typedef Matrix4t<float> Matrix4f;
|
|
}
|
|
#endif
|
|
|
|
#include <sstream>
|
|
namespace uf {
|
|
namespace string {
|
|
template<typename T, size_t R, size_t C>
|
|
uf::stl::string /*UF_API*/ toString( const pod::Matrix<T,R,C>& v );
|
|
}
|
|
}
|
|
namespace ext {
|
|
namespace json {
|
|
template<typename T, size_t R, size_t C = R> ext::json::Value /*UF_API*/ encode( const pod::Matrix<T,R,C>& v );
|
|
template<typename T, size_t R, size_t C = R> pod::Matrix<T,R,C>& /*UF_API*/ decode( const ext::json::Value& v, pod::Matrix<T,R,C>& );
|
|
template<typename T, size_t R, size_t C = R> pod::Matrix<T,R,C> /*UF_API*/ decode( const ext::json::Value& v, const pod::Matrix<T,R,C>& = uf::matrix::identity() );
|
|
}
|
|
}
|
|
|
|
#include "matrix/matrix.inl" |