mirror of
https://github.com/overte-org/overte.git
synced 2025-08-09 14:29:03 +02:00
Merge branch 'master' of https://github.com/highfidelity/hifi into hdr
This commit is contained in:
commit
fef5e3c8da
3 changed files with 130 additions and 200 deletions
|
@ -93,7 +93,7 @@ var ZERO_VEC = {
|
||||||
z: 0
|
z: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
var NULL_ACTION_ID = "{00000000-0000-0000-000000000000}";
|
var NULL_UUID = "{00000000-0000-0000-0000-000000000000}";
|
||||||
var MSEC_PER_SEC = 1000.0;
|
var MSEC_PER_SEC = 1000.0;
|
||||||
|
|
||||||
// these control how long an abandoned pointer line or action will hang around
|
// these control how long an abandoned pointer line or action will hang around
|
||||||
|
@ -109,7 +109,10 @@ var GRABBABLE_PROPERTIES = [
|
||||||
"collisionMask",
|
"collisionMask",
|
||||||
"collisionsWillMove",
|
"collisionsWillMove",
|
||||||
"locked",
|
"locked",
|
||||||
"name"
|
"name",
|
||||||
|
"shapeType",
|
||||||
|
"parentID",
|
||||||
|
"parentJointIndex"
|
||||||
];
|
];
|
||||||
|
|
||||||
var GRABBABLE_DATA_KEY = "grabbableKey"; // shared with grab.js
|
var GRABBABLE_DATA_KEY = "grabbableKey"; // shared with grab.js
|
||||||
|
@ -117,9 +120,11 @@ var GRAB_USER_DATA_KEY = "grabKey"; // shared with grab.js
|
||||||
|
|
||||||
var DEFAULT_GRABBABLE_DATA = {
|
var DEFAULT_GRABBABLE_DATA = {
|
||||||
grabbable: true,
|
grabbable: true,
|
||||||
|
disableReleaseVelocity: false
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// sometimes we want to exclude objects from being picked
|
// sometimes we want to exclude objects from being picked
|
||||||
var USE_BLACKLIST = true;
|
var USE_BLACKLIST = true;
|
||||||
var blacklist = [];
|
var blacklist = [];
|
||||||
|
@ -160,7 +165,6 @@ var STATE_EQUIP_SPRING = 16;
|
||||||
// the possible list of names is: static, dynamic, kinematic, myAvatar, otherAvatar
|
// the possible list of names is: static, dynamic, kinematic, myAvatar, otherAvatar
|
||||||
var COLLISION_MASK_WHILE_GRABBED = "dynamic,otherAvatar";
|
var COLLISION_MASK_WHILE_GRABBED = "dynamic,otherAvatar";
|
||||||
|
|
||||||
|
|
||||||
function stateToName(state) {
|
function stateToName(state) {
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case STATE_OFF:
|
case STATE_OFF:
|
||||||
|
@ -279,8 +283,6 @@ function MyController(hand) {
|
||||||
|
|
||||||
var SPATIAL_CONTROLLERS_PER_PALM = 2;
|
var SPATIAL_CONTROLLERS_PER_PALM = 2;
|
||||||
var TIP_CONTROLLER_OFFSET = 1;
|
var TIP_CONTROLLER_OFFSET = 1;
|
||||||
this.palm = SPATIAL_CONTROLLERS_PER_PALM * hand;
|
|
||||||
this.tip = SPATIAL_CONTROLLERS_PER_PALM * hand + TIP_CONTROLLER_OFFSET;
|
|
||||||
|
|
||||||
this.actionID = null; // action this script created...
|
this.actionID = null; // action this script created...
|
||||||
this.grabbedEntity = null; // on this entity.
|
this.grabbedEntity = null; // on this entity.
|
||||||
|
@ -726,6 +728,10 @@ function MyController(hand) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this.propsArePhysical = function(props) {
|
||||||
|
var isPhysical = (props.shapeType && props.shapeType != 'none');
|
||||||
|
return isPhysical;
|
||||||
|
}
|
||||||
|
|
||||||
this.turnOffVisualizations = function() {
|
this.turnOffVisualizations = function() {
|
||||||
if (USE_ENTITY_LINES_FOR_SEARCHING === true || USE_ENTITY_LINES_FOR_MOVING === true) {
|
if (USE_ENTITY_LINES_FOR_SEARCHING === true || USE_ENTITY_LINES_FOR_MOVING === true) {
|
||||||
|
@ -800,7 +806,6 @@ function MyController(hand) {
|
||||||
|
|
||||||
// the trigger is being pressed, so do a ray test to see what we are hitting
|
// the trigger is being pressed, so do a ray test to see what we are hitting
|
||||||
var handPosition = this.getHandPosition();
|
var handPosition = this.getHandPosition();
|
||||||
|
|
||||||
var controllerHandInput = (this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand;
|
var controllerHandInput = (this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand;
|
||||||
var currentHandRotation = Controller.getPoseValue(controllerHandInput).rotation;
|
var currentHandRotation = Controller.getPoseValue(controllerHandInput).rotation;
|
||||||
var handDeltaRotation = Quat.multiply(currentHandRotation, Quat.inverse(this.startingHandRotation));
|
var handDeltaRotation = Quat.multiply(currentHandRotation, Quat.inverse(this.startingHandRotation));
|
||||||
|
@ -825,6 +830,9 @@ function MyController(hand) {
|
||||||
this.lastPickTime = now;
|
this.lastPickTime = now;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rayPickedCandidateEntities = []; // the list of candidates to consider grabbing
|
||||||
|
|
||||||
|
this.intersectionDistance = 0.0;
|
||||||
for (var index = 0; index < pickRays.length; ++index) {
|
for (var index = 0; index < pickRays.length; ++index) {
|
||||||
var pickRay = pickRays[index];
|
var pickRay = pickRays[index];
|
||||||
var directionNormalized = Vec3.normalize(pickRay.direction);
|
var directionNormalized = Vec3.normalize(pickRay.direction);
|
||||||
|
@ -834,14 +842,6 @@ function MyController(hand) {
|
||||||
direction: pickRay.direction
|
direction: pickRay.direction
|
||||||
};
|
};
|
||||||
|
|
||||||
if (WANT_DEBUG) {
|
|
||||||
this.debugLine(pickRayBacked.origin, Vec3.multiply(pickRayBacked.direction, NEAR_PICK_MAX_DISTANCE), {
|
|
||||||
red: 0,
|
|
||||||
green: 255,
|
|
||||||
blue: 0
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
Messages.sendMessage('Hifi-Light-Overlay-Ray-Check', JSON.stringify(pickRayBacked));
|
Messages.sendMessage('Hifi-Light-Overlay-Ray-Check', JSON.stringify(pickRayBacked));
|
||||||
|
|
||||||
var intersection;
|
var intersection;
|
||||||
|
@ -852,189 +852,85 @@ function MyController(hand) {
|
||||||
intersection = Entities.findRayIntersection(pickRayBacked, true);
|
intersection = Entities.findRayIntersection(pickRayBacked, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (intersection.intersects) {
|
if (intersection.intersects) {
|
||||||
|
rayPickedCandidateEntities.push(intersection.entityID);
|
||||||
// the ray is intersecting something we can move.
|
|
||||||
this.intersectionDistance = Vec3.distance(pickRay.origin, intersection.intersection);
|
this.intersectionDistance = Vec3.distance(pickRay.origin, intersection.intersection);
|
||||||
|
|
||||||
var grabbableData = getEntityCustomData(GRABBABLE_DATA_KEY, intersection.entityID, DEFAULT_GRABBABLE_DATA);
|
|
||||||
var defaultDisableNearGrabData = {
|
|
||||||
disableNearGrab: false
|
|
||||||
};
|
|
||||||
//sometimes we want things to stay right where they are when we let go.
|
|
||||||
var disableNearGrabData = getEntityCustomData('handControllerKey', intersection.entityID, defaultDisableNearGrabData);
|
|
||||||
|
|
||||||
if (intersection.properties.name == "Grab Debug Entity") {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof grabbableData.grabbable !== 'undefined' && !grabbableData.grabbable) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (this.intersectionDistance > pickRay.length) {
|
|
||||||
// too far away for this ray.
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (this.intersectionDistance <= NEAR_PICK_MAX_DISTANCE) {
|
|
||||||
// the hand is very close to the intersected object. go into close-grabbing mode.
|
|
||||||
if (grabbableData.wantsTrigger) {
|
|
||||||
this.grabbedEntity = intersection.entityID;
|
|
||||||
this.setState(STATE_NEAR_TRIGGER);
|
|
||||||
return;
|
|
||||||
} else if (!intersection.properties.locked) {
|
|
||||||
this.grabbedEntity = intersection.entityID;
|
|
||||||
if (this.state == STATE_SEARCHING) {
|
|
||||||
if (disableNearGrabData.disableNearGrab !== true) {
|
|
||||||
this.setState(STATE_NEAR_GRABBING);
|
|
||||||
} else {
|
|
||||||
//disable near grab on this thing
|
|
||||||
}
|
|
||||||
} else { // equipping
|
|
||||||
if (typeof grabbableData.spatialKey !== 'undefined') {
|
|
||||||
// TODO
|
|
||||||
// if we go to STATE_EQUIP_SPRING the item will be pulled to the hand and will then switch
|
|
||||||
// to STATE_EQUIP. This needs some debugging, so just jump straight to STATE_EQUIP here.
|
|
||||||
// this.setState(STATE_EQUIP_SPRING);
|
|
||||||
this.setState(STATE_EQUIP);
|
|
||||||
} else {
|
|
||||||
this.setState(STATE_EQUIP);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (!entityIsGrabbedByOther(intersection.entityID)) {
|
|
||||||
// don't allow two people to distance grab the same object
|
|
||||||
if (intersection.properties.collisionsWillMove && !intersection.properties.locked) {
|
|
||||||
// the hand is far from the intersected object. go into distance-holding mode
|
|
||||||
this.grabbedEntity = intersection.entityID;
|
|
||||||
if (this.state == STATE_EQUIP_SEARCHING) {
|
|
||||||
// if a distance pick in equip mode hits something with a spatialKey, equip it
|
|
||||||
// TODO use STATE_EQUIP_SPRING here once it works right.
|
|
||||||
// this.setState(STATE_EQUIP_SPRING);
|
|
||||||
if (typeof grabbableData.spatialKey === 'undefined') {
|
|
||||||
// We want to give a temporary position offset to this object so it is pulled close to hand
|
|
||||||
var intersectionPointToCenterDistance = Vec3.length(Vec3.subtract(intersection.intersection, intersection.properties.position));
|
|
||||||
this.temporaryPositionOffset = Vec3.normalize(Vec3.subtract(intersection.properties.position, handPosition));
|
|
||||||
this.temporaryPositionOffset = Vec3.multiply(this.temporaryPositionOffset, intersectionPointToCenterDistance * FAR_TO_NEAR_GRAB_PADDING_FACTOR);
|
|
||||||
|
|
||||||
}
|
|
||||||
this.setState(STATE_EQUIP);
|
|
||||||
this.turnOffVisualizations();
|
|
||||||
return;
|
|
||||||
} else if ((this.state == STATE_SEARCHING) && this.triggerSmoothedGrab()) {
|
|
||||||
this.setState(STATE_DISTANCE_HOLDING);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else if (grabbableData.wantsTrigger && this.triggerSmoothedGrab()) {
|
|
||||||
this.grabbedEntity = intersection.entityID;
|
|
||||||
this.setState(STATE_FAR_TRIGGER);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nearPickedCandidateEntities = Entities.findEntities(handPosition, GRAB_RADIUS);
|
||||||
|
candidateEntities = rayPickedCandidateEntities.concat(nearPickedCandidateEntities);
|
||||||
|
|
||||||
// forward ray test failed, try sphere test.
|
var forbiddenNames = ["Grab Debug Entity", "grab pointer"];
|
||||||
if (WANT_DEBUG) {
|
var forbiddenTyes = ['Unknown', 'Light', 'ParticleEffect', 'PolyLine', 'Zone'];
|
||||||
Entities.addEntity({
|
|
||||||
type: "Sphere",
|
|
||||||
name: "Grab Debug Entity",
|
|
||||||
dimensions: {
|
|
||||||
x: GRAB_RADIUS,
|
|
||||||
y: GRAB_RADIUS,
|
|
||||||
z: GRAB_RADIUS
|
|
||||||
},
|
|
||||||
visible: true,
|
|
||||||
position: handPosition,
|
|
||||||
color: {
|
|
||||||
red: 0,
|
|
||||||
green: 255,
|
|
||||||
blue: 0
|
|
||||||
},
|
|
||||||
lifetime: 0.1,
|
|
||||||
collisionsWillMove: false,
|
|
||||||
ignoreForCollisions: true,
|
|
||||||
userData: JSON.stringify({
|
|
||||||
grabbableKey: {
|
|
||||||
grabbable: false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
this.grabbedEntity = null;
|
||||||
for (i = 0; i < nearbyEntities.length; i++) {
|
for (i = 0; i < candidateEntities.length; i++) {
|
||||||
var grabbableDataForCandidate =
|
var grabbableDataForCandidate =
|
||||||
getEntityCustomData(GRABBABLE_DATA_KEY, nearbyEntities[i], DEFAULT_GRABBABLE_DATA);
|
getEntityCustomData(GRABBABLE_DATA_KEY, candidateEntities[i], DEFAULT_GRABBABLE_DATA);
|
||||||
if (typeof grabbableDataForCandidate.grabbable !== 'undefined' && !grabbableDataForCandidate.grabbable) {
|
var propsForCandidate = Entities.getEntityProperties(candidateEntities[i], GRABBABLE_PROPERTIES);
|
||||||
|
var grabbable = (typeof grabbableDataForCandidate.grabbable === 'undefined' || grabbableDataForCandidate.grabbable);
|
||||||
|
if (!grabbable && !grabbableDataForCandidate.wantsTrigger) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
var propsForCandidate = Entities.getEntityProperties(nearbyEntities[i], GRABBABLE_PROPERTIES);
|
if (forbiddenTyes.indexOf(propsForCandidate.type) >= 0) {
|
||||||
|
|
||||||
if (propsForCandidate.type == 'Unknown') {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (propsForCandidate.type == 'Light') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (propsForCandidate.type == 'ParticleEffect') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (propsForCandidate.type == 'PolyLine') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (propsForCandidate.type == 'Zone') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (propsForCandidate.locked && !grabbableDataForCandidate.wantsTrigger) {
|
if (propsForCandidate.locked && !grabbableDataForCandidate.wantsTrigger) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (forbiddenNames.indexOf(propsForCandidate.name) >= 0) {
|
||||||
if (propsForCandidate.name == "Grab Debug Entity") {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (propsForCandidate.name == "grab pointer") {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
distance = Vec3.distance(propsForCandidate.position, handPosition);
|
distance = Vec3.distance(propsForCandidate.position, handPosition);
|
||||||
|
if (distance > PICK_MAX_DISTANCE) {
|
||||||
|
// too far away, don't grab
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (distance < minDistance) {
|
if (distance < minDistance) {
|
||||||
this.grabbedEntity = nearbyEntities[i];
|
this.grabbedEntity = candidateEntities[i];
|
||||||
minDistance = distance;
|
minDistance = distance;
|
||||||
props = propsForCandidate;
|
props = propsForCandidate;
|
||||||
grabbableData = grabbableDataForCandidate;
|
grabbableData = grabbableDataForCandidate;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (this.grabbedEntity !== null) {
|
if (this.grabbedEntity !== null) {
|
||||||
|
// We've found an entity that we'll do something with.
|
||||||
|
var near = (nearPickedCandidateEntities.indexOf(this.grabbedEntity) >= 0);
|
||||||
|
var isPhysical = this.propsArePhysical(props);
|
||||||
|
|
||||||
|
// near or far trigger
|
||||||
if (grabbableData.wantsTrigger) {
|
if (grabbableData.wantsTrigger) {
|
||||||
this.setState(STATE_NEAR_TRIGGER);
|
this.setState(near ? STATE_NEAR_TRIGGER : STATE_FAR_TRIGGER);
|
||||||
return;
|
|
||||||
} else if (!props.locked && props.collisionsWillMove) {
|
|
||||||
var defaultDisableNearGrabData = {
|
|
||||||
disableNearGrab: false
|
|
||||||
};
|
|
||||||
//sometimes we want things to stay right where they are when we let go.
|
|
||||||
var disableNearGrabData = getEntityCustomData('handControllerKey', this.grabbedEntity, defaultDisableNearGrabData);
|
|
||||||
if (disableNearGrabData.disableNearGrab === true) {
|
|
||||||
//do nothing because near grab is disabled for this object
|
|
||||||
} else {
|
|
||||||
this.setState(this.state == STATE_SEARCHING ? STATE_NEAR_GRABBING : STATE_EQUIP)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
// near grab or equip with action
|
||||||
|
if (isPhysical && near) {
|
||||||
|
this.setState(this.state == STATE_SEARCHING ? STATE_NEAR_GRABBING : STATE_EQUIP);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// far grab or equip with action
|
||||||
|
if (isPhysical && !near) {
|
||||||
|
this.temporaryPositionOffset = null;
|
||||||
|
if (typeof grabbableData.spatialKey === 'undefined') {
|
||||||
|
// We want to give a temporary position offset to this object so it is pulled close to hand
|
||||||
|
var intersectionPointToCenterDistance = Vec3.length(Vec3.subtract(intersection.intersection,
|
||||||
|
intersection.properties.position));
|
||||||
|
this.temporaryPositionOffset = Vec3.normalize(Vec3.subtract(intersection.properties.position, handPosition));
|
||||||
|
this.temporaryPositionOffset = Vec3.multiply(this.temporaryPositionOffset,
|
||||||
|
intersectionPointToCenterDistance *
|
||||||
|
FAR_TO_NEAR_GRAB_PADDING_FACTOR);
|
||||||
|
}
|
||||||
|
this.setState(this.state == STATE_SEARCHING ? STATE_DISTANCE_HOLDING : STATE_EQUIP);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// else this thing isn't physical. grab it by reparenting it.
|
||||||
|
this.setState(STATE_NEAR_GRABBING);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//search line visualizations
|
//search line visualizations
|
||||||
|
@ -1046,20 +942,31 @@ function MyController(hand) {
|
||||||
this.handleParticleBeam(distantPickRay.origin, this.getHandRotation(), NO_INTERSECT_COLOR);
|
this.handleParticleBeam(distantPickRay.origin, this.getHandRotation(), NO_INTERSECT_COLOR);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (USE_OVERLAY_LINES_FOR_SEARCHING === true) {
|
// if (USE_OVERLAY_LINES_FOR_SEARCHING === true) {
|
||||||
this.overlayLineOn(searchVisualizationPickRay.origin, Vec3.sum(searchVisualizationPickRay.origin, Vec3.multiply(searchVisualizationPickRay.direction, LINE_LENGTH)), NO_INTERSECT_COLOR);
|
// this.overlayLineOn(searchVisualizationPickRay.origin,
|
||||||
}
|
// Vec3.sum(searchVisualizationPickRay.origin,
|
||||||
|
// Vec3.multiply(searchVisualizationPickRay.direction,
|
||||||
|
// LINE_LENGTH)),
|
||||||
|
// NO_INTERSECT_COLOR);
|
||||||
|
// }
|
||||||
|
|
||||||
if (this.intersectionDistance > 0) {
|
if (this.intersectionDistance > 0) {
|
||||||
var SPHERE_INTERSECTION_SIZE = 0.011;
|
var SPHERE_INTERSECTION_SIZE = 0.011;
|
||||||
var SEARCH_SPHERE_FOLLOW_RATE = 0.50;
|
var SEARCH_SPHERE_FOLLOW_RATE = 0.50;
|
||||||
var SEARCH_SPHERE_CHASE_DROP = 0.2;
|
var SEARCH_SPHERE_CHASE_DROP = 0.2;
|
||||||
this.searchSphereDistance = this.searchSphereDistance * SEARCH_SPHERE_FOLLOW_RATE + this.intersectionDistance * (1.0 - SEARCH_SPHERE_FOLLOW_RATE);
|
this.searchSphereDistance = this.searchSphereDistance * SEARCH_SPHERE_FOLLOW_RATE +
|
||||||
var searchSphereLocation = Vec3.sum(distantPickRay.origin, Vec3.multiply(distantPickRay.direction, this.searchSphereDistance));
|
this.intersectionDistance * (1.0 - SEARCH_SPHERE_FOLLOW_RATE);
|
||||||
searchSphereLocation.y -= ((this.intersectionDistance - this.searchSphereDistance) / this.intersectionDistance) * SEARCH_SPHERE_CHASE_DROP;
|
var searchSphereLocation = Vec3.sum(distantPickRay.origin,
|
||||||
this.searchSphereOn(searchSphereLocation, SPHERE_INTERSECTION_SIZE * this.intersectionDistance, this.triggerSmoothedGrab() ? INTERSECT_COLOR : NO_INTERSECT_COLOR);
|
Vec3.multiply(distantPickRay.direction, this.searchSphereDistance));
|
||||||
|
searchSphereLocation.y -= ((this.intersectionDistance - this.searchSphereDistance) /
|
||||||
|
this.intersectionDistance) * SEARCH_SPHERE_CHASE_DROP;
|
||||||
|
this.searchSphereOn(searchSphereLocation,
|
||||||
|
SPHERE_INTERSECTION_SIZE * this.intersectionDistance,
|
||||||
|
this.triggerSmoothedGrab() ? INTERSECT_COLOR : NO_INTERSECT_COLOR);
|
||||||
if (USE_OVERLAY_LINES_FOR_SEARCHING === true) {
|
if (USE_OVERLAY_LINES_FOR_SEARCHING === true) {
|
||||||
this.overlayLineOn(handPosition, searchSphereLocation, this.triggerSmoothedGrab() ? INTERSECT_COLOR : NO_INTERSECT_COLOR);
|
this.overlayLineOn(handPosition,
|
||||||
|
searchSphereLocation,
|
||||||
|
this.triggerSmoothedGrab() ? INTERSECT_COLOR : NO_INTERSECT_COLOR);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1085,7 +992,7 @@ function MyController(hand) {
|
||||||
this.radiusScalar = 1.0;
|
this.radiusScalar = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.actionID = NULL_ACTION_ID;
|
this.actionID = NULL_UUID;
|
||||||
this.actionID = Entities.addAction("spring", this.grabbedEntity, {
|
this.actionID = Entities.addAction("spring", this.grabbedEntity, {
|
||||||
targetPosition: this.currentObjectPosition,
|
targetPosition: this.currentObjectPosition,
|
||||||
linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME,
|
linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME,
|
||||||
|
@ -1094,7 +1001,7 @@ function MyController(hand) {
|
||||||
tag: getTag(),
|
tag: getTag(),
|
||||||
ttl: ACTION_TTL
|
ttl: ACTION_TTL
|
||||||
});
|
});
|
||||||
if (this.actionID === NULL_ACTION_ID) {
|
if (this.actionID === NULL_UUID) {
|
||||||
this.actionID = null;
|
this.actionID = null;
|
||||||
}
|
}
|
||||||
this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC);
|
this.actionTimeout = now + (ACTION_TTL * MSEC_PER_SEC);
|
||||||
|
@ -1283,7 +1190,6 @@ function MyController(hand) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
this.setupHoldAction = function() {
|
this.setupHoldAction = function() {
|
||||||
this.actionID = Entities.addAction("hold", this.grabbedEntity, {
|
this.actionID = Entities.addAction("hold", this.grabbedEntity, {
|
||||||
hand: this.hand === RIGHT_HAND ? "right" : "left",
|
hand: this.hand === RIGHT_HAND ? "right" : "left",
|
||||||
|
@ -1295,7 +1201,7 @@ function MyController(hand) {
|
||||||
kinematicSetVelocity: true,
|
kinematicSetVelocity: true,
|
||||||
ignoreIK: this.ignoreIK
|
ignoreIK: this.ignoreIK
|
||||||
});
|
});
|
||||||
if (this.actionID === NULL_ACTION_ID) {
|
if (this.actionID === NULL_UUID) {
|
||||||
this.actionID = null;
|
this.actionID = null;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -1330,7 +1236,6 @@ function MyController(hand) {
|
||||||
var projection = Vec3.sum(axisStart, Vec3.multiply(scalar, Vec3.normalize(bPrime)));
|
var projection = Vec3.sum(axisStart, Vec3.multiply(scalar, Vec3.normalize(bPrime)));
|
||||||
|
|
||||||
return projection
|
return projection
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
this.nearGrabbing = function() {
|
this.nearGrabbing = function() {
|
||||||
|
@ -1378,9 +1283,19 @@ function MyController(hand) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var isPhysical = this.propsArePhysical(grabbedProperties);
|
||||||
if (!this.setupHoldAction()) {
|
if (isPhysical) {
|
||||||
return;
|
// grab entity via action
|
||||||
|
if (!this.setupHoldAction()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// grab entity via parenting
|
||||||
|
var handJointIndex = MyAvatar.getJointIndex(this.hand === RIGHT_HAND ? "RightHand" : "LeftHand");
|
||||||
|
Entities.editEntity(this.grabbedEntity, {
|
||||||
|
parentID: MyAvatar.sessionUUID,
|
||||||
|
parentJointIndex: handJointIndex
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.state == STATE_NEAR_GRABBING) {
|
if (this.state == STATE_NEAR_GRABBING) {
|
||||||
|
@ -1447,7 +1362,13 @@ function MyController(hand) {
|
||||||
Entities.callEntityMethod(this.grabbedEntity, "continueEquip");
|
Entities.callEntityMethod(this.grabbedEntity, "continueEquip");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.actionTimeout - now < ACTION_TTL_REFRESH * MSEC_PER_SEC) {
|
//// jbp::: SEND UPDATE MESSAGE TO WEARABLES MANAGER
|
||||||
|
Messages.sendMessage('Hifi-Wearables-Manager', JSON.stringify({
|
||||||
|
action: 'update',
|
||||||
|
grabbedEntity: this.grabbedEntity
|
||||||
|
}))
|
||||||
|
|
||||||
|
if (this.actionID && this.actionTimeout - now < ACTION_TTL_REFRESH * MSEC_PER_SEC) {
|
||||||
// if less than a 5 seconds left, refresh the actions ttl
|
// if less than a 5 seconds left, refresh the actions ttl
|
||||||
var success = Entities.updateAction(this.grabbedEntity, this.actionID, {
|
var success = Entities.updateAction(this.grabbedEntity, this.actionID, {
|
||||||
hand: this.hand === RIGHT_HAND ? "right" : "left",
|
hand: this.hand === RIGHT_HAND ? "right" : "left",
|
||||||
|
@ -1496,7 +1417,7 @@ function MyController(hand) {
|
||||||
|
|
||||||
if (typeof this.equipSpringID === 'undefined' ||
|
if (typeof this.equipSpringID === 'undefined' ||
|
||||||
this.equipSpringID === null ||
|
this.equipSpringID === null ||
|
||||||
this.equipSpringID === NULL_ACTION_ID) {
|
this.equipSpringID === NULL_UUID) {
|
||||||
this.equipSpringID = Entities.addAction("spring", this.grabbedEntity, {
|
this.equipSpringID = Entities.addAction("spring", this.grabbedEntity, {
|
||||||
targetPosition: targetPosition,
|
targetPosition: targetPosition,
|
||||||
linearTimeScale: EQUIP_SPRING_TIMEFRAME,
|
linearTimeScale: EQUIP_SPRING_TIMEFRAME,
|
||||||
|
@ -1505,7 +1426,7 @@ function MyController(hand) {
|
||||||
ttl: ACTION_TTL,
|
ttl: ACTION_TTL,
|
||||||
ignoreIK: ignoreIK
|
ignoreIK: ignoreIK
|
||||||
});
|
});
|
||||||
if (this.equipSpringID === NULL_ACTION_ID) {
|
if (this.equipSpringID === NULL_UUID) {
|
||||||
this.equipSpringID = null;
|
this.equipSpringID = null;
|
||||||
this.setState(STATE_OFF);
|
this.setState(STATE_OFF);
|
||||||
return;
|
return;
|
||||||
|
@ -1682,12 +1603,10 @@ function MyController(hand) {
|
||||||
|
|
||||||
if (this.grabbedEntity !== null) {
|
if (this.grabbedEntity !== null) {
|
||||||
if (this.actionID !== null) {
|
if (this.actionID !== null) {
|
||||||
//add velocity whatnot
|
|
||||||
var defaultReleaseVelocityData = {
|
|
||||||
disableReleaseVelocity: false
|
|
||||||
};
|
|
||||||
//sometimes we want things to stay right where they are when we let go.
|
//sometimes we want things to stay right where they are when we let go.
|
||||||
var releaseVelocityData = getEntityCustomData('handControllerKey', this.grabbedEntity, defaultReleaseVelocityData);
|
var releaseVelocityData = getEntityCustomData(GRABBABLE_DATA_KEY,
|
||||||
|
this.grabbedEntity,
|
||||||
|
DEFAULT_GRABBABLE_DATA);
|
||||||
if (releaseVelocityData.disableReleaseVelocity === true) {
|
if (releaseVelocityData.disableReleaseVelocity === true) {
|
||||||
Entities.deleteAction(this.grabbedEntity, this.actionID);
|
Entities.deleteAction(this.grabbedEntity, this.actionID);
|
||||||
|
|
||||||
|
@ -1708,16 +1627,23 @@ function MyController(hand) {
|
||||||
} else {
|
} else {
|
||||||
//don't make adjustments
|
//don't make adjustments
|
||||||
Entities.deleteAction(this.grabbedEntity, this.actionID);
|
Entities.deleteAction(this.grabbedEntity, this.actionID);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.deactivateEntity(this.grabbedEntity);
|
this.deactivateEntity(this.grabbedEntity);
|
||||||
|
|
||||||
this.grabbedEntity = null;
|
|
||||||
this.actionID = null;
|
this.actionID = null;
|
||||||
this.setState(STATE_OFF);
|
this.setState(STATE_OFF);
|
||||||
|
|
||||||
|
//// jbp::: SEND RELEASE MESSAGE TO WEARABLES MANAGER
|
||||||
|
|
||||||
|
Messages.sendMessage('Hifi-Wearables-Manager', JSON.stringify({
|
||||||
|
action: 'checkIfWearable',
|
||||||
|
grabbedEntity: this.grabbedEntity
|
||||||
|
}))
|
||||||
|
|
||||||
|
this.grabbedEntity = null;
|
||||||
};
|
};
|
||||||
|
|
||||||
this.cleanup = function() {
|
this.cleanup = function() {
|
||||||
|
@ -1738,6 +1664,8 @@ function MyController(hand) {
|
||||||
data["gravity"] = grabbedProperties.gravity;
|
data["gravity"] = grabbedProperties.gravity;
|
||||||
data["collisionMask"] = grabbedProperties.collisionMask;
|
data["collisionMask"] = grabbedProperties.collisionMask;
|
||||||
data["collisionsWillMove"] = grabbedProperties.collisionsWillMove;
|
data["collisionsWillMove"] = grabbedProperties.collisionsWillMove;
|
||||||
|
data["parentID"] = grabbedProperties.parentID;
|
||||||
|
data["parentJointIndex"] = grabbedProperties.parentJointIndex;
|
||||||
var whileHeldProperties = {
|
var whileHeldProperties = {
|
||||||
gravity: {
|
gravity: {
|
||||||
x: 0,
|
x: 0,
|
||||||
|
@ -1761,7 +1689,10 @@ function MyController(hand) {
|
||||||
Entities.editEntity(entityID, {
|
Entities.editEntity(entityID, {
|
||||||
gravity: data["gravity"],
|
gravity: data["gravity"],
|
||||||
collisionMask: data["collisionMask"],
|
collisionMask: data["collisionMask"],
|
||||||
collisionsWillMove: data["collisionsWillMove"]
|
collisionsWillMove: data["collisionsWillMove"],
|
||||||
|
ignoreForCollisions: data["ignoreForCollisions"],
|
||||||
|
parentID: data["parentID"],
|
||||||
|
parentJointIndex: data["parentJointIndex"]
|
||||||
});
|
});
|
||||||
data = null;
|
data = null;
|
||||||
}
|
}
|
||||||
|
|
|
@ -241,7 +241,6 @@ void ObjectAction::activateBody(bool forceActivation) {
|
||||||
auto rigidBody = getRigidBody();
|
auto rigidBody = getRigidBody();
|
||||||
if (rigidBody) {
|
if (rigidBody) {
|
||||||
rigidBody->activate(forceActivation);
|
rigidBody->activate(forceActivation);
|
||||||
assert(rigidBody->isActive());
|
|
||||||
} else {
|
} else {
|
||||||
qDebug() << "ObjectAction::activateBody -- no rigid body" << (void*)rigidBody;
|
qDebug() << "ObjectAction::activateBody -- no rigid body" << (void*)rigidBody;
|
||||||
}
|
}
|
||||||
|
|
|
@ -58,16 +58,16 @@ void ObjectActionSpring::updateActionWorker(btScalar deltaTimeStep) {
|
||||||
|
|
||||||
const float MAX_TIMESCALE = 600.0f; // 10 min is a long time
|
const float MAX_TIMESCALE = 600.0f; // 10 min is a long time
|
||||||
if (_linearTimeScale < MAX_TIMESCALE) {
|
if (_linearTimeScale < MAX_TIMESCALE) {
|
||||||
|
btVector3 targetVelocity(0.0f, 0.0f, 0.0f);
|
||||||
btVector3 offset = rigidBody->getCenterOfMassPosition() - glmToBullet(_positionalTarget);
|
btVector3 offset = rigidBody->getCenterOfMassPosition() - glmToBullet(_positionalTarget);
|
||||||
float offsetLength = offset.length();
|
float offsetLength = offset.length();
|
||||||
btVector3 targetVelocity(0.0f, 0.0f, 0.0f);
|
if (offsetLength > FLT_EPSILON) {
|
||||||
|
float speed = glm::min(offsetLength / _linearTimeScale, SPRING_MAX_SPEED);
|
||||||
float speed = (offsetLength > FLT_EPSILON) ? glm::min(offsetLength / _linearTimeScale, SPRING_MAX_SPEED) : 0.0f;
|
targetVelocity = (-speed / offsetLength) * offset;
|
||||||
targetVelocity = (-speed / offsetLength) * offset;
|
if (speed > rigidBody->getLinearSleepingThreshold()) {
|
||||||
if (speed > rigidBody->getLinearSleepingThreshold()) {
|
rigidBody->activate();
|
||||||
rigidBody->activate();
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// this action is aggresively critically damped and defeats the current velocity
|
// this action is aggresively critically damped and defeats the current velocity
|
||||||
rigidBody->setLinearVelocity(targetVelocity);
|
rigidBody->setLinearVelocity(targetVelocity);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue