Avatar loading orb now indicates status

white - no url has been received yet for this avatar
purple - a url has been received for this avatar but it's content is still downloading/loading
blue - (only visible breifly) content has succesfully loaded
red - (only visible briefly) content has failed to download.
This commit is contained in:
Anthony Thibault 2018-09-11 13:12:46 -07:00
parent 19a9fb00c6
commit bc5d9a46a2
4 changed files with 50 additions and 5 deletions

View file

@ -11,6 +11,24 @@
#include "AvatarMotionState.h" #include "AvatarMotionState.h"
static xColor getLoadingOrbColor(Avatar::LoadingStatus loadingStatus) {
const xColor NO_MODEL_COLOR(0xe3, 0xe3, 0xe3);
const xColor LOAD_MODEL_COLOR(0xef, 0x93, 0xd1);
const xColor LOAD_SUCCESS_COLOR(0x1f, 0xc6, 0xa6);
const xColor LOAD_FAILURE_COLOR(0xc6, 0x21, 0x47);
switch (loadingStatus) {
case Avatar::LoadingStatus::NoModel:
return NO_MODEL_COLOR;
case Avatar::LoadingStatus::LoadModel:
return LOAD_MODEL_COLOR;
case Avatar::LoadingStatus::LoadSuccess:
return LOAD_SUCCESS_COLOR;
case Avatar::LoadingStatus::LoadFailure:
return LOAD_FAILURE_COLOR;
}
}
OtherAvatar::OtherAvatar(QThread* thread) : Avatar(thread) { OtherAvatar::OtherAvatar(QThread* thread) : Avatar(thread) {
// give the pointer to our head to inherited _headData variable from AvatarData // give the pointer to our head to inherited _headData variable from AvatarData
_headData = new Head(this); _headData = new Head(this);
@ -48,7 +66,7 @@ void OtherAvatar::createOrb() {
if (_otherAvatarOrbMeshPlaceholderID.isNull()) { if (_otherAvatarOrbMeshPlaceholderID.isNull()) {
_otherAvatarOrbMeshPlaceholder = std::make_shared<Sphere3DOverlay>(); _otherAvatarOrbMeshPlaceholder = std::make_shared<Sphere3DOverlay>();
_otherAvatarOrbMeshPlaceholder->setAlpha(1.0f); _otherAvatarOrbMeshPlaceholder->setAlpha(1.0f);
_otherAvatarOrbMeshPlaceholder->setColor({ 0xFF, 0x00, 0xFF }); _otherAvatarOrbMeshPlaceholder->setColor(getLoadingOrbColor(_loadingStatus));
_otherAvatarOrbMeshPlaceholder->setIsSolid(false); _otherAvatarOrbMeshPlaceholder->setIsSolid(false);
_otherAvatarOrbMeshPlaceholder->setPulseMin(0.5); _otherAvatarOrbMeshPlaceholder->setPulseMin(0.5);
_otherAvatarOrbMeshPlaceholder->setPulseMax(1.0); _otherAvatarOrbMeshPlaceholder->setPulseMax(1.0);
@ -64,6 +82,13 @@ void OtherAvatar::createOrb() {
} }
} }
void OtherAvatar::indicateLoadingStatus(LoadingStatus loadingStatus) {
Avatar::indicateLoadingStatus(loadingStatus);
if (_otherAvatarOrbMeshPlaceholder) {
_otherAvatarOrbMeshPlaceholder->setColor(getLoadingOrbColor(_loadingStatus));
}
}
void OtherAvatar::setSpaceIndex(int32_t index) { void OtherAvatar::setSpaceIndex(int32_t index) {
assert(_spaceIndex == -1); assert(_spaceIndex == -1);
_spaceIndex = index; _spaceIndex = index;

View file

@ -28,6 +28,7 @@ public:
virtual void instantiableAvatar() override { }; virtual void instantiableAvatar() override { };
virtual void createOrb() override; virtual void createOrb() override;
virtual void indicateLoadingStatus(LoadingStatus loadingStatus) override;
void updateOrbPosition(); void updateOrbPosition();
void removeOrb(); void removeOrb();

View file

@ -126,6 +126,8 @@ Avatar::Avatar(QThread* thread) :
_leftPointerGeometryID = geometryCache->allocateID(); _leftPointerGeometryID = geometryCache->allocateID();
_rightPointerGeometryID = geometryCache->allocateID(); _rightPointerGeometryID = geometryCache->allocateID();
_lastRenderUpdateTime = usecTimestampNow(); _lastRenderUpdateTime = usecTimestampNow();
indicateLoadingStatus(LoadingStatus::NoModel);
} }
Avatar::~Avatar() { Avatar::~Avatar() {
@ -1370,12 +1372,15 @@ void Avatar::scaleVectorRelativeToPosition(glm::vec3 &positionToScale) const {
} }
void Avatar::setSkeletonModelURL(const QUrl& skeletonModelURL) { void Avatar::setSkeletonModelURL(const QUrl& skeletonModelURL) {
AvatarData::setSkeletonModelURL(skeletonModelURL);
if (QThread::currentThread() == thread()) {
if (!isMyAvatar()) { if (!isMyAvatar()) {
createOrb(); createOrb();
} }
AvatarData::setSkeletonModelURL(skeletonModelURL);
if (QThread::currentThread() == thread()) {
_skeletonModel->setURL(_skeletonModelURL); _skeletonModel->setURL(_skeletonModelURL);
indicateLoadingStatus(LoadingStatus::LoadModel);
} else { } else {
QMetaObject::invokeMethod(_skeletonModel.get(), "setURL", Qt::QueuedConnection, Q_ARG(QUrl, _skeletonModelURL)); QMetaObject::invokeMethod(_skeletonModel.get(), "setURL", Qt::QueuedConnection, Q_ARG(QUrl, _skeletonModelURL));
} }
@ -1388,6 +1393,7 @@ void Avatar::setModelURLFinished(bool success) {
_reconstructSoftEntitiesJointMap = true; _reconstructSoftEntitiesJointMap = true;
if (!success && _skeletonModelURL != AvatarData::defaultFullAvatarModelUrl()) { if (!success && _skeletonModelURL != AvatarData::defaultFullAvatarModelUrl()) {
indicateLoadingStatus(LoadingStatus::LoadFailure);
const int MAX_SKELETON_DOWNLOAD_ATTEMPTS = 4; // NOTE: we don't want to be as generous as ResourceCache is, we only want 4 attempts const int MAX_SKELETON_DOWNLOAD_ATTEMPTS = 4; // NOTE: we don't want to be as generous as ResourceCache is, we only want 4 attempts
if (_skeletonModel->getResourceDownloadAttemptsRemaining() <= 0 || if (_skeletonModel->getResourceDownloadAttemptsRemaining() <= 0 ||
_skeletonModel->getResourceDownloadAttempts() > MAX_SKELETON_DOWNLOAD_ATTEMPTS) { _skeletonModel->getResourceDownloadAttempts() > MAX_SKELETON_DOWNLOAD_ATTEMPTS) {
@ -1403,6 +1409,9 @@ void Avatar::setModelURLFinished(bool success) {
<< "out of:" << MAX_SKELETON_DOWNLOAD_ATTEMPTS; << "out of:" << MAX_SKELETON_DOWNLOAD_ATTEMPTS;
} }
} }
if (success) {
indicateLoadingStatus(LoadingStatus::LoadSuccess);
}
} }
// rig is ready // rig is ready

View file

@ -107,6 +107,14 @@ public:
virtual bool isMyAvatar() const override { return false; } virtual bool isMyAvatar() const override { return false; }
virtual void createOrb() { } virtual void createOrb() { }
enum class LoadingStatus {
NoModel,
LoadModel,
LoadSuccess,
LoadFailure
};
virtual void indicateLoadingStatus(LoadingStatus loadingStatus) { _loadingStatus = loadingStatus; }
virtual QVector<glm::quat> getJointRotations() const override; virtual QVector<glm::quat> getJointRotations() const override;
using AvatarData::getJointRotation; using AvatarData::getJointRotation;
virtual glm::quat getJointRotation(int index) const override; virtual glm::quat getJointRotation(int index) const override;
@ -540,6 +548,8 @@ protected:
static const float MYAVATAR_LOADING_PRIORITY; static const float MYAVATAR_LOADING_PRIORITY;
static const float OTHERAVATAR_LOADING_PRIORITY; static const float OTHERAVATAR_LOADING_PRIORITY;
static const float ATTACHMENT_LOADING_PRIORITY; static const float ATTACHMENT_LOADING_PRIORITY;
LoadingStatus _loadingStatus { LoadingStatus::NoModel };
}; };
#endif // hifi_Avatar_h #endif // hifi_Avatar_h