mirror of
https://github.com/Armored-Dragon/overte.git
synced 2025-03-11 16:13:16 +01:00
Merge pull request #6206 from samcake/controllers
Controllers : Add a new kind onf controller to expose ReadOnly state from the application
This commit is contained in:
commit
570b4a32da
10 changed files with 252 additions and 112 deletions
|
@ -11,17 +11,17 @@
|
|||
|
||||
|
||||
function makeSphere(color) {
|
||||
var SPHERE_SIZE = 0.05;
|
||||
var sphere = Overlays.addOverlay("sphere", {
|
||||
position: { x: 0, y: 0, z: 0 },
|
||||
size: SPHERE_SIZE,
|
||||
color: color,
|
||||
alpha: 1.0,
|
||||
solid: true,
|
||||
visible: true,
|
||||
});
|
||||
var SPHERE_SIZE = 0.05;
|
||||
var sphere = Overlays.addOverlay("sphere", {
|
||||
position: { x: 0, y: 0, z: 0 },
|
||||
size: SPHERE_SIZE,
|
||||
color: color,
|
||||
alpha: 1.0,
|
||||
solid: true,
|
||||
visible: true,
|
||||
});
|
||||
|
||||
return sphere;
|
||||
return sphere;
|
||||
}
|
||||
|
||||
|
||||
|
@ -32,68 +32,69 @@ var RIGHT_HAND = 1;
|
|||
|
||||
var COLORS = [ { red: 255, green: 0, blue: 0 }, { red: 0, green: 0, blue: 255 } ];
|
||||
|
||||
|
||||
function index(handNum, indexNum) {
|
||||
return handNum * NUM_HANDS + indexNum;
|
||||
return handNum * NUM_HANDS + indexNum;
|
||||
}
|
||||
|
||||
var app = {};
|
||||
|
||||
|
||||
function setup() {
|
||||
app.spheres = new Array();
|
||||
app.spheres = new Array();
|
||||
|
||||
for (var h = 0; h < NUM_HANDS; h++) {
|
||||
for (var s = 0; s < NUM_SPHERES_PER_HAND; s++) {
|
||||
var i = index(h, s);
|
||||
app.spheres[i] = makeSphere(COLORS[h]);
|
||||
print("Added Sphere num " + i + " = " + JSON.stringify(app.spheres[i]));
|
||||
}
|
||||
}
|
||||
for (var h = 0; h < NUM_HANDS; h++) {
|
||||
for (var s = 0; s < NUM_SPHERES_PER_HAND; s++) {
|
||||
var i = index(h, s);
|
||||
app.spheres[i] = makeSphere(COLORS[h]);
|
||||
print("Added Sphere num " + i + " = " + JSON.stringify(app.spheres[i]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function updateHand(handNum, deltaTime) {
|
||||
var pose;
|
||||
var handName = "right";
|
||||
if (handNum == LEFT_HAND) {
|
||||
pose = MyAvatar.getLeftHandPose();
|
||||
handName = "left";
|
||||
} else {
|
||||
pose = MyAvatar.getRightHandPose();
|
||||
handName = "right";
|
||||
}
|
||||
var pose;
|
||||
var handName = "right";
|
||||
if (handNum == LEFT_HAND) {
|
||||
pose = MyAvatar.getLeftHandPose();
|
||||
handName = "left";
|
||||
} else {
|
||||
pose = MyAvatar.getRightHandPose();
|
||||
handName = "right";
|
||||
}
|
||||
|
||||
if (pose.valid) {
|
||||
//print(handName + " hand moving" + JSON.stringify(pose));
|
||||
Overlays.editOverlay(app.spheres[index(handNum, 0)], {
|
||||
position: pose.translation,
|
||||
visible: true,
|
||||
});
|
||||
var vpos = Vec3.sum(Vec3.multiply(10 * deltaTime, pose.velocity), pose.translation);
|
||||
Overlays.editOverlay(app.spheres[index(handNum, 1)], {
|
||||
position: vpos,
|
||||
visible: true,
|
||||
});
|
||||
} else {
|
||||
Overlays.editOverlay(app.spheres[index(handNum, 0)], {
|
||||
visible: false
|
||||
});
|
||||
if (pose.valid) {
|
||||
//print(handName + " hand moving" + JSON.stringify(pose));
|
||||
Overlays.editOverlay(app.spheres[index(handNum, 0)], {
|
||||
position: pose.translation,
|
||||
visible: true,
|
||||
});
|
||||
var vpos = Vec3.sum(Vec3.multiply(10 * deltaTime, pose.velocity), pose.translation);
|
||||
Overlays.editOverlay(app.spheres[index(handNum, 1)], {
|
||||
position: vpos,
|
||||
visible: true,
|
||||
});
|
||||
} else {
|
||||
Overlays.editOverlay(app.spheres[index(handNum, 0)], {
|
||||
visible: false
|
||||
});
|
||||
|
||||
Overlays.editOverlay(app.spheres[index(handNum, 1)], {
|
||||
visible: false
|
||||
});
|
||||
}
|
||||
Overlays.editOverlay(app.spheres[index(handNum, 1)], {
|
||||
visible: false
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function update(deltaTime) {
|
||||
updateHand(LEFT_HAND, deltaTime);
|
||||
updateHand(RIGHT_HAND, deltaTime);
|
||||
updateHand(LEFT_HAND, deltaTime);
|
||||
updateHand(RIGHT_HAND, deltaTime);
|
||||
}
|
||||
|
||||
function scriptEnding() {
|
||||
print("Removing spheres = " + JSON.stringify(app.spheres));
|
||||
for (var i = 0; i < app.spheres.length; i++) {
|
||||
Overlays.deleteOverlay(app.spheres[i]);
|
||||
}
|
||||
print("Removing spheres = " + JSON.stringify(app.spheres));
|
||||
for (var i = 0; i < app.spheres.length; i++) {
|
||||
Overlays.deleteOverlay(app.spheres[i]);
|
||||
}
|
||||
}
|
||||
|
||||
setup();
|
||||
|
|
|
@ -66,6 +66,7 @@
|
|||
#include <input-plugins/InputPlugin.h>
|
||||
#include <input-plugins/Joystick.h> // this should probably be removed
|
||||
#include <controllers/UserInputMapper.h>
|
||||
#include <controllers/StateController.h>
|
||||
#include <LogHandler.h>
|
||||
#include <MainWindow.h>
|
||||
#include <MessageDialog.h>
|
||||
|
@ -143,6 +144,7 @@
|
|||
#include "ui/UpdateDialog.h"
|
||||
#include "Util.h"
|
||||
|
||||
|
||||
// ON WIndows PC, NVidia Optimus laptop, we want to enable NVIDIA GPU
|
||||
// FIXME seems to be broken.
|
||||
#if defined(Q_OS_WIN)
|
||||
|
@ -346,47 +348,47 @@ int _keyboardFocusHighlightID{ -1 };
|
|||
PluginContainer* _pluginContainer;
|
||||
|
||||
Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
||||
QApplication(argc, argv),
|
||||
_dependencyManagerIsSetup(setupEssentials(argc, argv)),
|
||||
_window(new MainWindow(desktop())),
|
||||
_toolWindow(NULL),
|
||||
_undoStackScriptingInterface(&_undoStack),
|
||||
_frameCount(0),
|
||||
_fps(60.0f),
|
||||
_physicsEngine(new PhysicsEngine(Vectors::ZERO)),
|
||||
_entities(true, this, this),
|
||||
_entityClipboardRenderer(false, this, this),
|
||||
_entityClipboard(new EntityTree()),
|
||||
_lastQueriedTime(usecTimestampNow()),
|
||||
_mirrorViewRect(QRect(MIRROR_VIEW_LEFT_PADDING, MIRROR_VIEW_TOP_PADDING, MIRROR_VIEW_WIDTH, MIRROR_VIEW_HEIGHT)),
|
||||
_firstRun("firstRun", true),
|
||||
_previousScriptLocation("LastScriptLocation", DESKTOP_LOCATION),
|
||||
_scriptsLocationHandle("scriptsLocation", DESKTOP_LOCATION),
|
||||
_fieldOfView("fieldOfView", DEFAULT_FIELD_OF_VIEW_DEGREES),
|
||||
_scaleMirror(1.0f),
|
||||
_rotateMirror(0.0f),
|
||||
_raiseMirror(0.0f),
|
||||
_lastMouseMoveWasSimulated(false),
|
||||
_enableProcessOctreeThread(true),
|
||||
_runningScriptsWidget(NULL),
|
||||
_runningScriptsWidgetWasVisible(false),
|
||||
_lastNackTime(usecTimestampNow()),
|
||||
_lastSendDownstreamAudioStats(usecTimestampNow()),
|
||||
_aboutToQuit(false),
|
||||
_notifiedPacketVersionMismatchThisDomain(false),
|
||||
_maxOctreePPS(maxOctreePacketsPerSecond.get()),
|
||||
_lastFaceTrackerUpdate(0)
|
||||
QApplication(argc, argv),
|
||||
_dependencyManagerIsSetup(setupEssentials(argc, argv)),
|
||||
_window(new MainWindow(desktop())),
|
||||
_toolWindow(NULL),
|
||||
_undoStackScriptingInterface(&_undoStack),
|
||||
_frameCount(0),
|
||||
_fps(60.0f),
|
||||
_physicsEngine(new PhysicsEngine(Vectors::ZERO)),
|
||||
_entities(true, this, this),
|
||||
_entityClipboardRenderer(false, this, this),
|
||||
_entityClipboard(new EntityTree()),
|
||||
_lastQueriedTime(usecTimestampNow()),
|
||||
_mirrorViewRect(QRect(MIRROR_VIEW_LEFT_PADDING, MIRROR_VIEW_TOP_PADDING, MIRROR_VIEW_WIDTH, MIRROR_VIEW_HEIGHT)),
|
||||
_firstRun("firstRun", true),
|
||||
_previousScriptLocation("LastScriptLocation", DESKTOP_LOCATION),
|
||||
_scriptsLocationHandle("scriptsLocation", DESKTOP_LOCATION),
|
||||
_fieldOfView("fieldOfView", DEFAULT_FIELD_OF_VIEW_DEGREES),
|
||||
_scaleMirror(1.0f),
|
||||
_rotateMirror(0.0f),
|
||||
_raiseMirror(0.0f),
|
||||
_lastMouseMoveWasSimulated(false),
|
||||
_enableProcessOctreeThread(true),
|
||||
_runningScriptsWidget(NULL),
|
||||
_runningScriptsWidgetWasVisible(false),
|
||||
_lastNackTime(usecTimestampNow()),
|
||||
_lastSendDownstreamAudioStats(usecTimestampNow()),
|
||||
_aboutToQuit(false),
|
||||
_notifiedPacketVersionMismatchThisDomain(false),
|
||||
_maxOctreePPS(maxOctreePacketsPerSecond.get()),
|
||||
_lastFaceTrackerUpdate(0)
|
||||
{
|
||||
thread()->setObjectName("Main Thread");
|
||||
|
||||
|
||||
setInstance(this);
|
||||
|
||||
|
||||
auto controllerScriptingInterface = DependencyManager::get<controller::ScriptingInterface>().data();
|
||||
_controllerScriptingInterface = dynamic_cast<ControllerScriptingInterface*>(controllerScriptingInterface);
|
||||
// to work around the Qt constant wireless scanning, set the env for polling interval very high
|
||||
const QByteArray EXTREME_BEARER_POLL_TIMEOUT = QString::number(INT_MAX).toLocal8Bit();
|
||||
qputenv("QT_BEARER_POLL_TIMEOUT", EXTREME_BEARER_POLL_TIMEOUT);
|
||||
|
||||
|
||||
_entityClipboard->createRootElement();
|
||||
|
||||
_pluginContainer = new PluginContainerProxy();
|
||||
|
@ -449,7 +451,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
|||
audioIO->moveToThread(audioThread);
|
||||
|
||||
auto& audioScriptingInterface = AudioScriptingInterface::getInstance();
|
||||
|
||||
|
||||
connect(audioThread, &QThread::started, audioIO.data(), &AudioClient::start);
|
||||
connect(audioIO.data(), &AudioClient::destroyed, audioThread, &QThread::quit);
|
||||
connect(audioThread, &QThread::finished, audioThread, &QThread::deleteLater);
|
||||
|
@ -488,7 +490,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
|||
connect(&domainHandler, SIGNAL(disconnectedFromDomain()), SLOT(clearDomainOctreeDetails()));
|
||||
connect(&domainHandler, &DomainHandler::settingsReceived, this, &Application::domainSettingsReceived);
|
||||
connect(&domainHandler, &DomainHandler::hostnameChanged,
|
||||
DependencyManager::get<AddressManager>().data(), &AddressManager::storeCurrentAddress);
|
||||
DependencyManager::get<AddressManager>().data(), &AddressManager::storeCurrentAddress);
|
||||
|
||||
// update our location every 5 seconds in the metaverse server, assuming that we are authenticated with one
|
||||
const qint64 DATA_SERVER_LOCATION_CHANGE_UPDATE_MSECS = 5 * 1000;
|
||||
|
@ -499,7 +501,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
|||
|
||||
// if we get a domain change, immediately attempt update location in metaverse server
|
||||
connect(&nodeList->getDomainHandler(), &DomainHandler::connectedToDomain,
|
||||
discoverabilityManager.data(), &DiscoverabilityManager::updateLocation);
|
||||
discoverabilityManager.data(), &DiscoverabilityManager::updateLocation);
|
||||
|
||||
connect(nodeList.data(), &NodeList::nodeAdded, this, &Application::nodeAdded);
|
||||
connect(nodeList.data(), &NodeList::nodeKilled, this, &Application::nodeKilled);
|
||||
|
@ -538,14 +540,14 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
|||
connect(addressManager.data(), &AddressManager::hostChanged, this, &Application::updateWindowTitle);
|
||||
connect(this, &QCoreApplication::aboutToQuit, addressManager.data(), &AddressManager::storeCurrentAddress);
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifdef _WIN32
|
||||
WSADATA WsaData;
|
||||
int wsaresult = WSAStartup(MAKEWORD(2,2), &WsaData);
|
||||
#endif
|
||||
int wsaresult = WSAStartup(MAKEWORD(2, 2), &WsaData);
|
||||
#endif
|
||||
|
||||
// tell the NodeList instance who to tell the domain server we care about
|
||||
nodeList->addSetOfNodeTypesToNodeInterestSet(NodeSet() << NodeType::AudioMixer << NodeType::AvatarMixer
|
||||
<< NodeType::EntityServer << NodeType::AssetServer);
|
||||
<< NodeType::EntityServer << NodeType::AssetServer);
|
||||
|
||||
// connect to the packet sent signal of the _entityEditSender
|
||||
connect(&_entityEditSender, &EntityEditPacketSender::packetSent, this, &Application::packetSent);
|
||||
|
@ -618,12 +620,12 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
|||
// hook up bandwidth estimator
|
||||
QSharedPointer<BandwidthRecorder> bandwidthRecorder = DependencyManager::get<BandwidthRecorder>();
|
||||
connect(nodeList.data(), &LimitedNodeList::dataSent,
|
||||
bandwidthRecorder.data(), &BandwidthRecorder::updateOutboundData);
|
||||
bandwidthRecorder.data(), &BandwidthRecorder::updateOutboundData);
|
||||
connect(&nodeList->getPacketReceiver(), &PacketReceiver::dataReceived,
|
||||
bandwidthRecorder.data(), &BandwidthRecorder::updateInboundData);
|
||||
bandwidthRecorder.data(), &BandwidthRecorder::updateInboundData);
|
||||
|
||||
connect(&getMyAvatar()->getSkeletonModel(), &SkeletonModel::skeletonLoaded,
|
||||
this, &Application::checkSkeleton, Qt::QueuedConnection);
|
||||
this, &Application::checkSkeleton, Qt::QueuedConnection);
|
||||
|
||||
// Setup the userInputMapper with the actions
|
||||
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
||||
|
@ -633,9 +635,19 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
|||
}
|
||||
});
|
||||
|
||||
// A new controllerInput device used to reflect current values from the application state
|
||||
_applicationStateDevice = new controller::StateController("Application");
|
||||
auto InHMDLambda = controller::StateController::ReadLambda([]() -> float {
|
||||
return (float) qApp->getAvatarUpdater()->isHMDMode();
|
||||
});
|
||||
_applicationStateDevice->addInputVariant("InHMD", InHMDLambda);
|
||||
|
||||
userInputMapper->registerDevice(_applicationStateDevice);
|
||||
|
||||
// Setup the keyboardMouseDevice and the user input mapper with the default bindings
|
||||
userInputMapper->registerDevice(_keyboardMouseDevice);
|
||||
|
||||
|
||||
// check first run...
|
||||
if (_firstRun.get()) {
|
||||
qCDebug(interfaceapp) << "This is a first run...";
|
||||
|
@ -795,6 +807,10 @@ void Application::cleanupBeforeQuit() {
|
|||
|
||||
AnimDebugDraw::getInstance().shutdown();
|
||||
|
||||
// FIXME: once we move to shared pointer for the INputDevice we shoud remove this naked delete:
|
||||
delete _applicationStateDevice;
|
||||
_applicationStateDevice = nullptr;
|
||||
|
||||
if (_keyboardFocusHighlightID > 0) {
|
||||
getOverlays().deleteOverlay(_keyboardFocusHighlightID);
|
||||
_keyboardFocusHighlightID = -1;
|
||||
|
@ -2738,6 +2754,7 @@ void Application::update(float deltaTime) {
|
|||
}
|
||||
myAvatar->setDriveKeys(ZOOM, userInputMapper->getActionState(controller::Action::TRANSLATE_CAMERA_Z));
|
||||
}
|
||||
|
||||
controller::Pose leftHand = userInputMapper->getPoseState(controller::Action::LEFT_HAND);
|
||||
controller::Pose rightHand = userInputMapper->getPoseState(controller::Action::RIGHT_HAND);
|
||||
Hand* hand = DependencyManager::get<AvatarManager>()->getMyAvatar()->getHand();
|
||||
|
|
|
@ -71,6 +71,10 @@ class FaceTracker;
|
|||
class MainWindow;
|
||||
class AssetUpload;
|
||||
|
||||
namespace controller {
|
||||
class StateController;
|
||||
}
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
static const UINT UWM_IDENTIFY_INSTANCES =
|
||||
RegisterWindowMessage("UWM_IDENTIFY_INSTANCES_{8AB82783-B74A-4258-955B-8188C22AA0D6}_" + qgetenv("USERNAME"));
|
||||
|
@ -442,6 +446,7 @@ private:
|
|||
|
||||
OctreeQuery _octreeQuery; // NodeData derived class for querying octee cells from octree servers
|
||||
|
||||
controller::StateController* _applicationStateDevice{ nullptr }; // Default ApplicationDevice reflecting the state of different properties of the session
|
||||
KeyboardMouseDevice* _keyboardMouseDevice{ nullptr }; // Default input device, the good old keyboard mouse and maybe touchpad
|
||||
AvatarUpdate* _avatarUpdate {nullptr};
|
||||
SimpleMovingAverage _avatarSimsPerSecond {10};
|
||||
|
|
|
@ -77,7 +77,7 @@ enum class Action {
|
|||
// Biseced aliases for TRANSLATE_CAMERA_Z
|
||||
BOOM_IN,
|
||||
BOOM_OUT,
|
||||
|
||||
|
||||
NUM_ACTIONS,
|
||||
};
|
||||
|
||||
|
|
|
@ -26,6 +26,5 @@ namespace controller {
|
|||
return NAN;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,8 @@ namespace controller {
|
|||
|
||||
using Modifiers = std::vector<Input>;
|
||||
typedef QPair<Input, QString> InputPair;
|
||||
|
||||
class Endpoint;
|
||||
using EndpointPtr = std::shared_ptr<Endpoint>;
|
||||
|
||||
template<typename T>
|
||||
using InputGetter = std::function<T(const Input& input, int timestamp)>;
|
||||
|
@ -32,6 +33,7 @@ namespace controller {
|
|||
using PoseGetter = InputGetter<Pose>;
|
||||
using ResetBindings = std::function<bool()>;
|
||||
using AvailableInputGetter = std::function<Input::NamedVector()>;
|
||||
using EndpointCreator = std::function<EndpointPtr(const Input&)>;
|
||||
|
||||
class DeviceProxy {
|
||||
public:
|
||||
|
@ -42,6 +44,9 @@ namespace controller {
|
|||
PoseGetter getPose = [](const Input& input, int timestamp) -> Pose { return Pose(); };
|
||||
AvailableInputGetter getAvailabeInputs = []() -> Input::NamedVector const { return Input::NamedVector(); };
|
||||
float getValue(const Input& input, int timestamp = 0) const;
|
||||
|
||||
EndpointCreator createEndpoint = [](const Input& input) -> EndpointPtr { return EndpointPtr(); };
|
||||
|
||||
QString _name;
|
||||
};
|
||||
}
|
||||
|
|
61
libraries/controllers/src/controllers/StateController.cpp
Normal file
61
libraries/controllers/src/controllers/StateController.cpp
Normal file
|
@ -0,0 +1,61 @@
|
|||
//
|
||||
// StateController.cpp
|
||||
// controllers/src/controllers
|
||||
//
|
||||
// Created by Sam Gateau on 2015-10-27.
|
||||
// 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 "StateController.h"
|
||||
|
||||
#include <PathUtils.h>
|
||||
|
||||
#include "DeviceProxy.h"
|
||||
#include "UserInputMapper.h"
|
||||
#include "impl/Endpoint.h"
|
||||
|
||||
namespace controller {
|
||||
|
||||
StateController::StateController(QString name) : InputDevice(name) {
|
||||
}
|
||||
|
||||
StateController::~StateController() {
|
||||
}
|
||||
|
||||
void StateController::update(float deltaTime, bool jointsCaptured) {}
|
||||
|
||||
void StateController::focusOutEvent() {}
|
||||
|
||||
void StateController::addInputVariant(QString name, ReadLambda& lambda) {
|
||||
_namedReadLambdas.push_back(NamedReadLambda(name, lambda));
|
||||
}
|
||||
void StateController::buildDeviceProxy(DeviceProxy::Pointer proxy) {
|
||||
proxy->_name = _name;
|
||||
proxy->getButton = [this] (const Input& input, int timestamp) -> bool { return getButton(input.getChannel()); };
|
||||
proxy->getAxis = [this] (const Input& input, int timestamp) -> float { return getAxis(input.getChannel()); };
|
||||
proxy->getAvailabeInputs = [this] () -> QVector<Input::NamedPair> {
|
||||
|
||||
|
||||
QVector<Input::NamedPair> availableInputs;
|
||||
|
||||
int i = 0;
|
||||
for (auto& pair : _namedReadLambdas) {
|
||||
availableInputs.push_back(Input::NamedPair(Input(_deviceID, i, ChannelType::BUTTON), pair.first));
|
||||
i++;
|
||||
}
|
||||
return availableInputs;
|
||||
};
|
||||
proxy->createEndpoint = [this] (const Input& input) -> Endpoint::Pointer {
|
||||
if (input.getChannel() < _namedReadLambdas.size()) {
|
||||
return std::make_shared<LambdaEndpoint>(_namedReadLambdas[input.getChannel()].second);
|
||||
}
|
||||
|
||||
return Endpoint::Pointer();
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
}
|
49
libraries/controllers/src/controllers/StateController.h
Normal file
49
libraries/controllers/src/controllers/StateController.h
Normal file
|
@ -0,0 +1,49 @@
|
|||
//
|
||||
// StateController.h
|
||||
// controllers/src/controllers
|
||||
//
|
||||
// Created by Sam Gateau on 2015-10-27.
|
||||
// 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
|
||||
//
|
||||
|
||||
#ifndef hifi_StateController_h
|
||||
#define hifi_StateController_h
|
||||
|
||||
#include <QtCore/QObject>
|
||||
#include <QtCore/QVector>
|
||||
|
||||
#include "InputDevice.h"
|
||||
|
||||
namespace controller {
|
||||
|
||||
class StateController : public QObject, public InputDevice {
|
||||
Q_OBJECT
|
||||
Q_PROPERTY(QString name READ getName)
|
||||
|
||||
public:
|
||||
const QString& getName() const { return _name; }
|
||||
|
||||
// Device functions
|
||||
virtual void buildDeviceProxy(DeviceProxy::Pointer proxy) override;
|
||||
virtual QString getDefaultMappingConfig() override { return QString(); }
|
||||
virtual void update(float deltaTime, bool jointsCaptured) override;
|
||||
virtual void focusOutEvent() override;
|
||||
|
||||
StateController(QString name);
|
||||
virtual ~StateController();
|
||||
|
||||
using ReadLambda = std::function<float()>;
|
||||
using NamedReadLambda = QPair<QString, ReadLambda>;
|
||||
|
||||
void addInputVariant(QString name, ReadLambda& lambda);
|
||||
|
||||
protected:
|
||||
QVector<NamedReadLambda> _namedReadLambdas;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // hifi_StateController_h
|
|
@ -21,6 +21,7 @@
|
|||
#include <NumericalConstants.h>
|
||||
|
||||
#include "StandardController.h"
|
||||
#include "StateController.h"
|
||||
|
||||
#include "Logging.h"
|
||||
|
||||
|
@ -89,13 +90,16 @@ void UserInputMapper::registerDevice(InputDevice* device) {
|
|||
if (_endpointsByInput.count(input)) {
|
||||
continue;
|
||||
}
|
||||
Endpoint::Pointer endpoint;
|
||||
if (input.device == STANDARD_DEVICE) {
|
||||
endpoint = std::make_shared<StandardEndpoint>(input);
|
||||
} else if (input.device == ACTIONS_DEVICE) {
|
||||
endpoint = std::make_shared<ActionEndpoint>(input);
|
||||
} else {
|
||||
endpoint = std::make_shared<InputEndpoint>(input);
|
||||
|
||||
Endpoint::Pointer endpoint = proxy->createEndpoint(input);
|
||||
if (!endpoint) {
|
||||
if (input.device == STANDARD_DEVICE) {
|
||||
endpoint = std::make_shared<StandardEndpoint>(input);
|
||||
} else if (input.device == ACTIONS_DEVICE) {
|
||||
endpoint = std::make_shared<ActionEndpoint>(input);
|
||||
} else {
|
||||
endpoint = std::make_shared<InputEndpoint>(input);
|
||||
}
|
||||
}
|
||||
_inputsByEndpoint[endpoint] = input;
|
||||
_endpointsByInput[input] = endpoint;
|
||||
|
@ -953,19 +957,17 @@ Mapping::Pointer UserInputMapper::parseMapping(const QString& json) {
|
|||
QJsonDocument doc = QJsonDocument::fromJson(json.toUtf8(), &error);
|
||||
// check validity of the document
|
||||
if (doc.isNull()) {
|
||||
qDebug() << "Invalid JSON...\n";
|
||||
qDebug() << error.errorString();
|
||||
qDebug() << "JSON was:\n" << json << endl;
|
||||
return Mapping::Pointer();
|
||||
}
|
||||
|
||||
if (!doc.isObject()) {
|
||||
qWarning() << "Mapping json Document is not an object" << endl;
|
||||
qDebug() << "JSON was:\n" << json << endl;
|
||||
return Mapping::Pointer();
|
||||
}
|
||||
|
||||
// FIXME how did we detect this?
|
||||
// qDebug() << "Invalid JSON...\n";
|
||||
// qDebug() << error.errorString();
|
||||
// qDebug() << "JSON was:\n" << json << endl;
|
||||
//}
|
||||
return parseMapping(doc.object());
|
||||
}
|
||||
|
||||
|
|
|
@ -84,6 +84,7 @@ namespace controller {
|
|||
Pose getPoseState(Action action) const { return _poseStates[toInt(action)]; }
|
||||
int findAction(const QString& actionName) const;
|
||||
QVector<QString> getActionNames() const;
|
||||
Input inputFromAction(Action action) const { return getActionInputs()[toInt(action)].first; }
|
||||
|
||||
void setActionState(Action action, float value) { _actionStates[toInt(action)] = value; }
|
||||
void deltaActionState(Action action, float delta) { _actionStates[toInt(action)] += delta; }
|
||||
|
|
Loading…
Reference in a new issue