diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index be5fdd7edb..6feb2fb672 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -156,13 +156,6 @@ var STATE_CONTINUE_EQUIP = 14; var STATE_WAITING_FOR_BUMPER_RELEASE = 15; var STATE_EQUIP_SPRING = 16; -// Used by the HandAnimaitonBuddy to play hand animations -var IDLE_HAND_STATES = [STATE_OFF, STATE_RELEASE]; -var OPEN_HAND_STATES = [STATE_SEARCHING, STATE_EQUIP_SEARCHING]; -var POINT_HAND_STATES = [STATE_NEAR_TRIGGER, STATE_CONTINUE_NEAR_TRIGGER, STATE_FAR_TRIGGER, STATE_CONTINUE_FAR_TRIGGER]; -var FAR_GRASP_HAND_STATES = [STATE_DISTANCE_HOLDING, STATE_CONTINUE_DISTANCE_HOLDING]; -// otherwise grasp - // collision masks are specified by comma-separated list of group names // the possible list of names is: static, dynamic, kinematic, myAvatar, otherAvatar var COLLISION_MASK_WHILE_GRABBED = "dynamic,otherAvatar"; @@ -274,94 +267,6 @@ function getSpatialOffsetRotation(hand, spatialKey) { return rotation; } -var HAND_IDLE_RAMP_ON_RATE = 0.1; -var HAND_IDLE_RAMP_OFF_RATE = 0.02; - -// ctor -function HandAnimationBuddy(handController) { - - this.handController = handController; - this.hand = handController.hand; - this.handIdleAlpha = 0; - - var handPrefix = (this.hand === RIGHT_HAND) ? "right" : "left"; - this.animVarKeys = { - idle: handPrefix + "HandIdle", - overlayAlpha: handPrefix + "HandOverlayAlpha", - open: handPrefix + "HandOpen", - point: handPrefix + "HandPoint", - farGrasp: handPrefix + "HandFarGrasp", - grasp: handPrefix + "HandGrasp" - }; - - // hook up anim var handler - var self = this; - this.animHandlerId = MyAvatar.addAnimationStateHandler(function (props) { - return self.animStateHandler(props); - }, []); -} - -HandAnimationBuddy.prototype.animStateHandler = function (props) { - var foundState = false; - var result = {}; - - var state = this.handController.state; - var keys = this.animVarKeys; - - // idle check & process - if (IDLE_HAND_STATES.indexOf(state) != -1) { - // ramp down handIdleAlpha - this.handIdleAlpha = Math.max(0, this.handIdleAlpha - HAND_IDLE_RAMP_OFF_RATE); - result[keys.idle] = true; - foundState = true; - } else { - // ramp up handIdleAlpha - this.handIdleAlpha = Math.min(1, this.handIdleAlpha + HAND_IDLE_RAMP_ON_RATE); - result[keys.idle] = false; - } - result[keys.overlayAlpha] = this.handIdleAlpha; - - // open check - if (OPEN_HAND_STATES.indexOf(state) != -1) { - result[keys.open] = true; - foundState = true; - } else { - result[keys.open] = false; - } - - // point check - if (POINT_HAND_STATES.indexOf(state) != -1) { - result[keys.point] = true; - foundState = true; - } else { - result[keys.point] = false; - } - - // far grasp check - if (FAR_GRASP_HAND_STATES.indexOf(state) != -1) { - result[keys.farGrasp] = true; - foundState = true; - } else { - result[keys.farGrasp] = false; - } - - // grasp check - if (!foundState) { - result[keys.grasp] = true; - } else { - result[keys.grasp] = false; - } - - return result; -}; - -HandAnimationBuddy.prototype.cleanup = function () { - if (this.animHandlerId) { - MyAvatar.removeAnimationStateHandler(this.animHandlerId); - this.animHandlerId = undefined; - } -}; - function MyController(hand) { this.hand = hand; if (this.hand === RIGHT_HAND) { @@ -402,8 +307,6 @@ function MyController(hand) { this.offsetPosition = Vec3.ZERO; this.offsetRotation = Quat.IDENTITY; - this.handAnimationBuddy = new HandAnimationBuddy(this); - var _this = this; this.update = function() { @@ -1822,7 +1725,6 @@ function MyController(hand) { Entities.deleteEntity(this.particleBeam); Entities.deleteEntity(this.spotLight); Entities.deleteEntity(this.pointLight); - this.handAnimationBuddy.cleanup(); }; this.activateEntity = function(entityID, grabbedProperties) { diff --git a/examples/controllers/hydra/squeezeHands.js b/examples/controllers/hydra/squeezeHands.js deleted file mode 100644 index 00ba4800f4..0000000000 --- a/examples/controllers/hydra/squeezeHands.js +++ /dev/null @@ -1,76 +0,0 @@ -// -// squeezeHands.js -// examples -// -// Created by Philip Rosedale on June 4, 2014 -// Copyright 2014 High Fidelity, Inc. -// -// Distributed under the Apache License, Version 2.0. -// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html -// - -HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; - -var rightHandAnimation = HIFI_PUBLIC_BUCKET + "animations/RightHandAnimPhilip.fbx"; -var leftHandAnimation = HIFI_PUBLIC_BUCKET + "animations/LeftHandAnimPhilip.fbx"; - -var LEFT = 0; -var RIGHT = 1; - -var lastLeftFrame = 0; -var lastRightFrame = 0; - -var leftDirection = true; -var rightDirection = true; - -var LAST_FRAME = 15.0; // What is the number of the last frame we want to use in the animation? -var SMOOTH_FACTOR = 0.0; -var MAX_FRAMES = 30.0; - -Script.update.connect(function(deltaTime) { - var leftTriggerValue = Controller.getTriggerValue(LEFT); - var rightTriggerValue = Controller.getTriggerValue(RIGHT); - - var leftFrame, rightFrame; - - // Average last few trigger frames together for a bit of smoothing - leftFrame = (leftTriggerValue * LAST_FRAME) * (1.0 - SMOOTH_FACTOR) + lastLeftFrame * SMOOTH_FACTOR; - rightFrame = (rightTriggerValue * LAST_FRAME) * (1.0 - SMOOTH_FACTOR) + lastRightFrame * SMOOTH_FACTOR; - - if (!leftDirection) { - leftFrame = MAX_FRAMES - leftFrame; - } - if (!rightDirection) { - rightFrame = MAX_FRAMES - rightFrame; - } - - if ((leftTriggerValue == 1.0) && (leftDirection == true)) { - leftDirection = false; - lastLeftFrame = MAX_FRAMES - leftFrame; - } else if ((leftTriggerValue == 0.0) && (leftDirection == false)) { - leftDirection = true; - lastLeftFrame = leftFrame; - } - if ((rightTriggerValue == 1.0) && (rightDirection == true)) { - rightDirection = false; - lastRightFrame = MAX_FRAMES - rightFrame; - } else if ((rightTriggerValue == 0.0) && (rightDirection == false)) { - rightDirection = true; - lastRightFrame = rightFrame; - } - - if ((leftFrame != lastLeftFrame) && leftHandAnimation.length){ - MyAvatar.startAnimation(leftHandAnimation, 30.0, 1.0, false, true, leftFrame, leftFrame); - } - if ((rightFrame != lastRightFrame) && rightHandAnimation.length) { - MyAvatar.startAnimation(rightHandAnimation, 30.0, 1.0, false, true, rightFrame, rightFrame); - } - - lastLeftFrame = leftFrame; - lastRightFrame = rightFrame; -}); - -Script.scriptEnding.connect(function() { - MyAvatar.stopAnimation(leftHandAnimation); - MyAvatar.stopAnimation(rightHandAnimation); -}); \ No newline at end of file diff --git a/examples/controllers/squeezeHands.js b/examples/controllers/squeezeHands.js index 3bf13d8646..9fdb359b25 100644 --- a/examples/controllers/squeezeHands.js +++ b/examples/controllers/squeezeHands.js @@ -1,86 +1,80 @@ // -// squeezeHands.js -// examples +// controllers/squeezeHands.js // -// Created by Philip Rosedale on June 4, 2014 -// Copyright 2014 High Fidelity, Inc. +// Created by Anthony J. Thibault +// Copyright 2015 High Fidelity, Inc. +// +// Default script to drive the animation of the hands based on hand controllers. // // Distributed under the Apache License, Version 2.0. // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // -var HIFI_PUBLIC_BUCKET = "http://s3.amazonaws.com/hifi-public/"; -var HIFI_OZAN_BUCKET = "http://hifi-public.s3.amazonaws.com/ozan/"; - -var rightHandAnimation = HIFI_OZAN_BUCKET + "anim/squeeze_hands/right_hand_anim.fbx"; -var leftHandAnimation = HIFI_OZAN_BUCKET + "anim/squeeze_hands/left_hand_anim.fbx"; - var lastLeftTrigger = 0; var lastRightTrigger = 0; - -var leftIsClosing = true; -var rightIsClosing = true; - -var LAST_FRAME = 15.0; // What is the number of the last frame we want to use in the animation? -var SMOOTH_FACTOR = 0.75; -var MAX_FRAMES = 30.0; - +var leftHandOverlayAlpha = 0; +var rightHandOverlayAlpha = 0; var CONTROLLER_DEAD_SPOT = 0.25; +var TRIGGER_SMOOTH_TIMESCALE = 0.1; +var OVERLAY_RAMP_RATE = 8.0; function clamp(val, min, max) { - if (val < min) { - return min; - } else if (val > max) { - return max; - } else { - return val; - } + return Math.min(Math.max(val, min), max); } function normalizeControllerValue(val) { - return clamp((val - CONTROLLER_DEAD_SPOT) / (1.0 - CONTROLLER_DEAD_SPOT), 0.0, 1.0); + return clamp((val - CONTROLLER_DEAD_SPOT) / (1 - CONTROLLER_DEAD_SPOT), 0, 1); } -Script.update.connect(function(deltaTime) { +function lerp(a, b, alpha) { + return a * (1 - alpha) + b * alpha; +} + +function init() { + Script.update.connect(update); + MyAvatar.addAnimationStateHandler(animStateHandler, ["leftHandOverlayAlpha", "rightHandOverlayAlpha", + "leftHandGraspAlpha", "rightHandGraspAlpha"]); +} + +function animStateHandler(props) { + return { leftHandOverlayAlpha: leftHandOverlayAlpha, + leftHandGraspAlpha: lastLeftTrigger, + rightHandOverlayAlpha: rightHandOverlayAlpha, + rightHandGraspAlpha: lastRightTrigger }; +} + +function update(dt) { var leftTrigger = normalizeControllerValue(Controller.getValue(Controller.Standard.LT)); var rightTrigger = normalizeControllerValue(Controller.getValue(Controller.Standard.RT)); // Average last few trigger values together for a bit of smoothing - var smoothLeftTrigger = leftTrigger * (1.0 - SMOOTH_FACTOR) + lastLeftTrigger * SMOOTH_FACTOR; - var smoothRightTrigger = rightTrigger * (1.0 - SMOOTH_FACTOR) + lastRightTrigger * SMOOTH_FACTOR; + var tau = clamp(dt / TRIGGER_SMOOTH_TIMESCALE, 0, 1); + lastLeftTrigger = lerp(leftTrigger, lastLeftTrigger, tau); + lastRightTrigger = lerp(rightTrigger, lastRightTrigger, tau); - if (leftTrigger == 0.0) { - leftIsClosing = true; - } else if (leftTrigger == 1.0) { - leftIsClosing = false; + // ramp on/off left hand overlay + var leftHandPose = Controller.getPoseValue(Controller.Standard.LeftHand); + if (leftHandPose.valid) { + leftHandOverlayAlpha = clamp(leftHandOverlayAlpha + OVERLAY_RAMP_RATE * dt, 0, 1); + } else { + leftHandOverlayAlpha = clamp(leftHandOverlayAlpha - OVERLAY_RAMP_RATE * dt, 0, 1); } - if (rightTrigger == 0.0) { - rightIsClosing = true; - } else if (rightTrigger == 1.0) { - rightIsClosing = false; + // ramp on/off right hand overlay + var rightHandPose = Controller.getPoseValue(Controller.Standard.RightHand); + if (rightHandPose.valid) { + rightHandOverlayAlpha = clamp(rightHandOverlayAlpha + OVERLAY_RAMP_RATE * dt, 0, 1); + } else { + rightHandOverlayAlpha = clamp(rightHandOverlayAlpha - OVERLAY_RAMP_RATE * dt, 0, 1); } +} - lastLeftTrigger = smoothLeftTrigger; - lastRightTrigger = smoothRightTrigger; +function shutdown() { + Script.update.disconnect(update); + MyAvatar.removeAnimationStateHandler(animStateHandler); +} - // 0..15 - var leftFrame = smoothLeftTrigger * LAST_FRAME; - var rightFrame = smoothRightTrigger * LAST_FRAME; +Script.scriptEnding.connect(shutdown); - var adjustedLeftFrame = (leftIsClosing) ? leftFrame : (MAX_FRAMES - leftFrame); - if (leftHandAnimation.length) { - MyAvatar.startAnimation(leftHandAnimation, 30.0, 1.0, false, true, adjustedLeftFrame, adjustedLeftFrame); - } - - var adjustedRightFrame = (rightIsClosing) ? rightFrame : (MAX_FRAMES - rightFrame); - if (rightHandAnimation.length) { - MyAvatar.startAnimation(rightHandAnimation, 30.0, 1.0, false, true, adjustedRightFrame, adjustedRightFrame); - } -}); - -Script.scriptEnding.connect(function() { - MyAvatar.stopAnimation(leftHandAnimation); - MyAvatar.stopAnimation(rightHandAnimation); -}); +init(); diff --git a/examples/defaultScripts.js b/examples/defaultScripts.js index 443e4b3bf8..5ca62470ee 100644 --- a/examples/defaultScripts.js +++ b/examples/defaultScripts.js @@ -17,6 +17,7 @@ Script.load("inspect.js"); Script.load("notifications.js"); Script.load("users.js"); Script.load("controllers/handControllerGrab.js"); +Script.load("controllers/squeezeHands.js"); Script.load("grab.js"); Script.load("directory.js"); Script.load("dialTone.js"); diff --git a/interface/resources/meshes/defaultAvatar_full/avatar-animation.json b/interface/resources/meshes/defaultAvatar_full/avatar-animation.json index efd16576ee..cbd7b08a16 100644 --- a/interface/resources/meshes/defaultAvatar_full/avatar-animation.json +++ b/interface/resources/meshes/defaultAvatar_full/avatar-animation.json @@ -113,7 +113,7 @@ "id": "rightHandOverlay", "type": "overlay", "data": { - "alpha": 1.0, + "alpha": 0.0, "boneSet": "rightHand", "alphaVar": "rightHandOverlayAlpha" }, @@ -122,125 +122,50 @@ "id": "rightHandStateMachine", "type": "stateMachine", "data": { - "currentState": "rightHandIdle", + "currentState": "rightHandGrasp", "states": [ - { - "id": "rightHandIdle", - "interpTarget": 3, - "interpDuration": 3, - "transitions": [ - { "var": "rightHandOpen", "state": "rightHandOpen" }, - { "var": "rightHandGrasp", "state": "rightHandGrasp" }, - { "var": "rightHandPoint", "state": "rightHandPoint" }, - { "var": "rightHandFarGrasp", "state": "rightHandFarGrasp" } - ] - }, - { - "id": "rightHandOpen", - "interpTarget": 3, - "interpDuration": 3, - "transitions": [ - { "var": "rightHandIdle", "state": "rightHandIdle" }, - { "var": "rightHandGrasp", "state": "rightHandGrasp" }, - { "var": "rightHandPoint", "state": "rightHandPoint" }, - { "var": "rightHandFarGrasp", "state": "rightHandFarGrasp" } - ] - }, { "id": "rightHandGrasp", "interpTarget": 3, "interpDuration": 3, - "transitions": [ - { "var": "rightHandOpen", "state": "rightHandOpen" }, - { "var": "rightHandIdle", "state": "rightHandIdle" }, - { "var": "rightHandPoint", "state": "rightHandPoint" }, - { "var": "rightHandFarGrasp", "state": "rightHandFarGrasp" } - ] - }, - { - "id": "rightHandPoint", - "interpTarget": 3, - "interpDuration": 3, - "transitions": [ - { "var": "rightHandOpen", "state": "rightHandOpen" }, - { "var": "rightHandIdle", "state": "rightHandIdle" }, - { "var": "rightHandGrasp", "state": "rightHandGrasp" }, - { "var": "rightHandFarGrasp", "state": "rightHandFarGrasp" } - ] - }, - { - "id": "rightHandFarGrasp", - "interpTarget": 3, - "interpDuration": 3, - "transitions": [ - { "var": "rightHandOpen", "state": "rightHandOpen" }, - { "var": "rightHandIdle", "state": "rightHandIdle" }, - { "var": "rightHandGrasp", "state": "rightHandGrasp" }, - { "var": "rightHandPoint", "state": "rightHandPoint" } - ] + "transitions": [] } ] }, "children": [ - { - "id": "rightHandIdle", - "type": "clip", - "data": { - "url": "http://hifi-public.s3.amazonaws.com/ozan/anim/hand_anims/point_right_hand.fbx", - "startFrame": 0.0, - "endFrame": 0.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "rightHandOpen", - "type": "clip", - "data": { - "url": "https://hifi-content.s3.amazonaws.com/ozan/dev/anim/hand_anims/search_right.fbx", - "startFrame": 0.0, - "endFrame": 0.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, { "id": "rightHandGrasp", - "type": "clip", + "type": "blendLinear", "data": { - "url": "https://hifi-content.s3.amazonaws.com/ozan/dev/anim/hand_anims/grasp_right.fbx", - "startFrame": 0.0, - "endFrame": 0.0, - "timeScale": 1.0, - "loopFlag": true + "alpha": 0.0, + "alphaVar": "rightHandGraspAlpha" }, - "children": [] - }, - { - "id": "rightHandPoint", - "type": "clip", - "data": { - "url": "http://hifi-public.s3.amazonaws.com/ozan/anim/hand_anims/point_right_hand.fbx", - "startFrame": 20.0, - "endFrame": 20.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "rightHandFarGrasp", - "type": "clip", - "data": { - "url": "https://hifi-content.s3.amazonaws.com/ozan/dev/anim/hand_anims/far_grasp_right.fbx", - "startFrame": 0.0, - "endFrame": 0.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] + "children": [ + { + "id": "rightHandGraspOpen", + "type": "clip", + "data": { + "url": "https://hifi-content.s3.amazonaws.com/ozan/dev/anim/hand_anims/hydra_pose_open_right_v2.fbx", + "startFrame": 0.0, + "endFrame": 0.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "rightHandGraspClosed", + "type": "clip", + "data": { + "url": "https://hifi-content.s3.amazonaws.com/ozan/dev/anim/hand_anims/hydra_pose_close_right_v2.fbx", + "startFrame": 0.0, + "endFrame": 0.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] } ] }, @@ -248,7 +173,7 @@ "id": "leftHandOverlay", "type": "overlay", "data": { - "alpha": 1.0, + "alpha": 0.0, "boneSet": "leftHand", "alphaVar" : "leftHandOverlayAlpha" }, @@ -257,127 +182,50 @@ "id": "leftHandStateMachine", "type": "stateMachine", "data": { - "currentState": "leftHandIdle", + "currentState": "leftHandGrasp", "states": [ - { - "id": "leftHandIdle", - "interpTarget": 3, - "interpDuration": 3, - "transitions": [ - { "var": "leftHandOpen", "state": "leftHandOpen" }, - { "var": "leftHandGrasp", "state": "leftHandGrasp" }, - { "var": "leftHandPoint", "state": "leftHandPoint" }, - { "var": "leftHandFarGrasp", "state": "leftHandFarGrasp" } - ] - }, - { - "id": "leftHandOpen", - "interpTarget": 3, - "interpDuration": 3, - "transitions": [ - { "var": "leftHandIdle", "state": "leftHandIdle" }, - { "var": "leftHandGrasp", "state": "leftHandGrasp" }, - { "var": "leftHandPoint", "state": "leftHandPoint" }, - { "var": "leftHandFarGrasp", "state": "leftHandFarGrasp" } - ] - }, { "id": "leftHandGrasp", "interpTarget": 3, "interpDuration": 3, - "transitions": [ - { "var": "leftHandOpen", "state": "leftHandOpen" }, - { "var": "leftHandIdle", "state": "leftHandIdle" }, - { "var": "leftHandPoint", "state": "leftHandPoint" }, - { "var": "leftHandFarGrasp", "state": "leftHandFarGrasp" } - ] - }, - { - "id": "leftHandPoint", - "interpTarget": 3, - "interpDuration": 3, - "transitions": [ - { "var": "leftHandOpen", "state": "leftHandOpen" }, - { "var": "leftHandIdle", "state": "leftHandIdle" }, - { "var": "leftHandGrasp", "state": "leftHandGrasp" }, - { "var": "leftHandFarGrasp", "state": "leftHandFarGrasp" } - ] - }, - { - "id": "leftHandFarGrasp", - "interpTarget": 3, - "interpDuration": 3, - "transitions": [ - { "var": "leftHandOpen", "state": "leftHandOpen" }, - { "var": "leftHandIdle", "state": "leftHandIdle" }, - { "var": "leftHandGrasp", "state": "leftHandGrasp" }, - { "var": "leftHandPoint", "state": "leftHandPoint" } - ] + "transitions": [] } ] }, "children": [ - { - "id": "leftHandIdle", - "type": "clip", - "data": { - "url": "http://hifi-public.s3.amazonaws.com/ozan/anim/hand_anims/point_left_hand.fbx", - "startFrame": 0.0, - "endFrame": 0.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "leftHandOpen", - "type": "clip", - "data": { - - "url": "https://hifi-content.s3.amazonaws.com/ozan/dev/anim/hand_anims/search_left.fbx", - "startFrame": 0.0, - "endFrame": 0.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, { "id": "leftHandGrasp", - "type": "clip", + "type": "blendLinear", "data": { - "url": "https://hifi-content.s3.amazonaws.com/ozan/dev/anim/hand_anims/grasp_left.fbx", - "startFrame": 0.0, - "endFrame": 0.0, - "timeScale": 1.0, - "loopFlag": true + "alpha": 0.0, + "alphaVar": "leftHandGraspAlpha" }, - "children": [] - }, - { - "id": "leftHandPoint", - "type": "clip", - "data": { - "url": "http://hifi-public.s3.amazonaws.com/ozan/anim/hand_anims/point_left_hand.fbx", - "startFrame": 12.0, - "endFrame": 12.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "leftHandFarGrasp", - "type": "clip", - "data": { - - "url": "https://hifi-content.s3.amazonaws.com/ozan/dev/anim/hand_anims/far_grasp_left.fbx", - "startFrame": 0.0, - "endFrame": 0.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] + "children": [ + { + "id": "leftHandGraspOpen", + "type": "clip", + "data": { + "url": "https://hifi-public.s3.amazonaws.com/ozan/anim/grab/grab_left.fbx", + "startFrame": 0.0, + "endFrame": 0.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "leftHandGraspClosed", + "type": "clip", + "data": { + "url": "https://hifi-public.s3.amazonaws.com/ozan/anim/grab/grab_left.fbx", + "startFrame": 10.0, + "endFrame": 10.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + } + ] } ] },