/// <summary> /// Rotates a mat4 by the given angle /// </summary> /// <param name="output">{mat4} out the receiving matrix</param> /// <param name="a">{mat4} a the matrix to rotate</param> /// <param name="rad">{Number} rad the angle to rotate the matrix by</param> /// <param name="axis">{vec3} axis the axis to rotate around</param> /// <returns>{mat4} out</returns> public static float[] Rotate(float[] output, float[] a, float rad, float[] axis) { float x = axis[0]; float y = axis[1]; float z = axis[2]; float len = GameMath.Sqrt(x * x + y * y + z * z); float s; float c; float t; float a00; float a01; float a02; float a03; float a10; float a11; float a12; float a13; float a20; float a21; float a22; float a23; float b00; float b01; float b02; float b10; float b11; float b12; float b20; float b21; float b22; if (GlMatrixMathf.Abs(len) < GlMatrixMathf.GLMAT_EPSILON()) { return(null); } len = 1 / len; x *= len; y *= len; z *= len; s = GameMath.Sin(rad); c = GameMath.Cos(rad); t = 1 - c; a00 = a[0]; a01 = a[1]; a02 = a[2]; a03 = a[3]; a10 = a[4]; a11 = a[5]; a12 = a[6]; a13 = a[7]; a20 = a[8]; a21 = a[9]; a22 = a[10]; a23 = a[11]; // Construct the elements of the rotation matrix b00 = x * x * t + c; b01 = y * x * t + z * s; b02 = z * x * t - y * s; b10 = x * y * t - z * s; b11 = y * y * t + c; b12 = z * y * t + x * s; b20 = x * z * t + y * s; b21 = y * z * t - x * s; b22 = z * z * t + c; // Perform rotation-specific matrix multiplication output[0] = a00 * b00 + a10 * b01 + a20 * b02; output[1] = a01 * b00 + a11 * b01 + a21 * b02; output[2] = a02 * b00 + a12 * b01 + a22 * b02; output[3] = a03 * b00 + a13 * b01 + a23 * b02; output[4] = a00 * b10 + a10 * b11 + a20 * b12; output[5] = a01 * b10 + a11 * b11 + a21 * b12; output[6] = a02 * b10 + a12 * b11 + a22 * b12; output[7] = a03 * b10 + a13 * b11 + a23 * b12; output[8] = a00 * b20 + a10 * b21 + a20 * b22; output[9] = a01 * b20 + a11 * b21 + a21 * b22; output[10] = a02 * b20 + a12 * b21 + a22 * b22; output[11] = a03 * b20 + a13 * b21 + a23 * b22; if (a != output) { // If the source and destination differ, copy the unchanged last row output[12] = a[12]; output[13] = a[13]; output[14] = a[14]; output[15] = a[15]; } return(output); }
/// <summary> /// Generates a look-at matrix with the given eye position, focal point, and up axis /// </summary> /// <param name="output">{mat4} out mat4 frustum matrix will be written into</param> /// <param name="eye">{vec3} eye Position of the viewer</param> /// <param name="center">{vec3} center Point the viewer is looking at</param> /// <param name="up">{vec3} up vec3 pointing up</param> /// <returns>{mat4} out</returns> public static float[] LookAt(float[] output, float[] eye, float[] center, float[] up) { float x0; float x1; float x2; float y0; float y1; float y2; float z0; float z1; float z2; float len; float eyex = eye[0]; float eyey = eye[1]; float eyez = eye[2]; float upx = up[0]; float upy = up[1]; float upz = up[2]; float centerx = center[0]; float centery = center[1]; float centerz = center[2]; if (GlMatrixMathf.Abs(eyex - centerx) < GlMatrixMathf.GLMAT_EPSILON() && GlMatrixMathf.Abs(eyey - centery) < GlMatrixMathf.GLMAT_EPSILON() && GlMatrixMathf.Abs(eyez - centerz) < GlMatrixMathf.GLMAT_EPSILON()) { return(Mat4f.Identity(output)); } z0 = eyex - centerx; z1 = eyey - centery; z2 = eyez - centerz; len = 1 / GameMath.Sqrt(z0 * z0 + z1 * z1 + z2 * z2); z0 *= len; z1 *= len; z2 *= len; x0 = upy * z2 - upz * z1; x1 = upz * z0 - upx * z2; x2 = upx * z1 - upy * z0; len = GameMath.Sqrt(x0 * x0 + x1 * x1 + x2 * x2); if (len == 0) { x0 = 0; x1 = 0; x2 = 0; } else { len = 1 / len; x0 *= len; x1 *= len; x2 *= len; } y0 = z1 * x2 - z2 * x1; y1 = z2 * x0 - z0 * x2; y2 = z0 * x1 - z1 * x0; len = GameMath.Sqrt(y0 * y0 + y1 * y1 + y2 * y2); if (len == 0) { y0 = 0; y1 = 0; y2 = 0; } else { len = 1 / len; y0 *= len; y1 *= len; y2 *= len; } output[0] = x0; output[1] = y0; output[2] = z0; output[3] = 0; output[4] = x1; output[5] = y1; output[6] = z1; output[7] = 0; output[8] = x2; output[9] = y2; output[10] = z2; output[11] = 0; output[12] = -(x0 * eyex + x1 * eyey + x2 * eyez); output[13] = -(y0 * eyex + y1 * eyey + y2 * eyez); output[14] = -(z0 * eyex + z1 * eyey + z2 * eyez); output[15] = 1; return(output); }