MatrixCamera.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ 4.0 / 4.0 / untmp / DEVDIV_TFS / Dev10 / Releases / RTMRel / wpf / src / Core / CSharp / System / Windows / Media3D / MatrixCamera.cs / 1305600 / MatrixCamera.cs

                            //---------------------------------------------------------------------------- 
//
// 
//    Copyright (C) Microsoft Corporation.  All rights reserved.
//  
//
//--------------------------------------------------------------------------- 
 
using System;
using System.Diagnostics; 
using System.Windows;
using MS.Internal.Media3D;
using System.ComponentModel.Design.Serialization;
using System.Windows.Markup; 
using CultureInfo = System.Globalization.CultureInfo;
 
using SR=MS.Internal.PresentationCore.SR; 
using SRID=MS.Internal.PresentationCore.SRID;
 
namespace System.Windows.Media.Media3D
{
    /// 
    ///     The MatrixCamera subclass of Camera provides a means for directly 
    ///     specifying a Matrix as the projection transformation.  This is
    ///     useful for apps that have their own projection matrix calculation 
    ///     mechanisms. 
    /// 
    public partial class MatrixCamera : Camera 
    {
        //-----------------------------------------------------
        //
        //  Constructors 
        //
        //----------------------------------------------------- 
 
        #region Constructors
 
        /// 
        ///     Default constructor
        /// 
        public MatrixCamera() {} 

        ///  
        ///     Construct a MatrixCamera from view and projection matrices 
        /// 
        public MatrixCamera(Matrix3D viewMatrix, Matrix3D projectionMatrix) 
        {
            ViewMatrix = viewMatrix;
            ProjectionMatrix = projectionMatrix;
        } 

        #endregion Constructors 
 
        //------------------------------------------------------
        // 
        //  Public Methods
        //
        //-----------------------------------------------------
 
        //------------------------------------------------------
        // 
        //  Public Properties 
        //
        //------------------------------------------------------ 

        //-----------------------------------------------------
        //
        //  Internal Methods 
        //
        //------------------------------------------------------ 
 
        #region Internal Methods
 
        // NOTE:  We consider Camera.Transform to be part of the view matrix
        //        here, where as the read/write ViewMatrix property does not
        //        include the camera's Transform.
        internal override Matrix3D GetViewMatrix() 
        {
            Matrix3D viewMatrix = ViewMatrix; 
            PrependInverseTransform(Transform, ref viewMatrix); 
            return viewMatrix;
        } 

        internal override Matrix3D GetProjectionMatrix(double aspectRatio) { return ProjectionMatrix; }

        internal override RayHitTestParameters RayFromViewportPoint(Point p, Size viewSize, Rect3D boundingRect, out double distanceAdjustment) 
        {
            // 
            //  Compute rayParameters 
            //
 
            // Find the point on the projection plane in post-projective space where
            // the viewport maps to a 2x2 square from (-1,1)-(1,-1).
            Point np = M3DUtil.GetNormalizedPoint(p, viewSize);
 
            //
 
 
            // So (conceptually) the user clicked on the point (np.X,
            // np.Y, 0) in post-projection clipping space and the ray 
            // extends in the direction (0, 0, 1) because our ray
            // after projection looks down the positive z axis.  We
            // need to convert this ray and direction back to world
            // space. 

            Matrix3D worldToCamera = GetViewMatrix() * ProjectionMatrix; 
            Matrix3D cameraToWorld = worldToCamera; 

            if (!cameraToWorld.HasInverse) 
            {
                //

 

 
                // NTRAID#Longhorn-1180933-2004/07/30-danwo - Need to handle singular matrix cameras 
                throw new NotSupportedException(SR.Get(SRID.HitTest_Singular));
            } 

            cameraToWorld.Invert();

            Point4D origin4D = new Point4D(np.X,np.Y,0,1) * cameraToWorld; 
            Point3D origin = new Point3D( origin4D.X/origin4D.W,
                                          origin4D.Y/origin4D.W, 
                                          origin4D.Z/origin4D.W ); 

            // To transform the direction we use the Jacobian of 
            // cameraToWorld at the point np.X,np.Y,0 that we just
            // transformed.
            //
            // The Jacobian of the homogeneous matrix M is a 3x3 matrix. 
            //
            // Let x be the point we are computing the Jacobian at, and y be the 
            // result of transforming x by M, i.e. 
            // (wy w) = (x 1) M
            // Where (wy w) is the homogeneous point representing y with w as its homogeneous coordinate 
            // And (x 1) is the homogeneous point representing x with 1 as its homogeneous coordinate
            //
            // Then the i,j component of the Jacobian (at x) is
            // (M_ij - M_i4 y_j) / w 
            //
            // Since we're only concerned with the direction of the 
            // transformed vector and not its magnitude, we can scale 
            // this matrix by a POSITIVE factor.  The computation
            // below computes the Jacobian scaled by 1/w and then 
            // after we normalize the final vector we flip it around
            // if w is negative.
            //
            // To transform a vector we just right multiply it by this Jacobian matrix. 
            //
            // Compute the Jacobian at np.X,np.Y,0 ignoring the constant factor of w. 
            // Here's the pattern 
            //
            // double Jij = cameraToWorld.Mij - cameraToWorld.Mi4 * origin.j 
            //
            // but we only need J31,J32,&J33 because we're only
            // transforming the vector 0,0,1
 
            double J31 = cameraToWorld.M31 - cameraToWorld.M34 * origin.X;
            double J32 = cameraToWorld.M32 - cameraToWorld.M34 * origin.Y; 
            double J33 = cameraToWorld.M33 - cameraToWorld.M34 * origin.Z; 

            // Then multiply that matrix by (0, 0, 1) which is 
            // the direction of the ray in post-projection space.
            Vector3D direction = new Vector3D( J31, J32, J33 );
            direction.Normalize();
 
            // We multiplied by the Jacobian times W, so we need to
            // account for whether that flipped our result or not. 
            if (origin4D.W < 0) 
            {
                direction = -direction; 
            }

            RayHitTestParameters rayParameters = new RayHitTestParameters(origin, direction);
 
            //
            //  Compute HitTestProjectionMatrix 
            // 

            // The viewportMatrix will take normalized clip space into 
            // viewport coordinates, with an additional 2D translation
            // to put the ray at the origin.
            Matrix3D viewportMatrix = new Matrix3D();
            viewportMatrix.TranslatePrepend(new Vector3D(-p.X,viewSize.Height-p.Y,0)); 
            viewportMatrix.ScalePrepend(new Vector3D(viewSize.Width/2,-viewSize.Height/2,1));
            viewportMatrix.TranslatePrepend(new Vector3D(1,1,0)); 
 
            // `First world-to-camera, then camera's projection, then normalized clip space to viewport.
            rayParameters.HitTestProjectionMatrix = 
                worldToCamera *
                viewportMatrix;

            // 
            // MatrixCamera does not allow for Near/Far plane adjustment, so
            // the distanceAdjustment remains 0. 
            // 
            distanceAdjustment = 0.0;
 
            return rayParameters;
        }

        #endregion Internal Methods 

        //----------------------------------------------------- 
        // 
        //  Private Fields
        // 
        //-----------------------------------------------------
    }
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK