//获取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); }
//向量插值 public HVector InterpVec(HVector vec, float t) { HVector vecRet = new HVector(); vecRet.x = MathHelper.Interp(x, vec.x, t); vecRet.y = MathHelper.Interp(y, vec.y, t); vecRet.z = MathHelper.Interp(z, vec.z, t); vecRet.w = 1.0f; return(vecRet); }
//向量减法 public HVector Sub(HVector vec) { HVector vecRet = new HVector(); vecRet.w = 1; vecRet.x = x - vec.x; vecRet.y = y - vec.y; vecRet.z = z - vec.z; return(vecRet); }
//向量加法 public HVector Add(HVector vec) { HVector vecRet = new HVector(); vecRet.w = 1; vecRet.x = x + vec.x; vecRet.y = y + vec.y; vecRet.z = z + vec.z; return(vecRet); }
//向量乘矩阵 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 HVector HomogenizeToScreenCoord(HVector Origin) { int ScreenWidth = HScreenDevice.GetInstance().ScreenWidth; int ScreenHeight = HScreenDevice.GetInstance().ScreenHeight; float rhw = 1.0f / Origin.w; HVector vecRet = new HVector(); vecRet.x = (Origin.x * rhw + 1.0f) * ScreenWidth * 0.5f; vecRet.y = (1.0f - Origin.y * rhw) * ScreenHeight * 0.5f; vecRet.z = Origin.z * rhw; vecRet.w = 1.0f; return(vecRet); }
//向量归一 public HVector Normalize() { HVector vecRet = new HVector(); float len = Length(); if (len != 0.0f) { vecRet.x = x / len; vecRet.y = y / len; vecRet.z = z / len; } return(vecRet); }
//向量叉乘 返回向量 右手螺旋决定方向 public HVector CrossProduct(HVector vec) { HVector vecRet = new HVector(); float m1, m2, m3; m1 = y * vec.z - z * vec.y; m2 = z * vec.x - x * vec.z; m3 = x * vec.y - y * vec.x; vecRet.x = m1; vecRet.y = m2; vecRet.z = m3; vecRet.w = 1.0f; return(vecRet); }
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 HVector MulMVPMat(HVector Origin) { return(Origin.MulMat(MVPMat)); }
//向量点乘 返回是值 A x B = |A||B|Cos public float DotProduct(HVector vec) { return(x * vec.x + y * vec.y + z * vec.z); }
public a2v(HVector posPara) { pos = posPara; }