mirror of
https://github.com/overte-org/overte.git
synced 2025-04-22 01:24:05 +02:00
Support for animGraphUrl override in FST file.
This commit is contained in:
parent
592a50356b
commit
2429b82b5e
5 changed files with 72 additions and 14 deletions
interface/src
libraries/model-networking/src/model-networking
|
@ -687,7 +687,9 @@ void MyAvatar::saveData() {
|
|||
_fullAvatarURLFromPreferences.toString());
|
||||
|
||||
settings.setValue("fullAvatarModelName", _fullAvatarModelName);
|
||||
settings.setValue("animGraphURL", _animGraphUrl);
|
||||
|
||||
QUrl animGraphUrl = _prefOverrideAnimGraphUrl.get();
|
||||
settings.setValue("animGraphURL", animGraphUrl);
|
||||
|
||||
settings.beginWriteArray("attachmentData");
|
||||
for (int i = 0; i < _attachmentData.size(); i++) {
|
||||
|
@ -800,7 +802,7 @@ void MyAvatar::loadData() {
|
|||
_targetScale = loadSetting(settings, "scale", 1.0f);
|
||||
setScale(glm::vec3(_targetScale));
|
||||
|
||||
_animGraphUrl = settings.value("animGraphURL", "").toString();
|
||||
_prefOverrideAnimGraphUrl.set(QUrl(settings.value("animGraphURL", "").toString()));
|
||||
_fullAvatarURLFromPreferences = settings.value("fullAvatarURL", AvatarData::defaultFullAvatarModelUrl()).toUrl();
|
||||
_fullAvatarModelName = settings.value("fullAvatarModelName", DEFAULT_FULL_AVATAR_MODEL_NAME).toString();
|
||||
|
||||
|
@ -1379,21 +1381,55 @@ void MyAvatar::initHeadBones() {
|
|||
}
|
||||
}
|
||||
|
||||
QUrl MyAvatar::getAnimGraphOverrideUrl() const {
|
||||
return _prefOverrideAnimGraphUrl.get();
|
||||
}
|
||||
|
||||
void MyAvatar::setAnimGraphOverrideUrl(QUrl value) {
|
||||
_prefOverrideAnimGraphUrl.set(value);
|
||||
if (!value.isEmpty()) {
|
||||
setAnimGraphUrl(value);
|
||||
} else {
|
||||
initAnimGraph();
|
||||
}
|
||||
}
|
||||
|
||||
QUrl MyAvatar::getAnimGraphUrl() const {
|
||||
return _currentAnimGraphUrl.get();
|
||||
}
|
||||
|
||||
void MyAvatar::setAnimGraphUrl(const QUrl& url) {
|
||||
if (_animGraphUrl == url) {
|
||||
|
||||
if (QThread::currentThread() != thread()) {
|
||||
QMetaObject::invokeMethod(this, "setAnimGraphUrl", Q_ARG(QUrl, url));
|
||||
return;
|
||||
}
|
||||
|
||||
if (_currentAnimGraphUrl.get() == url) {
|
||||
return;
|
||||
}
|
||||
destroyAnimGraph();
|
||||
_skeletonModel->reset(); // Why is this necessary? Without this, we crash in the next render.
|
||||
_animGraphUrl = url;
|
||||
initAnimGraph();
|
||||
|
||||
_currentAnimGraphUrl.set(url);
|
||||
_rig->initAnimGraph(url);
|
||||
|
||||
_bodySensorMatrix = deriveBodyFromHMDSensor(); // Based on current cached HMD position/rotation..
|
||||
updateSensorToWorldMatrix(); // Uses updated position/orientation and _bodySensorMatrix changes
|
||||
}
|
||||
|
||||
void MyAvatar::initAnimGraph() {
|
||||
auto graphUrl =_animGraphUrl.isEmpty() ?
|
||||
QUrl::fromLocalFile(PathUtils::resourcesPath() + "avatar/avatar-animation.json") :
|
||||
QUrl(_animGraphUrl);
|
||||
QUrl graphUrl;
|
||||
if (!_prefOverrideAnimGraphUrl.get().isEmpty()) {
|
||||
graphUrl = _prefOverrideAnimGraphUrl.get();
|
||||
} else if (!_fstAnimGraphOverrideUrl.isEmpty()) {
|
||||
graphUrl = _fstAnimGraphOverrideUrl;
|
||||
} else {
|
||||
graphUrl = QUrl::fromLocalFile(PathUtils::resourcesPath() + "avatar/avatar-animation.json");
|
||||
}
|
||||
|
||||
_rig->initAnimGraph(graphUrl);
|
||||
_currentAnimGraphUrl.set(graphUrl);
|
||||
|
||||
_bodySensorMatrix = deriveBodyFromHMDSensor(); // Based on current cached HMD position/rotation..
|
||||
updateSensorToWorldMatrix(); // Uses updated position/orientation and _bodySensorMatrix changes
|
||||
|
@ -1411,6 +1447,7 @@ void MyAvatar::postUpdate(float deltaTime) {
|
|||
if (_skeletonModel->initWhenReady(scene)) {
|
||||
initHeadBones();
|
||||
_skeletonModel->setCauterizeBoneSet(_headBoneSet);
|
||||
_fstAnimGraphOverrideUrl = _skeletonModel->getGeometry()->getAnimGraphOverrideUrl();
|
||||
initAnimGraph();
|
||||
}
|
||||
|
||||
|
|
|
@ -288,8 +288,6 @@ public slots:
|
|||
|
||||
Q_INVOKABLE void updateMotionBehaviorFromMenu();
|
||||
|
||||
Q_INVOKABLE QUrl getAnimGraphUrl() const { return _animGraphUrl; }
|
||||
|
||||
void setEnableDebugDrawDefaultPose(bool isEnabled);
|
||||
void setEnableDebugDrawAnimPose(bool isEnabled);
|
||||
void setEnableDebugDrawPosition(bool isEnabled);
|
||||
|
@ -299,7 +297,11 @@ public slots:
|
|||
void setEnableMeshVisible(bool isEnabled);
|
||||
void setUseAnimPreAndPostRotations(bool isEnabled);
|
||||
void setEnableInverseKinematics(bool isEnabled);
|
||||
Q_INVOKABLE void setAnimGraphUrl(const QUrl& url);
|
||||
|
||||
QUrl getAnimGraphOverrideUrl() const; // thread-safe
|
||||
void setAnimGraphOverrideUrl(QUrl value); // thread-safe
|
||||
QUrl getAnimGraphUrl() const; // thread-safe
|
||||
void setAnimGraphUrl(const QUrl& url); // thread-safe
|
||||
|
||||
glm::vec3 getPositionForAudio();
|
||||
glm::quat getOrientationForAudio();
|
||||
|
@ -403,7 +405,9 @@ private:
|
|||
// Avatar Preferences
|
||||
QUrl _fullAvatarURLFromPreferences;
|
||||
QString _fullAvatarModelName;
|
||||
QUrl _animGraphUrl {""};
|
||||
ThreadSafeValueCache<QUrl> _currentAnimGraphUrl;
|
||||
ThreadSafeValueCache<QUrl> _prefOverrideAnimGraphUrl;
|
||||
QUrl _fstAnimGraphOverrideUrl;
|
||||
bool _useSnapTurn { true };
|
||||
bool _clearOverlayWhenMoving { true };
|
||||
|
||||
|
|
|
@ -161,8 +161,8 @@ void setupPreferences() {
|
|||
preferences->addPreference(preference);
|
||||
}
|
||||
{
|
||||
auto getter = [=]()->QString { return myAvatar->getAnimGraphUrl().toString(); };
|
||||
auto setter = [=](const QString& value) { myAvatar->setAnimGraphUrl(value); };
|
||||
auto getter = [=]()->QString { return myAvatar->getAnimGraphOverrideUrl().toString(); };
|
||||
auto setter = [=](const QString& value) { myAvatar->setAnimGraphOverrideUrl(QUrl(value)); };
|
||||
auto preference = new EditPreference(AVATAR_TUNING, "Avatar animation JSON", getter, setter);
|
||||
preference->setPlaceholderText("default");
|
||||
preferences->addPreference(preference);
|
||||
|
|
|
@ -67,6 +67,18 @@ void GeometryMappingResource::downloadFinished(const QByteArray& data) {
|
|||
_textureBaseUrl = resolveTextureBaseUrl(url, _url.resolved(texdir));
|
||||
}
|
||||
|
||||
auto animGraphVariant = mapping.value("animGraphUrl");
|
||||
if (animGraphVariant.isValid()) {
|
||||
QUrl fstUrl(animGraphVariant.toString());
|
||||
if (fstUrl.isValid()) {
|
||||
_animGraphOverrideUrl = _url.resolved(fstUrl);
|
||||
} else {
|
||||
_animGraphOverrideUrl = QUrl();
|
||||
}
|
||||
} else {
|
||||
_animGraphOverrideUrl = QUrl();
|
||||
}
|
||||
|
||||
auto modelCache = DependencyManager::get<ModelCache>();
|
||||
GeometryExtra extra{ mapping, _textureBaseUrl };
|
||||
|
||||
|
@ -284,6 +296,8 @@ Geometry::Geometry(const Geometry& geometry) {
|
|||
for (const auto& material : geometry._materials) {
|
||||
_materials.push_back(std::make_shared<NetworkMaterial>(*material));
|
||||
}
|
||||
|
||||
_animGraphOverrideUrl = geometry._animGraphOverrideUrl;
|
||||
}
|
||||
|
||||
void Geometry::setTextures(const QVariantMap& textureMap) {
|
||||
|
|
|
@ -52,6 +52,7 @@ public:
|
|||
void setTextures(const QVariantMap& textureMap);
|
||||
|
||||
virtual bool areTexturesLoaded() const;
|
||||
const QUrl& getAnimGraphOverrideUrl() const { return _animGraphOverrideUrl; }
|
||||
|
||||
protected:
|
||||
friend class GeometryMappingResource;
|
||||
|
@ -64,6 +65,8 @@ protected:
|
|||
// Copied to each geometry, mutable throughout lifetime via setTextures
|
||||
NetworkMaterials _materials;
|
||||
|
||||
QUrl _animGraphOverrideUrl;
|
||||
|
||||
private:
|
||||
mutable bool _areTexturesLoaded { false };
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue