.. _nav-cube-page:

#########################
Using the Navigation Cube
#########################

.. image:: ../../images/nav_cube.png

The :class:`OverlayNavigationCube <cee::vis::OverlayNavigationCube>` is a navigation tool to be positioned in a corner 
and aids with model interaction. The navigation cube will always show the orientation of the camera and provides a 
simple and interactive way of navigating the view.

To utilize the navigation cube feature, it must be setup and connected to the mouse events in the viewer. 

The navigation cube is an overlay item and is managed through the views :class:`Overlay <cee::vis::Overlay>`. To show 
the navigation cube in the view, call:

.. code-block:: cpp

    m_overlayNavigationCube = new cee::vis::OverlayNavigationCube(&view()->camera(), cee::vis::Font::createNormalFont().get());
    view()->overlay().addItem(m_overlayNavigationCube.get(), cee::vis::OverlayItem::BOTTOM_LEFT, cee::vis::OverlayItem::HORIZONTAL);

When the mouse cursor hovers over the navigation cube, the corresponding face, edge, corner or arrow can be highlighted. 
To sync this with mouse movements, you need to call 
:func:`OverlayNavigationCube::updateHighlight() <cee::vis::OverlayNavigationCube::updateHighlight>` from the mouse move 
event.

.. code-block:: cpp

    void ViewerWidget::mouseMoveEvent(QMouseEvent* event)
    {
        ...
        if (mouseButtonsDown == Qt::NoButton) // No mousebutton pressed
        {
            if (m_overlayNavigationCube->updateHighlight(me.x(), me.y(), *view()))
            {
                update();
            }
        }
        ...
    }

When the user click on a face, edge, corder or arrow on the navigation cube, the navigation cube will readjust 
accordingly and the camera orientation must be synchronized. Call 
:func:`OverlayNavigationCube::processSelection() <cee::vis::OverlayNavigationCube::processSelection>` to update 
navigation cube and camera orientation.

This can be done in the simples form:

.. code-block:: cpp

    void ViewerWidget::mouseReleaseEvent(QMouseEvent* event)
    {
        ...
        if (buttonClick == Qt::LeftButton) 
        {
            cee::Vec3d newViewDir;
            cee::Vec3d newUp;
            if (m_overlayNavigationCube->processSelection(me.x(), me.y(), *view(), &newViewDir, &newUp))
            {
                cee::BoundingBox boundingBox = view()->boundingBox();
                cee::Vec3d newEye = view()->camera().computeFitViewEyePosition(boundingBox, newViewDir, newUp);

                m_view.camera().setFromLookAt(newEye, newViewDir, newUp);
            }
        }
        ...
    }

Or fancier, using camera animation:

.. code-block:: cpp

    void ViewerWidget::mouseReleaseEvent(QMouseEvent* event)
    {
        ...
        if (buttonClick == Qt::LeftButton)
        {
            cee::Vec3d newViewDir;
            cee::Vec3d newUp;
            if (m_overlayNavigationCube->processSelection(me.x(), me.y(), *view(), &newViewDir, &newUp))
            {
                cee::BoundingBox boundingBox = view()->boundingBox();
                cee::Vec3d newEye = view()->camera().computeFitViewEyePosition(boundingBox, newViewDir, newUp);

                cee::vis::CameraAnimation anim(&view()->camera(), newEye, newViewDir, newUp);
                anim.setTargetOrthoHeight(boundingBox.radius() * 2.0);
                anim.setTargetFieldOfViewYDegrees(40.0);
                anim.setDuration(0.4f);

                while (anim.updateCamera())
                {
                    repaint();
                }
            }
        }
        ...
    }

**See the demo apps for example code**

.. |img_demo_qt| image:: ../../images/example_qt_demoapp.png
   :width: 150

.. |img_demo_wf| image:: ../../images/example_winforms_demoapp.png
   :width: 150

+-----------------------+------------------------------------------------------------------------------------+
| |img_demo_qt|         | **Location**\ : Examples/Qt/QtDemoApp |br|                                         |
|                       | A small Post Processor written in Qt to showcase some of the features in the  |br| |
|                       | UnstructGrid component.                                                            |
+-----------------------+------------------------------------------------------------------------------------+
| |img_demo_wf|         | **Location**\ : Examples/WinForms/WinFormsDemoApp |br|                             |
|                       | A small Post Processor written in WinForms to showcase some of the features   |br| |
|                       | in the UnstructGrid component.                                                     |
+-----------------------+------------------------------------------------------------------------------------+
