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

📄 matrix.h

📁 大型多人在线游戏开发,该书光盘上附带的源码
💻 H
📖 第 1 页 / 共 3 页
字号:
	// | f11 f21 f31 f41 |   | f1[0] f1[4] f1[8]  f1[12] |   | f2[0][0] f2[1][0] f2[2][0] f2[3][0] |
	// | f12 f22 f32 f42 |   | f1[1] f1[5] f1[9]  f1[13] |   | f2[0][1] f2[1][1] f2[2][1] f2[3][1] |
	// | f13 f23 f33 f43 | = | f1[2] f1[6] f1[10] f1[14] | = | f2[0][2] f2[1][2] f2[2][2] f2[3][2] |
	// | f14 f24 f34 f44 |   | f1[3] f1[7] f1[11] f1[15] |   | f2[0][3] f2[1][3] f2[2][3] f2[3][3] |
	union
	{
		struct { float f11, f12, f13, f14, f21, f22, f23, f24, f31, f32, f33, f34, f41, f42, f43, f44; };
		float f1[16];
		float f2[4][4];
	};

	CMatrix()							{}
	CMatrix(const float f)				{ *this = f; }
	CMatrix(const float *pf)			{ *this = pf; }
	CMatrix(const CQuaternion &q)		{ *this = q; }

	// Init functions
	void ZeroMatrix()
	{
		f11 = f12 = f13 = f14 = f21 = f22 = f23 = f24 = f31 = f32 = f33 = f34 = f41 = f42 = f43 = f44 = 0;
	}
	void IdentityMatrix()
	{
		f12 = f13 = f14 = f21 = f23 = f24 = f31 = f32 = f34 = f41 = f42 = f43 = 0;
		f11 = f22 = f33 = f44 = 1;
	}

	operator float*()								{ return f1; }
	float &operator[](const int n)					{ return f1[n]; }
	float &operator()(const int i, const int j)		{ return f2[i][j]; }
	operator const float*() const					{ return f1; }
	float operator[](const int n) const				{ return f1[n]; }
	float operator()(const int i, const int j) const{ return f2[i][j]; }

	void operator=(const float f)					{ for(register int i=0; i<16; i++) f1[i] = f; }
	void operator=(const float *pf)					{ for(register int i=0; i<16; i++) f1[i] = pf[i]; }
	void operator=(const CQuaternion &q);

	CMatrix operator*(const CMatrix &m) const;
	void operator*=(const CMatrix &m)				{ *this = *this * m; }
	CVector operator*(const CVector &v) const		{ return TransformVector(v); }

	CVector TransformVector(const CVector &v) const
	{
		// 9 muls, 9 adds
		// | f11 f21 f31 f41 |   | v.x |   | f11*v.x+f21*v.y+f31*v.z+f41 |
		// | f12 f22 f32 f42 |   | v.y |   | f12*v.x+f22*v.y+f32*v.z+f42 |
		// | f13 f23 f33 f43 | * | v.z | = | f13*v.x+f23*v.y+f33*v.z+f43 |
		// | 0   0   0   1   |   | 1   |   | 1                           |
		return CVector((f11*v.x+f21*v.y+f31*v.z+f41),
					   (f12*v.x+f22*v.y+f32*v.z+f42),
					   (f13*v.x+f23*v.y+f33*v.z+f43));
	}
	CVector TransformNormal(const CVector &v) const
	{
		// 9 muls, 6 adds
		// (Transpose rotation vectors, ignore position)
		// | f11 f12 f13 0 |   | v.x |   | f11*v.x+f12*v.y+f13*v.z |
		// | f21 f22 f23 0 |   | v.y |   | f21*v.x+f22*v.y+f23*v.z |
		// | f31 f32 f33 0 | * | v.z | = | f31*v.x+f32*v.y+f33*v.z |
		// | 0   0   0   1 |   | 1   |   | 1                       |
		return CVector((f11*v.x+f12*v.y+f13*v.z),
					   (f21*v.x+f22*v.y+f23*v.z),
					   (f31*v.x+f32*v.y+f33*v.z));
	}

	// Translate functions
	void TranslateMatrix(const float x, const float y, const float z)
	{
		// | 1  0  0  x |
		// | 0  1  0  y |
		// | 0  0  1  z |
		// | 0  0  0  1 |
		f12 = f13 = f14 = f21 = f23 = f24 = f31 = f32 = f34 = 0;
		f11 = f22 = f33 = f44 = 1;
		f41 = x; f42 = y; f43 = z;
	}
	void TranslateMatrix(const float *pf)		{ TranslateMatrix(pf[0], pf[1], pf[2]); }
	void Translate(const float x, const float y, const float z)
	{
		// 9 muls, 9 adds
		// | f11 f21 f31 f41 |   | 1  0  0  x |   | f11 f21 f31 f11*x+f21*y+f31*z+f41 |
		// | f12 f22 f32 f42 |   | 0  1  0  y |   | f12 f22 f32 f12*x+f22*y+f32*z+f42 |
		// | f13 f23 f33 f43 | * | 0  0  1  z | = | f13 f23 f33 f13*x+f23*y+f33*z+f43 |
		// | 0   0   0   1   |   | 0  0  0  1 |   | 0   0   0   1                     |
		f41 = f11*x+f21*y+f31*z+f41;
		f42 = f12*x+f22*y+f32*z+f42;
		f43 = f13*x+f23*y+f33*z+f43;
	}
	void Translate(const float *pf)				{ Translate(pf[0], pf[1], pf[2]); }

	// Scale functions
	void ScaleMatrix(const float x, const float y, const float z)
	{
		// | x  0  0  0 |
		// | 0  y  0  0 |
		// | 0  0  z  0 |
		// | 0  0  0  1 |
		f12 = f13 = f14 = f21 = f23 = f24 = f31 = f32 = f34 = f41 = f42 = f43 = 0;
		f11 = x; f22 = y; f33 = z; f44 = 1;
	}
	void ScaleMatrix(const float *pf)			{ ScaleMatrix(pf[0], pf[1], pf[2]); }
	void Scale(const float x, const float y, const float z)
	{
		// 9 muls
		// | f11 f21 f31 f41 |   | x  0  0  0 |   | f11*x f21*y f31*z f41 |
		// | f12 f22 f32 f42 |   | 0  y  0  0 |   | f12*x f22*y f32*z f42 |
		// | f13 f23 f33 f43 | * | 0  0  z  0 | = | f13*x f23*y f33*z f43 |
		// | 0   0   0   1   |   | 0  0  0  1 |   | 0     0     0     1   |
		f11 *= x; f21 *= y; f31 *= z;
		f12 *= x; f22 *= y; f32 *= z;
		f13 *= x; f23 *= y; f33 *= z;
	}
	void Scale(const float *pf)					{ Scale(pf[0], pf[1], pf[2]); }

	// Rotate functions
	void RotateXMatrix(const float fRadians)
	{
		// | 1 0    0     0 |
		// | 0 fCos -fSin 0 |
		// | 0 fSin fCos  0 |
		// | 0 0    0     1 |
		f12 = f13 = f14 = f21 = f24 = f31 = f34 = f41 = f42 = f43 = 0;
		f11 = f44 = 1;

		float fCos = cosf(fRadians);
		float fSin = sinf(fRadians);
		f22 = f33 = fCos;
		f23 = fSin;
		f32 = -fSin;
	}
	void RotateX(const float fRadians)
	{
		// 12 muls, 6 adds, 2 trig function calls
		// | f11 f21 f31 f41 |   | 1 0    0     0 |   | f11 f21*fCos+f31*fSin f31*fCos-f21*fSin f41 |
		// | f12 f22 f32 f42 |   | 0 fCos -fSin 0 |   | f12 f22*fCos+f32*fSin f32*fCos-f22*fSin f42 |
		// | f13 f23 f33 f43 | * | 0 fSin fCos  0 | = | f13 f23*fCos+f33*fSin f33*fCos-f23*fSin f43 |
		// | 0   0   0   1   |   | 0 0    0     1 |   | 0   0                 0                 1   |
		float fTemp, fCos, fSin;
		fCos = cosf(fRadians);
		fSin = sinf(fRadians);
		fTemp = f21*fCos+f31*fSin;
		f31 = f31*fCos-f21*fSin;
		f21 = fTemp;
		fTemp = f22*fCos+f32*fSin;
		f32 = f32*fCos-f22*fSin;
		f22 = fTemp;
		fTemp = f23*fCos+f33*fSin;
		f33 = f33*fCos-f23*fSin;
		f23 = fTemp;
	}
	void RotateYMatrix(const float fRadians)
	{
		// | fCos  0 fSin  0 |
		// | 0     1 0     0 |
		// | -fSin 0 fCos  0 |
		// | 0     0 0     1 |
		f12 = f14 = f21 = f23 = f24 = f32 = f34 = f41 = f42 = f43 = 0;
		f22 = f44 = 1;

		float fCos = cosf(fRadians);
		float fSin = sinf(fRadians);
		f11 = f33 = fCos;
		f13 = -fSin;
		f31 = fSin;
	}
	void RotateY(const float fRadians)
	{
		// 12 muls, 6 adds, 2 trig function calls
		// | f11 f21 f31 f41 |   | fCos  0 fSin  0 |   | f11*fCos-f31*fSin f21 f11*fSin+f31*fCos f41 |
		// | f12 f22 f32 f42 |   | 0     1 0     0 |   | f12*fCos-f32*fSin f22 f12*fSin+f32*fCos f42 |
		// | f13 f23 f33 f43 | * | -fSin 0 fCos  0 | = | f13*fCos-f33*fSin f23 f13*fSin+f33*fCos f43 |
		// | 0   0   0   1   |   | 0     0 0     1 |   | 0                 0   0                 1   |
		float fTemp, fCos, fSin;
		fCos = cosf(fRadians);
		fSin = sinf(fRadians);
		fTemp = f11*fCos-f31*fSin;
		f31 = f11*fSin+f31*fCos;
		f11 = fTemp;
		fTemp = f12*fCos-f32*fSin;
		f32 = f12*fSin+f32*fCos;
		f12 = fTemp;
		fTemp = f13*fCos-f33*fSin;
		f33 = f13*fSin+f33*fCos;
		f13 = fTemp;
	}
	void RotateZMatrix(const float fRadians)
	{
		// | fCos -fSin 0 0 |
		// | fSin fCos  0 0 |
		// | 0    0     1 0 |
		// | 0    0     0 1 |
		f13 = f14 = f23 = f24 = f31 = f32 = f34 = f41 = f42 = f43 = 0;
		f33 = f44 = 1;

		float fCos = cosf(fRadians);
		float fSin = sinf(fRadians);
		f11 = f22 = fCos;
		f12 = fSin;
		f21 = -fSin;
	}
	void RotateZ(const float fRadians)
	{
		// 12 muls, 6 adds, 2 trig function calls
		// | f11 f21 f31 f41 |   | fCos -fSin 0 0 |   | f11*fCos+f21*fSin f21*fCos-f11*fSin f31 f41 |
		// | f12 f22 f32 f42 |   | fSin fCos  0 0 |   | f12*fCos+f22*fSin f22*fCos-f12*fSin f32 f42 |
		// | f13 f23 f33 f43 | * | 0    0     1 0 | = | f13*fCos+f23*fSin f23*fCos-f13*fSin f33 f43 |
		// | 0   0   0   1   |   | 0    0     0 1 |   | 0                 0                 0   1   |
		float fTemp, fCos, fSin;
		fCos = cosf(fRadians);
		fSin = sinf(fRadians);
		fTemp = f11*fCos+f21*fSin;
		f21 = f21*fCos-f11*fSin;
		f11 = fTemp;
		fTemp = f12*fCos+f22*fSin;
		f22 = f22*fCos-f12*fSin;
		f12 = fTemp;
		fTemp = f13*fCos+f23*fSin;
		f23 = f23*fCos-f13*fSin;
		f13 = fTemp;
	}
	void RotateMatrix(const CVector &v, const float f)
	{
		// 15 muls, 10 adds, 2 trig function calls
		float fCos = cosf(f);
		CVector vCos = v * (1 - fCos);
		CVector vSin = v * sinf(f);

		f14 = f24 = f34 = f41 = f42 = f43 = 0;
		f44 = 1;

		f11 = (v.x * vCos.x) + fCos;
		f21 = (v.x * vCos.y) - (vSin.z);
		f31 = (v.x * vCos.z) + (vSin.y);
		f12 = (v.y * vCos.x) + (vSin.z);
		f22 = (v.y * vCos.y) + fCos;
		f32 = (v.y * vCos.z) - (vSin.x);
		f13 = (v.z * vCos.x) - (vSin.y);
		f32 = (v.z * vCos.y) + (vSin.x);
		f33 = (v.z * vCos.z) + fCos;
	}
	void Rotate(const CVector &v, const float f)
	{
		// 51 muls, 37 adds, 2 trig function calls
		CMatrix mat;
		mat.RotateMatrix(v, f);
		*this *= mat;
	}

	void ModelMatrix(const CQuaternion &q, const CVector &vFrom)
	{
		*this = q;
		f41 = vFrom.x;
		f42 = vFrom.y;
		f43 = vFrom.z;
	}
	void ModelMatrix(const CVector &vFrom, const CVector &vView, const CVector &vUp, const CVector &vRight)
	{
		f11 = vRight.x;	f21 = vUp.x;	f31 = -vView.x;	f41 = vFrom.x;
		f12 = vRight.y;	f22 = vUp.y;	f32 = -vView.y;	f42 = vFrom.y;
		f13 = vRight.z;	f23 = vUp.z;	f33 = -vView.z;	f43 = vFrom.z;
		f14 = 0;		f24 = 0;		f34 = 0;		f44 = 1;
	}
	void ModelMatrix(const CVector &vFrom, const CVector &vAt, const CVector &vUp)
	{
		CVector vView = vAt - vFrom;
		vView.Normalize();
		CVector vRight = vView ^ vUp;
		vRight.Normalize();
		CVector vTrueUp = vRight ^ vView;
		vTrueUp.Normalize();
		ModelMatrix(vFrom, vView, vTrueUp, vRight);
	}

	void ViewMatrix(const CQuaternion &q, const CVector &vFrom)
	{
		*this = q;
		Transpose();
		f41 = -(vFrom.x*f11 + vFrom.y*f21 + vFrom.z*f31);
		f42 = -(vFrom.x*f12 + vFrom.y*f22 + vFrom.z*f32);
		f43 = -(vFrom.x*f13 + vFrom.y*f23 + vFrom.z*f33);
	}
	void ViewMatrix(const CVector &vFrom, const CVector &vView, const CVector &vUp, const CVector &vRight)
	{
		// 9 muls, 9 adds
		f11 = vRight.x;	f21 = vRight.y;	f31 = vRight.z;	f41 = -(vFrom | vRight);
		f12 = vUp.x;	f22 = vUp.y;	f32 = vUp.z;	f42 = -(vFrom | vUp);
		f13 = -vView.x;	f23 = -vView.y;	f33 = -vView.z;	f43 = -(vFrom | -vView);
		f14 = 0;		f24 = 0;		f34 = 0;		f44 = 1;
	}
	void ViewMatrix(const CVector &vFrom, const CVector &vAt, const CVector &vUp)
	{
		CVector vView = vAt - vFrom;
		vView.Normalize();
		CVector vRight = vView ^ vUp;
		vRight.Normalize();
		CVector vTrueUp = vRight ^ vView;
		vTrueUp.Normalize();
		ViewMatrix(vFrom, vView, vTrueUp, vRight);
	}

	void ProjectionMatrix(const float fNear, const float fFar, const float fFOV, const float fAspect)
	{
		// 2 muls, 3 divs, 2 adds, 1 trig function call
		float h = 1.0f / tanf(DEGTORAD(fFOV * 0.5f));
		float Q = fFar / (fFar - fNear);
		f12 = f13 = f14 = f21 = f23 = f24 = f31 = f32 = f41 = f42 = f44 = 0;
		f11 = h / fAspect;
		f22 = h;
		f33 = Q;
		f34 = 1;
		f43 = -Q*fNear;
	}

	// For orthogonal matrices, I belive this also gives you the inverse.
	void Transpose()
	{
		float f;
		SWAP(f12, f21, f);
		SWAP(f13, f31, f);
		SWAP(f14, f41, f);
		SWAP(f23, f32, f);
		SWAP(f24, f42, f);
		SWAP(f34, f43, f);
	}
};


class CRay
{
public:
	CDoubleVector m_vOrigin;
	CDoubleVector m_vDirection;

	CRay()		{}
	CRay(CDoubleVector p1, CDoubleVector p2)	{ Init(p1, p2); }
	void Init(CDoubleVector p1, CDoubleVector p2)
	{
		m_vOrigin = p1;
		m_vDirection = p2 - p1;
		m_vDirection.Normalize();
	}

	bool Intersect(CDoubleVector vCenter, double dRadius)
	{
		CDoubleVector vDir = vCenter - m_vOrigin;
		double v = m_vDirection | vDir;
		double b2 = (vDir|vDir) - v*v;
		double r2 = dRadius * dRadius;
		if(b2 > r2)
			return false;
		//vIntersection = m_vOrigin + m_vDirection * (v - sqrtf(r2 - b2));
		return true;
	}
};

/*******************************************************************************
* Class: CLine

⌨️ 快捷键说明

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