mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-13 22:27:13 +02:00
Merge pull request #5097 from jherico/cursor_manager
Cursor manager first pass
This commit is contained in:
commit
c0deff9fdc
7 changed files with 214 additions and 53 deletions
BIN
interface/resources/images/reticleLink.png
Normal file
BIN
interface/resources/images/reticleLink.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.2 KiB |
BIN
interface/resources/images/reticleWhite.png
Normal file
BIN
interface/resources/images/reticleWhite.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.6 KiB |
|
@ -57,6 +57,7 @@
|
|||
|
||||
#include <AccountManager.h>
|
||||
#include <AddressManager.h>
|
||||
#include <CursorManager.h>
|
||||
#include <AmbientOcclusionEffect.h>
|
||||
#include <AudioInjector.h>
|
||||
#include <DeferredLightingEffect.h>
|
||||
|
@ -1239,9 +1240,20 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
}
|
||||
break;
|
||||
|
||||
case Qt::Key_Apostrophe:
|
||||
resetSensors();
|
||||
case Qt::Key_Apostrophe: {
|
||||
if (isMeta) {
|
||||
auto cursor = Cursor::Manager::instance().getCursor();
|
||||
auto curIcon = cursor->getIcon();
|
||||
if (curIcon == Cursor::Icon::DEFAULT) {
|
||||
cursor->setIcon(Cursor::Icon::LINK);
|
||||
} else {
|
||||
cursor->setIcon(Cursor::Icon::DEFAULT);
|
||||
}
|
||||
} else {
|
||||
resetSensors();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Qt::Key_A:
|
||||
if (isShifted) {
|
||||
|
@ -1365,12 +1377,27 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
|||
case Qt::Key_Slash:
|
||||
Menu::getInstance()->triggerOption(MenuOption::Stats);
|
||||
break;
|
||||
case Qt::Key_Plus:
|
||||
_myAvatar->increaseSize();
|
||||
|
||||
case Qt::Key_Plus: {
|
||||
if (isMeta && event->modifiers().testFlag(Qt::KeypadModifier)) {
|
||||
auto& cursorManager = Cursor::Manager::instance();
|
||||
cursorManager.setScale(cursorManager.getScale() * 1.1f);
|
||||
} else {
|
||||
_myAvatar->increaseSize();
|
||||
}
|
||||
break;
|
||||
case Qt::Key_Minus:
|
||||
_myAvatar->decreaseSize();
|
||||
}
|
||||
|
||||
case Qt::Key_Minus: {
|
||||
if (isMeta && event->modifiers().testFlag(Qt::KeypadModifier)) {
|
||||
auto& cursorManager = Cursor::Manager::instance();
|
||||
cursorManager.setScale(cursorManager.getScale() / 1.1f);
|
||||
} else {
|
||||
_myAvatar->decreaseSize();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
case Qt::Key_Equal:
|
||||
_myAvatar->resetSize();
|
||||
break;
|
||||
|
|
|
@ -22,7 +22,7 @@
|
|||
#include <gpu/GLBackend.h>
|
||||
#include <GLMHelpers.h>
|
||||
#include <OffscreenUi.h>
|
||||
#include <PathUtils.h>
|
||||
#include <CursorManager.h>
|
||||
#include <PerfStat.h>
|
||||
|
||||
#include "AudioClient.h"
|
||||
|
@ -128,7 +128,6 @@ ApplicationOverlay::ApplicationOverlay() :
|
|||
_alpha(1.0f),
|
||||
_oculusUIRadius(1.0f),
|
||||
_trailingAudioLoudness(0.0f),
|
||||
_crosshairTexture(0),
|
||||
_previousBorderWidth(-1),
|
||||
_previousBorderHeight(-1),
|
||||
_previousMagnifierBottomLeft(),
|
||||
|
@ -260,6 +259,18 @@ gpu::PipelinePointer ApplicationOverlay::getDrawPipeline() {
|
|||
return _standardDrawPipeline;
|
||||
}
|
||||
|
||||
void ApplicationOverlay::bindCursorTexture(gpu::Batch& batch, uint8_t cursorIndex) {
|
||||
auto& cursorManager = Cursor::Manager::instance();
|
||||
auto cursor = cursorManager.getCursor(cursorIndex);
|
||||
auto iconId = cursor->getIcon();
|
||||
if (!_cursors.count(iconId)) {
|
||||
auto iconPath = cursorManager.getIconImage(cursor->getIcon());
|
||||
_cursors[iconId] = DependencyManager::get<TextureCache>()->
|
||||
getImageTexture(iconPath);
|
||||
}
|
||||
batch.setUniformTexture(0, _cursors[iconId]);
|
||||
}
|
||||
|
||||
#define CURSOR_PIXEL_SIZE 32.0f
|
||||
|
||||
// Draws the FBO texture for the screen
|
||||
|
@ -267,12 +278,6 @@ void ApplicationOverlay::displayOverlayTexture(RenderArgs* renderArgs) {
|
|||
if (_alpha == 0.0f) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_crosshairTexture) {
|
||||
_crosshairTexture = TextureCache::getImageTexture(
|
||||
PathUtils::resourcesPath() + "images/arrow.png");
|
||||
}
|
||||
|
||||
|
||||
renderArgs->_context->syncCache();
|
||||
|
||||
|
@ -301,7 +306,7 @@ void ApplicationOverlay::displayOverlayTexture(RenderArgs* renderArgs) {
|
|||
glm::vec2 mouseSize = CURSOR_PIXEL_SIZE / canvasSize;
|
||||
model.setScale(vec3(mouseSize, 1.0f));
|
||||
batch.setModelTransform(model);
|
||||
batch.setUniformTexture(0, _crosshairTexture);
|
||||
bindCursorTexture(batch);
|
||||
glm::vec4 reticleColor = { RETICLE_COLOR[0], RETICLE_COLOR[1], RETICLE_COLOR[2], 1.0f };
|
||||
DependencyManager::get<GeometryCache>()->renderUnitQuad(batch, vec4(1));
|
||||
renderArgs->_context->render(batch);
|
||||
|
@ -328,24 +333,6 @@ glm::vec2 getPolarCoordinates(const PalmData& palm) {
|
|||
return polar;
|
||||
}
|
||||
|
||||
void ApplicationOverlay::renderReticle(gpu::Batch& batch, glm::quat orientation, float alpha) {
|
||||
if (!_crosshairTexture) {
|
||||
_crosshairTexture = TextureCache::getImageTexture(
|
||||
PathUtils::resourcesPath() + "images/arrow.png");
|
||||
}
|
||||
|
||||
batch.setUniformTexture(0, _crosshairTexture);
|
||||
glm::vec4 reticleColor = { RETICLE_COLOR[0], RETICLE_COLOR[1], RETICLE_COLOR[2], alpha };
|
||||
|
||||
vec3 dist = getPoint(0, 0);
|
||||
mat4 reticleXfm = glm::translate(mat4(), vec3(0, 0, -1));
|
||||
reticleXfm = glm::mat4_cast(orientation) * reticleXfm;
|
||||
reticleXfm = glm::scale(reticleXfm, vec3(reticleSize, reticleSize, 1.0f));
|
||||
batch.setModelTransform(Transform(reticleXfm));
|
||||
DependencyManager::get<GeometryCache>()->renderUnitQuad(batch, glm::vec4(1), _reticleQuad);
|
||||
}
|
||||
|
||||
|
||||
// Draws the FBO texture for Oculus rift.
|
||||
void ApplicationOverlay::displayOverlayTextureHmd(RenderArgs* renderArgs, Camera& whichCamera) {
|
||||
if (_alpha == 0.0f) {
|
||||
|
@ -373,12 +360,9 @@ void ApplicationOverlay::displayOverlayTextureHmd(RenderArgs* renderArgs, Camera
|
|||
drawSphereSection(batch);
|
||||
|
||||
|
||||
if (!_crosshairTexture) {
|
||||
_crosshairTexture = TextureCache::getImageTexture(
|
||||
PathUtils::resourcesPath() + "images/arrow.png");
|
||||
}
|
||||
batch.setUniformTexture(0, _crosshairTexture);
|
||||
bindCursorTexture(batch);
|
||||
auto geometryCache = DependencyManager::get<GeometryCache>();
|
||||
vec3 reticleScale = vec3(Cursor::Manager::instance().getScale() * reticleSize);
|
||||
//Controller Pointers
|
||||
for (int i = 0; i < (int)myAvatar->getHand()->getNumPalms(); i++) {
|
||||
PalmData& palm = myAvatar->getHand()->getPalms()[i];
|
||||
|
@ -387,7 +371,7 @@ void ApplicationOverlay::displayOverlayTextureHmd(RenderArgs* renderArgs, Camera
|
|||
// Convert to quaternion
|
||||
mat4 pointerXfm = glm::mat4_cast(quat(vec3(polar.y, -polar.x, 0.0f))) * glm::translate(mat4(), vec3(0, 0, -1));
|
||||
mat4 reticleXfm = overlayXfm * pointerXfm;
|
||||
reticleXfm = glm::scale(reticleXfm, vec3(reticleSize, reticleSize, 1.0f));
|
||||
reticleXfm = glm::scale(reticleXfm, reticleScale);
|
||||
batch.setModelTransform(reticleXfm);
|
||||
// Render reticle at location
|
||||
geometryCache->renderUnitQuad(batch, glm::vec4(1), _reticleQuad);
|
||||
|
@ -400,7 +384,7 @@ void ApplicationOverlay::displayOverlayTextureHmd(RenderArgs* renderArgs, Camera
|
|||
_reticlePosition[MOUSE].y()));
|
||||
mat4 pointerXfm = glm::mat4_cast(quat(vec3(-projection.y, projection.x, 0.0f))) * glm::translate(mat4(), vec3(0, 0, -1));
|
||||
mat4 reticleXfm = overlayXfm * pointerXfm;
|
||||
reticleXfm = glm::scale(reticleXfm, vec3(reticleSize, reticleSize, 1.0f));
|
||||
reticleXfm = glm::scale(reticleXfm, reticleScale);
|
||||
batch.setModelTransform(reticleXfm);
|
||||
geometryCache->renderUnitQuad(batch, glm::vec4(1), _reticleQuad);
|
||||
}
|
||||
|
@ -487,16 +471,12 @@ bool ApplicationOverlay::calculateRayUICollisionPoint(const glm::vec3& position,
|
|||
|
||||
//Renders optional pointers
|
||||
void ApplicationOverlay::renderPointers() {
|
||||
//lazily load crosshair texture
|
||||
if (_crosshairTexture == 0) {
|
||||
_crosshairTexture = TextureCache::getImageTexture(PathUtils::resourcesPath() + "images/arrow.png");
|
||||
}
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
glEnable(GL_BLEND);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
//glEnable(GL_TEXTURE_2D);
|
||||
//glEnable(GL_BLEND);
|
||||
//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, gpu::GLBackend::getTextureID(_crosshairTexture));
|
||||
//glActiveTexture(GL_TEXTURE0);
|
||||
//bindCursorTexture();
|
||||
|
||||
if (qApp->isHMDMode() && !qApp->getLastMouseMoveWasSimulated() && !qApp->isMouseHidden()) {
|
||||
//If we are in oculus, render reticle later
|
||||
|
@ -541,8 +521,8 @@ void ApplicationOverlay::renderPointers() {
|
|||
_magActive[MOUSE] = false;
|
||||
renderControllerPointers();
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
//glBindTexture(GL_TEXTURE_2D, 0);
|
||||
//glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
void ApplicationOverlay::renderControllerPointers() {
|
||||
|
|
|
@ -72,7 +72,6 @@ private:
|
|||
float _hmdUIAngularSize = DEFAULT_HMD_UI_ANGULAR_SIZE;
|
||||
QOpenGLFramebufferObject* _framebufferObject;
|
||||
|
||||
void renderReticle(gpu::Batch& batch, glm::quat orientation, float alpha);
|
||||
void renderPointers();
|
||||
void renderMagnifier(glm::vec2 magPos, float sizeMult, bool showBorder);
|
||||
|
||||
|
@ -83,6 +82,7 @@ private:
|
|||
void renderCameraToggle();
|
||||
void renderStatsAndLogs();
|
||||
void renderDomainConnectionStatusBorder();
|
||||
void bindCursorTexture(gpu::Batch& batch, uint8_t cursorId = 0);
|
||||
|
||||
void buildFramebufferObject();
|
||||
|
||||
|
@ -104,7 +104,8 @@ private:
|
|||
float _trailingAudioLoudness;
|
||||
|
||||
|
||||
gpu::TexturePointer _crosshairTexture;
|
||||
QMap<uint16_t, gpu::TexturePointer> _cursors;
|
||||
|
||||
GLuint _newUiTexture{ 0 };
|
||||
|
||||
int _reticleQuad;
|
||||
|
|
92
libraries/ui/src/CursorManager.cpp
Normal file
92
libraries/ui/src/CursorManager.cpp
Normal file
|
@ -0,0 +1,92 @@
|
|||
//
|
||||
// Created by Bradley Austin Davis on 2015/06/08
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "CursorManager.h"
|
||||
|
||||
#include <QCursor>
|
||||
#include <QWidget>
|
||||
#include <QUrl>
|
||||
|
||||
#include <PathUtils.h>
|
||||
|
||||
namespace Cursor {
|
||||
|
||||
void Instance::setIcon(uint16_t icon) {
|
||||
_icon = icon;
|
||||
}
|
||||
|
||||
uint16_t Instance::getIcon() const {
|
||||
return _icon;
|
||||
}
|
||||
|
||||
|
||||
class MouseInstance : public Instance {
|
||||
Source getType() const {
|
||||
return Source::MOUSE;
|
||||
}
|
||||
|
||||
ivec2 getScreenPosition() const {
|
||||
return toGlm(QCursor::pos());
|
||||
}
|
||||
|
||||
ivec2 getWindowPosition(QWidget* widget) const {
|
||||
return toGlm(widget->mapFromGlobal(QCursor::pos()));
|
||||
}
|
||||
|
||||
vec2 getRelativePosition(QWidget* widget) const {
|
||||
vec2 pos = getWindowPosition(widget);
|
||||
pos /= vec2(toGlm(widget->size()));
|
||||
return pos;
|
||||
}
|
||||
};
|
||||
|
||||
static QMap<uint16_t, QString> ICONS;
|
||||
static uint16_t _customIconId = Icon::USER_BASE;
|
||||
|
||||
Manager::Manager() {
|
||||
ICONS[Icon::DEFAULT] = PathUtils::resourcesPath() + "images/arrow.png";
|
||||
ICONS[Icon::LINK] = PathUtils::resourcesPath() + "images/reticleLink.png";
|
||||
}
|
||||
|
||||
Manager& Manager::instance() {
|
||||
static Manager instance;
|
||||
return instance;
|
||||
}
|
||||
|
||||
uint8_t Manager::getCount() {
|
||||
return 1;
|
||||
}
|
||||
|
||||
Instance* Manager::getCursor(uint8_t index) {
|
||||
Q_ASSERT(index < getCount());
|
||||
static MouseInstance mouseInstance;
|
||||
if (index == 0) {
|
||||
return &mouseInstance;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
uint16_t Manager::registerIcon(const QString& path) {
|
||||
ICONS[_customIconId] = path;
|
||||
return _customIconId++;
|
||||
}
|
||||
|
||||
const QString& Manager::getIconImage(uint16_t icon) {
|
||||
Q_ASSERT(ICONS.count(icon));
|
||||
return ICONS[icon];
|
||||
}
|
||||
|
||||
float Manager::getScale() {
|
||||
return _scale;
|
||||
}
|
||||
|
||||
void Manager::setScale(float scale) {
|
||||
_scale = scale;
|
||||
}
|
||||
|
||||
}
|
61
libraries/ui/src/CursorManager.h
Normal file
61
libraries/ui/src/CursorManager.h
Normal file
|
@ -0,0 +1,61 @@
|
|||
//
|
||||
// Created by Bradley Austin Davis on 2015/06/08
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
|
||||
#include <GLMHelpers.h>
|
||||
|
||||
namespace Cursor {
|
||||
enum class Source {
|
||||
MOUSE,
|
||||
LEFT_HAND,
|
||||
RIGHT_HAND,
|
||||
UNKNOWN,
|
||||
};
|
||||
|
||||
enum Icon {
|
||||
DEFAULT,
|
||||
LINK,
|
||||
GRAB,
|
||||
|
||||
// Add new system cursors here
|
||||
|
||||
// User cursors will have ids over this value
|
||||
USER_BASE = 0xFF,
|
||||
};
|
||||
|
||||
class Instance {
|
||||
public:
|
||||
virtual Source getType() const = 0;
|
||||
virtual ivec2 getWindowPosition(QWidget* widget) const = 0;
|
||||
virtual vec2 getRelativePosition(QWidget* widget) const = 0;
|
||||
virtual ivec2 getScreenPosition() const = 0;
|
||||
virtual void setIcon(uint16_t icon);
|
||||
virtual uint16_t getIcon() const;
|
||||
private:
|
||||
uint16_t _icon;
|
||||
};
|
||||
|
||||
class Manager {
|
||||
Manager();
|
||||
Manager(const Manager& other) = delete;
|
||||
public:
|
||||
static Manager& instance();
|
||||
uint8_t getCount();
|
||||
float getScale();
|
||||
void setScale(float scale);
|
||||
Instance* getCursor(uint8_t index = 0);
|
||||
uint16_t registerIcon(const QString& path);
|
||||
const QString& getIconImage(uint16_t icon);
|
||||
private:
|
||||
float _scale{ 1.0f };
|
||||
};
|
||||
}
|
||||
|
||||
|
Loading…
Reference in a new issue