From ff746c31413d2aebe4a651dd1681a8cff31f227c Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 11 Feb 2019 12:19:33 -0800 Subject: [PATCH 1/4] flag collision group/mask dirty after grab --- libraries/entities/src/EntityItem.cpp | 33 +++++++++++++++++++-------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 1fb1ebb1bc..777f9ba167 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1897,7 +1897,7 @@ glm::vec3 EntityItem::getUnscaledDimensions() const { void EntityItem::setRotation(glm::quat rotation) { if (getLocalOrientation() != rotation) { setLocalOrientation(rotation); - _flags |= Simulation::DIRTY_ROTATION; + markDirtyFlags(Simulation::DIRTY_ROTATION); forEachDescendant([&](SpatiallyNestablePointer object) { if (object->getNestableType() == NestableType::Entity) { EntityItemPointer entity = std::static_pointer_cast(object); @@ -1927,7 +1927,7 @@ void EntityItem::setVelocity(const glm::vec3& value) { velocity = value; } setLocalVelocity(velocity); - _flags |= Simulation::DIRTY_LINEAR_VELOCITY; + markDirtyFlags(Simulation::DIRTY_LINEAR_VELOCITY); } } } @@ -1982,7 +1982,7 @@ void EntityItem::setAngularVelocity(const glm::vec3& value) { angularVelocity = value; } setLocalAngularVelocity(angularVelocity); - _flags |= Simulation::DIRTY_ANGULAR_VELOCITY; + markDirtyFlags(Simulation::DIRTY_ANGULAR_VELOCITY); } } } @@ -2168,8 +2168,14 @@ bool EntityItem::addAction(EntitySimulationPointer simulation, EntityDynamicPoin void EntityItem::enableNoBootstrap() { if (!(bool)(_flags & Simulation::SPECIAL_FLAGS_NO_BOOTSTRAPPING)) { - _flags |= Simulation::SPECIAL_FLAGS_NO_BOOTSTRAPPING; - _flags |= Simulation::DIRTY_COLLISION_GROUP; // may need to not collide with own avatar + markDirtyFlags(Simulation::DIRTY_COLLISION_GROUP); + markSpecialFlags(Simulation::SPECIAL_FLAGS_NO_BOOTSTRAPPING); + + // NOTE: unlike disableNoBootstrap() below, we do not call simulation->changeEntity() here + // because most enableNoBootstrap() cases are already correctly handled outside this scope + // and I didn't want to add redundant work. + // TODO: cleanup Grabs & dirtySimulationFlags to be more efficient and make more sense. + forEachDescendant([&](SpatiallyNestablePointer child) { if (child->getNestableType() == NestableType::Entity) { EntityItemPointer entity = std::static_pointer_cast(child); @@ -2182,13 +2188,21 @@ void EntityItem::enableNoBootstrap() { void EntityItem::disableNoBootstrap() { if (!stillHasGrabActions()) { - _flags &= ~Simulation::SPECIAL_FLAGS_NO_BOOTSTRAPPING; - _flags |= Simulation::DIRTY_COLLISION_GROUP; // may need to not collide with own avatar + markDirtyFlags(Simulation::DIRTY_COLLISION_GROUP); + clearSpecialFlags(Simulation::SPECIAL_FLAGS_NO_BOOTSTRAPPING); + + EntityTreePointer entityTree = getTree(); + assert(entityTree); + EntitySimulationPointer simulation = entityTree->getSimulation(); + assert(simulation); + simulation->changeEntity(getThisPointer()); + forEachDescendant([&](SpatiallyNestablePointer child) { if (child->getNestableType() == NestableType::Entity) { EntityItemPointer entity = std::static_pointer_cast(child); entity->markDirtyFlags(Simulation::DIRTY_COLLISION_GROUP); entity->clearSpecialFlags(Simulation::SPECIAL_FLAGS_NO_BOOTSTRAPPING); + simulation->changeEntity(entity); } }); } @@ -2574,7 +2588,7 @@ QList EntityItem::getActionsOfType(EntityDynamicType typeT void EntityItem::locationChanged(bool tellPhysics) { requiresRecalcBoxes(); if (tellPhysics) { - _flags |= Simulation::DIRTY_TRANSFORM; + markDirtyFlags(Simulation::DIRTY_TRANSFORM); EntityTreePointer tree = getTree(); if (tree) { tree->entityChanged(getThisPointer()); @@ -3445,7 +3459,7 @@ void EntityItem::addGrab(GrabPointer grab) { if (useAction) { EntityTreePointer entityTree = getTree(); assert(entityTree); - EntitySimulationPointer simulation = entityTree ? entityTree->getSimulation() : nullptr; + EntitySimulationPointer simulation = entityTree->getSimulation(); assert(simulation); auto actionFactory = DependencyManager::get(); @@ -3494,7 +3508,6 @@ void EntityItem::removeGrab(GrabPointer grab) { setLocalVelocity(glm::vec3(0.0f)); setAngularVelocity(glm::vec3(0.0f)); } - markDirtyFlags(Simulation::DIRTY_MOTION_TYPE); QUuid actionID = grab->getActionID(); if (!actionID.isNull()) { From fab3e5e3fd32a8b61f7c110f045f10eed9cc20ba Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Mon, 11 Feb 2019 16:13:56 -0800 Subject: [PATCH 2/4] remember hash of AvatarEntityItemData --- interface/src/avatar/OtherAvatar.cpp | 5 +++++ interface/src/avatar/OtherAvatar.h | 10 ++++++++++ .../avatars-renderer/src/avatars-renderer/Avatar.cpp | 5 ----- .../avatars-renderer/src/avatars-renderer/Avatar.h | 6 ++---- libraries/avatars/src/AvatarData.h | 2 +- 5 files changed, 18 insertions(+), 10 deletions(-) diff --git a/interface/src/avatar/OtherAvatar.cpp b/interface/src/avatar/OtherAvatar.cpp index a3950c8e96..67eb919b73 100755 --- a/interface/src/avatar/OtherAvatar.cpp +++ b/interface/src/avatar/OtherAvatar.cpp @@ -510,6 +510,11 @@ void OtherAvatar::handleChangedAvatarEntityData() { } } stateItr.value().success = success; + if (success) { + stateItr.value().hash = newHash; + } else { + stateItr.value().hash = 0; + } } AvatarEntityIDs recentlyRemovedAvatarEntities = getAndClearRecentlyRemovedIDs(); diff --git a/interface/src/avatar/OtherAvatar.h b/interface/src/avatar/OtherAvatar.h index 3ecd35413f..6461a0107c 100644 --- a/interface/src/avatar/OtherAvatar.h +++ b/interface/src/avatar/OtherAvatar.h @@ -76,6 +76,16 @@ protected: void onAddAttachedAvatarEntity(const QUuid& id); void onRemoveAttachedAvatarEntity(const QUuid& id); + class AvatarEntityDataHash { + public: + AvatarEntityDataHash(uint32_t h) : hash(h) {}; + uint32_t hash { 0 }; + bool success { false }; + }; + + using MapOfAvatarEntityDataHashes = QMap; + MapOfAvatarEntityDataHashes _avatarEntityDataHashes; + std::vector _attachedAvatarEntities; std::shared_ptr _otherAvatarOrbMeshPlaceholder { nullptr }; OverlayID _otherAvatarOrbMeshPlaceholderID { UNKNOWN_OVERLAY_ID }; diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index ba5529e1c0..36ad6c6b82 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -305,11 +305,6 @@ void Avatar::setTargetScale(float targetScale) { } } -void Avatar::setAvatarEntityDataChanged(bool value) { - AvatarData::setAvatarEntityDataChanged(value); - _avatarEntityDataHashes.clear(); -} - void Avatar::removeAvatarEntitiesFromTree() { auto treeRenderer = DependencyManager::get(); EntityTreePointer entityTree = treeRenderer ? treeRenderer->getTree() : nullptr; diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h index b43fe012b7..39b77f2b65 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h @@ -480,8 +480,6 @@ public: virtual void setModelScale(float scale) { _modelScale = scale; } virtual glm::vec3 scaleForChildren() const override { return glm::vec3(getModelScale()); } - virtual void setAvatarEntityDataChanged(bool value) override; - // Show hide the model representation of the avatar virtual void setEnableMeshVisible(bool isEnabled); virtual bool getEnableMeshVisible() const; @@ -647,8 +645,8 @@ protected: bool success { false }; }; - using MapOfAvatarEntityDataHashes = QMap; - MapOfAvatarEntityDataHashes _avatarEntityDataHashes; + //using MapOfAvatarEntityDataHashes = QMap; + //MapOfAvatarEntityDataHashes _avatarEntityDataHashes; uint64_t _lastRenderUpdateTime { 0 }; int _leftPointerGeometryID { 0 }; diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index d071b74d6e..63396a59ac 100755 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -1147,7 +1147,7 @@ public: */ Q_INVOKABLE virtual void setAvatarEntityData(const AvatarEntityMap& avatarEntityData); - virtual void setAvatarEntityDataChanged(bool value) { _avatarEntityDataChanged = value; } + void setAvatarEntityDataChanged(bool value) { _avatarEntityDataChanged = value; } AvatarEntityIDs getAndClearRecentlyRemovedIDs(); /**jsdoc From 3ea6241cc91e9eafe224ebcaf1d313d3624dad2a Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 12 Feb 2019 12:50:47 -0800 Subject: [PATCH 3/4] send update for AvatarEntity on deleteGrab --- interface/src/avatar/MyAvatar.cpp | 12 ++++++++++++ interface/src/avatar/MyAvatar.h | 1 + .../avatars-renderer/src/avatars-renderer/Avatar.cpp | 7 +++++++ .../avatars-renderer/src/avatars-renderer/Avatar.h | 5 ++--- 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 92d9270d20..1c7f2ae400 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -5312,3 +5312,15 @@ void MyAvatar::releaseGrab(const QUuid& grabID) { } } +void MyAvatar::sendPacket(const QUuid& entityID, const EntityItemProperties& properties) const { + auto treeRenderer = DependencyManager::get(); + EntityTreePointer entityTree = treeRenderer ? treeRenderer->getTree() : nullptr; + if (entityTree) { + entityTree->withWriteLock([&] { + // force an update packet + EntityEditPacketSender* packetSender = qApp->getEntityEditPacketSender(); + packetSender->queueEditEntityMessage(PacketType::EntityEdit, entityTree, entityID, properties); + }); + } +} + diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 0d27988543..c279673486 100755 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -1882,6 +1882,7 @@ private: bool didTeleport(); bool getIsAway() const { return _isAway; } void setAway(bool value); + void sendPacket(const QUuid& entityID, const EntityItemProperties& properties) const override; std::mutex _pinnedJointsMutex; std::vector _pinnedJoints; diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp index 36ad6c6b82..c17c7d9fc5 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.cpp @@ -363,6 +363,13 @@ bool Avatar::applyGrabChanges() { target->removeGrab(grab); _avatarGrabs.erase(itr); grabAddedOrRemoved = true; + if (isMyAvatar()) { + const EntityItemPointer& entity = std::dynamic_pointer_cast(target); + if (entity && entity->getEntityHostType() == entity::HostType::AVATAR && entity->getSimulationOwner().getID() == getID()) { + EntityItemProperties properties = entity->getProperties(); + sendPacket(entity->getID(), properties); + } + } } else { undeleted.push_back(id); } diff --git a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h index 39b77f2b65..06942a13d8 100644 --- a/libraries/avatars-renderer/src/avatars-renderer/Avatar.h +++ b/libraries/avatars-renderer/src/avatars-renderer/Avatar.h @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -601,6 +602,7 @@ protected: // protected methods... bool isLookingAtMe(AvatarSharedPointer avatar) const; + virtual void sendPacket(const QUuid& entityID, const EntityItemProperties& properties) const { } bool applyGrabChanges(); void relayJointDataToChildren(); @@ -645,9 +647,6 @@ protected: bool success { false }; }; - //using MapOfAvatarEntityDataHashes = QMap; - //MapOfAvatarEntityDataHashes _avatarEntityDataHashes; - uint64_t _lastRenderUpdateTime { 0 }; int _leftPointerGeometryID { 0 }; int _rightPointerGeometryID { 0 }; From 9f9f512c59f9132bcc3799d573536f85a3df1a5e Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 12 Feb 2019 13:22:22 -0800 Subject: [PATCH 4/4] undoing markDirty() overhead because _flags is atomic --- libraries/entities/src/EntityItem.cpp | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/libraries/entities/src/EntityItem.cpp b/libraries/entities/src/EntityItem.cpp index 777f9ba167..5c423b2fe5 100644 --- a/libraries/entities/src/EntityItem.cpp +++ b/libraries/entities/src/EntityItem.cpp @@ -1897,7 +1897,7 @@ glm::vec3 EntityItem::getUnscaledDimensions() const { void EntityItem::setRotation(glm::quat rotation) { if (getLocalOrientation() != rotation) { setLocalOrientation(rotation); - markDirtyFlags(Simulation::DIRTY_ROTATION); + _flags |= Simulation::DIRTY_ROTATION; forEachDescendant([&](SpatiallyNestablePointer object) { if (object->getNestableType() == NestableType::Entity) { EntityItemPointer entity = std::static_pointer_cast(object); @@ -1927,7 +1927,7 @@ void EntityItem::setVelocity(const glm::vec3& value) { velocity = value; } setLocalVelocity(velocity); - markDirtyFlags(Simulation::DIRTY_LINEAR_VELOCITY); + _flags |= Simulation::DIRTY_LINEAR_VELOCITY; } } } @@ -1982,7 +1982,7 @@ void EntityItem::setAngularVelocity(const glm::vec3& value) { angularVelocity = value; } setLocalAngularVelocity(angularVelocity); - markDirtyFlags(Simulation::DIRTY_ANGULAR_VELOCITY); + _flags |= Simulation::DIRTY_ANGULAR_VELOCITY; } } } @@ -2168,8 +2168,8 @@ bool EntityItem::addAction(EntitySimulationPointer simulation, EntityDynamicPoin void EntityItem::enableNoBootstrap() { if (!(bool)(_flags & Simulation::SPECIAL_FLAGS_NO_BOOTSTRAPPING)) { - markDirtyFlags(Simulation::DIRTY_COLLISION_GROUP); - markSpecialFlags(Simulation::SPECIAL_FLAGS_NO_BOOTSTRAPPING); + _flags |= Simulation::SPECIAL_FLAGS_NO_BOOTSTRAPPING; + _flags |= Simulation::DIRTY_COLLISION_GROUP; // may need to not collide with own avatar // NOTE: unlike disableNoBootstrap() below, we do not call simulation->changeEntity() here // because most enableNoBootstrap() cases are already correctly handled outside this scope @@ -2188,8 +2188,8 @@ void EntityItem::enableNoBootstrap() { void EntityItem::disableNoBootstrap() { if (!stillHasGrabActions()) { - markDirtyFlags(Simulation::DIRTY_COLLISION_GROUP); - clearSpecialFlags(Simulation::SPECIAL_FLAGS_NO_BOOTSTRAPPING); + _flags &= ~Simulation::SPECIAL_FLAGS_NO_BOOTSTRAPPING; + _flags |= Simulation::DIRTY_COLLISION_GROUP; // may need to not collide with own avatar EntityTreePointer entityTree = getTree(); assert(entityTree); @@ -2588,7 +2588,7 @@ QList EntityItem::getActionsOfType(EntityDynamicType typeT void EntityItem::locationChanged(bool tellPhysics) { requiresRecalcBoxes(); if (tellPhysics) { - markDirtyFlags(Simulation::DIRTY_TRANSFORM); + _flags |= Simulation::DIRTY_TRANSFORM; EntityTreePointer tree = getTree(); if (tree) { tree->entityChanged(getThisPointer());