first cut at translate and scale pose filters

This commit is contained in:
ZappoMan 2017-04-11 12:17:28 -07:00
parent d5f5192954
commit bab7d1e596
9 changed files with 153 additions and 1 deletions

View file

@ -20,6 +20,8 @@
#include <PathUtils.h>
#include <NumericalConstants.h>
#include <StreamUtils.h>
#include "StandardController.h"
#include "StateController.h"
@ -561,7 +563,18 @@ bool UserInputMapper::applyRoute(const Route::Pointer& route, bool force) {
if (source->isPose()) {
Pose value = getPose(source, route->peek);
static const Pose IDENTITY_POSE { vec3(), quat() };
if (debugRoutes && route->debug) {
qCDebug(controllers) << "Value was t:" << value.translation << "r:" << value.rotation;
}
// Apply each of the filters.
for (const auto& filter : route->filters) {
value = filter->apply(value);
}
if (debugRoutes && route->debug) {
qCDebug(controllers) << "Filtered value was t:" << value.translation << "r:" << value.rotation;
if (!value.valid) {
qCDebug(controllers) << "Applying invalid pose";
} else if (value == IDENTITY_POSE) {

View file

@ -24,6 +24,7 @@
#include "filters/InvertFilter.h"
#include "filters/PulseFilter.h"
#include "filters/ScaleFilter.h"
#include "filters/TranslateFilter.h"
using namespace controller;
@ -37,6 +38,7 @@ REGISTER_FILTER_CLASS_INSTANCE(HysteresisFilter, "hysteresis")
REGISTER_FILTER_CLASS_INSTANCE(InvertFilter, "invert")
REGISTER_FILTER_CLASS_INSTANCE(ScaleFilter, "scale")
REGISTER_FILTER_CLASS_INSTANCE(PulseFilter, "pulse")
REGISTER_FILTER_CLASS_INSTANCE(TranslateFilter, "translate")
const QString JSON_FILTER_TYPE = QStringLiteral("type");
const QString JSON_FILTER_PARAMS = QStringLiteral("params");
@ -76,7 +78,6 @@ bool Filter::parseSingleFloatParameter(const QJsonValue& parameters, const QStri
return true;
}
} else if (parameters.isObject()) {
static const QString JSON_MIN = QStringLiteral("interval");
auto objectParameters = parameters.toObject();
if (objectParameters.contains(name)) {
output = objectParameters[name].toDouble();
@ -86,6 +87,30 @@ bool Filter::parseSingleFloatParameter(const QJsonValue& parameters, const QStri
return false;
}
// FIXME - we're not really using the name
bool Filter::parseVec3Parameter(const QJsonValue& parameters, const QString& name, glm::vec3& output) {
if (parameters.isDouble()) {
output = glm::vec3(parameters.toDouble());
return true;
} else if (parameters.isArray()) {
auto arrayParameters = parameters.toArray();
if (arrayParameters.size() == 3) {
output = glm::vec3(arrayParameters[0].toDouble(),
arrayParameters[1].toDouble(),
arrayParameters[2].toDouble());
return true;
}
} else if (parameters.isObject()) {
auto objectParameters = parameters.toObject();
if (objectParameters.contains("x") && objectParameters.contains("y") && objectParameters.contains("z")) {
output = glm::vec3(objectParameters["x"].toDouble(),
objectParameters["y"].toDouble(),
objectParameters["z"].toDouble());
return true;
}
}
return false;
}
#if 0

View file

@ -21,6 +21,8 @@
#include <QtCore/QEasingCurve>
#include "../Pose.h"
class QJsonValue;
namespace controller {
@ -34,6 +36,8 @@ namespace controller {
using Factory = hifi::SimpleFactory<Filter, QString>;
virtual float apply(float value) const = 0;
virtual Pose apply(Pose value) const { return value; } // most filters don't operate on poses
// Factory features
virtual bool parseParameters(const QJsonValue& parameters) { return true; }
@ -42,6 +46,7 @@ namespace controller {
static Factory& getFactory() { return _factory; }
static bool parseSingleFloatParameter(const QJsonValue& parameters, const QString& name, float& output);
static bool parseVec3Parameter(const QJsonValue& parameters, const QString& name, glm::vec3& output);
protected:
static Factory _factory;
};

View file

@ -26,6 +26,7 @@
#include "filters/InvertFilter.h"
#include "filters/PulseFilter.h"
#include "filters/ScaleFilter.h"
#include "filters/TranslateFilter.h"
#include "conditionals/AndConditional.h"
using namespace controller;
@ -103,6 +104,12 @@ QObject* RouteBuilderProxy::deadZone(float min) {
return this;
}
QObject* RouteBuilderProxy::translate(glm::vec3 translate) {
qDebug() << __FUNCTION__ << "translate:" << translate;
addFilter(std::make_shared<TranslateFilter>(translate));
return this;
}
QObject* RouteBuilderProxy::constrainToInteger() {
addFilter(std::make_shared<ConstrainToIntegerFilter>());
return this;

View file

@ -48,6 +48,7 @@ class RouteBuilderProxy : public QObject {
Q_INVOKABLE QObject* deadZone(float min);
Q_INVOKABLE QObject* constrainToInteger();
Q_INVOKABLE QObject* constrainToPositiveInteger();
Q_INVOKABLE QObject* translate(glm::vec3 translate);
private:
void to(const Endpoint::Pointer& destination);

View file

@ -10,6 +10,8 @@
#ifndef hifi_Controllers_Filters_Scale_h
#define hifi_Controllers_Filters_Scale_h
#include <glm/gtc/matrix_transform.hpp>
#include "../Filter.h"
namespace controller {
@ -23,6 +25,11 @@ public:
virtual float apply(float value) const override {
return value * _scale;
}
virtual Pose apply(Pose value) const override {
return value.transform(glm::scale(glm::mat4(), glm::vec3(_scale)));
}
virtual bool parseParameters(const QJsonValue& parameters) override;
private:

View file

@ -0,0 +1,23 @@
//
// Created by Bradley Austin Davis 2015/10/25
// 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
//
#include "TranslateFilter.h"
#include <QtCore/QJsonObject>
#include <QtCore/QJsonArray>
#include <StreamUtils.h>
using namespace controller;
bool TranslateFilter::parseParameters(const QJsonValue& parameters) {
static const QString JSON_TRANSLATE = QStringLiteral("translate");
bool result = parseVec3Parameter(parameters, JSON_TRANSLATE, _translate);
qDebug() << __FUNCTION__ << "_translate:" << _translate;
return result;
}

View file

@ -0,0 +1,47 @@
//
// Created by Brad Hefta-Gaub 2017/04/11
// 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
//
#pragma once
#ifndef hifi_Controllers_Filters_Translate_h
#define hifi_Controllers_Filters_Translate_h
#include <glm/gtx/transform.hpp>
#include <StreamUtils.h>
#include "../Filter.h"
namespace controller {
class TranslateFilter : public Filter {
REGISTER_FILTER_CLASS(TranslateFilter);
public:
TranslateFilter() {
qDebug() << __FUNCTION__;
}
TranslateFilter(glm::vec3 translate) : _translate(translate) {
qDebug() << __FUNCTION__ << "translate:" << translate;
}
virtual float apply(float value) const override {
return value;
}
virtual Pose apply(Pose value) const override {
return value.transform(glm::translate(_translate));
}
virtual bool parseParameters(const QJsonValue& parameters) override;
private:
glm::vec3 _translate { 0.0f };
};
}
#endif

View file

@ -0,0 +1,24 @@
//
// puppetFeet3.js
// examples/controllers
//
// Created by Brad Hefta-Gaub on 2017/04/11
// 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
//
var MAPPING_NAME = "com.highfidelity.examples.puppetFeet3";
var mapping = Controller.newMapping(MAPPING_NAME);
var puppetOffset = { x: 0, y: -1, z: 0 };
mapping.from(Controller.Standard.LeftHand).peek().translate(puppetOffset).to(Controller.Standard.LeftFoot);
Controller.enableMapping(MAPPING_NAME);
Script.scriptEnding.connect(function(){
mapping.disable();
});