Merge branch 'master' into tony/mac-fixes

This commit is contained in:
Anthony J. Thibault 2015-11-05 08:26:44 -08:00
commit d9f4b0218e
14 changed files with 389 additions and 284 deletions

View file

@ -0,0 +1,72 @@
//
// spaceMouseDebug.js
// examples
//
// 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
//
var firstmove = 1;
var position = {
x: 0,
y: 0,
z: 0
};
var rotation = {
x: 0,
y: 0,
z: 0
};
function toggleFirstMove() {
if(firstmove){
print("____________________________________");
firstmove = 0;
}
}
function spacemouseCheck() {
return Controller.Hardware.Spacemouse !== undefined;
}
function update(deltaTime) {
if(spacemouseCheck){
if(Controller.getValue(Controller.Standard.LY) != 0){
toggleFirstMove();
print("- Controller TY: " + Controller.getValue(Controller.Standard.LY));
}
if(Controller.getValue(Controller.Standard.LX) != 0){
toggleFirstMove();
print("- Controller RZ: " + Controller.getValue(Controller.Standard.LX));
}
if(Controller.getValue(Controller.Standard.LB) != 0){
toggleFirstMove();
print("- Controller LEFTB: " + Controller.getValue(Controller.Standard.LB));
}
if(Controller.getValue(Controller.Standard.RY) != 0){
toggleFirstMove();
print("- Controller TZ: " + Controller.getValue(Controller.Standard.RY));
}
if(Controller.getValue(Controller.Standard.RX) != 0){
toggleFirstMove();
print("- Controller TX: " + Controller.getValue(Controller.Standard.RX));
}
if(Controller.getValue(Controller.Standard.RB) != 0){
toggleFirstMove();
print("- Controller RIGHTB: " + Controller.getValue(Controller.Standard.RB));
}
firstmove = 1;
}
}
Script.update.connect(update);

View file

