mirror of
https://github.com/overte-org/community-apps.git
synced 2025-08-27 22:25:52 +02:00
273 lines
No EOL
8.1 KiB
JavaScript
273 lines
No EOL
8.1 KiB
JavaScript
'use strict';
|
|
|
|
//
|
|
// nyx.js
|
|
//
|
|
// Created by Kalila L. on Oct 6 2020.
|
|
// Copyright 2020 Vircadia contributors.
|
|
//
|
|
// Distributed under the Apache License, Version 2.0.
|
|
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
|
//
|
|
|
|
Script.include("/~/system/libraries/utils.js");
|
|
|
|
var SETTING_NYX_PREFIX = "nyx/";
|
|
|
|
// BEGIN ENTITY MENU OVERLAY
|
|
|
|
var enableEntityWebMenu = true;
|
|
var entityWebMenu;
|
|
var entityWebMenuActive = false;
|
|
var registeredEntityMenus = {};
|
|
var lastTriggeredEntityInfo = {};
|
|
var MENU_WEB_ENTITY_SCALE = {
|
|
x: 1,
|
|
y: 1.5,
|
|
z: 0.01
|
|
};
|
|
var MENU_WEB_ENTITY_ROTATION_UPDATE_INTERVAL = 500; // 500 ms
|
|
var BOOTSTRAP_MENU_WEB_ENTITY_SCALE = {
|
|
x: 0.01,
|
|
y: 0.01,
|
|
z: 0.01
|
|
};
|
|
var BOOTSTRAP_MENU_WEB_ENTITY_POSITION = Vec3.ZERO;
|
|
var BOOTSTRAP_MENU_WEB_ENTITY_SOURCE = Script.resolvePath("./index.html");
|
|
var BOOTSTRAP_MENU_WEB_ENTITY_DPI = 7;
|
|
var NYX_UI_CHANNEL = "nyx-ui";
|
|
|
|
function registerWithEntityMenu(messageData) {
|
|
registeredEntityMenus[messageData.entityID] = messageData.menuItems;
|
|
|
|
var dataToSend = {
|
|
registeredEntityMenus: registeredEntityMenus
|
|
};
|
|
|
|
sendToWeb(entityWebMenu, 'script-to-web-registered-entity-menus', dataToSend);
|
|
}
|
|
|
|
function deregisterWithEntityMenu(messageData) {
|
|
delete registeredEntityMenus[messageData.entityID];
|
|
|
|
var dataToSend = {
|
|
registeredEntityMenus: registeredEntityMenus
|
|
};
|
|
|
|
sendToWeb(entityWebMenu, 'script-to-web-registered-entity-menus', dataToSend);
|
|
}
|
|
|
|
function toggleEntityMenu(pressedEntityID) {
|
|
if (!entityWebMenuActive && enableEntityWebMenu === true) {
|
|
var triggeredEntityProperties = Entities.getEntityProperties(pressedEntityID);
|
|
var lastEditedByName;
|
|
|
|
if (AvatarManager.getPalData([triggeredEntityProperties.lastEditedBy]).data[0]) {
|
|
lastEditedByName = AvatarManager.getPalData([triggeredEntityProperties.lastEditedBy]).data[0].sessionDisplayName
|
|
} else {
|
|
lastEditedByName = triggeredEntityProperties.lastEditedBy;
|
|
}
|
|
|
|
lastTriggeredEntityInfo = {
|
|
id: pressedEntityID,
|
|
name: triggeredEntityProperties.name,
|
|
type: triggeredEntityProperties.type,
|
|
lastEditedBy: triggeredEntityProperties.lastEditedBy,
|
|
lastEditedByName: lastEditedByName,
|
|
entityHostType: triggeredEntityProperties.entityHostType,
|
|
description: triggeredEntityProperties.description,
|
|
position: triggeredEntityProperties.position,
|
|
rotation: triggeredEntityProperties.rotation
|
|
};
|
|
|
|
sendToWeb(entityWebMenu, 'script-to-web-triggered-entity-info', lastTriggeredEntityInfo);
|
|
|
|
Entities.editEntity(entityWebMenu, {
|
|
position: Entities.getEntityProperties(pressedEntityID, ['position']).position,
|
|
dimensions: MENU_WEB_ENTITY_SCALE,
|
|
rotation: Camera.orientation,
|
|
visible: true
|
|
});
|
|
|
|
entityWebMenuActive = true;
|
|
|
|
updateEntityMenuRotation();
|
|
} else if (entityWebMenuActive && pressedEntityID !== entityWebMenu) {
|
|
Entities.editEntity(entityWebMenu, {
|
|
position: BOOTSTRAP_MENU_WEB_ENTITY_POSITION,
|
|
dimensions: BOOTSTRAP_MENU_WEB_ENTITY_SCALE
|
|
});
|
|
|
|
entityWebMenuActive = false;
|
|
}
|
|
}
|
|
|
|
function updateEntityMenuRotation() {
|
|
if (entityWebMenuActive) {
|
|
Script.setTimeout(function() {
|
|
Entities.editEntity(entityWebMenu, {
|
|
rotation: Camera.orientation
|
|
});
|
|
|
|
updateEntityMenuRotation();
|
|
}, MENU_WEB_ENTITY_ROTATION_UPDATE_INTERVAL);
|
|
}
|
|
}
|
|
|
|
function bootstrapEntityMenu() {
|
|
entityWebMenu = Entities.addEntity({
|
|
type: "Web",
|
|
billboardMode: 'full',
|
|
renderLayer: 'hud',
|
|
visible: false,
|
|
grab: {
|
|
'grabbable': false
|
|
},
|
|
rotation: Camera.orientation,
|
|
maxFPS: 30,
|
|
sourceUrl: BOOTSTRAP_MENU_WEB_ENTITY_SOURCE,
|
|
position: BOOTSTRAP_MENU_WEB_ENTITY_POSITION,
|
|
dimensions: BOOTSTRAP_MENU_WEB_ENTITY_SCALE,
|
|
dpi: BOOTSTRAP_MENU_WEB_ENTITY_DPI
|
|
}, 'local');
|
|
}
|
|
|
|
// END ENTITY MENU OVERLAY
|
|
|
|
function sendToWeb(sendToEntity, command, data) {
|
|
var dataToSend = {
|
|
"command": command,
|
|
"data": data
|
|
};
|
|
|
|
Entities.emitScriptEvent(sendToEntity, JSON.stringify(dataToSend));
|
|
}
|
|
|
|
function onWebEventReceived(sendingEntityID, event) {
|
|
if (sendingEntityID === entityWebMenu) {
|
|
var eventJSON = JSON.parse(event);
|
|
|
|
if (eventJSON.command === "ready") {
|
|
var dataToSend = {
|
|
registeredEntityMenus: registeredEntityMenus,
|
|
lastTriggeredEntityInfo: lastTriggeredEntityInfo
|
|
};
|
|
|
|
sendToWeb(entityWebMenu, 'script-to-web-registered-entity-menus', dataToSend);
|
|
}
|
|
|
|
if (eventJSON.command === "menu-item-triggered") {
|
|
var dataToSend = {
|
|
entityID: eventJSON.data.triggeredEntityID,
|
|
menuItem: eventJSON.data.menuItem
|
|
};
|
|
|
|
Messages.sendLocalMessage(NYX_UI_CHANNEL, JSON.stringify(dataToSend));
|
|
|
|
if (entityWebMenuActive) {
|
|
toggleEntityMenu(); // Close the menu if a menu item was pressed.
|
|
}
|
|
}
|
|
|
|
if (eventJSON.command === "close-entity-menu") {
|
|
if (entityWebMenuActive) {
|
|
toggleEntityMenu(); // Close the menu if it is active.
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
function onMessageReceived(channel, message, senderID, localOnly) {
|
|
// print("NYX UI Message received:");
|
|
// print("- channel: " + channel);
|
|
// print("- message: " + message);
|
|
// print("- sender: " + senderID);
|
|
// print("- localOnly: " + localOnly);
|
|
|
|
if (channel === NYX_UI_CHANNEL && MyAvatar.sessionUUID === senderID) {
|
|
messageData = JSON.parse(message);
|
|
|
|
if (messageData.command === 'register-with-entity-menu') {
|
|
registerWithEntityMenu(messageData);
|
|
}
|
|
|
|
if (messageData.command === 'deregister-with-entity-menu') {
|
|
deregisterWithEntityMenu(messageData);
|
|
}
|
|
}
|
|
}
|
|
|
|
function onMousePressOnEntity (pressedEntityID, event) {
|
|
if (event.isPrimaryHeld && event.isSecondaryHeld && !isInEditMode()) {
|
|
toggleEntityMenu(pressedEntityID);
|
|
}
|
|
}
|
|
|
|
// Nyx Menu
|
|
|
|
var NYX_MAIN_MENU = "Settings > Nyx";
|
|
var NYX_ENTITY_MENU_ENABLED = "Enable Entity Menu";
|
|
|
|
function handleMenuEvent(menuItem) {
|
|
if (menuItem === NYX_ENTITY_MENU_ENABLED) {
|
|
enableEntityWebMenu = Menu.isOptionChecked(NYX_ENTITY_MENU_ENABLED);
|
|
}
|
|
}
|
|
|
|
function bootstrapNyxMenu() {
|
|
if (!Menu.menuExists(NYX_MAIN_MENU)) {
|
|
Menu.addMenu(NYX_MAIN_MENU);
|
|
Menu.addMenuItem({
|
|
menuName: NYX_MAIN_MENU,
|
|
menuItemName: NYX_ENTITY_MENU_ENABLED,
|
|
isCheckable: true,
|
|
isChecked: Settings.getValue(SETTING_NYX_PREFIX + NYX_ENTITY_MENU_ENABLED, true)
|
|
});
|
|
}
|
|
}
|
|
|
|
function unloadNyxMenu() {
|
|
Settings.setValue(SETTING_NYX_PREFIX + NYX_ENTITY_MENU_ENABLED, Menu.isOptionChecked(NYX_ENTITY_MENU_ENABLED));
|
|
|
|
Menu.removeMenuItem(NYX_MAIN_MENU, NYX_ENTITY_MENU_ENABLED);
|
|
Menu.removeMenu(NYX_MAIN_MENU);
|
|
}
|
|
|
|
// Nyx Menu
|
|
|
|
// BOOTSTRAPPING
|
|
|
|
function startup() {
|
|
Messages.messageReceived.connect(onMessageReceived);
|
|
Entities.mousePressOnEntity.connect(onMousePressOnEntity);
|
|
Entities.webEventReceived.connect(onWebEventReceived);
|
|
Menu.menuItemEvent.connect(handleMenuEvent);
|
|
|
|
bootstrapNyxMenu();
|
|
bootstrapEntityMenu();
|
|
}
|
|
|
|
startup();
|
|
|
|
Script.scriptEnding.connect(function () {
|
|
Messages.messageReceived.disconnect(onMessageReceived);
|
|
Entities.mousePressOnEntity.disconnect(onMousePressOnEntity);
|
|
Entities.webEventReceived.disconnect(onWebEventReceived);
|
|
Menu.menuItemEvent.disconnect(handleMenuEvent);
|
|
|
|
unloadNyxMenu();
|
|
|
|
Entities.deleteEntity(entityWebMenu);
|
|
entityWebMenu = null;
|
|
});
|
|
|
|
// BOOTSTRAPPING TESTING CODE
|
|
|
|
// var messageToSend = {
|
|
// 'command': 'register-with-entity-menu',
|
|
// 'entityID': '{768542d0-e962-49e3-94fb-85651d56f5ae}',
|
|
// 'menuItems': ['This', 'Is', 'Nice']
|
|
// };
|
|
//
|
|
// Messages.sendLocalMessage(NYX_UI_CHANNEL, JSON.stringify(messageToSend));
|