Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Core / CSharp / 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. //---------------------------------------------------------------------------- // // // 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
- ItemsPresenter.cs
- Lasso.cs
- ActivationServices.cs
- OutputScope.cs
- HostingEnvironmentSection.cs
- MetafileHeaderWmf.cs
- HttpProxyTransportBindingElement.cs
- PreviousTrackingServiceAttribute.cs
- LogicalExpr.cs
- MappingModelBuildProvider.cs
- PerfService.cs
- ClientData.cs
- HyperLinkStyle.cs
- SqlInternalConnectionSmi.cs
- UriTemplateVariableQueryValue.cs
- NodeInfo.cs
- Container.cs
- DateTimeOffset.cs
- MenuItemBinding.cs
- MediaElementAutomationPeer.cs
- InvalidOleVariantTypeException.cs
- Variable.cs
- _PooledStream.cs
- MsmqNonTransactedPoisonHandler.cs
- FixedSOMTableRow.cs
- SBCSCodePageEncoding.cs
- CodeEntryPointMethod.cs
- InkSerializer.cs
- DifferencingCollection.cs
- TypeReference.cs
- MetadataArtifactLoaderXmlReaderWrapper.cs
- SoapTypeAttribute.cs
- TimeSpan.cs
- IsolatedStoragePermission.cs
- Enumerable.cs
- PerformanceCountersBase.cs
- UntypedNullExpression.cs
- prompt.cs
- _BaseOverlappedAsyncResult.cs
- ProfileManager.cs
- ListSortDescriptionCollection.cs
- BrowserCapabilitiesCodeGenerator.cs
- Compensate.cs
- TypeSchema.cs
- DefaultBinder.cs
- AlphabeticalEnumConverter.cs
- XmlDataSourceDesigner.cs
- IndentedTextWriter.cs
- Int64Converter.cs
- BindStream.cs
- RequestStatusBarUpdateEventArgs.cs
- ExpressionBuilderContext.cs
- XPathNodePointer.cs
- StylusCollection.cs
- _ConnectStream.cs
- RemoteWebConfigurationHost.cs
- ContextStaticAttribute.cs
- FormViewDeletedEventArgs.cs
- ProxyAttribute.cs
- CollectionViewSource.cs
- StoreContentChangedEventArgs.cs
- OleServicesContext.cs
- ListItemCollection.cs
- WeakKeyDictionary.cs
- DesignerActionItemCollection.cs
- DataSourceExpressionCollection.cs
- assertwrapper.cs
- Material.cs
- VirtualPathProvider.cs
- XmlTypeMapping.cs
- DataRelationCollection.cs
- LicenseException.cs
- EdmScalarPropertyAttribute.cs
- TableLayoutSettingsTypeConverter.cs
- NumberEdit.cs
- RankException.cs
- WindowsStartMenu.cs
- BitmapPalettes.cs
- TdsParserSafeHandles.cs
- OAVariantLib.cs
- ReadOnlyDictionary.cs
- EntityDataSourceColumn.cs
- Stack.cs
- RequestUriProcessor.cs
- InputScopeManager.cs
- RedistVersionInfo.cs
- MsmqTransportSecurityElement.cs
- uribuilder.cs
- InvalidCommandTreeException.cs
- ForeignKeyConstraint.cs
- DataViewManagerListItemTypeDescriptor.cs
- CultureTableRecord.cs
- x509utils.cs
- MarginCollapsingState.cs
- RoutedPropertyChangedEventArgs.cs
- RtfControls.cs
- WebPartMovingEventArgs.cs
- HttpRequestContext.cs
- AudioFormatConverter.cs
- XmlSchemaSet.cs