Merge pull request #10146 from AndrewMeadows/avoid-invisible-avatars-002

avoid invisible avatars redux
This commit is contained in:
Seth Alves 2017-04-11 07:07:03 -07:00 committed by GitHub
commit bf16309917
9 changed files with 173 additions and 118 deletions

View file

@ -1802,10 +1802,11 @@ Application::~Application() {
_physicsEngine->setCharacterController(nullptr); _physicsEngine->setCharacterController(nullptr);
// remove avatars from physics engine // remove avatars from physics engine
DependencyManager::get<AvatarManager>()->clearAllAvatars(); DependencyManager::get<AvatarManager>()->clearOtherAvatars();
VectorOfMotionStates motionStates; VectorOfMotionStates motionStates;
DependencyManager::get<AvatarManager>()->getObjectsToRemoveFromPhysics(motionStates); DependencyManager::get<AvatarManager>()->getObjectsToRemoveFromPhysics(motionStates);
_physicsEngine->removeObjects(motionStates); _physicsEngine->removeObjects(motionStates);
DependencyManager::get<AvatarManager>()->deleteAllAvatars();
DependencyManager::destroy<AvatarManager>(); DependencyManager::destroy<AvatarManager>();
DependencyManager::destroy<AnimationCache>(); DependencyManager::destroy<AnimationCache>();

View file

@ -193,6 +193,9 @@ void Avatar::animateScaleChanges(float deltaTime) {
} }
setScale(glm::vec3(animatedScale)); // avatar scale is uniform setScale(glm::vec3(animatedScale)); // avatar scale is uniform
// flag the joints as having changed for force update to RenderItem
_hasNewJointData = true;
// TODO: rebuilding the shape constantly is somehwat expensive. // TODO: rebuilding the shape constantly is somehwat expensive.
// We should only rebuild after significant change. // We should only rebuild after significant change.
rebuildCollisionShape(); rebuildCollisionShape();
@ -200,8 +203,12 @@ void Avatar::animateScaleChanges(float deltaTime) {
} }
void Avatar::setTargetScale(float targetScale) { void Avatar::setTargetScale(float targetScale) {
AvatarData::setTargetScale(targetScale); float newValue = glm::clamp(targetScale, MIN_AVATAR_SCALE, MAX_AVATAR_SCALE);
_isAnimatingScale = true; if (_targetScale != newValue) {
_targetScale = newValue;
_scaleChanged = usecTimestampNow();
_isAnimatingScale = true;
}
} }
void Avatar::updateAvatarEntities() { void Avatar::updateAvatarEntities() {
@ -476,7 +483,7 @@ static TextRenderer3D* textRenderer(TextRendererType type) {
return displayNameRenderer; return displayNameRenderer;
} }
bool Avatar::addToScene(AvatarSharedPointer self, std::shared_ptr<render::Scene> scene, render::Transaction& transaction) { void Avatar::addToScene(AvatarSharedPointer self, std::shared_ptr<render::Scene> scene, render::Transaction& transaction) {
auto avatarPayload = new render::Payload<AvatarData>(self); auto avatarPayload = new render::Payload<AvatarData>(self);
auto avatarPayloadPointer = Avatar::PayloadPointer(avatarPayload); auto avatarPayloadPointer = Avatar::PayloadPointer(avatarPayload);
_renderItemID = scene->allocateID(); _renderItemID = scene->allocateID();
@ -486,9 +493,6 @@ bool Avatar::addToScene(AvatarSharedPointer self, std::shared_ptr<render::Scene>
for (auto& attachmentModel : _attachmentModels) { for (auto& attachmentModel : _attachmentModels) {
attachmentModel->addToScene(scene, transaction); attachmentModel->addToScene(scene, transaction);
} }
_inScene = true;
return true;
} }
void Avatar::removeFromScene(AvatarSharedPointer self, std::shared_ptr<render::Scene> scene, render::Transaction& transaction) { void Avatar::removeFromScene(AvatarSharedPointer self, std::shared_ptr<render::Scene> scene, render::Transaction& transaction) {
@ -498,7 +502,6 @@ void Avatar::removeFromScene(AvatarSharedPointer self, std::shared_ptr<render::S
for (auto& attachmentModel : _attachmentModels) { for (auto& attachmentModel : _attachmentModels) {
attachmentModel->removeFromScene(scene, transaction); attachmentModel->removeFromScene(scene, transaction);
} }
_inScene = false;
} }
void Avatar::updateRenderItem(render::Transaction& transaction) { void Avatar::updateRenderItem(render::Transaction& transaction) {
@ -1450,7 +1453,7 @@ void Avatar::addToScene(AvatarSharedPointer myHandle) {
} }
} }
void Avatar::ensureInScene(AvatarSharedPointer self) { void Avatar::ensureInScene(AvatarSharedPointer self) {
if (!_inScene) { if (!render::Item::isValidID(_renderItemID)) {
addToScene(self); addToScene(self);
} }
} }

View file

@ -81,7 +81,7 @@ public:
virtual void render(RenderArgs* renderArgs, const glm::vec3& cameraPosition); virtual void render(RenderArgs* renderArgs, const glm::vec3& cameraPosition);
bool addToScene(AvatarSharedPointer self, std::shared_ptr<render::Scene> scene, void addToScene(AvatarSharedPointer self, std::shared_ptr<render::Scene> scene,
render::Transaction& transaction); render::Transaction& transaction);
void removeFromScene(AvatarSharedPointer self, std::shared_ptr<render::Scene> scene, void removeFromScene(AvatarSharedPointer self, std::shared_ptr<render::Scene> scene,
@ -305,6 +305,7 @@ protected:
void addToScene(AvatarSharedPointer self); void addToScene(AvatarSharedPointer self);
void ensureInScene(AvatarSharedPointer self); void ensureInScene(AvatarSharedPointer self);
bool isInScene() const { return render::Item::isValidID(_renderItemID); }
// Some rate tracking support // Some rate tracking support
RateCounter<> _simulationRate; RateCounter<> _simulationRate;
@ -330,7 +331,6 @@ private:
int _nameRectGeometryID { 0 }; int _nameRectGeometryID { 0 };
bool _initialized; bool _initialized;
bool _isLookAtTarget { false }; bool _isLookAtTarget { false };
bool _inScene { false };
bool _isAnimatingScale { false }; bool _isAnimatingScale { false };
float getBoundingRadius() const; float getBoundingRadius() const;

View file

@ -68,7 +68,7 @@ void AvatarManager::registerMetaTypes(QScriptEngine* engine) {
} }
AvatarManager::AvatarManager(QObject* parent) : AvatarManager::AvatarManager(QObject* parent) :
_avatarFades(), _avatarsToFade(),
_myAvatar(std::make_shared<MyAvatar>(std::make_shared<Rig>())) _myAvatar(std::make_shared<MyAvatar>(std::make_shared<Rig>()))
{ {
// register a meta type for the weak pointer we'll use for the owning avatar mixer for each avatar // register a meta type for the weak pointer we'll use for the owning avatar mixer for each avatar
@ -100,15 +100,16 @@ void AvatarManager::init() {
_avatarHash.insert(MY_AVATAR_KEY, _myAvatar); _avatarHash.insert(MY_AVATAR_KEY, _myAvatar);
} }
_shouldRender = DependencyManager::get<SceneScriptingInterface>()->shouldRenderAvatars();
connect(DependencyManager::get<SceneScriptingInterface>().data(), &SceneScriptingInterface::shouldRenderAvatarsChanged, connect(DependencyManager::get<SceneScriptingInterface>().data(), &SceneScriptingInterface::shouldRenderAvatarsChanged,
this, &AvatarManager::updateAvatarRenderStatus, Qt::QueuedConnection); this, &AvatarManager::updateAvatarRenderStatus, Qt::QueuedConnection);
render::ScenePointer scene = qApp->getMain3DScene(); if (_shouldRender) {
render::Transaction transaction; render::ScenePointer scene = qApp->getMain3DScene();
if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderAvatars()) { render::Transaction transaction;
_myAvatar->addToScene(_myAvatar, scene, transaction); _myAvatar->addToScene(_myAvatar, scene, transaction);
scene->enqueueTransaction(transaction);
} }
scene->enqueueTransaction(transaction);
} }
void AvatarManager::updateMyAvatar(float deltaTime) { void AvatarManager::updateMyAvatar(float deltaTime) {
@ -151,7 +152,7 @@ float AvatarManager::getAvatarSimulationRate(const QUuid& sessionID, const QStri
void AvatarManager::updateOtherAvatars(float deltaTime) { void AvatarManager::updateOtherAvatars(float deltaTime) {
// lock the hash for read to check the size // lock the hash for read to check the size
QReadLocker lock(&_hashLock); QReadLocker lock(&_hashLock);
if (_avatarHash.size() < 2 && _avatarFades.isEmpty()) { if (_avatarHash.size() < 2 && _avatarsToFade.isEmpty()) {
return; return;
} }
lock.unlock(); lock.unlock();
@ -181,30 +182,24 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
// DO NOT update or fade out uninitialized Avatars // DO NOT update or fade out uninitialized Avatars
return true; // ignore it return true; // ignore it
} }
if (avatar->shouldDie()) {
removeAvatar(avatar->getID());
return true; // ignore it
}
if (avatar->isDead()) {
return true; // ignore it
}
return false; return false;
}); });
render::Transaction transaction;
uint64_t startTime = usecTimestampNow(); uint64_t startTime = usecTimestampNow();
const uint64_t UPDATE_BUDGET = 2000; // usec const uint64_t UPDATE_BUDGET = 2000; // usec
uint64_t updateExpiry = startTime + UPDATE_BUDGET; uint64_t updateExpiry = startTime + UPDATE_BUDGET;
int numAvatarsUpdated = 0; int numAvatarsUpdated = 0;
int numAVatarsNotUpdated = 0; int numAVatarsNotUpdated = 0;
render::Transaction transaction;
while (!sortedAvatars.empty()) { while (!sortedAvatars.empty()) {
const AvatarPriority& sortData = sortedAvatars.top(); const AvatarPriority& sortData = sortedAvatars.top();
const auto& avatar = std::static_pointer_cast<Avatar>(sortData.avatar); const auto& avatar = std::static_pointer_cast<Avatar>(sortData.avatar);
// for ALL avatars... // for ALL avatars...
avatar->ensureInScene(avatar); if (_shouldRender) {
avatar->ensureInScene(avatar);
}
if (!avatar->getMotionState()) { if (!avatar->getMotionState()) {
ShapeInfo shapeInfo; ShapeInfo shapeInfo;
avatar->computeShapeInfo(shapeInfo); avatar->computeShapeInfo(shapeInfo);
@ -218,6 +213,10 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
} }
} }
avatar->animateScaleChanges(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; const float OUT_OF_VIEW_THRESHOLD = 0.5f * AvatarData::OUT_OF_VIEW_PENALTY;
uint64_t now = usecTimestampNow(); uint64_t now = usecTimestampNow();
@ -259,10 +258,24 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
sortedAvatars.pop(); sortedAvatars.pop();
} }
if (_shouldRender) {
if (!_avatarsToFade.empty()) {
QReadLocker lock(&_hashLock);
QVector<AvatarSharedPointer>::iterator itr = _avatarsToFade.begin();
while (itr != _avatarsToFade.end() && usecTimestampNow() > updateExpiry) {
auto avatar = std::static_pointer_cast<Avatar>(*itr);
avatar->animateScaleChanges(deltaTime);
avatar->simulate(deltaTime, true);
avatar->updateRenderItem(transaction);
++itr;
}
}
qApp->getMain3DScene()->enqueueTransaction(transaction);
}
_avatarSimulationTime = (float)(usecTimestampNow() - startTime) / (float)USECS_PER_MSEC; _avatarSimulationTime = (float)(usecTimestampNow() - startTime) / (float)USECS_PER_MSEC;
_numAvatarsUpdated = numAvatarsUpdated; _numAvatarsUpdated = numAvatarsUpdated;
_numAvatarsNotUpdated = numAVatarsNotUpdated; _numAvatarsNotUpdated = numAVatarsNotUpdated;
qApp->getMain3DScene()->enqueueTransaction(transaction);
simulateAvatarFades(deltaTime); simulateAvatarFades(deltaTime);
} }
@ -277,54 +290,76 @@ void AvatarManager::postUpdate(float deltaTime) {
} }
void AvatarManager::simulateAvatarFades(float deltaTime) { void AvatarManager::simulateAvatarFades(float deltaTime) {
QVector<AvatarSharedPointer>::iterator fadingIterator = _avatarFades.begin(); if (_avatarsToFade.empty()) {
return;
}
const float SHRINK_RATE = 0.15f; const float SHRINK_RATE = 0.15f;
const float MIN_FADE_SCALE = MIN_AVATAR_SCALE; const float MIN_FADE_SCALE = MIN_AVATAR_SCALE;
render::ScenePointer scene = qApp->getMain3DScene(); QReadLocker locker(&_hashLock);
render::Transaction transaction; QVector<AvatarSharedPointer>::iterator itr = _avatarsToFade.begin();
while (fadingIterator != _avatarFades.end()) { while (itr != _avatarsToFade.end()) {
auto avatar = std::static_pointer_cast<Avatar>(*fadingIterator); auto avatar = std::static_pointer_cast<Avatar>(*itr);
avatar->setTargetScale(avatar->getUniformScale() * SHRINK_RATE); avatar->setTargetScale(avatar->getUniformScale() * SHRINK_RATE);
avatar->animateScaleChanges(deltaTime); avatar->animateScaleChanges(deltaTime);
if (avatar->getTargetScale() <= MIN_FADE_SCALE) { if (avatar->getTargetScale() <= MIN_FADE_SCALE) {
avatar->removeFromScene(*fadingIterator, scene, transaction); // fading to zero is such a rare event we push unique transaction for each one
// only remove from _avatarFades if we're sure its motionState has been removed from PhysicsEngine if (avatar->isInScene()) {
render::ScenePointer scene = qApp->getMain3DScene();
render::Transaction transaction;
avatar->removeFromScene(*itr, scene, transaction);
if (scene) {
scene->enqueueTransaction(transaction);
}
}
// only remove from _avatarsToFade if we're sure its motionState has been removed from PhysicsEngine
if (_motionStatesToRemoveFromPhysics.empty()) { if (_motionStatesToRemoveFromPhysics.empty()) {
fadingIterator = _avatarFades.erase(fadingIterator); itr = _avatarsToFade.erase(itr);
} else { } else {
++fadingIterator; ++itr;
} }
} else { } else {
const bool inView = true; // HACK const bool inView = true; // HACK
avatar->simulate(deltaTime, inView); avatar->simulate(deltaTime, inView);
++fadingIterator; ++itr;
} }
} }
scene->enqueueTransaction(transaction);
} }
AvatarSharedPointer AvatarManager::newSharedAvatar() { AvatarSharedPointer AvatarManager::newSharedAvatar() {
return std::make_shared<Avatar>(std::make_shared<Rig>()); return std::make_shared<Avatar>(std::make_shared<Rig>());
} }
AvatarSharedPointer AvatarManager::addAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer) { void AvatarManager::processAvatarDataPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode) {
auto newAvatar = AvatarHashMap::addAvatar(sessionUUID, mixerWeakPointer); PerformanceTimer perfTimer("receiveAvatar");
auto rawRenderableAvatar = std::static_pointer_cast<Avatar>(newAvatar); // enumerate over all of the avatars in this packet
// only add them if mixerWeakPointer points to something (meaning that mixer is still around)
rawRenderableAvatar->addToScene(rawRenderableAvatar); while (message->getBytesLeftToRead()) {
AvatarSharedPointer avatarData = parseAvatarData(message, sendingNode);
return newAvatar; if (avatarData) {
} auto avatar = std::static_pointer_cast<Avatar>(avatarData);
if (avatar->isInScene()) {
// virtual if (!_shouldRender) {
void AvatarManager::removeAvatar(const QUuid& sessionUUID, KillAvatarReason removalReason) { // rare transition so we process the transaction immediately
QWriteLocker locker(&_hashLock); render::ScenePointer scene = qApp->getMain3DScene();
if (scene) {
auto removedAvatar = _avatarHash.take(sessionUUID); render::Transaction transaction;
if (removedAvatar) { avatar->removeFromScene(avatar, scene, transaction);
handleRemovedAvatar(removedAvatar, removalReason); scene->enqueueTransaction(transaction);
}
}
} else if (_shouldRender) {
// very rare transition so we process the transaction immediately
render::ScenePointer scene = qApp->getMain3DScene();
if (scene) {
render::Transaction transaction;
avatar->addToScene(avatar, scene, transaction);
scene->enqueueTransaction(transaction);
}
}
}
} }
} }
@ -353,35 +388,46 @@ void AvatarManager::handleRemovedAvatar(const AvatarSharedPointer& removedAvatar
DependencyManager::get<NodeList>()->removeFromIgnoreMuteSets(avatar->getSessionUUID()); DependencyManager::get<NodeList>()->removeFromIgnoreMuteSets(avatar->getSessionUUID());
DependencyManager::get<UsersScriptingInterface>()->avatarDisconnected(avatar->getSessionUUID()); DependencyManager::get<UsersScriptingInterface>()->avatarDisconnected(avatar->getSessionUUID());
} }
_avatarFades.push_back(removedAvatar); _avatarsToFade.push_back(removedAvatar);
} }
void AvatarManager::clearOtherAvatars() { void AvatarManager::clearOtherAvatars() {
// clear any avatars that came from an avatar-mixer // Remove other avatars from the world but don't actually remove them from _avatarHash
QWriteLocker locker(&_hashLock); // each will either be removed on timeout or will re-added to the world on receipt of update.
render::ScenePointer scene = qApp->getMain3DScene();
render::Transaction transaction;
QReadLocker locker(&_hashLock);
AvatarHash::iterator avatarIterator = _avatarHash.begin(); AvatarHash::iterator avatarIterator = _avatarHash.begin();
while (avatarIterator != _avatarHash.end()) { while (avatarIterator != _avatarHash.end()) {
auto avatar = std::static_pointer_cast<Avatar>(avatarIterator.value()); auto avatar = std::static_pointer_cast<Avatar>(avatarIterator.value());
if (avatar == _myAvatar || !avatar->isInitialized()) { if (avatar != _myAvatar) {
// don't remove myAvatar or uninitialized avatars from the list if (avatar->isInScene()) {
++avatarIterator; avatar->removeFromScene(avatar, scene, transaction);
} else { }
auto removedAvatar = avatarIterator.value(); AvatarMotionState* motionState = avatar->getMotionState();
avatarIterator = _avatarHash.erase(avatarIterator); if (motionState) {
_motionStatesThatMightUpdate.remove(motionState);
handleRemovedAvatar(removedAvatar); _motionStatesToAddToPhysics.remove(motionState);
_motionStatesToRemoveFromPhysics.push_back(motionState);
}
} }
++avatarIterator;
}
if (scene) {
scene->enqueueTransaction(transaction);
} }
_myAvatar->clearLookAtTargetAvatar(); _myAvatar->clearLookAtTargetAvatar();
} }
void AvatarManager::clearAllAvatars() { void AvatarManager::deleteAllAvatars() {
clearOtherAvatars(); QReadLocker locker(&_hashLock);
AvatarHash::iterator avatarIterator = _avatarHash.begin();
QWriteLocker locker(&_hashLock); while (avatarIterator != _avatarHash.end()) {
auto avatar = std::static_pointer_cast<Avatar>(avatarIterator.value());
handleRemovedAvatar(_myAvatar); avatarIterator = _avatarHash.erase(avatarIterator);
avatar->die();
}
} }
void AvatarManager::setLocalLights(const QVector<AvatarManager::LocalLight>& localLights) { void AvatarManager::setLocalLights(const QVector<AvatarManager::LocalLight>& localLights) {
@ -475,26 +521,25 @@ void AvatarManager::handleCollisionEvents(const CollisionEvents& collisionEvents
} }
void AvatarManager::updateAvatarRenderStatus(bool shouldRenderAvatars) { void AvatarManager::updateAvatarRenderStatus(bool shouldRenderAvatars) {
if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderAvatars()) { _shouldRender = shouldRenderAvatars;
render::ScenePointer scene = qApp->getMain3DScene();
render::Transaction transaction;
if (_shouldRender) {
for (auto avatarData : _avatarHash) { for (auto avatarData : _avatarHash) {
auto avatar = std::static_pointer_cast<Avatar>(avatarData); auto avatar = std::static_pointer_cast<Avatar>(avatarData);
render::ScenePointer scene = qApp->getMain3DScene();
render::Transaction transaction;
avatar->addToScene(avatar, scene, transaction); avatar->addToScene(avatar, scene, transaction);
scene->enqueueTransaction(transaction);
} }
} else { } else {
for (auto avatarData : _avatarHash) { for (auto avatarData : _avatarHash) {
auto avatar = std::static_pointer_cast<Avatar>(avatarData); auto avatar = std::static_pointer_cast<Avatar>(avatarData);
render::ScenePointer scene = qApp->getMain3DScene();
render::Transaction transaction;
avatar->removeFromScene(avatar, scene, transaction); avatar->removeFromScene(avatar, scene, transaction);
scene->enqueueTransaction(transaction);
} }
} }
if (scene) {
scene->enqueueTransaction(transaction);
}
} }
AvatarSharedPointer AvatarManager::getAvatarBySessionID(const QUuid& sessionID) const { AvatarSharedPointer AvatarManager::getAvatarBySessionID(const QUuid& sessionID) const {
if (sessionID == AVATAR_SELF_ID || sessionID == _myAvatar->getSessionUUID()) { if (sessionID == AVATAR_SELF_ID || sessionID == _myAvatar->getSessionUUID()) {
return _myAvatar; return _myAvatar;

View file

@ -53,7 +53,7 @@ public:
void postUpdate(float deltaTime); void postUpdate(float deltaTime);
void clearOtherAvatars(); void clearOtherAvatars();
void clearAllAvatars(); void deleteAllAvatars();
bool shouldShowReceiveStats() const { return _shouldShowReceiveStats; } bool shouldShowReceiveStats() const { return _shouldShowReceiveStats; }
@ -91,8 +91,8 @@ public slots:
void setShouldShowReceiveStats(bool shouldShowReceiveStats) { _shouldShowReceiveStats = shouldShowReceiveStats; } void setShouldShowReceiveStats(bool shouldShowReceiveStats) { _shouldShowReceiveStats = shouldShowReceiveStats; }
void updateAvatarRenderStatus(bool shouldRenderAvatars); void updateAvatarRenderStatus(bool shouldRenderAvatars);
private slots: protected slots:
virtual void removeAvatar(const QUuid& sessionUUID, KillAvatarReason removalReason = KillAvatarReason::NoReason) override; void processAvatarDataPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode) override;
private: private:
explicit AvatarManager(QObject* parent = 0); explicit AvatarManager(QObject* parent = 0);
@ -100,12 +100,15 @@ private:
void simulateAvatarFades(float deltaTime); void simulateAvatarFades(float deltaTime);
// virtual overrides AvatarSharedPointer newSharedAvatar() override;
virtual AvatarSharedPointer newSharedAvatar() override; void handleRemovedAvatar(const AvatarSharedPointer& removedAvatar, KillAvatarReason removalReason = KillAvatarReason::NoReason) override;
virtual AvatarSharedPointer addAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer) override;
virtual void handleRemovedAvatar(const AvatarSharedPointer& removedAvatar, KillAvatarReason removalReason = KillAvatarReason::NoReason) override; QVector<AvatarSharedPointer> _avatarsToFade;
SetOfAvatarMotionStates _motionStatesThatMightUpdate;
VectorOfMotionStates _motionStatesToRemoveFromPhysics;
SetOfMotionStates _motionStatesToAddToPhysics;
QVector<AvatarSharedPointer> _avatarFades;
std::shared_ptr<MyAvatar> _myAvatar; std::shared_ptr<MyAvatar> _myAvatar;
quint64 _lastSendAvatarDataTime = 0; // Controls MyAvatar send data rate. quint64 _lastSendAvatarDataTime = 0; // Controls MyAvatar send data rate.
@ -115,14 +118,11 @@ private:
std::list<QPointer<AudioInjector>> _collisionInjectors; std::list<QPointer<AudioInjector>> _collisionInjectors;
SetOfAvatarMotionStates _motionStatesThatMightUpdate;
SetOfMotionStates _motionStatesToAddToPhysics;
VectorOfMotionStates _motionStatesToRemoveFromPhysics;
RateCounter<> _myAvatarSendRate; RateCounter<> _myAvatarSendRate;
int _numAvatarsUpdated { 0 }; int _numAvatarsUpdated { 0 };
int _numAvatarsNotUpdated { 0 }; int _numAvatarsNotUpdated { 0 };
float _avatarSimulationTime { 0.0f }; float _avatarSimulationTime { 0.0f };
bool _shouldRender { true };
}; };
Q_DECLARE_METATYPE(AvatarManager::LocalLight) Q_DECLARE_METATYPE(AvatarManager::LocalLight)

View file

@ -54,6 +54,7 @@
#include "DebugDraw.h" #include "DebugDraw.h"
#include "EntityEditPacketSender.h" #include "EntityEditPacketSender.h"
#include "MovingEntitiesOperator.h" #include "MovingEntitiesOperator.h"
#include "SceneScriptingInterface.h"
using namespace std; using namespace std;
@ -1634,7 +1635,7 @@ void MyAvatar::postUpdate(float deltaTime) {
Avatar::postUpdate(deltaTime); Avatar::postUpdate(deltaTime);
render::ScenePointer scene = qApp->getMain3DScene(); render::ScenePointer scene = qApp->getMain3DScene();
if (_skeletonModel->initWhenReady(scene)) { if (DependencyManager::get<SceneScriptingInterface>()->shouldRenderAvatars() && _skeletonModel->initWhenReady(scene)) {
initHeadBones(); initHeadBones();
_skeletonModel->setCauterizeBoneSet(_headBoneSet); _skeletonModel->setCauterizeBoneSet(_headBoneSet);
_fstAnimGraphOverrideUrl = _skeletonModel->getGeometry()->getAnimGraphOverrideUrl(); _fstAnimGraphOverrideUrl = _skeletonModel->getGeometry()->getAnimGraphOverrideUrl();

View file

@ -123,6 +123,7 @@ void AvatarData::setTargetScale(float targetScale) {
if (_targetScale != newValue) { if (_targetScale != newValue) {
_targetScale = newValue; _targetScale = newValue;
_scaleChanged = usecTimestampNow(); _scaleChanged = usecTimestampNow();
_avatarScaleChanged = _scaleChanged;
} }
} }

View file

@ -80,13 +80,10 @@ AvatarSharedPointer AvatarHashMap::addAvatar(const QUuid& sessionUUID, const QWe
AvatarSharedPointer AvatarHashMap::newOrExistingAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer) { AvatarSharedPointer AvatarHashMap::newOrExistingAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer) {
QWriteLocker locker(&_hashLock); QWriteLocker locker(&_hashLock);
auto avatar = _avatarHash.value(sessionUUID); auto avatar = _avatarHash.value(sessionUUID);
if (!avatar) { if (!avatar) {
avatar = addAvatar(sessionUUID, mixerWeakPointer); avatar = addAvatar(sessionUUID, mixerWeakPointer);
} }
return avatar; return avatar;
} }
@ -103,27 +100,33 @@ void AvatarHashMap::processAvatarDataPacket(QSharedPointer<ReceivedMessage> mess
// enumerate over all of the avatars in this packet // enumerate over all of the avatars in this packet
// only add them if mixerWeakPointer points to something (meaning that mixer is still around) // only add them if mixerWeakPointer points to something (meaning that mixer is still around)
while (message->getBytesLeftToRead()) { while (message->getBytesLeftToRead()) {
QUuid sessionUUID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID)); parseAvatarData(message, sendingNode);
}
}
int positionBeforeRead = message->getPosition(); AvatarSharedPointer AvatarHashMap::parseAvatarData(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode) {
QUuid sessionUUID = QUuid::fromRfc4122(message->readWithoutCopy(NUM_BYTES_RFC4122_UUID));
QByteArray byteArray = message->readWithoutCopy(message->getBytesLeftToRead()); int positionBeforeRead = message->getPosition();
// make sure this isn't our own avatar data or for a previously ignored node QByteArray byteArray = message->readWithoutCopy(message->getBytesLeftToRead());
auto nodeList = DependencyManager::get<NodeList>();
if (sessionUUID != _lastOwnerSessionUUID && (!nodeList->isIgnoringNode(sessionUUID) || nodeList->getRequestsDomainListData())) { // make sure this isn't our own avatar data or for a previously ignored node
auto avatar = newOrExistingAvatar(sessionUUID, sendingNode); auto nodeList = DependencyManager::get<NodeList>();
// have the matching (or new) avatar parse the data from the packet if (sessionUUID != _lastOwnerSessionUUID && (!nodeList->isIgnoringNode(sessionUUID) || nodeList->getRequestsDomainListData())) {
int bytesRead = avatar->parseDataFromBuffer(byteArray); auto avatar = newOrExistingAvatar(sessionUUID, sendingNode);
message->seek(positionBeforeRead + bytesRead);
} else { // have the matching (or new) avatar parse the data from the packet
// create a dummy AvatarData class to throw this data on the ground int bytesRead = avatar->parseDataFromBuffer(byteArray);
AvatarData dummyData; message->seek(positionBeforeRead + bytesRead);
int bytesRead = dummyData.parseDataFromBuffer(byteArray); return avatar;
message->seek(positionBeforeRead + bytesRead); } else {
} // create a dummy AvatarData class to throw this data on the ground
AvatarData dummyData;
int bytesRead = dummyData.parseDataFromBuffer(byteArray);
message->seek(positionBeforeRead + bytesRead);
return std::make_shared<AvatarData>();
} }
} }

