/*!
    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();
    }
}
Beispiel #2
0
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);
    }
}
Beispiel #3
0
//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));
}