Added distance attentuation of linear and angular rate

This commit is contained in:
Philip Rosedale 2016-11-22 10:24:02 -08:00
parent c81d5b0793
commit c1e044364f

View file

@ -8,6 +8,8 @@
// //
// Grab's physically moveable entities with the mouse, by applying a spring force. // Grab's physically moveable entities with the mouse, by applying a spring force.
// //
// Updated November 22, 2016 by Philip Rosedale: Add distance attenuation of grab effect
//
// Distributed under the Apache License, Version 2.0. // Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
// //
@ -48,6 +50,23 @@ var enabled = true;
function getTag() { function getTag() {
return "grab-" + MyAvatar.sessionUUID; return "grab-" + MyAvatar.sessionUUID;
} }
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
function distanceGrabTimescale(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;
}
function getMass(dimensions, density) {
return (dimensions.x * dimensions.y * dimensions.z) * density;
}
function entityIsGrabbedByOther(entityID) { function entityIsGrabbedByOther(entityID) {
// by convention, a distance grab sets the tag of its action to be grab-*owner-session-id*. // by convention, a distance grab sets the tag of its action to be grab-*owner-session-id*.
@ -445,6 +464,8 @@ Grabber.prototype.moveEvent = function(event) {
this.originalGravity = entityProperties.gravity; this.originalGravity = entityProperties.gravity;
} }
this.currentPosition = entityProperties.position; this.currentPosition = entityProperties.position;
this.mass = getMass(entityProperties.dimensions, entityProperties.density);
var cameraPosition = Camera.getPosition();
var actionArgs = { var actionArgs = {
tag: getTag(), tag: getTag(),
@ -465,15 +486,19 @@ Grabber.prototype.moveEvent = function(event) {
//var qZero = this.lastRotation; //var qZero = this.lastRotation;
this.lastRotation = Quat.multiply(deltaQ, this.lastRotation); this.lastRotation = Quat.multiply(deltaQ, this.lastRotation);
var distanceToCamera = Vec3.length(Vec3.subtract(this.currentPosition, cameraPosition));
var angularTimeScale = distanceGrabTimescale(this.mass, distanceToCamera);
actionArgs = { actionArgs = {
targetRotation: this.lastRotation, targetRotation: this.lastRotation,
angularTimeScale: 0.1, angularTimeScale: angularTimeScale,
tag: getTag(), tag: getTag(),
ttl: ACTION_TTL ttl: ACTION_TTL
}; };
} else { } else {
var newPointOnPlane; var newPointOnPlane;
if (this.mode === "verticalCylinder") { if (this.mode === "verticalCylinder") {
// for this mode we recompute the plane based on current Camera // for this mode we recompute the plane based on current Camera
var planeNormal = Quat.getFront(Camera.getOrientation()); var planeNormal = Quat.getFront(Camera.getOrientation());
@ -487,8 +512,9 @@ Grabber.prototype.moveEvent = function(event) {
y: this.pointOnPlane.y, y: this.pointOnPlane.y,
z: this.pointOnPlane.z z: this.pointOnPlane.z
}; };
} else { } else {
var cameraPosition = Camera.getPosition();
newPointOnPlane = mouseIntersectionWithPlane( newPointOnPlane = mouseIntersectionWithPlane(
this.pointOnPlane, this.planeNormal, mouse.current, this.maxDistance); this.pointOnPlane, this.planeNormal, mouse.current, this.maxDistance);
var relativePosition = Vec3.subtract(newPointOnPlane, cameraPosition); var relativePosition = Vec3.subtract(newPointOnPlane, cameraPosition);
@ -501,9 +527,12 @@ Grabber.prototype.moveEvent = function(event) {
} }
this.targetPosition = Vec3.subtract(newPointOnPlane, this.offset); this.targetPosition = Vec3.subtract(newPointOnPlane, this.offset);
var distanceToCamera = Vec3.length(Vec3.subtract(this.targetPosition, cameraPosition));
var linearTimeScale = distanceGrabTimescale(this.mass, distanceToCamera);
actionArgs = { actionArgs = {
targetPosition: this.targetPosition, targetPosition: this.targetPosition,
linearTimeScale: 0.1, linearTimeScale: linearTimeScale,
tag: getTag(), tag: getTag(),
ttl: ACTION_TTL ttl: ACTION_TTL
}; };