void AppStage_HMDSettings::render()
{
    switch (m_menuState)
    {
    case eHmdMenuState::idle:
    {
        if (m_selectedHmdIndex >= 0)
        {
//            const OpenVRHmdInfo &hmdInfo = m_hmdInfos[m_selectedHmdIndex];

            //###HipsterSloth $TODO Render the model retrieved from OpenVR
            glm::mat4 scale3 = glm::scale(glm::mat4(1.f), glm::vec3(3.f, 3.f, 3.f));
            drawDK2Model(scale3);
        }
    }
    break;

    case eHmdMenuState::failedHmdListRequest:
    {
    } break;

    default:
        assert(0 && "unreachable");
    }
}
void AppStage_ComputeTrackerPoses::render()
{
    switch (m_menuState)
    {
    case eMenuState::inactive:
        break;
    case eMenuState::pendingControllerListRequest:
    case eMenuState::pendingControllerStartRequest:
    case eMenuState::pendingTrackerListRequest:
    case eMenuState::pendingTrackerStartRequest:
        break;
    case eMenuState::failedControllerListRequest:
    case eMenuState::failedControllerStartRequest:
    case eMenuState::failedTrackerListRequest:
    case eMenuState::failedTrackerStartRequest:
        break;
    case eMenuState::verifyHMD:
        {
            if (m_hmdView != nullptr)
            {
                PSMovePose pose = m_hmdView->getDisplayHmdPose();
                glm::quat orientation(pose.Orientation.w, pose.Orientation.x, pose.Orientation.y, pose.Orientation.z);
                glm::vec3 position(pose.Position.x, pose.Position.y, pose.Position.z);

                glm::mat4 rot = glm::mat4_cast(orientation);
                glm::mat4 trans = glm::translate(glm::mat4(1.0f), position);
                glm::mat4 transform = trans * rot;

                drawDK2Model(transform);
                drawTransformedAxes(transform, 10.f);
            }

            {
                PSMoveVolume volume;

                if (m_app->getOpenVRContext()->getHMDTrackingVolume(volume))
                {
                    drawTransformedVolume(glm::mat4(1.f), &volume, glm::vec3(0.f, 1.f, 1.f));
                }
            }
        } break;
    case eMenuState::verifyTrackers:
        {
            render_tracker_video();
        } break;
    case eMenuState::selectCalibrationType:
        break;
    case eMenuState::calibrateWithHMD:
        m_pCalibrateWithHMD->render();
        break;
    case eMenuState::calibrateWithMat:
        m_pCalibrateWithMat->render();
        break;
    case eMenuState::testTracking:
        {
            // Draw the origin axes
            drawTransformedAxes(glm::mat4(1.0f), 100.f);

            // Draw the HMD and tracking volume
            if (m_hmdView != nullptr)
            {
                // Compute a transform that goes from HMD tracking space to PSMove tracking space
                PSMovePose hmd_pose_at_origin = m_app->getOpenVRContext()->getHMDPoseAtPSMoveTrackingSpaceOrigin();
                glm::mat4 tracking_space_transform = psmove_pose_to_glm_mat4(hmd_pose_at_origin);
                glm::mat4 tracking_space_inv_transform = glm::inverse(tracking_space_transform);

                // Put the HMD transform in PSMove tracking space
                PSMovePose hmd_pose = m_hmdView->getDisplayHmdPose();
                glm::mat4 hmd_transform = tracking_space_inv_transform * psmove_pose_to_glm_mat4(hmd_pose);

                drawDK2Model(hmd_transform);
                drawTransformedAxes(hmd_transform, 10.f);

                PSMoveVolume volume;
                if (m_app->getOpenVRContext()->getHMDTrackingVolume(volume))
                {
                    drawTransformedVolume(tracking_space_inv_transform, &volume, glm::vec3(0.f, 1.f, 1.f));
                }
            }

            // Draw the frustum for each tracking camera
            for (t_tracker_state_map_iterator iter = m_trackerViews.begin(); iter != m_trackerViews.end(); ++iter)
            {
                const ClientTrackerView *trackerView = iter->second.trackerView;

                {
                    PSMoveFrustum frustum = trackerView->getTrackerFrustum();

                    drawFrustum(&frustum, k_psmove_frustum_color);
                }

                {
                    PSMovePose pose = trackerView->getTrackerPose();
                    glm::mat4 cameraTransform = psmove_pose_to_glm_mat4(pose);

                    drawTransformedAxes(cameraTransform, 20.f);
                }
            }

            // Draw the psmove model
            {
                PSMovePose pose = m_controllerView->GetPSMoveView().GetPose();
                glm::mat4 worldTransform = psmove_pose_to_glm_mat4(pose);

                drawPSMoveModel(worldTransform, glm::vec3(1.f, 1.f, 1.f));
                drawTransformedAxes(worldTransform, 10.f);
            }

        } break;
    case eMenuState::calibrateStepFailed:
        break;
    default:
        assert(0 && "unreachable");
    }
}