//获取旋转矩阵 XYZ轴旋转 public static HMatrix GetRotateMat(float x, float y, float z) { //X Y Z矩阵相乘 这里是为了好理解 但是这样做效率有浪费 6次三角函数 2次矩阵乘法 HMatrix matRet = GetRotateMatX(x).Mul(GetRotateMatY(y)).Mul(GetRotateMatZ(z)); return(matRet); }
//获取LookAt矩阵 //相机的位置 相机的看着那个位置(决定相机方向) 相机上方位置 // see:https://zhuanlan.zhihu.com/p/66384929 // Rx Ry Rz 0 // Ux Uy Uz 0 // Dx Dy Dz 0 // 0 0 0 1 相机空间是左手系 public static HMatrix GetLookAtMat(HVector camera, HVector at, HVector up) { HMatrix matRet = new HMatrix(); HVector CameraXAxis, CameraYAxis, CameraZAxis; CameraZAxis = at.Sub(camera); CameraZAxis = CameraZAxis.Normalize(); CameraYAxis = up.Normalize(); CameraXAxis = CameraZAxis.CrossProduct(CameraYAxis); CameraXAxis = CameraXAxis.Normalize(); matRet.m[0, 0] = CameraXAxis.x; matRet.m[1, 0] = CameraXAxis.y; matRet.m[2, 0] = CameraXAxis.z; matRet.m[3, 0] = -CameraXAxis.DotProduct(camera); matRet.m[0, 1] = CameraYAxis.x; matRet.m[1, 1] = CameraYAxis.y; matRet.m[2, 1] = CameraYAxis.z; matRet.m[3, 1] = -CameraYAxis.DotProduct(camera); matRet.m[0, 2] = CameraZAxis.x; matRet.m[1, 2] = CameraZAxis.y; matRet.m[2, 2] = CameraZAxis.z; matRet.m[3, 2] = -CameraZAxis.DotProduct(camera); matRet.m[0, 3] = matRet.m[1, 3] = matRet.m[2, 3] = 0.0f; matRet.m[3, 3] = 1.0f; return(matRet); }
//更新MVP矩阵 void UpdateMVPMat() { HMatrix mat = MathHelper.GetRotateMat(0, 0.8f, 0.8f); Transform.ModleMat = mat; Transform.UpdateMVPMat(); }
//获取缩放矩阵 public static HMatrix GetScaleMat(float x, float y, float z) { HMatrix matRet = new HMatrix(); matRet = GetIdentityMat(); matRet.m[0, 0] = x; matRet.m[1, 1] = y; matRet.m[2, 2] = z; return(matRet); }
//获取平移矩阵 public static HMatrix GetTranslateMat(float x, float y, float z) { HMatrix matRet = new HMatrix(); matRet = GetIdentityMat(); matRet.m[3, 0] = x; matRet.m[3, 1] = y; matRet.m[3, 2] = z; return(matRet); }
//获取0矩阵 public static HMatrix GetZeroMat() { HMatrix matRet = new HMatrix(); matRet.m[0, 0] = matRet.m[0, 1] = matRet.m[0, 2] = matRet.m[0, 3] = 0.0f; matRet.m[1, 0] = matRet.m[1, 1] = matRet.m[1, 2] = matRet.m[1, 3] = 0.0f; matRet.m[2, 0] = matRet.m[2, 1] = matRet.m[2, 2] = matRet.m[2, 3] = 0.0f; matRet.m[3, 0] = matRet.m[3, 1] = matRet.m[3, 2] = matRet.m[3, 3] = 0.0f; return(matRet); }
//向量乘矩阵 public HVector MulMat(HMatrix mat) { HVector vec = new HVector(); float X = x, Y = y, Z = z, W = w; vec.x = X * mat.m[0, 0] + Y * mat.m[1, 0] + Z * mat.m[2, 0] + W * mat.m[3, 0]; vec.y = X * mat.m[0, 1] + Y * mat.m[1, 1] + Z * mat.m[2, 1] + W * mat.m[3, 1]; vec.z = X * mat.m[0, 2] + Y * mat.m[1, 2] + Z * mat.m[2, 2] + W * mat.m[3, 2]; vec.w = X * mat.m[0, 3] + Y * mat.m[1, 3] + Z * mat.m[2, 3] + W * mat.m[3, 3]; return(vec); }
//获取投影矩阵 乘以这个矩阵之后得到的是相机空间的坐标 public static HMatrix GetPerspectiveMat(float fovy, float aspect, float zn, float zf) { float fax = 1.0f / (float)Math.Tan(fovy * 0.5f); HMatrix matRet = GetZeroMat(); matRet.m[0, 0] = (float)(fax / aspect); matRet.m[1, 1] = (float)(fax); matRet.m[2, 2] = zf / (zf - zn); matRet.m[3, 2] = -zn * zf / (zf - zn); matRet.m[2, 3] = 1; return(matRet); }
//获取旋转矩阵 Z轴旋转 // https://blog.csdn.net/csxiaoshui/article/details/65446125 public static HMatrix GetRotateMatZ(float z) { HMatrix matRet = GetIdentityMat(); //单位矩阵 float SinValue = (float)Math.Sin(z); float CosValue = (float)Math.Cos(z); matRet.m[0, 0] = CosValue; matRet.m[1, 0] = -SinValue; matRet.m[2, 0] = 0; matRet.m[3, 0] = 0; matRet.m[0, 1] = SinValue; matRet.m[1, 1] = CosValue; matRet.m[2, 1] = 0; matRet.m[3, 1] = 0; matRet.m[0, 2] = 0; matRet.m[1, 2] = 0; matRet.m[2, 2] = 1; matRet.m[3, 2] = 0; matRet.m[0, 3] = 0; matRet.m[1, 3] = 0; matRet.m[2, 3] = 0; matRet.m[3, 3] = 1; return(matRet); }
//矩阵缩放 public HMatrix Scale(float f) { HMatrix matRet = new HMatrix(); int i, j; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { matRet.m[i, j] = m[i, j] * f; } } return(matRet); }
//矩阵减法 public HMatrix Sub(HMatrix mat) { HMatrix matRet = new HMatrix(); int i, j; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { matRet.m[i, j] = m[i, j] - mat.m[i, j]; } } return(matRet); }
//补充单元测试 public bool UnitTest() { HMatrix mat1 = new HMatrix(); HMatrix mat2 = new HMatrix(); HMatrix mat3 = new HMatrix(); mat1.m[0, 0] = 0; mat1.m[1, 0] = 0; mat1.m[2, 0] = 0; mat1.m[3, 0] = 0; mat1.m[0, 1] = 0; mat1.m[1, 1] = 0; mat1.m[2, 1] = 0; mat1.m[3, 1] = 0; mat1.m[0, 2] = 0; mat1.m[1, 2] = 0; mat1.m[2, 2] = 0; mat1.m[3, 2] = 0; mat1.m[0, 3] = 0; mat1.m[1, 3] = 0; mat1.m[2, 3] = 0; mat1.m[3, 3] = 0; if (mat1.Add(mat2) != mat3) { return(false); } return(true); }
//矩阵乘法 public HMatrix Mul(HMatrix mat) { HMatrix matRet = new HMatrix(); int i, j; for (i = 0; i < 4; i++) { for (j = 0; j < 4; j++) { matRet.m[i, j] = (m[i, 0] * mat.m[0, j]) + (m[i, 1] * mat.m[1, j]) + (m[i, 2] * mat.m[2, j]) + (m[i, 3] * mat.m[3, j]); } } return(matRet); }
public void Init() { int ScreenWidth = HScreenDevice.GetInstance().ScreenWidth; int ScreenHeight = HScreenDevice.GetInstance().ScreenHeight; ModleMat = MathHelper.GetIdentityMat(); HVector camera = new HVector(5, 0, 0, 1); HVector at = new HVector(0, 0, 0, 1); HVector up = new HVector(0, 1, 0, 1); ViewMat = MathHelper.GetLookAtMat( camera, at, up ); // fov = 90度 0.5pai ProjectionMat = MathHelper.GetPerspectiveMat(3.1415926f * 0.5f, (float)ScreenWidth / (float)ScreenHeight, 1.0f, 500.0f); UpdateMVPMat(); }
// 更新投影矩阵 public void UpdateMVPMat() { MVPMat = ModleMat.Mul(ViewMat).Mul(ProjectionMat); }