Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / wpf / src / Core / CSharp / System / Windows / Media3D / OrthographicCamera.cs / 1 / OrthographicCamera.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 an orthagraphic projection camera.
///
public partial class OrthographicCamera : ProjectionCamera
{
//-----------------------------------------------------
//
// Constructors
//
//-----------------------------------------------------
///
public OrthographicCamera() {}
///
public OrthographicCamera(Point3D position, Vector3D lookDirection, Vector3D upDirection, double width)
{
Position = position;
LookDirection = lookDirection;
UpDirection = upDirection;
Width = width;
}
//------------------------------------------------------
//
// Public Methods
//
//-----------------------------------------------------
//------------------------------------------------------
//
// Public Properties
//
//------------------------------------------------------
//-----------------------------------------------------
//
// Internal Methods
//
//------------------------------------------------------
#region Internal Methods
internal Matrix3D GetProjectionMatrix(double aspectRatio, double zn, double zf)
{
double w = Width;
double h = w/aspectRatio;
double m22 = 1/(zn-zf);
double m32 = zn*m22;
return new Matrix3D(
2/w, 0, 0, 0,
0, 2/h, 0, 0,
0, 0, m22, 0,
0, 0, m32, 1);
}
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;
double zn = NearPlaneDistance;
double zf = FarPlaneDistance;
double width = Width;
//
// 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);
double aspectRatio = M3DUtil.GetAspectRatio(viewSize);
double w = width;
double h = w/aspectRatio;
// Direction is always perpendicular to the viewing surface.
Vector3D direction = new Vector3D(0, 0, -1);
// Apply the inverse of the view matrix to our ray.
Matrix3D viewMatrix = CreateViewMatrix(Transform, ref position, ref lookDirection, ref upDirection);
Matrix3D invView = viewMatrix;
invView.Invert();
// We construct our ray such that the origin resides on the near
// plane. If our near plane is too far from our the bounding box
// of our scene then the results will be inaccurate. (e.g.,
// OrthographicCameras permit negative near planes, so the near
// plane could be at -Inf.)
//
// However, it is permissable to move the near plane nearer to
// the scene bounds without changing what the ray intersects.
// If the near plane is sufficiently far from the scene bounds
// we make this adjustment below to increase precision.
Rect3D transformedBoundingBox =
M3DUtil.ComputeTransformedAxisAlignedBoundingBox(
ref boundingRect,
ref viewMatrix);
// DANGER: The NearPlaneDistance property is specified as a
// distance from the camera position along the
// LookDirection with (Near < Far).
//
// However, when we transform our scene bounds so that
// the camera is aligned with the negative Z-axis the
// relationship inverts (Near > Far) as illustrated
// below:
//
// NearPlane Y FarPlane
// | ^ |
// | | |
// | | (rect.Z + rect.SizeZ) |
// | | o____ |
// | | | | |
// | | | | |
// | | ____o |
// | | (rect.Z) |
// | Camera -> |
// +Z <----------+----------------------------> -Z
// | 0 |
//
// It is surprising, but its the "far" side of the
// transformed scene bounds that determines the near
// plane distance.
double zn2 = - AddEpsilon(transformedBoundingBox.Z+transformedBoundingBox.SizeZ);
if (zn2 > zn)
{
//
// Our near plane is far from our children. Construct a new
// near plane that's closer. Note that this will modify our
// distance computations, so we have to be sure to adjust our
// distances appropriately.
//
distanceAdjustment = zn2 - zn;
zn = zn2;
}
else
{
//
// Our near plane is either close to or in front of our
// children, so let's keep it -- no distance adjustment needed.
//
distanceAdjustment = 0.0;
}
// Our origin is the point normalized to the front of our viewing volume.
// To find our origin's x/y we just need to scale the normalize point by our
// width/height. In camera space we are looking down the negative Z axis
// so we just set Z to be -zn which puts us on the projection plane
// (Windows OS #1005064).
Point3D origin = new Point3D(np.X*(w/2), np.Y*(h/2), -zn);
invView.MultiplyPoint(ref origin);
invView.MultiplyVector(ref direction);
RayHitTestParameters rayParameters = new RayHitTestParameters(origin, direction);
//
// 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 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 =
viewMatrix *
projectionMatrix *
viewportMatrix;
return rayParameters;
}
#endregion Internal Methods
//-----------------------------------------------------
//
// Private Methods
//
//-----------------------------------------------------
private double AddEpsilon(double x)
{
//
// x is either close to 0 or not. If it's close to 0, then 1.0 is
// sufficiently large to act as an epsilon. If it's not, then
// 0.1*Math.Abs(x) sufficiently large.
//
return x + 0.1*Math.Abs(x) + 1.0;
}
//-----------------------------------------------------
//
// 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 an orthagraphic projection camera.
///
public partial class OrthographicCamera : ProjectionCamera
{
//-----------------------------------------------------
//
// Constructors
//
//-----------------------------------------------------
///
public OrthographicCamera() {}
///
public OrthographicCamera(Point3D position, Vector3D lookDirection, Vector3D upDirection, double width)
{
Position = position;
LookDirection = lookDirection;
UpDirection = upDirection;
Width = width;
}
//------------------------------------------------------
//
// Public Methods
//
//-----------------------------------------------------
//------------------------------------------------------
//
// Public Properties
//
//------------------------------------------------------
//-----------------------------------------------------
//
// Internal Methods
//
//------------------------------------------------------
#region Internal Methods
internal Matrix3D GetProjectionMatrix(double aspectRatio, double zn, double zf)
{
double w = Width;
double h = w/aspectRatio;
double m22 = 1/(zn-zf);
double m32 = zn*m22;
return new Matrix3D(
2/w, 0, 0, 0,
0, 2/h, 0, 0,
0, 0, m22, 0,
0, 0, m32, 1);
}
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;
double zn = NearPlaneDistance;
double zf = FarPlaneDistance;
double width = Width;
//
// 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);
double aspectRatio = M3DUtil.GetAspectRatio(viewSize);
double w = width;
double h = w/aspectRatio;
// Direction is always perpendicular to the viewing surface.
Vector3D direction = new Vector3D(0, 0, -1);
// Apply the inverse of the view matrix to our ray.
Matrix3D viewMatrix = CreateViewMatrix(Transform, ref position, ref lookDirection, ref upDirection);
Matrix3D invView = viewMatrix;
invView.Invert();
// We construct our ray such that the origin resides on the near
// plane. If our near plane is too far from our the bounding box
// of our scene then the results will be inaccurate. (e.g.,
// OrthographicCameras permit negative near planes, so the near
// plane could be at -Inf.)
//
// However, it is permissable to move the near plane nearer to
// the scene bounds without changing what the ray intersects.
// If the near plane is sufficiently far from the scene bounds
// we make this adjustment below to increase precision.
Rect3D transformedBoundingBox =
M3DUtil.ComputeTransformedAxisAlignedBoundingBox(
ref boundingRect,
ref viewMatrix);
// DANGER: The NearPlaneDistance property is specified as a
// distance from the camera position along the
// LookDirection with (Near < Far).
//
// However, when we transform our scene bounds so that
// the camera is aligned with the negative Z-axis the
// relationship inverts (Near > Far) as illustrated
// below:
//
// NearPlane Y FarPlane
// | ^ |
// | | |
// | | (rect.Z + rect.SizeZ) |
// | | o____ |
// | | | | |
// | | | | |
// | | ____o |
// | | (rect.Z) |
// | Camera -> |
// +Z <----------+----------------------------> -Z
// | 0 |
//
// It is surprising, but its the "far" side of the
// transformed scene bounds that determines the near
// plane distance.
double zn2 = - AddEpsilon(transformedBoundingBox.Z+transformedBoundingBox.SizeZ);
if (zn2 > zn)
{
//
// Our near plane is far from our children. Construct a new
// near plane that's closer. Note that this will modify our
// distance computations, so we have to be sure to adjust our
// distances appropriately.
//
distanceAdjustment = zn2 - zn;
zn = zn2;
}
else
{
//
// Our near plane is either close to or in front of our
// children, so let's keep it -- no distance adjustment needed.
//
distanceAdjustment = 0.0;
}
// Our origin is the point normalized to the front of our viewing volume.
// To find our origin's x/y we just need to scale the normalize point by our
// width/height. In camera space we are looking down the negative Z axis
// so we just set Z to be -zn which puts us on the projection plane
// (Windows OS #1005064).
Point3D origin = new Point3D(np.X*(w/2), np.Y*(h/2), -zn);
invView.MultiplyPoint(ref origin);
invView.MultiplyVector(ref direction);
RayHitTestParameters rayParameters = new RayHitTestParameters(origin, direction);
//
// 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 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 =
viewMatrix *
projectionMatrix *
viewportMatrix;
return rayParameters;
}
#endregion Internal Methods
//-----------------------------------------------------
//
// Private Methods
//
//-----------------------------------------------------
private double AddEpsilon(double x)
{
//
// x is either close to 0 or not. If it's close to 0, then 1.0 is
// sufficiently large to act as an epsilon. If it's not, then
// 0.1*Math.Abs(x) sufficiently large.
//
return x + 0.1*Math.Abs(x) + 1.0;
}
//-----------------------------------------------------
//
// 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
- TransactionChannelFaultConverter.cs
- ValueProviderWrapper.cs
- EntityViewContainer.cs
- RawTextInputReport.cs
- ScriptResourceAttribute.cs
- FixedSOMFixedBlock.cs
- WebMessageEncoderFactory.cs
- GeometryHitTestParameters.cs
- HttpResponse.cs
- Gdiplus.cs
- XmlArrayAttribute.cs
- ImmutableObjectAttribute.cs
- CodeCompileUnit.cs
- AppearanceEditorPart.cs
- MetadataItem_Static.cs
- WebAdminConfigurationHelper.cs
- AddInPipelineAttributes.cs
- HyperLinkDesigner.cs
- StringAnimationBase.cs
- HttpDebugHandler.cs
- WebPartConnectionsConnectVerb.cs
- FullTextState.cs
- MessageEventSubscriptionService.cs
- Animatable.cs
- Inline.cs
- TextEditorTyping.cs
- RegexCapture.cs
- WhileDesigner.cs
- PrimitiveXmlSerializers.cs
- HyperLinkColumn.cs
- SocketAddress.cs
- ToolboxComponentsCreatingEventArgs.cs
- OleDbConnectionInternal.cs
- SchemaHelper.cs
- DoubleAnimation.cs
- Label.cs
- SqlBuilder.cs
- FileDialogCustomPlace.cs
- Block.cs
- ProfileSettings.cs
- HandlerBase.cs
- TransformCryptoHandle.cs
- _ReceiveMessageOverlappedAsyncResult.cs
- ObjectListGeneralPage.cs
- ObjectParameter.cs
- DesigntimeLicenseContext.cs
- CalendarAutomationPeer.cs
- NavigationProgressEventArgs.cs
- ModifierKeysValueSerializer.cs
- MediaScriptCommandRoutedEventArgs.cs
- diagnosticsswitches.cs
- RawStylusInput.cs
- DataGridViewControlCollection.cs
- IndexExpression.cs
- NativeMethods.cs
- CornerRadiusConverter.cs
- RNGCryptoServiceProvider.cs
- AppendHelper.cs
- EdmPropertyAttribute.cs
- CacheMemory.cs
- CfgArc.cs
- Timer.cs
- Mutex.cs
- FixedSOMGroup.cs
- ReaderWriterLockWrapper.cs
- Interlocked.cs
- SeekStoryboard.cs
- NativeCppClassAttribute.cs
- ContentHostHelper.cs
- DesignerVerbCollection.cs
- StorageMappingItemLoader.cs
- UTF7Encoding.cs
- CodeDomSerializerBase.cs
- AnnotationDocumentPaginator.cs
- GeneralTransform.cs
- Attributes.cs
- XPathDocument.cs
- RemotingServices.cs
- HttpConfigurationSystem.cs
- XmlLinkedNode.cs
- BaseTemplateCodeDomTreeGenerator.cs
- CheckBoxAutomationPeer.cs
- UpdateException.cs
- DynamicQueryStringParameter.cs
- SortedList.cs
- EncryptedPackageFilter.cs
- NumericUpDownAcceleration.cs
- Brushes.cs
- HScrollBar.cs
- ButtonChrome.cs
- ActivityExecutor.cs
- SmtpFailedRecipientsException.cs
- WindowsSidIdentity.cs
- Token.cs
- DiffuseMaterial.cs
- MailDefinition.cs
- GroupStyle.cs
- DiscoveryReference.cs
- storepermissionattribute.cs
- ProfileSettings.cs