From 0bf822f17b54731cb6bffa66e7660842381b2ae7 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Thu, 11 Feb 2016 16:48:54 -0800 Subject: [PATCH 01/19] update and add another entity script --- .../CellScience/Scripts/moveRandomly.js | 138 ++------------- .../Scripts/zoomAndMoveRandomly.js | 159 ++++++++++++++++++ .../CellScience/backgroundMusicAC.js | 8 +- .../CellScience/importCellScience.js | 4 +- 4 files changed, 181 insertions(+), 128 deletions(-) create mode 100644 unpublishedScripts/DomainContent/CellScience/Scripts/zoomAndMoveRandomly.js diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/moveRandomly.js b/unpublishedScripts/DomainContent/CellScience/Scripts/moveRandomly.js index a975f74733..8c3a6c0852 100644 --- a/unpublishedScripts/DomainContent/CellScience/Scripts/moveRandomly.js +++ b/unpublishedScripts/DomainContent/CellScience/Scripts/moveRandomly.js @@ -8,124 +8,32 @@ var self = this; - this.preload = function(entityId) { - //print('preload move randomly') + this.preload=function(entityId){ this.isConnected = false; this.entityId = entityId; - this.updateInterval = 100; - this.posFrame = 0; - this.rotFrame = 0; - this.posInterval = 100; - this.rotInterval = 100; this.minVelocity = 1; this.maxVelocity = 5; this.minAngularVelocity = 0.01; this.maxAngularVelocity = 0.03; - - this.initialize(entityId); - this.initTimeout = null; - - - var userData = { - ownershipKey: { - owner: MyAvatar.sessionUUID - }, - grabbableKey: { - grabbable: false - } - }; - - Entities.editEntity(entityId, { - userData: JSON.stringify(userData) - }) + Script.setTimeout(self.move,self.getTotalWait()) } - this.initialize = function(entityId) { - //print('move randomly should initialize' + entityId) - var properties = Entities.getEntityProperties(entityId); - if (properties.userData.length === 0 || properties.hasOwnProperty('userData') === false) { - self.initTimeout = Script.setTimeout(function() { - //print('no user data yet, try again in one second') - self.initialize(entityId); - }, 1000) - } else { - //print('userdata before parse attempt' + properties.userData) - self.userData = null; - try { - self.userData = JSON.parse(properties.userData); - } catch (err) { - //print('error parsing json'); - //print('properties are:' + properties.userData); - return; - } - Script.update.connect(self.update); - this.isConnected = true; - } - } - - this.update = function(deltaTime) { - // print('jbp in update') - var data = Entities.getEntityProperties(self.entityId, 'userData').userData; - var userData; - try { - userData = JSON.parse(data) - } catch (e) { - //print('error parsing json' + data) - return; - }; - - // print('userdata is' + data) - //if the entity doesnt have an owner set yet - if (userData.hasOwnProperty('ownershipKey') !== true) { - //print('no movement owner yet') - return; - } - - //print('owner is:::' + userData.ownershipKey.owner) - //get all the avatars to see if the owner is around + this.getTotalWait = function() { var avatars = AvatarList.getAvatarIdentifiers(); - var ownerIsAround = false; + var avatarCount = avatars.length; + var random = Math.random() * 2000; + var totalWait = random * (avatarCount * 2); - //if the current owner is not me... - if (userData.ownershipKey.owner !== MyAvatar.sessionUUID) { + return totalWait + } - //look to see if the current owner is around anymore - for (var i = 0; i < avatars.length; i++) { - if (avatars[i] === userData.ownershipKey.owner) { - ownerIsAround = true - //the owner is around - return; - }; - } - //if the owner is not around, then take ownership - if (ownerIsAround === false) { - //print('taking ownership') + this.move = function() { + print('jbp im the owner so move it') + + - var userData = { - ownershipKey: { - owner: MyAvatar.sessionUUID - }, - grabbableKey: { - grabbable: false - } - }; - Entities.editEntity(self.entityId, { - userData: JSON.stringify(data) - }) - } - } - //but if the current owner IS me, then move it - else { - //print('jbp im the owner so move it') - self.posFrame++; - self.rotFrame++; - - if (self.posFrame > self.posInterval) { - - self.posInterval = 100 * Math.random() + 300; - self.posFrame = 0; var magnitudeV = self.maxVelocity; var directionV = { @@ -137,16 +45,9 @@ //print("POS magnitude is " + magnitudeV + " and direction is " + directionV.x); Entities.editEntity(self.entityId, { velocity: Vec3.multiply(magnitudeV, Vec3.normalize(directionV)) - }); - } - - if (self.rotFrame > self.rotInterval) { - - self.rotInterval = 100 * Math.random() + 250; - self.rotFrame = 0; - + var magnitudeAV = self.maxAngularVelocity; var directionAV = { @@ -160,20 +61,13 @@ }); - } - - } + + Script.setTimeout(self.move,self.getTotalWait()) } - this.unload = function() { - if (this.initTimeout !== null) { - Script.clearTimeout(this.initTimeout); - } - if (this.isConnected === true) { - Script.update.disconnect(this.update); - } + this.unload = function() { } diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/zoomAndMoveRandomly.js b/unpublishedScripts/DomainContent/CellScience/Scripts/zoomAndMoveRandomly.js new file mode 100644 index 0000000000..f0f77b12e0 --- /dev/null +++ b/unpublishedScripts/DomainContent/CellScience/Scripts/zoomAndMoveRandomly.js @@ -0,0 +1,159 @@ +// Copyright 2016 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 +// + +(function() { + var teleport; + var portalDestination; + var animationURL; + var self = this; + + this.entered = true; + + this.preload = function(entityID) { + this.entityId = entityID; + this.initialize(entityID); + this.initTimeout = null; + this.minVelocity = 1; + this.maxVelocity = 5; + this.minAngularVelocity = 0.01; + this.maxAngularVelocity = 0.03; + Script.setTimeout(self.move, self.getTotalWait()) + } + + this.initialize = function(entityID) { + // print(' should initialize') + var properties = Entities.getEntityProperties(entityID); + if (properties.userData.length === 0 || properties.hasOwnProperty('userData') === false) { + self.initTimeout = Script.setTimeout(function() { + // print(' no user data yet, try again in one second') + self.initialize(entityID); + }, 1000) + } else { + // print(' has userData') + self.portalDestination = properties.userData; + animationURL = properties.modelURL; + self.soundOptions = { + stereo: true, + loop: false, + localOnly: false, + position: properties.position, + volume: 0.5 + }; + + self.teleportSound = SoundCache.getSound("https://hifi-content.s3.amazonaws.com/DomainContent/CellScience/Audio/whoosh.wav"); + // print(" portal destination is " + self.portalDestination); + } + } + + this.enterEntity = function(entityID) { + //print('ENTERED A BOUNDARY ENTITY, SHOULD ZOOM', entityID) + var data = JSON.parse(Entities.getEntityProperties(this.entityId).userData); + //print('DATA IS::' + data) + if (data != null) { + print("Teleporting to (" + data.location.x + ", " + data.location.y + ", " + data.location.z + ")"); + + MyAvatar.position = data.location; + + // if (data.hasOwnProperty('entryPoint') && data.hasOwnProperty('target')) { + // this.lookAtTarget(data.entryPoint, data.target); + // } + // else{ + + // } + } + + } + + this.lookAtTarget = function(entryPoint, target) { + //print('SHOULD LOOK AT TARGET') + var direction = Vec3.normalize(Vec3.subtract(entryPoint, target)); + var pitch = Quat.angleAxis(Math.asin(-direction.y) * 180.0 / Math.PI, { + x: 1, + y: 0, + z: 0 + }); + var yaw = Quat.angleAxis(Math.atan2(direction.x, direction.z) * 180.0 / Math.PI, { + x: 0, + y: 1, + z: 0 + }); + + MyAvatar.goToLocation(entryPoint, true, yaw); + + MyAvatar.headYaw = 0; + + } + + this.leaveEntity = function(entityID) { + Entities.editEntity(entityID, { + animationURL: animationURL, + animationSettings: '{ "frameIndex": 1, "running": false }' + }); + this.entered = false; + if (this.initTimeout !== null) { + Script.clearTimeout(this.initTimeout); + } + //playSound(); + } + + this.unload = function() { + if (this.initTimeout !== null) { + Script.clearTimeout(this.initTimeout); + } + } + + this.hoverEnterEntity = function(entityID) { + Entities.editEntity(entityID, { + animationURL: animationURL, + animationSettings: '{ "fps": 24, "firstFrame": 1, "lastFrame": 25, "frameIndex": 1, "running": true, "hold": true }' + }); + } + + this.getTotalWait = function() { + var avatars = AvatarList.getAvatarIdentifiers(); + var avatarCount = avatars.length; + var random = Math.random() * 2000; + var totalWait = random * (avatarCount * 2); + + return totalWait + } + + + this.move = function() { + print('jbp im the owner so move it') + + var magnitudeV = self.maxVelocity; + var directionV = { + x: Math.random() - 0.5, + y: Math.random() - 0.5, + z: Math.random() - 0.5 + }; + + //print("POS magnitude is " + magnitudeV + " and direction is " + directionV.x); + Entities.editEntity(self.entityId, { + velocity: Vec3.multiply(magnitudeV, Vec3.normalize(directionV)) + }); + + + + var magnitudeAV = self.maxAngularVelocity; + + var directionAV = { + x: Math.random() - 0.5, + y: Math.random() - 0.5, + z: Math.random() - 0.5 + }; + //print("ROT magnitude is " + magnitudeAV + " and direction is " + directionAV.x); + Entities.editEntity(self.entityId, { + angularVelocity: Vec3.multiply(magnitudeAV, Vec3.normalize(directionAV)) + + }); + + Script.setTimeout(self.move, self.getTotalWait()) + } + +}) \ No newline at end of file diff --git a/unpublishedScripts/DomainContent/CellScience/backgroundMusicAC.js b/unpublishedScripts/DomainContent/CellScience/backgroundMusicAC.js index 0ee5b3bf32..1b4c06caaa 100644 --- a/unpublishedScripts/DomainContent/CellScience/backgroundMusicAC.js +++ b/unpublishedScripts/DomainContent/CellScience/backgroundMusicAC.js @@ -7,7 +7,7 @@ var soundMap = [{ y: 15850, z: 15850 }, - volume: 0.1, + volume: 0.03, loop: true } }, { @@ -19,7 +19,7 @@ var soundMap = [{ y: 15950, z: 15950 }, - volume: 0.1, + volume: 0.03, loop: true } }, { @@ -31,7 +31,7 @@ var soundMap = [{ y: 15650, z: 15650 }, - volume: 0.1, + volume: 0.03, loop: true } }, { @@ -43,7 +43,7 @@ var soundMap = [{ y: 15750, z: 15750 }, - volume: 0.1, + volume: 0.03, loop: true } } diff --git a/unpublishedScripts/DomainContent/CellScience/importCellScience.js b/unpublishedScripts/DomainContent/CellScience/importCellScience.js index ca0eb21f21..7d9a49294f 100644 --- a/unpublishedScripts/DomainContent/CellScience/importCellScience.js +++ b/unpublishedScripts/DomainContent/CellScience/importCellScience.js @@ -5,7 +5,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -var version = 1035; +var version = 1039; var cellLayout; var baseLocation = "https://hifi-content.s3.amazonaws.com/DomainContent/CellScience/"; @@ -120,7 +120,7 @@ var scenes = [{ location: locations.cellLayout[1], baseURL: baseLocation }), - script: "zoom.js?" + version, + script: "zoomAndMoveRandomly.js?" + version, visible: true }], boundary: { From f346ac7023c4ea9f4819bc13677867ac9b9add91 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Fri, 12 Feb 2016 13:58:02 -0800 Subject: [PATCH 02/19] logging --- examples/gridTest.js | 5 +++-- .../CellScience/Scripts/moveRandomly.js | 8 ++------ .../CellScience/Scripts/navigationButton.js | 6 +++--- .../CellScience/Scripts/showIdentification.js | 3 ++- .../DomainContent/CellScience/Scripts/zoom.js | 1 + .../Scripts/zoomAndMoveRandomly.js | 1 - .../CellScience/importCellScience.js | 20 +++++++++++-------- 7 files changed, 23 insertions(+), 21 deletions(-) diff --git a/examples/gridTest.js b/examples/gridTest.js index 0d6040470f..5bbd3246ae 100644 --- a/examples/gridTest.js +++ b/examples/gridTest.js @@ -17,8 +17,8 @@ var SIZE = 10.0; var SEPARATION = 20.0; var ROWS_X = 30; var ROWS_Z = 30; -var TYPE = "Sphere"; // Right now this can be "Box" or "Model" or "Sphere" -var MODEL_URL = "https://hifi-public.s3.amazonaws.com/models/props/LowPolyIsland/CypressTreeGroup.fbx"; +var TYPE = "Model"; // Right now this can be "Box" or "Model" or "Sphere" +var MODEL_URL = "http://hifi-content.s3.amazonaws.com/DomainContent/CellScience/Instances/vesicle.fbx"; var MODEL_DIMENSION = { x: 33, y: 16, z: 49 }; var RATE_PER_SECOND = 1000; // The entity server will drop data if we create things too fast. var SCRIPT_INTERVAL = 100; @@ -38,6 +38,7 @@ Script.setInterval(function () { var numToCreate = RATE_PER_SECOND * (SCRIPT_INTERVAL / 1000.0); for (var i = 0; i < numToCreate; i++) { var position = { x: SIZE + (x * SEPARATION), y: SIZE, z: SIZE + (z * SEPARATION) }; + print('position:'+JSON.stringify(position)) if (TYPE == "Model") { Entities.addEntity({ type: TYPE, diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/moveRandomly.js b/unpublishedScripts/DomainContent/CellScience/Scripts/moveRandomly.js index 8c3a6c0852..2cced94672 100644 --- a/unpublishedScripts/DomainContent/CellScience/Scripts/moveRandomly.js +++ b/unpublishedScripts/DomainContent/CellScience/Scripts/moveRandomly.js @@ -9,6 +9,7 @@ var self = this; this.preload=function(entityId){ + print('JBP MOVE RANDOMLY PRELOAD') this.isConnected = false; this.entityId = entityId; this.minVelocity = 1; @@ -22,7 +23,7 @@ this.getTotalWait = function() { var avatars = AvatarList.getAvatarIdentifiers(); var avatarCount = avatars.length; - var random = Math.random() * 2000; + var random = Math.random() * 5000; var totalWait = random * (avatarCount * 2); return totalWait @@ -30,11 +31,6 @@ this.move = function() { - print('jbp im the owner so move it') - - - - var magnitudeV = self.maxVelocity; var directionV = { x: Math.random() - 0.5, diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/navigationButton.js b/unpublishedScripts/DomainContent/CellScience/Scripts/navigationButton.js index 4136f1f81b..16fb31189a 100644 --- a/unpublishedScripts/DomainContent/CellScience/Scripts/navigationButton.js +++ b/unpublishedScripts/DomainContent/CellScience/Scripts/navigationButton.js @@ -17,6 +17,7 @@ var baseURL = "https://hifi-content.s3.amazonaws.com/DomainContent/CellScience/"; this.preload = function(entityId) { + print('JBP NAV PRELOAD') this.entityId = entityId; this.initialize(entityId); this.initTimeout = null; @@ -58,14 +59,13 @@ self.buttonImageURL = baseURL + "GUI/GUI_" + self.userData.name + ".png?" + version; print('JBP BUTTON IMAGE URL:' + self.buttonImageURL) if (self.button === undefined) { - // print('NAV NO BUTTON ADDING ONE!!') + print('JBP NO BUTTON ADDING ONE!!') self.button = true; self.addButton(); } else { - // print('NAV SELF ALREADY HAS A BUTTON!!') + print('JBP SELF ALREADY HAS A BUTTON!!') } - } } diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/showIdentification.js b/unpublishedScripts/DomainContent/CellScience/Scripts/showIdentification.js index d8b32ab176..b7aad5e652 100644 --- a/unpublishedScripts/DomainContent/CellScience/Scripts/showIdentification.js +++ b/unpublishedScripts/DomainContent/CellScience/Scripts/showIdentification.js @@ -10,8 +10,9 @@ var self = this; var baseURL = "https://hifi-content.s3.amazonaws.com/DomainContent/CellScience/"; - var version = 2; + var version = 3; this.preload = function(entityId) { + print('JBP SHOW IDENTIFICATION PRELOAD') this.soundPlaying = null; this.entityId = entityId; self.initTimeout = null; diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/zoom.js b/unpublishedScripts/DomainContent/CellScience/Scripts/zoom.js index da41ec64ba..d075966524 100644 --- a/unpublishedScripts/DomainContent/CellScience/Scripts/zoom.js +++ b/unpublishedScripts/DomainContent/CellScience/Scripts/zoom.js @@ -14,6 +14,7 @@ this.entered = true; this.preload = function(entityID) { + print('JBP Zoom PRELOAD') this.entityId = entityID; this.initialize(entityID); this.initTimeout = null; diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/zoomAndMoveRandomly.js b/unpublishedScripts/DomainContent/CellScience/Scripts/zoomAndMoveRandomly.js index f0f77b12e0..e4ee59cb6b 100644 --- a/unpublishedScripts/DomainContent/CellScience/Scripts/zoomAndMoveRandomly.js +++ b/unpublishedScripts/DomainContent/CellScience/Scripts/zoomAndMoveRandomly.js @@ -124,7 +124,6 @@ this.move = function() { - print('jbp im the owner so move it') var magnitudeV = self.maxVelocity; var directionV = { diff --git a/unpublishedScripts/DomainContent/CellScience/importCellScience.js b/unpublishedScripts/DomainContent/CellScience/importCellScience.js index 7d9a49294f..bf112f5bad 100644 --- a/unpublishedScripts/DomainContent/CellScience/importCellScience.js +++ b/unpublishedScripts/DomainContent/CellScience/importCellScience.js @@ -5,7 +5,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -var version = 1039; +var version = 1041; var cellLayout; var baseLocation = "https://hifi-content.s3.amazonaws.com/DomainContent/CellScience/"; @@ -645,8 +645,7 @@ function createLayoutLights() { } function CreateNavigationButton(scene, number) { - // print('NAV NAVIGATION CREATING NAV!!' +scene.name + " " + number) - + print('JBP NAVIGATION CREATING NAV!!' +scene.name + " " + number) Entities.addEntity({ type: "Box", @@ -657,11 +656,11 @@ function CreateNavigationButton(scene, number) { blue: 0 }, dimensions: { - x: 16000, - y: 16000, - z: 16000 + x: 14000, + y: 14000, + z: 14000 }, - visible: false, + visible: true, userData: JSON.stringify({ name: scene.name, entryPoint: scene.entryPoint, @@ -9045,4 +9044,9 @@ createLayoutLights(); Script.scriptEnding.connect(function() { Entities.addingEntity.disconnect(makeUngrabbable); -}); \ No newline at end of file +}); + +Script.setTimeout(function(){ + print('JBP stopping cell science import'); + Script.stop(); +},30000) \ No newline at end of file From e828a7e6e2b2fd0dfae93bfa202108b01698ce87 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Fri, 12 Feb 2016 19:38:40 -0800 Subject: [PATCH 03/19] quiet prints --- .../CellScience/Scripts/moveRandomly.js | 1 - .../CellScience/Scripts/navigationButton.js | 22 +++++++++---------- .../CellScience/Scripts/showIdentification.js | 1 - .../DomainContent/CellScience/Scripts/zoom.js | 1 - .../CellScience/importCellScience.js | 14 +++++------- 5 files changed, 15 insertions(+), 24 deletions(-) diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/moveRandomly.js b/unpublishedScripts/DomainContent/CellScience/Scripts/moveRandomly.js index 2cced94672..cc822ddf8a 100644 --- a/unpublishedScripts/DomainContent/CellScience/Scripts/moveRandomly.js +++ b/unpublishedScripts/DomainContent/CellScience/Scripts/moveRandomly.js @@ -9,7 +9,6 @@ var self = this; this.preload=function(entityId){ - print('JBP MOVE RANDOMLY PRELOAD') this.isConnected = false; this.entityId = entityId; this.minVelocity = 1; diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/navigationButton.js b/unpublishedScripts/DomainContent/CellScience/Scripts/navigationButton.js index 16fb31189a..c1187bc6d5 100644 --- a/unpublishedScripts/DomainContent/CellScience/Scripts/navigationButton.js +++ b/unpublishedScripts/DomainContent/CellScience/Scripts/navigationButton.js @@ -7,7 +7,7 @@ (function() { - var version = 11; + var version = 12; var added = false; this.frame = 0; var utilsScript = Script.resolvePath('utils.js'); @@ -17,29 +17,27 @@ var baseURL = "https://hifi-content.s3.amazonaws.com/DomainContent/CellScience/"; this.preload = function(entityId) { - print('JBP NAV PRELOAD') this.entityId = entityId; this.initialize(entityId); this.initTimeout = null; } this.initialize = function(entityId) { - print('JBP nav button should initialize' + entityId) var properties = Entities.getEntityProperties(entityId); if (properties.userData.length === 0 || properties.hasOwnProperty('userData') === false) { self.initTimeout = Script.setTimeout(function() { - print('JBP no user data yet, try again in one second') + // print(' no user data yet, try again in one second') self.initialize(entityId); }, 1000) } else { - print('JBP userdata before parse attempt' + properties.userData) + // print('userdata before parse attempt' + properties.userData) self.userData = null; try { self.userData = JSON.parse(properties.userData); } catch (err) { - print('JBP error parsing json'); - print('JBP properties are:' + properties.userData); + // print(' error parsing json'); + // print(' properties are:' + properties.userData); return; } @@ -47,9 +45,9 @@ var mySavedSettings = Settings.getValue(entityId); if (mySavedSettings.buttons !== undefined) { - print('JBP preload buttons' + mySavedSettings.buttons) + // print(' preload buttons' + mySavedSettings.buttons) mySavedSettings.buttons.forEach(function(b) { - print('JBP deleting button' + b) + // print(' deleting button' + b) Overlays.deleteOverlay(b); }) Settings.setValue(entityId, '') @@ -57,14 +55,14 @@ self.buttonImageURL = baseURL + "GUI/GUI_" + self.userData.name + ".png?" + version; - print('JBP BUTTON IMAGE URL:' + self.buttonImageURL) + // print(' BUTTON IMAGE URL:' + self.buttonImageURL) if (self.button === undefined) { - print('JBP NO BUTTON ADDING ONE!!') + // print(' NO BUTTON ADDING ONE!!') self.button = true; self.addButton(); } else { - print('JBP SELF ALREADY HAS A BUTTON!!') + //print(' SELF ALREADY HAS A BUTTON!!') } } } diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/showIdentification.js b/unpublishedScripts/DomainContent/CellScience/Scripts/showIdentification.js index b7aad5e652..3f6067693c 100644 --- a/unpublishedScripts/DomainContent/CellScience/Scripts/showIdentification.js +++ b/unpublishedScripts/DomainContent/CellScience/Scripts/showIdentification.js @@ -12,7 +12,6 @@ var version = 3; this.preload = function(entityId) { - print('JBP SHOW IDENTIFICATION PRELOAD') this.soundPlaying = null; this.entityId = entityId; self.initTimeout = null; diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/zoom.js b/unpublishedScripts/DomainContent/CellScience/Scripts/zoom.js index d075966524..da41ec64ba 100644 --- a/unpublishedScripts/DomainContent/CellScience/Scripts/zoom.js +++ b/unpublishedScripts/DomainContent/CellScience/Scripts/zoom.js @@ -14,7 +14,6 @@ this.entered = true; this.preload = function(entityID) { - print('JBP Zoom PRELOAD') this.entityId = entityID; this.initialize(entityID); this.initTimeout = null; diff --git a/unpublishedScripts/DomainContent/CellScience/importCellScience.js b/unpublishedScripts/DomainContent/CellScience/importCellScience.js index bf112f5bad..db50635f93 100644 --- a/unpublishedScripts/DomainContent/CellScience/importCellScience.js +++ b/unpublishedScripts/DomainContent/CellScience/importCellScience.js @@ -5,7 +5,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -var version = 1041; +var version = 1043; var cellLayout; var baseLocation = "https://hifi-content.s3.amazonaws.com/DomainContent/CellScience/"; @@ -609,12 +609,10 @@ function ImportScene(scene) { clearAllNav(); function clearAllNav() { - // print('NAV CLEARING ALL NAV'); var result = Entities.findEntities(MyAvatar.position, 25000); result.forEach(function(r) { var properties = Entities.getEntityProperties(r, "name"); if (properties.name.indexOf('navigation button') > -1) { - // print('NAV DELETING NAV BUTTON AT START:: '+r) Entities.deleteEntity(r); } }) @@ -645,8 +643,6 @@ function createLayoutLights() { } function CreateNavigationButton(scene, number) { - print('JBP NAVIGATION CREATING NAV!!' +scene.name + " " + number) - Entities.addEntity({ type: "Box", name: scene.name + " navigation button", @@ -656,11 +652,11 @@ function CreateNavigationButton(scene, number) { blue: 0 }, dimensions: { - x: 14000, - y: 14000, - z: 14000 + x: 16000, + y: 16000, + z: 16000 }, - visible: true, + visible: false, userData: JSON.stringify({ name: scene.name, entryPoint: scene.entryPoint, From 214723f1bfdf86cf1821265742e53d016be628a0 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Thu, 18 Feb 2016 14:27:47 -0800 Subject: [PATCH 04/19] baton for moving vesicles" " --- .../CellScience/Scripts/colorRandomly.js | 104 +++++ .../CellScience/Scripts/moveRandomly.js | 71 ---- .../CellScience/Scripts/moveRandomly2.js | 95 +++++ .../CellScience/Scripts/virtualBaton.js | 381 ++++++++++++++++++ .../Scripts/zoomAndMoveRandomly.js | 48 ++- .../CellScience/importCellScience.js | 10 +- 6 files changed, 618 insertions(+), 91 deletions(-) create mode 100644 unpublishedScripts/DomainContent/CellScience/Scripts/colorRandomly.js delete mode 100644 unpublishedScripts/DomainContent/CellScience/Scripts/moveRandomly.js create mode 100644 unpublishedScripts/DomainContent/CellScience/Scripts/moveRandomly2.js create mode 100644 unpublishedScripts/DomainContent/CellScience/Scripts/virtualBaton.js diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/colorRandomly.js b/unpublishedScripts/DomainContent/CellScience/Scripts/colorRandomly.js new file mode 100644 index 0000000000..cf4ee810e7 --- /dev/null +++ b/unpublishedScripts/DomainContent/CellScience/Scripts/colorRandomly.js @@ -0,0 +1,104 @@ +// Copyright 2016 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 +// +(function() { + + Script.include(Script.resolvePath('virtualBaton.js')); + + var self = this; + + var baton; + var iOwn = false; + var currentInterval; + var _entityId; + + function startUpdate() { + iOwn = true; + print('i am the owner ' + _entityId) + } + + function stopUpdateAndReclaim() { + print('i released the object ' + _entityId) + iOwn = false; + baton.claim(startUpdate, stopUpdateAndReclaim); + } + + this.preload = function(entityId) { + this.isConnected = false; + this.entityId = entityId; + _entityId = entityId; + this.minVelocity = 1; + this.maxVelocity = 5; + this.minAngularVelocity = 0.01; + this.maxAngularVelocity = 0.03; + baton = virtualBaton({ + batonName: 'io.highfidelity.vesicles:' + entityId, // One winner for each entity + }); + stopUpdateAndReclaim(); + currentInterval = Script.setInterval(self.move, self.getTotalWait()) + } + + + this.getTotalWait = function() { + return (Math.random() * 5000) * 2; + // var avatars = AvatarList.getAvatarIdentifiers(); + // var avatarCount = avatars.length; + // var random = Math.random() * 5000; + // var totalWait = random * (avatarCount * 2); + // print('cellscience color avatarcount, totalwait: ', avatarCount, totalWait) + // return totalWait + } + + + this.move = function() { + if (!iOwn) { + return; + } + + var properties = Entities.getEntityProperties(self.entityId); + var color = properties.color; + + var newColor; + var red = { + red: 255, + green: 0, + blue: 0 + } + var green = { + red: 0, + green: 255, + blue: 0 + } + var blue = { + red: 0, + green: 0, + blue: 255 + } + if (color.red > 0) { + newColor = green; + } + if (color.green > 0) { + newColor = blue; + } + if (color.blue > 0) { + newColor = red + } + Entities.editEntity(self.entityId, { + color: newColor + }); + + + } + + + this.unload = function() { + baton.release(function() {}); + Script.clearTimeout(currentInterval); + } + + + +}) \ No newline at end of file diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/moveRandomly.js b/unpublishedScripts/DomainContent/CellScience/Scripts/moveRandomly.js deleted file mode 100644 index cc822ddf8a..0000000000 --- a/unpublishedScripts/DomainContent/CellScience/Scripts/moveRandomly.js +++ /dev/null @@ -1,71 +0,0 @@ -// Copyright 2016 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 -// -(function() { - - var self = this; - - this.preload=function(entityId){ - this.isConnected = false; - this.entityId = entityId; - this.minVelocity = 1; - this.maxVelocity = 5; - this.minAngularVelocity = 0.01; - this.maxAngularVelocity = 0.03; - Script.setTimeout(self.move,self.getTotalWait()) - } - - - this.getTotalWait = function() { - var avatars = AvatarList.getAvatarIdentifiers(); - var avatarCount = avatars.length; - var random = Math.random() * 5000; - var totalWait = random * (avatarCount * 2); - - return totalWait - } - - - this.move = function() { - var magnitudeV = self.maxVelocity; - var directionV = { - x: Math.random() - 0.5, - y: Math.random() - 0.5, - z: Math.random() - 0.5 - }; - - //print("POS magnitude is " + magnitudeV + " and direction is " + directionV.x); - Entities.editEntity(self.entityId, { - velocity: Vec3.multiply(magnitudeV, Vec3.normalize(directionV)) - }); - - - var magnitudeAV = self.maxAngularVelocity; - - var directionAV = { - x: Math.random() - 0.5, - y: Math.random() - 0.5, - z: Math.random() - 0.5 - }; - //print("ROT magnitude is " + magnitudeAV + " and direction is " + directionAV.x); - Entities.editEntity(self.entityId, { - angularVelocity: Vec3.multiply(magnitudeAV, Vec3.normalize(directionAV)) - - }); - - - - Script.setTimeout(self.move,self.getTotalWait()) - } - - - this.unload = function() { - - } - - - -}) \ No newline at end of file diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/moveRandomly2.js b/unpublishedScripts/DomainContent/CellScience/Scripts/moveRandomly2.js new file mode 100644 index 0000000000..f720ca91cc --- /dev/null +++ b/unpublishedScripts/DomainContent/CellScience/Scripts/moveRandomly2.js @@ -0,0 +1,95 @@ +// Copyright 2016 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 +// +(function() { + + Script.include('virtualBaton.js'); + + var self = this; + + var baton; + var iOwn = false; + var currentInterval; + var _entityId; + + function startUpdate() { + iOwn = true; + print('i am the owner ' + _entityId) + } + + function stopUpdateAndReclaim() { + print('i released the object ' + _entityId) + iOwn = false; + baton.claim(startUpdate, stopUpdateAndReclaim); + } + + this.preload = function(entityId) { + this.isConnected = false; + this.entityId = entityId; + _entityId = entityId; + this.minVelocity = 1; + this.maxVelocity = 5; + this.minAngularVelocity = 0.01; + this.maxAngularVelocity = 0.03; + baton = virtualBaton({ + batonName: 'io.highfidelity.vesicles:' + entityId, // One winner for each entity + }); + stopUpdateAndReclaim(); + currentInterval = Script.setInterval(self.move, self.getTotalWait()) + } + + + this.getTotalWait = function() { + return (Math.random() * 5000) * 2; + // var avatars = AvatarList.getAvatarIdentifiers(); + // var avatarCount = avatars.length; + // var random = Math.random() * 5000; + // var totalWait = random * (avatarCount * 2); + // print('cellscience color avatarcount, totalwait: ', avatarCount, totalWait) + // return totalWait + } + + + this.move = function() { + if (!iOwn) { + return; + } + + var magnitudeV = self.maxVelocity; + var directionV = { + x: Math.random() - 0.5, + y: Math.random() - 0.5, + z: Math.random() - 0.5 + }; + + //print("POS magnitude is " + magnitudeV + " and direction is " + directionV.x); + + var magnitudeAV = self.maxAngularVelocity; + + var directionAV = { + x: Math.random() - 0.5, + y: Math.random() - 0.5, + z: Math.random() - 0.5 + }; + //print("ROT magnitude is " + magnitudeAV + " and direction is " + directionAV.x); + Entities.editEntity(self.entityId, { + velocity: Vec3.multiply(magnitudeV, Vec3.normalize(directionV)), + angularVelocity: Vec3.multiply(magnitudeAV, Vec3.normalize(directionAV)) + + }); + + + } + + + this.unload = function() { + baton.release(function() {}); + Script.clearInterval(currentInterval); + } + + + +}) \ No newline at end of file diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/virtualBaton.js b/unpublishedScripts/DomainContent/CellScience/Scripts/virtualBaton.js new file mode 100644 index 0000000000..63f96a5c1e --- /dev/null +++ b/unpublishedScripts/DomainContent/CellScience/Scripts/virtualBaton.js @@ -0,0 +1,381 @@ +"use strict"; +/*jslint nomen: true, plusplus: true, vars: true */ +/*global Messages, Script, MyAvatar, AvatarList, Entities, print */ + +// Created by Howard Stearns +// Copyright 2016 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 +// +// Allows cooperating scripts to pass a "virtual baton" between them, +// which is useful when part of a script should only be executed by +// the one participant that is holding this particular baton. +// +// A virtual baton is simply any string agreed upon by the scripts +// that use it. Only one script at a time can hold the baton, and it +// holds it until that script releases it, or the other scripts +// determine that the holding script is not responding. The script +// automatically determines who among claimants has the baton, if anyone, +// and holds an "election" if necessary. +// +// See entityScript/tribble.js as an example, and the functions +// virtualBaton(), claim(), release(). +// + +// Answers a new virtualBaton for the given parameters, of which 'key' +// is required. +function virtualBatonf(options) { + // Answer averages (number +/- variability). Avoids having everyone act in lockstep. + function randomize(number, variability) { + var allowedDeviation = number * variability; // one side of the deviation range + var allowedDeviationRange = allowedDeviation * 2; // total range for +/- deviation + var randomDeviation = Math.random() * allowedDeviationRange; + var result = number - allowedDeviation + randomDeviation; + return result; + } + // Allow testing outside in a harness outside of High Fidelity. + // See sourceCodeSandbox/tests/mocha/test/testVirtualBaton.js + var globals = options.globals || {}, + messages = globals.Messages || Messages, + myAvatar = globals.MyAvatar || MyAvatar, + avatarList = globals.AvatarList || AvatarList, + entities = globals.Entities || Entities, + timers = globals.Script || Script, + log = globals.print || print; + + var batonName = options.batonName, // The identify of the baton. + // instanceId is the identify of this particular copy of the script among all copies using the same batonName + // in the domain. For example, if you wanted only one entity among multiple entity scripts to hold the baton, + // you could specify virtualBaton({batonName: 'someBatonName', instanceId: MyAvatar.sessionUUID + entityID}). + instanceId = options.instanceId || myAvatar.sessionUUID, + // virtualBaton() returns the exports object with properties. You can pass in an object to be side-effected. + exports = options.exports || {}, + // Handy to set false if we believe the optimizations are wrong, or to use both values in a test harness. + useOptimizations = (options.useOptimizations === undefined) ? true : options.useOptimizations, + electionTimeout = options.electionTimeout || randomize(500, 0.2), // ms. If no winner in this time, hold a new election. + recheckInterval = options.recheckInterval || randomize(500, 0.2), // ms. Check that winners remain connected. + // If you supply your own instanceId, you might also supply a connectionTest that answers + // truthy iff the given id is still valid and connected, and is run at recheckInterval. You + // can use exports.validId (see below), and the default answers truthy if id is valid or a + // concatenation of two valid ids. (This handles the most common cases of instanceId being + // either (the default) MyAvatar.sessionUUID, an entityID, or the concatenation (in either + // order) of both.) + connectionTest = options.connectionTest || function connectionTest(id) { + var idLength = 38; + if (id.length === idLength) { + return exports.validId(id); + } + return (id.length === 2 * idLength) && exports.validId(id.slice(0, idLength)) && exports.validId(id.slice(idLength)); + }; + + if (!batonName) { + throw new Error("A virtualBaton must specify a batonName."); + } + // Truthy if id exists as either a connected avatar or valid entity. + exports.validId = function validId(id) { + var avatar = avatarList.getAvatar(id); + if (avatar && (avatar.sessionUUID === id)) { + return true; + } + var properties = entities.getEntityProperties(id, ['type']); + return properties && properties.type; + }; + + // Various logging, controllable through options. + function debug() { // Display the arguments not just [Object object]. + log.apply(null, [].map.call(arguments, JSON.stringify)); + } + function debugFlow() { + if (options.debugFlow) { + debug.apply(null, arguments); + } + } + function debugSend(destination, operation, data) { + if (options.debugSend) { + debug('baton:', batonName, instanceId, 's=>', destination, operation, data); + } + } + function debugReceive(senderID, operation, data) { // senderID is client sessionUUID -- not necessarily instanceID! + if (options.debugReceive) { + debug('baton:', batonName, senderID, '=>r', instanceId, operation, data); + } + } + + // Messages: Just synactic sugar for hooking things up to Messages system. + // We create separate subchannel strings for each operation within our general channelKey, instead of using + // a switch in the receiver. + var channelKey = "io.highfidelity.virtualBaton:" + batonName, + subchannelHandlers = {}, // Message channel string => {receiver, op} + subchannelKeys = {}; // operation => Message channel string + function subchannelKey(operation) { + return channelKey + ':' + operation; + } + function receive(operation, handler) { // Record a handler for an operation on our channelKey + var subKey = subchannelKey(operation); + subchannelHandlers[subKey] = {receiver: handler, op: operation}; + subchannelKeys[operation] = subKey; + messages.subscribe(subKey); + } + function sendHelper(subchannel, data) { + var message = JSON.stringify(data); + messages.sendMessage(subchannel, message); + } + function send1(operation, destination, data) { // Send data for an operation to just one destination on our channelKey. + debugSend(destination, operation, data); + sendHelper(subchannelKey(operation) + destination, data); + } + function send(operation, data) { // Send data for an operation on our channelKey. + debugSend('-', operation, data); + sendHelper(subchannelKeys[operation], data); + } + function messageHandler(channel, messageString, senderID) { + var handler = subchannelHandlers[channel]; + if (!handler) { + return; + } + var data = JSON.parse(messageString); + debugReceive(senderID, handler.op, data); + handler.receiver(data); + } + messages.messageReceived.connect(messageHandler); + + var nPromises = 0, nAccepted = 0, electionWatchdog; + + // It would be great if we had a way to know how many subscribers our channel has. Failing that... + var nNack = 0, previousNSubscribers = 0, lastGathering = 0, thisTimeout = electionTimeout; + function nSubscribers() { // Answer the number of subscribers. + // To find nQuorum, we need to know how many scripts are being run using this batonName, which isn't + // the same as the number of clients! + // + // If we overestimate by too much, we may fail to reach consensus, which triggers a new + // election proposal, so we take the number of acceptors to be the max(nPromises, nAccepted) + // + nNack reported in the previous round. + // + // If we understimate by too much, there can be different pockets on the Internet that each + // believe they have agreement on different holders of the baton, which is precisely what + // the virtualBaton is supposed to avoid. Therefore we need to allow 'nack' to gather stragglers. + + var now = Date.now(), elapsed = now - lastGathering; + if (elapsed >= thisTimeout) { + previousNSubscribers = Math.max(nPromises, nAccepted) + nNack; + lastGathering = now; + } // ...otherwise we use the previous value unchanged. + + // On startup, we do one proposal that we cannot possibly close, so that we'll + // lock things up for the full electionTimeout to gather responses. + if (!previousNSubscribers) { + var LARGE_INTEGER = Number.MAX_SAFE_INTEGER || (-1 >>> 1); // QT doesn't define the ECMA constant. Max int will do for our purposes. + previousNSubscribers = LARGE_INTEGER; + } + return previousNSubscribers; + } + + // MAIN ALGORITHM + // + // Internally, this uses the Paxos algorith to hold elections. + // Alternatively, we could have the message server pick and maintain a winner, but it would + // still have to deal with the same issues of verification in the presence of lost/delayed/reordered messages. + // Paxos is known to be optimal under these circumstances, except that its best to have a dedicated proposer + // (such as the server). + function betterNumber(number, best) { + return (number.number || 0) > best.number; + } + // Paxos Proposer behavior + var proposalNumber = 0, + nQuorum = 0, + bestPromise = {number: 0}, + claimCallback, + releaseCallback; + function propose() { // Make a new proposal, so that we learn/update the proposalNumber and winner. + // Even though we send back a 'nack' if the proposal is obsolete, with network errors + // there's no way to know for certain that we've failed. The electionWatchdog will try a new + // proposal if we have not been accepted by a quorum after election Timeout. + if (electionWatchdog) { + // If we had a means of determining nSubscribers other than by counting, we could just + // timers.clearTimeout(electionWatchdog) and not return. + return; + } + thisTimeout = randomize(electionTimeout, 0.5); // Note use in nSubcribers. + electionWatchdog = timers.setTimeout(function () { + electionWatchdog = null; + propose(); + }, thisTimeout); + var nAcceptors = nSubscribers(); + nQuorum = Math.floor(nAcceptors / 2) + 1; + + proposalNumber = Math.max(proposalNumber, bestPromise.number) + 1; + debugFlow('baton:', batonName, instanceId, 'propose', proposalNumber, + 'claim:', !!claimCallback, 'nAcceptors:', nAcceptors, nPromises, nAccepted, nNack); + nPromises = nAccepted = nNack = 0; + send('prepare!', {number: proposalNumber, proposerId: instanceId}); + } + // We create a distinguished promise subchannel for our id, because promises need only be sent to the proposer. + receive('promise' + instanceId, function (data) { + if (betterNumber(data, bestPromise)) { + bestPromise = data; + } + if ((data.proposalNumber === proposalNumber) && (++nPromises >= nQuorum)) { // Note check for not being a previous round + var answer = {number: data.proposalNumber, proposerId: data.proposerId, winner: bestPromise.winner}; // Not data.number. + if (!answer.winner || (answer.winner === instanceId)) { // We get to pick. + answer.winner = claimCallback ? instanceId : null; + } + send('accept!', answer); + } + }); + receive('nack' + instanceId, function (data) { // An acceptor reports more recent data... + if (data.proposalNumber === proposalNumber) { + nNack++; // For updating nQuorum. + // IWBNI if we started our next proposal right now/here, but we need a decent nNack count. + // Lets save that optimization for another day... + } + }); + // Paxos Acceptor behavior + var bestProposal = {number: 0}, accepted = {}; + function acceptedId() { + return accepted && accepted.winner; + } + receive('prepare!', function (data) { + var response = {proposalNumber: data.number, proposerId: data.proposerId}; + if (betterNumber(data, bestProposal)) { + bestProposal = data; + if (accepted.winner && connectionTest(accepted.winner)) { + response.number = accepted.number; + response.winner = accepted.winner; + } + send1('promise', data.proposerId, response); + } else { + send1('nack', data.proposerId, response); + } + }); + receive('accept!', function (data) { + if (!betterNumber(bestProposal, data)) { + bestProposal = accepted = data; // Update both with current data. Might have missed the proposal earlier. + if (useOptimizations) { + // The Paxos literature describes every acceptor sending 'accepted' to + // every proposer and learner. In our case, these are the same nodes that received + // the 'accept!' message, so we can send to just the originating proposer and invoke + // our own accepted handler directly. + // Note that this optimization cannot be used with Byzantine Paxos (which needs another + // multi-broadcast to detect lying and collusion). + debugSend('/', 'accepted', data); + debugReceive(instanceId, 'accepted', data); // direct on next line, which doesn't get logging. + subchannelHandlers[subchannelKey('accepted') + instanceId].receiver(data); + if (data.proposerId !== instanceId) { // i.e., we didn't already do it directly on the line above. + send1('accepted', data.proposerId, data); + } + } else { + send('accepted', data); + } + } else { + send1('nack', data.proposerId, {proposalNumber: data.number}); + } + }); + // Paxos Learner behavior. + function localRelease() { + var callback = releaseCallback; + debugFlow('baton:', batonName, 'localRelease', 'callback:', !!releaseCallback); + if (!releaseCallback) { + return; + } // Already released, but we might still receive a stale message. That's ok. + releaseCallback = undefined; + callback(batonName); // Pass batonName so that clients may use the same handler for different batons. + } + receive('accepted' + (useOptimizations ? instanceId : ''), function (data) { // See note in 'accept!' regarding use of instanceId here. + if (betterNumber(accepted, data)) { // Especially when !useOptimizations, we can receive other acceptances late. + return; + } + var oldAccepted = accepted; + debugFlow('baton:', batonName, instanceId, 'accepted', data.number, data.winner); + accepted = data; + // If we are proposer, make sure we get a quorum of acceptances. + if ((data.proposerId === instanceId) && (data.number === proposalNumber) && (++nAccepted >= nQuorum)) { + if (electionWatchdog) { + timers.clearTimeout(electionWatchdog); + electionWatchdog = null; + } + } + // If we are the winner -- regardless of whether we were the proposer. + if (acceptedId() === instanceId) { + if (claimCallback) { + var callback = claimCallback; + claimCallback = undefined; + callback(batonName); + } else if (!releaseCallback) { // We won, but have been released and are no longer interested. + // Propose that someone else take the job. + timers.setTimeout(propose, 0); // Asynchronous to queue message handling if some are synchronous and others not. + } + } else if (releaseCallback && (oldAccepted.winner === instanceId)) { // We've been released by someone else! + localRelease(); // This can happen if enough people thought we'd disconnected. + } + }); + + // Public Interface + // + // Registers an intent to hold the baton: + // Calls onElection(batonName) once, if you are elected by the scripts + // to be the unique holder of the baton, which may be never. + // Calls onRelease(batonName) once, if the baton held by you is released, + // whether this is by you calling release(), or by losing + // an election when you become disconnected. + // You may claim again at any time after the start of onRelease + // being called. + exports.claim = function claim(onElection, onRelease) { + debugFlow('baton:', batonName, instanceId, 'claim'); + if (claimCallback) { + log("Ignoring attempt to claim virtualBaton " + batonName + ", which is already waiting for claim."); + return; + } + if (releaseCallback) { + log("Ignoring attempt to claim virtualBaton " + batonName + ", which is somehow incorrect released, and that should not happen."); + return; + } + claimCallback = onElection; + releaseCallback = onRelease; + propose(); + return exports; // Allows chaining. e.g., var baton = virtualBaton({batonName: 'foo'}.claim(onClaim, onRelease); + }; + // Release the baton you hold, or just log that you are not holding it. + exports.release = function release(optionalReplacementOnRelease) { + debugFlow('baton:', batonName, instanceId, 'release'); + if (optionalReplacementOnRelease) { // If you want to change. + releaseCallback = optionalReplacementOnRelease; + } + if (acceptedId() !== instanceId) { + log("Ignoring attempt to release virtualBaton " + batonName + ", which is not being held."); + return; + } + localRelease(); + if (!claimCallback) { // No claim set in release callback. + propose(); + } + return exports; + }; + exports.recheckWatchdog = timers.setInterval(function recheck() { + var holder = acceptedId(); // If we're waiting and we notice the holder is gone, ... + if (holder && claimCallback && !electionWatchdog && !connectionTest(holder)) { + bestPromise.winner = null; // used if the quorum agrees that old winner is not there + propose(); // ... propose an election. + } + }, recheckInterval); + exports.unload = function unload() { // Disconnect from everything. + messages.messageReceived.disconnect(messageHandler); + timers.clearInterval(exports.recheckWatchdog); + if (electionWatchdog) { + timers.clearTimeout(electionWatchdog); + } + electionWatchdog = claimCallback = releaseCallback = null; + Object.keys(subchannelHandlers).forEach(messages.unsubscribe); + debugFlow('baton:', batonName, instanceId, 'unload'); + return exports; + }; + + // Gather nAcceptors by making two proposals with some gathering time, even without a claim. + propose(); + return exports; +} +if (typeof module !== 'undefined') { // Allow testing in nodejs. + module.exports = virtualBatonf; +} else { + virtualBaton = virtualBatonf; +} diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/zoomAndMoveRandomly.js b/unpublishedScripts/DomainContent/CellScience/Scripts/zoomAndMoveRandomly.js index e4ee59cb6b..16c83b29dd 100644 --- a/unpublishedScripts/DomainContent/CellScience/Scripts/zoomAndMoveRandomly.js +++ b/unpublishedScripts/DomainContent/CellScience/Scripts/zoomAndMoveRandomly.js @@ -9,19 +9,42 @@ var teleport; var portalDestination; var animationURL; - var self = this; this.entered = true; + Script.include('virtualBaton.js'); + + var self = this; + var baton; + var iOwn = false; + var currentInterval; + var _entityId; + + function startUpdate() { + iOwn = true; + print('i am the owner ' + _entityId) + } + + function stopUpdateAndReclaim() { + print('i released the object ' + _entityId) + iOwn = false; + baton.claim(startUpdate, stopUpdateAndReclaim); + } this.preload = function(entityID) { this.entityId = entityID; + _entityId = entityID; this.initialize(entityID); this.initTimeout = null; this.minVelocity = 1; this.maxVelocity = 5; this.minAngularVelocity = 0.01; this.maxAngularVelocity = 0.03; - Script.setTimeout(self.move, self.getTotalWait()) + baton = virtualBaton({ + batonName: 'io.highfidelity.vesicles:' + entityId, // One winner for each entity + }); + stopUpdateAndReclaim(); + currentInterval = Script.setInterval(self.move, self.getTotalWait()) + } this.initialize = function(entityID) { @@ -104,6 +127,8 @@ if (this.initTimeout !== null) { Script.clearTimeout(this.initTimeout); } + baton.release(function() {}); + Script.clearInterval(currentInterval); } this.hoverEnterEntity = function(entityID) { @@ -114,16 +139,13 @@ } this.getTotalWait = function() { - var avatars = AvatarList.getAvatarIdentifiers(); - var avatarCount = avatars.length; - var random = Math.random() * 2000; - var totalWait = random * (avatarCount * 2); - - return totalWait + return (Math.random() * 5000) * 2; } - this.move = function() { + if (!iOwn) { + return; + } var magnitudeV = self.maxVelocity; var directionV = { @@ -133,11 +155,6 @@ }; //print("POS magnitude is " + magnitudeV + " and direction is " + directionV.x); - Entities.editEntity(self.entityId, { - velocity: Vec3.multiply(magnitudeV, Vec3.normalize(directionV)) - }); - - var magnitudeAV = self.maxAngularVelocity; @@ -148,11 +165,12 @@ }; //print("ROT magnitude is " + magnitudeAV + " and direction is " + directionAV.x); Entities.editEntity(self.entityId, { + velocity: Vec3.multiply(magnitudeV, Vec3.normalize(directionV)), angularVelocity: Vec3.multiply(magnitudeAV, Vec3.normalize(directionAV)) }); - Script.setTimeout(self.move, self.getTotalWait()) + } }) \ No newline at end of file diff --git a/unpublishedScripts/DomainContent/CellScience/importCellScience.js b/unpublishedScripts/DomainContent/CellScience/importCellScience.js index db50635f93..63f99c53a3 100644 --- a/unpublishedScripts/DomainContent/CellScience/importCellScience.js +++ b/unpublishedScripts/DomainContent/CellScience/importCellScience.js @@ -5,7 +5,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -var version = 1043; +var version = 1049; var cellLayout; var baseLocation = "https://hifi-content.s3.amazonaws.com/DomainContent/CellScience/"; @@ -194,7 +194,7 @@ var scenes = [{ grabbable: false } }), - script: "moveRandomly.js?" + version, + script: "moveRandomly2.js?" + version, visible: true }, { //golgi vesicles model: "vesicle", @@ -238,7 +238,7 @@ var scenes = [{ grabbable: false } }), - script: "moveRandomly.js?" + version, + script: "moveRandomly2.js?" + version, visible: true }, { model: "vesicle", @@ -304,7 +304,7 @@ var scenes = [{ grabbable: false } }), - script: "moveRandomly.js?" + version, + script: "moveRandomly2.js?" + version, visible: true }, { //outer vesicles model: "vesicle", @@ -326,7 +326,7 @@ var scenes = [{ grabbable: false } }), - script: "moveRandomly.js?" + version, + script: "moveRandomly2.js?" + version, visible: true }, // {//wigglies From f0d8ffce6582fc63e6adf9486a10c1d511f94250 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 22 Feb 2016 10:25:56 -0800 Subject: [PATCH 05/19] cleanup errors --- .../DomainContent/CellScience/Scripts/moveRandomly2.js | 10 +++------- .../CellScience/Scripts/zoomAndMoveRandomly.js | 7 +++++-- .../DomainContent/CellScience/importCellScience.js | 2 +- 3 files changed, 9 insertions(+), 10 deletions(-) diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/moveRandomly2.js b/unpublishedScripts/DomainContent/CellScience/Scripts/moveRandomly2.js index f720ca91cc..ec7b249db0 100644 --- a/unpublishedScripts/DomainContent/CellScience/Scripts/moveRandomly2.js +++ b/unpublishedScripts/DomainContent/CellScience/Scripts/moveRandomly2.js @@ -44,12 +44,6 @@ this.getTotalWait = function() { return (Math.random() * 5000) * 2; - // var avatars = AvatarList.getAvatarIdentifiers(); - // var avatarCount = avatars.length; - // var random = Math.random() * 5000; - // var totalWait = random * (avatarCount * 2); - // print('cellscience color avatarcount, totalwait: ', avatarCount, totalWait) - // return totalWait } @@ -86,7 +80,9 @@ this.unload = function() { - baton.release(function() {}); + if (baton) { + baton.release(function() {}); + } Script.clearInterval(currentInterval); } diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/zoomAndMoveRandomly.js b/unpublishedScripts/DomainContent/CellScience/Scripts/zoomAndMoveRandomly.js index 16c83b29dd..21e585cd91 100644 --- a/unpublishedScripts/DomainContent/CellScience/Scripts/zoomAndMoveRandomly.js +++ b/unpublishedScripts/DomainContent/CellScience/Scripts/zoomAndMoveRandomly.js @@ -40,7 +40,7 @@ this.minAngularVelocity = 0.01; this.maxAngularVelocity = 0.03; baton = virtualBaton({ - batonName: 'io.highfidelity.vesicles:' + entityId, // One winner for each entity + batonName: 'io.highfidelity.vesicles:' + entityID, // One winner for each entity }); stopUpdateAndReclaim(); currentInterval = Script.setInterval(self.move, self.getTotalWait()) @@ -127,7 +127,10 @@ if (this.initTimeout !== null) { Script.clearTimeout(this.initTimeout); } - baton.release(function() {}); + if (baton) { + baton.release(function() {}); + } + Script.clearInterval(currentInterval); } diff --git a/unpublishedScripts/DomainContent/CellScience/importCellScience.js b/unpublishedScripts/DomainContent/CellScience/importCellScience.js index 63f99c53a3..900a54d9e3 100644 --- a/unpublishedScripts/DomainContent/CellScience/importCellScience.js +++ b/unpublishedScripts/DomainContent/CellScience/importCellScience.js @@ -5,7 +5,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -var version = 1049; +var version = 1051; var cellLayout; var baseLocation = "https://hifi-content.s3.amazonaws.com/DomainContent/CellScience/"; From f7b3da078b2ec28209118bbd60ccd5ba2e41cb4a Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 22 Feb 2016 11:36:53 -0800 Subject: [PATCH 06/19] dont move cells in space, just angular velocity --- .../CellScience/Scripts/zoomAndMoveRandomly.js | 14 +++++++------- .../DomainContent/CellScience/importCellScience.js | 2 +- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/zoomAndMoveRandomly.js b/unpublishedScripts/DomainContent/CellScience/Scripts/zoomAndMoveRandomly.js index 21e585cd91..bf249a4644 100644 --- a/unpublishedScripts/DomainContent/CellScience/Scripts/zoomAndMoveRandomly.js +++ b/unpublishedScripts/DomainContent/CellScience/Scripts/zoomAndMoveRandomly.js @@ -150,12 +150,12 @@ return; } - var magnitudeV = self.maxVelocity; - var directionV = { - x: Math.random() - 0.5, - y: Math.random() - 0.5, - z: Math.random() - 0.5 - }; + // var magnitudeV = self.maxVelocity; + // var directionV = { + // x: Math.random() - 0.5, + // y: Math.random() - 0.5, + // z: Math.random() - 0.5 + // }; //print("POS magnitude is " + magnitudeV + " and direction is " + directionV.x); @@ -168,7 +168,7 @@ }; //print("ROT magnitude is " + magnitudeAV + " and direction is " + directionAV.x); Entities.editEntity(self.entityId, { - velocity: Vec3.multiply(magnitudeV, Vec3.normalize(directionV)), + // velocity: Vec3.multiply(magnitudeV, Vec3.normalize(directionV)), angularVelocity: Vec3.multiply(magnitudeAV, Vec3.normalize(directionAV)) }); diff --git a/unpublishedScripts/DomainContent/CellScience/importCellScience.js b/unpublishedScripts/DomainContent/CellScience/importCellScience.js index 900a54d9e3..b061dc6931 100644 --- a/unpublishedScripts/DomainContent/CellScience/importCellScience.js +++ b/unpublishedScripts/DomainContent/CellScience/importCellScience.js @@ -5,7 +5,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -var version = 1051; +var version = 1052; var cellLayout; var baseLocation = "https://hifi-content.s3.amazonaws.com/DomainContent/CellScience/"; From e4bc0ce69103ccdd950793255384f9a6b3719a66 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 22 Feb 2016 13:08:58 -0800 Subject: [PATCH 07/19] tests --- .../DomainContent/CellScience/Scripts/zoom.js | 12 ---------- .../Scripts/zoomAndMoveRandomly.js | 23 +++++++------------ .../CellScience/importCellScience.js | 2 +- 3 files changed, 9 insertions(+), 28 deletions(-) diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/zoom.js b/unpublishedScripts/DomainContent/CellScience/Scripts/zoom.js index da41ec64ba..3fc5acae2a 100644 --- a/unpublishedScripts/DomainContent/CellScience/Scripts/zoom.js +++ b/unpublishedScripts/DomainContent/CellScience/Scripts/zoom.js @@ -52,13 +52,7 @@ print("Teleporting to (" + data.location.x + ", " + data.location.y + ", " + data.location.z + ")"); MyAvatar.position = data.location; - - // if (data.hasOwnProperty('entryPoint') && data.hasOwnProperty('target')) { - // this.lookAtTarget(data.entryPoint, data.target); - // } - // else{ - // } } } @@ -103,10 +97,4 @@ } } - this.hoverEnterEntity = function(entityID) { - Entities.editEntity(entityID, { - animationURL: animationURL, - animationSettings: '{ "fps": 24, "firstFrame": 1, "lastFrame": 25, "frameIndex": 1, "running": true, "hold": true }' - }); - } }) \ No newline at end of file diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/zoomAndMoveRandomly.js b/unpublishedScripts/DomainContent/CellScience/Scripts/zoomAndMoveRandomly.js index bf249a4644..703c4ead33 100644 --- a/unpublishedScripts/DomainContent/CellScience/Scripts/zoomAndMoveRandomly.js +++ b/unpublishedScripts/DomainContent/CellScience/Scripts/zoomAndMoveRandomly.js @@ -15,18 +15,19 @@ var self = this; var baton; - var iOwn = false; + + this.iOwn = false; var currentInterval; var _entityId; function startUpdate() { - iOwn = true; + self.iOwn = true; print('i am the owner ' + _entityId) } function stopUpdateAndReclaim() { print('i released the object ' + _entityId) - iOwn = false; + self.iOwn = false; baton.claim(startUpdate, stopUpdateAndReclaim); } @@ -40,7 +41,7 @@ this.minAngularVelocity = 0.01; this.maxAngularVelocity = 0.03; baton = virtualBaton({ - batonName: 'io.highfidelity.vesicles:' + entityID, // One winner for each entity + batonName: 'io.highfidelity.cells:' + entityID, // One winner for each entity }); stopUpdateAndReclaim(); currentInterval = Script.setInterval(self.move, self.getTotalWait()) @@ -146,19 +147,11 @@ } this.move = function() { - if (!iOwn) { + if (self.iOwn===false) { + print('cell is not owned by me...') return; } - // var magnitudeV = self.maxVelocity; - // var directionV = { - // x: Math.random() - 0.5, - // y: Math.random() - 0.5, - // z: Math.random() - 0.5 - // }; - - //print("POS magnitude is " + magnitudeV + " and direction is " + directionV.x); - var magnitudeAV = self.maxAngularVelocity; var directionAV = { @@ -166,7 +159,7 @@ y: Math.random() - 0.5, z: Math.random() - 0.5 }; - //print("ROT magnitude is " + magnitudeAV + " and direction is " + directionAV.x); + print("ROT magnitude is " + magnitudeAV + " and direction is " + directionAV.x); Entities.editEntity(self.entityId, { // velocity: Vec3.multiply(magnitudeV, Vec3.normalize(directionV)), angularVelocity: Vec3.multiply(magnitudeAV, Vec3.normalize(directionAV)) diff --git a/unpublishedScripts/DomainContent/CellScience/importCellScience.js b/unpublishedScripts/DomainContent/CellScience/importCellScience.js index b061dc6931..4ae5e5de36 100644 --- a/unpublishedScripts/DomainContent/CellScience/importCellScience.js +++ b/unpublishedScripts/DomainContent/CellScience/importCellScience.js @@ -5,7 +5,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -var version = 1052; +var version = 1055; var cellLayout; var baseLocation = "https://hifi-content.s3.amazonaws.com/DomainContent/CellScience/"; From 46aebabd9b2330567dc89feca3f57a1ed42a0e66 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Mon, 22 Feb 2016 17:54:45 -0800 Subject: [PATCH 08/19] switch branches --- .../Scripts/zoomAndMoveRandomly.js | 20 ++++++------------- .../CellScience/importCellScience.js | 10 +++++----- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/zoomAndMoveRandomly.js b/unpublishedScripts/DomainContent/CellScience/Scripts/zoomAndMoveRandomly.js index 703c4ead33..dd6a48c617 100644 --- a/unpublishedScripts/DomainContent/CellScience/Scripts/zoomAndMoveRandomly.js +++ b/unpublishedScripts/DomainContent/CellScience/Scripts/zoomAndMoveRandomly.js @@ -38,8 +38,8 @@ this.initTimeout = null; this.minVelocity = 1; this.maxVelocity = 5; - this.minAngularVelocity = 0.01; - this.maxAngularVelocity = 0.03; + this.minAngularVelocity = 0.03; + this.maxAngularVelocity = 0.10; baton = virtualBaton({ batonName: 'io.highfidelity.cells:' + entityID, // One winner for each entity }); @@ -69,7 +69,7 @@ }; self.teleportSound = SoundCache.getSound("https://hifi-content.s3.amazonaws.com/DomainContent/CellScience/Audio/whoosh.wav"); - // print(" portal destination is " + self.portalDestination); + } } @@ -81,13 +81,6 @@ print("Teleporting to (" + data.location.x + ", " + data.location.y + ", " + data.location.z + ")"); MyAvatar.position = data.location; - - // if (data.hasOwnProperty('entryPoint') && data.hasOwnProperty('target')) { - // this.lookAtTarget(data.entryPoint, data.target); - // } - // else{ - - // } } } @@ -143,11 +136,11 @@ } this.getTotalWait = function() { - return (Math.random() * 5000) * 2; + return (Math.random() * 5000) * 3; } this.move = function() { - if (self.iOwn===false) { + if (self.iOwn === false) { print('cell is not owned by me...') return; } @@ -159,9 +152,8 @@ y: Math.random() - 0.5, z: Math.random() - 0.5 }; - print("ROT magnitude is " + magnitudeAV + " and direction is " + directionAV.x); + // print("ROT magnitude is " + magnitudeAV + " and direction is " + directionAV.x); Entities.editEntity(self.entityId, { - // velocity: Vec3.multiply(magnitudeV, Vec3.normalize(directionV)), angularVelocity: Vec3.multiply(magnitudeAV, Vec3.normalize(directionAV)) }); diff --git a/unpublishedScripts/DomainContent/CellScience/importCellScience.js b/unpublishedScripts/DomainContent/CellScience/importCellScience.js index 4ae5e5de36..25323495d1 100644 --- a/unpublishedScripts/DomainContent/CellScience/importCellScience.js +++ b/unpublishedScripts/DomainContent/CellScience/importCellScience.js @@ -5,7 +5,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -var version = 1055; +var version = 1057; var cellLayout; var baseLocation = "https://hifi-content.s3.amazonaws.com/DomainContent/CellScience/"; @@ -103,16 +103,16 @@ var scenes = [{ instances: [{ model: "Cell", dimensions: { - x: 550, - y: 620, - z: 550 + x: 500, + y: 570, + z: 500 }, offset: { x: 0, y: 0, z: 0 }, - radius: 500, + radius: 450, number: 10, userData: JSON.stringify({ entryPoint: locations.cellLayout[1], From 6fd149f22dbc63075243af6f42ba93c4a4ccf3d2 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Tue, 23 Feb 2016 12:27:05 -0800 Subject: [PATCH 09/19] no avatar --- .../DomainContent/CellScience/motorProteinControllerAC.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/unpublishedScripts/DomainContent/CellScience/motorProteinControllerAC.js b/unpublishedScripts/DomainContent/CellScience/motorProteinControllerAC.js index 672ec1fd92..59577d49ba 100644 --- a/unpublishedScripts/DomainContent/CellScience/motorProteinControllerAC.js +++ b/unpublishedScripts/DomainContent/CellScience/motorProteinControllerAC.js @@ -18,8 +18,6 @@ if (USE_LOCAL_HOST === true) { var USE_LOCAL_HOST = false; -Agent.isAvatar = true; - EntityViewer.setPosition({ x: 3000, y: 13500, From 46fbf38b5d38e7e7a1a9447d1e9e805fdc477ea7 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Wed, 24 Feb 2016 12:36:18 -0800 Subject: [PATCH 10/19] ac movers --- .../CellScience/Scripts/colorRandomly.js | 104 ----- .../CellScience/Scripts/moveRandomly2.js | 91 ----- .../Scripts/showButtonToPlaySound.js | 4 - .../CellScience/Scripts/virtualBaton.js | 381 ------------------ .../Scripts/zoomAndMoveRandomly.js | 164 -------- .../CellScience/importCellScience.js | 43 +- .../DomainContent/CellScience/moveCellsAC.js | 96 +++++ .../CellScience/moveVesiclesAC.js | 106 +++++ 8 files changed, 212 insertions(+), 777 deletions(-) delete mode 100644 unpublishedScripts/DomainContent/CellScience/Scripts/colorRandomly.js delete mode 100644 unpublishedScripts/DomainContent/CellScience/Scripts/moveRandomly2.js delete mode 100644 unpublishedScripts/DomainContent/CellScience/Scripts/virtualBaton.js delete mode 100644 unpublishedScripts/DomainContent/CellScience/Scripts/zoomAndMoveRandomly.js create mode 100644 unpublishedScripts/DomainContent/CellScience/moveCellsAC.js create mode 100644 unpublishedScripts/DomainContent/CellScience/moveVesiclesAC.js diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/colorRandomly.js b/unpublishedScripts/DomainContent/CellScience/Scripts/colorRandomly.js deleted file mode 100644 index cf4ee810e7..0000000000 --- a/unpublishedScripts/DomainContent/CellScience/Scripts/colorRandomly.js +++ /dev/null @@ -1,104 +0,0 @@ -// Copyright 2016 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 -// -(function() { - - Script.include(Script.resolvePath('virtualBaton.js')); - - var self = this; - - var baton; - var iOwn = false; - var currentInterval; - var _entityId; - - function startUpdate() { - iOwn = true; - print('i am the owner ' + _entityId) - } - - function stopUpdateAndReclaim() { - print('i released the object ' + _entityId) - iOwn = false; - baton.claim(startUpdate, stopUpdateAndReclaim); - } - - this.preload = function(entityId) { - this.isConnected = false; - this.entityId = entityId; - _entityId = entityId; - this.minVelocity = 1; - this.maxVelocity = 5; - this.minAngularVelocity = 0.01; - this.maxAngularVelocity = 0.03; - baton = virtualBaton({ - batonName: 'io.highfidelity.vesicles:' + entityId, // One winner for each entity - }); - stopUpdateAndReclaim(); - currentInterval = Script.setInterval(self.move, self.getTotalWait()) - } - - - this.getTotalWait = function() { - return (Math.random() * 5000) * 2; - // var avatars = AvatarList.getAvatarIdentifiers(); - // var avatarCount = avatars.length; - // var random = Math.random() * 5000; - // var totalWait = random * (avatarCount * 2); - // print('cellscience color avatarcount, totalwait: ', avatarCount, totalWait) - // return totalWait - } - - - this.move = function() { - if (!iOwn) { - return; - } - - var properties = Entities.getEntityProperties(self.entityId); - var color = properties.color; - - var newColor; - var red = { - red: 255, - green: 0, - blue: 0 - } - var green = { - red: 0, - green: 255, - blue: 0 - } - var blue = { - red: 0, - green: 0, - blue: 255 - } - if (color.red > 0) { - newColor = green; - } - if (color.green > 0) { - newColor = blue; - } - if (color.blue > 0) { - newColor = red - } - Entities.editEntity(self.entityId, { - color: newColor - }); - - - } - - - this.unload = function() { - baton.release(function() {}); - Script.clearTimeout(currentInterval); - } - - - -}) \ No newline at end of file diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/moveRandomly2.js b/unpublishedScripts/DomainContent/CellScience/Scripts/moveRandomly2.js deleted file mode 100644 index ec7b249db0..0000000000 --- a/unpublishedScripts/DomainContent/CellScience/Scripts/moveRandomly2.js +++ /dev/null @@ -1,91 +0,0 @@ -// Copyright 2016 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 -// -(function() { - - Script.include('virtualBaton.js'); - - var self = this; - - var baton; - var iOwn = false; - var currentInterval; - var _entityId; - - function startUpdate() { - iOwn = true; - print('i am the owner ' + _entityId) - } - - function stopUpdateAndReclaim() { - print('i released the object ' + _entityId) - iOwn = false; - baton.claim(startUpdate, stopUpdateAndReclaim); - } - - this.preload = function(entityId) { - this.isConnected = false; - this.entityId = entityId; - _entityId = entityId; - this.minVelocity = 1; - this.maxVelocity = 5; - this.minAngularVelocity = 0.01; - this.maxAngularVelocity = 0.03; - baton = virtualBaton({ - batonName: 'io.highfidelity.vesicles:' + entityId, // One winner for each entity - }); - stopUpdateAndReclaim(); - currentInterval = Script.setInterval(self.move, self.getTotalWait()) - } - - - this.getTotalWait = function() { - return (Math.random() * 5000) * 2; - } - - - this.move = function() { - if (!iOwn) { - return; - } - - var magnitudeV = self.maxVelocity; - var directionV = { - x: Math.random() - 0.5, - y: Math.random() - 0.5, - z: Math.random() - 0.5 - }; - - //print("POS magnitude is " + magnitudeV + " and direction is " + directionV.x); - - var magnitudeAV = self.maxAngularVelocity; - - var directionAV = { - x: Math.random() - 0.5, - y: Math.random() - 0.5, - z: Math.random() - 0.5 - }; - //print("ROT magnitude is " + magnitudeAV + " and direction is " + directionAV.x); - Entities.editEntity(self.entityId, { - velocity: Vec3.multiply(magnitudeV, Vec3.normalize(directionV)), - angularVelocity: Vec3.multiply(magnitudeAV, Vec3.normalize(directionAV)) - - }); - - - } - - - this.unload = function() { - if (baton) { - baton.release(function() {}); - } - Script.clearInterval(currentInterval); - } - - - -}) \ No newline at end of file diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/showButtonToPlaySound.js b/unpublishedScripts/DomainContent/CellScience/Scripts/showButtonToPlaySound.js index 6651e435b4..8ee5e0092e 100644 --- a/unpublishedScripts/DomainContent/CellScience/Scripts/showButtonToPlaySound.js +++ b/unpublishedScripts/DomainContent/CellScience/Scripts/showButtonToPlaySound.js @@ -36,8 +36,6 @@ return; } - - self.addButton(); self.buttonShowing = false; self.showDistance = self.userData.showDistance; @@ -51,8 +49,6 @@ }; self.sound = SoundCache.getSound(this.soundURL); - - } this.addButton = function() { diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/virtualBaton.js b/unpublishedScripts/DomainContent/CellScience/Scripts/virtualBaton.js deleted file mode 100644 index 63f96a5c1e..0000000000 --- a/unpublishedScripts/DomainContent/CellScience/Scripts/virtualBaton.js +++ /dev/null @@ -1,381 +0,0 @@ -"use strict"; -/*jslint nomen: true, plusplus: true, vars: true */ -/*global Messages, Script, MyAvatar, AvatarList, Entities, print */ - -// Created by Howard Stearns -// Copyright 2016 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 -// -// Allows cooperating scripts to pass a "virtual baton" between them, -// which is useful when part of a script should only be executed by -// the one participant that is holding this particular baton. -// -// A virtual baton is simply any string agreed upon by the scripts -// that use it. Only one script at a time can hold the baton, and it -// holds it until that script releases it, or the other scripts -// determine that the holding script is not responding. The script -// automatically determines who among claimants has the baton, if anyone, -// and holds an "election" if necessary. -// -// See entityScript/tribble.js as an example, and the functions -// virtualBaton(), claim(), release(). -// - -// Answers a new virtualBaton for the given parameters, of which 'key' -// is required. -function virtualBatonf(options) { - // Answer averages (number +/- variability). Avoids having everyone act in lockstep. - function randomize(number, variability) { - var allowedDeviation = number * variability; // one side of the deviation range - var allowedDeviationRange = allowedDeviation * 2; // total range for +/- deviation - var randomDeviation = Math.random() * allowedDeviationRange; - var result = number - allowedDeviation + randomDeviation; - return result; - } - // Allow testing outside in a harness outside of High Fidelity. - // See sourceCodeSandbox/tests/mocha/test/testVirtualBaton.js - var globals = options.globals || {}, - messages = globals.Messages || Messages, - myAvatar = globals.MyAvatar || MyAvatar, - avatarList = globals.AvatarList || AvatarList, - entities = globals.Entities || Entities, - timers = globals.Script || Script, - log = globals.print || print; - - var batonName = options.batonName, // The identify of the baton. - // instanceId is the identify of this particular copy of the script among all copies using the same batonName - // in the domain. For example, if you wanted only one entity among multiple entity scripts to hold the baton, - // you could specify virtualBaton({batonName: 'someBatonName', instanceId: MyAvatar.sessionUUID + entityID}). - instanceId = options.instanceId || myAvatar.sessionUUID, - // virtualBaton() returns the exports object with properties. You can pass in an object to be side-effected. - exports = options.exports || {}, - // Handy to set false if we believe the optimizations are wrong, or to use both values in a test harness. - useOptimizations = (options.useOptimizations === undefined) ? true : options.useOptimizations, - electionTimeout = options.electionTimeout || randomize(500, 0.2), // ms. If no winner in this time, hold a new election. - recheckInterval = options.recheckInterval || randomize(500, 0.2), // ms. Check that winners remain connected. - // If you supply your own instanceId, you might also supply a connectionTest that answers - // truthy iff the given id is still valid and connected, and is run at recheckInterval. You - // can use exports.validId (see below), and the default answers truthy if id is valid or a - // concatenation of two valid ids. (This handles the most common cases of instanceId being - // either (the default) MyAvatar.sessionUUID, an entityID, or the concatenation (in either - // order) of both.) - connectionTest = options.connectionTest || function connectionTest(id) { - var idLength = 38; - if (id.length === idLength) { - return exports.validId(id); - } - return (id.length === 2 * idLength) && exports.validId(id.slice(0, idLength)) && exports.validId(id.slice(idLength)); - }; - - if (!batonName) { - throw new Error("A virtualBaton must specify a batonName."); - } - // Truthy if id exists as either a connected avatar or valid entity. - exports.validId = function validId(id) { - var avatar = avatarList.getAvatar(id); - if (avatar && (avatar.sessionUUID === id)) { - return true; - } - var properties = entities.getEntityProperties(id, ['type']); - return properties && properties.type; - }; - - // Various logging, controllable through options. - function debug() { // Display the arguments not just [Object object]. - log.apply(null, [].map.call(arguments, JSON.stringify)); - } - function debugFlow() { - if (options.debugFlow) { - debug.apply(null, arguments); - } - } - function debugSend(destination, operation, data) { - if (options.debugSend) { - debug('baton:', batonName, instanceId, 's=>', destination, operation, data); - } - } - function debugReceive(senderID, operation, data) { // senderID is client sessionUUID -- not necessarily instanceID! - if (options.debugReceive) { - debug('baton:', batonName, senderID, '=>r', instanceId, operation, data); - } - } - - // Messages: Just synactic sugar for hooking things up to Messages system. - // We create separate subchannel strings for each operation within our general channelKey, instead of using - // a switch in the receiver. - var channelKey = "io.highfidelity.virtualBaton:" + batonName, - subchannelHandlers = {}, // Message channel string => {receiver, op} - subchannelKeys = {}; // operation => Message channel string - function subchannelKey(operation) { - return channelKey + ':' + operation; - } - function receive(operation, handler) { // Record a handler for an operation on our channelKey - var subKey = subchannelKey(operation); - subchannelHandlers[subKey] = {receiver: handler, op: operation}; - subchannelKeys[operation] = subKey; - messages.subscribe(subKey); - } - function sendHelper(subchannel, data) { - var message = JSON.stringify(data); - messages.sendMessage(subchannel, message); - } - function send1(operation, destination, data) { // Send data for an operation to just one destination on our channelKey. - debugSend(destination, operation, data); - sendHelper(subchannelKey(operation) + destination, data); - } - function send(operation, data) { // Send data for an operation on our channelKey. - debugSend('-', operation, data); - sendHelper(subchannelKeys[operation], data); - } - function messageHandler(channel, messageString, senderID) { - var handler = subchannelHandlers[channel]; - if (!handler) { - return; - } - var data = JSON.parse(messageString); - debugReceive(senderID, handler.op, data); - handler.receiver(data); - } - messages.messageReceived.connect(messageHandler); - - var nPromises = 0, nAccepted = 0, electionWatchdog; - - // It would be great if we had a way to know how many subscribers our channel has. Failing that... - var nNack = 0, previousNSubscribers = 0, lastGathering = 0, thisTimeout = electionTimeout; - function nSubscribers() { // Answer the number of subscribers. - // To find nQuorum, we need to know how many scripts are being run using this batonName, which isn't - // the same as the number of clients! - // - // If we overestimate by too much, we may fail to reach consensus, which triggers a new - // election proposal, so we take the number of acceptors to be the max(nPromises, nAccepted) - // + nNack reported in the previous round. - // - // If we understimate by too much, there can be different pockets on the Internet that each - // believe they have agreement on different holders of the baton, which is precisely what - // the virtualBaton is supposed to avoid. Therefore we need to allow 'nack' to gather stragglers. - - var now = Date.now(), elapsed = now - lastGathering; - if (elapsed >= thisTimeout) { - previousNSubscribers = Math.max(nPromises, nAccepted) + nNack; - lastGathering = now; - } // ...otherwise we use the previous value unchanged. - - // On startup, we do one proposal that we cannot possibly close, so that we'll - // lock things up for the full electionTimeout to gather responses. - if (!previousNSubscribers) { - var LARGE_INTEGER = Number.MAX_SAFE_INTEGER || (-1 >>> 1); // QT doesn't define the ECMA constant. Max int will do for our purposes. - previousNSubscribers = LARGE_INTEGER; - } - return previousNSubscribers; - } - - // MAIN ALGORITHM - // - // Internally, this uses the Paxos algorith to hold elections. - // Alternatively, we could have the message server pick and maintain a winner, but it would - // still have to deal with the same issues of verification in the presence of lost/delayed/reordered messages. - // Paxos is known to be optimal under these circumstances, except that its best to have a dedicated proposer - // (such as the server). - function betterNumber(number, best) { - return (number.number || 0) > best.number; - } - // Paxos Proposer behavior - var proposalNumber = 0, - nQuorum = 0, - bestPromise = {number: 0}, - claimCallback, - releaseCallback; - function propose() { // Make a new proposal, so that we learn/update the proposalNumber and winner. - // Even though we send back a 'nack' if the proposal is obsolete, with network errors - // there's no way to know for certain that we've failed. The electionWatchdog will try a new - // proposal if we have not been accepted by a quorum after election Timeout. - if (electionWatchdog) { - // If we had a means of determining nSubscribers other than by counting, we could just - // timers.clearTimeout(electionWatchdog) and not return. - return; - } - thisTimeout = randomize(electionTimeout, 0.5); // Note use in nSubcribers. - electionWatchdog = timers.setTimeout(function () { - electionWatchdog = null; - propose(); - }, thisTimeout); - var nAcceptors = nSubscribers(); - nQuorum = Math.floor(nAcceptors / 2) + 1; - - proposalNumber = Math.max(proposalNumber, bestPromise.number) + 1; - debugFlow('baton:', batonName, instanceId, 'propose', proposalNumber, - 'claim:', !!claimCallback, 'nAcceptors:', nAcceptors, nPromises, nAccepted, nNack); - nPromises = nAccepted = nNack = 0; - send('prepare!', {number: proposalNumber, proposerId: instanceId}); - } - // We create a distinguished promise subchannel for our id, because promises need only be sent to the proposer. - receive('promise' + instanceId, function (data) { - if (betterNumber(data, bestPromise)) { - bestPromise = data; - } - if ((data.proposalNumber === proposalNumber) && (++nPromises >= nQuorum)) { // Note check for not being a previous round - var answer = {number: data.proposalNumber, proposerId: data.proposerId, winner: bestPromise.winner}; // Not data.number. - if (!answer.winner || (answer.winner === instanceId)) { // We get to pick. - answer.winner = claimCallback ? instanceId : null; - } - send('accept!', answer); - } - }); - receive('nack' + instanceId, function (data) { // An acceptor reports more recent data... - if (data.proposalNumber === proposalNumber) { - nNack++; // For updating nQuorum. - // IWBNI if we started our next proposal right now/here, but we need a decent nNack count. - // Lets save that optimization for another day... - } - }); - // Paxos Acceptor behavior - var bestProposal = {number: 0}, accepted = {}; - function acceptedId() { - return accepted && accepted.winner; - } - receive('prepare!', function (data) { - var response = {proposalNumber: data.number, proposerId: data.proposerId}; - if (betterNumber(data, bestProposal)) { - bestProposal = data; - if (accepted.winner && connectionTest(accepted.winner)) { - response.number = accepted.number; - response.winner = accepted.winner; - } - send1('promise', data.proposerId, response); - } else { - send1('nack', data.proposerId, response); - } - }); - receive('accept!', function (data) { - if (!betterNumber(bestProposal, data)) { - bestProposal = accepted = data; // Update both with current data. Might have missed the proposal earlier. - if (useOptimizations) { - // The Paxos literature describes every acceptor sending 'accepted' to - // every proposer and learner. In our case, these are the same nodes that received - // the 'accept!' message, so we can send to just the originating proposer and invoke - // our own accepted handler directly. - // Note that this optimization cannot be used with Byzantine Paxos (which needs another - // multi-broadcast to detect lying and collusion). - debugSend('/', 'accepted', data); - debugReceive(instanceId, 'accepted', data); // direct on next line, which doesn't get logging. - subchannelHandlers[subchannelKey('accepted') + instanceId].receiver(data); - if (data.proposerId !== instanceId) { // i.e., we didn't already do it directly on the line above. - send1('accepted', data.proposerId, data); - } - } else { - send('accepted', data); - } - } else { - send1('nack', data.proposerId, {proposalNumber: data.number}); - } - }); - // Paxos Learner behavior. - function localRelease() { - var callback = releaseCallback; - debugFlow('baton:', batonName, 'localRelease', 'callback:', !!releaseCallback); - if (!releaseCallback) { - return; - } // Already released, but we might still receive a stale message. That's ok. - releaseCallback = undefined; - callback(batonName); // Pass batonName so that clients may use the same handler for different batons. - } - receive('accepted' + (useOptimizations ? instanceId : ''), function (data) { // See note in 'accept!' regarding use of instanceId here. - if (betterNumber(accepted, data)) { // Especially when !useOptimizations, we can receive other acceptances late. - return; - } - var oldAccepted = accepted; - debugFlow('baton:', batonName, instanceId, 'accepted', data.number, data.winner); - accepted = data; - // If we are proposer, make sure we get a quorum of acceptances. - if ((data.proposerId === instanceId) && (data.number === proposalNumber) && (++nAccepted >= nQuorum)) { - if (electionWatchdog) { - timers.clearTimeout(electionWatchdog); - electionWatchdog = null; - } - } - // If we are the winner -- regardless of whether we were the proposer. - if (acceptedId() === instanceId) { - if (claimCallback) { - var callback = claimCallback; - claimCallback = undefined; - callback(batonName); - } else if (!releaseCallback) { // We won, but have been released and are no longer interested. - // Propose that someone else take the job. - timers.setTimeout(propose, 0); // Asynchronous to queue message handling if some are synchronous and others not. - } - } else if (releaseCallback && (oldAccepted.winner === instanceId)) { // We've been released by someone else! - localRelease(); // This can happen if enough people thought we'd disconnected. - } - }); - - // Public Interface - // - // Registers an intent to hold the baton: - // Calls onElection(batonName) once, if you are elected by the scripts - // to be the unique holder of the baton, which may be never. - // Calls onRelease(batonName) once, if the baton held by you is released, - // whether this is by you calling release(), or by losing - // an election when you become disconnected. - // You may claim again at any time after the start of onRelease - // being called. - exports.claim = function claim(onElection, onRelease) { - debugFlow('baton:', batonName, instanceId, 'claim'); - if (claimCallback) { - log("Ignoring attempt to claim virtualBaton " + batonName + ", which is already waiting for claim."); - return; - } - if (releaseCallback) { - log("Ignoring attempt to claim virtualBaton " + batonName + ", which is somehow incorrect released, and that should not happen."); - return; - } - claimCallback = onElection; - releaseCallback = onRelease; - propose(); - return exports; // Allows chaining. e.g., var baton = virtualBaton({batonName: 'foo'}.claim(onClaim, onRelease); - }; - // Release the baton you hold, or just log that you are not holding it. - exports.release = function release(optionalReplacementOnRelease) { - debugFlow('baton:', batonName, instanceId, 'release'); - if (optionalReplacementOnRelease) { // If you want to change. - releaseCallback = optionalReplacementOnRelease; - } - if (acceptedId() !== instanceId) { - log("Ignoring attempt to release virtualBaton " + batonName + ", which is not being held."); - return; - } - localRelease(); - if (!claimCallback) { // No claim set in release callback. - propose(); - } - return exports; - }; - exports.recheckWatchdog = timers.setInterval(function recheck() { - var holder = acceptedId(); // If we're waiting and we notice the holder is gone, ... - if (holder && claimCallback && !electionWatchdog && !connectionTest(holder)) { - bestPromise.winner = null; // used if the quorum agrees that old winner is not there - propose(); // ... propose an election. - } - }, recheckInterval); - exports.unload = function unload() { // Disconnect from everything. - messages.messageReceived.disconnect(messageHandler); - timers.clearInterval(exports.recheckWatchdog); - if (electionWatchdog) { - timers.clearTimeout(electionWatchdog); - } - electionWatchdog = claimCallback = releaseCallback = null; - Object.keys(subchannelHandlers).forEach(messages.unsubscribe); - debugFlow('baton:', batonName, instanceId, 'unload'); - return exports; - }; - - // Gather nAcceptors by making two proposals with some gathering time, even without a claim. - propose(); - return exports; -} -if (typeof module !== 'undefined') { // Allow testing in nodejs. - module.exports = virtualBatonf; -} else { - virtualBaton = virtualBatonf; -} diff --git a/unpublishedScripts/DomainContent/CellScience/Scripts/zoomAndMoveRandomly.js b/unpublishedScripts/DomainContent/CellScience/Scripts/zoomAndMoveRandomly.js deleted file mode 100644 index dd6a48c617..0000000000 --- a/unpublishedScripts/DomainContent/CellScience/Scripts/zoomAndMoveRandomly.js +++ /dev/null @@ -1,164 +0,0 @@ -// Copyright 2016 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 -// - -(function() { - var teleport; - var portalDestination; - var animationURL; - - this.entered = true; - Script.include('virtualBaton.js'); - - var self = this; - var baton; - - this.iOwn = false; - var currentInterval; - var _entityId; - - function startUpdate() { - self.iOwn = true; - print('i am the owner ' + _entityId) - } - - function stopUpdateAndReclaim() { - print('i released the object ' + _entityId) - self.iOwn = false; - baton.claim(startUpdate, stopUpdateAndReclaim); - } - - this.preload = function(entityID) { - this.entityId = entityID; - _entityId = entityID; - this.initialize(entityID); - this.initTimeout = null; - this.minVelocity = 1; - this.maxVelocity = 5; - this.minAngularVelocity = 0.03; - this.maxAngularVelocity = 0.10; - baton = virtualBaton({ - batonName: 'io.highfidelity.cells:' + entityID, // One winner for each entity - }); - stopUpdateAndReclaim(); - currentInterval = Script.setInterval(self.move, self.getTotalWait()) - - } - - this.initialize = function(entityID) { - // print(' should initialize') - var properties = Entities.getEntityProperties(entityID); - if (properties.userData.length === 0 || properties.hasOwnProperty('userData') === false) { - self.initTimeout = Script.setTimeout(function() { - // print(' no user data yet, try again in one second') - self.initialize(entityID); - }, 1000) - } else { - // print(' has userData') - self.portalDestination = properties.userData; - animationURL = properties.modelURL; - self.soundOptions = { - stereo: true, - loop: false, - localOnly: false, - position: properties.position, - volume: 0.5 - }; - - self.teleportSound = SoundCache.getSound("https://hifi-content.s3.amazonaws.com/DomainContent/CellScience/Audio/whoosh.wav"); - - } - } - - this.enterEntity = function(entityID) { - //print('ENTERED A BOUNDARY ENTITY, SHOULD ZOOM', entityID) - var data = JSON.parse(Entities.getEntityProperties(this.entityId).userData); - //print('DATA IS::' + data) - if (data != null) { - print("Teleporting to (" + data.location.x + ", " + data.location.y + ", " + data.location.z + ")"); - - MyAvatar.position = data.location; - } - - } - - this.lookAtTarget = function(entryPoint, target) { - //print('SHOULD LOOK AT TARGET') - var direction = Vec3.normalize(Vec3.subtract(entryPoint, target)); - var pitch = Quat.angleAxis(Math.asin(-direction.y) * 180.0 / Math.PI, { - x: 1, - y: 0, - z: 0 - }); - var yaw = Quat.angleAxis(Math.atan2(direction.x, direction.z) * 180.0 / Math.PI, { - x: 0, - y: 1, - z: 0 - }); - - MyAvatar.goToLocation(entryPoint, true, yaw); - - MyAvatar.headYaw = 0; - - } - - this.leaveEntity = function(entityID) { - Entities.editEntity(entityID, { - animationURL: animationURL, - animationSettings: '{ "frameIndex": 1, "running": false }' - }); - this.entered = false; - if (this.initTimeout !== null) { - Script.clearTimeout(this.initTimeout); - } - //playSound(); - } - - this.unload = function() { - if (this.initTimeout !== null) { - Script.clearTimeout(this.initTimeout); - } - if (baton) { - baton.release(function() {}); - } - - Script.clearInterval(currentInterval); - } - - this.hoverEnterEntity = function(entityID) { - Entities.editEntity(entityID, { - animationURL: animationURL, - animationSettings: '{ "fps": 24, "firstFrame": 1, "lastFrame": 25, "frameIndex": 1, "running": true, "hold": true }' - }); - } - - this.getTotalWait = function() { - return (Math.random() * 5000) * 3; - } - - this.move = function() { - if (self.iOwn === false) { - print('cell is not owned by me...') - return; - } - - var magnitudeAV = self.maxAngularVelocity; - - var directionAV = { - x: Math.random() - 0.5, - y: Math.random() - 0.5, - z: Math.random() - 0.5 - }; - // print("ROT magnitude is " + magnitudeAV + " and direction is " + directionAV.x); - Entities.editEntity(self.entityId, { - angularVelocity: Vec3.multiply(magnitudeAV, Vec3.normalize(directionAV)) - - }); - - - } - -}) \ No newline at end of file diff --git a/unpublishedScripts/DomainContent/CellScience/importCellScience.js b/unpublishedScripts/DomainContent/CellScience/importCellScience.js index 25323495d1..55b09cd4a7 100644 --- a/unpublishedScripts/DomainContent/CellScience/importCellScience.js +++ b/unpublishedScripts/DomainContent/CellScience/importCellScience.js @@ -120,7 +120,7 @@ var scenes = [{ location: locations.cellLayout[1], baseURL: baseLocation }), - script: "zoomAndMoveRandomly.js?" + version, + script: "zoom.js?" + version, visible: true }], boundary: { @@ -194,7 +194,6 @@ var scenes = [{ grabbable: false } }), - script: "moveRandomly2.js?" + version, visible: true }, { //golgi vesicles model: "vesicle", @@ -238,7 +237,6 @@ var scenes = [{ grabbable: false } }), - script: "moveRandomly2.js?" + version, visible: true }, { model: "vesicle", @@ -304,7 +302,6 @@ var scenes = [{ grabbable: false } }), - script: "moveRandomly2.js?" + version, visible: true }, { //outer vesicles model: "vesicle", @@ -326,32 +323,8 @@ var scenes = [{ grabbable: false } }), - script: "moveRandomly2.js?" + version, visible: true - }, - // {//wigglies - // model:"wiggly", - // dimensions:{x:320,y:40,z:160}, - // randomSize: 10, - // offset:{x:0,y:0,z:0}, - // radius:1800, - // number:50, - // userData:"", - // script:"moveRandomly", - // visible:true - // }, - //// {//wigglies - // model:"wiggly", - // dimensions:{x:640,y:80,z:320}, - // randomSize: 10, - // offset:{x:0,y:0,z:0}, - // radius:2100, - // number:50, - // userData:"", - // script:"moveRandomly", - // visible:true - // }, - { + }, { model: "hexokinase", dimensions: { x: 3, @@ -813,7 +786,7 @@ function CreateInstances(scene) { x: 0, y: 0, z: 0 - }, idBounds, 150); + }, idBounds, 150, scene.instances[i]); } //print('SCRIPT AT CREATE ENTITY: ' + script) @@ -824,8 +797,11 @@ function CreateInstances(scene) { -function CreateIdentification(name, position, rotation, dimensions, showDistance) { +function CreateIdentification(name, position, rotation, dimensions, showDistance, parentID) { //print ("creating ID for " + name); + if (parentID === undefined) { + parentID = "{00000000-0000-0000-0000-000000000000}"; + } Entities.addEntity({ type: "Sphere", name: "ID for " + name, @@ -834,6 +810,7 @@ function CreateIdentification(name, position, rotation, dimensions, showDistance green: 0, blue: 0 }, + parentID: parentID, dimensions: dimensions, position: position, rotation: rotation, @@ -9042,7 +9019,7 @@ Script.scriptEnding.connect(function() { Entities.addingEntity.disconnect(makeUngrabbable); }); -Script.setTimeout(function(){ +Script.setTimeout(function() { print('JBP stopping cell science import'); Script.stop(); -},30000) \ No newline at end of file +}, 30000) \ No newline at end of file diff --git a/unpublishedScripts/DomainContent/CellScience/moveCellsAC.js b/unpublishedScripts/DomainContent/CellScience/moveCellsAC.js new file mode 100644 index 0000000000..30e83108d6 --- /dev/null +++ b/unpublishedScripts/DomainContent/CellScience/moveCellsAC.js @@ -0,0 +1,96 @@ +var basePosition = { + x: 3000, + y: 13500, + z: 3000 +}; + +var initialized = false; + +EntityViewer.setPosition(basePosition); +EntityViewer.setKeyholeRadius(60000); +var octreeQueryInterval = Script.setInterval(function() { + EntityViewer.queryOctree(); +}, 200); + +var THROTTLE = true; +var THROTTLE_RATE = 5000; + +var sinceLastUpdate = 0; + +print('cells script') + +function findCells() { + var results = Entities.findEntities(basePosition, 60000); + + if (results.length === 0) { + print('no entities found') + return; + } + + results.forEach(function(v) { + var name = Entities.getEntityProperties(v, 'name').name; + print('name is:: ' + name) + if (name === 'Cell') { + print('found a cell!!' + v) + Script.setTimeout(function() { + moveCell(v); + }, Math.random() * THROTTLE_RATE) + } + }); +} + + +var minAngularVelocity = 0.01; +var maxAngularVelocity = 0.03; + +function moveCell(entityId) { + print('moving a cell! ' + entityId) + + var magnitudeAV = maxAngularVelocity; + + var directionAV = { + x: Math.random() - 0.5, + y: Math.random() - 0.5, + z: Math.random() - 0.5 + }; + print("ROT magnitude is " + magnitudeAV + " and direction is " + directionAV.x); + Entities.editEntity(entityId, { + angularVelocity: Vec3.multiply(magnitudeAV, Vec3.normalize(directionAV)) + }); + +} + +function update(deltaTime) { + + // print('deltaTime',deltaTime) + if (!initialized) { + print("checking for servers..."); + if (Entities.serversExist() && Entities.canRez()) { + print("servers exist -- makeAll..."); + Entities.setPacketsPerSecond(6000); + print("PPS:" + Entities.getPacketsPerSecond()); + initialized = true; + } + return; + } + + if (THROTTLE === true) { + sinceLastUpdate = sinceLastUpdate + deltaTime * 1000; + if (sinceLastUpdate > THROTTLE_RATE) { + print('SHOULD FIND CELLS!!!') + sinceLastUpdate = 0; + findCells(); + } else { + // print('returning in update ' + sinceLastUpdate) + return; + } + } + +} + +function unload() { + Script.update.disconnect(update); +} + +Script.update.connect(update); +Script.scriptEnding.connect(unload); \ No newline at end of file diff --git a/unpublishedScripts/DomainContent/CellScience/moveVesiclesAC.js b/unpublishedScripts/DomainContent/CellScience/moveVesiclesAC.js new file mode 100644 index 0000000000..ce8da54eb2 --- /dev/null +++ b/unpublishedScripts/DomainContent/CellScience/moveVesiclesAC.js @@ -0,0 +1,106 @@ +var basePosition = { + x: 3000, + y: 13500, + z: 3000 +}; + +var initialized = false; + +EntityViewer.setPosition(basePosition); +EntityViewer.setKeyholeRadius(60000); +var octreeQueryInterval = Script.setInterval(function() { + EntityViewer.queryOctree(); +}, 200); + +var THROTTLE = true; +var THROTTLE_RATE = 5000; + +var sinceLastUpdate = 0; + +print('vesicle script') + +function findVesicles() { + var results = Entities.findEntities(basePosition, 60000); + + if (results.length === 0) { + print('no entities found') + return; + } + + results.forEach(function(v) { + var name = Entities.getEntityProperties(v, 'name').name; + print('name is:: ' + name) + if (name === 'vesicle') { + print('found a vesicle!!' + v) + Script.setTimeout(function() { + moveVesicle(v); + }, Math.random() * THROTTLE_RATE) + } + }); +} + +var minVelocity = 1; +var maxVelocity = 5; +var minAngularVelocity = 0.01; +var maxAngularVelocity = 0.03; + +function moveVesicle(entityId) { + print('moving a vesicle! ' + entityId) + var magnitudeV = maxVelocity; + var directionV = { + x: Math.random() - 0.5, + y: Math.random() - 0.5, + z: Math.random() - 0.5 + }; + + print("POS magnitude is " + magnitudeV + " and direction is " + directionV.x); + + var magnitudeAV = maxAngularVelocity; + + var directionAV = { + x: Math.random() - 0.5, + y: Math.random() - 0.5, + z: Math.random() - 0.5 + }; + print("ROT magnitude is " + magnitudeAV + " and direction is " + directionAV.x); + Entities.editEntity(entityId, { + velocity: Vec3.multiply(magnitudeV, Vec3.normalize(directionV)), + angularVelocity: Vec3.multiply(magnitudeAV, Vec3.normalize(directionAV)) + }); + +} + +function update(deltaTime) { + + // print('deltaTime',deltaTime) + if (!initialized) { + print("checking for servers..."); + if (Entities.serversExist() && Entities.canRez()) { + print("servers exist -- makeAll..."); + Entities.setPacketsPerSecond(6000); + print("PPS:" + Entities.getPacketsPerSecond()); + initialized = true; + } + return; + } + + if (THROTTLE === true) { + sinceLastUpdate = sinceLastUpdate + deltaTime * 1000; + if (sinceLastUpdate > THROTTLE_RATE) { + print('SHOULD FIND VESICLES!!!') + sinceLastUpdate = 0; + findVesicles(); + } else { + // print('returning in update ' + sinceLastUpdate) + return; + } + } + +} + +function unload() { + Script.update.disconnect(update); +} + +Script.update.connect(update); +Script.scriptEnding.connect(unload); \ No newline at end of file From baa030b7b07a24612953807d5a116398e8354f17 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Wed, 24 Feb 2016 13:18:01 -0800 Subject: [PATCH 11/19] cleanup and submit --- .../CellScience/importCellScience.js | 2 +- .../DomainContent/CellScience/moveCellsAC.js | 21 ++++++++++++------- .../CellScience/moveVesiclesAC.js | 20 +++++++++++------- 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/unpublishedScripts/DomainContent/CellScience/importCellScience.js b/unpublishedScripts/DomainContent/CellScience/importCellScience.js index 55b09cd4a7..6a6de23f4e 100644 --- a/unpublishedScripts/DomainContent/CellScience/importCellScience.js +++ b/unpublishedScripts/DomainContent/CellScience/importCellScience.js @@ -5,7 +5,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -var version = 1057; +var version = 1100; var cellLayout; var baseLocation = "https://hifi-content.s3.amazonaws.com/DomainContent/CellScience/"; diff --git a/unpublishedScripts/DomainContent/CellScience/moveCellsAC.js b/unpublishedScripts/DomainContent/CellScience/moveCellsAC.js index 30e83108d6..881f8e981c 100644 --- a/unpublishedScripts/DomainContent/CellScience/moveCellsAC.js +++ b/unpublishedScripts/DomainContent/CellScience/moveCellsAC.js @@ -1,3 +1,10 @@ +// Copyright 2016 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 basePosition = { x: 3000, y: 13500, @@ -17,21 +24,21 @@ var THROTTLE_RATE = 5000; var sinceLastUpdate = 0; -print('cells script') +//print('cells script') function findCells() { var results = Entities.findEntities(basePosition, 60000); if (results.length === 0) { - print('no entities found') + // print('no entities found') return; } results.forEach(function(v) { var name = Entities.getEntityProperties(v, 'name').name; - print('name is:: ' + name) + // print('name is:: ' + name) if (name === 'Cell') { - print('found a cell!!' + v) + // print('found a cell!!' + v) Script.setTimeout(function() { moveCell(v); }, Math.random() * THROTTLE_RATE) @@ -44,7 +51,7 @@ var minAngularVelocity = 0.01; var maxAngularVelocity = 0.03; function moveCell(entityId) { - print('moving a cell! ' + entityId) + // print('moving a cell! ' + entityId) var magnitudeAV = maxAngularVelocity; @@ -53,7 +60,7 @@ function moveCell(entityId) { y: Math.random() - 0.5, z: Math.random() - 0.5 }; - print("ROT magnitude is " + magnitudeAV + " and direction is " + directionAV.x); + // print("ROT magnitude is " + magnitudeAV + " and direction is " + directionAV.x); Entities.editEntity(entityId, { angularVelocity: Vec3.multiply(magnitudeAV, Vec3.normalize(directionAV)) }); @@ -77,7 +84,7 @@ function update(deltaTime) { if (THROTTLE === true) { sinceLastUpdate = sinceLastUpdate + deltaTime * 1000; if (sinceLastUpdate > THROTTLE_RATE) { - print('SHOULD FIND CELLS!!!') + // print('SHOULD FIND CELLS!!!') sinceLastUpdate = 0; findCells(); } else { diff --git a/unpublishedScripts/DomainContent/CellScience/moveVesiclesAC.js b/unpublishedScripts/DomainContent/CellScience/moveVesiclesAC.js index ce8da54eb2..3e70934cba 100644 --- a/unpublishedScripts/DomainContent/CellScience/moveVesiclesAC.js +++ b/unpublishedScripts/DomainContent/CellScience/moveVesiclesAC.js @@ -1,3 +1,10 @@ +// Copyright 2016 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 basePosition = { x: 3000, y: 13500, @@ -17,7 +24,7 @@ var THROTTLE_RATE = 5000; var sinceLastUpdate = 0; -print('vesicle script') +//print('vesicle script') function findVesicles() { var results = Entities.findEntities(basePosition, 60000); @@ -31,7 +38,7 @@ function findVesicles() { var name = Entities.getEntityProperties(v, 'name').name; print('name is:: ' + name) if (name === 'vesicle') { - print('found a vesicle!!' + v) + // print('found a vesicle!!' + v) Script.setTimeout(function() { moveVesicle(v); }, Math.random() * THROTTLE_RATE) @@ -45,7 +52,7 @@ var minAngularVelocity = 0.01; var maxAngularVelocity = 0.03; function moveVesicle(entityId) { - print('moving a vesicle! ' + entityId) + // print('moving a vesicle! ' + entityId) var magnitudeV = maxVelocity; var directionV = { x: Math.random() - 0.5, @@ -53,7 +60,7 @@ function moveVesicle(entityId) { z: Math.random() - 0.5 }; - print("POS magnitude is " + magnitudeV + " and direction is " + directionV.x); + // print("POS magnitude is " + magnitudeV + " and direction is " + directionV.x); var magnitudeAV = maxAngularVelocity; @@ -62,7 +69,7 @@ function moveVesicle(entityId) { y: Math.random() - 0.5, z: Math.random() - 0.5 }; - print("ROT magnitude is " + magnitudeAV + " and direction is " + directionAV.x); + // print("ROT magnitude is " + magnitudeAV + " and direction is " + directionAV.x); Entities.editEntity(entityId, { velocity: Vec3.multiply(magnitudeV, Vec3.normalize(directionV)), angularVelocity: Vec3.multiply(magnitudeAV, Vec3.normalize(directionAV)) @@ -71,7 +78,6 @@ function moveVesicle(entityId) { } function update(deltaTime) { - // print('deltaTime',deltaTime) if (!initialized) { print("checking for servers..."); @@ -87,7 +93,7 @@ function update(deltaTime) { if (THROTTLE === true) { sinceLastUpdate = sinceLastUpdate + deltaTime * 1000; if (sinceLastUpdate > THROTTLE_RATE) { - print('SHOULD FIND VESICLES!!!') + // print('SHOULD FIND VESICLES!!!') sinceLastUpdate = 0; findVesicles(); } else { From b4edfe2390d5821d13e76aae5e9c77af8bc3324a Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Thu, 25 Feb 2016 12:06:22 -0800 Subject: [PATCH 12/19] no expiry for simulation ownership --- .../src/entities/EntityServer.cpp | 11 +- assignment-client/src/entities/EntityServer.h | 8 +- .../entities/src/SimpleEntitySimulation.cpp | 122 ++++++++++++------ .../entities/src/SimpleEntitySimulation.h | 7 +- libraries/physics/src/EntityMotionState.cpp | 23 ++-- 5 files changed, 106 insertions(+), 65 deletions(-) diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index b6223497e6..b177d2a9a0 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -277,14 +277,17 @@ void EntityServer::readAdditionalConfiguration(const QJsonObject& settingsSectio // set of stats to have, but we'd probably want a different data structure if we keep it very long. // Since this version uses a single shared QMap for all senders, there could be some lock contention // on this QWriteLocker -void EntityServer::trackSend(const QUuid& dataID, quint64 dataLastEdited, const QUuid& viewerNode) { +void EntityServer::trackSend(const QUuid& dataID, quint64 dataLastEdited, const QUuid& sessionID) { QWriteLocker locker(&_viewerSendingStatsLock); - _viewerSendingStats[viewerNode][dataID] = { usecTimestampNow(), dataLastEdited }; + _viewerSendingStats[sessionID][dataID] = { usecTimestampNow(), dataLastEdited }; } -void EntityServer::trackViewerGone(const QUuid& viewerNode) { +void EntityServer::trackViewerGone(const QUuid& sessionID) { QWriteLocker locker(&_viewerSendingStatsLock); - _viewerSendingStats.remove(viewerNode); + _viewerSendingStats.remove(sessionID); + if (_entitySimulation) { + _entitySimulation->clearOwnership(sessionID); + } } QString EntityServer::serverSubclassStats() { diff --git a/assignment-client/src/entities/EntityServer.h b/assignment-client/src/entities/EntityServer.h index cd603f44d8..74057bfa5d 100644 --- a/assignment-client/src/entities/EntityServer.h +++ b/assignment-client/src/entities/EntityServer.h @@ -27,6 +27,8 @@ struct ViewerSendingStats { quint64 lastEdited; }; +class SimpleEntitySimulation; + class EntityServer : public OctreeServer, public NewlyCreatedEntityHook { Q_OBJECT public: @@ -52,8 +54,8 @@ public: virtual void readAdditionalConfiguration(const QJsonObject& settingsSectionObject) override; virtual QString serverSubclassStats() override; - virtual void trackSend(const QUuid& dataID, quint64 dataLastEdited, const QUuid& viewerNode) override; - virtual void trackViewerGone(const QUuid& viewerNode) override; + virtual void trackSend(const QUuid& dataID, quint64 dataLastEdited, const QUuid& sessionID) override; + virtual void trackViewerGone(const QUuid& sessionID) override; public slots: void pruneDeletedEntities(); @@ -65,7 +67,7 @@ private slots: void handleEntityPacket(QSharedPointer message, SharedNodePointer senderNode); private: - EntitySimulation* _entitySimulation; + SimpleEntitySimulation* _entitySimulation; QTimer* _pruneDeletedEntitiesTimer = nullptr; QReadWriteLock _viewerSendingStatsLock; diff --git a/libraries/entities/src/SimpleEntitySimulation.cpp b/libraries/entities/src/SimpleEntitySimulation.cpp index bdf27f4440..693d80b27d 100644 --- a/libraries/entities/src/SimpleEntitySimulation.cpp +++ b/libraries/entities/src/SimpleEntitySimulation.cpp @@ -18,51 +18,69 @@ #include "EntityItem.h" #include "EntitiesLogging.h" -const quint64 MIN_SIMULATION_OWNERSHIP_UPDATE_PERIOD = 2 * USECS_PER_SECOND; - -void SimpleEntitySimulation::updateEntitiesInternal(const quint64& now) { - if (_entitiesWithSimulator.size() == 0) { - return; - } - - if (now < _nextSimulationExpiry) { - // nothing has expired yet - return; - } - - // If an Entity has a simulation owner but there has been no update for a while: clear the owner. - // If an Entity goes ownerless for too long: zero velocity and remove from _entitiesWithSimulator. - _nextSimulationExpiry = now + MIN_SIMULATION_OWNERSHIP_UPDATE_PERIOD; +const quint64 MAX_OWNERLESS_PERIOD = 2 * USECS_PER_SECOND; +void SimpleEntitySimulation::clearOwnership(const QUuid& ownerID) { QMutexLocker lock(&_mutex); - SetOfEntities::iterator itemItr = _entitiesWithSimulator.begin(); - while (itemItr != _entitiesWithSimulator.end()) { + SetOfEntities::iterator itemItr = _entitiesWithSimulationOwner.begin(); + while (itemItr != _entitiesWithSimulationOwner.end()) { EntityItemPointer entity = *itemItr; - quint64 expiry = entity->getLastChangedOnServer() + MIN_SIMULATION_OWNERSHIP_UPDATE_PERIOD; - if (expiry < now) { - if (entity->getSimulatorID().isNull()) { - // no simulators are volunteering - // zero the velocity on this entity so that it doesn't drift far away - entity->setVelocity(Vectors::ZERO); - entity->setAngularVelocity(Vectors::ZERO); - entity->setAcceleration(Vectors::ZERO); - // remove from list - itemItr = _entitiesWithSimulator.erase(itemItr); - continue; - } else { - // the simulator has stopped updating this object - // clear ownership and restart timer, giving nearby simulators time to volunteer - qCDebug(entities) << "auto-removing simulation owner " << entity->getSimulatorID(); - entity->clearSimulationOwnership(); + if (entity->getSimulatorID() == ownerID) { + // the simulator has abandonded this object --> remove from owned list + qCDebug(entities) << "auto-removing simulation owner " << entity->getSimulatorID(); + itemItr = _entitiesWithSimulationOwner.erase(itemItr); + + if (entity->getDynamic() && entity->hasLocalVelocity()) { + // it is still moving dynamically --> add to orphaned list + _entitiesThatNeedSimulationOwner.insert(entity); + quint64 expiry = entity->getLastChangedOnServer() + MAX_OWNERLESS_PERIOD; + if (expiry < _nextOwnerlessExpiry) { + _nextOwnerlessExpiry = expiry; + } } + + // remove ownership and dirty all the tree elements that contain the it + entity->clearSimulationOwnership(); entity->markAsChangedOnServer(); - // dirty all the tree elements that contain the entity DirtyOctreeElementOperator op(entity->getElement()); getEntityTree()->recurseTreeWithOperator(&op); - } else if (expiry < _nextSimulationExpiry) { - _nextSimulationExpiry = expiry; + } else { + ++itemItr; + } + } +} + +void SimpleEntitySimulation::updateEntitiesInternal(const quint64& now) { + if (now > _nextOwnerlessExpiry) { + // search for ownerless objects that have expired + QMutexLocker lock(&_mutex); + _nextOwnerlessExpiry = -1; + SetOfEntities::iterator itemItr = _entitiesThatNeedSimulationOwner.begin(); + while (itemItr != _entitiesThatNeedSimulationOwner.end()) { + EntityItemPointer entity = *itemItr; + quint64 expiry = entity->getLastChangedOnServer() + MAX_OWNERLESS_PERIOD; + if (expiry < now) { + // no simulators have volunteered ownership --> remove from list + itemItr = _entitiesThatNeedSimulationOwner.erase(itemItr); + + if (entity->getSimulatorID().isNull() && entity->getDynamic() && entity->hasLocalVelocity()) { + // zero the derivatives + entity->setVelocity(Vectors::ZERO); + entity->setAngularVelocity(Vectors::ZERO); + entity->setAcceleration(Vectors::ZERO); + + // dirty all the tree elements that contain it + entity->markAsChangedOnServer(); + DirtyOctreeElementOperator op(entity->getElement()); + getEntityTree()->recurseTreeWithOperator(&op); + } + } else { + ++itemItr; + if (expiry < _nextOwnerlessExpiry) { + _nextOwnerlessExpiry = expiry; + } + } } - ++itemItr; } } @@ -70,26 +88,46 @@ void SimpleEntitySimulation::addEntityInternal(EntityItemPointer entity) { EntitySimulation::addEntityInternal(entity); if (!entity->getSimulatorID().isNull()) { QMutexLocker lock(&_mutex); - _entitiesWithSimulator.insert(entity); + _entitiesWithSimulationOwner.insert(entity); + } else if (entity->getDynamic() && entity->hasLocalVelocity()) { + QMutexLocker lock(&_mutex); + _entitiesThatNeedSimulationOwner.insert(entity); + quint64 expiry = entity->getLastChangedOnServer() + MAX_OWNERLESS_PERIOD; + if (expiry < _nextOwnerlessExpiry) { + _nextOwnerlessExpiry = expiry; + } } } void SimpleEntitySimulation::removeEntityInternal(EntityItemPointer entity) { EntitySimulation::removeEntityInternal(entity); QMutexLocker lock(&_mutex); - _entitiesWithSimulator.remove(entity); + _entitiesWithSimulationOwner.remove(entity); + _entitiesThatNeedSimulationOwner.remove(entity); } void SimpleEntitySimulation::changeEntityInternal(EntityItemPointer entity) { EntitySimulation::changeEntityInternal(entity); - if (!entity->getSimulatorID().isNull()) { + if (entity->getSimulatorID().isNull()) { QMutexLocker lock(&_mutex); - _entitiesWithSimulator.insert(entity); + _entitiesWithSimulationOwner.remove(entity); + if (entity->getDynamic() && entity->hasLocalVelocity()) { + _entitiesThatNeedSimulationOwner.insert(entity); + quint64 expiry = entity->getLastChangedOnServer() + MAX_OWNERLESS_PERIOD; + if (expiry < _nextOwnerlessExpiry) { + _nextOwnerlessExpiry = expiry; + } + } + } else { + QMutexLocker lock(&_mutex); + _entitiesWithSimulationOwner.insert(entity); + _entitiesThatNeedSimulationOwner.remove(entity); } entity->clearDirtyFlags(); } void SimpleEntitySimulation::clearEntitiesInternal() { - _entitiesWithSimulator.clear(); + _entitiesWithSimulationOwner.clear(); + _entitiesThatNeedSimulationOwner.clear(); } diff --git a/libraries/entities/src/SimpleEntitySimulation.h b/libraries/entities/src/SimpleEntitySimulation.h index 53a7574bf2..d9c04fdcf9 100644 --- a/libraries/entities/src/SimpleEntitySimulation.h +++ b/libraries/entities/src/SimpleEntitySimulation.h @@ -21,6 +21,8 @@ public: SimpleEntitySimulation() : EntitySimulation() { } virtual ~SimpleEntitySimulation() { clearEntitiesInternal(); } + void clearOwnership(const QUuid& ownerID); + protected: virtual void updateEntitiesInternal(const quint64& now) override; virtual void addEntityInternal(EntityItemPointer entity) override; @@ -28,8 +30,9 @@ protected: virtual void changeEntityInternal(EntityItemPointer entity) override; virtual void clearEntitiesInternal() override; - SetOfEntities _entitiesWithSimulator; - quint64 _nextSimulationExpiry { 0 }; + SetOfEntities _entitiesWithSimulationOwner; + SetOfEntities _entitiesThatNeedSimulationOwner; + quint64 _nextOwnerlessExpiry { 0 }; }; #endif // hifi_SimpleEntitySimulation_h diff --git a/libraries/physics/src/EntityMotionState.cpp b/libraries/physics/src/EntityMotionState.cpp index 8c0dab98db..6a818a1972 100644 --- a/libraries/physics/src/EntityMotionState.cpp +++ b/libraries/physics/src/EntityMotionState.cpp @@ -272,7 +272,7 @@ bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) { float dt = (float)(numSteps) * PHYSICS_ENGINE_FIXED_SUBSTEP; if (_numInactiveUpdates > 0) { - const uint8_t MAX_NUM_INACTIVE_UPDATES = 3; + const uint8_t MAX_NUM_INACTIVE_UPDATES = 20; if (_numInactiveUpdates > MAX_NUM_INACTIVE_UPDATES) { // clear local ownership (stop sending updates) and let the server clear itself _entity->clearSimulationOwnership(); @@ -282,7 +282,7 @@ bool EntityMotionState::remoteSimulationOutOfSync(uint32_t simulationStep) { // until it is removed from the outgoing updates // (which happens when we don't own the simulation and it isn't touching our simulation) const float INACTIVE_UPDATE_PERIOD = 0.5f; - return (dt > INACTIVE_UPDATE_PERIOD); + return (dt > INACTIVE_UPDATE_PERIOD * (float)_numInactiveUpdates); } if (!_body->isActive()) { @@ -404,8 +404,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, const Q assert(_entity); assert(entityTreeIsLocked()); - bool active = _body->isActive(); - if (!active) { + if (!_body->isActive()) { // make sure all derivatives are zero glm::vec3 zero(0.0f); _entity->setVelocity(zero); @@ -495,16 +494,12 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, const Q qCDebug(physics) << " lastSimulated:" << debugTime(lastSimulated, now); #endif //def WANT_DEBUG - if (sessionID == _entity->getSimulatorID()) { - // we think we own the simulation - if (!active) { - // we own the simulation but the entity has stopped, so we tell the server that we're clearing simulatorID - // but we remember that we do still own it... and rely on the server to tell us that we don't - properties.clearSimulationOwner(); - _outgoingPriority = ZERO_SIMULATION_PRIORITY; - } - // else the ownership is not changing so we don't bother to pack it - } else { + if (_numInactiveUpdates > 0) { + // we own the simulation but the entity has stopped, so we tell the server that we're clearing simulatorID + // but we remember that we do still own it... and rely on the server to tell us that we don't + properties.clearSimulationOwner(); + _outgoingPriority = ZERO_SIMULATION_PRIORITY; + } else if (sessionID != _entity->getSimulatorID()) { // we don't own the simulation for this entity yet, but we're sending a bid for it properties.setSimulationOwner(sessionID, glm::max(_outgoingPriority, VOLUNTEER_SIMULATION_PRIORITY)); _nextOwnershipBid = now + USECS_BETWEEN_OWNERSHIP_BIDS; From b0cb4b719994a2e825c7b56f0bf515544e8ef61f Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Fri, 26 Feb 2016 10:26:02 -0800 Subject: [PATCH 13/19] disable boundaries --- .../CellScience/importCellScience.js | 513 +++++++++--------- 1 file changed, 248 insertions(+), 265 deletions(-) diff --git a/unpublishedScripts/DomainContent/CellScience/importCellScience.js b/unpublishedScripts/DomainContent/CellScience/importCellScience.js index 6a6de23f4e..876df8adb1 100644 --- a/unpublishedScripts/DomainContent/CellScience/importCellScience.js +++ b/unpublishedScripts/DomainContent/CellScience/importCellScience.js @@ -5,7 +5,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -var version = 1100; +var version = 1112; var cellLayout; var baseLocation = "https://hifi-content.s3.amazonaws.com/DomainContent/CellScience/"; @@ -112,7 +112,7 @@ var scenes = [{ y: 0, z: 0 }, - radius: 450, + radius: 500, number: 10, userData: JSON.stringify({ entryPoint: locations.cellLayout[1], @@ -151,267 +151,253 @@ var scenes = [{ skybox: "cosmos_skybox_blurred" }, instances: [{ - model: "translation", - dimensions: { - x: 10, - y: 16, - z: 10 + model: "translation", + dimensions: { + x: 10, + y: 16, + z: 10 + }, + offset: { + x: 0, + y: 0, + z: 0 + }, + radius: 300, + number: 7, + userData: JSON.stringify({ + grabbableKey: { + grabbable: false }, - offset: { - x: 0, - y: 0, - z: 0 + target: locations.ribosome[1], + location: locations.ribosome[0], + baseURL: baseLocation + }), + script: "zoom.js?" + version, + visible: true + }, { + model: "vesicle", + dimensions: { + x: 60, + y: 60, + z: 60 + }, + randomSize: 10, + offset: { + x: 0, + y: 0, + z: 0 + }, + radius: 1000, + number: 22, + userData: JSON.stringify({ + grabbableKey: { + grabbable: false + } + }), + visible: true + }, { //golgi vesicles + model: "vesicle", + dimensions: { + x: 10, + y: 10, + z: 10 + }, + randomSize: 10, + offset: { + x: -319, + y: 66, + z: 976 + }, + radius: 140, + number: 10, + userData: JSON.stringify({ + grabbableKey: { + grabbable: false + } + }), + script: "", + visible: true + }, { //golgi vesicles + model: "vesicle", + dimensions: { + x: 15, + y: 15, + z: 15 + }, + randomSize: 10, + offset: { + x: -319, + y: 66, + z: 976 + }, + radius: 115, + number: 7, + userData: JSON.stringify({ + grabbableKey: { + grabbable: false + } + }), + visible: true + }, { + model: "vesicle", + dimensions: { + x: 50, + y: 50, + z: 50 + }, + randomSize: 10, + offset: { + x: 0, + y: 0, + z: 0 + }, + radius: 600, + number: 15, + userData: JSON.stringify({ + grabbableKey: { + grabbable: false + } + }), + script: "", + visible: true + }, { //outer vesicles + model: "vesicle", + dimensions: { + x: 60, + y: 60, + z: 60 + }, + randomSize: 10, + offset: { + x: 0, + y: 0, + z: 0 + }, + radius: 1600, + number: 22, + userData: JSON.stringify({ + grabbableKey: { + grabbable: false + } + }), + script: "", + visible: true + }, { //outer vesicles + model: "vesicle", + dimensions: { + x: 40, + y: 40, + z: 40 + }, + randomSize: 10, + offset: { + x: 0, + y: 0, + z: 0 + }, + radius: 1400, + number: 22, + userData: JSON.stringify({ + grabbableKey: { + grabbable: false + } + }), + visible: true + }, { //outer vesicles + model: "vesicle", + dimensions: { + x: 80, + y: 80, + z: 80 + }, + randomSize: 10, + offset: { + x: 0, + y: 0, + z: 0 + }, + radius: 1800, + number: 22, + userData: JSON.stringify({ + grabbableKey: { + grabbable: false + } + }), + visible: true + }, { + model: "hexokinase", + dimensions: { + x: 3, + y: 4, + z: 3 + }, + randomSize: 10, + offset: { + x: 236, + y: 8, + z: 771 + }, + radius: 80, + number: 7, + userData: JSON.stringify({ + grabbableKey: { + grabbable: false }, - radius: 300, - number: 7, - userData: JSON.stringify({ - grabbableKey: { - grabbable: false - }, - target: locations.ribosome[1], - location: locations.ribosome[0], - baseURL: baseLocation - }), - script: "zoom.js?" + version, - visible: true - }, { - model: "vesicle", - dimensions: { - x: 60, - y: 60, - z: 60 + target: locations.hexokinase[1], + location: locations.hexokinase[0], + baseURL: baseLocation + }), + script: "zoom.js?" + version, + visible: true + }, { + model: "pfructo_kinase", + dimensions: { + x: 3, + y: 4, + z: 3 + }, + randomSize: 10, + offset: { + x: 236, + y: 8, + z: 771 + }, + radius: 60, + number: 7, + userData: JSON.stringify({ + grabbableKey: { + grabbable: false }, - randomSize: 10, - offset: { - x: 0, - y: 0, - z: 0 + target: locations.hexokinase[1], + location: locations.hexokinase[0], + }), + script: "zoom.js?" + version, + visible: true + }, { + model: "glucose_isomerase", + dimensions: { + x: 3, + y: 4, + z: 3 + }, + randomSize: 10, + offset: { + x: 236, + y: 8, + z: 771 + }, + radius: 70, + number: 7, + userData: JSON.stringify({ + grabbableKey: { + grabbable: false }, - radius: 1000, - number: 22, - userData: JSON.stringify({ - grabbableKey: { - grabbable: false - } - }), - visible: true - }, { //golgi vesicles - model: "vesicle", - dimensions: { - x: 10, - y: 10, - z: 10 - }, - randomSize: 10, - offset: { - x: -319, - y: 66, - z: 976 - }, - radius: 140, - number: 10, - userData: JSON.stringify({ - grabbableKey: { - grabbable: false - } - }), - script: "", - visible: true - }, { //golgi vesicles - model: "vesicle", - dimensions: { - x: 15, - y: 15, - z: 15 - }, - randomSize: 10, - offset: { - x: -319, - y: 66, - z: 976 - }, - radius: 115, - number: 7, - userData: JSON.stringify({ - grabbableKey: { - grabbable: false - } - }), - visible: true - }, { - model: "vesicle", - dimensions: { - x: 50, - y: 50, - z: 50 - }, - randomSize: 10, - offset: { - x: 0, - y: 0, - z: 0 - }, - radius: 600, - number: 15, - userData: JSON.stringify({ - grabbableKey: { - grabbable: false - } - }), - script: "", - visible: true - }, { //outer vesicles - model: "vesicle", - dimensions: { - x: 60, - y: 60, - z: 60 - }, - randomSize: 10, - offset: { - x: 0, - y: 0, - z: 0 - }, - radius: 1600, - number: 22, - userData: JSON.stringify({ - grabbableKey: { - grabbable: false - } - }), - script: "", - visible: true - }, { //outer vesicles - model: "vesicle", - dimensions: { - x: 40, - y: 40, - z: 40 - }, - randomSize: 10, - offset: { - x: 0, - y: 0, - z: 0 - }, - radius: 1400, - number: 22, - userData: JSON.stringify({ - grabbableKey: { - grabbable: false - } - }), - visible: true - }, { //outer vesicles - model: "vesicle", - dimensions: { - x: 80, - y: 80, - z: 80 - }, - randomSize: 10, - offset: { - x: 0, - y: 0, - z: 0 - }, - radius: 1800, - number: 22, - userData: JSON.stringify({ - grabbableKey: { - grabbable: false - } - }), - visible: true - }, { - model: "hexokinase", - dimensions: { - x: 3, - y: 4, - z: 3 - }, - randomSize: 10, - offset: { - x: 236, - y: 8, - z: 771 - }, - radius: 80, - number: 7, - userData: JSON.stringify({ - grabbableKey: { - grabbable: false - }, - target: locations.hexokinase[1], - location: locations.hexokinase[0], - baseURL: baseLocation - }), - script: "zoom.js?" + version, - visible: true - }, { - model: "pfructo_kinase", - dimensions: { - x: 3, - y: 4, - z: 3 - }, - randomSize: 10, - offset: { - x: 236, - y: 8, - z: 771 - }, - radius: 60, - number: 7, - userData: JSON.stringify({ - grabbableKey: { - grabbable: false - }, - target: locations.hexokinase[1], - location: locations.hexokinase[0], - }), - script: "zoom.js?" + version, - visible: true - }, { - model: "glucose_isomerase", - dimensions: { - x: 3, - y: 4, - z: 3 - }, - randomSize: 10, - offset: { - x: 236, - y: 8, - z: 771 - }, - radius: 70, - number: 7, - userData: JSON.stringify({ - grabbableKey: { - grabbable: false - }, - target: locations.hexokinase[1], - location: locations.hexokinase[0], - }), - script: "zoom.js?" + version, - visible: true - } - // { - // model:"NPC", - // dimensions:{x:20,y:20,z:20}, - // randomSize: 10, - // offset:{x:208.593693,y:6.113100222,z:153.3202277}, - // radius:520, - // number:25, - // userData: "", - // script:"", - // visible:true - // } - - - ], + target: locations.hexokinase[1], + location: locations.hexokinase[0], + }), + script: "zoom.js?" + version, + visible: true + }], boundary: { radius: locations.cellLayout[2], center: locations.cellLayout[0], @@ -573,7 +559,7 @@ function ImportScene(scene) { CreateZone(scene); CreateInstances(scene); - CreateBoundary(scene); + // CreateBoundary(scene); // print("done " + scene.name); @@ -797,11 +783,9 @@ function CreateInstances(scene) { -function CreateIdentification(name, position, rotation, dimensions, showDistance, parentID) { +function CreateIdentification(name, position, rotation, dimensions, showDistance) { //print ("creating ID for " + name); - if (parentID === undefined) { - parentID = "{00000000-0000-0000-0000-000000000000}"; - } + Entities.addEntity({ type: "Sphere", name: "ID for " + name, @@ -810,7 +794,6 @@ function CreateIdentification(name, position, rotation, dimensions, showDistance green: 0, blue: 0 }, - parentID: parentID, dimensions: dimensions, position: position, rotation: rotation, From 6c6ea3f0a76ce9bdc433216f3e3bcb6ad5d678e0 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Fri, 26 Feb 2016 10:42:45 -0800 Subject: [PATCH 14/19] code cleanup --- .../DomainContent/CellScience/moveCellsAC.js | 14 +++++++------- .../DomainContent/CellScience/moveVesiclesAC.js | 10 +++------- 2 files changed, 10 insertions(+), 14 deletions(-) diff --git a/unpublishedScripts/DomainContent/CellScience/moveCellsAC.js b/unpublishedScripts/DomainContent/CellScience/moveCellsAC.js index 881f8e981c..cf35e081e0 100644 --- a/unpublishedScripts/DomainContent/CellScience/moveCellsAC.js +++ b/unpublishedScripts/DomainContent/CellScience/moveCellsAC.js @@ -30,18 +30,18 @@ function findCells() { var results = Entities.findEntities(basePosition, 60000); if (results.length === 0) { - // print('no entities found') + // print('no entities found') return; } results.forEach(function(v) { var name = Entities.getEntityProperties(v, 'name').name; - // print('name is:: ' + name) + // print('name is:: ' + name) if (name === 'Cell') { - // print('found a cell!!' + v) + // print('found a cell!!' + v) Script.setTimeout(function() { moveCell(v); - }, Math.random() * THROTTLE_RATE) + }, Math.random() * THROTTLE_RATE); } }); } @@ -51,7 +51,7 @@ var minAngularVelocity = 0.01; var maxAngularVelocity = 0.03; function moveCell(entityId) { - // print('moving a cell! ' + entityId) + // print('moving a cell! ' + entityId) var magnitudeAV = maxAngularVelocity; @@ -60,7 +60,7 @@ function moveCell(entityId) { y: Math.random() - 0.5, z: Math.random() - 0.5 }; - // print("ROT magnitude is " + magnitudeAV + " and direction is " + directionAV.x); + // print("ROT magnitude is " + magnitudeAV + " and direction is " + directionAV.x); Entities.editEntity(entityId, { angularVelocity: Vec3.multiply(magnitudeAV, Vec3.normalize(directionAV)) }); @@ -84,7 +84,7 @@ function update(deltaTime) { if (THROTTLE === true) { sinceLastUpdate = sinceLastUpdate + deltaTime * 1000; if (sinceLastUpdate > THROTTLE_RATE) { - // print('SHOULD FIND CELLS!!!') + // print('SHOULD FIND CELLS!!!') sinceLastUpdate = 0; findCells(); } else { diff --git a/unpublishedScripts/DomainContent/CellScience/moveVesiclesAC.js b/unpublishedScripts/DomainContent/CellScience/moveVesiclesAC.js index 3e70934cba..922f0d94cf 100644 --- a/unpublishedScripts/DomainContent/CellScience/moveVesiclesAC.js +++ b/unpublishedScripts/DomainContent/CellScience/moveVesiclesAC.js @@ -30,18 +30,17 @@ function findVesicles() { var results = Entities.findEntities(basePosition, 60000); if (results.length === 0) { - print('no entities found') + // print('no entities found'); return; } results.forEach(function(v) { var name = Entities.getEntityProperties(v, 'name').name; - print('name is:: ' + name) if (name === 'vesicle') { - // print('found a vesicle!!' + v) + //print('found a vesicle!!' + v) Script.setTimeout(function() { moveVesicle(v); - }, Math.random() * THROTTLE_RATE) + }, Math.random() * THROTTLE_RATE); } }); } @@ -78,7 +77,6 @@ function moveVesicle(entityId) { } function update(deltaTime) { - // print('deltaTime',deltaTime) if (!initialized) { print("checking for servers..."); if (Entities.serversExist() && Entities.canRez()) { @@ -93,11 +91,9 @@ function update(deltaTime) { if (THROTTLE === true) { sinceLastUpdate = sinceLastUpdate + deltaTime * 1000; if (sinceLastUpdate > THROTTLE_RATE) { - // print('SHOULD FIND VESICLES!!!') sinceLastUpdate = 0; findVesicles(); } else { - // print('returning in update ' + sinceLastUpdate) return; } } From 6d9c5856041ffd26eb1f06bbe03a463fb6fecb47 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Fri, 26 Feb 2016 12:01:59 -0800 Subject: [PATCH 15/19] add fade between depths in depth reticle --- examples/depthReticle.js | 47 +++++++++++++++++++++++++++++++++++----- 1 file changed, 41 insertions(+), 6 deletions(-) diff --git a/examples/depthReticle.js b/examples/depthReticle.js index a60e61d07c..a8afb80df2 100644 --- a/examples/depthReticle.js +++ b/examples/depthReticle.js @@ -12,17 +12,24 @@ var APPARENT_2D_OVERLAY_DEPTH = 1.0; var APPARENT_MAXIMUM_DEPTH = 100.0; // this is a depth at which things all seem sufficiently distant -var lastDepthCheckTime = 0; +var lastDepthCheckTime = Date.now(); +var desiredDepth = APPARENT_2D_OVERLAY_DEPTH; +var wasDepth = Reticle.depth; // depth at the time we changed our desired depth +var desiredDepthLastSet = lastDepthCheckTime; // time we changed our desired depth +var TIME_BETWEEN_DEPTH_CHECKS = 100; +var TIME_TO_FADE_DEPTH = 50; Script.update.connect(function(deltaTime) { - var TIME_BETWEEN_DEPTH_CHECKS = 100; - var timeSinceLastDepthCheck = Date.now() - lastDepthCheckTime; + var now = Date.now(); + var timeSinceLastDepthCheck = now - lastDepthCheckTime; if (timeSinceLastDepthCheck > TIME_BETWEEN_DEPTH_CHECKS) { + var newDesiredDepth = desiredDepth; + lastDepthCheckTime = now; var reticlePosition = Reticle.position; // first check the 2D Overlays if (Reticle.pointingAtSystemOverlay || Overlays.getOverlayAtPoint(reticlePosition)) { - Reticle.setDepth(APPARENT_2D_OVERLAY_DEPTH); + newDesiredDepth = APPARENT_2D_OVERLAY_DEPTH; } else { var pickRay = Camera.computePickRay(reticlePosition.x, reticlePosition.y); @@ -37,11 +44,39 @@ Script.update.connect(function(deltaTime) { // If either the overlays or entities intersect, then set the reticle depth to // the distance of intersection if (result.intersects) { - Reticle.setDepth(result.distance); + newDesiredDepth = result.distance; } else { // if nothing intersects... set the depth to some sufficiently large depth - Reticle.setDepth(APPARENT_MAXIMUM_DEPTH); + newDesiredDepth = APPARENT_MAXIMUM_DEPTH; } } + + // If the desired depth has changed, reset our fade start time + if (desiredDepth != newDesiredDepth) { + desiredDepthLastSet = now; + desiredDepth = newDesiredDepth; + wasDepth = Reticle.depth; + } + } + + // move the reticle toward the desired depth + if (desiredDepth != Reticle.depth) { + + // determine the time between now, and when we set our determined our desiredDepth + var elapsed = now - desiredDepthLastSet; + var distanceToFade = desiredDepth - wasDepth; + var percentElapsed = Math.min(1, elapsed / TIME_TO_FADE_DEPTH); + + // special case to handle no fade settings + if (TIME_TO_FADE_DEPTH == 0) { + percentElapsed = 1; + } + var depthDelta = distanceToFade * percentElapsed; + + var newDepth = wasDepth + depthDelta; + if (percentElapsed == 1) { + newDepth = desiredDepth; + } + Reticle.setDepth(newDepth); } }); From 9a01c933221c5a65499e75442668adc08c804474 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Fri, 26 Feb 2016 14:28:27 -0800 Subject: [PATCH 16/19] Avatar: fix for rendering avatar attachments --- interface/src/avatar/Avatar.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 83351d5188..0bd134bef5 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -400,7 +400,7 @@ void Avatar::render(RenderArgs* renderArgs, const glm::vec3& cameraPosition) { frustum = qApp->getDisplayViewFrustum(); } - if (frustum->sphereIntersectsFrustum(getPosition(), boundingRadius)) { + if (!frustum->sphereIntersectsFrustum(getPosition(), boundingRadius)) { endRender(); return; } From e403c990d96f8c174ecb97b82e0ed906b7ed5159 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Sat, 27 Feb 2016 17:13:09 -0800 Subject: [PATCH 17/19] make fade non-linear --- examples/depthReticle.js | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/examples/depthReticle.js b/examples/depthReticle.js index a8afb80df2..4b649f49b6 100644 --- a/examples/depthReticle.js +++ b/examples/depthReticle.js @@ -14,10 +14,9 @@ var APPARENT_2D_OVERLAY_DEPTH = 1.0; var APPARENT_MAXIMUM_DEPTH = 100.0; // this is a depth at which things all seem sufficiently distant var lastDepthCheckTime = Date.now(); var desiredDepth = APPARENT_2D_OVERLAY_DEPTH; -var wasDepth = Reticle.depth; // depth at the time we changed our desired depth -var desiredDepthLastSet = lastDepthCheckTime; // time we changed our desired depth var TIME_BETWEEN_DEPTH_CHECKS = 100; -var TIME_TO_FADE_DEPTH = 50; +var MINIMUM_DEPTH_ADJUST = 0.01; +var NON_LINEAR_DIVISOR = 2; Script.update.connect(function(deltaTime) { var now = Date.now(); @@ -53,30 +52,21 @@ Script.update.connect(function(deltaTime) { // If the desired depth has changed, reset our fade start time if (desiredDepth != newDesiredDepth) { - desiredDepthLastSet = now; desiredDepth = newDesiredDepth; - wasDepth = Reticle.depth; } } // move the reticle toward the desired depth if (desiredDepth != Reticle.depth) { - // determine the time between now, and when we set our determined our desiredDepth - var elapsed = now - desiredDepthLastSet; - var distanceToFade = desiredDepth - wasDepth; - var percentElapsed = Math.min(1, elapsed / TIME_TO_FADE_DEPTH); - - // special case to handle no fade settings - if (TIME_TO_FADE_DEPTH == 0) { - percentElapsed = 1; - } - var depthDelta = distanceToFade * percentElapsed; - - var newDepth = wasDepth + depthDelta; - if (percentElapsed == 1) { + // cut distance between desiredDepth and current depth in half until we're close enough + var distanceToAdjustThisCycle = (desiredDepth - Reticle.depth) / NON_LINEAR_DIVISOR; + if (Math.abs(distanceToAdjustThisCycle) < MINIMUM_DEPTH_ADJUST) { newDepth = desiredDepth; + } else { + newDepth = Reticle.depth + distanceToAdjustThisCycle; } + Reticle.setDepth(newDepth); } }); From 188cf3694b83f36a6808bac3659ff7f1958f2f99 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Sat, 27 Feb 2016 17:31:35 -0800 Subject: [PATCH 18/19] fix rotation of depth reticle --- interface/src/ui/ApplicationCompositor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/ui/ApplicationCompositor.cpp b/interface/src/ui/ApplicationCompositor.cpp index 99f0b4fdc4..59d794d7cb 100644 --- a/interface/src/ui/ApplicationCompositor.cpp +++ b/interface/src/ui/ApplicationCompositor.cpp @@ -301,7 +301,7 @@ void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int // look at borrowed from overlays float elevation = -asinf(relativePosition.y / glm::length(relativePosition)); float azimuth = atan2f(relativePosition.x, relativePosition.z); - glm::quat faceCamera = glm::quat(glm::vec3(elevation, azimuth, 0)) * quat(vec3(0, 0, -1)); // this extra *quat(vec3(0,0,-1)) was required to get the quad to flip this seems like we could optimize + glm::quat faceCamera = glm::quat(glm::vec3(elevation, azimuth, 0)) * quat(vec3(0, -PI, 0)); // this extra *quat(vec3(0,-PI,0)) was required to get the quad to flip this seems like we could optimize Transform transform; transform.setTranslation(relativePosition); From a933935e2d6af70dea252a2707efa2d3ce8d7675 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Sun, 28 Feb 2016 15:13:49 -0800 Subject: [PATCH 19/19] lock mutex in clearEntitiesInernal() --- libraries/entities/src/SimpleEntitySimulation.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/entities/src/SimpleEntitySimulation.cpp b/libraries/entities/src/SimpleEntitySimulation.cpp index 693d80b27d..6bf25f767d 100644 --- a/libraries/entities/src/SimpleEntitySimulation.cpp +++ b/libraries/entities/src/SimpleEntitySimulation.cpp @@ -127,6 +127,7 @@ void SimpleEntitySimulation::changeEntityInternal(EntityItemPointer entity) { } void SimpleEntitySimulation::clearEntitiesInternal() { + QMutexLocker lock(&_mutex); _entitiesWithSimulationOwner.clear(); _entitiesThatNeedSimulationOwner.clear(); }