diff --git a/examples/html/entityList.html b/examples/html/entityList.html new file mode 100644 index 0000000000..7caa45f19d --- /dev/null +++ b/examples/html/entityList.html @@ -0,0 +1,125 @@ + + + + + + + +
+ +
+ + + + + + + + + + +
TypeURL
+ + + diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html index 695879b678..a79edfb181 100644 --- a/examples/html/entityProperties.html +++ b/examples/html/entityProperties.html @@ -214,7 +214,7 @@ elModelSection.style.display = 'block'; elModelURL.value = properties.modelURL; elModelAnimationURL.value = properties.animationURL; - elModelAnimationPlaying.checked = properties.animationPlaying; + elModelAnimationPlaying.checked = properties.animationIsPlaying; elModelAnimationFPS.value = properties.animationFPS; } diff --git a/examples/html/style.css b/examples/html/style.css index 1625fd094f..b721c31b88 100644 --- a/examples/html/style.css +++ b/examples/html/style.css @@ -93,3 +93,40 @@ input.coord { width: 6em; height: 2em; } + +table#entity-table { + border-collapse: collapse; + font-family: Sans-Serif; + font-size: 12px; + width: 100%; +} + +#entity-table tr { + cursor: pointer; +} + +tr.selected { + background-color: #AAA; +} + +#entity-table th { + background-color: #333; + color: #fff; + border: 0px black solid; + text-align: left; + word-wrap: nowrap; + white-space: nowrap; +} + +#entity-table td { + border: 0px black solid; + word-wrap: nowrap; + white-space: nowrap; +} + +th#entity-type { + width: 60px; +} + +th#entity-url { +} diff --git a/examples/libraries/entityList.js b/examples/libraries/entityList.js new file mode 100644 index 0000000000..65c06c8cea --- /dev/null +++ b/examples/libraries/entityList.js @@ -0,0 +1,70 @@ +EntityListTool = function(opts) { + var that = {}; + + var url = Script.resolvePath('html/entityList.html'); + var webView = new WebWindow('Entities', url, 200, 280); + + var visible = false; + + webView.setVisible(visible); + + that.setVisible = function(newVisible) { + visible = newVisible; + webView.setVisible(visible); + }; + + selectionManager.addEventListener(function() { + var selectedIDs = []; + + for (var i = 0; i < selectionManager.selections.length; i++) { + selectedIDs.push(selectionManager.selections[i].id); + } + + data = { + type: 'selectionUpdate', + selectedIDs: selectedIDs, + }; + webView.eventBridge.emitScriptEvent(JSON.stringify(data)); + }); + + webView.eventBridge.webEventReceived.connect(function(data) { + data = JSON.parse(data); + if (data.type == "selectionUpdate") { + var ids = data.entityIds; + var entityIDs = []; + for (var i = 0; i < ids.length; i++) { + var entityID = Entities.getEntityItemID(ids[i]); + if (entityID.isKnownID) { + entityIDs.push(entityID); + } else { + print("Tried to select invalid entity: " + ids[i]); + } + } + selectionManager.setSelections(entityIDs); + if (data.focus) { + cameraManager.focus(selectionManager.worldPosition, + selectionManager.worldDimensions, + Menu.isOptionChecked(MENU_EASE_ON_FOCUS)); + } + } else if (data.type == "refresh") { + var entities = []; + var ids = Entities.findEntities(MyAvatar.position, 100); + for (var i = 0; i < ids.length; i++) { + var id = ids[i]; + var properties = Entities.getEntityProperties(id); + entities.push({ + id: id.id, + type: properties.type, + url: properties.type == "Model" ? properties.modelURL : "", + }); + } + var data = { + type: "update", + entities: entities, + }; + webView.eventBridge.emitScriptEvent(JSON.stringify(data)); + } + }); + + return that; +}; diff --git a/examples/libraries/entitySelectionTool.js b/examples/libraries/entitySelectionTool.js index ada876e9b1..e760fb0463 100644 --- a/examples/libraries/entitySelectionTool.js +++ b/examples/libraries/entitySelectionTool.js @@ -1242,7 +1242,7 @@ SelectionDisplay = (function () { Quat.getFront(lastCameraOrientation)); var vector = Vec3.subtract(newIntersection, lastPlaneIntersection); - lastPlaneIntersection = newIntersection; + vector = grid.snapToGrid(vector); // we only care about the Y axis vector.x = 0; @@ -1258,10 +1258,15 @@ SelectionDisplay = (function () { Vec3.print(" newPosition:", newPosition); } for (var i = 0; i < SelectionManager.selections.length; i++) { - var properties = Entities.getEntityProperties(SelectionManager.selections[i]); + var id = SelectionManager.selections[i]; + var properties = selectionManager.savedProperties[id.id]; + var original = properties.position; - properties.position = Vec3.sum(properties.position, vector); - Entities.editEntity(SelectionManager.selections[i], properties); + var newPosition = Vec3.sum(properties.position, vector); + + Entities.editEntity(id, { + position: newPosition, + }); } SelectionManager._update(); diff --git a/examples/newEditEntities.js b/examples/newEditEntities.js index f866893411..27a3e8a9d2 100644 --- a/examples/newEditEntities.js +++ b/examples/newEditEntities.js @@ -39,6 +39,9 @@ Script.include("libraries/gridTool.js"); var grid = Grid(); gridTool = GridTool({ horizontalGrid: grid }); +Script.include("libraries/entityList.js"); +var entityListTool = EntityListTool(); + selectionManager.addEventListener(selectionDisplay.updateHandles); var windowDimensions = Controller.getViewportDimensions(); @@ -283,6 +286,7 @@ var toolBar = (function () { if (activeButton === toolBar.clicked(clickedOverlay)) { isActive = !isActive; if (!isActive) { + entityListTool.setVisible(false); gridTool.setVisible(false); grid.setEnabled(false); propertiesTool.setVisible(false); @@ -290,6 +294,7 @@ var toolBar = (function () { cameraManager.disable(); } else { cameraManager.enable(); + entityListTool.setVisible(true); gridTool.setVisible(true); grid.setEnabled(true); propertiesTool.setVisible(true); diff --git a/libraries/entities/src/EntityScriptingInterface.cpp b/libraries/entities/src/EntityScriptingInterface.cpp index 29c4a8b19a..e66da97390 100644 --- a/libraries/entities/src/EntityScriptingInterface.cpp +++ b/libraries/entities/src/EntityScriptingInterface.cpp @@ -44,6 +44,20 @@ EntityItemID EntityScriptingInterface::addEntity(const EntityItemProperties& pro return id; } +EntityItemID EntityScriptingInterface::getEntityItemID(const QString& uuid) { + EntityItemID entityID = EntityItemID(QUuid(uuid), UNKNOWN_ENTITY_TOKEN, false); + + _entityTree->lockForRead(); + EntityItem* entity = const_cast(_entityTree->findEntityByEntityItemID(entityID)); + _entityTree->unlock(); + + if (entity) { + return entity->getEntityItemID(); + } + + return entityID; +} + EntityItemID EntityScriptingInterface::identifyEntity(EntityItemID entityID) { EntityItemID actualID = entityID; diff --git a/libraries/entities/src/EntityScriptingInterface.h b/libraries/entities/src/EntityScriptingInterface.h index 2150fa51da..7269579ab0 100644 --- a/libraries/entities/src/EntityScriptingInterface.h +++ b/libraries/entities/src/EntityScriptingInterface.h @@ -64,6 +64,9 @@ public slots: /// adds a model with the specific properties Q_INVOKABLE EntityItemID addEntity(const EntityItemProperties& properties); + // Get EntityItemID from uuid string + Q_INVOKABLE EntityItemID getEntityItemID(const QString& entityID); + /// identify a recently created model to determine its true ID Q_INVOKABLE EntityItemID identifyEntity(EntityItemID entityID);