+1

How to change the view to a standard-view in code?

Mehdi Rafeie 8 years ago updated by fresh 6 months ago 6

Hello there,

Thank you for your nice toolkit. I would like to know how to change the camera view to a standard view, such as top view, in code? Simply, I need a piece of code to do exactly what is happening by clicking on a side of the ViewCube.

Just found it out.

e.g. top-view:

helixViewPort3D.SetView(helixViewPort3D.Camera.Position, new Vector3D(0, 0, -1), new Vector3D(0, 1, 0), 1000);

+3

Although it works, changing the view using the code I posted above could cause the object to get out of the screen. So, I wrote a class called CameraController to exactly change the camera view as done by the ViewCube. (just rewrote the SetCameraView method of this class based on the HelixToolkit.Wpf.ViewCubeVisual3D.FaceMouseLeftButtonDown) Such a method may be added to the HelixToolkit.Wpf.HelixViewport3D as an overload of the SetView method.


I also added four isometric views to the class. It might be a good suggestion if you add these views and the rest of isometric views to the ViewCube by adding some tiny cubes to the corners of the view-cube.


    public static class CameraController
    {
        public enum eCameraViews
        {
            Fore,
            Back,
            Left,
            Right,
            Top,
            Bottom,
            Isometric_PPP,
            Isometric_MPP,
            Isometric_PMP,
            Isometric_MMP
        }
        private struct CameraViews
        {
            public struct StandardViews
            {
                public struct Normals
                {
                    public static Vector3D Fore
                    {
                        get { return new Vector3D(1, 0, 0); }
                    }
                    public static Vector3D Back
                    {
                        get { return new Vector3D(-1, 0, 0); }
                    }
                    public static Vector3D Left
                    {
                        get { return new Vector3D(0, 1, 0); }
                    }
                    public static Vector3D Right
                    {
                        get { return new Vector3D(0, -1, 0); }
                    }
                    public static Vector3D Top
                    {
                        get { return new Vector3D(0, 0, 1); }
                    }
                    public static Vector3D Bottom
                    {
                        get { return new Vector3D(0, 0, -1); }
                    }
                }
                public struct UpVectors
                {
                    public static Vector3D Fore
                    {
                        get { return new Vector3D(0, 0, 1); }
                    }
                    public static Vector3D Back
                    {
                        get { return new Vector3D(0, 0, 1); }
                    }
                    public static Vector3D Left
                    {
                        get { return new Vector3D(0, 0, 1); }
                    }
                    public static Vector3D Right
                    {
                        get { return new Vector3D(0, 0, 1); }
                    }
                    public static Vector3D Top
                    {
                        get { return new Vector3D(0, 1, 0); }
                    }
                    public static Vector3D Bottom
                    {
                        get { return new Vector3D(0, -1, 0); }
                    }
                }
            }
            public struct IsometricViews
            {
                public struct Normals
                {
                    public static Vector3D PPP
                    {
                        get { return new Vector3D(1, 1, 1); }
                    }
                    public static Vector3D MPP
                    {
                        get { return new Vector3D(-1, 1, 1); }
                    }
                    public static Vector3D PMP
                    {
                        get { return new Vector3D(1, -1, 1); }
                    }
                    public static Vector3D MMP
                    {
                        get { return new Vector3D(-1, -1, 1); }
                    }
                }
                public struct UpVectors
                {
                    public static Vector3D PPP
                    {
                        get { return new Vector3D(-1, -1, 1); }
                    }
                    public static Vector3D MPP
                    {
                        get { return new Vector3D(1, -1, 1); }
                    }
                    public static Vector3D PMP
                    {
                        get { return new Vector3D(-1, 1, 1); }
                    }
                    public static Vector3D MMP
                    {
                        get { return new Vector3D(1, 1, 1); }
                    }
                }
            }
        }
        private static Vector3D GetNormal(eCameraViews view)
        {
            switch (view)
            {
                case eCameraViews.Top: return CameraViews.StandardViews.Normals.Top;
                case eCameraViews.Bottom: return CameraViews.StandardViews.Normals.Bottom;
                case eCameraViews.Left: return CameraViews.StandardViews.Normals.Left;
                case eCameraViews.Right: return CameraViews.StandardViews.Normals.Right;
                case eCameraViews.Isometric_PPP: return CameraViews.IsometricViews.Normals.PPP;
                case eCameraViews.Isometric_MPP: return CameraViews.IsometricViews.Normals.MPP;
                case eCameraViews.Isometric_PMP: return CameraViews.IsometricViews.Normals.PMP;
                case eCameraViews.Isometric_MMP: return CameraViews.IsometricViews.Normals.MMP;
                default:
                    throw new NotSupportedException();
            }
        }
        private static Vector3D GetUpVector(eCameraViews view)
        {
            switch (view)
            {
                case eCameraViews.Top: return CameraViews.StandardViews.UpVectors.Top;
                case eCameraViews.Bottom: return CameraViews.StandardViews.UpVectors.Bottom;
                case eCameraViews.Left: return CameraViews.StandardViews.UpVectors.Left;
                case eCameraViews.Right: return CameraViews.StandardViews.UpVectors.Right;
                case eCameraViews.Isometric_PPP: return CameraViews.IsometricViews.UpVectors.PPP;
                case eCameraViews.Isometric_MPP: return CameraViews.IsometricViews.UpVectors.MPP;
                case eCameraViews.Isometric_PMP: return CameraViews.IsometricViews.UpVectors.PMP;
                case eCameraViews.Isometric_MMP: return CameraViews.IsometricViews.UpVectors.MMP;
                default:
                    throw new NotSupportedException();
            }
        }
        public static void SetCameraView(HelixViewport3D viewPort, eCameraViews view, double animationTime)
        {
            Vector3D faceNormal = GetNormal(view);
            Vector3D faceUp = GetUpVector(view);
            Vector3D lookDirection = -faceNormal;
            Vector3D upDirection = faceUp;
            lookDirection.Normalize();
            upDirection.Normalize();
            ProjectionCamera camera = viewPort.Camera as ProjectionCamera;
            if (camera != null)
            {
                Point3D target = camera.Position + camera.LookDirection;
                double distance = camera.LookDirection.Length;
                lookDirection *= distance;
                Point3D newPosition = target - lookDirection;
                viewPort.SetView(newPosition, lookDirection, upDirection, animationTime);
            }
        }
    }

I. Konuk,

Thanks for the message. CameraController is a static class with two public members—a method (i.e. SetCameraView) and an enumerator (i.e. eCameraViews). All you need to do is to call the SetCameraView method. Here is an example.

CameraController.SetCameraView(helixVP, CameraController.eCameraViews.Isometric_PPP, 1000);

where helixVP is an instance of HelixToolkit.Wpf.HelixViewport3DCameraController.eCameraViews.Isometric_PPP is the desired view (an isometric view with three positive normal vectors, namely Isometric_PPP or Isometric+++), and 1000 is the animation time in ms.

Hope it clarifies how to use the class.

Regards,

Mehdi

Your class is very usefull. You could further enhance it by using the extension method

    public static void SetCameraView(this HelixViewport3D viewPort, ...

this way you can call this method directly :

    myViewport.SetCameraView(...)

Hi Mehdi, 

Congrats on the nice solution. 

I also used it for my project and it works as a charm! 

Only one small extra addition: 

In the methods GetNormal and GetUpVector the cases for Fore and Back where missed, so this can be added in these methods. 

private static Vector3D GetNormal(eCameraViews view)
{
switch (view)
{
case eCameraViews.Top: return CameraViews.StandardViews.Normals.Top;
case eCameraViews.Bottom: return CameraViews.StandardViews.Normals.Bottom;
case eCameraViews.Left: return CameraViews.StandardViews.Normals.Left;
case eCameraViews.Right: return CameraViews.StandardViews.Normals.Right;
case eCameraViews.Fore: return CameraViews.StandardViews.Normals.Fore;
case eCameraViews.Back: return CameraViews.StandardViews.Normals.Back;
case eCameraViews.Isometric_PPP: return CameraViews.IsometricViews.Normals.PPP;
case eCameraViews.Isometric_MPP: return CameraViews.IsometricViews.Normals.MPP;
case eCameraViews.Isometric_PMP: return CameraViews.IsometricViews.Normals.PMP;
case eCameraViews.Isometric_MMP: return CameraViews.IsometricViews.Normals.MMP;
default:
throw new NotSupportedException();
}
}

private static Vector3D GetUpVector(eCameraViews view)
{
switch (view)
{
case eCameraViews.Top: return CameraViews.StandardViews.UpVectors.Top;
case eCameraViews.Bottom: return CameraViews.StandardViews.UpVectors.Bottom;
case eCameraViews.Left: return CameraViews.StandardViews.UpVectors.Left;
case eCameraViews.Right: return CameraViews.StandardViews.UpVectors.Right;
case eCameraViews.Fore: return CameraViews.StandardViews.UpVectors.Fore;
case eCameraViews.Back: return CameraViews.StandardViews.UpVectors.Back;
case eCameraViews.Isometric_PPP: return CameraViews.IsometricViews.UpVectors.PPP;
case eCameraViews.Isometric_MPP: return CameraViews.IsometricViews.UpVectors.MPP;
case eCameraViews.Isometric_PMP: return CameraViews.IsometricViews.UpVectors.PMP;
case eCameraViews.Isometric_MMP: return CameraViews.IsometricViews.UpVectors.MMP;
default:
throw new NotSupportedException();
}
}

Kind regards, 
Joachim

How to implement automatic camera view adjustment, so that when the model is too large or too small, the camera automatically adjusts its position to ensure a proper view of the complete model.