Limits on distance and mass for far grabbing

This commit is contained in:
Philip Rosedale 2016-01-29 00:52:59 -08:00
parent 8efe15cb21
commit 9f95a9de89
2 changed files with 52 additions and 32 deletions

View file

@ -12,7 +12,7 @@
// The rectangular area in the domain where the flock will fly // The rectangular area in the domain where the flock will fly
var lowerCorner = { x: 0, y: 0, z: 0 }; var lowerCorner = { x: 0, y: 0, z: 0 };
var upperCorner = { x: 10, y: 10, z: 10 }; var upperCorner = { x: 30, y: 10, z: 30 };
var STARTING_FRACTION = 0.25; var STARTING_FRACTION = 0.25;
var NUM_BIRDS = 50; var NUM_BIRDS = 50;
@ -36,7 +36,7 @@ var ALIGNMENT_FORCE = 1.5;
var COHESION_FORCE = 1.0; var COHESION_FORCE = 1.0;
var MAX_COHESION_VELOCITY = 0.5; var MAX_COHESION_VELOCITY = 0.5;
var followBirds = true; var followBirds = false;
var AVATAR_FOLLOW_RATE = 0.001; var AVATAR_FOLLOW_RATE = 0.001;
var AVATAR_FOLLOW_VELOCITY_TIMESCALE = 2.0; var AVATAR_FOLLOW_VELOCITY_TIMESCALE = 2.0;
var AVATAR_FOLLOW_ORIENTATION_RATE = 0.005; var AVATAR_FOLLOW_ORIENTATION_RATE = 0.005;

View file

