mirror of
https://github.com/overte-org/overte.git
synced 2025-04-21 08:04:01 +02:00
Merge pull request #2974 from Barnold1953/OculusOverlay
Curved Oculus Overlay
This commit is contained in:
commit
948415d4b4
7 changed files with 178 additions and 23 deletions
|
@ -51,7 +51,7 @@ var flockGravity = { x: 0, y: -1, z: 0};
|
|||
var enableRandomXZThrust = false; // leading birds randomly decide to thrust in some random direction.
|
||||
var enableSomeBirdsLead = false; // birds randomly decide not fly toward flock, causing other birds to follow
|
||||
var leaders = 0; // number of birds leading
|
||||
var PROBABILITY_TO_LEAD = 0.1; // probabolity a bird will choose to lead
|
||||
var PROBABILITY_TO_LEAD = 0.1; // probability a bird will choose to lead
|
||||
|
||||
var birds = new Array(); // array of bird state data
|
||||
|
||||
|
|
|
@ -1007,6 +1007,12 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
case Qt::Key_At:
|
||||
Menu::getInstance()->goTo();
|
||||
break;
|
||||
case Qt::Key_B:
|
||||
_applicationOverlay.setOculusAngle(_applicationOverlay.getOculusAngle() - RADIANS_PER_DEGREE);
|
||||
break;
|
||||
case Qt::Key_N:
|
||||
_applicationOverlay.setOculusAngle(_applicationOverlay.getOculusAngle() + RADIANS_PER_DEGREE);
|
||||
break;
|
||||
default:
|
||||
event->ignore();
|
||||
break;
|
||||
|
@ -1097,7 +1103,8 @@ void Application::mouseMoveEvent(QMouseEvent* event) {
|
|||
|
||||
|
||||
_lastMouseMove = usecTimestampNow();
|
||||
if (_mouseHidden) {
|
||||
|
||||
if (_mouseHidden && !OculusManager::isConnected) {
|
||||
getGLWidget()->setCursor(Qt::ArrowCursor);
|
||||
_mouseHidden = false;
|
||||
_seenMouseMove = true;
|
||||
|
|
|
@ -348,7 +348,6 @@ Menu::Menu() :
|
|||
|
||||
QMenu* avatarOptionsMenu = developerMenu->addMenu("Avatar Options");
|
||||
|
||||
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::AllowOculusCameraModeChange, 0, false);
|
||||
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::Avatars, 0, true);
|
||||
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::AvatarsReceiveShadows, 0, true);
|
||||
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::RenderSkeletonCollisionShapes);
|
||||
|
@ -375,6 +374,10 @@ Menu::Menu() :
|
|||
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::GlowWhenSpeaking, 0, true);
|
||||
addCheckableActionToQMenuAndActionHash(avatarOptionsMenu, MenuOption::ChatCircling, 0, false);
|
||||
|
||||
QMenu* oculusOptionsMenu = developerMenu->addMenu("Oculus Options");
|
||||
addCheckableActionToQMenuAndActionHash(oculusOptionsMenu, MenuOption::AllowOculusCameraModeChange, 0, false);
|
||||
addCheckableActionToQMenuAndActionHash(oculusOptionsMenu, MenuOption::DisplayOculusOverlays, 0, true);
|
||||
|
||||
QMenu* handOptionsMenu = developerMenu->addMenu("Hand Options");
|
||||
|
||||
addCheckableActionToQMenuAndActionHash(handOptionsMenu,
|
||||
|
|
|
@ -326,6 +326,7 @@ namespace MenuOption {
|
|||
const QString DisplayModelBounds = "Display Model Bounds";
|
||||
const QString DisplayModelElementProxy = "Display Model Element Bounds";
|
||||
const QString DisplayModelElementChildProxies = "Display Model Element Children";
|
||||
const QString DisplayOculusOverlays = "Display Oculus Overlays";
|
||||
const QString DisplayTimingDetails = "Display Timing Details";
|
||||
const QString DontFadeOnVoxelServerChanges = "Don't Fade In/Out on Voxel Server Changes";
|
||||
const QString EchoLocalAudio = "Echo Local Audio";
|
||||
|
|
|
@ -86,7 +86,7 @@ void OculusManager::display(Camera& whichCamera) {
|
|||
// We only need to render the overlays to a texture once, then we just render the texture as a quad
|
||||
// PrioVR will only work if renderOverlay is called, calibration is connected to Application::renderingOverlay()
|
||||
applicationOverlay.renderOverlay(true);
|
||||
const bool displayOverlays = false;
|
||||
const bool displayOverlays = Menu::getInstance()->isOptionChecked(MenuOption::DisplayOculusOverlays);
|
||||
|
||||
Application::getInstance()->getGlowEffect()->prepare();
|
||||
|
||||
|
|
|
@ -19,7 +19,10 @@
|
|||
|
||||
#include "ui/Stats.h"
|
||||
|
||||
ApplicationOverlay::ApplicationOverlay() : _framebufferObject(NULL) {
|
||||
ApplicationOverlay::ApplicationOverlay() :
|
||||
_framebufferObject(NULL),
|
||||
_oculusAngle(65.0f * RADIANS_PER_DEGREE),
|
||||
_distance(0.5f) {
|
||||
|
||||
}
|
||||
|
||||
|
@ -45,6 +48,10 @@ void ApplicationOverlay::renderOverlay(bool renderToTexture) {
|
|||
BandwidthMeter* bandwidthMeter = application->getBandwidthMeter();
|
||||
NodeBounds& nodeBoundsDisplay = application->getNodeBoundsDisplay();
|
||||
|
||||
int mouseX = application->getMouseX();
|
||||
int mouseY = application->getMouseY();
|
||||
bool renderPointer = renderToTexture;
|
||||
|
||||
if (renderToTexture) {
|
||||
getFramebufferObject()->bind();
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
@ -220,6 +227,34 @@ void ApplicationOverlay::renderOverlay(bool renderToTexture) {
|
|||
|
||||
overlays.render2D();
|
||||
|
||||
// Render a crosshair over the pointer when in Oculus
|
||||
if (renderPointer) {
|
||||
const float pointerWidth = 10;
|
||||
const float pointerHeight = 10;
|
||||
const float crossPad = 4;
|
||||
|
||||
mouseX -= pointerWidth / 2.0f;
|
||||
mouseY += pointerHeight / 2.0f;
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
glColor3f(1, 0, 0);
|
||||
|
||||
//Horizontal crosshair
|
||||
glVertex2i(mouseX, mouseY - crossPad);
|
||||
glVertex2i(mouseX + pointerWidth, mouseY - crossPad);
|
||||
glVertex2i(mouseX + pointerWidth, mouseY - pointerHeight + crossPad);
|
||||
glVertex2i(mouseX, mouseY - pointerHeight + crossPad);
|
||||
|
||||
//Vertical crosshair
|
||||
glVertex2i(mouseX + crossPad, mouseY);
|
||||
glVertex2i(mouseX + pointerWidth - crossPad, mouseY);
|
||||
glVertex2i(mouseX + pointerWidth - crossPad, mouseY - pointerHeight);
|
||||
glVertex2i(mouseX + crossPad, mouseY - pointerHeight);
|
||||
|
||||
glEnd();
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
glMatrixMode(GL_MODELVIEW);
|
||||
|
@ -227,7 +262,6 @@ void ApplicationOverlay::renderOverlay(bool renderToTexture) {
|
|||
glEnable(GL_LIGHTING);
|
||||
glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_CONSTANT_ALPHA, GL_ONE);
|
||||
|
||||
|
||||
if (renderToTexture) {
|
||||
getFramebufferObject()->release();
|
||||
}
|
||||
|
@ -262,6 +296,15 @@ void ApplicationOverlay::displayOverlayTexture(Camera& whichCamera) {
|
|||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
// Fast helper functions
|
||||
inline float max(float a, float b) {
|
||||
return (a > b) ? a : b;
|
||||
}
|
||||
|
||||
inline float min(float a, float b) {
|
||||
return (a < b) ? a : b;
|
||||
}
|
||||
|
||||
// Draws the FBO texture for Oculus rift. TODO: Draw a curved texture instead of plane.
|
||||
void ApplicationOverlay::displayOverlayTextureOculus(Camera& whichCamera) {
|
||||
|
||||
|
@ -271,23 +314,37 @@ void ApplicationOverlay::displayOverlayTextureOculus(Camera& whichCamera) {
|
|||
MyAvatar* myAvatar = application->getAvatar();
|
||||
const glm::vec3& viewMatrixTranslation = application->getViewMatrixTranslation();
|
||||
|
||||
// Calculates the world space width and height of the texture based on a desired FOV
|
||||
const float overlayFov = whichCamera.getFieldOfView() * PI / 180.0f;
|
||||
const float overlayDistance = 1;
|
||||
int mouseX = application->getMouseX();
|
||||
int mouseY = application->getMouseY();
|
||||
int widgetWidth = glWidget->width();
|
||||
int widgetHeight = glWidget->height();
|
||||
float magnifyWidth = 80.0f;
|
||||
float magnifyHeight = 60.0f;
|
||||
const float magnification = 4.0f;
|
||||
|
||||
// Get vertical FoV of the displayed overlay texture
|
||||
const float halfVerticalAngle = _oculusAngle / 2.0f;
|
||||
const float verticalAngle = halfVerticalAngle * 2.0f;
|
||||
const float overlayAspectRatio = glWidget->width() / (float)glWidget->height();
|
||||
const float overlayHeight = overlayDistance * tan(overlayFov);
|
||||
const float overlayWidth = overlayHeight * overlayAspectRatio;
|
||||
const float halfOverlayWidth = overlayWidth / 2;
|
||||
const float halfOverlayHeight = overlayHeight / 2;
|
||||
const float halfOverlayHeight = _distance * tan(halfVerticalAngle);
|
||||
|
||||
// The more vertices, the better the curve
|
||||
const int numHorizontalVertices = 20;
|
||||
// U texture coordinate width at each quad
|
||||
const float quadTexWidth = 1.0f / (numHorizontalVertices - 1);
|
||||
|
||||
// Get horizontal angle and angle increment from vertical angle and aspect ratio
|
||||
const float horizontalAngle = halfVerticalAngle * 2.0f * overlayAspectRatio;
|
||||
const float angleIncrement = horizontalAngle / (numHorizontalVertices - 1);
|
||||
const float halfHorizontalAngle = horizontalAngle / 2;
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
|
||||
glDepthMask(GL_FALSE);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, getFramebufferObject()->texture());
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
glDisable(GL_LIGHTING);
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
|
@ -305,21 +362,102 @@ void ApplicationOverlay::displayOverlayTextureOculus(Camera& whichCamera) {
|
|||
glm::vec3 pos = whichCamera.getPosition();
|
||||
glm::quat rot = myAvatar->getOrientation();
|
||||
glm::vec3 axis = glm::axis(rot);
|
||||
pos += rot * glm::vec3(0.0, 0.0, -overlayDistance);
|
||||
|
||||
|
||||
glTranslatef(pos.x, pos.y, pos.z);
|
||||
glRotatef(glm::degrees(glm::angle(rot)), axis.x, axis.y, axis.z);
|
||||
|
||||
glColor3f(1.0f, 1.0f, 1.0f);
|
||||
|
||||
glDepthMask(GL_TRUE);
|
||||
|
||||
glEnable(GL_ALPHA_TEST);
|
||||
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;
|
||||
}
|
||||
|
||||
float newWidth = magnifyWidth * magnification;
|
||||
float newHeight = magnifyHeight * magnification;
|
||||
float tmp;
|
||||
|
||||
// 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 halfMagnifyHeight = magnifyHeight / 2.0f;
|
||||
|
||||
float leftX, rightX, leftZ, rightZ;
|
||||
|
||||
// Get position on hemisphere using angle
|
||||
leftX = sin(leftAngle) * _distance;
|
||||
rightX = sin(rightAngle) * _distance;
|
||||
leftZ = -cos(leftAngle) * _distance;
|
||||
rightZ = -cos(rightAngle) * _distance;
|
||||
|
||||
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(1, 0); glVertex3f(-halfOverlayWidth, halfOverlayHeight, 0);
|
||||
glTexCoord2f(0, 0); glVertex3f(halfOverlayWidth, halfOverlayHeight, 0);
|
||||
glTexCoord2f(0, 1); glVertex3f(halfOverlayWidth, -halfOverlayHeight, 0);
|
||||
glTexCoord2f(1, 1); glVertex3f(-halfOverlayWidth, -halfOverlayHeight, 0);
|
||||
|
||||
glTexCoord2f(magnifyULeft, magnifyVBottom); glVertex3f(leftX, topY, leftZ);
|
||||
glTexCoord2f(magnifyURight, magnifyVBottom); glVertex3f(rightX, topY, rightZ);
|
||||
glTexCoord2f(magnifyURight, magnifyVTop); glVertex3f(rightX, bottomY, rightZ);
|
||||
glTexCoord2f(magnifyULeft, magnifyVTop); glVertex3f(leftX, bottomY, leftZ);
|
||||
|
||||
glEnd();
|
||||
|
||||
glDepthMask(GL_FALSE);
|
||||
glDisable(GL_ALPHA_TEST);
|
||||
|
||||
//TODO: Remove immediate mode in favor of VBO
|
||||
glBegin(GL_QUADS);
|
||||
// Place the vertices in a semicircle curve around the camera
|
||||
for (int i = 0; i < numHorizontalVertices-1; i++) {
|
||||
|
||||
// Calculate the X and Z coordinates from the angles and radius from camera
|
||||
leftX = sin(angleIncrement * i - halfHorizontalAngle) * _distance;
|
||||
rightX = sin(angleIncrement * (i + 1) - halfHorizontalAngle) * _distance;
|
||||
leftZ = -cos(angleIncrement * i - halfHorizontalAngle) * _distance;
|
||||
rightZ = -cos(angleIncrement * (i + 1) - halfHorizontalAngle) * _distance;
|
||||
|
||||
glTexCoord2f(quadTexWidth * i, 1); glVertex3f(leftX, halfOverlayHeight, leftZ);
|
||||
glTexCoord2f(quadTexWidth * (i + 1), 1); glVertex3f(rightX, halfOverlayHeight, rightZ);
|
||||
glTexCoord2f(quadTexWidth * (i + 1), 0); glVertex3f(rightX, -halfOverlayHeight, rightZ);
|
||||
glTexCoord2f(quadTexWidth * i, 0); glVertex3f(leftX, -halfOverlayHeight, leftZ);
|
||||
}
|
||||
|
||||
glEnd();
|
||||
|
||||
glPopMatrix();
|
||||
|
||||
glEnable(GL_DEPTH_TEST);
|
||||
|
||||
glDepthMask(GL_TRUE);
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
|
|
@ -28,11 +28,17 @@ public:
|
|||
|
||||
// Getters
|
||||
QOpenGLFramebufferObject* getFramebufferObject();
|
||||
float getOculusAngle() const { return _oculusAngle; }
|
||||
|
||||
// Setters
|
||||
void setOculusAngle(float oculusAngle) { _oculusAngle = oculusAngle; }
|
||||
|
||||
private:
|
||||
|
||||
QOpenGLFramebufferObject* _framebufferObject;
|
||||
float _trailingAudioLoudness;
|
||||
float _oculusAngle;
|
||||
float _distance;
|
||||
};
|
||||
|
||||
#endif // hifi_ApplicationOverlay_h
|
Loading…
Reference in a new issue