mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 15:17:42 +02:00
Merge pull request #16392 from kitely/load-avatar-entities-after-skeleton
In Bookmarks, attach avatar entities after the skeleton is loaded
This commit is contained in:
commit
9948a181dc
5 changed files with 46 additions and 17 deletions
|
@ -212,22 +212,36 @@ void AvatarBookmarks::loadBookmark(const QString& bookmarkName) {
|
||||||
auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
auto myAvatar = DependencyManager::get<AvatarManager>()->getMyAvatar();
|
||||||
auto treeRenderer = DependencyManager::get<EntityTreeRenderer>();
|
auto treeRenderer = DependencyManager::get<EntityTreeRenderer>();
|
||||||
EntityTreePointer entityTree = treeRenderer ? treeRenderer->getTree() : nullptr;
|
EntityTreePointer entityTree = treeRenderer ? treeRenderer->getTree() : nullptr;
|
||||||
myAvatar->clearWornAvatarEntities();
|
|
||||||
|
// Once the skeleton URL has been loaded, add the Avatar Entities.
|
||||||
|
// We have to wait, because otherwise the avatar entities will try to get attached to the joints
|
||||||
|
// of the *current* avatar at first. But the current avatar might have a different joints scheme
|
||||||
|
// from the new avatar, and that would cause the entities to be attached to the wrong joints.
|
||||||
|
|
||||||
|
std::shared_ptr<QMetaObject::Connection> connection1 = std::make_shared<QMetaObject::Connection>();
|
||||||
|
*connection1 = connect(myAvatar.get(), &MyAvatar::onLoadComplete, [this, bookmark, bookmarkName, myAvatar, connection1]() {
|
||||||
|
qCDebug(interfaceapp) << "Finish loading avatar bookmark" << bookmarkName;
|
||||||
|
QObject::disconnect(*connection1);
|
||||||
|
myAvatar->clearWornAvatarEntities();
|
||||||
|
const float& qScale = bookmark.value(ENTRY_AVATAR_SCALE, 1.0f).toFloat();
|
||||||
|
myAvatar->setAvatarScale(qScale);
|
||||||
|
QList<QVariant> attachments = bookmark.value(ENTRY_AVATAR_ATTACHMENTS, QList<QVariant>()).toList();
|
||||||
|
myAvatar->setAttachmentsVariant(attachments);
|
||||||
|
QVariantList avatarEntities = bookmark.value(ENTRY_AVATAR_ENTITIES, QVariantList()).toList();
|
||||||
|
addAvatarEntities(avatarEntities);
|
||||||
|
emit bookmarkLoaded(bookmarkName);
|
||||||
|
});
|
||||||
|
|
||||||
|
std::shared_ptr<QMetaObject::Connection> connection2 = std::make_shared<QMetaObject::Connection>();
|
||||||
|
*connection2 = connect(myAvatar.get(), &MyAvatar::onLoadFailed, [this, bookmarkName, connection2]() {
|
||||||
|
qCDebug(interfaceapp) << "Failed to load avatar bookmark" << bookmarkName;
|
||||||
|
QObject::disconnect(*connection2);
|
||||||
|
});
|
||||||
|
|
||||||
|
qCDebug(interfaceapp) << "Start loading avatar bookmark" << bookmarkName;
|
||||||
|
|
||||||
const QString& avatarUrl = bookmark.value(ENTRY_AVATAR_URL, "").toString();
|
const QString& avatarUrl = bookmark.value(ENTRY_AVATAR_URL, "").toString();
|
||||||
myAvatar->useFullAvatarURL(avatarUrl);
|
myAvatar->useFullAvatarURL(avatarUrl);
|
||||||
qCDebug(interfaceapp) << "Avatar On";
|
|
||||||
const QList<QVariant>& attachments = bookmark.value(ENTRY_AVATAR_ATTACHMENTS, QList<QVariant>()).toList();
|
|
||||||
|
|
||||||
qCDebug(interfaceapp) << "Attach " << attachments;
|
|
||||||
myAvatar->setAttachmentsVariant(attachments);
|
|
||||||
|
|
||||||
const float& qScale = bookmark.value(ENTRY_AVATAR_SCALE, 1.0f).toFloat();
|
|
||||||
myAvatar->setAvatarScale(qScale);
|
|
||||||
|
|
||||||
const QVariantList& avatarEntities = bookmark.value(ENTRY_AVATAR_ENTITIES, QVariantList()).toList();
|
|
||||||
addAvatarEntities(avatarEntities);
|
|
||||||
|
|
||||||
emit bookmarkLoaded(bookmarkName);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -349,7 +349,8 @@ MyAvatar::MyAvatar(QThread* thread) :
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(&(_skeletonModel->getRig()), SIGNAL(onLoadComplete()), this, SIGNAL(onLoadComplete()));
|
connect(&(_skeletonModel->getRig()), &Rig::onLoadComplete, this, &MyAvatar::onLoadComplete);
|
||||||
|
connect(&(_skeletonModel->getRig()), &Rig::onLoadFailed, this, &MyAvatar::onLoadFailed);
|
||||||
|
|
||||||
_characterController.setDensity(_density);
|
_characterController.setDensity(_density);
|
||||||
}
|
}
|
||||||
|
@ -2635,6 +2636,8 @@ void MyAvatar::useFullAvatarURL(const QUrl& fullAvatarURL, const QString& modelN
|
||||||
if (urlString.isEmpty() || (fullAvatarURL != getSkeletonModelURL())) {
|
if (urlString.isEmpty() || (fullAvatarURL != getSkeletonModelURL())) {
|
||||||
setSkeletonModelURL(fullAvatarURL);
|
setSkeletonModelURL(fullAvatarURL);
|
||||||
UserActivityLogger::getInstance().changedModel("skeleton", urlString);
|
UserActivityLogger::getInstance().changedModel("skeleton", urlString);
|
||||||
|
} else {
|
||||||
|
emit onLoadComplete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2463,10 +2463,17 @@ signals:
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* Triggered when the avatar's model finishes loading.
|
* Triggered when the avatar's model finishes loading.
|
||||||
* @function MyAvatar.onLoadComplete
|
* @function MyAvatar.onLoadComplete
|
||||||
* @returns {Signal}
|
* @returns {Signal}
|
||||||
*/
|
*/
|
||||||
void onLoadComplete();
|
void onLoadComplete();
|
||||||
|
|
||||||
|
/**jsdoc
|
||||||
|
* Triggered when the avatar's model has failed to load.
|
||||||
|
* @function MyAvatar.onLoadFailed
|
||||||
|
* @returns {Signal}
|
||||||
|
*/
|
||||||
|
void onLoadFailed();
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* Triggered when your avatar changes from being active to being away.
|
* Triggered when your avatar changes from being active to being away.
|
||||||
* @function MyAvatar.wentAway
|
* @function MyAvatar.wentAway
|
||||||
|
|
|
@ -2353,6 +2353,7 @@ void Rig::initAnimGraph(const QUrl& url) {
|
||||||
// abort load if the previous skeleton was deleted.
|
// abort load if the previous skeleton was deleted.
|
||||||
auto sharedSkeletonPtr = weakSkeletonPtr.lock();
|
auto sharedSkeletonPtr = weakSkeletonPtr.lock();
|
||||||
if (!sharedSkeletonPtr) {
|
if (!sharedSkeletonPtr) {
|
||||||
|
emit onLoadFailed();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2386,8 +2387,9 @@ void Rig::initAnimGraph(const QUrl& url) {
|
||||||
}
|
}
|
||||||
emit onLoadComplete();
|
emit onLoadComplete();
|
||||||
});
|
});
|
||||||
connect(_animLoader.get(), &AnimNodeLoader::error, [url](int error, QString str) {
|
connect(_animLoader.get(), &AnimNodeLoader::error, [this, url](int error, QString str) {
|
||||||
qCritical(animation) << "Error loading: code = " << error << "str =" << str;
|
qCritical(animation) << "Error loading: code = " << error << "str =" << str;
|
||||||
|
emit onLoadFailed();
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(_networkLoader.get(), &AnimNodeLoader::success, [this, weakSkeletonPtr, networkUrl](AnimNode::Pointer nodeIn) {
|
connect(_networkLoader.get(), &AnimNodeLoader::success, [this, weakSkeletonPtr, networkUrl](AnimNode::Pointer nodeIn) {
|
||||||
|
@ -2415,6 +2417,8 @@ void Rig::initAnimGraph(const QUrl& url) {
|
||||||
connect(_networkLoader.get(), &AnimNodeLoader::error, [networkUrl](int error, QString str) {
|
connect(_networkLoader.get(), &AnimNodeLoader::error, [networkUrl](int error, QString str) {
|
||||||
qCritical(animation) << "Error loading: code = " << error << "str =" << str;
|
qCritical(animation) << "Error loading: code = " << error << "str =" << str;
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
emit onLoadComplete();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -260,6 +260,7 @@ public:
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void onLoadComplete();
|
void onLoadComplete();
|
||||||
|
void onLoadFailed();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
bool isIndexValid(int index) const { return _animSkeleton && index >= 0 && index < _animSkeleton->getNumJoints(); }
|
bool isIndexValid(int index) const { return _animSkeleton && index >= 0 && index < _animSkeleton->getNumJoints(); }
|
||||||
|
|
Loading…
Reference in a new issue