mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-05 21:22:07 +02:00
663 lines
23 KiB
JavaScript
663 lines
23 KiB
JavaScript
"use strict";
|
|
/*jslint vars:true, plusplus:true, forin:true*/
|
|
/*global Tablet, Script, Entities, MyAvatar, Camera, Quat, HMD, Account, UserActivityLogger, Messages, print,
|
|
AvatarBookmarks, ContextOverlay, AddressManager
|
|
*/
|
|
/* eslint indent: ["error", 4, { "outerIIFEBody": 0 }] */
|
|
//
|
|
// avatarapp.js
|
|
//
|
|
// Created by Alexander Ivash on April 30, 2018
|
|
// Copyright 2016 High Fidelity, Inc
|
|
//
|
|
// Distributed under the Apache License, Version 2.0
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
//
|
|
|
|
(function() { // BEGIN LOCAL_SCOPE
|
|
|
|
var AVATARAPP_QML_SOURCE = "hifi/AvatarApp.qml";
|
|
Script.include("/~/system/libraries/controllers.js");
|
|
|
|
// constants from AvatarBookmarks.h
|
|
var ENTRY_AVATAR_URL = "avatarUrl";
|
|
var ENTRY_AVATAR_ENTITIES = "avatarEntites";
|
|
var ENTRY_AVATAR_SCALE = "avatarScale";
|
|
|
|
function executeLater(callback) {
|
|
Script.setTimeout(callback, 300);
|
|
}
|
|
|
|
function isWearable(avatarEntity) {
|
|
return avatarEntity.properties.visible === true &&
|
|
(avatarEntity.properties.parentID === MyAvatar.sessionUUID || avatarEntity.properties.parentID === MyAvatar.SELF_ID);
|
|
}
|
|
|
|
function getMyAvatarWearables() {
|
|
var entitiesArray = MyAvatar.getAvatarEntitiesVariant();
|
|
var wearablesArray = [];
|
|
|
|
for (var i = 0; i < entitiesArray.length; ++i) {
|
|
var entity = entitiesArray[i];
|
|
if (!isWearable(entity)) {
|
|
continue;
|
|
}
|
|
|
|
var localRotation = entity.properties.localRotation;
|
|
entity.properties.localRotationAngles = Quat.safeEulerAngles(localRotation);
|
|
wearablesArray.push(entity);
|
|
}
|
|
|
|
return wearablesArray;
|
|
}
|
|
|
|
function getMyAvatar() {
|
|
var avatar = {};
|
|
avatar[ENTRY_AVATAR_URL] = MyAvatar.skeletonModelURL;
|
|
avatar[ENTRY_AVATAR_SCALE] = MyAvatar.getAvatarScale();
|
|
avatar[ENTRY_AVATAR_ENTITIES] = getMyAvatarWearables();
|
|
return avatar;
|
|
}
|
|
|
|
function getMyAvatarSettings() {
|
|
return {
|
|
dominantHand: MyAvatar.getDominantHand(),
|
|
hmdAvatarAlignmentType: MyAvatar.getHmdAvatarAlignmentType(),
|
|
collisionsEnabled: MyAvatar.getCollisionsEnabled(),
|
|
otherAvatarsCollisionsEnabled: MyAvatar.getOtherAvatarsCollisionsEnabled(),
|
|
collisionSoundUrl : MyAvatar.collisionSoundURL,
|
|
animGraphUrl: MyAvatar.getAnimGraphUrl(),
|
|
animGraphOverrideUrl : MyAvatar.getAnimGraphOverrideUrl(),
|
|
};
|
|
}
|
|
|
|
function updateAvatarWearables(avatar, callback, wearablesOverride) {
|
|
executeLater(function() {
|
|
var wearables = wearablesOverride ? wearablesOverride : getMyAvatarWearables();
|
|
avatar[ENTRY_AVATAR_ENTITIES] = wearables;
|
|
|
|
sendToQml({'method' : 'wearablesUpdated', 'wearables' : wearables});
|
|
sendToQml({ 'method' : 'wearablesFrozenChanged', 'wearablesFrozen' : getWearablesFrozen()});
|
|
|
|
if(callback)
|
|
callback();
|
|
});
|
|
}
|
|
|
|
var adjustWearables = {
|
|
opened : false,
|
|
cameraMode : '',
|
|
setOpened : function(value) {
|
|
if(this.opened !== value) {
|
|
if(value) {
|
|
this.cameraMode = Camera.mode;
|
|
|
|
if(!HMD.active) {
|
|
Camera.mode = 'mirror';
|
|
}
|
|
} else {
|
|
Camera.mode = this.cameraMode;
|
|
}
|
|
|
|
this.opened = value;
|
|
}
|
|
}
|
|
};
|
|
|
|
var currentAvatarWearablesBackup = null;
|
|
var currentAvatar = null;
|
|
var currentAvatarSettings = getMyAvatarSettings();
|
|
|
|
var notifyScaleChanged = true;
|
|
function onTargetScaleChanged() {
|
|
if(currentAvatar.scale !== MyAvatar.getAvatarScale()) {
|
|
currentAvatar.scale = MyAvatar.getAvatarScale();
|
|
if(notifyScaleChanged) {
|
|
sendToQml({'method' : 'scaleChanged', 'value' : currentAvatar.scale});
|
|
}
|
|
}
|
|
}
|
|
|
|
function onSkeletonModelURLChanged() {
|
|
if(currentAvatar || (currentAvatar.skeletonModelURL !== MyAvatar.skeletonModelURL)) {
|
|
fromQml({'method' : 'getAvatars'});
|
|
}
|
|
}
|
|
|
|
function onDominantHandChanged(dominantHand) {
|
|
if(currentAvatarSettings.dominantHand !== dominantHand) {
|
|
currentAvatarSettings.dominantHand = dominantHand;
|
|
sendToQml({'method' : 'settingChanged', 'name' : 'dominantHand', 'value' : dominantHand});
|
|
}
|
|
}
|
|
|
|
function onHmdAvatarAlignmentTypeChanged(type) {
|
|
if (currentAvatarSettings.hmdAvatarAlignmentType !== type) {
|
|
currentAvatarSettings.hmdAvatarAlignmentType = type;
|
|
sendToQml({'method' : 'settingChanged', 'name' : 'hmdAvatarAlignmentType', 'value' : type});
|
|
}
|
|
}
|
|
|
|
function onCollisionsEnabledChanged(enabled) {
|
|
if(currentAvatarSettings.collisionsEnabled !== enabled) {
|
|
currentAvatarSettings.collisionsEnabled = enabled;
|
|
sendToQml({'method' : 'settingChanged', 'name' : 'collisionsEnabled', 'value' : enabled});
|
|
}
|
|
}
|
|
|
|
function onOtherAvatarsCollisionsEnabledChanged(enabled) {
|
|
if (currentAvatarSettings.otherAvatarsCollisionsEnabled !== enabled) {
|
|
currentAvatarSettings.otherAvatarsCollisionsEnabled = enabled;
|
|
sendToQml({ 'method': 'settingChanged', 'name': 'otherAvatarsCollisionsEnabled', 'value': enabled });
|
|
}
|
|
}
|
|
|
|
function onNewCollisionSoundUrl(url) {
|
|
if(currentAvatarSettings.collisionSoundUrl !== url) {
|
|
currentAvatarSettings.collisionSoundUrl = url;
|
|
sendToQml({'method' : 'settingChanged', 'name' : 'collisionSoundUrl', 'value' : url});
|
|
}
|
|
}
|
|
|
|
function onAnimGraphUrlChanged(url) {
|
|
if (currentAvatarSettings.animGraphUrl !== url) {
|
|
currentAvatarSettings.animGraphUrl = url;
|
|
sendToQml({ 'method': 'settingChanged', 'name': 'animGraphUrl', 'value': currentAvatarSettings.animGraphUrl });
|
|
|
|
if (currentAvatarSettings.animGraphOverrideUrl !== MyAvatar.getAnimGraphOverrideUrl()) {
|
|
currentAvatarSettings.animGraphOverrideUrl = MyAvatar.getAnimGraphOverrideUrl();
|
|
sendToQml({ 'method': 'settingChanged', 'name': 'animGraphOverrideUrl',
|
|
'value': currentAvatarSettings.animGraphOverrideUrl });
|
|
}
|
|
}
|
|
}
|
|
|
|
var selectedAvatarEntityID = null;
|
|
var grabbedAvatarEntityChangeNotifier = null;
|
|
|
|
var MARKETPLACE_PURCHASES_QML_PATH = "hifi/commerce/wallet/Wallet.qml";
|
|
var MARKETPLACE_URL = Account.metaverseServerURL + "/marketplace";
|
|
var MARKETPLACES_INJECT_SCRIPT_URL = Script.resolvePath("html/js/marketplacesInject.js");
|
|
|
|
function getWearablesFrozen() {
|
|
var wearablesFrozen = true;
|
|
var wearablesArray = getMyAvatarWearables();
|
|
wearablesArray.forEach(function(wearable) {
|
|
if (isGrabbable(wearable.id)) {
|
|
wearablesFrozen = false;
|
|
}
|
|
});
|
|
|
|
return wearablesFrozen;
|
|
}
|
|
|
|
function freezeWearables() {
|
|
var wearablesArray = getMyAvatarWearables();
|
|
wearablesArray.forEach(function(wearable) {
|
|
setGrabbable(wearable.id, false);
|
|
});
|
|
}
|
|
|
|
function unfreezeWearables() {
|
|
var wearablesArray = getMyAvatarWearables();
|
|
wearablesArray.forEach(function(wearable) {
|
|
setGrabbable(wearable.id, true);
|
|
});
|
|
}
|
|
|
|
|
|
function fromQml(message) { // messages are {method, params}, like json-rpc. See also sendToQml.
|
|
switch (message.method) {
|
|
case 'getAvatars':
|
|
currentAvatar = getMyAvatar();
|
|
currentAvatarSettings = getMyAvatarSettings();
|
|
|
|
message.data = {
|
|
'bookmarks' : AvatarBookmarks.getBookmarks(),
|
|
'displayName' : MyAvatar.displayName,
|
|
'currentAvatar' : currentAvatar,
|
|
'currentAvatarSettings' : currentAvatarSettings
|
|
};
|
|
|
|
for(var bookmarkName in message.data.bookmarks) {
|
|
var bookmark = message.data.bookmarks[bookmarkName];
|
|
|
|
if (bookmark.avatarEntites) {
|
|
bookmark.avatarEntites.forEach(function(avatarEntity) {
|
|
avatarEntity.properties.localRotationAngles = Quat.safeEulerAngles(avatarEntity.properties.localRotation);
|
|
});
|
|
}
|
|
}
|
|
|
|
sendToQml(message);
|
|
break;
|
|
case 'selectAvatar':
|
|
Entities.addingWearable.disconnect(onAddingWearable);
|
|
Entities.deletingWearable.disconnect(onDeletingWearable);
|
|
AvatarBookmarks.loadBookmark(message.name);
|
|
Entities.addingWearable.connect(onAddingWearable);
|
|
Entities.deletingWearable.connect(onDeletingWearable);
|
|
sendToQml({ 'method' : 'wearablesFrozenChanged', 'wearablesFrozen' : getWearablesFrozen()});
|
|
break;
|
|
case 'deleteAvatar':
|
|
AvatarBookmarks.removeBookmark(message.name);
|
|
break;
|
|
case 'addAvatar':
|
|
AvatarBookmarks.addBookmark(message.name);
|
|
break;
|
|
case 'adjustWearable':
|
|
if(message.properties.localRotationAngles) {
|
|
message.properties.localRotation = Quat.fromVec3Degrees(message.properties.localRotationAngles);
|
|
}
|
|
|
|
Entities.editEntity(message.entityID, message.properties);
|
|
message.properties = Entities.getEntityProperties(message.entityID, Object.keys(message.properties));
|
|
|
|
if(message.properties.localRotation) {
|
|
message.properties.localRotationAngles = Quat.safeEulerAngles(message.properties.localRotation);
|
|
}
|
|
|
|
sendToQml({'method' : 'wearableUpdated', 'entityID' : message.entityID, wearableIndex : message.wearableIndex, properties : message.properties, updateUI : false});
|
|
break;
|
|
case 'adjustWearablesOpened':
|
|
currentAvatarWearablesBackup = getMyAvatarWearables();
|
|
adjustWearables.setOpened(true);
|
|
unfreezeWearables();
|
|
|
|
Entities.mousePressOnEntity.connect(onSelectedEntity);
|
|
Messages.subscribe('Hifi-Object-Manipulation');
|
|
Messages.messageReceived.connect(handleWearableMessages);
|
|
break;
|
|
case 'adjustWearablesClosed':
|
|
if(!message.save) {
|
|
// revert changes using snapshot of wearables
|
|
if(currentAvatarWearablesBackup !== null) {
|
|
AvatarBookmarks.updateAvatarEntities(currentAvatarWearablesBackup);
|
|
updateAvatarWearables(currentAvatar, null, currentAvatarWearablesBackup);
|
|
}
|
|
} else {
|
|
sendToQml({'method' : 'updateAvatarInBookmarks'});
|
|
}
|
|
|
|
adjustWearables.setOpened(false);
|
|
ensureWearableSelected(null);
|
|
Entities.mousePressOnEntity.disconnect(onSelectedEntity);
|
|
Messages.messageReceived.disconnect(handleWearableMessages);
|
|
Messages.unsubscribe('Hifi-Object-Manipulation');
|
|
break;
|
|
case 'addWearable':
|
|
|
|
var joints = MyAvatar.getJointNames();
|
|
var hipsIndex = -1;
|
|
|
|
for(var i = 0; i < joints.length; ++i) {
|
|
if(joints[i] === 'Hips') {
|
|
hipsIndex = i;
|
|
break;
|
|
}
|
|
}
|
|
|
|
var properties = {
|
|
name: "Custom wearable",
|
|
type: "Model",
|
|
modelURL: message.url,
|
|
parentID: MyAvatar.sessionUUID,
|
|
relayParentJoints: false,
|
|
parentJointIndex: hipsIndex
|
|
};
|
|
|
|
Entities.addingWearable.disconnect(onAddingWearable);
|
|
var entityID = Entities.addEntity(properties, true);
|
|
Entities.addingWearable.connect(onAddingWearable);
|
|
|
|
updateAvatarWearables(currentAvatar, function() {
|
|
onSelectedEntity(entityID);
|
|
});
|
|
break;
|
|
case 'selectWearable':
|
|
ensureWearableSelected(message.entityID);
|
|
break;
|
|
case 'deleteWearable':
|
|
|
|
Entities.deletingWearable.disconnect(onDeletingWearable);
|
|
Entities.deleteEntity(message.entityID);
|
|
Entities.deletingWearable.connect(onDeletingWearable);
|
|
|
|
updateAvatarWearables(currentAvatar);
|
|
break;
|
|
case 'changeDisplayName':
|
|
if (MyAvatar.displayName !== message.displayName) {
|
|
MyAvatar.displayName = message.displayName;
|
|
UserActivityLogger.palAction("display_name_change", message.displayName);
|
|
}
|
|
break;
|
|
case 'applyExternalAvatar':
|
|
var currentAvatarURL = MyAvatar.getFullAvatarURLFromPreferences();
|
|
if(currentAvatarURL !== message.avatarURL) {
|
|
MyAvatar.useFullAvatarURL(message.avatarURL);
|
|
sendToQml({'method' : 'externalAvatarApplied', 'avatarURL' : message.avatarURL});
|
|
}
|
|
break;
|
|
case 'navigate':
|
|
var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
|
if(message.url.indexOf('app://') === 0) {
|
|
if (message.url === 'app://marketplace') {
|
|
tablet.gotoWebScreen(MARKETPLACE_URL, MARKETPLACES_INJECT_SCRIPT_URL);
|
|
} else if (message.url === 'app://purchases') {
|
|
tablet.pushOntoStack(MARKETPLACE_PURCHASES_QML_PATH);
|
|
}
|
|
|
|
} else if(message.url.indexOf('hifi://') === 0) {
|
|
AddressManager.handleLookupString(message.url, false);
|
|
} else if(message.url.indexOf('https://') === 0 || message.url.indexOf('http://') === 0) {
|
|
tablet.gotoWebScreen(message.url, MARKETPLACES_INJECT_SCRIPT_URL);
|
|
}
|
|
|
|
break;
|
|
case 'setScale':
|
|
notifyScaleChanged = false;
|
|
MyAvatar.setAvatarScale(message.avatarScale);
|
|
currentAvatar.avatarScale = message.avatarScale;
|
|
notifyScaleChanged = true;
|
|
break;
|
|
case 'revertScale':
|
|
MyAvatar.setAvatarScale(message.avatarScale);
|
|
currentAvatar.avatarScale = message.avatarScale;
|
|
break;
|
|
case 'saveSettings':
|
|
MyAvatar.setAvatarScale(message.avatarScale);
|
|
currentAvatar.avatarScale = message.avatarScale;
|
|
|
|
MyAvatar.setDominantHand(message.settings.dominantHand);
|
|
MyAvatar.setHmdAvatarAlignmentType(message.settings.hmdAvatarAlignmentType);
|
|
MyAvatar.setOtherAvatarsCollisionsEnabled(message.settings.otherAvatarsCollisionsEnabled);
|
|
MyAvatar.setCollisionsEnabled(message.settings.collisionsEnabled);
|
|
MyAvatar.collisionSoundURL = message.settings.collisionSoundUrl;
|
|
MyAvatar.setAnimGraphOverrideUrl(message.settings.animGraphOverrideUrl);
|
|
|
|
currentAvatarSettings = getMyAvatarSettings();
|
|
break;
|
|
case 'toggleWearablesFrozen':
|
|
var wearablesFrozen = getWearablesFrozen();
|
|
wearablesFrozen = !wearablesFrozen;
|
|
if (wearablesFrozen) {
|
|
freezeWearables();
|
|
} else {
|
|
unfreezeWearables();
|
|
}
|
|
sendToQml({'method' : 'wearablesFrozenChanged', 'wearablesFrozen' : wearablesFrozen});
|
|
break;
|
|
default:
|
|
print('Unrecognized message from AvatarApp.qml');
|
|
}
|
|
}
|
|
|
|
function isGrabbable(entityID) {
|
|
if(entityID === null) {
|
|
return false;
|
|
}
|
|
|
|
var properties = Entities.getEntityProperties(entityID, ['avatarEntity', 'grab.grabbable']);
|
|
if (properties.avatarEntity) {
|
|
return properties.grab.grabbable;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
function setGrabbable(entityID, grabbable) {
|
|
var properties = Entities.getEntityProperties(entityID, ['avatarEntity', 'grab.grabbable']);
|
|
if (properties.avatarEntity && properties.grab.grabbable != grabbable) {
|
|
var editProps = { grab: { grabbable: grabbable }};
|
|
Entities.editEntity(entityID, editProps);
|
|
sendToQml({ 'method' : 'wearablesFrozenChanged', 'wearablesFrozen' : getWearablesFrozen()});
|
|
}
|
|
}
|
|
|
|
function ensureWearableSelected(entityID) {
|
|
if(selectedAvatarEntityID !== entityID) {
|
|
if(grabbedAvatarEntityChangeNotifier !== null) {
|
|
Script.clearInterval(grabbedAvatarEntityChangeNotifier);
|
|
grabbedAvatarEntityChangeNotifier = null;
|
|
}
|
|
selectedAvatarEntityID = entityID;
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
function isEntityBeingWorn(entityID) {
|
|
return Entities.getEntityProperties(entityID, 'parentID').parentID === MyAvatar.sessionUUID;
|
|
}
|
|
|
|
function onSelectedEntity(entityID, pointerEvent) {
|
|
if(selectedAvatarEntityID !== entityID && isEntityBeingWorn(entityID))
|
|
{
|
|
if(ensureWearableSelected(entityID)) {
|
|
sendToQml({'method' : 'selectAvatarEntity', 'entityID' : selectedAvatarEntityID});
|
|
}
|
|
}
|
|
}
|
|
|
|
function onAddingWearable(entityID) {
|
|
updateAvatarWearables(currentAvatar, function() {
|
|
sendToQml({'method' : 'updateAvatarInBookmarks'});
|
|
});
|
|
sendToQml({ 'method' : 'wearablesFrozenChanged', 'wearablesFrozen' : getWearablesFrozen()});
|
|
}
|
|
|
|
function onDeletingWearable(entityID) {
|
|
updateAvatarWearables(currentAvatar, function() {
|
|
sendToQml({'method' : 'updateAvatarInBookmarks'});
|
|
});
|
|
sendToQml({ 'method' : 'wearablesFrozenChanged', 'wearablesFrozen' : getWearablesFrozen()});
|
|
}
|
|
|
|
function handleWearableMessages(channel, message, sender) {
|
|
if (channel !== 'Hifi-Object-Manipulation') {
|
|
return;
|
|
}
|
|
|
|
var parsedMessage = null;
|
|
|
|
try {
|
|
parsedMessage = JSON.parse(message);
|
|
} catch (e) {
|
|
return;
|
|
}
|
|
|
|
var entityID = parsedMessage.grabbedEntity;
|
|
|
|
var updateWearable = function() {
|
|
// for some reasons Entities.getEntityProperties returns more than was asked..
|
|
var propertyNames = ['localPosition', 'localRotation', 'dimensions', 'naturalDimensions'];
|
|
var entityProperties = Entities.getEntityProperties(selectedAvatarEntityID, propertyNames);
|
|
var properties = {};
|
|
|
|
propertyNames.forEach(function(propertyName) {
|
|
properties[propertyName] = entityProperties[propertyName];
|
|
});
|
|
|
|
properties.localRotationAngles = Quat.safeEulerAngles(properties.localRotation);
|
|
sendToQml({'method' : 'wearableUpdated', 'entityID' : selectedAvatarEntityID,
|
|
'wearableIndex' : -1, 'properties' : properties, updateUI : true});
|
|
|
|
};
|
|
|
|
if(parsedMessage.action === 'grab') {
|
|
if(selectedAvatarEntityID !== entityID) {
|
|
ensureWearableSelected(entityID);
|
|
sendToQml({'method' : 'selectAvatarEntity', 'entityID' : selectedAvatarEntityID});
|
|
}
|
|
|
|
grabbedAvatarEntityChangeNotifier = Script.setInterval(updateWearable, 1000);
|
|
} else if(parsedMessage.action === 'release') {
|
|
if(grabbedAvatarEntityChangeNotifier !== null) {
|
|
Script.clearInterval(grabbedAvatarEntityChangeNotifier);
|
|
grabbedAvatarEntityChangeNotifier = null;
|
|
updateWearable();
|
|
}
|
|
}
|
|
}
|
|
|
|
function sendToQml(message) {
|
|
tablet.sendToQml(message);
|
|
}
|
|
|
|
function onBookmarkLoaded(bookmarkName) {
|
|
executeLater(function() {
|
|
currentAvatar = getMyAvatar();
|
|
sendToQml({'method' : 'bookmarkLoaded', 'data' : {'name' : bookmarkName, 'currentAvatar' : currentAvatar} });
|
|
});
|
|
}
|
|
|
|
function onBookmarkDeleted(bookmarkName) {
|
|
sendToQml({'method' : 'bookmarkDeleted', 'name' : bookmarkName});
|
|
}
|
|
|
|
function onBookmarkAdded(bookmarkName) {
|
|
var bookmark = AvatarBookmarks.getBookmark(bookmarkName);
|
|
bookmark.avatarEntites.forEach(function(avatarEntity) {
|
|
avatarEntity.properties.localRotationAngles = Quat.safeEulerAngles(avatarEntity.properties.localRotation);
|
|
});
|
|
|
|
sendToQml({ 'method': 'bookmarkAdded', 'bookmarkName': bookmarkName, 'bookmark': bookmark });
|
|
}
|
|
|
|
//
|
|
// Manage the connection between the button and the window.
|
|
//
|
|
var button;
|
|
var buttonName = "AVATAR";
|
|
var tablet = null;
|
|
|
|
function startup() {
|
|
tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
|
|
button = tablet.addButton({
|
|
text: buttonName,
|
|
icon: "icons/tablet-icons/avatar-i.svg",
|
|
activeIcon: "icons/tablet-icons/avatar-a.svg",
|
|
sortOrder: 7
|
|
});
|
|
button.clicked.connect(onTabletButtonClicked);
|
|
tablet.screenChanged.connect(onTabletScreenChanged);
|
|
}
|
|
|
|
startup();
|
|
|
|
var isWired = false;
|
|
function off() {
|
|
if(adjustWearables.opened) {
|
|
adjustWearables.setOpened(false);
|
|
ensureWearableSelected(null);
|
|
Entities.mousePressOnEntity.disconnect(onSelectedEntity);
|
|
|
|
Messages.messageReceived.disconnect(handleWearableMessages);
|
|
Messages.unsubscribe('Hifi-Object-Manipulation');
|
|
}
|
|
|
|
if (isWired) { // It is not ok to disconnect these twice, hence guard.
|
|
isWired = false;
|
|
|
|
AvatarBookmarks.bookmarkLoaded.disconnect(onBookmarkLoaded);
|
|
AvatarBookmarks.bookmarkDeleted.disconnect(onBookmarkDeleted);
|
|
AvatarBookmarks.bookmarkAdded.disconnect(onBookmarkAdded);
|
|
|
|
Entities.addingWearable.disconnect(onAddingWearable);
|
|
Entities.deletingWearable.disconnect(onDeletingWearable);
|
|
MyAvatar.skeletonModelURLChanged.disconnect(onSkeletonModelURLChanged);
|
|
MyAvatar.dominantHandChanged.disconnect(onDominantHandChanged);
|
|
MyAvatar.hmdAvatarAlignmentTypeChanged.disconnect(onHmdAvatarAlignmentTypeChanged);
|
|
MyAvatar.collisionsEnabledChanged.disconnect(onCollisionsEnabledChanged);
|
|
MyAvatar.otherAvatarsCollisionsEnabledChanged.disconnect(onOtherAvatarsCollisionsEnabledChanged);
|
|
MyAvatar.newCollisionSoundURL.disconnect(onNewCollisionSoundUrl);
|
|
MyAvatar.animGraphUrlChanged.disconnect(onAnimGraphUrlChanged);
|
|
MyAvatar.targetScaleChanged.disconnect(onTargetScaleChanged);
|
|
}
|
|
}
|
|
|
|
function on() {
|
|
|
|
if (!isWired) { // It is not ok to connect these twice, hence guard.
|
|
isWired = true;
|
|
|
|
AvatarBookmarks.bookmarkLoaded.connect(onBookmarkLoaded);
|
|
AvatarBookmarks.bookmarkDeleted.connect(onBookmarkDeleted);
|
|
AvatarBookmarks.bookmarkAdded.connect(onBookmarkAdded);
|
|
|
|
Entities.addingWearable.connect(onAddingWearable);
|
|
Entities.deletingWearable.connect(onDeletingWearable);
|
|
MyAvatar.skeletonModelURLChanged.connect(onSkeletonModelURLChanged);
|
|
MyAvatar.dominantHandChanged.connect(onDominantHandChanged);
|
|
MyAvatar.hmdAvatarAlignmentTypeChanged.connect(onHmdAvatarAlignmentTypeChanged);
|
|
MyAvatar.collisionsEnabledChanged.connect(onCollisionsEnabledChanged);
|
|
MyAvatar.otherAvatarsCollisionsEnabledChanged.connect(onOtherAvatarsCollisionsEnabledChanged);
|
|
MyAvatar.newCollisionSoundURL.connect(onNewCollisionSoundUrl);
|
|
MyAvatar.animGraphUrlChanged.connect(onAnimGraphUrlChanged);
|
|
MyAvatar.targetScaleChanged.connect(onTargetScaleChanged);
|
|
}
|
|
}
|
|
|
|
function onTabletButtonClicked() {
|
|
if (onAvatarAppScreen) {
|
|
// for toolbar-mode: go back to home screen, this will close the window.
|
|
tablet.gotoHomeScreen();
|
|
} else {
|
|
ContextOverlay.enabled = false;
|
|
tablet.loadQMLSource(AVATARAPP_QML_SOURCE);
|
|
}
|
|
}
|
|
var hasEventBridge = false;
|
|
function wireEventBridge(on) {
|
|
if (on) {
|
|
if (!hasEventBridge) {
|
|
tablet.fromQml.connect(fromQml);
|
|
hasEventBridge = true;
|
|
}
|
|
} else {
|
|
if (hasEventBridge) {
|
|
tablet.fromQml.disconnect(fromQml);
|
|
hasEventBridge = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
var onAvatarAppScreen = false;
|
|
function onTabletScreenChanged(type, url) {
|
|
var onAvatarAppScreenNow = (type === "QML" && url === AVATARAPP_QML_SOURCE);
|
|
wireEventBridge(onAvatarAppScreenNow);
|
|
// for toolbar mode: change button to active when window is first openend, false otherwise.
|
|
button.editProperties({isActive: onAvatarAppScreenNow});
|
|
|
|
if (!onAvatarAppScreen && onAvatarAppScreenNow) {
|
|
on();
|
|
} else if(onAvatarAppScreen && !onAvatarAppScreenNow) {
|
|
off();
|
|
}
|
|
|
|
onAvatarAppScreen = onAvatarAppScreenNow;
|
|
|
|
if(onAvatarAppScreenNow) {
|
|
sendToQml({ 'method' : 'initialize', 'data' : { jointNames : MyAvatar.getJointNames() }});
|
|
sendToQml({ 'method' : 'wearablesFrozenChanged', 'wearablesFrozen' : getWearablesFrozen()});
|
|
}
|
|
}
|
|
|
|
function shutdown() {
|
|
if (onAvatarAppScreen) {
|
|
tablet.gotoHomeScreen();
|
|
}
|
|
button.clicked.disconnect(onTabletButtonClicked);
|
|
tablet.removeButton(button);
|
|
tablet.screenChanged.disconnect(onTabletScreenChanged);
|
|
|
|
off();
|
|
}
|
|
|
|
//
|
|
// Cleanup.
|
|
//
|
|
Script.scriptEnding.connect(shutdown);
|
|
|
|
}()); // END LOCAL_SCOPE
|