mirror of
https://github.com/overte-org/overte.git
synced 2025-07-23 11:44:09 +02:00
merge from upstream
This commit is contained in:
commit
f91a2403be
65 changed files with 636 additions and 587 deletions
|
@ -55,9 +55,9 @@ void DomainGatekeeper::processConnectRequestPacket(QSharedPointer<ReceivedMessag
|
||||||
if (message->getSize() == 0) {
|
if (message->getSize() == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDataStream packetStream(message->getMessage());
|
QDataStream packetStream(message->getMessage());
|
||||||
|
|
||||||
// read a NodeConnectionData object from the packet so we can pass around this data while we're inspecting it
|
// read a NodeConnectionData object from the packet so we can pass around this data while we're inspecting it
|
||||||
NodeConnectionData nodeConnection = NodeConnectionData::fromDataStream(packetStream, message->getSenderSockAddr());
|
NodeConnectionData nodeConnection = NodeConnectionData::fromDataStream(packetStream, message->getSenderSockAddr());
|
||||||
|
|
||||||
|
@ -105,6 +105,7 @@ void DomainGatekeeper::processConnectRequestPacket(QSharedPointer<ReceivedMessag
|
||||||
DomainServerNodeData* nodeData = reinterpret_cast<DomainServerNodeData*>(node->getLinkedData());
|
DomainServerNodeData* nodeData = reinterpret_cast<DomainServerNodeData*>(node->getLinkedData());
|
||||||
nodeData->setSendingSockAddr(message->getSenderSockAddr());
|
nodeData->setSendingSockAddr(message->getSenderSockAddr());
|
||||||
nodeData->setNodeInterestSet(nodeConnection.interestList.toSet());
|
nodeData->setNodeInterestSet(nodeConnection.interestList.toSet());
|
||||||
|
nodeData->setPlaceName(nodeConnection.placeName);
|
||||||
|
|
||||||
// signal that we just connected a node so the DomainServer can get it a list
|
// signal that we just connected a node so the DomainServer can get it a list
|
||||||
// and broadcast its presence right away
|
// and broadcast its presence right away
|
||||||
|
@ -150,6 +151,7 @@ SharedNodePointer DomainGatekeeper::processAssignmentConnectRequest(const NodeCo
|
||||||
nodeData->setAssignmentUUID(matchingQueuedAssignment->getUUID());
|
nodeData->setAssignmentUUID(matchingQueuedAssignment->getUUID());
|
||||||
nodeData->setWalletUUID(it->second.getWalletUUID());
|
nodeData->setWalletUUID(it->second.getWalletUUID());
|
||||||
nodeData->setNodeVersion(it->second.getNodeVersion());
|
nodeData->setNodeVersion(it->second.getNodeVersion());
|
||||||
|
nodeData->setWasAssigned(true);
|
||||||
|
|
||||||
// cleanup the PendingAssignedNodeData for this assignment now that it's connecting
|
// cleanup the PendingAssignedNodeData for this assignment now that it's connecting
|
||||||
_pendingAssignedNodes.erase(it);
|
_pendingAssignedNodes.erase(it);
|
||||||
|
@ -282,7 +284,7 @@ SharedNodePointer DomainGatekeeper::processAgentConnectRequest(const NodeConnect
|
||||||
// set the edit rights for this user
|
// set the edit rights for this user
|
||||||
newNode->setIsAllowedEditor(isAllowedEditor);
|
newNode->setIsAllowedEditor(isAllowedEditor);
|
||||||
newNode->setCanRez(canRez);
|
newNode->setCanRez(canRez);
|
||||||
|
|
||||||
// grab the linked data for our new node so we can set the username
|
// grab the linked data for our new node so we can set the username
|
||||||
DomainServerNodeData* nodeData = reinterpret_cast<DomainServerNodeData*>(newNode->getLinkedData());
|
DomainServerNodeData* nodeData = reinterpret_cast<DomainServerNodeData*>(newNode->getLinkedData());
|
||||||
|
|
||||||
|
|
|
@ -462,7 +462,7 @@ void DomainServer::setupAutomaticNetworking() {
|
||||||
nodeList->startSTUNPublicSocketUpdate();
|
nodeList->startSTUNPublicSocketUpdate();
|
||||||
} else {
|
} else {
|
||||||
// send our heartbeat to data server so it knows what our network settings are
|
// send our heartbeat to data server so it knows what our network settings are
|
||||||
sendHeartbeatToDataServer();
|
sendHeartbeatToMetaverse();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "Cannot enable domain-server automatic networking without a domain ID."
|
qDebug() << "Cannot enable domain-server automatic networking without a domain ID."
|
||||||
|
@ -471,7 +471,7 @@ void DomainServer::setupAutomaticNetworking() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sendHeartbeatToDataServer();
|
sendHeartbeatToMetaverse();
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "Updating automatic networking setting in domain-server to" << _automaticNetworkingSetting;
|
qDebug() << "Updating automatic networking setting in domain-server to" << _automaticNetworkingSetting;
|
||||||
|
@ -480,7 +480,7 @@ void DomainServer::setupAutomaticNetworking() {
|
||||||
const int DOMAIN_SERVER_DATA_WEB_HEARTBEAT_MSECS = 15 * 1000;
|
const int DOMAIN_SERVER_DATA_WEB_HEARTBEAT_MSECS = 15 * 1000;
|
||||||
|
|
||||||
QTimer* dataHeartbeatTimer = new QTimer(this);
|
QTimer* dataHeartbeatTimer = new QTimer(this);
|
||||||
connect(dataHeartbeatTimer, SIGNAL(timeout()), this, SLOT(sendHeartbeatToDataServer()));
|
connect(dataHeartbeatTimer, SIGNAL(timeout()), this, SLOT(sendHeartbeatToMetaverse()));
|
||||||
dataHeartbeatTimer->start(DOMAIN_SERVER_DATA_WEB_HEARTBEAT_MSECS);
|
dataHeartbeatTimer->start(DOMAIN_SERVER_DATA_WEB_HEARTBEAT_MSECS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -678,6 +678,9 @@ void DomainServer::processListRequestPacket(QSharedPointer<ReceivedMessage> mess
|
||||||
DomainServerNodeData* nodeData = reinterpret_cast<DomainServerNodeData*>(sendingNode->getLinkedData());
|
DomainServerNodeData* nodeData = reinterpret_cast<DomainServerNodeData*>(sendingNode->getLinkedData());
|
||||||
nodeData->setNodeInterestSet(nodeRequestData.interestList.toSet());
|
nodeData->setNodeInterestSet(nodeRequestData.interestList.toSet());
|
||||||
|
|
||||||
|
// update the connecting hostname in case it has changed
|
||||||
|
nodeData->setPlaceName(nodeRequestData.placeName);
|
||||||
|
|
||||||
sendDomainListToNode(sendingNode, message->getSenderSockAddr());
|
sendDomainListToNode(sendingNode, message->getSenderSockAddr());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1029,11 +1032,11 @@ QJsonObject jsonForDomainSocketUpdate(const HifiSockAddr& socket) {
|
||||||
const QString DOMAIN_UPDATE_AUTOMATIC_NETWORKING_KEY = "automatic_networking";
|
const QString DOMAIN_UPDATE_AUTOMATIC_NETWORKING_KEY = "automatic_networking";
|
||||||
|
|
||||||
void DomainServer::performIPAddressUpdate(const HifiSockAddr& newPublicSockAddr) {
|
void DomainServer::performIPAddressUpdate(const HifiSockAddr& newPublicSockAddr) {
|
||||||
sendHeartbeatToDataServer(newPublicSockAddr.getAddress().toString());
|
sendHeartbeatToMetaverse(newPublicSockAddr.getAddress().toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void DomainServer::sendHeartbeatToDataServer(const QString& networkAddress) {
|
void DomainServer::sendHeartbeatToMetaverse(const QString& networkAddress) {
|
||||||
const QString DOMAIN_UPDATE = "/api/v1/domains/%1";
|
const QString DOMAIN_UPDATE = "/api/v1/domains/%1";
|
||||||
|
|
||||||
auto nodeList = DependencyManager::get<LimitedNodeList>();
|
auto nodeList = DependencyManager::get<LimitedNodeList>();
|
||||||
|
@ -1056,20 +1059,34 @@ void DomainServer::sendHeartbeatToDataServer(const QString& networkAddress) {
|
||||||
domainObject[RESTRICTED_ACCESS_FLAG] =
|
domainObject[RESTRICTED_ACCESS_FLAG] =
|
||||||
_settingsManager.valueOrDefaultValueForKeyPath(RESTRICTED_ACCESS_SETTINGS_KEYPATH).toBool();
|
_settingsManager.valueOrDefaultValueForKeyPath(RESTRICTED_ACCESS_SETTINGS_KEYPATH).toBool();
|
||||||
|
|
||||||
// add the number of currently connected agent users
|
// figure out the breakdown of currently connected interface clients
|
||||||
int numConnectedAuthedUsers = 0;
|
int numConnectedUnassigned = 0;
|
||||||
|
QJsonObject userHostnames;
|
||||||
|
|
||||||
nodeList->eachNode([&numConnectedAuthedUsers](const SharedNodePointer& node){
|
static const QString DEFAULT_HOSTNAME = "*";
|
||||||
if (node->getLinkedData() && !static_cast<DomainServerNodeData*>(node->getLinkedData())->getUsername().isEmpty()) {
|
|
||||||
++numConnectedAuthedUsers;
|
nodeList->eachNode([&numConnectedUnassigned, &userHostnames](const SharedNodePointer& node) {
|
||||||
|
if (node->getLinkedData()) {
|
||||||
|
auto nodeData = static_cast<DomainServerNodeData*>(node->getLinkedData());
|
||||||
|
|
||||||
|
if (!nodeData->wasAssigned()) {
|
||||||
|
++numConnectedUnassigned;
|
||||||
|
|
||||||
|
// increment the count for this hostname (or the default if we don't have one)
|
||||||
|
auto hostname = nodeData->getPlaceName().isEmpty() ? DEFAULT_HOSTNAME : nodeData->getPlaceName();
|
||||||
|
userHostnames[hostname] = userHostnames[hostname].toInt() + 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const QString DOMAIN_HEARTBEAT_KEY = "heartbeat";
|
static const QString DOMAIN_HEARTBEAT_KEY = "heartbeat";
|
||||||
const QString HEARTBEAT_NUM_USERS_KEY = "num_users";
|
static const QString HEARTBEAT_NUM_USERS_KEY = "num_users";
|
||||||
|
static const QString HEARTBEAT_USER_HOSTNAMES_KEY = "user_hostnames";
|
||||||
|
|
||||||
QJsonObject heartbeatObject;
|
QJsonObject heartbeatObject;
|
||||||
heartbeatObject[HEARTBEAT_NUM_USERS_KEY] = numConnectedAuthedUsers;
|
heartbeatObject[HEARTBEAT_NUM_USERS_KEY] = numConnectedUnassigned;
|
||||||
|
heartbeatObject[HEARTBEAT_USER_HOSTNAMES_KEY] = userHostnames;
|
||||||
|
|
||||||
domainObject[DOMAIN_HEARTBEAT_KEY] = heartbeatObject;
|
domainObject[DOMAIN_HEARTBEAT_KEY] = heartbeatObject;
|
||||||
|
|
||||||
QString domainUpdateJSON = QString("{\"domain\": %1 }").arg(QString(QJsonDocument(domainObject).toJson()));
|
QString domainUpdateJSON = QString("{\"domain\": %1 }").arg(QString(QJsonDocument(domainObject).toJson()));
|
||||||
|
|
|
@ -71,7 +71,7 @@ private slots:
|
||||||
void sendPendingTransactionsToServer();
|
void sendPendingTransactionsToServer();
|
||||||
|
|
||||||
void performIPAddressUpdate(const HifiSockAddr& newPublicSockAddr);
|
void performIPAddressUpdate(const HifiSockAddr& newPublicSockAddr);
|
||||||
void sendHeartbeatToDataServer() { sendHeartbeatToDataServer(QString()); }
|
void sendHeartbeatToMetaverse() { sendHeartbeatToMetaverse(QString()); }
|
||||||
void sendHeartbeatToIceServer();
|
void sendHeartbeatToIceServer();
|
||||||
|
|
||||||
void handleConnectedNode(SharedNodePointer newNode);
|
void handleConnectedNode(SharedNodePointer newNode);
|
||||||
|
@ -103,7 +103,7 @@ private:
|
||||||
|
|
||||||
void setupAutomaticNetworking();
|
void setupAutomaticNetworking();
|
||||||
void setupICEHeartbeatForFullNetworking();
|
void setupICEHeartbeatForFullNetworking();
|
||||||
void sendHeartbeatToDataServer(const QString& networkAddress);
|
void sendHeartbeatToMetaverse(const QString& networkAddress);
|
||||||
|
|
||||||
void randomizeICEServerAddress(bool shouldTriggerHostLookup);
|
void randomizeICEServerAddress(bool shouldTriggerHostLookup);
|
||||||
|
|
||||||
|
|
|
@ -56,6 +56,12 @@ public:
|
||||||
|
|
||||||
void addOverrideForKey(const QString& key, const QString& value, const QString& overrideValue);
|
void addOverrideForKey(const QString& key, const QString& value, const QString& overrideValue);
|
||||||
void removeOverrideForKey(const QString& key, const QString& value);
|
void removeOverrideForKey(const QString& key, const QString& value);
|
||||||
|
|
||||||
|
const QString& getPlaceName() { return _placeName; }
|
||||||
|
void setPlaceName(const QString& placeName) { _placeName = placeName; }
|
||||||
|
|
||||||
|
bool wasAssigned() const { return _wasAssigned; };
|
||||||
|
void setWasAssigned(bool wasAssigned) { _wasAssigned = wasAssigned; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QJsonObject overrideValuesIfNeeded(const QJsonObject& newStats);
|
QJsonObject overrideValuesIfNeeded(const QJsonObject& newStats);
|
||||||
|
@ -75,6 +81,10 @@ private:
|
||||||
bool _isAuthenticated = true;
|
bool _isAuthenticated = true;
|
||||||
NodeSet _nodeInterestSet;
|
NodeSet _nodeInterestSet;
|
||||||
QString _nodeVersion;
|
QString _nodeVersion;
|
||||||
|
|
||||||
|
QString _placeName;
|
||||||
|
|
||||||
|
bool _wasAssigned { false };
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_DomainServerNodeData_h
|
#endif // hifi_DomainServerNodeData_h
|
||||||
|
|
|
@ -23,7 +23,7 @@ NodeConnectionData NodeConnectionData::fromDataStream(QDataStream& dataStream, c
|
||||||
|
|
||||||
dataStream >> newHeader.nodeType
|
dataStream >> newHeader.nodeType
|
||||||
>> newHeader.publicSockAddr >> newHeader.localSockAddr
|
>> newHeader.publicSockAddr >> newHeader.localSockAddr
|
||||||
>> newHeader.interestList;
|
>> newHeader.interestList >> newHeader.placeName;
|
||||||
|
|
||||||
newHeader.senderSockAddr = senderSockAddr;
|
newHeader.senderSockAddr = senderSockAddr;
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ public:
|
||||||
HifiSockAddr localSockAddr;
|
HifiSockAddr localSockAddr;
|
||||||
HifiSockAddr senderSockAddr;
|
HifiSockAddr senderSockAddr;
|
||||||
QList<NodeType_t> interestList;
|
QList<NodeType_t> interestList;
|
||||||
|
QString placeName;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,10 +4,6 @@ project(${TARGET_NAME})
|
||||||
# set a default root dir for each of our optional externals if it was not passed
|
# set a default root dir for each of our optional externals if it was not passed
|
||||||
set(OPTIONAL_EXTERNALS "LeapMotion")
|
set(OPTIONAL_EXTERNALS "LeapMotion")
|
||||||
|
|
||||||
if(WIN32)
|
|
||||||
list(APPEND OPTIONAL_EXTERNALS "3DConnexionClient")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
foreach(EXTERNAL ${OPTIONAL_EXTERNALS})
|
foreach(EXTERNAL ${OPTIONAL_EXTERNALS})
|
||||||
string(TOUPPER ${EXTERNAL} ${EXTERNAL}_UPPERCASE)
|
string(TOUPPER ${EXTERNAL} ${EXTERNAL}_UPPERCASE)
|
||||||
if (NOT ${${EXTERNAL}_UPPERCASE}_ROOT_DIR)
|
if (NOT ${${EXTERNAL}_UPPERCASE}_ROOT_DIR)
|
||||||
|
|
|
@ -2,11 +2,11 @@
|
||||||
"name": "Spacemouse to Standard",
|
"name": "Spacemouse to Standard",
|
||||||
"channels": [
|
"channels": [
|
||||||
|
|
||||||
{ "from": "Spacemouse.TranslateX", "to": "Standard.RX" },
|
{ "from": "Spacemouse.TranslateX", "to": "Standard.LX" },
|
||||||
{ "from": "Spacemouse.TranslateY", "to": "Standard.LY" },
|
{ "from": "Spacemouse.TranslateY", "to": "Standard.LY" },
|
||||||
{ "from": "Spacemouse.TranslateZ", "to": "Standard.RY" },
|
{ "from": "Spacemouse.TranslateZ", "to": "Standard.RY" },
|
||||||
|
|
||||||
{ "from": "Spacemouse.RotateZ", "to": "Standard.LX" },
|
{ "from": "Spacemouse.RotateZ", "to": "Standard.RX" },
|
||||||
|
|
||||||
{ "from": "Spacemouse.LeftButton", "to": "Standard.LB" },
|
{ "from": "Spacemouse.LeftButton", "to": "Standard.LB" },
|
||||||
{ "from": "Spacemouse.RightButton", "to": "Standard.RB" }
|
{ "from": "Spacemouse.RightButton", "to": "Standard.RB" }
|
||||||
|
|
|
@ -108,7 +108,6 @@
|
||||||
#include "audio/AudioScope.h"
|
#include "audio/AudioScope.h"
|
||||||
#include "avatar/AvatarManager.h"
|
#include "avatar/AvatarManager.h"
|
||||||
#include "CrashHandler.h"
|
#include "CrashHandler.h"
|
||||||
#include "input-plugins/SpacemouseManager.h"
|
|
||||||
#include "devices/DdeFaceTracker.h"
|
#include "devices/DdeFaceTracker.h"
|
||||||
#include "devices/EyeTracker.h"
|
#include "devices/EyeTracker.h"
|
||||||
#include "devices/Faceshift.h"
|
#include "devices/Faceshift.h"
|
||||||
|
@ -199,6 +198,7 @@ static const float PHYSICS_READY_RANGE = 3.0f; // how far from avatar to check f
|
||||||
|
|
||||||
static const QString DESKTOP_LOCATION = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
|
static const QString DESKTOP_LOCATION = QStandardPaths::writableLocation(QStandardPaths::DesktopLocation);
|
||||||
|
|
||||||
|
static const QString INPUT_DEVICE_MENU_PREFIX = "Device: ";
|
||||||
Setting::Handle<int> maxOctreePacketsPerSecond("maxOctreePPS", DEFAULT_MAX_OCTREE_PPS);
|
Setting::Handle<int> maxOctreePacketsPerSecond("maxOctreePPS", DEFAULT_MAX_OCTREE_PPS);
|
||||||
|
|
||||||
const QHash<QString, Application::AcceptURLMethod> Application::_acceptedExtensions {
|
const QHash<QString, Application::AcceptURLMethod> Application::_acceptedExtensions {
|
||||||
|
@ -998,7 +998,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) :
|
||||||
RenderableWebEntityItem* webEntity = dynamic_cast<RenderableWebEntityItem*>(entity.get());
|
RenderableWebEntityItem* webEntity = dynamic_cast<RenderableWebEntityItem*>(entity.get());
|
||||||
if (webEntity) {
|
if (webEntity) {
|
||||||
webEntity->setProxyWindow(_window->windowHandle());
|
webEntity->setProxyWindow(_window->windowHandle());
|
||||||
if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) {
|
if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) {
|
||||||
_keyboardMouseDevice->pluginFocusOutEvent();
|
_keyboardMouseDevice->pluginFocusOutEvent();
|
||||||
}
|
}
|
||||||
_keyboardFocusedItem = entityItemID;
|
_keyboardFocusedItem = entityItemID;
|
||||||
|
@ -1126,7 +1126,7 @@ void Application::aboutToQuit() {
|
||||||
emit beforeAboutToQuit();
|
emit beforeAboutToQuit();
|
||||||
|
|
||||||
foreach(auto inputPlugin, PluginManager::getInstance()->getInputPlugins()) {
|
foreach(auto inputPlugin, PluginManager::getInstance()->getInputPlugins()) {
|
||||||
QString name = inputPlugin->getName();
|
QString name = INPUT_DEVICE_MENU_PREFIX + inputPlugin->getName();
|
||||||
QAction* action = Menu::getInstance()->getActionForOption(name);
|
QAction* action = Menu::getInstance()->getActionForOption(name);
|
||||||
if (action->isChecked()) {
|
if (action->isChecked()) {
|
||||||
inputPlugin->deactivate();
|
inputPlugin->deactivate();
|
||||||
|
@ -1445,8 +1445,7 @@ void Application::initializeUi() {
|
||||||
// This will set up the input plugins UI
|
// This will set up the input plugins UI
|
||||||
_activeInputPlugins.clear();
|
_activeInputPlugins.clear();
|
||||||
foreach(auto inputPlugin, PluginManager::getInstance()->getInputPlugins()) {
|
foreach(auto inputPlugin, PluginManager::getInstance()->getInputPlugins()) {
|
||||||
QString name = inputPlugin->getName();
|
if (KeyboardMouseDevice::NAME == inputPlugin->getName()) {
|
||||||
if (name == KeyboardMouseDevice::NAME) {
|
|
||||||
_keyboardMouseDevice = std::dynamic_pointer_cast<KeyboardMouseDevice>(inputPlugin);
|
_keyboardMouseDevice = std::dynamic_pointer_cast<KeyboardMouseDevice>(inputPlugin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1990,7 +1989,7 @@ void Application::keyPressEvent(QKeyEvent* event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasFocus()) {
|
if (hasFocus()) {
|
||||||
if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) {
|
if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) {
|
||||||
_keyboardMouseDevice->keyPressEvent(event);
|
_keyboardMouseDevice->keyPressEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2324,7 +2323,7 @@ void Application::keyReleaseEvent(QKeyEvent* event) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) {
|
if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) {
|
||||||
_keyboardMouseDevice->keyReleaseEvent(event);
|
_keyboardMouseDevice->keyReleaseEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2356,7 +2355,7 @@ void Application::keyReleaseEvent(QKeyEvent* event) {
|
||||||
void Application::focusOutEvent(QFocusEvent* event) {
|
void Application::focusOutEvent(QFocusEvent* event) {
|
||||||
auto inputPlugins = PluginManager::getInstance()->getInputPlugins();
|
auto inputPlugins = PluginManager::getInstance()->getInputPlugins();
|
||||||
foreach(auto inputPlugin, inputPlugins) {
|
foreach(auto inputPlugin, inputPlugins) {
|
||||||
QString name = inputPlugin->getName();
|
QString name = INPUT_DEVICE_MENU_PREFIX + inputPlugin->getName();
|
||||||
QAction* action = Menu::getInstance()->getActionForOption(name);
|
QAction* action = Menu::getInstance()->getActionForOption(name);
|
||||||
if (action && action->isChecked()) {
|
if (action && action->isChecked()) {
|
||||||
inputPlugin->pluginFocusOutEvent();
|
inputPlugin->pluginFocusOutEvent();
|
||||||
|
@ -2443,7 +2442,7 @@ void Application::mouseMoveEvent(QMouseEvent* event) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) {
|
if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) {
|
||||||
_keyboardMouseDevice->mouseMoveEvent(event);
|
_keyboardMouseDevice->mouseMoveEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2480,7 +2479,7 @@ void Application::mousePressEvent(QMouseEvent* event) {
|
||||||
|
|
||||||
|
|
||||||
if (hasFocus()) {
|
if (hasFocus()) {
|
||||||
if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) {
|
if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) {
|
||||||
_keyboardMouseDevice->mousePressEvent(event);
|
_keyboardMouseDevice->mousePressEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2525,7 +2524,7 @@ void Application::mouseReleaseEvent(QMouseEvent* event) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasFocus()) {
|
if (hasFocus()) {
|
||||||
if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) {
|
if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) {
|
||||||
_keyboardMouseDevice->mouseReleaseEvent(event);
|
_keyboardMouseDevice->mouseReleaseEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2552,7 +2551,7 @@ void Application::touchUpdateEvent(QTouchEvent* event) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) {
|
if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) {
|
||||||
_keyboardMouseDevice->touchUpdateEvent(event);
|
_keyboardMouseDevice->touchUpdateEvent(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2570,7 +2569,7 @@ void Application::touchBeginEvent(QTouchEvent* event) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) {
|
if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) {
|
||||||
_keyboardMouseDevice->touchBeginEvent(event);
|
_keyboardMouseDevice->touchBeginEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2587,7 +2586,7 @@ void Application::touchEndEvent(QTouchEvent* event) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) {
|
if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) {
|
||||||
_keyboardMouseDevice->touchEndEvent(event);
|
_keyboardMouseDevice->touchEndEvent(event);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2603,7 +2602,7 @@ void Application::wheelEvent(QWheelEvent* event) const {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) {
|
if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) {
|
||||||
_keyboardMouseDevice->wheelEvent(event);
|
_keyboardMouseDevice->wheelEvent(event);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2735,7 +2734,7 @@ void Application::idle() {
|
||||||
getActiveDisplayPlugin()->idle();
|
getActiveDisplayPlugin()->idle();
|
||||||
auto inputPlugins = PluginManager::getInstance()->getInputPlugins();
|
auto inputPlugins = PluginManager::getInstance()->getInputPlugins();
|
||||||
foreach(auto inputPlugin, inputPlugins) {
|
foreach(auto inputPlugin, inputPlugins) {
|
||||||
QString name = inputPlugin->getName();
|
QString name = INPUT_DEVICE_MENU_PREFIX + inputPlugin->getName();
|
||||||
QAction* action = Menu::getInstance()->getActionForOption(name);
|
QAction* action = Menu::getInstance()->getActionForOption(name);
|
||||||
if (action && action->isChecked()) {
|
if (action && action->isChecked()) {
|
||||||
inputPlugin->idle();
|
inputPlugin->idle();
|
||||||
|
@ -3378,22 +3377,18 @@ void Application::update(float deltaTime) {
|
||||||
};
|
};
|
||||||
|
|
||||||
InputPluginPointer keyboardMousePlugin;
|
InputPluginPointer keyboardMousePlugin;
|
||||||
bool jointsCaptured = false;
|
|
||||||
for (auto inputPlugin : PluginManager::getInstance()->getInputPlugins()) {
|
for (auto inputPlugin : PluginManager::getInstance()->getInputPlugins()) {
|
||||||
if (inputPlugin->getName() == KeyboardMouseDevice::NAME) {
|
if (inputPlugin->getName() == KeyboardMouseDevice::NAME) {
|
||||||
keyboardMousePlugin = inputPlugin;
|
keyboardMousePlugin = inputPlugin;
|
||||||
} else if (inputPlugin->isActive()) {
|
} else if (inputPlugin->isActive()) {
|
||||||
inputPlugin->pluginUpdate(deltaTime, calibrationData, jointsCaptured);
|
inputPlugin->pluginUpdate(deltaTime, calibrationData);
|
||||||
if (inputPlugin->isJointController()) {
|
|
||||||
jointsCaptured = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
userInputMapper->update(deltaTime);
|
userInputMapper->update(deltaTime);
|
||||||
|
|
||||||
if (keyboardMousePlugin && keyboardMousePlugin->isActive()) {
|
if (keyboardMousePlugin && keyboardMousePlugin->isActive()) {
|
||||||
keyboardMousePlugin->pluginUpdate(deltaTime, calibrationData, jointsCaptured);
|
keyboardMousePlugin->pluginUpdate(deltaTime, calibrationData);
|
||||||
}
|
}
|
||||||
|
|
||||||
_controllerScriptingInterface->updateInputControllers();
|
_controllerScriptingInterface->updateInputControllers();
|
||||||
|
@ -5156,21 +5151,23 @@ void Application::updateDisplayMode() {
|
||||||
Q_ASSERT_X(_displayPlugin, "Application::updateDisplayMode", "could not find an activated display plugin");
|
Q_ASSERT_X(_displayPlugin, "Application::updateDisplayMode", "could not find an activated display plugin");
|
||||||
}
|
}
|
||||||
|
|
||||||
static void addInputPluginToMenu(InputPluginPointer inputPlugin, bool active = false) {
|
static void addInputPluginToMenu(InputPluginPointer inputPlugin) {
|
||||||
auto menu = Menu::getInstance();
|
auto menu = Menu::getInstance();
|
||||||
QString name = inputPlugin->getName();
|
QString name = INPUT_DEVICE_MENU_PREFIX + inputPlugin->getName();
|
||||||
Q_ASSERT(!menu->menuItemExists(MenuOption::InputMenu, name));
|
Q_ASSERT(!menu->menuItemExists(MenuOption::InputMenu, name));
|
||||||
|
|
||||||
static QActionGroup* inputPluginGroup = nullptr;
|
static QActionGroup* inputPluginGroup = nullptr;
|
||||||
if (!inputPluginGroup) {
|
if (!inputPluginGroup) {
|
||||||
inputPluginGroup = new QActionGroup(menu);
|
inputPluginGroup = new QActionGroup(menu);
|
||||||
|
inputPluginGroup->setExclusive(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto parent = menu->getMenu(MenuOption::InputMenu);
|
auto parent = menu->getMenu(MenuOption::InputMenu);
|
||||||
auto action = menu->addCheckableActionToQMenuAndActionHash(parent,
|
auto action = menu->addCheckableActionToQMenuAndActionHash(parent,
|
||||||
name, 0, active, qApp,
|
name, 0, true, qApp,
|
||||||
SLOT(updateInputModes()));
|
SLOT(updateInputModes()));
|
||||||
|
|
||||||
inputPluginGroup->addAction(action);
|
inputPluginGroup->addAction(action);
|
||||||
inputPluginGroup->setExclusive(false);
|
|
||||||
Q_ASSERT(menu->menuItemExists(MenuOption::InputMenu, name));
|
Q_ASSERT(menu->menuItemExists(MenuOption::InputMenu, name));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5180,10 +5177,8 @@ void Application::updateInputModes() {
|
||||||
auto inputPlugins = PluginManager::getInstance()->getInputPlugins();
|
auto inputPlugins = PluginManager::getInstance()->getInputPlugins();
|
||||||
static std::once_flag once;
|
static std::once_flag once;
|
||||||
std::call_once(once, [&] {
|
std::call_once(once, [&] {
|
||||||
bool first = true;
|
|
||||||
foreach(auto inputPlugin, inputPlugins) {
|
foreach(auto inputPlugin, inputPlugins) {
|
||||||
addInputPluginToMenu(inputPlugin, first);
|
addInputPluginToMenu(inputPlugin);
|
||||||
first = false;
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
auto offscreenUi = DependencyManager::get<OffscreenUi>();
|
||||||
|
@ -5191,7 +5186,7 @@ void Application::updateInputModes() {
|
||||||
InputPluginList newInputPlugins;
|
InputPluginList newInputPlugins;
|
||||||
InputPluginList removedInputPlugins;
|
InputPluginList removedInputPlugins;
|
||||||
foreach(auto inputPlugin, inputPlugins) {
|
foreach(auto inputPlugin, inputPlugins) {
|
||||||
QString name = inputPlugin->getName();
|
QString name = INPUT_DEVICE_MENU_PREFIX + inputPlugin->getName();
|
||||||
QAction* action = menu->getActionForOption(name);
|
QAction* action = menu->getActionForOption(name);
|
||||||
|
|
||||||
auto it = std::find(std::begin(_activeInputPlugins), std::end(_activeInputPlugins), inputPlugin);
|
auto it = std::find(std::begin(_activeInputPlugins), std::end(_activeInputPlugins), inputPlugin);
|
||||||
|
|
|
@ -34,7 +34,6 @@
|
||||||
#include "avatar/AvatarManager.h"
|
#include "avatar/AvatarManager.h"
|
||||||
#include "devices/DdeFaceTracker.h"
|
#include "devices/DdeFaceTracker.h"
|
||||||
#include "devices/Faceshift.h"
|
#include "devices/Faceshift.h"
|
||||||
#include "input-plugins/SpacemouseManager.h"
|
|
||||||
#include "MainWindow.h"
|
#include "MainWindow.h"
|
||||||
#include "render/DrawStatus.h"
|
#include "render/DrawStatus.h"
|
||||||
#include "scripting/MenuScriptingInterface.h"
|
#include "scripting/MenuScriptingInterface.h"
|
||||||
|
@ -327,12 +326,6 @@ Menu::Menu() {
|
||||||
connect(speechRecognizer.data(), SIGNAL(enabledUpdated(bool)), speechRecognizerAction, SLOT(setChecked(bool)));
|
connect(speechRecognizer.data(), SIGNAL(enabledUpdated(bool)), speechRecognizerAction, SLOT(setChecked(bool)));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Settings > Input Devices
|
|
||||||
MenuWrapper* inputModeMenu = addMenu(MenuOption::InputMenu, "Advanced");
|
|
||||||
QActionGroup* inputModeGroup = new QActionGroup(inputModeMenu);
|
|
||||||
inputModeGroup->setExclusive(false);
|
|
||||||
|
|
||||||
|
|
||||||
// Developer menu ----------------------------------
|
// Developer menu ----------------------------------
|
||||||
MenuWrapper* developerMenu = addMenu("Developer", "Developer");
|
MenuWrapper* developerMenu = addMenu("Developer", "Developer");
|
||||||
|
|
||||||
|
@ -410,6 +403,12 @@ Menu::Menu() {
|
||||||
// Developer > Avatar >>>
|
// Developer > Avatar >>>
|
||||||
MenuWrapper* avatarDebugMenu = developerMenu->addMenu("Avatar");
|
MenuWrapper* avatarDebugMenu = developerMenu->addMenu("Avatar");
|
||||||
|
|
||||||
|
// Settings > Input Devices
|
||||||
|
MenuWrapper* inputModeMenu = addMenu(MenuOption::InputMenu, "Advanced");
|
||||||
|
QActionGroup* inputModeGroup = new QActionGroup(inputModeMenu);
|
||||||
|
inputModeGroup->setExclusive(false);
|
||||||
|
|
||||||
|
|
||||||
// Developer > Avatar > Face Tracking
|
// Developer > Avatar > Face Tracking
|
||||||
MenuWrapper* faceTrackingMenu = avatarDebugMenu->addMenu("Face Tracking");
|
MenuWrapper* faceTrackingMenu = avatarDebugMenu->addMenu("Face Tracking");
|
||||||
{
|
{
|
||||||
|
|
|
@ -114,7 +114,7 @@ namespace MenuOption {
|
||||||
const QString Help = "Help...";
|
const QString Help = "Help...";
|
||||||
const QString IncreaseAvatarSize = "Increase Avatar Size";
|
const QString IncreaseAvatarSize = "Increase Avatar Size";
|
||||||
const QString IndependentMode = "Independent Mode";
|
const QString IndependentMode = "Independent Mode";
|
||||||
const QString InputMenu = "Avatar>Input Devices";
|
const QString InputMenu = "Developer>Avatar>Input Devices";
|
||||||
const QString ActionMotorControl = "Enable Default Motor Control";
|
const QString ActionMotorControl = "Enable Default Motor Control";
|
||||||
const QString LeapMotionOnHMD = "Leap Motion on HMD";
|
const QString LeapMotionOnHMD = "Leap Motion on HMD";
|
||||||
const QString LoadScript = "Open and Run Script File...";
|
const QString LoadScript = "Open and Run Script File...";
|
||||||
|
|
|
@ -428,7 +428,14 @@ void MyAvatar::simulate(float deltaTime) {
|
||||||
EntityTreeRenderer* entityTreeRenderer = qApp->getEntities();
|
EntityTreeRenderer* entityTreeRenderer = qApp->getEntities();
|
||||||
EntityTreePointer entityTree = entityTreeRenderer ? entityTreeRenderer->getTree() : nullptr;
|
EntityTreePointer entityTree = entityTreeRenderer ? entityTreeRenderer->getTree() : nullptr;
|
||||||
if (entityTree) {
|
if (entityTree) {
|
||||||
|
bool flyingAllowed = true;
|
||||||
|
bool ghostingAllowed = true;
|
||||||
entityTree->withWriteLock([&] {
|
entityTree->withWriteLock([&] {
|
||||||
|
std::shared_ptr<ZoneEntityItem> zone = entityTreeRenderer->myAvatarZone();
|
||||||
|
if (zone) {
|
||||||
|
flyingAllowed = zone->getFlyingAllowed();
|
||||||
|
ghostingAllowed = zone->getGhostingAllowed();
|
||||||
|
}
|
||||||
auto now = usecTimestampNow();
|
auto now = usecTimestampNow();
|
||||||
EntityEditPacketSender* packetSender = qApp->getEntityEditPacketSender();
|
EntityEditPacketSender* packetSender = qApp->getEntityEditPacketSender();
|
||||||
MovingEntitiesOperator moveOperator(entityTree);
|
MovingEntitiesOperator moveOperator(entityTree);
|
||||||
|
@ -457,6 +464,10 @@ void MyAvatar::simulate(float deltaTime) {
|
||||||
entityTree->recurseTreeWithOperator(&moveOperator);
|
entityTree->recurseTreeWithOperator(&moveOperator);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
_characterController.setFlyingAllowed(flyingAllowed);
|
||||||
|
if (!_characterController.isEnabled() && !ghostingAllowed) {
|
||||||
|
_characterController.setEnabled(true);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
updateAvatarEntities();
|
updateAvatarEntities();
|
||||||
|
@ -1816,7 +1827,21 @@ void MyAvatar::updateMotionBehaviorFromMenu() {
|
||||||
} else {
|
} else {
|
||||||
_motionBehaviors &= ~AVATAR_MOTION_SCRIPTED_MOTOR_ENABLED;
|
_motionBehaviors &= ~AVATAR_MOTION_SCRIPTED_MOTOR_ENABLED;
|
||||||
}
|
}
|
||||||
_characterController.setEnabled(menu->isOptionChecked(MenuOption::EnableCharacterController));
|
|
||||||
|
bool ghostingAllowed = true;
|
||||||
|
EntityTreeRenderer* entityTreeRenderer = qApp->getEntities();
|
||||||
|
if (entityTreeRenderer) {
|
||||||
|
std::shared_ptr<ZoneEntityItem> zone = entityTreeRenderer->myAvatarZone();
|
||||||
|
if (zone) {
|
||||||
|
ghostingAllowed = zone->getGhostingAllowed();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
bool checked = menu->isOptionChecked(MenuOption::EnableCharacterController);
|
||||||
|
if (!ghostingAllowed) {
|
||||||
|
checked = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
_characterController.setEnabled(checked);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MyAvatar::clearDriveKeys() {
|
void MyAvatar::clearDriveKeys() {
|
||||||
|
|
|
@ -121,16 +121,8 @@ namespace controller {
|
||||||
return availableInputs;
|
return availableInputs;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ActionsDevice::update(float deltaTime, const InputCalibrationData& inpuCalibrationData, bool jointsCaptured) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void ActionsDevice::focusOutEvent() {
|
|
||||||
}
|
|
||||||
|
|
||||||
ActionsDevice::ActionsDevice() : InputDevice("Actions") {
|
ActionsDevice::ActionsDevice() : InputDevice("Actions") {
|
||||||
_deviceID = UserInputMapper::ACTIONS_DEVICE;
|
_deviceID = UserInputMapper::ACTIONS_DEVICE;
|
||||||
}
|
}
|
||||||
|
|
||||||
ActionsDevice::~ActionsDevice() {}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -109,13 +109,11 @@ class ActionsDevice : public QObject, public InputDevice {
|
||||||
Q_PROPERTY(QString name READ getName)
|
Q_PROPERTY(QString name READ getName)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual EndpointPointer createEndpoint(const Input& input) const override;
|
|
||||||
virtual Input::NamedVector getAvailableInputs() const override;
|
|
||||||
virtual void update(float deltaTime, const InputCalibrationData& inputCalibrationData, bool jointsCaptured) override;
|
|
||||||
virtual void focusOutEvent() override;
|
|
||||||
|
|
||||||
ActionsDevice();
|
ActionsDevice();
|
||||||
virtual ~ActionsDevice();
|
|
||||||
|
EndpointPointer createEndpoint(const Input& input) const override;
|
||||||
|
Input::NamedVector getAvailableInputs() const override;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,9 +57,9 @@ public:
|
||||||
|
|
||||||
// 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, const InputCalibrationData& inputCalibrationData, bool jointsCaptured) = 0;
|
virtual void update(float deltaTime, const InputCalibrationData& inputCalibrationData) {};
|
||||||
|
|
||||||
virtual void focusOutEvent() = 0;
|
virtual void focusOutEvent() {};
|
||||||
|
|
||||||
int getDeviceID() { return _deviceID; }
|
int getDeviceID() { return _deviceID; }
|
||||||
void setDeviceID(int deviceID) { _deviceID = deviceID; }
|
void setDeviceID(int deviceID) { _deviceID = deviceID; }
|
||||||
|
|
|
@ -22,12 +22,6 @@ StandardController::StandardController() : InputDevice("Standard") {
|
||||||
_deviceID = UserInputMapper::STANDARD_DEVICE;
|
_deviceID = UserInputMapper::STANDARD_DEVICE;
|
||||||
}
|
}
|
||||||
|
|
||||||
StandardController::~StandardController() {
|
|
||||||
}
|
|
||||||
|
|
||||||
void StandardController::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void StandardController::focusOutEvent() {
|
void StandardController::focusOutEvent() {
|
||||||
_axisStateMap.clear();
|
_axisStateMap.clear();
|
||||||
_buttonPressedMap.clear();
|
_buttonPressedMap.clear();
|
||||||
|
|
|
@ -28,11 +28,9 @@ 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, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override;
|
|
||||||
virtual void focusOutEvent() override;
|
virtual void focusOutEvent() override;
|
||||||
|
|
||||||
StandardController();
|
StandardController();
|
||||||
virtual ~StandardController();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,10 +35,7 @@ public:
|
||||||
const QString& getName() const { return _name; }
|
const QString& getName() const { return _name; }
|
||||||
|
|
||||||
// Device functions
|
// Device functions
|
||||||
virtual Input::NamedVector getAvailableInputs() const override;
|
Input::NamedVector getAvailableInputs() const override;
|
||||||
|
|
||||||
void update(float deltaTime, const InputCalibrationData& inputCalibrationData, bool jointsCaptured) override {}
|
|
||||||
void focusOutEvent() override {}
|
|
||||||
|
|
||||||
void setInputVariant(const QString& name, ReadLambda lambda);
|
void setInputVariant(const QString& name, ReadLambda lambda);
|
||||||
|
|
||||||
|
|
|
@ -88,6 +88,8 @@ public:
|
||||||
// For Scene.shouldRenderEntities
|
// For Scene.shouldRenderEntities
|
||||||
QList<EntityItemID>& getEntitiesLastInScene() { return _entityIDsLastInScene; }
|
QList<EntityItemID>& getEntitiesLastInScene() { return _entityIDsLastInScene; }
|
||||||
|
|
||||||
|
std::shared_ptr<ZoneEntityItem> myAvatarZone() { return _bestZone; }
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void mousePressOnEntity(const RayToEntityIntersectionResult& intersection, const QMouseEvent* event);
|
void mousePressOnEntity(const RayToEntityIntersectionResult& intersection, const QMouseEvent* event);
|
||||||
void mousePressOffEntity(const RayToEntityIntersectionResult& intersection, const QMouseEvent* event);
|
void mousePressOffEntity(const RayToEntityIntersectionResult& intersection, const QMouseEvent* event);
|
||||||
|
|
|
@ -307,6 +307,10 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const {
|
||||||
CHECK_PROPERTY_CHANGE(PROP_QUERY_AA_CUBE, queryAACube);
|
CHECK_PROPERTY_CHANGE(PROP_QUERY_AA_CUBE, queryAACube);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_LOCAL_POSITION, localPosition);
|
CHECK_PROPERTY_CHANGE(PROP_LOCAL_POSITION, localPosition);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_LOCAL_ROTATION, localRotation);
|
CHECK_PROPERTY_CHANGE(PROP_LOCAL_ROTATION, localRotation);
|
||||||
|
|
||||||
|
CHECK_PROPERTY_CHANGE(PROP_FLYING_ALLOWED, flyingAllowed);
|
||||||
|
CHECK_PROPERTY_CHANGE(PROP_GHOSTING_ALLOWED, ghostingAllowed);
|
||||||
|
|
||||||
CHECK_PROPERTY_CHANGE(PROP_CLIENT_ONLY, clientOnly);
|
CHECK_PROPERTY_CHANGE(PROP_CLIENT_ONLY, clientOnly);
|
||||||
CHECK_PROPERTY_CHANGE(PROP_OWNING_AVATAR_ID, owningAvatarID);
|
CHECK_PROPERTY_CHANGE(PROP_OWNING_AVATAR_ID, owningAvatarID);
|
||||||
|
|
||||||
|
@ -467,6 +471,9 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool
|
||||||
|
|
||||||
_stage.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
_stage.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
||||||
_skybox.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
_skybox.copyToScriptValue(_desiredProperties, properties, engine, skipDefaults, defaultEntityProperties);
|
||||||
|
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_FLYING_ALLOWED, flyingAllowed);
|
||||||
|
COPY_PROPERTY_TO_QSCRIPTVALUE(PROP_GHOSTING_ALLOWED, ghostingAllowed);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Web only
|
// Web only
|
||||||
|
@ -683,8 +690,13 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(jointTranslationsSet, qVectorBool, setJointTranslationsSet);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(jointTranslationsSet, qVectorBool, setJointTranslationsSet);
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(jointTranslations, qVectorVec3, setJointTranslations);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(jointTranslations, qVectorVec3, setJointTranslations);
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(clientOnly, bool, setClientOnly);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(clientOnly, bool, setClientOnly);
|
||||||
COPY_PROPERTY_FROM_QSCRIPTVALUE(owningAvatarID, QUuid, setOwningAvatarID);
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(owningAvatarID, QUuid, setOwningAvatarID);
|
||||||
|
=======
|
||||||
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(flyingAllowed, bool, setFlyingAllowed);
|
||||||
|
COPY_PROPERTY_FROM_QSCRIPTVALUE(ghostingAllowed, bool, setGhostingAllowed);
|
||||||
|
>>>>>>> e012630db23d8aba81fae0721f69322220b21be2
|
||||||
|
|
||||||
_lastEdited = usecTimestampNow();
|
_lastEdited = usecTimestampNow();
|
||||||
}
|
}
|
||||||
|
@ -856,6 +868,9 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue
|
||||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_STAGE_HOUR, Stage, stage, Hour, hour);
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_STAGE_HOUR, Stage, stage, Hour, hour);
|
||||||
ADD_GROUP_PROPERTY_TO_MAP(PROP_STAGE_AUTOMATIC_HOURDAY, Stage, stage, AutomaticHourDay, automaticHourDay);
|
ADD_GROUP_PROPERTY_TO_MAP(PROP_STAGE_AUTOMATIC_HOURDAY, Stage, stage, AutomaticHourDay, automaticHourDay);
|
||||||
|
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_FLYING_ALLOWED, FlyingAllowed, flyingAllowed, bool);
|
||||||
|
ADD_PROPERTY_TO_MAP(PROP_GHOSTING_ALLOWED, GhostingAllowed, ghostingAllowed, bool);
|
||||||
|
|
||||||
// FIXME - these are not yet handled
|
// FIXME - these are not yet handled
|
||||||
//ADD_PROPERTY_TO_MAP(PROP_CREATED, Created, created, quint64);
|
//ADD_PROPERTY_TO_MAP(PROP_CREATED, Created, created, quint64);
|
||||||
|
|
||||||
|
@ -1096,6 +1111,9 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem
|
||||||
|
|
||||||
_staticSkybox.setProperties(properties);
|
_staticSkybox.setProperties(properties);
|
||||||
_staticSkybox.appendToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState);
|
_staticSkybox.appendToEditPacket(packetData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState);
|
||||||
|
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_FLYING_ALLOWED, properties.getFlyingAllowed());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_GHOSTING_ALLOWED, properties.getGhostingAllowed());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (properties.getType() == EntityTypes::PolyVox) {
|
if (properties.getType() == EntityTypes::PolyVox) {
|
||||||
|
@ -1380,6 +1398,9 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COMPOUND_SHAPE_URL, QString, setCompoundShapeURL);
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_COMPOUND_SHAPE_URL, QString, setCompoundShapeURL);
|
||||||
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_BACKGROUND_MODE, BackgroundMode, setBackgroundMode);
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_BACKGROUND_MODE, BackgroundMode, setBackgroundMode);
|
||||||
properties.getSkybox().decodeFromEditPacket(propertyFlags, dataAt , processedBytes);
|
properties.getSkybox().decodeFromEditPacket(propertyFlags, dataAt , processedBytes);
|
||||||
|
|
||||||
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_FLYING_ALLOWED, bool, setFlyingAllowed);
|
||||||
|
READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_GHOSTING_ALLOWED, bool, setGhostingAllowed);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (properties.getType() == EntityTypes::PolyVox) {
|
if (properties.getType() == EntityTypes::PolyVox) {
|
||||||
|
@ -1571,8 +1592,13 @@ void EntityItemProperties::markAllChanged() {
|
||||||
|
|
||||||
_queryAACubeChanged = true;
|
_queryAACubeChanged = true;
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
_clientOnlyChanged = true;
|
_clientOnlyChanged = true;
|
||||||
_owningAvatarIDChanged = true;
|
_owningAvatarIDChanged = true;
|
||||||
|
=======
|
||||||
|
_flyingAllowedChanged = true;
|
||||||
|
_ghostingAllowedChanged = true;
|
||||||
|
>>>>>>> e012630db23d8aba81fae0721f69322220b21be2
|
||||||
}
|
}
|
||||||
|
|
||||||
// The minimum bounding box for the entity.
|
// The minimum bounding box for the entity.
|
||||||
|
@ -1900,6 +1926,13 @@ QList<QString> EntityItemProperties::listChangedProperties() {
|
||||||
out += "owningAvatarID";
|
out += "owningAvatarID";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (flyingAllowedChanged()) {
|
||||||
|
out += "flyingAllowed";
|
||||||
|
}
|
||||||
|
if (ghostingAllowedChanged()) {
|
||||||
|
out += "ghostingAllowed";
|
||||||
|
}
|
||||||
|
|
||||||
getAnimation().listChangedProperties(out);
|
getAnimation().listChangedProperties(out);
|
||||||
getKeyLight().listChangedProperties(out);
|
getKeyLight().listChangedProperties(out);
|
||||||
getSkybox().listChangedProperties(out);
|
getSkybox().listChangedProperties(out);
|
||||||
|
|
|
@ -205,6 +205,9 @@ public:
|
||||||
DEFINE_PROPERTY_REF(PROP_JOINT_TRANSLATIONS_SET, JointTranslationsSet, jointTranslationsSet, QVector<bool>, QVector<bool>());
|
DEFINE_PROPERTY_REF(PROP_JOINT_TRANSLATIONS_SET, JointTranslationsSet, jointTranslationsSet, QVector<bool>, QVector<bool>());
|
||||||
DEFINE_PROPERTY_REF(PROP_JOINT_TRANSLATIONS, JointTranslations, jointTranslations, QVector<glm::vec3>, QVector<glm::vec3>());
|
DEFINE_PROPERTY_REF(PROP_JOINT_TRANSLATIONS, JointTranslations, jointTranslations, QVector<glm::vec3>, QVector<glm::vec3>());
|
||||||
|
|
||||||
|
DEFINE_PROPERTY(PROP_FLYING_ALLOWED, FlyingAllowed, flyingAllowed, bool, ZoneEntityItem::DEFAULT_FLYING_ALLOWED);
|
||||||
|
DEFINE_PROPERTY(PROP_GHOSTING_ALLOWED, GhostingAllowed, ghostingAllowed, bool, ZoneEntityItem::DEFAULT_GHOSTING_ALLOWED);
|
||||||
|
|
||||||
DEFINE_PROPERTY(PROP_CLIENT_ONLY, ClientOnly, clientOnly, bool, false);
|
DEFINE_PROPERTY(PROP_CLIENT_ONLY, ClientOnly, clientOnly, bool, false);
|
||||||
DEFINE_PROPERTY_REF(PROP_OWNING_AVATAR_ID, OwningAvatarID, owningAvatarID, QUuid, UNKNOWN_ENTITY_ID);
|
DEFINE_PROPERTY_REF(PROP_OWNING_AVATAR_ID, OwningAvatarID, owningAvatarID, QUuid, UNKNOWN_ENTITY_ID);
|
||||||
|
|
||||||
|
@ -419,6 +422,9 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) {
|
||||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, JointTranslationsSet, jointTranslationsSet, "");
|
DEBUG_PROPERTY_IF_CHANGED(debug, properties, JointTranslationsSet, jointTranslationsSet, "");
|
||||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, JointTranslations, jointTranslations, "");
|
DEBUG_PROPERTY_IF_CHANGED(debug, properties, JointTranslations, jointTranslations, "");
|
||||||
|
|
||||||
|
DEBUG_PROPERTY_IF_CHANGED(debug, properties, FlyingAllowed, flyingAllowed, "");
|
||||||
|
DEBUG_PROPERTY_IF_CHANGED(debug, properties, GhostingAllowed, ghostingAllowed, "");
|
||||||
|
|
||||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, ClientOnly, clientOnly, "");
|
DEBUG_PROPERTY_IF_CHANGED(debug, properties, ClientOnly, clientOnly, "");
|
||||||
DEBUG_PROPERTY_IF_CHANGED(debug, properties, OwningAvatarID, owningAvatarID, "");
|
DEBUG_PROPERTY_IF_CHANGED(debug, properties, OwningAvatarID, owningAvatarID, "");
|
||||||
|
|
||||||
|
|
|
@ -169,6 +169,9 @@ enum EntityPropertyList {
|
||||||
|
|
||||||
PROP_FALLOFF_RADIUS, // for Light entity
|
PROP_FALLOFF_RADIUS, // for Light entity
|
||||||
|
|
||||||
|
PROP_FLYING_ALLOWED, // can avatars in a zone fly?
|
||||||
|
PROP_GHOSTING_ALLOWED, // can avatars in a zone turn off physics?
|
||||||
|
|
||||||
PROP_CLIENT_ONLY, // doesn't go over wire
|
PROP_CLIENT_ONLY, // doesn't go over wire
|
||||||
PROP_OWNING_AVATAR_ID, // doesn't go over wire
|
PROP_OWNING_AVATAR_ID, // doesn't go over wire
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,12 @@
|
||||||
bool ZoneEntityItem::_zonesArePickable = false;
|
bool ZoneEntityItem::_zonesArePickable = false;
|
||||||
bool ZoneEntityItem::_drawZoneBoundaries = false;
|
bool ZoneEntityItem::_drawZoneBoundaries = false;
|
||||||
|
|
||||||
|
|
||||||
const ShapeType ZoneEntityItem::DEFAULT_SHAPE_TYPE = SHAPE_TYPE_BOX;
|
const ShapeType ZoneEntityItem::DEFAULT_SHAPE_TYPE = SHAPE_TYPE_BOX;
|
||||||
const QString ZoneEntityItem::DEFAULT_COMPOUND_SHAPE_URL = "";
|
const QString ZoneEntityItem::DEFAULT_COMPOUND_SHAPE_URL = "";
|
||||||
|
const bool ZoneEntityItem::DEFAULT_FLYING_ALLOWED = true;
|
||||||
|
const bool ZoneEntityItem::DEFAULT_GHOSTING_ALLOWED = true;
|
||||||
|
|
||||||
|
|
||||||
EntityItemPointer ZoneEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
EntityItemPointer ZoneEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||||
EntityItemPointer entity { new ZoneEntityItem(entityID) };
|
EntityItemPointer entity { new ZoneEntityItem(entityID) };
|
||||||
|
@ -55,6 +59,9 @@ EntityItemProperties ZoneEntityItem::getProperties(EntityPropertyFlags desiredPr
|
||||||
|
|
||||||
_skyboxProperties.getProperties(properties);
|
_skyboxProperties.getProperties(properties);
|
||||||
|
|
||||||
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(flyingAllowed, getFlyingAllowed);
|
||||||
|
COPY_ENTITY_PROPERTY_TO_PROPERTIES(ghostingAllowed, getGhostingAllowed);
|
||||||
|
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,6 +77,9 @@ bool ZoneEntityItem::setProperties(const EntityItemProperties& properties) {
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(compoundShapeURL, setCompoundShapeURL);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(compoundShapeURL, setCompoundShapeURL);
|
||||||
SET_ENTITY_PROPERTY_FROM_PROPERTIES(backgroundMode, setBackgroundMode);
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(backgroundMode, setBackgroundMode);
|
||||||
|
|
||||||
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(flyingAllowed, setFlyingAllowed);
|
||||||
|
SET_ENTITY_PROPERTY_FROM_PROPERTIES(ghostingAllowed, setGhostingAllowed);
|
||||||
|
|
||||||
bool somethingChangedInSkybox = _skyboxProperties.setProperties(properties);
|
bool somethingChangedInSkybox = _skyboxProperties.setProperties(properties);
|
||||||
|
|
||||||
somethingChanged = somethingChanged || somethingChangedInKeyLight || somethingChangedInStage || somethingChangedInSkybox;
|
somethingChanged = somethingChanged || somethingChangedInKeyLight || somethingChangedInStage || somethingChangedInSkybox;
|
||||||
|
@ -116,6 +126,9 @@ int ZoneEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data,
|
||||||
bytesRead += bytesFromSkybox;
|
bytesRead += bytesFromSkybox;
|
||||||
dataAt += bytesFromSkybox;
|
dataAt += bytesFromSkybox;
|
||||||
|
|
||||||
|
READ_ENTITY_PROPERTY(PROP_FLYING_ALLOWED, bool, setFlyingAllowed);
|
||||||
|
READ_ENTITY_PROPERTY(PROP_GHOSTING_ALLOWED, bool, setGhostingAllowed);
|
||||||
|
|
||||||
return bytesRead;
|
return bytesRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -125,13 +138,16 @@ EntityPropertyFlags ZoneEntityItem::getEntityProperties(EncodeBitstreamParams& p
|
||||||
EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params);
|
EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params);
|
||||||
|
|
||||||
requestedProperties += _keyLightProperties.getEntityProperties(params);
|
requestedProperties += _keyLightProperties.getEntityProperties(params);
|
||||||
|
|
||||||
requestedProperties += PROP_SHAPE_TYPE;
|
requestedProperties += PROP_SHAPE_TYPE;
|
||||||
requestedProperties += PROP_COMPOUND_SHAPE_URL;
|
requestedProperties += PROP_COMPOUND_SHAPE_URL;
|
||||||
requestedProperties += PROP_BACKGROUND_MODE;
|
requestedProperties += PROP_BACKGROUND_MODE;
|
||||||
requestedProperties += _stageProperties.getEntityProperties(params);
|
requestedProperties += _stageProperties.getEntityProperties(params);
|
||||||
requestedProperties += _skyboxProperties.getEntityProperties(params);
|
requestedProperties += _skyboxProperties.getEntityProperties(params);
|
||||||
|
|
||||||
|
requestedProperties += PROP_FLYING_ALLOWED;
|
||||||
|
requestedProperties += PROP_GHOSTING_ALLOWED;
|
||||||
|
|
||||||
return requestedProperties;
|
return requestedProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,10 +171,12 @@ void ZoneEntityItem::appendSubclassData(OctreePacketData* packetData, EncodeBits
|
||||||
APPEND_ENTITY_PROPERTY(PROP_SHAPE_TYPE, (uint32_t)getShapeType());
|
APPEND_ENTITY_PROPERTY(PROP_SHAPE_TYPE, (uint32_t)getShapeType());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, getCompoundShapeURL());
|
APPEND_ENTITY_PROPERTY(PROP_COMPOUND_SHAPE_URL, getCompoundShapeURL());
|
||||||
APPEND_ENTITY_PROPERTY(PROP_BACKGROUND_MODE, (uint32_t)getBackgroundMode()); // could this be a uint16??
|
APPEND_ENTITY_PROPERTY(PROP_BACKGROUND_MODE, (uint32_t)getBackgroundMode()); // could this be a uint16??
|
||||||
|
|
||||||
_skyboxProperties.appendSubclassData(packetData, params, modelTreeElementExtraEncodeData, requestedProperties,
|
_skyboxProperties.appendSubclassData(packetData, params, modelTreeElementExtraEncodeData, requestedProperties,
|
||||||
propertyFlags, propertiesDidntFit, propertyCount, appendState);
|
propertyFlags, propertiesDidntFit, propertyCount, appendState);
|
||||||
|
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_FLYING_ALLOWED, getFlyingAllowed());
|
||||||
|
APPEND_ENTITY_PROPERTY(PROP_GHOSTING_ALLOWED, getGhostingAllowed());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ZoneEntityItem::debugDump() const {
|
void ZoneEntityItem::debugDump() const {
|
||||||
|
|
|
@ -70,6 +70,11 @@ public:
|
||||||
const SkyboxPropertyGroup& getSkyboxProperties() const { return _skyboxProperties; }
|
const SkyboxPropertyGroup& getSkyboxProperties() const { return _skyboxProperties; }
|
||||||
const StagePropertyGroup& getStageProperties() const { return _stageProperties; }
|
const StagePropertyGroup& getStageProperties() const { return _stageProperties; }
|
||||||
|
|
||||||
|
bool getFlyingAllowed() const { return _flyingAllowed; }
|
||||||
|
void setFlyingAllowed(bool value) { _flyingAllowed = value; }
|
||||||
|
bool getGhostingAllowed() const { return _ghostingAllowed; }
|
||||||
|
void setGhostingAllowed(bool value) { _ghostingAllowed = value; }
|
||||||
|
|
||||||
virtual bool supportsDetailedRayIntersection() const { return true; }
|
virtual bool supportsDetailedRayIntersection() const { return true; }
|
||||||
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
virtual bool findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction,
|
||||||
bool& keepSearching, OctreeElementPointer& element, float& distance,
|
bool& keepSearching, OctreeElementPointer& element, float& distance,
|
||||||
|
@ -80,18 +85,23 @@ public:
|
||||||
|
|
||||||
static const ShapeType DEFAULT_SHAPE_TYPE;
|
static const ShapeType DEFAULT_SHAPE_TYPE;
|
||||||
static const QString DEFAULT_COMPOUND_SHAPE_URL;
|
static const QString DEFAULT_COMPOUND_SHAPE_URL;
|
||||||
|
static const bool DEFAULT_FLYING_ALLOWED;
|
||||||
|
static const bool DEFAULT_GHOSTING_ALLOWED;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
KeyLightPropertyGroup _keyLightProperties;
|
KeyLightPropertyGroup _keyLightProperties;
|
||||||
|
|
||||||
ShapeType _shapeType = DEFAULT_SHAPE_TYPE;
|
ShapeType _shapeType = DEFAULT_SHAPE_TYPE;
|
||||||
QString _compoundShapeURL;
|
QString _compoundShapeURL;
|
||||||
|
|
||||||
BackgroundMode _backgroundMode = BACKGROUND_MODE_INHERIT;
|
BackgroundMode _backgroundMode = BACKGROUND_MODE_INHERIT;
|
||||||
|
|
||||||
StagePropertyGroup _stageProperties;
|
StagePropertyGroup _stageProperties;
|
||||||
SkyboxPropertyGroup _skyboxProperties;
|
SkyboxPropertyGroup _skyboxProperties;
|
||||||
|
|
||||||
|
bool _flyingAllowed { DEFAULT_FLYING_ALLOWED };
|
||||||
|
bool _ghostingAllowed { DEFAULT_GHOSTING_ALLOWED };
|
||||||
|
|
||||||
static bool _drawZoneBoundaries;
|
static bool _drawZoneBoundaries;
|
||||||
static bool _zonesArePickable;
|
static bool _zonesArePickable;
|
||||||
};
|
};
|
||||||
|
|
|
@ -25,7 +25,7 @@ public:
|
||||||
glBufferData(GL_ARRAY_BUFFER, _size, nullptr, GL_DYNAMIC_DRAW);
|
glBufferData(GL_ARRAY_BUFFER, _size, nullptr, GL_DYNAMIC_DRAW);
|
||||||
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
glBindBuffer(GL_ARRAY_BUFFER, 0);
|
||||||
|
|
||||||
if (original) {
|
if (original && original->_size) {
|
||||||
glBindBuffer(GL_COPY_WRITE_BUFFER, _buffer);
|
glBindBuffer(GL_COPY_WRITE_BUFFER, _buffer);
|
||||||
glBindBuffer(GL_COPY_READ_BUFFER, original->_buffer);
|
glBindBuffer(GL_COPY_READ_BUFFER, original->_buffer);
|
||||||
glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, original->_size);
|
glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, original->_size);
|
||||||
|
|
|
@ -20,11 +20,10 @@
|
||||||
|
|
||||||
const QString KeyboardMouseDevice::NAME = "Keyboard/Mouse";
|
const QString KeyboardMouseDevice::NAME = "Keyboard/Mouse";
|
||||||
|
|
||||||
void KeyboardMouseDevice::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) {
|
void KeyboardMouseDevice::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) {
|
||||||
|
|
||||||
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
||||||
userInputMapper->withLock([&, this]() {
|
userInputMapper->withLock([&, this]() {
|
||||||
_inputDevice->update(deltaTime, inputCalibrationData, jointsCaptured);
|
_inputDevice->update(deltaTime, inputCalibrationData);
|
||||||
});
|
});
|
||||||
|
|
||||||
// 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
|
||||||
|
@ -40,7 +39,7 @@ void KeyboardMouseDevice::pluginUpdate(float deltaTime, const controller::InputC
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void KeyboardMouseDevice::InputDevice::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) {
|
void KeyboardMouseDevice::InputDevice::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) {
|
||||||
_axisStateMap.clear();
|
_axisStateMap.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -65,12 +65,11 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
// Plugin functions
|
// Plugin functions
|
||||||
virtual bool isSupported() const override { return true; }
|
bool isSupported() const override { return true; }
|
||||||
virtual bool isJointController() const override { return false; }
|
const QString& getName() const override { return NAME; }
|
||||||
virtual const QString& getName() const override { return NAME; }
|
|
||||||
|
|
||||||
virtual void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); }
|
void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); }
|
||||||
virtual void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override;
|
void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override;
|
||||||
|
|
||||||
void keyPressEvent(QKeyEvent* event);
|
void keyPressEvent(QKeyEvent* event);
|
||||||
void keyReleaseEvent(QKeyEvent* event);
|
void keyReleaseEvent(QKeyEvent* event);
|
||||||
|
@ -97,7 +96,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, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override;
|
virtual void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) 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
|
||||||
|
|
|
@ -295,14 +295,20 @@ void AddressManager::goToAddressFromObject(const QVariantMap& dataObject, const
|
||||||
// set our current root place name to the name that came back
|
// set our current root place name to the name that came back
|
||||||
const QString PLACE_NAME_KEY = "name";
|
const QString PLACE_NAME_KEY = "name";
|
||||||
QString placeName = rootMap[PLACE_NAME_KEY].toString();
|
QString placeName = rootMap[PLACE_NAME_KEY].toString();
|
||||||
|
|
||||||
if (!placeName.isEmpty()) {
|
if (!placeName.isEmpty()) {
|
||||||
if (setHost(placeName, trigger)) {
|
if (setHost(placeName, trigger)) {
|
||||||
trigger = LookupTrigger::Internal;
|
trigger = LookupTrigger::Internal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_placeName = placeName;
|
||||||
} else {
|
} else {
|
||||||
if (setHost(domainIDString, trigger)) {
|
if (setHost(domainIDString, trigger)) {
|
||||||
trigger = LookupTrigger::Internal;
|
trigger = LookupTrigger::Internal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// this isn't a place, so clear the place name
|
||||||
|
_placeName.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if we had a path to override the path returned
|
// check if we had a path to override the path returned
|
||||||
|
@ -580,7 +586,9 @@ bool AddressManager::setHost(const QString& host, LookupTrigger trigger, quint16
|
||||||
bool AddressManager::setDomainInfo(const QString& hostname, quint16 port, LookupTrigger trigger) {
|
bool AddressManager::setDomainInfo(const QString& hostname, quint16 port, LookupTrigger trigger) {
|
||||||
bool hostChanged = setHost(hostname, trigger, port);
|
bool hostChanged = setHost(hostname, trigger, port);
|
||||||
|
|
||||||
|
// clear any current place information
|
||||||
_rootPlaceID = QUuid();
|
_rootPlaceID = QUuid();
|
||||||
|
_placeName.clear();
|
||||||
|
|
||||||
qCDebug(networking) << "Possible domain change required to connect to domain at" << hostname << "on" << port;
|
qCDebug(networking) << "Possible domain change required to connect to domain at" << hostname << "on" << port;
|
||||||
|
|
||||||
|
|
|
@ -58,6 +58,7 @@ public:
|
||||||
const QString currentPath(bool withOrientation = true) const;
|
const QString currentPath(bool withOrientation = true) const;
|
||||||
|
|
||||||
const QUuid& getRootPlaceID() const { return _rootPlaceID; }
|
const QUuid& getRootPlaceID() const { return _rootPlaceID; }
|
||||||
|
const QString& getPlaceName() const { return _placeName; }
|
||||||
|
|
||||||
const QString& getHost() const { return _host; }
|
const QString& getHost() const { return _host; }
|
||||||
|
|
||||||
|
@ -141,6 +142,7 @@ private:
|
||||||
|
|
||||||
QString _host;
|
QString _host;
|
||||||
quint16 _port;
|
quint16 _port;
|
||||||
|
QString _placeName;
|
||||||
QUuid _rootPlaceID;
|
QUuid _rootPlaceID;
|
||||||
PositionGetter _positionGetter;
|
PositionGetter _positionGetter;
|
||||||
OrientationGetter _orientationGetter;
|
OrientationGetter _orientationGetter;
|
||||||
|
|
|
@ -314,8 +314,10 @@ void NodeList::sendDomainServerCheckIn() {
|
||||||
packetStream << connectUUID;
|
packetStream << connectUUID;
|
||||||
}
|
}
|
||||||
|
|
||||||
// pack our data to send to the domain-server
|
// pack our data to send to the domain-server including
|
||||||
packetStream << _ownerType << _publicSockAddr << _localSockAddr << _nodeTypesOfInterest.toList();
|
// the hostname information (so the domain-server can see which place name we came in on)
|
||||||
|
packetStream << _ownerType << _publicSockAddr << _localSockAddr << _nodeTypesOfInterest.toList()
|
||||||
|
<< DependencyManager::get<AddressManager>()->getPlaceName();
|
||||||
|
|
||||||
if (!_domainHandler.isConnected()) {
|
if (!_domainHandler.isConnected()) {
|
||||||
DataServerAccountInfo& accountInfo = accountManager->getAccountInfo();
|
DataServerAccountInfo& accountInfo = accountManager->getAccountInfo();
|
||||||
|
|
|
@ -47,7 +47,7 @@ PacketVersion versionForPacketType(PacketType packetType) {
|
||||||
case PacketType::EntityAdd:
|
case PacketType::EntityAdd:
|
||||||
case PacketType::EntityEdit:
|
case PacketType::EntityEdit:
|
||||||
case PacketType::EntityData:
|
case PacketType::EntityData:
|
||||||
return VERSION_LIGHT_HAS_FALLOFF_RADIUS;
|
return VERSION_ENTITIES_NO_FLY_ZONES;
|
||||||
case PacketType::AvatarData:
|
case PacketType::AvatarData:
|
||||||
case PacketType::BulkAvatarData:
|
case PacketType::BulkAvatarData:
|
||||||
return static_cast<PacketVersion>(AvatarMixerPacketVersion::AvatarEntities);
|
return static_cast<PacketVersion>(AvatarMixerPacketVersion::AvatarEntities);
|
||||||
|
@ -58,6 +58,9 @@ PacketVersion versionForPacketType(PacketType packetType) {
|
||||||
case PacketType::AssetUpload:
|
case PacketType::AssetUpload:
|
||||||
// Removal of extension from Asset requests
|
// Removal of extension from Asset requests
|
||||||
return 18;
|
return 18;
|
||||||
|
case PacketType::DomainConnectRequest:
|
||||||
|
// addition of referring hostname information
|
||||||
|
return 18;
|
||||||
default:
|
default:
|
||||||
return 17;
|
return 17;
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,6 +171,7 @@ const PacketVersion VERSION_ENTITITES_HAVE_QUERY_BOX = 54;
|
||||||
const PacketVersion VERSION_ENTITITES_HAVE_COLLISION_MASK = 55;
|
const PacketVersion VERSION_ENTITITES_HAVE_COLLISION_MASK = 55;
|
||||||
const PacketVersion VERSION_ATMOSPHERE_REMOVED = 56;
|
const PacketVersion VERSION_ATMOSPHERE_REMOVED = 56;
|
||||||
const PacketVersion VERSION_LIGHT_HAS_FALLOFF_RADIUS = 57;
|
const PacketVersion VERSION_LIGHT_HAS_FALLOFF_RADIUS = 57;
|
||||||
|
const PacketVersion VERSION_ENTITIES_NO_FLY_ZONES = 58;
|
||||||
|
|
||||||
enum class AvatarMixerPacketVersion : PacketVersion {
|
enum class AvatarMixerPacketVersion : PacketVersion {
|
||||||
TranslationSupport = 17,
|
TranslationSupport = 17,
|
||||||
|
|
|
@ -264,6 +264,10 @@ void CharacterController::setState(State desiredState, const char* reason) {
|
||||||
#else
|
#else
|
||||||
void CharacterController::setState(State desiredState) {
|
void CharacterController::setState(State desiredState) {
|
||||||
#endif
|
#endif
|
||||||
|
if (!_flyingAllowed && desiredState == State::Hover) {
|
||||||
|
desiredState = State::InAir;
|
||||||
|
}
|
||||||
|
|
||||||
if (desiredState != _state) {
|
if (desiredState != _state) {
|
||||||
#ifdef DEBUG_STATE_CHANGE
|
#ifdef DEBUG_STATE_CHANGE
|
||||||
qCDebug(physics) << "CharacterController::setState" << stateToStr(desiredState) << "from" << stateToStr(_state) << "," << reason;
|
qCDebug(physics) << "CharacterController::setState" << stateToStr(desiredState) << "from" << stateToStr(_state) << "," << reason;
|
||||||
|
@ -644,3 +648,13 @@ bool CharacterController::getRigidBodyLocation(glm::vec3& avatarRigidBodyPositio
|
||||||
avatarRigidBodyRotation = bulletToGLM(worldTrans.getRotation());
|
avatarRigidBodyRotation = bulletToGLM(worldTrans.getRotation());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CharacterController::setFlyingAllowed(bool value) {
|
||||||
|
if (_flyingAllowed != value) {
|
||||||
|
_flyingAllowed = value;
|
||||||
|
|
||||||
|
if (!_flyingAllowed && _state == State::Hover) {
|
||||||
|
SET_STATE(State::InAir, "flying not allowed");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -110,6 +110,9 @@ public:
|
||||||
|
|
||||||
bool getRigidBodyLocation(glm::vec3& avatarRigidBodyPosition, glm::quat& avatarRigidBodyRotation);
|
bool getRigidBodyLocation(glm::vec3& avatarRigidBodyPosition, glm::quat& avatarRigidBodyRotation);
|
||||||
|
|
||||||
|
void setFlyingAllowed(bool value);
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
#ifdef DEBUG_STATE_CHANGE
|
#ifdef DEBUG_STATE_CHANGE
|
||||||
void setState(State state, const char* reason);
|
void setState(State state, const char* reason);
|
||||||
|
@ -172,6 +175,8 @@ protected:
|
||||||
btRigidBody* _rigidBody { nullptr };
|
btRigidBody* _rigidBody { nullptr };
|
||||||
uint32_t _pendingFlags { 0 };
|
uint32_t _pendingFlags { 0 };
|
||||||
uint32_t _previousFlags { 0 };
|
uint32_t _previousFlags { 0 };
|
||||||
|
|
||||||
|
bool _flyingAllowed { true };
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_CharacterControllerInterface_h
|
#endif // hifi_CharacterControllerInterface_h
|
||||||
|
|
|
@ -217,6 +217,12 @@ void PhysicalEntitySimulation::getObjectsToAddToPhysics(VectorOfMotionStates& re
|
||||||
} else if (entity->isReadyToComputeShape()) {
|
} else if (entity->isReadyToComputeShape()) {
|
||||||
ShapeInfo shapeInfo;
|
ShapeInfo shapeInfo;
|
||||||
entity->computeShapeInfo(shapeInfo);
|
entity->computeShapeInfo(shapeInfo);
|
||||||
|
int numPoints = shapeInfo.getMaxNumPoints();
|
||||||
|
if (numPoints > MAX_HULL_POINTS) {
|
||||||
|
qWarning() << "convex hull with" << numPoints
|
||||||
|
<< "points for entity" << entity->getName()
|
||||||
|
<< "at" << entity->getPosition() << " will be reduced";
|
||||||
|
}
|
||||||
btCollisionShape* shape = ObjectMotionState::getShapeManager()->getShape(shapeInfo);
|
btCollisionShape* shape = ObjectMotionState::getShapeManager()->getShape(shapeInfo);
|
||||||
if (shape) {
|
if (shape) {
|
||||||
EntityMotionState* motionState = new EntityMotionState(shape, entity);
|
EntityMotionState* motionState = new EntityMotionState(shape, entity);
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#include <glm/gtx/norm.hpp>
|
#include <glm/gtx/norm.hpp>
|
||||||
|
#include <BulletCollision/CollisionShapes/btShapeHull.h>
|
||||||
|
|
||||||
#include <SharedUtil.h> // for MILLIMETERS_PER_METER
|
#include <SharedUtil.h> // for MILLIMETERS_PER_METER
|
||||||
|
|
||||||
|
@ -64,6 +65,22 @@ btConvexHullShape* ShapeFactory::createConvexHull(const QVector<glm::vec3>& poin
|
||||||
correctedPoint = (points[i] - center) * relativeScale + center;
|
correctedPoint = (points[i] - center) * relativeScale + center;
|
||||||
hull->addPoint(btVector3(correctedPoint[0], correctedPoint[1], correctedPoint[2]), false);
|
hull->addPoint(btVector3(correctedPoint[0], correctedPoint[1], correctedPoint[2]), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (points.size() > MAX_HULL_POINTS) {
|
||||||
|
// create hull approximation
|
||||||
|
btShapeHull shapeHull(hull);
|
||||||
|
shapeHull.buildHull(margin);
|
||||||
|
// we cannot copy Bullet shapes so we must create a new one...
|
||||||
|
btConvexHullShape* newHull = new btConvexHullShape();
|
||||||
|
const btVector3* newPoints = shapeHull.getVertexPointer();
|
||||||
|
for (int i = 0; i < shapeHull.numVertices(); ++i) {
|
||||||
|
newHull->addPoint(newPoints[i], false);
|
||||||
|
}
|
||||||
|
// ...and delete the old one
|
||||||
|
delete hull;
|
||||||
|
hull = newHull;
|
||||||
|
}
|
||||||
|
|
||||||
hull->recalcLocalAabb();
|
hull->recalcLocalAabb();
|
||||||
return hull;
|
return hull;
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,10 +18,8 @@ namespace controller {
|
||||||
|
|
||||||
class InputPlugin : public Plugin {
|
class InputPlugin : public Plugin {
|
||||||
public:
|
public:
|
||||||
virtual bool isJointController() const = 0;
|
|
||||||
|
|
||||||
virtual void pluginFocusOutEvent() = 0;
|
virtual void pluginFocusOutEvent() = 0;
|
||||||
|
|
||||||
virtual void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) = 0;
|
virtual void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -294,13 +294,6 @@ void ScriptEngine::waitTillDoneRunning() {
|
||||||
|
|
||||||
auto startedWaiting = usecTimestampNow();
|
auto startedWaiting = usecTimestampNow();
|
||||||
while (workerThread->isRunning()) {
|
while (workerThread->isRunning()) {
|
||||||
// NOTE: This will be called on the main application thread from stopAllScripts.
|
|
||||||
// The application thread will need to continue to process events, because
|
|
||||||
// the scripts will likely need to marshall messages across to the main thread, e.g.
|
|
||||||
// if they access Settings or Menu in any of their shutdown code. So:
|
|
||||||
// Process events for the main application thread, allowing invokeMethod calls to pass between threads.
|
|
||||||
QCoreApplication::processEvents();
|
|
||||||
|
|
||||||
// If the final evaluation takes too long, then tell the script engine to stop running
|
// If the final evaluation takes too long, then tell the script engine to stop running
|
||||||
auto elapsedUsecs = usecTimestampNow() - startedWaiting;
|
auto elapsedUsecs = usecTimestampNow() - startedWaiting;
|
||||||
static const auto MAX_SCRIPT_EVALUATION_TIME = USECS_PER_SECOND;
|
static const auto MAX_SCRIPT_EVALUATION_TIME = USECS_PER_SECOND;
|
||||||
|
@ -326,6 +319,17 @@ void ScriptEngine::waitTillDoneRunning() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NOTE: This will be called on the main application thread from stopAllScripts.
|
||||||
|
// The application thread will need to continue to process events, because
|
||||||
|
// the scripts will likely need to marshall messages across to the main thread, e.g.
|
||||||
|
// if they access Settings or Menu in any of their shutdown code. So:
|
||||||
|
// Process events for the main application thread, allowing invokeMethod calls to pass between threads.
|
||||||
|
QCoreApplication::processEvents();
|
||||||
|
// In some cases (debugging), processEvents may give the thread enough time to shut down, so recheck it.
|
||||||
|
if (!thread()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// Avoid a pure busy wait
|
// Avoid a pure busy wait
|
||||||
QThread::yieldCurrentThread();
|
QThread::yieldCurrentThread();
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,6 +99,18 @@ uint32_t ShapeInfo::getNumSubShapes() const {
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int ShapeInfo::getMaxNumPoints() const {
|
||||||
|
int numPoints = 0;
|
||||||
|
for (int i = 0; i < _points.size(); ++i) {
|
||||||
|
int n = _points[i].size();
|
||||||
|
if (n > numPoints) {
|
||||||
|
numPoints = n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return numPoints;
|
||||||
|
}
|
||||||
|
|
||||||
float ShapeInfo::computeVolume() const {
|
float ShapeInfo::computeVolume() const {
|
||||||
const float DEFAULT_VOLUME = 1.0f;
|
const float DEFAULT_VOLUME = 1.0f;
|
||||||
float volume = DEFAULT_VOLUME;
|
float volume = DEFAULT_VOLUME;
|
||||||
|
|
|
@ -22,6 +22,10 @@
|
||||||
|
|
||||||
const float MIN_SHAPE_OFFSET = 0.001f; // offsets less than 1mm will be ignored
|
const float MIN_SHAPE_OFFSET = 0.001f; // offsets less than 1mm will be ignored
|
||||||
|
|
||||||
|
// Bullet has a mesh generation util for convex shapes that we used to
|
||||||
|
// trim convex hulls with many points down to only 42 points.
|
||||||
|
const int MAX_HULL_POINTS = 42;
|
||||||
|
|
||||||
enum ShapeType {
|
enum ShapeType {
|
||||||
SHAPE_TYPE_NONE,
|
SHAPE_TYPE_NONE,
|
||||||
SHAPE_TYPE_BOX,
|
SHAPE_TYPE_BOX,
|
||||||
|
@ -61,6 +65,7 @@ public:
|
||||||
|
|
||||||
void clearPoints () { _points.clear(); }
|
void clearPoints () { _points.clear(); }
|
||||||
void appendToPoints (const QVector<glm::vec3>& newPoints) { _points << newPoints; }
|
void appendToPoints (const QVector<glm::vec3>& newPoints) { _points << newPoints; }
|
||||||
|
int getMaxNumPoints() const;
|
||||||
|
|
||||||
float computeVolume() const;
|
float computeVolume() const;
|
||||||
|
|
||||||
|
|
|
@ -23,7 +23,7 @@ void StreamUtil::dump(std::ostream& s, const QByteArray& buffer) {
|
||||||
while (i < buffer.size()) {
|
while (i < buffer.size()) {
|
||||||
for(int j = 0; i < buffer.size() && j < row_size; ++j) {
|
for(int j = 0; i < buffer.size() && j < row_size; ++j) {
|
||||||
char byte = buffer[i];
|
char byte = buffer[i];
|
||||||
s << hex_digits[(byte >> 4) & 0x0f] << hex_digits[byte & 0x0f] << " ";
|
s << hex_digits[(byte >> 4) & 0x0f] << hex_digits[byte & 0x0f] << ' ';
|
||||||
++i;
|
++i;
|
||||||
}
|
}
|
||||||
s << "\n";
|
s << "\n";
|
||||||
|
@ -31,21 +31,21 @@ void StreamUtil::dump(std::ostream& s, const QByteArray& buffer) {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& s, const glm::vec3& v) {
|
std::ostream& operator<<(std::ostream& s, const glm::vec3& v) {
|
||||||
s << "<" << v.x << " " << v.y << " " << v.z << ">";
|
s << '(' << v.x << ' ' << v.y << ' ' << v.z << ')';
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& s, const glm::quat& q) {
|
std::ostream& operator<<(std::ostream& s, const glm::quat& q) {
|
||||||
s << "<" << q.x << " " << q.y << " " << q.z << " " << q.w << ">";
|
s << '(' << q.x << ' ' << q.y << ' ' << q.z << ' ' << q.w << ')';
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& s, const glm::mat4& m) {
|
std::ostream& operator<<(std::ostream& s, const glm::mat4& m) {
|
||||||
s << "[";
|
s << '[';
|
||||||
for (int j = 0; j < 4; ++j) {
|
for (int j = 0; j < 4; ++j) {
|
||||||
s << " " << m[0][j] << " " << m[1][j] << " " << m[2][j] << " " << m[3][j] << ";";
|
s << ' ' << m[0][j] << ' ' << m[1][j] << ' ' << m[2][j] << ' ' << m[3][j] << ';';
|
||||||
}
|
}
|
||||||
s << " ]";
|
s << " ]";
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,54 +69,37 @@ QDataStream& operator>>(QDataStream& in, glm::quat& quaternion) {
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
|
|
||||||
QDebug& operator<<(QDebug& dbg, const glm::vec2& v) {
|
QDebug& operator<<(QDebug& dbg, const glm::vec2& v) {
|
||||||
dbg.nospace() << "{type='glm::vec2'"
|
dbg.nospace() << '(' << v.x << ", " << v.y << ')';
|
||||||
", x=" << v.x <<
|
|
||||||
", y=" << v.y <<
|
|
||||||
"}";
|
|
||||||
return dbg;
|
return dbg;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDebug& operator<<(QDebug& dbg, const glm::vec3& v) {
|
QDebug& operator<<(QDebug& dbg, const glm::vec3& v) {
|
||||||
dbg.nospace() << "{type='glm::vec3'"
|
dbg.nospace() << '(' << v.x << ", " << v.y << ", " << v.z << ')';
|
||||||
", x=" << v.x <<
|
|
||||||
", y=" << v.y <<
|
|
||||||
", z=" << v.z <<
|
|
||||||
"}";
|
|
||||||
return dbg;
|
return dbg;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDebug& operator<<(QDebug& dbg, const glm::vec4& v) {
|
QDebug& operator<<(QDebug& dbg, const glm::vec4& v) {
|
||||||
dbg.nospace() << "{type='glm::vec4'"
|
dbg.nospace() << '(' << v.x << ", " << v.y << ", " << v.z << ", " << v.w << ')';
|
||||||
", x=" << v.x <<
|
|
||||||
", y=" << v.y <<
|
|
||||||
", z=" << v.z <<
|
|
||||||
", w=" << v.w <<
|
|
||||||
"}";
|
|
||||||
return dbg;
|
return dbg;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDebug& operator<<(QDebug& dbg, const glm::quat& q) {
|
QDebug& operator<<(QDebug& dbg, const glm::quat& q) {
|
||||||
dbg.nospace() << "{type='glm::quat'"
|
dbg.nospace() << '(' << q.x << ", " << q.y << ", " << q.z << ", " << q.w << ')';
|
||||||
", x=" << q.x <<
|
|
||||||
", y=" << q.y <<
|
|
||||||
", z=" << q.z <<
|
|
||||||
", w=" << q.w <<
|
|
||||||
"}";
|
|
||||||
return dbg;
|
return dbg;
|
||||||
}
|
}
|
||||||
|
|
||||||
QDebug& operator<<(QDebug& dbg, const glm::mat4& m) {
|
QDebug& operator<<(QDebug& dbg, const glm::mat4& m) {
|
||||||
dbg.nospace() << "{type='glm::mat4', [";
|
dbg.nospace() << '[';
|
||||||
for (int j = 0; j < 4; ++j) {
|
for (int j = 0; j < 4; ++j) {
|
||||||
dbg << ' ' << m[0][j] << ' ' << m[1][j] << ' ' << m[2][j] << ' ' << m[3][j] << ';';
|
dbg << ' ' << m[0][j] << ' ' << m[1][j] << ' ' << m[2][j] << ' ' << m[3][j] << ';';
|
||||||
}
|
}
|
||||||
return dbg << " ]}";
|
return dbg << " ]";
|
||||||
}
|
}
|
||||||
|
|
||||||
QDebug& operator<<(QDebug& dbg, const QVariantHash& v) {
|
QDebug& operator<<(QDebug& dbg, const QVariantHash& v) {
|
||||||
dbg.nospace() << "[";
|
dbg.nospace() << "[ ";
|
||||||
for (QVariantHash::const_iterator it = v.constBegin(); it != v.constEnd(); it++) {
|
for (QVariantHash::const_iterator it = v.constBegin(); it != v.constEnd(); it++) {
|
||||||
dbg << it.key() << ":" << it.value();
|
dbg << it.key() << ':' << it.value();
|
||||||
}
|
}
|
||||||
return dbg << " ]";
|
return dbg << " ]";
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,8 +6,11 @@
|
||||||
# See the accompanying file LICENSE or http:#www.apache.org/licenses/LICENSE-2.0.html
|
# See the accompanying file LICENSE or http:#www.apache.org/licenses/LICENSE-2.0.html
|
||||||
#
|
#
|
||||||
|
|
||||||
set(TARGET_NAME hifiNeuron)
|
if (APPLE OR WIN32)
|
||||||
setup_hifi_plugin(Script Qml Widgets)
|
|
||||||
link_hifi_libraries(shared controllers ui plugins input-plugins)
|
set(TARGET_NAME hifiNeuron)
|
||||||
target_neuron()
|
setup_hifi_plugin(Script Qml Widgets)
|
||||||
|
link_hifi_libraries(shared controllers ui plugins input-plugins)
|
||||||
|
target_neuron()
|
||||||
|
|
||||||
|
endif()
|
||||||
|
|
|
@ -25,9 +25,7 @@ Q_LOGGING_CATEGORY(inputplugins, "hifi.inputplugins")
|
||||||
#define __OS_XUN__ 1
|
#define __OS_XUN__ 1
|
||||||
#define BOOL int
|
#define BOOL int
|
||||||
|
|
||||||
#ifdef HAVE_NEURON
|
|
||||||
#include <NeuronDataReader.h>
|
#include <NeuronDataReader.h>
|
||||||
#endif
|
|
||||||
|
|
||||||
const QString NeuronPlugin::NAME = "Neuron";
|
const QString NeuronPlugin::NAME = "Neuron";
|
||||||
const QString NeuronPlugin::NEURON_ID_STRING = "Perception Neuron";
|
const QString NeuronPlugin::NEURON_ID_STRING = "Perception Neuron";
|
||||||
|
@ -166,69 +164,6 @@ static controller::StandardPoseChannel neuronJointIndexToPoseIndexMap[NeuronJoin
|
||||||
static glm::vec3 rightHandThumb1DefaultAbsTranslation(-2.155500650405884, -0.7610001564025879, 2.685631036758423);
|
static glm::vec3 rightHandThumb1DefaultAbsTranslation(-2.155500650405884, -0.7610001564025879, 2.685631036758423);
|
||||||
static glm::vec3 leftHandThumb1DefaultAbsTranslation(2.1555817127227783, -0.7603635787963867, 2.6856393814086914);
|
static glm::vec3 leftHandThumb1DefaultAbsTranslation(2.1555817127227783, -0.7603635787963867, 2.6856393814086914);
|
||||||
|
|
||||||
// default translations (cm)
|
|
||||||
static glm::vec3 neuronJointTranslations[NeuronJointIndex::Size] = {
|
|
||||||
{131.901, 95.6602, -27.9815},
|
|
||||||
{-9.55907, -1.58772, 0.0760284},
|
|
||||||
{0.0144232, -41.4683, -0.105322},
|
|
||||||
{1.59348, -41.5875, -0.557237},
|
|
||||||
{9.72077, -1.68926, -0.280643},
|
|
||||||
{0.0886684, -43.1586, -0.0111596},
|
|
||||||
{-2.98473, -44.0517, 0.0694456},
|
|
||||||
{0.110967, 16.3959, 0.140463},
|
|
||||||
{0.0500451, 10.0238, 0.0731921},
|
|
||||||
{0.061568, 10.4352, 0.0583075},
|
|
||||||
{0.0500606, 10.0217, 0.0711083},
|
|
||||||
{0.0317731, 10.7176, 0.0779325},
|
|
||||||
{-0.0204253, 9.71067, 0.131734},
|
|
||||||
{-3.24245, 7.13584, 0.185638},
|
|
||||||
{-13.0885, -0.0877601, 0.176065},
|
|
||||||
{-27.2674, 0.0688724, 0.0272146},
|
|
||||||
{-26.7673, 0.0301916, 0.0102847},
|
|
||||||
{-2.56017, 0.195537, 3.20968},
|
|
||||||
{-3.78796, 0, 0},
|
|
||||||
{-2.63141, 0, 0},
|
|
||||||
{-3.31579, 0.522947, 2.03495},
|
|
||||||
{-5.36589, -0.0939789, 1.02771},
|
|
||||||
{-3.72278, 0, 0},
|
|
||||||
{-2.11074, 0, 0},
|
|
||||||
{-3.47874, 0.532042, 0.778358},
|
|
||||||
{-5.32194, -0.0864, 0.322863},
|
|
||||||
{-4.06232, 0, 0},
|
|
||||||
{-2.54653, 0, 0},
|
|
||||||
{-3.46131, 0.553263, -0.132632},
|
|
||||||
{-4.76716, -0.0227368, -0.492632},
|
|
||||||
{-3.54073, 0, 0},
|
|
||||||
{-2.45634, 0, 0},
|
|
||||||
{-3.25137, 0.482779, -1.23613},
|
|
||||||
{-4.25937, -0.0227368, -1.12168},
|
|
||||||
{-2.83528, 0, 0},
|
|
||||||
{-1.79166, 0, 0},
|
|
||||||
{3.25624, 7.13148, -0.131575},
|
|
||||||
{13.149, -0.052598, -0.125076},
|
|
||||||
{27.2903, 0.00282644, -0.0181535},
|
|
||||||
{26.6602, 0.000969969, -0.0487599},
|
|
||||||
{2.56017, 0.195537, 3.20968},
|
|
||||||
{3.78796, 0, 0},
|
|
||||||
{2.63141, 0, 0},
|
|
||||||
{3.31579, 0.522947, 2.03495},
|
|
||||||
{5.36589, -0.0939789, 1.02771},
|
|
||||||
{3.72278, 0, 0},
|
|
||||||
{2.11074, 0, 0},
|
|
||||||
{3.47874, 0.532042, 0.778358},
|
|
||||||
{5.32194, -0.0864, 0.322863},
|
|
||||||
{4.06232, 0, 0},
|
|
||||||
{2.54653, 0, 0},
|
|
||||||
{3.46131, 0.553263, -0.132632},
|
|
||||||
{4.76716, -0.0227368, -0.492632},
|
|
||||||
{3.54073, 0, 0},
|
|
||||||
{2.45634, 0, 0},
|
|
||||||
{3.25137, 0.482779, -1.23613},
|
|
||||||
{4.25937, -0.0227368, -1.12168},
|
|
||||||
{2.83528, 0, 0},
|
|
||||||
{1.79166, 0, 0}
|
|
||||||
};
|
|
||||||
|
|
||||||
static controller::StandardPoseChannel neuronJointIndexToPoseIndex(NeuronJointIndex i) {
|
static controller::StandardPoseChannel neuronJointIndexToPoseIndex(NeuronJointIndex i) {
|
||||||
assert(i >= 0 && i < NeuronJointIndex::Size);
|
assert(i >= 0 && i < NeuronJointIndex::Size);
|
||||||
if (i >= 0 && i < NeuronJointIndex::Size) {
|
if (i >= 0 && i < NeuronJointIndex::Size) {
|
||||||
|
@ -307,16 +242,13 @@ static const char* controllerJointName(controller::StandardPoseChannel i) {
|
||||||
|
|
||||||
// convert between YXZ neuron euler angles in degrees to quaternion
|
// convert between YXZ neuron euler angles in degrees to quaternion
|
||||||
// this is the default setting in the Axis Neuron server.
|
// this is the default setting in the Axis Neuron server.
|
||||||
static quat eulerToQuat(vec3 euler) {
|
static quat eulerToQuat(const vec3& e) {
|
||||||
// euler.x and euler.y are swaped, WTF.
|
// euler.x and euler.y are swaped, WTF.
|
||||||
glm::vec3 e = glm::vec3(euler.y, euler.x, euler.z) * RADIANS_PER_DEGREE;
|
return (glm::angleAxis(e.x * RADIANS_PER_DEGREE, Vectors::UNIT_Y) *
|
||||||
return (glm::angleAxis(e.y, Vectors::UNIT_Y) *
|
glm::angleAxis(e.y * RADIANS_PER_DEGREE, Vectors::UNIT_X) *
|
||||||
glm::angleAxis(e.x, Vectors::UNIT_X) *
|
glm::angleAxis(e.z * RADIANS_PER_DEGREE, Vectors::UNIT_Z));
|
||||||
glm::angleAxis(e.z, Vectors::UNIT_Z));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HAVE_NEURON
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// neuronDataReader SDK callback functions
|
// neuronDataReader SDK callback functions
|
||||||
//
|
//
|
||||||
|
@ -355,21 +287,6 @@ void FrameDataReceivedCallback(void* context, SOCKET_REF sender, BvhDataHeaderEx
|
||||||
|
|
||||||
// copy the data
|
// copy the data
|
||||||
memcpy(&(neuronPlugin->_joints[0]), data, sizeof(NeuronPlugin::NeuronJoint) * NUM_JOINTS);
|
memcpy(&(neuronPlugin->_joints[0]), data, sizeof(NeuronPlugin::NeuronJoint) * NUM_JOINTS);
|
||||||
|
|
||||||
} else {
|
|
||||||
qCWarning(inputplugins) << "NeuronPlugin: unsuported binary format, please enable displacements";
|
|
||||||
|
|
||||||
// enter mutex
|
|
||||||
std::lock_guard<std::mutex> guard(neuronPlugin->_jointsMutex);
|
|
||||||
|
|
||||||
if (neuronPlugin->_joints.size() != NeuronJointIndex::Size) {
|
|
||||||
neuronPlugin->_joints.resize(NeuronJointIndex::Size, { { 0.0f, 0.0f, 0.0f }, { 0.0f, 0.0f, 0.0f } });
|
|
||||||
}
|
|
||||||
|
|
||||||
for (int i = 0; i < NeuronJointIndex::Size; i++) {
|
|
||||||
neuronPlugin->_joints[i].euler = glm::vec3();
|
|
||||||
neuronPlugin->_joints[i].pos = neuronJointTranslations[i];
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
static bool ONCE = false;
|
static bool ONCE = false;
|
||||||
|
@ -435,26 +352,19 @@ static void SocketStatusChangedCallback(void* context, SOCKET_REF sender, Socket
|
||||||
qCDebug(inputplugins) << "NeuronPlugin: socket status = " << message;
|
qCDebug(inputplugins) << "NeuronPlugin: socket status = " << message;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // #ifdef HAVE_NEURON
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// NeuronPlugin
|
// NeuronPlugin
|
||||||
//
|
//
|
||||||
|
|
||||||
bool NeuronPlugin::isSupported() const {
|
bool NeuronPlugin::isSupported() const {
|
||||||
#ifdef HAVE_NEURON
|
|
||||||
// Because it's a client/server network architecture, we can't tell
|
// Because it's a client/server network architecture, we can't tell
|
||||||
// if the neuron is actually connected until we connect to the server.
|
// if the neuron is actually connected until we connect to the server.
|
||||||
return true;
|
return true;
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool NeuronPlugin::activate() {
|
bool NeuronPlugin::activate() {
|
||||||
InputPlugin::activate();
|
InputPlugin::activate();
|
||||||
|
|
||||||
#ifdef HAVE_NEURON
|
|
||||||
// register with userInputMapper
|
// register with userInputMapper
|
||||||
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
||||||
userInputMapper->registerDevice(_inputDevice);
|
userInputMapper->registerDevice(_inputDevice);
|
||||||
|
@ -480,13 +390,9 @@ bool NeuronPlugin::activate() {
|
||||||
BRRegisterAutoSyncParmeter(_socketRef, Cmd_CombinationMode);
|
BRRegisterAutoSyncParmeter(_socketRef, Cmd_CombinationMode);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NeuronPlugin::deactivate() {
|
void NeuronPlugin::deactivate() {
|
||||||
#ifdef HAVE_NEURON
|
|
||||||
// unregister from userInputMapper
|
// unregister from userInputMapper
|
||||||
if (_inputDevice->_deviceID != controller::Input::INVALID_DEVICE) {
|
if (_inputDevice->_deviceID != controller::Input::INVALID_DEVICE) {
|
||||||
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
||||||
|
@ -499,10 +405,9 @@ void NeuronPlugin::deactivate() {
|
||||||
}
|
}
|
||||||
|
|
||||||
InputPlugin::deactivate();
|
InputPlugin::deactivate();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NeuronPlugin::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) {
|
void NeuronPlugin::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) {
|
||||||
std::vector<NeuronJoint> joints;
|
std::vector<NeuronJoint> joints;
|
||||||
{
|
{
|
||||||
// lock and copy
|
// lock and copy
|
||||||
|
@ -548,16 +453,23 @@ QString NeuronPlugin::InputDevice::getDefaultMappingConfig() const {
|
||||||
|
|
||||||
void NeuronPlugin::InputDevice::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, 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++) {
|
||||||
|
int poseIndex = neuronJointIndexToPoseIndex((NeuronJointIndex)i);
|
||||||
glm::vec3 linearVel, angularVel;
|
glm::vec3 linearVel, angularVel;
|
||||||
glm::vec3 pos = joints[i].pos;
|
const glm::vec3& pos = joints[i].pos;
|
||||||
glm::quat rot = eulerToQuat(joints[i].euler);
|
const glm::vec3& rotEuler = joints[i].euler;
|
||||||
|
|
||||||
|
if (Vectors::ZERO == pos && Vectors::ZERO == rotEuler) {
|
||||||
|
_poseStateMap[poseIndex] = controller::Pose();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
glm::quat rot = eulerToQuat(rotEuler);
|
||||||
if (i < prevJoints.size()) {
|
if (i < prevJoints.size()) {
|
||||||
linearVel = (pos - (prevJoints[i].pos * METERS_PER_CENTIMETER)) / deltaTime; // m/s
|
linearVel = (pos - (prevJoints[i].pos * METERS_PER_CENTIMETER)) / deltaTime; // m/s
|
||||||
// quat log imaginary part points along the axis of rotation, with length of one half the angle of rotation.
|
// quat log imaginary part points along the axis of rotation, with length of one half the angle of rotation.
|
||||||
glm::quat d = glm::log(rot * glm::inverse(eulerToQuat(prevJoints[i].euler)));
|
glm::quat d = glm::log(rot * glm::inverse(eulerToQuat(prevJoints[i].euler)));
|
||||||
angularVel = glm::vec3(d.x, d.y, d.z) / (0.5f * deltaTime); // radians/s
|
angularVel = glm::vec3(d.x, d.y, d.z) / (0.5f * deltaTime); // radians/s
|
||||||
}
|
}
|
||||||
int poseIndex = neuronJointIndexToPoseIndex((NeuronJointIndex)i);
|
|
||||||
_poseStateMap[poseIndex] = controller::Pose(pos, rot, linearVel, angularVel);
|
_poseStateMap[poseIndex] = controller::Pose(pos, rot, linearVel, angularVel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,7 +27,6 @@ public:
|
||||||
|
|
||||||
// Plugin functions
|
// Plugin functions
|
||||||
virtual bool isSupported() const override;
|
virtual bool isSupported() const override;
|
||||||
virtual bool isJointController() const override { return true; }
|
|
||||||
virtual const QString& getName() const override { return NAME; }
|
virtual const QString& getName() const override { return NAME; }
|
||||||
const QString& getID() const override { return NEURON_ID_STRING; }
|
const QString& getID() const override { return NEURON_ID_STRING; }
|
||||||
|
|
||||||
|
@ -35,7 +34,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, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override;
|
virtual void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override;
|
||||||
|
|
||||||
virtual void saveSettings() const override;
|
virtual void saveSettings() const override;
|
||||||
virtual void loadSettings() override;
|
virtual void loadSettings() override;
|
||||||
|
@ -56,7 +55,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, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override {};
|
virtual void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override {};
|
||||||
virtual void focusOutEvent() override {};
|
virtual void focusOutEvent() override {};
|
||||||
|
|
||||||
void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, 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);
|
||||||
|
|
|
@ -15,7 +15,6 @@
|
||||||
|
|
||||||
const float CONTROLLER_THRESHOLD = 0.3f;
|
const float CONTROLLER_THRESHOLD = 0.3f;
|
||||||
|
|
||||||
#ifdef HAVE_SDL2
|
|
||||||
const float MAX_AXIS = 32768.0f;
|
const float MAX_AXIS = 32768.0f;
|
||||||
|
|
||||||
Joystick::Joystick(SDL_JoystickID instanceId, SDL_GameController* sdlGameController) :
|
Joystick::Joystick(SDL_JoystickID instanceId, SDL_GameController* sdlGameController) :
|
||||||
|
@ -27,19 +26,15 @@ Joystick::Joystick(SDL_JoystickID instanceId, SDL_GameController* sdlGameControl
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
Joystick::~Joystick() {
|
Joystick::~Joystick() {
|
||||||
closeJoystick();
|
closeJoystick();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Joystick::closeJoystick() {
|
void Joystick::closeJoystick() {
|
||||||
#ifdef HAVE_SDL2
|
|
||||||
SDL_GameControllerClose(_sdlGameController);
|
SDL_GameControllerClose(_sdlGameController);
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Joystick::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) {
|
void Joystick::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) {
|
||||||
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;
|
||||||
|
@ -52,8 +47,6 @@ void Joystick::focusOutEvent() {
|
||||||
_buttonPressedMap.clear();
|
_buttonPressedMap.clear();
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef HAVE_SDL2
|
|
||||||
|
|
||||||
void Joystick::handleAxisEvent(const SDL_ControllerAxisEvent& event) {
|
void Joystick::handleAxisEvent(const SDL_ControllerAxisEvent& event) {
|
||||||
SDL_GameControllerAxis axis = (SDL_GameControllerAxis) event.axis;
|
SDL_GameControllerAxis axis = (SDL_GameControllerAxis) event.axis;
|
||||||
_axisStateMap[makeInput((controller::StandardAxisChannel)axis).getChannel()] = (float)event.value / MAX_AXIS;
|
_axisStateMap[makeInput((controller::StandardAxisChannel)axis).getChannel()] = (float)event.value / MAX_AXIS;
|
||||||
|
@ -69,8 +62,6 @@ void Joystick::handleButtonEvent(const SDL_ControllerButtonEvent& event) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
controller::Input::NamedVector Joystick::getAvailableInputs() const {
|
controller::Input::NamedVector Joystick::getAvailableInputs() const {
|
||||||
using namespace controller;
|
using namespace controller;
|
||||||
static const Input::NamedVector availableInputs{
|
static const Input::NamedVector availableInputs{
|
||||||
|
|
|
@ -15,10 +15,8 @@
|
||||||
#include <qobject.h>
|
#include <qobject.h>
|
||||||
#include <qvector.h>
|
#include <qvector.h>
|
||||||
|
|
||||||
#ifdef HAVE_SDL2
|
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#undef main
|
#undef main
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <controllers/InputDevice.h>
|
#include <controllers/InputDevice.h>
|
||||||
#include <controllers/StandardControls.h>
|
#include <controllers/StandardControls.h>
|
||||||
|
@ -26,10 +24,7 @@
|
||||||
class Joystick : public QObject, public controller::InputDevice {
|
class Joystick : public QObject, public controller::InputDevice {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
Q_PROPERTY(QString name READ getName)
|
Q_PROPERTY(QString name READ getName)
|
||||||
|
|
||||||
#ifdef HAVE_SDL2
|
|
||||||
Q_PROPERTY(int instanceId READ getInstanceId)
|
Q_PROPERTY(int instanceId READ getInstanceId)
|
||||||
#endif
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
using Pointer = std::shared_ptr<Joystick>;
|
using Pointer = std::shared_ptr<Joystick>;
|
||||||
|
@ -39,33 +34,25 @@ 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, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override;
|
virtual void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override;
|
||||||
virtual void focusOutEvent() override;
|
virtual void focusOutEvent() override;
|
||||||
|
|
||||||
Joystick() : InputDevice("GamePad") {}
|
Joystick() : InputDevice("GamePad") {}
|
||||||
~Joystick();
|
~Joystick();
|
||||||
|
|
||||||
#ifdef HAVE_SDL2
|
|
||||||
Joystick(SDL_JoystickID instanceId, SDL_GameController* sdlGameController);
|
Joystick(SDL_JoystickID instanceId, SDL_GameController* sdlGameController);
|
||||||
#endif
|
|
||||||
|
|
||||||
void closeJoystick();
|
void closeJoystick();
|
||||||
|
|
||||||
#ifdef HAVE_SDL2
|
|
||||||
void handleAxisEvent(const SDL_ControllerAxisEvent& event);
|
void handleAxisEvent(const SDL_ControllerAxisEvent& event);
|
||||||
void handleButtonEvent(const SDL_ControllerButtonEvent& event);
|
void handleButtonEvent(const SDL_ControllerButtonEvent& event);
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_SDL2
|
|
||||||
int getInstanceId() const { return _instanceId; }
|
int getInstanceId() const { return _instanceId; }
|
||||||
#endif
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef HAVE_SDL2
|
|
||||||
SDL_GameController* _sdlGameController;
|
SDL_GameController* _sdlGameController;
|
||||||
SDL_Joystick* _sdlJoystick;
|
SDL_Joystick* _sdlJoystick;
|
||||||
SDL_JoystickID _instanceId;
|
SDL_JoystickID _instanceId;
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // hifi_Joystick_h
|
#endif // hifi_Joystick_h
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
|
|
||||||
#include "SDL2Manager.h"
|
#include "SDL2Manager.h"
|
||||||
|
|
||||||
#ifdef HAVE_SDL2
|
|
||||||
static_assert(
|
static_assert(
|
||||||
(int)controller::A == (int)SDL_CONTROLLER_BUTTON_A &&
|
(int)controller::A == (int)SDL_CONTROLLER_BUTTON_A &&
|
||||||
(int)controller::B == (int)SDL_CONTROLLER_BUTTON_B &&
|
(int)controller::B == (int)SDL_CONTROLLER_BUTTON_B &&
|
||||||
|
@ -40,28 +39,16 @@ static_assert(
|
||||||
(int)controller::LT == (int)SDL_CONTROLLER_AXIS_TRIGGERLEFT &&
|
(int)controller::LT == (int)SDL_CONTROLLER_AXIS_TRIGGERLEFT &&
|
||||||
(int)controller::RT == (int)SDL_CONTROLLER_AXIS_TRIGGERRIGHT,
|
(int)controller::RT == (int)SDL_CONTROLLER_AXIS_TRIGGERRIGHT,
|
||||||
"SDL2 equvalence: Enums and values from StandardControls.h are assumed to match enums from SDL_gamecontroller.h");
|
"SDL2 equvalence: Enums and values from StandardControls.h are assumed to match enums from SDL_gamecontroller.h");
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
const QString SDL2Manager::NAME = "SDL2";
|
const QString SDL2Manager::NAME = "SDL2";
|
||||||
|
|
||||||
#ifdef HAVE_SDL2
|
|
||||||
SDL_JoystickID SDL2Manager::getInstanceId(SDL_GameController* controller) {
|
SDL_JoystickID SDL2Manager::getInstanceId(SDL_GameController* controller) {
|
||||||
SDL_Joystick* joystick = SDL_GameControllerGetJoystick(controller);
|
SDL_Joystick* joystick = SDL_GameControllerGetJoystick(controller);
|
||||||
return SDL_JoystickInstanceID(joystick);
|
return SDL_JoystickInstanceID(joystick);
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
SDL2Manager::SDL2Manager() :
|
|
||||||
#ifdef HAVE_SDL2
|
|
||||||
_openJoysticks(),
|
|
||||||
#endif
|
|
||||||
_isInitialized(false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void SDL2Manager::init() {
|
void SDL2Manager::init() {
|
||||||
#ifdef HAVE_SDL2
|
|
||||||
bool initSuccess = (SDL_Init(SDL_INIT_GAMECONTROLLER) == 0);
|
bool initSuccess = (SDL_Init(SDL_INIT_GAMECONTROLLER) == 0);
|
||||||
|
|
||||||
if (initSuccess) {
|
if (initSuccess) {
|
||||||
|
@ -88,66 +75,50 @@ void SDL2Manager::init() {
|
||||||
else {
|
else {
|
||||||
qDebug() << "Error initializing SDL2 Manager";
|
qDebug() << "Error initializing SDL2 Manager";
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDL2Manager::deinit() {
|
void SDL2Manager::deinit() {
|
||||||
#ifdef HAVE_SDL2
|
|
||||||
_openJoysticks.clear();
|
_openJoysticks.clear();
|
||||||
|
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool SDL2Manager::activate() {
|
bool SDL2Manager::activate() {
|
||||||
InputPlugin::activate();
|
InputPlugin::activate();
|
||||||
|
|
||||||
#ifdef HAVE_SDL2
|
|
||||||
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
||||||
for (auto joystick : _openJoysticks) {
|
for (auto joystick : _openJoysticks) {
|
||||||
userInputMapper->registerDevice(joystick);
|
userInputMapper->registerDevice(joystick);
|
||||||
emit joystickAdded(joystick.get());
|
emit joystickAdded(joystick.get());
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDL2Manager::deactivate() {
|
void SDL2Manager::deactivate() {
|
||||||
#ifdef HAVE_SDL2
|
|
||||||
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
||||||
for (auto joystick : _openJoysticks) {
|
for (auto joystick : _openJoysticks) {
|
||||||
userInputMapper->removeDevice(joystick->getDeviceID());
|
userInputMapper->removeDevice(joystick->getDeviceID());
|
||||||
emit joystickRemoved(joystick.get());
|
emit joystickRemoved(joystick.get());
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
InputPlugin::deactivate();
|
InputPlugin::deactivate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool SDL2Manager::isSupported() const {
|
bool SDL2Manager::isSupported() const {
|
||||||
#ifdef HAVE_SDL2
|
|
||||||
return true;
|
return true;
|
||||||
#else
|
|
||||||
return false;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDL2Manager::pluginFocusOutEvent() {
|
void SDL2Manager::pluginFocusOutEvent() {
|
||||||
#ifdef HAVE_SDL2
|
|
||||||
for (auto joystick : _openJoysticks) {
|
for (auto joystick : _openJoysticks) {
|
||||||
joystick->focusOutEvent();
|
joystick->focusOutEvent();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SDL2Manager::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) {
|
void SDL2Manager::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) {
|
||||||
#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, inputCalibrationData, jointsCaptured);
|
joystick->update(deltaTime, inputCalibrationData);
|
||||||
}
|
}
|
||||||
|
|
||||||
PerformanceTimer perfTimer("SDL2Manager::update");
|
PerformanceTimer perfTimer("SDL2Manager::update");
|
||||||
|
@ -197,5 +168,4 @@ void SDL2Manager::pluginUpdate(float deltaTime, const controller::InputCalibrati
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,9 +12,7 @@
|
||||||
#ifndef hifi__SDL2Manager_h
|
#ifndef hifi__SDL2Manager_h
|
||||||
#define hifi__SDL2Manager_h
|
#define hifi__SDL2Manager_h
|
||||||
|
|
||||||
#ifdef HAVE_SDL2
|
|
||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <controllers/UserInputMapper.h>
|
#include <controllers/UserInputMapper.h>
|
||||||
#include <input-plugins/InputPlugin.h>
|
#include <input-plugins/InputPlugin.h>
|
||||||
|
@ -24,30 +22,26 @@ class SDL2Manager : public InputPlugin {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
public:
|
public:
|
||||||
SDL2Manager();
|
|
||||||
|
|
||||||
// Plugin functions
|
// Plugin functions
|
||||||
virtual bool isSupported() const override;
|
bool isSupported() const override;
|
||||||
virtual bool isJointController() const override { return false; }
|
const QString& getName() const override { return NAME; }
|
||||||
virtual const QString& getName() const override { return NAME; }
|
|
||||||
|
|
||||||
virtual void init() override;
|
void init() override;
|
||||||
virtual void deinit() override;
|
void deinit() override;
|
||||||
|
|
||||||
/// Called when a plugin is being activated for use. May be called multiple times.
|
/// Called when a plugin is being activated for use. May be called multiple times.
|
||||||
virtual bool activate() override;
|
bool activate() override;
|
||||||
/// Called when a plugin is no longer being used. May be called multiple times.
|
/// Called when a plugin is no longer being used. May be called multiple times.
|
||||||
virtual void deactivate() override;
|
void deactivate() override;
|
||||||
|
|
||||||
virtual void pluginFocusOutEvent() override;
|
void pluginFocusOutEvent() override;
|
||||||
virtual void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override;
|
void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void joystickAdded(Joystick* joystick);
|
void joystickAdded(Joystick* joystick);
|
||||||
void joystickRemoved(Joystick* joystick);
|
void joystickRemoved(Joystick* joystick);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
#ifdef HAVE_SDL2
|
|
||||||
SDL_JoystickID getInstanceId(SDL_GameController* controller);
|
SDL_JoystickID getInstanceId(SDL_GameController* controller);
|
||||||
|
|
||||||
int axisInvalid() const { return SDL_CONTROLLER_AXIS_INVALID; }
|
int axisInvalid() const { return SDL_CONTROLLER_AXIS_INVALID; }
|
||||||
|
@ -81,8 +75,7 @@ private:
|
||||||
int buttonRelease() const { return SDL_RELEASED; }
|
int buttonRelease() const { return SDL_RELEASED; }
|
||||||
|
|
||||||
QMap<SDL_JoystickID, Joystick::Pointer> _openJoysticks;
|
QMap<SDL_JoystickID, Joystick::Pointer> _openJoysticks;
|
||||||
#endif
|
bool _isInitialized { false } ;
|
||||||
bool _isInitialized;
|
|
||||||
static const QString NAME;
|
static const QString NAME;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -134,12 +134,12 @@ void SixenseManager::setSixenseFilter(bool filter) {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void SixenseManager::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) {
|
void SixenseManager::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) {
|
||||||
BAIL_IF_NOT_LOADED
|
BAIL_IF_NOT_LOADED
|
||||||
|
|
||||||
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
||||||
userInputMapper->withLock([&, this]() {
|
userInputMapper->withLock([&, this]() {
|
||||||
_inputDevice->update(deltaTime, inputCalibrationData, jointsCaptured);
|
_inputDevice->update(deltaTime, inputCalibrationData);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (_inputDevice->_requestReset) {
|
if (_inputDevice->_requestReset) {
|
||||||
|
@ -148,7 +148,7 @@ void SixenseManager::pluginUpdate(float deltaTime, const controller::InputCalibr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void SixenseManager::InputDevice::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) {
|
void SixenseManager::InputDevice::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) {
|
||||||
BAIL_IF_NOT_LOADED
|
BAIL_IF_NOT_LOADED
|
||||||
#ifdef HAVE_SIXENSE
|
#ifdef HAVE_SIXENSE
|
||||||
_buttonPressedMap.clear();
|
_buttonPressedMap.clear();
|
||||||
|
@ -208,14 +208,10 @@ void SixenseManager::InputDevice::update(float deltaTime, const controller::Inpu
|
||||||
_axisStateMap[left ? LY : RY] = data->joystick_y;
|
_axisStateMap[left ? LY : RY] = data->joystick_y;
|
||||||
_axisStateMap[left ? LT : RT] = data->trigger;
|
_axisStateMap[left ? LT : RT] = data->trigger;
|
||||||
|
|
||||||
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, inputCalibrationData, 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 {
|
|
||||||
_poseStateMap.clear();
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
auto hand = left ? controller::StandardPoseChannel::LEFT_HAND : controller::StandardPoseChannel::RIGHT_HAND;
|
auto hand = left ? controller::StandardPoseChannel::LEFT_HAND : controller::StandardPoseChannel::RIGHT_HAND;
|
||||||
_poseStateMap[hand] = controller::Pose();
|
_poseStateMap[hand] = controller::Pose();
|
||||||
|
|
|
@ -28,7 +28,6 @@ class SixenseManager : public InputPlugin {
|
||||||
public:
|
public:
|
||||||
// Plugin functions
|
// Plugin functions
|
||||||
virtual bool isSupported() const override;
|
virtual bool isSupported() const override;
|
||||||
virtual bool isJointController() const override { return true; }
|
|
||||||
virtual const QString& getName() const override { return NAME; }
|
virtual const QString& getName() const override { return NAME; }
|
||||||
virtual const QString& getID() const override { return HYDRA_ID_STRING; }
|
virtual const QString& getID() const override { return HYDRA_ID_STRING; }
|
||||||
|
|
||||||
|
@ -36,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, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override;
|
virtual void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override;
|
||||||
|
|
||||||
virtual void saveSettings() const override;
|
virtual void saveSettings() const override;
|
||||||
virtual void loadSettings() override;
|
virtual void loadSettings() override;
|
||||||
|
@ -61,7 +60,7 @@ 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, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override;
|
virtual void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override;
|
||||||
virtual void focusOutEvent() override;
|
virtual void focusOutEvent() override;
|
||||||
|
|
||||||
void handleButtonEvent(unsigned int buttons, bool left);
|
void handleButtonEvent(unsigned int buttons, bool left);
|
||||||
|
|
18
plugins/hifiSpacemouse/CMakeLists.txt
Normal file
18
plugins/hifiSpacemouse/CMakeLists.txt
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
#
|
||||||
|
# Created by Bradley Austin Davis on 2016/05/11
|
||||||
|
# Copyright 2013-2016 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
|
||||||
|
#
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
set(TARGET_NAME hifiSpacemouse)
|
||||||
|
find_package(3DCONNEXIONCLIENT)
|
||||||
|
if (3DCONNEXIONCLIENT_FOUND)
|
||||||
|
setup_hifi_plugin(Script Qml Widgets)
|
||||||
|
link_hifi_libraries(shared networking controllers ui plugins input-plugins)
|
||||||
|
target_include_directories(${TARGET_NAME} PUBLIC ${3DCONNEXIONCLIENT_INCLUDE_DIRS})
|
||||||
|
target_link_libraries(${TARGET_NAME} ${3DCONNEXIONCLIENT_LIBRARIES})
|
||||||
|
endif()
|
||||||
|
endif()
|
|
@ -11,19 +11,75 @@
|
||||||
|
|
||||||
#include "SpacemouseManager.h"
|
#include "SpacemouseManager.h"
|
||||||
|
|
||||||
|
#ifdef Q_OS_WIN
|
||||||
|
#include <VersionHelpers.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include <UserActivityLogger.h>
|
#include <UserActivityLogger.h>
|
||||||
#include <PathUtils.h>
|
#include <PathUtils.h>
|
||||||
|
|
||||||
#include <plugins/PluginContainer.h>
|
#include <plugins/PluginContainer.h>
|
||||||
#include <controllers/UserInputMapper.h>
|
#include <controllers/UserInputMapper.h>
|
||||||
|
|
||||||
#include "../../../interface/src/Menu.h"
|
const QString SpacemouseManager::NAME { "Spacemouse" };
|
||||||
|
|
||||||
const float MAX_AXIS = 75.0f; // max forward = 2x speed
|
const float MAX_AXIS = 75.0f; // max forward = 2x speed
|
||||||
|
#define LOGITECH_VENDOR_ID 0x46d
|
||||||
|
|
||||||
static std::shared_ptr<SpacemouseDevice> instance = std::make_shared<SpacemouseDevice>();
|
#ifndef RIDEV_DEVNOTIFY
|
||||||
|
#define RIDEV_DEVNOTIFY 0x00002000
|
||||||
|
#endif
|
||||||
|
|
||||||
SpacemouseDevice::SpacemouseDevice() : InputDevice("Spacemouse")
|
const int TRACE_RIDI_DEVICENAME = 0;
|
||||||
|
const int TRACE_RIDI_DEVICEINFO = 0;
|
||||||
|
|
||||||
|
#ifdef _WIN64
|
||||||
|
typedef unsigned __int64 QWORD;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool Is3dmouseAttached();
|
||||||
|
|
||||||
|
std::shared_ptr<SpacemouseDevice> instance;
|
||||||
|
|
||||||
|
bool SpacemouseManager::isSupported() const {
|
||||||
|
return Is3dmouseAttached();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool SpacemouseManager::activate() {
|
||||||
|
fLast3dmouseInputTime = 0;
|
||||||
|
|
||||||
|
InitializeRawInput(GetActiveWindow());
|
||||||
|
|
||||||
|
QAbstractEventDispatcher::instance()->installNativeEventFilter(this);
|
||||||
|
|
||||||
|
if (!instance) {
|
||||||
|
instance = std::make_shared<SpacemouseDevice>();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (instance->getDeviceID() == controller::Input::INVALID_DEVICE) {
|
||||||
|
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
||||||
|
userInputMapper->registerDevice(instance);
|
||||||
|
UserActivityLogger::getInstance().connectedDevice("controller", NAME);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpacemouseManager::deactivate() {
|
||||||
|
QAbstractEventDispatcher::instance()->removeNativeEventFilter(this);
|
||||||
|
int deviceid = instance->getDeviceID();
|
||||||
|
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
||||||
|
userInputMapper->removeDevice(deviceid);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpacemouseManager::pluginFocusOutEvent() {
|
||||||
|
instance->focusOutEvent();
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpacemouseManager::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
SpacemouseDevice::SpacemouseDevice() : InputDevice(SpacemouseManager::NAME)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,71 +167,78 @@ 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, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) {
|
void SpacemouseDevice::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) {
|
||||||
// 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
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpacemouseManager::ManagerFocusOutEvent() {
|
|
||||||
instance->focusOutEvent();
|
|
||||||
}
|
|
||||||
|
|
||||||
void SpacemouseManager::init() {
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef HAVE_3DCONNEXIONCLIENT
|
|
||||||
|
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
|
|
||||||
#include <VersionHelpers.h>
|
bool SpacemouseManager::nativeEventFilter(const QByteArray& eventType, void* message, long* result) {
|
||||||
|
MSG* msg = static_cast< MSG * >(message);
|
||||||
void SpacemouseManager::toggleSpacemouse(bool shouldEnable) {
|
return RawInputEventFilter(message, result);
|
||||||
if (shouldEnable) {
|
|
||||||
init();
|
|
||||||
}
|
|
||||||
if (!shouldEnable && instance->getDeviceID() != controller::Input::INVALID_DEVICE) {
|
|
||||||
destroy();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpacemouseManager::init() {
|
|
||||||
if (Menu::getInstance()->isOptionChecked(MenuOption::Connexion)) {
|
|
||||||
fLast3dmouseInputTime = 0;
|
|
||||||
|
|
||||||
InitializeRawInput(GetActiveWindow());
|
//Get an initialized array of PRAWINPUTDEVICE for the 3D devices
|
||||||
|
//pNumDevices returns the number of devices to register. Currently this is always 1.
|
||||||
|
static PRAWINPUTDEVICE GetDevicesToRegister(unsigned int* pNumDevices) {
|
||||||
|
// Array of raw input devices to register
|
||||||
|
static RAWINPUTDEVICE sRawInputDevices[] = {
|
||||||
|
{ 0x01, 0x08, 0x00, 0x00 } // Usage Page = 0x01 Generic Desktop Page, Usage Id= 0x08 Multi-axis Controller
|
||||||
|
};
|
||||||
|
|
||||||
QAbstractEventDispatcher::instance()->installNativeEventFilter(this);
|
if (pNumDevices) {
|
||||||
|
*pNumDevices = sizeof(sRawInputDevices) / sizeof(sRawInputDevices[0]);
|
||||||
|
}
|
||||||
|
|
||||||
if (instance->getDeviceID() != controller::Input::INVALID_DEVICE) {
|
return sRawInputDevices;
|
||||||
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
}
|
||||||
userInputMapper->registerDevice(instance);
|
|
||||||
UserActivityLogger::getInstance().connectedDevice("controller", "Spacemouse");
|
|
||||||
|
//Detect the 3D mouse
|
||||||
|
bool Is3dmouseAttached() {
|
||||||
|
unsigned int numDevicesOfInterest = 0;
|
||||||
|
PRAWINPUTDEVICE devicesToRegister = GetDevicesToRegister(&numDevicesOfInterest);
|
||||||
|
|
||||||
|
unsigned int nDevices = 0;
|
||||||
|
|
||||||
|
if (::GetRawInputDeviceList(NULL, &nDevices, sizeof(RAWINPUTDEVICELIST)) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nDevices == 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<RAWINPUTDEVICELIST> rawInputDeviceList(nDevices);
|
||||||
|
if (::GetRawInputDeviceList(&rawInputDeviceList[0], &nDevices, sizeof(RAWINPUTDEVICELIST)) == static_cast<unsigned int>(-1)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < nDevices; ++i) {
|
||||||
|
RID_DEVICE_INFO rdi = { sizeof(rdi) };
|
||||||
|
unsigned int cbSize = sizeof(rdi);
|
||||||
|
|
||||||
|
if (GetRawInputDeviceInfo(rawInputDeviceList[i].hDevice, RIDI_DEVICEINFO, &rdi, &cbSize) > 0) {
|
||||||
|
//skip non HID and non logitec (3DConnexion) devices
|
||||||
|
if (rdi.dwType != RIM_TYPEHID || rdi.hid.dwVendorId != LOGITECH_VENDOR_ID) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
//check if devices matches Multi-axis Controller
|
||||||
|
for (unsigned int j = 0; j < numDevicesOfInterest; ++j) {
|
||||||
|
if (devicesToRegister[j].usUsage == rdi.hid.usUsage
|
||||||
|
&& devicesToRegister[j].usUsagePage == rdi.hid.usUsagePage) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpacemouseManager::destroy() {
|
|
||||||
QAbstractEventDispatcher::instance()->removeNativeEventFilter(this);
|
|
||||||
int deviceid = instance->getDeviceID();
|
|
||||||
auto userInputMapper = DependencyManager::get<UserInputMapper>();
|
|
||||||
userInputMapper->removeDevice(deviceid);
|
|
||||||
}
|
|
||||||
|
|
||||||
#define LOGITECH_VENDOR_ID 0x46d
|
|
||||||
|
|
||||||
#ifndef RIDEV_DEVNOTIFY
|
|
||||||
#define RIDEV_DEVNOTIFY 0x00002000
|
|
||||||
#endif
|
|
||||||
|
|
||||||
const int TRACE_RIDI_DEVICENAME = 0;
|
|
||||||
const int TRACE_RIDI_DEVICEINFO = 0;
|
|
||||||
|
|
||||||
#ifdef _WIN64
|
|
||||||
typedef unsigned __int64 QWORD;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// object angular velocity per mouse tick 0.008 milliradians per second per count
|
// object angular velocity per mouse tick 0.008 milliradians per second per count
|
||||||
static const double k3dmouseAngularVelocity = 8.0e-6; // radians per second per count
|
static const double k3dmouseAngularVelocity = 8.0e-6; // radians per second per count
|
||||||
|
|
||||||
|
@ -290,20 +353,9 @@ bool SpacemouseManager::RawInputEventFilter(void* msg, long* result) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Access the mouse parameters structure
|
|
||||||
I3dMouseParam& SpacemouseManager::MouseParams() {
|
|
||||||
return f3dMouseParams;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Access the mouse parameters structure
|
|
||||||
const I3dMouseParam& SpacemouseManager::MouseParams() const {
|
|
||||||
return f3dMouseParams;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Called with the processed motion data when a 3D mouse event is received
|
//Called with the processed motion data when a 3D mouse event is received
|
||||||
void SpacemouseManager::Move3d(HANDLE device, std::vector<float>& motionData) {
|
void SpacemouseManager::Move3d(HANDLE device, std::vector<float>& motionData) {
|
||||||
Q_UNUSED(device);
|
Q_UNUSED(device);
|
||||||
|
|
||||||
instance->cc_position = { motionData[0] * 1000, motionData[1] * 1000, motionData[2] * 1000 };
|
instance->cc_position = { motionData[0] * 1000, motionData[1] * 1000, motionData[2] * 1000 };
|
||||||
instance->cc_rotation = { motionData[3] * 1500, motionData[4] * 1500, motionData[5] * 1500 };
|
instance->cc_rotation = { motionData[3] * 1500, motionData[4] * 1500, motionData[5] * 1500 };
|
||||||
instance->handleAxisEvent();
|
instance->handleAxisEvent();
|
||||||
|
@ -321,62 +373,6 @@ void SpacemouseManager::On3dmouseKeyUp(HANDLE device, int virtualKeyCode) {
|
||||||
instance->setButton(0);
|
instance->setButton(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Get an initialized array of PRAWINPUTDEVICE for the 3D devices
|
|
||||||
//pNumDevices returns the number of devices to register. Currently this is always 1.
|
|
||||||
static PRAWINPUTDEVICE GetDevicesToRegister(unsigned int* pNumDevices) {
|
|
||||||
// Array of raw input devices to register
|
|
||||||
static RAWINPUTDEVICE sRawInputDevices[] = {
|
|
||||||
{ 0x01, 0x08, 0x00, 0x00 } // Usage Page = 0x01 Generic Desktop Page, Usage Id= 0x08 Multi-axis Controller
|
|
||||||
};
|
|
||||||
|
|
||||||
if (pNumDevices) {
|
|
||||||
*pNumDevices = sizeof(sRawInputDevices) / sizeof(sRawInputDevices[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return sRawInputDevices;
|
|
||||||
}
|
|
||||||
|
|
||||||
//Detect the 3D mouse
|
|
||||||
bool SpacemouseManager::Is3dmouseAttached() {
|
|
||||||
unsigned int numDevicesOfInterest = 0;
|
|
||||||
PRAWINPUTDEVICE devicesToRegister = GetDevicesToRegister(&numDevicesOfInterest);
|
|
||||||
|
|
||||||
unsigned int nDevices = 0;
|
|
||||||
|
|
||||||
if (::GetRawInputDeviceList(NULL, &nDevices, sizeof(RAWINPUTDEVICELIST)) != 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (nDevices == 0) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<RAWINPUTDEVICELIST> rawInputDeviceList(nDevices);
|
|
||||||
if (::GetRawInputDeviceList(&rawInputDeviceList[0], &nDevices, sizeof(RAWINPUTDEVICELIST)) == static_cast<unsigned int>(-1)) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (unsigned int i = 0; i < nDevices; ++i) {
|
|
||||||
RID_DEVICE_INFO rdi = { sizeof(rdi) };
|
|
||||||
unsigned int cbSize = sizeof(rdi);
|
|
||||||
|
|
||||||
if (GetRawInputDeviceInfo(rawInputDeviceList[i].hDevice, RIDI_DEVICEINFO, &rdi, &cbSize) > 0) {
|
|
||||||
//skip non HID and non logitec (3DConnexion) devices
|
|
||||||
if (rdi.dwType != RIM_TYPEHID || rdi.hid.dwVendorId != LOGITECH_VENDOR_ID) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
//check if devices matches Multi-axis Controller
|
|
||||||
for (unsigned int j = 0; j < numDevicesOfInterest; ++j) {
|
|
||||||
if (devicesToRegister[j].usUsage == rdi.hid.usUsage
|
|
||||||
&& devicesToRegister[j].usUsagePage == rdi.hid.usUsagePage) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize the window to recieve raw-input messages
|
// Initialize the window to recieve raw-input messages
|
||||||
// This needs to be called initially so that Windows will send the messages from the 3D mouse to the window.
|
// This needs to be called initially so that Windows will send the messages from the 3D mouse to the window.
|
||||||
|
@ -942,5 +938,3 @@ void MessageHandler(unsigned int connection, unsigned int messageType, void *mes
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __APPLE__
|
#endif // __APPLE__
|
||||||
|
|
||||||
#endif
|
|
|
@ -17,22 +17,8 @@
|
||||||
#include <controllers/InputDevice.h>
|
#include <controllers/InputDevice.h>
|
||||||
#include <controllers/StandardControls.h>
|
#include <controllers/StandardControls.h>
|
||||||
|
|
||||||
#include "InputPlugin.h"
|
#include <plugins/InputPlugin.h>
|
||||||
|
|
||||||
#ifndef HAVE_3DCONNEXIONCLIENT
|
|
||||||
class SpacemouseManager : public QObject {
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
void ManagerFocusOutEvent();
|
|
||||||
void init();
|
|
||||||
void destroy() {};
|
|
||||||
bool Is3dmouseAttached() { return false; };
|
|
||||||
public slots:
|
|
||||||
void toggleSpacemouse(bool shouldEnable) {};
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef HAVE_3DCONNEXIONCLIENT
|
|
||||||
// the windows connexion rawinput
|
// the windows connexion rawinput
|
||||||
#ifdef Q_OS_WIN
|
#ifdef Q_OS_WIN
|
||||||
|
|
||||||
|
@ -85,42 +71,26 @@ private:
|
||||||
Speed fSpeed;
|
Speed fSpeed;
|
||||||
};
|
};
|
||||||
|
|
||||||
class SpacemouseManager : public QObject, public QAbstractNativeEventFilter {
|
class SpacemouseManager : public InputPlugin, public QAbstractNativeEventFilter {
|
||||||
|
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
SpacemouseManager() {};
|
bool isSupported() const override;
|
||||||
|
const QString& getName() const override { return NAME; }
|
||||||
|
const QString& getID() const override { return NAME; }
|
||||||
|
|
||||||
void init();
|
bool activate() override;
|
||||||
void destroy();
|
void deactivate() override;
|
||||||
bool Is3dmouseAttached();
|
|
||||||
|
|
||||||
SpacemouseManager* client;
|
void pluginFocusOutEvent() override;
|
||||||
|
void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override;
|
||||||
|
|
||||||
void ManagerFocusOutEvent();
|
bool nativeEventFilter(const QByteArray& eventType, void* message, long* result) override;
|
||||||
|
|
||||||
I3dMouseParam& MouseParams();
|
|
||||||
const I3dMouseParam& MouseParams() const;
|
|
||||||
|
|
||||||
virtual void Move3d(HANDLE device, std::vector<float>& motionData);
|
|
||||||
virtual void On3dmouseKeyDown(HANDLE device, int virtualKeyCode);
|
|
||||||
virtual void On3dmouseKeyUp(HANDLE device, int virtualKeyCode);
|
|
||||||
|
|
||||||
virtual bool nativeEventFilter(const QByteArray& eventType, void* message, long* result) Q_DECL_OVERRIDE
|
|
||||||
{
|
|
||||||
MSG* msg = static_cast< MSG * >(message);
|
|
||||||
return RawInputEventFilter(message, result);
|
|
||||||
}
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void toggleSpacemouse(bool shouldEnable);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void Move3d(std::vector<float>& motionData);
|
|
||||||
void On3dmouseKeyDown(int virtualKeyCode);
|
|
||||||
void On3dmouseKeyUp(int virtualKeyCode);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void Move3d(HANDLE device, std::vector<float>& motionData);
|
||||||
|
void On3dmouseKeyDown(HANDLE device, int virtualKeyCode);
|
||||||
|
void On3dmouseKeyUp(HANDLE device, int virtualKeyCode);
|
||||||
bool InitializeRawInput(HWND hwndTarget);
|
bool InitializeRawInput(HWND hwndTarget);
|
||||||
|
|
||||||
bool RawInputEventFilter(void* msg, long* result);
|
bool RawInputEventFilter(void* msg, long* result);
|
||||||
|
@ -156,6 +126,9 @@ private:
|
||||||
|
|
||||||
// use to calculate distance traveled since last event
|
// use to calculate distance traveled since last event
|
||||||
DWORD fLast3dmouseInputTime;
|
DWORD fLast3dmouseInputTime;
|
||||||
|
|
||||||
|
static const QString NAME;
|
||||||
|
friend class SpacemouseDevice;
|
||||||
};
|
};
|
||||||
|
|
||||||
// the osx connexion api
|
// the osx connexion api
|
||||||
|
@ -176,8 +149,6 @@ public:
|
||||||
|
|
||||||
#endif // __APPLE__
|
#endif // __APPLE__
|
||||||
|
|
||||||
#endif
|
|
||||||
|
|
||||||
|
|
||||||
// connnects to the userinputmapper
|
// connnects to the userinputmapper
|
||||||
class SpacemouseDevice : public QObject, public controller::InputDevice {
|
class SpacemouseDevice : public QObject, public controller::InputDevice {
|
||||||
|
@ -214,7 +185,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, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override;
|
virtual void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override;
|
||||||
virtual void focusOutEvent() override;
|
virtual void focusOutEvent() override;
|
||||||
|
|
||||||
glm::vec3 cc_position;
|
glm::vec3 cc_position;
|
45
plugins/hifiSpacemouse/src/SpacemouseProvider.cpp
Normal file
45
plugins/hifiSpacemouse/src/SpacemouseProvider.cpp
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
//
|
||||||
|
// Created by Bradley Austin Davis on 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 <mutex>
|
||||||
|
|
||||||
|
#include <QtCore/QObject>
|
||||||
|
#include <QtCore/QtPlugin>
|
||||||
|
#include <QtCore/QStringList>
|
||||||
|
|
||||||
|
#include <plugins/RuntimePlugin.h>
|
||||||
|
#include <plugins/InputPlugin.h>
|
||||||
|
|
||||||
|
#include "SpacemouseManager.h"
|
||||||
|
|
||||||
|
class SpacemouseProvider : public QObject, public InputProvider
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PLUGIN_METADATA(IID InputProvider_iid FILE "plugin.json")
|
||||||
|
Q_INTERFACES(InputProvider)
|
||||||
|
|
||||||
|
public:
|
||||||
|
SpacemouseProvider(QObject* parent = nullptr) : QObject(parent) {}
|
||||||
|
virtual ~SpacemouseProvider() {}
|
||||||
|
|
||||||
|
virtual InputPluginList getInputPlugins() override {
|
||||||
|
static std::once_flag once;
|
||||||
|
std::call_once(once, [&] {
|
||||||
|
InputPluginPointer plugin(new SpacemouseManager());
|
||||||
|
if (plugin->isSupported()) {
|
||||||
|
_inputPlugins.push_back(plugin);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return _inputPlugins;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
InputPluginList _inputPlugins;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "SpacemouseProvider.moc"
|
1
plugins/hifiSpacemouse/src/plugin.json
Normal file
1
plugins/hifiSpacemouse/src/plugin.json
Normal file
|
@ -0,0 +1 @@
|
||||||
|
{}
|
|
@ -76,12 +76,12 @@ void OculusControllerManager::deactivate() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void OculusControllerManager::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) {
|
void OculusControllerManager::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) {
|
||||||
PerformanceTimer perfTimer("OculusControllerManager::TouchDevice::update");
|
PerformanceTimer perfTimer("OculusControllerManager::TouchDevice::update");
|
||||||
|
|
||||||
if (_touch) {
|
if (_touch) {
|
||||||
if (OVR_SUCCESS(ovr_GetInputState(_session, ovrControllerType_Touch, &_inputState))) {
|
if (OVR_SUCCESS(ovr_GetInputState(_session, ovrControllerType_Touch, &_inputState))) {
|
||||||
_touch->update(deltaTime, inputCalibrationData, jointsCaptured);
|
_touch->update(deltaTime, inputCalibrationData);
|
||||||
} else {
|
} else {
|
||||||
qCWarning(oculus) << "Unable to read Oculus touch input state";
|
qCWarning(oculus) << "Unable to read Oculus touch input state";
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,7 @@ void OculusControllerManager::pluginUpdate(float deltaTime, const controller::In
|
||||||
|
|
||||||
if (_remote) {
|
if (_remote) {
|
||||||
if (OVR_SUCCESS(ovr_GetInputState(_session, ovrControllerType_Remote, &_inputState))) {
|
if (OVR_SUCCESS(ovr_GetInputState(_session, ovrControllerType_Remote, &_inputState))) {
|
||||||
_remote->update(deltaTime, inputCalibrationData, jointsCaptured);
|
_remote->update(deltaTime, inputCalibrationData);
|
||||||
} else {
|
} else {
|
||||||
qCWarning(oculus) << "Unable to read Oculus remote input state";
|
qCWarning(oculus) << "Unable to read Oculus remote input state";
|
||||||
}
|
}
|
||||||
|
@ -158,7 +158,7 @@ QString OculusControllerManager::RemoteDevice::getDefaultMappingConfig() const {
|
||||||
return MAPPING_JSON;
|
return MAPPING_JSON;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OculusControllerManager::RemoteDevice::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) {
|
void OculusControllerManager::RemoteDevice::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) {
|
||||||
_buttonPressedMap.clear();
|
_buttonPressedMap.clear();
|
||||||
const auto& inputState = _parent._inputState;
|
const auto& inputState = _parent._inputState;
|
||||||
for (const auto& pair : BUTTON_MAP) {
|
for (const auto& pair : BUTTON_MAP) {
|
||||||
|
@ -172,21 +172,19 @@ void OculusControllerManager::RemoteDevice::focusOutEvent() {
|
||||||
_buttonPressedMap.clear();
|
_buttonPressedMap.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void OculusControllerManager::TouchDevice::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) {
|
void OculusControllerManager::TouchDevice::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) {
|
||||||
_poseStateMap.clear();
|
_poseStateMap.clear();
|
||||||
_buttonPressedMap.clear();
|
_buttonPressedMap.clear();
|
||||||
|
|
||||||
if (!jointsCaptured) {
|
int numTrackedControllers = 0;
|
||||||
int numTrackedControllers = 0;
|
static const auto REQUIRED_HAND_STATUS = ovrStatus_OrientationTracked & ovrStatus_PositionTracked;
|
||||||
static const auto REQUIRED_HAND_STATUS = ovrStatus_OrientationTracked & ovrStatus_PositionTracked;
|
auto tracking = ovr_GetTrackingState(_parent._session, 0, false);
|
||||||
auto tracking = ovr_GetTrackingState(_parent._session, 0, false);
|
ovr_for_each_hand([&](ovrHandType hand) {
|
||||||
ovr_for_each_hand([&](ovrHandType hand) {
|
++numTrackedControllers;
|
||||||
++numTrackedControllers;
|
if (REQUIRED_HAND_STATUS == (tracking.HandStatusFlags[hand] & REQUIRED_HAND_STATUS)) {
|
||||||
if (REQUIRED_HAND_STATUS == (tracking.HandStatusFlags[hand] & REQUIRED_HAND_STATUS)) {
|
handlePose(deltaTime, inputCalibrationData, hand, tracking.HandPoses[hand]);
|
||||||
handlePose(deltaTime, inputCalibrationData, hand, tracking.HandPoses[hand]);
|
}
|
||||||
}
|
});
|
||||||
});
|
|
||||||
}
|
|
||||||
using namespace controller;
|
using namespace controller;
|
||||||
// Axes
|
// Axes
|
||||||
const auto& inputState = _parent._inputState;
|
const auto& inputState = _parent._inputState;
|
||||||
|
|
|
@ -24,14 +24,13 @@ class OculusControllerManager : public InputPlugin {
|
||||||
public:
|
public:
|
||||||
// Plugin functions
|
// Plugin functions
|
||||||
bool isSupported() const override;
|
bool isSupported() const override;
|
||||||
bool isJointController() const override { return true; }
|
|
||||||
const QString& getName() const override { return NAME; }
|
const QString& getName() const override { return NAME; }
|
||||||
|
|
||||||
bool activate() override;
|
bool activate() override;
|
||||||
void deactivate() override;
|
void deactivate() override;
|
||||||
|
|
||||||
void pluginFocusOutEvent() override;
|
void pluginFocusOutEvent() override;
|
||||||
void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override;
|
void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class OculusInputDevice : public controller::InputDevice {
|
class OculusInputDevice : public controller::InputDevice {
|
||||||
|
@ -49,7 +48,7 @@ private:
|
||||||
|
|
||||||
controller::Input::NamedVector getAvailableInputs() const override;
|
controller::Input::NamedVector getAvailableInputs() const override;
|
||||||
QString getDefaultMappingConfig() const override;
|
QString getDefaultMappingConfig() const override;
|
||||||
void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override;
|
void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override;
|
||||||
void focusOutEvent() override;
|
void focusOutEvent() override;
|
||||||
|
|
||||||
friend class OculusControllerManager;
|
friend class OculusControllerManager;
|
||||||
|
@ -62,7 +61,7 @@ private:
|
||||||
|
|
||||||
controller::Input::NamedVector getAvailableInputs() const override;
|
controller::Input::NamedVector getAvailableInputs() const override;
|
||||||
QString getDefaultMappingConfig() const override;
|
QString getDefaultMappingConfig() const override;
|
||||||
void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override;
|
void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override;
|
||||||
void focusOutEvent() override;
|
void focusOutEvent() override;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -9,7 +9,6 @@
|
||||||
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include <QtCore/QProcessEnvironment>
|
|
||||||
#include <QMainWindow>
|
#include <QMainWindow>
|
||||||
#include <QLoggingCategory>
|
#include <QLoggingCategory>
|
||||||
#include <QGLWidget>
|
#include <QGLWidget>
|
||||||
|
@ -30,10 +29,6 @@ Q_DECLARE_LOGGING_CATEGORY(displayplugins)
|
||||||
const QString OpenVrDisplayPlugin::NAME("OpenVR (Vive)");
|
const QString OpenVrDisplayPlugin::NAME("OpenVR (Vive)");
|
||||||
const QString StandingHMDSensorMode = "Standing HMD Sensor Mode"; // this probably shouldn't be hardcoded here
|
const QString StandingHMDSensorMode = "Standing HMD Sensor Mode"; // this probably shouldn't be hardcoded here
|
||||||
|
|
||||||
static const QString DEBUG_FLAG("HIFI_DEBUG_OPENVR");
|
|
||||||
static bool enableDebugOpenVR = QProcessEnvironment::systemEnvironment().contains(DEBUG_FLAG);
|
|
||||||
|
|
||||||
|
|
||||||
static vr::IVRCompositor* _compositor{ nullptr };
|
static vr::IVRCompositor* _compositor{ nullptr };
|
||||||
vr::TrackedDevicePose_t _trackedDevicePose[vr::k_unMaxTrackedDeviceCount];
|
vr::TrackedDevicePose_t _trackedDevicePose[vr::k_unMaxTrackedDeviceCount];
|
||||||
mat4 _trackedDevicePoseMat4[vr::k_unMaxTrackedDeviceCount];
|
mat4 _trackedDevicePoseMat4[vr::k_unMaxTrackedDeviceCount];
|
||||||
|
@ -43,7 +38,7 @@ static mat4 _sensorResetMat;
|
||||||
static std::array<vr::Hmd_Eye, 2> VR_EYES { { vr::Eye_Left, vr::Eye_Right } };
|
static std::array<vr::Hmd_Eye, 2> VR_EYES { { vr::Eye_Left, vr::Eye_Right } };
|
||||||
|
|
||||||
bool OpenVrDisplayPlugin::isSupported() const {
|
bool OpenVrDisplayPlugin::isSupported() const {
|
||||||
return (enableDebugOpenVR || !isOculusPresent()) && vr::VR_IsHmdPresent();
|
return openVrSupported();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool OpenVrDisplayPlugin::internalActivate() {
|
bool OpenVrDisplayPlugin::internalActivate() {
|
||||||
|
|
|
@ -13,6 +13,7 @@
|
||||||
#include <QtCore/QDebug>
|
#include <QtCore/QDebug>
|
||||||
#include <QtCore/QTimer>
|
#include <QtCore/QTimer>
|
||||||
#include <QtCore/QLoggingCategory>
|
#include <QtCore/QLoggingCategory>
|
||||||
|
#include <QtCore/QProcessEnvironment>
|
||||||
|
|
||||||
#include <Windows.h>
|
#include <Windows.h>
|
||||||
|
|
||||||
|
@ -44,6 +45,12 @@ bool isOculusPresent() {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool openVrSupported() {
|
||||||
|
static const QString DEBUG_FLAG("HIFI_DEBUG_OPENVR");
|
||||||
|
static bool enableDebugOpenVR = QProcessEnvironment::systemEnvironment().contains(DEBUG_FLAG);
|
||||||
|
return (enableDebugOpenVR || !isOculusPresent()) && vr::VR_IsHmdPresent();
|
||||||
|
}
|
||||||
|
|
||||||
vr::IVRSystem* acquireOpenVrSystem() {
|
vr::IVRSystem* acquireOpenVrSystem() {
|
||||||
bool hmdPresent = vr::VR_IsHmdPresent();
|
bool hmdPresent = vr::VR_IsHmdPresent();
|
||||||
if (hmdPresent) {
|
if (hmdPresent) {
|
||||||
|
|
|
@ -12,7 +12,8 @@
|
||||||
#include <glm/gtc/type_ptr.hpp>
|
#include <glm/gtc/type_ptr.hpp>
|
||||||
#include <glm/gtc/matrix_transform.hpp>
|
#include <glm/gtc/matrix_transform.hpp>
|
||||||
|
|
||||||
bool isOculusPresent();
|
bool openVrSupported();
|
||||||
|
|
||||||
vr::IVRSystem* acquireOpenVrSystem();
|
vr::IVRSystem* acquireOpenVrSystem();
|
||||||
void releaseOpenVrSystem();
|
void releaseOpenVrSystem();
|
||||||
|
|
||||||
|
|
|
@ -50,11 +50,9 @@ static const QString MENU_PATH = MENU_PARENT + ">" + MENU_NAME;
|
||||||
static const QString RENDER_CONTROLLERS = "Render Hand Controllers";
|
static const QString RENDER_CONTROLLERS = "Render Hand Controllers";
|
||||||
|
|
||||||
const QString ViveControllerManager::NAME = "OpenVR";
|
const QString ViveControllerManager::NAME = "OpenVR";
|
||||||
static const QString DEBUG_FLAG("HIFI_DEBUG_OPENVR");
|
|
||||||
static bool enableDebugOpenVR = QProcessEnvironment::systemEnvironment().contains(DEBUG_FLAG);
|
|
||||||
|
|
||||||
bool ViveControllerManager::isSupported() const {
|
bool ViveControllerManager::isSupported() const {
|
||||||
return (enableDebugOpenVR || !isOculusPresent()) && vr::VR_IsHmdPresent();
|
return openVrSupported();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ViveControllerManager::activate() {
|
bool ViveControllerManager::activate() {
|
||||||
|
@ -214,12 +212,12 @@ void ViveControllerManager::renderHand(const controller::Pose& pose, gpu::Batch&
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ViveControllerManager::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) {
|
void ViveControllerManager::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) {
|
||||||
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
||||||
|
|
||||||
// because update mutates the internal state we need to lock
|
// because update mutates the internal state we need to lock
|
||||||
userInputMapper->withLock([&, this]() {
|
userInputMapper->withLock([&, this]() {
|
||||||
_inputDevice->update(deltaTime, inputCalibrationData, jointsCaptured);
|
_inputDevice->update(deltaTime, inputCalibrationData);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (_inputDevice->_trackedControllers == 0 && _registeredWithInputMapper) {
|
if (_inputDevice->_trackedControllers == 0 && _registeredWithInputMapper) {
|
||||||
|
@ -235,7 +233,7 @@ void ViveControllerManager::pluginUpdate(float deltaTime, const controller::Inpu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViveControllerManager::InputDevice::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) {
|
void ViveControllerManager::InputDevice::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) {
|
||||||
_poseStateMap.clear();
|
_poseStateMap.clear();
|
||||||
_buttonPressedMap.clear();
|
_buttonPressedMap.clear();
|
||||||
|
|
||||||
|
@ -244,10 +242,8 @@ void ViveControllerManager::InputDevice::update(float deltaTime, const controlle
|
||||||
auto leftHandDeviceIndex = _system->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_LeftHand);
|
auto leftHandDeviceIndex = _system->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_LeftHand);
|
||||||
auto rightHandDeviceIndex = _system->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_RightHand);
|
auto rightHandDeviceIndex = _system->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_RightHand);
|
||||||
|
|
||||||
if (!jointsCaptured) {
|
handleHandController(deltaTime, leftHandDeviceIndex, inputCalibrationData, true);
|
||||||
handleHandController(deltaTime, leftHandDeviceIndex, inputCalibrationData, true);
|
handleHandController(deltaTime, rightHandDeviceIndex, inputCalibrationData, false);
|
||||||
handleHandController(deltaTime, rightHandDeviceIndex, inputCalibrationData, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
int numTrackedControllers = 0;
|
int numTrackedControllers = 0;
|
||||||
if (leftHandDeviceIndex != vr::k_unTrackedDeviceIndexInvalid) {
|
if (leftHandDeviceIndex != vr::k_unTrackedDeviceIndexInvalid) {
|
||||||
|
|
|
@ -31,17 +31,15 @@ namespace vr {
|
||||||
class ViveControllerManager : public InputPlugin {
|
class ViveControllerManager : public InputPlugin {
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
|
|
||||||
// Plugin functions
|
// Plugin functions
|
||||||
virtual bool isSupported() const override;
|
bool isSupported() const override;
|
||||||
virtual bool isJointController() const override { return true; }
|
|
||||||
const QString& getName() const override { return NAME; }
|
const QString& getName() const override { return NAME; }
|
||||||
|
|
||||||
virtual bool activate() override;
|
bool activate() override;
|
||||||
virtual void deactivate() override;
|
void deactivate() override;
|
||||||
|
|
||||||
virtual void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); }
|
void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); }
|
||||||
virtual void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override;
|
void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override;
|
||||||
|
|
||||||
void updateRendering(RenderArgs* args, render::ScenePointer scene, render::PendingChanges pendingChanges);
|
void updateRendering(RenderArgs* args, render::ScenePointer scene, render::PendingChanges pendingChanges);
|
||||||
|
|
||||||
|
@ -53,10 +51,10 @@ private:
|
||||||
InputDevice(vr::IVRSystem*& system) : controller::InputDevice("Vive"), _system(system) {}
|
InputDevice(vr::IVRSystem*& system) : controller::InputDevice("Vive"), _system(system) {}
|
||||||
private:
|
private:
|
||||||
// Device functions
|
// Device functions
|
||||||
virtual controller::Input::NamedVector getAvailableInputs() const override;
|
controller::Input::NamedVector getAvailableInputs() const override;
|
||||||
virtual QString getDefaultMappingConfig() const override;
|
QString getDefaultMappingConfig() const override;
|
||||||
virtual void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override;
|
void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override;
|
||||||
virtual void focusOutEvent() override;
|
void focusOutEvent() override;
|
||||||
|
|
||||||
void handleHandController(float deltaTime, uint32_t deviceIndex, const controller::InputCalibrationData& inputCalibrationData, bool isLeftHand);
|
void handleHandController(float deltaTime, uint32_t deviceIndex, const controller::InputCalibrationData& inputCalibrationData, bool isLeftHand);
|
||||||
void handleButtonEvent(float deltaTime, uint32_t button, bool pressed, bool touched, bool isLeftHand);
|
void handleButtonEvent(float deltaTime, uint32_t button, bool pressed, bool touched, bool isLeftHand);
|
||||||
|
|
|
@ -1112,8 +1112,8 @@ function MyController(hand) {
|
||||||
Controller.getPoseValue((this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand);
|
Controller.getPoseValue((this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand);
|
||||||
|
|
||||||
// transform it into world frame
|
// transform it into world frame
|
||||||
var controllerPosition = Vec3.sum(MyAvatar.position,
|
var controllerPositionVSAvatar = Vec3.multiplyQbyV(MyAvatar.orientation, avatarControllerPose.translation);
|
||||||
Vec3.multiplyQbyV(MyAvatar.orientation, avatarControllerPose.translation));
|
var controllerPosition = Vec3.sum(MyAvatar.position, controllerPositionVSAvatar);
|
||||||
var controllerRotation = Quat.multiply(MyAvatar.orientation, avatarControllerPose.rotation);
|
var controllerRotation = Quat.multiply(MyAvatar.orientation, avatarControllerPose.rotation);
|
||||||
|
|
||||||
var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, GRABBABLE_PROPERTIES);
|
var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, GRABBABLE_PROPERTIES);
|
||||||
|
@ -1161,7 +1161,7 @@ function MyController(hand) {
|
||||||
|
|
||||||
this.turnOffVisualizations();
|
this.turnOffVisualizations();
|
||||||
|
|
||||||
this.previousControllerPosition = controllerPosition;
|
this.previousControllerPositionVSAvatar = controllerPositionVSAvatar;
|
||||||
this.previousControllerRotation = controllerRotation;
|
this.previousControllerRotation = controllerRotation;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1179,8 +1179,8 @@ function MyController(hand) {
|
||||||
Controller.Standard.RightHand : Controller.Standard.LeftHand);
|
Controller.Standard.RightHand : Controller.Standard.LeftHand);
|
||||||
|
|
||||||
// transform it into world frame
|
// transform it into world frame
|
||||||
var controllerPosition = Vec3.sum(MyAvatar.position,
|
var controllerPositionVSAvatar = Vec3.multiplyQbyV(MyAvatar.orientation, avatarControllerPose.translation);
|
||||||
Vec3.multiplyQbyV(MyAvatar.orientation, avatarControllerPose.translation));
|
var controllerPosition = Vec3.sum(MyAvatar.position, controllerPositionVSAvatar);
|
||||||
var controllerRotation = Quat.multiply(MyAvatar.orientation, avatarControllerPose.rotation);
|
var controllerRotation = Quat.multiply(MyAvatar.orientation, avatarControllerPose.rotation);
|
||||||
|
|
||||||
var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, GRABBABLE_PROPERTIES);
|
var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, GRABBABLE_PROPERTIES);
|
||||||
|
@ -1197,7 +1197,8 @@ function MyController(hand) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// scale delta controller hand movement by radius.
|
// scale delta controller hand movement by radius.
|
||||||
var handMoved = Vec3.multiply(Vec3.subtract(controllerPosition, this.previousControllerPosition), radius);
|
var handMoved = Vec3.multiply(Vec3.subtract(controllerPositionVSAvatar, this.previousControllerPositionVSAvatar),
|
||||||
|
radius);
|
||||||
|
|
||||||
// double delta controller rotation
|
// double delta controller rotation
|
||||||
var handChange = Quat.multiply(Quat.slerp(this.previousControllerRotation,
|
var handChange = Quat.multiply(Quat.slerp(this.previousControllerRotation,
|
||||||
|
@ -1218,7 +1219,7 @@ function MyController(hand) {
|
||||||
var handControllerData = getEntityCustomData('handControllerKey', this.grabbedEntity, defaultMoveWithHeadData);
|
var handControllerData = getEntityCustomData('handControllerKey', this.grabbedEntity, defaultMoveWithHeadData);
|
||||||
|
|
||||||
// Update radialVelocity
|
// Update radialVelocity
|
||||||
var lastVelocity = Vec3.subtract(controllerPosition, this.previousControllerPosition);
|
var lastVelocity = Vec3.subtract(controllerPositionVSAvatar, this.previousControllerPositionVSAvatar);
|
||||||
lastVelocity = Vec3.multiply(lastVelocity, 1.0 / deltaTime);
|
lastVelocity = Vec3.multiply(lastVelocity, 1.0 / deltaTime);
|
||||||
var newRadialVelocity = Vec3.dot(lastVelocity,
|
var newRadialVelocity = Vec3.dot(lastVelocity,
|
||||||
Vec3.normalize(Vec3.subtract(grabbedProperties.position, controllerPosition)));
|
Vec3.normalize(Vec3.subtract(grabbedProperties.position, controllerPosition)));
|
||||||
|
@ -1266,7 +1267,9 @@ function MyController(hand) {
|
||||||
var clampedVector;
|
var clampedVector;
|
||||||
var targetPosition;
|
var targetPosition;
|
||||||
if (constraintData.axisStart !== false) {
|
if (constraintData.axisStart !== false) {
|
||||||
clampedVector = this.projectVectorAlongAxis(this.currentObjectPosition, constraintData.axisStart, constraintData.axisEnd);
|
clampedVector = this.projectVectorAlongAxis(this.currentObjectPosition,
|
||||||
|
constraintData.axisStart,
|
||||||
|
constraintData.axisEnd);
|
||||||
targetPosition = clampedVector;
|
targetPosition = clampedVector;
|
||||||
} else {
|
} else {
|
||||||
targetPosition = {
|
targetPosition = {
|
||||||
|
@ -1309,7 +1312,7 @@ function MyController(hand) {
|
||||||
print("continueDistanceHolding -- updateAction failed");
|
print("continueDistanceHolding -- updateAction failed");
|
||||||
}
|
}
|
||||||
|
|
||||||
this.previousControllerPosition = controllerPosition;
|
this.previousControllerPositionVSAvatar = controllerPositionVSAvatar;
|
||||||
this.previousControllerRotation = controllerRotation;
|
this.previousControllerRotation = controllerRotation;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -484,6 +484,9 @@
|
||||||
var elZoneSkyboxColorGreen = document.getElementById("property-zone-skybox-color-green");
|
var elZoneSkyboxColorGreen = document.getElementById("property-zone-skybox-color-green");
|
||||||
var elZoneSkyboxColorBlue = document.getElementById("property-zone-skybox-color-blue");
|
var elZoneSkyboxColorBlue = document.getElementById("property-zone-skybox-color-blue");
|
||||||
var elZoneSkyboxURL = document.getElementById("property-zone-skybox-url");
|
var elZoneSkyboxURL = document.getElementById("property-zone-skybox-url");
|
||||||
|
|
||||||
|
var elZoneFlyingAllowed = document.getElementById("property-zone-flying-allowed");
|
||||||
|
var elZoneGhostingAllowed = document.getElementById("property-zone-ghosting-allowed");
|
||||||
|
|
||||||
var elPolyVoxSections = document.querySelectorAll(".poly-vox-section");
|
var elPolyVoxSections = document.querySelectorAll(".poly-vox-section");
|
||||||
allSections.push(elPolyVoxSections);
|
allSections.push(elPolyVoxSections);
|
||||||
|
@ -626,18 +629,19 @@
|
||||||
var parsedUserData = {}
|
var parsedUserData = {}
|
||||||
try {
|
try {
|
||||||
parsedUserData = JSON.parse(properties.userData);
|
parsedUserData = JSON.parse(properties.userData);
|
||||||
|
|
||||||
|
if ("grabbableKey" in parsedUserData) {
|
||||||
|
if ("grabbable" in parsedUserData["grabbableKey"]) {
|
||||||
|
elGrabbable.checked = parsedUserData["grabbableKey"].grabbable;
|
||||||
|
}
|
||||||
|
if ("wantsTrigger" in parsedUserData["grabbableKey"]) {
|
||||||
|
elWantsTrigger.checked = parsedUserData["grabbableKey"].wantsTrigger;
|
||||||
|
}
|
||||||
|
if ("ignoreIK" in parsedUserData["grabbableKey"]) {
|
||||||
|
elIgnoreIK.checked = parsedUserData["grabbableKey"].ignoreIK;
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch(e) {}
|
} catch(e) {}
|
||||||
if ("grabbableKey" in parsedUserData) {
|
|
||||||
if ("grabbable" in parsedUserData["grabbableKey"]) {
|
|
||||||
elGrabbable.checked = parsedUserData["grabbableKey"].grabbable;
|
|
||||||
}
|
|
||||||
if ("wantsTrigger" in parsedUserData["grabbableKey"]) {
|
|
||||||
elWantsTrigger.checked = parsedUserData["grabbableKey"].wantsTrigger;
|
|
||||||
}
|
|
||||||
if ("ignoreIK" in parsedUserData["grabbableKey"]) {
|
|
||||||
elIgnoreIK.checked = parsedUserData["grabbableKey"].ignoreIK;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
elCollisionSoundURL.value = properties.collisionSoundURL;
|
elCollisionSoundURL.value = properties.collisionSoundURL;
|
||||||
elLifetime.value = properties.lifetime;
|
elLifetime.value = properties.lifetime;
|
||||||
|
@ -770,6 +774,9 @@
|
||||||
elZoneSkyboxColorGreen.value = properties.skybox.color.green;
|
elZoneSkyboxColorGreen.value = properties.skybox.color.green;
|
||||||
elZoneSkyboxColorBlue.value = properties.skybox.color.blue;
|
elZoneSkyboxColorBlue.value = properties.skybox.color.blue;
|
||||||
elZoneSkyboxURL.value = properties.skybox.url;
|
elZoneSkyboxURL.value = properties.skybox.url;
|
||||||
|
|
||||||
|
elZoneFlyingAllowed.checked = properties.flyingAllowed;
|
||||||
|
elZoneGhostingAllowed.checked = properties.ghostingAllowed;
|
||||||
|
|
||||||
showElements(document.getElementsByClassName('skybox-section'), elZoneBackgroundMode.value == 'skybox');
|
showElements(document.getElementsByClassName('skybox-section'), elZoneBackgroundMode.value == 'skybox');
|
||||||
} else if (properties.type == "PolyVox") {
|
} else if (properties.type == "PolyVox") {
|
||||||
|
@ -1076,7 +1083,10 @@
|
||||||
}));
|
}));
|
||||||
|
|
||||||
elZoneSkyboxURL.addEventListener('change', createEmitGroupTextPropertyUpdateFunction('skybox','url'));
|
elZoneSkyboxURL.addEventListener('change', createEmitGroupTextPropertyUpdateFunction('skybox','url'));
|
||||||
|
|
||||||
|
elZoneFlyingAllowed.addEventListener('change', createEmitCheckedPropertyUpdateFunction('flyingAllowed'));
|
||||||
|
elZoneGhostingAllowed.addEventListener('change', createEmitCheckedPropertyUpdateFunction('ghostingAllowed'));
|
||||||
|
|
||||||
var voxelVolumeSizeChangeFunction = createEmitVec3PropertyUpdateFunction(
|
var voxelVolumeSizeChangeFunction = createEmitVec3PropertyUpdateFunction(
|
||||||
'voxelVolumeSize', elVoxelVolumeSizeX, elVoxelVolumeSizeY, elVoxelVolumeSizeZ);
|
'voxelVolumeSize', elVoxelVolumeSizeX, elVoxelVolumeSizeY, elVoxelVolumeSizeZ);
|
||||||
elVoxelVolumeSizeX.addEventListener('change', voxelVolumeSizeChangeFunction);
|
elVoxelVolumeSizeX.addEventListener('change', voxelVolumeSizeChangeFunction);
|
||||||
|
@ -1791,6 +1801,15 @@
|
||||||
<input type="text" id="property-zone-skybox-url">
|
<input type="text" id="property-zone-skybox-url">
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="zone-group zone-section property checkbox">
|
||||||
|
<input type="checkbox" id="property-zone-flying-allowed">
|
||||||
|
<label for="property-zone-flying-allowed"> Flying Allowed</label>
|
||||||
|
</div>
|
||||||
|
<div class="zone-group zone-section property checkbox">
|
||||||
|
<input type="checkbox" id="property-zone-ghosting-allowed">
|
||||||
|
<label for="property-zone-ghosting-allowed"> Ghosting Allowed</label>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
<div class="section-header web-group web-section">
|
<div class="section-header web-group web-section">
|
||||||
<label>Web</label><span>M</span>
|
<label>Web</label><span>M</span>
|
||||||
|
|
|
@ -121,7 +121,7 @@ int main(int argc, char** argv) {
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach(auto inputPlugin, PluginManager::getInstance()->getInputPlugins()) {
|
foreach(auto inputPlugin, PluginManager::getInstance()->getInputPlugins()) {
|
||||||
inputPlugin->pluginUpdate(delta, calibrationData, false);
|
inputPlugin->pluginUpdate(delta, calibrationData);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
auto userInputMapper = DependencyManager::get<controller::UserInputMapper>();
|
||||||
|
@ -144,7 +144,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, calibrationData, false);
|
inputPlugin->pluginUpdate(0, calibrationData);
|
||||||
}
|
}
|
||||||
rootContext->setContextProperty("Controllers", new MyControllerScriptingInterface());
|
rootContext->setContextProperty("Controllers", new MyControllerScriptingInterface());
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue