bumper is now an equip toggle

This commit is contained in:
Seth Alves 2015-11-17 09:51:52 -08:00
parent 36af315e5d
commit b062d23f61
3 changed files with 105 additions and 16 deletions

View file

@ -28,6 +28,8 @@ var TRIGGER_SMOOTH_RATIO = 0.1; // 0.0 disables smoothing of trigger value
var TRIGGER_ON_VALUE = 0.4; var TRIGGER_ON_VALUE = 0.4;
var TRIGGER_OFF_VALUE = 0.15; var TRIGGER_OFF_VALUE = 0.15;
var BUMPER_ON_VALUE = 0.5;
// //
// distant manipulation // distant manipulation
// //
@ -106,6 +108,11 @@ var STATE_CONTINUE_NEAR_TRIGGER = 7;
var STATE_FAR_TRIGGER = 8; var STATE_FAR_TRIGGER = 8;
var STATE_CONTINUE_FAR_TRIGGER = 9; var STATE_CONTINUE_FAR_TRIGGER = 9;
var STATE_RELEASE = 10; var STATE_RELEASE = 10;
var STATE_EQUIP_SEARCHING = 11;
var STATE_EQUIP = 12
var STATE_CONTINUE_EQUIP_BD = 13; // equip while bumper is still held down
var STATE_CONTINUE_EQUIP = 14;
var STATE_WAITING_FOR_BUMPER_RELEASE = 15;
function stateToName(state) { function stateToName(state) {
@ -132,6 +139,16 @@ function stateToName(state) {
return "continue_far_trigger"; return "continue_far_trigger";
case STATE_RELEASE: case STATE_RELEASE:
return "release"; return "release";
case STATE_EQUIP_SEARCHING:
return "equip_searching";
case STATE_EQUIP:
return "equip";
case STATE_CONTINUE_EQUIP_BD:
return "continue_equip_bd";
case STATE_CONTINUE_EQUIP:
return "continue_equip";
case STATE_WAITING_FOR_BUMPER_RELEASE:
return "waiting_for_bumper_release";
} }
return "unknown"; return "unknown";
@ -182,6 +199,7 @@ function MyController(hand) {
this.pointer = null; // entity-id of line object this.pointer = null; // entity-id of line object
this.triggerValue = 0; // rolling average of trigger value this.triggerValue = 0; // rolling average of trigger value
this.rawTriggerValue = 0; this.rawTriggerValue = 0;
this.rawBumperValue = 0;
this.offsetPosition = { x: 0.0, y: 0.0, z: 0.0 }; this.offsetPosition = { x: 0.0, y: 0.0, z: 0.0 };
this.offsetRotation = { x: 0.0, y: 0.0, z: 0.0, w: 1.0 }; this.offsetRotation = { x: 0.0, y: 0.0, z: 0.0, w: 1.0 };
@ -200,6 +218,9 @@ function MyController(hand) {
case STATE_SEARCHING: case STATE_SEARCHING:
this.search(); this.search();
break; break;
case STATE_EQUIP_SEARCHING:
this.search();
break;
case STATE_DISTANCE_HOLDING: case STATE_DISTANCE_HOLDING:
this.distanceHolding(); this.distanceHolding();
break; break;
@ -209,7 +230,15 @@ function MyController(hand) {
case STATE_NEAR_GRABBING: case STATE_NEAR_GRABBING:
this.nearGrabbing(); this.nearGrabbing();
break; break;
case STATE_EQUIP:
this.nearGrabbing();
break;
case STATE_WAITING_FOR_BUMPER_RELEASE:
this.waitingForBumperRelease();
break;
case STATE_CONTINUE_NEAR_GRABBING: case STATE_CONTINUE_NEAR_GRABBING:
case STATE_CONTINUE_EQUIP_BD:
case STATE_CONTINUE_EQUIP:
this.continueNearGrabbing(); this.continueNearGrabbing();
break; break;
case STATE_NEAR_TRIGGER: case STATE_NEAR_TRIGGER:
@ -281,10 +310,15 @@ function MyController(hand) {
this.pointer = null; this.pointer = null;
}; };
this.eitherTrigger = function (value) { this.triggerPress = function (value) {
_this.rawTriggerValue = value; _this.rawTriggerValue = value;
}; };
this.bumperPress = function (value) {
_this.rawBumperValue = value;
};
this.updateSmoothedTrigger = function () { this.updateSmoothedTrigger = function () {
var triggerValue = this.rawTriggerValue; var triggerValue = this.rawTriggerValue;
// smooth out trigger value // smooth out trigger value
@ -305,23 +339,37 @@ function MyController(hand) {
return triggerValue > TRIGGER_ON_VALUE; return triggerValue > TRIGGER_ON_VALUE;
}; };
this.bumperSqueezed = function() {
return _this.rawBumperValue > BUMPER_ON_VALUE;
}
this.bumperReleased = function() {
return _this.rawBumperValue < BUMPER_ON_VALUE;
}
this.off = function() { this.off = function() {
if (this.triggerSmoothedSqueezed()) { if (this.triggerSmoothedSqueezed()) {
this.lastPickTime = 0; this.lastPickTime = 0;
this.setState(STATE_SEARCHING); this.setState(STATE_SEARCHING);
return; return;
} }
if (this.bumperSqueezed()) {
this.lastPickTime = 0;
this.setState(STATE_EQUIP_SEARCHING);
return;
}
} }
this.search = function() { this.search = function() {
this.grabbedEntity = null; this.grabbedEntity = null;
//if this hand is the one that's disabled, we don't want to search for anything at all // if this hand is the one that's disabled, we don't want to search for anything at all
if (this.hand === disabledHand) { if (this.hand === disabledHand) {
return; return;
} }
if (this.triggerSmoothedReleased()) { if (this.state == STATE_SEARCHING ? this.triggerSmoothedReleased() : this.bumperReleased()) {
this.setState(STATE_RELEASE); this.setState(STATE_RELEASE);
return; return;
} }
@ -398,7 +446,7 @@ function MyController(hand) {
return; return;
} else if (!intersection.properties.locked) { } else if (!intersection.properties.locked) {
this.grabbedEntity = intersection.entityID; this.grabbedEntity = intersection.entityID;
this.setState(STATE_NEAR_GRABBING); this.setState(this.state == STATE_SEARCHING ? STATE_NEAR_GRABBING : STATE_EQUIP)
return; return;
} }
} else if (! entityIsGrabbedByOther(intersection.entityID)) { } else if (! entityIsGrabbedByOther(intersection.entityID)) {
@ -407,8 +455,14 @@ function MyController(hand) {
&& !intersection.properties.locked) { && !intersection.properties.locked) {
// the hand is far from the intersected object. go into distance-holding mode // the hand is far from the intersected object. go into distance-holding mode
this.grabbedEntity = intersection.entityID; this.grabbedEntity = intersection.entityID;
this.setState(STATE_DISTANCE_HOLDING); if (typeof grabbableData.spatialKey !== 'undefined' && this.state == STATE_EQUIP_SEARCHING) {
return; // if a distance pick in equip mode hits something with a spatialKey, equip it
this.setState(STATE_EQUIP);
return;
} else if (this.state == STATE_SEARCHING) {
this.setState(STATE_DISTANCE_HOLDING);
return;
}
} else if (grabbableData.wantsTrigger) { } else if (grabbableData.wantsTrigger) {
this.grabbedEntity = intersection.entityID; this.grabbedEntity = intersection.entityID;
this.setState(STATE_FAR_TRIGGER); this.setState(STATE_FAR_TRIGGER);
@ -434,6 +488,7 @@ function MyController(hand) {
var nearbyEntities = Entities.findEntities(handPosition, GRAB_RADIUS); var nearbyEntities = Entities.findEntities(handPosition, GRAB_RADIUS);
var minDistance = PICK_MAX_DISTANCE; var minDistance = PICK_MAX_DISTANCE;
var i, props, distance, grabbableData; var i, props, distance, grabbableData;
this.grabbedEntity = null;
for (i = 0; i < nearbyEntities.length; i++) { for (i = 0; i < nearbyEntities.length; i++) {
var grabbableDataForCandidate = var grabbableDataForCandidate =
getEntityCustomData(GRABBABLE_DATA_KEY, nearbyEntities[i], DEFAULT_GRABBABLE_DATA); getEntityCustomData(GRABBABLE_DATA_KEY, nearbyEntities[i], DEFAULT_GRABBABLE_DATA);
@ -490,7 +545,7 @@ function MyController(hand) {
this.setState(STATE_NEAR_TRIGGER); this.setState(STATE_NEAR_TRIGGER);
return; return;
} else if (!props.locked && props.collisionsWillMove) { } else if (!props.locked && props.collisionsWillMove) {
this.setState(STATE_NEAR_GRABBING); this.setState(this.state == STATE_SEARCHING ? STATE_NEAR_GRABBING : STATE_EQUIP)
return; return;
} }
}; };
@ -634,13 +689,12 @@ function MyController(hand) {
return; return;
} }
if (this.triggerSmoothedReleased()) { if (this.state == STATE_NEAR_GRABBING && this.triggerSmoothedReleased()) {
this.setState(STATE_RELEASE); this.setState(STATE_RELEASE);
Entities.callEntityMethod(this.grabbedEntity, "releaseGrab"); Entities.callEntityMethod(this.grabbedEntity, "releaseGrab");
return; return;
} }
this.lineOff(); this.lineOff();
var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, GRABBABLE_PROPERTIES); var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, GRABBABLE_PROPERTIES);
@ -686,7 +740,7 @@ function MyController(hand) {
this.actionID = null; this.actionID = null;
} else { } else {
this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC); this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC);
this.setState(STATE_CONTINUE_NEAR_GRABBING); this.setState(this.state == STATE_NEAR_GRABBING ? STATE_CONTINUE_NEAR_GRABBING : STATE_CONTINUE_EQUIP_BD)
if (this.hand === RIGHT_HAND) { if (this.hand === RIGHT_HAND) {
Entities.callEntityMethod(this.grabbedEntity, "setRightHand"); Entities.callEntityMethod(this.grabbedEntity, "setRightHand");
} else { } else {
@ -696,17 +750,26 @@ function MyController(hand) {
} }
this.currentHandControllerTipPosition = (this.hand === RIGHT_HAND) ? MyAvatar.rightHandTipPosition : MyAvatar.leftHandTipPosition;; this.currentHandControllerTipPosition =
(this.hand === RIGHT_HAND) ? MyAvatar.rightHandTipPosition : MyAvatar.leftHandTipPosition;
this.currentObjectTime = Date.now(); this.currentObjectTime = Date.now();
}; };
this.continueNearGrabbing = function() { this.continueNearGrabbing = function() {
if (this.triggerSmoothedReleased()) { if (this.state == STATE_CONTINUE_NEAR_GRABBING && this.triggerSmoothedReleased()) {
this.setState(STATE_RELEASE); this.setState(STATE_RELEASE);
Entities.callEntityMethod(this.grabbedEntity, "releaseGrab"); Entities.callEntityMethod(this.grabbedEntity, "releaseGrab");
return; return;
} }
if (this.state == STATE_CONTINUE_EQUIP_BD && this.bumperReleased()) {
this.setState(STATE_CONTINUE_EQUIP);
return;
}
if (this.state == STATE_CONTINUE_EQUIP && this.bumperSqueezed()) {
this.setState(STATE_WAITING_FOR_BUMPER_RELEASE);
return;
}
// Keep track of the fingertip velocity to impart when we release the object. // Keep track of the fingertip velocity to impart when we release the object.
// Note that the idea of using a constant 'tip' velocity regardless of the // Note that the idea of using a constant 'tip' velocity regardless of the
@ -740,6 +803,13 @@ function MyController(hand) {
} }
}; };
this.waitingForBumperRelease = function() {
if (this.bumperReleased()) {
this.setState(STATE_RELEASE);
Entities.callEntityMethod(this.grabbedEntity, "releaseGrab");
}
}
this.nearTrigger = function() { this.nearTrigger = function() {
if (this.triggerSmoothedReleased()) { if (this.triggerSmoothedReleased()) {
this.setState(STATE_RELEASE); this.setState(STATE_RELEASE);
@ -919,6 +989,7 @@ function MyController(hand) {
} }
Entities.editEntity(entityID, whileHeldProperties); Entities.editEntity(entityID, whileHeldProperties);
} }
setEntityCustomData(GRAB_USER_DATA_KEY, entityID, data); setEntityCustomData(GRAB_USER_DATA_KEY, entityID, data);
return data; return data;
}; };
@ -948,8 +1019,12 @@ var leftController = new MyController(LEFT_HAND);
var MAPPING_NAME = "com.highfidelity.handControllerGrab"; var MAPPING_NAME = "com.highfidelity.handControllerGrab";
var mapping = Controller.newMapping(MAPPING_NAME); var mapping = Controller.newMapping(MAPPING_NAME);
mapping.from([Controller.Standard.RB, Controller.Standard.RT]).peek().to(rightController.eitherTrigger); mapping.from([Controller.Standard.RT]).peek().to(rightController.triggerPress);
mapping.from([Controller.Standard.LB, Controller.Standard.LT]).peek().to(leftController.eitherTrigger); mapping.from([Controller.Standard.LT]).peek().to(leftController.triggerPress);
mapping.from([Controller.Standard.RB]).peek().to(rightController.bumperPress);
mapping.from([Controller.Standard.LB]).peek().to(leftController.bumperPress);
Controller.enableMapping(MAPPING_NAME); Controller.enableMapping(MAPPING_NAME);

