diff --git a/scripts/simplifiedUI/system/assets/images/icon-particles.svg b/scripts/simplifiedUI/system/assets/images/icon-particles.svg
deleted file mode 100644
index 5e0105d7cd..0000000000
--- a/scripts/simplifiedUI/system/assets/images/icon-particles.svg
+++ /dev/null
@@ -1,29 +0,0 @@
-
-
-
diff --git a/scripts/simplifiedUI/system/assets/images/icon-point-light.svg b/scripts/simplifiedUI/system/assets/images/icon-point-light.svg
deleted file mode 100644
index 896c35b63b..0000000000
--- a/scripts/simplifiedUI/system/assets/images/icon-point-light.svg
+++ /dev/null
@@ -1,57 +0,0 @@
-
-
-
-
diff --git a/scripts/simplifiedUI/system/assets/images/icon-spot-light.svg b/scripts/simplifiedUI/system/assets/images/icon-spot-light.svg
deleted file mode 100644
index ac2f87bb27..0000000000
--- a/scripts/simplifiedUI/system/assets/images/icon-spot-light.svg
+++ /dev/null
@@ -1,37 +0,0 @@
-
-
-
-
diff --git a/scripts/simplifiedUI/system/assets/images/icon-zone.svg b/scripts/simplifiedUI/system/assets/images/icon-zone.svg
deleted file mode 100644
index 41aeac4951..0000000000
--- a/scripts/simplifiedUI/system/assets/images/icon-zone.svg
+++ /dev/null
@@ -1,73 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/scripts/simplifiedUI/system/edit.js b/scripts/simplifiedUI/system/edit.js
deleted file mode 100644
index cf99f3a618..0000000000
--- a/scripts/simplifiedUI/system/edit.js
+++ /dev/null
@@ -1,2858 +0,0 @@
-// edit.js
-//
-// Created by Brad Hefta-Gaub on 10/2/14.
-// Persist toolbar by HRS 6/11/15.
-// Copyright 2014 High Fidelity, Inc.
-//
-// This script allows you to edit entities with a new UI/UX for mouse and trackpad based editing
-//
-// Distributed under the Apache License, Version 2.0.
-// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
-//
-
-/* global Script, SelectionDisplay, LightOverlayManager, CameraManager, Grid, GridTool, EntityListTool, Vec3, SelectionManager,
- Overlays, OverlayWebWindow, UserActivityLogger, Settings, Entities, Tablet, Toolbars, Messages, Menu, Camera,
- progressDialog, tooltip, MyAvatar, Quat, Controller, Clipboard, HMD, UndoStack, OverlaySystemWindow,
- keyUpEventFromUIWindow:true */
-
-(function() { // BEGIN LOCAL_SCOPE
-
-"use strict";
-
-var EDIT_TOGGLE_BUTTON = "com.highfidelity.interface.system.editButton";
-
-var CONTROLLER_MAPPING_NAME = "com.highfidelity.editMode";
-
-Script.include([
- "libraries/stringHelpers.js",
- "libraries/dataViewHelpers.js",
- "libraries/progressDialog.js",
- "libraries/entitySelectionTool.js",
- "libraries/ToolTip.js",
- "libraries/entityCameraTool.js",
- "libraries/gridTool.js",
- "libraries/entityList.js",
- "libraries/utils.js",
- "libraries/entityIconOverlayManager.js"
-]);
-
-var CreateWindow = Script.require('./modules/createWindow.js');
-
-var TITLE_OFFSET = 60;
-var CREATE_TOOLS_WIDTH = 490;
-var MAX_DEFAULT_ENTITY_LIST_HEIGHT = 942;
-
-var DEFAULT_IMAGE = "https://hifi-content.s3.amazonaws.com/DomainContent/production/no-image.jpg";
-
-var createToolsWindow = new CreateWindow(
- Script.resolvePath("create/EditTools.qml"),
- 'Create Tools',
- 'com.highfidelity.create.createToolsWindow',
- function () {
- var windowHeight = Window.innerHeight - TITLE_OFFSET;
- if (windowHeight > MAX_DEFAULT_ENTITY_LIST_HEIGHT) {
- windowHeight = MAX_DEFAULT_ENTITY_LIST_HEIGHT;
- }
- return {
- size: {
- x: CREATE_TOOLS_WIDTH,
- y: windowHeight
- },
- position: {
- x: Window.x + Window.innerWidth - CREATE_TOOLS_WIDTH,
- y: Window.y + TITLE_OFFSET
- }
- }
- },
- false
-);
-
-/**
- * @description Returns true in case we should use the tablet version of the CreateApp
- * @returns boolean
- */
-var shouldUseEditTabletApp = function() {
- return HMD.active || (!HMD.active && !Settings.getValue("desktopTabletBecomesToolbar", true));
-};
-
-
-var selectionDisplay = SelectionDisplay;
-var selectionManager = SelectionManager;
-
-var PARTICLE_SYSTEM_URL = Script.resolvePath("assets/images/icon-particles.svg");
-var POINT_LIGHT_URL = Script.resolvePath("assets/images/icon-point-light.svg");
-var SPOT_LIGHT_URL = Script.resolvePath("assets/images/icon-spot-light.svg");
-var ZONE_URL = Script.resolvePath("assets/images/icon-zone.svg");
-
-var entityIconOverlayManager = new EntityIconOverlayManager(['Light', 'ParticleEffect', 'Zone'], function(entityID) {
- var properties = Entities.getEntityProperties(entityID, ['type', 'isSpotlight']);
- if (properties.type === 'Light') {
- return {
- url: properties.isSpotlight ? SPOT_LIGHT_URL : POINT_LIGHT_URL,
- };
- } else if (properties.type === 'Zone') {
- return {
- url: ZONE_URL,
- };
- } else {
- return {
- url: PARTICLE_SYSTEM_URL,
- };
- }
-});
-
-var cameraManager = new CameraManager();
-
-var grid = new Grid();
-var gridTool = new GridTool({
- horizontalGrid: grid,
- createToolsWindow: createToolsWindow,
- shouldUseEditTabletApp: shouldUseEditTabletApp
-});
-gridTool.setVisible(false);
-
-var EntityShapeVisualizer = Script.require('./modules/entityShapeVisualizer.js');
-var entityShapeVisualizer = new EntityShapeVisualizer(["Zone"]);
-
-var entityListTool = new EntityListTool(shouldUseEditTabletApp);
-
-selectionManager.addEventListener(function () {
- selectionDisplay.updateHandles();
- entityIconOverlayManager.updatePositions();
- entityShapeVisualizer.setEntities(selectionManager.selections);
-});
-
-var DEGREES_TO_RADIANS = Math.PI / 180.0;
-var RADIANS_TO_DEGREES = 180.0 / Math.PI;
-
-var MIN_ANGULAR_SIZE = 2;
-var MAX_ANGULAR_SIZE = 45;
-var allowLargeModels = true;
-var allowSmallModels = true;
-
-var DEFAULT_DIMENSION = 0.20;
-
-var DEFAULT_DIMENSIONS = {
- x: DEFAULT_DIMENSION,
- y: DEFAULT_DIMENSION,
- z: DEFAULT_DIMENSION
-};
-
-var DEFAULT_LIGHT_DIMENSIONS = Vec3.multiply(20, DEFAULT_DIMENSIONS);
-
-var MENU_AUTO_FOCUS_ON_SELECT = "Auto Focus on Select";
-var MENU_EASE_ON_FOCUS = "Ease Orientation on Focus";
-var MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE = "Show Lights and Particle Systems in Create Mode";
-var MENU_SHOW_ZONES_IN_EDIT_MODE = "Show Zones in Create Mode";
-
-var MENU_CREATE_ENTITIES_GRABBABLE = "Create Entities As Grabbable (except Zones, Particles, and Lights)";
-var MENU_ALLOW_SELECTION_LARGE = "Allow Selecting of Large Models";
-var MENU_ALLOW_SELECTION_SMALL = "Allow Selecting of Small Models";
-var MENU_ALLOW_SELECTION_LIGHTS = "Allow Selecting of Lights";
-
-var SETTING_AUTO_FOCUS_ON_SELECT = "autoFocusOnSelect";
-var SETTING_EASE_ON_FOCUS = "cameraEaseOnFocus";
-var SETTING_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE = "showLightsAndParticlesInEditMode";
-var SETTING_SHOW_ZONES_IN_EDIT_MODE = "showZonesInEditMode";
-
-var SETTING_EDIT_PREFIX = "Edit/";
-
-
-var CREATE_ENABLED_ICON = "icons/tablet-icons/edit-i.svg";
-var CREATE_DISABLED_ICON = "icons/tablet-icons/edit-disabled.svg";
-
-// marketplace info, etc. not quite ready yet.
-var SHOULD_SHOW_PROPERTY_MENU = false;
-var INSUFFICIENT_PERMISSIONS_ERROR_MSG = "You do not have the necessary permissions to edit on this domain.";
-var INSUFFICIENT_PERMISSIONS_IMPORT_ERROR_MSG = "You do not have the necessary permissions to place items on this domain.";
-
-var isActive = false;
-var createButton = null;
-
-var IMPORTING_SVO_OVERLAY_WIDTH = 144;
-var IMPORTING_SVO_OVERLAY_HEIGHT = 30;
-var IMPORTING_SVO_OVERLAY_MARGIN = 5;
-var IMPORTING_SVO_OVERLAY_LEFT_MARGIN = 34;
-var importingSVOImageOverlay = Overlays.addOverlay("image", {
- imageURL: Script.resolvePath("assets") + "/images/hourglass.svg",
- width: 20,
- height: 20,
- alpha: 1.0,
- x: Window.innerWidth - IMPORTING_SVO_OVERLAY_WIDTH,
- y: Window.innerHeight - IMPORTING_SVO_OVERLAY_HEIGHT,
- visible: false
-});
-var importingSVOTextOverlay = Overlays.addOverlay("text", {
- font: {
- size: 14
- },
- text: "Importing SVO...",
- leftMargin: IMPORTING_SVO_OVERLAY_LEFT_MARGIN,
- x: Window.innerWidth - IMPORTING_SVO_OVERLAY_WIDTH - IMPORTING_SVO_OVERLAY_MARGIN,
- y: Window.innerHeight - IMPORTING_SVO_OVERLAY_HEIGHT - IMPORTING_SVO_OVERLAY_MARGIN,
- width: IMPORTING_SVO_OVERLAY_WIDTH,
- height: IMPORTING_SVO_OVERLAY_HEIGHT,
- backgroundColor: {
- red: 80,
- green: 80,
- blue: 80
- },
- backgroundAlpha: 0.7,
- visible: false
-});
-
-var MARKETPLACE_URL = Account.metaverseServerURL + "/marketplace";
-var marketplaceWindow = new OverlayWebWindow({
- title: 'Marketplace',
- source: "about:blank",
- width: 900,
- height: 700,
- visible: false
-});
-
-function showMarketplace(marketplaceID) {
- var url = MARKETPLACE_URL;
- if (marketplaceID) {
- url = url + "/items/" + marketplaceID;
- }
- marketplaceWindow.setURL(url);
- marketplaceWindow.setVisible(true);
- marketplaceWindow.raise();
-
- UserActivityLogger.logAction("opened_marketplace");
-}
-
-function hideMarketplace() {
- marketplaceWindow.setVisible(false);
- marketplaceWindow.setURL("about:blank");
-}
-
-// function toggleMarketplace() {
-// if (marketplaceWindow.visible) {
-// hideMarketplace();
-// } else {
-// showMarketplace();
-// }
-// }
-
-function adjustPositionPerBoundingBox(position, direction, registration, dimensions, orientation) {
- // Adjust the position such that the bounding box (registration, dimensions and orientation) lies behind the original
- // position in the given direction.
- var CORNERS = [
- { x: 0, y: 0, z: 0 },
- { x: 0, y: 0, z: 1 },
- { x: 0, y: 1, z: 0 },
- { x: 0, y: 1, z: 1 },
- { x: 1, y: 0, z: 0 },
- { x: 1, y: 0, z: 1 },
- { x: 1, y: 1, z: 0 },
- { x: 1, y: 1, z: 1 },
- ];
-
- // Go through all corners and find least (most negative) distance in front of position.
- var distance = 0;
- for (var i = 0, length = CORNERS.length; i < length; i++) {
- var cornerVector =
- Vec3.multiplyQbyV(orientation, Vec3.multiplyVbyV(Vec3.subtract(CORNERS[i], registration), dimensions));
- var cornerDistance = Vec3.dot(cornerVector, direction);
- distance = Math.min(cornerDistance, distance);
- }
- position = Vec3.sum(Vec3.multiply(distance, direction), position);
- return position;
-}
-
-var GRABBABLE_ENTITIES_MENU_CATEGORY = "Edit";
-
-// Handles any edit mode updates required when domains have switched
-function checkEditPermissionsAndUpdate() {
- if ((createButton === null) || (createButton === undefined)) {
- //--EARLY EXIT--( nothing to safely update )
- return;
- }
-
- var hasRezPermissions = (Entities.canRez() || Entities.canRezTmp() || Entities.canRezCertified() || Entities.canRezTmpCertified());
- createButton.editProperties({
- icon: (hasRezPermissions ? CREATE_ENABLED_ICON : CREATE_DISABLED_ICON),
- captionColor: (hasRezPermissions ? "#ffffff" : "#888888"),
- });
-
- if (!hasRezPermissions && isActive) {
- that.setActive(false);
- tablet.gotoHomeScreen();
- }
-}
-
-// Copies the properties in `b` into `a`. `a` will be modified.
-function copyProperties(a, b) {
- for (var key in b) {
- a[key] = b[key];
- }
- return a;
-}
-
-const DEFAULT_DYNAMIC_PROPERTIES = {
- dynamic: true,
- damping: 0.39347,
- angularDamping: 0.39347,
- gravity: { x: 0, y: -9.8, z: 0 },
-};
-
-const DEFAULT_NON_DYNAMIC_PROPERTIES = {
- dynamic: false,
- damping: 0,
- angularDamping: 0,
- gravity: { x: 0, y: 0, z: 0 },
-};
-
-const DEFAULT_ENTITY_PROPERTIES = {
- All: {
- description: "",
- rotation: { x: 0, y: 0, z: 0, w: 1 },
- collidesWith: "static,dynamic,kinematic,otherAvatar,myAvatar",
- collisionSoundURL: "",
- cloneable: false,
- ignoreIK: true,
- canCastShadow: true,
- href: "",
- script: "",
- serverScripts:"",
- velocity: {
- x: 0,
- y: 0,
- z: 0
- },
- angularVelocity: {
- x: 0,
- y: 0,
- z: 0
- },
- restitution: 0.5,
- friction: 0.5,
- density: 1000,
- dynamic: false,
- },
- Shape: {
- shape: "Box",
- dimensions: { x: 0.2, y: 0.2, z: 0.2 },
- color: { red: 0, green: 180, blue: 239 },
- },
- Text: {
- text: "Text",
- dimensions: {
- x: 0.65,
- y: 0.3,
- z: 0.01
- },
- textColor: { red: 255, green: 255, blue: 255 },
- backgroundColor: { red: 0, green: 0, blue: 0 },
- lineHeight: 0.06,
- faceCamera: false,
- },
- Zone: {
- dimensions: {
- x: 10,
- y: 10,
- z: 10
- },
- flyingAllowed: true,
- ghostingAllowed: true,
- filter: "",
- keyLightMode: "inherit",
- keyLightColor: { red: 255, green: 255, blue: 255 },
- keyLight: {
- intensity: 1.0,
- direction: {
- x: 0.0,
- y: -0.707106769084930, // 45 degrees
- z: 0.7071067690849304
- },
- castShadows: true
- },
- ambientLightMode: "inherit",
- ambientLight: {
- ambientIntensity: 0.5,
- ambientURL: ""
- },
- hazeMode: "inherit",
- haze: {
- hazeRange: 1000,
- hazeAltitudeEffect: false,
- hazeBaseRef: 0,
- hazeColor: {
- red: 128,
- green: 154,
- blue: 179
- },
- hazeBackgroundBlend: 0,
- hazeEnableGlare: false,
- hazeGlareColor: {
- red: 255,
- green: 229,
- blue: 179
- },
- },
- shapeType: "box",
- bloomMode: "inherit",
- avatarPriority: "inherit"
- },
- Model: {
- collisionShape: "none",
- compoundShapeURL: "",
- animation: {
- url: "",
- running: false,
- allowTranslation: false,
- loop: true,
- hold: false,
- currentFrame: 0,
- firstFrame: 0,
- lastFrame: 100000,
- fps: 30.0,
- }
- },
- Image: {
- dimensions: {
- x: 0.5385,
- y: 0.2819,
- z: 0.0092
- },
- shapeType: "box",
- collisionless: true,
- keepAspectRatio: false,
- imageURL: DEFAULT_IMAGE
- },
- Web: {
- dimensions: {
- x: 1.6,
- y: 0.9,
- z: 0.01
- },
- sourceUrl: "https://highfidelity.com/",
- dpi: 30,
- },
- ParticleEffect: {
- lifespan: 1.5,
- maxParticles: 10,
- textures: "https://content.highfidelity.com/DomainContent/production/Particles/wispy-smoke.png",
- emitRate: 5.5,
- emitSpeed: 0,
- speedSpread: 0,
- emitDimensions: { x: 0, y: 0, z: 0 },
- emitOrientation: { x: 0, y: 0, z: 0, w: 1 },
- emitterShouldTrail: true,
- particleRadius: 0.25,
- radiusStart: 0,
- radiusSpread: 0,
- particleColor: {
- red: 255,
- green: 255,
- blue: 255
- },
- colorSpread: {
- red: 0,
- green: 0,
- blue: 0
- },
- alpha: 0,
- alphaStart: 1,
- alphaSpread: 0,
- emitAcceleration: {
- x: 0,
- y: 2.5,
- z: 0
- },
- accelerationSpread: {
- x: 0,
- y: 0,
- z: 0
- },
- particleSpin: 0,
- spinSpread: 0,
- rotateWithEntity: false,
- polarStart: 0,
- polarFinish: Math.PI,
- azimuthStart: -Math.PI,
- azimuthFinish: Math.PI
- },
- Light: {
- color: { red: 255, green: 255, blue: 255 },
- intensity: 5.0,
- dimensions: DEFAULT_LIGHT_DIMENSIONS,
- falloffRadius: 1.0,
- isSpotlight: false,
- exponent: 1.0,
- cutoff: 75.0,
- },
-};
-
-var toolBar = (function () {
- var EDIT_SETTING = "io.highfidelity.isEditing"; // for communication with other scripts
- var that = {},
- toolBar,
- activeButton = null,
- systemToolbar = null,
- dialogWindow = null,
- tablet = null;
-
- function createNewEntity(requestedProperties) {
- var dimensions = requestedProperties.dimensions ? requestedProperties.dimensions : DEFAULT_DIMENSIONS;
- var position = getPositionToCreateEntity();
- var entityID = null;
-
- var properties = {};
-
- copyProperties(properties, DEFAULT_ENTITY_PROPERTIES.All);
-
- var type = requestedProperties.type;
- if (type === "Box" || type === "Sphere") {
- copyProperties(properties, DEFAULT_ENTITY_PROPERTIES.Shape);
- } else {
- copyProperties(properties, DEFAULT_ENTITY_PROPERTIES[type]);
- }
-
- // We apply the requested properties first so that they take priority over any default properties.
- copyProperties(properties, requestedProperties);
-
- if (properties.dynamic) {
- copyProperties(properties, DEFAULT_DYNAMIC_PROPERTIES);
- } else {
- copyProperties(properties, DEFAULT_NON_DYNAMIC_PROPERTIES);
- }
-
-
- if (position !== null && position !== undefined) {
- var direction;
- if (Camera.mode === "entity" || Camera.mode === "independent") {
- direction = Camera.orientation;
- } else {
- direction = MyAvatar.orientation;
- }
- direction = Vec3.multiplyQbyV(direction, Vec3.UNIT_Z);
-
- var PRE_ADJUST_ENTITY_TYPES = ["Box", "Sphere", "Shape", "Text", "Image", "Web", "Material"];
- if (PRE_ADJUST_ENTITY_TYPES.indexOf(properties.type) !== -1) {
-
- // Adjust position of entity per bounding box prior to creating it.
- var registration = properties.registration;
- if (registration === undefined) {
- var DEFAULT_REGISTRATION = { x: 0.5, y: 0.5, z: 0.5 };
- registration = DEFAULT_REGISTRATION;
- }
-
- var orientation = properties.orientation;
- if (orientation === undefined) {
- properties.orientation = MyAvatar.orientation;
- var DEFAULT_ORIENTATION = properties.orientation;
- orientation = DEFAULT_ORIENTATION;
- } else {
- // If the orientation is already defined, we perform the corresponding rotation assuming that
- // our start referential is the avatar referential.
- properties.orientation = Quat.multiply(MyAvatar.orientation, properties.orientation);
- var DEFAULT_ORIENTATION = properties.orientation;
- orientation = DEFAULT_ORIENTATION;
- }
-
- position = adjustPositionPerBoundingBox(position, direction, registration, dimensions, orientation);
- }
-
- position = grid.snapToSurface(grid.snapToGrid(position, false, dimensions), dimensions);
- properties.position = position;
-
- if (!properties.grab) {
- properties.grab = {};
- if (Menu.isOptionChecked(MENU_CREATE_ENTITIES_GRABBABLE) &&
- !(properties.type === "Zone" || properties.type === "Light" || properties.type === "ParticleEffect")) {
- properties.grab.grabbable = true;
- } else {
- properties.grab.grabbable = false;
- }
- }
-
- entityID = Entities.addEntity(properties);
- SelectionManager.addEntity(entityID, false, this);
- SelectionManager.saveProperties();
- pushCommandForSelections([{
- entityID: entityID,
- properties: properties
- }], [], true);
-
- var POST_ADJUST_ENTITY_TYPES = ["Model"];
- if (POST_ADJUST_ENTITY_TYPES.indexOf(properties.type) !== -1) {
- // Adjust position of entity per bounding box after it has been created and auto-resized.
- var initialDimensions = Entities.getEntityProperties(entityID, ["dimensions"]).dimensions;
- var DIMENSIONS_CHECK_INTERVAL = 200;
- var MAX_DIMENSIONS_CHECKS = 10;
- var dimensionsCheckCount = 0;
- var dimensionsCheckFunction = function () {
- dimensionsCheckCount++;
- var properties = Entities.getEntityProperties(entityID, ["dimensions", "registrationPoint", "rotation"]);
- if (!Vec3.equal(properties.dimensions, initialDimensions)) {
- position = adjustPositionPerBoundingBox(position, direction, properties.registrationPoint,
- properties.dimensions, properties.rotation);
- position = grid.snapToSurface(grid.snapToGrid(position, false, properties.dimensions),
- properties.dimensions);
- Entities.editEntity(entityID, {
- position: position
- });
- selectionManager._update(false, this);
- } else if (dimensionsCheckCount < MAX_DIMENSIONS_CHECKS) {
- Script.setTimeout(dimensionsCheckFunction, DIMENSIONS_CHECK_INTERVAL);
- }
- };
- Script.setTimeout(dimensionsCheckFunction, DIMENSIONS_CHECK_INTERVAL);
- }
- } else {
- Window.notifyEditError("Can't create " + properties.type + ": " +
- properties.type + " would be out of bounds.");
- }
-
- selectionManager.clearSelections(this);
- entityListTool.sendUpdate();
- selectionManager.setSelections([entityID], this);
-
- Window.setFocus();
-
- return entityID;
- }
-
- function closeExistingDialogWindow() {
- if (dialogWindow) {
- dialogWindow.close();
- dialogWindow = null;
- }
- }
-
- function cleanup() {
- that.setActive(false);
- if (tablet) {
- tablet.removeButton(activeButton);
- }
- if (systemToolbar) {
- systemToolbar.removeButton(EDIT_TOGGLE_BUTTON);
- }
- }
-
- var buttonHandlers = {}; // only used to tablet mode
-
- function addButton(name, handler) {
- buttonHandlers[name] = handler;
- }
-
- var SHAPE_TYPE_NONE = 0;
- var SHAPE_TYPE_SIMPLE_HULL = 1;
- var SHAPE_TYPE_SIMPLE_COMPOUND = 2;
- var SHAPE_TYPE_STATIC_MESH = 3;
- var SHAPE_TYPE_BOX = 4;
- var SHAPE_TYPE_SPHERE = 5;
- var DYNAMIC_DEFAULT = false;
-
- var MATERIAL_MODE_UV = 0;
- var MATERIAL_MODE_PROJECTED = 1;
-
- function handleNewModelDialogResult(result) {
- if (result) {
- var url = result.url;
- var shapeType;
- switch (result.collisionShapeIndex) {
- case SHAPE_TYPE_SIMPLE_HULL:
- shapeType = "simple-hull";
- break;
- case SHAPE_TYPE_SIMPLE_COMPOUND:
- shapeType = "simple-compound";
- break;
- case SHAPE_TYPE_STATIC_MESH:
- shapeType = "static-mesh";
- break;
- case SHAPE_TYPE_BOX:
- shapeType = "box";
- break;
- case SHAPE_TYPE_SPHERE:
- shapeType = "sphere";
- break;
- default:
- shapeType = "none";
- }
-
- var dynamic = result.dynamic !== null ? result.dynamic : DYNAMIC_DEFAULT;
- if (shapeType === "static-mesh" && dynamic) {
- // The prompt should prevent this case
- print("Error: model cannot be both static mesh and dynamic. This should never happen.");
- } else if (url) {
- createNewEntity({
- type: "Model",
- modelURL: url,
- shapeType: shapeType,
- grab: {
- grabbable: result.grabbable
- },
- dynamic: dynamic,
- });
- }
- }
- }
-
- function handleNewMaterialDialogResult(result) {
- if (result) {
- var materialURL = result.textInput;
- //var materialMappingMode;
- //switch (result.comboBox) {
- // case MATERIAL_MODE_PROJECTED:
- // materialMappingMode = "projected";
- // break;
- // default:
- // shapeType = "uv";
- //}
- var materialData = "";
- if (materialURL.startsWith("materialData")) {
- materialData = JSON.stringify({
- "materials": {}
- });
- }
-
- var DEFAULT_LAYERED_MATERIAL_PRIORITY = 1;
- if (materialURL) {
- createNewEntity({
- type: "Material",
- materialURL: materialURL,
- //materialMappingMode: materialMappingMode,
- priority: DEFAULT_LAYERED_MATERIAL_PRIORITY,
- materialData: materialData
- });
- }
- }
- }
-
- function fromQml(message) { // messages are {method, params}, like json-rpc. See also sendToQml.
- var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
- tablet.popFromStack();
- switch (message.method) {
- case "newModelDialogAdd":
- handleNewModelDialogResult(message.params);
- closeExistingDialogWindow();
- break;
- case "newModelDialogCancel":
- closeExistingDialogWindow();
- break;
- case "newEntityButtonClicked":
- buttonHandlers[message.params.buttonName]();
- break;
- case "newMaterialDialogAdd":
- handleNewMaterialDialogResult(message.params);
- closeExistingDialogWindow();
- break;
- case "newMaterialDialogCancel":
- closeExistingDialogWindow();
- break;
- }
- }
-
- var entitiesToDelete = [];
- var deletedEntityTimer = null;
- var DELETE_ENTITY_TIMER_TIMEOUT = 100;
-
- function checkDeletedEntityAndUpdate(entityID) {
- // Allow for multiple entity deletes before updating the entities selected.
- entitiesToDelete.push(entityID);
- if (deletedEntityTimer !== null) {
- Script.clearTimeout(deletedEntityTimer);
- }
- deletedEntityTimer = Script.setTimeout(function () {
- if (entitiesToDelete.length > 0) {
- selectionManager.removeEntities(entitiesToDelete, this);
- }
- entityListTool.removeEntities(entitiesToDelete, selectionManager.selections);
- entitiesToDelete = [];
- deletedEntityTimer = null;
- }, DELETE_ENTITY_TIMER_TIMEOUT);
- }
-
- function initialize() {
- Script.scriptEnding.connect(cleanup);
- Window.domainChanged.connect(function () {
- if (isActive) {
- tablet.gotoHomeScreen();
- }
- that.setActive(false);
- that.clearEntityList();
- checkEditPermissionsAndUpdate();
- });
-
- HMD.displayModeChanged.connect(function() {
- if (isActive) {
- tablet.gotoHomeScreen();
- }
- that.setActive(false);
- });
-
- Entities.canAdjustLocksChanged.connect(function (canAdjustLocks) {
- if (isActive && !canAdjustLocks) {
- that.setActive(false);
- }
- checkEditPermissionsAndUpdate();
- });
-
- Entities.canRezChanged.connect(checkEditPermissionsAndUpdate);
- Entities.canRezTmpChanged.connect(checkEditPermissionsAndUpdate);
- Entities.canRezCertifiedChanged.connect(checkEditPermissionsAndUpdate);
- Entities.canRezTmpCertifiedChanged.connect(checkEditPermissionsAndUpdate);
- var hasRezPermissions = (Entities.canRez() || Entities.canRezTmp() || Entities.canRezCertified() || Entities.canRezTmpCertified());
-
- Entities.deletingEntity.connect(checkDeletedEntityAndUpdate);
-
- var createButtonIconRsrc = (hasRezPermissions ? CREATE_ENABLED_ICON : CREATE_DISABLED_ICON);
- tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
- activeButton = tablet.addButton({
- captionColor: hasRezPermissions ? "#ffffff" : "#888888",
- icon: createButtonIconRsrc,
- activeIcon: "icons/tablet-icons/edit-a.svg",
- text: "CREATE",
- sortOrder: 10
- });
- createButton = activeButton;
- tablet.screenChanged.connect(function (type, url) {
- var isGoingToHomescreenOnDesktop = (!shouldUseEditTabletApp() &&
- (url === 'hifi/tablet/TabletHome.qml' || url === ''));
- if (isActive && (type !== "QML" || url !== Script.resolvePath("create/Edit.qml")) && !isGoingToHomescreenOnDesktop) {
- that.setActive(false);
- }
- });
- tablet.fromQml.connect(fromQml);
- createToolsWindow.fromQml.addListener(fromQml);
-
- createButton.clicked.connect(function() {
- if ( ! (Entities.canRez() || Entities.canRezTmp() || Entities.canRezCertified() || Entities.canRezTmpCertified()) ) {
- Window.notifyEditError(INSUFFICIENT_PERMISSIONS_ERROR_MSG);
- return;
- }
-
- that.toggle();
- });
-
- addButton("importEntitiesButton", function() {
- Window.browseChanged.connect(onFileOpenChanged);
- Window.browseAsync("Select Model to Import", "", "*.json");
- });
-
- addButton("openAssetBrowserButton", function() {
- Window.showAssetServer();
- });
- function createNewEntityDialogButtonCallback(entityType) {
- return function() {
- if (shouldUseEditTabletApp()) {
- // tablet version of new-model dialog
- var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
- tablet.pushOntoStack(Script.resolvePath("create/New" + entityType + "Dialog.qml"));
- } else {
- closeExistingDialogWindow();
- var qmlPath = Script.resolvePath("create/New" + entityType + "Window.qml");
- var DIALOG_WINDOW_SIZE = { x: 500, y: 300 };
- dialogWindow = Desktop.createWindow(qmlPath, {
- title: "New " + entityType + " Entity",
- flags: Desktop.ALWAYS_ON_TOP | Desktop.CLOSE_BUTTON_HIDES,
- presentationMode: Desktop.PresentationMode.NATIVE,
- size: DIALOG_WINDOW_SIZE,
- visible: true
- });
- dialogWindow.fromQml.connect(fromQml);
- }
- };
- }
-
- addButton("newModelButton", createNewEntityDialogButtonCallback("Model"));
-
- addButton("newShapeButton", function () {
- createNewEntity({
- type: "Shape",
- shape: "Cube",
- });
- });
-
- addButton("newLightButton", function () {
- createNewEntity({
- type: "Light",
- });
- });
-
- addButton("newTextButton", function () {
- createNewEntity({
- type: "Text",
- });
- });
-
- addButton("newImageButton", function () {
- createNewEntity({
- type: "Image",
- });
- });
-
- addButton("newWebButton", function () {
- createNewEntity({
- type: "Web",
- });
- });
-
- addButton("newZoneButton", function () {
- createNewEntity({
- type: "Zone",
- });
- });
-
- addButton("newParticleButton", function () {
- createNewEntity({
- type: "ParticleEffect",
- });
- });
-
- addButton("newMaterialButton", createNewEntityDialogButtonCallback("Material"));
-
- var deactivateCreateIfDesktopWindowsHidden = function() {
- if (!shouldUseEditTabletApp() && !entityListTool.isVisible() && !createToolsWindow.isVisible()) {
- that.setActive(false);
- }
- };
- entityListTool.interactiveWindowHidden.addListener(this, deactivateCreateIfDesktopWindowsHidden);
- createToolsWindow.interactiveWindowHidden.addListener(this, deactivateCreateIfDesktopWindowsHidden);
-
- that.setActive(false);
- }
-
- that.clearEntityList = function () {
- entityListTool.clearEntityList();
- };
-
- that.toggle = function () {
- that.setActive(!isActive);
- if (!isActive) {
- tablet.gotoHomeScreen();
- }
- };
-
- that.setActive = function (active) {
- ContextOverlay.enabled = !active;
- Settings.setValue(EDIT_SETTING, active);
- if (active) {
- Controller.captureEntityClickEvents();
- } else {
- Controller.releaseEntityClickEvents();
-
- closeExistingDialogWindow();
- }
- if (active === isActive) {
- return;
- }
- if (active && !Entities.canRez() && !Entities.canRezTmp() && !Entities.canRezCertified() && !Entities.canRezTmpCertified()) {
- Window.notifyEditError(INSUFFICIENT_PERMISSIONS_ERROR_MSG);
- return;
- }
- Messages.sendLocalMessage("edit-events", JSON.stringify({
- enabled: active
- }));
- isActive = active;
- activeButton.editProperties({isActive: isActive});
- undoHistory.setEnabled(isActive);
-
- var tablet = Tablet.getTablet("com.highfidelity.interface.tablet.system");
-
- if (!isActive) {
- entityListTool.setVisible(false);
- gridTool.setVisible(false);
- grid.setEnabled(false);
- propertiesTool.setVisible(false);
- selectionManager.clearSelections(this);
- cameraManager.disable();
- selectionDisplay.disableTriggerMapping();
- tablet.landscape = false;
- Controller.disableMapping(CONTROLLER_MAPPING_NAME);
- } else {
- if (shouldUseEditTabletApp()) {
- tablet.loadQMLSource(Script.resolvePath("create/Edit.qml"), true);
- } else {
- // make other apps inactive while in desktop mode
- tablet.gotoHomeScreen();
- }
- UserActivityLogger.enabledEdit();
- entityListTool.setVisible(true);
- entityListTool.sendUpdate();
- gridTool.setVisible(true);
- grid.setEnabled(true);
- propertiesTool.setVisible(true);
- selectionDisplay.enableTriggerMapping();
- print("starting tablet in landscape mode");
- tablet.landscape = true;
- Controller.enableMapping(CONTROLLER_MAPPING_NAME);
- // Not sure what the following was meant to accomplish, but it currently causes
- // everybody else to think that Interface has lost focus overall. fogbugzid:558
- // Window.setFocus();
- }
- entityIconOverlayManager.setVisible(isActive && Menu.isOptionChecked(MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE));
- Entities.setDrawZoneBoundaries(isActive && Menu.isOptionChecked(MENU_SHOW_ZONES_IN_EDIT_MODE));
- };
-
- initialize();
- return that;
-})();
-
-var selectedEntityID;
-var orientation;
-var intersection;
-
-
-function rayPlaneIntersection(pickRay, point, normal) { //
- //
- // This version of the test returns the intersection of a line with a plane
- //
- var collides = Vec3.dot(pickRay.direction, normal);
-
- var d = -Vec3.dot(point, normal);
- var t = -(Vec3.dot(pickRay.origin, normal) + d) / collides;
-
- return Vec3.sum(pickRay.origin, Vec3.multiply(pickRay.direction, t));
-}
-
-function rayPlaneIntersection2(pickRay, point, normal) {
- //
- // This version of the test returns false if the ray is directed away from the plane
- //
- var collides = Vec3.dot(pickRay.direction, normal);
- var d = -Vec3.dot(point, normal);
- var t = -(Vec3.dot(pickRay.origin, normal) + d) / collides;
- if (t < 0.0) {
- return false;
- } else {
- return Vec3.sum(pickRay.origin, Vec3.multiply(pickRay.direction, t));
- }
-}
-
-function findClickedEntity(event) {
- var pickZones = event.isControl;
-
- if (pickZones) {
- Entities.setZonesArePickable(true);
- }
-
- var pickRay = Camera.computePickRay(event.x, event.y);
- var tabletIDs = getMainTabletIDs();
- if (tabletIDs.length > 0) {
- var overlayResult = Overlays.findRayIntersection(pickRay, true, tabletIDs);
- if (overlayResult.intersects) {
- return null;
- }
- }
-
- var entityResult = Entities.findRayIntersection(pickRay, true); // want precision picking
- var iconResult = entityIconOverlayManager.findRayIntersection(pickRay);
- iconResult.accurate = true;
-
- if (pickZones) {
- Entities.setZonesArePickable(false);
- }
-
- var result;
-
- if (iconResult.intersects) {
- result = iconResult;
- } else if (entityResult.intersects) {
- result = entityResult;
- } else {
- return null;
- }
-
- if (!result.accurate) {
- return null;
- }
-
- var foundEntity = result.entityID;
- return {
- pickRay: pickRay,
- entityID: foundEntity,
- intersection: result.intersection
- };
-}
-
-// Handles selections on overlays while in edit mode by querying entities from
-// entityIconOverlayManager.
-function handleOverlaySelectionToolUpdates(channel, message, sender) {
- var wantDebug = false;
- if (sender !== MyAvatar.sessionUUID || channel !== 'entityToolUpdates')
- return;
-
- var data = JSON.parse(message);
-
- if (data.method === "selectOverlay") {
- if (!selectionDisplay.triggered() || selectionDisplay.triggeredHand === data.hand) {
- if (wantDebug) {
- print("setting selection to overlay " + data.overlayID);
- }
- var entity = entityIconOverlayManager.findEntity(data.overlayID);
-
- if (entity !== null) {
- selectionManager.setSelections([entity], this);
- }
- }
- }
-}
-
-function handleMessagesReceived(channel, message, sender) {
- switch( channel ){
- case 'entityToolUpdates': {
- handleOverlaySelectionToolUpdates( channel, message, sender );
- break;
- }
- default: {
- return;
- }
- }
-}
-
-Messages.subscribe("entityToolUpdates");
-Messages.messageReceived.connect(handleMessagesReceived);
-
-var mouseHasMovedSincePress = false;
-var mousePressStartTime = 0;
-var mousePressStartPosition = {
- x: 0,
- y: 0
-};
-var mouseDown = false;
-
-function mousePressEvent(event) {
- mouseDown = true;
- mousePressStartPosition = {
- x: event.x,
- y: event.y
- };
- mousePressStartTime = Date.now();
- mouseHasMovedSincePress = false;
- mouseCapturedByTool = false;
-
- if (propertyMenu.mousePressEvent(event) || progressDialog.mousePressEvent(event)) {
- mouseCapturedByTool = true;
- return;
- }
- if (isActive) {
- if (cameraManager.mousePressEvent(event) || selectionDisplay.mousePressEvent(event)) {
- // Event handled; do nothing.
- return;
- }
- }
-}
-
-var mouseCapturedByTool = false;
-var lastMousePosition = null;
-var CLICK_TIME_THRESHOLD = 500 * 1000; // 500 ms
-var CLICK_MOVE_DISTANCE_THRESHOLD = 20;
-var IDLE_MOUSE_TIMEOUT = 200;
-
-var lastMouseMoveEvent = null;
-
-function mouseMoveEventBuffered(event) {
- lastMouseMoveEvent = event;
-}
-
-function mouseMove(event) {
- if (mouseDown && !mouseHasMovedSincePress) {
- var timeSincePressMicro = Date.now() - mousePressStartTime;
-
- var dX = mousePressStartPosition.x - event.x;
- var dY = mousePressStartPosition.y - event.y;
- var sqDist = (dX * dX) + (dY * dY);
-
- // If less than CLICK_TIME_THRESHOLD has passed since the mouse click AND the mouse has moved
- // less than CLICK_MOVE_DISTANCE_THRESHOLD distance, then don't register this as a mouse move
- // yet. The goal is to provide mouse clicks that are more lenient to small movements.
- if (timeSincePressMicro < CLICK_TIME_THRESHOLD && sqDist < CLICK_MOVE_DISTANCE_THRESHOLD) {
- return;
- }
- mouseHasMovedSincePress = true;
- }
-
- if (!isActive) {
- return;
- }
-
- // allow the selectionDisplay and cameraManager to handle the event first, if it doesn't handle it, then do our own thing
- if (selectionDisplay.mouseMoveEvent(event) || propertyMenu.mouseMoveEvent(event) || cameraManager.mouseMoveEvent(event)) {
- return;
- }
-
- lastMousePosition = {
- x: event.x,
- y: event.y
- };
-}
-
-function mouseReleaseEvent(event) {
- mouseDown = false;
-
- if (lastMouseMoveEvent) {
- mouseMove(lastMouseMoveEvent);
- lastMouseMoveEvent = null;
- }
- if (propertyMenu.mouseReleaseEvent(event)) {
- return true;
- }
- if (isActive && selectionManager.hasSelection()) {
- tooltip.show(false);
- }
- if (mouseCapturedByTool) {
-
- return;
- }
-
- cameraManager.mouseReleaseEvent(event);
-
- if (!mouseHasMovedSincePress) {
- mouseClickEvent(event);
- }
-}
-
-function wasTabletOrEditHandleClicked(event) {
- var rayPick = Camera.computePickRay(event.x, event.y);
- var result = Overlays.findRayIntersection(rayPick, true);
- if (result.intersects) {
- var overlayID = result.overlayID;
- var tabletIDs = getMainTabletIDs();
- if (tabletIDs.indexOf(overlayID) >= 0) {
- return true;
- } else if (selectionDisplay.isEditHandle(overlayID)) {
- return true;
- }
- }
- return false;
-}
-
-function mouseClickEvent(event) {
- var wantDebug = false;
- var result, properties, tabletClicked;
- if (isActive && event.isLeftButton) {
- result = findClickedEntity(event);
- var tabletOrEditHandleClicked = wasTabletOrEditHandleClicked(event);
- if (tabletOrEditHandleClicked) {
- return;
- }
-
- if (result === null || result === undefined) {
- if (!event.isShifted) {
- selectionManager.clearSelections(this);
- }
- return;
- }
- toolBar.setActive(true);
- var pickRay = result.pickRay;
- var foundEntity = result.entityID;
- if (HMD.tabletID && foundEntity === HMD.tabletID) {
- return;
- }
- properties = Entities.getEntityProperties(foundEntity);
- var halfDiagonal = Vec3.length(properties.dimensions) / 2.0;
-
- if (wantDebug) {
- print("Checking properties: " + properties.id + " " + " - Half Diagonal:" + halfDiagonal);
- }
- // P P - Model
- // /| A - Palm
- // / | d B - unit vector toward tip
- // / | X - base of the perpendicular line
- // A---X----->B d - distance fom axis
- // x x - distance from A
- //
- // |X-A| = (P-A).B
- // X === A + ((P-A).B)B
- // d = |P-X|
-
- var A = pickRay.origin;
- var B = Vec3.normalize(pickRay.direction);
- var P = properties.position;
-
- var x = Vec3.dot(Vec3.subtract(P, A), B);
-
- var angularSize = 2 * Math.atan(halfDiagonal / Vec3.distance(Camera.getPosition(), properties.position)) *
- 180 / Math.PI;
-
- var sizeOK = (allowLargeModels || angularSize < MAX_ANGULAR_SIZE) &&
- (allowSmallModels || angularSize > MIN_ANGULAR_SIZE);
-
- if (0 < x && sizeOK) {
- selectedEntityID = foundEntity;
- orientation = MyAvatar.orientation;
- intersection = rayPlaneIntersection(pickRay, P, Quat.getForward(orientation));
-
- if (!event.isShifted) {
- selectionManager.setSelections([foundEntity], this);
- } else {
- selectionManager.addEntity(foundEntity, true, this);
- }
- selectionManager.saveProperties();
-
- if (wantDebug) {
- print("Model selected: " + foundEntity);
- }
- selectionDisplay.select(selectedEntityID, event);
-
- if (Menu.isOptionChecked(MENU_AUTO_FOCUS_ON_SELECT)) {
- cameraManager.enable();
- cameraManager.focus(selectionManager.worldPosition,
- selectionManager.worldDimensions,
- Menu.isOptionChecked(MENU_EASE_ON_FOCUS));
- }
- }
- } else if (event.isRightButton) {
- result = findClickedEntity(event);
- if (result) {
- if (SHOULD_SHOW_PROPERTY_MENU !== true) {
- return;
- }
- properties = Entities.getEntityProperties(result.entityID);
- if (properties.marketplaceID) {
- propertyMenu.marketplaceID = properties.marketplaceID;
- propertyMenu.updateMenuItemText(showMenuItem, "Show in Marketplace");
- } else {
- propertyMenu.marketplaceID = null;
- propertyMenu.updateMenuItemText(showMenuItem, "No marketplace info");
- }
- propertyMenu.setPosition(event.x, event.y);
- propertyMenu.show();
- } else {
- propertyMenu.hide();
- }
- }
-}
-
-Controller.mousePressEvent.connect(mousePressEvent);
-Controller.mouseMoveEvent.connect(mouseMoveEventBuffered);
-Controller.mouseReleaseEvent.connect(mouseReleaseEvent);
-
-
-// In order for editVoxels and editModels to play nice together, they each check to see if a "delete" menu item already
-// exists. If it doesn't they add it. If it does they don't. They also only delete the menu item if they were the one that
-// added it.
-var modelMenuAddedDelete = false;
-var originalLightsArePickable = Entities.getLightsArePickable();
-
-function setupModelMenus() {
- // adj our menuitems
- Menu.addMenuItem({
- menuName: "Edit",
- menuItemName: "Undo",
- shortcutKey: 'Ctrl+Z',
- position: 0,
- });
- Menu.addMenuItem({
- menuName: "Edit",
- menuItemName: "Redo",
- shortcutKey: 'Ctrl+Y',
- position: 1,
- });
-
- Menu.addMenuItem({
- menuName: "Edit",
- menuItemName: "Entities",
- isSeparator: true
- });
- if (!Menu.menuItemExists("Edit", "Delete")) {
- Menu.addMenuItem({
- menuName: "Edit",
- menuItemName: "Delete",
- shortcutKeyEvent: {
- text: "delete"
- },
- afterItem: "Entities",
- });
- modelMenuAddedDelete = true;
- }
-
- Menu.addMenuItem({
- menuName: "Edit",
- menuItemName: "Parent Entity to Last",
- afterItem: "Entities"
- });
-
- Menu.addMenuItem({
- menuName: "Edit",
- menuItemName: "Unparent Entity",
- afterItem: "Parent Entity to Last"
- });
-
- Menu.addMenuItem({
- menuName: GRABBABLE_ENTITIES_MENU_CATEGORY,
- menuItemName: MENU_CREATE_ENTITIES_GRABBABLE,
- afterItem: "Unparent Entity",
- isCheckable: true,
- isChecked: Settings.getValue(SETTING_EDIT_PREFIX + MENU_CREATE_ENTITIES_GRABBABLE, true)
- });
-
- Menu.addMenuItem({
- menuName: "Edit",
- menuItemName: MENU_ALLOW_SELECTION_LARGE,
- afterItem: MENU_CREATE_ENTITIES_GRABBABLE,
- isCheckable: true,
- isChecked: Settings.getValue(SETTING_EDIT_PREFIX + MENU_ALLOW_SELECTION_LARGE, true)
- });
- Menu.addMenuItem({
- menuName: "Edit",
- menuItemName: MENU_ALLOW_SELECTION_SMALL,
- afterItem: MENU_ALLOW_SELECTION_LARGE,
- isCheckable: true,
- isChecked: Settings.getValue(SETTING_EDIT_PREFIX + MENU_ALLOW_SELECTION_SMALL, true)
- });
- Menu.addMenuItem({
- menuName: "Edit",
- menuItemName: MENU_ALLOW_SELECTION_LIGHTS,
- afterItem: MENU_ALLOW_SELECTION_SMALL,
- isCheckable: true,
- isChecked: Settings.getValue(SETTING_EDIT_PREFIX + MENU_ALLOW_SELECTION_LIGHTS, false)
- });
- Menu.addMenuItem({
- menuName: "Edit",
- menuItemName: "Select All Entities In Box",
- afterItem: "Allow Selecting of Lights"
- });
- Menu.addMenuItem({
- menuName: "Edit",
- menuItemName: "Select All Entities Touching Box",
- afterItem: "Select All Entities In Box"
- });
-
- Menu.addMenuItem({
- menuName: "Edit",
- menuItemName: "Export Entities",
- afterItem: "Entities"
- });
- Menu.addMenuItem({
- menuName: "Edit",
- menuItemName: "Import Entities",
- afterItem: "Export Entities"
- });
- Menu.addMenuItem({
- menuName: "Edit",
- menuItemName: "Import Entities from URL",
- afterItem: "Import Entities"
- });
-
- Menu.addMenuItem({
- menuName: "Edit",
- menuItemName: MENU_AUTO_FOCUS_ON_SELECT,
- isCheckable: true,
- isChecked: Settings.getValue(SETTING_AUTO_FOCUS_ON_SELECT) === "true"
- });
- Menu.addMenuItem({
- menuName: "Edit",
- menuItemName: MENU_EASE_ON_FOCUS,
- afterItem: MENU_AUTO_FOCUS_ON_SELECT,
- isCheckable: true,
- isChecked: Settings.getValue(SETTING_EASE_ON_FOCUS) === "true"
- });
- Menu.addMenuItem({
- menuName: "Edit",
- menuItemName: MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE,
- afterItem: MENU_EASE_ON_FOCUS,
- isCheckable: true,
- isChecked: Settings.getValue(SETTING_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE) !== "false"
- });
- Menu.addMenuItem({
- menuName: "Edit",
- menuItemName: MENU_SHOW_ZONES_IN_EDIT_MODE,
- afterItem: MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE,
- isCheckable: true,
- isChecked: Settings.getValue(SETTING_SHOW_ZONES_IN_EDIT_MODE) !== "false"
- });
-
- Entities.setLightsArePickable(false);
-}
-
-setupModelMenus(); // do this when first running our script.
-
-function cleanupModelMenus() {
- Menu.removeMenuItem("Edit", "Undo");
- Menu.removeMenuItem("Edit", "Redo");
-
- Menu.removeSeparator("Edit", "Entities");
- if (modelMenuAddedDelete) {
- // delete our menuitems
- Menu.removeMenuItem("Edit", "Delete");
- }
-
- Menu.removeMenuItem("Edit", "Parent Entity to Last");
- Menu.removeMenuItem("Edit", "Unparent Entity");
- Menu.removeMenuItem("Edit", "Allow Selecting of Large Models");
- Menu.removeMenuItem("Edit", "Allow Selecting of Small Models");
- Menu.removeMenuItem("Edit", "Allow Selecting of Lights");
- Menu.removeMenuItem("Edit", "Select All Entities In Box");
- Menu.removeMenuItem("Edit", "Select All Entities Touching Box");
-
- Menu.removeMenuItem("Edit", "Export Entities");
- Menu.removeMenuItem("Edit", "Import Entities");
- Menu.removeMenuItem("Edit", "Import Entities from URL");
-
- Menu.removeMenuItem("Edit", MENU_AUTO_FOCUS_ON_SELECT);
- Menu.removeMenuItem("Edit", MENU_EASE_ON_FOCUS);
- Menu.removeMenuItem("Edit", MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE);
- Menu.removeMenuItem("Edit", MENU_SHOW_ZONES_IN_EDIT_MODE);
- Menu.removeMenuItem("Edit", MENU_CREATE_ENTITIES_GRABBABLE);
-}
-
-Script.scriptEnding.connect(function () {
- toolBar.setActive(false);
- Settings.setValue(SETTING_AUTO_FOCUS_ON_SELECT, Menu.isOptionChecked(MENU_AUTO_FOCUS_ON_SELECT));
- Settings.setValue(SETTING_EASE_ON_FOCUS, Menu.isOptionChecked(MENU_EASE_ON_FOCUS));
- Settings.setValue(SETTING_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE, Menu.isOptionChecked(MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE));
- Settings.setValue(SETTING_SHOW_ZONES_IN_EDIT_MODE, Menu.isOptionChecked(MENU_SHOW_ZONES_IN_EDIT_MODE));
-
- Settings.setValue(SETTING_EDIT_PREFIX + MENU_ALLOW_SELECTION_LARGE, Menu.isOptionChecked(MENU_ALLOW_SELECTION_LARGE));
- Settings.setValue(SETTING_EDIT_PREFIX + MENU_ALLOW_SELECTION_SMALL, Menu.isOptionChecked(MENU_ALLOW_SELECTION_SMALL));
- Settings.setValue(SETTING_EDIT_PREFIX + MENU_ALLOW_SELECTION_LIGHTS, Menu.isOptionChecked(MENU_ALLOW_SELECTION_LIGHTS));
-
-
- progressDialog.cleanup();
- cleanupModelMenus();
- tooltip.cleanup();
- selectionDisplay.cleanup();
- entityShapeVisualizer.cleanup();
- Entities.setLightsArePickable(originalLightsArePickable);
-
- Overlays.deleteOverlay(importingSVOImageOverlay);
- Overlays.deleteOverlay(importingSVOTextOverlay);
-
- Controller.keyReleaseEvent.disconnect(keyReleaseEvent);
- Controller.keyPressEvent.disconnect(keyPressEvent);
-
- Controller.mousePressEvent.disconnect(mousePressEvent);
- Controller.mouseMoveEvent.disconnect(mouseMoveEventBuffered);
- Controller.mouseReleaseEvent.disconnect(mouseReleaseEvent);
-
- Messages.messageReceived.disconnect(handleMessagesReceived);
- Messages.unsubscribe("entityToolUpdates");
- createButton = null;
-});
-
-var lastOrientation = null;
-var lastPosition = null;
-
-// Do some stuff regularly, like check for placement of various overlays
-Script.update.connect(function (deltaTime) {
- progressDialog.move();
- selectionDisplay.checkControllerMove();
- var dOrientation = Math.abs(Quat.dot(Camera.orientation, lastOrientation) - 1);
- var dPosition = Vec3.distance(Camera.position, lastPosition);
- if (dOrientation > 0.001 || dPosition > 0.001) {
- propertyMenu.hide();
- lastOrientation = Camera.orientation;
- lastPosition = Camera.position;
- }
- if (lastMouseMoveEvent) {
- mouseMove(lastMouseMoveEvent);
- lastMouseMoveEvent = null;
- }
-});
-
-function insideBox(center, dimensions, point) {
- return (Math.abs(point.x - center.x) <= (dimensions.x / 2.0)) &&
- (Math.abs(point.y - center.y) <= (dimensions.y / 2.0)) &&
- (Math.abs(point.z - center.z) <= (dimensions.z / 2.0));
-}
-
-function selectAllEntitiesInCurrentSelectionBox(keepIfTouching) {
- if (selectionManager.hasSelection()) {
- // Get all entities touching the bounding box of the current selection
- var boundingBoxCorner = Vec3.subtract(selectionManager.worldPosition,
- Vec3.multiply(selectionManager.worldDimensions, 0.5));
- var entities = Entities.findEntitiesInBox(boundingBoxCorner, selectionManager.worldDimensions);
-
- if (!keepIfTouching) {
- var isValid;
- if (selectionManager.localPosition === null || selectionManager.localPosition === undefined) {
- isValid = function (position) {
- return insideBox(selectionManager.worldPosition, selectionManager.worldDimensions, position);
- };
- } else {
- isValid = function (position) {
- var localPosition = Vec3.multiplyQbyV(Quat.inverse(selectionManager.localRotation),
- Vec3.subtract(position,
- selectionManager.localPosition));
- return insideBox(Vec3.ZERO, selectionManager.localDimensions, localPosition);
- };
- }
- for (var i = 0; i < entities.length; ++i) {
- var properties = Entities.getEntityProperties(entities[i]);
- if (!isValid(properties.position)) {
- entities.splice(i, 1);
- --i;
- }
- }
- }
- selectionManager.setSelections(entities, this);
- }
-}
-
-function sortSelectedEntities(selected) {
- var sortedEntities = selected.slice();
- var begin = 0;
- while (begin < sortedEntities.length) {
- var elementRemoved = false;
- var next = begin + 1;
- while (next < sortedEntities.length) {
- var beginID = sortedEntities[begin];
- var nextID = sortedEntities[next];
-
- if (Entities.isChildOfParent(beginID, nextID)) {
- sortedEntities[begin] = nextID;
- sortedEntities[next] = beginID;
- sortedEntities.splice(next, 1);
- elementRemoved = true;
- break;
- } else if (Entities.isChildOfParent(nextID, beginID)) {
- sortedEntities.splice(next, 1);
- elementRemoved = true;
- break;
- }
- next++;
- }
- if (!elementRemoved) {
- begin++;
- }
- }
- return sortedEntities;
-}
-
-function recursiveDelete(entities, childrenList, deletedIDs, entityHostType) {
- var wantDebug = false;
- var entitiesLength = entities.length;
- var initialPropertySets = Entities.getMultipleEntityProperties(entities);
- var entityHostTypes = Entities.getMultipleEntityProperties(entities, 'entityHostType');
- for (var i = 0; i < entitiesLength; ++i) {
- var entityID = entities[i];
-
- if (entityHostTypes[i].entityHostType !== entityHostType) {
- if (wantDebug) {
- console.log("Skipping deletion of entity " + entityID + " with conflicting entityHostType: " +
- entityHostTypes[i].entityHostType + ", expected: " + entityHostType);
- }
- continue;
- }
-
- var children = Entities.getChildrenIDs(entityID);
- var grandchildrenList = [];
- recursiveDelete(children, grandchildrenList, deletedIDs, entityHostType);
- childrenList.push({
- entityID: entityID,
- properties: initialPropertySets[i],
- children: grandchildrenList
- });
- deletedIDs.push(entityID);
- Entities.deleteEntity(entityID);
- }
-}
-
-function unparentSelectedEntities() {
- if (SelectionManager.hasSelection()) {
- var selectedEntities = selectionManager.selections;
- var parentCheck = false;
-
- if (selectedEntities.length < 1) {
- Window.notifyEditError("You must have an entity selected in order to unparent it.");
- return;
- }
- selectedEntities.forEach(function (id, index) {
- var parentId = Entities.getEntityProperties(id, ["parentID"]).parentID;
- if (parentId !== null && parentId.length > 0 && parentId !== Uuid.NULL) {
- parentCheck = true;
- }
- Entities.editEntity(id, {parentID: null});
- return true;
- });
- if (parentCheck) {
- if (selectedEntities.length > 1) {
- Window.notify("Entities unparented");
- } else {
- Window.notify("Entity unparented");
- }
- } else {
- if (selectedEntities.length > 1) {
- Window.notify("Selected Entities have no parents");
- } else {
- Window.notify("Selected Entity does not have a parent");
- }
- }
- } else {
- Window.notifyEditError("You have nothing selected to unparent");
- }
-}
-function parentSelectedEntities() {
- if (SelectionManager.hasSelection()) {
- var selectedEntities = selectionManager.selections;
- if (selectedEntities.length <= 1) {
- Window.notifyEditError("You must have multiple entities selected in order to parent them");
- return;
- }
- var parentCheck = false;
- var lastEntityId = selectedEntities[selectedEntities.length - 1];
- selectedEntities.forEach(function (id, index) {
- if (lastEntityId !== id) {
- var parentId = Entities.getEntityProperties(id, ["parentID"]).parentID;
- if (parentId !== lastEntityId) {
- parentCheck = true;
- }
- Entities.editEntity(id, {parentID: lastEntityId});
- }
- });
-
- if (parentCheck) {
- Window.notify("Entities parented");
- } else {
- Window.notify("Entities are already parented to last");
- }
- } else {
- Window.notifyEditError("You have nothing selected to parent");
- }
-}
-function deleteSelectedEntities() {
- if (SelectionManager.hasSelection()) {
- var deletedIDs = [];
-
- SelectionManager.saveProperties();
- var savedProperties = [];
- var newSortedSelection = sortSelectedEntities(selectionManager.selections);
- var entityHostTypes = Entities.getMultipleEntityProperties(newSortedSelection, 'entityHostType');
- for (var i = 0; i < newSortedSelection.length; ++i) {
- var entityID = newSortedSelection[i];
- var initialProperties = SelectionManager.savedProperties[entityID];
- if (initialProperties.locked ||
- (initialProperties.avatarEntity && initialProperties.owningAvatarID !== MyAvatar.sessionUUID)) {
- continue;
- }
- var children = Entities.getChildrenIDs(entityID);
- var childList = [];
- recursiveDelete(children, childList, deletedIDs, entityHostTypes[i].entityHostType);
- savedProperties.push({
- entityID: entityID,
- properties: initialProperties,
- children: childList
- });
- deletedIDs.push(entityID);
- Entities.deleteEntity(entityID);
- }
-
- if (savedProperties.length > 0) {
- SelectionManager.clearSelections(this);
- pushCommandForSelections([], savedProperties);
- entityListTool.deleteEntities(deletedIDs);
- }
- }
-}
-
-function toggleSelectedEntitiesLocked() {
- if (SelectionManager.hasSelection()) {
- var locked = !Entities.getEntityProperties(SelectionManager.selections[0], ["locked"]).locked;
- for (var i = 0; i < selectionManager.selections.length; i++) {
- var entityID = SelectionManager.selections[i];
- Entities.editEntity(entityID, {
- locked: locked
- });
- }
- entityListTool.sendUpdate();
- selectionManager._update(false, this);
- }
-}
-
-function toggleSelectedEntitiesVisible() {
- if (SelectionManager.hasSelection()) {
- var visible = !Entities.getEntityProperties(SelectionManager.selections[0], ["visible"]).visible;
- for (var i = 0; i < selectionManager.selections.length; i++) {
- var entityID = SelectionManager.selections[i];
- Entities.editEntity(entityID, {
- visible: visible
- });
- }
- entityListTool.sendUpdate();
- selectionManager._update(false, this);
- }
-}
-
-function onFileSaveChanged(filename) {
- Window.saveFileChanged.disconnect(onFileSaveChanged);
- if (filename !== "") {
- var success = Clipboard.exportEntities(filename, selectionManager.selections);
- if (!success) {
- Window.notifyEditError("Export failed.");
- }
- }
-}
-
-function onFileOpenChanged(filename) {
- // disconnect the event, otherwise the requests will stack up
- try {
- // Not all calls to onFileOpenChanged() connect an event.
- Window.browseChanged.disconnect(onFileOpenChanged);
- } catch (e) {
- // Ignore.
- }
-
- var importURL = null;
- if (filename !== "") {
- importURL = filename;
- if (!/^(http|https):\/\//.test(filename)) {
- importURL = "file:///" + importURL;
- }
- }
- if (importURL) {
- if (!isActive && (Entities.canRez() && Entities.canRezTmp() && Entities.canRezCertified() && Entities.canRezTmpCertified())) {
- toolBar.toggle();
- }
- importSVO(importURL);
- }
-}
-
-function onPromptTextChanged(prompt) {
- Window.promptTextChanged.disconnect(onPromptTextChanged);
- if (prompt !== "") {
- if (!isActive && (Entities.canRez() && Entities.canRezTmp() && Entities.canRezCertified() && Entities.canRezTmpCertified())) {
- toolBar.toggle();
- }
- importSVO(prompt);
- }
-}
-
-function handleMenuEvent(menuItem) {
- if (menuItem === "Allow Selecting of Small Models") {
- allowSmallModels = Menu.isOptionChecked("Allow Selecting of Small Models");
- } else if (menuItem === "Allow Selecting of Large Models") {
- allowLargeModels = Menu.isOptionChecked("Allow Selecting of Large Models");
- } else if (menuItem === "Allow Selecting of Lights") {
- Entities.setLightsArePickable(Menu.isOptionChecked("Allow Selecting of Lights"));
- } else if (menuItem === "Delete") {
- deleteSelectedEntities();
- } else if (menuItem === "Undo") {
- undoHistory.undo();
- } else if (menuItem === "Redo") {
- undoHistory.redo();
- } else if (menuItem === "Parent Entity to Last") {
- parentSelectedEntities();
- } else if (menuItem === "Unparent Entity") {
- unparentSelectedEntities();
- } else if (menuItem === "Export Entities") {
- if (!selectionManager.hasSelection()) {
- Window.notifyEditError("No entities have been selected.");
- } else {
- Window.saveFileChanged.connect(onFileSaveChanged);
- Window.saveAsync("Select Where to Save", "", "*.json");
- }
- } else if (menuItem === "Import Entities" || menuItem === "Import Entities from URL") {
- if (menuItem === "Import Entities") {
- Window.browseChanged.connect(onFileOpenChanged);
- Window.browseAsync("Select Model to Import", "", "*.json");
- } else {
- Window.promptTextChanged.connect(onPromptTextChanged);
- Window.promptAsync("URL of SVO to import", "");
- }
- } else if (menuItem === "Select All Entities In Box") {
- selectAllEntitiesInCurrentSelectionBox(false);
- } else if (menuItem === "Select All Entities Touching Box") {
- selectAllEntitiesInCurrentSelectionBox(true);
- } else if (menuItem === MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE) {
- entityIconOverlayManager.setVisible(isActive && Menu.isOptionChecked(MENU_SHOW_LIGHTS_AND_PARTICLES_IN_EDIT_MODE));
- } else if (menuItem === MENU_SHOW_ZONES_IN_EDIT_MODE) {
- Entities.setDrawZoneBoundaries(isActive && Menu.isOptionChecked(MENU_SHOW_ZONES_IN_EDIT_MODE));
- } else if (menuItem === MENU_CREATE_ENTITIES_GRABBABLE) {
- Settings.setValue(SETTING_EDIT_PREFIX + menuItem, Menu.isOptionChecked(menuItem));
- }
- tooltip.show(false);
-}
-
-var HALF_TREE_SCALE = 16384;
-
-function getPositionToCreateEntity(extra) {
- var CREATE_DISTANCE = 2;
- var position;
- var delta = extra !== undefined ? extra : 0;
- if (Camera.mode === "entity" || Camera.mode === "independent") {
- position = Vec3.sum(Camera.position, Vec3.multiply(Quat.getForward(Camera.orientation), CREATE_DISTANCE + delta));
- } else {
- position = Vec3.sum(MyAvatar.position, Vec3.multiply(Quat.getForward(MyAvatar.orientation), CREATE_DISTANCE + delta));
- }
-
- if (position.x > HALF_TREE_SCALE || position.y > HALF_TREE_SCALE || position.z > HALF_TREE_SCALE) {
- return null;
- }
- return position;
-}
-
-function importSVO(importURL) {
- if (!Entities.canRez() && !Entities.canRezTmp() &&
- !Entities.canRezCertified() && !Entities.canRezTmpCertified()) {
- Window.notifyEditError(INSUFFICIENT_PERMISSIONS_IMPORT_ERROR_MSG);
- return;
- }
-
- Overlays.editOverlay(importingSVOTextOverlay, {
- visible: true
- });
- Overlays.editOverlay(importingSVOImageOverlay, {
- visible: true
- });
-
- var success = Clipboard.importEntities(importURL);
-
- if (success) {
- var VERY_LARGE = 10000;
- var isLargeImport = Clipboard.getClipboardContentsLargestDimension() >= VERY_LARGE;
- var position = Vec3.ZERO;
- if (!isLargeImport) {
- position = getPositionToCreateEntity(Clipboard.getClipboardContentsLargestDimension() / 2);
- }
- if (position !== null && position !== undefined) {
- var pastedEntityIDs = Clipboard.pasteEntities(position);
- if (!isLargeImport) {
- // The first entity in Clipboard gets the specified position with the rest being relative to it. Therefore, move
- // entities after they're imported so that they're all the correct distance in front of and with geometric mean
- // centered on the avatar/camera direction.
- var deltaPosition = Vec3.ZERO;
- var entityPositions = [];
- var entityParentIDs = [];
-
- var propType = Entities.getEntityProperties(pastedEntityIDs[0], ["type"]).type;
- var NO_ADJUST_ENTITY_TYPES = ["Zone", "Light", "ParticleEffect"];
- if (NO_ADJUST_ENTITY_TYPES.indexOf(propType) === -1) {
- var targetDirection;
- if (Camera.mode === "entity" || Camera.mode === "independent") {
- targetDirection = Camera.orientation;
- } else {
- targetDirection = MyAvatar.orientation;
- }
- targetDirection = Vec3.multiplyQbyV(targetDirection, Vec3.UNIT_Z);
-
- var targetPosition = getPositionToCreateEntity();
- var deltaParallel = HALF_TREE_SCALE; // Distance to move entities parallel to targetDirection.
- var deltaPerpendicular = Vec3.ZERO; // Distance to move entities perpendicular to targetDirection.
- for (var i = 0, length = pastedEntityIDs.length; i < length; i++) {
- var curLoopEntityProps = Entities.getEntityProperties(pastedEntityIDs[i], ["position", "dimensions",
- "registrationPoint", "rotation", "parentID"]);
- var adjustedPosition = adjustPositionPerBoundingBox(targetPosition, targetDirection,
- curLoopEntityProps.registrationPoint, curLoopEntityProps.dimensions, curLoopEntityProps.rotation);
- var delta = Vec3.subtract(adjustedPosition, curLoopEntityProps.position);
- var distance = Vec3.dot(delta, targetDirection);
- deltaParallel = Math.min(distance, deltaParallel);
- deltaPerpendicular = Vec3.sum(Vec3.subtract(delta, Vec3.multiply(distance, targetDirection)),
- deltaPerpendicular);
- entityPositions[i] = curLoopEntityProps.position;
- entityParentIDs[i] = curLoopEntityProps.parentID;
- }
- deltaPerpendicular = Vec3.multiply(1 / pastedEntityIDs.length, deltaPerpendicular);
- deltaPosition = Vec3.sum(Vec3.multiply(deltaParallel, targetDirection), deltaPerpendicular);
- }
-
- if (grid.getSnapToGrid()) {
- var firstEntityProps = Entities.getEntityProperties(pastedEntityIDs[0], ["position", "dimensions",
- "registrationPoint"]);
- var positionPreSnap = Vec3.sum(deltaPosition, firstEntityProps.position);
- position = grid.snapToSurface(grid.snapToGrid(positionPreSnap, false, firstEntityProps.dimensions,
- firstEntityProps.registrationPoint), firstEntityProps.dimensions, firstEntityProps.registrationPoint);
- deltaPosition = Vec3.subtract(position, firstEntityProps.position);
- }
-
- if (!Vec3.equal(deltaPosition, Vec3.ZERO)) {
- for (var editEntityIndex = 0, numEntities = pastedEntityIDs.length; editEntityIndex < numEntities; editEntityIndex++) {
- if (Uuid.isNull(entityParentIDs[editEntityIndex])) {
- Entities.editEntity(pastedEntityIDs[editEntityIndex], {
- position: Vec3.sum(deltaPosition, entityPositions[editEntityIndex])
- });
- }
- }
- }
- }
-
- if (isActive) {
- selectionManager.setSelections(pastedEntityIDs, this);
- }
- } else {
- Window.notifyEditError("Can't import entities: entities would be out of bounds.");
- }
- } else {
- Window.notifyEditError("There was an error importing the entity file.");
- }
-
- Overlays.editOverlay(importingSVOTextOverlay, {
- visible: false
- });
- Overlays.editOverlay(importingSVOImageOverlay, {
- visible: false
- });
-}
-Window.svoImportRequested.connect(importSVO);
-
-Menu.menuItemEvent.connect(handleMenuEvent);
-
-var keyPressEvent = function (event) {
- if (isActive) {
- cameraManager.keyPressEvent(event);
- }
-};
-var keyReleaseEvent = function (event) {
- if (isActive) {
- cameraManager.keyReleaseEvent(event);
- }
-};
-Controller.keyReleaseEvent.connect(keyReleaseEvent);
-Controller.keyPressEvent.connect(keyPressEvent);
-
-function deleteKey(value) {
- if (value === 0) { // on release
- deleteSelectedEntities();
- }
-}
-function deselectKey(value) {
- if (value === 0) { // on release
- selectionManager.clearSelections(this);
- }
-}
-function toggleKey(value) {
- if (value === 0) { // on release
- selectionDisplay.toggleSpaceMode();
- }
-}
-function focusKey(value) {
- if (value === 0) { // on release
- cameraManager.enable();
- if (selectionManager.hasSelection()) {
- cameraManager.focus(selectionManager.worldPosition, selectionManager.worldDimensions,
- Menu.isOptionChecked(MENU_EASE_ON_FOCUS));
- }
- }
-}
-function gridKey(value) {
- if (value === 0) { // on release
- if (selectionManager.hasSelection()) {
- grid.moveToSelection();
- }
- }
-}
-function recursiveAdd(newParentID, parentData) {
- if (parentData.children !== undefined) {
- var children = parentData.children;
- for (var i = 0; i < children.length; i++) {
- var childProperties = children[i].properties;
- childProperties.parentID = newParentID;
- var newChildID = Entities.addEntity(childProperties);
- recursiveAdd(newChildID, children[i]);
- }
- }
-}
-
-var UndoHistory = function(onUpdate) {
- this.history = [];
- // The current position is the index of the last executed action in the history array.
- //
- // -1 0 1 2 3 <- position
- // A B C D <- actions in history
- //
- // If our lastExecutedIndex is 1, the last executed action is B.
- // If we undo, we undo B (index 1). If we redo, we redo C (index 2).
- this.lastExecutedIndex = -1;
- this.enabled = true;
- this.onUpdate = onUpdate;
-};
-
-UndoHistory.prototype.pushCommand = function(undoFn, undoArgs, redoFn, redoArgs) {
- if (!this.enabled) {
- return;
- }
- // Delete any history following the last executed action.
- this.history.splice(this.lastExecutedIndex + 1);
- this.history.push({
- undoFn: undoFn,
- undoArgs: undoArgs,
- redoFn: redoFn,
- redoArgs: redoArgs
- });
- this.lastExecutedIndex++;
-
- if (this.onUpdate) {
- this.onUpdate();
- }
-};
-UndoHistory.prototype.setEnabled = function(enabled) {
- this.enabled = enabled;
- if (this.onUpdate) {
- this.onUpdate();
- }
-};
-UndoHistory.prototype.canUndo = function() {
- return this.enabled && this.lastExecutedIndex >= 0;
-};
-UndoHistory.prototype.canRedo = function() {
- return this.enabled && this.lastExecutedIndex < this.history.length - 1;
-};
-UndoHistory.prototype.undo = function() {
- if (!this.canUndo()) {
- console.warn("Cannot undo action");
- return;
- }
-
- var command = this.history[this.lastExecutedIndex];
- command.undoFn(command.undoArgs);
- this.lastExecutedIndex--;
-
- if (this.onUpdate) {
- this.onUpdate();
- }
-};
-UndoHistory.prototype.redo = function() {
- if (!this.canRedo()) {
- console.warn("Cannot redo action");
- return;
- }
-
- var command = this.history[this.lastExecutedIndex + 1];
- command.redoFn(command.redoArgs);
- this.lastExecutedIndex++;
-
- if (this.onUpdate) {
- this.onUpdate();
- }
-};
-
-function updateUndoRedoMenuItems() {
- Menu.setMenuEnabled("Edit > Undo", undoHistory.canUndo());
- Menu.setMenuEnabled("Edit > Redo", undoHistory.canRedo());
-}
-var undoHistory = new UndoHistory(updateUndoRedoMenuItems);
-updateUndoRedoMenuItems();
-
-// When an entity has been deleted we need a way to "undo" this deletion. Because it's not currently
-// possible to create an entity with a specific id, earlier undo commands to the deleted entity
-// will fail if there isn't a way to find the new entity id.
-var DELETED_ENTITY_MAP = {};
-
-function applyEntityProperties(data) {
- var editEntities = data.editEntities;
- var createEntities = data.createEntities;
- var deleteEntities = data.deleteEntities;
- var selectedEntityIDs = [];
- var selectEdits = createEntities.length === 0 || !data.selectCreated;
- var i, entityID, entityProperties;
- for (i = 0; i < createEntities.length; i++) {
- entityID = createEntities[i].entityID;
- entityProperties = createEntities[i].properties;
- var newEntityID = Entities.addEntity(entityProperties);
- recursiveAdd(newEntityID, createEntities[i]);
- DELETED_ENTITY_MAP[entityID] = newEntityID;
- if (data.selectCreated) {
- selectedEntityIDs.push(newEntityID);
- }
- }
- for (i = 0; i < deleteEntities.length; i++) {
- entityID = deleteEntities[i].entityID;
- if (DELETED_ENTITY_MAP[entityID] !== undefined) {
- entityID = DELETED_ENTITY_MAP[entityID];
- }
- Entities.deleteEntity(entityID);
- var index = selectedEntityIDs.indexOf(entityID);
- if (index >= 0) {
- selectedEntityIDs.splice(index, 1);
- }
- }
- for (i = 0; i < editEntities.length; i++) {
- entityID = editEntities[i].entityID;
- if (DELETED_ENTITY_MAP[entityID] !== undefined) {
- entityID = DELETED_ENTITY_MAP[entityID];
- }
- entityProperties = editEntities[i].properties;
- if (entityProperties !== null) {
- Entities.editEntity(entityID, entityProperties);
- }
- if (selectEdits) {
- selectedEntityIDs.push(entityID);
- }
- }
-
- // We might be getting an undo while edit.js is disabled. If that is the case, don't set
- // our selections, causing the edit widgets to display.
- if (isActive) {
- selectionManager.setSelections(selectedEntityIDs, this);
- selectionManager.saveProperties();
- }
-}
-
-// For currently selected entities, push a command to the UndoStack that uses the current entity properties for the
-// redo command, and the saved properties for the undo command. Also, include create and delete entity data.
-function pushCommandForSelections(createdEntityData, deletedEntityData, doNotSaveEditProperties) {
- doNotSaveEditProperties = false;
- var undoData = {
- editEntities: [],
- createEntities: deletedEntityData || [],
- deleteEntities: createdEntityData || [],
- selectCreated: true
- };
- var redoData = {
- editEntities: [],
- createEntities: createdEntityData || [],
- deleteEntities: deletedEntityData || [],
- selectCreated: true
- };
- for (var i = 0; i < SelectionManager.selections.length; i++) {
- var entityID = SelectionManager.selections[i];
- var initialProperties = SelectionManager.savedProperties[entityID];
- var currentProperties = null;
- if (!initialProperties) {
- continue;
- }
-
- if (doNotSaveEditProperties) {
- initialProperties = null;
- } else {
- currentProperties = Entities.getEntityProperties(entityID);
- }
-
- undoData.editEntities.push({
- entityID: entityID,
- properties: initialProperties
- });
- redoData.editEntities.push({
- entityID: entityID,
- properties: currentProperties
- });
- }
- undoHistory.pushCommand(applyEntityProperties, undoData, applyEntityProperties, redoData);
-}
-
-var ServerScriptStatusMonitor = function(entityID, statusCallback) {
- var self = this;
-
- self.entityID = entityID;
- self.active = true;
- self.sendRequestTimerID = null;
-
- var onStatusReceived = function(success, isRunning, status, errorInfo) {
- if (self.active) {
- statusCallback({
- statusRetrieved: success,
- isRunning: isRunning,
- status: status,
- errorInfo: errorInfo
- });
- self.sendRequestTimerID = Script.setTimeout(function() {
- if (self.active) {
- Entities.getServerScriptStatus(entityID, onStatusReceived);
- }
- }, 1000);
- }
- };
- self.stop = function() {
- self.active = false;
- };
-
- Entities.getServerScriptStatus(entityID, onStatusReceived);
-};
-
-var PropertiesTool = function (opts) {
- var that = {};
-
- var webView = null;
- webView = Tablet.getTablet("com.highfidelity.interface.tablet.system");
- webView.setVisible = function(value) {};
-
- var visible = false;
-
- // This keeps track of the last entity ID that was selected. If multiple entities
- // are selected or if no entity is selected this will be `null`.
- var currentSelectedEntityID = null;
- var statusMonitor = null;
- var blockPropertyUpdates = false;
-
- that.setVisible = function (newVisible) {
- visible = newVisible;
- webView.setVisible(shouldUseEditTabletApp() && visible);
- createToolsWindow.setVisible(!shouldUseEditTabletApp() && visible);
- };
-
- that.setVisible(false);
-
- function emitScriptEvent(data) {
- var dataString = JSON.stringify(data);
- webView.emitScriptEvent(dataString);
- createToolsWindow.emitScriptEvent(dataString);
- }
-
- function updateScriptStatus(info) {
- info.type = "server_script_status";
- emitScriptEvent(info);
- }
-
- function resetScriptStatus() {
- updateScriptStatus({
- statusRetrieved: undefined,
- isRunning: undefined,
- status: "",
- errorInfo: ""
- });
- }
-
- that.setSpaceMode = function(spaceMode) {
- emitScriptEvent({
- type: 'setSpaceMode',
- spaceMode: spaceMode
- })
- };
-
- function updateSelections(selectionUpdated, caller) {
- if (blockPropertyUpdates) {
- return;
- }
-
- var data = {
- type: 'update',
- spaceMode: selectionDisplay.getSpaceMode(),
- isPropertiesToolUpdate: caller === this,
- };
-
- if (selectionUpdated) {
- resetScriptStatus();
-
- if (selectionManager.selections.length !== 1) {
- if (statusMonitor !== null) {
- statusMonitor.stop();
- statusMonitor = null;
- }
- currentSelectedEntityID = null;
- } else if (currentSelectedEntityID !== selectionManager.selections[0]) {
- if (statusMonitor !== null) {
- statusMonitor.stop();
- }
- var entityID = selectionManager.selections[0];
- currentSelectedEntityID = entityID;
- statusMonitor = new ServerScriptStatusMonitor(entityID, updateScriptStatus);
- }
- }
-
- var selections = [];
- for (var i = 0; i < selectionManager.selections.length; i++) {
- var entity = {};
- entity.id = selectionManager.selections[i];
- entity.properties = Entities.getEntityProperties(selectionManager.selections[i]);
- if (entity.properties.rotation !== undefined) {
- entity.properties.rotation = Quat.safeEulerAngles(entity.properties.rotation);
- }
- if (entity.properties.localRotation !== undefined) {
- entity.properties.localRotation = Quat.safeEulerAngles(entity.properties.localRotation);
- }
- if (entity.properties.emitOrientation !== undefined) {
- entity.properties.emitOrientation = Quat.safeEulerAngles(entity.properties.emitOrientation);
- }
- if (entity.properties.keyLight !== undefined && entity.properties.keyLight.direction !== undefined) {
- entity.properties.keyLight.direction = Vec3.toPolar(entity.properties.keyLight.direction);
- entity.properties.keyLight.direction.z = 0.0;
- }
- selections.push(entity);
- }
- data.selections = selections;
-
- emitScriptEvent(data);
- }
- selectionManager.addEventListener(updateSelections, this);
-
-
- var onWebEventReceived = function(data) {
- try {
- data = JSON.parse(data);
- } catch(e) {
- return;
- }
- var i, properties, dY, diff, newPosition;
- if (data.type === "update") {
-
- if (data.properties || data.propertiesMap) {
- var propertiesMap = data.propertiesMap;
- if (propertiesMap === undefined) {
- propertiesMap = [{
- entityIDs: data.ids,
- properties: data.properties,
- }];
- }
-
- var sendListUpdate = false;
- propertiesMap.forEach(function(propertiesObject) {
- var properties = propertiesObject.properties;
- var updateEntityIDs = propertiesObject.entityIDs;
- if (properties.dynamic === false) {
- // this object is leaving dynamic, so we zero its velocities
- properties.localVelocity = Vec3.ZERO;
- properties.localAngularVelocity = Vec3.ZERO;
- }
- if (properties.rotation !== undefined) {
- properties.rotation = Quat.fromVec3Degrees(properties.rotation);
- }
- if (properties.localRotation !== undefined) {
- properties.localRotation = Quat.fromVec3Degrees(properties.localRotation);
- }
- if (properties.emitOrientation !== undefined) {
- properties.emitOrientation = Quat.fromVec3Degrees(properties.emitOrientation);
- }
- if (properties.keyLight !== undefined && properties.keyLight.direction !== undefined) {
- var currentKeyLightDirection = Vec3.toPolar(Entities.getEntityProperties(selectionManager.selections[0], ['keyLight.direction']).keyLight.direction);
- if (properties.keyLight.direction.x === undefined) {
- properties.keyLight.direction.x = currentKeyLightDirection.x;
- }
- if (properties.keyLight.direction.y === undefined) {
- properties.keyLight.direction.y = currentKeyLightDirection.y;
- }
- properties.keyLight.direction = Vec3.fromPolar(properties.keyLight.direction.x, properties.keyLight.direction.y);
- }
-
- updateEntityIDs.forEach(function (entityID) {
- Entities.editEntity(entityID, properties);
- });
-
- if (properties.name !== undefined || properties.modelURL !== undefined || properties.materialURL !== undefined ||
- properties.visible !== undefined || properties.locked !== undefined) {
-
- sendListUpdate = true;
- }
-
- });
- if (sendListUpdate) {
- entityListTool.sendUpdate();
- }
- }
-
-
- if (data.onlyUpdateEntities) {
- blockPropertyUpdates = true;
- } else {
- pushCommandForSelections();
- SelectionManager.saveProperties();
- }
- selectionManager._update(false, this);
- blockPropertyUpdates = false;
- } else if (data.type === 'saveUserData' || data.type === 'saveMaterialData') {
- data.ids.forEach(function(entityID) {
- Entities.editEntity(entityID, data.properties);
- });
- } else if (data.type === "showMarketplace") {
- showMarketplace();
- } else if (data.type === "action") {
- if (data.action === "moveSelectionToGrid") {
- if (selectionManager.hasSelection()) {
- selectionManager.saveProperties();
- dY = grid.getOrigin().y - (selectionManager.worldPosition.y - selectionManager.worldDimensions.y / 2);
- diff = {
- x: 0,
- y: dY,
- z: 0
- };
- for (i = 0; i < selectionManager.selections.length; i++) {
- properties = selectionManager.savedProperties[selectionManager.selections[i]];
- newPosition = Vec3.sum(properties.position, diff);
- Entities.editEntity(selectionManager.selections[i], {
- position: newPosition
- });
- }
- pushCommandForSelections();
- selectionManager._update(false, this);
- }
- } else if (data.action === "moveAllToGrid") {
- if (selectionManager.hasSelection()) {
- selectionManager.saveProperties();
- for (i = 0; i < selectionManager.selections.length; i++) {
- properties = selectionManager.savedProperties[selectionManager.selections[i]];
- var bottomY = properties.boundingBox.center.y - properties.boundingBox.dimensions.y / 2;
- dY = grid.getOrigin().y - bottomY;
- diff = {
- x: 0,
- y: dY,
- z: 0
- };
- newPosition = Vec3.sum(properties.position, diff);
- Entities.editEntity(selectionManager.selections[i], {
- position: newPosition
- });
- }
- pushCommandForSelections();
- selectionManager._update(false, this);
- }
- } else if (data.action === "resetToNaturalDimensions") {
- if (selectionManager.hasSelection()) {
- selectionManager.saveProperties();
- for (i = 0; i < selectionManager.selections.length; i++) {
- properties = selectionManager.savedProperties[selectionManager.selections[i]];
- var naturalDimensions = properties.naturalDimensions;
-
- // If any of the natural dimensions are not 0, resize
- if (properties.type === "Model" && naturalDimensions.x === 0 && naturalDimensions.y === 0 &&
- naturalDimensions.z === 0) {
- Window.notifyEditError("Cannot reset entity to its natural dimensions: Model URL" +
- " is invalid or the model has not yet been loaded.");
- } else {
- Entities.editEntity(selectionManager.selections[i], {
- dimensions: properties.naturalDimensions
- });
- }
- }
- pushCommandForSelections();
- selectionManager._update(false, this);
- }
- } else if (data.action === "previewCamera") {
- if (selectionManager.hasSelection()) {
- Camera.mode = "entity";
- Camera.cameraEntity = selectionManager.selections[0];
- }
- } else if (data.action === "rescaleDimensions") {
- var multiplier = data.percentage / 100.0;
- if (selectionManager.hasSelection()) {
- selectionManager.saveProperties();
- for (i = 0; i < selectionManager.selections.length; i++) {
- properties = selectionManager.savedProperties[selectionManager.selections[i]];
- Entities.editEntity(selectionManager.selections[i], {
- dimensions: Vec3.multiply(multiplier, properties.dimensions)
- });
- }
- pushCommandForSelections();
- selectionManager._update(false, this);
- }
- } else if (data.action === "reloadClientScripts") {
- if (selectionManager.hasSelection()) {
- var timestamp = Date.now();
- for (i = 0; i < selectionManager.selections.length; i++) {
- Entities.editEntity(selectionManager.selections[i], {
- scriptTimestamp: timestamp
- });
- }
- }
- } else if (data.action === "reloadServerScripts") {
- if (selectionManager.hasSelection()) {
- for (i = 0; i < selectionManager.selections.length; i++) {
- Entities.reloadServerScripts(selectionManager.selections[i]);
- }
- }
- }
- } else if (data.type === "propertiesPageReady") {
- updateSelections(true);
- } else if (data.type === "tooltipsRequest") {
- emitScriptEvent({
- type: 'tooltipsReply',
- tooltips: Script.require('./assets/data/createAppTooltips.json'),
- hmdActive: HMD.active,
- });
- } else if (data.type === "propertyRangeRequest") {
- var propertyRanges = {};
- data.properties.forEach(function (property) {
- propertyRanges[property] = Entities.getPropertyInfo(property);
- });
- emitScriptEvent({
- type: 'propertyRangeReply',
- propertyRanges: propertyRanges,
- });
- } else if (data.type === "materialTargetRequest") {
- var parentModelData;
- var properties = Entities.getEntityProperties(data.entityID, ["type", "parentID"]);
- if (properties.type === "Material" && properties.parentID !== Uuid.NULL) {
- var parentType = Entities.getEntityProperties(properties.parentID, ["type"]).type;
- if (parentType === "Model" || Entities.getNestableType(properties.parentID) === "avatar") {
- parentModelData = Graphics.getModel(properties.parentID);
- } else if (parentType === "Shape" || parentType === "Box" || parentType === "Sphere") {
- parentModelData = {};
- parentModelData.numMeshes = 1;
- parentModelData.materialNames = [];
- }
- }
- emitScriptEvent({
- type: 'materialTargetReply',
- entityID: data.entityID,
- materialTargetData: parentModelData,
- });
- }
- };
-
- HMD.displayModeChanged.connect(function() {
- emitScriptEvent({
- type: 'hmdActiveChanged',
- hmdActive: HMD.active,
- });
- });
-
- createToolsWindow.webEventReceived.addListener(this, onWebEventReceived);
-
- webView.webEventReceived.connect(this, onWebEventReceived);
-
- return that;
-};
-
-
-var PopupMenu = function () {
- var self = this;
-
- var MENU_ITEM_HEIGHT = 21;
- var MENU_ITEM_SPACING = 1;
- var TEXT_MARGIN = 7;
-
- var overlays = [];
- var overlayInfo = {};
-
- var visible = false;
-
- var upColor = {
- red: 0,
- green: 0,
- blue: 0
- };
- var downColor = {
- red: 192,
- green: 192,
- blue: 192
- };
- var overColor = {
- red: 128,
- green: 128,
- blue: 128
- };
-
- self.onSelectMenuItem = function () {};
-
- self.addMenuItem = function (name) {
- var id = Overlays.addOverlay("text", {
- text: name,
- backgroundAlpha: 1.0,
- backgroundColor: upColor,
- topMargin: TEXT_MARGIN,
- leftMargin: TEXT_MARGIN,
- width: 210,
- height: MENU_ITEM_HEIGHT,
- font: {
- size: 12
- },
- visible: false
- });
- overlays.push(id);
- overlayInfo[id] = {
- name: name
- };
- return id;
- };
-
- self.updateMenuItemText = function (id, newText) {
- Overlays.editOverlay(id, {
- text: newText
- });
- };
-
- self.setPosition = function (x, y) {
- for (var key in overlayInfo) {
- Overlays.editOverlay(key, {
- x: x,
- y: y
- });
- y += MENU_ITEM_HEIGHT + MENU_ITEM_SPACING;
- }
- };
-
- self.onSelected = function () {};
-
- var pressingOverlay = null;
- var hoveringOverlay = null;
-
- self.mousePressEvent = function (event) {
- if (event.isLeftButton) {
- var overlay = Overlays.getOverlayAtPoint({
- x: event.x,
- y: event.y
- });
- if (overlay in overlayInfo) {
- pressingOverlay = overlay;
- Overlays.editOverlay(pressingOverlay, {
- backgroundColor: downColor
- });
- } else {
- self.hide();
- }
- return false;
- }
- };
- self.mouseMoveEvent = function (event) {
- if (visible) {
- var overlay = Overlays.getOverlayAtPoint({
- x: event.x,
- y: event.y
- });
- if (!pressingOverlay) {
- if (hoveringOverlay !== null && overlay !== hoveringOverlay) {
- Overlays.editOverlay(hoveringOverlay, {
- backgroundColor: upColor
- });
- hoveringOverlay = null;
- }
- if (overlay !== hoveringOverlay && overlay in overlayInfo) {
- Overlays.editOverlay(overlay, {
- backgroundColor: overColor
- });
- hoveringOverlay = overlay;
- }
- }
- }
- return false;
- };
- self.mouseReleaseEvent = function (event) {
- var overlay = Overlays.getOverlayAtPoint({
- x: event.x,
- y: event.y
- });
- if (pressingOverlay !== null && pressingOverlay !== undefined) {
- if (overlay === pressingOverlay) {
- self.onSelectMenuItem(overlayInfo[overlay].name);
- }
- Overlays.editOverlay(pressingOverlay, {
- backgroundColor: upColor
- });
- pressingOverlay = null;
- self.hide();
- }
- };
-
- self.setVisible = function (newVisible) {
- if (newVisible !== visible) {
- visible = newVisible;
- for (var key in overlayInfo) {
- Overlays.editOverlay(key, {
- visible: newVisible
- });
- }
- }
- };
- self.show = function () {
- self.setVisible(true);
- };
- self.hide = function () {
- self.setVisible(false);
- };
-
- function cleanup() {
- ContextOverlay.enabled = true;
- for (var i = 0; i < overlays.length; i++) {
- Overlays.deleteOverlay(overlays[i]);
- }
- Controller.mousePressEvent.disconnect(self.mousePressEvent);
- Controller.mouseMoveEvent.disconnect(self.mouseMoveEvent);
- Controller.mouseReleaseEvent.disconnect(self.mouseReleaseEvent);
-
- Entities.canRezChanged.disconnect(checkEditPermissionsAndUpdate);
- Entities.canRezTmpChanged.disconnect(checkEditPermissionsAndUpdate);
- Entities.canRezCertifiedChanged.disconnect(checkEditPermissionsAndUpdate);
- Entities.canRezTmpCertifiedChanged.disconnect(checkEditPermissionsAndUpdate);
- }
-
- Controller.mousePressEvent.connect(self.mousePressEvent);
- Controller.mouseMoveEvent.connect(self.mouseMoveEvent);
- Controller.mouseReleaseEvent.connect(self.mouseReleaseEvent);
- Script.scriptEnding.connect(cleanup);
-
- return this;
-};
-
-function whenPressed(fn) {
- return function(value) {
- if (value > 0) {
- fn();
- }
- };
-}
-
-function whenReleased(fn) {
- return function(value) {
- if (value === 0) {
- fn();
- }
- };
-}
-
-var isOnMacPlatform = Controller.getValue(Controller.Hardware.Application.PlatformMac);
-
-var mapping = Controller.newMapping(CONTROLLER_MAPPING_NAME);
-if (isOnMacPlatform) {
- mapping.from([Controller.Hardware.Keyboard.Backspace]).to(deleteKey);
-} else {
- mapping.from([Controller.Hardware.Keyboard.Delete]).to(deleteKey);
-}
-mapping.from([Controller.Hardware.Keyboard.T]).to(toggleKey);
-mapping.from([Controller.Hardware.Keyboard.F]).to(focusKey);
-mapping.from([Controller.Hardware.Keyboard.G]).to(gridKey);
-mapping.from([Controller.Hardware.Keyboard.X])
- .when([Controller.Hardware.Keyboard.Control])
- .to(whenReleased(function() { selectionManager.cutSelectedEntities() }));
-mapping.from([Controller.Hardware.Keyboard.C])
- .when([Controller.Hardware.Keyboard.Control])
- .to(whenReleased(function() { selectionManager.copySelectedEntities() }));
-mapping.from([Controller.Hardware.Keyboard.V])
- .when([Controller.Hardware.Keyboard.Control])
- .to(whenReleased(function() { selectionManager.pasteEntities() }));
-mapping.from([Controller.Hardware.Keyboard.D])
- .when([Controller.Hardware.Keyboard.Control])
- .to(whenReleased(function() { selectionManager.duplicateSelection() }));
-
-// Bind undo to ctrl-shift-z to maintain backwards-compatibility
-mapping.from([Controller.Hardware.Keyboard.Z])
- .when([Controller.Hardware.Keyboard.Control, Controller.Hardware.Keyboard.Shift])
- .to(whenPressed(function() { undoHistory.redo() }));
-
-
-mapping.from([Controller.Hardware.Keyboard.P])
- .when([Controller.Hardware.Keyboard.Control, Controller.Hardware.Keyboard.Shift])
- .to(whenReleased(function() { unparentSelectedEntities(); }));
-
-mapping.from([Controller.Hardware.Keyboard.P])
- .when([Controller.Hardware.Keyboard.Control, !Controller.Hardware.Keyboard.Shift])
- .to(whenReleased(function() { parentSelectedEntities(); }));
-
-keyUpEventFromUIWindow = function(keyUpEvent) {
- var WANT_DEBUG_MISSING_SHORTCUTS = false;
-
- var pressedValue = 0.0;
-
- if ((!isOnMacPlatform && keyUpEvent.keyCodeString === "Delete")
- || (isOnMacPlatform && keyUpEvent.keyCodeString === "Backspace")) {
-
- deleteKey(pressedValue);
- } else if (keyUpEvent.keyCodeString === "T") {
- toggleKey(pressedValue);
- } else if (keyUpEvent.keyCodeString === "F") {
- focusKey(pressedValue);
- } else if (keyUpEvent.keyCodeString === "G") {
- gridKey(pressedValue);
- } else if (keyUpEvent.controlKey && keyUpEvent.keyCodeString === "X") {
- selectionManager.cutSelectedEntities();
- } else if (keyUpEvent.controlKey && keyUpEvent.keyCodeString === "C") {
- selectionManager.copySelectedEntities();
- } else if (keyUpEvent.controlKey && keyUpEvent.keyCodeString === "V") {
- selectionManager.pasteEntities();
- } else if (keyUpEvent.controlKey && keyUpEvent.keyCodeString === "D") {
- selectionManager.duplicateSelection();
- } else if (!isOnMacPlatform && keyUpEvent.controlKey && !keyUpEvent.shiftKey && keyUpEvent.keyCodeString === "Z") {
- undoHistory.undo(); // undo is only handled via handleMenuItem on Mac
- } else if (keyUpEvent.controlKey && !keyUpEvent.shiftKey && keyUpEvent.keyCodeString === "P") {
- parentSelectedEntities();
- } else if (keyUpEvent.controlKey && keyUpEvent.shiftKey && keyUpEvent.keyCodeString === "P") {
- unparentSelectedEntities();
- } else if (!isOnMacPlatform &&
- ((keyUpEvent.controlKey && keyUpEvent.shiftKey && keyUpEvent.keyCodeString === "Z") ||
- (keyUpEvent.controlKey && keyUpEvent.keyCodeString === "Y"))) {
- undoHistory.redo(); // redo is only handled via handleMenuItem on Mac
- } else if (WANT_DEBUG_MISSING_SHORTCUTS) {
- console.warn("unhandled key event: " + JSON.stringify(keyUpEvent))
- }
-};
-
-var propertyMenu = new PopupMenu();
-
-propertyMenu.onSelectMenuItem = function (name) {
-
- if (propertyMenu.marketplaceID) {
- showMarketplace(propertyMenu.marketplaceID);
- }
-};
-
-var showMenuItem = propertyMenu.addMenuItem("Show in Marketplace");
-
-var propertiesTool = new PropertiesTool();
-
-selectionDisplay.onSpaceModeChange = function(spaceMode) {
- entityListTool.setSpaceMode(spaceMode);
- propertiesTool.setSpaceMode(spaceMode);
-};
-
-}()); // END LOCAL_SCOPE
diff --git a/scripts/simplifiedUI/system/html/entityList.html b/scripts/simplifiedUI/system/html/entityList.html
deleted file mode 100644
index 986e5c09b0..0000000000
--- a/scripts/simplifiedUI/system/html/entityList.html
+++ /dev/null
@@ -1,93 +0,0 @@
-
-
-
- Entity List
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/scripts/simplifiedUI/system/html/entityProperties.html b/scripts/simplifiedUI/system/html/entityProperties.html
deleted file mode 100644
index 67f03a33a2..0000000000
--- a/scripts/simplifiedUI/system/html/entityProperties.html
+++ /dev/null
@@ -1,51 +0,0 @@
-
-
-
-
- Properties
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/scripts/simplifiedUI/system/html/js/createAppTooltip.js b/scripts/simplifiedUI/system/html/js/createAppTooltip.js
deleted file mode 100644
index 3eb206d8a3..0000000000
--- a/scripts/simplifiedUI/system/html/js/createAppTooltip.js
+++ /dev/null
@@ -1,116 +0,0 @@
-// createAppTooltip.js
-//
-// Created by Thijs Wenker on 17 Oct 2018
-// Copyright 2018 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
-
-const CREATE_APP_TOOLTIP_OFFSET = 20;
-const TOOLTIP_DELAY = 500; // ms
-const TOOLTIP_DEBUG = false;
-
-function CreateAppTooltip() {
- this._tooltipData = null;
- this._tooltipDiv = null;
- this._delayTimeout = null;
- this._isEnabled = false;
-}
-
-CreateAppTooltip.prototype = {
- _tooltipData: null,
- _tooltipDiv: null,
- _delayTimeout: null,
- _isEnabled: null,
-
- _removeTooltipIfExists: function() {
- if (this._delayTimeout !== null) {
- window.clearTimeout(this._delayTimeout);
- this._delayTimeout = null;
- }
-
- if (this._tooltipDiv !== null) {
- this._tooltipDiv.remove();
- this._tooltipDiv = null;
- }
- },
-
- setIsEnabled: function(isEnabled) {
- this._isEnabled = isEnabled;
- },
-
- setTooltipData: function(tooltipData) {
- this._tooltipData = tooltipData;
- },
-
- registerTooltipElement: function(element, tooltipID, jsPropertyName) {
- element.addEventListener("mouseover", function() {
- if (!this._isEnabled) {
- return;
- }
-
- this._removeTooltipIfExists();
-
- this._delayTimeout = window.setTimeout(function() {
- let tooltipData = this._tooltipData[tooltipID];
-
- if (!tooltipData || tooltipData.tooltip === "") {
- if (!TOOLTIP_DEBUG) {
- return;
- }
- tooltipData = { tooltip: 'PLEASE SET THIS TOOLTIP' };
- }
-
- let elementRect = element.getBoundingClientRect();
- let elTip = document.createElement("div");
- elTip.className = "create-app-tooltip";
-
- let elTipDescription = document.createElement("div");
- elTipDescription.className = "create-app-tooltip-description";
- elTipDescription.innerText = tooltipData.tooltip;
- elTip.appendChild(elTipDescription);
-
- let jsAttribute = jsPropertyName;
- if (tooltipData.jsPropertyName) {
- jsAttribute = tooltipData.jsPropertyName;
- }
-
- if (!tooltipData.skipJSProperty) {
- let elTipJSAttribute = document.createElement("div");
- elTipJSAttribute.className = "create-app-tooltip-js-attribute";
- elTipJSAttribute.innerText = `JS Attribute: ${jsAttribute}`;
- elTip.appendChild(elTipJSAttribute);
- }
-
- document.body.appendChild(elTip);
-
- let elementTop = window.pageYOffset + elementRect.top;
-
- let desiredTooltipTop = elementTop + element.clientHeight + CREATE_APP_TOOLTIP_OFFSET;
- let desiredTooltipLeft = window.pageXOffset + elementRect.left;
-
- if ((window.innerHeight + window.pageYOffset) < (desiredTooltipTop + elTip.clientHeight)) {
- // show above when otherwise out of bounds
- elTip.style.top = elementTop - CREATE_APP_TOOLTIP_OFFSET - elTip.clientHeight;
- } else {
- // show tooltip below by default
- elTip.style.top = desiredTooltipTop;
- }
- if ((window.innerWidth + window.pageXOffset) < (desiredTooltipLeft + elTip.clientWidth)) {
- elTip.style.left = document.body.clientWidth + window.pageXOffset - elTip.offsetWidth;
- } else {
- elTip.style.left = desiredTooltipLeft;
- }
-
- this._tooltipDiv = elTip;
- }.bind(this), TOOLTIP_DELAY);
- }.bind(this), false);
- element.addEventListener("mouseout", function() {
- if (!this._isEnabled) {
- return;
- }
-
- this._removeTooltipIfExists();
- }.bind(this), false);
- }
-};
diff --git a/scripts/simplifiedUI/system/libraries/EditEntityList.qml b/scripts/simplifiedUI/system/libraries/EditEntityList.qml
deleted file mode 100644
index 4fc5ff19ef..0000000000
--- a/scripts/simplifiedUI/system/libraries/EditEntityList.qml
+++ /dev/null
@@ -1,12 +0,0 @@
-import QtQuick 2.7
-import QtQuick.Controls 2.2
-import QtWebChannel 1.0
-import QtGraphicalEffects 1.0
-import "qrc:///qml/controls" as HifiControls
-
-HifiControls.WebView {
- id: entityListToolWebView
- url: Qt.resolvedUrl("../html/entityList.html")
- enabled: true
- blurOnCtrlShift: false
-}
diff --git a/scripts/simplifiedUI/system/libraries/entityList.js b/scripts/simplifiedUI/system/libraries/entityList.js
deleted file mode 100644
index 585e4e06a5..0000000000
--- a/scripts/simplifiedUI/system/libraries/entityList.js
+++ /dev/null
@@ -1,330 +0,0 @@
-"use strict";
-
-// entityList.js
-//
-// Copyright 2014 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
-//
-
-/* global EntityListTool, Tablet, selectionManager, Entities, Camera, MyAvatar, Vec3, Menu, Messages,
- cameraManager, MENU_EASE_ON_FOCUS, deleteSelectedEntities, toggleSelectedEntitiesLocked, toggleSelectedEntitiesVisible,
- keyUpEventFromUIWindow, Script, SelectionDisplay, SelectionManager, Clipboard */
-
-var PROFILING_ENABLED = false;
-var profileIndent = '';
-const PROFILE_NOOP = function(_name, fn, args) {
- fn.apply(this, args);
-};
-const PROFILE = !PROFILING_ENABLED ? PROFILE_NOOP : function(name, fn, args) {
- console.log("PROFILE-Script " + profileIndent + "(" + name + ") Begin");
- var previousIndent = profileIndent;
- profileIndent += ' ';
- var before = Date.now();
- fn.apply(this, args);
- var delta = Date.now() - before;
- profileIndent = previousIndent;
- console.log("PROFILE-Script " + profileIndent + "(" + name + ") End " + delta + "ms");
-};
-
-EntityListTool = function(shouldUseEditTabletApp) {
- var that = {};
-
- var CreateWindow = Script.require('../modules/createWindow.js');
-
- var TITLE_OFFSET = 60;
- var ENTITY_LIST_WIDTH = 495;
- var MAX_DEFAULT_CREATE_TOOLS_HEIGHT = 778;
- var entityListWindow = new CreateWindow(
- Script.resolvePath("../create/EditEntityList.qml"),
- 'Entity List',
- 'com.highfidelity.create.entityListWindow',
- function () {
- var windowHeight = Window.innerHeight - TITLE_OFFSET;
- if (windowHeight > MAX_DEFAULT_CREATE_TOOLS_HEIGHT) {
- windowHeight = MAX_DEFAULT_CREATE_TOOLS_HEIGHT;
- }
- return {
- size: {
- x: ENTITY_LIST_WIDTH,
- y: windowHeight
- },
- position: {
- x: Window.x,
- y: Window.y + TITLE_OFFSET
- }
- };
- },
- false
- );
-
- var webView = null;
- webView = Tablet.getTablet("com.highfidelity.interface.tablet.system");
- webView.setVisible = function(value){ };
-
- var filterInView = false;
- var searchRadius = 100;
-
- var visible = false;
-
- that.webView = webView;
-
- that.setVisible = function(newVisible) {
- visible = newVisible;
- webView.setVisible(shouldUseEditTabletApp() && visible);
- entityListWindow.setVisible(!shouldUseEditTabletApp() && visible);
- };
-
- that.isVisible = function() {
- return entityListWindow.isVisible();
- };
-
- that.setVisible(false);
-
- function emitJSONScriptEvent(data) {
- var dataString;
- PROFILE("Script-JSON.stringify", function() {
- dataString = JSON.stringify(data);
- });
- PROFILE("Script-emitScriptEvent", function() {
- webView.emitScriptEvent(dataString);
- if (entityListWindow.window) {
- entityListWindow.window.emitScriptEvent(dataString);
- }
- });
- }
-
- that.toggleVisible = function() {
- that.setVisible(!visible);
- };
-
- selectionManager.addEventListener(function(isSelectionUpdate, caller) {
- if (caller === that) {
- // ignore events that we emitted from the entity list itself
- return;
- }
- var selectedIDs = [];
-
- for (var i = 0; i < selectionManager.selections.length; i++) {
- selectedIDs.push(selectionManager.selections[i]);
- }
-
- emitJSONScriptEvent({
- type: 'selectionUpdate',
- selectedIDs: selectedIDs
- });
- });
-
- that.setSpaceMode = function(spaceMode) {
- emitJSONScriptEvent({
- type: 'setSpaceMode',
- spaceMode: spaceMode
- });
- };
-
- that.clearEntityList = function() {
- emitJSONScriptEvent({
- type: 'clearEntityList'
- });
- };
-
- that.removeEntities = function (deletedIDs, selectedIDs) {
- emitJSONScriptEvent({
- type: 'removeEntities',
- deletedIDs: deletedIDs,
- selectedIDs: selectedIDs
- });
- };
-
- that.deleteEntities = function (deletedIDs) {
- emitJSONScriptEvent({
- type: "deleted",
- ids: deletedIDs
- });
- };
-
- function valueIfDefined(value) {
- return value !== undefined ? value : "";
- }
-
- function entityIsBaked(properties) {
- if (properties.type === "Model") {
- var lowerModelURL = properties.modelURL.toLowerCase();
- return lowerModelURL.endsWith(".baked.fbx") || lowerModelURL.endsWith(".baked.fst");
- } else if (properties.type === "Zone") {
- var lowerSkyboxURL = properties.skybox ? properties.skybox.url.toLowerCase() : "";
- var lowerAmbientURL = properties.ambientLight ? properties.ambientLight.ambientURL.toLowerCase() : "";
- return (lowerSkyboxURL === "" || lowerSkyboxURL.endsWith(".texmeta.json")) &&
- (lowerAmbientURL === "" || lowerAmbientURL.endsWith(".texmeta.json"));
- } else {
- return false;
- }
- }
-
- that.sendUpdate = function() {
- PROFILE('Script-sendUpdate', function() {
- var entities = [];
-
- var ids;
- PROFILE("findEntities", function() {
- if (filterInView) {
- ids = Entities.findEntitiesInFrustum(Camera.frustum);
- } else {
- ids = Entities.findEntities(MyAvatar.position, searchRadius);
- }
- });
-
- var cameraPosition = Camera.position;
- PROFILE("getMultipleProperties", function () {
- var multipleProperties = Entities.getMultipleEntityProperties(ids, ['name', 'type', 'locked',
- 'visible', 'renderInfo', 'modelURL', 'materialURL', 'imageURL', 'script', 'certificateID',
- 'skybox.url', 'ambientLight.url']);
- for (var i = 0; i < multipleProperties.length; i++) {
- var properties = multipleProperties[i];
-
- if (!filterInView || Vec3.distance(properties.position, cameraPosition) <= searchRadius) {
- var url = "";
- if (properties.type === "Model") {
- url = properties.modelURL;
- } else if (properties.type === "Material") {
- url = properties.materialURL;
- } else if (properties.type === "Image") {
- url = properties.imageURL;
- }
- entities.push({
- id: ids[i],
- name: properties.name,
- type: properties.type,
- url: url,
- locked: properties.locked,
- visible: properties.visible,
- certificateID: properties.certificateID,
- verticesCount: (properties.renderInfo !== undefined ?
- valueIfDefined(properties.renderInfo.verticesCount) : ""),
- texturesCount: (properties.renderInfo !== undefined ?
- valueIfDefined(properties.renderInfo.texturesCount) : ""),
- texturesSize: (properties.renderInfo !== undefined ?
- valueIfDefined(properties.renderInfo.texturesSize) : ""),
- hasTransparent: (properties.renderInfo !== undefined ?
- valueIfDefined(properties.renderInfo.hasTransparent) : ""),
- isBaked: entityIsBaked(properties),
- drawCalls: (properties.renderInfo !== undefined ?
- valueIfDefined(properties.renderInfo.drawCalls) : ""),
- hasScript: properties.script !== ""
- });
- }
- }
- });
-
- var selectedIDs = [];
- for (var j = 0; j < selectionManager.selections.length; j++) {
- selectedIDs.push(selectionManager.selections[j]);
- }
-
- emitJSONScriptEvent({
- type: "update",
- entities: entities,
- selectedIDs: selectedIDs,
- spaceMode: SelectionDisplay.getSpaceMode(),
- });
- });
- };
-
- function onFileSaveChanged(filename) {
- Window.saveFileChanged.disconnect(onFileSaveChanged);
- if (filename !== "") {
- var success = Clipboard.exportEntities(filename, selectionManager.selections);
- if (!success) {
- Window.notifyEditError("Export failed.");
- }
- }
- }
-
- var onWebEventReceived = function(data) {
- try {
- data = JSON.parse(data);
- } catch(e) {
- print("entityList.js: Error parsing JSON");
- return;
- }
-
- if (data.type === "selectionUpdate") {
- var ids = data.entityIds;
- var entityIDs = [];
- for (var i = 0; i < ids.length; i++) {
- entityIDs.push(ids[i]);
- }
- selectionManager.setSelections(entityIDs, that);
- if (data.focus) {
- cameraManager.enable();
- cameraManager.focus(selectionManager.worldPosition,
- selectionManager.worldDimensions,
- Menu.isOptionChecked(MENU_EASE_ON_FOCUS));
- }
- } else if (data.type === "refresh") {
- that.sendUpdate();
- } else if (data.type === "teleport") {
- if (selectionManager.hasSelection()) {
- MyAvatar.position = selectionManager.worldPosition;
- }
- } else if (data.type === "export") {
- if (!selectionManager.hasSelection()) {
- Window.notifyEditError("No entities have been selected.");
- } else {
- Window.saveFileChanged.connect(onFileSaveChanged);
- Window.saveAsync("Select Where to Save", "", "*.json");
- }
- } else if (data.type === "pal") {
- var sessionIds = {}; // Collect the sessionsIds of all selected entities, w/o duplicates.
- selectionManager.selections.forEach(function (id) {
- var lastEditedBy = Entities.getEntityProperties(id, 'lastEditedBy').lastEditedBy;
- if (lastEditedBy) {
- sessionIds[lastEditedBy] = true;
- }
- });
- var dedupped = Object.keys(sessionIds);
- if (!selectionManager.selections.length) {
- Window.alert('No objects selected.');
- } else if (!dedupped.length) {
- Window.alert('There were no recent users of the ' + selectionManager.selections.length + ' selected objects.');
- } else {
- // No need to subscribe if we're just sending.
- Messages.sendMessage('com.highfidelity.pal', JSON.stringify({method: 'select', params: [dedupped, true, false]}), 'local');
- }
- } else if (data.type === "delete") {
- deleteSelectedEntities();
- } else if (data.type === "toggleLocked") {
- toggleSelectedEntitiesLocked();
- } else if (data.type === "toggleVisible") {
- toggleSelectedEntitiesVisible();
- } else if (data.type === "filterInView") {
- filterInView = data.filterInView === true;
- } else if (data.type === "radius") {
- searchRadius = data.radius;
- } else if (data.type === "cut") {
- SelectionManager.cutSelectedEntities();
- } else if (data.type === "copy") {
- SelectionManager.copySelectedEntities();
- } else if (data.type === "paste") {
- SelectionManager.pasteEntities();
- } else if (data.type === "duplicate") {
- SelectionManager.duplicateSelection();
- that.sendUpdate();
- } else if (data.type === "rename") {
- Entities.editEntity(data.entityID, {name: data.name});
- // make sure that the name also gets updated in the properties window
- SelectionManager._update();
- } else if (data.type === "toggleSpaceMode") {
- SelectionDisplay.toggleSpaceMode();
- } else if (data.type === 'keyUpEvent') {
- keyUpEventFromUIWindow(data.keyUpEvent);
- }
- };
-
- webView.webEventReceived.connect(onWebEventReceived);
- entityListWindow.webEventReceived.addListener(onWebEventReceived);
- that.interactiveWindowHidden = entityListWindow.interactiveWindowHidden;
-
- return that;
-};
diff --git a/scripts/simplifiedUI/system/libraries/entitySelectionTool.js b/scripts/simplifiedUI/system/libraries/entitySelectionTool.js
deleted file mode 100644
index 3fdc1d6652..0000000000
--- a/scripts/simplifiedUI/system/libraries/entitySelectionTool.js
+++ /dev/null
@@ -1,2925 +0,0 @@
-//
-// entitySelectionTool.js
-// examples
-//
-// Created by Brad hefta-Gaub on 10/1/14.
-// Modified by Daniela Fontes * @DanielaFifo and Tiago Andrade @TagoWill on 4/7/2017
-// Modified by David Back on 1/9/2018
-// Copyright 2014 High Fidelity, Inc.
-//
-// This script implements a class useful for building tools for editing entities.
-//
-// Distributed under the Apache License, Version 2.0.
-// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
-//
-
-/* global SelectionManager, SelectionDisplay, grid, rayPlaneIntersection, rayPlaneIntersection2, pushCommandForSelections,
- getMainTabletIDs, getControllerWorldLocation, TRIGGER_ON_VALUE */
-
-const SPACE_LOCAL = "local";
-const SPACE_WORLD = "world";
-const HIGHLIGHT_LIST_NAME = "editHandleHighlightList";
-
-Script.include([
- "./controllers.js",
- "./controllerDispatcherUtils.js",
- "./utils.js"
-]);
-
-
-function deepCopy(v) {
- return JSON.parse(JSON.stringify(v));
-}
-
-SelectionManager = (function() {
- var that = {};
-
- // FUNCTION: SUBSCRIBE TO UPDATE MESSAGES
- function subscribeToUpdateMessages() {
- Messages.subscribe("entityToolUpdates");
- Messages.messageReceived.connect(handleEntitySelectionToolUpdates);
- }
-
- // FUNCTION: HANDLE ENTITY SELECTION TOOL UPDATES
- function handleEntitySelectionToolUpdates(channel, message, sender) {
- if (channel !== 'entityToolUpdates') {
- return;
- }
- if (sender !== MyAvatar.sessionUUID) {
- return;
- }
-
- var wantDebug = false;
- var messageParsed;
- try {
- messageParsed = JSON.parse(message);
- } catch (err) {
- print("ERROR: entitySelectionTool.handleEntitySelectionToolUpdates - got malformed message");
- return;
- }
-
- if (messageParsed.method === "selectEntity") {
- if (!SelectionDisplay.triggered() || SelectionDisplay.triggeredHand === messageParsed.hand) {
- if (wantDebug) {
- print("setting selection to " + messageParsed.entityID);
- }
- that.setSelections([messageParsed.entityID], that);
- }
- } else if (messageParsed.method === "clearSelection") {
- if (!SelectionDisplay.triggered() || SelectionDisplay.triggeredHand === messageParsed.hand) {
- that.clearSelections();
- }
- } else if (messageParsed.method === "pointingAt") {
- if (messageParsed.hand === Controller.Standard.RightHand) {
- that.pointingAtDesktopWindowRight = messageParsed.desktopWindow;
- that.pointingAtTabletRight = messageParsed.tablet;
- } else {
- that.pointingAtDesktopWindowLeft = messageParsed.desktopWindow;
- that.pointingAtTabletLeft = messageParsed.tablet;
- }
- }
- }
-
- subscribeToUpdateMessages();
-
- // disabling this for now as it is causing rendering issues with the other handle overlays
- /*
- var COLOR_ORANGE_HIGHLIGHT = { red: 255, green: 99, blue: 9 };
- var editHandleOutlineStyle = {
- outlineUnoccludedColor: COLOR_ORANGE_HIGHLIGHT,
- outlineOccludedColor: COLOR_ORANGE_HIGHLIGHT,
- fillUnoccludedColor: COLOR_ORANGE_HIGHLIGHT,
- fillOccludedColor: COLOR_ORANGE_HIGHLIGHT,
- outlineUnoccludedAlpha: 1,
- outlineOccludedAlpha: 0,
- fillUnoccludedAlpha: 0,
- fillOccludedAlpha: 0,
- outlineWidth: 3,
- isOutlineSmooth: true
- };
- Selection.enableListHighlight(HIGHLIGHT_LIST_NAME, editHandleOutlineStyle);
- */
-
- that.savedProperties = {};
- that.selections = [];
- var listeners = [];
-
- that.localRotation = Quat.IDENTITY;
- that.localPosition = Vec3.ZERO;
- that.localDimensions = Vec3.ZERO;
- that.localRegistrationPoint = Vec3.HALF;
-
- that.worldRotation = Quat.IDENTITY;
- that.worldPosition = Vec3.ZERO;
- that.worldDimensions = Vec3.ZERO;
- that.worldRegistrationPoint = Vec3.HALF;
- that.centerPosition = Vec3.ZERO;
-
- that.pointingAtDesktopWindowLeft = false;
- that.pointingAtDesktopWindowRight = false;
- that.pointingAtTabletLeft = false;
- that.pointingAtTabletRight = false;
-
- that.saveProperties = function() {
- that.savedProperties = {};
- for (var i = 0; i < that.selections.length; i++) {
- var entityID = that.selections[i];
- that.savedProperties[entityID] = Entities.getEntityProperties(entityID);
- }
- };
-
- that.addEventListener = function(func, thisContext) {
- listeners.push({
- callback: func,
- thisContext: thisContext
- });
- };
-
- that.hasSelection = function() {
- return that.selections.length > 0;
- };
-
- that.setSelections = function(entityIDs, caller) {
- that.selections = [];
- for (var i = 0; i < entityIDs.length; i++) {
- var entityID = entityIDs[i];
- that.selections.push(entityID);
- Selection.addToSelectedItemsList(HIGHLIGHT_LIST_NAME, "entity", entityID);
- }
-
- that._update(true, caller);
- };
-
- that.addEntity = function(entityID, toggleSelection, caller) {
- if (entityID) {
- var idx = -1;
- for (var i = 0; i < that.selections.length; i++) {
- if (entityID === that.selections[i]) {
- idx = i;
- break;
- }
- }
- if (idx === -1) {
- that.selections.push(entityID);
- Selection.addToSelectedItemsList(HIGHLIGHT_LIST_NAME, "entity", entityID);
- } else if (toggleSelection) {
- that.selections.splice(idx, 1);
- Selection.removeFromSelectedItemsList(HIGHLIGHT_LIST_NAME, "entity", entityID);
- }
- }
-
- that._update(true, caller);
- };
-
- function removeEntityByID(entityID) {
- var idx = that.selections.indexOf(entityID);
- if (idx >= 0) {
- that.selections.splice(idx, 1);
- Selection.removeFromSelectedItemsList(HIGHLIGHT_LIST_NAME, "entity", entityID);
- }
- }
-
- that.removeEntity = function (entityID, caller) {
- removeEntityByID(entityID);
- that._update(true, caller);
- };
-
- that.removeEntities = function(entityIDs, caller) {
- for (var i = 0, length = entityIDs.length; i < length; i++) {
- removeEntityByID(entityIDs[i]);
- }
- that._update(true, caller);
- };
-
- that.clearSelections = function(caller) {
- that.selections = [];
- that._update(true, caller);
- };
-
- that.addChildrenEntities = function(parentEntityID, entityList, entityHostType) {
- var wantDebug = false;
- var children = Entities.getChildrenIDs(parentEntityID);
- var entityHostTypes = Entities.getMultipleEntityProperties(children, 'entityHostType');
- for (var i = 0; i < children.length; i++) {
- var childID = children[i];
-
- if (entityHostTypes[i].entityHostType !== entityHostType) {
- if (wantDebug) {
- console.log("Skipping addition of entity " + childID + " with conflicting entityHostType: " +
- entityHostTypes[i].entityHostType + ", expected: " + entityHostType);
- }
- continue;
- }
-
- if (entityList.indexOf(childID) < 0) {
- entityList.push(childID);
- }
- that.addChildrenEntities(childID, entityList, entityHostType);
- }
- };
-
- // Determine if an entity is being grabbed.
- // This is mostly a heuristic - there is no perfect way to know if an entity is being
- // grabbed.
- //
- // @return {boolean} true if the given entity with `properties` is being grabbed by an avatar
- function nonDynamicEntityIsBeingGrabbedByAvatar(properties) {
- if (properties.dynamic || Uuid.isNull(properties.parentID)) {
- return false;
- }
-
- var avatar = AvatarList.getAvatar(properties.parentID);
- if (Uuid.isNull(avatar.sessionUUID)) {
- return false;
- }
-
- var grabJointNames = [
- 'RightHand', 'LeftHand',
- '_CONTROLLER_RIGHTHAND', '_CONTROLLER_LEFTHAND',
- '_CAMERA_RELATIVE_CONTROLLER_RIGHTHAND', '_CAMERA_RELATIVE_CONTROLLER_LEFTHAND',
- '_FARGRAB_RIGHTHAND', '_FARGRAB_LEFTHAND', '_FARGRAB_MOUSE'
- ];
-
- for (var i = 0; i < grabJointNames.length; ++i) {
- if (avatar.getJointIndex(grabJointNames[i]) === properties.parentJointIndex) {
- return true;
- }
- }
-
- return false;
- }
-
- var entityClipboard = {
- entities: {}, // Map of id -> properties for copied entities
- position: { x: 0, y: 0, z: 0 },
- dimensions: { x: 0, y: 0, z: 0 },
- };
-
- that.duplicateSelection = function() {
- var entitiesToDuplicate = [];
- var duplicatedEntityIDs = [];
- var duplicatedChildrenWithOldParents = [];
- var originalEntityToNewEntityID = [];
-
- SelectionManager.saveProperties();
-
- // build list of entities to duplicate by including any unselected children of selected parent entities
- var originalEntityIDs = Object.keys(that.savedProperties);
- var entityHostTypes = Entities.getMultipleEntityProperties(originalEntityIDs, 'entityHostType');
- for (var i = 0; i < originalEntityIDs.length; i++) {
- var originalEntityID = originalEntityIDs[i];
- if (entitiesToDuplicate.indexOf(originalEntityID) === -1) {
- entitiesToDuplicate.push(originalEntityID);
- }
- that.addChildrenEntities(originalEntityID, entitiesToDuplicate, entityHostTypes[i].entityHostType);
- }
-
- // duplicate entities from above and store their original to new entity mappings and children needing re-parenting
- for (var i = 0; i < entitiesToDuplicate.length; i++) {
- var originalEntityID = entitiesToDuplicate[i];
- var properties = that.savedProperties[originalEntityID];
- if (properties === undefined) {
- properties = Entities.getEntityProperties(originalEntityID);
- }
- if (!properties.locked && (!properties.avatarEntity || properties.owningAvatarID === MyAvatar.sessionUUID)) {
- if (nonDynamicEntityIsBeingGrabbedByAvatar(properties)) {
- properties.parentID = null;
- properties.parentJointIndex = null;
- properties.localPosition = properties.position;
- properties.localRotation = properties.rotation;
- }
-
- properties.localVelocity = Vec3.ZERO;
- properties.localAngularVelocity = Vec3.ZERO;
-
- delete properties.actionData;
- var newEntityID = Entities.addEntity(properties);
-
- // Re-apply actions from the original entity
- var actionIDs = Entities.getActionIDs(properties.id);
- for (var j = 0; j < actionIDs.length; ++j) {
- var actionID = actionIDs[j];
- var actionArguments = Entities.getActionArguments(properties.id, actionID);
- if (actionArguments) {
- var type = actionArguments.type;
- if (type === 'hold' || type === 'far-grab') {
- continue;
- }
- delete actionArguments.ttl;
- Entities.addAction(type, newEntityID, actionArguments);
- }
- }
-
- duplicatedEntityIDs.push({
- entityID: newEntityID,
- properties: properties
- });
- if (properties.parentID !== Uuid.NULL) {
- duplicatedChildrenWithOldParents[newEntityID] = properties.parentID;
- }
- originalEntityToNewEntityID[originalEntityID] = newEntityID;
- }
- }
-
- // re-parent duplicated children to the duplicate entities of their original parents (if they were duplicated)
- Object.keys(duplicatedChildrenWithOldParents).forEach(function(childIDNeedingNewParent) {
- var originalParentID = duplicatedChildrenWithOldParents[childIDNeedingNewParent];
- var newParentID = originalEntityToNewEntityID[originalParentID];
- if (newParentID) {
- Entities.editEntity(childIDNeedingNewParent, { parentID: newParentID });
- for (var i = 0; i < duplicatedEntityIDs.length; i++) {
- var duplicatedEntity = duplicatedEntityIDs[i];
- if (duplicatedEntity.entityID === childIDNeedingNewParent) {
- duplicatedEntity.properties.parentID = newParentID;
- }
- }
- }
- });
-
- return duplicatedEntityIDs;
- };
-
- // Create the entities in entityProperties, maintaining parent-child relationships.
- // @param entityProperties {array} - Array of entity property objects
- that.createEntities = function(entityProperties) {
- var entitiesToCreate = [];
- var createdEntityIDs = [];
- var createdChildrenWithOldParents = [];
- var originalEntityToNewEntityID = [];
-
- that.saveProperties();
-
- for (var i = 0; i < entityProperties.length; ++i) {
- var properties = entityProperties[i];
- if (properties.parentID in originalEntityToNewEntityID) {
- properties.parentID = originalEntityToNewEntityID[properties.parentID];
- } else {
- delete properties.parentID;
- }
-
- delete properties.actionData;
- var newEntityID = Entities.addEntity(properties);
-
- if (newEntityID) {
- createdEntityIDs.push({
- entityID: newEntityID,
- properties: properties
- });
- if (properties.parentID !== Uuid.NULL) {
- createdChildrenWithOldParents[newEntityID] = properties.parentID;
- }
- originalEntityToNewEntityID[properties.id] = newEntityID;
- properties.id = newEntityID;
- }
- }
-
- return createdEntityIDs;
- };
-
- that.cutSelectedEntities = function() {
- that.copySelectedEntities();
- deleteSelectedEntities();
- };
-
- that.copySelectedEntities = function() {
- var entityProperties = Entities.getMultipleEntityProperties(that.selections);
- var entityHostTypes = Entities.getMultipleEntityProperties(that.selections, 'entityHostType');
- var entities = {};
- entityProperties.forEach(function(props) {
- entities[props.id] = props;
- });
-
- function appendChildren(entityID, entities, entityHostType) {
- var wantDebug = false;
- var childrenIDs = Entities.getChildrenIDs(entityID);
- var entityHostTypes = Entities.getMultipleEntityProperties(childrenIDs, 'entityHostType');
- for (var i = 0; i < childrenIDs.length; ++i) {
- var id = childrenIDs[i];
-
- if (entityHostTypes[i].entityHostType !== entityHostType) {
- if (wantDebug) {
- console.warn("Skipping addition of entity " + id + " with conflicting entityHostType: " +
- entityHostTypes[i].entityHostType + ", expected: " + entityHostType);
- }
- continue;
- }
-
- if (!(id in entities)) {
- entities[id] = Entities.getEntityProperties(id);
- appendChildren(id, entities, entityHostType);
- }
- }
- }
-
- var len = entityProperties.length;
- for (var i = 0; i < len; ++i) {
- appendChildren(entityProperties[i].id, entities, entityHostTypes[i].entityHostType);
- }
-
- for (var id in entities) {
- var parentID = entities[id].parentID;
- entities[id].root = !(parentID in entities);
- }
-
- entityClipboard.entities = [];
-
- var ids = Object.keys(entities);
- while (ids.length > 0) {
- // Go through all remaining entities.
- // If an entity does not have a parent left, move it into the list
- for (var i = 0; i < ids.length; ++i) {
- var id = ids[i];
- var parentID = entities[id].parentID;
- if (parentID in entities) {
- continue;
- }
- entityClipboard.entities.push(entities[id]);
- delete entities[id];
- }
- ids = Object.keys(entities);
- }
-
- // Calculate size
- if (entityClipboard.entities.length === 0) {
- entityClipboard.dimensions = { x: 0, y: 0, z: 0 };
- entityClipboard.position = { x: 0, y: 0, z: 0 };
- } else {
- var properties = entityClipboard.entities;
- var brn = properties[0].boundingBox.brn;
- var tfl = properties[0].boundingBox.tfl;
- for (var i = 1; i < properties.length; i++) {
- var bb = properties[i].boundingBox;
- brn.x = Math.min(bb.brn.x, brn.x);
- brn.y = Math.min(bb.brn.y, brn.y);
- brn.z = Math.min(bb.brn.z, brn.z);
- tfl.x = Math.max(bb.tfl.x, tfl.x);
- tfl.y = Math.max(bb.tfl.y, tfl.y);
- tfl.z = Math.max(bb.tfl.z, tfl.z);
- }
- entityClipboard.dimensions = {
- x: tfl.x - brn.x,
- y: tfl.y - brn.y,
- z: tfl.z - brn.z
- };
- entityClipboard.position = {
- x: brn.x + entityClipboard.dimensions.x / 2,
- y: brn.y + entityClipboard.dimensions.y / 2,
- z: brn.z + entityClipboard.dimensions.z / 2
- };
- }
- };
-
- that.pasteEntities = function() {
- var dimensions = entityClipboard.dimensions;
- var maxDimension = Math.max(dimensions.x, dimensions.y, dimensions.z);
- var pastePosition = getPositionToCreateEntity(maxDimension);
- var deltaPosition = Vec3.subtract(pastePosition, entityClipboard.position);
-
- var copiedProperties = [];
- var ids = [];
- entityClipboard.entities.forEach(function(originalProperties) {
- var properties = deepCopy(originalProperties);
- if (properties.root) {
- properties.position = Vec3.sum(properties.position, deltaPosition);
- delete properties.localPosition;
- } else {
- delete properties.position;
- }
- copiedProperties.push(properties);
- });
-
- var currentSelections = deepCopy(SelectionManager.selections);
-
- function redo(copiedProperties) {
- var created = that.createEntities(copiedProperties);
- var ids = [];
- for (var i = 0; i < created.length; ++i) {
- ids.push(created[i].entityID);
- }
- SelectionManager.setSelections(ids);
- }
-
- function undo(copiedProperties) {
- for (var i = 0; i < copiedProperties.length; ++i) {
- Entities.deleteEntity(copiedProperties[i].id);
- }
- SelectionManager.setSelections(currentSelections);
- }
-
- redo(copiedProperties);
- undoHistory.pushCommand(undo, copiedProperties, redo, copiedProperties);
- };
-
- that._update = function(selectionUpdated, caller) {
- var properties = null;
- if (that.selections.length === 0) {
- that.localDimensions = null;
- that.localPosition = null;
- that.worldDimensions = null;
- that.worldPosition = null;
- that.worldRotation = null;
- } else if (that.selections.length === 1) {
- properties = Entities.getEntityProperties(that.selections[0],
- ['dimensions', 'position', 'rotation', 'registrationPoint', 'boundingBox', 'type']);
- that.localDimensions = properties.dimensions;
- that.localPosition = properties.position;
- that.localRotation = properties.rotation;
- that.localRegistrationPoint = properties.registrationPoint;
-
- that.worldDimensions = properties.boundingBox.dimensions;
- that.worldPosition = properties.boundingBox.center;
- that.worldRotation = Quat.IDENTITY;
-
- that.entityType = properties.type;
-
- if (selectionUpdated) {
- SelectionDisplay.useDesiredSpaceMode();
- }
- } else {
- properties = Entities.getEntityProperties(that.selections[0], ['type', 'boundingBox']);
-
- that.entityType = properties.type;
-
- var brn = properties.boundingBox.brn;
- var tfl = properties.boundingBox.tfl;
-
- for (var i = 1; i < that.selections.length; i++) {
- properties = Entities.getEntityProperties(that.selections[i], 'boundingBox');
- var bb = properties.boundingBox;
- brn.x = Math.min(bb.brn.x, brn.x);
- brn.y = Math.min(bb.brn.y, brn.y);
- brn.z = Math.min(bb.brn.z, brn.z);
- tfl.x = Math.max(bb.tfl.x, tfl.x);
- tfl.y = Math.max(bb.tfl.y, tfl.y);
- tfl.z = Math.max(bb.tfl.z, tfl.z);
- }
-
- that.localRotation = null;
- that.localDimensions = null;
- that.localPosition = null;
- that.worldDimensions = {
- x: tfl.x - brn.x,
- y: tfl.y - brn.y,
- z: tfl.z - brn.z
- };
- that.worldRotation = Quat.IDENTITY;
- that.worldPosition = {
- x: brn.x + (that.worldDimensions.x / 2),
- y: brn.y + (that.worldDimensions.y / 2),
- z: brn.z + (that.worldDimensions.z / 2)
- };
-
- // For 1+ selections we can only modify selections in world space
- SelectionDisplay.setSpaceMode(SPACE_WORLD, false);
- }
-
- for (var j = 0; j < listeners.length; j++) {
- try {
- listeners[j].callback.call(listeners[j].thisContext, selectionUpdated === true, caller);
- } catch (e) {
- print("ERROR: entitySelectionTool.update got exception: " + JSON.stringify(e));
- }
- }
- };
-
- return that;
-})();
-
-// Normalize degrees to be in the range (-180, 180)
-function normalizeDegrees(degrees) {
- var maxDegrees = 360;
- var halfMaxDegrees = maxDegrees / 2;
- degrees = ((degrees + halfMaxDegrees) % maxDegrees) - halfMaxDegrees;
- if (degrees <= -halfMaxDegrees) {
- degrees += maxDegrees;
- }
- return degrees;
-}
-
-// SELECTION DISPLAY DEFINITION
-SelectionDisplay = (function() {
- var that = {};
-
- const COLOR_GREEN = { red: 31, green: 198, blue: 166 };
- const COLOR_BLUE = { red: 0, green: 147, blue: 197 };
- const COLOR_RED = { red: 226, green: 51, blue: 77 };
- const COLOR_HOVER = { red: 227, green: 227, blue: 227 };
- const COLOR_ROTATE_CURRENT_RING = { red: 255, green: 99, blue: 9 };
- const COLOR_BOUNDING_EDGE = { red: 87, green: 87, blue: 87 };
- const COLOR_SCALE_CUBE = { red: 106, green: 106, blue: 106 };
- const COLOR_SCALE_CUBE_SELECTED = { red: 18, green: 18, blue: 18 };
- const COLOR_DEBUG_PICK_PLANE = { red: 255, green: 255, blue: 255 };
- const COLOR_DEBUG_PICK_PLANE_HIT = { red: 255, green: 165, blue: 0 };
-
- const TRANSLATE_ARROW_CYLINDER_OFFSET = 0.1;
- const TRANSLATE_ARROW_CYLINDER_CAMERA_DISTANCE_MULTIPLE = 0.005;
- const TRANSLATE_ARROW_CYLINDER_Y_MULTIPLE = 7.5;
- const TRANSLATE_ARROW_CONE_CAMERA_DISTANCE_MULTIPLE = 0.025;
- const TRANSLATE_ARROW_CONE_OFFSET_CYLINDER_DIMENSION_MULTIPLE = 0.83;
-
- const ROTATE_RING_CAMERA_DISTANCE_MULTIPLE = 0.15;
- const ROTATE_CTRL_SNAP_ANGLE = 22.5;
- const ROTATE_DEFAULT_SNAP_ANGLE = 1;
- const ROTATE_DEFAULT_TICK_MARKS_ANGLE = 5;
- const ROTATE_RING_IDLE_INNER_RADIUS = 0.92;
- const ROTATE_RING_SELECTED_INNER_RADIUS = 0.9;
-
- // These are multipliers for sizing the rotation degrees display while rotating an entity
- const ROTATE_DISPLAY_DISTANCE_MULTIPLIER = 2;
- const ROTATE_DISPLAY_SIZE_X_MULTIPLIER = 0.2;
- const ROTATE_DISPLAY_SIZE_Y_MULTIPLIER = 0.09;
- const ROTATE_DISPLAY_LINE_HEIGHT_MULTIPLIER = 0.07;
-
- const STRETCH_CUBE_OFFSET = 0.06;
- const STRETCH_CUBE_CAMERA_DISTANCE_MULTIPLE = 0.02;
- const STRETCH_PANEL_WIDTH = 0.01;
-
- const SCALE_OVERLAY_CAMERA_DISTANCE_MULTIPLE = 0.02;
- const SCALE_DIMENSIONS_CAMERA_DISTANCE_MULTIPLE = 0.5;
-
- const BOUNDING_EDGE_OFFSET = 0.5;
-
- const DUPLICATOR_OFFSET = { x: 0.9, y: -0.9, z: 0.9 };
-
- const CTRL_KEY_CODE = 16777249;
-
- const RAIL_AXIS_LENGTH = 10000;
-
- const NEGATE_VECTOR = -1;
- const NO_HAND = -1;
-
- const DEBUG_PICK_PLANE_HIT_LIMIT = 200;
- const DEBUG_PICK_PLANE_HIT_CAMERA_DISTANCE_MULTIPLE = 0.01;
-
- const TRANSLATE_DIRECTION = {
- X: 0,
- Y: 1,
- Z: 2
- };
-
- const STRETCH_DIRECTION = {
- X: 0,
- Y: 1,
- Z: 2,
- ALL: 3
- };
-
- const ROTATE_DIRECTION = {
- PITCH: 0,
- YAW: 1,
- ROLL: 2
- };
-
- const INEDIT_STATUS_CHANNEL = "Hifi-InEdit-Status";
-
- /**
- * The current space mode, this could have been a forced space mode since we do not support multi selection while in
- * local space mode.
- * @type {string} - should only be set to SPACE_LOCAL or SPACE_WORLD
- */
- var spaceMode = SPACE_LOCAL;
-
- /**
- * The desired space mode, this is the user set space mode, which should be respected whenever it is possible. In the case
- * of multi entity selection this space mode may differ from the actual spaceMode.
- * @type {string} - should only be set to SPACE_LOCAL or SPACE_WORLD
- */
- var desiredSpaceMode = SPACE_LOCAL;
-
- var overlayNames = [];
- var lastControllerPoses = [
- getControllerWorldLocation(Controller.Standard.LeftHand, true),
- getControllerWorldLocation(Controller.Standard.RightHand, true)
- ];
-
- var worldRotationX;
- var worldRotationY;
- var worldRotationZ;
-
- var activeStretchCubePanelOffset = null;
-
- var previousHandle = null;
- var previousHandleHelper = null;
- var previousHandleColor;
-
- var ctrlPressed = false;
-
- that.replaceCollisionsAfterStretch = false;
-
- var handlePropertiesTranslateArrowCones = {
- alpha: 1,
- shape: "Cone",
- solid: true,
- visible: false,
- ignorePickIntersection: true,
- drawInFront: true
- };
- var handlePropertiesTranslateArrowCylinders = {
- alpha: 1,
- shape: "Cylinder",
- solid: true,
- visible: false,
- ignorePickIntersection: true,
- drawInFront: true
- };
- var handleTranslateXCone = Overlays.addOverlay("shape", handlePropertiesTranslateArrowCones);
- var handleTranslateXCylinder = Overlays.addOverlay("shape", handlePropertiesTranslateArrowCylinders);
- Overlays.editOverlay(handleTranslateXCone, { color: COLOR_RED });
- Overlays.editOverlay(handleTranslateXCylinder, { color: COLOR_RED });
- var handleTranslateYCone = Overlays.addOverlay("shape", handlePropertiesTranslateArrowCones);
- var handleTranslateYCylinder = Overlays.addOverlay("shape", handlePropertiesTranslateArrowCylinders);
- Overlays.editOverlay(handleTranslateYCone, { color: COLOR_GREEN });
- Overlays.editOverlay(handleTranslateYCylinder, { color: COLOR_GREEN });
- var handleTranslateZCone = Overlays.addOverlay("shape", handlePropertiesTranslateArrowCones);
- var handleTranslateZCylinder = Overlays.addOverlay("shape", handlePropertiesTranslateArrowCylinders);
- Overlays.editOverlay(handleTranslateZCone, { color: COLOR_BLUE });
- Overlays.editOverlay(handleTranslateZCylinder, { color: COLOR_BLUE });
-
- var handlePropertiesRotateRings = {
- alpha: 1,
- solid: true,
- startAt: 0,
- endAt: 360,
- innerRadius: ROTATE_RING_IDLE_INNER_RADIUS,
- majorTickMarksAngle: ROTATE_DEFAULT_TICK_MARKS_ANGLE,
- majorTickMarksLength: 0.1,
- visible: false,
- ignorePickIntersection: true,
- drawInFront: true
- };
- var handleRotatePitchRing = Overlays.addOverlay("circle3d", handlePropertiesRotateRings);
- Overlays.editOverlay(handleRotatePitchRing, {
- color: COLOR_RED,
- majorTickMarksColor: COLOR_RED
- });
- var handleRotateYawRing = Overlays.addOverlay("circle3d", handlePropertiesRotateRings);
- Overlays.editOverlay(handleRotateYawRing, {
- color: COLOR_GREEN,
- majorTickMarksColor: COLOR_GREEN
- });
- var handleRotateRollRing = Overlays.addOverlay("circle3d", handlePropertiesRotateRings);
- Overlays.editOverlay(handleRotateRollRing, {
- color: COLOR_BLUE,
- majorTickMarksColor: COLOR_BLUE
- });
-
- var handleRotateCurrentRing = Overlays.addOverlay("circle3d", {
- alpha: 1,
- color: COLOR_ROTATE_CURRENT_RING,
- solid: true,
- innerRadius: 0.9,
- visible: false,
- ignorePickIntersection: true,
- drawInFront: true
- });
-
- var rotationDegreesDisplay = Overlays.addOverlay("text3d", {
- text: "",
- color: { red: 0, green: 0, blue: 0 },
- backgroundColor: { red: 255, green: 255, blue: 255 },
- alpha: 0.7,
- backgroundAlpha: 0.7,
- visible: false,
- isFacingAvatar: true,
- drawInFront: true,
- ignorePickIntersection: true,
- dimensions: { x: 0, y: 0 },
- lineHeight: 0.0,
- topMargin: 0,
- rightMargin: 0,
- bottomMargin: 0,
- leftMargin: 0
- });
-
- var handlePropertiesStretchCubes = {
- solid: true,
- visible: false,
- ignorePickIntersection: true,
- drawInFront: true
- };
- var handleStretchXCube = Overlays.addOverlay("cube", handlePropertiesStretchCubes);
- Overlays.editOverlay(handleStretchXCube, { color: COLOR_RED });
- var handleStretchYCube = Overlays.addOverlay("cube", handlePropertiesStretchCubes);
- Overlays.editOverlay(handleStretchYCube, { color: COLOR_GREEN });
- var handleStretchZCube = Overlays.addOverlay("cube", handlePropertiesStretchCubes);
- Overlays.editOverlay(handleStretchZCube, { color: COLOR_BLUE });
-
- var handlePropertiesStretchPanel = {
- alpha: 0.5,
- solid: true,
- visible: false,
- ignorePickIntersection: true,
- drawInFront: true
- };
- var handleStretchXPanel = Overlays.addOverlay("cube", handlePropertiesStretchPanel);
- Overlays.editOverlay(handleStretchXPanel, { color: COLOR_RED });
- var handleStretchYPanel = Overlays.addOverlay("cube", handlePropertiesStretchPanel);
- Overlays.editOverlay(handleStretchYPanel, { color: COLOR_GREEN });
- var handleStretchZPanel = Overlays.addOverlay("cube", handlePropertiesStretchPanel);
- Overlays.editOverlay(handleStretchZPanel, { color: COLOR_BLUE });
-
- var handleScaleCube = Overlays.addOverlay("cube", {
- size: 0.025,
- color: COLOR_SCALE_CUBE,
- solid: true,
- visible: false,
- ignorePickIntersection: true,
- drawInFront: true,
- borderSize: 1.4
- });
-
- var handleBoundingBox = Overlays.addOverlay("cube", {
- alpha: 1,
- color: COLOR_BOUNDING_EDGE,
- visible: false,
- ignorePickIntersection: true,
- drawInFront: true,
- isSolid: false
- });
-
- var handleDuplicator = Overlays.addOverlay("cube", {
- alpha: 1,
- size: 0.05,
- color: COLOR_GREEN,
- solid: true,
- visible: false,
- ignorePickIntersection: true,
- drawInFront: true,
- borderSize: 1.4
- });
-
- // setting to 0 alpha for now to keep this hidden vs using visible false
- // because its used as the translate xz tool handle overlay
- var selectionBox = Overlays.addOverlay("cube", {
- size: 1,
- color: COLOR_RED,
- alpha: 0,
- solid: false,
- visible: false,
- ignorePickIntersection: true,
- dashed: false
- });
-
- // Handle for x-z translation of particle effect and light entities while inside the bounding box.
- // Limitation: If multiple entities are selected, only the first entity's icon translates the selection.
- var iconSelectionBox = Overlays.addOverlay("cube", {
- size: 0.3, // Match entity icon size.
- color: COLOR_RED,
- alpha: 0,
- solid: false,
- visible: false,
- ignorePickIntersection: true,
- dashed: false
- });
-
- var xRailOverlay = Overlays.addOverlay("line3d", {
- visible: false,
- start: Vec3.ZERO,
- end: Vec3.ZERO,
- color: {
- red: 255,
- green: 0,
- blue: 0
- },
- ignorePickIntersection: true // always ignore this
- });
- var yRailOverlay = Overlays.addOverlay("line3d", {
- visible: false,
- start: Vec3.ZERO,
- end: Vec3.ZERO,
- color: {
- red: 0,
- green: 255,
- blue: 0
- },
- ignorePickIntersection: true // always ignore this
- });
- var zRailOverlay = Overlays.addOverlay("line3d", {
- visible: false,
- start: Vec3.ZERO,
- end: Vec3.ZERO,
- color: {
- red: 0,
- green: 0,
- blue: 255
- },
- ignorePickIntersection: true // always ignore this
- });
-
- var allOverlays = [
- handleTranslateXCone,
- handleTranslateXCylinder,
- handleTranslateYCone,
- handleTranslateYCylinder,
- handleTranslateZCone,
- handleTranslateZCylinder,
- handleRotatePitchRing,
- handleRotateYawRing,
- handleRotateRollRing,
- handleRotateCurrentRing,
- rotationDegreesDisplay,
- handleStretchXCube,
- handleStretchYCube,
- handleStretchZCube,
- handleStretchXPanel,
- handleStretchYPanel,
- handleStretchZPanel,
- handleScaleCube,
- handleBoundingBox,
- handleDuplicator,
- selectionBox,
- iconSelectionBox,
- xRailOverlay,
- yRailOverlay,
- zRailOverlay
- ];
-
- const nonLayeredOverlays = [selectionBox, iconSelectionBox];
-
- var maximumHandleInAllOverlays = handleDuplicator;
-
- overlayNames[handleTranslateXCone] = "handleTranslateXCone";
- overlayNames[handleTranslateXCylinder] = "handleTranslateXCylinder";
- overlayNames[handleTranslateYCone] = "handleTranslateYCone";
- overlayNames[handleTranslateYCylinder] = "handleTranslateYCylinder";
- overlayNames[handleTranslateZCone] = "handleTranslateZCone";
- overlayNames[handleTranslateZCylinder] = "handleTranslateZCylinder";
-
- overlayNames[handleRotatePitchRing] = "handleRotatePitchRing";
- overlayNames[handleRotateYawRing] = "handleRotateYawRing";
- overlayNames[handleRotateRollRing] = "handleRotateRollRing";
- overlayNames[handleRotateCurrentRing] = "handleRotateCurrentRing";
- overlayNames[rotationDegreesDisplay] = "rotationDegreesDisplay";
-
- overlayNames[handleStretchXCube] = "handleStretchXCube";
- overlayNames[handleStretchYCube] = "handleStretchYCube";
- overlayNames[handleStretchZCube] = "handleStretchZCube";
- overlayNames[handleStretchXPanel] = "handleStretchXPanel";
- overlayNames[handleStretchYPanel] = "handleStretchYPanel";
- overlayNames[handleStretchZPanel] = "handleStretchZPanel";
-
- overlayNames[handleScaleCube] = "handleScaleCube";
-
- overlayNames[handleBoundingBox] = "handleBoundingBox";
-
- overlayNames[handleDuplicator] = "handleDuplicator";
- overlayNames[selectionBox] = "selectionBox";
- overlayNames[iconSelectionBox] = "iconSelectionBox";
-
- var activeTool = null;
- var handleTools = {};
-
- var debugPickPlaneEnabled = false;
- var debugPickPlane = Overlays.addOverlay("shape", {
- shape: "Quad",
- alpha: 0.25,
- color: COLOR_DEBUG_PICK_PLANE,
- solid: true,
- visible: false,
- ignorePickIntersection: true,
- drawInFront: false
- });
- var debugPickPlaneHits = [];
-
- // We get mouseMoveEvents from the handControllers, via handControllerPointer.
- // But we dont' get mousePressEvents.
- that.triggerClickMapping = Controller.newMapping(Script.resolvePath('') + '-click');
- that.triggerPressMapping = Controller.newMapping(Script.resolvePath('') + '-press');
- that.triggeredHand = NO_HAND;
- that.pressedHand = NO_HAND;
- that.editingHand = NO_HAND;
- that.triggered = function() {
- return that.triggeredHand !== NO_HAND;
- };
- function pointingAtDesktopWindowOrTablet(hand) {
- var pointingAtDesktopWindow = (hand === Controller.Standard.RightHand &&
- SelectionManager.pointingAtDesktopWindowRight) ||
- (hand === Controller.Standard.LeftHand &&
- SelectionManager.pointingAtDesktopWindowLeft);
- var pointingAtTablet = (hand === Controller.Standard.RightHand && SelectionManager.pointingAtTabletRight) ||
- (hand === Controller.Standard.LeftHand && SelectionManager.pointingAtTabletLeft);
- return pointingAtDesktopWindow || pointingAtTablet;
- }
- function makeClickHandler(hand) {
- return function (clicked) {
- // Don't allow both hands to trigger at the same time
- if (that.triggered() && hand !== that.triggeredHand) {
- return;
- }
- if (!that.triggered() && clicked && !pointingAtDesktopWindowOrTablet(hand)) {
- that.triggeredHand = hand;
- that.mousePressEvent({});
- } else if (that.triggered() && !clicked) {
- that.triggeredHand = NO_HAND;
- that.mouseReleaseEvent({});
- }
- };
- }
- function makePressHandler(hand) {
- return function (value) {
- if (value >= TRIGGER_ON_VALUE && !that.triggered() && !pointingAtDesktopWindowOrTablet(hand)) {
- that.pressedHand = hand;
- that.updateHighlight({});
- } else {
- that.pressedHand = NO_HAND;
- that.resetPreviousHandleColor();
- }
- }
- }
- that.triggerClickMapping.from(Controller.Standard.RTClick).peek().to(makeClickHandler(Controller.Standard.RightHand));
- that.triggerClickMapping.from(Controller.Standard.LTClick).peek().to(makeClickHandler(Controller.Standard.LeftHand));
- that.triggerPressMapping.from(Controller.Standard.RT).peek().to(makePressHandler(Controller.Standard.RightHand));
- that.triggerPressMapping.from(Controller.Standard.LT).peek().to(makePressHandler(Controller.Standard.LeftHand));
- that.enableTriggerMapping = function() {
- that.triggerClickMapping.enable();
- that.triggerPressMapping.enable();
- };
- that.disableTriggerMapping = function() {
- that.triggerClickMapping.disable();
- that.triggerPressMapping.disable();
- };
- Script.scriptEnding.connect(that.disableTriggerMapping);
-
- // FUNCTION DEF(s): Intersection Check Helpers
- function testRayIntersect(queryRay, overlayIncludes, overlayExcludes) {
- var wantDebug = false;
- if ((queryRay === undefined) || (queryRay === null)) {
- if (wantDebug) {
- print("testRayIntersect - EARLY EXIT -> queryRay is undefined OR null!");
- }
- return null;
- }
-
- // We want to first check the drawInFront overlays (i.e. the handles, but really everything except the selectionBoxes)
- // so that you can click on them even when they're behind things
- var overlayIncludesLayered = [];
- var overlayIncludesNonLayered = [];
- for (var i = 0; i < overlayIncludes.length; i++) {
- var value = overlayIncludes[i];
- var contains = false;
- for (var j = 0; j < nonLayeredOverlays.length; j++) {
- if (nonLayeredOverlays[j] === value) {
- contains = true;
- break;
- }
- }
- if (contains) {
- overlayIncludesNonLayered.push(value);
- } else {
- overlayIncludesLayered.push(value);
- }
- }
-
- var intersectObj = Overlays.findRayIntersection(queryRay, true, overlayIncludesLayered, overlayExcludes);
-
- if (!intersectObj.intersects && overlayIncludesNonLayered.length > 0) {
- intersectObj = Overlays.findRayIntersection(queryRay, true, overlayIncludesNonLayered, overlayExcludes);
- }
-
- if (wantDebug) {
- if (!overlayIncludes) {
- print("testRayIntersect - no overlayIncludes provided.");
- }
- if (!overlayExcludes) {
- print("testRayIntersect - no overlayExcludes provided.");
- }
- print("testRayIntersect - Hit: " + intersectObj.intersects);
- print(" intersectObj.overlayID:" + intersectObj.overlayID + "[" + overlayNames[intersectObj.overlayID] + "]");
- print(" OverlayName: " + overlayNames[intersectObj.overlayID]);
- print(" intersectObj.distance:" + intersectObj.distance);
- print(" intersectObj.face:" + intersectObj.face);
- Vec3.print(" intersectObj.intersection:", intersectObj.intersection);
- }
-
- return intersectObj;
- }
-
- function isPointInsideBox(point, box) {
- var position = Vec3.subtract(point, box.position);
- position = Vec3.multiplyQbyV(Quat.inverse(box.rotation), position);
- return Math.abs(position.x) <= box.dimensions.x / 2 && Math.abs(position.y) <= box.dimensions.y / 2
- && Math.abs(position.z) <= box.dimensions.z / 2;
- }
-
- that.isEditHandle = function(overlayID) {
- var overlayIndex = allOverlays.indexOf(overlayID);
- var maxHandleIndex = allOverlays.indexOf(maximumHandleInAllOverlays);
- return overlayIndex >= 0 && overlayIndex <= maxHandleIndex;
- };
-
- // FUNCTION: MOUSE PRESS EVENT
- that.mousePressEvent = function (event) {
- var wantDebug = false;
- if (wantDebug) {
- print("=============== eST::MousePressEvent BEG =======================");
- }
- if (!event.isLeftButton && !that.triggered()) {
- // EARLY EXIT-(if another mouse button than left is pressed ignore it)
- return false;
- }
-
- var pickRay = generalComputePickRay(event.x, event.y);
- // TODO_Case6491: Move this out to setup just to make it once
- var interactiveOverlays = getMainTabletIDs();
- for (var key in handleTools) {
- if (handleTools.hasOwnProperty(key)) {
- interactiveOverlays.push(key);
- }
- }
-
- // Start with unknown mode, in case no tool can handle this.
- activeTool = null;
-
- var results = testRayIntersect(pickRay, interactiveOverlays);
- if (results.intersects) {
- var hitOverlayID = results.overlayID;
- if ((HMD.tabletID && hitOverlayID === HMD.tabletID) || (HMD.tabletScreenID && hitOverlayID === HMD.tabletScreenID)
- || (HMD.homeButtonID && hitOverlayID === HMD.homeButtonID)) {
- // EARLY EXIT-(mouse clicks on the tablet should override the edit affordances)
- return false;
- }
-
- var hitTool = handleTools[ hitOverlayID ];
- if (hitTool) {
- activeTool = hitTool;
- that.clearDebugPickPlane();
- if (activeTool.onBegin) {
- that.editingHand = that.triggeredHand;
- Messages.sendLocalMessage(INEDIT_STATUS_CHANNEL, JSON.stringify({
- method: "editing",
- hand: that.editingHand === Controller.Standard.LeftHand ? LEFT_HAND : RIGHT_HAND,
- editing: true
- }));
- activeTool.onBegin(event, pickRay, results);
- } else {
- print("ERROR: entitySelectionTool.mousePressEvent - ActiveTool(" + activeTool.mode + ") missing onBegin");
- }
- } else {
- print("ERROR: entitySelectionTool.mousePressEvent - Hit unexpected object, check interactiveOverlays");
- }// End_if (hitTool)
- }// End_If(results.intersects)
-
- if (wantDebug) {
- print(" DisplayMode: " + getMode());
- print("=============== eST::MousePressEvent END =======================");
- }
-
- // If mode is known then we successfully handled this;
- // otherwise, we're missing a tool.
- return activeTool;
- };
-
- that.resetPreviousHandleColor = function() {
- if (previousHandle !== null) {
- Overlays.editOverlay(previousHandle, { color: previousHandleColor });
- previousHandle = null;
- }
- if (previousHandleHelper !== null) {
- Overlays.editOverlay(previousHandleHelper, { color: previousHandleColor });
- previousHandleHelper = null;
- }
- };
-
- that.getHandleHelper = function(overlay) {
- if (overlay === handleTranslateXCone) {
- return handleTranslateXCylinder;
- } else if (overlay === handleTranslateXCylinder) {
- return handleTranslateXCone;
- } else if (overlay === handleTranslateYCone) {
- return handleTranslateYCylinder;
- } else if (overlay === handleTranslateYCylinder) {
- return handleTranslateYCone;
- } else if (overlay === handleTranslateZCone) {
- return handleTranslateZCylinder;
- } else if (overlay === handleTranslateZCylinder) {
- return handleTranslateZCone;
- }
- return Uuid.NULL;
- };
-
- that.updateHighlight = function(event) {
- // if no tool is active, then just look for handles to highlight...
- var pickRay = generalComputePickRay(event.x, event.y);
- var result = testRayIntersect(pickRay, allOverlays);
- var pickedColor;
- var highlightNeeded = false;
-
- if (result.intersects) {
- switch (result.overlayID) {
- case handleTranslateXCone:
- case handleTranslateXCylinder:
- case handleRotatePitchRing:
- case handleStretchXCube:
- pickedColor = COLOR_RED;
- highlightNeeded = true;
- break;
- case handleTranslateYCone:
- case handleTranslateYCylinder:
- case handleRotateYawRing:
- case handleStretchYCube:
- pickedColor = COLOR_GREEN;
- highlightNeeded = true;
- break;
- case handleTranslateZCone:
- case handleTranslateZCylinder:
- case handleRotateRollRing:
- case handleStretchZCube:
- pickedColor = COLOR_BLUE;
- highlightNeeded = true;
- break;
- case handleScaleCube:
- pickedColor = COLOR_SCALE_CUBE;
- highlightNeeded = true;
- break;
- default:
- that.resetPreviousHandleColor();
- break;
- }
-
- if (highlightNeeded) {
- that.resetPreviousHandleColor();
- Overlays.editOverlay(result.overlayID, { color: COLOR_HOVER });
- previousHandle = result.overlayID;
- previousHandleHelper = that.getHandleHelper(result.overlayID);
- if (previousHandleHelper !== null) {
- Overlays.editOverlay(previousHandleHelper, { color: COLOR_HOVER });
- }
- previousHandleColor = pickedColor;
- }
-
- } else {
- that.resetPreviousHandleColor();
- }
- };
-
- // FUNCTION: MOUSE MOVE EVENT
- var lastMouseEvent = null;
- that.mouseMoveEvent = function(event) {
- var wantDebug = false;
- if (wantDebug) {
- print("=============== eST::MouseMoveEvent BEG =======================");
- }
- lastMouseEvent = event;
- if (activeTool) {
- if (wantDebug) {
- print(" Trigger ActiveTool(" + activeTool.mode + ")'s onMove");
- }
- activeTool.onMove(event);
-
- if (wantDebug) {
- print(" Trigger SelectionManager::update");
- }
- SelectionManager._update(false, that);
-
- if (wantDebug) {
- print("=============== eST::MouseMoveEvent END =======================");
- }
- // EARLY EXIT--(Move handled via active tool)
- return true;
- }
-
- that.updateHighlight(event);
-
- if (wantDebug) {
- print("=============== eST::MouseMoveEvent END =======================");
- }
- return false;
- };
-
- // FUNCTION: MOUSE RELEASE EVENT
- that.mouseReleaseEvent = function(event) {
- var wantDebug = false;
- if (wantDebug) {
- print("=============== eST::MouseReleaseEvent BEG =======================");
- }
- var showHandles = false;
- if (activeTool) {
- if (activeTool.onEnd) {
- if (wantDebug) {
- print(" Triggering ActiveTool(" + activeTool.mode + ")'s onEnd");
- }
- Messages.sendLocalMessage(INEDIT_STATUS_CHANNEL, JSON.stringify({
- method: "editing",
- hand: that.editingHand === Controller.Standard.LeftHand ? LEFT_HAND : RIGHT_HAND,
- editing: false
- }));
- that.editingHand = NO_HAND;
- activeTool.onEnd(event);
- } else if (wantDebug) {
- print(" ActiveTool(" + activeTool.mode + ")'s missing onEnd");
- }
- }
-
- showHandles = activeTool; // base on prior tool value
- activeTool = null;
-
- // if something is selected, then reset the "original" properties for any potential next click+move operation
- if (SelectionManager.hasSelection()) {
- if (showHandles) {
- if (wantDebug) {
- print(" Triggering that.select");
- }
- that.select(SelectionManager.selections[0], event);
- }
- }
-
- if (wantDebug) {
- print("=============== eST::MouseReleaseEvent END =======================");
- }
- };
-
- // Control key remains active only while key is held down
- that.keyReleaseEvent = function(event) {
- if (event.key === CTRL_KEY_CODE) {
- ctrlPressed = false;
- that.updateActiveRotateRing();
- }
- that.updateLastMouseEvent(event);
- };
-
- // Triggers notification on specific key driven events
- that.keyPressEvent = function(event) {
- if (event.key === CTRL_KEY_CODE) {
- ctrlPressed = true;
- that.updateActiveRotateRing();
- }
- that.updateLastMouseEvent(event);
- };
-
- that.updateLastMouseEvent = function(event) {
- if (activeTool && lastMouseEvent !== null) {
- var change = lastMouseEvent.isShifted !== event.isShifted || lastMouseEvent.isMeta !== event.isMeta ||
- lastMouseEvent.isControl !== event.isControl || lastMouseEvent.isAlt !== event.isAlt;
- lastMouseEvent.isShifted = event.isShifted;
- lastMouseEvent.isMeta = event.isMeta;
- lastMouseEvent.isControl = event.isControl;
- lastMouseEvent.isAlt = event.isAlt;
- if (change) {
- activeTool.onMove(lastMouseEvent);
- }
- }
- };
-
- // NOTE: mousePressEvent and mouseMoveEvent from the main script should call us., so we don't hook these:
- // Controller.mousePressEvent.connect(that.mousePressEvent);
- // Controller.mouseMoveEvent.connect(that.mouseMoveEvent);
- Controller.mouseReleaseEvent.connect(that.mouseReleaseEvent);
- Controller.keyPressEvent.connect(that.keyPressEvent);
- Controller.keyReleaseEvent.connect(that.keyReleaseEvent);
-
- that.checkControllerMove = function() {
- if (SelectionManager.hasSelection()) {
- var controllerPose = getControllerWorldLocation(that.triggeredHand, true);
- var hand = (that.triggeredHand === Controller.Standard.LeftHand) ? 0 : 1;
- if (controllerPose.valid && lastControllerPoses[hand].valid && that.triggered()) {
- if (!Vec3.equal(controllerPose.position, lastControllerPoses[hand].position) ||
- !Vec3.equal(controllerPose.rotation, lastControllerPoses[hand].rotation)) {
- that.mouseMoveEvent({});
- }
- }
- lastControllerPoses[hand] = controllerPose;
- }
- };
-
- function controllerComputePickRay() {
- var hand = that.triggered() ? that.triggeredHand : that.pressedHand;
- var controllerPose = getControllerWorldLocation(hand, true);
- if (controllerPose.valid) {
- var controllerPosition = controllerPose.translation;
- // This gets point direction right, but if you want general quaternion it would be more complicated:
- var controllerDirection = Quat.getUp(controllerPose.rotation);
- return {origin: controllerPosition, direction: controllerDirection};
- }
- }
-
- function generalComputePickRay(x, y) {
- return controllerComputePickRay() || Camera.computePickRay(x, y);
- }
-
- function getControllerAvatarFramePositionFromPickRay(pickRay) {
- var controllerPosition = Vec3.subtract(pickRay.origin, MyAvatar.position);
- controllerPosition = Vec3.multiplyQbyV(Quat.inverse(MyAvatar.orientation), controllerPosition);
- return controllerPosition;
- }
-
- function getDistanceToCamera(position) {
- var cameraPosition = Camera.getPosition();
- var toCameraDistance = Vec3.length(Vec3.subtract(cameraPosition, position));
- return toCameraDistance;
- }
-
- function usePreviousPickRay(pickRayDirection, previousPickRayDirection, normal) {
- return (Vec3.dot(pickRayDirection, normal) > 0 && Vec3.dot(previousPickRayDirection, normal) < 0) ||
- (Vec3.dot(pickRayDirection, normal) < 0 && Vec3.dot(previousPickRayDirection, normal) > 0);
- }
-
- // @return string - The mode of the currently active tool;
- // otherwise, "UNKNOWN" if there's no active tool.
- function getMode() {
- return (activeTool ? activeTool.mode : "UNKNOWN");
- }
-
- that.cleanup = function() {
- for (var i = 0; i < allOverlays.length; i++) {
- Overlays.deleteOverlay(allOverlays[i]);
- }
- that.clearDebugPickPlane();
- };
-
- that.select = function(entityID, event) {
- var properties = Entities.getEntityProperties(SelectionManager.selections[0]);
-
- if (event !== false) {
- var wantDebug = false;
- if (wantDebug) {
- print("select() with EVENT...... ");
- print(" event.y:" + event.y);
- Vec3.print(" current position:", properties.position);
- }
- }
-
- that.updateHandles();
- };
-
-
- /**
- * This callback is used for spaceMode changes.
- * @callback spaceModeChangedCallback
- * @param {string} spaceMode
- */
-
- /**
- * set this property with a callback to keep track of spaceMode changes.
- * @type {spaceModeChangedCallback}
- */
- that.onSpaceModeChange = null;
-
- // FUNCTION: SET SPACE MODE
- that.setSpaceMode = function(newSpaceMode, isDesiredChange) {
- var wantDebug = false;
- if (wantDebug) {
- print("======> SetSpaceMode called. ========");
- }
-
- if (spaceMode !== newSpaceMode) {
- if (wantDebug) {
- print(" Updating SpaceMode From: " + spaceMode + " To: " + newSpaceMode);
- }
- if (isDesiredChange) {
- desiredSpaceMode = newSpaceMode;
- }
- spaceMode = newSpaceMode;
-
- if (that.onSpaceModeChange !== null) {
- that.onSpaceModeChange(newSpaceMode);
- }
-
- that.updateHandles();
- } else if (wantDebug) {
- print("WARNING: entitySelectionTool.setSpaceMode - Can't update SpaceMode. CurrentMode: " +
- spaceMode + " DesiredMode: " + newSpaceMode);
- }
- if (wantDebug) {
- print("====== SetSpaceMode called. <========");
- }
- };
-
- // FUNCTION: TOGGLE SPACE MODE
- that.toggleSpaceMode = function() {
- var wantDebug = false;
- if (wantDebug) {
- print("========> ToggleSpaceMode called. =========");
- }
- if ((spaceMode === SPACE_WORLD) && (SelectionManager.selections.length > 1)) {
- if (wantDebug) {
- print("Local space editing is not available with multiple selections");
- }
- return;
- }
- if (wantDebug) {
- print("PreToggle: " + spaceMode);
- }
- that.setSpaceMode((spaceMode === SPACE_LOCAL) ? SPACE_WORLD : SPACE_LOCAL, true);
- if (wantDebug) {
- print("PostToggle: " + spaceMode);
- print("======== ToggleSpaceMode called. <=========");
- }
- };
-
- /**
- * Switches the display mode back to the set desired display mode
- */
- that.useDesiredSpaceMode = function() {
- var wantDebug = false;
- if (wantDebug) {
- print("========> UseDesiredSpaceMode called. =========");
- }
- that.setSpaceMode(desiredSpaceMode, false);
- if (wantDebug) {
- print("PostToggle: " + spaceMode);
- print("======== UseDesiredSpaceMode called. <=========");
- }
- };
-
- /**
- * Get the currently set SpaceMode
- * @returns {string} spaceMode
- */
- that.getSpaceMode = function() {
- return spaceMode;
- };
-
- function addHandleTool(overlay, tool) {
- handleTools[overlay] = tool;
- return tool;
- }
-
- // @param: toolHandle: The overlayID associated with the tool
- // that correlates to the tool you wish to query.
- // @note: If toolHandle is null or undefined then activeTool
- // will be checked against those values as opposed to
- // the tool registered under toolHandle. Null & Undefined
- // are treated as separate values.
- // @return: bool - Indicates if the activeTool is that queried.
- function isActiveTool(toolHandle) {
- if (!toolHandle) {
- // Allow isActiveTool(null) and similar to return true if there's
- // no active tool
- return (activeTool === toolHandle);
- }
-
- if (!handleTools.hasOwnProperty(toolHandle)) {
- print("WARNING: entitySelectionTool.isActiveTool - Encountered unknown grabberToolHandle: " +
- toolHandle + ". Tools should be registered via addHandleTool.");
- // EARLY EXIT
- return false;
- }
-
- return (activeTool === handleTools[ toolHandle ]);
- }
-
- // FUNCTION: UPDATE HANDLES
- that.updateHandles = function() {
- var wantDebug = false;
- if (wantDebug) {
- print("======> Update Handles =======");
- print(" Selections Count: " + SelectionManager.selections.length);
- print(" SpaceMode: " + spaceMode);
- print(" DisplayMode: " + getMode());
- }
-
- if (SelectionManager.selections.length === 0) {
- that.setOverlaysVisible(false);
- that.clearDebugPickPlane();
- return;
- }
-
- if (SelectionManager.hasSelection()) {
- var position = SelectionManager.worldPosition;
- var rotation = spaceMode === SPACE_LOCAL ? SelectionManager.localRotation : SelectionManager.worldRotation;
- var dimensions = spaceMode === SPACE_LOCAL ? SelectionManager.localDimensions : SelectionManager.worldDimensions;
- var rotationInverse = Quat.inverse(rotation);
- var toCameraDistance = getDistanceToCamera(position);
-
- var rotationDegrees = 90;
- var localRotationX = Quat.fromPitchYawRollDegrees(0, 0, -rotationDegrees);
- var rotationX = Quat.multiply(rotation, localRotationX);
- worldRotationX = rotationX;
- var localRotationY = Quat.fromPitchYawRollDegrees(0, rotationDegrees, 0);
- var rotationY = Quat.multiply(rotation, localRotationY);
- worldRotationY = rotationY;
- var localRotationZ = Quat.fromPitchYawRollDegrees(rotationDegrees, 0, 0);
- var rotationZ = Quat.multiply(rotation, localRotationZ);
- worldRotationZ = rotationZ;
-
- var selectionBoxGeometry = {
- position: position,
- rotation: rotation,
- dimensions: dimensions
- };
- var isCameraInsideBox = isPointInsideBox(Camera.position, selectionBoxGeometry);
-
- // in HMD if outside the bounding box clamp the overlays to the bounding box for now so lasers can hit them
- var maxHandleDimension = 0;
- if (HMD.active && !isCameraInsideBox) {
- maxHandleDimension = Math.max(dimensions.x, dimensions.y, dimensions.z);
- }
-
- // UPDATE ROTATION RINGS
- // rotateDimension is used as the base dimension for all overlays
- var rotateDimension = Math.max(maxHandleDimension, toCameraDistance * ROTATE_RING_CAMERA_DISTANCE_MULTIPLE);
- var rotateDimensions = { x: rotateDimension, y: rotateDimension, z: rotateDimension };
- if (!isActiveTool(handleRotatePitchRing)) {
- Overlays.editOverlay(handleRotatePitchRing, {
- position: position,
- rotation: rotationY,
- dimensions: rotateDimensions,
- majorTickMarksAngle: ROTATE_DEFAULT_TICK_MARKS_ANGLE
- });
- }
- if (!isActiveTool(handleRotateYawRing)) {
- Overlays.editOverlay(handleRotateYawRing, {
- position: position,
- rotation: rotationZ,
- dimensions: rotateDimensions,
- majorTickMarksAngle: ROTATE_DEFAULT_TICK_MARKS_ANGLE
- });
- }
- if (!isActiveTool(handleRotateRollRing)) {
- Overlays.editOverlay(handleRotateRollRing, {
- position: position,
- rotation: rotationX,
- dimensions: rotateDimensions,
- majorTickMarksAngle: ROTATE_DEFAULT_TICK_MARKS_ANGLE
- });
- }
- Overlays.editOverlay(handleRotateCurrentRing, { dimensions: rotateDimensions });
- that.updateActiveRotateRing();
-
- // UPDATE TRANSLATION ARROWS
- var arrowCylinderDimension = rotateDimension * TRANSLATE_ARROW_CYLINDER_CAMERA_DISTANCE_MULTIPLE /
- ROTATE_RING_CAMERA_DISTANCE_MULTIPLE;
- var arrowCylinderDimensions = {
- x: arrowCylinderDimension,
- y: arrowCylinderDimension * TRANSLATE_ARROW_CYLINDER_Y_MULTIPLE,
- z: arrowCylinderDimension
- };
- var arrowConeDimension = rotateDimension * TRANSLATE_ARROW_CONE_CAMERA_DISTANCE_MULTIPLE /
- ROTATE_RING_CAMERA_DISTANCE_MULTIPLE;
- var arrowConeDimensions = { x: arrowConeDimension, y: arrowConeDimension, z: arrowConeDimension };
- var arrowCylinderOffset = rotateDimension * TRANSLATE_ARROW_CYLINDER_OFFSET / ROTATE_RING_CAMERA_DISTANCE_MULTIPLE;
- var arrowConeOffset = arrowCylinderDimensions.y * TRANSLATE_ARROW_CONE_OFFSET_CYLINDER_DIMENSION_MULTIPLE;
- var cylinderXPosition = { x: arrowCylinderOffset, y: 0, z: 0 };
- cylinderXPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, cylinderXPosition));
- Overlays.editOverlay(handleTranslateXCylinder, {
- position: cylinderXPosition,
- rotation: rotationX,
- dimensions: arrowCylinderDimensions
- });
- var cylinderXOffset = Vec3.subtract(cylinderXPosition, position);
- var coneXPosition = Vec3.sum(cylinderXPosition, Vec3.multiply(Vec3.normalize(cylinderXOffset), arrowConeOffset));
- Overlays.editOverlay(handleTranslateXCone, {
- position: coneXPosition,
- rotation: rotationX,
- dimensions: arrowConeDimensions
- });
- var cylinderYPosition = { x: 0, y: arrowCylinderOffset, z: 0 };
- cylinderYPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, cylinderYPosition));
- Overlays.editOverlay(handleTranslateYCylinder, {
- position: cylinderYPosition,
- rotation: rotationY,
- dimensions: arrowCylinderDimensions
- });
- var cylinderYOffset = Vec3.subtract(cylinderYPosition, position);
- var coneYPosition = Vec3.sum(cylinderYPosition, Vec3.multiply(Vec3.normalize(cylinderYOffset), arrowConeOffset));
- Overlays.editOverlay(handleTranslateYCone, {
- position: coneYPosition,
- rotation: rotationY,
- dimensions: arrowConeDimensions
- });
- var cylinderZPosition = { x: 0, y: 0, z: arrowCylinderOffset };
- cylinderZPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, cylinderZPosition));
- Overlays.editOverlay(handleTranslateZCylinder, {
- position: cylinderZPosition,
- rotation: rotationZ,
- dimensions: arrowCylinderDimensions
- });
- var cylinderZOffset = Vec3.subtract(cylinderZPosition, position);
- var coneZPosition = Vec3.sum(cylinderZPosition, Vec3.multiply(Vec3.normalize(cylinderZOffset), arrowConeOffset));
- Overlays.editOverlay(handleTranslateZCone, {
- position: coneZPosition,
- rotation: rotationZ,
- dimensions: arrowConeDimensions
- });
-
- // UPDATE SCALE CUBE
- var scaleCubeRotation = spaceMode === SPACE_LOCAL ? rotation : Quat.IDENTITY;
- var scaleCubeDimension = rotateDimension * SCALE_OVERLAY_CAMERA_DISTANCE_MULTIPLE /
- ROTATE_RING_CAMERA_DISTANCE_MULTIPLE;
- var scaleCubeDimensions = { x: scaleCubeDimension, y: scaleCubeDimension, z: scaleCubeDimension };
- Overlays.editOverlay(handleScaleCube, {
- position: position,
- rotation: scaleCubeRotation,
- dimensions: scaleCubeDimensions
- });
-
- // UPDATE BOUNDING BOX
- Overlays.editOverlay(handleBoundingBox, {
- position: position,
- rotation: rotation,
- dimensions: dimensions
- });
-
- // UPDATE STRETCH HIGHLIGHT PANELS
- var edgeOffsetX = BOUNDING_EDGE_OFFSET * dimensions.x;
- var edgeOffsetY = BOUNDING_EDGE_OFFSET * dimensions.y;
- var edgeOffsetZ = BOUNDING_EDGE_OFFSET * dimensions.z;
- var RBFPosition = { x: edgeOffsetX, y: -edgeOffsetY, z: edgeOffsetZ };
- RBFPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, RBFPosition));
- var RTFPosition = { x: edgeOffsetX, y: edgeOffsetY, z: edgeOffsetZ };
- RTFPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, RTFPosition));
- var LTNPosition = { x: -edgeOffsetX, y: edgeOffsetY, z: -edgeOffsetZ };
- LTNPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, LTNPosition));
- var RTNPosition = { x: edgeOffsetX, y: edgeOffsetY, z: -edgeOffsetZ };
- RTNPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, RTNPosition));
-
- var RBFPositionRotated = Vec3.multiplyQbyV(rotationInverse, RBFPosition);
- var RTFPositionRotated = Vec3.multiplyQbyV(rotationInverse, RTFPosition);
- var LTNPositionRotated = Vec3.multiplyQbyV(rotationInverse, LTNPosition);
- var RTNPositionRotated = Vec3.multiplyQbyV(rotationInverse, RTNPosition);
- var stretchPanelXDimensions = Vec3.subtract(RTNPositionRotated, RBFPositionRotated);
- var tempY = Math.abs(stretchPanelXDimensions.y);
- stretchPanelXDimensions.x = STRETCH_PANEL_WIDTH;
- stretchPanelXDimensions.y = Math.abs(stretchPanelXDimensions.z);
- stretchPanelXDimensions.z = tempY;
- var stretchPanelXPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, { x: dimensions.x / 2, y: 0, z: 0 }));
- Overlays.editOverlay(handleStretchXPanel, {
- position: stretchPanelXPosition,
- rotation: rotationZ,
- dimensions: stretchPanelXDimensions
- });
- var stretchPanelYDimensions = Vec3.subtract(LTNPositionRotated, RTFPositionRotated);
- var tempX = Math.abs(stretchPanelYDimensions.x);
- stretchPanelYDimensions.x = Math.abs(stretchPanelYDimensions.z);
- stretchPanelYDimensions.y = STRETCH_PANEL_WIDTH;
- stretchPanelYDimensions.z = tempX;
- var stretchPanelYPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, { x: 0, y: dimensions.y / 2, z: 0 }));
- Overlays.editOverlay(handleStretchYPanel, {
- position: stretchPanelYPosition,
- rotation: rotationY,
- dimensions: stretchPanelYDimensions
- });
- var stretchPanelZDimensions = Vec3.subtract(LTNPositionRotated, RBFPositionRotated);
- tempX = Math.abs(stretchPanelZDimensions.x);
- stretchPanelZDimensions.x = Math.abs(stretchPanelZDimensions.y);
- stretchPanelZDimensions.y = tempX;
- stretchPanelZDimensions.z = STRETCH_PANEL_WIDTH;
- var stretchPanelZPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, { x: 0, y: 0, z: dimensions.z / 2 }));
- Overlays.editOverlay(handleStretchZPanel, {
- position: stretchPanelZPosition,
- rotation: rotationX,
- dimensions: stretchPanelZDimensions
- });
-
- // UPDATE STRETCH CUBES
- var stretchCubeDimension = rotateDimension * STRETCH_CUBE_CAMERA_DISTANCE_MULTIPLE /
- ROTATE_RING_CAMERA_DISTANCE_MULTIPLE;
- var stretchCubeDimensions = { x: stretchCubeDimension, y: stretchCubeDimension, z: stretchCubeDimension };
- var stretchCubeOffset = rotateDimension * STRETCH_CUBE_OFFSET / ROTATE_RING_CAMERA_DISTANCE_MULTIPLE;
- var stretchXPosition, stretchYPosition, stretchZPosition;
- if (isActiveTool(handleStretchXCube)) {
- stretchXPosition = Vec3.subtract(stretchPanelXPosition, activeStretchCubePanelOffset);
- } else {
- stretchXPosition = { x: stretchCubeOffset, y: 0, z: 0 };
- stretchXPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, stretchXPosition));
- }
- if (isActiveTool(handleStretchYCube)) {
- stretchYPosition = Vec3.subtract(stretchPanelYPosition, activeStretchCubePanelOffset);
- } else {
- stretchYPosition = { x: 0, y: stretchCubeOffset, z: 0 };
- stretchYPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, stretchYPosition));
- }
- if (isActiveTool(handleStretchZCube)) {
- stretchZPosition = Vec3.subtract(stretchPanelZPosition, activeStretchCubePanelOffset);
- } else {
- stretchZPosition = { x: 0, y: 0, z: stretchCubeOffset };
- stretchZPosition = Vec3.sum(position, Vec3.multiplyQbyV(rotation, stretchZPosition));
- }
- Overlays.editOverlay(handleStretchXCube, {
- position: stretchXPosition,
- rotation: rotationX,
- dimensions: stretchCubeDimensions
- });
- Overlays.editOverlay(handleStretchYCube, {
- position: stretchYPosition,
- rotation: rotationY,
- dimensions: stretchCubeDimensions
- });
- Overlays.editOverlay(handleStretchZCube, {
- position: stretchZPosition,
- rotation: rotationZ,
- dimensions: stretchCubeDimensions
- });
-
- // UPDATE SELECTION BOX (CURRENTLY INVISIBLE WITH 0 ALPHA FOR TRANSLATE XZ TOOL)
- var inModeRotate = isActiveTool(handleRotatePitchRing) ||
- isActiveTool(handleRotateYawRing) ||
- isActiveTool(handleRotateRollRing);
- selectionBoxGeometry.visible = !inModeRotate && !isCameraInsideBox;
- selectionBoxGeometry.ignorePickIntersection = !selectionBoxGeometry.visible;
- Overlays.editOverlay(selectionBox, selectionBoxGeometry);
-
- // UPDATE ICON TRANSLATE HANDLE
- if (SelectionManager.entityType === "ParticleEffect" || SelectionManager.entityType === "Light") {
- var iconSelectionBoxGeometry = {
- position: position,
- rotation: rotation
- };
- iconSelectionBoxGeometry.visible = !inModeRotate && isCameraInsideBox;
- iconSelectionBoxGeometry.ignorePickIntersection = !iconSelectionBoxGeometry.visible;
- Overlays.editOverlay(iconSelectionBox, iconSelectionBoxGeometry);
- } else {
- Overlays.editOverlay(iconSelectionBox, {
- visible: false,
- ignorePickIntersection: true
- });
- }
-
- // UPDATE DUPLICATOR (CURRENTLY HIDDEN FOR NOW)
- var handleDuplicatorOffset = {
- x: DUPLICATOR_OFFSET.x * dimensions.x,
- y: DUPLICATOR_OFFSET.y * dimensions.y,
- z: DUPLICATOR_OFFSET.z * dimensions.z
- };
- var handleDuplicatorPos = Vec3.sum(position, Vec3.multiplyQbyV(rotation, handleDuplicatorOffset));
- Overlays.editOverlay(handleDuplicator, {
- position: handleDuplicatorPos,
- rotation: rotation,
- dimensions: scaleCubeDimensions
- });
- }
-
- that.setHandleTranslateXVisible(!activeTool || isActiveTool(handleTranslateXCone) ||
- isActiveTool(handleTranslateXCylinder));
- that.setHandleTranslateYVisible(!activeTool || isActiveTool(handleTranslateYCone) ||
- isActiveTool(handleTranslateYCylinder));
- that.setHandleTranslateZVisible(!activeTool || isActiveTool(handleTranslateZCone) ||
- isActiveTool(handleTranslateZCylinder));
- that.setHandleRotatePitchVisible(!activeTool || isActiveTool(handleRotatePitchRing));
- that.setHandleRotateYawVisible(!activeTool || isActiveTool(handleRotateYawRing));
- that.setHandleRotateRollVisible(!activeTool || isActiveTool(handleRotateRollRing));
-
- var showScaleStretch = !activeTool && SelectionManager.selections.length === 1 && spaceMode === SPACE_LOCAL;
- that.setHandleStretchXVisible(showScaleStretch || isActiveTool(handleStretchXCube));
- that.setHandleStretchYVisible(showScaleStretch || isActiveTool(handleStretchYCube));
- that.setHandleStretchZVisible(showScaleStretch || isActiveTool(handleStretchZCube));
- that.setHandleScaleVisible(showScaleStretch || isActiveTool(handleScaleCube));
-
- var showOutlineForZone = (SelectionManager.selections.length === 1 &&
- typeof SelectionManager.savedProperties[SelectionManager.selections[0]] !== "undefined" &&
- SelectionManager.savedProperties[SelectionManager.selections[0]].type === "Zone");
- that.setHandleBoundingBoxVisible(showOutlineForZone || (!isActiveTool(handleRotatePitchRing) &&
- !isActiveTool(handleRotateYawRing) &&
- !isActiveTool(handleRotateRollRing)));
-
- // keep duplicator always hidden for now since you can hold Alt to duplicate while
- // translating an entity - we may bring duplicator back for HMD only later
- // that.setHandleDuplicatorVisible(!activeTool || isActiveTool(handleDuplicator));
-
- if (wantDebug) {
- print("====== Update Handles <=======");
- }
- };
- Script.update.connect(that.updateHandles);
-
- // FUNCTION: UPDATE ACTIVE ROTATE RING
- that.updateActiveRotateRing = function() {
- var activeRotateRing = null;
- if (isActiveTool(handleRotatePitchRing)) {
- activeRotateRing = handleRotatePitchRing;
- } else if (isActiveTool(handleRotateYawRing)) {
- activeRotateRing = handleRotateYawRing;
- } else if (isActiveTool(handleRotateRollRing)) {
- activeRotateRing = handleRotateRollRing;
- }
- if (activeRotateRing !== null) {
- var tickMarksAngle = ctrlPressed ? ROTATE_CTRL_SNAP_ANGLE : ROTATE_DEFAULT_TICK_MARKS_ANGLE;
- Overlays.editOverlay(activeRotateRing, { majorTickMarksAngle: tickMarksAngle });
- }
- };
-
- // FUNCTION: SET OVERLAYS VISIBLE
- that.setOverlaysVisible = function(isVisible) {
- for (var i = 0, length = allOverlays.length; i < length; i++) {
- Overlays.editOverlay(allOverlays[i], { visible: isVisible, ignorePickIntersection: !isVisible });
- }
- };
-
- // FUNCTION: SET HANDLE TRANSLATE VISIBLE
- that.setHandleTranslateVisible = function(isVisible) {
- that.setHandleTranslateXVisible(isVisible);
- that.setHandleTranslateYVisible(isVisible);
- that.setHandleTranslateZVisible(isVisible);
- };
-
- that.setHandleTranslateXVisible = function(isVisible) {
- Overlays.editOverlay(handleTranslateXCone, { visible: isVisible, ignorePickIntersection: !isVisible });
- Overlays.editOverlay(handleTranslateXCylinder, { visible: isVisible, ignorePickIntersection: !isVisible });
- };
-
- that.setHandleTranslateYVisible = function(isVisible) {
- Overlays.editOverlay(handleTranslateYCone, { visible: isVisible, ignorePickIntersection: !isVisible });
- Overlays.editOverlay(handleTranslateYCylinder, { visible: isVisible, ignorePickIntersection: !isVisible });
- };
-
- that.setHandleTranslateZVisible = function(isVisible) {
- Overlays.editOverlay(handleTranslateZCone, { visible: isVisible, ignorePickIntersection: !isVisible });
- Overlays.editOverlay(handleTranslateZCylinder, { visible: isVisible, ignorePickIntersection: !isVisible });
- };
-
- // FUNCTION: SET HANDLE ROTATE VISIBLE
- that.setHandleRotateVisible = function(isVisible) {
- that.setHandleRotatePitchVisible(isVisible);
- that.setHandleRotateYawVisible(isVisible);
- that.setHandleRotateRollVisible(isVisible);
- };
-
- that.setHandleRotatePitchVisible = function(isVisible) {
- Overlays.editOverlay(handleRotatePitchRing, { visible: isVisible, ignorePickIntersection: !isVisible });
- };
-
- that.setHandleRotateYawVisible = function(isVisible) {
- Overlays.editOverlay(handleRotateYawRing, { visible: isVisible, ignorePickIntersection: !isVisible });
- };
-
- that.setHandleRotateRollVisible = function(isVisible) {
- Overlays.editOverlay(handleRotateRollRing, { visible: isVisible, ignorePickIntersection: !isVisible });
- };
-
- // FUNCTION: SET HANDLE STRETCH VISIBLE
- that.setHandleStretchVisible = function(isVisible) {
- that.setHandleStretchXVisible(isVisible);
- that.setHandleStretchYVisible(isVisible);
- that.setHandleStretchZVisible(isVisible);
- };
-
- that.setHandleStretchXVisible = function(isVisible) {
- Overlays.editOverlay(handleStretchXCube, { visible: isVisible, ignorePickIntersection: !isVisible });
- };
-
- that.setHandleStretchYVisible = function(isVisible) {
- Overlays.editOverlay(handleStretchYCube, { visible: isVisible, ignorePickIntersection: !isVisible });
- };
-
- that.setHandleStretchZVisible = function(isVisible) {
- Overlays.editOverlay(handleStretchZCube, { visible: isVisible, ignorePickIntersection: !isVisible });
- };
-
- // FUNCTION: SET HANDLE SCALE VISIBLE
- that.setHandleScaleVisible = function(isVisible) {
- that.setHandleScaleVisible(isVisible);
- that.setHandleBoundingBoxVisible(isVisible);
- };
-
- that.setHandleScaleVisible = function(isVisible) {
- Overlays.editOverlay(handleScaleCube, { visible: isVisible, ignorePickIntersection: !isVisible });
- };
-
- that.setHandleBoundingBoxVisible = function(isVisible) {
- Overlays.editOverlay(handleBoundingBox, { visible: isVisible, ignorePickIntersection: true });
- };
-
- // FUNCTION: SET HANDLE DUPLICATOR VISIBLE
- that.setHandleDuplicatorVisible = function(isVisible) {
- Overlays.editOverlay(handleDuplicator, { visible: isVisible, ignorePickIntersection: !isVisible });
- };
-
- // FUNCTION: DEBUG PICK PLANE
- that.showDebugPickPlane = function(pickPlanePosition, pickPlaneNormal) {
- var planePlusNormal = Vec3.sum(pickPlanePosition, pickPlaneNormal);
- var rotation = Quat.lookAtSimple(planePlusNormal, pickPlanePosition);
- var dimensionXZ = getDistanceToCamera(pickPlanePosition) * 1.25;
- var dimensions = { x:dimensionXZ, y:dimensionXZ, z:STRETCH_PANEL_WIDTH };
- Overlays.editOverlay(debugPickPlane, {
- position: pickPlanePosition,
- rotation: rotation,
- dimensions: dimensions,
- visible: true
- });
- };
-
- that.showDebugPickPlaneHit = function(pickHitPosition) {
- var dimension = getDistanceToCamera(pickHitPosition) * DEBUG_PICK_PLANE_HIT_CAMERA_DISTANCE_MULTIPLE;
- var pickPlaneHit = Overlays.addOverlay("shape", {
- alpha: 0.5,
- shape: "Sphere",
- solid: true,
- visible: true,
- ignorePickIntersection: true,
- drawInFront: false,
- color: COLOR_DEBUG_PICK_PLANE_HIT,
- position: pickHitPosition,
- dimensions: { x: dimension, y: dimension, z: dimension }
- });
- debugPickPlaneHits.push(pickPlaneHit);
- if (debugPickPlaneHits.length > DEBUG_PICK_PLANE_HIT_LIMIT) {
- var removedPickPlaneHit = debugPickPlaneHits.shift();
- Overlays.deleteOverlay(removedPickPlaneHit);
- }
- };
-
- that.clearDebugPickPlane = function() {
- Overlays.editOverlay(debugPickPlane, { visible: false });
- for (var i = 0; i < debugPickPlaneHits.length; i++) {
- Overlays.deleteOverlay(debugPickPlaneHits[i]);
- }
- debugPickPlaneHits = [];
- };
-
- // TOOL DEFINITION: HANDLE TRANSLATE XZ TOOL
- function addHandleTranslateXZTool(overlay, mode, doDuplicate) {
- var initialPick = null;
- var isConstrained = false;
- var constrainMajorOnly = false;
- var startPosition = null;
- var duplicatedEntityIDs = null;
- var pickPlanePosition = null;
- var pickPlaneNormal = { x: 0, y: 1, z: 0 };
- var greatestDimension = 0.0;
- var startingDistance = 0.0;
- var startingElevation = 0.0;
- addHandleTool(overlay, {
- mode: mode,
- onBegin: function(event, pickRay, pickResult) {
- var wantDebug = false;
- if (wantDebug) {
- print("================== TRANSLATE_XZ(Beg) -> =======================");
- Vec3.print(" pickRay", pickRay);
- Vec3.print(" pickRay.origin", pickRay.origin);
- Vec3.print(" pickResult.intersection", pickResult.intersection);
- }
-
- // Duplicate entities if alt is pressed. This will make a
- // copy of the selected entities and move the _original_ entities, not
- // the new ones.
- if (event.isAlt || doDuplicate) {
- duplicatedEntityIDs = SelectionManager.duplicateSelection();
- var ids = [];
- for (var i = 0; i < duplicatedEntityIDs.length; ++i) {
- ids.push(duplicatedEntityIDs[i].entityID);
- }
- SelectionManager.setSelections(ids);
- } else {
- duplicatedEntityIDs = null;
- }
-
- SelectionManager.saveProperties();
- that.resetPreviousHandleColor();
-
- that.setHandleTranslateVisible(false);
- that.setHandleRotateVisible(false);
- that.setHandleScaleVisible(false);
- that.setHandleStretchVisible(false);
- that.setHandleDuplicatorVisible(false);
-
- startPosition = SelectionManager.worldPosition;
- pickPlanePosition = pickResult.intersection;
- greatestDimension = Math.max(Math.max(SelectionManager.worldDimensions.x,
- SelectionManager.worldDimensions.y),
- SelectionManager.worldDimensions.z);
- startingDistance = Vec3.distance(pickRay.origin, SelectionManager.position);
- startingElevation = this.elevation(pickRay.origin, pickPlanePosition);
- if (wantDebug) {
- print(" longest dimension: " + greatestDimension);
- print(" starting distance: " + startingDistance);
- print(" starting elevation: " + startingElevation);
- }
-
- initialPick = rayPlaneIntersection(pickRay, pickPlanePosition, pickPlaneNormal);
-
- if (debugPickPlaneEnabled) {
- that.showDebugPickPlane(pickPlanePosition, pickPlaneNormal);
- that.showDebugPickPlaneHit(initialPick);
- }
-
- isConstrained = false;
- if (wantDebug) {
- print("================== TRANSLATE_XZ(End) <- =======================");
- }
- },
- onEnd: function(event, reason) {
- pushCommandForSelections(duplicatedEntityIDs);
- if (isConstrained) {
- Overlays.editOverlay(xRailOverlay, {
- visible: false,
- ignorePickIntersection: true
- });
- Overlays.editOverlay(zRailOverlay, {
- visible: false,
- ignorePickIntersection: true
- });
- }
- },
- elevation: function(origin, intersection) {
- return (origin.y - intersection.y) / Vec3.distance(origin, intersection);
- },
- onMove: function(event) {
- var wantDebug = false;
- var pickRay = generalComputePickRay(event.x, event.y);
-
- var newPick = rayPlaneIntersection2(pickRay, pickPlanePosition, pickPlaneNormal);
-
- // If the pick ray doesn't hit the pick plane in this direction, do nothing.
- // this will happen when someone drags across the horizon from the side they started on.
- if (!newPick) {
- if (wantDebug) {
- print(" "+ mode + "Pick ray does not intersect XZ plane.");
- }
-
- // EARLY EXIT--(Invalid ray detected.)
- return;
- }
-
- if (debugPickPlaneEnabled) {
- that.showDebugPickPlaneHit(newPick);
- }
-
- var vector = Vec3.subtract(newPick, initialPick);
-
- // If the mouse is too close to the horizon of the pick plane, stop moving
- var MIN_ELEVATION = 0.02; // largest dimension of object divided by distance to it
- var elevation = this.elevation(pickRay.origin, newPick);
- if (wantDebug) {
- print("Start Elevation: " + startingElevation + ", elevation: " + elevation);
- }
- if ((startingElevation > 0.0 && elevation < MIN_ELEVATION) ||
- (startingElevation < 0.0 && elevation > -MIN_ELEVATION)) {
- if (wantDebug) {
- print(" "+ mode + " - too close to horizon!");
- }
-
- // EARLY EXIT--(Don't proceed past the reached limit.)
- return;
- }
-
- // If the angular size of the object is too small, stop moving
- var MIN_ANGULAR_SIZE = 0.01; // Radians
- if (greatestDimension > 0) {
- var angularSize = Math.atan(greatestDimension / Vec3.distance(pickRay.origin, newPick));
- if (wantDebug) {
- print("Angular size = " + angularSize);
- }
- if (angularSize < MIN_ANGULAR_SIZE) {
- return;
- }
- }
-
- // If shifted, constrain to one axis
- if (event.isShifted) {
- if (Math.abs(vector.x) > Math.abs(vector.z)) {
- vector.z = 0;
- } else {
- vector.x = 0;
- }
- if (!isConstrained) {
- var xStart = Vec3.sum(startPosition, {
- x: -RAIL_AXIS_LENGTH,
- y: 0,
- z: 0
- });
- var xEnd = Vec3.sum(startPosition, {
- x: RAIL_AXIS_LENGTH,
- y: 0,
- z: 0
- });
- var zStart = Vec3.sum(startPosition, {
- x: 0,
- y: 0,
- z: -RAIL_AXIS_LENGTH
- });
- var zEnd = Vec3.sum(startPosition, {
- x: 0,
- y: 0,
- z: RAIL_AXIS_LENGTH
- });
- Overlays.editOverlay(xRailOverlay, {
- start: xStart,
- end: xEnd,
- visible: true,
- ignorePickIntersection: true
- });
- Overlays.editOverlay(zRailOverlay, {
- start: zStart,
- end: zEnd,
- visible: true,
- ignorePickIntersection: true
- });
- isConstrained = true;
- }
- } else {
- if (isConstrained) {
- Overlays.editOverlay(xRailOverlay, {
- visible: false,
- ignorePickIntersection: true
- });
- Overlays.editOverlay(zRailOverlay, {
- visible: false,
- ignorePickIntersection: true
- });
- isConstrained = false;
- }
- }
-
- constrainMajorOnly = event.isControl;
- var negateAndHalve = -0.5;
- var cornerPosition = Vec3.sum(startPosition, Vec3.multiply(negateAndHalve, SelectionManager.worldDimensions));
- vector = Vec3.subtract(
- grid.snapToGrid(Vec3.sum(cornerPosition, vector), constrainMajorOnly),
- cornerPosition);
-
- // editing a parent will cause all the children to automatically follow along, so don't
- // edit any entity who has an ancestor in SelectionManager.selections
- var toMove = SelectionManager.selections.filter(function (selection) {
- if (SelectionManager.selections.indexOf(SelectionManager.savedProperties[selection].parentID) >= 0) {
- return false; // a parent is also being moved, so don't issue an edit for this entity
- } else {
- return true;
- }
- });
-
- for (var i = 0; i < toMove.length; i++) {
- var properties = SelectionManager.savedProperties[toMove[i]];
- if (!properties) {
- continue;
- }
- var newPosition = Vec3.sum(properties.position, {
- x: vector.x,
- y: 0,
- z: vector.z
- });
- Entities.editEntity(toMove[i], {
- position: newPosition
- });
-
- if (wantDebug) {
- print("translateXZ... ");
- Vec3.print(" vector:", vector);
- Vec3.print(" newPosition:", properties.position);
- Vec3.print(" newPosition:", newPosition);
- }
- }
-
- SelectionManager._update(false, this);
- }
- });
- }
-
- // TOOL DEFINITION: HANDLE TRANSLATE TOOL
- function addHandleTranslateTool(overlay, mode, direction) {
- var pickPlanePosition = null;
- var pickPlaneNormal = null;
- var initialPick = null;
- var projectionVector = null;
- var previousPickRay = null;
- var rotation = null;
- addHandleTool(overlay, {
- mode: mode,
- onBegin: function(event, pickRay, pickResult) {
- // Duplicate entities if alt is pressed. This will make a
- // copy of the selected entities and move the _original_ entities, not
- // the new ones.
- if (event.isAlt) {
- duplicatedEntityIDs = SelectionManager.duplicateSelection();
- var ids = [];
- for (var i = 0; i < duplicatedEntityIDs.length; ++i) {
- ids.push(duplicatedEntityIDs[i].entityID);
- }
- SelectionManager.setSelections(ids);
- } else {
- duplicatedEntityIDs = null;
- }
-
- var axisVector;
- if (direction === TRANSLATE_DIRECTION.X) {
- axisVector = { x: 1, y: 0, z: 0 };
- } else if (direction === TRANSLATE_DIRECTION.Y) {
- axisVector = { x: 0, y: 1, z: 0 };
- } else if (direction === TRANSLATE_DIRECTION.Z) {
- axisVector = { x: 0, y: 0, z: 1 };
- }
-
- rotation = spaceMode === SPACE_LOCAL ? SelectionManager.localRotation : SelectionManager.worldRotation;
- axisVector = Vec3.multiplyQbyV(rotation, axisVector);
- pickPlaneNormal = Vec3.cross(Vec3.cross(pickRay.direction, axisVector), axisVector);
- pickPlanePosition = SelectionManager.worldPosition;
- initialPick = rayPlaneIntersection(pickRay, pickPlanePosition, pickPlaneNormal);
-
- SelectionManager.saveProperties();
- that.resetPreviousHandleColor();
-
- that.setHandleTranslateXVisible(direction === TRANSLATE_DIRECTION.X);
- that.setHandleTranslateYVisible(direction === TRANSLATE_DIRECTION.Y);
- that.setHandleTranslateZVisible(direction === TRANSLATE_DIRECTION.Z);
- that.setHandleRotateVisible(false);
- that.setHandleStretchVisible(false);
- that.setHandleScaleVisible(false);
- that.setHandleDuplicatorVisible(false);
-
- previousPickRay = pickRay;
-
- if (debugPickPlaneEnabled) {
- that.showDebugPickPlane(pickPlanePosition, pickPlaneNormal);
- that.showDebugPickPlaneHit(initialPick);
- }
- },
- onEnd: function(event, reason) {
- pushCommandForSelections(duplicatedEntityIDs);
- },
- onMove: function(event) {
- var pickRay = generalComputePickRay(event.x, event.y);
-
- // Use previousPickRay if new pickRay will cause resulting rayPlaneIntersection values to wrap around
- if (usePreviousPickRay(pickRay.direction, previousPickRay.direction, pickPlaneNormal)) {
- pickRay = previousPickRay;
- }
-
- var newPick = rayPlaneIntersection(pickRay, pickPlanePosition, pickPlaneNormal);
- if (debugPickPlaneEnabled) {
- that.showDebugPickPlaneHit(newPick);
- }
-
- var vector = Vec3.subtract(newPick, initialPick);
-
- if (direction === TRANSLATE_DIRECTION.X) {
- projectionVector = { x: 1, y: 0, z: 0 };
- } else if (direction === TRANSLATE_DIRECTION.Y) {
- projectionVector = { x: 0, y: 1, z: 0 };
- } else if (direction === TRANSLATE_DIRECTION.Z) {
- projectionVector = { x: 0, y: 0, z: 1 };
- }
- projectionVector = Vec3.multiplyQbyV(rotation, projectionVector);
-
- var dotVector = Vec3.dot(vector, projectionVector);
- vector = Vec3.multiply(dotVector, projectionVector);
- var gridOrigin = grid.getOrigin();
- vector = Vec3.subtract(grid.snapToGrid(Vec3.sum(vector, gridOrigin)), gridOrigin);
-
- var wantDebug = false;
- if (wantDebug) {
- print("translateUpDown... ");
- print(" event.y:" + event.y);
- Vec3.print(" newIntersection:", newIntersection);
- Vec3.print(" vector:", vector);
- }
-
- // editing a parent will cause all the children to automatically follow along, so don't
- // edit any entity who has an ancestor in SelectionManager.selections
- var toMove = SelectionManager.selections.filter(function (selection) {
- if (SelectionManager.selections.indexOf(SelectionManager.savedProperties[selection].parentID) >= 0) {
- return false; // a parent is also being moved, so don't issue an edit for this entity
- } else {
- return true;
- }
- });
-
- for (var i = 0; i < toMove.length; i++) {
- var id = toMove[i];
- var properties = SelectionManager.savedProperties[id];
- var newPosition = Vec3.sum(properties.position, vector);
- Entities.editEntity(id, { position: newPosition });
- }
-
- previousPickRay = pickRay;
-
- SelectionManager._update(false, this);
- }
- });
- }
-
- // TOOL DEFINITION: HANDLE STRETCH TOOL
- function addHandleStretchTool(overlay, mode, directionEnum) {
- var initialPick = null;
- var initialPosition = null;
- var initialDimensions = null;
- var rotation = null;
- var registrationPoint = null;
- var pickPlanePosition = null;
- var pickPlaneNormal = null;
- var previousPickRay = null;
- var directionVector = null;
- var axisVector = null;
- var signs = null;
- var mask = null;
- var stretchPanel = null;
- var handleStretchCube = null;
- var deltaPivot = null;
- addHandleTool(overlay, {
- mode: mode,
- onBegin: function(event, pickRay, pickResult) {
- if (directionEnum === STRETCH_DIRECTION.X) {
- stretchPanel = handleStretchXPanel;
- handleStretchCube = handleStretchXCube;
- directionVector = { x: -1, y: 0, z: 0 };
- } else if (directionEnum === STRETCH_DIRECTION.Y) {
- stretchPanel = handleStretchYPanel;
- handleStretchCube = handleStretchYCube;
- directionVector = { x: 0, y: -1, z: 0 };
- } else if (directionEnum === STRETCH_DIRECTION.Z) {
- stretchPanel = handleStretchZPanel;
- handleStretchCube = handleStretchZCube;
- directionVector = { x: 0, y: 0, z: -1 };
- }
-
- rotation = SelectionManager.localRotation;
- initialPosition = SelectionManager.localPosition;
- initialDimensions = SelectionManager.localDimensions;
- registrationPoint = SelectionManager.localRegistrationPoint;
-
- axisVector = Vec3.multiply(NEGATE_VECTOR, directionVector);
- axisVector = Vec3.multiplyQbyV(rotation, axisVector);
-
- signs = {
- x: directionVector.x < 0 ? -1 : (directionVector.x > 0 ? 1 : 0),
- y: directionVector.y < 0 ? -1 : (directionVector.y > 0 ? 1 : 0),
- z: directionVector.z < 0 ? -1 : (directionVector.z > 0 ? 1 : 0)
- };
- mask = {
- x: Math.abs(directionVector.x) > 0 ? 1 : 0,
- y: Math.abs(directionVector.y) > 0 ? 1 : 0,
- z: Math.abs(directionVector.z) > 0 ? 1 : 0
- };
-
- var pivot = directionVector;
- var offset = Vec3.multiply(directionVector, NEGATE_VECTOR);
-
- // Modify range of registrationPoint to be [-0.5, 0.5]
- var centeredRP = Vec3.subtract(registrationPoint, {
- x: 0.5,
- y: 0.5,
- z: 0.5
- });
-
- // Scale pivot to be in the same range as registrationPoint
- var scaledPivot = Vec3.multiply(0.5, pivot);
- deltaPivot = Vec3.subtract(centeredRP, scaledPivot);
-
- var scaledOffset = Vec3.multiply(0.5, offset);
-
- // Offset from the registration point
- var offsetRP = Vec3.subtract(scaledOffset, centeredRP);
-
- // Scaled offset in world coordinates
- var scaledOffsetWorld = Vec3.multiplyVbyV(initialDimensions, offsetRP);
-
- pickPlaneNormal = Vec3.cross(Vec3.cross(pickRay.direction, axisVector), axisVector);
- pickPlanePosition = Vec3.sum(initialPosition, Vec3.multiplyQbyV(rotation, scaledOffsetWorld));
- initialPick = rayPlaneIntersection(pickRay, pickPlanePosition, pickPlaneNormal);
-
- that.setHandleTranslateVisible(false);
- that.setHandleRotateVisible(false);
- that.setHandleScaleVisible(true);
- that.setHandleStretchXVisible(directionEnum === STRETCH_DIRECTION.X);
- that.setHandleStretchYVisible(directionEnum === STRETCH_DIRECTION.Y);
- that.setHandleStretchZVisible(directionEnum === STRETCH_DIRECTION.Z);
- that.setHandleDuplicatorVisible(false);
-
- SelectionManager.saveProperties();
- that.resetPreviousHandleColor();
-
- var collisionToRemove = "myAvatar";
- var properties = Entities.getEntityProperties(SelectionManager.selections[0]);
- if (properties.collidesWith.indexOf(collisionToRemove) > -1) {
- var newCollidesWith = properties.collidesWith.replace(collisionToRemove, "");
- Entities.editEntity(SelectionManager.selections[0], {collidesWith: newCollidesWith});
- that.replaceCollisionsAfterStretch = true;
- }
-
- if (stretchPanel !== null) {
- Overlays.editOverlay(stretchPanel, { visible: true, ignorePickIntersection: false });
- }
- var stretchCubePosition = Overlays.getProperty(handleStretchCube, "position");
- var stretchPanelPosition = Overlays.getProperty(stretchPanel, "position");
- activeStretchCubePanelOffset = Vec3.subtract(stretchPanelPosition, stretchCubePosition);
-
- previousPickRay = pickRay;
-
- if (debugPickPlaneEnabled) {
- that.showDebugPickPlane(pickPlanePosition, pickPlaneNormal);
- that.showDebugPickPlaneHit(initialPick);
- }
- },
- onEnd: function(event, reason) {
- if (that.replaceCollisionsAfterStretch) {
- var newCollidesWith = SelectionManager.savedProperties[SelectionManager.selections[0]].collidesWith;
- Entities.editEntity(SelectionManager.selections[0], {collidesWith: newCollidesWith});
- that.replaceCollisionsAfterStretch = false;
- }
-
- if (stretchPanel !== null) {
- Overlays.editOverlay(stretchPanel, { visible: false, ignorePickIntersection: true });
- }
- activeStretchCubePanelOffset = null;
-
- pushCommandForSelections();
- },
- onMove: function(event) {
- var pickRay = generalComputePickRay(event.x, event.y);
-
- // Use previousPickRay if new pickRay will cause resulting rayPlaneIntersection values to wrap around
- if (usePreviousPickRay(pickRay.direction, previousPickRay.direction, pickPlaneNormal)) {
- pickRay = previousPickRay;
- }
-
- var newPick = rayPlaneIntersection(pickRay, pickPlanePosition, pickPlaneNormal);
- if (debugPickPlaneEnabled) {
- that.showDebugPickPlaneHit(newPick);
- }
-
- var changeInDimensions = Vec3.subtract(newPick, initialPick);
- var dotVector = Vec3.dot(changeInDimensions, axisVector);
- changeInDimensions = Vec3.multiply(dotVector, axisVector);
- changeInDimensions = Vec3.multiplyQbyV(Quat.inverse(rotation), changeInDimensions);
- changeInDimensions = Vec3.multiplyVbyV(mask, changeInDimensions);
- changeInDimensions = grid.snapToSpacing(changeInDimensions);
- changeInDimensions = Vec3.multiply(NEGATE_VECTOR, Vec3.multiplyVbyV(signs, changeInDimensions));
-
- var newDimensions = Vec3.sum(initialDimensions, changeInDimensions);
-
- var minimumDimension = Entities.getPropertyInfo("dimensions").minimum;
- if (newDimensions.x < minimumDimension) {
- newDimensions.x = minimumDimension;
- changeInDimensions.x = minimumDimension - initialDimensions.x;
- }
- if (newDimensions.y < minimumDimension) {
- newDimensions.y = minimumDimension;
- changeInDimensions.y = minimumDimension - initialDimensions.y;
- }
- if (newDimensions.z < minimumDimension) {
- newDimensions.z = minimumDimension;
- changeInDimensions.z = minimumDimension - initialDimensions.z;
- }
-
- var changeInPosition = Vec3.multiplyQbyV(rotation, Vec3.multiplyVbyV(deltaPivot, changeInDimensions));
- var newPosition = Vec3.sum(initialPosition, changeInPosition);
-
- Entities.editEntity(SelectionManager.selections[0], {
- position: newPosition,
- dimensions: newDimensions
- });
-
- var wantDebug = false;
- if (wantDebug) {
- print(mode);
- Vec3.print(" changeInDimensions:", changeInDimensions);
- Vec3.print(" newDimensions:", newDimensions);
- Vec3.print(" changeInPosition:", changeInPosition);
- Vec3.print(" newPosition:", newPosition);
- }
-
- previousPickRay = pickRay;
-
- SelectionManager._update(false, this);
- }
- });
- }
-
- // TOOL DEFINITION: HANDLE SCALE TOOL
- function addHandleScaleTool(overlay, mode) {
- var initialPick = null;
- var initialPosition = null;
- var initialDimensions = null;
- var pickPlanePosition = null;
- var pickPlaneNormal = null;
- var previousPickRay = null;
- addHandleTool(overlay, {
- mode: mode,
- onBegin: function(event, pickRay, pickResult) {
- initialPosition = SelectionManager.localPosition;
- initialDimensions = SelectionManager.localDimensions;
-
- pickPlanePosition = initialPosition;
- pickPlaneNormal = Vec3.subtract(pickRay.origin, pickPlanePosition);
- initialPick = rayPlaneIntersection(pickRay, pickPlanePosition, pickPlaneNormal);
-
- that.setHandleTranslateVisible(false);
- that.setHandleRotateVisible(false);
- that.setHandleScaleVisible(true);
- that.setHandleStretchVisible(false);
- that.setHandleDuplicatorVisible(false);
-
- SelectionManager.saveProperties();
- that.resetPreviousHandleColor();
-
- var collisionToRemove = "myAvatar";
- var properties = Entities.getEntityProperties(SelectionManager.selections[0]);
- if (properties.collidesWith.indexOf(collisionToRemove) > -1) {
- var newCollidesWith = properties.collidesWith.replace(collisionToRemove, "");
- Entities.editEntity(SelectionManager.selections[0], {collidesWith: newCollidesWith});
- that.replaceCollisionsAfterStretch = true;
- }
-
- previousPickRay = pickRay;
-
- if (debugPickPlaneEnabled) {
- that.showDebugPickPlane(pickPlanePosition, pickPlaneNormal);
- that.showDebugPickPlaneHit(initialPick);
- }
- },
- onEnd: function(event, reason) {
- if (that.replaceCollisionsAfterStretch) {
- var newCollidesWith = SelectionManager.savedProperties[SelectionManager.selections[0]].collidesWith;
- Entities.editEntity(SelectionManager.selections[0], {collidesWith: newCollidesWith});
- that.replaceCollisionsAfterStretch = false;
- }
-
- pushCommandForSelections();
- },
- onMove: function(event) {
- var pickRay = generalComputePickRay(event.x, event.y);
-
- // Use previousPickRay if new pickRay will cause resulting rayPlaneIntersection values to wrap around
- if (usePreviousPickRay(pickRay.direction, previousPickRay.direction, pickPlaneNormal)) {
- pickRay = previousPickRay;
- }
-
- var newPick = rayPlaneIntersection(pickRay, pickPlanePosition, pickPlaneNormal);
- if (debugPickPlaneEnabled) {
- that.showDebugPickPlaneHit(newPick);
- }
-
- var toCameraDistance = getDistanceToCamera(initialPosition);
- var dimensionsMultiple = toCameraDistance * SCALE_DIMENSIONS_CAMERA_DISTANCE_MULTIPLE;
- var changeInDimensions = Vec3.subtract(newPick, initialPick);
- changeInDimensions = Vec3.multiplyQbyV(Quat.inverse(Camera.orientation), changeInDimensions);
- changeInDimensions = grid.snapToSpacing(changeInDimensions);
- changeInDimensions = Vec3.multiply(changeInDimensions, dimensionsMultiple);
-
- var averageDimensionChange = (changeInDimensions.x + changeInDimensions.y + changeInDimensions.z) / 3;
- var averageInitialDimension = (initialDimensions.x + initialDimensions.y + initialDimensions.z) / 3;
- percentChange = averageDimensionChange / averageInitialDimension;
- percentChange += 1.0;
-
- var newDimensions = Vec3.multiply(percentChange, initialDimensions);
- newDimensions.x = Math.abs(newDimensions.x);
- newDimensions.y = Math.abs(newDimensions.y);
- newDimensions.z = Math.abs(newDimensions.z);
-
- var minimumDimension = Entities.getPropertyInfo("dimensions").minimum;
- if (newDimensions.x < minimumDimension) {
- newDimensions.x = minimumDimension;
- changeInDimensions.x = minimumDimension - initialDimensions.x;
- }
- if (newDimensions.y < minimumDimension) {
- newDimensions.y = minimumDimension;
- changeInDimensions.y = minimumDimension - initialDimensions.y;
- }
- if (newDimensions.z < minimumDimension) {
- newDimensions.z = minimumDimension;
- changeInDimensions.z = minimumDimension - initialDimensions.z;
- }
-
- Entities.editEntity(SelectionManager.selections[0], { dimensions: newDimensions });
-
- var wantDebug = false;
- if (wantDebug) {
- print(mode);
- Vec3.print(" changeInDimensions:", changeInDimensions);
- Vec3.print(" newDimensions:", newDimensions);
- }
-
- previousPickRay = pickRay;
-
- SelectionManager._update(false, this);
- }
- });
- }
-
- // FUNCTION: UPDATE ROTATION DEGREES OVERLAY
- function updateRotationDegreesOverlay(angleFromZero, position) {
- var toCameraDistance = getDistanceToCamera(position);
- var overlayProps = {
- position: position,
- dimensions: {
- x: toCameraDistance * ROTATE_DISPLAY_SIZE_X_MULTIPLIER,
- y: toCameraDistance * ROTATE_DISPLAY_SIZE_Y_MULTIPLIER
- },
- lineHeight: toCameraDistance * ROTATE_DISPLAY_LINE_HEIGHT_MULTIPLIER,
- text: normalizeDegrees(-angleFromZero) + "°"
- };
- Overlays.editOverlay(rotationDegreesDisplay, overlayProps);
- }
-
- // FUNCTION DEF: updateSelectionsRotation
- // Helper func used by rotation handle tools
- function updateSelectionsRotation(rotationChange, initialPosition) {
- if (!rotationChange) {
- print("ERROR: entitySelectionTool.updateSelectionsRotation - Invalid arg specified!!");
-
- // EARLY EXIT
- return;
- }
-
- // Entities should only reposition if we are rotating multiple selections around
- // the selections center point. Otherwise, the rotation will be around the entities
- // registration point which does not need repositioning.
- var reposition = (SelectionManager.selections.length > 1);
-
- // editing a parent will cause all the children to automatically follow along, so don't
- // edit any entity who has an ancestor in SelectionManager.selections
- var toRotate = SelectionManager.selections.filter(function (selection) {
- if (SelectionManager.selections.indexOf(SelectionManager.savedProperties[selection].parentID) >= 0) {
- return false; // a parent is also being moved, so don't issue an edit for this entity
- } else {
- return true;
- }
- });
-
- for (var i = 0; i < toRotate.length; i++) {
- var entityID = toRotate[i];
- var initialProperties = SelectionManager.savedProperties[entityID];
-
- var newProperties = {
- rotation: Quat.multiply(rotationChange, initialProperties.rotation)
- };
-
- if (reposition) {
- var dPos = Vec3.subtract(initialProperties.position, initialPosition);
- dPos = Vec3.multiplyQbyV(rotationChange, dPos);
- newProperties.position = Vec3.sum(initialPosition, dPos);
- }
-
- Entities.editEntity(entityID, newProperties);
- }
- }
-
- // TOOL DEFINITION: HANDLE ROTATION TOOL
- function addHandleRotateTool(overlay, mode, direction) {
- var selectedHandle = null;
- var worldRotation = null;
- var initialRotation = null;
- var rotationCenter = null;
- var rotationNormal = null;
- var rotationZero = null;
- var rotationDegreesPosition = null;
- addHandleTool(overlay, {
- mode: mode,
- onBegin: function(event, pickRay, pickResult) {
- var wantDebug = false;
- if (wantDebug) {
- print("================== " + getMode() + "(addHandleRotateTool onBegin) -> =======================");
- }
-
- if (direction === ROTATE_DIRECTION.PITCH) {
- rotationNormal = { x: 1, y: 0, z: 0 };
- worldRotation = worldRotationY;
- selectedHandle = handleRotatePitchRing;
- } else if (direction === ROTATE_DIRECTION.YAW) {
- rotationNormal = { x: 0, y: 1, z: 0 };
- worldRotation = worldRotationZ;
- selectedHandle = handleRotateYawRing;
- } else if (direction === ROTATE_DIRECTION.ROLL) {
- rotationNormal = { x: 0, y: 0, z: 1 };
- worldRotation = worldRotationX;
- selectedHandle = handleRotateRollRing;
- }
-
- initialRotation = spaceMode === SPACE_LOCAL ? SelectionManager.localRotation : SelectionManager.worldRotation;
- rotationNormal = Vec3.multiplyQbyV(initialRotation, rotationNormal);
- rotationCenter = SelectionManager.worldPosition;
-
- SelectionManager.saveProperties();
- that.resetPreviousHandleColor();
-
- that.setHandleTranslateVisible(false);
- that.setHandleRotatePitchVisible(direction === ROTATE_DIRECTION.PITCH);
- that.setHandleRotateYawVisible(direction === ROTATE_DIRECTION.YAW);
- that.setHandleRotateRollVisible(direction === ROTATE_DIRECTION.ROLL);
- that.setHandleStretchVisible(false);
- that.setHandleScaleVisible(false);
- that.setHandleDuplicatorVisible(false);
-
- Overlays.editOverlay(selectedHandle, {
- hasTickMarks: true,
- solid: false,
- innerRadius: ROTATE_RING_SELECTED_INNER_RADIUS
- });
-
- Overlays.editOverlay(rotationDegreesDisplay, { visible: true });
- Overlays.editOverlay(handleRotateCurrentRing, {
- position: rotationCenter,
- rotation: worldRotation,
- startAt: 0,
- endAt: 0,
- visible: true,
- ignorePickIntersection: false
- });
-
- // editOverlays may not have committed rotation changes.
- // Compute zero position based on where the overlay will be eventually.
- var initialPick = rayPlaneIntersection(pickRay, rotationCenter, rotationNormal);
- // In case of a parallel ray, this will be null, which will cause early-out
- // in the onMove helper.
- rotationZero = initialPick;
-
- var rotationCenterToZero = Vec3.subtract(rotationZero, rotationCenter);
- var rotationCenterToZeroLength = Vec3.length(rotationCenterToZero);
- rotationDegreesPosition = Vec3.sum(rotationCenter, Vec3.multiply(Vec3.normalize(rotationCenterToZero),
- rotationCenterToZeroLength * ROTATE_DISPLAY_DISTANCE_MULTIPLIER));
- updateRotationDegreesOverlay(0, rotationDegreesPosition);
-
- if (debugPickPlaneEnabled) {
- that.showDebugPickPlane(rotationCenter, rotationNormal);
- that.showDebugPickPlaneHit(initialPick);
- }
-
- if (wantDebug) {
- print("================== " + getMode() + "(addHandleRotateTool onBegin) <- =======================");
- }
- },
- onEnd: function(event, reason) {
- var wantDebug = false;
- if (wantDebug) {
- print("================== " + getMode() + "(addHandleRotateTool onEnd) -> =======================");
- }
- Overlays.editOverlay(rotationDegreesDisplay, { visible: false, ignorePickIntersection: true });
- Overlays.editOverlay(selectedHandle, {
- hasTickMarks: false,
- solid: true,
- innerRadius: ROTATE_RING_IDLE_INNER_RADIUS
- });
- Overlays.editOverlay(handleRotateCurrentRing, { visible: false, ignorePickIntersection: true });
- pushCommandForSelections();
- if (wantDebug) {
- print("================== " + getMode() + "(addHandleRotateTool onEnd) <- =======================");
- }
- },
- onMove: function(event) {
- if (!rotationZero) {
- print("ERROR: entitySelectionTool.addHandleRotateTool.onMove - " +
- "Invalid RotationZero Specified (missed rotation target plane?)");
-
- // EARLY EXIT
- return;
- }
-
- var wantDebug = false;
- if (wantDebug) {
- print("================== "+ getMode() + "(addHandleRotateTool onMove) -> =======================");
- Vec3.print(" rotationZero: ", rotationZero);
- }
-
- var pickRay = generalComputePickRay(event.x, event.y);
- var result = rayPlaneIntersection(pickRay, rotationCenter, rotationNormal);
- if (result) {
- var centerToZero = Vec3.subtract(rotationZero, rotationCenter);
- var centerToIntersect = Vec3.subtract(result, rotationCenter);
-
- if (wantDebug) {
- Vec3.print(" RotationNormal: ", rotationNormal);
- Vec3.print(" rotationZero: ", rotationZero);
- Vec3.print(" rotationCenter: ", rotationCenter);
- Vec3.print(" intersect: ", result);
- Vec3.print(" centerToZero: ", centerToZero);
- Vec3.print(" centerToIntersect: ", centerToIntersect);
- }
-
- // Note: orientedAngle which wants normalized centerToZero and centerToIntersect
- // handles that internally, so it's to pass unnormalized vectors here.
- var angleFromZero = Vec3.orientedAngle(centerToZero, centerToIntersect, rotationNormal);
- var snapAngle = ctrlPressed ? ROTATE_CTRL_SNAP_ANGLE : ROTATE_DEFAULT_SNAP_ANGLE;
- angleFromZero = Math.floor(angleFromZero / snapAngle) * snapAngle;
- var rotationChange = Quat.angleAxis(angleFromZero, rotationNormal);
- updateSelectionsRotation(rotationChange, rotationCenter);
- updateRotationDegreesOverlay(-angleFromZero, rotationDegreesPosition);
-
- if (direction === ROTATE_DIRECTION.YAW) {
- angleFromZero *= -1;
- }
-
- var startAtCurrent = 0;
- var endAtCurrent = angleFromZero;
- var maxDegrees = 360;
- if (angleFromZero < 0) {
- startAtCurrent = maxDegrees + angleFromZero;
- endAtCurrent = maxDegrees;
- }
- Overlays.editOverlay(handleRotateCurrentRing, {
- startAt: startAtCurrent,
- endAt: endAtCurrent
- });
-
- if (debugPickPlaneEnabled) {
- that.showDebugPickPlaneHit(result);
- }
- }
-
- if (wantDebug) {
- print("================== "+ getMode() + "(addHandleRotateTool onMove) <- =======================");
- }
- }
- });
- }
-
- addHandleTranslateXZTool(selectionBox, "TRANSLATE_XZ", false);
- addHandleTranslateXZTool(iconSelectionBox, "TRANSLATE_XZ", false);
- addHandleTranslateXZTool(handleDuplicator, "DUPLICATE", true);
-
- addHandleTranslateTool(handleTranslateXCone, "TRANSLATE_X", TRANSLATE_DIRECTION.X);
- addHandleTranslateTool(handleTranslateXCylinder, "TRANSLATE_X", TRANSLATE_DIRECTION.X);
- addHandleTranslateTool(handleTranslateYCone, "TRANSLATE_Y", TRANSLATE_DIRECTION.Y);
- addHandleTranslateTool(handleTranslateYCylinder, "TRANSLATE_Y", TRANSLATE_DIRECTION.Y);
- addHandleTranslateTool(handleTranslateZCone, "TRANSLATE_Z", TRANSLATE_DIRECTION.Z);
- addHandleTranslateTool(handleTranslateZCylinder, "TRANSLATE_Z", TRANSLATE_DIRECTION.Z);
-
- addHandleRotateTool(handleRotatePitchRing, "ROTATE_PITCH", ROTATE_DIRECTION.PITCH);
- addHandleRotateTool(handleRotateYawRing, "ROTATE_YAW", ROTATE_DIRECTION.YAW);
- addHandleRotateTool(handleRotateRollRing, "ROTATE_ROLL", ROTATE_DIRECTION.ROLL);
-
- addHandleStretchTool(handleStretchXCube, "STRETCH_X", STRETCH_DIRECTION.X);
- addHandleStretchTool(handleStretchYCube, "STRETCH_Y", STRETCH_DIRECTION.Y);
- addHandleStretchTool(handleStretchZCube, "STRETCH_Z", STRETCH_DIRECTION.Z);
-
- addHandleScaleTool(handleScaleCube, "SCALE");
-
- return that;
-}());
diff --git a/scripts/simplifiedUI/system/assets/images/hourglass.svg b/scripts/system/create/assets/images/hourglass.svg
similarity index 100%
rename from scripts/simplifiedUI/system/assets/images/hourglass.svg
rename to scripts/system/create/assets/images/hourglass.svg
diff --git a/scripts/system/create/edit.js b/scripts/system/create/edit.js
index ae7cd43767..f50bc547e5 100644
--- a/scripts/system/create/edit.js
+++ b/scripts/system/create/edit.js
@@ -31,7 +31,7 @@ Script.include([
"../libraries/entityCameraTool.js",
"../libraries/utils.js",
"../libraries/entityIconOverlayManager.js",
- "../libraries/gridTool/gridTool.js",
+ "../libraries/gridTool.js",
"entityList/entityList.js",
"entitySelectionTool/entitySelectionTool.js"
]);
diff --git a/scripts/system/create/modules/entityShapeVisualizer.js b/scripts/system/create/modules/entityShapeVisualizer.js
index da28369cdd..dbf09a1cb7 100644
--- a/scripts/system/create/modules/entityShapeVisualizer.js
+++ b/scripts/system/create/modules/entityShapeVisualizer.js
@@ -146,8 +146,8 @@ EntityShape.prototype = {
parentID: this.entity,
priority: 1,
materialMappingMode: PROJECTED_MATERIALS ? "projected" : "uv",
- materialURL: Script.resolvePath("../assets/images/materials/GridPattern.json"),
- ignorePickIntersection: true,
+ materialURL: Script.resolvePath("../../assets/images/materials/GridPattern.json"),
+ ignorePickIntersection: true
}, "local");
},
update: function() {
diff --git a/scripts/system/create/qml/EditTabView.qml b/scripts/system/create/qml/EditTabView.qml
index 4c780c3427..f90a962f7a 100644
--- a/scripts/system/create/qml/EditTabView.qml
+++ b/scripts/system/create/qml/EditTabView.qml
@@ -263,7 +263,7 @@ TabBar {
property Component visualItem: Component {
WebView {
id: gridControlsWebView
- url: Qt.resolvedURL("../../libraries/gridTool/html/gridControls.html")
+ url: Qt.resolvedURL("../../html/gridControls.html")
enabled: true
blurOnCtrlShift: false
}
diff --git a/scripts/system/create/qml/EditToolsTabView.qml b/scripts/system/create/qml/EditToolsTabView.qml
index fdba4cdbc9..0ce8d8e8d4 100644
--- a/scripts/system/create/qml/EditToolsTabView.qml
+++ b/scripts/system/create/qml/EditToolsTabView.qml
@@ -253,7 +253,7 @@ TabBar {
property Component visualItem: Component {
WebView {
id: gridControlsWebView
- url: Qt.resolvedUrl("../../libraries/gridTool/html/gridControls.html")
+ url: Qt.resolvedUrl("../../html/gridControls.html")
enabled: true
blurOnCtrlShift: false
}
diff --git a/scripts/system/marketplaces/marketplaces.js b/scripts/system/marketplaces/marketplaces.js
index 5c7623066b..38287e3af3 100644
--- a/scripts/system/marketplaces/marketplaces.js
+++ b/scripts/system/marketplaces/marketplaces.js
@@ -17,7 +17,7 @@ var selectionDisplay = null; // for gridTool.js to ignore
(function () { // BEGIN LOCAL_SCOPE
var AppUi = Script.require('appUi');
-Script.include("/~/system/libraries/gridTool/gridTool.js");
+Script.include("/~/system/libraries/gridTool.js");
Script.include("/~/system/libraries/connectionUtils.js");
Script.include("/~/system/libraries/accountUtils.js");