DOing the groundwork to pass along the pose

still not working
This commit is contained in:
samcake 2015-10-19 19:05:37 -07:00
parent 052ad1236c
commit 8701d73ee9
9 changed files with 254 additions and 114 deletions

View file

@ -1,90 +1,90 @@
//
// controllerScriptingExamples.js
// examples
//
// Created by Sam Gondelman on 6/2/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
//
// Assumes you only have the default keyboard connected
/*myFirstMapping = function() {
return {
"name": "example",
"channels": [
{ "from": "Keyboard.W", "to": "Actions.LONGITUDINAL_FORWARD" },
{ "from": "Keyboard.S", "to": "Actions.LONGITUDINAL_BACKWARD" },
{ "from": "Keyboard.Left", "to": "Actions.LATERAL_LEFT" },
{ "from": "Keyboard.Right", "to": "Actions.LATERAL_RIGHT" },
{ "from": "Keyboard.A", "to": "Actions.YAW_LEFT" },
{ "from": "Keyboard.D", "to": "Actions.YAW_RIGHT" },
{ "from": "Keyboard.C", "to": "Actions.VERTICAL_DOWN" },
{ "from": "Keyboard.E", "to": "Actions.VERTICAL_UP" },
{
"from": "Standard.LX",
"filters": [ {
"type": "scale",
"params": [2.0],
}
],
"to": "Actions.LATERAL_LEFT",
}, {
"from": "Keyboard.B",
"to": "Actions.Yaw"
}
]
}
}
*/
mySecondMapping = function() {
return {
"name": "example2",
"channels": [
{ "from": "Standard.LY", "to": "Actions.TranslateZ" },
{ "from": "Standard.LX", "to": "Actions.Yaw" },
]
}
}
//Script.include('mapping-test0.json');
/*var myFirstMappingJSON = myFirstMapping();
print('myFirstMappingJSON' + JSON.stringify(myFirstMappingJSON));
var mapping = Controller.parseMapping(JSON.stringify(myFirstMappingJSON));
Controller.enableMapping("example3");
var mySecondMappingJSON = mySecondMapping();
print('mySecondMappingJSON' + JSON.stringify(mySecondMappingJSON));
var mapping2 = Controller.parseMapping(JSON.stringify(mySecondMappingJSON));
mapping2.enable();
Controller.enableMapping("example2");
*/
var mapping3 = Controller.loadMapping(Script.resolvePath("example3.json"));
Controller.enableMapping("example3");
/*
Object.keys(Controller.Standard).forEach(function (input) {
print("Controller.Standard." + input + ":" + Controller.Standard[input]);
});
Object.keys(Controller.Hardware).forEach(function (deviceName) {
Object.keys(Controller.Hardware[deviceName]).forEach(function (input) {
print("Controller.Hardware." + deviceName + "." + input + ":" + Controller.Hardware[deviceName][input]);
});
});
Object.keys(Controller.Actions).forEach(function (actionName) {
print("Controller.Actions." + actionName + ":" + Controller.Actions[actionName]);
});
//
// controllerScriptingExamples.js
// examples
//
// Created by Sam Gondelman on 6/2/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
//
// Assumes you only have the default keyboard connected
/*myFirstMapping = function() {
return {
"name": "example",
"channels": [
{ "from": "Keyboard.W", "to": "Actions.LONGITUDINAL_FORWARD" },
{ "from": "Keyboard.S", "to": "Actions.LONGITUDINAL_BACKWARD" },
{ "from": "Keyboard.Left", "to": "Actions.LATERAL_LEFT" },
{ "from": "Keyboard.Right", "to": "Actions.LATERAL_RIGHT" },
{ "from": "Keyboard.A", "to": "Actions.YAW_LEFT" },
{ "from": "Keyboard.D", "to": "Actions.YAW_RIGHT" },
{ "from": "Keyboard.C", "to": "Actions.VERTICAL_DOWN" },
{ "from": "Keyboard.E", "to": "Actions.VERTICAL_UP" },
{
"from": "Standard.LX",
"filters": [ {
"type": "scale",
"params": [2.0],
}
],
"to": "Actions.LATERAL_LEFT",
}, {
"from": "Keyboard.B",
"to": "Actions.Yaw"
}
]
}
}
*/
mySecondMapping = function() {
return {
"name": "example2",
"channels": [
{ "from": "Standard.LY", "to": "Actions.TranslateZ" },
{ "from": "Standard.LX", "to": "Actions.Yaw" },
]
}
}
//Script.include('mapping-test0.json');
/*var myFirstMappingJSON = myFirstMapping();
print('myFirstMappingJSON' + JSON.stringify(myFirstMappingJSON));
var mapping = Controller.parseMapping(JSON.stringify(myFirstMappingJSON));
Controller.enableMapping("example3");
var mySecondMappingJSON = mySecondMapping();
print('mySecondMappingJSON' + JSON.stringify(mySecondMappingJSON));
var mapping2 = Controller.parseMapping(JSON.stringify(mySecondMappingJSON));
mapping2.enable();
Controller.enableMapping("example2");
*/
var mapping3 = Controller.loadMapping(Script.resolvePath("example3.json"));
Controller.enableMapping("example3");
/*
Object.keys(Controller.Standard).forEach(function (input) {
print("Controller.Standard." + input + ":" + Controller.Standard[input]);
});
Object.keys(Controller.Hardware).forEach(function (deviceName) {
Object.keys(Controller.Hardware[deviceName]).forEach(function (input) {
print("Controller.Hardware." + deviceName + "." + input + ":" + Controller.Hardware[deviceName][input]);
});
});
Object.keys(Controller.Actions).forEach(function (actionName) {
print("Controller.Actions." + actionName + ":" + Controller.Actions[actionName]);
});
*/

