From a7547ef11e5ab1e70f56511215ddc7b13a6a1e97 Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Sun, 25 Oct 2015 16:44:43 -0700 Subject: [PATCH] Adding hysteresis filter, moving filters to individual files --- .../src/controllers/impl/Filter.cpp | 226 ++++++++++++------ .../controllers/src/controllers/impl/Filter.h | 198 +-------------- .../controllers/impl/RouteBuilderProxy.cpp | 52 ++-- .../src/controllers/impl/RouteBuilderProxy.h | 4 +- .../controllers/impl/filters/ClampFilter.cpp | 38 +++ .../controllers/impl/filters/ClampFilter.h | 32 +++ .../impl/filters/ConstrainToIntegerFilter.cpp | 9 + .../impl/filters/ConstrainToIntegerFilter.h | 30 +++ .../ConstrainToPositiveIntegerFilter.cpp | 9 + .../ConstrainToPositiveIntegerFilter.h | 30 +++ .../impl/filters/DeadZoneFilter.cpp | 26 ++ .../controllers/impl/filters/DeadZoneFilter.h | 31 +++ .../impl/filters/HysteresisFilter.cpp | 57 +++++ .../impl/filters/HysteresisFilter.h | 31 +++ .../controllers/impl/filters/InvertFilter.cpp | 9 + .../controllers/impl/filters/InvertFilter.h | 29 +++ .../controllers/impl/filters/PulseFilter.cpp | 37 +++ .../controllers/impl/filters/PulseFilter.h | 36 +++ .../controllers/impl/filters/ScaleFilter.cpp | 19 ++ .../controllers/impl/filters/ScaleFilter.h | 34 +++ 20 files changed, 638 insertions(+), 299 deletions(-) create mode 100644 libraries/controllers/src/controllers/impl/filters/ClampFilter.cpp create mode 100644 libraries/controllers/src/controllers/impl/filters/ClampFilter.h create mode 100644 libraries/controllers/src/controllers/impl/filters/ConstrainToIntegerFilter.cpp create mode 100644 libraries/controllers/src/controllers/impl/filters/ConstrainToIntegerFilter.h create mode 100644 libraries/controllers/src/controllers/impl/filters/ConstrainToPositiveIntegerFilter.cpp create mode 100644 libraries/controllers/src/controllers/impl/filters/ConstrainToPositiveIntegerFilter.h create mode 100644 libraries/controllers/src/controllers/impl/filters/DeadZoneFilter.cpp create mode 100644 libraries/controllers/src/controllers/impl/filters/DeadZoneFilter.h create mode 100644 libraries/controllers/src/controllers/impl/filters/HysteresisFilter.cpp create mode 100644 libraries/controllers/src/controllers/impl/filters/HysteresisFilter.h create mode 100644 libraries/controllers/src/controllers/impl/filters/InvertFilter.cpp create mode 100644 libraries/controllers/src/controllers/impl/filters/InvertFilter.h create mode 100644 libraries/controllers/src/controllers/impl/filters/PulseFilter.cpp create mode 100644 libraries/controllers/src/controllers/impl/filters/PulseFilter.h create mode 100644 libraries/controllers/src/controllers/impl/filters/ScaleFilter.cpp create mode 100644 libraries/controllers/src/controllers/impl/filters/ScaleFilter.h diff --git a/libraries/controllers/src/controllers/impl/Filter.cpp b/libraries/controllers/src/controllers/impl/Filter.cpp index bc31e9ea44..09188318eb 100644 --- a/libraries/controllers/src/controllers/impl/Filter.cpp +++ b/libraries/controllers/src/controllers/impl/Filter.cpp @@ -14,101 +14,183 @@ #include #include -#include "SharedUtil.h" +#include + +#include "filters/ClampFilter.h" +#include "filters/ConstrainToIntegerFilter.h" +#include "filters/ConstrainToPositiveIntegerFilter.h" +#include "filters/DeadZoneFilter.h" +#include "filters/HysteresisFilter.h" +#include "filters/InvertFilter.h" +#include "filters/PulseFilter.h" +#include "filters/ScaleFilter.h" using namespace controller; Filter::Factory Filter::_factory; -REGISTER_FILTER_CLASS_INSTANCE(InvertFilter, "invert") +REGISTER_FILTER_CLASS_INSTANCE(ClampFilter, "clamp") REGISTER_FILTER_CLASS_INSTANCE(ConstrainToIntegerFilter, "constrainToInteger") REGISTER_FILTER_CLASS_INSTANCE(ConstrainToPositiveIntegerFilter, "constrainToPositiveInteger") -REGISTER_FILTER_CLASS_INSTANCE(ScaleFilter, "scale") -REGISTER_FILTER_CLASS_INSTANCE(ClampFilter, "clamp") REGISTER_FILTER_CLASS_INSTANCE(DeadZoneFilter, "deadZone") +REGISTER_FILTER_CLASS_INSTANCE(HysteresisFilter, "hysteresis") +REGISTER_FILTER_CLASS_INSTANCE(InvertFilter, "invert") +REGISTER_FILTER_CLASS_INSTANCE(ScaleFilter, "scale") REGISTER_FILTER_CLASS_INSTANCE(PulseFilter, "pulse") - const QString JSON_FILTER_TYPE = QStringLiteral("type"); const QString JSON_FILTER_PARAMS = QStringLiteral("params"); -Filter::Pointer Filter::parse(const QJsonObject& json) { - // The filter is an object, now let s check for type and potential arguments +Filter::Pointer Filter::parse(const QJsonValue& json) { Filter::Pointer filter; - auto filterType = json[JSON_FILTER_TYPE]; - if (filterType.isString()) { + if (json.isString()) { + filter = Filter::getFactory().create(json.toString()); + } else if (json.isObject()) { + QJsonObject jsonObj = json.toObject(); + // The filter is an object, now let s check for type and potential arguments + auto filterType = jsonObj[JSON_FILTER_TYPE]; filter = Filter::getFactory().create(filterType.toString()); if (filter) { - // Filter is defined, need to read the parameters and validate - auto parameters = json[JSON_FILTER_PARAMS]; - if (parameters.isArray()) { - if (filter->parseParameters(parameters.toArray())) { - } + QJsonValue params = jsonObj; + if (jsonObj.contains(JSON_FILTER_PARAMS)) { + params = jsonObj[JSON_FILTER_PARAMS]; + } + if (!filter->parseParameters(params)) { + qWarning() << "Unable to parse filter parameters " << params; + return Filter::Pointer(); } - - return filter; } } - return Filter::Pointer(); + return filter; } - -bool ScaleFilter::parseParameters(const QJsonArray& parameters) { - if (parameters.size() > 1) { - _scale = parameters[0].toDouble(); - } - return true; -} - - -bool ClampFilter::parseParameters(const QJsonArray& parameters) { - if (parameters.size() > 1) { - _min = parameters[0].toDouble(); - } - if (parameters.size() > 2) { - _max = parameters[1].toDouble(); - } - return true; -} - - -float DeadZoneFilter::apply(float value) const { - float scale = 1.0f / (1.0f - _min); - if (std::abs(value) < _min) { - return 0.0f; - } - return (value - _min) * scale; -} - -bool DeadZoneFilter::parseParameters(const QJsonArray& parameters) { - if (parameters.size() > 1) { - _min = parameters[0].toDouble(); - } - return true; -} - - -float PulseFilter::apply(float value) const { - float result = 0.0f; - - if (0.0f != value) { - float now = secTimestampNow(); - float delta = now - _lastEmitTime; - if (delta >= _interval) { - _lastEmitTime = now; - result = value; +bool Filter::parseSingleFloatParameter(const QJsonValue& parameters, const QString& name, float& output) { + if (parameters.isDouble()) { + output = parameters.toDouble(); + return true; + } else if (parameters.isArray()) { + auto arrayParameters = parameters.toArray(); + if (arrayParameters.size() > 1) { + output = arrayParameters[0].toDouble(); + return true; } - } - - return result; -} - -bool PulseFilter::parseParameters(const QJsonArray& parameters) { - if (parameters.size() > 1) { - _interval = parameters[0].toDouble(); - } - 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(); + return true; + } + } + return false; } + +#if 0 + +namespace controller { + + class LambdaFilter : public Filter { + public: + // LambdaFilter() {}12 + LambdaFilter(Lambda f) : _function(f) {}; + + virtual float apply(float value) const { + return _function(value); + } + + virtual bool parseParameters(const QJsonArray& parameters) { return true; } + + // REGISTER_FILTER_CLASS(LambdaFilter); + private: + Lambda _function; + }; + + class ScriptFilter : public Filter { + public: + + }; + + + + //class EasingFilter : public Filter { + //public: + // virtual float apply(float value) const override; + + //private: + // QEasingCurve _curve; + //}; + + //// GLSL style filters + //class StepFilter : public Filter { + //public: + // StepFilter(float edge) : _edge(edge) {}; + // virtual float apply(float value) const override; + + //private: + // const float _edge; + //}; + + //class PowFilter : public Filter { + //public: + // PowFilter(float exponent) : _exponent(exponent) {}; + // virtual float apply(float value) const override; + + //private: + // const float _exponent; + //}; + + //class AbsFilter : public Filter { + //public: + // virtual float apply(float value) const override; + //}; + + //class SignFilter : public Filter { + //public: + // virtual float apply(float value) const override; + //}; + + //class FloorFilter : public Filter { + //public: + // virtual float apply(float value) const override { + // return floor(newValue); + // } + //}; + + //class CeilFilter : public Filter { + //public: + // virtual float apply(float value) const override { + // return ceil(newValue); + // } + //}; + + //class FractFilter : public Filter { + //public: + // virtual float apply(float value) const override { + // return fract(newValue); + // } + //}; + + //class MinFilter : public Filter { + //public: + // MinFilter(float mine) : _min(min) {}; + + // virtual float apply(float value) const override { + // return glm::min(_min, newValue); + // } + + //private: + // const float _min; + //}; + + //class MaxFilter : public Filter { + //public: + // MaxFilter(float max) : _max(max) {}; + // virtual float apply(float newValue, float oldValue) override; + //private: + // const float _max; + //}; +} +#endif \ No newline at end of file diff --git a/libraries/controllers/src/controllers/impl/Filter.h b/libraries/controllers/src/controllers/impl/Filter.h index 1fa9833044..77585c8ebb 100644 --- a/libraries/controllers/src/controllers/impl/Filter.h +++ b/libraries/controllers/src/controllers/impl/Filter.h @@ -21,8 +21,7 @@ #include -class QJsonObject; -class QJsonArray; +class QJsonValue; namespace controller { @@ -36,11 +35,13 @@ namespace controller { virtual float apply(float value) const = 0; // Factory features - virtual bool parseParameters(const QJsonArray& parameters) { return true; } + virtual bool parseParameters(const QJsonValue& parameters) { return true; } - static Pointer parse(const QJsonObject& json); + static Pointer parse(const QJsonValue& json); static void registerBuilder(const QString& name, Factory::Builder builder); static Factory& getFactory() { return _factory; } + + static bool parseSingleFloatParameter(const QJsonValue& parameters, const QString& name, float& output); protected: static Factory _factory; }; @@ -54,194 +55,5 @@ namespace controller { #define REGISTER_FILTER_CLASS_INSTANCE(classEntry, className) \ classEntry::Registrar classEntry::_registrar(className, Filter::getFactory()); -namespace controller { - - class LambdaFilter : public Filter { - public: - // LambdaFilter() {} - LambdaFilter(Lambda f) : _function(f) {}; - - virtual float apply(float value) const { - return _function(value); - } - - virtual bool parseParameters(const QJsonArray& parameters) { return true; } - -// REGISTER_FILTER_CLASS(LambdaFilter); - private: - Lambda _function; - }; - - class ScriptFilter : public Filter { - public: - - }; - - class ScaleFilter : public Filter { - REGISTER_FILTER_CLASS(ScaleFilter); - public: - ScaleFilter() {} - ScaleFilter(float scale): _scale(scale) {} - - virtual float apply(float value) const override { - return value * _scale; - } - virtual bool parseParameters(const QJsonArray& parameters); - - private: - float _scale = 1.0f; - }; - - class InvertFilter : public ScaleFilter { - REGISTER_FILTER_CLASS(InvertFilter); - public: - InvertFilter() : ScaleFilter(-1.0f) {} - - virtual bool parseParameters(const QJsonArray& parameters) { return true; } - - private: - }; - - class ClampFilter : public Filter { - REGISTER_FILTER_CLASS(ClampFilter); - public: - ClampFilter(float min = 0.0, float max = 1.0) : _min(min), _max(max) {}; - - virtual float apply(float value) const override { - return glm::clamp(value, _min, _max); - } - virtual bool parseParameters(const QJsonArray& parameters) override; - protected: - float _min = 0.0f; - float _max = 1.0f; - }; - - class DeadZoneFilter : public Filter { - REGISTER_FILTER_CLASS(DeadZoneFilter); - public: - DeadZoneFilter(float min = 0.0) : _min(min) {}; - - virtual float apply(float value) const override; - virtual bool parseParameters(const QJsonArray& parameters) override; - protected: - float _min = 0.0f; - }; - - class PulseFilter : public Filter { - REGISTER_FILTER_CLASS(PulseFilter); - public: - PulseFilter() {} - PulseFilter(float interval) : _interval(interval) {} - - - virtual float apply(float value) const override; - - virtual bool parseParameters(const QJsonArray& parameters); - - private: - mutable float _lastEmitTime{ -::std::numeric_limits::max() }; - float _interval = 1.0f; - }; - - class ConstrainToIntegerFilter : public Filter { - REGISTER_FILTER_CLASS(ConstrainToIntegerFilter); - public: - ConstrainToIntegerFilter() {}; - - virtual float apply(float value) const override { - return glm::sign(value); - } - protected: - }; - - class ConstrainToPositiveIntegerFilter : public Filter { - REGISTER_FILTER_CLASS(ConstrainToPositiveIntegerFilter); - public: - ConstrainToPositiveIntegerFilter() {}; - - virtual float apply(float value) const override { - return (value <= 0.0f) ? 0.0f : 1.0f; - } - protected: - }; - - //class EasingFilter : public Filter { - //public: - // virtual float apply(float value) const override; - - //private: - // QEasingCurve _curve; - //}; - - //// GLSL style filters - //class StepFilter : public Filter { - //public: - // StepFilter(float edge) : _edge(edge) {}; - // virtual float apply(float value) const override; - - //private: - // const float _edge; - //}; - - //class PowFilter : public Filter { - //public: - // PowFilter(float exponent) : _exponent(exponent) {}; - // virtual float apply(float value) const override; - - //private: - // const float _exponent; - //}; - - //class AbsFilter : public Filter { - //public: - // virtual float apply(float value) const override; - //}; - - //class SignFilter : public Filter { - //public: - // virtual float apply(float value) const override; - //}; - - //class FloorFilter : public Filter { - //public: - // virtual float apply(float value) const override { - // return floor(newValue); - // } - //}; - - //class CeilFilter : public Filter { - //public: - // virtual float apply(float value) const override { - // return ceil(newValue); - // } - //}; - - //class FractFilter : public Filter { - //public: - // virtual float apply(float value) const override { - // return fract(newValue); - // } - //}; - - //class MinFilter : public Filter { - //public: - // MinFilter(float mine) : _min(min) {}; - - // virtual float apply(float value) const override { - // return glm::min(_min, newValue); - // } - - //private: - // const float _min; - //}; - - //class MaxFilter : public Filter { - //public: - // MaxFilter(float max) : _max(max) {}; - // virtual float apply(float newValue, float oldValue) override; - //private: - // const float _max; - //}; -} #endif diff --git a/libraries/controllers/src/controllers/impl/RouteBuilderProxy.cpp b/libraries/controllers/src/controllers/impl/RouteBuilderProxy.cpp index d56d699c28..49e615439d 100644 --- a/libraries/controllers/src/controllers/impl/RouteBuilderProxy.cpp +++ b/libraries/controllers/src/controllers/impl/RouteBuilderProxy.cpp @@ -18,6 +18,15 @@ #include "../ScriptingInterface.h" #include "../Logging.h" +#include "filters/ClampFilter.h" +#include "filters/ConstrainToIntegerFilter.h" +#include "filters/ConstrainToPositiveIntegerFilter.h" +#include "filters/DeadZoneFilter.h" +#include "filters/HysteresisFilter.h" +#include "filters/InvertFilter.h" +#include "filters/PulseFilter.h" +#include "filters/ScaleFilter.h" + using namespace controller; void RouteBuilderProxy::toQml(const QJSValue& destination) { @@ -43,18 +52,6 @@ QObject* RouteBuilderProxy::debug(bool enable) { return this; } -QObject* RouteBuilderProxy::filterQml(const QJSValue& expression) { - if (expression.isCallable()) { - addFilter([=](float value) { - QJSValue originalExpression = expression; - QJSValueList params({ QJSValue(value) }); - auto result = originalExpression.call(params); - return (float)(result.toNumber()); - }); - } - return this; -} - QObject* RouteBuilderProxy::when(const QScriptValue& expression) { _route->conditional = _parent.conditionalFor(expression); return this; @@ -65,53 +62,46 @@ QObject* RouteBuilderProxy::whenQml(const QJSValue& expression) { return this; } - -QObject* RouteBuilderProxy::filter(const QScriptValue& expression) { - return this; -} - - QObject* RouteBuilderProxy::clamp(float min, float max) { - addFilter(Filter::Pointer(new ClampFilter(min, max))); + addFilter(std::make_shared(min, max)); return this; } QObject* RouteBuilderProxy::scale(float multiplier) { - addFilter(Filter::Pointer(new ScaleFilter(multiplier))); + addFilter(std::make_shared(multiplier)); return this; } QObject* RouteBuilderProxy::invert() { - addFilter(Filter::Pointer(new InvertFilter())); + addFilter(std::make_shared()); + return this; +} + +QObject* RouteBuilderProxy::hysteresis(float min, float max) { + addFilter(std::make_shared(min, max)); return this; } QObject* RouteBuilderProxy::deadZone(float min) { - addFilter(Filter::Pointer(new DeadZoneFilter(min))); + addFilter(std::make_shared(min)); return this; } QObject* RouteBuilderProxy::constrainToInteger() { - addFilter(Filter::Pointer(new ConstrainToIntegerFilter())); + addFilter(std::make_shared()); return this; } QObject* RouteBuilderProxy::constrainToPositiveInteger() { - addFilter(Filter::Pointer(new ConstrainToPositiveIntegerFilter())); + addFilter(std::make_shared()); return this; } - QObject* RouteBuilderProxy::pulse(float interval) { - addFilter(Filter::Pointer(new PulseFilter(interval))); + addFilter(std::make_shared(interval)); return this; } -void RouteBuilderProxy::addFilter(Filter::Lambda lambda) { - Filter::Pointer filterPointer = std::make_shared < LambdaFilter > (lambda); - addFilter(filterPointer); -} - void RouteBuilderProxy::addFilter(Filter::Pointer filter) { _route->filters.push_back(filter); } diff --git a/libraries/controllers/src/controllers/impl/RouteBuilderProxy.h b/libraries/controllers/src/controllers/impl/RouteBuilderProxy.h index 4bcfba5acd..d55aa80f6b 100644 --- a/libraries/controllers/src/controllers/impl/RouteBuilderProxy.h +++ b/libraries/controllers/src/controllers/impl/RouteBuilderProxy.h @@ -34,14 +34,13 @@ class RouteBuilderProxy : public QObject { : _parent(parent), _mapping(mapping), _route(route) { } Q_INVOKABLE void toQml(const QJSValue& destination); - Q_INVOKABLE QObject* filterQml(const QJSValue& expression); Q_INVOKABLE QObject* whenQml(const QJSValue& expression); Q_INVOKABLE void to(const QScriptValue& destination); Q_INVOKABLE QObject* debug(bool enable = true); Q_INVOKABLE QObject* when(const QScriptValue& expression); - Q_INVOKABLE QObject* filter(const QScriptValue& expression); Q_INVOKABLE QObject* clamp(float min, float max); + Q_INVOKABLE QObject* hysteresis(float min, float max); Q_INVOKABLE QObject* pulse(float interval); Q_INVOKABLE QObject* scale(float multiplier); Q_INVOKABLE QObject* invert(); @@ -52,7 +51,6 @@ class RouteBuilderProxy : public QObject { private: void to(const Endpoint::Pointer& destination); void conditional(const Conditional::Pointer& conditional); - void addFilter(Filter::Lambda lambda); void addFilter(Filter::Pointer filter); UserInputMapper& _parent; Mapping::Pointer _mapping; diff --git a/libraries/controllers/src/controllers/impl/filters/ClampFilter.cpp b/libraries/controllers/src/controllers/impl/filters/ClampFilter.cpp new file mode 100644 index 0000000000..ec22981ef3 --- /dev/null +++ b/libraries/controllers/src/controllers/impl/filters/ClampFilter.cpp @@ -0,0 +1,38 @@ +// +// 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 "ClampFilter.h" + +#include +#include + +using namespace controller; + +bool ClampFilter::parseParameters(const QJsonValue& parameters) { + if (parameters.isArray()) { + auto arrayParameters = parameters.toArray(); + if (arrayParameters.size() > 1) { + _min = arrayParameters[0].toDouble(); + } + if (arrayParameters.size() > 2) { + _max = arrayParameters[1].toDouble(); + } + } else if (parameters.isObject()) { + static const QString JSON_MAX = QStringLiteral("max"); + static const QString JSON_MIN = QStringLiteral("min"); + + auto objectParameters = parameters.toObject(); + if (objectParameters.contains(JSON_MIN)) { + _min = objectParameters[JSON_MIN].toDouble(); + } + if (objectParameters.contains(JSON_MAX)) { + _max = objectParameters[JSON_MAX].toDouble(); + } + } + return true; +} diff --git a/libraries/controllers/src/controllers/impl/filters/ClampFilter.h b/libraries/controllers/src/controllers/impl/filters/ClampFilter.h new file mode 100644 index 0000000000..fd82821b3e --- /dev/null +++ b/libraries/controllers/src/controllers/impl/filters/ClampFilter.h @@ -0,0 +1,32 @@ +// +// 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 +// + +#pragma once +#ifndef hifi_Controllers_Filters_Clamp_h +#define hifi_Controllers_Filters_Clamp_h + +#include "../Filter.h" + +namespace controller { + +class ClampFilter : public Filter { + REGISTER_FILTER_CLASS(ClampFilter); +public: + ClampFilter(float min = 0.0, float max = 1.0) : _min(min), _max(max) {}; + virtual float apply(float value) const override { + return glm::clamp(value, _min, _max); + } + virtual bool parseParameters(const QJsonValue& parameters) override; +protected: + float _min = 0.0f; + float _max = 1.0f; +}; + +} + +#endif diff --git a/libraries/controllers/src/controllers/impl/filters/ConstrainToIntegerFilter.cpp b/libraries/controllers/src/controllers/impl/filters/ConstrainToIntegerFilter.cpp new file mode 100644 index 0000000000..78ffb47693 --- /dev/null +++ b/libraries/controllers/src/controllers/impl/filters/ConstrainToIntegerFilter.cpp @@ -0,0 +1,9 @@ +// +// 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 "ConstrainToIntegerFilter.h" diff --git a/libraries/controllers/src/controllers/impl/filters/ConstrainToIntegerFilter.h b/libraries/controllers/src/controllers/impl/filters/ConstrainToIntegerFilter.h new file mode 100644 index 0000000000..580dc2a856 --- /dev/null +++ b/libraries/controllers/src/controllers/impl/filters/ConstrainToIntegerFilter.h @@ -0,0 +1,30 @@ +// +// 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 +// + +#pragma once +#ifndef hifi_Controllers_Filters_ConstrainToIntegerFilter_h +#define hifi_Controllers_Filters_ConstrainToIntegerFilter_h + +#include "../Filter.h" + +namespace controller { + +class ConstrainToIntegerFilter : public Filter { + REGISTER_FILTER_CLASS(ConstrainToIntegerFilter); +public: + ConstrainToIntegerFilter() {}; + + virtual float apply(float value) const override { + return glm::sign(value); + } +protected: +}; + +} + +#endif diff --git a/libraries/controllers/src/controllers/impl/filters/ConstrainToPositiveIntegerFilter.cpp b/libraries/controllers/src/controllers/impl/filters/ConstrainToPositiveIntegerFilter.cpp new file mode 100644 index 0000000000..d78942b18f --- /dev/null +++ b/libraries/controllers/src/controllers/impl/filters/ConstrainToPositiveIntegerFilter.cpp @@ -0,0 +1,9 @@ +// +// 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 "ConstrainToPositiveIntegerFilter.h" diff --git a/libraries/controllers/src/controllers/impl/filters/ConstrainToPositiveIntegerFilter.h b/libraries/controllers/src/controllers/impl/filters/ConstrainToPositiveIntegerFilter.h new file mode 100644 index 0000000000..27395cde24 --- /dev/null +++ b/libraries/controllers/src/controllers/impl/filters/ConstrainToPositiveIntegerFilter.h @@ -0,0 +1,30 @@ +// +// 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 +// + +#pragma once +#ifndef hifi_Controllers_Filters_ConstrainToPositiveInteger_h +#define hifi_Controllers_Filters_ConstrainToPositiveInteger_h + +#include "../Filter.h" + +namespace controller { + +class ConstrainToPositiveIntegerFilter : public Filter { + REGISTER_FILTER_CLASS(ConstrainToPositiveIntegerFilter); +public: + ConstrainToPositiveIntegerFilter() {}; + + virtual float apply(float value) const override { + return (value <= 0.0f) ? 0.0f : 1.0f; + } +protected: +}; + +} + +#endif diff --git a/libraries/controllers/src/controllers/impl/filters/DeadZoneFilter.cpp b/libraries/controllers/src/controllers/impl/filters/DeadZoneFilter.cpp new file mode 100644 index 0000000000..809308eeab --- /dev/null +++ b/libraries/controllers/src/controllers/impl/filters/DeadZoneFilter.cpp @@ -0,0 +1,26 @@ +// +// 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 "DeadZoneFilter.h" + +#include +#include + +using namespace controller; +float DeadZoneFilter::apply(float value) const { + float scale = 1.0f / (1.0f - _min); + if (std::abs(value) < _min) { + return 0.0f; + } + return (value - _min) * scale; +} + +bool DeadZoneFilter::parseParameters(const QJsonValue& parameters) { + static const QString JSON_MIN = QStringLiteral("min"); + return parseSingleFloatParameter(parameters, JSON_MIN, _min); +} diff --git a/libraries/controllers/src/controllers/impl/filters/DeadZoneFilter.h b/libraries/controllers/src/controllers/impl/filters/DeadZoneFilter.h new file mode 100644 index 0000000000..70ac657415 --- /dev/null +++ b/libraries/controllers/src/controllers/impl/filters/DeadZoneFilter.h @@ -0,0 +1,31 @@ +// +// 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 +// + +#pragma once +#ifndef hifi_Controllers_Filters_DeadZoneFilter_h +#define hifi_Controllers_Filters_DeadZoneFilter_h + +#include "../Filter.h" + +namespace controller { + +class DeadZoneFilter : public Filter { + REGISTER_FILTER_CLASS(DeadZoneFilter); +public: + DeadZoneFilter(float min = 0.0) : _min(min) {}; + + virtual float apply(float value) const override; + virtual bool parseParameters(const QJsonValue& parameters) override; +protected: + float _min = 0.0f; +}; + + +} + +#endif diff --git a/libraries/controllers/src/controllers/impl/filters/HysteresisFilter.cpp b/libraries/controllers/src/controllers/impl/filters/HysteresisFilter.cpp new file mode 100644 index 0000000000..c1edfe35da --- /dev/null +++ b/libraries/controllers/src/controllers/impl/filters/HysteresisFilter.cpp @@ -0,0 +1,57 @@ +// +// 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 "HysteresisFilter.h" + +#include +#include + +using namespace controller; + +float HysteresisFilter::apply(float value) const { + if (_signaled) { + if (value <= _min) { + _signaled = false; + } + } else { + if (value >= _max) { + _signaled = true; + } + } + return _signaled ? 1.0f : 0.0f; +} + +bool HysteresisFilter::parseParameters(const QJsonValue& parameters) { + if (parameters.isArray()) { + auto arrayParameters = parameters.toArray(); + if (arrayParameters.size() > 1) { + _min = arrayParameters[0].toDouble(); + } + if (arrayParameters.size() > 2) { + _max = arrayParameters[1].toDouble(); + } + } else if (parameters.isObject()) { + static const QString JSON_MAX = QStringLiteral("max"); + static const QString JSON_MIN = QStringLiteral("min"); + + auto objectParameters = parameters.toObject(); + if (objectParameters.contains(JSON_MIN)) { + _min = objectParameters[JSON_MIN].toDouble(); + } + if (objectParameters.contains(JSON_MAX)) { + _max = objectParameters[JSON_MAX].toDouble(); + } + } else { + return false; + } + + if (_min > _max) { + std::swap(_min, _max); + } + return true; +} diff --git a/libraries/controllers/src/controllers/impl/filters/HysteresisFilter.h b/libraries/controllers/src/controllers/impl/filters/HysteresisFilter.h new file mode 100644 index 0000000000..cf33f1bbff --- /dev/null +++ b/libraries/controllers/src/controllers/impl/filters/HysteresisFilter.h @@ -0,0 +1,31 @@ +// +// 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 +// + +#pragma once +#ifndef hifi_Controllers_Filters_Hysteresis_h +#define hifi_Controllers_Filters_Hysteresis_h + +#include "../Filter.h" + +namespace controller { + +class HysteresisFilter : public Filter { + REGISTER_FILTER_CLASS(HysteresisFilter); +public: + HysteresisFilter(float min = 0.25, float max = 0.75) : _min(min), _max(max) {}; + virtual float apply(float value) const override; + virtual bool parseParameters(const QJsonValue& parameters) override; +protected: + float _min; + float _max; + mutable bool _signaled { false }; +}; + +} + +#endif diff --git a/libraries/controllers/src/controllers/impl/filters/InvertFilter.cpp b/libraries/controllers/src/controllers/impl/filters/InvertFilter.cpp new file mode 100644 index 0000000000..db582b84cc --- /dev/null +++ b/libraries/controllers/src/controllers/impl/filters/InvertFilter.cpp @@ -0,0 +1,9 @@ +// +// 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 "InvertFilter.h" diff --git a/libraries/controllers/src/controllers/impl/filters/InvertFilter.h b/libraries/controllers/src/controllers/impl/filters/InvertFilter.h new file mode 100644 index 0000000000..889cd0140c --- /dev/null +++ b/libraries/controllers/src/controllers/impl/filters/InvertFilter.h @@ -0,0 +1,29 @@ +// +// 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 +// + +#pragma once +#ifndef hifi_Controllers_Filters_InvertFilter_h +#define hifi_Controllers_Filters_InvertFilter_h + +#include "ScaleFilter.h" + +namespace controller { + +class InvertFilter : public ScaleFilter { + REGISTER_FILTER_CLASS(InvertFilter); +public: + InvertFilter() : ScaleFilter(-1.0f) {} + + virtual bool parseParameters(const QJsonArray& parameters) { return true; } + +private: +}; + +} + +#endif diff --git a/libraries/controllers/src/controllers/impl/filters/PulseFilter.cpp b/libraries/controllers/src/controllers/impl/filters/PulseFilter.cpp new file mode 100644 index 0000000000..f4e1f04791 --- /dev/null +++ b/libraries/controllers/src/controllers/impl/filters/PulseFilter.cpp @@ -0,0 +1,37 @@ +// +// 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 "PulseFilter.h" + +#include +#include + +using namespace controller; + + + +float PulseFilter::apply(float value) const { + float result = 0.0f; + + if (0.0f != value) { + float now = secTimestampNow(); + float delta = now - _lastEmitTime; + if (delta >= _interval) { + _lastEmitTime = now; + result = value; + } + } + + return result; +} + +bool PulseFilter::parseParameters(const QJsonValue& parameters) { + static const QString JSON_MIN = QStringLiteral("interval"); + return parseSingleFloatParameter(parameters, JSON_MIN, _interval); +} + diff --git a/libraries/controllers/src/controllers/impl/filters/PulseFilter.h b/libraries/controllers/src/controllers/impl/filters/PulseFilter.h new file mode 100644 index 0000000000..2512b479cf --- /dev/null +++ b/libraries/controllers/src/controllers/impl/filters/PulseFilter.h @@ -0,0 +1,36 @@ +// +// 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 +// + +#pragma once +#ifndef hifi_Controllers_Filters_Pulse_h +#define hifi_Controllers_Filters_Pulse_h + +#include "../Filter.h" + +namespace controller { + + +class PulseFilter : public Filter { + REGISTER_FILTER_CLASS(PulseFilter); +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::max() }; + float _interval = 1.0f; +}; + +} + +#endif diff --git a/libraries/controllers/src/controllers/impl/filters/ScaleFilter.cpp b/libraries/controllers/src/controllers/impl/filters/ScaleFilter.cpp new file mode 100644 index 0000000000..4a310e3a04 --- /dev/null +++ b/libraries/controllers/src/controllers/impl/filters/ScaleFilter.cpp @@ -0,0 +1,19 @@ +// +// 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 "ScaleFilter.h" + +#include +#include + +using namespace controller; + +bool ScaleFilter::parseParameters(const QJsonValue& parameters) { + static const QString JSON_SCALE = QStringLiteral("scale"); + return parseSingleFloatParameter(parameters, JSON_SCALE, _scale); +} diff --git a/libraries/controllers/src/controllers/impl/filters/ScaleFilter.h b/libraries/controllers/src/controllers/impl/filters/ScaleFilter.h new file mode 100644 index 0000000000..39c5edd4e5 --- /dev/null +++ b/libraries/controllers/src/controllers/impl/filters/ScaleFilter.h @@ -0,0 +1,34 @@ +// +// 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 +// + +#pragma once +#ifndef hifi_Controllers_Filters_Scale_h +#define hifi_Controllers_Filters_Scale_h + +#include "../Filter.h" + +namespace controller { + +class ScaleFilter : public Filter { + REGISTER_FILTER_CLASS(ScaleFilter); +public: + ScaleFilter() {} + ScaleFilter(float scale) : _scale(scale) {} + + virtual float apply(float value) const override { + return value * _scale; + } + virtual bool parseParameters(const QJsonValue& parameters); + +private: + float _scale = 1.0f; +}; + +} + +#endif