diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index b0369303e9..76714170fb 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -532,10 +532,14 @@ void MyAvatar::forgetChild(SpatiallyNestablePointer newChild) const { SpatiallyNestable::forgetChild(newChild); } -void MyAvatar::updateChildCauterization(SpatiallyNestablePointer object) { +void MyAvatar::recalculateChildCauterization() const { + _cauterizationNeedsUpdate = true; +} + +void MyAvatar::updateChildCauterization(SpatiallyNestablePointer object, bool cauterize) { if (object->getNestableType() == NestableType::Entity) { EntityItemPointer entity = std::static_pointer_cast(object); - entity->setCauterized(!_prevShouldDrawHead); + entity->setCauterized(cauterize); } } @@ -545,17 +549,42 @@ void MyAvatar::simulate(float deltaTime) { animateScaleChanges(deltaTime); if (_cauterizationNeedsUpdate) { - const std::unordered_set& headBoneSet = _skeletonModel->getCauterizeBoneSet(); + _cauterizationNeedsUpdate = false; + + // Redisplay cauterized entities that are no longer children of the avatar. + auto cauterizedChild = _cauterizedChildrenOfHead.begin(); + if (cauterizedChild != _cauterizedChildrenOfHead.end()) { + auto children = getChildren(); + while (cauterizedChild != _cauterizedChildrenOfHead.end()) { + if (!children.contains(*cauterizedChild)) { + updateChildCauterization(*cauterizedChild, false); + cauterizedChild = _cauterizedChildrenOfHead.erase(cauterizedChild); + } else { + ++cauterizedChild; + } + } + } + + // Update cauterization of entities that are children of the avatar. + auto headBoneSet = _skeletonModel->getCauterizeBoneSet(); forEachChild([&](SpatiallyNestablePointer object) { bool isChildOfHead = headBoneSet.find(object->getParentJointIndex()) != headBoneSet.end(); if (isChildOfHead) { - updateChildCauterization(object); + // Cauterize or display children of head per head drawing state. + updateChildCauterization(object, !_prevShouldDrawHead); object->forEachDescendant([&](SpatiallyNestablePointer descendant) { - updateChildCauterization(descendant); + updateChildCauterization(descendant, !_prevShouldDrawHead); }); + _cauterizedChildrenOfHead.insert(object); + } else if (_cauterizedChildrenOfHead.find(object) != _cauterizedChildrenOfHead.end()) { + // Redisplay cauterized children that are not longer children of the head. + updateChildCauterization(object, false); + object->forEachDescendant([&](SpatiallyNestablePointer descendant) { + updateChildCauterization(descendant, false); + }); + _cauterizedChildrenOfHead.erase(object); } }); - _cauterizationNeedsUpdate = false; } { diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 1a6feb142a..7cb1cfb4b4 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -1374,6 +1374,7 @@ private slots: protected: virtual void beParentOfChild(SpatiallyNestablePointer newChild) const override; virtual void forgetChild(SpatiallyNestablePointer newChild) const override; + virtual void recalculateChildCauterization() const override; private: @@ -1566,6 +1567,7 @@ private: glm::quat _goToOrientation; std::unordered_set _headBoneSet; + std::unordered_set _cauterizedChildrenOfHead; bool _prevShouldDrawHead; bool _rigEnabled { true }; @@ -1621,7 +1623,7 @@ private: // height of user in sensor space, when standing erect. ThreadSafeValueCache _userHeight { DEFAULT_AVATAR_HEIGHT }; - void updateChildCauterization(SpatiallyNestablePointer object); + void updateChildCauterization(SpatiallyNestablePointer object, bool cauterize); // max unscaled forward movement speed ThreadSafeValueCache _walkSpeed { DEFAULT_AVATAR_MAX_WALKING_SPEED }; diff --git a/libraries/shared/src/SpatiallyNestable.cpp b/libraries/shared/src/SpatiallyNestable.cpp index 324cee3417..ccb275ffc9 100644 --- a/libraries/shared/src/SpatiallyNestable.cpp +++ b/libraries/shared/src/SpatiallyNestable.cpp @@ -165,6 +165,10 @@ void SpatiallyNestable::forgetChild(SpatiallyNestablePointer newChild) const { void SpatiallyNestable::setParentJointIndex(quint16 parentJointIndex) { _parentJointIndex = parentJointIndex; + auto parent = _parent.lock(); + if (parent) { + parent->recalculateChildCauterization(); + } } glm::vec3 SpatiallyNestable::worldToLocal(const glm::vec3& position, diff --git a/libraries/shared/src/SpatiallyNestable.h b/libraries/shared/src/SpatiallyNestable.h index 5d4793ba4e..361f0aaf17 100644 --- a/libraries/shared/src/SpatiallyNestable.h +++ b/libraries/shared/src/SpatiallyNestable.h @@ -218,6 +218,7 @@ protected: virtual void beParentOfChild(SpatiallyNestablePointer newChild) const; virtual void forgetChild(SpatiallyNestablePointer newChild) const; + virtual void recalculateChildCauterization() const { } mutable ReadWriteLockable _childrenLock; mutable QHash _children;