moved low velocity filter in the input system

This commit is contained in:
Dante Ruiz 2017-05-16 00:15:06 +01:00
parent e414064586
commit 975b1ab077
12 changed files with 100 additions and 71 deletions

View file

@ -3622,10 +3622,6 @@ void Application::idle(float nsecsElapsed) {
_overlayConductor.update(secondsSinceLastUpdate);
}
void Application::setLowVelocityFilter(bool lowVelocityFilter) {
controller::InputDevice::setLowVelocityFilter(lowVelocityFilter);
}
ivec2 Application::getMouse() const {
return getApplicationCompositor().getReticlePosition();
}

View file

@ -324,7 +324,6 @@ public slots:
void updateThreadPoolCount() const;
void updateSystemTabletMode();
static void setLowVelocityFilter(bool lowVelocityFilter);
Q_INVOKABLE void loadDialog();
Q_INVOKABLE void loadScriptURLDialog() const;
void toggleLogDialog();

View file

@ -538,8 +538,6 @@ Menu::Menu() {
MenuWrapper* handOptionsMenu = developerMenu->addMenu("Hands");
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false,
avatar.get(), SLOT(setEnableDebugDrawHandControllers(bool)));
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::LowVelocityFilter, 0, true,
qApp, SLOT(setLowVelocityFilter(bool)));
MenuWrapper* leapOptionsMenu = handOptionsMenu->addMenu("Leap Motion");
addCheckableActionToQMenuAndActionHash(leapOptionsMenu, MenuOption::LeapMotionOnHMD, 0, false);

View file

