From 93516423bb9aeb87c887252f82967b7bd09b48fa Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Fri, 11 Jan 2019 21:32:18 +0100 Subject: [PATCH 1/3] zone visualizer prototype --- scripts/system/edit.js | 14 +- .../system/modules/entityShapeVisualizer.js | 209 ++++++++++++++++++ 2 files changed, 221 insertions(+), 2 deletions(-) create mode 100644 scripts/system/modules/entityShapeVisualizer.js diff --git a/scripts/system/edit.js b/scripts/system/edit.js index 84143f4c25..c6a30fe209 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -82,13 +82,18 @@ 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.resourcesPath() + "icons/create-icons/23-zone-01.svg"; -var entityIconOverlayManager = new EntityIconOverlayManager(['Light', 'ParticleEffect'], function(entityID) { +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, @@ -106,11 +111,15 @@ var gridTool = new GridTool({ }); 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.updateSelection(selectionManager.selections); }); var DEGREES_TO_RADIANS = Math.PI / 180.0; @@ -836,7 +845,7 @@ var toolBar = (function () { dialogWindow.fromQml.connect(fromQml); } }; - }; + } addButton("newModelButton", createNewEntityDialogButtonCallback("Model")); @@ -1492,6 +1501,7 @@ Script.scriptEnding.connect(function () { cleanupModelMenus(); tooltip.cleanup(); selectionDisplay.cleanup(); + entityShapeVisualizer.cleanup(); Entities.setLightsArePickable(originalLightsArePickable); Overlays.deleteOverlay(importingSVOImageOverlay); diff --git a/scripts/system/modules/entityShapeVisualizer.js b/scripts/system/modules/entityShapeVisualizer.js new file mode 100644 index 0000000000..5c91b1311c --- /dev/null +++ b/scripts/system/modules/entityShapeVisualizer.js @@ -0,0 +1,209 @@ +"use strict"; + +// entityShapeVisualizer.js +// +// Created by Thijs Wenker on 1/11/19 +// +// Copyright 2019 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 +// + +var SHAPETYPE_TO_SHAPE = { + "sphere": "Sphere", + "box": "Cube", + "ellipsoid": "Sphere", + "cylinder-y": "Cylinder", +}; + +function getEntityShapePropertiesForType(properties) { + switch (properties.type) { + case "Zone": + if (SHAPETYPE_TO_SHAPE[properties.shapeType]) { + return { + type: "Shape", + shape: SHAPETYPE_TO_SHAPE[properties.shapeType] + } + } else if (properties.shapeType === "compound") { + return { + type: "Model", + modelURL: properties.compoundShapeURL + } + } + break; + } + + // Default properties + return { + type: "Shape", + shape: "Cube" + } +} + +function getStringifiedEntityShapePropertiesForType(properties) { + return JSON.stringify(getEntityShapePropertiesForType(properties)); +} + +var REQUESTED_ENTITY_SHAPE_PROPERTIES = [ + 'type', 'shapeType', 'compoundShapeURL', 'localDimensions' +]; + +function EntityShape(entityID) { + this.entityID = entityID; + var properties = Entities.getEntityProperties(entityID, REQUESTED_ENTITY_SHAPE_PROPERTIES); + + this.previousPropertiesForTypeStringified = getStringifiedEntityShapePropertiesForType(properties); + + this.initialize(properties, this.previousPropertiesForTypeStringified); +} + +EntityShape.prototype = { + initialize: function(properties, propertiesForTypeStringified) { + // Create new instance of JS object: + var overlayProperties = JSON.parse(propertiesForTypeStringified); + + overlayProperties.localPosition = Vec3.ZERO; + overlayProperties.localRotation = Quat.IDENTITY; + overlayProperties.localDimensions = properties.localDimensions; + overlayProperties.canCastShadows = false; + overlayProperties.parentID = this.entityID; + overlayProperties.collisionless = true; + this.entity = Entities.addEntity(overlayProperties, "local"); + + console.warn("created " + this.entity); + console.warn("SHAPETYPE = " + properties.shapeType); + console.warn("SHAPE = " + Entities.getEntityProperties(this.entity, "shape").shape); + + + this.materialEntity = Entities.addEntity({ + type: "Material", + localPosition: Vec3.ZERO, + localRotation: Quat.IDENTITY, + localDimensions: properties.localDimensions, + parentID: this.entity, + priority: 1, + materialURL: "materialData", + materialData: JSON.stringify({ + materialVersion: 1, + materials: { + albedo: [0.0, 0.0, 7.0], + unlit: true, + opacity: 0.4 + } + }), + }, "local"); + + }, + + update: function() { + var properties = Entities.getEntityProperties(this.entityID, REQUESTED_ENTITY_SHAPE_PROPERTIES); + var propertiesForTypeStringified = getStringifiedEntityShapePropertiesForType(properties); + if (propertiesForTypeStringified !== this.previousPropertiesForTypeStringified) { + this.previousPropertiesForTypeStringified = propertiesForTypeStringified; + console.warn("Clearing old properties"); + this.clear(); + this.initialize(properties, propertiesForTypeStringified); + } else { + Entities.editEntity(this.entity, { + localDimensions: properties.localDimensions, + }); + } + + + + //this.previousProperties = Entities.getEntityProperties(this.entityID, REQUESTED_ENTITY_SHAPE_PROPERTIES); + + + console.warn(JSON.stringify(this.previousProperties)); + }, + clear: function() { + Entities.deleteEntity(this.materialEntity); + Entities.deleteEntity(this.entity); + } +}; + +function EntityShapeVisualizer(visualizedTypes) { + this.acceptedEntities = []; + this.ignoredEntities = []; + this.entityShapes = {}; + + this.visualizedTypes = visualizedTypes; +} + +EntityShapeVisualizer.prototype = { + addEntity: function(entityID, properties) { + if (this.entityShapes[entityID]) { + return; + } + this.entityShapes[entityID] = new EntityShape(entityID); + + }, + updateEntity: function(entityID) { + if (!this.entityShapes[entityID]) { + return; + } + this.entityShapes[entityID].update(); + }, + removeEntity: function(entityID) { + if (!this.entityShapes[entityID]) { + return; + } + this.entityShapes[entityID].clear(); + delete this.entityShapes[entityID]; + }, + cleanup: function() { + Object.keys(this.entityShapes).forEach(function(entityID) { + this.entityShapes[entityID].clear(); + }, this); + this.entityShapes = {}; + }, + updateSelection: function(selection) { + var qualifiedSelection = selection.filter(function(entityID) { + if (this.acceptedEntities.indexOf(entityID) !== -1) { + return true; + } + if (this.ignoredEntities.indexOf(entityID) !== -1) { + return false; + } + if (this.visualizedTypes.indexOf(Entities.getEntityProperties(entityID, "type").type) !== -1) { + this.acceptedEntities.push(entityID); + return true; + } + this.ignoredEntities.push(entityID); + return false; + }, this); + + + var newEntries = []; + var updateEntries = []; + + var currentEntries = Object.keys(this.entityShapes); + qualifiedSelection.forEach(function(entityID) { + if (currentEntries.indexOf(entityID) !== -1) { + updateEntries.push(entityID); + } else { + newEntries.push(entityID); + } + }); + + var deleteEntries = currentEntries.filter(function(entityID) { + return updateEntries.indexOf(entityID) === -1; + }); + + deleteEntries.forEach(function(entityID) { + console.warn("removing " + entityID); + this.removeEntity(entityID); + }, this); + + updateEntries.forEach(function(entityID) { + this.updateEntity(entityID); + }, this); + + newEntries.forEach(function(entityID) { + this.addEntity(entityID); + }, this); + } +}; + +module.exports = EntityShapeVisualizer; From b2f16570967c72d243ebc8680eb5c220ba628f5a Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Wed, 23 Jan 2019 19:28:34 +0100 Subject: [PATCH 2/3] grid pattern --- .../materials/boxgridpatterncreatezonew.png | Bin 0 -> 8623 bytes .../system/modules/entityShapeVisualizer.js | 49 ++++++++---------- 2 files changed, 22 insertions(+), 27 deletions(-) create mode 100644 scripts/system/assets/images/materials/boxgridpatterncreatezonew.png diff --git a/scripts/system/assets/images/materials/boxgridpatterncreatezonew.png b/scripts/system/assets/images/materials/boxgridpatterncreatezonew.png new file mode 100644 index 0000000000000000000000000000000000000000..2ecc7f85704c735794e8881b8cd3116422096874 GIT binary patch literal 8623 zcmeHNc~nzZ8ow!$2oi!v*|)GyaZ)H^*#u-0!r}r1K?{RIP?m{E*b;%HB2Q{+~J7G7$P>F5=+Dq zlOrPlNbaA$7!)^WtCYbzsvLA|V!sX3h_Gx|(OQceH8(s?e^uA|Ksn|(@&4k=8^I&j zS9rBfy1Kf?CX-yj1!qO4*;Znn&q#WaVp)C2CUy<2X0V6)%Z?^91*@RpfqK=ey6-Au zs~i(fkfO`-rZ?u*e}f;$aBv^~;?N6jCgvXhNupk~;xu*9n=-j)FvxnK@XVx9mI-Zn zO5fx*O5o851kh9PfkO$z-PH(B%MpiZ(~0Z+x@PA}QL$z>T={C@9i|GxfdqNzv5 z^zk=F?)$3V^^(~UFPF0BBgYtK*Uki7uI-4k+U^xL?-Kt=w!{Al?ndXX9s`G;;!H7p zYpdN>_$gYwIR1I-hK$_d!1k5_XWQudKArwoEQU^H*`k|S3Zo-_1LbhrfvNuUF_wLQ zE&(JG^#XU!^3KWbz`!l7?GwpnRBfxWQJn28*N30Ko&U&k;UD*YDQ~nNm~{?oD=sPb zZ2EdOHQxpy_=*+BzubAiY5r;4-+PyCX{x$xS`cxUDC_^YXYvZc(m1M};$6CP#LlWGzeWDgjL)x@ftt}WjNCS@ z?-pG-1<}N=m;e`|M! z$@dJ0Otr96Hs`~0y&N(&`gz)%i@7sy)b=9VVEk|7FEUWLlvfWq>k4;!Zs`u#lZxKb z<4?w|+gbPsmnP@+^%G{^6YrnTO!J%>UB0b9#t%_U6M9oI_V2pLX6Y~bZ`Y$8AD%Ec zv$bV+xlgxO_q^&jsf1`gbz z?*weDlD7=DCf}TTmhso8J=T^yi!wdR=>!V8d#ojBHf<~v#a`HJM~h0WAnn7Q;&m4r z9O<-Qu0eZX=BsV6!SjAmN!jrqF0j*!g6+!`JRIkbT6^^8K81#6j!?b>gVjICOR_K`|&k&Hog!)CSPy4wqbLKgOpP0$U) zvK>5FnN#K5a|nDR_EJo~#$2^q){sXdmVeTxDD%W#*9NRht~Xj>z}Tv6*xZ%v$mV8Y z@vO}1$NEVqyah70(aaE0d+n~Pl0eFt+&WSFO&s7Co3bER$_l{u%Ks!j4W z^bh82w?NLG3XkFz297lo=;2XZ-F@MEvJL%QLLzcd#|-l|=8%jf4amYmJz^ABhp}Xi zZB{EvWESgn28~_QY*q^oXBO-Es*I2f!?JhbS(!`UxD})^p_V_W^r=JksRoT*71}qb zpR@*Vfh^7lkK&H12##!He#uSIh_rBgpY4s#Uvn%^aQ3U_E+utFDKuK+TyOMxHn)|g zOgMb|qim9JW4pfC7p@3s{3#02lm$@Gt|YDYfgwkbn=Utet=2GMjAc0RYGY zUhb|y_y}C8XaE4YSdSnw0P8kDF9KY=qy_*$#p8Y4P@@P{@EJzY;Jq9G8pC*3C;#OB zsezy5T)$M1eZYUqS6cwP9j(}2gVFC0F1a(3YGC^DvZT`ii1#cV0c#S$2C7kD+kuz=#ts@* zZSBHmkSdH2qffyl(eo+@H2r7_`GP(o>8cP&(=&w75z>7kq2yBtJgXp#L)e%Pz6MwR z8xmB`%F6IMNYz%6w?B6LDoQ?ufEN4aB`B0K2eiSwcvSFsN1<{$>Qf;l-GR~(ppOQe z+YCi#Y?TaMJksAU9yNmo^+sgA^pIM`fzlC(9lRL_)u@q@z~lcgipmM0(Pm^JRXQRU zOAjgO=8N%5yd6v`>2Qf-B#aW6R3T+BsUY%+F-c4m4;YwKFsUREfWK6$OrbET;N{Kmb0dSY-;8SkJ(uf=~Y> zwuB$=d_++KlL{u41Oor}N9uLGHQL_+P;ai(u!zB7)+_1VpX{zkfjA+&=fFZoYa(%% z75+K2RDDzND+oROKM(DL=mH^SoABqtOC+V=C5jqA|GE$tuaFSDoEAj+)u9Eb2Jg1R K^_Fw!v3~+z)}_J# literal 0 HcmV?d00001 diff --git a/scripts/system/modules/entityShapeVisualizer.js b/scripts/system/modules/entityShapeVisualizer.js index 5c91b1311c..d1136c513c 100644 --- a/scripts/system/modules/entityShapeVisualizer.js +++ b/scripts/system/modules/entityShapeVisualizer.js @@ -11,7 +11,6 @@ // var SHAPETYPE_TO_SHAPE = { - "sphere": "Sphere", "box": "Cube", "ellipsoid": "Sphere", "cylinder-y": "Cylinder", @@ -23,13 +22,23 @@ function getEntityShapePropertiesForType(properties) { if (SHAPETYPE_TO_SHAPE[properties.shapeType]) { return { type: "Shape", - shape: SHAPETYPE_TO_SHAPE[properties.shapeType] - } + shape: SHAPETYPE_TO_SHAPE[properties.shapeType], + localDimensions: properties.localDimensions + }; } else if (properties.shapeType === "compound") { return { type: "Model", - modelURL: properties.compoundShapeURL - } + modelURL: properties.compoundShapeURL, + localDimensions: properties.localDimensions + }; + } else if (properties.shapeType === "sphere") { + var sphereDiameter = Math.max(properties.localDimensions.x, properties.localDimensions.y, + properties.localDimensions.z); + return { + type: "Sphere", + modelURL: properties.compoundShapeURL, + localDimensions: {x: sphereDiameter, y: sphereDiameter, z: sphereDiameter} + }; } break; } @@ -37,8 +46,9 @@ function getEntityShapePropertiesForType(properties) { // Default properties return { type: "Shape", - shape: "Cube" - } + shape: "Cube", + localDimensions: properties.localDimensions + }; } function getStringifiedEntityShapePropertiesForType(properties) { @@ -65,17 +75,11 @@ EntityShape.prototype = { overlayProperties.localPosition = Vec3.ZERO; overlayProperties.localRotation = Quat.IDENTITY; - overlayProperties.localDimensions = properties.localDimensions; overlayProperties.canCastShadows = false; overlayProperties.parentID = this.entityID; overlayProperties.collisionless = true; this.entity = Entities.addEntity(overlayProperties, "local"); - - console.warn("created " + this.entity); - console.warn("SHAPETYPE = " + properties.shapeType); - console.warn("SHAPE = " + Entities.getEntityProperties(this.entity, "shape").shape); - - + var PROJECTED_MATERIALS = false; this.materialEntity = Entities.addEntity({ type: "Material", localPosition: Vec3.ZERO, @@ -83,39 +87,31 @@ EntityShape.prototype = { localDimensions: properties.localDimensions, parentID: this.entity, priority: 1, + materialMappingMode: PROJECTED_MATERIALS ? "projected" : "uv", materialURL: "materialData", materialData: JSON.stringify({ materialVersion: 1, materials: { albedo: [0.0, 0.0, 7.0], unlit: true, - opacity: 0.4 + opacity: 0.4, + albedoMap: Script.resolvePath("../assets/images/materials/boxgridpatterncreatezonew.png") } }), }, "local"); - }, - update: function() { var properties = Entities.getEntityProperties(this.entityID, REQUESTED_ENTITY_SHAPE_PROPERTIES); var propertiesForTypeStringified = getStringifiedEntityShapePropertiesForType(properties); if (propertiesForTypeStringified !== this.previousPropertiesForTypeStringified) { this.previousPropertiesForTypeStringified = propertiesForTypeStringified; - console.warn("Clearing old properties"); this.clear(); this.initialize(properties, propertiesForTypeStringified); } else { Entities.editEntity(this.entity, { - localDimensions: properties.localDimensions, + localDimensions: JSON.parse(propertiesForTypeStringified).localDimensions, }); } - - - - //this.previousProperties = Entities.getEntityProperties(this.entityID, REQUESTED_ENTITY_SHAPE_PROPERTIES); - - - console.warn(JSON.stringify(this.previousProperties)); }, clear: function() { Entities.deleteEntity(this.materialEntity); @@ -192,7 +188,6 @@ EntityShapeVisualizer.prototype = { }); deleteEntries.forEach(function(entityID) { - console.warn("removing " + entityID); this.removeEntity(entityID); }, this); From ef1018c49bebcd87d1a402cd3fd94486a3b628a7 Mon Sep 17 00:00:00 2001 From: Thijs Wenker Date: Mon, 28 Jan 2019 16:10:29 +0100 Subject: [PATCH 3/3] - EntityShapeVisualizer.updateSelection -> EntityShapeVisualizer.setEntities (for a more generic use) - GridPattern -> Material - Replaced stringified compare with deep compare - Copied+modified zone icon (consistent color, removed sharp edges) --- scripts/system/assets/images/icon-zone.svg | 73 +++++++++++ .../assets/images/materials/GridPattern.json | 13 ++ ...patterncreatezonew.png => GridPattern.png} | Bin scripts/system/edit.js | 4 +- .../system/modules/entityShapeVisualizer.js | 115 +++++++++++++----- 5 files changed, 171 insertions(+), 34 deletions(-) create mode 100644 scripts/system/assets/images/icon-zone.svg create mode 100644 scripts/system/assets/images/materials/GridPattern.json rename scripts/system/assets/images/materials/{boxgridpatterncreatezonew.png => GridPattern.png} (100%) diff --git a/scripts/system/assets/images/icon-zone.svg b/scripts/system/assets/images/icon-zone.svg new file mode 100644 index 0000000000..41aeac4951 --- /dev/null +++ b/scripts/system/assets/images/icon-zone.svg @@ -0,0 +1,73 @@ + + + +image/svg+xml \ No newline at end of file diff --git a/scripts/system/assets/images/materials/GridPattern.json b/scripts/system/assets/images/materials/GridPattern.json new file mode 100644 index 0000000000..468b709ea4 --- /dev/null +++ b/scripts/system/assets/images/materials/GridPattern.json @@ -0,0 +1,13 @@ +{ + "materialVersion": 1, + "materials": { + "albedo": [ + 0.0, + 0.0, + 7.0 + ], + "unlit": true, + "opacity": 0.4, + "albedoMap": "GridPattern.png" + } +} diff --git a/scripts/system/assets/images/materials/boxgridpatterncreatezonew.png b/scripts/system/assets/images/materials/GridPattern.png similarity index 100% rename from scripts/system/assets/images/materials/boxgridpatterncreatezonew.png rename to scripts/system/assets/images/materials/GridPattern.png diff --git a/scripts/system/edit.js b/scripts/system/edit.js index c6a30fe209..2e175d72a4 100644 --- a/scripts/system/edit.js +++ b/scripts/system/edit.js @@ -82,7 +82,7 @@ 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.resourcesPath() + "icons/create-icons/23-zone-01.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']); @@ -119,7 +119,7 @@ var entityListTool = new EntityListTool(shouldUseEditTabletApp); selectionManager.addEventListener(function () { selectionDisplay.updateHandles(); entityIconOverlayManager.updatePositions(); - entityShapeVisualizer.updateSelection(selectionManager.selections); + entityShapeVisualizer.setEntities(selectionManager.selections); }); var DEGREES_TO_RADIANS = Math.PI / 180.0; diff --git a/scripts/system/modules/entityShapeVisualizer.js b/scripts/system/modules/entityShapeVisualizer.js index d1136c513c..fe950c2e2b 100644 --- a/scripts/system/modules/entityShapeVisualizer.js +++ b/scripts/system/modules/entityShapeVisualizer.js @@ -16,6 +16,10 @@ var SHAPETYPE_TO_SHAPE = { "cylinder-y": "Cylinder", }; +var REQUESTED_ENTITY_SHAPE_PROPERTIES = [ + 'type', 'shapeType', 'compoundShapeURL', 'localDimensions' +]; + function getEntityShapePropertiesForType(properties) { switch (properties.type) { case "Zone": @@ -51,27 +55,80 @@ function getEntityShapePropertiesForType(properties) { }; } -function getStringifiedEntityShapePropertiesForType(properties) { - return JSON.stringify(getEntityShapePropertiesForType(properties)); +function deepEqual(a, b) { + if (a === b) { + return true; + } + + if (typeof(a) !== "object" || typeof(b) !== "object") { + return false; + } + + if (Object.keys(a).length !== Object.keys(b).length) { + return false; + } + + for (var property in a) { + if (!a.hasOwnProperty(property)) { + continue; + } + if (!b.hasOwnProperty(property)) { + return false; + } + if (!deepEqual(a[property], b[property])) { + return false; + } + } + return true; } -var REQUESTED_ENTITY_SHAPE_PROPERTIES = [ - 'type', 'shapeType', 'compoundShapeURL', 'localDimensions' -]; +/** + * Returns an array of property names which are different in comparison. + * @param propertiesA + * @param propertiesB + * @returns {Array} - array of different property names + */ +function compareEntityProperties(propertiesA, propertiesB) { + var differentProperties = [], + property; + + for (property in propertiesA) { + if (!propertiesA.hasOwnProperty(property)) { + continue; + } + if (!propertiesB.hasOwnProperty(property) || !deepEqual(propertiesA[property], propertiesB[property])) { + differentProperties.push(property); + } + } + for (property in propertiesB) { + if (!propertiesB.hasOwnProperty(property)) { + continue; + } + if (!propertiesA.hasOwnProperty(property)) { + differentProperties.push(property); + } + } + + return differentProperties; +} + +function deepCopy(v) { + return JSON.parse(JSON.stringify(v)); +} function EntityShape(entityID) { this.entityID = entityID; - var properties = Entities.getEntityProperties(entityID, REQUESTED_ENTITY_SHAPE_PROPERTIES); + var propertiesForType = getEntityShapePropertiesForType(Entities.getEntityProperties(entityID, REQUESTED_ENTITY_SHAPE_PROPERTIES)); - this.previousPropertiesForTypeStringified = getStringifiedEntityShapePropertiesForType(properties); + this.previousPropertiesForType = propertiesForType; - this.initialize(properties, this.previousPropertiesForTypeStringified); + this.initialize(propertiesForType); } EntityShape.prototype = { - initialize: function(properties, propertiesForTypeStringified) { + initialize: function(properties) { // Create new instance of JS object: - var overlayProperties = JSON.parse(propertiesForTypeStringified); + var overlayProperties = deepCopy(properties); overlayProperties.localPosition = Vec3.ZERO; overlayProperties.localRotation = Quat.IDENTITY; @@ -88,29 +145,23 @@ EntityShape.prototype = { parentID: this.entity, priority: 1, materialMappingMode: PROJECTED_MATERIALS ? "projected" : "uv", - materialURL: "materialData", - materialData: JSON.stringify({ - materialVersion: 1, - materials: { - albedo: [0.0, 0.0, 7.0], - unlit: true, - opacity: 0.4, - albedoMap: Script.resolvePath("../assets/images/materials/boxgridpatterncreatezonew.png") - } - }), + materialURL: Script.resolvePath("../assets/images/materials/GridPattern.json"), }, "local"); }, update: function() { - var properties = Entities.getEntityProperties(this.entityID, REQUESTED_ENTITY_SHAPE_PROPERTIES); - var propertiesForTypeStringified = getStringifiedEntityShapePropertiesForType(properties); - if (propertiesForTypeStringified !== this.previousPropertiesForTypeStringified) { - this.previousPropertiesForTypeStringified = propertiesForTypeStringified; - this.clear(); - this.initialize(properties, propertiesForTypeStringified); - } else { + var propertiesForType = getEntityShapePropertiesForType(Entities.getEntityProperties(this.entityID, REQUESTED_ENTITY_SHAPE_PROPERTIES)); + + var difference = compareEntityProperties(propertiesForType, this.previousPropertiesForType); + + if (deepEqual(difference, ['localDimensions'])) { + this.previousPropertiesForType = propertiesForType; Entities.editEntity(this.entity, { - localDimensions: JSON.parse(propertiesForTypeStringified).localDimensions, + localDimensions: propertiesForType.localDimensions, }); + } else if (difference.length > 0) { + this.previousPropertiesForType = propertiesForType; + this.clear(); + this.initialize(propertiesForType); } }, clear: function() { @@ -128,7 +179,7 @@ function EntityShapeVisualizer(visualizedTypes) { } EntityShapeVisualizer.prototype = { - addEntity: function(entityID, properties) { + addEntity: function(entityID) { if (this.entityShapes[entityID]) { return; } @@ -154,8 +205,8 @@ EntityShapeVisualizer.prototype = { }, this); this.entityShapes = {}; }, - updateSelection: function(selection) { - var qualifiedSelection = selection.filter(function(entityID) { + setEntities: function(entities) { + var qualifiedEntities = entities.filter(function(entityID) { if (this.acceptedEntities.indexOf(entityID) !== -1) { return true; } @@ -175,7 +226,7 @@ EntityShapeVisualizer.prototype = { var updateEntries = []; var currentEntries = Object.keys(this.entityShapes); - qualifiedSelection.forEach(function(entityID) { + qualifiedEntities.forEach(function(entityID) { if (currentEntries.indexOf(entityID) !== -1) { updateEntries.push(entityID); } else {