Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Core / System / Windows / Media3D / PerspectiveCamera.cs / 1 / PerspectiveCamera.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;
namespace System.Windows.Media.Media3D
{
///
/// Encapsulates a perspective projection camera.
///
public partial class PerspectiveCamera : ProjectionCamera
{
//-----------------------------------------------------
//
// Constructors
//
//-----------------------------------------------------
#region Constructors
///
public PerspectiveCamera() {}
///
public PerspectiveCamera(Point3D position, Vector3D lookDirection, Vector3D upDirection, double fieldOfView)
{
Position = position;
LookDirection = lookDirection;
UpDirection = upDirection;
FieldOfView = fieldOfView;
}
#endregion Constructors
//------------------------------------------------------
//
// Public Methods
//
//-----------------------------------------------------
//------------------------------------------------------
//
// Public Properties
//
//------------------------------------------------------
//-----------------------------------------------------
//
// Public Events
//
//------------------------------------------------------
//-----------------------------------------------------
//
// Internal Methods
//
//-----------------------------------------------------
#region Internal Methods
internal Matrix3D GetProjectionMatrix(double aspectRatio, double zn, double zf)
{
double fov = M3DUtil.DegreesToRadians(FieldOfView);
// Note: h and w are 1/2 of the inverse of the width/height ratios:
//
// h = 1/(heightDepthRatio) * (1/2)
// w = 1/(widthDepthRatio) * (1/2)
//
// Computation for h is a bit different than what you will find in
// D3DXMatrixPerspectiveFovRH because we have a horizontal rather
// than vertical FoV.
double halfWidthDepthRatio = Math.Tan(fov/2);
double h = aspectRatio/halfWidthDepthRatio;
double w = 1/halfWidthDepthRatio;
double m22 = zf != Double.PositiveInfinity ? zf/(zn-zf) : -1;
double m32 = zn*m22;
return new Matrix3D(
w, 0, 0, 0,
0, h, 0, 0,
0, 0, m22, -1,
0, 0, m32, 0);
}
internal override Matrix3D GetProjectionMatrix(double aspectRatio)
{
return GetProjectionMatrix(aspectRatio, NearPlaneDistance, FarPlaneDistance);
}
internal override RayHitTestParameters RayFromViewportPoint(Point p, Size viewSize, Rect3D boundingRect, out double distanceAdjustment)
{
// The camera may be animating. Take a snapshot of the current value
// and get the property values we need. (Window OS #992662)
Point3D position = Position;
Vector3D lookDirection = LookDirection;
Vector3D upDirection = UpDirection;
Transform3D transform = Transform;
double zn = NearPlaneDistance;
double zf = FarPlaneDistance;
double fov = M3DUtil.DegreesToRadians(FieldOfView);
//
// 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);
// Note: h and w are 1/2 of the inverse of the width/height ratios:
//
// h = 1/(heightDepthRatio) * (1/2)
// w = 1/(widthDepthRatio) * (1/2)
//
// Computation for h is a bit different than what you will find in
// D3DXMatrixPerspectiveFovRH because we have a horizontal rather
// than vertical FoV.
double aspectRatio = M3DUtil.GetAspectRatio(viewSize);
double halfWidthDepthRatio = Math.Tan(fov/2);
double h = aspectRatio/halfWidthDepthRatio;
double w = 1/halfWidthDepthRatio;
// To get from projective space to camera space we apply the
// width/height ratios to find our normalized point at 1 unit
// in front of the camera. (1 is convenient, but has no other
// special significance.) See note above about the construction
// of w and h.
Vector3D rayDirection = new Vector3D(np.X/w, np.Y/h, -1);
// Apply the inverse of the view matrix to our rayDirection vector
// to convert it from camera to world space.
//
// NOTE: Because our construction of the ray assumes that the
// viewMatrix translates the position to the origin we pass
// null for the Camera.Transform below and account for it
// later.
Matrix3D viewMatrix = CreateViewMatrix(/* trasform = */ null, ref position, ref lookDirection, ref upDirection);
Matrix3D invView = viewMatrix;
invView.Invert();
invView.MultiplyVector(ref rayDirection);
// The we have the ray direction, now we need the origin. The camera's
// position would work except that we would intersect geometry between
// the camera plane and the near plane so instead we must find the
// point on the project plane where the ray (position, rayDirection)
// intersect (Windows OS #1005064):
//
// | _.> p = camera position
// rd _+" ld = camera look direction
// .-" |ro pp = projection plane
// _.-" | rd = ray direction
// p +"--------+---> ro = desired ray origin on pp
// ld |
// pp
//
// Above we constructed the direction such that it's length projects to
// 1 unit on the lookDirection vector.
//
//
// rd _.>
// .-" rd = unnormalized rayDirection
// _.-" ld = normalized lookDirection (length = 1)
// -"--------->
// ld
//
// So to find the desired rayOrigin on the projection plane we simply do:
Point3D rayOrigin = position + zn*rayDirection;
rayDirection.Normalize();
// Account for the Camera.Transform we ignored during ray construction above.
if (transform != null && transform != Transform3D.Identity)
{
Matrix3D m = transform.Value;
m.MultiplyPoint(ref rayOrigin);
m.MultiplyVector(ref rayDirection);
PrependInverseTransform(m, ref viewMatrix);
}
RayHitTestParameters rayParameters = new RayHitTestParameters(rayOrigin, rayDirection);
//
// Compute HitTestProjectionMatrix
//
Matrix3D projectionMatrix = GetProjectionMatrix(aspectRatio, zn, zf);
// The projectionMatrix takes camera-space 3D points into normalized clip
// space.
// The viewportMatrix will take normalized clip space into
// viewport coordinates, with an additional 2D translation
// to put the ray at the rayOrigin.
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 =
viewMatrix *
projectionMatrix *
viewportMatrix;
//
// Perspective camera doesn't allow negative NearPlanes, so there's
// not much point in adjusting the ray origin. Hence, 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
- DictationGrammar.cs
- JsonMessageEncoderFactory.cs
- SequentialUshortCollection.cs
- PrtCap_Reader.cs
- HashCodeCombiner.cs
- ParserStreamGeometryContext.cs
- Number.cs
- Token.cs
- KnownTypes.cs
- AutomationIdentifier.cs
- LiteralLink.cs
- UnsafeNativeMethods.cs
- Transform3D.cs
- ModuleBuilderData.cs
- RemoteWebConfigurationHostServer.cs
- ComEventsSink.cs
- SafeNativeMethods.cs
- XsdBuilder.cs
- SchemaHelper.cs
- PeerResolverSettings.cs
- Types.cs
- Decoder.cs
- ErrorView.xaml.cs
- Enlistment.cs
- SemanticResultValue.cs
- TreeViewImageKeyConverter.cs
- Bezier.cs
- DetailsViewDeleteEventArgs.cs
- ExpressionBuilder.cs
- LinkLabel.cs
- CloudCollection.cs
- WmlLiteralTextAdapter.cs
- QilSortKey.cs
- FrameworkContentElement.cs
- X500Name.cs
- Decoder.cs
- EntitySet.cs
- FamilyMap.cs
- ExclusiveTcpTransportManager.cs
- ParserHooks.cs
- UITypeEditor.cs
- SystemIcmpV4Statistics.cs
- DbModificationCommandTree.cs
- AnyAllSearchOperator.cs
- ClientConfigurationSystem.cs
- CurrentChangedEventManager.cs
- PerspectiveCamera.cs
- ScrollPattern.cs
- BrushMappingModeValidation.cs
- wgx_commands.cs
- LayoutTableCell.cs
- Utils.cs
- UnsafeNativeMethods.cs
- HiddenField.cs
- CompilerScope.Storage.cs
- AssemblyName.cs
- X509CertificateCollection.cs
- DllNotFoundException.cs
- RangeValidator.cs
- ObjectDisposedException.cs
- WebHttpBindingCollectionElement.cs
- DocumentScope.cs
- DesignOnlyAttribute.cs
- RSACryptoServiceProvider.cs
- XmlDataSourceView.cs
- IdentityModelDictionary.cs
- NameNode.cs
- Vector.cs
- HttpCapabilitiesEvaluator.cs
- SqlDataSourceCommandEventArgs.cs
- XmlQualifiedName.cs
- WebBrowserUriTypeConverter.cs
- PerformanceCounterManager.cs
- UnknownWrapper.cs
- LoginName.cs
- DSASignatureFormatter.cs
- ToolStripPanel.cs
- DBConnection.cs
- SafeNativeMethods.cs
- ValidationSummary.cs
- HttpClientCertificate.cs
- DesignTimeData.cs
- UnsafeNativeMethods.cs
- Light.cs
- XmlAttribute.cs
- GeneralTransform3D.cs
- MiniModule.cs
- PagesSection.cs
- RegionInfo.cs
- WorkflowDesignerMessageFilter.cs
- XmlSchemaSimpleContent.cs
- CodeCatchClause.cs
- TextSimpleMarkerProperties.cs
- DataSourceHelper.cs
- Baml2006KnownTypes.cs
- Screen.cs
- Comparer.cs
- FilteredAttributeCollection.cs
- TextFindEngine.cs
- ComponentRenameEvent.cs