mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 19:56:44 +02:00
Controller Pose values are relative to Avatar.
Pass a InputCalibrationData to each inputPlugin and inputDevice. This contains the most up sensorToWorldMatrix, avatarMat and hmdSensorMatrix. Each input plugin can use this data to transform it's poses into Avatar space before sending it up the chain. This fixes a bug in the handControllerGrab.js script that relied on the hand controller rotation/positions being in the avatar frame.
This commit is contained in:
parent
3dbb444a65
commit
111ed65bf8
31 changed files with 131 additions and 89 deletions
|
@ -3070,13 +3070,18 @@ void Application::update(float deltaTime) {
|
||||||
|
|
||||||
auto myAvatar = getMyAvatar();
|
auto myAvatar = getMyAvatar();
|
||||||
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
||||||
userInputMapper->setSensorToWorldMat(myAvatar->getSensorToWorldMatrix());
|
|
||||||
userInputMapper->update(deltaTime);
|
userInputMapper->update(deltaTime);
|
||||||
|
|
||||||
|
controller::InputCalibrationData calibrationData = {
|
||||||
|
myAvatar->getSensorToWorldMatrix(),
|
||||||
|
createMatFromQuatAndPos(myAvatar->getOrientation(), myAvatar->getPosition()),
|
||||||
|
myAvatar->getHMDSensorMatrix()
|
||||||
|
};
|
||||||
|
|
||||||
bool jointsCaptured = false;
|
bool jointsCaptured = false;
|
||||||
for (auto inputPlugin : PluginManager::getInstance()->getInputPlugins()) {
|
for (auto inputPlugin : PluginManager::getInstance()->getInputPlugins()) {
|
||||||
if (inputPlugin->isActive()) {
|
if (inputPlugin->isActive()) {
|
||||||
inputPlugin->pluginUpdate(deltaTime, jointsCaptured);
|
inputPlugin->pluginUpdate(deltaTime, calibrationData, jointsCaptured);
|
||||||
if (inputPlugin->isJointController()) {
|
if (inputPlugin->isJointController()) {
|
||||||
jointsCaptured = true;
|
jointsCaptured = true;
|
||||||
}
|
}
|
||||||
|
@ -4981,14 +4986,9 @@ void Application::setPalmData(Hand* hand, const controller::Pose& pose, float de
|
||||||
auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||||
palm.setActive(pose.isValid());
|
palm.setActive(pose.isValid());
|
||||||
|
|
||||||
// transform from sensor space, to world space, to avatar model space.
|
// controller pose is in Avatar frame.
|
||||||
glm::mat4 poseMat = createMatFromQuatAndPos(pose.getRotation(), pose.getTranslation() * myAvatar->getScale());
|
glm::vec3 position = pose.getTranslation();
|
||||||
glm::mat4 sensorToWorldMat = myAvatar->getSensorToWorldMatrix();
|
glm::quat rotation = pose.getRotation();
|
||||||
glm::mat4 modelMat = createMatFromQuatAndPos(myAvatar->getOrientation(), myAvatar->getPosition());
|
|
||||||
glm::mat4 objectPose = glm::inverse(modelMat) * sensorToWorldMat * poseMat;
|
|
||||||
|
|
||||||
glm::vec3 position = extractTranslation(objectPose);
|
|
||||||
glm::quat rotation = glm::quat_cast(objectPose);
|
|
||||||
|
|
||||||
// Compute current velocity from position change
|
// Compute current velocity from position change
|
||||||
glm::vec3 rawVelocity;
|
glm::vec3 rawVelocity;
|
||||||
|
|
|
@ -1392,7 +1392,7 @@ void MyAvatar::updateOrientation(float deltaTime) {
|
||||||
desiredFacing.y = 0.0f;
|
desiredFacing.y = 0.0f;
|
||||||
|
|
||||||
// This is our reference frame, it is captured when the user begins to move.
|
// This is our reference frame, it is captured when the user begins to move.
|
||||||
glm::vec3 referenceFacing = transformVector(_sensorToWorldMatrix, _hoverReferenceCameraFacing);
|
glm::vec3 referenceFacing = transformVectorFast(_sensorToWorldMatrix, _hoverReferenceCameraFacing);
|
||||||
referenceFacing.y = 0.0f;
|
referenceFacing.y = 0.0f;
|
||||||
referenceFacing = glm::normalize(referenceFacing);
|
referenceFacing = glm::normalize(referenceFacing);
|
||||||
glm::vec3 referenceRight(referenceFacing.z, 0.0f, -referenceFacing.x);
|
glm::vec3 referenceRight(referenceFacing.z, 0.0f, -referenceFacing.x);
|
||||||
|
@ -1597,7 +1597,7 @@ void MyAvatar::updatePosition(float deltaTime) {
|
||||||
if (!_hoverReferenceCameraFacingIsCaptured && (fabs(_driveKeys[TRANSLATE_Z]) > 0.1f || fabs(_driveKeys[TRANSLATE_X]) > 0.1f)) {
|
if (!_hoverReferenceCameraFacingIsCaptured && (fabs(_driveKeys[TRANSLATE_Z]) > 0.1f || fabs(_driveKeys[TRANSLATE_X]) > 0.1f)) {
|
||||||
_hoverReferenceCameraFacingIsCaptured = true;
|
_hoverReferenceCameraFacingIsCaptured = true;
|
||||||
// transform the camera facing vector into sensor space.
|
// transform the camera facing vector into sensor space.
|
||||||
_hoverReferenceCameraFacing = transformVector(glm::inverse(_sensorToWorldMatrix), getHead()->getCameraOrientation() * Vectors::UNIT_Z);
|
_hoverReferenceCameraFacing = transformVectorFast(glm::inverse(_sensorToWorldMatrix), getHead()->getCameraOrientation() * Vectors::UNIT_Z);
|
||||||
} else if (_hoverReferenceCameraFacingIsCaptured && (fabs(_driveKeys[TRANSLATE_Z]) <= 0.1f && fabs(_driveKeys[TRANSLATE_X]) <= 0.1f)) {
|
} else if (_hoverReferenceCameraFacingIsCaptured && (fabs(_driveKeys[TRANSLATE_Z]) <= 0.1f && fabs(_driveKeys[TRANSLATE_X]) <= 0.1f)) {
|
||||||
_hoverReferenceCameraFacingIsCaptured = false;
|
_hoverReferenceCameraFacingIsCaptured = false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,7 +120,7 @@ namespace controller {
|
||||||
return availableInputs;
|
return availableInputs;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionsDevice::update(float deltaTime, bool jointsCaptured) {
|
void ActionsDevice::update(float deltaTime, const InputCalibrationData& inpuCalibrationData, bool jointsCaptured) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionsDevice::focusOutEvent() {
|
void ActionsDevice::focusOutEvent() {
|
||||||
|
|
|
@ -110,7 +110,7 @@ class ActionsDevice : public QObject, public InputDevice {
|
||||||
public:
|
public:
|
||||||
virtual EndpointPointer createEndpoint(const Input& input) const override;
|
virtual EndpointPointer createEndpoint(const Input& input) const override;
|
||||||
virtual Input::NamedVector getAvailableInputs() const override;
|
virtual Input::NamedVector getAvailableInputs() const override;
|
||||||
virtual void update(float deltaTime, bool jointsCaptured) override;
|
virtual void update(float deltaTime, const InputCalibrationData& inputCalibrationData, bool jointsCaptured) override;
|
||||||
virtual void focusOutEvent() override;
|
virtual void focusOutEvent() override;
|
||||||
|
|
||||||
ActionsDevice();
|
ActionsDevice();
|
||||||
|
|
|
@ -15,6 +15,12 @@
|
||||||
|
|
||||||
namespace controller {
|
namespace controller {
|
||||||
|
|
||||||
|
struct InputCalibrationData {
|
||||||
|
glm::mat4 sensorToWorldMat;
|
||||||
|
glm::mat4 avatarMat;
|
||||||
|
glm::mat4 hmdSensorMat;
|
||||||
|
};
|
||||||
|
|
||||||
enum class ChannelType {
|
enum class ChannelType {
|
||||||
UNKNOWN = 0,
|
UNKNOWN = 0,
|
||||||
BUTTON,
|
BUTTON,
|
||||||
|
|
|
@ -52,12 +52,12 @@ public:
|
||||||
float getValue(const Input& input) const;
|
float getValue(const Input& input) const;
|
||||||
float getValue(ChannelType channelType, uint16_t channel) const;
|
float getValue(ChannelType channelType, uint16_t channel) const;
|
||||||
Pose getPoseValue(uint16_t channel) const;
|
Pose getPoseValue(uint16_t channel) const;
|
||||||
|
|
||||||
const QString& getName() const { return _name; }
|
const QString& getName() const { return _name; }
|
||||||
|
|
||||||
// Update call MUST be called once per simulation loop
|
// Update call MUST be called once per simulation loop
|
||||||
// It takes care of updating the action states and deltas
|
// It takes care of updating the action states and deltas
|
||||||
virtual void update(float deltaTime, bool jointsCaptured) = 0;
|
virtual void update(float deltaTime, const InputCalibrationData& inputCalibrationData, bool jointsCaptured) = 0;
|
||||||
|
|
||||||
virtual void focusOutEvent() = 0;
|
virtual void focusOutEvent() = 0;
|
||||||
|
|
||||||
|
@ -101,4 +101,4 @@ private:
|
||||||
static float _reticleMoveSpeed;
|
static float _reticleMoveSpeed;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,5 +60,14 @@ namespace controller {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Pose Pose::transform(const glm::mat4& mat) const {
|
||||||
|
auto rot = glmExtractRotation(mat);
|
||||||
|
Pose pose(transformPoint(mat, translation),
|
||||||
|
rot * rotation,
|
||||||
|
transformVectorFast(mat, velocity),
|
||||||
|
rot * angularVelocity);
|
||||||
|
pose.valid = valid;
|
||||||
|
return pose;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,8 @@ namespace controller {
|
||||||
vec3 getVelocity() const { return velocity; }
|
vec3 getVelocity() const { return velocity; }
|
||||||
vec3 getAngularVelocity() const { return angularVelocity; }
|
vec3 getAngularVelocity() const { return angularVelocity; }
|
||||||
|
|
||||||
|
Pose transform(const glm::mat4& mat) const;
|
||||||
|
|
||||||
static QScriptValue toScriptValue(QScriptEngine* engine, const Pose& event);
|
static QScriptValue toScriptValue(QScriptEngine* engine, const Pose& event);
|
||||||
static void fromScriptValue(const QScriptValue& object, Pose& event);
|
static void fromScriptValue(const QScriptValue& object, Pose& event);
|
||||||
};
|
};
|
||||||
|
|
|
@ -25,7 +25,7 @@ StandardController::StandardController() : InputDevice("Standard") {
|
||||||
StandardController::~StandardController() {
|
StandardController::~StandardController() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void StandardController::update(float deltaTime, bool jointsCaptured) {
|
void StandardController::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void StandardController::focusOutEvent() {
|
void StandardController::focusOutEvent() {
|
||||||
|
|
|
@ -28,7 +28,7 @@ public:
|
||||||
virtual EndpointPointer createEndpoint(const Input& input) const override;
|
virtual EndpointPointer createEndpoint(const Input& input) const override;
|
||||||
virtual Input::NamedVector getAvailableInputs() const override;
|
virtual Input::NamedVector getAvailableInputs() const override;
|
||||||
virtual QStringList getDefaultMappingConfigs() const override;
|
virtual QStringList getDefaultMappingConfigs() const override;
|
||||||
virtual void update(float deltaTime, bool jointsCaptured) override;
|
virtual void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override;
|
||||||
virtual void focusOutEvent() override;
|
virtual void focusOutEvent() override;
|
||||||
|
|
||||||
StandardController();
|
StandardController();
|
||||||
|
|
|
@ -25,7 +25,7 @@ StateController::StateController() : InputDevice("Application") {
|
||||||
StateController::~StateController() {
|
StateController::~StateController() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void StateController::update(float deltaTime, bool jointsCaptured) {}
|
void StateController::update(float deltaTime, const InputCalibrationData& inputCalibrationData, bool jointsCaptured) {}
|
||||||
|
|
||||||
void StateController::focusOutEvent() {}
|
void StateController::focusOutEvent() {}
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@ public:
|
||||||
|
|
||||||
// Device functions
|
// Device functions
|
||||||
virtual Input::NamedVector getAvailableInputs() const override;
|
virtual Input::NamedVector getAvailableInputs() const override;
|
||||||
virtual void update(float deltaTime, bool jointsCaptured) override;
|
virtual void update(float deltaTime, const InputCalibrationData& inputCalibrationData, bool jointsCaptured) override;
|
||||||
virtual void focusOutEvent() override;
|
virtual void focusOutEvent() override;
|
||||||
|
|
||||||
StateController();
|
StateController();
|
||||||
|
|
|
@ -97,9 +97,6 @@ namespace controller {
|
||||||
// Update means go grab all the device input channels and update the output channel values
|
// Update means go grab all the device input channels and update the output channel values
|
||||||
void update(float deltaTime);
|
void update(float deltaTime);
|
||||||
|
|
||||||
void setSensorToWorldMat(glm::mat4 sensorToWorldMat) { _sensorToWorldMat = sensorToWorldMat; }
|
|
||||||
glm::mat4 getSensorToWorldMat() { return _sensorToWorldMat; }
|
|
||||||
|
|
||||||
const DevicesMap& getDevices() { return _registeredDevices; }
|
const DevicesMap& getDevices() { return _registeredDevices; }
|
||||||
uint16 getStandardDeviceID() const { return STANDARD_DEVICE; }
|
uint16 getStandardDeviceID() const { return STANDARD_DEVICE; }
|
||||||
InputDevice::Pointer getStandardDevice() { return _registeredDevices[getStandardDeviceID()]; }
|
InputDevice::Pointer getStandardDevice() { return _registeredDevices[getStandardDeviceID()]; }
|
||||||
|
@ -131,8 +128,6 @@ namespace controller {
|
||||||
std::vector<Pose> _poseStates = std::vector<Pose>(toInt(Action::NUM_ACTIONS));
|
std::vector<Pose> _poseStates = std::vector<Pose>(toInt(Action::NUM_ACTIONS));
|
||||||
std::vector<float> _lastStandardStates = std::vector<float>();
|
std::vector<float> _lastStandardStates = std::vector<float>();
|
||||||
|
|
||||||
glm::mat4 _sensorToWorldMat;
|
|
||||||
|
|
||||||
int recordDeviceOfType(const QString& deviceName);
|
int recordDeviceOfType(const QString& deviceName);
|
||||||
QHash<const QString&, int> _deviceCounts;
|
QHash<const QString&, int> _deviceCounts;
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,8 @@
|
||||||
|
|
||||||
const QString KeyboardMouseDevice::NAME = "Keyboard/Mouse";
|
const QString KeyboardMouseDevice::NAME = "Keyboard/Mouse";
|
||||||
|
|
||||||
void KeyboardMouseDevice::pluginUpdate(float deltaTime, bool jointsCaptured) {
|
void KeyboardMouseDevice::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) {
|
||||||
_inputDevice->update(deltaTime, jointsCaptured);
|
_inputDevice->update(deltaTime, inputCalibrationData, jointsCaptured);
|
||||||
|
|
||||||
// For touch event, we need to check that the last event is not too long ago
|
// For touch event, we need to check that the last event is not too long ago
|
||||||
// Maybe it's a Qt issue, but the touch event sequence (begin, update, end) is not always called properly
|
// Maybe it's a Qt issue, but the touch event sequence (begin, update, end) is not always called properly
|
||||||
|
@ -36,7 +36,7 @@ void KeyboardMouseDevice::pluginUpdate(float deltaTime, bool jointsCaptured) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeyboardMouseDevice::InputDevice::update(float deltaTime, bool jointsCaptured) {
|
void KeyboardMouseDevice::InputDevice::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) {
|
||||||
_axisStateMap.clear();
|
_axisStateMap.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -70,7 +70,7 @@ public:
|
||||||
virtual const QString& getName() const override { return NAME; }
|
virtual const QString& getName() const override { return NAME; }
|
||||||
|
|
||||||
virtual void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); }
|
virtual void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); }
|
||||||
virtual void pluginUpdate(float deltaTime, bool jointsCaptured) override;
|
virtual void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override;
|
||||||
|
|
||||||
void keyPressEvent(QKeyEvent* event);
|
void keyPressEvent(QKeyEvent* event);
|
||||||
void keyReleaseEvent(QKeyEvent* event);
|
void keyReleaseEvent(QKeyEvent* event);
|
||||||
|
@ -97,7 +97,7 @@ protected:
|
||||||
// Device functions
|
// Device functions
|
||||||
virtual controller::Input::NamedVector getAvailableInputs() const override;
|
virtual controller::Input::NamedVector getAvailableInputs() const override;
|
||||||
virtual QString getDefaultMappingConfig() const override;
|
virtual QString getDefaultMappingConfig() const override;
|
||||||
virtual void update(float deltaTime, bool jointsCaptured) override;
|
virtual void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override;
|
||||||
virtual void focusOutEvent() override;
|
virtual void focusOutEvent() override;
|
||||||
|
|
||||||
// Let's make it easy for Qt because we assume we love Qt forever
|
// Let's make it easy for Qt because we assume we love Qt forever
|
||||||
|
|
|
@ -111,7 +111,7 @@ controller::Input::NamedPair SpacemouseDevice::makePair(SpacemouseDevice::Positi
|
||||||
return controller::Input::NamedPair(makeInput(axis), name);
|
return controller::Input::NamedPair(makeInput(axis), name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpacemouseDevice::update(float deltaTime, bool jointsCaptured) {
|
void SpacemouseDevice::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) {
|
||||||
// the update is done in the SpacemouseManager class.
|
// 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 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
|
// for osx the api will call DeviceAddedHandler or DeviceRemoveHandler when a 3Dconnexion device is attached or detached
|
||||||
|
|
|
@ -214,7 +214,7 @@ public:
|
||||||
|
|
||||||
virtual controller::Input::NamedVector getAvailableInputs() const override;
|
virtual controller::Input::NamedVector getAvailableInputs() const override;
|
||||||
virtual QString getDefaultMappingConfig() const override;
|
virtual QString getDefaultMappingConfig() const override;
|
||||||
virtual void update(float deltaTime, bool jointsCaptured) override;
|
virtual void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override;
|
||||||
virtual void focusOutEvent() override;
|
virtual void focusOutEvent() override;
|
||||||
|
|
||||||
glm::vec3 cc_position;
|
glm::vec3 cc_position;
|
||||||
|
|
|
@ -12,12 +12,16 @@
|
||||||
|
|
||||||
#include "Plugin.h"
|
#include "Plugin.h"
|
||||||
|
|
||||||
|
namespace controller {
|
||||||
|
struct InputCalibrationData;
|
||||||
|
}
|
||||||
|
|
||||||
class InputPlugin : public Plugin {
|
class InputPlugin : public Plugin {
|
||||||
public:
|
public:
|
||||||
virtual bool isJointController() const = 0;
|
virtual bool isJointController() const = 0;
|
||||||
|
|
||||||
virtual void pluginFocusOutEvent() = 0;
|
virtual void pluginFocusOutEvent() = 0;
|
||||||
|
|
||||||
virtual void pluginUpdate(float deltaTime, bool jointsCaptured) = 0;
|
virtual void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -407,7 +407,14 @@ glm::vec3 transformPoint(const glm::mat4& m, const glm::vec3& p) {
|
||||||
return glm::vec3(temp.x / temp.w, temp.y / temp.w, temp.z / temp.w);
|
return glm::vec3(temp.x / temp.w, temp.y / temp.w, temp.z / temp.w);
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec3 transformVector(const glm::mat4& m, const glm::vec3& v) {
|
// does not handle non-uniform scale correctly, but it's faster then transformVectorFull
|
||||||
|
glm::vec3 transformVectorFast(const glm::mat4& m, const glm::vec3& v) {
|
||||||
|
glm::mat3 rot(m);
|
||||||
|
return rot * v;
|
||||||
|
}
|
||||||
|
|
||||||
|
// handles non-uniform scale.
|
||||||
|
glm::vec3 transformVectorFull(const glm::mat4& m, const glm::vec3& v) {
|
||||||
glm::mat3 rot(m);
|
glm::mat3 rot(m);
|
||||||
return glm::inverse(glm::transpose(rot)) * v;
|
return glm::inverse(glm::transpose(rot)) * v;
|
||||||
}
|
}
|
||||||
|
@ -437,7 +444,7 @@ glm::vec2 getFacingDir2D(const glm::quat& rot) {
|
||||||
}
|
}
|
||||||
|
|
||||||
glm::vec2 getFacingDir2D(const glm::mat4& m) {
|
glm::vec2 getFacingDir2D(const glm::mat4& m) {
|
||||||
glm::vec3 facing3D = transformVector(m, Vectors::UNIT_NEG_Z);
|
glm::vec3 facing3D = transformVectorFast(m, Vectors::UNIT_NEG_Z);
|
||||||
glm::vec2 facing2D(facing3D.x, facing3D.z);
|
glm::vec2 facing2D(facing3D.x, facing3D.z);
|
||||||
const float ALMOST_ZERO = 0.0001f;
|
const float ALMOST_ZERO = 0.0001f;
|
||||||
if (glm::length(facing2D) < ALMOST_ZERO) {
|
if (glm::length(facing2D) < ALMOST_ZERO) {
|
||||||
|
|
|
@ -215,7 +215,8 @@ glm::mat4 createMatFromQuatAndPos(const glm::quat& q, const glm::vec3& p);
|
||||||
glm::quat cancelOutRollAndPitch(const glm::quat& q);
|
glm::quat cancelOutRollAndPitch(const glm::quat& q);
|
||||||
glm::mat4 cancelOutRollAndPitch(const glm::mat4& m);
|
glm::mat4 cancelOutRollAndPitch(const glm::mat4& m);
|
||||||
glm::vec3 transformPoint(const glm::mat4& m, const glm::vec3& p);
|
glm::vec3 transformPoint(const glm::mat4& m, const glm::vec3& p);
|
||||||
glm::vec3 transformVector(const glm::mat4& m, const glm::vec3& v);
|
glm::vec3 transformVectorFast(const glm::mat4& m, const glm::vec3& v);
|
||||||
|
glm::vec3 transformVectorFull(const glm::mat4& m, const glm::vec3& v);
|
||||||
|
|
||||||
// Calculate an orthogonal basis from a primary and secondary axis.
|
// Calculate an orthogonal basis from a primary and secondary axis.
|
||||||
// The uAxis, vAxis & wAxis will form an orthognal basis.
|
// The uAxis, vAxis & wAxis will form an orthognal basis.
|
||||||
|
|
|
@ -498,14 +498,14 @@ void NeuronPlugin::deactivate() {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void NeuronPlugin::pluginUpdate(float deltaTime, bool jointsCaptured) {
|
void NeuronPlugin::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) {
|
||||||
std::vector<NeuronJoint> joints;
|
std::vector<NeuronJoint> joints;
|
||||||
{
|
{
|
||||||
// lock and copy
|
// lock and copy
|
||||||
std::lock_guard<std::mutex> guard(_jointsMutex);
|
std::lock_guard<std::mutex> guard(_jointsMutex);
|
||||||
joints = _joints;
|
joints = _joints;
|
||||||
}
|
}
|
||||||
_inputDevice->update(deltaTime, joints, _prevJoints);
|
_inputDevice->update(deltaTime, inputCalibrationData, joints, _prevJoints);
|
||||||
_prevJoints = joints;
|
_prevJoints = joints;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -537,7 +537,7 @@ QString NeuronPlugin::InputDevice::getDefaultMappingConfig() const {
|
||||||
return MAPPING_JSON;
|
return MAPPING_JSON;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NeuronPlugin::InputDevice::update(float deltaTime, const std::vector<NeuronPlugin::NeuronJoint>& joints, const std::vector<NeuronPlugin::NeuronJoint>& prevJoints) {
|
void NeuronPlugin::InputDevice::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, const std::vector<NeuronPlugin::NeuronJoint>& joints, const std::vector<NeuronPlugin::NeuronJoint>& prevJoints) {
|
||||||
for (size_t i = 0; i < joints.size(); i++) {
|
for (size_t i = 0; i < joints.size(); i++) {
|
||||||
glm::vec3 linearVel, angularVel;
|
glm::vec3 linearVel, angularVel;
|
||||||
glm::vec3 pos = joints[i].pos;
|
glm::vec3 pos = joints[i].pos;
|
||||||
|
|
|
@ -35,7 +35,7 @@ public:
|
||||||
virtual void deactivate() override;
|
virtual void deactivate() override;
|
||||||
|
|
||||||
virtual void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); }
|
virtual void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); }
|
||||||
virtual void pluginUpdate(float deltaTime, bool jointsCaptured) override;
|
virtual void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override;
|
||||||
|
|
||||||
virtual void saveSettings() const override;
|
virtual void saveSettings() const override;
|
||||||
virtual void loadSettings() override;
|
virtual void loadSettings() override;
|
||||||
|
@ -56,10 +56,10 @@ protected:
|
||||||
// Device functions
|
// Device functions
|
||||||
virtual controller::Input::NamedVector getAvailableInputs() const override;
|
virtual controller::Input::NamedVector getAvailableInputs() const override;
|
||||||
virtual QString getDefaultMappingConfig() const override;
|
virtual QString getDefaultMappingConfig() const override;
|
||||||
virtual void update(float deltaTime, bool jointsCaptured) override {};
|
virtual void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override {};
|
||||||
virtual void focusOutEvent() override {};
|
virtual void focusOutEvent() override {};
|
||||||
|
|
||||||
void update(float deltaTime, const std::vector<NeuronPlugin::NeuronJoint>& joints, const std::vector<NeuronPlugin::NeuronJoint>& prevJoints);
|
void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, const std::vector<NeuronPlugin::NeuronJoint>& joints, const std::vector<NeuronPlugin::NeuronJoint>& prevJoints);
|
||||||
};
|
};
|
||||||
|
|
||||||
std::shared_ptr<InputDevice> _inputDevice { std::make_shared<InputDevice>() };
|
std::shared_ptr<InputDevice> _inputDevice { std::make_shared<InputDevice>() };
|
||||||
|
|
|
@ -39,7 +39,7 @@ void Joystick::closeJoystick() {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void Joystick::update(float deltaTime, bool jointsCaptured) {
|
void Joystick::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) {
|
||||||
for (auto axisState : _axisStateMap) {
|
for (auto axisState : _axisStateMap) {
|
||||||
if (fabsf(axisState.second) < CONTROLLER_THRESHOLD) {
|
if (fabsf(axisState.second) < CONTROLLER_THRESHOLD) {
|
||||||
_axisStateMap[axisState.first] = 0.0f;
|
_axisStateMap[axisState.first] = 0.0f;
|
||||||
|
|
|
@ -39,7 +39,7 @@ public:
|
||||||
// Device functions
|
// Device functions
|
||||||
virtual controller::Input::NamedVector getAvailableInputs() const override;
|
virtual controller::Input::NamedVector getAvailableInputs() const override;
|
||||||
virtual QString getDefaultMappingConfig() const override;
|
virtual QString getDefaultMappingConfig() const override;
|
||||||
virtual void update(float deltaTime, bool jointsCaptured) override;
|
virtual void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override;
|
||||||
virtual void focusOutEvent() override;
|
virtual void focusOutEvent() override;
|
||||||
|
|
||||||
Joystick() : InputDevice("GamePad") {}
|
Joystick() : InputDevice("GamePad") {}
|
||||||
|
|
|
@ -138,12 +138,12 @@ void SDL2Manager::pluginFocusOutEvent() {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDL2Manager::pluginUpdate(float deltaTime, bool jointsCaptured) {
|
void SDL2Manager::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) {
|
||||||
#ifdef HAVE_SDL2
|
#ifdef HAVE_SDL2
|
||||||
if (_isInitialized) {
|
if (_isInitialized) {
|
||||||
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
||||||
for (auto joystick : _openJoysticks) {
|
for (auto joystick : _openJoysticks) {
|
||||||
joystick->update(deltaTime, jointsCaptured);
|
joystick->update(deltaTime, inputCalibrationData, jointsCaptured);
|
||||||
}
|
}
|
||||||
|
|
||||||
PerformanceTimer perfTimer("SDL2Manager::update");
|
PerformanceTimer perfTimer("SDL2Manager::update");
|
||||||
|
|
|
@ -40,7 +40,7 @@ public:
|
||||||
virtual void deactivate() override;
|
virtual void deactivate() override;
|
||||||
|
|
||||||
virtual void pluginFocusOutEvent() override;
|
virtual void pluginFocusOutEvent() override;
|
||||||
virtual void pluginUpdate(float deltaTime, bool jointsCaptured) override;
|
virtual void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void joystickAdded(Joystick* joystick);
|
void joystickAdded(Joystick* joystick);
|
||||||
|
|
|
@ -132,16 +132,16 @@ void SixenseManager::setSixenseFilter(bool filter) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SixenseManager::pluginUpdate(float deltaTime, bool jointsCaptured) {
|
void SixenseManager::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) {
|
||||||
BAIL_IF_NOT_LOADED
|
BAIL_IF_NOT_LOADED
|
||||||
_inputDevice->update(deltaTime, jointsCaptured);
|
_inputDevice->update(deltaTime, inputCalibrationData, jointsCaptured);
|
||||||
if (_inputDevice->_requestReset) {
|
if (_inputDevice->_requestReset) {
|
||||||
_container->requestReset();
|
_container->requestReset();
|
||||||
_inputDevice->_requestReset = false;
|
_inputDevice->_requestReset = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SixenseManager::InputDevice::update(float deltaTime, bool jointsCaptured) {
|
void SixenseManager::InputDevice::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) {
|
||||||
BAIL_IF_NOT_LOADED
|
BAIL_IF_NOT_LOADED
|
||||||
#ifdef HAVE_SIXENSE
|
#ifdef HAVE_SIXENSE
|
||||||
_buttonPressedMap.clear();
|
_buttonPressedMap.clear();
|
||||||
|
@ -205,7 +205,7 @@ void SixenseManager::InputDevice::update(float deltaTime, bool jointsCaptured) {
|
||||||
if (!jointsCaptured) {
|
if (!jointsCaptured) {
|
||||||
// Rotation of Palm
|
// Rotation of Palm
|
||||||
glm::quat rotation(data->rot_quat[3], data->rot_quat[0], data->rot_quat[1], data->rot_quat[2]);
|
glm::quat rotation(data->rot_quat[3], data->rot_quat[0], data->rot_quat[1], data->rot_quat[2]);
|
||||||
handlePoseEvent(deltaTime, position, rotation, left);
|
handlePoseEvent(deltaTime, inputCalibrationData, position, rotation, left);
|
||||||
rawPoses[i] = controller::Pose(position, rotation, Vectors::ZERO, Vectors::ZERO);
|
rawPoses[i] = controller::Pose(position, rotation, Vectors::ZERO, Vectors::ZERO);
|
||||||
} else {
|
} else {
|
||||||
_poseStateMap.clear();
|
_poseStateMap.clear();
|
||||||
|
@ -415,7 +415,7 @@ void SixenseManager::InputDevice::handleButtonEvent(unsigned int buttons, bool l
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SixenseManager::InputDevice::handlePoseEvent(float deltaTime, glm::vec3 position, glm::quat rotation, bool left) {
|
void SixenseManager::InputDevice::handlePoseEvent(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, const glm::vec3& position, const glm::quat& rotation, bool left) {
|
||||||
BAIL_IF_NOT_LOADED
|
BAIL_IF_NOT_LOADED
|
||||||
#ifdef HAVE_SIXENSE
|
#ifdef HAVE_SIXENSE
|
||||||
auto hand = left ? controller::StandardPoseChannel::LEFT_HAND : controller::StandardPoseChannel::RIGHT_HAND;
|
auto hand = left ? controller::StandardPoseChannel::LEFT_HAND : controller::StandardPoseChannel::RIGHT_HAND;
|
||||||
|
@ -437,7 +437,7 @@ void SixenseManager::InputDevice::handlePoseEvent(float deltaTime, glm::vec3 pos
|
||||||
auto prevPose = _poseStateMap[hand];
|
auto prevPose = _poseStateMap[hand];
|
||||||
|
|
||||||
// Transform the measured position into body frame.
|
// Transform the measured position into body frame.
|
||||||
position = _avatarRotation * (position + _avatarPosition);
|
vec3 pos = _avatarRotation * (position + _avatarPosition);
|
||||||
|
|
||||||
// From ABOVE the hand canonical axes look like this:
|
// From ABOVE the hand canonical axes look like this:
|
||||||
//
|
//
|
||||||
|
@ -476,7 +476,7 @@ void SixenseManager::InputDevice::handlePoseEvent(float deltaTime, glm::vec3 pos
|
||||||
// rotation = postOffset * Qsh^ * (measuredRotation * preOffset) * Qsh
|
// rotation = postOffset * Qsh^ * (measuredRotation * preOffset) * Qsh
|
||||||
//
|
//
|
||||||
// TODO: find a shortcut with fewer rotations.
|
// TODO: find a shortcut with fewer rotations.
|
||||||
rotation = _avatarRotation * postOffset * glm::inverse(sixenseToHand) * rotation * preOffset * sixenseToHand;
|
glm::quat rot = _avatarRotation * postOffset * glm::inverse(sixenseToHand) * rotation * preOffset * sixenseToHand;
|
||||||
|
|
||||||
glm::vec3 velocity(0.0f);
|
glm::vec3 velocity(0.0f);
|
||||||
glm::vec3 angularVelocity(0.0f);
|
glm::vec3 angularVelocity(0.0f);
|
||||||
|
@ -484,11 +484,11 @@ void SixenseManager::InputDevice::handlePoseEvent(float deltaTime, glm::vec3 pos
|
||||||
if (prevPose.isValid() && deltaTime > std::numeric_limits<float>::epsilon()) {
|
if (prevPose.isValid() && deltaTime > std::numeric_limits<float>::epsilon()) {
|
||||||
auto& samples = _collectedSamples[hand];
|
auto& samples = _collectedSamples[hand];
|
||||||
|
|
||||||
velocity = (position - prevPose.getTranslation()) / deltaTime;
|
velocity = (pos - prevPose.getTranslation()) / deltaTime;
|
||||||
samples.first.addSample(velocity);
|
samples.first.addSample(velocity);
|
||||||
velocity = samples.first.average;
|
velocity = samples.first.average;
|
||||||
|
|
||||||
auto deltaRot = glm::normalize(rotation * glm::conjugate(prevPose.getRotation()));
|
auto deltaRot = glm::normalize(rot * glm::conjugate(prevPose.getRotation()));
|
||||||
auto axis = glm::axis(deltaRot);
|
auto axis = glm::axis(deltaRot);
|
||||||
auto speed = glm::angle(deltaRot) / deltaTime;
|
auto speed = glm::angle(deltaRot) / deltaTime;
|
||||||
assert(!glm::isnan(speed));
|
assert(!glm::isnan(speed));
|
||||||
|
@ -500,7 +500,10 @@ void SixenseManager::InputDevice::handlePoseEvent(float deltaTime, glm::vec3 pos
|
||||||
_collectedSamples[hand].second.clear();
|
_collectedSamples[hand].second.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
_poseStateMap[hand] = controller::Pose(position, rotation, velocity, angularVelocity);
|
// transform pose into avatar frame.
|
||||||
|
glm::mat4 controllerToAvatar = glm::inverse(inputCalibrationData.avatarMat) * inputCalibrationData.sensorToWorldMat;
|
||||||
|
auto avatarPose = controller::Pose(pos, rot, velocity, angularVelocity).transform(controllerToAvatar);
|
||||||
|
_poseStateMap[hand] = avatarPose;
|
||||||
#endif // HAVE_SIXENSE
|
#endif // HAVE_SIXENSE
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ public:
|
||||||
virtual void deactivate() override;
|
virtual void deactivate() override;
|
||||||
|
|
||||||
virtual void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); }
|
virtual void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); }
|
||||||
virtual void pluginUpdate(float deltaTime, bool jointsCaptured) override;
|
virtual void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override;
|
||||||
|
|
||||||
virtual void saveSettings() const override;
|
virtual void saveSettings() const override;
|
||||||
virtual void loadSettings() override;
|
virtual void loadSettings() override;
|
||||||
|
@ -66,11 +66,11 @@ private:
|
||||||
// Device functions
|
// Device functions
|
||||||
virtual controller::Input::NamedVector getAvailableInputs() const override;
|
virtual controller::Input::NamedVector getAvailableInputs() const override;
|
||||||
virtual QString getDefaultMappingConfig() const override;
|
virtual QString getDefaultMappingConfig() const override;
|
||||||
virtual void update(float deltaTime, bool jointsCaptured) override;
|
virtual void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override;
|
||||||
virtual void focusOutEvent() override;
|
virtual void focusOutEvent() override;
|
||||||
|
|
||||||
void handleButtonEvent(unsigned int buttons, bool left);
|
void handleButtonEvent(unsigned int buttons, bool left);
|
||||||
void handlePoseEvent(float deltaTime, glm::vec3 position, glm::quat rotation, bool left);
|
void handlePoseEvent(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, const glm::vec3& position, const glm::quat& rotation, bool left);
|
||||||
void updateCalibration(SixenseControllerData* controllers);
|
void updateCalibration(SixenseControllerData* controllers);
|
||||||
|
|
||||||
friend class SixenseManager;
|
friend class SixenseManager;
|
||||||
|
|
|
@ -102,7 +102,7 @@ void ViveControllerManager::activate() {
|
||||||
// vertexBufferPtr->getSize() - sizeof(float) * 2,
|
// vertexBufferPtr->getSize() - sizeof(float) * 2,
|
||||||
// sizeof(vr::RenderModel_Vertex_t),
|
// sizeof(vr::RenderModel_Vertex_t),
|
||||||
// gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::RAW)));
|
// gpu::Element(gpu::VEC2, gpu::FLOAT, gpu::RAW)));
|
||||||
|
|
||||||
gpu::Element formatGPU = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA);
|
gpu::Element formatGPU = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA);
|
||||||
gpu::Element formatMip = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA);
|
gpu::Element formatMip = gpu::Element(gpu::VEC4, gpu::NUINT8, gpu::RGBA);
|
||||||
_texture = gpu::TexturePointer(
|
_texture = gpu::TexturePointer(
|
||||||
|
@ -205,8 +205,8 @@ void ViveControllerManager::renderHand(const controller::Pose& pose, gpu::Batch&
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ViveControllerManager::pluginUpdate(float deltaTime, bool jointsCaptured) {
|
void ViveControllerManager::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) {
|
||||||
_inputDevice->update(deltaTime, jointsCaptured);
|
_inputDevice->update(deltaTime, inputCalibrationData, jointsCaptured);
|
||||||
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
||||||
|
|
||||||
if (_inputDevice->_trackedControllers == 0 && _registeredWithInputMapper) {
|
if (_inputDevice->_trackedControllers == 0 && _registeredWithInputMapper) {
|
||||||
|
@ -222,7 +222,7 @@ void ViveControllerManager::pluginUpdate(float deltaTime, bool jointsCaptured) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViveControllerManager::InputDevice::update(float deltaTime, bool jointsCaptured) {
|
void ViveControllerManager::InputDevice::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) {
|
||||||
_poseStateMap.clear();
|
_poseStateMap.clear();
|
||||||
|
|
||||||
_buttonPressedMap.clear();
|
_buttonPressedMap.clear();
|
||||||
|
@ -232,29 +232,29 @@ void ViveControllerManager::InputDevice::update(float deltaTime, bool jointsCapt
|
||||||
int numTrackedControllers = 0;
|
int numTrackedControllers = 0;
|
||||||
|
|
||||||
for (vr::TrackedDeviceIndex_t device = vr::k_unTrackedDeviceIndex_Hmd + 1;
|
for (vr::TrackedDeviceIndex_t device = vr::k_unTrackedDeviceIndex_Hmd + 1;
|
||||||
device < vr::k_unMaxTrackedDeviceCount && numTrackedControllers < 2; ++device) {
|
device < vr::k_unMaxTrackedDeviceCount && numTrackedControllers < 2; ++device) {
|
||||||
|
|
||||||
if (!_hmd->IsTrackedDeviceConnected(device)) {
|
if (!_hmd->IsTrackedDeviceConnected(device)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_hmd->GetTrackedDeviceClass(device) != vr::TrackedDeviceClass_Controller) {
|
if (_hmd->GetTrackedDeviceClass(device) != vr::TrackedDeviceClass_Controller) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_trackedDevicePose[device].bPoseIsValid) {
|
if (!_trackedDevicePose[device].bPoseIsValid) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
numTrackedControllers++;
|
numTrackedControllers++;
|
||||||
bool left = numTrackedControllers == 2;
|
bool left = numTrackedControllers == 2;
|
||||||
|
|
||||||
const mat4& mat = _trackedDevicePoseMat4[device];
|
const mat4& mat = _trackedDevicePoseMat4[device];
|
||||||
|
|
||||||
if (!jointsCaptured) {
|
if (!jointsCaptured) {
|
||||||
handlePoseEvent(mat, numTrackedControllers - 1);
|
handlePoseEvent(inputCalibrationData, mat, numTrackedControllers - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle inputs
|
// handle inputs
|
||||||
vr::VRControllerState_t controllerState = vr::VRControllerState_t();
|
vr::VRControllerState_t controllerState = vr::VRControllerState_t();
|
||||||
if (_hmd->GetControllerState(device, &controllerState)) {
|
if (_hmd->GetControllerState(device, &controllerState)) {
|
||||||
|
@ -271,7 +271,7 @@ void ViveControllerManager::InputDevice::update(float deltaTime, bool jointsCapt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_trackedControllers = numTrackedControllers;
|
_trackedControllers = numTrackedControllers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -314,7 +314,7 @@ void ViveControllerManager::InputDevice::handleButtonEvent(uint32_t button, bool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViveControllerManager::InputDevice::handlePoseEvent(const mat4& mat, bool left) {
|
void ViveControllerManager::InputDevice::handlePoseEvent(const controller::InputCalibrationData& inputCalibrationData, const mat4& mat, bool left) {
|
||||||
// When the sensor-to-world rotation is identity the coordinate axes look like this:
|
// When the sensor-to-world rotation is identity the coordinate axes look like this:
|
||||||
//
|
//
|
||||||
// user
|
// user
|
||||||
|
@ -342,11 +342,11 @@ void ViveControllerManager::InputDevice::handlePoseEvent(const mat4& mat, bool l
|
||||||
// | | | |
|
// | | | |
|
||||||
//
|
//
|
||||||
|
|
||||||
// So when the user is standing in Vive space facing the -zAxis with hands outstretched and palms down
|
// So when the user is standing in Vive space facing the -zAxis with hands outstretched and palms down
|
||||||
// the rotation to align the Vive axes with those of the hands is:
|
// the rotation to align the Vive axes with those of the hands is:
|
||||||
//
|
//
|
||||||
// QviveToHand = halfTurnAboutY * quaterTurnAboutX
|
// QviveToHand = halfTurnAboutY * quaterTurnAboutX
|
||||||
|
|
||||||
// Due to how the Vive controllers fit into the palm there is an offset that is different for each hand.
|
// Due to how the Vive controllers fit into the palm there is an offset that is different for each hand.
|
||||||
// You can think of this offset as the inverse of the measured rotation when the hands are posed, such that
|
// You can think of this offset as the inverse of the measured rotation when the hands are posed, such that
|
||||||
// the combination (measurement * offset) is identity at this orientation.
|
// the combination (measurement * offset) is identity at this orientation.
|
||||||
|
@ -384,8 +384,11 @@ void ViveControllerManager::InputDevice::handlePoseEvent(const mat4& mat, bool l
|
||||||
|
|
||||||
position += rotation * (left ? leftTranslationOffset : rightTranslationOffset);
|
position += rotation * (left ? leftTranslationOffset : rightTranslationOffset);
|
||||||
rotation = rotation * (left ? leftRotationOffset : rightRotationOffset);
|
rotation = rotation * (left ? leftRotationOffset : rightRotationOffset);
|
||||||
|
|
||||||
_poseStateMap[left ? controller::LEFT_HAND : controller::RIGHT_HAND] = controller::Pose(position, rotation);
|
// transform into avatar frame
|
||||||
|
glm::mat4 controllerToAvatar = glm::inverse(inputCalibrationData.avatarMat) * inputCalibrationData.sensorToWorldMat;
|
||||||
|
auto avatarPose = controller::Pose(position, rotation).transform(controllerToAvatar);
|
||||||
|
_poseStateMap[left ? controller::LEFT_HAND : controller::RIGHT_HAND] = avatarPose;
|
||||||
}
|
}
|
||||||
|
|
||||||
controller::Input::NamedVector ViveControllerManager::InputDevice::getAvailableInputs() const {
|
controller::Input::NamedVector ViveControllerManager::InputDevice::getAvailableInputs() const {
|
||||||
|
@ -436,7 +439,7 @@ QString ViveControllerManager::InputDevice::getDefaultMappingConfig() const {
|
||||||
|
|
||||||
//void ViveControllerManager::assignDefaultInputMapping(UserInputMapper& mapper) {
|
//void ViveControllerManager::assignDefaultInputMapping(UserInputMapper& mapper) {
|
||||||
// const float JOYSTICK_MOVE_SPEED = 1.0f;
|
// const float JOYSTICK_MOVE_SPEED = 1.0f;
|
||||||
//
|
//
|
||||||
// // Left Trackpad: Movement, strafing
|
// // Left Trackpad: Movement, strafing
|
||||||
// mapper.addInputChannel(UserInputMapper::LONGITUDINAL_FORWARD, makeInput(AXIS_Y_POS, 0), makeInput(TRACKPAD_BUTTON, 0), JOYSTICK_MOVE_SPEED);
|
// mapper.addInputChannel(UserInputMapper::LONGITUDINAL_FORWARD, makeInput(AXIS_Y_POS, 0), makeInput(TRACKPAD_BUTTON, 0), JOYSTICK_MOVE_SPEED);
|
||||||
// mapper.addInputChannel(UserInputMapper::LONGITUDINAL_BACKWARD, makeInput(AXIS_Y_NEG, 0), makeInput(TRACKPAD_BUTTON, 0), JOYSTICK_MOVE_SPEED);
|
// mapper.addInputChannel(UserInputMapper::LONGITUDINAL_BACKWARD, makeInput(AXIS_Y_NEG, 0), makeInput(TRACKPAD_BUTTON, 0), JOYSTICK_MOVE_SPEED);
|
||||||
|
@ -446,17 +449,17 @@ QString ViveControllerManager::InputDevice::getDefaultMappingConfig() const {
|
||||||
// // Right Trackpad: Vertical movement, zooming
|
// // Right Trackpad: Vertical movement, zooming
|
||||||
// mapper.addInputChannel(UserInputMapper::VERTICAL_UP, makeInput(AXIS_Y_POS, 1), makeInput(TRACKPAD_BUTTON, 1), JOYSTICK_MOVE_SPEED);
|
// mapper.addInputChannel(UserInputMapper::VERTICAL_UP, makeInput(AXIS_Y_POS, 1), makeInput(TRACKPAD_BUTTON, 1), JOYSTICK_MOVE_SPEED);
|
||||||
// mapper.addInputChannel(UserInputMapper::VERTICAL_DOWN, makeInput(AXIS_Y_NEG, 1), makeInput(TRACKPAD_BUTTON, 1), JOYSTICK_MOVE_SPEED);
|
// mapper.addInputChannel(UserInputMapper::VERTICAL_DOWN, makeInput(AXIS_Y_NEG, 1), makeInput(TRACKPAD_BUTTON, 1), JOYSTICK_MOVE_SPEED);
|
||||||
//
|
//
|
||||||
// // Buttons
|
// // Buttons
|
||||||
// mapper.addInputChannel(UserInputMapper::SHIFT, makeInput(BUTTON_A, 0));
|
// mapper.addInputChannel(UserInputMapper::SHIFT, makeInput(BUTTON_A, 0));
|
||||||
// mapper.addInputChannel(UserInputMapper::SHIFT, makeInput(BUTTON_A, 1));
|
// mapper.addInputChannel(UserInputMapper::SHIFT, makeInput(BUTTON_A, 1));
|
||||||
//
|
//
|
||||||
// mapper.addInputChannel(UserInputMapper::ACTION1, makeInput(GRIP_BUTTON, 0));
|
// mapper.addInputChannel(UserInputMapper::ACTION1, makeInput(GRIP_BUTTON, 0));
|
||||||
// mapper.addInputChannel(UserInputMapper::ACTION2, makeInput(GRIP_BUTTON, 1));
|
// mapper.addInputChannel(UserInputMapper::ACTION2, makeInput(GRIP_BUTTON, 1));
|
||||||
//
|
//
|
||||||
// mapper.addInputChannel(UserInputMapper::LEFT_HAND_CLICK, makeInput(BACK_TRIGGER, 0));
|
// mapper.addInputChannel(UserInputMapper::LEFT_HAND_CLICK, makeInput(BACK_TRIGGER, 0));
|
||||||
// mapper.addInputChannel(UserInputMapper::RIGHT_HAND_CLICK, makeInput(BACK_TRIGGER, 1));
|
// mapper.addInputChannel(UserInputMapper::RIGHT_HAND_CLICK, makeInput(BACK_TRIGGER, 1));
|
||||||
//
|
//
|
||||||
// // Hands
|
// // Hands
|
||||||
// mapper.addInputChannel(UserInputMapper::LEFT_HAND, makeInput(LEFT_HAND));
|
// mapper.addInputChannel(UserInputMapper::LEFT_HAND, makeInput(LEFT_HAND));
|
||||||
// mapper.addInputChannel(UserInputMapper::RIGHT_HAND, makeInput(RIGHT_HAND));
|
// mapper.addInputChannel(UserInputMapper::RIGHT_HAND, makeInput(RIGHT_HAND));
|
||||||
|
|
|
@ -41,7 +41,7 @@ public:
|
||||||
virtual void deactivate() override;
|
virtual void deactivate() override;
|
||||||
|
|
||||||
virtual void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); }
|
virtual void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); }
|
||||||
virtual void pluginUpdate(float deltaTime, bool jointsCaptured) override;
|
virtual void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override;
|
||||||
|
|
||||||
void updateRendering(RenderArgs* args, render::ScenePointer scene, render::PendingChanges pendingChanges);
|
void updateRendering(RenderArgs* args, render::ScenePointer scene, render::PendingChanges pendingChanges);
|
||||||
|
|
||||||
|
@ -55,12 +55,12 @@ private:
|
||||||
// Device functions
|
// Device functions
|
||||||
virtual controller::Input::NamedVector getAvailableInputs() const override;
|
virtual controller::Input::NamedVector getAvailableInputs() const override;
|
||||||
virtual QString getDefaultMappingConfig() const override;
|
virtual QString getDefaultMappingConfig() const override;
|
||||||
virtual void update(float deltaTime, bool jointsCaptured) override;
|
virtual void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override;
|
||||||
virtual void focusOutEvent() override;
|
virtual void focusOutEvent() override;
|
||||||
|
|
||||||
void handleButtonEvent(uint32_t button, bool pressed, bool left);
|
void handleButtonEvent(uint32_t button, bool pressed, bool left);
|
||||||
void handleAxisEvent(uint32_t axis, float x, float y, bool left);
|
void handleAxisEvent(uint32_t axis, float x, float y, bool left);
|
||||||
void handlePoseEvent(const mat4& mat, bool left);
|
void handlePoseEvent(const controller::InputCalibrationData& inputCalibrationData, const mat4& mat, bool left);
|
||||||
|
|
||||||
int _trackedControllers { 0 };
|
int _trackedControllers { 0 };
|
||||||
vr::IVRSystem*& _hmd;
|
vr::IVRSystem*& _hmd;
|
||||||
|
|
|
@ -123,8 +123,14 @@ int main(int argc, char** argv) {
|
||||||
float delta = now - last;
|
float delta = now - last;
|
||||||
last = now;
|
last = now;
|
||||||
|
|
||||||
|
InputCalibrationData calibrationData = {
|
||||||
|
glm::mat4(),
|
||||||
|
glm::mat4(),
|
||||||
|
glm::mat4()
|
||||||
|
};
|
||||||
|
|
||||||
foreach(auto inputPlugin, PluginManager::getInstance()->getInputPlugins()) {
|
foreach(auto inputPlugin, PluginManager::getInstance()->getInputPlugins()) {
|
||||||
inputPlugin->pluginUpdate(delta, false);
|
inputPlugin->pluginUpdate(delta, calibrationData, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
||||||
|
@ -133,6 +139,12 @@ int main(int argc, char** argv) {
|
||||||
timer.start(50);
|
timer.start(50);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
InputCalibrationData calibrationData = {
|
||||||
|
glm::mat4(),
|
||||||
|
glm::mat4(),
|
||||||
|
glm::mat4()
|
||||||
|
};
|
||||||
|
|
||||||
DependencyManager::set<controller::UserInputMapper>();
|
DependencyManager::set<controller::UserInputMapper>();
|
||||||
foreach(auto inputPlugin, PluginManager::getInstance()->getInputPlugins()) {
|
foreach(auto inputPlugin, PluginManager::getInstance()->getInputPlugins()) {
|
||||||
QString name = inputPlugin->getName();
|
QString name = inputPlugin->getName();
|
||||||
|
@ -141,7 +153,7 @@ int main(int argc, char** argv) {
|
||||||
if (name == KeyboardMouseDevice::NAME) {
|
if (name == KeyboardMouseDevice::NAME) {
|
||||||
userInputMapper->registerDevice(std::dynamic_pointer_cast<KeyboardMouseDevice>(inputPlugin)->getInputDevice());
|
userInputMapper->registerDevice(std::dynamic_pointer_cast<KeyboardMouseDevice>(inputPlugin)->getInputDevice());
|
||||||
}
|
}
|
||||||
inputPlugin->pluginUpdate(0, false);
|
inputPlugin->pluginUpdate(0, calibrationData, false);
|
||||||
}
|
}
|
||||||
rootContext->setContextProperty("Controllers", new MyControllerScriptingInterface());
|
rootContext->setContextProperty("Controllers", new MyControllerScriptingInterface());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue