⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 vmath

📁 赫赫大名的 OGRE 游戏引擎
💻
📖 第 1 页 / 共 3 页
字号:
				// Component-wise negation

inline	const	Matrix		operator -() const
				{
					Matrix	result;
					for (unsigned int i = 0; i < N*M; i++) result._data[i] = -_data[i];
					return result;
				}

				// Component-wise subtraction with matrix

inline	const	Matrix		operator -(const Matrix & m) const
				{
					Matrix	result;
					for (unsigned int i = 0; i < N*M; i++) result._data[i] = _data[i] - m._data[i];
					return result;
				}

				// Component-wise subtraction with scalar

inline	const	Matrix		operator -(const T & value) const
				{
					Matrix	result;
					for (unsigned int i = 0; i < N*M; i++) result._data[i] = _data[i] - value;
					return result;
				}

				// Component-wise subtraction with scalar (scalar - component)

inline	const	Matrix		inverseSubtract(const T & value) const
				{
					Matrix	result;
					for (unsigned int i = 0; i < N*M; i++) result._data[i] = value - _data[i];
					return result;
				}

				// Component-wise subtraction with matrix (into self)

inline	const	Matrix		operator -=(const Matrix & m)
				{
					for (unsigned int i = 0; i < N*M; i++) _data[i] -= m._data[i];
					return *this;
				}

				// Component-wise subtraction with scalar (into self)

inline	const	Matrix		operator -=(const T & value)
				{
					for (unsigned int i = 0; i < N*M; i++) _data[i] -= value;
					return *this;
				}

				// Total all components

inline		T		total()
				{
					T	tot = static_cast<T>(0);
					for (unsigned int i = 0; i < N*M; i++) tot += _data[i];
					return tot;
				}

				// Comparison for equality

inline	const	bool		operator ==(const Matrix & m) const
				{
					for (unsigned int i = 0; i < N*M; i++) if (_data[i] != m._data[i]) return false;
					return true;
				}

				// Comparison for inequality

inline	const	bool		operator !=(const Matrix & m) const
				{
					return !(*this == m);
				}

inline	const	bool		operator <(const Matrix & m) const
				{
					for (unsigned int i = 0; i < N*M; i++) if (_data[i] >= m._data[i]) return false;
					return true;
				}

inline	const	bool		operator <=(const Matrix & m) const
				{
					for (unsigned int i = 0; i < N*M; i++) if (_data[i] > m._data[i]) return false;
					return true;
				}

inline	const	bool		operator >(const Matrix & m) const
				{
					for (unsigned int i = 0; i < N*M; i++) if (_data[i] <= m._data[i]) return false;
					return true;
				}

inline	const	bool		operator >=(const Matrix & m) const
				{
					for (unsigned int i = 0; i < N*M; i++) if (_data[i] < m._data[i]) return false;
					return true;
				}

				// Generates a converted matrix. Result is a matrix that has been converted from one type to another.
				//
				// Offers two options:
				//
				// rowColumnSwap: if true, toggle between row-major and column-major
				// leftRightSwap: if true, toggle between left-handed and right-handed coordinate systems
				//
				// Default behaviour is a row-/column-major swap, but not a left-/right-handed swap.
				
inline		Matrix		genConvertedType(const bool rowColumnSwap = true, const bool leftRightSwap = false) const
				{
					TemplateAssert(N >= 3 && M >= 3);

					Matrix	result = *this;
					if (leftRightSwap)
					{
						for (unsigned int i = 2; i < N; i++)
						{
							result(i,2) = -result(i,2);
						}
					}

					if (rowColumnSwap)
					{
						result.transpose();
					}
					return result;
				}

				// Orthogonal transpose
				//
				// Note that matrix must be square (i.e. N == M)

inline		void		transpose()
				{
					TemplateAssert(N == M);

					// Transpose the matrix

					Matrix result;
					for (unsigned int j = 0; j < M; j++)
					{
						for (unsigned int i = 0; i < N; i++)
						{
							result(j,i) = (*this)(i,j);
						}
					}
					*this = result;
				}

				// Returns determinant of the matrix (4x4 only)

inline		T		determinant()
				{
					TemplateAssert(N == 4 && M == 4);

					Matrix &	m = *this;
					return	  (m(0,0) * m(1,1) - m(1,0) * m(0,1)) * (m(2,2) * m(3,3) - m(3,2) * m(2,3))
						- (m(0,0) * m(2,1) - m(2,0) * m(0,1)) * (m(1,2) * m(3,3) - m(3,2) * m(1,3))
						+ (m(0,0) * m(3,1) - m(3,0) * m(0,1)) * (m(1,2) * m(2,3) - m(2,2) * m(1,3))
						+ (m(1,0) * m(2,1) - m(2,0) * m(1,1)) * (m(0,2) * m(3,3) - m(3,2) * m(0,3))
						- (m(1,0) * m(3,1) - m(3,0) * m(1,1)) * (m(0,2) * m(2,3) - m(2,2) * m(0,3))
						+ (m(2,0) * m(3,1) - m(3,0) * m(2,1)) * (m(0,2) * m(1,3) - m(1,2) * m(0,3));
				}

				// Inverts the matrix (4x4 only)

