Code:
/ 4.0 / 4.0 / 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.
//----------------------------------------------------------------------------
//
//
// 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

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ChannelBase.cs
- AuthenticateEventArgs.cs
- ContentValidator.cs
- MatrixConverter.cs
- FormViewPageEventArgs.cs
- OracleLob.cs
- _ServiceNameStore.cs
- KeyEvent.cs
- ToolStripDropDownButton.cs
- StringValidatorAttribute.cs
- RootBrowserWindowAutomationPeer.cs
- SByte.cs
- EffectiveValueEntry.cs
- ConfigsHelper.cs
- MenuItem.cs
- BinaryOperationBinder.cs
- XsdValidatingReader.cs
- ResourceExpressionBuilder.cs
- SwitchCase.cs
- DbProviderFactoriesConfigurationHandler.cs
- BypassElementCollection.cs
- Enlistment.cs
- AnimationLayer.cs
- MetadataAssemblyHelper.cs
- HttpProfileGroupBase.cs
- ToolBarTray.cs
- ObservableDictionary.cs
- Debugger.cs
- WebServiceTypeData.cs
- SharedUtils.cs
- DateTimeFormatInfoScanner.cs
- Compensation.cs
- InteropAutomationProvider.cs
- AnimationClock.cs
- CollectionsUtil.cs
- SystemWebSectionGroup.cs
- Quaternion.cs
- BitmapEffectInputConnector.cs
- XmlDocumentSerializer.cs
- WmlTextViewAdapter.cs
- DefaultSection.cs
- SoapConverter.cs
- XmlIterators.cs
- ApplicationFileCodeDomTreeGenerator.cs
- ProfilePropertyNameValidator.cs
- DataGridViewColumnCollection.cs
- CollectionViewProxy.cs
- DocumentReferenceCollection.cs
- AutomationPropertyInfo.cs
- XsdDateTime.cs
- RemoteAsymmetricSignatureFormatter.cs
- QilGeneratorEnv.cs
- DropShadowBitmapEffect.cs
- InvalidAsynchronousStateException.cs
- TraceSource.cs
- Mappings.cs
- LinkClickEvent.cs
- DataGridHelper.cs
- WebServiceHandler.cs
- ClassicBorderDecorator.cs
- EmissiveMaterial.cs
- ISAPIWorkerRequest.cs
- HttpApplicationFactory.cs
- SqlNotificationRequest.cs
- SqlCaseSimplifier.cs
- TargetConverter.cs
- CommonGetThemePartSize.cs
- XPathItem.cs
- DateTimeOffset.cs
- localization.cs
- _SslStream.cs
- ToolStripPanel.cs
- FileRegion.cs
- TraceContext.cs
- RegionData.cs
- StreamGeometry.cs
- WinOEToolBoxItem.cs
- NegotiationTokenAuthenticator.cs
- PaperSource.cs
- Package.cs
- FileLogRecord.cs
- HtmlAnchor.cs
- FactoryId.cs
- Int32Storage.cs
- DBSqlParser.cs
- IsolationInterop.cs
- codemethodreferenceexpression.cs
- RightsManagementPermission.cs
- ListViewSelectEventArgs.cs
- RewritingPass.cs
- ScriptDescriptor.cs
- OrderedDictionary.cs
- Drawing.cs
- GridSplitter.cs
- SrgsElementFactory.cs
- DataGridSortCommandEventArgs.cs
- SR.cs
- SystemPens.cs
- LogicalExpr.cs
- InfiniteIntConverter.cs