/// <summary>
        /// The sort children.
        /// </summary>
        private void SortChildren()
        {
            var vp = Visual3DHelper.GetViewport3D(this);

            if (vp == null)
            {
                return;
            }

            var cam = vp.Camera as ProjectionCamera;

            if (cam == null)
            {
                return;
            }

            var cameraPos = cam.Position;
            var transform = new MatrixTransform3D(Visual3DHelper.GetTransform(this));

            IList <Visual3D> transparentChildren = new List <Visual3D>();
            IList <Visual3D> opaqueChildren      = new List <Visual3D>();

            if (this.CheckForOpaqueVisuals)
            {
                foreach (var child in this.Children)
                {
                    if (this.IsVisualTransparent(child))
                    {
                        transparentChildren.Add(child);
                    }
                    else
                    {
                        opaqueChildren.Add(child);
                    }
                }
            }
            else
            {
                transparentChildren = this.Children;
            }

            // sort the children by distance from camera (note that OrderBy is a stable sort algorithm)
            var sortedTransparentChildren =
                transparentChildren.OrderBy(item => - this.GetCameraDistance(item, cameraPos, transform)).ToList();

            this.Children.Clear();

            // add the opaque children
            foreach (var c in opaqueChildren)
            {
                this.Children.Add(c);
            }

            // add the sorted transparent children
            foreach (var c in sortedTransparentChildren)
            {
                this.Children.Add(c);
            }
        }
        /// <summary>
        /// Updates the clipping object.
        /// </summary>
        private void UpdateClipping()
        {
            var vp = Visual3DHelper.GetViewport3D(this);

            if (vp == null)
            {
                return;
            }

            this.Clipping = new CohenSutherlandClipping(10, vp.ActualWidth - 20, 10, vp.ActualHeight - 20);
        }
Exemple #3
0
        /// <summary>
        /// Invoked when an unhandled <see cref="E:System.Windows.Input.Mouse.MouseDown" /> attached event reaches an element in its route that is derived from this class. Implement this method to add class handling for this event.
        /// </summary>
        /// <param name="e">The <see cref="T:System.Windows.Input.MouseButtonEventArgs" /> that contains the event data. This event data reports details about the mouse button that was pressed and the handled state.</param>
        protected override void OnMouseDown(MouseButtonEventArgs e)
        {
            base.OnMouseDown(e);
            this.ParentViewport = Visual3DHelper.GetViewport3D(this);
            this.Camera         = this.ParentViewport.Camera as ProjectionCamera;
            var projectionCamera = this.Camera;

            if (projectionCamera != null)
            {
                this.HitPlaneNormal = projectionCamera.LookDirection;
            }

            this.CaptureMouse();
        }
        /// <summary>
        /// The sort children.
        /// </summary>
        private void SortChildren()
        {
            var vp = Visual3DHelper.GetViewport3D(this);

            if (vp == null)
            {
                return;
            }

            var cam = vp.Camera as ProjectionCamera;

            if (cam == null)
            {
                return;
            }

            var cameraPos = cam.Position;
            var transform = new MatrixTransform3D(Visual3DHelper.GetTransform(this));

            IList <Visual3D> transparentChildren = new List <Visual3D>();
            IList <Visual3D> opaqueChildren      = new List <Visual3D>();

            if (this.CheckForOpaqueVisuals)
            {
                foreach (var child in this.Children)
                {
                    if (this.IsVisualTransparent(child))
                    {
                        transparentChildren.Add(child);
                    }
                    else
                    {
                        opaqueChildren.Add(child);
                    }
                }
            }
            else
            {
                transparentChildren = this.Children;
            }

            // sort the children by distance from camera (note that OrderBy is a stable sort algorithm)
            var sortedTransparentChildren =
                transparentChildren.OrderBy(item => - this.GetCameraDistance(item, cameraPos, transform)).ToList();

            // Now that opaqueChildren and sortedTransparentChildren describe our desired ordering, we need sort the current children in the new order.
            // To optimize the efficiency of this procedure we want to change the children list as little as possible.
            // Unfortunatally the Visual3DCollection does not have a swap method and we always need to remove an item before we can add it again as
            // temporary duplicates result in exceptions in the visual tree.
            // Due to this set of considerations we use selection sort to sort the current Children. (if we could swap without removal, cycle sort might be a small improvement)

            for (int desiredIndex = 0; desiredIndex < opaqueChildren.Count; desiredIndex++)
            {
                Visual3D currentChild = opaqueChildren[desiredIndex];
                int      currentIndex = Children.IndexOf(currentChild);
                //Insert in the proper spot if not contained:
                if (currentIndex == -1)
                {
                    Children.Insert(desiredIndex, currentChild);
                    continue;
                }
                //Do nothing if it is in the correct spot;
                //The order of the opaque children does not matter as long as they are before the transparent children:
                if (currentIndex < opaqueChildren.Count)
                {
                    continue;
                }

                //remove from old spot and insert to the new correct spot:
                Children.RemoveAt(currentIndex);
                Children.Insert(desiredIndex, currentChild);
            }

            for (int desiredIndex = opaqueChildren.Count; desiredIndex < opaqueChildren.Count + sortedTransparentChildren.Count; desiredIndex++)
            {
                Visual3D currentChild = sortedTransparentChildren[desiredIndex - opaqueChildren.Count];
                int      currentIndex = Children.IndexOf(currentChild);
                //Insert in the proper spot if not contained:
                if (currentIndex == -1)
                {
                    Children.Insert(desiredIndex, currentChild);
                    continue;
                }
                //Do nothing if it is in the correct spot:
                if (currentIndex == desiredIndex)
                {
                    continue;
                }

                //remove from old spot and insert to the new correct spot:
                Children.RemoveAt(currentIndex);
                Children.Insert(desiredIndex, currentChild);
            }
        }