mirror of
https://github.com/Armored-Dragon/overte.git
synced 2025-03-11 16:13:16 +01:00
Merge pull request #6156 from jherico/controllers
Minor cleanup and fix for broken conditional strafe
This commit is contained in:
commit
978d248c9e
8 changed files with 126 additions and 61 deletions
|
@ -23,6 +23,11 @@ Rectangle {
|
|||
|
||||
function update() {
|
||||
value = Controller.getValue(controlId);
|
||||
if (log) {
|
||||
var log = Math.log(10) / Math.log(Math.abs(value));
|
||||
var sign = Math.sign(value);
|
||||
value = log * sign;
|
||||
}
|
||||
canvas.requestPaint();
|
||||
}
|
||||
|
||||
|
|
|
@ -91,8 +91,7 @@ HifiControls.VrDialog {
|
|||
Hydra { device: root.hydra; width: 180 }
|
||||
}
|
||||
|
||||
Grid {
|
||||
columns: 6
|
||||
Row {
|
||||
spacing: 4
|
||||
ScrollingGraph {
|
||||
controlId: Controller.Actions.Yaw
|
||||
|
@ -117,13 +116,41 @@ HifiControls.VrDialog {
|
|||
max: 2.0
|
||||
size: 64
|
||||
}
|
||||
|
||||
ScrollingGraph {
|
||||
controlId: Controller.Actions.StepYaw
|
||||
label: "StepYaw"
|
||||
min: -20.0
|
||||
max: 20.0
|
||||
size: 64
|
||||
}
|
||||
}
|
||||
|
||||
Row {
|
||||
ScrollingGraph {
|
||||
controlId: Controller.Actions.TranslateZ
|
||||
label: "TranslateZ"
|
||||
min: -2.0
|
||||
max: 2.0
|
||||
size: 64
|
||||
}
|
||||
|
||||
ScrollingGraph {
|
||||
controlId: Controller.Actions.Forward
|
||||
label: "Forward"
|
||||
min: -2.0
|
||||
max: 2.0
|
||||
size: 64
|
||||
}
|
||||
|
||||
ScrollingGraph {
|
||||
controlId: Controller.Actions.Backward
|
||||
label: "Backward"
|
||||
min: -2.0
|
||||
max: 2.0
|
||||
size: 64
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} // dialog
|
||||
|
|
|
@ -48,18 +48,6 @@ namespace controller {
|
|||
makeAxisPair(Action::STEP_TRANSLATE_X, "StepTranslateX"),
|
||||
makeAxisPair(Action::STEP_TRANSLATE_X, "StepTranslateY"),
|
||||
makeAxisPair(Action::STEP_TRANSLATE_X, "StepTranslateZ"),
|
||||
makeAxisPair(Action::LONGITUDINAL_BACKWARD, "Backward"),
|
||||
makeAxisPair(Action::LONGITUDINAL_FORWARD, "Forward"),
|
||||
makeAxisPair(Action::LATERAL_LEFT, "StrafeLeft"),
|
||||
makeAxisPair(Action::LATERAL_RIGHT, "StrafeRight"),
|
||||
makeAxisPair(Action::VERTICAL_DOWN, "Down"),
|
||||
makeAxisPair(Action::VERTICAL_UP, "Up"),
|
||||
makeAxisPair(Action::YAW_LEFT, "YawLeft"),
|
||||
makeAxisPair(Action::YAW_RIGHT, "YawRight"),
|
||||
makeAxisPair(Action::PITCH_DOWN, "PitchDown"),
|
||||
makeAxisPair(Action::PITCH_UP, "PitchUp"),
|
||||
makeAxisPair(Action::BOOM_IN, "BoomIn"),
|
||||
makeAxisPair(Action::BOOM_OUT, "BoomOut"),
|
||||
|
||||
makePosePair(Action::LEFT_HAND, "LeftHand"),
|
||||
makePosePair(Action::RIGHT_HAND, "RightHand"),
|
||||
|
@ -73,6 +61,20 @@ namespace controller {
|
|||
makeButtonPair(Action::CONTEXT_MENU, "ContextMenu"),
|
||||
makeButtonPair(Action::TOGGLE_MUTE, "ToggleMute"),
|
||||
|
||||
// Aliases and bisected versions
|
||||
makeAxisPair(Action::LONGITUDINAL_BACKWARD, "Backward"),
|
||||
makeAxisPair(Action::LONGITUDINAL_FORWARD, "Forward"),
|
||||
makeAxisPair(Action::LATERAL_LEFT, "StrafeLeft"),
|
||||
makeAxisPair(Action::LATERAL_RIGHT, "StrafeRight"),
|
||||
makeAxisPair(Action::VERTICAL_DOWN, "Down"),
|
||||
makeAxisPair(Action::VERTICAL_UP, "Up"),
|
||||
makeAxisPair(Action::YAW_LEFT, "YawLeft"),
|
||||
makeAxisPair(Action::YAW_RIGHT, "YawRight"),
|
||||
makeAxisPair(Action::PITCH_DOWN, "PitchDown"),
|
||||
makeAxisPair(Action::PITCH_UP, "PitchUp"),
|
||||
makeAxisPair(Action::BOOM_IN, "BoomIn"),
|
||||
makeAxisPair(Action::BOOM_OUT, "BoomOut"),
|
||||
|
||||
// Deprecated aliases
|
||||
// FIXME remove after we port all scripts
|
||||
makeAxisPair(Action::LONGITUDINAL_BACKWARD, "LONGITUDINAL_BACKWARD"),
|
||||
|
|
|
@ -24,6 +24,8 @@ namespace controller {
|
|||
Endpoint::Pointer destination;
|
||||
Conditional::Pointer conditional;
|
||||
Filter::List filters;
|
||||
QString json;
|
||||
bool debug { false };
|
||||
|
||||
using Pointer = std::shared_ptr<Route>;
|
||||
using List = std::list<Pointer>;
|
||||
|
|
|
@ -73,10 +73,26 @@ void StandardController::buildDeviceProxy(DeviceProxy::Pointer proxy) {
|
|||
availableInputs.append(makePair(LT, "LT"));
|
||||
availableInputs.append(makePair(RT, "RT"));
|
||||
|
||||
|
||||
// Finger abstractions
|
||||
availableInputs.append(makePair(LEFT_PRIMARY_THUMB, "LeftPrimaryThumb"));
|
||||
availableInputs.append(makePair(LEFT_SECONDARY_THUMB, "LeftSecondaryThumb"));
|
||||
availableInputs.append(makePair(RIGHT_PRIMARY_THUMB, "RightPrimaryThumb"));
|
||||
availableInputs.append(makePair(RIGHT_SECONDARY_THUMB, "RightSecondaryThumb"));
|
||||
|
||||
availableInputs.append(makePair(LEFT_PRIMARY_INDEX, "LeftPrimaryIndex"));
|
||||
availableInputs.append(makePair(LEFT_SECONDARY_INDEX, "LeftSecondaryIndex"));
|
||||
availableInputs.append(makePair(RIGHT_PRIMARY_INDEX, "RightPrimaryIndex"));
|
||||
availableInputs.append(makePair(RIGHT_SECONDARY_INDEX, "RightSecondaryIndex"));
|
||||
|
||||
availableInputs.append(makePair(LEFT_GRIP, "LeftGrip"));
|
||||
availableInputs.append(makePair(RIGHT_GRIP, "RightGrip"));
|
||||
|
||||
// Poses
|
||||
availableInputs.append(makePair(LEFT_HAND, "LeftHand"));
|
||||
availableInputs.append(makePair(RIGHT_HAND, "RightHand"));
|
||||
|
||||
|
||||
// Aliases, PlayStation style names
|
||||
availableInputs.append(makePair(LB, "L1"));
|
||||
availableInputs.append(makePair(RB, "R1"));
|
||||
|
@ -95,10 +111,6 @@ void StandardController::buildDeviceProxy(DeviceProxy::Pointer proxy) {
|
|||
availableInputs.append(makePair(DR, "Right"));
|
||||
|
||||
|
||||
availableInputs.append(makePair(LEFT_PRIMARY_THUMB, "LeftPrimaryThumb"));
|
||||
availableInputs.append(makePair(LEFT_SECONDARY_THUMB, "LeftSecondaryThumb"));
|
||||
availableInputs.append(makePair(RIGHT_PRIMARY_THUMB, "RightPrimaryThumb"));
|
||||
availableInputs.append(makePair(RIGHT_SECONDARY_THUMB, "RightSecondaryThumb"));
|
||||
|
||||
return availableInputs;
|
||||
};
|
||||
|
|
|
@ -42,6 +42,14 @@ namespace controller {
|
|||
RIGHT_PRIMARY_THUMB,
|
||||
RIGHT_SECONDARY_THUMB,
|
||||
|
||||
LEFT_PRIMARY_INDEX,
|
||||
LEFT_SECONDARY_INDEX,
|
||||
RIGHT_PRIMARY_INDEX,
|
||||
RIGHT_SECONDARY_INDEX,
|
||||
|
||||
LEFT_GRIP,
|
||||
RIGHT_GRIP,
|
||||
|
||||
NUM_STANDARD_BUTTONS
|
||||
};
|
||||
|
||||
|
|
|
@ -655,8 +655,6 @@ Input UserInputMapper::makeStandardInput(controller::StandardPoseChannel pose) {
|
|||
|
||||
void UserInputMapper::runMappings() {
|
||||
static auto deviceNames = getDeviceNames();
|
||||
_overrides.clear();
|
||||
|
||||
for (auto endpointEntry : this->_endpointsByInput) {
|
||||
endpointEntry.second->reset();
|
||||
}
|
||||
|
@ -675,60 +673,59 @@ void UserInputMapper::runMappings() {
|
|||
}
|
||||
applyRoute(route);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void UserInputMapper::applyRoute(const Route::Pointer& route) {
|
||||
if (route->debug) {
|
||||
qCDebug(controllers) << "Applying route " << route->json;
|
||||
}
|
||||
|
||||
if (route->conditional) {
|
||||
if (!route->conditional->satisfied()) {
|
||||
if (route->debug) {
|
||||
qCDebug(controllers) << "Conditional failed";
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
auto source = route->source;
|
||||
if (_overrides.count(source)) {
|
||||
source = _overrides[source];
|
||||
}
|
||||
|
||||
// Endpoints can only be read once (though a given mapping can route them to
|
||||
// Most endpoints can only be read once (though a given mapping can route them to
|
||||
// multiple places). Consider... If the default is to wire the A button to JUMP
|
||||
// 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->debug) {
|
||||
qCDebug(controllers) << "Source unreadable";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
auto input = source->getInput();
|
||||
float value = source->value();
|
||||
if (value != 0.0) {
|
||||
int i = 0;
|
||||
}
|
||||
|
||||
auto destination = route->destination;
|
||||
// THis could happen if the route destination failed to create
|
||||
// FIXME: Maybe do not create the route if the destination failed and avoid this case ?
|
||||
if (!destination) {
|
||||
if (route->debug) {
|
||||
qCDebug(controllers) << "Bad Destination";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// FIXME?, should come before or after the override logic?
|
||||
if (!destination->writeable()) {
|
||||
if (route->debug) {
|
||||
qCDebug(controllers) << "Destination unwritable";
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Only consume the input if the route isn't a loopback.
|
||||
// This allows mappings like `mapping.from(xbox.RY).invert().to(xbox.RY);`
|
||||
bool loopback = (source->getInput() == destination->getInput()) && (source->getInput() != Input::INVALID_INPUT);
|
||||
// Each time we loop back we re-write the override
|
||||
if (loopback) {
|
||||
_overrides[source] = destination = std::make_shared<StandardEndpoint>(source->getInput());
|
||||
}
|
||||
|
||||
// Fetch the value, may have been overriden by previous loopback routes
|
||||
if (source->isPose()) {
|
||||
if (route->debug) {
|
||||
qCDebug(controllers) << "Applying pose";
|
||||
}
|
||||
Pose value = getPose(source);
|
||||
// no filters yet for pose
|
||||
destination->apply(value, Pose(), source);
|
||||
|
@ -736,11 +733,18 @@ void UserInputMapper::applyRoute(const Route::Pointer& route) {
|
|||
// Fetch the value, may have been overriden by previous loopback routes
|
||||
float value = getValue(source);
|
||||
|
||||
if (route->debug) {
|
||||
qCDebug(controllers) << "Value was " << value;
|
||||
}
|
||||
// Apply each of the filters.
|
||||
for (const auto& filter : route->filters) {
|
||||
value = filter->apply(value);
|
||||
}
|
||||
|
||||
if (route->debug) {
|
||||
qCDebug(controllers) << "Filtered value was " << value;
|
||||
}
|
||||
|
||||
destination->apply(value, 0, source);
|
||||
}
|
||||
}
|
||||
|
@ -850,11 +854,6 @@ void UserInputMapper::enableMapping(const QString& mappingName, bool enable) {
|
|||
|
||||
float UserInputMapper::getValue(const Endpoint::Pointer& endpoint) const {
|
||||
Locker locker(_lock);
|
||||
auto valuesIterator = _overrides.find(endpoint);
|
||||
if (_overrides.end() != valuesIterator) {
|
||||
return valuesIterator->second->value();
|
||||
}
|
||||
|
||||
return endpoint->value();
|
||||
}
|
||||
|
||||
|
@ -900,6 +899,7 @@ Mapping::Pointer UserInputMapper::loadMapping(const QString& jsonFile) {
|
|||
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_WHEN = QStringLiteral("when");
|
||||
static const QString JSON_CHANNEL_TO = QStringLiteral("to");
|
||||
static const QString JSON_CHANNEL_FILTERS = QStringLiteral("filters");
|
||||
|
@ -1052,9 +1052,12 @@ Route::Pointer UserInputMapper::parseRoute(const QJsonValue& value) {
|
|||
return Route::Pointer();
|
||||
}
|
||||
|
||||
const auto& obj = value.toObject();
|
||||
auto obj = value.toObject();
|
||||
Route::Pointer result = std::make_shared<Route>();
|
||||
|
||||
result->json = QString(QJsonDocument(obj).toJson());
|
||||
result->source = parseSource(obj[JSON_CHANNEL_FROM]);
|
||||
result->debug = obj[JSON_CHANNEL_DEBUG].toBool();
|
||||
if (!result->source) {
|
||||
qWarning() << "Invalid route source " << obj[JSON_CHANNEL_FROM];
|
||||
return Route::Pointer();
|
||||
|
@ -1067,6 +1070,11 @@ Route::Pointer UserInputMapper::parseRoute(const QJsonValue& value) {
|
|||
return Route::Pointer();
|
||||
}
|
||||
|
||||
if (result->source == result->destination) {
|
||||
qWarning() << "Loopback routes not supported " << obj;
|
||||
return Route::Pointer();
|
||||
}
|
||||
|
||||
if (obj.contains(JSON_CHANNEL_WHEN)) {
|
||||
auto conditionalsValue = obj[JSON_CHANNEL_WHEN];
|
||||
result->conditional = parseConditional(conditionalsValue);
|
||||
|
@ -1138,26 +1146,28 @@ void UserInputMapper::enableMapping(const Mapping::Pointer& mapping) {
|
|||
// are processed in order so this ensures that the standard -> action processing
|
||||
// takes place after all of the hardware -> standard or hardware -> action processing
|
||||
// because standard -> action is the first set of routes added.
|
||||
for (auto route : mapping->routes) {
|
||||
if (route->source->getInput().device == STANDARD_DEVICE) {
|
||||
_standardRoutes.push_front(route);
|
||||
} else {
|
||||
_deviceRoutes.push_front(route);
|
||||
}
|
||||
}
|
||||
Route::List standardRoutes = mapping->routes;
|
||||
standardRoutes.remove_if([](const Route::Pointer& value) {
|
||||
return (value->source->getInput().device == STANDARD_DEVICE);
|
||||
});
|
||||
_standardRoutes.insert(_standardRoutes.begin(), standardRoutes.begin(), standardRoutes.end());
|
||||
|
||||
Route::List deviceRoutes = mapping->routes;
|
||||
deviceRoutes.remove_if([](const Route::Pointer& value) {
|
||||
return (value->source->getInput().device != STANDARD_DEVICE);
|
||||
});
|
||||
_deviceRoutes.insert(_deviceRoutes.begin(), deviceRoutes.begin(), deviceRoutes.end());
|
||||
}
|
||||
|
||||
void UserInputMapper::disableMapping(const Mapping::Pointer& mapping) {
|
||||
Locker locker(_lock);
|
||||
const auto& deviceRoutes = mapping->routes;
|
||||
std::set<Route::Pointer> routeSet(deviceRoutes.begin(), deviceRoutes.end());
|
||||
|
||||
// FIXME this seems to result in empty route pointers... need to find a better way to remove them.
|
||||
std::remove_if(_deviceRoutes.begin(), _deviceRoutes.end(), [&](Route::Pointer route)->bool {
|
||||
return routeSet.count(route) != 0;
|
||||
_deviceRoutes.remove_if([&](const Route::Pointer& value){
|
||||
return routeSet.count(value) != 0;
|
||||
});
|
||||
std::remove_if(_standardRoutes.begin(), _standardRoutes.end(), [&](Route::Pointer route)->bool {
|
||||
return routeSet.count(route) != 0;
|
||||
_standardRoutes.remove_if([&](const Route::Pointer& value) {
|
||||
return routeSet.count(value) != 0;
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -165,7 +165,6 @@ namespace controller {
|
|||
EndpointToInputMap _inputsByEndpoint;
|
||||
EndpointPairMap _compositeEndpoints;
|
||||
|
||||
EndpointOverrideMap _overrides;
|
||||
MappingNameMap _mappingsByName;
|
||||
MappingDeviceMap _mappingsByDevice;
|
||||
|
||||
|
|
Loading…
Reference in a new issue