Пример #1
0
        private static Matrix3D GetViewMatrix(ProjectionCamera camera)
        {
            if (camera == null) throw new ArgumentNullException("camera");

            // This math is identical to what you find documented for
            // D3DXMatrixLookAtRH with the exception that WPF uses a
            // LookDirection vector rather than a LookAt point.

            Vector3D zAxis = -camera.LookDirection;
            zAxis.Normalize();

            Vector3D xAxis = Vector3D.CrossProduct(camera.UpDirection, zAxis);
            xAxis.Normalize();

            Vector3D yAxis = Vector3D.CrossProduct(zAxis, xAxis);

            Vector3D position = (Vector3D)camera.Position;
            double offsetX = -Vector3D.DotProduct(xAxis, position);
            double offsetY = -Vector3D.DotProduct(yAxis, position);
            double offsetZ = -Vector3D.DotProduct(zAxis, position);

            Matrix3D m = new Matrix3D(
                xAxis.X, yAxis.X, zAxis.X, 0,
                xAxis.Y, yAxis.Y, zAxis.Y, 0,
                xAxis.Z, yAxis.Z, zAxis.Z, 0,
                offsetX, offsetY, offsetZ, 1);

            return m;
        }
Пример #2
0
        private static void PositionPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ProjectionCamera target = ((ProjectionCamera)d);


            target.PropertyChanged(PositionProperty);
        }
Пример #3
0
        private static Matrix3D GetViewMatrix(ProjectionCamera camera)
        {
            Debug.Assert(camera != null,
                         "Caller needs to ensure camera is non-null.");

            // This math is identical to what you find documented for
            // D3DXMatrixLookAtRH with the exception that WPF uses a
            // LookDirection vector rather than a LookAt point.

            Vector3D zAxis = -camera.LookDirection;
            zAxis.Normalize();

            Vector3D xAxis = Vector3D.CrossProduct(camera.UpDirection, zAxis);
            xAxis.Normalize();

            Vector3D yAxis = Vector3D.CrossProduct(zAxis, xAxis);

            Vector3D position = (Vector3D)camera.Position;
            double offsetX = -Vector3D.DotProduct(xAxis, position);
            double offsetY = -Vector3D.DotProduct(yAxis, position);
            double offsetZ = -Vector3D.DotProduct(zAxis, position);

            return new Matrix3D(
                xAxis.X, yAxis.X, zAxis.X, 0,
                xAxis.Y, yAxis.Y, zAxis.Y, 0,
                xAxis.Z, yAxis.Z, zAxis.Z, 0,
                offsetX, offsetY, offsetZ, 1);
        }
Пример #4
0
        private static void FarPlaneDistancePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            ProjectionCamera target = ((ProjectionCamera)d);


            target.PropertyChanged(FarPlaneDistanceProperty);
        }
Пример #5
0
        public CameraController(Camera c, IListLayout l, PointLight p)
        {
            camera = (ProjectionCamera)c;
            layout = l;
            light = p;

            try
            {
                Transform3DGroup group = camera.Transform as Transform3DGroup;
                RotateTransform3D rot = group.Children[0] as RotateTransform3D;
                cameraRotX = rot.Rotation as AxisAngleRotation3D;
                rot = group.Children[1] as RotateTransform3D;
                cameraRotY = rot.Rotation as AxisAngleRotation3D;
                rot = group.Children[2] as RotateTransform3D;
                cameraRotZ = rot.Rotation as AxisAngleRotation3D;
            }
            catch (Exception )
            {
                System.Diagnostics.Debug.WriteLine("camera transformations are wrong!!!");
            }
            try
            {
                Transform3DGroup group = light.Transform as Transform3DGroup;
                RotateTransform3D rot = group.Children[0] as RotateTransform3D;
                lightRotX = rot.Rotation as AxisAngleRotation3D;
                rot = group.Children[1] as RotateTransform3D;
                lightRotY = rot.Rotation as AxisAngleRotation3D;
                rot = group.Children[2] as RotateTransform3D;
                lightRotZ = rot.Rotation as AxisAngleRotation3D;
            }
            catch (Exception )
            {
                System.Diagnostics.Debug.WriteLine("light transformations are wrong!!!");
            }
        }
Пример #6
0
		/// <summary>
		/// Create a MatrixCamera from an existing ProjectionCamera
		/// </summary>
		/// <param name="camera">Camera</param>
		/// <param name="width">Viewport height</param>
		/// <param name="height">Viewport width</param>
		/// <returns>MatrixCamera</returns>
		public static MatrixCamera CreateMatrixCamera( ProjectionCamera camera, double width, double height )
		{
			MatrixCamera matrixCamera = new MatrixCamera(
				CreateViewMatrix( camera ),
				CreateProjectionMatrix( camera, width, height, camera.NearPlaneDistance, camera.FarPlaneDistance ) );
			matrixCamera.Transform = camera.Transform;

			return matrixCamera;
		}
Пример #7
0
		/// <summary>
		/// Create a MatrixCamera from an existing ProjectionCamera
		/// </summary>
		/// <param name="camera">Camera</param>
		/// <param name="width">Viewport height</param>
		/// <param name="height">Viewport width</param>
		/// <param name="near">Near plane distance</param>
		/// <param name="far">Far plane distance</param>
		/// <returns>MatrixCamera</returns>
		public static MatrixCamera CreateMatrixCamera( ProjectionCamera camera, double width, double height, double near, double far )
		{
			MatrixCamera matrixCamera = new MatrixCamera(
				CreateViewMatrix( camera ),
				CreateProjectionMatrix( camera, width, height, near, far ) );
			matrixCamera.Transform = camera.Transform;

			return matrixCamera;
		}
Пример #8
0
		/// <summary>
		/// Create a Projection matrix from an existing ProjectionCamera and view size
		/// (code acquired with Reflector)
		/// </summary>
		/// <param name="camera">Camera</param>
		/// <param name="width">Width</param>
		/// <param name="height">Height</param>
		public static Matrix3D CreateProjectionMatrix( ProjectionCamera camera, double width, double height, double near, double far )
		{
			double aspectRatio = width / height;
			double zn = near;
			double zf = far;

			double fov = ( camera is PerspectiveCamera ) ? ( camera as PerspectiveCamera ).FieldOfView : 60;

			double num2 = Math.Tan( DegreesToRadians( fov ) / 2 );
			double num5 = aspectRatio / num2;
			double num4 = 1 / num2;
			double num = ( zf != double.PositiveInfinity ) ? ( zf / ( zn - zf ) ) : -1;
			return new Matrix3D( num4, 0, 0, 0, 0, num5, 0, 0, 0, 0, num, -1, 0, 0, zn * num, 0 );
		}
Пример #9
0
        /// <summary>
        /// Animates the camera position and directions.
        /// </summary>
        /// <param name="camera">
        /// The camera to animate.
        /// </param>
        /// <param name="newPosition">
        /// The position to animate to.
        /// </param>
        /// <param name="newDirection">
        /// The direction to animate to.
        /// </param>
        /// <param name="newUpDirection">
        /// The up direction to animate to.
        /// </param>
        /// <param name="animationTime">
        /// Animation time in milliseconds.
        /// </param>
        public static void AnimateTo(
            ProjectionCamera camera,
            Point3D newPosition,
            Vector3D newDirection,
            Vector3D newUpDirection,
            double animationTime)
        {
            var fromPosition = camera.Position;
            var fromDirection = camera.LookDirection;
            var fromUpDirection = camera.UpDirection;

            camera.Position = newPosition;
            camera.LookDirection = newDirection;
            camera.UpDirection = newUpDirection;

            if (animationTime > 0)
            {
                var a1 = new Point3DAnimation(
                    fromPosition, newPosition, new Duration(TimeSpan.FromMilliseconds(animationTime)))
                    {
                        AccelerationRatio = 0.3,
                        DecelerationRatio = 0.5,
                        FillBehavior = FillBehavior.Stop

                    };
                a1.Completed += (s, a) => { camera.BeginAnimation(ProjectionCamera.PositionProperty, null); };
                camera.BeginAnimation(ProjectionCamera.PositionProperty, a1);

                var a2 = new Vector3DAnimation(
                    fromDirection, newDirection, new Duration(TimeSpan.FromMilliseconds(animationTime)))
                    {
                        AccelerationRatio = 0.3,
                        DecelerationRatio = 0.5,
                        FillBehavior = FillBehavior.Stop
                    };
                a2.Completed += (s, a) => { camera.BeginAnimation(ProjectionCamera.LookDirectionProperty, null); };
                camera.BeginAnimation(ProjectionCamera.LookDirectionProperty, a2);

                var a3 = new Vector3DAnimation(
                    fromUpDirection, newUpDirection, new Duration(TimeSpan.FromMilliseconds(animationTime)))
                    {
                        AccelerationRatio = 0.3,
                        DecelerationRatio = 0.5,
                        FillBehavior = FillBehavior.Stop
                    };
                a3.Completed += (s, a) => { camera.BeginAnimation(ProjectionCamera.UpDirectionProperty, null); };
                camera.BeginAnimation(ProjectionCamera.UpDirectionProperty, a3);
            }
        }