View file

@ -35,7 +35,12 @@ namespace controller {
Endpoint(const UserInputMapper::Input& input) : _input(input) {}
virtual float value() = 0;
virtual void apply(float newValue, float oldValue, const Pointer& source) = 0;
const UserInputMapper::Input& getInput() { return _input; }
virtual Pose pose() { return Pose(); }
virtual void apply(const Pose& newValue, const Pose& oldValue, const Pointer& source) {}
virtual const bool isPose() { return _input.isPose(); }
const UserInputMapper::Input& getInput() { return _input; }
protected:
UserInputMapper::Input _input;
};

View file

@ -35,10 +35,16 @@ namespace controller {
}
virtual float value() override { return _currentValue; }
virtual void apply(float newValue, float oldValue, const Pointer& source) override { _currentValue = newValue; }
virtual void apply(float newValue, float oldValue, const Pointer& source) override {
_currentValue = newValue;
}
virtual Pose pose() override { return _currentPose; }
virtual void apply(const Pose& newValue, const Pose& oldValue, const Pointer& source) override {
_currentPose = newValue;
}
private:
float _currentValue{ 0.0f };
Pose _currentPose{};
};
@ -109,6 +115,49 @@ namespace controller {
Endpoint::Pointer _second;
};
class InputEndpoint : public Endpoint {
public:
InputEndpoint(const UserInputMapper::Input& id = UserInputMapper::Input::INVALID_INPUT)
: Endpoint(id) {
}
virtual float value() override {
_currentValue = 0.0f;
if (isPose()) {
return _currentValue;
}
auto userInputMapper = DependencyManager::get<UserInputMapper>();
auto deviceProxy = userInputMapper->getDeviceProxy(_input);
if (!deviceProxy) {
return _currentValue;
}
_currentValue = deviceProxy->getValue(_input, 0);
return _currentValue;
}
virtual void apply(float newValue, float oldValue, const Pointer& source) override {}
virtual Pose pose() override {
_currentPose = Pose();
if (!isPose()) {
return _currentPose;
}
auto userInputMapper = DependencyManager::get<UserInputMapper>();
auto deviceProxy = userInputMapper->getDeviceProxy(_input);
if (!deviceProxy) {
return _currentPose;
}
_currentPose = deviceProxy->getPose(_input, 0);
return _currentPose;
}
virtual void apply(const Pose& newValue, const Pose& oldValue, const Pointer& source) override {
}
private:
float _currentValue{ 0.0f };
Pose _currentPose{};
};
class ActionEndpoint : public Endpoint {
public:
ActionEndpoint(const UserInputMapper::Input& id = UserInputMapper::Input::INVALID_INPUT)
@ -125,8 +174,18 @@ namespace controller {
}
}
virtual Pose pose() override { return _currentPose; }
virtual void apply(const Pose& newValue, const Pose& oldValue, const Pointer& source) override {
_currentPose = newValue;
if (!(_input == UserInputMapper::Input::INVALID_INPUT)) {
auto userInputMapper = DependencyManager::get<UserInputMapper>();
userInputMapper->setActionState(UserInputMapper::Action(_input.getChannel()), _currentPose);
}
}
private:
float _currentValue{ 0.0f };
Pose _currentPose{};
};
QRegularExpression ScriptingInterface::SANITIZE_NAME_EXPRESSION{ "[\\(\\)\\.\\s]" };
@ -263,8 +322,34 @@ namespace controller {
return getValue(UserInputMapper::Input(device, source, UserInputMapper::ChannelType::AXIS).getID());
}
Pose ScriptingInterface::getPoseValue(const int& source) const {
if (!Input(source).isPose()) {
return Pose();
}
UserInputMapper::Input input(source);
auto iterator = _endpoints.find(input);
if (_endpoints.end() == iterator) {
return Pose();
}
const auto& endpoint = iterator->second;
return getPoseValue(endpoint);
}
Pose ScriptingInterface::getPoseValue(const Endpoint::Pointer& endpoint) const {
/*auto valuesIterator = _overrideValues.find(endpoint);
if (_overrideValues.end() != valuesIterator) {
return valuesIterator->second;
}*/
return endpoint->pose();
}
Pose ScriptingInterface::getPoseValue(StandardPoseChannel source, uint16_t device) const {
return Pose();
return getPoseValue(UserInputMapper::Input(device, source, UserInputMapper::ChannelType::POSE).getID());
}
void ScriptingInterface::update() {
@ -321,18 +406,25 @@ namespace controller {
}
// Fetch the value, may have been overriden by previous loopback routes
float value = getValue(source);
if (source->isPose()) {
Pose value = getPoseValue(source);
// Apply each of the filters.
const auto& filters = route->_filters;
for (const auto& filter : route->_filters) {
value = filter->apply(value);
}
if (loopback) {
_overrideValues[source] = value;
destination->apply(value, Pose(), source);
} else {
destination->apply(value, 0, source);
float value = getValue(source);
// Apply each of the filters.
const auto& filters = route->_filters;
for (const auto& filter : route->_filters) {
value = filter->apply(value);
}
if (loopback) {
_overrideValues[source] = value;
} else {
destination->apply(value, 0, source);
}
}
}
}
@ -483,13 +575,14 @@ namespace controller {
if (_endpoints.count(input)) {
continue;
}
_endpoints[input] = std::make_shared<LambdaEndpoint>([=] {
/* _endpoints[input] = std::make_shared<LambdaEndpoint>([=] {
auto deviceProxy = userInputMapper->getDeviceProxy(input);
if (!deviceProxy) {
return 0.0f;
}
return deviceProxy->getValue(input, 0);
});
});*/
_endpoints[input] = std::make_shared<InputEndpoint>(input);
}
}
}

View file

@ -79,7 +79,9 @@ namespace controller {
Q_INVOKABLE float getValue(const int& source) const;
Q_INVOKABLE float getButtonValue(StandardButtonChannel source, uint16_t device = 0) const;
Q_INVOKABLE float getAxisValue(StandardAxisChannel source, uint16_t device = 0) const;
Q_INVOKABLE Pose getPoseValue(const int& source) const;
Q_INVOKABLE Pose getPoseValue(StandardPoseChannel source, uint16_t device = 0) const;
Q_INVOKABLE QObject* newMapping(const QString& mappingName = QUuid::createUuid().toString());
Q_INVOKABLE void enableMapping(const QString& mappingName, bool enable = true);
Q_INVOKABLE void disableMapping(const QString& mappingName) { enableMapping(mappingName, false); }
@ -148,6 +150,7 @@ namespace controller {
void update(Mapping::Pointer& mapping, EndpointSet& consumed);
float getValue(const Endpoint::Pointer& endpoint) const;
Pose getPoseValue(const Endpoint::Pointer& endpoint) const;
Endpoint::Pointer endpointFor(const QJSValue& endpoint);
Endpoint::Pointer endpointFor(const QScriptValue& endpoint);
Endpoint::Pointer endpointFor(const UserInputMapper::Input& endpoint);

View file

@ -72,8 +72,8 @@ void StandardController::registerToUserInputMapper(UserInputMapper& mapper) {
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::RT), "RT"));
// Poses
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::LEFT), "LeftPose"));
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::RIGHT), "RightPose"));
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::LEFT_HAND), "LeftHand"));
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::RIGHT_HAND), "RightHand"));
// Aliases, PlayStation style names
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::LB), "L1"));

View file

@ -50,8 +50,8 @@ namespace controller {
// No correlation to SDL
enum StandardPoseChannel {
LEFT = 0,
RIGHT,
LEFT_HAND = 0,
RIGHT_HAND,
HEAD,
NUM_STANDARD_POSES
};

View file

@ -308,12 +308,17 @@ void UserInputMapper::update(float deltaTime) {
}
}
// Scale all the channel step with the scale
//manage the external action states changes coming from the Controllers Graph
for (auto i = 0; i < NUM_ACTIONS; i++) {
if (_externalActionStates[i] != 0) {
_actionStates[i] += _externalActionStates[i];
_externalActionStates[i] = 0.0f;
}
if (_externalPoseStates[i].isValid()) {
_poseStates[i] = _externalPoseStates[i];
_externalPoseStates[i] = PoseValue();
}
}
// merge the bisected and non-bisected axes for now
@ -432,6 +437,35 @@ void UserInputMapper::createActionNames() {
_actionNames[ROLL] = "Roll";
_actionNames[PITCH] = "Pitch";
_actionNames[YAW] = "Yaw";
_actionInputs[LONGITUDINAL_BACKWARD] = Input(ACTIONS_DEVICE, LONGITUDINAL_BACKWARD, ChannelType::AXIS);
_actionInputs[LONGITUDINAL_FORWARD] = Input(ACTIONS_DEVICE, LONGITUDINAL_BACKWARD, ChannelType::AXIS);
_actionInputs[LATERAL_LEFT] = Input(ACTIONS_DEVICE, LATERAL_LEFT, ChannelType::AXIS);
_actionInputs[LATERAL_RIGHT] = Input(ACTIONS_DEVICE, LATERAL_RIGHT, ChannelType::AXIS);
_actionInputs[VERTICAL_DOWN] = Input(ACTIONS_DEVICE, VERTICAL_DOWN, ChannelType::AXIS);
_actionInputs[VERTICAL_UP] = Input(ACTIONS_DEVICE, VERTICAL_UP, ChannelType::AXIS);
_actionInputs[YAW_LEFT] = Input(ACTIONS_DEVICE, YAW_LEFT, ChannelType::AXIS);
_actionInputs[YAW_RIGHT] = Input(ACTIONS_DEVICE, YAW_RIGHT, ChannelType::AXIS);
_actionInputs[PITCH_DOWN] = Input(ACTIONS_DEVICE, PITCH_DOWN, ChannelType::AXIS);
_actionInputs[PITCH_UP] = Input(ACTIONS_DEVICE, PITCH_UP, ChannelType::AXIS);
_actionInputs[BOOM_IN] = Input(ACTIONS_DEVICE, BOOM_IN, ChannelType::AXIS);
_actionInputs[BOOM_OUT] = Input(ACTIONS_DEVICE, BOOM_OUT, ChannelType::AXIS);
_actionInputs[LEFT_HAND] = Input(ACTIONS_DEVICE, LEFT_HAND, ChannelType::POSE);
_actionInputs[RIGHT_HAND] = Input(ACTIONS_DEVICE, RIGHT_HAND, ChannelType::POSE);
_actionInputs[LEFT_HAND_CLICK] = Input(ACTIONS_DEVICE, LEFT_HAND_CLICK, ChannelType::AXIS);
_actionInputs[RIGHT_HAND_CLICK] = Input(ACTIONS_DEVICE, RIGHT_HAND_CLICK, ChannelType::AXIS);
_actionInputs[SHIFT] = Input(ACTIONS_DEVICE, SHIFT, ChannelType::BUTTON);
_actionInputs[ACTION1] = Input(ACTIONS_DEVICE, ACTION1, ChannelType::BUTTON);
_actionInputs[ACTION2] = Input(ACTIONS_DEVICE, ACTION2, ChannelType::BUTTON);
_actionInputs[CONTEXT_MENU] = Input(ACTIONS_DEVICE, CONTEXT_MENU, ChannelType::BUTTON);
_actionInputs[TOGGLE_MUTE] = Input(ACTIONS_DEVICE, TOGGLE_MUTE, ChannelType::AXIS);
_actionInputs[TRANSLATE_X] = Input(ACTIONS_DEVICE, TRANSLATE_X, ChannelType::AXIS);
_actionInputs[TRANSLATE_Y] = Input(ACTIONS_DEVICE, TRANSLATE_Y, ChannelType::AXIS);
_actionInputs[TRANSLATE_Z] = Input(ACTIONS_DEVICE, TRANSLATE_Z, ChannelType::AXIS);
_actionInputs[ROLL] = Input(ACTIONS_DEVICE, ROLL, ChannelType::AXIS);
_actionInputs[PITCH] = Input(ACTIONS_DEVICE, PITCH, ChannelType::AXIS);
_actionInputs[YAW] = Input(ACTIONS_DEVICE, YAW, ChannelType::AXIS);
}
void UserInputMapper::registerStandardDevice() {

View file

@ -134,13 +134,15 @@ public:
QVector<Action> getAllActions() const;
QString getActionName(Action action) const { return UserInputMapper::_actionNames[(int) action]; }
float getActionState(Action action) const { return _actionStates[action]; }
PoseValue getPoseState(Action action) const { return _poseStates[action]; }
const PoseValue& getPoseState(Action action) const { return _poseStates[action]; }
int findAction(const QString& actionName) const;
QVector<QString> getActionNames() const;
Input getActionInput(Action action) const { return _actionInputs[action]; }
void assignDefaulActionScales();
void setActionState(Action action, float value) { _externalActionStates[action] = value; }
void deltaActionState(Action action, float delta) { _externalActionStates[action] += delta; }
void setActionState(Action action, const PoseValue& value) { _externalPoseStates[action] = value; }
// Add input channel to the mapper and check that all the used channels are registered.
// Return true if theinput channel is created correctly, false either
@ -224,11 +226,14 @@ protected:
typedef std::multimap<Action, InputChannel> ActionToInputsMap;
ActionToInputsMap _actionToInputsMap;
std::vector<Input> _actionInputs = std::vector<Input>(NUM_ACTIONS, Input());
std::vector<float> _actionStates = std::vector<float>(NUM_ACTIONS, 0.0f);
std::vector<float> _externalActionStates = std::vector<float>(NUM_ACTIONS, 0.0f);
std::vector<float> _actionScales = std::vector<float>(NUM_ACTIONS, 1.0f);
std::vector<float> _lastActionStates = std::vector<float>(NUM_ACTIONS, 0.0f);
std::vector<PoseValue> _poseStates = std::vector<PoseValue>(NUM_ACTIONS);
std::vector<PoseValue> _externalPoseStates = std::vector<PoseValue>(NUM_ACTIONS);
glm::mat4 _sensorToWorldMat;

View file

@ -236,7 +236,7 @@ void SixenseManager::update(float deltaTime, bool jointsCaptured) {
_poseStateMap.clear();
}
} else {
_poseStateMap[left ? controller::StandardPoseChannel::LEFT : controller::StandardPoseChannel::RIGHT] = UserInputMapper::PoseValue();
_poseStateMap[left ? controller::StandardPoseChannel::LEFT_HAND : controller::StandardPoseChannel::RIGHT_HAND] = UserInputMapper::PoseValue();
}
}
@ -444,7 +444,7 @@ void SixenseManager::handlePoseEvent(glm::vec3 position, glm::quat rotation, boo
// TODO: find a shortcut with fewer rotations.
rotation = _avatarRotation * postOffset * glm::inverse(sixenseToHand) * rotation * preOffset * sixenseToHand;
_poseStateMap[left ? controller::StandardPoseChannel::LEFT : controller::StandardPoseChannel::RIGHT] =
_poseStateMap[left ? controller::StandardPoseChannel::LEFT_HAND : controller::StandardPoseChannel::RIGHT_HAND] =
UserInputMapper::PoseValue(position, rotation);
#endif // HAVE_SIXENSE
}
@ -490,8 +490,8 @@ void SixenseManager::registerToUserInputMapper(UserInputMapper& mapper) {
availableInputs.append(UserInputMapper::InputPair(makeInput(RX), "RX"));
availableInputs.append(UserInputMapper::InputPair(makeInput(RY), "RY"));
availableInputs.append(UserInputMapper::InputPair(makeInput(RT), "RT"));
availableInputs.append(UserInputMapper::InputPair(makeInput(LEFT), "LeftPose"));
availableInputs.append(UserInputMapper::InputPair(makeInput(RIGHT), "RightPose"));
availableInputs.append(UserInputMapper::InputPair(makeInput(LEFT_HAND), "LeftHand"));
availableInputs.append(UserInputMapper::InputPair(makeInput(RIGHT_HAND), "RightHand"));
return availableInputs;
};
mapper.registerDevice(_deviceID, proxy);