Exemple #1
0
        /// <summary>
        /// Transforms from local to world coordinates.
        /// </summary>
        /// <param name="vector">
        /// The vector (local coordinates).
        /// </param>
        /// <returns>
        /// Transformed vector (world coordinates).
        /// </returns>
        protected Vector3D ToWorld(Vector3D vector)
        {
            var mat = Visual3DHelper.GetTransform(this);
            var t   = new MatrixTransform3D(mat);

            return(t.Transform(vector));
        }
Exemple #2
0
        /// <summary>
        /// Updates the transforms.
        /// </summary>
        /// <returns>
        /// True if the transform was changed.
        /// </returns>
        public bool UpdateTransforms()
        {
            var transform = Visual3DHelper.GetViewportTransform(this.visual);

            if (!transform.HasValue)
            {
                return(false);
            }

            var newTransform = transform.Value;

            if (double.IsNaN(newTransform.M11))
            {
                return(false);
            }

            if (!newTransform.HasInverse)
            {
                return(false);
            }

            if (newTransform == this.visualToScreen)
            {
                return(false);
            }

            this.visualToScreen = this.screenToVisual = newTransform;
            this.screenToVisual.Invert();

            return(true);
        }
        /// <summary>
        /// Gets the distance from the camera for the specified visual.
        /// </summary>
        /// <param name="c">
        /// The visual.
        /// </param>
        /// <param name="cameraPos">
        /// The camera position.
        /// </param>
        /// <param name="transform">
        /// The total transform of the visual.
        /// </param>
        /// <returns>
        /// The camera distance.
        /// </returns>
        private double GetCameraDistance(Visual3D c, Point3D cameraPos, Transform3D transform)
        {
            var bounds = Visual3DHelper.FindBounds(c, transform);

            switch (this.Method)
            {
            case SortingMethod.BoundingBoxCenter:
                var mid = new Point3D(
                    bounds.X + bounds.SizeX * 0.5, bounds.Y + bounds.SizeY * 0.5, bounds.Z + bounds.SizeZ * 0.5);
                return((mid - cameraPos).LengthSquared);

            case SortingMethod.BoundingBoxCorners:
                double d = double.MaxValue;
                d = Math.Min(d, cameraPos.DistanceTo(new Point3D(bounds.X, bounds.Y, bounds.Z)));
                d = Math.Min(d, cameraPos.DistanceTo(new Point3D(bounds.X + bounds.SizeX, bounds.Y, bounds.Z)));
                d = Math.Min(
                    d, cameraPos.DistanceTo(new Point3D(bounds.X + bounds.SizeX, bounds.Y + bounds.SizeY, bounds.Z)));
                d = Math.Min(d, cameraPos.DistanceTo(new Point3D(bounds.X, bounds.Y + bounds.SizeY, bounds.Z)));
                d = Math.Min(d, cameraPos.DistanceTo(new Point3D(bounds.X, bounds.Y, bounds.Z + bounds.SizeZ)));
                d = Math.Min(
                    d, cameraPos.DistanceTo(new Point3D(bounds.X + bounds.SizeX, bounds.Y, bounds.Z + bounds.SizeZ)));
                d = Math.Min(
                    d,
                    cameraPos.DistanceTo(
                        new Point3D(bounds.X + bounds.SizeX, bounds.Y + bounds.SizeY, bounds.Z + bounds.SizeZ)));
                d = Math.Min(
                    d, cameraPos.DistanceTo(new Point3D(bounds.X, bounds.Y + bounds.SizeY, bounds.Z + bounds.SizeZ)));
                return(d);

            default:
                var boundingSphere = BoundingSphere.CreateFromRect3D(bounds);
                return(boundingSphere.DistanceFrom(cameraPos));
            }
        }
Exemple #4
0
        /// <summary>
        /// Transforms from local to world coordinates.
        /// </summary>
        /// <param name="point">
        /// The point (local coordinates).
        /// </param>
        /// <returns>
        /// Transformed point (world coordinates).
        /// </returns>
        protected Point3D ToWorld(Point3D point)
        {
            var mat = Visual3DHelper.GetTransform(this);
            var t   = new MatrixTransform3D(mat);

            return(t.Transform(point));
        }
        /// <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);
            }
        }
Exemple #6
0
        /// <summary>
        /// Transforms from world to local coordinates.
        /// </summary>
        /// <param name="worldPoint">
        /// The point (world coordinates).
        /// </param>
        /// <returns>
        /// Transformed vector (local coordinates).
        /// </returns>
        protected Point3D ToLocal(Point3D worldPoint)
        {
            var mat = Visual3DHelper.GetTransform(this);

            mat.Invert();
            var t = new MatrixTransform3D(mat);

            return(t.Transform(worldPoint));
        }
        /// <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 #8
0
        /// <summary>
        /// Zooms to fit the extents of the specified viewport.
        /// </summary>
        /// <param name="camera">
        /// The actual camera.
        /// </param>
        /// <param name="viewport">
        /// The viewport.
        /// </param>
        /// <param name="animationTime">
        /// The animation time.
        /// </param>
        public static void ZoomExtents(this ProjectionCamera camera, Viewport3D viewport, double animationTime = 0)
        {
            var bounds   = Visual3DHelper.FindBounds(viewport.Children);
            var diagonal = new Vector3D(bounds.SizeX, bounds.SizeY, bounds.SizeZ);

            if (bounds.IsEmpty || diagonal.LengthSquared < double.Epsilon)
            {
                return;
            }

            ZoomExtents(camera, viewport, bounds, animationTime);
        }
Exemple #9
0
 /// <summary>
 /// Applies the cutting planes.
 /// </summary>
 /// <param name="forceUpdate">
 /// if set to <c>true</c> [force update].
 /// </param>
 private void ApplyCuttingPlanes(bool forceUpdate = false)
 {
     lock (this)
     {
         this.NewCutGeometries      = new Dictionary <Model3D, Geometry3D>();
         this.NewOriginalGeometries = new Dictionary <Model3D, Geometry3D>();
         this.forceUpdate           = forceUpdate;
         Visual3DHelper.Traverse <GeometryModel3D>(this.Children, this.ApplyCuttingPlanesToModel);
         this.CutGeometries      = this.NewCutGeometries;
         this.OriginalGeometries = this.NewOriginalGeometries;
     }
 }
Exemple #10
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();
        }
Exemple #11
0
        /// <summary>
        /// Exports the specified viewport.
        /// Exports model, camera and lights.
        /// </summary>
        /// <param name="viewport">
        /// The viewport.
        /// </param>
        public virtual void Export(Viewport3D viewport)
        {
            this.ExportHeader();
            this.ExportViewport(viewport);

            // Export objects
            Visual3DHelper.Traverse <GeometryModel3D>(viewport.Children, this.ExportModel);

            // Export camera
            this.ExportCamera(viewport.Camera);

            // Export lights
            Visual3DHelper.Traverse <Light>(viewport.Children, this.ExportLight);
        }
        /// <summary>
        /// The composition target_ rendering.
        /// </summary>
        /// <param name="sender">
        /// The sender.
        /// </param>
        /// <param name="e">
        /// The event arguments.
        /// </param>
        protected override void OnCompositionTargetRendering(object sender, RenderingEventArgs e)
        {
            if (this.isRendering)
            {
                if (!Visual3DHelper.IsAttachedToViewport3D(this))
                {
                    return;
                }

                if (this.UpdateTransforms())
                {
                    this.UpdateGeometry();
                }
            }
        }
