Apply clang-format-all.sh using the _clang-format file through all the cpp/.h files. make sure not to apply it to certain serialization structures, since some parser expects the * as part of the name, instead of type. This commit contains no other changes aside from adding and applying clang-format-all.sh
856 lines
26 KiB
C++
856 lines
26 KiB
C++
///////////////////////////////////////////////////////////////////////////////
|
|
// Matrice.h
|
|
// =========
|
|
// NxN Matrix Math classes
|
|
//
|
|
// The elements of the matrix are stored as column major order.
|
|
// | 0 2 | | 0 3 6 | | 0 4 8 12 |
|
|
// | 1 3 | | 1 4 7 | | 1 5 9 13 |
|
|
// | 2 5 8 | | 2 6 10 14 |
|
|
// | 3 7 11 15 |
|
|
//
|
|
// AUTHOR: Song Ho Ahn (song.ahn@gmail.com)
|
|
// CREATED: 2005-06-24
|
|
// UPDATED: 2013-09-30
|
|
//
|
|
// Copyright (C) 2005 Song Ho Ahn
|
|
///////////////////////////////////////////////////////////////////////////////
|
|
|
|
#ifndef MATH_MATRICES_H
|
|
#define MATH_MATRICES_H
|
|
|
|
#include <iostream>
|
|
#include <iomanip>
|
|
#include "Vectors.h"
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// 2x2 matrix
|
|
///////////////////////////////////////////////////////////////////////////
|
|
class Matrix2
|
|
{
|
|
public:
|
|
// constructors
|
|
Matrix2(); // init with identity
|
|
Matrix2(const float src[4]);
|
|
Matrix2(float m0, float m1, float m2, float m3);
|
|
|
|
void set(const float src[4]);
|
|
void set(float m0, float m1, float m2, float m3);
|
|
void setRow(int index, const float row[2]);
|
|
void setRow(int index, const Vector2& v);
|
|
void setColumn(int index, const float col[2]);
|
|
void setColumn(int index, const Vector2& v);
|
|
|
|
const float* get() const;
|
|
float getDeterminant();
|
|
|
|
Matrix2& identity();
|
|
Matrix2& transpose(); // transpose itself and return reference
|
|
Matrix2& invert();
|
|
|
|
// operators
|
|
Matrix2 operator+(const Matrix2& rhs) const; // add rhs
|
|
Matrix2 operator-(const Matrix2& rhs) const; // subtract rhs
|
|
Matrix2& operator+=(const Matrix2& rhs); // add rhs and update this object
|
|
Matrix2& operator-=(const Matrix2& rhs); // subtract rhs and update this object
|
|
Vector2 operator*(const Vector2& rhs) const; // multiplication: v' = M * v
|
|
Matrix2 operator*(const Matrix2& rhs) const; // multiplication: M3 = M1 * M2
|
|
Matrix2& operator*=(const Matrix2& rhs); // multiplication: M1' = M1 * M2
|
|
bool operator==(const Matrix2& rhs) const; // exact compare, no epsilon
|
|
bool operator!=(const Matrix2& rhs) const; // exact compare, no epsilon
|
|
float operator[](int index) const; // subscript operator v[0], v[1]
|
|
float& operator[](int index); // subscript operator v[0], v[1]
|
|
|
|
friend Matrix2 operator-(const Matrix2& m); // unary operator (-)
|
|
friend Matrix2 operator*(float scalar, const Matrix2& m); // pre-multiplication
|
|
friend Vector2 operator*(const Vector2& vec, const Matrix2& m); // pre-multiplication
|
|
friend std::ostream& operator<<(std::ostream& os, const Matrix2& m);
|
|
|
|
protected:
|
|
private:
|
|
float m[4];
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// 3x3 matrix
|
|
///////////////////////////////////////////////////////////////////////////
|
|
class Matrix3
|
|
{
|
|
public:
|
|
// constructors
|
|
Matrix3(); // init with identity
|
|
Matrix3(const float src[9]);
|
|
Matrix3(float m0, float m1, float m2, // 1st column
|
|
float m3, float m4, float m5, // 2nd column
|
|
float m6, float m7, float m8); // 3rd column
|
|
|
|
void set(const float src[9]);
|
|
void set(float m0, float m1, float m2, // 1st column
|
|
float m3, float m4, float m5, // 2nd column
|
|
float m6, float m7, float m8); // 3rd column
|
|
void setRow(int index, const float row[3]);
|
|
void setRow(int index, const Vector3& v);
|
|
void setColumn(int index, const float col[3]);
|
|
void setColumn(int index, const Vector3& v);
|
|
|
|
const float* get() const;
|
|
float getDeterminant();
|
|
|
|
Matrix3& identity();
|
|
Matrix3& transpose(); // transpose itself and return reference
|
|
Matrix3& invert();
|
|
|
|
// operators
|
|
Matrix3 operator+(const Matrix3& rhs) const; // add rhs
|
|
Matrix3 operator-(const Matrix3& rhs) const; // subtract rhs
|
|
Matrix3& operator+=(const Matrix3& rhs); // add rhs and update this object
|
|
Matrix3& operator-=(const Matrix3& rhs); // subtract rhs and update this object
|
|
Vector3 operator*(const Vector3& rhs) const; // multiplication: v' = M * v
|
|
Matrix3 operator*(const Matrix3& rhs) const; // multiplication: M3 = M1 * M2
|
|
Matrix3& operator*=(const Matrix3& rhs); // multiplication: M1' = M1 * M2
|
|
bool operator==(const Matrix3& rhs) const; // exact compare, no epsilon
|
|
bool operator!=(const Matrix3& rhs) const; // exact compare, no epsilon
|
|
float operator[](int index) const; // subscript operator v[0], v[1]
|
|
float& operator[](int index); // subscript operator v[0], v[1]
|
|
|
|
friend Matrix3 operator-(const Matrix3& m); // unary operator (-)
|
|
friend Matrix3 operator*(float scalar, const Matrix3& m); // pre-multiplication
|
|
friend Vector3 operator*(const Vector3& vec, const Matrix3& m); // pre-multiplication
|
|
friend std::ostream& operator<<(std::ostream& os, const Matrix3& m);
|
|
|
|
protected:
|
|
private:
|
|
float m[9];
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// 4x4 matrix
|
|
///////////////////////////////////////////////////////////////////////////
|
|
class Matrix4
|
|
{
|
|
public:
|
|
// constructors
|
|
Matrix4(); // init with identity
|
|
Matrix4(const float src[16]);
|
|
Matrix4(float m00, float m01, float m02, float m03, // 1st column
|
|
float m04, float m05, float m06, float m07, // 2nd column
|
|
float m08, float m09, float m10, float m11, // 3rd column
|
|
float m12, float m13, float m14, float m15); // 4th column
|
|
|
|
void set(const float src[16]);
|
|
void set(float m00, float m01, float m02, float m03, // 1st column
|
|
float m04, float m05, float m06, float m07, // 2nd column
|
|
float m08, float m09, float m10, float m11, // 3rd column
|
|
float m12, float m13, float m14, float m15); // 4th column
|
|
void setRow(int index, const float row[4]);
|
|
void setRow(int index, const Vector4& v);
|
|
void setRow(int index, const Vector3& v);
|
|
void setColumn(int index, const float col[4]);
|
|
void setColumn(int index, const Vector4& v);
|
|
void setColumn(int index, const Vector3& v);
|
|
|
|
const float* get() const;
|
|
const float* getTranspose(); // return transposed matrix
|
|
float getDeterminant();
|
|
|
|
Matrix4& identity();
|
|
Matrix4& transpose(); // transpose itself and return reference
|
|
Matrix4& invert(); // check best inverse method before inverse
|
|
Matrix4& invertEuclidean(); // inverse of Euclidean transform matrix
|
|
Matrix4& invertAffine(); // inverse of affine transform matrix
|
|
Matrix4& invertProjective(); // inverse of projective matrix using partitioning
|
|
Matrix4& invertGeneral(); // inverse of generic matrix
|
|
|
|
// transform matrix
|
|
Matrix4& translate(float x, float y, float z); // translation by (x,y,z)
|
|
Matrix4& translate(const Vector3& v); //
|
|
Matrix4& rotate(float angle, const Vector3& axis); // rotate angle(degree) along the given axix
|
|
Matrix4& rotate(float angle, float x, float y, float z);
|
|
Matrix4& rotateX(float angle); // rotate on X-axis with degree
|
|
Matrix4& rotateY(float angle); // rotate on Y-axis with degree
|
|
Matrix4& rotateZ(float angle); // rotate on Z-axis with degree
|
|
Matrix4& scale(float scale); // uniform scale
|
|
Matrix4& scale(float sx, float sy, float sz); // scale by (sx, sy, sz) on each axis
|
|
|
|
// operators
|
|
Matrix4 operator+(const Matrix4& rhs) const; // add rhs
|
|
Matrix4 operator-(const Matrix4& rhs) const; // subtract rhs
|
|
Matrix4& operator+=(const Matrix4& rhs); // add rhs and update this object
|
|
Matrix4& operator-=(const Matrix4& rhs); // subtract rhs and update this object
|
|
Vector4 operator*(const Vector4& rhs) const; // multiplication: v' = M * v
|
|
Vector3 operator*(const Vector3& rhs) const; // multiplication: v' = M * v
|
|
Matrix4 operator*(const Matrix4& rhs) const; // multiplication: M3 = M1 * M2
|
|
Matrix4& operator*=(const Matrix4& rhs); // multiplication: M1' = M1 * M2
|
|
bool operator==(const Matrix4& rhs) const; // exact compare, no epsilon
|
|
bool operator!=(const Matrix4& rhs) const; // exact compare, no epsilon
|
|
float operator[](int index) const; // subscript operator v[0], v[1]
|
|
float& operator[](int index); // subscript operator v[0], v[1]
|
|
|
|
friend Matrix4 operator-(const Matrix4& m); // unary operator (-)
|
|
friend Matrix4 operator*(float scalar, const Matrix4& m); // pre-multiplication
|
|
friend Vector3 operator*(const Vector3& vec, const Matrix4& m); // pre-multiplication
|
|
friend Vector4 operator*(const Vector4& vec, const Matrix4& m); // pre-multiplication
|
|
friend std::ostream& operator<<(std::ostream& os, const Matrix4& m);
|
|
|
|
protected:
|
|
private:
|
|
float getCofactor(float m0, float m1, float m2,
|
|
float m3, float m4, float m5,
|
|
float m6, float m7, float m8);
|
|
|
|
float m[16];
|
|
float tm[16]; // transpose m
|
|
};
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// inline functions for Matrix2
|
|
///////////////////////////////////////////////////////////////////////////
|
|
inline Matrix2::Matrix2()
|
|
{
|
|
// initially identity matrix
|
|
identity();
|
|
}
|
|
|
|
inline Matrix2::Matrix2(const float src[4])
|
|
{
|
|
set(src);
|
|
}
|
|
|
|
inline Matrix2::Matrix2(float m0, float m1, float m2, float m3)
|
|
{
|
|
set(m0, m1, m2, m3);
|
|
}
|
|
|
|
inline void Matrix2::set(const float src[4])
|
|
{
|
|
m[0] = src[0];
|
|
m[1] = src[1];
|
|
m[2] = src[2];
|
|
m[3] = src[3];
|
|
}
|
|
|
|
inline void Matrix2::set(float m0, float m1, float m2, float m3)
|
|
{
|
|
m[0] = m0;
|
|
m[1] = m1;
|
|
m[2] = m2;
|
|
m[3] = m3;
|
|
}
|
|
|
|
inline void Matrix2::setRow(int index, const float row[2])
|
|
{
|
|
m[index] = row[0];
|
|
m[index + 2] = row[1];
|
|
}
|
|
|
|
inline void Matrix2::setRow(int index, const Vector2& v)
|
|
{
|
|
m[index] = v.x;
|
|
m[index + 2] = v.y;
|
|
}
|
|
|
|
inline void Matrix2::setColumn(int index, const float col[2])
|
|
{
|
|
m[index * 2] = col[0];
|
|
m[index * 2 + 1] = col[1];
|
|
}
|
|
|
|
inline void Matrix2::setColumn(int index, const Vector2& v)
|
|
{
|
|
m[index * 2] = v.x;
|
|
m[index * 2 + 1] = v.y;
|
|
}
|
|
|
|
inline const float* Matrix2::get() const
|
|
{
|
|
return m;
|
|
}
|
|
|
|
inline Matrix2& Matrix2::identity()
|
|
{
|
|
m[0] = m[3] = 1.0f;
|
|
m[1] = m[2] = 0.0f;
|
|
return *this;
|
|
}
|
|
|
|
inline Matrix2 Matrix2::operator+(const Matrix2& rhs) const
|
|
{
|
|
return Matrix2(m[0] + rhs[0], m[1] + rhs[1], m[2] + rhs[2], m[3] + rhs[3]);
|
|
}
|
|
|
|
inline Matrix2 Matrix2::operator-(const Matrix2& rhs) const
|
|
{
|
|
return Matrix2(m[0] - rhs[0], m[1] - rhs[1], m[2] - rhs[2], m[3] - rhs[3]);
|
|
}
|
|
|
|
inline Matrix2& Matrix2::operator+=(const Matrix2& rhs)
|
|
{
|
|
m[0] += rhs[0];
|
|
m[1] += rhs[1];
|
|
m[2] += rhs[2];
|
|
m[3] += rhs[3];
|
|
return *this;
|
|
}
|
|
|
|
inline Matrix2& Matrix2::operator-=(const Matrix2& rhs)
|
|
{
|
|
m[0] -= rhs[0];
|
|
m[1] -= rhs[1];
|
|
m[2] -= rhs[2];
|
|
m[3] -= rhs[3];
|
|
return *this;
|
|
}
|
|
|
|
inline Vector2 Matrix2::operator*(const Vector2& rhs) const
|
|
{
|
|
return Vector2(m[0] * rhs.x + m[2] * rhs.y, m[1] * rhs.x + m[3] * rhs.y);
|
|
}
|
|
|
|
inline Matrix2 Matrix2::operator*(const Matrix2& rhs) const
|
|
{
|
|
return Matrix2(m[0] * rhs[0] + m[2] * rhs[1], m[1] * rhs[0] + m[3] * rhs[1],
|
|
m[0] * rhs[2] + m[2] * rhs[3], m[1] * rhs[2] + m[3] * rhs[3]);
|
|
}
|
|
|
|
inline Matrix2& Matrix2::operator*=(const Matrix2& rhs)
|
|
{
|
|
*this = *this * rhs;
|
|
return *this;
|
|
}
|
|
|
|
inline bool Matrix2::operator==(const Matrix2& rhs) const
|
|
{
|
|
return (m[0] == rhs[0]) && (m[1] == rhs[1]) && (m[2] == rhs[2]) && (m[3] == rhs[3]);
|
|
}
|
|
|
|
inline bool Matrix2::operator!=(const Matrix2& rhs) const
|
|
{
|
|
return (m[0] != rhs[0]) || (m[1] != rhs[1]) || (m[2] != rhs[2]) || (m[3] != rhs[3]);
|
|
}
|
|
|
|
inline float Matrix2::operator[](int index) const
|
|
{
|
|
return m[index];
|
|
}
|
|
|
|
inline float& Matrix2::operator[](int index)
|
|
{
|
|
return m[index];
|
|
}
|
|
|
|
inline Matrix2 operator-(const Matrix2& rhs)
|
|
{
|
|
return Matrix2(-rhs[0], -rhs[1], -rhs[2], -rhs[3]);
|
|
}
|
|
|
|
inline Matrix2 operator*(float s, const Matrix2& rhs)
|
|
{
|
|
return Matrix2(s * rhs[0], s * rhs[1], s * rhs[2], s * rhs[3]);
|
|
}
|
|
|
|
inline Vector2 operator*(const Vector2& v, const Matrix2& rhs)
|
|
{
|
|
return Vector2(v.x * rhs[0] + v.y * rhs[1], v.x * rhs[2] + v.y * rhs[3]);
|
|
}
|
|
|
|
inline std::ostream& operator<<(std::ostream& os, const Matrix2& m)
|
|
{
|
|
os << std::fixed << std::setprecision(5);
|
|
os << "[" << std::setw(10) << m[0] << " " << std::setw(10) << m[2] << "]\n"
|
|
<< "[" << std::setw(10) << m[1] << " " << std::setw(10) << m[3] << "]\n";
|
|
os << std::resetiosflags(std::ios_base::fixed | std::ios_base::floatfield);
|
|
return os;
|
|
}
|
|
// END OF MATRIX2 INLINE //////////////////////////////////////////////////////
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// inline functions for Matrix3
|
|
///////////////////////////////////////////////////////////////////////////
|
|
inline Matrix3::Matrix3()
|
|
{
|
|
// initially identity matrix
|
|
identity();
|
|
}
|
|
|
|
inline Matrix3::Matrix3(const float src[9])
|
|
{
|
|
set(src);
|
|
}
|
|
|
|
inline Matrix3::Matrix3(float m0, float m1, float m2,
|
|
float m3, float m4, float m5,
|
|
float m6, float m7, float m8)
|
|
{
|
|
set(m0, m1, m2, m3, m4, m5, m6, m7, m8);
|
|
}
|
|
|
|
inline void Matrix3::set(const float src[9])
|
|
{
|
|
m[0] = src[0];
|
|
m[1] = src[1];
|
|
m[2] = src[2];
|
|
m[3] = src[3];
|
|
m[4] = src[4];
|
|
m[5] = src[5];
|
|
m[6] = src[6];
|
|
m[7] = src[7];
|
|
m[8] = src[8];
|
|
}
|
|
|
|
inline void Matrix3::set(float m0, float m1, float m2,
|
|
float m3, float m4, float m5,
|
|
float m6, float m7, float m8)
|
|
{
|
|
m[0] = m0;
|
|
m[1] = m1;
|
|
m[2] = m2;
|
|
m[3] = m3;
|
|
m[4] = m4;
|
|
m[5] = m5;
|
|
m[6] = m6;
|
|
m[7] = m7;
|
|
m[8] = m8;
|
|
}
|
|
|
|
inline void Matrix3::setRow(int index, const float row[3])
|
|
{
|
|
m[index] = row[0];
|
|
m[index + 3] = row[1];
|
|
m[index + 6] = row[2];
|
|
}
|
|
|
|
inline void Matrix3::setRow(int index, const Vector3& v)
|
|
{
|
|
m[index] = v.x;
|
|
m[index + 3] = v.y;
|
|
m[index + 6] = v.z;
|
|
}
|
|
|
|
inline void Matrix3::setColumn(int index, const float col[3])
|
|
{
|
|
m[index * 3] = col[0];
|
|
m[index * 3 + 1] = col[1];
|
|
m[index * 3 + 2] = col[2];
|
|
}
|
|
|
|
inline void Matrix3::setColumn(int index, const Vector3& v)
|
|
{
|
|
m[index * 3] = v.x;
|
|
m[index * 3 + 1] = v.y;
|
|
m[index * 3 + 2] = v.z;
|
|
}
|
|
|
|
inline const float* Matrix3::get() const
|
|
{
|
|
return m;
|
|
}
|
|
|
|
inline Matrix3& Matrix3::identity()
|
|
{
|
|
m[0] = m[4] = m[8] = 1.0f;
|
|
m[1] = m[2] = m[3] = m[5] = m[6] = m[7] = 0.0f;
|
|
return *this;
|
|
}
|
|
|
|
inline Matrix3 Matrix3::operator+(const Matrix3& rhs) const
|
|
{
|
|
return Matrix3(m[0] + rhs[0], m[1] + rhs[1], m[2] + rhs[2],
|
|
m[3] + rhs[3], m[4] + rhs[4], m[5] + rhs[5],
|
|
m[6] + rhs[6], m[7] + rhs[7], m[8] + rhs[8]);
|
|
}
|
|
|
|
inline Matrix3 Matrix3::operator-(const Matrix3& rhs) const
|
|
{
|
|
return Matrix3(m[0] - rhs[0], m[1] - rhs[1], m[2] - rhs[2],
|
|
m[3] - rhs[3], m[4] - rhs[4], m[5] - rhs[5],
|
|
m[6] - rhs[6], m[7] - rhs[7], m[8] - rhs[8]);
|
|
}
|
|
|
|
inline Matrix3& Matrix3::operator+=(const Matrix3& rhs)
|
|
{
|
|
m[0] += rhs[0];
|
|
m[1] += rhs[1];
|
|
m[2] += rhs[2];
|
|
m[3] += rhs[3];
|
|
m[4] += rhs[4];
|
|
m[5] += rhs[5];
|
|
m[6] += rhs[6];
|
|
m[7] += rhs[7];
|
|
m[8] += rhs[8];
|
|
return *this;
|
|
}
|
|
|
|
inline Matrix3& Matrix3::operator-=(const Matrix3& rhs)
|
|
{
|
|
m[0] -= rhs[0];
|
|
m[1] -= rhs[1];
|
|
m[2] -= rhs[2];
|
|
m[3] -= rhs[3];
|
|
m[4] -= rhs[4];
|
|
m[5] -= rhs[5];
|
|
m[6] -= rhs[6];
|
|
m[7] -= rhs[7];
|
|
m[8] -= rhs[8];
|
|
return *this;
|
|
}
|
|
|
|
inline Vector3 Matrix3::operator*(const Vector3& rhs) const
|
|
{
|
|
return Vector3(m[0] * rhs.x + m[3] * rhs.y + m[6] * rhs.z,
|
|
m[1] * rhs.x + m[4] * rhs.y + m[7] * rhs.z,
|
|
m[2] * rhs.x + m[5] * rhs.y + m[8] * rhs.z);
|
|
}
|
|
|
|
inline Matrix3 Matrix3::operator*(const Matrix3& rhs) const
|
|
{
|
|
return Matrix3(m[0] * rhs[0] + m[3] * rhs[1] + m[6] * rhs[2], m[1] * rhs[0] + m[4] * rhs[1] + m[7] * rhs[2], m[2] * rhs[0] + m[5] * rhs[1] + m[8] * rhs[2],
|
|
m[0] * rhs[3] + m[3] * rhs[4] + m[6] * rhs[5], m[1] * rhs[3] + m[4] * rhs[4] + m[7] * rhs[5], m[2] * rhs[3] + m[5] * rhs[4] + m[8] * rhs[5],
|
|
m[0] * rhs[6] + m[3] * rhs[7] + m[6] * rhs[8], m[1] * rhs[6] + m[4] * rhs[7] + m[7] * rhs[8], m[2] * rhs[6] + m[5] * rhs[7] + m[8] * rhs[8]);
|
|
}
|
|
|
|
inline Matrix3& Matrix3::operator*=(const Matrix3& rhs)
|
|
{
|
|
*this = *this * rhs;
|
|
return *this;
|
|
}
|
|
|
|
inline bool Matrix3::operator==(const Matrix3& rhs) const
|
|
{
|
|
return (m[0] == rhs[0]) && (m[1] == rhs[1]) && (m[2] == rhs[2]) &&
|
|
(m[3] == rhs[3]) && (m[4] == rhs[4]) && (m[5] == rhs[5]) &&
|
|
(m[6] == rhs[6]) && (m[7] == rhs[7]) && (m[8] == rhs[8]);
|
|
}
|
|
|
|
inline bool Matrix3::operator!=(const Matrix3& rhs) const
|
|
{
|
|
return (m[0] != rhs[0]) || (m[1] != rhs[1]) || (m[2] != rhs[2]) ||
|
|
(m[3] != rhs[3]) || (m[4] != rhs[4]) || (m[5] != rhs[5]) ||
|
|
(m[6] != rhs[6]) || (m[7] != rhs[7]) || (m[8] != rhs[8]);
|
|
}
|
|
|
|
inline float Matrix3::operator[](int index) const
|
|
{
|
|
return m[index];
|
|
}
|
|
|
|
inline float& Matrix3::operator[](int index)
|
|
{
|
|
return m[index];
|
|
}
|
|
|
|
inline Matrix3 operator-(const Matrix3& rhs)
|
|
{
|
|
return Matrix3(-rhs[0], -rhs[1], -rhs[2], -rhs[3], -rhs[4], -rhs[5], -rhs[6], -rhs[7], -rhs[8]);
|
|
}
|
|
|
|
inline Matrix3 operator*(float s, const Matrix3& rhs)
|
|
{
|
|
return Matrix3(s * rhs[0], s * rhs[1], s * rhs[2], s * rhs[3], s * rhs[4], s * rhs[5], s * rhs[6], s * rhs[7], s * rhs[8]);
|
|
}
|
|
|
|
inline Vector3 operator*(const Vector3& v, const Matrix3& m)
|
|
{
|
|
return Vector3(v.x * m[0] + v.y * m[1] + v.z * m[2], v.x * m[3] + v.y * m[4] + v.z * m[5], v.x * m[6] + v.y * m[7] + v.z * m[8]);
|
|
}
|
|
|
|
inline std::ostream& operator<<(std::ostream& os, const Matrix3& m)
|
|
{
|
|
os << std::fixed << std::setprecision(5);
|
|
os << "[" << std::setw(10) << m[0] << " " << std::setw(10) << m[3] << " " << std::setw(10) << m[6] << "]\n"
|
|
<< "[" << std::setw(10) << m[1] << " " << std::setw(10) << m[4] << " " << std::setw(10) << m[7] << "]\n"
|
|
<< "[" << std::setw(10) << m[2] << " " << std::setw(10) << m[5] << " " << std::setw(10) << m[8] << "]\n";
|
|
os << std::resetiosflags(std::ios_base::fixed | std::ios_base::floatfield);
|
|
return os;
|
|
}
|
|
// END OF MATRIX3 INLINE //////////////////////////////////////////////////////
|
|
|
|
///////////////////////////////////////////////////////////////////////////
|
|
// inline functions for Matrix4
|
|
///////////////////////////////////////////////////////////////////////////
|
|
inline Matrix4::Matrix4()
|
|
{
|
|
// initially identity matrix
|
|
identity();
|
|
}
|
|
|
|
inline Matrix4::Matrix4(const float src[16])
|
|
{
|
|
set(src);
|
|
}
|
|
|
|
inline Matrix4::Matrix4(float m00, float m01, float m02, float m03,
|
|
float m04, float m05, float m06, float m07,
|
|
float m08, float m09, float m10, float m11,
|
|
float m12, float m13, float m14, float m15)
|
|
{
|
|
set(m00, m01, m02, m03, m04, m05, m06, m07, m08, m09, m10, m11, m12, m13, m14, m15);
|
|
}
|
|
|
|
inline void Matrix4::set(const float src[16])
|
|
{
|
|
m[0] = src[0];
|
|
m[1] = src[1];
|
|
m[2] = src[2];
|
|
m[3] = src[3];
|
|
m[4] = src[4];
|
|
m[5] = src[5];
|
|
m[6] = src[6];
|
|
m[7] = src[7];
|
|
m[8] = src[8];
|
|
m[9] = src[9];
|
|
m[10] = src[10];
|
|
m[11] = src[11];
|
|
m[12] = src[12];
|
|
m[13] = src[13];
|
|
m[14] = src[14];
|
|
m[15] = src[15];
|
|
}
|
|
|
|
inline void Matrix4::set(float m00, float m01, float m02, float m03,
|
|
float m04, float m05, float m06, float m07,
|
|
float m08, float m09, float m10, float m11,
|
|
float m12, float m13, float m14, float m15)
|
|
{
|
|
m[0] = m00;
|
|
m[1] = m01;
|
|
m[2] = m02;
|
|
m[3] = m03;
|
|
m[4] = m04;
|
|
m[5] = m05;
|
|
m[6] = m06;
|
|
m[7] = m07;
|
|
m[8] = m08;
|
|
m[9] = m09;
|
|
m[10] = m10;
|
|
m[11] = m11;
|
|
m[12] = m12;
|
|
m[13] = m13;
|
|
m[14] = m14;
|
|
m[15] = m15;
|
|
}
|
|
|
|
inline void Matrix4::setRow(int index, const float row[4])
|
|
{
|
|
m[index] = row[0];
|
|
m[index + 4] = row[1];
|
|
m[index + 8] = row[2];
|
|
m[index + 12] = row[3];
|
|
}
|
|
|
|
inline void Matrix4::setRow(int index, const Vector4& v)
|
|
{
|
|
m[index] = v.x;
|
|
m[index + 4] = v.y;
|
|
m[index + 8] = v.z;
|
|
m[index + 12] = v.w;
|
|
}
|
|
|
|
inline void Matrix4::setRow(int index, const Vector3& v)
|
|
{
|
|
m[index] = v.x;
|
|
m[index + 4] = v.y;
|
|
m[index + 8] = v.z;
|
|
}
|
|
|
|
inline void Matrix4::setColumn(int index, const float col[4])
|
|
{
|
|
m[index * 4] = col[0];
|
|
m[index * 4 + 1] = col[1];
|
|
m[index * 4 + 2] = col[2];
|
|
m[index * 4 + 3] = col[3];
|
|
}
|
|
|
|
inline void Matrix4::setColumn(int index, const Vector4& v)
|
|
{
|
|
m[index * 4] = v.x;
|
|
m[index * 4 + 1] = v.y;
|
|
m[index * 4 + 2] = v.z;
|
|
m[index * 4 + 3] = v.w;
|
|
}
|
|
|
|
inline void Matrix4::setColumn(int index, const Vector3& v)
|
|
{
|
|
m[index * 4] = v.x;
|
|
m[index * 4 + 1] = v.y;
|
|
m[index * 4 + 2] = v.z;
|
|
}
|
|
|
|
inline const float* Matrix4::get() const
|
|
{
|
|
return m;
|
|
}
|
|
|
|
inline const float* Matrix4::getTranspose()
|
|
{
|
|
tm[0] = m[0];
|
|
tm[1] = m[4];
|
|
tm[2] = m[8];
|
|
tm[3] = m[12];
|
|
tm[4] = m[1];
|
|
tm[5] = m[5];
|
|
tm[6] = m[9];
|
|
tm[7] = m[13];
|
|
tm[8] = m[2];
|
|
tm[9] = m[6];
|
|
tm[10] = m[10];
|
|
tm[11] = m[14];
|
|
tm[12] = m[3];
|
|
tm[13] = m[7];
|
|
tm[14] = m[11];
|
|
tm[15] = m[15];
|
|
return tm;
|
|
}
|
|
|
|
inline Matrix4& Matrix4::identity()
|
|
{
|
|
m[0] = m[5] = m[10] = m[15] = 1.0f;
|
|
m[1] = m[2] = m[3] = m[4] = m[6] = m[7] = m[8] = m[9] = m[11] = m[12] = m[13] = m[14] = 0.0f;
|
|
return *this;
|
|
}
|
|
|
|
inline Matrix4 Matrix4::operator+(const Matrix4& rhs) const
|
|
{
|
|
return Matrix4(m[0] + rhs[0], m[1] + rhs[1], m[2] + rhs[2], m[3] + rhs[3],
|
|
m[4] + rhs[4], m[5] + rhs[5], m[6] + rhs[6], m[7] + rhs[7],
|
|
m[8] + rhs[8], m[9] + rhs[9], m[10] + rhs[10], m[11] + rhs[11],
|
|
m[12] + rhs[12], m[13] + rhs[13], m[14] + rhs[14], m[15] + rhs[15]);
|
|
}
|
|
|
|
inline Matrix4 Matrix4::operator-(const Matrix4& rhs) const
|
|
{
|
|
return Matrix4(m[0] - rhs[0], m[1] - rhs[1], m[2] - rhs[2], m[3] - rhs[3],
|
|
m[4] - rhs[4], m[5] - rhs[5], m[6] - rhs[6], m[7] - rhs[7],
|
|
m[8] - rhs[8], m[9] - rhs[9], m[10] - rhs[10], m[11] - rhs[11],
|
|
m[12] - rhs[12], m[13] - rhs[13], m[14] - rhs[14], m[15] - rhs[15]);
|
|
}
|
|
|
|
inline Matrix4& Matrix4::operator+=(const Matrix4& rhs)
|
|
{
|
|
m[0] += rhs[0];
|
|
m[1] += rhs[1];
|
|
m[2] += rhs[2];
|
|
m[3] += rhs[3];
|
|
m[4] += rhs[4];
|
|
m[5] += rhs[5];
|
|
m[6] += rhs[6];
|
|
m[7] += rhs[7];
|
|
m[8] += rhs[8];
|
|
m[9] += rhs[9];
|
|
m[10] += rhs[10];
|
|
m[11] += rhs[11];
|
|
m[12] += rhs[12];
|
|
m[13] += rhs[13];
|
|
m[14] += rhs[14];
|
|
m[15] += rhs[15];
|
|
return *this;
|
|
}
|
|
|
|
inline Matrix4& Matrix4::operator-=(const Matrix4& rhs)
|
|
{
|
|
m[0] -= rhs[0];
|
|
m[1] -= rhs[1];
|
|
m[2] -= rhs[2];
|
|
m[3] -= rhs[3];
|
|
m[4] -= rhs[4];
|
|
m[5] -= rhs[5];
|
|
m[6] -= rhs[6];
|
|
m[7] -= rhs[7];
|
|
m[8] -= rhs[8];
|
|
m[9] -= rhs[9];
|
|
m[10] -= rhs[10];
|
|
m[11] -= rhs[11];
|
|
m[12] -= rhs[12];
|
|
m[13] -= rhs[13];
|
|
m[14] -= rhs[14];
|
|
m[15] -= rhs[15];
|
|
return *this;
|
|
}
|
|
|
|
inline Vector4 Matrix4::operator*(const Vector4& rhs) const
|
|
{
|
|
return Vector4(m[0] * rhs.x + m[4] * rhs.y + m[8] * rhs.z + m[12] * rhs.w,
|
|
m[1] * rhs.x + m[5] * rhs.y + m[9] * rhs.z + m[13] * rhs.w,
|
|
m[2] * rhs.x + m[6] * rhs.y + m[10] * rhs.z + m[14] * rhs.w,
|
|
m[3] * rhs.x + m[7] * rhs.y + m[11] * rhs.z + m[15] * rhs.w);
|
|
}
|
|
|
|
inline Vector3 Matrix4::operator*(const Vector3& rhs) const
|
|
{
|
|
return Vector3(m[0] * rhs.x + m[4] * rhs.y + m[8] * rhs.z,
|
|
m[1] * rhs.x + m[5] * rhs.y + m[9] * rhs.z,
|
|
m[2] * rhs.x + m[6] * rhs.y + m[10] * rhs.z);
|
|
}
|
|
|
|
inline Matrix4 Matrix4::operator*(const Matrix4& n) const
|
|
{
|
|
return Matrix4(m[0] * n[0] + m[4] * n[1] + m[8] * n[2] + m[12] * n[3], m[1] * n[0] + m[5] * n[1] + m[9] * n[2] + m[13] * n[3], m[2] * n[0] + m[6] * n[1] + m[10] * n[2] + m[14] * n[3], m[3] * n[0] + m[7] * n[1] + m[11] * n[2] + m[15] * n[3],
|
|
m[0] * n[4] + m[4] * n[5] + m[8] * n[6] + m[12] * n[7], m[1] * n[4] + m[5] * n[5] + m[9] * n[6] + m[13] * n[7], m[2] * n[4] + m[6] * n[5] + m[10] * n[6] + m[14] * n[7], m[3] * n[4] + m[7] * n[5] + m[11] * n[6] + m[15] * n[7],
|
|
m[0] * n[8] + m[4] * n[9] + m[8] * n[10] + m[12] * n[11], m[1] * n[8] + m[5] * n[9] + m[9] * n[10] + m[13] * n[11], m[2] * n[8] + m[6] * n[9] + m[10] * n[10] + m[14] * n[11], m[3] * n[8] + m[7] * n[9] + m[11] * n[10] + m[15] * n[11],
|
|
m[0] * n[12] + m[4] * n[13] + m[8] * n[14] + m[12] * n[15], m[1] * n[12] + m[5] * n[13] + m[9] * n[14] + m[13] * n[15], m[2] * n[12] + m[6] * n[13] + m[10] * n[14] + m[14] * n[15], m[3] * n[12] + m[7] * n[13] + m[11] * n[14] + m[15] * n[15]);
|
|
}
|
|
|
|
inline Matrix4& Matrix4::operator*=(const Matrix4& rhs)
|
|
{
|
|
*this = *this * rhs;
|
|
return *this;
|
|
}
|
|
|
|
inline bool Matrix4::operator==(const Matrix4& n) const
|
|
{
|
|
return (m[0] == n[0]) && (m[1] == n[1]) && (m[2] == n[2]) && (m[3] == n[3]) &&
|
|
(m[4] == n[4]) && (m[5] == n[5]) && (m[6] == n[6]) && (m[7] == n[7]) &&
|
|
(m[8] == n[8]) && (m[9] == n[9]) && (m[10] == n[10]) && (m[11] == n[11]) &&
|
|
(m[12] == n[12]) && (m[13] == n[13]) && (m[14] == n[14]) && (m[15] == n[15]);
|
|
}
|
|
|
|
inline bool Matrix4::operator!=(const Matrix4& n) const
|
|
{
|
|
return (m[0] != n[0]) || (m[1] != n[1]) || (m[2] != n[2]) || (m[3] != n[3]) ||
|
|
(m[4] != n[4]) || (m[5] != n[5]) || (m[6] != n[6]) || (m[7] != n[7]) ||
|
|
(m[8] != n[8]) || (m[9] != n[9]) || (m[10] != n[10]) || (m[11] != n[11]) ||
|
|
(m[12] != n[12]) || (m[13] != n[13]) || (m[14] != n[14]) || (m[15] != n[15]);
|
|
}
|
|
|
|
inline float Matrix4::operator[](int index) const
|
|
{
|
|
return m[index];
|
|
}
|
|
|
|
inline float& Matrix4::operator[](int index)
|
|
{
|
|
return m[index];
|
|
}
|
|
|
|
inline Matrix4 operator-(const Matrix4& rhs)
|
|
{
|
|
return Matrix4(-rhs[0], -rhs[1], -rhs[2], -rhs[3], -rhs[4], -rhs[5], -rhs[6], -rhs[7], -rhs[8], -rhs[9], -rhs[10], -rhs[11], -rhs[12], -rhs[13], -rhs[14], -rhs[15]);
|
|
}
|
|
|
|
inline Matrix4 operator*(float s, const Matrix4& rhs)
|
|
{
|
|
return Matrix4(s * rhs[0], s * rhs[1], s * rhs[2], s * rhs[3], s * rhs[4], s * rhs[5], s * rhs[6], s * rhs[7], s * rhs[8], s * rhs[9], s * rhs[10], s * rhs[11], s * rhs[12], s * rhs[13], s * rhs[14], s * rhs[15]);
|
|
}
|
|
|
|
inline Vector4 operator*(const Vector4& v, const Matrix4& m)
|
|
{
|
|
return Vector4(v.x * m[0] + v.y * m[1] + v.z * m[2] + v.w * m[3], v.x * m[4] + v.y * m[5] + v.z * m[6] + v.w * m[7], v.x * m[8] + v.y * m[9] + v.z * m[10] + v.w * m[11], v.x * m[12] + v.y * m[13] + v.z * m[14] + v.w * m[15]);
|
|
}
|
|
|
|
inline Vector3 operator*(const Vector3& v, const Matrix4& m)
|
|
{
|
|
return Vector3(v.x * m[0] + v.y * m[1] + v.z * m[2], v.x * m[4] + v.y * m[5] + v.z * m[6], v.x * m[8] + v.y * m[9] + v.z * m[10]);
|
|
}
|
|
|
|
inline std::ostream& operator<<(std::ostream& os, const Matrix4& m)
|
|
{
|
|
os << std::fixed << std::setprecision(5);
|
|
os << "[" << std::setw(10) << m[0] << " " << std::setw(10) << m[4] << " " << std::setw(10) << m[8] << " " << std::setw(10) << m[12] << "]\n"
|
|
<< "[" << std::setw(10) << m[1] << " " << std::setw(10) << m[5] << " " << std::setw(10) << m[9] << " " << std::setw(10) << m[13] << "]\n"
|
|
<< "[" << std::setw(10) << m[2] << " " << std::setw(10) << m[6] << " " << std::setw(10) << m[10] << " " << std::setw(10) << m[14] << "]\n"
|
|
<< "[" << std::setw(10) << m[3] << " " << std::setw(10) << m[7] << " " << std::setw(10) << m[11] << " " << std::setw(10) << m[15] << "]\n";
|
|
os << std::resetiosflags(std::ios_base::fixed | std::ios_base::floatfield);
|
|
return os;
|
|
}
|
|
// END OF MATRIX4 INLINE //////////////////////////////////////////////////////
|
|
#endif
|