@ -178,12 +178,11 @@ function MyController(hand) {
this.actionID = null; // action this script created...
this.grabbedEntity = null; // on this entity.
this.grabbedVelocity = ZERO_VEC; // rolling average of held object's velocity
this.state = STATE_OFF;
this.pointer = null; // entity-id of line object
this.triggerValue = 0; // rolling average of trigger value
this.rawTriggerValue = 0;
this.offsetPosition = { x: 0.0, y: 0.0, z: 0.0 };
this.offsetRotation = { x: 0.0, y: 0.0, z: 0.0, w: 1.0 };
@ -452,6 +451,14 @@ function MyController(hand) {
continue;
}
if (propsForCandidate.type == 'ParticleEffect') {
continue;
}
if (propsForCandidate.type == 'Zone') {
continue;
}
if (propsForCandidate.locked && !grabbableDataForCandidate.wantsTrigger) {
continue;
}
@ -587,7 +594,6 @@ function MyController(hand) {
var deltaPosition = Vec3.subtract(newObjectPosition, this.currentObjectPosition); // meters
var now = Date.now();
var deltaTime = (now - this.currentObjectTime) / MSEC_PER_SEC; // convert to seconds
this.computeReleaseVelocity(deltaPosition, deltaTime, false);
this.currentObjectPosition = newObjectPosition;
this.currentObjectTime = now;
@ -707,7 +713,6 @@ function MyController(hand) {
var deltaPosition = Vec3.subtract(handControllerPosition, this.currentHandControllerTipPosition); // meters
var deltaTime = (now - this.currentObjectTime) / MSEC_PER_SEC; // convert to seconds
this.computeReleaseVelocity(deltaPosition, deltaTime, true);
this.currentHandControllerTipPosition = handControllerPosition;
this.currentObjectTime = now;
@ -859,23 +864,6 @@ function MyController(hand) {
Entities.callEntityMethod(entityID, "stopTouch");
};
this.computeReleaseVelocity = function(deltaPosition, deltaTime, useMultiplier) {
if (deltaTime > 0.0 && !vec3equal(deltaPosition, ZERO_VEC)) {
var grabbedVelocity = Vec3.multiply(deltaPosition, 1.0 / deltaTime);
// don't update grabbedVelocity if the trigger is off. the smoothing of the trigger
// value would otherwise give the held object time to slow down.
if (this.triggerSqueezed()) {
this.grabbedVelocity =
Vec3.sum(Vec3.multiply(this.grabbedVelocity, (1.0 - NEAR_GRABBING_VELOCITY_SMOOTH_RATIO)),
Vec3.multiply(grabbedVelocity, NEAR_GRABBING_VELOCITY_SMOOTH_RATIO));
}
if (useMultiplier) {
this.grabbedVelocity = Vec3.multiply(this.grabbedVelocity, RELEASE_VELOCITY_MULTIPLIER);
}
}
};
this.release = function() {
if(this.hand !== disabledHand){
@ -893,13 +881,6 @@ function MyController(hand) {
this.deactivateEntity(this.grabbedEntity);
// the action will tend to quickly bring an object's velocity to zero. now that
// the action is gone, set the objects velocity to something the holder might expect.
Entities.editEntity(this.grabbedEntity, {
velocity: this.grabbedVelocity
});
this.grabbedVelocity = ZERO_VEC;
this.grabbedEntity = null;
this.actionID = null;
this.setState(STATE_OFF);

View file

@ -12,28 +12,49 @@
{ "from": "Keyboard.W", "when": "Keyboard.Shift", "to": "Actions.PITCH_UP" },
{ "from": { "makeAxis" : ["Keyboard.MouseMoveLeft", "Keyboard.MouseMoveRight"] },
{ "comment" : "Mouse turn need to be small continuous increments",
"from": { "makeAxis" : [
[ "Keyboard.MouseMoveLeft" ],
[ "Keyboard.MouseMoveRight" ]
]
},
"when": [ "Application.InHMD", "Application.ComfortMode", "Keyboard.RightMouseButton" ],
"to": "Actions.StepYaw",
"filters":
[
"constrainToInteger",
{ "type": "pulse", "interval": 0.5 },
{ "type": "scale", "scale": 15 }
{ "type": "pulse", "interval": 0.2 },
{ "type": "scale", "scale": 22.5 }
]
},
{ "comment" : "Touchpad turn need to be small continuous increments, but without the RMB constraint",
"from": { "makeAxis" : [
[ "Keyboard.TouchpadLeft" ],
[ "Keyboard.TouchpadRight" ]
]
},
"when": [ "Application.InHMD", "Application.ComfortMode" ],
"to": "Actions.StepYaw",
"filters":
[
"constrainToInteger",
{ "type": "pulse", "interval": 0.2 },
{ "type": "scale", "scale": 22.5 }
]
},
{ "from": { "makeAxis" : [
["Keyboard.A", "Keyboard.Left", "Keyboard.TouchpadLeft"],
["Keyboard.D", "Keyboard.Right", "Keyboard.TouchpadRight"]
["Keyboard.A", "Keyboard.Left" ],
["Keyboard.D", "Keyboard.Right"]
]
},
"when": [ "Application.InHMD", "Application.ComfortMode" ],
"to": "Actions.StepYaw",
"filters":
[
{ "type": "pulse", "interval": 0.5 },
{ "type": "scale", "scale": 15 }
{ "type": "pulse", "interval": 0.5, "resetOnZero": true },
{ "type": "scale", "scale": 22.5 }
]
},

View file

@ -0,0 +1,15 @@
{
"name": "Spacemouse to Standard",
"channels": [
{ "from": "Spacemouse.TranslateX", "to": "Standard.RX" },
{ "from": "Spacemouse.TranslateY", "to": "Standard.LY" },
{ "from": "Spacemouse.TranslateZ", "to": "Standard.RY" },
{ "from": "Spacemouse.RotateZ", "to": "Standard.LX" },
{ "from": "Spacemouse.LeftButton", "to": "Standard.LB" },
{ "from": "Spacemouse.RightButton", "to": "Standard.RB" }
]
}

View file

@ -100,7 +100,7 @@
#include "audio/AudioScope.h"
#include "avatar/AvatarManager.h"
#include "CrashHandler.h"
#include "devices/3DConnexionClient.h"
#include "input-plugins/SpacemouseManager.h"
#include "devices/DdeFaceTracker.h"
#include "devices/EyeTracker.h"
#include "devices/Faceshift.h"
@ -726,10 +726,8 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
// Now that menu is initalized we can sync myAvatar with it's state.
getMyAvatar()->updateMotionBehaviorFromMenu();
#if 0
// the 3Dconnexion device wants to be initiliazed after a window is displayed.
ConnexionClient::getInstance().init();
#endif
SpacemouseManager::getInstance().init();
auto& packetReceiver = nodeList->getPacketReceiver();
packetReceiver.registerListener(PacketType::DomainConnectionDenied, this, "handleDomainConnectionDeniedPacket");
@ -1851,9 +1849,10 @@ void Application::focusOutEvent(QFocusEvent* event) {
inputPlugin->pluginFocusOutEvent();
}
}
#if 0
ConnexionData::getInstance().focusOutEvent();
#endif
//SpacemouseDevice::getInstance().focusOutEvent();
//SpacemouseManager::getInstance().getDevice()->focusOutEvent();
SpacemouseManager::getInstance().ManagerFocusOutEvent();
// synthesize events for keys currently pressed, since we may not get their release events
foreach (int key, _keysPressed) {
@ -2795,7 +2794,7 @@ void Application::update(float deltaTime) {
float timeFactor = EXPECTED_FRAME_RATE * deltaTime;
myAvatar->setDriveKeys(PITCH, -1.0f * userInputMapper->getActionState(controller::Action::PITCH) / timeFactor);
myAvatar->setDriveKeys(YAW, -1.0f * userInputMapper->getActionState(controller::Action::YAW) / timeFactor);
myAvatar->setDriveKeys(STEP_YAW, -1.0f * userInputMapper->getActionState(controller::Action::STEP_YAW) / timeFactor);
myAvatar->setDriveKeys(STEP_YAW, -1.0f * userInputMapper->getActionState(controller::Action::STEP_YAW));
}
}
myAvatar->setDriveKeys(ZOOM, userInputMapper->getActionState(controller::Action::TRANSLATE_CAMERA_Z));

View file

@ -30,7 +30,7 @@
#include "devices/DdeFaceTracker.h"
#include "devices/Faceshift.h"
#include "devices/RealSense.h"
#include "devices/3DConnexionClient.h"
#include "input-plugins/SpacemouseManager.h"
#include "MainWindow.h"
#include "scripting/MenuScriptingInterface.h"
#include "ui/AssetUploadDialogFactory.h"
@ -464,13 +464,9 @@ Menu::Menu() {
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::MeshVisible, 0, true,
avatar, SLOT(setEnableMeshVisible(bool)));
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::DisableEyelidAdjustment, 0, false);
#if 0
addCheckableActionToQMenuAndActionHash(avatarDebugMenu,
MenuOption::Connexion,
0, false,
&ConnexionClient::getInstance(),
SLOT(toggleConnexion(bool)));
#endif
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::Connexion, 0, false, &SpacemouseManager::getInstance(), SLOT(toggleSpacemouse(bool)));
addCheckableActionToQMenuAndActionHash(avatarDebugMenu, MenuOption::ComfortMode, 0, true);
MenuWrapper* handOptionsMenu = developerMenu->addMenu("Hands");

View file

@ -1029,6 +1029,7 @@ Mapping::Pointer UserInputMapper::parseMapping(const QJsonValue& json) {
}
mapping->routes.push_back(route);
}
_mappingsByName[mapping->name] = mapping;
return mapping;
}

View file

@ -13,7 +13,7 @@
using namespace controller;
const float PulseFilter::DEFAULT_LAST_EMIT_TIME = -::std::numeric_limits<float>::max();
float PulseFilter::apply(float value) const {
float result = 0.0f;
@ -25,13 +25,22 @@ float PulseFilter::apply(float value) const {
_lastEmitTime = now;
result = value;
}
} else if (_resetOnZero) {
_lastEmitTime = DEFAULT_LAST_EMIT_TIME;
}
return result;
}
bool PulseFilter::parseParameters(const QJsonValue& parameters) {
static const QString JSON_MIN = QStringLiteral("interval");
return parseSingleFloatParameter(parameters, JSON_MIN, _interval);
static const QString JSON_INTERVAL = QStringLiteral("interval");
static const QString JSON_RESET = QStringLiteral("resetOnZero");
if (parameters.isObject()) {
auto obj = parameters.toObject();
if (obj.contains(JSON_RESET)) {
_resetOnZero = obj[JSON_RESET].toBool();
}
}
return parseSingleFloatParameter(parameters, JSON_INTERVAL, _interval);
}

View file

@ -21,14 +21,15 @@ public:
PulseFilter() {}
PulseFilter(float interval) : _interval(interval) {}
virtual float apply(float value) const override;
virtual bool parseParameters(const QJsonValue& parameters);
private:
mutable float _lastEmitTime { -::std::numeric_limits<float>::max() };
float _interval = 1.0f;
static const float DEFAULT_LAST_EMIT_TIME;
mutable float _lastEmitTime { DEFAULT_LAST_EMIT_TIME };
bool _resetOnZero { false };
float _interval { 1.0f };
};
}

View file

@ -1,5 +1,5 @@
//
// 3DConnexionClient.cpp
// SpacemouseManager.cpp
// interface/src/devices
//
// Created by MarcelEdward Verhagen on 09-06-15.
@ -9,107 +9,74 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "SpacemouseManager.h"
#include "3DConnexionClient.h"
#if 0
#include <UserActivityLogger.h>
#include <PathUtils.h>
#include "Menu.h"
#include <plugins/PluginContainer.h>
#include <controllers/UserInputMapper.h>
#include "../../../interface/src/Menu.h"
const float MAX_AXIS = 75.0f; // max forward = 2x speed
void ConnexionData::focusOutEvent() {
static std::shared_ptr<SpacemouseDevice> instance;
SpacemouseDevice::SpacemouseDevice() :
InputDevice("Spacemouse")
{
instance = std::shared_ptr<SpacemouseDevice>(this);
}
void SpacemouseDevice::focusOutEvent() {
_axisStateMap.clear();
_buttonPressedMap.clear();
};
ConnexionData& ConnexionData::getInstance() {
static ConnexionData sharedInstance;
return sharedInstance;
}
ConnexionData::ConnexionData() : InputDevice("ConnexionClient") {}
void ConnexionData::handleAxisEvent() {
void SpacemouseDevice::handleAxisEvent() {
auto rotation = cc_rotation / MAX_AXIS;
_axisStateMap[ROTATE_X] = rotation.x;
_axisStateMap[ROTATE_X] = rotation.x;
_axisStateMap[ROTATE_Y] = rotation.y;
_axisStateMap[ROTATE_Z] = rotation.z;
auto position = cc_rotation / MAX_AXIS;
auto position = cc_position / MAX_AXIS;
_axisStateMap[TRANSLATE_X] = position.x;
_axisStateMap[TRANSLATE_Y] = position.y;
_axisStateMap[TRANSLATE_Z] = position.z;
}
void ConnexionData::setButton(int lastButtonState) {
void SpacemouseDevice::setButton(int lastButtonState) {
_buttonPressedMap.clear();
_buttonPressedMap.insert(lastButtonState);
}
void ConnexionData::buildDeviceProxy(controller::DeviceProxy::Pointer proxy) {
proxy->_name = _name = "ConnexionClient";
proxy->getButton = [this](const controller::Input& input, int timestamp) -> bool { return this->getButton(input.getChannel()); };
proxy->getAxis = [this](const controller::Input& input, int timestamp) -> float { return this->getAxis(input.getChannel()); };
proxy->getAvailabeInputs = [this]() -> QVector<controller::Input::NamedPair> {
using namespace controller;
static QVector<controller::Input::NamedPair> availableInputs {
Input::NamedPair(makeInput(BUTTON_1), "LeftButton"),
Input::NamedPair(makeInput(BUTTON_2), "RightButton"),
Input::NamedPair(makeInput(BUTTON_3), "BothButtons"),
Input::NamedPair(makeInput(TRANSLATE_X), "TranslateX"),
Input::NamedPair(makeInput(TRANSLATE_Y), "TranslateY"),
Input::NamedPair(makeInput(TRANSLATE_Z), "TranslateZ"),
Input::NamedPair(makeInput(ROTATE_X), "RotateX"),
Input::NamedPair(makeInput(ROTATE_Y), "RotateY"),
Input::NamedPair(makeInput(ROTATE_Z), "RotateZ"),
};
return availableInputs;
controller::Input::NamedVector SpacemouseDevice::getAvailableInputs() const {
using namespace controller;
static const Input::NamedVector availableInputs{
makePair(BUTTON_1, "LeftButton"),
makePair(BUTTON_2, "RightButton"),
//makePair(BUTTON_3, "BothButtons"),
makePair(TRANSLATE_X, "TranslateX"),
makePair(TRANSLATE_Y, "TranslateY"),
makePair(TRANSLATE_Z, "TranslateZ"),
//makePair(ROTATE_X, "RotateX"),
//makePair(ROTATE_Y, "RotateY"),
makePair(ROTATE_Z, "RotateZ"),
};
return availableInputs;
}
QString ConnexionData::getDefaultMappingConfig() {
static const QString MAPPING_JSON = PathUtils::resourcesPath() + "/controllers/vive.json";
QString SpacemouseDevice::getDefaultMappingConfig() const {
static const QString MAPPING_JSON = PathUtils::resourcesPath() + "/controllers/spacemouse.json";
return MAPPING_JSON;
}
//void ConnexionData::assignDefaultInputMapping(UserInputMapper& mapper) {
// const float JOYSTICK_MOVE_SPEED = 1.0f;
// //const float DPAD_MOVE_SPEED = 0.5f;
// const float JOYSTICK_YAW_SPEED = 0.5f;
// const float JOYSTICK_PITCH_SPEED = 0.25f;
// const float BOOM_SPEED = 0.1f;
//
// // Y axes are flipped (up is negative)
// // postion: Movement, strafing
// mapper.addInputChannel(UserInputMapper::LONGITUDINAL_FORWARD, makeInput(POSITION_AXIS_Y_NEG), JOYSTICK_MOVE_SPEED);
// mapper.addInputChannel(UserInputMapper::LONGITUDINAL_BACKWARD, makeInput(POSITION_AXIS_Y_POS), JOYSTICK_MOVE_SPEED);
// mapper.addInputChannel(UserInputMapper::LATERAL_RIGHT, makeInput(POSITION_AXIS_X_POS), JOYSTICK_MOVE_SPEED);
// mapper.addInputChannel(UserInputMapper::LATERAL_LEFT, makeInput(POSITION_AXIS_X_NEG), JOYSTICK_MOVE_SPEED);
// mapper.addInputChannel(UserInputMapper::VERTICAL_UP, makeInput(POSITION_AXIS_Z_NEG), JOYSTICK_MOVE_SPEED);
// mapper.addInputChannel(UserInputMapper::VERTICAL_DOWN, makeInput(POSITION_AXIS_Z_POS), JOYSTICK_MOVE_SPEED);
//
// // Rotation: Camera orientation with button 1
// mapper.addInputChannel(UserInputMapper::YAW_RIGHT, makeInput(ROTATION_AXIS_Z_POS), JOYSTICK_YAW_SPEED);
// mapper.addInputChannel(UserInputMapper::YAW_LEFT, makeInput(ROTATION_AXIS_Z_NEG), JOYSTICK_YAW_SPEED);
// mapper.addInputChannel(UserInputMapper::PITCH_DOWN, makeInput(ROTATION_AXIS_Y_NEG), JOYSTICK_PITCH_SPEED);
// mapper.addInputChannel(UserInputMapper::PITCH_UP, makeInput(ROTATION_AXIS_Y_POS), JOYSTICK_PITCH_SPEED);
//
// // Button controls
// // Zoom
// mapper.addInputChannel(UserInputMapper::BOOM_IN, makeInput(BUTTON_1), BOOM_SPEED);
// mapper.addInputChannel(UserInputMapper::BOOM_OUT, makeInput(BUTTON_2), BOOM_SPEED);
//
// // Zoom
// // mapper.addInputChannel(UserInputMapper::BOOM_IN, makeInput(ROTATION_AXIS_Z_NEG), BOOM_SPEED);
// // mapper.addInputChannel(UserInputMapper::BOOM_OUT, makeInput(ROTATION_AXIS_Z_POS), BOOM_SPEED);
//
//}
float ConnexionData::getButton(int channel) const {
float SpacemouseDevice::getButton(int channel) const {
if (!_buttonPressedMap.empty()) {
if (_buttonPressedMap.find(channel) != _buttonPressedMap.end()) {
return 1.0f;
@ -120,7 +87,7 @@ float ConnexionData::getButton(int channel) const {
return 0.0f;
}
float ConnexionData::getAxis(int channel) const {
float SpacemouseDevice::getAxis(int channel) const {
auto axis = _axisStateMap.find(channel);
if (axis != _axisStateMap.end()) {
return (*axis).second;
@ -129,55 +96,75 @@ float ConnexionData::getAxis(int channel) const {
}
}
controller::Input ConnexionData::makeInput(ConnexionData::ButtonChannel button) {
controller::Input SpacemouseDevice::makeInput(SpacemouseDevice::ButtonChannel button) const {
return controller::Input(_deviceID, button, controller::ChannelType::BUTTON);
}
controller::Input ConnexionData::makeInput(ConnexionData::PositionChannel axis) {
controller::Input SpacemouseDevice::makeInput(SpacemouseDevice::PositionChannel axis) const {
return controller::Input(_deviceID, axis, controller::ChannelType::AXIS);
}
void ConnexionData::update(float deltaTime, bool jointsCaptured) {
// the update is done in the ConnexionClient class.
controller::Input::NamedPair SpacemouseDevice::makePair(SpacemouseDevice::ButtonChannel button, const QString& name) const {
return controller::Input::NamedPair(makeInput(button), name);
}
controller::Input::NamedPair SpacemouseDevice::makePair(SpacemouseDevice::PositionChannel axis, const QString& name) const {
return controller::Input::NamedPair(makeInput(axis), name);
}
void SpacemouseDevice::update(float deltaTime, bool jointsCaptured) {
// the update is done in the SpacemouseManager class.
// for windows in the nativeEventFilter the inputmapper is connected or registed or removed when an 3Dconnnexion device is attached or detached
// for osx the api will call DeviceAddedHandler or DeviceRemoveHandler when a 3Dconnexion device is attached or detached
}
ConnexionClient& ConnexionClient::getInstance() {
static ConnexionClient sharedInstance;
SpacemouseManager& SpacemouseManager::getInstance() {
static SpacemouseManager sharedInstance;
if (instance == nullptr) {
new SpacemouseDevice();
}
return sharedInstance;
}
void SpacemouseManager::ManagerFocusOutEvent() {
instance->focusOutEvent();
}
#ifdef HAVE_3DCONNEXIONCLIENT
#ifdef Q_OS_WIN
#include <VersionHelpers.h>
void ConnexionClient::toggleConnexion(bool shouldEnable) {
ConnexionData& connexiondata = ConnexionData::getInstance();
if (shouldEnable && connexiondata.getDeviceID() == 0) {
void SpacemouseManager::toggleSpacemouse(bool shouldEnable) {
if (shouldEnable) {
init();
}
if (!shouldEnable && connexiondata.getDeviceID() != 0) {
if (!shouldEnable && instance->getDeviceID() != controller::Input::INVALID_DEVICE) {
destroy();
}
}
void ConnexionClient::init() {
void SpacemouseManager::init() {
if (Menu::getInstance()->isOptionChecked(MenuOption::Connexion)) {
fLast3dmouseInputTime = 0;
InitializeRawInput(GetActiveWindow());
QAbstractEventDispatcher::instance()->installNativeEventFilter(this);
if (instance->getDeviceID() != controller::Input::INVALID_DEVICE) {
auto userInputMapper = DependencyManager::get<UserInputMapper>();
userInputMapper->registerDevice(instance);
UserActivityLogger::getInstance().connectedDevice("controller", "Spacemouse");
}
}
}
void ConnexionClient::destroy() {
void SpacemouseManager::destroy() {
QAbstractEventDispatcher::instance()->removeNativeEventFilter(this);
ConnexionData& connexiondata = ConnexionData::getInstance();
int deviceid = connexiondata.getDeviceID();
int deviceid = instance->getDeviceID();
auto userInputMapper = DependencyManager::get<UserInputMapper>();
userInputMapper->removeDevice(deviceid);
}
@ -281,14 +268,15 @@ unsigned short HidToVirtualKey(unsigned long pid, unsigned short hidKeyCode) {
return virtualkey;
}
bool ConnexionClient::RawInputEventFilter(void* msg, long* result) {
ConnexionData& connexiondata = ConnexionData::getInstance();
bool SpacemouseManager::RawInputEventFilter(void* msg, long* result) {
auto userInputMapper = DependencyManager::get<UserInputMapper>();
if (Is3dmouseAttached() && connexiondata.getDeviceID() == 0) {
userInputMapper->registerDevice(&connexiondata);
UserActivityLogger::getInstance().connectedDevice("controller", "3Dconnexion");
} else if (!Is3dmouseAttached() && connexiondata.getDeviceID() != 0) {
userInputMapper->removeDevice(connexiondata.getDeviceID());
if (Is3dmouseAttached() && instance->getDeviceID() == controller::Input::INVALID_DEVICE) {
userInputMapper->registerDevice(instance);
UserActivityLogger::getInstance().connectedDevice("controller", "Spacemouse");
}
else if (!Is3dmouseAttached() && instance->getDeviceID() != controller::Input::INVALID_DEVICE) {
userInputMapper->removeDevice(instance->getDeviceID());
}
if (!Is3dmouseAttached()) {
@ -309,36 +297,34 @@ bool ConnexionClient::RawInputEventFilter(void* msg, long* result) {
}
// Access the mouse parameters structure
I3dMouseParam& ConnexionClient::MouseParams() {
I3dMouseParam& SpacemouseManager::MouseParams() {
return f3dMouseParams;
}
// Access the mouse parameters structure
const I3dMouseParam& ConnexionClient::MouseParams() const {
const I3dMouseParam& SpacemouseManager::MouseParams() const {
return f3dMouseParams;
}
//Called with the processed motion data when a 3D mouse event is received
void ConnexionClient::Move3d(HANDLE device, std::vector<float>& motionData) {
void SpacemouseManager::Move3d(HANDLE device, std::vector<float>& motionData) {
Q_UNUSED(device);
ConnexionData& connexiondata = ConnexionData::getInstance();
connexiondata.cc_position = { motionData[0] * 1000, motionData[1] * 1000, motionData[2] * 1000 };
connexiondata.cc_rotation = { motionData[3] * 1500, motionData[4] * 1500, motionData[5] * 1500 };
connexiondata.handleAxisEvent();
instance->cc_position = { motionData[0] * 1000, motionData[1] * 1000, motionData[2] * 1000 };
instance->cc_rotation = { motionData[3] * 1500, motionData[4] * 1500, motionData[5] * 1500 };
instance->handleAxisEvent();
}
//Called when a 3D mouse key is pressed
void ConnexionClient::On3dmouseKeyDown(HANDLE device, int virtualKeyCode) {
void SpacemouseManager::On3dmouseKeyDown(HANDLE device, int virtualKeyCode) {
Q_UNUSED(device);
ConnexionData& connexiondata = ConnexionData::getInstance();
connexiondata.setButton(virtualKeyCode);
instance->setButton(virtualKeyCode);
}
//Called when a 3D mouse key is released
void ConnexionClient::On3dmouseKeyUp(HANDLE device, int virtualKeyCode) {
void SpacemouseManager::On3dmouseKeyUp(HANDLE device, int virtualKeyCode) {
Q_UNUSED(device);
ConnexionData& connexiondata = ConnexionData::getInstance();
connexiondata.setButton(0);
instance->setButton(0);
}
//Get an initialized array of PRAWINPUTDEVICE for the 3D devices
@ -357,7 +343,7 @@ static PRAWINPUTDEVICE GetDevicesToRegister(unsigned int* pNumDevices) {
}
//Detect the 3D mouse
bool ConnexionClient::Is3dmouseAttached() {
bool SpacemouseManager::Is3dmouseAttached() {
unsigned int numDevicesOfInterest = 0;
PRAWINPUTDEVICE devicesToRegister = GetDevicesToRegister(&numDevicesOfInterest);
@ -400,7 +386,7 @@ bool ConnexionClient::Is3dmouseAttached() {
// Initialize the window to recieve raw-input messages
// This needs to be called initially so that Windows will send the messages from the 3D mouse to the window.
bool ConnexionClient::InitializeRawInput(HWND hwndTarget) {
bool SpacemouseManager::InitializeRawInput(HWND hwndTarget) {
fWindow = hwndTarget;
// Simply fail if there is no window
@ -429,7 +415,7 @@ bool ConnexionClient::InitializeRawInput(HWND hwndTarget) {
}
//Get the raw input data from Windows
UINT ConnexionClient::GetRawInputBuffer(PRAWINPUT pData, PUINT pcbSize, UINT cbSizeHeader) {
UINT SpacemouseManager::GetRawInputBuffer(PRAWINPUT pData, PUINT pcbSize, UINT cbSizeHeader) {
//Includes workaround for incorrect alignment of the RAWINPUT structure on x64 os
//when running as Wow64 (copied directly from 3DConnexion code)
#ifdef _WIN64
@ -477,7 +463,7 @@ UINT ConnexionClient::GetRawInputBuffer(PRAWINPUT pData, PUINT pcbSize, UINT cbS
// Process the raw input device data
// On3dmouseInput() does all the preprocessing of the rawinput device data before
// finally calling the Move3d method.
void ConnexionClient::On3dmouseInput() {
void SpacemouseManager::On3dmouseInput() {
// Don't do any data processing in background
bool bIsForeground = (::GetActiveWindow() != NULL);
if (!bIsForeground) {
@ -529,7 +515,7 @@ void ConnexionClient::On3dmouseInput() {
// If we have not received data for a while send a zero event
if ((--(iterator->second.fTimeToLive)) == 0) {
iterator->second.fAxes.assign(6, .0);
} else if ( !iterator->second.fIsDirty) { //!t_bPoll3dmouse &&
} else if (!iterator->second.fIsDirty) { //!t_bPoll3dmouse &&
// If we are not polling then only handle the data that was actually received
++iterator;
continue;
@ -604,7 +590,7 @@ void ConnexionClient::On3dmouseInput() {
}
//Called when new raw input data is available
void ConnexionClient::OnRawInput(UINT nInputCode, HRAWINPUT hRawInput) {
void SpacemouseManager::OnRawInput(UINT nInputCode, HRAWINPUT hRawInput) {
const size_t cbSizeOfBuffer = 1024;
BYTE pBuffer[cbSizeOfBuffer];
@ -645,7 +631,7 @@ void ConnexionClient::OnRawInput(UINT nInputCode, HRAWINPUT hRawInput) {
}
}
bool ConnexionClient::TranslateRawInputData(UINT nInputCode, PRAWINPUT pRawInput) {
bool SpacemouseManager::TranslateRawInputData(UINT nInputCode, PRAWINPUT pRawInput) {
bool bIsForeground = (nInputCode == RIM_INPUT);
// We are not interested in keyboard or mouse data received via raw input
@ -670,20 +656,20 @@ bool ConnexionClient::TranslateRawInputData(UINT nInputCode, PRAWINPUT pRawInput
if (::GetRawInputDeviceInfo(pRawInput->header.hDevice, RIDI_DEVICEINFO, &sRidDeviceInfo, &cbSize) == cbSize) {
if (TRACE_RIDI_DEVICEINFO == 1) {
switch (sRidDeviceInfo.dwType) {
case RIM_TYPEMOUSE:
qDebug("\tsRidDeviceInfo.dwType=RIM_TYPEMOUSE\n");
break;
case RIM_TYPEKEYBOARD:
qDebug("\tsRidDeviceInfo.dwType=RIM_TYPEKEYBOARD\n");
break;
case RIM_TYPEHID:
qDebug("\tsRidDeviceInfo.dwType=RIM_TYPEHID\n");
qDebug("\tVendor=0x%x\n\tProduct=0x%x\n\tUsagePage=0x%x\n\tUsage=0x%x\n",
sRidDeviceInfo.hid.dwVendorId,
sRidDeviceInfo.hid.dwProductId,
sRidDeviceInfo.hid.usUsagePage,
sRidDeviceInfo.hid.usUsage);
break;
case RIM_TYPEMOUSE:
qDebug("\tsRidDeviceInfo.dwType=RIM_TYPEMOUSE\n");
break;
case RIM_TYPEKEYBOARD:
qDebug("\tsRidDeviceInfo.dwType=RIM_TYPEKEYBOARD\n");
break;
case RIM_TYPEHID:
qDebug("\tsRidDeviceInfo.dwType=RIM_TYPEHID\n");
qDebug("\tVendor=0x%x\n\tProduct=0x%x\n\tUsagePage=0x%x\n\tUsage=0x%x\n",
sRidDeviceInfo.hid.dwVendorId,
sRidDeviceInfo.hid.dwProductId,
sRidDeviceInfo.hid.usUsagePage,
sRidDeviceInfo.hid.usUsage);
break;
}
}
@ -700,16 +686,16 @@ bool ConnexionClient::TranslateRawInputData(UINT nInputCode, PRAWINPUT pRawInput
//qDebug("Pan/Zoom RI Data =\t0x%x,\t0x%x,\t0x%x\n", pnRawData[0], pnRawData[1], pnRawData[2]);
if (pRawInput->data.hid.dwSizeHid >= 13) { // Highspeed package
// Cache the rotation data
deviceData.fAxes[3] = static_cast<float>(pnRawData[3]);
deviceData.fAxes[4] = static_cast<float>(pnRawData[4]);
deviceData.fAxes[5] = static_cast<float>(pnRawData[5]);
deviceData.fIsDirty = true;
//if (pRawInput->data.hid.dwSizeHid >= 13) { // Highspeed package
// // Cache the rotation data
// deviceData.fAxes[3] = static_cast<float>(pnRawData[3]);
// deviceData.fAxes[4] = static_cast<float>(pnRawData[4]);
// deviceData.fAxes[5] = static_cast<float>(pnRawData[5]);
// deviceData.fIsDirty = true;
//qDebug("Rotation RI Data =\t0x%x,\t0x%x,\t0x%x\n", pnRawData[3], pnRawData[4], pnRawData[5]);
return true;
}
// qDebug("Rotation RI Data =\t0x%x,\t0x%x,\t0x%x\n", pnRawData[3], pnRawData[4], pnRawData[5]);
// return true;
//}
} else { // Zero out the data if the app is not in forground
deviceData.fAxes.assign(6, 0.f);
}
@ -824,15 +810,15 @@ bool MouseParameters::IsLockHorizon() const {
}
void MouseParameters::SetLockHorizon(bool bOn) {
fIsLockHorizon=bOn;
fIsLockHorizon = bOn;
}
void MouseParameters::SetNavigationMode(Navigation navigation) {
fNavigation=navigation;
fNavigation = navigation;
}
void MouseParameters::SetPivotMode(Pivot pivot) {
if (fPivot!=PIVOT_MANUAL || pivot!=PIVOT_AUTO_OVERRIDE) {
if (fPivot != PIVOT_MANUAL || pivot != PIVOT_AUTO_OVERRIDE) {
fPivot = pivot;
}
}
@ -845,13 +831,13 @@ void MouseParameters::SetPivotVisibility(PivotVisibility visibility) {
int fConnexionClientID;
static ConnexionDeviceState lastState;
static SpacemouseDeviceState lastState;
static void DeviceAddedHandler(unsigned int connection);
static void DeviceRemovedHandler(unsigned int connection);
static void MessageHandler(unsigned int connection, unsigned int messageType, void *messageArgument);
void ConnexionClient::toggleConnexion(bool shouldEnable) {
void SpacemouseManager::toggleSpacemouse(bool shouldEnable) {
if (shouldEnable && !Is3dmouseAttached()) {
init();
}
@ -860,7 +846,7 @@ void ConnexionClient::toggleConnexion(bool shouldEnable) {
}
}
void ConnexionClient::init() {
void SpacemouseManager::init() {
// Make sure the framework is installed
if (Menu::getInstance()->isOptionChecked(MenuOption::Connexion)) {
// Install message handler and register our client
@ -870,8 +856,7 @@ void ConnexionClient::init() {
// ...or use this to take over system-wide
fConnexionClientID = RegisterConnexionClient(kConnexionClientWildcard, NULL, kConnexionClientModeTakeOver, kConnexionMaskAll);
ConnexionData& connexiondata = ConnexionData::getInstance();
memcpy(&connexiondata.clientId, &fConnexionClientID, (long)sizeof(int));
memcpy(&instance->clientId, &fConnexionClientID, (long)sizeof(int));
// A separate API call is required to capture buttons beyond the first 8
SetConnexionClientButtonMask(fConnexionClientID, kConnexionMaskAllButtons);
@ -879,17 +864,17 @@ void ConnexionClient::init() {
// use default switches
ConnexionClientControl(fConnexionClientID, kConnexionCtlSetSwitches, kConnexionSwitchesDisabled, NULL);
if (Is3dmouseAttached() && connexiondata.getDeviceID() == 0) {
if (Is3dmouseAttached() && instance->getDeviceID() == controller::Input::INVALID_DEVICE) {
auto userInputMapper = DependencyManager::get<UserInputMapper>();
userInputMapper->registerDevice(&connexiondata);
UserActivityLogger::getInstance().connectedDevice("controller", "3Dconnexion");
userInputMapper->registerDevice(instance);
UserActivityLogger::getInstance().connectedDevice("controller", "Spacemouse");
}
//let one axis be dominant
//ConnexionClientControl(fConnexionClientID, kConnexionCtlSetSwitches, kConnexionSwitchDominant | kConnexionSwitchEnableAll, NULL);
}
}
void ConnexionClient::destroy() {
void SpacemouseManager::destroy() {
// Make sure the framework is installed
if (&InstallConnexionHandlers != NULL) {
// Unregister our client and clean up all handlers
@ -898,36 +883,33 @@ void ConnexionClient::destroy() {
}
CleanupConnexionHandlers();
fConnexionClientID = 0;
ConnexionData& connexiondata = ConnexionData::getInstance();
if (connexiondata.getDeviceID()!=0) {
if (instance->getDeviceID() != controller::Input::INVALID_DEVICE) {
auto userInputMapper = DependencyManager::get<UserInputMapper>();
userInputMapper->removeDevice(connexiondata.getDeviceID());
connexiondata.setDeviceID(0);
userInputMapper->removeDevice(instance->getDeviceID());
instance->setDeviceID(controller::Input::INVALID_DEVICE);
}
}
}
void DeviceAddedHandler(unsigned int connection) {
ConnexionData& connexiondata = ConnexionData::getInstance();
if (connexiondata.getDeviceID() == 0) {
qCWarning(interfaceapp) << "3Dconnexion device added ";
if (instance->getDeviceID() == controller::Input::INVALID_DEVICE) {
qCWarning(interfaceapp) << "Spacemouse device added ";
auto userInputMapper = DependencyManager::get<UserInputMapper>();
userInputMapper->registerDevice(&connexiondata);
UserActivityLogger::getInstance().connectedDevice("controller", "3Dconnexion");
userInputMapper->registerDevice(instance);
UserActivityLogger::getInstance().connectedDevice("controller", "Spacemouse");
}
}
void DeviceRemovedHandler(unsigned int connection) {
ConnexionData& connexiondata = ConnexionData::getInstance();
if (connexiondata.getDeviceID() != 0) {
qCWarning(interfaceapp) << "3Dconnexion device removed";
if (instance->getDeviceID() != controller::Input::INVALID_DEVICE) {
qCWarning(interfaceapp) << "Spacemouse device removed";
auto userInputMapper = DependencyManager::get<UserInputMapper>();
userInputMapper->removeDevice(connexiondata.getDeviceID());
connexiondata.setDeviceID(0);
userInputMapper->removeDevice(instance->getDeviceID());
instance->setDeviceID(controller::Input::INVALID_DEVICE);
}
}
bool ConnexionClient::Is3dmouseAttached() {
bool SpacemouseManager::Is3dmouseAttached() {
int result;
if (fConnexionClientID) {
if (ConnexionControl(kConnexionCtlGetDeviceID, 0, &result)) {
@ -939,21 +921,20 @@ bool ConnexionClient::Is3dmouseAttached() {
}
void MessageHandler(unsigned int connection, unsigned int messageType, void *messageArgument) {
ConnexionDeviceState *state;
SpacemouseDeviceState *state;
switch (messageType) {
case kConnexionMsgDeviceState:
state = (ConnexionDeviceState*)messageArgument;
state = (SpacemouseDeviceState*)messageArgument;
if (state->client == fConnexionClientID) {
ConnexionData& connexiondata = ConnexionData::getInstance();
connexiondata.cc_position = { state->axis[0], state->axis[1], state->axis[2] };
connexiondata.cc_rotation = { state->axis[3], state->axis[4], state->axis[5] };
instance->cc_position = { state->axis[0], state->axis[1], state->axis[2] };
instance->cc_rotation = { state->axis[3], state->axis[4], state->axis[5] };
connexiondata.handleAxisEvent();
instance->handleAxisEvent();
if (state->buttons != lastState.buttons) {
connexiondata.setButton(state->buttons);
instance->setButton(state->buttons);
}
memmove(&lastState, state, (long)sizeof(ConnexionDeviceState));
memmove(&lastState, state, (long)sizeof(SpacemouseDeviceState));
}
break;
case kConnexionMsgPrefsChanged:
@ -968,5 +949,4 @@ void MessageHandler(unsigned int connection, unsigned int messageType, void *mes
#endif // __APPLE__
#endif // HAVE_3DCONNEXIONCLIENT
#endif
#endif

View file

@ -1,4 +1,4 @@
// 3DConnexionClient.h
// SpacemouseManager.h
// interface/src/devices
//
// Created by Marcel Verhagen on 09-06-15.
@ -8,34 +8,38 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#ifndef hifi_3DConnexionClient_h
#define hifi_3DConnexionClient_h
#ifndef hifi_SpacemouseManager_h
#define hifi_SpacemouseManager_h
#define HAVE_3DCONNEXIONCLIENT
#if 0
#include <QObject>
#include <QLibrary>
#include <controllers/UserInputMapper.h>
#include <controllers/InputDevice.h>
#include <controllers/StandardControls.h>
#include "InterfaceLogging.h"
#include "InputPlugin.h"
#ifndef HAVE_3DCONNEXIONCLIENT
class ConnexionClient : public QObject {
class SpacemouseManager : public QObject {
Q_OBJECT
public:
static ConnexionClient& getInstance();
static SpacemouseManager& getInstance();
void ManagerFocusOutEvent();
void init() {};
void destroy() {};
bool Is3dmouseAttached() { return false; };
public slots:
void toggleConnexion(bool shouldEnable) {};
public slots:
void toggleSpacemouse(bool shouldEnable) {};
};
#endif // NOT_HAVE_3DCONNEXIONCLIENT
#endif
#ifdef HAVE_3DCONNEXIONCLIENT
// the windows connexion rawinput
#ifdef Q_OS_WIN
#include "I3dMouseParams.h"
#include "../../../interface/external/3dconnexionclient/include/I3dMouseParams.h"
#include <QAbstractNativeEventFilter>
#include <QAbstractEventDispatcher>
#include <Winsock2.h>
@ -67,6 +71,8 @@ public:
void SetPivotVisibility(PivotVisibility visibility);
static bool Is3dmouseAttached();
private:
MouseParameters(const MouseParameters&);
@ -82,17 +88,20 @@ private:
Speed fSpeed;
};
class ConnexionClient : public QObject, public QAbstractNativeEventFilter {
class SpacemouseManager : public QObject, public QAbstractNativeEventFilter {
Q_OBJECT
public:
ConnexionClient() {};
SpacemouseManager() {};
static ConnexionClient& getInstance();
static SpacemouseManager& getInstance();
void init();
void destroy();
bool Is3dmouseAttached();
ConnexionClient* client;
SpacemouseManager* client;
void ManagerFocusOutEvent();
I3dMouseParam& MouseParams();
const I3dMouseParam& MouseParams() const;
@ -104,11 +113,11 @@ public:
virtual bool nativeEventFilter(const QByteArray& eventType, void* message, long* result) Q_DECL_OVERRIDE
{
MSG* msg = static_cast< MSG * >(message);
return RawInputEventFilter(message, result);
return RawInputEventFilter(message, result);
}
public slots:
void toggleConnexion(bool shouldEnable);
public slots:
void toggleSpacemouse(bool shouldEnable);
signals:
void Move3d(std::vector<float>& motionData);
@ -157,31 +166,30 @@ private:
#else
#include <glm/glm.hpp>
#include "ConnexionClientAPI.h"
#include "../../../interface/external/3dconnexionclient/include/ConnexionClientAPI.h"
class ConnexionClient : public QObject {
class SpacemouseManager : public QObject {
Q_OBJECT
public:
static ConnexionClient& getInstance();
static SpacemouseManager& getInstance();
void init();
void destroy();
bool Is3dmouseAttached();
public slots:
void toggleConnexion(bool shouldEnable);
public slots:
void toggleSpacemouse(bool shouldEnable);
};
#endif // __APPLE__
#endif // HAVE_3DCONNEXIONCLIENT
#endif
// connnects to the userinputmapper
class ConnexionData : public QObject, public controller::InputDevice {
class SpacemouseDevice : public QObject, public controller::InputDevice {
Q_OBJECT
public:
static ConnexionData& getInstance();
ConnexionData();
SpacemouseDevice();
enum PositionChannel {
TRANSLATE_X,
TRANSLATE_Y,
@ -203,10 +211,14 @@ public:
float getButton(int channel) const;
float getAxis(int channel) const;
controller::Input makeInput(ConnexionData::PositionChannel axis);
controller::Input makeInput(ConnexionData::ButtonChannel button);
virtual void buildDeviceProxy(controller::DeviceProxy::Pointer proxy) override;
virtual QString getDefaultMappingConfig() override;
controller::Input makeInput(SpacemouseDevice::PositionChannel axis) const;
controller::Input makeInput(SpacemouseDevice::ButtonChannel button) const;
controller::Input::NamedPair makePair(SpacemouseDevice::PositionChannel axis, const QString& name) const;
controller::Input::NamedPair makePair(SpacemouseDevice::ButtonChannel button, const QString& name) const;
virtual controller::Input::NamedVector getAvailableInputs() const override;
virtual QString getDefaultMappingConfig() const override;
virtual void update(float deltaTime, bool jointsCaptured) override;
virtual void focusOutEvent() override;
@ -218,23 +230,4 @@ public:
void handleAxisEvent();
};
#else // #if 0
#include <QObject>
#include <QLibrary>
// stub
class ConnexionClient : public QObject {
Q_OBJECT
public:
static ConnexionClient& getInstance();
void init() {};
void destroy() {};
bool Is3dmouseAttached() { return false; };
public slots:
void toggleConnexion(bool shouldEnable) {};
};
#endif
#endif // defined(hifi_3DConnexionClient_h)
#endif // defined(hifi_SpacemouseManager_h)

View file

@ -0,0 +1,9 @@
set(TARGET_NAME recording)
# set a default root dir for each of our optional externals if it was not passed
setup_hifi_library(Script)
# use setup_hifi_library macro to setup our project and link appropriate Qt modules
link_hifi_libraries(shared)
GroupSources("src/recording")

View file

@ -0,0 +1,28 @@
//
// Created by Bradley Austin Davis 2015/11/04
// 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_Recording_Forward_h
#define hifi_Recording_Forward_h
#include <memory>
#include <list>
namespace recording {
// A recording of some set of state from the application, usually avatar
// data + audio for a single person
class Clip;
// An interface for interacting with clips, creating them by recording or
// playing them back. Also serialization to and from files / network sources
class Deck;
}
#endif

View file

@ -25,7 +25,7 @@ bool OculusDebugDisplayPlugin::isSupported() const {
}
void OculusDebugDisplayPlugin::customizeContext() {
WindowOpenGLDisplayPlugin::customizeContext();
OculusBaseDisplayPlugin::customizeContext();
enableVsync(false);
}