Merge pull request #15271 from amantley/overrideHandAnimsSquashed

Allow Hand Animations to be Overridden
This commit is contained in:
Shannon Romano 2019-04-17 11:53:41 -07:00 committed by GitHub
commit da314694b4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 522 additions and 221 deletions

View file

@ -197,260 +197,100 @@
"id": "rightHandStateMachine",
"type": "stateMachine",
"data": {
"currentState": "rightHandGrasp",
"currentState": "rightHandAnimNone",
"states": [
{
"id": "rightHandGrasp",
"interpTarget": 3,
"id": "rightHandAnimNone",
"interpTarget": 1,
"interpDuration": 3,
"transitions": [
{ "var": "isRightIndexPoint", "state": "rightIndexPoint" },
{ "var": "isRightThumbRaise", "state": "rightThumbRaise" },
{ "var": "isRightIndexPointAndThumbRaise", "state": "rightIndexPointAndThumbRaise" }
{ "var": "rightHandAnimA", "state": "rightHandAnimA" },
{ "var": "rightHandAnimB", "state": "rightHandAnimB" }
]
},
{
"id": "rightIndexPoint",
"interpTarget": 15,
"id": "rightHandAnimA",
"interpTarget": 1,
"interpDuration": 3,
"transitions": [
{ "var": "isRightHandGrasp", "state": "rightHandGrasp" },
{ "var": "isRightThumbRaise", "state": "rightThumbRaise" },
{ "var": "isRightIndexPointAndThumbRaise", "state": "rightIndexPointAndThumbRaise" }
{ "var": "rightHandAnimNone", "state": "rightHandAnimNone" },
{ "var": "rightHandAnimB", "state": "rightHandAnimB" }
]
},
{
"id": "rightThumbRaise",
"interpTarget": 15,
"id": "rightHandAnimB",
"interpTarget": 1,
"interpDuration": 3,
"transitions": [
{ "var": "isRightHandGrasp", "state": "rightHandGrasp" },
{ "var": "isRightIndexPoint", "state": "rightIndexPoint" },
{ "var": "isRightIndexPointAndThumbRaise", "state": "rightIndexPointAndThumbRaise" }
]
},
{
"id": "rightIndexPointAndThumbRaise",
"interpTarget": 15,
"interpDuration": 3,
"transitions": [
{ "var": "isRightHandGrasp", "state": "rightHandGrasp" },
{ "var": "isRightIndexPoint", "state": "rightIndexPoint" },
{ "var": "isRightThumbRaise", "state": "rightThumbRaise" }
{ "var": "rightHandAnimNone", "state": "rightHandAnimNone" },
{ "var": "rightHandAnimA", "state": "rightHandAnimA" }
]
}
]
},
"children": [
{
"id": "rightHandGrasp",
"type": "blendLinear",
"data": {
"alpha": 0.0,
"alphaVar": "rightHandGraspAlpha"
},
"children": [
{
"id": "rightHandGraspOpen",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/hydra_pose_open_right.fbx",
"startFrame": 0.0,
"endFrame": 0.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
},
{
"id": "rightHandGraspClosed",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/hydra_pose_closed_right.fbx",
"startFrame": 0.0,
"endFrame": 0.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
}
]
},
{
"id": "rightIndexPoint",
"type": "blendLinear",
"data": {
"alpha": 0.0,
"alphaVar": "rightHandGraspAlpha"
},
"children": [
{
"id": "rightIndexPointOpen",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/touch_point_open_right.fbx",
"startFrame": 15.0,
"endFrame": 15.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
},
{
"id": "rightIndexPointClosed",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/touch_point_closed_right.fbx",
"startFrame": 15.0,
"endFrame": 15.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
}
]
},
{
"id": "rightThumbRaise",
"type": "blendLinear",
"data": {
"alpha": 0.0,
"alphaVar": "rightHandGraspAlpha"
},
"children": [
{
"id": "rightThumbRaiseOpen",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/touch_thumb_open_right.fbx",
"startFrame": 15.0,
"endFrame": 15.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
},
{
"id": "rightThumbRaiseClosed",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/touch_thumb_closed_right.fbx",
"startFrame": 15.0,
"endFrame": 15.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
}
]
},
{
"id": "rightIndexPointAndThumbRaise",
"type": "blendLinear",
"data": {
"alpha": 0.0,
"alphaVar": "rightHandGraspAlpha"
},
"children": [
{
"id": "rightIndexPointAndThumbRaiseOpen",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/touch_thumb_point_open_right.fbx",
"startFrame": 15.0,
"endFrame": 15.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
},
{
"id": "rightIndexPointAndThumbRaiseClosed",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/touch_thumb_point_closed_right.fbx",
"startFrame": 15.0,
"endFrame": 15.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
}
]
}
]
},
{
"id": "leftHandOverlay",
"type": "overlay",
"data": {
"alpha": 0.0,
"boneSet": "leftHand",
"alphaVar": "leftHandOverlayAlpha"
},
"children": [
{
"id": "leftHandStateMachine",
"id": "rightHandAnimNone",
"type": "stateMachine",
"data": {
"currentState": "leftHandGrasp",
"currentState": "rightHandGrasp",
"states": [
{
"id": "leftHandGrasp",
"id": "rightHandGrasp",
"interpTarget": 3,
"interpDuration": 3,
"transitions": [
{ "var": "isLeftIndexPoint", "state": "leftIndexPoint" },
{ "var": "isLeftThumbRaise", "state": "leftThumbRaise" },
{ "var": "isLeftIndexPointAndThumbRaise", "state": "leftIndexPointAndThumbRaise" }
{ "var": "isRightIndexPoint", "state": "rightIndexPoint" },
{ "var": "isRightThumbRaise", "state": "rightThumbRaise" },
{ "var": "isRightIndexPointAndThumbRaise", "state": "rightIndexPointAndThumbRaise" }
]
},
{
"id": "leftIndexPoint",
"id": "rightIndexPoint",
"interpTarget": 15,
"interpDuration": 3,
"transitions": [
{ "var": "isLeftHandGrasp", "state": "leftHandGrasp" },
{ "var": "isLeftThumbRaise", "state": "leftThumbRaise" },
{ "var": "isLeftIndexPointAndThumbRaise", "state": "leftIndexPointAndThumbRaise" }
{ "var": "isRightHandGrasp", "state": "rightHandGrasp" },
{ "var": "isRightThumbRaise", "state": "rightThumbRaise" },
{ "var": "isRightIndexPointAndThumbRaise", "state": "rightIndexPointAndThumbRaise" }
]
},
{
"id": "leftThumbRaise",
"id": "rightThumbRaise",
"interpTarget": 15,
"interpDuration": 3,
"transitions": [
{ "var": "isLeftHandGrasp", "state": "leftHandGrasp" },
{ "var": "isLeftIndexPoint", "state": "leftIndexPoint" },
{ "var": "isLeftIndexPointAndThumbRaise", "state": "leftIndexPointAndThumbRaise" }
{ "var": "isRightHandGrasp", "state": "rightHandGrasp" },
{ "var": "isRightIndexPoint", "state": "rightIndexPoint" },
{ "var": "isRightIndexPointAndThumbRaise", "state": "rightIndexPointAndThumbRaise" }
]
},
{
"id": "leftIndexPointAndThumbRaise",
"id": "rightIndexPointAndThumbRaise",
"interpTarget": 15,
"interpDuration": 3,
"transitions": [
{ "var": "isLeftHandGrasp", "state": "leftHandGrasp" },
{ "var": "isLeftIndexPoint", "state": "leftIndexPoint" },
{ "var": "isLeftThumbRaise", "state": "leftThumbRaise" }
{ "var": "isRightHandGrasp", "state": "rightHandGrasp" },
{ "var": "isRightIndexPoint", "state": "rightIndexPoint" },
{ "var": "isRightThumbRaise", "state": "rightThumbRaise" }
]
}
]
},
"children": [
{
"id": "leftHandGrasp",
"id": "rightHandGrasp",
"type": "blendLinear",
"data": {
"alpha": 0.0,
"alphaVar": "leftHandGraspAlpha"
"alphaVar": "rightHandGraspAlpha"
},
"children": [
{
"id": "leftHandGraspOpen",
"id": "rightHandGraspOpen",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/hydra_pose_open_left.fbx",
"url": "qrc:///avatar/animations/hydra_pose_open_right.fbx",
"startFrame": 0.0,
"endFrame": 0.0,
"timeScale": 1.0,
@ -459,12 +299,12 @@
"children": []
},
{
"id": "leftHandGraspClosed",
"id": "rightHandGraspClosed",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/hydra_pose_closed_left.fbx",
"startFrame": 10.0,
"endFrame": 10.0,
"url": "qrc:///avatar/animations/hydra_pose_closed_right.fbx",
"startFrame": 0.0,
"endFrame": 0.0,
"timeScale": 1.0,
"loopFlag": true
},
@ -473,18 +313,18 @@
]
},
{
"id": "leftIndexPoint",
"id": "rightIndexPoint",
"type": "blendLinear",
"data": {
"data": {
"alpha": 0.0,
"alphaVar": "leftHandGraspAlpha"
"alphaVar": "rightHandGraspAlpha"
},
"children": [
{
"id": "leftIndexPointOpen",
"id": "rightIndexPointOpen",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/touch_point_open_left.fbx",
"url": "qrc:///avatar/animations/touch_point_open_right.fbx",
"startFrame": 15.0,
"endFrame": 15.0,
"timeScale": 1.0,
@ -493,10 +333,10 @@
"children": []
},
{
"id": "leftIndexPointClosed",
"id": "rightIndexPointClosed",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/touch_point_closed_left.fbx",
"url": "qrc:///avatar/animations/touch_point_closed_right.fbx",
"startFrame": 15.0,
"endFrame": 15.0,
"timeScale": 1.0,
@ -507,18 +347,18 @@
]
},
{
"id": "leftThumbRaise",
"id": "rightThumbRaise",
"type": "blendLinear",
"data": {
"data": {
"alpha": 0.0,
"alphaVar": "leftHandGraspAlpha"
"alphaVar": "rightHandGraspAlpha"
},
"children": [
{
"id": "leftThumbRaiseOpen",
"id": "rightThumbRaiseOpen",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/touch_thumb_open_left.fbx",
"url": "qrc:///avatar/animations/touch_thumb_open_right.fbx",
"startFrame": 15.0,
"endFrame": 15.0,
"timeScale": 1.0,
@ -527,10 +367,10 @@
"children": []
},
{
"id": "leftThumbRaiseClosed",
"id": "rightThumbRaiseClosed",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/touch_thumb_closed_left.fbx",
"url": "qrc:///avatar/animations/touch_thumb_closed_right.fbx",
"startFrame": 15.0,
"endFrame": 15.0,
"timeScale": 1.0,
@ -541,18 +381,18 @@
]
},
{
"id": "leftIndexPointAndThumbRaise",
"id": "rightIndexPointAndThumbRaise",
"type": "blendLinear",
"data": {
"data": {
"alpha": 0.0,
"alphaVar": "leftHandGraspAlpha"
"alphaVar": "rightHandGraspAlpha"
},
"children": [
{
"id": "leftIndexPointAndThumbRaiseOpen",
"id": "rightIndexPointAndThumbRaiseOpen",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/touch_thumb_point_open_left.fbx",
"url": "qrc:///avatar/animations/touch_thumb_point_open_right.fbx",
"startFrame": 15.0,
"endFrame": 15.0,
"timeScale": 1.0,
@ -561,10 +401,10 @@
"children": []
},
{
"id": "leftIndexPointAndThumbRaiseClosed",
"id": "rightIndexPointAndThumbRaiseClosed",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/touch_thumb_point_closed_left.fbx",
"url": "qrc:///avatar/animations/touch_thumb_point_closed_right.fbx",
"startFrame": 15.0,
"endFrame": 15.0,
"timeScale": 1.0,
@ -577,6 +417,290 @@
]
},
{
"id": "rightHandAnimA",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/touch_thumb_point_open_right.fbx",
"startFrame": 15.0,
"endFrame": 15.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
},
{
"id": "rightHandAnimB",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/touch_thumb_point_open_right.fbx",
"startFrame": 15.0,
"endFrame": 15.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
}
]
},
{
"id": "leftHandOverlay",
"type": "overlay",
"data": {
"alpha": 0.0,
"boneSet": "leftHand",
"alphaVar": "leftHandOverlayAlpha"
},
"children": [
{
"id": "leftHandStateMachine",
"type": "stateMachine",
"data": {
"currentState": "leftHandAnimNone",
"states": [
{
"id": "leftHandAnimNone",
"interpTarget": 1,
"interpDuration": 3,
"transitions": [
{ "var": "leftHandAnimA", "state": "leftHandAnimA" },
{ "var": "leftHandAnimB", "state": "leftHandAnimB" }
]
},
{
"id": "leftHandAnimA",
"interpTarget": 1,
"interpDuration": 3,
"transitions": [
{ "var": "leftHandAnimNone", "state": "leftHandAnimNone" },
{ "var": "leftHandAnimB", "state": "leftHandAnimB" }
]
},
{
"id": "leftHandAnimB",
"interpTarget": 1,
"interpDuration": 3,
"transitions": [
{ "var": "leftHandAnimNone", "state": "leftHandAnimNone" },
{ "var": "leftHandAnimA", "state": "leftHandAnimA" }
]
}
]
},
"children": [
{
"id": "leftHandAnimNone",
"type": "stateMachine",
"data": {
"currentState": "leftHandGrasp",
"states": [
{
"id": "leftHandGrasp",
"interpTarget": 3,
"interpDuration": 3,
"transitions": [
{ "var": "isLeftIndexPoint", "state": "leftIndexPoint" },
{ "var": "isLeftThumbRaise", "state": "leftThumbRaise" },
{ "var": "isLeftIndexPointAndThumbRaise", "state": "leftIndexPointAndThumbRaise" }
]
},
{
"id": "leftIndexPoint",
"interpTarget": 15,
"interpDuration": 3,
"transitions": [
{ "var": "isLeftHandGrasp", "state": "leftHandGrasp" },
{ "var": "isLeftThumbRaise", "state": "leftThumbRaise" },
{ "var": "isLeftIndexPointAndThumbRaise", "state": "leftIndexPointAndThumbRaise" }
]
},
{
"id": "leftThumbRaise",
"interpTarget": 15,
"interpDuration": 3,
"transitions": [
{ "var": "isLeftHandGrasp", "state": "leftHandGrasp" },
{ "var": "isLeftIndexPoint", "state": "leftIndexPoint" },
{ "var": "isLeftIndexPointAndThumbRaise", "state": "leftIndexPointAndThumbRaise" }
]
},
{
"id": "leftIndexPointAndThumbRaise",
"interpTarget": 15,
"interpDuration": 3,
"transitions": [
{ "var": "isLeftHandGrasp", "state": "leftHandGrasp" },
{ "var": "isLeftIndexPoint", "state": "leftIndexPoint" },
{ "var": "isLeftThumbRaise", "state": "leftThumbRaise" }
]
}
]
},
"children": [
{
"id": "leftHandGrasp",
"type": "blendLinear",
"data": {
"alpha": 0.0,
"alphaVar": "leftHandGraspAlpha"
},
"children": [
{
"id": "leftHandGraspOpen",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/hydra_pose_open_left.fbx",
"startFrame": 0.0,
"endFrame": 0.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
},
{
"id": "leftHandGraspClosed",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/hydra_pose_closed_left.fbx",
"startFrame": 10.0,
"endFrame": 10.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
}
]
},
{
"id": "leftIndexPoint",
"type": "blendLinear",
"data": {
"alpha": 0.0,
"alphaVar": "leftHandGraspAlpha"
},
"children": [
{
"id": "leftIndexPointOpen",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/touch_point_open_left.fbx",
"startFrame": 15.0,
"endFrame": 15.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
},
{
"id": "leftIndexPointClosed",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/touch_point_closed_left.fbx",
"startFrame": 15.0,
"endFrame": 15.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
}
]
},
{
"id": "leftThumbRaise",
"type": "blendLinear",
"data": {
"alpha": 0.0,
"alphaVar": "leftHandGraspAlpha"
},
"children": [
{
"id": "leftThumbRaiseOpen",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/touch_thumb_open_left.fbx",
"startFrame": 15.0,
"endFrame": 15.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
},
{
"id": "leftThumbRaiseClosed",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/touch_thumb_closed_left.fbx",
"startFrame": 15.0,
"endFrame": 15.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
}
]
},
{
"id": "leftIndexPointAndThumbRaise",
"type": "blendLinear",
"data": {
"alpha": 0.0,
"alphaVar": "leftHandGraspAlpha"
},
"children": [
{
"id": "leftIndexPointAndThumbRaiseOpen",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/touch_thumb_point_open_left.fbx",
"startFrame": 15.0,
"endFrame": 15.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
},
{
"id": "leftIndexPointAndThumbRaiseClosed",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/touch_thumb_point_closed_left.fbx",
"startFrame": 15.0,
"endFrame": 15.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
}
]
}
]
},
{
"id": "leftHandAnimA",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/touch_thumb_point_open_left.fbx",
"startFrame": 15.0,
"endFrame": 15.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
},
{
"id": "leftHandAnimB",
"type": "clip",
"data": {
"url": "qrc:///avatar/animations/touch_thumb_point_open_left.fbx",
"startFrame": 15.0,
"endFrame": 15.0,
"timeScale": 1.0,
"loopFlag": true
},
"children": []
}
]
},
{
"id": "mainStateMachine",
"type": "stateMachine",
"data": {
@ -1594,4 +1718,4 @@
}
]
}
}
}

View file

@ -1199,6 +1199,15 @@ void MyAvatar::overrideAnimation(const QString& url, float fps, bool loop, float
_skeletonModel->getRig().overrideAnimation(url, fps, loop, firstFrame, lastFrame);
}
void MyAvatar::overrideHandAnimation(bool isLeft, const QString& url, float fps, bool loop, float firstFrame, float lastFrame) {
if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(this, "overrideHandAnimation", Q_ARG(bool, isLeft), Q_ARG(const QString&, url), Q_ARG(float, fps),
Q_ARG(bool, loop), Q_ARG(float, firstFrame), Q_ARG(float, lastFrame));
return;
}
_skeletonModel->getRig().overrideHandAnimation(isLeft, url, fps, loop, firstFrame, lastFrame);
}
void MyAvatar::restoreAnimation() {
if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(this, "restoreAnimation");
@ -1207,6 +1216,14 @@ void MyAvatar::restoreAnimation() {
_skeletonModel->getRig().restoreAnimation();
}
void MyAvatar::restoreHandAnimation(bool isLeft) {
if (QThread::currentThread() != thread()) {
QMetaObject::invokeMethod(this, "restoreHandAnimation", Q_ARG(bool, isLeft));
return;
}
_skeletonModel->getRig().restoreHandAnimation(isLeft);
}
QStringList MyAvatar::getAnimationRoles() {
if (QThread::currentThread() != thread()) {
QStringList result;

View file

@ -597,6 +597,26 @@ public:
*/
Q_INVOKABLE void overrideAnimation(const QString& url, float fps, bool loop, float firstFrame, float lastFrame);
/**jsdoc
* <code>overrideHandAnimation()</code> Gets the overrides the default hand poses that are triggered with controller buttons.
* use {@link MyAvatar.restoreHandAnimation}.</p> to restore the default poses.
* @function MyAvatar.overrideHandAnimation
* @param isLeft {boolean} Set true if using the left hand
* @param url {string} The URL to the animation file. Animation files need to be FBX format, but only need to contain the
* avatar skeleton and animation data.
* @param fps {number} The frames per second (FPS) rate for the animation playback. 30 FPS is normal speed.
* @param loop {boolean} Set to true if the animation should loop.
* @param firstFrame {number} The frame the animation should start at.
* @param lastFrame {number} The frame the animation should end at
* @example <caption> Override left hand animation for three seconds. </caption>
* // Override the left hand pose then restore the default pose.
* MyAvatar.overrideHandAnimation(isLeft, ANIM_URL, 30, true, 0, 53);
* Script.setTimeout(function () {
* MyAvatar.restoreHandAnimation();
* }, 3000);
*/
Q_INVOKABLE void overrideHandAnimation(bool isLeft, const QString& url, float fps, bool loop, float firstFrame, float lastFrame);
/**jsdoc
* Restores the default animations.
* <p>The avatar animation system includes a set of default animations along with rules for how those animations are blended
@ -615,6 +635,24 @@ public:
*/
Q_INVOKABLE void restoreAnimation();
/**jsdoc
* Restores the default hand animation state machine that is driven by the state machine in the avatar-animation json.
* <p>The avatar animation system includes a set of default animations along with rules for how those animations are blended
* together with procedural data (such as look at vectors, hand sensors etc.). Playing your own custom animations will
* override the default animations. <code>restoreHandAnimation()</code> is used to restore the default hand poses
* If you aren't currently playing an override hand
* animation, this function has no effect.</p>
* @function MyAvatar.restoreHandAnimation
* @param isLeft {boolean} Set to true if using the left hand
* @example <caption> Override left hand animation for three seconds. </caption>
* // Override the left hand pose then restore the default pose.
* MyAvatar.overrideHandAnimation(isLeft, ANIM_URL, 30, true, 0, 53);
* Script.setTimeout(function () {
* MyAvatar.restoreHandAnimation();
* }, 3000);
*/
Q_INVOKABLE void restoreHandAnimation(bool isLeft);
/**jsdoc
* Gets the current animation roles.
* <p>Each avatar has an avatar-animation.json file that defines which animations are used and how they are blended together

View file

@ -370,6 +370,88 @@ void Rig::restoreAnimation() {
}
}
void Rig::overrideHandAnimation(bool isLeft, const QString& url, float fps, bool loop, float firstFrame, float lastFrame) {
HandAnimState::ClipNodeEnum clipNodeEnum;
if (isLeft) {
if (_leftHandAnimState.clipNodeEnum == HandAnimState::None || _leftHandAnimState.clipNodeEnum == HandAnimState::B) {
clipNodeEnum = HandAnimState::A;
} else {
clipNodeEnum = HandAnimState::B;
}
} else {
if (_rightHandAnimState.clipNodeEnum == HandAnimState::None || _rightHandAnimState.clipNodeEnum == HandAnimState::B) {
clipNodeEnum = HandAnimState::A;
} else {
clipNodeEnum = HandAnimState::B;
}
}
if (_animNode) {
std::shared_ptr<AnimClip> clip;
if (isLeft) {
if (clipNodeEnum == HandAnimState::A) {
clip = std::dynamic_pointer_cast<AnimClip>(_animNode->findByName("leftHandAnimA"));
} else {
clip = std::dynamic_pointer_cast<AnimClip>(_animNode->findByName("leftHandAnimB"));
}
} else {
if (clipNodeEnum == HandAnimState::A) {
clip = std::dynamic_pointer_cast<AnimClip>(_animNode->findByName("rightHandAnimA"));
} else {
clip = std::dynamic_pointer_cast<AnimClip>(_animNode->findByName("rightHandAnimB"));
}
}
if (clip) {
// set parameters
clip->setLoopFlag(loop);
clip->setStartFrame(firstFrame);
clip->setEndFrame(lastFrame);
const float REFERENCE_FRAMES_PER_SECOND = 30.0f;
float timeScale = fps / REFERENCE_FRAMES_PER_SECOND;
clip->setTimeScale(timeScale);
clip->loadURL(url);
}
}
// notify the handAnimStateMachine the desired state.
if (isLeft) {
// store current hand anim state.
_leftHandAnimState = { clipNodeEnum, url, fps, loop, firstFrame, lastFrame };
_animVars.set("leftHandAnimNone", false);
_animVars.set("leftHandAnimA", clipNodeEnum == HandAnimState::A);
_animVars.set("leftHandAnimB", clipNodeEnum == HandAnimState::B);
} else {
// store current hand anim state.
_rightHandAnimState = { clipNodeEnum, url, fps, loop, firstFrame, lastFrame };
_animVars.set("rightHandAnimNone", false);
_animVars.set("rightHandAnimA", clipNodeEnum == HandAnimState::A);
_animVars.set("rightHandAnimB", clipNodeEnum == HandAnimState::B);
}
}
void Rig::restoreHandAnimation(bool isLeft) {
if (isLeft) {
if (_leftHandAnimState.clipNodeEnum != HandAnimState::None) {
_leftHandAnimState.clipNodeEnum = HandAnimState::None;
// notify the handAnimStateMachine the desired state.
_animVars.set("leftHandAnimNone", true);
_animVars.set("leftHandAnimA", false);
_animVars.set("leftHandAnimB", false);
}
} else {
if (_rightHandAnimState.clipNodeEnum != HandAnimState::None) {
_rightHandAnimState.clipNodeEnum = HandAnimState::None;
// notify the handAnimStateMachine the desired state.
_animVars.set("rightHandAnimNone", true);
_animVars.set("rightHandAnimA", false);
_animVars.set("rightHandAnimB", false);
}
}
}
void Rig::overrideNetworkAnimation(const QString& url, float fps, bool loop, float firstFrame, float lastFrame) {
NetworkAnimState::ClipNodeEnum clipNodeEnum = NetworkAnimState::None;
@ -2068,6 +2150,20 @@ void Rig::initAnimGraph(const QUrl& url) {
overrideAnimation(origState.url, origState.fps, origState.loop, origState.firstFrame, origState.lastFrame);
}
if (_rightHandAnimState.clipNodeEnum != HandAnimState::None) {
// restore the right hand animation we had before reset.
HandAnimState origState = _rightHandAnimState;
_rightHandAnimState = { HandAnimState::None, "", 30.0f, false, 0.0f, 0.0f };
overrideHandAnimation(false, origState.url, origState.fps, origState.loop, origState.firstFrame, origState.lastFrame);
}
if (_leftHandAnimState.clipNodeEnum != HandAnimState::None) {
// restore the left hand animation we had before reset.
HandAnimState origState = _leftHandAnimState;
_leftHandAnimState = { HandAnimState::None, "", 30.0f, false, 0.0f, 0.0f };
overrideHandAnimation(true, origState.url, origState.fps, origState.loop, origState.firstFrame, origState.lastFrame);
}
// restore the role animations we had before reset.
for (auto& roleAnimState : _roleAnimStates) {
auto roleState = roleAnimState.second;

View file

@ -118,6 +118,9 @@ public:
void overrideAnimation(const QString& url, float fps, bool loop, float firstFrame, float lastFrame);
bool isPlayingOverrideAnimation() const { return _userAnimState.clipNodeEnum != UserAnimState::None; };
void restoreAnimation();
void overrideHandAnimation(bool isLeft, const QString& url, float fps, bool loop, float firstFrame, float lastFrame);
void restoreHandAnimation(bool isLeft);
void overrideNetworkAnimation(const QString& url, float fps, bool loop, float firstFrame, float lastFrame);
void triggerNetworkRole(const QString& role);
@ -357,6 +360,27 @@ protected:
float blendTime;
};
struct HandAnimState {
enum ClipNodeEnum {
None = 0,
A,
B
};
HandAnimState() : clipNodeEnum(HandAnimState::None) {}
HandAnimState(ClipNodeEnum clipNodeEnumIn, const QString& urlIn, float fpsIn, bool loopIn, float firstFrameIn, float lastFrameIn) :
clipNodeEnum(clipNodeEnumIn), url(urlIn), fps(fpsIn), loop(loopIn), firstFrame(firstFrameIn), lastFrame(lastFrameIn) {
}
ClipNodeEnum clipNodeEnum;
QString url;
float fps;
bool loop;
float firstFrame;
float lastFrame;
};
struct UserAnimState {
enum ClipNodeEnum {
None = 0,
@ -391,6 +415,8 @@ protected:
UserAnimState _userAnimState;
NetworkAnimState _networkAnimState;
HandAnimState _rightHandAnimState;
HandAnimState _leftHandAnimState;
std::map<QString, RoleAnimState> _roleAnimStates;
float _leftHandOverlayAlpha { 0.0f };