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
- TextLineResult.cs
- DynamicILGenerator.cs
- TableSectionStyle.cs
- DynamicPropertyReader.cs
- TemplateXamlTreeBuilder.cs
- DbTransaction.cs
- IgnoreDeviceFilterElement.cs
- DialogWindow.cs
- InertiaRotationBehavior.cs
- Attributes.cs
- XmlSubtreeReader.cs
- BitArray.cs
- KnownTypes.cs
- DecimalConstantAttribute.cs
- RuleConditionDialog.Designer.cs
- RotateTransform.cs
- MiniParameterInfo.cs
- SamlAuthorityBinding.cs
- EnumerableCollectionView.cs
- Variant.cs
- UpdateCommand.cs
- SchemaObjectWriter.cs
- DateTimeValueSerializerContext.cs
- BoolExpr.cs
- QilTargetType.cs
- RectAnimationBase.cs
- SByte.cs
- SeekStoryboard.cs
- filewebresponse.cs
- OneOfTypeConst.cs
- SQLGuid.cs
- DrawingImage.cs
- WebBrowserHelper.cs
- RoleManagerEventArgs.cs
- CrossAppDomainChannel.cs
- XPathScanner.cs
- RepeaterItem.cs
- CircleHotSpot.cs
- JavaScriptObjectDeserializer.cs
- GeometryGroup.cs
- CommunicationObjectAbortedException.cs
- DateRangeEvent.cs
- TypeCollectionPropertyEditor.cs
- IdentityModelDictionary.cs
- AuthStoreRoleProvider.cs
- WeakRefEnumerator.cs
- IPEndPoint.cs
- ICspAsymmetricAlgorithm.cs
- SystemThemeKey.cs
- TemplateBuilder.cs
- SHA1Managed.cs
- LogicalExpr.cs
- HyperLinkColumn.cs
- ClientSideQueueItem.cs
- MailAddressCollection.cs
- SessionStateSection.cs
- ViewUtilities.cs
- DataSysAttribute.cs
- PrintPreviewControl.cs
- DispatcherProcessingDisabled.cs
- CookieParameter.cs
- CodeAttributeDeclaration.cs
- ToolboxItemAttribute.cs
- URI.cs
- SmiTypedGetterSetter.cs
- ThousandthOfEmRealDoubles.cs
- HiddenFieldPageStatePersister.cs
- UrlAuthFailedErrorFormatter.cs
- Html32TextWriter.cs
- XmlUtf8RawTextWriter.cs
- Flowchart.cs
- ScrollChrome.cs
- LoginUtil.cs
- EdmRelationshipRoleAttribute.cs
- TypeElement.cs
- DataGridCellInfo.cs
- ErrorEventArgs.cs
- DataGridViewTopRowAccessibleObject.cs
- PeerChannelListener.cs
- DelayLoadType.cs
- FilterableAttribute.cs
- CodeExpressionStatement.cs
- Model3D.cs
- MetadataItem_Static.cs
- RemotingServices.cs
- ServiceBuildProvider.cs
- Style.cs
- SymLanguageVendor.cs
- ComponentRenameEvent.cs
- Trigger.cs
- ConnectivityStatus.cs
- MenuAdapter.cs
- SqlConnectionPoolProviderInfo.cs
- StatusBarItem.cs
- RecordsAffectedEventArgs.cs
- AddInIpcChannel.cs
- SiteOfOriginContainer.cs
- XpsFontSerializationService.cs
- XsltInput.cs
- PingOptions.cs