diff --git a/scripts/system/controllers/grab.js b/scripts/system/controllers/grab.js index 3ce44c2672..f43798e6f1 100644 --- a/scripts/system/controllers/grab.js +++ b/scripts/system/controllers/grab.js @@ -14,9 +14,12 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +/* global MyAvatar, Entities, Script, Camera, Vec3, Reticle, Overlays, getEntityCustomData, Messages, Quat, Controller */ + + (function() { // BEGIN LOCAL_SCOPE -Script.include("../libraries/utils.js"); +Script.include("/~/system/libraries/utils.js"); var MAX_SOLID_ANGLE = 0.01; // objects that appear smaller than this can't be grabbed var ZERO_VEC3 = { @@ -31,11 +34,6 @@ var IDENTITY_QUAT = { w: 0 }; var GRABBABLE_DATA_KEY = "grabbableKey"; // shared with handControllerGrab.js -var GRAB_USER_DATA_KEY = "grabKey"; // shared with handControllerGrab.js - -var MSECS_PER_SEC = 1000.0; -var HEART_BEAT_INTERVAL = 5 * MSECS_PER_SEC; -var HEART_BEAT_TIMEOUT = 15 * MSECS_PER_SEC; var DEFAULT_GRABBABLE_DATA = { grabbable: true, @@ -74,7 +72,7 @@ function entityIsGrabbedByOther(entityID) { for (var actionIndex = 0; actionIndex < actionIDs.length; actionIndex++) { var actionID = actionIDs[actionIndex]; var actionArguments = Entities.getActionArguments(entityID, actionID); - var tag = actionArguments["tag"]; + var tag = actionArguments.tag; if (tag == getTag()) { // we see a grab-*uuid* shaped tag, but it's our tag, so that's okay. continue; @@ -155,14 +153,14 @@ Mouse.prototype.startDrag = function(position) { y: position.y }; this.startRotateDrag(); -} +}; Mouse.prototype.updateDrag = function(position) { this.current = { x: position.x, y: position.y }; -} +}; Mouse.prototype.startRotateDrag = function() { this.previous = { @@ -174,7 +172,7 @@ Mouse.prototype.startRotateDrag = function() { y: this.current.y }; this.cursorRestore = Reticle.getPosition(); -} +}; Mouse.prototype.getDrag = function() { var delta = { @@ -186,7 +184,7 @@ Mouse.prototype.getDrag = function() { y: this.current.y }; return delta; -} +}; Mouse.prototype.restoreRotateCursor = function() { Reticle.setPosition(this.cursorRestore); @@ -194,7 +192,7 @@ Mouse.prototype.restoreRotateCursor = function() { x: this.rotateStart.x, y: this.rotateStart.y }; -} +}; var mouse = new Mouse(); @@ -218,13 +216,13 @@ Beacon.prototype.enable = function() { Overlays.editOverlay(this.overlayID, { visible: true }); -} +}; Beacon.prototype.disable = function() { Overlays.editOverlay(this.overlayID, { visible: false }); -} +}; Beacon.prototype.updatePosition = function(position) { Overlays.editOverlay(this.overlayID, { @@ -240,7 +238,7 @@ Beacon.prototype.updatePosition = function(position) { z: position.z } }); -} +}; var beacon = new Beacon(); @@ -262,7 +260,7 @@ function Grabber() { this.planeNormal = ZERO_VEC3; // maxDistance is a function of the size of the object. - this.maxDistance; + this.maxDistance = 0; // mode defines the degrees of freedom of the grab target positions // relative to startPosition options include: @@ -281,8 +279,8 @@ function Grabber() { z: 0 }; - this.targetPosition; - this.targetRotation; + this.targetPosition = null; + this.targetRotation = null; this.liftKey = false; // SHIFT this.rotateKey = false; // CONTROL @@ -318,7 +316,7 @@ Grabber.prototype.computeNewGrabPlane = function() { var xzOffset = Vec3.subtract(this.pointOnPlane, Camera.getPosition()); xzOffset.y = 0; this.xzDistanceToGrab = Vec3.length(xzOffset); -} +}; Grabber.prototype.pressEvent = function(event) { if (!enabled) { @@ -353,10 +351,8 @@ Grabber.prototype.pressEvent = function(event) { mouse.startDrag(event); - this.lastHeartBeat = 0; - var clickedEntity = pickResults.entityID; - var entityProperties = Entities.getEntityProperties(clickedEntity) + var entityProperties = Entities.getEntityProperties(clickedEntity); this.startPosition = entityProperties.position; this.lastRotation = entityProperties.rotation; var cameraPosition = Camera.getPosition(); @@ -369,7 +365,7 @@ Grabber.prototype.pressEvent = function(event) { return; } - this.activateEntity(clickedEntity, entityProperties); + // this.activateEntity(clickedEntity, entityProperties); this.isGrabbing = true; this.entityID = clickedEntity; @@ -405,10 +401,9 @@ Grabber.prototype.pressEvent = function(event) { grabbedEntity: this.entityID })); - // TODO: play sounds again when we aren't leaking AudioInjector threads //Audio.playSound(grabSound, { position: entityProperties.position, volume: VOLUME }); -} +}; Grabber.prototype.releaseEvent = function(event) { if (event.isLeftButton!==true ||event.isRightButton===true || event.isMiddleButton===true) { @@ -416,9 +411,11 @@ Grabber.prototype.releaseEvent = function(event) { } if (this.isGrabbing) { - this.deactivateEntity(this.entityID); - this.isGrabbing = false - Entities.deleteAction(this.entityID, this.actionID); + // this.deactivateEntity(this.entityID); + this.isGrabbing = false; + if (this.actionID) { + Entities.deleteAction(this.entityID, this.actionID); + } this.actionID = null; beacon.disable(); @@ -432,32 +429,17 @@ Grabber.prototype.releaseEvent = function(event) { joint: "mouse" })); - // TODO: play sounds again when we aren't leaking AudioInjector threads //Audio.playSound(releaseSound, { position: entityProperties.position, volume: VOLUME }); } -} - - -Grabber.prototype.heartBeat = function(entityID) { - var now = Date.now(); - if (now - this.lastHeartBeat > HEART_BEAT_INTERVAL) { - var data = getEntityCustomData(GRAB_USER_DATA_KEY, entityID, {}); - data["heartBeat"] = now; - setEntityCustomData(GRAB_USER_DATA_KEY, entityID, data); - this.lastHeartBeat = now; - } }; - Grabber.prototype.moveEvent = function(event) { if (!this.isGrabbing) { return; } mouse.updateDrag(event); - this.heartBeat(this.entityID); - // see if something added/restored gravity var entityProperties = Entities.getEntityProperties(this.entityID); if (Vec3.length(entityProperties.gravity) !== 0.0) { @@ -486,8 +468,8 @@ Grabber.prototype.moveEvent = function(event) { //var qZero = this.lastRotation; this.lastRotation = Quat.multiply(deltaQ, this.lastRotation); - var distanceToCamera = Vec3.length(Vec3.subtract(this.currentPosition, cameraPosition)); - var angularTimeScale = distanceGrabTimescale(this.mass, distanceToCamera); + var distanceToCameraR = Vec3.length(Vec3.subtract(this.currentPosition, cameraPosition)); + var angularTimeScale = distanceGrabTimescale(this.mass, distanceToCameraR); actionArgs = { targetRotation: this.lastRotation, @@ -527,8 +509,8 @@ Grabber.prototype.moveEvent = function(event) { } this.targetPosition = Vec3.subtract(newPointOnPlane, this.offset); - var distanceToCamera = Vec3.length(Vec3.subtract(this.targetPosition, cameraPosition)); - var linearTimeScale = distanceGrabTimescale(this.mass, distanceToCamera); + var distanceToCameraL = Vec3.length(Vec3.subtract(this.targetPosition, cameraPosition)); + var linearTimeScale = distanceGrabTimescale(this.mass, distanceToCameraL); actionArgs = { targetPosition: this.targetPosition, @@ -537,7 +519,6 @@ Grabber.prototype.moveEvent = function(event) { ttl: ACTION_TTL }; - beacon.updatePosition(this.targetPosition); } @@ -548,7 +529,7 @@ Grabber.prototype.moveEvent = function(event) { } else { Entities.updateAction(this.entityID, this.actionID, actionArgs); } -} +}; Grabber.prototype.keyReleaseEvent = function(event) { if (event.text === "SHIFT") { @@ -558,7 +539,7 @@ Grabber.prototype.keyReleaseEvent = function(event) { this.rotateKey = false; } this.computeNewGrabPlane(); -} +}; Grabber.prototype.keyPressEvent = function(event) { if (event.text === "SHIFT") { @@ -568,49 +549,8 @@ Grabber.prototype.keyPressEvent = function(event) { this.rotateKey = true; } this.computeNewGrabPlane(); -} - -Grabber.prototype.activateEntity = function(entityID, grabbedProperties) { - var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, entityID, DEFAULT_GRABBABLE_DATA); - var invertSolidWhileHeld = grabbableData["invertSolidWhileHeld"]; - var data = getEntityCustomData(GRAB_USER_DATA_KEY, entityID, {}); - data["activated"] = true; - data["avatarId"] = MyAvatar.sessionUUID; - data["refCount"] = data["refCount"] ? data["refCount"] + 1 : 1; - // zero gravity and set collisionless to true, but in a way that lets us put them back, after all grabs are done - if (data["refCount"] == 1) { - data["gravity"] = grabbedProperties.gravity; - data["collisionless"] = grabbedProperties.collisionless; - data["dynamic"] = grabbedProperties.dynamic; - var whileHeldProperties = {gravity: {x:0, y:0, z:0}}; - if (invertSolidWhileHeld) { - whileHeldProperties["collisionless"] = ! grabbedProperties.collisionless; - } - Entities.editEntity(entityID, whileHeldProperties); - } - setEntityCustomData(GRAB_USER_DATA_KEY, entityID, data); }; -Grabber.prototype.deactivateEntity = function(entityID) { - var data = getEntityCustomData(GRAB_USER_DATA_KEY, entityID, {}); - if (data && data["refCount"]) { - data["refCount"] = data["refCount"] - 1; - if (data["refCount"] < 1) { - Entities.editEntity(entityID, { - gravity: data["gravity"], - collisionless: data["collisionless"], - dynamic: data["dynamic"] - }); - data = null; - } - } else { - data = null; - } - setEntityCustomData(GRAB_USER_DATA_KEY, entityID, data); -}; - - - var grabber = new Grabber(); function pressEvent(event) { @@ -646,7 +586,7 @@ function editEvent(channel, message, sender, localOnly) { try { var data = JSON.parse(message); if ("enabled" in data) { - enabled = !data["enabled"]; + enabled = !data.enabled; } } catch(e) { } diff --git a/scripts/system/controllers/handControllerGrab.js b/scripts/system/controllers/handControllerGrab.js index a0ac0566d9..3458108f54 100644 --- a/scripts/system/controllers/handControllerGrab.js +++ b/scripts/system/controllers/handControllerGrab.js @@ -2997,7 +2997,6 @@ function MyController(hand) { children.forEach(function(childID) { if (childID !== _this.stylus) { - print(childID + " vs " + _this.stylus); // we appear to be holding something and this script isn't in a state that would be holding something. // unhook it. if we previously took note of this entity's parent, put it back where it was. This // works around some problems that happen when more than one hand or avatar is passing something around. diff --git a/scripts/system/libraries/WebTablet.js b/scripts/system/libraries/WebTablet.js index 7f7b958e43..31d3d91f54 100644 --- a/scripts/system/libraries/WebTablet.js +++ b/scripts/system/libraries/WebTablet.js @@ -7,12 +7,11 @@ // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -/* global getControllerWorldLocation, setEntityCustomData, Tablet, WebTablet:true */ +/* global getControllerWorldLocation, setEntityCustomData, Tablet, WebTablet:true, HMD, Settings, Script, Vec3, Quat, MyAvatar, Entities, Overlays, Camera, Messages */ Script.include(Script.resolvePath("../libraries/utils.js")); Script.include(Script.resolvePath("../libraries/controllers.js")); -var RAD_TO_DEG = 180 / Math.PI; var X_AXIS = {x: 1, y: 0, z: 0}; var Y_AXIS = {x: 0, y: 1, z: 0}; var DEFAULT_DPI = 32; @@ -91,6 +90,7 @@ WebTablet = function (url, width, dpi, hand, clientOnly) { // compute position, rotation & parentJointIndex of the tablet this.calculateTabletAttachmentProperties(hand, tabletProperties); + this.cleanUpOldTablets(); this.tabletEntityID = Entities.addEntity(tabletProperties, clientOnly); var WEB_ENTITY_Z_OFFSET = -0.0125; @@ -219,6 +219,27 @@ WebTablet.prototype.register = function() { Messages.messageReceived.connect(this.receive); }; +WebTablet.prototype.cleanUpOldTabletsOnJoint = function(jointIndex) { + var children = Entities.getChildrenIDsOfJoint(MyAvatar.sessionUUID, jointIndex); + print("cleanup " + children); + children.forEach(function(childID) { + var props = Entities.getEntityProperties(childID, ["name"]); + if (props.name == "WebTablet Tablet") { + print("cleaning up " + props.name); + Entities.deleteEntity(childID); + } else { + print("not cleaning up " + props.name); + } + }); +}; + +WebTablet.prototype.cleanUpOldTablets = function() { + this.cleanUpOldTabletsOnJoint(-1); + this.cleanUpOldTabletsOnJoint(SENSOR_TO_ROOM_MATRIX); + this.cleanUpOldTabletsOnJoint(CAMERA_MATRIX); + this.cleanUpOldTabletsOnJoint(65529); +} + WebTablet.prototype.unregister = function() { Messages.unsubscribe("home"); Messages.messageReceived.disconnect(this.receive);