@ -1301,28 +1301,10 @@ void MyAvatar::rebuildCollisionShape() {
_characterController.setLocalBoundingBox(corner, diagonal);
}
static controller::Pose applyLowVelocityFilter(const controller::Pose& oldPose, const controller::Pose& newPose) {
controller::Pose finalPose = newPose;
if (newPose.isValid()) {
// Use a velocity sensitive filter to damp small motions and preserve large ones with
// no latency.
float velocityFilter = glm::clamp(1.0f - glm::length(oldPose.getVelocity()), 0.0f, 1.0f);
finalPose.translation = oldPose.getTranslation() * velocityFilter + newPose.getTranslation() * (1.0f - velocityFilter);
finalPose.rotation = safeMix(oldPose.getRotation(), newPose.getRotation(), 1.0f - velocityFilter);
}
return finalPose;
}
void MyAvatar::setHandControllerPosesInSensorFrame(const controller::Pose& left, const controller::Pose& right) {
if (controller::InputDevice::getLowVelocityFilter()) {
auto oldLeftPose = getLeftHandControllerPoseInSensorFrame();
auto oldRightPose = getRightHandControllerPoseInSensorFrame();
_leftHandControllerPoseInSensorFrameCache.set(applyLowVelocityFilter(oldLeftPose, left));
_rightHandControllerPoseInSensorFrameCache.set(applyLowVelocityFilter(oldRightPose, right));
} else {
_leftHandControllerPoseInSensorFrameCache.set(left);
_rightHandControllerPoseInSensorFrameCache.set(right);
}
_leftHandControllerPoseInSensorFrameCache.set(left);
_rightHandControllerPoseInSensorFrameCache.set(right);
}
controller::Pose MyAvatar::getLeftHandControllerPoseInSensorFrame() const {
@ -1352,15 +1334,8 @@ controller::Pose MyAvatar::getRightHandControllerPoseInAvatarFrame() const {
}
void MyAvatar::setFootControllerPosesInSensorFrame(const controller::Pose& left, const controller::Pose& right) {
if (controller::InputDevice::getLowVelocityFilter()) {
auto oldLeftPose = getLeftFootControllerPoseInSensorFrame();
auto oldRightPose = getRightFootControllerPoseInSensorFrame();
_leftFootControllerPoseInSensorFrameCache.set(applyLowVelocityFilter(oldLeftPose, left));
_rightFootControllerPoseInSensorFrameCache.set(applyLowVelocityFilter(oldRightPose, right));
} else {
_leftFootControllerPoseInSensorFrameCache.set(left);
_rightFootControllerPoseInSensorFrameCache.set(right);
}
_leftFootControllerPoseInSensorFrameCache.set(left);
_rightFootControllerPoseInSensorFrameCache.set(right);
}
controller::Pose MyAvatar::getLeftFootControllerPoseInSensorFrame() const {
@ -1390,15 +1365,8 @@ controller::Pose MyAvatar::getRightFootControllerPoseInAvatarFrame() const {
}
void MyAvatar::setSpineControllerPosesInSensorFrame(const controller::Pose& hips, const controller::Pose& spine2) {
if (controller::InputDevice::getLowVelocityFilter()) {
auto oldHipsPose = getHipsControllerPoseInSensorFrame();
auto oldSpine2Pose = getSpine2ControllerPoseInSensorFrame();
_hipsControllerPoseInSensorFrameCache.set(applyLowVelocityFilter(oldHipsPose, hips));
_spine2ControllerPoseInSensorFrameCache.set(applyLowVelocityFilter(oldSpine2Pose, spine2));
} else {
_hipsControllerPoseInSensorFrameCache.set(hips);
_spine2ControllerPoseInSensorFrameCache.set(spine2);
}
_hipsControllerPoseInSensorFrameCache.set(hips);
_spine2ControllerPoseInSensorFrameCache.set(spine2);
}
controller::Pose MyAvatar::getHipsControllerPoseInSensorFrame() const {
@ -1428,12 +1396,7 @@ controller::Pose MyAvatar::getSpine2ControllerPoseInAvatarFrame() const {
}
void MyAvatar::setHeadControllerPoseInSensorFrame(const controller::Pose& head) {
if (controller::InputDevice::getLowVelocityFilter()) {
auto oldHeadPose = getHeadControllerPoseInSensorFrame();
_headControllerPoseInSensorFrameCache.set(applyLowVelocityFilter(oldHeadPose, head));
} else {
_headControllerPoseInSensorFrameCache.set(head);
}
_headControllerPoseInSensorFrameCache.set(head);
}
controller::Pose MyAvatar::getHeadControllerPoseInSensorFrame() const {

View file

@ -15,10 +15,6 @@
namespace controller {
bool InputDevice::_lowVelocityFilter = false;
float InputDevice::_translationFilterConstant = 0.1f;
float InputDevice::_rotationFilterConstant = 0.1f;
const float DEFAULT_HAND_RETICLE_MOVE_SPEED = 37.5f;
float InputDevice::_reticleMoveSpeed = DEFAULT_HAND_RETICLE_MOVE_SPEED;

View file

@ -77,17 +77,13 @@ public:
static float getReticleMoveSpeed() { return _reticleMoveSpeed; }
static void setReticleMoveSpeed(float reticleMoveSpeed) { _reticleMoveSpeed = reticleMoveSpeed; }
static bool getLowVelocityFilter() { return _lowVelocityFilter; };
Input makeInput(StandardButtonChannel button) const;
Input makeInput(StandardAxisChannel axis) const;
Input makeInput(StandardPoseChannel pose) const;
Input::NamedPair makePair(StandardButtonChannel button, const QString& name) const;
Input::NamedPair makePair(StandardAxisChannel button, const QString& name) const;
Input::NamedPair makePair(StandardPoseChannel button, const QString& name) const;
public slots:
static void setLowVelocityFilter(bool newLowVelocityFilter) { _lowVelocityFilter = newLowVelocityFilter; };
protected:
friend class UserInputMapper;
@ -104,10 +100,6 @@ protected:
AxisStateMap _axisStateMap;
PoseStateMap _poseStateMap;
static bool _lowVelocityFilter;
static float _translationFilterConstant;
static float _rotationFilterConstant;
private:
static float _reticleMoveSpeed;
};

View file

@ -28,6 +28,7 @@
#include "filters/TransformFilter.h"
#include "filters/PostTransformFilter.h"
#include "filters/RotateFilter.h"
#include "filters/LowVelocityFilter.h"
using namespace controller;
@ -45,6 +46,7 @@ REGISTER_FILTER_CLASS_INSTANCE(TranslateFilter, "translate")
REGISTER_FILTER_CLASS_INSTANCE(TransformFilter, "transform")
REGISTER_FILTER_CLASS_INSTANCE(PostTransformFilter, "postTransform")
REGISTER_FILTER_CLASS_INSTANCE(RotateFilter, "rotate")
REGISTER_FILTER_CLASS_INSTANCE(LowVelocityFilter, "lowVelocity")
const QString JSON_FILTER_TYPE = QStringLiteral("type");
const QString JSON_FILTER_PARAMS = QStringLiteral("params");
@ -286,4 +288,4 @@ namespace controller {
// const float _max;
//};
}
#endif
#endif

View file

@ -30,6 +30,7 @@
#include "filters/TransformFilter.h"
#include "filters/PostTransformFilter.h"
#include "filters/RotateFilter.h"
#include "filters/LowVelocityFilter.h"
#include "conditionals/AndConditional.h"
using namespace controller;
@ -127,6 +128,11 @@ QObject* RouteBuilderProxy::rotate(glm::quat rotation) {
return this;
}
QObject* RouteBuilderProxy::lowVelocity(float rotationConstant, float translationConstant) {
addFilter(std::make_shared<LowVelocityFilter>(rotationConstant, translationConstant));
return this;
}
QObject* RouteBuilderProxy::constrainToInteger() {
addFilter(std::make_shared<ConstrainToIntegerFilter>());
return this;

View file

@ -52,6 +52,7 @@ class RouteBuilderProxy : public QObject {
Q_INVOKABLE QObject* transform(glm::mat4 transform);
Q_INVOKABLE QObject* postTransform(glm::mat4 transform);
Q_INVOKABLE QObject* rotate(glm::quat rotation);
Q_INVOKABLE QObject* lowVelocity(float rotationConstant, float translationConstant);
private:
void to(const Endpoint::Pointer& destination);

View file

@ -0,0 +1,46 @@
//
// Created by Dante Ruiz 2017/05/15
// Copyright 2017 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include "LowVelocityFilter.h"
#include <QtCore/QJsonObject>
#include <QtCore/QJsonArray>
static const QString JSON_ROTATION = QStringLiteral("rotation");
static const QString JSON_TRANSLATION = QStringLiteral("translation");
namespace controller {
Pose LowVelocityFilter::apply(Pose newPose) const {
Pose finalPose = newPose;
if (finalPose.isValid()) {
float rotationFilter = glm::clamp(1.0f - (glm::length(_oldPose.getVelocity() / _rotationConstant)), 0.0f, 1.0f);
float translationFilter = glm::clamp(1.0f - (glm::length(_oldPose.getVelocity() / _translationConstant)), 0.0f, 1.0f);
finalPose.translation = _oldPose.getTranslation() * translationFilter + newPose.getTranslation() * (1.0f - translationFilter);
finalPose.rotation = safeMix(_oldPose.getRotation(), newPose.getRotation(), 1.0f - rotationFilter);
}
_oldPose = finalPose;
return finalPose;
}
bool LowVelocityFilter::parseParameters(const QJsonValue& parameters) {
if (parameters.isObject()) {
auto obj = parameters.toObject();
if (obj.contains(JSON_ROTATION) && obj.contains(JSON_TRANSLATION)) {
_rotationConstant = obj[JSON_ROTATION].toDouble();
_translationConstant = obj[JSON_TRANSLATION].toDouble();
qDebug() << "--------->Successfully parsed low velocity filter";
return true;
}
}
qDebug() << "--------->failed parsed low velocity filter";
return false;
}
}

View file

@ -0,0 +1,36 @@
//
// Created by Dante Ruiz 2017/05/15
// Copyright 2017 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#ifndef hifi_Controllers_Filters_Low_Velocity_h
#define hifi_Controllers_Filters_Low_Velocity_h
#include "../Filter.h"
namespace controller {
class LowVelocityFilter : public Filter {
REGISTER_FILTER_CLASS(LowVelocityFilter);
public:
LowVelocityFilter() {}
LowVelocityFilter(float rotationConstant, float translationConstant) :
_translationConstant(translationConstant), _rotationConstant(rotationConstant) {}
virtual float apply(float value) const override { return value; }
virtual Pose apply(Pose newPose) const;
virtual bool parseParameters(const QJsonValue& parameters) override;
private:
float _translationConstant { 0.1f };
float _rotationConstant { 0.1f };
mutable Pose _oldPose { Pose() };
};
}
#endif

View file

@ -169,7 +169,6 @@ ViveControllerManager::InputDevice::InputDevice(vr::IVRSystem*& system) : contro
_configStringMap[Config::Feet] = QString("Feet");
_configStringMap[Config::FeetAndHips] = QString("FeetAndHips");
_configStringMap[Config::FeetHipsAndChest] = QString("FeetHipsAndChest");
_lowVelocityFilter = false;
}
void ViveControllerManager::InputDevice::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) {
@ -661,11 +660,6 @@ void ViveControllerManager::InputDevice::createPreferences() {
preferences->addPreference(preference);
}
{
auto getter = [this]()->float { return _translationFilterConstant; };
auto setter = [this](const float& value) { _translationFilterConstant; };
}
}