mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 08:21:24 +02:00
Support for multiple oculus overlay magnifiers
This commit is contained in:
parent
762751ef6a
commit
18543ff313
2 changed files with 139 additions and 121 deletions
|
@ -16,6 +16,7 @@
|
||||||
|
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "ApplicationOverlay.h"
|
#include "ApplicationOverlay.h"
|
||||||
|
#include "devices/OculusManager.h"
|
||||||
|
|
||||||
#include "ui/Stats.h"
|
#include "ui/Stats.h"
|
||||||
|
|
||||||
|
@ -35,7 +36,7 @@ ApplicationOverlay::~ApplicationOverlay() {
|
||||||
|
|
||||||
const float WHITE_TEXT[] = { 0.93f, 0.93f, 0.93f };
|
const float WHITE_TEXT[] = { 0.93f, 0.93f, 0.93f };
|
||||||
|
|
||||||
void renderControllerPointer() {
|
void ApplicationOverlay::renderControllerPointer() {
|
||||||
Application* application = Application::getInstance();
|
Application* application = Application::getInstance();
|
||||||
QGLWidget* glWidget = application->getGLWidget();
|
QGLWidget* glWidget = application->getGLWidget();
|
||||||
MyAvatar* myAvatar = application->getAvatar();
|
MyAvatar* myAvatar = application->getAvatar();
|
||||||
|
@ -60,7 +61,7 @@ void renderControllerPointer() {
|
||||||
if (handData->getPalms()[palmIndex].isActive()) {
|
if (handData->getPalms()[palmIndex].isActive()) {
|
||||||
palmData = &handData->getPalms()[palmIndex];
|
palmData = &handData->getPalms()[palmIndex];
|
||||||
} else {
|
} else {
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get directon relative to avatar orientation
|
// Get directon relative to avatar orientation
|
||||||
|
@ -75,24 +76,25 @@ void renderControllerPointer() {
|
||||||
int mouseX = cursorRange * xAngle;
|
int mouseX = cursorRange * xAngle;
|
||||||
int mouseY = cursorRange * yAngle;
|
int mouseY = cursorRange * yAngle;
|
||||||
|
|
||||||
if (mouseX < 0) {
|
if (mouseX < 0 || mouseX >= glWidget->width() || mouseY < 0 || mouseY >= glWidget->height()) {
|
||||||
//mouseX = 0;
|
|
||||||
continue;
|
|
||||||
} else if (mouseX > glWidget->width()) {
|
|
||||||
//mouseX = glWidget->width();
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (mouseY < 0) {
|
|
||||||
//mouseY = 0;
|
|
||||||
continue;
|
|
||||||
} else if (mouseY > glWidget->width()) {
|
|
||||||
//mouseY = glWidget->width();
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
const float pointerWidth = 40;
|
float pointerWidth = 40;
|
||||||
const float pointerHeight = 40;
|
float pointerHeight = 40;
|
||||||
const float crossPad = 16;
|
float crossPad = 16;
|
||||||
|
//if we have the oculus, we should make the cursor smaller since it will be
|
||||||
|
//magnified
|
||||||
|
if (OculusManager::isConnected()) {
|
||||||
|
pointerWidth /= 4;
|
||||||
|
pointerHeight /= 4;
|
||||||
|
crossPad /= 4;
|
||||||
|
|
||||||
|
_mouseX[_numMagnifiers] = mouseX;
|
||||||
|
_mouseY[_numMagnifiers] = mouseY;
|
||||||
|
_numMagnifiers++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
mouseX -= pointerWidth / 2.0f;
|
mouseX -= pointerWidth / 2.0f;
|
||||||
mouseY += pointerHeight / 2.0f;
|
mouseY += pointerHeight / 2.0f;
|
||||||
|
@ -131,6 +133,8 @@ void ApplicationOverlay::renderOverlay(bool renderToTexture) {
|
||||||
BandwidthMeter* bandwidthMeter = application->getBandwidthMeter();
|
BandwidthMeter* bandwidthMeter = application->getBandwidthMeter();
|
||||||
NodeBounds& nodeBoundsDisplay = application->getNodeBoundsDisplay();
|
NodeBounds& nodeBoundsDisplay = application->getNodeBoundsDisplay();
|
||||||
|
|
||||||
|
_numMagnifiers = 0;
|
||||||
|
|
||||||
int mouseX = application->getMouseX();
|
int mouseX = application->getMouseX();
|
||||||
int mouseY = application->getMouseY();
|
int mouseY = application->getMouseY();
|
||||||
bool renderPointer = renderToTexture;
|
bool renderPointer = renderToTexture;
|
||||||
|
@ -310,15 +314,21 @@ void ApplicationOverlay::renderOverlay(bool renderToTexture) {
|
||||||
|
|
||||||
overlays.render2D();
|
overlays.render2D();
|
||||||
|
|
||||||
// Render a crosshair over the pointer when in Oculus
|
// Render a crosshair over the mouse when in Oculus
|
||||||
if (renderPointer) {
|
if (renderPointer && application->getLastMouseMoveType() == QEvent::MouseMove) {
|
||||||
const float pointerWidth = 10;
|
const float pointerWidth = 10;
|
||||||
const float pointerHeight = 10;
|
const float pointerHeight = 10;
|
||||||
const float crossPad = 4;
|
const float crossPad = 4;
|
||||||
|
|
||||||
|
|
||||||
|
_numMagnifiers = 1;
|
||||||
|
_mouseX[0] = application->getMouseX();
|
||||||
|
_mouseY[0] = application->getMouseY();
|
||||||
|
|
||||||
mouseX -= pointerWidth / 2.0f;
|
mouseX -= pointerWidth / 2.0f;
|
||||||
mouseY += pointerHeight / 2.0f;
|
mouseY += pointerHeight / 2.0f;
|
||||||
|
|
||||||
|
|
||||||
glBegin(GL_QUADS);
|
glBegin(GL_QUADS);
|
||||||
|
|
||||||
glColor3f(1, 0, 0);
|
glColor3f(1, 0, 0);
|
||||||
|
@ -336,7 +346,7 @@ void ApplicationOverlay::renderOverlay(bool renderToTexture) {
|
||||||
glVertex2i(mouseX + crossPad, mouseY - pointerHeight);
|
glVertex2i(mouseX + crossPad, mouseY - pointerHeight);
|
||||||
|
|
||||||
glEnd();
|
glEnd();
|
||||||
} else if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseMouseInput)) {
|
} else if (application->getLastMouseMoveType() == CONTROLLER_MOVE_EVENT && Menu::getInstance()->isOptionChecked(MenuOption::SixenseMouseInput)) {
|
||||||
//only render controller pointer if we aren't already rendering a mouse pointer
|
//only render controller pointer if we aren't already rendering a mouse pointer
|
||||||
renderControllerPointer();
|
renderControllerPointer();
|
||||||
}
|
}
|
||||||
|
@ -418,12 +428,8 @@ void ApplicationOverlay::displayOverlayTextureOculus(Camera& whichCamera) {
|
||||||
MyAvatar* myAvatar = application->getAvatar();
|
MyAvatar* myAvatar = application->getAvatar();
|
||||||
const glm::vec3& viewMatrixTranslation = application->getViewMatrixTranslation();
|
const glm::vec3& viewMatrixTranslation = application->getViewMatrixTranslation();
|
||||||
|
|
||||||
int mouseX = application->getMouseX();
|
|
||||||
int mouseY = application->getMouseY();
|
|
||||||
const int widgetWidth = glWidget->width();
|
const int widgetWidth = glWidget->width();
|
||||||
const int widgetHeight = glWidget->height();
|
const int widgetHeight = glWidget->height();
|
||||||
float magnifyWidth = 80.0f;
|
|
||||||
float magnifyHeight = 60.0f;
|
|
||||||
const float magnification = 4.0f;
|
const float magnification = 4.0f;
|
||||||
|
|
||||||
// Get vertical FoV of the displayed overlay texture
|
// Get vertical FoV of the displayed overlay texture
|
||||||
|
@ -480,114 +486,122 @@ void ApplicationOverlay::displayOverlayTextureOculus(Camera& whichCamera) {
|
||||||
glEnable(GL_ALPHA_TEST);
|
glEnable(GL_ALPHA_TEST);
|
||||||
glAlphaFunc(GL_GREATER, 0.01f);
|
glAlphaFunc(GL_GREATER, 0.01f);
|
||||||
|
|
||||||
//Draw the magnifying glass
|
|
||||||
|
|
||||||
mouseX -= magnifyWidth / 2;
|
|
||||||
mouseY -= magnifyHeight / 2;
|
|
||||||
|
|
||||||
//clamp the magnification
|
|
||||||
if (mouseX < 0) {
|
|
||||||
magnifyWidth += mouseX;
|
|
||||||
mouseX = 0;
|
|
||||||
} else if (mouseX + magnifyWidth > widgetWidth) {
|
|
||||||
magnifyWidth = widgetWidth - mouseX;
|
|
||||||
}
|
|
||||||
if (mouseY < 0) {
|
|
||||||
magnifyHeight += mouseY;
|
|
||||||
mouseY = 0;
|
|
||||||
} else if (mouseY + magnifyHeight > widgetHeight) {
|
|
||||||
magnifyHeight = widgetHeight - mouseY;
|
|
||||||
}
|
|
||||||
|
|
||||||
const float halfMagnifyHeight = magnifyHeight / 2.0f;
|
|
||||||
|
|
||||||
float newWidth = magnifyWidth * magnification;
|
|
||||||
float newHeight = magnifyHeight * magnification;
|
|
||||||
|
|
||||||
// Magnification Texture Coordinates
|
|
||||||
float magnifyULeft = mouseX / (float)widgetWidth;
|
|
||||||
float magnifyURight = (mouseX + magnifyWidth) / (float)widgetWidth;
|
|
||||||
float magnifyVBottom = 1.0f - mouseY / (float)widgetHeight;
|
|
||||||
float magnifyVTop = 1.0f - (mouseY + magnifyHeight) / (float)widgetHeight;
|
|
||||||
|
|
||||||
// Coordinates of magnification overlay
|
|
||||||
float newMouseX = (mouseX + magnifyWidth / 2) - newWidth / 2.0f;
|
|
||||||
float newMouseY = (mouseY + magnifyHeight / 2) + newHeight / 2.0f;
|
|
||||||
|
|
||||||
// Get angle on the UI
|
|
||||||
float leftAngle = (newMouseX / (float)widgetWidth) * horizontalAngle - halfHorizontalAngle;
|
|
||||||
float rightAngle = ((newMouseX + newWidth) / (float)widgetWidth) * horizontalAngle - halfHorizontalAngle;
|
|
||||||
|
|
||||||
float bottomAngle = (newMouseY / (float)widgetHeight) * _oculusAngle - halfVerticalAngle;
|
|
||||||
float topAngle = ((newMouseY - newHeight) / (float)widgetHeight) * _oculusAngle - halfVerticalAngle;
|
|
||||||
|
|
||||||
float leftX, rightX, leftZ, rightZ, topZ, bottomZ;
|
float leftX, rightX, leftZ, rightZ, topZ, bottomZ;
|
||||||
|
|
||||||
// Get position on hemisphere using angle
|
|
||||||
if (_uiType == HEMISPHERE) {
|
|
||||||
|
|
||||||
//Get new UV coordinates from our magnification window
|
//Draw the magnifiers
|
||||||
float newULeft = newMouseX / widgetWidth;
|
for (int i = 0; i < _numMagnifiers; i++) {
|
||||||
float newURight = (newMouseX + newWidth) / widgetWidth;
|
|
||||||
float newVBottom = 1.0 - newMouseY / widgetHeight;
|
|
||||||
float newVTop = 1.0 - (newMouseY - newHeight) / widgetHeight;
|
|
||||||
|
|
||||||
// Project our position onto the hemisphere using the UV coordinates
|
float magnifyWidth = 80.0f;
|
||||||
float lX = sin((newULeft - 0.5f) * textureFov);
|
float magnifyHeight = 60.0f;
|
||||||
float rX = sin((newURight - 0.5f) * textureFov);
|
|
||||||
float bY = sin((newVBottom - 0.5f) * textureFov);
|
|
||||||
float tY = sin((newVTop - 0.5f) * textureFov);
|
|
||||||
|
|
||||||
float dist;
|
|
||||||
//Bottom Left
|
|
||||||
dist = sqrt(lX * lX + bY * bY);
|
|
||||||
float blZ = sqrt(1.0f - dist * dist);
|
|
||||||
//Top Left
|
|
||||||
dist = sqrt(lX * lX + tY * tY);
|
|
||||||
float tlZ = sqrt(1.0f - dist * dist);
|
|
||||||
//Bottom Right
|
|
||||||
dist = sqrt(rX * rX + bY * bY);
|
|
||||||
float brZ = sqrt(1.0f - dist * dist);
|
|
||||||
//Top Right
|
|
||||||
dist = sqrt(rX * rX + tY * tY);
|
|
||||||
float trZ = sqrt(1.0f - dist * dist);
|
|
||||||
|
|
||||||
glBegin(GL_QUADS);
|
int mouseX = _mouseX[i];
|
||||||
|
int mouseY = _mouseY[i];
|
||||||
|
mouseX -= magnifyWidth / 2;
|
||||||
|
mouseY -= magnifyHeight / 2;
|
||||||
|
|
||||||
glTexCoord2f(magnifyULeft, magnifyVBottom); glVertex3f(lX, tY, -tlZ);
|
//clamp the magnification
|
||||||
glTexCoord2f(magnifyURight, magnifyVBottom); glVertex3f(rX, tY, -trZ);
|
if (mouseX < 0) {
|
||||||
glTexCoord2f(magnifyURight, magnifyVTop); glVertex3f(rX, bY, -brZ);
|
magnifyWidth += mouseX;
|
||||||
glTexCoord2f(magnifyULeft, magnifyVTop); glVertex3f(lX, bY, -blZ);
|
mouseX = 0;
|
||||||
|
} else if (mouseX + magnifyWidth > widgetWidth) {
|
||||||
glEnd();
|
magnifyWidth = widgetWidth - mouseX;
|
||||||
|
}
|
||||||
} else {
|
if (mouseY < 0) {
|
||||||
leftX = sin(leftAngle) * _distance;
|
magnifyHeight += mouseY;
|
||||||
rightX = sin(rightAngle) * _distance;
|
mouseY = 0;
|
||||||
leftZ = -cos(leftAngle) * _distance;
|
} else if (mouseY + magnifyHeight > widgetHeight) {
|
||||||
rightZ = -cos(rightAngle) * _distance;
|
magnifyHeight = widgetHeight - mouseY;
|
||||||
if (_uiType == CURVED_SEMICIRCLE) {
|
|
||||||
topZ = -cos(topAngle * overlayAspectRatio) * _distance;
|
|
||||||
bottomZ = -cos(bottomAngle * overlayAspectRatio) * _distance;
|
|
||||||
} else {
|
|
||||||
// Dont want to use topZ or bottomZ for SEMICIRCLE
|
|
||||||
topZ = -99999;
|
|
||||||
bottomZ = -99999;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float bottomY = (1.0 - newMouseY / (float)widgetHeight) * halfOverlayHeight * 2.0f - halfOverlayHeight;
|
const float halfMagnifyHeight = magnifyHeight / 2.0f;
|
||||||
float topY = bottomY + (newHeight / widgetHeight) * halfOverlayHeight * 2;
|
|
||||||
|
|
||||||
//TODO: Remove immediate mode in favor of VBO
|
float newWidth = magnifyWidth * magnification;
|
||||||
glBegin(GL_QUADS);
|
float newHeight = magnifyHeight * magnification;
|
||||||
|
|
||||||
glTexCoord2f(magnifyULeft, magnifyVBottom); glVertex3f(leftX, topY, max(topZ, leftZ));
|
// Magnification Texture Coordinates
|
||||||
glTexCoord2f(magnifyURight, magnifyVBottom); glVertex3f(rightX, topY, max(topZ, rightZ));
|
float magnifyULeft = mouseX / (float)widgetWidth;
|
||||||
glTexCoord2f(magnifyURight, magnifyVTop); glVertex3f(rightX, bottomY, max(bottomZ, rightZ));
|
float magnifyURight = (mouseX + magnifyWidth) / (float)widgetWidth;
|
||||||
glTexCoord2f(magnifyULeft, magnifyVTop); glVertex3f(leftX, bottomY, max(bottomZ, leftZ));
|
float magnifyVBottom = 1.0f - mouseY / (float)widgetHeight;
|
||||||
|
float magnifyVTop = 1.0f - (mouseY + magnifyHeight) / (float)widgetHeight;
|
||||||
|
|
||||||
glEnd();
|
// Coordinates of magnification overlay
|
||||||
|
float newMouseX = (mouseX + magnifyWidth / 2) - newWidth / 2.0f;
|
||||||
|
float newMouseY = (mouseY + magnifyHeight / 2) + newHeight / 2.0f;
|
||||||
|
|
||||||
|
// Get angle on the UI
|
||||||
|
float leftAngle = (newMouseX / (float)widgetWidth) * horizontalAngle - halfHorizontalAngle;
|
||||||
|
float rightAngle = ((newMouseX + newWidth) / (float)widgetWidth) * horizontalAngle - halfHorizontalAngle;
|
||||||
|
|
||||||
|
float bottomAngle = (newMouseY / (float)widgetHeight) * _oculusAngle - halfVerticalAngle;
|
||||||
|
float topAngle = ((newMouseY - newHeight) / (float)widgetHeight) * _oculusAngle - halfVerticalAngle;
|
||||||
|
|
||||||
|
// Get position on hemisphere using angle
|
||||||
|
if (_uiType == HEMISPHERE) {
|
||||||
|
|
||||||
|
//Get new UV coordinates from our magnification window
|
||||||
|
float newULeft = newMouseX / widgetWidth;
|
||||||
|
float newURight = (newMouseX + newWidth) / widgetWidth;
|
||||||
|
float newVBottom = 1.0 - newMouseY / widgetHeight;
|
||||||
|
float newVTop = 1.0 - (newMouseY - newHeight) / widgetHeight;
|
||||||
|
|
||||||
|
// Project our position onto the hemisphere using the UV coordinates
|
||||||
|
float lX = sin((newULeft - 0.5f) * textureFov);
|
||||||
|
float rX = sin((newURight - 0.5f) * textureFov);
|
||||||
|
float bY = sin((newVBottom - 0.5f) * textureFov);
|
||||||
|
float tY = sin((newVTop - 0.5f) * textureFov);
|
||||||
|
|
||||||
|
float dist;
|
||||||
|
//Bottom Left
|
||||||
|
dist = sqrt(lX * lX + bY * bY);
|
||||||
|
float blZ = sqrt(1.0f - dist * dist);
|
||||||
|
//Top Left
|
||||||
|
dist = sqrt(lX * lX + tY * tY);
|
||||||
|
float tlZ = sqrt(1.0f - dist * dist);
|
||||||
|
//Bottom Right
|
||||||
|
dist = sqrt(rX * rX + bY * bY);
|
||||||
|
float brZ = sqrt(1.0f - dist * dist);
|
||||||
|
//Top Right
|
||||||
|
dist = sqrt(rX * rX + tY * tY);
|
||||||
|
float trZ = sqrt(1.0f - dist * dist);
|
||||||
|
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
|
||||||
|
glTexCoord2f(magnifyULeft, magnifyVBottom); glVertex3f(lX, tY, -tlZ);
|
||||||
|
glTexCoord2f(magnifyURight, magnifyVBottom); glVertex3f(rX, tY, -trZ);
|
||||||
|
glTexCoord2f(magnifyURight, magnifyVTop); glVertex3f(rX, bY, -brZ);
|
||||||
|
glTexCoord2f(magnifyULeft, magnifyVTop); glVertex3f(lX, bY, -blZ);
|
||||||
|
|
||||||
|
glEnd();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
leftX = sin(leftAngle) * _distance;
|
||||||
|
rightX = sin(rightAngle) * _distance;
|
||||||
|
leftZ = -cos(leftAngle) * _distance;
|
||||||
|
rightZ = -cos(rightAngle) * _distance;
|
||||||
|
if (_uiType == CURVED_SEMICIRCLE) {
|
||||||
|
topZ = -cos(topAngle * overlayAspectRatio) * _distance;
|
||||||
|
bottomZ = -cos(bottomAngle * overlayAspectRatio) * _distance;
|
||||||
|
} else {
|
||||||
|
// Dont want to use topZ or bottomZ for SEMICIRCLE
|
||||||
|
topZ = -99999;
|
||||||
|
bottomZ = -99999;
|
||||||
|
}
|
||||||
|
|
||||||
|
float bottomY = (1.0 - newMouseY / (float)widgetHeight) * halfOverlayHeight * 2.0f - halfOverlayHeight;
|
||||||
|
float topY = bottomY + (newHeight / widgetHeight) * halfOverlayHeight * 2;
|
||||||
|
|
||||||
|
//TODO: Remove immediate mode in favor of VBO
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
|
||||||
|
glTexCoord2f(magnifyULeft, magnifyVBottom); glVertex3f(leftX, topY, max(topZ, leftZ));
|
||||||
|
glTexCoord2f(magnifyURight, magnifyVBottom); glVertex3f(rightX, topY, max(topZ, rightZ));
|
||||||
|
glTexCoord2f(magnifyURight, magnifyVTop); glVertex3f(rightX, bottomY, max(bottomZ, rightZ));
|
||||||
|
glTexCoord2f(magnifyULeft, magnifyVTop); glVertex3f(leftX, bottomY, max(bottomZ, leftZ));
|
||||||
|
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
glDepthMask(GL_FALSE);
|
glDepthMask(GL_FALSE);
|
||||||
glDisable(GL_ALPHA_TEST);
|
glDisable(GL_ALPHA_TEST);
|
||||||
|
|
||||||
|
|
|
@ -46,6 +46,7 @@ private:
|
||||||
|
|
||||||
typedef QPair<GLuint, GLuint> VerticesIndices;
|
typedef QPair<GLuint, GLuint> VerticesIndices;
|
||||||
|
|
||||||
|
void renderControllerPointer();
|
||||||
void renderTexturedHemisphere();
|
void renderTexturedHemisphere();
|
||||||
|
|
||||||
QOpenGLFramebufferObject* _framebufferObject;
|
QOpenGLFramebufferObject* _framebufferObject;
|
||||||
|
@ -53,6 +54,9 @@ private:
|
||||||
float _oculusAngle;
|
float _oculusAngle;
|
||||||
float _distance;
|
float _distance;
|
||||||
UIType _uiType;
|
UIType _uiType;
|
||||||
|
int _mouseX[2];
|
||||||
|
int _mouseY[2];
|
||||||
|
int _numMagnifiers;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_ApplicationOverlay_h
|
#endif // hifi_ApplicationOverlay_h
|
Loading…
Reference in a new issue