inline		void		invert()
				{
					TemplateAssert(N == 4 && M == 4);

					T	d = determinant();
					if (d == 0.0) return;

					d = 1.0 / d;

					Matrix &	m = *this;
					Matrix		result;
					result(0,0) = d * (m(1,1) * (m(2,2) * m(3,3) - m(3,2) * m(2,3)) + m(2,1) * (m(3,2) * m(1,3) - m(1,2) * m(3,3)) + m(3,1) * (m(1,2) * m(2,3) - m(2,2) * m(1,3)));
					result(1,0) = d * (m(1,2) * (m(2,0) * m(3,3) - m(3,0) * m(2,3)) + m(2,2) * (m(3,0) * m(1,3) - m(1,0) * m(3,3)) + m(3,2) * (m(1,0) * m(2,3) - m(2,0) * m(1,3)));
					result(2,0) = d * (m(1,3) * (m(2,0) * m(3,1) - m(3,0) * m(2,1)) + m(2,3) * (m(3,0) * m(1,1) - m(1,0) * m(3,1)) + m(3,3) * (m(1,0) * m(2,1) - m(2,0) * m(1,1)));
					result(3,0) = d * (m(1,0) * (m(3,1) * m(2,2) - m(2,1) * m(3,2)) + m(2,0) * (m(1,1) * m(3,2) - m(3,1) * m(1,2)) + m(3,0) * (m(2,1) * m(1,2) - m(1,1) * m(2,2)));
					result(0,1) = d * (m(2,1) * (m(0,2) * m(3,3) - m(3,2) * m(0,3)) + m(3,1) * (m(2,2) * m(0,3) - m(0,2) * m(2,3)) + m(0,1) * (m(3,2) * m(2,3) - m(2,2) * m(3,3)));
					result(1,1) = d * (m(2,2) * (m(0,0) * m(3,3) - m(3,0) * m(0,3)) + m(3,2) * (m(2,0) * m(0,3) - m(0,0) * m(2,3)) + m(0,2) * (m(3,0) * m(2,3) - m(2,0) * m(3,3)));
					result(2,1) = d * (m(2,3) * (m(0,0) * m(3,1) - m(3,0) * m(0,1)) + m(3,3) * (m(2,0) * m(0,1) - m(0,0) * m(2,1)) + m(0,3) * (m(3,0) * m(2,1) - m(2,0) * m(3,1)));
					result(3,1) = d * (m(2,0) * (m(3,1) * m(0,2) - m(0,1) * m(3,2)) + m(3,0) * (m(0,1) * m(2,2) - m(2,1) * m(0,2)) + m(0,0) * (m(2,1) * m(3,2) - m(3,1) * m(2,2)));
					result(0,2) = d * (m(3,1) * (m(0,2) * m(1,3) - m(1,2) * m(0,3)) + m(0,1) * (m(1,2) * m(3,3) - m(3,2) * m(1,3)) + m(1,1) * (m(3,2) * m(0,3) - m(0,2) * m(3,3)));
					result(1,2) = d * (m(3,2) * (m(0,0) * m(1,3) - m(1,0) * m(0,3)) + m(0,2) * (m(1,0) * m(3,3) - m(3,0) * m(1,3)) + m(1,2) * (m(3,0) * m(0,3) - m(0,0) * m(3,3)));
					result(2,2) = d * (m(3,3) * (m(0,0) * m(1,1) - m(1,0) * m(0,1)) + m(0,3) * (m(1,0) * m(3,1) - m(3,0) * m(1,1)) + m(1,3) * (m(3,0) * m(0,1) - m(0,0) * m(3,1)));
					result(3,2) = d * (m(3,0) * (m(1,1) * m(0,2) - m(0,1) * m(1,2)) + m(0,0) * (m(3,1) * m(1,2) - m(1,1) * m(3,2)) + m(1,0) * (m(0,1) * m(3,2) - m(3,1) * m(0,2)));
					result(0,3) = d * (m(0,1) * (m(2,2) * m(1,3) - m(1,2) * m(2,3)) + m(1,1) * (m(0,2) * m(2,3) - m(2,2) * m(0,3)) + m(2,1) * (m(1,2) * m(0,3) - m(0,2) * m(1,3)));
					result(1,3) = d * (m(0,2) * (m(2,0) * m(1,3) - m(1,0) * m(2,3)) + m(1,2) * (m(0,0) * m(2,3) - m(2,0) * m(0,3)) + m(2,2) * (m(1,0) * m(0,3) - m(0,0) * m(1,3)));
					result(2,3) = d * (m(0,3) * (m(2,0) * m(1,1) - m(1,0) * m(2,1)) + m(1,3) * (m(0,0) * m(2,1) - m(2,0) * m(0,1)) + m(2,3) * (m(1,0) * m(0,1) - m(0,0) * m(1,1)));
					result(3,3) = d * (m(0,0) * (m(1,1) * m(2,2) - m(2,1) * m(1,2)) + m(1,0) * (m(2,1) * m(0,2) - m(0,1) * m(2,2)) + m(2,0) * (m(0,1) * m(1,2) - m(1,1) * m(0,2)));
					*this = result;
				}

				// Fill the matrix with a single value

