mirror of
https://github.com/AleziaKurdis/overte.git
synced 2025-04-08 04:52:12 +02:00
Merge pull request #6250 from jherico/peek
Adding peek support for endpoints
This commit is contained in:
commit
286905c20c
19 changed files with 74 additions and 42 deletions
|
@ -910,8 +910,8 @@ var leftController = new MyController(LEFT_HAND);
|
|||
var MAPPING_NAME = "com.highfidelity.handControllerGrab";
|
||||
|
||||
var mapping = Controller.newMapping(MAPPING_NAME);
|
||||
mapping.from([Controller.Standard.RB, Controller.Standard.RT]).to(rightController.eitherTrigger);
|
||||
mapping.from([Controller.Standard.LB, Controller.Standard.LT]).to(leftController.eitherTrigger);
|
||||
mapping.from([Controller.Standard.RB, Controller.Standard.RT]).peek().to(rightController.eitherTrigger);
|
||||
mapping.from([Controller.Standard.LB, Controller.Standard.LT]).peek().to(leftController.eitherTrigger);
|
||||
Controller.enableMapping(MAPPING_NAME);
|
||||
|
||||
|
||||
|
|
|
@ -513,7 +513,7 @@ bool UserInputMapper::applyRoute(const Route::Pointer& route, bool force) {
|
|||
// and someone else wires it to CONTEXT_MENU, I don't want both to occur when
|
||||
// I press the button. The exception is if I'm wiring a control back to itself
|
||||
// in order to adjust my interface, like inverting the Y axis on an analog stick
|
||||
if (!source->readable()) {
|
||||
if (!route->peek && !source->readable()) {
|
||||
if (debugRoutes && route->debug) {
|
||||
qCDebug(controllers) << "Source unreadable";
|
||||
}
|
||||
|
@ -539,7 +539,7 @@ bool UserInputMapper::applyRoute(const Route::Pointer& route, bool force) {
|
|||
|
||||
// Fetch the value, may have been overriden by previous loopback routes
|
||||
if (source->isPose()) {
|
||||
Pose value = getPose(source);
|
||||
Pose value = getPose(source, route->peek);
|
||||
static const Pose IDENTITY_POSE { vec3(), quat() };
|
||||
if (debugRoutes && route->debug) {
|
||||
if (!value.valid) {
|
||||
|
@ -554,7 +554,7 @@ 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);
|
||||
float value = getValue(source, route->peek);
|
||||
|
||||
if (debugRoutes && route->debug) {
|
||||
qCDebug(controllers) << "Value was " << value;
|
||||
|
@ -691,8 +691,8 @@ void UserInputMapper::enableMapping(const QString& mappingName, bool enable) {
|
|||
}
|
||||
}
|
||||
|
||||
float UserInputMapper::getValue(const Endpoint::Pointer& endpoint) {
|
||||
return endpoint->value();
|
||||
float UserInputMapper::getValue(const Endpoint::Pointer& endpoint, bool peek) {
|
||||
return peek ? endpoint->peek() : endpoint->value();
|
||||
}
|
||||
|
||||
float UserInputMapper::getValue(const Input& input) const {
|
||||
|
@ -704,11 +704,11 @@ float UserInputMapper::getValue(const Input& input) const {
|
|||
return endpoint->value();
|
||||
}
|
||||
|
||||
Pose UserInputMapper::getPose(const Endpoint::Pointer& endpoint) {
|
||||
Pose UserInputMapper::getPose(const Endpoint::Pointer& endpoint, bool peek) {
|
||||
if (!endpoint->isPose()) {
|
||||
return Pose();
|
||||
}
|
||||
return endpoint->pose();
|
||||
return peek ? endpoint->peekPose() : endpoint->pose();
|
||||
}
|
||||
|
||||
Pose UserInputMapper::getPose(const Input& input) const {
|
||||
|
@ -742,6 +742,7 @@ static const QString JSON_NAME = QStringLiteral("name");
|
|||
static const QString JSON_CHANNELS = QStringLiteral("channels");
|
||||
static const QString JSON_CHANNEL_FROM = QStringLiteral("from");
|
||||
static const QString JSON_CHANNEL_DEBUG = QStringLiteral("debug");
|
||||
static const QString JSON_CHANNEL_PEEK = QStringLiteral("peek");
|
||||
static const QString JSON_CHANNEL_WHEN = QStringLiteral("when");
|
||||
static const QString JSON_CHANNEL_TO = QStringLiteral("to");
|
||||
static const QString JSON_CHANNEL_FILTERS = QStringLiteral("filters");
|
||||
|
@ -953,6 +954,7 @@ Route::Pointer UserInputMapper::parseRoute(const QJsonValue& value) {
|
|||
result->json = QString(QJsonDocument(obj).toJson());
|
||||
result->source = parseSource(obj[JSON_CHANNEL_FROM]);
|
||||
result->debug = obj[JSON_CHANNEL_DEBUG].toBool();
|
||||
result->debug = obj[JSON_CHANNEL_PEEK].toBool();
|
||||
if (!result->source) {
|
||||
qWarning() << "Invalid route source " << obj[JSON_CHANNEL_FROM];
|
||||
return Route::Pointer();
|
||||
|
|
|
@ -38,8 +38,8 @@ namespace controller {
|
|||
|
||||
class UserInputMapper : public QObject, public Dependency {
|
||||
Q_OBJECT
|
||||
SINGLETON_DEPENDENCY
|
||||
Q_ENUMS(Action)
|
||||
SINGLETON_DEPENDENCY
|
||||
Q_ENUMS(Action)
|
||||
|
||||
public:
|
||||
// FIXME move to unordered set / map
|
||||
|
@ -135,8 +135,8 @@ namespace controller {
|
|||
int recordDeviceOfType(const QString& deviceName);
|
||||
QHash<const QString&, int> _deviceCounts;
|
||||
|
||||
static float getValue(const EndpointPointer& endpoint);
|
||||
static Pose getPose(const EndpointPointer& endpoint);
|
||||
static float getValue(const EndpointPointer& endpoint, bool peek = false);
|
||||
static Pose getPose(const EndpointPointer& endpoint, bool peek = false);
|
||||
|
||||
friend class RouteBuilderProxy;
|
||||
friend class MappingBuilderProxy;
|
||||
|
|
|
@ -36,12 +36,13 @@ namespace controller {
|
|||
using WriteLambda = std::function<void(float)>;
|
||||
|
||||
Endpoint(const Input& input) : _input(input) {}
|
||||
virtual float value() = 0;
|
||||
virtual float value() { return peek(); }
|
||||
virtual float peek() const = 0;
|
||||
virtual void apply(float value, const Pointer& source) = 0;
|
||||
virtual Pose pose() { return Pose(); }
|
||||
virtual Pose peekPose() const { return Pose(); };
|
||||
virtual Pose pose() { return peekPose(); }
|
||||
virtual void apply(const Pose& value, const Pointer& source) {}
|
||||
virtual bool isPose() { return _input.isPose(); }
|
||||
|
||||
virtual bool isPose() const { return _input.isPose(); }
|
||||
virtual bool writeable() const { return true; }
|
||||
virtual bool readable() const { return true; }
|
||||
virtual void reset() { }
|
||||
|
@ -58,7 +59,7 @@ namespace controller {
|
|||
LambdaEndpoint(ReadLambda readLambda, WriteLambda writeLambda = [](float) {})
|
||||
: Endpoint(Input::INVALID_INPUT), _readLambda(readLambda), _writeLambda(writeLambda) { }
|
||||
|
||||
virtual float value() override { return _readLambda(); }
|
||||
virtual float peek() const override { return _readLambda(); }
|
||||
virtual void apply(float value, const Pointer& source) override { _writeLambda(value); }
|
||||
|
||||
private:
|
||||
|
@ -73,10 +74,10 @@ namespace controller {
|
|||
: Endpoint(id) {
|
||||
}
|
||||
|
||||
virtual float value() override { return _currentValue; }
|
||||
virtual float peek() const override { return _currentValue; }
|
||||
virtual void apply(float value, const Pointer& source) override { _currentValue = value; }
|
||||
|
||||
virtual Pose pose() override { return _currentPose; }
|
||||
virtual Pose peekPose() const override { return _currentPose; }
|
||||
virtual void apply(const Pose& value, const Pointer& source) override {
|
||||
_currentPose = value;
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ namespace controller {
|
|||
Filter::List filters;
|
||||
QString json;
|
||||
bool debug { false };
|
||||
bool peek { false };
|
||||
|
||||
using Pointer = std::shared_ptr<Route>;
|
||||
using List = std::list<Pointer>;
|
||||
|
|
|
@ -52,6 +52,11 @@ QObject* RouteBuilderProxy::debug(bool enable) {
|
|||
return this;
|
||||
}
|
||||
|
||||
QObject* RouteBuilderProxy::peek(bool enable) {
|
||||
_route->peek = enable;
|
||||
return this;
|
||||
}
|
||||
|
||||
QObject* RouteBuilderProxy::when(const QScriptValue& expression) {
|
||||
_route->conditional = _parent.conditionalFor(expression);
|
||||
return this;
|
||||
|
|
|
@ -38,6 +38,7 @@ class RouteBuilderProxy : public QObject {
|
|||
|
||||
Q_INVOKABLE void to(const QScriptValue& destination);
|
||||
Q_INVOKABLE QObject* debug(bool enable = true);
|
||||
Q_INVOKABLE QObject* peek(bool enable = true);
|
||||
Q_INVOKABLE QObject* when(const QScriptValue& expression);
|
||||
Q_INVOKABLE QObject* clamp(float min, float max);
|
||||
Q_INVOKABLE QObject* hysteresis(float min, float max);
|
||||
|
@ -48,7 +49,7 @@ class RouteBuilderProxy : public QObject {
|
|||
Q_INVOKABLE QObject* constrainToInteger();
|
||||
Q_INVOKABLE QObject* constrainToPositiveInteger();
|
||||
|
||||
private:
|
||||
private:
|
||||
void to(const Endpoint::Pointer& destination);
|
||||
void conditional(const Conditional::Pointer& conditional);
|
||||
void addFilter(Filter::Pointer filter);
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace controller {
|
|||
class EndpointConditional : public Conditional {
|
||||
public:
|
||||
EndpointConditional(Endpoint::Pointer endpoint) : _endpoint(endpoint) {}
|
||||
virtual bool satisfied() override { return _endpoint && _endpoint->value() != 0.0f; }
|
||||
virtual bool satisfied() override { return _endpoint && _endpoint->peek() != 0.0f; }
|
||||
private:
|
||||
Endpoint::Pointer _endpoint;
|
||||
};
|
||||
|
|
|
@ -23,10 +23,10 @@ class ActionEndpoint : public Endpoint {
|
|||
public:
|
||||
ActionEndpoint(const Input& id = Input::INVALID_INPUT) : Endpoint(id) { }
|
||||
|
||||
virtual float value() override { return _currentValue; }
|
||||
virtual float peek() const { return _currentValue; }
|
||||
virtual void apply(float newValue, const Pointer& source) override;
|
||||
|
||||
virtual Pose pose() override { return _currentPose; }
|
||||
virtual Pose peekPose() const { return _currentPose; }
|
||||
virtual void apply(const Pose& value, const Pointer& source) override;
|
||||
|
||||
virtual void reset() override;
|
||||
|
|
|
@ -27,13 +27,19 @@ AnyEndpoint::AnyEndpoint(Endpoint::List children) : Endpoint(Input::INVALID_INPU
|
|||
}
|
||||
}
|
||||
|
||||
float AnyEndpoint::peek() const {
|
||||
float result = 0;
|
||||
for (auto& child : _children) {
|
||||
result = std::max(result, child->peek());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
// Fetching the value must trigger any necessary side effects of value() on ALL the children.
|
||||
float AnyEndpoint::value() {
|
||||
float result = 0;
|
||||
for (auto& child : _children) {
|
||||
float childResult = child->value();
|
||||
if (childResult != 0.0f) {
|
||||
result = childResult;
|
||||
}
|
||||
result = std::max(result, child->value());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -19,6 +19,7 @@ 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 bool writeable() const override;
|
||||
|
|
|
@ -21,9 +21,7 @@ public:
|
|||
using Pointer = std::shared_ptr<ArrayEndpoint>;
|
||||
ArrayEndpoint() : Endpoint(Input::INVALID_INPUT) { }
|
||||
|
||||
virtual float value() override {
|
||||
return 0.0;
|
||||
}
|
||||
virtual float peek() const override { return 0.0f; }
|
||||
|
||||
virtual void apply(float value, const Endpoint::Pointer& source) override {
|
||||
for (auto& child : _children) {
|
||||
|
|
|
@ -24,6 +24,12 @@ bool CompositeEndpoint::readable() const {
|
|||
return first->readable() && second->readable();
|
||||
}
|
||||
|
||||
float CompositeEndpoint::peek() const {
|
||||
float result = first->peek() * -1.0f + second->peek();
|
||||
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();
|
||||
return result;
|
||||
|
|
|
@ -18,6 +18,7 @@ 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 bool readable() const override;
|
||||
|
|
|
@ -13,10 +13,10 @@
|
|||
#include "../../UserInputMapper.h"
|
||||
|
||||
using namespace controller;
|
||||
float InputEndpoint::value(){
|
||||
_read = true;
|
||||
|
||||
float InputEndpoint::peek() const {
|
||||
if (isPose()) {
|
||||
return pose().valid ? 1.0f : 0.0f;
|
||||
return peekPose().valid ? 1.0f : 0.0f;
|
||||
}
|
||||
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
||||
auto deviceProxy = userInputMapper->getDevice(_input);
|
||||
|
@ -26,8 +26,12 @@ float InputEndpoint::value(){
|
|||
return deviceProxy->getValue(_input);
|
||||
}
|
||||
|
||||
Pose InputEndpoint::pose() {
|
||||
float InputEndpoint::value(){
|
||||
_read = true;
|
||||
return peek();
|
||||
}
|
||||
|
||||
Pose InputEndpoint::peekPose() const {
|
||||
if (!isPose()) {
|
||||
return Pose();
|
||||
}
|
||||
|
@ -39,3 +43,8 @@ Pose InputEndpoint::pose() {
|
|||
return deviceProxy->getPose(_input.channel);
|
||||
}
|
||||
|
||||
Pose InputEndpoint::pose() {
|
||||
_read = true;
|
||||
return peekPose();
|
||||
}
|
||||
|
||||
|
|
|
@ -20,9 +20,11 @@ public:
|
|||
: Endpoint(id) {
|
||||
}
|
||||
|
||||
virtual float peek() const override;
|
||||
virtual float value() override;
|
||||
// FIXME need support for writing back to vibration / force feedback effects
|
||||
virtual void apply(float newValue, const Pointer& source) override {}
|
||||
virtual Pose peekPose() const override;
|
||||
virtual Pose pose() override;
|
||||
virtual void apply(const Pose& value, const Pointer& source) override { }
|
||||
|
||||
|
|
|
@ -24,9 +24,8 @@ public:
|
|||
: Endpoint(Input::INVALID_INPUT), _callable(callable) {
|
||||
}
|
||||
|
||||
virtual float value() {
|
||||
float result = (float)_callable.call().toNumber();
|
||||
return result;
|
||||
virtual float peek() const {
|
||||
return (float)const_cast<JSEndpoint*>(this)->_callable.call().toNumber();
|
||||
}
|
||||
|
||||
virtual void apply(float newValue, const Pointer& source) {
|
||||
|
|
|
@ -12,8 +12,8 @@
|
|||
|
||||
using namespace controller;
|
||||
|
||||
float ScriptEndpoint::value() {
|
||||
updateValue();
|
||||
float ScriptEndpoint::peek() const {
|
||||
const_cast<ScriptEndpoint*>(this)->updateValue();
|
||||
return _lastValueRead;
|
||||
}
|
||||
|
||||
|
|
|
@ -24,8 +24,8 @@ public:
|
|||
: Endpoint(Input::INVALID_INPUT), _callable(callable) {
|
||||
}
|
||||
|
||||
virtual float value();
|
||||
virtual void apply(float newValue, const Pointer& source);
|
||||
virtual float peek() const override;
|
||||
virtual void apply(float newValue, const Pointer& source) override;
|
||||
|
||||
protected:
|
||||
Q_INVOKABLE void updateValue();
|
||||
|
|
Loading…
Reference in a new issue