mirror of
https://github.com/overte-org/overte.git
synced 2025-07-22 18:34:56 +02:00
Merging
This commit is contained in:
commit
cdfe9788d1
56 changed files with 2125 additions and 1939 deletions
|
@ -1,12 +1,12 @@
|
||||||
set(TARGET_NAME assignment-client)
|
set(TARGET_NAME assignment-client)
|
||||||
|
|
||||||
setup_hifi_project(Core Gui Network Script Widgets WebSockets)
|
setup_hifi_project(Core Gui Network Script Quick Widgets WebSockets)
|
||||||
|
|
||||||
# link in the shared libraries
|
# link in the shared libraries
|
||||||
link_hifi_libraries(
|
link_hifi_libraries(
|
||||||
audio avatars octree environment gpu model fbx entities
|
audio avatars octree environment gpu model fbx entities
|
||||||
networking animation shared script-engine embedded-webserver
|
networking animation shared script-engine embedded-webserver
|
||||||
physics
|
controllers physics
|
||||||
)
|
)
|
||||||
|
|
||||||
include_application_version()
|
include_application_version()
|
||||||
|
|
|
@ -54,7 +54,7 @@ return {
|
||||||
var myFirstMappingJSON = myFirstMapping();
|
var myFirstMappingJSON = myFirstMapping();
|
||||||
print('myFirstMappingJSON' + JSON.stringify(myFirstMappingJSON));
|
print('myFirstMappingJSON' + JSON.stringify(myFirstMappingJSON));
|
||||||
|
|
||||||
var mapping = NewControllers.parseMapping(JSON.stringify(myFirstMappingJSON));
|
var mapping = Controller.parseMapping(JSON.stringify(myFirstMappingJSON));
|
||||||
|
|
||||||
Object.keys(Controller.Standard).forEach(function (input) {
|
Object.keys(Controller.Standard).forEach(function (input) {
|
||||||
print("Controller.Standard." + input + ":" + Controller.Standard[input]);
|
print("Controller.Standard." + input + ":" + Controller.Standard[input]);
|
||||||
|
|
|
@ -11,6 +11,16 @@
|
||||||
|
|
||||||
// Assumes you only have the default keyboard connected
|
// Assumes you only have the default keyboard connected
|
||||||
|
|
||||||
|
function findAction(name) {
|
||||||
|
var actions = Controller.getAllActions();
|
||||||
|
for (var i = 0; i < actions.length; i++) {
|
||||||
|
if (actions[i].actionName == name) {
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// If the action isn't found, it will default to the first available action
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
var hydra = Controller.Hardware.Hydra2;
|
var hydra = Controller.Hardware.Hydra2;
|
||||||
|
@ -46,44 +56,48 @@ Controller.resetAllDeviceBindings();
|
||||||
// Query all actions
|
// Query all actions
|
||||||
print("All Actions: \n" + Controller.getAllActions());
|
print("All Actions: \n" + Controller.getAllActions());
|
||||||
|
|
||||||
|
var actionId = findAction("YAW_LEFT")
|
||||||
|
|
||||||
|
print("Yaw Left action ID: " + actionId)
|
||||||
|
|
||||||
// Each action stores:
|
// Each action stores:
|
||||||
// action: int representation of enum
|
// action: int representation of enum
|
||||||
print("Action 5 int: \n" + Controller.getAllActions()[5].action);
|
print("Action int: \n" + Controller.getAllActions()[actionId].action);
|
||||||
|
|
||||||
// actionName: string representation of enum
|
// actionName: string representation of enum
|
||||||
print("Action 5 name: \n" + Controller.getAllActions()[5].actionName);
|
print("Action name: \n" + Controller.getAllActions()[actionId].actionName);
|
||||||
|
|
||||||
// inputChannels: list of all inputchannels that control that action
|
// inputChannels: list of all inputchannels that control that action
|
||||||
print("Action 5 input channels: \n" + Controller.getAllActions()[5].inputChannels + "\n");
|
print("Action input channels: \n" + Controller.getAllActions()[actionId].inputChannels + "\n");
|
||||||
|
|
||||||
|
|
||||||
// Each input channel stores:
|
// Each input channel stores:
|
||||||
// action: Action that this InputChannel maps to
|
// action: Action that this InputChannel maps to
|
||||||
print("Input channel action: \n" + Controller.getAllActions()[5].inputChannels[0].action);
|
print("Input channel action: \n" + Controller.getAllActions()[actionId].inputChannels[0].action);
|
||||||
|
|
||||||
// scale: sensitivity of input
|
// scale: sensitivity of input
|
||||||
print("Input channel scale: \n" + Controller.getAllActions()[5].inputChannels[0].scale);
|
print("Input channel scale: \n" + Controller.getAllActions()[actionId].inputChannels[0].scale);
|
||||||
|
|
||||||
// input and modifier: Inputs
|
// input and modifier: Inputs
|
||||||
print("Input channel input and modifier: \n" + Controller.getAllActions()[5].inputChannels[0].input + "\n" + Controller.getAllActions()[5].inputChannels[0].modifier + "\n");
|
print("Input channel input and modifier: \n" + Controller.getAllActions()[actionId].inputChannels[0].input + "\n" + Controller.getAllActions()[actionId].inputChannels[0].modifier + "\n");
|
||||||
|
|
||||||
|
|
||||||
// Each Input stores:
|
// Each Input stores:
|
||||||
// device: device of input
|
// device: device of input
|
||||||
print("Input device: \n" + Controller.getAllActions()[5].inputChannels[0].input.device);
|
print("Input device: \n" + Controller.getAllActions()[actionId].inputChannels[0].input.device);
|
||||||
|
|
||||||
// channel: channel of input
|
// channel: channel of input
|
||||||
print("Input channel: \n" + Controller.getAllActions()[5].inputChannels[0].input.channel);
|
print("Input channel: \n" + Controller.getAllActions()[actionId].inputChannels[0].input.channel);
|
||||||
|
|
||||||
// type: type of input (Unknown, Button, Axis, Joint)
|
// type: type of input (Unknown, Button, Axis, Joint)
|
||||||
print("Input type: \n" + Controller.getAllActions()[5].inputChannels[0].input.type);
|
print("Input type: \n" + Controller.getAllActions()[actionId].inputChannels[0].input.type);
|
||||||
|
|
||||||
// id: id of input
|
// id: id of input
|
||||||
print("Input id: \n" + Controller.getAllActions()[5].inputChannels[0].input.id + "\n");
|
print("Input id: \n" + Controller.getAllActions()[actionId].inputChannels[0].input.id + "\n");
|
||||||
|
|
||||||
|
|
||||||
// You can get the name of a device from its id
|
// You can get the name of a device from its id
|
||||||
print("Device 1 name: \n" + Controller.getDeviceName(Controller.getAllActions()[5].inputChannels[0].input.id));
|
print("Device 1 name: \n" + Controller.getDeviceName(Controller.getAllActions()[actionId].inputChannels[0].input.id));
|
||||||
|
|
||||||
// You can also get all of a devices input channels
|
// You can also get all of a devices input channels
|
||||||
print("Device 1's input channels: \n" + Controller.getAllInputsForDevice(1) + "\n");
|
print("Device 1's input channels: \n" + Controller.getAllInputsForDevice(1) + "\n");
|
||||||
|
@ -119,7 +133,7 @@ for (i = 0; i < availableInputs.length; i++) {
|
||||||
|
|
||||||
// You can modify key bindings by using these avaiable inputs
|
// You can modify key bindings by using these avaiable inputs
|
||||||
// This will replace e (up) with 6
|
// This will replace e (up) with 6
|
||||||
var e = Controller.getAllActions()[5].inputChannels[0];
|
var e = Controller.getAllActions()[actionId].inputChannels[0];
|
||||||
Controller.removeInputChannel(e);
|
Controller.removeInputChannel(e);
|
||||||
e.input = availableInputs[6].input;
|
e.input = availableInputs[6].input;
|
||||||
Controller.addInputChannel(e);
|
Controller.addInputChannel(e);
|
|
@ -38,7 +38,7 @@ var mouseLook = (function () {
|
||||||
keyboardID = 0;
|
keyboardID = 0;
|
||||||
|
|
||||||
function onKeyPressEvent(event) {
|
function onKeyPressEvent(event) {
|
||||||
if (event.text == 'M') {
|
if (event.text == 'm') {
|
||||||
active = !active;
|
active = !active;
|
||||||
updateMapping();
|
updateMapping();
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,8 +16,9 @@ var scriptURL = Script.resolvePath('wallTarget.js');
|
||||||
|
|
||||||
var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/target.fbx';
|
var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/target.fbx';
|
||||||
var COLLISION_HULL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/target_collision_hull.obj';
|
var COLLISION_HULL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/target_collision_hull.obj';
|
||||||
|
var MINIMUM_MOVE_LENGTH = 0.05;
|
||||||
|
var RESET_DISTANCE = 0.5;
|
||||||
|
|
||||||
var RESET_DISTANCE = 1;
|
|
||||||
var TARGET_USER_DATA_KEY = 'hifi-ping_pong_target';
|
var TARGET_USER_DATA_KEY = 'hifi-ping_pong_target';
|
||||||
var NUMBER_OF_TARGETS = 6;
|
var NUMBER_OF_TARGETS = 6;
|
||||||
var TARGETS_PER_ROW = 3;
|
var TARGETS_PER_ROW = 3;
|
||||||
|
@ -60,6 +61,8 @@ var targets = [];
|
||||||
|
|
||||||
var originalPositions = [];
|
var originalPositions = [];
|
||||||
|
|
||||||
|
var lastPositions = [];
|
||||||
|
|
||||||
function addTargets() {
|
function addTargets() {
|
||||||
var i;
|
var i;
|
||||||
var row = -1;
|
var row = -1;
|
||||||
|
@ -77,6 +80,7 @@ function addTargets() {
|
||||||
position.y = startPosition.y - (row * VERTICAL_SPACING);
|
position.y = startPosition.y - (row * VERTICAL_SPACING);
|
||||||
|
|
||||||
originalPositions.push(position);
|
originalPositions.push(position);
|
||||||
|
lastPositions.push(position);
|
||||||
|
|
||||||
var targetProperties = {
|
var targetProperties = {
|
||||||
name: 'Target',
|
name: 'Target',
|
||||||
|
@ -103,7 +107,11 @@ function testTargetDistanceFromStart() {
|
||||||
var distance = Vec3.subtract(originalPosition, currentPosition);
|
var distance = Vec3.subtract(originalPosition, currentPosition);
|
||||||
var length = Vec3.length(distance);
|
var length = Vec3.length(distance);
|
||||||
|
|
||||||
if (length > RESET_DISTANCE) {
|
var moving = Vec3.length(Vec3.subtract(currentPosition, lastPositions[index]));
|
||||||
|
|
||||||
|
lastPositions[index] = currentPosition;
|
||||||
|
|
||||||
|
if (length > RESET_DISTANCE && moving < MINIMUM_MOVE_LENGTH) {
|
||||||
|
|
||||||
Entities.deleteEntity(target);
|
Entities.deleteEntity(target);
|
||||||
|
|
||||||
|
@ -117,10 +125,16 @@ function testTargetDistanceFromStart() {
|
||||||
compoundShapeURL: COLLISION_HULL_URL,
|
compoundShapeURL: COLLISION_HULL_URL,
|
||||||
position: originalPositions[index],
|
position: originalPositions[index],
|
||||||
rotation: rotation,
|
rotation: rotation,
|
||||||
script: scriptURL
|
script: scriptURL,
|
||||||
|
userData: JSON.stringify({
|
||||||
|
grabbableKey: {
|
||||||
|
grabbable: false
|
||||||
|
}
|
||||||
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
targets[index] = Entities.addEntity(targetProperties);
|
targets[index] = Entities.addEntity(targetProperties);
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -142,7 +156,7 @@ function deleteTargets() {
|
||||||
}
|
}
|
||||||
|
|
||||||
Entities.deletingEntity.connect(deleteEntity);
|
Entities.deletingEntity.connect(deleteEntity);
|
||||||
var distanceCheckInterval = Script.setInterval(testTargetDistanceFromStart, 1000);
|
var distanceCheckInterval = Script.setInterval(testTargetDistanceFromStart, 500);
|
||||||
|
|
||||||
addTargets();
|
addTargets();
|
||||||
|
|
||||||
|
|
|
@ -98,9 +98,8 @@ endif()
|
||||||
# link required hifi libraries
|
# link required hifi libraries
|
||||||
link_hifi_libraries(shared octree environment gpu procedural model render fbx networking model-networking entities avatars
|
link_hifi_libraries(shared octree environment gpu procedural model render fbx networking model-networking entities avatars
|
||||||
audio audio-client animation script-engine physics
|
audio audio-client animation script-engine physics
|
||||||
render-utils entities-renderer ui auto-updater
|
render-utils entities-renderer ui auto-updater
|
||||||
plugins display-plugins input-plugins
|
controllers plugins display-plugins input-plugins )
|
||||||
controllers)
|
|
||||||
|
|
||||||
target_bullet()
|
target_bullet()
|
||||||
target_glew()
|
target_glew()
|
||||||
|
|
|
@ -60,7 +60,7 @@
|
||||||
#include <InfoView.h>
|
#include <InfoView.h>
|
||||||
#include <input-plugins/InputPlugin.h>
|
#include <input-plugins/InputPlugin.h>
|
||||||
#include <input-plugins/Joystick.h> // this should probably be removed
|
#include <input-plugins/Joystick.h> // this should probably be removed
|
||||||
#include <input-plugins/UserInputMapper.h>
|
#include <controllers/UserInputMapper.h>
|
||||||
#include <LogHandler.h>
|
#include <LogHandler.h>
|
||||||
#include <MainWindow.h>
|
#include <MainWindow.h>
|
||||||
#include <MessageDialog.h>
|
#include <MessageDialog.h>
|
||||||
|
@ -614,7 +614,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
||||||
|
|
||||||
// Setup the userInputMapper with the actions
|
// Setup the userInputMapper with the actions
|
||||||
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
||||||
connect(userInputMapper.data(), &UserInputMapper::actionEvent, &_controllerScriptingInterface, &AbstractControllerScriptingInterface::actionEvent);
|
connect(userInputMapper.data(), &UserInputMapper::actionEvent, &_controllerScriptingInterface, &ControllerScriptingInterface::actionEvent);
|
||||||
connect(userInputMapper.data(), &UserInputMapper::actionEvent, [this](int action, float state) {
|
connect(userInputMapper.data(), &UserInputMapper::actionEvent, [this](int action, float state) {
|
||||||
if (state) {
|
if (state) {
|
||||||
switch (action) {
|
switch (action) {
|
||||||
|
@ -1559,7 +1559,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
||||||
cursor->setIcon(Cursor::Icon::DEFAULT);
|
cursor->setIcon(Cursor::Icon::DEFAULT);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
resetSensors();
|
resetSensors(true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -2708,7 +2708,7 @@ void Application::update(float deltaTime) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dispatch input events
|
// Dispatch input events
|
||||||
_controllerScriptingInterface.updateInputControllers();
|
_controllerScriptingInterface.update();
|
||||||
|
|
||||||
// Transfer the user inputs to the driveKeys
|
// Transfer the user inputs to the driveKeys
|
||||||
myAvatar->clearDriveKeys();
|
myAvatar->clearDriveKeys();
|
||||||
|
@ -3581,7 +3581,7 @@ void Application::renderRearViewMirror(RenderArgs* renderArgs, const QRect& regi
|
||||||
renderArgs->_viewport = originalViewport;
|
renderArgs->_viewport = originalViewport;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::resetSensors() {
|
void Application::resetSensors(bool andReload) {
|
||||||
DependencyManager::get<Faceshift>()->reset();
|
DependencyManager::get<Faceshift>()->reset();
|
||||||
DependencyManager::get<DdeFaceTracker>()->reset();
|
DependencyManager::get<DdeFaceTracker>()->reset();
|
||||||
DependencyManager::get<EyeTracker>()->reset();
|
DependencyManager::get<EyeTracker>()->reset();
|
||||||
|
@ -3593,7 +3593,7 @@ void Application::resetSensors() {
|
||||||
QPoint windowCenter = mainWindow->geometry().center();
|
QPoint windowCenter = mainWindow->geometry().center();
|
||||||
_glWidget->cursor().setPos(currentScreen, windowCenter);
|
_glWidget->cursor().setPos(currentScreen, windowCenter);
|
||||||
|
|
||||||
getMyAvatar()->reset();
|
getMyAvatar()->reset(andReload);
|
||||||
|
|
||||||
QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(), "reset", Qt::QueuedConnection);
|
QMetaObject::invokeMethod(DependencyManager::get<AudioClient>().data(), "reset", Qt::QueuedConnection);
|
||||||
}
|
}
|
||||||
|
|
|
@ -161,7 +161,7 @@ public:
|
||||||
|
|
||||||
ToolWindow* getToolWindow() { return _toolWindow ; }
|
ToolWindow* getToolWindow() { return _toolWindow ; }
|
||||||
|
|
||||||
virtual AbstractControllerScriptingInterface* getControllerScriptingInterface() { return &_controllerScriptingInterface; }
|
virtual controller::ScriptingInterface* getControllerScriptingInterface() { return &_controllerScriptingInterface; }
|
||||||
virtual void registerScriptEngineWithApplicationServices(ScriptEngine* scriptEngine);
|
virtual void registerScriptEngineWithApplicationServices(ScriptEngine* scriptEngine);
|
||||||
|
|
||||||
QImage renderAvatarBillboard(RenderArgs* renderArgs);
|
QImage renderAvatarBillboard(RenderArgs* renderArgs);
|
||||||
|
@ -274,7 +274,7 @@ public slots:
|
||||||
void setRawAvatarUpdateThreading();
|
void setRawAvatarUpdateThreading();
|
||||||
void setRawAvatarUpdateThreading(bool isThreaded);
|
void setRawAvatarUpdateThreading(bool isThreaded);
|
||||||
|
|
||||||
void resetSensors();
|
void resetSensors(bool andReload = false);
|
||||||
void setActiveFaceTracker();
|
void setActiveFaceTracker();
|
||||||
|
|
||||||
#ifdef HAVE_IVIEWHMD
|
#ifdef HAVE_IVIEWHMD
|
||||||
|
|
|
@ -461,6 +461,7 @@ Menu::Menu() {
|
||||||
0, false,
|
0, false,
|
||||||
&ConnexionClient::getInstance(),
|
&ConnexionClient::getInstance(),
|
||||||
SLOT(toggleConnexion(bool)));
|
SLOT(toggleConnexion(bool)));
|
||||||
|
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::ComfortMode, 0, true);
|
||||||
|
|
||||||
MenuWrapper* handOptionsMenu = developerMenu->addMenu("Hands");
|
MenuWrapper* handOptionsMenu = developerMenu->addMenu("Hands");
|
||||||
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false);
|
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false);
|
||||||
|
|
|
@ -159,6 +159,7 @@ namespace MenuOption {
|
||||||
const QString CenterPlayerInView = "Center Player In View";
|
const QString CenterPlayerInView = "Center Player In View";
|
||||||
const QString Chat = "Chat...";
|
const QString Chat = "Chat...";
|
||||||
const QString Collisions = "Collisions";
|
const QString Collisions = "Collisions";
|
||||||
|
const QString ComfortMode = "Comfort Mode";
|
||||||
const QString Connexion = "Activate 3D Connexion Devices";
|
const QString Connexion = "Activate 3D Connexion Devices";
|
||||||
const QString Console = "Console...";
|
const QString Console = "Console...";
|
||||||
const QString ControlWithSpeech = "Control With Speech";
|
const QString ControlWithSpeech = "Control With Speech";
|
||||||
|
|
|
@ -144,7 +144,7 @@ void PluginContainerProxy::unsetFullscreen(const QScreen* avoid) {
|
||||||
|
|
||||||
void PluginContainerProxy::requestReset() {
|
void PluginContainerProxy::requestReset() {
|
||||||
// We could signal qApp to sequence this, but it turns out that requestReset is only used from within the main thread anyway.
|
// We could signal qApp to sequence this, but it turns out that requestReset is only used from within the main thread anyway.
|
||||||
qApp->resetSensors();
|
qApp->resetSensors(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PluginContainerProxy::showDisplayPluginsTools() {
|
void PluginContainerProxy::showDisplayPluginsTools() {
|
||||||
|
|
|
@ -140,16 +140,18 @@ QByteArray MyAvatar::toByteArray(bool cullSmallChanges, bool sendAll) {
|
||||||
return AvatarData::toByteArray(cullSmallChanges, sendAll);
|
return AvatarData::toByteArray(cullSmallChanges, sendAll);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAvatar::reset() {
|
void MyAvatar::reset(bool andReload) {
|
||||||
// Gather animation mode...
|
// Gather animation mode...
|
||||||
// This should be simpler when we have only graph animations always on.
|
// This should be simpler when we have only graph animations always on.
|
||||||
bool isRig = _rig->getEnableRig();
|
bool isRig = _rig->getEnableRig();
|
||||||
// seting rig animation to true, below, will clear the graph animation menu item, so grab it now.
|
// seting rig animation to true, below, will clear the graph animation menu item, so grab it now.
|
||||||
bool isGraph = _rig->getEnableAnimGraph() || Menu::getInstance()->isOptionChecked(MenuOption::EnableAnimGraph);
|
bool isGraph = _rig->getEnableAnimGraph() || Menu::getInstance()->isOptionChecked(MenuOption::EnableAnimGraph);
|
||||||
// ... and get to sane configuration where other activity won't bother us.
|
// ... and get to sane configuration where other activity won't bother us.
|
||||||
qApp->setRawAvatarUpdateThreading(false);
|
if (andReload) {
|
||||||
_rig->disableHands = true;
|
qApp->setRawAvatarUpdateThreading(false);
|
||||||
setEnableRigAnimations(true);
|
_rig->disableHands = true;
|
||||||
|
setEnableRigAnimations(true);
|
||||||
|
}
|
||||||
|
|
||||||
// Reset dynamic state.
|
// Reset dynamic state.
|
||||||
_wasPushing = _isPushing = _isBraking = _billboardValid = _straighteningLean = false;
|
_wasPushing = _isPushing = _isBraking = _billboardValid = _straighteningLean = false;
|
||||||
|
@ -158,32 +160,34 @@ void MyAvatar::reset() {
|
||||||
_targetVelocity = glm::vec3(0.0f);
|
_targetVelocity = glm::vec3(0.0f);
|
||||||
setThrust(glm::vec3(0.0f));
|
setThrust(glm::vec3(0.0f));
|
||||||
|
|
||||||
// Get fresh data, in case we're really slow and out of wack.
|
if (andReload) {
|
||||||
_hmdSensorMatrix = qApp->getHMDSensorPose();
|
// Get fresh data, in case we're really slow and out of wack.
|
||||||
_hmdSensorPosition = extractTranslation(_hmdSensorMatrix);
|
_hmdSensorMatrix = qApp->getHMDSensorPose();
|
||||||
_hmdSensorOrientation = glm::quat_cast(_hmdSensorMatrix);
|
_hmdSensorPosition = extractTranslation(_hmdSensorMatrix);
|
||||||
|
_hmdSensorOrientation = glm::quat_cast(_hmdSensorMatrix);
|
||||||
|
|
||||||
// Reset body position/orientation under the head.
|
// Reset body position/orientation under the head.
|
||||||
auto newBodySensorMatrix = deriveBodyFromHMDSensor(); // Based on current cached HMD position/rotation..
|
auto newBodySensorMatrix = deriveBodyFromHMDSensor(); // Based on current cached HMD position/rotation..
|
||||||
auto worldBodyMatrix = _sensorToWorldMatrix * newBodySensorMatrix;
|
auto worldBodyMatrix = _sensorToWorldMatrix * newBodySensorMatrix;
|
||||||
glm::vec3 worldBodyPos = extractTranslation(worldBodyMatrix);
|
glm::vec3 worldBodyPos = extractTranslation(worldBodyMatrix);
|
||||||
glm::quat worldBodyRot = glm::normalize(glm::quat_cast(worldBodyMatrix));
|
glm::quat worldBodyRot = glm::normalize(glm::quat_cast(worldBodyMatrix));
|
||||||
|
|
||||||
// FIXME: Hack to retain the previous behavior wrt height.
|
// FIXME: Hack to retain the previous behavior wrt height.
|
||||||
// I'd like to make the body match head height, but that will have to wait for separate PR.
|
// I'd like to make the body match head height, but that will have to wait for separate PR.
|
||||||
worldBodyPos.y = getPosition().y;
|
worldBodyPos.y = getPosition().y;
|
||||||
|
|
||||||
setPosition(worldBodyPos);
|
setPosition(worldBodyPos);
|
||||||
setOrientation(worldBodyRot);
|
setOrientation(worldBodyRot);
|
||||||
// If there is any discrepency between positioning and the head (as there is in initial deriveBodyFromHMDSensor),
|
// If there is any discrepency between positioning and the head (as there is in initial deriveBodyFromHMDSensor),
|
||||||
// we can make that right by setting _bodySensorMatrix = newBodySensorMatrix.
|
// we can make that right by setting _bodySensorMatrix = newBodySensorMatrix.
|
||||||
// However, doing so will make the head want to point to the previous body orientation, as cached above.
|
// However, doing so will make the head want to point to the previous body orientation, as cached above.
|
||||||
//_bodySensorMatrix = newBodySensorMatrix;
|
//_bodySensorMatrix = newBodySensorMatrix;
|
||||||
//updateSensorToWorldMatrix(); // Uses updated position/orientation and _bodySensorMatrix changes
|
//updateSensorToWorldMatrix(); // Uses updated position/orientation and _bodySensorMatrix changes
|
||||||
|
|
||||||
_skeletonModel.simulate(0.1f); // non-zero
|
_skeletonModel.simulate(0.1f); // non-zero
|
||||||
setEnableRigAnimations(false);
|
setEnableRigAnimations(false);
|
||||||
_skeletonModel.simulate(0.1f);
|
_skeletonModel.simulate(0.1f);
|
||||||
|
}
|
||||||
if (isRig) {
|
if (isRig) {
|
||||||
setEnableRigAnimations(true);
|
setEnableRigAnimations(true);
|
||||||
Menu::getInstance()->setIsOptionChecked(MenuOption::EnableRigAnimations, true);
|
Menu::getInstance()->setIsOptionChecked(MenuOption::EnableRigAnimations, true);
|
||||||
|
@ -191,8 +195,10 @@ void MyAvatar::reset() {
|
||||||
setEnableAnimGraph(true);
|
setEnableAnimGraph(true);
|
||||||
Menu::getInstance()->setIsOptionChecked(MenuOption::EnableAnimGraph, true);
|
Menu::getInstance()->setIsOptionChecked(MenuOption::EnableAnimGraph, true);
|
||||||
}
|
}
|
||||||
_rig->disableHands = false;
|
if (andReload) {
|
||||||
qApp->setRawAvatarUpdateThreading();
|
_rig->disableHands = false;
|
||||||
|
qApp->setRawAvatarUpdateThreading();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAvatar::update(float deltaTime) {
|
void MyAvatar::update(float deltaTime) {
|
||||||
|
@ -1514,33 +1520,69 @@ bool MyAvatar::shouldRenderHead(const RenderArgs* renderArgs) const {
|
||||||
|
|
||||||
void MyAvatar::updateOrientation(float deltaTime) {
|
void MyAvatar::updateOrientation(float deltaTime) {
|
||||||
// Smoothly rotate body with arrow keys
|
// Smoothly rotate body with arrow keys
|
||||||
float targetSpeed = (_driveKeys[ROT_LEFT] - _driveKeys[ROT_RIGHT]) * YAW_SPEED;
|
float targetSpeed = 0.0f;
|
||||||
if (targetSpeed != 0.0f) {
|
|
||||||
const float ROTATION_RAMP_TIMESCALE = 0.1f;
|
// FIXME - this comfort mode code is a total hack, remove it when we have new input mapping
|
||||||
float blend = deltaTime / ROTATION_RAMP_TIMESCALE;
|
bool isComfortMode = Menu::getInstance()->isOptionChecked(MenuOption::ComfortMode);
|
||||||
if (blend > 1.0f) {
|
bool isHMDMode = qApp->getAvatarUpdater()->isHMDMode();
|
||||||
blend = 1.0f;
|
|
||||||
}
|
if (!isHMDMode || !isComfortMode) {
|
||||||
_bodyYawDelta = (1.0f - blend) * _bodyYawDelta + blend * targetSpeed;
|
targetSpeed = (_driveKeys[ROT_LEFT] - _driveKeys[ROT_RIGHT]) * YAW_SPEED;
|
||||||
} else if (_bodyYawDelta != 0.0f) {
|
|
||||||
// attenuate body rotation speed
|
if (targetSpeed != 0.0f) {
|
||||||
const float ROTATION_DECAY_TIMESCALE = 0.05f;
|
const float ROTATION_RAMP_TIMESCALE = 0.1f;
|
||||||
float attenuation = 1.0f - deltaTime / ROTATION_DECAY_TIMESCALE;
|
float blend = deltaTime / ROTATION_RAMP_TIMESCALE;
|
||||||
if (attenuation < 0.0f) {
|
if (blend > 1.0f) {
|
||||||
attenuation = 0.0f;
|
blend = 1.0f;
|
||||||
}
|
}
|
||||||
_bodyYawDelta *= attenuation;
|
_bodyYawDelta = (1.0f - blend) * _bodyYawDelta + blend * targetSpeed;
|
||||||
|
} else if (_bodyYawDelta != 0.0f) {
|
||||||
|
// attenuate body rotation speed
|
||||||
|
const float ROTATION_DECAY_TIMESCALE = 0.05f;
|
||||||
|
float attenuation = 1.0f - deltaTime / ROTATION_DECAY_TIMESCALE;
|
||||||
|
if (attenuation < 0.0f) {
|
||||||
|
attenuation = 0.0f;
|
||||||
|
}
|
||||||
|
_bodyYawDelta *= attenuation;
|
||||||
|
|
||||||
|
float MINIMUM_ROTATION_RATE = 2.0f;
|
||||||
|
if (fabsf(_bodyYawDelta) < MINIMUM_ROTATION_RATE) {
|
||||||
|
_bodyYawDelta = 0.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// update body orientation by movement inputs
|
||||||
|
setOrientation(getOrientation() *
|
||||||
|
glm::quat(glm::radians(glm::vec3(0.0f, _bodyYawDelta * deltaTime, 0.0f))));
|
||||||
|
|
||||||
|
} else {
|
||||||
|
// Comfort Mode: If you press any of the left/right rotation drive keys or input, you'll
|
||||||
|
// get an instantaneous 15 degree turn. If you keep holding the key down you'll get another
|
||||||
|
// snap turn every half second.
|
||||||
|
_bodyYawDelta = 0.0f;
|
||||||
|
|
||||||
|
static quint64 lastPulse = 0;
|
||||||
|
quint64 now = usecTimestampNow();
|
||||||
|
quint64 COMFORT_MODE_PULSE_TIMING = USECS_PER_SECOND / 2; // turn once per half second
|
||||||
|
|
||||||
|
float driveLeft = _driveKeys[ROT_LEFT];
|
||||||
|
float driveRight= _driveKeys[ROT_RIGHT];
|
||||||
|
|
||||||
|
if ((driveLeft != 0.0f || driveRight != 0.0f) && (now - lastPulse > COMFORT_MODE_PULSE_TIMING)) {
|
||||||
|
lastPulse = now;
|
||||||
|
|
||||||
|
const float SNAP_TURN_DELTA = 15.0f; // degrees
|
||||||
|
float direction = (driveLeft - driveRight) < 0.0f ? -1.0f : 1.0f;
|
||||||
|
float turnAmount = direction * SNAP_TURN_DELTA;
|
||||||
|
|
||||||
|
// update body orientation by movement inputs
|
||||||
|
setOrientation(getOrientation() *
|
||||||
|
glm::quat(glm::radians(glm::vec3(0.0f, turnAmount, 0.0f))));
|
||||||
|
|
||||||
float MINIMUM_ROTATION_RATE = 2.0f;
|
|
||||||
if (fabsf(_bodyYawDelta) < MINIMUM_ROTATION_RATE) {
|
|
||||||
_bodyYawDelta = 0.0f;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
getHead()->setBasePitch(getHead()->getBasePitch() + (_driveKeys[ROT_UP] - _driveKeys[ROT_DOWN]) * PITCH_SPEED * deltaTime);
|
getHead()->setBasePitch(getHead()->getBasePitch() + (_driveKeys[ROT_UP] - _driveKeys[ROT_DOWN]) * PITCH_SPEED * deltaTime);
|
||||||
// update body orientation by movement inputs
|
|
||||||
setOrientation(getOrientation() *
|
|
||||||
glm::quat(glm::radians(glm::vec3(0.0f, _bodyYawDelta * deltaTime, 0.0f))));
|
|
||||||
|
|
||||||
if (qApp->getAvatarUpdater()->isHMDMode()) {
|
if (qApp->getAvatarUpdater()->isHMDMode()) {
|
||||||
glm::quat orientation = glm::quat_cast(getSensorToWorldMatrix()) * getHMDSensorOrientation();
|
glm::quat orientation = glm::quat_cast(getSensorToWorldMatrix()) * getHMDSensorOrientation();
|
||||||
|
|
|
@ -58,7 +58,7 @@ public:
|
||||||
AudioListenerMode getAudioListenerModeCamera() const { return FROM_CAMERA; }
|
AudioListenerMode getAudioListenerModeCamera() const { return FROM_CAMERA; }
|
||||||
AudioListenerMode getAudioListenerModeCustom() const { return CUSTOM; }
|
AudioListenerMode getAudioListenerModeCustom() const { return CUSTOM; }
|
||||||
|
|
||||||
void reset();
|
void reset(bool andReload = false);
|
||||||
void update(float deltaTime);
|
void update(float deltaTime);
|
||||||
void preRender(RenderArgs* renderArgs);
|
void preRender(RenderArgs* renderArgs);
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
#include <QObject>
|
#include <QObject>
|
||||||
#include <QLibrary>
|
#include <QLibrary>
|
||||||
#include <input-plugins/UserInputMapper.h>
|
#include <controllers/UserInputMapper.h>
|
||||||
|
|
||||||
#include "InterfaceLogging.h"
|
#include "InterfaceLogging.h"
|
||||||
|
|
||||||
|
|
|
@ -9,21 +9,20 @@
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include "ControllerScriptingInterface.h"
|
||||||
|
|
||||||
#include <avatar/AvatarManager.h>
|
#include <avatar/AvatarManager.h>
|
||||||
#include <avatar/MyAvatar.h>
|
#include <avatar/MyAvatar.h>
|
||||||
#include <HandData.h>
|
#include <HandData.h>
|
||||||
#include <HFBackEvent.h>
|
#include <HFBackEvent.h>
|
||||||
|
#include <plugins/PluginManager.h>
|
||||||
#include <controllers/NewControllerScriptingInterface.h>
|
|
||||||
|
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "devices/MotionTracker.h"
|
#include "devices/MotionTracker.h"
|
||||||
#include "ControllerScriptingInterface.h"
|
|
||||||
|
|
||||||
// TODO: this needs to be removed, as well as any related controller-specific information
|
// TODO: this needs to be removed, as well as any related controller-specific information
|
||||||
#include <input-plugins/SixenseManager.h>
|
#include <input-plugins/SixenseManager.h>
|
||||||
|
|
||||||
|
|
||||||
ControllerScriptingInterface::ControllerScriptingInterface() :
|
ControllerScriptingInterface::ControllerScriptingInterface() :
|
||||||
_mouseCaptured(false),
|
_mouseCaptured(false),
|
||||||
_touchCaptured(false),
|
_touchCaptured(false),
|
||||||
|
@ -34,7 +33,6 @@ ControllerScriptingInterface::ControllerScriptingInterface() :
|
||||||
}
|
}
|
||||||
|
|
||||||
ControllerScriptingInterface::~ControllerScriptingInterface() {
|
ControllerScriptingInterface::~ControllerScriptingInterface() {
|
||||||
delete _newControllerScriptingInterface;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -118,7 +116,7 @@ void inputPairFromScriptValue(const QScriptValue& object, UserInputMapper::Input
|
||||||
inputPair.second = QString(object.property("inputName").toVariant().toString());
|
inputPair.second = QString(object.property("inputName").toVariant().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControllerScriptingInterface::registerControllerTypes(ScriptEngine* engine) {
|
void ControllerScriptingInterface::registerControllerTypes(QScriptEngine* engine) {
|
||||||
qScriptRegisterSequenceMetaType<QVector<UserInputMapper::Action> >(engine);
|
qScriptRegisterSequenceMetaType<QVector<UserInputMapper::Action> >(engine);
|
||||||
qScriptRegisterSequenceMetaType<QVector<UserInputMapper::InputChannel> >(engine);
|
qScriptRegisterSequenceMetaType<QVector<UserInputMapper::InputChannel> >(engine);
|
||||||
qScriptRegisterSequenceMetaType<QVector<UserInputMapper::InputPair> >(engine);
|
qScriptRegisterSequenceMetaType<QVector<UserInputMapper::InputPair> >(engine);
|
||||||
|
@ -126,13 +124,6 @@ void ControllerScriptingInterface::registerControllerTypes(ScriptEngine* engine)
|
||||||
qScriptRegisterMetaType(engine, inputChannelToScriptValue, inputChannelFromScriptValue);
|
qScriptRegisterMetaType(engine, inputChannelToScriptValue, inputChannelFromScriptValue);
|
||||||
qScriptRegisterMetaType(engine, inputToScriptValue, inputFromScriptValue);
|
qScriptRegisterMetaType(engine, inputToScriptValue, inputFromScriptValue);
|
||||||
qScriptRegisterMetaType(engine, inputPairToScriptValue, inputPairFromScriptValue);
|
qScriptRegisterMetaType(engine, inputPairToScriptValue, inputPairFromScriptValue);
|
||||||
|
|
||||||
wireUpControllers(engine);
|
|
||||||
|
|
||||||
// hack in the new controller scripting interface...
|
|
||||||
_newControllerScriptingInterface = new controller::NewControllerScriptingInterface();
|
|
||||||
engine->registerGlobalObject("NewControllers", _newControllerScriptingInterface);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControllerScriptingInterface::handleMetaEvent(HFMetaEvent* event) {
|
void ControllerScriptingInterface::handleMetaEvent(HFMetaEvent* event) {
|
||||||
|
@ -192,6 +183,7 @@ const PalmData* ControllerScriptingInterface::getActivePalm(int palmIndex) const
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
bool ControllerScriptingInterface::isPrimaryButtonPressed() const {
|
bool ControllerScriptingInterface::isPrimaryButtonPressed() const {
|
||||||
const PalmData* primaryPalm = getPrimaryPalm();
|
const PalmData* primaryPalm = getPrimaryPalm();
|
||||||
if (primaryPalm) {
|
if (primaryPalm) {
|
||||||
|
@ -345,6 +337,7 @@ glm::vec3 ControllerScriptingInterface::getSpatialControlNormal(int controlIndex
|
||||||
}
|
}
|
||||||
return glm::vec3(0); // bad index
|
return glm::vec3(0); // bad index
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
bool ControllerScriptingInterface::isKeyCaptured(QKeyEvent* event) const {
|
bool ControllerScriptingInterface::isKeyCaptured(QKeyEvent* event) const {
|
||||||
return isKeyCaptured(KeyEvent(*event));
|
return isKeyCaptured(KeyEvent(*event));
|
||||||
|
@ -395,97 +388,64 @@ glm::vec2 ControllerScriptingInterface::getViewportDimensions() const {
|
||||||
return qApp->getUiSize();
|
return qApp->getUiSize();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString ControllerScriptingInterface::sanatizeName(const QString& name) {
|
controller::InputController::Pointer ControllerScriptingInterface::createInputController(const QString& deviceName, const QString& tracker) {
|
||||||
QString cleanName { name };
|
|
||||||
cleanName.remove(QRegularExpression{"[\\(\\)\\.\\s]"});
|
|
||||||
return cleanName;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ControllerScriptingInterface::wireUpControllers(ScriptEngine* engine) {
|
|
||||||
|
|
||||||
// Controller.Standard.*
|
|
||||||
auto standardDevice = DependencyManager::get<UserInputMapper>()->getStandardDevice();
|
|
||||||
if (standardDevice) {
|
|
||||||
auto deviceName = sanatizeName(standardDevice->getName());
|
|
||||||
auto deviceInputs = standardDevice->getAvailabeInputs();
|
|
||||||
for (const auto& inputMapping : deviceInputs) {
|
|
||||||
auto input = inputMapping.first;
|
|
||||||
auto inputName = sanatizeName(inputMapping.second);
|
|
||||||
QString deviceInputName{ "Controller." + deviceName + "." + inputName };
|
|
||||||
engine->registerValue(deviceInputName, input.getID());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Controller.Hardware.*
|
|
||||||
auto devices = DependencyManager::get<UserInputMapper>()->getDevices();
|
|
||||||
for(const auto& deviceMapping : devices) {
|
|
||||||
auto device = deviceMapping.second.get();
|
|
||||||
auto deviceName = sanatizeName(device->getName());
|
|
||||||
auto deviceInputs = device->getAvailabeInputs();
|
|
||||||
for (const auto& inputMapping : deviceInputs) {
|
|
||||||
auto input = inputMapping.first;
|
|
||||||
auto inputName = sanatizeName(inputMapping.second);
|
|
||||||
QString deviceInputName { "Controller.Hardware." + deviceName + "." + inputName };
|
|
||||||
engine->registerValue(deviceInputName, input.getID());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Controller.Actions.*
|
|
||||||
auto actionNames = DependencyManager::get<UserInputMapper>()->getActionNames();
|
|
||||||
int actionNumber = 0;
|
|
||||||
for (const auto& actionName : actionNames) {
|
|
||||||
QString safeActionName { "Controller.Actions." + sanatizeName(actionName) };
|
|
||||||
engine->registerValue(safeActionName, actionNumber);
|
|
||||||
actionNumber++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
AbstractInputController* ControllerScriptingInterface::createInputController(const QString& deviceName, const QString& tracker) {
|
|
||||||
// This is where we retreive the Device Tracker category and then the sub tracker within it
|
// This is where we retreive the Device Tracker category and then the sub tracker within it
|
||||||
//TODO C++11 auto icIt = _inputControllers.find(0);
|
auto icIt = _inputControllers.find(0);
|
||||||
InputControllerMap::iterator icIt = _inputControllers.find(0);
|
|
||||||
|
|
||||||
if (icIt != _inputControllers.end()) {
|
if (icIt != _inputControllers.end()) {
|
||||||
return (*icIt).second;
|
return (*icIt).second;
|
||||||
} else {
|
}
|
||||||
|
|
||||||
// Look for device
|
|
||||||
DeviceTracker::ID deviceID = DeviceTracker::getDeviceID(deviceName.toStdString());
|
|
||||||
if (deviceID < 0) {
|
|
||||||
deviceID = 0;
|
|
||||||
}
|
|
||||||
// TODO in this current implementation, we just pick the device assuming there is one (normally the Leapmotion)
|
|
||||||
// in the near future we need to change that to a real mapping between the devices and the deviceName
|
|
||||||
// ALso we need to expand the spec so we can fall back on the "default" controller per categories
|
|
||||||
|
|
||||||
if (deviceID >= 0) {
|
// Look for device
|
||||||
// TODO here again the assumption it's the LeapMotion and so it's a MOtionTracker, this would need to be changed to support different types of devices
|
DeviceTracker::ID deviceID = DeviceTracker::getDeviceID(deviceName.toStdString());
|
||||||
MotionTracker* motionTracker = dynamic_cast< MotionTracker* > (DeviceTracker::getDevice(deviceID));
|
if (deviceID < 0) {
|
||||||
if (motionTracker) {
|
deviceID = 0;
|
||||||
MotionTracker::Index trackerID = motionTracker->findJointIndex(tracker.toStdString());
|
}
|
||||||
if (trackerID >= 0) {
|
// TODO in this current implementation, we just pick the device assuming there is one (normally the Leapmotion)
|
||||||
AbstractInputController* inputController = new InputController(deviceID, trackerID, this);
|
// in the near future we need to change that to a real mapping between the devices and the deviceName
|
||||||
|
// ALso we need to expand the spec so we can fall back on the "default" controller per categories
|
||||||
|
|
||||||
_inputControllers.insert(InputControllerMap::value_type(inputController->getKey(), inputController));
|
if (deviceID >= 0) {
|
||||||
|
// TODO here again the assumption it's the LeapMotion and so it's a MOtionTracker, this would need to be changed to support different types of devices
|
||||||
return inputController;
|
MotionTracker* motionTracker = dynamic_cast< MotionTracker* > (DeviceTracker::getDevice(deviceID));
|
||||||
}
|
if (motionTracker) {
|
||||||
|
MotionTracker::Index trackerID = motionTracker->findJointIndex(tracker.toStdString());
|
||||||
|
if (trackerID >= 0) {
|
||||||
|
controller::InputController::Pointer inputController = std::make_shared<InputController>(deviceID, trackerID, this);
|
||||||
|
controller::InputController::Key key = inputController->getKey();
|
||||||
|
_inputControllers.insert(InputControllerMap::value_type(inputController->getKey(), inputController));
|
||||||
|
return inputController;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return controller::InputController::Pointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControllerScriptingInterface::releaseInputController(AbstractInputController* input) {
|
void ControllerScriptingInterface::releaseInputController(controller::InputController::Pointer input) {
|
||||||
_inputControllers.erase(input->getKey());
|
_inputControllers.erase(input->getKey());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ControllerScriptingInterface::updateInputControllers() {
|
void ControllerScriptingInterface::update() {
|
||||||
//TODO C++11 for (auto it = _inputControllers.begin(); it != _inputControllers.end(); it++) {
|
static float last = secTimestampNow();
|
||||||
for (InputControllerMap::iterator it = _inputControllers.begin(); it != _inputControllers.end(); it++) {
|
float now = secTimestampNow();
|
||||||
(*it).second->update();
|
float delta = now - last;
|
||||||
|
last = now;
|
||||||
|
|
||||||
|
for(auto inputPlugin : PluginManager::getInstance()->getInputPlugins()) {
|
||||||
|
if (inputPlugin->isActive()) {
|
||||||
|
inputPlugin->pluginUpdate(delta, false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
||||||
|
userInputMapper->update(delta);
|
||||||
|
|
||||||
|
for (auto entry : _inputControllers) {
|
||||||
|
entry.second->update();
|
||||||
|
}
|
||||||
|
|
||||||
|
controller::ScriptingInterface::update();
|
||||||
}
|
}
|
||||||
|
|
||||||
QVector<UserInputMapper::Action> ControllerScriptingInterface::getAllActions() {
|
QVector<UserInputMapper::Action> ControllerScriptingInterface::getAllActions() {
|
||||||
|
@ -545,7 +505,6 @@ QVector<QString> ControllerScriptingInterface::getActionNames() const {
|
||||||
}
|
}
|
||||||
|
|
||||||
InputController::InputController(int deviceTrackerId, int subTrackerId, QObject* parent) :
|
InputController::InputController(int deviceTrackerId, int subTrackerId, QObject* parent) :
|
||||||
AbstractInputController(),
|
|
||||||
_deviceTrackerId(deviceTrackerId),
|
_deviceTrackerId(deviceTrackerId),
|
||||||
_subTrackerId(subTrackerId),
|
_subTrackerId(subTrackerId),
|
||||||
_isActive(false)
|
_isActive(false)
|
||||||
|
@ -568,7 +527,7 @@ void InputController::update() {
|
||||||
joint->getLocFrame().getRotation(_eventCache.locRotation);
|
joint->getLocFrame().getRotation(_eventCache.locRotation);
|
||||||
|
|
||||||
_isActive = true;
|
_isActive = true;
|
||||||
emit spatialEvent(_eventCache);
|
//emit spatialEvent(_eventCache);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -580,3 +539,19 @@ const unsigned int INPUTCONTROLLER_KEY_DEVICE_MASK = 16;
|
||||||
InputController::Key InputController::getKey() const {
|
InputController::Key InputController::getKey() const {
|
||||||
return (((_deviceTrackerId & INPUTCONTROLLER_KEY_DEVICE_MASK) << INPUTCONTROLLER_KEY_DEVICE_OFFSET) | _subTrackerId);
|
return (((_deviceTrackerId & INPUTCONTROLLER_KEY_DEVICE_MASK) << INPUTCONTROLLER_KEY_DEVICE_OFFSET) | _subTrackerId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ControllerScriptingInterface::emitKeyPressEvent(QKeyEvent* event) { emit keyPressEvent(KeyEvent(*event)); }
|
||||||
|
void ControllerScriptingInterface::emitKeyReleaseEvent(QKeyEvent* event) { emit keyReleaseEvent(KeyEvent(*event)); }
|
||||||
|
|
||||||
|
void ControllerScriptingInterface::emitMouseMoveEvent(QMouseEvent* event, unsigned int deviceID) { emit mouseMoveEvent(MouseEvent(*event, deviceID)); }
|
||||||
|
void ControllerScriptingInterface::emitMousePressEvent(QMouseEvent* event, unsigned int deviceID) { emit mousePressEvent(MouseEvent(*event, deviceID)); }
|
||||||
|
void ControllerScriptingInterface::emitMouseDoublePressEvent(QMouseEvent* event, unsigned int deviceID) { emit mouseDoublePressEvent(MouseEvent(*event, deviceID)); }
|
||||||
|
void ControllerScriptingInterface::emitMouseReleaseEvent(QMouseEvent* event, unsigned int deviceID) { emit mouseReleaseEvent(MouseEvent(*event, deviceID)); }
|
||||||
|
|
||||||
|
void ControllerScriptingInterface::emitTouchBeginEvent(const TouchEvent& event) { emit touchBeginEvent(event); }
|
||||||
|
void ControllerScriptingInterface::emitTouchEndEvent(const TouchEvent& event) { emit touchEndEvent(event); }
|
||||||
|
void ControllerScriptingInterface::emitTouchUpdateEvent(const TouchEvent& event) { emit touchUpdateEvent(event); }
|
||||||
|
|
||||||
|
void ControllerScriptingInterface::emitWheelEvent(QWheelEvent* event) { emit wheelEvent(*event); }
|
||||||
|
|
||||||
|
|
|
@ -14,15 +14,20 @@
|
||||||
|
|
||||||
#include <QtCore/QObject>
|
#include <QtCore/QObject>
|
||||||
|
|
||||||
#include <input-plugins/UserInputMapper.h>
|
#include <controllers/UserInputMapper.h>
|
||||||
|
#include <controllers/ScriptingInterface.h>
|
||||||
|
|
||||||
|
#include <HFActionEvent.h>
|
||||||
|
#include <KeyEvent.h>
|
||||||
|
#include <MouseEvent.h>
|
||||||
|
#include <SpatialEvent.h>
|
||||||
|
#include <TouchEvent.h>
|
||||||
|
#include <WheelEvent.h>
|
||||||
|
class ScriptEngine;
|
||||||
|
|
||||||
#include <AbstractControllerScriptingInterface.h>
|
|
||||||
class PalmData;
|
class PalmData;
|
||||||
namespace controller {
|
|
||||||
class NewControllerScriptingInterface;
|
|
||||||
}
|
|
||||||
|
|
||||||
class InputController : public AbstractInputController {
|
class InputController : public controller::InputController {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
@ -53,30 +58,53 @@ signals:
|
||||||
|
|
||||||
|
|
||||||
/// handles scripting of input controller commands from JS
|
/// handles scripting of input controller commands from JS
|
||||||
class ControllerScriptingInterface : public AbstractControllerScriptingInterface {
|
class ControllerScriptingInterface : public controller::ScriptingInterface {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ControllerScriptingInterface();
|
ControllerScriptingInterface();
|
||||||
~ControllerScriptingInterface();
|
~ControllerScriptingInterface();
|
||||||
|
|
||||||
virtual void registerControllerTypes(ScriptEngine* engine);
|
Q_INVOKABLE QVector<UserInputMapper::Action> getAllActions();
|
||||||
|
|
||||||
|
Q_INVOKABLE bool addInputChannel(UserInputMapper::InputChannel inputChannel);
|
||||||
|
Q_INVOKABLE bool removeInputChannel(UserInputMapper::InputChannel inputChannel);
|
||||||
|
Q_INVOKABLE QVector<UserInputMapper::InputChannel> getInputChannelsForAction(UserInputMapper::Action action);
|
||||||
|
|
||||||
|
Q_INVOKABLE QVector<UserInputMapper::InputPair> getAvailableInputs(unsigned int device);
|
||||||
|
Q_INVOKABLE QVector<UserInputMapper::InputChannel> getAllInputsForDevice(unsigned int device);
|
||||||
|
|
||||||
|
Q_INVOKABLE QString getDeviceName(unsigned int device);
|
||||||
|
|
||||||
|
Q_INVOKABLE float getActionValue(int action);
|
||||||
|
|
||||||
|
Q_INVOKABLE void resetDevice(unsigned int device);
|
||||||
|
Q_INVOKABLE void resetAllDeviceBindings();
|
||||||
|
Q_INVOKABLE int findDevice(QString name);
|
||||||
|
Q_INVOKABLE QVector<QString> getDeviceNames();
|
||||||
|
|
||||||
|
Q_INVOKABLE int findAction(QString actionName);
|
||||||
|
Q_INVOKABLE QVector<QString> getActionNames() const;
|
||||||
|
|
||||||
|
|
||||||
|
virtual void registerControllerTypes(QScriptEngine* engine);
|
||||||
|
|
||||||
void emitKeyPressEvent(QKeyEvent* event) { emit keyPressEvent(KeyEvent(*event)); }
|
void emitKeyPressEvent(QKeyEvent* event);
|
||||||
void emitKeyReleaseEvent(QKeyEvent* event) { emit keyReleaseEvent(KeyEvent(*event)); }
|
void emitKeyReleaseEvent(QKeyEvent* event);
|
||||||
|
|
||||||
void handleMetaEvent(HFMetaEvent* event);
|
void handleMetaEvent(HFMetaEvent* event);
|
||||||
|
|
||||||
void emitMouseMoveEvent(QMouseEvent* event, unsigned int deviceID = 0) { emit mouseMoveEvent(MouseEvent(*event, deviceID)); }
|
void emitMouseMoveEvent(QMouseEvent* event, unsigned int deviceID = 0);
|
||||||
void emitMousePressEvent(QMouseEvent* event, unsigned int deviceID = 0) { emit mousePressEvent(MouseEvent(*event, deviceID)); }
|
void emitMousePressEvent(QMouseEvent* event, unsigned int deviceID = 0);
|
||||||
void emitMouseDoublePressEvent(QMouseEvent* event, unsigned int deviceID = 0) { emit mouseDoublePressEvent(MouseEvent(*event, deviceID)); }
|
void emitMouseDoublePressEvent(QMouseEvent* event, unsigned int deviceID = 0);
|
||||||
void emitMouseReleaseEvent(QMouseEvent* event, unsigned int deviceID = 0) { emit mouseReleaseEvent(MouseEvent(*event, deviceID)); }
|
void emitMouseReleaseEvent(QMouseEvent* event, unsigned int deviceID = 0);
|
||||||
|
|
||||||
void emitTouchBeginEvent(const TouchEvent& event) { emit touchBeginEvent(event); }
|
void emitTouchBeginEvent(const TouchEvent& event);
|
||||||
void emitTouchEndEvent(const TouchEvent& event) { emit touchEndEvent(event); }
|
void emitTouchEndEvent(const TouchEvent& event);
|
||||||
void emitTouchUpdateEvent(const TouchEvent& event) { emit touchUpdateEvent(event); }
|
void emitTouchUpdateEvent(const TouchEvent& event);
|
||||||
|
|
||||||
void emitWheelEvent(QWheelEvent* event) { emit wheelEvent(*event); }
|
void emitWheelEvent(QWheelEvent* event);
|
||||||
|
|
||||||
bool isKeyCaptured(QKeyEvent* event) const;
|
bool isKeyCaptured(QKeyEvent* event) const;
|
||||||
bool isKeyCaptured(const KeyEvent& event) const;
|
bool isKeyCaptured(const KeyEvent& event) const;
|
||||||
|
@ -86,48 +114,10 @@ public:
|
||||||
bool areActionsCaptured() const { return _actionsCaptured; }
|
bool areActionsCaptured() const { return _actionsCaptured; }
|
||||||
bool isJoystickCaptured(int joystickIndex) const;
|
bool isJoystickCaptured(int joystickIndex) const;
|
||||||
|
|
||||||
void updateInputControllers();
|
virtual void update() override;
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
Q_INVOKABLE virtual QVector<UserInputMapper::Action> getAllActions();
|
|
||||||
|
|
||||||
Q_INVOKABLE virtual bool addInputChannel(UserInputMapper::InputChannel inputChannel);
|
|
||||||
Q_INVOKABLE virtual bool removeInputChannel(UserInputMapper::InputChannel inputChannel);
|
|
||||||
Q_INVOKABLE virtual QVector<UserInputMapper::InputChannel> getInputChannelsForAction(UserInputMapper::Action action);
|
|
||||||
|
|
||||||
Q_INVOKABLE virtual QVector<UserInputMapper::InputPair> getAvailableInputs(unsigned int device);
|
|
||||||
Q_INVOKABLE virtual QVector<UserInputMapper::InputChannel> getAllInputsForDevice(unsigned int device);
|
|
||||||
|
|
||||||
Q_INVOKABLE virtual QString getDeviceName(unsigned int device);
|
|
||||||
|
|
||||||
Q_INVOKABLE virtual float getActionValue(int action);
|
|
||||||
|
|
||||||
Q_INVOKABLE virtual void resetDevice(unsigned int device);
|
|
||||||
Q_INVOKABLE virtual void resetAllDeviceBindings();
|
|
||||||
Q_INVOKABLE virtual int findDevice(QString name);
|
|
||||||
Q_INVOKABLE virtual QVector<QString> getDeviceNames();
|
|
||||||
|
|
||||||
Q_INVOKABLE virtual int findAction(QString actionName);
|
|
||||||
Q_INVOKABLE virtual QVector<QString> getActionNames() const;
|
|
||||||
|
|
||||||
virtual bool isPrimaryButtonPressed() const;
|
|
||||||
virtual glm::vec2 getPrimaryJoystickPosition() const;
|
|
||||||
|
|
||||||
virtual int getNumberOfButtons() const;
|
|
||||||
virtual bool isButtonPressed(int buttonIndex) const;
|
|
||||||
|
|
||||||
virtual int getNumberOfTriggers() const;
|
|
||||||
virtual float getTriggerValue(int triggerIndex) const;
|
|
||||||
|
|
||||||
virtual int getNumberOfJoysticks() const;
|
|
||||||
virtual glm::vec2 getJoystickPosition(int joystickIndex) const;
|
|
||||||
|
|
||||||
virtual int getNumberOfSpatialControls() const;
|
|
||||||
virtual glm::vec3 getSpatialControlPosition(int controlIndex) const;
|
|
||||||
virtual glm::vec3 getSpatialControlVelocity(int controlIndex) const;
|
|
||||||
virtual glm::vec3 getSpatialControlNormal(int controlIndex) const;
|
|
||||||
virtual glm::quat getSpatialControlRawRotation(int controlIndex) const;
|
|
||||||
virtual glm::vec3 getSpatialControlRawAngularVelocity(int controlIndex) const;
|
|
||||||
virtual void captureKeyEvents(const KeyEvent& event);
|
virtual void captureKeyEvents(const KeyEvent& event);
|
||||||
virtual void releaseKeyEvents(const KeyEvent& event);
|
virtual void releaseKeyEvents(const KeyEvent& event);
|
||||||
|
|
||||||
|
@ -149,9 +139,31 @@ public slots:
|
||||||
virtual glm::vec2 getViewportDimensions() const;
|
virtual glm::vec2 getViewportDimensions() const;
|
||||||
|
|
||||||
/// Factory to create an InputController
|
/// Factory to create an InputController
|
||||||
virtual AbstractInputController* createInputController(const QString& deviceName, const QString& tracker);
|
virtual controller::InputController::Pointer createInputController(const QString& deviceName, const QString& tracker);
|
||||||
|
virtual void releaseInputController(controller::InputController::Pointer input);
|
||||||
|
|
||||||
virtual void releaseInputController(AbstractInputController* input);
|
signals:
|
||||||
|
void keyPressEvent(const KeyEvent& event);
|
||||||
|
void keyReleaseEvent(const KeyEvent& event);
|
||||||
|
|
||||||
|
void actionStartEvent(const HFActionEvent& event);
|
||||||
|
void actionEndEvent(const HFActionEvent& event);
|
||||||
|
|
||||||
|
void backStartEvent();
|
||||||
|
void backEndEvent();
|
||||||
|
|
||||||
|
void mouseMoveEvent(const MouseEvent& event, unsigned int deviceID = 0);
|
||||||
|
void mousePressEvent(const MouseEvent& event, unsigned int deviceID = 0);
|
||||||
|
void mouseDoublePressEvent(const MouseEvent& event, unsigned int deviceID = 0);
|
||||||
|
void mouseReleaseEvent(const MouseEvent& event, unsigned int deviceID = 0);
|
||||||
|
|
||||||
|
void touchBeginEvent(const TouchEvent& event);
|
||||||
|
void touchEndEvent(const TouchEvent& event);
|
||||||
|
void touchUpdateEvent(const TouchEvent& event);
|
||||||
|
|
||||||
|
void wheelEvent(const WheelEvent& event);
|
||||||
|
|
||||||
|
void actionEvent(int action, float state);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QString sanatizeName(const QString& name); /// makes a name clean for inclusing in JavaScript
|
QString sanatizeName(const QString& name); /// makes a name clean for inclusing in JavaScript
|
||||||
|
@ -168,12 +180,9 @@ private:
|
||||||
QMultiMap<int,KeyEvent> _capturedKeys;
|
QMultiMap<int,KeyEvent> _capturedKeys;
|
||||||
QSet<int> _capturedJoysticks;
|
QSet<int> _capturedJoysticks;
|
||||||
|
|
||||||
typedef std::map< AbstractInputController::Key, AbstractInputController* > InputControllerMap;
|
using InputKey = controller::InputController::Key;
|
||||||
|
using InputControllerMap = std::map<InputKey, controller::InputController::Pointer>;
|
||||||
InputControllerMap _inputControllers;
|
InputControllerMap _inputControllers;
|
||||||
|
|
||||||
void wireUpControllers(ScriptEngine* engine);
|
|
||||||
|
|
||||||
controller::NewControllerScriptingInterface* _newControllerScriptingInterface = nullptr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const int NUMBER_OF_SPATIALCONTROLS_PER_PALM = 2; // the hand and the tip
|
const int NUMBER_OF_SPATIALCONTROLS_PER_PALM = 2; // the hand and the tip
|
||||||
|
|
|
@ -27,7 +27,7 @@
|
||||||
|
|
||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include <input-plugins/SixenseManager.h> // TODO: any references to sixense should be removed here
|
#include <input-plugins/SixenseManager.h> // TODO: any references to sixense should be removed here
|
||||||
#include <input-plugins/InputDevice.h>
|
#include <controllers/InputDevice.h>
|
||||||
|
|
||||||
|
|
||||||
// Used to animate the magnification windows
|
// Used to animate the magnification windows
|
||||||
|
|
|
@ -4,7 +4,7 @@ set(TARGET_NAME controllers)
|
||||||
setup_hifi_library(Script)
|
setup_hifi_library(Script)
|
||||||
|
|
||||||
# use setup_hifi_library macro to setup our project and link appropriate Qt modules
|
# use setup_hifi_library macro to setup our project and link appropriate Qt modules
|
||||||
link_hifi_libraries(shared plugins input-plugins)
|
link_hifi_libraries(shared)
|
||||||
|
|
||||||
GroupSources("src/controllers")
|
GroupSources("src/controllers")
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
#include <input-plugins/UserInputMapper.h>
|
#include "UserInputMapper.h"
|
||||||
|
|
||||||
class QScriptValue;
|
class QScriptValue;
|
||||||
|
|
||||||
|
|
|
@ -1,92 +0,0 @@
|
||||||
//
|
|
||||||
// Created by Bradley Austin Davis 2015/10/09
|
|
||||||
// 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
|
|
||||||
//
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
#ifndef hifi_Controllers_NewControllerScriptingInterface_h
|
|
||||||
#define hifi_Controllers_NewControllerScriptingInterface_h
|
|
||||||
|
|
||||||
#include <unordered_map>
|
|
||||||
#include <unordered_set>
|
|
||||||
#include <map>
|
|
||||||
#include <set>
|
|
||||||
|
|
||||||
#include <QtCore/QObject>
|
|
||||||
#include <QtCore/QVariant>
|
|
||||||
|
|
||||||
#include <QtQml/QJSValue>
|
|
||||||
#include <QtScript/QScriptValue>
|
|
||||||
|
|
||||||
#include <input-plugins/UserInputMapper.h>
|
|
||||||
|
|
||||||
#include "Mapping.h"
|
|
||||||
|
|
||||||
class QScriptValue;
|
|
||||||
|
|
||||||
namespace controller {
|
|
||||||
class NewControllerScriptingInterface : public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
Q_PROPERTY(QVariantMap Hardware READ getHardware CONSTANT FINAL)
|
|
||||||
Q_PROPERTY(QVariantMap Actions READ getActions CONSTANT FINAL)
|
|
||||||
Q_PROPERTY(QVariantMap Standard READ getStandard CONSTANT FINAL)
|
|
||||||
|
|
||||||
public:
|
|
||||||
NewControllerScriptingInterface();
|
|
||||||
Q_INVOKABLE float getValue(const int& source);
|
|
||||||
|
|
||||||
Q_INVOKABLE void update();
|
|
||||||
Q_INVOKABLE QObject* newMapping(const QString& mappingName = QUuid::createUuid().toString());
|
|
||||||
Q_INVOKABLE QObject* parseMapping(const QString& json);
|
|
||||||
Q_INVOKABLE void enableMapping(const QString& mappingName, bool enable = true);
|
|
||||||
Q_INVOKABLE void disableMapping(const QString& mappingName) {
|
|
||||||
enableMapping(mappingName, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const QVariantMap& getHardware() { return _hardware; }
|
|
||||||
const QVariantMap& getActions() { return _actions; }
|
|
||||||
const QVariantMap& getStandard() { return _standard; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
|
|
||||||
// FIXME move to unordered set / map
|
|
||||||
using MappingMap = std::map<QString, Mapping::Pointer>;
|
|
||||||
using MappingStack = std::list<Mapping::Pointer>;
|
|
||||||
using InputToEndpointMap = std::map<UserInputMapper::Input, Endpoint::Pointer>;
|
|
||||||
using EndpointSet = std::unordered_set<Endpoint::Pointer>;
|
|
||||||
using ValueMap = std::map<Endpoint::Pointer, float>;
|
|
||||||
using EndpointPair = std::pair<Endpoint::Pointer, Endpoint::Pointer>;
|
|
||||||
using EndpointPairMap = std::map<EndpointPair, Endpoint::Pointer>;
|
|
||||||
|
|
||||||
void update(Mapping::Pointer& mapping, EndpointSet& consumed);
|
|
||||||
float getValue(const Endpoint::Pointer& endpoint);
|
|
||||||
Endpoint::Pointer endpointFor(const QJSValue& endpoint);
|
|
||||||
Endpoint::Pointer endpointFor(const QScriptValue& endpoint);
|
|
||||||
Endpoint::Pointer endpointFor(const UserInputMapper::Input& endpoint);
|
|
||||||
Endpoint::Pointer compositeEndpointFor(Endpoint::Pointer first, Endpoint::Pointer second);
|
|
||||||
|
|
||||||
UserInputMapper::Input inputFor(const QString& inputName);
|
|
||||||
|
|
||||||
friend class MappingBuilderProxy;
|
|
||||||
friend class RouteBuilderProxy;
|
|
||||||
private:
|
|
||||||
uint16_t _nextFunctionId;
|
|
||||||
InputToEndpointMap _endpoints;
|
|
||||||
EndpointPairMap _compositeEndpoints;
|
|
||||||
|
|
||||||
ValueMap _overrideValues;
|
|
||||||
MappingMap _mappingsByName;
|
|
||||||
MappingStack _activeMappings;
|
|
||||||
|
|
||||||
QVariantMap _hardware;
|
|
||||||
QVariantMap _actions;
|
|
||||||
QVariantMap _standard;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -5,7 +5,7 @@
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
#include "NewControllerScriptingInterface.h"
|
#include "ScriptingInterface.h"
|
||||||
|
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
@ -17,17 +17,13 @@
|
||||||
|
|
||||||
#include <GLMHelpers.h>
|
#include <GLMHelpers.h>
|
||||||
#include <DependencyManager.h>
|
#include <DependencyManager.h>
|
||||||
#include <input-plugins/UserInputMapper.h>
|
|
||||||
#include <input-plugins/InputPlugin.h>
|
|
||||||
#include <input-plugins/KeyboardMouseDevice.h>
|
|
||||||
#include <plugins/PluginManager.h>
|
|
||||||
|
|
||||||
#include "impl/MappingBuilderProxy.h"
|
#include "impl/MappingBuilderProxy.h"
|
||||||
#include "Logging.h"
|
#include "Logging.h"
|
||||||
|
#include "InputDevice.h"
|
||||||
|
|
||||||
namespace controller {
|
namespace controller {
|
||||||
|
|
||||||
|
|
||||||
class VirtualEndpoint : public Endpoint {
|
class VirtualEndpoint : public Endpoint {
|
||||||
public:
|
public:
|
||||||
VirtualEndpoint(const UserInputMapper::Input& id = UserInputMapper::Input(-1))
|
VirtualEndpoint(const UserInputMapper::Input& id = UserInputMapper::Input(-1))
|
||||||
|
@ -98,18 +94,15 @@ namespace controller {
|
||||||
Endpoint::Pointer _second;
|
Endpoint::Pointer _second;
|
||||||
};
|
};
|
||||||
|
|
||||||
QString sanatizeName(const QString& name) {
|
|
||||||
QString cleanName{ name };
|
QRegularExpression ScriptingInterface::SANITIZE_NAME_EXPRESSION{ "[\\(\\)\\.\\s]" };
|
||||||
cleanName.remove(QRegularExpression{ "[\\(\\)\\.\\s]" });
|
|
||||||
return cleanName;
|
|
||||||
}
|
|
||||||
|
|
||||||
QVariantMap createDeviceMap(const UserInputMapper::DeviceProxy* device) {
|
QVariantMap createDeviceMap(const UserInputMapper::DeviceProxy* device) {
|
||||||
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
||||||
QVariantMap deviceMap;
|
QVariantMap deviceMap;
|
||||||
for (const auto& inputMapping : device->getAvailabeInputs()) {
|
for (const auto& inputMapping : device->getAvailabeInputs()) {
|
||||||
const auto& input = inputMapping.first;
|
const auto& input = inputMapping.first;
|
||||||
const auto inputName = sanatizeName(inputMapping.second);
|
const auto inputName = QString(inputMapping.second).remove(ScriptingInterface::SANITIZE_NAME_EXPRESSION);
|
||||||
qCDebug(controllers) << "\tInput " << input.getChannel() << (int)input.getType()
|
qCDebug(controllers) << "\tInput " << input.getChannel() << (int)input.getType()
|
||||||
<< QString::number(input.getID(), 16) << ": " << inputName;
|
<< QString::number(input.getID(), 16) << ": " << inputName;
|
||||||
deviceMap.insert(inputName, input.getID());
|
deviceMap.insert(inputName, input.getID());
|
||||||
|
@ -117,12 +110,12 @@ namespace controller {
|
||||||
return deviceMap;
|
return deviceMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
NewControllerScriptingInterface::NewControllerScriptingInterface() {
|
ScriptingInterface::ScriptingInterface() {
|
||||||
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
||||||
auto devices = userInputMapper->getDevices();
|
auto devices = userInputMapper->getDevices();
|
||||||
for (const auto& deviceMapping : devices) {
|
for (const auto& deviceMapping : devices) {
|
||||||
auto device = deviceMapping.second.get();
|
auto device = deviceMapping.second.get();
|
||||||
auto deviceName = sanatizeName(device->getName());
|
auto deviceName = QString(device->getName()).remove(ScriptingInterface::SANITIZE_NAME_EXPRESSION);
|
||||||
qCDebug(controllers) << "Device" << deviceMapping.first << ":" << deviceName;
|
qCDebug(controllers) << "Device" << deviceMapping.first << ":" << deviceName;
|
||||||
// Expose the IDs to JS
|
// Expose the IDs to JS
|
||||||
_hardware.insert(deviceName, createDeviceMap(device));
|
_hardware.insert(deviceName, createDeviceMap(device));
|
||||||
|
@ -165,7 +158,8 @@ namespace controller {
|
||||||
UserInputMapper::Input actionInput(UserInputMapper::Input::ACTIONS_DEVICE, actionNumber++, UserInputMapper::ChannelType::AXIS);
|
UserInputMapper::Input actionInput(UserInputMapper::Input::ACTIONS_DEVICE, actionNumber++, UserInputMapper::ChannelType::AXIS);
|
||||||
qCDebug(controllers) << "\tAction: " << actionName << " " << QString::number(actionInput.getID(), 16);
|
qCDebug(controllers) << "\tAction: " << actionName << " " << QString::number(actionInput.getID(), 16);
|
||||||
// Expose the IDs to JS
|
// Expose the IDs to JS
|
||||||
_actions.insert(sanatizeName(actionName), actionInput.getID());
|
QString cleanActionName = QString(actionName).remove(ScriptingInterface::SANITIZE_NAME_EXPRESSION);
|
||||||
|
_actions.insert(cleanActionName, actionInput.getID());
|
||||||
|
|
||||||
// Create the endpoints
|
// Create the endpoints
|
||||||
// FIXME action endpoints need to accumulate values, and have them cleared at each frame
|
// FIXME action endpoints need to accumulate values, and have them cleared at each frame
|
||||||
|
@ -173,7 +167,7 @@ namespace controller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QObject* NewControllerScriptingInterface::newMapping(const QString& mappingName) {
|
QObject* ScriptingInterface::newMapping(const QString& mappingName) {
|
||||||
if (_mappingsByName.count(mappingName)) {
|
if (_mappingsByName.count(mappingName)) {
|
||||||
qCWarning(controllers) << "Refusing to recreate mapping named " << mappingName;
|
qCWarning(controllers) << "Refusing to recreate mapping named " << mappingName;
|
||||||
}
|
}
|
||||||
|
@ -183,7 +177,7 @@ namespace controller {
|
||||||
return new MappingBuilderProxy(*this, mapping);
|
return new MappingBuilderProxy(*this, mapping);
|
||||||
}
|
}
|
||||||
|
|
||||||
QObject* NewControllerScriptingInterface::parseMapping(const QString& json) {
|
QObject* ScriptingInterface::parseMapping(const QString& json) {
|
||||||
|
|
||||||
QJsonObject obj;
|
QJsonObject obj;
|
||||||
QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
|
QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8());
|
||||||
|
@ -211,7 +205,7 @@ namespace controller {
|
||||||
|
|
||||||
Q_INVOKABLE QObject* newMapping(const QJsonObject& json);
|
Q_INVOKABLE QObject* newMapping(const QJsonObject& json);
|
||||||
|
|
||||||
void NewControllerScriptingInterface::enableMapping(const QString& mappingName, bool enable) {
|
void ScriptingInterface::enableMapping(const QString& mappingName, bool enable) {
|
||||||
auto iterator = _mappingsByName.find(mappingName);
|
auto iterator = _mappingsByName.find(mappingName);
|
||||||
if (_mappingsByName.end() == iterator) {
|
if (_mappingsByName.end() == iterator) {
|
||||||
qCWarning(controllers) << "Request to enable / disable unknown mapping " << mappingName;
|
qCWarning(controllers) << "Request to enable / disable unknown mapping " << mappingName;
|
||||||
|
@ -231,7 +225,7 @@ namespace controller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
float NewControllerScriptingInterface::getValue(const int& source) {
|
float ScriptingInterface::getValue(const int& source) const {
|
||||||
// return (sin(secTimestampNow()) + 1.0f) / 2.0f;
|
// return (sin(secTimestampNow()) + 1.0f) / 2.0f;
|
||||||
UserInputMapper::Input input(source);
|
UserInputMapper::Input input(source);
|
||||||
auto iterator = _endpoints.find(input);
|
auto iterator = _endpoints.find(input);
|
||||||
|
@ -243,7 +237,7 @@ namespace controller {
|
||||||
return getValue(endpoint);
|
return getValue(endpoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
float NewControllerScriptingInterface::getValue(const Endpoint::Pointer& endpoint) {
|
float ScriptingInterface::getValue(const Endpoint::Pointer& endpoint) const {
|
||||||
auto valuesIterator = _overrideValues.find(endpoint);
|
auto valuesIterator = _overrideValues.find(endpoint);
|
||||||
if (_overrideValues.end() != valuesIterator) {
|
if (_overrideValues.end() != valuesIterator) {
|
||||||
return valuesIterator->second;
|
return valuesIterator->second;
|
||||||
|
@ -252,19 +246,20 @@ namespace controller {
|
||||||
return endpoint->value();
|
return endpoint->value();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float ScriptingInterface::getButtonValue(StandardButtonChannel source, uint16_t device) const {
|
||||||
void NewControllerScriptingInterface::update() {
|
return getValue(UserInputMapper::Input(device, source, UserInputMapper::ChannelType::BUTTON).getID());
|
||||||
static float last = secTimestampNow();
|
}
|
||||||
float now = secTimestampNow();
|
|
||||||
float delta = now - last;
|
|
||||||
last = now;
|
|
||||||
|
|
||||||
foreach(auto inputPlugin, PluginManager::getInstance()->getInputPlugins()) {
|
float ScriptingInterface::getAxisValue(StandardAxisChannel source, uint16_t device) const {
|
||||||
inputPlugin->pluginUpdate(delta, false);
|
return getValue(UserInputMapper::Input(device, source, UserInputMapper::ChannelType::AXIS).getID());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
glm::mat4 ScriptingInterface::getPoseValue(StandardPoseChannel source, uint16_t device) const {
|
||||||
|
return glm::mat4();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptingInterface::update() {
|
||||||
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
||||||
userInputMapper->update(delta);
|
|
||||||
|
|
||||||
_overrideValues.clear();
|
_overrideValues.clear();
|
||||||
EndpointSet readEndpoints;
|
EndpointSet readEndpoints;
|
||||||
|
@ -324,9 +319,7 @@ namespace controller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Endpoint::Pointer ScriptingInterface::endpointFor(const QJSValue& endpoint) {
|
||||||
|
|
||||||
Endpoint::Pointer NewControllerScriptingInterface::endpointFor(const QJSValue& endpoint) {
|
|
||||||
if (endpoint.isNumber()) {
|
if (endpoint.isNumber()) {
|
||||||
return endpointFor(UserInputMapper::Input(endpoint.toInt()));
|
return endpointFor(UserInputMapper::Input(endpoint.toInt()));
|
||||||
}
|
}
|
||||||
|
@ -340,7 +333,7 @@ namespace controller {
|
||||||
return Endpoint::Pointer();
|
return Endpoint::Pointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
Endpoint::Pointer NewControllerScriptingInterface::endpointFor(const QScriptValue& endpoint) {
|
Endpoint::Pointer ScriptingInterface::endpointFor(const QScriptValue& endpoint) {
|
||||||
if (endpoint.isNumber()) {
|
if (endpoint.isNumber()) {
|
||||||
return endpointFor(UserInputMapper::Input(endpoint.toInt32()));
|
return endpointFor(UserInputMapper::Input(endpoint.toInt32()));
|
||||||
}
|
}
|
||||||
|
@ -354,11 +347,11 @@ namespace controller {
|
||||||
return Endpoint::Pointer();
|
return Endpoint::Pointer();
|
||||||
}
|
}
|
||||||
|
|
||||||
UserInputMapper::Input NewControllerScriptingInterface::inputFor(const QString& inputName) {
|
UserInputMapper::Input ScriptingInterface::inputFor(const QString& inputName) {
|
||||||
return DependencyManager::get<UserInputMapper>()->findDeviceInput(inputName);
|
return DependencyManager::get<UserInputMapper>()->findDeviceInput(inputName);
|
||||||
}
|
}
|
||||||
|
|
||||||
Endpoint::Pointer NewControllerScriptingInterface::endpointFor(const UserInputMapper::Input& inputId) {
|
Endpoint::Pointer ScriptingInterface::endpointFor(const UserInputMapper::Input& inputId) {
|
||||||
auto iterator = _endpoints.find(inputId);
|
auto iterator = _endpoints.find(inputId);
|
||||||
if (_endpoints.end() == iterator) {
|
if (_endpoints.end() == iterator) {
|
||||||
qWarning() << "Unknown input: " << QString::number(inputId.getID(), 16);
|
qWarning() << "Unknown input: " << QString::number(inputId.getID(), 16);
|
||||||
|
@ -367,7 +360,7 @@ namespace controller {
|
||||||
return iterator->second;
|
return iterator->second;
|
||||||
}
|
}
|
||||||
|
|
||||||
Endpoint::Pointer NewControllerScriptingInterface::compositeEndpointFor(Endpoint::Pointer first, Endpoint::Pointer second) {
|
Endpoint::Pointer ScriptingInterface::compositeEndpointFor(Endpoint::Pointer first, Endpoint::Pointer second) {
|
||||||
EndpointPair pair(first, second);
|
EndpointPair pair(first, second);
|
||||||
Endpoint::Pointer result;
|
Endpoint::Pointer result;
|
||||||
auto iterator = _compositeEndpoints.find(pair);
|
auto iterator = _compositeEndpoints.find(pair);
|
||||||
|
@ -380,6 +373,70 @@ namespace controller {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ScriptingInterface::isPrimaryButtonPressed() const {
|
||||||
|
return isButtonPressed(StandardButtonChannel::A);
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec2 ScriptingInterface::getPrimaryJoystickPosition() const {
|
||||||
|
return getJoystickPosition(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ScriptingInterface::getNumberOfButtons() const {
|
||||||
|
return StandardButtonChannel::NUM_STANDARD_BUTTONS;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ScriptingInterface::isButtonPressed(int buttonIndex) const {
|
||||||
|
return getButtonValue((StandardButtonChannel)buttonIndex) == 0.0 ? false : true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ScriptingInterface::getNumberOfTriggers() const {
|
||||||
|
return StandardCounts::TRIGGERS;
|
||||||
|
}
|
||||||
|
|
||||||
|
float ScriptingInterface::getTriggerValue(int triggerIndex) const {
|
||||||
|
return getAxisValue(triggerIndex == 0 ? StandardAxisChannel::LT : StandardAxisChannel::RT);
|
||||||
|
}
|
||||||
|
|
||||||
|
int ScriptingInterface::getNumberOfJoysticks() const {
|
||||||
|
return StandardCounts::ANALOG_STICKS;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec2 ScriptingInterface::getJoystickPosition(int joystickIndex) const {
|
||||||
|
StandardAxisChannel xid = StandardAxisChannel::LX;
|
||||||
|
StandardAxisChannel yid = StandardAxisChannel::LY;
|
||||||
|
if (joystickIndex != 0) {
|
||||||
|
xid = StandardAxisChannel::RX;
|
||||||
|
yid = StandardAxisChannel::RY;
|
||||||
|
}
|
||||||
|
vec2 result;
|
||||||
|
result.x = getAxisValue(xid);
|
||||||
|
result.y = getAxisValue(yid);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ScriptingInterface::getNumberOfSpatialControls() const {
|
||||||
|
return StandardCounts::POSES;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 ScriptingInterface::getSpatialControlPosition(int controlIndex) const {
|
||||||
|
// FIXME extract the position from the standard pose
|
||||||
|
return vec3();
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 ScriptingInterface::getSpatialControlVelocity(int controlIndex) const {
|
||||||
|
// FIXME extract the velocity from the standard pose
|
||||||
|
return vec3();
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::vec3 ScriptingInterface::getSpatialControlNormal(int controlIndex) const {
|
||||||
|
// FIXME extract the normal from the standard pose
|
||||||
|
return vec3();
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::quat ScriptingInterface::getSpatialControlRawRotation(int controlIndex) const {
|
||||||
|
// FIXME extract the rotation from the standard pose
|
||||||
|
return quat();
|
||||||
|
}
|
||||||
} // namespace controllers
|
} // namespace controllers
|
||||||
|
|
||||||
//var mapping = Controller.newMapping();
|
//var mapping = Controller.newMapping();
|
141
libraries/controllers/src/controllers/ScriptingInterface.h
Normal file
141
libraries/controllers/src/controllers/ScriptingInterface.h
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
//
|
||||||
|
// AbstractControllerScriptingInterface.h
|
||||||
|
// libraries/script-engine/src
|
||||||
|
//
|
||||||
|
// Created by Brad Hefta-Gaub on 12/17/13.
|
||||||
|
// Copyright 2013 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
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
#ifndef hifi_AbstractControllerScriptingInterface_h
|
||||||
|
#define hifi_AbstractControllerScriptingInterface_h
|
||||||
|
|
||||||
|
#include <unordered_map>
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <map>
|
||||||
|
#include <set>
|
||||||
|
|
||||||
|
#include <glm/glm.hpp>
|
||||||
|
#include <glm/gtc/quaternion.hpp>
|
||||||
|
|
||||||
|
#include <QtCore/QObject>
|
||||||
|
#include <QtCore/QVariant>
|
||||||
|
|
||||||
|
#include <QtQml/QJSValue>
|
||||||
|
#include <QtScript/QScriptValue>
|
||||||
|
|
||||||
|
#include "UserInputMapper.h"
|
||||||
|
#include "StandardControls.h"
|
||||||
|
#include "Mapping.h"
|
||||||
|
|
||||||
|
namespace controller {
|
||||||
|
class InputController : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
using Key = unsigned int;
|
||||||
|
using Pointer = std::shared_ptr<InputController>;
|
||||||
|
|
||||||
|
virtual void update() = 0;
|
||||||
|
virtual Key getKey() const = 0;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual bool isActive() const = 0;
|
||||||
|
virtual glm::vec3 getAbsTranslation() const = 0;
|
||||||
|
virtual glm::quat getAbsRotation() const = 0;
|
||||||
|
virtual glm::vec3 getLocTranslation() const = 0;
|
||||||
|
virtual glm::quat getLocRotation() const = 0;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
//void spatialEvent(const SpatialEvent& event);
|
||||||
|
};
|
||||||
|
|
||||||
|
/// handles scripting of input controller commands from JS
|
||||||
|
class ScriptingInterface : public QObject {
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(QVariantMap Hardware READ getHardware CONSTANT FINAL)
|
||||||
|
Q_PROPERTY(QVariantMap Actions READ getActions CONSTANT FINAL)
|
||||||
|
Q_PROPERTY(QVariantMap Standard READ getStandard CONSTANT FINAL)
|
||||||
|
|
||||||
|
public:
|
||||||
|
ScriptingInterface();
|
||||||
|
|
||||||
|
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 glm::mat4 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);
|
||||||
|
}
|
||||||
|
Q_INVOKABLE QObject* parseMapping(const QString& json);
|
||||||
|
|
||||||
|
Q_INVOKABLE bool isPrimaryButtonPressed() const;
|
||||||
|
Q_INVOKABLE glm::vec2 getPrimaryJoystickPosition() const;
|
||||||
|
|
||||||
|
Q_INVOKABLE int getNumberOfButtons() const;
|
||||||
|
Q_INVOKABLE bool isButtonPressed(int buttonIndex) const;
|
||||||
|
|
||||||
|
Q_INVOKABLE int getNumberOfTriggers() const;
|
||||||
|
Q_INVOKABLE float getTriggerValue(int triggerIndex) const;
|
||||||
|
|
||||||
|
Q_INVOKABLE int getNumberOfJoysticks() const;
|
||||||
|
Q_INVOKABLE glm::vec2 getJoystickPosition(int joystickIndex) const;
|
||||||
|
|
||||||
|
Q_INVOKABLE int getNumberOfSpatialControls() const;
|
||||||
|
Q_INVOKABLE glm::vec3 getSpatialControlPosition(int controlIndex) const;
|
||||||
|
Q_INVOKABLE glm::vec3 getSpatialControlVelocity(int controlIndex) const;
|
||||||
|
Q_INVOKABLE glm::vec3 getSpatialControlNormal(int controlIndex) const;
|
||||||
|
Q_INVOKABLE glm::quat getSpatialControlRawRotation(int controlIndex) const;
|
||||||
|
|
||||||
|
Q_INVOKABLE const QVariantMap& getHardware() { return _hardware; }
|
||||||
|
Q_INVOKABLE const QVariantMap& getActions() { return _actions; }
|
||||||
|
Q_INVOKABLE const QVariantMap& getStandard() { return _standard; }
|
||||||
|
|
||||||
|
static QRegularExpression SANITIZE_NAME_EXPRESSION;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
virtual void update();
|
||||||
|
virtual void registerControllerTypes(QScriptEngine* engine) = 0;
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class MappingBuilderProxy;
|
||||||
|
friend class RouteBuilderProxy;
|
||||||
|
|
||||||
|
// FIXME move to unordered set / map
|
||||||
|
using MappingMap = std::map<QString, Mapping::Pointer>;
|
||||||
|
using MappingStack = std::list<Mapping::Pointer>;
|
||||||
|
using InputToEndpointMap = std::map<UserInputMapper::Input, Endpoint::Pointer>;
|
||||||
|
using EndpointSet = std::unordered_set<Endpoint::Pointer>;
|
||||||
|
using ValueMap = std::map<Endpoint::Pointer, float>;
|
||||||
|
using EndpointPair = std::pair<Endpoint::Pointer, Endpoint::Pointer>;
|
||||||
|
using EndpointPairMap = std::map<EndpointPair, Endpoint::Pointer>;
|
||||||
|
|
||||||
|
void update(Mapping::Pointer& mapping, EndpointSet& consumed);
|
||||||
|
float getValue(const Endpoint::Pointer& endpoint) const;
|
||||||
|
Endpoint::Pointer endpointFor(const QJSValue& endpoint);
|
||||||
|
Endpoint::Pointer endpointFor(const QScriptValue& endpoint);
|
||||||
|
Endpoint::Pointer endpointFor(const UserInputMapper::Input& endpoint);
|
||||||
|
Endpoint::Pointer compositeEndpointFor(Endpoint::Pointer first, Endpoint::Pointer second);
|
||||||
|
|
||||||
|
UserInputMapper::Input inputFor(const QString& inputName);
|
||||||
|
|
||||||
|
QVariantMap _hardware;
|
||||||
|
QVariantMap _actions;
|
||||||
|
QVariantMap _standard;
|
||||||
|
|
||||||
|
InputToEndpointMap _endpoints;
|
||||||
|
EndpointPairMap _compositeEndpoints;
|
||||||
|
|
||||||
|
ValueMap _overrideValues;
|
||||||
|
MappingMap _mappingsByName;
|
||||||
|
MappingStack _activeMappings;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif // hifi_AbstractControllerScriptingInterface_h
|
|
@ -38,59 +38,59 @@ void StandardController::registerToUserInputMapper(UserInputMapper& mapper) {
|
||||||
proxy->getAvailabeInputs = [this] () -> QVector<UserInputMapper::InputPair> {
|
proxy->getAvailabeInputs = [this] () -> QVector<UserInputMapper::InputPair> {
|
||||||
QVector<UserInputMapper::InputPair> availableInputs;
|
QVector<UserInputMapper::InputPair> availableInputs;
|
||||||
// Buttons
|
// Buttons
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::A), "A"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::A), "A"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::B), "B"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::B), "B"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::X), "X"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::X), "X"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::Y), "Y"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::Y), "Y"));
|
||||||
|
|
||||||
// DPad
|
// DPad
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::DU), "DU"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::DU), "DU"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::DD), "DD"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::DD), "DD"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::DL), "DL"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::DL), "DL"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::DR), "DR"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::DR), "DR"));
|
||||||
|
|
||||||
// Bumpers
|
// Bumpers
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::LB), "LB"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::LB), "LB"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::RB), "RB"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::RB), "RB"));
|
||||||
|
|
||||||
// Stick press
|
// Stick press
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::LS), "LS"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::LS), "LS"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::RS), "RS"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::RS), "RS"));
|
||||||
|
|
||||||
// Center buttons
|
// Center buttons
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::START), "Start"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::START), "Start"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::BACK), "Back"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::BACK), "Back"));
|
||||||
|
|
||||||
// Analog sticks
|
// Analog sticks
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::LY), "LY"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::LY), "LY"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::LX), "LX"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::LX), "LX"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::RY), "RY"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::RY), "RY"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::RX), "RX"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::RX), "RX"));
|
||||||
|
|
||||||
// Triggers
|
// Triggers
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::LT), "LT"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::LT), "LT"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::RT), "RT"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::RT), "RT"));
|
||||||
|
|
||||||
// Poses
|
// Poses
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::LeftPose), "LeftPose"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::LEFT), "LeftPose"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::RightPose), "RightPose"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::RIGHT), "RightPose"));
|
||||||
|
|
||||||
// Aliases, PlayStation style names
|
// Aliases, PlayStation style names
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::LB), "L1"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::LB), "L1"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::RB), "R1"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::RB), "R1"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::LT), "L2"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::LT), "L2"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::RT), "R2"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::RT), "R2"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::LS), "L3"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::LS), "L3"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::RS), "R3"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::RS), "R3"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::BACK), "Select"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::BACK), "Select"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::A), "Cross"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::A), "Cross"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::B), "Circle"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::B), "Circle"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::X), "Square"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::X), "Square"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::Y), "Triangle"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::Y), "Triangle"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::DU), "Up"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::DU), "Up"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::DD), "Down"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::DD), "Down"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::DL), "Left"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::DL), "Left"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::DR), "Right"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::DR), "Right"));
|
||||||
|
|
||||||
|
|
||||||
return availableInputs;
|
return availableInputs;
|
||||||
|
@ -108,14 +108,14 @@ void StandardController::registerToUserInputMapper(UserInputMapper& mapper) {
|
||||||
void StandardController::assignDefaultInputMapping(UserInputMapper& mapper) {
|
void StandardController::assignDefaultInputMapping(UserInputMapper& mapper) {
|
||||||
}
|
}
|
||||||
|
|
||||||
UserInputMapper::Input StandardController::makeInput(Controllers::StandardButtonChannel button) {
|
UserInputMapper::Input StandardController::makeInput(controller::StandardButtonChannel button) {
|
||||||
return UserInputMapper::Input(_deviceID, button, UserInputMapper::ChannelType::BUTTON);
|
return UserInputMapper::Input(_deviceID, button, UserInputMapper::ChannelType::BUTTON);
|
||||||
}
|
}
|
||||||
|
|
||||||
UserInputMapper::Input StandardController::makeInput(Controllers::StandardAxisChannel axis) {
|
UserInputMapper::Input StandardController::makeInput(controller::StandardAxisChannel axis) {
|
||||||
return UserInputMapper::Input(_deviceID, axis, UserInputMapper::ChannelType::AXIS);
|
return UserInputMapper::Input(_deviceID, axis, UserInputMapper::ChannelType::AXIS);
|
||||||
}
|
}
|
||||||
|
|
||||||
UserInputMapper::Input StandardController::makeInput(Controllers::StandardPoseChannel pose) {
|
UserInputMapper::Input StandardController::makeInput(controller::StandardPoseChannel pose) {
|
||||||
return UserInputMapper::Input(_deviceID, pose, UserInputMapper::ChannelType::POSE);
|
return UserInputMapper::Input(_deviceID, pose, UserInputMapper::ChannelType::POSE);
|
||||||
}
|
}
|
|
@ -38,9 +38,9 @@ public:
|
||||||
StandardController() : InputDevice("Standard") {}
|
StandardController() : InputDevice("Standard") {}
|
||||||
~StandardController();
|
~StandardController();
|
||||||
|
|
||||||
UserInputMapper::Input makeInput(Controllers::StandardButtonChannel button);
|
UserInputMapper::Input makeInput(controller::StandardButtonChannel button);
|
||||||
UserInputMapper::Input makeInput(Controllers::StandardAxisChannel axis);
|
UserInputMapper::Input makeInput(controller::StandardAxisChannel axis);
|
||||||
UserInputMapper::Input makeInput(Controllers::StandardPoseChannel pose);
|
UserInputMapper::Input makeInput(controller::StandardPoseChannel pose);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
};
|
};
|
|
@ -7,7 +7,7 @@
|
||||||
//
|
//
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
namespace Controllers {
|
namespace controller {
|
||||||
|
|
||||||
// Needs to match order and values of SDL_GameControllerButton
|
// Needs to match order and values of SDL_GameControllerButton
|
||||||
enum StandardButtonChannel {
|
enum StandardButtonChannel {
|
||||||
|
@ -30,7 +30,8 @@ namespace Controllers {
|
||||||
DU,
|
DU,
|
||||||
DD,
|
DD,
|
||||||
DL,
|
DL,
|
||||||
DR
|
DR,
|
||||||
|
NUM_STANDARD_BUTTONS
|
||||||
};
|
};
|
||||||
|
|
||||||
// Needs to match order and values of SDL_GameControllerAxis
|
// Needs to match order and values of SDL_GameControllerAxis
|
||||||
|
@ -43,13 +44,21 @@ namespace Controllers {
|
||||||
RY,
|
RY,
|
||||||
// Triggers
|
// Triggers
|
||||||
LT,
|
LT,
|
||||||
RT
|
RT,
|
||||||
|
NUM_STANDARD_AXES
|
||||||
};
|
};
|
||||||
|
|
||||||
// No correlation to SDL
|
// No correlation to SDL
|
||||||
enum StandardPoseChannel {
|
enum StandardPoseChannel {
|
||||||
LeftPose = 0,
|
LEFT = 0,
|
||||||
RightPose
|
RIGHT,
|
||||||
|
HEAD,
|
||||||
|
NUM_STANDARD_POSES
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum StandardCounts {
|
||||||
|
TRIGGERS = 2,
|
||||||
|
ANALOG_STICKS = 2,
|
||||||
|
POSES = 2, // FIXME 3? if we want to expose the head?
|
||||||
|
};
|
||||||
}
|
}
|
|
@ -12,9 +12,7 @@
|
||||||
#include "UserInputMapper.h"
|
#include "UserInputMapper.h"
|
||||||
#include "StandardController.h"
|
#include "StandardController.h"
|
||||||
|
|
||||||
#include <QLoggingCategory>
|
#include "Logging.h"
|
||||||
Q_DECLARE_LOGGING_CATEGORY(userInputMapper)
|
|
||||||
Q_LOGGING_CATEGORY(userInputMapper, "hifi.userInputMapper")
|
|
||||||
|
|
||||||
const UserInputMapper::Input UserInputMapper::Input::INVALID_INPUT = UserInputMapper::Input(UINT16_MAX);
|
const UserInputMapper::Input UserInputMapper::Input::INVALID_INPUT = UserInputMapper::Input(UINT16_MAX);
|
||||||
const uint16_t UserInputMapper::Input::INVALID_DEVICE = INVALID_INPUT.getDevice();
|
const uint16_t UserInputMapper::Input::INVALID_DEVICE = INVALID_INPUT.getDevice();
|
||||||
|
@ -36,7 +34,7 @@ UserInputMapper::~UserInputMapper() {
|
||||||
bool UserInputMapper::registerDevice(uint16 deviceID, const DeviceProxy::Pointer& proxy){
|
bool UserInputMapper::registerDevice(uint16 deviceID, const DeviceProxy::Pointer& proxy){
|
||||||
proxy->_name += " (" + QString::number(deviceID) + ")";
|
proxy->_name += " (" + QString::number(deviceID) + ")";
|
||||||
_registeredDevices[deviceID] = proxy;
|
_registeredDevices[deviceID] = proxy;
|
||||||
qCDebug(userInputMapper) << "Registered input device <" << proxy->_name << "> deviceID = " << deviceID;
|
qCDebug(controllers) << "Registered input device <" << proxy->_name << "> deviceID = " << deviceID;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,7 +113,7 @@ UserInputMapper::Input UserInputMapper::findDeviceInput(const QString& inputName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
qCDebug(userInputMapper) << "Couldn\'t find InputChannel named <" << inputName << "> for device <" << deviceName << ">";
|
qCDebug(controllers) << "Couldn\'t find InputChannel named <" << inputName << "> for device <" << deviceName << ">";
|
||||||
|
|
||||||
} else if (deviceName == "Actions") {
|
} else if (deviceName == "Actions") {
|
||||||
deviceID = Input::ACTIONS_DEVICE;
|
deviceID = Input::ACTIONS_DEVICE;
|
||||||
|
@ -127,13 +125,13 @@ UserInputMapper::Input UserInputMapper::findDeviceInput(const QString& inputName
|
||||||
actionNum++;
|
actionNum++;
|
||||||
}
|
}
|
||||||
|
|
||||||
qCDebug(userInputMapper) << "Couldn\'t find ActionChannel named <" << inputName << "> among actions";
|
qCDebug(controllers) << "Couldn\'t find ActionChannel named <" << inputName << "> among actions";
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
qCDebug(userInputMapper) << "Couldn\'t find InputDevice named <" << deviceName << ">";
|
qCDebug(controllers) << "Couldn\'t find InputDevice named <" << deviceName << ">";
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
qCDebug(userInputMapper) << "Couldn\'t understand <" << inputName << "> as a valid inputDevice.inputName";
|
qCDebug(controllers) << "Couldn\'t understand <" << inputName << "> as a valid inputDevice.inputName";
|
||||||
}
|
}
|
||||||
|
|
||||||
return Input();
|
return Input();
|
||||||
|
@ -364,12 +362,12 @@ void UserInputMapper::assignDefaulActionScales() {
|
||||||
_actionStates[SHIFT] = 1.0f; // on
|
_actionStates[SHIFT] = 1.0f; // on
|
||||||
_actionStates[ACTION1] = 1.0f; // default
|
_actionStates[ACTION1] = 1.0f; // default
|
||||||
_actionStates[ACTION2] = 1.0f; // default
|
_actionStates[ACTION2] = 1.0f; // default
|
||||||
_actionStates[TranslateX] = 1.0f; // default
|
_actionStates[TRANSLATE_X] = 1.0f; // default
|
||||||
_actionStates[TranslateY] = 1.0f; // default
|
_actionStates[TRANSLATE_Y] = 1.0f; // default
|
||||||
_actionStates[TranslateZ] = 1.0f; // default
|
_actionStates[TRANSLATE_Z] = 1.0f; // default
|
||||||
_actionStates[Roll] = 1.0f; // default
|
_actionStates[ROLL] = 1.0f; // default
|
||||||
_actionStates[Pitch] = 1.0f; // default
|
_actionStates[PITCH] = 1.0f; // default
|
||||||
_actionStates[Yaw] = 1.0f; // default
|
_actionStates[YAW] = 1.0f; // default
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is only necessary as long as the actions are hardcoded
|
// This is only necessary as long as the actions are hardcoded
|
||||||
|
@ -396,12 +394,12 @@ void UserInputMapper::createActionNames() {
|
||||||
_actionNames[ACTION2] = "ACTION2";
|
_actionNames[ACTION2] = "ACTION2";
|
||||||
_actionNames[CONTEXT_MENU] = "CONTEXT_MENU";
|
_actionNames[CONTEXT_MENU] = "CONTEXT_MENU";
|
||||||
_actionNames[TOGGLE_MUTE] = "TOGGLE_MUTE";
|
_actionNames[TOGGLE_MUTE] = "TOGGLE_MUTE";
|
||||||
_actionNames[TranslateX] = "TranslateX";
|
_actionNames[TRANSLATE_X] = "TranslateX";
|
||||||
_actionNames[TranslateY] = "TranslateY";
|
_actionNames[TRANSLATE_Y] = "TranslateY";
|
||||||
_actionNames[TranslateZ] = "TranslateZ";
|
_actionNames[TRANSLATE_Z] = "TranslateZ";
|
||||||
_actionNames[Roll] = "Roll";
|
_actionNames[ROLL] = "Roll";
|
||||||
_actionNames[Pitch] = "Pitch";
|
_actionNames[PITCH] = "Pitch";
|
||||||
_actionNames[Yaw] = "Yaw";
|
_actionNames[YAW] = "Yaw";
|
||||||
}
|
}
|
||||||
|
|
||||||
void UserInputMapper::registerStandardDevice() {
|
void UserInputMapper::registerStandardDevice() {
|
||||||
|
@ -423,4 +421,4 @@ float UserInputMapper::DeviceProxy::getValue(const Input& input, int timestamp)
|
||||||
default:
|
default:
|
||||||
return 0.0f;
|
return 0.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
56
libraries/input-plugins/src/input-plugins/UserInputMapper.h → libraries/controllers/src/controllers/UserInputMapper.h
Executable file → Normal file
56
libraries/input-plugins/src/input-plugins/UserInputMapper.h → libraries/controllers/src/controllers/UserInputMapper.h
Executable file → Normal file
|
@ -152,44 +152,52 @@ public:
|
||||||
// Actions are the output channels of the Mapper, that's what the InputChannel map to
|
// Actions are the output channels of the Mapper, that's what the InputChannel map to
|
||||||
// For now the Actions are hardcoded, this is bad, but we will fix that in the near future
|
// For now the Actions are hardcoded, this is bad, but we will fix that in the near future
|
||||||
enum Action {
|
enum Action {
|
||||||
LONGITUDINAL_BACKWARD = 0,
|
TRANSLATE_X = 0,
|
||||||
LONGITUDINAL_FORWARD,
|
TRANSLATE_Y,
|
||||||
|
TRANSLATE_Z,
|
||||||
|
ROTATE_X, PITCH = ROTATE_X,
|
||||||
|
ROTATE_Y, YAW = ROTATE_Y,
|
||||||
|
ROTATE_Z, ROLL = ROTATE_Z,
|
||||||
|
|
||||||
LATERAL_LEFT,
|
TRANSLATE_CAMERA_Z,
|
||||||
LATERAL_RIGHT,
|
|
||||||
|
|
||||||
VERTICAL_DOWN,
|
|
||||||
VERTICAL_UP,
|
|
||||||
|
|
||||||
YAW_LEFT,
|
|
||||||
YAW_RIGHT,
|
|
||||||
|
|
||||||
PITCH_DOWN,
|
|
||||||
PITCH_UP,
|
|
||||||
|
|
||||||
BOOM_IN,
|
|
||||||
BOOM_OUT,
|
|
||||||
|
|
||||||
LEFT_HAND,
|
LEFT_HAND,
|
||||||
RIGHT_HAND,
|
RIGHT_HAND,
|
||||||
|
|
||||||
LEFT_HAND_CLICK,
|
LEFT_HAND_CLICK,
|
||||||
RIGHT_HAND_CLICK,
|
RIGHT_HAND_CLICK,
|
||||||
|
|
||||||
SHIFT,
|
|
||||||
|
|
||||||
ACTION1,
|
ACTION1,
|
||||||
ACTION2,
|
ACTION2,
|
||||||
|
|
||||||
CONTEXT_MENU,
|
CONTEXT_MENU,
|
||||||
TOGGLE_MUTE,
|
TOGGLE_MUTE,
|
||||||
|
|
||||||
TranslateX,
|
SHIFT,
|
||||||
TranslateY,
|
|
||||||
TranslateZ,
|
// Biseced aliases for TRANSLATE_Z
|
||||||
Roll,
|
LONGITUDINAL_BACKWARD,
|
||||||
Pitch,
|
LONGITUDINAL_FORWARD,
|
||||||
Yaw,
|
|
||||||
|
// Biseced aliases for TRANSLATE_X
|
||||||
|
LATERAL_LEFT,
|
||||||
|
LATERAL_RIGHT,
|
||||||
|
|
||||||
|
// Biseced aliases for TRANSLATE_Y
|
||||||
|
VERTICAL_DOWN,
|
||||||
|
VERTICAL_UP,
|
||||||
|
|
||||||
|
// Biseced aliases for ROTATE_Y
|
||||||
|
YAW_LEFT,
|
||||||
|
YAW_RIGHT,
|
||||||
|
|
||||||
|
// Biseced aliases for ROTATE_X
|
||||||
|
PITCH_DOWN,
|
||||||
|
PITCH_UP,
|
||||||
|
|
||||||
|
// Biseced aliases for TRANSLATE_CAMERA_Z
|
||||||
|
BOOM_IN,
|
||||||
|
BOOM_OUT,
|
||||||
|
|
||||||
NUM_ACTIONS,
|
NUM_ACTIONS,
|
||||||
};
|
};
|
|
@ -15,7 +15,7 @@
|
||||||
#include <QJSonArray>
|
#include <QJSonArray>
|
||||||
|
|
||||||
#include "RouteBuilderProxy.h"
|
#include "RouteBuilderProxy.h"
|
||||||
#include "../NewControllerScriptingInterface.h"
|
#include "../ScriptingInterface.h"
|
||||||
#include "../Logging.h"
|
#include "../Logging.h"
|
||||||
|
|
||||||
using namespace controller;
|
using namespace controller;
|
||||||
|
|
|
@ -21,12 +21,14 @@ class QJsonValue;
|
||||||
|
|
||||||
namespace controller {
|
namespace controller {
|
||||||
|
|
||||||
class NewControllerScriptingInterface;
|
class ScriptingInterface;
|
||||||
|
|
||||||
|
// TODO migrate functionality to a MappingBuilder class and make the proxy defer to that
|
||||||
|
// (for easier use in both C++ and JS)
|
||||||
class MappingBuilderProxy : public QObject {
|
class MappingBuilderProxy : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
MappingBuilderProxy(NewControllerScriptingInterface& parent, Mapping::Pointer mapping)
|
MappingBuilderProxy(ScriptingInterface& parent, Mapping::Pointer mapping)
|
||||||
: _parent(parent), _mapping(mapping) { }
|
: _parent(parent), _mapping(mapping) { }
|
||||||
|
|
||||||
Q_INVOKABLE QObject* from(const QJSValue& source);
|
Q_INVOKABLE QObject* from(const QJSValue& source);
|
||||||
|
@ -48,7 +50,7 @@ protected:
|
||||||
QObject* from(const Endpoint::Pointer& source);
|
QObject* from(const Endpoint::Pointer& source);
|
||||||
|
|
||||||
friend class RouteBuilderProxy;
|
friend class RouteBuilderProxy;
|
||||||
NewControllerScriptingInterface& _parent;
|
ScriptingInterface& _parent;
|
||||||
Mapping::Pointer _mapping;
|
Mapping::Pointer _mapping;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
#include <GLMHelpers.h>
|
#include <GLMHelpers.h>
|
||||||
|
|
||||||
#include "MappingBuilderProxy.h"
|
#include "MappingBuilderProxy.h"
|
||||||
#include "../NewControllerScriptingInterface.h"
|
#include "../ScriptingInterface.h"
|
||||||
#include "../Logging.h"
|
#include "../Logging.h"
|
||||||
|
|
||||||
namespace controller {
|
namespace controller {
|
||||||
|
|
|
@ -20,12 +20,14 @@ class QJsonValue;
|
||||||
|
|
||||||
namespace controller {
|
namespace controller {
|
||||||
|
|
||||||
class NewControllerScriptingInterface;
|
class ScriptingInterface;
|
||||||
|
|
||||||
|
// TODO migrate functionality to a RouteBuilder class and make the proxy defer to that
|
||||||
|
// (for easier use in both C++ and JS)
|
||||||
class RouteBuilderProxy : public QObject {
|
class RouteBuilderProxy : public QObject {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
RouteBuilderProxy(NewControllerScriptingInterface& parent, Mapping::Pointer mapping, Route::Pointer route)
|
RouteBuilderProxy(ScriptingInterface& parent, Mapping::Pointer mapping, Route::Pointer route)
|
||||||
: _parent(parent), _mapping(mapping), _route(route) { }
|
: _parent(parent), _mapping(mapping), _route(route) { }
|
||||||
|
|
||||||
Q_INVOKABLE void to(const QJSValue& destination);
|
Q_INVOKABLE void to(const QJSValue& destination);
|
||||||
|
@ -52,7 +54,7 @@ class RouteBuilderProxy : public QObject {
|
||||||
Mapping::Pointer _mapping;
|
Mapping::Pointer _mapping;
|
||||||
Route::Pointer _route;
|
Route::Pointer _route;
|
||||||
|
|
||||||
NewControllerScriptingInterface& _parent;
|
ScriptingInterface& _parent;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
set(TARGET_NAME entities-renderer)
|
set(TARGET_NAME entities-renderer)
|
||||||
AUTOSCRIBE_SHADER_LIB(gpu model render render-utils)
|
AUTOSCRIBE_SHADER_LIB(gpu model render render-utils)
|
||||||
setup_hifi_library(Widgets Network Script)
|
setup_hifi_library(Widgets Network Script)
|
||||||
link_hifi_libraries(shared gpu procedural model model-networking script-engine render render-utils)
|
link_hifi_libraries(shared gpu procedural model model-networking script-engine controllers render render-utils)
|
||||||
|
|
||||||
target_bullet()
|
target_bullet()
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
set(TARGET_NAME input-plugins)
|
set(TARGET_NAME input-plugins)
|
||||||
setup_hifi_library()
|
setup_hifi_library()
|
||||||
link_hifi_libraries(shared plugins gpu render-utils)
|
link_hifi_libraries(shared plugins controllers)
|
||||||
|
|
||||||
GroupSources("src/input-plugins")
|
GroupSources("src/input-plugins")
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ InputPluginList getInputPlugins() {
|
||||||
new KeyboardMouseDevice(),
|
new KeyboardMouseDevice(),
|
||||||
new SDL2Manager(),
|
new SDL2Manager(),
|
||||||
new SixenseManager(),
|
new SixenseManager(),
|
||||||
//new ViveControllerManager(),
|
new ViveControllerManager(),
|
||||||
nullptr
|
nullptr
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,167 +1,164 @@
|
||||||
//
|
//
|
||||||
// Joystick.cpp
|
// Joystick.cpp
|
||||||
// input-plugins/src/input-plugins
|
// input-plugins/src/input-plugins
|
||||||
//
|
//
|
||||||
// Created by Stephen Birarda on 2014-09-23.
|
// Created by Stephen Birarda on 2014-09-23.
|
||||||
// Copyright 2014 High Fidelity, Inc.
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
//
|
//
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <limits>
|
#include "Joystick.h"
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
#include <limits>
|
||||||
|
#include <glm/glm.hpp>
|
||||||
#include "Joystick.h"
|
|
||||||
|
const float CONTROLLER_THRESHOLD = 0.3f;
|
||||||
#include "StandardControls.h"
|
|
||||||
|
#ifdef HAVE_SDL2
|
||||||
const float CONTROLLER_THRESHOLD = 0.3f;
|
const float MAX_AXIS = 32768.0f;
|
||||||
|
|
||||||
#ifdef HAVE_SDL2
|
Joystick::Joystick(SDL_JoystickID instanceId, const QString& name, SDL_GameController* sdlGameController) :
|
||||||
const float MAX_AXIS = 32768.0f;
|
InputDevice(name),
|
||||||
|
_sdlGameController(sdlGameController),
|
||||||
Joystick::Joystick(SDL_JoystickID instanceId, const QString& name, SDL_GameController* sdlGameController) :
|
_sdlJoystick(SDL_GameControllerGetJoystick(_sdlGameController)),
|
||||||
InputDevice(name),
|
_instanceId(instanceId)
|
||||||
_sdlGameController(sdlGameController),
|
{
|
||||||
_sdlJoystick(SDL_GameControllerGetJoystick(_sdlGameController)),
|
|
||||||
_instanceId(instanceId)
|
}
|
||||||
{
|
|
||||||
|
#endif
|
||||||
}
|
|
||||||
|
Joystick::~Joystick() {
|
||||||
#endif
|
closeJoystick();
|
||||||
|
}
|
||||||
Joystick::~Joystick() {
|
|
||||||
closeJoystick();
|
void Joystick::closeJoystick() {
|
||||||
}
|
#ifdef HAVE_SDL2
|
||||||
|
SDL_GameControllerClose(_sdlGameController);
|
||||||
void Joystick::closeJoystick() {
|
#endif
|
||||||
#ifdef HAVE_SDL2
|
}
|
||||||
SDL_GameControllerClose(_sdlGameController);
|
|
||||||
#endif
|
void Joystick::update(float deltaTime, bool jointsCaptured) {
|
||||||
}
|
for (auto axisState : _axisStateMap) {
|
||||||
|
if (fabsf(axisState.second) < CONTROLLER_THRESHOLD) {
|
||||||
void Joystick::update(float deltaTime, bool jointsCaptured) {
|
_axisStateMap[axisState.first] = 0.0f;
|
||||||
for (auto axisState : _axisStateMap) {
|
}
|
||||||
if (fabsf(axisState.second) < CONTROLLER_THRESHOLD) {
|
}
|
||||||
_axisStateMap[axisState.first] = 0.0f;
|
}
|
||||||
}
|
|
||||||
}
|
void Joystick::focusOutEvent() {
|
||||||
}
|
_axisStateMap.clear();
|
||||||
|
_buttonPressedMap.clear();
|
||||||
void Joystick::focusOutEvent() {
|
};
|
||||||
_axisStateMap.clear();
|
|
||||||
_buttonPressedMap.clear();
|
#ifdef HAVE_SDL2
|
||||||
};
|
|
||||||
|
void Joystick::handleAxisEvent(const SDL_ControllerAxisEvent& event) {
|
||||||
#ifdef HAVE_SDL2
|
SDL_GameControllerAxis axis = (SDL_GameControllerAxis) event.axis;
|
||||||
|
_axisStateMap[makeInput((controller::StandardAxisChannel)axis).getChannel()] = (float)event.value / MAX_AXIS;
|
||||||
void Joystick::handleAxisEvent(const SDL_ControllerAxisEvent& event) {
|
}
|
||||||
SDL_GameControllerAxis axis = (SDL_GameControllerAxis) event.axis;
|
|
||||||
_axisStateMap[makeInput((Controllers::StandardAxisChannel)axis).getChannel()] = (float)event.value / MAX_AXIS;
|
void Joystick::handleButtonEvent(const SDL_ControllerButtonEvent& event) {
|
||||||
}
|
auto input = makeInput((controller::StandardButtonChannel)event.button);
|
||||||
|
bool newValue = event.state == SDL_PRESSED;
|
||||||
void Joystick::handleButtonEvent(const SDL_ControllerButtonEvent& event) {
|
if (newValue) {
|
||||||
auto input = makeInput((Controllers::StandardButtonChannel)event.button);
|
_buttonPressedMap.insert(input.getChannel());
|
||||||
bool newValue = event.state == SDL_PRESSED;
|
} else {
|
||||||
if (newValue) {
|
_buttonPressedMap.erase(input.getChannel());
|
||||||
_buttonPressedMap.insert(input.getChannel());
|
}
|
||||||
} else {
|
}
|
||||||
_buttonPressedMap.erase(input.getChannel());
|
|
||||||
}
|
#endif
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
void Joystick::registerToUserInputMapper(UserInputMapper& mapper) {
|
||||||
|
// Grab the current free device ID
|
||||||
|
_deviceID = mapper.getFreeDeviceID();
|
||||||
void Joystick::registerToUserInputMapper(UserInputMapper& mapper) {
|
|
||||||
// Grab the current free device ID
|
auto proxy = std::make_shared<UserInputMapper::DeviceProxy>(_name);
|
||||||
_deviceID = mapper.getFreeDeviceID();
|
proxy->getButton = [this] (const UserInputMapper::Input& input, int timestamp) -> bool { return this->getButton(input.getChannel()); };
|
||||||
|
proxy->getAxis = [this] (const UserInputMapper::Input& input, int timestamp) -> float { return this->getAxis(input.getChannel()); };
|
||||||
auto proxy = std::make_shared<UserInputMapper::DeviceProxy>(_name);
|
proxy->getAvailabeInputs = [this] () -> QVector<UserInputMapper::InputPair> {
|
||||||
proxy->getButton = [this] (const UserInputMapper::Input& input, int timestamp) -> bool { return this->getButton(input.getChannel()); };
|
QVector<UserInputMapper::InputPair> availableInputs;
|
||||||
proxy->getAxis = [this] (const UserInputMapper::Input& input, int timestamp) -> float { return this->getAxis(input.getChannel()); };
|
// Buttons
|
||||||
proxy->getAvailabeInputs = [this] () -> QVector<UserInputMapper::InputPair> {
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::A), "A"));
|
||||||
QVector<UserInputMapper::InputPair> availableInputs;
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::B), "B"));
|
||||||
// Buttons
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::X), "X"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::A), "A"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::Y), "Y"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::B), "B"));
|
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::X), "X"));
|
// DPad
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::Y), "Y"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::DU), "DU"));
|
||||||
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::DD), "DD"));
|
||||||
// DPad
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::DL), "DL"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::DU), "DU"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::DR), "DR"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::DD), "DD"));
|
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::DL), "DL"));
|
// Bumpers
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::DR), "DR"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::LB), "LB"));
|
||||||
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::RB), "RB"));
|
||||||
// Bumpers
|
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::LB), "LB"));
|
// Stick press
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::RB), "RB"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::LS), "LS"));
|
||||||
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::RS), "RS"));
|
||||||
// Stick press
|
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::LS), "LS"));
|
// Center buttons
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::RS), "RS"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::START), "Start"));
|
||||||
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::BACK), "Back"));
|
||||||
// Center buttons
|
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::START), "Start"));
|
// Analog sticks
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::BACK), "Back"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::LY), "LY"));
|
||||||
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::LX), "LX"));
|
||||||
// Analog sticks
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::RY), "RY"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::LY), "LY"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::RX), "RX"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::LX), "LX"));
|
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::RY), "RY"));
|
// Triggers
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::RX), "RX"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::LT), "LT"));
|
||||||
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::RT), "RT"));
|
||||||
// Triggers
|
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::LT), "LT"));
|
// Aliases, PlayStation style names
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::RT), "RT"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::LB), "L1"));
|
||||||
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::RB), "R1"));
|
||||||
// Aliases, PlayStation style names
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::LT), "L2"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::LB), "L1"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::RT), "R2"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::RB), "R1"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::LS), "L3"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::LT), "L2"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::RS), "R3"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::RT), "R2"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::BACK), "Select"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::LS), "L3"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::A), "Cross"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::RS), "R3"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::B), "Circle"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::BACK), "Select"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::X), "Square"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::A), "Cross"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::Y), "Triangle"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::B), "Circle"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::DU), "Up"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::X), "Square"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::DD), "Down"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::Y), "Triangle"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::DL), "Left"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::DU), "Up"));
|
availableInputs.append(UserInputMapper::InputPair(makeInput(controller::DR), "Right"));
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::DD), "Down"));
|
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::DL), "Left"));
|
return availableInputs;
|
||||||
availableInputs.append(UserInputMapper::InputPair(makeInput(Controllers::DR), "Right"));
|
};
|
||||||
|
proxy->resetDeviceBindings = [this, &mapper] () -> bool {
|
||||||
return availableInputs;
|
mapper.removeAllInputChannelsForDevice(_deviceID);
|
||||||
};
|
this->assignDefaultInputMapping(mapper);
|
||||||
proxy->resetDeviceBindings = [this, &mapper] () -> bool {
|
return true;
|
||||||
mapper.removeAllInputChannelsForDevice(_deviceID);
|
};
|
||||||
this->assignDefaultInputMapping(mapper);
|
mapper.registerDevice(_deviceID, proxy);
|
||||||
return true;
|
}
|
||||||
};
|
|
||||||
mapper.registerDevice(_deviceID, proxy);
|
void Joystick::assignDefaultInputMapping(UserInputMapper& mapper) {
|
||||||
}
|
#ifdef HAVE_SDL2
|
||||||
|
const float JOYSTICK_MOVE_SPEED = 1.0f;
|
||||||
void Joystick::assignDefaultInputMapping(UserInputMapper& mapper) {
|
const float DPAD_MOVE_SPEED = 0.5f;
|
||||||
#ifdef HAVE_SDL2
|
const float JOYSTICK_YAW_SPEED = 0.5f;
|
||||||
const float JOYSTICK_MOVE_SPEED = 1.0f;
|
const float JOYSTICK_PITCH_SPEED = 0.25f;
|
||||||
const float DPAD_MOVE_SPEED = 0.5f;
|
const float BOOM_SPEED = 0.1f;
|
||||||
const float JOYSTICK_YAW_SPEED = 0.5f;
|
|
||||||
const float JOYSTICK_PITCH_SPEED = 0.25f;
|
#endif
|
||||||
const float BOOM_SPEED = 0.1f;
|
}
|
||||||
|
|
||||||
#endif
|
UserInputMapper::Input Joystick::makeInput(controller::StandardButtonChannel button) {
|
||||||
}
|
return UserInputMapper::Input(_deviceID, button, UserInputMapper::ChannelType::BUTTON);
|
||||||
|
}
|
||||||
UserInputMapper::Input Joystick::makeInput(Controllers::StandardButtonChannel button) {
|
|
||||||
return UserInputMapper::Input(_deviceID, button, UserInputMapper::ChannelType::BUTTON);
|
UserInputMapper::Input Joystick::makeInput(controller::StandardAxisChannel axis) {
|
||||||
}
|
return UserInputMapper::Input(_deviceID, axis, UserInputMapper::ChannelType::AXIS);
|
||||||
|
}
|
||||||
UserInputMapper::Input Joystick::makeInput(Controllers::StandardAxisChannel axis) {
|
|
||||||
return UserInputMapper::Input(_deviceID, axis, UserInputMapper::ChannelType::AXIS);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
|
@ -1,73 +1,73 @@
|
||||||
//
|
//
|
||||||
// Joystick.h
|
// Joystick.h
|
||||||
// input-plugins/src/input-plugins
|
// input-plugins/src/input-plugins
|
||||||
//
|
//
|
||||||
// Created by Stephen Birarda on 2014-09-23.
|
// Created by Stephen Birarda on 2014-09-23.
|
||||||
// Copyright 2014 High Fidelity, Inc.
|
// Copyright 2014 High Fidelity, Inc.
|
||||||
//
|
//
|
||||||
// Distributed under the Apache License, Version 2.0.
|
// Distributed under the Apache License, Version 2.0.
|
||||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
//
|
//
|
||||||
|
|
||||||
#ifndef hifi_Joystick_h
|
#ifndef hifi_Joystick_h
|
||||||
#define hifi_Joystick_h
|
#define hifi_Joystick_h
|
||||||
|
|
||||||
#include <qobject.h>
|
#include <qobject.h>
|
||||||
#include <qvector.h>
|
#include <qvector.h>
|
||||||
|
|
||||||
#ifdef HAVE_SDL2
|
#ifdef HAVE_SDL2
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#undef main
|
#undef main
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "InputDevice.h"
|
#include <controllers/InputDevice.h>
|
||||||
#include "StandardControls.h"
|
#include <controllers/StandardControls.h>
|
||||||
|
|
||||||
class Joystick : public QObject, public InputDevice {
|
class Joystick : public QObject, public InputDevice {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(QString name READ getName)
|
Q_PROPERTY(QString name READ getName)
|
||||||
|
|
||||||
#ifdef HAVE_SDL2
|
#ifdef HAVE_SDL2
|
||||||
Q_PROPERTY(int instanceId READ getInstanceId)
|
Q_PROPERTY(int instanceId READ getInstanceId)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
const QString& getName() const { return _name; }
|
const QString& getName() const { return _name; }
|
||||||
|
|
||||||
// Device functions
|
// Device functions
|
||||||
virtual void registerToUserInputMapper(UserInputMapper& mapper) override;
|
virtual void registerToUserInputMapper(UserInputMapper& mapper) override;
|
||||||
virtual void assignDefaultInputMapping(UserInputMapper& mapper) override;
|
virtual void assignDefaultInputMapping(UserInputMapper& mapper) override;
|
||||||
virtual void update(float deltaTime, bool jointsCaptured) override;
|
virtual void update(float deltaTime, bool jointsCaptured) override;
|
||||||
virtual void focusOutEvent() override;
|
virtual void focusOutEvent() override;
|
||||||
|
|
||||||
Joystick() : InputDevice("Joystick") {}
|
Joystick() : InputDevice("Joystick") {}
|
||||||
~Joystick();
|
~Joystick();
|
||||||
|
|
||||||
UserInputMapper::Input makeInput(Controllers::StandardButtonChannel button);
|
UserInputMapper::Input makeInput(controller::StandardButtonChannel button);
|
||||||
UserInputMapper::Input makeInput(Controllers::StandardAxisChannel axis);
|
UserInputMapper::Input makeInput(controller::StandardAxisChannel axis);
|
||||||
|
|
||||||
#ifdef HAVE_SDL2
|
#ifdef HAVE_SDL2
|
||||||
Joystick(SDL_JoystickID instanceId, const QString& name, SDL_GameController* sdlGameController);
|
Joystick(SDL_JoystickID instanceId, const QString& name, SDL_GameController* sdlGameController);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void closeJoystick();
|
void closeJoystick();
|
||||||
|
|
||||||
#ifdef HAVE_SDL2
|
#ifdef HAVE_SDL2
|
||||||
void handleAxisEvent(const SDL_ControllerAxisEvent& event);
|
void handleAxisEvent(const SDL_ControllerAxisEvent& event);
|
||||||
void handleButtonEvent(const SDL_ControllerButtonEvent& event);
|
void handleButtonEvent(const SDL_ControllerButtonEvent& event);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_SDL2
|
#ifdef HAVE_SDL2
|
||||||
int getInstanceId() const { return _instanceId; }
|
int getInstanceId() const { return _instanceId; }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef HAVE_SDL2
|
#ifdef HAVE_SDL2
|
||||||
SDL_GameController* _sdlGameController;
|
SDL_GameController* _sdlGameController;
|
||||||
SDL_Joystick* _sdlJoystick;
|
SDL_Joystick* _sdlJoystick;
|
||||||
SDL_JoystickID _instanceId;
|
SDL_JoystickID _instanceId;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_Joystick_h
|
#endif // hifi_Joystick_h
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
|
|
||||||
#include <QtCore/QPoint>
|
#include <QtCore/QPoint>
|
||||||
|
|
||||||
#include "InputDevice.h"
|
#include <controllers/InputDevice.h>
|
||||||
#include "InputPlugin.h"
|
#include "InputPlugin.h"
|
||||||
|
|
||||||
class QTouchEvent;
|
class QTouchEvent;
|
||||||
|
|
|
@ -16,9 +16,9 @@
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "InputPlugin.h"
|
#include <controllers/UserInputMapper.h>
|
||||||
#include "UserInputMapper.h"
|
|
||||||
|
|
||||||
|
#include "InputPlugin.h"
|
||||||
#include "Joystick.h"
|
#include "Joystick.h"
|
||||||
|
|
||||||
class SDL2Manager : public InputPlugin {
|
class SDL2Manager : public InputPlugin {
|
||||||
|
|
|
@ -24,8 +24,9 @@
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <controllers/InputDevice.h>
|
||||||
|
|
||||||
#include "InputPlugin.h"
|
#include "InputPlugin.h"
|
||||||
#include "InputDevice.h"
|
|
||||||
|
|
||||||
class QLibrary;
|
class QLibrary;
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@
|
||||||
|
|
||||||
#include <model/Geometry.h>
|
#include <model/Geometry.h>
|
||||||
#include <gpu/Texture.h>
|
#include <gpu/Texture.h>
|
||||||
#include "InputDevice.h"
|
#include <controllers/InputDevice.h>
|
||||||
#include "InputPlugin.h"
|
#include "InputPlugin.h"
|
||||||
#include <RenderArgs.h>
|
#include <RenderArgs.h>
|
||||||
#include <render/Scene.h>
|
#include <render/Scene.h>
|
||||||
|
|
|
@ -24,7 +24,7 @@ void AssetResourceRequest::doSend() {
|
||||||
// Make request to atp
|
// Make request to atp
|
||||||
auto assetClient = DependencyManager::get<AssetClient>();
|
auto assetClient = DependencyManager::get<AssetClient>();
|
||||||
auto parts = _url.path().split(".", QString::SkipEmptyParts);
|
auto parts = _url.path().split(".", QString::SkipEmptyParts);
|
||||||
auto hash = parts[0];
|
auto hash = parts.length() > 0 ? parts[0] : "";
|
||||||
auto extension = parts.length() > 1 ? parts[1] : "";
|
auto extension = parts.length() > 1 ? parts[1] : "";
|
||||||
|
|
||||||
if (hash.length() != SHA256_HASH_HEX_LENGTH) {
|
if (hash.length() != SHA256_HASH_HEX_LENGTH) {
|
||||||
|
|
|
@ -1,3 +1,3 @@
|
||||||
set(TARGET_NAME script-engine)
|
set(TARGET_NAME script-engine)
|
||||||
setup_hifi_library(Gui Network Script WebSockets Widgets)
|
setup_hifi_library(Gui Network Script WebSockets Widgets)
|
||||||
link_hifi_libraries(shared networking octree gpu procedural model model-networking fbx entities animation audio physics)
|
link_hifi_libraries(shared networking octree gpu procedural model model-networking fbx entities controllers animation audio physics)
|
||||||
|
|
|
@ -1,125 +0,0 @@
|
||||||
//
|
|
||||||
// AbstractControllerScriptingInterface.h
|
|
||||||
// libraries/script-engine/src
|
|
||||||
//
|
|
||||||
// Created by Brad Hefta-Gaub on 12/17/13.
|
|
||||||
// Copyright 2013 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
|
|
||||||
//
|
|
||||||
|
|
||||||
#ifndef hifi_AbstractControllerScriptingInterface_h
|
|
||||||
#define hifi_AbstractControllerScriptingInterface_h
|
|
||||||
|
|
||||||
#include <QtCore/QObject>
|
|
||||||
|
|
||||||
#include <glm/glm.hpp>
|
|
||||||
#include <glm/gtc/quaternion.hpp>
|
|
||||||
|
|
||||||
#include "HFActionEvent.h"
|
|
||||||
#include "KeyEvent.h"
|
|
||||||
#include "MouseEvent.h"
|
|
||||||
#include "SpatialEvent.h"
|
|
||||||
#include "TouchEvent.h"
|
|
||||||
#include "WheelEvent.h"
|
|
||||||
|
|
||||||
class ScriptEngine;
|
|
||||||
|
|
||||||
class AbstractInputController : public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
typedef unsigned int Key;
|
|
||||||
|
|
||||||
virtual void update() = 0;
|
|
||||||
|
|
||||||
virtual Key getKey() const = 0;
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
|
|
||||||
virtual bool isActive() const = 0;
|
|
||||||
virtual glm::vec3 getAbsTranslation() const = 0;
|
|
||||||
virtual glm::quat getAbsRotation() const = 0;
|
|
||||||
virtual glm::vec3 getLocTranslation() const = 0;
|
|
||||||
virtual glm::quat getLocRotation() const = 0;
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void spatialEvent(const SpatialEvent& event);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
/// handles scripting of input controller commands from JS
|
|
||||||
class AbstractControllerScriptingInterface : public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
virtual void registerControllerTypes(ScriptEngine* engine) = 0;
|
|
||||||
|
|
||||||
virtual bool isPrimaryButtonPressed() const = 0;
|
|
||||||
virtual glm::vec2 getPrimaryJoystickPosition() const = 0;
|
|
||||||
|
|
||||||
virtual int getNumberOfButtons() const = 0;
|
|
||||||
virtual bool isButtonPressed(int buttonIndex) const = 0;
|
|
||||||
|
|
||||||
virtual int getNumberOfTriggers() const = 0;
|
|
||||||
virtual float getTriggerValue(int triggerIndex) const = 0;
|
|
||||||
|
|
||||||
virtual int getNumberOfJoysticks() const = 0;
|
|
||||||
virtual glm::vec2 getJoystickPosition(int joystickIndex) const = 0;
|
|
||||||
|
|
||||||
virtual int getNumberOfSpatialControls() const = 0;
|
|
||||||
virtual glm::vec3 getSpatialControlPosition(int controlIndex) const = 0;
|
|
||||||
virtual glm::vec3 getSpatialControlVelocity(int controlIndex) const = 0;
|
|
||||||
virtual glm::vec3 getSpatialControlNormal(int controlIndex) const = 0;
|
|
||||||
virtual glm::quat getSpatialControlRawRotation(int controlIndex) const = 0;
|
|
||||||
|
|
||||||
virtual void captureKeyEvents(const KeyEvent& event) = 0;
|
|
||||||
virtual void releaseKeyEvents(const KeyEvent& event) = 0;
|
|
||||||
|
|
||||||
virtual void captureMouseEvents() = 0;
|
|
||||||
virtual void releaseMouseEvents() = 0;
|
|
||||||
|
|
||||||
virtual void captureTouchEvents() = 0;
|
|
||||||
virtual void releaseTouchEvents() = 0;
|
|
||||||
|
|
||||||
virtual void captureWheelEvents() = 0;
|
|
||||||
virtual void releaseWheelEvents() = 0;
|
|
||||||
|
|
||||||
virtual void captureActionEvents() = 0;
|
|
||||||
virtual void releaseActionEvents() = 0;
|
|
||||||
|
|
||||||
virtual void captureJoystick(int joystickIndex) = 0;
|
|
||||||
virtual void releaseJoystick(int joystickIndex) = 0;
|
|
||||||
|
|
||||||
virtual glm::vec2 getViewportDimensions() const = 0;
|
|
||||||
|
|
||||||
|
|
||||||
virtual AbstractInputController* createInputController( const QString& category, const QString& tracker ) = 0;
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void keyPressEvent(const KeyEvent& event);
|
|
||||||
void keyReleaseEvent(const KeyEvent& event);
|
|
||||||
|
|
||||||
void actionStartEvent(const HFActionEvent& event);
|
|
||||||
void actionEndEvent(const HFActionEvent& event);
|
|
||||||
|
|
||||||
void backStartEvent();
|
|
||||||
void backEndEvent();
|
|
||||||
|
|
||||||
void mouseMoveEvent(const MouseEvent& event, unsigned int deviceID = 0);
|
|
||||||
void mousePressEvent(const MouseEvent& event, unsigned int deviceID = 0);
|
|
||||||
void mouseDoublePressEvent(const MouseEvent& event, unsigned int deviceID = 0);
|
|
||||||
void mouseReleaseEvent(const MouseEvent& event, unsigned int deviceID = 0);
|
|
||||||
|
|
||||||
void touchBeginEvent(const TouchEvent& event);
|
|
||||||
void touchEndEvent(const TouchEvent& event);
|
|
||||||
void touchUpdateEvent(const TouchEvent& event);
|
|
||||||
|
|
||||||
void wheelEvent(const WheelEvent& event);
|
|
||||||
|
|
||||||
void actionEvent(int action, float state);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // hifi_AbstractControllerScriptingInterface_h
|
|
|
@ -12,7 +12,10 @@
|
||||||
#ifndef hifi_AbstractScriptingServicesInterface_h
|
#ifndef hifi_AbstractScriptingServicesInterface_h
|
||||||
#define hifi_AbstractScriptingServicesInterface_h
|
#define hifi_AbstractScriptingServicesInterface_h
|
||||||
|
|
||||||
class AbstractControllerScriptingInterface;
|
namespace controller {
|
||||||
|
class ScriptingInterface;
|
||||||
|
}
|
||||||
|
|
||||||
class Transform;
|
class Transform;
|
||||||
class ScriptEngine;
|
class ScriptEngine;
|
||||||
class QThread;
|
class QThread;
|
||||||
|
@ -22,7 +25,7 @@ class AbstractScriptingServicesInterface {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// Returns the controller interface for the application
|
/// Returns the controller interface for the application
|
||||||
virtual AbstractControllerScriptingInterface* getControllerScriptingInterface() = 0;
|
virtual controller::ScriptingInterface* getControllerScriptingInterface() = 0;
|
||||||
|
|
||||||
/// Registers application specific services with a script engine.
|
/// Registers application specific services with a script engine.
|
||||||
virtual void registerScriptEngineWithApplicationServices(ScriptEngine* scriptEngine) = 0;
|
virtual void registerScriptEngineWithApplicationServices(ScriptEngine* scriptEngine) = 0;
|
||||||
|
|
|
@ -76,16 +76,16 @@ void avatarDataFromScriptValue(const QScriptValue &object, AvatarData* &out) {
|
||||||
out = qobject_cast<AvatarData*>(object.toQObject());
|
out = qobject_cast<AvatarData*>(object.toQObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
QScriptValue inputControllerToScriptValue(QScriptEngine *engine, AbstractInputController* const &in) {
|
QScriptValue inputControllerToScriptValue(QScriptEngine *engine, controller::InputController* const &in) {
|
||||||
return engine->newQObject(in);
|
return engine->newQObject(in);
|
||||||
}
|
}
|
||||||
|
|
||||||
void inputControllerFromScriptValue(const QScriptValue &object, AbstractInputController* &out) {
|
void inputControllerFromScriptValue(const QScriptValue &object, controller::InputController* &out) {
|
||||||
out = qobject_cast<AbstractInputController*>(object.toQObject());
|
out = qobject_cast<controller::InputController*>(object.toQObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
ScriptEngine::ScriptEngine(const QString& scriptContents, const QString& fileNameString,
|
ScriptEngine::ScriptEngine(const QString& scriptContents, const QString& fileNameString,
|
||||||
AbstractControllerScriptingInterface* controllerScriptingInterface, bool wantSignals) :
|
controller::ScriptingInterface* controllerScriptingInterface, bool wantSignals) :
|
||||||
|
|
||||||
_scriptContents(scriptContents),
|
_scriptContents(scriptContents),
|
||||||
_isFinished(false),
|
_isFinished(false),
|
||||||
|
@ -93,7 +93,7 @@ ScriptEngine::ScriptEngine(const QString& scriptContents, const QString& fileNam
|
||||||
_isInitialized(false),
|
_isInitialized(false),
|
||||||
_timerFunctionMap(),
|
_timerFunctionMap(),
|
||||||
_wantSignals(wantSignals),
|
_wantSignals(wantSignals),
|
||||||
_controllerScriptingInterface(controllerScriptingInterface),
|
_controllerScriptingInterface(controllerScriptingInterface),
|
||||||
_fileNameString(fileNameString),
|
_fileNameString(fileNameString),
|
||||||
_quatLibrary(),
|
_quatLibrary(),
|
||||||
_vec3Library(),
|
_vec3Library(),
|
||||||
|
|
|
@ -26,8 +26,10 @@
|
||||||
#include <LimitedNodeList.h>
|
#include <LimitedNodeList.h>
|
||||||
#include <EntityItemID.h>
|
#include <EntityItemID.h>
|
||||||
#include <EntitiesScriptEngineProvider.h>
|
#include <EntitiesScriptEngineProvider.h>
|
||||||
|
#include <controllers/ScriptingInterface.h>
|
||||||
|
|
||||||
#include "AbstractControllerScriptingInterface.h"
|
|
||||||
|
#include "MouseEvent.h"
|
||||||
#include "ArrayBufferClass.h"
|
#include "ArrayBufferClass.h"
|
||||||
#include "AudioScriptingInterface.h"
|
#include "AudioScriptingInterface.h"
|
||||||
#include "Quat.h"
|
#include "Quat.h"
|
||||||
|
@ -53,7 +55,7 @@ class ScriptEngine : public QScriptEngine, public ScriptUser, public EntitiesScr
|
||||||
public:
|
public:
|
||||||
ScriptEngine(const QString& scriptContents = NO_SCRIPT,
|
ScriptEngine(const QString& scriptContents = NO_SCRIPT,
|
||||||
const QString& fileNameString = QString(""),
|
const QString& fileNameString = QString(""),
|
||||||
AbstractControllerScriptingInterface* controllerScriptingInterface = NULL,
|
controller::ScriptingInterface* controllerScriptingInterface = nullptr,
|
||||||
bool wantSignals = true);
|
bool wantSignals = true);
|
||||||
|
|
||||||
~ScriptEngine();
|
~ScriptEngine();
|
||||||
|
@ -182,7 +184,7 @@ private:
|
||||||
QObject* setupTimerWithInterval(const QScriptValue& function, int intervalMS, bool isSingleShot);
|
QObject* setupTimerWithInterval(const QScriptValue& function, int intervalMS, bool isSingleShot);
|
||||||
void stopTimer(QTimer* timer);
|
void stopTimer(QTimer* timer);
|
||||||
|
|
||||||
AbstractControllerScriptingInterface* _controllerScriptingInterface;
|
controller::ScriptingInterface* _controllerScriptingInterface;
|
||||||
QString _fileNameString;
|
QString _fileNameString;
|
||||||
Quat _quatLibrary;
|
Quat _quatLibrary;
|
||||||
Vec3 _vec3Library;
|
Vec3 _vec3Library;
|
||||||
|
|
|
@ -8,17 +8,17 @@ import "./controls"
|
||||||
|
|
||||||
Column {
|
Column {
|
||||||
id: root
|
id: root
|
||||||
property var actions: NewControllers.Actions
|
property var actions: Controllers.Actions
|
||||||
property var standard: NewControllers.Standard
|
property var standard: Controllers.Standard
|
||||||
property var testMapping: null
|
property var testMapping: null
|
||||||
property var xbox: null
|
property var xbox: null
|
||||||
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
var patt = /^X360Controller/;
|
var patt = /^X360Controller/;
|
||||||
for (var prop in NewControllers.Hardware) {
|
for (var prop in Controllers.Hardware) {
|
||||||
if(patt.test(prop)) {
|
if(patt.test(prop)) {
|
||||||
root.xbox = NewControllers.Hardware[prop]
|
root.xbox = Controllers.Hardware[prop]
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ Column {
|
||||||
Timer {
|
Timer {
|
||||||
interval: 50; running: true; repeat: true
|
interval: 50; running: true; repeat: true
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
NewControllers.update();
|
Controllers.update();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ Column {
|
||||||
Button {
|
Button {
|
||||||
text: "Default Mapping"
|
text: "Default Mapping"
|
||||||
onClicked: {
|
onClicked: {
|
||||||
var mapping = NewControllers.newMapping("Default");
|
var mapping = Controllers.newMapping("Default");
|
||||||
mapping.from(xbox.A).to(standard.A);
|
mapping.from(xbox.A).to(standard.A);
|
||||||
mapping.from(xbox.B).to(standard.B);
|
mapping.from(xbox.B).to(standard.B);
|
||||||
mapping.from(xbox.X).to(standard.X);
|
mapping.from(xbox.X).to(standard.X);
|
||||||
|
@ -59,7 +59,7 @@ Column {
|
||||||
mapping.from(xbox.RX).to(standard.RX);
|
mapping.from(xbox.RX).to(standard.RX);
|
||||||
mapping.from(xbox.LT).to(standard.LT);
|
mapping.from(xbox.LT).to(standard.LT);
|
||||||
mapping.from(xbox.RT).to(standard.RT);
|
mapping.from(xbox.RT).to(standard.RT);
|
||||||
NewControllers.enableMapping("Default");
|
Controllers.enableMapping("Default");
|
||||||
enabled = false;
|
enabled = false;
|
||||||
text = "Built"
|
text = "Built"
|
||||||
}
|
}
|
||||||
|
@ -68,16 +68,35 @@ Column {
|
||||||
Button {
|
Button {
|
||||||
text: "Build Mapping"
|
text: "Build Mapping"
|
||||||
onClicked: {
|
onClicked: {
|
||||||
var mapping = NewControllers.newMapping();
|
var mapping = Controllers.newMapping();
|
||||||
// Inverting a value
|
// Inverting a value
|
||||||
mapping.from(xbox.RY).invert().to(standard.RY);
|
mapping.from(xbox.RY).invert().to(standard.RY);
|
||||||
// Assigning a value from a function
|
// Assigning a value from a function
|
||||||
mapping.from(function() { return Math.sin(Date.now() / 250); }).to(standard.RX);
|
mapping.from(function() { return Math.sin(Date.now() / 250); }).to(standard.RX);
|
||||||
// Constrainting a value to -1, 0, or 1, with a deadzone
|
// Constrainting a value to -1, 0, or 1, with a deadzone
|
||||||
mapping.from(xbox.LY).deadZone(0.5).constrainToInteger().to(standard.LY);
|
mapping.from(xbox.LY).deadZone(0.5).constrainToInteger().to(standard.LY);
|
||||||
mapping.join(standard.LB, standard.RB).pulse(0.5).to(actions.Yaw);
|
// change join to makeAxis
|
||||||
|
mapping.join(standard.LB, standard.RB).to(actions.Yaw);
|
||||||
mapping.from(actions.Yaw).clamp(0, 1).invert().to(actions.YAW_RIGHT);
|
mapping.from(actions.Yaw).clamp(0, 1).invert().to(actions.YAW_RIGHT);
|
||||||
mapping.from(actions.Yaw).clamp(-1, 0).to(actions.YAW_LEFT);
|
mapping.from(actions.Yaw).clamp(-1, 0).to(actions.YAW_LEFT);
|
||||||
|
|
||||||
|
// mapping.modifier(keyboard.Ctrl).scale(2.0)
|
||||||
|
|
||||||
|
// mapping.from(keyboard.A).to(actions.TranslateLeft)
|
||||||
|
// mapping.from(keyboard.A, keyboard.Shift).to(actions.TurnLeft)
|
||||||
|
// mapping.from(keyboard.A, keyboard.Shift, keyboard.Ctrl).scale(2.0).to(actions.TurnLeft)
|
||||||
|
|
||||||
|
// // First loopbacks
|
||||||
|
// // Then non-loopbacks by constraint level (number of inputs)
|
||||||
|
// mapping.from(xbox.RX).deadZone(0.2).to(xbox.RX)
|
||||||
|
|
||||||
|
// mapping.from(standard.RB, standard.LB, keyboard.Shift).to(actions.TurnLeft)
|
||||||
|
|
||||||
|
|
||||||
|
// mapping.from(keyboard.A, keyboard.Shift).to(actions.TurnLeft)
|
||||||
|
|
||||||
|
|
||||||
|
// mapping.from(keyboard.W).when(keyboard.Shift).to(actions.Forward)
|
||||||
testMapping = mapping;
|
testMapping = mapping;
|
||||||
enabled = false
|
enabled = false
|
||||||
text = "Built"
|
text = "Built"
|
||||||
|
@ -105,7 +124,7 @@ Column {
|
||||||
Row {
|
Row {
|
||||||
spacing: 8
|
spacing: 8
|
||||||
ScrollingGraph {
|
ScrollingGraph {
|
||||||
controlId: NewControllers.Actions.Yaw
|
controlId: Controllers.Actions.Yaw
|
||||||
label: "Yaw"
|
label: "Yaw"
|
||||||
min: -3.0
|
min: -3.0
|
||||||
max: 3.0
|
max: 3.0
|
||||||
|
@ -113,7 +132,7 @@ Column {
|
||||||
}
|
}
|
||||||
|
|
||||||
ScrollingGraph {
|
ScrollingGraph {
|
||||||
controlId: NewControllers.Actions.YAW_LEFT
|
controlId: Controllers.Actions.YAW_LEFT
|
||||||
label: "Yaw Left"
|
label: "Yaw Left"
|
||||||
min: -3.0
|
min: -3.0
|
||||||
max: 3.0
|
max: 3.0
|
||||||
|
@ -121,7 +140,7 @@ Column {
|
||||||
}
|
}
|
||||||
|
|
||||||
ScrollingGraph {
|
ScrollingGraph {
|
||||||
controlId: NewControllers.Actions.YAW_RIGHT
|
controlId: Controllers.Actions.YAW_RIGHT
|
||||||
label: "Yaw Right"
|
label: "Yaw Right"
|
||||||
min: -3.0
|
min: -3.0
|
||||||
max: 3.0
|
max: 3.0
|
||||||
|
|
|
@ -13,7 +13,7 @@ Item {
|
||||||
property color color: 'black'
|
property color color: 'black'
|
||||||
|
|
||||||
function update() {
|
function update() {
|
||||||
value = NewControllers.getValue(controlId);
|
value = Controllers.getValue(controlId);
|
||||||
canvas.requestPaint();
|
canvas.requestPaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,8 +15,8 @@ Item {
|
||||||
|
|
||||||
function update() {
|
function update() {
|
||||||
value = Qt.vector2d(
|
value = Qt.vector2d(
|
||||||
NewControllers.getValue(controlIds[0]),
|
Controllers.getValue(controlIds[0]),
|
||||||
NewControllers.getValue(controlIds[1])
|
Controllers.getValue(controlIds[1])
|
||||||
);
|
);
|
||||||
canvas.requestPaint();
|
canvas.requestPaint();
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ Item {
|
||||||
property string label: ""
|
property string label: ""
|
||||||
|
|
||||||
function update() {
|
function update() {
|
||||||
value = NewControllers.getValue(controlId);
|
value = Controllers.getValue(controlId);
|
||||||
canvas.requestPaint();
|
canvas.requestPaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ Item {
|
||||||
Timer {
|
Timer {
|
||||||
interval: 50; running: true; repeat: true
|
interval: 50; running: true; repeat: true
|
||||||
onTriggered: {
|
onTriggered: {
|
||||||
root.value = NewControllers.getValue(root.controlId);
|
root.value = Controllers.getValue(root.controlId);
|
||||||
canvas.requestPaint();
|
canvas.requestPaint();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -38,10 +38,10 @@
|
||||||
#include <plugins/PluginManager.h>
|
#include <plugins/PluginManager.h>
|
||||||
#include <input-plugins/InputPlugin.h>
|
#include <input-plugins/InputPlugin.h>
|
||||||
#include <input-plugins/KeyboardMouseDevice.h>
|
#include <input-plugins/KeyboardMouseDevice.h>
|
||||||
#include <controllers/NewControllerScriptingInterface.h>
|
#include <controllers/ScriptingInterface.h>
|
||||||
|
|
||||||
#include <DependencyManager.h>
|
#include <DependencyManager.h>
|
||||||
#include <input-plugins/UserInputMapper.h>
|
#include <controllers/UserInputMapper.h>
|
||||||
|
|
||||||
const QString& getQmlDir() {
|
const QString& getQmlDir() {
|
||||||
static QString dir;
|
static QString dir;
|
||||||
|
@ -79,16 +79,39 @@ public:
|
||||||
virtual const DisplayPlugin* getActiveDisplayPlugin() const override { return nullptr; }
|
virtual const DisplayPlugin* getActiveDisplayPlugin() const override { return nullptr; }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class MyControllerScriptingInterface : public controller::ScriptingInterface {
|
||||||
|
public:
|
||||||
|
virtual void registerControllerTypes(QScriptEngine* engine) {};
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
QGuiApplication app(argc, argv);
|
QGuiApplication app(argc, argv);
|
||||||
QQmlApplicationEngine engine;
|
QQmlApplicationEngine engine;
|
||||||
for (auto path : qApp->libraryPaths()) {
|
for (auto path : qApp->libraryPaths()) {
|
||||||
qDebug() << path;
|
qDebug() << path;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (auto path : qApp->libraryPaths()) {
|
for (auto path : qApp->libraryPaths()) {
|
||||||
qDebug() << path;
|
qDebug() << path;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QTimer timer;
|
||||||
|
QObject::connect(&timer, &QTimer::timeout, [] {
|
||||||
|
static float last = secTimestampNow();
|
||||||
|
float now = secTimestampNow();
|
||||||
|
float delta = now - last;
|
||||||
|
last = now;
|
||||||
|
|
||||||
|
foreach(auto inputPlugin, PluginManager::getInstance()->getInputPlugins()) {
|
||||||
|
inputPlugin->pluginUpdate(delta, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
||||||
|
userInputMapper->update(delta);
|
||||||
|
});
|
||||||
|
timer.start(50);
|
||||||
|
|
||||||
{
|
{
|
||||||
DependencyManager::set<UserInputMapper>();
|
DependencyManager::set<UserInputMapper>();
|
||||||
foreach(auto inputPlugin, PluginManager::getInstance()->getInputPlugins()) {
|
foreach(auto inputPlugin, PluginManager::getInstance()->getInputPlugins()) {
|
||||||
|
@ -100,17 +123,9 @@ int main(int argc, char** argv) {
|
||||||
keyboardMouseDevice->registerToUserInputMapper(*userInputMapper);
|
keyboardMouseDevice->registerToUserInputMapper(*userInputMapper);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//new PluginContainerProxy();
|
//new PluginContainerProxy();
|
||||||
auto rootContext = engine.rootContext();
|
auto rootContext = engine.rootContext();
|
||||||
|
rootContext->setContextProperty("Controllers", new MyControllerScriptingInterface());
|
||||||
auto controllers = new NewControllerScriptingInterface();
|
|
||||||
rootContext->setContextProperty("NewControllers", controllers);
|
|
||||||
QVariantMap map;
|
|
||||||
map.insert("Hardware", controllers->property("Hardware"));
|
|
||||||
map.insert("Actions", controllers->property("Actions"));
|
|
||||||
rootContext->setContextProperty("ControllerIds", map);
|
|
||||||
}
|
}
|
||||||
engine.load(getQmlDir() + "main.qml");
|
engine.load(getQmlDir() + "main.qml");
|
||||||
app.exec();
|
app.exec();
|
||||||
|
|
|
@ -319,6 +319,9 @@
|
||||||
userData: JSON.stringify({
|
userData: JSON.stringify({
|
||||||
resetMe: {
|
resetMe: {
|
||||||
resetMe: true
|
resetMe: true
|
||||||
|
},
|
||||||
|
grabbableKey: {
|
||||||
|
invertSolidWhileHeld: true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@ -378,7 +381,8 @@
|
||||||
var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/target.fbx';
|
var MODEL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/target.fbx';
|
||||||
var COLLISION_HULL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/target_collision_hull.obj';
|
var COLLISION_HULL_URL = 'http://hifi-public.s3.amazonaws.com/models/ping_pong_gun/target_collision_hull.obj';
|
||||||
|
|
||||||
var RESET_DISTANCE = 1;
|
var MINIMUM_MOVE_LENGTH = 0.05;
|
||||||
|
var RESET_DISTANCE = 0.5;
|
||||||
var TARGET_USER_DATA_KEY = 'hifi-ping_pong_target';
|
var TARGET_USER_DATA_KEY = 'hifi-ping_pong_target';
|
||||||
var NUMBER_OF_TARGETS = 6;
|
var NUMBER_OF_TARGETS = 6;
|
||||||
var TARGETS_PER_ROW = 3;
|
var TARGETS_PER_ROW = 3;
|
||||||
|
@ -392,7 +396,6 @@
|
||||||
var VERTICAL_SPACING = TARGET_DIMENSIONS.y + 0.5;
|
var VERTICAL_SPACING = TARGET_DIMENSIONS.y + 0.5;
|
||||||
var HORIZONTAL_SPACING = TARGET_DIMENSIONS.z + 0.5;
|
var HORIZONTAL_SPACING = TARGET_DIMENSIONS.z + 0.5;
|
||||||
|
|
||||||
|
|
||||||
var startPosition = {
|
var startPosition = {
|
||||||
x: 548.68,
|
x: 548.68,
|
||||||
y: 497.30,
|
y: 497.30,
|
||||||
|
@ -413,6 +416,9 @@
|
||||||
userData: JSON.stringify({
|
userData: JSON.stringify({
|
||||||
resetMe: {
|
resetMe: {
|
||||||
resetMe: true
|
resetMe: true
|
||||||
|
},
|
||||||
|
grabbableKey: {
|
||||||
|
grabbable: false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@ -421,6 +427,8 @@
|
||||||
|
|
||||||
var originalPositions = [];
|
var originalPositions = [];
|
||||||
|
|
||||||
|
var lastPositions = [];
|
||||||
|
|
||||||
function addTargets() {
|
function addTargets() {
|
||||||
var i;
|
var i;
|
||||||
var row = -1;
|
var row = -1;
|
||||||
|
@ -437,6 +445,7 @@
|
||||||
position.y = startPosition.y - (row * VERTICAL_SPACING);
|
position.y = startPosition.y - (row * VERTICAL_SPACING);
|
||||||
|
|
||||||
originalPositions.push(position);
|
originalPositions.push(position);
|
||||||
|
lastPositions.push(position);
|
||||||
|
|
||||||
var targetProperties = {
|
var targetProperties = {
|
||||||
name: 'Target',
|
name: 'Target',
|
||||||
|
@ -452,6 +461,9 @@
|
||||||
userData: JSON.stringify({
|
userData: JSON.stringify({
|
||||||
resetMe: {
|
resetMe: {
|
||||||
resetMe: true
|
resetMe: true
|
||||||
|
},
|
||||||
|
grabbableKey: {
|
||||||
|
grabbable: false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
@ -468,7 +480,11 @@
|
||||||
var distance = Vec3.subtract(originalPosition, currentPosition);
|
var distance = Vec3.subtract(originalPosition, currentPosition);
|
||||||
var length = Vec3.length(distance);
|
var length = Vec3.length(distance);
|
||||||
|
|
||||||
if (length > RESET_DISTANCE) {
|
var moving = Vec3.length(Vec3.subtract(currentPosition, lastPositions[index]));
|
||||||
|
|
||||||
|
lastPositions[index] = currentPosition;
|
||||||
|
|
||||||
|
if (length > RESET_DISTANCE && moving < MINIMUM_MOVE_LENGTH) {
|
||||||
|
|
||||||
Entities.deleteEntity(target);
|
Entities.deleteEntity(target);
|
||||||
|
|
||||||
|
@ -486,11 +502,14 @@
|
||||||
userData: JSON.stringify({
|
userData: JSON.stringify({
|
||||||
resetMe: {
|
resetMe: {
|
||||||
resetMe: true
|
resetMe: true
|
||||||
|
},
|
||||||
|
grabbableKey: {
|
||||||
|
grabbable: false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
var target = Entities.addEntity(targetProperties);
|
|
||||||
targets[index] = target;
|
targets[index] = Entities.addEntity(targetProperties);
|
||||||
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -548,6 +567,9 @@
|
||||||
userData: JSON.stringify({
|
userData: JSON.stringify({
|
||||||
resetMe: {
|
resetMe: {
|
||||||
resetMe: true
|
resetMe: true
|
||||||
|
},
|
||||||
|
grabbableKey: {
|
||||||
|
grabbable: false
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@ -583,7 +605,11 @@
|
||||||
userData: JSON.stringify({
|
userData: JSON.stringify({
|
||||||
resetMe: {
|
resetMe: {
|
||||||
resetMe: true
|
resetMe: true
|
||||||
|
},
|
||||||
|
grabbableKey: {
|
||||||
|
invertSolidWhileHeld: true
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -851,6 +877,9 @@
|
||||||
userData: JSON.stringify({
|
userData: JSON.stringify({
|
||||||
resetMe: {
|
resetMe: {
|
||||||
resetMe: true,
|
resetMe: true,
|
||||||
|
},
|
||||||
|
grabbableKey: {
|
||||||
|
invertSolidWhileHeld: true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
@ -940,6 +969,9 @@
|
||||||
userData: JSON.stringify({
|
userData: JSON.stringify({
|
||||||
resetMe: {
|
resetMe: {
|
||||||
resetMe: true,
|
resetMe: true,
|
||||||
|
},
|
||||||
|
grabbableKey: {
|
||||||
|
invertSolidWhileHeld: true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@ -1014,6 +1046,9 @@
|
||||||
userData: JSON.stringify({
|
userData: JSON.stringify({
|
||||||
resetMe: {
|
resetMe: {
|
||||||
resetMe: true,
|
resetMe: true,
|
||||||
|
},
|
||||||
|
grabbableKey: {
|
||||||
|
invertSolidWhileHeld: true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@ -1053,6 +1088,9 @@
|
||||||
userData: JSON.stringify({
|
userData: JSON.stringify({
|
||||||
resetMe: {
|
resetMe: {
|
||||||
resetMe: true,
|
resetMe: true,
|
||||||
|
},
|
||||||
|
grabbableKey: {
|
||||||
|
invertSolidWhileHeld: true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@ -1090,6 +1128,9 @@
|
||||||
userData: JSON.stringify({
|
userData: JSON.stringify({
|
||||||
resetMe: {
|
resetMe: {
|
||||||
resetMe: true,
|
resetMe: true,
|
||||||
|
},
|
||||||
|
grabbableKey: {
|
||||||
|
invertSolidWhileHeld: true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
@ -1126,6 +1167,9 @@
|
||||||
userData: JSON.stringify({
|
userData: JSON.stringify({
|
||||||
resetMe: {
|
resetMe: {
|
||||||
resetMe: true,
|
resetMe: true,
|
||||||
|
},
|
||||||
|
grabbableKey: {
|
||||||
|
invertSolidWhileHeld: true
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue