diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 84d6689e92..2ccc540105 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -5310,7 +5310,7 @@ void MyAvatar::releaseGrab(const QUuid& grabID) { _avatarGrabsLock.withWriteLock([&] { if (_avatarGrabData.remove(grabID)) { - _deletedAvatarGrabs.insert(grabID); + _deletedAvatarGrabs.push_back(grabID); tellHandler = true; } }); diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index c5f5725594..d27a3026af 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -331,19 +331,18 @@ bool Avatar::updateGrabs() { } bool grabAddedOrRemoved = false; - // update the Grabs according to any changes in _avatarGrabData _avatarGrabsLock.withWriteLock([&] { if (_avatarGrabDataChanged) { + // collect changes in _avatarGrabData foreach (auto grabID, _avatarGrabData.keys()) { - AvatarGrabMap::iterator grabItr = _avatarGrabs.find(grabID); - if (grabItr == _avatarGrabs.end()) { + MapOfGrabs::iterator itr = _avatarGrabs.find(grabID); + if (itr == _avatarGrabs.end()) { GrabPointer grab = std::make_shared(); grab->fromByteArray(_avatarGrabData.value(grabID)); _avatarGrabs[grabID] = grab; _changedAvatarGrabs.insert(grabID); } else { - GrabPointer grab = grabItr.value(); - bool changed = grab->fromByteArray(_avatarGrabData.value(grabID)); + bool changed = itr->second->fromByteArray(_avatarGrabData.value(grabID)); if (changed) { _changedAvatarGrabs.insert(grabID); } @@ -352,40 +351,38 @@ bool Avatar::updateGrabs() { _avatarGrabDataChanged = false; } - QMutableSetIterator delItr(_deletedAvatarGrabs); - while (delItr.hasNext()) { - QUuid grabID = delItr.next(); - GrabPointer grab = _avatarGrabs[grabID]; - if (!grab) { - delItr.remove(); + // delete _avatarGrabs + VectorOfIDs undeleted; + for (const auto& id : _deletedAvatarGrabs) { + MapOfGrabs::iterator itr = _avatarGrabs.find(id); + if (itr == _avatarGrabs.end()) { continue; } bool success; + const GrabPointer& grab = itr->second; SpatiallyNestablePointer target = SpatiallyNestable::findByID(grab->getTargetID(), success); - - // only clear this entry from the _deletedAvatarGrabs if we found the entity. if (success && target) { target->removeGrab(grab); - delItr.remove(); + _avatarGrabs.erase(itr); grabAddedOrRemoved = true; + } else { + undeleted.push_back(id); } - _avatarGrabs.remove(grabID); - _changedAvatarGrabs.remove(grabID); } + _deletedAvatarGrabs = std::move(undeleted); - QMutableSetIterator changeItr(_changedAvatarGrabs); - while (changeItr.hasNext()) { - QUuid grabID = changeItr.next(); - GrabPointer& grab = _avatarGrabs[grabID]; - if (!grab) { - changeItr.remove(); + // change _avatarGrabs and add Actions to target + SetOfIDs unchanged; + for (const auto& id : _changedAvatarGrabs) { + MapOfGrabs::iterator itr = _avatarGrabs.find(id); + if (itr == _avatarGrabs.end()) { continue; } bool success; + const GrabPointer& grab = itr->second; SpatiallyNestablePointer target = SpatiallyNestable::findByID(grab->getTargetID(), success); - if (success && target) { target->addGrab(grab); if (isMyAvatar()) { @@ -394,11 +391,12 @@ bool Avatar::updateGrabs() { entity->upgradeScriptSimulationPriority(PERSONAL_SIMULATION_PRIORITY); } } - // only clear this entry from the _changedAvatarGrabs if we found the entity. - changeItr.remove(); grabAddedOrRemoved = true; + } else { + unchanged.insert(id); } } + _changedAvatarGrabs = std::move(unchanged); }); return grabAddedOrRemoved; } @@ -406,8 +404,8 @@ bool Avatar::updateGrabs() { void Avatar::accumulateGrabPositions(std::map& grabAccumulators) { // relay avatar's joint position to grabbed target in a way that allows for averaging _avatarGrabsLock.withReadLock([&] { - foreach (auto grabID, _avatarGrabs.keys()) { - const GrabPointer& grab = _avatarGrabs.value(grabID); + for (const auto& entry : _avatarGrabs) { + const GrabPointer& grab = entry.second; if (!grab || !grab->getActionID().isNull()) { continue; // the accumulated value isn't used, in this case. @@ -1922,3 +1920,12 @@ scriptable::ScriptableModelBase Avatar::getScriptableModel() { } return result; } + +void Avatar::clearAvatarGrabData(const QUuid& id) { + AvatarData::clearAvatarGrabData(id); + _avatarGrabsLock.withWriteLock([&] { + if (_avatarGrabs.find(id) == _avatarGrabs.end()) { + _deletedAvatarGrabs.push_back(id); + } + }); +} diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h index d5431ad2d2..75ae697603 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h @@ -14,6 +14,9 @@ #include #include #include +#include +#include +#include #include @@ -23,10 +26,12 @@ #include #include +#include +#include + #include "Head.h" #include "SkeletonModel.h" #include "Rig.h" -#include #include "MetaModelPayload.h" @@ -625,8 +630,15 @@ protected: static void metaBlendshapeOperator(render::ItemID renderItemID, int blendshapeNumber, const QVector& blendshapeOffsets, const QVector& blendedMeshSizes, const render::ItemIDs& subItemIDs); + void clearAvatarGrabData(const QUuid& grabID) override; - AvatarGrabMap _avatarGrabs; + using SetOfIDs = std::set; + using VectorOfIDs = std::vector; + using MapOfGrabs = std::map; + + MapOfGrabs _avatarGrabs; + SetOfIDs _changedAvatarGrabs; // updated grab IDs -- changes needed to entities or physics + VectorOfIDs _deletedAvatarGrabs; // deleted grab IDs -- changes needed to entities or physics }; #endif // hifi_Avatar_h diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index ba3845e8e7..f4981d7347 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -2997,7 +2997,6 @@ void AvatarData::clearAvatarGrabData(const QUuid& grabID) { _avatarGrabsLock.withWriteLock([&] { if (_avatarGrabData.remove(grabID)) { _avatarGrabDataChanged = true; - _deletedAvatarGrabs.insert(grabID); } }); } diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index 2889e5ffa3..9aabf9cb9d 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -54,7 +54,6 @@ #include "AvatarTraits.h" #include "HeadData.h" #include "PathUtils.h" -#include "Grab.h" #include @@ -67,8 +66,6 @@ using PackedAvatarEntityMap = QMap; // similar to AvatarEntit using AvatarEntityIDs = QSet; using AvatarGrabDataMap = QMap; -using AvatarGrabIDs = QSet; -using AvatarGrabMap = QMap; using AvatarDataSequenceNumber = uint16_t; @@ -1473,8 +1470,6 @@ protected: mutable ReadWriteLockable _avatarGrabsLock; AvatarGrabDataMap _avatarGrabData; bool _avatarGrabDataChanged { false }; // by network - AvatarGrabIDs _changedAvatarGrabs; // updated grab IDs -- changes needed to entities or physics - AvatarGrabIDs _deletedAvatarGrabs; // deleted grab IDs -- changes needed to entities or physics // used to transform any sensor into world space, including the _hmdSensorMat, or hand controllers. ThreadSafeValueCache _sensorToWorldMatrixCache { glm::mat4() }; @@ -1537,7 +1532,7 @@ protected: } bool updateAvatarGrabData(const QUuid& grabID, const QByteArray& grabData); - void clearAvatarGrabData(const QUuid& grabID); + virtual void clearAvatarGrabData(const QUuid& grabID); private: friend void avatarStateFromFrame(const QByteArray& frameData, AvatarData* _avatar);