inline		void		fill(const T & value)
				{
					T	*ptr = _data;
					for (unsigned int i = 0; i < N*M; i++, ptr++) *ptr = value;
				}

				// Generate identity matrix
				//
				// Note that matrix must be square (i.e. N == M)

static	const	Matrix		genIdentity()
				{
					TemplateAssert(N == M);

					// Make it identity

					Matrix		result;
					T		*ptr = result._data;
					for (unsigned int j = 0; j < M; j++)
					{
						for (unsigned int i = 0; i < N; i++, ptr++)
						{
							if (i == j)	*ptr = static_cast<T>(1);
							else		*ptr = static_cast<T>(0);
						}
					}
					return result;
				}

				// Generate rotation matrix (3x3) for rotation about the X axis (i.e. rotation happens along the Y/Z plane)
				//
				// Rotation happens in a counter-clockwise direction around the X vector

static	const	Matrix		genXRotation(const T & theta)
				{
					TemplateAssert(N >= 3 && M >= 3);

					// Start with identity

					Matrix	result = genIdentity();

					// Fill it in

					T	ct = static_cast<T>(cos(static_cast<double>(theta)));
					T	st = static_cast<T>(sin(static_cast<double>(theta)));
					result(1,1) =  ct;
					result(2,1) = -st;
					result(1,2) =  st;
					result(2,2) =  ct;
					return result;
				}

				// Generate rotation matrix (3x3) for rotation about the Y axis (i.e. rotation happens along the X/Z plane)
				//
				// Rotation happens in a counter-clockwise direction around the Y vector
				//
				// Note that the matrix must be a minimum of 3x3

static	const	Matrix		genYRotation(const T & theta)
				{
					TemplateAssert(N >= 3 && M >= 3);

					// Start with identity

					Matrix	result = genIdentity();

					// Fill it in

					T	ct = static_cast<T>(cos(static_cast<double>(theta)));
					T	st = static_cast<T>(sin(static_cast<double>(theta)));
					result(0,0) =  ct;
					result(2,0) =  st;
					result(0,2) = -st;
					result(2,2) =  ct;
					return result;
				}

				// Generate rotation matrix (3x3) for rotation about the Z axis (i.e. rotation happens along the X/Y plane)
				//
				// Rotation happens in a counter-clockwise direction around the Z vector
				//
				// Note that this matrix is allowed to be only 2x2 as this is a 2-D rotation

static	const	Matrix		genZRotation(const T & theta)
				{
					TemplateAssert(N >= 3 && M >= 3);

					// Start with identity

					Matrix	result = genIdentity();

					// Fill it in

					T	ct = static_cast<T>(cos(static_cast<double>(theta)));
					T	st = static_cast<T>(sin(static_cast<double>(theta)));
					result(0,0) =  ct;
					result(1,0) = -st;
					result(0,1) =  st;
					result(1,1) =  ct;
					return result;
				}

				// Generate a concatenated rotation matrix (3x3) for rotation about all axes (i.e. arbitrary rotation)
				//
				// Rotation happens in a counter-clockwise direction around each vector
				//
				// Rotation happens in the following order: First Z, then Y and finally X.

static	const	Matrix		genRotation(const T & xTheta, const T & yTheta, const T & zTheta)
				{
					return genZRotation(zTheta) >> genYRotation(yTheta) >> genXRotation(xTheta);
				}

				// Generate a 'look-at' matrix. Must be a 3x3 result because this routine uses a cross product

static	const	Matrix<3, 3, T>	genLookat(const Matrix<3, 1, T> & v, const T & theta = static_cast<T>(0))
				{
					Matrix<3, 1, T>	zAxis = v;
					zAxis.normalize();

					Matrix<3, 1, T>	yAxis;
					yAxis.fill(static_cast<T>(0));

					// Handle the degenerate case... (this acts exactly like 3DS-R4)

					if (!zAxis.x() && !zAxis.z())	yAxis.z() = -zAxis.y();
					else				yAxis.y() = static_cast<T>(1);

					Matrix<3, 1, T>	xAxis = yAxis % zAxis;
					xAxis.normalize();

					yAxis = xAxis % zAxis;
					yAxis.normalize();
					yAxis = -yAxis;

					Matrix<3, 3, T>	m(xAxis, yAxis, zAxis);
					return m >> genZRotation(theta);
				}

				// Scale a matrix

inline		void		scale(const Matrix<N, 1, T> & m)
				{
					TemplateAssert(N <= M);

					for (unsigned int i = 0; i < N; i++)
					{
						(*this)(i,i) *= m(i,0);
					}
				}

				// Generate a scale matrix

static		Matrix		genScale(const Matrix<N, 1, T> & m)
				{
					TemplateAssert(N <= M);

					Matrix	result;
					result = genIdentity();
					for (unsigned int i = 0; i < N; i++)
					{
						result(i,i) *= m(i,0);
					}
					return result;
				}

				// Generate a translation matrix

static		Matrix		genTranslate(const Matrix<N, 1, T> & m)
				{
					TemplateAssert(M <= N);

					Matrix	result;
					result = genIdentity();
					for (unsigned int i = 0; i < M; i++)
					{
						result(N-1,i) += m(i,0);
					}
					return result;
				}

				// Generate a shear matrix

static		Matrix		genShear(const T x, const T y)
				{
					TemplateAssert(N > 1 && M > 1);

					Matrix	result;
					result = genIdentity();
					result(1,0) = x;
					result(0,1) = y;
					return result;
				}

				// Generate a (4x4) perspective projection matrix (as per D3D)

static	const	Matrix<4, 4, T>	genProjectPerspectiveD3D(const T & fov, const T & aspect, const T & n, const T & f)
				{
					T	w  = static_cast<T>(1.0 / tan(fov / static_cast<T>(2)));
					T	h  = static_cast<T>(1.0 / tan(fov / static_cast<T>(2)));
					if (aspect > 1.0)	w /= aspect;
					else			h *= aspect;
					T	q  = f / (f - n);

					Matrix<4, 4, T>	result;
					result.fill(static_cast<T>(0));
					result(0,0) = w;
					result(1,1) = h;
					result(2,2) = q;
					result(3,2) = -q*n;
					result(2,3) = 1;
					return result;
				}

				// Generate a (4x4) perspective projection matrix (as per Blinn)

static	const	Matrix<4, 4, T>	genProjectPerspectiveBlinn(const T & fov, const T & aspect, const T & n, const T & f)
				{
					T	w  = static_cast<T>(cos(fov / static_cast<T>(2)));
					T	h  = static_cast<T>(cos(fov / static_cast<T>(2)));
					if (aspect > 1.0)	w /= aspect;
					else			h *= aspect;
					T	s  = static_cast<T>(sin(fov / static_cast<T>(2)));
					T	d  = static_cast<T>(1) - n/f;

					Matrix<4, 4, T>	result;
					result.fill(static_cast<T>(0));
					result(0,0) = w;
					result(1,1) = h;
					result(2,2) = s / d;
					result(3,2) = -(s * n / d);
					result(2,3) = s;
					return result;
				}

				// Generate a (4x4) perspective projection matrix (as per glFrustum)

static	const	Matrix<4, 4, T>	genProjectPerspectiveGlFrustum(const T & l, const T & r, const T & b, const T & t, const T & n, const T & f)
				{
					Matrix<4, 4, T>	result;
					result.fill(static_cast<T>(0));
					result(0,0) = (2*n)/(r-l);
					result(2,0) = (r+l)/(r-l);
					result(1,1) = (2*n)/(t-b);
					result(2,1) = (t+b)/(t-b);
					result(2,2) = (-(f+n))/(f-n);
					result(3,2) = (-2*f*n)/(f-n);
					result(2,3) = -1;
					return result;
				}

				// Generate a (4x4) orthogonal projection matrix (as per glOrtho)

static	const	Matrix<4, 4, T>	genProjectGlOrtho(const T & l, const T & r, const T & b, const T & t, const T & n, const T & f)
				{
					Matrix<4, 4, T>	result;
					result.fill(static_cast<T>(0));
					result(0,0) =  2/(r-l);
					result(1,1) =  2/(t-b);
					result(2,2) = -2/(f-n);
					result(3,3) =  1;
					result(3,0) = -((r+l)/(r-l));
					result(3,1) = -((t+b)/(t-b));
					result(3,2) = -((f+n)/(f-n));

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -