first cut at simulating mouse/reticle behavior with input contorllers

This commit is contained in:
Brad Hefta-Gaub 2015-12-15 13:07:47 -08:00
parent 205bc1b790
commit 3dcdfbc0f1
13 changed files with 123 additions and 353 deletions

View file

@ -0,0 +1,39 @@
//
// reticleTest.js
// examples/controllers
//
// Created by Brad Hefta-Gaub on 2015/12/15
// 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
//
var mappingJSON = {
"name": "com.highfidelity.testing.reticleWithJoystick",
"channels": [
{ "from": "Standard.RT", "to": "Actions.ReticleClick", "filters": "constrainToInteger" },
{ "from": "Standard.RX", "to": "Actions.ReticleX",
"filters":
[
{ "type": "pulse", "interval": 0.05 },
{ "type": "scale", "scale": 20 }
]
},
{ "from": "Standard.RY", "to": "Actions.ReticleY",
"filters":
[
{ "type": "pulse", "interval": 0.05 },
{ "type": "scale", "scale": 20 }
]
},
]
};
mapping = Controller.parseMapping(JSON.stringify(mappingJSON));
mapping.enable();
Script.scriptEnding.connect(function(){
mapping.disable();
});

View file

@ -11,7 +11,7 @@
{ "from": "Keyboard.S", "when": "Keyboard.Shift", "to": "Actions.PITCH_DOWN" },
{ "from": "Keyboard.W", "when": "Keyboard.Shift", "to": "Actions.PITCH_UP" },
{ "comment" : "Mouse turn need to be small continuous increments",
"from": { "makeAxis" : [
[ "Keyboard.MouseMoveLeft" ],
@ -75,7 +75,6 @@
{ "from": "Keyboard.S", "to": "Actions.LONGITUDINAL_BACKWARD" },
{ "from": "Keyboard.C", "to": "Actions.VERTICAL_DOWN" },
{ "from": "Keyboard.E", "to": "Actions.VERTICAL_UP" },
{ "from": "Keyboard.Left", "when": "Keyboard.RightMouseButton", "to": "Actions.LATERAL_LEFT" },
{ "from": "Keyboard.Right", "when": "Keyboard.RightMouseButton", "to": "Actions.LATERAL_RIGHT" },
{ "from": "Keyboard.Left", "when": "Keyboard.Shift", "to": "Actions.LATERAL_LEFT" },

View file

@ -13,8 +13,8 @@
{ "type": "scale", "scale": 22.5 }
]
},
{ "from": "Standard.RX", "to": "Actions.Yaw" },
{ "from": "Standard.RX", "to": "Actions.Yaw" },
{ "from": "Standard.RY",
"when": "Application.Grounded",
"to": "Actions.Up",
@ -24,6 +24,7 @@
"invert"
]
},
{ "from": "Standard.RY", "to": "Actions.Up", "filters": "invert"},
{ "from": [ "Standard.DU", "Standard.DL", "Standard.DR", "Standard.DD" ], "to": "Standard.LeftPrimaryThumb" },

View file

@ -382,7 +382,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
_scaleMirror(1.0f),
_rotateMirror(0.0f),
_raiseMirror(0.0f),
_lastMouseMoveWasSimulated(false),
_enableProcessOctreeThread(true),
_runningScriptsWidget(NULL),
_runningScriptsWidgetWasVisible(false),
@ -664,6 +663,21 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
// Setup the userInputMapper with the actions
auto userInputMapper = DependencyManager::get<UserInputMapper>();
connect(userInputMapper.data(), &UserInputMapper::actionEvent, [this](int action, float state) {
if (action == controller::toInt(controller::Action::RETICLE_CLICK)) {
auto globalPos = getReticlePosition();
auto localPos = _glWidget->mapFromGlobal(globalPos);
if (state) {
QMouseEvent mousePress(QEvent::MouseButtonPress, localPos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
sendEvent(_glWidget, &mousePress);
_reticleClickPressed = true;
} else {
QMouseEvent mouseRelease(QEvent::MouseButtonRelease, localPos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier);
sendEvent(_glWidget, &mouseRelease);
_reticleClickPressed = false;
}
return; // nothing else to do
}
if (state) {
if (action == controller::toInt(controller::Action::TOGGLE_MUTE)) {
DependencyManager::get<AudioClient>()->toggleMute();
@ -671,6 +685,14 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
cycleCamera();
} else if (action == controller::toInt(controller::Action::CONTEXT_MENU)) {
VrMenu::toggle(); // show context menu even on non-stereo displays
} else if (action == controller::toInt(controller::Action::RETICLE_X)) {
auto reticlePos = getReticlePosition();
reticlePos.setX(reticlePos.x() + state);
setReticlePosition(reticlePos);
} else if (action == controller::toInt(controller::Action::RETICLE_Y)) {
auto reticlePos = getReticlePosition();
reticlePos.setY(reticlePos.y() + state);
setReticlePosition(reticlePos);
}
}
});
@ -692,8 +714,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
// Setup the keyboardMouseDevice and the user input mapper with the default bindings
userInputMapper->registerDevice(_keyboardMouseDevice->getInputDevice());
userInputMapper->loadDefaultMapping(userInputMapper->getStandardDeviceID());
// check first run...
@ -745,15 +765,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
setActiveEyeTracker();
#endif
_oldHandMouseX[0] = -1;
_oldHandMouseY[0] = -1;
_oldHandMouseX[1] = -1;
_oldHandMouseY[1] = -1;
_oldHandLeftClick[0] = false;
_oldHandRightClick[0] = false;
_oldHandLeftClick[1] = false;
_oldHandRightClick[1] = false;
auto applicationUpdater = DependencyManager::get<AutoUpdater>();
connect(applicationUpdater.data(), &AutoUpdater::newVersionIsAvailable, dialogsManager.data(), &DialogsManager::showUpdateDialog);
applicationUpdater->checkForUpdate();
@ -1940,8 +1951,6 @@ void Application::focusOutEvent(QFocusEvent* event) {
void Application::mouseMoveEvent(QMouseEvent* event, unsigned int deviceID) {
PROFILE_RANGE(__FUNCTION__);
// Used by application overlay to determine how to draw cursor(s)
_lastMouseMoveWasSimulated = deviceID > 0;
if (_aboutToQuit) {
return;
@ -1969,11 +1978,20 @@ void Application::mouseMoveEvent(QMouseEvent* event, unsigned int deviceID) {
auto offscreenUi = DependencyManager::get<OffscreenUi>();
QPointF transformedPos = offscreenUi->mapToVirtualScreen(event->localPos(), _glWidget);
auto button = event->button();
auto buttons = event->buttons();
// Determine if the ReticleClick Action is 1 and if so, fake include the LeftMouseButton
if (_reticleClickPressed) {
if (button == Qt::NoButton) {
button = Qt::LeftButton;
}
buttons |= Qt::LeftButton;
}
QMouseEvent mappedEvent(event->type(),
transformedPos,
event->screenPos(), event->button(),
event->buttons(), event->modifiers());
event->screenPos(), button,
buttons, event->modifiers());
getEntities()->mouseMoveEvent(&mappedEvent, deviceID);
_controllerScriptingInterface->emitMouseMoveEvent(&mappedEvent, deviceID); // send events to any registered scripts
@ -2877,13 +2895,6 @@ void Application::update(float deltaTime) {
Hand* hand = DependencyManager::get<AvatarManager>()->getMyAvatar()->getHand();
setPalmData(hand, leftHand, deltaTime, HandData::LeftHand, userInputMapper->getActionState(controller::Action::LEFT_HAND_CLICK));
setPalmData(hand, rightHand, deltaTime, HandData::RightHand, userInputMapper->getActionState(controller::Action::RIGHT_HAND_CLICK));
if (Menu::getInstance()->isOptionChecked(MenuOption::EnableHandMouseInput)) {
emulateMouse(hand, userInputMapper->getActionState(controller::Action::LEFT_HAND_CLICK),
userInputMapper->getActionState(controller::Action::SHIFT), HandData::LeftHand);
emulateMouse(hand, userInputMapper->getActionState(controller::Action::RIGHT_HAND_CLICK),
userInputMapper->getActionState(controller::Action::SHIFT), HandData::RightHand);
}
updateThreads(deltaTime); // If running non-threaded, then give the threads some time to process...
updateDialogs(deltaTime); // update various stats dialogs if present
@ -4742,6 +4753,14 @@ bool Application::isThrottleRendering() const {
return getActiveDisplayPlugin()->isThrottled();
}
QPoint Application::getReticlePosition() const {
return QCursor::pos();
}
void Application::setReticlePosition(QPoint position) {
QCursor::setPos(position);
}
ivec2 Application::getTrueMouse() const {
return toGlm(_glWidget->mapFromGlobal(QCursor::pos()));
}
@ -5062,125 +5081,6 @@ void Application::setPalmData(Hand* hand, const controller::Pose& pose, float de
});
}
void Application::emulateMouse(Hand* hand, float click, float shift, HandData::Hand whichHand) {
auto palms = hand->getCopyOfPalms();
// Locate the palm, if it exists and is active
PalmData* palm;
bool foundHand = false;
for (size_t j = 0; j < palms.size(); j++) {
if (palms[j].whichHand() == whichHand) {
palm = &(palms[j]);
foundHand = true;
break;
}
}
if (!foundHand || !palm->isActive()) {
return;
}
// Process the mouse events
QPoint pos;
// FIXME - this mouse emulation stuff needs to be reworked for new controller input plugins
unsigned int deviceID = whichHand == HandData::LeftHand ? CONTROLLER_0_EVENT : CONTROLLER_1_EVENT;
int index = (int)whichHand; // FIXME - hack attack
if (isHMDMode()) {
pos = getApplicationCompositor().getPalmClickLocation(palm);
} else {
// Get directon relative to avatar orientation
glm::vec3 direction = glm::inverse(getMyAvatar()->getOrientation()) * palm->getFingerDirection();
// Get the angles, scaled between (-0.5,0.5)
float xAngle = (atan2f(direction.z, direction.x) + (float)M_PI_2);
float yAngle = 0.5f - ((atan2f(direction.z, direction.y) + (float)M_PI_2));
auto canvasSize = getCanvasSize();
// Get the pixel range over which the xAngle and yAngle are scaled
float cursorRange = canvasSize.x * controller::InputDevice::getCursorPixelRangeMult();
pos.setX(canvasSize.x / 2.0f + cursorRange * xAngle);
pos.setY(canvasSize.y / 2.0f + cursorRange * yAngle);
}
//If we are off screen then we should stop processing, and if a trigger or bumper is pressed,
//we should unpress them.
if (pos.x() == INT_MAX) {
if (_oldHandLeftClick[index]) {
QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, Qt::LeftButton, Qt::LeftButton, 0);
mouseReleaseEvent(&mouseEvent, deviceID);
_oldHandLeftClick[index] = false;
}
if (_oldHandRightClick[index]) {
QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, Qt::RightButton, Qt::RightButton, 0);
mouseReleaseEvent(&mouseEvent, deviceID);
_oldHandRightClick[index] = false;
}
return;
}
//If position has changed, emit a mouse move to the application
if (pos.x() != _oldHandMouseX[index] || pos.y() != _oldHandMouseY[index]) {
QMouseEvent mouseEvent(QEvent::MouseMove, pos, Qt::NoButton, Qt::NoButton, 0);
// Only send the mouse event if the opposite left button isnt held down.
// Is this check necessary?
if (!_oldHandLeftClick[(int)(!index)]) {
mouseMoveEvent(&mouseEvent, deviceID);
}
}
_oldHandMouseX[index] = pos.x();
_oldHandMouseY[index] = pos.y();
//We need separate coordinates for clicks, since we need to check if
//a magnification window was clicked on
int clickX = pos.x();
int clickY = pos.y();
//Set pos to the new click location, which may be the same if no magnification window is open
pos.setX(clickX);
pos.setY(clickY);
// Right click
if (shift == 1.0f && click == 1.0f) {
if (!_oldHandRightClick[index]) {
_oldHandRightClick[index] = true;
QMouseEvent mouseEvent(QEvent::MouseButtonPress, pos, Qt::RightButton, Qt::RightButton, 0);
mousePressEvent(&mouseEvent, deviceID);
}
} else if (_oldHandRightClick[index]) {
QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, Qt::RightButton, Qt::RightButton, 0);
mouseReleaseEvent(&mouseEvent, deviceID);
_oldHandRightClick[index] = false;
}
// Left click
if (shift != 1.0f && click == 1.0f) {
if (!_oldHandLeftClick[index]) {
_oldHandLeftClick[index] = true;
QMouseEvent mouseEvent(QEvent::MouseButtonPress, pos, Qt::LeftButton, Qt::LeftButton, 0);
mousePressEvent(&mouseEvent, deviceID);
}
} else if (_oldHandLeftClick[index]) {
QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, Qt::LeftButton, Qt::LeftButton, 0);
mouseReleaseEvent(&mouseEvent, deviceID);
_oldHandLeftClick[index] = false;
}
}
void Application::crashApplication() {
qCDebug(interfaceapp) << "Intentionally crashed Interface";
QObject* object = nullptr;

View file

@ -143,9 +143,11 @@ public:
EntityTreeRenderer* getEntityClipboardRenderer() { return &_entityClipboardRenderer; }
EntityEditPacketSender* getEntityEditPacketSender() { return &_entityEditSender; }
QPoint getReticlePosition() const;
void setReticlePosition(QPoint position);
ivec2 getMouse() const;
ivec2 getTrueMouse() const;
bool getLastMouseMoveWasSimulated() const { return _lastMouseMoveWasSimulated; }
FaceTracker* getActiveFaceTracker();
FaceTracker* getSelectedFaceTracker();
@ -361,7 +363,6 @@ private:
void update(float deltaTime);
void setPalmData(Hand* hand, const controller::Pose& pose, float deltaTime, HandData::Hand whichHand, float triggerValue);
void emulateMouse(Hand* hand, float click, float shift, HandData::Hand whichHand);
// Various helper functions called during update()
void updateLOD();
@ -476,8 +477,6 @@ private:
Environment _environment;
bool _lastMouseMoveWasSimulated;
QSet<int> _keysPressed;
bool _enableProcessOctreeThread;
@ -537,14 +536,6 @@ private:
ApplicationCompositor _compositor;
OverlayConductor _overlayConductor;
// FIXME - Hand Controller to mouse emulation helpers. This is crufty and should be moved
// into the input plugins or something.
int _oldHandMouseX[(int)HandData::NUMBER_OF_HANDS];
int _oldHandMouseY[(int)HandData::NUMBER_OF_HANDS];
bool _oldHandLeftClick[(int)HandData::NUMBER_OF_HANDS];
bool _oldHandRightClick[(int)HandData::NUMBER_OF_HANDS];
DialogsManagerScriptingInterface* _dialogsManagerScriptingInterface = new DialogsManagerScriptingInterface();
EntityItemID _keyboardFocusedItem;
@ -559,6 +550,8 @@ private:
bool _inPaint = false;
bool _isGLInitialized { false };
bool _physicsEnabled { false };
bool _reticleClickPressed { false };
};
#endif // hifi_Application_h

