연재 완료/프로그래밍용 수학 공부

16. 행렬(3) - 행렬 클래스 구현

라이피 (Lypi) 2018. 12. 11. 18:30
반응형

// 구현 예시임


header

 	struct float2x2
	{
		union {
			struct {
				float _11, _12;
				float _21, _22;
			};
			float m[2][2];
			float2 _1, _2;
		};

		float2x2();
		float2x2(float2 __1, float2 __2);

		//복사연산자 기본값으로 정의
		float2x2(const float2x2&) = default;
		float2x2(float2x2&&) = default;

		//대입연산자 기본값으로 정의
		float2x2& operator= (const float2x2&) = default;
		float2x2& operator= (float2x2&&) = default;
	};

	struct float3x3
	{
		union {
			struct {
				float _11, _12, _13;
				float _21, _22, _23;
				float _31, _32, _33;
			};
			float m[3][3];
			float3 _1, _2, _3;
		};

		float3x3();
		float3x3(float3 __1, float3 __2, float3 __3);

		//복사연산자 기본값으로 정의
		float3x3(const float3x3&) = default;
		float3x3(float3x3&&) = default;

		//대입연산자 기본값으로 정의
		float3x3& operator= (const float3x3&) = default;
		float3x3& operator= (float3x3&&) = default;
	};

	struct float4x4
	{
		union {
			struct {
				float _11, _12, _13, _14;
				float _21, _22, _23, _24;
				float _31, _32, _33, _34;
				float _41, _42, _43, _44;
			};
			float m[4][4];
			float4 _1, _2, _3, _4;
		};

		float4x4();
		float4x4(float4 __1, float4 __2, float4 __3, float4 __4);

		//복사연산자 기본값으로 정의
		float4x4(const float4x4&) = default;
		float4x4(float4x4&&) = default;

		//대입연산자 기본값으로 정의
		float4x4& operator= (const float4x4&) = default;
		float4x4& operator= (float4x4&&) = default;
	};

	struct stdMatrix : float4x4
	{
		static const stdMatrix Identity;
		static const stdMatrix ZeroMat;


		//생성자 
		stdMatrix() { *this = Identity; }
		stdMatrix(float4 __1, float4 __2, float4 __3, float4 __4);

		//method
		bool operator== (const stdMatrix& M) const;
		bool operator!= (const stdMatrix& M) const;

		stdMatrix operator+= (const stdMatrix& M);
		stdMatrix operator-= (const stdMatrix& M);

		stdMatrix operator+ (const stdMatrix& M);
		stdMatrix operator- (const stdMatrix& M);
		stdMatrix operator* (const stdMatrix& M);
		stdMatrix operator* (const float S);

		//static
		//static stdMatrix operator* (const float S, stdMatrix M);

		stdMatrix Transpose();
		void Transpose(stdMatrix& result);

		float deteminant();
		stdMatrix Inverse();
		void Inverse(stdMatrix& result);

		stdMatrix InverseG();
		void InverseG(stdMatrix& result);

		stdMatrix Translation(const Vector3& V);
		void Translation(const Vector3& V, stdMatrix& result);

		stdMatrix Scale(const Vector3& V);
		void Scale(const Vector3& V, stdMatrix& result);

		stdMatrix XRotate(const float& Radian);
		void XRotate(const float& Radian, stdMatrix& result);

		stdMatrix YRotate(const float& Radian);
		void YRotate(const float& Radian, stdMatrix& result);

		stdMatrix ZRotate(const float& Radian);
		void ZRotate(const float& Radian, stdMatrix& result);

		stdMatrix ObjectLookAt(Vector3& Pos, Vector3& Target, Vector3& Up);
		void ObjectLookAt(Vector3& Pos, Vector3& Target, Vector3& Up, stdMatrix& result);

		stdMatrix ViewLookAt(Vector3& Pos, Vector3& Target, Vector3& Up);
		void ViewLookAt(Vector3& Pos, Vector3& Target, Vector3& Up, stdMatrix& result);

		stdMatrix CompViewMat(Vector3& Pos, Vector3& Target, Vector3& Up);
		void CompViewMat(Vector3& Pos, Vector3& Target, Vector3& Up, stdMatrix& result);

		stdMatrix PerspectiveLH(const float& NearPlane, const float& FarPlane, const float& Width, const float& Height);
		void PerspectiveLH(const float& NearPlane, const float& FarPlane, const float& Width, const float& Height, stdMatrix& result);

		stdMatrix PerspectiveFovLH(const float& NearPlane, const float& FarPlane, const float& fovy, const float& Aspect);
		void PerspectiveFovLH(const float& NearPlane, const float& FarPlane, const float& fovy, const float& Aspect, stdMatrix& result);

		stdMatrix AxisAngle(const Vector3& vAxis, const float& Radian);
		void AxisAngle(const Vector3& vAxis, const float& Radian, stdMatrix& result);
	};


