summaryrefslogtreecommitdiff
path: root/Runtime/Math/Matrix3x3.h
blob: f8843499191f48c991a1a22fb513e5b3f5536da7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
#pragma once

#include "Vector3.h"
#include "Runtime/Modules/ExportModules.h"

class EXPORT_COREMODULE Matrix3x3f
{
	public:

	float m_Data[9];
	
	///@todo: Can't be Transfer optimized because Transfer doesn't write the same as memory layout
	DECLARE_SERIALIZE_NO_PPTR (Matrix3x3f)
	
	Matrix3x3f () {}
	Matrix3x3f (float m00, float m01, float m02, float m10, float m11, float m12, float m20, float m21, float m22) { Get (0,0) = m00; Get (1,0) = m10; Get (2,0) = m20; Get (0,1) = m01; Get (1,1) =m11; Get (2,1) = m21; Get (0,2) = m02; Get (1,2) = m12; Get (2,2) = m22; }
	explicit Matrix3x3f (const class Matrix4x4f& m);
	// The Get function accesses the matrix in std math convention
 	// m0,0 m0,1 m0,2
	// m1,0 m1,1 m1,2
	// m2,0 m2,1 m2,2

	// The floats are laid out:
	// m0   m3   m6	
	// m1   m4   m7	
	// m2   m5   m8	
	
	
	float& Get (int row, int column) 				{ return m_Data[row + (column * 3)]; }
	const float& Get (int row, int column)const 	{ return m_Data[row + (column * 3)]; }
	
	float& operator [] (int row) 				{ return m_Data[row]; }
	float operator [] (int row) const 				{ return m_Data[row]; }
	
	float* GetPtr ()								{ return m_Data; }
	const float* GetPtr () const				{ return m_Data; }
	
	Vector3f GetColumn (int col) const { return Vector3f (Get (0, col), Get (1, col), Get (2, col)); }
	Matrix3x3f& operator = (const class Matrix4x4f& m);
		
	Matrix3x3f& operator *= (const Matrix3x3f& inM);
	Matrix3x3f& operator *= (const class Matrix4x4f& inM);
	friend Matrix3x3f operator * (const Matrix3x3f& lhs, const Matrix3x3f& rhs)	{ Matrix3x3f temp (lhs); temp *= rhs; return temp; }
	Vector3f MultiplyVector3 (const Vector3f& inV) const;
	void MultiplyVector3 (const Vector3f& inV, Vector3f& output) const;

	Vector3f MultiplyPoint3 (const Vector3f& inV) const					{ return MultiplyVector3 (inV); }
	Vector3f MultiplyVector3Transpose (const Vector3f& inV) const;
	Vector3f MultiplyPoint3Transpose (const Vector3f& inV) const		{ return MultiplyVector3Transpose (inV); }

	Matrix3x3f& operator *= (float f);
	Matrix3x3f& operator /= (float f) { return *this *= (1.0F / f); }
	
	float GetDeterminant () const;
	
//	Matrix3x3f& Transpose (const Matrix3x3f& inM);
	Matrix3x3f& Transpose ();
//	Matrix3x3f& Invert (const Matrix3x3f& inM)												{ return Transpose (inM); }
	bool Invert ();
	void InvertTranspose ();
	
	Matrix3x3f& SetIdentity ();
	Matrix3x3f& SetZero ();
	Matrix3x3f& SetFromToRotation (const Vector3f& from, const Vector3f& to);
	Matrix3x3f& SetAxisAngle (const Vector3f& rotationAxis, float radians);
	Matrix3x3f& SetOrthoNormalBasis (const Vector3f& inX, const Vector3f& inY, const Vector3f& inZ);
	Matrix3x3f& SetOrthoNormalBasisInverse (const Vector3f& inX, const Vector3f& inY, const Vector3f& inZ);
	Matrix3x3f& SetScale (const Vector3f& inScale);
	Matrix3x3f& Scale (const Vector3f& inScale);
	
	bool IsIdentity (float threshold = Vector3f::epsilon);
	
	static const Matrix3x3f zero;
	static const Matrix3x3f identity;
};

// Generates an orthornormal basis from a look at rotation, returns if it was successful
// (Righthanded)
bool LookRotationToMatrix (const Vector3f& viewVec, const Vector3f& upVec, Matrix3x3f* m);

bool MatrixToEuler (const Matrix3x3f& matrix, Vector3f& v);
void EulerToMatrix (const Vector3f& v, Matrix3x3f& matrix);

inline Vector3f Matrix3x3f::MultiplyVector3 (const Vector3f& v) const
{
	Vector3f res;
	res.x = m_Data[0] * v.x + m_Data[3] * v.y + m_Data[6] * v.z;
	res.y = m_Data[1] * v.x + m_Data[4] * v.y + m_Data[7] * v.z;
	res.z = m_Data[2] * v.x + m_Data[5] * v.y + m_Data[8] * v.z;
	return res;
}

inline void Matrix3x3f::MultiplyVector3 (const Vector3f& v, Vector3f& output) const
{
	output.x = m_Data[0] * v.x + m_Data[3] * v.y + m_Data[6] * v.z;
	output.y = m_Data[1] * v.x + m_Data[4] * v.y + m_Data[7] * v.z;
	output.z = m_Data[2] * v.x + m_Data[5] * v.y + m_Data[8] * v.z;
}


inline Vector3f Matrix3x3f::MultiplyVector3Transpose (const Vector3f& v) const
{
	Vector3f res;
	res.x = Get (0, 0) * v.x + Get (1, 0) * v.y + Get (2, 0) * v.z;
	res.y = Get (0, 1) * v.x + Get (1, 1) * v.y + Get (2, 1) * v.z;
	res.z = Get (0, 2) * v.x + Get (1, 2) * v.y + Get (2, 2) * v.z;
	return res;
}


template<class TransferFunction>
inline void Matrix3x3f::Transfer (TransferFunction& t)
{
	t.Transfer (Get (0, 0), "e00");	t.Transfer (Get (0, 1), "e01");	t.Transfer (Get (0, 2), "e02");
	t.Transfer (Get (1, 0), "e10");	t.Transfer (Get (1, 1), "e11");	t.Transfer (Get (1, 2), "e12");
	t.Transfer (Get (2, 0), "e20");	t.Transfer (Get (2, 1), "e21");	t.Transfer (Get (2, 2), "e22");
}

void EXPORT_COREMODULE OrthoNormalize (Matrix3x3f& matrix);