View file

@ -49,11 +49,11 @@ signals:
public slots: public slots:
bool isAvatarInRange(const glm::vec3 & position, const float range); bool isAvatarInRange(const glm::vec3 & position, const float range);
private slots: protected slots:
void sessionUUIDChanged(const QUuid& sessionUUID, const QUuid& oldUUID); void sessionUUIDChanged(const QUuid& sessionUUID, const QUuid& oldUUID);
void processAvatarDataPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode); virtual void processAvatarDataPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
void processAvatarIdentityPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode); void processAvatarIdentityPacket(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
void processKillAvatar(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode); void processKillAvatar(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
void processExitingSpaceBubble(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode); void processExitingSpaceBubble(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
@ -61,12 +61,13 @@ private slots:
protected: protected:
AvatarHashMap(); AvatarHashMap();
virtual AvatarSharedPointer parseAvatarData(QSharedPointer<ReceivedMessage> message, SharedNodePointer sendingNode);
virtual AvatarSharedPointer newSharedAvatar(); virtual AvatarSharedPointer newSharedAvatar();
virtual AvatarSharedPointer addAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer); virtual AvatarSharedPointer addAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer);
AvatarSharedPointer newOrExistingAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer); AvatarSharedPointer newOrExistingAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer);
virtual AvatarSharedPointer findAvatar(const QUuid& sessionUUID) const; // uses a QReadLocker on the hashLock virtual AvatarSharedPointer findAvatar(const QUuid& sessionUUID) const; // uses a QReadLocker on the hashLock
virtual void removeAvatar(const QUuid& sessionUUID, KillAvatarReason removalReason = KillAvatarReason::NoReason); virtual void removeAvatar(const QUuid& sessionUUID, KillAvatarReason removalReason = KillAvatarReason::NoReason);
virtual void handleRemovedAvatar(const AvatarSharedPointer& removedAvatar, KillAvatarReason removalReason = KillAvatarReason::NoReason); virtual void handleRemovedAvatar(const AvatarSharedPointer& removedAvatar, KillAvatarReason removalReason = KillAvatarReason::NoReason);
AvatarHash _avatarHash; AvatarHash _avatarHash;