cpp

 #pragma region matrix

	float2x2::float2x2()
	{
		for (int i = 0; i < 2; i++) {
			for (int k = 0; k < 2; k++) {
				m[i][k] = 0;
			}
		}
	}

	float2x2::float2x2(float2 __0, float2 __1)
	{
		for (int i = 0; i < 2; i++) {
			m[0][i] = __0.f[i];
			m[1][i] = __1.f[i];
		}
	}


	float3x3::float3x3()
	{
		for (int i = 0; i < 3; i++) {
			for (int k = 0; k < 3; k++) {
				m[i][k] = 0;
			}
		}
	}

	float3x3::float3x3(float3 __0, float3 __1, float3 __2)
	{
		for (int i = 0; i < 3; i++) {
			m[0][i] = __0.f[i];
			m[1][i] = __1.f[i];
			m[2][i] = __2.f[i];
		}
	}

	float4x4::float4x4()
	{
		for (int i = 0; i < 4; i++) {
			for (int k = 0; k < 4; k++) {
				m[i][k] = 0;
			}
		}
	}

	float4x4::float4x4(float4 __0, float4 __1, float4 __2, float4 __3)
	{
		for (int i = 0; i < 4; i++) {
			m[0][i] = __0.f[i];
			m[1][i] = __1.f[i];
			m[2][i] = __2.f[i];
			m[3][i] = __3.f[i];
		}
	}

#pragma endregion

