1

I'm building a WPF app that has some 3D objects in view and the view should be able to be panned and rotated. I'm using HelixViewport3D for this from the HelixToolkit NuGet pakcage, HelixToolkit.Wpf library. The view should be rotated by holding down the mouse wheel and moving the mouse around. I'm using the left click for panning and the right click is for showing tooltips of objects in the view.

The .xaml snippet for the viewport:

<helix:HelixViewport3D x:Name="viewport" ClipToBounds="True" ShowViewCube="False">
    <helix:HelixViewport3D.Camera>
        <PerspectiveCamera Position="3 2 6" LookDirection="0 -2 -3"></PerspectiveCamera>
    </helix:HelixViewport3D.Camera>
    ...
    ..
    .

In the MainWindow constructor:

viewport.RotateGesture = new MouseGesture(MouseAction.MiddleClick);
viewport.PanGesture = new MouseGesture(MouseAction.LeftClick);

Doing this pans the camera when i hold down the mouse wheel in stead of rotating it. The panning on left click works fine.

If I use MouseAction.WheelClick in stead of MouseAction.MiddleClick, then scrolling the mouse wheel will initiate the rotating as i move my mouse around, as I would like it to when i hold down the wheel, and only stops tracking the mouse and rotating when i click the mouse wheel. This also removes the zooming feature since it is apparently overwritten by this new gesture. Holding down the wheel and moving the mouse around still pans the camera.

If I use MouseAction.RightClick it works perfectly fine with the right mouse click, but as I said this feature needs to be implemented with the mouse wheel click and not the right click.

Note: Holding down the mouse wheel ALWAYS pans the camera.

Is there a way to rotate the camera with the mouse wheel click as was intended?

Another thing that's seemingly unrelated to my current problem but is very strange, when I double click the mouse wheel, regardless of the gestures, the camera jumps to some strange location and shifts to an awkward viewing angle. It always goes to the exact same position and angle regardless of where it was then the wheel was double clicked. Not sure if this has anything to do with my problem though.

Fish
  • 91
  • 7

2 Answers2

2

The HelixViewport3D object has 2 pan gesture properties, PanGesture and PandGesture2.

I'm not sure about this but from some experimenting the default PanGesture2 is the mouse wheel click, and there is no default PanGesture. So by doing:

viewport.PanGesture = new MouseGesture(MouseAction.LeftClick);
viewport.PanGesture2 = null;

the default gesture is overwritten and you can use the middle click for whatever you want without it panning.

Fish
  • 91
  • 7
0

For my laptop touchpad, I've put "viewport.RotateGesture" to left button and "viewport.PanGesture" to right button. There is no wheel click on a tochpad, only wheel zoom, which is connected to camera zoom. Until now I've used SimpleDemo from the toolkit as a basis for my Helix test apps, it exports each and every camera option to menus. Very handy to explore the Helix Camera.

When you need specific behaviour or gestures, or automate camera movement (swirling etc) you can set both to null and roll your own camera controller. You can control Helix camera by accessing it directly.

My Helix viewport in Xaml is named "view1", I can access the camera from MainWindow.Xaml.cs, and create a suitable one like this:

((MainViewModel)DataContext).InitializeCamera();           // set it up (see below)
this.view1.Camera =  ((MainViewModel)DataContext).Camera;  // connect to viewport
       

The viewmodel, creating a Camera for one of 2 animation sceneries,

    ... 

    public PerspectiveCamera Camera { get; set; }

    public void InitializeCamera()
    {
        Camera = new PerspectiveCamera()
        {
            UpDirection = new Vector3D(0, 0, 1),
            FieldOfView = 45,
        };
        if (Title.IndexOf("Traject") == 0)
            Camera.AnimateTo(new Point3D(-30, -50, 20), new Vector3D(0.4, 1, -0.3), new Vector3D(0, 0, 1), 2000.0);
        else
       if (Title.IndexOf("Coffee") == 0)
            Camera.AnimateTo(new Point3D(30, 9, 25), new Vector3D(-2, -0.3, -1.5), new Vector3D(0, 0, 1), 2000.0);
   }

My viewmodel also has a OnMoveCamera event which can be called by my animations to change the camera view direction to a certain Point3D. That event looks as follows

public void OnMoveCamera(Point3D plookat)
{
        camera?.ChangeDirection(plookat - camera.Position, camera.UpDirection, 2000.0);
}

The 2000.0 argument is milliseconds camera animation. If you want the camera to snap onto a new target, set it to 0.

Goodies
  • 1,951
  • 21
  • 26