mirror of
https://github.com/overte-org/overte.git
synced 2025-04-14 23:49:05 +02:00
Merge pull request #14239 from ElderOrb/FB19219
FB19219 - Make avatarapp to handle wearables update via drag&drop
This commit is contained in:
commit
0425ae1231
8 changed files with 94 additions and 17 deletions
|
@ -3277,4 +3277,8 @@ void EntityItem::prepareForSimulationOwnershipBid(EntityItemProperties& properti
|
||||||
properties.setEntityHostType(getEntityHostType());
|
properties.setEntityHostType(getEntityHostType());
|
||||||
properties.setOwningAvatarID(getOwningAvatarID());
|
properties.setOwningAvatarID(getOwningAvatarID());
|
||||||
setLastBroadcast(now); // for debug/physics status icons
|
setLastBroadcast(now); // for debug/physics status icons
|
||||||
|
}
|
||||||
|
|
||||||
|
bool EntityItem::isWearable() const {
|
||||||
|
return isVisible() && (getParentID() == DependencyManager::get<NodeList>()->getSessionUUID() || getParentID() == AVATAR_SELF_ID);
|
||||||
}
|
}
|
|
@ -489,7 +489,7 @@ public:
|
||||||
void scriptHasUnloaded();
|
void scriptHasUnloaded();
|
||||||
void setScriptHasFinishedPreload(bool value);
|
void setScriptHasFinishedPreload(bool value);
|
||||||
bool isScriptPreloadFinished();
|
bool isScriptPreloadFinished();
|
||||||
|
virtual bool isWearable() const;
|
||||||
bool isDomainEntity() const { return _hostType == entity::HostType::DOMAIN; }
|
bool isDomainEntity() const { return _hostType == entity::HostType::DOMAIN; }
|
||||||
bool isAvatarEntity() const { return _hostType == entity::HostType::AVATAR; }
|
bool isAvatarEntity() const { return _hostType == entity::HostType::AVATAR; }
|
||||||
bool isLocalEntity() const { return _hostType == entity::HostType::LOCAL; }
|
bool isLocalEntity() const { return _hostType == entity::HostType::LOCAL; }
|
||||||
|
|
|
@ -114,6 +114,8 @@ bool EntityScriptingInterface::canReplaceContent() {
|
||||||
|
|
||||||
void EntityScriptingInterface::setEntityTree(EntityTreePointer elementTree) {
|
void EntityScriptingInterface::setEntityTree(EntityTreePointer elementTree) {
|
||||||
if (_entityTree) {
|
if (_entityTree) {
|
||||||
|
disconnect(_entityTree.get(), &EntityTree::addingEntityPointer, this, &EntityScriptingInterface::onAddingEntity);
|
||||||
|
disconnect(_entityTree.get(), &EntityTree::deletingEntityPointer, this, &EntityScriptingInterface::onDeletingEntity);
|
||||||
disconnect(_entityTree.get(), &EntityTree::addingEntity, this, &EntityScriptingInterface::addingEntity);
|
disconnect(_entityTree.get(), &EntityTree::addingEntity, this, &EntityScriptingInterface::addingEntity);
|
||||||
disconnect(_entityTree.get(), &EntityTree::deletingEntity, this, &EntityScriptingInterface::deletingEntity);
|
disconnect(_entityTree.get(), &EntityTree::deletingEntity, this, &EntityScriptingInterface::deletingEntity);
|
||||||
disconnect(_entityTree.get(), &EntityTree::clearingEntities, this, &EntityScriptingInterface::clearingEntities);
|
disconnect(_entityTree.get(), &EntityTree::clearingEntities, this, &EntityScriptingInterface::clearingEntities);
|
||||||
|
@ -122,6 +124,8 @@ void EntityScriptingInterface::setEntityTree(EntityTreePointer elementTree) {
|
||||||
_entityTree = elementTree;
|
_entityTree = elementTree;
|
||||||
|
|
||||||
if (_entityTree) {
|
if (_entityTree) {
|
||||||
|
connect(_entityTree.get(), &EntityTree::addingEntityPointer, this, &EntityScriptingInterface::onAddingEntity, Qt::DirectConnection);
|
||||||
|
connect(_entityTree.get(), &EntityTree::deletingEntityPointer, this, &EntityScriptingInterface::onDeletingEntity, Qt::DirectConnection);
|
||||||
connect(_entityTree.get(), &EntityTree::addingEntity, this, &EntityScriptingInterface::addingEntity);
|
connect(_entityTree.get(), &EntityTree::addingEntity, this, &EntityScriptingInterface::addingEntity);
|
||||||
connect(_entityTree.get(), &EntityTree::deletingEntity, this, &EntityScriptingInterface::deletingEntity);
|
connect(_entityTree.get(), &EntityTree::deletingEntity, this, &EntityScriptingInterface::deletingEntity);
|
||||||
connect(_entityTree.get(), &EntityTree::clearingEntities, this, &EntityScriptingInterface::clearingEntities);
|
connect(_entityTree.get(), &EntityTree::clearingEntities, this, &EntityScriptingInterface::clearingEntities);
|
||||||
|
@ -1060,7 +1064,17 @@ void EntityScriptingInterface::handleEntityScriptCallMethodPacket(QSharedPointer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void EntityScriptingInterface::onAddingEntity(EntityItem* entity) {
|
||||||
|
if (entity->isWearable()) {
|
||||||
|
emit addingWearable(entity->getEntityItemID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityScriptingInterface::onDeletingEntity(EntityItem* entity) {
|
||||||
|
if (entity->isWearable()) {
|
||||||
|
emit deletingWearable(entity->getEntityItemID());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QUuid EntityScriptingInterface::findClosestEntity(const glm::vec3& center, float radius) const {
|
QUuid EntityScriptingInterface::findClosestEntity(const glm::vec3& center, float radius) const {
|
||||||
PROFILE_RANGE(script_entities, __FUNCTION__);
|
PROFILE_RANGE(script_entities, __FUNCTION__);
|
||||||
|
|
|
@ -1908,6 +1908,31 @@ signals:
|
||||||
*/
|
*/
|
||||||
void addingEntity(const EntityItemID& entityID);
|
void addingEntity(const EntityItemID& entityID);
|
||||||
|
|
||||||
|
/**jsdoc
|
||||||
|
* Triggered when an 'wearable' entity is deleted.
|
||||||
|
* @function Entities.deletingWearable
|
||||||
|
* @param {Uuid} entityID - The ID of the 'wearable' entity deleted.
|
||||||
|
* @returns {Signal}
|
||||||
|
* @example <caption>Report when an 'wearable' entity is deleted.</caption>
|
||||||
|
* Entities.deletingWearable.connect(function (entityID) {
|
||||||
|
* print("Deleted wearable: " + entityID);
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
void deletingWearable(const EntityItemID& entityID);
|
||||||
|
|
||||||
|
/**jsdoc
|
||||||
|
* Triggered when an 'wearable' entity is added to Interface's local in-memory tree of entities it knows about. This may occur when
|
||||||
|
* 'wearable' entities are added to avatar
|
||||||
|
* @function Entities.addingWearable
|
||||||
|
* @param {Uuid} entityID - The ID of the 'wearable' entity added.
|
||||||
|
* @returns {Signal}
|
||||||
|
* @example <caption>Report when an 'wearable' entity is added.</caption>
|
||||||
|
* Entities.addingWearable.connect(function (entityID) {
|
||||||
|
* print("Added wearable: " + entityID);
|
||||||
|
* });
|
||||||
|
*/
|
||||||
|
void addingWearable(const EntityItemID& entityID);
|
||||||
|
|
||||||
/**jsdoc
|
/**jsdoc
|
||||||
* Triggered when you disconnect from a domain, at which time Interface's local in-memory tree of entities it knows about
|
* Triggered when you disconnect from a domain, at which time Interface's local in-memory tree of entities it knows about
|
||||||
* is cleared.
|
* is cleared.
|
||||||
|
@ -1938,6 +1963,8 @@ protected:
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void handleEntityScriptCallMethodPacket(QSharedPointer<ReceivedMessage> receivedMessage, SharedNodePointer senderNode);
|
void handleEntityScriptCallMethodPacket(QSharedPointer<ReceivedMessage> receivedMessage, SharedNodePointer senderNode);
|
||||||
|
void onAddingEntity(EntityItem* entity);
|
||||||
|
void onDeletingEntity(EntityItem* entity);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool actionWorker(const QUuid& entityID, std::function<bool(EntitySimulationPointer, EntityItemPointer)> actor);
|
bool actionWorker(const QUuid& entityID, std::function<bool(EntitySimulationPointer, EntityItemPointer)> actor);
|
||||||
|
|
|
@ -305,6 +305,7 @@ void EntityTree::postAddEntity(EntityItemPointer entity) {
|
||||||
fixupNeedsParentFixups();
|
fixupNeedsParentFixups();
|
||||||
|
|
||||||
emit addingEntity(entity->getEntityItemID());
|
emit addingEntity(entity->getEntityItemID());
|
||||||
|
emit addingEntityPointer(entity.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
bool EntityTree::updateEntity(const EntityItemID& entityID, const EntityItemProperties& properties, const SharedNodePointer& senderNode) {
|
bool EntityTree::updateEntity(const EntityItemID& entityID, const EntityItemProperties& properties, const SharedNodePointer& senderNode) {
|
||||||
|
|
|
@ -309,6 +309,7 @@ signals:
|
||||||
void deletingEntity(const EntityItemID& entityID);
|
void deletingEntity(const EntityItemID& entityID);
|
||||||
void deletingEntityPointer(EntityItem* entityID);
|
void deletingEntityPointer(EntityItem* entityID);
|
||||||
void addingEntity(const EntityItemID& entityID);
|
void addingEntity(const EntityItemID& entityID);
|
||||||
|
void addingEntityPointer(EntityItem* entityID);
|
||||||
void editingEntityPointer(const EntityItemPointer& entityID);
|
void editingEntityPointer(const EntityItemPointer& entityID);
|
||||||
void entityScriptChanging(const EntityItemID& entityItemID, const bool reload);
|
void entityScriptChanging(const EntityItemID& entityItemID, const bool reload);
|
||||||
void entityServerScriptChanging(const EntityItemID& entityItemID, const bool reload);
|
void entityServerScriptChanging(const EntityItemID& entityItemID, const bool reload);
|
||||||
|
|
|
@ -519,7 +519,6 @@ QVector<bool> ModelEntityItem::getJointTranslationsSet() const {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool ModelEntityItem::hasModel() const {
|
bool ModelEntityItem::hasModel() const {
|
||||||
return resultWithReadLock<bool>([&] {
|
return resultWithReadLock<bool>([&] {
|
||||||
return !_modelURL.isEmpty();
|
return !_modelURL.isEmpty();
|
||||||
|
|
|
@ -69,12 +69,12 @@ function getMyAvatarSettings() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function updateAvatarWearables(avatar, bookmarkAvatarName, callback) {
|
function updateAvatarWearables(avatar, callback) {
|
||||||
executeLater(function() {
|
executeLater(function() {
|
||||||
var wearables = getMyAvatarWearables();
|
var wearables = getMyAvatarWearables();
|
||||||
avatar[ENTRY_AVATAR_ENTITIES] = wearables;
|
avatar[ENTRY_AVATAR_ENTITIES] = wearables;
|
||||||
|
|
||||||
sendToQml({'method' : 'wearablesUpdated', 'wearables' : wearables, 'avatarName' : bookmarkAvatarName})
|
sendToQml({'method' : 'wearablesUpdated', 'wearables' : wearables})
|
||||||
|
|
||||||
if(callback)
|
if(callback)
|
||||||
callback();
|
callback();
|
||||||
|
@ -188,7 +188,11 @@ function fromQml(message) { // messages are {method, params}, like json-rpc. See
|
||||||
sendToQml(message)
|
sendToQml(message)
|
||||||
break;
|
break;
|
||||||
case 'selectAvatar':
|
case 'selectAvatar':
|
||||||
|
Entities.addingWearable.disconnect(onAddingWearable);
|
||||||
|
Entities.deletingWearable.disconnect(onDeletingWearable);
|
||||||
AvatarBookmarks.loadBookmark(message.name);
|
AvatarBookmarks.loadBookmark(message.name);
|
||||||
|
Entities.addingWearable.connect(onAddingWearable);
|
||||||
|
Entities.deletingWearable.connect(onDeletingWearable);
|
||||||
break;
|
break;
|
||||||
case 'deleteAvatar':
|
case 'deleteAvatar':
|
||||||
AvatarBookmarks.removeBookmark(message.name);
|
AvatarBookmarks.removeBookmark(message.name);
|
||||||
|
@ -223,7 +227,7 @@ function fromQml(message) { // messages are {method, params}, like json-rpc. See
|
||||||
// revert changes using snapshot of wearables
|
// revert changes using snapshot of wearables
|
||||||
if(currentAvatarWearablesBackup !== null) {
|
if(currentAvatarWearablesBackup !== null) {
|
||||||
AvatarBookmarks.updateAvatarEntities(currentAvatarWearablesBackup);
|
AvatarBookmarks.updateAvatarEntities(currentAvatarWearablesBackup);
|
||||||
updateAvatarWearables(currentAvatar, message.avatarName);
|
updateAvatarWearables(currentAvatar);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
sendToQml({'method' : 'updateAvatarInBookmarks'});
|
sendToQml({'method' : 'updateAvatarInBookmarks'});
|
||||||
|
@ -256,8 +260,11 @@ function fromQml(message) { // messages are {method, params}, like json-rpc. See
|
||||||
parentJointIndex: hipsIndex
|
parentJointIndex: hipsIndex
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Entities.addingWearable.disconnect(onAddingWearable);
|
||||||
var entityID = Entities.addEntity(properties, true);
|
var entityID = Entities.addEntity(properties, true);
|
||||||
updateAvatarWearables(currentAvatar, message.avatarName, function() {
|
Entities.addingWearable.connect(onAddingWearable);
|
||||||
|
|
||||||
|
updateAvatarWearables(currentAvatar, function() {
|
||||||
onSelectedEntity(entityID);
|
onSelectedEntity(entityID);
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
@ -265,8 +272,12 @@ function fromQml(message) { // messages are {method, params}, like json-rpc. See
|
||||||
ensureWearableSelected(message.entityID);
|
ensureWearableSelected(message.entityID);
|
||||||
break;
|
break;
|
||||||
case 'deleteWearable':
|
case 'deleteWearable':
|
||||||
|
|
||||||
|
Entities.deletingWearable.disconnect(onDeletingWearable);
|
||||||
Entities.deleteEntity(message.entityID);
|
Entities.deleteEntity(message.entityID);
|
||||||
updateAvatarWearables(currentAvatar, message.avatarName);
|
Entities.deletingWearable.connect(onDeletingWearable);
|
||||||
|
|
||||||
|
updateAvatarWearables(currentAvatar);
|
||||||
break;
|
break;
|
||||||
case 'changeDisplayName':
|
case 'changeDisplayName':
|
||||||
if (MyAvatar.displayName !== message.displayName) {
|
if (MyAvatar.displayName !== message.displayName) {
|
||||||
|
@ -380,6 +391,18 @@ function onSelectedEntity(entityID, pointerEvent) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function onAddingWearable(entityID) {
|
||||||
|
updateAvatarWearables(currentAvatar, function() {
|
||||||
|
sendToQml({'method' : 'updateAvatarInBookmarks'});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function onDeletingWearable(entityID) {
|
||||||
|
updateAvatarWearables(currentAvatar, function() {
|
||||||
|
sendToQml({'method' : 'updateAvatarInBookmarks'});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function handleWearableMessages(channel, message, sender) {
|
function handleWearableMessages(channel, message, sender) {
|
||||||
if (channel !== 'Hifi-Object-Manipulation') {
|
if (channel !== 'Hifi-Object-Manipulation') {
|
||||||
return;
|
return;
|
||||||
|
@ -485,6 +508,8 @@ function off() {
|
||||||
AvatarBookmarks.bookmarkDeleted.disconnect(onBookmarkDeleted);
|
AvatarBookmarks.bookmarkDeleted.disconnect(onBookmarkDeleted);
|
||||||
AvatarBookmarks.bookmarkAdded.disconnect(onBookmarkAdded);
|
AvatarBookmarks.bookmarkAdded.disconnect(onBookmarkAdded);
|
||||||
|
|
||||||
|
Entities.addingWearable.disconnect(onAddingWearable);
|
||||||
|
Entities.deletingWearable.disconnect(onDeletingWearable);
|
||||||
MyAvatar.skeletonModelURLChanged.disconnect(onSkeletonModelURLChanged);
|
MyAvatar.skeletonModelURLChanged.disconnect(onSkeletonModelURLChanged);
|
||||||
MyAvatar.dominantHandChanged.disconnect(onDominantHandChanged);
|
MyAvatar.dominantHandChanged.disconnect(onDominantHandChanged);
|
||||||
MyAvatar.collisionsEnabledChanged.disconnect(onCollisionsEnabledChanged);
|
MyAvatar.collisionsEnabledChanged.disconnect(onCollisionsEnabledChanged);
|
||||||
|
@ -495,16 +520,23 @@ function off() {
|
||||||
}
|
}
|
||||||
|
|
||||||
function on() {
|
function on() {
|
||||||
AvatarBookmarks.bookmarkLoaded.connect(onBookmarkLoaded);
|
|
||||||
AvatarBookmarks.bookmarkDeleted.connect(onBookmarkDeleted);
|
|
||||||
AvatarBookmarks.bookmarkAdded.connect(onBookmarkAdded);
|
|
||||||
|
|
||||||
MyAvatar.skeletonModelURLChanged.connect(onSkeletonModelURLChanged);
|
if (!isWired) { // It is not ok to connect these twice, hence guard.
|
||||||
MyAvatar.dominantHandChanged.connect(onDominantHandChanged);
|
isWired = true;
|
||||||
MyAvatar.collisionsEnabledChanged.connect(onCollisionsEnabledChanged);
|
|
||||||
MyAvatar.newCollisionSoundURL.connect(onNewCollisionSoundUrl);
|
AvatarBookmarks.bookmarkLoaded.connect(onBookmarkLoaded);
|
||||||
MyAvatar.animGraphUrlChanged.connect(onAnimGraphUrlChanged);
|
AvatarBookmarks.bookmarkDeleted.connect(onBookmarkDeleted);
|
||||||
MyAvatar.targetScaleChanged.connect(onTargetScaleChanged);
|
AvatarBookmarks.bookmarkAdded.connect(onBookmarkAdded);
|
||||||
|
|
||||||
|
Entities.addingWearable.connect(onAddingWearable);
|
||||||
|
Entities.deletingWearable.connect(onDeletingWearable);
|
||||||
|
MyAvatar.skeletonModelURLChanged.connect(onSkeletonModelURLChanged);
|
||||||
|
MyAvatar.dominantHandChanged.connect(onDominantHandChanged);
|
||||||
|
MyAvatar.collisionsEnabledChanged.connect(onCollisionsEnabledChanged);
|
||||||
|
MyAvatar.newCollisionSoundURL.connect(onNewCollisionSoundUrl);
|
||||||
|
MyAvatar.animGraphUrlChanged.connect(onAnimGraphUrlChanged);
|
||||||
|
MyAvatar.targetScaleChanged.connect(onTargetScaleChanged);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onTabletButtonClicked() {
|
function onTabletButtonClicked() {
|
||||||
|
@ -514,7 +546,6 @@ function onTabletButtonClicked() {
|
||||||
} else {
|
} else {
|
||||||
ContextOverlay.enabled = false;
|
ContextOverlay.enabled = false;
|
||||||
tablet.loadQMLSource(AVATARAPP_QML_SOURCE);
|
tablet.loadQMLSource(AVATARAPP_QML_SOURCE);
|
||||||
isWired = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var hasEventBridge = false;
|
var hasEventBridge = false;
|
||||||
|
|
Loading…
Reference in a new issue