138 lines
5.6 KiB
C++
138 lines
5.6 KiB
C++
#pragma once
|
|
|
|
#include <J3ML/LinearAlgebra.h>
|
|
#include <J3ML/LinearAlgebra/Vector2.h>
|
|
#include <J3ML/LinearAlgebra/Vector3.h>
|
|
#include <J3ML/LinearAlgebra/Quaternion.h>
|
|
|
|
namespace LinearAlgebra {
|
|
/// A 3-by-3 matrix for linear transformations of 3D geometry.
|
|
/* This can represent any kind of linear transformations of 3D geometry, which include
|
|
* rotation, scale, shear, mirroring, and orthographic projection.
|
|
* A 3x3 matrix cannot represent translation, which requires a 3x4, or perspective projection (4x4).
|
|
* The elements of this matrix are
|
|
* m_00, m_01, m_02
|
|
* m_10, m_11, m_12
|
|
* m_20, m_21, m_22
|
|
*
|
|
* The element m_yx is the value on the row y and column x.
|
|
* You can access m_yx using the double-bracket notation m[y][x], or using the member function At.
|
|
*
|
|
* @note The member functions in this class use the convention that transforms are applied to
|
|
* vectors in the form M * v. This means that "Matrix3x3 M, M1, M2; M = M1 * M2;" gives a transformation M
|
|
* that applies M2 first, followed by M1 second
|
|
*/
|
|
class Matrix3x3 {
|
|
public:
|
|
enum { Rows = 3 };
|
|
enum { Cols = 3 };
|
|
|
|
static const Matrix3x3 Zero;
|
|
static const Matrix3x3 Identity;
|
|
static const Matrix3x3 NaN;
|
|
|
|
Matrix3x3() {}
|
|
Matrix3x3(float val);
|
|
Matrix3x3(float m00, float m01, float m02, float m10, float m11, float m12, float m20, float m21, float m22);
|
|
Matrix3x3(const Vector3& r1, const Vector3& r2, const Vector3& r3);
|
|
explicit Matrix3x3(const Quaternion& orientation);
|
|
|
|
static Matrix3x3 RotateX(float radians);
|
|
static Matrix3x3 RotateY(float radians);
|
|
static Matrix3x3 RotateZ(float radians);
|
|
|
|
Vector3 GetRow(int index) const;
|
|
Vector3 GetColumn(int index) const;
|
|
|
|
float &At(int row, int col);
|
|
float At(int x, int y) const;
|
|
|
|
void SetRotatePart(const Vector3& a, float angle);
|
|
|
|
/// Creates a new M3x3 that rotates about the given axis by the given angle
|
|
static Matrix3x3 RotateAxisAngle(const Vector3& axis, float angleRadians);
|
|
|
|
static Matrix3x3 RotateFromTo(const Vector3& source, const Vector3& direction)
|
|
{
|
|
|
|
}
|
|
|
|
void SetRow(int i, const Vector3 &vector3);
|
|
void SetColumn(int i, const Vector3& vector);
|
|
void SetAt(int x, int y, float value);
|
|
|
|
void Orthonormalize(int c0, int c1, int c2)
|
|
{
|
|
Vector3 v0 = GetColumn(c0);
|
|
Vector3 v1 = GetColumn(c1);
|
|
Vector3 v2 = GetColumn(c2);
|
|
Vector3::Orthonormalize(v0, v1, v2);
|
|
SetColumn(c0, v0);
|
|
SetColumn(c1, v1);
|
|
SetColumn(c2, v2);
|
|
}
|
|
|
|
static Matrix3x3 LookAt(const Vector3& forward, const Vector3& target, const Vector3& localUp, const Vector3& worldUp);
|
|
|
|
static Matrix3x3 FromQuat(const Quaternion& orientation);
|
|
|
|
Quaternion ToQuat() const;
|
|
|
|
/// Creates a new Matrix3x3 as a combination of rotation and scale.
|
|
// This function creates a new matrix M in the form M = R * S
|
|
// where R is a rotation matrix and S is a scale matrix.
|
|
// Transforming a vector v using this matrix computes the vector
|
|
// v' == M * v == R*S*v == (R * (S * v)) which means the scale operation
|
|
// is applied to the vector first, followed by rotation, and finally translation
|
|
static Matrix3x3 FromRS(const Quaternion& rotate, const Vector3& scale);
|
|
static Matrix3x3 FromRS(const Matrix3x3 &rotate, const Vector3& scale);
|
|
|
|
|
|
/// Creates a new transformation matrix that scales by the given factors.
|
|
// This matrix scales with respect to origin.
|
|
static Matrix3x3 Scale(float sx, float sy, float sz);
|
|
static Matrix3x3 Scale(const Vector3& scale);
|
|
|
|
/// Returns the main diagonal.
|
|
Vector3 Diagonal() const;
|
|
/// Returns the local +X/+Y/+Z axis in world space.
|
|
/// This is the same as transforming the vector{1,0,0} by this matrix.
|
|
Vector3 WorldX() const;
|
|
/// Returns the local +Y axis in world space.
|
|
/// This is the same as transforming the vector{0,1,0} by this matrix.
|
|
Vector3 WorldY() const;
|
|
/// Returns the local +Z axis in world space.
|
|
/// This is the same as transforming the vector{0,0,1} by this matrix.
|
|
Vector3 WorldZ() const;
|
|
|
|
/// Computes the determinant of this matrix.
|
|
// If the determinant is nonzero, this matrix is invertible.
|
|
// If the determinant is negative, this matrix performs reflection about some axis.
|
|
// From http://msdn.microsoft.com/en-us/library/bb204853(VS.85).aspx :
|
|
// "If the determinant is positive, the basis is said to be "positively" oriented (or right-handed).
|
|
// If the determinant is negative, the basis is said to be "negatively" oriented (or left-handed)."
|
|
// @note This function computes 9 LOADs, 9 MULs and 5 ADDs. */
|
|
float Determinant() const;
|
|
|
|
// Returns an inverted copy of this matrix. This
|
|
Matrix3x3 Inverse() const;
|
|
|
|
// Returns a transposed copy of this matrix.
|
|
Matrix3x3 Transpose() const;
|
|
|
|
// Transforms the given vectors by this matrix M, i.e. returns M * (x,y,z)
|
|
Vector2 Transform(const Vector2& rhs) const;
|
|
Vector3 Transform(const Vector3& rhs) const;
|
|
|
|
Vector3 operator[](int row) const
|
|
{
|
|
return Vector3{elems[row][0], elems[row][1], elems[row][2]};
|
|
}
|
|
|
|
Vector3 operator * (const Vector3& rhs) const;
|
|
Matrix3x3 operator * (const Matrix3x3& rhs) const;
|
|
|
|
protected:
|
|
float elems[3][3];
|
|
};
|
|
} |