@ -41,6 +41,8 @@ var PICK_WITH_HAND_RAY = true;
var DISTANCE_HOLDING_RADIUS_FACTOR = 3.5; // multiplied by distance between hand and object var DISTANCE_HOLDING_RADIUS_FACTOR = 3.5; // multiplied by distance between hand and object
var DISTANCE_HOLDING_ACTION_TIMEFRAME = 0.1; // how quickly objects move to their new position var DISTANCE_HOLDING_ACTION_TIMEFRAME = 0.1; // how quickly objects move to their new position
var DISTANCE_HOLDING_UNITY_MASS = 1200; // The mass at which the distance holding action timeframe is unmodified
var DISTANCE_HOLDING_UNITY_DISTANCE = 6; // The distance at which the distance holding action timeframe is unmodified
var DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR = 2.0; // object rotates this much more than hand did var DISTANCE_HOLDING_ROTATION_EXAGGERATION_FACTOR = 2.0; // object rotates this much more than hand did
var MOVE_WITH_HEAD = true; // experimental head-control of distantly held objects var MOVE_WITH_HEAD = true; // experimental head-control of distantly held objects
var FAR_TO_NEAR_GRAB_PADDING_FACTOR = 1.2; var FAR_TO_NEAR_GRAB_PADDING_FACTOR = 1.2;
@ -114,7 +116,9 @@ var GRABBABLE_PROPERTIES = [
"name", "name",
"shapeType", "shapeType",
"parentID", "parentID",
"parentJointIndex" "parentJointIndex",
"density",
"dimensions"
]; ];
var GRABBABLE_DATA_KEY = "grabbableKey"; // shared with grab.js var GRABBABLE_DATA_KEY = "grabbableKey"; // shared with grab.js
@ -295,7 +299,7 @@ function MyController(hand) {
this.rawBumperValue = 0; this.rawBumperValue = 0;
//for visualizations //for visualizations
this.overlayLine = null; this.overlayLine = null;
this.particleBeam = null; this.particleBeamObject = null;
//for lights //for lights
this.spotlight = null; this.spotlight = null;
@ -479,34 +483,32 @@ function MyController(hand) {
this.handleDistantParticleBeam = function(handPosition, objectPosition, color) { this.handleDistantParticleBeam = function(handPosition, objectPosition, color) {
var handToObject = Vec3.subtract(objectPosition, handPosition); var handToObject = Vec3.subtract(objectPosition, handPosition);
var finalRotation = Quat.rotationBetween(Vec3.multiply(-1, Vec3.UP), handToObject); var finalRotationObject = Quat.rotationBetween(Vec3.multiply(-1, Vec3.UP), handToObject);
var distance = Vec3.distance(handPosition, objectPosition); var distance = Vec3.distance(handPosition, objectPosition);
var speed = 5; var speed = distance * 3;
var spread = 0; var spread = 0;
var lifespan = distance / speed; var lifespan = distance / speed;
if (this.particleBeam === null) { if (this.particleBeamObject === null) {
this.createParticleBeam(objectPosition, finalRotation, color, speed, spread, lifespan); this.createParticleBeam(objectPosition, finalRotationObject, color, speed, spread, lifespan);
} else { } else {
this.updateParticleBeam(objectPosition, finalRotation, color, speed, spread, lifespan); this.updateParticleBeam(objectPosition, finalRotationObject, color, speed, spread, lifespan);
} }
}; };
this.createParticleBeam = function(position, orientation, color, speed, spread, lifespan) { this.createParticleBeam = function(positionObject, orientationObject, color, speed, spread, lifespan) {
var particleBeamProperties = { var particleBeamPropertiesObject = {
type: "ParticleEffect", type: "ParticleEffect",
isEmitting: true, isEmitting: true,
position: position, position: positionObject,
visible: false, visible: false,
lifetime: 60, lifetime: 60,
"name": "Particle Beam", "name": "Particle Beam",
"color": color, "color": color,
"maxParticles": 2000, "maxParticles": 2000,
"lifespan": lifespan, "lifespan": lifespan,
"emitRate": 50, "emitRate": 1000,
"emitSpeed": speed, "emitSpeed": speed,
"speedSpread": spread, "speedSpread": spread,
"emitOrientation": { "emitOrientation": {
@ -544,26 +546,25 @@ function MyController(hand) {
"additiveBlending": 0, "additiveBlending": 0,
"textures": "https://hifi-content.s3.amazonaws.com/alan/dev/textures/grabsprite-3.png" "textures": "https://hifi-content.s3.amazonaws.com/alan/dev/textures/grabsprite-3.png"
} }
this.particleBeam = Entities.addEntity(particleBeamProperties); this.particleBeamObject = Entities.addEntity(particleBeamPropertiesObject);
}; };
this.updateParticleBeam = function(position, orientation, color, speed, spread, lifespan) { this.updateParticleBeam = function(positionObject, orientationObject, color, speed, spread, lifespan) {
Entities.editEntity(this.particleBeam, { Entities.editEntity(this.particleBeamObject, {
rotation: orientation, rotation: orientationObject,
position: position, position: positionObject,
visible: true, visible: true,
color: color, color: color,
emitSpeed: speed, emitSpeed: speed,
speedSpread: spread, speedSpread: spread,
lifespan: lifespan lifespan: lifespan
}) })
}; };
this.renewParticleBeamLifetime = function() { this.renewParticleBeamLifetime = function() {
var props = Entities.getEntityProperties(this.particleBeam, "age"); var props = Entities.getEntityProperties(this.particleBeamObject, "age");
Entities.editEntity(this.particleBeam, { Entities.editEntity(this.particleBeamObject, {
lifetime: TEMPORARY_PARTICLE_BEAM_LIFETIME + props.age // renew lifetime lifetime: TEMPORARY_PARTICLE_BEAM_LIFETIME + props.age // renew lifetime
}) })
} }
@ -684,9 +685,9 @@ function MyController(hand) {
}; };
this.particleBeamOff = function() { this.particleBeamOff = function() {
if (this.particleBeam !== null) { if (this.particleBeamObject !== null) {
Entities.deleteEntity(this.particleBeam); Entities.deleteEntity(this.particleBeamObject);
this.particleBeam = null; this.particleBeamObject = null;
} }
} }
@ -864,6 +865,7 @@ function MyController(hand) {
// too far away, don't grab // too far away, don't grab
continue; continue;
} }
if (distance < minDistance) { if (distance < minDistance) {
this.grabbedEntity = candidateEntities[i]; this.grabbedEntity = candidateEntities[i];
minDistance = distance; minDistance = distance;
@ -932,6 +934,18 @@ function MyController(hand) {
} }
}; };
this.distanceGrabTimescale = function(mass, distance) {
var timeScale = DISTANCE_HOLDING_ACTION_TIMEFRAME * mass / DISTANCE_HOLDING_UNITY_MASS * distance / DISTANCE_HOLDING_UNITY_DISTANCE;
if (timeScale < DISTANCE_HOLDING_ACTION_TIMEFRAME) {
timeScale = DISTANCE_HOLDING_ACTION_TIMEFRAME;
}
return timeScale;
}
this.getMass = function(dimensions, density) {
return (dimensions.x * dimensions.y * dimensions.z) * density;
}
this.distanceHolding = function() { this.distanceHolding = function() {
var handControllerPosition = (this.hand === RIGHT_HAND) ? MyAvatar.rightHandPosition : MyAvatar.leftHandPosition; var handControllerPosition = (this.hand === RIGHT_HAND) ? MyAvatar.rightHandPosition : MyAvatar.leftHandPosition;
var controllerHandInput = (this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand; var controllerHandInput = (this.hand === RIGHT_HAND) ? Controller.Standard.RightHand : Controller.Standard.LeftHand;
@ -953,12 +967,17 @@ function MyController(hand) {
this.radiusScalar = 1.0; this.radiusScalar = 1.0;
} }
// compute the mass for the purpose of energy and how quickly to move object
this.mass = this.getMass(grabbedProperties.dimensions, grabbedProperties.density);
var distanceToObject = Vec3.length(Vec3.subtract(MyAvatar.position, grabbedProperties.position));
var timeScale = this.distanceGrabTimescale(this.mass, distanceToObject);
this.actionID = NULL_UUID; 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: timeScale,
targetRotation: this.currentObjectRotation, targetRotation: this.currentObjectRotation,
angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, angularTimeScale: timeScale,
tag: getTag(), tag: getTag(),
ttl: ACTION_TTL ttl: ACTION_TTL
}); });
@ -1135,11 +1154,12 @@ function MyController(hand) {
this.handleSpotlight(this.grabbedEntity); this.handleSpotlight(this.grabbedEntity);
} }
var distanceToObject = Vec3.length(Vec3.subtract(MyAvatar.position, this.currentObjectPosition));
var success = Entities.updateAction(this.grabbedEntity, this.actionID, { var success = Entities.updateAction(this.grabbedEntity, this.actionID, {
targetPosition: targetPosition, targetPosition: targetPosition,
linearTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, linearTimeScale: this.distanceGrabTimescale(this.mass, distanceToObject),
targetRotation: this.currentObjectRotation, targetRotation: this.currentObjectRotation,
angularTimeScale: DISTANCE_HOLDING_ACTION_TIMEFRAME, angularTimeScale: this.distanceGrabTimescale(this.mass, distanceToObject),
ttl: ACTION_TTL ttl: ACTION_TTL
}); });
if (success) { if (success) {
@ -1607,7 +1627,7 @@ function MyController(hand) {
this.cleanup = function() { this.cleanup = function() {
this.release(); this.release();
Entities.deleteEntity(this.particleBeam); Entities.deleteEntity(this.particleBeamObject);
Entities.deleteEntity(this.spotLight); Entities.deleteEntity(this.spotLight);
Entities.deleteEntity(this.pointLight); Entities.deleteEntity(this.pointLight);
}; };