clean up grab.js. provide a way to delete old tablets that got saved into Settings on exit

This commit is contained in:
Seth Alves 2017-01-19 11:34:38 -08:00
parent 99de46cb27
commit 41ddfbfd27
3 changed files with 55 additions and 95 deletions

View file

@ -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) {
}

View file

@ -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.

View file

@ -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);