diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index d57905ee33..7be93dcecc 100755 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -531,10 +531,10 @@ void MyAvatar::forgetChild(SpatiallyNestablePointer newChild) const { SpatiallyNestable::forgetChild(newChild); } -void MyAvatar::updateChildCauterization(SpatiallyNestablePointer object) { +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); } } @@ -544,16 +544,41 @@ void MyAvatar::simulate(float deltaTime) { animateScaleChanges(deltaTime); if (_cauterizationNeedsUpdate) { - const std::unordered_set& headBoneSet = _skeletonModel->getCauterizeBoneSet(); + + // 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); + _cauterizedChildrenOfHead.erase(*cauterizedChild); + } + ++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..3f9f82cc59 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -1566,6 +1566,7 @@ private: glm::quat _goToOrientation; std::unordered_set _headBoneSet; + std::unordered_set _cauterizedChildrenOfHead; bool _prevShouldDrawHead; bool _rigEnabled { true }; @@ -1621,7 +1622,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 };