diff --git a/interface/resources/images/analog_stick.png b/interface/resources/images/analog_stick.png index e9457c7307..238c2c74f4 100644 Binary files a/interface/resources/images/analog_stick.png and b/interface/resources/images/analog_stick.png differ diff --git a/interface/resources/images/analog_stick_base.png b/interface/resources/images/analog_stick_base.png index 3b7b8aa8a9..ac8c1b9ae8 100644 Binary files a/interface/resources/images/analog_stick_base.png and b/interface/resources/images/analog_stick_base.png differ diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp index 1a1714ad56..010572fcf2 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.cpp @@ -11,6 +11,7 @@ #include <mutex> +#include <QScreen> #include <QtGui/QWindow> #include <QtGui/QGuiApplication> #include <QtWidgets/QAction> @@ -25,10 +26,14 @@ static const QString FULLSCREEN = "Fullscreen"; void Basic2DWindowOpenGLDisplayPlugin::customizeContext() { auto iconPath = PathUtils::resourcesPath() + "images/analog_stick.png"; auto image = QImage(iconPath); + qreal dpi = getFullscreenTarget()->physicalDotsPerInch(); + _virtualPadPixelSize = dpi * 512 / 534; // 534 dpi for Pixel XL and Mate 9 Pro + if (image.format() != QImage::Format_ARGB32) { image = image.convertToFormat(QImage::Format_ARGB32); } if ((image.width() > 0) && (image.height() > 0)) { + image = image.scaled(_virtualPadPixelSize, _virtualPadPixelSize, Qt::KeepAspectRatio); _virtualPadStickTexture = gpu::Texture::createStrict( gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA), @@ -49,6 +54,8 @@ void Basic2DWindowOpenGLDisplayPlugin::customizeContext() { image = image.convertToFormat(QImage::Format_ARGB32); } if ((image.width() > 0) && (image.height() > 0)) { + image = image.scaled(_virtualPadPixelSize, _virtualPadPixelSize, Qt::KeepAspectRatio); + _virtualPadStickBaseTexture = gpu::Texture::createStrict( gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA), image.width(), image.height(), @@ -91,7 +98,8 @@ void Basic2DWindowOpenGLDisplayPlugin::compositeExtra() { auto& virtualPadManager = VirtualPad::Manager::instance(); if(virtualPadManager.getLeftVirtualPad()->isBeingTouched()) { // render stick base - auto stickBaseTransform = DependencyManager::get<CompositorHelper>()->getPoint2DTransform(virtualPadManager.getLeftVirtualPad()->getFirstTouch()); + auto stickBaseTransform = DependencyManager::get<CompositorHelper>()->getPoint2DTransform(virtualPadManager.getLeftVirtualPad()->getFirstTouch(), + _virtualPadPixelSize, _virtualPadPixelSize); render([&](gpu::Batch& batch) { batch.enableStereo(false); batch.setProjectionTransform(mat4()); @@ -103,7 +111,8 @@ void Basic2DWindowOpenGLDisplayPlugin::compositeExtra() { batch.draw(gpu::TRIANGLE_STRIP, 4); }); // render stick head - auto stickTransform = DependencyManager::get<CompositorHelper>()->getPoint2DTransform(virtualPadManager.getLeftVirtualPad()->getCurrentTouch()); + auto stickTransform = DependencyManager::get<CompositorHelper>()->getPoint2DTransform(virtualPadManager.getLeftVirtualPad()->getCurrentTouch(), + _virtualPadPixelSize, _virtualPadPixelSize); render([&](gpu::Batch& batch) { batch.enableStereo(false); batch.setProjectionTransform(mat4()); diff --git a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h index d9b942bd97..04568dcb27 100644 --- a/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h +++ b/libraries/display-plugins/src/display-plugins/Basic2DWindowOpenGLDisplayPlugin.h @@ -44,4 +44,5 @@ private: gpu::TexturePointer _virtualPadStickTexture; gpu::TexturePointer _virtualPadStickBaseTexture; + qreal _virtualPadPixelSize; }; diff --git a/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp b/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp index 74225b5b39..fb53ca253f 100644 --- a/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp +++ b/libraries/display-plugins/src/display-plugins/CompositorHelper.cpp @@ -458,9 +458,8 @@ glm::mat4 CompositorHelper::getReticleTransform(const glm::mat4& eyePose, const return result; } -glm::mat4 CompositorHelper::getPoint2DTransform(const glm::vec2& point) const { +glm::mat4 CompositorHelper::getPoint2DTransform(const glm::vec2& point, float sizeX, float sizeY) const { glm::mat4 result; - static const float PIXEL_SIZE = 512.0f; const auto canvasSize = vec2(toGlm(_renderingWidget->size()));; QPoint qPoint(point.x,point.y); vec2 position = toGlm(_renderingWidget->mapFromGlobal(qPoint)); @@ -469,7 +468,7 @@ glm::mat4 CompositorHelper::getPoint2DTransform(const glm::vec2& point) const { position -= 1.0; position.y *= -1.0f; - vec2 size = PIXEL_SIZE / canvasSize; + vec2 size = vec2(sizeX / canvasSize.x, sizeY / canvasSize.y); result = glm::scale(glm::translate(glm::mat4(), vec3(position, 0.0f)), vec3(size, 1.0f)); return result; } diff --git a/libraries/display-plugins/src/display-plugins/CompositorHelper.h b/libraries/display-plugins/src/display-plugins/CompositorHelper.h index 5b65315f45..234818c740 100644 --- a/libraries/display-plugins/src/display-plugins/CompositorHelper.h +++ b/libraries/display-plugins/src/display-plugins/CompositorHelper.h @@ -90,7 +90,7 @@ public: glm::vec2 getReticleMaximumPosition() const; glm::mat4 getReticleTransform(const glm::mat4& eyePose = glm::mat4(), const glm::vec3& headPosition = glm::vec3()) const; - glm::mat4 getPoint2DTransform(const glm::vec2& point = glm::vec2()) const; + glm::mat4 getPoint2DTransform(const glm::vec2& point = glm::vec2(), float sizeX = 512.0f, float sizeY = 512.0f) const; ReticleInterface* getReticleInterface() { return _reticleInterface; } diff --git a/libraries/input-plugins/src/input-plugins/TouchscreenVirtualPadDevice.cpp b/libraries/input-plugins/src/input-plugins/TouchscreenVirtualPadDevice.cpp index 53683870df..40bc341fe2 100644 --- a/libraries/input-plugins/src/input-plugins/TouchscreenVirtualPadDevice.cpp +++ b/libraries/input-plugins/src/input-plugins/TouchscreenVirtualPadDevice.cpp @@ -22,6 +22,8 @@ #include <NumericalConstants.h> #include "VirtualPadManager.h" +#include <cmath> + const char* TouchscreenVirtualPadDevice::NAME = "TouchscreenVirtualPad"; bool TouchscreenVirtualPadDevice::isSupported() const { @@ -37,6 +39,21 @@ bool TouchscreenVirtualPadDevice::isSupported() const { return false; } +void TouchscreenVirtualPadDevice::initFromEvent(const QTouchEvent* event) { + QScreen* eventScreen = event->window()->screen(); + if (_screenDPI != eventScreen->physicalDotsPerInch()) { + _screenWidthCenter = eventScreen->size().width() / 2; + _screenDPIScale.x = (float)eventScreen->physicalDotsPerInchX(); + _screenDPIScale.y = (float)eventScreen->physicalDotsPerInchY(); + _screenDPI = eventScreen->physicalDotsPerInch(); + + _fixedPosition = true; // This should be config + _fixedRadius = _screenDPI * 256 / 534; + qreal margin = _screenDPI * 59 / 534; // 59px is for our 'base' of 534dpi (Pixel XL or Huawei Mate 9 Pro) + _fixedCenterPosition = glm::vec2( _fixedRadius + margin, eventScreen->size().height() - margin - _fixedRadius ); + } +} + float clip(float n, float lower, float upper) { return std::max(lower, std::min(n, upper)); } @@ -132,13 +149,7 @@ void TouchscreenVirtualPadDevice::touchBeginEvent(const QTouchEvent* event) { return; } KeyboardMouseDevice::enableTouch(false); - QScreen* eventScreen = event->window()->screen(); - _screenWidthCenter = eventScreen->size().width() / 2; - if (_screenDPI != eventScreen->physicalDotsPerInch()) { - _screenDPIScale.x = (float)eventScreen->physicalDotsPerInchX(); - _screenDPIScale.y = (float)eventScreen->physicalDotsPerInchY(); - _screenDPI = eventScreen->physicalDotsPerInch(); - } + initFromEvent(event); } void TouchscreenVirtualPadDevice::touchEndEvent(const QTouchEvent* event) { @@ -169,14 +180,13 @@ void TouchscreenVirtualPadDevice::touchUpdateEvent(const QTouchEvent* event) { bool rightTouchFound = false; for (int i = 0; i < _touchPointCount; ++i) { glm::vec2 thisPoint(tPoints[i].pos().x(), tPoints[i].pos().y()); - if (thisPoint.x < _screenWidthCenter) { + if (_validTouchLeft) { + leftTouchFound = true; + touchLeftUpdate(thisPoint); + } else if (touchLeftBeginPointIsValid(thisPoint)) { if (!leftTouchFound) { leftTouchFound = true; - if (!_validTouchLeft) { - touchLeftBegin(thisPoint); - } else { - touchLeftUpdate(thisPoint); - } + touchLeftBegin(thisPoint); } } else { if (!rightTouchFound) { @@ -197,10 +207,24 @@ void TouchscreenVirtualPadDevice::touchUpdateEvent(const QTouchEvent* event) { } } +bool TouchscreenVirtualPadDevice::touchLeftBeginPointIsValid(glm::vec2 touchPoint) { + if (_fixedPosition) { + // inside circle + return pow(touchPoint.x - _fixedCenterPosition.x,2.0) + pow(touchPoint.y - _fixedCenterPosition.y, 2.0) < pow(_fixedRadius, 2.0); + } else { + // left side + return touchPoint.x < _screenWidthCenter; + } +} + void TouchscreenVirtualPadDevice::touchLeftBegin(glm::vec2 touchPoint) { auto& virtualPadManager = VirtualPad::Manager::instance(); if (virtualPadManager.isEnabled()) { - _firstTouchLeftPoint = touchPoint; + if (_fixedPosition) { + _firstTouchLeftPoint = _fixedCenterPosition; + } else { + _firstTouchLeftPoint = touchPoint; + } _validTouchLeft = true; } } diff --git a/libraries/input-plugins/src/input-plugins/TouchscreenVirtualPadDevice.h b/libraries/input-plugins/src/input-plugins/TouchscreenVirtualPadDevice.h index fd74009ee8..fd2342bfec 100644 --- a/libraries/input-plugins/src/input-plugins/TouchscreenVirtualPadDevice.h +++ b/libraries/input-plugins/src/input-plugins/TouchscreenVirtualPadDevice.h @@ -74,15 +74,21 @@ protected: int _screenWidthCenter; std::shared_ptr<InputDevice> _inputDevice { std::make_shared<InputDevice>() }; + bool _fixedPosition; + glm::vec2 _fixedCenterPosition; + qreal _fixedRadius; + void touchLeftBegin(glm::vec2 touchPoint); void touchLeftUpdate(glm::vec2 touchPoint); void touchLeftEnd(); + bool touchLeftBeginPointIsValid(glm::vec2 touchPoint); void touchRightBegin(glm::vec2 touchPoint); void touchRightUpdate(glm::vec2 touchPoint); void touchRightEnd(); // just for debug private: void debugPoints(const QTouchEvent* event, QString who); + void initFromEvent(const QTouchEvent* event); };