cache avatar identity info forever

This commit is contained in:
Andrew Meadows 2017-04-25 09:42:03 -07:00 committed by ZappoMan
parent 08972da843
commit 4511156d7b
7 changed files with 50 additions and 64 deletions

View file

@ -115,8 +115,6 @@ Avatar::Avatar(QThread* thread, RigPointer rig) :
}
Avatar::~Avatar() {
assert(isDead()); // mark dead before calling the dtor
auto treeRenderer = DependencyManager::get<EntityTreeRenderer>();
EntityTreePointer entityTree = treeRenderer ? treeRenderer->getTree() : nullptr;
if (entityTree) {
@ -447,6 +445,24 @@ float Avatar::getSimulationRate(const QString& rateName) const {
return 0.0f;
}
void Avatar::getIdentity(Identity& identity) const {
identity.uuid = getSessionUUID();
identity.skeletonModelURL = _skeletonModelURL;
identity.attachmentData = _attachmentData;
identity.displayName = _displayName;
identity.sessionDisplayName = _sessionDisplayName;
identity.avatarEntityData = _avatarEntityData;
}
void Avatar::setIdentity(const Identity& identity) {
assert(identity.uuid == getSessionUUID());
setSkeletonModelURL(identity.skeletonModelURL);
_attachmentData = identity.attachmentData;
_displayName = identity.displayName;
_sessionDisplayName = identity.sessionDisplayName;
_avatarEntityData = identity.avatarEntityData;
}
bool Avatar::isLookingAtMe(AvatarSharedPointer avatar) const {
const float HEAD_SPHERE_RADIUS = 0.1f;
glm::vec3 theirLookAt = dynamic_pointer_cast<Avatar>(avatar)->getHead()->getLookAtPosition();
@ -510,12 +526,13 @@ static TextRenderer3D* textRenderer(TextRendererType type) {
void Avatar::addToScene(AvatarSharedPointer self, const render::ScenePointer& scene, render::Transaction& transaction) {
auto avatarPayload = new render::Payload<AvatarData>(self);
auto avatarPayloadPointer = Avatar::PayloadPointer(avatarPayload);
_renderItemID = scene->allocateID();
transaction.resetItem(_renderItemID, avatarPayloadPointer);
_skeletonModel->addToScene(scene, transaction);
if (_skeletonModel->addToScene(scene, transaction)) {
_renderItemID = scene->allocateID();
transaction.resetItem(_renderItemID, avatarPayloadPointer);
for (auto& attachmentModel : _attachmentModels) {
attachmentModel->addToScene(scene, transaction);
for (auto& attachmentModel : _attachmentModels) {
attachmentModel->addToScene(scene, transaction);
}
}
}

View file

@ -238,6 +238,9 @@ public:
return (lerpValue*(4.0f - 2.0f * lerpValue) - 1.0f);
}
void getIdentity(Identity& identity) const;
void setIdentity(const Identity& identity);
public slots:
// FIXME - these should be migrated to use Pose data instead

View file

@ -214,11 +214,6 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
}
avatar->animateScaleChanges(deltaTime);
if (avatar->shouldDie()) {
avatar->die();
removeAvatar(avatar->getID());
}
const float OUT_OF_VIEW_THRESHOLD = 0.5f * AvatarData::OUT_OF_VIEW_PENALTY;
uint64_t now = usecTimestampNow();
if (now < updateExpiry) {
@ -331,35 +326,14 @@ AvatarSharedPointer AvatarManager::newSharedAvatar() {
return std::make_shared<Avatar>(qApp->thread(), std::make_shared<Rig>());
}
void AvatarManager::processAvatarDataPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode) {
PerformanceTimer perfTimer("receiveAvatar");
// enumerate over all of the avatars in this packet
// only add them if mixerWeakPointer points to something (meaning that mixer is still around)
while (message->getBytesLeftToRead()) {
AvatarSharedPointer avatarData = parseAvatarData(message, sendingNode);
if (avatarData) {
auto avatar = std::static_pointer_cast<Avatar>(avatarData);
if (avatar->isInScene()) {
if (!_shouldRender) {
// rare transition so we process the transaction immediately
const render::ScenePointer& scene = qApp->getMain3DScene();
render::Transaction transaction;
avatar->removeFromScene(avatar, scene, transaction);
if (scene) {
scene->enqueueTransaction(transaction);
}
}
} else if (_shouldRender) {
// very rare transition so we process the transaction immediately
const render::ScenePointer& scene = qApp->getMain3DScene();
render::Transaction transaction;
avatar->addToScene(avatar, scene, transaction);
if (scene) {
scene->enqueueTransaction(transaction);
}
}
}
AvatarSharedPointer AvatarManager::addAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer) {
AvatarSharedPointer avatarData = AvatarHashMap::addAvatar(sessionUUID, mixerWeakPointer);
QMap<QUuid, AvatarData::Identity>::iterator itr = _identityCache.find(sessionUUID);
if (itr != _identityCache.end()) {
auto avatar = std::static_pointer_cast<Avatar>(avatarData);
avatar->setIdentity(*itr);
}
return avatarData;
}
void AvatarManager::handleRemovedAvatar(const AvatarSharedPointer& removedAvatar, KillAvatarReason removalReason) {
@ -367,8 +341,13 @@ void AvatarManager::handleRemovedAvatar(const AvatarSharedPointer& removedAvatar
// removedAvatar is a shared pointer to an AvatarData but we need to get to the derived Avatar
// class in this context so we can call methods that don't exist at the base class.
Avatar* avatar = static_cast<Avatar*>(removedAvatar.get());
avatar->die();
auto avatar = std::static_pointer_cast<Avatar>(removedAvatar);
// there is no way to request identity data from the avatar-mixer
// therefore whenever we remove an avatar we cache the identity in case we need it later
AvatarData::Identity identity;
avatar->getIdentity(identity);
_identityCache[avatar->getSessionUUID()] = identity;
AvatarMotionState* motionState = avatar->getMotionState();
if (motionState) {
@ -404,14 +383,11 @@ void AvatarManager::clearOtherAvatars() {
if (avatar->isInScene()) {
avatar->removeFromScene(avatar, scene, transaction);
}
AvatarMotionState* motionState = avatar->getMotionState();
if (motionState) {
_motionStatesThatMightUpdate.remove(motionState);
_motionStatesToAddToPhysics.remove(motionState);
_motionStatesToRemoveFromPhysics.push_back(motionState);
}
handleRemovedAvatar(avatar);
avatarIterator = _avatarHash.erase(avatarIterator);
} else {
++avatarIterator;
}
++avatarIterator;
}
scene->enqueueTransaction(transaction);
_myAvatar->clearLookAtTargetAvatar();

View file

@ -98,9 +98,6 @@ public slots:
void setShouldShowReceiveStats(bool shouldShowReceiveStats) { _shouldShowReceiveStats = shouldShowReceiveStats; }
void updateAvatarRenderStatus(bool shouldRenderAvatars);
protected slots:
void processAvatarDataPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode) override;
private:
explicit AvatarManager(QObject* parent = 0);
explicit AvatarManager(const AvatarManager& other);
@ -108,6 +105,7 @@ private:
void simulateAvatarFades(float deltaTime);
AvatarSharedPointer newSharedAvatar() override;
AvatarSharedPointer addAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer) override;
void handleRemovedAvatar(const AvatarSharedPointer& removedAvatar, KillAvatarReason removalReason = KillAvatarReason::NoReason) override;
QVector<AvatarSharedPointer> _avatarsToFade;
@ -120,6 +118,7 @@ private:
quint64 _lastSendAvatarDataTime = 0; // Controls MyAvatar send data rate.
QVector<AvatarManager::LocalLight> _localLights;
QMap<QUuid, AvatarData::Identity> _identityCache;
bool _shouldShowReceiveStats = false;

View file

@ -1521,9 +1521,6 @@ void AvatarData::processAvatarIdentity(const Identity& identity, bool& identityC
setAvatarEntityData(identity.avatarEntityData);
identityChanged = true;
}
// flag this avatar as non-stale by updating _averageBytesReceived
const int BOGUS_NUM_BYTES = 1;
_averageBytesReceived.updateAverage(BOGUS_NUM_BYTES);
// use the timestamp from this identity, since we want to honor the updated times in "server clock"
// this will overwrite any changes we made locally to this AvatarData's _identityUpdatedAt

View file

@ -110,9 +110,7 @@ const char LEFT_HAND_POINTING_FLAG = 1;
const char RIGHT_HAND_POINTING_FLAG = 2;
const char IS_FINGER_POINTING_FLAG = 4;
const qint64 AVATAR_UPDATE_TIMEOUT = 5 * USECS_PER_SECOND;
// AvatarData state flags - we store the details about the packet encoding in the first byte,
// AvatarData state flags - we store the details about the packet encoding in the first byte,
// before the "header" structure
const char AVATARDATA_FLAGS_MINIMUM = 0;
@ -568,7 +566,6 @@ public:
void setOwningAvatarMixer(const QWeakPointer<Node>& owningAvatarMixer) { _owningAvatarMixer = owningAvatarMixer; }
int getUsecsSinceLastUpdate() const { return _averageBytesReceived.getUsecsSinceLastEvent(); }
int getAverageBytesReceivedPerSecond() const;
int getReceiveRate() const;
@ -604,9 +601,6 @@ public:
return _lastSentJointData;
}
bool shouldDie() const { return _owningAvatarMixer.isNull() || getUsecsSinceLastUpdate() > AVATAR_UPDATE_TIMEOUT; }
static const float OUT_OF_VIEW_PENALTY;
static void sortAvatars(
@ -631,7 +625,7 @@ public:
signals:
void displayNameChanged();
public slots:
void sendAvatarDataPacket();
void sendIdentityPacket();

View file

@ -57,7 +57,7 @@ public slots:
protected slots:
void sessionUUIDChanged(const QUuid& sessionUUID, const QUuid& oldUUID);
virtual void processAvatarDataPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
void processAvatarDataPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
void processAvatarIdentityPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
void processKillAvatar(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
void processExitingSpaceBubble(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);