#pragma region stdMatrix

	stdMatrix::stdMatrix(float4 __1, float4 __2, float4 __3, float4 __4)
		: float4x4(__1, __2, __3, __4)	{ }

	bool stdMatrix::operator== (const stdMatrix& M) const
	{
		for (int i = 0; i < 4; i++) {
			for (int k = 0; k < 4; k++) {
				if (abs(m[i][k] - M.m[i][k]) > L_Epsilon) {
					return false;
				}
			}
		}

		return true;
	}

	bool stdMatrix::operator!= (const stdMatrix& M) const
	{
		for (int i = 0; i < 4; i++) {
			for (int k = 0; k < 4; k++) {
				if (abs(m[i][k] - M.m[i][k]) > L_Epsilon) {
					return true;
				}
			}
		}

		return false;
	}

	stdMatrix stdMatrix::operator+ (const stdMatrix& M)
	{
		stdMatrix ret;

		for (int i = 0; i < 4; i++) {
			for (int k = 0; k < 4; k++) {
				ret.m[i][k] = m[i][k] + M.m[i][k];
			}
		}

		return ret;
	}

	stdMatrix stdMatrix::operator- (const stdMatrix& M)
	{
		stdMatrix ret;

		for (int i = 0; i < 4; i++) {
			for (int k = 0; k < 4; k++) {
				ret.m[i][k] = m[i][k] - M.m[i][k];
			}
		}

		return ret;
	}

	stdMatrix stdMatrix::operator* (const stdMatrix& M)
	{
		stdMatrix ret;

		for (int i = 0; i < 4; i++) {
			for (int k = 0; k < 4; k++) {
				ret.m[i][k] =
					m[i][0] * M.m[0][k] +
					m[i][1] * M.m[1][k] +
					m[i][2] * M.m[2][k] +
					m[i][3] * M.m[3][k];
			}
		}

		return ret;
	}

	stdMatrix stdMatrix::operator* (const float S)
	{
		stdMatrix ret;

		for (int i = 0; i < 4; i++) {
			for (int k = 0; k < 4; k++) {
				ret.m[i][k] = S * m[i][k];
			}
		}

		return ret;
	}

	stdMatrix stdMatrix::operator+= (const stdMatrix& M)
	{
		for (int i = 0; i < 4; i++) {
			for (int k = 0; k < 4; k++) {
				m[i][k] += M.m[i][k];
			}
		}
		stdMatrix rm(*this);
		return rm;
	}

	stdMatrix stdMatrix::operator-= (const stdMatrix& M)
	{
		for (int i = 0; i < 4; i++) {
			for (int k = 0; k < 4; k++) {
				m[i][k] -= M.m[i][k];
			}
		}
		stdMatrix rm(*this);
		return rm;
	}

	stdMatrix operator* (const float S, stdMatrix M)
	{
		stdMatrix ret;

		for (int i = 0; i < 4; i++) {
			for (int k = 0; k < 4; k++) {
				ret.m[i][k] = S * M.m[i][k];
			}
		}

		return ret;
	}

	stdMatrix stdMatrix::Transpose()
	{
		stdMatrix ret = *this;

		for (int i = 0; i < 4; i++) {
			for (int k = 0; k < 4; k++) {
				m[i][k] = m[k][i];
			}
		}

		return ret;
	}

	void stdMatrix::Transpose(stdMatrix& result)
	{
		for (int i = 0; i < 4; i++) {
			for (int k = 0; k < 4; k++) {
				result.m[i][k] = m[k][i];
			}
		}
	}

	//알고리즘을 쓰지 않고 그냥 생 노가다 식을 때려넣음(..)
	float stdMatrix::deteminant()
	{
		return
			m[0][0] * m[1][1] * m[2][2] * m[3][3] +
			m[0][0] * m[1][2] * m[2][3] * m[3][1] +
			m[0][0] * m[1][3] * m[2][1] * m[3][2] +

			m[0][1] * m[1][0] * m[2][3] * m[3][2] +
			m[0][1] * m[1][2] * m[2][0] * m[3][3] +
			m[0][1] * m[1][3] * m[2][2] * m[3][0] +

			m[0][2] * m[1][0] * m[2][1] * m[3][3] +
			m[0][2] * m[1][1] * m[2][3] * m[3][0] +
			m[0][2] * m[1][3] * m[2][0] * m[3][1] +

			m[0][3] * m[1][0] * m[2][2] * m[3][1] +
			m[0][3] * m[1][1] * m[2][0] * m[3][2] +
			m[0][3] * m[1][2] * m[2][1] * m[3][0] -

			m[0][0] * m[1][1] * m[2][3] * m[3][2] -
			m[0][0] * m[1][2] * m[2][1] * m[3][3] -
			m[0][0] * m[1][3] * m[2][2] * m[3][1] -
											
			m[0][1] * m[1][0] * m[2][2] * m[3][3] -
			m[0][1] * m[1][2] * m[2][3] * m[3][0] -
			m[0][1] * m[1][3] * m[2][0] * m[3][2] -
											
			m[0][2] * m[1][0] * m[2][3] * m[3][1] -
			m[0][2] * m[1][1] * m[2][0] * m[3][3] -
			m[0][2] * m[1][3] * m[2][1] * m[3][0] -
											
			m[0][3] * m[1][0] * m[2][1] * m[3][2] -
			m[0][3] * m[1][1] * m[2][2] * m[3][0] -
			m[0][3] * m[1][2] * m[2][0] * m[3][1];
	}

	stdMatrix stdMatrix::Inverse()
	{
		stdMatrix ret = *this;

		float det = this->deteminant();

		assert(det != 0);

		float b11 = m[1][1] * m[2][2] * m[3][3] + m[1][2] * m[2][3] * m[3][1] + m[1][3] * m[2][1] * m[3][2] - m[1][1] * m[2][3] * m[3][2] - m[1][2] * m[2][1] * m[3][3] - m[1][3] * m[2][2] * m[3][1];
		float b12 = m[0][1] * m[2][3] * m[3][2] + m[0][2] * m[2][1] * m[3][3] + m[0][3] * m[2][2] * m[3][1] - m[0][1] * m[2][2] * m[3][3] -	m[0][2] * m[2][3] * m[3][1] - m[0][3] * m[2][1] * m[3][2];
		float b13 =	m[0][1] * m[2][2] * m[3][3] + m[0][2] * m[2][3] * m[3][1] + m[0][3] * m[2][1] * m[3][2] - m[0][1] * m[2][3] * m[3][2] - m[0][2] * m[2][1] * m[3][3] - m[0][3] * m[2][2] * m[3][1];
		float b14 =	m[0][1] * m[1][3] * m[2][2] + m[0][2] * m[1][1] * m[2][3] + m[0][3] * m[1][2] * m[2][1] - m[0][1] * m[1][2] * m[2][3] -	m[0][2] * m[1][3] * m[2][1] - m[0][3] * m[1][1] * m[2][2];

		float b21 =	m[1][0] * m[2][3] * m[3][2] + m[1][2] * m[2][0] * m[3][3] +	m[1][3] * m[2][2] * m[3][0] - m[1][0] * m[2][2] * m[3][3] -	m[1][2] * m[2][3] * m[3][0] - m[1][3] * m[2][0] * m[3][2];
		float b22 =	m[0][0] * m[2][2] * m[3][3] + m[0][2] * m[2][3] * m[3][0] + m[0][3] * m[2][0] * m[3][2] - m[0][0] * m[2][3] * m[3][2] -	m[0][2] * m[2][0] * m[3][3] - m[0][3] * m[2][2] * m[3][0];
		float b23 = m[0][0] * m[1][3] * m[3][2] + m[0][2] * m[1][0] * m[3][3] +	m[0][3] * m[1][2] * m[3][0] - m[0][0] * m[1][2] * m[3][3] -	m[0][2] * m[1][3] * m[3][0] - m[0][3] * m[1][0] * m[3][2];
		float b24 =	m[0][0] * m[1][2] * m[2][3] + m[0][2] * m[1][3] * m[2][0] +	m[0][3] * m[1][0] * m[2][2] - m[0][0] * m[1][3] * m[2][2] -	m[0][2] * m[1][0] * m[2][3] - m[0][3] * m[1][2] * m[2][0];

		float b31 =	m[1][0] * m[2][1] * m[3][3] + m[1][1] * m[2][3] * m[3][0] +	m[1][3] * m[2][0] * m[3][1] - m[1][0] * m[2][3] * m[3][1] -	m[1][1] * m[2][0] * m[3][3] - m[1][3] * m[2][1] * m[3][0];
		float b32 = m[1][0] * m[2][3] * m[3][1] + m[1][1] * m[2][0] * m[3][3] +	m[1][3] * m[2][1] * m[3][0] - m[1][0] * m[2][1] * m[3][3] -	m[1][1] * m[2][3] * m[3][0] - m[1][3] * m[2][0] * m[3][1];
		float b33 = m[0][0] * m[1][1] * m[3][3] + m[0][1] * m[1][3] * m[3][0] +	m[0][3] * m[1][0] * m[3][1] - m[0][0] * m[1][3] * m[3][1] -	m[0][1] * m[1][0] * m[3][3] - m[0][3] * m[1][1] * m[3][0];
		float b34 =	m[0][0] * m[1][3] * m[2][1] + m[0][1] * m[1][0] * m[2][3] +	m[0][3] * m[1][1] * m[2][0] - m[0][0] * m[1][1] * m[2][3] -	m[0][1] * m[1][3] * m[2][0] - m[0][3] * m[1][0] * m[2][1];

		float b41 = m[1][0] * m[2][2] * m[3][1] + m[1][1] * m[2][0] * m[3][2] + m[1][2] * m[2][1] * m[3][0] - m[1][0] * m[2][1] * m[3][2] - m[1][1] * m[2][2] * m[3][0] - m[1][2] * m[2][0] * m[3][1];
		float b42 =	m[0][0] * m[2][1] * m[3][2] + m[0][1] * m[2][2] * m[3][0] +	m[0][2] * m[2][0] * m[3][1] - m[0][0] * m[2][2] * m[3][1] -	m[0][1] * m[2][0] * m[3][2] - m[0][2] * m[2][1] * m[3][0];
		float b43 =	m[0][0] * m[1][2] * m[3][1] + m[0][1] * m[1][0] * m[3][2] + m[0][2] * m[1][1] * m[3][0] - m[0][0] * m[1][1] * m[3][2] - m[0][1] * m[1][2] * m[3][0] - m[0][2] * m[1][0] * m[3][1];
		float b44 = m[0][0] * m[1][1] * m[2][2] + m[0][1] * m[1][2] * m[2][0] +	m[0][2] * m[1][0] * m[2][1] - m[0][0] * m[1][2] * m[2][1] -	m[0][1] * m[1][0] * m[2][2] - m[0][2] * m[1][1] * m[2][0];

		stdMatrix subMat = {
			{ b11, b12, b13, b14 },
			{ b21, b22, b23, b24 },
			{ b31, b32, b33, b34 },
			{ b41, b42, b43, b44 }
		};

		*this = 1/det * subMat;

		return ret;
	}

	//이런 방법도 있다고 한다(..)
	stdMatrix stdMatrix::InverseG()
	{
		stdMatrix ret = *this;

		float d12 = (_31*_42 - _41 * _32);
		float d13 = (_31*_43 - _41 * _33);
		float d23 = (_32*_43 - _42 * _33);
		float d24 = (_32*_44 - _42 * _34);
		float d34 = (_33*_44 - _43 * _34);
		float d41 = (_34*_41 - _44 * _31);

		float tmp[16];
		tmp[0] = (_22 * d34 - _23 * d24 + _24 * d23);
		tmp[1] = -(_21 * d34 + _23 * d41 + _24 * d13);
		tmp[2] = (_21 * d24 + _22 * d41 + _24 * d12);
		tmp[3] = -(_21 * d23 - _22 * d13 + _23 * d12);

		float det = _11 * tmp[0] + _12 * tmp[1] + _13 * tmp[2] + _14 * tmp[3];

		assert(det != 0);
	
		float invDet = 1.0f / det;
		tmp[0] *= invDet;
		tmp[1] *= invDet;
		tmp[2] *= invDet;
		tmp[3] *= invDet;

		tmp[4] = -(_12 * d34 - _13 * d24 + _14 * d23) * invDet;
		tmp[5] = (_11 * d34 + _13 * d41 + _14 * d13) * invDet;
		tmp[6] = -(_11 * d24 + _12 * d41 + _14 * d12) * invDet;
		tmp[7] = (_11 * d23 - _12 * d13 + _13 * d12) * invDet;

		d12 = _11 * _22 - _21 * _12;
		d13 = _11 * _23 - _21 * _13;
		d23 = _12 * _23 - _22 * _13;
		d24 = _12 * _24 - _22 * _14;
		d34 = _13 * _24 - _23 * _14;
		d41 = _14 * _21 - _24 * _11;

		tmp[8] = (_42 * d34 - _43 * d24 + _44 * d23) * invDet;
		tmp[9] = -(_41 * d34 + _43 * d41 + _44 * d13) * invDet;
		tmp[10] = (_41 * d24 + _42 * d41 + _44 * d12) * invDet;
		tmp[11] = -(_41 * d23 - _42 * d13 + _43 * d12) * invDet;
		tmp[12] = -(_32 * d34 - _33 * d24 + _34 * d23) * invDet;
		tmp[13] = (_31 * d34 + _33 * d41 + _34 * d13) * invDet;
		tmp[14] = -(_31 * d24 + _32 * d41 + _34 * d12) * invDet;
		tmp[15] = (_31 * d23 - _32 * d13 + _33 * d12) * invDet;

		stdMatrix matInverse = {
			{ tmp[ 0], tmp[ 1], tmp[ 2], tmp[ 3] },
			{ tmp[ 4], tmp[ 5], tmp[ 6], tmp[ 7] },
			{ tmp[ 8], tmp[ 9], tmp[10], tmp[11] },
			{ tmp[12], tmp[13], tmp[14], tmp[15] },
		};

		*this = matInverse.Transpose();
				
		return ret;
	}

	void stdMatrix::Inverse(stdMatrix& result)
	{
		float det = this->deteminant();

		assert(det != 0);

		float b11 = m[1][1] * m[2][2] * m[3][3] + m[1][2] * m[2][3] * m[3][1] + m[1][3] * m[2][1] * m[3][2] - m[1][1] * m[2][3] * m[3][2] - m[1][2] * m[2][1] * m[3][3] - m[1][3] * m[2][2] * m[3][1];
		float b12 = m[0][1] * m[2][3] * m[3][2] + m[0][2] * m[2][1] * m[3][3] + m[0][3] * m[2][2] * m[3][1] - m[0][1] * m[2][2] * m[3][3] - m[0][2] * m[2][3] * m[3][1] - m[0][3] * m[2][1] * m[3][2];
		float b13 = m[0][1] * m[2][2] * m[3][3] + m[0][2] * m[2][3] * m[3][1] + m[0][3] * m[2][1] * m[3][2] - m[0][1] * m[2][3] * m[3][2] - m[0][2] * m[2][1] * m[3][3] - m[0][3] * m[2][2] * m[3][1];
		float b14 = m[0][1] * m[1][3] * m[2][2] + m[0][2] * m[1][1] * m[2][3] + m[0][3] * m[1][2] * m[2][1] - m[0][1] * m[1][2] * m[2][3] - m[0][2] * m[1][3] * m[2][1] - m[0][3] * m[1][1] * m[2][2];

		float b21 = m[1][0] * m[2][3] * m[3][2] + m[1][2] * m[2][0] * m[3][3] + m[1][3] * m[2][2] * m[3][0] - m[1][0] * m[2][2] * m[3][3] - m[1][2] * m[2][3] * m[3][0] - m[1][3] * m[2][0] * m[3][2];
		float b22 = m[0][0] * m[2][2] * m[3][3] + m[0][2] * m[2][3] * m[3][0] + m[0][3] * m[2][0] * m[3][2] - m[0][0] * m[2][3] * m[3][2] - m[0][2] * m[2][0] * m[3][3] - m[0][3] * m[2][2] * m[3][0];
		float b23 = m[0][0] * m[1][3] * m[3][2] + m[0][2] * m[1][0] * m[3][3] + m[0][3] * m[1][2] * m[3][0] - m[0][0] * m[1][2] * m[3][3] - m[0][2] * m[1][3] * m[3][0] - m[0][3] * m[1][0] * m[3][2];
		float b24 = m[0][0] * m[1][2] * m[2][3] + m[0][2] * m[1][3] * m[2][0] + m[0][3] * m[1][0] * m[2][2] - m[0][0] * m[1][3] * m[2][2] - m[0][2] * m[1][0] * m[2][3] - m[0][3] * m[1][2] * m[2][0];

		float b31 = m[1][0] * m[2][1] * m[3][3] + m[1][1] * m[2][3] * m[3][0] + m[1][3] * m[2][0] * m[3][1] - m[1][0] * m[2][3] * m[3][1] - m[1][1] * m[2][0] * m[3][3] - m[1][3] * m[2][1] * m[3][0];
		float b32 = m[1][0] * m[2][3] * m[3][1] + m[1][1] * m[2][0] * m[3][3] + m[1][3] * m[2][1] * m[3][0] - m[1][0] * m[2][1] * m[3][3] - m[1][1] * m[2][3] * m[3][0] - m[1][3] * m[2][0] * m[3][1];
		float b33 = m[0][0] * m[1][1] * m[3][3] + m[0][1] * m[1][3] * m[3][0] + m[0][3] * m[1][0] * m[3][1] - m[0][0] * m[1][3] * m[3][1] - m[0][1] * m[1][0] * m[3][3] - m[0][3] * m[1][1] * m[3][0];
		float b34 = m[0][0] * m[1][3] * m[2][1] + m[0][1] * m[1][0] * m[2][3] + m[0][3] * m[1][1] * m[2][0] - m[0][0] * m[1][1] * m[2][3] - m[0][1] * m[1][3] * m[2][0] - m[0][3] * m[1][0] * m[2][1];

		float b41 = m[1][0] * m[2][2] * m[3][1] + m[1][1] * m[2][0] * m[3][2] + m[1][2] * m[2][1] * m[3][0] - m[1][0] * m[2][1] * m[3][2] - m[1][1] * m[2][2] * m[3][0] - m[1][2] * m[2][0] * m[3][1];
		float b42 = m[0][0] * m[2][1] * m[3][2] + m[0][1] * m[2][2] * m[3][0] + m[0][2] * m[2][0] * m[3][1] - m[0][0] * m[2][2] * m[3][1] - m[0][1] * m[2][0] * m[3][2] - m[0][2] * m[2][1] * m[3][0];
		float b43 = m[0][0] * m[1][2] * m[3][1] + m[0][1] * m[1][0] * m[3][2] + m[0][2] * m[1][1] * m[3][0] - m[0][0] * m[1][1] * m[3][2] - m[0][1] * m[1][2] * m[3][0] - m[0][2] * m[1][0] * m[3][1];
		float b44 = m[0][0] * m[1][1] * m[2][2] + m[0][1] * m[1][2] * m[2][0] + m[0][2] * m[1][0] * m[2][1] - m[0][0] * m[1][2] * m[2][1] - m[0][1] * m[1][0] * m[2][2] - m[0][2] * m[1][1] * m[2][0];

		stdMatrix subMat = { 
			{ b11, b12, b13, b14 },
			{ b21, b22, b23, b24 },
			{ b31, b32, b33, b34 },
			{ b41, b42, b43, b44 } 
		};

		result = 1 / det * subMat;
	}

	void stdMatrix::InverseG(stdMatrix& result)
	{
		float d12 = (_31*_42 - _41 * _32);
		float d13 = (_31*_43 - _41 * _33);
		float d23 = (_32*_43 - _42 * _33);
		float d24 = (_32*_44 - _42 * _34);
		float d34 = (_33*_44 - _43 * _34);
		float d41 = (_34*_41 - _44 * _31);

		float tmp[16];
		tmp[0] = (_22 * d34 - _23 * d24 + _24 * d23);
		tmp[1] = -(_21 * d34 + _23 * d41 + _24 * d13);
		tmp[2] = (_21 * d24 + _22 * d41 + _24 * d12);
		tmp[3] = -(_21 * d23 - _22 * d13 + _23 * d12);

		float det = _11 * tmp[0] + _12 * tmp[1] + _13 * tmp[2] + _14 * tmp[3];

		assert(det != 0);

		float invDet = 1.0f / det;
		tmp[0] *= invDet;
		tmp[1] *= invDet;
		tmp[2] *= invDet;
		tmp[3] *= invDet;

		tmp[4] = -(_12 * d34 - _13 * d24 + _14 * d23) * invDet;
		tmp[5] = (_11 * d34 + _13 * d41 + _14 * d13) * invDet;
		tmp[6] = -(_11 * d24 + _12 * d41 + _14 * d12) * invDet;
		tmp[7] = (_11 * d23 - _12 * d13 + _13 * d12) * invDet;

		d12 = _11 * _22 - _21 * _12;
		d13 = _11 * _23 - _21 * _13;
		d23 = _12 * _23 - _22 * _13;
		d24 = _12 * _24 - _22 * _14;
		d34 = _13 * _24 - _23 * _14;
		d41 = _14 * _21 - _24 * _11;

		tmp[8] = (_42 * d34 - _43 * d24 + _44 * d23) * invDet;
		tmp[9] = -(_41 * d34 + _43 * d41 + _44 * d13) * invDet;
		tmp[10] = (_41 * d24 + _42 * d41 + _44 * d12) * invDet;
		tmp[11] = -(_41 * d23 - _42 * d13 + _43 * d12) * invDet;
		tmp[12] = -(_32 * d34 - _33 * d24 + _34 * d23) * invDet;
		tmp[13] = (_31 * d34 + _33 * d41 + _34 * d13) * invDet;
		tmp[14] = -(_31 * d24 + _32 * d41 + _34 * d12) * invDet;
		tmp[15] = (_31 * d23 - _32 * d13 + _33 * d12) * invDet;

		stdMatrix matInverse = {
			{ tmp[0], tmp[1], tmp[2], tmp[3] },
		{ tmp[4], tmp[5], tmp[6], tmp[7] },
		{ tmp[8], tmp[9], tmp[10], tmp[11] },
		{ tmp[12], tmp[13], tmp[14], tmp[15] },
		};

		result = matInverse.Transpose();
	}

	stdMatrix stdMatrix::Translation(const Vector3& V)
	{
		stdMatrix bf = *this;




		_41 = V.x; _42 = V.y; _43 = V.z;
		
		return bf;
	}

	void stdMatrix::Translation(const Vector3& V, stdMatrix& result)
	{



		result._41 = V.x; result._42 = V.y; result._43 = V.z;
	}

	stdMatrix stdMatrix::Scale(const Vector3& V)
	{
		stdMatrix bf = *this;

		_11 = V.x;
					_22 = V.y;
								_33 = V.z;

		return bf;
	}

	void stdMatrix::Scale(const Vector3& V, stdMatrix& result)
	{
		result._11 = V.x;
							result._22 = V.y;
												result._33 = V.z;
	}

	stdMatrix stdMatrix::XRotate(const float& Radian)
	{
		stdMatrix bf = *this;

		float Sin = (float)sin(Radian);	float Cos = (float)cos(Radian);


				_22 =  Cos; _23 = Sin;
				_32 = -Sin; _33 = Cos;


		return bf;
	}

	void stdMatrix::XRotate(const float& Radian, stdMatrix& result)
	{
		float Sin = (float)sin(Radian);	float Cos = (float)cos(Radian);

				result._22 =  Cos; result._23 = Sin;
				result._32 = -Sin; result._33 = Cos;
	}

	stdMatrix stdMatrix::YRotate(const float& Radian)
	{
		stdMatrix bf = *this;

		float Sin = (float)sin(Radian); float Cos = (float)cos(Radian);

		_11 =  Cos;		 _13 = Sin;

		_31 = -Sin;		 _33 = Cos;

		return bf;
	}

	void stdMatrix::YRotate(const float& Radian, stdMatrix& result)
	{
		float Sin = (float)sin(Radian);	float Cos = (float)cos(Radian);

		result._11 =  Cos;		 result._13 = Sin;

		result._31 = -Sin;		 result._33 = Cos;
	}

	stdMatrix stdMatrix::ZRotate(const float& Radian)
	{
		stdMatrix bf = *this;

		float Sin = (float)sin(Radian); float Cos = (float)cos(Radian);

		_11 =  Cos; _12 = Sin;
		_21 = -Sin; _22 = Cos;

		return bf;
	}

	void stdMatrix::ZRotate(const float& Radian, stdMatrix& result)
	{
		float Sin = (float)sin(Radian);	float Cos = (float)cos(Radian);

		result._11 =  Cos; result._12 = Sin;
		result._21 = -Sin; result._22 = Cos;
	}

	stdMatrix stdMatrix::ObjectLookAt(Vector3& Pos, Vector3& Target, Vector3& Up)
	{
		stdMatrix bf = *this;

		Vector3 vDir = Target - Pos; vDir.Normalize();
		float fDot = Vector3::Dot(Up, vDir);
		Vector3 vC = vDir * fDot;
		Vector3 vUV = Up - (vDir * fDot); vUV.Normalize();
		Vector3 vRV = Vector3::Cross(vUV, vDir);

		_11 =  vRV.x; _12 =  vRV.y; _13 =  vRV.z;
		_21 =  vUV.x; _22 =  vUV.y; _23 =  vUV.z;
		_31 = vDir.x; _32 = vDir.y; _33 = vDir.z;
		_41 =  Pos.x; _42 =  Pos.y; _43 =  Pos.z;

		return bf;
	}

	void stdMatrix::ObjectLookAt(Vector3& Pos, Vector3& Target, Vector3& Up, stdMatrix& result)
	{
		Vector3 vDir = Target - Pos; vDir.Normalize();
		float fDot = Vector3::Dot(Up, vDir);
		Vector3 vC = vDir * fDot;
		Vector3 vUV = Up - (vDir * fDot); vUV.Normalize();
		Vector3 vRV = Vector3::Cross(vUV, vDir);

		result._11 =  vRV.x;  result._12 =  vRV.y; result._13 =  vRV.z;
		result._21 =  vUV.x;  result._22 =  vUV.y; result._23 =  vUV.z;
		result._31 = vDir.x;  result._32 = vDir.y; result._33 = vDir.z;
		result._41 =  Pos.x;  result._42 =  Pos.y; result._43 =  Pos.z;
	}

	stdMatrix stdMatrix::ViewLookAt(Vector3& Pos, Vector3& Target, Vector3& Up)
	{
		stdMatrix bf = *this;

		Vector3 vDir = Target - Pos; vDir.Normalize();
		float fDot = Vector3::Dot(Up, vDir);
		Vector3 vC = vDir * fDot;
		Vector3 vUV = Up - (vDir * fDot); vUV.Normalize();
		Vector3 vRV = Vector3::Cross(vUV, vDir);

		_11 = vRV.x; _12 = vUV.x; _13 = vDir.x;
		_21 = vRV.y; _22 = vUV.y; _23 = vDir.y;
		_31 = vRV.z; _32 = vUV.z; _33 = vDir.z;

		_41 = -(Pos.x* vRV.x + Pos.y* vRV.y + Pos.x* vRV.y);
		_42 = -(Pos.x* vUV.x + Pos.y* vUV.y + Pos.x* vUV.y);
		_43 = -(Pos.x*vDir.x + Pos.y*vDir.y + Pos.x*vDir.y);

		return bf;
	}

	void stdMatrix::ViewLookAt(Vector3& Pos, Vector3& Target, Vector3& Up, stdMatrix& result)
	{
		Vector3 vDir = Target - Pos; vDir.Normalize();
		float fDot = Vector3::Dot(Up, vDir);
		Vector3 vC = vDir * fDot;
		Vector3 vUV = Up - (vDir * fDot); vUV.Normalize();
		Vector3 vRV = Vector3::Cross(vUV, vDir);

		result._11 = vRV.x; result._12 = vUV.x; result._13 = vDir.x;
		result._21 = vRV.y; result._22 = vUV.y; result._23 = vDir.y;
		result._31 = vRV.z; result._32 = vUV.z; result._33 = vDir.z;

		result._41 = -(Pos.x* vRV.x + Pos.y* vRV.y + Pos.x* vRV.y);
		result._42 = -(Pos.x* vUV.x + Pos.y* vUV.y + Pos.x* vUV.y);
		result._43 = -(Pos.x*vDir.x + Pos.y*vDir.y + Pos.x*vDir.y);
	}

	stdMatrix stdMatrix::CompViewMat(Vector3& Pos, Vector3& Target, Vector3& Up)
	{
		stdMatrix bf = *this;

		ObjectLookAt(Pos, Target, Up);
		Inverse();

		return bf;
	}

	void stdMatrix::CompViewMat(Vector3& Pos, Vector3& Target, Vector3& Up, stdMatrix& result)
	{
		ObjectLookAt(Pos, Target, Up, result);
		Inverse(result);
	}

	stdMatrix stdMatrix::PerspectiveLH(const float& NearPlane, const float& FarPlane, const float& Width, const float& Height)
	{
		stdMatrix bf = *this;

		*this = ZeroMat;

		_11 = (2.f * NearPlane) / (Width);
		_22 = (2.f * NearPlane) / (Height);
		_33 = FarPlane / (FarPlane - NearPlane);
		_34 = 1.f;
		_43 = NearPlane * FarPlane / (NearPlane - FarPlane);
		
		return bf;
	}

	void stdMatrix::PerspectiveLH(const float& NearPlane, const float& FarPlane, const float& Width, const float& Height, stdMatrix& result)
	{
		result = ZeroMat;

		result._11 = (2.f * NearPlane) / (Width);
		result._22 = (2.f * NearPlane) / (Height);
		result._33 = FarPlane / (FarPlane - NearPlane);
		result._34 = 1.f;
		result._43 = NearPlane * FarPlane / (NearPlane - FarPlane);
	}

	stdMatrix stdMatrix::PerspectiveFovLH(const float& NearPlane, const float& FarPlane, const float& fovy, const float& Aspect)
	{
		stdMatrix bf = *this;

		*this = ZeroMat;

		_11 = 1 / tan(fovy*0.5f) / (Aspect);
		_22 = 1 / tan(fovy*0.5f);
		_33 = FarPlane / (FarPlane - NearPlane);
		_34 = 1.f;
		_43 = NearPlane * FarPlane / (NearPlane - FarPlane);

		return bf;
	}

	void stdMatrix::PerspectiveFovLH(const float& NearPlane, const float& FarPlane, const float& fovy, const float& Aspect, stdMatrix& result)
	{
		result = ZeroMat;

		result._11 = 1 / tan(fovy*0.5f) / (Aspect);
		result._22 = 1 / tan(fovy*0.5f);
		result._33 = FarPlane / (FarPlane - NearPlane);
		result._34 = 1.f;
		result._43 = NearPlane * FarPlane / (NearPlane - FarPlane);
	}

	stdMatrix stdMatrix::AxisAngle(const Vector3& vAxis, const float& Radian)
	{
		float Sin = (float)sin(Radian);	float Cos = (float)cos(Radian);

		_11 = vAxis.x * vAxis.x * (1 - Cos) + Cos;
		_12 = vAxis.y * vAxis.x * (1 - Cos) - (vAxis.z*Sin);
		_13 = vAxis.z * vAxis.x * (1 - Cos) + (vAxis.y*Sin);
		_14 = 0.f;

		_21 = vAxis.x * vAxis.y * (1 - Cos) - (vAxis.z*Sin);
		_22 = vAxis.y * vAxis.y * (1 - Cos) + Cos;
		_23 = vAxis.z * vAxis.y * (1 - Cos) + (vAxis.x*Sin);
		_24 = 0.f;

		_31 = vAxis.x * vAxis.z * (1 - Cos) + (vAxis.y*Sin);
		_32 = vAxis.y * vAxis.z * (1 - Cos) - (vAxis.x*Sin);
		_33 = vAxis.z * vAxis.z * (1 - Cos) + Cos;
		_34 = 0.f;

		_41 = _42 = _43 = 0.f; _44 = 1.f;
	}

	void stdMatrix::AxisAngle(const Vector3& vAxis, const float& Radian, stdMatrix& result)
	{
		float Sin = (float)sin(Radian);	float Cos = (float)cos(Radian);

		result._11 = vAxis.x * vAxis.x * (1 - Cos) + Cos;
		result._12 = vAxis.y * vAxis.x * (1 - Cos) - (vAxis.z*Sin);
		result._13 = vAxis.z * vAxis.x * (1 - Cos) + (vAxis.y*Sin);
		result._14 = 0.f;

		result._21 = vAxis.x * vAxis.y * (1 - Cos) - (vAxis.z*Sin);
		result._22 = vAxis.y * vAxis.y * (1 - Cos) + Cos;
		result._23 = vAxis.z * vAxis.y * (1 - Cos) + (vAxis.x*Sin);
		result._24 = 0.f;

		result._31 = vAxis.x * vAxis.z * (1 - Cos) + (vAxis.y*Sin);
		result._32 = vAxis.y * vAxis.z * (1 - Cos) - (vAxis.x*Sin);
		result._33 = vAxis.z * vAxis.z * (1 - Cos) + Cos;
		result._34 = 0.f;

		result._41 = result._42 = result._43 = 0.f; result._44 = 1.f;
	}

	const stdMatrix stdMatrix::Identity = 
	{ 
		{1.f, 0.f, 0.f, 0.f},
	    {0.f, 1.f, 0.f, 0.f},
	    {0.f, 0.f, 1.f, 0.f},
	    {0.f, 0.f, 0.f, 1.f} 
	};

	const stdMatrix stdMatrix::ZeroMat =
	{
		{ 0.f, 0.f, 0.f, 0.f },
		{ 0.f, 0.f, 0.f, 0.f },
		{ 0.f, 0.f, 0.f, 0.f },
		{ 0.f, 0.f, 0.f, 0.f }
	};
#pragma endregion


반응형