From 328fc29bc595faa62ef1ae69604d6fabebca7ece Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 1 Nov 2017 17:01:19 +1300 Subject: [PATCH 01/25] Fix serverScripts not being able to see entities in parent/child tree --- .../src/entities/EntityTreeSendThread.cpp | 14 +++++++++----- .../src/entities/EntityTreeSendThread.h | 3 ++- libraries/entities/src/DiffTraversal.cpp | 5 +++-- libraries/entities/src/DiffTraversal.h | 3 ++- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/assignment-client/src/entities/EntityTreeSendThread.cpp b/assignment-client/src/entities/EntityTreeSendThread.cpp index 03014bae6a..e96a9dc667 100644 --- a/assignment-client/src/entities/EntityTreeSendThread.cpp +++ b/assignment-client/src/entities/EntityTreeSendThread.cpp @@ -96,7 +96,7 @@ void EntityTreeSendThread::traverseTreeAndSendContents(SharedNodePointer node, O nodeData->copyCurrentViewFrustum(viewFrustum); EntityTreeElementPointer root = std::dynamic_pointer_cast(_myServer->getOctree()->getRoot()); int32_t lodLevelOffset = nodeData->getBoundaryLevelAdjust() + (viewFrustumChanged ? LOW_RES_MOVING_ADJUST : NO_BOUNDARY_ADJUST); - startNewTraversal(viewFrustum, root, lodLevelOffset, nodeData->getUsesFrustum()); + startNewTraversal(viewFrustum, root, lodLevelOffset, nodeData->getUsesFrustum(), isFullScene); // When the viewFrustum changed the sort order may be incorrect, so we re-sort // and also use the opportunity to cull anything no longer in view @@ -175,7 +175,7 @@ bool EntityTreeSendThread::addAncestorsToExtraFlaggedEntities(const QUuid& filte return parentWasNew || ancestorsWereNew; } - // since we didn't have a parent niether of our parents or ancestors could be new additions + // since we didn't have a parent, neither of our parents or ancestors could be new additions return false; } @@ -204,8 +204,10 @@ bool EntityTreeSendThread::addDescendantsToExtraFlaggedEntities(const QUuid& fil return hasNewChild || hasNewDescendants; } -void EntityTreeSendThread::startNewTraversal(const ViewFrustum& view, EntityTreeElementPointer root, int32_t lodLevelOffset, bool usesViewFrustum) { - DiffTraversal::Type type = _traversal.prepareNewTraversal(view, root, lodLevelOffset, usesViewFrustum); +void EntityTreeSendThread::startNewTraversal(const ViewFrustum& view, EntityTreeElementPointer root, int32_t lodLevelOffset, + bool usesViewFrustum, bool isFullScene) { + + DiffTraversal::Type type = _traversal.prepareNewTraversal(view, root, lodLevelOffset, usesViewFrustum, isFullScene); // there are three types of traversal: // // (1) FirstTime = at login --> find everything in view @@ -423,12 +425,14 @@ bool EntityTreeSendThread::traverseTreeAndBuildNextPacketPayload(EncodeBitstream uint64_t sendTime = usecTimestampNow(); auto nodeData = static_cast(params.nodeData); nodeData->stats.encodeStarted(); + auto entityNodeData = static_cast(_node.toStrongRef()->getLinkedData()); while(!_sendQueue.empty()) { PrioritizedEntity queuedItem = _sendQueue.top(); EntityItemPointer entity = queuedItem.getEntity(); if (entity) { // Only send entities that match the jsonFilters, but keep track of everything we've tried to send so we don't try to send it again - if (entity->matchesJSONFilters(jsonFilters)) { + if (entity->matchesJSONFilters(jsonFilters) || entityNodeData->isEntityFlaggedAsExtra(entity->getID())) { + entityNodeData->insertSentFilteredEntity(entity->getID()); OctreeElement::AppendState appendEntityState = entity->appendEntityData(&_packetData, params, _extraEncodeData); if (appendEntityState != OctreeElement::COMPLETED) { diff --git a/assignment-client/src/entities/EntityTreeSendThread.h b/assignment-client/src/entities/EntityTreeSendThread.h index 49901491ff..1781de9890 100644 --- a/assignment-client/src/entities/EntityTreeSendThread.h +++ b/assignment-client/src/entities/EntityTreeSendThread.h @@ -38,7 +38,8 @@ private: bool addAncestorsToExtraFlaggedEntities(const QUuid& filteredEntityID, EntityItem& entityItem, EntityNodeData& nodeData); bool addDescendantsToExtraFlaggedEntities(const QUuid& filteredEntityID, EntityItem& entityItem, EntityNodeData& nodeData); - void startNewTraversal(const ViewFrustum& viewFrustum, EntityTreeElementPointer root, int32_t lodLevelOffset, bool usesViewFrustum); + void startNewTraversal(const ViewFrustum& viewFrustum, EntityTreeElementPointer root, int32_t lodLevelOffset, + bool usesViewFrustum, bool isFullScene); bool traverseTreeAndBuildNextPacketPayload(EncodeBitstreamParams& params, const QJsonObject& jsonFilters) override; void preDistributionProcessing() override; diff --git a/libraries/entities/src/DiffTraversal.cpp b/libraries/entities/src/DiffTraversal.cpp index 2f9423daa3..9b16ee90bf 100644 --- a/libraries/entities/src/DiffTraversal.cpp +++ b/libraries/entities/src/DiffTraversal.cpp @@ -142,7 +142,8 @@ DiffTraversal::DiffTraversal() { _path.reserve(MIN_PATH_DEPTH); } -DiffTraversal::Type DiffTraversal::prepareNewTraversal(const ViewFrustum& viewFrustum, EntityTreeElementPointer root, int32_t lodLevelOffset, bool usesViewFrustum) { +DiffTraversal::Type DiffTraversal::prepareNewTraversal(const ViewFrustum& viewFrustum, EntityTreeElementPointer root, + int32_t lodLevelOffset, bool usesViewFrustum, bool isFullScene) { assert(root); // there are three types of traversal: // @@ -163,7 +164,7 @@ DiffTraversal::Type DiffTraversal::prepareNewTraversal(const ViewFrustum& viewFr Type type; // If usesViewFrustum changes, treat it as a First traversal - if (_completedView.startTime == 0 || _currentView.usesViewFrustum != _completedView.usesViewFrustum) { + if (_completedView.startTime == 0 || _currentView.usesViewFrustum != _completedView.usesViewFrustum || isFullScene) { type = Type::First; _currentView.viewFrustum = viewFrustum; _currentView.lodScaleFactor = lodScaleFactor; diff --git a/libraries/entities/src/DiffTraversal.h b/libraries/entities/src/DiffTraversal.h index c26e48ae5f..becf322fd5 100644 --- a/libraries/entities/src/DiffTraversal.h +++ b/libraries/entities/src/DiffTraversal.h @@ -57,7 +57,8 @@ public: DiffTraversal(); - Type prepareNewTraversal(const ViewFrustum& viewFrustum, EntityTreeElementPointer root, int32_t lodLevelOffset, bool usesViewFrustum); + Type prepareNewTraversal(const ViewFrustum& viewFrustum, EntityTreeElementPointer root, int32_t lodLevelOffset, + bool usesViewFrustum, bool isFullScene); const ViewFrustum& getCurrentView() const { return _currentView.viewFrustum; } const ViewFrustum& getCompletedView() const { return _completedView.viewFrustum; } From da63e85699c62271145962f7a1b1d95ab87a70f4 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Wed, 1 Nov 2017 09:17:04 -0700 Subject: [PATCH 02/25] Bug 8270 fixed --- libraries/animation/src/AnimClip.h | 1 + libraries/animation/src/Rig.cpp | 21 +++++++++++++++++++ libraries/animation/src/Rig.h | 2 ++ .../src/avatars-renderer/Avatar.cpp | 12 +++++++++++ .../src/avatars-renderer/Avatar.h | 3 +++ 5 files changed, 39 insertions(+) diff --git a/libraries/animation/src/AnimClip.h b/libraries/animation/src/AnimClip.h index c7e7ebf3ee..7121cff356 100644 --- a/libraries/animation/src/AnimClip.h +++ b/libraries/animation/src/AnimClip.h @@ -54,6 +54,7 @@ public: void setMirrorFlag(bool mirrorFlag) { _mirrorFlag = mirrorFlag; } void loadURL(const QString& url); + const QString& getURL() { return _url; } protected: virtual void setCurrentFrameInternal(float frame) override; diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 0f2bce5ca4..8293cb91f4 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -144,6 +144,27 @@ QStringList Rig::getAnimationRoles() const { } } +QVector> Rig::getAnimationClips() const { + QVector> list; + if (_animNode) { + _animNode->traverse([&](AnimNode::Pointer node) { + // only report clip nodes as valid roles. + auto clipNode = std::dynamic_pointer_cast(node); + if (clipNode) { + // filter out the userAnims, they are for internal use only. + if (!clipNode->getID().startsWith("userAnim")) { + list.append(clipNode); + } + } + return true; + }); + return list; + } + else { + return list; + } +} + void Rig::overrideRoleAnimation(const QString& role, const QString& url, float fps, bool loop, float firstFrame, float lastFrame) { if (_animNode) { AnimNode::Pointer node = _animNode->findByName(role); diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 18d49c5f1e..9290b41513 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -21,6 +21,7 @@ #include #include +#include "AnimClip.h" #include "AnimNode.h" #include "AnimNodeLoader.h" #include "SimpleMovingAverage.h" @@ -107,6 +108,7 @@ public: QStringList getAnimationRoles() const; void overrideRoleAnimation(const QString& role, const QString& url, float fps, bool loop, float firstFrame, float lastFrame); void restoreRoleAnimation(const QString& role); + QVector> getAnimationClips() const; void initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOffset); void reset(const FBXGeometry& geometry); diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index 142e57c9e5..0d2e730a1a 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -139,6 +139,7 @@ Avatar::~Avatar() { void Avatar::init() { getHead()->init(); _skeletonModel->init(); + connect(&_skeletonModel->getRig(), &Rig::onLoadComplete, this, &Avatar::restoreAnimations); _initialized = true; } @@ -198,6 +199,16 @@ void Avatar::setTargetScale(float targetScale) { } } +void Avatar::restoreAnimations() { + for (int i = 0; i < _animationCache.size(); i++) { + auto clip = _animationCache[i]; + const float REFERENCE_FRAMES_PER_SECOND = 30.0f; + float fps = REFERENCE_FRAMES_PER_SECOND / clip->getTimeScale(); + qDebug() << clip->getID() << " " << clip->getURL() << " " << fps << " " << clip->getLoopFlag() << " " << clip->getStartFrame() << " " << clip->getEndFrame(); + _skeletonModel->getRig().overrideRoleAnimation(clip->getID(), clip->getURL(), fps, clip->getLoopFlag(), clip->getStartFrame(), clip->getEndFrame()); + } +} + void Avatar::updateAvatarEntities() { PerformanceTimer perfTimer("attachments"); // - if queueEditEntityMessage sees clientOnly flag it does _myAvatar->updateAvatarEntity() @@ -1177,6 +1188,7 @@ void Avatar::scaleVectorRelativeToPosition(glm::vec3 &positionToScale) const { } void Avatar::setSkeletonModelURL(const QUrl& skeletonModelURL) { + _animationCache = _skeletonModel->getRig().getAnimationClips(); AvatarData::setSkeletonModelURL(skeletonModelURL); if (QThread::currentThread() == thread()) { _skeletonModel->setURL(_skeletonModelURL); diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h index a5ec307c50..09e1451aa9 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h @@ -274,6 +274,7 @@ public slots: glm::vec3 getRightPalmPosition() const; glm::quat getRightPalmRotation() const; + void restoreAnimations(); void setModelURLFinished(bool success); protected: @@ -377,6 +378,8 @@ private: float _displayNameTargetAlpha { 1.0f }; float _displayNameAlpha { 1.0f }; + + QVector> _animationCache; }; #endif // hifi_Avatar_h From 76e06a62143c24f510d8474c960ecda323ef7194 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Wed, 1 Nov 2017 15:28:28 -0700 Subject: [PATCH 03/25] Update to stable-v-staging metaverse switching, to handle marketplace injection. --- scripts/system/html/js/marketplacesInject.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/system/html/js/marketplacesInject.js b/scripts/system/html/js/marketplacesInject.js index 4b127baef8..dc0c610ace 100644 --- a/scripts/system/html/js/marketplacesInject.js +++ b/scripts/system/html/js/marketplacesInject.js @@ -89,7 +89,7 @@ window.location = "https://clara.io/library?gameCheck=true&public=true"; }); $('#exploreHifiMarketplace').on('click', function () { - window.location = "http://www.highfidelity.com/marketplace"; + window.location = metaverseServerURL + "/marketplace"; }); } @@ -612,9 +612,9 @@ var HIFI_ITEM_PAGE = 3; var pageType = DIRECTORY; - if (location.href.indexOf("highfidelity.com/") !== -1) { pageType = HIFI; } + if (location.href.indexOf(metaverseServerURL + "/") !== -1) { pageType = HIFI; } if (location.href.indexOf("clara.io/") !== -1) { pageType = CLARA; } - if (location.href.indexOf("highfidelity.com/marketplace/items/") !== -1) { pageType = HIFI_ITEM_PAGE; } + if (location.href.indexOf(metaverseServerURL + "/marketplace/items/") !== -1) { pageType = HIFI_ITEM_PAGE; } injectCommonCode(pageType === DIRECTORY); switch (pageType) { From 6a2dc38fdd402e42b648a74b2254387f85ae1665 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Wed, 1 Nov 2017 19:38:37 -0700 Subject: [PATCH 04/25] restoring previous roles --- libraries/animation/src/Rig.cpp | 30 +++++-------------- libraries/animation/src/Rig.h | 17 +++++++++-- .../src/avatars-renderer/Avatar.cpp | 12 -------- .../src/avatars-renderer/Avatar.h | 4 +-- 4 files changed, 24 insertions(+), 39 deletions(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 8293cb91f4..e16afc65c2 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -144,27 +144,6 @@ QStringList Rig::getAnimationRoles() const { } } -QVector> Rig::getAnimationClips() const { - QVector> list; - if (_animNode) { - _animNode->traverse([&](AnimNode::Pointer node) { - // only report clip nodes as valid roles. - auto clipNode = std::dynamic_pointer_cast(node); - if (clipNode) { - // filter out the userAnims, they are for internal use only. - if (!clipNode->getID().startsWith("userAnim")) { - list.append(clipNode); - } - } - return true; - }); - return list; - } - else { - return list; - } -} - void Rig::overrideRoleAnimation(const QString& role, const QString& url, float fps, bool loop, float firstFrame, float lastFrame) { if (_animNode) { AnimNode::Pointer node = _animNode->findByName(role); @@ -173,6 +152,7 @@ void Rig::overrideRoleAnimation(const QString& role, const QString& url, float f const float REFERENCE_FRAMES_PER_SECOND = 30.0f; float timeScale = fps / REFERENCE_FRAMES_PER_SECOND; auto clipNode = std::make_shared(role, url, firstFrame, lastFrame, timeScale, loop, false); + _roleAnimState[role] = { role, url, fps, loop, firstFrame, lastFrame }; AnimNode::Pointer parent = node->getParent(); parent->replaceChild(node, clipNode); } else { @@ -1659,8 +1639,14 @@ void Rig::initAnimGraph(const QUrl& url) { _userAnimState = { UserAnimState::None, "", 30.0f, false, 0.0f, 0.0f }; overrideAnimation(origState.url, origState.fps, origState.loop, origState.firstFrame, origState.lastFrame); } + // restore the role animations we had before reset. + for (auto ite = _roleAnimState.begin(); ite != _roleAnimState.end(); ite++) { + auto role = ite->first; + auto roleState = _roleAnimState[role]; + overrideRoleAnimation(roleState.role, roleState.url, roleState.fps, roleState.loop, roleState.firstFrame, roleState.lastFrame); + } _animLoading = false; - + emit onLoadComplete(); }); connect(_animLoader.get(), &AnimNodeLoader::error, [url](int error, QString str) { diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 9290b41513..a63d5eb0a5 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -21,7 +21,6 @@ #include #include -#include "AnimClip.h" #include "AnimNode.h" #include "AnimNodeLoader.h" #include "SimpleMovingAverage.h" @@ -108,7 +107,7 @@ public: QStringList getAnimationRoles() const; void overrideRoleAnimation(const QString& role, const QString& url, float fps, bool loop, float firstFrame, float lastFrame); void restoreRoleAnimation(const QString& role); - QVector> getAnimationClips() const; + //QVector> getAnimationClips() const; void initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOffset); void reset(const FBXGeometry& geometry); @@ -337,8 +336,22 @@ protected: float firstFrame; float lastFrame; }; + + struct RoleAnimState { + RoleAnimState() {} + RoleAnimState(const QString& roleId, const QString& urlIn, float fpsIn, bool loopIn, float firstFrameIn, float lastFrameIn) : + role(roleId), url(urlIn), fps(fpsIn), loop(loopIn), firstFrame(firstFrameIn), lastFrame(lastFrameIn) {} + + QString role; + QString url; + float fps; + bool loop; + float firstFrame; + float lastFrame; + }; UserAnimState _userAnimState; + std::map _roleAnimState; float _leftHandOverlayAlpha { 0.0f }; float _rightHandOverlayAlpha { 0.0f }; diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index 0d2e730a1a..142e57c9e5 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -139,7 +139,6 @@ Avatar::~Avatar() { void Avatar::init() { getHead()->init(); _skeletonModel->init(); - connect(&_skeletonModel->getRig(), &Rig::onLoadComplete, this, &Avatar::restoreAnimations); _initialized = true; } @@ -199,16 +198,6 @@ void Avatar::setTargetScale(float targetScale) { } } -void Avatar::restoreAnimations() { - for (int i = 0; i < _animationCache.size(); i++) { - auto clip = _animationCache[i]; - const float REFERENCE_FRAMES_PER_SECOND = 30.0f; - float fps = REFERENCE_FRAMES_PER_SECOND / clip->getTimeScale(); - qDebug() << clip->getID() << " " << clip->getURL() << " " << fps << " " << clip->getLoopFlag() << " " << clip->getStartFrame() << " " << clip->getEndFrame(); - _skeletonModel->getRig().overrideRoleAnimation(clip->getID(), clip->getURL(), fps, clip->getLoopFlag(), clip->getStartFrame(), clip->getEndFrame()); - } -} - void Avatar::updateAvatarEntities() { PerformanceTimer perfTimer("attachments"); // - if queueEditEntityMessage sees clientOnly flag it does _myAvatar->updateAvatarEntity() @@ -1188,7 +1177,6 @@ void Avatar::scaleVectorRelativeToPosition(glm::vec3 &positionToScale) const { } void Avatar::setSkeletonModelURL(const QUrl& skeletonModelURL) { - _animationCache = _skeletonModel->getRig().getAnimationClips(); AvatarData::setSkeletonModelURL(skeletonModelURL); if (QThread::currentThread() == thread()) { _skeletonModel->setURL(_skeletonModelURL); diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h index 09e1451aa9..a06ba0fb82 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h @@ -274,7 +274,7 @@ public slots: glm::vec3 getRightPalmPosition() const; glm::quat getRightPalmRotation() const; - void restoreAnimations(); + //void restoreAnimations(); void setModelURLFinished(bool success); protected: @@ -378,8 +378,6 @@ private: float _displayNameTargetAlpha { 1.0f }; float _displayNameAlpha { 1.0f }; - - QVector> _animationCache; }; #endif // hifi_Avatar_h From e201e82ec26aa0ce28b63a1bf36b6c0828e9e6fd Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Wed, 1 Nov 2017 19:45:56 -0700 Subject: [PATCH 05/25] formatting --- libraries/animation/src/AnimClip.h | 1 - libraries/animation/src/Rig.cpp | 2 +- libraries/avatars-renderer/src/avatars-renderer/Avatar.h | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/libraries/animation/src/AnimClip.h b/libraries/animation/src/AnimClip.h index 7121cff356..c7e7ebf3ee 100644 --- a/libraries/animation/src/AnimClip.h +++ b/libraries/animation/src/AnimClip.h @@ -54,7 +54,6 @@ public: void setMirrorFlag(bool mirrorFlag) { _mirrorFlag = mirrorFlag; } void loadURL(const QString& url); - const QString& getURL() { return _url; } protected: virtual void setCurrentFrameInternal(float frame) override; diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index e16afc65c2..9df12de540 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -1646,7 +1646,7 @@ void Rig::initAnimGraph(const QUrl& url) { overrideRoleAnimation(roleState.role, roleState.url, roleState.fps, roleState.loop, roleState.firstFrame, roleState.lastFrame); } _animLoading = false; - + emit onLoadComplete(); }); connect(_animLoader.get(), &AnimNodeLoader::error, [url](int error, QString str) { diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h index a06ba0fb82..a5ec307c50 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h @@ -274,7 +274,6 @@ public slots: glm::vec3 getRightPalmPosition() const; glm::quat getRightPalmRotation() const; - //void restoreAnimations(); void setModelURLFinished(bool success); protected: From 9e0e1ab5a54c85f3721a629aee5e2e9e67e3dae4 Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Wed, 1 Nov 2017 19:56:16 -0700 Subject: [PATCH 06/25] erase comment --- libraries/animation/src/Rig.h | 1 - 1 file changed, 1 deletion(-) diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index a63d5eb0a5..8ca701ec2d 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -107,7 +107,6 @@ public: QStringList getAnimationRoles() const; void overrideRoleAnimation(const QString& role, const QString& url, float fps, bool loop, float firstFrame, float lastFrame); void restoreRoleAnimation(const QString& role); - //QVector> getAnimationClips() const; void initJointStates(const FBXGeometry& geometry, const glm::mat4& modelOffset); void reset(const FBXGeometry& geometry); From 81509b3e92e4a13b3129a97a6ef71e5fcc15869e Mon Sep 17 00:00:00 2001 From: luiscuenca Date: Thu, 2 Nov 2017 10:34:57 -0700 Subject: [PATCH 07/25] coding standard --- libraries/animation/src/Rig.cpp | 7 +++---- libraries/animation/src/Rig.h | 2 +- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 9df12de540..acf7bf81d8 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -152,7 +152,7 @@ void Rig::overrideRoleAnimation(const QString& role, const QString& url, float f const float REFERENCE_FRAMES_PER_SECOND = 30.0f; float timeScale = fps / REFERENCE_FRAMES_PER_SECOND; auto clipNode = std::make_shared(role, url, firstFrame, lastFrame, timeScale, loop, false); - _roleAnimState[role] = { role, url, fps, loop, firstFrame, lastFrame }; + _roleAnimStates[role] = { role, url, fps, loop, firstFrame, lastFrame }; AnimNode::Pointer parent = node->getParent(); parent->replaceChild(node, clipNode); } else { @@ -1640,9 +1640,8 @@ void Rig::initAnimGraph(const QUrl& url) { overrideAnimation(origState.url, origState.fps, origState.loop, origState.firstFrame, origState.lastFrame); } // restore the role animations we had before reset. - for (auto ite = _roleAnimState.begin(); ite != _roleAnimState.end(); ite++) { - auto role = ite->first; - auto roleState = _roleAnimState[role]; + for (auto& roleAnimState : _roleAnimStates) { + auto roleState = roleAnimState.second; overrideRoleAnimation(roleState.role, roleState.url, roleState.fps, roleState.loop, roleState.firstFrame, roleState.lastFrame); } _animLoading = false; diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 8ca701ec2d..e9cc444bd4 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -350,7 +350,7 @@ protected: }; UserAnimState _userAnimState; - std::map _roleAnimState; + std::map _roleAnimStates; float _leftHandOverlayAlpha { 0.0f }; float _rightHandOverlayAlpha { 0.0f }; From babaef8399012346342f2fb5651d7ac7a1aa223c Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Fri, 3 Nov 2017 05:59:59 -0700 Subject: [PATCH 08/25] Fix the audio input device peak meters --- interface/resources/qml/hifi/audio/Audio.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/hifi/audio/Audio.qml b/interface/resources/qml/hifi/audio/Audio.qml index 12c2ec1835..87ddce49ca 100644 --- a/interface/resources/qml/hifi/audio/Audio.qml +++ b/interface/resources/qml/hifi/audio/Audio.qml @@ -213,8 +213,8 @@ Rectangle { anchors.right: parent.right peak: model.peak; anchors.verticalCenter: parent.verticalCenter - visible: (bar.currentIndex === 1 && selectedHMD && isVR) || - (bar.currentIndex === 0 && selectedDesktop && !isVR) && + visible: ((bar.currentIndex === 1 && isVR) || + (bar.currentIndex === 0 && !isVR)) && Audio.devices.input.peakValuesAvailable; } } From c496429a85cad2616f6c9f696ccbae19dbad3d25 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Fri, 3 Nov 2017 10:40:25 -0700 Subject: [PATCH 09/25] Add Machine Fingerprint to receive_at endpoint txn' --- interface/src/commerce/Ledger.cpp | 10 ++++++++-- interface/src/commerce/Ledger.h | 2 +- interface/src/commerce/Wallet.cpp | 4 +++- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/interface/src/commerce/Ledger.cpp b/interface/src/commerce/Ledger.cpp index 904847cb5f..f607c923ee 100644 --- a/interface/src/commerce/Ledger.cpp +++ b/interface/src/commerce/Ledger.cpp @@ -90,7 +90,7 @@ void Ledger::buy(const QString& hfc_key, int cost, const QString& asset_id, cons signedSend("transaction", transactionString, hfc_key, "buy", "buySuccess", "buyFailure", controlled_failure); } -bool Ledger::receiveAt(const QString& hfc_key, const QString& old_key) { +bool Ledger::receiveAt(const QString& hfc_key, const QString& old_key, const QString& machine_fingerprint) { auto accountManager = DependencyManager::get(); if (!accountManager->isLoggedIn()) { qCWarning(commerce) << "Cannot set receiveAt when not logged in."; @@ -99,7 +99,13 @@ bool Ledger::receiveAt(const QString& hfc_key, const QString& old_key) { return false; // We know right away that we will fail, so tell the caller. } - signedSend("public_key", hfc_key.toUtf8(), old_key, "receive_at", "receiveAtSuccess", "receiveAtFailure"); + QJsonObject transaction; + transaction["hfc_key"] = hfc_key; + transaction["machine_fingerprint"] = machine_fingerprint; + QJsonDocument transactionDoc{ transaction }; + auto transactionString = transactionDoc.toJson(QJsonDocument::Compact); + + signedSend("transaction", transactionString, old_key, "receive_at", "receiveAtSuccess", "receiveAtFailure"); return true; // Note that there may still be an asynchronous signal of failure that callers might be interested in. } diff --git a/interface/src/commerce/Ledger.h b/interface/src/commerce/Ledger.h index 42eb0ffc49..54f3f780f3 100644 --- a/interface/src/commerce/Ledger.h +++ b/interface/src/commerce/Ledger.h @@ -26,7 +26,7 @@ class Ledger : public QObject, public Dependency { public: void buy(const QString& hfc_key, int cost, const QString& asset_id, const QString& inventory_key, const bool controlled_failure = false); - bool receiveAt(const QString& hfc_key, const QString& old_key); + bool receiveAt(const QString& hfc_key, const QString& old_key, const QString& machine_fingerprint); void balance(const QStringList& keys); void inventory(const QStringList& keys); void history(const QStringList& keys); diff --git a/interface/src/commerce/Wallet.cpp b/interface/src/commerce/Wallet.cpp index 85632ff8f1..9bc8dc9e43 100644 --- a/interface/src/commerce/Wallet.cpp +++ b/interface/src/commerce/Wallet.cpp @@ -16,6 +16,7 @@ #include "ui/ImageProvider.h" #include "scripting/HMDScriptingInterface.h" +#include #include #include #include @@ -541,7 +542,8 @@ bool Wallet::generateKeyPair() { // 2. It is maximally private, and we can step back from that later if desired. // 3. It maximally exercises all the machinery, so we are most likely to surface issues now. auto ledger = DependencyManager::get(); - return ledger->receiveAt(key, oldKey); + QString machineFingerprint = uuidStringWithoutCurlyBraces(FingerprintUtils::getMachineFingerprint()); + return ledger->receiveAt(key, oldKey, machineFingerprint); } QStringList Wallet::listPublicKeys() { From 539cf35f30970c031ea0ccc48aa8cadf206b2fd3 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Fri, 3 Nov 2017 17:14:27 -0700 Subject: [PATCH 10/25] saving work --- interface/src/raypick/LaserPointer.cpp | 2 +- interface/src/raypick/LaserPointer.h | 2 +- .../controllerModules/farActionGrabEntity.js | 44 ++++++++++++++++++- .../libraries/controllerDispatcherUtils.js | 29 ++++++++++++ 4 files changed, 74 insertions(+), 3 deletions(-) diff --git a/interface/src/raypick/LaserPointer.cpp b/interface/src/raypick/LaserPointer.cpp index 75b43a251b..9da8ff34ac 100644 --- a/interface/src/raypick/LaserPointer.cpp +++ b/interface/src/raypick/LaserPointer.cpp @@ -233,7 +233,7 @@ void LaserPointer::setLaserLength(const float laserLength) { }); } -void LaserPointer::setLockEndUUID(QUuid objectID, const bool isOverlay) { +void LaserPointer::setLockEndUUID(QUuid objectID, const bool isOverlay, const glm::mat4& offset) { withWriteLock([&] { _objectLockEnd = std::pair(objectID, isOverlay); }); diff --git a/interface/src/raypick/LaserPointer.h b/interface/src/raypick/LaserPointer.h index f2350c7199..a80f9d447d 100644 --- a/interface/src/raypick/LaserPointer.h +++ b/interface/src/raypick/LaserPointer.h @@ -74,7 +74,7 @@ public: void setPrecisionPicking(const bool precisionPicking); void setLaserLength(const float laserLength); - void setLockEndUUID(QUuid objectID, const bool isOverlay); + void setLockEndUUID(QUuid objectID, const bool isOverlay, const glm::mat4& offset = glm::mat4()); void setIgnoreItems(const QVector& ignoreItems) const; void setIncludeItems(const QVector& includeItems) const; diff --git a/scripts/system/controllers/controllerModules/farActionGrabEntity.js b/scripts/system/controllers/controllerModules/farActionGrabEntity.js index e34855d521..e63d7c7c35 100644 --- a/scripts/system/controllers/controllerModules/farActionGrabEntity.js +++ b/scripts/system/controllers/controllerModules/farActionGrabEntity.js @@ -19,6 +19,7 @@ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); Script.include("/~/system/libraries/controllers.js"); +Script.include("/~/system/libraries/Xform.hs"); (function() { var PICK_WITH_HAND_RAY = true; @@ -113,10 +114,42 @@ Script.include("/~/system/libraries/controllers.js"); ]; var MARGIN = 25; + + function TargetObject(entityID) { + this.entityID = entityID; + this.entityProps = null; + this.parentID = null; + this.parentProps = []; + this.childrenProps = []; + this.parentsCollisionStatus = []; + this.childrenCollisionStatus = []; + this.madeDynamic = null; + this.parentEntityProps = null; + + this.makeDynamic = function() { + }; + + this.saveCollisionStatus = function() { + }; + + this.restoreEntitiesProperties = function() { + }; + + this.getTargetEntity = function() { + var parentPropsLength = this.parentProps.length; + if (parentPropsLength !== 0) { + return this.parentProps[parentPropsLength].id; + } + return this.entityID; + }; + } + function FarActionGrabEntity(hand) { this.hand = hand; this.grabbedThingID = null; + this.targetObject = null; this.actionID = null; // action this script created... + this.entityToLockOnto = null; this.entityWithContextOverlay = false; this.contextOverlayTimer = false; this.previousCollisionStatus = false; @@ -158,7 +191,8 @@ Script.include("/~/system/libraries/controllers.js"); LaserPointers.enableLaserPointer(laserPointerID); LaserPointers.setRenderState(laserPointerID, mode); if (this.distanceHolding || this.distanceRotating) { - LaserPointers.setLockEndUUID(laserPointerID, this.grabbedThingID, this.grabbedIsOverlay); + // calculate offset + LaserPointers.setLockEndUUID(laserPointerID, this.entityToLockOnto, this.grabbedIsOverlay); } else { LaserPointers.setLockEndUUID(laserPointerID, null, false); } @@ -351,6 +385,7 @@ Script.include("/~/system/libraries/controllers.js"); } this.actionID = null; this.grabbedThingID = null; + this.entityToLockOnto = null; }; this.updateRecommendedArea = function() { @@ -497,17 +532,24 @@ Script.include("/~/system/libraries/controllers.js"); if (rayPickInfo.type === RayPick.INTERSECTED_ENTITY) { if (controllerData.triggerClicks[this.hand]) { var entityID = rayPickInfo.objectID; + this.entityToLockOnto = entityID; var targetProps = Entities.getEntityProperties(entityID, [ "dynamic", "shapeType", "position", "rotation", "dimensions", "density", "userData", "locked", "type" ]); + this.targetObject = new TargetObject(entityID); if (entityID !== this.entityWithContextOverlay) { this.destroyContextOverlay(); } if (entityIsGrabbable(targetProps)) { + var groupRootProps = findGroupParent(controllerData, targetProps); + if (entityIsGrabbable(groupRootProps)) { + targetProps = groupRootProps; + entityID = targetProps.id; + } if (!entityIsDistanceGrabbable(targetProps)) { targetProps.dynamic = true; this.previousCollisionStatus = targetProps.collisionless; diff --git a/scripts/system/libraries/controllerDispatcherUtils.js b/scripts/system/libraries/controllerDispatcherUtils.js index cd3f1a711f..148530c5ec 100644 --- a/scripts/system/libraries/controllerDispatcherUtils.js +++ b/scripts/system/libraries/controllerDispatcherUtils.js @@ -35,12 +35,14 @@ propsArePhysical:true, controllerDispatcherPluginsNeedSort:true, projectOntoXYPlane:true, + getChildrenProps:true, projectOntoEntityXYPlane:true, projectOntoOverlayXYPlane:true, entityHasActions:true, ensureDynamic:true, findGroupParent:true, BUMPER_ON_VALUE:true, + getEntityParents:true, findHandChildEntities:true, TEAR_AWAY_DISTANCE:true, TEAR_AWAY_COUNT:true, @@ -306,6 +308,33 @@ findGroupParent = function (controllerData, targetProps) { return targetProps; }; +getChildrenProps = function(entityID) { + var childrenProps = []; + var childrenIDs = Entities.getChildrenIDs(entityID); + for (var index = 0; index < childrenIDs.length; index++) { + var childProps = Entities.getEntityProperties(childrenIDs[index]); + childrenProps.push(childProps); + } + return childrenProps; +}; + +getEntityParents = function(targetProps) { + var parentProperties = []; + while (targetProps.parentID && + targetProps.parentID !== Uuid.NULL && + Entities.getNestableType(targetProps.parentID) == "entity") { + var parentProps = Entities.getEntityProperties(targetProps.parentID, DISPATCHER_PROPERTIES); + if (!parentProps) { + break; + } + parentProps.id = targetProps.parentID; + targetProps = parentProps; + parentProperties.push(parentProps); + } + + return parentProperties; +}; + findHandChildEntities = function(hand) { // find children of avatar's hand joint From 6ca9cc02399f30d1034f7d945b47992573a2e99c Mon Sep 17 00:00:00 2001 From: Ken Cooke Date: Fri, 3 Nov 2017 18:40:55 -0700 Subject: [PATCH 11/25] Update WASAPI audio plugin --- cmake/externals/wasapi/CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmake/externals/wasapi/CMakeLists.txt b/cmake/externals/wasapi/CMakeLists.txt index 4437024962..4c0ffaf88f 100644 --- a/cmake/externals/wasapi/CMakeLists.txt +++ b/cmake/externals/wasapi/CMakeLists.txt @@ -6,8 +6,8 @@ if (WIN32) include(ExternalProject) ExternalProject_Add( ${EXTERNAL_NAME} - URL http://hifi-public.s3.amazonaws.com/dependencies/qtaudio_wasapi9.zip - URL_MD5 94f4765bdbcd53cd099f349ae031e769 + URL http://hifi-public.s3.amazonaws.com/dependencies/qtaudio_wasapi10.zip + URL_MD5 4f40e49715a420fb67b45b9cee19052c CONFIGURE_COMMAND "" BUILD_COMMAND "" INSTALL_COMMAND "" From d4b4d188ed28bdf6875dd66ef34598aa0ad2005b Mon Sep 17 00:00:00 2001 From: ZappoMan Date: Sat, 4 Nov 2017 13:40:41 -0700 Subject: [PATCH 12/25] allow splitting of edit or add entity packets across multiple edit packets when property list is larger than MTU --- .../entities/src/EntityEditPacketSender.cpp | 42 ++++++++++++------- libraries/entities/src/EntityItem.cpp | 4 +- .../entities/src/EntityItemProperties.cpp | 34 ++++++--------- libraries/entities/src/EntityItemProperties.h | 4 +- libraries/entities/src/EntityPropertyFlags.h | 29 +++++++------ libraries/octree/src/OctreePacketData.cpp | 12 +++++- libraries/octree/src/OctreePacketData.h | 1 + tests/octree/src/OctreeTests.cpp | 2 +- 8 files changed, 71 insertions(+), 57 deletions(-) diff --git a/libraries/entities/src/EntityEditPacketSender.cpp b/libraries/entities/src/EntityEditPacketSender.cpp index e82ed82093..168b0cd446 100644 --- a/libraries/entities/src/EntityEditPacketSender.cpp +++ b/libraries/entities/src/EntityEditPacketSender.cpp @@ -93,27 +93,41 @@ void EntityEditPacketSender::queueEditEntityMessage(PacketType type, QByteArray bufferOut(NLPacket::maxPayloadSize(type), 0); - bool success; + OctreeElement::AppendState encodeResult = OctreeElement::PARTIAL; // start the loop assuming there's more to send auto nodeList = DependencyManager::get(); + + EntityPropertyFlags didntFitProperties; + EntityItemProperties propertiesCopy = properties; + if (properties.parentIDChanged() && properties.getParentID() == AVATAR_SELF_ID) { - EntityItemProperties propertiesCopy = properties; const QUuid myNodeID = nodeList->getSessionUUID(); propertiesCopy.setParentID(myNodeID); - success = EntityItemProperties::encodeEntityEditPacket(type, entityItemID, propertiesCopy, bufferOut); - } else { - success = EntityItemProperties::encodeEntityEditPacket(type, entityItemID, properties, bufferOut); } - if (success) { - #ifdef WANT_DEBUG - qCDebug(entities) << "calling queueOctreeEditMessage()..."; - qCDebug(entities) << " id:" << entityItemID; - qCDebug(entities) << " properties:" << properties; - #endif - queueOctreeEditMessage(type, bufferOut); - if (type == PacketType::EntityAdd && !properties.getCertificateID().isEmpty()) { - emit addingEntityWithCertificate(properties.getCertificateID(), DependencyManager::get()->getPlaceName()); + EntityPropertyFlags requestedProperties = propertiesCopy.getChangedProperties(); + + while (encodeResult == OctreeElement::PARTIAL) { + encodeResult = EntityItemProperties::encodeEntityEditPacket(type, entityItemID, propertiesCopy, bufferOut, requestedProperties, didntFitProperties); + + if (encodeResult != OctreeElement::NONE) { + #ifdef WANT_DEBUG + qCDebug(entities) << "calling queueOctreeEditMessage()..."; + qCDebug(entities) << " id:" << entityItemID; + qCDebug(entities) << " properties:" << properties; + #endif + queueOctreeEditMessage(type, bufferOut); + if (type == PacketType::EntityAdd && !properties.getCertificateID().isEmpty()) { + emit addingEntityWithCertificate(properties.getCertificateID(), DependencyManager::get()->getPlaceName()); + } } + + // if we still have properties to send, switch the message type to edit, and request only the packets that didn't fit + if (encodeResult != OctreeElement::COMPLETED) { + type = PacketType::EntityEdit; + requestedProperties = didntFitProperties; + } + + bufferOut.resize(NLPacket::maxPayloadSize(type)); // resize our output buffer for the next packet } } diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index f6f4e48a73..3f054e1ccb 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -83,7 +83,7 @@ EntityPropertyFlags EntityItem::getEntityProperties(EncodeBitstreamParams& param requestedProperties += PROP_ANGULAR_VELOCITY; requestedProperties += PROP_ACCELERATION; - requestedProperties += PROP_DIMENSIONS; // NOTE: PROP_RADIUS obsolete + requestedProperties += PROP_DIMENSIONS; requestedProperties += PROP_DENSITY; requestedProperties += PROP_GRAVITY; requestedProperties += PROP_DAMPING; @@ -241,7 +241,7 @@ OctreeElement::AppendState EntityItem::appendEntityData(OctreePacketData* packet APPEND_ENTITY_PROPERTY(PROP_ANGULAR_VELOCITY, getLocalAngularVelocity()); APPEND_ENTITY_PROPERTY(PROP_ACCELERATION, getAcceleration()); - APPEND_ENTITY_PROPERTY(PROP_DIMENSIONS, getDimensions()); // NOTE: PROP_RADIUS obsolete + APPEND_ENTITY_PROPERTY(PROP_DIMENSIONS, getDimensions()); APPEND_ENTITY_PROPERTY(PROP_DENSITY, getDensity()); APPEND_ENTITY_PROPERTY(PROP_GRAVITY, getGravity()); APPEND_ENTITY_PROPERTY(PROP_DAMPING, getDamping()); diff --git a/libraries/entities/src/EntityItemProperties.cpp b/libraries/entities/src/EntityItemProperties.cpp index f774b208c4..108fc14e30 100644 --- a/libraries/entities/src/EntityItemProperties.cpp +++ b/libraries/entities/src/EntityItemProperties.cpp @@ -1221,8 +1221,9 @@ void EntityItemProperties::entityPropertyFlagsFromScriptValue(const QScriptValue // // TODO: Implement support for script and visible properties. // -bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItemID id, const EntityItemProperties& properties, - QByteArray& buffer) { +OctreeElement::AppendState EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItemID id, const EntityItemProperties& properties, + QByteArray& buffer, EntityPropertyFlags requestedProperties, EntityPropertyFlags& didntFitProperties) { + OctreePacketData ourDataPacket(false, buffer.size()); // create a packetData object to add out packet details too. OctreePacketData* packetData = &ourDataPacket; // we want a pointer to this so we can use our APPEND_ENTITY_PROPERTY macro @@ -1264,17 +1265,8 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem QByteArray encodedUpdateDelta = updateDeltaCoder; EntityPropertyFlags propertyFlags(PROP_LAST_ITEM); - EntityPropertyFlags requestedProperties = properties.getChangedProperties(); EntityPropertyFlags propertiesDidntFit = requestedProperties; - // TODO: we need to handle the multi-pass form of this, similar to how we handle entity data - // - // If we are being called for a subsequent pass at appendEntityData() that failed to completely encode this item, - // then our modelTreeElementExtraEncodeData should include data about which properties we need to append. - //if (modelTreeElementExtraEncodeData && modelTreeElementExtraEncodeData->includedItems.contains(getEntityItemID())) { - // requestedProperties = modelTreeElementExtraEncodeData->includedItems.value(getEntityItemID()); - //} - LevelDetails entityLevel = packetData->startLevel(); // Last Edited quint64 always first, before any other details, which allows us easy access to adjusting this @@ -1302,7 +1294,7 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem int propertyCount = 0; bool headerFits = successIDFits && successTypeFits && successLastEditedFits - && successLastUpdatedFits && successPropertyFlagsFits; + && successLastUpdatedFits && successPropertyFlagsFits; int startOfEntityItemData = packetData->getUncompressedByteOffset(); @@ -1316,7 +1308,7 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem APPEND_ENTITY_PROPERTY(PROP_SIMULATION_OWNER, properties._simulationOwner.toByteArray()); APPEND_ENTITY_PROPERTY(PROP_POSITION, properties.getPosition()); - APPEND_ENTITY_PROPERTY(PROP_DIMENSIONS, properties.getDimensions()); // NOTE: PROP_RADIUS obsolete + APPEND_ENTITY_PROPERTY(PROP_DIMENSIONS, properties.getDimensions()); APPEND_ENTITY_PROPERTY(PROP_ROTATION, properties.getRotation()); APPEND_ENTITY_PROPERTY(PROP_DENSITY, properties.getDensity()); APPEND_ENTITY_PROPERTY(PROP_VELOCITY, properties.getVelocity()); @@ -1472,6 +1464,7 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem properties.getType() == EntityTypes::Sphere) { APPEND_ENTITY_PROPERTY(PROP_SHAPE, properties.getShape()); } + APPEND_ENTITY_PROPERTY(PROP_NAME, properties.getName()); APPEND_ENTITY_PROPERTY(PROP_COLLISION_SOUND_URL, properties.getCollisionSoundURL()); APPEND_ENTITY_PROPERTY(PROP_ACTION_DATA, properties.getActionData()); @@ -1522,12 +1515,7 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem // If any part of the model items didn't fit, then the element is considered partial if (appendState != OctreeElement::COMPLETED) { - // TODO: handle mechanism for handling partial fitting data! - // add this item into our list for the next appendElementData() pass - //modelTreeElementExtraEncodeData->includedItems.insert(getEntityItemID(), propertiesDidntFit); - - // for now, if it's not complete, it's not successful - success = false; + didntFitProperties = propertiesDidntFit; } } @@ -1543,11 +1531,15 @@ bool EntityItemProperties::encodeEntityEditPacket(PacketType command, EntityItem } else { qCDebug(entities) << "ERROR - encoded edit message doesn't fit in output buffer."; success = false; + appendState = OctreeElement::NONE; // if we got here, then we didn't include the item + // maybe we should assert!!! } } else { packetData->discardSubTree(); } - return success; + + + return appendState; } QByteArray EntityItemProperties::getPackedNormals() const { @@ -1673,7 +1665,7 @@ bool EntityItemProperties::decodeEntityEditPacket(const unsigned char* data, int READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_SIMULATION_OWNER, QByteArray, setSimulationOwner); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_POSITION, glm::vec3, setPosition); - READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_DIMENSIONS, glm::vec3, setDimensions); // NOTE: PROP_RADIUS obsolete + READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_DIMENSIONS, glm::vec3, setDimensions); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_ROTATION, glm::quat, setRotation); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_DENSITY, float, setDensity); READ_ENTITY_PROPERTY_TO_PROPERTIES(PROP_VELOCITY, glm::vec3, setVelocity); diff --git a/libraries/entities/src/EntityItemProperties.h b/libraries/entities/src/EntityItemProperties.h index a8bb063934..732dbdf69f 100644 --- a/libraries/entities/src/EntityItemProperties.h +++ b/libraries/entities/src/EntityItemProperties.h @@ -262,8 +262,8 @@ public: float getLocalRenderAlpha() const { return _localRenderAlpha; } void setLocalRenderAlpha(float value) { _localRenderAlpha = value; _localRenderAlphaChanged = true; } - static bool encodeEntityEditPacket(PacketType command, EntityItemID id, const EntityItemProperties& properties, - QByteArray& buffer); + static OctreeElement::AppendState encodeEntityEditPacket(PacketType command, EntityItemID id, const EntityItemProperties& properties, + QByteArray& buffer, EntityPropertyFlags requestedProperties, EntityPropertyFlags& didntFitProperties); static bool encodeEraseEntityMessage(const EntityItemID& entityItemID, QByteArray& buffer); diff --git a/libraries/entities/src/EntityPropertyFlags.h b/libraries/entities/src/EntityPropertyFlags.h index f0f22b0091..35d40b669a 100644 --- a/libraries/entities/src/EntityPropertyFlags.h +++ b/libraries/entities/src/EntityPropertyFlags.h @@ -21,8 +21,7 @@ enum EntityPropertyList { // these properties are supported by the EntityItem base class PROP_VISIBLE, PROP_POSITION, - PROP_RADIUS, // NOTE: PROP_RADIUS is obsolete and only included in old format streams - PROP_DIMENSIONS = PROP_RADIUS, + PROP_DIMENSIONS, PROP_ROTATION, PROP_DENSITY, PROP_VELOCITY, @@ -47,13 +46,13 @@ enum EntityPropertyList { PROP_ANGULAR_VELOCITY, PROP_ANGULAR_DAMPING, PROP_COLLISIONLESS, - PROP_DYNAMIC, + PROP_DYNAMIC, // 24 // property used by Light entity PROP_IS_SPOTLIGHT, PROP_DIFFUSE_COLOR, - PROP_AMBIENT_COLOR_UNUSED, - PROP_SPECULAR_COLOR_UNUSED, + PROP_AMBIENT_COLOR_UNUSED, // FIXME - No longer used, can remove and bump protocol + PROP_SPECULAR_COLOR_UNUSED, // FIXME - No longer used, can remove and bump protocol PROP_INTENSITY, // Previously PROP_CONSTANT_ATTENUATION PROP_LINEAR_ATTENUATION_UNUSED, PROP_QUADRATIC_ATTENUATION_UNUSED, @@ -61,30 +60,30 @@ enum EntityPropertyList { PROP_CUTOFF, // available to all entities - PROP_LOCKED, + PROP_LOCKED, // 34 PROP_TEXTURES, // used by Model entities - PROP_ANIMATION_SETTINGS, // used by Model entities - PROP_USER_DATA, // all entities + PROP_ANIMATION_SETTINGS_UNUSED, // FIXME - No longer used, can remove and bump protocol + PROP_USER_DATA, // all entities -- 37 PROP_SHAPE_TYPE, // used by Model + zones entities // used by ParticleEffect entities - PROP_MAX_PARTICLES, - PROP_LIFESPAN, + PROP_MAX_PARTICLES, // 39 + PROP_LIFESPAN, // 40 -- used by all entities PROP_EMIT_RATE, PROP_EMIT_SPEED, PROP_EMIT_STRENGTH, - PROP_EMIT_ACCELERATION, - PROP_PARTICLE_RADIUS, + PROP_EMIT_ACCELERATION, // FIXME - doesn't seem to get set in mark all changed???? + PROP_PARTICLE_RADIUS, // 45!! PROP_COMPOUND_SHAPE_URL, // used by Model + zones entities PROP_MARKETPLACE_ID, // all entities PROP_ACCELERATION, // all entities PROP_SIMULATION_OWNER, // formerly known as PROP_SIMULATOR_ID - PROP_NAME, // all entities + PROP_NAME, // all entities -- 50 PROP_COLLISION_SOUND_URL, PROP_RESTITUTION, - PROP_FRICTION, + PROP_FRICTION, // 53 PROP_VOXEL_VOLUME_SIZE, PROP_VOXEL_DATA, @@ -96,7 +95,7 @@ enum EntityPropertyList { // used by hyperlinks PROP_HREF, - PROP_DESCRIPTION, + PROP_DESCRIPTION, // 61 PROP_FACE_CAMERA, PROP_SCRIPT_TIMESTAMP, diff --git a/libraries/octree/src/OctreePacketData.cpp b/libraries/octree/src/OctreePacketData.cpp index 493dfdcff5..b5b4a161ef 100644 --- a/libraries/octree/src/OctreePacketData.cpp +++ b/libraries/octree/src/OctreePacketData.cpp @@ -68,8 +68,8 @@ bool OctreePacketData::append(const unsigned char* data, int length) { _dirty = true; } - const bool wantDebug = false; - if (wantDebug && !success) { + #ifdef WANT_DEBUG + if (!success) { qCDebug(octree) << "OctreePacketData::append(const unsigned char* data, int length) FAILING...."; qCDebug(octree) << " length=" << length; qCDebug(octree) << " _bytesAvailable=" << _bytesAvailable; @@ -77,6 +77,7 @@ bool OctreePacketData::append(const unsigned char* data, int length) { qCDebug(octree) << " _targetSize=" << _targetSize; qCDebug(octree) << " _bytesReserved=" << _bytesReserved; } + #endif return success; } @@ -647,6 +648,13 @@ void OctreePacketData::debugContent() { printf("\n"); } +void OctreePacketData::debugBytes() { + qCDebug(octree) << " _bytesAvailable=" << _bytesAvailable; + qCDebug(octree) << " _bytesInUse=" << _bytesInUse; + qCDebug(octree) << " _targetSize=" << _targetSize; + qCDebug(octree) << " _bytesReserved=" << _bytesReserved; +} + int OctreePacketData::unpackDataFromBytes(const unsigned char* dataBytes, QString& result) { uint16_t length; memcpy(&length, dataBytes, sizeof(length)); diff --git a/libraries/octree/src/OctreePacketData.h b/libraries/octree/src/OctreePacketData.h index ed6a49941b..37c171504b 100644 --- a/libraries/octree/src/OctreePacketData.h +++ b/libraries/octree/src/OctreePacketData.h @@ -240,6 +240,7 @@ public: /// displays contents for debugging void debugContent(); + void debugBytes(); static quint64 getCompressContentTime() { return _compressContentTime; } /// total time spent compressing content static quint64 getCompressContentCalls() { return _compressContentCalls; } /// total calls to compress content diff --git a/tests/octree/src/OctreeTests.cpp b/tests/octree/src/OctreeTests.cpp index 64d68e8e13..81300a1293 100644 --- a/tests/octree/src/OctreeTests.cpp +++ b/tests/octree/src/OctreeTests.cpp @@ -74,7 +74,7 @@ void OctreeTests::propertyFlagsTests() { EntityPropertyFlags props; props.setHasProperty(PROP_VISIBLE); props.setHasProperty(PROP_POSITION); - props.setHasProperty(PROP_RADIUS); + props.setHasProperty(PROP_DIMENSIONS); props.setHasProperty(PROP_MODEL_URL); props.setHasProperty(PROP_COMPOUND_SHAPE_URL); props.setHasProperty(PROP_ROTATION); From 4a5f52155c8d60a0e7e52a56805691a01ab7c8f5 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sun, 5 Nov 2017 14:33:30 +1300 Subject: [PATCH 13/25] Pin node pointer --- assignment-client/src/entities/EntityTreeSendThread.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/assignment-client/src/entities/EntityTreeSendThread.cpp b/assignment-client/src/entities/EntityTreeSendThread.cpp index e96a9dc667..f5f8450de7 100644 --- a/assignment-client/src/entities/EntityTreeSendThread.cpp +++ b/assignment-client/src/entities/EntityTreeSendThread.cpp @@ -425,7 +425,8 @@ bool EntityTreeSendThread::traverseTreeAndBuildNextPacketPayload(EncodeBitstream uint64_t sendTime = usecTimestampNow(); auto nodeData = static_cast(params.nodeData); nodeData->stats.encodeStarted(); - auto entityNodeData = static_cast(_node.toStrongRef()->getLinkedData()); + auto entityNode = _node.toStrongRef(); + auto entityNodeData = static_cast(entityNode->getLinkedData()); while(!_sendQueue.empty()) { PrioritizedEntity queuedItem = _sendQueue.top(); EntityItemPointer entity = queuedItem.getEntity(); From a76b7855b5d29b887af4784fc538d33a0365272c Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sun, 5 Nov 2017 15:03:43 +1300 Subject: [PATCH 14/25] Record only explicitly filtered-in entities for flagging extras --- assignment-client/src/entities/EntityTreeSendThread.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/assignment-client/src/entities/EntityTreeSendThread.cpp b/assignment-client/src/entities/EntityTreeSendThread.cpp index f5f8450de7..a259dacecd 100644 --- a/assignment-client/src/entities/EntityTreeSendThread.cpp +++ b/assignment-client/src/entities/EntityTreeSendThread.cpp @@ -432,8 +432,12 @@ bool EntityTreeSendThread::traverseTreeAndBuildNextPacketPayload(EncodeBitstream EntityItemPointer entity = queuedItem.getEntity(); if (entity) { // Only send entities that match the jsonFilters, but keep track of everything we've tried to send so we don't try to send it again - if (entity->matchesJSONFilters(jsonFilters) || entityNodeData->isEntityFlaggedAsExtra(entity->getID())) { - entityNodeData->insertSentFilteredEntity(entity->getID()); + bool entityMatchesFilters = entity->matchesJSONFilters(jsonFilters); + if (entityMatchesFilters || entityNodeData->isEntityFlaggedAsExtra(entity->getID())) { + if (!jsonFilters.isEmpty() && entityMatchesFilters) { + // Record explicitly filtered-in entity so that extra entities can be flagged. + entityNodeData->insertSentFilteredEntity(entity->getID()); + } OctreeElement::AppendState appendEntityState = entity->appendEntityData(&_packetData, params, _extraEncodeData); if (appendEntityState != OctreeElement::COMPLETED) { From 05275afb4fe034461354cf1f8e0ebd3ba70969a6 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sun, 5 Nov 2017 15:48:02 +1300 Subject: [PATCH 15/25] Resending full scene is not necessary after all --- assignment-client/src/entities/EntityTreeSendThread.cpp | 6 +++--- assignment-client/src/entities/EntityTreeSendThread.h | 2 +- libraries/entities/src/DiffTraversal.cpp | 4 ++-- libraries/entities/src/DiffTraversal.h | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/assignment-client/src/entities/EntityTreeSendThread.cpp b/assignment-client/src/entities/EntityTreeSendThread.cpp index a259dacecd..11e4d533fb 100644 --- a/assignment-client/src/entities/EntityTreeSendThread.cpp +++ b/assignment-client/src/entities/EntityTreeSendThread.cpp @@ -96,7 +96,7 @@ void EntityTreeSendThread::traverseTreeAndSendContents(SharedNodePointer node, O nodeData->copyCurrentViewFrustum(viewFrustum); EntityTreeElementPointer root = std::dynamic_pointer_cast(_myServer->getOctree()->getRoot()); int32_t lodLevelOffset = nodeData->getBoundaryLevelAdjust() + (viewFrustumChanged ? LOW_RES_MOVING_ADJUST : NO_BOUNDARY_ADJUST); - startNewTraversal(viewFrustum, root, lodLevelOffset, nodeData->getUsesFrustum(), isFullScene); + startNewTraversal(viewFrustum, root, lodLevelOffset, nodeData->getUsesFrustum()); // When the viewFrustum changed the sort order may be incorrect, so we re-sort // and also use the opportunity to cull anything no longer in view @@ -205,9 +205,9 @@ bool EntityTreeSendThread::addDescendantsToExtraFlaggedEntities(const QUuid& fil } void EntityTreeSendThread::startNewTraversal(const ViewFrustum& view, EntityTreeElementPointer root, int32_t lodLevelOffset, - bool usesViewFrustum, bool isFullScene) { + bool usesViewFrustum) { - DiffTraversal::Type type = _traversal.prepareNewTraversal(view, root, lodLevelOffset, usesViewFrustum, isFullScene); + DiffTraversal::Type type = _traversal.prepareNewTraversal(view, root, lodLevelOffset, usesViewFrustum); // there are three types of traversal: // // (1) FirstTime = at login --> find everything in view diff --git a/assignment-client/src/entities/EntityTreeSendThread.h b/assignment-client/src/entities/EntityTreeSendThread.h index 1781de9890..a96a18494d 100644 --- a/assignment-client/src/entities/EntityTreeSendThread.h +++ b/assignment-client/src/entities/EntityTreeSendThread.h @@ -39,7 +39,7 @@ private: bool addDescendantsToExtraFlaggedEntities(const QUuid& filteredEntityID, EntityItem& entityItem, EntityNodeData& nodeData); void startNewTraversal(const ViewFrustum& viewFrustum, EntityTreeElementPointer root, int32_t lodLevelOffset, - bool usesViewFrustum, bool isFullScene); + bool usesViewFrustum); bool traverseTreeAndBuildNextPacketPayload(EncodeBitstreamParams& params, const QJsonObject& jsonFilters) override; void preDistributionProcessing() override; diff --git a/libraries/entities/src/DiffTraversal.cpp b/libraries/entities/src/DiffTraversal.cpp index 9b16ee90bf..764c420197 100644 --- a/libraries/entities/src/DiffTraversal.cpp +++ b/libraries/entities/src/DiffTraversal.cpp @@ -143,7 +143,7 @@ DiffTraversal::DiffTraversal() { } DiffTraversal::Type DiffTraversal::prepareNewTraversal(const ViewFrustum& viewFrustum, EntityTreeElementPointer root, - int32_t lodLevelOffset, bool usesViewFrustum, bool isFullScene) { + int32_t lodLevelOffset, bool usesViewFrustum) { assert(root); // there are three types of traversal: // @@ -164,7 +164,7 @@ DiffTraversal::Type DiffTraversal::prepareNewTraversal(const ViewFrustum& viewFr Type type; // If usesViewFrustum changes, treat it as a First traversal - if (_completedView.startTime == 0 || _currentView.usesViewFrustum != _completedView.usesViewFrustum || isFullScene) { + if (_completedView.startTime == 0 || _currentView.usesViewFrustum != _completedView.usesViewFrustum) { type = Type::First; _currentView.viewFrustum = viewFrustum; _currentView.lodScaleFactor = lodScaleFactor; diff --git a/libraries/entities/src/DiffTraversal.h b/libraries/entities/src/DiffTraversal.h index becf322fd5..eb7168356e 100644 --- a/libraries/entities/src/DiffTraversal.h +++ b/libraries/entities/src/DiffTraversal.h @@ -58,7 +58,7 @@ public: DiffTraversal(); Type prepareNewTraversal(const ViewFrustum& viewFrustum, EntityTreeElementPointer root, int32_t lodLevelOffset, - bool usesViewFrustum, bool isFullScene); + bool usesViewFrustum); const ViewFrustum& getCurrentView() const { return _currentView.viewFrustum; } const ViewFrustum& getCompletedView() const { return _completedView.viewFrustum; } From 9db0dd6fea01773b03f83fc65c6766b8da9952e2 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sun, 5 Nov 2017 20:38:37 +1300 Subject: [PATCH 16/25] Fix Asset Browser's "Copy URL" context menu --- interface/resources/qml/hifi/AssetServer.qml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/hifi/AssetServer.qml b/interface/resources/qml/hifi/AssetServer.qml index 5358ad1adc..37c3c2adab 100644 --- a/interface/resources/qml/hifi/AssetServer.qml +++ b/interface/resources/qml/hifi/AssetServer.qml @@ -16,10 +16,10 @@ import Qt.labs.settings 1.0 import "../styles-uit" import "../controls-uit" as HifiControls -import "../windows" +import "../windows" as Windows import "../dialogs" -ScrollingWindow { +Windows.ScrollingWindow { id: root objectName: "AssetServer" title: "Asset Browser" From e2ca3c6de04e6662f83ff80f550871220bd8afb8 Mon Sep 17 00:00:00 2001 From: Midnight Date: Sun, 5 Nov 2017 13:39:26 -0700 Subject: [PATCH 17/25] Fix lib file path Changed the include to what should be the correct file path. it does not exist in the controllers folder. --- scripts/system/libraries/cloneEntityUtils.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/system/libraries/cloneEntityUtils.js b/scripts/system/libraries/cloneEntityUtils.js index 777504b16d..63b161eb80 100644 --- a/scripts/system/libraries/cloneEntityUtils.js +++ b/scripts/system/libraries/cloneEntityUtils.js @@ -8,8 +8,7 @@ /* global entityIsCloneable:true, getGrabbableData:true, cloneEntity:true, propsAreCloneDynamic:true, Script, propsAreCloneDynamic:true, Entities*/ -Script.include("/~/system/controllers/controllerDispatcherUtils.js"); - +Script.include("/~/system/libraries/controllerDispatcherUtils.js"); // Object assign polyfill if (typeof Object.assign !== 'function') { From bb21c52783dba74bae3a32eff1266306c8a0f5c8 Mon Sep 17 00:00:00 2001 From: Zach Fox Date: Mon, 6 Nov 2017 15:12:01 -0800 Subject: [PATCH 18/25] Fix crash when logging out while Passphrase screen visible --- interface/src/commerce/QmlCommerce.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/commerce/QmlCommerce.cpp b/interface/src/commerce/QmlCommerce.cpp index 9d07ddb4ab..f29e46d843 100644 --- a/interface/src/commerce/QmlCommerce.cpp +++ b/interface/src/commerce/QmlCommerce.cpp @@ -33,7 +33,7 @@ QmlCommerce::QmlCommerce(QQuickItem* parent) : OffscreenQmlDialog(parent) { connect(ledger.data(), &Ledger::updateCertificateStatus, this, &QmlCommerce::updateCertificateStatus); auto accountManager = DependencyManager::get(); - connect(accountManager.data(), &AccountManager::usernameChanged, [&]() { + connect(accountManager.data(), &AccountManager::usernameChanged, this, [&]() { setPassphrase(""); }); } From 3b15897b123e40d6faa1dab4edb46bc36f77fd04 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Mon, 6 Nov 2017 15:21:20 -0800 Subject: [PATCH 19/25] fixed farGrab parent grabbing and laser LockEndUUID --- interface/src/raypick/LaserPointer.cpp | 11 +- interface/src/raypick/LaserPointer.h | 3 +- interface/src/raypick/LaserPointerManager.cpp | 4 +- interface/src/raypick/LaserPointerManager.h | 2 +- .../raypick/LaserPointerScriptingInterface.h | 2 +- .../controllerModules/farActionGrabEntity.js | 107 +++++++++++------- .../libraries/controllerDispatcherUtils.js | 10 -- 7 files changed, 78 insertions(+), 61 deletions(-) diff --git a/interface/src/raypick/LaserPointer.cpp b/interface/src/raypick/LaserPointer.cpp index 9da8ff34ac..0d691911c8 100644 --- a/interface/src/raypick/LaserPointer.cpp +++ b/interface/src/raypick/LaserPointer.cpp @@ -25,7 +25,7 @@ LaserPointer::LaserPointer(const QVariant& rayProps, const RenderStateMap& rende _distanceScaleEnd(distanceScaleEnd), _rayPickUID(DependencyManager::get()->createRayPick(rayProps)) { - + _offsetMat = glm::mat4(); for (auto& state : _renderStates) { if (!enabled || state.first != _currentRenderState) { @@ -134,8 +134,10 @@ void LaserPointer::updateRenderState(const RenderState& renderState, const Inter registrationPoint = glm::vec3(0.5f); } else { EntityItemProperties props = DependencyManager::get()->getEntityProperties(_objectLockEnd.first); - pos = props.getPosition(); - rot = props.getRotation(); + glm::mat4 entityMat = createMatFromQuatAndPos(props.getRotation(), props.getPosition()); + glm::mat4 finalPosAndRotMat = entityMat * _offsetMat; + pos = extractTranslation(finalPosAndRotMat); + rot = glmExtractRotation(finalPosAndRotMat); dim = props.getDimensions(); registrationPoint = props.getRegistrationPoint(); } @@ -233,9 +235,10 @@ void LaserPointer::setLaserLength(const float laserLength) { }); } -void LaserPointer::setLockEndUUID(QUuid objectID, const bool isOverlay, const glm::mat4& offset) { +void LaserPointer::setLockEndUUID(QUuid objectID, const bool isOverlay, const glm::mat4& offsetMat) { withWriteLock([&] { _objectLockEnd = std::pair(objectID, isOverlay); + _offsetMat = offsetMat; }); } diff --git a/interface/src/raypick/LaserPointer.h b/interface/src/raypick/LaserPointer.h index a80f9d447d..40a7d93356 100644 --- a/interface/src/raypick/LaserPointer.h +++ b/interface/src/raypick/LaserPointer.h @@ -74,7 +74,7 @@ public: void setPrecisionPicking(const bool precisionPicking); void setLaserLength(const float laserLength); - void setLockEndUUID(QUuid objectID, const bool isOverlay, const glm::mat4& offset = glm::mat4()); + void setLockEndUUID(QUuid objectID, const bool isOverlay, const glm::mat4& offsetMat = glm::mat4()); void setIgnoreItems(const QVector& ignoreItems) const; void setIncludeItems(const QVector& includeItems) const; @@ -91,6 +91,7 @@ private: bool _centerEndY; bool _lockEnd; bool _distanceScaleEnd; + glm::mat4 _offsetMat; std::pair _objectLockEnd { std::pair(QUuid(), false)}; const QUuid _rayPickUID; diff --git a/interface/src/raypick/LaserPointerManager.cpp b/interface/src/raypick/LaserPointerManager.cpp index 9d58cc2587..45420d1488 100644 --- a/interface/src/raypick/LaserPointerManager.cpp +++ b/interface/src/raypick/LaserPointerManager.cpp @@ -113,9 +113,9 @@ void LaserPointerManager::setIncludeItems(const QUuid& uid, const QVector } } -void LaserPointerManager::setLockEndUUID(const QUuid& uid, const QUuid& objectID, const bool isOverlay) const { +void LaserPointerManager::setLockEndUUID(const QUuid& uid, const QUuid& objectID, const bool isOverlay, const glm::mat4& offsetMat) const { auto laserPointer = find(uid); if (laserPointer) { - laserPointer->setLockEndUUID(objectID, isOverlay); + laserPointer->setLockEndUUID(objectID, isOverlay, offsetMat); } } diff --git a/interface/src/raypick/LaserPointerManager.h b/interface/src/raypick/LaserPointerManager.h index e302318483..25089a291a 100644 --- a/interface/src/raypick/LaserPointerManager.h +++ b/interface/src/raypick/LaserPointerManager.h @@ -39,7 +39,7 @@ public: void setIgnoreItems(const QUuid& uid, const QVector& ignoreEntities) const; void setIncludeItems(const QUuid& uid, const QVector& includeEntities) const; - void setLockEndUUID(const QUuid& uid, const QUuid& objectID, const bool isOverlay) const; + void setLockEndUUID(const QUuid& uid, const QUuid& objectID, const bool isOverlay, const glm::mat4& offsetMat = glm::mat4()) const; void update(); diff --git a/interface/src/raypick/LaserPointerScriptingInterface.h b/interface/src/raypick/LaserPointerScriptingInterface.h index 19262e6e5d..986c53e24f 100644 --- a/interface/src/raypick/LaserPointerScriptingInterface.h +++ b/interface/src/raypick/LaserPointerScriptingInterface.h @@ -35,7 +35,7 @@ public slots: Q_INVOKABLE void setIgnoreItems(const QUuid& uid, const QScriptValue& ignoreEntities) const; Q_INVOKABLE void setIncludeItems(const QUuid& uid, const QScriptValue& includeEntities) const; - Q_INVOKABLE void setLockEndUUID(const QUuid& uid, const QUuid& objectID, bool isOverlay) const { qApp->getLaserPointerManager().setLockEndUUID(uid, objectID, isOverlay); } + Q_INVOKABLE void setLockEndUUID(const QUuid& uid, const QUuid& objectID, bool isOverlay, const glm::mat4& offsetMat = glm::mat4()) const { qApp->getLaserPointerManager().setLockEndUUID(uid, objectID, isOverlay, offsetMat); } private: static RenderState buildRenderState(const QVariantMap& propMap); diff --git a/scripts/system/controllers/controllerModules/farActionGrabEntity.js b/scripts/system/controllers/controllerModules/farActionGrabEntity.js index e63d7c7c35..7d9a6dc1b5 100644 --- a/scripts/system/controllers/controllerModules/farActionGrabEntity.js +++ b/scripts/system/controllers/controllerModules/farActionGrabEntity.js @@ -13,13 +13,13 @@ makeDispatcherModuleParameters, MSECS_PER_SEC, HAPTIC_PULSE_STRENGTH, HAPTIC_PULSE_DURATION, PICK_MAX_DISTANCE, COLORS_GRAB_SEARCHING_HALF_SQUEEZE, COLORS_GRAB_SEARCHING_FULL_SQUEEZE, COLORS_GRAB_DISTANCE_HOLD, DEFAULT_SEARCH_SPHERE_DISTANCE, TRIGGER_OFF_VALUE, TRIGGER_ON_VALUE, ZERO_VEC, ensureDynamic, - getControllerWorldLocation, projectOntoEntityXYPlane, ContextOverlay, HMD, Reticle, Overlays, isPointingAtUI + getControllerWorldLocation, projectOntoEntityXYPlane, ContextOverlay, HMD, Reticle, Overlays, isPointingAtUI, Xform, getEntityParents */ Script.include("/~/system/libraries/controllerDispatcherUtils.js"); Script.include("/~/system/libraries/controllers.js"); -Script.include("/~/system/libraries/Xform.hs"); +Script.include("/~/system/libraries/Xform.js"); (function() { var PICK_WITH_HAND_RAY = true; @@ -115,32 +115,53 @@ Script.include("/~/system/libraries/Xform.hs"); var MARGIN = 25; - function TargetObject(entityID) { + function TargetObject(entityID, entityProps) { this.entityID = entityID; - this.entityProps = null; - this.parentID = null; - this.parentProps = []; - this.childrenProps = []; - this.parentsCollisionStatus = []; - this.childrenCollisionStatus = []; + this.entityProps = entityProps; + this.targetEntityID = null; + this.targetEntityProps = null; + this.previousCollisionStatus = null; this.madeDynamic = null; - this.parentEntityProps = null; this.makeDynamic = function() { + if (this.targetEntityID) { + var newProps = { + dynamic: true, + collisionless: true + }; + this.previousCollisionStatus = this.targetEntityProps.collisionless; + Entities.editEntity(this.targetEntityID, newProps); + this.madeDynamic = true; + } }; - this.saveCollisionStatus = function() { - }; - - this.restoreEntitiesProperties = function() { + this.restoreTargetEntityOriginalProps = function() { + if (this.madeDynamic) { + var props = {}; + props.dynamic = false; + props.collisionless = this.previousCollisionStatus; + var zeroVector = {x: 0, y: 0, z:0}; + props.localVelocity = zeroVector; + props.localRotation = zeroVector; + Entities.editEntity(this.targetEntityID, props); + } }; this.getTargetEntity = function() { var parentPropsLength = this.parentProps.length; if (parentPropsLength !== 0) { - return this.parentProps[parentPropsLength].id; + var targetEntity = { + id: this.parentProps[parentPropsLength - 1].id, + props: this.parentProps[parentPropsLength - 1]}; + this.targetEntityID = targetEntity.id; + this.targetEntityProps = targetEntity.props; + return targetEntity; } - return this.entityID; + this.targetEntityID = this.entityID; + this.targetEntityProps = this.entityProps; + return { + id: this.entityID, + props: this.entityProps}; }; } @@ -153,11 +174,11 @@ Script.include("/~/system/libraries/Xform.hs"); this.entityWithContextOverlay = false; this.contextOverlayTimer = false; this.previousCollisionStatus = false; + this.locked = false; this.reticleMinX = MARGIN; this.reticleMaxX; this.reticleMinY = MARGIN; this.reticleMaxY; - this.madeDynamic = false; var ACTION_TTL = 15; // seconds @@ -191,10 +212,25 @@ Script.include("/~/system/libraries/Xform.hs"); LaserPointers.enableLaserPointer(laserPointerID); LaserPointers.setRenderState(laserPointerID, mode); if (this.distanceHolding || this.distanceRotating) { - // calculate offset - LaserPointers.setLockEndUUID(laserPointerID, this.entityToLockOnto, this.grabbedIsOverlay); + if (!this.locked) { + // calculate offset + var targetProps = Entities.getEntityProperties(this.targetObject.entityID, [ + "position", + "rotation" + ]); + var zeroVector = { x: 0, y: 0, z:0, w: 0 }; + var intersection = controllerData.rayPicks[this.hand].intersection; + var intersectionMat = new Xform(zeroVector, intersection); + var modelMat = new Xform(targetProps.rotation, targetProps.position); + var modelMatInv = modelMat.inv(); + var xformMat = Xform.mul(modelMatInv, intersectionMat); + var offsetMat = Mat4.createFromRotAndTrans(xformMat.rot, xformMat.pos); + LaserPointers.setLockEndUUID(laserPointerID, this.targetObject.entityID, this.grabbedIsOverlay, offsetMat); + this.locked = true; + } } else { LaserPointers.setLockEndUUID(laserPointerID, null, false); + this.locked = false; } }; @@ -373,22 +409,15 @@ Script.include("/~/system/libraries/Xform.hs"); var args = [this.hand === RIGHT_HAND ? "right" : "left", MyAvatar.sessionUUID]; Entities.callEntityMethod(this.grabbedThingID, "releaseGrab", args); - - if (this.madeDynamic) { - var props = {}; - props.dynamic = false; - props.collisionless = this.previousCollisionStatus; - props.localVelocity = {x: 0, y: 0, z: 0}; - props.localRotation = {x: 0, y: 0, z: 0}; - Entities.editEntity(this.grabbedThingID, props); - this.madeDynamic = false; + if (this.targetObject) { + this.targetObject.restoreTargetEntityOriginalProps(); } this.actionID = null; this.grabbedThingID = null; - this.entityToLockOnto = null; + this.targetObject = null; }; - this.updateRecommendedArea = function() { + this.updateRecommendedArea = function() { var dims = Controller.getViewportDimensions(); this.reticleMaxX = dims.x - MARGIN; this.reticleMaxY = dims.y - MARGIN; @@ -532,30 +561,24 @@ Script.include("/~/system/libraries/Xform.hs"); if (rayPickInfo.type === RayPick.INTERSECTED_ENTITY) { if (controllerData.triggerClicks[this.hand]) { var entityID = rayPickInfo.objectID; - this.entityToLockOnto = entityID; var targetProps = Entities.getEntityProperties(entityID, [ "dynamic", "shapeType", "position", "rotation", "dimensions", "density", "userData", "locked", "type" ]); - this.targetObject = new TargetObject(entityID); + this.targetObject = new TargetObject(entityID, targetProps); + this.targetObject.parentProps = getEntityParents(targetProps); if (entityID !== this.entityWithContextOverlay) { this.destroyContextOverlay(); } + var targetEntity = this.targetObject.getTargetEntity(); + entityID = targetEntity.id; + targetProps = targetEntity.props; if (entityIsGrabbable(targetProps)) { - var groupRootProps = findGroupParent(controllerData, targetProps); - if (entityIsGrabbable(groupRootProps)) { - targetProps = groupRootProps; - entityID = targetProps.id; - } if (!entityIsDistanceGrabbable(targetProps)) { - targetProps.dynamic = true; - this.previousCollisionStatus = targetProps.collisionless; - targetProps.collisionless = true; - Entities.editEntity(entityID, targetProps); - this.madeDynamic = true; + this.targetObject.makeDynamic(); } if (!this.distanceRotating) { diff --git a/scripts/system/libraries/controllerDispatcherUtils.js b/scripts/system/libraries/controllerDispatcherUtils.js index 148530c5ec..fb6de0e683 100644 --- a/scripts/system/libraries/controllerDispatcherUtils.js +++ b/scripts/system/libraries/controllerDispatcherUtils.js @@ -308,16 +308,6 @@ findGroupParent = function (controllerData, targetProps) { return targetProps; }; -getChildrenProps = function(entityID) { - var childrenProps = []; - var childrenIDs = Entities.getChildrenIDs(entityID); - for (var index = 0; index < childrenIDs.length; index++) { - var childProps = Entities.getEntityProperties(childrenIDs[index]); - childrenProps.push(childProps); - } - return childrenProps; -}; - getEntityParents = function(targetProps) { var parentProperties = []; while (targetProps.parentID && From 41c6261b74d0d591a908fa31f255e07354eef803 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Mon, 6 Nov 2017 16:04:33 -0800 Subject: [PATCH 20/25] LaserPointer: made _objectLockEnd into a struct --- interface/src/raypick/LaserPointer.cpp | 23 ++++++++++++----------- interface/src/raypick/LaserPointer.h | 8 +++++++- 2 files changed, 19 insertions(+), 12 deletions(-) diff --git a/interface/src/raypick/LaserPointer.cpp b/interface/src/raypick/LaserPointer.cpp index 0d691911c8..f3d74d18a5 100644 --- a/interface/src/raypick/LaserPointer.cpp +++ b/interface/src/raypick/LaserPointer.cpp @@ -119,23 +119,23 @@ void LaserPointer::updateRenderState(const RenderState& renderState, const Inter qApp->getOverlays().editOverlay(renderState.getStartID(), startProps); } glm::vec3 endVec; - if (((defaultState || !_lockEnd) && _objectLockEnd.first.isNull()) || type == IntersectionType::HUD) { + if (((defaultState || !_lockEnd) && _lockEndObject.id.isNull()) || type == IntersectionType::HUD) { endVec = pickRay.origin + pickRay.direction * distance; } else { - if (!_objectLockEnd.first.isNull()) { + if (!_lockEndObject.id.isNull()) { glm::vec3 pos; glm::quat rot; glm::vec3 dim; glm::vec3 registrationPoint; - if (_objectLockEnd.second) { - pos = vec3FromVariant(qApp->getOverlays().getProperty(_objectLockEnd.first, "position").value); - rot = quatFromVariant(qApp->getOverlays().getProperty(_objectLockEnd.first, "rotation").value); - dim = vec3FromVariant(qApp->getOverlays().getProperty(_objectLockEnd.first, "dimensions").value); + if (_lockEndObject.isOverlay) { + pos = vec3FromVariant(qApp->getOverlays().getProperty(_lockEndObject.id, "position").value); + rot = quatFromVariant(qApp->getOverlays().getProperty(_lockEndObject.id, "rotation").value); + dim = vec3FromVariant(qApp->getOverlays().getProperty(_lockEndObject.id, "dimensions").value); registrationPoint = glm::vec3(0.5f); } else { - EntityItemProperties props = DependencyManager::get()->getEntityProperties(_objectLockEnd.first); + EntityItemProperties props = DependencyManager::get()->getEntityProperties(_lockEndObject.id); glm::mat4 entityMat = createMatFromQuatAndPos(props.getRotation(), props.getPosition()); - glm::mat4 finalPosAndRotMat = entityMat * _offsetMat; + glm::mat4 finalPosAndRotMat = entityMat * _lockEndObject.offsetMat; pos = extractTranslation(finalPosAndRotMat); rot = glmExtractRotation(finalPosAndRotMat); dim = props.getDimensions(); @@ -211,7 +211,7 @@ void LaserPointer::update() { withReadLock([&] { RayPickResult prevRayPickResult = qApp->getRayPickManager().getPrevRayPickResult(_rayPickUID); if (_renderingEnabled && !_currentRenderState.empty() && _renderStates.find(_currentRenderState) != _renderStates.end() && - (prevRayPickResult.type != IntersectionType::NONE || _laserLength > 0.0f || !_objectLockEnd.first.isNull())) { + (prevRayPickResult.type != IntersectionType::NONE || _laserLength > 0.0f || !_lockEndObject.id.isNull())) { float distance = _laserLength > 0.0f ? _laserLength : prevRayPickResult.distance; updateRenderState(_renderStates[_currentRenderState], prevRayPickResult.type, distance, prevRayPickResult.objectID, prevRayPickResult.searchRay, false); disableRenderState(_defaultRenderStates[_currentRenderState].second); @@ -237,8 +237,9 @@ void LaserPointer::setLaserLength(const float laserLength) { void LaserPointer::setLockEndUUID(QUuid objectID, const bool isOverlay, const glm::mat4& offsetMat) { withWriteLock([&] { - _objectLockEnd = std::pair(objectID, isOverlay); - _offsetMat = offsetMat; + _lockEndObject.id = objectID; + _lockEndObject.isOverlay; + _lockEndObject.offsetMat = offsetMat; }); } diff --git a/interface/src/raypick/LaserPointer.h b/interface/src/raypick/LaserPointer.h index 40a7d93356..2171698cc5 100644 --- a/interface/src/raypick/LaserPointer.h +++ b/interface/src/raypick/LaserPointer.h @@ -21,6 +21,12 @@ class RayPickResult; +struct LockEndObject { + QUuid id {QUuid()}; + bool isOverlay {false}; + glm::mat4 offsetMat {glm::mat4()}; +}; + class RenderState { public: @@ -91,8 +97,8 @@ private: bool _centerEndY; bool _lockEnd; bool _distanceScaleEnd; + LockEndObject _lockEndObject; glm::mat4 _offsetMat; - std::pair _objectLockEnd { std::pair(QUuid(), false)}; const QUuid _rayPickUID; From 646e5455ac8c4eee8454da1c3fa498196e50e67c Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Mon, 6 Nov 2017 16:05:44 -0800 Subject: [PATCH 21/25] forgot to remove unused variable --- interface/src/raypick/LaserPointer.h | 1 - 1 file changed, 1 deletion(-) diff --git a/interface/src/raypick/LaserPointer.h b/interface/src/raypick/LaserPointer.h index 2171698cc5..32ef189d76 100644 --- a/interface/src/raypick/LaserPointer.h +++ b/interface/src/raypick/LaserPointer.h @@ -98,7 +98,6 @@ private: bool _lockEnd; bool _distanceScaleEnd; LockEndObject _lockEndObject; - glm::mat4 _offsetMat; const QUuid _rayPickUID; From 067ed2ffe064126065852ec83cd56306421e206d Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Mon, 6 Nov 2017 16:09:31 -0800 Subject: [PATCH 22/25] apply coding standard --- interface/src/raypick/LaserPointer.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/raypick/LaserPointer.h b/interface/src/raypick/LaserPointer.h index 32ef189d76..896752a96e 100644 --- a/interface/src/raypick/LaserPointer.h +++ b/interface/src/raypick/LaserPointer.h @@ -22,9 +22,9 @@ class RayPickResult; struct LockEndObject { - QUuid id {QUuid()}; - bool isOverlay {false}; - glm::mat4 offsetMat {glm::mat4()}; + QUuid id { QUuid() }; + bool isOverlay { false }; + glm::mat4 offsetMat { glm::mat4() }; }; class RenderState { From c9d67f762bbcd1db95b73faf7f624fd3c8eacd39 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Mon, 6 Nov 2017 16:20:16 -0800 Subject: [PATCH 23/25] made requested changes --- interface/src/raypick/LaserPointer.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/interface/src/raypick/LaserPointer.cpp b/interface/src/raypick/LaserPointer.cpp index f3d74d18a5..32dd74279b 100644 --- a/interface/src/raypick/LaserPointer.cpp +++ b/interface/src/raypick/LaserPointer.cpp @@ -25,7 +25,6 @@ LaserPointer::LaserPointer(const QVariant& rayProps, const RenderStateMap& rende _distanceScaleEnd(distanceScaleEnd), _rayPickUID(DependencyManager::get()->createRayPick(rayProps)) { - _offsetMat = glm::mat4(); for (auto& state : _renderStates) { if (!enabled || state.first != _currentRenderState) { @@ -238,7 +237,7 @@ void LaserPointer::setLaserLength(const float laserLength) { void LaserPointer::setLockEndUUID(QUuid objectID, const bool isOverlay, const glm::mat4& offsetMat) { withWriteLock([&] { _lockEndObject.id = objectID; - _lockEndObject.isOverlay; + _lockEndObject.isOverlay = isOverlay; _lockEndObject.offsetMat = offsetMat; }); } From 60319e8d53a3605dc5cefc0f70e275357eacf364 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 7 Nov 2017 13:35:31 +1300 Subject: [PATCH 24/25] Don't move or rotate entities if Alt or Meta keys are pressed --- scripts/system/controllers/grab.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/system/controllers/grab.js b/scripts/system/controllers/grab.js index a1846e7ad7..eaa15ee3b1 100644 --- a/scripts/system/controllers/grab.js +++ b/scripts/system/controllers/grab.js @@ -315,6 +315,10 @@ Grabber.prototype.pressEvent = function(event) { return; } + if (event.isAlt || event.isMeta) { + return; + } + if (Overlays.getOverlayAtPoint(Reticle.position) > 0) { // the mouse is pointing at an overlay; don't look for entities underneath the overlay. return; From fadbf09cdd659569b4f8df988a9e23a48571c111 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 7 Nov 2017 18:10:10 +1300 Subject: [PATCH 25/25] Avoid potentially slow entity list refresh upon deleting entities --- scripts/system/edit.js | 13 +++++++++++-- scripts/system/html/js/entityList.js | 7 ++++++- 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/scripts/system/edit.js b/scripts/system/edit.js index e76a02b6f5..ba84ffd716 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -1333,7 +1333,7 @@ function sortSelectedEntities(selected) { return sortedEntities; } -function recursiveDelete(entities, childrenList) { +function recursiveDelete(entities, childrenList, deletedIDs) { var entitiesLength = entities.length; for (var i = 0; i < entitiesLength; i++) { var entityID = entities[i]; @@ -1346,6 +1346,7 @@ function recursiveDelete(entities, childrenList) { properties: initialProperties, children: grandchildrenList }); + deletedIDs.push(entityID); Entities.deleteEntity(entityID); } } @@ -1413,6 +1414,8 @@ function parentSelectedEntities() { } function deleteSelectedEntities() { if (SelectionManager.hasSelection()) { + var deletedIDs = []; + selectedParticleEntityID = null; particleExplorerTool.destroyWebView(); SelectionManager.saveProperties(); @@ -1423,16 +1426,22 @@ function deleteSelectedEntities() { var initialProperties = SelectionManager.savedProperties[entityID]; var children = Entities.getChildrenIDs(entityID); var childList = []; - recursiveDelete(children, childList); + recursiveDelete(children, childList, deletedIDs); savedProperties.push({ entityID: entityID, properties: initialProperties, children: childList }); + deletedIDs.push(entityID); Entities.deleteEntity(entityID); } SelectionManager.clearSelections(); pushCommandForSelections([], savedProperties); + + entityListTool.webView.emitScriptEvent(JSON.stringify({ + type: "deleted", + ids: deletedIDs + })); } } diff --git a/scripts/system/html/js/entityList.js b/scripts/system/html/js/entityList.js index ea79750154..7b25e66c67 100644 --- a/scripts/system/html/js/entityList.js +++ b/scripts/system/html/js/entityList.js @@ -286,7 +286,6 @@ function loaded() { } elDelete.onclick = function() { EventBridge.emitWebEvent(JSON.stringify({ type: 'delete' })); - refreshEntities(); } document.addEventListener("keydown", function (keyDownEvent) { @@ -362,6 +361,12 @@ function loaded() { updateSelectedEntities(data.selectedIDs); resize(); } + } else if (data.type === "deleted") { + for (i = 0, length = data.ids.length; i < length; i++) { + delete entities[data.ids[i]]; + entityList.remove("id", data.ids[i]); + } + refreshFooter(); } }); setTimeout(refreshEntities, 1000);