overte/examples/hydraMove.js
2014-03-14 13:03:14 -07:00

209 lines
8 KiB
JavaScript

//
// hydraMove.js
// hifi
//
// Created by Brad Hefta-Gaub on 2/10/14.
// Copyright (c) 2014 HighFidelity, Inc. All rights reserved.
//
// This is an example script that demonstrates use of the Controller and MyAvatar classes to implement
// avatar flying through the hydra/controller joysticks
//
//
var damping = 0.9;
var position = { x: MyAvatar.position.x, y: MyAvatar.position.y, z: MyAvatar.position.z };
var joysticksCaptured = false;
var THRUST_CONTROLLER = 0;
var VIEW_CONTROLLER = 1;
var INITIAL_THRUST_MULTPLIER = 1.0;
var THRUST_INCREASE_RATE = 1.05;
var MAX_THRUST_MULTIPLIER = 75.0;
var thrustMultiplier = INITIAL_THRUST_MULTPLIER;
var grabDelta = { x: 0, y: 0, z: 0};
var grabDeltaVelocity = { x: 0, y: 0, z: 0};
var grabStartRotation = { x: 0, y: 0, z: 0, w: 1};
var grabCurrentRotation = { x: 0, y: 0, z: 0, w: 1};
var grabbingWithRightHand = false;
var wasGrabbingWithRightHand = false;
var grabbingWithLeftHand = false;
var wasGrabbingWithLeftHand = false;
var EPSILON = 0.000001;
var velocity = { x: 0, y: 0, z: 0};
var THRUST_MAG_UP = 800.0;
var THRUST_MAG_DOWN = 300.0;
var THRUST_MAG_FWD = 500.0;
var THRUST_MAG_BACK = 300.0;
var THRUST_MAG_LATERAL = 250.0;
var THRUST_JUMP = 120.0;
var YAW_MAG = 500.0;
var PITCH_MAG = 100.0;
var THRUST_MAG_HAND_JETS = THRUST_MAG_FWD;
var JOYSTICK_YAW_MAG = YAW_MAG;
var JOYSTICK_PITCH_MAG = PITCH_MAG * 0.5;
var LEFT_PALM = 0;
var LEFT_BUTTON_4 = 4;
var RIGHT_PALM = 2;
var RIGHT_BUTTON_4 = 10;
// Used by handleGrabBehavior() for managing the grab position changes
function getAndResetGrabDelta() {
var HAND_GRAB_SCALE_DISTANCE = 2.0;
var delta = Vec3.multiply(grabDelta, (MyAvatar.scale * HAND_GRAB_SCALE_DISTANCE));
grabDelta = { x: 0, y: 0, z: 0};
var avatarRotation = MyAvatar.orientation;
var result = Vec3.multiplyQbyV(avatarRotation, Vec3.multiply(delta, -1));
return result;
}
// Used by handleGrabBehavior() for managing the grab velocity feature
function getAndResetGrabDeltaVelocity() {
var HAND_GRAB_SCALE_VELOCITY = 50.0;
var delta = Vec3.multiply(grabDeltaVelocity, (MyAvatar.scale * HAND_GRAB_SCALE_VELOCITY));
grabDeltaVelocity = { x: 0, y: 0, z: 0};
var avatarRotation = MyAvatar.orientation;
var result = Quat.multiply(avatarRotation, Vec3.multiply(delta, -1));
return result;
}
// Used by handleGrabBehavior() for managing the grab rotation feature
function getAndResetGrabRotation() {
var quatDiff = Quat.multiply(grabCurrentRotation, Quat.inverse(grabStartRotation));
grabStartRotation = grabCurrentRotation;
return quatDiff;
}
// handles all the grab related behavior: position (crawl), velocity (flick), and rotate (twist)
function handleGrabBehavior(deltaTime) {
// check for and handle grab behaviors
grabbingWithRightHand = Controller.isButtonPressed(RIGHT_BUTTON_4);
grabbingWithLeftHand = Controller.isButtonPressed(LEFT_BUTTON_4);
stoppedGrabbingWithLeftHand = false;
stoppedGrabbingWithRightHand = false;
if (grabbingWithRightHand && !wasGrabbingWithRightHand) {
// Just starting grab, capture starting rotation
grabStartRotation = Controller.getSpatialControlRawRotation(RIGHT_PALM);
}
if (grabbingWithRightHand) {
grabDelta = Vec3.sum(grabDelta, Vec3.multiply(Controller.getSpatialControlVelocity(RIGHT_PALM), deltaTime));
grabCurrentRotation = Controller.getSpatialControlRawRotation(RIGHT_PALM);
}
if (!grabbingWithRightHand && wasGrabbingWithRightHand) {
// Just ending grab, capture velocity
grabDeltaVelocity = Controller.getSpatialControlVelocity(RIGHT_PALM);
stoppedGrabbingWithRightHand = true;
}
if (grabbingWithLeftHand && !wasGrabbingWithLeftHand) {
// Just starting grab, capture starting rotation
grabStartRotation = Controller.getSpatialControlRawRotation(LEFT_PALM);
}
if (grabbingWithLeftHand) {
grabDelta = Vec3.sum(grabDelta, Vec3.multiply(Controller.getSpatialControlVelocity(LEFT_PALM), deltaTime));
grabCurrentRotation = Controller.getSpatialControlRawRotation(LEFT_PALM);
}
if (!grabbingWithLeftHand && wasGrabbingWithLeftHand) {
// Just ending grab, capture velocity
grabDeltaVelocity = Controller.getSpatialControlVelocity(LEFT_PALM);
stoppedGrabbingWithLeftHand = true;
}
grabbing = grabbingWithRightHand || grabbingWithLeftHand;
stoppedGrabbing = stoppedGrabbingWithRightHand || stoppedGrabbingWithLeftHand;
if (grabbing) {
// move position
var moveFromGrab = getAndResetGrabDelta();
if (Vec3.length(moveFromGrab) > EPSILON) {
MyAvatar.position = Vec3.sum(MyAvatar.position, moveFromGrab);
velocity = { x: 0, y: 0, z: 0};
}
// add some rotation...
var deltaRotation = getAndResetGrabRotation();
var GRAB_CONTROLLER_TURN_SCALING = 0.5;
var euler = Vec3.multiply(Quat.safeEulerAngles(deltaRotation), GRAB_CONTROLLER_TURN_SCALING);
// Adjust body yaw by yaw from controller
var orientation = Quat.multiply(Quat.angleAxis(-euler.y, {x:0, y: 1, z:0}), MyAvatar.orientation);
MyAvatar.orientation = orientation;
// Adjust head pitch from controller
MyAvatar.headPitch = MyAvatar.headPitch - euler.x;
}
// add some velocity...
if (stoppedGrabbing) {
velocity = Vec3.sum(velocity, getAndResetGrabDeltaVelocity());
}
// handle residual velocity
if(Vec3.length(velocity) > EPSILON) {
MyAvatar.position = Vec3.sum(MyAvatar.position, Vec3.multiply(velocity, deltaTime));
// damp velocity
velocity = Vec3.multiply(velocity, damping);
}
wasGrabbingWithRightHand = grabbingWithRightHand;
wasGrabbingWithLeftHand = grabbingWithLeftHand;
}
// Main update function that handles flying and grabbing behaviort
function flyWithHydra(deltaTime) {
var thrustJoystickPosition = Controller.getJoystickPosition(THRUST_CONTROLLER);
if (thrustJoystickPosition.x != 0 || thrustJoystickPosition.y != 0) {
if (thrustMultiplier < MAX_THRUST_MULTIPLIER) {
thrustMultiplier *= 1 + (deltaTime * THRUST_INCREASE_RATE);
}
var currentOrientation = MyAvatar.orientation;
var front = Quat.getFront(currentOrientation);
var right = Quat.getRight(currentOrientation);
var up = Quat.getUp(currentOrientation);
var thrustFront = Vec3.multiply(front, MyAvatar.scale * THRUST_MAG_HAND_JETS *
thrustJoystickPosition.y * thrustMultiplier * deltaTime);
MyAvatar.addThrust(thrustFront);
var thrustRight = Vec3.multiply(right, MyAvatar.scale * THRUST_MAG_HAND_JETS *
thrustJoystickPosition.x * thrustMultiplier * deltaTime);
MyAvatar.addThrust(thrustRight);
} else {
thrustMultiplier = INITIAL_THRUST_MULTPLIER;
}
// View Controller
var viewJoystickPosition = Controller.getJoystickPosition(VIEW_CONTROLLER);
if (viewJoystickPosition.x != 0 || viewJoystickPosition.y != 0) {
// change the body yaw based on our x controller
var orientation = MyAvatar.orientation;
var deltaOrientation = Quat.fromPitchYawRollDegrees(0, (-1 * viewJoystickPosition.x * JOYSTICK_YAW_MAG * deltaTime), 0);
MyAvatar.orientation = Quat.multiply(orientation, deltaOrientation);
// change the headPitch based on our x controller
//pitch += viewJoystickPosition.y * JOYSTICK_PITCH_MAG * deltaTime;
var newPitch = MyAvatar.headPitch + (viewJoystickPosition.y * JOYSTICK_PITCH_MAG * deltaTime);
MyAvatar.headPitch = newPitch;
}
handleGrabBehavior(deltaTime);
}
Script.update.connect(flyWithHydra);
Controller.captureJoystick(THRUST_CONTROLLER);
Controller.captureJoystick(VIEW_CONTROLLER);
// Map keyPress and mouse move events to our callbacks
function scriptEnding() {
// re-enabled the standard application for touch events
Controller.releaseJoystick(THRUST_CONTROLLER);
Controller.releaseJoystick(VIEW_CONTROLLER);
}
Script.scriptEnding.connect(scriptEnding);