diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 4a0f3905f6..3051f3faaf 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -478,6 +478,25 @@ function MyController(hand) { } }; + this.searchIndicatorOn = function(handPosition, distantPickRay) { + var SEARCH_SPHERE_SIZE = 0.011; + var SEARCH_SPHERE_FOLLOW_RATE = 0.50; + + if (this.intersectionDistance > 0) { + // If we hit something with our pick ray, move the search sphere toward that distance + this.searchSphereDistance = this.searchSphereDistance * SEARCH_SPHERE_FOLLOW_RATE + + this.intersectionDistance * (1.0 - SEARCH_SPHERE_FOLLOW_RATE); + } + + var searchSphereLocation = Vec3.sum(distantPickRay.origin, + Vec3.multiply(distantPickRay.direction, this.searchSphereDistance)); + this.searchSphereOn(searchSphereLocation, SEARCH_SPHERE_SIZE * this.searchSphereDistance, + (this.triggerSmoothedGrab() || this.bumperSqueezed()) ? INTERSECT_COLOR : NO_INTERSECT_COLOR); + if ((USE_OVERLAY_LINES_FOR_SEARCHING === true) && PICK_WITH_HAND_RAY) { + this.overlayLineOn(handPosition, searchSphereLocation, + (this.triggerSmoothedGrab() || this.bumperSqueezed()) ? INTERSECT_COLOR : NO_INTERSECT_COLOR); + } + } this.handleDistantParticleBeam = function(handPosition, objectPosition, color) { @@ -921,7 +940,8 @@ function MyController(hand) { continue; } - if (this.state == STATE_SEARCHING && !isPhysical && distance > NEAR_PICK_MAX_DISTANCE && !near) { + if (this.state == STATE_SEARCHING && + !isPhysical && distance > NEAR_PICK_MAX_DISTANCE && !near && !grabbableDataForCandidate.wantsTrigger) { // we can't distance-grab non-physical if (WANT_DEBUG_SEARCH_NAME && propsForCandidate.name == WANT_DEBUG_SEARCH_NAME) { print("grab is skipping '" + WANT_DEBUG_SEARCH_NAME + "': not physical and too far for near-grab"); @@ -1005,24 +1025,7 @@ function MyController(hand) { this.lineOn(distantPickRay.origin, Vec3.multiply(distantPickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR); } - var SEARCH_SPHERE_SIZE = 0.011; - var SEARCH_SPHERE_FOLLOW_RATE = 0.50; - - if (this.intersectionDistance > 0) { - // If we hit something with our pick ray, move the search sphere toward that distance - this.searchSphereDistance = this.searchSphereDistance * SEARCH_SPHERE_FOLLOW_RATE + - this.intersectionDistance * (1.0 - SEARCH_SPHERE_FOLLOW_RATE); - } - - var searchSphereLocation = Vec3.sum(distantPickRay.origin, - Vec3.multiply(distantPickRay.direction, this.searchSphereDistance)); - this.searchSphereOn(searchSphereLocation, SEARCH_SPHERE_SIZE * this.searchSphereDistance, - (this.triggerSmoothedGrab() || this.bumperSqueezed()) ? INTERSECT_COLOR : NO_INTERSECT_COLOR); - if ((USE_OVERLAY_LINES_FOR_SEARCHING === true) && PICK_WITH_HAND_RAY) { - this.overlayLineOn(handPosition, searchSphereLocation, - (this.triggerSmoothedGrab() || this.bumperSqueezed()) ? INTERSECT_COLOR : NO_INTERSECT_COLOR); - } - + this.searchIndicatorOn(handPosition, distantPickRay); Reticle.setVisible(false); }; @@ -1543,17 +1546,20 @@ function MyController(hand) { var now = Date.now(); if (now - this.lastPickTime > MSECS_PER_SEC / PICKS_PER_SECOND_PER_HAND) { var intersection = Entities.findRayIntersection(pickRay, true); - this.lastPickTime = now; - if (intersection.entityID != this.grabbedEntity) { - this.setState(STATE_RELEASE); - this.callEntityMethodOnGrabbed("stopFarTrigger"); - return; + if (intersection.accurate) { + this.lastPickTime = now; + if (intersection.entityID != this.grabbedEntity) { + this.setState(STATE_RELEASE); + this.callEntityMethodOnGrabbed("stopFarTrigger"); + return; + } + if (intersection.intersects) { + this.intersectionDistance = Vec3.distance(pickRay.origin, intersection.intersection); + } + this.searchIndicatorOn(handPosition, pickRay); } } - if (USE_ENTITY_LINES_FOR_MOVING === true) { - this.lineOn(pickRay.origin, Vec3.multiply(pickRay.direction, LINE_LENGTH), NO_INTERSECT_COLOR); - } this.callEntityMethodOnGrabbed("continueFarTrigger"); }; diff --git a/examples/edit.js b/examples/edit.js index 3e46160522..b2e52eee20 100644 --- a/examples/edit.js +++ b/examples/edit.js @@ -26,6 +26,7 @@ Script.include([ "libraries/entityCameraTool.js", "libraries/gridTool.js", "libraries/entityList.js", + "particle_explorer/particleExplorerTool.js", "libraries/lightOverlayManager.js", ]); @@ -37,17 +38,13 @@ var lightOverlayManager = new LightOverlayManager(); var cameraManager = new CameraManager(); var grid = Grid(); -// gridTool = GridTool({ -// horizontalGrid: grid -// }); -// gridTool.setVisible(false); var entityListTool = EntityListTool(); selectionManager.addEventListener(function() { selectionDisplay.updateHandles(); lightOverlayManager.updatePositions(); -}); +}); var toolIconUrl = HIFI_PUBLIC_BUCKET + "images/tools/"; var toolHeight = 50; @@ -109,11 +106,6 @@ var importingSVOImageOverlay = Overlays.addOverlay("image", { width: 20, height: 20, alpha: 1.0, - color: { - red: 255, - green: 255, - blue: 255 - }, x: Window.innerWidth - IMPORTING_SVO_OVERLAY_WIDTH, y: Window.innerHeight - IMPORTING_SVO_OVERLAY_HEIGHT, visible: false, @@ -139,9 +131,9 @@ var importingSVOTextOverlay = Overlays.addOverlay("text", { var MARKETPLACE_URL = "https://metaverse.highfidelity.com/marketplace"; var marketplaceWindow = new OverlayWebWindow({ - title: 'Marketplace', - source: "about:blank", - width: 900, + title: 'Marketplace', + source: "about:blank", + width: 900, height: 700, visible: false }); @@ -181,7 +173,8 @@ var toolBar = (function() { newTextButton, newWebButton, newZoneButton, - newPolyVoxButton; + newPolyVoxButton, + newParticleButton function initialize() { toolBar = new ToolBar(0, 0, ToolBar.VERTICAL, "highfidelity.edit.toolbar", function(windowDimensions, toolbar) { @@ -191,7 +184,7 @@ var toolBar = (function() { }; }); - + activeButton = toolBar.addTool({ imageURL: toolIconUrl + "edit-status.svg", @@ -319,6 +312,20 @@ var toolBar = (function() { visible: false }); + newParticleButton = toolBar.addTool({ + imageURL: toolIconUrl + "particle.svg", + subImage: { + x: 0, + y: 0, + width: 256, + height: 256 + }, + width: toolWidth, + height: toolHeight, + alpha: 0.9, + visible: false + }); + that.setActive(false); } @@ -365,6 +372,7 @@ var toolBar = (function() { toolBar.showTool(newWebButton, doShow); toolBar.showTool(newZoneButton, doShow); toolBar.showTool(newPolyVoxButton, doShow); + toolBar.showTool(newParticleButton, doShow); }; var RESIZE_INTERVAL = 50; @@ -432,8 +440,8 @@ var toolBar = (function() { newModelButtonDown = true; return true; } - - + + if (newCubeButton === toolBar.clicked(clickedOverlay)) { createNewEntity({ type: "Box", @@ -621,6 +629,22 @@ var toolBar = (function() { return true; } + if (newParticleButton === toolBar.clicked(clickedOverlay)) { + createNewEntity({ + type: "ParticleEffect", + isEmitting: true, + particleRadius: 0.1, + emitAcceleration: {x: 0, y: -1, z: 0}, + accelerationSpread: {x: 5, y: 0, z: 5}, + emitSpeed: 1, + lifespan: 1, + particleRadius: 0.025, + alphaFinish: 0, + emitRate: 100, + textures: "https://hifi-public.s3.amazonaws.com/alan/Particles/Particle-Sprite-Smoke-1.png", + }); + } + return false; }; @@ -641,7 +665,7 @@ var toolBar = (function() { } newModelButtonDown = false; - + return handled; } @@ -1231,7 +1255,8 @@ function selectAllEtitiesInCurrentSelectionBox(keepIfTouching) { function deleteSelectedEntities() { if (SelectionManager.hasSelection()) { - print(" Delete Entities"); + selectedParticleEntity = 0; + particleExplorerTool.destroyWebView(); SelectionManager.saveProperties(); var savedProperties = []; for (var i = 0; i < selectionManager.selections.length; i++) { @@ -1504,8 +1529,8 @@ PropertiesTool = function(opts) { var url = Script.resolvePath('html/entityProperties.html'); var webView = new OverlayWebWindow({ - title: 'Entity Properties', - source: url, + title: 'Entity Properties', + source: url, toolWindow: true }); @@ -1559,8 +1584,16 @@ PropertiesTool = function(opts) { } else { if (data.properties.dynamic === false) { // this object is leaving dynamic, so we zero its velocities - data.properties["velocity"] = {x: 0, y: 0, z: 0}; - data.properties["angularVelocity"] = {x: 0, y: 0, z: 0}; + data.properties["velocity"] = { + x: 0, + y: 0, + z: 0 + }; + data.properties["angularVelocity"] = { + x: 0, + y: 0, + z: 0 + }; } if (data.properties.rotation !== undefined) { var rotation = data.properties.rotation; @@ -1843,3 +1876,39 @@ propertyMenu.onSelectMenuItem = function(name) { var showMenuItem = propertyMenu.addMenuItem("Show in Marketplace"); propertiesTool = PropertiesTool(); +var particleExplorerTool = ParticleExplorerTool(); +var selectedParticleEntity = 0; +entityListTool.webView.eventBridge.webEventReceived.connect(function(data) { + var data = JSON.parse(data); + if (data.type == "selectionUpdate") { + var ids = data.entityIds; + if(ids.length === 1) { + if (Entities.getEntityProperties(ids[0], "type").type === "ParticleEffect" ) { + if (JSON.stringify(selectedParticleEntity) === JSON.stringify(ids[0])) { + // This particle entity is already selected, so return + return; + } + // Destroy the old particles web view first + particleExplorerTool.destroyWebView(); + particleExplorerTool.createWebView(); + var properties = Entities.getEntityProperties(ids[0]); + var particleData = { + messageType: "particle_settings", + currentProperties: properties + }; + selectedParticleEntity = ids[0]; + particleExplorerTool.setActiveParticleEntity(ids[0]); + + particleExplorerTool.webView.eventBridge.webEventReceived.connect(function(data) { + var data = JSON.parse(data); + if (data.messageType === "page_loaded") { + particleExplorerTool.webView.eventBridge.emitScriptEvent(JSON.stringify(particleData)); + } + }); + } else { + selectedParticleEntity = 0; + particleExplorerTool.destroyWebView(); + } + } + } +}); \ No newline at end of file diff --git a/examples/html/entityProperties.html b/examples/html/entityProperties.html index d8e5451ff8..fd98dcea2f 100644 --- a/examples/html/entityProperties.html +++ b/examples/html/entityProperties.html @@ -47,6 +47,17 @@ ); }; } + + function createEmitCheckedToStringPropertyUpdateFunction(checkboxElement, name, propertyName) { + var newString = ""; + if (checkboxElement.checked) { + newString += name + ""; + } else { + + } + + } + function createEmitGroupCheckedPropertyUpdateFunction(group, propertyName) { return function () { var properties = {}; @@ -64,7 +75,7 @@ function createEmitNumberPropertyUpdateFunction(propertyName) { return function() { EventBridge.emitWebEvent( - '{ "type":"update", "properties":{"' + propertyName + '":' + parseFloat(this.value).toFixed(2) + '}}' + '{ "type":"update", "properties":{"' + propertyName + '":' + Number(this.value.toFixed(4)) + '}}' ); }; } @@ -207,6 +218,28 @@ } }; + function updateCheckedSubProperty(propertyName, propertyValue, subPropertyElement, subPropertyString) { + if (subPropertyElement.checked) { + if (propertyValue.indexOf(subPropertyString)) { + propertyValue += subPropertyString + ','; + } + } else { + // We've unchecked, so remove + propertyValue = propertyValue.replace(subPropertyString + ",", ""); + } + + var _properties ={} + _properties[propertyName] = propertyValue; + + EventBridge.emitWebEvent( + JSON.stringify({ + type: "update", + properties: _properties + }) + ); + + } + function loaded() { openEventBridge(function() { var allSections = []; @@ -263,6 +296,11 @@ var elDensity = document.getElementById("property-density"); var elCollisionless = document.getElementById("property-collisionless"); var elDynamic = document.getElementById("property-dynamic" ); + var elCollideStatic = document.getElementById("property-collide-static"); + var elCollideDynamic = document.getElementById("property-collide-dynamic"); + var elCollideKinematic = document.getElementById("property-collide-kinematic"); + var elCollideMyAvatar = document.getElementById("property-collide-myAvatar"); + var elCollideOtherAvatar = document.getElementById("property-collide-otherAvatar"); var elCollisionSoundURL = document.getElementById("property-collision-sound-url"); var elLifetime = document.getElementById("property-lifetime"); var elScriptURL = document.getElementById("property-script-url"); @@ -312,15 +350,7 @@ var elHyperlinkHref = document.getElementById("property-hyperlink-href"); var elHyperlinkDescription = document.getElementById("property-hyperlink-description"); var elHyperlinkSections = document.querySelectorAll(".hyperlink-section"); - - var elParticleSections = document.querySelectorAll(".particle-section"); - allSections.push(elParticleSections); - var elParticleIsEmitting = document.getElementById("property-particle-is-emitting"); - var elParticleMaxParticles = document.getElementById("property-particle-maxparticles"); - var elParticleLifeSpan = document.getElementById("property-particle-lifespan"); - var elParticleEmitRate = document.getElementById("property-particle-emit-rate"); - var elParticleRadius = document.getElementById("property-particle-radius"); - var elParticleTextures = document.getElementById("property-particle-textures"); + var elTextSections = document.querySelectorAll(".text-section"); allSections.push(elTextSections); @@ -378,6 +408,7 @@ var elPreviewCameraButton = document.getElementById("preview-camera-button"); if (window.EventBridge !== undefined) { + var properties; EventBridge.scriptEventReceived.connect(function(data) { data = JSON.parse(data); if (data.type == "update") { @@ -419,7 +450,7 @@ var selected = false; } - var properties = data.selections[0].properties; + properties = data.selections[0].properties; elID.innerHTML = properties.id; @@ -433,54 +464,64 @@ } else { enableChildren(document.getElementById("properties-list"), 'input'); } + elName.value = properties.name; elVisible.checked = properties.visible; - elPositionX.value = properties.position.x.toFixed(2); - elPositionY.value = properties.position.y.toFixed(2); - elPositionZ.value = properties.position.z.toFixed(2); + elPositionX.value = properties.position.x.toFixed(4); + elPositionY.value = properties.position.y.toFixed(4); + elPositionZ.value = properties.position.z.toFixed(4); - elDimensionsX.value = properties.dimensions.x.toFixed(2); - elDimensionsY.value = properties.dimensions.y.toFixed(2); - elDimensionsZ.value = properties.dimensions.z.toFixed(2); + elDimensionsX.value = properties.dimensions.x.toFixed(4); + elDimensionsY.value = properties.dimensions.y.toFixed(4); + elDimensionsZ.value = properties.dimensions.z.toFixed(4); elParentID.value = properties.parentID; elParentJointIndex.value = properties.parentJointIndex; - elRegistrationX.value = properties.registrationPoint.x.toFixed(2); - elRegistrationY.value = properties.registrationPoint.y.toFixed(2); - elRegistrationZ.value = properties.registrationPoint.z.toFixed(2); + elRegistrationX.value = properties.registrationPoint.x.toFixed(4); + elRegistrationY.value = properties.registrationPoint.y.toFixed(4); + elRegistrationZ.value = properties.registrationPoint.z.toFixed(4); - elRotationX.value = properties.rotation.x.toFixed(2); - elRotationY.value = properties.rotation.y.toFixed(2); - elRotationZ.value = properties.rotation.z.toFixed(2); + elRotationX.value = properties.rotation.x.toFixed(4); + elRotationY.value = properties.rotation.y.toFixed(4); + elRotationZ.value = properties.rotation.z.toFixed(4); - elLinearVelocityX.value = properties.velocity.x.toFixed(2); - elLinearVelocityY.value = properties.velocity.y.toFixed(2); - elLinearVelocityZ.value = properties.velocity.z.toFixed(2); + elLinearVelocityX.value = properties.velocity.x.toFixed(4); + elLinearVelocityY.value = properties.velocity.y.toFixed(4); + elLinearVelocityZ.value = properties.velocity.z.toFixed(4); elLinearDamping.value = properties.damping.toFixed(2); - elAngularVelocityX.value = (properties.angularVelocity.x * RADIANS_TO_DEGREES).toFixed(2); - elAngularVelocityY.value = (properties.angularVelocity.y * RADIANS_TO_DEGREES).toFixed(2); - elAngularVelocityZ.value = (properties.angularVelocity.z * RADIANS_TO_DEGREES).toFixed(2); - elAngularDamping.value = properties.angularDamping.toFixed(2); + elAngularVelocityX.value = (properties.angularVelocity.x * RADIANS_TO_DEGREES).toFixed(4); + elAngularVelocityY.value = (properties.angularVelocity.y * RADIANS_TO_DEGREES).toFixed(4); + elAngularVelocityZ.value = (properties.angularVelocity.z * RADIANS_TO_DEGREES).toFixed(4); + elAngularDamping.value = properties.angularDamping.toFixed(4); - elRestitution.value = properties.restitution.toFixed(2); - elFriction.value = properties.friction.toFixed(2); + elRestitution.value = properties.restitution.toFixed(4); + elFriction.value = properties.friction.toFixed(4); - elGravityX.value = properties.gravity.x.toFixed(2); - elGravityY.value = properties.gravity.y.toFixed(2); - elGravityZ.value = properties.gravity.z.toFixed(2); + elGravityX.value = properties.gravity.x.toFixed(4); + elGravityY.value = properties.gravity.y.toFixed(4); + elGravityZ.value = properties.gravity.z.toFixed(4); - elAccelerationX.value = properties.acceleration.x.toFixed(2); - elAccelerationY.value = properties.acceleration.y.toFixed(2); - elAccelerationZ.value = properties.acceleration.z.toFixed(2); + elAccelerationX.value = properties.acceleration.x.toFixed(4); + elAccelerationY.value = properties.acceleration.y.toFixed(4); + elAccelerationZ.value = properties.acceleration.z.toFixed(4); - elDensity.value = properties.density.toFixed(2); + elDensity.value = properties.density.toFixed(4); elCollisionless.checked = properties.collisionless; elDynamic.checked = properties.dynamic; + + + elCollideStatic.checked = properties.collidesWith.indexOf("static") > -1; + elCollideKinematic.checked = properties.collidesWith.indexOf("kinematic") > -1; + elCollideDynamic.checked = properties.collidesWith.indexOf("dynamic") > -1; + elCollideMyAvatar.checked = properties.collidesWith.indexOf("myAvatar") > -1; + elCollideOtherAvatar.checked = properties.collidesWith.indexOf("otherAvatar") > -1; + + elCollisionSoundURL.value = properties.collisionSoundURL; elLifetime.value = properties.lifetime; elScriptURL.value = properties.script; @@ -602,18 +643,6 @@ elZoneSkyboxURL.value = properties.skybox.url; showElements(document.getElementsByClassName('skybox-section'), elZoneBackgroundMode.value == 'skybox'); - } else if (properties.type == "ParticleEffect") { - for (var i = 0; i < elParticleSections.length; i++) { - elParticleSections[i].style.display = 'block'; - } - - elParticleIsEmitting.checked = properties.isEmitting; - elParticleMaxParticles.value = properties.maxParticles; - elParticleLifeSpan.value = properties.lifespan.toFixed(2); - elParticleEmitRate.value = properties.emitRate.toFixed(1); - elParticleRadius.value = properties.particleRadius.toFixed(3); - elParticleTextures.value = properties.textures; - } else if (properties.type == "PolyVox") { for (var i = 0; i < elPolyVoxSections.length; i++) { elPolyVoxSections[i].style.display = 'block'; @@ -702,6 +731,29 @@ elDensity.addEventListener('change', createEmitNumberPropertyUpdateFunction('density')); elCollisionless.addEventListener('change', createEmitCheckedPropertyUpdateFunction('collisionless')); elDynamic.addEventListener('change', createEmitCheckedPropertyUpdateFunction('dynamic')); + + + + + elCollideDynamic.addEventListener('change', function() { + updateCheckedSubProperty("collidesWith", properties.collidesWith, elCollideDynamic, 'dynamic'); + }); + + elCollideKinematic.addEventListener('change', function() { + updateCheckedSubProperty("collidesWith", properties.collidesWith, elCollideKinematic, 'kinematic'); + }); + + elCollideStatic.addEventListener('change', function() { + updateCheckedSubProperty("collidesWith", properties.collidesWith, elCollideStatic, 'static'); + }); + elCollideMyAvatar.addEventListener('change', function() { + updateCheckedSubProperty("collidesWith", properties.collidesWith, elCollideMyAvatar, 'myAvatar'); + }); + elCollideOtherAvatar.addEventListener('change', function() { + updateCheckedSubProperty("collidesWith", properties.collidesWith, elCollideOtherAvatar, 'otherAvatar'); + }); + + elCollisionSoundURL.addEventListener('change', createEmitTextPropertyUpdateFunction('collisionSoundURL')); elLifetime.addEventListener('change', createEmitNumberPropertyUpdateFunction('lifetime')); @@ -749,13 +801,6 @@ elWebSourceURL.addEventListener('change', createEmitTextPropertyUpdateFunction('sourceUrl')); - elParticleIsEmitting.addEventListener('change', createEmitCheckedPropertyUpdateFunction('isEmitting')); - elParticleMaxParticles.addEventListener('change', createEmitNumberPropertyUpdateFunction('maxParticles')); - elParticleLifeSpan.addEventListener('change', createEmitNumberPropertyUpdateFunction('lifespan')); - elParticleEmitRate.addEventListener('change', createEmitNumberPropertyUpdateFunction('emitRate')); - elParticleRadius.addEventListener('change', createEmitNumberPropertyUpdateFunction('particleRadius')); - elParticleTextures.addEventListener('change', createEmitTextPropertyUpdateFunction('textures')); - elModelURL.addEventListener('change', createEmitTextPropertyUpdateFunction('modelURL')); elShapeType.addEventListener('change', createEmitTextPropertyUpdateFunction('shapeType')); elCompoundShapeURL.addEventListener('change', createEmitTextPropertyUpdateFunction('compoundShapeURL')); @@ -1192,9 +1237,9 @@
Position
-
X
-
Y
-
Z
+
X
+
Y
+
Z
@@ -1228,9 +1273,9 @@
Dimensions
-
X
-
Y
-
Z
+
X
+
Y
+
Z
@@ -1280,9 +1325,9 @@
Rotation
-
Pitch
-
Yaw
-
Roll
+
Pitch
+
Yaw
+
Roll
@@ -1384,6 +1429,48 @@ +
+ + +
Collides With:
+
+
+ static + + + +
+ +
+ dynamic + + + +
+ +
+ kinematic + + + +
+ +
+ myAvatar + + + +
+ +
+ otherAvatar + + + +
+
+ +
@@ -1500,51 +1587,6 @@
- -
- -
- -
- Is Emitting - - - -
-
-
Max Particles
-
- -
-
-
-
Particle Life Span
-
- -
-
-
-
Particle Emission Rate
-
- -
-
-
-
Particle Radius
-
- -
-
-
-
Textures
-
- -
-
- - - -
@@ -1584,4 +1626,4 @@
- \ No newline at end of file + diff --git a/examples/html/style.css b/examples/html/style.css index 5b794cbfec..83982dab15 100644 --- a/examples/html/style.css +++ b/examples/html/style.css @@ -263,6 +263,10 @@ table#properties-list { border-bottom: 0.75pt solid #e5e5e5; } +.sub-props-checkbox-group { + margin-left: 20px; +} + #properties-list .label { font-weight: bold; overflow: hidden; diff --git a/examples/libraries/entityCameraTool.js b/examples/libraries/entityCameraTool.js index e3e86cedb3..d209ed6c5c 100644 --- a/examples/libraries/entityCameraTool.js +++ b/examples/libraries/entityCameraTool.js @@ -614,142 +614,19 @@ CameraTool = function(cameraManager) { visible: false, }); - var defaultCubeProps = { - size: ORIENTATION_OVERLAY_CUBE_SIZE, - alpha: 1, - color: { - red: 255, - green: 0, - blue: 0 - }, - solid: true, - visible: true, - drawOnHUD: true, - }; - var defaultLineProps = { - lineWidth: 1.5, - alpha: 1, - position: { - x: 0, - y: 0, - z: 0 - }, - start: { - x: 0, - y: 0, - z: 0 - }, - end: { - x: 0, - y: 0, - z: 0 - }, - color: { - red: 255, - green: 0, - blue: 0 - }, - visible: false, - drawOnHUD: true, - }; - - var orientationOverlay = OverlayGroup({ - position: { - x: uiPosition.x + UI_WIDTH / 2, - y: uiPosition.y + UI_HEIGHT / 2, - }, - visible: false, - }); - - var OOHS = ORIENTATION_OVERLAY_HALF_SIZE; - var cubeX = orientationOverlay.createOverlay("cube", mergeObjects(defaultCubeProps, { - position: { - x: -OOHS, - y: OOHS, - z: OOHS - }, - color: RED, - })); - var cubeY = orientationOverlay.createOverlay("cube", mergeObjects(defaultCubeProps, { - position: { - x: OOHS, - y: -OOHS, - z: OOHS - }, - color: GREEN, - })); - var cubeZ = orientationOverlay.createOverlay("cube", mergeObjects(defaultCubeProps, { - position: { - x: OOHS, - y: OOHS, - z: -OOHS - }, - color: BLUE, - })); - orientationOverlay.createOverlay("line3d", mergeObjects(defaultLineProps, { - start: { - x: -OOHS, - y: OOHS, - z: OOHS - }, - end: { - x: OOHS, - y: OOHS, - z: OOHS - }, - color: RED, - })); - orientationOverlay.createOverlay("line3d", mergeObjects(defaultLineProps, { - start: { - x: OOHS, - y: -OOHS, - z: OOHS - }, - end: { - x: OOHS, - y: OOHS, - z: OOHS - }, - color: GREEN, - })); - orientationOverlay.createOverlay("line3d", mergeObjects(defaultLineProps, { - start: { - x: OOHS, - y: OOHS, - z: -OOHS - }, - end: { - x: OOHS, - y: OOHS, - z: OOHS - }, - color: BLUE, - })); - Script.scriptEnding.connect(function() { - orientationOverlay.destroy(); Overlays.deleteOverlay(background); Overlays.deleteOverlay(backgroundBorder); }); var flip = Quat.fromPitchYawRollDegrees(0, 180, 0); that.update = function() { - orientationOverlay.setProperties({ - rotation: Quat.multiply(flip, Quat.inverse(Camera.orientation)), - }); - if (Window.innerWidth != lastKnownWidth) { lastKnownWidth = Window.innerWidth; uiPosition = { x: lastKnownWidth - UI_WIDTH - UI_PADDING, y: UI_PADDING, }; - orientationOverlay.setProperties({ - position: { - x: uiPosition.x + ORIENTATION_OVERLAY_OFFSET.x, - y: uiPosition.y + ORIENTATION_OVERLAY_OFFSET.y, - } - }); Overlays.editOverlay(backgroundBorder, { x: uiPosition.x - BORDER_WIDTH, y: uiPosition.y - BORDER_WIDTH, @@ -766,29 +643,9 @@ CameraTool = function(cameraManager) { x: event.x, y: event.y }); - - if (clickedOverlay == cubeX) { - targetPitch = 0; - targetYaw = event.isLeftButton ? 90 : -90; - cameraManager.setTargetPitchYaw(targetPitch, targetYaw); - return true; - } else if (clickedOverlay == cubeY) { - targetPitch = event.isLeftButton ? 90 : -90; - targetYaw = 0; - cameraManager.setTargetPitchYaw(targetPitch, targetYaw); - return true; - } else if (clickedOverlay == cubeZ) { - targetPitch = 0; - targetYaw = event.isLeftButton ? 0 : 180; - cameraManager.setTargetPitchYaw(targetPitch, targetYaw); - return true; - } }; that.setVisible = function(visible) { - orientationOverlay.setProperties({ - visible: visible - }); Overlays.editOverlay(background, { visible: visible }); @@ -800,4 +657,4 @@ CameraTool = function(cameraManager) { that.setVisible(false); return that; -}; \ No newline at end of file +}; diff --git a/examples/libraries/entityList.js b/examples/libraries/entityList.js index b37ba58737..6c6c0aaecb 100644 --- a/examples/libraries/entityList.js +++ b/examples/libraries/entityList.js @@ -8,12 +8,16 @@ EntityListTool = function(opts) { title: 'Entities', source: url, toolWindow: true }); + + var searchRadius = 100; var visible = false; webView.setVisible(visible); + that.webView = webView; + that.setVisible = function(newVisible) { visible = newVisible; webView.setVisible(visible); @@ -71,6 +75,7 @@ EntityListTool = function(opts) { webView.eventBridge.emitScriptEvent(JSON.stringify(data)); } + webView.eventBridge.webEventReceived.connect(function(data) { data = JSON.parse(data); if (data.type == "selectionUpdate") { diff --git a/examples/libraries/overlayManager.js b/examples/libraries/overlayManager.js index 49398c5009..4438193313 100644 --- a/examples/libraries/overlayManager.js +++ b/examples/libraries/overlayManager.js @@ -221,7 +221,7 @@ var Base3DOverlay = generateOverlayClass(Overlay, ABSTRACT, [ "position", "lineWidth", "rotation", "isSolid", "isFilled", "isWire", "isDashedLine", - "ignoreRayIntersection", "drawInFront", "drawOnHUD" + "ignoreRayIntersection", "drawInFront" ]); var Planar3DOverlay = generateOverlayClass(Base3DOverlay, ABSTRACT, [ diff --git a/examples/particle_explorer/main.js b/examples/particle_explorer/main.js deleted file mode 100644 index 4c82312e44..0000000000 --- a/examples/particle_explorer/main.js +++ /dev/null @@ -1,504 +0,0 @@ -// -// main.js -// -// Created by James B. Pollack @imgntn on 9/26/2015 -// Copyright 2015 High Fidelity, Inc. -// Web app side of the App - contains GUI. -// This is an example of a new, easy way to do two way bindings between dynamically created GUI and in-world entities. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// -/*global window, alert, EventBridge, dat, listenForSettingsUpdates,createVec3Folder,createQuatFolder,writeVec3ToInterface,writeDataToInterface*/ - -var Settings = function() { - this.exportSettings = function() { - //copyExportSettingsToClipboard(); - showPreselectedPrompt(); - }; - this.importSettings = function() { - importSettings(); - }; -}; - -//2-way bindings-aren't quite ready yet. see bottom of file. -var AUTO_UPDATE = false; -var UPDATE_ALL_FREQUENCY = 100; - -var controllers = []; -var colorControllers = []; -var folders = []; -var gui = null; -var settings = new Settings(); -var updateInterval; - -var currentInputField; -var storedController; -var keysToIgnore = [ - 'importSettings', - 'exportSettings', - 'script', - 'visible', - 'locked', - 'userData', - 'position', - 'dimensions', - 'rotation', - 'id', - 'description', - 'type', - 'created', - 'age', - 'ageAsText', - 'boundingBox', - 'naturalDimensions', - 'naturalPosition', - 'velocity', - 'gravity', - 'acceleration', - 'damping', - 'restitution', - 'friction', - 'density', - 'lifetime', - 'scriptTimestamp', - 'registrationPoint', - 'angularVelocity', - 'angularDamping', - 'collisionless', - 'dynamic', - 'href', - 'actionData', - 'marketplaceID', - 'collisionSoundURL', - 'shapeType', - 'isEmitting', - 'sittingPoints', - 'originalTextures', - 'parentJointIndex', - 'parentID' -]; - -var individualKeys = []; -var vec3Keys = []; -var quatKeys = []; -var colorKeys = []; - -window.onload = function() { - if (typeof EventBridge !== 'undefined') { - - var stringifiedData = JSON.stringify({ - messageType: 'page_loaded' - }); - - EventBridge.emitWebEvent( - stringifiedData - ); - - listenForSettingsUpdates(); - window.onresize = setGUIWidthToWindowWidth; - } else { - console.log('No event bridge, probably not in interface.'); - } -}; - -function loadGUI() { - //whether or not to autoplace - gui = new dat.GUI({ - autoPlace: false - }); - - //if not autoplacing, put gui in a custom container - if (gui.autoPlace === false) { - var customContainer = document.getElementById('my-gui-container'); - customContainer.appendChild(gui.domElement); - } - - // presets for the GUI itself. a little confusing and import/export is mostly what we want to do at the moment. - // gui.remember(settings); - - var keys = _.keys(settings); - - _.each(keys, function(key) { - var shouldIgnore = _.contains(keysToIgnore, key); - - if (shouldIgnore) { - return; - } - - var subKeys = _.keys(settings[key]); - var hasX = _.contains(subKeys, 'x'); - var hasY = _.contains(subKeys, 'y'); - var hasZ = _.contains(subKeys, 'z'); - var hasW = _.contains(subKeys, 'w'); - var hasRed = _.contains(subKeys, 'red'); - var hasGreen = _.contains(subKeys, 'green'); - var hasBlue = _.contains(subKeys, 'blue'); - - if ((hasX && hasY && hasZ) && hasW === false) { - vec3Keys.push(key); - } else if (hasX && hasY && hasZ && hasW) { - quatKeys.push(key); - } else if (hasRed || hasGreen || hasBlue) { - colorKeys.push(key); - - } else { - individualKeys.push(key); - } - - }); - - //alphabetize our keys - individualKeys.sort(); - vec3Keys.sort(); - quatKeys.sort(); - colorKeys.sort(); - - //add to gui in the order they should appear - gui.add(settings, 'importSettings'); - gui.add(settings, 'exportSettings'); - addIndividualKeys(); - addFolders(); - - //set the gui width to match the web window width - gui.width = window.innerWidth; - - //2-way binding stuff - // if (AUTO_UPDATE) { - // setInterval(manuallyUpdateDisplay, UPDATE_ALL_FREQUENCY); - // registerDOMElementsForListenerBlocking(); - // } - -} - -function addIndividualKeys() { - _.each(individualKeys, function(key) { - //temporary patch for not crashing when this goes below 0 - var controller; - - if (key.indexOf('emitRate') > -1) { - controller = gui.add(settings, key).min(0); - } else { - controller = gui.add(settings, key); - - } - - //2-way - need to fix not being able to input exact values if constantly listening - //controller.listen(); - - //keep track of our controller - controllers.push(controller); - - //hook into change events for this gui controller - controller.onChange(function(value) { - // Fires on every change, drag, keypress, etc. - writeDataToInterface(this.property, value); - }); - - }); -} - -function addFolders() { - _.each(colorKeys, function(key) { - createColorPicker(key); - }); - _.each(vec3Keys, function(key) { - createVec3Folder(key); - }); - _.each(quatKeys, function(key) { - createQuatFolder(key); - }); -} - -function createColorPicker(key) { - var colorObject = settings[key]; - var colorArray = convertColorObjectToArray(colorObject); - settings[key] = colorArray; - var controller = gui.addColor(settings, key); - controller.onChange(function(value) { - var obj = {}; - obj[key] = convertColorArrayToObject(value); - writeVec3ToInterface(obj); - }); - - return; -} - -function createVec3Folder(category) { - var folder = gui.addFolder(category); - - folder.add(settings[category], 'x').step(0.1).onChange(function(value) { - // Fires when a controller loses focus. - var obj = {}; - obj[category] = {}; - obj[category][this.property] = value; - obj[category].y = settings[category].y; - obj[category].z = settings[category].z; - writeVec3ToInterface(obj); - }); - - folder.add(settings[category], 'y').step(0.1).onChange(function(value) { - // Fires when a controller loses focus. - var obj = {}; - obj[category] = {}; - obj[category].x = settings[category].x; - obj[category][this.property] = value; - obj[category].z = settings[category].z; - writeVec3ToInterface(obj); - }); - - folder.add(settings[category], 'z').step(0.1).onChange(function(value) { - // Fires when a controller loses focus. - var obj = {}; - obj[category] = {}; - obj[category].y = settings[category].y; - obj[category].x = settings[category].x; - obj[category][this.property] = value; - writeVec3ToInterface(obj); - }); - - folders.push(folder); - folder.open(); -} - -function createQuatFolder(category) { - var folder = gui.addFolder(category); - - folder.add(settings[category], 'x').step(0.1).onChange(function(value) { - // Fires when a controller loses focus. - var obj = {}; - obj[category] = {}; - obj[category][this.property] = value; - obj[category].y = settings[category].y; - obj[category].z = settings[category].z; - obj[category].w = settings[category].w; - writeVec3ToInterface(obj); - }); - - folder.add(settings[category], 'y').step(0.1).onChange(function(value) { - // Fires when a controller loses focus. - var obj = {}; - obj[category] = {}; - obj[category].x = settings[category].x; - obj[category][this.property] = value; - obj[category].z = settings[category].z; - obj[category].w = settings[category].w; - writeVec3ToInterface(obj); - }); - - folder.add(settings[category], 'z').step(0.1).onChange(function(value) { - // Fires when a controller loses focus. - var obj = {}; - obj[category] = {}; - obj[category].x = settings[category].x; - obj[category].y = settings[category].y; - obj[category][this.property] = value; - obj[category].w = settings[category].w; - writeVec3ToInterface(obj); - }); - - folder.add(settings[category], 'w').step(0.1).onChange(function(value) { - // Fires when a controller loses focus. - var obj = {}; - obj[category] = {}; - obj[category].x = settings[category].x; - obj[category].y = settings[category].y; - obj[category].z = settings[category].z; - obj[category][this.property] = value; - writeVec3ToInterface(obj); - }); - - folders.push(folder); - folder.open(); -} - -function convertColorObjectToArray(colorObject) { - var colorArray = []; - - _.each(colorObject, function(singleColor) { - colorArray.push(singleColor); - }); - - return colorArray; -} - -function convertColorArrayToObject(colorArray) { - var colorObject = { - red: colorArray[0], - green: colorArray[1], - blue: colorArray[2] - }; - - return colorObject; -} - -function writeDataToInterface(property, value) { - var data = {}; - data[property] = value; - - var sendData = { - messageType: "settings_update", - updatedSettings: data - }; - - var stringifiedData = JSON.stringify(sendData); - - EventBridge.emitWebEvent(stringifiedData); -} - -function writeVec3ToInterface(obj) { - var sendData = { - messageType: "settings_update", - updatedSettings: obj - }; - - var stringifiedData = JSON.stringify(sendData); - - EventBridge.emitWebEvent(stringifiedData); -} - -function listenForSettingsUpdates() { - EventBridge.scriptEventReceived.connect(function(data) { - data = JSON.parse(data); - - //2-way - // if (data.messageType === 'object_update') { - // _.each(data.objectSettings, function(value, key) { - // settings[key] = value; - // }); - // } - - if (data.messageType === 'initial_settings') { - _.each(data.initialSettings, function(value, key) { - settings[key] = {}; - settings[key] = value; - }); - - loadGUI(); - } - }); -} - -function manuallyUpdateDisplay() { - // Iterate over all controllers - // this is expensive, write a method for indiviudal controllers and use it when the value is different than a cached value, perhaps. - var i; - for (i in gui.__controllers) { - gui.__controllers[i].updateDisplay(); - } -} - -function setGUIWidthToWindowWidth() { - if (gui !== null) { - gui.width = window.innerWidth; - } -} - -function handleInputKeyPress(e) { - if (e.keyCode === 13) { - importSettings(); - } - return false; -} - -function importSettings() { - var importInput = document.getElementById('importer-input'); - - try { - var importedSettings = JSON.parse(importInput.value); - - var keys = _.keys(importedSettings); - - _.each(keys, function(key) { - var shouldIgnore = _.contains(keysToIgnore, key); - - if (shouldIgnore) { - return; - } - - settings[key] = importedSettings[key]; - }); - - writeVec3ToInterface(settings); - - manuallyUpdateDisplay(); - } catch (e) { - alert('Not properly formatted JSON'); - } -} - -function prepareSettingsForExport() { - var keys = _.keys(settings); - - var exportSettings = {}; - - _.each(keys, function(key) { - var shouldIgnore = _.contains(keysToIgnore, key); - - if (shouldIgnore) { - return; - } - - if (key.indexOf('color') > -1) { - var colorObject = convertColorArrayToObject(settings[key]); - settings[key] = colorObject; - } - - exportSettings[key] = settings[key]; - }); - - return JSON.stringify(exportSettings); -} - -function showPreselectedPrompt() { - window.prompt("Ctrl-C to copy, then Enter.", prepareSettingsForExport()); -} - -function removeContainerDomElement() { - var elem = document.getElementById("my-gui-container"); - elem.parentNode.removeChild(elem); -} - -function removeListenerFromGUI(key) { - _.each(gui.__listening, function(controller, index) { - if (controller.property === key) { - storedController = controller; - gui.__listening.splice(index, 1); - } - }); -} - -//the section below is to try to work at achieving two way bindings; -function addListenersBackToGUI() { - gui.__listening.push(storedController); - storedController = null; -} - -function registerDOMElementsForListenerBlocking() { - _.each(gui.__controllers, function(controller) { - var input = controller.domElement.childNodes[0]; - input.addEventListener('focus', function() { - console.log('INPUT ELEMENT GOT FOCUS!' + controller.property); - removeListenerFromGUI(controller.property); - }); - }); - - _.each(gui.__controllers, function(controller) { - var input = controller.domElement.childNodes[0]; - input.addEventListener('blur', function() { - console.log('INPUT ELEMENT GOT BLUR!' + controller.property); - addListenersBackToGUI(); - }); - }); - - // also listen to inputs inside of folders - _.each(gui.__folders, function(folder) { - _.each(folder.__controllers, function(controller) { - var input = controller.__input; - input.addEventListener('focus', function() { - console.log('FOLDER ELEMENT GOT FOCUS!' + controller.property); - }); - }); - }); -} - diff --git a/examples/particle_explorer/index.html b/examples/particle_explorer/particleExplorer.html similarity index 57% rename from examples/particle_explorer/index.html rename to examples/particle_explorer/particleExplorer.html index 4b9e2a9d36..d69d221306 100644 --- a/examples/particle_explorer/index.html +++ b/examples/particle_explorer/particleExplorer.html @@ -1,5 +1,5 @@