diff --git a/interface/src/raypick/PathPointer.cpp b/interface/src/raypick/PathPointer.cpp index 00ab32bde4..8a6995936f 100644 --- a/interface/src/raypick/PathPointer.cpp +++ b/interface/src/raypick/PathPointer.cpp @@ -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()) { diff --git a/libraries/controllers/src/controllers/AxisValue.cpp b/libraries/controllers/src/controllers/AxisValue.cpp index 49201dbf7a..4b7913754c 100644 --- a/libraries/controllers/src/controllers/AxisValue.cpp +++ b/libraries/controllers/src/controllers/AxisValue.cpp @@ -15,4 +15,7 @@ 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; + } } diff --git a/libraries/controllers/src/controllers/AxisValue.h b/libraries/controllers/src/controllers/AxisValue.h index 67fd5736b8..e4bc20f7d2 100644 --- a/libraries/controllers/src/controllers/AxisValue.h +++ b/libraries/controllers/src/controllers/AxisValue.h @@ -24,6 +24,9 @@ namespace controller { AxisValue() {} AxisValue(const float value, const quint64 timestamp); + + bool operator ==(const AxisValue& right) const; + bool operator !=(const AxisValue& right) const { return !(*this == right); } }; } diff --git a/libraries/controllers/src/controllers/InputDevice.cpp b/libraries/controllers/src/controllers/InputDevice.cpp index e46bb3c8b5..dd430263fa 100644 --- a/libraries/controllers/src/controllers/InputDevice.cpp +++ b/libraries/controllers/src/controllers/InputDevice.cpp @@ -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).value; + 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); } diff --git a/libraries/controllers/src/controllers/InputDevice.h b/libraries/controllers/src/controllers/InputDevice.h index 1d4ab1c5d8..7c3c31cb38 100644 --- a/libraries/controllers/src/controllers/InputDevice.h +++ b/libraries/controllers/src/controllers/InputDevice.h @@ -112,8 +112,8 @@ public: 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; } diff --git a/libraries/controllers/src/controllers/ScriptingInterface.cpp b/libraries/controllers/src/controllers/ScriptingInterface.cpp index ce730bffa8..07c59e1aaa 100644 --- a/libraries/controllers/src/controllers/ScriptingInterface.cpp +++ b/libraries/controllers/src/controllers/ScriptingInterface.cpp @@ -89,17 +89,17 @@ namespace controller { float ScriptingInterface::getValue(const int& source) const { auto userInputMapper = DependencyManager::get(); - 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(); - 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(); - return userInputMapper->getPose(Input((uint32_t)source)); + return userInputMapper->getPose(Input((uint32_t)source)); } QVector ScriptingInterface::getAllActions() { diff --git a/libraries/controllers/src/controllers/UserInputMapper.cpp b/libraries/controllers/src/controllers/UserInputMapper.cpp index 307064c073..e8503d8d1e 100755 --- a/libraries/controllers/src/controllers/UserInputMapper.cpp +++ b/libraries/controllers/src/controllers/UserInputMapper.cpp @@ -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(); @@ -604,10 +604,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 +615,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 +741,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(); } diff --git a/libraries/controllers/src/controllers/UserInputMapper.h b/libraries/controllers/src/controllers/UserInputMapper.h index 5fd21e6299..2b3c947491 100644 --- a/libraries/controllers/src/controllers/UserInputMapper.h +++ b/libraries/controllers/src/controllers/UserInputMapper.h @@ -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 _actionScales = std::vector(toInt(Action::NUM_ACTIONS), 1.0f); std::vector _lastActionStates = std::vector(toInt(Action::NUM_ACTIONS), 0.0f); std::vector _poseStates = std::vector(toInt(Action::NUM_ACTIONS)); - std::vector _lastStandardStates = std::vector(); + std::vector _lastStandardStates = std::vector(); - 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; diff --git a/libraries/controllers/src/controllers/impl/Endpoint.h b/libraries/controllers/src/controllers/impl/Endpoint.h index a938dd30b6..29ba7c97f0 100644 --- a/libraries/controllers/src/controllers/impl/Endpoint.h +++ b/libraries/controllers/src/controllers/impl/Endpoint.h @@ -16,6 +16,7 @@ #include +#include "../AxisValue.h" #include "../Input.h" #include "../Pose.h" @@ -36,12 +37,13 @@ namespace controller { using WriteLambda = std::function; 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) {} + virtual bool isAxis() const { return _input.isAxis(); } virtual bool isPose() const { return _input.isPose(); } virtual bool writeable() const { return true; } virtual bool readable() const { return true; } @@ -59,8 +61,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 +78,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 +93,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 {}; }; diff --git a/libraries/controllers/src/controllers/impl/Filter.h b/libraries/controllers/src/controllers/impl/Filter.h index 7afabb4bcb..5c88a5be58 100644 --- a/libraries/controllers/src/controllers/impl/Filter.h +++ b/libraries/controllers/src/controllers/impl/Filter.h @@ -21,6 +21,7 @@ #include +#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 diff --git a/libraries/controllers/src/controllers/impl/conditionals/EndpointConditional.h b/libraries/controllers/src/controllers/impl/conditionals/EndpointConditional.h index 0ba1347087..50a33471e7 100644 --- a/libraries/controllers/src/controllers/impl/conditionals/EndpointConditional.h +++ b/libraries/controllers/src/controllers/impl/conditionals/EndpointConditional.h @@ -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; }; diff --git a/libraries/controllers/src/controllers/impl/endpoints/ActionEndpoint.cpp b/libraries/controllers/src/controllers/impl/endpoints/ActionEndpoint.cpp index f73268b41f..122af5a30c 100644 --- a/libraries/controllers/src/controllers/impl/endpoints/ActionEndpoint.cpp +++ b/libraries/controllers/src/controllers/impl/endpoints/ActionEndpoint.cpp @@ -15,22 +15,22 @@ using namespace controller; -void ActionEndpoint::apply(float newValue, const Pointer& source) { +void ActionEndpoint::apply(AxisValue newValue, const Pointer& source) { auto userInputMapper = DependencyManager::get(); InputRecorder* inputRecorder = InputRecorder::getInstance(); QString actionName; if (inputRecorder->isPlayingback() || inputRecorder->isRecording()) { actionName = userInputMapper->getActionName(Action(_input.getChannel())); if (inputRecorder->isPlayingback()) { - newValue = inputRecorder->getActionState(actionName); + newValue = AxisValue(inputRecorder->getActionState(actionName), 0); } } - _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); + inputRecorder->setActionState(actionName, newValue.value); } void ActionEndpoint::apply(const Pose& value, const Pointer& source) { @@ -51,7 +51,7 @@ void ActionEndpoint::apply(const Pose& value, const Pointer& source) { } void ActionEndpoint::reset() { - _currentValue = 0.0f; + _currentValue = AxisValue(); _currentPose = Pose(); } diff --git a/libraries/controllers/src/controllers/impl/endpoints/ActionEndpoint.h b/libraries/controllers/src/controllers/impl/endpoints/ActionEndpoint.h index 1073dc6593..94da4663aa 100644 --- a/libraries/controllers/src/controllers/impl/endpoints/ActionEndpoint.h +++ b/libraries/controllers/src/controllers/impl/endpoints/ActionEndpoint.h @@ -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{}; }; diff --git a/libraries/controllers/src/controllers/impl/endpoints/AnyEndpoint.cpp b/libraries/controllers/src/controllers/impl/endpoints/AnyEndpoint.cpp index 598dfb6ee8..75acdd9d13 100644 --- a/libraries/controllers/src/controllers/impl/endpoints/AnyEndpoint.cpp +++ b/libraries/controllers/src/controllers/impl/endpoints/AnyEndpoint.cpp @@ -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)) { - result = childValue; + if (std::abs(childValue.value) > std::abs(result.value)) { + result.value = childValue.value; } } 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"); } diff --git a/libraries/controllers/src/controllers/impl/endpoints/AnyEndpoint.h b/libraries/controllers/src/controllers/impl/endpoints/AnyEndpoint.h index 8947eb675f..a9634f10d8 100644 --- a/libraries/controllers/src/controllers/impl/endpoints/AnyEndpoint.h +++ b/libraries/controllers/src/controllers/impl/endpoints/AnyEndpoint.h @@ -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; diff --git a/libraries/controllers/src/controllers/impl/endpoints/ArrayEndpoint.h b/libraries/controllers/src/controllers/impl/endpoints/ArrayEndpoint.h index 34d30a2e97..f928a4f568 100644 --- a/libraries/controllers/src/controllers/impl/endpoints/ArrayEndpoint.h +++ b/libraries/controllers/src/controllers/impl/endpoints/ArrayEndpoint.h @@ -21,9 +21,9 @@ public: using Pointer = std::shared_ptr; 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); diff --git a/libraries/controllers/src/controllers/impl/endpoints/CompositeEndpoint.cpp b/libraries/controllers/src/controllers/impl/endpoints/CompositeEndpoint.cpp index 1bd27489f8..bd75c97dd7 100644 --- a/libraries/controllers/src/controllers/impl/endpoints/CompositeEndpoint.cpp +++ b/libraries/controllers/src/controllers/impl/endpoints/CompositeEndpoint.cpp @@ -24,18 +24,18 @@ 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 result = AxisValue(first->peek().value * -1.0f + second->peek().value, 0); 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 result = AxisValue(first->value().value * -1.0f + second->value().value, 0); return result; } -void CompositeEndpoint::apply(float newValue, const Pointer& source) { +void CompositeEndpoint::apply(AxisValue newValue, const Pointer& source) { // Composites are read only } diff --git a/libraries/controllers/src/controllers/impl/endpoints/CompositeEndpoint.h b/libraries/controllers/src/controllers/impl/endpoints/CompositeEndpoint.h index 3249aa1d37..004df36273 100644 --- a/libraries/controllers/src/controllers/impl/endpoints/CompositeEndpoint.h +++ b/libraries/controllers/src/controllers/impl/endpoints/CompositeEndpoint.h @@ -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; }; diff --git a/libraries/controllers/src/controllers/impl/endpoints/InputEndpoint.cpp b/libraries/controllers/src/controllers/impl/endpoints/InputEndpoint.cpp index ce58c948d1..3755d860b6 100644 --- a/libraries/controllers/src/controllers/impl/endpoints/InputEndpoint.cpp +++ b/libraries/controllers/src/controllers/impl/endpoints/InputEndpoint.cpp @@ -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(); 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(); } diff --git a/libraries/controllers/src/controllers/impl/endpoints/InputEndpoint.h b/libraries/controllers/src/controllers/impl/endpoints/InputEndpoint.h index 7e4560dcf9..9581228cef 100644 --- a/libraries/controllers/src/controllers/impl/endpoints/InputEndpoint.h +++ b/libraries/controllers/src/controllers/impl/endpoints/InputEndpoint.h @@ -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 { } diff --git a/libraries/controllers/src/controllers/impl/endpoints/JSEndpoint.cpp b/libraries/controllers/src/controllers/impl/endpoints/JSEndpoint.cpp index 2f20cd82c6..c01b67f1bc 100644 --- a/libraries/controllers/src/controllers/impl/endpoints/JSEndpoint.cpp +++ b/libraries/controllers/src/controllers/impl/endpoints/JSEndpoint.cpp @@ -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); } diff --git a/libraries/controllers/src/controllers/impl/endpoints/JSEndpoint.h b/libraries/controllers/src/controllers/impl/endpoints/JSEndpoint.h index 4d179da8e6..6c953399dd 100644 --- a/libraries/controllers/src/controllers/impl/endpoints/JSEndpoint.h +++ b/libraries/controllers/src/controllers/impl/endpoints/JSEndpoint.h @@ -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; diff --git a/libraries/controllers/src/controllers/impl/endpoints/ScriptEndpoint.cpp b/libraries/controllers/src/controllers/impl/endpoints/ScriptEndpoint.cpp index e2c48d776f..9f971d2f04 100644 --- a/libraries/controllers/src/controllers/impl/endpoints/ScriptEndpoint.cpp +++ b/libraries/controllers/src/controllers/impl/endpoints/ScriptEndpoint.cpp @@ -34,9 +34,9 @@ QString formatException(const QScriptValue& exception) { return result; } -float ScriptEndpoint::peek() const { +AxisValue ScriptEndpoint::peek() const { const_cast(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), diff --git a/libraries/controllers/src/controllers/impl/endpoints/ScriptEndpoint.h b/libraries/controllers/src/controllers/impl/endpoints/ScriptEndpoint.h index 00439f5560..e739ab0b01 100644 --- a/libraries/controllers/src/controllers/impl/endpoints/ScriptEndpoint.h +++ b/libraries/controllers/src/controllers/impl/endpoints/ScriptEndpoint.h @@ -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; diff --git a/libraries/controllers/src/controllers/impl/endpoints/StandardEndpoint.h b/libraries/controllers/src/controllers/impl/endpoints/StandardEndpoint.h index 2006809fed..26a8063cdc 100644 --- a/libraries/controllers/src/controllers/impl/endpoints/StandardEndpoint.h +++ b/libraries/controllers/src/controllers/impl/endpoints/StandardEndpoint.h @@ -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); diff --git a/libraries/controllers/src/controllers/impl/filters/AccelerationLimiterFilter.h b/libraries/controllers/src/controllers/impl/filters/AccelerationLimiterFilter.h index 269fd54102..15653a7df6 100644 --- a/libraries/controllers/src/controllers/impl/filters/AccelerationLimiterFilter.h +++ b/libraries/controllers/src/controllers/impl/filters/AccelerationLimiterFilter.h @@ -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; diff --git a/libraries/controllers/src/controllers/impl/filters/ClampFilter.h b/libraries/controllers/src/controllers/impl/filters/ClampFilter.h index b06a43515f..04684655c9 100644 --- a/libraries/controllers/src/controllers/impl/filters/ClampFilter.h +++ b/libraries/controllers/src/controllers/impl/filters/ClampFilter.h @@ -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; } diff --git a/libraries/controllers/src/controllers/impl/filters/ConstrainToIntegerFilter.h b/libraries/controllers/src/controllers/impl/filters/ConstrainToIntegerFilter.h index 129e08741d..2cce5f828d 100644 --- a/libraries/controllers/src/controllers/impl/filters/ConstrainToIntegerFilter.h +++ b/libraries/controllers/src/controllers/impl/filters/ConstrainToIntegerFilter.h @@ -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; } diff --git a/libraries/controllers/src/controllers/impl/filters/ConstrainToPositiveIntegerFilter.h b/libraries/controllers/src/controllers/impl/filters/ConstrainToPositiveIntegerFilter.h index 8f2140721a..07dd6654f1 100644 --- a/libraries/controllers/src/controllers/impl/filters/ConstrainToPositiveIntegerFilter.h +++ b/libraries/controllers/src/controllers/impl/filters/ConstrainToPositiveIntegerFilter.h @@ -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; } diff --git a/libraries/controllers/src/controllers/impl/filters/DeadZoneFilter.cpp b/libraries/controllers/src/controllers/impl/filters/DeadZoneFilter.cpp index f07ef25976..84d3b9de60 100644 --- a/libraries/controllers/src/controllers/impl/filters/DeadZoneFilter.cpp +++ b/libraries/controllers/src/controllers/impl/filters/DeadZoneFilter.cpp @@ -12,13 +12,13 @@ #include 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) { diff --git a/libraries/controllers/src/controllers/impl/filters/DeadZoneFilter.h b/libraries/controllers/src/controllers/impl/filters/DeadZoneFilter.h index d898647126..7ac1e8a51d 100644 --- a/libraries/controllers/src/controllers/impl/filters/DeadZoneFilter.h +++ b/libraries/controllers/src/controllers/impl/filters/DeadZoneFilter.h @@ -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; } diff --git a/libraries/controllers/src/controllers/impl/filters/ExponentialSmoothingFilter.h b/libraries/controllers/src/controllers/impl/filters/ExponentialSmoothingFilter.h index 134f57243e..e0135a8f68 100644 --- a/libraries/controllers/src/controllers/impl/filters/ExponentialSmoothingFilter.h +++ b/libraries/controllers/src/controllers/impl/filters/ExponentialSmoothingFilter.h @@ -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; diff --git a/libraries/controllers/src/controllers/impl/filters/HysteresisFilter.cpp b/libraries/controllers/src/controllers/impl/filters/HysteresisFilter.cpp index a7f22e1de4..91e59a39b9 100644 --- a/libraries/controllers/src/controllers/impl/filters/HysteresisFilter.cpp +++ b/libraries/controllers/src/controllers/impl/filters/HysteresisFilter.cpp @@ -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) { diff --git a/libraries/controllers/src/controllers/impl/filters/HysteresisFilter.h b/libraries/controllers/src/controllers/impl/filters/HysteresisFilter.h index 4eb563754f..c7c817ecfa 100644 --- a/libraries/controllers/src/controllers/impl/filters/HysteresisFilter.h +++ b/libraries/controllers/src/controllers/impl/filters/HysteresisFilter.h @@ -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; } diff --git a/libraries/controllers/src/controllers/impl/filters/LowVelocityFilter.h b/libraries/controllers/src/controllers/impl/filters/LowVelocityFilter.h index ac5299dc6f..eb4f53797f 100644 --- a/libraries/controllers/src/controllers/impl/filters/LowVelocityFilter.h +++ b/libraries/controllers/src/controllers/impl/filters/LowVelocityFilter.h @@ -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; diff --git a/libraries/controllers/src/controllers/impl/filters/NotFilter.cpp b/libraries/controllers/src/controllers/impl/filters/NotFilter.cpp index 73460aed91..c0396857e5 100644 --- a/libraries/controllers/src/controllers/impl/filters/NotFilter.cpp +++ b/libraries/controllers/src/controllers/impl/filters/NotFilter.cpp @@ -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 }; } diff --git a/libraries/controllers/src/controllers/impl/filters/NotFilter.h b/libraries/controllers/src/controllers/impl/filters/NotFilter.h index ceb7d29de3..d68a9feff7 100644 --- a/libraries/controllers/src/controllers/impl/filters/NotFilter.h +++ b/libraries/controllers/src/controllers/impl/filters/NotFilter.h @@ -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; } }; diff --git a/libraries/controllers/src/controllers/impl/filters/PostTransformFilter.h b/libraries/controllers/src/controllers/impl/filters/PostTransformFilter.h index 3c1cb4f80c..aeb24cc3f8 100644 --- a/libraries/controllers/src/controllers/impl/filters/PostTransformFilter.h +++ b/libraries/controllers/src/controllers/impl/filters/PostTransformFilter.h @@ -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: diff --git a/libraries/controllers/src/controllers/impl/filters/PulseFilter.cpp b/libraries/controllers/src/controllers/impl/filters/PulseFilter.cpp index 6ef9d40802..d37eb99ca9 100644 --- a/libraries/controllers/src/controllers/impl/filters/PulseFilter.cpp +++ b/libraries/controllers/src/controllers/impl/filters/PulseFilter.cpp @@ -15,21 +15,21 @@ using namespace controller; const float PulseFilter::DEFAULT_LAST_EMIT_TIME = -::std::numeric_limits::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) { diff --git a/libraries/controllers/src/controllers/impl/filters/PulseFilter.h b/libraries/controllers/src/controllers/impl/filters/PulseFilter.h index 2e0da0efa9..dc56b3c6c9 100644 --- a/libraries/controllers/src/controllers/impl/filters/PulseFilter.h +++ b/libraries/controllers/src/controllers/impl/filters/PulseFilter.h @@ -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; } diff --git a/libraries/controllers/src/controllers/impl/filters/RotateFilter.h b/libraries/controllers/src/controllers/impl/filters/RotateFilter.h index c6735f6aa9..d1f1f2d269 100644 --- a/libraries/controllers/src/controllers/impl/filters/RotateFilter.h +++ b/libraries/controllers/src/controllers/impl/filters/RotateFilter.h @@ -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))); diff --git a/libraries/controllers/src/controllers/impl/filters/ScaleFilter.h b/libraries/controllers/src/controllers/impl/filters/ScaleFilter.h index 936498a7a1..3eb58e7f47 100644 --- a/libraries/controllers/src/controllers/impl/filters/ScaleFilter.h +++ b/libraries/controllers/src/controllers/impl/filters/ScaleFilter.h @@ -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 { diff --git a/libraries/controllers/src/controllers/impl/filters/TransformFilter.h b/libraries/controllers/src/controllers/impl/filters/TransformFilter.h index a34edaa337..c81af2ef17 100644 --- a/libraries/controllers/src/controllers/impl/filters/TransformFilter.h +++ b/libraries/controllers/src/controllers/impl/filters/TransformFilter.h @@ -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); } diff --git a/libraries/controllers/src/controllers/impl/filters/TranslateFilter.h b/libraries/controllers/src/controllers/impl/filters/TranslateFilter.h index ced9cbc689..476481807d 100644 --- a/libraries/controllers/src/controllers/impl/filters/TranslateFilter.h +++ b/libraries/controllers/src/controllers/impl/filters/TranslateFilter.h @@ -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); } diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp index ebc5a5cd3e..df58ea81c2 100755 --- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp +++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp @@ -21,6 +21,13 @@ const char* KeyboardMouseDevice::NAME = "Keyboard/Mouse"; bool KeyboardMouseDevice::_enableTouch = true; +void KeyboardMouseDevice::updateDeltaAxisValue(int channel, float value) { + // Use timestamps for delta values so that consecutive identical values can be output. + if (value != 0.0f || _inputDevice->_axisStateMap[channel].value != 0) { + _inputDevice->_axisStateMap[channel] = { value, usecTimestampNow() }; + } +} + void KeyboardMouseDevice::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) { auto userInputMapper = DependencyManager::get(); userInputMapper->withLock([&, this]() { @@ -31,11 +38,11 @@ void KeyboardMouseDevice::pluginUpdate(float deltaTime, const controller::InputC _inputDevice->_axisStateMap[MOUSE_AXIS_Y].value = _lastCursor.y(); QPoint currentMove = _lastCursor - _previousCursor; - _inputDevice->_axisStateMap[MOUSE_AXIS_X_POS].value = (currentMove.x() > 0 ? currentMove.x() : 0.0f); - _inputDevice->_axisStateMap[MOUSE_AXIS_X_NEG].value = (currentMove.x() < 0 ? -currentMove.x() : 0.0f); + 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 - _inputDevice->_axisStateMap[MOUSE_AXIS_Y_POS].value = (currentMove.y() < 0 ? -currentMove.y() : 0.0f); - _inputDevice->_axisStateMap[MOUSE_AXIS_Y_NEG].value = (currentMove.y() > 0 ? currentMove.y() : 0.0f); + 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; }); diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h index 45ca496c11..f6921c8e23 100644 --- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h +++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h @@ -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