From 0fe4e42511cbb67464131279ba6c44df3e209601 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 1 May 2016 13:53:44 -0700 Subject: [PATCH 01/23] added zone properties to allow flying/ghosting or not --- .../entities/src/EntityItemProperties.cpp | 27 +++++++++++++++++++ libraries/entities/src/EntityItemProperties.h | 6 +++++ libraries/entities/src/EntityPropertyFlags.h | 3 +++ libraries/entities/src/ZoneEntityItem.cpp | 24 ++++++++++++++--- libraries/entities/src/ZoneEntityItem.h | 16 ++++++++--- .../networking/src/udt/PacketHeaders.cpp | 2 +- libraries/networking/src/udt/PacketHeaders.h | 1 + scripts/system/html/entityProperties.html | 20 +++++++++++++- 8 files changed, 91 insertions(+), 8 deletions(-) diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index 92849d6e2f..feacb4ab98 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -309,6 +309,8 @@ EntityPropertyFlags EntityItemProperties::getChangedProperties() const { CHECK_PROPERTY_CHANGE(PROP_QUERY_AA_CUBE, queryAACube); CHECK_PROPERTY_CHANGE(PROP_LOCAL_POSITION, localPosition); CHECK_PROPERTY_CHANGE(PROP_LOCAL_ROTATION, localRotation); + CHECK_PROPERTY_CHANGE(PROP_FLYING_ALLOWED, flyingAllowed); + CHECK_PROPERTY_CHANGE(PROP_GHOSTING_ALLOWED, ghostingAllowed); changedProperties += _animation.getChangedProperties(); changedProperties += _keyLight.getChangedProperties(); @@ -467,6 +469,9 @@ QScriptValue EntityItemProperties::copyToScriptValue(QScriptEngine* engine, bool _stage.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 @@ -679,6 +684,9 @@ void EntityItemProperties::copyFromScriptValue(const QScriptValue& object, bool COPY_PROPERTY_FROM_QSCRIPTVALUE(jointTranslationsSet, qVectorBool, setJointTranslationsSet); COPY_PROPERTY_FROM_QSCRIPTVALUE(jointTranslations, qVectorVec3, setJointTranslations); + COPY_PROPERTY_FROM_QSCRIPTVALUE(flyingAllowed, bool, setFlyingAllowed); + COPY_PROPERTY_FROM_QSCRIPTVALUE(ghostingAllowed, bool, setGhostingAllowed); + _lastEdited = usecTimestampNow(); } @@ -849,6 +857,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_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 //ADD_PROPERTY_TO_MAP(PROP_CREATED, Created, created, quint64); @@ -1089,6 +1100,9 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem _staticSkybox.setProperties(properties); _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) { @@ -1373,6 +1387,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_BACKGROUND_MODE, BackgroundMode, setBackgroundMode); 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) { @@ -1564,6 +1581,9 @@ void EntityItemProperties::markAllChanged() { _jointTranslationsChanged = true; _queryAACubeChanged = true; + + _flyingAllowedChanged = true; + _ghostingAllowedChanged = true; } // The minimum bounding box for the entity. @@ -1885,6 +1905,13 @@ QList EntityItemProperties::listChangedProperties() { out += "queryAACube"; } + if (flyingAllowedChanged()) { + out += "flyingAllowed"; + } + if (ghostingAllowedChanged()) { + out += "ghostingAllowed"; + } + getAnimation().listChangedProperties(out); getKeyLight().listChangedProperties(out); getSkybox().listChangedProperties(out); diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index 2cf31e5632..f32bc977e0 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -205,6 +205,9 @@ public: DEFINE_PROPERTY_REF(PROP_JOINT_TRANSLATIONS_SET, JointTranslationsSet, jointTranslationsSet, QVector, QVector()); DEFINE_PROPERTY_REF(PROP_JOINT_TRANSLATIONS, JointTranslations, jointTranslations, QVector, QVector()); + DEFINE_PROPERTY(PROP_FLYING_ALLOWED, FlyingAllowed, flyingAllowed, bool, ZoneEntityItem::DEFAULT_FLYING_ALLOWED); + DEFINE_PROPERTY(PROP_GHOSTING_ALLOWED, GhostingAllowed, ghostingAllowed, bool, ZoneEntityItem::DEFAULT_GHOSTING_ALLOWED); + static QString getBackgroundModeString(BackgroundMode mode); @@ -421,6 +424,9 @@ inline QDebug operator<<(QDebug debug, const EntityItemProperties& properties) { DEBUG_PROPERTY_IF_CHANGED(debug, properties, JointTranslationsSet, jointTranslationsSet, ""); DEBUG_PROPERTY_IF_CHANGED(debug, properties, JointTranslations, jointTranslations, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, FlyingAllowed, flyingAllowed, ""); + DEBUG_PROPERTY_IF_CHANGED(debug, properties, GhostingAllowed, ghostingAllowed, ""); + properties.getAnimation().debugDump(); properties.getSkybox().debugDump(); properties.getStage().debugDump(); diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index 90a7c1e2f7..19b47da8e7 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -169,6 +169,9 @@ enum EntityPropertyList { 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? + //////////////////////////////////////////////////////////////////////////////////////////////////// // ATTENTION: add new properties to end of list just ABOVE this line PROP_AFTER_LAST_ITEM, diff --git a/libraries/entities/src/ZoneEntityItem.cpp b/libraries/entities/src/ZoneEntityItem.cpp index 6aabef5cc0..a28b8210c2 100644 --- a/libraries/entities/src/ZoneEntityItem.cpp +++ b/libraries/entities/src/ZoneEntityItem.cpp @@ -23,8 +23,12 @@ bool ZoneEntityItem::_zonesArePickable = false; bool ZoneEntityItem::_drawZoneBoundaries = false; + const ShapeType ZoneEntityItem::DEFAULT_SHAPE_TYPE = SHAPE_TYPE_BOX; 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 entity { new ZoneEntityItem(entityID) }; @@ -55,6 +59,9 @@ EntityItemProperties ZoneEntityItem::getProperties(EntityPropertyFlags desiredPr _skyboxProperties.getProperties(properties); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(flyingAllowed, getFlyingAllowed); + COPY_ENTITY_PROPERTY_TO_PROPERTIES(ghostingAllowed, getGhostingAllowed); + return properties; } @@ -70,6 +77,9 @@ bool ZoneEntityItem::setProperties(const EntityItemProperties& properties) { SET_ENTITY_PROPERTY_FROM_PROPERTIES(compoundShapeURL, setCompoundShapeURL); 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); somethingChanged = somethingChanged || somethingChangedInKeyLight || somethingChangedInStage || somethingChangedInSkybox; @@ -116,6 +126,9 @@ int ZoneEntityItem::readEntitySubclassDataFromBuffer(const unsigned char* data, bytesRead += bytesFromSkybox; dataAt += bytesFromSkybox; + READ_ENTITY_PROPERTY(PROP_FLYING_ALLOWED, bool, setFlyingAllowed); + READ_ENTITY_PROPERTY(PROP_GHOSTING_ALLOWED, bool, setGhostingAllowed); + return bytesRead; } @@ -125,13 +138,16 @@ EntityPropertyFlags ZoneEntityItem::getEntityProperties(EncodeBitstreamParams& p EntityPropertyFlags requestedProperties = EntityItem::getEntityProperties(params); requestedProperties += _keyLightProperties.getEntityProperties(params); - + requestedProperties += PROP_SHAPE_TYPE; requestedProperties += PROP_COMPOUND_SHAPE_URL; requestedProperties += PROP_BACKGROUND_MODE; requestedProperties += _stageProperties.getEntityProperties(params); requestedProperties += _skyboxProperties.getEntityProperties(params); - + + requestedProperties += PROP_FLYING_ALLOWED; + requestedProperties += PROP_GHOSTING_ALLOWED; + 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_COMPOUND_SHAPE_URL, getCompoundShapeURL()); APPEND_ENTITY_PROPERTY(PROP_BACKGROUND_MODE, (uint32_t)getBackgroundMode()); // could this be a uint16?? - + _skyboxProperties.appendSubclassData(packetData, params, modelTreeElementExtraEncodeData, requestedProperties, propertyFlags, propertiesDidntFit, propertyCount, appendState); + APPEND_ENTITY_PROPERTY(PROP_FLYING_ALLOWED, getFlyingAllowed()); + APPEND_ENTITY_PROPERTY(PROP_GHOSTING_ALLOWED, getGhostingAllowed()); } void ZoneEntityItem::debugDump() const { diff --git a/libraries/entities/src/ZoneEntityItem.h b/libraries/entities/src/ZoneEntityItem.h index 0326a0f441..56968aa9c9 100644 --- a/libraries/entities/src/ZoneEntityItem.h +++ b/libraries/entities/src/ZoneEntityItem.h @@ -70,6 +70,11 @@ public: const SkyboxPropertyGroup& getSkyboxProperties() const { return _skyboxProperties; } 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 findDetailedRayIntersection(const glm::vec3& origin, const glm::vec3& direction, bool& keepSearching, OctreeElementPointer& element, float& distance, @@ -80,18 +85,23 @@ public: static const ShapeType DEFAULT_SHAPE_TYPE; static const QString DEFAULT_COMPOUND_SHAPE_URL; - + static const bool DEFAULT_FLYING_ALLOWED; + static const bool DEFAULT_GHOSTING_ALLOWED; + protected: KeyLightPropertyGroup _keyLightProperties; - + ShapeType _shapeType = DEFAULT_SHAPE_TYPE; QString _compoundShapeURL; - + BackgroundMode _backgroundMode = BACKGROUND_MODE_INHERIT; StagePropertyGroup _stageProperties; SkyboxPropertyGroup _skyboxProperties; + bool _flyingAllowed { DEFAULT_FLYING_ALLOWED }; + bool _ghostingAllowed { DEFAULT_GHOSTING_ALLOWED }; + static bool _drawZoneBoundaries; static bool _zonesArePickable; }; diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index e4aab94090..6b917df87a 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -47,7 +47,7 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::EntityAdd: case PacketType::EntityEdit: case PacketType::EntityData: - return VERSION_LIGHT_HAS_FALLOFF_RADIUS; + return VERSION_ENTITIES_NO_FLY_ZONES; case PacketType::AvatarData: case PacketType::BulkAvatarData: return static_cast(AvatarMixerPacketVersion::SoftAttachmentSupport); diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index b98a87e439..42e5fff420 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -171,6 +171,7 @@ const PacketVersion VERSION_ENTITITES_HAVE_QUERY_BOX = 54; const PacketVersion VERSION_ENTITITES_HAVE_COLLISION_MASK = 55; const PacketVersion VERSION_ATMOSPHERE_REMOVED = 56; const PacketVersion VERSION_LIGHT_HAS_FALLOFF_RADIUS = 57; +const PacketVersion VERSION_ENTITIES_NO_FLY_ZONES = 58; enum class AvatarMixerPacketVersion : PacketVersion { TranslationSupport = 17, diff --git a/scripts/system/html/entityProperties.html b/scripts/system/html/entityProperties.html index ae5684d6c8..35a78682f3 100644 --- a/scripts/system/html/entityProperties.html +++ b/scripts/system/html/entityProperties.html @@ -484,6 +484,9 @@ var elZoneSkyboxColorGreen = document.getElementById("property-zone-skybox-color-green"); var elZoneSkyboxColorBlue = document.getElementById("property-zone-skybox-color-blue"); 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"); allSections.push(elPolyVoxSections); @@ -770,6 +773,9 @@ elZoneSkyboxColorGreen.value = properties.skybox.color.green; elZoneSkyboxColorBlue.value = properties.skybox.color.blue; elZoneSkyboxURL.value = properties.skybox.url; + + elZoneFlyingAllowed.checked = properties.flyingAllowed; + elZoneGhostingAllowed.checked = properties.ghostingAllowed; showElements(document.getElementsByClassName('skybox-section'), elZoneBackgroundMode.value == 'skybox'); } else if (properties.type == "PolyVox") { @@ -1076,7 +1082,10 @@ })); elZoneSkyboxURL.addEventListener('change', createEmitGroupTextPropertyUpdateFunction('skybox','url')); - + + elZoneFlyingAllowed.addEventListener('change', createEmitCheckedPropertyUpdateFunction('flyingAllowed')); + elZoneGhostingAllowed.addEventListener('change', createEmitCheckedPropertyUpdateFunction('ghostingAllowed')); + var voxelVolumeSizeChangeFunction = createEmitVec3PropertyUpdateFunction( 'voxelVolumeSize', elVoxelVolumeSizeX, elVoxelVolumeSizeY, elVoxelVolumeSizeZ); elVoxelVolumeSizeX.addEventListener('change', voxelVolumeSizeChangeFunction); @@ -1791,6 +1800,15 @@ +
+ + +
+
+ + +
+
M From ef85cc7803b0360f04ee0196b044a409096c9e23 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 1 May 2016 14:47:12 -0700 Subject: [PATCH 02/23] hook up zone flyingAllowed flag to character controller --- interface/src/avatar/MyAvatar.cpp | 6 ++++++ .../entities-renderer/src/EntityTreeRenderer.h | 2 ++ libraries/physics/src/CharacterController.cpp | 14 ++++++++++++++ libraries/physics/src/CharacterController.h | 5 +++++ 4 files changed, 27 insertions(+) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 614f7bd9fe..e039633961 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -426,7 +426,12 @@ void MyAvatar::simulate(float deltaTime) { EntityTreeRenderer* entityTreeRenderer = qApp->getEntities(); EntityTreePointer entityTree = entityTreeRenderer ? entityTreeRenderer->getTree() : nullptr; if (entityTree) { + bool flyingAllowed = true; entityTree->withWriteLock([&] { + std::shared_ptr zone = entityTreeRenderer->myAvatarZone(); + if (zone) { + flyingAllowed = zone->getFlyingAllowed(); + } auto now = usecTimestampNow(); EntityEditPacketSender* packetSender = qApp->getEntityEditPacketSender(); MovingEntitiesOperator moveOperator(entityTree); @@ -454,6 +459,7 @@ void MyAvatar::simulate(float deltaTime) { entityTree->recurseTreeWithOperator(&moveOperator); } }); + _characterController.setFlyingAllowed(flyingAllowed); } } diff --git a/libraries/entities-renderer/src/EntityTreeRenderer.h b/libraries/entities-renderer/src/EntityTreeRenderer.h index a6fc58e5f1..3eb3796c94 100644 --- a/libraries/entities-renderer/src/EntityTreeRenderer.h +++ b/libraries/entities-renderer/src/EntityTreeRenderer.h @@ -88,6 +88,8 @@ public: // For Scene.shouldRenderEntities QList& getEntitiesLastInScene() { return _entityIDsLastInScene; } + std::shared_ptr myAvatarZone() { return _bestZone; } + signals: void mousePressOnEntity(const RayToEntityIntersectionResult& intersection, const QMouseEvent* event); void mousePressOffEntity(const RayToEntityIntersectionResult& intersection, const QMouseEvent* event); diff --git a/libraries/physics/src/CharacterController.cpp b/libraries/physics/src/CharacterController.cpp index f685aee748..b9306b67b0 100644 --- a/libraries/physics/src/CharacterController.cpp +++ b/libraries/physics/src/CharacterController.cpp @@ -294,6 +294,10 @@ void CharacterController::setState(State desiredState, const char* reason) { #else void CharacterController::setState(State desiredState) { #endif + if (!_flyingAllowed && desiredState == State::Hover) { + desiredState = State::InAir; + } + if (desiredState != _state) { #ifdef DEBUG_STATE_CHANGE qCDebug(physics) << "CharacterController::setState" << stateToStr(desiredState) << "from" << stateToStr(_state) << "," << reason; @@ -544,3 +548,13 @@ bool CharacterController::getRigidBodyLocation(glm::vec3& avatarRigidBodyPositio avatarRigidBodyRotation = bulletToGLM(worldTrans.getRotation()); return true; } + +void CharacterController::setFlyingAllowed(bool value) { + if (_flyingAllowed != value) { + _flyingAllowed = value; + + if (!_flyingAllowed && _state == State::Hover) { + SET_STATE(State::InAir, "flying not allowed"); + } + } +} diff --git a/libraries/physics/src/CharacterController.h b/libraries/physics/src/CharacterController.h index d810e904a7..eac8379ad0 100644 --- a/libraries/physics/src/CharacterController.h +++ b/libraries/physics/src/CharacterController.h @@ -98,6 +98,9 @@ public: bool getRigidBodyLocation(glm::vec3& avatarRigidBodyPosition, glm::quat& avatarRigidBodyRotation); + void setFlyingAllowed(bool value); + + protected: #ifdef DEBUG_STATE_CHANGE void setState(State state, const char* reason); @@ -147,6 +150,8 @@ protected: btRigidBody* _rigidBody { nullptr }; uint32_t _pendingFlags { 0 }; uint32_t _previousFlags { 0 }; + + bool _flyingAllowed { true }; }; #endif // hifi_CharacterControllerInterface_h From 4feb2944edaab41830588df38da2a12e788f401f Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Sun, 1 May 2016 15:27:49 -0700 Subject: [PATCH 03/23] hook up zone's ghostingAllowed flag --- interface/src/avatar/MyAvatar.cpp | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index e039633961..2513bb7849 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -427,10 +427,12 @@ void MyAvatar::simulate(float deltaTime) { EntityTreePointer entityTree = entityTreeRenderer ? entityTreeRenderer->getTree() : nullptr; if (entityTree) { bool flyingAllowed = true; + bool ghostingAllowed = true; entityTree->withWriteLock([&] { std::shared_ptr zone = entityTreeRenderer->myAvatarZone(); if (zone) { flyingAllowed = zone->getFlyingAllowed(); + ghostingAllowed = zone->getGhostingAllowed(); } auto now = usecTimestampNow(); EntityEditPacketSender* packetSender = qApp->getEntityEditPacketSender(); @@ -460,6 +462,9 @@ void MyAvatar::simulate(float deltaTime) { } }); _characterController.setFlyingAllowed(flyingAllowed); + if (!_characterController.isEnabled() && !ghostingAllowed) { + _characterController.setEnabled(true); + } } } @@ -1839,7 +1844,21 @@ void MyAvatar::updateMotionBehaviorFromMenu() { } else { _motionBehaviors &= ~AVATAR_MOTION_SCRIPTED_MOTOR_ENABLED; } - _characterController.setEnabled(menu->isOptionChecked(MenuOption::EnableCharacterController)); + + bool ghostingAllowed = true; + EntityTreeRenderer* entityTreeRenderer = qApp->getEntities(); + if (entityTreeRenderer) { + std::shared_ptr zone = entityTreeRenderer->myAvatarZone(); + if (zone) { + ghostingAllowed = zone->getGhostingAllowed(); + } + } + bool checked = menu->isOptionChecked(MenuOption::EnableCharacterController); + if (!ghostingAllowed) { + checked = true; + } + + _characterController.setEnabled(checked); } void MyAvatar::clearDriveKeys() { From c480dcfddd740a939c60e0ef477256591612e8b2 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Wed, 18 May 2016 16:26:54 -0700 Subject: [PATCH 04/23] Check thread validity after event processing --- libraries/script-engine/src/ScriptEngine.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/libraries/script-engine/src/ScriptEngine.cpp b/libraries/script-engine/src/ScriptEngine.cpp index 15e896fac4..5f68dcfbf8 100644 --- a/libraries/script-engine/src/ScriptEngine.cpp +++ b/libraries/script-engine/src/ScriptEngine.cpp @@ -294,13 +294,6 @@ void ScriptEngine::waitTillDoneRunning() { auto startedWaiting = usecTimestampNow(); 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 auto elapsedUsecs = usecTimestampNow() - startedWaiting; 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 QThread::yieldCurrentThread(); } From fff260c2b9bcadd9d1a0d5597dd34b895edc491d Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Fri, 20 May 2016 09:27:50 -0700 Subject: [PATCH 05/23] Guard against zero-sized gl buffer copy --- libraries/gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libraries/gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp b/libraries/gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp index e56d671891..ac337550ca 100644 --- a/libraries/gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp +++ b/libraries/gpu-gl/src/gpu/gl41/GL41BackendBuffer.cpp @@ -25,7 +25,7 @@ public: glBufferData(GL_ARRAY_BUFFER, _size, nullptr, GL_DYNAMIC_DRAW); glBindBuffer(GL_ARRAY_BUFFER, 0); - if (original) { + if (original && original->_size) { glBindBuffer(GL_COPY_WRITE_BUFFER, _buffer); glBindBuffer(GL_COPY_READ_BUFFER, original->_buffer); glCopyBufferSubData(GL_COPY_READ_BUFFER, GL_COPY_WRITE_BUFFER, 0, 0, original->_size); From 7866fcf78c9bd44a2e0e9979136e05ec2c56070e Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Wed, 18 May 2016 23:23:11 -0700 Subject: [PATCH 06/23] trim high-point convex hulls --- .../physics/src/PhysicalEntitySimulation.cpp | 7 +++++++ libraries/physics/src/ShapeFactory.cpp | 18 ++++++++++++++++++ libraries/shared/src/ShapeInfo.cpp | 12 ++++++++++++ libraries/shared/src/ShapeInfo.h | 1 + 4 files changed, 38 insertions(+) diff --git a/libraries/physics/src/PhysicalEntitySimulation.cpp b/libraries/physics/src/PhysicalEntitySimulation.cpp index 3fbf8ffaf5..95ae45bbb2 100644 --- a/libraries/physics/src/PhysicalEntitySimulation.cpp +++ b/libraries/physics/src/PhysicalEntitySimulation.cpp @@ -217,6 +217,13 @@ void PhysicalEntitySimulation::getObjectsToAddToPhysics(VectorOfMotionStates& re } else if (entity->isReadyToComputeShape()) { ShapeInfo shapeInfo; entity->computeShapeInfo(shapeInfo); + int numPoints = shapeInfo.getMaxNumPoints(); + const int MAX_HULL_POINTS = 42; + if (numPoints > MAX_HULL_POINTS) { + glm::vec3 p = entity->getPosition(); + qDebug() << "entity" << entity->getName() << "at <" << p.x << p.y << p.z << ">" + << "has convex hull with" << numPoints << "points"; + } btCollisionShape* shape = ObjectMotionState::getShapeManager()->getShape(shapeInfo); if (shape) { EntityMotionState* motionState = new EntityMotionState(shape, entity); diff --git a/libraries/physics/src/ShapeFactory.cpp b/libraries/physics/src/ShapeFactory.cpp index de3e9cc794..8641873540 100644 --- a/libraries/physics/src/ShapeFactory.cpp +++ b/libraries/physics/src/ShapeFactory.cpp @@ -10,6 +10,7 @@ // #include +#include #include // for MILLIMETERS_PER_METER @@ -64,6 +65,23 @@ btConvexHullShape* ShapeFactory::createConvexHull(const QVector& poin correctedPoint = (points[i] - center) * relativeScale + center; hull->addPoint(btVector3(correctedPoint[0], correctedPoint[1], correctedPoint[2]), false); } + + const int MAX_HULL_POINTS = 42; + if (points.size() > MAX_HULL_POINTS) { + // create hull approximation + btShapeHull* shapeHull = new btShapeHull(hull); + shapeHull->buildHull(margin); + btConvexHullShape* newHull = new btConvexHullShape(); + const btVector3* newPoints = shapeHull->getVertexPointer(); + for (int i = 0; i < shapeHull->numVertices(); ++i) { + newHull->addPoint(newPoints[i], false); + } + delete hull; + delete shapeHull; + hull = newHull; + qDebug() << "reduced hull with" << points.size() << "points down to" << hull->getNumPoints(); // TODO: remove after testing + } + hull->recalcLocalAabb(); return hull; } diff --git a/libraries/shared/src/ShapeInfo.cpp b/libraries/shared/src/ShapeInfo.cpp index 1d0cd56b86..0974c88e73 100644 --- a/libraries/shared/src/ShapeInfo.cpp +++ b/libraries/shared/src/ShapeInfo.cpp @@ -99,6 +99,18 @@ uint32_t ShapeInfo::getNumSubShapes() const { } 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 { const float DEFAULT_VOLUME = 1.0f; float volume = DEFAULT_VOLUME; diff --git a/libraries/shared/src/ShapeInfo.h b/libraries/shared/src/ShapeInfo.h index 79390b6680..71fa12d5b5 100644 --- a/libraries/shared/src/ShapeInfo.h +++ b/libraries/shared/src/ShapeInfo.h @@ -61,6 +61,7 @@ public: void clearPoints () { _points.clear(); } void appendToPoints (const QVector& newPoints) { _points << newPoints; } + int getMaxNumPoints() const; float computeVolume() const; From 9fae1a7edd7ea016257cda3f0239db1de900be25 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 19 May 2016 00:16:25 -0700 Subject: [PATCH 07/23] tweak log format --- libraries/physics/src/PhysicalEntitySimulation.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/libraries/physics/src/PhysicalEntitySimulation.cpp b/libraries/physics/src/PhysicalEntitySimulation.cpp index 95ae45bbb2..15296e15ab 100644 --- a/libraries/physics/src/PhysicalEntitySimulation.cpp +++ b/libraries/physics/src/PhysicalEntitySimulation.cpp @@ -221,8 +221,10 @@ void PhysicalEntitySimulation::getObjectsToAddToPhysics(VectorOfMotionStates& re const int MAX_HULL_POINTS = 42; if (numPoints > MAX_HULL_POINTS) { glm::vec3 p = entity->getPosition(); - qDebug() << "entity" << entity->getName() << "at <" << p.x << p.y << p.z << ">" - << "has convex hull with" << numPoints << "points"; + qWarning().nospace() << "convex hull with " << numPoints + << " points for entity " << entity->getName() + << " at <" << p.x << ", " << p.y << ", " << p.z << ">" + << " will be reduced"; } btCollisionShape* shape = ObjectMotionState::getShapeManager()->getShape(shapeInfo); if (shape) { From 5a826d696a8438f9ea93a772211ae45c66b4bd50 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 19 May 2016 09:14:48 -0700 Subject: [PATCH 08/23] cleanup after code review --- libraries/physics/src/PhysicalEntitySimulation.cpp | 1 - libraries/physics/src/ShapeFactory.cpp | 10 ++++------ libraries/shared/src/ShapeInfo.h | 1 + 3 files changed, 5 insertions(+), 7 deletions(-) diff --git a/libraries/physics/src/PhysicalEntitySimulation.cpp b/libraries/physics/src/PhysicalEntitySimulation.cpp index 15296e15ab..3b271f6a81 100644 --- a/libraries/physics/src/PhysicalEntitySimulation.cpp +++ b/libraries/physics/src/PhysicalEntitySimulation.cpp @@ -218,7 +218,6 @@ void PhysicalEntitySimulation::getObjectsToAddToPhysics(VectorOfMotionStates& re ShapeInfo shapeInfo; entity->computeShapeInfo(shapeInfo); int numPoints = shapeInfo.getMaxNumPoints(); - const int MAX_HULL_POINTS = 42; if (numPoints > MAX_HULL_POINTS) { glm::vec3 p = entity->getPosition(); qWarning().nospace() << "convex hull with " << numPoints diff --git a/libraries/physics/src/ShapeFactory.cpp b/libraries/physics/src/ShapeFactory.cpp index 8641873540..8c1d44b273 100644 --- a/libraries/physics/src/ShapeFactory.cpp +++ b/libraries/physics/src/ShapeFactory.cpp @@ -66,18 +66,16 @@ btConvexHullShape* ShapeFactory::createConvexHull(const QVector& poin hull->addPoint(btVector3(correctedPoint[0], correctedPoint[1], correctedPoint[2]), false); } - const int MAX_HULL_POINTS = 42; if (points.size() > MAX_HULL_POINTS) { // create hull approximation - btShapeHull* shapeHull = new btShapeHull(hull); - shapeHull->buildHull(margin); + btShapeHull shapeHull(hull); + shapeHull.buildHull(margin); btConvexHullShape* newHull = new btConvexHullShape(); - const btVector3* newPoints = shapeHull->getVertexPointer(); - for (int i = 0; i < shapeHull->numVertices(); ++i) { + const btVector3* newPoints = shapeHull.getVertexPointer(); + for (int i = 0; i < shapeHull.numVertices(); ++i) { newHull->addPoint(newPoints[i], false); } delete hull; - delete shapeHull; hull = newHull; qDebug() << "reduced hull with" << points.size() << "points down to" << hull->getNumPoints(); // TODO: remove after testing } diff --git a/libraries/shared/src/ShapeInfo.h b/libraries/shared/src/ShapeInfo.h index 71fa12d5b5..7c76703b77 100644 --- a/libraries/shared/src/ShapeInfo.h +++ b/libraries/shared/src/ShapeInfo.h @@ -21,6 +21,7 @@ #include "DoubleHashKey.h" const float MIN_SHAPE_OFFSET = 0.001f; // offsets less than 1mm will be ignored +const int MAX_HULL_POINTS = 42; enum ShapeType { SHAPE_TYPE_NONE, From f3fc00bc3a2056798cd8ed3505cd18d831d03c30 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 19 May 2016 09:20:44 -0700 Subject: [PATCH 09/23] add comment for why MAX_HULL_POINTS is 42 --- libraries/shared/src/ShapeInfo.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/shared/src/ShapeInfo.h b/libraries/shared/src/ShapeInfo.h index 7c76703b77..1632d22450 100644 --- a/libraries/shared/src/ShapeInfo.h +++ b/libraries/shared/src/ShapeInfo.h @@ -21,6 +21,9 @@ #include "DoubleHashKey.h" 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 { From 83b8ef8131a6d44b40d8e35b73921c789f08c6e3 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 19 May 2016 13:18:18 -0700 Subject: [PATCH 10/23] clean up stream formatting of vec3 and friends --- .../physics/src/PhysicalEntitySimulation.cpp | 8 ++-- libraries/shared/src/StreamUtils.cpp | 45 ++++++------------- 2 files changed, 17 insertions(+), 36 deletions(-) diff --git a/libraries/physics/src/PhysicalEntitySimulation.cpp b/libraries/physics/src/PhysicalEntitySimulation.cpp index 3b271f6a81..6806b3a398 100644 --- a/libraries/physics/src/PhysicalEntitySimulation.cpp +++ b/libraries/physics/src/PhysicalEntitySimulation.cpp @@ -219,11 +219,9 @@ void PhysicalEntitySimulation::getObjectsToAddToPhysics(VectorOfMotionStates& re entity->computeShapeInfo(shapeInfo); int numPoints = shapeInfo.getMaxNumPoints(); if (numPoints > MAX_HULL_POINTS) { - glm::vec3 p = entity->getPosition(); - qWarning().nospace() << "convex hull with " << numPoints - << " points for entity " << entity->getName() - << " at <" << p.x << ", " << p.y << ", " << p.z << ">" - << " will be reduced"; + qWarning() << "convex hull with" << numPoints + << "points for entity" << entity->getName() + << "at" << entity->getPosition() << " will be reduced"; } btCollisionShape* shape = ObjectMotionState::getShapeManager()->getShape(shapeInfo); if (shape) { diff --git a/libraries/shared/src/StreamUtils.cpp b/libraries/shared/src/StreamUtils.cpp index d4378d82b3..876de2e698 100644 --- a/libraries/shared/src/StreamUtils.cpp +++ b/libraries/shared/src/StreamUtils.cpp @@ -23,7 +23,7 @@ void StreamUtil::dump(std::ostream& s, const QByteArray& buffer) { while (i < buffer.size()) { for(int j = 0; i < buffer.size() && j < row_size; ++j) { 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; } 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) { - s << "<" << v.x << " " << v.y << " " << v.z << ">"; + s << '(' << v.x << ' ' << v.y << ' ' << v.z << ')'; return s; } 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; } std::ostream& operator<<(std::ostream& s, const glm::mat4& m) { - s << "["; + s << '['; 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; } @@ -69,54 +69,37 @@ QDataStream& operator>>(QDataStream& in, glm::quat& quaternion) { #include QDebug& operator<<(QDebug& dbg, const glm::vec2& v) { - dbg.nospace() << "{type='glm::vec2'" - ", x=" << v.x << - ", y=" << v.y << - "}"; + dbg.nospace() << '(' << v.x << ", " << v.y << ')'; return dbg; } QDebug& operator<<(QDebug& dbg, const glm::vec3& v) { - dbg.nospace() << "{type='glm::vec3'" - ", x=" << v.x << - ", y=" << v.y << - ", z=" << v.z << - "}"; + dbg.nospace() << '(' << v.x << ", " << v.y << ", " << v.z << ')'; return dbg; } QDebug& operator<<(QDebug& dbg, const glm::vec4& v) { - dbg.nospace() << "{type='glm::vec4'" - ", x=" << v.x << - ", y=" << v.y << - ", z=" << v.z << - ", w=" << v.w << - "}"; + dbg.nospace() << '(' << v.x << ", " << v.y << ", " << v.z << ", " << v.w << ')'; return dbg; } QDebug& operator<<(QDebug& dbg, const glm::quat& q) { - dbg.nospace() << "{type='glm::quat'" - ", x=" << q.x << - ", y=" << q.y << - ", z=" << q.z << - ", w=" << q.w << - "}"; + dbg.nospace() << '(' << q.x << ", " << q.y << ", " << q.z << ", " << q.w << ')'; return dbg; } QDebug& operator<<(QDebug& dbg, const glm::mat4& m) { - dbg.nospace() << "{type='glm::mat4', ["; + dbg.nospace() << '['; for (int j = 0; j < 4; ++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) { - dbg.nospace() << "["; + dbg.nospace() << "[ "; for (QVariantHash::const_iterator it = v.constBegin(); it != v.constEnd(); it++) { - dbg << it.key() << ":" << it.value(); + dbg << it.key() << ':' << it.value(); } return dbg << " ]"; } From 0353e562e4589e83322fd36a3e0f9c6c2f4e27a1 Mon Sep 17 00:00:00 2001 From: Atlante45 Date: Thu, 19 May 2016 16:55:13 -0700 Subject: [PATCH 11/23] entityProperties.html handles non object userData --- scripts/system/html/entityProperties.html | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/scripts/system/html/entityProperties.html b/scripts/system/html/entityProperties.html index ae5684d6c8..e0bcf0efec 100644 --- a/scripts/system/html/entityProperties.html +++ b/scripts/system/html/entityProperties.html @@ -626,18 +626,19 @@ var parsedUserData = {} try { 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) {} - 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; elLifetime.value = properties.lifetime; From 51c16739f2a68d7eaa33344b8b385b4919f2f5e9 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 10 May 2016 12:05:22 -0700 Subject: [PATCH 12/23] provide a getter for the place name in AddressManager --- libraries/networking/src/AddressManager.cpp | 5 +++++ libraries/networking/src/AddressManager.h | 2 ++ 2 files changed, 7 insertions(+) diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index a97f4df35d..02962b636b 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -295,10 +295,13 @@ void AddressManager::goToAddressFromObject(const QVariantMap& dataObject, const // set our current root place name to the name that came back const QString PLACE_NAME_KEY = "name"; QString placeName = rootMap[PLACE_NAME_KEY].toString(); + if (!placeName.isEmpty()) { if (setHost(placeName, trigger)) { trigger = LookupTrigger::Internal; } + + _placeName = placeName; } else { if (setHost(domainIDString, trigger)) { trigger = LookupTrigger::Internal; @@ -580,7 +583,9 @@ bool AddressManager::setHost(const QString& host, LookupTrigger trigger, quint16 bool AddressManager::setDomainInfo(const QString& hostname, quint16 port, LookupTrigger trigger) { bool hostChanged = setHost(hostname, trigger, port); + // clear any current place information _rootPlaceID = QUuid(); + _placeName.clear(); qCDebug(networking) << "Possible domain change required to connect to domain at" << hostname << "on" << port; diff --git a/libraries/networking/src/AddressManager.h b/libraries/networking/src/AddressManager.h index dd0dbd9f38..643924ff5c 100644 --- a/libraries/networking/src/AddressManager.h +++ b/libraries/networking/src/AddressManager.h @@ -58,6 +58,7 @@ public: const QString currentPath(bool withOrientation = true) const; const QUuid& getRootPlaceID() const { return _rootPlaceID; } + const QString& getPlaceName() const { return _placeName; } const QString& getHost() const { return _host; } @@ -141,6 +142,7 @@ private: QString _host; quint16 _port; + QString _placeName; QUuid _rootPlaceID; PositionGetter _positionGetter; OrientationGetter _orientationGetter; From 7110fe98eba05dd7928aef5cf259eb23dbb6ba62 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 10 May 2016 12:13:22 -0700 Subject: [PATCH 13/23] associate incoming place name with DomainServerNodeData --- domain-server/src/DomainGatekeeper.cpp | 1 + domain-server/src/DomainServerNodeData.h | 5 +++++ domain-server/src/NodeConnectionData.cpp | 1 + domain-server/src/NodeConnectionData.h | 1 + libraries/networking/src/NodeList.cpp | 3 +++ libraries/networking/src/udt/PacketHeaders.cpp | 3 +++ 6 files changed, 14 insertions(+) diff --git a/domain-server/src/DomainGatekeeper.cpp b/domain-server/src/DomainGatekeeper.cpp index 919ac37ee9..76671461d3 100644 --- a/domain-server/src/DomainGatekeeper.cpp +++ b/domain-server/src/DomainGatekeeper.cpp @@ -105,6 +105,7 @@ void DomainGatekeeper::processConnectRequestPacket(QSharedPointer(node->getLinkedData()); nodeData->setSendingSockAddr(message->getSenderSockAddr()); nodeData->setNodeInterestSet(nodeConnection.interestList.toSet()); + nodeData->setPlaceName(nodeConnection.placeName); // signal that we just connected a node so the DomainServer can get it a list // and broadcast its presence right away diff --git a/domain-server/src/DomainServerNodeData.h b/domain-server/src/DomainServerNodeData.h index cd68aa3006..3ef5415cba 100644 --- a/domain-server/src/DomainServerNodeData.h +++ b/domain-server/src/DomainServerNodeData.h @@ -56,6 +56,9 @@ public: void addOverrideForKey(const QString& key, const QString& value, const QString& overrideValue); void removeOverrideForKey(const QString& key, const QString& value); + + const QString& getPlaceName() { return _placeName; } + void setPlaceName(const QString& placeName) { _placeName; } private: QJsonObject overrideValuesIfNeeded(const QJsonObject& newStats); @@ -75,6 +78,8 @@ private: bool _isAuthenticated = true; NodeSet _nodeInterestSet; QString _nodeVersion; + + QString _placeName; }; #endif // hifi_DomainServerNodeData_h diff --git a/domain-server/src/NodeConnectionData.cpp b/domain-server/src/NodeConnectionData.cpp index 80cb5950be..eabcfaacc6 100644 --- a/domain-server/src/NodeConnectionData.cpp +++ b/domain-server/src/NodeConnectionData.cpp @@ -19,6 +19,7 @@ NodeConnectionData NodeConnectionData::fromDataStream(QDataStream& dataStream, c if (isConnectRequest) { dataStream >> newHeader.connectUUID; + dataStream >> newHeader.placeName; } dataStream >> newHeader.nodeType diff --git a/domain-server/src/NodeConnectionData.h b/domain-server/src/NodeConnectionData.h index 6b3b8eb7c1..34119ffdab 100644 --- a/domain-server/src/NodeConnectionData.h +++ b/domain-server/src/NodeConnectionData.h @@ -27,6 +27,7 @@ public: HifiSockAddr localSockAddr; HifiSockAddr senderSockAddr; QList interestList; + QString placeName; }; diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index 482d0366fd..cee6404755 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -312,6 +312,9 @@ void NodeList::sendDomainServerCheckIn() { // pack the connect UUID for this connect request packetStream << connectUUID; + + // pack the hostname information (so the domain-server can see which place name we came in on) + packetStream << DependencyManager::get()->getPlaceName(); } // pack our data to send to the domain-server diff --git a/libraries/networking/src/udt/PacketHeaders.cpp b/libraries/networking/src/udt/PacketHeaders.cpp index e4aab94090..f6ad6b2970 100644 --- a/libraries/networking/src/udt/PacketHeaders.cpp +++ b/libraries/networking/src/udt/PacketHeaders.cpp @@ -58,6 +58,9 @@ PacketVersion versionForPacketType(PacketType packetType) { case PacketType::AssetUpload: // Removal of extension from Asset requests return 18; + case PacketType::DomainConnectRequest: + // addition of referring hostname information + return 18; default: return 17; } From 3b2a9b7b98995298d44a316671c08331995e25b2 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 10 May 2016 13:02:34 -0700 Subject: [PATCH 14/23] fix set of place name on DomainServerNodeData --- domain-server/src/DomainServerNodeData.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/domain-server/src/DomainServerNodeData.h b/domain-server/src/DomainServerNodeData.h index 3ef5415cba..a14d7ff768 100644 --- a/domain-server/src/DomainServerNodeData.h +++ b/domain-server/src/DomainServerNodeData.h @@ -58,7 +58,7 @@ public: void removeOverrideForKey(const QString& key, const QString& value); const QString& getPlaceName() { return _placeName; } - void setPlaceName(const QString& placeName) { _placeName; } + void setPlaceName(const QString& placeName) { _placeName = placeName; } private: QJsonObject overrideValuesIfNeeded(const QJsonObject& newStats); From 5884e1eadd03e62d49c92a6dd7f7a222760dda56 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 10 May 2016 13:03:18 -0700 Subject: [PATCH 15/23] rename metaverse heartbeat methods --- domain-server/src/DomainServer.cpp | 10 +++++----- domain-server/src/DomainServer.h | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 0aab6b7e31..e8199317f0 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -462,7 +462,7 @@ void DomainServer::setupAutomaticNetworking() { nodeList->startSTUNPublicSocketUpdate(); } else { // send our heartbeat to data server so it knows what our network settings are - sendHeartbeatToDataServer(); + sendHeartbeatToMetaverse(); } } else { qDebug() << "Cannot enable domain-server automatic networking without a domain ID." @@ -471,7 +471,7 @@ void DomainServer::setupAutomaticNetworking() { return; } } else { - sendHeartbeatToDataServer(); + sendHeartbeatToMetaverse(); } 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; 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); } @@ -1029,11 +1029,11 @@ QJsonObject jsonForDomainSocketUpdate(const HifiSockAddr& socket) { const QString DOMAIN_UPDATE_AUTOMATIC_NETWORKING_KEY = "automatic_networking"; 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"; auto nodeList = DependencyManager::get(); diff --git a/domain-server/src/DomainServer.h b/domain-server/src/DomainServer.h index 93bb5de494..fef3221b7d 100644 --- a/domain-server/src/DomainServer.h +++ b/domain-server/src/DomainServer.h @@ -71,7 +71,7 @@ private slots: void sendPendingTransactionsToServer(); void performIPAddressUpdate(const HifiSockAddr& newPublicSockAddr); - void sendHeartbeatToDataServer() { sendHeartbeatToDataServer(QString()); } + void sendHeartbeatToMetaverse() { sendHeartbeatToMetaverse(QString()); } void sendHeartbeatToIceServer(); void handleConnectedNode(SharedNodePointer newNode); @@ -103,7 +103,7 @@ private: void setupAutomaticNetworking(); void setupICEHeartbeatForFullNetworking(); - void sendHeartbeatToDataServer(const QString& networkAddress); + void sendHeartbeatToMetaverse(const QString& networkAddress); void randomizeICEServerAddress(bool shouldTriggerHostLookup); From 7d2d60f2005e5f931bbcae12a1ab253360e80d8e Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 10 May 2016 13:08:24 -0700 Subject: [PATCH 16/23] split assigned and un-assigned nodes --- domain-server/src/DomainGatekeeper.cpp | 3 ++- domain-server/src/DomainServerNodeData.h | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/domain-server/src/DomainGatekeeper.cpp b/domain-server/src/DomainGatekeeper.cpp index 76671461d3..e974ab26f4 100644 --- a/domain-server/src/DomainGatekeeper.cpp +++ b/domain-server/src/DomainGatekeeper.cpp @@ -151,6 +151,7 @@ SharedNodePointer DomainGatekeeper::processAssignmentConnectRequest(const NodeCo nodeData->setAssignmentUUID(matchingQueuedAssignment->getUUID()); nodeData->setWalletUUID(it->second.getWalletUUID()); nodeData->setNodeVersion(it->second.getNodeVersion()); + nodeData->setWasAssigned(true); // cleanup the PendingAssignedNodeData for this assignment now that it's connecting _pendingAssignedNodes.erase(it); @@ -283,7 +284,7 @@ SharedNodePointer DomainGatekeeper::processAgentConnectRequest(const NodeConnect // set the edit rights for this user newNode->setIsAllowedEditor(isAllowedEditor); newNode->setCanRez(canRez); - + // grab the linked data for our new node so we can set the username DomainServerNodeData* nodeData = reinterpret_cast(newNode->getLinkedData()); diff --git a/domain-server/src/DomainServerNodeData.h b/domain-server/src/DomainServerNodeData.h index a14d7ff768..f95403c779 100644 --- a/domain-server/src/DomainServerNodeData.h +++ b/domain-server/src/DomainServerNodeData.h @@ -59,6 +59,9 @@ public: const QString& getPlaceName() { return _placeName; } void setPlaceName(const QString& placeName) { _placeName = placeName; } + + bool wasAssigned() const { return _wasAssigned; }; + void setWasAssigned(bool wasAssigned) { _wasAssigned = wasAssigned; } private: QJsonObject overrideValuesIfNeeded(const QJsonObject& newStats); @@ -80,6 +83,8 @@ private: QString _nodeVersion; QString _placeName; + + bool _wasAssigned { false }; }; #endif // hifi_DomainServerNodeData_h From 962066c7d10fd9f5df126002f849b298477f0c06 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 10 May 2016 13:19:38 -0700 Subject: [PATCH 17/23] send user hostname breakdown with heartbeat --- domain-server/src/DomainServer.cpp | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index e8199317f0..75f1c9f6b6 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -1056,20 +1056,34 @@ void DomainServer::sendHeartbeatToMetaverse(const QString& networkAddress) { domainObject[RESTRICTED_ACCESS_FLAG] = _settingsManager.valueOrDefaultValueForKeyPath(RESTRICTED_ACCESS_SETTINGS_KEYPATH).toBool(); - // add the number of currently connected agent users - int numConnectedAuthedUsers = 0; + // figure out the breakdown of currently connected interface clients + int numConnectedUnassigned = 0; + QJsonObject userHostnames; - nodeList->eachNode([&numConnectedAuthedUsers](const SharedNodePointer& node){ - if (node->getLinkedData() && !static_cast(node->getLinkedData())->getUsername().isEmpty()) { - ++numConnectedAuthedUsers; + static const QString DEFAULT_HOSTNAME = "*"; + + nodeList->eachNode([&numConnectedUnassigned, &userHostnames](const SharedNodePointer& node) { + if (node->getLinkedData()) { + auto nodeData = static_cast(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"; - const QString HEARTBEAT_NUM_USERS_KEY = "num_users"; + static const QString DOMAIN_HEARTBEAT_KEY = "heartbeat"; + static const QString HEARTBEAT_NUM_USERS_KEY = "num_users"; + static const QString HEARTBEAT_USER_HOSTNAMES_KEY = "user_hostnames"; 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; QString domainUpdateJSON = QString("{\"domain\": %1 }").arg(QString(QJsonDocument(domainObject).toJson())); From 5ab876114f86a715cc380c5214848a797dd9cf99 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 10 May 2016 13:47:14 -0700 Subject: [PATCH 18/23] send hostname to DS with every DS packet to handle changes --- domain-server/src/DomainGatekeeper.cpp | 4 ++-- domain-server/src/DomainServer.cpp | 3 +++ domain-server/src/NodeConnectionData.cpp | 3 +-- libraries/networking/src/NodeList.cpp | 9 ++++----- 4 files changed, 10 insertions(+), 9 deletions(-) diff --git a/domain-server/src/DomainGatekeeper.cpp b/domain-server/src/DomainGatekeeper.cpp index e974ab26f4..61cc775e08 100644 --- a/domain-server/src/DomainGatekeeper.cpp +++ b/domain-server/src/DomainGatekeeper.cpp @@ -55,9 +55,9 @@ void DomainGatekeeper::processConnectRequestPacket(QSharedPointergetSize() == 0) { return; } - + QDataStream packetStream(message->getMessage()); - + // 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()); diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index 75f1c9f6b6..cfec72a24b 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -678,6 +678,9 @@ void DomainServer::processListRequestPacket(QSharedPointer mess DomainServerNodeData* nodeData = reinterpret_cast(sendingNode->getLinkedData()); nodeData->setNodeInterestSet(nodeRequestData.interestList.toSet()); + // update the connecting hostname in case it has changed + nodeData->setPlaceName(nodeRequestData.placeName); + sendDomainListToNode(sendingNode, message->getSenderSockAddr()); } diff --git a/domain-server/src/NodeConnectionData.cpp b/domain-server/src/NodeConnectionData.cpp index eabcfaacc6..28f769298c 100644 --- a/domain-server/src/NodeConnectionData.cpp +++ b/domain-server/src/NodeConnectionData.cpp @@ -19,12 +19,11 @@ NodeConnectionData NodeConnectionData::fromDataStream(QDataStream& dataStream, c if (isConnectRequest) { dataStream >> newHeader.connectUUID; - dataStream >> newHeader.placeName; } dataStream >> newHeader.nodeType >> newHeader.publicSockAddr >> newHeader.localSockAddr - >> newHeader.interestList; + >> newHeader.interestList >> newHeader.placeName; newHeader.senderSockAddr = senderSockAddr; diff --git a/libraries/networking/src/NodeList.cpp b/libraries/networking/src/NodeList.cpp index cee6404755..c295ffc700 100644 --- a/libraries/networking/src/NodeList.cpp +++ b/libraries/networking/src/NodeList.cpp @@ -312,13 +312,12 @@ void NodeList::sendDomainServerCheckIn() { // pack the connect UUID for this connect request packetStream << connectUUID; - - // pack the hostname information (so the domain-server can see which place name we came in on) - packetStream << DependencyManager::get()->getPlaceName(); } - // pack our data to send to the domain-server - packetStream << _ownerType << _publicSockAddr << _localSockAddr << _nodeTypesOfInterest.toList(); + // pack our data to send to the domain-server including + // the hostname information (so the domain-server can see which place name we came in on) + packetStream << _ownerType << _publicSockAddr << _localSockAddr << _nodeTypesOfInterest.toList() + << DependencyManager::get()->getPlaceName(); if (!_domainHandler.isConnected()) { DataServerAccountInfo& accountInfo = accountManager->getAccountInfo(); From 33379824c8d0ad122d0e5435a9fa7c88ae59042b Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 10 May 2016 15:15:22 -0700 Subject: [PATCH 19/23] clear place name if switching to a domain ID string --- libraries/networking/src/AddressManager.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libraries/networking/src/AddressManager.cpp b/libraries/networking/src/AddressManager.cpp index 02962b636b..36d9e621a9 100644 --- a/libraries/networking/src/AddressManager.cpp +++ b/libraries/networking/src/AddressManager.cpp @@ -306,6 +306,9 @@ void AddressManager::goToAddressFromObject(const QVariantMap& dataObject, const if (setHost(domainIDString, trigger)) { 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 From 07562f72af18341b42069a12aa251c64e4e45e8e Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 11 May 2016 17:23:24 -0700 Subject: [PATCH 20/23] Doing a pass over the input plugins and controller code --- interface/CMakeLists.txt | 4 - .../resources/controllers/spacemouse.json | 4 +- interface/src/Application.cpp | 55 ++--- interface/src/Menu.cpp | 13 +- interface/src/Menu.h | 2 +- .../controllers/src/controllers/Actions.cpp | 8 - .../controllers/src/controllers/Actions.h | 10 +- .../controllers/src/controllers/InputDevice.h | 4 +- .../src/controllers/StandardController.cpp | 6 - .../src/controllers/StandardController.h | 2 - .../src/controllers/StateController.h | 5 +- .../src/input-plugins/KeyboardMouseDevice.cpp | 7 +- .../src/input-plugins/KeyboardMouseDevice.h | 11 +- libraries/plugins/src/plugins/InputPlugin.h | 4 +- plugins/hifiNeuron/CMakeLists.txt | 11 +- plugins/hifiNeuron/src/NeuronPlugin.cpp | 118 ++------- plugins/hifiNeuron/src/NeuronPlugin.h | 5 +- plugins/hifiSdl2/src/Joystick.cpp | 11 +- plugins/hifiSdl2/src/Joystick.h | 15 +- plugins/hifiSdl2/src/SDL2Manager.cpp | 34 +-- plugins/hifiSdl2/src/SDL2Manager.h | 25 +- plugins/hifiSixense/src/SixenseManager.cpp | 18 +- plugins/hifiSixense/src/SixenseManager.h | 5 +- plugins/hifiSpacemouse/CMakeLists.txt | 18 ++ .../hifiSpacemouse/src}/SpacemouseManager.cpp | 230 +++++++++--------- .../hifiSpacemouse/src}/SpacemouseManager.h | 63 ++--- .../hifiSpacemouse/src/SpacemouseProvider.cpp | 45 ++++ plugins/hifiSpacemouse/src/plugin.json | 1 + .../oculus/src/OculusControllerManager.cpp | 30 ++- plugins/oculus/src/OculusControllerManager.h | 7 +- plugins/openvr/src/OpenVrDisplayPlugin.cpp | 7 +- plugins/openvr/src/OpenVrHelpers.cpp | 7 + plugins/openvr/src/OpenVrHelpers.h | 3 +- plugins/openvr/src/ViveControllerManager.cpp | 17 +- plugins/openvr/src/ViveControllerManager.h | 20 +- tests/controllers/src/main.cpp | 4 +- 36 files changed, 333 insertions(+), 496 deletions(-) create mode 100644 plugins/hifiSpacemouse/CMakeLists.txt rename {libraries/input-plugins/src/input-plugins => plugins/hifiSpacemouse/src}/SpacemouseManager.cpp (95%) rename {libraries/input-plugins/src/input-plugins => plugins/hifiSpacemouse/src}/SpacemouseManager.h (77%) create mode 100644 plugins/hifiSpacemouse/src/SpacemouseProvider.cpp create mode 100644 plugins/hifiSpacemouse/src/plugin.json diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 4f58cf73db..4381f3321b 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -4,10 +4,6 @@ project(${TARGET_NAME}) # set a default root dir for each of our optional externals if it was not passed set(OPTIONAL_EXTERNALS "LeapMotion") -if(WIN32) - list(APPEND OPTIONAL_EXTERNALS "3DConnexionClient") -endif() - foreach(EXTERNAL ${OPTIONAL_EXTERNALS}) string(TOUPPER ${EXTERNAL} ${EXTERNAL}_UPPERCASE) if (NOT ${${EXTERNAL}_UPPERCASE}_ROOT_DIR) diff --git a/interface/resources/controllers/spacemouse.json b/interface/resources/controllers/spacemouse.json index adcfef71a6..1480e1957d 100644 --- a/interface/resources/controllers/spacemouse.json +++ b/interface/resources/controllers/spacemouse.json @@ -2,11 +2,11 @@ "name": "Spacemouse to Standard", "channels": [ - { "from": "Spacemouse.TranslateX", "to": "Standard.RX" }, + { "from": "Spacemouse.TranslateX", "to": "Standard.LX" }, { "from": "Spacemouse.TranslateY", "to": "Standard.LY" }, { "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.RightButton", "to": "Standard.RB" } diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 6190de5875..8ebb9a1f9d 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -108,7 +108,6 @@ #include "audio/AudioScope.h" #include "avatar/AvatarManager.h" #include "CrashHandler.h" -#include "input-plugins/SpacemouseManager.h" #include "devices/DdeFaceTracker.h" #include "devices/EyeTracker.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 INPUT_DEVICE_MENU_PREFIX = "Device: "; Setting::Handle maxOctreePacketsPerSecond("maxOctreePPS", DEFAULT_MAX_OCTREE_PPS); const QHash Application::_acceptedExtensions { @@ -997,7 +997,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : RenderableWebEntityItem* webEntity = dynamic_cast(entity.get()); if (webEntity) { webEntity->setProxyWindow(_window->windowHandle()); - if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) { + if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) { _keyboardMouseDevice->pluginFocusOutEvent(); } _keyboardFocusedItem = entityItemID; @@ -1121,7 +1121,7 @@ void Application::aboutToQuit() { emit beforeAboutToQuit(); foreach(auto inputPlugin, PluginManager::getInstance()->getInputPlugins()) { - QString name = inputPlugin->getName(); + QString name = INPUT_DEVICE_MENU_PREFIX + inputPlugin->getName(); QAction* action = Menu::getInstance()->getActionForOption(name); if (action->isChecked()) { inputPlugin->deactivate(); @@ -1440,8 +1440,7 @@ void Application::initializeUi() { // This will set up the input plugins UI _activeInputPlugins.clear(); foreach(auto inputPlugin, PluginManager::getInstance()->getInputPlugins()) { - QString name = inputPlugin->getName(); - if (name == KeyboardMouseDevice::NAME) { + if (KeyboardMouseDevice::NAME == inputPlugin->getName()) { _keyboardMouseDevice = std::dynamic_pointer_cast(inputPlugin); } } @@ -1985,7 +1984,7 @@ void Application::keyPressEvent(QKeyEvent* event) { } if (hasFocus()) { - if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) { + if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) { _keyboardMouseDevice->keyPressEvent(event); } @@ -2319,7 +2318,7 @@ void Application::keyReleaseEvent(QKeyEvent* event) { return; } - if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) { + if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) { _keyboardMouseDevice->keyReleaseEvent(event); } @@ -2351,7 +2350,7 @@ void Application::keyReleaseEvent(QKeyEvent* event) { void Application::focusOutEvent(QFocusEvent* event) { auto inputPlugins = PluginManager::getInstance()->getInputPlugins(); foreach(auto inputPlugin, inputPlugins) { - QString name = inputPlugin->getName(); + QString name = INPUT_DEVICE_MENU_PREFIX + inputPlugin->getName(); QAction* action = Menu::getInstance()->getActionForOption(name); if (action && action->isChecked()) { inputPlugin->pluginFocusOutEvent(); @@ -2438,7 +2437,7 @@ void Application::mouseMoveEvent(QMouseEvent* event) { return; } - if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) { + if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) { _keyboardMouseDevice->mouseMoveEvent(event); } @@ -2475,7 +2474,7 @@ void Application::mousePressEvent(QMouseEvent* event) { if (hasFocus()) { - if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) { + if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) { _keyboardMouseDevice->mousePressEvent(event); } @@ -2520,7 +2519,7 @@ void Application::mouseReleaseEvent(QMouseEvent* event) { } if (hasFocus()) { - if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) { + if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) { _keyboardMouseDevice->mouseReleaseEvent(event); } @@ -2547,7 +2546,7 @@ void Application::touchUpdateEvent(QTouchEvent* event) { return; } - if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) { + if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) { _keyboardMouseDevice->touchUpdateEvent(event); } } @@ -2565,7 +2564,7 @@ void Application::touchBeginEvent(QTouchEvent* event) { return; } - if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) { + if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) { _keyboardMouseDevice->touchBeginEvent(event); } @@ -2582,7 +2581,7 @@ void Application::touchEndEvent(QTouchEvent* event) { return; } - if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) { + if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) { _keyboardMouseDevice->touchEndEvent(event); } @@ -2598,7 +2597,7 @@ void Application::wheelEvent(QWheelEvent* event) const { return; } - if (Menu::getInstance()->isOptionChecked(KeyboardMouseDevice::NAME)) { + if (Menu::getInstance()->isOptionChecked(INPUT_DEVICE_MENU_PREFIX + KeyboardMouseDevice::NAME)) { _keyboardMouseDevice->wheelEvent(event); } } @@ -2730,7 +2729,7 @@ void Application::idle() { getActiveDisplayPlugin()->idle(); auto inputPlugins = PluginManager::getInstance()->getInputPlugins(); foreach(auto inputPlugin, inputPlugins) { - QString name = inputPlugin->getName(); + QString name = INPUT_DEVICE_MENU_PREFIX + inputPlugin->getName(); QAction* action = Menu::getInstance()->getActionForOption(name); if (action && action->isChecked()) { inputPlugin->idle(); @@ -3373,22 +3372,18 @@ void Application::update(float deltaTime) { }; InputPluginPointer keyboardMousePlugin; - bool jointsCaptured = false; for (auto inputPlugin : PluginManager::getInstance()->getInputPlugins()) { if (inputPlugin->getName() == KeyboardMouseDevice::NAME) { keyboardMousePlugin = inputPlugin; } else if (inputPlugin->isActive()) { - inputPlugin->pluginUpdate(deltaTime, calibrationData, jointsCaptured); - if (inputPlugin->isJointController()) { - jointsCaptured = true; - } + inputPlugin->pluginUpdate(deltaTime, calibrationData); } } userInputMapper->update(deltaTime); if (keyboardMousePlugin && keyboardMousePlugin->isActive()) { - keyboardMousePlugin->pluginUpdate(deltaTime, calibrationData, jointsCaptured); + keyboardMousePlugin->pluginUpdate(deltaTime, calibrationData); } _controllerScriptingInterface->updateInputControllers(); @@ -5150,21 +5145,23 @@ void Application::updateDisplayMode() { 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(); - QString name = inputPlugin->getName(); + QString name = INPUT_DEVICE_MENU_PREFIX + inputPlugin->getName(); Q_ASSERT(!menu->menuItemExists(MenuOption::InputMenu, name)); static QActionGroup* inputPluginGroup = nullptr; if (!inputPluginGroup) { inputPluginGroup = new QActionGroup(menu); + inputPluginGroup->setExclusive(false); } + auto parent = menu->getMenu(MenuOption::InputMenu); auto action = menu->addCheckableActionToQMenuAndActionHash(parent, - name, 0, active, qApp, + name, 0, true, qApp, SLOT(updateInputModes())); + inputPluginGroup->addAction(action); - inputPluginGroup->setExclusive(false); Q_ASSERT(menu->menuItemExists(MenuOption::InputMenu, name)); } @@ -5174,10 +5171,8 @@ void Application::updateInputModes() { auto inputPlugins = PluginManager::getInstance()->getInputPlugins(); static std::once_flag once; std::call_once(once, [&] { - bool first = true; foreach(auto inputPlugin, inputPlugins) { - addInputPluginToMenu(inputPlugin, first); - first = false; + addInputPluginToMenu(inputPlugin); } }); auto offscreenUi = DependencyManager::get(); @@ -5185,7 +5180,7 @@ void Application::updateInputModes() { InputPluginList newInputPlugins; InputPluginList removedInputPlugins; foreach(auto inputPlugin, inputPlugins) { - QString name = inputPlugin->getName(); + QString name = INPUT_DEVICE_MENU_PREFIX + inputPlugin->getName(); QAction* action = menu->getActionForOption(name); auto it = std::find(std::begin(_activeInputPlugins), std::end(_activeInputPlugins), inputPlugin); diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 8b69bb8022..f946553b55 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -34,7 +34,6 @@ #include "avatar/AvatarManager.h" #include "devices/DdeFaceTracker.h" #include "devices/Faceshift.h" -#include "input-plugins/SpacemouseManager.h" #include "MainWindow.h" #include "render/DrawStatus.h" #include "scripting/MenuScriptingInterface.h" @@ -327,12 +326,6 @@ Menu::Menu() { connect(speechRecognizer.data(), SIGNAL(enabledUpdated(bool)), speechRecognizerAction, SLOT(setChecked(bool))); #endif - // Settings > Input Devices - MenuWrapper* inputModeMenu = addMenu(MenuOption::InputMenu, "Advanced"); - QActionGroup* inputModeGroup = new QActionGroup(inputModeMenu); - inputModeGroup->setExclusive(false); - - // Developer menu ---------------------------------- MenuWrapper* developerMenu = addMenu("Developer", "Developer"); @@ -410,6 +403,12 @@ Menu::Menu() { // Developer > 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 MenuWrapper* faceTrackingMenu = avatarDebugMenu->addMenu("Face Tracking"); { diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 484be9f346..7230ac2157 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -114,7 +114,7 @@ namespace MenuOption { const QString Help = "Help..."; const QString IncreaseAvatarSize = "Increase Avatar Size"; 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 LeapMotionOnHMD = "Leap Motion on HMD"; const QString LoadScript = "Open and Run Script File..."; diff --git a/libraries/controllers/src/controllers/Actions.cpp b/libraries/controllers/src/controllers/Actions.cpp index dba856cbaa..79ff4ecbf8 100644 --- a/libraries/controllers/src/controllers/Actions.cpp +++ b/libraries/controllers/src/controllers/Actions.cpp @@ -121,16 +121,8 @@ namespace controller { return availableInputs; } - void ActionsDevice::update(float deltaTime, const InputCalibrationData& inpuCalibrationData, bool jointsCaptured) { - } - - void ActionsDevice::focusOutEvent() { - } - ActionsDevice::ActionsDevice() : InputDevice("Actions") { _deviceID = UserInputMapper::ACTIONS_DEVICE; } - ActionsDevice::~ActionsDevice() {} - } diff --git a/libraries/controllers/src/controllers/Actions.h b/libraries/controllers/src/controllers/Actions.h index efdc45cb3d..724d17d951 100644 --- a/libraries/controllers/src/controllers/Actions.h +++ b/libraries/controllers/src/controllers/Actions.h @@ -109,13 +109,11 @@ class ActionsDevice : public QObject, public InputDevice { Q_PROPERTY(QString name READ getName) 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(); - virtual ~ActionsDevice(); + + EndpointPointer createEndpoint(const Input& input) const override; + Input::NamedVector getAvailableInputs() const override; + }; } diff --git a/libraries/controllers/src/controllers/InputDevice.h b/libraries/controllers/src/controllers/InputDevice.h index 93247965bc..afb1f7d1f7 100644 --- a/libraries/controllers/src/controllers/InputDevice.h +++ b/libraries/controllers/src/controllers/InputDevice.h @@ -57,9 +57,9 @@ public: // Update call MUST be called once per simulation loop // 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; } void setDeviceID(int deviceID) { _deviceID = deviceID; } diff --git a/libraries/controllers/src/controllers/StandardController.cpp b/libraries/controllers/src/controllers/StandardController.cpp index 5996cad5df..a9d317d407 100644 --- a/libraries/controllers/src/controllers/StandardController.cpp +++ b/libraries/controllers/src/controllers/StandardController.cpp @@ -22,12 +22,6 @@ StandardController::StandardController() : InputDevice("Standard") { _deviceID = UserInputMapper::STANDARD_DEVICE; } -StandardController::~StandardController() { -} - -void StandardController::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) { -} - void StandardController::focusOutEvent() { _axisStateMap.clear(); _buttonPressedMap.clear(); diff --git a/libraries/controllers/src/controllers/StandardController.h b/libraries/controllers/src/controllers/StandardController.h index fee608f822..58c3ecaa30 100644 --- a/libraries/controllers/src/controllers/StandardController.h +++ b/libraries/controllers/src/controllers/StandardController.h @@ -28,11 +28,9 @@ public: virtual EndpointPointer createEndpoint(const Input& input) const override; virtual Input::NamedVector getAvailableInputs() const override; virtual QStringList getDefaultMappingConfigs() const override; - virtual void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override; virtual void focusOutEvent() override; StandardController(); - virtual ~StandardController(); }; } diff --git a/libraries/controllers/src/controllers/StateController.h b/libraries/controllers/src/controllers/StateController.h index 57414c3ae8..c18c9df27c 100644 --- a/libraries/controllers/src/controllers/StateController.h +++ b/libraries/controllers/src/controllers/StateController.h @@ -35,10 +35,7 @@ public: const QString& getName() const { return _name; } // Device functions - virtual Input::NamedVector getAvailableInputs() const override; - - void update(float deltaTime, const InputCalibrationData& inputCalibrationData, bool jointsCaptured) override {} - void focusOutEvent() override {} + Input::NamedVector getAvailableInputs() const override; void setInputVariant(const QString& name, ReadLambda lambda); diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp index 4c0240eaf7..915ec1db87 100644 --- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp +++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp @@ -20,11 +20,10 @@ 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(); 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 @@ -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(); } diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h index 67d9ccb1b2..a66cc7060b 100644 --- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h +++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.h @@ -65,12 +65,11 @@ public: }; // Plugin functions - virtual bool isSupported() const override { return true; } - virtual bool isJointController() const override { return false; } - virtual const QString& getName() const override { return NAME; } + bool isSupported() const override { return true; } + const QString& getName() const override { return NAME; } - virtual void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); } - virtual void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override; + void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); } + void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override; void keyPressEvent(QKeyEvent* event); void keyReleaseEvent(QKeyEvent* event); @@ -97,7 +96,7 @@ protected: // Device functions virtual controller::Input::NamedVector getAvailableInputs() 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; // Let's make it easy for Qt because we assume we love Qt forever diff --git a/libraries/plugins/src/plugins/InputPlugin.h b/libraries/plugins/src/plugins/InputPlugin.h index b45fa862c1..02ae5f58d5 100644 --- a/libraries/plugins/src/plugins/InputPlugin.h +++ b/libraries/plugins/src/plugins/InputPlugin.h @@ -18,10 +18,8 @@ namespace controller { class InputPlugin : public Plugin { public: - virtual bool isJointController() const = 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; }; diff --git a/plugins/hifiNeuron/CMakeLists.txt b/plugins/hifiNeuron/CMakeLists.txt index 1cab2359a9..a9ed8cca6e 100644 --- a/plugins/hifiNeuron/CMakeLists.txt +++ b/plugins/hifiNeuron/CMakeLists.txt @@ -6,8 +6,11 @@ # See the accompanying file LICENSE or http:#www.apache.org/licenses/LICENSE-2.0.html # -set(TARGET_NAME hifiNeuron) -setup_hifi_plugin(Script Qml Widgets) -link_hifi_libraries(shared controllers ui plugins input-plugins) -target_neuron() +if (APPLE OR WIN32) + + set(TARGET_NAME hifiNeuron) + setup_hifi_plugin(Script Qml Widgets) + link_hifi_libraries(shared controllers ui plugins input-plugins) + target_neuron() +endif() diff --git a/plugins/hifiNeuron/src/NeuronPlugin.cpp b/plugins/hifiNeuron/src/NeuronPlugin.cpp index 6e2f744173..41c0eb0d4e 100644 --- a/plugins/hifiNeuron/src/NeuronPlugin.cpp +++ b/plugins/hifiNeuron/src/NeuronPlugin.cpp @@ -25,9 +25,7 @@ Q_LOGGING_CATEGORY(inputplugins, "hifi.inputplugins") #define __OS_XUN__ 1 #define BOOL int -#ifdef HAVE_NEURON #include -#endif const QString NeuronPlugin::NAME = "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 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) { assert(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 // 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. - glm::vec3 e = glm::vec3(euler.y, euler.x, euler.z) * RADIANS_PER_DEGREE; - return (glm::angleAxis(e.y, Vectors::UNIT_Y) * - glm::angleAxis(e.x, Vectors::UNIT_X) * - glm::angleAxis(e.z, Vectors::UNIT_Z)); + return (glm::angleAxis(e.x * RADIANS_PER_DEGREE, Vectors::UNIT_Y) * + glm::angleAxis(e.y * RADIANS_PER_DEGREE, Vectors::UNIT_X) * + glm::angleAxis(e.z * RADIANS_PER_DEGREE, Vectors::UNIT_Z)); } -#ifdef HAVE_NEURON - // // neuronDataReader SDK callback functions // @@ -355,21 +287,6 @@ void FrameDataReceivedCallback(void* context, SOCKET_REF sender, BvhDataHeaderEx // copy the data 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 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 { static bool ONCE = false; @@ -435,26 +352,19 @@ static void SocketStatusChangedCallback(void* context, SOCKET_REF sender, Socket qCDebug(inputplugins) << "NeuronPlugin: socket status = " << message; } -#endif // #ifdef HAVE_NEURON - // // NeuronPlugin // bool NeuronPlugin::isSupported() const { -#ifdef HAVE_NEURON // Because it's a client/server network architecture, we can't tell // if the neuron is actually connected until we connect to the server. return true; -#else - return false; -#endif } bool NeuronPlugin::activate() { InputPlugin::activate(); -#ifdef HAVE_NEURON // register with userInputMapper auto userInputMapper = DependencyManager::get(); userInputMapper->registerDevice(_inputDevice); @@ -480,13 +390,9 @@ bool NeuronPlugin::activate() { BRRegisterAutoSyncParmeter(_socketRef, Cmd_CombinationMode); return true; } -#else - return false; -#endif } void NeuronPlugin::deactivate() { -#ifdef HAVE_NEURON // unregister from userInputMapper if (_inputDevice->_deviceID != controller::Input::INVALID_DEVICE) { auto userInputMapper = DependencyManager::get(); @@ -499,10 +405,9 @@ void NeuronPlugin::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 joints; { // 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& joints, const std::vector& prevJoints) { for (size_t i = 0; i < joints.size(); i++) { + int poseIndex = neuronJointIndexToPoseIndex((NeuronJointIndex)i); glm::vec3 linearVel, angularVel; - glm::vec3 pos = joints[i].pos; - glm::quat rot = eulerToQuat(joints[i].euler); + const glm::vec3& pos = joints[i].pos; + 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()) { 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. 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 } - int poseIndex = neuronJointIndexToPoseIndex((NeuronJointIndex)i); _poseStateMap[poseIndex] = controller::Pose(pos, rot, linearVel, angularVel); } diff --git a/plugins/hifiNeuron/src/NeuronPlugin.h b/plugins/hifiNeuron/src/NeuronPlugin.h index 99859dcacb..9ddd79c013 100644 --- a/plugins/hifiNeuron/src/NeuronPlugin.h +++ b/plugins/hifiNeuron/src/NeuronPlugin.h @@ -27,7 +27,6 @@ public: // Plugin functions virtual bool isSupported() const override; - virtual bool isJointController() const override { return true; } virtual const QString& getName() const override { return NAME; } const QString& getID() const override { return NEURON_ID_STRING; } @@ -35,7 +34,7 @@ public: virtual void deactivate() override; 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 loadSettings() override; @@ -56,7 +55,7 @@ protected: // Device functions virtual controller::Input::NamedVector getAvailableInputs() 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 {}; void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, const std::vector& joints, const std::vector& prevJoints); diff --git a/plugins/hifiSdl2/src/Joystick.cpp b/plugins/hifiSdl2/src/Joystick.cpp index 9d195fd606..a109656489 100644 --- a/plugins/hifiSdl2/src/Joystick.cpp +++ b/plugins/hifiSdl2/src/Joystick.cpp @@ -15,7 +15,6 @@ const float CONTROLLER_THRESHOLD = 0.3f; -#ifdef HAVE_SDL2 const float MAX_AXIS = 32768.0f; Joystick::Joystick(SDL_JoystickID instanceId, SDL_GameController* sdlGameController) : @@ -27,19 +26,15 @@ Joystick::Joystick(SDL_JoystickID instanceId, SDL_GameController* sdlGameControl } -#endif - Joystick::~Joystick() { closeJoystick(); } void Joystick::closeJoystick() { -#ifdef HAVE_SDL2 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) { if (fabsf(axisState.second) < CONTROLLER_THRESHOLD) { _axisStateMap[axisState.first] = 0.0f; @@ -52,8 +47,6 @@ void Joystick::focusOutEvent() { _buttonPressedMap.clear(); }; -#ifdef HAVE_SDL2 - void Joystick::handleAxisEvent(const SDL_ControllerAxisEvent& event) { SDL_GameControllerAxis axis = (SDL_GameControllerAxis) event.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 { using namespace controller; static const Input::NamedVector availableInputs{ diff --git a/plugins/hifiSdl2/src/Joystick.h b/plugins/hifiSdl2/src/Joystick.h index 08bf27b960..e2eaeaef8b 100644 --- a/plugins/hifiSdl2/src/Joystick.h +++ b/plugins/hifiSdl2/src/Joystick.h @@ -15,10 +15,8 @@ #include #include -#ifdef HAVE_SDL2 #include #undef main -#endif #include #include @@ -26,10 +24,7 @@ class Joystick : public QObject, public controller::InputDevice { Q_OBJECT Q_PROPERTY(QString name READ getName) - -#ifdef HAVE_SDL2 Q_PROPERTY(int instanceId READ getInstanceId) -#endif public: using Pointer = std::shared_ptr; @@ -39,33 +34,25 @@ public: // Device functions virtual controller::Input::NamedVector getAvailableInputs() 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; Joystick() : InputDevice("GamePad") {} ~Joystick(); -#ifdef HAVE_SDL2 Joystick(SDL_JoystickID instanceId, SDL_GameController* sdlGameController); -#endif void closeJoystick(); -#ifdef HAVE_SDL2 void handleAxisEvent(const SDL_ControllerAxisEvent& event); void handleButtonEvent(const SDL_ControllerButtonEvent& event); -#endif -#ifdef HAVE_SDL2 int getInstanceId() const { return _instanceId; } -#endif private: -#ifdef HAVE_SDL2 SDL_GameController* _sdlGameController; SDL_Joystick* _sdlJoystick; SDL_JoystickID _instanceId; -#endif }; #endif // hifi_Joystick_h diff --git a/plugins/hifiSdl2/src/SDL2Manager.cpp b/plugins/hifiSdl2/src/SDL2Manager.cpp index 7091b20d21..0bdb68f830 100644 --- a/plugins/hifiSdl2/src/SDL2Manager.cpp +++ b/plugins/hifiSdl2/src/SDL2Manager.cpp @@ -16,7 +16,6 @@ #include "SDL2Manager.h" -#ifdef HAVE_SDL2 static_assert( (int)controller::A == (int)SDL_CONTROLLER_BUTTON_A && (int)controller::B == (int)SDL_CONTROLLER_BUTTON_B && @@ -40,28 +39,16 @@ static_assert( (int)controller::LT == (int)SDL_CONTROLLER_AXIS_TRIGGERLEFT && (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"); -#endif const QString SDL2Manager::NAME = "SDL2"; -#ifdef HAVE_SDL2 SDL_JoystickID SDL2Manager::getInstanceId(SDL_GameController* controller) { SDL_Joystick* joystick = SDL_GameControllerGetJoystick(controller); return SDL_JoystickInstanceID(joystick); } -#endif - -SDL2Manager::SDL2Manager() : -#ifdef HAVE_SDL2 -_openJoysticks(), -#endif -_isInitialized(false) -{ -} void SDL2Manager::init() { -#ifdef HAVE_SDL2 bool initSuccess = (SDL_Init(SDL_INIT_GAMECONTROLLER) == 0); if (initSuccess) { @@ -88,66 +75,50 @@ void SDL2Manager::init() { else { qDebug() << "Error initializing SDL2 Manager"; } -#endif } void SDL2Manager::deinit() { -#ifdef HAVE_SDL2 _openJoysticks.clear(); SDL_Quit(); -#endif } bool SDL2Manager::activate() { InputPlugin::activate(); -#ifdef HAVE_SDL2 auto userInputMapper = DependencyManager::get(); for (auto joystick : _openJoysticks) { userInputMapper->registerDevice(joystick); emit joystickAdded(joystick.get()); } return true; -#else - return false; -#endif } void SDL2Manager::deactivate() { -#ifdef HAVE_SDL2 auto userInputMapper = DependencyManager::get(); for (auto joystick : _openJoysticks) { userInputMapper->removeDevice(joystick->getDeviceID()); emit joystickRemoved(joystick.get()); } -#endif InputPlugin::deactivate(); } bool SDL2Manager::isSupported() const { -#ifdef HAVE_SDL2 return true; -#else - return false; -#endif } void SDL2Manager::pluginFocusOutEvent() { -#ifdef HAVE_SDL2 for (auto joystick : _openJoysticks) { joystick->focusOutEvent(); } -#endif } -void SDL2Manager::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) { -#ifdef HAVE_SDL2 +void SDL2Manager::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) { if (_isInitialized) { auto userInputMapper = DependencyManager::get(); for (auto joystick : _openJoysticks) { - joystick->update(deltaTime, inputCalibrationData, jointsCaptured); + joystick->update(deltaTime, inputCalibrationData); } PerformanceTimer perfTimer("SDL2Manager::update"); @@ -197,5 +168,4 @@ void SDL2Manager::pluginUpdate(float deltaTime, const controller::InputCalibrati } } } -#endif } diff --git a/plugins/hifiSdl2/src/SDL2Manager.h b/plugins/hifiSdl2/src/SDL2Manager.h index f69e23ee98..a597a87aee 100644 --- a/plugins/hifiSdl2/src/SDL2Manager.h +++ b/plugins/hifiSdl2/src/SDL2Manager.h @@ -12,9 +12,7 @@ #ifndef hifi__SDL2Manager_h #define hifi__SDL2Manager_h -#ifdef HAVE_SDL2 #include -#endif #include #include @@ -24,30 +22,26 @@ class SDL2Manager : public InputPlugin { Q_OBJECT public: - SDL2Manager(); - // Plugin functions - virtual bool isSupported() const override; - virtual bool isJointController() const override { return false; } - virtual const QString& getName() const override { return NAME; } + bool isSupported() const override; + const QString& getName() const override { return NAME; } - virtual void init() override; - virtual void deinit() override; + void init() override; + void deinit() override; /// 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. - virtual void deactivate() override; + void deactivate() override; - virtual void pluginFocusOutEvent() override; - virtual void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override; + void pluginFocusOutEvent() override; + void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override; signals: void joystickAdded(Joystick* joystick); void joystickRemoved(Joystick* joystick); private: -#ifdef HAVE_SDL2 SDL_JoystickID getInstanceId(SDL_GameController* controller); int axisInvalid() const { return SDL_CONTROLLER_AXIS_INVALID; } @@ -81,8 +75,7 @@ private: int buttonRelease() const { return SDL_RELEASED; } QMap _openJoysticks; -#endif - bool _isInitialized; + bool _isInitialized { false } ; static const QString NAME; }; diff --git a/plugins/hifiSixense/src/SixenseManager.cpp b/plugins/hifiSixense/src/SixenseManager.cpp index fdb7bb17fe..9ea79a8b96 100644 --- a/plugins/hifiSixense/src/SixenseManager.cpp +++ b/plugins/hifiSixense/src/SixenseManager.cpp @@ -134,12 +134,12 @@ void SixenseManager::setSixenseFilter(bool filter) { #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 auto userInputMapper = DependencyManager::get(); userInputMapper->withLock([&, this]() { - _inputDevice->update(deltaTime, inputCalibrationData, jointsCaptured); + _inputDevice->update(deltaTime, inputCalibrationData); }); 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 #ifdef HAVE_SIXENSE _buttonPressedMap.clear(); @@ -208,14 +208,10 @@ void SixenseManager::InputDevice::update(float deltaTime, const controller::Inpu _axisStateMap[left ? LY : RY] = data->joystick_y; _axisStateMap[left ? LT : RT] = data->trigger; - if (!jointsCaptured) { - // Rotation of Palm - 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); - rawPoses[i] = controller::Pose(position, rotation, Vectors::ZERO, Vectors::ZERO); - } else { - _poseStateMap.clear(); - } + // Rotation of Palm + 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); + rawPoses[i] = controller::Pose(position, rotation, Vectors::ZERO, Vectors::ZERO); } else { auto hand = left ? controller::StandardPoseChannel::LEFT_HAND : controller::StandardPoseChannel::RIGHT_HAND; _poseStateMap[hand] = controller::Pose(); diff --git a/plugins/hifiSixense/src/SixenseManager.h b/plugins/hifiSixense/src/SixenseManager.h index a46614b17a..6aec9fd4ad 100644 --- a/plugins/hifiSixense/src/SixenseManager.h +++ b/plugins/hifiSixense/src/SixenseManager.h @@ -28,7 +28,6 @@ class SixenseManager : public InputPlugin { public: // Plugin functions virtual bool isSupported() const override; - virtual bool isJointController() const override { return true; } virtual const QString& getName() const override { return NAME; } virtual const QString& getID() const override { return HYDRA_ID_STRING; } @@ -36,7 +35,7 @@ public: virtual void deactivate() override; 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 loadSettings() override; @@ -61,7 +60,7 @@ private: // Device functions virtual controller::Input::NamedVector getAvailableInputs() 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; void handleButtonEvent(unsigned int buttons, bool left); diff --git a/plugins/hifiSpacemouse/CMakeLists.txt b/plugins/hifiSpacemouse/CMakeLists.txt new file mode 100644 index 0000000000..bcfb309a69 --- /dev/null +++ b/plugins/hifiSpacemouse/CMakeLists.txt @@ -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() diff --git a/libraries/input-plugins/src/input-plugins/SpacemouseManager.cpp b/plugins/hifiSpacemouse/src/SpacemouseManager.cpp similarity index 95% rename from libraries/input-plugins/src/input-plugins/SpacemouseManager.cpp rename to plugins/hifiSpacemouse/src/SpacemouseManager.cpp index d946990319..8b584df366 100644 --- a/libraries/input-plugins/src/input-plugins/SpacemouseManager.cpp +++ b/plugins/hifiSpacemouse/src/SpacemouseManager.cpp @@ -17,13 +17,65 @@ #include #include -#include "../../../interface/src/Menu.h" +const QString SpacemouseManager::NAME { "Spacemouse" }; const float MAX_AXIS = 75.0f; // max forward = 2x speed +#define LOGITECH_VENDOR_ID 0x46d -static std::shared_ptr instance = std::make_shared(); +#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 instance; + +bool SpacemouseManager::isSupported() const { + return Is3dmouseAttached(); +} + +bool SpacemouseManager::activate() { + fLast3dmouseInputTime = 0; + + InitializeRawInput(GetActiveWindow()); + + QAbstractEventDispatcher::instance()->installNativeEventFilter(this); + + if (!instance) { + instance = std::make_shared(); + } + + if (instance->getDeviceID() == controller::Input::INVALID_DEVICE) { + auto userInputMapper = DependencyManager::get(); + 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->removeDevice(deviceid); +} + +void SpacemouseManager::pluginFocusOutEvent() { + instance->focusOutEvent(); +} + +void SpacemouseManager::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) { + +} + +SpacemouseDevice::SpacemouseDevice() : InputDevice(SpacemouseManager::NAME) { } @@ -111,71 +163,80 @@ controller::Input::NamedPair SpacemouseDevice::makePair(SpacemouseDevice::Positi 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. // 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 } -void SpacemouseManager::ManagerFocusOutEvent() { - instance->focusOutEvent(); -} - -void SpacemouseManager::init() { -} - -#ifdef HAVE_3DCONNEXIONCLIENT - #ifdef Q_OS_WIN #include -void SpacemouseManager::toggleSpacemouse(bool shouldEnable) { - if (shouldEnable) { - init(); - } - if (!shouldEnable && instance->getDeviceID() != controller::Input::INVALID_DEVICE) { - destroy(); - } +bool SpacemouseManager::nativeEventFilter(const QByteArray& eventType, void* message, long* result) { + MSG* msg = static_cast< MSG * >(message); + return RawInputEventFilter(message, result); } -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) { - auto userInputMapper = DependencyManager::get(); - userInputMapper->registerDevice(instance); - UserActivityLogger::getInstance().connectedDevice("controller", "Spacemouse"); + return sRawInputDevices; +} + + +//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(nDevices); + if (::GetRawInputDeviceList(&rawInputDeviceList[0], &nDevices, sizeof(RAWINPUTDEVICELIST)) == static_cast(-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->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 static const double k3dmouseAngularVelocity = 8.0e-6; // radians per second per count @@ -290,20 +351,9 @@ bool SpacemouseManager::RawInputEventFilter(void* msg, long* result) { 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 void SpacemouseManager::Move3d(HANDLE device, std::vector& motionData) { Q_UNUSED(device); - 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->handleAxisEvent(); @@ -321,62 +371,6 @@ void SpacemouseManager::On3dmouseKeyUp(HANDLE device, int virtualKeyCode) { 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(nDevices); - if (::GetRawInputDeviceList(&rawInputDeviceList[0], &nDevices, sizeof(RAWINPUTDEVICELIST)) == static_cast(-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 // This needs to be called initially so that Windows will send the messages from the 3D mouse to the window. @@ -942,5 +936,3 @@ void MessageHandler(unsigned int connection, unsigned int messageType, void *mes } #endif // __APPLE__ - -#endif diff --git a/libraries/input-plugins/src/input-plugins/SpacemouseManager.h b/plugins/hifiSpacemouse/src/SpacemouseManager.h similarity index 77% rename from libraries/input-plugins/src/input-plugins/SpacemouseManager.h rename to plugins/hifiSpacemouse/src/SpacemouseManager.h index 82c4fa8fb6..a9933902e5 100644 --- a/libraries/input-plugins/src/input-plugins/SpacemouseManager.h +++ b/plugins/hifiSpacemouse/src/SpacemouseManager.h @@ -17,22 +17,8 @@ #include #include -#include "InputPlugin.h" +#include -#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 #ifdef Q_OS_WIN @@ -85,42 +71,26 @@ private: Speed fSpeed; }; -class SpacemouseManager : public QObject, public QAbstractNativeEventFilter { +class SpacemouseManager : public InputPlugin, public QAbstractNativeEventFilter { Q_OBJECT public: - SpacemouseManager() {}; + bool isSupported() const override; + const QString& getName() const override { return NAME; } + const QString& getID() const override { return NAME; } - void init(); - void destroy(); - bool Is3dmouseAttached(); + bool activate() override; + void deactivate() override; - SpacemouseManager* client; + void pluginFocusOutEvent() override; + void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override; - void ManagerFocusOutEvent(); - - I3dMouseParam& MouseParams(); - const I3dMouseParam& MouseParams() const; - - virtual void Move3d(HANDLE device, std::vector& 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& motionData); - void On3dmouseKeyDown(int virtualKeyCode); - void On3dmouseKeyUp(int virtualKeyCode); + bool nativeEventFilter(const QByteArray& eventType, void* message, long* result) override; private: + void Move3d(HANDLE device, std::vector& motionData); + void On3dmouseKeyDown(HANDLE device, int virtualKeyCode); + void On3dmouseKeyUp(HANDLE device, int virtualKeyCode); bool InitializeRawInput(HWND hwndTarget); bool RawInputEventFilter(void* msg, long* result); @@ -156,6 +126,9 @@ private: // use to calculate distance traveled since last event DWORD fLast3dmouseInputTime; + + static const QString NAME; + friend class SpacemouseDevice; }; // the osx connexion api @@ -176,8 +149,6 @@ public: #endif // __APPLE__ -#endif - // connnects to the userinputmapper class SpacemouseDevice : public QObject, public controller::InputDevice { @@ -214,7 +185,7 @@ public: virtual controller::Input::NamedVector getAvailableInputs() 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; glm::vec3 cc_position; diff --git a/plugins/hifiSpacemouse/src/SpacemouseProvider.cpp b/plugins/hifiSpacemouse/src/SpacemouseProvider.cpp new file mode 100644 index 0000000000..c623f77d73 --- /dev/null +++ b/plugins/hifiSpacemouse/src/SpacemouseProvider.cpp @@ -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 + +#include +#include +#include + +#include +#include + +#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" diff --git a/plugins/hifiSpacemouse/src/plugin.json b/plugins/hifiSpacemouse/src/plugin.json new file mode 100644 index 0000000000..0967ef424b --- /dev/null +++ b/plugins/hifiSpacemouse/src/plugin.json @@ -0,0 +1 @@ +{} diff --git a/plugins/oculus/src/OculusControllerManager.cpp b/plugins/oculus/src/OculusControllerManager.cpp index 50ef6b09a1..09ab6ec159 100644 --- a/plugins/oculus/src/OculusControllerManager.cpp +++ b/plugins/oculus/src/OculusControllerManager.cpp @@ -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"); if (_touch) { if (OVR_SUCCESS(ovr_GetInputState(_session, ovrControllerType_Touch, &_inputState))) { - _touch->update(deltaTime, inputCalibrationData, jointsCaptured); + _touch->update(deltaTime, inputCalibrationData); } else { qCWarning(oculus) << "Unable to read Oculus touch input state"; } @@ -89,7 +89,7 @@ void OculusControllerManager::pluginUpdate(float deltaTime, const controller::In if (_remote) { if (OVR_SUCCESS(ovr_GetInputState(_session, ovrControllerType_Remote, &_inputState))) { - _remote->update(deltaTime, inputCalibrationData, jointsCaptured); + _remote->update(deltaTime, inputCalibrationData); } else { qCWarning(oculus) << "Unable to read Oculus remote input state"; } @@ -158,7 +158,7 @@ QString OculusControllerManager::RemoteDevice::getDefaultMappingConfig() const { 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(); const auto& inputState = _parent._inputState; for (const auto& pair : BUTTON_MAP) { @@ -172,21 +172,19 @@ void OculusControllerManager::RemoteDevice::focusOutEvent() { _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(); _buttonPressedMap.clear(); - if (!jointsCaptured) { - int numTrackedControllers = 0; - static const auto REQUIRED_HAND_STATUS = ovrStatus_OrientationTracked & ovrStatus_PositionTracked; - auto tracking = ovr_GetTrackingState(_parent._session, 0, false); - ovr_for_each_hand([&](ovrHandType hand) { - ++numTrackedControllers; - if (REQUIRED_HAND_STATUS == (tracking.HandStatusFlags[hand] & REQUIRED_HAND_STATUS)) { - handlePose(deltaTime, inputCalibrationData, hand, tracking.HandPoses[hand]); - } - }); - } + int numTrackedControllers = 0; + static const auto REQUIRED_HAND_STATUS = ovrStatus_OrientationTracked & ovrStatus_PositionTracked; + auto tracking = ovr_GetTrackingState(_parent._session, 0, false); + ovr_for_each_hand([&](ovrHandType hand) { + ++numTrackedControllers; + if (REQUIRED_HAND_STATUS == (tracking.HandStatusFlags[hand] & REQUIRED_HAND_STATUS)) { + handlePose(deltaTime, inputCalibrationData, hand, tracking.HandPoses[hand]); + } + }); using namespace controller; // Axes const auto& inputState = _parent._inputState; diff --git a/plugins/oculus/src/OculusControllerManager.h b/plugins/oculus/src/OculusControllerManager.h index 60969097f8..980e1286f8 100644 --- a/plugins/oculus/src/OculusControllerManager.h +++ b/plugins/oculus/src/OculusControllerManager.h @@ -24,14 +24,13 @@ class OculusControllerManager : public InputPlugin { public: // Plugin functions bool isSupported() const override; - bool isJointController() const override { return true; } const QString& getName() const override { return NAME; } bool activate() override; void deactivate() 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: class OculusInputDevice : public controller::InputDevice { @@ -49,7 +48,7 @@ private: controller::Input::NamedVector getAvailableInputs() 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; friend class OculusControllerManager; @@ -62,7 +61,7 @@ private: controller::Input::NamedVector getAvailableInputs() 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; private: diff --git a/plugins/openvr/src/OpenVrDisplayPlugin.cpp b/plugins/openvr/src/OpenVrDisplayPlugin.cpp index 38719fdca5..dba8fca208 100644 --- a/plugins/openvr/src/OpenVrDisplayPlugin.cpp +++ b/plugins/openvr/src/OpenVrDisplayPlugin.cpp @@ -9,7 +9,6 @@ #include -#include #include #include #include @@ -30,10 +29,6 @@ Q_DECLARE_LOGGING_CATEGORY(displayplugins) const QString OpenVrDisplayPlugin::NAME("OpenVR (Vive)"); 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 }; vr::TrackedDevicePose_t _trackedDevicePose[vr::k_unMaxTrackedDeviceCount]; mat4 _trackedDevicePoseMat4[vr::k_unMaxTrackedDeviceCount]; @@ -43,7 +38,7 @@ static mat4 _sensorResetMat; static std::array VR_EYES { { vr::Eye_Left, vr::Eye_Right } }; bool OpenVrDisplayPlugin::isSupported() const { - return (enableDebugOpenVR || !isOculusPresent()) && vr::VR_IsHmdPresent(); + return openVrSupported(); } bool OpenVrDisplayPlugin::internalActivate() { diff --git a/plugins/openvr/src/OpenVrHelpers.cpp b/plugins/openvr/src/OpenVrHelpers.cpp index 8ddf028dd2..8536ffd5d9 100644 --- a/plugins/openvr/src/OpenVrHelpers.cpp +++ b/plugins/openvr/src/OpenVrHelpers.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include @@ -44,6 +45,12 @@ bool isOculusPresent() { 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() { bool hmdPresent = vr::VR_IsHmdPresent(); if (hmdPresent) { diff --git a/plugins/openvr/src/OpenVrHelpers.h b/plugins/openvr/src/OpenVrHelpers.h index 81896a2ce5..4b06ca0813 100644 --- a/plugins/openvr/src/OpenVrHelpers.h +++ b/plugins/openvr/src/OpenVrHelpers.h @@ -12,7 +12,8 @@ #include #include -bool isOculusPresent(); +bool openVrSupported(); + vr::IVRSystem* acquireOpenVrSystem(); void releaseOpenVrSystem(); diff --git a/plugins/openvr/src/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp index fab383a955..5ca8f03ad7 100644 --- a/plugins/openvr/src/ViveControllerManager.cpp +++ b/plugins/openvr/src/ViveControllerManager.cpp @@ -50,11 +50,9 @@ static const QString MENU_PATH = MENU_PARENT + ">" + MENU_NAME; static const QString RENDER_CONTROLLERS = "Render Hand Controllers"; 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 { - return (enableDebugOpenVR || !isOculusPresent()) && vr::VR_IsHmdPresent(); + return openVrSupported(); } bool ViveControllerManager::activate() { @@ -214,12 +212,13 @@ 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) { + _inputDevice->update(deltaTime, inputCalibrationData); auto userInputMapper = DependencyManager::get(); // because update mutates the internal state we need to lock userInputMapper->withLock([&, this]() { - _inputDevice->update(deltaTime, inputCalibrationData, jointsCaptured); + _inputDevice->update(deltaTime, inputCalibrationData); }); if (_inputDevice->_trackedControllers == 0 && _registeredWithInputMapper) { @@ -235,7 +234,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(); _buttonPressedMap.clear(); @@ -244,10 +243,8 @@ void ViveControllerManager::InputDevice::update(float deltaTime, const controlle auto leftHandDeviceIndex = _system->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_LeftHand); auto rightHandDeviceIndex = _system->GetTrackedDeviceIndexForControllerRole(vr::TrackedControllerRole_RightHand); - if (!jointsCaptured) { - handleHandController(deltaTime, leftHandDeviceIndex, inputCalibrationData, true); - handleHandController(deltaTime, rightHandDeviceIndex, inputCalibrationData, false); - } + handleHandController(deltaTime, leftHandDeviceIndex, inputCalibrationData, true); + handleHandController(deltaTime, rightHandDeviceIndex, inputCalibrationData, false); int numTrackedControllers = 0; if (leftHandDeviceIndex != vr::k_unTrackedDeviceIndexInvalid) { diff --git a/plugins/openvr/src/ViveControllerManager.h b/plugins/openvr/src/ViveControllerManager.h index d55d4e726c..672ad59cfe 100644 --- a/plugins/openvr/src/ViveControllerManager.h +++ b/plugins/openvr/src/ViveControllerManager.h @@ -31,17 +31,15 @@ namespace vr { class ViveControllerManager : public InputPlugin { Q_OBJECT public: - // Plugin functions - virtual bool isSupported() const override; - virtual bool isJointController() const override { return true; } + bool isSupported() const override; const QString& getName() const override { return NAME; } - virtual bool activate() override; - virtual void deactivate() override; + bool activate() override; + void deactivate() override; - virtual void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); } - virtual void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override; + void pluginFocusOutEvent() override { _inputDevice->focusOutEvent(); } + void pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override; void updateRendering(RenderArgs* args, render::ScenePointer scene, render::PendingChanges pendingChanges); @@ -53,10 +51,10 @@ private: InputDevice(vr::IVRSystem*& system) : controller::InputDevice("Vive"), _system(system) {} private: // Device functions - virtual controller::Input::NamedVector getAvailableInputs() const override; - virtual QString getDefaultMappingConfig() const override; - virtual void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, bool jointsCaptured) override; - virtual void focusOutEvent() override; + controller::Input::NamedVector getAvailableInputs() const override; + QString getDefaultMappingConfig() const override; + void update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) override; + void focusOutEvent() override; 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); diff --git a/tests/controllers/src/main.cpp b/tests/controllers/src/main.cpp index 3a5b4a4a4d..36ed566ea7 100644 --- a/tests/controllers/src/main.cpp +++ b/tests/controllers/src/main.cpp @@ -121,7 +121,7 @@ int main(int argc, char** argv) { }; foreach(auto inputPlugin, PluginManager::getInstance()->getInputPlugins()) { - inputPlugin->pluginUpdate(delta, calibrationData, false); + inputPlugin->pluginUpdate(delta, calibrationData); } auto userInputMapper = DependencyManager::get(); @@ -144,7 +144,7 @@ int main(int argc, char** argv) { if (name == KeyboardMouseDevice::NAME) { userInputMapper->registerDevice(std::dynamic_pointer_cast(inputPlugin)->getInputDevice()); } - inputPlugin->pluginUpdate(0, calibrationData, false); + inputPlugin->pluginUpdate(0, calibrationData); } rootContext->setContextProperty("Controllers", new MyControllerScriptingInterface()); } From 73342b2758c1ae89188186a1b23b5e2b8b16664e Mon Sep 17 00:00:00 2001 From: Brad Davis Date: Wed, 18 May 2016 09:38:44 -0700 Subject: [PATCH 21/23] PR feedback --- plugins/hifiNeuron/src/NeuronPlugin.cpp | 2 +- plugins/hifiSpacemouse/src/SpacemouseManager.cpp | 6 ++++-- plugins/openvr/src/ViveControllerManager.cpp | 1 - 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/plugins/hifiNeuron/src/NeuronPlugin.cpp b/plugins/hifiNeuron/src/NeuronPlugin.cpp index 41c0eb0d4e..0a4bc7f8d2 100644 --- a/plugins/hifiNeuron/src/NeuronPlugin.cpp +++ b/plugins/hifiNeuron/src/NeuronPlugin.cpp @@ -458,7 +458,7 @@ void NeuronPlugin::InputDevice::update(float deltaTime, const controller::InputC const glm::vec3& pos = joints[i].pos; const glm::vec3& rotEuler = joints[i].euler; - if ((Vectors::ZERO == pos && Vectors::ZERO == rotEuler)) { + if (Vectors::ZERO == pos && Vectors::ZERO == rotEuler) { _poseStateMap[poseIndex] = controller::Pose(); continue; } diff --git a/plugins/hifiSpacemouse/src/SpacemouseManager.cpp b/plugins/hifiSpacemouse/src/SpacemouseManager.cpp index 8b584df366..3d9b93ff44 100644 --- a/plugins/hifiSpacemouse/src/SpacemouseManager.cpp +++ b/plugins/hifiSpacemouse/src/SpacemouseManager.cpp @@ -11,6 +11,10 @@ #include "SpacemouseManager.h" +#ifdef Q_OS_WIN +#include +#endif + #include #include @@ -171,8 +175,6 @@ void SpacemouseDevice::update(float deltaTime, const controller::InputCalibratio #ifdef Q_OS_WIN -#include - bool SpacemouseManager::nativeEventFilter(const QByteArray& eventType, void* message, long* result) { MSG* msg = static_cast< MSG * >(message); return RawInputEventFilter(message, result); diff --git a/plugins/openvr/src/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp index 5ca8f03ad7..12567b10d1 100644 --- a/plugins/openvr/src/ViveControllerManager.cpp +++ b/plugins/openvr/src/ViveControllerManager.cpp @@ -213,7 +213,6 @@ void ViveControllerManager::renderHand(const controller::Pose& pose, gpu::Batch& void ViveControllerManager::pluginUpdate(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) { - _inputDevice->update(deltaTime, inputCalibrationData); auto userInputMapper = DependencyManager::get(); // because update mutates the internal state we need to lock From 2e30f0916cc9a365b5a93171527499e22f5385cb Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 20 May 2016 15:07:47 -0700 Subject: [PATCH 22/23] remove debug logging and add some comments --- libraries/physics/src/ShapeFactory.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libraries/physics/src/ShapeFactory.cpp b/libraries/physics/src/ShapeFactory.cpp index 8c1d44b273..71b919b7ee 100644 --- a/libraries/physics/src/ShapeFactory.cpp +++ b/libraries/physics/src/ShapeFactory.cpp @@ -70,14 +70,15 @@ btConvexHullShape* ShapeFactory::createConvexHull(const QVector& poin // 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; - qDebug() << "reduced hull with" << points.size() << "points down to" << hull->getNumPoints(); // TODO: remove after testing } hull->recalcLocalAabb(); From a24d63a39c3974b05839499524a05c07ca86d1b7 Mon Sep 17 00:00:00 2001 From: Seth Alves Date: Fri, 20 May 2016 15:45:00 -0700 Subject: [PATCH 23/23] make distance-grab work better when avatar is walking --- .../system/controllers/handControllerGrab.js | 21 +++++++++++-------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/scripts/system/controllers/handControllerGrab.js b/scripts/system/controllers/handControllerGrab.js index ed4ac219c0..06549a38b5 100644 --- a/scripts/system/controllers/handControllerGrab.js +++ b/scripts/system/controllers/handControllerGrab.js @@ -1112,8 +1112,8 @@ function MyController(hand) { Controller.getPoseValue((this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand); // transform it into world frame - var controllerPosition = Vec3.sum(MyAvatar.position, - Vec3.multiplyQbyV(MyAvatar.orientation, avatarControllerPose.translation)); + var controllerPositionVSAvatar = Vec3.multiplyQbyV(MyAvatar.orientation, avatarControllerPose.translation); + var controllerPosition = Vec3.sum(MyAvatar.position, controllerPositionVSAvatar); var controllerRotation = Quat.multiply(MyAvatar.orientation, avatarControllerPose.rotation); var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, GRABBABLE_PROPERTIES); @@ -1161,7 +1161,7 @@ function MyController(hand) { this.turnOffVisualizations(); - this.previousControllerPosition = controllerPosition; + this.previousControllerPositionVSAvatar = controllerPositionVSAvatar; this.previousControllerRotation = controllerRotation; }; @@ -1179,8 +1179,8 @@ function MyController(hand) { Controller.Standard.RightHand : Controller.Standard.LeftHand); // transform it into world frame - var controllerPosition = Vec3.sum(MyAvatar.position, - Vec3.multiplyQbyV(MyAvatar.orientation, avatarControllerPose.translation)); + var controllerPositionVSAvatar = Vec3.multiplyQbyV(MyAvatar.orientation, avatarControllerPose.translation); + var controllerPosition = Vec3.sum(MyAvatar.position, controllerPositionVSAvatar); var controllerRotation = Quat.multiply(MyAvatar.orientation, avatarControllerPose.rotation); var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, GRABBABLE_PROPERTIES); @@ -1197,7 +1197,8 @@ function MyController(hand) { } // 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 var handChange = Quat.multiply(Quat.slerp(this.previousControllerRotation, @@ -1218,7 +1219,7 @@ function MyController(hand) { var handControllerData = getEntityCustomData('handControllerKey', this.grabbedEntity, defaultMoveWithHeadData); // Update radialVelocity - var lastVelocity = Vec3.subtract(controllerPosition, this.previousControllerPosition); + var lastVelocity = Vec3.subtract(controllerPositionVSAvatar, this.previousControllerPositionVSAvatar); lastVelocity = Vec3.multiply(lastVelocity, 1.0 / deltaTime); var newRadialVelocity = Vec3.dot(lastVelocity, Vec3.normalize(Vec3.subtract(grabbedProperties.position, controllerPosition))); @@ -1266,7 +1267,9 @@ function MyController(hand) { var clampedVector; var targetPosition; if (constraintData.axisStart !== false) { - clampedVector = this.projectVectorAlongAxis(this.currentObjectPosition, constraintData.axisStart, constraintData.axisEnd); + clampedVector = this.projectVectorAlongAxis(this.currentObjectPosition, + constraintData.axisStart, + constraintData.axisEnd); targetPosition = clampedVector; } else { targetPosition = { @@ -1309,7 +1312,7 @@ function MyController(hand) { print("continueDistanceHolding -- updateAction failed"); } - this.previousControllerPosition = controllerPosition; + this.previousControllerPositionVSAvatar = controllerPositionVSAvatar; this.previousControllerRotation = controllerRotation; };