Exemple #13
0
        /// <summary>
        /// Exports the specified viewport.
        /// Exports model, camera and lights.
        /// </summary>
        /// <param name="viewport">
        /// The viewport.
        /// </param>
        public override void Export(Viewport3D viewport)
        {
            this.ExportViewport(viewport);

            // Export camera

            // Export lights
            Visual3DHelper.Traverse <Light>(viewport.Children, this.ExportLight);

            this.writer.WriteStartElement("library_materials");
            Visual3DHelper.Traverse <GeometryModel3D>(viewport.Children, this.ExportMaterial);
            this.writer.WriteEndElement();

            this.writer.WriteStartElement("library_effects");
            Visual3DHelper.Traverse <GeometryModel3D>(viewport.Children, this.ExportEffect);
            this.writer.WriteEndElement();

            // writer.WriteStartElement("library_cameras");
            // this.ExportCamera(viewport.Camera);
            // writer.WriteEndElement();

            // writer.WriteStartElement("library_lights");
            // Visual3DHelper.Traverse<Light>(viewport.Children, this.ExportLight);
            // writer.WriteEndElement();
            this.writer.WriteStartElement("library_geometries");
            Visual3DHelper.Traverse <GeometryModel3D>(viewport.Children, this.ExportGeometry);
            this.writer.WriteEndElement();

            this.writer.WriteStartElement("library_nodes");
            Visual3DHelper.Traverse <GeometryModel3D>(viewport.Children, this.ExportNode);
            this.writer.WriteEndElement();

            this.writer.WriteStartElement("library_visual_scenes");
            this.writer.WriteStartElement("visual_scene");
            this.writer.WriteAttributeString("id", "RootNode");
            this.writer.WriteAttributeString("name", "RootNode");

            // this.ExportCameraNode(viewport.Camera);
            Visual3DHelper.Traverse <GeometryModel3D>(viewport.Children, this.ExportSceneNode);
            this.writer.WriteEndElement();
            this.writer.WriteEndElement();

            this.writer.WriteStartElement("scene");
            this.writer.WriteStartElement("instance_visual_scene");
            this.writer.WriteAttributeString("url", "#RootNode");
            this.writer.WriteEndElement();
            this.writer.WriteEndElement();
        }
        /// <summary>
        /// Gets the total number of triangles in the viewport.
        /// </summary>
        /// <param name="viewport">The viewport.</param>
        /// <returns>The total number of triangles</returns>
        public static int GetTotalNumberOfTriangles(Viewport3D viewport)
        {
            int count = 0;

            Visual3DHelper.Traverse <GeometryModel3D>(
                viewport.Children,
                (m, t) =>
            {
                var geometry = m.Geometry as MeshGeometry3D;
                if (geometry != null && geometry.TriangleIndices != null)
                {
                    count += geometry.TriangleIndices.Count / 3;
                }
            });
            return(count);
        }
Exemple #15
0
        /// <summary>
        /// The expand.
        /// </summary>
        protected virtual void OnExpansionChanged()
        {
            if (!this.ExpandOrigin.HasValue)
            {
                if (this.Content != null)
                {
                    this.actualExpandOrigin = this.Content.Bounds.Location;
                }
            }
            else
            {
                this.actualExpandOrigin = this.ExpandOrigin.Value;
            }

            Visual3DHelper.TraverseModel <GeometryModel3D>(this.Content, this.Expand);
        }
        /// <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);
            }
        }
Exemple #17
0
 /// <summary>
 /// Exports the specified visual.
 /// </summary>
 /// <param name="visual">
 /// The visual.
 /// </param>
 public void Export(Visual3D visual)
 {
     this.ExportHeader();
     Visual3DHelper.Traverse <GeometryModel3D>(visual, this.ExportModel);
 }
Exemple #18
0
 /// <summary>
 /// Exports the specified model.
 /// </summary>
 /// <param name="model">
 /// The model.
 /// </param>
 public void Export(Model3D model)
 {
     this.ExportHeader();
     Visual3DHelper.TraverseModel <GeometryModel3D>(model, this.ExportModel);
 }
Exemple #19
0
        /// <summary>
        /// Gets the distance squared.
        /// </summary>
        /// <param name="position">
        /// The position.
        /// </param>
        /// <param name="visual">
        /// The visual.
        /// </param>
        /// <returns>
        /// The get distance squared.
        /// </returns>
        public static double GetDistanceSquared(Point3D position, Visual3D visual)
        {
            var bounds = Visual3DHelper.FindBounds(visual, Transform3D.Identity);

            return(Point3D.Subtract(bounds.Location, position).LengthSquared);
        }