View file

@ -11,6 +11,12 @@ vec3toStr = function(v, digits) {
return "{ " + v.x.toFixed(digits) + ", " + v.y.toFixed(digits) + ", " + v.z.toFixed(digits)+ " }"; return "{ " + v.x.toFixed(digits) + ", " + v.y.toFixed(digits) + ", " + v.z.toFixed(digits)+ " }";
} }
quatToStr = function(q, digits) {
if (!digits) { digits = 3; }
return "{ " + q.w.toFixed(digits) + ", " + q.x.toFixed(digits) + ", " +
q.y.toFixed(digits) + ", " + q.z.toFixed(digits)+ " }";
}
vec3equal = function(v0, v1) { vec3equal = function(v0, v1) {
return (v0.x == v1.x) && (v0.y == v1.y) && (v0.z == v1.z); return (v0.x == v1.x) && (v0.y == v1.y) && (v0.z == v1.z);
} }
@ -51,7 +57,7 @@ addLine = function(origin, vector, color) {
// FIXME fetch from a subkey of user data to support non-destructive modifications // FIXME fetch from a subkey of user data to support non-destructive modifications
setEntityUserData = function(id, data) { setEntityUserData = function(id, data) {
var json = JSON.stringify(data) var json = JSON.stringify(data)
Entities.editEntity(id, { userData: json }); Entities.editEntity(id, { userData: json });
} }
// FIXME do non-destructive modification of the existing user data // FIXME do non-destructive modification of the existing user data
@ -60,7 +66,7 @@ getEntityUserData = function(id) {
var properties = Entities.getEntityProperties(id, "userData"); var properties = Entities.getEntityProperties(id, "userData");
if (properties.userData) { if (properties.userData) {
try { try {
results = JSON.parse(properties.userData); results = JSON.parse(properties.userData);
} catch(err) { } catch(err) {
logDebug(err); logDebug(err);
logDebug(properties.userData); logDebug(properties.userData);

View file

@ -704,6 +704,14 @@ void EntityTree::fixupTerseEditLogging(EntityItemProperties& properties, QList<Q
changedProperties[index] = QString("locked:") + changeHint; changedProperties[index] = QString("locked:") + changeHint;
} }
} }
if (properties.userDataChanged()) {
int index = changedProperties.indexOf("userData");
if (index >= 0) {
QString changeHint = properties.getUserData();
changedProperties[index] = QString("userData:") + changeHint;
}
}
} }
int EntityTree::processEditPacketData(NLPacket& packet, const unsigned char* editData, int maxLength, int EntityTree::processEditPacketData(NLPacket& packet, const unsigned char* editData, int maxLength,