View file

@ -477,7 +477,6 @@ Menu::Menu() {
MenuWrapper* handOptionsMenu = developerMenu->addMenu("Hands");
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false);
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::EnableHandMouseInput, 0, false);
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::LowVelocityFilter, 0, true,
qApp, SLOT(setLowVelocityFilter(bool)));

View file

@ -219,7 +219,6 @@ namespace MenuOption {
const QString FrameTimer = "Show Timer";
const QString FullscreenMirror = "Fullscreen Mirror";
const QString GlowWhenSpeaking = "Glow When Speaking";
const QString EnableHandMouseInput = "Enable Hand Controller Mouse Input";
const QString IncreaseAvatarSize = "Increase Avatar Size";
const QString IndependentMode = "Independent Mode";
const QString InputMenu = "Avatar>Input Devices";

View file

@ -115,10 +115,6 @@ bool raySphereIntersect(const glm::vec3 &dir, const glm::vec3 &origin, float r,
ApplicationCompositor::ApplicationCompositor() :
_alphaPropertyAnimation(new QPropertyAnimation(this, "alpha"))
{
memset(_reticleActive, 0, sizeof(_reticleActive));
memset(_magActive, 0, sizeof(_reticleActive));
memset(_magSizeMult, 0, sizeof(_magSizeMult));
auto geometryCache = DependencyManager::get<GeometryCache>();
_reticleQuad = geometryCache->allocateID();
@ -219,9 +215,6 @@ void ApplicationCompositor::displayOverlayTexture(RenderArgs* renderArgs) {
batch.setResourceTexture(0, overlayFramebuffer->getRenderBuffer(0));
geometryCache->renderUnitQuad(batch, vec4(vec3(1), _alpha));
// Doesn't actually render
renderPointers(batch);
//draw the mouse pointer
// Get the mouse coordinates and convert to NDC [-1, 1]
vec2 canvasSize = qApp->getCanvasSize();
@ -306,8 +299,7 @@ void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int
}
#endif
// Doesn't actually render
renderPointers(batch);
vec3 reticleScale = vec3(Cursor::Manager::instance().getScale() * reticleSize);
bindCursorTexture(batch);
@ -316,34 +308,13 @@ void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int
glm::mat4 overlayXfm;
_modelTransform.getMatrix(overlayXfm);
// Only render the hand pointers if the EnableHandMouseInput is enabled
if (Menu::getInstance()->isOptionChecked(MenuOption::EnableHandMouseInput)) {
MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
auto palms = myAvatar->getHand()->getCopyOfPalms();
for (const auto& palm : palms) {
if (palm.isActive()) {
glm::vec2 polar = getPolarCoordinates(palm);
// 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, reticleScale);
batch.setModelTransform(reticleXfm);
// Render reticle at location
geometryCache->renderUnitQuad(batch, glm::vec4(1), _reticleQuad);
}
}
}
//Mouse Pointer
if (_reticleActive[MOUSE]) {
glm::vec2 projection = screenToSpherical(glm::vec2(_reticlePosition[MOUSE].x(),
_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, reticleScale);
batch.setModelTransform(reticleXfm);
geometryCache->renderUnitQuad(batch, glm::vec4(1), _reticleQuad);
}
glm::vec2 projection = screenToSpherical(qApp->getTrueMouse());
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, reticleScale);
batch.setModelTransform(reticleXfm);
geometryCache->renderUnitQuad(batch, glm::vec4(1), _reticleQuad);
});
}
@ -423,124 +394,6 @@ bool ApplicationCompositor::calculateRayUICollisionPoint(const glm::vec3& positi
return false;
}
//Renders optional pointers
void ApplicationCompositor::renderPointers(gpu::Batch& batch) {
if (qApp->isHMDMode() && !qApp->getLastMouseMoveWasSimulated()) {
//If we are in oculus, render reticle later
auto trueMouse = qApp->getTrueMouse();
trueMouse /= qApp->getCanvasSize();
QPoint position = QPoint(qApp->getTrueMouse().x, qApp->getTrueMouse().y);
_reticlePosition[MOUSE] = position;
_reticleActive[MOUSE] = true;
_magActive[MOUSE] = _magnifier;
_reticleActive[LEFT_CONTROLLER] = false;
_reticleActive[RIGHT_CONTROLLER] = false;
} else if (qApp->getLastMouseMoveWasSimulated()
&& Menu::getInstance()->isOptionChecked(MenuOption::EnableHandMouseInput)) {
//only render controller pointer if we aren't already rendering a mouse pointer
_reticleActive[MOUSE] = false;
_magActive[MOUSE] = false;
renderControllerPointers(batch);
}
}
// FIXME - this is old code that likely needs to be removed and/or reworked to support the new input control model
void ApplicationCompositor::renderControllerPointers(gpu::Batch& batch) {
MyAvatar* myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
//Static variables used for storing controller state
static quint64 pressedTime[NUMBER_OF_RETICLES] = { 0ULL, 0ULL, 0ULL };
static bool isPressed[NUMBER_OF_RETICLES] = { false, false, false };
static bool stateWhenPressed[NUMBER_OF_RETICLES] = { false, false, false };
const HandData* handData = DependencyManager::get<AvatarManager>()->getMyAvatar()->getHandData();
auto palms = handData->getCopyOfPalms();
for (unsigned int palmIndex = 2; palmIndex < 4; palmIndex++) {
const int index = palmIndex - 1;
const PalmData* palmData = NULL;
if (palmIndex >= palms.size()) {
return;
}
if (palms[palmIndex].isActive()) {
palmData = &palms[palmIndex];
} else {
continue;
}
if (isPressed[index]) {
isPressed[index] = false;
//If the button was only pressed for < 250 ms
//then disable it.
const int MAX_BUTTON_PRESS_TIME = 250 * MSECS_TO_USECS;
if (usecTimestampNow() < pressedTime[index] + MAX_BUTTON_PRESS_TIME) {
_magActive[index] = !stateWhenPressed[index];
}
}
//if we have the oculus, we should make the cursor smaller since it will be
//magnified
if (qApp->isHMDMode()) {
QPoint point = getPalmClickLocation(palmData);
_reticlePosition[index] = point;
//When button 2 is pressed we drag the mag window
if (isPressed[index]) {
_magActive[index] = true;
}
// If oculus is enabled, we draw the crosshairs later
continue;
}
auto canvasSize = qApp->getCanvasSize();
int mouseX, mouseY;
// Get directon relative to avatar orientation
glm::vec3 direction = glm::inverse(myAvatar->getOrientation()) * palmData->getFingerDirection();
// Get the angles, scaled between (-0.5,0.5)
float xAngle = (atan2f(direction.z, direction.x) + PI_OVER_TWO);
float yAngle = 0.5f - ((atan2f(direction.z, direction.y) + (float)PI_OVER_TWO));
// Get the pixel range over which the xAngle and yAngle are scaled
float cursorRange = canvasSize.x * controller::InputDevice::getCursorPixelRangeMult();
mouseX = (canvasSize.x / 2.0f + cursorRange * xAngle);
mouseY = (canvasSize.y / 2.0f + cursorRange * yAngle);
//If the cursor is out of the screen then don't render it
if (mouseX < 0 || mouseX >= (int)canvasSize.x || mouseY < 0 || mouseY >= (int)canvasSize.y) {
_reticleActive[index] = false;
continue;
}
_reticleActive[index] = true;
const float reticleSize = 40.0f;
mouseX -= reticleSize / 2.0f;
mouseY += reticleSize / 2.0f;
glm::vec2 topLeft(mouseX, mouseY);
glm::vec2 bottomRight(mouseX + reticleSize, mouseY - reticleSize);
glm::vec2 texCoordTopLeft(0.0f, 0.0f);
glm::vec2 texCoordBottomRight(1.0f, 1.0f);
DependencyManager::get<GeometryCache>()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight,
glm::vec4(RETICLE_COLOR[0], RETICLE_COLOR[1], RETICLE_COLOR[2], 1.0f));
}
}
void ApplicationCompositor::buildHemiVertices(
const float fov, const float aspectRatio, const int slices, const int stacks) {
static float textureFOV = 0.0f, textureAspectRatio = 1.0f;

View file

@ -92,9 +92,6 @@ private:
void drawSphereSection(gpu::Batch& batch);
void updateTooltips();
void renderPointers(gpu::Batch& batch);
void renderControllerPointers(gpu::Batch& batch);
vec2 getPolarCoordinates(const PalmData& palm) const;
// Support for hovering and tooltips
@ -109,11 +106,6 @@ private:
float _textureAspectRatio{ 1.0f };
int _hemiVerticesID{ GeometryCache::UNKNOWN_ID };
enum Reticles { MOUSE, LEFT_CONTROLLER, RIGHT_CONTROLLER, NUMBER_OF_RETICLES };
bool _reticleActive[NUMBER_OF_RETICLES];
QPoint _reticlePosition[NUMBER_OF_RETICLES];
bool _magActive[NUMBER_OF_RETICLES];
float _magSizeMult[NUMBER_OF_RETICLES];
bool _magnifier{ true };
float _alpha{ 1.0f };

View file

@ -62,6 +62,14 @@ namespace controller {
makeButtonPair(Action::TOGGLE_MUTE, "ToggleMute"),
makeButtonPair(Action::CYCLE_CAMERA, "CycleCamera"),
makeAxisPair(Action::RETICLE_CLICK, "ReticleClick"),
makeAxisPair(Action::RETICLE_X, "ReticleX"),
makeAxisPair(Action::RETICLE_Y, "ReticleY"),
makeAxisPair(Action::RETICLE_LEFT, "ReticleLeft"),
makeAxisPair(Action::RETICLE_RIGHT, "ReticleRight"),
makeAxisPair(Action::RETICLE_UP, "ReticleUp"),
makeAxisPair(Action::RETICLE_DOWN, "ReticleDown"),
// Aliases and bisected versions
makeAxisPair(Action::LONGITUDINAL_BACKWARD, "Backward"),
makeAxisPair(Action::LONGITUDINAL_FORWARD, "Forward"),

View file

@ -55,6 +55,17 @@ enum class Action {
SHIFT,
// Pointer/Reticle control
RETICLE_CLICK,
RETICLE_X,
RETICLE_Y,
// Biseced aliases for RETICLE_X/RETICLE_Y
RETICLE_LEFT,
RETICLE_RIGHT,
RETICLE_UP,
RETICLE_DOWN,
// Biseced aliases for TRANSLATE_Z
LONGITUDINAL_BACKWARD,
LONGITUDINAL_FORWARD,
@ -78,7 +89,7 @@ enum class Action {
// Biseced aliases for TRANSLATE_CAMERA_Z
BOOM_IN,
BOOM_OUT,
NUM_ACTIONS,
};

View file

@ -255,6 +255,9 @@ void UserInputMapper::update(float deltaTime) {
fixBisectedAxis(_actionStates[toInt(Action::ROTATE_Y)], _actionStates[toInt(Action::YAW_LEFT)], _actionStates[toInt(Action::YAW_RIGHT)]);
fixBisectedAxis(_actionStates[toInt(Action::ROTATE_X)], _actionStates[toInt(Action::PITCH_UP)], _actionStates[toInt(Action::PITCH_DOWN)]);
fixBisectedAxis(_actionStates[toInt(Action::RETICLE_X)], _actionStates[toInt(Action::RETICLE_LEFT)], _actionStates[toInt(Action::RETICLE_RIGHT)]);
fixBisectedAxis(_actionStates[toInt(Action::RETICLE_Y)], _actionStates[toInt(Action::RETICLE_UP)], _actionStates[toInt(Action::RETICLE_DOWN)]);
static const float EPSILON = 0.01f;
for (auto i = 0; i < toInt(Action::NUM_ACTIONS); i++) {
_actionStates[i] *= _actionScales[i];
@ -319,42 +322,12 @@ QVector<QString> UserInputMapper::getActionNames() const {
}
return result;
}
/*
void UserInputMapper::assignDefaulActionScales() {
_actionScales[toInt(Action::LONGITUDINAL_BACKWARD)] = 1.0f; // 1m per unit
_actionScales[toInt(Action::LONGITUDINAL_FORWARD)] = 1.0f; // 1m per unit
_actionScales[toInt(Action::LATERAL_LEFT)] = 1.0f; // 1m per unit
_actionScales[toInt(Action::LATERAL_RIGHT)] = 1.0f; // 1m per unit
_actionScales[toInt(Action::VERTICAL_DOWN)] = 1.0f; // 1m per unit
_actionScales[toInt(Action::VERTICAL_UP)] = 1.0f; // 1m per unit
_actionScales[toInt(Action::YAW_LEFT)] = 1.0f; // 1 degree per unit
_actionScales[toInt(Action::YAW_RIGHT)] = 1.0f; // 1 degree per unit
_actionScales[toInt(Action::PITCH_DOWN)] = 1.0f; // 1 degree per unit
_actionScales[toInt(Action::PITCH_UP)] = 1.0f; // 1 degree per unit
_actionScales[toInt(Action::BOOM_IN)] = 0.5f; // .5m per unit
_actionScales[toInt(Action::BOOM_OUT)] = 0.5f; // .5m per unit
_actionScales[toInt(Action::LEFT_HAND)] = 1.0f; // default
_actionScales[toInt(Action::RIGHT_HAND)] = 1.0f; // default
_actionScales[toInt(Action::LEFT_HAND_CLICK)] = 1.0f; // on
_actionScales[toInt(Action::RIGHT_HAND_CLICK)] = 1.0f; // on
_actionScales[toInt(Action::SHIFT)] = 1.0f; // on
_actionScales[toInt(Action::ACTION1)] = 1.0f; // default
_actionScales[toInt(Action::ACTION2)] = 1.0f; // default
_actionScales[toInt(Action::TRANSLATE_X)] = 1.0f; // default
_actionScales[toInt(Action::TRANSLATE_Y)] = 1.0f; // default
_actionScales[toInt(Action::TRANSLATE_Z)] = 1.0f; // default
_actionScales[toInt(Action::ROLL)] = 1.0f; // default
_actionScales[toInt(Action::PITCH)] = 1.0f; // default
_actionScales[toInt(Action::YAW)] = 1.0f; // default
}
*/
static int actionMetaTypeId = qRegisterMetaType<Action>();
static int inputMetaTypeId = qRegisterMetaType<Input>();
static int inputPairMetaTypeId = qRegisterMetaType<Input::NamedPair>();
static int poseMetaTypeId = qRegisterMetaType<controller::Pose>("Pose");
QScriptValue inputToScriptValue(QScriptEngine* engine, const Input& input);
void inputFromScriptValue(const QScriptValue& object, Input& input);
QScriptValue actionToScriptValue(QScriptEngine* engine, const Action& action);

View file

@ -99,6 +99,9 @@ void KeyboardMouseDevice::mouseMoveEvent(QMouseEvent* event, unsigned int device
_inputDevice->_axisStateMap[MOUSE_AXIS_Y_POS] = (currentMove.y() < 0 ? -currentMove.y() : 0.0f);
_inputDevice->_axisStateMap[MOUSE_AXIS_Y_NEG] = (currentMove.y() > 0 ? currentMove.y() : 0.0f);
// FIXME - this has the characteristic that it will show large jumps when you move the cursor
// outside of the application window, because we don't get MouseEvents when the cursor is outside
// of the application window.
_lastCursor = currentPos;
_mouseMoved = true;