/*! This slot is used to recieve signals from the QDownloadManager class which provides Url download capability across the network. A successful download will have a valid QByteArray stored in \a assetData, while a failed download (due to network error, etc), will result in a NULL value. Successful downloads use the image data downloaded into \a assetData, which is converted to an image/texture, and emit a textureUpdated() signal. \sa QDownloadManager */ void QGLTexture2D::textureRequestFinished(QByteArray assetData) { //Ensure valid asset data exists. if (assetData.isEmpty()) { qWarning("Network request failed. Texture not loaded."); } else { //Convert asset data to an image. QImage texImage; texImage.loadFromData(assetData); setImage(texImage.mirrored()); emit textureUpdated(); } }
void QGLMaterial::setTextureUrl(const QUrl &url, int layer) { Q_ASSERT(layer >= 0); if (textureUrl(layer) != url) { QGLTexture2D *tex = 0; if (!url.isEmpty()) { tex = new QGLTexture2D(this); connect(tex, SIGNAL(textureUpdated()), this, SIGNAL(texturesChanged())); tex->setUrl(url); } setTexture(tex, layer); } }
//TODO: This is ugly and hacky and needs to get refactored void OverlayManager::asyncUpdate() { boost::lock_guard<boost::mutex> guard(mtx_); vr::TrackedDeviceIndex_t controller1 = -1; vr::TrackedDeviceIndex_t controller2 = -1; vr::VRControllerState_t hmdState; vr::VRControllerState_t controller1State; vr::VRControllerState_t controller2State; vr::TrackedDevicePose_t hmdPose; vr::TrackedDevicePose_t controller1Pose; vr::TrackedDevicePose_t controller2Pose; vr::HmdMatrix34_t overlayTransform; vr::HmdVector2_t overlayCenter; vr::ETrackingUniverseOrigin origin; unsigned int width, height; //Find the controllers vr::IVRSystem* vrSys = vr::VRSystem(); vr::IVRCompositor* vrComp = vr::VRCompositor(); vr::IVROverlay* vrOvrly = vr::VROverlay(); for (int i = 0; i < vr::k_unMaxTrackedDeviceCount; i++) { switch (vrSys->GetTrackedDeviceClass(i)) { case vr::TrackedDeviceClass_Controller: if (controller1 == -1) { controller1 = i; } if (controller1 >= 0 && i !=controller1) { controller2 = i; } if (controller2 >= 0) { break; } } } int count = 0; for (std::vector<std::shared_ptr<Overlay>>::iterator it = m_overlayVec.begin(); it != m_overlayVec.end(); ++it) { if (vrSys && controller1 >= 0 && (*it)->isVisible()) { //Set padding of the overlay based on scale float padding = 0.5f * ((float)(*it)->getScale() / 100.0f); float z_padding = 0.1f; //Get the controller pose information relative to tracking space vrSys->GetControllerStateWithPose(vrComp->GetTrackingSpace(), controller1, &controller1State, sizeof(controller1State), &controller1Pose); vrSys->GetControllerStateWithPose(vrComp->GetTrackingSpace(), controller2, &controller2State, sizeof(controller2State), &controller2Pose); vrSys->GetControllerStateWithPose(vrComp->GetTrackingSpace(), vr::k_unTrackedDeviceIndex_Hmd, &hmdState, sizeof(hmdState), &hmdPose); //Center of the overlay adjusted for scale overlayCenter.v[0] = 0.5f;// * ((float)(*it)->getScale() / 100.0f); overlayCenter.v[1] = 0.5f;// * ((float)(*it)->getScale() / 100.0f); //Get the overlay transform relative to tracking space vr::EVROverlayError err = vr::VROverlayError_None; if (err = vrOvrly->GetTransformForOverlayCoordinates((*it)->getOverlayHandle(), vrComp->GetTrackingSpace(), overlayCenter, &overlayTransform)) { DBOUT("Error with overlay!!" << err << std::endl); } //Converts Controller world tracking transform matrix to a transform matrix relative to the overlay Eigen::Transform<float, 3, Eigen::Affine> controller1Transform; Eigen::Transform<float, 3, Eigen::Affine> controller2Transform; Eigen::Transform<float, 3, Eigen::Affine> overlayTrans; for (int i = 0; i < 3; ++i) { for (int j = 0; j < 4; ++j) { controller1Transform(i, j) = controller1Pose.mDeviceToAbsoluteTracking.m[i][j]; controller2Transform(i, j) = controller2Pose.mDeviceToAbsoluteTracking.m[i][j]; overlayTrans(i, j) = overlayTransform.m[i][j]; } } Eigen::Matrix<float, 4, 4> overlayInverse = overlayTrans.matrix().inverse(); Eigen::Matrix<float, 4, 4> controller1OverlayTransform = overlayInverse * controller1Transform.matrix(); Eigen::Matrix<float, 4, 4> controller2OverlayTransform = overlayInverse * controller2Transform.matrix(); //Boolean values for if the controller is within the bounds of the overlay based on the padding //z-padding is used for the depth across the face of the overlay bool controller1InOverlay = (controller1OverlayTransform(0, 3) < padding && controller1OverlayTransform(0, 3) > -padding) && (controller1OverlayTransform(1, 3) < padding && controller1OverlayTransform(1, 3) > -padding) && (controller1OverlayTransform(2, 3) < z_padding && controller1OverlayTransform(2, 3) > -z_padding); bool controller2InOverlay = (controller2OverlayTransform(0, 3) < padding && controller2OverlayTransform(0, 3) > -padding) && (controller2OverlayTransform(1, 3) < padding && controller2OverlayTransform(1, 3) > -padding) && (controller2OverlayTransform(2, 3) < z_padding && controller2OverlayTransform(2, 3) > -z_padding);; //If the controller is within the bounds the center of the overlay if (controller1InOverlay || controller2InOverlay) { //Buzz controller -- Not working fix vr::VRSystem()->TriggerHapticPulse(controller1, 2, 2000); if (controller1InOverlay && (*it)->getTracking() != 2) { //If controller1 is not currently tracking and controller2 isn't tracking overlay if(controller1State.rAxis[1].x > 0.75f && (m_controller1Tracking == NULL || m_controller1Tracking == (*it).get()) && m_controller2Tracking != (*it).get()) { TrackingUpdate(it, controller1State, controller1Pose, controller1InOverlay, vrSys, vrComp); m_controller1Tracking = (*it).get(); emit textureUpdated(count); } //If trigger is released and was tracking, reset pointer to null; if (controller1State.rAxis[1].x < 0.75f && m_controller1Tracking != NULL) { m_controller1Tracking = NULL; } //If touchpad is pressed in overlay w/ debounce check if (((controller1State.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_SteamVR_Touchpad)) == vr::ButtonMaskFromId(vr::k_EButton_SteamVR_Touchpad)) && !m_controller1TouchPressed) { m_controller1TouchPressed = true; //bottom left - decrease opacity if (controller1State.rAxis[0].x < 0 && controller1State.rAxis[0].y < 0) (*it)->setTransparancy((*it)->getTransparancy() - 5); //bottom right - increase opacity if (controller1State.rAxis[0].x > 0 && controller1State.rAxis[0].y < 0) (*it)->setTransparancy((*it)->getTransparancy() + 5); //top left - decrease scale if (controller1State.rAxis[0].x < 0 && controller1State.rAxis[0].y > 0) (*it)->setScale((*it)->getScale() - 5); //top right - increase scale if (controller1State.rAxis[0].x > 0 && controller1State.rAxis[0].y > 0) (*it)->setScale((*it)->getScale() + 5); emit textureUpdated(count); } else if (((controller1State.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_SteamVR_Touchpad)) != vr::ButtonMaskFromId(vr::k_EButton_SteamVR_Touchpad)) && m_controller1TouchPressed) { m_controller1TouchPressed = false; } //If SideButton is pressed else if (((controller1State.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_Grip)) == vr::ButtonMaskFromId(vr::k_EButton_Grip)) && !m_controller1GripPressed) { m_controller1GripPressed = true; (*it)->setTracking(((*it)->getTracking() + 1) % 4); emit textureUpdated(count); } else if (((controller1State.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_Grip)) != vr::ButtonMaskFromId(vr::k_EButton_Grip)) && m_controller1GripPressed) { m_controller1GripPressed = false; } } if (controller2InOverlay && (*it)->getTracking() != 3) { //If controller2 is not currently tracking and controller1 isn't tracking overlay if (controller2State.rAxis[1].x > 0.75f && (m_controller2Tracking == NULL || m_controller2Tracking == (*it).get()) && m_controller1Tracking != (*it).get()) { TrackingUpdate(it, controller2State, controller2Pose, controller2InOverlay, vrSys, vrComp); m_controller2Tracking = (*it).get(); emit textureUpdated(count); } if (controller2State.rAxis[1].x < 0.75f && m_controller2Tracking != NULL) { m_controller2Tracking = NULL; } //If touchpad is pressed in overlay w/ debounce check if (((controller2State.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_SteamVR_Touchpad)) == vr::ButtonMaskFromId(vr::k_EButton_SteamVR_Touchpad)) && !m_controller2TouchPressed) { m_controller2TouchPressed = true; //bottom left - decrease opacity if (controller2State.rAxis[0].x < 0 && controller2State.rAxis[0].y < 0) (*it)->setTransparancy((*it)->getTransparancy() - 5); //bottom right - increase opacity if (controller2State.rAxis[0].x > 0 && controller2State.rAxis[0].y < 0) (*it)->setTransparancy((*it)->getTransparancy() + 5); //top left - decrease scale if (controller2State.rAxis[0].x < 0 && controller2State.rAxis[0].y > 0) (*it)->setScale((*it)->getScale() - 5); //top right - increase scale if (controller2State.rAxis[0].x > 0 && controller2State.rAxis[0].y > 0) (*it)->setScale((*it)->getScale() + 5); emit textureUpdated(count); } else if (((controller2State.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_SteamVR_Touchpad)) != vr::ButtonMaskFromId(vr::k_EButton_SteamVR_Touchpad)) && m_controller2TouchPressed) { m_controller2TouchPressed = false; } //If SideButton is pressed else if (((controller2State.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_Grip)) == vr::ButtonMaskFromId(vr::k_EButton_Grip)) && !m_controller2GripPressed) { m_controller2GripPressed = true; (*it)->setTracking(((*it)->getTracking() + 1) % 4); } else if (((controller2State.ulButtonPressed & vr::ButtonMaskFromId(vr::k_EButton_Grip)) != vr::ButtonMaskFromId(vr::k_EButton_Grip)) && m_controller2GripPressed) { m_controller2GripPressed = false; } } } //end controller in overlay if check } //end VR check if count++; } //end iterator loop for overlays m_timer.expires_from_now(boost::posix_time::milliseconds(5)); m_timer.async_wait(boost::bind(&OverlayManager::asyncUpdate, this)); }