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 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Type |
+ URL |
+
+
+
+
+
+
+
+
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);