none
How can I get a projection matrix?

    Question

  • 1. I want to get a projection matrix which I can get from a device.Transform.Projection attribute of managed Direct3D.
    Viewport3D.Transform.Value and Viewport3D.Camera.Transform.Value has a unitary matrix. How can I get it?
    2. Why device of managed Direct3D changes yScale value (M22 of projection matrix) but Viewport3D (as I guess) changes xScale value  (M11 of projection matrix) when client area was changed? Can I force Viewport3D to have a scaling behavior as much as device of managed Direct3D?

    Thanks
    Friday, April 10, 2009 8:24 AM

Answers

  • You can get the projection matrix by mathematical calculations.

    Pay attention to the type of Camera. PerspectiveCamera and OrthographicCamera has different calculation process.

    For example:

            private static Matrix3D GetProjectionMatrix(OrthographicCamera camera, double aspectRatio)
            { 
                // This math is identical to what you find documented for
                // D3DXMatrixOrthoRH with the exception that in WPF only
                // the camera's width is specified.  Height is calculated
                // from width and the aspect ratio.
                double w = camera.Width;
                double h = w / aspectRatio;
                double zn = camera.NearPlaneDistance;
                double zf = camera.FarPlaneDistance;
                double m33 = 1 / (zn - zf);
                double m43 = zn * m33;
                return new Matrix3D(
                    2 / w, 0, 0, 0,
                      0, 2 / h, 0, 0,
                      0, 0, m33, 0,
                      0, 0, m43, 1);
            }
            private static Matrix3D GetProjectionMatrix(PerspectiveCamera camera, double aspectRatio)
            { 
                // This math is identical to what you find documented for
                // D3DXMatrixPerspectiveFovRH with the exception that in
                // WPF the camera's horizontal rather the vertical
                // field-of-view is specified.
                double hFoV = MathUtils.DegreesToRadians(camera.FieldOfView);
                double zn = camera.NearPlaneDistance;
                double zf = camera.FarPlaneDistance;
                double xScale = 1 / Math.Tan(hFoV / 2);
                double yScale = aspectRatio * xScale;
                double m33 = (zf == double.PositiveInfinity) ? -1 : (zf / (zn - zf));
                double m43 = zn * m33;
                return new Matrix3D(
                    xScale, 0, 0, 0,
                         0, yScale, 0, 0,
                         0, 0, m33, -1,
                         0, 0, m43, 0);
            }
            /// <summary>
            ///     Computes the effective projection matrix for the given
            ///     camera.
            /// </summary>
            public static Matrix3D GetProjectionMatrix(Camera camera, double aspectRatio)
            {
                if (camera == null)
                {
                    throw new ArgumentNullException("camera");
                }
                PerspectiveCamera perspectiveCamera = camera as PerspectiveCamera;
                if (perspectiveCamera != null)
                {
                    return GetProjectionMatrix(perspectiveCamera, aspectRatio);
                }
                OrthographicCamera orthographicCamera = camera as OrthographicCamera;
                if (orthographicCamera != null)
                {
                    return GetProjectionMatrix(orthographicCamera, aspectRatio);
                }
                MatrixCamera matrixCamera = camera as MatrixCamera;
                if (matrixCamera != null)
                {
                    return matrixCamera.ProjectionMatrix;
                }
                throw new ArgumentException(String.Format("Unsupported camera type '{0}'.", camera.GetType().FullName), "camera");
            }
    • Proposed as answer by Tao Liang Tuesday, April 14, 2009 8:30 AM
    • Marked as answer by Tao Liang Wednesday, April 15, 2009 1:24 AM
    Tuesday, April 14, 2009 8:29 AM