Esempio n. 1
0
bool checkMinSpecImpl() {
    // If OpenVR isn't supported, we have no min spec, so pass
    if (!openVrSupported()) {
        return true;
    }

    // If we have at least MIN_CORES_SPEC cores, pass
    auto coreCount = QThread::idealThreadCount();
    if (coreCount >= MIN_CORES_SPEC) {
        return true;
    }

    // Even if we have too few cores... if the compositor is using async reprojection, pass
    auto system = acquireOpenVrSystem();
    auto compositor = vr::VRCompositor();
    if (system && compositor) {
        vr::Compositor_FrameTiming timing;
        memset(&timing, 0, sizeof(timing));
        timing.m_nSize = sizeof(vr::Compositor_FrameTiming);
        compositor->GetFrameTiming(&timing);
        releaseOpenVrSystem();
        if (timing.m_nReprojectionFlags & VRCompositor_ReprojectionAsync) {
            return true;
        }
    }

    // We're using OpenVR and we don't have enough cores...
    showMinSpecWarning();

    return false;
}
Esempio n. 2
0
void OpenVrDisplayPlugin::activate() {
    _container->setIsOptionChecked(StandingHMDSensorMode, true);

    if (!_system) {
        _system = acquireOpenVrSystem();
    }
    Q_ASSERT(_system);

    _system->GetRecommendedRenderTargetSize(&_renderTargetSize.x, &_renderTargetSize.y);
    // Recommended render target size is per-eye, so double the X size for 
    // left + right eyes
    _renderTargetSize.x *= 2;

    {
        Lock lock(_poseMutex);
        openvr_for_each_eye([&](vr::Hmd_Eye eye) {
            _eyeOffsets[eye] = toGlm(_system->GetEyeToHeadTransform(eye));
            _eyeProjections[eye] = toGlm(_system->GetProjectionMatrix(eye, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, vr::API_OpenGL));
        });
        // FIXME Calculate the proper combined projection by using GetProjectionRaw values from both eyes
        _cullingProjection = _eyeProjections[0];

    }

    _compositor = vr::VRCompositor();
    Q_ASSERT(_compositor);
    HmdDisplayPlugin::activate();
}
Esempio n. 3
0
void showMinSpecWarning() {
    auto vrSystem = acquireOpenVrSystem();
    auto vrOverlay = vr::VROverlay();
    if (!vrOverlay) {
        qFatal("Unable to initialize SteamVR overlay manager");
    }

    vr::VROverlayHandle_t minSpecFailedOverlay = 0;
    if (vr::VROverlayError_None != vrOverlay->CreateOverlay(FAILED_MIN_SPEC_OVERLAY_NAME, FAILED_MIN_SPEC_OVERLAY_FRIENDLY_NAME, &minSpecFailedOverlay)) {
        qFatal("Unable to create overlay");
    }

    // Needed here for PathUtils
    QCoreApplication miniApp(__argc, __argv);

    vrSystem->ResetSeatedZeroPose();
    QString imagePath = PathUtils::resourcesPath() + "/images/steam-min-spec-failed.png";
    vrOverlay->SetOverlayFromFile(minSpecFailedOverlay, imagePath.toLocal8Bit().toStdString().c_str());
    vrOverlay->SetHighQualityOverlay(minSpecFailedOverlay);
    vrOverlay->SetOverlayWidthInMeters(minSpecFailedOverlay, 1.4f);
    vrOverlay->SetOverlayInputMethod(minSpecFailedOverlay, vr::VROverlayInputMethod_Mouse);
    vrOverlay->ShowOverlay(minSpecFailedOverlay);

    QTimer* timer = new QTimer(&miniApp);
    timer->setInterval(FAILED_MIN_SPEC_UPDATE_INTERVAL_MS); // Qt::CoarseTimer acceptable, we don't need this to be frame rate accurate
    QObject::connect(timer, &QTimer::timeout, [&] {
        vr::TrackedDevicePose_t vrPoses[vr::k_unMaxTrackedDeviceCount];
        vrSystem->GetDeviceToAbsoluteTrackingPose(vr::TrackingUniverseSeated, 0, vrPoses, vr::k_unMaxTrackedDeviceCount);
        auto headPose = toGlm(vrPoses[vr::k_unTrackedDeviceIndex_Hmd].mDeviceToAbsoluteTracking);
        auto overlayPose = toOpenVr(headPose * glm::translate(glm::mat4(), vec3(0, 0, -1)));
        vrOverlay->SetOverlayTransformAbsolute(minSpecFailedOverlay, vr::TrackingUniverseSeated, &overlayPose);

        vr::VREvent_t event;
        while (vrSystem->PollNextEvent(&event, sizeof(event))) {
            switch (event.eventType) {
                case vr::VREvent_Quit:
                    vrSystem->AcknowledgeQuit_Exiting();
                    QCoreApplication::quit();
                    break;

                case vr::VREvent_ButtonPress:
                    // Quit on any button press except for 'putting on the headset'
                    if (event.data.controller.button != vr::k_EButton_ProximitySensor) {
                        QCoreApplication::quit();
                    }
                    break;

                default:
                    break;
            }
        }

    });
    timer->start();

    QTimer::singleShot(FAILED_MIN_SPEC_AUTO_QUIT_INTERVAL_MS, &miniApp, &QCoreApplication::quit);
    miniApp.exec();
}
Esempio n. 4
0
bool OpenVrDisplayPlugin::internalActivate() {
    Parent::internalActivate();

    _container->setIsOptionChecked(StandingHMDSensorMode, true);

    if (!_system) {
        _system = acquireOpenVrSystem();
    }
    if (!_system) {
        qWarning() << "Failed to initialize OpenVR";
        return false;
    }

    _system->GetRecommendedRenderTargetSize(&_renderTargetSize.x, &_renderTargetSize.y);
    // Recommended render target size is per-eye, so double the X size for 
    // left + right eyes
    _renderTargetSize.x *= 2;

    {
        Lock lock(_poseMutex);
        openvr_for_each_eye([&](vr::Hmd_Eye eye) {
            _eyeOffsets[eye] = toGlm(_system->GetEyeToHeadTransform(eye));
            _eyeProjections[eye] = toGlm(_system->GetProjectionMatrix(eye, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, vr::API_OpenGL));
        });
        // FIXME Calculate the proper combined projection by using GetProjectionRaw values from both eyes
        _cullingProjection = _eyeProjections[0];

    }

    _compositor = vr::VRCompositor();
    Q_ASSERT(_compositor);

    // enable async time warp
    // _compositor->ForceInterleavedReprojectionOn(true);

    // set up default sensor space such that the UI overlay will align with the front of the room.
    auto chaperone = vr::VRChaperone();
    if (chaperone) {
        float const UI_RADIUS = 1.0f;
        float const UI_HEIGHT = 1.6f;
        float const UI_Z_OFFSET = 0.5;

        float xSize, zSize;
        chaperone->GetPlayAreaSize(&xSize, &zSize);
        glm::vec3 uiPos(0.0f, UI_HEIGHT, UI_RADIUS - (0.5f * zSize) - UI_Z_OFFSET);
        _sensorResetMat = glm::inverse(createMatFromQuatAndPos(glm::quat(), uiPos));
    } else {
        qDebug() << "OpenVR: error could not get chaperone pointer";
    }

    return true;
}
Esempio n. 5
0
void OpenVrDisplayPlugin::activate() {
    _container->setIsOptionChecked(StandingHMDSensorMode, true);

    if (!_hmd) {
        _hmd = acquireOpenVrSystem();
    }
    Q_ASSERT(_hmd);

    _hmd->GetRecommendedRenderTargetSize(&_renderTargetSize.x, &_renderTargetSize.y);
    // Recommended render target size is per-eye, so double the X size for 
    // left + right eyes
    _renderTargetSize.x *= 2;
    openvr_for_each_eye([&](vr::Hmd_Eye eye) {
        PerEyeData& eyeData = _eyesData[eye];
        eyeData._projectionMatrix = toGlm(_hmd->GetProjectionMatrix(eye, DEFAULT_NEAR_CLIP, DEFAULT_FAR_CLIP, vr::API_OpenGL));
        eyeData._eyeOffset = toGlm(_hmd->GetEyeToHeadTransform(eye));
    });
    _compositor = vr::VRCompositor();
    Q_ASSERT(_compositor);
    WindowOpenGLDisplayPlugin::activate();
}
Esempio n. 6
0
bool OpenVrDisplayPlugin::isSupported() const {
    auto hmd = acquireOpenVrSystem();
    bool success = nullptr != hmd;
    releaseOpenVrSystem();
    return success;
}