Пример #10
0
		/// <summary>
		/// Create a View matrix from an existing ProjectionCamera
		/// (code acquired with Reflector)
		/// </summary>
		/// <param name="camera">Camera</param>
		/// <returns>View matrix</returns>
		public static Matrix3D CreateViewMatrix( ProjectionCamera camera )
		{
			Vector3D vectord2 = -camera.LookDirection;
			vectord2.Normalize();
			Vector3D vectord3 = Vector3D.CrossProduct( camera.UpDirection, vectord2 );
			vectord3.Normalize();
			Vector3D vectord4 = Vector3D.CrossProduct( vectord2, vectord3 );
			Vector3D vectord = (Vector3D)camera.Position;
			double offsetX = -Vector3D.DotProduct( vectord3, vectord );
			double offsetY = -Vector3D.DotProduct( vectord4, vectord );
			double offsetZ = -Vector3D.DotProduct( vectord2, vectord );
			Matrix3D viewMatrix = new Matrix3D( vectord3.X, vectord4.X, vectord2.X, 0, vectord3.Y, vectord4.Y, vectord2.Y, 0, vectord3.Z, vectord4.Z, vectord2.Z, 0, offsetX, offsetY, offsetZ, 1 );
			PrependInverseTransform( camera.Transform, ref viewMatrix );
			return viewMatrix;
		}
Пример #11
0
        public DepthPlanes( ProjectionCamera camera, BoundingBox bounds, double step )
        {
            // Find closest visible point to camera
            Point3D position = camera.Transform.Transform( camera.Position );
            Vector3D direction = camera.Transform.Transform( camera.LookDirection );
            Point3D lookAt = position + ( direction * camera.NearPlaneDistance );
            double xDir = Normalize( direction.X );
            double yDir = Normalize( direction.Y );
            double zDir = Normalize( direction.Z );

            double biggest = Math.Max( Math.Max( Math.Abs( lookAt.X ), Math.Abs( lookAt.Y ) ), Math.Abs( lookAt.Z ) );

            if ( xDir != 0 ) planes.Add( new Plane( new Vector3D( -xDir, 0, 0 ), -Distance( lookAt.X, biggest, bounds.Max.X, step ) ) );
            if ( yDir != 0 ) planes.Add( new Plane( new Vector3D( 0, -yDir, 0 ), -Distance( lookAt.Y, biggest, bounds.Max.Y, step ) ) );
            if ( zDir != 0 ) planes.Add( new Plane( new Vector3D( 0, 0, -zDir ), -Distance( lookAt.Z, biggest, bounds.Max.Z, step ) ) );
        }
Пример #12
0
        /// <summary>
        /// The update camera.
        /// </summary>
        /// <param name="camera">
        /// The camera.
        /// </param>
        public void UpdateCamera(ProjectionCamera camera)
        {
            camera.Position = this.Position;
            camera.LookDirection = this.LookDirection;
            camera.UpDirection = this.UpDirection;
            camera.NearPlaneDistance = this.NearPlaneDistance;
            camera.FarPlaneDistance = this.FarPlaneDistance;
            var pcamera = camera as PerspectiveCamera;
            if (pcamera != null)
            {
                pcamera.FieldOfView = this.FieldOfView;
            }

            var ocamera = camera as OrthographicCamera;
            if (ocamera != null)
            {
                ocamera.Width = this.Width;
            }
        }
Пример #13
0
        /// <summary>
        /// Initializes a new instance of the <see cref="CameraSetting"/> class.
        /// </summary>
        /// <param name="camera">
        /// The camera.
        /// </param>
        public CameraSetting(ProjectionCamera camera)
        {
            this.Position = camera.Position;
            this.LookDirection = camera.LookDirection;
            this.UpDirection = camera.UpDirection;
            this.NearPlaneDistance = camera.NearPlaneDistance;
            this.FarPlaneDistance = camera.FarPlaneDistance;
            var pcamera = camera as PerspectiveCamera;
            if (pcamera != null)
            {
                this.FieldOfView = pcamera.FieldOfView;
            }

            var ocamera = camera as OrthographicCamera;
            if (ocamera != null)
            {
                this.Width = ocamera.Width;
            }
        }
Пример #14
0
 /// <summary>
 /// Zooms to fit the specified bounding rectangle.
 /// </summary>
 /// <param name="actualCamera">
 /// The actual camera.
 /// </param>
 /// <param name="viewport">
 /// The viewport.
 /// </param>
 /// <param name="bounds">
 /// The bounding rectangle.
 /// </param>
 /// <param name="animationTime">
 /// The animation time.
 /// </param>
 public static void ZoomExtents(
     ProjectionCamera actualCamera, Viewport3D viewport, Rect3D bounds, double animationTime = 0)
 {
     var diagonal = new Vector3D(bounds.SizeX, bounds.SizeY, bounds.SizeZ);
     var center = bounds.Location + diagonal * 0.5;
     double radius = diagonal.Length * 0.5;
     ZoomExtents(actualCamera, viewport, center, radius, animationTime);
 }
Пример #15
0
        /// <summary>
        /// Zooms to fit the extents of the specified viewport.
        /// </summary>
        /// <param name="actualCamera">
        /// The actual camera.
        /// </param>
        /// <param name="viewport">
        /// The viewport.
        /// </param>
        /// <param name="animationTime">
        /// The animation time.
        /// </param>
        public static void ZoomExtents(ProjectionCamera actualCamera, 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 == 0)
            {
                return;
            }

            ZoomExtents(actualCamera, viewport, bounds, animationTime);
        }
Пример #16
0
 /// <summary>
 /// Set the camera target point and camera distance.
 /// </summary>
 /// <param name="camera">
 /// The camera.
 /// </param>
 /// <param name="target">
 /// The target point.
 /// </param>
 /// <param name="distance">
 /// The distance to the camera.
 /// </param>
 /// <param name="animationTime">
 /// The animation time.
 /// </param>
 public static void LookAt(ProjectionCamera camera, Point3D target, double distance, double animationTime)
 {
     Vector3D d = camera.LookDirection;
     d.Normalize();
     LookAt(camera, target, d * distance, animationTime);
 }
