diff --git a/examples/controllers/handControllerGrab.js b/examples/controllers/handControllerGrab.js index 419f2b78d4..432b2d46fc 100644 --- a/examples/controllers/handControllerGrab.js +++ b/examples/controllers/handControllerGrab.js @@ -157,7 +157,12 @@ 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 function stateToName(state) { switch (state) { @@ -265,6 +270,94 @@ 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) { @@ -304,84 +397,11 @@ function MyController(hand) { this.ignoreIK = false; this.offsetPosition = Vec3.ZERO; this.offsetRotation = Quat.IDENTITY; - this.handIdleAlpha = 0; - var HAND_IDLE_RAMP_ON_RATE = 0.1; - var HAND_IDLE_RAMP_OFF_RATE = 0.02; + this.handAnimationBuddy = new HandAnimationBuddy(this); var _this = this; - var farGrabStates = [STATE_DISTANCE_HOLDING, STATE_CONTINUE_DISTANCE_HOLDING]; - var pointStates = [STATE_SEARCHING, STATE_EQUIP_SEARCHING, - STATE_NEAR_TRIGGER, STATE_CONTINUE_NEAR_TRIGGER, - STATE_FAR_TRIGGER, STATE_CONTINUE_FAR_TRIGGER]; - var idleStates = [STATE_OFF]; - - var propList = ["isLeftHandFarGrab", "isLeftHandPoint", "isLeftHandIdle", "isLeftHandGrab", - "isRightHandFarGrab", "isRightHandPoint", "isRightHandIdle", "isRightHandGrab"]; - - // hook up anim var handler - this.animHandlerId = MyAvatar.addAnimationStateHandler(function (props) { - var foundState = false; - var result = {}; - - var isHandPrefix = (_this.hand === RIGHT_HAND) ? "isRight" : "isLeft"; - var handPrefix = (_this.hand === RIGHT_HAND) ? "right" : "left"; - - /* - // far grab check - if (farGrabStates.indexOf(_this.state) != -1) { - result[isHandPrefix + "HandFarGrab"] = true; - foundState = true; - } else { - result[isHandPrefix + "HandFarGrab"] = false; - } - */ - - result[handPrefix + "HandGrabBlend"] = _this.triggerValue; - - // point check - if (pointStates.indexOf(_this.state) != -1) { - result[isHandPrefix + "HandPoint"] = true; - foundState = true; - } else { - result[isHandPrefix + "HandPoint"] = false; - } - - // idle check - if (idleStates.indexOf(_this.state) != -1) { - - // ramp down handIdleAlpha - if (_this.handIdleAlpha > HAND_IDLE_RAMP_OFF_RATE) { - _this.handIdleAlpha -= HAND_IDLE_RAMP_OFF_RATE; - } else { - _this.handIdleAlpha = 0; - } - result[isHandPrefix + "HandIdle"] = true; - foundState = true; - } else { - - // ramp up handIdleAlpha - if (_this.handIdleAlpha < 1 - HAND_IDLE_RAMP_ON_RATE) { - _this.handIdleAlpha += HAND_IDLE_RAMP_ON_RATE; - } else { - _this.handIdleAlpha = 1; - } - result[isHandPrefix + "HandIdle"] = false; - } - - result[handPrefix + "HandOverlayAlpha"] = _this.handIdleAlpha; - - // grab check - if (!foundState) { - result[isHandPrefix + "HandGrab"] = true; - } else { - result[isHandPrefix + "HandGrab"] = false; - } - - return result; - }, propList); - this.update = function() { this.updateSmoothedTrigger(); @@ -1802,11 +1822,7 @@ function MyController(hand) { Entities.deleteEntity(this.particleBeam); Entities.deleteEntity(this.spotLight); Entities.deleteEntity(this.pointLight); - - if (this.animHandlerId) { - MyAvatar.removeAnimationStateHandler(this.animHandlerId); - this.animHandlerId = undefined; - } + this.handAnimationBuddy.cleanup(); }; this.activateEntity = function(entityID, grabbedProperties) { @@ -2008,4 +2024,4 @@ function renewParticleBeamLifetimes(deltaTime) { } rightController.renewParticleBeamLifetime(); leftController.renewParticleBeamLifetime(); -} \ No newline at end of file +} diff --git a/interface/resources/meshes/defaultAvatar_full/avatar-animation.json b/interface/resources/meshes/defaultAvatar_full/avatar-animation.json index 38cbbaa867..3f9708cdb3 100644 --- a/interface/resources/meshes/defaultAvatar_full/avatar-animation.json +++ b/interface/resources/meshes/defaultAvatar_full/avatar-animation.json @@ -129,36 +129,54 @@ "interpTarget": 3, "interpDuration": 3, "transitions": [ - { "var": "isRightHandPoint", "state": "rightHandPointIntro" }, - { "var": "isRightHandGrab", "state": "rightHandGrab" } + { "var": "rightHandOpen", "state": "rightHandOpen" }, + { "var": "rightHandGrasp", "state": "rightHandGrasp" }, + { "var": "rightHandPoint", "state": "rightHandPoint" }, + { "var": "rightHandFarGrasp", "state": "rightHandFarGrasp" } ] }, { - "id": "rightHandPointIntro", + "id": "rightHandOpen", "interpTarget": 3, "interpDuration": 3, "transitions": [ - { "var": "isRightHandIdle", "state": "rightHandIdle" }, - { "var": "isRightHandGrab", "state": "rightHandGrab" }, - { "var": "isRightHandPointIntroOnDone", "state": "rightHandPointHold" } + { "var": "rightHandIdle", "state": "rightHandIdle" }, + { "var": "rightHandGrasp", "state": "rightHandGrasp" }, + { "var": "rightHandPoint", "state": "rightHandPoint" }, + { "var": "rightHandFarGrasp", "state": "rightHandFarGrasp" } ] }, { - "id": "rightHandPointHold", + "id": "rightHandGrasp", "interpTarget": 3, "interpDuration": 3, "transitions": [ - { "var": "isRightHandIdle", "state": "rightHandIdle" }, - { "var": "isRightHandGrab", "state": "rightHandGrab" } + { "var": "rightHandOpen", "state": "rightHandOpen" }, + { "var": "rightHandIdle", "state": "rightHandIdle" }, + { "var": "rightHandPoint", "state": "rightHandPoint" }, + { "var": "rightHandFarGrasp", "state": "rightHandFarGrasp" } ] }, { - "id": "rightHandGrab", + "id": "rightHandPoint", "interpTarget": 3, "interpDuration": 3, "transitions": [ - { "var": "isRightHandIdle", "state": "rightHandIdle" }, - { "var": "isRightHandPoint", "state": "rightHandPointHold" } + { "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" } ] } ] @@ -177,7 +195,43 @@ "children": [] }, { - "id": "rightHandPointHold", + "id": "rightHandOpen", + "type": "clip", + "data": { + "url": "https://hifi-public.s3.amazonaws.com/ozan/anim/grab/force_grab_right.fbx", + "startFrame": 0.0, + "endFrame": 0.0, + "timeScale": 1.0, + "loopFlag": true + }, + "children": [] + }, + { + "id": "rightHandGrasp", + "type": "clip", + "data": { + "url": "https://hifi-public.s3.amazonaws.com/ozan/anim/grab/grab_right.fbx", + "startFrame": 10.0, + "endFrame": 10.0, + "timeScale": 1.0, + "loopFlag": true + }, + "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-public.s3.amazonaws.com/ozan/anim/grab/force_grab_right.fbx", @@ -187,52 +241,6 @@ "loopFlag": true }, "children": [] - }, - { - "id": "rightHandPointIntro", - "type": "clip", - "data": { - "url": "https://hifi-public.s3.amazonaws.com/ozan/anim/grab/force_grab_right.fbx", - "startFrame": 0.0, - "endFrame": 12.0, - "timeScale": 1.0, - "loopFlag": false - }, - "children": [] - }, - { - "id": "rightHandGrab", - "type": "blendLinear", - "data": { - "alpha": 0.0, - "alphaVar": "rightHandGrabBlend" - }, - "children": [ - { - "id": "rightHandOpen", - "type": "clip", - "data": { - "url": "https://hifi-public.s3.amazonaws.com/ozan/anim/grab/grab_right.fbx", - "startFrame": 0.0, - "endFrame": 0.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - }, - { - "id": "rightHandClose", - "type": "clip", - "data": { - "url": "https://hifi-public.s3.amazonaws.com/ozan/anim/grab/grab_right.fbx", - "startFrame": 10.0, - "endFrame": 10.0, - "timeScale": 1.0, - "loopFlag": true - }, - "children": [] - } - ] } ] }, @@ -256,36 +264,54 @@ "interpTarget": 3, "interpDuration": 3, "transitions": [ - { "var": "isLeftHandPoint", "state": "leftHandPointIntro" }, - { "var": "isLeftHandGrab", "state": "leftHandGrab" } + { "var": "leftHandOpen", "state": "leftHandOpen" }, + { "var": "leftHandGrasp", "state": "leftHandGrasp" }, + { "var": "leftHandPoint", "state": "leftHandPoint" }, + { "var": "leftHandFarGrasp", "state": "leftHandFarGrasp" } ] }, { - "id": "leftHandPointIntro", + "id": "leftHandOpen", "interpTarget": 3, "interpDuration": 3, "transitions": [ - { "var": "isLeftHandIdle", "state": "leftHandIdle" }, - { "var": "isLeftHandGrab", "state": "leftHandGrab" }, - { "var": "isLeftHandPointIntroOnDone", "state": "leftHandPointHold" } + { "var": "leftHandIdle", "state": "leftHandIdle" }, + { "var": "leftHandGrasp", "state": "leftHandGrasp" }, + { "var": "leftHandPoint", "state": "leftHandPoint" }, + { "var": "leftHandFarGrasp", "state": "leftHandFarGrasp" } ] }, { - "id": "leftHandPointHold", + "id": "leftHandGrasp", "interpTarget": 3, "interpDuration": 3, "transitions": [ - { "var": "isLeftHandIdle", "state": "leftHandIdle" }, - { "var": "isLeftHandGrab", "state": "leftHandGrab" } + { "var": "leftHandOpen", "state": "leftHandOpen" }, + { "var": "leftHandIdle", "state": "leftHandIdle" }, + { "var": "leftHandPoint", "state": "leftHandPoint" }, + { "var": "leftHandFarGrasp", "state": "leftHandFarGrasp" } ] }, { - "id": "leftHandGrab", + "id": "leftHandPoint", "interpTarget": 3, "interpDuration": 3, "transitions": [ - { "var": "isLeftHandIdle", "state": "leftHandIdle" }, - { "var": "isLeftHandPoint", "state": "leftHandPointHold" } + { "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" } ] } ] @@ -304,7 +330,33 @@ "children": [] }, { - "id": "leftHandPointHold", + "id": "leftHandOpen", + "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": "leftHandGrasp", + "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": [] + }, + { + "id": "leftHandPoint", "type": "clip", "data": { "url": "http://hifi-public.s3.amazonaws.com/ozan/anim/hand_anims/point_left_hand.fbx", @@ -316,50 +368,17 @@ "children": [] }, { - "id": "leftHandPointIntro", + "id": "leftHandFarGrasp", "type": "clip", "data": { - "url": "http://hifi-public.s3.amazonaws.com/ozan/anim/hand_anims/point_left_hand.fbx", + + "url": "https://hifi-public.s3.amazonaws.com/ozan/anim/grab/grab_left.fbx", "startFrame": 0.0, - "endFrame": 12.0, + "endFrame": 0.0, "timeScale": 1.0, - "loopFlag": false + "loopFlag": true }, "children": [] - }, - { - "id": "leftHandGrab", - "type": "blendLinear", - "data": { - "alpha": 0.0, - "alphaVar": "leftHandGrabBlend" - }, - "children": [ - { - "id": "leftHandOpen", - "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": "leftHandClose", - "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": [] - } - ] } ] }, diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index e8d952973b..3cd74afb81 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -119,7 +119,6 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { handParams.isLeftEnabled = true; handParams.leftPosition = Quaternions::Y_180 * leftPalm.getRawPosition(); handParams.leftOrientation = Quaternions::Y_180 * leftPalm.getRawRotation(); - handParams.leftTrigger = leftPalm.getTrigger(); } else { handParams.isLeftEnabled = false; } @@ -129,7 +128,6 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { handParams.isRightEnabled = true; handParams.rightPosition = Quaternions::Y_180 * rightPalm.getRawPosition(); handParams.rightOrientation = Quaternions::Y_180 * rightPalm.getRawRotation(); - handParams.rightTrigger = rightPalm.getTrigger(); } else { handParams.isRightEnabled = false; } diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index 8567945a87..bcda3e8f5c 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -960,7 +960,6 @@ void Rig::updateEyeJoint(int index, const glm::vec3& modelTranslation, const glm } void Rig::updateFromHandParameters(const HandParameters& params, float dt) { - if (_animSkeleton && _animNode) { if (params.isLeftEnabled) { _animVars.set("leftHandPosition", params.leftPosition); @@ -980,47 +979,6 @@ void Rig::updateFromHandParameters(const HandParameters& params, float dt) { _animVars.unset("rightHandRotation"); _animVars.set("rightHandType", (int)IKTarget::Type::HipsRelativeRotationAndPosition); } - - /* - // set leftHand grab vars - _animVars.set("isLeftHandIdle", false); - _animVars.set("isLeftHandPoint", false); - _animVars.set("isLeftHandGrab", false); - - // Split the trigger range into three zones. - bool rampOut = false; - if (params.leftTrigger > 0.6666f) { - _animVars.set("isLeftHandGrab", true); - } else if (params.leftTrigger > 0.3333f) { - _animVars.set("isLeftHandPoint", true); - } else { - _animVars.set("isLeftHandIdle", true); - rampOut = true; - } - const float OVERLAY_RAMP_OUT_SPEED = 6.0f; // ramp in and out over 1/6th of a sec - _leftHandOverlayAlpha = glm::clamp(_leftHandOverlayAlpha + (rampOut ? -1.0f : 1.0f) * OVERLAY_RAMP_OUT_SPEED * dt, 0.0f, 1.0f); - _animVars.set("leftHandOverlayAlpha", _leftHandOverlayAlpha); - _animVars.set("leftHandGrabBlend", params.leftTrigger); - - // set leftHand grab vars - _animVars.set("isRightHandIdle", false); - _animVars.set("isRightHandPoint", false); - _animVars.set("isRightHandGrab", false); - - // Split the trigger range into three zones - rampOut = false; - if (params.rightTrigger > 0.6666f) { - _animVars.set("isRightHandGrab", true); - } else if (params.rightTrigger > 0.3333f) { - _animVars.set("isRightHandPoint", true); - } else { - _animVars.set("isRightHandIdle", true); - rampOut = true; - } - _rightHandOverlayAlpha = glm::clamp(_rightHandOverlayAlpha + (rampOut ? -1.0f : 1.0f) * OVERLAY_RAMP_OUT_SPEED * dt, 0.0f, 1.0f); - _animVars.set("rightHandOverlayAlpha", _rightHandOverlayAlpha); - _animVars.set("rightHandGrabBlend", params.rightTrigger); - */ } } diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index 669af2ea64..0636230678 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -71,8 +71,6 @@ public: glm::quat leftOrientation = glm::quat(); // rig space (z forward) glm::vec3 rightPosition = glm::vec3(); // rig space glm::quat rightOrientation = glm::quat(); // rig space (z forward) - float leftTrigger = 0.0f; - float rightTrigger = 0.0f; }; virtual ~Rig() {}