예제 #1
0
파일: Mat4f.cs 프로젝트: Archina/vsapi
        /// <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);
        }
예제 #2
0
파일: Mat4f.cs 프로젝트: Archina/vsapi
        /// <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);
        }