Пример #17
0
		public CameraAgent(ThreadViewport3D evtHost)
		{
			host = evtHost;
			cmr = (ProjectionCamera)host.Camera;
		}
        /// <summary>
        /// Default constructor
        /// </summary>
        public Visualizer()
        {
            InitializeComponent();

            HorizontalRotation = 1.86;
            VerticalRotation = 0.56;

            IsVisibleChanged += OnIsVisibleChanged;

            viewport.Camera = camera = new PerspectiveCamera(new Point3D(), new Vector3D(1, 0, 0), new Vector3D(0, 0, 1), FieldOfView);

            lightsContainer.Content = lightFromEyes;
            Transform3DGroup transform3DGroup = new Transform3DGroup();
            transform3DGroup.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(0, 1, 0), 20)));
            transform3DGroup.Children.Add(new RotateTransform3D(new AxisAngleRotation3D(new Vector3D(1, 0, 0), -20)));
            lightsContainer.Transform = transform3DGroup;

            // Add ambient light
            viewport.Children.Add(new ModelVisual3D() { Content = lightAmbient });

            #region Axis (for debug only)

            /*Cylinder xaxis = new Cylinder(new Point3D(), new Point3D(100, 0,0), 1);
            Cylinder yaxis = new Cylinder(new Point3D(), new Point3D(0, 100, 0), 1);
            Cylinder zaxis = new Cylinder(new Point3D(), new Point3D(0, 0, 100), 1);
            xaxis.Material = new DiffuseMaterial(new SolidColorBrush(Colors.Red));
            yaxis.Material = new DiffuseMaterial(new SolidColorBrush(Colors.Green));
            zaxis.Material = new DiffuseMaterial(new SolidColorBrush(Colors.Blue));
            lightsContainer.Children.Add(xaxis);
            lightsContainer.Children.Add(yaxis);
            lightsContainer.Children.Add(zaxis);*/

            #endregion

            viewport.Children.Add(moleculesContainer);
            viewport.Children.Add(lightsContainer);
            viewport.Children.Add(shadowContainer);
        }
        /// <summary>
        /// Creates preview of this control (automatically setup the camera)
        /// </summary>
        public void CreatePreview(RenderTargetBitmap renderTargetBitmap)
        {
            bool wasDetached = !dataAttached;
            AttachData();

            if (moleculesContainer.Children.Count == 0)
            {
                if (wasDetached) DetachData();
                return;
            }

            ProjectionCamera backupCamera = camera;
            Double backupWidth = Width;
            Double backupHeight = Height;

            // Change size of the visualizer
            Width = renderTargetBitmap.PixelWidth;
            Height = renderTargetBitmap.PixelHeight;
            Measure(new Size(renderTargetBitmap.PixelWidth, renderTargetBitmap.PixelHeight));
            Arrange(new Rect(0, 0, renderTargetBitmap.PixelWidth, renderTargetBitmap.PixelHeight));

            // Change camera
            // Prepare bounding box
            Rect3D boundingBox = VisualTreeHelper.GetDescendantBounds(moleculesContainer);
            if (boundingBox.IsEmpty)
            {
                renderTargetBitmap.Render(this);
                boundingBox = VisualTreeHelper.GetDescendantBounds(moleculesContainer);
                if (boundingBox.IsEmpty) return;
            }
            OrthographicCamera orthographicCamera = new OrthographicCamera();

            #region Accomodate camera to fit content

            if (boundingBox.SizeZ < boundingBox.SizeX && boundingBox.SizeZ < boundingBox.SizeY)
            {
                orthographicCamera.Position = new Point3D(boundingBox.Location.X + boundingBox.SizeX / 2.0,
                                                          boundingBox.Location.Y + boundingBox.SizeY / 2.0,
                                                          boundingBox.Location.Z);
                orthographicCamera.LookDirection = new Vector3D(0, 0, 1);
                orthographicCamera.UpDirection = new Vector3D(0, 1, 0);
                orthographicCamera.Width = Math.Max(boundingBox.SizeX, boundingBox.SizeY) * (Width / Height);

            }
            else if (boundingBox.SizeX < boundingBox.SizeZ && boundingBox.SizeX < boundingBox.SizeY)
            {
                orthographicCamera.Position = new Point3D(boundingBox.Location.X,
                                                          boundingBox.Location.Y + boundingBox.SizeY / 2.0,
                                                          boundingBox.Location.Z + boundingBox.SizeZ / 2.0);
                orthographicCamera.LookDirection = new Vector3D(1, 0, 0);
                orthographicCamera.UpDirection = new Vector3D(0, 1, 0);
                orthographicCamera.Width = Math.Max(boundingBox.SizeY, boundingBox.SizeZ);
            }
            else
            {
                orthographicCamera.Position = new Point3D(boundingBox.Location.X + boundingBox.SizeX / 2.0,
                                                          boundingBox.Location.Y,
                                                          boundingBox.Location.Z + boundingBox.SizeZ / 2.0);
                orthographicCamera.LookDirection = new Vector3D(0, 1, 0);
                orthographicCamera.UpDirection = new Vector3D(1, 0, 0);
                orthographicCamera.Width = Math.Max(boundingBox.SizeX, boundingBox.SizeZ);
            }

            #endregion

            orthographicCamera.NearPlaneDistance = 0;

            // Set the camera & correct lights
            viewport.Camera = orthographicCamera;
            lightFromEyes.Direction = orthographicCamera.LookDirection;
            RenderOptions.SetEdgeMode(this, EdgeMode.Unspecified);
            UpdateLayout();
            renderTargetBitmap.Render(this);

            // Restore original values of the properties
            viewport.Camera = camera = backupCamera;
            Width = backupWidth;
            Height = backupHeight;

            if (wasDetached) DetachData();
        }
Пример #20
0
 /// <summary>
 /// Changes the direction of a camera.
 /// </summary>
 /// <param name="camera">
 /// The camera.
 /// </param>
 /// <param name="newLookDir">
 /// The new look dir.
 /// </param>
 /// <param name="newUpDirection">
 /// The new up direction.
 /// </param>
 /// <param name="animationTime">
 /// The animation time.
 /// </param>
 public static void ChangeDirection(
     ProjectionCamera camera, Vector3D newLookDir, Vector3D newUpDirection, double animationTime)
 {
     var target = camera.Position + camera.LookDirection;
     double length = camera.LookDirection.Length;
     newLookDir.Normalize();
     LookAt(camera, target, newLookDir * length, newUpDirection, animationTime);
 }
Пример #21
0
        /// <summary>
        /// Zooms to fit the specified sphere.
        /// </summary>
        /// <param name="camera">
        /// The camera to change.
        /// </param>
        /// <param name="viewport">
        /// The viewport.
        /// </param>
        /// <param name="center">
        /// The center of the sphere.
        /// </param>
        /// <param name="radius">
        /// The radius of the sphere.
        /// </param>
        /// <param name="animationTime">
        /// The animation time.
        /// </param>
        public static void ZoomExtents(
            ProjectionCamera camera,
            Viewport3D viewport,
            Point3D center,
            double radius,
            double animationTime = 0)
        {
            var perspectiveCamera = camera as PerspectiveCamera;
            if (perspectiveCamera != null)
            {
                FitView(camera, viewport, center, radius, perspectiveCamera.LookDirection, perspectiveCamera.UpDirection, animationTime);
                return;
            }

            var orthoCamera = camera as OrthographicCamera;
            if (orthoCamera != null)
            {
                FitView(camera, viewport, center, radius, orthoCamera.LookDirection, orthoCamera.UpDirection, animationTime);
            }
        }
