public ViewTransform(RtPoint from, RtPoint to, RtVector up) { Up = up; To = to; From = from; Forward = (To - From).Normalize(); var upNormalized = Up.Normalize(); Left = Forward.Cross(upNormalized); var trueUp = Left.Cross(Forward); var orientation = RtMatrix.Identity; orientation.M11 = Left.X; orientation.M12 = Left.Y; orientation.M13 = Left.Z; orientation.M21 = trueUp.X; orientation.M22 = trueUp.Y; orientation.M23 = trueUp.Z; orientation.M31 = -Forward.X; orientation.M32 = -Forward.Y; orientation.M33 = -Forward.Z; var translation = RtMatrix.Identity; translation.M14 = -from.X; translation.M24 = -from.Y; translation.M34 = -from.Z; Matrix = orientation * translation; }
Matrix LookAt(Vector3 up) { Vector3 right = Forward.Cross(up); right.Normalize( ); Vector3 recalcUp = right.Cross(Forward); recalcUp.Normalize( ); return (Matrix.LookAtLH(Position, Target, recalcUp)); }
public void Update(float delaMs) { // view Vector3 t = this.Translate; if (target.HasValue) { // look at View = Matrix4x4.GenLookAt(t, target.Value, up); // 将view matrix的前三行三列(3x3),每一行对应:Left, Up, Forward三轴,来求得各个轴的当前角度 // 因为LookAt实际上是求了view的反向变换:逆矩阵,下面的矩阵的转置为原来的变换矩阵 /* * view 是右手坐标系 * lx,ly,lz是x,左边为正,所以命名为:Left:l * ux,uy,uz是y,上边为正,所以命名为:Up:u * fx,fy,fz是z,向前为正,所以命名为:Forward:f * http://www.songho.ca/opengl/gl_camera.html#lookat |lx|ly|lz|0 | |1 |0 |0 |-tx| |lx|ly|lz|lx*(-tx)+ly*(-ty)+lz*(-tz)| |ux|uy|uz|0 |* |0 |1 |0 |-ty|= |ux|uy|uz|ux*(-tx)+uy*(-ty)+uz*(-tz)| |fx|fy|fz|0 | |0 |0 |1 |-tz| |fx|fy|fz|fx*(-tx)+fy*(-ty)+fz*(-tz)| |0 | 0| 0|1 | |0 |0 |0 |1 | |0 |0 |0 |1 | * */ // 后面再实现 } else { t = -t; var r = R_Before_T; // translate View = Matrix4x4.GenTranslateMat(t.x, t.y, t.z) * Matrix4x4.GenEulerMat(r.x, r.y, r.z); // rotate View = Matrix4x4.GenEulerMat(Euler.x, Euler.y, Euler.z).MulMat(View); } var matV = Matrix4x4.GenEulerMat(-Euler.x, -Euler.y, -Euler.z); Forward = matV * forward; Right = matV * right; Up = Forward.Cross(Right); // proj if (isOrtho) { // orthogonal Proj = Matrix4x4.GenOrthoFrustum(aspect, size, near, far); } else { // perspective Proj = Matrix4x4.GenFrustum(fov, aspect, near, far); } }