mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 03:44:02 +02:00
bumper is now an equip toggle
This commit is contained in:
parent
36af315e5d
commit
b062d23f61
3 changed files with 105 additions and 16 deletions
|
@ -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_OFF_VALUE = 0.15;
|
||||
|
||||
var BUMPER_ON_VALUE = 0.5;
|
||||
|
||||
//
|
||||
// distant manipulation
|
||||
//
|
||||
|
@ -106,6 +108,11 @@ var STATE_CONTINUE_NEAR_TRIGGER = 7;
|
|||
var STATE_FAR_TRIGGER = 8;
|
||||
var STATE_CONTINUE_FAR_TRIGGER = 9;
|
||||
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) {
|
||||
|
@ -132,6 +139,16 @@ function stateToName(state) {
|
|||
return "continue_far_trigger";
|
||||
case STATE_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";
|
||||
|
@ -182,6 +199,7 @@ function MyController(hand) {
|
|||
this.pointer = null; // entity-id of line object
|
||||
this.triggerValue = 0; // rolling average of trigger value
|
||||
this.rawTriggerValue = 0;
|
||||
this.rawBumperValue = 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 };
|
||||
|
@ -200,6 +218,9 @@ function MyController(hand) {
|
|||
case STATE_SEARCHING:
|
||||
this.search();
|
||||
break;
|
||||
case STATE_EQUIP_SEARCHING:
|
||||
this.search();
|
||||
break;
|
||||
case STATE_DISTANCE_HOLDING:
|
||||
this.distanceHolding();
|
||||
break;
|
||||
|
@ -209,7 +230,15 @@ function MyController(hand) {
|
|||
case STATE_NEAR_GRABBING:
|
||||
this.nearGrabbing();
|
||||
break;
|
||||
case STATE_EQUIP:
|
||||
this.nearGrabbing();
|
||||
break;
|
||||
case STATE_WAITING_FOR_BUMPER_RELEASE:
|
||||
this.waitingForBumperRelease();
|
||||
break;
|
||||
case STATE_CONTINUE_NEAR_GRABBING:
|
||||
case STATE_CONTINUE_EQUIP_BD:
|
||||
case STATE_CONTINUE_EQUIP:
|
||||
this.continueNearGrabbing();
|
||||
break;
|
||||
case STATE_NEAR_TRIGGER:
|
||||
|
@ -281,10 +310,15 @@ function MyController(hand) {
|
|||
this.pointer = null;
|
||||
};
|
||||
|
||||
this.eitherTrigger = function (value) {
|
||||
this.triggerPress = function (value) {
|
||||
_this.rawTriggerValue = value;
|
||||
};
|
||||
|
||||
this.bumperPress = function (value) {
|
||||
_this.rawBumperValue = value;
|
||||
};
|
||||
|
||||
|
||||
this.updateSmoothedTrigger = function () {
|
||||
var triggerValue = this.rawTriggerValue;
|
||||
// smooth out trigger value
|
||||
|
@ -305,23 +339,37 @@ function MyController(hand) {
|
|||
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() {
|
||||
if (this.triggerSmoothedSqueezed()) {
|
||||
this.lastPickTime = 0;
|
||||
this.setState(STATE_SEARCHING);
|
||||
return;
|
||||
}
|
||||
if (this.bumperSqueezed()) {
|
||||
this.lastPickTime = 0;
|
||||
this.setState(STATE_EQUIP_SEARCHING);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
this.search = function() {
|
||||
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) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.triggerSmoothedReleased()) {
|
||||
if (this.state == STATE_SEARCHING ? this.triggerSmoothedReleased() : this.bumperReleased()) {
|
||||
this.setState(STATE_RELEASE);
|
||||
return;
|
||||
}
|
||||
|
@ -398,7 +446,7 @@ function MyController(hand) {
|
|||
return;
|
||||
} else if (!intersection.properties.locked) {
|
||||
this.grabbedEntity = intersection.entityID;
|
||||
this.setState(STATE_NEAR_GRABBING);
|
||||
this.setState(this.state == STATE_SEARCHING ? STATE_NEAR_GRABBING : STATE_EQUIP)
|
||||
return;
|
||||
}
|
||||
} else if (! entityIsGrabbedByOther(intersection.entityID)) {
|
||||
|
@ -407,8 +455,14 @@ function MyController(hand) {
|
|||
&& !intersection.properties.locked) {
|
||||
// the hand is far from the intersected object. go into distance-holding mode
|
||||
this.grabbedEntity = intersection.entityID;
|
||||
this.setState(STATE_DISTANCE_HOLDING);
|
||||
return;
|
||||
if (typeof grabbableData.spatialKey !== 'undefined' && this.state == STATE_EQUIP_SEARCHING) {
|
||||
// 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) {
|
||||
this.grabbedEntity = intersection.entityID;
|
||||
this.setState(STATE_FAR_TRIGGER);
|
||||
|
@ -434,6 +488,7 @@ function MyController(hand) {
|
|||
var nearbyEntities = Entities.findEntities(handPosition, GRAB_RADIUS);
|
||||
var minDistance = PICK_MAX_DISTANCE;
|
||||
var i, props, distance, grabbableData;
|
||||
this.grabbedEntity = null;
|
||||
for (i = 0; i < nearbyEntities.length; i++) {
|
||||
var grabbableDataForCandidate =
|
||||
getEntityCustomData(GRABBABLE_DATA_KEY, nearbyEntities[i], DEFAULT_GRABBABLE_DATA);
|
||||
|
@ -490,7 +545,7 @@ function MyController(hand) {
|
|||
this.setState(STATE_NEAR_TRIGGER);
|
||||
return;
|
||||
} else if (!props.locked && props.collisionsWillMove) {
|
||||
this.setState(STATE_NEAR_GRABBING);
|
||||
this.setState(this.state == STATE_SEARCHING ? STATE_NEAR_GRABBING : STATE_EQUIP)
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
@ -634,13 +689,12 @@ function MyController(hand) {
|
|||
return;
|
||||
}
|
||||
|
||||
if (this.triggerSmoothedReleased()) {
|
||||
if (this.state == STATE_NEAR_GRABBING && this.triggerSmoothedReleased()) {
|
||||
this.setState(STATE_RELEASE);
|
||||
Entities.callEntityMethod(this.grabbedEntity, "releaseGrab");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
this.lineOff();
|
||||
|
||||
var grabbedProperties = Entities.getEntityProperties(this.grabbedEntity, GRABBABLE_PROPERTIES);
|
||||
|
@ -686,7 +740,7 @@ function MyController(hand) {
|
|||
this.actionID = null;
|
||||
} else {
|
||||
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) {
|
||||
Entities.callEntityMethod(this.grabbedEntity, "setRightHand");
|
||||
} 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.continueNearGrabbing = function() {
|
||||
if (this.triggerSmoothedReleased()) {
|
||||
if (this.state == STATE_CONTINUE_NEAR_GRABBING && this.triggerSmoothedReleased()) {
|
||||
this.setState(STATE_RELEASE);
|
||||
Entities.callEntityMethod(this.grabbedEntity, "releaseGrab");
|
||||
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.
|
||||
// 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() {
|
||||
if (this.triggerSmoothedReleased()) {
|
||||
this.setState(STATE_RELEASE);
|
||||
|
@ -919,6 +989,7 @@ function MyController(hand) {
|
|||
}
|
||||
Entities.editEntity(entityID, whileHeldProperties);
|
||||
}
|
||||
|
||||
setEntityCustomData(GRAB_USER_DATA_KEY, entityID, data);
|
||||
return data;
|
||||
};
|
||||
|
@ -948,8 +1019,12 @@ var leftController = new MyController(LEFT_HAND);
|
|||
var MAPPING_NAME = "com.highfidelity.handControllerGrab";
|
||||
|
||||
var mapping = Controller.newMapping(MAPPING_NAME);
|
||||
mapping.from([Controller.Standard.RB, Controller.Standard.RT]).peek().to(rightController.eitherTrigger);
|
||||
mapping.from([Controller.Standard.LB, Controller.Standard.LT]).peek().to(leftController.eitherTrigger);
|
||||
mapping.from([Controller.Standard.RT]).peek().to(rightController.triggerPress);
|
||||
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);
|
||||
|
||||
|
||||
|
|
|
@ -11,6 +11,12 @@ vec3toStr = function(v, 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) {
|
||||
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
|
||||
setEntityUserData = function(id, 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
|
||||
|
@ -60,7 +66,7 @@ getEntityUserData = function(id) {
|
|||
var properties = Entities.getEntityProperties(id, "userData");
|
||||
if (properties.userData) {
|
||||
try {
|
||||
results = JSON.parse(properties.userData);
|
||||
results = JSON.parse(properties.userData);
|
||||
} catch(err) {
|
||||
logDebug(err);
|
||||
logDebug(properties.userData);
|
||||
|
|
|
@ -704,6 +704,14 @@ void EntityTree::fixupTerseEditLogging(EntityItemProperties& properties, QList<Q
|
|||
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,
|
||||
|
|
Loading…
Reference in a new issue