Пример #22
0
        /// <summary>
        /// Fits the specified bounding sphere to the view.
        /// </summary>
        /// <param name="camera">The camera to change.</param>
        /// <param name="viewport">The viewport.</param>
        /// <param name="center">The center of the sphere.</param>
        /// <param name="radius">The radius of the sphere.</param>
        /// <param name="lookDirection">The look direction.</param>
        /// <param name="upDirection">The up direction.</param>
        /// <param name="animationTime">The animation time.</param>
        public static void FitView(
            ProjectionCamera camera,
            Viewport3D viewport,
            Point3D center,
            double radius,
            Vector3D lookDirection,
            Vector3D upDirection,
            double animationTime = 0)
        {
            var perspectiveCamera = camera as PerspectiveCamera;
            if (perspectiveCamera != null)
            {
                var pcam = perspectiveCamera;
                double disth = radius / Math.Tan(0.5 * pcam.FieldOfView * Math.PI / 180);
                double vfov = pcam.FieldOfView;
                if (viewport.ActualWidth > 0 && viewport.ActualHeight > 0)
                {
                    vfov *= viewport.ActualHeight / viewport.ActualWidth;
                }

                double distv = radius / Math.Tan(0.5 * vfov * Math.PI / 180);
                double dist = Math.Max(disth, distv);
                var dir = lookDirection;
                dir.Normalize();
                LookAt(perspectiveCamera, center, dir * dist, upDirection, animationTime);
                return;
            }

            var orthographicCamera = camera as OrthographicCamera;
            if (orthographicCamera != null)
            {
                LookAt(orthographicCamera, center, lookDirection, upDirection, animationTime);
                double newWidth = radius * 2;

                if (viewport.ActualWidth > viewport.ActualHeight)
                {
                    newWidth = radius * 2 * viewport.ActualWidth / viewport.ActualHeight;
                }

                AnimateWidth(orthographicCamera, newWidth, animationTime);
            }
        }
Пример #23
0
        /// <summary>
        /// Zooms to fit the specified sphere.
        /// </summary>
        /// <param name="camera">
        /// The camera.
        /// </param>
        /// <param name="viewport">
        /// The viewport.
        /// </param>
        /// <param name="center">
        /// The center of the sphere.
        /// </param>
        /// <param name="radius">
        /// The radius of the sphere.
        /// </param>
        /// <param name="animationTime">
        /// The animation time.
        /// </param>
        public static void ZoomExtents(
            ProjectionCamera camera, Viewport3D viewport, Point3D center, double radius, double animationTime = 0)
        {
            // var target = Camera.Position + Camera.LookDirection;
            if (camera is PerspectiveCamera)
            {
                var pcam = camera as PerspectiveCamera;
                double disth = radius / Math.Tan(0.5 * pcam.FieldOfView * Math.PI / 180);
                double vfov = pcam.FieldOfView / viewport.ActualWidth * viewport.ActualHeight;
                double distv = radius / Math.Tan(0.5 * vfov * Math.PI / 180);

                double dist = Math.Max(disth, distv);
                var dir = camera.LookDirection;
                dir.Normalize();
                LookAt(camera, center, dir * dist, animationTime);
            }

            if (camera is OrthographicCamera)
            {
                LookAt(camera, center, camera.LookDirection, animationTime);
                double newWidth = radius * 2;

                if (viewport.ActualWidth > viewport.ActualHeight)
                {
                    newWidth = radius * 2 * viewport.ActualWidth / viewport.ActualHeight;
                }

                AnimateWidth(camera as OrthographicCamera, newWidth, animationTime);
            }
        }
Пример #24
0
 /// <summary>
 /// Set the camera target point without changing the look direction.
 /// </summary>
 /// <param name="camera">
 /// The camera.
 /// </param>
 /// <param name="target">
 /// The target.
 /// </param>
 /// <param name="animationTime">
 /// The animation time.
 /// </param>
 public static void LookAt(ProjectionCamera camera, Point3D target, double animationTime)
 {
     LookAt(camera, target, camera.LookDirection, animationTime);
 }
