mirror of
https://github.com/overte-org/overte.git
synced 2025-04-08 07:12:40 +02:00
Merge pull request #14645 from ctrlaltdavid/M19774-d
Make mouselook directly proportional to right-click mouse
This commit is contained in:
commit
fd09180776
60 changed files with 331 additions and 223 deletions
|
@ -123,7 +123,16 @@
|
|||
|
||||
{ "from": { "makeAxis" : ["Keyboard.MouseMoveLeft", "Keyboard.MouseMoveRight"] },
|
||||
"when": "Keyboard.RightMouseButton",
|
||||
"to": "Actions.Yaw",
|
||||
"to": "Actions.DeltaYaw",
|
||||
"filters":
|
||||
[
|
||||
{ "type": "scale", "scale": 0.6 }
|
||||
]
|
||||
},
|
||||
|
||||
{ "from": { "makeAxis" : ["Keyboard.MouseMoveUp", "Keyboard.MouseMoveDown"] },
|
||||
"when": "Keyboard.RightMouseButton",
|
||||
"to": "Actions.DeltaPitch",
|
||||
"filters":
|
||||
[
|
||||
{ "type": "scale", "scale": 0.6 }
|
||||
|
@ -144,20 +153,6 @@
|
|||
{ "from": "Keyboard.PgDown", "to": "Actions.VERTICAL_DOWN" },
|
||||
{ "from": "Keyboard.PgUp", "to": "Actions.VERTICAL_UP" },
|
||||
|
||||
{ "from": "Keyboard.MouseMoveUp", "when": "Keyboard.RightMouseButton", "to": "Actions.PITCH_UP",
|
||||
"filters":
|
||||
[
|
||||
{ "type": "scale", "scale": 0.6 }
|
||||
]
|
||||
|
||||
},
|
||||
{ "from": "Keyboard.MouseMoveDown", "when": "Keyboard.RightMouseButton", "to": "Actions.PITCH_DOWN",
|
||||
"filters":
|
||||
[
|
||||
{ "type": "scale", "scale": 0.6 }
|
||||
]
|
||||
},
|
||||
|
||||
{ "from": "Keyboard.TouchpadDown", "to": "Actions.PITCH_DOWN" },
|
||||
{ "from": "Keyboard.TouchpadUp", "to": "Actions.PITCH_UP" },
|
||||
|
||||
|
|
|
@ -5967,6 +5967,8 @@ void Application::update(float deltaTime) {
|
|||
if (deltaTime > FLT_EPSILON) {
|
||||
myAvatar->setDriveKey(MyAvatar::PITCH, -1.0f * userInputMapper->getActionState(controller::Action::PITCH));
|
||||
myAvatar->setDriveKey(MyAvatar::YAW, -1.0f * userInputMapper->getActionState(controller::Action::YAW));
|
||||
myAvatar->setDriveKey(MyAvatar::DELTA_PITCH, -1.0f * userInputMapper->getActionState(controller::Action::DELTA_PITCH));
|
||||
myAvatar->setDriveKey(MyAvatar::DELTA_YAW, -1.0f * userInputMapper->getActionState(controller::Action::DELTA_YAW));
|
||||
myAvatar->setDriveKey(MyAvatar::STEP_YAW, -1.0f * userInputMapper->getActionState(controller::Action::STEP_YAW));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3178,9 +3178,10 @@ void MyAvatar::updateOrientation(float deltaTime) {
|
|||
_bodyYawDelta = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
float totalBodyYaw = _bodyYawDelta * deltaTime;
|
||||
|
||||
// Rotate directly proportional to delta yaw and delta pitch from right-click mouse movement.
|
||||
totalBodyYaw += getDriveKey(DELTA_YAW) * _yawSpeed / YAW_SPEED_DEFAULT;
|
||||
|
||||
// Comfort Mode: If you press any of the left/right rotation drive keys or input, you'll
|
||||
// get an instantaneous 15 degree turn. If you keep holding the key down you'll get another
|
||||
|
@ -3248,7 +3249,8 @@ void MyAvatar::updateOrientation(float deltaTime) {
|
|||
head->setBaseRoll(ROLL(euler));
|
||||
} else {
|
||||
head->setBaseYaw(0.0f);
|
||||
head->setBasePitch(getHead()->getBasePitch() + getDriveKey(PITCH) * _pitchSpeed * deltaTime);
|
||||
head->setBasePitch(getHead()->getBasePitch() + getDriveKey(PITCH) * _pitchSpeed * deltaTime
|
||||
+ getDriveKey(DELTA_PITCH) * _pitchSpeed / PITCH_SPEED_DEFAULT);
|
||||
head->setBaseRoll(0.0f);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -265,6 +265,8 @@ public:
|
|||
STEP_YAW,
|
||||
PITCH,
|
||||
ZOOM,
|
||||
DELTA_YAW,
|
||||
DELTA_PITCH,
|
||||
MAX_DRIVE_KEYS
|
||||
};
|
||||
Q_ENUM(DriveKeys)
|
||||
|
|
|
@ -223,7 +223,7 @@ Pointer::Buttons PathPointer::getPressedButtons(const PickResultPointer& pickRes
|
|||
std::string button = trigger.getButton();
|
||||
TriggerState& state = _states[button];
|
||||
// TODO: right now, LaserPointers don't support axes, only on/off buttons
|
||||
if (trigger.getEndpoint()->peek() >= 1.0f) {
|
||||
if (trigger.getEndpoint()->peek().value >= 1.0f) {
|
||||
toReturn.insert(button);
|
||||
|
||||
if (_previousButtons.find(button) == _previousButtons.end()) {
|
||||
|
|
|
@ -104,7 +104,7 @@ class ScriptEngine;
|
|||
* <ul>
|
||||
* <li>{@link Controller.getValue|getValue}</li>
|
||||
* <li>{@link Controller.getAxisValue|getAxisValue}</li>
|
||||
* <li>{@link Controller.getPoseValue|getgetPoseValue}</li>
|
||||
* <li>{@link Controller.getPoseValue|getPoseValue}</li>
|
||||
* <li>{@link Controller.getActionValue|getActionValue}</li>
|
||||
* </ul>
|
||||
*
|
||||
|
|
|
@ -52,11 +52,17 @@ namespace controller {
|
|||
* <tr><td><code>TranslateZ</code></td><td>number</td><td>number</td><td>Move the user's avatar in the direction of its
|
||||
* z-axis, if the camera isn't in independent or mirror modes.</td></tr>
|
||||
* <tr><td><code>Pitch</code></td><td>number</td><td>number</td><td>Rotate the user's avatar head and attached camera
|
||||
* about its negative x-axis (i.e., positive values pitch down), if the camera isn't in HMD, independent, or mirror
|
||||
* modes.</td></tr>
|
||||
* <tr><td><code>Yaw</code></td><td>number</td><td>number</td><td>Rotate the user's avatar about its y-axis, if the
|
||||
* camera isn't in independent or mirror modes.</td></tr>
|
||||
* about its negative x-axis (i.e., positive values pitch down) at a rate proportional to the control value, if the
|
||||
* camera isn't in HMD, independent, or mirror modes.</td></tr>
|
||||
* <tr><td><code>Yaw</code></td><td>number</td><td>number</td><td>Rotate the user's avatar about its y-axis at a rate
|
||||
* proportional to the control value, if the camera isn't in independent or mirror modes.</td></tr>
|
||||
* <tr><td><code>Roll</code></td><td>number</td><td>number</td><td>No action.</td></tr>
|
||||
* <tr><td><code>DeltaPitch</code></td><td>number</td><td>number</td><td>Rotate the user's avatar head and attached
|
||||
* camera about its negative x-axis (i.e., positive values pitch down) by an amount proportional to the control value,
|
||||
* if the camera isn't in HMD, independent, or mirror modes.</td></tr>
|
||||
* <tr><td><code>DeltaYaw</code></td><td>number</td><td>number</td><td>Rotate the user's avatar about its y-axis by an
|
||||
* amount proportional to the control value, if the camera isn't in independent or mirror modes.</td></tr>
|
||||
* <tr><td><code>DeltaRoll</code></td><td>number</td><td>number</td><td>No action.</td></tr>
|
||||
* <tr><td><code>StepTranslateX</code></td><td>number</td><td>number</td><td>No action.</td></tr>
|
||||
* <tr><td><code>StepTranslateY</code></td><td>number</td><td>number</td><td>No action.</td></tr>
|
||||
* <tr><td><code>StepTranslateZ</code></td><td>number</td><td>number</td><td>No action.</td></tr>
|
||||
|
@ -318,6 +324,9 @@ namespace controller {
|
|||
makeAxisPair(Action::ROLL, "Roll"),
|
||||
makeAxisPair(Action::PITCH, "Pitch"),
|
||||
makeAxisPair(Action::YAW, "Yaw"),
|
||||
makeAxisPair(Action::DELTA_YAW, "DeltaYaw"),
|
||||
makeAxisPair(Action::DELTA_PITCH, "DeltaPitch"),
|
||||
makeAxisPair(Action::DELTA_ROLL, "DeltaRoll"),
|
||||
makeAxisPair(Action::STEP_YAW, "StepYaw"),
|
||||
makeAxisPair(Action::STEP_PITCH, "StepPitch"),
|
||||
makeAxisPair(Action::STEP_ROLL, "StepRoll"),
|
||||
|
|
|
@ -27,6 +27,10 @@ enum class Action {
|
|||
ROTATE_Y, YAW = ROTATE_Y,
|
||||
ROTATE_Z, ROLL = ROTATE_Z,
|
||||
|
||||
DELTA_PITCH,
|
||||
DELTA_YAW,
|
||||
DELTA_ROLL,
|
||||
|
||||
STEP_YAW,
|
||||
// FIXME does this have a use case?
|
||||
STEP_PITCH,
|
||||
|
|
21
libraries/controllers/src/controllers/AxisValue.cpp
Normal file
21
libraries/controllers/src/controllers/AxisValue.cpp
Normal file
|
@ -0,0 +1,21 @@
|
|||
//
|
||||
// AxisValue.cpp
|
||||
//
|
||||
// Created by David Rowe on 14 Dec 2018.
|
||||
// Copyright 2018 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 "AxisValue.h"
|
||||
|
||||
namespace controller {
|
||||
|
||||
AxisValue::AxisValue(const float value, const quint64 timestamp) :
|
||||
value(value), timestamp(timestamp) { }
|
||||
|
||||
bool AxisValue::operator==(const AxisValue& right) const {
|
||||
return value == right.value && timestamp == right.timestamp;
|
||||
}
|
||||
}
|
34
libraries/controllers/src/controllers/AxisValue.h
Normal file
34
libraries/controllers/src/controllers/AxisValue.h
Normal file
|
@ -0,0 +1,34 @@
|
|||
//
|
||||
// AxisValue.h
|
||||
//
|
||||
// Created by David Rowe on 13 Dec 2018.
|
||||
// Copyright 2018 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
|
||||
#ifndef hifi_controllers_AxisValue_h
|
||||
#define hifi_controllers_AxisValue_h
|
||||
|
||||
#include <QtCore/qglobal.h>
|
||||
|
||||
namespace controller {
|
||||
|
||||
struct AxisValue {
|
||||
public:
|
||||
float value { 0.0f };
|
||||
// The value can be timestamped to determine if consecutive identical values should be output (e.g., mouse movement).
|
||||
quint64 timestamp { 0 };
|
||||
|
||||
AxisValue() {}
|
||||
AxisValue(const float value, const quint64 timestamp);
|
||||
|
||||
bool operator ==(const AxisValue& right) const;
|
||||
bool operator !=(const AxisValue& right) const { return !(*this == right); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // hifi_controllers_AxisValue_h
|
|
@ -26,12 +26,12 @@ namespace controller {
|
|||
return 0.0f;
|
||||
}
|
||||
|
||||
float InputDevice::getAxis(int channel) const {
|
||||
AxisValue InputDevice::getAxis(int channel) const {
|
||||
auto axis = _axisStateMap.find(channel);
|
||||
if (axis != _axisStateMap.end()) {
|
||||
return (*axis).second;
|
||||
} else {
|
||||
return 0.0f;
|
||||
return AxisValue();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -68,26 +68,25 @@ namespace controller {
|
|||
return Input::NamedPair(makeInput(pose), name);
|
||||
}
|
||||
|
||||
float InputDevice::getValue(ChannelType channelType, uint16_t channel) const {
|
||||
AxisValue InputDevice::getValue(ChannelType channelType, uint16_t channel) const {
|
||||
switch (channelType) {
|
||||
case ChannelType::AXIS:
|
||||
return getAxis(channel);
|
||||
|
||||
case ChannelType::BUTTON:
|
||||
return getButton(channel);
|
||||
return { getButton(channel), 0 };
|
||||
|
||||
case ChannelType::POSE:
|
||||
return getPose(channel).valid ? 1.0f : 0.0f;
|
||||
return { getPose(channel).valid ? 1.0f : 0.0f, 0 };
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return 0.0f;
|
||||
return { 0.0f, 0 };
|
||||
}
|
||||
|
||||
|
||||
float InputDevice::getValue(const Input& input) const {
|
||||
AxisValue InputDevice::getValue(const Input& input) const {
|
||||
return getValue(input.getType(), input.channel);
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include <QtCore/QString>
|
||||
|
||||
#include "AxisValue.h"
|
||||
#include "Pose.h"
|
||||
#include "Input.h"
|
||||
#include "StandardControls.h"
|
||||
|
@ -103,16 +104,16 @@ public:
|
|||
using Pointer = std::shared_ptr<InputDevice>;
|
||||
|
||||
typedef std::unordered_set<int> ButtonPressedMap;
|
||||
typedef std::map<int, float> AxisStateMap;
|
||||
typedef std::map<int, AxisValue> AxisStateMap;
|
||||
typedef std::map<int, Pose> PoseStateMap;
|
||||
|
||||
// Get current state for each channel
|
||||
float getButton(int channel) const;
|
||||
float getAxis(int channel) const;
|
||||
AxisValue getAxis(int channel) const;
|
||||
Pose getPose(int channel) const;
|
||||
|
||||
float getValue(const Input& input) const;
|
||||
float getValue(ChannelType channelType, uint16_t channel) const;
|
||||
AxisValue getValue(const Input& input) const;
|
||||
AxisValue getValue(ChannelType channelType, uint16_t channel) const;
|
||||
Pose getPoseValue(uint16_t channel) const;
|
||||
|
||||
const QString& getName() const { return _name; }
|
||||
|
|
|
@ -297,6 +297,13 @@ namespace controller {
|
|||
return 0.0f;
|
||||
}
|
||||
|
||||
InputRecorder::ActionStates InputRecorder::getActionstates() {
|
||||
if (_actionStateList.size() > 0) {
|
||||
return _actionStateList[_playCount];
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
controller::Pose InputRecorder::getPoseState(const QString& action) {
|
||||
if (_poseStateList.size() > 0) {
|
||||
return _poseStateList[_playCount][action];
|
||||
|
|
|
@ -45,6 +45,7 @@ namespace controller {
|
|||
void setActionState(const QString& action, float value);
|
||||
void setActionState(const QString& action, const controller::Pose& pose);
|
||||
float getActionState(const QString& action);
|
||||
ActionStates getActionstates();
|
||||
controller::Pose getPoseState(const QString& action);
|
||||
QString getSaveDirectory();
|
||||
void frameTick();
|
||||
|
|
|
@ -89,17 +89,17 @@ namespace controller {
|
|||
|
||||
float ScriptingInterface::getValue(const int& source) const {
|
||||
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
||||
return userInputMapper->getValue(Input((uint32_t)source));
|
||||
return userInputMapper->getValue(Input((uint32_t)source)).value;
|
||||
}
|
||||
|
||||
float ScriptingInterface::getAxisValue(int source) const {
|
||||
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
||||
return userInputMapper->getValue(Input((uint32_t)source));
|
||||
return userInputMapper->getValue(Input((uint32_t)source)).value;
|
||||
}
|
||||
|
||||
Pose ScriptingInterface::getPoseValue(const int& source) const {
|
||||
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
||||
return userInputMapper->getPose(Input((uint32_t)source));
|
||||
return userInputMapper->getPose(Input((uint32_t)source));
|
||||
}
|
||||
|
||||
QVector<Action> ScriptingInterface::getAllActions() {
|
||||
|
|
|
@ -290,17 +290,17 @@ void UserInputMapper::update(float deltaTime) {
|
|||
if ((int)_lastStandardStates.size() != standardInputs.size()) {
|
||||
_lastStandardStates.resize(standardInputs.size());
|
||||
for (auto& lastValue : _lastStandardStates) {
|
||||
lastValue = 0;
|
||||
lastValue = AxisValue();
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < standardInputs.size(); ++i) {
|
||||
const auto& input = standardInputs[i].first;
|
||||
float value = getValue(input);
|
||||
float& oldValue = _lastStandardStates[i];
|
||||
AxisValue value = getValue(input);
|
||||
AxisValue& oldValue = _lastStandardStates[i];
|
||||
if (value != oldValue) {
|
||||
oldValue = value;
|
||||
emit inputEvent(input.id, value);
|
||||
emit inputEvent(input.id, value.value);
|
||||
}
|
||||
}
|
||||
inputRecorder->frameTick();
|
||||
|
@ -489,6 +489,21 @@ void UserInputMapper::runMappings() {
|
|||
}
|
||||
applyRoutes(_standardRoutes);
|
||||
|
||||
InputRecorder* inputRecorder = InputRecorder::getInstance();
|
||||
if (inputRecorder->isPlayingback()) {
|
||||
if (debugRoutes) {
|
||||
qCDebug(controllers) << "Playing back recording actions";
|
||||
}
|
||||
|
||||
// Play back each numeric action even if there is no current route active for the action.
|
||||
auto actionStates = inputRecorder->getActionstates();
|
||||
for (InputRecorder::ActionStates::iterator it = actionStates.begin(); it != actionStates.end(); ++it) {
|
||||
setActionState((Action)findAction(it->first), it->second);
|
||||
}
|
||||
|
||||
// Poses are played back in StandardEndpoint.
|
||||
}
|
||||
|
||||
if (debugRoutes) {
|
||||
qCDebug(controllers) << "Done with mappings";
|
||||
}
|
||||
|
@ -604,10 +619,10 @@ bool UserInputMapper::applyRoute(const Route::Pointer& route, bool force) {
|
|||
destination->apply(value, source);
|
||||
} else {
|
||||
// Fetch the value, may have been overriden by previous loopback routes
|
||||
float value = getValue(source, route->peek);
|
||||
auto value = getValue(source, route->peek);
|
||||
|
||||
if (debugRoutes && route->debug) {
|
||||
qCDebug(controllers) << "Value was " << value;
|
||||
qCDebug(controllers) << "Value was " << value.value << value.timestamp;
|
||||
}
|
||||
// Apply each of the filters.
|
||||
for (const auto& filter : route->filters) {
|
||||
|
@ -615,7 +630,7 @@ bool UserInputMapper::applyRoute(const Route::Pointer& route, bool force) {
|
|||
}
|
||||
|
||||
if (debugRoutes && route->debug) {
|
||||
qCDebug(controllers) << "Filtered value was " << value;
|
||||
qCDebug(controllers) << "Filtered value was " << value.value << value.timestamp;
|
||||
}
|
||||
|
||||
destination->apply(value, source);
|
||||
|
@ -741,15 +756,15 @@ void UserInputMapper::enableMapping(const QString& mappingName, bool enable) {
|
|||
}
|
||||
}
|
||||
|
||||
float UserInputMapper::getValue(const Endpoint::Pointer& endpoint, bool peek) {
|
||||
AxisValue UserInputMapper::getValue(const Endpoint::Pointer& endpoint, bool peek) {
|
||||
return peek ? endpoint->peek() : endpoint->value();
|
||||
}
|
||||
|
||||
float UserInputMapper::getValue(const Input& input) const {
|
||||
AxisValue UserInputMapper::getValue(const Input& input) const {
|
||||
Locker locker(_lock);
|
||||
auto endpoint = endpointFor(input);
|
||||
if (!endpoint) {
|
||||
return 0;
|
||||
return AxisValue();
|
||||
}
|
||||
return endpoint->value();
|
||||
}
|
||||
|
|
|
@ -121,7 +121,7 @@ namespace controller {
|
|||
void unloadMappings(const QStringList& jsonFiles);
|
||||
void unloadMapping(const QString& jsonFile);
|
||||
|
||||
float getValue(const Input& input) const;
|
||||
AxisValue getValue(const Input& input) const;
|
||||
Pose getPose(const Input& input) const;
|
||||
|
||||
// perform an action when the UserInputMapper mutex is acquired.
|
||||
|
@ -147,9 +147,9 @@ namespace controller {
|
|||
std::vector<float> _actionScales = std::vector<float>(toInt(Action::NUM_ACTIONS), 1.0f);
|
||||
std::vector<float> _lastActionStates = std::vector<float>(toInt(Action::NUM_ACTIONS), 0.0f);
|
||||
std::vector<Pose> _poseStates = std::vector<Pose>(toInt(Action::NUM_ACTIONS));
|
||||
std::vector<float> _lastStandardStates = std::vector<float>();
|
||||
std::vector<AxisValue> _lastStandardStates = std::vector<AxisValue>();
|
||||
|
||||
static float getValue(const EndpointPointer& endpoint, bool peek = false);
|
||||
static AxisValue getValue(const EndpointPointer& endpoint, bool peek = false);
|
||||
static Pose getPose(const EndpointPointer& endpoint, bool peek = false);
|
||||
|
||||
friend class RouteBuilderProxy;
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#include <QtCore/QObject>
|
||||
|
||||
#include "../AxisValue.h"
|
||||
#include "../Input.h"
|
||||
#include "../Pose.h"
|
||||
|
||||
|
@ -36,9 +37,9 @@ namespace controller {
|
|||
using WriteLambda = std::function<void(float)>;
|
||||
|
||||
Endpoint(const Input& input) : _input(input) {}
|
||||
virtual float value() { return peek(); }
|
||||
virtual float peek() const = 0;
|
||||
virtual void apply(float value, const Pointer& source) = 0;
|
||||
virtual AxisValue value() { return peek(); }
|
||||
virtual AxisValue peek() const = 0;
|
||||
virtual void apply(AxisValue value, const Pointer& source) = 0;
|
||||
virtual Pose peekPose() const { return Pose(); };
|
||||
virtual Pose pose() { return peekPose(); }
|
||||
virtual void apply(const Pose& value, const Pointer& source) {}
|
||||
|
@ -59,8 +60,8 @@ namespace controller {
|
|||
LambdaEndpoint(ReadLambda readLambda, WriteLambda writeLambda = [](float) {})
|
||||
: Endpoint(Input::INVALID_INPUT), _readLambda(readLambda), _writeLambda(writeLambda) { }
|
||||
|
||||
virtual float peek() const override { return _readLambda(); }
|
||||
virtual void apply(float value, const Pointer& source) override { _writeLambda(value); }
|
||||
virtual AxisValue peek() const override { return AxisValue(_readLambda(), 0); }
|
||||
virtual void apply(AxisValue value, const Pointer& source) override { _writeLambda(value.value); }
|
||||
|
||||
private:
|
||||
ReadLambda _readLambda;
|
||||
|
@ -76,8 +77,8 @@ namespace controller {
|
|||
: Endpoint(Input::INVALID_INPUT), _readLambda(readLambda), _writeLambda(writeLambda) {
|
||||
}
|
||||
|
||||
virtual float peek() const override { return _readLambda(); }
|
||||
virtual void apply(float value, const Pointer& source) override { _writeLambda(value); }
|
||||
virtual AxisValue peek() const override { return AxisValue(_readLambda(), 0); }
|
||||
virtual void apply(AxisValue value, const Pointer& source) override { _writeLambda(value.value); }
|
||||
|
||||
private:
|
||||
const ReadLambda& _readLambda;
|
||||
|
@ -91,15 +92,15 @@ namespace controller {
|
|||
: Endpoint(id) {
|
||||
}
|
||||
|
||||
virtual float peek() const override { return _currentValue; }
|
||||
virtual void apply(float value, const Pointer& source) override { _currentValue = value; }
|
||||
virtual AxisValue peek() const override { return _currentValue; }
|
||||
virtual void apply(AxisValue value, const Pointer& source) override { _currentValue = value; }
|
||||
|
||||
virtual Pose peekPose() const override { return _currentPose; }
|
||||
virtual void apply(const Pose& value, const Pointer& source) override {
|
||||
_currentPose = value;
|
||||
}
|
||||
protected:
|
||||
float _currentValue { 0.0f };
|
||||
AxisValue _currentValue { 0.0f, 0 };
|
||||
Pose _currentPose {};
|
||||
};
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include <QtCore/QEasingCurve>
|
||||
|
||||
#include "../AxisValue.h"
|
||||
#include "../Pose.h"
|
||||
|
||||
class QJsonValue;
|
||||
|
@ -37,7 +38,7 @@ namespace controller {
|
|||
|
||||
virtual ~Filter() = default;
|
||||
|
||||
virtual float apply(float value) const = 0;
|
||||
virtual AxisValue apply(AxisValue value) const = 0;
|
||||
virtual Pose apply(Pose value) const = 0;
|
||||
|
||||
// Factory features
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace controller {
|
|||
class EndpointConditional : public Conditional {
|
||||
public:
|
||||
EndpointConditional(Endpoint::Pointer endpoint) : _endpoint(endpoint) {}
|
||||
virtual bool satisfied() override { return _endpoint && _endpoint->peek() != 0.0f; }
|
||||
virtual bool satisfied() override { return _endpoint && _endpoint->peek().value != 0.0f; }
|
||||
private:
|
||||
Endpoint::Pointer _endpoint;
|
||||
};
|
||||
|
|
|
@ -15,22 +15,19 @@
|
|||
|
||||
using namespace controller;
|
||||
|
||||
void ActionEndpoint::apply(float newValue, const Pointer& source) {
|
||||
void ActionEndpoint::apply(AxisValue newValue, const Pointer& source) {
|
||||
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
||||
InputRecorder* inputRecorder = InputRecorder::getInstance();
|
||||
QString actionName;
|
||||
if (inputRecorder->isPlayingback() || inputRecorder->isRecording()) {
|
||||
actionName = userInputMapper->getActionName(Action(_input.getChannel()));
|
||||
if (inputRecorder->isPlayingback()) {
|
||||
newValue = inputRecorder->getActionState(actionName);
|
||||
}
|
||||
QString actionName = userInputMapper->getActionName(Action(_input.getChannel()));
|
||||
inputRecorder->setActionState(actionName, newValue.value);
|
||||
}
|
||||
|
||||
_currentValue += newValue;
|
||||
_currentValue.value += newValue.value;
|
||||
|
||||
if (_input != Input::INVALID_INPUT) {
|
||||
userInputMapper->deltaActionState(Action(_input.getChannel()), newValue);
|
||||
userInputMapper->deltaActionState(Action(_input.getChannel()), newValue.value);
|
||||
}
|
||||
inputRecorder->setActionState(actionName, newValue);
|
||||
}
|
||||
|
||||
void ActionEndpoint::apply(const Pose& value, const Pointer& source) {
|
||||
|
@ -51,7 +48,7 @@ void ActionEndpoint::apply(const Pose& value, const Pointer& source) {
|
|||
}
|
||||
|
||||
void ActionEndpoint::reset() {
|
||||
_currentValue = 0.0f;
|
||||
_currentValue = AxisValue();
|
||||
_currentPose = Pose();
|
||||
}
|
||||
|
||||
|
|
|
@ -23,8 +23,8 @@ class ActionEndpoint : public Endpoint {
|
|||
public:
|
||||
ActionEndpoint(const Input& id = Input::INVALID_INPUT) : Endpoint(id) { }
|
||||
|
||||
virtual float peek() const override { return _currentValue; }
|
||||
virtual void apply(float newValue, const Pointer& source) override;
|
||||
virtual AxisValue peek() const override { return _currentValue; }
|
||||
virtual void apply(AxisValue newValue, const Pointer& source) override;
|
||||
|
||||
virtual Pose peekPose() const override { return _currentPose; }
|
||||
virtual void apply(const Pose& value, const Pointer& source) override;
|
||||
|
@ -32,7 +32,7 @@ public:
|
|||
virtual void reset() override;
|
||||
|
||||
private:
|
||||
float _currentValue{ 0.0f };
|
||||
AxisValue _currentValue { 0.0f, 0 };
|
||||
Pose _currentPose{};
|
||||
};
|
||||
|
||||
|
|
|
@ -27,13 +27,13 @@ AnyEndpoint::AnyEndpoint(Endpoint::List children) : Endpoint(Input::INVALID_INPU
|
|||
}
|
||||
}
|
||||
|
||||
// The value of an any-point is considered to be the maxiumum absolute value,
|
||||
// The value of an any-point is considered to be the maximum absolute value,
|
||||
// this handles any's of multiple axis values as well as single values as well
|
||||
float AnyEndpoint::peek() const {
|
||||
float result = 0.0f;
|
||||
AxisValue AnyEndpoint::peek() const {
|
||||
auto result = AxisValue();
|
||||
for (auto& child : _children) {
|
||||
auto childValue = child->peek();
|
||||
if (std::abs(childValue) > std::abs(result)) {
|
||||
if (std::abs(childValue.value) > std::abs(result.value)) {
|
||||
result = childValue;
|
||||
}
|
||||
}
|
||||
|
@ -41,18 +41,18 @@ float AnyEndpoint::peek() const {
|
|||
}
|
||||
|
||||
// Fetching the value must trigger any necessary side effects of value() on ALL the children.
|
||||
float AnyEndpoint::value() {
|
||||
float result = 0.0f;
|
||||
AxisValue AnyEndpoint::value() {
|
||||
auto result = AxisValue();
|
||||
for (auto& child : _children) {
|
||||
auto childValue = child->value();
|
||||
if (std::abs(childValue) > std::abs(result)) {
|
||||
if (std::abs(childValue.value) > std::abs(result.value)) {
|
||||
result = childValue;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void AnyEndpoint::apply(float newValue, const Endpoint::Pointer& source) {
|
||||
void AnyEndpoint::apply(AxisValue newValue, const Endpoint::Pointer& source) {
|
||||
qFatal("AnyEndpoint is read only");
|
||||
}
|
||||
|
||||
|
|
|
@ -19,9 +19,9 @@ class AnyEndpoint : public Endpoint {
|
|||
public:
|
||||
using Endpoint::apply;
|
||||
AnyEndpoint(Endpoint::List children);
|
||||
virtual float peek() const override;
|
||||
virtual float value() override;
|
||||
virtual void apply(float newValue, const Endpoint::Pointer& source) override;
|
||||
virtual AxisValue peek() const override;
|
||||
virtual AxisValue value() override;
|
||||
virtual void apply(AxisValue newValue, const Endpoint::Pointer& source) override;
|
||||
virtual bool writeable() const override;
|
||||
virtual bool readable() const override;
|
||||
|
||||
|
|
|
@ -21,9 +21,9 @@ public:
|
|||
using Pointer = std::shared_ptr<ArrayEndpoint>;
|
||||
ArrayEndpoint() : Endpoint(Input::INVALID_INPUT) { }
|
||||
|
||||
virtual float peek() const override { return 0.0f; }
|
||||
virtual AxisValue peek() const override { return AxisValue(); }
|
||||
|
||||
virtual void apply(float value, const Endpoint::Pointer& source) override {
|
||||
virtual void apply(AxisValue value, const Endpoint::Pointer& source) override {
|
||||
for (auto& child : _children) {
|
||||
if (child->writeable()) {
|
||||
child->apply(value, source);
|
||||
|
|
|
@ -24,18 +24,22 @@ bool CompositeEndpoint::readable() const {
|
|||
return first->readable() && second->readable();
|
||||
}
|
||||
|
||||
float CompositeEndpoint::peek() const {
|
||||
float result = first->peek() * -1.0f + second->peek();
|
||||
AxisValue CompositeEndpoint::peek() const {
|
||||
auto negative = first->peek();
|
||||
auto positive = second->peek();
|
||||
auto result = AxisValue(positive.value - negative.value, std::max(positive.timestamp, negative.timestamp));
|
||||
return result;
|
||||
}
|
||||
|
||||
// Fetching via value() must trigger any side effects of value() on the children
|
||||
float CompositeEndpoint::value() {
|
||||
float result = first->value() * -1.0f + second->value();
|
||||
AxisValue CompositeEndpoint::value() {
|
||||
auto negative = first->value();
|
||||
auto positive = second->value();
|
||||
auto result = AxisValue(positive.value - negative.value, std::max(positive.timestamp, negative.timestamp));
|
||||
return result;
|
||||
}
|
||||
|
||||
void CompositeEndpoint::apply(float newValue, const Pointer& source) {
|
||||
void CompositeEndpoint::apply(AxisValue newValue, const Pointer& source) {
|
||||
// Composites are read only
|
||||
}
|
||||
|
||||
|
|
|
@ -18,9 +18,9 @@ namespace controller {
|
|||
using Endpoint::apply;
|
||||
CompositeEndpoint(Endpoint::Pointer first, Endpoint::Pointer second);
|
||||
|
||||
virtual float peek() const override;
|
||||
virtual float value() override;
|
||||
virtual void apply(float newValue, const Pointer& source) override;
|
||||
virtual AxisValue peek() const override;
|
||||
virtual AxisValue value() override;
|
||||
virtual void apply(AxisValue newValue, const Pointer& source) override;
|
||||
virtual bool readable() const override;
|
||||
|
||||
};
|
||||
|
|
|
@ -14,19 +14,19 @@
|
|||
|
||||
using namespace controller;
|
||||
|
||||
float InputEndpoint::peek() const {
|
||||
AxisValue InputEndpoint::peek() const {
|
||||
if (isPose()) {
|
||||
return peekPose().valid ? 1.0f : 0.0f;
|
||||
return peekPose().valid ? AxisValue(1.0f, 0) : AxisValue(0.0f, 0);
|
||||
}
|
||||
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
||||
auto deviceProxy = userInputMapper->getDevice(_input);
|
||||
if (!deviceProxy) {
|
||||
return 0.0f;
|
||||
return AxisValue();
|
||||
}
|
||||
return deviceProxy->getValue(_input);
|
||||
}
|
||||
|
||||
float InputEndpoint::value(){
|
||||
AxisValue InputEndpoint::value() {
|
||||
_read = true;
|
||||
return peek();
|
||||
}
|
||||
|
|
|
@ -20,10 +20,11 @@ public:
|
|||
: Endpoint(id) {
|
||||
}
|
||||
|
||||
virtual float peek() const override;
|
||||
virtual float value() override;
|
||||
virtual AxisValue peek() const override;
|
||||
virtual AxisValue value() override;
|
||||
// FIXME need support for writing back to vibration / force feedback effects
|
||||
virtual void apply(float newValue, const Pointer& source) override {}
|
||||
virtual void apply(AxisValue newValue, const Pointer& source) override {}
|
||||
|
||||
virtual Pose peekPose() const override;
|
||||
virtual Pose pose() override;
|
||||
virtual void apply(const Pose& value, const Pointer& source) override { }
|
||||
|
|
|
@ -30,18 +30,18 @@ QString formatException(const QJSValue& exception) {
|
|||
return result;
|
||||
}
|
||||
|
||||
float JSEndpoint::peek() const {
|
||||
AxisValue JSEndpoint::peek() const {
|
||||
QJSValue result = _callable.call();
|
||||
if (result.isError()) {
|
||||
qCDebug(controllers).noquote() << formatException(result);
|
||||
return 0.0f;
|
||||
return AxisValue();
|
||||
} else {
|
||||
return (float)result.toNumber();
|
||||
return AxisValue((float)result.toNumber(), 0);
|
||||
}
|
||||
}
|
||||
|
||||
void JSEndpoint::apply(float newValue, const Pointer& source) {
|
||||
QJSValue result = _callable.call(QJSValueList({ QJSValue(newValue) }));
|
||||
void JSEndpoint::apply(AxisValue newValue, const Pointer& source) {
|
||||
QJSValue result = _callable.call(QJSValueList({ QJSValue(newValue.value) }));
|
||||
if (result.isError()) {
|
||||
qCDebug(controllers).noquote() << formatException(result);
|
||||
}
|
||||
|
|
|
@ -24,8 +24,8 @@ public:
|
|||
: Endpoint(Input::INVALID_INPUT), _callable(callable) {
|
||||
}
|
||||
|
||||
virtual float peek() const override;
|
||||
virtual void apply(float newValue, const Pointer& source) override;
|
||||
virtual AxisValue peek() const override;
|
||||
virtual void apply(AxisValue newValue, const Pointer& source) override;
|
||||
|
||||
private:
|
||||
mutable QJSValue _callable;
|
||||
|
|
|
@ -34,9 +34,9 @@ QString formatException(const QScriptValue& exception) {
|
|||
return result;
|
||||
}
|
||||
|
||||
float ScriptEndpoint::peek() const {
|
||||
AxisValue ScriptEndpoint::peek() const {
|
||||
const_cast<ScriptEndpoint*>(this)->updateValue();
|
||||
return _lastValueRead;
|
||||
return AxisValue(_lastValueRead, 0);
|
||||
}
|
||||
|
||||
void ScriptEndpoint::updateValue() {
|
||||
|
@ -58,15 +58,15 @@ void ScriptEndpoint::updateValue() {
|
|||
}
|
||||
}
|
||||
|
||||
void ScriptEndpoint::apply(float value, const Pointer& source) {
|
||||
void ScriptEndpoint::apply(AxisValue value, const Pointer& source) {
|
||||
if (value == _lastValueWritten) {
|
||||
return;
|
||||
}
|
||||
internalApply(value, source->getInput().getID());
|
||||
_lastValueWritten = value;
|
||||
internalApply(value.value, source->getInput().getID());
|
||||
}
|
||||
|
||||
void ScriptEndpoint::internalApply(float value, int sourceID) {
|
||||
_lastValueWritten = value;
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "internalApply", Qt::QueuedConnection,
|
||||
Q_ARG(float, value),
|
||||
|
|
|
@ -24,9 +24,8 @@ public:
|
|||
: Endpoint(Input::INVALID_INPUT), _callable(callable) {
|
||||
}
|
||||
|
||||
virtual float peek() const override;
|
||||
virtual void apply(float newValue, const Pointer& source) override;
|
||||
|
||||
virtual AxisValue peek() const override;
|
||||
virtual void apply(AxisValue newValue, const Pointer& source) override;
|
||||
|
||||
virtual Pose peekPose() const override;
|
||||
virtual void apply(const Pose& newValue, const Pointer& source) override;
|
||||
|
@ -42,7 +41,7 @@ protected:
|
|||
private:
|
||||
QScriptValue _callable;
|
||||
float _lastValueRead { 0.0f };
|
||||
float _lastValueWritten { 0.0f };
|
||||
AxisValue _lastValueWritten { 0.0f, 0 };
|
||||
|
||||
bool _returnPose { false };
|
||||
Pose _lastPoseRead;
|
||||
|
|
|
@ -25,19 +25,19 @@ public:
|
|||
virtual bool writeable() const override { return !_written; }
|
||||
virtual bool readable() const override { return !_read; }
|
||||
virtual void reset() override {
|
||||
apply(0.0f, Endpoint::Pointer());
|
||||
apply(AxisValue(), Endpoint::Pointer());
|
||||
apply(Pose(), Endpoint::Pointer());
|
||||
_written = _read = false;
|
||||
}
|
||||
|
||||
virtual float value() override {
|
||||
virtual AxisValue value() override {
|
||||
_read = true;
|
||||
return VirtualEndpoint::value();
|
||||
}
|
||||
|
||||
virtual void apply(float value, const Pointer& source) override {
|
||||
virtual void apply(AxisValue value, const Pointer& source) override {
|
||||
// For standard endpoints, the first NON-ZERO write counts.
|
||||
if (value != 0.0f) {
|
||||
if (value != AxisValue()) {
|
||||
_written = true;
|
||||
}
|
||||
VirtualEndpoint::apply(value, source);
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace controller {
|
|||
public:
|
||||
AccelerationLimiterFilter() {}
|
||||
|
||||
float apply(float value) const override { return value; }
|
||||
AxisValue apply(AxisValue value) const override { return value; }
|
||||
Pose apply(Pose value) const override;
|
||||
bool parseParameters(const QJsonValue& parameters) override;
|
||||
|
||||
|
|
|
@ -18,8 +18,8 @@ class ClampFilter : public Filter {
|
|||
REGISTER_FILTER_CLASS(ClampFilter);
|
||||
public:
|
||||
ClampFilter(float min = 0.0, float max = 1.0) : _min(min), _max(max) {};
|
||||
virtual float apply(float value) const override {
|
||||
return glm::clamp(value, _min, _max);
|
||||
virtual AxisValue apply(AxisValue value) const override {
|
||||
return { glm::clamp(value.value, _min, _max), value.timestamp };
|
||||
}
|
||||
|
||||
virtual Pose apply(Pose value) const override { return value; }
|
||||
|
|
|
@ -19,8 +19,8 @@ class ConstrainToIntegerFilter : public Filter {
|
|||
public:
|
||||
ConstrainToIntegerFilter() = default;
|
||||
|
||||
virtual float apply(float value) const override {
|
||||
return glm::sign(value);
|
||||
virtual AxisValue apply(AxisValue value) const override {
|
||||
return { glm::sign(value.value), value.timestamp };
|
||||
}
|
||||
|
||||
virtual Pose apply(Pose value) const override { return value; }
|
||||
|
|
|
@ -19,8 +19,8 @@ class ConstrainToPositiveIntegerFilter : public Filter {
|
|||
public:
|
||||
ConstrainToPositiveIntegerFilter() = default;
|
||||
|
||||
virtual float apply(float value) const override {
|
||||
return (value <= 0.0f) ? 0.0f : 1.0f;
|
||||
virtual AxisValue apply(AxisValue value) const override {
|
||||
return { (value.value <= 0.0f) ? 0.0f : 1.0f, value.timestamp };
|
||||
}
|
||||
|
||||
virtual Pose apply(Pose value) const override { return value; }
|
||||
|
|
|
@ -12,13 +12,13 @@
|
|||
#include <QtCore/QJsonArray>
|
||||
|
||||
using namespace controller;
|
||||
float DeadZoneFilter::apply(float value) const {
|
||||
float scale = ((value < 0.0f) ? -1.0f : 1.0f) / (1.0f - _min);
|
||||
float magnitude = std::abs(value);
|
||||
AxisValue DeadZoneFilter::apply(AxisValue value) const {
|
||||
float scale = ((value.value < 0.0f) ? -1.0f : 1.0f) / (1.0f - _min);
|
||||
float magnitude = std::abs(value.value);
|
||||
if (magnitude < _min) {
|
||||
return 0.0f;
|
||||
return { 0.0f, value.timestamp };
|
||||
}
|
||||
return (magnitude - _min) * scale;
|
||||
return { (magnitude - _min) * scale, value.timestamp };
|
||||
}
|
||||
|
||||
bool DeadZoneFilter::parseParameters(const QJsonValue& parameters) {
|
||||
|
|
|
@ -19,7 +19,7 @@ class DeadZoneFilter : public Filter {
|
|||
public:
|
||||
DeadZoneFilter(float min = 0.0) : _min(min) {};
|
||||
|
||||
virtual float apply(float value) const override;
|
||||
virtual AxisValue apply(AxisValue value) const override;
|
||||
|
||||
virtual Pose apply(Pose value) const override { return value; }
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace controller {
|
|||
ExponentialSmoothingFilter(float rotationConstant, float translationConstant) :
|
||||
_translationConstant(translationConstant), _rotationConstant(rotationConstant) {}
|
||||
|
||||
float apply(float value) const override { return value; }
|
||||
AxisValue apply(AxisValue value) const override { return value; }
|
||||
Pose apply(Pose value) const override;
|
||||
bool parseParameters(const QJsonValue& parameters) override;
|
||||
|
||||
|
|
|
@ -20,17 +20,17 @@ HysteresisFilter::HysteresisFilter(float min, float max) : _min(min), _max(max)
|
|||
};
|
||||
|
||||
|
||||
float HysteresisFilter::apply(float value) const {
|
||||
AxisValue HysteresisFilter::apply(AxisValue value) const {
|
||||
if (_signaled) {
|
||||
if (value <= _min) {
|
||||
if (value.value <= _min) {
|
||||
_signaled = false;
|
||||
}
|
||||
} else {
|
||||
if (value >= _max) {
|
||||
if (value.value >= _max) {
|
||||
_signaled = true;
|
||||
}
|
||||
}
|
||||
return _signaled ? 1.0f : 0.0f;
|
||||
return { _signaled ? 1.0f : 0.0f, value.timestamp };
|
||||
}
|
||||
|
||||
bool HysteresisFilter::parseParameters(const QJsonValue& parameters) {
|
||||
|
|
|
@ -18,7 +18,7 @@ class HysteresisFilter : public Filter {
|
|||
REGISTER_FILTER_CLASS(HysteresisFilter);
|
||||
public:
|
||||
HysteresisFilter(float min = 0.25, float max = 0.75);
|
||||
virtual float apply(float value) const override;
|
||||
virtual AxisValue apply(AxisValue value) const override;
|
||||
|
||||
virtual Pose apply(Pose value) const override { return value; }
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace controller {
|
|||
LowVelocityFilter(float rotationConstant, float translationConstant) :
|
||||
_translationConstant(translationConstant), _rotationConstant(rotationConstant) {}
|
||||
|
||||
float apply(float value) const override { return value; }
|
||||
AxisValue apply(AxisValue value) const override { return value; }
|
||||
Pose apply(Pose newPose) const override;
|
||||
bool parseParameters(const QJsonValue& parameters) override;
|
||||
|
||||
|
|
|
@ -5,6 +5,6 @@ using namespace controller;
|
|||
NotFilter::NotFilter() {
|
||||
}
|
||||
|
||||
float NotFilter::apply(float value) const {
|
||||
return (value == 0.0f) ? 1.0f : 0.0f;
|
||||
AxisValue NotFilter::apply(AxisValue value) const {
|
||||
return { (value.value == 0.0f) ? 1.0f : 0.0f, value.timestamp };
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ class NotFilter : public Filter {
|
|||
public:
|
||||
NotFilter();
|
||||
|
||||
virtual float apply(float value) const override;
|
||||
virtual AxisValue apply(AxisValue value) const override;
|
||||
virtual Pose apply(Pose value) const override { return value; }
|
||||
};
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ class PostTransformFilter : public Filter {
|
|||
public:
|
||||
PostTransformFilter() = default;
|
||||
PostTransformFilter(glm::mat4 transform) : _transform(transform) {}
|
||||
virtual float apply(float value) const override { return value; }
|
||||
virtual AxisValue apply(AxisValue value) const override { return value; }
|
||||
virtual Pose apply(Pose value) const override { return value.postTransform(_transform); }
|
||||
virtual bool parseParameters(const QJsonValue& parameters) override { return parseMat4Parameter(parameters, _transform); }
|
||||
private:
|
||||
|
|
|
@ -15,21 +15,21 @@ using namespace controller;
|
|||
|
||||
const float PulseFilter::DEFAULT_LAST_EMIT_TIME = -::std::numeric_limits<float>::max();
|
||||
|
||||
float PulseFilter::apply(float value) const {
|
||||
AxisValue PulseFilter::apply(AxisValue value) const {
|
||||
float result = 0.0f;
|
||||
|
||||
if (0.0f != value) {
|
||||
if (0.0f != value.value) {
|
||||
float now = secTimestampNow();
|
||||
float delta = now - _lastEmitTime;
|
||||
if (delta >= _interval) {
|
||||
_lastEmitTime = now;
|
||||
result = value;
|
||||
result = value.value;
|
||||
}
|
||||
} else if (_resetOnZero) {
|
||||
_lastEmitTime = DEFAULT_LAST_EMIT_TIME;
|
||||
}
|
||||
|
||||
return result;
|
||||
return { result, value.timestamp };
|
||||
}
|
||||
|
||||
bool PulseFilter::parseParameters(const QJsonValue& parameters) {
|
||||
|
|
|
@ -21,7 +21,7 @@ public:
|
|||
PulseFilter() = default;
|
||||
PulseFilter(float interval) : _interval(interval) {}
|
||||
|
||||
virtual float apply(float value) const override;
|
||||
virtual AxisValue apply(AxisValue value) const override;
|
||||
|
||||
virtual Pose apply(Pose value) const override { return value; }
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ public:
|
|||
RotateFilter() = default;
|
||||
RotateFilter(glm::quat rotation) : _rotation(rotation) {}
|
||||
|
||||
virtual float apply(float value) const override { return value; }
|
||||
virtual AxisValue apply(AxisValue value) const override { return value; }
|
||||
|
||||
virtual Pose apply(Pose value) const override {
|
||||
return value.transform(glm::mat4(glm::quat(_rotation)));
|
||||
|
|
|
@ -22,8 +22,8 @@ public:
|
|||
ScaleFilter() = default;
|
||||
ScaleFilter(float scale) : _scale(scale) {}
|
||||
|
||||
virtual float apply(float value) const override {
|
||||
return value * _scale;
|
||||
virtual AxisValue apply(AxisValue value) const override {
|
||||
return { value.value * _scale, value.timestamp };
|
||||
}
|
||||
|
||||
virtual Pose apply(Pose value) const override {
|
||||
|
|
|
@ -22,7 +22,7 @@ public:
|
|||
TransformFilter() = default;
|
||||
TransformFilter(glm::mat4 transform) : _transform(transform) {}
|
||||
|
||||
virtual float apply(float value) const override { return value; }
|
||||
virtual AxisValue apply(AxisValue value) const override { return value; }
|
||||
virtual Pose apply(Pose value) const override { return value.transform(_transform); }
|
||||
virtual bool parseParameters(const QJsonValue& parameters) override { return parseMat4Parameter(parameters, _transform); }
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ public:
|
|||
TranslateFilter() = default;
|
||||
TranslateFilter(glm::vec3 translate) : _translate(translate) {}
|
||||
|
||||
virtual float apply(float value) const override { return value; }
|
||||
virtual AxisValue apply(AxisValue value) const override { return value; }
|
||||
virtual Pose apply(Pose value) const override { return value.transform(glm::translate(_translate)); }
|
||||
virtual bool parseParameters(const QJsonValue& parameters) override { return parseVec3Parameter(parameters, _translate); }
|
||||
|
||||
|
|
|
@ -21,14 +21,27 @@
|
|||
const char* KeyboardMouseDevice::NAME = "Keyboard/Mouse";
|
||||
bool KeyboardMouseDevice::_enableTouch = true;
|
||||
|
||||
void KeyboardMouseDevice::updateDeltaAxisValue(int channel, float value) {
|
||||
// Associate timestamps with non-zero delta values so that consecutive identical values can be output.
|
||||
_inputDevice->_axisStateMap[channel] = { value, value != 0.0f ? usecTimestampNow() : 0 };
|
||||
}
|
||||
|
||||
void KeyboardMouseDevice::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) {
|
||||
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
||||
userInputMapper->withLock([&, this]() {
|
||||
_inputDevice->update(deltaTime, inputCalibrationData);
|
||||
eraseMouseClicked();
|
||||
|
||||
_inputDevice->_axisStateMap[MOUSE_AXIS_X] = _lastCursor.x();
|
||||
_inputDevice->_axisStateMap[MOUSE_AXIS_Y] = _lastCursor.y();
|
||||
_inputDevice->_axisStateMap[MOUSE_AXIS_X].value = _lastCursor.x();
|
||||
_inputDevice->_axisStateMap[MOUSE_AXIS_Y].value = _lastCursor.y();
|
||||
|
||||
QPoint currentMove = _lastCursor - _previousCursor;
|
||||
updateDeltaAxisValue(MOUSE_AXIS_X_POS, currentMove.x() > 0 ? currentMove.x() : 0.0f);
|
||||
updateDeltaAxisValue(MOUSE_AXIS_X_NEG, currentMove.x() < 0 ? -currentMove.x() : 0.0f);
|
||||
// Y mouse is inverted positive is pointing up the screen
|
||||
updateDeltaAxisValue(MOUSE_AXIS_Y_POS, currentMove.y() < 0 ? -currentMove.y() : 0.0f);
|
||||
updateDeltaAxisValue(MOUSE_AXIS_Y_NEG, currentMove.y() > 0 ? currentMove.y() : 0.0f);
|
||||
_previousCursor = _lastCursor;
|
||||
});
|
||||
|
||||
// For touch event, we need to check that the last event is not too long ago
|
||||
|
@ -73,7 +86,6 @@ void KeyboardMouseDevice::mousePressEvent(QMouseEvent* event) {
|
|||
}
|
||||
_lastCursor = event->pos();
|
||||
_mousePressTime = usecTimestampNow();
|
||||
_mouseMoved = false;
|
||||
|
||||
_mousePressPos = event->pos();
|
||||
_clickDeadspotActive = true;
|
||||
|
@ -102,21 +114,12 @@ void KeyboardMouseDevice::eraseMouseClicked() {
|
|||
|
||||
void KeyboardMouseDevice::mouseMoveEvent(QMouseEvent* event) {
|
||||
QPoint currentPos = event->pos();
|
||||
QPoint currentMove = currentPos - _lastCursor;
|
||||
|
||||
_inputDevice->_axisStateMap[MOUSE_AXIS_X_POS] = (currentMove.x() > 0 ? currentMove.x() : 0.0f);
|
||||
_inputDevice->_axisStateMap[MOUSE_AXIS_X_NEG] = (currentMove.x() < 0 ? -currentMove.x() : 0.0f);
|
||||
// Y mouse is inverted positive is pointing up the screen
|
||||
_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;
|
||||
|
||||
const int CLICK_EVENT_DEADSPOT = 6; // pixels
|
||||
if (_clickDeadspotActive && (_mousePressPos - currentPos).manhattanLength() > CLICK_EVENT_DEADSPOT) {
|
||||
_clickDeadspotActive = false;
|
||||
|
@ -125,11 +128,10 @@ void KeyboardMouseDevice::mouseMoveEvent(QMouseEvent* event) {
|
|||
|
||||
void KeyboardMouseDevice::wheelEvent(QWheelEvent* event) {
|
||||
auto currentMove = event->angleDelta() / 120.0f;
|
||||
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(MOUSE_AXIS_WHEEL_X_POS).getChannel()] = (currentMove.x() > 0 ? currentMove.x() : 0.0f);
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(MOUSE_AXIS_WHEEL_X_NEG).getChannel()] = (currentMove.x() < 0 ? -currentMove.x() : 0.0f);
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(MOUSE_AXIS_WHEEL_Y_POS).getChannel()] = (currentMove.y() > 0 ? currentMove.y() : 0.0f);
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(MOUSE_AXIS_WHEEL_Y_NEG).getChannel()] = (currentMove.y() < 0 ? -currentMove.y() : 0.0f);
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(MOUSE_AXIS_WHEEL_X_POS).getChannel()].value = currentMove.x() > 0 ? currentMove.x() : 0;
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(MOUSE_AXIS_WHEEL_X_NEG).getChannel()].value = currentMove.x() < 0 ? -currentMove.x() : 0;
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(MOUSE_AXIS_WHEEL_Y_POS).getChannel()].value = currentMove.y() > 0 ? currentMove.y() : 0;
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(MOUSE_AXIS_WHEEL_Y_NEG).getChannel()].value = currentMove.y() < 0 ? -currentMove.y() : 0;
|
||||
}
|
||||
|
||||
glm::vec2 evalAverageTouchPoints(const QList<QTouchEvent::TouchPoint>& points) {
|
||||
|
@ -168,12 +170,11 @@ void KeyboardMouseDevice::touchUpdateEvent(const QTouchEvent* event) {
|
|||
_isTouching = event->touchPointStates().testFlag(Qt::TouchPointPressed);
|
||||
} else {
|
||||
auto currentMove = currentPos - _lastTouch;
|
||||
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_X_POS).getChannel()] = (currentMove.x > 0 ? currentMove.x : 0.0f);
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_X_NEG).getChannel()] = (currentMove.x < 0 ? -currentMove.x : 0.0f);
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_X_POS).getChannel()].value = (currentMove.x > 0 ? currentMove.x : 0.0f);
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_X_NEG).getChannel()].value = (currentMove.x < 0 ? -currentMove.x : 0.0f);
|
||||
// Y mouse is inverted positive is pointing up the screen
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_Y_POS).getChannel()] = (currentMove.y < 0 ? -currentMove.y : 0.0f);
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_Y_NEG).getChannel()] = (currentMove.y > 0 ? currentMove.y : 0.0f);
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_Y_POS).getChannel()].value = (currentMove.y < 0 ? -currentMove.y : 0.0f);
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_Y_NEG).getChannel()].value = (currentMove.y > 0 ? currentMove.y : 0.0f);
|
||||
}
|
||||
|
||||
_lastTouch = currentPos;
|
||||
|
@ -247,16 +248,23 @@ controller::Input KeyboardMouseDevice::InputDevice::makeInput(KeyboardMouseDevic
|
|||
* </td></tr>
|
||||
* <tr><td><code>PgDown</code></td><td>number</td><td>number</td><td>The page down key on the keyboard or keypad is pressed.
|
||||
* </td></tr>
|
||||
* <tr><td><code>LeftMouseButton</code></td><td>number</td><td>number</td><td>The left mouse button pressed.</td></tr>
|
||||
* <tr><td><code>MiddleMouseButton</code></td><td>number</td><td>number</td><td>The middle mouse button pressed.</td></tr>
|
||||
* <tr><td><code>RightMouseButton</code></td><td>number</td><td>number</td><td>The right mouse button pressed.</td></tr>
|
||||
* <tr><td><code>LeftMouseClicked</code></td><td>number</td><td>number</td><td>The left mouse button clicked.</td></tr>
|
||||
* <tr><td><code>MiddleMouseClicked</code></td><td>number</td><td>number</td><td>The middle mouse button clicked.</td></tr>
|
||||
* <tr><td><code>RightMouseClicked</code></td><td>number</td><td>number</td><td>The right mouse button clicked.</td></tr>
|
||||
* <tr><td><code>MouseMoveRight</code></td><td>number</td><td>number</td><td>The mouse moved right.</td></tr>
|
||||
* <tr><td><code>MouseMoveLeft</code></td><td>number</td><td>number</td><td>The mouse moved left.</td></tr>
|
||||
* <tr><td><code>MouseMoveUp</code></td><td>number</td><td>number</td><td>The mouse moved up.</td></tr>
|
||||
* <tr><td><code>MouseMoveDown</code></td><td>number</td><td>number</td><td>The mouse moved down.</td></tr>
|
||||
* <tr><td><code>LeftMouseButton</code></td><td>number</td><td>number</td><td>The left mouse button is pressed.</td></tr>
|
||||
* <tr><td><code>MiddleMouseButton</code></td><td>number</td><td>number</td><td>The middle mouse button is pressed.
|
||||
* </td></tr>
|
||||
* <tr><td><code>RightMouseButton</code></td><td>number</td><td>number</td><td>The right mouse button is pressed.</td></tr>
|
||||
* <tr><td><code>LeftMouseClicked</code></td><td>number</td><td>number</td><td>The left mouse button was clicked.</td></tr>
|
||||
* <tr><td><code>MiddleMouseClicked</code></td><td>number</td><td>number</td><td>The middle mouse button was clicked.
|
||||
* </td></tr>
|
||||
* <tr><td><code>RightMouseClicked</code></td><td>number</td><td>number</td><td>The right mouse button was clicked.
|
||||
* </td></tr>
|
||||
* <tr><td><code>MouseMoveRight</code></td><td>number</td><td>number</td><td>The mouse moved right. The data value is how
|
||||
* far it moved.</td></tr>
|
||||
* <tr><td><code>MouseMoveLeft</code></td><td>number</td><td>number</td><td>The mouse moved left. The data value is how far
|
||||
* it moved.</td></tr>
|
||||
* <tr><td><code>MouseMoveUp</code></td><td>number</td><td>number</td><td>The mouse moved up. The data value is how far it
|
||||
* moved.</td></tr>
|
||||
* <tr><td><code>MouseMoveDown</code></td><td>number</td><td>number</td><td>The mouse moved down. The data value is how far
|
||||
* it moved.</td></tr>
|
||||
* <tr><td><code>MouseX</code></td><td>number</td><td>number</td><td>The mouse x-coordinate changed. The data value is its
|
||||
* new x-coordinate value.</td></tr>
|
||||
* <tr><td><code>MouseY</code></td><td>number</td><td>number</td><td>The mouse y-coordinate changed. The data value is its
|
||||
|
|
|
@ -118,9 +118,9 @@ public:
|
|||
|
||||
protected:
|
||||
QPoint _lastCursor;
|
||||
QPoint _previousCursor;
|
||||
QPoint _mousePressPos;
|
||||
quint64 _mousePressTime;
|
||||
bool _mouseMoved;
|
||||
bool _clickDeadspotActive;
|
||||
glm::vec2 _lastTouch;
|
||||
std::shared_ptr<InputDevice> _inputDevice { std::make_shared<InputDevice>() };
|
||||
|
@ -130,6 +130,9 @@ protected:
|
|||
std::chrono::high_resolution_clock::time_point _lastTouchTime;
|
||||
|
||||
static bool _enableTouch;
|
||||
|
||||
private:
|
||||
void updateDeltaAxisValue(int channel, float value);
|
||||
};
|
||||
|
||||
#endif // hifi_KeyboardMouseDevice_h
|
||||
|
|
|
@ -42,24 +42,24 @@ void TouchscreenDevice::pluginUpdate(float deltaTime, const controller::InputCal
|
|||
if (_touchPointCount == 1) {
|
||||
if (_firstTouchVec.x < _currentTouchVec.x) {
|
||||
distanceScaleX = (_currentTouchVec.x - _firstTouchVec.x) / _screenDPIScale.x;
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_X_POS).getChannel()] = distanceScaleX;
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_X_POS).getChannel()].value = distanceScaleX;
|
||||
} else if (_firstTouchVec.x > _currentTouchVec.x) {
|
||||
distanceScaleX = (_firstTouchVec.x - _currentTouchVec.x) / _screenDPIScale.x;
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_X_NEG).getChannel()] = distanceScaleX;
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_X_NEG).getChannel()].value = distanceScaleX;
|
||||
}
|
||||
// Y axis is inverted, positive is pointing up the screen
|
||||
if (_firstTouchVec.y > _currentTouchVec.y) {
|
||||
distanceScaleY = (_firstTouchVec.y - _currentTouchVec.y) / _screenDPIScale.y;
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_Y_POS).getChannel()] = distanceScaleY;
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_Y_POS).getChannel()].value = distanceScaleY;
|
||||
} else if (_firstTouchVec.y < _currentTouchVec.y) {
|
||||
distanceScaleY = (_currentTouchVec.y - _firstTouchVec.y) / _screenDPIScale.y;
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_Y_NEG).getChannel()] = distanceScaleY;
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_AXIS_Y_NEG).getChannel()].value = distanceScaleY;
|
||||
}
|
||||
} else if (_touchPointCount == 2) {
|
||||
if (_pinchScale > _lastPinchScale && _pinchScale != 0) {
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_GESTURE_PINCH_POS).getChannel()] = 1.0f;
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_GESTURE_PINCH_POS).getChannel()].value = 1.0f;
|
||||
} else if (_pinchScale != 0) {
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_GESTURE_PINCH_NEG).getChannel()] = 1.0f;
|
||||
_inputDevice->_axisStateMap[_inputDevice->makeInput(TOUCH_GESTURE_PINCH_NEG).getChannel()].value = 1.0;
|
||||
}
|
||||
_lastPinchScale = _pinchScale;
|
||||
}
|
||||
|
|
|
@ -135,8 +135,8 @@ glm::vec2 TouchscreenVirtualPadDevice::clippedPointInCircle(float radius, glm::v
|
|||
void TouchscreenVirtualPadDevice::processInputDeviceForMove(VirtualPad::Manager& virtualPadManager) {
|
||||
vec2 clippedPoint = clippedPointInCircle(_fixedRadiusForCalc, _moveRefTouchPoint, _moveCurrentTouchPoint);
|
||||
|
||||
_inputDevice->_axisStateMap[controller::LX] = (clippedPoint.x - _moveRefTouchPoint.x) / _fixedRadiusForCalc;
|
||||
_inputDevice->_axisStateMap[controller::LY] = (clippedPoint.y - _moveRefTouchPoint.y) / _fixedRadiusForCalc;
|
||||
_inputDevice->_axisStateMap[controller::LX].value = (clippedPoint.x - _moveRefTouchPoint.x) / _fixedRadiusForCalc;
|
||||
_inputDevice->_axisStateMap[controller::LY].value = (clippedPoint.y - _moveRefTouchPoint.y) / _fixedRadiusForCalc;
|
||||
|
||||
virtualPadManager.getLeftVirtualPad()->setFirstTouch(_moveRefTouchPoint);
|
||||
virtualPadManager.getLeftVirtualPad()->setCurrentTouch(clippedPoint);
|
||||
|
@ -148,8 +148,10 @@ void TouchscreenVirtualPadDevice::processInputDeviceForView() {
|
|||
// We use average across how many times we've got touchUpdate events.
|
||||
// Using the average instead of the full deltaX and deltaY, makes deltaTime in MyAvatar dont't accelerate rotation when there is a low touchUpdate rate (heavier domains).
|
||||
// (Because it multiplies this input value by deltaTime (with a coefficient)).
|
||||
_inputDevice->_axisStateMap[controller::RX] = _viewTouchUpdateCount == 0 ? 0 : (_viewCurrentTouchPoint.x - _viewRefTouchPoint.x) / _viewTouchUpdateCount;
|
||||
_inputDevice->_axisStateMap[controller::RY] = _viewTouchUpdateCount == 0 ? 0 : (_viewCurrentTouchPoint.y - _viewRefTouchPoint.y) / _viewTouchUpdateCount;
|
||||
_inputDevice->_axisStateMap[controller::RX].value =
|
||||
_viewTouchUpdateCount == 0 ? 0 : (_viewCurrentTouchPoint.x - _viewRefTouchPoint.x) / _viewTouchUpdateCount;
|
||||
_inputDevice->_axisStateMap[controller::RY].value =
|
||||
_viewTouchUpdateCount == 0 ? 0 : (_viewCurrentTouchPoint.y - _viewRefTouchPoint.y) / _viewTouchUpdateCount;
|
||||
|
||||
// after use, save last touch point as ref
|
||||
_viewRefTouchPoint = _viewCurrentTouchPoint;
|
||||
|
@ -442,8 +444,8 @@ void TouchscreenVirtualPadDevice::moveTouchUpdate(glm::vec2 touchPoint) {
|
|||
void TouchscreenVirtualPadDevice::moveTouchEnd() {
|
||||
if (_moveHasValidTouch) { // do stuff once
|
||||
_moveHasValidTouch = false;
|
||||
_inputDevice->_axisStateMap[controller::LX] = 0;
|
||||
_inputDevice->_axisStateMap[controller::LY] = 0;
|
||||
_inputDevice->_axisStateMap[controller::LX].value = 0;
|
||||
_inputDevice->_axisStateMap[controller::LY].value = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -465,8 +467,8 @@ void TouchscreenVirtualPadDevice::viewTouchUpdate(glm::vec2 touchPoint) {
|
|||
void TouchscreenVirtualPadDevice::viewTouchEnd() {
|
||||
if (_viewHasValidTouch) { // do stuff once
|
||||
_viewHasValidTouch = false;
|
||||
_inputDevice->_axisStateMap[controller::RX] = 0;
|
||||
_inputDevice->_axisStateMap[controller::RY] = 0;
|
||||
_inputDevice->_axisStateMap[controller::RX].value = 0;
|
||||
_inputDevice->_axisStateMap[controller::RY].value = 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -46,8 +46,8 @@ void Joystick::closeJoystick() {
|
|||
|
||||
void Joystick::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) {
|
||||
for (auto axisState : _axisStateMap) {
|
||||
if (fabsf(axisState.second) < CONTROLLER_THRESHOLD) {
|
||||
_axisStateMap[axisState.first] = 0.0f;
|
||||
if (fabsf(axisState.second.value) < CONTROLLER_THRESHOLD) {
|
||||
_axisStateMap[axisState.first].value = 0.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -59,7 +59,7 @@ void Joystick::focusOutEvent() {
|
|||
|
||||
void Joystick::handleAxisEvent(const SDL_ControllerAxisEvent& event) {
|
||||
SDL_GameControllerAxis axis = (SDL_GameControllerAxis) event.axis;
|
||||
_axisStateMap[makeInput((controller::StandardAxisChannel)axis).getChannel()] = (float)event.value / MAX_AXIS;
|
||||
_axisStateMap[makeInput((controller::StandardAxisChannel)axis).getChannel()].value = (float)event.value / MAX_AXIS;
|
||||
}
|
||||
|
||||
void Joystick::handleButtonEvent(const SDL_ControllerButtonEvent& event) {
|
||||
|
|
|
@ -258,15 +258,15 @@ void OculusControllerManager::TouchDevice::update(float deltaTime,
|
|||
using namespace controller;
|
||||
// Axes
|
||||
const auto& inputState = _parent._touchInputState;
|
||||
_axisStateMap[LX] = inputState.Thumbstick[ovrHand_Left].x;
|
||||
_axisStateMap[LY] = inputState.Thumbstick[ovrHand_Left].y;
|
||||
_axisStateMap[LT] = inputState.IndexTrigger[ovrHand_Left];
|
||||
_axisStateMap[LEFT_GRIP] = inputState.HandTrigger[ovrHand_Left];
|
||||
_axisStateMap[LX].value = inputState.Thumbstick[ovrHand_Left].x;
|
||||
_axisStateMap[LY].value = inputState.Thumbstick[ovrHand_Left].y;
|
||||
_axisStateMap[LT].value = inputState.IndexTrigger[ovrHand_Left];
|
||||
_axisStateMap[LEFT_GRIP].value = inputState.HandTrigger[ovrHand_Left];
|
||||
|
||||
_axisStateMap[RX] = inputState.Thumbstick[ovrHand_Right].x;
|
||||
_axisStateMap[RY] = inputState.Thumbstick[ovrHand_Right].y;
|
||||
_axisStateMap[RT] = inputState.IndexTrigger[ovrHand_Right];
|
||||
_axisStateMap[RIGHT_GRIP] = inputState.HandTrigger[ovrHand_Right];
|
||||
_axisStateMap[RX].value = inputState.Thumbstick[ovrHand_Right].x;
|
||||
_axisStateMap[RY].value = inputState.Thumbstick[ovrHand_Right].y;
|
||||
_axisStateMap[RT].value = inputState.IndexTrigger[ovrHand_Right];
|
||||
_axisStateMap[RIGHT_GRIP].value = inputState.HandTrigger[ovrHand_Right];
|
||||
|
||||
// Buttons
|
||||
for (const auto& pair : BUTTON_MAP) {
|
||||
|
|
|
@ -928,8 +928,8 @@ void ViveControllerManager::InputDevice::partitionTouchpad(int sButton, int xAxi
|
|||
const float CENTER_DEADBAND = 0.6f;
|
||||
const float DIAGONAL_DIVIDE_IN_RADIANS = PI / 4.0f;
|
||||
if (_buttonPressedMap.find(sButton) != _buttonPressedMap.end()) {
|
||||
float absX = abs(_axisStateMap[xAxis]);
|
||||
float absY = abs(_axisStateMap[yAxis]);
|
||||
float absX = abs(_axisStateMap[xAxis].value);
|
||||
float absY = abs(_axisStateMap[yAxis].value);
|
||||
glm::vec2 cartesianQuadrantI(absX, absY);
|
||||
float angle = glm::atan(cartesianQuadrantI.y / cartesianQuadrantI.x);
|
||||
float radius = glm::length(cartesianQuadrantI);
|
||||
|
@ -956,10 +956,10 @@ void ViveControllerManager::InputDevice::handleAxisEvent(float deltaTime, uint32
|
|||
} else {
|
||||
stick = _filteredRightStick.process(deltaTime, stick);
|
||||
}
|
||||
_axisStateMap[isLeftHand ? LX : RX] = stick.x;
|
||||
_axisStateMap[isLeftHand ? LY : RY] = stick.y;
|
||||
_axisStateMap[isLeftHand ? LX : RX].value = stick.x;
|
||||
_axisStateMap[isLeftHand ? LY : RY].value = stick.y;
|
||||
} else if (axis == vr::k_EButton_SteamVR_Trigger) {
|
||||
_axisStateMap[isLeftHand ? LT : RT] = x;
|
||||
_axisStateMap[isLeftHand ? LT : RT].value = x;
|
||||
// The click feeling on the Vive controller trigger represents a value of *precisely* 1.0,
|
||||
// so we can expose that as an additional button
|
||||
if (x >= 1.0f) {
|
||||
|
@ -1000,7 +1000,7 @@ void ViveControllerManager::InputDevice::handleButtonEvent(float deltaTime, uint
|
|||
if (button == vr::k_EButton_ApplicationMenu) {
|
||||
_buttonPressedMap.insert(isLeftHand ? LEFT_APP_MENU : RIGHT_APP_MENU);
|
||||
} else if (button == vr::k_EButton_Grip) {
|
||||
_axisStateMap[isLeftHand ? LEFT_GRIP : RIGHT_GRIP] = 1.0f;
|
||||
_axisStateMap[isLeftHand ? LEFT_GRIP : RIGHT_GRIP].value = 1.0f;
|
||||
} else if (button == vr::k_EButton_SteamVR_Trigger) {
|
||||
_buttonPressedMap.insert(isLeftHand ? LT : RT);
|
||||
} else if (button == vr::k_EButton_SteamVR_Touchpad) {
|
||||
|
@ -1008,7 +1008,7 @@ void ViveControllerManager::InputDevice::handleButtonEvent(float deltaTime, uint
|
|||
}
|
||||
} else {
|
||||
if (button == vr::k_EButton_Grip) {
|
||||
_axisStateMap[isLeftHand ? LEFT_GRIP : RIGHT_GRIP] = 0.0f;
|
||||
_axisStateMap[isLeftHand ? LEFT_GRIP : RIGHT_GRIP].value = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue