reference count grabs on an entity

This commit is contained in:
Seth Alves 2015-10-05 14:15:38 -07:00
parent 635c83dad1
commit 7f8411d947
2 changed files with 70 additions and 45 deletions

View file

@ -79,10 +79,8 @@ var STATE_NEAR_GRABBING_NON_COLLIDING = 6;
var STATE_CONTINUE_NEAR_GRABBING_NON_COLLIDING = 7;
var STATE_RELEASE = 8;
var GRAB_USER_DATA_KEY = "grabKey";
var GRABBABLE_DATA_KEY = "grabbableKey";
var GRAVITY_USER_DATA_KEY = "preGrabGravity";
var IGNORE_FOR_COLLISIONS_USER_DATA_KEY = "preGrabIgnoreForCollisions";
var GRABBABLE_DATA_KEY = "grabbableKey"; // shared with grab.js
var GRAB_USER_DATA_KEY = "grabKey"; // shared with grab.js
function getTag() {
return "grab-" + MyAvatar.sessionUUID;
@ -314,7 +312,8 @@ function MyController(hand, triggerAction) {
var handControllerPosition = Controller.getSpatialControlPosition(this.palm);
var handRotation = Quat.multiply(MyAvatar.orientation, Controller.getSpatialControlRawRotation(this.palm));
var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, ["position", "rotation"]);
var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, ["position", "rotation",
"gravity", "ignoreForCollisions"]);
// add the action and initialize some variables
this.currentObjectPosition = grabbedProperties.position;
@ -338,7 +337,7 @@ function MyController(hand, triggerAction) {
if (this.actionID !== null) {
this.setState(STATE_CONTINUE_DISTANCE_HOLDING);
this.activateEntity(this.grabbedEntity);
this.activateEntity(this.grabbedEntity, grabbedProperties);
if (this.hand === RIGHT_HAND) {
Entities.callEntityMethod(this.grabbedEntity, "setRightHand");
} else {
@ -441,10 +440,9 @@ function MyController(hand, triggerAction) {
this.lineOff();
this.activateEntity(this.grabbedEntity);
var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity,
["position", "rotation", "gravity", "ignoreForCollisions"]);
this.activateEntity(this.grabbedEntity, grabbedProperties);
var handRotation = this.getHandRotation();
var handPosition = this.getHandPosition();
@ -456,14 +454,6 @@ function MyController(hand, triggerAction) {
var offset = Vec3.subtract(currentObjectPosition, handPosition);
var offsetPosition = Vec3.multiplyQbyV(Quat.inverse(Quat.multiply(handRotation, offsetRotation)), offset);
// zero gravity and set ignoreForCollisions to true, but in a way that lets us put them back, after all grabs are done
this.saveGravity = getEntityCustomData(GRAVITY_USER_DATA_KEY, this.grabbedEntity, grabbedProperties.gravity);
setEntityCustomData(GRAVITY_USER_DATA_KEY, this.grabbedEntity, this.saveGravity);
this.saveIgnoreForCollisions = getEntityCustomData(IGNORE_FOR_COLLISIONS_USER_DATA_KEY, this.grabbedEntity,
grabbedProperties.ignoreForCollisions);
setEntityCustomData(IGNORE_FOR_COLLISIONS_USER_DATA_KEY, this.grabbedEntity, this.saveIgnoreForCollisions);
Entities.editEntity(this.grabbedEntity, {gravity: {x:0, y:0, z:0}, ignoreForCollisions: true});
this.actionID = NULL_ACTION_ID;
this.actionID = Entities.addAction("kinematic-hold", this.grabbedEntity, {
hand: this.hand === RIGHT_HAND ? "right" : "left",
@ -492,12 +482,7 @@ function MyController(hand, triggerAction) {
this.continueNearGrabbing = function() {
if (this.triggerSmoothedReleased()) {
this.setState(STATE_RELEASE);
Entities.editEntity(this.grabbedEntity,
{gravity: this.saveGravity, ignoreForCollisions: this.saveIgnoreForCollisions});
setEntityCustomData(IGNORE_FOR_COLLISIONS_USER_DATA_KEY, this.grabbedEntity, null);
setEntityCustomData(GRAVITY_USER_DATA_KEY, this.grabbedEntity, null);
return;
}
@ -656,20 +641,35 @@ function MyController(hand, triggerAction) {
this.release();
};
this.activateEntity = function() {
var data = {
activated: true,
avatarId: MyAvatar.sessionUUID
};
setEntityCustomData(GRAB_USER_DATA_KEY, this.grabbedEntity, data);
this.activateEntity = function(entityID, grabbedProperties) {
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 ignoreForCollisions 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["ignoreForCollisions"] = grabbedProperties.ignoreForCollisions;
Entities.editEntity(entityID, {gravity: {x:0, y:0, z:0}, ignoreForCollisions: true});
}
setEntityCustomData(GRAB_USER_DATA_KEY, entityID, data);
};
this.deactivateEntity = function() {
var data = {
activated: false,
avatarId: null
};
setEntityCustomData(GRAB_USER_DATA_KEY, this.grabbedEntity, data);
this.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"],
ignoreForCollisions: data["ignoreForCollisions"]
});
data = null;
}
} else {
data = null;
}
setEntityCustomData(GRAB_USER_DATA_KEY, entityID, data);
};
}

View file

@ -26,7 +26,8 @@ var IDENTITY_QUAT = {
z: 0,
w: 0
};
var GRABBABLE_DATA_KEY = "grabbableKey";
var GRABBABLE_DATA_KEY = "grabbableKey"; // shared with handControllerGrab.js
var GRAB_USER_DATA_KEY = "grabKey"; // shared with handControllerGrab.js
var defaultGrabbableData = {
grabbable: true
@ -247,7 +248,6 @@ Grabber = function() {
this.currentPosition = ZERO_VEC3;
this.planeNormal = ZERO_VEC3;
this.originalGravity = ZERO_VEC3;
// maxDistance is a function of the size of the object.
this.maxDistance;
@ -346,14 +346,11 @@ Grabber.prototype.pressEvent = function(event) {
return;
}
Entities.editEntity(clickedEntity, {
gravity: ZERO_VEC3
});
this.activateEntity(clickedEntity, entityProperties);
this.isGrabbing = true;
this.entityID = clickedEntity;
this.currentPosition = entityProperties.position;
this.originalGravity = entityProperties.gravity;
this.targetPosition = {
x: this.startPosition.x,
y: this.startPosition.y,
@ -379,12 +376,7 @@ Grabber.prototype.pressEvent = function(event) {
Grabber.prototype.releaseEvent = function() {
if (this.isGrabbing) {
if (Vec3.length(this.originalGravity) != 0) {
Entities.editEntity(this.entityID, {
gravity: this.originalGravity
});
}
this.deactivateEntity(this.entityID);
this.isGrabbing = false
Entities.deleteAction(this.entityID, this.actionID);
this.actionID = null;
@ -503,6 +495,39 @@ Grabber.prototype.keyPressEvent = function(event) {
this.computeNewGrabPlane();
}
Grabber.prototype.activateEntity = function(entityID, grabbedProperties) {
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 ignoreForCollisions 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["ignoreForCollisions"] = grabbedProperties.ignoreForCollisions;
Entities.editEntity(entityID, {gravity: {x:0, y:0, z:0}, ignoreForCollisions: true});
}
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"],
ignoreForCollisions: data["ignoreForCollisions"]
});
data = null;
}
} else {
data = null;
}
setEntityCustomData(GRAB_USER_DATA_KEY, entityID, data);
};
var grabber = new Grabber();
function pressEvent(event) {