Пример #25
0
        /// <summary>
        /// Zooms the camera to the specified rectangle.
        /// </summary>
        /// <param name="camera">
        /// The camera.
        /// </param>
        /// <param name="viewport">
        /// The viewport.
        /// </param>
        /// <param name="zoomRectangle">
        /// The zoom rectangle.
        /// </param>
        public static void ZoomToRectangle(ProjectionCamera camera, Viewport3D viewport, Rect zoomRectangle)
        {
            var topLeftRay = Viewport3DHelper.Point2DtoRay3D(viewport, zoomRectangle.TopLeft);
            var topRightRay = Viewport3DHelper.Point2DtoRay3D(viewport, zoomRectangle.TopRight);
            var centerRay = Viewport3DHelper.Point2DtoRay3D(
                viewport,
                new Point(
                    (zoomRectangle.Left + zoomRectangle.Right) * 0.5, (zoomRectangle.Top + zoomRectangle.Bottom) * 0.5));

            if (topLeftRay == null || topRightRay == null || centerRay == null)
            {
                // could not invert camera matrix
                return;
            }

            var u = topLeftRay.Direction;
            var v = topRightRay.Direction;
            var w = centerRay.Direction;
            u.Normalize();
            v.Normalize();
            w.Normalize();
            var perspectiveCamera = camera as PerspectiveCamera;
            if (perspectiveCamera != null)
            {
                var distance = camera.LookDirection.Length;

                // option 1: change distance
                var newDistance = distance * zoomRectangle.Width / viewport.ActualWidth;
                var newLookDirection = newDistance * w;
                var newPosition = perspectiveCamera.Position + (distance - newDistance) * w;
                var newTarget = newPosition + newLookDirection;
                LookAt(camera, newTarget, newLookDirection, 200);

                // option 2: change fov
                //    double newFieldOfView = Math.Acos(Vector3D.DotProduct(u, v));
                //    var newTarget = camera.Position + distance * w;
                //    pcamera.FieldOfView = newFieldOfView * 180 / Math.PI;
                //    LookAt(camera, newTarget, distance * w, 0);
            }

            var orthographicCamera = camera as OrthographicCamera;
            if (orthographicCamera != null)
            {
                orthographicCamera.Width *= zoomRectangle.Width / viewport.ActualWidth;
                var oldTarget = camera.Position + camera.LookDirection;
                var distance = camera.LookDirection.Length;
                var newTarget = centerRay.PlaneIntersection(oldTarget, w);
                if (newTarget != null)
                {
                    orthographicCamera.LookDirection = w * distance;
                    orthographicCamera.Position = newTarget.Value - orthographicCamera.LookDirection;
                }
            }
        }
Пример #26
0
 /// <summary>
 /// Set the camera target point and look direction
 /// </summary>
 /// <param name="camera">
 /// The camera.
 /// </param>
 /// <param name="target">
 /// The target.
 /// </param>
 /// <param name="newLookDirection">
 /// The new look direction.
 /// </param>
 /// <param name="animationTime">
 /// The animation time.
 /// </param>
 public static void LookAt(
     ProjectionCamera camera, Point3D target, Vector3D newLookDirection, double animationTime)
 {
     LookAt(camera, target, newLookDirection, camera.UpDirection, animationTime);
 }
Пример #27
0
        /// <summary>
        /// Sets the camera.
        /// </summary>
        /// <param name="camera">The camera.</param>
        /// <param name="changeUpDirectionFromZtoY">switch Y and Z if set to <c>true</c>.</param>
        public void SetCamera(ProjectionCamera camera, bool changeUpDirectionFromZtoY = true)
        {
            this.CamUp = new Vector3D(0, 1, 0);
            this.CamTarget = camera.Position + camera.LookDirection;
            this.CamPos = camera.Position;
            if (changeUpDirectionFromZtoY)
            {
                this.CamTarget = this.SwitchYZ(this.CamTarget);
                this.CamPos = this.SwitchYZ(this.CamPos);
            }

            var pc = camera as PerspectiveCamera;
            if (pc != null)
            {
                this.FieldOfView = pc.FieldOfView;
            }

            this.CamMotionUp = this.CamUp;
            this.CamMotionTarget = this.CamTarget;
            this.CamMotionPos = this.CamPos;
        }
