Using the navigation cube

../../_images/nav_cube.png

The 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 Overlay. To show the navigation cube in the view, call:

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 OverlayNavigationCube::updateHighlight() from the mouse move event.

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 OverlayNavigationCube::processSelection() to update navigation cube and camera orientation.

This can be done in the simples form:

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:

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

Location: Examples/Qt/QtDemoApp
A small Post Processor written in Qt to showcase some of the features in the
UnstructGrid component.

img_demo_wf

Location: Examples/WinForms/WinFormsDemoApp
A small Post Processor written in WinForms to showcase some of the features
in the UnstructGrid component.