AvatarManager::AvatarManager(QObject* parent) : _myAvatar(new MyAvatar(qApp->thread()), [](MyAvatar* ptr) { ptr->deleteLater(); }) { // register a meta type for the weak pointer we'll use for the owning avatar mixer for each avatar qRegisterMetaType<QWeakPointer<Node> >("NodeWeakPointer"); auto nodeList = DependencyManager::get<NodeList>(); // when we hear that the user has ignored an avatar by session UUID // immediately remove that avatar instead of waiting for the absence of packets from avatar mixer connect(nodeList.data(), &NodeList::ignoredNode, this, [this](const QUuid& nodeID, bool enabled) { if (enabled) { removeAvatar(nodeID, KillAvatarReason::AvatarIgnored); } else { auto avatar = std::static_pointer_cast<Avatar>(getAvatarBySessionID(nodeID)); if (avatar) { avatar->createOrb(); } } }); _transitConfig._totalFrames = AVATAR_TRANSIT_FRAME_COUNT; _transitConfig._minTriggerDistance = AVATAR_TRANSIT_MIN_TRIGGER_DISTANCE; _transitConfig._maxTriggerDistance = AVATAR_TRANSIT_MAX_TRIGGER_DISTANCE; _transitConfig._framesPerMeter = AVATAR_TRANSIT_FRAMES_PER_METER; _transitConfig._isDistanceBased = AVATAR_TRANSIT_DISTANCE_BASED; _transitConfig._abortDistance = AVATAR_TRANSIT_ABORT_DISTANCE; }
void AvatarManager::updateOtherAvatars(float deltaTime) { // lock the hash for read to check the size QReadLocker lock(&_hashLock); if (_avatarHash.size() < 2 && _avatarFades.isEmpty()) { return; } lock.unlock(); bool showWarnings = Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings); PerformanceWarning warn(showWarnings, "Application::updateAvatars()"); PerformanceTimer perfTimer("otherAvatars"); // simulate avatars auto hashCopy = getHashCopy(); AvatarHash::iterator avatarIterator = hashCopy.begin(); while (avatarIterator != hashCopy.end()) { auto avatar = std::static_pointer_cast<Avatar>(avatarIterator.value()); if (avatar == _myAvatar || !avatar->isInitialized()) { // DO NOT update _myAvatar! Its update has already been done earlier in the main loop. // DO NOT update or fade out uninitialized Avatars ++avatarIterator; } else if (avatar->shouldDie()) { removeAvatar(avatarIterator.key()); ++avatarIterator; } else { avatar->startUpdate(); avatar->simulate(deltaTime); avatar->endUpdate(); ++avatarIterator; } } // simulate avatar fades simulateAvatarFades(deltaTime); }
/** * @brief Removes our own avatar. */ void Profile::removeAvatar() { removeAvatar(core->getSelfId().publicKey); }