Code:
/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Core / System / Windows / Media3D / Viewport3DVisual.cs / 3 / Viewport3DVisual.cs
//----------------------------------------------------------------------------
//
//
// Copyright (C) Microsoft Corporation. All rights reserved.
//
//
//---------------------------------------------------------------------------
using MS.Internal;
using MS.Internal.Media;
using MS.Internal.Media3D;
using System;
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Diagnostics;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Composition;
using System.Windows.Markup;
using System.Windows.Media.Effects;
using MS.Internal.PresentationCore;
using SR=MS.Internal.PresentationCore.SR;
using SRID=MS.Internal.PresentationCore.SRID;
namespace System.Windows.Media.Media3D
{
///
/// The Viewport3DVisual provides the Camera and viewport Rect
/// required to project the Visual3Ds into 2D. The Viewport3DVisual
/// is the bridge between 2D visuals and 3D.
///
[ContentProperty("Children")]
public sealed class Viewport3DVisual : Visual, DUCE.IResource, IVisual3DContainer
{
//-----------------------------------------------------
//
// Constructors
//
//-----------------------------------------------------
///
/// Default constructor
///
public Viewport3DVisual() : base(DUCE.ResourceType.TYPE_VIEWPORT3DVISUAL)
{
_children = new Visual3DCollection(this);
}
//------------------------------------------------------
//
// Public Methods
//
//-----------------------------------------------------
#region Public Methods
// ------------------------------------------------------------------------------------------
// Publicly re-exposed VisualTreeHelper interfaces.
//
// Note that we do not want to expose the Children property on Viewport3DVisual
// since the Viewport3DVisual provides its own set of Visual3D children.
// ------------------------------------------------------------------------------------------
///
/// Re-exposes the Visual base class's corresponding VisualTreeHelper implementation as public method.
///
public DependencyObject Parent
{
get { return base.VisualParent; }
}
///
/// Re-exposes the Visual base class's corresponding VisualTreeHelper implementation as public method.
///
public Geometry Clip
{
get { return base.VisualClip; }
set { base.VisualClip = value; }
}
///
/// Re-exposes the Visual base class's corresponding VisualTreeHelper implementation as public method.
///
public double Opacity
{
get { return base.VisualOpacity; }
set { base.VisualOpacity = value; }
}
///
/// Re-exposes the Visual base class's corresponding VisualTreeHelper implementation as public method.
///
public Brush OpacityMask
{
get { return base.VisualOpacityMask; }
set { base.VisualOpacityMask = value; }
}
///
/// Re-exposes the Visual base class's corresponding VisualTreeHelper implementation as public method.
///
public BitmapEffect BitmapEffect
{
get { return base.VisualBitmapEffect; }
set { base.VisualBitmapEffect = value; }
}
///
/// Re-exposes the Visual base class's corresponding VisualTreeHelper implementation as public method.
///
public BitmapEffectInput BitmapEffectInput
{
get { return base.VisualBitmapEffectInput; }
set { base.VisualBitmapEffectInput = value; }
}
///
/// Re-exposes the Visual base class's corresponding VisualTreeHelper implementation as public method.
///
new public HitTestResult HitTest(Point point)
{
return base.HitTest(point);
}
///
/// Re-exposes the Visual base class's corresponding VisualTreeHelper implementation as public method.
///
new public void HitTest(HitTestFilterCallback filterCallback, HitTestResultCallback resultCallback, HitTestParameters hitTestParameters)
{
base.HitTest(filterCallback, resultCallback, hitTestParameters);
}
///
/// VisualContentBounds returns the bounding box for the contents of this Visual.
///
public Rect ContentBounds
{
get
{
return base.VisualContentBounds;
}
}
///
/// Gets or sets the Transform property.
///
public Transform Transform
{
get
{
return base.VisualTransform;
}
set
{
base.VisualTransform = value;
}
}
///
/// Gets or sets the Offset property.
///
public Vector Offset
{
get
{
return base.VisualOffset;
}
set
{
base.VisualOffset = value;
}
}
///
/// DescendantBounds returns the union of all of the content bounding
/// boxes for all of the descendants of the current visual, but not including
/// the contents of the current visual.
///
public Rect DescendantBounds
{
get
{
return base.VisualDescendantBounds;
}
}
#endregion Public Methods
//-----------------------------------------------------
//
// Public Properties
//
//------------------------------------------------------
#region Public Properties
///
/// DependencyProperty which backs the ModelVisual3D.Camera property.
///
public static readonly DependencyProperty CameraProperty =
DependencyProperty.Register(
"Camera",
/* propertyType = */ typeof(Camera),
/* ownerType = */ typeof(Viewport3DVisual),
new PropertyMetadata(
FreezableOperations.GetAsFrozen(new PerspectiveCamera()),
CameraPropertyChanged),
(ValidateValueCallback) delegate { return MediaContext.CurrentMediaContext.WriteAccessEnabled; });
private static void CameraPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Viewport3DVisual owner = ((Viewport3DVisual) d);
if (!e.IsASubPropertyChange)
{
if (e.OldValue != null)
{
owner.DisconnectAttachedResource(
VisualProxyFlags.Viewport3DVisual_IsCameraDirty,
((DUCE.IResource) e.OldValue));
}
owner.SetFlagsOnAllChannels(true, VisualProxyFlags.Viewport3DVisual_IsCameraDirty | VisualProxyFlags.IsContentDirty);
}
owner.ContentsChanged(/* sender = */ owner, EventArgs.Empty);
}
///
/// Camera for this Visual3D.
///
public Camera Camera
{
get
{
return (Camera) GetValue(CameraProperty);
}
set
{
SetValue(CameraProperty, value);
}
}
///
/// DependencyProperty which backs the ModelVisual3D.Viewport property.
///
public static readonly DependencyProperty ViewportProperty =
DependencyProperty.Register(
"Viewport",
/* propertyType = */ typeof(Rect),
/* ownerType = */ typeof(Viewport3DVisual),
new PropertyMetadata(Rect.Empty, ViewportPropertyChanged),
(ValidateValueCallback) delegate { return MediaContext.CurrentMediaContext.WriteAccessEnabled; });
private static void ViewportPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
Viewport3DVisual owner = ((Viewport3DVisual) d);
Debug.Assert(!e.IsASubPropertyChange,
"How are we receiving sub property changes from a struct?");
owner.SetFlagsOnAllChannels(true, VisualProxyFlags.Viewport3DVisual_IsViewportDirty | VisualProxyFlags.IsContentDirty);
owner.ContentsChanged(/* sender = */ owner, EventArgs.Empty);
}
///
/// Viewport for this Visual3D.
///
public Rect Viewport
{
get
{
return (Rect) GetValue(ViewportProperty);
}
set
{
SetValue(ViewportProperty, value);
}
}
///
/// The 3D children to be projected by this Viewport3DVisual.
///
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public Visual3DCollection Children
{
get
{
return _children;
}
}
#endregion Public Properties
//-----------------------------------------------------
//
// Public Events
//
//-----------------------------------------------------
//-----------------------------------------------------
//
// Protected Methods
//
//------------------------------------------------------
//-----------------------------------------------------
//
// Internal Methods
//
//------------------------------------------------------
#region Internal Methods
// CS0536: Intreface implementation must be public or explicit so we re-expose
// the internal methods as an explicit implementation of an internal interface.
void IVisual3DContainer.VerifyAPIReadOnly() { this.VerifyAPIReadOnly(); }
void IVisual3DContainer.VerifyAPIReadOnly(DependencyObject other) { this.VerifyAPIReadOnly(other); }
void IVisual3DContainer.VerifyAPIReadWrite() { this.VerifyAPIReadWrite(); }
void IVisual3DContainer.VerifyAPIReadWrite(DependencyObject other) { this.VerifyAPIReadWrite(other); }
// NOTE: The code here is highly similar to AddChildCore in ModelVisual3D,
// but slightly different because the parent is 2D here.
void IVisual3DContainer.AddChild(Visual3D child)
{
// It is invalid to modify the children collection that we
// might be iterating during a property invalidation tree walk.
if (IsVisualChildrenIterationInProgress)
{
throw new InvalidOperationException(SR.Get(SRID.CannotModifyVisualChildrenDuringTreeWalk));
}
Debug.Assert(child != null);
Debug.Assert(child.InternalVisualParent == null);
child.SetParent(this);
// set the inheritance context so databinding, etc... work
if (_inheritanceContextForChildren != null)
{
_inheritanceContextForChildren.ProvideSelfAsInheritanceContext(child, null);
}
SetFlagsOnAllChannels(true, VisualProxyFlags.IsContentDirty);
// The child already might be dirty. Hence we need to propagate dirty information
// from the parent and from the child.
Visual.PropagateFlags(
this,
VisualFlags.IsSubtreeDirtyForPrecompute | VisualFlags.NodeNeedsBitmapEffectUpdate,
VisualProxyFlags.IsSubtreeDirtyForRender);
Visual3D.PropagateFlags(
child,
VisualFlags.IsSubtreeDirtyForPrecompute,
VisualProxyFlags.IsSubtreeDirtyForRender);
//
// Fire notifications
OnVisualChildrenChanged(child, /* visualRemoved = */ null);
child.FireOnVisualParentChanged(null);
}
// NOTE: The code here is highly similar to RemoveChildCore in ModelVisual3D,
// but slightly different because the parent is 2D here.
void IVisual3DContainer.RemoveChild(Visual3D child)
{
int index = child.ParentIndex;
// It is invalid to modify the children collection that we
// might be iterating during a property invalidation tree walk.
if (IsVisualChildrenIterationInProgress)
{
throw new InvalidOperationException(SR.Get(SRID.CannotModifyVisualChildrenDuringTreeWalk));
}
Debug.Assert(child != null);
Debug.Assert(child.InternalVisualParent == this);
child.SetParent(/* newParent = */ (Visual) null); // CS0121: Call is ambigious without casting null to Visual.
// remove the inheritance context
if (_inheritanceContextForChildren != null)
{
_inheritanceContextForChildren.RemoveSelfAsInheritanceContext(child, null);
}
//
// Remove the child on all channels this visual is marshalled to.
//
for (int i = 0, limit = _proxy3D.Count; i < limit; i++)
{
DUCE.Channel channel = _proxy3D.GetChannel(i);
if (child.CheckFlagsAnd(channel, VisualProxyFlags.IsConnectedToParent))
{
channel.AddToRemoveAndReleaseQueue(
this,
child);
child.SetFlags(channel, false, VisualProxyFlags.IsConnectedToParent);
}
}
SetFlagsOnAllChannels(true, VisualProxyFlags.IsContentDirty);
//
// Force a full precompute and render pass for this visual.
//
Visual.PropagateFlags(
this,
VisualFlags.IsSubtreeDirtyForPrecompute | VisualFlags.NodeNeedsBitmapEffectUpdate,
VisualProxyFlags.IsSubtreeDirtyForRender);
//
child.FireOnVisualParentChanged(this);
OnVisualChildrenChanged(/* visualAdded = */ null , child);
}
///
/// Gets the number of Visual3D children that the IVisual3DContainer
/// contains.
///
int IVisual3DContainer.GetChildrenCount()
{
return InternalVisual2DOr3DChildrenCount;
}
///
/// Gets the index children of the IVisual3DContainer
///
Visual3D IVisual3DContainer.GetChild(int index)
{
return (Visual3D)InternalGet2DOr3DVisualChild(index);
}
///
/// Returns the number of children of this object (in most cases this will be
/// the number of Visuals, but it some cases, Viewport3DVisual for instance,
/// this is the number of Visual3Ds).
///
/// Used only by VisualTreeHelper.
///
internal override int InternalVisual2DOr3DChildrenCount
{
get
{
return Children.Count;
}
}
///
/// Used only by VisualTreeHelper.
///
/// Returns the child at index "index" (in most cases this will be
/// a Visual, but it some cases, Viewport3DVisual, for instance,
/// this is a Visual3D).
///
internal override DependencyObject InternalGet2DOr3DVisualChild(int index)
{
return Children[index];
}
internal override HitTestResultBehavior HitTestPointInternal(
HitTestFilterCallback filterCallback,
HitTestResultCallback resultCallback,
PointHitTestParameters hitTestParameters)
{
if (_children.Count != 0)
{
double distanceAdjustment;
RayHitTestParameters rayParams =
Camera.RayFromViewportPoint(
hitTestParameters.HitPoint,
Viewport.Size,
BBoxSubgraph,
out distanceAdjustment);
HitTestResultBehavior result = Visual3D.HitTestChildren(filterCallback, rayParams, this);
return rayParams.RaiseCallback(resultCallback, filterCallback, result, distanceAdjustment);
}
return HitTestResultBehavior.Continue;
}
///
/// Viewport3DVisual does not yet support Geometry hit testing.
///
protected override GeometryHitTestResult HitTestCore(GeometryHitTestParameters hitTestParameters)
{
throw new NotSupportedException(SR.Get(SRID.HitTest_Invalid, typeof(GeometryHitTestParameters).Name, this.GetType().Name));
}
internal Point WorldToViewport(Point4D point)
{
double aspectRatio = M3DUtil.GetAspectRatio(Viewport.Size);
Camera camera = Camera;
if (camera != null)
{
Matrix3D viewProjMatrix = camera.GetViewMatrix() * camera.GetProjectionMatrix(aspectRatio);
point *= viewProjMatrix;
Point point2D = new Point(point.X/point.W, point.Y/point.W);
point2D *= M3DUtil.GetHomogeneousToViewportTransform(Viewport);
return point2D;
}
else
{
return new Point(0,0);
}
}
///
/// Derived classes return the hit-test bounding box from the
/// GetHitTestBounds virtual. Visual uses the bounds to optimize
/// hit-testing.
///
internal override Rect GetHitTestBounds()
{
return CalculateSubgraphBoundsInnerSpace();
}
internal override Rect CalculateSubgraphBoundsInnerSpace(bool renderBounds)
{
Camera camera = Camera;
if (camera == null)
{
return Rect.Empty;
}
//
// Cache the 3D bounding box for future use. Here we are relying on
// the fact that this method is called by PrecomputeContent(),
// which is called prior to all usages of _bboxChildrenSubgraph3D.
//
_bboxChildrenSubgraph3D = ComputeSubgraphBounds3D();
if (_bboxChildrenSubgraph3D.IsEmpty)
{
// Attempting to project empty bounds will result in NaNs which
// which will ruin descendant bounds for the 2D tree. We handle
// this explicitly and early exit with the correct answer.
return Rect.Empty;
}
Rect viewport = Viewport;
// Common Case: Viewport3DVisual in a collasped UIElement.
if (viewport.IsEmpty)
{
// Creating a 3D homogenous space to 2D viewport space transform
// with an empty rectangle will result in NaNs which ruin the
// descendant bounds for the 2D tree. We handle this explicitly
// and early exit with the correct answer.
//
// (See also Windows OS Bugs #1637618)
return Rect.Empty;
}
double aspectRatio = M3DUtil.GetAspectRatio(viewport.Size);
Matrix3D viewProjMatrix = camera.GetViewMatrix() * camera.GetProjectionMatrix(aspectRatio);
Rect projectedBounds2D = MILUtilities.ProjectBounds(ref viewProjMatrix, ref _bboxChildrenSubgraph3D);
Matrix homoToLocal = M3DUtil.GetHomogeneousToViewportTransform(viewport);
MatrixUtil.TransformRect(ref projectedBounds2D, ref homoToLocal);
return projectedBounds2D;
}
//
// NOTE: Must only be called after PrecomputeContent().
//
private Rect3D BBoxSubgraph
{
get
{
Debug_VerifyCachedSubgraphBounds();
return _bboxChildrenSubgraph3D;
}
}
internal Rect3D ComputeSubgraphBounds3D()
{
Rect3D bboxChildrenSubgraph3D = Rect3D.Empty;
for (int i = 0, count = _children.InternalCount; i < count; i++)
{
Visual3D child = _children.InternalGetItem(i);
bboxChildrenSubgraph3D.Union(child.CalculateSubgraphBoundsOuterSpace());
}
return bboxChildrenSubgraph3D;
}
[Conditional("DEBUG")]
private void Debug_VerifyCachedSubgraphBounds()
{
Rect3D currentBounds = Rect3D.Empty;
currentBounds = ComputeSubgraphBounds3D();
Rect3D cachedBounds = _bboxChildrenSubgraph3D;
// The funny boolean logic below avoids asserts when the cached
// bounds contain NaNs. (NaN != NaN)
bool boundsAreEqual =
!(cachedBounds.X < currentBounds.X || cachedBounds.X > currentBounds.X) &&
!(cachedBounds.Y < currentBounds.Y || cachedBounds.Y > currentBounds.Y) &&
!(cachedBounds.Z < currentBounds.Z || cachedBounds.Z > currentBounds.Z) &&
!(cachedBounds.SizeX < currentBounds.SizeX || cachedBounds.SizeX > currentBounds.SizeX) &&
!(cachedBounds.SizeY < currentBounds.SizeY || cachedBounds.SizeY > currentBounds.SizeY) &&
!(cachedBounds.SizeZ < currentBounds.SizeZ || cachedBounds.SizeZ > currentBounds.SizeZ);
if (!boundsAreEqual)
{
Debug.Fail("Cached bbox subgraph is incorrect!");
}
}
internal override DUCE.ResourceHandle AddRefOnChannelCore(DUCE.Channel channel)
{
DUCE.ResourceHandle handle =
base.AddRefOnChannelCore(channel);
bool created = _proxy3D.CreateOrAddRefOnChannel(channel, DUCE.ResourceType.TYPE_VISUAL3D);
Debug.Assert(
_proxy.Count == _proxy3D.Count,
"Viewport has been marshalled to a different number of channels than the 3D content.");
// If we are creating the Viewport3DVisual/Visual3D for the first
// time on this channel we need to connect the 3D root.
if (created)
{
DUCE.Viewport3DVisualNode.Set3DChild(
handle,
_proxy3D.GetHandle(channel),
channel);
}
return handle;
}
internal override void ReleaseOnChannelCore(DUCE.Channel channel)
{
Debug.Assert(
_proxy.Count == _proxy3D.Count,
"Viewport has been marshalled to a different number of channels than the 3D content.");
base.ReleaseOnChannelCore(channel);
_proxy3D.ReleaseOnChannel(channel);
}
int DUCE.IResource.GetChannelCount()
{
return _proxy.Count;
}
DUCE.Channel DUCE.IResource.GetChannel(int index)
{
return _proxy.GetChannel(index);
}
///
/// Precompute pass.
///
internal override void PrecomputeContent()
{
base.PrecomputeContent();
// If any of our children root a 3D subtree which uses realization
// caches we need to set NodeUsesRealizationCaches on ourselves.
//
// NOTE: There is no 2D content on Visual so base.PrecomputeContent()
// does not initialize this flag. We start with false.
bool subTreeUsesRealizationCaches = false;
if (_children != null)
{
for (int i = 0, count = _children.InternalCount; i < count; i++)
{
Visual3D child = _children.InternalGetItem(i);
if (child != null)
{
// This merely tells the Visual3Ds to update their bounds
// caches if necessary. Later on we'll get the cached bounds
// from calling Visual3D.CalculateSubgraphBounds
Rect3D bboxSubgraphChildIgnored;
child.PrecomputeRecursive(out bboxSubgraphChildIgnored);
subTreeUsesRealizationCaches |=
child.CheckFlagsAnd(VisualFlags.NodeInSubtreeUsesRealizationCaches);
}
}
}
// NOTE: We set NodeUseRealizationCaches rather than
// NodeInSubtreeUsesRealizationCaches. This is because we
// use UpdateRealizations() on the Viewport3DVisual to bridge
// the realization walk into the Visual3D tree.
SetFlags(subTreeUsesRealizationCaches, VisualFlags.NodeUsesRealizationCaches);
//
// If realizations are used in the subtree, they could be glyphs
// which may induce multiple pathness.
//
SetFlags(subTreeUsesRealizationCaches, VisualFlags.NodeOrDescendantIntroducesGraphness);
}
internal override void RenderContent(RenderContext ctx, bool isOnChannel)
{
DUCE.Channel channel = ctx.Channel;
//
// At this point, the visual has to be marshalled. Force
// marshalling of the camera and viewport in case we have
// just created a new visual resource.
//
Debug.Assert(IsOnChannel(channel));
VisualProxyFlags flags = _proxy.GetFlags(channel);
//
// Make sure the camera resource is being marshalled properly.
//
if ((flags & VisualProxyFlags.Viewport3DVisual_IsCameraDirty) != 0)
{
Camera camera = Camera;
if (camera != null)
{
DUCE.Viewport3DVisualNode.SetCamera(
((DUCE.IResource)this).GetHandle(channel),
((DUCE.IResource)camera).AddRefOnChannel(channel),
channel);
}
else if (isOnChannel) /* camera == null */
{
DUCE.Viewport3DVisualNode.SetCamera(
((DUCE.IResource)this).GetHandle(channel),
DUCE.ResourceHandle.Null,
channel);
}
SetFlags(channel, false, VisualProxyFlags.Viewport3DVisual_IsCameraDirty);
}
//
// Set the viewport if it's dirty.
//
if ((flags & VisualProxyFlags.Viewport3DVisual_IsViewportDirty) != 0)
{
DUCE.Viewport3DVisualNode.SetViewport(
((DUCE.IResource)this).GetHandle(channel),
Viewport,
channel);
SetFlags(channel, false, VisualProxyFlags.Viewport3DVisual_IsViewportDirty);
}
//we only want to recurse in the children if the visual does not have a bitmap effect
//or we are in the BitmapVisualManager render pass
// Visit children of this node ------------------------------------------------------------------------
Debug.Assert(!CheckFlagsAnd(channel, VisualProxyFlags.IsContentNodeConnected),
"Only HostVisuals are expected to have a content node.");
if (_children != null)
{
for (uint i = 0; i < _children.InternalCount; i++)
{
Visual3D child = _children.InternalGetItem((int) i);
if (child != null)
{
if (child.CheckFlagsAnd(channel, VisualProxyFlags.IsSubtreeDirtyForRender) || // or the visual is dirty
!(child.IsOnChannel(channel))) // or the child has not been marshalled yet.
{
child.RenderRecursive(ctx);
}
if (child.IsOnChannel(channel))
{
if (!child.CheckFlagsAnd(channel, VisualProxyFlags.IsConnectedToParent))
{
DUCE.Visual3DNode.InsertChildAt(
_proxy3D.GetHandle(channel),
((DUCE.IResource)child).GetHandle(channel),
/* iPosition = */ i,
channel);
child.SetFlags(channel, true, VisualProxyFlags.IsConnectedToParent);
}
}
}
}
}
}
///
/// Override this function in derived classes to release unmanaged resources during Dispose
/// and during removal of a subtree.
///
internal override void FreeContent(DUCE.Channel channel)
{
Debug.Assert(IsOnChannel(channel));
Camera camera = Camera;
if (camera != null)
{
if (!CheckFlagsAnd(channel, VisualProxyFlags.Viewport3DVisual_IsCameraDirty))
{
((DUCE.IResource)camera).ReleaseOnChannel(channel);
SetFlagsOnAllChannels(true, VisualProxyFlags.Viewport3DVisual_IsCameraDirty);
}
}
if (_children != null)
{
for (int i = 0; i < _children.InternalCount; i++)
{
Visual3D visual = _children.InternalGetItem(i);
((DUCE.IResource)visual).ReleaseOnChannel(channel);
}
}
SetFlagsOnAllChannels(true, VisualProxyFlags.IsContentDirty);
base.FreeContent(channel);
}
///
/// Called by the base class to update realization caches.
/// Updates the realization cache on the scene3d.
///
internal override void UpdateRealizations(RealizationContext ctx)
{
Debug.Assert(CheckFlagsAnd(VisualFlags.NodeUsesRealizationCaches));
Camera camera = Camera;
if (camera != null)
{
// Do not call the base class here because that would kick of an
// unnecessary realization pass over the render data content of this
// Visual.
Matrix3DStack stack3D = ctx.Transform3DStack;
// PushWithoutAccumulating to enable nested usage of the Transform3DStack.
stack3D.PushWithoutAccumulating(M3DUtil.GetWorldToViewportTransform3D(camera, Viewport));
bool wasIn3DMode = ctx.Set3DMode(true);
for (int i = 0; i < _children.InternalCount; i++)
{
Visual3D child = _children.InternalGetItem(i);
if (child.CheckFlagsAnd(VisualFlags.NodeInSubtreeUsesRealizationCaches))
{
child.UpdateRealizations(ctx);
}
}
ctx.Set3DMode(wasIn3DMode);
stack3D.Pop(); // worldToViewport.
}
}
// Notify the Viewport3DVisual that the Visual3D subtree it hosts
// has been modified.
internal void Visual3DTreeChanged()
{
// The Visual3D tree is plugged into the 2D Visual tree via the
// same extensibility point we use for "content".
SetFlagsOnAllChannels(true, VisualProxyFlags.IsContentDirty);
ContentsChanged(/* sender = */ this, EventArgs.Empty);
}
///
/// Returns the handle this visual has on the given channel.
/// Note: The 3D handle is obtained from _proxy3D.
///
DUCE.ResourceHandle DUCE.IResource.Get3DHandle(DUCE.Channel channel)
{
return _proxy3D.GetHandle(channel);
}
// Because 2D Visuals and FEs do not participate in inheritance context
// we allow this backdoor for a Viewport3D to set itself as the inheritance
// context of the Visual3DCollection it exposes as Children.
[FriendAccessAllowed]
internal void SetInheritanceContextForChildren(DependencyObject inheritanceContextForChildren)
{
_inheritanceContextForChildren = inheritanceContextForChildren;
}
#endregion Internal Methods
//-----------------------------------------------------
//
// Private Fields
//
//------------------------------------------------------
#region Private Fields
///
/// The 3D content root.
///
///
/// Important! - Not readonly because CS will silently copy
/// for self-modifying methods. (C# Spec 14.5.4)
///
private VisualProxy _proxy3D;
private Rect3D _bboxChildrenSubgraph3D;
private readonly Visual3DCollection _children;
private DependencyObject _inheritanceContextForChildren;
#endregion 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
- TreeNodeCollectionEditorDialog.cs
- ObjectDataSource.cs
- InvalidEnumArgumentException.cs
- SemanticKeyElement.cs
- RegexBoyerMoore.cs
- DataGridViewSelectedRowCollection.cs
- EventMappingSettingsCollection.cs
- ProxyHwnd.cs
- HttpModuleActionCollection.cs
- DataGridState.cs
- TextDecorationCollection.cs
- OrderedDictionary.cs
- QueryCacheKey.cs
- RadioButtonRenderer.cs
- TextDecorationCollection.cs
- LinkedResourceCollection.cs
- SmiConnection.cs
- DesignerTransactionCloseEvent.cs
- OdbcConnectionOpen.cs
- Graph.cs
- NativeMethods.cs
- SqlServices.cs
- SiblingIterators.cs
- ItemDragEvent.cs
- DataGridViewTopLeftHeaderCell.cs
- StandardTransformFactory.cs
- AppDomain.cs
- RemotingConfigParser.cs
- SourceCollection.cs
- SystemWebSectionGroup.cs
- Mappings.cs
- SerializerDescriptor.cs
- Int32RectConverter.cs
- WaitHandle.cs
- BrushConverter.cs
- EnumerableCollectionView.cs
- WebHttpBehavior.cs
- RoleManagerSection.cs
- ToolStripGrip.cs
- AuthenticationService.cs
- ColumnCollection.cs
- DispatcherEventArgs.cs
- SkinBuilder.cs
- SequenceFullException.cs
- EpmSourceTree.cs
- IconHelper.cs
- CommandBindingCollection.cs
- ObjectCloneHelper.cs
- TypeConstant.cs
- TraceListeners.cs
- ManagementObjectSearcher.cs
- HttpModuleActionCollection.cs
- XmlDataSourceView.cs
- securestring.cs
- ToolStripPanelSelectionBehavior.cs
- XmlBaseReader.cs
- VariableQuery.cs
- TempFiles.cs
- ServiceContractAttribute.cs
- figurelengthconverter.cs
- EntityDataSourceEntitySetNameItem.cs
- BoolExpressionVisitors.cs
- NamespaceImport.cs
- ResourceLoader.cs
- IndexerNameAttribute.cs
- TextPattern.cs
- XmlUnspecifiedAttribute.cs
- DataMisalignedException.cs
- GestureRecognizer.cs
- WebPartConnectionsCancelVerb.cs
- IntranetCredentialPolicy.cs
- ApplicationSettingsBase.cs
- UserControl.cs
- MultiBinding.cs
- ScaleTransform3D.cs
- Stylesheet.cs
- DataGridViewAutoSizeModeEventArgs.cs
- AppModelKnownContentFactory.cs
- HighlightOverlayGlyph.cs
- webbrowsersite.cs
- XmlHierarchicalEnumerable.cs
- HierarchicalDataBoundControl.cs
- Comparer.cs
- SequenceNumber.cs
- GradientSpreadMethodValidation.cs
- PropertyEntry.cs
- ThreadStaticAttribute.cs
- KeyValueConfigurationCollection.cs
- BaseDataBoundControlDesigner.cs
- XhtmlConformanceSection.cs
- HtmlInputButton.cs
- ServiceObjectContainer.cs
- DbConnectionPoolOptions.cs
- filewebresponse.cs
- DefaultWorkflowTransactionService.cs
- Rectangle.cs
- TypeListConverter.cs
- SoapHeaderException.cs
- SQLMembershipProvider.cs
- LineProperties.cs