Пример #28
0
        /// <summary>
        /// Set the camera target point and directions
        /// </summary>
        /// <param name="camera">
        /// The camera.
        /// </param>
        /// <param name="target">
        /// The target.
        /// </param>
        /// <param name="newLookDirection">
        /// The new look direction.
        /// </param>
        /// <param name="newUpDirection">
        /// The new up direction.
        /// </param>
        /// <param name="animationTime">
        /// The animation time.
        /// </param>
        public static void LookAt(
            ProjectionCamera camera,
            Point3D target,
            Vector3D newLookDirection,
            Vector3D newUpDirection,
            double animationTime)
        {
            Point3D newPosition = target - newLookDirection;

            if (camera is PerspectiveCamera)
            {
                AnimateTo(camera as PerspectiveCamera, newPosition, newLookDirection, newUpDirection, animationTime);
            }

            if (camera is OrthographicCamera)
            {
                AnimateTo(camera as OrthographicCamera, newPosition, newLookDirection, newUpDirection, animationTime);
            }
        }
Пример #29
0
        /// <summary>
        /// Copies the specified camera, converts field of view/width if neccessary.
        /// </summary>
        /// <param name="source">
        /// The source camera.
        /// </param>
        /// <param name="dest">
        /// The destination camera.
        /// </param>
        public static void Copy(ProjectionCamera source, ProjectionCamera dest)
        {
            if (source == null || dest == null)
            {
                return;
            }

            dest.LookDirection = source.LookDirection;
            dest.Position = source.Position;
            dest.UpDirection = source.UpDirection;
            dest.NearPlaneDistance = source.NearPlaneDistance;
            dest.FarPlaneDistance = source.FarPlaneDistance;
            var psrc = source as PerspectiveCamera;
            var osrc = source as OrthographicCamera;
            var pdest = dest as PerspectiveCamera;
            var odest = dest as OrthographicCamera;
            if (pdest != null)
            {
                double fov = 45;
                if (psrc != null)
                {
                    fov = psrc.FieldOfView;
                }

                if (osrc != null)
                {
                    double dist = source.LookDirection.Length;
                    fov = Math.Atan(osrc.Width / 2 / dist) * 180 / Math.PI * 2;
                }

                pdest.FieldOfView = fov;
            }

            if (odest != null)
            {
                double width = 100;
                if (psrc != null)
                {
                    double dist = source.LookDirection.Length;
                    width = Math.Tan(psrc.FieldOfView / 180 * Math.PI / 2) * dist * 2;
                }

                if (osrc != null)
                {
                    width = osrc.Width;
                }

                odest.Width = width;
            }
        }
        /// <summary>
        /// Renders visualizer to bitmap
        /// </summary>
        public void RenderTo(RenderTargetBitmap renderTargetBitmap)
        {
            bool wasDetached = !dataAttached;
            AttachData();

            if (moleculesContainer.Children.Count == 0)
            {
                if (wasDetached) DetachData();
                return;
            }

            ProjectionCamera backupCamera = camera;
            Double backupWidth = Width;
            Double backupHeight = Height;

            // Change size of the visualizer
            Width = renderTargetBitmap.PixelWidth;
            Height = renderTargetBitmap.PixelHeight;
            Measure(new Size(renderTargetBitmap.PixelWidth, renderTargetBitmap.PixelHeight));
            Arrange(new Rect(0, 0, renderTargetBitmap.PixelWidth, renderTargetBitmap.PixelHeight));

            // Finish the animations
            CompleteAnimation();

            RenderOptions.SetEdgeMode(this, EdgeMode.Unspecified);
            UpdateLayout();
            renderTargetBitmap.Render(this);

            // Restore original values of the properties
            viewport.Camera = camera = backupCamera;
            Width = backupWidth;
            Height = backupHeight;

            if (wasDetached) DetachData();
        }
Пример #31
0
        /// <summary>
        /// Copy the direction of the source <see cref="Camera"/>. Used for the CoordinateSystem view.
        /// </summary>
        /// <param name="source">
        /// The source camera.
        /// </param>
        /// <param name="dest">
        /// The destination camera.
        /// </param>
        /// <param name="distance">
        /// New length of the LookDirection vector.
        /// </param>
        public static void CopyDirectionOnly(ProjectionCamera source, ProjectionCamera dest, double distance)
        {
            if (source == null || dest == null)
            {
                return;
            }

            Vector3D dir = source.LookDirection;
            dir.Normalize();
            dir *= distance;

            dest.LookDirection = dir;
            dest.Position = new Point3D(-dest.LookDirection.X, -dest.LookDirection.Y, -dest.LookDirection.Z);
            dest.UpDirection = source.UpDirection;
        }
 public static void SetDirection(ProjectionCamera target, ProjectionCamera source)
 {
     target.LookDirection = source.LookDirection;
     target.UpDirection = source.UpDirection;
 }