From 6302ae6bd5d204b91a5a2773a3cb1d8d738c20b7 Mon Sep 17 00:00:00 2001 From: Menithal Date: Wed, 15 Feb 2017 19:48:29 +0200 Subject: [PATCH 01/33] Changed AudioScope Hotkeys, Allowing User Hotkeys AudioScope Open Hotkey changed from Ctrl + P to Ctrl + Alt + P and Audioscope Pause Hotkey changed from Ctrl + Shift + P to Ctrl + Shift + Alt + P --- interface/src/Menu.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index acf97ad5f7..431fe0638a 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -577,7 +577,7 @@ Menu::Menu() { nodeList.data(), SLOT(toggleSendNewerDSConnectVersion(bool))); #endif - + // Developer >> Tests >>> MenuWrapper* testMenu = developerMenu->addMenu("Tests"); addActionToQMenuAndActionHash(testMenu, MenuOption::RunClientScriptTests, 0, dialogsManager.data(), SLOT(showTestingResults())); @@ -628,9 +628,9 @@ Menu::Menu() { auto scope = DependencyManager::get(); MenuWrapper* audioScopeMenu = audioDebugMenu->addMenu("Audio Scope"); - addCheckableActionToQMenuAndActionHash(audioScopeMenu, MenuOption::AudioScope, Qt::CTRL | Qt::Key_P, false, + addCheckableActionToQMenuAndActionHash(audioScopeMenu, MenuOption::AudioScope, Qt::CTRL | Qt::ALT | Qt::Key_P, false, scope.data(), SLOT(toggle())); - addCheckableActionToQMenuAndActionHash(audioScopeMenu, MenuOption::AudioScopePause, Qt::CTRL | Qt::SHIFT | Qt::Key_P, false, + addCheckableActionToQMenuAndActionHash(audioScopeMenu, MenuOption::AudioScopePause, Qt::CTRL | Qt::ALT | Qt::SHIFT | Qt::Key_P, false, scope.data(), SLOT(togglePause())); addDisabledActionAndSeparator(audioScopeMenu, "Display Frames"); From 7b02d1073a08cca23b904f2c1848b38fe7a9ca5a Mon Sep 17 00:00:00 2001 From: Menithal Date: Wed, 15 Feb 2017 19:49:31 +0200 Subject: [PATCH 02/33] Added a generic Window Notification for Feedback This allows to use the existing Pop-up notifications for generic notification messages --- scripts/system/notifications.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/system/notifications.js b/scripts/system/notifications.js index 3ae071c7e3..b2ebb1fd46 100644 --- a/scripts/system/notifications.js +++ b/scripts/system/notifications.js @@ -521,6 +521,9 @@ function onEditError(msg) { createNotification(wordWrap(msg), NotificationType.EDIT_ERROR); } +function onNotify(msg) { + createNotification(wordWrap(msg), NotificationType.UNKNOWN); // Needs a generic notification system for user feedback, thus using this +} function onSnapshotTaken(pathStillSnapshot, pathAnimatedSnapshot, notify) { if (notify) { @@ -637,6 +640,7 @@ Window.domainConnectionRefused.connect(onDomainConnectionRefused); Window.snapshotTaken.connect(onSnapshotTaken); Window.processingGif.connect(processingGif); Window.notifyEditError = onEditError; +Window.notify = onNotify; setup(); From 655c49d9c00f68d8a6f6814d819ceffd1032ce7a Mon Sep 17 00:00:00 2001 From: Menithal Date: Wed, 15 Feb 2017 19:50:15 +0200 Subject: [PATCH 03/33] edit.js: started to work on Parenting via hotkey --- scripts/system/edit.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/scripts/system/edit.js b/scripts/system/edit.js index da39edf8ba..5476e1208f 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -1096,7 +1096,30 @@ function recursiveDelete(entities, childrenList) { Entities.deleteEntity(entityID); } } +function parentSelectedEntities() { + if (SelectionManager.hasSelection()) { + SelectionManager.saveProperties(); + var selectedEntities = selectionManager.selections; + if (selectedEntities.length <= 1) { + Window.notifyEditError("You must have multiple objects selected in order to parent them"); + return; + } + var lastEntityId = selectedEntities[selectedEntities.length] + selectedEntities.some(function (id, index) { + if (lastId === id) { + return false; + } + Entities.editProperties(id, {parentID: lastId}) + return true; + }); + SelectionManager.clearSelections(); + + Window.notify("Entities Parented"); + } else { + Window.notifyEditError("You have nothing selected") + } +} function deleteSelectedEntities() { if (SelectionManager.hasSelection()) { selectedParticleEntity = 0; @@ -1324,6 +1347,8 @@ Controller.keyReleaseEvent.connect(function (event) { }); grid.setPosition(newPosition); } + } else if (event.text === 'p' && event.isCtrl) { + parentSelectedEntities(); } }); From c3021ae60d917bb7c50df1757d07f6e5f46aa25b Mon Sep 17 00:00:00 2001 From: Menithal Date: Wed, 15 Feb 2017 22:21:29 +0200 Subject: [PATCH 04/33] Fixing Menu Items for Parenting / Unparenting --- scripts/system/edit.js | 78 ++++++++++++++++++++++++++++++++---------- 1 file changed, 59 insertions(+), 19 deletions(-) diff --git a/scripts/system/edit.js b/scripts/system/edit.js index 5476e1208f..afb171e936 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -838,7 +838,6 @@ function setupModelMenus() { }); modelMenuAddedDelete = true; } - Menu.addMenuItem({ menuName: "Edit", menuItemName: "Entity List...", @@ -846,6 +845,23 @@ function setupModelMenus() { afterItem: "Entities", grouping: "Advanced" }); + + Menu.addMenuItem({ + menuName: "Edit", + menuItemName: "Parent Entity to Last", + shortcutKey: "CTRL+P", + afterItem: "Entity List...", + grouping: "Advanced" + }); + + Menu.addMenuItem({ + menuName: "Edit", + menuItemName: "Unparent Entity", + afterItem: "Entity List...", + shortcutKey: "CTRL+SHIFT+P", + afterItem: "Entity List...", + grouping: "Advanced" + }); Menu.addMenuItem({ menuName: "Edit", menuItemName: "Allow Selecting of Large Models", @@ -953,6 +969,8 @@ function cleanupModelMenus() { Menu.removeMenuItem("Edit", "Delete"); } + Menu.removeMenuItem("Edit", "Parent"); + Menu.removeMenuItem("Edit", "Unparent"); Menu.removeMenuItem("Edit", "Entity List..."); Menu.removeMenuItem("Edit", "Allow Selecting of Large Models"); Menu.removeMenuItem("Edit", "Allow Selecting of Small Models"); @@ -1096,28 +1114,42 @@ function recursiveDelete(entities, childrenList) { Entities.deleteEntity(entityID); } } -function parentSelectedEntities() { +function unparentSelectedEntities() { + print("unparenting2 Selected Entities"); if (SelectionManager.hasSelection()) { - SelectionManager.saveProperties(); var selectedEntities = selectionManager.selections; - if (selectedEntities.length <= 1) { - Window.notifyEditError("You must have multiple objects selected in order to parent them"); - return; - } - - var lastEntityId = selectedEntities[selectedEntities.length] - selectedEntities.some(function (id, index) { - if (lastId === id) { - return false; - } - Entities.editProperties(id, {parentID: lastId}) + selectedEntities.forEach(function (id, index) { + Entities.editEntity(id, {parentID: null}) return true; }); - SelectionManager.clearSelections(); - Window.notify("Entities Parented"); + Window.notify("Entities Unparented"); + } + +} +function parentSelectedEntities() { + print("parenting selected Entities"); + if (SelectionManager.hasSelection()) { + var selectedEntities = selectionManager.selections; + if (selectedEntities.length <= 1) { + Window.notifyEditError("You must have multiple objects selected in order to parent them"); + return; + } + var lastEntityId = selectedEntities[selectedEntities.length-1]; + + print("last " + lastEntityId); + selectedEntities.forEach(function (id, index) { + if (lastEntityId !== id) { + print("iterating2 " + id); + + // OK time to check why this breaks! + Entities.editEntity(id, {parentID: lastEntityId}) + } + }); + + Window.notify("Entities Parented"); } else { - Window.notifyEditError("You have nothing selected") + Window.notifyEditError("You have nothing selected") } } function deleteSelectedEntities() { @@ -1182,6 +1214,10 @@ function handeMenuEvent(menuItem) { Entities.setLightsArePickable(Menu.isOptionChecked("Allow Selecting of Lights")); } else if (menuItem === "Delete") { deleteSelectedEntities(); + } else if (menuItem === "Parent") { + parentSelectedEntities(); + } else if (menuItem === "Unparent") { + unparentSelectedEntities(); } else if (menuItem === "Export Entities") { if (!selectionManager.hasSelection()) { Window.notifyEditError("No entities have been selected."); @@ -1347,8 +1383,12 @@ Controller.keyReleaseEvent.connect(function (event) { }); grid.setPosition(newPosition); } - } else if (event.text === 'p' && event.isCtrl) { - parentSelectedEntities(); + } else if (event.text === 'p' && event.isControl ) { + if (event.isShifted) { + unparentSelectedEntities(); + } else { + parentSelectedEntities(); + } } }); From ff2c344eaaab3e7e6d121415fb8530277ea46428 Mon Sep 17 00:00:00 2001 From: Menithal Date: Thu, 16 Feb 2017 09:04:58 +0200 Subject: [PATCH 05/33] Migrated Audioscope Hotkeys to use F2 instead of P Apparently ctrl + shift + P which was planned to be used in the client for unparenting entities did not work out, as the command went out of the main view. Migrating to ctrl + F2 and ctrl + alt + F2 --- interface/src/Menu.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 431fe0638a..3ff5e00c06 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -628,9 +628,9 @@ Menu::Menu() { auto scope = DependencyManager::get(); MenuWrapper* audioScopeMenu = audioDebugMenu->addMenu("Audio Scope"); - addCheckableActionToQMenuAndActionHash(audioScopeMenu, MenuOption::AudioScope, Qt::CTRL | Qt::ALT | Qt::Key_P, false, + addCheckableActionToQMenuAndActionHash(audioScopeMenu, MenuOption::AudioScope, Qt::CTRL | Qt::Key_F2, false, scope.data(), SLOT(toggle())); - addCheckableActionToQMenuAndActionHash(audioScopeMenu, MenuOption::AudioScopePause, Qt::CTRL | Qt::ALT | Qt::SHIFT | Qt::Key_P, false, + addCheckableActionToQMenuAndActionHash(audioScopeMenu, MenuOption::AudioScopePause, Qt::CTRL | Qt::ALT | Qt::Key_F2, false, scope.data(), SLOT(togglePause())); addDisabledActionAndSeparator(audioScopeMenu, "Display Frames"); From d96f95a7e9b52765137c2c8d1d27eb93f9eba776 Mon Sep 17 00:00:00 2001 From: Menithal Date: Thu, 16 Feb 2017 10:05:59 +0200 Subject: [PATCH 06/33] Updated edit.js and selection tool Last selected entity will now be yellow instead of orange --- scripts/system/edit.js | 8 +------ .../system/libraries/entitySelectionTool.js | 22 +++++++++++-------- 2 files changed, 14 insertions(+), 16 deletions(-) diff --git a/scripts/system/edit.js b/scripts/system/edit.js index afb171e936..1c76e03efd 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -1115,7 +1115,6 @@ function recursiveDelete(entities, childrenList) { } } function unparentSelectedEntities() { - print("unparenting2 Selected Entities"); if (SelectionManager.hasSelection()) { var selectedEntities = selectionManager.selections; selectedEntities.forEach(function (id, index) { @@ -1128,7 +1127,6 @@ function unparentSelectedEntities() { } function parentSelectedEntities() { - print("parenting selected Entities"); if (SelectionManager.hasSelection()) { var selectedEntities = selectionManager.selections; if (selectedEntities.length <= 1) { @@ -1137,16 +1135,12 @@ function parentSelectedEntities() { } var lastEntityId = selectedEntities[selectedEntities.length-1]; - print("last " + lastEntityId); selectedEntities.forEach(function (id, index) { if (lastEntityId !== id) { - print("iterating2 " + id); - // OK time to check why this breaks! Entities.editEntity(id, {parentID: lastEntityId}) } }); - Window.notify("Entities Parented"); } else { Window.notifyEditError("You have nothing selected") @@ -1384,7 +1378,7 @@ Controller.keyReleaseEvent.connect(function (event) { grid.setPosition(newPosition); } } else if (event.text === 'p' && event.isControl ) { - if (event.isShifted) { + if (event.isAlt) { unparentSelectedEntities(); } else { parentSelectedEntities(); diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index b9bae72d14..146dc1894b 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -1170,14 +1170,14 @@ SelectionDisplay = (function() { // determine which bottom corner we are closest to /*------------------------------ example: - + BRF +--------+ BLF | | | | BRN +--------+ BLN - + * - + ------------------------------*/ var cameraPosition = Camera.getPosition(); @@ -2189,8 +2189,12 @@ SelectionDisplay = (function() { offset = Vec3.multiplyQbyV(properties.rotation, offset); var boxPosition = Vec3.sum(properties.position, offset); + var color = {red: 255, green: 153, blue: 0}; + if (i >= selectionManager.selections.length - 1) color = {red: 255, green: 255, blue: 0}; + Overlays.editOverlay(selectionBoxes[i], { position: boxPosition, + color: color, rotation: properties.rotation, dimensions: properties.dimensions, visible: true, @@ -2395,7 +2399,7 @@ SelectionDisplay = (function() { if (wantDebug) { print("Start Elevation: " + translateXZTool.startingElevation + ", elevation: " + elevation); } - if ((translateXZTool.startingElevation > 0.0 && elevation < MIN_ELEVATION) || + if ((translateXZTool.startingElevation > 0.0 && elevation < MIN_ELEVATION) || (translateXZTool.startingElevation < 0.0 && elevation > -MIN_ELEVATION)) { if (wantDebug) { print("too close to horizon!"); @@ -3857,7 +3861,7 @@ SelectionDisplay = (function() { }; that.mousePressEvent = function(event) { - var wantDebug = false; + var wantDebug = false; if (!event.isLeftButton && !that.triggered) { // if another mouse button than left is pressed ignore it return false; @@ -3883,7 +3887,7 @@ SelectionDisplay = (function() { if (result.intersects) { - + if (wantDebug) { print("something intersects... "); print(" result.overlayID:" + result.overlayID + "[" + overlayNames[result.overlayID] + "]"); @@ -3983,7 +3987,7 @@ SelectionDisplay = (function() { if (wantDebug) { print("rotate handle case..."); } - + // After testing our stretch handles, then check out rotate handles Overlays.editOverlay(yawHandle, { @@ -4205,7 +4209,7 @@ SelectionDisplay = (function() { case selectionBox: activeTool = translateXZTool; translateXZTool.pickPlanePosition = result.intersection; - translateXZTool.greatestDimension = Math.max(Math.max(SelectionManager.worldDimensions.x, SelectionManager.worldDimensions.y), + translateXZTool.greatestDimension = Math.max(Math.max(SelectionManager.worldDimensions.x, SelectionManager.worldDimensions.y), SelectionManager.worldDimensions.z); if (wantDebug) { print("longest dimension: " + translateXZTool.greatestDimension); @@ -4214,7 +4218,7 @@ SelectionDisplay = (function() { translateXZTool.startingElevation = translateXZTool.elevation(pickRay.origin, translateXZTool.pickPlanePosition); print(" starting elevation: " + translateXZTool.startingElevation); } - + mode = translateXZTool.mode; activeTool.onBegin(event); somethingClicked = 'selectionBox'; From 7a5665ff4f2370f1cae6b018cb2568cd07a3aa59 Mon Sep 17 00:00:00 2001 From: Menithal Date: Thu, 16 Feb 2017 10:09:19 +0200 Subject: [PATCH 07/33] Hotkey change to make AudioScope similar to earlier --- interface/src/Menu.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 3ff5e00c06..c131367aee 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -630,7 +630,7 @@ Menu::Menu() { MenuWrapper* audioScopeMenu = audioDebugMenu->addMenu("Audio Scope"); addCheckableActionToQMenuAndActionHash(audioScopeMenu, MenuOption::AudioScope, Qt::CTRL | Qt::Key_F2, false, scope.data(), SLOT(toggle())); - addCheckableActionToQMenuAndActionHash(audioScopeMenu, MenuOption::AudioScopePause, Qt::CTRL | Qt::ALT | Qt::Key_F2, false, + addCheckableActionToQMenuAndActionHash(audioScopeMenu, MenuOption::AudioScopePause, Qt::CTRL | Qt::SHIFT | Qt::Key_F2, false, scope.data(), SLOT(togglePause())); addDisabledActionAndSeparator(audioScopeMenu, "Display Frames"); From afbf4bc30f53cd63efc2df1ab5ebfa14de7ec65d Mon Sep 17 00:00:00 2001 From: Menithal Date: Thu, 16 Feb 2017 10:52:42 +0200 Subject: [PATCH 08/33] Fixed Parenting/Unparenting Menu Removal and Binding --- scripts/system/edit.js | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/scripts/system/edit.js b/scripts/system/edit.js index 1c76e03efd..b83ca9a896 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -969,8 +969,8 @@ function cleanupModelMenus() { Menu.removeMenuItem("Edit", "Delete"); } - Menu.removeMenuItem("Edit", "Parent"); - Menu.removeMenuItem("Edit", "Unparent"); + Menu.removeMenuItem("Edit", "Parent Entity to Last"); + Menu.removeMenuItem("Edit", "Unparent Entity"); Menu.removeMenuItem("Edit", "Entity List..."); Menu.removeMenuItem("Edit", "Allow Selecting of Large Models"); Menu.removeMenuItem("Edit", "Allow Selecting of Small Models"); @@ -1134,10 +1134,8 @@ function parentSelectedEntities() { return; } var lastEntityId = selectedEntities[selectedEntities.length-1]; - selectedEntities.forEach(function (id, index) { if (lastEntityId !== id) { - // OK time to check why this breaks! Entities.editEntity(id, {parentID: lastEntityId}) } }); @@ -1208,9 +1206,9 @@ function handeMenuEvent(menuItem) { Entities.setLightsArePickable(Menu.isOptionChecked("Allow Selecting of Lights")); } else if (menuItem === "Delete") { deleteSelectedEntities(); - } else if (menuItem === "Parent") { + } else if (menuItem === "Parent Entity to Last") { parentSelectedEntities(); - } else if (menuItem === "Unparent") { + } else if (menuItem === "Unparent Entity") { unparentSelectedEntities(); } else if (menuItem === "Export Entities") { if (!selectionManager.hasSelection()) { @@ -1378,7 +1376,7 @@ Controller.keyReleaseEvent.connect(function (event) { grid.setPosition(newPosition); } } else if (event.text === 'p' && event.isControl ) { - if (event.isAlt) { + if (event.isShifted) { unparentSelectedEntities(); } else { parentSelectedEntities(); From f5d266a56253703e35a8baf78159479ccac22ac7 Mon Sep 17 00:00:00 2001 From: Menithal Date: Fri, 17 Feb 2017 23:28:28 +0200 Subject: [PATCH 09/33] Updated --- scripts/system/edit.js | 26 ++++++++++++------- scripts/system/html/entityList.html | 3 +++ scripts/system/html/entityProperties.html | 3 ++- scripts/system/html/js/parentingHotkey.js | 12 +++++++++ .../system/libraries/entitySelectionTool.js | 4 +-- 5 files changed, 36 insertions(+), 12 deletions(-) create mode 100644 scripts/system/html/js/parentingHotkey.js diff --git a/scripts/system/edit.js b/scripts/system/edit.js index b83ca9a896..d759760893 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -859,7 +859,6 @@ function setupModelMenus() { menuItemName: "Unparent Entity", afterItem: "Entity List...", shortcutKey: "CTRL+SHIFT+P", - afterItem: "Entity List...", grouping: "Advanced" }); Menu.addMenuItem({ @@ -1003,6 +1002,9 @@ Script.scriptEnding.connect(function () { Overlays.deleteOverlay(importingSVOImageOverlay); Overlays.deleteOverlay(importingSVOTextOverlay); + + Controller.keyReleaseEvent.disconnect(keyReleaseEvent); + Controller.keyPressEvent.disconnect(keyPressEvent); }); var lastOrientation = null; @@ -1121,10 +1123,8 @@ function unparentSelectedEntities() { Entities.editEntity(id, {parentID: null}) return true; }); - Window.notify("Entities Unparented"); } - } function parentSelectedEntities() { if (SelectionManager.hasSelection()) { @@ -1335,13 +1335,12 @@ Window.svoImportRequested.connect(importSVO); Menu.menuItemEvent.connect(handeMenuEvent); -Controller.keyPressEvent.connect(function (event) { +var keyPressEvent = function (event) { if (isActive) { cameraManager.keyPressEvent(event); } -}); - -Controller.keyReleaseEvent.connect(function (event) { +}; +var keyReleaseEvent = function (event) { if (isActive) { cameraManager.keyReleaseEvent(event); } @@ -1375,14 +1374,16 @@ Controller.keyReleaseEvent.connect(function (event) { }); grid.setPosition(newPosition); } - } else if (event.text === 'p' && event.isControl ) { + } else if (event.text === 'p' && event.isControl && !event.isAutoRepeat ) { if (event.isShifted) { unparentSelectedEntities(); } else { parentSelectedEntities(); } } -}); +}; +Controller.keyReleaseEvent.connect(keyReleaseEvent); +Controller.keyPressEvent.connect(keyPressEvent); function recursiveAdd(newParentID, parentData) { var children = parentData.children; @@ -1632,6 +1633,10 @@ var PropertiesTool = function (opts) { } pushCommandForSelections(); selectionManager._update(); + } else if(data.type === 'parent') { + parentSelectedEntities(); + } else if(data.type === 'unparent') { + unparentSelectedEntities(); } else if(data.type === 'saveUserData'){ //the event bridge and json parsing handle our avatar id string differently. var actualID = data.id.split('"')[1]; @@ -1889,6 +1894,9 @@ var PopupMenu = function () { 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); } Controller.mousePressEvent.connect(self.mousePressEvent); diff --git a/scripts/system/html/entityList.html b/scripts/system/html/entityList.html index 197d8f550a..67d1973fa7 100644 --- a/scripts/system/html/entityList.html +++ b/scripts/system/html/entityList.html @@ -16,6 +16,7 @@ +
@@ -89,6 +90,8 @@ + +
No entities found in view within a 100 meter radius. Try moving to a different location and refreshing.
diff --git a/scripts/system/html/entityProperties.html b/scripts/system/html/entityProperties.html index b11127b26c..84c8a15dd3 100644 --- a/scripts/system/html/entityProperties.html +++ b/scripts/system/html/entityProperties.html @@ -22,6 +22,7 @@ +
@@ -61,7 +62,7 @@
- +

diff --git a/scripts/system/html/js/parentingHotkey.js b/scripts/system/html/js/parentingHotkey.js new file mode 100644 index 0000000000..c17dae01fe --- /dev/null +++ b/scripts/system/html/js/parentingHotkey.js @@ -0,0 +1,12 @@ +var keyReleaseEvent = function (event) { + if (event.text === 'p' && event.isControl && !event.isAutoRepeat ) { + if (event.isShifted) { + EventBridge.emitWebEvent(JSON.stringify({ type: 'unparent' })); + } else { + EventBridge.emitWebEvent(JSON.stringify({ type: 'parent' })); + } + } +}; + +window.onkeypress = keyReleaseEvent; +Controller.keyReleaseEvent.connect(keyReleaseEvent); diff --git a/scripts/system/libraries/entitySelectionTool.js b/scripts/system/libraries/entitySelectionTool.js index 146dc1894b..13f61dfd80 100644 --- a/scripts/system/libraries/entitySelectionTool.js +++ b/scripts/system/libraries/entitySelectionTool.js @@ -2189,8 +2189,8 @@ SelectionDisplay = (function() { offset = Vec3.multiplyQbyV(properties.rotation, offset); var boxPosition = Vec3.sum(properties.position, offset); - var color = {red: 255, green: 153, blue: 0}; - if (i >= selectionManager.selections.length - 1) color = {red: 255, green: 255, blue: 0}; + var color = {red: 255, green: 128, blue: 0}; + if (i >= selectionManager.selections.length - 1) color = {red: 255, green: 255, blue: 64}; Overlays.editOverlay(selectionBoxes[i], { position: boxPosition, From dcbe3c622db92d2e5729813392a9c483c5ae1c22 Mon Sep 17 00:00:00 2001 From: Menithal Date: Sat, 18 Feb 2017 11:51:19 +0200 Subject: [PATCH 10/33] Added Hotkey Listening to the webview Ctrl + P and Ctrl + Shift + P are now available even if the edit window has been selected --- scripts/system/edit.js | 13 +++---- scripts/system/html/entityList.html | 2 - scripts/system/html/entityProperties.html | 1 - scripts/system/html/js/entityList.js | 44 ++++++++++++---------- scripts/system/html/js/entityProperties.js | 16 ++++++-- scripts/system/html/js/gridControls.js | 11 +++++- scripts/system/html/js/parentingHotkey.js | 12 ------ 7 files changed, 52 insertions(+), 47 deletions(-) delete mode 100644 scripts/system/html/js/parentingHotkey.js diff --git a/scripts/system/edit.js b/scripts/system/edit.js index d759760893..d0236ce993 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -1374,12 +1374,6 @@ var keyReleaseEvent = function (event) { }); grid.setPosition(newPosition); } - } else if (event.text === 'p' && event.isControl && !event.isAutoRepeat ) { - if (event.isShifted) { - unparentSelectedEntities(); - } else { - parentSelectedEntities(); - } } }; Controller.keyReleaseEvent.connect(keyReleaseEvent); @@ -1586,6 +1580,7 @@ var PropertiesTool = function (opts) { print('Edit.js received web event that was not valid json.') return; } + print(JSON.stringify(data)) var i, properties, dY, diff, newPosition; if (data.type === "print") { if (data.message) { @@ -1924,7 +1919,11 @@ var particleExplorerTool = new ParticleExplorerTool(); var selectedParticleEntity = 0; entityListTool.webView.webEventReceived.connect(function (data) { data = JSON.parse(data); - if (data.type === "selectionUpdate") { + if(data.type === 'parent') { + parentSelectedEntities(); + } else if(data.type === 'unparent') { + unparentSelectedEntities(); + } else if (data.type === "selectionUpdate") { var ids = data.entityIds; if (ids.length === 1) { if (Entities.getEntityProperties(ids[0], "type").type === "ParticleEffect") { diff --git a/scripts/system/html/entityList.html b/scripts/system/html/entityList.html index 67d1973fa7..3cb79353f9 100644 --- a/scripts/system/html/entityList.html +++ b/scripts/system/html/entityList.html @@ -16,7 +16,6 @@ -
@@ -91,7 +90,6 @@ -
No entities found in view within a 100 meter radius. Try moving to a different location and refreshing.
diff --git a/scripts/system/html/entityProperties.html b/scripts/system/html/entityProperties.html index 84c8a15dd3..cc73d71517 100644 --- a/scripts/system/html/entityProperties.html +++ b/scripts/system/html/entityProperties.html @@ -22,7 +22,6 @@ -
diff --git a/scripts/system/html/js/entityList.js b/scripts/system/html/js/entityList.js index 1af9c1e1d6..53d2d9030b 100644 --- a/scripts/system/html/js/entityList.js +++ b/scripts/system/html/js/entityList.js @@ -26,7 +26,7 @@ debugPrint = function (message) { }; function loaded() { - openEventBridge(function() { + openEventBridge(function() { entityList = new List('entity-list', { valueNames: ['name', 'type', 'url', 'locked', 'visible'], page: MAX_ITEMS}); entityList.clear(); elEntityTable = document.getElementById("entity-table"); @@ -48,7 +48,7 @@ function loaded() { elNoEntitiesInView = document.getElementById("no-entities-in-view"); elNoEntitiesRadius = document.getElementById("no-entities-radius"); elEntityTableScroll = document.getElementById("entity-table-scroll"); - + document.getElementById("entity-name").onclick = function() { setSortColumn('name'); }; @@ -90,7 +90,7 @@ function loaded() { selection = selection.concat(selectedEntities); } else if (clickEvent.shiftKey && selectedEntities.length > 0) { var previousItemFound = -1; - var clickedItemFound = -1; + var clickedItemFound = -1; for (var entity in entityList.visibleItems) { if (clickedItemFound === -1 && this.dataset.entityId == entityList.visibleItems[entity].values().id) { clickedItemFound = entity; @@ -113,11 +113,11 @@ function loaded() { selection = selection.concat(betweenItems, selectedEntities); } } - + selectedEntities = selection; - + this.className = 'selected'; - + EventBridge.emitWebEvent(JSON.stringify({ type: "selectionUpdate", focus: false, @@ -126,7 +126,7 @@ function loaded() { refreshFooter(); } - + function onRowDoubleClicked() { EventBridge.emitWebEvent(JSON.stringify({ type: "selectionUpdate", @@ -134,7 +134,7 @@ function loaded() { entityIds: [this.dataset.entityId], })); } - + const BYTES_PER_MEGABYTE = 1024 * 1024; function decimalMegabytes(number) { @@ -173,7 +173,7 @@ function loaded() { currentElement.onclick = onRowClicked; currentElement.ondblclick = onRowDoubleClicked; }); - + if (refreshEntityListTimer) { clearTimeout(refreshEntityListTimer); } @@ -183,13 +183,13 @@ function loaded() { item.values({ name: name, url: filename, locked: locked, visible: visible }); } } - + function clearEntities() { entities = {}; entityList.clear(); refreshFooter(); } - + var elSortOrder = { name: document.querySelector('#entity-name .sort-order'), type: document.querySelector('#entity-type .sort-order'), @@ -215,12 +215,12 @@ function loaded() { entityList.sort(currentSortColumn, { order: currentSortOrder }); } setSortColumn('type'); - + function refreshEntities() { clearEntities(); EventBridge.emitWebEvent(JSON.stringify({ type: 'refresh' })); } - + function refreshFooter() { if (selectedEntities.length > 1) { elFooter.firstChild.nodeValue = selectedEntities.length + " entities selected"; @@ -239,7 +239,7 @@ function loaded() { entityList.search(elFilter.value); refreshFooter(); } - + function updateSelectedEntities(selectedIDs) { var notFound = false; for (var id in entities) { @@ -262,7 +262,7 @@ function loaded() { return notFound; } - + elRefresh.onclick = function() { refreshEntities(); } @@ -282,7 +282,7 @@ function loaded() { EventBridge.emitWebEvent(JSON.stringify({ type: 'delete' })); refreshEntities(); } - + document.addEventListener("keydown", function (keyDownEvent) { if (keyDownEvent.target.nodeName === "INPUT") { return; @@ -292,8 +292,15 @@ function loaded() { EventBridge.emitWebEvent(JSON.stringify({ type: 'delete' })); refreshEntities(); } + if (keyDownEvent.keyCode === 80 && keyDownEvent.ctrlKey) { + if (keyDownEvent.shiftKey) { + EventBridge.emitWebEvent(JSON.stringify({ type: 'unparent' })); + } else { + EventBridge.emitWebEvent(JSON.stringify({ type: 'parent' })); + } + } }, false); - + var isFilterInView = false; var FILTER_IN_VIEW_ATTRIBUTE = "pressed"; elNoEntitiesInView.style.display = "none"; @@ -320,7 +327,7 @@ function loaded() { if (window.EventBridge !== undefined) { EventBridge.scriptEventReceived.connect(function(data) { data = JSON.parse(data); - + if (data.type === "clearEntityList") { clearEntities(); } else if (data.type == "selectionUpdate") { @@ -426,4 +433,3 @@ function loaded() { event.preventDefault(); }, false); } - diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index 8879c0f34e..ab8a3f7c85 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -273,7 +273,7 @@ function updateCheckedSubProperty(propertyName, propertyValue, subPropertyElemen propertyValue += subPropertyString + ','; } } else { - // We've unchecked, so remove + // We've unchecked, so remove propertyValue = propertyValue.replace(subPropertyString + ",", ""); } @@ -780,7 +780,7 @@ function loaded() { if (lastEntityID !== '"' + properties.id + '"' && lastEntityID !== null && editor !== null) { saveJSONUserData(true); } - //the event bridge and json parsing handle our avatar id string differently. + //the event bridge and json parsing handle our avatar id string differently. lastEntityID = '"' + properties.id + '"'; elID.innerHTML = properties.id; @@ -1390,7 +1390,7 @@ function loaded() { elZoneFlyingAllowed.addEventListener('change', createEmitCheckedPropertyUpdateFunction('flyingAllowed')); elZoneGhostingAllowed.addEventListener('change', createEmitCheckedPropertyUpdateFunction('ghostingAllowed')); elZoneFilterURL.addEventListener('change', createEmitTextPropertyUpdateFunction('filterURL')); - + var voxelVolumeSizeChangeFunction = createEmitVec3PropertyUpdateFunction( 'voxelVolumeSize', elVoxelVolumeSizeX, elVoxelVolumeSizeY, elVoxelVolumeSizeZ); elVoxelVolumeSizeX.addEventListener('change', voxelVolumeSizeChangeFunction); @@ -1441,7 +1441,15 @@ function loaded() { })); }); - + document.addEventListener("keydown", function (keyDown) { + if (keyDown.keyCode === 80 && keyDown.ctrlKey) { + if (keyDown.shiftKey) { + EventBridge.emitWebEvent(JSON.stringify({ type: 'unparent' })); + } else { + EventBridge.emitWebEvent(JSON.stringify({ type: 'parent' })); + } + } + }); window.onblur = function() { // Fake a change event var ev = document.createEvent("HTMLEvents"); diff --git a/scripts/system/html/js/gridControls.js b/scripts/system/html/js/gridControls.js index a245ed4cda..75052414ee 100644 --- a/scripts/system/html/js/gridControls.js +++ b/scripts/system/html/js/gridControls.js @@ -131,10 +131,17 @@ function loaded() { EventBridge.emitWebEvent(JSON.stringify({ type: 'init' })); }); - + document.addEventListener("keydown", function (keyDown) { + if (keyDown.keyCode === 80 && keyDown.ctrlKey) { + if (keyDown.shiftKey) { + EventBridge.emitWebEvent(JSON.stringify({ type: 'unparent' })); + } else { + EventBridge.emitWebEvent(JSON.stringify({ type: 'parent' })); + } + } + }) // Disable right-click context menu which is not visible in the HMD and makes it seem like the app has locked document.addEventListener("contextmenu", function (event) { event.preventDefault(); }, false); } - diff --git a/scripts/system/html/js/parentingHotkey.js b/scripts/system/html/js/parentingHotkey.js deleted file mode 100644 index c17dae01fe..0000000000 --- a/scripts/system/html/js/parentingHotkey.js +++ /dev/null @@ -1,12 +0,0 @@ -var keyReleaseEvent = function (event) { - if (event.text === 'p' && event.isControl && !event.isAutoRepeat ) { - if (event.isShifted) { - EventBridge.emitWebEvent(JSON.stringify({ type: 'unparent' })); - } else { - EventBridge.emitWebEvent(JSON.stringify({ type: 'parent' })); - } - } -}; - -window.onkeypress = keyReleaseEvent; -Controller.keyReleaseEvent.connect(keyReleaseEvent); From 0df6305f901e24ab1b3f4d3028f4c169059cb8e9 Mon Sep 17 00:00:00 2001 From: Menithal Date: Sat, 18 Feb 2017 18:22:01 +0200 Subject: [PATCH 11/33] Revert removal of hotkey from js event --- scripts/system/edit.js | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/scripts/system/edit.js b/scripts/system/edit.js index d0236ce993..688fabab8b 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -849,7 +849,6 @@ function setupModelMenus() { Menu.addMenuItem({ menuName: "Edit", menuItemName: "Parent Entity to Last", - shortcutKey: "CTRL+P", afterItem: "Entity List...", grouping: "Advanced" }); @@ -858,7 +857,6 @@ function setupModelMenus() { menuName: "Edit", menuItemName: "Unparent Entity", afterItem: "Entity List...", - shortcutKey: "CTRL+SHIFT+P", grouping: "Advanced" }); Menu.addMenuItem({ @@ -1374,6 +1372,12 @@ var keyReleaseEvent = function (event) { }); grid.setPosition(newPosition); } + } else if (event.text === 'p' && event.isControl && !event.isAutoRepeat ) { + if (event.isShifted) { + unparentSelectedEntities(); + } else { + parentSelectedEntities(); + } } }; Controller.keyReleaseEvent.connect(keyReleaseEvent); From f3c806e91090c720e4f3841600f7933d44258a7e Mon Sep 17 00:00:00 2001 From: Menithal Date: Sat, 18 Feb 2017 18:33:00 +0200 Subject: [PATCH 12/33] Revert of hotkey detection, removed menu hotkeys - Holding hotkeys will no longer spam parent events rapidly, detects only the release --- scripts/system/edit.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/edit.js b/scripts/system/edit.js index 688fabab8b..bc76489c41 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -1372,7 +1372,7 @@ var keyReleaseEvent = function (event) { }); grid.setPosition(newPosition); } - } else if (event.text === 'p' && event.isControl && !event.isAutoRepeat ) { + } else if (event.key === 80 && event.isControl && !event.isAutoRepeat ) { if (event.isShifted) { unparentSelectedEntities(); } else { From 9b8503eba5ce4d359c30c681e4765e8dfa242227 Mon Sep 17 00:00:00 2001 From: Menithal Date: Sun, 19 Feb 2017 18:18:38 +0200 Subject: [PATCH 13/33] Initial Grab Clone --- scripts/system/html/entityProperties.html | 15 ++++++++++++++- scripts/system/html/js/entityProperties.js | 13 ++++++++++--- 2 files changed, 24 insertions(+), 4 deletions(-) diff --git a/scripts/system/html/entityProperties.html b/scripts/system/html/entityProperties.html index b11127b26c..4c3723a2ef 100644 --- a/scripts/system/html/entityProperties.html +++ b/scripts/system/html/entityProperties.html @@ -61,7 +61,7 @@
- +

@@ -295,12 +295,25 @@
+
+ + +
+
+
+ Cloneable Settings +
+
+
+
+
+

diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index 8879c0f34e..63cb037ada 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -273,7 +273,7 @@ function updateCheckedSubProperty(propertyName, propertyValue, subPropertyElemen propertyValue += subPropertyString + ','; } } else { - // We've unchecked, so remove + // We've unchecked, so remove propertyValue = propertyValue.replace(subPropertyString + ",", ""); } @@ -584,6 +584,7 @@ function loaded() { var elCollisionSoundURL = document.getElementById("property-collision-sound-url"); var elGrabbable = document.getElementById("property-grabbable"); + var elCloneable = document.getElementById("property-cloneable"); var elWantsTrigger = document.getElementById("property-wants-trigger"); var elIgnoreIK = document.getElementById("property-ignore-ik"); @@ -780,7 +781,7 @@ function loaded() { if (lastEntityID !== '"' + properties.id + '"' && lastEntityID !== null && editor !== null) { saveJSONUserData(true); } - //the event bridge and json parsing handle our avatar id string differently. + //the event bridge and json parsing handle our avatar id string differently. lastEntityID = '"' + properties.id + '"'; elID.innerHTML = properties.id; @@ -1156,6 +1157,12 @@ function loaded() { elGrabbable.addEventListener('change', function() { userDataChanger("grabbableKey", "grabbable", elGrabbable, elUserData, properties.dynamic); }); + elCloneable.addEventListener('change', function () { + userDataChanger("grabbableKey", "cloneable", elCloneable, elUserData, false); + if (elCloneable.checked) { + + } + }); elWantsTrigger.addEventListener('change', function() { userDataChanger("grabbableKey", "wantsTrigger", elWantsTrigger, elUserData, false); }); @@ -1390,7 +1397,7 @@ function loaded() { elZoneFlyingAllowed.addEventListener('change', createEmitCheckedPropertyUpdateFunction('flyingAllowed')); elZoneGhostingAllowed.addEventListener('change', createEmitCheckedPropertyUpdateFunction('ghostingAllowed')); elZoneFilterURL.addEventListener('change', createEmitTextPropertyUpdateFunction('filterURL')); - + var voxelVolumeSizeChangeFunction = createEmitVec3PropertyUpdateFunction( 'voxelVolumeSize', elVoxelVolumeSizeX, elVoxelVolumeSizeY, elVoxelVolumeSizeZ); elVoxelVolumeSizeX.addEventListener('change', voxelVolumeSizeChangeFunction); From 2a4b493de560049bf34f2e179cca4970a830a7c7 Mon Sep 17 00:00:00 2001 From: Menithal Date: Sun, 19 Feb 2017 18:24:56 +0200 Subject: [PATCH 14/33] Changed order on Menu --- scripts/system/edit.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/system/edit.js b/scripts/system/edit.js index bc76489c41..61bbd23180 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -856,14 +856,14 @@ function setupModelMenus() { Menu.addMenuItem({ menuName: "Edit", menuItemName: "Unparent Entity", - afterItem: "Entity List...", + afterItem: "Parent Entity to Last", grouping: "Advanced" }); Menu.addMenuItem({ menuName: "Edit", menuItemName: "Allow Selecting of Large Models", shortcutKey: "CTRL+META+L", - afterItem: "Entity List...", + afterItem: "Unparent Entity", isCheckable: true, isChecked: true, grouping: "Advanced" From d9f86612de72cb10004d70ae68db4e06669650fb Mon Sep 17 00:00:00 2001 From: Menithal Date: Sun, 19 Feb 2017 20:18:11 +0200 Subject: [PATCH 15/33] Fixed view toggle, Added new Notifications - View Toggle now only toggles if no other modifiers are pressed - More notification, and cases for notification - Parenting to existing parent - Unparenting when there is no parent - Unparenting single entities --- interface/src/Application.cpp | 10 ++++--- scripts/system/edit.js | 54 ++++++++++++++++++++++++++++------- 2 files changed, 50 insertions(+), 14 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 488e97b5e6..bfc5be29e7 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2886,10 +2886,12 @@ void Application::keyPressEvent(QKeyEvent* event) { } break; case Qt::Key_P: { - bool isFirstPersonChecked = Menu::getInstance()->isOptionChecked(MenuOption::FirstPerson); - Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, !isFirstPersonChecked); - Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, isFirstPersonChecked); - cameraMenuChanged(); + if (!(isShifted || isMeta || isOption)) { + bool isFirstPersonChecked = Menu::getInstance()->isOptionChecked(MenuOption::FirstPerson); + Menu::getInstance()->setIsOptionChecked(MenuOption::FirstPerson, !isFirstPersonChecked); + Menu::getInstance()->setIsOptionChecked(MenuOption::ThirdPerson, isFirstPersonChecked); + cameraMenuChanged(); + } break; } diff --git a/scripts/system/edit.js b/scripts/system/edit.js index 61bbd23180..7731edd622 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -1116,30 +1116,64 @@ function recursiveDelete(entities, childrenList) { } function unparentSelectedEntities() { if (SelectionManager.hasSelection()) { - var selectedEntities = selectionManager.selections; - selectedEntities.forEach(function (id, index) { - Entities.editEntity(id, {parentID: null}) - return true; - }); - Window.notify("Entities Unparented"); + var selectedEntities = selectionManager.selections; + var parentCheck = false; + + if (selectedEntities.length < 1) { + Window.notifyEditError("You must have an entity selected inorder to unparent it."); + return; + } + selectedEntities.forEach(function (id, index) { + var parentId = Entities.getEntityProperties(id, ["parentID"]).parentID; + if (parentId !== null && parentId.length > 0 && parentId !== "{00000000-0000-0000-0000-000000000000}") { + 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 objects selected in order to parent them"); - return; + 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}) } }); - Window.notify("Entities Parented"); + + if(parentCheck) { + Window.notify("Entities parented"); + }else { + Window.notify("Entities are already parented to last"); + } } else { - Window.notifyEditError("You have nothing selected") + Window.notifyEditError("You have nothing selected to parent"); } } function deleteSelectedEntities() { From e95e50ad6ebade12a4c07e0bfcd524803fbc9d73 Mon Sep 17 00:00:00 2001 From: Menithal Date: Thu, 23 Feb 2017 10:34:04 +0200 Subject: [PATCH 16/33] Preliminary work on edit.js to allow for new param --- scripts/system/html/entityProperties.html | 6 ++-- scripts/system/html/js/entityProperties.js | 38 +++++++++++++++++----- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/scripts/system/html/entityProperties.html b/scripts/system/html/entityProperties.html index 4c3723a2ef..25cd4417d5 100644 --- a/scripts/system/html/entityProperties.html +++ b/scripts/system/html/entityProperties.html @@ -305,13 +305,13 @@
-
+
Cloneable Settings
-
-
+
+
diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index 63cb037ada..7212fd9b9e 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -323,13 +323,9 @@ function setUserDataFromEditor(noUpdate) { }) ); } - } - - } - -function userDataChanger(groupName, keyName, checkBoxElement, userDataElement, defaultValue) { +function userDataChanger(groupName, keyName, values, userDataElement, defaultValue) { var properties = {}; var parsedData = {}; try { @@ -339,15 +335,19 @@ function userDataChanger(groupName, keyName, checkBoxElement, userDataElement, d } else { parsedData = JSON.parse(userDataElement.value); } - } catch (e) {} if (!(groupName in parsedData)) { parsedData[groupName] = {} } + delete parsedData[groupName][keyName]; - if (checkBoxElement.checked !== defaultValue) { - parsedData[groupName][keyName] = checkBoxElement.checked; + if (values instanceof Element) { + if (values.checked !== defaultValue) { + parsedData[groupName][keyName] = values.checked; + } + } else { + parsedData[groupName][keyName] = values; } if (Object.keys(parsedData[groupName]).length == 0) { @@ -584,7 +584,12 @@ function loaded() { var elCollisionSoundURL = document.getElementById("property-collision-sound-url"); var elGrabbable = document.getElementById("property-grabbable"); + var elCloneable = document.getElementById("property-cloneable"); + var elCloneableGroup = document.getElementById("group-cloneable-group"); + var elCloneableLifetime = document.getElementById("property-cloneable-lifetime"); + var elCloneableLimit = document.getElementById("property-cloneable-limit") + var elWantsTrigger = document.getElementById("property-wants-trigger"); var elIgnoreIK = document.getElementById("property-ignore-ik"); @@ -1160,9 +1165,24 @@ function loaded() { elCloneable.addEventListener('change', function () { userDataChanger("grabbableKey", "cloneable", elCloneable, elUserData, false); if (elCloneable.checked) { - + var cloneProperties = { + lifetime: 300, + limit: 10 + }; + userDataChanger("grabbableKey", "cloneable-properties", cloneProperties, elUserData, false); + elCloneableGroup.style.display = "block"; + } else { + userDataChanger("grabbableKey", "cloneable-properties", {}, elUserData, false); + elCloneableGroup.style.display = "none"; } }); + + var numberListener = function (event) { + userDataChanger("grabbableKey", event.target.getAttribute("data-user-data-type"), event.target.value, elUserData, false}); + }; + elCloneableLifetime.addEventListener('change', numberListener); + elCloneableLimit.addEventListener('change', numberListener); + elWantsTrigger.addEventListener('change', function() { userDataChanger("grabbableKey", "wantsTrigger", elWantsTrigger, elUserData, false); }); From 4d98cc436b63af354f05c0a84afa481ba4769e88 Mon Sep 17 00:00:00 2001 From: Menithal Date: Thu, 23 Feb 2017 23:20:21 +0200 Subject: [PATCH 17/33] Finished up Edit.js --- scripts/system/html/entityProperties.html | 6 +-- scripts/system/html/js/entityProperties.js | 43 +++++++++++++++------- 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/scripts/system/html/entityProperties.html b/scripts/system/html/entityProperties.html index 25cd4417d5..e775be9e3a 100644 --- a/scripts/system/html/entityProperties.html +++ b/scripts/system/html/entityProperties.html @@ -297,7 +297,7 @@
- +
@@ -310,8 +310,8 @@ Cloneable Settings
-
-
+
+
diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index 7212fd9b9e..629b9dc4e9 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -586,9 +586,10 @@ function loaded() { var elGrabbable = document.getElementById("property-grabbable"); var elCloneable = document.getElementById("property-cloneable"); + var elCloneableGroup = document.getElementById("group-cloneable-group"); var elCloneableLifetime = document.getElementById("property-cloneable-lifetime"); - var elCloneableLimit = document.getElementById("property-cloneable-limit") + var elCloneableLimit = document.getElementById("property-cloneable-limit"); var elWantsTrigger = document.getElementById("property-wants-trigger"); var elIgnoreIK = document.getElementById("property-ignore-ik"); @@ -853,6 +854,7 @@ function loaded() { elCollideOtherAvatar.checked = properties.collidesWith.indexOf("otherAvatar") > -1; elGrabbable.checked = properties.dynamic; + elWantsTrigger.checked = false; elIgnoreIK.checked = true; var parsedUserData = {} @@ -869,8 +871,27 @@ function loaded() { if ("ignoreIK" in parsedUserData["grabbableKey"]) { elIgnoreIK.checked = parsedUserData["grabbableKey"].ignoreIK; } + if ("cloneable" in parsedUserData["grabbableKey"]) { + elCloneable.checked = parsedUserData["grabbableKey"].cloneable; + + elCloneableGroup.style.display = elCloneable.checked ? "block": "none"; + elCloneableLimit.value = elCloneable.checked ? 10: 0; + elCloneableLifetime.value = elCloneable.checked ? 300: 0; + } else { + elCloneable.checked = false; + elCloneableGroup.style.display = elCloneable.checked ? "block": "none"; + elCloneableLimit.value = 0; + elCloneableLifetime.value = 0; + } + if ("cloneLifetime" in parsedUserData["grabbableKey"]) { + elCloneableLifetime.value = parsedUserData["grabbableKey"].cloneLifetime; + } + if ("cloneLimit" in parsedUserData["grabbableKey"]) { + elCloneableLimit.value = parsedUserData["grabbableKey"].cloneLimit; + } } - } catch (e) {} + } catch (e) { + } elCollisionSoundURL.value = properties.collisionSoundURL; elLifetime.value = properties.lifetime; @@ -1162,23 +1183,19 @@ function loaded() { elGrabbable.addEventListener('change', function() { userDataChanger("grabbableKey", "grabbable", elGrabbable, elUserData, properties.dynamic); }); - elCloneable.addEventListener('change', function () { - userDataChanger("grabbableKey", "cloneable", elCloneable, elUserData, false); - if (elCloneable.checked) { - var cloneProperties = { - lifetime: 300, - limit: 10 - }; - userDataChanger("grabbableKey", "cloneable-properties", cloneProperties, elUserData, false); + elCloneable.addEventListener('change', function (event) { + if (event.target.checked) { + userDataChanger("grabbableKey", "cloneLifetime", 300, elUserData, -1); + userDataChanger("grabbableKey", "cloneLimit", 10, elUserData, -1); elCloneableGroup.style.display = "block"; } else { - userDataChanger("grabbableKey", "cloneable-properties", {}, elUserData, false); elCloneableGroup.style.display = "none"; } + userDataChanger("grabbableKey", "cloneable", event.target, elUserData, null); }); - + var numberListener = function (event) { - userDataChanger("grabbableKey", event.target.getAttribute("data-user-data-type"), event.target.value, elUserData, false}); + userDataChanger("grabbableKey", event.target.getAttribute("data-user-data-type"), parseInt(event.target.value), elUserData, false); }; elCloneableLifetime.addEventListener('change', numberListener); elCloneableLimit.addEventListener('change', numberListener); From 10151c3f5b23f5a9302f9aadd2db13cfdc23f1a7 Mon Sep 17 00:00:00 2001 From: Menithal Date: Fri, 24 Feb 2017 08:04:03 +0200 Subject: [PATCH 18/33] Added Multi-userdata field updater --- scripts/system/html/js/entityProperties.js | 112 +++++++++++++-------- 1 file changed, 71 insertions(+), 41 deletions(-) diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index 629b9dc4e9..abffdaee96 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -27,6 +27,7 @@ var EDITOR_TIMEOUT_DURATION = 1500; var colorPickers = []; var lastEntityID = null; + debugPrint = function(message) { EventBridge.emitWebEvent( JSON.stringify({ @@ -325,49 +326,65 @@ function setUserDataFromEditor(noUpdate) { } } } -function userDataChanger(groupName, keyName, values, userDataElement, defaultValue) { - var properties = {}; - var parsedData = {}; - try { - if ($('#userdata-editor').css('height') !== "0px") { - //if there is an expanded, we want to use its json. - parsedData = getEditorJSON(); - } else { - parsedData = JSON.parse(userDataElement.value); +function multiUserDataChanger(groupName, keyPair, userDataElement, defaults) { + var properties = {}; + var parsedData = {}; + try { + if ($('#userdata-editor').css('height') !== "0px") { + //if there is an expanded, we want to use its json. + parsedData = getEditorJSON(); + } else { + parsedData = JSON.parse(userDataElement.value); + } + } catch (e) {} + + if (!(groupName in parsedData)) { + parsedData[groupName] = {} + } + var keys = Object.keys(keyPair); + keys.forEach(function (key) { + delete parsedData[groupName][key]; + if (keyPair[key] instanceof Element) { + if(keyPair[key].type === "checkbox") { + if (keyPair[key].checked !== defaults[key]) { + parsedData[groupName][key] = keyPair[key].checked; + } + } else { + var val = isNaN(keyPair[key].value) ? keyPair[key].value : parseInt(keyPair[key].value); + if (val !== defaults[key]) { + parsedData[groupName][key] = val; } - } catch (e) {} - - if (!(groupName in parsedData)) { - parsedData[groupName] = {} - } - - delete parsedData[groupName][keyName]; - if (values instanceof Element) { - if (values.checked !== defaultValue) { - parsedData[groupName][keyName] = values.checked; } } else { - parsedData[groupName][keyName] = values; + parsedData[groupName][key] = keyPair[key]; } + }); - if (Object.keys(parsedData[groupName]).length == 0) { - delete parsedData[groupName]; - } - if (Object.keys(parsedData).length > 0) { - properties['userData'] = JSON.stringify(parsedData); - } else { - properties['userData'] = ''; - } + if (Object.keys(parsedData[groupName]).length == 0) { + delete parsedData[groupName]; + } + if (Object.keys(parsedData).length > 0) { + properties['userData'] = JSON.stringify(parsedData); + } else { + properties['userData'] = ''; + } - userDataElement.value = properties['userData']; + userDataElement.value = properties['userData']; - EventBridge.emitWebEvent( - JSON.stringify({ - id: lastEntityID, - type: "update", - properties: properties, - }) - ); + EventBridge.emitWebEvent( + JSON.stringify({ + id: lastEntityID, + type: "update", + properties: properties, + }) + ); + +} +function userDataChanger(groupName, keyName, values, userDataElement, defaultValue) { + var val = {}, def = {}; + val[keyName] = values; + def[keyName] = defaultValue; + multiUserDataChanger(groupName, val, userDataElement, def); }; function setTextareaScrolling(element) { @@ -873,15 +890,18 @@ function loaded() { } if ("cloneable" in parsedUserData["grabbableKey"]) { elCloneable.checked = parsedUserData["grabbableKey"].cloneable; - elCloneableGroup.style.display = elCloneable.checked ? "block": "none"; elCloneableLimit.value = elCloneable.checked ? 10: 0; elCloneableLifetime.value = elCloneable.checked ? 300: 0; + elDynamic.checked = elCloneable.checked ? false: properties.dynamic; + } else { elCloneable.checked = false; + elCloneableGroup.style.display = elCloneable.checked ? "block": "none"; elCloneableLimit.value = 0; elCloneableLifetime.value = 0; + } if ("cloneLifetime" in parsedUserData["grabbableKey"]) { elCloneableLifetime.value = parsedUserData["grabbableKey"].cloneLifetime; @@ -1184,14 +1204,24 @@ function loaded() { userDataChanger("grabbableKey", "grabbable", elGrabbable, elUserData, properties.dynamic); }); elCloneable.addEventListener('change', function (event) { - if (event.target.checked) { - userDataChanger("grabbableKey", "cloneLifetime", 300, elUserData, -1); - userDataChanger("grabbableKey", "cloneLimit", 10, elUserData, -1); + var checked = event.target.checked; + if (checked) { + multiUserDataChanger("grabbableKey", + {cloneLifetime: elCloneableLifetime, cloneLimit: elCloneableLimit, cloneable: event.target}, + elUserData, + {cloneLifetime: 300, cloneLimit: 10, cloneable: false}); elCloneableGroup.style.display = "block"; + EventBridge.emitWebEvent( + '{"id":' + lastEntityID + ', "type":"update", "properties":{"dynamic":false}}' + ); + EventBridge.emitWebEvent( + '{"id":' + lastEntityID + ', "type":"update", "properties":{"grabbable":true}}' + ); } else { elCloneableGroup.style.display = "none"; } - userDataChanger("grabbableKey", "cloneable", event.target, elUserData, null); + + userDataChanger("grabbableKey", "cloneable", checked, elUserData, null); }); var numberListener = function (event) { From 69949cd6b56c18bd173b9a59a209038c8e41d24f Mon Sep 17 00:00:00 2001 From: Menithal Date: Sun, 26 Feb 2017 18:49:13 +0200 Subject: [PATCH 19/33] Finalized Grab-Clone action --- .../system/controllers/handControllerGrab.js | 83 ++++++++++++++++++- 1 file changed, 82 insertions(+), 1 deletion(-) diff --git a/scripts/system/controllers/handControllerGrab.js b/scripts/system/controllers/handControllerGrab.js index ea76490b7b..7f67c11a7c 100644 --- a/scripts/system/controllers/handControllerGrab.js +++ b/scripts/system/controllers/handControllerGrab.js @@ -266,6 +266,27 @@ CONTROLLER_STATE_MACHINE[STATE_OVERLAY_STYLUS_TOUCHING] = { }; CONTROLLER_STATE_MACHINE[STATE_OVERLAY_LASER_TOUCHING] = CONTROLLER_STATE_MACHINE[STATE_OVERLAY_STYLUS_TOUCHING]; +// Object assign polyfill +if (typeof Object.assign != 'function') { + Object.assign = function(target, varArgs) { + 'use strict'; + if (target == null) { + throw new TypeError('Cannot convert undefined or null to object'); + } + var to = Object(target); + for (var index = 1; index < arguments.length; index++) { + var nextSource = arguments[index]; + if (nextSource != null) { + for (var nextKey in nextSource) { + if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) { + to[nextKey] = nextSource[nextKey]; + } + } + } + } + return to; + }; +} function distanceBetweenPointAndEntityBoundingBox(point, entityProps) { var entityXform = new Xform(entityProps.rotation, entityProps.position); @@ -1437,7 +1458,18 @@ function MyController(hand) { return true; }; + this.entityIsCloneable = function(entityID) { + var entityProps = entityPropertiesCache.getGrabbableProps(entityID); + var props = entityPropertiesCache.getProps(entityID); + if (!props) { + return false; + } + if (entityProps.hasOwnProperty("cloneable")/*&& props.locked*/) { + return entityProps.cloneable; + } + return false; + } this.entityIsGrabbable = function(entityID) { var grabbableProps = entityPropertiesCache.getGrabbableProps(entityID); var props = entityPropertiesCache.getProps(entityID); @@ -1517,7 +1549,7 @@ function MyController(hand) { this.entityIsNearGrabbable = function(entityID, handPosition, maxDistance) { - if (!this.entityIsGrabbable(entityID)) { + if (!this.entityIsCloneable(entityID) && !this.entityIsGrabbable(entityID)) { return false; } @@ -2359,6 +2391,55 @@ function MyController(hand) { reparentProps.localPosition = this.offsetPosition; reparentProps.localRotation = this.offsetRotation; } + + if (grabbedProperties.userData.length > 0) { + try{ + var userData = JSON.parse(grabbedProperties.userData); + var grabInfo = userData.grabbableKey; + if (grabInfo && grabInfo.cloneable) { + + var worldEntities = Entities.findEntitiesInBox(Vec3.subtract(MyAvatar.position, {x:25,y:25, z:25}), {x:50, y: 50, z: 50}) + var count = 0; + worldEntities.forEach(function(item) { + var item = Entities.getEntityProperties(item, ["name"]); + if (item.name === grabbedProperties.name) { + count++; + } + }) + var cloneableProps = Entities.getEntityProperties(grabbedProperties.id); + var lifetime = grabInfo.cloneLifetime ? grabInfo.cloneLifetime : 300; + var limit = grabInfo.cloneLimit ? grabInfo.cloneLimit : 10; + var cUserData = Object.assign({}, userData); + var cProperties = Object.assign({}, cloneableProps); + + if (count > limit) { + delete cloneableProps; + delete lifetime; + delete cUserData; + delete cProperties; + return; + } + + delete cUserData.grabbableKey.cloneLifetime; + delete cUserData.grabbableKey.cloneable; + delete cUserData.grabbableKey.cloneLimit; + delete cProperties.id + cUserData.grabbableKey.triggerable = true; + cUserData.grabbableKey.grabbable = true; + cProperties.lifetime = lifetime; + cProperties.userData = JSON.stringify(cUserData); + this.grabbedEntity = Entities.addEntity(cProperties); + grabbedProperties = Entities.getEntityProperties(this.grabbedEntity); + var _this = this; + Script.setTimeout(function () { + // This is needed to wait for the grabbed entity to have been instanciated. + _this.callEntityMethodOnGrabbed("startEquip"); + },400); + } + }catch(e) { + print("ERROR: " + e); + } + } Entities.editEntity(this.grabbedEntity, reparentProps); if (this.thisHandIsParent(grabbedProperties)) { From 1d8be2aeaa682c3fa33b65077f6eb3543c09a995 Mon Sep 17 00:00:00 2001 From: Menithal Date: Sun, 26 Feb 2017 19:17:46 +0200 Subject: [PATCH 20/33] Added missing dynamic --- scripts/system/controllers/handControllerGrab.js | 5 +++++ scripts/system/html/entityProperties.html | 4 ++++ scripts/system/html/js/entityProperties.js | 12 +++++++----- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/scripts/system/controllers/handControllerGrab.js b/scripts/system/controllers/handControllerGrab.js index 7f67c11a7c..4b469798ab 100644 --- a/scripts/system/controllers/handControllerGrab.js +++ b/scripts/system/controllers/handControllerGrab.js @@ -2409,6 +2409,7 @@ function MyController(hand) { var cloneableProps = Entities.getEntityProperties(grabbedProperties.id); var lifetime = grabInfo.cloneLifetime ? grabInfo.cloneLifetime : 300; var limit = grabInfo.cloneLimit ? grabInfo.cloneLimit : 10; + var dynamic = grabInfo.cloneDynamic ? grabInfo.cloneDynamic : false; var cUserData = Object.assign({}, userData); var cProperties = Object.assign({}, cloneableProps); @@ -2422,8 +2423,12 @@ function MyController(hand) { delete cUserData.grabbableKey.cloneLifetime; delete cUserData.grabbableKey.cloneable; + delete cUserData.grabbableKey.cloneDynamic; delete cUserData.grabbableKey.cloneLimit; delete cProperties.id + + cProperties.dynamic = dynamic; + cProperties.locked = false; cUserData.grabbableKey.triggerable = true; cUserData.grabbableKey.grabbable = true; cProperties.lifetime = lifetime; diff --git a/scripts/system/html/entityProperties.html b/scripts/system/html/entityProperties.html index e775be9e3a..a0497d6a92 100644 --- a/scripts/system/html/entityProperties.html +++ b/scripts/system/html/entityProperties.html @@ -312,6 +312,10 @@
+
+ + +
diff --git a/scripts/system/html/js/entityProperties.js b/scripts/system/html/js/entityProperties.js index abffdaee96..2c77d54e85 100644 --- a/scripts/system/html/js/entityProperties.js +++ b/scripts/system/html/js/entityProperties.js @@ -603,7 +603,7 @@ function loaded() { var elGrabbable = document.getElementById("property-grabbable"); var elCloneable = document.getElementById("property-cloneable"); - + var elCloneableDynamic = document.getElementById("property-cloneable-dynamic"); var elCloneableGroup = document.getElementById("group-cloneable-group"); var elCloneableLifetime = document.getElementById("property-cloneable-lifetime"); var elCloneableLimit = document.getElementById("property-cloneable-limit"); @@ -893,15 +893,14 @@ function loaded() { elCloneableGroup.style.display = elCloneable.checked ? "block": "none"; elCloneableLimit.value = elCloneable.checked ? 10: 0; elCloneableLifetime.value = elCloneable.checked ? 300: 0; + elCloneableDynamic.checked = parsedUserData["grabbableKey"].cloneDynamic ? parsedUserData["grabbableKey"].cloneDynamic : properties.dynamic; elDynamic.checked = elCloneable.checked ? false: properties.dynamic; - } else { elCloneable.checked = false; - + elCloneableDynamic.checked = false; elCloneableGroup.style.display = elCloneable.checked ? "block": "none"; elCloneableLimit.value = 0; elCloneableLifetime.value = 0; - } if ("cloneLifetime" in parsedUserData["grabbableKey"]) { elCloneableLifetime.value = parsedUserData["grabbableKey"].cloneLifetime; @@ -1203,11 +1202,14 @@ function loaded() { elGrabbable.addEventListener('change', function() { userDataChanger("grabbableKey", "grabbable", elGrabbable, elUserData, properties.dynamic); }); + elCloneableDynamic.addEventListener('change', function (event){ + userDataChanger("grabbableKey", "cloneDynamic", event.target, elUserData, -1); + }); elCloneable.addEventListener('change', function (event) { var checked = event.target.checked; if (checked) { multiUserDataChanger("grabbableKey", - {cloneLifetime: elCloneableLifetime, cloneLimit: elCloneableLimit, cloneable: event.target}, + {cloneLifetime: elCloneableLifetime, cloneLimit: elCloneableLimit, cloneDynamic: elCloneableDynamic, cloneable: event.target}, elUserData, {cloneLifetime: 300, cloneLimit: 10, cloneable: false}); elCloneableGroup.style.display = "block"; From 9fbde41dc45508324ac1feef09f647cc51b39c44 Mon Sep 17 00:00:00 2001 From: Menithal Date: Mon, 27 Feb 2017 23:27:48 +0200 Subject: [PATCH 21/33] Styling formating and Rebuild attempt --- .../system/controllers/handControllerGrab.js | 99 ++++++++++--------- 1 file changed, 50 insertions(+), 49 deletions(-) diff --git a/scripts/system/controllers/handControllerGrab.js b/scripts/system/controllers/handControllerGrab.js index 4b469798ab..ad6adf7722 100644 --- a/scripts/system/controllers/handControllerGrab.js +++ b/scripts/system/controllers/handControllerGrab.js @@ -1465,7 +1465,7 @@ function MyController(hand) { return false; } - if (entityProps.hasOwnProperty("cloneable")/*&& props.locked*/) { + if (entityProps.hasOwnProperty("cloneable")) { return entityProps.cloneable; } return false; @@ -2393,57 +2393,58 @@ function MyController(hand) { } if (grabbedProperties.userData.length > 0) { - try{ - var userData = JSON.parse(grabbedProperties.userData); - var grabInfo = userData.grabbableKey; - if (grabInfo && grabInfo.cloneable) { + try{ + var userData = JSON.parse(grabbedProperties.userData); + var grabInfo = userData.grabbableKey; + if (grabInfo && grabInfo.cloneable) { + // Check if + var worldEntities = Entities.findEntitiesInBox(Vec3.subtract(MyAvatar.position, {x:25,y:25, z:25}), {x:50, y: 50, z: 50}) + var count = 0; + worldEntities.forEach(function(item) { + var item = Entities.getEntityProperties(item, ["name"]); + if (item.name === grabbedProperties.name) { + count++; + } + }) + var cloneableProps = Entities.getEntityProperties(grabbedProperties.id); + var lifetime = grabInfo.cloneLifetime ? grabInfo.cloneLifetime : 300; + var limit = grabInfo.cloneLimit ? grabInfo.cloneLimit : 10; + var dynamic = grabInfo.cloneDynamic ? grabInfo.cloneDynamic : false; + var cUserData = Object.assign({}, userData); + var cProperties = Object.assign({}, cloneableProps); - var worldEntities = Entities.findEntitiesInBox(Vec3.subtract(MyAvatar.position, {x:25,y:25, z:25}), {x:50, y: 50, z: 50}) - var count = 0; - worldEntities.forEach(function(item) { - var item = Entities.getEntityProperties(item, ["name"]); - if (item.name === grabbedProperties.name) { - count++; + if (count > limit) { + delete cloneableProps; + delete lifetime; + delete cUserData; + delete cProperties; + return; + } + + delete cUserData.grabbableKey.cloneLifetime; + delete cUserData.grabbableKey.cloneable; + delete cUserData.grabbableKey.cloneDynamic; + delete cUserData.grabbableKey.cloneLimit; + delete cProperties.id + + cProperties.dynamic = dynamic; + cProperties.locked = false; + cUserData.grabbableKey.triggerable = true; + cUserData.grabbableKey.grabbable = true; + cProperties.lifetime = lifetime; + cProperties.userData = JSON.stringify(cUserData); + this.grabbedEntity = Entities.addEntity(cProperties); + grabbedProperties = Entities.getEntityProperties(this.grabbedEntity); + var _this = this; + + Script.setTimeout(function () { + // This is needed to wait for the grabbed entity to have been instanciated. + _this.callEntityMethodOnGrabbed("startEquip"); + },400); } - }) - var cloneableProps = Entities.getEntityProperties(grabbedProperties.id); - var lifetime = grabInfo.cloneLifetime ? grabInfo.cloneLifetime : 300; - var limit = grabInfo.cloneLimit ? grabInfo.cloneLimit : 10; - var dynamic = grabInfo.cloneDynamic ? grabInfo.cloneDynamic : false; - var cUserData = Object.assign({}, userData); - var cProperties = Object.assign({}, cloneableProps); - - if (count > limit) { - delete cloneableProps; - delete lifetime; - delete cUserData; - delete cProperties; - return; - } - - delete cUserData.grabbableKey.cloneLifetime; - delete cUserData.grabbableKey.cloneable; - delete cUserData.grabbableKey.cloneDynamic; - delete cUserData.grabbableKey.cloneLimit; - delete cProperties.id - - cProperties.dynamic = dynamic; - cProperties.locked = false; - cUserData.grabbableKey.triggerable = true; - cUserData.grabbableKey.grabbable = true; - cProperties.lifetime = lifetime; - cProperties.userData = JSON.stringify(cUserData); - this.grabbedEntity = Entities.addEntity(cProperties); - grabbedProperties = Entities.getEntityProperties(this.grabbedEntity); - var _this = this; - Script.setTimeout(function () { - // This is needed to wait for the grabbed entity to have been instanciated. - _this.callEntityMethodOnGrabbed("startEquip"); - },400); + }catch(e) { + print("ERROR: " + e); } - }catch(e) { - print("ERROR: " + e); - } } Entities.editEntity(this.grabbedEntity, reparentProps); From b1639ee3aafb07c96e1e516c74446bbe99737a9e Mon Sep 17 00:00:00 2001 From: Matti Lahtinen Date: Mon, 27 Feb 2017 23:40:06 +0200 Subject: [PATCH 22/33] Removed a Stray Print json that would spam logs. --- scripts/system/edit.js | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/system/edit.js b/scripts/system/edit.js index 7731edd622..bfa5ee478b 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -1618,7 +1618,6 @@ var PropertiesTool = function (opts) { print('Edit.js received web event that was not valid json.') return; } - print(JSON.stringify(data)) var i, properties, dY, diff, newPosition; if (data.type === "print") { if (data.message) { From d0c2c26a8e77209d6cba4c4a5c97538a4678d268 Mon Sep 17 00:00:00 2001 From: Matti Lahtinen Date: Tue, 28 Feb 2017 16:37:08 +0200 Subject: [PATCH 23/33] One last gotcha from the conflict resolution. --- scripts/system/controllers/handControllerGrab.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/system/controllers/handControllerGrab.js b/scripts/system/controllers/handControllerGrab.js index 14d737de55..fd13b74f7d 100644 --- a/scripts/system/controllers/handControllerGrab.js +++ b/scripts/system/controllers/handControllerGrab.js @@ -2497,7 +2497,7 @@ function MyController(hand) { cProperties.lifetime = lifetime; cProperties.userData = JSON.stringify(cUserData); this.grabbedThingID = Entities.addEntity(cProperties); - grabbedProperties = Entities.getEntityProperties(this.grabbedEntity); + grabbedProperties = Entities.getEntityProperties(this.grabbedThingID); var _this = this; Script.setTimeout(function () { From f538ac24f30515a2abd0f772a9a1822fe033b1d5 Mon Sep 17 00:00:00 2001 From: Menithal Date: Wed, 1 Mar 2017 22:07:02 +0200 Subject: [PATCH 24/33] Various Properties --- scripts/system/html/entityProperties.html | 2 +- scripts/system/html/js/entityProperties.js | 149 +++++++++++---------- 2 files changed, 78 insertions(+), 73 deletions(-) diff --git a/scripts/system/html/entityProperties.html b/scripts/system/html/entityProperties.html index a0497d6a92..5022dbd6a6 100644 --- a/scripts/system/html/entityProperties.html +++ b/scripts/system/html/entityProperties.html @@ -305,7 +305,7 @@ -
+