overte-HifiExperiments/interface/src/ui/UserInputMapper.cpp
2015-05-05 11:05:28 -07:00

146 lines
5.3 KiB
C++
Executable file

//
// UserInputMapper.cpp
// interface/src/ui
//
// Created by Sam Gateau on 4/27/15.
// Copyright 2015 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "UserInputMapper.h"
#include <algorithm>
// UserInputMapper Class
bool UserInputMapper::registerDevice(uint16 deviceID, const DeviceProxy::Pointer& proxy){
_registeredDevices[deviceID] = proxy;
return true;
}
UserInputMapper::DeviceProxy::Pointer UserInputMapper::getDeviceProxy(const Input& input) {
auto device = _registeredDevices.find(input.getDevice());
if (device != _registeredDevices.end()) {
return (device->second);
} else {
return DeviceProxy::Pointer();
}
}
bool UserInputMapper::addInputChannel(Action action, const Input& input, float scale) {
return addInputChannel(action, input, Input(), scale);
}
bool UserInputMapper::addInputChannel(Action action, const Input& input, const Input& modifier, float scale) {
// Check that the device is registered
if (!getDeviceProxy(input)) {
qDebug() << "UserInputMapper::addInputChannel: The input comes from a device #" << input.getDevice() << "is unknown. no inputChannel mapped.";
return false;
}
auto inputChannel = InputChannel(input, modifier, action, scale);
// Insert or replace the input to modifiers
if (inputChannel.hasModifier()) {
auto& modifiers = _inputToModifiersMap[input.getID()];
modifiers.push_back(inputChannel._modifier);
std::sort(modifiers.begin(), modifiers.end());
}
// Now update the action To Inputs side of things
_actionToInputsMap.insert(ActionToInputsMap::value_type(action, inputChannel));
return true;
}
int UserInputMapper::addInputChannels(const InputChannels& channels) {
int nbAdded = 0;
for (auto& channel : channels) {
nbAdded += addInputChannel(channel._action, channel._input, channel._modifier, channel._scale);
}
return nbAdded;
}
int UserInputMapper::getInputChannels(InputChannels& channels) const {
for (auto& channel : _actionToInputsMap) {
channels.push_back(channel.second);
}
return _actionToInputsMap.size();
}
void UserInputMapper::update(float deltaTime) {
// Reset the axis state for next loop
for (auto& channel : _actionStates) {
channel = 0.0f;
}
int currentTimestamp = 0;
for (auto& channelInput : _actionToInputsMap) {
auto& inputMapping = channelInput.second;
auto& inputID = inputMapping._input;
bool enabled = true;
// Check if this input channel has modifiers and collect the possibilities
auto modifiersIt = _inputToModifiersMap.find(inputID.getID());
if (modifiersIt != _inputToModifiersMap.end()) {
Modifiers validModifiers;
bool isActiveModifier = false;
for (auto& modifier : modifiersIt->second) {
auto deviceProxy = getDeviceProxy(modifier);
if (deviceProxy && deviceProxy->getButton(modifier, currentTimestamp)) {
validModifiers.push_back(modifier);
isActiveModifier |= (modifier.getID() == inputMapping._modifier.getID());
}
}
enabled = (validModifiers.empty() && !inputMapping.hasModifier()) || isActiveModifier;
}
// if enabled: default input or all modifiers on
auto deviceProxy = getDeviceProxy(inputID);
if (enabled && deviceProxy) {
switch (inputMapping._input.getType()) {
case ChannelType::BUTTON: {
_actionStates[channelInput.first] += inputMapping._scale * float(deviceProxy->getButton(inputID, currentTimestamp));// * deltaTime; // weight the impulse by the deltaTime
break;
}
case ChannelType::AXIS: {
_actionStates[channelInput.first] += inputMapping._scale * deviceProxy->getAxis(inputID, currentTimestamp);
break;
}
case ChannelType::JOINT: {
// _channelStates[channelInput.first].jointVal = deviceProxy->getJoint(inputID, currentTimestamp);
break;
}
default: {
break; //silence please
}
}
} else{
// Channel input not enabled
enabled = false;
}
}
// Scale all the channel step with the scale
for (auto i = 0; i < NUM_ACTIONS; i++) {
_actionStates[i] *= _actionScales[i];
}
}
void UserInputMapper::assignDefaulActionScales() {
_actionScales[LONGITUDINAL_BACKWARD] = 1.0f; // 1m per unit
_actionScales[LONGITUDINAL_FORWARD] = 1.0f; // 1m per unit
_actionScales[LATERAL_LEFT] = 1.0f; // 1m per unit
_actionScales[LATERAL_RIGHT] = 1.0f; // 1m per unit
_actionScales[VERTICAL_DOWN] = 1.0f; // 1m per unit
_actionScales[VERTICAL_UP] = 1.0f; // 1m per unit
_actionScales[YAW_LEFT] = 1.0f; // 1 degree per unit
_actionScales[YAW_RIGHT] = 1.0f; // 1 degree per unit
_actionScales[PITCH_DOWN] = 1.0f; // 1 degree per unit
_actionScales[PITCH_UP] = 1.0f; // 1 degree per unit
_actionScales[BOOM_IN] = 1.0f; // 1m per unit
_actionScales[BOOM_OUT] = 1.0f; // 1m per unit
}